2023.02.10 14:35 [3509048] smart account 3PCENpEKe8atwELZ7oCSmcdEfcRuKTrUx99 > SELF 0.00000000 Waves

{ "type": 13, "id": "6sctcNuFGAUPXB9ex3252dvCpNVt4TEDcNqBfxoUNE5j", "fee": 3600000, "feeAssetId": null, "timestamp": 1676028969722, "version": 2, "chainId": 87, "sender": "3PCENpEKe8atwELZ7oCSmcdEfcRuKTrUx99", "senderPublicKey": "24dorn126Pv4mGCgUu61v1RLxqW4VNXbuHjmCHh7tc3K", "proofs": [ "4dEKdzdVUDjLUeCXQSuUgkiEuw5KkKB3i9S2vbFDpSQ8M9VSe2168vKnsdEAzWebnn2knpsWzwJdro2W9yxHgJhV" ], "script": "base64:BgKBLggCEgMKAQgSABIECgIBBBIDCgEBEgQKAgEEEgQKAggBEgQKAggBEgQKAggBEgUKAwEIARIAEgQKAgEBEgMKAQESBQoDAQEBEgQKAggIEgASABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50IgJmYyIDbXBrIgRwbXBrIgJwbCICcGgiAWgiCXRpbWVzdGFtcCIDcGF1Igt1c2VyQWRkcmVzcyIEdHhJZCIDZ2F1IgJhYSICcGEiBmtleUZlZSIKZmVlRGVmYXVsdCIDZmVlIgZrZXlLTHAiFWtleUtMcFJlZnJlc2hlZEhlaWdodCISa2V5S0xwUmVmcmVzaERlbGF5IhZrTHBSZWZyZXNoRGVsYXlEZWZhdWx0Ig9rTHBSZWZyZXNoRGVsYXkiEGtleUZhY3RvcnlDb25maWciDWtleU1hdGNoZXJQdWIiKWtleU1hcHBpbmdQb29sQ29udHJhY3RBZGRyZXNzVG9Qb29sQXNzZXRzIhNwb29sQ29udHJhY3RBZGRyZXNzIg1rZXlQb29sQ29uZmlnIglpQW10QXNzZXQiC2lQcmljZUFzc2V0Ih9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiE2tleUFsbFBvb2xzU2h1dGRvd24iDWtleVBvb2xXZWlnaHQiD2NvbnRyYWN0QWRkcmVzcyIWa2V5QWxsb3dlZExwU2NyaXB0SGFzaCIWa2V5RmVlQ29sbGVjdG9yQWRkcmVzcyIPdGhyb3dPcmRlckVycm9yIgpvcmRlclZhbGlkIg5vcmRlclZhbGlkSW5mbyILc2VuZGVyVmFsaWQiDG1hdGNoZXJWYWxpZCIPZ2V0U3RyaW5nT3JGYWlsIgdhZGRyZXNzIgNrZXkiDGdldEludE9yRmFpbCIIdGhyb3dFcnIiA21zZyIGZm10RXJyIg9mYWN0b3J5Q29udHJhY3QiE2ZlZUNvbGxlY3RvckFkZHJlc3MiBWluRmVlIgFAIgZvdXRGZWUiEGlzR2xvYmFsU2h1dGRvd24iE2dldE1hdGNoZXJQdWJPckZhaWwiDWdldFBvb2xDb25maWciCGFtdEFzc2V0IgpwcmljZUFzc2V0IgxwYXJzZUFzc2V0SWQiBWlucHV0Ig9hc3NldElkVG9TdHJpbmciD3BhcnNlUG9vbENvbmZpZyIKcG9vbENvbmZpZyIQcG9vbENvbmZpZ1BhcnNlZCILJHQwODQwODg1NzQiDmNmZ1Bvb2xBZGRyZXNzIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIhBnZXRGYWN0b3J5Q29uZmlnIg9zdGFraW5nQ29udHJhY3QiEHNsaXBwYWdlQ29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIiFXNsaXBwYWdlVG9sZXJhbmNlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIhJzbGlwYWdlQW10QXNzZXRBbXQiFHNsaXBhZ2VQcmljZUFzc2V0QW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiB2Fzc2V0SWQiD2NhbGNQcmljZUJpZ0ludCIIcHJBbXRYMTgiCGFtQW10WDE4IhRjYWxjUHJpY2VCaWdJbnRSb3VuZCIQcHJpdmF0ZUNhbGNQcmljZSIKYW1Bc3NldERjbSIKcHJBc3NldERjbSIFYW1BbXQiBXByQW10Ig5hbXRBc3NldEFtdFgxOCIQcHJpY2VBc3NldEFtdFgxOCIKY2FsY1ByaWNlcyIFbHBBbXQiA2NmZyILYW10QXNzZXREY20iDXByaWNlQXNzZXREY20iCHByaWNlWDE4IghscEFtdFgxOCITbHBQcmljZUluQW1Bc3NldFgxOCITbHBQcmljZUluUHJBc3NldFgxOCIPY2FsY3VsYXRlUHJpY2VzIgZwcmljZXMiFGVzdGltYXRlR2V0T3BlcmF0aW9uIgZ0eElkNTgiCnBtdEFzc2V0SWQiCHBtdExwQW10IglscEFzc2V0SWQiCWFtQXNzZXRJZCIJcHJBc3NldElkIgpwb29sU3RhdHVzIgpscEVtaXNzaW9uIglhbUJhbGFuY2UiDGFtQmFsYW5jZVgxOCIJcHJCYWxhbmNlIgxwckJhbGFuY2VYMTgiC2N1clByaWNlWDE4IghjdXJQcmljZSILcG10THBBbXRYMTgiDWxwRW1pc3Npb25YMTgiC291dEFtQW10WDE4IgtvdXRQckFtdFgxOCIIb3V0QW1BbXQiCG91dFByQW10IgVzdGF0ZSIUZXN0aW1hdGVQdXRPcGVyYXRpb24iEXNsaXBwYWdlVG9sZXJhbmNlIgxpbkFtQXNzZXRBbXQiC2luQW1Bc3NldElkIgxpblByQXNzZXRBbXQiC2luUHJBc3NldElkIgppc0V2YWx1YXRlIgZlbWl0THAiDGFtQXNzZXRJZFN0ciIMcHJBc3NldElkU3RyIgtpQW10QXNzZXRJZCINaVByaWNlQXNzZXRJZCIOaW5BbUFzc2V0SWRTdHIiDmluUHJBc3NldElkU3RyIg9pbkFtQXNzZXRBbXRYMTgiD2luUHJBc3NldEFtdFgxOCIMdXNlclByaWNlWDE4IgNyZXMiC3NsaXBwYWdlWDE4IhRzbGlwcGFnZVRvbGVyYW5jZVgxOCIKcHJWaWFBbVgxOCIKYW1WaWFQclgxOCIMZXhwZWN0ZWRBbXRzIhFleHBBbXRBc3NldEFtdFgxOCITZXhwUHJpY2VBc3NldEFtdFgxOCIJY2FsY0xwQW10Ig5jYWxjQW1Bc3NldFBtdCIOY2FsY1ByQXNzZXRQbXQiDHNsaXBwYWdlQ2FsYyIJZW1pdExwQW10IgZhbURpZmYiBnByRGlmZiILY29tbW9uU3RhdGUiB2NhbGNLTHAiDWFtb3VudEJhbGFuY2UiDHByaWNlQmFsYW5jZSIQYW1vdW50QmFsYW5jZVgxOCIPcHJpY2VCYWxhbmNlWDE4Igp1cGRhdGVkS0xwIg5jYWxjQ3VycmVudEtMcCIQYW1vdW50QXNzZXREZWx0YSIPcHJpY2VBc3NldERlbHRhIhRscEFzc2V0RW1pc3Npb25EZWx0YSISYW1vdW50QXNzZXRCYWxhbmNlIhFwcmljZUFzc2V0QmFsYW5jZSIPbHBBc3NldEVtaXNzaW9uIgpjdXJyZW50S0xwIhJyZWZyZXNoS0xwSW50ZXJuYWwiF2Ftb3VudEFzc2V0QmFsYW5jZURlbHRhIhZwcmljZUFzc2V0QmFsYW5jZURlbHRhIgdhY3Rpb25zIhJ2YWxpZGF0ZVVwZGF0ZWRLTHAiBm9sZEtMcCIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDIxNDgwMjE2OTIiA2tMcCINJHQwMjIxMzIyMjIzMiINdW51c2VkQWN0aW9ucyIGa0xwTmV3Igxpc09yZGVyVmFsaWQiBGluZm8iCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgZhbW91bnQiB2VtaXRJbnYiDWVtaXRJbnZMZWdhY3kiByRtYXRjaDAiFWxlZ2FjeUZhY3RvcnlDb250cmFjdCIHdGFrZUZlZSIJZmVlQW1vdW50Ig9jYWxjUHV0T25lVG9rZW4iEHBheW1lbnRBbW91bnRSYXciDnBheW1lbnRBc3NldElkIgZpc0V2YWwiEGFtb3VudEJhbGFuY2VSYXciD3ByaWNlQmFsYW5jZVJhdyIUcGF5bWVudEluQW1vdW50QXNzZXQiDSR0MDI1MzQ1MjU2MzgiEGFtb3VudEJhbGFuY2VPbGQiD3ByaWNlQmFsYW5jZU9sZCINJHQwMjU2NDIyNTc5MSIUYW1vdW50QXNzZXRBbW91bnRSYXciE3ByaWNlQXNzZXRBbW91bnRSYXciDSR0MDI1OTIzMjU5ODciDXBheW1lbnRBbW91bnQiEGFtb3VudEJhbGFuY2VOZXciD3ByaWNlQmFsYW5jZU5ldyILcHJpY2VOZXdYMTgiCHByaWNlTmV3Ig5wYXltZW50QmFsYW5jZSIUcGF5bWVudEJhbGFuY2VCaWdJbnQiDHN1cHBseUJpZ0ludCILY2hlY2hTdXBwbHkiDWRlcG9zaXRCaWdJbnQiC2lzc3VlQW1vdW50IgtwcmljZU9sZFgxOCIIcHJpY2VPbGQiBGxvc3MiDSR0MDI3NjY4Mjc4MzUiB2JhbGFuY2UiD2lzc3VlQW1vdW50Qm90aCIPY2FsY0dldE9uZVRva2VuIgpvdXRBc3NldElkIgZjaGVja3MiEG91dEluQW1vdW50QXNzZXQiDWJhbGFuY2VCaWdJbnQiGG91dEluQW1vdW50QXNzZXREZWNpbWFscyIMYW1CYWxhbmNlT2xkIgxwckJhbGFuY2VPbGQiCm91dEJhbGFuY2UiEG91dEJhbGFuY2VCaWdJbnQiDnJlZGVlbWVkQmlnSW50IglhbW91bnRSYXciDSR0MDI5OTEzMjk5NjkiC3RvdGFsQW1vdW50Ig0kdDAyOTk3MzMwMTk5IgtvdXRBbUFtb3VudCILb3V0UHJBbW91bnQiDGFtQmFsYW5jZU5ldyIMcHJCYWxhbmNlTmV3IhhhbW91bnRCb3RoSW5QYXltZW50QXNzZXQiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiAXMiHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0Iglpc01hbmFnZXIiAnBrIgttdXN0TWFuYWdlciICcGQiF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52Ig0kdDAzNDcyNzM1MTg5IhFyZWZyZXNoS0xwQWN0aW9ucyIRaXNVcGRhdGVkS0xwVmFsaWQiC21heFNsaXBwYWdlIg0kdDAzNTc1MTM1ODE2IgxtaW5PdXRBbW91bnQiCWF1dG9TdGFrZSIgaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWQiDWlzUHV0RGlzYWJsZWQiB3BheW1lbnQiDSR0MDM3MDA0MzcxNTYiBWJvbnVzIhNlbWl0QW1vdW50RXN0aW1hdGVkIgplbWl0QW1vdW50IghzdGFrZUludiIHc2VuZEZlZSINJHQwMzc3NDIzNzkzOSINJHQwMzc5NDIzODA1MCINJHQwMzgzNTYzODUxMyINb3V0QXNzZXRJZFN0ciINaXNHZXREaXNhYmxlZCINJHQwMzkzOTgzOTU1MSIPYW1vdW50RXN0aW1hdGVkIgdidXJuSW52Ig1hc3NldFRyYW5zZmVyIg0kdDA0MDA1MTQwMjk4IhBmZWVBbW91bnRGb3JDYWxjIg0kdDA0MDMwMTQwNDA5Ig0kdDA0MDY2NjQwODIyIg11bnN0YWtlQW1vdW50Igp1bnN0YWtlSW52Ig0kdDA0MTcyNzQxODc4Ig0kdDA0MjM3MzQyNjIwIg0kdDA0MjYyMzQyNzMxIglvdXRBbXRBbXQiFGJ1cm5MUEFzc2V0T25GYWN0b3J5Ig0kdDA0MzY3NzQzNzU5IhJub0xlc3NUaGVuQW10QXNzZXQiFG5vTGVzc1RoZW5QcmljZUFzc2V0Ig0kdDA0NDcwODQ0Nzg5Ig1jaGVja1BheW1lbnRzIg9jaGVja1Bvb2xTdGF0dXMiDSR0MDQ1OTE1NDU5OTYiFW5vTGVzc1RoZW5BbW91bnRBc3NldCIMY2hlY2tBbW91bnRzIg0kdDA0NzI5MTQ3MzcyIgthbXRBc3NldFN0ciINcHJpY2VBc3NldFN0ciIYbGFzdFJlZnJlc2hlZEJsb2NrSGVpZ2h0Ih1jaGVja0xhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCINJHQwNDg1NTk0ODYyMyIQa0xwVXBkYXRlQWN0aW9ucyIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIg1wb29sTFBCYWxhbmNlIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIgpwcmljZXNMaXN0Ig9scEFtdEFzc2V0U2hhcmUiEWxwUHJpY2VBc3NldFNoYXJlIgpwb29sV2VpZ2h0IgxjdXJQcmljZUNhbGMiDGFtQmFsYW5jZVJhdyIMcHJCYWxhbmNlUmF3Ig9hbUJhbGFuY2VSYXdYMTgiD3ByQmFsYW5jZVJhd1gxOCIQcGF5bWVudExwQXNzZXRJZCIMcGF5bWVudExwQW10IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXkiCm1hdGNoZXJQdWIiDSR0MDU3Mjg1NTczNTQiB25ld0hhc2giC2FsbG93ZWRIYXNoIgtjdXJyZW50SGFzaHIAAWEACAABYgCAwtcvAAFjCQC2AgEAgMLXLwABZAkAtgIBAICAkLu61q3wDQABZQkAtgIBAAAAAWYJALYCAQAAAAFnCQC2AgEAAQABaAkAtgIBAAIAAWkCBVdBVkVTAAFqAgJfXwABawABAAFsAAIAAW0AAwABbgAEAAFvAAEAAXAAAgABcQADAAFyAAQAAXMABQABdAAGAAF1AAcAAXYACAABdwAJAAF4AAoAAXkAAQABegACAAFBAAMAAUIAAQABQwAHAQFEAgFFAUYJALwCAwkAtgIBBQFFBQFkCQC2AgEFAUYBAUcCAUUBRgkAvAIDBQFFBQFkBQFGAQFIAgFJAUoJAKADAQkAvAIDBQFJCQC2AgEFAUoFAWQBAUsDAUkBSgFMCQCgAwEJAL0CBAUBSQkAtgIBBQFKBQFkBQFMAQFNAwFOAU8BUAkAawMFAU4FAU8FAVABAVEBAUkDCQBmAgAABQFJCQEBLQEFAUkFAUkBAVIBAUkDCQC/AgIFAWUFAUkJAL4CAQUBSQUBSQEBUwACEyVzX19mYWN0b3J5Q29udHJhY3QBAVQAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBVgACESVzJXNfX3ByaWNlX19sYXN0AQFXAgFYAVkJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFYCQDMCAIJAKQDAQUBWQUDbmlsBQFqAQFaAgJhYQJhYgkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAmFhAgJfXwUCYWIBAmFjAgJhYQJhYgkArAICCQCsAgIJAKwCAgILJXMlcyVzX19HX18FAmFhAgJfXwUCYWIBAmFkAAIPJXNfX2Ftb3VudEFzc2V0AQJhZQACDiVzX19wcmljZUFzc2V0AAJhZgIHJXNfX2ZlZQACYWcJAGsDAAoFAWIAkE4AAmFoCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFmBQJhZwACYWkJALkJAgkAzAgCAgIlcwkAzAgCAgNrTHAFA25pbAUBagACYWoJALkJAgkAzAgCAgIlcwkAzAgCAhJrTHBSZWZyZXNoZWRIZWlnaHQFA25pbAUBagACYWsJALkJAgkAzAgCAgIlcwkAzAgCAg9yZWZyZXNoS0xwRGVsYXkFA25pbAUBagACYWwAHgACYW0JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWsFAmFsAQJhbgACESVzX19mYWN0b3J5Q29uZmlnAQJhbwACGCVzJXNfX21hdGNoZXJfX3B1YmxpY0tleQECYXABAmFxCQCsAgIJAKwCAgIIJXMlcyVzX18FAmFxAiBfX21hcHBpbmdzX19wb29sQ29udHJhY3QyTHBBc3NldAECYXICAmFzAmF0CQCsAgIJAKwCAgkArAICCQCsAgICCCVkJWQlc19fBQJhcwICX18FAmF0AghfX2NvbmZpZwECYXUBAmF2CQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmF2AQJhdwACDCVzX19zaHV0ZG93bgECYXgBAmF5CQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUCYXkBAmF6AAIXJXNfX2FsbG93ZWRMcFNjcmlwdEhhc2gAAmFBAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwECYUIEAmFDAmFEAmFFAmFGCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhQwICICgFAmFEAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFFAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhRgECYUcCAmFIAmFJCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYUgFAmFJCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFICQDMCAICAS4JAMwIAgUCYUkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUoCAmFIAmFJCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYUgFAmFJCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFICQDMCAICAS4JAMwIAgUCYUkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUsBAmFMCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFMBQNuaWwCASABAmFNAQJhTAkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFMBQNuaWwCASAAAmFOCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUcCBQR0aGlzCQEBUwAAAmFPCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUcCBQJhTgUCYUEAAmFQCgACYVEJAPwHBAUCYU4CEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhUQIDSW50BQJhUQkAAgEJAKwCAgkAAwEFAmFRAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmFSCgACYVEJAPwHBAUCYU4CEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVECA0ludAUCYVEJAAIBCQCsAgIJAAMBBQJhUQIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhUwAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYU4JAQJhdwAHAQJhVAAJANkEAQkBAmFHAgUCYU4JAQJhbwABAmFVAAQCYVYJAQJhRwIFBHRoaXMJAQJhZAAEAmFXCQECYUcCBQR0aGlzCQECYWUABAJhdAkBAmFKAgUCYU4JAQJhdQEFAmFXBAJhcwkBAmFKAgUCYU4JAQJhdQEFAmFWCQC1CQIJAQJhRwIFAmFOCQECYXICCQCkAwEFAmFzCQCkAwEFAmF0BQFqAQJhWAECYVkDCQAAAgUCYVkFAWkFBHVuaXQJANkEAQUCYVkBAmFaAQJhWQMJAAACBQJhWQUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhWQECYmEBAmJiCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYmIFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYgUBcAkA2QQBCQCRAwIFAmJiBQFxCQECYVgBCQCRAwIFAmJiBQFyCQECYVgBCQCRAwIFAmJiBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmIFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYgUBdQACYmMJAQJiYQEJAQJhVQAAAmJkBQJiYwACYmUIBQJiZAJfMQACYmYIBQJiZAJfMgACYmcIBQJiZAJfMwACYmgIBQJiZAJfNAACYmkIBQJiZAJfNQACYmoIBQJiZAJfNgACYmsIBQJiZAJfNwECYmwACQC1CQIJAQJhRwIFAmFOCQECYW4ABQFqAAJibQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJsAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYm4JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJibAAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJvCgJicAJicQJicgJicwJidAJidQJidgJidwJieAJieQkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYnAJAMwIAgkApAMBBQJicQkAzAgCCQCkAwEFAmJyCQDMCAIJAKQDAQUCYnMJAMwIAgkApAMBBQJidAkAzAgCCQCkAwEFAmJ1CQDMCAIJAKQDAQUCYnYJAMwIAgkApAMBBQJidwkAzAgCCQCkAwEFAmJ4CQDMCAIJAKQDAQUCYnkFA25pbAUBagECYnoGAmJBAmJCAmJDAmJzAmJ2AmJ3CQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkEJAMwIAgkApAMBBQJiQgkAzAgCCQCkAwEFAmJDCQDMCAIJAKQDAQUCYnMJAMwIAgkApAMBBQJidgkAzAgCCQCkAwEFAmJ3BQNuaWwFAWoBAmJEAQJiRQMJAAACBQJiRQIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYkUBAmJGAgJiRwJiSAkAvAIDBQJiRwUBZAUCYkgBAmJJAwJiRwJiSAFMCQC9AgQFAmJHBQFkBQJiSAUBTAECYkoEAmJLAmJMAmJNAmJOBAJiTwkBAUQCBQJiTQUCYksEAmJQCQEBRAIFAmJOBQJiTAkBAmJGAgUCYlAFAmJPAQJiUQMCYk0CYk4CYlIEAmJTCQECYVUABAJiVAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJTBQF0BAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJTBQF1BAJiVgkBAmJKBAUCYlQFAmJVBQJiTQUCYk4EAmJICQEBRAIFAmJNBQJiVAQCYkcJAQFEAgUCYk4FAmJVBAJiVwkBAUQCBQJiUgUBYgQCYlgJAQJiRgIFAmJIBQJiVwQCYlkJAQJiRgIFAmJHBQJiVwkAzAgCBQJiVgkAzAgCBQJiWAkAzAgCBQJiWQUDbmlsAQJiWgMCYk0CYk4CYlIEAmNhCQECYlEDBQJiTQUCYk4FAmJSCQDMCAIJAQFIAgkAkQMCBQJjYQAABQFiCQDMCAIJAQFIAgkAkQMCBQJjYQABBQFiCQDMCAIJAQFIAgkAkQMCBQJjYQACBQFiBQNuaWwBAmNiBAJjYwJjZAJjZQJhYQQCYlMJAQJhVQAEAmNmCQCRAwIFAmJTBQFxBAJjZwkAkQMCBQJiUwUBcgQCY2gJAJEDAgUCYlMFAXMEAmJLCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXQEAmJMCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXUEAmNpCQCRAwIFAmJTBQFwBAJjaggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmNmCQCsAgIJAKwCAgIGQXNzZXQgBQJjZgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJjZgUCY2QJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNrCQECYkQBBQJjZwQCY2wJAQFEAgUCY2sFAmJLBAJjbQkBAmJEAQUCY2gEAmNuCQEBRAIFAmNtBQJiTAQCY28JAQJiRgIFAmNuBQJjbAQCY3AJAQFIAgUCY28FAWIEAmNxCQEBRAIFAmNlBQFiBAJjcgkBAUQCBQJjagUBYgQCY3MJALwCAwUCY2wFAmNxBQJjcgQCY3QJALwCAwUCY24FAmNxBQJjcgQCY3UJAQFLAwUCY3MFAmJLBQVGTE9PUgQCY3YJAQFLAwUCY3QFAmJMBQVGTE9PUgQCY3cDCQAAAgUCY2MCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFhBQJjdQMJAAACBQJjZwIFV0FWRVMFBHVuaXQJANkEAQUCY2cJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWEFAmN2AwkAAAIFAmNoAgVXQVZFUwUEdW5pdAkA2QQBBQJjaAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWMCCQClCAEFAmFhBQJjYwkBAmJ6BgUCY3UFAmN2BQJjZQUCY3AFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFWAAUCY3AJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY3AFA25pbAkAnAoKBQJjdQUCY3YFAmNnBQJjaAUCY2sFAmNtBQJjagUCY28FAmNpBQJjdwECY3gJAmNjAmN5AmN6AmNBAmNCAmNDAmFhAmNEAmNFBAJiUwkBAmFVAAQCY2YJANkEAQkAkQMCBQJiUwUBcQQCY0YJAJEDAgUCYlMFAXIEAmNHCQCRAwIFAmJTBQFzBAJjSAkAkQMCBQJiUwUBdgQCY0kJAJEDAgUCYlMFAXcEAmJUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXQEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXUEAmNpCQCRAwIFAmJTBQFwBAJjaggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJjZgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJjZgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNKCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmNBCQDZBAECBVdBVkVTBAJjSwkA2AQBCQELdmFsdWVPckVsc2UCBQJjQwkA2QQBAgVXQVZFUwMDCQECIT0CBQJjRgUCY0oGCQECIT0CBQJjRwUCY0sJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJjawMFAmNECQECYkQBBQJjRgkAZQIJAQJiRAEFAmNGBQJjegQCY20DBQJjRAkBAmJEAQUCY0cJAGUCCQECYkQBBQJjRwUCY0IEAmNMCQEBRAIFAmN6BQJiVAQCY00JAQFEAgUCY0IFAmJVBAJjTgkBAmJGAgUCY00FAmNMBAJjbAkBAUQCBQJjawUCYlQEAmNuCQEBRAIFAmNtBQJiVQQCY08DCQAAAgUCY2oAAAQCY28FAWUEAmNQBQFlBAJiVwkAdgYJALkCAgUCY0wFAmNNAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmJXBQFiCQEBSAIFAmNMBQJiVAkBAUgCBQJjTQUCYlUJAQJiRgIJALcCAgUCY24FAmNNCQC3AgIFAmNsBQJjTAUCY1AEAmNvCQECYkYCBQJjbgUCY2wEAmNQCQC8AgMJAQFSAQkAuAICBQJjbwUCY04FAWQFAmNvBAJjUQkBAUQCBQJjeQUBYgMDCQECIT0CBQJjbwUBZQkAvwICBQJjUAUCY1EHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmNQAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCY1EEAmNyCQEBRAIFAmNqBQFiBAJjUgkAvQIEBQJjTAkBAmJJAwUCY24FAmNsBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJjUwkAvQIEBQJjTQUBZAkBAmJJAwUCY24FAmNsBQVGTE9PUgUHQ0VJTElORwQCY1QDCQC/AgIFAmNSBQJjTQkAlAoCBQJjUwUCY00JAJQKAgUCY0wFAmNSBAJjVQgFAmNUAl8xBAJjVggFAmNUAl8yBAJiVwkAvQIEBQJjcgUCY1YFAmNuBQVGTE9PUgkAlwoFCQEBSwMFAmJXBQFiBQVGTE9PUgkBAUsDBQJjVQUCYlQFB0NFSUxJTkcJAQFLAwUCY1YFAmJVBQdDRUlMSU5HBQJjbwUCY1AEAmNXCAUCY08CXzEEAmNYCAUCY08CXzIEAmNZCAUCY08CXzMEAmNwCQEBSAIIBQJjTwJfNAUBYgQCY1oJAQFIAggFAmNPAl81BQFiAwkAZwIAAAUCY1cJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmRhAwkBASEBBQJjRQAABQJjVwQCZGIJAGUCBQJjegUCY1gEAmRjCQBlAgUCY0IFAmNZBAJkZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVYABQJjcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjcAkAzAgCCQELU3RyaW5nRW50cnkCCQEBWgIFAmFhBQJjYwkBAmJvCgUCY1gFAmNZBQJkYQUCY3AFAmN5BQJjWgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZGIFAmRjBQNuaWwJAJ8KDQUCY1cFAmRhBQJjcAUCY2sFAmNtBQJjagUCY2YFAmNpBQJkZAUCZGIFAmRjBQJjQQUCY0MBAmRlAwJkZgJkZwJjagQCZGgJAQFHAgUCZGYJALYCAQUCYmoEAmRpCQEBRwIFAmRnCQC2AgEFAmJrBAJkagkAvAIDCQB2BgkAuQICBQJkaAUCZGkAAAkAtgIBAAUAAQASBQRET1dOBQFnBQJjagMJAAACBQJjagUBZgUBZgUCZGoBAmRrAwJkbAJkbQJkbgQCZG8JALgCAgkAtgIBCQECYkQBCQECYVoBBQJiaAUCZGwEAmRwCQC4AgIJALYCAQkBAmJEAQkBAmFaAQUCYmkFAmRtBAJkcQkAuAICCQC2AgEICQEFdmFsdWUBCQDsBwEFAmJnCHF1YW50aXR5BQJkbgQCZHIJAQJkZQMFAmRvBQJkcAUCZHEFAmRyAQJkcwMCZHQCZHUCZG4EAmRvCQBkAgkBAmJEAQkBAmFaAQUCYmgFAmR0BAJkcAkAZAIJAQJiRAEJAQJhWgEFAmJpBQJkdQQCZHEJAGQCCAkBBXZhbHVlAQkA7AcBBQJiZwhxdWFudGl0eQUCZG4EAmRqCQECZGUDCQC2AgEFAmRvCQC2AgEFAmRwCQC2AgEFAmRxBAJkdgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYWoFBmhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCBQJhaQkApgMBBQJkagUDbmlsCQCUCgIFAmR2BQJkagECZHcCAmR4AmRqAwkAwAICBQJkagUCZHgGCQECYUsBCQC5CQIJAMwIAgIidXBkYXRlZCBLTHAgbG93ZXIgdGhhbiBjdXJyZW50IEtMcAkAzAgCCQCmAwEFAmR4CQDMCAIJAKYDAQUCZGoFA25pbAIBIAECZHkBAmR6BAJkbwkBAmJEAQkBAmFaAQUCYmgEAmRwCQECYkQBCQECYVoBBQJiaQQCZEEIBQJkegZhbW91bnQEAmRCCQBuBAgFAmR6BmFtb3VudAgFAmR6BXByaWNlBQFiBQVGTE9PUgQCZEMDCQAAAggFAmR6CW9yZGVyVHlwZQUDQnV5CQCUCgIFAmRBCQEBLQEFAmRCCQCUCgIJAQEtAQUCZEEFAmRCBAJkdAgFAmRDAl8xBAJkdQgFAmRDAl8yAwMDCQECYVMABgkAAAIFAmJmBQFtBgkAAAIFAmJmBQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAMDCQECIT0CCAgFAmR6CWFzc2V0UGFpcgthbW91bnRBc3NldAUCYmgGCQECIT0CCAgFAmR6CWFzc2V0UGFpcgpwcmljZUFzc2V0BQJiaQkAAgECE1dyb25nIG9yZGVyIGFzc2V0cy4EAmRECQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhaQIBMAkBAmFNAQILaW52YWxpZCBrTHAEAmRFCQECZHMDBQJkdAUCZHUAAAQCZEYIBQJkRQJfMQQCZEcIBQJkRQJfMgQCZEgJAMACAgUCZEcFAmREBAJkSQkAuQkCCQDMCAICBGtMcD0JAMwIAgkApgMBBQJkRAkAzAgCAggga0xwTmV3PQkAzAgCCQCmAwEFAmRHCQDMCAICFCBhbW91bnRBc3NldEJhbGFuY2U9CQDMCAIJAKQDAQUCZG8JAMwIAgITIHByaWNlQXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmRwCQDMCAICGSBhbW91bnRBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJkdAkAzAgCAhggcHJpY2VBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJkdQkAzAgCAgggaGVpZ2h0PQkAzAgCCQCkAwEFBmhlaWdodAUDbmlsAgAJAJQKAgUCZEgFAmRJAQJkSgECZEsDCQECIT0CCQCQAwEIBQJkSwhwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEAmRMCQEFdmFsdWUBCQCRAwIIBQJkSwhwYXltZW50cwAABAJjZAkBBXZhbHVlAQgFAmRMB2Fzc2V0SWQEAmRNCAUCZEwGYW1vdW50BAJjTwkBAmNiBAkA2AQBCAUCZEsNdHJhbnNhY3Rpb25JZAkA2AQBBQJjZAUCZE0IBQJkSwZjYWxsZXIEAmN1CAUCY08CXzEEAmN2CAUCY08CXzIEAmNpCQENcGFyc2VJbnRWYWx1ZQEIBQJjTwJfOQQCY3cIBQJjTwNfMTADAwkBAmFTAAYJAAACBQJjaQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2kJAJcKBQUCY3UFAmN2BQJkTQUCY2QFAmN3AQJkTgMCZEsCY3kCY0UDCQECIT0CCQCQAwEIBQJkSwhwYXltZW50cwACCQACAQIfZXhhY3RseSAyIHBheW1lbnRzIGFyZSBleHBlY3RlZAQCZE8JAQV2YWx1ZQEJAJEDAggFAmRLCHBheW1lbnRzAAAEAmRQCQEFdmFsdWUBCQCRAwIIBQJkSwhwYXltZW50cwABBAJkUQkBAmN4CQkA2AQBCAUCZEsNdHJhbnNhY3Rpb25JZAUCY3kIBQJkTwZhbW91bnQIBQJkTwdhc3NldElkCAUCZFAGYW1vdW50CAUCZFAHYXNzZXRJZAkApQgBCAUCZEsGY2FsbGVyBwUCY0UEAmNpCQENcGFyc2VJbnRWYWx1ZQEIBQJkUQJfOAMDAwkBAmFTAAYJAAACBQJjaQUBbAYJAAACBQJjaQUBbgkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2kFAmRRAQJkUgECZFMEAmRUCQD8BwQFAmFOAgRlbWl0CQDMCAIFAmRTBQNuaWwFA25pbAMJAAACBQJkVAUCZFQEAmRVBAJkVgUCZFQDCQABAgUCZFYCB0FkZHJlc3MEAmRXBQJkVgkA/AcEBQJkVwIEZW1pdAkAzAgCBQJkUwUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZFUFAmRVBQJkUwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZFgCAmRTAmFoBAJkWQMJAAACBQJhaAAAAAAJAGsDBQJkUwUCYWgFAWIJAJQKAgkAZQIFAmRTBQJkWQUCZFkBAmRaBAJlYQJlYgJhYQJhYgQCZWMJAAACBQJhYgUEdW5pdAQCZWQJAQJiRAEJAQJhWgEFAmJoBAJlZQkBAmJEAQkBAmFaAQUCYmkEAmVmAwkAAAIFAmViBQJiaAYDCQAAAgUCZWIFAmJpBwkBAmFLAQINaW52YWxpZCBhc3NldAQCZWcDBQJlYwkAlAoCBQJlZAUCZWUDBQJlZgkAlAoCCQBlAgUCZWQFAmVhBQJlZQkAlAoCBQJlZAkAZQIFAmVlBQJlYQQCZWgIBQJlZwJfMQQCZWkIBQJlZwJfMgQCZWoDBQJlZgkAlAoCBQJlYQAACQCUCgIAAAUCZWEEAmVrCAUCZWoCXzEEAmVsCAUCZWoCXzIEAmRBCAkBAmRYAgUCZWsFAmFQAl8xBAJkQggJAQJkWAIFAmVsBQJhUAJfMQQCZW0JAQJkWAIFAmVhBQJhUAQCZW4IBQJlbQJfMQQCZFkIBQJlbQJfMgQCZW8JAGQCBQJlaAUCZEEEAmVwCQBkAgUCZWkFAmRCBAJlcQkBAmJGAgkBAUQCBQJlcAUCYmsJAQFEAgUCZW8FAmJqBAJlcgkBAUgCBQJlcQUBYgQCZXMDBQJlZgUCZWgFAmVpBAJldAkAtgIBBQJlcwQCZXUJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiZwkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJiZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmV2AwkAvwICBQJldQUBZgYJAQJhSwECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZXYFAmV2BAJldwkAtgIBBQJlbgQCZXgJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZXUJALgCAgkBCnNxcnRCaWdJbnQECQC3AgIFAWQJALoCAgkAuQICBQJldwUBZAUCZXQAEgASBQRET1dOBQFkBQFkBQNuaWwEAmRkAwUCZWMFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVYABQJlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJlcgkAzAgCCQELU3RyaW5nRW50cnkCCQEBWgIJAKUIAQkBBXZhbHVlAQUCYWEJANgEAQkBBXZhbHVlAQUCYWIJAQJibwoFAmVrBQJlbAUCZXgFAmVyAAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQCZXkJAQJiRgIJAQFEAgUCZWkFAmJrCQEBRAIFAmVoBQJiagQCZXoJAQFIAgUCZXkFAWIEAmVBBAJlQgMFAmVmCQCUCgIFAmVrBQJlaAkAlAoCBQJlbAUCZWkEAmRTCAUCZUICXzEEAmVDCAUCZUICXzIEAmVECQCgAwEJALwCAwUCZXUJALYCAQkAaQIFAmRTAAIJALYCAQUCZUMJAGsDCQBlAgUCZXgFAmVEBQFiBQJlRAkAlwoFBQJleAUCZGQFAmRZBQJlQQUCZWYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmVFBQJlRgJlbgJlYgJhYQJhYgQCZWMJAAACBQJhYgUEdW5pdAQCYlMJAQJhVQAEAmJUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXQEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXUEAmVHCQDMCAIDCQAAAgUCZWIFAmJnBgkBAmFLAQIQaW52YWxpZCBscCBhc3NldAUDbmlsAwkAAAIFAmVHBQJlRwQCZUgDCQAAAgUCZUYFAmJoBgMJAAACBQJlRgUCYmkHCQECYUsBAg1pbnZhbGlkIGFzc2V0BAJlSQMFAmVICQC2AgEJAQJiRAEJAQJhWgEFAmJoCQC2AgEJAQJiRAEJAQJhWgEFAmJpBAJlSgMFAmVIBQJiVAUCYlUEAmVLCQECYkQBCQECYVoBBQJiaAQCZUwJAQJiRAEJAQJhWgEFAmJpBAJlTQMFAmVIBQJlSwUCZUwEAmVOCQC2AgEFAmVNBAJldQkAtgIBCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJnCQCsAgIJAKwCAgIGYXNzZXQgCQDYBAEFAmJnAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZU8JALYCAQUCZW4EAmVQCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmVJCQC4AgIFAWQJAHYGCQC4AgIFAWQJALoCAgkAuQICBQJlTwUBZAUCZXUAEgUBaAAAABIFBERPV04FAWQFA25pbAQCZVEJAQJkWAIFAmVQBQJhUgQCZVIIBQJlUQJfMQQCZFkIBQJlUQJfMgQCZVMDBQJlSAkAlgoEBQJlUgAACQBlAgUCZUsFAmVQBQJlTAkAlgoEAAAFAmVSBQJlSwkAZQIFAmVMBQJlUAQCZVQIBQJlUwJfMQQCZVUIBQJlUwJfMgQCZVYIBQJlUwJfMwQCZVcIBQJlUwJfNAQCZXEJAQJiRgIJAQFEAgUCZVcFAmJrCQEBRAIFAmVWBQJiagQCZXIJAQFIAgUCZXEFAWIEAmRkAwUCZWMFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWMCCQClCAEJAQV2YWx1ZQEFAmFhCQDYBAEJAQV2YWx1ZQEFAmFiCQECYnoGBQJlVAUCZVUFAmVuBQJlcgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVYABQJlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJlcgUDbmlsBAJleQkBAmJGAgkBAUQCBQJlTAUCYmsJAQFEAgUCZUsFAmJqBAJlegkBAUgCBQJleQUBYgQCZUEEAmVYCQBoAgkAoAMBCQC8AgMFAmVJBQJlTwUCZXUAAgkAawMJAGUCBQJlUgUCZVgFAWIFAmVYCQCXCgUFAmVSBQJkZAUCZFkFAmVBBQJlSAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZVkABAJkVgkAoggBCQEBVAADCQABAgUCZFYCBlN0cmluZwQCZVoFAmRWCQDZBAEFAmVaAwkAAQIFAmRWAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmZhAAQCZFYJAKIIAQkBAVUAAwkAAQIFAmRWAgZTdHJpbmcEAmVaBQJkVgkA2QQBBQJlWgMJAAECBQJkVgIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJmYgECZEsEAmRWCQECZVkAAwkAAQIFAmRWAgpCeXRlVmVjdG9yBAJmYwUCZFYJAAACCAUCZEsPY2FsbGVyUHVibGljS2V5BQJmYwMJAAECBQJkVgIEVW5pdAkAAAIIBQJkSwZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECZmQBAmRLBAJmZQkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJkVgkBAmVZAAMJAAECBQJkVgIKQnl0ZVZlY3RvcgQCZmMFAmRWAwkAAAIIBQJkSw9jYWxsZXJQdWJsaWNLZXkFAmZjBgUCZmUDCQABAgUCZFYCBFVuaXQDCQAAAggFAmRLBmNhbGxlcgUEdGhpcwYFAmZlCQACAQILTWF0Y2ggZXJyb3IbAmRLAQpzZXRNYW5hZ2VyAQJmZgQCZmcJAQJmZAEFAmRLAwkAAAIFAmZnBQJmZwQCZmgJANkEAQUCZmYDCQAAAgUCZmgFAmZoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFVAAUCZmYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkSwEOY29uZmlybU1hbmFnZXIABAJmaQkBAmZhAAQCZmoDCQEJaXNEZWZpbmVkAQUCZmkGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZqBQJmagQCZmsDCQAAAggFAmRLD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZmkGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZrBQJmawkAzAgCCQELU3RyaW5nRW50cnkCCQEBVAAJANgEAQkBBXZhbHVlAQUCZmkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVUABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEsBA3B1dAICY3kCZmwDCQBmAgAABQJjeQkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJkUQkBAmROAwUCZEsFAmN5BgQCZGEIBQJkUQJfMgQCY2YIBQJkUQJfNwQCY3cIBQJkUQJfOQQCZGIIBQJkUQNfMTAEAmRjCAUCZFEDXzExBAJmbQgFAmRRA18xMgQCZm4IBQJkUQNfMTMEAmRPCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJkSwhwYXltZW50cwAABmFtb3VudAQCZFAJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRLCHBheW1lbnRzAAEGYW1vdW50BAJkcgkBAmRrAwUCZE8FAmRQCQC2AgEAAAMJAAACBQJkcgUCZHIEAmRUCQD8BwQFAmFOAgRlbWl0CQDMCAIFAmRhBQNuaWwFA25pbAMJAAACBQJkVAUCZFQEAmRVBAJkVgUCZFQDCQABAgUCZFYCB0FkZHJlc3MEAmRXBQJkVgkA/AcEBQJkVwIEZW1pdAkAzAgCBQJkYQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZFUFAmRVBAJmbwMJAGYCBQJkYgAACQD8BwQFAmJuAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZm0FAmRiBQNuaWwFA25pbAMJAAACBQJmbwUCZm8EAmZwAwkAZgIFAmRjAAAJAPwHBAUCYm4CA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmbgUCZGMFA25pbAUDbmlsAwkAAAIFAmZwBQJmcAQCZnEDBQJmbAQCZnIJAPwHBAUCYm0CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNmBQJkYQUDbmlsAwkAAAIFAmZyBQJmcgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkSwZjYWxsZXIFAmRhBQJjZgUDbmlsBAJmcwkBAmRzAwAAAAAAAAMJAAACBQJmcwUCZnMEAmRqCAUCZnMCXzIEAmZ0CAUCZnMCXzEEAmZ1CQECZHcCBQJkcgUCZGoDCQAAAgUCZnUFAmZ1CQDOCAIJAM4IAgUCY3cFAmZxBQJmdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkSwEKcHV0Rm9yRnJlZQECZnYDCQBmAgAABQJmdgkAAgECFEludmFsaWQgdmFsdWUgcGFzc2VkBAJkUQkBAmROAwUCZEsFAmZ2BwQCY3cIBQJkUQJfOQQCZE8JALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRLCHBheW1lbnRzAAAGYW1vdW50BAJkUAkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZEsIcGF5bWVudHMAAQZhbW91bnQEAmRyCQECZGsDBQJkTwUCZFAJALYCAQAAAwkAAAIFAmRyBQJkcgQCZncJAQJkcwMAAAAAAAAEAmZ0CAUCZncCXzEEAmRqCAUCZncCXzIEAmZ1CQECZHcCBQJkcgUCZGoDCQAAAgUCZnUFAmZ1CQDOCAIFAmN3BQJmdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkSwEJcHV0T25lVGtuAgJmeAJmeQQCZnoKAAJhUQkA/AcEBQJhTgIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFRAgdCb29sZWFuBQJhUQkAAgEJAKwCAgkAAwEFAmFRAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmQQMDAwkBAmFTAAYJAAACBQJiZgUBbAYJAAACBQJiZgUBbgYFAmZ6BAJlRwkAzAgCAwMJAQEhAQUCZkEGCQECZmIBBQJkSwYJAQJhSwECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRLCHBheW1lbnRzAAEGCQECYUsBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlRwUCZUcEAmZCCQCRAwIIBQJkSwhwYXltZW50cwAABAJlYggFAmZCB2Fzc2V0SWQEAmVhCAUCZkIGYW1vdW50BAJkcgMJAAACBQJlYgUCYmgJAQJkawMJALYCAQUCZWEJALYCAQAACQC2AgEAAAMJAAACBQJlYgUCYmkJAQJkawMJALYCAQAACQC2AgEFAmVhCQC2AgEAAAkBAmFLAQIecGF5bWVudCBhc3NldCBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFAmRyBQJkcgQCYWEIBQJkSwZjYWxsZXIEAmFiCAUCZEsNdHJhbnNhY3Rpb25JZAQCZkMJAQJkWgQFAmVhBQJlYgUCYWEFAmFiAwkAAAIFAmZDBQJmQwQCZWYIBQJmQwJfNQQCZkQIBQJmQwJfNAQCZFkIBQJmQwJfMwQCZGQIBQJmQwJfMgQCZkUIBQJmQwJfMQQCZkYDAwkAZgIFAmZ4AAAJAGYCBQJmeAUCZkUHCQECYUsBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZ4BQNuaWwCAAUCZkUEAmRUCQECZFIBBQJmRgMJAAACBQJkVAUCZFQEAmZxAwUCZnkEAmZHCQD8BwQFAmJtAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiZwUCZkYFA25pbAMJAAACBQJmRwUCZkcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZEsGY2FsbGVyBQJmRgUCYmcFA25pbAQCZkgDCQBmAgUCZFkAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhTwUCZFkFAmViBQNuaWwFA25pbAQCZkkDCQAAAgUEdGhpcwUCYU8JAJQKAgAAAAADBQJlZgkAlAoCCQEBLQEFAmRZAAAJAJQKAgAACQEBLQEFAmRZBAJkdAgFAmZJAl8xBAJkdQgFAmZJAl8yBAJmSgkBAmRzAwUCZHQFAmR1AAAEAmZ0CAUCZkoCXzEEAmRqCAUCZkoCXzIEAmRECQEFdmFsdWUBCQCiCAEFAmFpBAJmdQkBAmR3AgUCZHIFAmRqAwkAAAIFAmZ1BQJmdQkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZAUCZnEFAmZIBQJmdAUCZkYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEsBEXB1dE9uZVRrblJFQURPTkxZAgJlYgJlYQQCZksJAQJkWgQFAmVhCQECYVgBBQJlYgUEdW5pdAUEdW5pdAQCZkUIBQJmSwJfMQQCZGQIBQJmSwJfMgQCZFkIBQJmSwJfMwQCZkQIBQJmSwJfNAQCZWYIBQJmSwJfNQkAlAoCBQNuaWwJAJUKAwUCZkUFAmRZBQJmRAJkSwEJZ2V0T25lVGtuAgJmTAJmeAQCZnoKAAJhUQkA/AcEBQJhTgIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFRAgdCb29sZWFuBQJhUQkAAgEJAKwCAgkAAwEFAmFRAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmTQMDCQECYVMABgkAAAIFAmJmBQFuBgUCZnoEAmVHCQDMCAIDAwkBASEBBQJmTQYJAQJmYgEFAmRLBgkBAmFLAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZEsIcGF5bWVudHMAAQYJAQJhSwECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVHBQJlRwQCZUYJAQJhWAEFAmZMBAJmQgkAkQMCCAUCZEsIcGF5bWVudHMAAAQCZWIIBQJmQgdhc3NldElkBAJlbggFAmZCBmFtb3VudAQCZHIJAQJkawMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHIFAmRyBAJhYQgFAmRLBmNhbGxlcgQCYWIIBQJkSw10cmFuc2FjdGlvbklkBAJmTgkBAmVFBQUCZUYFAmVuBQJlYgUCYWEFAmFiAwkAAAIFAmZOBQJmTgQCZUgIBQJmTgJfNQQCZkQIBQJmTgJfNAQCZFkIBQJmTgJfMwQCZGQIBQJmTgJfMgQCZk8IBQJmTgJfMQQCZFMDAwkAZgIFAmZ4AAAJAGYCBQJmeAUCZk8HCQECYUsBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZ4BQNuaWwCAAUCZk8EAmZQCQD8BwQFAmFOAgRidXJuCQDMCAIFAmVuBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmViBQJlbgUDbmlsAwkAAAIFAmZQBQJmUAQCZlEJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWEFAmRTBQJlRgUDbmlsBAJmSAMJAGYCBQJkWQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFPBQJkWQUCZUYFA25pbAUDbmlsBAJmUgQCZlMDCQAAAgUEdGhpcwUCYU8AAAUCZFkDBQJlSAkAlAoCCQEBLQEJAGQCBQJkUwUCZlMAAAkAlAoCAAAJAQEtAQkAZAIFAmRTBQJmUwQCZHQIBQJmUgJfMQQCZHUIBQJmUgJfMgQCZlQJAQJkcwMFAmR0BQJkdQAABAJmdAgFAmZUAl8xBAJkaggFAmZUAl8yBAJmdQkBAmR3AgUCZHIFAmRqAwkAAAIFAmZ1BQJmdQkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZAUCZlEFAmZIBQJmdAUCZFMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEsBEWdldE9uZVRrblJFQURPTkxZAgJlRgJlbgQCZlUJAQJlRQUJAQJhWAEFAmVGBQJlbgUCYmcFBHVuaXQFBHVuaXQEAmZPCAUCZlUCXzEEAmRkCAUCZlUCXzIEAmRZCAUCZlUCXzMEAmZECAUCZlUCXzQEAmVICAUCZlUCXzUJAJQKAgUDbmlsCQCVCgMFAmZPBQJkWQUCZkQCZEsBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmZWAmZMAmZ4BAJmegoAAmFRCQD8BwQFAmFOAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVECB0Jvb2xlYW4FAmFRCQACAQkArAICCQADAQUCYVECHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZNAwMJAQJhUwAGCQAAAgUCYmYFAW4GBQJmegQCZUcJAMwIAgMDCQEBIQEFAmZNBgkBAmZiAQUCZEsGCQECYUsBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkSwhwYXltZW50cwAABgkBAmFLAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZUcFAmVHBAJlRgkBAmFYAQUCZkwEAmFhCAUCZEsGY2FsbGVyBAJhYggFAmRLDXRyYW5zYWN0aW9uSWQEAmRyCQECZGsDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRyBQJkcgQCZlcJAPwHBAUCYm0CB3Vuc3Rha2UJAMwIAgkA2AQBBQJiZwkAzAgCBQJmVgUDbmlsBQNuaWwDCQAAAgUCZlcFAmZXBAJmWAkBAmVFBQUCZUYFAmZWBQJiZwUCYWEFAmFiAwkAAAIFAmZYBQJmWAQCZUgIBQJmWAJfNQQCZkQIBQJmWAJfNAQCZFkIBQJmWAJfMwQCZGQIBQJmWAJfMgQCZk8IBQJmWAJfMQQCZFMDAwkAZgIFAmZ4AAAJAGYCBQJmeAUCZk8HCQECYUsBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZ4BQNuaWwCAAUCZk8EAmZQCQD8BwQFAmFOAgRidXJuCQDMCAIFAmZWBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJnBQJmVgUDbmlsAwkAAAIFAmZQBQJmUAQCZlEJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRLBmNhbGxlcgUCZFMFAmVGBQNuaWwEAmZIAwkAZgIFAmRZAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYU8FAmRZBQJlRgUDbmlsBQNuaWwEAmZZBAJmUwMJAAACBQR0aGlzBQJhTwAABQJkWQMFAmVICQCUCgIJAQEtAQkAZAIFAmRTBQJmUwAACQCUCgIAAAkBAS0BCQBkAgUCZFMFAmZTBAJkdAgFAmZZAl8xBAJkdQgFAmZZAl8yBAJmWgkBAmRzAwUCZHQFAmR1AAAEAmZ0CAUCZloCXzEEAmRqCAUCZloCXzIEAmZ1CQECZHcCBQJkcgUCZGoDCQAAAgUCZnUFAmZ1CQCUCgIJAM4IAgkAzggCCQDOCAIFAmRkBQJmUQUCZkgFAmZ0BQJkUwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkSwEDZ2V0AAQCY08JAQJkSgEFAmRLBAJnYQgFAmNPAl8xBAJjdggFAmNPAl8yBAJkTQgFAmNPAl8zBAJjZAgFAmNPAl80BAJjdwgFAmNPAl81BAJkcgkBAmRrAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJkcgUCZHIEAmdiCQD8BwQFAmFOAgRidXJuCQDMCAIFAmRNBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNkBQJkTQUDbmlsAwkAAAIFAmdiBQJnYgQCZ2MJAQJkcwMJAQEtAQUCZ2EJAQEtAQUCY3YAAAQCZnQIBQJnYwJfMQQCZGoIBQJnYwJfMgQCZnUJAQJkdwIFAmRyBQJkagMJAAACBQJmdQUCZnUJAM4IAgUCY3cFAmZ0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRLAQlnZXROb0xlc3MCAmdkAmdlBAJjTwkBAmRKAQUCZEsEAmN1CAUCY08CXzEEAmN2CAUCY08CXzIEAmRNCAUCY08CXzMEAmNkCAUCY08CXzQEAmN3CAUCY08CXzUDCQBmAgUCZ2QFAmN1CQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJjdQIDIDwgCQCkAwEFAmdkAwkAZgIFAmdlBQJjdgkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmN2AgMgPCAJAKQDAQUCZ2UEAmRyCQECZGsDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRyBQJkcgQCZ2IJAPwHBAUCYU4CBGJ1cm4JAMwIAgUCZE0FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2QFAmRNBQNuaWwDCQAAAgUCZ2IFAmdiBAJnZgkBAmRzAwkBAS0BBQJjdQkBAS0BBQJjdgAABAJmdAgFAmdmAl8xBAJkaggFAmdmAl8yBAJmdQkBAmR3AgUCZHIFAmRqAwkAAAIFAmZ1BQJmdQkAzggCBQJjdwUCZnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEsBDXVuc3Rha2VBbmRHZXQBAmRTBAJnZwMJAQIhPQIJAJADAQgFAmRLCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmdnBQJnZwQCYlMJAQJhVQAEAmNmCQDZBAEJAJEDAgUCYlMFAXEEAmRyCQECZGsDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRyBQJkcgQCZlcJAPwHBAUCYm0CB3Vuc3Rha2UJAMwIAgkA2AQBBQJjZgkAzAgCBQJkUwUDbmlsBQNuaWwDCQAAAgUCZlcFAmZXBAJjTwkBAmNiBAkA2AQBCAUCZEsNdHJhbnNhY3Rpb25JZAkA2AQBBQJjZgUCZFMIBQJkSwZjYWxsZXIEAmN1CAUCY08CXzEEAmN2CAUCY08CXzIEAmNpCQENcGFyc2VJbnRWYWx1ZQEIBQJjTwJfOQQCY3cIBQJjTwNfMTAEAmdoAwMJAQJhUwAGCQAAAgUCY2kFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNpBgMJAAACBQJnaAUCZ2gEAmdiCQD8BwQFAmFOAgRidXJuCQDMCAIFAmRTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNmBQJkUwUDbmlsAwkAAAIFAmdiBQJnYgQCZ2kJAQJkcwMJAQEtAQUCY3UJAQEtAQUCY3YAAAQCZnQIBQJnaQJfMQQCZGoIBQJnaQJfMgQCZnUJAQJkdwIFAmRyBQJkagMJAAACBQJmdQUCZnUJAM4IAgUCY3cFAmZ0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRLARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJmVgJnagJnZQQCZk0DCQECYVMABgkAAAIFAmJmBQFuBAJlRwkAzAgCAwkBASEBBQJmTQYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkSwhwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVHBQJlRwQCZHIJAQJkawMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHIFAmRyBAJmVwkA/AcEBQJibQIHdW5zdGFrZQkAzAgCCQDYBAEFAmJnCQDMCAIFAmZWBQNuaWwFA25pbAMJAAACBQJmVwUCZlcEAmNPCQECY2IECQDYBAEIBQJkSw10cmFuc2FjdGlvbklkCQDYBAEFAmJnBQJmVggFAmRLBmNhbGxlcgQCY3UIBQJjTwJfMQQCY3YIBQJjTwJfMgQCY3cIBQJjTwNfMTAEAmdrCQDMCAIDCQBnAgUCY3UFAmdqBgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdqBQNuaWwCAAkAzAgCAwkAZwIFAmN2BQJnZQYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdlBQNuaWwCAAUDbmlsAwkAAAIFAmdrBQJnawQCZ2IJAPwHBAUCYU4CBGJ1cm4JAMwIAgUCZlYFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYmcFAmZWBQNuaWwDCQAAAgUCZ2IFAmdiBAJnbAkBAmRzAwkBAS0BBQJjdQkBAS0BBQJjdgAABAJmdAgFAmdsAl8xBAJkaggFAmdsAl8yBAJmdQkBAmR3AgUCZHIFAmRqAwkAAAIFAmZ1BQJmdQkAzggCBQJjdwUCZnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEsBCGFjdGl2YXRlAgJnbQJnbgMJAQIhPQIJAKUIAQgFAmRLBmNhbGxlcgkApQgBBQJhTgkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAAFAmdtCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmduBQNuaWwCB3N1Y2Nlc3MCZEsBCnJlZnJlc2hLTHAABAJnbwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQJhagAABAJncAMJAGcCCQBlAgUGaGVpZ2h0BQJnbwUCYW0FBHVuaXQJAQJhSwEJALkJAgkAzAgCCQCkAwEFAmFtCQDMCAICLyBibG9ja3MgaGF2ZSBub3QgcGFzc2VkIHNpbmNlIHRoZSBwcmV2aW91cyBjYWxsBQNuaWwCAAMJAAACBQJncAUCZ3AEAmRECQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhaQIBMAkBAmFNAQILaW52YWxpZCBrTHAEAmdxCQECZHMDAAAAAAAABAJncggFAmdxAl8xBAJkaggFAmdxAl8yBAJkdgMJAQIhPQIFAmREBQJkagUCZ3IJAQJhSwECEm5vdGhpbmcgdG8gcmVmcmVzaAkAlAoCBQJkdgkApgMBBQJkagkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkSwEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYVUAAmRLARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJiRQkAlAoCBQNuaWwJAQJiRAEFAmJFAmRLARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJiTQJiTgJiUgQCY2EJAQJiUQMFAmJNBQJiTgUCYlIJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJjYQAACQDMCAIJAKYDAQkAkQMCBQJjYQABCQDMCAIJAKYDAQkAkQMCBQJjYQACBQNuaWwCZEsBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFFAUYJAJQKAgUDbmlsCQCmAwEJAQFEAgUBRQUBRgJkSwEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBSQFKCQCUCgIFA25pbAkBAUgCCQCnAwEFAUkFAUoCZEsBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQICYkcCYkgJAJQKAgUDbmlsCQCmAwEJAQJiRgIJAKcDAQUCYkcJAKcDAQUCYkgCZEsBI2VzdGltYXRlUHV0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZCQJjYwJjeQJjegJjQQJjQgJjQwJhYQJjRAJjRQkAlAoCBQNuaWwJAQJjeAkFAmNjBQJjeQUCY3oFAmNBBQJjQgUCY0MFAmFhBQJjRAUCY0UCZEsBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJjYwJjZAJjZQJhYQQCY08JAQJjYgQFAmNjBQJjZAUCY2UJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFhCQCUCgIFA25pbAkAnAoKCAUCY08CXzEIBQJjTwJfMggFAmNPAl8zCAUCY08CXzQIBQJjTwJfNQgFAmNPAl82CAUCY08CXzcJAKYDAQgFAmNPAl84CAUCY08CXzkIBQJjTwNfMTACZEsBDXN0YXRzUkVBRE9OTFkABAJiUwkBAmFVAAQCY2YJANkEAQkAkQMCBQJiUwUBcQQCZ3MJAJEDAgUCYlMFAXIEAmd0CQCRAwIFAmJTBQFzBAJjSAkAkQMCBQJiUwUBdgQCY0kJAJEDAgUCYlMFAXcEAmJUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXQEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlMFAXUEAmd1CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNmCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNmAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ3YJAQJiRAEFAmdzBAJndwkBAmJEAQUCZ3QEAmd4AwkAAAIFAmd1AAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmJRAwUCZ3YFAmd3BQJndQQCY3AAAAQCZ3kJAQFIAgkAkQMCBQJneAABBQFiBAJnegkBAUgCCQCRAwIFAmd4AAIFAWIEAmdBCQEFdmFsdWUBCQCaCAIFAmFOCQECYXgBCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJndgkAzAgCCQCkAwEFAmd3CQDMCAIJAKQDAQUCZ3UJAMwIAgkApAMBBQJjcAkAzAgCCQCkAwEFAmd5CQDMCAIJAKQDAQUCZ3oJAMwIAgkApAMBBQJnQQUDbmlsBQFqAmRLASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECY3oEAmJTCQECYVUABAJjZgkA2QQBCQCRAwIFAmJTBQFxBAJjRgkAkQMCBQJiUwUBcgQCY2cJANkEAQUCY0YEAmNHCQCRAwIFAmJTBQFzBAJjaAkA2QQBBQJjRwQCYlQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiUwUBdAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiUwUBdQQCY2kJAJEDAgUCYlMFAXAEAmd1CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNmCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNmAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ3YJAQJiRAEFAmNGBAJndwkBAmJEAQUCY0cEAmJPCQEBRAIFAmd2BQJiVAQCYlAJAQFEAgUCZ3cFAmJVBAJjbwMJAAACBQJndQAABQFlCQECYkYCBQJiUAUCYk8EAmNMCQEBRAIFAmN6BQJiVAQCY00JALwCAwUCY0wFAmNvBQFkBAJjQgkBAUgCBQJjTQUCYlUEAmRRCQECY3gJAgAAoMIeBQJjegUCY2cFAmNCBQJjaAIABgcEAmNXCAUCZFECXzEEAmdCCAUCZFECXzMEAmNrCAUCZFECXzQEAmNtCAUCZFECXzUEAmNqCAUCZFECXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNXCQDMCAIJAKQDAQkBAUgCBQJjbwUBYgkAzAgCCQCkAwEFAmNrCQDMCAIJAKQDAQUCY20JAMwIAgkApAMBBQJjagkAzAgCBQJjaQkAzAgCCQCkAwEFAmN6CQDMCAIJAKQDAQUCY0IFA25pbAUBagJkSwEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECY0IEAmJTCQECYVUABAJjZgkA2QQBCQCRAwIFAmJTBQFxBAJjRgkAkQMCBQJiUwUBcgQCY2cJANkEAQUCY0YEAmNHCQCRAwIFAmJTBQFzBAJjaAkA2QQBBQJjRwQCYlQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiUwUBdAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiUwUBdQQCY2kJAJEDAgUCYlMFAXAEAmd1CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNmCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNmAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ0MJAQJiRAEFAmNGBAJnRAkBAmJEAQUCY0cEAmdFCQEBRAIFAmdDBQJiVAQCZ0YJAQFEAgUCZ0QFAmJVBAJjbwMJAAACBQJndQAABQFlCQECYkYCBQJnRgUCZ0UEAmNNCQEBRAIFAmNCBQJiVQQCY0wJALwCAwUCY00FAWQFAmNvBAJjegkBAUgCBQJjTAUCYlQEAmRRCQECY3gJAgAAoMIeBQJjegUCY2cFAmNCBQJjaAIABgcEAmNXCAUCZFECXzEEAmdCCAUCZFECXzMEAmNrCAUCZFECXzQEAmNtCAUCZFECXzUEAmNqCAUCZFECXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNXCQDMCAIJAKQDAQkBAUgCBQJjbwUBYgkAzAgCCQCkAwEFAmNrCQDMCAIJAKQDAQUCY20JAMwIAgkApAMBBQJjagkAzAgCBQJjaQkAzAgCCQCkAwEFAmN6CQDMCAIJAKQDAQUCY0IFA25pbAUBagJkSwETZXZhbHVhdGVHZXRSRUFET05MWQICZ0cCZ0gEAmNPCQECY2IEAgAFAmdHBQJnSAUEdGhpcwQCY3UIBQJjTwJfMQQCY3YIBQJjTwJfMgQCY2sIBQJjTwJfNQQCY20IBQJjTwJfNgQCY2oIBQJjTwJfNwQCY3AIBQJjTwJfOAQCY2kJAQ1wYXJzZUludFZhbHVlAQgFAmNPAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY3UJAMwIAgkApAMBBQJjdgkAzAgCCQCkAwEFAmNrCQDMCAIJAKQDAQUCY20JAMwIAgkApAMBBQJjagkAzAgCCQCmAwEFAmNwCQDMCAIJAKQDAQUCY2kFA25pbAUBagECZ0kBAmdKAAQCZ0sEAmRWCQECZVkAAwkAAQIFAmRWAgpCeXRlVmVjdG9yBAJmYwUCZFYFAmZjAwkAAQIFAmRWAgRVbml0CAUCZ0kPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmRWBQJnSQMJAAECBQJkVgIFT3JkZXIEAmR6BQJkVgQCZ0wJAQJhVAAEAmdNCQECZHkBBQJkegQCYUMIBQJnTQJfMQQCYUQIBQJnTQJfMgQCYUUJAPQDAwgFAmR6CWJvZHlCeXRlcwkAkQMCCAUCZHoGcHJvb2ZzAAAIBQJkeg9zZW5kZXJQdWJsaWNLZXkEAmFGCQD0AwMIBQJkeglib2R5Qnl0ZXMJAJEDAggFAmR6BnByb29mcwABBQJnTAMDAwUCYUMFAmFFBwUCYUYHBgkBAmFCBAUCYUMFAmFEBQJhRQUCYUYDCQABAgUCZFYCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJlWgUCZFYDCQD0AwMIBQJnSQlib2R5Qnl0ZXMJAJEDAggFAmdJBnByb29mcwAABQJnSwYEAmdOCQD2AwEJAQV2YWx1ZQEIBQJlWgZzY3JpcHQEAmdPCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYU4JAQJhegAEAmdQCQDxBwEFBHRoaXMDCQAAAgUCZ08FAmdOCQECIT0CBQJnUAUCZ04HCQD0AwMIBQJnSQlib2R5Qnl0ZXMJAJEDAggFAmdJBnByb29mcwAABQJnS0Hdfx8=", "height": 3509048, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: GVSUzU21M4AF7edhGHMtYfxWkFGirrAjR1Zu8qhVZqv5 Next: 3Hop4Nrf8wdReCwcySyaMqUwjwbKK6Kut7b8LwsBF83R Diff:
OldNewDifferences
14721472 then true
14731473 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
14741474 case s: SetScriptTransaction =>
1475- let newHash = blake2b256(value(s.script))
1476- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1477- let currentHash = scriptHash(this)
1478- if (if ((allowedHash == newHash))
1479- then (currentHash != newHash)
1480- else false)
1475+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
14811476 then true
1482- else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1477+ else {
1478+ let newHash = blake2b256(value(s.script))
1479+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1480+ let currentHash = scriptHash(this)
1481+ if ((allowedHash == newHash))
1482+ then (currentHash != newHash)
1483+ else false
1484+ }
14831485 case _ =>
14841486 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
14851487 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
8585
8686
8787 func fc () = "%s__factoryContract"
8888
8989
9090 func mpk () = "%s__managerPublicKey"
9191
9292
9393 func pmpk () = "%s__pendingManagerPublicKey"
9494
9595
9696 func pl () = "%s%s__price__last"
9797
9898
9999 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
100100
101101
102102 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
103103
104104
105105 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
106106
107107
108108 func aa () = "%s__amountAsset"
109109
110110
111111 func pa () = "%s__priceAsset"
112112
113113
114114 let keyFee = "%s__fee"
115115
116116 let feeDefault = fraction(10, scale8, 10000)
117117
118118 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
119119
120120 let keyKLp = makeString(["%s", "kLp"], SEP)
121121
122122 let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
123123
124124 let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
125125
126126 let kLpRefreshDelayDefault = 30
127127
128128 let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
129129
130130 func keyFactoryConfig () = "%s__factoryConfig"
131131
132132
133133 func keyMatcherPub () = "%s%s__matcher__publicKey"
134134
135135
136136 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
137137
138138
139139 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
140140
141141
142142 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
143143
144144
145145 func keyAllPoolsShutdown () = "%s__shutdown"
146146
147147
148148 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
149149
150150
151151 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
152152
153153
154154 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
155155
156156 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
157157
158158
159159 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
160160
161161
162162 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
163163
164164
165165 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
166166
167167
168168 func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
169169
170170
171171 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
172172
173173 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
174174
175175 let inFee = {
176176 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
177177 if ($isInstanceOf(@, "Int"))
178178 then @
179179 else throw(($getType(@) + " couldn't be cast to Int"))
180180 }
181181
182182 let outFee = {
183183 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
184184 if ($isInstanceOf(@, "Int"))
185185 then @
186186 else throw(($getType(@) + " couldn't be cast to Int"))
187187 }
188188
189189 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
190190
191191
192192 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
193193
194194
195195 func getPoolConfig () = {
196196 let amtAsset = getStringOrFail(this, aa())
197197 let priceAsset = getStringOrFail(this, pa())
198198 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
199199 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
200200 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
201201 }
202202
203203
204204 func parseAssetId (input) = if ((input == wavesString))
205205 then unit
206206 else fromBase58String(input)
207207
208208
209209 func assetIdToString (input) = if ((input == unit))
210210 then wavesString
211211 else toBase58String(value(input))
212212
213213
214214 func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
215215
216216
217217 let poolConfigParsed = parsePoolConfig(getPoolConfig())
218218
219219 let $t084088574 = poolConfigParsed
220220
221221 let cfgPoolAddress = $t084088574._1
222222
223223 let cfgPoolStatus = $t084088574._2
224224
225225 let cfgLpAssetId = $t084088574._3
226226
227227 let cfgAmountAssetId = $t084088574._4
228228
229229 let cfgPriceAssetId = $t084088574._5
230230
231231 let cfgAmountAssetDecimals = $t084088574._6
232232
233233 let cfgPriceAssetDecimals = $t084088574._7
234234
235235 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
236236
237237
238238 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
239239
240240 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
241241
242242 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
243243
244244
245245 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
246246
247247
248248 func getAccBalance (assetId) = if ((assetId == "WAVES"))
249249 then wavesBalance(this).available
250250 else assetBalance(this, fromBase58String(assetId))
251251
252252
253253 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
254254
255255
256256 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
257257
258258
259259 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
260260 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
261261 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
262262 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
263263 }
264264
265265
266266 func calcPrices (amAmt,prAmt,lpAmt) = {
267267 let cfg = getPoolConfig()
268268 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
269269 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
270270 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
271271 let amAmtX18 = toX18(amAmt, amtAssetDcm)
272272 let prAmtX18 = toX18(prAmt, priceAssetDcm)
273273 let lpAmtX18 = toX18(lpAmt, scale8)
274274 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
275275 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
276276 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
277277 }
278278
279279
280280 func calculatePrices (amAmt,prAmt,lpAmt) = {
281281 let prices = calcPrices(amAmt, prAmt, lpAmt)
282282 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
283283 }
284284
285285
286286 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
287287 let cfg = getPoolConfig()
288288 let lpAssetId = cfg[idxPoolLPAssetId]
289289 let amAssetId = cfg[idxAmtAssetId]
290290 let prAssetId = cfg[idxPriceAssetId]
291291 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
292292 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
293293 let poolStatus = cfg[idxPoolStatus]
294294 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
295295 if ((lpAssetId != pmtAssetId))
296296 then throw("Invalid asset passed.")
297297 else {
298298 let amBalance = getAccBalance(amAssetId)
299299 let amBalanceX18 = toX18(amBalance, amAssetDcm)
300300 let prBalance = getAccBalance(prAssetId)
301301 let prBalanceX18 = toX18(prBalance, prAssetDcm)
302302 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
303303 let curPrice = fromX18(curPriceX18, scale8)
304304 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
305305 let lpEmissionX18 = toX18(lpEmission, scale8)
306306 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
307307 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
308308 let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
309309 let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
310310 let state = if ((txId58 == ""))
311311 then nil
312312 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
313313 then unit
314314 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
315315 then unit
316316 else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
317317 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
318318 }
319319 }
320320
321321
322322 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
323323 let cfg = getPoolConfig()
324324 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
325325 let amAssetIdStr = cfg[idxAmtAssetId]
326326 let prAssetIdStr = cfg[idxPriceAssetId]
327327 let iAmtAssetId = cfg[idxIAmtAssetId]
328328 let iPriceAssetId = cfg[idxIPriceAssetId]
329329 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
330330 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
331331 let poolStatus = cfg[idxPoolStatus]
332332 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
333333 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
334334 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
335335 if (if ((amAssetIdStr != inAmAssetIdStr))
336336 then true
337337 else (prAssetIdStr != inPrAssetIdStr))
338338 then throw("Invalid amt or price asset passed.")
339339 else {
340340 let amBalance = if (isEvaluate)
341341 then getAccBalance(amAssetIdStr)
342342 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
343343 let prBalance = if (isEvaluate)
344344 then getAccBalance(prAssetIdStr)
345345 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
346346 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
347347 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
348348 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
349349 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
350350 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
351351 let res = if ((lpEmission == 0))
352352 then {
353353 let curPriceX18 = zeroBigInt
354354 let slippageX18 = zeroBigInt
355355 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
356356 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
357357 }
358358 else {
359359 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
360360 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
361361 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
362362 if (if ((curPriceX18 != zeroBigInt))
363363 then (slippageX18 > slippageToleranceX18)
364364 else false)
365365 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
366366 else {
367367 let lpEmissionX18 = toX18(lpEmission, scale8)
368368 let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
369369 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
370370 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
371371 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
372372 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
373373 let expAmtAssetAmtX18 = expectedAmts._1
374374 let expPriceAssetAmtX18 = expectedAmts._2
375375 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
376376 $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
377377 }
378378 }
379379 let calcLpAmt = res._1
380380 let calcAmAssetPmt = res._2
381381 let calcPrAssetPmt = res._3
382382 let curPrice = fromX18(res._4, scale8)
383383 let slippageCalc = fromX18(res._5, scale8)
384384 if ((0 >= calcLpAmt))
385385 then throw("Invalid calculations. LP calculated is less than zero.")
386386 else {
387387 let emitLpAmt = if (!(emitLp))
388388 then 0
389389 else calcLpAmt
390390 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
391391 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
392392 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
393393 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
394394 }
395395 }
396396 }
397397
398398
399399 func calcKLp (amountBalance,priceBalance,lpEmission) = {
400400 let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
401401 let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
402402 let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
403403 if ((lpEmission == big0))
404404 then big0
405405 else updatedKLp
406406 }
407407
408408
409409 func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
410410 let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
411411 let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
412412 let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
413413 let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
414414 currentKLp
415415 }
416416
417417
418418 func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
419419 let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
420420 let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
421421 let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
422422 let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
423423 let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
424424 $Tuple2(actions, updatedKLp)
425425 }
426426
427427
428428 func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
429429 then true
430430 else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
431431
432432
433433 func validateMatcherOrderAllowed (order) = {
434434 let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
435435 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
436436 let amountAssetAmount = order.amount
437437 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
438438 let $t02148021692 = if ((order.orderType == Buy))
439439 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
440440 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
441441 let amountAssetBalanceDelta = $t02148021692._1
442442 let priceAssetBalanceDelta = $t02148021692._2
443443 if (if (if (isGlobalShutdown())
444444 then true
445445 else (cfgPoolStatus == PoolMatcherDisabled))
446446 then true
447447 else (cfgPoolStatus == PoolShutdown))
448448 then throw("Exchange operations disabled")
449449 else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
450450 then true
451451 else (order.assetPair.priceAsset != cfgPriceAssetId))
452452 then throw("Wrong order assets.")
453453 else {
454454 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
455455 let $t02213222232 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
456456 let unusedActions = $t02213222232._1
457457 let kLpNew = $t02213222232._2
458458 let isOrderValid = (kLpNew >= kLp)
459459 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
460460 $Tuple2(isOrderValid, info)
461461 }
462462 }
463463
464464
465465 func commonGet (i) = if ((size(i.payments) != 1))
466466 then throw("exactly 1 payment is expected")
467467 else {
468468 let pmt = value(i.payments[0])
469469 let pmtAssetId = value(pmt.assetId)
470470 let pmtAmt = pmt.amount
471471 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
472472 let outAmAmt = res._1
473473 let outPrAmt = res._2
474474 let poolStatus = parseIntValue(res._9)
475475 let state = res._10
476476 if (if (isGlobalShutdown())
477477 then true
478478 else (poolStatus == PoolShutdown))
479479 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
480480 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
481481 }
482482
483483
484484 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
485485 then throw("exactly 2 payments are expected")
486486 else {
487487 let amAssetPmt = value(i.payments[0])
488488 let prAssetPmt = value(i.payments[1])
489489 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
490490 let poolStatus = parseIntValue(estPut._8)
491491 if (if (if (isGlobalShutdown())
492492 then true
493493 else (poolStatus == PoolPutDisabled))
494494 then true
495495 else (poolStatus == PoolShutdown))
496496 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
497497 else estPut
498498 }
499499
500500
501501 func emit (amount) = {
502502 let emitInv = invoke(factoryContract, "emit", [amount], nil)
503503 if ((emitInv == emitInv))
504504 then {
505505 let emitInvLegacy = match emitInv {
506506 case legacyFactoryContract: Address =>
507507 invoke(legacyFactoryContract, "emit", [amount], nil)
508508 case _ =>
509509 unit
510510 }
511511 if ((emitInvLegacy == emitInvLegacy))
512512 then amount
513513 else throw("Strict value is not equal to itself.")
514514 }
515515 else throw("Strict value is not equal to itself.")
516516 }
517517
518518
519519 func takeFee (amount,fee) = {
520520 let feeAmount = if ((fee == 0))
521521 then 0
522522 else fraction(amount, fee, scale8)
523523 $Tuple2((amount - feeAmount), feeAmount)
524524 }
525525
526526
527527 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
528528 let isEval = (txId == unit)
529529 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
530530 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
531531 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
532532 then true
533533 else if ((paymentAssetId == cfgPriceAssetId))
534534 then false
535535 else throwErr("invalid asset")
536536 let $t02534525638 = if (isEval)
537537 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
538538 else if (paymentInAmountAsset)
539539 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
540540 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
541541 let amountBalanceOld = $t02534525638._1
542542 let priceBalanceOld = $t02534525638._2
543543 let $t02564225791 = if (paymentInAmountAsset)
544544 then $Tuple2(paymentAmountRaw, 0)
545545 else $Tuple2(0, paymentAmountRaw)
546546 let amountAssetAmountRaw = $t02564225791._1
547547 let priceAssetAmountRaw = $t02564225791._2
548548 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
549549 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
550550 let $t02592325987 = takeFee(paymentAmountRaw, inFee)
551551 let paymentAmount = $t02592325987._1
552552 let feeAmount = $t02592325987._2
553553 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
554554 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
555555 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
556556 let priceNew = fromX18(priceNewX18, scale8)
557557 let paymentBalance = if (paymentInAmountAsset)
558558 then amountBalanceOld
559559 else priceBalanceOld
560560 let paymentBalanceBigInt = toBigInt(paymentBalance)
561561 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
562562 let chechSupply = if ((supplyBigInt > big0))
563563 then true
564564 else throwErr("initial deposit requires all coins")
565565 if ((chechSupply == chechSupply))
566566 then {
567567 let depositBigInt = toBigInt(paymentAmount)
568568 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
569569 let commonState = if (isEval)
570570 then nil
571571 else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
572572 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
573573 let priceOld = fromX18(priceOldX18, scale8)
574574 let loss = {
575575 let $t02766827835 = if (paymentInAmountAsset)
576576 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
577577 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
578578 let amount = $t02766827835._1
579579 let balance = $t02766827835._2
580580 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
581581 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
582582 }
583583 $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
584584 }
585585 else throw("Strict value is not equal to itself.")
586586 }
587587
588588
589589 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
590590 let isEval = (txId == unit)
591591 let cfg = getPoolConfig()
592592 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
593593 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
594594 let checks = [if ((paymentAssetId == cfgLpAssetId))
595595 then true
596596 else throwErr("invalid lp asset")]
597597 if ((checks == checks))
598598 then {
599599 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
600600 then true
601601 else if ((outAssetId == cfgPriceAssetId))
602602 then false
603603 else throwErr("invalid asset")
604604 let balanceBigInt = if (outInAmountAsset)
605605 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
606606 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
607607 let outInAmountAssetDecimals = if (outInAmountAsset)
608608 then amtAssetDcm
609609 else priceAssetDcm
610610 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
611611 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
612612 let outBalance = if (outInAmountAsset)
613613 then amBalanceOld
614614 else prBalanceOld
615615 let outBalanceBigInt = toBigInt(outBalance)
616616 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
617617 let redeemedBigInt = toBigInt(paymentAmount)
618618 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
619619 let $t02991329969 = takeFee(amountRaw, outFee)
620620 let totalAmount = $t02991329969._1
621621 let feeAmount = $t02991329969._2
622622 let $t02997330199 = if (outInAmountAsset)
623623 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
624624 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
625625 let outAmAmount = $t02997330199._1
626626 let outPrAmount = $t02997330199._2
627627 let amBalanceNew = $t02997330199._3
628628 let prBalanceNew = $t02997330199._4
629629 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
630630 let priceNew = fromX18(priceNewX18, scale8)
631631 let commonState = if (isEval)
632632 then nil
633633 else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
634634 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
635635 let priceOld = fromX18(priceOldX18, scale8)
636636 let loss = {
637637 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
638638 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
639639 }
640640 $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
641641 }
642642 else throw("Strict value is not equal to itself.")
643643 }
644644
645645
646646 func managerPublicKeyOrUnit () = match getString(mpk()) {
647647 case s: String =>
648648 fromBase58String(s)
649649 case _: Unit =>
650650 unit
651651 case _ =>
652652 throw("Match error")
653653 }
654654
655655
656656 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
657657 case s: String =>
658658 fromBase58String(s)
659659 case _: Unit =>
660660 unit
661661 case _ =>
662662 throw("Match error")
663663 }
664664
665665
666666 func isManager (i) = match managerPublicKeyOrUnit() {
667667 case pk: ByteVector =>
668668 (i.callerPublicKey == pk)
669669 case _: Unit =>
670670 (i.caller == this)
671671 case _ =>
672672 throw("Match error")
673673 }
674674
675675
676676 func mustManager (i) = {
677677 let pd = throw("Permission denied")
678678 match managerPublicKeyOrUnit() {
679679 case pk: ByteVector =>
680680 if ((i.callerPublicKey == pk))
681681 then true
682682 else pd
683683 case _: Unit =>
684684 if ((i.caller == this))
685685 then true
686686 else pd
687687 case _ =>
688688 throw("Match error")
689689 }
690690 }
691691
692692
693693 @Callable(i)
694694 func setManager (pendingManagerPublicKey) = {
695695 let checkCaller = mustManager(i)
696696 if ((checkCaller == checkCaller))
697697 then {
698698 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
699699 if ((checkManagerPublicKey == checkManagerPublicKey))
700700 then [StringEntry(pmpk(), pendingManagerPublicKey)]
701701 else throw("Strict value is not equal to itself.")
702702 }
703703 else throw("Strict value is not equal to itself.")
704704 }
705705
706706
707707
708708 @Callable(i)
709709 func confirmManager () = {
710710 let pm = pendingManagerPublicKeyOrUnit()
711711 let hasPM = if (isDefined(pm))
712712 then true
713713 else throw("No pending manager")
714714 if ((hasPM == hasPM))
715715 then {
716716 let checkPM = if ((i.callerPublicKey == value(pm)))
717717 then true
718718 else throw("You are not pending manager")
719719 if ((checkPM == checkPM))
720720 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
721721 else throw("Strict value is not equal to itself.")
722722 }
723723 else throw("Strict value is not equal to itself.")
724724 }
725725
726726
727727
728728 @Callable(i)
729729 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
730730 then throw("Invalid slippageTolerance passed")
731731 else {
732732 let estPut = commonPut(i, slippageTolerance, true)
733733 let emitLpAmt = estPut._2
734734 let lpAssetId = estPut._7
735735 let state = estPut._9
736736 let amDiff = estPut._10
737737 let prDiff = estPut._11
738738 let amId = estPut._12
739739 let prId = estPut._13
740740 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
741741 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
742742 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
743743 if ((currentKLp == currentKLp))
744744 then {
745745 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
746746 if ((emitInv == emitInv))
747747 then {
748748 let emitInvLegacy = match emitInv {
749749 case legacyFactoryContract: Address =>
750750 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
751751 case _ =>
752752 unit
753753 }
754754 if ((emitInvLegacy == emitInvLegacy))
755755 then {
756756 let slippageAInv = if ((amDiff > 0))
757757 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
758758 else nil
759759 if ((slippageAInv == slippageAInv))
760760 then {
761761 let slippagePInv = if ((prDiff > 0))
762762 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
763763 else nil
764764 if ((slippagePInv == slippagePInv))
765765 then {
766766 let lpTransfer = if (shouldAutoStake)
767767 then {
768768 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
769769 if ((slpStakeInv == slpStakeInv))
770770 then nil
771771 else throw("Strict value is not equal to itself.")
772772 }
773773 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
774774 let $t03472735189 = refreshKLpInternal(0, 0, 0)
775775 if (($t03472735189 == $t03472735189))
776776 then {
777777 let updatedKLp = $t03472735189._2
778778 let refreshKLpActions = $t03472735189._1
779779 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
780780 if ((isUpdatedKLpValid == isUpdatedKLpValid))
781781 then ((state ++ lpTransfer) ++ refreshKLpActions)
782782 else throw("Strict value is not equal to itself.")
783783 }
784784 else throw("Strict value is not equal to itself.")
785785 }
786786 else throw("Strict value is not equal to itself.")
787787 }
788788 else throw("Strict value is not equal to itself.")
789789 }
790790 else throw("Strict value is not equal to itself.")
791791 }
792792 else throw("Strict value is not equal to itself.")
793793 }
794794 else throw("Strict value is not equal to itself.")
795795 }
796796
797797
798798
799799 @Callable(i)
800800 func putForFree (maxSlippage) = if ((0 > maxSlippage))
801801 then throw("Invalid value passed")
802802 else {
803803 let estPut = commonPut(i, maxSlippage, false)
804804 let state = estPut._9
805805 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
806806 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
807807 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
808808 if ((currentKLp == currentKLp))
809809 then {
810810 let $t03575135816 = refreshKLpInternal(0, 0, 0)
811811 let refreshKLpActions = $t03575135816._1
812812 let updatedKLp = $t03575135816._2
813813 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
814814 if ((isUpdatedKLpValid == isUpdatedKLpValid))
815815 then (state ++ refreshKLpActions)
816816 else throw("Strict value is not equal to itself.")
817817 }
818818 else throw("Strict value is not equal to itself.")
819819 }
820820
821821
822822
823823 @Callable(i)
824824 func putOneTkn (minOutAmount,autoStake) = {
825825 let isPoolOneTokenOperationsDisabled = {
826826 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
827827 if ($isInstanceOf(@, "Boolean"))
828828 then @
829829 else throw(($getType(@) + " couldn't be cast to Boolean"))
830830 }
831831 let isPutDisabled = if (if (if (isGlobalShutdown())
832832 then true
833833 else (cfgPoolStatus == PoolPutDisabled))
834834 then true
835835 else (cfgPoolStatus == PoolShutdown))
836836 then true
837837 else isPoolOneTokenOperationsDisabled
838838 let checks = [if (if (!(isPutDisabled))
839839 then true
840840 else isManager(i))
841841 then true
842842 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
843843 then true
844844 else throwErr("exactly 1 payment are expected")]
845845 if ((checks == checks))
846846 then {
847847 let payment = i.payments[0]
848848 let paymentAssetId = payment.assetId
849849 let paymentAmountRaw = payment.amount
850850 let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
851851 then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
852852 else if ((paymentAssetId == cfgPriceAssetId))
853853 then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
854854 else throwErr("payment asset is not supported")
855855 if ((currentKLp == currentKLp))
856856 then {
857857 let userAddress = i.caller
858858 let txId = i.transactionId
859859 let $t03700437156 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
860860 if (($t03700437156 == $t03700437156))
861861 then {
862862 let paymentInAmountAsset = $t03700437156._5
863863 let bonus = $t03700437156._4
864864 let feeAmount = $t03700437156._3
865865 let commonState = $t03700437156._2
866866 let emitAmountEstimated = $t03700437156._1
867867 let emitAmount = if (if ((minOutAmount > 0))
868868 then (minOutAmount > emitAmountEstimated)
869869 else false)
870870 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
871871 else emitAmountEstimated
872872 let emitInv = emit(emitAmount)
873873 if ((emitInv == emitInv))
874874 then {
875875 let lpTransfer = if (autoStake)
876876 then {
877877 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
878878 if ((stakeInv == stakeInv))
879879 then nil
880880 else throw("Strict value is not equal to itself.")
881881 }
882882 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
883883 let sendFee = if ((feeAmount > 0))
884884 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
885885 else nil
886886 let $t03774237939 = if ((this == feeCollectorAddress))
887887 then $Tuple2(0, 0)
888888 else if (paymentInAmountAsset)
889889 then $Tuple2(-(feeAmount), 0)
890890 else $Tuple2(0, -(feeAmount))
891891 let amountAssetBalanceDelta = $t03774237939._1
892892 let priceAssetBalanceDelta = $t03774237939._2
893893 let $t03794238050 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
894894 let refreshKLpActions = $t03794238050._1
895895 let updatedKLp = $t03794238050._2
896896 let kLp = value(getString(keyKLp))
897897 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
898898 if ((isUpdatedKLpValid == isUpdatedKLpValid))
899899 then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
900900 else throw("Strict value is not equal to itself.")
901901 }
902902 else throw("Strict value is not equal to itself.")
903903 }
904904 else throw("Strict value is not equal to itself.")
905905 }
906906 else throw("Strict value is not equal to itself.")
907907 }
908908 else throw("Strict value is not equal to itself.")
909909 }
910910
911911
912912
913913 @Callable(i)
914914 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
915915 let $t03835638513 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
916916 let emitAmountEstimated = $t03835638513._1
917917 let commonState = $t03835638513._2
918918 let feeAmount = $t03835638513._3
919919 let bonus = $t03835638513._4
920920 let paymentInAmountAsset = $t03835638513._5
921921 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
922922 }
923923
924924
925925
926926 @Callable(i)
927927 func getOneTkn (outAssetIdStr,minOutAmount) = {
928928 let isPoolOneTokenOperationsDisabled = {
929929 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
930930 if ($isInstanceOf(@, "Boolean"))
931931 then @
932932 else throw(($getType(@) + " couldn't be cast to Boolean"))
933933 }
934934 let isGetDisabled = if (if (isGlobalShutdown())
935935 then true
936936 else (cfgPoolStatus == PoolShutdown))
937937 then true
938938 else isPoolOneTokenOperationsDisabled
939939 let checks = [if (if (!(isGetDisabled))
940940 then true
941941 else isManager(i))
942942 then true
943943 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
944944 then true
945945 else throwErr("exactly 1 payment are expected")]
946946 if ((checks == checks))
947947 then {
948948 let outAssetId = parseAssetId(outAssetIdStr)
949949 let payment = i.payments[0]
950950 let paymentAssetId = payment.assetId
951951 let paymentAmount = payment.amount
952952 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
953953 if ((currentKLp == currentKLp))
954954 then {
955955 let userAddress = i.caller
956956 let txId = i.transactionId
957957 let $t03939839551 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
958958 if (($t03939839551 == $t03939839551))
959959 then {
960960 let outInAmountAsset = $t03939839551._5
961961 let bonus = $t03939839551._4
962962 let feeAmount = $t03939839551._3
963963 let commonState = $t03939839551._2
964964 let amountEstimated = $t03939839551._1
965965 let amount = if (if ((minOutAmount > 0))
966966 then (minOutAmount > amountEstimated)
967967 else false)
968968 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
969969 else amountEstimated
970970 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
971971 if ((burnInv == burnInv))
972972 then {
973973 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
974974 let sendFee = if ((feeAmount > 0))
975975 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
976976 else nil
977977 let $t04005140298 = {
978978 let feeAmountForCalc = if ((this == feeCollectorAddress))
979979 then 0
980980 else feeAmount
981981 if (outInAmountAsset)
982982 then $Tuple2(-((amount + feeAmountForCalc)), 0)
983983 else $Tuple2(0, -((amount + feeAmountForCalc)))
984984 }
985985 let amountAssetBalanceDelta = $t04005140298._1
986986 let priceAssetBalanceDelta = $t04005140298._2
987987 let $t04030140409 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
988988 let refreshKLpActions = $t04030140409._1
989989 let updatedKLp = $t04030140409._2
990990 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
991991 if ((isUpdatedKLpValid == isUpdatedKLpValid))
992992 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
993993 else throw("Strict value is not equal to itself.")
994994 }
995995 else throw("Strict value is not equal to itself.")
996996 }
997997 else throw("Strict value is not equal to itself.")
998998 }
999999 else throw("Strict value is not equal to itself.")
10001000 }
10011001 else throw("Strict value is not equal to itself.")
10021002 }
10031003
10041004
10051005
10061006 @Callable(i)
10071007 func getOneTknREADONLY (outAssetId,paymentAmount) = {
10081008 let $t04066640822 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
10091009 let amountEstimated = $t04066640822._1
10101010 let commonState = $t04066640822._2
10111011 let feeAmount = $t04066640822._3
10121012 let bonus = $t04066640822._4
10131013 let outInAmountAsset = $t04066640822._5
10141014 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10151015 }
10161016
10171017
10181018
10191019 @Callable(i)
10201020 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
10211021 let isPoolOneTokenOperationsDisabled = {
10221022 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
10231023 if ($isInstanceOf(@, "Boolean"))
10241024 then @
10251025 else throw(($getType(@) + " couldn't be cast to Boolean"))
10261026 }
10271027 let isGetDisabled = if (if (isGlobalShutdown())
10281028 then true
10291029 else (cfgPoolStatus == PoolShutdown))
10301030 then true
10311031 else isPoolOneTokenOperationsDisabled
10321032 let checks = [if (if (!(isGetDisabled))
10331033 then true
10341034 else isManager(i))
10351035 then true
10361036 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
10371037 then true
10381038 else throwErr("no payments are expected")]
10391039 if ((checks == checks))
10401040 then {
10411041 let outAssetId = parseAssetId(outAssetIdStr)
10421042 let userAddress = i.caller
10431043 let txId = i.transactionId
10441044 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
10451045 if ((currentKLp == currentKLp))
10461046 then {
10471047 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10481048 if ((unstakeInv == unstakeInv))
10491049 then {
10501050 let $t04172741878 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
10511051 if (($t04172741878 == $t04172741878))
10521052 then {
10531053 let outInAmountAsset = $t04172741878._5
10541054 let bonus = $t04172741878._4
10551055 let feeAmount = $t04172741878._3
10561056 let commonState = $t04172741878._2
10571057 let amountEstimated = $t04172741878._1
10581058 let amount = if (if ((minOutAmount > 0))
10591059 then (minOutAmount > amountEstimated)
10601060 else false)
10611061 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
10621062 else amountEstimated
10631063 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10641064 if ((burnInv == burnInv))
10651065 then {
10661066 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10671067 let sendFee = if ((feeAmount > 0))
10681068 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10691069 else nil
10701070 let $t04237342620 = {
10711071 let feeAmountForCalc = if ((this == feeCollectorAddress))
10721072 then 0
10731073 else feeAmount
10741074 if (outInAmountAsset)
10751075 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10761076 else $Tuple2(0, -((amount + feeAmountForCalc)))
10771077 }
10781078 let amountAssetBalanceDelta = $t04237342620._1
10791079 let priceAssetBalanceDelta = $t04237342620._2
10801080 let $t04262342731 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
10811081 let refreshKLpActions = $t04262342731._1
10821082 let updatedKLp = $t04262342731._2
10831083 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10841084 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10851085 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10861086 else throw("Strict value is not equal to itself.")
10871087 }
10881088 else throw("Strict value is not equal to itself.")
10891089 }
10901090 else throw("Strict value is not equal to itself.")
10911091 }
10921092 else throw("Strict value is not equal to itself.")
10931093 }
10941094 else throw("Strict value is not equal to itself.")
10951095 }
10961096 else throw("Strict value is not equal to itself.")
10971097 }
10981098
10991099
11001100
11011101 @Callable(i)
11021102 func get () = {
11031103 let res = commonGet(i)
11041104 let outAmtAmt = res._1
11051105 let outPrAmt = res._2
11061106 let pmtAmt = res._3
11071107 let pmtAssetId = res._4
11081108 let state = res._5
11091109 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11101110 if ((currentKLp == currentKLp))
11111111 then {
11121112 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11131113 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11141114 then {
11151115 let $t04367743759 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
11161116 let refreshKLpActions = $t04367743759._1
11171117 let updatedKLp = $t04367743759._2
11181118 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11191119 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11201120 then (state ++ refreshKLpActions)
11211121 else throw("Strict value is not equal to itself.")
11221122 }
11231123 else throw("Strict value is not equal to itself.")
11241124 }
11251125 else throw("Strict value is not equal to itself.")
11261126 }
11271127
11281128
11291129
11301130 @Callable(i)
11311131 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
11321132 let res = commonGet(i)
11331133 let outAmAmt = res._1
11341134 let outPrAmt = res._2
11351135 let pmtAmt = res._3
11361136 let pmtAssetId = res._4
11371137 let state = res._5
11381138 if ((noLessThenAmtAsset > outAmAmt))
11391139 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
11401140 else if ((noLessThenPriceAsset > outPrAmt))
11411141 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
11421142 else {
11431143 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11441144 if ((currentKLp == currentKLp))
11451145 then {
11461146 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11471147 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11481148 then {
11491149 let $t04470844789 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
11501150 let refreshKLpActions = $t04470844789._1
11511151 let updatedKLp = $t04470844789._2
11521152 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11531153 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11541154 then (state ++ refreshKLpActions)
11551155 else throw("Strict value is not equal to itself.")
11561156 }
11571157 else throw("Strict value is not equal to itself.")
11581158 }
11591159 else throw("Strict value is not equal to itself.")
11601160 }
11611161 }
11621162
11631163
11641164
11651165 @Callable(i)
11661166 func unstakeAndGet (amount) = {
11671167 let checkPayments = if ((size(i.payments) != 0))
11681168 then throw("No payments are expected")
11691169 else true
11701170 if ((checkPayments == checkPayments))
11711171 then {
11721172 let cfg = getPoolConfig()
11731173 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11741174 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11751175 if ((currentKLp == currentKLp))
11761176 then {
11771177 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
11781178 if ((unstakeInv == unstakeInv))
11791179 then {
11801180 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
11811181 let outAmAmt = res._1
11821182 let outPrAmt = res._2
11831183 let poolStatus = parseIntValue(res._9)
11841184 let state = res._10
11851185 let checkPoolStatus = if (if (isGlobalShutdown())
11861186 then true
11871187 else (poolStatus == PoolShutdown))
11881188 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
11891189 else true
11901190 if ((checkPoolStatus == checkPoolStatus))
11911191 then {
11921192 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
11931193 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11941194 then {
11951195 let $t04591545996 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
11961196 let refreshKLpActions = $t04591545996._1
11971197 let updatedKLp = $t04591545996._2
11981198 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11991199 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001200 then (state ++ refreshKLpActions)
12011201 else throw("Strict value is not equal to itself.")
12021202 }
12031203 else throw("Strict value is not equal to itself.")
12041204 }
12051205 else throw("Strict value is not equal to itself.")
12061206 }
12071207 else throw("Strict value is not equal to itself.")
12081208 }
12091209 else throw("Strict value is not equal to itself.")
12101210 }
12111211 else throw("Strict value is not equal to itself.")
12121212 }
12131213
12141214
12151215
12161216 @Callable(i)
12171217 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
12181218 let isGetDisabled = if (isGlobalShutdown())
12191219 then true
12201220 else (cfgPoolStatus == PoolShutdown)
12211221 let checks = [if (!(isGetDisabled))
12221222 then true
12231223 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
12241224 then true
12251225 else throw("no payments are expected")]
12261226 if ((checks == checks))
12271227 then {
12281228 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12291229 if ((currentKLp == currentKLp))
12301230 then {
12311231 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
12321232 if ((unstakeInv == unstakeInv))
12331233 then {
12341234 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
12351235 let outAmAmt = res._1
12361236 let outPrAmt = res._2
12371237 let state = res._10
12381238 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
12391239 then true
12401240 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
12411241 then true
12421242 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
12431243 if ((checkAmounts == checkAmounts))
12441244 then {
12451245 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
12461246 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12471247 then {
12481248 let $t04729147372 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
12491249 let refreshKLpActions = $t04729147372._1
12501250 let updatedKLp = $t04729147372._2
12511251 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12521252 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12531253 then (state ++ refreshKLpActions)
12541254 else throw("Strict value is not equal to itself.")
12551255 }
12561256 else throw("Strict value is not equal to itself.")
12571257 }
12581258 else throw("Strict value is not equal to itself.")
12591259 }
12601260 else throw("Strict value is not equal to itself.")
12611261 }
12621262 else throw("Strict value is not equal to itself.")
12631263 }
12641264 else throw("Strict value is not equal to itself.")
12651265 }
12661266
12671267
12681268
12691269 @Callable(i)
12701270 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
12711271 then throw("permissions denied")
12721272 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
12731273
12741274
12751275
12761276 @Callable(i)
12771277 func refreshKLp () = {
12781278 let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
12791279 let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
12801280 then unit
12811281 else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
12821282 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
12831283 then {
12841284 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
12851285 let $t04855948623 = refreshKLpInternal(0, 0, 0)
12861286 let kLpUpdateActions = $t04855948623._1
12871287 let updatedKLp = $t04855948623._2
12881288 let actions = if ((kLp != updatedKLp))
12891289 then kLpUpdateActions
12901290 else throwErr("nothing to refresh")
12911291 $Tuple2(actions, toString(updatedKLp))
12921292 }
12931293 else throw("Strict value is not equal to itself.")
12941294 }
12951295
12961296
12971297
12981298 @Callable(i)
12991299 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
13001300
13011301
13021302
13031303 @Callable(i)
13041304 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
13051305
13061306
13071307
13081308 @Callable(i)
13091309 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
13101310 let prices = calcPrices(amAmt, prAmt, lpAmt)
13111311 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
13121312 }
13131313
13141314
13151315
13161316 @Callable(i)
13171317 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
13181318
13191319
13201320
13211321 @Callable(i)
13221322 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
13231323
13241324
13251325
13261326 @Callable(i)
13271327 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
13281328
13291329
13301330
13311331 @Callable(i)
13321332 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
13331333
13341334
13351335
13361336 @Callable(i)
13371337 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
13381338 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
13391339 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
13401340 }
13411341
13421342
13431343
13441344 @Callable(i)
13451345 func statsREADONLY () = {
13461346 let cfg = getPoolConfig()
13471347 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13481348 let amtAssetId = cfg[idxAmtAssetId]
13491349 let priceAssetId = cfg[idxPriceAssetId]
13501350 let iAmtAssetId = cfg[idxIAmtAssetId]
13511351 let iPriceAssetId = cfg[idxIPriceAssetId]
13521352 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13531353 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13541354 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13551355 let accAmtAssetBalance = getAccBalance(amtAssetId)
13561356 let accPriceAssetBalance = getAccBalance(priceAssetId)
13571357 let pricesList = if ((poolLPBalance == 0))
13581358 then [zeroBigInt, zeroBigInt, zeroBigInt]
13591359 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
13601360 let curPrice = 0
13611361 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
13621362 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
13631363 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
13641364 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
13651365 }
13661366
13671367
13681368
13691369 @Callable(i)
13701370 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
13711371 let cfg = getPoolConfig()
13721372 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13731373 let amAssetIdStr = cfg[idxAmtAssetId]
13741374 let amAssetId = fromBase58String(amAssetIdStr)
13751375 let prAssetIdStr = cfg[idxPriceAssetId]
13761376 let prAssetId = fromBase58String(prAssetIdStr)
13771377 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13781378 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13791379 let poolStatus = cfg[idxPoolStatus]
13801380 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13811381 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
13821382 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
13831383 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
13841384 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
13851385 let curPriceX18 = if ((poolLPBalance == 0))
13861386 then zeroBigInt
13871387 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
13881388 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
13891389 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
13901390 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
13911391 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
13921392 let calcLpAmt = estPut._1
13931393 let curPriceCalc = estPut._3
13941394 let amBalance = estPut._4
13951395 let prBalance = estPut._5
13961396 let lpEmission = estPut._6
13971397 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
13981398 }
13991399
14001400
14011401
14021402 @Callable(i)
14031403 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
14041404 let cfg = getPoolConfig()
14051405 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14061406 let amAssetIdStr = cfg[idxAmtAssetId]
14071407 let amAssetId = fromBase58String(amAssetIdStr)
14081408 let prAssetIdStr = cfg[idxPriceAssetId]
14091409 let prAssetId = fromBase58String(prAssetIdStr)
14101410 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14111411 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14121412 let poolStatus = cfg[idxPoolStatus]
14131413 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14141414 let amBalanceRaw = getAccBalance(amAssetIdStr)
14151415 let prBalanceRaw = getAccBalance(prAssetIdStr)
14161416 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
14171417 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
14181418 let curPriceX18 = if ((poolLPBalance == 0))
14191419 then zeroBigInt
14201420 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
14211421 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
14221422 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
14231423 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
14241424 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
14251425 let calcLpAmt = estPut._1
14261426 let curPriceCalc = estPut._3
14271427 let amBalance = estPut._4
14281428 let prBalance = estPut._5
14291429 let lpEmission = estPut._6
14301430 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
14311431 }
14321432
14331433
14341434
14351435 @Callable(i)
14361436 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
14371437 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
14381438 let outAmAmt = res._1
14391439 let outPrAmt = res._2
14401440 let amBalance = res._5
14411441 let prBalance = res._6
14421442 let lpEmission = res._7
14431443 let curPrice = res._8
14441444 let poolStatus = parseIntValue(res._9)
14451445 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
14461446 }
14471447
14481448
14491449 @Verifier(tx)
14501450 func verify () = {
14511451 let targetPublicKey = match managerPublicKeyOrUnit() {
14521452 case pk: ByteVector =>
14531453 pk
14541454 case _: Unit =>
14551455 tx.senderPublicKey
14561456 case _ =>
14571457 throw("Match error")
14581458 }
14591459 match tx {
14601460 case order: Order =>
14611461 let matcherPub = getMatcherPubOrFail()
14621462 let $t05728557354 = validateMatcherOrderAllowed(order)
14631463 let orderValid = $t05728557354._1
14641464 let orderValidInfo = $t05728557354._2
14651465 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
14661466 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
14671467 if (if (if (orderValid)
14681468 then senderValid
14691469 else false)
14701470 then matcherValid
14711471 else false)
14721472 then true
14731473 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
14741474 case s: SetScriptTransaction =>
1475- let newHash = blake2b256(value(s.script))
1476- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1477- let currentHash = scriptHash(this)
1478- if (if ((allowedHash == newHash))
1479- then (currentHash != newHash)
1480- else false)
1475+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
14811476 then true
1482- else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1477+ else {
1478+ let newHash = blake2b256(value(s.script))
1479+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1480+ let currentHash = scriptHash(this)
1481+ if ((allowedHash == newHash))
1482+ then (currentHash != newHash)
1483+ else false
1484+ }
14831485 case _ =>
14841486 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
14851487 }
14861488 }
14871489

github/deemru/w8io/786bc32 
125.58 ms