diff --git a/addons/cetmix_tower_server/models/cx_tower_server.py b/addons/cetmix_tower_server/models/cx_tower_server.py new file mode 100644 index 0000000..b7e3650 --- /dev/null +++ b/addons/cetmix_tower_server/models/cx_tower_server.py @@ -0,0 +1 @@ +IyBDb3B5cmlnaHQgKEMpIDIwMjIgQ2V0bWl4IE/DnAojIExpY2Vuc2UgQUdQTC0zLjAgb3IgbGF0ZXIgKGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsKS4KaW1wb3J0IGFzdAppbXBvcnQgaW8KaW1wb3J0IGxvZ2dpbmcKZnJvbSBkYXRldGltZSBpbXBvcnQgdGltZWRlbHRhCmZyb20gZnVuY3Rvb2xzIGltcG9ydCB3cmFwcwoKZnJvbSBvZG9vIGltcG9ydCBfLCBhcGksIGZpZWxkcywgbW9kZWxzCmZyb20gb2Rvby5leGNlcHRpb25zIGltcG9ydCBVc2VyRXJyb3IsIFZhbGlkYXRpb25FcnJvcgpmcm9tIG9kb28udG9vbHMuc2FmZV9ldmFsIGltcG9ydCBzYWZlX2V2YWwKCmZyb20gb2Rvby5hZGRvbnMuYmFzZS5tb2RlbHMucmVzX3VzZXJzIGltcG9ydCBjaGVja19pZGVudGl0eQoKZnJvbSAuLnNzaC5zc2ggaW1wb3J0IFNTSENvbm5lY3Rpb24sIFNTSE1hbmFnZXIKZnJvbSAuY29uc3RhbnRzIGltcG9ydCAoCiAgICBBTk9USEVSX0NPTU1BTkRfUlVOTklORywKICAgIENPTU1BTkRfTk9UX0NPTVBBVElCTEVfV0lUSF9TRVJWRVIsCiAgICBDT01NQU5EX1RJTUVEX09VVCwKICAgIENPTU1BTkRfVElNRURfT1VUX01FU1NBR0UsCiAgICBGSUxFX0NSRUFUSU9OX0ZBSUxFRCwKICAgIEdFTkVSQUxfRVJST1IsCiAgICBKRVRfTk9UX0ZPVU5ELAogICAgSkVUX1RFTVBMQVRFX05PVF9GT1VORCwKICAgIE5PX0NPTU1BTkRfUlVOTkVSX0ZPVU5ELAogICAgUFlUSE9OX0NPTU1BTkRfRVJST1IsCiAgICBTU0hfQ09OTkVDVElPTl9FUlJPUiwKICAgIFdBWVBPSU5UX0NSRUFURV9GQUlMRUQsCiAgICBXQVlQT0lOVF9URU1QTEFURV9OT1RfRk9VTkQsCikKZnJvbSAudG9vbHMgaW1wb3J0IGdlbmVyYXRlX3JhbmRvbV9pZAoKX2xvZ2dlciA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKF9fbmFtZV9fKQoKCmRlZiBlbnN1cmVfc3NoX2Rpc2Nvbm5lY3QoZnVuYyk6CiAgICAiIiIKICAgIERlY29yYXRvciB0aGF0IGVuc3VyZXMgdGhlIFNTSCBjb25uZWN0aW9uIGlzIGRpc2Nvbm5lY3RlZCBhZnRlciB0aGUgdHJhbnNhY3Rpb24KICAgIGNvbXBsZXRlcywgd2hldGhlciBieSBjb21taXQgb3Igcm9sbGJhY2suCgogICAgVGhpcyBkZWNvcmF0b3IgcmVnaXN0ZXJzIGhvb2tzIChwb3N0Y29tbWl0IGFuZCBwb3N0cm9sbGJhY2spIGJlZm9yZSBjYWxsaW5nIHRoZQogICAgZGVjb3JhdGVkIGZ1bmN0aW9uLiBUaHVzLCBldmVuIGlmIHRoZSBmdW5jdGlvbiByYWlzZXMgYW4gZXhjZXB0aW9uIChhbmQgaXQncyBjYXVnaHQKICAgIGF0IGEgaGlnaGVyIGxldmVsKSwgdGhlIGhvb2tzIHdpbGwgc3RpbGwgYmUgZXhlY3V0ZWQsIGVuc3VyaW5nIHRoYXQgdGhlCiAgICBTU0ggY29ubmVjdGlvbiBpcyBjbG9zZWQuCiAgICAiIiIKCiAgICBAd3JhcHMoZnVuYykKICAgIGRlZiB3cmFwcGVkKHNlbGYsICphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgIyBUcnkgdG8gb2J0YWluIHRoZSBTU0ggY29ubmVjdGlvbiBvbmNlCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb25uZWN0aW9uID0gc2VsZi5fZ2V0X3NzaF9jbGllbnQocmFpc2Vfb25fZXJyb3I9VHJ1ZSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIF9sb2dnZXIuZXJyb3IoZiJFcnJvciBvYnRhaW5pbmcgU1NIIGNvbm5lY3Rpb246IHtlfSIpCiAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBOb25lCgogICAgICAgICMgRGVmaW5lIGEgaG9vayB0byBkaXNjb25uZWN0IHRoZSBTU0ggY29ubmVjdGlvbiB1c2luZyB0aGUgb2J0YWluZWQgY29ubmVjdGlvbi4KICAgICAgICBkZWYgZGlzY29ubmVjdF9jb25uZWN0aW9uKCk6CiAgICAgICAgICAgIGlmIGNvbm5lY3Rpb246CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNjb25uZWN0KCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLmVycm9yKGYiRXJyb3IgZGlzY29ubmVjdGluZyBTU0ggY29ubmVjdGlvbjoge2V9IikKCiAgICAgICAgIyBSZWdpc3RlciB0aGUgZGlzY29ubmVjdCBob29rIGZvciBib3RoIGNvbW1pdCBhbmQgcm9sbGJhY2sgZXZlbnRzLgogICAgICAgIHNlbGYuZW52LmNyLnBvc3Rjb21taXQuYWRkKGRpc2Nvbm5lY3RfY29ubmVjdGlvbikKICAgICAgICBzZWxmLmVudi5jci5wb3N0cm9sbGJhY2suYWRkKGRpc2Nvbm5lY3RfY29ubmVjdGlvbikKCiAgICAgICAgIyBDYWxsIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24uCiAgICAgICAgcmVzdWx0ID0gZnVuYyhzZWxmLCAqYXJncywgKiprd2FyZ3MpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIHJldHVybiB3cmFwcGVkCgoKY2xhc3MgQ3hUb3dlclNlcnZlcihtb2RlbHMuTW9kZWwpOgogICAgIiIiUmVwcmVzZW50cyBhIHNlcnZlciBlbnRpdHkuCgogICAgS2VlcHMgaW5mb3JtYXRpb24gcmVxdWlyZWQgdG8gY29ubmVjdCBhbmQgcGVyZm9ybSByb3V0aW5lIG9wZXJhdGlvbnMKICAgIHN1Y2ggYXMgY29uZmlndXJhdGlvbiwgZmlsZSBtYW5hZ2VtZW50IGV0Yy4KICAgICIiIgoKICAgIF9uYW1lID0gImN4LnRvd2VyLnNlcnZlciIKICAgIF9pbmhlcml0ID0gWwogICAgICAgICJjeC50b3dlci5hY2Nlc3Mucm9sZS5taXhpbiIsCiAgICAgICAgImN4LnRvd2VyLnZhcmlhYmxlLm1peGluIiwKICAgICAgICAiY3gudG93ZXIucmVmZXJlbmNlLm1peGluIiwKICAgICAgICAiY3gudG93ZXIubWV0YWRhdGEubWl4aW4iLAogICAgICAgICJtYWlsLnRocmVhZCIsCiAgICAgICAgIm1haWwuYWN0aXZpdHkubWl4aW4iLAogICAgICAgICJjeC50b3dlci52YXVsdC5taXhpbiIsCiAgICAgICAgImN4LnRvd2VyLnRhZy5taXhpbiIsCiAgICBdCiAgICBfZGVzY3JpcHRpb24gPSAiQ2V0bWl4IFRvd2VyIFNlcnZlciIKICAgIF9vcmRlciA9ICJuYW1lIGFzYyIKCiAgICBTRUNSRVRfRklFTERTID0gWyJzc2hfcGFzc3dvcmQiLCAiaG9zdF9rZXkiXQoKICAgICMgLS0tLSBNYWluCiAgICBhY3RpdmUgPSBmaWVsZHMuQm9vbGVhbihkZWZhdWx0PVRydWUpCiAgICBjb2xvciA9IGZpZWxkcy5JbnRlZ2VyKGhlbHA9IkZvciBiZXR0ZXIgdmlzdWFsaXphdGlvbiBpbiB2aWV3cyIpCiAgICBwYXJ0bmVyX2lkID0gZmllbGRzLk1hbnkyb25lKGNvbW9kZWxfbmFtZT0icmVzLnBhcnRuZXIiKQogICAgc3RhdHVzID0gZmllbGRzLlNlbGVjdGlvbigKICAgICAgICBzZWxlY3Rpb249bGFtYmRhIHNlbGY6IHNlbGYuX3NlbGVjdGlvbl9zdGF0dXMoKSwKICAgICAgICBkZWZhdWx0PU5vbmUsCiAgICAgICAgcmVxdWlyZWQ9RmFsc2UsCiAgICApCgogICAgIyAtLS0tIENvbm5lY3Rpb24KICAgIGlwX3Y0X2FkZHJlc3MgPSBmaWVsZHMuQ2hhcigKICAgICAgICBzdHJpbmc9IklQdjQgQWRkcmVzcyIsIGdyb3Vwcz0iY2V0bWl4X3Rvd2VyX3NlcnZlci5ncm91cF9tYW5hZ2VyIgogICAgKQogICAgaXBfdjZfYWRkcmVzcyA9IGZpZWxkcy5DaGFyKAogICAgICAgIHN0cmluZz0iSVB2NiBBZGRyZXNzIiwgZ3JvdXBzPSJjZXRtaXhfdG93ZXJfc2VydmVyLmdyb3VwX21hbmFnZXIiCiAgICApCiAgICBza2lwX2hvc3Rfa2V5ID0gZmllbGRzLkJvb2xlYW4oCiAgICAgICAgZGVmYXVsdD1GYWxzZSwKICAgICAgICBoZWxwPSJFbmFibGUgdG8gc2tpcCBob3N0IGtleSB2ZXJpZmljYXRpb24iLAogICAgKQogICAgaG9zdF9rZXkgPSBmaWVsZHMuQ2hhcigKICAgICAgICBncm91cHM9ImNldG1peF90b3dlcl9zZXJ2ZXIuZ3JvdXBfbWFuYWdlciIsCiAgICAgICAgaGVscD0iSG9zdCBrZXkgdG8gdmVyaWZ5IHRoZSBzZXJ2ZXIiLAogICAgKQogICAgc3NoX3BvcnQgPSBmaWVsZHMuSW50ZWdlcigKICAgICAgICBzdHJpbmc9IlNTSCBwb3J0IiwKICAgICAgICByZXF1aXJlZD1UcnVlLAogICAgICAgIGRlZmF1bHQ9MjIsCiAgICAgICAgZ3JvdXBzPSJjZXRtaXhfdG93ZXJfc2VydmVyLmdyb3VwX21hbmFnZXIiLAogICAgKQogICAgc3NoX3VzZXJuYW1lID0gZmllbGRzLkNoYXIoCiAgICAgICAgc3RyaW5nPSJTU0ggVXNlcm5hbWUiLCByZXF1aXJlZD1UcnVlLCBncm91cHM9ImNldG1peF90b3dlcl9zZXJ2ZXIuZ3JvdXBfbWFuYWdlciIKICAgICkKICAgIHNzaF9wYXNzd29yZCA9IGZpZWxkcy5DaGFyKAogICAgICAgIHN0cmluZz0iU1NIIFBhc3N3b3JkIiwKICAgICAgICBncm91cHM9ImNldG1peF90b3dlcl9zZXJ2ZXIuZ3JvdXBfbWFuYWdlciIsCiAgICApCiAgICBzc2hfa2V5X2lkID0gZmllbGRzLk1hbnkyb25lKAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIua2V5IiwKICAgICAgICBzdHJpbmc9IlNTSCBQcml2YXRlIEtleSIsCiAgICAgICAgZG9tYWluPVsoImtleV90eXBlIiwgIj0iLCAiayIpXSwKICAgICAgICBncm91cHM9ImNldG1peF90b3dlcl9zZXJ2ZXIuZ3JvdXBfbWFuYWdlciIsCiAgICApCiAgICBzc2hfYXV0aF9tb2RlID0gZmllbGRzLlNlbGVjdGlvbigKICAgICAgICBzdHJpbmc9IlNTSCBBdXRoIE1vZGUiLAogICAgICAgIHNlbGVjdGlvbj1bCiAgICAgICAgICAgICgicCIsICJQYXNzd29yZCIpLAogICAgICAgICAgICAoImsiLCAiS2V5IiksCiAgICAgICAgXSwKICAgICAgICBkZWZhdWx0PSJwIiwKICAgICAgICByZXF1aXJlZD1UcnVlLAogICAgICAgIGdyb3Vwcz0iY2V0bWl4X3Rvd2VyX3NlcnZlci5ncm91cF9tYW5hZ2VyIiwKICAgICkKICAgIHVzZV9zdWRvID0gZmllbGRzLlNlbGVjdGlvbigKICAgICAgICBzdHJpbmc9IlVzZSBzdWRvIiwKICAgICAgICBzZWxlY3Rpb249WygibiIsICJXaXRob3V0IHBhc3N3b3JkIiksICgicCIsICJXaXRoIHBhc3N3b3JkIildLAogICAgICAgIGhlbHA9IlJ1biBjb21tYW5kcyB1c2luZyAnc3VkbycuIExlYXZlIGVtcHR5IGlmICdzdWRvJyBpcyBub3QgbmVlZGVkLiIsCiAgICAgICAgZ3JvdXBzPSJjZXRtaXhfdG93ZXJfc2VydmVyLmdyb3VwX21hbmFnZXIiLAogICAgKQogICAgdXJsID0gZmllbGRzLkNoYXIoCiAgICAgICAgc3RyaW5nPSJVUkwiLCBoZWxwPSJTZXJ2ZXIgd2ViIGludGVyZmFjZSwgZWcgJ2h0dHBzOi8vZG9nZS5leGFtcGxlLmNvbSciCiAgICApCiAgICAjIC0tLS0gVmFyaWFibGVzCiAgICB2YXJpYWJsZV92YWx1ZV9pZHMgPSBmaWVsZHMuT25lMm1hbnkoCiAgICAgICAgaW52ZXJzZV9uYW1lPSJzZXJ2ZXJfaWQiICAjIE90aGVyIGZpZWxkIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgaW4gbWl4aW4KICAgICkKCiAgICAjIC0tLS0gS2V5cwogICAgc2VjcmV0X2lkcyA9IGZpZWxkcy5PbmUybWFueSgKICAgICAgICBzdHJpbmc9IlNlY3JldHMiLAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIua2V5LnZhbHVlIiwKICAgICAgICBpbnZlcnNlX25hbWU9InNlcnZlcl9pZCIsCiAgICAgICAgZ3JvdXBzPSJjZXRtaXhfdG93ZXJfc2VydmVyLmdyb3VwX21hbmFnZXIiLAogICAgKQoKICAgICMgLS0tLSBBdHRyaWJ1dGVzCiAgICBvc19pZCA9IGZpZWxkcy5NYW55Mm9uZSgKICAgICAgICBzdHJpbmc9Ik9wZXJhdGluZyBTeXN0ZW0iLAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIub3MiLAogICAgICAgIGdyb3Vwcz0iY2V0bWl4X3Rvd2VyX3NlcnZlci5ncm91cF9tYW5hZ2VyIiwKICAgICkKICAgIHRhZ19pZHMgPSBmaWVsZHMuTWFueTJtYW55KAogICAgICAgIHJlbGF0aW9uPSJjeF90b3dlcl9zZXJ2ZXJfdGFnX3JlbCIsCiAgICAgICAgY29sdW1uMT0ic2VydmVyX2lkIiwKICAgICAgICBjb2x1bW4yPSJ0YWdfaWQiLAogICAgKQogICAgbm90ZSA9IGZpZWxkcy5UZXh0KCkKICAgIGNvbW1hbmRfbG9nX2lkcyA9IGZpZWxkcy5PbmUybWFueSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmNvbW1hbmQubG9nIiwgaW52ZXJzZV9uYW1lPSJzZXJ2ZXJfaWQiCiAgICApCiAgICBwbGFuX2xvZ19pZHMgPSBmaWVsZHMuT25lMm1hbnkoCiAgICAgICAgY29tb2RlbF9uYW1lPSJjeC50b3dlci5wbGFuLmxvZyIsIGludmVyc2VfbmFtZT0ic2VydmVyX2lkIgogICAgKQogICAgZmlsZV9pZHMgPSBmaWVsZHMuT25lMm1hbnkoCiAgICAgICAgImN4LnRvd2VyLmZpbGUiLAogICAgICAgICJzZXJ2ZXJfaWQiLAogICAgICAgIHN0cmluZz0iRmlsZXMiLAogICAgKQogICAgZmlsZV9jb3VudCA9IGZpZWxkcy5JbnRlZ2VyKAogICAgICAgICJUb3RhbCBGaWxlcyIsCiAgICAgICAgY29tcHV0ZT0iX2NvbXB1dGVfY291bnRlcnMiLAogICAgKQoKICAgICMgLS0tLSBTZXJ2ZXIgbG9ncwogICAgc2VydmVyX2xvZ19pZHMgPSBmaWVsZHMuT25lMm1hbnkoCiAgICAgICAgc3RyaW5nPSJTZXJ2ZXIgTG9ncyIsCiAgICAgICAgY29tb2RlbF9uYW1lPSJjeC50b3dlci5zZXJ2ZXIubG9nIiwKICAgICAgICBpbnZlcnNlX25hbWU9InNlcnZlcl9pZCIsCiAgICApCgogICAgIyAtLS0tIFJlbGF0ZWQgc2VydmVyIHRlbXBsYXRlCiAgICBzZXJ2ZXJfdGVtcGxhdGVfaWQgPSBmaWVsZHMuTWFueTJvbmUoCiAgICAgICAgImN4LnRvd2VyLnNlcnZlci50ZW1wbGF0ZSIsCiAgICAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgICAgICBpbmRleD1UcnVlLAogICAgKQoKICAgICMgLS0tLSBEZWxldGUgcGxhbgogICAgcGxhbl9kZWxldGVfaWQgPSBmaWVsZHMuTWFueTJvbmUoCiAgICAgICAgImN4LnRvd2VyLnBsYW4iLAogICAgICAgIHN0cmluZz0iT24gRGVsZXRlIFBsYW4iLAogICAgICAgIGdyb3Vwcz0iY2V0bWl4X3Rvd2VyX3NlcnZlci5ncm91cF9tYW5hZ2VyIiwKICAgICAgICBoZWxwPSJUaGlzIEZsaWdodHBsYW4gd2lsbCBiZSBydW4gd2hlbiB0aGUgc2VydmVyIGlzIGRlbGV0ZWQiLAogICAgKQoKICAgICMgLS0tLSBKZXRzCiAgICBqZXRfdGVtcGxhdGVfaWRzID0gZmllbGRzLk1hbnkybWFueSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmpldC50ZW1wbGF0ZSIsCiAgICAgICAgcmVsYXRpb249ImN4X3Rvd2VyX2pldF90ZW1wbGF0ZV9zZXJ2ZXJfcmVsIiwKICAgICAgICBjb2x1bW4xPSJzZXJ2ZXJfaWQiLAogICAgICAgIGNvbHVtbjI9ImpldF90ZW1wbGF0ZV9pZCIsCiAgICAgICAgc3RyaW5nPSJJbnN0YWxsZWQgSmV0IFRlbXBsYXRlcyIsCiAgICAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgICAgICBjb3B5PUZhbHNlLAogICAgKQogICAgamV0X3RlbXBsYXRlX2NvdW50ID0gZmllbGRzLkludGVnZXIoCiAgICAgICAgY29tcHV0ZT0iX2NvbXB1dGVfY291bnRlcnMiLAogICAgKQogICAgamV0X2lkcyA9IGZpZWxkcy5PbmUybWFueSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmpldCIsCiAgICAgICAgaW52ZXJzZV9uYW1lPSJzZXJ2ZXJfaWQiLAogICAgICAgIHN0cmluZz0iSmV0cyIsCiAgICAgICAgY29weT1GYWxzZSwKICAgICkKICAgIGpldF9jb3VudCA9IGZpZWxkcy5JbnRlZ2VyKAogICAgICAgIGNvbXB1dGU9Il9jb21wdXRlX2NvdW50ZXJzIiwKICAgICkKCiAgICAjIC0tLS0gQWNjZXNzLiBBZGQgcmVsYXRpb24gZm9yIG1peGluIGZpZWxkcwoKICAgIHVzZXJfaWRzID0gZmllbGRzLk1hbnkybWFueSgKICAgICAgICByZWxhdGlvbj0iY3hfdG93ZXJfc2VydmVyX3VzZXJfcmVsIiwKICAgICkKICAgIG1hbmFnZXJfaWRzID0gZmllbGRzLk1hbnkybWFueSgKICAgICAgICByZWxhdGlvbj0iY3hfdG93ZXJfc2VydmVyX21hbmFnZXJfcmVsIiwKICAgICkKCiAgICAjIC0tLS0gU2hvcnRjdXRzCiAgICBzaG9ydGN1dF9pZHMgPSBmaWVsZHMuTWFueTJtYW55KAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIuc2hvcnRjdXQiLAogICAgICAgIHJlbGF0aW9uPSJjeF90b3dlcl9zZXJ2ZXJfc2hvcnRjdXRfcmVsIiwKICAgICAgICBjb2x1bW4xPSJzZXJ2ZXJfaWQiLAogICAgICAgIGNvbHVtbjI9InNob3J0Y3V0X2lkIiwKICAgICAgICBzdHJpbmc9IlNob3J0Y3V0cyIsCiAgICApCgogICAgIyAtLS0tIFNjaGVkdWxlZCBUYXNrcwogICAgc2NoZWR1bGVkX3Rhc2tfaWRzID0gZmllbGRzLk1hbnkybWFueSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLnNjaGVkdWxlZC50YXNrIiwKICAgICAgICByZWxhdGlvbj0iY3hfdG93ZXJfc2NoZWR1bGVkX3Rhc2tfc2VydmVyX3JlbCIsCiAgICAgICAgY29sdW1uMT0ic2VydmVyX2lkIiwKICAgICAgICBjb2x1bW4yPSJzY2hlZHVsZWRfdGFza19pZCIsCiAgICAgICAgc3RyaW5nPSJTY2hlZHVsZWQgVGFza3MiLAogICAgKQoKICAgIGNvbW1hbmRfaWRzID0gZmllbGRzLk1hbnkybWFueSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmNvbW1hbmQiLAogICAgICAgIHJlbGF0aW9uPSJjeF90b3dlcl9zZXJ2ZXJfY29tbWFuZF9yZWwiLAogICAgICAgIGNvbHVtbjE9InNlcnZlcl9pZCIsCiAgICAgICAgY29sdW1uMj0iY29tbWFuZF9pZCIsCiAgICAgICAgc3RyaW5nPSJDb21tYW5kcyIsCiAgICApCgogICAgcGxhbl9pZHMgPSBmaWVsZHMuTWFueTJtYW55KAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIucGxhbiIsCiAgICAgICAgcmVsYXRpb249ImN4X3Rvd2VyX3BsYW5fY3hfdG93ZXJfc2VydmVyX3JlbCIsCiAgICAgICAgY29sdW1uMT0iY3hfdG93ZXJfc2VydmVyX2lkIiwKICAgICAgICBjb2x1bW4yPSJjeF90b3dlcl9wbGFuX2lkIiwKICAgICAgICBzdHJpbmc9IkZsaWdodCBQbGFucyIsCiAgICApCgogICAgZGVmIF9zZWxlY3Rpb25fc3RhdHVzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFN0YXR1cyBzZWxlY3Rpb24gb3B0aW9ucwoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBsaXN0OiBzdGF0dXMgc2VsZWN0aW9uIG9wdGlvbnMKICAgICAgICAiIiIKICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAoInN0b3BwZWQiLCAiU3RvcHBlZCIpLAogICAgICAgICAgICAoInN0YXJ0aW5nIiwgIlN0YXJ0aW5nIiksCiAgICAgICAgICAgICgicnVubmluZyIsICJSdW5uaW5nIiksCiAgICAgICAgICAgICgic3RvcHBpbmciLCAiU3RvcHBpbmciKSwKICAgICAgICAgICAgKCJyZXN0YXJ0aW5nIiwgIlJlc3RhcnRpbmciKSwKICAgICAgICAgICAgKCJkZWxldGluZyIsICJEZWxldGluZyIpLAogICAgICAgICAgICAoImRlbGV0ZV9lcnJvciIsICJEZWxldGlvbiBFcnJvciIpLAogICAgICAgIF0KCiAgICAjIC0tLS0gQ29tcHV0ZWQgZmllbGRzCiAgICBkZWYgX2NvbXB1dGVfY291bnRlcnMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ29tcHV0ZSB0b3RhbCBqZXQgdGVtcGxhdGUsIGpldHMgYW5kIGZpbGVzIGluc3RhbGxlZCBvbiBzZXJ2ZXIKICAgICAgICBOb3RlOiBhcyBudW1iZXJzIGRlcGVuZCBvbiB0aGUgcmVjb3JkcyB1c2VyIGhhcyBhY2Nlc3MgdG8sCiAgICAgICAgd2UgZG9uJ3Qgc3RvcmUgdGhlIHZhbHVlcy4KICAgICAgICBAZGVwZW5kcyBpcyBub3QgbmVlZGVkIGJlY2F1c2UgdGhleSBhcmUgZGlzcGxheWVkIGluIHRoZSB2aWV3cyBvbmx5CiAgICAgICAgb3IgY29tcHV0ZWQgd2hlbiBhY2Nlc3NlZCBleHBsaWNpdGx5LgogICAgICAgICIiIgogICAgICAgIGZvciBzZXJ2ZXIgaW4gc2VsZjoKICAgICAgICAgICAgc2VydmVyLnVwZGF0ZSgKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAiamV0X3RlbXBsYXRlX2NvdW50IjogbGVuKHNlcnZlci5qZXRfdGVtcGxhdGVfaWRzKSwKICAgICAgICAgICAgICAgICAgICAiamV0X2NvdW50IjogbGVuKHNlcnZlci5qZXRfaWRzKSwKICAgICAgICAgICAgICAgICAgICAiZmlsZV9jb3VudCI6IGxlbihzZXJ2ZXIuZmlsZV9pZHMpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApCgogICAgQGFwaS5jb25zdHJhaW5zKCJpcF92NF9hZGRyZXNzIiwgImlwX3Y2X2FkZHJlc3MiLCAic3NoX2F1dGhfbW9kZSIpCiAgICBkZWYgX2NvbnN0cmFpbnRfc3NoX3NldHRpbmdzKHNlbGYpOgogICAgICAgICIiIkVuc3VyZSBTU0ggc2V0dGluZ3MgYXJlIHZhbGlkLgogICAgICAgIFNldCAnc2tpcF9zc2hfc2V0dGluZ3NfY2hlY2snIGNvbnRleHQga2V5IHRvIHNraXAgdGhlIGNoZWNrcwogICAgICAgICIiIgogICAgICAgICMgU2tpcCB0aGUgY2hlY2sgaWYgY29udGV4dCBrZXkgaXMgc2V0CiAgICAgICAgaWYgc2VsZi5fY29udGV4dC5nZXQoInNraXBfc3NoX3NldHRpbmdzX2NoZWNrIik6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBmb3IgcmVjIGluIHNlbGY6CiAgICAgICAgICAgICMgQ29tYmluZSBhbGwgZXJyb3JzIHRvZ2V0aGVyCiAgICAgICAgICAgIHZhbGlkYXRpb25fZXJyb3JzID0gW10KICAgICAgICAgICAgaWYgbm90IHJlYy5pcF92NF9hZGRyZXNzIGFuZCBub3QgcmVjLmlwX3Y2X2FkZHJlc3M6CiAgICAgICAgICAgICAgICB2YWxpZGF0aW9uX2Vycm9ycy5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAgICAgIlBsZWFzZSBwcm92aWRlIElQdjQgb3IgSVB2NiBhZGRyZXNzIGZvciAlKHNydilzIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3J2PXJlYy5uYW1lLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgaWYgcmVjLnNzaF9hdXRoX21vZGUgPT0gImsiIGFuZCBub3QgcmVjLnNzaF9rZXlfaWQ6CiAgICAgICAgICAgICAgICB2YWxpZGF0aW9uX2Vycm9ycy5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgXygiUGxlYXNlIHByb3ZpZGUgU1NIIEtleSBmb3IgJShzcnYpcyIsIHNydj1yZWMubmFtZSkKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgUmFpc2UgZXJyb3JzIGlmIGFueQogICAgICAgICAgICBpZiB2YWxpZGF0aW9uX2Vycm9yczoKICAgICAgICAgICAgICAgIHZhbGlkYXRpb25fZXJyb3IgPSAiXG4iLmpvaW4odmFsaWRhdGlvbl9lcnJvcnMpCiAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbl9lcnJvcikKCiAgICBAYXBpLm1vZGVsX2NyZWF0ZV9tdWx0aQogICAgZGVmIGNyZWF0ZShzZWxmLCB2YWxzX2xpc3QpOgogICAgICAgICIiIk92ZXJyaWRlIGNyZWF0ZSB0byB2YWxpZGF0ZSBTU0ggcGFzc3dvcmQgYmVmb3JlIHJlY29yZCBjcmVhdGlvbi4iIiIKICAgICAgICAjIFZhbGlkYXRlIFNTSCBwYXNzd29yZCBiZWZvcmUgY3JlYXRpbmcgcmVjb3JkcwogICAgICAgIGlmIG5vdCBzZWxmLl9jb250ZXh0LmdldCgic2tpcF9zc2hfc2V0dGluZ3NfY2hlY2siKToKICAgICAgICAgICAgdmFsaWRhdGlvbl9lcnJvcnMgPSBbXQogICAgICAgICAgICBmb3IgdmFscyBpbiB2YWxzX2xpc3Q6CiAgICAgICAgICAgICAgICBpZiB2YWxzLmdldCgic3NoX2F1dGhfbW9kZSIpID09ICJwIiBhbmQgbm90IHZhbHMuZ2V0KCJzc2hfcGFzc3dvcmQiKToKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJfbmFtZSA9IHZhbHNbIm5hbWUiXQogICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25fZXJyb3JzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgXygiUGxlYXNlIHByb3ZpZGUgU1NIIHBhc3N3b3JkIGZvciAlKHNydilzIiwgc3J2PXNlcnZlcl9uYW1lKQogICAgICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIHZhbGlkYXRpb25fZXJyb3JzOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKCJcbiIuam9pbih2YWxpZGF0aW9uX2Vycm9ycykpCgogICAgICAgIHJldHVybiBzdXBlcigpLmNyZWF0ZSh2YWxzX2xpc3QpCgogICAgZGVmIHVubGluayhzZWxmKToKICAgICAgICAiIiJSdW4gcG9zdC1kZWxldGUgZmxpZ2h0IHBsYW4iIiIKICAgICAgICBzZXJ2ZXJzX3RvX2RlbGV0ZSA9IHNlbGYuZW52WyJjeC50b3dlci5zZXJ2ZXIiXQogICAgICAgIGZsaWdodF9wbGFuX2xvZ19vYmogPSBzZWxmLmVudlsiY3gudG93ZXIucGxhbi5sb2ciXQoKICAgICAgICBmb3Igc2VydmVyIGluIHNlbGY6CiAgICAgICAgICAgICMgSWYgZm9yY2VkLCBubyBkZWxldGUgcGxhbiwgb3IgYWxyZWFkeSBpbiBkZWxldGluZyBzdGF0ZSwKICAgICAgICAgICAgIyBza2lwIHBsYW4gcnVubmluZwogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICBzZWxmLl9jb250ZXh0LmdldCgic2VydmVyX2ZvcmNlX2RlbGV0ZSIpCiAgICAgICAgICAgICAgICBvciBub3Qgc2VydmVyLnBsYW5fZGVsZXRlX2lkCiAgICAgICAgICAgICAgICBvciBzZXJ2ZXIuX2lzX2JlaW5nX2RlbGV0ZWQoKQogICAgICAgICAgICApOgogICAgICAgICAgICAgICAgc2VydmVyc190b19kZWxldGUgfD0gc2VydmVyCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgcGxhbl9sYWJlbCA9IGdlbmVyYXRlX3JhbmRvbV9pZCg0KQogICAgICAgICAgICBzZXJ2ZXIucGxhbl9kZWxldGVfaWQuX3J1bl9zaW5nbGUoCiAgICAgICAgICAgICAgICBzZXJ2ZXI9c2VydmVyLCAqKnsicGxhbl9sb2ciOiB7ImxhYmVsIjogcGxhbl9sYWJlbH19CiAgICAgICAgICAgICkKICAgICAgICAgICAgcGxhbl9sb2cgPSBmbGlnaHRfcGxhbl9sb2dfb2JqLnNlYXJjaCgKICAgICAgICAgICAgICAgIFsKICAgICAgICAgICAgICAgICAgICAoInNlcnZlcl9pZCIsICI9Iiwgc2VydmVyLmlkKSwKICAgICAgICAgICAgICAgICAgICAoInBsYW5faWQiLCAiPSIsIHNlcnZlci5wbGFuX2RlbGV0ZV9pZC5pZCksCiAgICAgICAgICAgICAgICAgICAgKCJsYWJlbCIsICI9IiwgcGxhbl9sYWJlbCksCiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgSWYgcGxhbiBoYXMgZmluaXNoZWQsIGVpdGhlciBtYXJrIGZvciBkZWxldGlvbiBvciBzZXQgYW4gZXJyb3IKICAgICAgICAgICAgaWYgcGxhbl9sb2cgYW5kIHBsYW5fbG9nLmZpbmlzaF9kYXRlOgogICAgICAgICAgICAgICAgaWYgcGxhbl9sb2cucGxhbl9zdGF0dXMgPT0gMDoKICAgICAgICAgICAgICAgICAgICBzZXJ2ZXJzX3RvX2RlbGV0ZSB8PSBzZXJ2ZXIKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VydmVyLnN0YXR1cyA9ICJkZWxldGVfZXJyb3IiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFBsYW4gc3RpbGwgaW4gcHJvZ3Jlc3MKICAgICAgICAgICAgICAgIHNlcnZlci5zdGF0dXMgPSAiZGVsZXRpbmciCgogICAgICAgIHJldHVybiBzdXBlcihDeFRvd2VyU2VydmVyLCBzZXJ2ZXJzX3RvX2RlbGV0ZSkudW5saW5rKCkKCiAgICBAYXBpLnJldHVybnMoInNlbGYiLCBsYW1iZGEgdmFsdWU6IHZhbHVlLmlkKQogICAgZGVmIGNvcHkoc2VsZiwgZGVmYXVsdD1Ob25lKToKICAgICAgICBkZWZhdWx0ID0gZGVmYXVsdCBvciB7fQogICAgICAgIGRlZmF1bHRbInN0YXR1cyJdID0gTm9uZQoKICAgICAgICBmaWxlX2lkcyA9IHNlbGYuZW52WyJjeC50b3dlci5maWxlIl0KICAgICAgICBmb3IgZmlsZSBpbiBzZWxmLmZpbGVfaWRzOgogICAgICAgICAgICBmaWxlX2lkcyB8PSBmaWxlLmNvcHkoCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgImF1dG9fc3luYyI6IEZhbHNlLAogICAgICAgICAgICAgICAgICAgICJrZWVwX3doZW5fZGVsZXRlZCI6IFRydWUsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkKICAgICAgICBkZWZhdWx0WyJmaWxlX2lkcyJdID0gZmlsZV9pZHMuaWRzCgogICAgICAgICMgQ29weSBTU0ggcGFzc3dvcmQgYW5kIGhvc3Qga2V5CiAgICAgICAgZGVmYXVsdFsic3NoX3Bhc3N3b3JkIl0gPSBzZWxmLl9nZXRfc2VjcmV0X3ZhbHVlKCJzc2hfcGFzc3dvcmQiKQogICAgICAgIGRlZmF1bHRbImhvc3Rfa2V5Il0gPSBzZWxmLl9nZXRfc2VjcmV0X3ZhbHVlKCJob3N0X2tleSIpCiAgICAgICAgcmVzdWx0ID0gc3VwZXIoKS5jb3B5KGRlZmF1bHQ9ZGVmYXVsdCkKCiAgICAgICAgIyBDb3B5IHNlcnZlciBzZWNyZXRzCiAgICAgICAgZm9yIHNlY3JldCBpbiBzZWxmLnNlY3JldF9pZHM6CiAgICAgICAgICAgIHNlY3JldC5zdWRvKCkuY29weSh7InNlcnZlcl9pZCI6IHJlc3VsdC5pZH0pCgogICAgICAgIGZvciB2YXJfdmFsdWUgaW4gc2VsZi52YXJpYWJsZV92YWx1ZV9pZHM6CiAgICAgICAgICAgICMgRHVwbGljYXRpbmcgYSBzZXJ2ZXIgd2l0aCB2YXJpYWJsZSB2YWx1ZXMgYW5kIHRoZW4gZHVwbGljYXRpbmcgdGhlCiAgICAgICAgICAgICMgZHVwbGljYXRlIGNhdXNlcyBhIHVuaXF1ZW5lc3MgY29uc3RyYWludCBlcnJvciBmb3IgdGhlICdyZWZlcmVuY2UnIGZpZWxkCiAgICAgICAgICAgICMgaW4gJ2N4LnRvd2VyLnZhcmlhYmxlLnZhbHVlJy4gVGhpcyBoYXBwZW5zIGJlY2F1c2UgJ3JlZmVyZW5jZScgaXMKICAgICAgICAgICAgIyBnZW5lcmF0ZWQgZnJvbSB0aGUgJ25hbWUnIGZpZWxkLCB3aGljaCBpcyBhIHJlbGF0ZWQgZmllbGQgIGZldGNoaW5nIHRoZQogICAgICAgICAgICAjIHNhbWUgdmFsdWUgYWNyb3NzIGR1cGxpY2F0aW9ucy4gVG8gYXZvaWQgdGhpcywgd2UgcGFzcyB0aGUgZXhpc3RpbmcKICAgICAgICAgICAgIyAncmVmZXJlbmNlJyBhcyAnbmFtZScgZHVyaW5nIGR1cGxpY2F0aW9uLCBlbnN1cmluZyB1bmlxdWUgJ3JlZmVyZW5jZScKICAgICAgICAgICAgIyBnZW5lcmF0aW9uIGZvciBlYWNoIGNvcHkuCiAgICAgICAgICAgIHZhcl92YWx1ZS5jb3B5KHsic2VydmVyX2lkIjogcmVzdWx0LmlkLCAibmFtZSI6IHZhcl92YWx1ZS5yZWZlcmVuY2V9KQoKICAgICAgICBmb3Igc2VydmVyX2xvZyBpbiBzZWxmLnNlcnZlcl9sb2dfaWRzOgogICAgICAgICAgICBzZXJ2ZXJfbG9nLmNvcHkoeyJzZXJ2ZXJfaWQiOiByZXN1bHQuaWR9KQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLSBBY3Rpb25zCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIEBjaGVja19pZGVudGl0eQogICAgZGVmIGFjdGlvbl9zaG93X2hvc3Rfa2V5KHNlbGYpOgogICAgICAgICIiIlNob3cgaG9zdCBrZXkiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIHRyeToKICAgICAgICAgICAgaG9zdF9rZXkgPSBzZWxmLl9nZXRfaG9zdF9rZXlfZnJvbV9ob3N0KCkKICAgICAgICAgICAgaXNfZXJyb3IgPSBGYWxzZQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZXJyb3I6CiAgICAgICAgICAgIGlzX2Vycm9yID0gVHJ1ZQogICAgICAgICAgICBob3N0X2tleSA9IGVycm9yCiAgICAgICAgY29udGV4dCA9IHsKICAgICAgICAgICAgImRlZmF1bHRfaG9zdF9rZXkiOiBob3N0X2tleSwKICAgICAgICAgICAgImRlZmF1bHRfaXNfZXJyb3IiOiBpc19lcnJvciwKICAgICAgICAgICAgImRlZmF1bHRfc2VydmVyX2lkIjogc2VsZi5pZCwKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInR5cGUiOiAiaXIuYWN0aW9ucy5hY3Rfd2luZG93IiwKICAgICAgICAgICAgIm5hbWUiOiBfKCJIb3N0IEtleSIpLAogICAgICAgICAgICAicmVzX21vZGVsIjogImN4LnRvd2VyLnNlcnZlci5ob3N0LmtleS53aXphcmQiLAogICAgICAgICAgICAidmlld19tb2RlIjogImZvcm0iLAogICAgICAgICAgICAidGFyZ2V0IjogIm5ldyIsCiAgICAgICAgICAgICJjb250ZXh0IjogY29udGV4dCwKICAgICAgICB9CgogICAgZGVmIGFjdGlvbl91cGRhdGVfc2VydmVyX2xvZ3Moc2VsZik6CiAgICAgICAgIiIiVXBkYXRlIHNlbGVjdGVkIGxvZyBmcm9tIGl0cyBzb3VyY2UuIiIiCiAgICAgICAgZm9yIHNlcnZlciBpbiBzZWxmOgogICAgICAgICAgICBpZiBzZXJ2ZXIuc2VydmVyX2xvZ19pZHM6CiAgICAgICAgICAgICAgICBzZXJ2ZXIuc2VydmVyX2xvZ19pZHMuYWN0aW9uX3VwZGF0ZV9sb2coKQoKICAgIGRlZiBhY3Rpb25fb3Blbl9jb21tYW5kX2xvZ3Moc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgT3BlbiBjdXJyZW50IHNlcnZlciBjb21tYW5kIGxvZyByZWNvcmRzCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBhY3Rpb24gPSBzZWxmLmVudlsiaXIuYWN0aW9ucy5hY3Rpb25zIl0uX2Zvcl94bWxfaWQoCiAgICAgICAgICAgICJjZXRtaXhfdG93ZXJfc2VydmVyLmFjdGlvbl9jeF90b3dlcl9jb21tYW5kX2xvZyIKICAgICAgICApCiAgICAgICAgYWN0aW9uWyJkb21haW4iXSA9IFsoInNlcnZlcl9pZCIsICI9Iiwgc2VsZi5pZCldICAjIHB5bGludDogZGlzYWJsZT1uby1tZW1iZXIKICAgICAgICByZXR1cm4gYWN0aW9uCgogICAgZGVmIGFjdGlvbl9vcGVuX3BsYW5fbG9ncyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBPcGVuIGN1cnJlbnQgc2VydmVyIGZsaWdodHBsYW4gbG9nIHJlY29yZHMKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIGFjdGlvbiA9IHNlbGYuZW52WyJpci5hY3Rpb25zLmFjdGlvbnMiXS5fZm9yX3htbF9pZCgKICAgICAgICAgICAgImNldG1peF90b3dlcl9zZXJ2ZXIuYWN0aW9uX2N4X3Rvd2VyX3BsYW5fbG9nIgogICAgICAgICkKICAgICAgICBhY3Rpb25bImRvbWFpbiJdID0gWygic2VydmVyX2lkIiwgIj0iLCBzZWxmLmlkKV0gICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgIHJldHVybiBhY3Rpb24KCiAgICBkZWYgYWN0aW9uX3J1bl9jb21tYW5kKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJldHVybnMgd2l6YXJkIGFjdGlvbiB0byBzZWxlY3QgY29tbWFuZCBhbmQgcnVuIGl0CiAgICAgICAgIiIiCiAgICAgICAgY29udGV4dCA9IHNlbGYuZW52LmNvbnRleHQuY29weSgpCiAgICAgICAgY29udGV4dC51cGRhdGUoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJkZWZhdWx0X3NlcnZlcl9pZHMiOiBzZWxmLmlkcywKICAgICAgICAgICAgfQogICAgICAgICkKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAidHlwZSI6ICJpci5hY3Rpb25zLmFjdF93aW5kb3ciLAogICAgICAgICAgICAibmFtZSI6IF8oIlJ1biBDb21tYW5kIiksCiAgICAgICAgICAgICJyZXNfbW9kZWwiOiAiY3gudG93ZXIuY29tbWFuZC5ydW4ud2l6YXJkIiwKICAgICAgICAgICAgInZpZXdfbW9kZSI6ICJmb3JtIiwKICAgICAgICAgICAgInRhcmdldCI6ICJuZXciLAogICAgICAgICAgICAiY29udGV4dCI6IGNvbnRleHQsCiAgICAgICAgfQoKICAgIGRlZiBhY3Rpb25fcnVuX2ZsaWdodF9wbGFuKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJldHVybnMgd2l6YXJkIGFjdGlvbiB0byBzZWxlY3QgZmxpZ2h0cGxhbiBhbmQgcnVuIGl0CiAgICAgICAgIiIiCiAgICAgICAgY29udGV4dCA9IHNlbGYuZW52LmNvbnRleHQuY29weSgpCiAgICAgICAgY29udGV4dC51cGRhdGUoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJkZWZhdWx0X3NlcnZlcl9pZHMiOiBzZWxmLmlkcywKICAgICAgICAgICAgfQogICAgICAgICkKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAidHlwZSI6ICJpci5hY3Rpb25zLmFjdF93aW5kb3ciLAogICAgICAgICAgICAibmFtZSI6IF8oIlJ1biBGbGlnaHQgUGxhbiIpLAogICAgICAgICAgICAicmVzX21vZGVsIjogImN4LnRvd2VyLnBsYW4ucnVuLndpemFyZCIsCiAgICAgICAgICAgICJ2aWV3X21vZGUiOiAiZm9ybSIsCiAgICAgICAgICAgICJ0YXJnZXQiOiAibmV3IiwKICAgICAgICAgICAgImNvbnRleHQiOiBjb250ZXh0LAogICAgICAgIH0KCiAgICBkZWYgYWN0aW9uX25ld19qZXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgUmV0dXJucyB3aXphcmQgYWN0aW9uIHRvIGxhdW5jaCBhIGpldAogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgY29udGV4dCA9IHNlbGYuZW52LmNvbnRleHQuY29weSgpCiAgICAgICAgY29udGV4dC51cGRhdGUoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJkZWZhdWx0X3NlcnZlcl9pZCI6IHNlbGYuaWQsCiAgICAgICAgICAgIH0KICAgICAgICApCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInR5cGUiOiAiaXIuYWN0aW9ucy5hY3Rfd2luZG93IiwKICAgICAgICAgICAgIm5hbWUiOiBfKCJMYXVuY2ggTmV3IEpldCIpLAogICAgICAgICAgICAicmVzX21vZGVsIjogImN4LnRvd2VyLmpldC5jcmVhdGUud2l6YXJkIiwKICAgICAgICAgICAgInZpZXdfbW9kZSI6ICJmb3JtIiwKICAgICAgICAgICAgInRhcmdldCI6ICJuZXciLAogICAgICAgICAgICAiY29udGV4dCI6IGNvbnRleHQsCiAgICAgICAgfQoKICAgIGRlZiBhY3Rpb25fb3Blbl9maWxlcyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBPcGVuIGZpbGVzIG9mIHRoZSBjdXJyZW50IHNlcnZlcgogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgYWN0aW9uID0gc2VsZi5lbnZbImlyLmFjdGlvbnMuYWN0aW9ucyJdLl9mb3JfeG1sX2lkKAogICAgICAgICAgICAiY2V0bWl4X3Rvd2VyX3NlcnZlci5jeF90b3dlcl9maWxlX2FjdGlvbiIKICAgICAgICApCiAgICAgICAgYWN0aW9uWyJkb21haW4iXSA9IFsoInNlcnZlcl9pZCIsICI9Iiwgc2VsZi5pZCldICAjIHB5bGludDogZGlzYWJsZT1uby1tZW1iZXIKCiAgICAgICAgY29udGV4dCA9IHNlbGYuX2NvbnRleHQuY29weSgpCiAgICAgICAgaWYgImNvbnRleHQiIGluIGFjdGlvbiBhbmQgaXNpbnN0YW5jZSgoYWN0aW9uWyJjb250ZXh0Il0pLCBzdHIpOgogICAgICAgICAgICBjb250ZXh0LnVwZGF0ZShhc3QubGl0ZXJhbF9ldmFsKGFjdGlvblsiY29udGV4dCJdKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBjb250ZXh0LnVwZGF0ZShhY3Rpb24uZ2V0KCJjb250ZXh0Iiwge30pKQoKICAgICAgICBjb250ZXh0LnVwZGF0ZSgKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImRlZmF1bHRfc2VydmVyX2lkIjogc2VsZi5pZCwgICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgICAgICB9CiAgICAgICAgKQogICAgICAgIGFjdGlvblsiY29udGV4dCJdID0gY29udGV4dAogICAgICAgIHJldHVybiBhY3Rpb24KCiAgICBkZWYgYWN0aW9uX29wZW5famV0cyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBPcGVuIGpldHMgb2YgdGhlIGN1cnJlbnQgc2VydmVyCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBhY3Rpb24gPSBzZWxmLmVudlsiaXIuYWN0aW9ucy5hY3Rpb25zIl0uX2Zvcl94bWxfaWQoCiAgICAgICAgICAgICJjZXRtaXhfdG93ZXJfc2VydmVyLmN4X3Rvd2VyX2pldF9hY3Rpb24iCiAgICAgICAgKQogICAgICAgIGFjdGlvblsiZG9tYWluIl0gPSBbKCJzZXJ2ZXJfaWQiLCAiPSIsIHNlbGYuaWQpXSAgIyBweWxpbnQ6IGRpc2FibGU9bm8tbWVtYmVyCgogICAgICAgIGNvbnRleHQgPSBzZWxmLl9jb250ZXh0LmNvcHkoKQogICAgICAgIGlmICJjb250ZXh0IiBpbiBhY3Rpb24gYW5kIGlzaW5zdGFuY2UoKGFjdGlvblsiY29udGV4dCJdKSwgc3RyKToKICAgICAgICAgICAgY29udGV4dC51cGRhdGUoYXN0LmxpdGVyYWxfZXZhbChhY3Rpb25bImNvbnRleHQiXSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgY29udGV4dC51cGRhdGUoYWN0aW9uLmdldCgiY29udGV4dCIsIHt9KSkKCiAgICAgICAgY29udGV4dC51cGRhdGUoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJkZWZhdWx0X3NlcnZlcl9pZCI6IHNlbGYuaWQsICAjIHB5bGludDogZGlzYWJsZT1uby1tZW1iZXIKICAgICAgICAgICAgfQogICAgICAgICkKICAgICAgICBhY3Rpb25bImNvbnRleHQiXSA9IGNvbnRleHQKICAgICAgICByZXR1cm4gYWN0aW9uCgogICAgZGVmIGFjdGlvbl9pbnN0YWxsX2pldF90ZW1wbGF0ZShzZWxmKToKICAgICAgICAiIiJBY3Rpb24gdG8gaW5zdGFsbCB0aGUgSmV0IFRlbXBsYXRlIG9uIHRoZSBzZWxlY3RlZCBzZXJ2ZXJzLiIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgIyBPcGVuIHRoZSB3aXphcmQgdG8gaW5zdGFsbCB0aGUgdGVtcGxhdGUgb24gdGhlIHNlbGVjdGVkIHNlcnZlcnMKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAidHlwZSI6ICJpci5hY3Rpb25zLmFjdF93aW5kb3ciLAogICAgICAgICAgICAibmFtZSI6IF8oIkluc3RhbGwgSmV0IFRlbXBsYXRlIiksCiAgICAgICAgICAgICJyZXNfbW9kZWwiOiAiY3gudG93ZXIuamV0LnRlbXBsYXRlLmluc3RhbGwud2l6IiwKICAgICAgICAgICAgInZpZXdfbW9kZSI6ICJmb3JtIiwKICAgICAgICAgICAgInRhcmdldCI6ICJuZXciLAogICAgICAgICAgICAiY29udGV4dCI6IHsKICAgICAgICAgICAgICAgICJkZWZhdWx0X3NlcnZlcl9pZHMiOiBzZWxmLmlkcywgICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgICAgICB9LAogICAgICAgIH0KCiAgICBkZWYgYWN0aW9uX3VuaW5zdGFsbF9qZXRfdGVtcGxhdGUoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVW5pbnN0YWxsIGpldCB0ZW1wbGF0ZSBmcm9tIHRoZSBjdXJyZW50IHNlcnZlcgogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgamV0X3RlbXBsYXRlX2lkID0gc2VsZi5lbnYuY29udGV4dC5nZXQoImpldF90ZW1wbGF0ZV9pZCIpCiAgICAgICAgaWYgamV0X3RlbXBsYXRlX2lkIGFuZCBqZXRfdGVtcGxhdGVfaWQgaW4gc2VsZi5qZXRfdGVtcGxhdGVfaWRzLmlkczoKICAgICAgICAgICAgamV0X3RlbXBsYXRlID0gc2VsZi5lbnZbImN4LnRvd2VyLmpldC50ZW1wbGF0ZSJdLmJyb3dzZShqZXRfdGVtcGxhdGVfaWQpCiAgICAgICAgICAgIGlmIGpldF90ZW1wbGF0ZToKICAgICAgICAgICAgICAgIGpldF90ZW1wbGF0ZS51bmluc3RhbGxfZnJvbV9zZXJ2ZXJzKHNlbGYpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLSBDb25uZWN0aXZpdHkKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZGVmIF9nZXRfc3NoX2NsaWVudChzZWxmLCByYWlzZV9vbl9lcnJvcj1GYWxzZSwgdGltZW91dD01MDAwLCBza2lwX2hvc3Rfa2V5PUZhbHNlKToKICAgICAgICAiIiJDcmVhdGUgYSBuZXcgU1NIIGNsaWVudCBpbnN0YW5jZQoKICAgICAgICBBcmdzOgogICAgICAgICAgICByYWlzZV9vbl9lcnJvciAoYm9vbCwgb3B0aW9uYWwpOiBJZiB0cnVlIHdpbGwgcmFpc2UgZXhjZXB0aW9uCiAgICAgICAgICAgICBpbiBjYXNlIG9yIGVycm9yLCBvdGhlcndpc2UgRmFsc2Ugd2lsbCBiZSByZXR1cm5lZAogICAgICAgICAgICBEZWZhdWx0cyB0byBUcnVlLgogICAgICAgICAgICB0aW1lb3V0IChpbnQsIG9wdGlvbmFsKTogU1NIIGNvbm5lY3Rpb24gdGltZW91dCBpbiBzZWNvbmRzLgogICAgICAgICAgICBza2lwX2hvc3Rfa2V5IChib29sLCBvcHRpb25hbCk6IElmIHRydWUgd2lsbCBza2lwIGhvc3Qga2V5IHZlcmlmaWNhdGlvbi4KICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIEZhbHNlLgoKICAgICAgICBSYWlzZXM6CiAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvcjogSWYgdGhlIHByb3ZpZGVkIHNlcnZlciByZWZlcmVuY2UgaXMgaW52YWxpZCBvcgogICAgICAgICAgICAgICAgdGhlIHNlcnZlciBjYW5ub3QgYmUgZm91bmQuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIFNTSDogU1NIIG1hbmFnZXIgaW5zdGFuY2Ugb3IgRmFsc2UgYW5kIGV4Y2VwdGlvbiBjb250ZW50CiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBzZWxmID0gc2VsZi5zdWRvKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGhvc3Rfa2V5ID0gc2VsZi5fZ2V0X3NlY3JldF92YWx1ZSgiaG9zdF9rZXkiKQoKICAgICAgICAgICAgIyBDaGVjayBob3N0IG9ubHkgaWYgSVAgYWRkcmVzcyBpcyBwcmVzZW50CiAgICAgICAgICAgIHNraXBfaG9zdF9rZXkgPSBza2lwX2hvc3Rfa2V5IG9yIHNlbGYuc2tpcF9ob3N0X2tleQogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICBub3QgaG9zdF9rZXkKICAgICAgICAgICAgICAgIGFuZCBub3Qgc2tpcF9ob3N0X2tleQogICAgICAgICAgICAgICAgYW5kIChzZWxmLmlwX3Y0X2FkZHJlc3Mgb3Igc2VsZi5pcF92Nl9hZGRyZXNzKQogICAgICAgICAgICApOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAgIF8oIkhvc3Qga2V5IG5vdCBmb3VuZCBmb3Igc2VydmVyICUoc2VydmVyKXMiLCBzZXJ2ZXI9c2VsZi5uYW1lKQogICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgY29ubmVjdGlvbiA9IFNTSENvbm5lY3Rpb24oCiAgICAgICAgICAgICAgICBob3N0PXNlbGYuaXBfdjRfYWRkcmVzcyBvciBzZWxmLmlwX3Y2X2FkZHJlc3MsCiAgICAgICAgICAgICAgICBwb3J0PXNlbGYuc3NoX3BvcnQsCiAgICAgICAgICAgICAgICB1c2VybmFtZT1zZWxmLnNzaF91c2VybmFtZSwKICAgICAgICAgICAgICAgIHBhc3N3b3JkPXNlbGYuX2dldF9zc2hfcGFzc3dvcmQoKSwKICAgICAgICAgICAgICAgIHNzaF9rZXk9c2VsZi5fZ2V0X3NzaF9rZXkoKSwKICAgICAgICAgICAgICAgIGhvc3Rfa2V5PWhvc3Rfa2V5IGlmIGhvc3Rfa2V5IGFuZCBub3Qgc2VsZi5za2lwX2hvc3Rfa2V5IGVsc2UgTm9uZSwKICAgICAgICAgICAgICAgIG1vZGU9c2VsZi5zc2hfYXV0aF9tb2RlLAogICAgICAgICAgICAgICAgdGltZW91dD10aW1lb3V0LAogICAgICAgICAgICApCiAgICAgICAgICAgIGNsaWVudCA9IFNTSE1hbmFnZXIoY29ubmVjdGlvbikKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihfKCJTU0ggY29ubmVjdGlvbiBlcnJvciAlKGVycilzIiwgZXJyPWUpKSBmcm9tIGUKICAgICAgICAgICAgcmV0dXJuIEZhbHNlLCBlCiAgICAgICAgcmV0dXJuIGNsaWVudAoKICAgIGRlZiB0ZXN0X3NzaF9jb25uZWN0aW9uKAogICAgICAgIHNlbGYsCiAgICAgICAgcmFpc2Vfb25fZXJyb3I9VHJ1ZSwKICAgICAgICByZXR1cm5fbm90aWZpY2F0aW9uPVRydWUsCiAgICAgICAgdHJ5X2NvbW1hbmQ9VHJ1ZSwKICAgICAgICB0cnlfZmlsZT1UcnVlLAogICAgICAgIHRpbWVvdXQ9NjAsCiAgICApOgogICAgICAgICIiIlRlc3QgU1NIIGNvbm5lY3Rpb24uCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHJhaXNlX29uX2Vycm9yIChib29sLCBvcHRpb25hbCk6IFJhaXNlIGV4Y2VwdGlvbiBpbiBjYXNlIG9mIGVycm9yLgogICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gVHJ1ZS4KICAgICAgICAgICAgcmV0dXJuX25vdGlmaWNhdGlvbiAoYm9vbCwgb3B0aW9uYWwpOiBTaG93IHN0aWNreSBub3RpZmljYXRpb24KICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIFRydWUuCiAgICAgICAgICAgIHRyeV9jb21tYW5kIChib29sLCBvcHRpb25hbCk6IFRyeSB0byBydW4gYSBjb21tYW5kLgogICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gVHJ1ZS4KICAgICAgICAgICAgdHJ5X2ZpbGUgKGJvb2wsIG9wdGlvbmFsKTogVHJ5IGZpbGUgb3BlcmF0aW9ucy4KICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIFRydWUuCiAgICAgICAgICAgIHRpbWVvdXQgKGludCwgb3B0aW9uYWwpOiBTU0ggY29ubmVjdGlvbiB0aW1lb3V0IGluIHNlY29uZHMuCiAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byA2MC4KCiAgICAgICAgUmFpc2VzOgogICAgICAgICAgICBWYWxpZGF0aW9uRXJyb3I6IEluIGNhc2Ugb2YgU1NIIGNvbm5lY3Rpb24gZXJyb3IuCiAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvcjogSW4gY2FzZSBvZiBubyBvdXRwdXQgcmVjZWl2ZWQuCiAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvcjogSW4gY2FzZSBvZiBmaWxlIG9wZXJhdGlvbnMgZXJyb3IuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IHsKICAgICAgICAgICAgICAgICJzdGF0dXMiOiBpbnQsCiAgICAgICAgICAgICAgICAicmVzcG9uc2UiOiBzdHIsCiAgICAgICAgICAgICAgICAiZXJyb3IiOiBzdHIsCiAgICAgICAgICAgIH0KICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIGNsaWVudCA9IHNlbGYuX2dldF9zc2hfY2xpZW50KHJhaXNlX29uX2Vycm9yPXJhaXNlX29uX2Vycm9yLCB0aW1lb3V0PXRpbWVvdXQpCgogICAgICAgIGlmIG5vdCB0cnlfY29tbWFuZCBhbmQgbm90IHRyeV9maWxlOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBjbGllbnQuY29ubmVjdGlvbi5jb25uZWN0KCkKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6IDAsCiAgICAgICAgICAgICAgICAgICAgInJlc3BvbnNlIjogXygiQ29ubmVjdGlvbiBzdWNjZXNzZnVsLiIpLAogICAgICAgICAgICAgICAgICAgICJlcnJvciI6ICIiLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIF8oIlNTSCBjb25uZWN0aW9uIGVycm9yICUoZXJyKXMiLCBlcnI9ZSkKICAgICAgICAgICAgICAgICAgICApIGZyb20gZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAic3RhdHVzIjogU1NIX0NPTk5FQ1RJT05fRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICJyZXNwb25zZSI6IF8oIkNvbm5lY3Rpb24gZmFpbGVkLiIpLAogICAgICAgICAgICAgICAgICAgICAgICAiZXJyb3IiOiBlLAogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgIyBUcnkgY29tbWFuZAogICAgICAgIGlmIHRyeV9jb21tYW5kOgogICAgICAgICAgICBjb21tYW5kID0gc2VsZi5fZ2V0X2Nvbm5lY3Rpb25fdGVzdF9jb21tYW5kKCkKICAgICAgICAgICAgdGVzdF9yZXN1bHQgPSBzZWxmLl9ydW5fY29tbWFuZF91c2luZ19zc2goCiAgICAgICAgICAgICAgICBjbGllbnQsIGNvbW1hbmRfY29kZT1jb21tYW5kLCAqKnsicmFpc2Vfb25fZXJyb3IiOiByYWlzZV9vbl9lcnJvcn0KICAgICAgICAgICAgKQogICAgICAgICAgICBzdGF0dXMgPSB0ZXN0X3Jlc3VsdC5nZXQoInN0YXR1cyIsIDApCiAgICAgICAgICAgIHJlc3BvbnNlID0gdGVzdF9yZXN1bHQuZ2V0KCJyZXNwb25zZSIsICIiKQogICAgICAgICAgICBlcnJvciA9IHRlc3RfcmVzdWx0LmdldCgiZXJyb3IiLCAiIikKCiAgICAgICAgICAgICMgR290IGFuIGVycm9yCiAgICAgICAgICAgIGlmIHJhaXNlX29uX2Vycm9yIGFuZCAoc3RhdHVzICE9IDAgb3IgZXJyb3IpOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3QgcnVuIGNvbW1hbmRcbi4gQ09ERTogJShzdGF0dXMpcy4gIgogICAgICAgICAgICAgICAgICAgICAgICAiUkVTVUxUOiAlKHJlcylzLiBFUlJPUjogJShlcnIpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cz1zdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlcz1yZXNwb25zZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyPWVycm9yLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgTm8gb3V0cHV0IHJlY2VpdmVkCiAgICAgICAgICAgIGlmIHJhaXNlX29uX2Vycm9yIGFuZCBub3QgcmVzcG9uc2U6CiAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAgICAgIk5vIG91dHB1dCByZWNlaXZlZC4iCiAgICAgICAgICAgICAgICAgICAgICAgICIgUGxlYXNlIGxvZyBpbiBtYW51YWxseSBhbmQgY2hlY2sgZm9yIGFueSBpc3N1ZXMuXG4iCiAgICAgICAgICAgICAgICAgICAgICAgICI9PT1cbkNPREU6ICUoc3RhdHVzKXMiLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCiAgICAgICAgaWYgdHJ5X2ZpbGU6CiAgICAgICAgICAgICMgdGVzdCB1cGxvYWQgZmlsZQogICAgICAgICAgICBzZWxmLnVwbG9hZF9maWxlKCJ0ZXN0IiwgIi90bXAvY2V0bWl4X3Rvd2VyX3Rlc3RfY29ubmVjdGlvbi50eHQiKQoKICAgICAgICAgICAgIyB0ZXN0IGRvd25sb2FkIGxvYWRlZCBmaWxlCiAgICAgICAgICAgIHNlbGYuZG93bmxvYWRfZmlsZSgiL3RtcC9jZXRtaXhfdG93ZXJfdGVzdF9jb25uZWN0aW9uLnR4dCIpCgogICAgICAgICAgICAjIHJlbW92ZSBmaWxlIGZyb20gc2VydmVyCiAgICAgICAgICAgIGZpbGVfdGVzdF9yZXN1bHQgPSBzZWxmLl9ydW5fY29tbWFuZF91c2luZ19zc2goCiAgICAgICAgICAgICAgICBjbGllbnQsIGNvbW1hbmRfY29kZT0icm0gLXJmIC90bXAvY2V0bWl4X3Rvd2VyX3Rlc3RfY29ubmVjdGlvbi50eHQiCiAgICAgICAgICAgICkKICAgICAgICAgICAgZmlsZV9zdGF0dXMgPSBmaWxlX3Rlc3RfcmVzdWx0LmdldCgic3RhdHVzIiwgMCkKICAgICAgICAgICAgZmlsZV9lcnJvciA9IGZpbGVfdGVzdF9yZXN1bHQuZ2V0KCJlcnJvciIsICIiKQoKICAgICAgICAgICAgIyBJbiBjYXNlIG9mIGFuIGVycm9yLCByYWlzZSBvciByZXBsYWNlIGNvbW1hbmQgcmVzdWx0IHdpdGggZmlsZSB0ZXN0IHJlc3VsdAogICAgICAgICAgICBpZiBmaWxlX3N0YXR1cyAhPSAwIG9yIGZpbGVfZXJyb3I6CiAgICAgICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHJlbW92ZSB0ZXN0IGZpbGUgdXNpbmcgY29tbWFuZC5cbiAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ09ERTogJShzdGF0dXMpcy4gRVJST1I6ICUoZXJyKXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyPWZpbGVfZXJyb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM9ZmlsZV9zdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICApCgogICAgICAgICAgICAgICAgIyBSZXBsYWNlIGNvbW1hbmQgcmVzdWx0IHdpdGggZmlsZSB0ZXN0IHJlc3VsdAogICAgICAgICAgICAgICAgdGVzdF9yZXN1bHQgPSBmaWxlX3Rlc3RfcmVzdWx0CgogICAgICAgICMgUmV0dXJuIG5vdGlmaWNhdGlvbgogICAgICAgIGlmIHJldHVybl9ub3RpZmljYXRpb246CiAgICAgICAgICAgIHJlc3BvbnNlID0gdGVzdF9yZXN1bHQuZ2V0KCJyZXNwb25zZSIsICIiKQogICAgICAgICAgICByZXR1cm4gc2VsZi5fZ2V0X25vdGlmaWNhdGlvbl9hY3Rpb24oCiAgICAgICAgICAgICAgICBfKAogICAgICAgICAgICAgICAgICAgICJDb25uZWN0aW9uIHRlc3QgcGFzc2VkISBcbiUocmVzKXMiLAogICAgICAgICAgICAgICAgICAgIHJlcz1yZXNwb25zZS5yc3RyaXAoKSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICBub3RpZmljYXRpb25fdHlwZT0iaW5mbyIsCiAgICAgICAgICAgICAgICB0aXRsZT1fKCJTdWNjZXNzIiksCiAgICAgICAgICAgICAgICBzdGlja3k9RmFsc2UsCiAgICAgICAgICAgICkKCiAgICAgICAgcmV0dXJuIHRlc3RfcmVzdWx0CgogICAgZGVmIF9nZXRfY29ubmVjdGlvbl90ZXN0X2NvbW1hbmQoc2VsZik6CiAgICAgICAgIiIiR2V0IGNvbW1hbmQgdXNlZCB0byB0ZXN0IFNTSCBjb25uZWN0aW9uCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIENoYXI6IFNTSCBjb21tYW5kCiAgICAgICAgIiIiCiAgICAgICAgY29tbWFuZCA9ICJ1bmFtZSAtYSIKICAgICAgICByZXR1cm4gY29tbWFuZAoKICAgIGRlZiBfZ2V0X3NzaF9wYXNzd29yZChzZWxmKToKICAgICAgICAiIiJHZXQgc3NoIHBhc3N3b3JkCiAgICAgICAgVGhpcyBmdW5jdGlvbiBwcmVwYXJlcyBhbmQgcmV0dXJucyBzc2ggcGFzc3dvcmQgZm9yIHRoZSBzc2ggY29ubmVjdGlvbgogICAgICAgIE92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gdG8gaW1wbGVtZW50IG93biBwYXNzd29yZCBhbGdvcml0aG1zCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIENoYXI6IHBhc3N3b3JkIHJlYWR5IHRvIGJlIHVzZWQgZm9yIGNvbm5lY3Rpb24gcGFyYW1ldGVycwogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgcGFzc3dvcmQgPSBzZWxmLl9nZXRfc2VjcmV0X3ZhbHVlKCJzc2hfcGFzc3dvcmQiKQogICAgICAgIHJldHVybiBwYXNzd29yZAoKICAgIGRlZiBfZ2V0X3NzaF9rZXkoc2VsZik6CiAgICAgICAgIiIiR2V0IFNTSCBrZXkKICAgICAgICBHZXQgcHJpdmF0ZSBrZXkgZm9yIGFuIFNTSCBjb25uZWN0aW9uCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIENoYXI6IFNTSCBwcml2YXRlIGtleQogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgIyBUbyBlbnN1cmUgdGhhdCBrZXkgd2lsbCBiZSByZWFkCiAgICAgICAgIyByZWdhcmRsZXNzIG9mIGFjY2VzcyByaWdodHMKICAgICAgICBpZiBzZWxmLnN1ZG8oKS5zc2hfa2V5X2lkOgogICAgICAgICAgICAjIFVzZSBjb250ZXh0IGtleSB0byByZWFkIHNlY3JldCB2YWx1ZQogICAgICAgICAgICBzc2hfa2V5ID0gc2VsZi5zc2hfa2V5X2lkLl9nZXRfc2VjcmV0X3ZhbHVlKCJzZWNyZXRfdmFsdWUiKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNzaF9rZXkgPSBOb25lCiAgICAgICAgcmV0dXJuIHNzaF9rZXkKCiAgICBAZW5zdXJlX3NzaF9kaXNjb25uZWN0CiAgICBkZWYgX2dldF9ob3N0X2tleV9mcm9tX2hvc3Qoc2VsZiwgcmFpc2Vfb25fZXJyb3I9RmFsc2UsIHRpbWVvdXQ9NjApOgogICAgICAgICIiIkdldCBob3N0IGtleQoKICAgICAgICBBcmdzOgogICAgICAgICAgICByYWlzZV9vbl9lcnJvciAoYm9vbCwgb3B0aW9uYWwpOiBJZiB0cnVlIHdpbGwgcmFpc2UgZXhjZXB0aW9uCiAgICAgICAgICAgIGluIGNhc2Ugb3IgZXJyb3IsIG90aGVyd2lzZSBGYWxzZSB3aWxsIGJlIHJldHVybmVkCiAgICAgICAgICAgIERlZmF1bHRzIHRvIFRydWUuCiAgICAgICAgICAgIHRpbWVvdXQgKGludCwgb3B0aW9uYWwpOiBTU0ggY29ubmVjdGlvbiB0aW1lb3V0IGluIHNlY29uZHMuCgogICAgICAgIFJhaXNlczoKICAgICAgICAgICAgVmFsaWRhdGlvbkVycm9yOiBJZiB0aGUgcHJvdmlkZWQgc2VydmVyIHJlZmVyZW5jZSBpcyBpbnZhbGlkIG9yCiAgICAgICAgICAgICAgICB0aGUgc2VydmVyIGNhbm5vdCBiZSBmb3VuZC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgSG9zdCBrZXk6IEhvc3Qga2V5IG9mIHRoZSBzZXJ2ZXIKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQoKICAgICAgICAjIENoZWNrIGFjY2VzcyBiZWZvcmUgZ2V0dGluZyBob3N0IGtleQogICAgICAgICMgVGhpcyBpcyBuZWVkZWQgdG8gYXZvaWQgcG9zc2libGUgYWNjZXNzIHZpb2xhdGlvbnMKICAgICAgICBzZWxmLmNoZWNrX2FjY2Vzc19yaWdodHMoInJlYWQiKQogICAgICAgIHNlbGYuY2hlY2tfYWNjZXNzX3J1bGUoInJlYWQiKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgU2tpcCBob3N0IGtleSB2ZXJpZmljYXRpb24gdG8gb2J0YWluIHRoZSBzZXJ2ZXIncyByZWFsIGhvc3Qga2V5LgogICAgICAgICAgICBjbGllbnQgPSBzZWxmLl9nZXRfc3NoX2NsaWVudCgKICAgICAgICAgICAgICAgIHJhaXNlX29uX2Vycm9yPXJhaXNlX29uX2Vycm9yLCB0aW1lb3V0PXRpbWVvdXQsIHNraXBfaG9zdF9rZXk9VHJ1ZQogICAgICAgICAgICApCgogICAgICAgICAgICAjIERpc2FibGUgaG9zdCBrZXkgdmVyaWZpY2F0aW9uIGZvciB0aGlzIGNvbm5lY3Rpb24gb25seSwgdG8gb2J0YWluIHRoZQogICAgICAgICAgICAjIHNlcnZlcidzIHJlYWwgaG9zdCBrZXkuIElmIGEgcHJlLWNvbmZpZ3VyZWQgaG9zdCBrZXkgaXMgaW5jb3JyZWN0IHVzaW5nCiAgICAgICAgICAgICMgaXQgd291bGQgY2F1c2UgYSBrZXkgbWlzbWF0Y2ggZXJyb3IuIEJ5IHNldHRpbmcgaG9zdF9rZXkgdG8gRmFsc2UKICAgICAgICAgICAgIyBoZXJlLCB3ZSB0cmlnZ2VyIEF1dG9BZGRQb2xpY3kgZm9yIHRoaXMgY29ubmVjdGlvbiwgd2hpY2ggYXV0b21hdGljYWxseQogICAgICAgICAgICAjIGFjY2VwdHMgdGhlIHNlcnZlcidzIGFjdHVhbCBob3N0IGtleS4KICAgICAgICAgICAgY2xpZW50LmNvbm5lY3Rpb24uaG9zdF9rZXkgPSBGYWxzZQoKICAgICAgICAgICAgc3NoX2NsaWVudCA9IGNsaWVudC5jb25uZWN0aW9uLmNvbm5lY3QoKQogICAgICAgICAgICB0cmFuc3BvcnQgPSBzc2hfY2xpZW50LmdldF90cmFuc3BvcnQoKQogICAgICAgICAgICByZW1vdGVfa2V5ID0gdHJhbnNwb3J0LmdldF9yZW1vdGVfc2VydmVyX2tleSgpCiAgICAgICAgICAgIGhvc3Rfa2V5ID0gcmVtb3RlX2tleS5nZXRfYmFzZTY0KCkKICAgICAgICAgICAgcmV0dXJuIGhvc3Rfa2V5CiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcigKICAgICAgICAgICAgICAgICAgICBfKCJFcnJvciByZXRyaWV2aW5nIGhvc3Qga2V5OiAlKGVycilzIiwgZXJyPWUpCiAgICAgICAgICAgICAgICApIGZyb20gZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyAtLS0tIENvbW1hbmQgZXhlY3V0aW9uCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGRlZiBydW5fY29tbWFuZCgKICAgICAgICBzZWxmLAogICAgICAgIGNvbW1hbmQsCiAgICAgICAgcGF0aD1Ob25lLAogICAgICAgIHN1ZG89Tm9uZSwKICAgICAgICBzc2hfY29ubmVjdGlvbj1Ob25lLAogICAgICAgIGpldF90ZW1wbGF0ZT1Ob25lLAogICAgICAgIGpldD1Ob25lLAogICAgICAgICoqa3dhcmdzLAogICAgKToKICAgICAgICAiIiJUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uIHRvIHVzZSBmb3IgcnVubmluZyBjb21tYW5kcy4KICAgICAgICBJdCByZW5kZXJzIGNvbW1hbmQgY29kZSwgY3JlYXRlcyBsb2cgcmVjb3JkIGFuZCBjYWxscyBjb21tYW5kIHJ1bm5lci4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgY29tbWFuZCAoY3gudG93ZXIuY29tbWFuZCgpKTogQ29tbWFuZCByZWNvcmQKICAgICAgICAgICAgcGF0aCAoQ2hhcik6IGRpcmVjdG9yeSB3aGVyZSBjb21tYW5kIGlzIHJ1bi4KICAgICAgICAgICAgICAgIFByb3ZpZGUgaW4gY2FzZSB5b3UgbmVlZCB0byBvdmVycmlkZSBkZWZhdWx0IGNvbW1hbmQgdmFsdWUKICAgICAgICAgICAgc3VkbyAoQm9vbGVhbik6IHVzZSBzdWRvCiAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byBOb25lCiAgICAgICAgICAgIHNzaF9jb25uZWN0aW9uIChTU0ggY2xpZW50IGluc3RhbmNlLCBvcHRpb25hbCk6IFNTSCBjb25uZWN0aW9uLgogICAgICAgICAgICAgICAgUGFzcyB0byByZXVzZSBleGlzdGluZyBjb25uZWN0aW9uLgogICAgICAgICAgICAgICAgVGhpcyBpcyB1c2VmdWwgaW4gY2FzZSB5b3Ugd291bGQgbGlrZSB0byBzcGVlZCB1cAogICAgICAgICAgICAgICAgdGhlIHNzaCBjb21tYW5kIHJ1bm5pbmcuCiAgICAgICAgICAgIGpldF90ZW1wbGF0ZSAoY3gudG93ZXIuamV0LnRlbXBsYXRlKCkpIEpldCBUZW1wbGF0ZSByZWNvcmQKICAgICAgICAgICAgICAgIFBhc3MgdG8gcnVuIGZvciBzcGVjaWZpYyBqZXQgdGVtcGxhdGUKICAgICAgICAgICAgamV0IChjeC50b3dlci5qZXQoKSk6IEpldCByZWNvcmQKICAgICAgICAgICAgICAgIFBhc3MgdG8gcnVuIGZvciBzcGVjaWZpYyBqZXQKICAgICAgICAgICAga3dhcmdzIChkaWN0KTogIGV4dHJhIGFyZ3VtZW50cy4gVXNlIHRvIHBhc3MgZXh0ZXJuYWwgdmFsdWVzLgogICAgICAgICAgICAgICAgRm9sbG93aW5nIGtleXMgYXJlIHN1cHBvcnRlZCBieSBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIC0gIndheXBvaW50IiwgY3gudG93ZXIuamV0LndheXBvaW50KCk6IHdheXBvaW50IHJlY29yZAogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHJ1bm5pbmcgZm9yIGEgd2F5cG9pbnQgKGUuZy4gZnJvbSB3YXlwb2ludCBwbGFuKQogICAgICAgICAgICAgICAgICAgIC0gImxvZyIsIGRpY3QoKTogdmFsdWVzIHBhc3NlZCB0byBsb2dnZXIKICAgICAgICAgICAgICAgICAgICAtICJrZXkiLCBkaWN0KCk6IHZhbHVlcyBwYXNzZWQgdG8ga2V5IHBhcnNlcgogICAgICAgICAgICAgICAgICAgIC0gInZhcmlhYmxlX3ZhbHVlcyIsIGRpY3QoKTogY3VzdG9tIHZhcmlhYmxlIHZhbHVlcwogICAgICAgICAgICAgICAgICAgICAgICBpbiB0aGUgZm9ybWF0IG9mIGB7dmFyaWFibGVfcmVmZXJlbmNlOiB2YXJpYWJsZV92YWx1ZX1gCiAgICAgICAgICAgICAgICAgICAgICAgIGVnIGB7J29kb29fdmVyc2lvbic6ICcxNi4wJ31gCiAgICAgICAgICAgICAgICAgICAgICAgIFdpbGwgYmUgYXBwbGllZCBvbmx5IGlmIHVzZXIgaGFzIHdyaXRlIGFjY2VzcyB0byB0aGUgc2VydmVyLgogICAgICAgIENvbnRleHQ6CiAgICAgICAgICAgIG5vX2NvbW1hbmRfbG9nIChCb29sKTogc2V0IHRoaXMgY29udGV4dCBrZXkgdG8gYFRydWVgCiAgICAgICAgICAgICAgICB0byBkaXNhYmxlIGxvZyBjcmVhdGlvbi4KICAgICAgICAgICAgQ29tbWFuZCBydW5uaW5nIHJlc3VsdHMgd2lsbCBiZSByZXR1cm5lZCBpbnN0ZWFkLgogICAgICAgICAgICBJZiBhbnkgbm9uIGNvbW1hbmQgcmVsYXRlZCBlcnJvciBvY2N1cnMgaW4gdGhlIGNvbW1hbmQgcnVubmluZyBmbG93CiAgICAgICAgICAgIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHJhaXNlZC4KICAgICAgICAgICAgSU1QT1JUQU5UOiBiZSBhd2FyZSB3aGVuIHJ1bm5pbmcgY29tbWFuZHMgd2l0aCBgbm9fY29tbWFuZF9sb2c9VHJ1ZWAKICAgICAgICAgICAgYmVjYXVzZSBubyBgQWxsb3cgUGFyYWxsZWwgUnVuYCBjaGVjayB3aWxsIGJlIGRvbmUhCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgZGljdCgpOiBjb21tYW5kIHJ1bm5pbmcgcmVzdWx0IGlmIGBub19jb21tYW5kX2xvZ2AKICAgICAgICAgICAgICAgIGNvbnRleHQgdmFsdWUgPT0gVHJ1ZSBlbHNlIE5vbmUKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQoKICAgICAgICAjIENoZWNrIGlmIGpldCBiZWxvbmdzIHRvIHRoZSBzZXJ2ZXIKICAgICAgICBpZiBqZXQgYW5kIG5vdCBqZXQuc2VydmVyX2lkID09IHNlbGY6CiAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcigKICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgIkpldCAnJShqZXQpcycgZG9lc24ndCBiZWxvbmcgdG8gdGhlIHNlcnZlciAnJShzZXJ2ZXIpcycuIiwKICAgICAgICAgICAgICAgICAgICBqZXQ9amV0Lm5hbWUsCiAgICAgICAgICAgICAgICAgICAgc2VydmVyPXNlbGYubmFtZSwgICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCgogICAgICAgICMgRm9yY2Ugc2V0IGpldCB0ZW1wbGF0ZSBmcm9tIGpldCBpZiBqZXQgaXMgcHJvdmlkZWQKICAgICAgICBpZiBqZXQ6CiAgICAgICAgICAgIGpldF90ZW1wbGF0ZSA9IGpldC5qZXRfdGVtcGxhdGVfaWQKCiAgICAgICAgIyBQb3B1bGF0ZSBgc3Vkb2AgdmFsdWUgZnJvbSB0aGUgc2VydmVyIHNldHRpbmdzIGlmIG5vdCBwcm92aWRlZCBleHBsaWNpdGx5CiAgICAgICAgaWYgc2VsZi5zdWRvKCkuc3NoX3VzZXJuYW1lID09ICJyb290IjoKICAgICAgICAgICAgc3VkbyA9IEZhbHNlCiAgICAgICAgZWxpZiBzdWRvIGlzIE5vbmUgb3Igc3VkbzoKICAgICAgICAgICAgc3VkbyA9IHNlbGYuc3VkbygpLnVzZV9zdWRvCgogICAgICAgICMgUHJlcGFyZSBsb2cgb2JqZWN0CiAgICAgICAgbG9nX29iaiA9IHNlbGYuZW52WyJjeC50b3dlci5jb21tYW5kLmxvZyJdCiAgICAgICAgbG9nX3ZhbHMgPSBrd2FyZ3MuZ2V0KCJsb2ciLCB7fSkKICAgICAgICBsb2dfdmFscy51cGRhdGUoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJ1c2Vfc3VkbyI6IHN1ZG8sCiAgICAgICAgICAgICAgICAidmFyaWFibGVfdmFsdWVzIjoga3dhcmdzLmdldCgidmFyaWFibGVfdmFsdWVzIiwge30pLAogICAgICAgICAgICAgICAgImpldF90ZW1wbGF0ZV9pZCI6IGpldF90ZW1wbGF0ZS5pZCBpZiBqZXRfdGVtcGxhdGUgZWxzZSBOb25lLAogICAgICAgICAgICAgICAgImpldF9pZCI6IGpldC5pZCBpZiBqZXQgZWxzZSBOb25lLAogICAgICAgICAgICB9CiAgICAgICAgKQogICAgICAgICMgQ2hlY2sgaWYgbm8gbG9nIHJlY29yZCBzaG91bGQgYmUgY3JlYXRlZAogICAgICAgIG5vX2NvbW1hbmRfbG9nID0gc2VsZi5fY29udGV4dC5nZXQoIm5vX2NvbW1hbmRfbG9nIikKCiAgICAgICAgIyBDaGVjayBpZiBjb21tYW5kIGNhbiBiZSBydW4gb24gdGhpcyBzZXJ2ZXI6CiAgICAgICAgIyAxLiBTZXJ2ZXIgaXMgbGlzdGVkIGluIGNvbW1hbmQncyBzZXJ2ZXJfaWRzCiAgICAgICAgIyAyLiBUaGVyZSBhcmUgbm8gc2VydmVyX2lkcyBhdCBhbGwgKGNvbW1hbmQgaXMgbm90IHNlcnZlciBzcGVjaWZpYykKICAgICAgICBpZiBub3QgY29tbWFuZC5fY2hlY2tfc2VydmVyX2NvbXBhdGliaWxpdHkoc2VsZik6CiAgICAgICAgICAgIGVycm9yID0gXygiQ29tbWFuZCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBzZXJ2ZXIiKQogICAgICAgICAgICBpZiBub19jb21tYW5kX2xvZzoKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6IENPTU1BTkRfTk9UX0NPTVBBVElCTEVfV0lUSF9TRVJWRVIsCiAgICAgICAgICAgICAgICAgICAgInJlc3BvbnNlIjogTm9uZSwKICAgICAgICAgICAgICAgICAgICAiZXJyb3IiOiBlcnJvciwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9nX29iai5yZWNvcmQoCiAgICAgICAgICAgICAgICBzZXJ2ZXJfaWQ9c2VsZi5pZCwgICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgICAgICAgICAgY29tbWFuZF9pZD1jb21tYW5kLmlkLAogICAgICAgICAgICAgICAgc3RhdHVzPUNPTU1BTkRfTk9UX0NPTVBBVElCTEVfV0lUSF9TRVJWRVIsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgICAgICoqbG9nX3ZhbHMsCiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQ2hlY2sgaWYgYW5vdGhlciBpbnN0YW5jZSBvZiB0aGUgc2FtZSBjb21tYW5kIGlzIHJ1bm5pbmcKICAgICAgICBhbm90aGVyX2NvbW1hbmRfcnVubmluZ19kb21haW4gPSBbCiAgICAgICAgICAgICgic2VydmVyX2lkIiwgIj0iLCBzZWxmLmlkKSwKICAgICAgICAgICAgKCJjb21tYW5kX2lkIiwgIj0iLCBjb21tYW5kLmlkKSwKICAgICAgICAgICAgKCJpc19ydW5uaW5nIiwgIj0iLCBUcnVlKSwKICAgICAgICBdCiAgICAgICAgaWYgamV0X3RlbXBsYXRlOgogICAgICAgICAgICBhbm90aGVyX2NvbW1hbmRfcnVubmluZ19kb21haW4uYXBwZW5kKAogICAgICAgICAgICAgICAgKCJqZXRfdGVtcGxhdGVfaWQiLCAiPSIsIGpldF90ZW1wbGF0ZS5pZCkKICAgICAgICAgICAgKQogICAgICAgIGlmIGpldDoKICAgICAgICAgICAgYW5vdGhlcl9jb21tYW5kX3J1bm5pbmdfZG9tYWluLmFwcGVuZCgoImpldF9pZCIsICI9IiwgamV0LmlkKSkKICAgICAgICBhbm90aGVyX2NvbW1hbmRfcnVubmluZ19ibG9jayA9ICgKICAgICAgICAgICAgbm90IGNvbW1hbmQuYWxsb3dfcGFyYWxsZWxfcnVuCiAgICAgICAgICAgIGFuZCBsb2dfb2JqLnN1ZG8oKS5zZWFyY2hfY291bnQoZG9tYWluPWFub3RoZXJfY29tbWFuZF9ydW5uaW5nX2RvbWFpbikKICAgICAgICApCiAgICAgICAgIyBBbm90aGVyIGNvbW1hbmQgaXMgcnVubmluZywgcmV0dXJuIGVycm9yCiAgICAgICAgaWYgYW5vdGhlcl9jb21tYW5kX3J1bm5pbmdfYmxvY2s6CiAgICAgICAgICAgIGlmIG5vX2NvbW1hbmRfbG9nOgogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAic3RhdHVzIjogQU5PVEhFUl9DT01NQU5EX1JVTk5JTkcsCiAgICAgICAgICAgICAgICAgICAgInJlc3BvbnNlIjogTm9uZSwKICAgICAgICAgICAgICAgICAgICAiZXJyb3IiOiBfKCJBbm90aGVyIGluc3RhbmNlIG9mIHRoZSBjb21tYW5kIGlzIGFscmVhZHkgcnVubmluZyIpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBsb2dfb2JqLnJlY29yZCgKICAgICAgICAgICAgICAgIHNlcnZlcl9pZD1zZWxmLmlkLCAgIyBweWxpbnQ6IGRpc2FibGU9bm8tbWVtYmVyCiAgICAgICAgICAgICAgICBjb21tYW5kX2lkPWNvbW1hbmQuaWQsCiAgICAgICAgICAgICAgICBzdGF0dXM9QU5PVEhFUl9DT01NQU5EX1JVTk5JTkcsCiAgICAgICAgICAgICAgICBlcnJvcj1fKCJBbm90aGVyIGluc3RhbmNlIG9mIHRoZSBjb21tYW5kIGlzIGFscmVhZHkgcnVubmluZyIpLAogICAgICAgICAgICAgICAgKipsb2dfdmFscywKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBSZW5kZXIgY29tbWFuZAogICAgICAgIGN1c3RvbV92YXJpYWJsZV92YWx1ZXMgPSBrd2FyZ3MuZ2V0KCJ2YXJpYWJsZV92YWx1ZXMiLCB7fSkKICAgICAgICByZW5kZXJlZF9jb21tYW5kID0gc2VsZi5fcmVuZGVyX2NvbW1hbmQoCiAgICAgICAgICAgIGNvbW1hbmQ9Y29tbWFuZCwKICAgICAgICAgICAgcGF0aD1wYXRoLAogICAgICAgICAgICBqZXRfdGVtcGxhdGU9amV0X3RlbXBsYXRlLAogICAgICAgICAgICBqZXQ9amV0LAogICAgICAgICAgICBjdXN0b21fdmFyaWFibGVfdmFsdWVzPWN1c3RvbV92YXJpYWJsZV92YWx1ZXMsCiAgICAgICAgKQogICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfY29kZSA9IHJlbmRlcmVkX2NvbW1hbmRbInJlbmRlcmVkX2NvZGUiXQogICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfcGF0aCA9IHJlbmRlcmVkX2NvbW1hbmRbInJlbmRlcmVkX3BhdGgiXQoKICAgICAgICAjIFByZXBhcmUga2V5IHJlbmRlcmVyIHZhbHVlcwogICAgICAgIGtleV92YWxzID0ga3dhcmdzLmdldCgia2V5Iiwge30pICAjIEdldCB2YWxzIGZyb20ga3dhcmdzCiAgICAgICAga2V5X3ZhbHMudXBkYXRlKHsic2VydmVyX2lkIjogc2VsZi5pZH0pICAjIHB5bGludDogZGlzYWJsZT1uby1tZW1iZXIKICAgICAgICBpZiBzZWxmLnBhcnRuZXJfaWQ6CiAgICAgICAgICAgIGtleV92YWxzLnVwZGF0ZSh7InBhcnRuZXJfaWQiOiBzZWxmLnBhcnRuZXJfaWQuaWR9KQogICAgICAgIGt3YXJncy51cGRhdGUoeyJrZXkiOiBrZXlfdmFsc30pCgogICAgICAgICMgU2F2ZSByZW5kZXJlZCBjb2RlIHRvIGxvZwogICAgICAgIGlmIG5vX2NvbW1hbmRfbG9nOgogICAgICAgICAgICBsb2dfcmVjb3JkID0gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGxvZ192YWxzLnVwZGF0ZSgKICAgICAgICAgICAgICAgIHsiY29kZSI6IHJlbmRlcmVkX2NvbW1hbmRfY29kZSwgInBhdGgiOiByZW5kZXJlZF9jb21tYW5kX3BhdGh9CiAgICAgICAgICAgICkKICAgICAgICAgICAgIyBDcmVhdGUgbG9nIHJlY29yZAogICAgICAgICAgICBsb2dfcmVjb3JkID0gbG9nX29iai5zdGFydChzZWxmLmlkLCBjb21tYW5kLmlkLCAqKmxvZ192YWxzKSAgIyBweWxpbnQ6IGRpc2FibGU9bm8tbWVtYmVyCiAgICAgICAgIyBJZiBvbiBjb21tYW5kIHdlIGhhdmUgdGhlIGZsYWcKICAgICAgICBpZiBjb21tYW5kLm5vX3NwbGl0X2Zvcl9zdWRvOgogICAgICAgICAgICBrd2FyZ3NbIm5vX3NwbGl0X2Zvcl9zdWRvIl0gPSBUcnVlCiAgICAgICAgcmV0dXJuIHNlbGYuX2NvbW1hbmRfcnVubmVyX3dyYXBwZXIoCiAgICAgICAgICAgIGNvbW1hbmQ9Y29tbWFuZCwKICAgICAgICAgICAgbG9nX3JlY29yZD1sb2dfcmVjb3JkLAogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGU9cmVuZGVyZWRfY29tbWFuZF9jb2RlLAogICAgICAgICAgICBzdWRvPXN1ZG8sCiAgICAgICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfcGF0aD1yZW5kZXJlZF9jb21tYW5kX3BhdGgsCiAgICAgICAgICAgIHNzaF9jb25uZWN0aW9uPXNzaF9jb25uZWN0aW9uLAogICAgICAgICAgICAqKmt3YXJncywKICAgICAgICApCgogICAgZGVmIF9yZW5kZXJfY29tbWFuZCgKICAgICAgICBzZWxmLAogICAgICAgIGNvbW1hbmQsCiAgICAgICAgcGF0aD1Ob25lLAogICAgICAgIGpldF90ZW1wbGF0ZT1Ob25lLAogICAgICAgIGpldD1Ob25lLAogICAgICAgIGN1c3RvbV92YXJpYWJsZV92YWx1ZXM9Tm9uZSwKICAgICk6CiAgICAgICAgIiIiUmVuZGVycyBjb21tYW5kIGNvZGUgZm9yIHNlbGVjdGVkIGNvbW1hbmQgZm9yIGN1cnJlbnQgc2VydmVyCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGNvbW1hbmQgKGN4LnRvd2VyLmNvbW1hbmQpOiBDb21tYW5kIHRvIHJlbmRlcgogICAgICAgICAgICBwYXRoIChDaGFyKTogUGF0aCB3aGVyZSB0byBydW4gdGhlIGNvbW1hbmQuCiAgICAgICAgICAgICAgICBQcm92aWRlIGluIGNhc2UgeW91IG5lZWQgdG8gb3ZlcnJpZGUgZGVmYXVsdCBjb21tYW5kIHBhdGgKICAgICAgICAgICAgamV0IChjeC50b3dlci5qZXQoKSk6IEpldCB0byByZW5kZXIgY29tbWFuZCBmb3IKICAgICAgICAgICAgY3VzdG9tX3ZhcmlhYmxlX3ZhbHVlcyAoZGljdCk6IEN1c3RvbSB2YXJpYWJsZSB2YWx1ZXMgdG8gcmVuZGVyIGNvbW1hbmQKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0OiByZW5kZXJlZCB2YWx1ZXMKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAicmVuZGVyZWRfY29kZSI6IHJlbmRlcmVkIGNvbW1hbmQgY29kZSwKICAgICAgICAgICAgICAgICAgICAicmVuZGVyZWRfcGF0aCI6IHJlbmRlcmVkIGNvbW1hbmQgcGF0aAogICAgICAgICAgICAgICAgfQogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCgogICAgICAgIHZhcmlhYmxlX3JlZmVyZW5jZXMgPSBbXQoKICAgICAgICAjIEdldCB2YXJpYWJsZXMgZnJvbSBjb2RlCiAgICAgICAgaWYgY29tbWFuZC5jb2RlOgogICAgICAgICAgICB2YXJpYWJsZXNfZXh0cmFjdGVkID0gY29tbWFuZC5nZXRfdmFyaWFibGVzX2Zyb21fY29kZShjb21tYW5kLmNvZGUpCiAgICAgICAgICAgIGZvciB2ZSBpbiB2YXJpYWJsZXNfZXh0cmFjdGVkOgogICAgICAgICAgICAgICAgaWYgdmUgbm90IGluIHZhcmlhYmxlX3JlZmVyZW5jZXM6CiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVfcmVmZXJlbmNlcy5hcHBlbmQodmUpCgogICAgICAgICMgR2V0IHZhcmlhYmxlcyBmcm9tIHBhdGgKICAgICAgICBwYXRoID0gcGF0aCBpZiBwYXRoIGVsc2UgY29tbWFuZC5wYXRoCiAgICAgICAgaWYgcGF0aDoKICAgICAgICAgICAgdmFyaWFibGVzX2V4dHJhY3RlZCA9IGNvbW1hbmQuZ2V0X3ZhcmlhYmxlc19mcm9tX2NvZGUocGF0aCkKICAgICAgICAgICAgZm9yIHZlIGluIHZhcmlhYmxlc19leHRyYWN0ZWQ6CiAgICAgICAgICAgICAgICBpZiB2ZSBub3QgaW4gdmFyaWFibGVfcmVmZXJlbmNlczoKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZV9yZWZlcmVuY2VzLmFwcGVuZCh2ZSkKCiAgICAgICAgIyBJZiB0aGVyZSBhcmUgdmFyaWFibGVzIHRvIHJlbmRlciwgZ2V0IHZhcmlhYmxlIHZhbHVlcwogICAgICAgIGlmIHZhcmlhYmxlX3JlZmVyZW5jZXM6CiAgICAgICAgICAgICMgR2V0IHRoZSB2YXJpYWJsZSB2YWx1ZXMKICAgICAgICAgICAgdmFyaWFibGVfdmFsdWVzID0gKAogICAgICAgICAgICAgICAgc2VsZi5lbnZbImN4LnRvd2VyLnZhcmlhYmxlIl0KICAgICAgICAgICAgICAgIC5zdWRvKCkKICAgICAgICAgICAgICAgIC5fZ2V0X3ZhcmlhYmxlX3ZhbHVlc19ieV9yZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlX3JlZmVyZW5jZXMsIHNlcnZlcj1zZWxmLCBqZXRfdGVtcGxhdGU9amV0X3RlbXBsYXRlLCBqZXQ9amV0CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgQXBwbHkgY3VzdG9tIHZhcmlhYmxlIHZhbHVlcyBvbmx5IGlmIHVzZXIgaGFzIHdyaXRlIGFjY2VzcyB0byB0aGUgc2VydmVyCiAgICAgICAgICAgIGhhc193cml0ZV9hY2Nlc3MgPSBzZWxmLl9oYXZlX2FjY2Vzc190b19zZXJ2ZXIoIndyaXRlIikKICAgICAgICAgICAgaWYgY3VzdG9tX3ZhcmlhYmxlX3ZhbHVlcyBhbmQgaGFzX3dyaXRlX2FjY2VzczoKICAgICAgICAgICAgICAgIHZhcmlhYmxlX3ZhbHVlcy51cGRhdGUoY3VzdG9tX3ZhcmlhYmxlX3ZhbHVlcykKCiAgICAgICAgICAgICMgUmVuZGVyIGNvbW1hbmQgY29kZSBhbmQgcGF0aCB1c2luZyB2YXJpYWJsZXMKICAgICAgICAgICAgaWYgdmFyaWFibGVfdmFsdWVzOgogICAgICAgICAgICAgICAgaWYgY29tbWFuZC5hY3Rpb24gPT0gInB5dGhvbl9jb2RlIjoKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZV92YWx1ZXNbInB5dGhvbmljX21vZGUiXSA9IFRydWUKCiAgICAgICAgICAgICAgICByZW5kZXJlZF9jb2RlID0gKAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQucmVuZGVyX2NvZGVfY3VzdG9tKGNvbW1hbmQuY29kZSwgKip2YXJpYWJsZV92YWx1ZXMpCiAgICAgICAgICAgICAgICAgICAgaWYgY29tbWFuZC5jb2RlCiAgICAgICAgICAgICAgICAgICAgZWxzZSBGYWxzZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgcmVuZGVyZWRfcGF0aCA9ICgKICAgICAgICAgICAgICAgICAgICBjb21tYW5kLnJlbmRlcl9jb2RlX2N1c3RvbShwYXRoLCAqKnZhcmlhYmxlX3ZhbHVlcykKICAgICAgICAgICAgICAgICAgICBpZiBwYXRoCiAgICAgICAgICAgICAgICAgICAgZWxzZSBGYWxzZQogICAgICAgICAgICAgICAgKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICByZW5kZXJlZF9jb2RlID0gY29tbWFuZC5jb2RlCiAgICAgICAgICAgIHJlbmRlcmVkX3BhdGggPSBwYXRoCgogICAgICAgIHJldHVybiB7InJlbmRlcmVkX2NvZGUiOiByZW5kZXJlZF9jb2RlLCAicmVuZGVyZWRfcGF0aCI6IHJlbmRlcmVkX3BhdGh9CgogICAgZGVmIF9oYXZlX2FjY2Vzc190b19zZXJ2ZXIoc2VsZiwgb3BlcmF0aW9uKToKICAgICAgICAiIiJDaGVjayBhY2Nlc3MgdG8gdGhlIHNlcnZlci4KICAgICAgICBUaGlzIGlzIGEgd3JhcHBlciBmdW5jdGlvbiBvdmVyIHRoZSBPZG9vIGJ1aWx0LWluIG9uZXMuCiAgICAgICAgSXQncyB1c2VkIGluIG9yZGVyIHdlIG5lZWQgdG8gaW1wbGVtZW50IGN1c3RvbSBhY2Nlc3MgY2hlY2tzLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBvcGVyYXRpb24gKENoYXIpOiBPcGVyYXRpb24gdG8gY2hlY2sgYWNjZXNzCiAgICAgICAgICAgICAgICBzYW1lIGZvcm1hdCBhcyBgY2hlY2tfYWNjZXNzX3JpZ2h0c2AKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBCb29sOiBUcnVlIGlmIGFjY2VzcyBpcyBncmFudGVkLCBGYWxzZSBvdGhlcndpc2UKICAgICAgICAiIiIKICAgICAgICAjIENoZWNrIGFjY2VzcyByaWdodHMgZmlyc3QKICAgICAgICBoYXNfd3JpdGVfYWNjZXNzID0gc2VsZi5jaGVja19hY2Nlc3NfcmlnaHRzKG9wZXJhdGlvbiwgcmFpc2VfZXhjZXB0aW9uPUZhbHNlKQoKICAgICAgICAjIENoZWNrIGFjY2VzcyBydWxlIHRvIHBhcnRpCiAgICAgICAgaWYgaGFzX3dyaXRlX2FjY2VzczoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5jaGVja19hY2Nlc3NfcnVsZShvcGVyYXRpb24pCiAgICAgICAgICAgIGV4Y2VwdCBVc2VyRXJyb3I6CiAgICAgICAgICAgICAgICBoYXNfd3JpdGVfYWNjZXNzID0gRmFsc2UKICAgICAgICByZXR1cm4gaGFzX3dyaXRlX2FjY2VzcwoKICAgIGRlZiBydW5fZmxpZ2h0X3BsYW4oc2VsZiwgZmxpZ2h0X3BsYW4sIGpldF90ZW1wbGF0ZT1Ob25lLCBqZXQ9Tm9uZSwgKiprd2FyZ3MpOgogICAgICAgICIiIgogICAgICAgIFJ1bnMgZmxpZ2h0IHBsYW4gb24gdGhlIGN1cnJlbnQgc2VydmVyLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBmbGlnaHRfcGxhbiAoY3gudG93ZXIucGxhbigpKTogZmxpZ2h0IHBsYW4gdG8gcnVuCiAgICAgICAgICAgIGpldF90ZW1wbGF0ZSAoY3gudG93ZXIuamV0LnRlbXBsYXRlKCkpOiBqZXQgdGVtcGxhdGUKICAgICAgICAgICAgICAgIHRvIHJ1biB0aGUgZmxpZ2h0IHBsYW4gb24KICAgICAgICAgICAgamV0IChjeC50b3dlci5qZXQoKSk6IGpldCB0byBydW4gdGhlIGZsaWdodCBwbGFuIG9uCiAgICAgICAgICAgIGt3YXJncyAoZGljdCk6IE9wdGlvbmFsIGFyZ3VtZW50cwogICAgICAgICAgICAgICAgRm9sbG93aW5nIGFyZSBzdXBwb3J0ZWQgYnV0IG5vdCBsaW1pdGVkIHRvOgogICAgICAgICAgICAgICAgICAgIC0gInBsYW5fbG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gZmxpZ2h0cGxhbiBsb2dnZXJ9CiAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgIC0gImtleSI6IHt2YWx1ZXMgcGFzc2VkIHRvIGtleSBwYXJzZXJ9CiAgICAgICAgICAgICAgICAgICAgLSAidmFyaWFibGVfdmFsdWVzIiwgZGljdCgpOiBjdXN0b20gdmFyaWFibGUgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBmb3JtYXQgb2YgYHt2YXJpYWJsZV9yZWZlcmVuY2U6IHZhcmlhYmxlX3ZhbHVlfWAKICAgICAgICAgICAgICAgICAgICAgICAgZWcgYHsnb2Rvb192ZXJzaW9uJzogJzE2LjAnfWAKICAgICAgICAgICAgICAgICAgICAgICAgV2lsbCBiZSBhcHBsaWVkIG9ubHkgaWYgdXNlciBoYXMgd3JpdGUgYWNjZXNzIHRvIHRoZSBzZXJ2ZXIuCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIucGxhbi5sb2coKSk6IHBsYW4gbG9nIHJlY29yZAogICAgICAgICIiIgoKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQoKICAgICAgICAjIENoZWNrIGlmIGpldCBiZWxvbmdzIHRvIHRoZSBzZXJ2ZXIKICAgICAgICBpZiBqZXQgYW5kIG5vdCBqZXQuc2VydmVyX2lkID09IHNlbGY6CiAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcigKICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgIkpldCAnJShqZXQpcycgZG9lc24ndCBiZWxvbmcgdG8gdGhlIHNlcnZlciAnJShzZXJ2ZXIpcycuIiwKICAgICAgICAgICAgICAgICAgICBqZXQ9amV0Lm5hbWUsCiAgICAgICAgICAgICAgICAgICAgc2VydmVyPXNlbGYubmFtZSwgICMgcHlsaW50OiBkaXNhYmxlPW5vLW1lbWJlcgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCgogICAgICAgICMgU2V0IGpldCB0ZW1wbGF0ZSBmcm9tIGpldCBpZiBqZXQgaXMgcHJvdmlkZWQKICAgICAgICBpZiBqZXQ6CiAgICAgICAgICAgIGpldF90ZW1wbGF0ZSA9IGpldC5qZXRfdGVtcGxhdGVfaWQKCiAgICAgICAgIyBSdW4gZmxpZ2h0IHBsYW4KICAgICAgICByZXR1cm4gZmxpZ2h0X3BsYW4uX3J1bl9zaW5nbGUoCiAgICAgICAgICAgIHNlbGYsIGpldF90ZW1wbGF0ZT1qZXRfdGVtcGxhdGUsIGpldD1qZXQsICoqa3dhcmdzCiAgICAgICAgKQoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXJfd3JhcHBlcigKICAgICAgICBzZWxmLAogICAgICAgIGNvbW1hbmQsCiAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGUsCiAgICAgICAgc3Vkbz1Ob25lLAogICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfcGF0aD1Ob25lLAogICAgICAgIHNzaF9jb25uZWN0aW9uPU5vbmUsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgICIiIlVzZWQgdG8gaW1wbGVtZW50IGN1c3RvbSBydW5uZXIgbWVjaGFuaXNtcy4KICAgICAgICBVc2UgaXQgaW4gY2FzZSB5b3UgbmVlZCB0byByZWRlZmluZSB0aGUgZW50aXJlIGNvbW1hbmQgcnVubmluZyBlbmdpbmUuCiAgICAgICAgRWcgaXQncyB1c2VkIGluIGBjZXRtaXhfdG93ZXJfc2VydmVyX3F1ZXVlYCBPQ0EgYHF1ZXVlX2pvYmAgaW1wbGVtZW50YXRpb24uCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGNvbW1hbmQgKGN4LnRvd2VyLmNvbW1hbmQoKSk6IENvbW1hbmQKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIuY29tbWFuZC5sb2coKSk6IENvbW1hbmQgbG9nIHJlY29yZAogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGUgKFRleHQpOiBSZW5kZXJlZCBjb21tYW5kIGNvZGUuCiAgICAgICAgICAgICAgICBXZSBhcmUgcGFzc2luZyBpbiBjYXNlIGl0IGRpZmZlcnMgZnJvbSBjb21tYW5kIGNvZGUgaW4gdGhlIGxvZyByZWNvcmQuCiAgICAgICAgICAgIHN1ZG8gKFNlbGVjdGlvbik6IENvbW1hbmQgc3VkbyBtb2RlLiBEZWZhdWx0cyB0byBOb25lLgogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX3BhdGggKENoYXIsIG9wdGlvbmFsKTogUmVuZGVyZWQgY29tbWFuZCBwYXRoLgogICAgICAgICAgICBzc2hfY29ubmVjdGlvbiAoU1NIIGNsaWVudCBpbnN0YW5jZSwgb3B0aW9uYWwpOiBTU0ggY29ubmVjdGlvbiB0byByZXVzZS4KICAgICAgICBrd2FyZ3MgKGRpY3QpOiAgZXh0cmEgYXJndW1lbnRzLiBVc2UgdG8gcGFzcyBleHRlcm5hbCB2YWx1ZXMuCiAgICAgICAgICAgICAgICBGb2xsb3dpbmcga2V5cyBhcmUgc3VwcG9ydGVkIGJ5IGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgIC0gImtleSI6IHt2YWx1ZXMgcGFzc2VkIHRvIGtleSBwYXJzZXJ9CgogICAgICAgIENvbnRleHQ6CiAgICAgICAgICAgIHVzZV9zdWRvIChCb29sKTogdXNlIHN1ZG8gZm9yIGNvbW1hbmQgcnVubmluZwoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0KCk6IGNvbW1hbmQgcnVubmluZyByZXN1bHQgaWYgYGxvZ19yZWNvcmRgIGlzIGRlZmluZWQgZWxzZSBOb25lCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuX2NvbW1hbmRfcnVubmVyKAogICAgICAgICAgICBjb21tYW5kPWNvbW1hbmQsCiAgICAgICAgICAgIGxvZ19yZWNvcmQ9bG9nX3JlY29yZCwKICAgICAgICAgICAgcmVuZGVyZWRfY29tbWFuZF9jb2RlPXJlbmRlcmVkX2NvbW1hbmRfY29kZSwKICAgICAgICAgICAgc3Vkbz1zdWRvLAogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX3BhdGg9cmVuZGVyZWRfY29tbWFuZF9wYXRoLAogICAgICAgICAgICBzc2hfY29ubmVjdGlvbj1zc2hfY29ubmVjdGlvbiwKICAgICAgICAgICAgKiprd2FyZ3MsCiAgICAgICAgKQoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXIoCiAgICAgICAgc2VsZiwKICAgICAgICBjb21tYW5kLAogICAgICAgIGxvZ19yZWNvcmQsCiAgICAgICAgcmVuZGVyZWRfY29tbWFuZF9jb2RlLAogICAgICAgIHN1ZG89Tm9uZSwKICAgICAgICByZW5kZXJlZF9jb21tYW5kX3BhdGg9Tm9uZSwKICAgICAgICBzc2hfY29ubmVjdGlvbj1Ob25lLAogICAgICAgICoqa3dhcmdzLAogICAgKToKICAgICAgICAiIiJUb3AgbGV2ZWwgY29tbWFuZCBydW5uZXIgZnVuY3Rpb24uCiAgICAgICAgQ2FsbHMgY29tbWFuZCB0eXBlIHNwZWNpZmljIHJ1bm5lcnMuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGNvbW1hbmQgKGN4LnRvd2VyLmNvbW1hbmQoKSk6IENvbW1hbmQKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIuY29tbWFuZC5sb2coKSk6IENvbW1hbmQgbG9nIHJlY29yZAogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGUgKFRleHQpOiBSZW5kZXJlZCBjb21tYW5kIGNvZGUuCiAgICAgICAgICAgICAgICBXZSBhcmUgcGFzc2luZyBpbiBjYXNlIGl0IGRpZmZlcnMgZnJvbSBjb21tYW5kIGNvZGUgaW4gdGhlIGxvZyByZWNvcmQuCiAgICAgICAgICAgIHN1ZG8gKFNlbGVjdGlvbik6IENvbW1hbmQgc3VkbyBtb2RlLiBEZWZhdWx0cyB0byBOb25lLgogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX3BhdGggKENoYXIsIG9wdGlvbmFsKTogUmVuZGVyZWQgY29tbWFuZCBwYXRoLgogICAgICAgICAgICBzc2hfY29ubmVjdGlvbiAoU1NIIGNsaWVudCBpbnN0YW5jZSwgb3B0aW9uYWwpOiBTU0ggY29ubmVjdGlvbiB0byByZXVzZS4KICAgICAgICAgICAga3dhcmdzIChkaWN0KTogIGV4dHJhIGFyZ3VtZW50cy4gVXNlIHRvIHBhc3MgZXh0ZXJuYWwgdmFsdWVzLgogICAgICAgICAgICAgICAgRm9sbG93aW5nIGtleXMgYXJlIHN1cHBvcnRlZCBieSBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIC0gImxvZyI6IHt2YWx1ZXMgcGFzc2VkIHRvIGxvZ2dlcn0KICAgICAgICAgICAgICAgICAgICAtICJrZXkiOiB7dmFsdWVzIHBhc3NlZCB0byBrZXkgcGFyc2VyfQogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogY29tbWFuZCBydW5uaW5nIHJlc3VsdCBpZiBgbG9nX3JlY29yZGAgaXMgZGVmaW5lZCBlbHNlIE5vbmUKICAgICAgICAiIiIKICAgICAgICByZXNwb25zZSA9IE5vbmUKICAgICAgICBuZWVkX2NoZWNrX3NlcnZlcl9zdGF0dXMgPSBUcnVlCiAgICAgICAgaWYgY29tbWFuZC5hY3Rpb24gPT0gInNzaF9jb21tYW5kIjoKICAgICAgICAgICAgcmVzcG9uc2UgPSBzZWxmLl9jb21tYW5kX3J1bm5lcl9zc2goCiAgICAgICAgICAgICAgICBsb2dfcmVjb3JkPWxvZ19yZWNvcmQsCiAgICAgICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGU9cmVuZGVyZWRfY29tbWFuZF9jb2RlLAogICAgICAgICAgICAgICAgc3Vkbz1zdWRvLAogICAgICAgICAgICAgICAgcmVuZGVyZWRfY29tbWFuZF9wYXRoPXJlbmRlcmVkX2NvbW1hbmRfcGF0aCwKICAgICAgICAgICAgICAgIHNzaF9jb25uZWN0aW9uPXNzaF9jb25uZWN0aW9uLAogICAgICAgICAgICAgICAgKiprd2FyZ3MsCiAgICAgICAgICAgICkKICAgICAgICBlbGlmIGNvbW1hbmQuYWN0aW9uID09ICJmaWxlX3VzaW5nX3RlbXBsYXRlIjoKICAgICAgICAgICAgcmVzcG9uc2UgPSBzZWxmLl9jb21tYW5kX3J1bm5lcl9maWxlX3VzaW5nX3RlbXBsYXRlKAogICAgICAgICAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICAgICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfcGF0aCwKICAgICAgICAgICAgICAgICoqa3dhcmdzLAogICAgICAgICAgICApCiAgICAgICAgZWxpZiBjb21tYW5kLmFjdGlvbiA9PSAicHl0aG9uX2NvZGUiOgogICAgICAgICAgICByZXNwb25zZSA9IHNlbGYuX2NvbW1hbmRfcnVubmVyX3B5dGhvbl9jb2RlKAogICAgICAgICAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICAgICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfY29kZSwKICAgICAgICAgICAgICAgICoqa3dhcmdzLAogICAgICAgICAgICApCiAgICAgICAgZWxpZiBjb21tYW5kLmFjdGlvbiA9PSAiamV0X2FjdGlvbiI6CiAgICAgICAgICAgIHJlc3BvbnNlID0gc2VsZi5fY29tbWFuZF9ydW5uZXJfamV0X2FjdGlvbigKICAgICAgICAgICAgICAgIGxvZ19yZWNvcmQsCiAgICAgICAgICAgICAgICAqKmt3YXJncywKICAgICAgICAgICAgKQogICAgICAgIGVsaWYgY29tbWFuZC5hY3Rpb24gPT0gImNyZWF0ZV93YXlwb2ludCI6CiAgICAgICAgICAgIHJlc3BvbnNlID0gc2VsZi5fY29tbWFuZF9ydW5uZXJfY3JlYXRlX3dheXBvaW50KAogICAgICAgICAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICAgICAgICAgICoqa3dhcmdzLAogICAgICAgICAgICApCiAgICAgICAgZWxpZiBjb21tYW5kLmFjdGlvbiA9PSAicGxhbiI6CiAgICAgICAgICAgIHJlc3BvbnNlID0gc2VsZi53aXRoX2NvbnRleHQoCiAgICAgICAgICAgICAgICBwcmV2ZW50X3BsYW5fcmVjdXJzaW9uPVRydWUKICAgICAgICAgICAgKS5fY29tbWFuZF9ydW5uZXJfZmxpZ2h0X3BsYW4oCiAgICAgICAgICAgICAgICBsb2dfcmVjb3JkPWxvZ19yZWNvcmQsCiAgICAgICAgICAgICAgICBmbGlnaHRfcGxhbj1jb21tYW5kLmZsaWdodF9wbGFuX2lkLAogICAgICAgICAgICAgICAgKiprd2FyZ3MsCiAgICAgICAgICAgICkKICAgICAgICAgICAgbmVlZF9jaGVja19zZXJ2ZXJfc3RhdHVzID0gVHJ1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG5lZWRfY2hlY2tfc2VydmVyX3N0YXR1cyA9IEZhbHNlCgogICAgICAgIGlmICgKICAgICAgICAgICAgbmVlZF9jaGVja19zZXJ2ZXJfc3RhdHVzCiAgICAgICAgICAgIGFuZCBjb21tYW5kLnNlcnZlcl9zdGF0dXMKICAgICAgICAgICAgYW5kICgKICAgICAgICAgICAgICAgIChsb2dfcmVjb3JkIGFuZCBsb2dfcmVjb3JkLmNvbW1hbmRfc3RhdHVzID09IDApCiAgICAgICAgICAgICAgICBvciAocmVzcG9uc2UgYW5kIHJlc3BvbnNlWyJzdGF0dXMiXSA9PSAwKQogICAgICAgICAgICApCiAgICAgICAgKToKICAgICAgICAgICAgc2VsZi53cml0ZSh7InN0YXR1cyI6IGNvbW1hbmQuc2VydmVyX3N0YXR1c30pCgogICAgICAgIGlmIG5lZWRfY2hlY2tfc2VydmVyX3N0YXR1czoKICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlCgogICAgICAgIGVycm9yX21lc3NhZ2UgPSBfKAogICAgICAgICAgICAiTm8gcnVubmVyIGZvdW5kIGZvciBjb21tYW5kIGFjdGlvbiAnJShjbWRfYWN0aW9uKXMnIiwKICAgICAgICAgICAgY21kX2FjdGlvbj1jb21tYW5kLmFjdGlvbiwKICAgICAgICApCiAgICAgICAgaWYgbG9nX3JlY29yZDoKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBmaW5pc2hfZGF0ZT1maWVsZHMuRGF0ZXRpbWUubm93KCksCiAgICAgICAgICAgICAgICBzdGF0dXM9Tk9fQ09NTUFORF9SVU5ORVJfRk9VTkQsCiAgICAgICAgICAgICAgICByZXNwb25zZT1Ob25lLAogICAgICAgICAgICAgICAgZXJyb3I9ZXJyb3JfbWVzc2FnZSwKICAgICAgICAgICAgKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihlcnJvcl9tZXNzYWdlKQoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXJfZmlsZV91c2luZ190ZW1wbGF0ZV9jcmVhdGVfZmlsZSgKICAgICAgICBzZWxmLCBsb2dfcmVjb3JkLCBzZXJ2ZXJfZGlyLCAqKmt3YXJncwogICAgKToKICAgICAgICAiIiIKICAgICAgICBDcmVhdGVzIGEgZmlsZSBvbiB0aGUgc2VydmVyIHVzaW5nIHRoZSBzcGVjaWZpZWQgZmlsZSB0ZW1wbGF0ZS4KCiAgICAgICAgVGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgdG8gYWxsb3cgb3ZlcnJpZGluZyB0aGUgZmlsZSBjcmVhdGlvbiBsb2dpYwogICAgICAgIGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGNyZWF0ZWQgZmlsZSBvYmplY3QuCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbG9nX3JlY29yZCAocmVjb3Jkc2V0KTogQ29tbWFuZCBsb2cgcmVjb3JkLgogICAgICAgICAgICBzZXJ2ZXJfZGlyIChzdHIpOiBUaGUgZGlyZWN0b3J5IG9uIHRoZSBzZXJ2ZXIgd2hlcmUgdGhlIGZpbGUgc2hvdWxkIGJlCiAgICAgICAgICAgICAgICBjcmVhdGVkLgogICAgICAgICAgICAqKmt3YXJnczogQWRkaXRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgcmVjb3JkOiBUaGUgY3JlYXRlZCBmaWxlIHJlY29yZC4KICAgICAgICAiIiIKICAgICAgICBmaWxlX3RlbXBsYXRlX2lkID0gbG9nX3JlY29yZC5jb21tYW5kX2lkLmZpbGVfdGVtcGxhdGVfaWQKICAgICAgICByZXR1cm4gZmlsZV90ZW1wbGF0ZV9pZC5jcmVhdGVfZmlsZSgKICAgICAgICAgICAgc2VydmVyPXNlbGYsCiAgICAgICAgICAgIHNlcnZlcl9kaXI9c2VydmVyX2RpciwKICAgICAgICAgICAgaWZfZmlsZV9leGlzdHM9bG9nX3JlY29yZC5jb21tYW5kX2lkLmlmX2ZpbGVfZXhpc3RzLAogICAgICAgICAgICBqZXRfdGVtcGxhdGU9bG9nX3JlY29yZC5qZXRfdGVtcGxhdGVfaWQsCiAgICAgICAgICAgIGpldD1sb2dfcmVjb3JkLmpldF9pZCwKICAgICAgICApCgogICAgZGVmIF9jb21tYW5kX3J1bm5lcl9maWxlX3VzaW5nX3RlbXBsYXRlKAogICAgICAgIHNlbGYsCiAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICBzZXJ2ZXJfZGlyLAogICAgICAgICoqa3dhcmdzLAogICAgKToKICAgICAgICAiIiIKICAgICAgICBSdW4gdGhlIGNvbW1hbmQgdG8gY3JlYXRlIGEgZmlsZSBmcm9tIGEgdGVtcGxhdGUgYW5kIHB1c2ggdG8gc2VydmVyIGlmIHNvdXJjZQogICAgICAgIGlzICd0b3dlcicgYW5kIHB1bGwgdG8gdG93ZXIgaWYgc291cmNlIGlzICdzZXJ2ZXInLgoKICAgICAgICBUaGlzIGZ1bmN0aW9uIGF0dGVtcHRzIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG9uIHRoZSBzZXJ2ZXIvdG93ZXIgdXNpbmcgdGhlCiAgICAgICAgc3BlY2lmaWVkIGZpbGUgdGVtcGxhdGUuIElmIHRoZSBmaWxlIGNyZWF0aW9uIGlzIHN1Y2Nlc3NmdWwsIGl0IHVwbG9hZHMKICAgICAgICB0aGUgZmlsZSB0byB0aGUgc2VydmVyL3Rvd2VyLiBUaGUgZnVuY3Rpb24gbG9ncyB0aGUgc3RhdHVzIG9mIHRoZSBvcGVyYXRpb24KICAgICAgICBpbiB0aGUgcHJvdmlkZWQgbG9nIHJlY29yZC4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbG9nX3JlY29yZCAocmVjb3Jkc2V0KTogVGhlIGxvZyByZWNvcmQgdG8gdXBkYXRlIHdpdGggdGhlIGNvbW1hbmQncwogICAgICAgICAgICAgICAgc3RhdHVzLgogICAgICAgICAgICBzZXJ2ZXJfZGlyIChzdHIpOiBUaGUgZGlyZWN0b3J5IG9uIHRoZSBzZXJ2ZXIgd2hlcmUgdGhlIGZpbGUgc2hvdWxkIGJlCiAgICAgICAgICAgICAgICBjcmVhdGVkLgogICAgICAgICAgICAqKmt3YXJnczogQWRkaXRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cy4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgTm9uZQoKICAgICAgICBSYWlzZXM6CiAgICAgICAgICAgIEV4Y2VwdGlvbjogSWYgYW55IGVycm9yIG9jY3VycyBkdXJpbmcgdGhlIGZpbGUgY3JlYXRpb24gb3IgdXBsb2FkCiAgICAgICAgICAgICAgICBwcm9jZXNzLCBpdCBsb2dzIHRoZSBlcnJvciBhbmQgdGhlIGV4Y2VwdGlvbiBtZXNzYWdlIGluIHRoZQogICAgICAgICAgICAgICAgbG9nIHJlY29yZC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgQXR0ZW1wdCB0byBjcmVhdGUgYSBuZXcgZmlsZSB1c2luZyB0aGUgdGVtcGxhdGUgZm9yIHRoZSBjdXJyZW50IHNlcnZlcgogICAgICAgICAgICBmaWxlID0gc2VsZi5fY29tbWFuZF9ydW5uZXJfZmlsZV91c2luZ190ZW1wbGF0ZV9jcmVhdGVfZmlsZSgKICAgICAgICAgICAgICAgIGxvZ19yZWNvcmQ9bG9nX3JlY29yZCwKICAgICAgICAgICAgICAgIHNlcnZlcl9kaXI9c2VydmVyX2RpciwKICAgICAgICAgICAgKQoKICAgICAgICAgICAgIyBJZiBmaWxlIGNyZWF0aW9uIGZhaWxlZCwgbG9nIHRoZSBmYWlsdXJlIGFuZCBleGl0CiAgICAgICAgICAgIGlmIG5vdCBmaWxlOgogICAgICAgICAgICAgICAgY29tbWFuZF9yZXN1bHQgPSB7CiAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6IEZJTEVfQ1JFQVRJT05fRkFJTEVELAogICAgICAgICAgICAgICAgICAgICJyZXNwb25zZSI6IE5vbmUsCiAgICAgICAgICAgICAgICAgICAgImVycm9yIjogXygiRmlsZSBhbHJlYWR5IGV4aXN0cyIpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgbG9nX3JlY29yZDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmlzaF9kYXRlPWZpZWxkcy5EYXRldGltZS5ub3coKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzPWNvbW1hbmRfcmVzdWx0WyJzdGF0dXMiXSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2U9Y29tbWFuZF9yZXN1bHRbInJlc3BvbnNlIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yPWNvbW1hbmRfcmVzdWx0WyJlcnJvciJdLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbW1hbmRfcmVzdWx0CgogICAgICAgICAgICAjIENvbnRleHQgaXMgdXNlZCB0byBkZXRlY3QgYSByZXRyeQogICAgICAgICAgICAjIGFuZCBhdm9pZCBoYW5kbGluZyBza2lwIGxvZ2ljIG9uIGZpcnN0IGF0dGVtcHQKICAgICAgICAgICAgaXNfY3JlYXRpb25fc2tpcHBlZCA9IGZpbGUuX2NvbnRleHQuZ2V0KCJmaWxlX2NyZWF0aW9uX3NraXBwZWQiKQoKICAgICAgICAgICAgaWYgbm90IGlzX2NyZWF0aW9uX3NraXBwZWQ6CiAgICAgICAgICAgICAgICBpZiBmaWxlLnNvdXJjZSA9PSAic2VydmVyIjoKICAgICAgICAgICAgICAgICAgICBmaWxlLmFjdGlvbl9wdWxsX2Zyb21fc2VydmVyKCkKICAgICAgICAgICAgICAgIGVsaWYgZmlsZS5zb3VyY2UgPT0gInRvd2VyIjoKICAgICAgICAgICAgICAgICAgICBmaWxlLmFjdGlvbl9wdXNoX3RvX3NlcnZlcigpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFVzZXJFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGaWxlIHNvdXJjZSBjYW5ub3QgYmUgZGV0ZXJtaW5lZDogJyUoc291cmNlKXMnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZT1maWxlLnNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIGxvZ19yZWNvcmQuY29tbWFuZF9pZC5kaXNjb25uZWN0X2ZpbGU6CiAgICAgICAgICAgICAgICBmaWxlLmFjdGlvbl91bmxpbmtfZnJvbV90ZW1wbGF0ZSgpCgogICAgICAgICAgICBpZiBpc19jcmVhdGlvbl9za2lwcGVkOgogICAgICAgICAgICAgICAgcmV0dXJuIGxvZ19yZWNvcmQuZmluaXNoKAogICAgICAgICAgICAgICAgICAgIGZpZWxkcy5EYXRldGltZS5ub3coKSwKICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgIF8oIkZpbGUgYWxyZWFkeSBleGlzdHMgb24gc2VydmVyLiBVcGxvYWQgc2tpcHBlZCIpLAogICAgICAgICAgICAgICAgICAgIE5vbmUsCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICAjIExvZyB0aGUgc3VjY2Vzc2Z1bCBjcmVhdGlvbiBhbmQgdXBsb2FkIG9mIHRoZSBmaWxlCiAgICAgICAgICAgIHJldHVybiBsb2dfcmVjb3JkLmZpbmlzaCgKICAgICAgICAgICAgICAgIGZpbmlzaF9kYXRlPWZpZWxkcy5EYXRldGltZS5ub3coKSwKICAgICAgICAgICAgICAgIHN0YXR1cz0wLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9XygiRmlsZSBjcmVhdGVkIGFuZCB1cGxvYWRlZCBzdWNjZXNzZnVsbHkiKSwKICAgICAgICAgICAgICAgIGVycm9yPU5vbmUsCiAgICAgICAgICAgICkKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICAjIExvZyBhbnkgZXhjZXB0aW9uIHRoYXQgb2NjdXJzIGR1cmluZyB0aGUgcHJvY2VzcwogICAgICAgICAgICBsb2dfcmVjb3JkLmZpbmlzaCgKICAgICAgICAgICAgICAgIGZpbmlzaF9kYXRlPWZpZWxkcy5EYXRldGltZS5ub3coKSwKICAgICAgICAgICAgICAgIHN0YXR1cz1GSUxFX0NSRUFUSU9OX0ZBSUxFRCwKICAgICAgICAgICAgICAgIHJlc3BvbnNlPU5vbmUsCiAgICAgICAgICAgICAgICBlcnJvcj1fKCJBbiBlcnJvciBvY2N1cnJlZDogJShlcnJvcilzIiwgZXJyb3I9c3RyKGUpKSwKICAgICAgICAgICAgKQoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXJfc3NoKAogICAgICAgIHNlbGYsCiAgICAgICAgbG9nX3JlY29yZCwKICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGUsCiAgICAgICAgc3Vkbz1Ob25lLAogICAgICAgIHJlbmRlcmVkX2NvbW1hbmRfcGF0aD1Ob25lLAogICAgICAgIHNzaF9jb25uZWN0aW9uPU5vbmUsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgICIiIlJ1biBTU0ggY29tbWFuZC4KICAgICAgICBVcGRhdGVzIHRoZSByZWNvcmQgaW4gdGhlIENvbW1hbmQgTG9nIChjeC50b3dlci5jb21tYW5kLmxvZykKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIuY29tbWFuZC5sb2coKSk6IENvbW1hbmQgbG9nIHJlY29yZAogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX2NvZGUgKFRleHQpOiBSZW5kZXJlZCBjb21tYW5kIGNvZGUuCiAgICAgICAgICAgICAgICBXZSBhcmUgcGFzc2luZyBpbiBjYXNlIGl0IGRpZmZlcnMgZnJvbSBjb21tYW5kIGNvZGUgaW4gdGhlIGxvZyByZWNvcmQuCiAgICAgICAgICAgIHN1ZG8gKFNlbGVjdGlvbik6IENvbW1hbmQgc3VkbyBtb2RlLiBEZWZhdWx0cyB0byBOb25lLgogICAgICAgICAgICByZW5kZXJlZF9jb21tYW5kX3BhdGggKENoYXIsIG9wdGlvbmFsKTogUmVuZGVyZWQgY29tbWFuZCBwYXRoLgogICAgICAgICAgICBzc2hfY29ubmVjdGlvbiAoU1NIIGNsaWVudCBpbnN0YW5jZSwgb3B0aW9uYWwpOiBTU0ggY29ubmVjdGlvbiB0byByZXVzZS4KICAgICAgICBrd2FyZ3MgKGRpY3QpOiAgZXh0cmEgYXJndW1lbnRzLiBVc2UgdG8gcGFzcyBleHRlcm5hbCB2YWx1ZXMuCiAgICAgICAgICAgICAgICBGb2xsb3dpbmcga2V5cyBhcmUgc3VwcG9ydGVkIGJ5IGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgIC0gImtleSI6IHt2YWx1ZXMgcGFzc2VkIHRvIGtleSBwYXJzZXJ9CiAgICAgICAgICAgICAgICAgICAgLSAicmFpc2Vfb25fZXJyb3IiOiBSYWlzZSBleGNlcHRpb24gb24gZXJyb3IuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogY29tbWFuZCBydW5uaW5nIHJlc3VsdCBpZiBgbG9nX3JlY29yZGAgaXMgZGVmaW5lZCBlbHNlIE5vbmUKICAgICAgICAiIiIKICAgICAgICByYWlzZV9vbl9lcnJvciA9IGt3YXJncy5nZXQoInJhaXNlX29uX2Vycm9yIiwgRmFsc2UpCiAgICAgICAgaWYgbm90IHNzaF9jb25uZWN0aW9uOgogICAgICAgICAgICBzc2hfY29ubmVjdGlvbiA9IHNlbGYuX2dldF9zc2hfY2xpZW50KHJhaXNlX29uX2Vycm9yPXJhaXNlX29uX2Vycm9yKQoKICAgICAgICAjIFJ1biBjb21tYW5kCiAgICAgICAgY29tbWFuZF9yZXN1bHQgPSBzZWxmLl9ydW5fY29tbWFuZF91c2luZ19zc2goCiAgICAgICAgICAgIGNsaWVudD1zc2hfY29ubmVjdGlvbiwKICAgICAgICAgICAgY29tbWFuZF9jb2RlPXJlbmRlcmVkX2NvbW1hbmRfY29kZSwKICAgICAgICAgICAgY29tbWFuZF9wYXRoPXJlbmRlcmVkX2NvbW1hbmRfcGF0aCwKICAgICAgICAgICAgcmFpc2Vfb25fZXJyb3I9cmFpc2Vfb25fZXJyb3IsCiAgICAgICAgICAgIHN1ZG89c3VkbywKICAgICAgICAgICAgKiprd2FyZ3MsCiAgICAgICAgKQoKICAgICAgICAjIExvZyByZXN1bHQKICAgICAgICBpZiBsb2dfcmVjb3JkOgogICAgICAgICAgICBsb2dfcmVjb3JkLmZpbmlzaCgKICAgICAgICAgICAgICAgIGZpbmlzaF9kYXRlPWZpZWxkcy5EYXRldGltZS5ub3coKSwKICAgICAgICAgICAgICAgIHN0YXR1cz1jb21tYW5kX3Jlc3VsdFsic3RhdHVzIl0sCiAgICAgICAgICAgICAgICByZXNwb25zZT1jb21tYW5kX3Jlc3VsdFsicmVzcG9uc2UiXSwKICAgICAgICAgICAgICAgIGVycm9yPWNvbW1hbmRfcmVzdWx0WyJlcnJvciJdLAogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGNvbW1hbmRfcmVzdWx0CgogICAgZGVmIF9jb21tYW5kX3J1bm5lcl9mbGlnaHRfcGxhbigKICAgICAgICBzZWxmLCBsb2dfcmVjb3JkLCBmbGlnaHRfcGxhbiwgcmFpc2Vfb25fZXJyb3I9RmFsc2UsICoqa3dhcmdzCiAgICApOgogICAgICAgICIiIgogICAgICAgIFJ1biBGbGlnaHQgcGxhbiBmcm9tIGNvbW1hbmQuCiAgICAgICAgVXBkYXRlcyB0aGUgcmVjb3JkIGluIHRoZSBDb21tYW5kIExvZyAoY3gudG93ZXIuY29tbWFuZC5sb2cpCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIuY29tbWFuZC5sb2coKSk6IENvbW1hbmQgbG9nIHJlY29yZC4KICAgICAgICAgICAgZmxpZ2h0X3BsYW4gKGN4LnRvd2VyLnBsYW4oKSk6IEZsaWdodCBQbGFuIHRvIGJlIHJ1bi4KICAgICAgICAgICAgcmFpc2Vfb25fZXJyb3IgKGJvb2wsIG9wdGlvbmFsKTogcmFpc2UgZXJyb3Igb24gZXJyb3IuCiAgICAgICAgICAgIGt3YXJncyAoZGljdCk6ICBleHRyYSBhcmd1bWVudHMuIFVzZSB0byBwYXNzIGV4dGVybmFsIHZhbHVlcy4KICAgICAgICAgICAgICAgICAgICBGb2xsb3dpbmcga2V5cyBhcmUgc3VwcG9ydGVkIGJ5IGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC0gImxvZyI6IHt2YWx1ZXMgcGFzc2VkIHRvIGxvZ2dlcn0KICAgICAgICAgICAgICAgICAgICAgICAgLSAia2V5Ijoge3ZhbHVlcyBwYXNzZWQgdG8ga2V5IHBhcnNlcn0KICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0KCk6IGZsaWdodCBwbGFuIHJ1bm5pbmcgcmVzdWx0IGlmIGBsb2dfcmVjb3JkYCBpcwogICAgICAgICAgICAgICAgICAgIG5vdCBkZWZpbmVkIGVsc2UgTm9uZQogICAgICAgICIiIgogICAgICAgIHJlc3BvbnNlID0gTm9uZQogICAgICAgIGVycm9yID0gTm9uZQogICAgICAgIHN0YXR1cyA9IDAKICAgICAgICBwbGFuX2xvZ19yZWNvcmQgPSBOb25lCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIEdlbmVyYXRlIGN1c3RvbSBsYWJlbCBhbmQgYWRkIHZhbHVlcyBmb3IgbG9nCiAgICAgICAgICAgIGt3YXJnc1sicGxhbl9sb2ciXSA9IHsKICAgICAgICAgICAgICAgICJsYWJlbCI6IGdlbmVyYXRlX3JhbmRvbV9pZCg0KSwKICAgICAgICAgICAgICAgICJwYXJlbnRfZmxpZ2h0X3BsYW5fbG9nX2lkIjogbG9nX3JlY29yZC5wbGFuX2xvZ19pZC5pZCwKICAgICAgICAgICAgfQogICAgICAgICAgICAjIGFkZCBleGVjdXRlZCBjb21tYW5kIHdpdGggYWN0aW9uICJwbGFuIiB0byBzYXZlIGxpbmsgdG8gcGxhbiBsb2cKICAgICAgICAgICAga3dhcmdzWyJmbGlnaHRfcGxhbl9jb21tYW5kX2xvZyJdID0gbG9nX3JlY29yZAogICAgICAgICAgICBwbGFuX2xvZ19yZWNvcmQgPSBmbGlnaHRfcGxhbi53aXRoX2NvbnRleHQoZnJvbV9jb21tYW5kPVRydWUpLl9ydW5fc2luZ2xlKAogICAgICAgICAgICAgICAgc2VydmVyPXNlbGYsCiAgICAgICAgICAgICAgICBqZXRfdGVtcGxhdGU9bG9nX3JlY29yZC5qZXRfdGVtcGxhdGVfaWQsCiAgICAgICAgICAgICAgICBqZXQ9bG9nX3JlY29yZC5qZXRfaWQsCiAgICAgICAgICAgICAgICAqKmt3YXJncywKICAgICAgICAgICAgKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogICMgcHlsaW50OiBkaXNhYmxlPWJyb2FkLWV4Y2VwdGlvbi1jYXVnaHQKICAgICAgICAgICAgaWYgcmFpc2Vfb25fZXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgXygiRmxpZ2h0IHBsYW4gcnVubmluZyBlcnJvciAlKGVycilzIiwgZXJyPWUpCiAgICAgICAgICAgICAgICApIGZyb20gZQogICAgICAgICAgICBzdGF0dXMgPSBHRU5FUkFMX0VSUk9SCiAgICAgICAgICAgIGVycm9yID0gZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIHBsYW5fbG9nX3JlY29yZC5wbGFuX3N0YXR1cyAhPSAwOgogICAgICAgICAgICAgICAgc3RhdHVzID0gcGxhbl9sb2dfcmVjb3JkLnBsYW5fc3RhdHVzCiAgICAgICAgICAgICAgICBlcnJvciA9IF8oIkZsaWdodCBwbGFuIHJ1bm5pbmcgZXJyb3IiKQoKICAgICAgICByZXN1bHQgPSB7InN0YXR1cyI6IHN0YXR1cywgInJlc3BvbnNlIjogcmVzcG9uc2UsICJlcnJvciI6IGVycm9yfQogICAgICAgIGlmIGxvZ19yZWNvcmQ6CiAgICAgICAgICAgIGxvZ19yZWNvcmQuZmluaXNoKAogICAgICAgICAgICAgICAgZmluaXNoX2RhdGU9ZmllbGRzLkRhdGV0aW1lLm5vdygpLAogICAgICAgICAgICAgICAgc3RhdHVzPXJlc3VsdFsic3RhdHVzIl0sCiAgICAgICAgICAgICAgICByZXNwb25zZT1yZXN1bHRbInJlc3BvbnNlIl0sCiAgICAgICAgICAgICAgICBlcnJvcj1yZXN1bHRbImVycm9yIl0sCiAgICAgICAgICAgICAgICB2YXJpYWJsZV92YWx1ZXM9cGxhbl9sb2dfcmVjb3JkLnZhcmlhYmxlX3ZhbHVlcwogICAgICAgICAgICAgICAgaWYgcGxhbl9sb2dfcmVjb3JkCiAgICAgICAgICAgICAgICBlbHNlIE5vbmUsCiAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIF9jb21tYW5kX3J1bm5lcl9weXRob25fY29kZSgKICAgICAgICBzZWxmLAogICAgICAgIGxvZ19yZWNvcmQsCiAgICAgICAgcmVuZGVyZWRfY29kZSwKICAgICAgICAqKmt3YXJncywKICAgICk6CiAgICAgICAgIiIiCiAgICAgICAgUnVuIFB5dGhvbiBjb2RlLgogICAgICAgIFVwZGF0ZXMgdGhlIHJlY29yZCBpbiB0aGUgQ29tbWFuZCBMb2cgKGN4LnRvd2VyLmNvbW1hbmQubG9nKQoKICAgICAgICBBcmdzOgogICAgICAgICAgICBsb2dfcmVjb3JkIChjeC50b3dlci5jb21tYW5kLmxvZygpKTogQ29tbWFuZCBsb2cgcmVjb3JkCiAgICAgICAgICAgIHJlbmRlcmVkX2NvZGUgKFRleHQpOiBSZW5kZXJlZCBweXRob24gY29kZS4KICAgICAgICBrd2FyZ3MgKGRpY3QpOiAgZXh0cmEgYXJndW1lbnRzLiBVc2UgdG8gcGFzcyBleHRlcm5hbCB2YWx1ZXMuCiAgICAgICAgICAgICAgICBGb2xsb3dpbmcga2V5cyBhcmUgc3VwcG9ydGVkIGJ5IGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgIC0gImtleSI6IHt2YWx1ZXMgcGFzc2VkIHRvIGtleSBwYXJzZXJ9CgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogcHl0aG9uIGNvZGUgcnVubmluZyByZXN1bHQgaWYgYGxvZ19yZWNvcmRgIGlzCiAgICAgICAgICAgICAgICAgICAgbm90IGRlZmluZWQgZWxzZSBOb25lCiAgICAgICAgIiIiCiAgICAgICAgIyBSdW4gcHl0aG9uIGNvZGUKICAgICAgICByZXN1bHQgPSBzZWxmLl9ydW5fcHl0aG9uX2NvZGUoCiAgICAgICAgICAgIGNvZGU9cmVuZGVyZWRfY29kZSwKICAgICAgICAgICAgcmFpc2Vfb25fZXJyb3I9RmFsc2UsCiAgICAgICAgICAgICoqa3dhcmdzLAogICAgICAgICkKCiAgICAgICAgIyBMb2cgcmVzdWx0CiAgICAgICAgaWYgbG9nX3JlY29yZDoKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBmaW5pc2hfZGF0ZT1maWVsZHMuRGF0ZXRpbWUubm93KCksCiAgICAgICAgICAgICAgICBzdGF0dXM9cmVzdWx0WyJzdGF0dXMiXSwKICAgICAgICAgICAgICAgIHJlc3BvbnNlPXJlc3VsdFsicmVzcG9uc2UiXSwKICAgICAgICAgICAgICAgIGVycm9yPXJlc3VsdFsiZXJyb3IiXSwKICAgICAgICAgICAgICAgIHZhcmlhYmxlX3ZhbHVlcz1yZXN1bHRbInZhcmlhYmxlX3ZhbHVlcyJdLAogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXJfamV0X2FjdGlvbigKICAgICAgICBzZWxmLAogICAgICAgIGxvZ19yZWNvcmQsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgICIiIgogICAgICAgIFJ1biBKZXQgYWN0aW9uLgogICAgICAgIFVwZGF0ZXMgdGhlIHJlY29yZCBpbiB0aGUgQ29tbWFuZCBMb2cgKGN4LnRvd2VyLmNvbW1hbmQubG9nKQoKICAgICAgICBBcmdzOgogICAgICAgICAgICBsb2dfcmVjb3JkIChjeC50b3dlci5jb21tYW5kLmxvZygpKTogQ29tbWFuZCBsb2cgcmVjb3JkCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogamV0IGFjdGlvbiBydW5uaW5nIHJlc3VsdCBpZiBgbG9nX3JlY29yZGAgaXMKICAgICAgICAgICAgICAgICAgICBub3QgZGVmaW5lZCBlbHNlIE5vbmUKCiAgICAgICAgUmFpc2VzOgogICAgICAgICAgICBWYWxpZGF0aW9uRXJyb3I6IGlmIGBsb2dfcmVjb3JkYCBpcyBub3QgZGVmaW5lZAogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBsb2dfcmVjb3JkOgogICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICBfKCJDb21tYW5kIGxvZyBpcyByZXF1aXJlZCBmb3IgJ0pldCBBY3Rpb24nIGNvbW1hbmRzISIpCiAgICAgICAgICAgICkKCiAgICAgICAgIyBJbml0aWFsaXplIHJlc3VsdCB2YWx1ZXMKICAgICAgICBzdGF0dXMgPSAwCiAgICAgICAgcmVzcG9uc2UgPSBOb25lCiAgICAgICAgZXJyb3IgPSBOb25lCiAgICAgICAgZGVwZW5kZW50X2pldHMgPSBOb25lCgogICAgICAgICMgR2V0IHRoZSBhY3Rpb24gZnJvbSB0aGUgY29tbWFuZAogICAgICAgIGFjdGlvbiA9IGxvZ19yZWNvcmQuY29tbWFuZF9pZC5qZXRfYWN0aW9uX2lkCiAgICAgICAgaWYgbm90IGFjdGlvbjoKICAgICAgICAgICAgc3RhdHVzID0gR0VORVJBTF9FUlJPUgogICAgICAgICAgICBlcnJvciA9IF8oIkpldCBhY3Rpb24gaXMgbm90IGZvdW5kLiIpCiAgICAgICAgICAgIGxvZ19yZWNvcmQuZmluaXNoKAogICAgICAgICAgICAgICAgc3RhdHVzPXN0YXR1cywKICAgICAgICAgICAgICAgIHJlc3BvbnNlPXJlc3BvbnNlLAogICAgICAgICAgICAgICAgZXJyb3I9ZXJyb3IsCiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuIHsic3RhdHVzIjogc3RhdHVzLCAicmVzcG9uc2UiOiByZXNwb25zZSwgImVycm9yIjogZXJyb3J9CgogICAgICAgIGpldF9mb3Jfd2hpY2hfY29tbWFuZF9pc19ydW4gPSBsb2dfcmVjb3JkLmpldF9pZAogICAgICAgIHJlcXVlc3RlZF9qZXRfdGVtcGxhdGUgPSBsb2dfcmVjb3JkLmNvbW1hbmRfaWQuamV0X3RlbXBsYXRlX2lkCgogICAgICAgIGlmIG5vdCBqZXRfZm9yX3doaWNoX2NvbW1hbmRfaXNfcnVuOgogICAgICAgICAgICBzdGF0dXMgPSBKRVRfTk9UX0ZPVU5ECiAgICAgICAgICAgIGVycm9yID0gXygiSmV0IGZvciB3aGljaCBjb21tYW5kIGlzIHJ1biBpcyBub3QgZm91bmQuIikKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9cmVzcG9uc2UsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4geyJzdGF0dXMiOiBzdGF0dXMsICJyZXNwb25zZSI6IHJlc3BvbnNlLCAiZXJyb3IiOiBlcnJvcn0KICAgICAgICBpZiBub3QgcmVxdWVzdGVkX2pldF90ZW1wbGF0ZToKICAgICAgICAgICAgc3RhdHVzID0gSkVUX1RFTVBMQVRFX05PVF9GT1VORAogICAgICAgICAgICBlcnJvciA9IF8oIkpldCB0ZW1wbGF0ZSBpcyBub3QgZm91bmQuIikKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9cmVzcG9uc2UsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4geyJzdGF0dXMiOiBzdGF0dXMsICJyZXNwb25zZSI6IHJlc3BvbnNlLCAiZXJyb3IiOiBlcnJvcn0KCiAgICAgICAgIyBUcmlnZ2VyIGZvciB0aGUgamV0IGl0c2VsZiBpZiB0aGUgc2FtZSBqZXQgdGVtcGxhdGUgaXMgdXNlZAogICAgICAgICMgVGhpcyBpcyB1c2VkIHdoZW4geW91IHdhbnQgdG8gdHJpZ2dlciBhbiBhY3Rpb24gZm9yCiAgICAgICAgIyB0aGUgc2FtZSBqZXQgZm9yIHdoaWNoIHRoZSBjb21tYW5kIGlzIHJ1bi4KICAgICAgICBpZiBqZXRfZm9yX3doaWNoX2NvbW1hbmRfaXNfcnVuLmpldF90ZW1wbGF0ZV9pZCA9PSByZXF1ZXN0ZWRfamV0X3RlbXBsYXRlOgogICAgICAgICAgICBkZXBlbmRlbnRfamV0cyA9IGpldF9mb3Jfd2hpY2hfY29tbWFuZF9pc19ydW4KICAgICAgICBlbHNlOgogICAgICAgICAgICAjIEdldCBkZXBlbmRlbnQgamV0cyBieSB0ZW1wbGF0ZQogICAgICAgICAgICBkZXBlbmRlbnRfamV0cyA9ICgKICAgICAgICAgICAgICAgIGpldF9mb3Jfd2hpY2hfY29tbWFuZF9pc19ydW4uX2dldF9kZXBlbmRlbnRfamV0c19ieV90ZW1wbGF0ZSgKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0ZWRfamV0X3RlbXBsYXRlCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKCiAgICAgICAgaWYgZGVwZW5kZW50X2pldHM6CiAgICAgICAgICAgICMgVHJpZ2dlciB0aGUgYWN0aW9uIGZvciBhbGwgZGVwZW5kZW50IGpldHM7IGFnZ3JlZ2F0ZSBmYWlsdXJlcyBhcwogICAgICAgICAgICAjICJyZWY6IG1lc3NhZ2UsIHJlZjI6IG1lc3NhZ2UyIiBmb3IgdGhlIGNvbW1hbmQgbG9nLgogICAgICAgICAgICBlcnJvcl9wYXJ0cyA9IFtdCiAgICAgICAgICAgIGZvciBqZXQgaW4gZGVwZW5kZW50X2pldHM6CiAgICAgICAgICAgICAgICByZXN1bHQgPSBqZXQuX3RyaWdnZXJfYWN0aW9uKAogICAgICAgICAgICAgICAgICAgIGFjdGlvbj1hY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgcmFpc2VfaWZfbm90X2F2YWlsYWJsZT1GYWxzZSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGlmIG5vdCByZXN1bHQ6CiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGpldF9zdGF0dXMgPSByZXN1bHQuZ2V0KCJzdGF0dXMiLCAwKQogICAgICAgICAgICAgICAgamV0X2Vycm9yID0gcmVzdWx0LmdldCgiZXJyb3IiKQogICAgICAgICAgICAgICAgaWYgamV0X3N0YXR1cyA9PSAwIGFuZCBub3QgamV0X2Vycm9yOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICBpZiBqZXRfZXJyb3I6CiAgICAgICAgICAgICAgICAgICAgZXJyb3JfcGFydHMuYXBwZW5kKGYie2pldC5yZWZlcmVuY2V9OiB7amV0X2Vycm9yfSIpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGVycm9yX3BhcnRzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlKGpldClzOiBhY3Rpb24gZmFpbGVkIChzdGF0dXMgJShzdGF0dXMpcykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgamV0PWpldC5yZWZlcmVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM9amV0X3N0YXR1cywKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgIyBDb21wb3NlIHRoZSBtYWluIG1lc3NhZ2UKICAgICAgICAgICAgamV0X3JlZmVyZW5jZXMgPSAiLCAiLmpvaW4oamV0LnJlZmVyZW5jZSBmb3IgamV0IGluIGRlcGVuZGVudF9qZXRzKQoKICAgICAgICAgICAgbWFpbl9tZXNzYWdlID0gXygKICAgICAgICAgICAgICAgICJBY3Rpb24gdHJpZ2dlcmVkIGZvciAlKGpldF9yZWZlcmVuY2VzKXMiLAogICAgICAgICAgICAgICAgamV0X3JlZmVyZW5jZXM9amV0X3JlZmVyZW5jZXMsCiAgICAgICAgICAgICkKCiAgICAgICAgICAgIGlmIGVycm9yX3BhcnRzOgogICAgICAgICAgICAgICAgc3RhdHVzID0gR0VORVJBTF9FUlJPUgogICAgICAgICAgICAgICAgZXJyb3IgPSAiXG4iLmpvaW4oCiAgICAgICAgICAgICAgICAgICAgWwogICAgICAgICAgICAgICAgICAgICAgICBtYWluX21lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3BhcnRzWzBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBsZW4oZXJyb3JfcGFydHMpID09IDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgIiwgIi5qb2luKGVycm9yX3BhcnRzKQogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gTm9uZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBtYWluX21lc3NhZ2UKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9cmVzcG9uc2UsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgKQogICAgICAgICMgSWYgbm8gZGVwZW5kZW50IGpldHMsIGZpbmlzaCB0aGUgY29tbWFuZAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHN0YXR1cyA9IDAgICMgbm8gZGVwZW5kZW50IGpldHMsIHNvIHRoZSBjb21tYW5kIGlzIGZpbmlzaGVkIHdpdGggbm8gZXJyb3IKICAgICAgICAgICAgcmVzcG9uc2UgPSBfKAogICAgICAgICAgICAgICAgIkpldCAlKGpldClzIGhhcyBubyBkZXBlbmRlbnQgamV0cyB3aXRoIHRlbXBsYXRlICUodGVtcGxhdGUpcy4iLAogICAgICAgICAgICAgICAgamV0PWpldF9mb3Jfd2hpY2hfY29tbWFuZF9pc19ydW4ubmFtZSwKICAgICAgICAgICAgICAgIHRlbXBsYXRlPXJlcXVlc3RlZF9qZXRfdGVtcGxhdGUubmFtZSwKICAgICAgICAgICAgKQoKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9cmVzcG9uc2UsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgKQogICAgICAgICMgUmV0dXJuIHJlc3VsdAogICAgICAgIHJldHVybiB7InN0YXR1cyI6IHN0YXR1cywgInJlc3BvbnNlIjogcmVzcG9uc2UsICJlcnJvciI6IGVycm9yfQoKICAgIGRlZiBfY29tbWFuZF9ydW5uZXJfY3JlYXRlX3dheXBvaW50KHNlbGYsIGxvZ19yZWNvcmQsICoqa3dhcmdzKToKICAgICAgICAiIiJSdW4gQ3JlYXRlIGEgV2F5cG9pbnQgY29tbWFuZC4KCiAgICAgICAgQ3JlYXRlcyBhIHdheXBvaW50IGZvciB0aGUgcGxhbidzIGpldCBmcm9tIHRoZSBjb21tYW5kJ3Mgd2F5cG9pbnQgdGVtcGxhdGUuCiAgICAgICAgVGhlIGZsaWdodCBwbGFuIHNldHMgdGhlIGpldCBhcyBidXN5LCBzbyB3ZSBwYXNzIGlnbm9yZV9idXN5PVRydWUgc28KICAgICAgICBjcmVhdGlvbiBpcyBhbGxvd2VkLiBUaGUgY29tbWFuZCBsb2cgaXMgbm90IGZpbmlzaGVkIGhlcmUgd2hlbiBhIHdheXBvaW50CiAgICAgICAgaXMgY3JlYXRlZDsgdGhlIHdheXBvaW50IGNhbGxiYWNrIChfZmluYWxpemVfY3JlYXRlX3dheXBvaW50X2NvbW1hbmRfbG9nKQogICAgICAgIGZpbmlzaGVzIGl0IHdoZW4gdGhlIHdheXBvaW50IHJlYWNoZXMgcmVhZHkvY3VycmVudCBvciBlcnJvci4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbG9nX3JlY29yZCAoY3gudG93ZXIuY29tbWFuZC5sb2cpOiBDb21tYW5kIGxvZyByZWNvcmQuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IHN0YXR1cywgcmVzcG9uc2UgKGUuZy4gd2F5cG9pbnQgaWQgd2hlbiBjcmVhdGVkKSwgZXJyb3IuCiAgICAgICAgICAgICAgICBXaGVuIHdheXBvaW50IGlzIGNyZWF0ZWQsIHN0YXR1cyAwIGFuZCByZXNwb25zZSBpbmRpY2F0ZQogICAgICAgICAgICAgICAgZGVmZXJyZWQgY29tcGxldGlvbjsgdGhlIGxvZyBzdGF5cyBydW5uaW5nIHVudGlsIHRoZSBjYWxsYmFjay4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgbG9nX3JlY29yZDoKICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgXygiQ29tbWFuZCBsb2cgaXMgcmVxdWlyZWQgZm9yICdDcmVhdGUgYSBXYXlwb2ludCcgY29tbWFuZHMhIikKICAgICAgICAgICAgKQogICAgICAgIGNvbW1hbmQgPSBsb2dfcmVjb3JkLmNvbW1hbmRfaWQKICAgICAgICBqZXQgPSBsb2dfcmVjb3JkLmpldF9pZAogICAgICAgIHdheXBvaW50X3RlbXBsYXRlID0gY29tbWFuZC53YXlwb2ludF90ZW1wbGF0ZV9pZAoKICAgICAgICBzdGF0dXMgPSAwCiAgICAgICAgcmVzcG9uc2UgPSBOb25lCiAgICAgICAgZXJyb3IgPSBOb25lCgogICAgICAgIGlmIG5vdCBqZXQ6CiAgICAgICAgICAgIHN0YXR1cyA9IEpFVF9OT1RfRk9VTkQKICAgICAgICAgICAgZXJyb3IgPSBfKCJKZXQgZm9yIHdoaWNoIGNvbW1hbmQgaXMgcnVuIGlzIG5vdCBmb3VuZC4iKQogICAgICAgICAgICBsb2dfcmVjb3JkLmZpbmlzaCgKICAgICAgICAgICAgICAgIHN0YXR1cz1zdGF0dXMsCiAgICAgICAgICAgICAgICByZXNwb25zZT1yZXNwb25zZSwKICAgICAgICAgICAgICAgIGVycm9yPWVycm9yLAogICAgICAgICAgICApCiAgICAgICAgICAgIHJldHVybiB7InN0YXR1cyI6IHN0YXR1cywgInJlc3BvbnNlIjogcmVzcG9uc2UsICJlcnJvciI6IGVycm9yfQoKICAgICAgICBpZiBub3Qgd2F5cG9pbnRfdGVtcGxhdGU6CiAgICAgICAgICAgIHN0YXR1cyA9IFdBWVBPSU5UX1RFTVBMQVRFX05PVF9GT1VORAogICAgICAgICAgICBlcnJvciA9IF8oIldheXBvaW50IHRlbXBsYXRlIGlzIG5vdCBzZXQuIikKICAgICAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgICAgICBzdGF0dXM9c3RhdHVzLAogICAgICAgICAgICAgICAgcmVzcG9uc2U9cmVzcG9uc2UsCiAgICAgICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4geyJzdGF0dXMiOiBzdGF0dXMsICJyZXNwb25zZSI6IHJlc3BvbnNlLCAiZXJyb3IiOiBlcnJvcn0KCiAgICAgICAgdHJ5OgogICAgICAgICAgICB3YXlwb2ludCA9IGpldC5jcmVhdGVfd2F5cG9pbnQoCiAgICAgICAgICAgICAgICB3YXlwb2ludF90ZW1wbGF0ZSwKICAgICAgICAgICAgICAgIGZseV9oZXJlPWNvbW1hbmQuZmx5X2hlcmUsCiAgICAgICAgICAgICAgICBpZ25vcmVfYnVzeT1UcnVlLAogICAgICAgICAgICAgICAgY3JlYXRlZF9mcm9tX2NvbW1hbmRfbG9nPWxvZ19yZWNvcmQsCiAgICAgICAgICAgICkKICAgICAgICBleGNlcHQgVmFsaWRhdGlvbkVycm9yOgogICAgICAgICAgICB3YXlwb2ludCA9IEZhbHNlCgogICAgICAgIGlmIG5vdCB3YXlwb2ludDoKICAgICAgICAgICAgc3RhdHVzID0gV0FZUE9JTlRfQ1JFQVRFX0ZBSUxFRAogICAgICAgICAgICBlcnJvciA9IF8oCiAgICAgICAgICAgICAgICAiV2F5cG9pbnQgY3JlYXRpb24gZmFpbGVkIChlLmcuIHdheXBvaW50IHRlbXBsYXRlICIKICAgICAgICAgICAgICAgICJkb2VzIG5vdCBtYXRjaCBqZXQgdGVtcGxhdGUpLiIKICAgICAgICAgICAgKQogICAgICAgICAgICBsb2dfcmVjb3JkLmZpbmlzaCgKICAgICAgICAgICAgICAgIHN0YXR1cz1zdGF0dXMsCiAgICAgICAgICAgICAgICByZXNwb25zZT1yZXNwb25zZSwKICAgICAgICAgICAgICAgIGVycm9yPWVycm9yLAogICAgICAgICAgICApCiAgICAgICAgICAgIHJldHVybiB7InN0YXR1cyI6IHN0YXR1cywgInJlc3BvbnNlIjogcmVzcG9uc2UsICJlcnJvciI6IGVycm9yfQoKICAgICAgICAjIERvIG5vdCBmaW5pc2ggdGhlIGxvZzsgd2F5cG9pbnQgY2FsbGJhY2sgd2lsbCBmaW5pc2ggaXQgd2hlbgogICAgICAgICMgcmVhZHkvY3VycmVudC9lcnJvcgogICAgICAgIHJlc3BvbnNlID0geyJ3YXlwb2ludF9pZCI6IHdheXBvaW50LmlkfQogICAgICAgIHJldHVybiB7InN0YXR1cyI6IDAsICJyZXNwb25zZSI6IHJlc3BvbnNlLCAiZXJyb3IiOiBOb25lfQoKICAgIEBlbnN1cmVfc3NoX2Rpc2Nvbm5lY3QKICAgIGRlZiBfcnVuX2NvbW1hbmRfdXNpbmdfc3NoKAogICAgICAgIHNlbGYsCiAgICAgICAgY2xpZW50LAogICAgICAgIGNvbW1hbmRfY29kZSwKICAgICAgICBjb21tYW5kX3BhdGg9Tm9uZSwKICAgICAgICByYWlzZV9vbl9lcnJvcj1GYWxzZSwKICAgICAgICBzdWRvPU5vbmUsCiAgICAgICAgKiprd2FyZ3MsCiAgICApOgogICAgICAgICIiIlRoaXMgaXMgYSBsb3cgbGV2ZWwgbWV0aG9kIGZvciBydW5uaW5nIGFuIFNTSCBjb21tYW5kLgogICAgICAgIFVzZSBpdCBpbiBjYXNlIHlvdSBuZWVkIHRvIGdldCBkaXJlY3Qgb3V0cHV0IG9mIGFuIFNTSCBjb21tYW5kLgogICAgICAgIE90aGVyd2lzZSBjYWxsIGBydW5fY29tbWFuZCgpYAoKICAgICAgICBBcmdzOgogICAgICAgICAgICBjbGllbnQgKENvbm5lY3Rpb24pOiB2YWxpZCBzZXJ2ZXIgc3NoIGNvbm5lY3Rpb24gb2JqZWN0CiAgICAgICAgICAgIGNvbW1hbmRfY29kZSAoVGV4dCk6IGNvbW1hbmQgdGV4dAogICAgICAgICAgICBjb21tYW5kX3BhdGggKENoYXIsIG9wdGlvbmFsKTogZGlyZWN0b3J5IHdoZXJlIGNvbW1hbmQgc2hvdWxkIGJlIHJ1bgogICAgICAgICAgICByYWlzZV9vbl9lcnJvciAoYm9vbCwgb3B0aW9uYWwpOiByYWlzZSBlcnJvciBvbiBlcnJvcgogICAgICAgICAgICBzdWRvIChTZWxlY3Rpb24pOiBDb21tYW5kIHN1ZG8gbW9kZS4gRGVmYXVsdHMgdG8gTm9uZS4gRGVmYXVsdHMgdG8gTm9uZS4KICAgICAgICAgICAga3dhcmdzIChkaWN0KTogIGV4dHJhIGFyZ3VtZW50cy4gVXNlIHRvIHBhc3MgZXh0ZXJuYWwgdmFsdWVzLgogICAgICAgICAgICAgICAgICAgIEZvbGxvd2luZyBrZXlzIGFyZSBzdXBwb3J0ZWQgYnkgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgICAgICAtICJrZXkiOiB7dmFsdWVzIHBhc3NlZCB0byBrZXkgcGFyc2VyfQoKICAgICAgICBSYWlzZXM6CiAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvcjogaWYgY2xpZW50IGlzIG5vdCB2YWxpZAogICAgICAgICAgICBWYWxpZGF0aW9uRXJyb3I6IGNvbW1hbmQgcnVuIGVycm9yCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IHsKICAgICAgICAgICAgICAgICJzdGF0dXMiOiA8aW50PiwKICAgICAgICAgICAgICAgICJyZXNwb25zZSI6IFRleHQsCiAgICAgICAgICAgICAgICAiZXJyb3IiOiBUZXh0CiAgICAgICAgICAgIH0KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgY2xpZW50OgogICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihfKCJTU0ggQ2xpZW50IGlzIG5vdCBkZWZpbmVkLiIpKQogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgInN0YXR1cyI6IFNTSF9DT05ORUNUSU9OX0VSUk9SLAogICAgICAgICAgICAgICAgInJlc3BvbnNlIjogRmFsc2UsCiAgICAgICAgICAgICAgICAiZXJyb3IiOiBfKCJTU0ggQ2xpZW50IGlzIG5vdCBkZWZpbmVkLiIpLAogICAgICAgICAgICB9CgogICAgICAgICMgQ2xpZW50IGNvbnRhaW5zIGEgcmVzdWx0IG9mIF9nZXRfc3NoX2NsaWVudCgpCiAgICAgICAgIyBJZiBpdCdzIGEgdHVwbGUsIGl0IG1lYW5zIHRoZXJlIHdhcyBhbiBlcnJvciBnZXR0aW5nIHRoZSBjbGllbnQKICAgICAgICBpZiBpc2luc3RhbmNlKGNsaWVudCwgdHVwbGUpOgogICAgICAgICAgICBlcnJvciA9IGNsaWVudFsxXQogICAgICAgICAgICBpZiByYWlzZV9vbl9lcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihlcnJvcikKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJzdGF0dXMiOiBTU0hfQ09OTkVDVElPTl9FUlJPUiwKICAgICAgICAgICAgICAgICJyZXNwb25zZSI6IEZhbHNlLAogICAgICAgICAgICAgICAgImVycm9yIjogZXJyb3IsCiAgICAgICAgICAgIH0KCiAgICAgICAgIyBQYXJzZSBpbmxpbmUgc2VjcmV0cwogICAgICAgIGNvZGVfYW5kX3NlY3JldHMgPSBzZWxmLmVudlsiY3gudG93ZXIua2V5Il0uX3BhcnNlX2NvZGVfYW5kX3JldHVybl9rZXlfdmFsdWVzKAogICAgICAgICAgICBjb21tYW5kX2NvZGUsICoqa3dhcmdzLmdldCgia2V5Iiwge30pCiAgICAgICAgKQogICAgICAgIGNvbW1hbmRfY29kZSA9IGNvZGVfYW5kX3NlY3JldHNbImNvZGUiXQogICAgICAgIHNlY3JldHMgPSBjb2RlX2FuZF9zZWNyZXRzWyJrZXlfdmFsdWVzIl0KCiAgICAgICAgIyBQcmVwYXJlIHNzaCBjb21tYW5kCiAgICAgICAgcHJlcGFyZWRfY29tbWFuZF9jb2RlID0gc2VsZi5fcHJlcGFyZV9zc2hfY29tbWFuZCgKICAgICAgICAgICAgY29tbWFuZF9jb2RlLAogICAgICAgICAgICBjb21tYW5kX3BhdGgsCiAgICAgICAgICAgIHN1ZG8sCiAgICAgICAgICAgICoqa3dhcmdzLAogICAgICAgICkKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzdGF0dXMgPSBbXQogICAgICAgICAgICByZXNwb25zZSA9IFtdCiAgICAgICAgICAgIGVycm9yID0gW10KCiAgICAgICAgICAgICMgQ29tbWFuZCBpcyBhIHNpbmdsZSBzdGluZy4gTm8gJ3N1ZG8nIG9yICdzdWRvJyB3L28gcGFzc3dvcmQKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShwcmVwYXJlZF9jb21tYW5kX2NvZGUsIHN0cik6CiAgICAgICAgICAgICAgICBzdGF0dXMsIHJlc3BvbnNlLCBlcnJvciA9IGNsaWVudC5jb21tYW5kX2V4ZWN1dG9yLmV4ZWNfY29tbWFuZCgKICAgICAgICAgICAgICAgICAgICBwcmVwYXJlZF9jb21tYW5kX2NvZGUsIHN1ZG89c3VkbwogICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgIyBNdWx0aXBsZSBjb21tYW5kczogc3VkbyB3aXRoIHBhc3N3b3JkCiAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShwcmVwYXJlZF9jb21tYW5kX2NvZGUsIGxpc3QpOgogICAgICAgICAgICAgICAgZm9yIGNtZCBpbiBwcmVwYXJlZF9jb21tYW5kX2NvZGU6CiAgICAgICAgICAgICAgICAgICAgc3QsIHJlc3AsIGVyciA9IGNsaWVudC5jb21tYW5kX2V4ZWN1dG9yLmV4ZWNfY29tbWFuZChjbWQsIHN1ZG89c3VkbykKICAgICAgICAgICAgICAgICAgICBzdGF0dXMuYXBwZW5kKHN0KQogICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlICs9IHJlc3AKICAgICAgICAgICAgICAgICAgICBlcnJvciArPSBlcnIKCiAgICAgICAgICAgICMgU29tZXRoaW5nIHdlaXJkICkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBHRU5FUkFMX0VSUk9SCgogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgaWYgcmFpc2Vfb25fZXJyb3I6CiAgICAgICAgICAgICAgICBfbG9nZ2VyLmVycm9yKGYiU1NIIHJ1biBjb21tYW5kIGVycm9yOiB7ZX0iKQogICAgICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKF8oIlNTSCBydW4gY29tbWFuZCBlcnJvciAlKGVycilzIiwgZXJyPWUpKSBmcm9tIGUKICAgICAgICAgICAgc3RhdHVzID0gR0VORVJBTF9FUlJPUgogICAgICAgICAgICByZXNwb25zZSA9IFtdCiAgICAgICAgICAgIGVycm9yID0gW2VdCgogICAgICAgIHJlc3VsdCA9IHNlbGYuX3BhcnNlX2NvbW1hbmRfcmVzdWx0cyhzdGF0dXMsIHJlc3BvbnNlLCBlcnJvciwgc2VjcmV0cywgKiprd2FyZ3MpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcnVuX3B5dGhvbl9jb2RlKAogICAgICAgIHNlbGYsCiAgICAgICAgY29kZSwKICAgICAgICByYWlzZV9vbl9lcnJvcj1GYWxzZSwKICAgICAgICAqKmt3YXJncywKICAgICk6CiAgICAgICAgIiIiCiAgICAgICAgVGhpcyBpcyBhIGxvdyBsZXZlbCBtZXRob2QgZm9yIFB5dGhvbiBjb2RlIHJ1bm5pbmcuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGNvZGUgKFRleHQpOiBweXRob24gY29kZQogICAgICAgICAgICByYWlzZV9vbl9lcnJvciAoYm9vbCwgb3B0aW9uYWwpOiByYWlzZSBlcnJvciBvbiBlcnJvcgogICAgICAgICAgICBrd2FyZ3MgKGRpY3QpOiAgZXh0cmEgYXJndW1lbnRzLiBVc2UgdG8gcGFzcyBleHRlcm5hbCB2YWx1ZXMuCiAgICAgICAgICAgICAgICBGb2xsb3dpbmcga2V5cyBhcmUgc3VwcG9ydGVkIGJ5IGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLSAibG9nIjoge3ZhbHVlcyBwYXNzZWQgdG8gbG9nZ2VyfQogICAgICAgICAgICAgICAgICAgIC0gImtleSI6IHt2YWx1ZXMgcGFzc2VkIHRvIGtleSBwYXJzZXJ9CgogICAgICAgIFJhaXNlczoKICAgICAgICAgICAgVmFsaWRhdGlvbkVycm9yOiBweXRob24gY29kZSBydW5uaW5nIGVycm9yCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IHsKICAgICAgICAgICAgICAgICJzdGF0dXMiOiA8aW50PiwKICAgICAgICAgICAgICAgICJyZXNwb25zZSI6IFRleHQsCiAgICAgICAgICAgICAgICAiZXJyb3IiOiBUZXh0CiAgICAgICAgICAgIH0KICAgICAgICAiIiIKICAgICAgICByZXNwb25zZSA9IE5vbmUKICAgICAgICBlcnJvciA9IE5vbmUKICAgICAgICBzdGF0dXMgPSAwCiAgICAgICAgc2VjcmV0cyA9IE5vbmUKCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIFBhcnNlIGlubGluZSBzZWNyZXRzCiAgICAgICAgICAgIGNvZGVfYW5kX3NlY3JldHMgPSBzZWxmLmVudlsKICAgICAgICAgICAgICAgICJjeC50b3dlci5rZXkiCiAgICAgICAgICAgIF0uX3BhcnNlX2NvZGVfYW5kX3JldHVybl9rZXlfdmFsdWVzKAogICAgICAgICAgICAgICAgY29kZSwgcHl0aG9uaWNfbW9kZT1UcnVlLCAqKmt3YXJncy5nZXQoImtleSIsIHt9KQogICAgICAgICAgICApCiAgICAgICAgICAgIHNlY3JldHMgPSBjb2RlX2FuZF9zZWNyZXRzLmdldCgia2V5X3ZhbHVlcyIpCiAgICAgICAgICAgIGNvbW1hbmRfY29kZSA9IGNvZGVfYW5kX3NlY3JldHNbImNvZGUiXQoKICAgICAgICAgICAgY29kZSA9IHNlbGYuZW52WyJjeC50b3dlci5rZXkiXS5fcGFyc2VfY29kZSgKICAgICAgICAgICAgICAgIGNvbW1hbmRfY29kZSwgcHl0aG9uaWNfbW9kZT1UcnVlLCAqKmt3YXJncy5nZXQoImtleSIsIHt9KQogICAgICAgICAgICApCgogICAgICAgICAgICAjIENoZWNrIGlmIGNvZGUgY29udGFpbnMgYmFubmVkIGtleXdvcmRzCiAgICAgICAgICAgIGJhbm5lZF9rZXl3b3JkcyA9IHNlbGYuZW52WwogICAgICAgICAgICAgICAgImN4LnRvd2VyLmNvbW1hbmQiCiAgICAgICAgICAgIF0uX2dldF9iYW5uZWRfcHl0aG9uX2NvZGVfa2V5d29yZHMoKQogICAgICAgICAgICBmb3IgYmFubmVkX2tleXdvcmQgaW4gYmFubmVkX2tleXdvcmRzOgogICAgICAgICAgICAgICAgaWYgYmFubmVkX2tleXdvcmQgaW4gY29kZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9sbG93aW5nIGtleXdvcmQgaXMgbm90IGFsbG93ZWQgaW4gUHl0aG9uIGNvZGU6IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAnJShiYW5uZWRfa2V5d29yZClzJyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYW5uZWRfa2V5d29yZD1iYW5uZWRfa2V5d29yZCwKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgIyBHZXQgamV0IHRlbXBsYXRlLCBqZXQgYW5kIHdheXBvaW50IGZyb20ga3dhcmdzIG9yIGxvZwogICAgICAgICAgICBsb2dfdmFscyA9IGt3YXJncy5nZXQoImxvZyIsIHt9KQogICAgICAgICAgICBpZiBsb2dfdmFsczoKICAgICAgICAgICAgICAgIGpldF90ZW1wbGF0ZV9pZCA9IGxvZ192YWxzLmdldCgiamV0X3RlbXBsYXRlX2lkIikKICAgICAgICAgICAgICAgIGpldF9pZCA9IGxvZ192YWxzLmdldCgiamV0X2lkIikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGpldF90ZW1wbGF0ZV9pZCA9IGt3YXJncy5nZXQoImpldF90ZW1wbGF0ZV9pZCIpCiAgICAgICAgICAgICAgICBqZXRfaWQgPSBrd2FyZ3MuZ2V0KCJqZXRfaWQiKQogICAgICAgICAgICB3YXlwb2ludCA9IGt3YXJncy5nZXQoIndheXBvaW50IikKCiAgICAgICAgICAgIGpldF90ZW1wbGF0ZSA9ICgKICAgICAgICAgICAgICAgIHNlbGYuZW52WyJjeC50b3dlci5qZXQudGVtcGxhdGUiXS5icm93c2UoamV0X3RlbXBsYXRlX2lkKQogICAgICAgICAgICAgICAgaWYgamV0X3RlbXBsYXRlX2lkCiAgICAgICAgICAgICAgICBlbHNlIE5vbmUKICAgICAgICAgICAgKQogICAgICAgICAgICBqZXQgPSBzZWxmLmVudlsiY3gudG93ZXIuamV0Il0uYnJvd3NlKGpldF9pZCkgaWYgamV0X2lkIGVsc2UgTm9uZQoKICAgICAgICAgICAgIyBHZXQgdGhlIGV2YWx1YXRpb24gY29udGV4dCBmb3IgdGhlIHB5dGhvbiBjb21tYW5kCiAgICAgICAgICAgIGV2YWxfY29udGV4dCA9IHNlbGYuZW52WwogICAgICAgICAgICAgICAgImN4LnRvd2VyLmNvbW1hbmQiCiAgICAgICAgICAgIF0uX2dldF9weXRob25fY29tbWFuZF9ldmFsX2NvbnRleHQoCiAgICAgICAgICAgICAgICBzZXJ2ZXI9c2VsZiwKICAgICAgICAgICAgICAgIGpldF90ZW1wbGF0ZT1qZXRfdGVtcGxhdGUsCiAgICAgICAgICAgICAgICBqZXQ9amV0LAogICAgICAgICAgICAgICAgd2F5cG9pbnQ9d2F5cG9pbnQsCiAgICAgICAgICAgICAgICB2YXJpYWJsZV92YWx1ZXM9a3dhcmdzLmdldCgidmFyaWFibGVfdmFsdWVzIiwge30pLAogICAgICAgICAgICApCgogICAgICAgICAgICBzYWZlX2V2YWwoCiAgICAgICAgICAgICAgICBjb2RlLAogICAgICAgICAgICAgICAgZXZhbF9jb250ZXh0LAogICAgICAgICAgICAgICAgbW9kZT0iZXhlYyIsCiAgICAgICAgICAgICAgICBub2NvcHk9VHJ1ZSwKICAgICAgICAgICAgKQogICAgICAgICAgICBrd2FyZ3NbInZhcmlhYmxlX3ZhbHVlcyJdID0gZXZhbF9jb250ZXh0LmdldCgiY3VzdG9tX3ZhbHVlcyIsIHt9KQogICAgICAgICAgICByZXN1bHQgPSBldmFsX2NvbnRleHQuZ2V0KCJyZXN1bHQiKQogICAgICAgICAgICBpZiByZXN1bHQ6CiAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXN1bHQuZ2V0KCJleGl0X2NvZGUiLCAwKQogICAgICAgICAgICAgICAgaWYgc3RhdHVzID09IDA6CiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBbcmVzdWx0LmdldCgibWVzc2FnZSIpXQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFtyZXN1bHQuZ2V0KCJtZXNzYWdlIildCgogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTogICMgcHlsaW50OiBkaXNhYmxlPWJyb2FkLWV4Y2VwdGlvbi1jYXVnaHQKICAgICAgICAgICAgaWYgcmFpc2Vfb25fZXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgXygiUHl0aG9uIGNvZGUgcnVubmluZyBlcnJvcjogJShlcnIpcyIsIGVycj1lKQogICAgICAgICAgICAgICAgKSBmcm9tIGUKICAgICAgICAgICAgc3RhdHVzID0gUFlUSE9OX0NPTU1BTkRfRVJST1IKICAgICAgICAgICAgZXJyb3IgPSBbZV0KCiAgICAgICAgcmVzdWx0ID0gc2VsZi5fcGFyc2VfY29tbWFuZF9yZXN1bHRzKHN0YXR1cywgcmVzcG9uc2UsIGVycm9yLCBzZWNyZXRzLCAqKmt3YXJncykKICAgICAgICByZXN1bHRbInZhcmlhYmxlX3ZhbHVlcyJdID0ga3dhcmdzLmdldCgidmFyaWFibGVfdmFsdWVzIiwge30pCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcHJlcGFyZV9zc2hfY29tbWFuZChzZWxmLCBjb21tYW5kX2NvZGUsIHBhdGg9Tm9uZSwgc3Vkbz1Ob25lLCAqKmt3YXJncyk6CiAgICAgICAgIiIiUHJlcGFyZSBzc2ggY29tbWFuZAogICAgICAgIElNUE9SVEFOVDoKICAgICAgICBDb21tYW5kcyBydW4gd2l0aCBzdWRvIHdpbGwgYmUgcnVuIHNlcGFyYXRlbHkgb25lIGFmdGVyIGFub3RoZXIKICAgICAgICBldmVuIGlmIHRoZXJlIGlzIGEgc2luZ2xlIGNvbW1hbmQgc2VwYXJhdGVkIHdpdGggJyYmJwogICAgICAgIEV4YW1wbGVzOgogICAgICAgICAgICAjIERlZmF1bHQgKHN1ZG8gd2l0aCBzcGxpdHRpbmcpOgogICAgICAgICAgICAicHdkICYmIGxzIC1sIiBiZWNvbWVzOgogICAgICAgICAgICAgICAgc3VkbyBwd2QKICAgICAgICAgICAgICAgIHN1ZG8gbHMgLWwKCiAgICAgICAgICAgICMgV2l0aCBub19zcGxpdF9mb3Jfc3Vkbz1UcnVlOgogICAgICAgICAgICAgICAgc3VkbyBwd2QgJiYgbHMgLWwKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgY29tbWFuZF9jb2RlIChzdHIpOiBpbml0aWFsIGNvbW1hbmQKICAgICAgICAgICAgcGF0aCAoc3RyLCBvcHRpb25hbCk6IGRpcmVjdG9yeSB3aGVyZSBjb21tYW5kIHNob3VsZCBiZSBydW4KICAgICAgICAgICAgc3VkbyAoc3RyLCBvcHRpb25hbCk6IHN1ZG8gbW9kZSAoJ24nIG9yICdwJykKICAgICAgICAgICAgICAgICduJyDigJQgc3VkbyB3aXRob3V0IHBhc3N3b3JkCiAgICAgICAgICAgICAgICAncCcg4oCUIHN1ZG8gd2l0aCBwYXNzd29yZAogICAgICAgICAgICBrd2FyZ3MgKGRpY3QpOiBleHRyYSBhcmd1bWVudHMuIFN1cHBvcnRlZCBrZXlzOgogICAgICAgICAgICAgICAgLSAibG9nIjogdmFsdWVzIHBhc3NlZCB0byBsb2dnZXIKICAgICAgICAgICAgICAgIC0gImtleSI6IHZhbHVlcyBwYXNzZWQgdG8ga2V5IHBhcnNlcgogICAgICAgICAgICAgICAgLSAibm9fc3BsaXRfZm9yX3N1ZG8iIChib29sKTogaWYgVHJ1ZSwgZG8gbm90IHNwbGl0IG9uICcmJicKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgbGlzdCBvciBzdHI6IGlmIHN1ZG89J3AnICh3aXRoIHBhc3N3b3JkKSwgcmV0dXJucyBhIGxpc3Qgb2YgY29tbWFuZHM7CiAgICAgICAgICAgICAgICBpZiBzdWRvPSduJywgcmV0dXJucyBhIHNpbmdsZSBzdHJpbmcgKHBvc3NpYmx5IGpvaW5lZCBieSAnJiYnKTsKICAgICAgICAgICAgICAgIHdpdGhvdXQgc3VkbywgcmV0dXJucyB0aGUgcmF3IGNvbW1hbmRfY29kZS4KICAgICAgICAiIiIKICAgICAgICAjIFByZXBhcmUgY29tbWFuZCBmb3Igc3VkbyBpZiBuZWVkZWQKICAgICAgICBpZiBzdWRvOgogICAgICAgICAgICAjIEFkZCBsb2NhdGlvbgogICAgICAgICAgICBzdWRvX3ByZWZpeCA9ICJzdWRvIC1TIC1wICcnIgoKICAgICAgICAgICAgbm9fc3BsaXQgPSBrd2FyZ3MuZ2V0KCJub19zcGxpdF9mb3Jfc3VkbyIsIEZhbHNlKQoKICAgICAgICAgICAgc2VwYXJhdG9yID0gIiYmIgogICAgICAgICAgICAjIHNwbGl0IG9ubHkgd2hlbiAnJiYnIGlzIHByZXNlbnQgQU5EIHNwbGl0dGluZyBpcyBub3QgZGlzYWJsZWQKICAgICAgICAgICAgaWYgc2VwYXJhdG9yIGluIGNvbW1hbmRfY29kZSBhbmQgbm90IG5vX3NwbGl0OgogICAgICAgICAgICAgICAgcmVzdWx0ID0gKAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmRfY29kZS5yZXBsYWNlKCJcXCIsICIiKS5yZXBsYWNlKCJcbiIsICIiKS5zcGxpdChzZXBhcmF0b3IpCiAgICAgICAgICAgICAgICApCgogICAgICAgICAgICAgICAgIyBTdWRvIHdpdGggcGFzc3dvcmQgZXhwZWN0cyBhIGxpc3Qgb2YgY29tbWFuZHMKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFtmIntzdWRvX3ByZWZpeH0ge2NtZC5zdHJpcCgpfSIgZm9yIGNtZCBpbiByZXN1bHRdCgogICAgICAgICAgICAgICAgIyBNZXJnZSBiYWNrIGludG8gYSBzaW5nbGUgY29tbWFuZCBpcyBzdWRvIGlzIHdpdGhvdXQgcGFzc3dvcmQKICAgICAgICAgICAgICAgIGlmIHN1ZG8gPT0gIm4iOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGYiIHtzZXBhcmF0b3J9ICIuam9pbihyZXN1bHQpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIHNpbmdsZSBjb21tYW5kIG9yIG5vX3NwbGl0IHJlcXVlc3RlZAogICAgICAgICAgICAgICAgcmVzdWx0ID0gZiJ7c3Vkb19wcmVmaXh9IHtjb21tYW5kX2NvZGV9IgogICAgICAgICAgICAgICAgIyBTdWRvIHdpdGggcGFzc3dvcmQgZXhwZWN0cyBhIGxpc3Qgb2YgY29tbWFuZHMKICAgICAgICAgICAgICAgIGlmIHN1ZG8gPT0gInAiOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFtyZXN1bHRdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBDb21tYW5kIHdpdGhvdXQgc3VkbyBpcyBhbHdheXMgcnVuIGFzIGlzCiAgICAgICAgICAgIHJlc3VsdCA9IGNvbW1hbmRfY29kZQogICAgICAgICMgQWRkIHBhdGggY2hhbmdlIGNvbW1hbmQKICAgICAgICBpZiBwYXRoOgogICAgICAgICAgICAjIEFkZCBzdWRvIHByZWZpeCBpZiBuZWVkZWQKICAgICAgICAgICAgY2RfY29tbWFuZCA9IGYiY2Qge3BhdGh9IgoKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShyZXN1bHQsIGxpc3QpOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gW2NkX2NvbW1hbmRdICsgcmVzdWx0CiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZXN1bHQgPSBmIntjZF9jb21tYW5kfSAmJiB7cmVzdWx0fSIKCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcGFyc2VfY29tbWFuZF9yZXN1bHRzKAogICAgICAgIHNlbGYsIHN0YXR1cywgcmVzcG9uc2UsIGVycm9yLCBrZXlfdmFsdWVzPU5vbmUsICoqa3dhcmdzCiAgICApOgogICAgICAgICIiIgogICAgICAgIFBhcnNlIHJlc3VsdHMgb2YgYSBjb21tYW5kIHJ1biB3aXRoIHN1ZG8gKGVpdGhlciBTU0ggb3IgUHl0aG9uKS4KICAgICAgICBSZW1vdmVzIHNlY3JldHMgYW5kIGZvcm1hdHMgdGhlIHJlc3BvbnNlIGFuZCBlcnJvciBtZXNzYWdlcy4KCiAgICAgICAgUGFyYW1pa28gcmV0dXJucyBTU0ggcmVzcG9uc2UgYW5kIGVycm9yIGFzIGxpc3QuCiAgICAgICAgV2hlbiBydW5uaW5nIGEgY29tbWFuZCB3aXRoIHN1ZG8gd2l0aCBwYXNzd29yZCB3ZSByZXR1cm4gc3RhdHVzIGFzIGEgbGlzdCB0b28uCiAgICAgICAgXwoKICAgICAgICBBcmdzOgogICAgICAgICAgICBzdGF0dXMgKEludCBvciBsaXN0IG9mIGludCk6IFN0YXR1cyBvciBzdGF0dXNlcwogICAgICAgICAgICByZXNwb25zZSAobGlzdCk6IFJlc3BvbnNlCiAgICAgICAgICAgIGVycm9yIChsaXN0KTogRXJyb3IKICAgICAgICAgICAga2V5X3ZhbHVlcyAobGlzdCk6IFNlY3JldHMgdGhhdCB3ZXJlIGRpc2NvdmVyZWQgaW4gY29kZS4KICAgICAgICAgICAgICAgIFVzZWQgdG8gY2xlYW4gdXAgY29tbWFuZCByZXN1bHQuCiAgICAgICAgICAgIGt3YXJncyAoZGljdCk6ICBleHRyYSBhcmd1bWVudHMuIFVzZSB0byBwYXNzIGV4dGVybmFsIHZhbHVlcy4KICAgICAgICAgICAgICAgIEZvbGxvd2luZyBrZXlzIGFyZSBzdXBwb3J0ZWQgYnkgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAtICJsb2ciOiB7dmFsdWVzIHBhc3NlZCB0byBsb2dnZXJ9CiAgICAgICAgICAgICAgICAgICAgLSAia2V5Ijoge3ZhbHVlcyBwYXNzZWQgdG8ga2V5IHBhcnNlcn0KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgZGljdDogewogICAgICAgICAgICAgICAgInN0YXR1cyI6IDxpbnQ+LAogICAgICAgICAgICAgICAgInJlc3BvbnNlIjogPHRleHQ+LAogICAgICAgICAgICAgICAgImVycm9yIjogPHRleHQ+CiAgICAgICAgICAgIH0KICAgICAgICAiIiIKCiAgICAgICAgIyBJbiBjYXNlIG9mIHNldmVyYWwgc3RhdHVzZXMgd2UgcmV0dXJuIHRoZSBsYXN0IG9uZSB0aGF0IGlzIG5vdCAwICgib2siKQogICAgICAgICMgRWcgZm9yIFswLDEsMCw0LDBdIHJlc3VsdCB3aWxsIGJlIDQKICAgICAgICBpZiBpc2luc3RhbmNlKHN0YXR1cywgbGlzdCk6CiAgICAgICAgICAgIGZpbmFsX3N0YXR1cyA9IDAKICAgICAgICAgICAgZm9yIHN0IGluIHN0YXR1czoKICAgICAgICAgICAgICAgIGlmIHN0ICE9IDAgYW5kIHN0ICE9IHN0YXR1czoKICAgICAgICAgICAgICAgICAgICBmaW5hbF9zdGF0dXMgPSBzdAoKICAgICAgICAgICAgc3RhdHVzID0gZmluYWxfc3RhdHVzCgogICAgICAgICMgVGhpcyBpcyBuZWVkZWQgdG8gcmVtb3ZlIGtleXMKICAgICAgICBpZiBrZXlfdmFsdWVzOgogICAgICAgICAgICBrZXlfbW9kZWwgPSBzZWxmLmVudlsiY3gudG93ZXIua2V5Il0KCiAgICAgICAgIyBDb21wb3NlIHJlc3BvbnNlIG1lc3NhZ2UKICAgICAgICBpZiByZXNwb25zZSBhbmQgaXNpbnN0YW5jZShyZXNwb25zZSwgbGlzdCk6CiAgICAgICAgICAgICMgUmVwbGFjZSBzZWNyZXRzIHdpdGggc3BvaWxlcgogICAgICAgICAgICByZXNwb25zZV92YWxzID0gWwogICAgICAgICAgICAgICAga2V5X21vZGVsLl9yZXBsYWNlX3dpdGhfc3BvaWxlcihzdHIociksIGtleV92YWx1ZXMpCiAgICAgICAgICAgICAgICBpZiBrZXlfdmFsdWVzCiAgICAgICAgICAgICAgICBlbHNlIHN0cihyKQogICAgICAgICAgICAgICAgZm9yIHIgaW4gcmVzcG9uc2UKICAgICAgICAgICAgXQogICAgICAgICAgICByZXNwb25zZSA9ICIiLmpvaW4ocmVzcG9uc2VfdmFscykKCiAgICAgICAgZWxpZiBub3QgcmVzcG9uc2U6CiAgICAgICAgICAgICMgRm9yIG5vdCB0byBzYXZlIGFuIGVtcHR5IGxpc3QgYFtdYCBpbiBsb2cKICAgICAgICAgICAgcmVzcG9uc2UgPSBOb25lCgogICAgICAgICMgQ29tcG9zZSBlcnJvciBtZXNzYWdlCiAgICAgICAgaWYgZXJyb3IgYW5kIGlzaW5zdGFuY2UoZXJyb3IsIGxpc3QpOgogICAgICAgICAgICAjIFJlcGxhY2Ugc2VjcmV0cyB3aXRoIHNwb2lsZXIKICAgICAgICAgICAgZXJyb3JfdmFscyA9IFsKICAgICAgICAgICAgICAgIGtleV9tb2RlbC5fcmVwbGFjZV93aXRoX3Nwb2lsZXIoc3RyKGUpLCBrZXlfdmFsdWVzKQogICAgICAgICAgICAgICAgaWYga2V5X3ZhbHVlcwogICAgICAgICAgICAgICAgZWxzZSBzdHIoZSkKICAgICAgICAgICAgICAgIGZvciBlIGluIGVycm9yCiAgICAgICAgICAgIF0KICAgICAgICAgICAgZXJyb3IgPSAiIi5qb2luKGVycm9yX3ZhbHMpCiAgICAgICAgZWxpZiBub3QgZXJyb3I6CiAgICAgICAgICAgICMgRm9yIG5vdCB0byBzYXZlIGFuIGVtcHR5IGxpc3QgYFtdYCBpbiBsb2cKICAgICAgICAgICAgZXJyb3IgPSBOb25lCgogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICJzdGF0dXMiOiBzdGF0dXMsCiAgICAgICAgICAgICJyZXNwb25zZSI6IHJlc3BvbnNlLAogICAgICAgICAgICAiZXJyb3IiOiBlcnJvciwKICAgICAgICB9CgogICAgZGVmIF9jaGVja196b21iaWVfY29tbWFuZHMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ2hlY2sgY29tbWFuZHMgdGhhdCBhcmUgcnVubmluZyBsb25nZXIgdGhhbiB0aGUgdGltZW91dAogICAgICAgIGFuZCBtYXJrIHRoZW0gYXMgZmluaXNoZWQKICAgICAgICAiIiIKICAgICAgICB0aW1lb3V0ID0gaW50KAogICAgICAgICAgICBzZWxmLmVudlsiaXIuY29uZmlnX3BhcmFtZXRlciJdCiAgICAgICAgICAgIC5zdWRvKCkKICAgICAgICAgICAgLmdldF9wYXJhbSgiY2V0bWl4X3Rvd2VyX3NlcnZlci5jb21tYW5kX3RpbWVvdXQiLCAwKQogICAgICAgICkKICAgICAgICBpZiBub3QgdGltZW91dDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU1NIIG9yIFB5dGhvbiBjb21tYW5kIGlzIHJ1bm5pbmcgbG9uZ2VyIHRoYW4gdGhlIHRpbWVvdXQKICAgICAgICAjIFdlIGFyZSBub3QgdGVybWluYXRpbmcgRmxpZ2h0IFBsYW5zIGFuZCBGaWxlIFVwbG9hZCBjb21tYW5kcwogICAgICAgIGRvbWFpbiA9IFsKICAgICAgICAgICAgKCJpc19ydW5uaW5nIiwgIj0iLCBUcnVlKSwKICAgICAgICAgICAgKCJzdGFydF9kYXRlIiwgIjwiLCBmaWVsZHMuRGF0ZXRpbWUubm93KCkgLSB0aW1lZGVsdGEoc2Vjb25kcz10aW1lb3V0KSksCiAgICAgICAgICAgICgiY29tbWFuZF9hY3Rpb24iLCAiaW4iLCBbInNzaF9jb21tYW5kIiwgInB5dGhvbl9jb2RlIl0pLAogICAgICAgIF0KICAgICAgICB6b21iaWVfY29tbWFuZF9sb2dzID0gc2VsZi5lbnZbImN4LnRvd2VyLmNvbW1hbmQubG9nIl0uc2VhcmNoKGRvbWFpbikKICAgICAgICBpZiB6b21iaWVfY29tbWFuZF9sb2dzOgogICAgICAgICAgICB6b21iaWVfY29tbWFuZF9sb2dzLmZpbmlzaCgKICAgICAgICAgICAgICAgIHN0YXR1cz1DT01NQU5EX1RJTUVEX09VVCwKICAgICAgICAgICAgICAgIHJlc3BvbnNlPU5vbmUsCiAgICAgICAgICAgICAgICBlcnJvcj1DT01NQU5EX1RJTUVEX09VVF9NRVNTQUdFLAogICAgICAgICAgICApCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLSBGaWxlIG1hbmFnZW1lbnQKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgQGVuc3VyZV9zc2hfZGlzY29ubmVjdAogICAgZGVmIGRlbGV0ZV9maWxlKHNlbGYsIHJlbW90ZV9wYXRoKToKICAgICAgICAiIiIKICAgICAgICBEZWxldGUgZmlsZSBmcm9tIHJlbW90ZSBzZXJ2ZXIKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgcmVtb3RlX3BhdGggKFRleHQpOiBmdWxsIHBhdGggZmlsZSBsb2NhdGlvbiB3aXRoIGZpbGUgdHlwZQogICAgICAgICAgICAgKGUuZy4gL3Rlc3QvbXlfZmlsZS50eHQpLgogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgY2xpZW50ID0gc2VsZi5fZ2V0X3NzaF9jbGllbnQocmFpc2Vfb25fZXJyb3I9VHJ1ZSkKICAgICAgICBjbGllbnQuc2Z0cF9zZXJ2aWNlLmRlbGV0ZV9maWxlKHJlbW90ZV9wYXRoKQoKICAgIEBlbnN1cmVfc3NoX2Rpc2Nvbm5lY3QKICAgIGRlZiB1cGxvYWRfZmlsZShzZWxmLCBkYXRhLCByZW1vdGVfcGF0aCwgZnJvbV9wYXRoPUZhbHNlKToKICAgICAgICAiIiIKICAgICAgICBVcGxvYWQgZmlsZSB0byByZW1vdGUgc2VydmVyLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBkYXRhIChUZXh0LCBCeXRlcyk6IElmIHRoZSBkYXRhIGFyZSB0ZXh0LCB0aGV5IGFyZSBjb252ZXJ0ZWQgdG8gYnl0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbnMgYSBsb2NhbCBmaWxlIHBhdGggaWYgZnJvbV9wYXRoPVRydWUuCiAgICAgICAgICAgIHJlbW90ZV9wYXRoIChUZXh0KTogZnVsbCBwYXRoIGZpbGUgbG9jYXRpb24gd2l0aCBmaWxlIHR5cGUKICAgICAgICAgICAgIChlLmcuIC90ZXN0L215X2ZpbGUudHh0KS4KICAgICAgICAgICAgZnJvbV9wYXRoIChCb29sZWFuKTogc2V0IFRydWUgaWYgYGRhdGFgIGlzIGZpbGUgcGF0aC4KCiAgICAgICAgUmFpc2U6CiAgICAgICAgICAgIFR5cGVFcnJvcjogaW5jb3JyZWN0IHR5cGUgb2YgZmlsZS4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgUmVzdWx0IChjbGFzcyBwYXJhbWlrby5zZnRwX2F0dHIuU0ZUUEF0dHJpYnV0ZXMpOiBtZXRhZGF0YSBvZiB0aGUKICAgICAgICAgICAgIHVwbG9hZGVkIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBjbGllbnQgPSBzZWxmLl9nZXRfc3NoX2NsaWVudChyYWlzZV9vbl9lcnJvcj1UcnVlKQogICAgICAgIGlmIGZyb21fcGF0aDoKICAgICAgICAgICAgcmVzdWx0ID0gY2xpZW50LnNmdHBfc2VydmljZS51cGxvYWRfZmlsZShkYXRhLCByZW1vdGVfcGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIENvbnZlcnQgc3RyaW5nIHRvIGJ5dGVzCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoZGF0YSwgc3RyKToKICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLmVuY29kZSgpCiAgICAgICAgICAgIGZpbGUgPSBpby5CeXRlc0lPKGRhdGEpCiAgICAgICAgICAgIHJlc3VsdCA9IGNsaWVudC5zZnRwX3NlcnZpY2UudXBsb2FkX2ZpbGUoZmlsZSwgcmVtb3RlX3BhdGgpCgogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBAZW5zdXJlX3NzaF9kaXNjb25uZWN0CiAgICBkZWYgZG93bmxvYWRfZmlsZShzZWxmLCByZW1vdGVfcGF0aCk6CiAgICAgICAgIiIiCiAgICAgICAgRG93bmxvYWQgZmlsZSBmcm9tIHJlbW90ZSBzZXJ2ZXIKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgcmVtb3RlX3BhdGggKFRleHQpOiBmdWxsIHBhdGggZmlsZSBsb2NhdGlvbiB3aXRoIGZpbGUgdHlwZQogICAgICAgICAgICAgKGUuZy4gL3Rlc3QvbXlfZmlsZS50eHQpLgoKICAgICAgICBSYWlzZToKICAgICAgICAgICAgVmFsaWRhdGlvbkVycm9yOiByYWlzZSBpZiBmaWxlIG5vdCBmb3VuZC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgUmVzdWx0IChCeXRlcyk6IGZpbGUgY29udGVudC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIGNsaWVudCA9IHNlbGYuX2dldF9zc2hfY2xpZW50KHJhaXNlX29uX2Vycm9yPVRydWUpCiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXN1bHQgPSBjbGllbnQuc2Z0cF9zZXJ2aWNlLmRvd25sb2FkX2ZpbGUocmVtb3RlX3BhdGgpCgogICAgICAgIGV4Y2VwdCBGaWxlTm90Rm91bmRFcnJvciBhcyBmZToKICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgXygiVGhlIGZpbGUgJShmX3BhdGgpcyBub3QgZm91bmQuIiwgZl9wYXRoPXJlbW90ZV9wYXRoKQogICAgICAgICAgICApIGZyb20gZmUKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLSBBdXhpbGlhcnkgZnVuY3Rpb25zCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGRlZiBnZXRfdmFyaWFibGVfdmFsdWUoc2VsZiwgdmFyaWFibGVfcmVmZXJlbmNlLCBub19mYWxsYmFjaz1GYWxzZSk6CiAgICAgICAgIiIiCiAgICAgICAgUmV0dXJuIHRoZSB2YWx1ZSBvZiBhIHZhcmlhYmxlIGZvciB0aGUgY3VycmVudCBzZXJ2ZXIuCiAgICAgICAgTkI6IHRoaXMgZnVuY3Rpb24gZm9sbG93cyB0aGUgdmFsdWUgYXBwbGljYXRpb24gb3JkZXIuCiAgICAgICAgU28gaXQgd2lsbCByZXR1cm4gdGhlIGdsb2JhbCB2YWx1ZSBpZiBzZXJ2ZXIgdmFsdWUgaXMgbm90IHNldC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgc3RyOiBUaGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGZvciB0aGUgY3VycmVudCByZWNvcmQgb3IgTm9uZQogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgdmFyaWFibGUgPSBzZWxmLmVudlsiY3gudG93ZXIudmFyaWFibGUiXS5nZXRfYnlfcmVmZXJlbmNlKHZhcmlhYmxlX3JlZmVyZW5jZSkKICAgICAgICBpZiBub3QgdmFyaWFibGU6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgdmFsdWVzID0gdmFyaWFibGUuX2dldF92YXJpYWJsZV92YWx1ZXNfYnlfcmVmZXJlbmNlcygKICAgICAgICAgICAgdmFyaWFibGVfcmVmZXJlbmNlcz1bdmFyaWFibGVfcmVmZXJlbmNlXSwgc2VydmVyPXNlbGYKICAgICAgICApCiAgICAgICAgcmV0dXJuIHZhbHVlc1t2YXJpYWJsZV9yZWZlcmVuY2VdCgogICAgZGVmIHNlcnZlcl90b2dnbGVfYWN0aXZlKHNlbGYsIHNlbGZfYWN0aXZlKToKICAgICAgICAiIiIKICAgICAgICBDaGFuZ2UgYWN0aXZlIHN0YXR1cyBvZiByZWxhdGVkIHJlY29yZHM6CiAgICAgICAgLSBmaWxlcwogICAgICAgIC0gY29tbWFuZHMKICAgICAgICAtIHBsYW5zCiAgICAgICAgLSB2YXJpYWJsZSB2YWx1ZXMKICAgICAgICBBZGQgY3VzdG9tIGxvZ2ljIHRvIHlvdXIgbW9kZWwgaWYgeW91IHdhbnQgdG8gY2hhbmdlCiAgICAgICAgdGhlIGFjdGl2ZSBzdGF0dXMgb2Ygb3RoZXIgcmVjb3Jkcy4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgc2VsZl9hY3RpdmUgKGJvb2wpOiBhY3RpdmUgc3RhdHVzIG9mIHRoZSByZWNvcmQKICAgICAgICAiIiIKICAgICAgICBzZWxmLmZpbGVfaWRzLmZpbHRlcmVkKGxhbWJkYSBmOiBmLmFjdGl2ZSA9PSBzZWxmX2FjdGl2ZSkudG9nZ2xlX2FjdGl2ZSgpCiAgICAgICAgc2VsZi5jb21tYW5kX2xvZ19pZHMuZmlsdGVyZWQobGFtYmRhIGM6IGMuYWN0aXZlID09IHNlbGZfYWN0aXZlKS50b2dnbGVfYWN0aXZlKCkKICAgICAgICBzZWxmLnBsYW5fbG9nX2lkcy5maWx0ZXJlZChsYW1iZGEgcDogcC5hY3RpdmUgPT0gc2VsZl9hY3RpdmUpLnRvZ2dsZV9hY3RpdmUoKQogICAgICAgIHNlbGYudmFyaWFibGVfdmFsdWVfaWRzLmZpbHRlcmVkKAogICAgICAgICAgICBsYW1iZGEgdnY6IHZ2LmFjdGl2ZSA9PSBzZWxmX2FjdGl2ZQogICAgICAgICkudG9nZ2xlX2FjdGl2ZSgpCgogICAgZGVmIHRvZ2dsZV9hY3RpdmUoc2VsZik6CiAgICAgICAgIiIiQXJjaGl2ZSBvciB1bmFyY2hpdmUgcmVsYXRlZCBzZXJ2ZXIiIiIKICAgICAgICByZXMgPSBzdXBlcigpLnRvZ2dsZV9hY3RpdmUoKQogICAgICAgIHNlcnZlcl9hY3RpdmUgPSBzZWxmLndpdGhfY29udGV4dChhY3RpdmVfdGVzdD1GYWxzZSkuZmlsdGVyZWQoCiAgICAgICAgICAgIGxhbWJkYSB4OiB4LmFjdGl2ZQogICAgICAgICkKICAgICAgICBzZXJ2ZXJfbm90X2FjdGl2ZSA9IHNlbGYgLSBzZXJ2ZXJfYWN0aXZlCiAgICAgICAgaWYgc2VydmVyX2FjdGl2ZToKICAgICAgICAgICAgc2VydmVyX2FjdGl2ZS5zZXJ2ZXJfdG9nZ2xlX2FjdGl2ZShGYWxzZSkKICAgICAgICBpZiBzZXJ2ZXJfbm90X2FjdGl2ZToKICAgICAgICAgICAgc2VydmVyX25vdF9hY3RpdmUuc2VydmVyX3RvZ2dsZV9hY3RpdmUoVHJ1ZSkKICAgICAgICByZXR1cm4gcmVzCgogICAgZGVmIF9pc19iZWluZ19kZWxldGVkKHNlbGYpOgogICAgICAgICIiIkNoZWNrIGlmIHRoZSBzZXJ2ZXIgaXMgYmVpbmcgZGVsZXRlZC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgYm9vbDogVHJ1ZSBpZiB0aGUgc2VydmVyIGlzIGJlaW5nIGRlbGV0ZWQsIEZhbHNlIG90aGVyd2lzZQogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgcmV0dXJuIHNlbGYuc3RhdHVzIGFuZCBzZWxmLnN0YXR1cyA9PSAiZGVsZXRpbmciCgogICAgZGVmIF9nZXRfcG9zdF9jcmVhdGVfZmllbGRzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIEFkZCBmaWVsZHMgdGhhdCBzaG91bGQgYmUgcG9wdWxhdGVkIGFmdGVyIHNlcnZlciBjcmVhdGlvbgogICAgICAgICIiIgogICAgICAgIHJlcyA9IHN1cGVyKCkuX2dldF9wb3N0X2NyZWF0ZV9maWVsZHMoKQogICAgICAgIHJldHVybiByZXMgKyBbInZhcmlhYmxlX3ZhbHVlX2lkcyIsICJzZXJ2ZXJfbG9nX2lkcyIsICJzZWNyZXRfaWRzIl0KCiAgICBkZWYgX2dldF9ub3RpZmljYXRpb25fYWN0aW9uKAogICAgICAgIHNlbGYsIG1lc3NhZ2UsIG5vdGlmaWNhdGlvbl90eXBlPSJpbmZvIiwgdGl0bGU9Tm9uZSwgc3RpY2t5PVRydWUKICAgICk6CiAgICAgICAgIiIiR2V0IG5vdGlmaWNhdGlvbiBhY3Rpb24KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgbWVzc2FnZSAoc3RyKTogTWVzc2FnZQogICAgICAgICAgICBub3RpZmljYXRpb25fdHlwZSAoc3RyLCBvcHRpb25hbCk6IE5vdGlmaWNhdGlvbiB0eXBlLiBEZWZhdWx0cyB0byAiaW5mbyIuCiAgICAgICAgICAgIHRpdGxlIChzdHIsIG9wdGlvbmFsKTogVGl0bGUuIERlZmF1bHRzIHRvIE5vbmUuCiAgICAgICAgICAgIHN0aWNreSAoYm9vbCwgb3B0aW9uYWwpOiBTdGlja3kgbm90aWZpY2F0aW9uLiBEZWZhdWx0cyB0byBUcnVlLgoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0OiBOb3RpZmljYXRpb24gYWN0aW9uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInR5cGUiOiAiaXIuYWN0aW9ucy5jbGllbnQiLAogICAgICAgICAgICAidGFnIjogImRpc3BsYXlfbm90aWZpY2F0aW9uIiwKICAgICAgICAgICAgInBhcmFtcyI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogbm90aWZpY2F0aW9uX3R5cGUsCiAgICAgICAgICAgICAgICAidGl0bGUiOiB0aXRsZSwKICAgICAgICAgICAgICAgICJtZXNzYWdlIjogbWVzc2FnZSwKICAgICAgICAgICAgICAgICJzdGlja3kiOiBzdGlja3ksCiAgICAgICAgICAgIH0sCiAgICAgICAgfQoKICAgIGRlZiBfZ2V0X2RlcGVuZGVudF9tb2RlbF9yZWxhdGlvbl9maWVsZHMoc2VsZik6CiAgICAgICAgIiIiQ2hlY2sgY3gudG93ZXIucmVmZXJlbmNlLm1peGluIGZvciB0aGUgZnVuY3Rpb24gZG9jdW1lbnRhdGlvbiIiIgogICAgICAgIHJlcyA9IHN1cGVyKCkuX2dldF9kZXBlbmRlbnRfbW9kZWxfcmVsYXRpb25fZmllbGRzKCkKICAgICAgICByZXR1cm4gcmVzICsgWyJ2YXJpYWJsZV92YWx1ZV9pZHMiLCAiZmlsZV9pZHMiXQo= \ No newline at end of file