{ "name": "MedRailConsent", "structs": { "AuditEntry": [ { "name": "ts", "type": "uint64" }, { "name": "requester", "type": "address" }, { "name": "scope", "type": "string" }, { "name": "endpoint", "type": "string" }, { "name": "action", "type": "string" } ], "GrantRecord": [ { "name": "status", "type": "uint8" }, { "name": "granted_at", "type": "uint64" }, { "name": "expires_at", "type": "uint64" } ] }, "methods": [ { "name": "create", "args": [], "returns": { "type": "void" }, "actions": { "create": [ "NoOp" ], "call": [] }, "readonly": false, "desc": "Deployer becomes the initial admin (the MedRail backend operator account).", "events": [], "recommendations": {} }, { "name": "set_admin", "args": [ { "type": "address", "name": "new_admin" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Rotate the backend operator key without redeploying the contract.", "events": [], "recommendations": {} }, { "name": "fund_mbr", "args": [ { "type": "pay", "name": "payment" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Top up the app account's own balance so it can cover box MBR itself.\nCallable by anyone (typically the admin at setup time, or periodically as more grants/audit entries accumulate). Boxes are owned by the app account, not by callers, so the app must carry enough balance to create them; this keeps every other method's signature simple.", "events": [], "recommendations": {} }, { "name": "request_access", "args": [ { "type": "address", "name": "patient" }, { "type": "string", "name": "scope" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Requester signals interest in a scope. No state is persisted for this \u2014\nit is a notification event only; the patient's `grant_access` call is the first thing that actually costs box MBR and becomes queryable state.", "events": [ { "name": "AccessRequested", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ] } ], "recommendations": {} }, { "name": "grant_access", "args": [ { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" }, { "type": "uint64", "name": "duration_seconds" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Txn.sender is the patient. duration_seconds == 0 means no expiry.", "events": [ { "name": "AccessGranted", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" }, { "type": "uint64", "name": "expires_at" } ] } ], "recommendations": {} }, { "name": "revoke_access", "args": [ { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Txn.sender is the patient.", "events": [ { "name": "AccessRevoked", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ] } ], "recommendations": {} }, { "name": "check_access", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ], "returns": { "type": "bool" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": true, "desc": "True iff a currently-valid (granted, unexpired, unrevoked) consent exists.", "events": [], "recommendations": {} }, { "name": "get_grant", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ], "returns": { "type": "(uint8,uint64,uint64)", "struct": "GrantRecord" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": true, "events": [], "recommendations": {} }, { "name": "log_access", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" }, { "type": "string", "name": "endpoint" }, { "type": "string", "name": "action" } ], "returns": { "type": "uint64" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Admin-only. Appends one immutable audit entry for `patient` and returns its\nsequence number. Called by the MedRail backend right after the x402 facilitator confirms settlement for a call touching that patient.", "events": [], "recommendations": {} }, { "name": "get_audit_count", "args": [ { "type": "address", "name": "patient" } ], "returns": { "type": "uint64" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": true, "events": [], "recommendations": {} }, { "name": "get_audit_entry", "args": [ { "type": "address", "name": "patient" }, { "type": "uint64", "name": "seq" } ], "returns": { "type": "(uint64,address,string,string,string)", "struct": "AuditEntry" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": true, "events": [], "recommendations": {} }, { "name": "get_grant_box_mbr", "args": [], "returns": { "type": "uint64" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": true, "desc": "Minimum balance a single grant box locks up \u2014 a compile-time constant\nthe backend can quote when sizing `fund_mbr` calls, without hard-coding it.", "events": [], "recommendations": {} }, { "name": "withdraw_excess", "args": [ { "type": "uint64", "name": "amount" } ], "returns": { "type": "void" }, "actions": { "create": [], "call": [ "NoOp" ] }, "readonly": false, "desc": "Admin-only escape hatch to reclaim ALGO over the app's MBR requirement\n(e.g. if it was overfunded via `fund_mbr`). Never touches box contents.", "events": [], "recommendations": {} } ], "arcs": [ 22, 28 ], "networks": {}, "state": { "schema": { "global": { "ints": 4, "bytes": 1 }, "local": { "ints": 0, "bytes": 0 } }, "keys": { "global": { "admin": { "keyType": "AVMString", "valueType": "address", "key": "YWRtaW4=" }, "total_requests": { "keyType": "AVMString", "valueType": "AVMUint64", "key": "dG90YWxfcmVxdWVzdHM=" }, "total_grants_active": { "keyType": "AVMString", "valueType": "AVMUint64", "key": "dG90YWxfZ3JhbnRzX2FjdGl2ZQ==" }, "total_revocations": { "keyType": "AVMString", "valueType": "AVMUint64", "key": "dG90YWxfcmV2b2NhdGlvbnM=" }, "total_audit_entries": { "keyType": "AVMString", "valueType": "AVMUint64", "key": "dG90YWxfYXVkaXRfZW50cmllcw==" } }, "local": {}, "box": {} }, "maps": { "global": {}, "local": {}, "box": { "grants": { "keyType": "AVMBytes", "valueType": "GrantRecord", "prefix": "Zw==" }, "audit_seq": { "keyType": "address", "valueType": "uint64", "prefix": "cw==" }, "audit_log": { "keyType": "AVMBytes", "valueType": "AuditEntry", "prefix": "YQ==" } } } }, "bareActions": { "create": [], "call": [] }, "sourceInfo": { "approval": { "sourceInfo": [ { "pc": [ 271, 847, 1031 ], "errorMessage": "check self.admin exists" }, { "pc": [ 932 ], "errorMessage": "check self.total_audit_entries exists" }, { "pc": [ 461, 582 ], "errorMessage": "check self.total_grants_active exists" }, { "pc": [ 322 ], "errorMessage": "check self.total_requests exists" }, { "pc": [ 592 ], "errorMessage": "check self.total_revocations exists" }, { "pc": [ 310, 369, 517, 641, 739, 799, 817, 835 ], "errorMessage": "invalid array length header" }, { "pc": [ 317, 376, 524, 648, 746, 808, 826, 841 ], "errorMessage": "invalid number of bytes for arc4.dynamic_array" }, { "pc": [ 265, 304, 360, 508, 627, 635, 725, 733, 780, 790, 957, 985 ], "errorMessage": "invalid number of bytes for arc4.static_array" }, { "pc": [ 388, 994, 1024 ], "errorMessage": "invalid number of bytes for arc4.uint64" }, { "pc": [ 294 ], "errorMessage": "must pay the app" }, { "pc": [ 1007 ], "errorMessage": "no such audit entry" }, { "pc": [ 543, 763 ], "errorMessage": "no such grant" }, { "pc": [ 273, 849, 1036 ], "errorMessage": "only admin" }, { "pc": [ 288 ], "errorMessage": "transaction type is pay" } ], "pcOffsetMethod": "none" }, "clear": { "sourceInfo": [], "pcOffsetMethod": "none" } }, "source": { "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuYXBwcm92YWxfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIGludGNibG9jayAwIDEgMzIgMgogICAgYnl0ZWNibG9jayAidG90YWxfZ3JhbnRzX2FjdGl2ZSIgImFkbWluIiAweDE1MWY3Yzc1ICJnIiAweDAxICJ0b3RhbF9yZXF1ZXN0cyIgInRvdGFsX3Jldm9jYXRpb25zIiAidG90YWxfYXVkaXRfZW50cmllcyIgMHgwMDQyCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxMDkKICAgIC8vIHNlbGYudG90YWxfcmVxdWVzdHMgPSBHbG9iYWxTdGF0ZShVSW50NjQoMCkpCiAgICBieXRlYyA1IC8vICJ0b3RhbF9yZXF1ZXN0cyIKICAgIGludGNfMCAvLyAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTEwCiAgICAvLyBzZWxmLnRvdGFsX2dyYW50c19hY3RpdmUgPSBHbG9iYWxTdGF0ZShVSW50NjQoMCkpCiAgICBieXRlY18wIC8vICJ0b3RhbF9ncmFudHNfYWN0aXZlIgogICAgaW50Y18wIC8vIDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxMTEKICAgIC8vIHNlbGYudG90YWxfcmV2b2NhdGlvbnMgPSBHbG9iYWxTdGF0ZShVSW50NjQoMCkpCiAgICBieXRlYyA2IC8vICJ0b3RhbF9yZXZvY2F0aW9ucyIKICAgIGludGNfMCAvLyAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTEyCiAgICAvLyBzZWxmLnRvdGFsX2F1ZGl0X2VudHJpZXMgPSBHbG9iYWxTdGF0ZShVSW50NjQoMCkpCiAgICBieXRlYyA3IC8vICJ0b3RhbF9hdWRpdF9lbnRyaWVzIgogICAgaW50Y18wIC8vIDAKICAgIGFwcF9nbG9iYWxfcHV0CgptYWluX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEwNgogICAgLy8gY2xhc3MgTWVkUmFpbENvbnNlbnQoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJ6IG1haW5fY3JlYXRlX05vT3BAMTgKICAgIHB1c2hieXRlc3MgMHg0NGYyYzFiZSAweGQxNDc0YjVhIDB4ZDg0ZGViZDAgMHg4YzNhZDUzOSAweGE2N2FlY2JjIDB4MmRiNzc4YWIgMHhkMGFjZTRmNiAweDBmYWVkODViIDB4ZDI5MjY4YTYgMHg0ZWMxMjA5MSAweDA1NmNhNGE3IDB4ZWZhYTY1NjIgLy8gbWV0aG9kICJzZXRfYWRtaW4oYWRkcmVzcyl2b2lkIiwgbWV0aG9kICJmdW5kX21icihwYXkpdm9pZCIsIG1ldGhvZCAicmVxdWVzdF9hY2Nlc3MoYWRkcmVzcyxzdHJpbmcpdm9pZCIsIG1ldGhvZCAiZ3JhbnRfYWNjZXNzKGFkZHJlc3Msc3RyaW5nLHVpbnQ2NCl2b2lkIiwgbWV0aG9kICJyZXZva2VfYWNjZXNzKGFkZHJlc3Msc3RyaW5nKXZvaWQiLCBtZXRob2QgImNoZWNrX2FjY2VzcyhhZGRyZXNzLGFkZHJlc3Msc3RyaW5nKWJvb2wiLCBtZXRob2QgImdldF9ncmFudChhZGRyZXNzLGFkZHJlc3Msc3RyaW5nKSh1aW50OCx1aW50NjQsdWludDY0KSIsIG1ldGhvZCAibG9nX2FjY2VzcyhhZGRyZXNzLGFkZHJlc3Msc3RyaW5nLHN0cmluZyxzdHJpbmcpdWludDY0IiwgbWV0aG9kICJnZXRfYXVkaXRfY291bnQoYWRkcmVzcyl1aW50NjQiLCBtZXRob2QgImdldF9hdWRpdF9lbnRyeShhZGRyZXNzLHVpbnQ2NCkodWludDY0LGFkZHJlc3Msc3RyaW5nLHN0cmluZyxzdHJpbmcpIiwgbWV0aG9kICJnZXRfZ3JhbnRfYm94X21icigpdWludDY0IiwgbWV0aG9kICJ3aXRoZHJhd19leGNlc3ModWludDY0KXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBzZXRfYWRtaW4gZnVuZF9tYnIgcmVxdWVzdF9hY2Nlc3MgZ3JhbnRfYWNjZXNzIHJldm9rZV9hY2Nlc3MgY2hlY2tfYWNjZXNzIGdldF9ncmFudCBsb2dfYWNjZXNzIGdldF9hdWRpdF9jb3VudCBnZXRfYXVkaXRfZW50cnkgbWFpbl9nZXRfZ3JhbnRfYm94X21icl9yb3V0ZUAxNSB3aXRoZHJhd19leGNlc3MKICAgIGVycgoKbWFpbl9nZXRfZ3JhbnRfYm94X21icl9yb3V0ZUAxNToKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjI0OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBwdXNoYnl0ZXMgMHgxNTFmN2M3NTAwMDAwMDAwMDAwMDU2NTQKICAgIGxvZwogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKbWFpbl9jcmVhdGVfTm9PcEAxODoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEwNgogICAgLy8gY2xhc3MgTWVkUmFpbENvbnNlbnQoQVJDNENvbnRyYWN0KToKICAgIHB1c2hieXRlcyAweDRjNWM2MWJhIC8vIG1ldGhvZCAiY3JlYXRlKCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggY3JlYXRlCiAgICBlcnIKCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5jcmVhdGVbcm91dGluZ10oKSAtPiB2b2lkOgpjcmVhdGU6CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxMjEKICAgIC8vIHNlbGYuYWRtaW4udmFsdWUgPSBUeG4uc2VuZGVyCiAgICBieXRlY18xIC8vICJhZG1pbiIKICAgIHR4biBTZW5kZXIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5jb25zZW50LmNvbnRyYWN0Lk1lZFJhaWxDb25zZW50LnNldF9hZG1pbltyb3V0aW5nXSgpIC0+IHZvaWQ6CnNldF9hZG1pbjoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18yIC8vIDMyCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnN0YXRpY19hcnJheTxhcmM0LnVpbnQ4LCAzMj4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEyNgogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5hZG1pbi52YWx1ZSwgIm9ubHkgYWRtaW4iCiAgICB0eG4gU2VuZGVyCiAgICBpbnRjXzAgLy8gMAogICAgYnl0ZWNfMSAvLyAiYWRtaW4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYWRtaW4gZXhpc3RzCiAgICA9PQogICAgYXNzZXJ0IC8vIG9ubHkgYWRtaW4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEyNwogICAgLy8gc2VsZi5hZG1pbi52YWx1ZSA9IG5ld19hZG1pbgogICAgYnl0ZWNfMSAvLyAiYWRtaW4iCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5mdW5kX21icltyb3V0aW5nXSgpIC0+IHZvaWQ6CmZ1bmRfbWJyOgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTI5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnRjXzEgLy8gMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50Y18xIC8vIHBheQogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIHBheQogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTM4CiAgICAvLyBhc3NlcnQgcGF5bWVudC5yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLCAibXVzdCBwYXkgdGhlIGFwcCIKICAgIGd0eG5zIFJlY2VpdmVyCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyBtdXN0IHBheSB0aGUgYXBwCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxMjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5jb25zZW50LmNvbnRyYWN0Lk1lZFJhaWxDb25zZW50LnJlcXVlc3RfYWNjZXNzW3JvdXRpbmddKCkgLT4gdm9pZDoKcmVxdWVzdF9hY2Nlc3M6CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBsZW4KICAgIGludGNfMiAvLyAzMgogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC5zdGF0aWNfYXJyYXk8YXJjNC51aW50OCwgMzI+CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBpbnRjXzMgLy8gMgogICAgKwogICAgZGlnIDEKICAgIGxlbgogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC5keW5hbWljX2FycmF5PGFyYzQudWludDg+CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNDUKICAgIC8vIHNlbGYudG90YWxfcmVxdWVzdHMudmFsdWUgKz0gMQogICAgaW50Y18wIC8vIDAKICAgIGJ5dGVjIDUgLy8gInRvdGFsX3JlcXVlc3RzIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnRvdGFsX3JlcXVlc3RzIGV4aXN0cwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ5dGVjIDUgLy8gInRvdGFsX3JlcXVlc3RzIgogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE0NgogICAgLy8gYXJjNC5lbWl0KEFjY2Vzc1JlcXVlc3RlZChhcmM0LkFkZHJlc3MoVHhuLnNlbmRlciksIGFyYzQuQWRkcmVzcyhwYXRpZW50KSwgYXJjNC5TdHJpbmcoc2NvcGUpKSkKICAgIHR4biBTZW5kZXIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBieXRlYyA4IC8vIDB4MDA0MgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDk5ZjA5NGVlIC8vIG1ldGhvZCAiQWNjZXNzUmVxdWVzdGVkKGFkZHJlc3MsYWRkcmVzcyxzdHJpbmcpIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gc21hcnRfY29udHJhY3RzLmNvbnNlbnQuY29udHJhY3QuTWVkUmFpbENvbnNlbnQuZ3JhbnRfYWNjZXNzW3JvdXRpbmddKCkgLT4gdm9pZDoKZ3JhbnRfYWNjZXNzOgogICAgcHVzaGJ5dGVzICIiCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwbiAyCiAgICBsZW4KICAgIGludGNfMiAvLyAzMgogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC5zdGF0aWNfYXJyYXk8YXJjNC51aW50OCwgMzI+CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBkdXAKICAgIGNvdmVyIDMKICAgIGR1cAogICAgaW50Y18wIC8vIDAKICAgIGV4dHJhY3RfdWludDE2IC8vIG9uIGVycm9yOiBpbnZhbGlkIGFycmF5IGxlbmd0aCBoZWFkZXIKICAgIGludGNfMyAvLyAyCiAgICArCiAgICBkaWcgMQogICAgbGVuCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LmR5bmFtaWNfYXJyYXk8YXJjNC51aW50OD4KICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBkdXAKICAgIGxlbgogICAgcHVzaGludCA4CiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnVpbnQ2NAogICAgYnRvaQogICAgZHVwCiAgICBjb3ZlciAzCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNTEKICAgIC8vIGtleSA9IGdyYW50X2tleShUeG4uc2VuZGVyLCByZXF1ZXN0ZXIsIHNjb3BlKQogICAgdHhuIFNlbmRlcgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6OTgKICAgIC8vIHJldHVybiBvcC5zaGEyNTYocGF0aWVudC5ieXRlcyArIHJlcXVlc3Rlci5ieXRlcyArIHNjb3BlLmJ5dGVzKQogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzaGEyNTYKICAgIHN3YXAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE1MgogICAgLy8gZXhwaXJlc19hdCA9IFVJbnQ2NCgwKSBpZiBkdXJhdGlvbl9zZWNvbmRzID09IFVJbnQ2NCgwKSBlbHNlIEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wICsgZHVyYXRpb25fc2Vjb25kcwogICAgYm56IGdyYW50X2FjY2Vzc190ZXJuYXJ5X2ZhbHNlQDMKICAgIGJ1cnkgMQogICAgaW50Y18wIC8vIDAKCmdyYW50X2FjY2Vzc190ZXJuYXJ5X21lcmdlQDQ6CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNTQtMTU3CiAgICAvLyAjIEEgYm94IGNhbiBleGlzdCB3aGlsZSBpbmFjdGl2ZSAocHJldmlvdXNseSByZXZva2VkKSwgc28gImRvZXMgdGhlIGJveAogICAgLy8gIyBleGlzdCIgaXMgbm90IHRoZSBzYW1lIHF1ZXN0aW9uIGFzICJpcyBpdCBhbHJlYWR5IGNvdW50ZWQgYXMgYWN0aXZlIiDigJQKICAgIC8vICMgdGhlIGNvdW50ZXIgbXVzdCBrZXkgb2ZmIHByaW9yICpzdGF0dXMqLCBub3QgcHJpb3IgKmV4aXN0ZW5jZSouCiAgICAvLyB3YXNfYWN0aXZlX2JlZm9yZSA9IEZhbHNlCiAgICBpbnRjXzAgLy8gMAogICAgYnVyeSA1CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNTgKICAgIC8vIGlmIHNlbGYuZ3JhbnRzLm1heWJlKGtleSlbMV06CiAgICBieXRlY18zIC8vICJnIgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIGR1cAogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBieiBncmFudF9hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUA2CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNTkKICAgIC8vIHdhc19hY3RpdmVfYmVmb3JlID0gc2VsZi5ncmFudHMubWF5YmUoa2V5KVswXS5zdGF0dXMgPT0gYXJjNC5VSW50OChTVEFUVVNfR1JBTlRFRCkKICAgIGR1cAogICAgYm94X2dldAogICAgcG9wCiAgICBleHRyYWN0IDAgMQogICAgYnl0ZWMgNCAvLyAweDAxCiAgICBiPT0KICAgIGJ1cnkgNQoKZ3JhbnRfYWNjZXNzX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE2MwogICAgLy8gZ3JhbnRlZF9hdD1hcmM0LlVJbnQ2NChHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCksCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBpdG9iCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNjQKICAgIC8vIGV4cGlyZXNfYXQ9YXJjNC5VSW50NjQoZXhwaXJlc19hdCksCiAgICB1bmNvdmVyIDIKICAgIGl0b2IKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNjIKICAgIC8vIHN0YXR1cz1hcmM0LlVJbnQ4KFNUQVRVU19HUkFOVEVEKSwKICAgIGJ5dGVjIDQgLy8gMHgwMQogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTYxLTE2NQogICAgLy8gc2VsZi5ncmFudHNba2V5XSA9IEdyYW50UmVjb3JkKAogICAgLy8gICAgIHN0YXR1cz1hcmM0LlVJbnQ4KFNUQVRVU19HUkFOVEVEKSwKICAgIC8vICAgICBncmFudGVkX2F0PWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICAgICBleHBpcmVzX2F0PWFyYzQuVUludDY0KGV4cGlyZXNfYXQpLAogICAgLy8gKQogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTY2CiAgICAvLyBpZiBub3Qgd2FzX2FjdGl2ZV9iZWZvcmU6CiAgICBkaWcgMwogICAgYm56IGdyYW50X2FjY2Vzc19hZnRlcl9pZl9lbHNlQDgKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE2NwogICAgLy8gc2VsZi50b3RhbF9ncmFudHNfYWN0aXZlLnZhbHVlICs9IDEKICAgIGludGNfMCAvLyAwCiAgICBieXRlY18wIC8vICJ0b3RhbF9ncmFudHNfYWN0aXZlIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnRvdGFsX2dyYW50c19hY3RpdmUgZXhpc3RzCiAgICBpbnRjXzEgLy8gMQogICAgKwogICAgYnl0ZWNfMCAvLyAidG90YWxfZ3JhbnRzX2FjdGl2ZSIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CgpncmFudF9hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUA4OgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTcxCiAgICAvLyBhcmM0LkFkZHJlc3MoVHhuLnNlbmRlciksCiAgICB0eG4gU2VuZGVyCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNzAtMTc1CiAgICAvLyBBY2Nlc3NHcmFudGVkKAogICAgLy8gICAgIGFyYzQuQWRkcmVzcyhUeG4uc2VuZGVyKSwKICAgIC8vICAgICBhcmM0LkFkZHJlc3MocmVxdWVzdGVyKSwKICAgIC8vICAgICBhcmM0LlN0cmluZyhzY29wZSksCiAgICAvLyAgICAgYXJjNC5VSW50NjQoZXhwaXJlc19hdCksCiAgICAvLyApCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgcHVzaGJ5dGVzIDB4MDA0YQogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTY5LTE3NgogICAgLy8gYXJjNC5lbWl0KAogICAgLy8gICAgIEFjY2Vzc0dyYW50ZWQoCiAgICAvLyAgICAgICAgIGFyYzQuQWRkcmVzcyhUeG4uc2VuZGVyKSwKICAgIC8vICAgICAgICAgYXJjNC5BZGRyZXNzKHJlcXVlc3RlciksCiAgICAvLyAgICAgICAgIGFyYzQuU3RyaW5nKHNjb3BlKSwKICAgIC8vICAgICAgICAgYXJjNC5VSW50NjQoZXhwaXJlc19hdCksCiAgICAvLyAgICAgKQogICAgLy8gKQogICAgcHVzaGJ5dGVzIDB4NGQxNTUxMjAgLy8gbWV0aG9kICJBY2Nlc3NHcmFudGVkKGFkZHJlc3MsYWRkcmVzcyxzdHJpbmcsdWludDY0KSIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNDgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKZ3JhbnRfYWNjZXNzX3Rlcm5hcnlfZmFsc2VAMzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE1MgogICAgLy8gZXhwaXJlc19hdCA9IFVJbnQ2NCgwKSBpZiBkdXJhdGlvbl9zZWNvbmRzID09IFVJbnQ2NCgwKSBlbHNlIEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wICsgZHVyYXRpb25fc2Vjb25kcwogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgdW5jb3ZlciAyCiAgICArCiAgICBiIGdyYW50X2FjY2Vzc190ZXJuYXJ5X21lcmdlQDQKCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5yZXZva2VfYWNjZXNzW3JvdXRpbmddKCkgLT4gdm9pZDoKcmV2b2tlX2FjY2VzczoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBkdXBuIDIKICAgIGxlbgogICAgaW50Y18yIC8vIDMyCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnN0YXRpY19hcnJheTxhcmM0LnVpbnQ4LCAzMj4KICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGR1cAogICAgY292ZXIgMgogICAgZHVwCiAgICBpbnRjXzAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgaW50Y18zIC8vIDIKICAgICsKICAgIGRpZyAxCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE4MQogICAgLy8ga2V5ID0gZ3JhbnRfa2V5KFR4bi5zZW5kZXIsIHJlcXVlc3Rlciwgc2NvcGUpCiAgICB0eG4gU2VuZGVyCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weTo5OAogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihwYXRpZW50LmJ5dGVzICsgcmVxdWVzdGVyLmJ5dGVzICsgc2NvcGUuYnl0ZXMpCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzaGEyNTYKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE4MgogICAgLy8gYXNzZXJ0IHNlbGYuZ3JhbnRzLm1heWJlKGtleSlbMV0sICJubyBzdWNoIGdyYW50IgogICAgYnl0ZWNfMyAvLyAiZyIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZHVwCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBubyBzdWNoIGdyYW50CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxODMKICAgIC8vIHJlY29yZCA9IHNlbGYuZ3JhbnRzLm1heWJlKGtleSlbMF0uY29weSgpCiAgICBkdXAKICAgIGJveF9nZXQKICAgIHBvcAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTg1CiAgICAvLyB3YXNfYWN0aXZlID0gcmVjb3JkLnN0YXR1cyA9PSBhcmM0LlVJbnQ4KFNUQVRVU19HUkFOVEVEKQogICAgZHVwCiAgICBleHRyYWN0IDAgMQogICAgYnl0ZWMgNCAvLyAweDAxCiAgICBiPT0KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE4OAogICAgLy8gZ3JhbnRlZF9hdD1yZWNvcmQuZ3JhbnRlZF9hdCwKICAgIGRpZyAxCiAgICBleHRyYWN0IDEgOAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTg5CiAgICAvLyBleHBpcmVzX2F0PXJlY29yZC5leHBpcmVzX2F0LAogICAgdW5jb3ZlciAyCiAgICBleHRyYWN0IDkgOAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTg3CiAgICAvLyBzdGF0dXM9YXJjNC5VSW50OChTVEFUVVNfUkVWT0tFRCksCiAgICBwdXNoYnl0ZXMgMHgwMgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTg2LTE5MAogICAgLy8gc2VsZi5ncmFudHNba2V5XSA9IEdyYW50UmVjb3JkKAogICAgLy8gICAgIHN0YXR1cz1hcmM0LlVJbnQ4KFNUQVRVU19SRVZPS0VEKSwKICAgIC8vICAgICBncmFudGVkX2F0PXJlY29yZC5ncmFudGVkX2F0LAogICAgLy8gICAgIGV4cGlyZXNfYXQ9cmVjb3JkLmV4cGlyZXNfYXQsCiAgICAvLyApCiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICB1bmNvdmVyIDIKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE5MQogICAgLy8gaWYgd2FzX2FjdGl2ZToKICAgIGJ6IHJldm9rZV9hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUAzCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxOTIKICAgIC8vIHNlbGYudG90YWxfZ3JhbnRzX2FjdGl2ZS52YWx1ZSAtPSAxCiAgICBpbnRjXzAgLy8gMAogICAgYnl0ZWNfMCAvLyAidG90YWxfZ3JhbnRzX2FjdGl2ZSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50b3RhbF9ncmFudHNfYWN0aXZlIGV4aXN0cwogICAgaW50Y18xIC8vIDEKICAgIC0KICAgIGJ5dGVjXzAgLy8gInRvdGFsX2dyYW50c19hY3RpdmUiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTkzCiAgICAvLyBzZWxmLnRvdGFsX3Jldm9jYXRpb25zLnZhbHVlICs9IDEKICAgIGludGNfMCAvLyAwCiAgICBieXRlYyA2IC8vICJ0b3RhbF9yZXZvY2F0aW9ucyIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50b3RhbF9yZXZvY2F0aW9ucyBleGlzdHMKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBieXRlYyA2IC8vICJ0b3RhbF9yZXZvY2F0aW9ucyIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CgpyZXZva2VfYWNjZXNzX2FmdGVyX2lmX2Vsc2VAMzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE5NQogICAgLy8gYXJjNC5lbWl0KEFjY2Vzc1Jldm9rZWQoYXJjNC5BZGRyZXNzKFR4bi5zZW5kZXIpLCBhcmM0LkFkZHJlc3MocmVxdWVzdGVyKSwgYXJjNC5TdHJpbmcoc2NvcGUpKSkKICAgIHR4biBTZW5kZXIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBieXRlYyA4IC8vIDB4MDA0MgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHB1c2hieXRlcyAweDM2ZGQ4ZGI0IC8vIG1ldGhvZCAiQWNjZXNzUmV2b2tlZChhZGRyZXNzLGFkZHJlc3Msc3RyaW5nKSIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxNzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgoKCi8vIHNtYXJ0X2NvbnRyYWN0cy5jb25zZW50LmNvbnRyYWN0Lk1lZFJhaWxDb25zZW50LmNoZWNrX2FjY2Vzc1tyb3V0aW5nXSgpIC0+IHZvaWQ6CmNoZWNrX2FjY2VzczoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18yIC8vIDMyCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnN0YXRpY19hcnJheTxhcmM0LnVpbnQ4LCAzMj4KICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzIgLy8gMzIKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuc3RhdGljX2FycmF5PGFyYzQudWludDgsIDMyPgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZHVwCiAgICBpbnRjXzAgLy8gMAogICAgZXh0cmFjdF91aW50MTYgLy8gb24gZXJyb3I6IGludmFsaWQgYXJyYXkgbGVuZ3RoIGhlYWRlcgogICAgaW50Y18zIC8vIDIKICAgICsKICAgIGRpZyAxCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgZXh0cmFjdCAyIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5Ojk4CiAgICAvLyByZXR1cm4gb3Auc2hhMjU2KHBhdGllbnQuYnl0ZXMgKyByZXF1ZXN0ZXIuYnl0ZXMgKyBzY29wZS5ieXRlcykKICAgIGNvdmVyIDIKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzaGEyNTYKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIwMQogICAgLy8gaWYgbm90IHNlbGYuZ3JhbnRzLm1heWJlKGtleSlbMV06CiAgICBieXRlY18zIC8vICJnIgogICAgc3dhcAogICAgY29uY2F0CiAgICBkdXAKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYm56IGNoZWNrX2FjY2Vzc19hZnRlcl9pZl9lbHNlQDMKICAgIHBvcAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjAyCiAgICAvLyByZXR1cm4gRmFsc2UKICAgIGludGNfMCAvLyAwCgpjaGVja19hY2Nlc3NfYWZ0ZXJfaW5saW5lZF9zbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5jaGVja19hY2Nlc3NAODoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBwdXNoYnl0ZXMgMHgwMAogICAgaW50Y18wIC8vIDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlY18yIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgpjaGVja19hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjAzCiAgICAvLyByZWNvcmQgPSBzZWxmLmdyYW50cy5tYXliZShrZXkpWzBdLmNvcHkoKQogICAgYm94X2dldAogICAgcG9wCiAgICBkdXAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIwNAogICAgLy8gaWYgcmVjb3JkLnN0YXR1cyAhPSBhcmM0LlVJbnQ4KFNUQVRVU19HUkFOVEVEKToKICAgIGV4dHJhY3QgMCAxCiAgICBieXRlYyA0IC8vIDB4MDEKICAgIGIhPQogICAgYnogY2hlY2tfYWNjZXNzX2FmdGVyX2lmX2Vsc2VANQogICAgcG9wCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMDUKICAgIC8vIHJldHVybiBGYWxzZQogICAgaW50Y18wIC8vIDAKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjE5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBiIGNoZWNrX2FjY2Vzc19hZnRlcl9pbmxpbmVkX3NtYXJ0X2NvbnRyYWN0cy5jb25zZW50LmNvbnRyYWN0Lk1lZFJhaWxDb25zZW50LmNoZWNrX2FjY2Vzc0A4CgpjaGVja19hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUA1OgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjA2CiAgICAvLyBleHBpcmVzX2F0ID0gcmVjb3JkLmV4cGlyZXNfYXQuYXNfdWludDY0KCkKICAgIHB1c2hpbnQgOQogICAgZXh0cmFjdF91aW50NjQKICAgIGR1cAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjA3CiAgICAvLyBpZiBleHBpcmVzX2F0ID09IFVJbnQ2NCgwKToKICAgIGJueiBjaGVja19hY2Nlc3NfYWZ0ZXJfaWZfZWxzZUA3CiAgICBwb3AKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIwOAogICAgLy8gcmV0dXJuIFRydWUKICAgIGludGNfMSAvLyAxCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToxOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgYiBjaGVja19hY2Nlc3NfYWZ0ZXJfaW5saW5lZF9zbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5jaGVja19hY2Nlc3NAOAoKY2hlY2tfYWNjZXNzX2FmdGVyX2lmX2Vsc2VANzoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIwOQogICAgLy8gcmV0dXJuIGJvb2woR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPCBleHBpcmVzX2F0KQogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgPgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIGIgY2hlY2tfYWNjZXNzX2FmdGVyX2lubGluZWRfc21hcnRfY29udHJhY3RzLmNvbnNlbnQuY29udHJhY3QuTWVkUmFpbENvbnNlbnQuY2hlY2tfYWNjZXNzQDgKCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5nZXRfZ3JhbnRbcm91dGluZ10oKSAtPiB2b2lkOgpnZXRfZ3JhbnQ6CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBsZW4KICAgIGludGNfMiAvLyAzMgogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC5zdGF0aWNfYXJyYXk8YXJjNC51aW50OCwgMzI+CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBkdXAKICAgIGxlbgogICAgaW50Y18yIC8vIDMyCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnN0YXRpY19hcnJheTxhcmM0LnVpbnQ4LCAzMj4KICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGR1cAogICAgaW50Y18wIC8vIDAKICAgIGV4dHJhY3RfdWludDE2IC8vIG9uIGVycm9yOiBpbnZhbGlkIGFycmF5IGxlbmd0aCBoZWFkZXIKICAgIGludGNfMyAvLyAyCiAgICArCiAgICBkaWcgMQogICAgbGVuCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LmR5bmFtaWNfYXJyYXk8YXJjNC51aW50OD4KICAgIGV4dHJhY3QgMiAwCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weTo5OAogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihwYXRpZW50LmJ5dGVzICsgcmVxdWVzdGVyLmJ5dGVzICsgc2NvcGUuYnl0ZXMpCiAgICBjb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc2hhMjU2CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMTQKICAgIC8vIGFzc2VydCBzZWxmLmdyYW50cy5tYXliZShrZXkpWzFdLCAibm8gc3VjaCBncmFudCIKICAgIGJ5dGVjXzMgLy8gImciCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGR1cAogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBhc3NlcnQgLy8gbm8gc3VjaCBncmFudAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjE1CiAgICAvLyByZXR1cm4gc2VsZi5ncmFudHMubWF5YmUoa2V5KVswXS5jb3B5KCkKICAgIGJveF9nZXQKICAgIHBvcAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjExCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIGJ5dGVjXzIgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC5sb2dfYWNjZXNzW3JvdXRpbmddKCkgLT4gdm9pZDoKbG9nX2FjY2VzczoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIxNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBkdXBuIDIKICAgIGxlbgogICAgaW50Y18yIC8vIDMyCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LnN0YXRpY19hcnJheTxhcmM0LnVpbnQ4LCAzMj4KICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGR1cAogICAgY292ZXIgMgogICAgbGVuCiAgICBpbnRjXzIgLy8gMzIKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuc3RhdGljX2FycmF5PGFyYzQudWludDgsIDMyPgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgZHVwCiAgICBjb3ZlciAzCiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBpbnRjXzMgLy8gMgogICAgKwogICAgc3dhcAogICAgbGVuCiAgICBkdXAKICAgIGNvdmVyIDMKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgZHVwCiAgICBjb3ZlciA0CiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBpbnRjXzMgLy8gMgogICAgKwogICAgc3dhcAogICAgbGVuCiAgICBkdXAKICAgIGNvdmVyIDMKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuZHluYW1pY19hcnJheTxhcmM0LnVpbnQ4PgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgZHVwCiAgICBjb3ZlciA0CiAgICBkdXAKICAgIGludGNfMCAvLyAwCiAgICBleHRyYWN0X3VpbnQxNiAvLyBvbiBlcnJvcjogaW52YWxpZCBhcnJheSBsZW5ndGggaGVhZGVyCiAgICBpbnRjXzMgLy8gMgogICAgKwogICAgc3dhcAogICAgbGVuCiAgICA9PQogICAgYXNzZXJ0IC8vIGludmFsaWQgbnVtYmVyIG9mIGJ5dGVzIGZvciBhcmM0LmR5bmFtaWNfYXJyYXk8YXJjNC51aW50OD4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIyMgogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5hZG1pbi52YWx1ZSwgIm9ubHkgYWRtaW4iCiAgICB0eG4gU2VuZGVyCiAgICBpbnRjXzAgLy8gMAogICAgYnl0ZWNfMSAvLyAiYWRtaW4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYWRtaW4gZXhpc3RzCiAgICA9PQogICAgYXNzZXJ0IC8vIG9ubHkgYWRtaW4KICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIyNAogICAgLy8gc2VxLCBleGlzdGVkID0gc2VsZi5hdWRpdF9zZXEubWF5YmUocGF0aWVudCkKICAgIHB1c2hieXRlcyAicyIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZHVwCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMjUKICAgIC8vIG5leHRfc2VxID0gVUludDY0KDEpIGlmIG5vdCBleGlzdGVkIGVsc2Ugc2VxICsgMQogICAgYm56IGxvZ19hY2Nlc3NfdGVybmFyeV9mYWxzZUAzCiAgICBwb3AKICAgIGludGNfMSAvLyAxCgpsb2dfYWNjZXNzX3Rlcm5hcnlfbWVyZ2VANDoKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIyNgogICAgLy8gc2VsZi5hdWRpdF9zZXFbcGF0aWVudF0gPSBuZXh0X3NlcQogICAgaXRvYgogICAgc3dhcAogICAgZGlnIDEKICAgIGJveF9wdXQKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIyOQogICAgLy8gdHM9YXJjNC5VSW50NjQoR2xvYmFsLmxhdGVzdF90aW1lc3RhbXApLAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgaXRvYgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjI4LTIzNAogICAgLy8gc2VsZi5hdWRpdF9sb2dbYXVkaXRfa2V5KHBhdGllbnQsIG5leHRfc2VxKV0gPSBBdWRpdEVudHJ5KAogICAgLy8gICAgIHRzPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICAgICByZXF1ZXN0ZXI9YXJjNC5BZGRyZXNzKHJlcXVlc3RlciksCiAgICAvLyAgICAgc2NvcGU9YXJjNC5TdHJpbmcoc2NvcGUpLAogICAgLy8gICAgIGVuZHBvaW50PWFyYzQuU3RyaW5nKGVuZHBvaW50KSwKICAgIC8vICAgICBhY3Rpb249YXJjNC5TdHJpbmcoYWN0aW9uKSwKICAgIC8vICkKICAgIHVuY292ZXIgNQogICAgY29uY2F0CiAgICBwdXNoYnl0ZXMgMHgwMDJlCiAgICBjb25jYXQKICAgIHB1c2hpbnQgNDYKICAgIHVuY292ZXIgNAogICAgKwogICAgZHVwCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgdW5jb3ZlciAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIHVuY292ZXIgMwogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGNvbmNhdAogICAgdW5jb3ZlciA0CiAgICBjb25jYXQKICAgIHVuY292ZXIgMwogICAgY29uY2F0CiAgICB1bmNvdmVyIDIKICAgIGNvbmNhdAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MTAzCiAgICAvLyByZXR1cm4gcGF0aWVudC5ieXRlcyArIG9wLml0b2Ioc2VxKQogICAgdW5jb3ZlciAyCiAgICBkaWcgMgogICAgY29uY2F0CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMjgKICAgIC8vIHNlbGYuYXVkaXRfbG9nW2F1ZGl0X2tleShwYXRpZW50LCBuZXh0X3NlcSldID0gQXVkaXRFbnRyeSgKICAgIHB1c2hieXRlcyAiYSIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjI4LTIzNAogICAgLy8gc2VsZi5hdWRpdF9sb2dbYXVkaXRfa2V5KHBhdGllbnQsIG5leHRfc2VxKV0gPSBBdWRpdEVudHJ5KAogICAgLy8gICAgIHRzPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICAgICByZXF1ZXN0ZXI9YXJjNC5BZGRyZXNzKHJlcXVlc3RlciksCiAgICAvLyAgICAgc2NvcGU9YXJjNC5TdHJpbmcoc2NvcGUpLAogICAgLy8gICAgIGVuZHBvaW50PWFyYzQuU3RyaW5nKGVuZHBvaW50KSwKICAgIC8vICAgICBhY3Rpb249YXJjNC5TdHJpbmcoYWN0aW9uKSwKICAgIC8vICkKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyMzUKICAgIC8vIHNlbGYudG90YWxfYXVkaXRfZW50cmllcy52YWx1ZSArPSAxCiAgICBpbnRjXzAgLy8gMAogICAgYnl0ZWMgNyAvLyAidG90YWxfYXVkaXRfZW50cmllcyIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50b3RhbF9hdWRpdF9lbnRyaWVzIGV4aXN0cwogICAgaW50Y18xIC8vIDEKICAgICsKICAgIGJ5dGVjIDcgLy8gInRvdGFsX2F1ZGl0X2VudHJpZXMiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjE3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGJ5dGVjXzIgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCmxvZ19hY2Nlc3NfdGVybmFyeV9mYWxzZUAzOgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjI1CiAgICAvLyBuZXh0X3NlcSA9IFVJbnQ2NCgxKSBpZiBub3QgZXhpc3RlZCBlbHNlIHNlcSArIDEKICAgIGludGNfMSAvLyAxCiAgICArCiAgICBiIGxvZ19hY2Nlc3NfdGVybmFyeV9tZXJnZUA0CgoKLy8gc21hcnRfY29udHJhY3RzLmNvbnNlbnQuY29udHJhY3QuTWVkUmFpbENvbnNlbnQuZ2V0X2F1ZGl0X2NvdW50W3JvdXRpbmddKCkgLT4gdm9pZDoKZ2V0X2F1ZGl0X2NvdW50OgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzIgLy8gMzIKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuc3RhdGljX2FycmF5PGFyYzQudWludDgsIDMyPgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjQwCiAgICAvLyByZXR1cm4gc2VsZi5hdWRpdF9zZXEuZ2V0KHBhdGllbnQsIGRlZmF1bHQ9VUludDY0KDApKQogICAgcHVzaGJ5dGVzICJzIgogICAgc3dhcAogICAgY29uY2F0CiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBpbnRjXzAgLy8gMAogICAgc3dhcAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjIzOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBpdG9iCiAgICBieXRlY18yIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzEgLy8gMQogICAgcmV0dXJuCgoKLy8gc21hcnRfY29udHJhY3RzLmNvbnNlbnQuY29udHJhY3QuTWVkUmFpbENvbnNlbnQuZ2V0X2F1ZGl0X2VudHJ5W3JvdXRpbmddKCkgLT4gdm9pZDoKZ2V0X2F1ZGl0X2VudHJ5OgogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgbGVuCiAgICBpbnRjXzIgLy8gMzIKICAgID09CiAgICBhc3NlcnQgLy8gaW52YWxpZCBudW1iZXIgb2YgYnl0ZXMgZm9yIGFyYzQuc3RhdGljX2FycmF5PGFyYzQudWludDgsIDMyPgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZHVwCiAgICBsZW4KICAgIHB1c2hpbnQgOAogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC51aW50NjQKICAgIGJ0b2kKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjEwMwogICAgLy8gcmV0dXJuIHBhdGllbnQuYnl0ZXMgKyBvcC5pdG9iKHNlcSkKICAgIGl0b2IKICAgIGNvbmNhdAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjQ1CiAgICAvLyBhc3NlcnQgc2VsZi5hdWRpdF9sb2cubWF5YmUoa2V5KVsxXSwgIm5vIHN1Y2ggYXVkaXQgZW50cnkiCiAgICBwdXNoYnl0ZXMgImEiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGR1cAogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBhc3NlcnQgLy8gbm8gc3VjaCBhdWRpdCBlbnRyeQogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjQ2CiAgICAvLyByZXR1cm4gc2VsZi5hdWRpdF9sb2cubWF5YmUoa2V5KVswXS5jb3B5KCkKICAgIGJveF9nZXQKICAgIHBvcAogICAgLy8gc21hcnRfY29udHJhY3RzL2NvbnNlbnQvY29udHJhY3QucHk6MjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIGJ5dGVjXzIgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMSAvLyAxCiAgICByZXR1cm4KCgovLyBzbWFydF9jb250cmFjdHMuY29uc2VudC5jb250cmFjdC5NZWRSYWlsQ29uc2VudC53aXRoZHJhd19leGNlc3Nbcm91dGluZ10oKSAtPiB2b2lkOgp3aXRoZHJhd19leGNlc3M6CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBsZW4KICAgIHB1c2hpbnQgOAogICAgPT0KICAgIGFzc2VydCAvLyBpbnZhbGlkIG51bWJlciBvZiBieXRlcyBmb3IgYXJjNC51aW50NjQKICAgIGJ0b2kKICAgIC8vIHNtYXJ0X2NvbnRyYWN0cy9jb25zZW50L2NvbnRyYWN0LnB5OjI1OAogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5hZG1pbi52YWx1ZSwgIm9ubHkgYWRtaW4iCiAgICB0eG4gU2VuZGVyCiAgICBpbnRjXzAgLy8gMAogICAgYnl0ZWNfMSAvLyAiYWRtaW4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYWRtaW4gZXhpc3RzCiAgICBzd2FwCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBvbmx5IGFkbWluCiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyNTkKICAgIC8vIGl0eG4uUGF5bWVudChyZWNlaXZlcj1zZWxmLmFkbWluLnZhbHVlLCBhbW91bnQ9YW1vdW50LCBmZWU9MCkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIGl0eG5fZmllbGQgQW1vdW50CiAgICBpbnRjXzEgLy8gcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnRjXzAgLy8gMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGl0eG5fc3VibWl0CiAgICAvLyBzbWFydF9jb250cmFjdHMvY29uc2VudC9jb250cmFjdC5weToyNTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgaW50Y18xIC8vIDEKICAgIHJldHVybgo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBhbGdvcHkuYXJjNC5BUkM0Q29udHJhY3QuY2xlYXJfc3RhdGVfcHJvZ3JhbSgpIC0+IHVpbnQ2NDoKbWFpbjoKICAgIHB1c2hpbnQgMQogICAgcmV0dXJuCg==" }, "byteCode": { "approval": "CyAEAAEgAiYJE3RvdGFsX2dyYW50c19hY3RpdmUFYWRtaW4EFR98dQFnAQEOdG90YWxfcmVxdWVzdHMRdG90YWxfcmV2b2NhdGlvbnMTdG90YWxfYXVkaXRfZW50cmllcwIAQjEYQAAPJwUiZygiZycGImcnByJnMRkURDEYQQBtggwERPLBvgTRR0taBNhN69AEjDrVOQSmeuy8BC23eKsE0Kzk9gQPrthbBNKSaKYETsEgkQQFbKSnBO+qZWI2GgCODAAmADsATQCCARgBkAHyAigC2gL2AAEDHACADBUffHUAAAAAAABWVLAjQ4AETFxhujYaAI4BAAEAKTEAZyNDNhoBSRUkEkQxACIpZUQSRClMZyNDMRYjCUk4ECMSRDgHMgoSRCNDNhoBSRUkEkQ2GgJJIlklCEsBFRJEIicFZUQjCCcFTGcxAE8CUCcIUExQgASZ8JTuTFCwI0OAADYaAUcCFSQSRDYaAklOA0kiWSUISwEVEkRXAgA2GgNJFYEIEkQXSU4DMQBPA1BPAlABTEAAVkUBIiJFBStPAlBJvUUBQQALSb5IVwABJwSoRQUyBxZPAhZJTwInBExQTFBPAky/SwNAAAkiKGVEIwgoTGcxAE8CUIACAEpQTFBMUIAETRVRIExQsCNDMgdPAghC/6U2GgFHAhUkEkQ2GgJJTgJJIlklCEsBFRJEVwIAMQBPAlBMUAErTFBJvUUBREm+SElXAAEnBKhLAVcBCE8CVwkIgAECTwJQTFBPAky/QQAUIihlRCMJKExnIicGZUQjCCcGTGcxAE8CUCcIUExQgAQ23Y20TFCwI0M2GgFJFSQSRDYaAkkVJBJENhoDSSJZJQhLARUSRFcCAE4CUExQAStMUEm9RQFAAA9IIoABACJPAlQqTFCwI0O+SElXAAEnBKlBAAVIIkL/4oEJW0lAAAVII0L/1jIHDUL/0DYaAUkVJBJENhoCSRUkEkQ2GgNJIlklCEsBFRJEVwIATgJQTFABK0xQSb1FAUS+SCpMULAjQzYaAUcCFSQSRDYaAklOAhUkEkQ2GgNJTgNJIlklCEwVSU4DEkQ2GgRJTgRJIlklCEwVSU4DEkQ2GgVJTgRJIlklCEwVEkQxACIpZUQSRIABc0xQSb5MF0xAAFJIIxZMSwG/MgcWTwVQgAIALlCBLk8ECEkWVwYCTwJMUExPAwgWVwYCUE8EUE8DUE8CUE8CSwJQgAFhTFBJvEhMvyInB2VEIwgnB0xnKkxQsCNDIwhC/6s2GgFJFSQSRIABc0xQvkwXIkxPAk0WKkxQsCNDNhoBSRUkEkQ2GgJJFYEIEkQXFlCAAWFMUEm9RQFEvkgqTFCwI0M2GgFJFYEIEkQXMQAiKWVETEsBEkSxsgeyCCOyECKyAbMjQw==", "clear": "C4EBQw==" }, "compilerInfo": { "compiler": "puya", "compilerVersion": { "major": 5, "minor": 9, "patch": 0 } }, "events": [ { "name": "AccessRequested", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ] }, { "name": "AccessGranted", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" }, { "type": "uint64", "name": "expires_at" } ] }, { "name": "AccessRevoked", "args": [ { "type": "address", "name": "patient" }, { "type": "address", "name": "requester" }, { "type": "string", "name": "scope" } ] } ], "templateVariables": {} }