tx · FYtV6T65yfyHpFw7vxKTmVqqQpbRPdkqQJ6H9W4ts4XH

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.05500000 Waves

2024.11.14 20:31 [3371415] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "FYtV6T65yfyHpFw7vxKTmVqqQpbRPdkqQJ6H9W4ts4XH", "fee": 5500000, "feeAssetId": null, "timestamp": 1731605527875, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "3L1di47rWDyFjn6zaviPftraakduG2rwGdXUbGQzgge7NFeMRhV6SsUntrcK9fF7PdxyCPsFi3xCna8uWBYScC5d" ], "script": "base64:BgKqAQgCEgMKAQgSBAoCCAESAwoBBBIAEgMKAQgSBAoCCAgSBAoCCAgSAwoBCBIAEgQKAggIEgQKAggIEgQKAgEIEgQKAgEIEgQKAggIEgASAwoBARIECgIICBIECgIICBIFCgMICAgSBAoCCAgSBwoFAQEBAQESAwoBARIFCgMBAQgSAwoBCBIDCgEIEgASBAoCCAESBAoCCAESAwoBCBIAEgASAwoBCBIDCgEIvgEAFktTX1NFUEFSQVRFX1BVQkxJQ19LRVkHABNLU19BTExPV19ST0JPX0RVQ0tTBwAKREFZX01JTExJUwCAuJkpABRPTERfU1RBS0lOR19ERUFETElORQCA87jCsTIABWNoYWluCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAANwdWIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDADBRZLU19TRVBBUkFURV9QVUJMSUNfS0VZASCrF1ePFWfjWVRBsNZy62abxKPTZl7VmYZQ35g3H7IJCAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgDCQAAAgEBVAUHJG1hdGNoMAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgJAAIBAg1Vbmtub3duIGNoYWluAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABVkZWZhdWx0UmVzdEFkZHJlc3NTdHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDACIzNQUUN1dkZidmg0TGtQVW5yblUxejNqbmJBMXA5bTNXTmh2AwkAAAIBAVQFByRtYXRjaDACIzNNdW1rR0d6dENLQVhwV0RxeGtkZG9mcVhTVWJxUWt2U0p5CQACAQINVW5rbm93biBjaGFpbgAQYWNyZXMyQWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1A0VUgzVDluWHBNTnBVbVNtUWpQbUV6M0c4NXQzem42ZUEDCQAAAgEBVAUHJG1hdGNoMAIjM05CUHgxRmNpdTNKUU5FR1oyMWpTblRkdXRMTkdHQlVTWGgJAAIBAg1Vbmtub3duIGNoYWluAA5hcmJpdHJhZ2VEZWxheQQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAUKREFZX01JTExJUwMJAAACAQFUBQckbWF0Y2gwAODUAwkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAFU1NJWkUAGQAFTVNJWkUAZAAFTFNJWkUA4QEABlhMU0laRQCQAwAHWFhMU0laRQDxBAAFSVRFUjYJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAAEUlkeENmZ0Vjb25vbXlEYXBwAAIAFElkeENmZ0dvdmVybmFuY2VEYXBwAAMADUlkeENmZ1dsZ0RhcHAABAAUSWR4Q2ZnVG91cm5hbWVudERhcHAABwAPSWR4Q2ZnQWNyZXNEYXBwAAgBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPZWNvbm9teUNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnRWNvbm9teURhcHAAC2dvdkNvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUUSWR4Q2ZnR292ZXJuYW5jZURhcHAAC3dsZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUNSWR4Q2ZnV2xnRGFwcAASdG91cm5hbWVudENvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUUSWR4Q2ZnVG91cm5hbWVudERhcHAADWFjcmVzQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBQ9JZHhDZmdBY3Jlc0RhcHAACnJlY0xhbmROdW0AAAALcmVjTGFuZFNpemUAAQALcmVjVGVycmFpbnMAAgAMcmVjQ29udGluZW50AAMAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ1hY3Jlc0NvbnRyYWN0BQ9hY3Jlc0Fzc2V0SWRLZXkCF0FDUkVTIGlzIG5vdCBpc3N1ZWQgeWV0AAtyYW5kb21EZWxheQACAQlrZXlDb21taXQBB2FkZHJlc3MJAKwCAgIPZmluaXNoQmxvY2tGb3JfBQdhZGRyZXNzARFrZXlSZXNQcm9wb3J0aW9ucwACE3Jlc1R5cGVzUHJvcG9ydGlvbnMBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCWNvbnRpbmVudAkArAICAhRyZXNUeXBlc0J5Q29udGluZW50XwUJY29udGluZW50ARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBCW93bmVyQWRkcgkArAICAhNzdGFrZWRMYW5kc0J5T3duZXJfBQlvd25lckFkZHIBFmtleVN0YWtlZFBpZWNlc0J5T3duZXIBCW93bmVyQWRkcgkArAICAhRzdGFrZWRQaWVjZXNCeU93bmVyXwUJb3duZXJBZGRyAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAW4FByRtYXRjaDAFAW4JAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBCWFzQW55TGlzdAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0EAWwFByRtYXRjaDAFAWwJAAIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BD251bVBpZWNlc0J5U2l6ZQEIbGFuZFNpemUEByRtYXRjaDAFCGxhbmRTaXplAwkAAAICAVMFByRtYXRjaDAFBVNTSVpFAwkAAAICAU0FByRtYXRjaDAFBU1TSVpFAwkAAAICAUwFByRtYXRjaDAFBUxTSVpFAwkAAAICAlhMBQckbWF0Y2gwBQZYTFNJWkUDCQAAAgIDWFhMBQckbWF0Y2gwBQdYWExTSVpFCQACAQIRVW5rbm93biBsYW5kIHNpemUBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARFrZXlMYXN0VHhJZEJ5VXNlcgEEYWRkcgkArAICAg9sYXN0VHhJZEJ5VXNlcl8FBGFkZHIBCmZpeGVkUG9pbnQCA3ZhbAhkZWNpbWFscwQGdGVuUG93CQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgQHbG93UGFydAkApAMBCQBqAgUDdmFsBQZ0ZW5Qb3cEBnplcm9lcwkAsAICCQCkAwEFBnRlblBvdwkAZAIAAQkAsQIBBQdsb3dQYXJ0CQCsAgIJAKwCAgkArAICCQCkAwEJAGkCBQN2YWwFBnRlblBvdwIBLgUGemVyb2VzBQdsb3dQYXJ0AQ9nZXRSYW5kb21OdW1iZXIDCG1heFZhbHVlBHNhbHQHZW50cm9weQMJAGcCAAAFCG1heFZhbHVlCQACAQIWbWF4VmFsdWUgc2hvdWxkIGJlID4gMAQKcmFuZG9tSGFzaAkA9wMBCQDLAQIFBHNhbHQFB2VudHJvcHkJAGoCCQCxCQEFCnJhbmRvbUhhc2gFCG1heFZhbHVlAQlmaW5hbFRpbWUACQCXAwEJAMwIAggFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgUUT0xEX1NUQUtJTkdfREVBRExJTkUFA25pbAAKTEFORFBSRUZJWAIETEFORAAKRFVDS1BSRUZJWAIERFVDSwALUk9CT19QUkVGSVgCBFJPQk8ACkFSVFBSRVNBTEUCB1BSRVNBTEUABk5VTVJFUwAGABhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVIAGQAPREFJTFlSRVNCWVBJRUNFAID40gEADFdITVVMVElQTElFUgCAyK+gJQAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAEFJFU09VUkNFUFJJQ0VNSU4A1bUCABVNSU5fVVNEVF9GRUVfREVMSVZFUlkA0IYDABVVU0RUMkFDUkVTX01VTFRJUExJRVIACgAXQUxMT1dFRF9GUkVFX0RFTElWRVJJRVMAAAAaQUNSRVNfRk9SX0RFTElWRVJZX0FUVEVNUFQAgISvXwAJcHJvZFR5cGVzCQDMCAICEEZpcnN0IEFpZCBLaXQgTDEJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMgkAzAgCAhBGaXJzdCBBaWQgS2l0IEwzCQDMCAICC0JhY2twYWNrIEwxCQDMCAICC0JhY2twYWNrIEwyCQDMCAICC0JhY2twYWNrIEwzCQDMCAICDkZvb2QgUmF0aW9uIEwxCQDMCAICDkZvb2QgUmF0aW9uIEwyCQDMCAICDkZvb2QgUmF0aW9uIEwzCQDMCAICC0pldCBQYWNrIEwxCQDMCAICC0pldCBQYWNrIEwyCQDMCAICC0pldCBQYWNrIEwzCQDMCAICCVNoaWVsZCBMMQkAzAgCAglTaGllbGQgTDIJAMwIAgIJU2hpZWxkIEwzCQDMCAICB01pbmUgTDEJAMwIAgIHTWluZSBMMgkAzAgCAgdNaW5lIEwzCQDMCAICB1RyYXAgTDEJAMwIAgIHVHJhcCBMMgkAzAgCAgdUcmFwIEwzCQDMCAICC0Jvb20tRG9nIEwxCQDMCAICC0Jvb20tRG9nIEwyCQDMCAICC0Jvb20tRG9nIEwzBQNuaWwAEHByb2R1Y3Rpb25NYXRyaXgJAMwIAgIlOF84XzhfMTdfMTdfNDJfMTJfMF8zMF8wLDAsMCwwLDAsMCwwXwkAzAgCAiU4XzhfOF8xN18xN180Ml8yNF8wXzYwXzAsMCw1LDIsMCwwLDBfCQDMCAICJzhfOF84XzE3XzE3XzQyXzM2XzBfMTIwXzAsMCwxMCw0LDAsMCwwXwkAzAgCAik4XzE5XzE5XzhfMjdfMTlfMjZfMV8yMF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNTJfMV80MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNzhfMV84MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAiU4XzhfOF84XzhfNjBfMTNfMl8yXzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8yNl8yXzRfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIlOF84XzhfOF84XzYwXzM5XzJfOF8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfMzBfM18zMF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfNjBfM181MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfOTBfM183MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8xMV80XzEwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzIyXzRfMjBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMzNfNF8zMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAio0XzEzXzIyXzRfMzVfMjJfMjNfMF81MCwxLDBfMCwwLDAsMCwwLDAsMF8JAMwIAgIqNF8xM18yMl80XzM1XzIyXzQ2XzBfNTAsMSwxXzAsMiw1LDAsMCwwLDBfCQDMCAICKzRfMTNfMjJfNF8zNV8yMl82OV8wXzUwLDIsMV8wLDUsMTAsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzIwXzFfMzAsMSwxXzAsMCwwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV80MF8xXzMwLDEsMl8yLDEsMywwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNjBfMV8zMCwxLDNfNSwyLDgsMCwwLDAsMF8JAMwIAgInMjNfMjNfNV8yMF8yM182XzM1XzJfMTAwXzAsMCwwLDAsMCwwLDBfCQDMCAICJzIzXzIzXzVfMjBfMjNfNl83MF8yXzE1MF8wLDAsMCwwLDAsMCwwXwkAzAgCAigyM18yM181XzIwXzIzXzZfMTA1XzJfMjAwXzAsMCwwLDAsMCwwLDBfBQNuaWwACXJJZHhDb2VmZgAGABBySWR4UmVxdWlyZW1lbnRzAAkACXJJZHhTbG90cwAKAA5QUk9EVUNUUEtHU0laRQAKAAt3aElkeExldmVscwAAAAh3aElkeFJlcwABAAh3aElkeE1hdAACAAl3aElkeFByb2QAAwAJd2hJZHhMT0ZUAAQACXZvbExvY2tlZAAAAAt2b2xPY2N1cGllZAABAAd2b2xGcmVlAAIACHZvbFRvdGFsAAMACmJwSWR4TGV2ZWwAAAAIYnBJZHhSZXMAAQAIYnBJZHhNYXQAAgAJYnBJZHhQcm9kAAMACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICA25vXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIFbGNuYV8FB2Fzc2V0SWQBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIDc3RfBQdhc3NldElkASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgIDbGFzCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAUDbmlsAgFfASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIGc3R0YW9fBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIDd2hfBQtsYW5kQXNzZXRJZAEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgtpbmZyYUxldmVsXwUHYXNzZXRJZAEaa2V5RHVja0Fzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIYZHVja0N1c3RvbU5hbWVCeUFzc2V0SWRfBQdhc3NldElkARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQRhZGRyCQCsAgICGGFjY291bnRDdXN0b21OYW1lQnlBZGRyXwUEYWRkcgEPa2V5QWRkcmVzc1JlZkJ5AQRhZGRyCQCsAgICCWFjY1JlZkJ5XwUEYWRkcgEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawELZHVja0Fzc2V0SWQJAKwCAgIab25ib2FyZEFydEFjdGl2YXRlZE9uRHVja18FC2R1Y2tBc3NldElkARxrZXlPbmJvYXJkQXJ0RHVja0FjdGl2YXRlZEJ5AQRhZGRyCQCsAgICGm9uYm9hcmRBcnRBY3RpdmF0ZWREdWNrQnlfBQRhZGRyARNrZXlBZGRyZXNzUmVmZXJyYWxzAQRhZGRyCQCsAgICDWFjY1JlZmVycmFsc18FBGFkZHIBEGtleUR1Y2tJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIKZHVja093bmVyXwUHYXNzZXRJZAEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBFWtleVVzZXJHd2xSZWxlYXNlVGltZQEIdXNlckFkZHIJAKwCAgIaJXMlc19fdXNlckd3bFJlbGVhc2VUaW1lX18FCHVzZXJBZGRyAA9kZWxpdmVyeUZ1bmRLZXkCDGRlbGl2ZXJ5RnVuZAANbGFzdFRvdXJJZEtleQIOJXNfX2xhc3RUb3VySWQABlNDQUxFOACAwtcvAAx4cExldmVsU2NhbGUAgBkAD3hwTGV2ZWxSZWNpcFBvdwCgHwASbnVtUG9pbnRzT25MZXZlbFVwAAMADHJlcXVpcmVtZW50cwkAzAgCAghTdHJlbmd0aAkAzAgCAghBY2N1cmFjeQkAzAgCAglJbnRlbGxlY3QJAMwIAgIJRW5kdXJhbmNlCQDMCAICCURleHRlcml0eQkAzAgCAgVMZXZlbAkAzAgCAgZIZWFsdGgFA25pbAAMY2hhclN0cmVuZ3RoAAAADGNoYXJBY2N1cmFjeQABAA1jaGFySW50ZWxsZWN0AAIADWNoYXJFbmR1cmFuY2UAAwANY2hhckRleHRlcml0eQAEAApOVU1NQUlOQVVYAAIACE1BWFNMT1RTAAIADU1BWFBST0RJTlNMT1QAHgENa2V5RHVja0hlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgILZHVja0hlYWx0aF8FC2R1Y2tBc3NldElkAQxrZXlEdWNrQ2hhcnMBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tDaGFyc18FC2R1Y2tBc3NldElkAQlrZXlEdWNrWFABC2R1Y2tBc3NldElkCQCsAgICB2R1Y2tYUF8FC2R1Y2tBc3NldElkAQxrZXlEdWNrTGV2ZWwBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tMZXZlbF8FC2R1Y2tBc3NldElkARFrZXlEdWNrRnJlZVBvaW50cwELZHVja0Fzc2V0SWQJAKwCAgIPZHVja0ZyZWVQb2ludHNfBQtkdWNrQXNzZXRJZAEQa2V5RHVja0VxdWlwbWVudAELZHVja0Fzc2V0SWQJAKwCAgIOZHVja0VxdWlwbWVudF8FC2R1Y2tBc3NldElkAQlrZXlVc2VyWFABBGFkZHIJAKwCAgIHdXNlclhQXwUEYWRkcgEMa2V5VXNlckxldmVsAQRhZGRyCQCsAgICCnVzZXJMZXZlbF8FBGFkZHIBEWtleVVzZXJGcmVlUG9pbnRzAQRhZGRyCQCsAgICD3VzZXJGcmVlUG9pbnRzXwUEYWRkcgEOa2V5U2F2ZWRIZWFsdGgBC2R1Y2tBc3NldElkCQCsAgICDHNhdmVkSGVhbHRoXwULZHVja0Fzc2V0SWQBEGtleVNhdmVkTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDnNhdmVkTG9jYXRpb25fBQtkdWNrQXNzZXRJZAEUa2V5RHVja0RlbGl2ZXJ5Q291bnQBC2R1Y2tBc3NldElkCQCsAgICGXRvdGFsRGVsaXZlcnlDb3VudEJ5RHVja18FC2R1Y2tBc3NldElkARRrZXlVc2VyRGVsaXZlcnlDb3VudAEEYWRkcgkArAICAhJ1c2VyRGVsaXZlcnlDb3VudF8FBGFkZHIBFmtleVVzZXJMYXN0RGVsaXZlcnlEYXkBBGFkZHIJAKwCAgIUdXNlckxhc3REZWxpdmVyeURheV8FBGFkZHIAB3hwQ2xhaW0AkE4ADHhwQ3VzdG9tTmFtZQDAhD0ACXhwT25ib2FyZADAhD0BCWxldmVsQnlYUAECeHAJAGsDBQx4cExldmVsU2NhbGUJAGwGBQJ4cAAEBQ94cExldmVsUmVjaXBQb3cABAAEBQRET1dOBQZTQ0FMRTgBCW1heEhlYWx0aAEFbGV2ZWwJAGQCAGQFBWxldmVsAQdsZXZlbFVwAgljdXJyTGV2ZWwFbmV3WFAECG5ld0xldmVsCQEJbGV2ZWxCeVhQAQUFbmV3WFAJAMwIAgUIbmV3TGV2ZWwJAMwIAgkAaAIFEm51bVBvaW50c09uTGV2ZWxVcAkAZQIFCG5ld0xldmVsBQljdXJyTGV2ZWwFA25pbAAJREFZTUlMTElTAIC4mSkBFGtleUxhc3RBcmJUaW1lQnlVc2VyAQRhZGRyCQCsAgICEGxhc3RBcmJUaW1lVXNlcl8FBGFkZHIBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQRhZGRyCQCsAgICGGFjcmVzU3Rha2VkQW1vdW50QnlVc2VyXwUEYWRkcgAMUkVOQU1JTkdDT1NUAMCWsQIACk1BWE5BTUVMRU4AMgAPUFJFU0FMRU5VTUxBTkRTAPQDARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEEbmFtZQkArAICAgRsY25fBQRuYW1lAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICAgVpbGFvXwUHYXNzZXRJZAIBXwUJb3duZXJBZGRyARFrZXlMYW5kTnVtVG9Pd25lcgEHbGFuZE51bQkArAICAgNsb18FB2xhbmROdW0BGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQRuYW1lCQCsAgICEWR1Y2tCeUN1c3RvbU5hbWVfBQRuYW1lARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQRuYW1lCQCsAgICFGFjY291bnRCeUN1c3RvbU5hbWVfBQRuYW1lAQlrZXlPbGRpZXMAAgpvbGRpZXNMaXN0AAtjbGFpbU1vZGVXaAAAAA1jbGFpbU1vZGVEdWNrAAEAE2NsYWltTW9kZVdoVGhlbkR1Y2sAAgETZGlzdHJpYnV0ZUJ5V2VpZ2h0cwIFdG90YWwHd2VpZ2h0cwQDc3VtCQBkAgkAZAIJAGQCCQBkAgkAZAIJAJEDAgUHd2VpZ2h0cwAACQCRAwIFB3dlaWdodHMAAQkAkQMCBQd3ZWlnaHRzAAIJAJEDAgUHd2VpZ2h0cwADCQCRAwIFB3dlaWdodHMABAkAkQMCBQd3ZWlnaHRzAAUDCQBnAgAABQNzdW0JAAIBAhBaZXJvIHdlaWdodHMgc3VtBAVub3JtNgkAawMFBXRvdGFsBQVNVUxUNgUDc3VtCgEKbm9ybWFsaXplcgIDYWNjBGVsZW0JAM0IAgUDYWNjCQBrAwUEZWxlbQUFbm9ybTYFBU1VTFQ2CgACJGwFB3dlaWdodHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCm5vcm1hbGl6ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBEmdldE5lZWRlZE1hdGVyaWFscwEFdG90YWwEBXByb3BzCQC1CQIJAQV2YWx1ZQEJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAIBXwMJAQIhPQIJAJADAQUFcHJvcHMFBk5VTVJFUwkAAgECFldyb25nIHByb3BvcnRpb25zIGRhdGEEAXIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAAJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAMJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAQJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAUFA25pbAkBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBQV0b3RhbAUBcgEOcHJvZFN0clRvQnl0ZXMBB3Byb2RTdHIEBXBMaXN0AwkAAAIFB3Byb2RTdHICAAUDbmlsCQC8CQIFB3Byb2RTdHICAV8KAQR0b0JWAgNhY2MGcmVjaXBlBAFqCQBpAgkAyAEBBQNhY2MACAQEY3VycgMJAGYCCQCQAwEFBXBMaXN0BQFqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcExpc3QFAWoAAAkAywECBQNhY2MJAJoDAQUEY3VycgoAAiRsBRBwcm9kdWN0aW9uTWF0cml4CgACJHMJAJADAQUCJGwKAAUkYWNjMAEACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQR0b0JWAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIBDmJ5dGVzVG9Qcm9kU3RyAQJidgoBBmZyb21CVgIDYWNjBnJlY2lwZQQBagkAkAMBBQNhY2MEAWIJAMkBAgkAygECBQJidgkAaAIACAUBagAICQDNCAIFA2FjYwkApAMBCQCxCQEFAWIJALoJAgoAAiRsBRBwcm9kdWN0aW9uTWF0cml4CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZmcm9tQlYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgIBXwEVY2hlY2tTdGF0UmVxdWlyZW1lbnRzAglkdWNrU3RhdHMEcmVxcwoBBWNoZWNrAgNhY2MBagQEYnVmZgMJAGYCCQCQAwEFCWR1Y2tTdGF0cwkAZAIABwUBagkAkQMCBQlkdWNrU3RhdHMJAGQCAAcFAWoAAAMJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEcmVxcwUBagkAZAIJAJEDAgUJZHVja1N0YXRzBQFqBQRidWZmCQACAQkArAICAhtSZXF1aXJlbWVudCBub3Qgc2F0aXNmaWVkOiAJAJEDAgUMcmVxdWlyZW1lbnRzBQFqBgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAcKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWNoZWNrAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA3CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcBCGFkZFByb2RCBwZpZHhDbnQFcExpc3QKaXNQb3NpdGl2ZQdzZWdtZW50B21haW5BdXgEc2xvdAlkdWNrU3RhdHMEBXBhcnRzCQC1CQIFBmlkeENudAIBOgMJAQIhPQIJAJADAQUFcGFydHMAAgkAAgECKEluY29ycmVjdCBmb3JtYXQsIHNob3VsZCBiZSBpbmRleDphbW91bnQDAwkBASEBBQppc1Bvc2l0aXZlCQECIT0CCQCxAgEJAJEDAgUFcGFydHMAAAACBwkAAgECK1Byb2R1Y3QgaWR4IHNob3VsZCBiZSAyIGRpZ2l0cywgemVybyBwYWRkZWQECnByb2R1Y3RJZHgJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwAABAVjb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAEDAwkAZgIAAAUKcHJvZHVjdElkeAYJAGcCBQpwcm9kdWN0SWR4CQCQAwEFEHByb2R1Y3Rpb25NYXRyaXgJAAIBAhNVbmtub3duIHByb2R1Y3QgaWR4AwkAZgIAAAUFY291bnQJAAIBAhdDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZQMJAGYCBQVjb3VudAUNTUFYUFJPRElOU0xPVAkAAgEJAKwCAgkArAICCQCsAgICFENhbid0IHB1dCBtb3JlIHRoYW4gCQCkAwEFDU1BWFBST0RJTlNMT1QCBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQpwcm9kdWN0SWR4AwkAAAIFBWNvdW50AAAJAJQKAgUFcExpc3QHBARoZWFkCQDJAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4BARjdXJyCQCxCQEJAMkBAgkAygECBQVwTGlzdAkAaAIACAUKcHJvZHVjdElkeAAIBAR0YWlsCQDKAQIFBXBMaXN0CQBoAgAICQBkAgUKcHJvZHVjdElkeAABBAZyZWNpcGUJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4BQpwcm9kdWN0SWR4AgFfAwMJAQEhAQUKaXNQb3NpdGl2ZQkAZgIFBWNvdW50BQRjdXJyBwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAglZb3UgaGF2ZSAJAKQDAQUEY3VycgIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgCEywgYnV0IHRyaWVkIHRvIHVzZSAJAKQDAQUFY291bnQECWlzQmlnSXRlbQMDCQEBIQEFCmlzUG9zaXRpdmUJARVjaGVja1N0YXRSZXF1aXJlbWVudHMCBQlkdWNrU3RhdHMJALUJAgkAkQMCBQZyZWNpcGUFEHJJZHhSZXF1aXJlbWVudHMCASwHBAZjb21wYXQJAJEDAgUGcmVjaXBlBQlySWR4U2xvdHMDCQAAAgUGY29tcGF0AgAJAAIBAhdJdGVtIGNhbm5vdCBiZSBlcXVpcHBlZAQBYwkBDXBhcnNlSW50VmFsdWUBBQZjb21wYXQEBGNTZWcJAGkCBQFjAGQDCQECIT0CBQdzZWdtZW50BQRjU2VnCQACAQIUU2VnbWVudCBpbmNvbXBhdGlibGUECGNNYWluQXV4CQBpAgkAagIFAWMAZAAKAwkBAiE9AgUHbWFpbkF1eAUIY01haW5BdXgJAAIBAhFTbG90IGluY29tcGF0aWJsZQQJY051bVNsb3RzCQBqAgUBYwAKAwMJAQIhPQIFBHNsb3QAAAkAZgIFCWNOdW1TbG90cwABBwkAAgECHkJpZyBpdGVtcyBzaG91bGQgb2NjdXB5IHNsb3QgMAkAZgIFCWNOdW1TbG90cwABBwkAlAoCCQDLAQIJAMsBAgUEaGVhZAkAmgMBCQBkAgUEY3VycgMFCmlzUG9zaXRpdmUFBWNvdW50CQEBLQEFBWNvdW50BQR0YWlsBQlpc0JpZ0l0ZW0BC3Nsb3RzR3JvdXBCBgFnBGJwSW4KaXNQb3NpdGl2ZQdzZWdtZW50B21haW5BdXgFc3RhdHMDCQECIT0CBQFnAgAEBXNsb3RzCQC1CQIFAWcCASwDCQBmAgkAkAMBBQVzbG90cwUITUFYU0xPVFMJAAIBAhJXcm9uZyBzbG90cyBmb3JtYXQEAnMwCQCRAwIFBXNsb3RzAAAEAnMxAwkAZgIJAJADAQUFc2xvdHMAAQkAkQMCBQVzbG90cwABAgADAwkAAAIFAnMwAgAJAAACBQJzMQIABwUEYnBJbgQFdG1wUzADCQECIT0CBQJzMAIACQEIYWRkUHJvZEIHBQJzMAUEYnBJbgUKaXNQb3NpdGl2ZQUHc2VnbWVudAUHbWFpbkF1eAAABQVzdGF0cwkAlAoCBQRicEluBwMJAQIhPQIFAnMxAgADCAUFdG1wUzACXzIJAAIBAh5CaWcgaXRlbSBhbHJlYWR5IG9jY3VwaWVzIHNsb3QICQEIYWRkUHJvZEIHBQJzMQgFBXRtcFMwAl8xBQppc1Bvc2l0aXZlBQdzZWdtZW50BQdtYWluQXV4AAEFBXN0YXRzAl8xCAUFdG1wUzACXzEFBGJwSW4BBmRyZXNzQgQHc2VnTGlzdAZwQnl0ZXMKaXNQb3NpdGl2ZQVzdGF0cwoBB3NlZ21lbnQCA2FjYwNzZWcEAWoIBQNhY2MCXzEEB21haW5BdXgJALUJAgUDc2VnAgE7AwkBAiE9AgkAkAMBBQdtYWluQXV4BQpOVU1NQUlOQVVYCQACAQIUV3Jvbmcgc2VnbWVudCBmb3JtYXQEAW0JAJEDAgUHbWFpbkF1eAAABAFhCQCRAwIFB21haW5BdXgAAQMDCQAAAgUBbQIACQAAAgUBYQIABwkAlAoCCQBkAgUBagABCAUDYWNjAl8yBAR0bXBNCQELc2xvdHNHcm91cEIGBQFtCAUDYWNjAl8yBQppc1Bvc2l0aXZlBQFqAAAFBXN0YXRzCQCUCgIJAGQCBQFqAAEJAQtzbG90c0dyb3VwQgYFAWEFBHRtcE0FCmlzUG9zaXRpdmUFAWoAAQUFc3RhdHMICgACJGwFB3NlZ0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUGcEJ5dGVzCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdzZWdtZW50AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAl8yARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAhwcm9wTGlzdA10ZXJyYWluQ291bnRzDWxhbmRTaXplSW5kZXgEc2lnbgMJAQIhPQIJAJADAQUIcHJvcExpc3QFBk5VTVJFUwkAAgECFldyb25nIHByb3BvcnRpb25zIGRhdGEKAQd1cGRhdGVyAgNhY2MBaQQGcmVzdWx0CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb3BMaXN0BQFpCQBoAgkAaAIFBHNpZ24JAJEDAgUNdGVycmFpbkNvdW50cwUBaQUNbGFuZFNpemVJbmRleAMJAGYCAAAFBnJlc3VsdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIWUGFuaWMhIFBpZWNlcyBvZiB0eXBlPQkApAMBBQFpAgcsIHNpZ249CQCkAwEFBHNpZ24CEywgdGVycmFpbkNvdW50c1tpXT0JAKQDAQkAkQMCBQ10ZXJyYWluQ291bnRzBQFpAhAsIGxhbmRTaXplSW5kZXg9CQCkAwEFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHdXBkYXRlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgERdXBkYXRlUHJvcG9ydGlvbnMDDXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduBAhwcm9wTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfCQC5CQIJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAUIcHJvcExpc3QFDXRlcnJhaW5Db3VudHMFDWxhbmRTaXplSW5kZXgFBHNpZ24CAV8BDWNvdW50VGVycmFpbnMBCHRlcnJhaW5zCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUEAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFCAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQwABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUQAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFFAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRgABBQNuaWwBBmFkZFJlcwUKY3VycmVudFJlcw10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwFpBAlyZXNPZlR5cGUJAGgCCQBoAgkAawMFCWRlbHRhVGltZQUXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMFCURBWU1JTExJUwkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmN1cnJlbnRSZXMFAWkFCXJlc09mVHlwZQQBcgoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwEPdmlydENsYWltQWRkUmVzBQpjdXJyZW50UmVzDXRlcnJhaW5Db3VudHMJZGVsdGFUaW1lDWxhbmRTaXplSW5kZXgXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMKAQVhZGRlcgIDYWNjAWkECXJlc09mVHlwZQkAaAIJAGgCCQBrAwUJZGVsdGFUaW1lBRdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwUJREFZTUlMTElTCQCRAwIFDXRlcnJhaW5Db3VudHMFAWkFDWxhbmRTaXplSW5kZXgEDHRvdGFsUmVzVHlwZQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpjdXJyZW50UmVzBQFpBQlyZXNPZlR5cGUJAJQKAgkAzQgCCAUDYWNjAl8xBQx0b3RhbFJlc1R5cGUJAGQCCAUDYWNjAl8yBQx0b3RhbFJlc1R5cGUKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQVhZGRlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgEJdmlydENsYWltBA10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwx0ZXJyYWluQ291bnQECXJlc09mVHlwZQkAaAIJAGgCCQBrAwUJZGVsdGFUaW1lBRdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwUJREFZTUlMTElTBQx0ZXJyYWluQ291bnQFDWxhbmRTaXplSW5kZXgJAJQKAgkAzQgCCAUDYWNjAl8xBQlyZXNPZlR5cGUJAGQCCAUDYWNjAl8yBQlyZXNPZlR5cGUKAAIkbAUNdGVycmFpbkNvdW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAQ1kaXN0cmlidXRlUmVzBAxjdXJyZW50V2hSZXMOY3VycmVudFBhY2tSZXMKcmVzVG9DbGFpbQt3aFNwYWNlTGVmdAQOcmVzTGlzdFRvQ2xhaW0IBQpyZXNUb0NsYWltAl8xBAxyZXNBbVRvQ2xhaW0IBQpyZXNUb0NsYWltAl8yAwkAAAIFDHJlc0FtVG9DbGFpbQAACQCUCgIJALkJAgUMY3VycmVudFdoUmVzAgFfCQC5CQIFDmN1cnJlbnRQYWNrUmVzAgFfAwkAZwIFC3doU3BhY2VMZWZ0BQxyZXNBbVRvQ2xhaW0KAQhhZGRMaXN0cwIDYWNjAWkJAM0IAgUDYWNjCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUMY3VycmVudFdoUmVzBQFpCQCRAwIFDnJlc0xpc3RUb0NsYWltBQFpBAFyCgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhhZGRMaXN0cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAlAoCCQC5CQIFAXICAV8JALkJAgUOY3VycmVudFBhY2tSZXMCAV8KAQxhZGRQYXJ0TGlzdHMCA2FjYwFpBAZ3aFBhcnQJAGsDCQCRAwIFDnJlc0xpc3RUb0NsYWltBQFpBQt3aFNwYWNlTGVmdAUMcmVzQW1Ub0NsYWltCQCUCgIJAM0IAggFA2FjYwJfMQkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDGN1cnJlbnRXaFJlcwUBaQUGd2hQYXJ0CQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkFBndoUGFydAQBcgoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDGFkZFBhcnRMaXN0cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAlAoCCQC5CQIIBQFyAl8xAgFfCQC5CQIIBQFyAl8yAgFfAQtnZXRCYWNrcGFjawEFYnBLZXkEAXAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoCAToJAMwIAgkApAMBCQELdmFsdWVPckVsc2UCCQC2CQEJAJEDAgUBcAUKYnBJZHhMZXZlbAAACQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAXAFCWJwSWR4UHJvZAUDbmlsARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJdm9sUHJlZml4BAVwYXJ0cwkAtQkCBQl2b2xQcmVmaXgCAV8JAGgCCQBoAgUMV0hNVUxUSVBMSUVSCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAEAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAABF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQljdXJyZW50V2gEBWdvb2RzCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCgEJc3VtUmVzTWF0AgNhY2MEaXRlbQkAZAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQRpdGVtCgEHc3VtUHJvZAIDYWNjBGl0ZW0EA2lkeAgFA2FjYwJfMQQEcGtncwkAaQIJAGUCCQBkAgkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBQ5QUk9EVUNUUEtHU0laRQABBQ5QUk9EVUNUUEtHU0laRQkAlAoCCQBkAgUDaWR4AAEJAGQCCAUDYWNjAl8yCQBoAgUEcGtncwUFTVVMVDgECHdoUmVzVm9sCgACJGwJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlzdW1SZXNNYXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYECHdoTWF0Vm9sCgACJGwJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlzdW1SZXNNYXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjFfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYECndoR29vZHNWb2wDCQAAAgUFZ29vZHMCAAAACAoAAiRsCQC8CQIFBWdvb2RzAgFfCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAAAAoBBSRmMl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHc3VtUHJvZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjJfMgIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAl8yCQBkAgkAZAIFCHdoUmVzVm9sBQh3aE1hdFZvbAUKd2hHb29kc1ZvbAEMZ2V0V2FyZWhvdXNlAwV3aEtleQlsYW5kSW5kZXgKaW5mcmFMZXZlbAQJdm9sUHJlZml4CQCsAgIJAKwCAgkApAMBBQlsYW5kSW5kZXgCAV8JAKQDAQUKaW5mcmFMZXZlbAQHd2hUb3RhbAkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQUJdm9sUHJlZml4BAV3aFN0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQV3aEtleQkArAICBQl2b2xQcmVmaXgCGzowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDo6MAQCd2gJALwJAgUFd2hTdHICAToECndoT2NjdXBpZWQJARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEFAndoBAZ3aExvZnQDCQBmAgAFCQCQAwEFAndoCQC5CQIJAMwIAgIBMAkAzAgCCQCkAwEFCndoT2NjdXBpZWQJAMwIAgkApAMBCQBlAgUHd2hUb3RhbAUKd2hPY2N1cGllZAkAzAgCCQCkAwEFB3doVG90YWwFA25pbAIBXwQEbG9mdAkAtQkCCQCRAwIFAndoBQl3aElkeExPRlQCAV8ECHdoTG9ja2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUJdm9sTG9ja2VkBANvY2MDCQBmAgkAkAMBBQRsb2Z0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUKd2hPY2N1cGllZAkAuQkCCQDMCAIJAKQDAQUId2hMb2NrZWQJAMwIAgkApAMBBQNvY2MJAMwIAgkApAMBCQBlAgkAZQIFB3doVG90YWwFCHdoTG9ja2VkBQNvY2MJAMwIAgkApAMBBQd3aFRvdGFsBQNuaWwCAV8JAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQJ3aAUId2hJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQJ3aAUId2hJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgUGd2hMb2Z0BQNuaWwBDGFwcGx5Qm9udXNlcwILbGFuZEFzc2V0SWQGcGllY2VzBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQJYXJ0UGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAAAEBGFkZDYJAGkCBQppbmZyYUxldmVsAAYEBGFkZDcJAGkCBQppbmZyYUxldmVsAAcJAGQCCQBkAgUPREFJTFlSRVNCWVBJRUNFCQBrAwUPREFJTFlSRVNCWVBJRUNFCQBkAgkAZAIFCmluZnJhTGV2ZWwFBGFkZDYJAGgCAAIFBGFkZDcABQkAawMFD0RBSUxZUkVTQllQSUVDRQUJYXJ0UGllY2VzCQBoAgUGcGllY2VzAAUBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwRhZGRyCWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluBA0kdDAzNDI0NzM0Nzg2AwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJQKAgUNbGFuZEFzc2V0SWRJbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAgAEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAkAlAoCCQCRAwIFA2xvYwUIbG9jSWR4SWQFC2R1Y2tBc3NldElkBAtsYW5kQXNzZXRJZAgFDSR0MDM0MjQ3MzQ3ODYCXzEEBmR1Y2tJZAgFDSR0MDM0MjQ3MzQ3ODYCXzIEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAgVMYW5kIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8JAJYKBAUGZHVja0lkBQtsYW5kQXNzZXRJZAUBZAUJc2F2ZWRUaW1lARBjbGFpbVJlc0ludGVybmFsBARhZGRyBmFtb3VudAljbGFpbU1vZGUNbGFuZEFzc2V0SWRJbgMJAGYCAAAFBmFtb3VudAkAAgECD05lZ2F0aXZlIGFtb3VudAQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUJY2xhaW1Nb2RlBQ1sYW5kQXNzZXRJZEluBAhsYW5kU2l6ZQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCCAUBYwJfMwULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIJAQlmaW5hbFRpbWUACAUBYwJfNAMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEIBQFjAl80AgosIGZpbmFsID0gCQCkAwEJAQlmaW5hbFRpbWUABAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIIBQFjAl8yBQZwaWVjZXMECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUGYW1vdW50BQhhdmFpbFJlcwkAAgEJAKwCAgkArAICCQCsAgICIk5vdCBlbm91Z2ggcmVzb3VyY2VzLCBhdmFpbGFibGUgPSAJAKQDAQUIYXZhaWxSZXMCDiwgcmVxdWVzdGVkID0gCQCkAwEFBmFtb3VudAQMbmV3RGVsdGFUaW1lCQBrAwkAZQIFCGF2YWlsUmVzBQZhbW91bnQFCURBWU1JTExJUwkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwQMbmV3VGltZXN0YW1wCQBlAgkBCWZpbmFsVGltZQAFDG5ld0RlbHRhVGltZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQKcmVzVG9DbGFpbQkBCXZpcnRDbGFpbQQFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEIBQFjAl8yBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIAAAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQEbG9mdAkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBAt3aFNwYWNlTGVmdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUDAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAGYCBQZhbW91bnQFC3doU3BhY2VMZWZ0BwkAAgEJAKwCAgkArAICAgVPbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIYIHNwYWNlIGxlZnQgaW4gd2FyZWhvdXNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQOY3VycmVudFBhY2tSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EDSR0MDM3MTU2MzgwMjcDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlgoECQEGYWRkUmVzBQUMY3VycmVudFdoUmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQpyZXNUb0NsYWltAl8yCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQpyZXNUb0NsYWltAl8yAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlgoECQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUEBWRpc3RyCQENZGlzdHJpYnV0ZVJlcwQFDGN1cnJlbnRXaFJlcwUOY3VycmVudFBhY2tSZXMFCnJlc1RvQ2xhaW0FC3doU3BhY2VMZWZ0BAR3aEFtCQCXAwEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUJAMwIAggFCnJlc1RvQ2xhaW0CXzIFA25pbAkAlgoECAUFZGlzdHICXzEIBQVkaXN0cgJfMgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUEd2hBbQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQR3aEFtBAV3aFJlcwgFDSR0MDM3MTU2MzgwMjcCXzEEBWJwUmVzCAUNJHQwMzcxNTYzODAyNwJfMgQFbG9mdE8IBQ0kdDAzNzE1NjM4MDI3Al8zBAVsb2Z0RggFDSR0MDM3MTU2MzgwMjcCXzQJAJcKBQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBCAUBYwJfMgUMbmV3VGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgIBQFjAl8yBQRhZGRyBQxuZXdUaW1lc3RhbXAFA25pbAUFYnBLZXkJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQVicFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAUFd2hLZXkJAMwIAgkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzCQDMCAIFBXdoUmVzCQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkAkQMCBQRsb2Z0BQh2b2xUb3RhbAUDbmlsAgFfBQNuaWwBCGNsYWltQWxsBARhZGRyC2xhbmRBc3NldElkBnBpZWNlcwljbGFpbU1vZGUEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBBXZhbHVlAQkAnwgBBQd0aW1lS2V5BAhhdmFpbFJlcwkAaAIJAGsDCQBlAgkBCWZpbmFsVGltZQAFCXNhdmVkVGltZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMFCURBWU1JTExJUwUGcGllY2VzCQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFCGF2YWlsUmVzBQljbGFpbU1vZGUFC2xhbmRBc3NldElkARN1cGRhdGVTdGF0c0ludGVybmFsBAZsdmxLZXkFeHBLZXkJcG9pbnRzS2V5B2RlbHRhWFAEAnhwCQELdmFsdWVPckVsc2UCCQCfCAEFBXhwS2V5AAAEBW5ld1hQCQBkAgUCeHAFB2RlbHRhWFAECWx2bFBvaW50cwkBB2xldmVsVXACCQELdmFsdWVPckVsc2UCCQCfCAEFBmx2bEtleQAABQVuZXdYUAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQZsdmxLZXkJAJEDAgUJbHZsUG9pbnRzAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFBXhwS2V5BQVuZXdYUAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcG9pbnRzS2V5CQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwb2ludHNLZXkAAAkAkQMCBQlsdmxQb2ludHMAAQUDbmlsBQVuZXdYUAEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCC2R1Y2tBc3NldElkB2RlbHRhWFAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULZHVja0Fzc2V0SWQEBGFkZHIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFC2R1Y2tBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMDAwUTS1NfQUxMT1dfUk9CT19EVUNLUwkAAAIIBQVhc3NldAZpc3N1ZXIFBHRoaXMHCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQULUk9CT19QUkVGSVgHCQETdXBkYXRlU3RhdHNJbnRlcm5hbAQJAQxrZXlVc2VyTGV2ZWwBBQRhZGRyCQEJa2V5VXNlclhQAQUEYWRkcgkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgUHZGVsdGFYUAkBE3VwZGF0ZVN0YXRzSW50ZXJuYWwECQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQJAQlrZXlEdWNrWFABBQtkdWNrQXNzZXRJZAkBEWtleUR1Y2tGcmVlUG9pbnRzAQULZHVja0Fzc2V0SWQFB2RlbHRhWFABFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBGFkZHIHZGVsdGFYUAkBE3VwZGF0ZVN0YXRzSW50ZXJuYWwECQEMa2V5VXNlckxldmVsAQUEYWRkcgkBCWtleVVzZXJYUAEFBGFkZHIJARFrZXlVc2VyRnJlZVBvaW50cwEFBGFkZHIFB2RlbHRhWFABEmFjdGl2YXRlT25ib2FyZEFydAEEYWRkcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFBGFkZHIEBXJlZkJ5CQCiCAEFCHJlZkJ5S2V5AwkBASEBCQEJaXNEZWZpbmVkAQUFcmVmQnkJAAIBAilZb3UgYXJlIG5vdCBlbGlnaWJsZSBmb3IgT05CT0FSRCBhcnRpZmFjdAQGYXJ0S2V5CQEca2V5T25ib2FyZEFydER1Y2tBY3RpdmF0ZWRCeQEFBGFkZHIEB2FydER1Y2sJAKIIAQUGYXJ0S2V5AwkBCWlzRGVmaW5lZAEFB2FydER1Y2sJAAIBCQCsAgICL1lvdSBhbHJlYWR5IHVzZWQgeW91ciBPTkJPQVJEIGFydGlmYWN0IG9uIGR1Y2sgCQEFdmFsdWUBBQdhcnREdWNrBBBkdWNrQWN0aXZhdG9yS2V5CQEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawEFC2R1Y2tBc3NldElkBA1kdWNrQWN0aXZhdG9yCQCiCAEFEGR1Y2tBY3RpdmF0b3JLZXkDCQEJaXNEZWZpbmVkAQUNZHVja0FjdGl2YXRvcgkAAgEJAKwCAgkArAICCQCsAgICCVRoZSBkdWNrIAULZHVja0Fzc2V0SWQCNCBhbHJlYWR5IGdvdCBwb2ludHMgZnJvbSBPTkJPQVJEIGFydGlmYWN0IGZyb20gdXNlciAJAQV2YWx1ZQEFDWR1Y2tBY3RpdmF0b3IJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZhcnRLZXkFC2R1Y2tBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFEGR1Y2tBY3RpdmF0b3JLZXkFBGFkZHIFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQl4cE9uYm9hcmQCXzEBEmFjdGl2YXRlUHJlc2FsZUFydAIEYWRkcg1sYW5kQXNzZXRJZEluBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBRNjbGFpbU1vZGVXaFRoZW5EdWNrBQ1sYW5kQXNzZXRJZEluBAtsYW5kQXNzZXRJZAgFAWMCXzIEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBA1hY3RpdmF0aW9uS2V5CQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAMJAGYCCQELdmFsdWVPckVsc2UCCQCfCAEFDWFjdGl2YXRpb25LZXkAAAAACQACAQIlUHJlc2FsZSBhcnRpZmFjdCBpcyBhbHJlYWR5IGFjdGl2YXRlZAMJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAggFAWMCXzMFCnJlY0xhbmROdW0FD1BSRVNBTEVOVU1MQU5EUwkAAgEJAKwCAgkArAICCQCsAgIFCkxBTkRQUkVGSVgCASAFC2xhbmRBc3NldElkAiUgaXMgbm90IGVsaWdpYmxlIGZvciBwcmVzYWxlIGFydGlmYWN0BAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsBAUEYWRkcgULbGFuZEFzc2V0SWQFBnBpZWNlcwUTY2xhaW1Nb2RlV2hUaGVuRHVjawkAzQgCCQDNCAIJAM0IAggFC2NsYWltUmVzdWx0Al8xCQEMSW50ZWdlckVudHJ5AgUNYWN0aXZhdGlvbktleQUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAggFC2NsYWltUmVzdWx0Al81AgE6AQZwcm9sb2cBAWkDAwkBAiE9AggFAWkMb3JpZ2luQ2FsbGVyBQxyZXN0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYXN0VHhJZEJ5VXNlcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAETdW5zdGFrZUxhbmRJbnRlcm5hbAIEYWRkcgtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQIbGFuZEluZm8JALUJAggJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAtkZXNjcmlwdGlvbgIBXwQIbGFuZFNpemUJAJEDAgUIbGFuZEluZm8FC3JlY0xhbmRTaXplBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBBQhsYW5kU2l6ZQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQhsYW5kSW5mbwULcmVjVGVycmFpbnMECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEDGN1cnJlbnRXaFJlcwkAtQkCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMCAV8EB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBEUBleHRyTmF0aXZlKDEwNTUpAQUHdGltZUtleQQJZGVsdGFUaW1lCQBlAgkBCWZpbmFsVGltZQAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIKLCBmaW5hbCA9IAkApAMBCQEJZmluYWxUaW1lAAQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMEDXJlc0FmdGVyQ2xhaW0JAQ92aXJ0Q2xhaW1BZGRSZXMFBQxjdXJyZW50V2hSZXMFDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQPYWNyZXNGcm9tUGllY2VzCQBkAgkAaAIFBnBpZWNlcwUFTVVMVDgJAGkCCQBoAgkAZAIJAGgCBQZwaWVjZXMFCmluZnJhTGV2ZWwFCWFydFBpZWNlcwUFTVVMVDgABQQMYWNyZXNGcm9tUmVzCQBoAgkAawMIBQ1yZXNBZnRlckNsYWltAl8yBRBSRVNPVVJDRVBSSUNFTUlOBQVNVUxUOAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSCgEGc3VtTWF0AgNhY2MEaXRlbQkAZAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQRpdGVtBAV3aE1hdAoAAiRsCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGc3VtTWF0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBAxhY3Jlc0Zyb21NYXQJAGgCCQBrAwUFd2hNYXQJAGgCAAIFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4BRVVU0RUMkFDUkVTX01VTFRJUExJRVIEBXByb2RzAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8KAQdzdW1Qcm9kAgNhY2MEaXRlbQQBaggFA2FjYwJfMgQLcmVjaXBlQ29lZmYJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUBagIBXwUJcklkeENvZWZmCQCUCgIJAGQCCAUDYWNjAl8xCQBoAgkAaAIJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQULcmVjaXBlQ29lZmYFBU1VTFQ2CQBkAgUBagABBAZ3aFByb2QKAAIkbAUFcHJvZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAAACgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdzdW1Qcm9kAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAyNAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAQNYWNyZXNGcm9tUHJvZAkAaAIJAGsDCAUGd2hQcm9kAl8xCQBoAgACBRBSRVNPVVJDRVBSSUNFTUlOBQVNVUxUOAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSCQCWCgQFD2FjcmVzRnJvbVBpZWNlcwUMYWNyZXNGcm9tUmVzBQxhY3Jlc0Zyb21NYXQFDWFjcmVzRnJvbVByb2QBE3Vuc3Rha2VEdWNrSW50ZXJuYWwCBGFkZHILZHVja0Fzc2V0SWQEBWVxS2V5CQEQa2V5RHVja0VxdWlwbWVudAEFC2R1Y2tBc3NldElkBAtjdXJyZW50U2VncwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAIBXwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECXRlbXBQcm9kQgkBBmRyZXNzQgQFC2N1cnJlbnRTZWdzCQEOcHJvZFN0clRvQnl0ZXMBCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QGBQNuaWwECm5ld1Byb2RTdHIJAQ5ieXRlc1RvUHJvZFN0cgEFCXRlbXBQcm9kQgoBCXN1bVJlc01hdAIDYWNjBGl0ZW0JAGQCBQNhY2MJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQFYnBSZXMKAAIkbAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJc3VtUmVzTWF0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBAxhY3Jlc0Zyb21SZXMJAGgCCQBrAwUFYnBSZXMFEFJFU09VUkNFUFJJQ0VNSU4FBU1VTFQ4BRVVU0RUMkFDUkVTX01VTFRJUExJRVIEBWJwTWF0CgACJGwJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8KAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCXN1bVJlc01hdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgQMYWNyZXNGcm9tTWF0CQBoAgkAawMFBWJwTWF0CQBoAgACBRBSRVNPVVJDRVBSSUNFTUlOBQVNVUxUOAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSBAVwcm9kcwMJAAACBQpuZXdQcm9kU3RyAgAFA25pbAkAvAkCBQpuZXdQcm9kU3RyAgFfCgEHc3VtUHJvZAIDYWNjBGl0ZW0EAWoIBQNhY2MCXzIEC3JlY2lwZUNvZWZmCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFAWoCAV8FCXJJZHhDb2VmZgkAlAoCCQBkAggFA2FjYwJfMQkAaAIJAGgCCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0FC3JlY2lwZUNvZWZmBQVNVUxUNgkAZAIFAWoAAQQGYnBQcm9kCgACJGwFBXByb2RzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCAAAAAAoBBSRmMl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHc3VtUHJvZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMjQJAQUkZjJfMgIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgEDWFjcmVzRnJvbVByb2QJAGgCCQBrAwgFBmJwUHJvZAJfMQkAaAIAAgUQUkVTT1VSQ0VQUklDRU1JTgUFTVVMVDgFFVVTRFQyQUNSRVNfTVVMVElQTElFUgkAlQoDBQxhY3Jlc0Zyb21SZXMFDGFjcmVzRnJvbU1hdAUNYWNyZXNGcm9tUHJvZCEBaQENY29uc3RydWN0b3JWMQEIcmVzdEFkZHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5UmVzdEFkZHJlc3MABQhyZXN0QWRkcgUDbmlsAWkBC3NhdmVJbnRlZ2VyAgNrZXkGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIgc2F2ZUludGVnZXIgaXMgbm90IHB1YmxpYyBtZXRob2QJAMwIAgkBDEludGVnZXJFbnRyeQIFA2tleQUGYW1vdW50BQNuaWwBaQEKc2V0QmxvY2tlZAEJaXNCbG9ja2VkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQprZXlCbG9ja2VkAAUJaXNCbG9ja2VkBQNuaWwBaQEJc3Rha2VMYW5kAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKTEFORFBSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUEdGhpcwkAAgECF1Vua25vd24gaXNzdWVyIG9mIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkxBTkRQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAtsYW5kTnVtU2l6ZQkAsAICCAUFYXNzZXQEbmFtZQAEBAdsYW5kTnVtAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCA1hYTAkAswICBQtsYW5kTnVtU2l6ZQADAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCAlhMCQCzAgIFC2xhbmROdW1TaXplAAIJALMCAgULbGFuZE51bVNpemUAAQMJAQEhAQkBCWlzRGVmaW5lZAEJALYJAQUHbGFuZE51bQkAAgEJAKwCAgIeQ2Fubm90IHBhcnNlIGxhbmQgbnVtYmVyIGZyb20gCAUFYXNzZXQEbmFtZQQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAABBAxyZXNCeUNvbnRLZXkJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQkAkQMCBQFkBQxyZWNDb250aW5lbnQECWNvbnRQcm9wcwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFDHJlc0J5Q29udEtleQILMF8wXzBfMF8wXzACAV8EEHVwZGF0ZWRDb250UHJvcHMJALkJAgkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwEBQljb250UHJvcHMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAABAgFfBAhsYW5kc0tleQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFB2FkZHJlc3MECGxhbmRzU3RyCQCiCAEFCGxhbmRzS2V5BAVsYW5kcwMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBWxhbmRzBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIiWW91ciBzdGFrZWQgbGFuZHMgYWxyZWFkeSBjb250YWluIAULbGFuZEFzc2V0SWQDCQBnAgkAkAMBBQVsYW5kcwUYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSCQACAQkArAICCQCsAgICGVlvdXIgYWxyZWFkeSBzdGFrZWQgbWF4ICgJAKQDAQUYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSAgcpIGxhbmRzBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFB2FkZHJlc3MECW9sZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAQJd2xnUmVzdWx0CQD8BwQFC3dsZ0NvbnRyYWN0AhJvblN0YWtlVW5zdGFrZUxhbmQJAMwIAgUHYWRkcmVzcwUDbmlsBQNuaWwJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkAzQgCBQVsYW5kcwULbGFuZEFzc2V0SWQCAV8JAMwIAgkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQkAZAIFCW9sZFBpZWNlcwUGcGllY2VzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtBQdhZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFB2FkZHJlc3MFCmluZnJhTGV2ZWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AgUMcmVzQnlDb250S2V5BRB1cGRhdGVkQ29udFByb3BzBQNuaWwFDXByb2xvZ0FjdGlvbnMFCXdsZ1Jlc3VsdAFpAQt1bnN0YWtlTGFuZAENbGFuZEFzc2V0SWRJbgQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQBZAgFAWMCXzMECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wEEDHJlc0J5Q29udEtleQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCQCRAwIFAWQFDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMcmVzQnlDb250S2V5AgswXzBfMF8wXzBfMAIBXwQQdXBkYXRlZENvbnRQcm9wcwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wECAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQOZ292UmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgUOZ292UmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI5WW91ciBnV0wgYXJlIHRha2luZyBwYXJ0IGluIHZvdGluZywgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmdvdlJlbGVhc2VUaW1lBA5hcmJSZWxlYXNlVGltZQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgULd2xnQ29udHJhY3QJARRrZXlMYXN0QXJiVGltZUJ5VXNlcgEFBGFkZHIAAAUOYXJiaXRyYWdlRGVsYXkDCQBmAgUOYXJiUmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI/WW91ciBzdGFrZWQgbGFuZHMgdG9vayBwYXJ0IGluIGFyYml0cmFnZSwgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmFyYlJlbGVhc2VUaW1lBAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgQMc3Rha2VkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAABAluZXdQaWVjZXMDCQBmAgUGcGllY2VzBQxzdGFrZWRQaWVjZXMAAAkAZQIFDHN0YWtlZFBpZWNlcwUGcGllY2VzBAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQRhZGRyBQNuaWwFA25pbAkAlAoCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEJANkEAQULbGFuZEFzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAFBXByb3BzCQDMCAIJAQtTdHJpbmdFbnRyeQIFDHJlc0J5Q29udEtleQUQdXBkYXRlZENvbnRQcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQDMCAIDCQBmAgkAkAMBBQVsYW5kcwABCQELU3RyaW5nRW50cnkCBQhsYW5kc0tleQkAuwkCCQDRCAIFBWxhbmRzCQEFdmFsdWUBBQNpZHgCAV8JAQtEZWxldGVFbnRyeQEFCGxhbmRzS2V5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlwaWVjZXNLZXkFCW5ld1BpZWNlcwUDbmlsBQ1wcm9sb2dBY3Rpb25zBQl3bGdSZXN1bHQBaQETdW5zdGFrZUxhbmRDYWxsYmFjawILbGFuZEFzc2V0SWQEYWRkcgMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyBRBhY3JlczJBZGRyZXNzU3RyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEDXVuc3Rha2VSZXN1bHQJARN1bnN0YWtlTGFuZEludGVybmFsAgUEYWRkcgULbGFuZEFzc2V0SWQECXdsZ1Jlc3VsdAkA/AcEBQt3bGdDb250cmFjdAISb25TdGFrZVVuc3Rha2VMYW5kCQDMCAIFBGFkZHIFA25pbAUDbmlsCQCUCgIJAMwIAgkBBEJ1cm4CCQDZBAEFC2xhbmRBc3NldElkAAEJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyBQNuaWwJAJcKBQgFDXVuc3Rha2VSZXN1bHQCXzEIBQ11bnN0YWtlUmVzdWx0Al8yCAUNdW5zdGFrZVJlc3VsdAJfMwgFDXVuc3Rha2VSZXN1bHQCXzQFCXdsZ1Jlc3VsdAFpARN1bnN0YWtlTGFuZFJFQURPTkxZAgtsYW5kQXNzZXRJZARhZGRyBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUxhbmRJbnRlcm5hbAIFBGFkZHIFC2xhbmRBc3NldElkCQCUCgIFA25pbAUNdW5zdGFrZVJlc3VsdAFpARx1bnN0YWtlTGFuZHNGaW5hbGl6ZUNhbGxiYWNrAQRhZGRyAwkBAiE9AgkApQgBCAUBaQZjYWxsZXIFEGFjcmVzMkFkZHJlc3NTdHIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtEZWxldGVFbnRyeQEJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgUDbmlsAAABaQEUY29udmVydFVuc3Rha2VkTGFuZHMAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFBHRoaXMJAAIBAhdVbmtub3duIGlzc3VlciBvZiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkxBTkRQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpMQU5EUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQLYWNyZXNBbW91bnQJAGQCCQBoAgUGcGllY2VzBQVNVUxUOAkAaQIJAGgCCQBkAgkAaAIFBnBpZWNlcwUKaW5mcmFMZXZlbAUJYXJ0UGllY2VzBQVNVUxUOAAFBANyZXEJAPwHBAUNYWNyZXNDb250cmFjdAIUcmVxdWVzdEFjcmVzQ2FsbGJhY2sJAMwIAgULYWNyZXNBbW91bnQFA25pbAUDbmlsAwkAAAIFA3JlcQUDcmVxBAVjYWxsYgkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBBRBhY3JlczJBZGRyZXNzU3RyAhJzdGFrZUFjcmVzQ2FsbGJhY2sJAMwIAgUHYWRkcmVzcwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQxhY3Jlc0Fzc2V0SWQFC2FjcmVzQW1vdW50BQNuaWwDCQAAAgUFY2FsbGIFBWNhbGxiCQCUCgIJAMwIAgkBBEJ1cm4CCQDZBAEFC2xhbmRBc3NldElkAAEFA25pbAAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE3Vuc3Rha2VEdWNrQ2FsbGJhY2sCC2R1Y2tBc3NldElkBGFkZHIDCQECIT0CCQClCAEIBQFpBmNhbGxlcgUQYWNyZXMyQWRkcmVzc1N0cgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUR1Y2tJbnRlcm5hbAIFBGFkZHIFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUEYWRkcgABCQDZBAEFC2R1Y2tBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULZHVja0Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBEGtleUR1Y2tJZFRvT3duZXIBBQtkdWNrQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkRVQ0tQUkVGSVgFC2R1Y2tBc3NldElkBQRhZGRyCQDMCAIJAQtEZWxldGVFbnRyeQEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHIFA25pbAUNdW5zdGFrZVJlc3VsdAFpARN1bnN0YWtlRHVja1JFQURPTkxZAgtkdWNrQXNzZXRJZARhZGRyBA11bnN0YWtlUmVzdWx0CQETdW5zdGFrZUR1Y2tJbnRlcm5hbAIFBGFkZHIFC2R1Y2tBc3NldElkCQCUCgIFA25pbAUNdW5zdGFrZVJlc3VsdAFpAQhjbGFpbVJlcwIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAUNY2xhaW1Nb2RlRHVjawUObGFuZEFzc2V0SWRTdHIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM0IAgkAzQgCCQDOCAIIBQZyZXN1bHQCXzEICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzMFCGJwSWR4UmVzAWkBDGNsYWltUmVzVG9XSAIGYW1vdW50DmxhbmRBc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAULY2xhaW1Nb2RlV2gFDmxhbmRBc3NldElkU3RyCQCUCgIJAM4IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQ1wcm9sb2dBY3Rpb25zCQCRAwIIBQZyZXN1bHQCXzUFCHdoSWR4UmVzAWkBDnVwZGF0ZUJhY2twYWNrAgtkdWNrQXNzZXRJZAduZXdQYWNrAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBQduZXdQYWNrBQNuaWwFB25ld1BhY2sBaQEPY29tbWl0Rm9yUmFuZG9tAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEC2ZpbmlzaEJsb2NrCQBkAgUGaGVpZ2h0BQtyYW5kb21EZWxheQQEYWRkcgkApQgBCAUBaQZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJa2V5Q29tbWl0AQUEYWRkcgULZmluaXNoQmxvY2sFA25pbAUNcHJvbG9nQWN0aW9ucwULZmluaXNoQmxvY2sBaQEMcmV2ZWFsUmFuZG9tAQhtYXhWYWx1ZQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAlmaW5pc2hLZXkJAQlrZXlDb21taXQBBQRhZGRyBAtmaW5pc2hCbG9jawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFCWZpbmlzaEtleQIkWW91IGhhdmUgdG8gY29tbWl0Rm9yUmFuZG9tKCkgZmlyc3QhAwkAZgIFC2ZpbmlzaEJsb2NrBQZoZWlnaHQJAAIBCQCsAgICNFJhbmRvbSBudW1iZXIgaXMgbm90IHJlYWR5IHlldCwgd2FpdCB1bnRpbCBoZWlnaHQgPSAJAKQDAQULZmluaXNoQmxvY2sEB2VudHJvcHkJAQV2YWx1ZQEICQEFdmFsdWUBCQDtBwEFC2ZpbmlzaEJsb2NrA3ZyZgQEc2FsdAkAmwMBCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlMYXN0VHhJZEJ5VXNlcgEFBGFkZHICAAQEcmFuZAkBD2dldFJhbmRvbU51bWJlcgMFCG1heFZhbHVlBQRzYWx0BQdlbnRyb3B5CQCUCgIJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBBQlmaW5pc2hLZXkFA25pbAUNcHJvbG9nQWN0aW9ucwUEcmFuZAFpARBhY3RpdmF0ZUFydGlmYWN0AgdhcnROYW1lDmxhbmRBc3NldElkT3B0BA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpBmNhbGxlcgQGcmVzdWx0BAckbWF0Y2gwBQdhcnROYW1lAwkAAAICB1BSRVNBTEUFByRtYXRjaDAJARJhY3RpdmF0ZVByZXNhbGVBcnQCBQRhZGRyBQ5sYW5kQXNzZXRJZE9wdAMJAAACAgdPTkJPQVJEBQckbWF0Y2gwCQESYWN0aXZhdGVPbmJvYXJkQXJ0AQUEYWRkcgkAAgECEFVua25vd24gYXJ0aWZhY3QJAM4IAgUGcmVzdWx0BQ1wcm9sb2dBY3Rpb25zAWkBDXNhdmVXYXJlaG91c2UCBXdoU3RyC2xhbmRBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBAJ3aAkAvAkCBQV3aFN0cgIBOgMJAQIhPQIJAJADAQUCd2gABQkAAgECMHdhcmVob3VzZSBzdHJpbmcgc2hvdWxkIGNvbnRhaW4gNCAnOicgc2VwYXJhdG9ycwQFbG9mdEwJAJEDAgkAtQkCCQCRAwIFAndoBQl3aElkeExPRlQCAV8FCXZvbExvY2tlZAQFbG9mdE8JARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEFAndoBAVsb2Z0VAkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQkAkQMCBQJ3aAULd2hJZHhMZXZlbHMEBWxvZnRGCQBlAgkAZQIFBWxvZnRUCQENcGFyc2VJbnRWYWx1ZQEFBWxvZnRMBQVsb2Z0TwMJAGYCAAAFBWxvZnRGCQACAQIwT3BlcmF0aW9uIGxlYWRzIHRvIG5lZ2F0aXZlIGZyZWUgd2FyZWhvdXNlIHNwYWNlBAhuZXdXaFN0cgkAugkCCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUCd2gFCHdoSWR4UmVzCQDMCAIJAJEDAgUCd2gFCHdoSWR4TWF0CQDMCAIJAJEDAgUCd2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgUFbG9mdEwJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAKQDAQUFbG9mdFQFA25pbAIBXwUDbmlsAgE6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkFCG5ld1doU3RyBQNuaWwFCG5ld1doU3RyAWkBDXNldEN1c3RvbU5hbWUDB2Fzc2V0SWQKY3VzdG9tTmFtZQR0eXBlBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECGkFsbG93ZWQgVVNEVCBwYXltZW50IG9ubHkhAwkBAiE9AggFA3BtdAZhbW91bnQFDFJFTkFNSU5HQ09TVAkAAgEJAKwCAgISUGF5bWVudCBzaG91bGQgYmUgCQCkAwEFDFJFTkFNSU5HQ09TVAMJAQhjb250YWlucwIFCmN1c3RvbU5hbWUCAl9fCQACAQkArAICAh5OYW1lIHNob3VsZCBub3QgY29udGFpbiAnX18nOiAFCmN1c3RvbU5hbWUDCQBmAgkAsQIBBQpjdXN0b21OYW1lBQpNQVhOQU1FTEVOCQACAQkArAICAhlOYW1lIHRvbyBsb25nLCBtYXhMZW5ndGg9CQCkAwEFCk1BWE5BTUVMRU4EBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAdhY3Rpb25zBAckbWF0Y2gwBQR0eXBlAwkAAAICB0FDQ09VTlQFByRtYXRjaDAECnJldmVyc2VLZXkJARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQUKY3VzdG9tTmFtZQQJbmFtZU93bmVyCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUJbmFtZU93bmVyCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lBA1hZGRyVG9OYW1lS2V5CQEWa2V5QWRkcmVzc1RvQ3VzdG9tTmFtZQEFBGFkZHIEB29sZE5hbWUJAKIIAQUNYWRkclRvTmFtZUtleQQHZnJlZU9sZAMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQkBBXZhbHVlAQUHb2xkTmFtZQUDbmlsBQNuaWwJAM4IAgkAzQgCCQDNCAIFB2ZyZWVPbGQJAQtTdHJpbmdFbnRyeQIFDWFkZHJUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFBGFkZHIICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIFDHhwQ3VzdG9tTmFtZQJfMQMJAAACAgRMQU5EBQckbWF0Y2gwBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUHYXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAggFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQdhc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBApyZXZlcnNlS2V5CQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lBAluYW1lT3duZXIJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQluYW1lT3duZXIJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUEDmFzc2V0VG9OYW1lS2V5CQEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBBQdhc3NldElkBAdvbGROYW1lCQCiCAEFDmFzc2V0VG9OYW1lS2V5BAdmcmVlT2xkAwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQkBBXZhbHVlAQUHb2xkTmFtZQUDbmlsBQNuaWwJAM4IAgkAzQgCCQDNCAIFB2ZyZWVPbGQJAQtTdHJpbmdFbnRyeQIFDmFzc2V0VG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQdhc3NldElkCAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyBQx4cEN1c3RvbU5hbWUCXzEDCQAAAgIERFVDSwUHJG1hdGNoMAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFB2Fzc2V0SWQDAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5BgkBASEBCQEJaXNEZWZpbmVkAQkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyCQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQdhc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpEVUNLUFJFRklYAg0gaXMgbm90IHlvdXJzBApyZXZlcnNlS2V5CQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lBAluYW1lT3duZXIJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQluYW1lT3duZXIJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUEDmFzc2V0VG9OYW1lS2V5CQEaa2V5RHVja0Fzc2V0SWRUb0N1c3RvbU5hbWUBBQdhc3NldElkBAdvbGROYW1lCQCiCAEFDmFzc2V0VG9OYW1lS2V5BAdmcmVlT2xkAwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQkBBXZhbHVlAQUHb2xkTmFtZQUDbmlsBQNuaWwJAM4IAgkAzQgCCQDNCAIFB2ZyZWVPbGQJAQtTdHJpbmdFbnRyeQIFDmFzc2V0VG9OYW1lS2V5BQpjdXN0b21OYW1lCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQdhc3NldElkCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgUHYXNzZXRJZAUMeHBDdXN0b21OYW1lAl8xCQACAQITVW5rbm93biBlbnRpdHkgdHlwZQkAlAoCCQDOCAIJAM0IAgUHYWN0aW9ucwkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQFDXByb2xvZ0FjdGlvbnMAAAFpAQxzZXRSZWZlcnJhbHMCCW9sZFBsYXllcgluZXdQbGF5ZXIDCQECIT0CCAUBaQ9jYWxsZXJQdWJsaWNLZXkFA3B1YgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkAwkBASEBCQEJaXNEZWZpbmVkAQkApggBBQlvbGRQbGF5ZXIJAAIBCQCsAgICEUludmFsaWQgYWRkcmVzczogBQlvbGRQbGF5ZXIECm5ld2JpZUFkZHIJAKYIAQUJbmV3UGxheWVyAwkBASEBCQEJaXNEZWZpbmVkAQUKbmV3YmllQWRkcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW5ld1BsYXllcgQJb2xkTGFzdFR4CQCiCAEJARFrZXlMYXN0VHhJZEJ5VXNlcgEFCW9sZFBsYXllcgMJAQEhAQkBCWlzRGVmaW5lZAEFCW9sZExhc3RUeAkAAgECIm9sZFBsYXllciBkaWRuJ3QgZG8gYW55IHR4IGluIGdhbWUDCQBnAgAACAkA7wcBCQEFdmFsdWUBBQpuZXdiaWVBZGRyCWF2YWlsYWJsZQkAAgECFm5ld1BsYXllciBoYXMgbm8gV0FWRVMEB29sZHNLZXkJAQlrZXlPbGRpZXMABARvbGRzCQCiCAEFB29sZHNLZXkEBm9sZGllcwMJAQlpc0RlZmluZWQBBQRvbGRzCQC8CQIJAQV2YWx1ZQEFBG9sZHMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQZvbGRpZXMFCW5ld1BsYXllcgkAAgEJAKwCAgUJbmV3UGxheWVyAiYgaXMgbm90IG5ld2JpZSAoYWxyZWFkeSBoYXMgcmVmZXJyYWxzKQQIcmVmQnlLZXkJAQ9rZXlBZGRyZXNzUmVmQnkBBQluZXdQbGF5ZXIEBXJlZkJ5CQCiCAEFCHJlZkJ5S2V5AwMJAQlpc0RlZmluZWQBBQVyZWZCeQkBCWlzRGVmaW5lZAEJAKYIAQkBBXZhbHVlAQUFcmVmQnkHCQACAQkArAICCQCsAgIFCW5ld1BsYXllcgIUIGFscmVhZHkgaGFzIHJlZkJ5OiAJAQV2YWx1ZQEFBXJlZkJ5BAdyZWZzS2V5CQETa2V5QWRkcmVzc1JlZmVycmFscwEFCW9sZFBsYXllcgQEcmVmcwkAoggBBQdyZWZzS2V5BAlyZWZzQXJyYXkDCQEJaXNEZWZpbmVkAQUEcmVmcwkAvAkCCQEFdmFsdWUBBQRyZWZzAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUJcmVmc0FycmF5BQluZXdQbGF5ZXIJAAIBCQCsAgIJAKwCAgkArAICBQlvbGRQbGF5ZXICEiBhbHJlYWR5IGNvbnRhaW5zIAUJbmV3UGxheWVyAhEgd2l0aGluIHJlZmVycmFscwQHbmV3UmVmcwkAugkCCQDNCAIFCXJlZnNBcnJheQUJbmV3UGxheWVyAgFfBAduZXdPbGRzAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJb2xkUGxheWVyCQEFdmFsdWUBBQRvbGRzCQC6CQIJAM0IAgUGb2xkaWVzBQlvbGRQbGF5ZXICAV8JAJQKAgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHJlZkJ5S2V5BQlvbGRQbGF5ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHcmVmc0tleQUHbmV3UmVmcwkAzAgCCQELU3RyaW5nRW50cnkCBQdvbGRzS2V5BQduZXdPbGRzBQNuaWwFDXByb2xvZ0FjdGlvbnMAAAFpARBkaXN0cmlidXRlUG9pbnRzBQhzdHJlbmd0aAhhY2N1cmFjeQlpbnRlbGxlY3QJZW5kdXJhbmNlCWRleHRlcml0eQQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC3ZpcnRXbGdEYXRhCQEJYXNBbnlMaXN0AQkA/AcEBQt3bGdDb250cmFjdAISY2hlY2tXbGdYcFJFQURPTkxZCQDMCAIFBGFkZHIFA25pbAUDbmlsBA12aXJ0V2xnUG9pbnRzCQEFYXNJbnQBCQCRAwIFC3ZpcnRXbGdEYXRhAAEEDyR0MDEwMDIyODEwMDYxOAMJAGcCAAAFDXZpcnRXbGdQb2ludHMJAJQKAgAABQNuaWwEB2RlbHRhWFAJAQVhc0ludAEJAPwHBAULd2xnQ29udHJhY3QCCXRha2VXbGdYcAkAzAgCBQRhZGRyBQNuaWwFA25pbAMJAAACBQdkZWx0YVhQBQdkZWx0YVhQCQCUCgIFDXZpcnRXbGdQb2ludHMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQxrZXlVc2VyTGV2ZWwBBQRhZGRyCQEFYXNJbnQBCQCRAwIFC3ZpcnRXbGdEYXRhAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQlrZXlVc2VyWFABBQRhZGRyCQEFYXNJbnQBCQCRAwIFC3ZpcnRXbGdEYXRhAAIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQJd2xnUG9pbnRzCAUPJHQwMTAwMjI4MTAwNjE4Al8xBAp3bGdBY3Rpb25zCAUPJHQwMTAwMjI4MTAwNjE4Al8yBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECmZyZWVLZXlBY2MJARFrZXlVc2VyRnJlZVBvaW50cwEFBGFkZHIEDWZyZWVQb2ludHNBY2MJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFCmZyZWVLZXlBY2MAAAUJd2xnUG9pbnRzBAtmcmVlS2V5RHVjawkBEWtleUR1Y2tGcmVlUG9pbnRzAQULZHVja0Fzc2V0SWQEDmZyZWVQb2ludHNEdWNrCQELdmFsdWVPckVsc2UCCQCfCAEFC2ZyZWVLZXlEdWNrAAAEB3N1bUZyZWUJAGQCBQ1mcmVlUG9pbnRzQWNjBQ5mcmVlUG9pbnRzRHVjawQPc3VtVG9EaXN0cmlidXRlCQBkAgkAZAIJAGQCCQBkAgUIc3RyZW5ndGgFCGFjY3VyYWN5BQlpbnRlbGxlY3QFCWVuZHVyYW5jZQUJZGV4dGVyaXR5AwkAZgIFD3N1bVRvRGlzdHJpYnV0ZQUHc3VtRnJlZQkAAgEJAKwCAgkArAICAg9UaGVyZSBhcmUgb25seSAJAKQDAQUHc3VtRnJlZQIaIGZyZWUgcG9pbnRzIHRvIGRpc3RyaWJ1dGUECGNoYXJzS2V5CQEMa2V5RHVja0NoYXJzAQULZHVja0Fzc2V0SWQEBWNoYXJzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIY2hhcnNLZXkCCTBfMF8wXzBfMAIBXwQGbmV3QWNjCQBlAgUNZnJlZVBvaW50c0FjYwUPc3VtVG9EaXN0cmlidXRlCQCUCgIJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQpmcmVlS2V5QWNjAwkAZgIAAAUGbmV3QWNjAAAFBm5ld0FjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgULZnJlZUtleUR1Y2sDCQBmAgAABQZuZXdBY2MJAGQCBQ5mcmVlUG9pbnRzRHVjawUGbmV3QWNjBQ5mcmVlUG9pbnRzRHVjawkAzAgCCQELU3RyaW5nRW50cnkCBQhjaGFyc0tleQkAuQkCCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhclN0cmVuZ3RoBQhzdHJlbmd0aAkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDGNoYXJBY2N1cmFjeQUIYWNjdXJhY3kJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFySW50ZWxsZWN0BQlpbnRlbGxlY3QJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRW5kdXJhbmNlBQllbmR1cmFuY2UJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRGV4dGVyaXR5BQlkZXh0ZXJpdHkFA25pbAIBXwUDbmlsBQ1wcm9sb2dBY3Rpb25zBQp3bGdBY3Rpb25zAAABaQEcc3BsaXRCeUdsb2JhbFdlaWdodHNSRUFET05MWQEGYW1vdW50CQCUCgIFA25pbAkBEmdldE5lZWRlZE1hdGVyaWFscwEFBmFtb3VudAFpASRzcGxpdEJ5R2xvYmFsQW5kTG9jYWxXZWlnaHRzUkVBRE9OTFkDCW1hdEFtb3VudAlyZXNBbW91bnQIdGVycmFpbnMEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQUIdGVycmFpbnMJAJQKAgUDbmlsCQCUCgIJARJnZXROZWVkZWRNYXRlcmlhbHMBBQltYXRBbW91bnQJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUJcmVzQW1vdW50BQ10ZXJyYWluQ291bnRzAWkBE2dldEJhY2twYWNrUkVBRE9OTFkBC2R1Y2tBc3NldElkCQCUCgIFA25pbAkAuQkCCQELZ2V0QmFja3BhY2sBCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAIBOgFpARRnZXRXYXJlaG91c2VSRUFET05MWQELbGFuZEFzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAACQCUCgIFA25pbAkAugkCCQEMZ2V0V2FyZWhvdXNlAwkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwCAToBaQEKc2F2ZUxhc3RUeAADCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFC3dsZ0NvbnRyYWN0CQDMCAIFD2Vjb25vbXlDb250cmFjdAkAzAgCBRJ0b3VybmFtZW50Q29udHJhY3QJAMwIAgUNYWNyZXNDb250cmFjdAUDbmlsCAUBaQZjYWxsZXIJAAIBAg1BY2Nlc3MgZGVuaWVkCQCUCgIJAQZwcm9sb2cBBQFpACoBaQEPdXBkYXRlRHVja1N0YXRzAgtkdWNrQXNzZXRJZAdkZWx0YVhQAwkBAiE9AggFAWkGY2FsbGVyBQ9lY29ub215Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkCQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAUHZGVsdGFYUAFpAQ51cGRhdGVBY2NTdGF0cwIEYWRkcgdkZWx0YVhQAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQt3bGdDb250cmFjdAkAzAgCBQ9lY29ub215Q29udHJhY3QJAMwIAgUNYWNyZXNDb250cmFjdAUDbmlsCAUBaQZjYWxsZXIJAAIBAg1BY2Nlc3MgZGVuaWVkCQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIFB2RlbHRhWFABaQETaW5pdER1Y2tUb3VyQXR0ZW1wdAELZHVja0Fzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFEnRvdXJuYW1lbnRDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAljdXJIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAQJY3VyTG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1ckxvY0tleQUPREVGQVVMVExPQ0FUSU9OBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUSdG91cm5hbWVudENvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEDHRvdXJMb2NhdGlvbgkArAICCQCkAwEFBmxhc3RJZAIEX1RfMAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAUJY3VySGVhbHRoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFBW1heEhQCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQFC2N1ckxvY2F0aW9uCQDMCAIJAQtTdHJpbmdFbnRyeQIFCWN1ckxvY0tleQUMdG91ckxvY2F0aW9uBQNuaWwFDHRvdXJMb2NhdGlvbgFpAQxicmVha0F0dGVtcHQABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJY3VyTG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1ckxvY0tleQUPREVGQVVMVExPQ0FUSU9OAwkBAiE9AgkAkQMCCQC1CQIFC2N1ckxvY2F0aW9uAgFfBQpsb2NJZHhUeXBlAgFUCQACAQIiWW91ciBkdWNrIGlzIG5vdCBpbiB0aGUgdG91cm5hbWVudAQLc2F2ZWRIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBA1zYXZlZExvY2F0aW9uCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQCUCgIJAM0IAgkAzQgCBQ1wcm9sb2dBY3Rpb25zCQEMSW50ZWdlckVudHJ5AgkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAULc2F2ZWRIZWFsdGgJAQtTdHJpbmdFbnRyeQIFCWN1ckxvY0tleQUNc2F2ZWRMb2NhdGlvbgULY3VyTG9jYXRpb24BaQEUYnJlYWtBdHRlbXB0Q2FsbGJhY2sAAwkBAiE9AggFAWkGY2FsbGVyBRJ0b3VybmFtZW50Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUDbmlsAhRicmVha0F0dGVtcHRDYWxsYmFjawFpARZleGl0VG91cm5hbWVudEludGVybmFsAQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDUFjY2VzcyBkZW5pZWQEC3NhdmVkSGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAQNc2F2ZWRMb2NhdGlvbgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkAzAgCCQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFDXNhdmVkTG9jYXRpb24FA25pbAcBaQEPcHJvY2Vzc0RlbGl2ZXJ5AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDUFjY2VzcyBkZW5pZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAlmdW5kVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPZWNvbm9teUNvbnRyYWN0BQ9kZWxpdmVyeUZ1bmRLZXkAAAMJAGYCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFCWZ1bmRUb3RhbAkAAgEJAKwCAgIgRGVsaXZlcnkgaXMgbm90IGF2YWlsYWJsZSwgZnVuZD0JAQpmaXhlZFBvaW50AgUJZnVuZFRvdGFsAAYEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAECGNvdW50S2V5CQEUa2V5VXNlckRlbGl2ZXJ5Q291bnQBBQRhZGRyBAdsYXN0RGF5CQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlVc2VyTGFzdERlbGl2ZXJ5RGF5AQUEYWRkcgAABAV0b2RheQkAaQIFA25vdwUJREFZTUlMTElTBAVjb3VudAMJAAACBQdsYXN0RGF5BQV0b2RheQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQhjb3VudEtleQAAAAAEBWFjcmVzCQELdmFsdWVPckVsc2UCCQCaCAIFDWFjcmVzQ29udHJhY3QJARprZXlBY3Jlc1N0YWtlZEFtb3VudEJ5VXNlcgEFBGFkZHIAAAQRYWxsb3dlZERlbGl2ZXJpZXMJAGQCBRdBTExPV0VEX0ZSRUVfREVMSVZFUklFUwkAaQIFBWFjcmVzBRpBQ1JFU19GT1JfREVMSVZFUllfQVRURU1QVAMJAGcCBQVjb3VudAURYWxsb3dlZERlbGl2ZXJpZXMJAAIBCQCsAgIJAKwCAgIRWW91IGFscmVhZHkgdXNlZCAJAKQDAQURYWxsb3dlZERlbGl2ZXJpZXMCHCBkZWxpdmVyeSBhdHRlbXB0cyBmb3IgdG9kYXkEDmdsb2JhbENvdW50S2V5CQEUa2V5RHVja0RlbGl2ZXJ5Q291bnQBBQtkdWNrQXNzZXRJZAQGcmV3YXJkCQD8BwQFD2Vjb25vbXlDb250cmFjdAISc2VuZERlbGl2ZXJ5UmV3YXJkCQDMCAIFBGFkZHIFA25pbAUDbmlsCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFCGNvdW50S2V5CQBkAgUFY291bnQAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleVVzZXJMYXN0RGVsaXZlcnlEYXkBBQRhZGRyBQV0b2RheQkAzAgCCQEMSW50ZWdlckVudHJ5AgUOZ2xvYmFsQ291bnRLZXkJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFDmdsb2JhbENvdW50S2V5AAAAAQUDbmlsBQZyZXdhcmQAcpicIw==", "height": 3371415, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: APzGFXMxYcCpJKgTZnDnCT5jPAtcW6GkPzoi98xVbAmS Next: H2z1QR1j7NPRg9kvAtCCXxeK6dqVzKQGHqLfSy5cpp5Y Diff:
OldNewDifferences
33 {-# CONTENT_TYPE DAPP #-}
44 let KS_SEPARATE_PUBLIC_KEY = false
55
6-let KS_ALLOW_BIG_INFRA_MERGE = false
7-
86 let KS_ALLOW_ROBO_DUCKS = false
97
108 let DAY_MILLIS = 86400000
119
12-let OLD_STAKING_DEADLINE = 1727740799000
10+let OLD_STAKING_DEADLINE = 1731279600000
1311
1412 let chain = take(drop(this.bytes, 1), 1)
1513
5149 else throw("Unknown chain")
5250 }
5351
54-let InfraUpgradeCostS = match chain {
55- case _ =>
56- if ((base58'2W' == $match0))
57- then 10000000000
58- else if ((base58'2T' == $match0))
59- then 100000000
60- else throw("Unknown chain")
61-}
62-
6352 let arbitrageDelay = match chain {
6453 case _ =>
6554 if ((base58'2W' == $match0))
9079 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
9180
9281
93-let IdxCfgStakingDapp = 1
94-
9582 let IdxCfgEconomyDapp = 2
9683
9784 let IdxCfgGovernanceDapp = 3
118105
119106 let restCfg = readRestCfgOrFail(restContract)
120107
121-let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
122-
123108 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
124109
125110 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
137122 let recTerrains = 2
138123
139124 let recContinent = 3
140-
141-let wlgAssetIdKey = "wlg_assetId"
142-
143-let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
144125
145126 let acresAssetIdKey = "acresAssetId"
146127
163144 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
164145
165146
166-func asString (v) = match v {
167- case s: String =>
168- s
169- case _ =>
170- throw("fail to cast into String")
171-}
172-
173-
174147 func asInt (v) = match v {
175148 case n: Int =>
176149 n
184157 l
185158 case _ =>
186159 throw("fail to cast into List[Any]")
187-}
188-
189-
190-func asBoolean (v) = match v {
191- case s: Boolean =>
192- s
193- case _ =>
194- throw("fail to cast into Boolean")
195160 }
196161
197162
209174 then XXLSIZE
210175 else throw("Unknown land size")
211176 }
212-
213-
214-func isDigit (s) = isDefined(parseInt(s))
215177
216178
217179 func keyBlocked () = "contractsBlocked"
259221
260222 let RESOURCEPRICEMIN = 39637
261223
262-let ESSELLCOEF = 10
263-
264224 let MIN_USDT_FEE_DELIVERY = 50000
265225
266226 let USDT2ACRES_MULTIPLIER = 10
267-
268-let MIN_WLGOLD_ROBBERY = 100000000
269-
270-let ALLOWED_FREE_ROBBERIES = 0
271-
272-let ACRES_FOR_ROBBERY_ATTEMPT = 200000000
273227
274228 let ALLOWED_FREE_DELIVERIES = 0
275229
277231
278232 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3", "Boom-Dog L1", "Boom-Dog L2", "Boom-Dog L3"]
279233
280-let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
281-
282-let COEFF2MAT = 10000000
283-
284234 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_", "23_23_5_20_23_6_35_2_100_0,0,0,0,0,0,0_", "23_23_5_20_23_6_70_2_150_0,0,0,0,0,0,0_", "23_23_5_20_23_6_105_2_200_0,0,0,0,0,0,0_"]
285235
286236 let rIdxCoeff = 6
287-
288-let rIdxEffect = 8
289237
290238 let rIdxRequirements = 9
291239
318266 let bpIdxMat = 2
319267
320268 let bpIdxProd = 3
321-
322-let locIdxContinent = 0
323269
324270 let locIdxType = 1
325271
379325 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
380326
381327
382-func keyEsWarehouse () = "emergencyWarehouseProducts"
383-
384-
385328 let deliveryFundKey = "deliveryFund"
386329
387330 let lastTourIdKey = "%s__lastTourId"
388-
389-func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
390-
391-
392-func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
393-
394-
395-func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
396-
397-
398-let idxStatic = 0
399-
400-let idxDynamic = 1
401-
402-let tStaticEnd = 6
403-
404-let tDynamicStatus = 1
405-
406-func getTourData (tourContract,tId) = {
407- let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
408- let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
409-[static, dynamic]
410- }
411-
412-
413-func isInTournament (tourContract,location) = {
414- let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
415- let loc = split(location, "_")
416- let now = lastBlock.timestamp
417- let tData = getTourData(tourContract, lastId)
418- let static = tData[idxStatic]
419- let dynamic = tData[idxDynamic]
420- if (if (if ((loc[locIdxType] == "T"))
421- then (parseIntValue(loc[locIdxContinent]) == lastId)
422- else false)
423- then (dynamic[tDynamicStatus] == "INPROGRESS")
424- else false)
425- then (parseIntValue(static[tStaticEnd]) > now)
426- else false
427- }
428-
429-
430-func onMission (tourContract,location) = {
431- let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
432- let loc = split(location, "_")
433- let now = lastBlock.timestamp
434- let tData = getTourData(tourContract, lastId)
435- let static = tData[idxStatic]
436- let dynamic = tData[idxDynamic]
437- let locType = loc[locIdxType]
438- if (if (if ((loc[locIdxType] == "T"))
439- then (parseIntValue(loc[locIdxContinent]) == lastId)
440- else false)
441- then (dynamic[tDynamicStatus] == "INPROGRESS")
442- else false)
443- then (parseIntValue(static[tStaticEnd]) > now)
444- else false
445- }
446-
447-
448-func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
449-
450-
451-func cheatAttempt (oldLoc,newLoc,cheatCase) = throw(((((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc) + ", case=") + toString(cheatCase)))
452-
453331
454332 let SCALE8 = 100000000
455333
470348 let charEndurance = 3
471349
472350 let charDexterity = 4
473-
474-let segBackpack = 0
475-
476-let NUMSEGMENTS = 6
477351
478352 let NUMMAINAUX = 2
479353
514388 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
515389
516390
517-func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
518-
519-
520-func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
521-
522-
523-func keyDuckRobberyCount (duckAssetId) = ("totalRobberyCountByDuck_" + duckAssetId)
524-
525-
526-func keyUserRobberyCount (addr) = ("userRobberyCount_" + addr)
527-
528-
529-func keyUserLastRobberyDay (addr) = ("userLastRobberyDay_" + addr)
530-
531-
532391 func keyDuckDeliveryCount (duckAssetId) = ("totalDeliveryCountByDuck_" + duckAssetId)
533392
534393
540399
541400 let xpClaim = 10000
542401
543-let xpSuccessFlight = 10000
544-
545-let xpFailFlight = 2000
546-
547-let xpSuccessRob = 10000
548-
549-let xpFailRob = 2000
550-
551-let xpCallES = 100000
552-
553402 let xpCustomName = 1000000
554403
555-let xpNewSLand = 5000000
556-
557-let xpUpgradeInfra = 10000
558-
559-let xpMerge = 1000000
560-
561404 let xpOnboard = 1000000
562-
563-let xpHeal = 10000
564405
565406 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
566407
574415 }
575416
576417
577-func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
578- let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
579- let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
580- let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
581- let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
582- ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
583- then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
584- else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
585- }
586-
587-
588418 let DAYMILLIS = 86400000
589419
590420 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
593423 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
594424
595425
596-let incubatorAddr = match chain {
597- case _ =>
598- if ((base58'2W' == $match0))
599- then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
600- else if ((base58'2T' == $match0))
601- then this
602- else throw("Unknown chain")
603-}
604-
605-let breederAddr = match chain {
606- case _ =>
607- if ((base58'2W' == $match0))
608- then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
609- else if ((base58'2T' == $match0))
610- then this
611- else throw("Unknown chain")
612-}
613-
614-let FIVEMINUTESMILLIS = 300000
615-
616426 let RENAMINGCOST = 5000000
617427
618428 let MAXNAMELEN = 50
619429
620-let InfraUpgradeCostSUsdt = 10000000
621-
622-let EXPMATERIALS = match chain {
623- case _ =>
624- if ((base58'2W' == $match0))
625- then 252289527462
626- else if ((base58'2T' == $match0))
627- then 2522895274
628- else throw("Unknown chain")
629-}
630-
631-let EXPUSDT = match chain {
632- case _ =>
633- if ((base58'2W' == $match0))
634- then 250000000
635- else if ((base58'2T' == $match0))
636- then 250000000
637- else throw("Unknown chain")
638-}
639-
640-let ROBO_DUCK_USDT = 100000
641-
642-let S_COST_ACRES = 2500000000
643-
644-let FIVEX = toBigInt(5)
645-
646-let TWENTYX = toBigInt(20)
647-
648-let TWENTY2X = toBigInt((20 * 20))
649-
650-let TWENTY3X = toBigInt(((20 * 20) * 20))
651-
652-let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
653-
654-let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
655-
656430 let PRESALENUMLANDS = 500
657431
658-func keyNextFreeLandNum () = "nextLandNum"
659-
660-
661432 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
662-
663-
664-func keyLandToAssetId (landNum) = ("la_" + landNum)
665433
666434
667435 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
679447 func keyOldies () = "oldiesList"
680448
681449
682-func keyNextRoboDuck () = "nextRoboDuck"
683-
684-
685450 let claimModeWh = 0
686451
687452 let claimModeDuck = 1
688453
689454 let claimModeWhThenDuck = 2
690-
691-let flHealth = 0
692-
693-let flTimestamp = 5
694-
695-let flBonus = 6
696-
697-let flProdsUsed = 7
698-
699-let rlHealth = 0
700-
701-let rlProdsUsed = 1
702-
703-let rlType = 0
704-
705-let rlLastTx = 2
706-
707-let rlTimestamp = 3
708-
709-func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
710-
711-
712-func toVolume (amount,pkgSize) = {
713- let pkgs = if ((amount >= 0))
714- then (((amount + pkgSize) - 1) / pkgSize)
715- else -((((-(amount) + pkgSize) - 1) / pkgSize))
716- (pkgs * MULT8)
717- }
718-
719455
720456 func distributeByWeights (total,weights) = {
721457 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
750486 distributeByWeights(total, r)
751487 }
752488 }
753-
754-
755-func subtractMaterials (shouldUseMat,has,totalNeed) = {
756- let need = getNeededMaterials(totalNeed)
757- func subtractor (acc,idx) = {
758- let result = (parseIntValue(has[idx]) - need[idx])
759- if ((0 > result))
760- then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
761- else (acc :+ toString(result))
762- }
763-
764- if (shouldUseMat)
765- then {
766- let $l = ITER6
767- let $s = size($l)
768- let $acc0 = nil
769- func $f0_1 ($a,$i) = if (($i >= $s))
770- then $a
771- else subtractor($a, $l[$i])
772-
773- func $f0_2 ($a,$i) = if (($i >= $s))
774- then $a
775- else throw("List size exceeds 6")
776-
777- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
778- }
779- else has
780- }
781-
782-
783-func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
784- then $Tuple3(oldEq, false, false)
785- else {
786- func subUsed (acc,idxAmt) = {
787- let parts = split(idxAmt, ",")
788- if ((size(parts) != 2))
789- then throw("Incorrect format, should be index,amount")
790- else {
791- let idx = parseIntValue(parts[0])
792- if (if ((0 > idx))
793- then true
794- else (idx >= size(productionMatrix)))
795- then throw("Unknown product idx")
796- else {
797- let amt = parseIntValue(parts[1])
798- let eqParts = split(acc._1, (parts[0] + ":"))
799- if ((size(eqParts) != 2))
800- then throw((("You don't have " + prodTypes[idx]) + " equipped"))
801- else {
802- let tmp = eqParts[1]
803- let numLen = if (isDigit(take(drop(tmp, 1), 1)))
804- then 2
805- else 1
806- let curr = parseIntValue(take(tmp, numLen))
807- let tail = drop(tmp, numLen)
808- let newAmt = if ((curr >= amt))
809- then (curr - amt)
810- else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
811- $Tuple3(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
812- then true
813- else if (if ((idx >= 6))
814- then (8 >= idx)
815- else false)
816- then (newAmt == 0)
817- else false, if (acc._3)
818- then true
819- else if (if ((idx >= 3))
820- then (5 >= idx)
821- else false)
822- then (amt > 0)
823- else false)
824- }
825- }
826- }
827- }
828-
829- let $l = split(pUsed, "_")
830- let $s = size($l)
831- let $acc0 = $Tuple3(oldEq, false, false)
832- func $f0_1 ($a,$i) = if (($i >= $s))
833- then $a
834- else subUsed($a, $l[$i])
835-
836- func $f0_2 ($a,$i) = if (($i >= $s))
837- then $a
838- else throw("List size exceeds 10")
839-
840- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
841- }
842489
843490
844491 func prodStrToBytes (prodStr) = {
1049696 }
1050697
1051698
1052-func canWearCurrentEquipment (duckAssetId) = {
1053- let eqKey = keyDuckEquipment(duckAssetId)
1054- let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
1055- let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
1056- let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
1057- let segBpAux = split(currEq[segBackpack], ";")[1]
1058- let buffEffect = if ((segBpAux == ""))
1059- then 0
1060- else {
1061- let aux0 = split(segBpAux, ",")[0]
1062- if ((aux0 == ""))
1063- then 0
1064- else {
1065- let idxCnt = split(aux0, ":")
1066- let idx = idxCnt[0]
1067- let cnt = idxCnt[1]
1068- if (if (if (if (if ((idx == "06"))
1069- then true
1070- else (idx == "07"))
1071- then true
1072- else (idx == "08"))
1073- then (cnt != "")
1074- else false)
1075- then (parseIntValue(cnt) > 0)
1076- else false)
1077- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
1078- else 0
1079- }
1080- }
1081- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
1082- let newProdB = dressB(currEq, tempProdB, false, stats)
1083- (newProdB == newProdB)
1084- }
1085-
1086-
1087699 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
1088700 then throw("Wrong proportions data")
1089701 else {
1235847 }
1236848
1237849
1238-func abs (x) = if ((x >= toBigInt(0)))
1239- then x
1240- else -(x)
1241-
1242-
1243-let freq = [[6, 9, 14, 15, 16], [5, 8, 13, 14, 15], [1, 4, 9, 10, 15], [1, 6, 7, 15, 19], [4, 7, 8, 13, 18]]
1244-
1245-func genChar (n,freqs) = {
1246- let rem = toInt((n % TWENTYX))
1247- let letter = if ((freqs[0] > rem))
1248- then "A"
1249- else if ((freqs[1] > rem))
1250- then "B"
1251- else if ((freqs[2] > rem))
1252- then "C"
1253- else if ((freqs[3] > rem))
1254- then "D"
1255- else if ((freqs[4] > rem))
1256- then "E"
1257- else "F"
1258- letter
1259- }
1260-
1261-
1262-func genTerrains (seed,continentIdx) = {
1263- let f = freq[continentIdx]
1264- func terrainGenerator (acc,elem) = $Tuple2((((((acc._1 + genChar(acc._2, f)) + genChar((acc._2 / TWENTYX), f)) + genChar((acc._2 / TWENTY2X), f)) + genChar((acc._2 / TWENTY3X), f)) + genChar((acc._2 / TWENTY4X), f)), (acc._2 / TWENTY5X))
1265-
1266- let t = {
1267- let $l = [1, 2, 3, 4, 5]
1268- let $s = size($l)
1269- let $acc0 = $Tuple2("", (seed / FIVEX))
1270- func $f0_1 ($a,$i) = if (($i >= $s))
1271- then $a
1272- else terrainGenerator($a, $l[$i])
1273-
1274- func $f0_2 ($a,$i) = if (($i >= $s))
1275- then $a
1276- else throw("List size exceeds 5")
1277-
1278- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1279- }
1280- t._1
1281- }
1282-
1283-
1284-let PERM25 = [7, 2, 15, 19, 8, 24, 1, 21, 16, 5, 0, 22, 20, 23, 11, 4, 18, 12, 6, 10, 3, 17, 13, 9, 14]
1285-
1286-let TCHARS = ["A", "B", "C", "D", "E", "F"]
1287-
1288-func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
1289- func step1 (acc,s) = {
1290- let j = acc._2
1291- let el = parseIntValue(s)
1292- let x = if ((el == 0))
1293- then 0
1294- else if ((el >= (4 * landSizeIndex)))
1295- then (el / landSizeIndex)
1296- else if ((el > (3 * landSizeIndex)))
1297- then 3
1298- else (((el - 1) / landSizeIndex) + 1)
1299- $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
1300- }
1301-
1302- let t = {
1303- let $l = sumTerrains
1304- let $s = size($l)
1305- let $acc0 = $Tuple3(nil, 0, 0)
1306- func $f0_1 ($a,$i) = if (($i >= $s))
1307- then $a
1308- else step1($a, $l[$i])
1309-
1310- func $f0_2 ($a,$i) = if (($i >= $s))
1311- then $a
1312- else throw("List size exceeds 6")
1313-
1314- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1315- }
1316- let arr = t._1
1317- let maxIdx = value(indexOf(arr, max(arr)))
1318- let delta = (t._3 - 25)
1319- func subber (acc,idx) = {
1320- let val = if ((idx == maxIdx))
1321- then (arr[idx] - delta)
1322- else arr[idx]
1323- let zeroes = if ((val == 0))
1324- then nil
1325- else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
1326- let c = TCHARS[idx]
1327- func listGen (ac,ignored) = (ac :+ c)
1328-
1329- let z = {
1330- let $l = zeroes
1331- let $s = size($l)
1332- let $acc0 = nil
1333- func $f1_1 ($a,$i) = if (($i >= $s))
1334- then $a
1335- else listGen($a, $l[$i])
1336-
1337- func $f1_2 ($a,$i) = if (($i >= $s))
1338- then $a
1339- else throw("List size exceeds 25")
1340-
1341- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
1342- }
1343- (acc ++ z)
1344- }
1345-
1346- let r = {
1347- let $l = ITER6
1348- let $s = size($l)
1349- let $acc0 = nil
1350- func $f1_1 ($a,$i) = if (($i >= $s))
1351- then $a
1352- else subber($a, $l[$i])
1353-
1354- func $f1_2 ($a,$i) = if (($i >= $s))
1355- then $a
1356- else throw("List size exceeds 6")
1357-
1358- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1359- }
1360- func permut (acc,j) = (acc + r[j])
1361-
1362- let $l = PERM25
1363- let $s = size($l)
1364- let $acc0 = ""
1365- func $f2_1 ($a,$i) = if (($i >= $s))
1366- then $a
1367- else permut($a, $l[$i])
1368-
1369- func $f2_2 ($a,$i) = if (($i >= $s))
1370- then $a
1371- else throw("List size exceeds 25")
1372-
1373- $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
1374- }
1375-
1376-
1377850 func getBackpack (bpKey) = {
1378851 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
1379852 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
1470943 }
1471944
1472945
1473-func getWarehouseSpaceLeft (currentWh) = {
1474- let occupiedVol = getWarehouseOccupiedVol(currentWh)
1475- let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
1476- ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
1477- }
1478-
1479-
1480-func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
1481- then throw("cargoListStr should contain exactly 2 ':' separators")
1482- else {
1483- let resParts = split(cargoParts[0], "_")
1484- let matParts = split(cargoParts[1], "_")
1485- let prodParts = if ((cargoParts[2] == ""))
1486- then nil
1487- else split_4C(cargoParts[2], "_")
1488- if ((size(resParts) != NUMRES))
1489- then throw("All 6 resources should be passed")
1490- else if ((size(matParts) != NUMRES))
1491- then throw("All 6 materials should be passed")
1492- else {
1493- let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
1494- let currWhRes = split(currentWh[whIdxRes], "_")
1495- let currWhMat = split(currentWh[whIdxMat], "_")
1496- let currWhProd = if ((currentWh[whIdxProd] == ""))
1497- then nil
1498- else split_4C(currentWh[whIdxProd], "_")
1499- let currentPackRes = split(currentPack[bpIdxRes], "_")
1500- let currentPackMat = split(currentPack[bpIdxMat], "_")
1501- let currentPackProd = if ((currentPack[bpIdxProd] == ""))
1502- then nil
1503- else split_4C(currentPack[bpIdxProd], "_")
1504- func mvR (acc,item) = {
1505- let i = acc._1
1506- let am = parseIntValue(item)
1507- let whr = parseIntValue(currWhRes[i])
1508- let bpr = parseIntValue(currentPackRes[i])
1509- if ((am == 0))
1510- then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
1511- else if ((am > 0))
1512- then if ((am > bpr))
1513- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
1514- else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
1515- else if ((-(am) > whr))
1516- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
1517- else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
1518- }
1519-
1520- let r = {
1521- let $l = resParts
1522- let $s = size($l)
1523- let $acc0 = $Tuple4(0, nil, nil, 0)
1524- func $f0_1 ($a,$i) = if (($i >= $s))
1525- then $a
1526- else mvR($a, $l[$i])
1527-
1528- func $f0_2 ($a,$i) = if (($i >= $s))
1529- then $a
1530- else throw("List size exceeds 6")
1531-
1532- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1533- }
1534- func mvM (acc,item) = {
1535- let i = acc._1
1536- let am = parseIntValue(item)
1537- let whm = parseIntValue(currWhMat[i])
1538- let bpm = parseIntValue(currentPackMat[i])
1539- if ((am == 0))
1540- then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
1541- else if ((am > 0))
1542- then if ((am > bpm))
1543- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
1544- else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
1545- else if ((-(am) > whm))
1546- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
1547- else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
1548- }
1549-
1550- let m = {
1551- let $l = matParts
1552- let $s = size($l)
1553- let $acc0 = $Tuple4(0, nil, nil, r._4)
1554- func $f1_1 ($a,$i) = if (($i >= $s))
1555- then $a
1556- else mvM($a, $l[$i])
1557-
1558- func $f1_2 ($a,$i) = if (($i >= $s))
1559- then $a
1560- else throw("List size exceeds 6")
1561-
1562- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1563- }
1564- func mvP (acc,item) = {
1565- let i = acc._1
1566- let am = parseIntValue(item)
1567- let whp = if ((size(currWhProd) > i))
1568- then parseIntValue(currWhProd[i])
1569- else 0
1570- let bpp = if ((size(currentPackProd) > i))
1571- then parseIntValue(currentPackProd[i])
1572- else 0
1573- if ((am == 0))
1574- then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
1575- else if ((am > 0))
1576- then if ((am > bpp))
1577- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
1578- else {
1579- let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
1580- $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
1581- }
1582- else if ((-(am) > whp))
1583- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
1584- else {
1585- let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
1586- $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
1587- }
1588- }
1589-
1590- let p = if ((size(prodParts) != 0))
1591- then {
1592- let $l = prodParts
1593- let $s = size($l)
1594- let $acc0 = $Tuple4(0, nil, nil, m._4)
1595- func $f2_1 ($a,$i) = if (($i >= $s))
1596- then $a
1597- else mvP($a, $l[$i])
1598-
1599- func $f2_2 ($a,$i) = if (($i >= $s))
1600- then $a
1601- else throw("List size exceeds 50")
1602-
1603- $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 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)
1604- }
1605- else $Tuple4(0, currWhProd, currentPackProd, m._4)
1606- let volSaldo = p._4
1607- if ((volSaldo > whSpaceLeft))
1608- then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
1609- else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
1610- }
1611- }
1612-
1613-
1614-func expeditionInternal (caller,txId) = {
1615- let userAddr = toString(caller)
1616- let bigNum = abs(toBigInt(txId))
1617- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1618- let landNum = toString(freeNum)
1619- let continentIdx = toInt((bigNum % FIVEX))
1620- let terrains = genTerrains(bigNum, continentIdx)
1621- let continent = continents[continentIdx]
1622- let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
1623- let assetId = calculateAssetId(issue)
1624- let id = toBase58String(assetId)
1625- $Tuple2([IntegerEntry(keyNextFreeLandNum(), (freeNum + 1)), issue, StringEntry(keyLandToAssetId(landNum), id), StringEntry(keyLandAssetIdToOwner(id), userAddr), StringEntry(keyLandNumToOwner(landNum), userAddr), IntegerEntry(keyInfraLevelByAssetId(id), 0), IntegerEntry(keyInfraLevelByAssetIdAndOwner(id, userAddr), 0), ScriptTransfer(caller, 1, assetId)], $Tuple2(id, continent))
1626- }
1627-
1628-
1629-func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
1630- then throw("signature does not match")
1631- else {
1632- let parts = split_4C(toUtf8String(message), ";")
1633- let flightLog = split_4C(parts[0], "|")
1634- let hp = split(flightLog[flHealth], "_")
1635- let curHP = parseIntValue(hp[0])
1636- let newHP = parseIntValue(hp[1])
1637- let newLocTxVer = split(parts[1], ":")
1638- let newLocation = newLocTxVer[0]
1639- let time = parseIntValue(flightLog[flTimestamp])
1640- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
1641- then true
1642- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1643- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
1644- else {
1645- let txFromMsg = newLocTxVer[1]
1646- let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
1647- if ((lastTx != txFromMsg))
1648- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
1649- else {
1650- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
1651- let keyHealth = keyDuckHealth(duckAssetId)
1652- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
1653- let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
1654- if ((oldFromState != curHP))
1655- then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
1656- else if ((0 >= curHP))
1657- then throw("You can't fly with zero health")
1658- else if (!(canWearCurrentEquipment(duckAssetId)))
1659- then throw("Equipment incompatible")
1660- else {
1661- let bonus = if ((size(flightLog) > flBonus))
1662- then flightLog[flBonus]
1663- else ""
1664- let prodUsed = if ((size(flightLog) > flProdsUsed))
1665- then flightLog[flProdsUsed]
1666- else ""
1667- let sentAmount = if (if ((newHP > 0))
1668- then (bonus == "$")
1669- else false)
1670- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1671- else 0
1672- $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
1673- }
1674- }
1675- }
1676- }
1677-
1678-
1679946 func applyBonuses (landAssetId,pieces) = {
1680947 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1681948 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
1686953
1687954
1688955 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1689- let $t03415334692 = if ((claimMode == claimModeWh))
956+ let $t03424734786 = if ((claimMode == claimModeWh))
1690957 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
1691958 else {
1692959 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
1696963 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
1697964 else $Tuple2(loc[locIdxId], duckAssetId)
1698965 }
1699- let landAssetId = $t03415334692._1
1700- let duckId = $t03415334692._2
966+ let landAssetId = $t03424734786._1
967+ let duckId = $t03424734786._2
1701968 let asset = value(assetInfo(fromBase58String(landAssetId)))
1702969 let timeKey = keyStakedTimeByAssetId(landAssetId)
1703970 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17451012 let currentPack = getBackpack(bpKey)
17461013 let currentPackRes = split(currentPack[bpIdxRes], "_")
17471014 let currentWhRes = split(currentWh[whIdxRes], "_")
1748- let $t03706237933 = if ((claimMode == claimModeWh))
1015+ let $t03715638027 = if ((claimMode == claimModeWh))
17491016 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17501017 else if ((claimMode == claimModeDuck))
17511018 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17541021 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17551022 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17561023 }
1757- let whRes = $t03706237933._1
1758- let bpRes = $t03706237933._2
1759- let loftO = $t03706237933._3
1760- let loftF = $t03706237933._4
1024+ let whRes = $t03715638027._1
1025+ let bpRes = $t03715638027._2
1026+ let loftO = $t03715638027._3
1027+ let loftF = $t03715638027._4
17611028 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
17621029 }
17631030 }
17701037 let savedTime = value(getInteger(timeKey))
17711038 let availRes = (fraction((finalTime() - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
17721039 claimResInternal(addr, availRes, claimMode, landAssetId)
1773- }
1774-
1775-
1776-func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
1777- let addr = toString(caller)
1778- let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
1779- let pieces = numPiecesBySize(c._3[recLandSize])
1780- let infraKey = keyInfraLevelByAssetId(c._2)
1781- let curLevel = valueOrElse(getInteger(infraKey), 0)
1782- if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
1783- then (curLevel >= 3)
1784- else false)
1785- then throw("Currently max infrastructure level = 3")
1786- else {
1787- let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
1788- let newLevel = (curLevel + 1)
1789- if (if (KS_ALLOW_BIG_INFRA_MERGE)
1790- then (newLevel > maxInfra)
1791- else false)
1792- then throw(("Currently max infrastructure level = " + toString(maxInfra)))
1793- else {
1794- let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
1795- if (if (!(shouldUseMat))
1796- then (paymentAmount != cost)
1797- else false)
1798- then throw(("Payment attached should be " + toString(cost)))
1799- else {
1800- let bpKey = keyBackpackByDuck(c._1)
1801- let currentPack = getBackpack(bpKey)
1802- let mList = split(currentPack[bpIdxMat], "_")
1803- let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
1804- let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
1805- let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
1806- let whData = claimResult._5
1807- let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
1808- let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
1809- let newVol = getWarehouseTotalVolume(newVolData)
1810- let loft = split(whData[whIdxLOFT], "_")
1811- let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
1812- $Tuple3(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], newLoftStr], ":"))] ++ claimResult._1), newLevel, matUsed)
1813- }
1814- }
1815- }
18161040 }
18171041
18181042
18761100 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
18771101 }
18781102 }
1879-
1880-
1881-func checkTournament (duckAssetId) = {
1882- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
1883- let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1884- let now = lastBlock.timestamp
1885- let tData = getTourData(tournamentContract, lastId)
1886- let static = tData[idxStatic]
1887- let dynamic = tData[idxDynamic]
1888- if ((curLocation[locIdxType] != "T"))
1889- then false
1890- else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
1891- then (dynamic[tDynamicStatus] == "INPROGRESS")
1892- else false)
1893- then (parseIntValue(static[tStaticEnd]) > now)
1894- else false)
1895- then throw("Your duck is taking part in the tournament")
1896- else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
1897- }
1898-
1899-
1900-func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
1901- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
1902- if (checkTournament(duckAssetId))
1903- then throw("mergeInternal_checkTournament")
1904- else {
1905- func checkMerge (acc,landAssetId) = {
1906- let asset = value(assetInfo(fromBase58String(landAssetId)))
1907- let timeKey = keyStakedTimeByAssetId(landAssetId)
1908- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1909- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1910- if ((owner != addr))
1911- then throw((LANDPREFIX + " is not yours"))
1912- else {
1913- let d = split(asset.description, "_")
1914- let continent = d[recContinent]
1915- if (if ((acc._3 != ""))
1916- then (acc._3 != continent)
1917- else false)
1918- then throw("Lands should be on the same continent to merge")
1919- else {
1920- let landSize = d[recLandSize]
1921- let sizesIn = acc._1
1922- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1923- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1924- let pieces = numPiecesBySize(landSize)
1925- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1926- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1927- let reqLevel = match landSize {
1928- case _ =>
1929- if (("S" == $match0))
1930- then 3
1931- else if (("M" == $match0))
1932- then 4
1933- else if (("L" == $match0))
1934- then 5
1935- else if (("XL" == $match0))
1936- then 6
1937- else throw("Only S, M, L, XL can merge")
1938- }
1939- if ((infraLevel != reqLevel))
1940- then throw("All lands should be maxed to merge")
1941- else {
1942- let landNum = d[recLandNum]
1943- let terrainCounts = countTerrains(d[recTerrains])
1944- let deltaTime = (lastBlock.timestamp - savedTime)
1945- if ((0 > deltaTime))
1946- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1947- else {
1948- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1949- let landIndex = (pieces / SSIZE)
1950- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1951- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1952- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1953- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1954- let lands = acc._7
1955- let idx = indexOf(lands, landAssetId)
1956- if (!(isDefined(idx)))
1957- then throw(("Your staked lands don't contain " + landAssetId))
1958- else {
1959- let customKey = keyLandAssetIdToCustomName(landAssetId)
1960- let customName = valueOrElse(getString(customKey), "")
1961- $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1962- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1963- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1964- }
1965- }
1966- }
1967- }
1968- }
1969- }
1970-
1971- let bpKey = keyBackpackByDuck(duckAssetId)
1972- let currentPack = getBackpack(bpKey)
1973- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1974- let landsKey = keyStakedLandsByOwner(addr)
1975- let landsStr = getString(landsKey)
1976- let landsIn = if (isDefined(landsStr))
1977- then split_51C(value(landsStr), "_")
1978- else nil
1979- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1980- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1981- let r = {
1982- let $l = landAssetIds
1983- let $s = size($l)
1984- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1985- func $f0_1 ($a,$i) = if (($i >= $s))
1986- then $a
1987- else checkMerge($a, $l[$i])
1988-
1989- func $f0_2 ($a,$i) = if (($i >= $s))
1990- then $a
1991- else throw("List size exceeds 5")
1992-
1993- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1994- }
1995- let continent = r._3
1996- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1997- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1998- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1999- let newLandNum = toString(freeNum)
2000- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2001- let assetId = calculateAssetId(issue)
2002- let newLandAssetId = toBase58String(assetId)
2003- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2004- let piecesKey = keyStakedPiecesByOwner(addr)
2005- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2006- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2007- then StringEntry(landsKey, makeString_11C(r._7, "_"))
2008- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2009- then 0
2010- else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
2011- }
2012- }
2013-
2014-
2015-func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
2016-
2017-
2018-func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
2019-
2020-
2021-func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
2022-
2023-
2024-func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
2025-
2026-
2027-func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
2028- case _ =>
2029- if ((4 == $match0))
2030- then s2m(addr, landAssetIds)
2031- else if ((3 == $match0))
2032- then m2l(addr, landAssetIds)
2033- else if ((5 == $match0))
2034- then l2xl(addr, landAssetIds)
2035- else if ((2 == $match0))
2036- then xl2xxl(addr, landAssetIds)
2037- else throw("Unknown merge")
2038-}
20391103
20401104
20411105 func prolog (i) = if (if ((i.originCaller != restContract))
23791443
23801444
23811445 @Callable(i)
2382-func stakeDuck () = {
2383- let prologActions = prolog(i)
2384- if ((size(i.payments) != 1))
2385- then throw("Exactly one payment required")
2386- else {
2387- let pmt = value(i.payments[0])
2388- let assetId = value(pmt.assetId)
2389- let address = toString(i.caller)
2390- if ((pmt.amount != 1))
2391- then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
2392- else {
2393- let asset = value(assetInfo(assetId))
2394- let isRobo = if (if (KS_ALLOW_ROBO_DUCKS)
2395- then (asset.issuer == this)
2396- else false)
2397- then contains(asset.name, ROBO_PREFIX)
2398- else false
2399- if (if (if ((asset.issuer != incubatorAddr))
2400- then (asset.issuer != breederAddr)
2401- else false)
2402- then !(isRobo)
2403- else false)
2404- then throw((((("Unknown issuer of " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " token"))
2405- else if (if (!(contains(asset.name, DUCKPREFIX)))
2406- then !(isRobo)
2407- else false)
2408- then throw((((("Only NFT " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " tokens are accepted"))
2409- else {
2410- let assetIdStr = toBase58String(assetId)
2411- let timeKey = keyStakedTimeByAssetId(assetIdStr)
2412- if (isDefined(getInteger(timeKey)))
2413- then throw((("NFT " + asset.name) + " is already staked"))
2414- else if (isDefined(getString(keyStakedDuckByOwner(address))))
2415- then throw(("You already staked one duck: " + asset.name))
2416- else {
2417- let locKey = keyDuckLocation(assetIdStr)
2418- let location = getString(locKey)
2419- let bpKey = keyBackpackByDuck(assetIdStr)
2420- let backpack = getString(bpKey)
2421- let keyHealth = keyDuckHealth(assetIdStr)
2422- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2423- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2424- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2425- then nil
2426- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2427- then nil
2428- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
2429- }
2430- }
2431- }
2432- }
2433- }
2434-
2435-
2436-
2437-@Callable(i)
2438-func unstakeDuck (assetIdStr) = {
2439- let prologActions = prolog(i)
2440- if ((size(i.payments) != 0))
2441- then throw("No payments required")
2442- else {
2443- let assetId = fromBase58String(assetIdStr)
2444- let address = toString(i.caller)
2445- let asset = value(assetInfo(assetId))
2446- let timeKey = keyStakedTimeByAssetId(assetIdStr)
2447- if (!(isDefined(getInteger(timeKey))))
2448- then throw((("NFT " + asset.name) + " is not staked"))
2449- else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
2450- then throw((("The duck " + asset.name) + " is not staked"))
2451- else {
2452- let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
2453- if ((owner != address))
2454- then throw("Staked NFT is not yours")
2455- else if (checkTournament(assetIdStr))
2456- then throw("unstakeDuck_checkTournament")
2457- else {
2458- let keyHealth = keyDuckHealth(assetIdStr)
2459- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2460- let health = valueOrElse(getInteger(keyHealth), maxHP)
2461- if ((maxHP > health))
2462- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2463- else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
2464- }
2465- }
2466- }
2467- }
2468-
2469-
2470-
2471-@Callable(i)
24721446 func unstakeDuckCallback (duckAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
24731447 then throw("Permission denied")
24741448 else {
25161490
25171491
25181492 @Callable(i)
2519-func flight (message,sig) = {
2520- let prologActions = prolog(i)
2521- if ((size(i.payments) != 0))
2522- then throw("No payments required")
2523- else {
2524- let userAddr = toString(i.caller)
2525- let f = flightCommon(userAddr, message, sig)
2526- let newHP = f._1
2527- let duckAssetId = f._2
2528- let locKey = keyDuckLocation(duckAssetId)
2529- let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
2530- let newLocation = f._4
2531- if ((newLocation == curLocation))
2532- then throw("You can't fly to the same location")
2533- else {
2534- let newLoc = split(newLocation, "_")
2535- let isTour = (newLoc[locIdxType] == "T")
2536- let isDeliv = (newLoc[locIdxType] == "D")
2537- let eqKey = keyDuckEquipment(duckAssetId)
2538- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2539- let $t07376973875 = subtractEquipment(currentEq, f._5)
2540- let newEq = $t07376973875._1
2541- let shouldZeroBuffs = $t07376973875._2
2542- let ignored = $t07376973875._3
2543- let $t07387875710 = if (!(onMission(tournamentContract, curLocation)))
2544- then if (isTour)
2545- then cheatAttempt(curLocation, newLocation, 5)
2546- else if (!(isDeliv))
2547- then if ((newHP > 0))
2548- then $Tuple2(newLocation, newHP)
2549- else $Tuple2(curLocation, 0)
2550- else if ((newHP > 0))
2551- then {
2552- let s = invoke(this, "processDelivery", [duckAssetId], nil)
2553- if ((s == s))
2554- then $Tuple2(curLocation, newHP)
2555- else throw("Strict value is not equal to itself.")
2556- }
2557- else $Tuple2(curLocation, 0)
2558- else if (isInTournament(tournamentContract, curLocation))
2559- then if (!(isInTournament(tournamentContract, newLocation)))
2560- then throw("Your duck is taking part in the tournament")
2561- else {
2562- let score = parseIntValue(newLoc[locIdxId])
2563- let curLoc = split(curLocation, "_")
2564- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2565- if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2566- then cheatAttempt(curLocation, newLocation, 7)
2567- else if ((newHP > 0))
2568- then {
2569- let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2570- let updLocal = if ((score > localBest))
2571- then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2572- else unit
2573- if ((updLocal == updLocal))
2574- then $Tuple2(newLocation, newHP)
2575- else throw("Strict value is not equal to itself.")
2576- }
2577- else $Tuple2(curLocation, 0)
2578- }
2579- else throw(("Unknown curLocation:" + curLocation))
2580- let locToSave = $t07387875710._1
2581- let hpToSave = $t07387875710._2
2582- $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
2583- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2584- else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2585- then xpSuccessFlight
2586- else xpFailFlight)._1), f._3)
2587- }
2588- }
2589- }
2590-
2591-
2592-
2593-@Callable(i)
2594-func heal (quantityL1,quantityL2,quantityL3) = {
2595- let prologActions = prolog(i)
2596- if (if (if ((0 > quantityL1))
2597- then true
2598- else (0 > quantityL2))
2599- then true
2600- else (0 > quantityL3))
2601- then throw("Quantity cannot be negative")
2602- else {
2603- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2604- if (checkTournament(duckAssetId))
2605- then throw("heal_checkTournament")
2606- else {
2607- let qts = [quantityL1, quantityL2, quantityL3]
2608- let keyHealth = keyDuckHealth(duckAssetId)
2609- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2610- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2611- if ((oldHealth >= maxHP))
2612- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2613- else {
2614- let bpKey = keyBackpackByDuck(duckAssetId)
2615- let currentPack = getBackpack(bpKey)
2616- let prodList = if ((currentPack[bpIdxProd] == ""))
2617- then nil
2618- else split_4C(currentPack[bpIdxProd], "_")
2619- func iterateProd (acc,recipe) = {
2620- let n = acc._2
2621- let x = if ((size(prodList) > n))
2622- then parseIntValue(prodList[n])
2623- else 0
2624- if ((3 > n))
2625- then {
2626- let q = qts[n]
2627- if ((q > x))
2628- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2629- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2630- }
2631- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2632- }
2633-
2634- let result = {
2635- let $l = productionMatrix
2636- let $s = size($l)
2637- let $acc0 = $Tuple3(nil, 0, 0)
2638- func $f0_1 ($a,$i) = if (($i >= $s))
2639- then $a
2640- else iterateProd($a, $l[$i])
2641-
2642- func $f0_2 ($a,$i) = if (($i >= $s))
2643- then $a
2644- else throw("List size exceeds 50")
2645-
2646- $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)
2647- }
2648- let newHealth = min([maxHP, (oldHealth + result._3)])
2649- $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2650- }
2651- }
2652- }
2653- }
2654-
2655-
2656-
2657-@Callable(i)
2658-func healES () = {
2659- let prologActions = prolog(i)
2660- if ((size(i.payments) != 1))
2661- then throw("Exactly one payment required")
2662- else {
2663- let pmt = value(i.payments[0])
2664- if ((pmt.assetId != usdtAssetId))
2665- then throw("Allowed USDT payment only!")
2666- else {
2667- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2668- if (checkTournament(duckAssetId))
2669- then throw("healES_checkTournament")
2670- else {
2671- let keyHealth = keyDuckHealth(duckAssetId)
2672- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2673- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2674- if ((oldHealth > 0))
2675- then throw("HP should be 0 to call Emergency Service")
2676- else {
2677- let bpKey = keyBackpackByDuck(duckAssetId)
2678- let currentPack = getBackpack(bpKey)
2679- let prodList = if ((currentPack[bpIdxProd] == ""))
2680- then nil
2681- else split_4C(currentPack[bpIdxProd], "_")
2682- let medKitAmount1 = if ((size(prodList) > 0))
2683- then parseIntValue(prodList[0])
2684- else 0
2685- let medKitAmount2 = if ((size(prodList) > 1))
2686- then parseIntValue(prodList[1])
2687- else 0
2688- let medKitAmount3 = if ((size(prodList) > 2))
2689- then parseIntValue(prodList[2])
2690- else 0
2691- if (if (if ((medKitAmount1 > 0))
2692- then true
2693- else (medKitAmount2 > 0))
2694- then true
2695- else (medKitAmount3 > 0))
2696- then throw("You have to use own Medical Kit")
2697- else {
2698- let existStr = getString(economyContract, keyEsWarehouse())
2699- let existAmounts = if (isDefined(existStr))
2700- then split_4C(value(existStr), "_")
2701- else nil
2702- let existAmount = if ((size(existAmounts) > 0))
2703- then parseIntValue(existAmounts[0])
2704- else 0
2705- if ((0 >= existAmount))
2706- then throw("There are no Medical Kits L1 at Emergency Service storage")
2707- else {
2708- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2709- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2710- let recipe = split(productionMatrix[0], "_")
2711- let totalMat = getRecipeMaterials(recipe)
2712- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2713- if ((pmt.amount != sellPrice))
2714- then throw(("Payment attached should be " + toString(sellPrice)))
2715- else {
2716- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2717- $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2718- }
2719- }
2720- }
2721- }
2722- }
2723- }
2724- }
2725- }
2726-
2727-
2728-
2729-@Callable(i)
27301493 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
27311494 then throw("permission denied")
27321495 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
27621525
27631526
27641527 @Callable(i)
2765-func buySLand () = {
2766- let prologActions = prolog(i)
2767- if ((size(i.payments) != 1))
2768- then throw("Exactly one payment required")
2769- else {
2770- let pmt = value(i.payments[0])
2771- if ((pmt.assetId != usdtAssetId))
2772- then throw("Allowed USDT payment only!")
2773- else if ((pmt.amount != EXPUSDT))
2774- then throw(("Payment attached should be " + toString(EXPUSDT)))
2775- else {
2776- let result = expeditionInternal(i.caller, i.transactionId)
2777- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2778- $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2779- }
2780- }
2781- }
2782-
2783-
2784-
2785-@Callable(i)
2786-func expedition (message,sig) = {
2787- let prologActions = prolog(i)
2788- if ((size(i.payments) != 0))
2789- then throw("No payments required")
2790- else {
2791- let userAddr = toString(i.caller)
2792- let f = flightCommon(userAddr, message, sig)
2793- let duckAssetId = f._2
2794- let keyHealth = keyDuckHealth(duckAssetId)
2795- let bpKey = keyBackpackByDuck(duckAssetId)
2796- let currentPack = getBackpack(bpKey)
2797- let mList = split(currentPack[bpIdxMat], "_")
2798- let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
2799- let eqKey = keyDuckEquipment(duckAssetId)
2800- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2801- let $t08363083736 = subtractEquipment(currentEq, f._5)
2802- let newEq = $t08363083736._1
2803- let shouldZeroBuffs = $t08363083736._2
2804- let ignored = $t08363083736._3
2805- let e = expeditionInternal(i.caller, i.transactionId)
2806- let id = e._2._1
2807- let result = if ((0 >= f._1))
2808- then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
2809- else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
2810- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2811- else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
2812- if (checkTournament(duckAssetId))
2813- then throw("expedition_checkTournament")
2814- else {
2815- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2816- $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
2817- }
2818- }
2819- }
2820-
2821-
2822-
2823-@Callable(i)
2824-func buySLandForAcres () = {
2825- let prologActions = prolog(i)
2826- if ((size(i.payments) != 1))
2827- then throw("exactly 1 payment must be attached")
2828- else {
2829- let pmt = i.payments[0]
2830- let amt = pmt.amount
2831- if (if (!(isDefined(pmt.assetId)))
2832- then true
2833- else (value(pmt.assetId) != acresAssetId))
2834- then throw("ACRES payments only!")
2835- else if ((amt != S_COST_ACRES))
2836- then throw(("Payment attached should be " + toString(S_COST_ACRES)))
2837- else {
2838- let result = expeditionInternal(i.caller, i.transactionId)
2839- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
2840- $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2841- }
2842- }
2843- }
2844-
2845-
2846-
2847-@Callable(i)
2848-func upgradeInfra (landAssetId) = {
2849- let prologActions = prolog(i)
2850- if ((size(i.payments) != 0))
2851- then throw("No payments required")
2852- else {
2853- let result = upInfraCommon(true, i.caller, 0, landAssetId)
2854- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2855- $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
2856- }
2857- }
2858-
2859-
2860-
2861-@Callable(i)
28621528 func activateArtifact (artName,landAssetIdOpt) = {
28631529 let prologActions = prolog(i)
28641530 if ((size(i.payments) != 0))
28741540 else throw("Unknown artifact")
28751541 }
28761542 (result ++ prologActions)
2877- }
2878- }
2879-
2880-
2881-
2882-@Callable(i)
2883-func mergeLands (landAssetIds) = {
2884- let prologActions = prolog(i)
2885- if ((size(i.payments) != 0))
2886- then throw("No payments required")
2887- else {
2888- let result = mergeCommon(toString(i.caller), landAssetIds)
2889- $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
2890- }
2891- }
2892-
2893-
2894-
2895-@Callable(i)
2896-func cargoExchange (cargoListStr,landAssetId) = {
2897- let prologActions = prolog(i)
2898- if ((size(i.payments) != 0))
2899- then throw("No payments required")
2900- else {
2901- let cargoParts = split_4C(cargoListStr, ":")
2902- let addr = toString(i.originCaller)
2903- let asset = value(assetInfo(fromBase58String(landAssetId)))
2904- let timeKey = keyStakedTimeByAssetId(landAssetId)
2905- if (!(isDefined(getInteger(timeKey))))
2906- then throw((asset.name + " is not staked"))
2907- else {
2908- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
2909- if ((owner != addr))
2910- then throw((LANDPREFIX + " is not yours"))
2911- else {
2912- let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
2913- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
2914- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
2915- let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
2916- let loc = split(value(curLocation), "_")
2917- if ((loc[locIdxType] != "L"))
2918- then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
2919- else if ((loc[locIdxId] != landAssetId))
2920- then throw(("Duck should be on the land " + landAssetId))
2921- else {
2922- let whKey = keyWarehouseByLand(landAssetId)
2923- let currentWh = getWarehouse(whKey, landIndex, infraLevel)
2924- let bpKey = keyBackpackByDuck(duckAssetId)
2925- let currentPack = getBackpack(bpKey)
2926- let result = moveStuff(cargoParts, currentWh, currentPack)
2927- let loft = split(currentWh[whIdxLOFT], "_")
2928- let loftO = (parseIntValue(loft[volOccupied]) + result._7)
2929- let loftF = (parseIntValue(loft[volFree]) - result._7)
2930- ([StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString_2C([currentWh[whIdxLevels], result._1, result._2, result._3, makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")], ":"))] ++ prologActions)
2931- }
2932- }
2933- }
29341543 }
29351544 }
29361545
31241733 let addr = toString(i.originCaller)
31251734 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
31261735 let virtWlgPoints = asInt(virtWlgData[1])
3127- let $t09954899938 = if ((0 >= virtWlgPoints))
1736+ let $t0100228100618 = if ((0 >= virtWlgPoints))
31281737 then $Tuple2(0, nil)
31291738 else {
31301739 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
31321741 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
31331742 else throw("Strict value is not equal to itself.")
31341743 }
3135- let wlgPoints = $t09954899938._1
3136- let wlgActions = $t09954899938._2
1744+ let wlgPoints = $t0100228100618._1
1745+ let wlgActions = $t0100228100618._2
31371746 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
31381747 let freeKeyAcc = keyUserFreePoints(addr)
31391748 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
32041813 func updateAccStats (addr,deltaXP) = if (!(containsElement([wlgContract, economyContract, acresContract], i.caller)))
32051814 then throw("Access denied")
32061815 else updateAccStatsInternal(addr, deltaXP)
3207-
3208-
3209-
3210-@Callable(i)
3211-func equipDuck (equipment) = {
3212- let prologActions = prolog(i)
3213- if ((size(i.payments) != 0))
3214- then throw("No payments required")
3215- else {
3216- let addr = toString(i.originCaller)
3217- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3218- if (checkTournament(duckAssetId))
3219- then throw("equipDuck_checkTournament")
3220- else {
3221- let eqKey = keyDuckEquipment(duckAssetId)
3222- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3223- let bpKey = keyBackpackByDuck(duckAssetId)
3224- let currentPack = getBackpack(bpKey)
3225- let newEq = split(equipment, "_")
3226- if ((size(newEq) != NUMSEGMENTS))
3227- then throw("Wrong equipment string")
3228- else {
3229- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3230- let segBpAux = split(newEq[segBackpack], ";")[1]
3231- let buffEffect = if ((segBpAux == ""))
3232- then 0
3233- else {
3234- let aux0 = split(segBpAux, ",")[0]
3235- if ((aux0 == ""))
3236- then 0
3237- else {
3238- let idxCnt = split(aux0, ":")
3239- let idx = idxCnt[0]
3240- let cnt = idxCnt[1]
3241- if (if (if (if (if ((idx == "06"))
3242- then true
3243- else (idx == "07"))
3244- then true
3245- else (idx == "08"))
3246- then (cnt != "")
3247- else false)
3248- then (parseIntValue(cnt) > 0)
3249- else false)
3250- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3251- else 0
3252- }
3253- }
3254- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3255- let newProdB = dressB(newEq, tempProdB, false, stats)
3256- let newProdStr = bytesToProdStr(newProdB)
3257- $Tuple2(([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_"))] ++ prologActions), 0)
3258- }
3259- }
3260- }
3261- }
32621816
32631817
32641818
33451899 }
33461900
33471901
3348-
3349-@Callable(i)
3350-func robLand (message,sig) = {
3351- let prologActions = prolog(i)
3352- if ((size(i.payments) != 1))
3353- then throw("exactly 1 payment must be attached")
3354- else {
3355- let pmt = i.payments[0]
3356- let wlgAmt = pmt.amount
3357- if (if (!(isDefined(pmt.assetId)))
3358- then true
3359- else (value(pmt.assetId) != wlgAssetId))
3360- then throw("WLGOLD payments only!")
3361- else if ((wlgAmt != MIN_WLGOLD_ROBBERY))
3362- then throw((("Payment should be " + fixedPoint(MIN_WLGOLD_ROBBERY, 8)) + " WLGOLD"))
3363- else {
3364- let addr = toString(i.caller)
3365- if (!(sigVerify_8Kb(message, sig, pub)))
3366- then throw("signature does not match")
3367- else {
3368- let parts = split_4C(toUtf8String(message), ";")
3369- let robLog = split_4C(parts[0], "|")
3370- let hp = split(robLog[rlHealth], "_")
3371- let curHP = parseIntValue(hp[0])
3372- let newHP = parseIntValue(hp[1])
3373- let prodUsed = robLog[rlProdsUsed]
3374- let lastPart = split(parts[1], "|")
3375- let robType = lastPart[rlType]
3376- if ((robType != "B"))
3377- then throw("Only bank robbery is supported")
3378- else {
3379- let time = parseIntValue(lastPart[rlTimestamp])
3380- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
3381- then true
3382- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
3383- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
3384- else {
3385- let txFromMsg = lastPart[rlLastTx]
3386- let lastTx = valueOrElse(getString(keyLastTxIdByUser(addr)), "")
3387- if ((lastTx != txFromMsg))
3388- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3389- else {
3390- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3391- let eqKey = keyDuckEquipment(duckAssetId)
3392- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
3393- let $t0117116117227 = subtractEquipment(currentEq, prodUsed)
3394- let newEq = $t0117116117227._1
3395- let shouldZeroBuffs = $t0117116117227._2
3396- let isBpUsed = $t0117116117227._3
3397- let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
3398- if (isInTournament(tournamentContract, curLocation))
3399- then throw("Your duck is taking part in the tournament")
3400- else {
3401- let now = lastBlock.timestamp
3402- let countKey = keyUserRobberyCount(addr)
3403- let lastDay = valueOrElse(getInteger(keyUserLastRobberyDay(addr)), 0)
3404- let today = (now / DAYMILLIS)
3405- let count = if ((lastDay == today))
3406- then valueOrElse(getInteger(countKey), 0)
3407- else 0
3408- let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
3409- let allowedRobberies = (ALLOWED_FREE_ROBBERIES + (acres / ACRES_FOR_ROBBERY_ATTEMPT))
3410- if ((count >= allowedRobberies))
3411- then throw((("You already used " + toString(allowedRobberies)) + " robbery attempts for today"))
3412- else {
3413- let globalCountKey = keyDuckRobberyCount(duckAssetId)
3414- let loot = if ((newHP > 0))
3415- then {
3416- let fundTotal = assetBalance(this, wlgAssetId)
3417- let prize = if (isBpUsed)
3418- then (2 * MIN_WLGOLD_ROBBERY)
3419- else (5 * MIN_WLGOLD_ROBBERY)
3420- if ((prize > fundTotal))
3421- then throw(((("Robbery is not available, funds = " + fixedPoint(fundTotal, 8)) + " WLGOLD, required = ") + fixedPoint(prize, 8)))
3422- else [ScriptTransfer(i.caller, prize, wlgAssetId)]
3423- }
3424- else nil
3425- $Tuple2((((((((((prologActions ++ loot) ++ (if (shouldZeroBuffs)
3426- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
3427- else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
3428- then xpSuccessRob
3429- else xpFailRob)._1) :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)) :+ IntegerEntry(countKey, (count + 1))) :+ IntegerEntry(keyUserLastRobberyDay(addr), today)) :+ IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))) :+ StringEntry(eqKey, newEq)) :+ IntegerEntry(keyDuckHealth(duckAssetId), max([newHP, 0]))), 0)
3430- }
3431- }
3432- }
3433- }
3434- }
3435- }
3436- }
3437- }
3438- }
3439-
3440-
3441-
3442-@Callable(i)
3443-func buyRoboDuck () = if (!(KS_ALLOW_ROBO_DUCKS))
3444- then throw("Feature is turned off")
3445- else {
3446- let prologActions = prolog(i)
3447- if ((size(i.payments) != 1))
3448- then throw("Exactly one payment required")
3449- else {
3450- let pmt = value(i.payments[0])
3451- if ((pmt.assetId != usdtAssetId))
3452- then throw("Allowed USDT payment only!")
3453- else if ((pmt.amount != ROBO_DUCK_USDT))
3454- then throw((("Payment attached should be " + fixedPoint(ROBO_DUCK_USDT, 6)) + " USDT"))
3455- else {
3456- let nextNum = valueOrElse(getInteger(keyNextRoboDuck()), 0)
3457- let bytez = toBytes(nextNum)
3458- let name = ((ROBO_PREFIX + "-") + takeRight(toBase16String(bytez), 8))
3459- let color = takeRight(toBase16String(sha256_16Kb(bytez)), 6)
3460- let issue = Issue(name, ("Robo Duck NFT for WavesLands game, background color = #" + color), 1, 0, false)
3461- let assetId = calculateAssetId(issue)
3462- $Tuple2(((((prologActions :+ IntegerEntry(keyNextRoboDuck(), (nextNum + 1))) :+ issue) :+ ScriptTransfer(i.originCaller, 1, assetId)) :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)), $Tuple2(toBase58String(assetId), color))
3463- }
3464- }
3465- }
3466-
3467-
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let KS_SEPARATE_PUBLIC_KEY = false
55
6-let KS_ALLOW_BIG_INFRA_MERGE = false
7-
86 let KS_ALLOW_ROBO_DUCKS = false
97
108 let DAY_MILLIS = 86400000
119
12-let OLD_STAKING_DEADLINE = 1727740799000
10+let OLD_STAKING_DEADLINE = 1731279600000
1311
1412 let chain = take(drop(this.bytes, 1), 1)
1513
1614 let pub = match chain {
1715 case _ =>
1816 if ((base58'2W' == $match0))
1917 then if (KS_SEPARATE_PUBLIC_KEY)
2018 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
2119 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
2220 else if ((base58'2T' == $match0))
2321 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
2422 else throw("Unknown chain")
2523 }
2624
2725 let usdtAssetId = match chain {
2826 case _ =>
2927 if ((base58'2W' == $match0))
3028 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
3129 else if ((base58'2T' == $match0))
3230 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
3331 else throw("Unknown chain")
3432 }
3533
3634 let defaultRestAddressStr = match chain {
3735 case _ =>
3836 if ((base58'2W' == $match0))
3937 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
4038 else if ((base58'2T' == $match0))
4139 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
4240 else throw("Unknown chain")
4341 }
4442
4543 let acres2AddressStr = match chain {
4644 case _ =>
4745 if ((base58'2W' == $match0))
4846 then "3P4UH3T9nXpMNpUmSmQjPmEz3G85t3zn6eA"
4947 else if ((base58'2T' == $match0))
5048 then "3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh"
5149 else throw("Unknown chain")
5250 }
5351
54-let InfraUpgradeCostS = match chain {
55- case _ =>
56- if ((base58'2W' == $match0))
57- then 10000000000
58- else if ((base58'2T' == $match0))
59- then 100000000
60- else throw("Unknown chain")
61-}
62-
6352 let arbitrageDelay = match chain {
6453 case _ =>
6554 if ((base58'2W' == $match0))
6655 then DAY_MILLIS
6756 else if ((base58'2T' == $match0))
6857 then 60000
6958 else throw("Unknown chain")
7059 }
7160
7261 let SEP = "__"
7362
7463 let MULT6 = 1000000
7564
7665 let MULT8 = 100000000
7766
7867 let SSIZE = 25
7968
8069 let MSIZE = 100
8170
8271 let LSIZE = 225
8372
8473 let XLSIZE = 400
8574
8675 let XXLSIZE = 625
8776
8877 let ITER6 = [0, 1, 2, 3, 4, 5]
8978
9079 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
9180
9281
93-let IdxCfgStakingDapp = 1
94-
9582 let IdxCfgEconomyDapp = 2
9683
9784 let IdxCfgGovernanceDapp = 3
9885
9986 let IdxCfgWlgDapp = 4
10087
10188 let IdxCfgTournamentDapp = 7
10289
10390 let IdxCfgAcresDapp = 8
10491
10592 func keyRestCfg () = "%s__restConfig"
10693
10794
10895 func keyRestAddress () = "%s__restAddr"
10996
11097
11198 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
11299
113100
114101 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
115102
116103
117104 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
118105
119106 let restCfg = readRestCfgOrFail(restContract)
120107
121-let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
122-
123108 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
124109
125110 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
126111
127112 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
128113
129114 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
130115
131116 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
132117
133118 let recLandNum = 0
134119
135120 let recLandSize = 1
136121
137122 let recTerrains = 2
138123
139124 let recContinent = 3
140-
141-let wlgAssetIdKey = "wlg_assetId"
142-
143-let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
144125
145126 let acresAssetIdKey = "acresAssetId"
146127
147128 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
148129
149130 let randomDelay = 2
150131
151132 func keyCommit (address) = ("finishBlockFor_" + address)
152133
153134
154135 func keyResProportions () = "resTypesProportions"
155136
156137
157138 func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
158139
159140
160141 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
161142
162143
163144 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
164145
165146
166-func asString (v) = match v {
167- case s: String =>
168- s
169- case _ =>
170- throw("fail to cast into String")
171-}
172-
173-
174147 func asInt (v) = match v {
175148 case n: Int =>
176149 n
177150 case _ =>
178151 throw("fail to cast into Int")
179152 }
180153
181154
182155 func asAnyList (v) = match v {
183156 case l: List[Any] =>
184157 l
185158 case _ =>
186159 throw("fail to cast into List[Any]")
187-}
188-
189-
190-func asBoolean (v) = match v {
191- case s: Boolean =>
192- s
193- case _ =>
194- throw("fail to cast into Boolean")
195160 }
196161
197162
198163 func numPiecesBySize (landSize) = match landSize {
199164 case _ =>
200165 if (("S" == $match0))
201166 then SSIZE
202167 else if (("M" == $match0))
203168 then MSIZE
204169 else if (("L" == $match0))
205170 then LSIZE
206171 else if (("XL" == $match0))
207172 then XLSIZE
208173 else if (("XXL" == $match0))
209174 then XXLSIZE
210175 else throw("Unknown land size")
211176 }
212-
213-
214-func isDigit (s) = isDefined(parseInt(s))
215177
216178
217179 func keyBlocked () = "contractsBlocked"
218180
219181
220182 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
221183
222184
223185 func fixedPoint (val,decimals) = {
224186 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
225187 let lowPart = toString((val % tenPow))
226188 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
227189 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
228190 }
229191
230192
231193 func getRandomNumber (maxValue,salt,entropy) = if ((0 >= maxValue))
232194 then throw("maxValue should be > 0")
233195 else {
234196 let randomHash = sha256((salt + entropy))
235197 (toInt(randomHash) % maxValue)
236198 }
237199
238200
239201 func finalTime () = min([lastBlock.timestamp, OLD_STAKING_DEADLINE])
240202
241203
242204 let LANDPREFIX = "LAND"
243205
244206 let DUCKPREFIX = "DUCK"
245207
246208 let ROBO_PREFIX = "ROBO"
247209
248210 let ARTPRESALE = "PRESALE"
249211
250212 let NUMRES = 6
251213
252214 let MAX_LANDS_STAKED_BY_USER = 25
253215
254216 let DAILYRESBYPIECE = 3456000
255217
256218 let WHMULTIPLIER = 10000000000
257219
258220 let DEFAULTLOCATION = "Africa_F_Africa"
259221
260222 let RESOURCEPRICEMIN = 39637
261223
262-let ESSELLCOEF = 10
263-
264224 let MIN_USDT_FEE_DELIVERY = 50000
265225
266226 let USDT2ACRES_MULTIPLIER = 10
267-
268-let MIN_WLGOLD_ROBBERY = 100000000
269-
270-let ALLOWED_FREE_ROBBERIES = 0
271-
272-let ACRES_FOR_ROBBERY_ATTEMPT = 200000000
273227
274228 let ALLOWED_FREE_DELIVERIES = 0
275229
276230 let ACRES_FOR_DELIVERY_ATTEMPT = 200000000
277231
278232 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3", "Boom-Dog L1", "Boom-Dog L2", "Boom-Dog L3"]
279233
280-let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
281-
282-let COEFF2MAT = 10000000
283-
284234 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_", "23_23_5_20_23_6_35_2_100_0,0,0,0,0,0,0_", "23_23_5_20_23_6_70_2_150_0,0,0,0,0,0,0_", "23_23_5_20_23_6_105_2_200_0,0,0,0,0,0,0_"]
285235
286236 let rIdxCoeff = 6
287-
288-let rIdxEffect = 8
289237
290238 let rIdxRequirements = 9
291239
292240 let rIdxSlots = 10
293241
294242 let PRODUCTPKGSIZE = 10
295243
296244 let whIdxLevels = 0
297245
298246 let whIdxRes = 1
299247
300248 let whIdxMat = 2
301249
302250 let whIdxProd = 3
303251
304252 let whIdxLOFT = 4
305253
306254 let volLocked = 0
307255
308256 let volOccupied = 1
309257
310258 let volFree = 2
311259
312260 let volTotal = 3
313261
314262 let bpIdxLevel = 0
315263
316264 let bpIdxRes = 1
317265
318266 let bpIdxMat = 2
319267
320268 let bpIdxProd = 3
321-
322-let locIdxContinent = 0
323269
324270 let locIdxType = 1
325271
326272 let locIdxId = 2
327273
328274 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
329275
330276
331277 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
332278
333279
334280 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
335281
336282
337283 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
338284
339285
340286 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
341287
342288
343289 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
344290
345291
346292 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
347293
348294
349295 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
350296
351297
352298 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
353299
354300
355301 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
356302
357303
358304 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
359305
360306
361307 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
362308
363309
364310 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
365311
366312
367313 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
368314
369315
370316 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
371317
372318
373319 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
374320
375321
376322 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
377323
378324
379325 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
380326
381327
382-func keyEsWarehouse () = "emergencyWarehouseProducts"
383-
384-
385328 let deliveryFundKey = "deliveryFund"
386329
387330 let lastTourIdKey = "%s__lastTourId"
388-
389-func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
390-
391-
392-func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
393-
394-
395-func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
396-
397-
398-let idxStatic = 0
399-
400-let idxDynamic = 1
401-
402-let tStaticEnd = 6
403-
404-let tDynamicStatus = 1
405-
406-func getTourData (tourContract,tId) = {
407- let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
408- let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
409-[static, dynamic]
410- }
411-
412-
413-func isInTournament (tourContract,location) = {
414- let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
415- let loc = split(location, "_")
416- let now = lastBlock.timestamp
417- let tData = getTourData(tourContract, lastId)
418- let static = tData[idxStatic]
419- let dynamic = tData[idxDynamic]
420- if (if (if ((loc[locIdxType] == "T"))
421- then (parseIntValue(loc[locIdxContinent]) == lastId)
422- else false)
423- then (dynamic[tDynamicStatus] == "INPROGRESS")
424- else false)
425- then (parseIntValue(static[tStaticEnd]) > now)
426- else false
427- }
428-
429-
430-func onMission (tourContract,location) = {
431- let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
432- let loc = split(location, "_")
433- let now = lastBlock.timestamp
434- let tData = getTourData(tourContract, lastId)
435- let static = tData[idxStatic]
436- let dynamic = tData[idxDynamic]
437- let locType = loc[locIdxType]
438- if (if (if ((loc[locIdxType] == "T"))
439- then (parseIntValue(loc[locIdxContinent]) == lastId)
440- else false)
441- then (dynamic[tDynamicStatus] == "INPROGRESS")
442- else false)
443- then (parseIntValue(static[tStaticEnd]) > now)
444- else false
445- }
446-
447-
448-func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
449-
450-
451-func cheatAttempt (oldLoc,newLoc,cheatCase) = throw(((((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc) + ", case=") + toString(cheatCase)))
452-
453331
454332 let SCALE8 = 100000000
455333
456334 let xpLevelScale = 3200
457335
458336 let xpLevelRecipPow = 4000
459337
460338 let numPointsOnLevelUp = 3
461339
462340 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
463341
464342 let charStrength = 0
465343
466344 let charAccuracy = 1
467345
468346 let charIntellect = 2
469347
470348 let charEndurance = 3
471349
472350 let charDexterity = 4
473-
474-let segBackpack = 0
475-
476-let NUMSEGMENTS = 6
477351
478352 let NUMMAINAUX = 2
479353
480354 let MAXSLOTS = 2
481355
482356 let MAXPRODINSLOT = 30
483357
484358 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
485359
486360
487361 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
488362
489363
490364 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
491365
492366
493367 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
494368
495369
496370 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
497371
498372
499373 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
500374
501375
502376 func keyUserXP (addr) = ("userXP_" + addr)
503377
504378
505379 func keyUserLevel (addr) = ("userLevel_" + addr)
506380
507381
508382 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
509383
510384
511385 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
512386
513387
514388 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
515389
516390
517-func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
518-
519-
520-func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
521-
522-
523-func keyDuckRobberyCount (duckAssetId) = ("totalRobberyCountByDuck_" + duckAssetId)
524-
525-
526-func keyUserRobberyCount (addr) = ("userRobberyCount_" + addr)
527-
528-
529-func keyUserLastRobberyDay (addr) = ("userLastRobberyDay_" + addr)
530-
531-
532391 func keyDuckDeliveryCount (duckAssetId) = ("totalDeliveryCountByDuck_" + duckAssetId)
533392
534393
535394 func keyUserDeliveryCount (addr) = ("userDeliveryCount_" + addr)
536395
537396
538397 func keyUserLastDeliveryDay (addr) = ("userLastDeliveryDay_" + addr)
539398
540399
541400 let xpClaim = 10000
542401
543-let xpSuccessFlight = 10000
544-
545-let xpFailFlight = 2000
546-
547-let xpSuccessRob = 10000
548-
549-let xpFailRob = 2000
550-
551-let xpCallES = 100000
552-
553402 let xpCustomName = 1000000
554403
555-let xpNewSLand = 5000000
556-
557-let xpUpgradeInfra = 10000
558-
559-let xpMerge = 1000000
560-
561404 let xpOnboard = 1000000
562-
563-let xpHeal = 10000
564405
565406 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
566407
567408
568409 func maxHealth (level) = (100 + level)
569410
570411
571412 func levelUp (currLevel,newXP) = {
572413 let newLevel = levelByXP(newXP)
573414 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
574415 }
575416
576417
577-func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
578- let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
579- let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
580- let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
581- let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
582- ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
583- then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
584- else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
585- }
586-
587-
588418 let DAYMILLIS = 86400000
589419
590420 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
591421
592422
593423 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
594424
595425
596-let incubatorAddr = match chain {
597- case _ =>
598- if ((base58'2W' == $match0))
599- then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
600- else if ((base58'2T' == $match0))
601- then this
602- else throw("Unknown chain")
603-}
604-
605-let breederAddr = match chain {
606- case _ =>
607- if ((base58'2W' == $match0))
608- then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
609- else if ((base58'2T' == $match0))
610- then this
611- else throw("Unknown chain")
612-}
613-
614-let FIVEMINUTESMILLIS = 300000
615-
616426 let RENAMINGCOST = 5000000
617427
618428 let MAXNAMELEN = 50
619429
620-let InfraUpgradeCostSUsdt = 10000000
621-
622-let EXPMATERIALS = match chain {
623- case _ =>
624- if ((base58'2W' == $match0))
625- then 252289527462
626- else if ((base58'2T' == $match0))
627- then 2522895274
628- else throw("Unknown chain")
629-}
630-
631-let EXPUSDT = match chain {
632- case _ =>
633- if ((base58'2W' == $match0))
634- then 250000000
635- else if ((base58'2T' == $match0))
636- then 250000000
637- else throw("Unknown chain")
638-}
639-
640-let ROBO_DUCK_USDT = 100000
641-
642-let S_COST_ACRES = 2500000000
643-
644-let FIVEX = toBigInt(5)
645-
646-let TWENTYX = toBigInt(20)
647-
648-let TWENTY2X = toBigInt((20 * 20))
649-
650-let TWENTY3X = toBigInt(((20 * 20) * 20))
651-
652-let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
653-
654-let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
655-
656430 let PRESALENUMLANDS = 500
657431
658-func keyNextFreeLandNum () = "nextLandNum"
659-
660-
661432 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
662-
663-
664-func keyLandToAssetId (landNum) = ("la_" + landNum)
665433
666434
667435 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
668436
669437
670438 func keyLandNumToOwner (landNum) = ("lo_" + landNum)
671439
672440
673441 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
674442
675443
676444 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
677445
678446
679447 func keyOldies () = "oldiesList"
680448
681449
682-func keyNextRoboDuck () = "nextRoboDuck"
683-
684-
685450 let claimModeWh = 0
686451
687452 let claimModeDuck = 1
688453
689454 let claimModeWhThenDuck = 2
690-
691-let flHealth = 0
692-
693-let flTimestamp = 5
694-
695-let flBonus = 6
696-
697-let flProdsUsed = 7
698-
699-let rlHealth = 0
700-
701-let rlProdsUsed = 1
702-
703-let rlType = 0
704-
705-let rlLastTx = 2
706-
707-let rlTimestamp = 3
708-
709-func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
710-
711-
712-func toVolume (amount,pkgSize) = {
713- let pkgs = if ((amount >= 0))
714- then (((amount + pkgSize) - 1) / pkgSize)
715- else -((((-(amount) + pkgSize) - 1) / pkgSize))
716- (pkgs * MULT8)
717- }
718-
719455
720456 func distributeByWeights (total,weights) = {
721457 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
722458 if ((0 >= sum))
723459 then throw("Zero weights sum")
724460 else {
725461 let norm6 = fraction(total, MULT6, sum)
726462 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
727463
728464 let $l = weights
729465 let $s = size($l)
730466 let $acc0 = nil
731467 func $f0_1 ($a,$i) = if (($i >= $s))
732468 then $a
733469 else normalizer($a, $l[$i])
734470
735471 func $f0_2 ($a,$i) = if (($i >= $s))
736472 then $a
737473 else throw("List size exceeds 6")
738474
739475 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
740476 }
741477 }
742478
743479
744480 func getNeededMaterials (total) = {
745481 let props = split(value(getString(keyResProportions())), "_")
746482 if ((size(props) != NUMRES))
747483 then throw("Wrong proportions data")
748484 else {
749485 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
750486 distributeByWeights(total, r)
751487 }
752488 }
753-
754-
755-func subtractMaterials (shouldUseMat,has,totalNeed) = {
756- let need = getNeededMaterials(totalNeed)
757- func subtractor (acc,idx) = {
758- let result = (parseIntValue(has[idx]) - need[idx])
759- if ((0 > result))
760- then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
761- else (acc :+ toString(result))
762- }
763-
764- if (shouldUseMat)
765- then {
766- let $l = ITER6
767- let $s = size($l)
768- let $acc0 = nil
769- func $f0_1 ($a,$i) = if (($i >= $s))
770- then $a
771- else subtractor($a, $l[$i])
772-
773- func $f0_2 ($a,$i) = if (($i >= $s))
774- then $a
775- else throw("List size exceeds 6")
776-
777- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
778- }
779- else has
780- }
781-
782-
783-func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
784- then $Tuple3(oldEq, false, false)
785- else {
786- func subUsed (acc,idxAmt) = {
787- let parts = split(idxAmt, ",")
788- if ((size(parts) != 2))
789- then throw("Incorrect format, should be index,amount")
790- else {
791- let idx = parseIntValue(parts[0])
792- if (if ((0 > idx))
793- then true
794- else (idx >= size(productionMatrix)))
795- then throw("Unknown product idx")
796- else {
797- let amt = parseIntValue(parts[1])
798- let eqParts = split(acc._1, (parts[0] + ":"))
799- if ((size(eqParts) != 2))
800- then throw((("You don't have " + prodTypes[idx]) + " equipped"))
801- else {
802- let tmp = eqParts[1]
803- let numLen = if (isDigit(take(drop(tmp, 1), 1)))
804- then 2
805- else 1
806- let curr = parseIntValue(take(tmp, numLen))
807- let tail = drop(tmp, numLen)
808- let newAmt = if ((curr >= amt))
809- then (curr - amt)
810- else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
811- $Tuple3(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
812- then true
813- else if (if ((idx >= 6))
814- then (8 >= idx)
815- else false)
816- then (newAmt == 0)
817- else false, if (acc._3)
818- then true
819- else if (if ((idx >= 3))
820- then (5 >= idx)
821- else false)
822- then (amt > 0)
823- else false)
824- }
825- }
826- }
827- }
828-
829- let $l = split(pUsed, "_")
830- let $s = size($l)
831- let $acc0 = $Tuple3(oldEq, false, false)
832- func $f0_1 ($a,$i) = if (($i >= $s))
833- then $a
834- else subUsed($a, $l[$i])
835-
836- func $f0_2 ($a,$i) = if (($i >= $s))
837- then $a
838- else throw("List size exceeds 10")
839-
840- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
841- }
842489
843490
844491 func prodStrToBytes (prodStr) = {
845492 let pList = if ((prodStr == ""))
846493 then nil
847494 else split_4C(prodStr, "_")
848495 func toBV (acc,recipe) = {
849496 let j = (size(acc) / 8)
850497 let curr = if ((size(pList) > j))
851498 then parseIntValue(pList[j])
852499 else 0
853500 (acc + toBytes(curr))
854501 }
855502
856503 let $l = productionMatrix
857504 let $s = size($l)
858505 let $acc0 = base58''
859506 func $f0_1 ($a,$i) = if (($i >= $s))
860507 then $a
861508 else toBV($a, $l[$i])
862509
863510 func $f0_2 ($a,$i) = if (($i >= $s))
864511 then $a
865512 else throw("List size exceeds 50")
866513
867514 $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)
868515 }
869516
870517
871518 func bytesToProdStr (bv) = {
872519 func fromBV (acc,recipe) = {
873520 let j = size(acc)
874521 let b = take(drop(bv, (8 * j)), 8)
875522 (acc :+ toString(toInt(b)))
876523 }
877524
878525 makeString_2C({
879526 let $l = productionMatrix
880527 let $s = size($l)
881528 let $acc0 = nil
882529 func $f0_1 ($a,$i) = if (($i >= $s))
883530 then $a
884531 else fromBV($a, $l[$i])
885532
886533 func $f0_2 ($a,$i) = if (($i >= $s))
887534 then $a
888535 else throw("List size exceeds 50")
889536
890537 $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)
891538 }, "_")
892539 }
893540
894541
895542 func checkStatRequirements (duckStats,reqs) = {
896543 func check (acc,j) = {
897544 let buff = if ((size(duckStats) > (7 + j)))
898545 then duckStats[(7 + j)]
899546 else 0
900547 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
901548 then throw(("Requirement not satisfied: " + requirements[j]))
902549 else true
903550 }
904551
905552 let $l = [0, 1, 2, 3, 4, 5, 6]
906553 let $s = size($l)
907554 let $acc0 = false
908555 func $f0_1 ($a,$i) = if (($i >= $s))
909556 then $a
910557 else check($a, $l[$i])
911558
912559 func $f0_2 ($a,$i) = if (($i >= $s))
913560 then $a
914561 else throw("List size exceeds 7")
915562
916563 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
917564 }
918565
919566
920567 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
921568 let parts = split(idxCnt, ":")
922569 if ((size(parts) != 2))
923570 then throw("Incorrect format, should be index:amount")
924571 else if (if (!(isPositive))
925572 then (size(parts[0]) != 2)
926573 else false)
927574 then throw("Product idx should be 2 digits, zero padded")
928575 else {
929576 let productIdx = parseIntValue(parts[0])
930577 let count = parseIntValue(parts[1])
931578 if (if ((0 > productIdx))
932579 then true
933580 else (productIdx >= size(productionMatrix)))
934581 then throw("Unknown product idx")
935582 else if ((0 > count))
936583 then throw("Count can't be negative")
937584 else if ((count > MAXPRODINSLOT))
938585 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
939586 else if ((count == 0))
940587 then $Tuple2(pList, false)
941588 else {
942589 let head = take(pList, (8 * productIdx))
943590 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
944591 let tail = drop(pList, (8 * (productIdx + 1)))
945592 let recipe = split(productionMatrix[productIdx], "_")
946593 if (if (!(isPositive))
947594 then (count > curr)
948595 else false)
949596 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
950597 else {
951598 let isBigItem = if (if (!(isPositive))
952599 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
953600 else false)
954601 then {
955602 let compat = recipe[rIdxSlots]
956603 if ((compat == ""))
957604 then throw("Item cannot be equipped")
958605 else {
959606 let c = parseIntValue(compat)
960607 let cSeg = (c / 100)
961608 if ((segment != cSeg))
962609 then throw("Segment incompatible")
963610 else {
964611 let cMainAux = ((c % 100) / 10)
965612 if ((mainAux != cMainAux))
966613 then throw("Slot incompatible")
967614 else {
968615 let cNumSlots = (c % 10)
969616 if (if ((slot != 0))
970617 then (cNumSlots > 1)
971618 else false)
972619 then throw("Big items should occupy slot 0")
973620 else (cNumSlots > 1)
974621 }
975622 }
976623 }
977624 }
978625 else false
979626 $Tuple2(((head + toBytes((curr + (if (isPositive)
980627 then count
981628 else -(count))))) + tail), isBigItem)
982629 }
983630 }
984631 }
985632 }
986633
987634
988635 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
989636 then {
990637 let slots = split(g, ",")
991638 if ((size(slots) > MAXSLOTS))
992639 then throw("Wrong slots format")
993640 else {
994641 let s0 = slots[0]
995642 let s1 = if ((size(slots) > 1))
996643 then slots[1]
997644 else ""
998645 if (if ((s0 == ""))
999646 then (s1 == "")
1000647 else false)
1001648 then bpIn
1002649 else {
1003650 let tmpS0 = if ((s0 != ""))
1004651 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
1005652 else $Tuple2(bpIn, false)
1006653 if ((s1 != ""))
1007654 then if (tmpS0._2)
1008655 then throw("Big item already occupies slot")
1009656 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
1010657 else tmpS0._1
1011658 }
1012659 }
1013660 }
1014661 else bpIn
1015662
1016663
1017664 func dressB (segList,pBytes,isPositive,stats) = {
1018665 func segment (acc,seg) = {
1019666 let j = acc._1
1020667 let mainAux = split(seg, ";")
1021668 if ((size(mainAux) != NUMMAINAUX))
1022669 then throw("Wrong segment format")
1023670 else {
1024671 let m = mainAux[0]
1025672 let a = mainAux[1]
1026673 if (if ((m == ""))
1027674 then (a == "")
1028675 else false)
1029676 then $Tuple2((j + 1), acc._2)
1030677 else {
1031678 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
1032679 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
1033680 }
1034681 }
1035682 }
1036683
1037684 ( let $l = segList
1038685 let $s = size($l)
1039686 let $acc0 = $Tuple2(0, pBytes)
1040687 func $f0_1 ($a,$i) = if (($i >= $s))
1041688 then $a
1042689 else segment($a, $l[$i])
1043690
1044691 func $f0_2 ($a,$i) = if (($i >= $s))
1045692 then $a
1046693 else throw("List size exceeds 6")
1047694
1048695 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
1049696 }
1050697
1051698
1052-func canWearCurrentEquipment (duckAssetId) = {
1053- let eqKey = keyDuckEquipment(duckAssetId)
1054- let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
1055- let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
1056- let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
1057- let segBpAux = split(currEq[segBackpack], ";")[1]
1058- let buffEffect = if ((segBpAux == ""))
1059- then 0
1060- else {
1061- let aux0 = split(segBpAux, ",")[0]
1062- if ((aux0 == ""))
1063- then 0
1064- else {
1065- let idxCnt = split(aux0, ":")
1066- let idx = idxCnt[0]
1067- let cnt = idxCnt[1]
1068- if (if (if (if (if ((idx == "06"))
1069- then true
1070- else (idx == "07"))
1071- then true
1072- else (idx == "08"))
1073- then (cnt != "")
1074- else false)
1075- then (parseIntValue(cnt) > 0)
1076- else false)
1077- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
1078- else 0
1079- }
1080- }
1081- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
1082- let newProdB = dressB(currEq, tempProdB, false, stats)
1083- (newProdB == newProdB)
1084- }
1085-
1086-
1087699 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
1088700 then throw("Wrong proportions data")
1089701 else {
1090702 func updater (acc,i) = {
1091703 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
1092704 if ((0 > result))
1093705 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
1094706 else (acc :+ toString(result))
1095707 }
1096708
1097709 let $l = ITER6
1098710 let $s = size($l)
1099711 let $acc0 = nil
1100712 func $f0_1 ($a,$i) = if (($i >= $s))
1101713 then $a
1102714 else updater($a, $l[$i])
1103715
1104716 func $f0_2 ($a,$i) = if (($i >= $s))
1105717 then $a
1106718 else throw("List size exceeds 6")
1107719
1108720 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1109721 }
1110722
1111723
1112724 func updateProportions (terrainCounts,landSizeIndex,sign) = {
1113725 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1114726 makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
1115727 }
1116728
1117729
1118730 func countTerrains (terrains) = [(size(split(terrains, "A")) - 1), (size(split(terrains, "B")) - 1), (size(split(terrains, "C")) - 1), (size(split(terrains, "D")) - 1), (size(split(terrains, "E")) - 1), (size(split(terrains, "F")) - 1)]
1119731
1120732
1121733 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
1122734 func adder (acc,i) = {
1123735 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
1124736 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
1125737 }
1126738
1127739 let r = {
1128740 let $l = ITER6
1129741 let $s = size($l)
1130742 let $acc0 = nil
1131743 func $f0_1 ($a,$i) = if (($i >= $s))
1132744 then $a
1133745 else adder($a, $l[$i])
1134746
1135747 func $f0_2 ($a,$i) = if (($i >= $s))
1136748 then $a
1137749 else throw("List size exceeds 6")
1138750
1139751 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1140752 }
1141753 makeString(r, "_")
1142754 }
1143755
1144756
1145757 func virtClaimAddRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
1146758 func adder (acc,i) = {
1147759 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
1148760 let totalResType = (parseIntValue(currentRes[i]) + resOfType)
1149761 $Tuple2((acc._1 :+ totalResType), (acc._2 + totalResType))
1150762 }
1151763
1152764 let $l = ITER6
1153765 let $s = size($l)
1154766 let $acc0 = $Tuple2(nil, 0)
1155767 func $f0_1 ($a,$i) = if (($i >= $s))
1156768 then $a
1157769 else adder($a, $l[$i])
1158770
1159771 func $f0_2 ($a,$i) = if (($i >= $s))
1160772 then $a
1161773 else throw("List size exceeds 6")
1162774
1163775 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1164776 }
1165777
1166778
1167779 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
1168780 func adder (acc,terrainCount) = {
1169781 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCount) * landSizeIndex)
1170782 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
1171783 }
1172784
1173785 let $l = terrainCounts
1174786 let $s = size($l)
1175787 let $acc0 = $Tuple2(nil, 0)
1176788 func $f0_1 ($a,$i) = if (($i >= $s))
1177789 then $a
1178790 else adder($a, $l[$i])
1179791
1180792 func $f0_2 ($a,$i) = if (($i >= $s))
1181793 then $a
1182794 else throw("List size exceeds 6")
1183795
1184796 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1185797 }
1186798
1187799
1188800 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
1189801 let resListToClaim = resToClaim._1
1190802 let resAmToClaim = resToClaim._2
1191803 if ((resAmToClaim == 0))
1192804 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
1193805 else if ((whSpaceLeft >= resAmToClaim))
1194806 then {
1195807 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
1196808
1197809 let r = {
1198810 let $l = ITER6
1199811 let $s = size($l)
1200812 let $acc0 = nil
1201813 func $f0_1 ($a,$i) = if (($i >= $s))
1202814 then $a
1203815 else addLists($a, $l[$i])
1204816
1205817 func $f0_2 ($a,$i) = if (($i >= $s))
1206818 then $a
1207819 else throw("List size exceeds 6")
1208820
1209821 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1210822 }
1211823 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
1212824 }
1213825 else {
1214826 func addPartLists (acc,i) = {
1215827 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
1216828 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
1217829 }
1218830
1219831 let r = {
1220832 let $l = ITER6
1221833 let $s = size($l)
1222834 let $acc0 = $Tuple2(nil, nil)
1223835 func $f0_1 ($a,$i) = if (($i >= $s))
1224836 then $a
1225837 else addPartLists($a, $l[$i])
1226838
1227839 func $f0_2 ($a,$i) = if (($i >= $s))
1228840 then $a
1229841 else throw("List size exceeds 6")
1230842
1231843 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1232844 }
1233845 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
1234846 }
1235847 }
1236848
1237849
1238-func abs (x) = if ((x >= toBigInt(0)))
1239- then x
1240- else -(x)
1241-
1242-
1243-let freq = [[6, 9, 14, 15, 16], [5, 8, 13, 14, 15], [1, 4, 9, 10, 15], [1, 6, 7, 15, 19], [4, 7, 8, 13, 18]]
1244-
1245-func genChar (n,freqs) = {
1246- let rem = toInt((n % TWENTYX))
1247- let letter = if ((freqs[0] > rem))
1248- then "A"
1249- else if ((freqs[1] > rem))
1250- then "B"
1251- else if ((freqs[2] > rem))
1252- then "C"
1253- else if ((freqs[3] > rem))
1254- then "D"
1255- else if ((freqs[4] > rem))
1256- then "E"
1257- else "F"
1258- letter
1259- }
1260-
1261-
1262-func genTerrains (seed,continentIdx) = {
1263- let f = freq[continentIdx]
1264- func terrainGenerator (acc,elem) = $Tuple2((((((acc._1 + genChar(acc._2, f)) + genChar((acc._2 / TWENTYX), f)) + genChar((acc._2 / TWENTY2X), f)) + genChar((acc._2 / TWENTY3X), f)) + genChar((acc._2 / TWENTY4X), f)), (acc._2 / TWENTY5X))
1265-
1266- let t = {
1267- let $l = [1, 2, 3, 4, 5]
1268- let $s = size($l)
1269- let $acc0 = $Tuple2("", (seed / FIVEX))
1270- func $f0_1 ($a,$i) = if (($i >= $s))
1271- then $a
1272- else terrainGenerator($a, $l[$i])
1273-
1274- func $f0_2 ($a,$i) = if (($i >= $s))
1275- then $a
1276- else throw("List size exceeds 5")
1277-
1278- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1279- }
1280- t._1
1281- }
1282-
1283-
1284-let PERM25 = [7, 2, 15, 19, 8, 24, 1, 21, 16, 5, 0, 22, 20, 23, 11, 4, 18, 12, 6, 10, 3, 17, 13, 9, 14]
1285-
1286-let TCHARS = ["A", "B", "C", "D", "E", "F"]
1287-
1288-func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
1289- func step1 (acc,s) = {
1290- let j = acc._2
1291- let el = parseIntValue(s)
1292- let x = if ((el == 0))
1293- then 0
1294- else if ((el >= (4 * landSizeIndex)))
1295- then (el / landSizeIndex)
1296- else if ((el > (3 * landSizeIndex)))
1297- then 3
1298- else (((el - 1) / landSizeIndex) + 1)
1299- $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
1300- }
1301-
1302- let t = {
1303- let $l = sumTerrains
1304- let $s = size($l)
1305- let $acc0 = $Tuple3(nil, 0, 0)
1306- func $f0_1 ($a,$i) = if (($i >= $s))
1307- then $a
1308- else step1($a, $l[$i])
1309-
1310- func $f0_2 ($a,$i) = if (($i >= $s))
1311- then $a
1312- else throw("List size exceeds 6")
1313-
1314- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1315- }
1316- let arr = t._1
1317- let maxIdx = value(indexOf(arr, max(arr)))
1318- let delta = (t._3 - 25)
1319- func subber (acc,idx) = {
1320- let val = if ((idx == maxIdx))
1321- then (arr[idx] - delta)
1322- else arr[idx]
1323- let zeroes = if ((val == 0))
1324- then nil
1325- else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
1326- let c = TCHARS[idx]
1327- func listGen (ac,ignored) = (ac :+ c)
1328-
1329- let z = {
1330- let $l = zeroes
1331- let $s = size($l)
1332- let $acc0 = nil
1333- func $f1_1 ($a,$i) = if (($i >= $s))
1334- then $a
1335- else listGen($a, $l[$i])
1336-
1337- func $f1_2 ($a,$i) = if (($i >= $s))
1338- then $a
1339- else throw("List size exceeds 25")
1340-
1341- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
1342- }
1343- (acc ++ z)
1344- }
1345-
1346- let r = {
1347- let $l = ITER6
1348- let $s = size($l)
1349- let $acc0 = nil
1350- func $f1_1 ($a,$i) = if (($i >= $s))
1351- then $a
1352- else subber($a, $l[$i])
1353-
1354- func $f1_2 ($a,$i) = if (($i >= $s))
1355- then $a
1356- else throw("List size exceeds 6")
1357-
1358- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1359- }
1360- func permut (acc,j) = (acc + r[j])
1361-
1362- let $l = PERM25
1363- let $s = size($l)
1364- let $acc0 = ""
1365- func $f2_1 ($a,$i) = if (($i >= $s))
1366- then $a
1367- else permut($a, $l[$i])
1368-
1369- func $f2_2 ($a,$i) = if (($i >= $s))
1370- then $a
1371- else throw("List size exceeds 25")
1372-
1373- $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
1374- }
1375-
1376-
1377850 func getBackpack (bpKey) = {
1378851 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
1379852 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
1380853 then p[bpIdxRes]
1381854 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
1382855 then p[bpIdxMat]
1383856 else "0_0_0_0_0_0", p[bpIdxProd]]
1384857 }
1385858
1386859
1387860 func getWarehouseTotalVolume (volPrefix) = {
1388861 let parts = split(volPrefix, "_")
1389862 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
1390863 }
1391864
1392865
1393866 func getWarehouseOccupiedVol (currentWh) = {
1394867 let goods = currentWh[whIdxProd]
1395868 func sumResMat (acc,item) = (acc + parseIntValue(item))
1396869
1397870 func sumProd (acc,item) = {
1398871 let idx = acc._1
1399872 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
1400873 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
1401874 }
1402875
1403876 let whResVol = {
1404877 let $l = split(currentWh[whIdxRes], "_")
1405878 let $s = size($l)
1406879 let $acc0 = 0
1407880 func $f0_1 ($a,$i) = if (($i >= $s))
1408881 then $a
1409882 else sumResMat($a, $l[$i])
1410883
1411884 func $f0_2 ($a,$i) = if (($i >= $s))
1412885 then $a
1413886 else throw("List size exceeds 6")
1414887
1415888 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1416889 }
1417890 let whMatVol = {
1418891 let $l = split(currentWh[whIdxMat], "_")
1419892 let $s = size($l)
1420893 let $acc0 = 0
1421894 func $f1_1 ($a,$i) = if (($i >= $s))
1422895 then $a
1423896 else sumResMat($a, $l[$i])
1424897
1425898 func $f1_2 ($a,$i) = if (($i >= $s))
1426899 then $a
1427900 else throw("List size exceeds 6")
1428901
1429902 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1430903 }
1431904 let whGoodsVol = if ((goods == ""))
1432905 then 0
1433906 else ( let $l = split_4C(goods, "_")
1434907 let $s = size($l)
1435908 let $acc0 = $Tuple2(0, 0)
1436909 func $f2_1 ($a,$i) = if (($i >= $s))
1437910 then $a
1438911 else sumProd($a, $l[$i])
1439912
1440913 func $f2_2 ($a,$i) = if (($i >= $s))
1441914 then $a
1442915 else throw("List size exceeds 50")
1443916
1444917 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 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))._2
1445918 ((whResVol + whMatVol) + whGoodsVol)
1446919 }
1447920
1448921
1449922 func getWarehouse (whKey,landIndex,infraLevel) = {
1450923 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
1451924 let whTotal = getWarehouseTotalVolume(volPrefix)
1452925 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
1453926 let wh = split_4C(whStr, ":")
1454927 let whOccupied = getWarehouseOccupiedVol(wh)
1455928 let whLoft = if ((5 > size(wh)))
1456929 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
1457930 else {
1458931 let loft = split(wh[whIdxLOFT], "_")
1459932 let whLocked = parseIntValue(loft[volLocked])
1460933 let occ = if ((size(loft) > 1))
1461934 then parseIntValue(loft[volOccupied])
1462935 else whOccupied
1463936 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
1464937 }
1465938 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
1466939 then wh[whIdxRes]
1467940 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
1468941 then wh[whIdxMat]
1469942 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
1470943 }
1471944
1472945
1473-func getWarehouseSpaceLeft (currentWh) = {
1474- let occupiedVol = getWarehouseOccupiedVol(currentWh)
1475- let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
1476- ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
1477- }
1478-
1479-
1480-func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
1481- then throw("cargoListStr should contain exactly 2 ':' separators")
1482- else {
1483- let resParts = split(cargoParts[0], "_")
1484- let matParts = split(cargoParts[1], "_")
1485- let prodParts = if ((cargoParts[2] == ""))
1486- then nil
1487- else split_4C(cargoParts[2], "_")
1488- if ((size(resParts) != NUMRES))
1489- then throw("All 6 resources should be passed")
1490- else if ((size(matParts) != NUMRES))
1491- then throw("All 6 materials should be passed")
1492- else {
1493- let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
1494- let currWhRes = split(currentWh[whIdxRes], "_")
1495- let currWhMat = split(currentWh[whIdxMat], "_")
1496- let currWhProd = if ((currentWh[whIdxProd] == ""))
1497- then nil
1498- else split_4C(currentWh[whIdxProd], "_")
1499- let currentPackRes = split(currentPack[bpIdxRes], "_")
1500- let currentPackMat = split(currentPack[bpIdxMat], "_")
1501- let currentPackProd = if ((currentPack[bpIdxProd] == ""))
1502- then nil
1503- else split_4C(currentPack[bpIdxProd], "_")
1504- func mvR (acc,item) = {
1505- let i = acc._1
1506- let am = parseIntValue(item)
1507- let whr = parseIntValue(currWhRes[i])
1508- let bpr = parseIntValue(currentPackRes[i])
1509- if ((am == 0))
1510- then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
1511- else if ((am > 0))
1512- then if ((am > bpr))
1513- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
1514- else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
1515- else if ((-(am) > whr))
1516- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
1517- else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
1518- }
1519-
1520- let r = {
1521- let $l = resParts
1522- let $s = size($l)
1523- let $acc0 = $Tuple4(0, nil, nil, 0)
1524- func $f0_1 ($a,$i) = if (($i >= $s))
1525- then $a
1526- else mvR($a, $l[$i])
1527-
1528- func $f0_2 ($a,$i) = if (($i >= $s))
1529- then $a
1530- else throw("List size exceeds 6")
1531-
1532- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1533- }
1534- func mvM (acc,item) = {
1535- let i = acc._1
1536- let am = parseIntValue(item)
1537- let whm = parseIntValue(currWhMat[i])
1538- let bpm = parseIntValue(currentPackMat[i])
1539- if ((am == 0))
1540- then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
1541- else if ((am > 0))
1542- then if ((am > bpm))
1543- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
1544- else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
1545- else if ((-(am) > whm))
1546- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
1547- else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
1548- }
1549-
1550- let m = {
1551- let $l = matParts
1552- let $s = size($l)
1553- let $acc0 = $Tuple4(0, nil, nil, r._4)
1554- func $f1_1 ($a,$i) = if (($i >= $s))
1555- then $a
1556- else mvM($a, $l[$i])
1557-
1558- func $f1_2 ($a,$i) = if (($i >= $s))
1559- then $a
1560- else throw("List size exceeds 6")
1561-
1562- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
1563- }
1564- func mvP (acc,item) = {
1565- let i = acc._1
1566- let am = parseIntValue(item)
1567- let whp = if ((size(currWhProd) > i))
1568- then parseIntValue(currWhProd[i])
1569- else 0
1570- let bpp = if ((size(currentPackProd) > i))
1571- then parseIntValue(currentPackProd[i])
1572- else 0
1573- if ((am == 0))
1574- then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
1575- else if ((am > 0))
1576- then if ((am > bpp))
1577- then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
1578- else {
1579- let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
1580- $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
1581- }
1582- else if ((-(am) > whp))
1583- then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
1584- else {
1585- let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
1586- $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
1587- }
1588- }
1589-
1590- let p = if ((size(prodParts) != 0))
1591- then {
1592- let $l = prodParts
1593- let $s = size($l)
1594- let $acc0 = $Tuple4(0, nil, nil, m._4)
1595- func $f2_1 ($a,$i) = if (($i >= $s))
1596- then $a
1597- else mvP($a, $l[$i])
1598-
1599- func $f2_2 ($a,$i) = if (($i >= $s))
1600- then $a
1601- else throw("List size exceeds 50")
1602-
1603- $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 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)
1604- }
1605- else $Tuple4(0, currWhProd, currentPackProd, m._4)
1606- let volSaldo = p._4
1607- if ((volSaldo > whSpaceLeft))
1608- then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
1609- else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
1610- }
1611- }
1612-
1613-
1614-func expeditionInternal (caller,txId) = {
1615- let userAddr = toString(caller)
1616- let bigNum = abs(toBigInt(txId))
1617- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1618- let landNum = toString(freeNum)
1619- let continentIdx = toInt((bigNum % FIVEX))
1620- let terrains = genTerrains(bigNum, continentIdx)
1621- let continent = continents[continentIdx]
1622- let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
1623- let assetId = calculateAssetId(issue)
1624- let id = toBase58String(assetId)
1625- $Tuple2([IntegerEntry(keyNextFreeLandNum(), (freeNum + 1)), issue, StringEntry(keyLandToAssetId(landNum), id), StringEntry(keyLandAssetIdToOwner(id), userAddr), StringEntry(keyLandNumToOwner(landNum), userAddr), IntegerEntry(keyInfraLevelByAssetId(id), 0), IntegerEntry(keyInfraLevelByAssetIdAndOwner(id, userAddr), 0), ScriptTransfer(caller, 1, assetId)], $Tuple2(id, continent))
1626- }
1627-
1628-
1629-func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
1630- then throw("signature does not match")
1631- else {
1632- let parts = split_4C(toUtf8String(message), ";")
1633- let flightLog = split_4C(parts[0], "|")
1634- let hp = split(flightLog[flHealth], "_")
1635- let curHP = parseIntValue(hp[0])
1636- let newHP = parseIntValue(hp[1])
1637- let newLocTxVer = split(parts[1], ":")
1638- let newLocation = newLocTxVer[0]
1639- let time = parseIntValue(flightLog[flTimestamp])
1640- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
1641- then true
1642- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
1643- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
1644- else {
1645- let txFromMsg = newLocTxVer[1]
1646- let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
1647- if ((lastTx != txFromMsg))
1648- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
1649- else {
1650- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
1651- let keyHealth = keyDuckHealth(duckAssetId)
1652- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
1653- let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
1654- if ((oldFromState != curHP))
1655- then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
1656- else if ((0 >= curHP))
1657- then throw("You can't fly with zero health")
1658- else if (!(canWearCurrentEquipment(duckAssetId)))
1659- then throw("Equipment incompatible")
1660- else {
1661- let bonus = if ((size(flightLog) > flBonus))
1662- then flightLog[flBonus]
1663- else ""
1664- let prodUsed = if ((size(flightLog) > flProdsUsed))
1665- then flightLog[flProdsUsed]
1666- else ""
1667- let sentAmount = if (if ((newHP > 0))
1668- then (bonus == "$")
1669- else false)
1670- then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
1671- else 0
1672- $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
1673- }
1674- }
1675- }
1676- }
1677-
1678-
1679946 func applyBonuses (landAssetId,pieces) = {
1680947 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1681948 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
1682949 let add6 = (infraLevel / 6)
1683950 let add7 = (infraLevel / 7)
1684951 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
1685952 }
1686953
1687954
1688955 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1689- let $t03415334692 = if ((claimMode == claimModeWh))
956+ let $t03424734786 = if ((claimMode == claimModeWh))
1690957 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
1691958 else {
1692959 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
1693960 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
1694961 let loc = split(value(curLocation), "_")
1695962 if ((loc[locIdxType] != "L"))
1696963 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
1697964 else $Tuple2(loc[locIdxId], duckAssetId)
1698965 }
1699- let landAssetId = $t03415334692._1
1700- let duckId = $t03415334692._2
966+ let landAssetId = $t03424734786._1
967+ let duckId = $t03424734786._2
1701968 let asset = value(assetInfo(fromBase58String(landAssetId)))
1702969 let timeKey = keyStakedTimeByAssetId(landAssetId)
1703970 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
1704971 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1705972 if ((owner != addr))
1706973 then throw((LANDPREFIX + " is not yours"))
1707974 else {
1708975 let d = split(asset.description, "_")
1709976 $Tuple4(duckId, landAssetId, d, savedTime)
1710977 }
1711978 }
1712979
1713980
1714981 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
1715982 then throw("Negative amount")
1716983 else {
1717984 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
1718985 let landSize = c._3[recLandSize]
1719986 let terrainCounts = countTerrains(c._3[recTerrains])
1720987 let deltaTime = (finalTime() - c._4)
1721988 if ((0 > deltaTime))
1722989 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", final = ") + toString(finalTime())))
1723990 else {
1724991 let pieces = numPiecesBySize(landSize)
1725992 let dailyProductionByPiece = applyBonuses(c._2, pieces)
1726993 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
1727994 if ((amount > availRes))
1728995 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
1729996 else {
1730997 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
1731998 let newTimestamp = (finalTime() - newDeltaTime)
1732999 let landIndex = (pieces / SSIZE)
17331000 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
17341001 let whKey = keyWarehouseByLand(c._2)
17351002 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
17361003 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
17371004 let loft = split(currentWh[whIdxLOFT], "_")
17381005 let whSpaceLeft = parseIntValue(loft[volFree])
17391006 if (if ((claimMode == claimModeWh))
17401007 then (amount > whSpaceLeft)
17411008 else false)
17421009 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
17431010 else {
17441011 let bpKey = keyBackpackByDuck(c._1)
17451012 let currentPack = getBackpack(bpKey)
17461013 let currentPackRes = split(currentPack[bpIdxRes], "_")
17471014 let currentWhRes = split(currentWh[whIdxRes], "_")
1748- let $t03706237933 = if ((claimMode == claimModeWh))
1015+ let $t03715638027 = if ((claimMode == claimModeWh))
17491016 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17501017 else if ((claimMode == claimModeDuck))
17511018 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17521019 else {
17531020 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
17541021 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17551022 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17561023 }
1757- let whRes = $t03706237933._1
1758- let bpRes = $t03706237933._2
1759- let loftO = $t03706237933._3
1760- let loftF = $t03706237933._4
1024+ let whRes = $t03715638027._1
1025+ let bpRes = $t03715638027._2
1026+ let loftO = $t03715638027._3
1027+ let loftF = $t03715638027._4
17611028 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
17621029 }
17631030 }
17641031 }
17651032 }
17661033
17671034
17681035 func claimAll (addr,landAssetId,pieces,claimMode) = {
17691036 let timeKey = keyStakedTimeByAssetId(landAssetId)
17701037 let savedTime = value(getInteger(timeKey))
17711038 let availRes = (fraction((finalTime() - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
17721039 claimResInternal(addr, availRes, claimMode, landAssetId)
1773- }
1774-
1775-
1776-func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
1777- let addr = toString(caller)
1778- let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
1779- let pieces = numPiecesBySize(c._3[recLandSize])
1780- let infraKey = keyInfraLevelByAssetId(c._2)
1781- let curLevel = valueOrElse(getInteger(infraKey), 0)
1782- if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
1783- then (curLevel >= 3)
1784- else false)
1785- then throw("Currently max infrastructure level = 3")
1786- else {
1787- let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
1788- let newLevel = (curLevel + 1)
1789- if (if (KS_ALLOW_BIG_INFRA_MERGE)
1790- then (newLevel > maxInfra)
1791- else false)
1792- then throw(("Currently max infrastructure level = " + toString(maxInfra)))
1793- else {
1794- let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
1795- if (if (!(shouldUseMat))
1796- then (paymentAmount != cost)
1797- else false)
1798- then throw(("Payment attached should be " + toString(cost)))
1799- else {
1800- let bpKey = keyBackpackByDuck(c._1)
1801- let currentPack = getBackpack(bpKey)
1802- let mList = split(currentPack[bpIdxMat], "_")
1803- let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
1804- let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
1805- let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
1806- let whData = claimResult._5
1807- let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
1808- let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
1809- let newVol = getWarehouseTotalVolume(newVolData)
1810- let loft = split(whData[whIdxLOFT], "_")
1811- let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
1812- $Tuple3(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], newLoftStr], ":"))] ++ claimResult._1), newLevel, matUsed)
1813- }
1814- }
1815- }
18161040 }
18171041
18181042
18191043 func updateStatsInternal (lvlKey,xpKey,pointsKey,deltaXP) = {
18201044 let xp = valueOrElse(getInteger(xpKey), 0)
18211045 let newXP = (xp + deltaXP)
18221046 let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
18231047 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(pointsKey, (valueOrElse(getInteger(pointsKey), 0) + lvlPoints[1]))], newXP)
18241048 }
18251049
18261050
18271051 func updateDuckStatsInternal (duckAssetId,deltaXP) = {
18281052 let asset = value(assetInfo(fromBase58String(duckAssetId)))
18291053 let addr = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), (("NFT " + asset.name) + " is orphaned"))
18301054 if (if (if (KS_ALLOW_ROBO_DUCKS)
18311055 then (asset.issuer == this)
18321056 else false)
18331057 then contains(asset.name, ROBO_PREFIX)
18341058 else false)
18351059 then updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
18361060 else updateStatsInternal(keyDuckLevel(duckAssetId), keyDuckXP(duckAssetId), keyDuckFreePoints(duckAssetId), deltaXP)
18371061 }
18381062
18391063
18401064 func updateAccStatsInternal (addr,deltaXP) = updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
18411065
18421066
18431067 func activateOnboardArt (addr) = {
18441068 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18451069 let refByKey = keyAddressRefBy(addr)
18461070 let refBy = getString(refByKey)
18471071 if (!(isDefined(refBy)))
18481072 then throw("You are not eligible for ONBOARD artifact")
18491073 else {
18501074 let artKey = keyOnboardArtDuckActivatedBy(addr)
18511075 let artDuck = getString(artKey)
18521076 if (isDefined(artDuck))
18531077 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
18541078 else {
18551079 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
18561080 let duckActivator = getString(duckActivatorKey)
18571081 if (isDefined(duckActivator))
18581082 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
18591083 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
18601084 }
18611085 }
18621086 }
18631087
18641088
18651089 func activatePresaleArt (addr,landAssetIdIn) = {
18661090 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
18671091 let landAssetId = c._2
18681092 let pieces = numPiecesBySize(c._3[recLandSize])
18691093 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
18701094 if ((valueOrElse(getInteger(activationKey), 0) > 0))
18711095 then throw("Presale artifact is already activated")
18721096 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
18731097 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
18741098 else {
18751099 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
18761100 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
18771101 }
18781102 }
1879-
1880-
1881-func checkTournament (duckAssetId) = {
1882- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
1883- let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1884- let now = lastBlock.timestamp
1885- let tData = getTourData(tournamentContract, lastId)
1886- let static = tData[idxStatic]
1887- let dynamic = tData[idxDynamic]
1888- if ((curLocation[locIdxType] != "T"))
1889- then false
1890- else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
1891- then (dynamic[tDynamicStatus] == "INPROGRESS")
1892- else false)
1893- then (parseIntValue(static[tStaticEnd]) > now)
1894- else false)
1895- then throw("Your duck is taking part in the tournament")
1896- else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
1897- }
1898-
1899-
1900-func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
1901- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
1902- if (checkTournament(duckAssetId))
1903- then throw("mergeInternal_checkTournament")
1904- else {
1905- func checkMerge (acc,landAssetId) = {
1906- let asset = value(assetInfo(fromBase58String(landAssetId)))
1907- let timeKey = keyStakedTimeByAssetId(landAssetId)
1908- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1909- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1910- if ((owner != addr))
1911- then throw((LANDPREFIX + " is not yours"))
1912- else {
1913- let d = split(asset.description, "_")
1914- let continent = d[recContinent]
1915- if (if ((acc._3 != ""))
1916- then (acc._3 != continent)
1917- else false)
1918- then throw("Lands should be on the same continent to merge")
1919- else {
1920- let landSize = d[recLandSize]
1921- let sizesIn = acc._1
1922- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1923- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1924- let pieces = numPiecesBySize(landSize)
1925- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1926- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1927- let reqLevel = match landSize {
1928- case _ =>
1929- if (("S" == $match0))
1930- then 3
1931- else if (("M" == $match0))
1932- then 4
1933- else if (("L" == $match0))
1934- then 5
1935- else if (("XL" == $match0))
1936- then 6
1937- else throw("Only S, M, L, XL can merge")
1938- }
1939- if ((infraLevel != reqLevel))
1940- then throw("All lands should be maxed to merge")
1941- else {
1942- let landNum = d[recLandNum]
1943- let terrainCounts = countTerrains(d[recTerrains])
1944- let deltaTime = (lastBlock.timestamp - savedTime)
1945- if ((0 > deltaTime))
1946- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1947- else {
1948- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1949- let landIndex = (pieces / SSIZE)
1950- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1951- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1952- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1953- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1954- let lands = acc._7
1955- let idx = indexOf(lands, landAssetId)
1956- if (!(isDefined(idx)))
1957- then throw(("Your staked lands don't contain " + landAssetId))
1958- else {
1959- let customKey = keyLandAssetIdToCustomName(landAssetId)
1960- let customName = valueOrElse(getString(customKey), "")
1961- $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1962- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1963- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1964- }
1965- }
1966- }
1967- }
1968- }
1969- }
1970-
1971- let bpKey = keyBackpackByDuck(duckAssetId)
1972- let currentPack = getBackpack(bpKey)
1973- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1974- let landsKey = keyStakedLandsByOwner(addr)
1975- let landsStr = getString(landsKey)
1976- let landsIn = if (isDefined(landsStr))
1977- then split_51C(value(landsStr), "_")
1978- else nil
1979- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1980- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1981- let r = {
1982- let $l = landAssetIds
1983- let $s = size($l)
1984- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1985- func $f0_1 ($a,$i) = if (($i >= $s))
1986- then $a
1987- else checkMerge($a, $l[$i])
1988-
1989- func $f0_2 ($a,$i) = if (($i >= $s))
1990- then $a
1991- else throw("List size exceeds 5")
1992-
1993- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1994- }
1995- let continent = r._3
1996- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1997- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1998- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1999- let newLandNum = toString(freeNum)
2000- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2001- let assetId = calculateAssetId(issue)
2002- let newLandAssetId = toBase58String(assetId)
2003- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2004- let piecesKey = keyStakedPiecesByOwner(addr)
2005- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2006- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2007- then StringEntry(landsKey, makeString_11C(r._7, "_"))
2008- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2009- then 0
2010- else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
2011- }
2012- }
2013-
2014-
2015-func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
2016-
2017-
2018-func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
2019-
2020-
2021-func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
2022-
2023-
2024-func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
2025-
2026-
2027-func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
2028- case _ =>
2029- if ((4 == $match0))
2030- then s2m(addr, landAssetIds)
2031- else if ((3 == $match0))
2032- then m2l(addr, landAssetIds)
2033- else if ((5 == $match0))
2034- then l2xl(addr, landAssetIds)
2035- else if ((2 == $match0))
2036- then xl2xxl(addr, landAssetIds)
2037- else throw("Unknown merge")
2038-}
20391103
20401104
20411105 func prolog (i) = if (if ((i.originCaller != restContract))
20421106 then valueOrElse(getBoolean(keyBlocked()), false)
20431107 else false)
20441108 then throw("Contracts are under maintenance")
20451109 else [StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
20461110
20471111
20481112 func unstakeLandInternal (addr,landAssetId) = {
20491113 let whKey = keyWarehouseByLand(landAssetId)
20501114 let landInfo = split(value(assetInfo(fromBase58String(landAssetId))).description, "_")
20511115 let landSize = landInfo[recLandSize]
20521116 let pieces = numPiecesBySize(landSize)
20531117 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
20541118 let landIndex = (pieces / SSIZE)
20551119 let terrainCounts = countTerrains(landInfo[recTerrains])
20561120 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
20571121 let currentWhRes = split(currentWh[whIdxRes], "_")
20581122 let timeKey = keyStakedTimeByAssetId(landAssetId)
20591123 let savedTime = getIntegerValue(timeKey)
20601124 let deltaTime = (finalTime() - savedTime)
20611125 if ((0 > deltaTime))
20621126 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", final = ") + toString(finalTime())))
20631127 else {
20641128 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
20651129 let resAfterClaim = virtClaimAddRes(currentWhRes, terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
20661130 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
20671131 let acresFromPieces = ((pieces * MULT8) + ((((pieces * infraLevel) + artPieces) * MULT8) / 5))
20681132 let acresFromRes = (fraction(resAfterClaim._2, RESOURCEPRICEMIN, MULT8) * USDT2ACRES_MULTIPLIER)
20691133 func sumMat (acc,item) = (acc + parseIntValue(item))
20701134
20711135 let whMat = {
20721136 let $l = split(currentWh[whIdxMat], "_")
20731137 let $s = size($l)
20741138 let $acc0 = 0
20751139 func $f0_1 ($a,$i) = if (($i >= $s))
20761140 then $a
20771141 else sumMat($a, $l[$i])
20781142
20791143 func $f0_2 ($a,$i) = if (($i >= $s))
20801144 then $a
20811145 else throw("List size exceeds 6")
20821146
20831147 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
20841148 }
20851149 let acresFromMat = (fraction(whMat, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
20861150 let prods = if ((currentWh[whIdxProd] == ""))
20871151 then nil
20881152 else split_4C(currentWh[whIdxProd], "_")
20891153 func sumProd (acc,item) = {
20901154 let j = acc._2
20911155 let recipeCoeff = parseIntValue(split(productionMatrix[j], "_")[rIdxCoeff])
20921156 $Tuple2((acc._1 + ((parseIntValue(item) * recipeCoeff) * MULT6)), (j + 1))
20931157 }
20941158
20951159 let whProd = {
20961160 let $l = prods
20971161 let $s = size($l)
20981162 let $acc0 = $Tuple2(0, 0)
20991163 func $f1_1 ($a,$i) = if (($i >= $s))
21001164 then $a
21011165 else sumProd($a, $l[$i])
21021166
21031167 func $f1_2 ($a,$i) = if (($i >= $s))
21041168 then $a
21051169 else throw("List size exceeds 24")
21061170
21071171 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24)
21081172 }
21091173 let acresFromProd = (fraction(whProd._1, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
21101174 $Tuple4(acresFromPieces, acresFromRes, acresFromMat, acresFromProd)
21111175 }
21121176 }
21131177
21141178
21151179 func unstakeDuckInternal (addr,duckAssetId) = {
21161180 let eqKey = keyDuckEquipment(duckAssetId)
21171181 let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
21181182 let bpKey = keyBackpackByDuck(duckAssetId)
21191183 let currentPack = getBackpack(bpKey)
21201184 let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
21211185 let newProdStr = bytesToProdStr(tempProdB)
21221186 func sumResMat (acc,item) = (acc + parseIntValue(item))
21231187
21241188 let bpRes = {
21251189 let $l = split(currentPack[bpIdxRes], "_")
21261190 let $s = size($l)
21271191 let $acc0 = 0
21281192 func $f0_1 ($a,$i) = if (($i >= $s))
21291193 then $a
21301194 else sumResMat($a, $l[$i])
21311195
21321196 func $f0_2 ($a,$i) = if (($i >= $s))
21331197 then $a
21341198 else throw("List size exceeds 6")
21351199
21361200 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
21371201 }
21381202 let acresFromRes = (fraction(bpRes, RESOURCEPRICEMIN, MULT8) * USDT2ACRES_MULTIPLIER)
21391203 let bpMat = {
21401204 let $l = split(currentPack[bpIdxMat], "_")
21411205 let $s = size($l)
21421206 let $acc0 = 0
21431207 func $f1_1 ($a,$i) = if (($i >= $s))
21441208 then $a
21451209 else sumResMat($a, $l[$i])
21461210
21471211 func $f1_2 ($a,$i) = if (($i >= $s))
21481212 then $a
21491213 else throw("List size exceeds 6")
21501214
21511215 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
21521216 }
21531217 let acresFromMat = (fraction(bpMat, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
21541218 let prods = if ((newProdStr == ""))
21551219 then nil
21561220 else split_4C(newProdStr, "_")
21571221 func sumProd (acc,item) = {
21581222 let j = acc._2
21591223 let recipeCoeff = parseIntValue(split(productionMatrix[j], "_")[rIdxCoeff])
21601224 $Tuple2((acc._1 + ((parseIntValue(item) * recipeCoeff) * MULT6)), (j + 1))
21611225 }
21621226
21631227 let bpProd = {
21641228 let $l = prods
21651229 let $s = size($l)
21661230 let $acc0 = $Tuple2(0, 0)
21671231 func $f2_1 ($a,$i) = if (($i >= $s))
21681232 then $a
21691233 else sumProd($a, $l[$i])
21701234
21711235 func $f2_2 ($a,$i) = if (($i >= $s))
21721236 then $a
21731237 else throw("List size exceeds 24")
21741238
21751239 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24)
21761240 }
21771241 let acresFromProd = (fraction(bpProd._1, (2 * RESOURCEPRICEMIN), MULT8) * USDT2ACRES_MULTIPLIER)
21781242 $Tuple3(acresFromRes, acresFromMat, acresFromProd)
21791243 }
21801244
21811245
21821246 @Callable(i)
21831247 func constructorV1 (restAddr) = if ((i.caller != this))
21841248 then throw("Permission denied")
21851249 else [StringEntry(keyRestAddress(), restAddr)]
21861250
21871251
21881252
21891253 @Callable(i)
21901254 func saveInteger (key,amount) = if ((i.caller != this))
21911255 then throw("saveInteger is not public method")
21921256 else [IntegerEntry(key, amount)]
21931257
21941258
21951259
21961260 @Callable(i)
21971261 func setBlocked (isBlocked) = if ((i.caller != this))
21981262 then throw("permission denied")
21991263 else [BooleanEntry(keyBlocked(), isBlocked)]
22001264
22011265
22021266
22031267 @Callable(i)
22041268 func stakeLand () = {
22051269 let prologActions = prolog(i)
22061270 if ((size(i.payments) != 1))
22071271 then throw("Exactly one payment required")
22081272 else {
22091273 let pmt = value(i.payments[0])
22101274 let assetId = value(pmt.assetId)
22111275 let address = toString(i.caller)
22121276 if ((pmt.amount != 1))
22131277 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
22141278 else {
22151279 let asset = value(assetInfo(assetId))
22161280 if ((asset.issuer != this))
22171281 then throw("Unknown issuer of token")
22181282 else if (!(contains(asset.name, LANDPREFIX)))
22191283 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
22201284 else {
22211285 let landNumSize = drop(asset.name, 4)
22221286 let landNum = if (contains(landNumSize, "XXL"))
22231287 then dropRight(landNumSize, 3)
22241288 else if (contains(landNumSize, "XL"))
22251289 then dropRight(landNumSize, 2)
22261290 else dropRight(landNumSize, 1)
22271291 if (!(isDefined(parseInt(landNum))))
22281292 then throw(("Cannot parse land number from " + asset.name))
22291293 else {
22301294 let landAssetId = toBase58String(assetId)
22311295 let timeKey = keyStakedTimeByAssetId(landAssetId)
22321296 if (isDefined(getInteger(timeKey)))
22331297 then throw((("NFT " + asset.name) + " is already staked"))
22341298 else {
22351299 let d = split(asset.description, "_")
22361300 let terrainCounts = countTerrains(d[recTerrains])
22371301 let pieces = numPiecesBySize(d[recLandSize])
22381302 let landIndex = (pieces / SSIZE)
22391303 let props = updateProportions(terrainCounts, landIndex, 1)
22401304 let resByContKey = keyResTypesByContinent(d[recContinent])
22411305 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
22421306 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
22431307 let landsKey = keyStakedLandsByOwner(address)
22441308 let landsStr = getString(landsKey)
22451309 let lands = if (isDefined(landsStr))
22461310 then split_51C(value(landsStr), "_")
22471311 else nil
22481312 if (containsElement(lands, landAssetId))
22491313 then throw(("Your staked lands already contain " + landAssetId))
22501314 else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
22511315 then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
22521316 else {
22531317 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
22541318 let piecesKey = keyStakedPiecesByOwner(address)
22551319 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
22561320 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
22571321 $Tuple2(([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps)] ++ prologActions), wlgResult)
22581322 }
22591323 }
22601324 }
22611325 }
22621326 }
22631327 }
22641328 }
22651329
22661330
22671331
22681332 @Callable(i)
22691333 func unstakeLand (landAssetIdIn) = {
22701334 let prologActions = prolog(i)
22711335 if ((size(i.payments) != 0))
22721336 then throw("No payments required")
22731337 else {
22741338 let addr = toString(i.caller)
22751339 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
22761340 let landAssetId = c._2
22771341 let d = c._3
22781342 let landsKey = keyStakedLandsByOwner(addr)
22791343 let terrainCounts = countTerrains(d[recTerrains])
22801344 let pieces = numPiecesBySize(d[recLandSize])
22811345 let landIndex = (pieces / SSIZE)
22821346 let props = updateProportions(terrainCounts, landIndex, -1)
22831347 let resByContKey = keyResTypesByContinent(d[recContinent])
22841348 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
22851349 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
22861350 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
22871351 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
22881352 let idx = indexOf(lands, landAssetId)
22891353 if (!(isDefined(idx)))
22901354 then throw(("Your staked lands don't contain " + landAssetId))
22911355 else {
22921356 let now = lastBlock.timestamp
22931357 let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
22941358 if ((govReleaseTime >= now))
22951359 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
22961360 else {
22971361 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastArbTimeByUser(addr)), 0) + arbitrageDelay)
22981362 if ((arbReleaseTime > now))
22991363 then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
23001364 else {
23011365 let piecesKey = keyStakedPiecesByOwner(addr)
23021366 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
23031367 let newPieces = if ((pieces > stakedPieces))
23041368 then 0
23051369 else (stakedPieces - pieces)
23061370 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
23071371 $Tuple2(([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
23081372 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
23091373 else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
23101374 }
23111375 }
23121376 }
23131377 }
23141378 }
23151379
23161380
23171381
23181382 @Callable(i)
23191383 func unstakeLandCallback (landAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
23201384 then throw("Permission denied")
23211385 else {
23221386 let unstakeResult = unstakeLandInternal(addr, landAssetId)
23231387 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
23241388 $Tuple2([Burn(fromBase58String(landAssetId), 1), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))], $Tuple5(unstakeResult._1, unstakeResult._2, unstakeResult._3, unstakeResult._4, wlgResult))
23251389 }
23261390
23271391
23281392
23291393 @Callable(i)
23301394 func unstakeLandREADONLY (landAssetId,addr) = {
23311395 let unstakeResult = unstakeLandInternal(addr, landAssetId)
23321396 $Tuple2(nil, unstakeResult)
23331397 }
23341398
23351399
23361400
23371401 @Callable(i)
23381402 func unstakeLandsFinalizeCallback (addr) = if ((toString(i.caller) != acres2AddressStr))
23391403 then throw("Permission denied")
23401404 else $Tuple2([DeleteEntry(keyStakedLandsByOwner(addr)), DeleteEntry(keyStakedPiecesByOwner(addr))], 0)
23411405
23421406
23431407
23441408 @Callable(i)
23451409 func convertUnstakedLands () = if ((size(i.payments) != 1))
23461410 then throw("Exactly one payment required")
23471411 else {
23481412 let pmt = value(i.payments[0])
23491413 let assetId = value(pmt.assetId)
23501414 let address = toString(i.caller)
23511415 if ((pmt.amount != 1))
23521416 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
23531417 else {
23541418 let asset = value(assetInfo(assetId))
23551419 if ((asset.issuer != this))
23561420 then throw("Unknown issuer of token")
23571421 else if (!(contains(asset.name, LANDPREFIX)))
23581422 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
23591423 else {
23601424 let landAssetId = toBase58String(assetId)
23611425 let d = split(asset.description, "_")
23621426 let pieces = numPiecesBySize(d[recLandSize])
23631427 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
23641428 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
23651429 let acresAmount = ((pieces * MULT8) + ((((pieces * infraLevel) + artPieces) * MULT8) / 5))
23661430 let req = invoke(acresContract, "requestAcresCallback", [acresAmount], nil)
23671431 if ((req == req))
23681432 then {
23691433 let callb = invoke(addressFromStringValue(acres2AddressStr), "stakeAcresCallback", [address], [AttachedPayment(acresAssetId, acresAmount)])
23701434 if ((callb == callb))
23711435 then $Tuple2([Burn(fromBase58String(landAssetId), 1)], 0)
23721436 else throw("Strict value is not equal to itself.")
23731437 }
23741438 else throw("Strict value is not equal to itself.")
23751439 }
23761440 }
23771441 }
23781442
23791443
23801444
23811445 @Callable(i)
2382-func stakeDuck () = {
2383- let prologActions = prolog(i)
2384- if ((size(i.payments) != 1))
2385- then throw("Exactly one payment required")
2386- else {
2387- let pmt = value(i.payments[0])
2388- let assetId = value(pmt.assetId)
2389- let address = toString(i.caller)
2390- if ((pmt.amount != 1))
2391- then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
2392- else {
2393- let asset = value(assetInfo(assetId))
2394- let isRobo = if (if (KS_ALLOW_ROBO_DUCKS)
2395- then (asset.issuer == this)
2396- else false)
2397- then contains(asset.name, ROBO_PREFIX)
2398- else false
2399- if (if (if ((asset.issuer != incubatorAddr))
2400- then (asset.issuer != breederAddr)
2401- else false)
2402- then !(isRobo)
2403- else false)
2404- then throw((((("Unknown issuer of " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " token"))
2405- else if (if (!(contains(asset.name, DUCKPREFIX)))
2406- then !(isRobo)
2407- else false)
2408- then throw((((("Only NFT " + DUCKPREFIX) + " or ") + ROBO_PREFIX) + " tokens are accepted"))
2409- else {
2410- let assetIdStr = toBase58String(assetId)
2411- let timeKey = keyStakedTimeByAssetId(assetIdStr)
2412- if (isDefined(getInteger(timeKey)))
2413- then throw((("NFT " + asset.name) + " is already staked"))
2414- else if (isDefined(getString(keyStakedDuckByOwner(address))))
2415- then throw(("You already staked one duck: " + asset.name))
2416- else {
2417- let locKey = keyDuckLocation(assetIdStr)
2418- let location = getString(locKey)
2419- let bpKey = keyBackpackByDuck(assetIdStr)
2420- let backpack = getString(bpKey)
2421- let keyHealth = keyDuckHealth(assetIdStr)
2422- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2423- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2424- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2425- then nil
2426- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2427- then nil
2428- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
2429- }
2430- }
2431- }
2432- }
2433- }
2434-
2435-
2436-
2437-@Callable(i)
2438-func unstakeDuck (assetIdStr) = {
2439- let prologActions = prolog(i)
2440- if ((size(i.payments) != 0))
2441- then throw("No payments required")
2442- else {
2443- let assetId = fromBase58String(assetIdStr)
2444- let address = toString(i.caller)
2445- let asset = value(assetInfo(assetId))
2446- let timeKey = keyStakedTimeByAssetId(assetIdStr)
2447- if (!(isDefined(getInteger(timeKey))))
2448- then throw((("NFT " + asset.name) + " is not staked"))
2449- else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
2450- then throw((("The duck " + asset.name) + " is not staked"))
2451- else {
2452- let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
2453- if ((owner != address))
2454- then throw("Staked NFT is not yours")
2455- else if (checkTournament(assetIdStr))
2456- then throw("unstakeDuck_checkTournament")
2457- else {
2458- let keyHealth = keyDuckHealth(assetIdStr)
2459- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2460- let health = valueOrElse(getInteger(keyHealth), maxHP)
2461- if ((maxHP > health))
2462- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2463- else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
2464- }
2465- }
2466- }
2467- }
2468-
2469-
2470-
2471-@Callable(i)
24721446 func unstakeDuckCallback (duckAssetId,addr) = if ((toString(i.caller) != acres2AddressStr))
24731447 then throw("Permission denied")
24741448 else {
24751449 let unstakeResult = unstakeDuckInternal(addr, duckAssetId)
24761450 $Tuple2([ScriptTransfer(addressFromStringValue(addr), 1, fromBase58String(duckAssetId)), DeleteEntry(keyStakedTimeByAssetId(duckAssetId)), DeleteEntry(keyDuckIdToOwner(duckAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, duckAssetId, addr)), DeleteEntry(keyStakedDuckByOwner(addr))], unstakeResult)
24771451 }
24781452
24791453
24801454
24811455 @Callable(i)
24821456 func unstakeDuckREADONLY (duckAssetId,addr) = {
24831457 let unstakeResult = unstakeDuckInternal(addr, duckAssetId)
24841458 $Tuple2(nil, unstakeResult)
24851459 }
24861460
24871461
24881462
24891463 @Callable(i)
24901464 func claimRes (amount,landAssetIdStr) = {
24911465 let prologActions = prolog(i)
24921466 if ((size(i.payments) != 0))
24931467 then throw("No payments required")
24941468 else {
24951469 let addr = toString(i.originCaller)
24961470 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
24971471 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
24981472 $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._3[bpIdxRes])
24991473 }
25001474 }
25011475
25021476
25031477
25041478 @Callable(i)
25051479 func claimResToWH (amount,landAssetIdStr) = {
25061480 let prologActions = prolog(i)
25071481 if ((size(i.payments) != 0))
25081482 then throw("No payments required")
25091483 else {
25101484 let addr = toString(i.originCaller)
25111485 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
25121486 $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._5[whIdxRes])
25131487 }
25141488 }
25151489
25161490
25171491
25181492 @Callable(i)
2519-func flight (message,sig) = {
2520- let prologActions = prolog(i)
2521- if ((size(i.payments) != 0))
2522- then throw("No payments required")
2523- else {
2524- let userAddr = toString(i.caller)
2525- let f = flightCommon(userAddr, message, sig)
2526- let newHP = f._1
2527- let duckAssetId = f._2
2528- let locKey = keyDuckLocation(duckAssetId)
2529- let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
2530- let newLocation = f._4
2531- if ((newLocation == curLocation))
2532- then throw("You can't fly to the same location")
2533- else {
2534- let newLoc = split(newLocation, "_")
2535- let isTour = (newLoc[locIdxType] == "T")
2536- let isDeliv = (newLoc[locIdxType] == "D")
2537- let eqKey = keyDuckEquipment(duckAssetId)
2538- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2539- let $t07376973875 = subtractEquipment(currentEq, f._5)
2540- let newEq = $t07376973875._1
2541- let shouldZeroBuffs = $t07376973875._2
2542- let ignored = $t07376973875._3
2543- let $t07387875710 = if (!(onMission(tournamentContract, curLocation)))
2544- then if (isTour)
2545- then cheatAttempt(curLocation, newLocation, 5)
2546- else if (!(isDeliv))
2547- then if ((newHP > 0))
2548- then $Tuple2(newLocation, newHP)
2549- else $Tuple2(curLocation, 0)
2550- else if ((newHP > 0))
2551- then {
2552- let s = invoke(this, "processDelivery", [duckAssetId], nil)
2553- if ((s == s))
2554- then $Tuple2(curLocation, newHP)
2555- else throw("Strict value is not equal to itself.")
2556- }
2557- else $Tuple2(curLocation, 0)
2558- else if (isInTournament(tournamentContract, curLocation))
2559- then if (!(isInTournament(tournamentContract, newLocation)))
2560- then throw("Your duck is taking part in the tournament")
2561- else {
2562- let score = parseIntValue(newLoc[locIdxId])
2563- let curLoc = split(curLocation, "_")
2564- let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
2565- if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
2566- then cheatAttempt(curLocation, newLocation, 7)
2567- else if ((newHP > 0))
2568- then {
2569- let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
2570- let updLocal = if ((score > localBest))
2571- then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
2572- else unit
2573- if ((updLocal == updLocal))
2574- then $Tuple2(newLocation, newHP)
2575- else throw("Strict value is not equal to itself.")
2576- }
2577- else $Tuple2(curLocation, 0)
2578- }
2579- else throw(("Unknown curLocation:" + curLocation))
2580- let locToSave = $t07387875710._1
2581- let hpToSave = $t07387875710._2
2582- $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
2583- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2584- else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
2585- then xpSuccessFlight
2586- else xpFailFlight)._1), f._3)
2587- }
2588- }
2589- }
2590-
2591-
2592-
2593-@Callable(i)
2594-func heal (quantityL1,quantityL2,quantityL3) = {
2595- let prologActions = prolog(i)
2596- if (if (if ((0 > quantityL1))
2597- then true
2598- else (0 > quantityL2))
2599- then true
2600- else (0 > quantityL3))
2601- then throw("Quantity cannot be negative")
2602- else {
2603- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2604- if (checkTournament(duckAssetId))
2605- then throw("heal_checkTournament")
2606- else {
2607- let qts = [quantityL1, quantityL2, quantityL3]
2608- let keyHealth = keyDuckHealth(duckAssetId)
2609- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2610- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2611- if ((oldHealth >= maxHP))
2612- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2613- else {
2614- let bpKey = keyBackpackByDuck(duckAssetId)
2615- let currentPack = getBackpack(bpKey)
2616- let prodList = if ((currentPack[bpIdxProd] == ""))
2617- then nil
2618- else split_4C(currentPack[bpIdxProd], "_")
2619- func iterateProd (acc,recipe) = {
2620- let n = acc._2
2621- let x = if ((size(prodList) > n))
2622- then parseIntValue(prodList[n])
2623- else 0
2624- if ((3 > n))
2625- then {
2626- let q = qts[n]
2627- if ((q > x))
2628- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2629- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2630- }
2631- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2632- }
2633-
2634- let result = {
2635- let $l = productionMatrix
2636- let $s = size($l)
2637- let $acc0 = $Tuple3(nil, 0, 0)
2638- func $f0_1 ($a,$i) = if (($i >= $s))
2639- then $a
2640- else iterateProd($a, $l[$i])
2641-
2642- func $f0_2 ($a,$i) = if (($i >= $s))
2643- then $a
2644- else throw("List size exceeds 50")
2645-
2646- $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)
2647- }
2648- let newHealth = min([maxHP, (oldHealth + result._3)])
2649- $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2650- }
2651- }
2652- }
2653- }
2654-
2655-
2656-
2657-@Callable(i)
2658-func healES () = {
2659- let prologActions = prolog(i)
2660- if ((size(i.payments) != 1))
2661- then throw("Exactly one payment required")
2662- else {
2663- let pmt = value(i.payments[0])
2664- if ((pmt.assetId != usdtAssetId))
2665- then throw("Allowed USDT payment only!")
2666- else {
2667- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2668- if (checkTournament(duckAssetId))
2669- then throw("healES_checkTournament")
2670- else {
2671- let keyHealth = keyDuckHealth(duckAssetId)
2672- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2673- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2674- if ((oldHealth > 0))
2675- then throw("HP should be 0 to call Emergency Service")
2676- else {
2677- let bpKey = keyBackpackByDuck(duckAssetId)
2678- let currentPack = getBackpack(bpKey)
2679- let prodList = if ((currentPack[bpIdxProd] == ""))
2680- then nil
2681- else split_4C(currentPack[bpIdxProd], "_")
2682- let medKitAmount1 = if ((size(prodList) > 0))
2683- then parseIntValue(prodList[0])
2684- else 0
2685- let medKitAmount2 = if ((size(prodList) > 1))
2686- then parseIntValue(prodList[1])
2687- else 0
2688- let medKitAmount3 = if ((size(prodList) > 2))
2689- then parseIntValue(prodList[2])
2690- else 0
2691- if (if (if ((medKitAmount1 > 0))
2692- then true
2693- else (medKitAmount2 > 0))
2694- then true
2695- else (medKitAmount3 > 0))
2696- then throw("You have to use own Medical Kit")
2697- else {
2698- let existStr = getString(economyContract, keyEsWarehouse())
2699- let existAmounts = if (isDefined(existStr))
2700- then split_4C(value(existStr), "_")
2701- else nil
2702- let existAmount = if ((size(existAmounts) > 0))
2703- then parseIntValue(existAmounts[0])
2704- else 0
2705- if ((0 >= existAmount))
2706- then throw("There are no Medical Kits L1 at Emergency Service storage")
2707- else {
2708- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2709- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2710- let recipe = split(productionMatrix[0], "_")
2711- let totalMat = getRecipeMaterials(recipe)
2712- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2713- if ((pmt.amount != sellPrice))
2714- then throw(("Payment attached should be " + toString(sellPrice)))
2715- else {
2716- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2717- $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2718- }
2719- }
2720- }
2721- }
2722- }
2723- }
2724- }
2725- }
2726-
2727-
2728-
2729-@Callable(i)
27301493 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
27311494 then throw("permission denied")
27321495 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
27331496
27341497
27351498
27361499 @Callable(i)
27371500 func commitForRandom () = {
27381501 let prologActions = prolog(i)
27391502 let finishBlock = (height + randomDelay)
27401503 let addr = toString(i.caller)
27411504 $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
27421505 }
27431506
27441507
27451508
27461509 @Callable(i)
27471510 func revealRandom (maxValue) = {
27481511 let prologActions = prolog(i)
27491512 let addr = toString(i.caller)
27501513 let finishKey = keyCommit(addr)
27511514 let finishBlock = valueOrErrorMessage(getInteger(finishKey), "You have to commitForRandom() first!")
27521515 if ((finishBlock > height))
27531516 then throw(("Random number is not ready yet, wait until height = " + toString(finishBlock)))
27541517 else {
27551518 let entropy = value(value(blockInfoByHeight(finishBlock)).vrf)
27561519 let salt = toBytes(valueOrElse(getString(keyLastTxIdByUser(addr)), ""))
27571520 let rand = getRandomNumber(maxValue, salt, entropy)
27581521 $Tuple2(([DeleteEntry(finishKey)] ++ prologActions), rand)
27591522 }
27601523 }
27611524
27621525
27631526
27641527 @Callable(i)
2765-func buySLand () = {
2766- let prologActions = prolog(i)
2767- if ((size(i.payments) != 1))
2768- then throw("Exactly one payment required")
2769- else {
2770- let pmt = value(i.payments[0])
2771- if ((pmt.assetId != usdtAssetId))
2772- then throw("Allowed USDT payment only!")
2773- else if ((pmt.amount != EXPUSDT))
2774- then throw(("Payment attached should be " + toString(EXPUSDT)))
2775- else {
2776- let result = expeditionInternal(i.caller, i.transactionId)
2777- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2778- $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2779- }
2780- }
2781- }
2782-
2783-
2784-
2785-@Callable(i)
2786-func expedition (message,sig) = {
2787- let prologActions = prolog(i)
2788- if ((size(i.payments) != 0))
2789- then throw("No payments required")
2790- else {
2791- let userAddr = toString(i.caller)
2792- let f = flightCommon(userAddr, message, sig)
2793- let duckAssetId = f._2
2794- let keyHealth = keyDuckHealth(duckAssetId)
2795- let bpKey = keyBackpackByDuck(duckAssetId)
2796- let currentPack = getBackpack(bpKey)
2797- let mList = split(currentPack[bpIdxMat], "_")
2798- let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
2799- let eqKey = keyDuckEquipment(duckAssetId)
2800- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2801- let $t08363083736 = subtractEquipment(currentEq, f._5)
2802- let newEq = $t08363083736._1
2803- let shouldZeroBuffs = $t08363083736._2
2804- let ignored = $t08363083736._3
2805- let e = expeditionInternal(i.caller, i.transactionId)
2806- let id = e._2._1
2807- let result = if ((0 >= f._1))
2808- then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
2809- else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
2810- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
2811- else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
2812- if (checkTournament(duckAssetId))
2813- then throw("expedition_checkTournament")
2814- else {
2815- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2816- $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
2817- }
2818- }
2819- }
2820-
2821-
2822-
2823-@Callable(i)
2824-func buySLandForAcres () = {
2825- let prologActions = prolog(i)
2826- if ((size(i.payments) != 1))
2827- then throw("exactly 1 payment must be attached")
2828- else {
2829- let pmt = i.payments[0]
2830- let amt = pmt.amount
2831- if (if (!(isDefined(pmt.assetId)))
2832- then true
2833- else (value(pmt.assetId) != acresAssetId))
2834- then throw("ACRES payments only!")
2835- else if ((amt != S_COST_ACRES))
2836- then throw(("Payment attached should be " + toString(S_COST_ACRES)))
2837- else {
2838- let result = expeditionInternal(i.caller, i.transactionId)
2839- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
2840- $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
2841- }
2842- }
2843- }
2844-
2845-
2846-
2847-@Callable(i)
2848-func upgradeInfra (landAssetId) = {
2849- let prologActions = prolog(i)
2850- if ((size(i.payments) != 0))
2851- then throw("No payments required")
2852- else {
2853- let result = upInfraCommon(true, i.caller, 0, landAssetId)
2854- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
2855- $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
2856- }
2857- }
2858-
2859-
2860-
2861-@Callable(i)
28621528 func activateArtifact (artName,landAssetIdOpt) = {
28631529 let prologActions = prolog(i)
28641530 if ((size(i.payments) != 0))
28651531 then throw("No payments required")
28661532 else {
28671533 let addr = toString(i.caller)
28681534 let result = match artName {
28691535 case _ =>
28701536 if (("PRESALE" == $match0))
28711537 then activatePresaleArt(addr, landAssetIdOpt)
28721538 else if (("ONBOARD" == $match0))
28731539 then activateOnboardArt(addr)
28741540 else throw("Unknown artifact")
28751541 }
28761542 (result ++ prologActions)
2877- }
2878- }
2879-
2880-
2881-
2882-@Callable(i)
2883-func mergeLands (landAssetIds) = {
2884- let prologActions = prolog(i)
2885- if ((size(i.payments) != 0))
2886- then throw("No payments required")
2887- else {
2888- let result = mergeCommon(toString(i.caller), landAssetIds)
2889- $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
2890- }
2891- }
2892-
2893-
2894-
2895-@Callable(i)
2896-func cargoExchange (cargoListStr,landAssetId) = {
2897- let prologActions = prolog(i)
2898- if ((size(i.payments) != 0))
2899- then throw("No payments required")
2900- else {
2901- let cargoParts = split_4C(cargoListStr, ":")
2902- let addr = toString(i.originCaller)
2903- let asset = value(assetInfo(fromBase58String(landAssetId)))
2904- let timeKey = keyStakedTimeByAssetId(landAssetId)
2905- if (!(isDefined(getInteger(timeKey))))
2906- then throw((asset.name + " is not staked"))
2907- else {
2908- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
2909- if ((owner != addr))
2910- then throw((LANDPREFIX + " is not yours"))
2911- else {
2912- let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
2913- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
2914- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
2915- let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
2916- let loc = split(value(curLocation), "_")
2917- if ((loc[locIdxType] != "L"))
2918- then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
2919- else if ((loc[locIdxId] != landAssetId))
2920- then throw(("Duck should be on the land " + landAssetId))
2921- else {
2922- let whKey = keyWarehouseByLand(landAssetId)
2923- let currentWh = getWarehouse(whKey, landIndex, infraLevel)
2924- let bpKey = keyBackpackByDuck(duckAssetId)
2925- let currentPack = getBackpack(bpKey)
2926- let result = moveStuff(cargoParts, currentWh, currentPack)
2927- let loft = split(currentWh[whIdxLOFT], "_")
2928- let loftO = (parseIntValue(loft[volOccupied]) + result._7)
2929- let loftF = (parseIntValue(loft[volFree]) - result._7)
2930- ([StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString_2C([currentWh[whIdxLevels], result._1, result._2, result._3, makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")], ":"))] ++ prologActions)
2931- }
2932- }
2933- }
29341543 }
29351544 }
29361545
29371546
29381547
29391548 @Callable(i)
29401549 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
29411550 then throw("Access denied")
29421551 else {
29431552 let whKey = keyWarehouseByLand(landAssetId)
29441553 let wh = split_4C(whStr, ":")
29451554 if ((size(wh) != 5))
29461555 then throw("warehouse string should contain 4 ':' separators")
29471556 else {
29481557 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
29491558 let loftO = getWarehouseOccupiedVol(wh)
29501559 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
29511560 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
29521561 if ((0 > loftF))
29531562 then throw("Operation leads to negative free warehouse space")
29541563 else {
29551564 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
29561565 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
29571566 }
29581567 }
29591568 }
29601569
29611570
29621571
29631572 @Callable(i)
29641573 func setCustomName (assetId,customName,type) = {
29651574 let prologActions = prolog(i)
29661575 if ((size(i.payments) != 1))
29671576 then throw("Exactly one payment required")
29681577 else {
29691578 let pmt = value(i.payments[0])
29701579 if ((pmt.assetId != usdtAssetId))
29711580 then throw("Allowed USDT payment only!")
29721581 else if ((pmt.amount != RENAMINGCOST))
29731582 then throw(("Payment should be " + toString(RENAMINGCOST)))
29741583 else if (contains(customName, "__"))
29751584 then throw(("Name should not contain '__': " + customName))
29761585 else if ((size(customName) > MAXNAMELEN))
29771586 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
29781587 else {
29791588 let addr = toString(i.originCaller)
29801589 let actions = match type {
29811590 case _ =>
29821591 if (("ACCOUNT" == $match0))
29831592 then {
29841593 let reverseKey = keyCustomNameToAddress(customName)
29851594 let nameOwner = getString(reverseKey)
29861595 if (isDefined(nameOwner))
29871596 then throw(("Name already registered: " + customName))
29881597 else {
29891598 let addrToNameKey = keyAddressToCustomName(addr)
29901599 let oldName = getString(addrToNameKey)
29911600 let freeOld = if (isDefined(oldName))
29921601 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
29931602 else nil
29941603 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
29951604 }
29961605 }
29971606 else if (("LAND" == $match0))
29981607 then {
29991608 let asset = value(assetInfo(fromBase58String(assetId)))
30001609 let timeKey = keyStakedTimeByAssetId(assetId)
30011610 if (!(isDefined(getInteger(timeKey))))
30021611 then throw((asset.name + " is not staked"))
30031612 else {
30041613 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
30051614 if ((owner != addr))
30061615 then throw((LANDPREFIX + " is not yours"))
30071616 else {
30081617 let reverseKey = keyLandCustomNameToAssetId(customName)
30091618 let nameOwner = getString(reverseKey)
30101619 if (isDefined(nameOwner))
30111620 then throw(("Name already registered: " + customName))
30121621 else {
30131622 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
30141623 let oldName = getString(assetToNameKey)
30151624 let freeOld = if (isDefined(oldName))
30161625 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
30171626 else nil
30181627 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
30191628 }
30201629 }
30211630 }
30221631 }
30231632 else if (("DUCK" == $match0))
30241633 then {
30251634 let asset = value(assetInfo(fromBase58String(assetId)))
30261635 let timeKey = keyStakedTimeByAssetId(assetId)
30271636 if (if (!(isDefined(getInteger(timeKey))))
30281637 then true
30291638 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
30301639 then throw((asset.name + " is not staked"))
30311640 else {
30321641 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
30331642 if ((owner != addr))
30341643 then throw((DUCKPREFIX + " is not yours"))
30351644 else {
30361645 let reverseKey = keyDuckCustomNameToAssetId(customName)
30371646 let nameOwner = getString(reverseKey)
30381647 if (isDefined(nameOwner))
30391648 then throw(("Name already registered: " + customName))
30401649 else {
30411650 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
30421651 let oldName = getString(assetToNameKey)
30431652 let freeOld = if (isDefined(oldName))
30441653 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
30451654 else nil
30461655 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
30471656 }
30481657 }
30491658 }
30501659 }
30511660 else throw("Unknown entity type")
30521661 }
30531662 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
30541663 }
30551664 }
30561665 }
30571666
30581667
30591668
30601669 @Callable(i)
30611670 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
30621671 then throw("Permission denied")
30631672 else {
30641673 let prologActions = prolog(i)
30651674 if ((size(i.payments) != 0))
30661675 then throw("No payments required")
30671676 else if (!(isDefined(addressFromString(oldPlayer))))
30681677 then throw(("Invalid address: " + oldPlayer))
30691678 else {
30701679 let newbieAddr = addressFromString(newPlayer)
30711680 if (!(isDefined(newbieAddr)))
30721681 then throw(("Invalid address: " + newPlayer))
30731682 else {
30741683 let oldLastTx = getString(keyLastTxIdByUser(oldPlayer))
30751684 if (!(isDefined(oldLastTx)))
30761685 then throw("oldPlayer didn't do any tx in game")
30771686 else if ((0 >= wavesBalance(value(newbieAddr)).available))
30781687 then throw("newPlayer has no WAVES")
30791688 else {
30801689 let oldsKey = keyOldies()
30811690 let olds = getString(oldsKey)
30821691 let oldies = if (isDefined(olds))
30831692 then split_4C(value(olds), "_")
30841693 else nil
30851694 if (containsElement(oldies, newPlayer))
30861695 then throw((newPlayer + " is not newbie (already has referrals)"))
30871696 else {
30881697 let refByKey = keyAddressRefBy(newPlayer)
30891698 let refBy = getString(refByKey)
30901699 if (if (isDefined(refBy))
30911700 then isDefined(addressFromString(value(refBy)))
30921701 else false)
30931702 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
30941703 else {
30951704 let refsKey = keyAddressReferrals(oldPlayer)
30961705 let refs = getString(refsKey)
30971706 let refsArray = if (isDefined(refs))
30981707 then split_4C(value(refs), "_")
30991708 else nil
31001709 if (containsElement(refsArray, newPlayer))
31011710 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
31021711 else {
31031712 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
31041713 let newOlds = if (containsElement(oldies, oldPlayer))
31051714 then value(olds)
31061715 else makeString_2C((oldies :+ oldPlayer), "_")
31071716 $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
31081717 }
31091718 }
31101719 }
31111720 }
31121721 }
31131722 }
31141723 }
31151724
31161725
31171726
31181727 @Callable(i)
31191728 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
31201729 let prologActions = prolog(i)
31211730 if ((size(i.payments) != 0))
31221731 then throw("No payments required")
31231732 else {
31241733 let addr = toString(i.originCaller)
31251734 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
31261735 let virtWlgPoints = asInt(virtWlgData[1])
3127- let $t09954899938 = if ((0 >= virtWlgPoints))
1736+ let $t0100228100618 = if ((0 >= virtWlgPoints))
31281737 then $Tuple2(0, nil)
31291738 else {
31301739 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
31311740 if ((deltaXP == deltaXP))
31321741 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
31331742 else throw("Strict value is not equal to itself.")
31341743 }
3135- let wlgPoints = $t09954899938._1
3136- let wlgActions = $t09954899938._2
1744+ let wlgPoints = $t0100228100618._1
1745+ let wlgActions = $t0100228100618._2
31371746 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
31381747 let freeKeyAcc = keyUserFreePoints(addr)
31391748 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
31401749 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
31411750 let freePointsDuck = valueOrElse(getInteger(freeKeyDuck), 0)
31421751 let sumFree = (freePointsAcc + freePointsDuck)
31431752 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
31441753 if ((sumToDistribute > sumFree))
31451754 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
31461755 else {
31471756 let charsKey = keyDuckChars(duckAssetId)
31481757 let chars = split(valueOrElse(getString(charsKey), "0_0_0_0_0"), "_")
31491758 let newAcc = (freePointsAcc - sumToDistribute)
31501759 $Tuple2((([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
31511760 then 0
31521761 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
31531762 then (freePointsDuck + newAcc)
31541763 else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_"))] ++ prologActions) ++ wlgActions), 0)
31551764 }
31561765 }
31571766 }
31581767
31591768
31601769
31611770 @Callable(i)
31621771 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
31631772
31641773
31651774
31661775 @Callable(i)
31671776 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
31681777 let terrainCounts = countTerrains(terrains)
31691778 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
31701779 }
31711780
31721781
31731782
31741783 @Callable(i)
31751784 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
31761785
31771786
31781787
31791788 @Callable(i)
31801789 func getWarehouseREADONLY (landAssetId) = {
31811790 let asset = value(assetInfo(fromBase58String(landAssetId)))
31821791 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
31831792 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
31841793 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
31851794 }
31861795
31871796
31881797
31891798 @Callable(i)
31901799 func saveLastTx () = if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], i.caller)))
31911800 then throw("Access denied")
31921801 else $Tuple2(prolog(i), 42)
31931802
31941803
31951804
31961805 @Callable(i)
31971806 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
31981807 then throw("Access denied")
31991808 else updateDuckStatsInternal(duckAssetId, deltaXP)
32001809
32011810
32021811
32031812 @Callable(i)
32041813 func updateAccStats (addr,deltaXP) = if (!(containsElement([wlgContract, economyContract, acresContract], i.caller)))
32051814 then throw("Access denied")
32061815 else updateAccStatsInternal(addr, deltaXP)
3207-
3208-
3209-
3210-@Callable(i)
3211-func equipDuck (equipment) = {
3212- let prologActions = prolog(i)
3213- if ((size(i.payments) != 0))
3214- then throw("No payments required")
3215- else {
3216- let addr = toString(i.originCaller)
3217- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3218- if (checkTournament(duckAssetId))
3219- then throw("equipDuck_checkTournament")
3220- else {
3221- let eqKey = keyDuckEquipment(duckAssetId)
3222- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3223- let bpKey = keyBackpackByDuck(duckAssetId)
3224- let currentPack = getBackpack(bpKey)
3225- let newEq = split(equipment, "_")
3226- if ((size(newEq) != NUMSEGMENTS))
3227- then throw("Wrong equipment string")
3228- else {
3229- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3230- let segBpAux = split(newEq[segBackpack], ";")[1]
3231- let buffEffect = if ((segBpAux == ""))
3232- then 0
3233- else {
3234- let aux0 = split(segBpAux, ",")[0]
3235- if ((aux0 == ""))
3236- then 0
3237- else {
3238- let idxCnt = split(aux0, ":")
3239- let idx = idxCnt[0]
3240- let cnt = idxCnt[1]
3241- if (if (if (if (if ((idx == "06"))
3242- then true
3243- else (idx == "07"))
3244- then true
3245- else (idx == "08"))
3246- then (cnt != "")
3247- else false)
3248- then (parseIntValue(cnt) > 0)
3249- else false)
3250- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3251- else 0
3252- }
3253- }
3254- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3255- let newProdB = dressB(newEq, tempProdB, false, stats)
3256- let newProdStr = bytesToProdStr(newProdB)
3257- $Tuple2(([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_"))] ++ prologActions), 0)
3258- }
3259- }
3260- }
3261- }
32621816
32631817
32641818
32651819 @Callable(i)
32661820 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
32671821 then throw("Access denied")
32681822 else {
32691823 let keyHealth = keyDuckHealth(duckAssetId)
32701824 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
32711825 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
32721826 let curLocKey = keyDuckLocation(duckAssetId)
32731827 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32741828 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
32751829 let tourLocation = (toString(lastId) + "_T_0")
32761830 $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
32771831 }
32781832
32791833
32801834
32811835 @Callable(i)
32821836 func breakAttempt () = {
32831837 let prologActions = prolog(i)
32841838 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
32851839 let curLocKey = keyDuckLocation(duckAssetId)
32861840 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32871841 if ((split(curLocation, "_")[locIdxType] != "T"))
32881842 then throw("Your duck is not in the tournament")
32891843 else {
32901844 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
32911845 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
32921846 $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
32931847 }
32941848 }
32951849
32961850
32971851
32981852 @Callable(i)
32991853 func breakAttemptCallback () = if ((i.caller != tournamentContract))
33001854 then throw("Access denied")
33011855 else {
33021856 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.originCaller))), "You don't have a duck staked")
33031857 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), getIntegerValue(keySavedHealth(duckAssetId))), StringEntry(keyDuckLocation(duckAssetId), getStringValue(keySavedLocation(duckAssetId)))], "breakAttemptCallback")
33041858 }
33051859
33061860
33071861
33081862 @Callable(i)
33091863 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
33101864 then throw("Access denied")
33111865 else {
33121866 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
33131867 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
33141868 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
33151869 }
33161870
33171871
33181872
33191873 @Callable(i)
33201874 func processDelivery (duckAssetId) = if ((i.caller != this))
33211875 then throw("Access denied")
33221876 else {
33231877 let addr = toString(i.originCaller)
33241878 let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
33251879 if ((MIN_USDT_FEE_DELIVERY > fundTotal))
33261880 then throw(("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)))
33271881 else {
33281882 let now = lastBlock.timestamp
33291883 let countKey = keyUserDeliveryCount(addr)
33301884 let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(addr)), 0)
33311885 let today = (now / DAYMILLIS)
33321886 let count = if ((lastDay == today))
33331887 then valueOrElse(getInteger(countKey), 0)
33341888 else 0
33351889 let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
33361890 let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
33371891 if ((count >= allowedDeliveries))
33381892 then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
33391893 else {
33401894 let globalCountKey = keyDuckDeliveryCount(duckAssetId)
33411895 let reward = invoke(economyContract, "sendDeliveryReward", [addr], nil)
33421896 $Tuple2([IntegerEntry(countKey, (count + 1)), IntegerEntry(keyUserLastDeliveryDay(addr), today), IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))], reward)
33431897 }
33441898 }
33451899 }
33461900
33471901
3348-
3349-@Callable(i)
3350-func robLand (message,sig) = {
3351- let prologActions = prolog(i)
3352- if ((size(i.payments) != 1))
3353- then throw("exactly 1 payment must be attached")
3354- else {
3355- let pmt = i.payments[0]
3356- let wlgAmt = pmt.amount
3357- if (if (!(isDefined(pmt.assetId)))
3358- then true
3359- else (value(pmt.assetId) != wlgAssetId))
3360- then throw("WLGOLD payments only!")
3361- else if ((wlgAmt != MIN_WLGOLD_ROBBERY))
3362- then throw((("Payment should be " + fixedPoint(MIN_WLGOLD_ROBBERY, 8)) + " WLGOLD"))
3363- else {
3364- let addr = toString(i.caller)
3365- if (!(sigVerify_8Kb(message, sig, pub)))
3366- then throw("signature does not match")
3367- else {
3368- let parts = split_4C(toUtf8String(message), ";")
3369- let robLog = split_4C(parts[0], "|")
3370- let hp = split(robLog[rlHealth], "_")
3371- let curHP = parseIntValue(hp[0])
3372- let newHP = parseIntValue(hp[1])
3373- let prodUsed = robLog[rlProdsUsed]
3374- let lastPart = split(parts[1], "|")
3375- let robType = lastPart[rlType]
3376- if ((robType != "B"))
3377- then throw("Only bank robbery is supported")
3378- else {
3379- let time = parseIntValue(lastPart[rlTimestamp])
3380- if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
3381- then true
3382- else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
3383- then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
3384- else {
3385- let txFromMsg = lastPart[rlLastTx]
3386- let lastTx = valueOrElse(getString(keyLastTxIdByUser(addr)), "")
3387- if ((lastTx != txFromMsg))
3388- then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3389- else {
3390- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
3391- let eqKey = keyDuckEquipment(duckAssetId)
3392- let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
3393- let $t0117116117227 = subtractEquipment(currentEq, prodUsed)
3394- let newEq = $t0117116117227._1
3395- let shouldZeroBuffs = $t0117116117227._2
3396- let isBpUsed = $t0117116117227._3
3397- let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
3398- if (isInTournament(tournamentContract, curLocation))
3399- then throw("Your duck is taking part in the tournament")
3400- else {
3401- let now = lastBlock.timestamp
3402- let countKey = keyUserRobberyCount(addr)
3403- let lastDay = valueOrElse(getInteger(keyUserLastRobberyDay(addr)), 0)
3404- let today = (now / DAYMILLIS)
3405- let count = if ((lastDay == today))
3406- then valueOrElse(getInteger(countKey), 0)
3407- else 0
3408- let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(addr)), 0)
3409- let allowedRobberies = (ALLOWED_FREE_ROBBERIES + (acres / ACRES_FOR_ROBBERY_ATTEMPT))
3410- if ((count >= allowedRobberies))
3411- then throw((("You already used " + toString(allowedRobberies)) + " robbery attempts for today"))
3412- else {
3413- let globalCountKey = keyDuckRobberyCount(duckAssetId)
3414- let loot = if ((newHP > 0))
3415- then {
3416- let fundTotal = assetBalance(this, wlgAssetId)
3417- let prize = if (isBpUsed)
3418- then (2 * MIN_WLGOLD_ROBBERY)
3419- else (5 * MIN_WLGOLD_ROBBERY)
3420- if ((prize > fundTotal))
3421- then throw(((("Robbery is not available, funds = " + fixedPoint(fundTotal, 8)) + " WLGOLD, required = ") + fixedPoint(prize, 8)))
3422- else [ScriptTransfer(i.caller, prize, wlgAssetId)]
3423- }
3424- else nil
3425- $Tuple2((((((((((prologActions ++ loot) ++ (if (shouldZeroBuffs)
3426- then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
3427- else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
3428- then xpSuccessRob
3429- else xpFailRob)._1) :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)) :+ IntegerEntry(countKey, (count + 1))) :+ IntegerEntry(keyUserLastRobberyDay(addr), today)) :+ IntegerEntry(globalCountKey, (valueOrElse(getInteger(globalCountKey), 0) + 1))) :+ StringEntry(eqKey, newEq)) :+ IntegerEntry(keyDuckHealth(duckAssetId), max([newHP, 0]))), 0)
3430- }
3431- }
3432- }
3433- }
3434- }
3435- }
3436- }
3437- }
3438- }
3439-
3440-
3441-
3442-@Callable(i)
3443-func buyRoboDuck () = if (!(KS_ALLOW_ROBO_DUCKS))
3444- then throw("Feature is turned off")
3445- else {
3446- let prologActions = prolog(i)
3447- if ((size(i.payments) != 1))
3448- then throw("Exactly one payment required")
3449- else {
3450- let pmt = value(i.payments[0])
3451- if ((pmt.assetId != usdtAssetId))
3452- then throw("Allowed USDT payment only!")
3453- else if ((pmt.amount != ROBO_DUCK_USDT))
3454- then throw((("Payment attached should be " + fixedPoint(ROBO_DUCK_USDT, 6)) + " USDT"))
3455- else {
3456- let nextNum = valueOrElse(getInteger(keyNextRoboDuck()), 0)
3457- let bytez = toBytes(nextNum)
3458- let name = ((ROBO_PREFIX + "-") + takeRight(toBase16String(bytez), 8))
3459- let color = takeRight(toBase16String(sha256_16Kb(bytez)), 6)
3460- let issue = Issue(name, ("Robo Duck NFT for WavesLands game, background color = #" + color), 1, 0, false)
3461- let assetId = calculateAssetId(issue)
3462- $Tuple2(((((prologActions :+ IntegerEntry(keyNextRoboDuck(), (nextNum + 1))) :+ issue) :+ ScriptTransfer(i.originCaller, 1, assetId)) :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)), $Tuple2(toBase58String(assetId), color))
3463- }
3464- }
3465- }
3466-
3467-

github/deemru/w8io/169f3d6 
383.54 ms