From 6739cac57b2ec8fbb9f96e617c03428ffaebccfd Mon Sep 17 00:00:00 2001 From: git_admin Date: Mon, 27 Apr 2026 06:52:53 +0000 Subject: [PATCH] Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) --- addons/cetmix_tower_server/models/cx_tower_jet_waypoint.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 addons/cetmix_tower_server/models/cx_tower_jet_waypoint.py diff --git a/addons/cetmix_tower_server/models/cx_tower_jet_waypoint.py b/addons/cetmix_tower_server/models/cx_tower_jet_waypoint.py new file mode 100644 index 0000000..286f8d5 --- /dev/null +++ b/addons/cetmix_tower_server/models/cx_tower_jet_waypoint.py @@ -0,0 +1 @@ +IyBDb3B5cmlnaHQgKEMpIDIwMjQgQ2V0bWl4IE/DnAojIExpY2Vuc2UgQUdQTC0zLjAgb3IgbGF0ZXIgKGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsKS4KaW1wb3J0IGxvZ2dpbmcKCmZyb20gb2RvbyBpbXBvcnQgXywgYXBpLCBmaWVsZHMsIG1vZGVscwpmcm9tIG9kb28uZXhjZXB0aW9ucyBpbXBvcnQgVmFsaWRhdGlvbkVycm9yCgpmcm9tIC5jb25zdGFudHMgaW1wb3J0IEdFTkVSQUxfRVJST1IsIFdBWVBPSU5UX0NSRUFURV9GQUlMRUQKZnJvbSAudG9vbHMgaW1wb3J0IGdlbmVyYXRlX3JhbmRvbV9pZAoKX2xvZ2dlciA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKF9fbmFtZV9fKQoKCmNsYXNzIEN4VG93ZXJKZXRXYXlwb2ludChtb2RlbHMuTW9kZWwpOgogICAgIiIiSmV0IFdheXBvaW50cyByZXByZXNlbnQgd2F5cG9pbnRzIGZvciBqZXRzIiIiCgogICAgX25hbWUgPSAiY3gudG93ZXIuamV0LndheXBvaW50IgogICAgX2Rlc2NyaXB0aW9uID0gIkNldG1peCBUb3dlciBKZXQgV2F5cG9pbnQiCiAgICBfaW5oZXJpdCA9IFsKICAgICAgICAiY3gudG93ZXIucmVmZXJlbmNlLm1peGluIiwKICAgICAgICAiY3gudG93ZXIuYWNjZXNzLm1peGluIiwKICAgICAgICAiY3gudG93ZXIubWV0YWRhdGEubWl4aW4iLAogICAgXQogICAgX29yZGVyID0gImNyZWF0ZV9kYXRlIGRlc2MiCgogICAgbmFtZSA9IGZpZWxkcy5DaGFyKHJlcXVpcmVkPVRydWUpCiAgICBhY2Nlc3NfbGV2ZWwgPSBmaWVsZHMuU2VsZWN0aW9uKAogICAgICAgIHNlbGVjdGlvbj1sYW1iZGEgc2VsZjogc2VsZi5lbnZbCiAgICAgICAgICAgICJjeC50b3dlci5qZXQud2F5cG9pbnQudGVtcGxhdGUiCiAgICAgICAgXS5fc2VsZWN0aW9uX2FjY2Vzc19sZXZlbCgpLAogICAgICAgIGNvbXB1dGU9Il9jb21wdXRlX2FjY2Vzc19sZXZlbCIsCiAgICAgICAgcmVhZG9ubHk9RmFsc2UsCiAgICAgICAgc3RvcmU9VHJ1ZSwKICAgICkKICAgIHN0YXRlID0gZmllbGRzLlNlbGVjdGlvbigKICAgICAgICBzZWxlY3Rpb249WwogICAgICAgICAgICAoImRyYWZ0IiwgIkRyYWZ0IiksCiAgICAgICAgICAgICgicHJlcGFyaW5nIiwgIlByZXBhcmluZyIpLAogICAgICAgICAgICAoInJlYWR5IiwgIlJlYWR5IiksCiAgICAgICAgICAgICgiZXJyb3IiLCAiRXJyb3IiKSwKICAgICAgICAgICAgKCJhcnJpdmluZyIsICJBcnJpdmluZyIpLAogICAgICAgICAgICAoImxlYXZpbmciLCAiTGVhdmluZyIpLAogICAgICAgICAgICAoImN1cnJlbnQiLCAiQ3VycmVudCIpLAogICAgICAgICAgICAoImRlbGV0aW5nIiwgIkRlbGV0aW5nIiksCiAgICAgICAgICAgICgiZGVsZXRlZCIsICJEZWxldGVkIiksCiAgICAgICAgXSwKICAgICAgICBkZWZhdWx0PSJkcmFmdCIsCiAgICAgICAgcmVxdWlyZWQ9VHJ1ZSwKICAgICAgICByZWFkb25seT1UcnVlLAogICAgKQogICAgY2FuX2ZseV90byA9IGZpZWxkcy5Cb29sZWFuKAogICAgICAgIGNvbXB1dGU9Il9jb21wdXRlX2Nhbl9mbHlfdG8iLAogICAgICAgIHJlYWRvbmx5PVRydWUsCiAgICApCiAgICBpc19kZXN0aW5hdGlvbiA9IGZpZWxkcy5Cb29sZWFuKAogICAgICAgIGhlbHA9IkluZGljYXRlcyBpZiB0aGlzIHdheXBvaW50IGlzIHRoZSBjdXJyZW50IGRlc3RpbmF0aW9uIiwKICAgICkKICAgIGpldF9pZCA9IGZpZWxkcy5NYW55Mm9uZSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmpldCIsCiAgICAgICAgcmVxdWlyZWQ9VHJ1ZSwKICAgICAgICBvbmRlbGV0ZT0iY2FzY2FkZSIsCiAgICAgICAgaGVscD0iSmV0IHRoaXMgd2F5cG9pbnQgYmVsb25ncyB0byIsCiAgICApCiAgICBqZXRfdGVtcGxhdGVfaWQgPSBmaWVsZHMuTWFueTJvbmUoCiAgICAgICAgY29tb2RlbF9uYW1lPSJjeC50b3dlci5qZXQudGVtcGxhdGUiLAogICAgICAgIHJlbGF0ZWQ9ImpldF9pZC5qZXRfdGVtcGxhdGVfaWQiLAogICAgICAgIHJlYWRvbmx5PVRydWUsCiAgICApCiAgICB3YXlwb2ludF90ZW1wbGF0ZV9pZCA9IGZpZWxkcy5NYW55Mm9uZSgKICAgICAgICBzdHJpbmc9IlR5cGUiLAogICAgICAgIGNvbW9kZWxfbmFtZT0iY3gudG93ZXIuamV0LndheXBvaW50LnRlbXBsYXRlIiwKICAgICAgICBoZWxwPSJXYXlwb2ludCB0ZW1wbGF0ZSB0aGlzIHdheXBvaW50IGlzIGJhc2VkIG9uIiwKICAgICAgICBkb21haW49IlsoJ2pldF90ZW1wbGF0ZV9pZCcsICc9JywgamV0X3RlbXBsYXRlX2lkKV0iLAogICAgICAgIHJlcXVpcmVkPVRydWUsCiAgICAgICAgb25kZWxldGU9InJlc3RyaWN0IiwKICAgICkKICAgIHZhcmlhYmxlX3ZhbHVlcyA9IGZpZWxkcy5Kc29uKAogICAgICAgIGhlbHA9IkN1c3RvbSB2YXJpYWJsZSB2YWx1ZXMgZm9yIHRoaXMgd2F5cG9pbnQiLAogICAgICAgIHJlYWRvbmx5PVRydWUsCiAgICApCiAgICB2YXJpYWJsZV92YWx1ZXNfdGV4dCA9IGZpZWxkcy5UZXh0KAogICAgICAgIGhlbHA9IkN1c3RvbSB2YXJpYWJsZSB2YWx1ZXMgZm9yIHRoaXMgd2F5cG9pbnQiLAogICAgICAgIGNvbXB1dGU9Il9jb21wdXRlX3ZhcmlhYmxlX3ZhbHVlc190ZXh0IiwKICAgICkKICAgIGNyZWF0ZWRfZnJvbV9jb21tYW5kX2xvZ19pZCA9IGZpZWxkcy5NYW55Mm9uZSgKICAgICAgICBjb21vZGVsX25hbWU9ImN4LnRvd2VyLmNvbW1hbmQubG9nIiwKICAgICAgICBzdHJpbmc9IkNyZWF0ZWQgRnJvbSIsCiAgICAgICAgaGVscD0iQ29tbWFuZCBsb2cgdGhhdCBjcmVhdGVkIHRoaXMgd2F5cG9pbnQ7IHRoZSB3YXlwb2ludCBjYWxsYmFjayAiCiAgICAgICAgImZpbmlzaGVzIGl0IHdoZW4gdGhlIHdheXBvaW50IHJlYWNoZXMgcmVhZHkvY3VycmVudCBvciBlcnJvci4gIgogICAgICAgICJLZXB0IGZvciBkZWJ1Z2dpbmcvYXVkaXQuIiwKICAgICAgICBvbmRlbGV0ZT0ic2V0IG51bGwiLAogICAgICAgIGNvcHk9RmFsc2UsCiAgICApCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tIFNlbGVjdGlvbiAtLS0tLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgX3NlbGVjdGlvbl9hY2Nlc3NfbGV2ZWwoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQXZhaWxhYmxlIGFjY2VzcyBsZXZlbHMKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgTGlzdCBvZiB0dXBsZXM6IGF2YWlsYWJsZSBvcHRpb25zLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBbCiAgICAgICAgICAgICgiMiIsICJNYW5hZ2VyIiksCiAgICAgICAgICAgICgiMyIsICJSb290IiksCiAgICAgICAgXQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIC0tLS0tLS0tLSBDb21wdXRlZCBGaWVsZHMgLS0tLS0tLS0tCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgQGFwaS5kZXBlbmRzKCJuYW1lIiwgImNyZWF0ZV9kYXRlIikKICAgIGRlZiBfY29tcHV0ZV9kaXNwbGF5X25hbWUoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ29tcHV0ZSB0aGUgZGlzcGxheSBuYW1lIG9mIHRoZSB3YXlwb2ludAogICAgICAgICIiIgogICAgICAgIGZvciB3YXlwb2ludCBpbiBzZWxmOgogICAgICAgICAgICB0aW1lc3RhbXAgPSBmaWVsZHMuRGF0ZXRpbWUuY29udGV4dF90aW1lc3RhbXAoCiAgICAgICAgICAgICAgICB3YXlwb2ludCwgd2F5cG9pbnQuY3JlYXRlX2RhdGUKICAgICAgICAgICAgKQogICAgICAgICAgICBmb3JtYXR0ZWRfZGF0ZSA9IHRpbWVzdGFtcC5zdHJmdGltZSgiJVktJW0tJWQgJUg6JU06JVMiKQogICAgICAgICAgICB3YXlwb2ludC5kaXNwbGF5X25hbWUgPSBmInt3YXlwb2ludC5uYW1lfSAoe2Zvcm1hdHRlZF9kYXRlfSkiCgogICAgQGFwaS5kZXBlbmRzKCJ3YXlwb2ludF90ZW1wbGF0ZV9pZCIpCiAgICBkZWYgX2NvbXB1dGVfYWNjZXNzX2xldmVsKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFNldCBkZWZhdWx0IGFjY2VzcyBsZXZlbCB0byB0aGUgd2F5cG9pbnQgdGVtcGxhdGUgYWNjZXNzIGxldmVsCiAgICAgICAgIiIiCiAgICAgICAgZm9yIHdheXBvaW50IGluIHNlbGY6CiAgICAgICAgICAgIGlmIHdheXBvaW50LndheXBvaW50X3RlbXBsYXRlX2lkOgogICAgICAgICAgICAgICAgd2F5cG9pbnQuYWNjZXNzX2xldmVsID0gd2F5cG9pbnQud2F5cG9pbnRfdGVtcGxhdGVfaWQuYWNjZXNzX2xldmVsCgogICAgQGFwaS5kZXBlbmRzKCJqZXRfaWQud2F5cG9pbnRfaWRzIiwgImpldF9pZC53YXlwb2ludF9pZHMuc3RhdGUiKQogICAgZGVmIF9jb21wdXRlX2Nhbl9mbHlfdG8oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ2FuIGZseSBvbmx5IGlmIHdheXBvaW50IGlzIGluIHRoZSByZWFkeSBzdGF0ZSBhbmQKICAgICAgICBpcyBub3QgdGhlIGN1cnJlbnQgd2F5cG9pbnQgYW5kIGFsbCB0aGUgamV0IHdheXBvaW50cwogICAgICAgIGFyZSBpbiB0aGUgInJlYWR5IiBzdGF0ZQogICAgICAgICIiIgogICAgICAgIGZvciB3YXlwb2ludCBpbiBzZWxmOgogICAgICAgICAgICBhbGxfd2F5cG9pbnRzID0gd2F5cG9pbnQuamV0X2lkLndheXBvaW50X2lkcwogICAgICAgICAgICB3YXlwb2ludC5jYW5fZmx5X3RvID0gd2F5cG9pbnQuc3RhdGUgPT0gInJlYWR5IiBhbmQgbm90IGJvb2woCiAgICAgICAgICAgICAgICBhbGxfd2F5cG9pbnRzLmZpbHRlcmVkKAogICAgICAgICAgICAgICAgICAgIGxhbWJkYSB3OiB3LnN0YXRlIG5vdCBpbiBbInJlYWR5IiwgImVycm9yIiwgImN1cnJlbnQiXQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApCgogICAgQGFwaS5kZXBlbmRzKCJ2YXJpYWJsZV92YWx1ZXMiKQogICAgZGVmIF9jb21wdXRlX3ZhcmlhYmxlX3ZhbHVlc190ZXh0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENvbXB1dGUgdGhlIHZhcmlhYmxlIHZhbHVlcyB0ZXh0IGZvciB0aGUgd2F5cG9pbnQKICAgICAgICAiIiIKICAgICAgICBmb3Igd2F5cG9pbnQgaW4gc2VsZjoKICAgICAgICAgICAgd2F5cG9pbnQudmFyaWFibGVfdmFsdWVzX3RleHQgPSAoCiAgICAgICAgICAgICAgICBzdHIod2F5cG9pbnQudmFyaWFibGVfdmFsdWVzKSBpZiB3YXlwb2ludC52YXJpYWJsZV92YWx1ZXMgZWxzZSBGYWxzZQogICAgICAgICAgICApCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tIENvbnN0cmFpbnRzIC0tLS0tLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBAYXBpLmNvbnN0cmFpbnMoImlzX2Rlc3RpbmF0aW9uIiwgImpldF9pZCIpCiAgICBkZWYgX2NoZWNrX2lzX2Rlc3RpbmF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZhbGlkYXRlIGBgaXNfZGVzdGluYXRpb25gYCBvbiBlYWNoIHdheXBvaW50IGluIHRoZSByZWNvcmRzZXQuCgogICAgICAgIFJhaXNlcyBhIFZhbGlkYXRpb25FcnJvciB3aGVuOgogICAgICAgIC0gVGhlIHdheXBvaW50IGlzIGJlaW5nIHNldCBhcyBkZXN0aW5hdGlvbiB3aGlsZSBpbiB0aGUgYGBkcmFmdGBgLAogICAgICAgICAgYGBlcnJvcmBgLCBgYGxlYXZpbmdgYCwgYGBkZWxldGluZ2BgLCBvciBgYGRlbGV0ZWRgYCBzdGF0ZS4KICAgICAgICAgIFVzZSBgYHByZXBhcmUoaXNfZGVzdGluYXRpb249VHJ1ZSlgYCB0byBkZXNpZ25hdGUgYSBkZXN0aW5hdGlvbgogICAgICAgICAgd2F5cG9pbnQ7IGl0IHRyYW5zaXRpb25zIHRoZSB3YXlwb2ludCBvdXQgb2YgYGBkcmFmdGBgIGFuZCBzZXRzCiAgICAgICAgICBgYGlzX2Rlc3RpbmF0aW9uYGAgYXRvbWljYWxseS4KICAgICAgICAtIEFub3RoZXIgZGVzdGluYXRpb24gd2F5cG9pbnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoZSBzYW1lIGpldAogICAgICAgICAgKGF0IG1vc3Qgb25lIGRlc3RpbmF0aW9uIHBlciBqZXQgaXMgYWxsb3dlZCkuCiAgICAgICAgIiIiCiAgICAgICAgZGVzdGluYXRpb25fd2F5cG9pbnRzID0gc2VsZi5maWx0ZXJlZCgiaXNfZGVzdGluYXRpb24iKQogICAgICAgIGlmIG5vdCBkZXN0aW5hdGlvbl93YXlwb2ludHM6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBleGlzdGluZ19kZXN0aW5hdGlvbnMgPSBzZWxmLnNlYXJjaCgKICAgICAgICAgICAgWwogICAgICAgICAgICAgICAgKCJqZXRfaWQiLCAiaW4iLCBkZXN0aW5hdGlvbl93YXlwb2ludHMubWFwcGVkKCJqZXRfaWQiKS5pZHMpLAogICAgICAgICAgICAgICAgKCJpc19kZXN0aW5hdGlvbiIsICI9IiwgVHJ1ZSksCiAgICAgICAgICAgICAgICAoImlkIiwgIm5vdCBpbiIsIGRlc3RpbmF0aW9uX3dheXBvaW50cy5pZHMpLAogICAgICAgICAgICBdCiAgICAgICAgKQogICAgICAgIGV4aXN0aW5nX2J5X2pldCA9IHt3cC5qZXRfaWQuaWQ6IHdwIGZvciB3cCBpbiBleGlzdGluZ19kZXN0aW5hdGlvbnN9CgogICAgICAgICMgVHJhY2sgamV0IElEcyBhbHJlYWR5IGNsYWltZWQgYXMgZGVzdGluYXRpb24gd2l0aGluIHRoaXMgYmF0Y2ggc28gdGhhdAogICAgICAgICMgdHdvIHJlY29yZHMgaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24gYXJlIGNhdWdodCBldmVuIHRob3VnaCBuZWl0aGVyCiAgICAgICAgIyBhcHBlYXJzIGluIHRoZSBEQiBzZWFyY2ggYWJvdmUuCiAgICAgICAgc2Vlbl9pbl9iYXRjaCA9IHt9CgogICAgICAgIGludmFsaWRfc3RhdGVzID0geyJkcmFmdCIsICJlcnJvciIsICJsZWF2aW5nIiwgImRlbGV0aW5nIiwgImRlbGV0ZWQifQoKICAgICAgICBmb3Igd2F5cG9pbnQgaW4gZGVzdGluYXRpb25fd2F5cG9pbnRzOgogICAgICAgICAgICBpZiB3YXlwb2ludC5zdGF0ZSBpbiBpbnZhbGlkX3N0YXRlczoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcigKICAgICAgICAgICAgICAgICAgICBfKAogICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHNldCBpc19kZXN0aW5hdGlvbiB0byBUcnVlIGZvciB3YXlwb2ludCAlKHdheXBvaW50KXMgIgogICAgICAgICAgICAgICAgICAgICAgICAiYmVjYXVzZSBpdCBpcyBpbiB0aGUgJShzdGF0ZSlzIHN0YXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2F5cG9pbnQ9d2F5cG9pbnQubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9d2F5cG9pbnQuc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBqZXRfaWQgPSB3YXlwb2ludC5qZXRfaWQuaWQKICAgICAgICAgICAgZHVwbGljYXRlID0gZXhpc3RpbmdfYnlfamV0LmdldChqZXRfaWQpIG9yIHNlZW5faW5fYmF0Y2guZ2V0KGpldF9pZCkKICAgICAgICAgICAgaWYgZHVwbGljYXRlOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKAogICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICJXYXlwb2ludCAlKGV4aXN0aW5nKXMgaXMgYWxyZWFkeSBzZXQgYXMgdGhlIGRlc3RpbmF0aW9uICIKICAgICAgICAgICAgICAgICAgICAgICAgImZvciBqZXQgJShqZXQpcy4gT25seSBvbmUgZGVzdGluYXRpb24gd2F5cG9pbnQgaXMgYWxsb3dlZCAiCiAgICAgICAgICAgICAgICAgICAgICAgICJwZXIgamV0LiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nPWR1cGxpY2F0ZS5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBqZXQ9d2F5cG9pbnQuamV0X2lkLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICBzZWVuX2luX2JhdGNoW2pldF9pZF0gPSB3YXlwb2ludAoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIC0tLS0tLS0tLSBDUlVEIE1ldGhvZHMgLS0tLS0tLS0tLS0tLQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIEBhcGkubW9kZWxfY3JlYXRlX211bHRpCiAgICBkZWYgY3JlYXRlKHNlbGYsIHZhbHNfbGlzdCk6CiAgICAgICAgIiIiCiAgICAgICAgQ3JlYXRlIHdheXBvaW50cwogICAgICAgIC0gR2VuZXJhdGUgd2F5cG9pbnQgcmVmZXJlbmNlIGlmIG5vdCBwcm92aWRlZAogICAgICAgICIiIgoKICAgICAgICBmb3IgdmFscyBpbiB2YWxzX2xpc3Q6CiAgICAgICAgICAgIGlmIG5vdCB2YWxzLmdldCgicmVmZXJlbmNlIik6CiAgICAgICAgICAgICAgICB2YWxzWyJyZWZlcmVuY2UiXSA9IGdlbmVyYXRlX3JhbmRvbV9pZCgKICAgICAgICAgICAgICAgICAgICBzZWN0aW9ucz00LCBwb3B1bGF0aW9uPTQsIHNlcGFyYXRvcj0iXyIKICAgICAgICAgICAgICAgICkKICAgICAgICBqZXRzID0gc3VwZXIoKS5jcmVhdGUodmFsc19saXN0KQogICAgICAgIHJldHVybiBqZXRzCgogICAgZGVmIHdyaXRlKHNlbGYsIHZhbHMpOgogICAgICAgICIiIgogICAgICAgIFdyaXRlLiBEbyBub3QgYWxsb3cgdG8gbW9kaWZ5IHRoZSB0ZW1wbGF0ZQogICAgICAgIGlmIHRoZSB3YXlwb2ludCBpcyBub3QgaW4gdGhlIGRyYWZ0IHN0YXRlCiAgICAgICAgIiIiCiAgICAgICAgaWYgIndheXBvaW50X3RlbXBsYXRlX2lkIiBpbiB2YWxzIGFuZCBub3QgdmFscy5nZXQoInN0YXRlIikgPT0gImRyYWZ0IjoKICAgICAgICAgICAgZm9yIHdheXBvaW50IGluIHNlbGY6CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgd2F5cG9pbnQud2F5cG9pbnRfdGVtcGxhdGVfaWQuaWQgIT0gdmFscy5nZXQoIndheXBvaW50X3RlbXBsYXRlX2lkIikKICAgICAgICAgICAgICAgICAgICBhbmQgd2F5cG9pbnQuc3RhdGUgIT0gImRyYWZ0IgogICAgICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGNoYW5nZSB3YXlwb2ludCB0eXBlIGZvciAlKHdheXBvaW50KXMgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJlY2F1c2UgaXQgaXMgbm90IGluIHRoZSBkcmFmdCBzdGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXlwb2ludD13YXlwb2ludC5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICMgSW52YWxpZGF0ZSB0aGUgc3RhdGUgZmllbGQKICAgICAgICBmaWVsZHNfdG9faW52YWxpZGF0ZSA9IFtdCiAgICAgICAgaWYgInN0YXRlIiBpbiB2YWxzOgogICAgICAgICAgICBmaWVsZHNfdG9faW52YWxpZGF0ZS5hcHBlbmQoInN0YXRlIikKICAgICAgICBpZiAidmFyaWFibGVfdmFsdWVzIiBpbiB2YWxzOgogICAgICAgICAgICBmaWVsZHNfdG9faW52YWxpZGF0ZS5hcHBlbmQoInZhcmlhYmxlX3ZhbHVlcyIpCiAgICAgICAgaWYgImlzX2Rlc3RpbmF0aW9uIiBpbiB2YWxzOgogICAgICAgICAgICBmaWVsZHNfdG9faW52YWxpZGF0ZS5hcHBlbmQoImlzX2Rlc3RpbmF0aW9uIikKICAgICAgICBpZiBmaWVsZHNfdG9faW52YWxpZGF0ZToKICAgICAgICAgICAgc2VsZi5pbnZhbGlkYXRlX3JlY29yZHNldChmaWVsZHNfdG9faW52YWxpZGF0ZSkKICAgICAgICByZXR1cm4gc3VwZXIoKS53cml0ZSh2YWxzKQoKICAgIGRlZiB1bmxpbmsoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVW5saW5rLgoKICAgICAgICBSYWlzZXM6CiAgICAgICAgICAgIFZhbGlkYXRpb25FcnJvcjogSWYgdGhlIHdheXBvaW50IGNhbm5vdCBiZSBkZWxldGVkCiAgICAgICAgICAgICAgICBzZXQgdGhlIGNvbnRleHQgdmFsdWUgJ3dheXBvaW50X25vX3JhaXNlX29uX2RlbGV0ZScgdG8gVHJ1ZQogICAgICAgICAgICAgICAgZm9yIG5vdCB0byByYWlzZSB0aGUgZXhjZXB0aW9uLgogICAgICAgICIiIgogICAgICAgICMgRGVsZXRhYmxlIHdheXBvaW50czoKICAgICAgICAjIC0gYXJlIGluIHRoZSAnZHJhZnQnIG9yICdkZWxldGVkJyBzdGF0ZQogICAgICAgICMgLSB3YXlwb2ludCBpcyBpbiB0aGUgJ3JlYWR5JyBvciAnZXJyb3InIHN0YXRlIGFuZCB0ZW1wbGF0ZQogICAgICAgICMgICBkb2Vzbid0IGhhdmUgb25fZGVsZXRlIGZsaWdodCBwbGFuCiAgICAgICAgIyBOb24tZGVsZXRhYmxlIHdheXBvaW50czoKICAgICAgICAjIC0gYXJlIGluIHRoZSAnYXJyaXZpbmcnLCAnbGVhdmluZycgb3IgJ3ByZXBhcmluZycgc3RhdGUKICAgICAgICAjICAgb3IgaXMgdGhlIGN1cnJlbnQgd2F5cG9pbnQgb2YgdGhlIGpldAogICAgICAgICMgICBvciBpcyBtYXJrZWQgYXMgdGhlIGFjdGl2ZSBkZXN0aW5hdGlvbiAoaXNfZGVzdGluYXRpb249VHJ1ZSkKICAgICAgICAjIE5lZWQgdG8gcnVuIHRoZSBvbl9kZWxldGUgZmxpZ2h0IHBsYW46CiAgICAgICAgIyAtIHdheXBvaW50IGlzIGluIHRoZSAncmVhZHknIG9yICdlcnJvcicgc3RhdGUgYW5kIHRlbXBsYXRlIGhhcwogICAgICAgICMgIG9uX2RlbGV0ZSBmbGlnaHQgcGxhbgogICAgICAgIGlmIHNlbGYuX2NvbnRleHQuZ2V0KCJ3YXlwb2ludF9mb3JjZV9kZWxldGUiKToKICAgICAgICAgICAgcmV0dXJuIHN1cGVyKCkudW5saW5rKCkKCiAgICAgICAgd2F5cG9pbnRzX3RvX2RlbGV0ZSA9IHNlbGYuYnJvd3NlKCkKICAgICAgICB3YXlwb2ludHNfdG9fcnVuX2RlbGV0ZV9wbGFuID0gc2VsZi5icm93c2UoKQogICAgICAgIGZvciB3YXlwb2ludCBpbiBzZWxmOgogICAgICAgICAgICBpZiB3YXlwb2ludC5pc19kZXN0aW5hdGlvbjoKICAgICAgICAgICAgICAgIGV4Y2VwdGlvbl9tZXNzYWdlID0gXygKICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGRlbGV0ZSB3YXlwb2ludCAlKHdheXBvaW50KXMgYmVjYXVzZSBpdCBpcyAiCiAgICAgICAgICAgICAgICAgICAgImN1cnJlbnRseSBkZXNpZ25hdGVkIGFzIHRoZSBkZXN0aW5hdGlvbiBmb3IgamV0ICUoamV0KXMuIiwKICAgICAgICAgICAgICAgICAgICB3YXlwb2ludD13YXlwb2ludC5uYW1lLAogICAgICAgICAgICAgICAgICAgIGpldD13YXlwb2ludC5qZXRfaWQubmFtZSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGlmIHNlbGYuX2NvbnRleHQuZ2V0KCJ3YXlwb2ludF9ub19yYWlzZV9vbl9kZWxldGUiKToKICAgICAgICAgICAgICAgICAgICBfbG9nZ2VyLmVycm9yKGV4Y2VwdGlvbl9tZXNzYWdlKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoZXhjZXB0aW9uX21lc3NhZ2UpCiAgICAgICAgICAgIGlmIHdheXBvaW50LnN0YXRlIG5vdCBpbiBbImRyYWZ0IiwgImRlbGV0ZWQiLCAiZXJyb3IiLCAicmVhZHkiXToKICAgICAgICAgICAgICAgIGlmIHdheXBvaW50LnN0YXRlID09ICJjdXJyZW50IjoKICAgICAgICAgICAgICAgICAgICBleGNlcHRpb25fbWVzc2FnZSA9IF8oCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3QgZGVsZXRlIHRoZSB3YXlwb2ludCAlKHdheXBvaW50KXMgYmVjYXVzZSBpdCBpcyIKICAgICAgICAgICAgICAgICAgICAgICAgIiB0aGUgY3VycmVudCB3YXlwb2ludCBvZiB0aGUgamV0ICUoamV0KXMiLAogICAgICAgICAgICAgICAgICAgICAgICB3YXlwb2ludD13YXlwb2ludC5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBqZXQ9d2F5cG9pbnQuamV0X2lkLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBleGNlcHRpb25fbWVzc2FnZSA9IF8oCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3QgZGVsZXRlIHRoZSB3YXlwb2ludCAlKHdheXBvaW50KXMgYmVjYXVzZSBpdCBpcyIKICAgICAgICAgICAgICAgICAgICAgICAgIiBpbiB0aGUgJShzdGF0ZSlzIHN0YXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2F5cG9pbnQ9d2F5cG9pbnQubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9d2F5cG9pbnQuc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgaWYgc2VsZi5fY29udGV4dC5nZXQoIndheXBvaW50X25vX3JhaXNlX29uX2RlbGV0ZSIpOgogICAgICAgICAgICAgICAgICAgIF9sb2dnZXIuZXJyb3IoZXhjZXB0aW9uX21lc3NhZ2UpCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihleGNlcHRpb25fbWVzc2FnZSkKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgd2F5cG9pbnQuc3RhdGUgaW4gWyJyZWFkeSIsICJlcnJvciJdCiAgICAgICAgICAgICAgICBhbmQgd2F5cG9pbnQud2F5cG9pbnRfdGVtcGxhdGVfaWQucGxhbl9kZWxldGVfaWQKICAgICAgICAgICAgKToKICAgICAgICAgICAgICAgIHdheXBvaW50c190b19ydW5fZGVsZXRlX3BsYW4gfD0gd2F5cG9pbnQKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHdheXBvaW50c190b19kZWxldGUgfD0gd2F5cG9pbnQKCiAgICAgICAgaWYgd2F5cG9pbnRzX3RvX2RlbGV0ZToKICAgICAgICAgICAgcmVzdWx0ID0gc3VwZXIoQ3hUb3dlckpldFdheXBvaW50LCB3YXlwb2ludHNfdG9fZGVsZXRlKS51bmxpbmsoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJlc3VsdCA9IFRydWUKCiAgICAgICAgZm9yIHdheXBvaW50IGluIHdheXBvaW50c190b19ydW5fZGVsZXRlX3BsYW46CiAgICAgICAgICAgIHdheXBvaW50LndyaXRlKHsic3RhdGUiOiAiZGVsZXRpbmcifSkKICAgICAgICAgICAgd2F5cG9pbnQuamV0X2lkLnNlcnZlcl9pZC5zdWRvKCkucnVuX2ZsaWdodF9wbGFuKAogICAgICAgICAgICAgICAgamV0PXdheXBvaW50LmpldF9pZCwKICAgICAgICAgICAgICAgIGZsaWdodF9wbGFuPXdheXBvaW50LndheXBvaW50X3RlbXBsYXRlX2lkLnBsYW5fZGVsZXRlX2lkLAogICAgICAgICAgICAgICAgcGxhbl9sb2c9eyJ3YXlwb2ludF9pZCI6IHdheXBvaW50LmlkfSwKICAgICAgICAgICAgICAgIHZhcmlhYmxlX3ZhbHVlcz13YXlwb2ludC5fZ2V0X2N1c3RvbV92YXJpYWJsZV92YWx1ZXMoKSwKICAgICAgICAgICAgKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyAtLS0tLS0tLS0gV2F5cG9pbnQgU2V0dGVycyAtLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgcHJlcGFyZShzZWxmLCBpc19kZXN0aW5hdGlvbj1GYWxzZSk6CiAgICAgICAgIiIiCiAgICAgICAgUHJlcGFyZSB0aGUgbmV3bHkgY3JlYXRlZCB3YXlwb2ludC4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgaXNfZGVzdGluYXRpb24gKGJvb2wpOiBUcnVlIGlmIHRoZSB3YXlwb2ludCBpcyB0aGUgZGVzdGluYXRpb24KICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBCb29sZWFuOiBUcnVlIGlmIHRoZSB3YXlwb2ludCB3YXMgcHJlcGFyZWQgc3VjY2Vzc2Z1bGx5CiAgICAgICAgUmFpc2VzOgogICAgICAgICAgICBWYWxpZGF0aW9uRXJyb3I6IElmIHRoZSB3YXlwb2ludCBjYW5ub3QgYmUgcHJlcGFyZWQKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIF9sb2dnZXIuaW5mbygKICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICJQcmVwYXJpbmcgd2F5cG9pbnQgJSh3YXlwb2ludClzIG9uIGpldCAlKGpldClzIiwKICAgICAgICAgICAgICAgIHdheXBvaW50PXNlbGYubmFtZSwKICAgICAgICAgICAgICAgIGpldD1zZWxmLmpldF9pZC5uYW1lLAogICAgICAgICAgICApCiAgICAgICAgKQogICAgICAgIGlmIG5vdCBzZWxmLnN0YXRlID09ICJkcmFmdCI6CiAgICAgICAgICAgIGVycm9yID0gXygKICAgICAgICAgICAgICAgICJDYW5ub3QgcHJlcGFyZSB3YXlwb2ludCAlKHdheXBvaW50KXMgb24gamV0ICUoamV0KXMgYmVjYXVzZSIKICAgICAgICAgICAgICAgICIgaXQgaXMgbm90IGluIHRoZSAnZHJhZnQnIHN0YXRlIiwKICAgICAgICAgICAgICAgIHdheXBvaW50PXNlbGYubmFtZSwKICAgICAgICAgICAgICAgIGpldD1zZWxmLmpldF9pZC5uYW1lLAogICAgICAgICAgICApCiAgICAgICAgICAgIF9sb2dnZXIuZXJyb3IoZXJyb3IpCiAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcihlcnJvcikKCiAgICAgICAgaWYgc2VsZi53YXlwb2ludF90ZW1wbGF0ZV9pZC5wbGFuX2NyZWF0ZV9pZDoKICAgICAgICAgICAgc2VsZi53cml0ZSh7InN0YXRlIjogInByZXBhcmluZyIsICJpc19kZXN0aW5hdGlvbiI6IGlzX2Rlc3RpbmF0aW9ufSkKICAgICAgICAgICAgd2l0aCBzZWxmLmVudi5jci5zYXZlcG9pbnQoKToKICAgICAgICAgICAgICAgIHNlbGYuamV0X2lkLnNlcnZlcl9pZC5zdWRvKCkucnVuX2ZsaWdodF9wbGFuKAogICAgICAgICAgICAgICAgICAgIGZsaWdodF9wbGFuPXNlbGYud2F5cG9pbnRfdGVtcGxhdGVfaWQucGxhbl9jcmVhdGVfaWQsCiAgICAgICAgICAgICAgICAgICAgamV0PXNlbGYuamV0X2lkLAogICAgICAgICAgICAgICAgICAgIHBsYW5fbG9nPXsKICAgICAgICAgICAgICAgICAgICAgICAgIndheXBvaW50X2lkIjogc2VsZi5pZCwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlX3ZhbHVlcz1zZWxmLl9nZXRfY3VzdG9tX3ZhcmlhYmxlX3ZhbHVlcygpLAogICAgICAgICAgICAgICAgKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud3JpdGUoeyJzdGF0ZSI6ICJyZWFkeSIsICJpc19kZXN0aW5hdGlvbiI6IGlzX2Rlc3RpbmF0aW9ufSkKICAgICAgICAgICAgIyBTYXZlIGpldCB2YXJpYWJsZSB2YWx1ZXMgd2hlbiBzdGF0ZSBjaGFuZ2VzIHRvIHJlYWR5CiAgICAgICAgICAgIHNlbGYuX3NhdmVfdmFyaWFibGVfdmFsdWVzKCkKCiAgICAgICAgICAgICMgUmVmcmVzaCB0aGUgZnJvbnRlbmQgdmlld3MKICAgICAgICAgICAgc2VsZi5lbnYudXNlci5yZWxvYWRfdmlld3MobW9kZWw9ImN4LnRvd2VyLmpldCIsIHJlY19pZHM9W3NlbGYuamV0X2lkLmlkXSkKCiAgICAgICAgICAgICMgRmx5IHRvIHRoaXMgd2F5cG9pbnQgaWYgc2V0IGFzIGRlc3RpbmF0aW9uCiAgICAgICAgICAgIGlmIGlzX2Rlc3RpbmF0aW9uOgogICAgICAgICAgICAgICAgc2VsZi5mbHlfdG8oKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZmluYWxpemVfY3JlYXRlX3dheXBvaW50X2NvbW1hbmRfbG9nKHN1Y2Nlc3M9VHJ1ZSkKICAgICAgICBfbG9nZ2VyLmluZm8oCiAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAiU3VjY2Vzc2Z1bGx5IHByZXBhcmVkIHdheXBvaW50ICUod2F5cG9pbnQpcyBvbiBqZXQgJShqZXQpcyIsCiAgICAgICAgICAgICAgICB3YXlwb2ludD1zZWxmLm5hbWUsCiAgICAgICAgICAgICAgICBqZXQ9c2VsZi5qZXRfaWQubmFtZSwKICAgICAgICAgICAgKQogICAgICAgICkKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBmbHlfdG8oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgRmx5IHRvIHRoZSB3YXlwb2ludAoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBib29sOiBUcnVlIGlmIGV2ZW50IHdhcyBoYW5kbGVkIGVsc2UgRmFsc2UKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQogICAgICAgIF9sb2dnZXIuaW5mbygKICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICJGbHlpbmcgdG8gd2F5cG9pbnQgJSh3YXlwb2ludClzIG9uIGpldCAlKGpldClzIiwKICAgICAgICAgICAgICAgIHdheXBvaW50PXNlbGYubmFtZSwKICAgICAgICAgICAgICAgIGpldD1zZWxmLmpldF9pZC5uYW1lLAogICAgICAgICAgICApCiAgICAgICAgKQogICAgICAgIGlmIHNlbGYuc3RhdGUgIT0gInJlYWR5IjoKICAgICAgICAgICAgZXJyb3IgPSBfKAogICAgICAgICAgICAgICAgIkNhbm5vdCBmbHkgdG8gd2F5cG9pbnQgJSh3YXlwb2ludClzIG9uIGpldCAlKGpldClzIGJlY2F1c2UiCiAgICAgICAgICAgICAgICAiIGl0IGlzIG5vdCBpbiB0aGUgJ3JlYWR5JyBzdGF0ZSIsCiAgICAgICAgICAgICAgICB3YXlwb2ludD1zZWxmLm5hbWUsCiAgICAgICAgICAgICAgICBqZXQ9c2VsZi5qZXRfaWQubmFtZSwKICAgICAgICAgICAgKQogICAgICAgICAgICBfbG9nZ2VyLmVycm9yKGVycm9yKQogICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoZXJyb3IpCgogICAgICAgICMgQ2Fubm90IGZseSB0byB3YXlwb2ludCBpZiB0aGVyZSBpcyBhbm90aGVyIHdheXBvaW50CiAgICAgICAgIyAgaW4gdGhlICJhcnJpdmluZyIgb3Igc3RhdGUKICAgICAgICBvdGhlcl93YXlwb2ludHMgPSBzZWxmLmpldF9pZC53YXlwb2ludF9pZHMuZmlsdGVyZWQoCiAgICAgICAgICAgIGxhbWJkYSB3OiB3LnN0YXRlIGluIFsiYXJyaXZpbmciLCAibGVhdmluZyJdCiAgICAgICAgKQogICAgICAgIGlmIG90aGVyX3dheXBvaW50czoKICAgICAgICAgICAgZXJyb3IgPSBfKAogICAgICAgICAgICAgICAgIkNhbm5vdCBmbHkgdG8gd2F5cG9pbnQgJSh3YXlwb2ludClzIG9uIGpldCAlKGpldClzIGJlY2F1c2UiCiAgICAgICAgICAgICAgICAiIHRoZXJlIGlzIGFub3RoZXIgd2F5cG9pbnQgJShvdGhlcl93YXlwb2ludClzICIKICAgICAgICAgICAgICAgICJpbiB0aGUgJ2Fycml2aW5nJyBvciAnbGVhdmluZycgc3RhdGUiLAogICAgICAgICAgICAgICAgd2F5cG9pbnQ9c2VsZi5uYW1lLAogICAgICAgICAgICAgICAgamV0PXNlbGYuamV0X2lkLm5hbWUsCiAgICAgICAgICAgICAgICBvdGhlcl93YXlwb2ludD1vdGhlcl93YXlwb2ludHNbMF0ubmFtZSwKICAgICAgICAgICAgKQogICAgICAgICAgICBfbG9nZ2VyLmVycm9yKGVycm9yKQogICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoZXJyb3IpCgogICAgICAgICMgTGVhdmUgdGhlIHByZXZpb3VzIHdheXBvaW50CiAgICAgICAgcHJldmlvdXNfd2F5cG9pbnQgPSBzZWxmLmpldF9pZC53YXlwb2ludF9pZAogICAgICAgIGlmIG5vdCBwcmV2aW91c193YXlwb2ludDoKICAgICAgICAgICAgIyBObyBwcmV2aW91cyB3YXlwb2ludCwgc2V0IHN0YXRlIHRvIGFycml2aW5nCiAgICAgICAgICAgICMgVmFyaWFibGUgdmFsdWVzIHdpbGwgYmUgcmVzdG9yZWQgaW4gX2Fycml2ZSgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoeyJzdGF0ZSI6ICJhcnJpdmluZyIsICJpc19kZXN0aW5hdGlvbiI6IFRydWV9KQogICAgICAgICAgICBzZWxmLl9hcnJpdmUoKQogICAgICAgICAgICByZXR1cm4gVHJ1ZQoKICAgICAgICAjIERvbid0IGdvIHRvIHRoZSB3YXlwb2ludCBpZiBpdCBpcyBhbHJlYWR5IHRoZSBjdXJyZW50IHdheXBvaW50CiAgICAgICAgaWYgcHJldmlvdXNfd2F5cG9pbnQuaWQgPT0gc2VsZi5pZDoKICAgICAgICAgICAgcmV0dXJuIFRydWUKCiAgICAgICAgIyBDYW5ub3QgbGVhdmUgdGhlIHdheXBvaW50IGlmIGl0IGlzIG5vdCByZWFkeSBvciBjdXJyZW50CiAgICAgICAgaWYgcHJldmlvdXNfd2F5cG9pbnQuc3RhdGUgbm90IGluIFsicmVhZHkiLCAiY3VycmVudCJdOgogICAgICAgICAgICBlcnJvciA9IF8oCiAgICAgICAgICAgICAgICAiQ2Fubm90IGZseSB0byB3YXlwb2ludCAlKHdheXBvaW50KXMgb24gamV0ICUoamV0KXMgYmVjYXVzZSIKICAgICAgICAgICAgICAgICIgdGhlIHByZXZpb3VzIHdheXBvaW50ICUocHJldmlvdXNfd2F5cG9pbnQpcyBpcyBub3QgaW4gdGhlIgogICAgICAgICAgICAgICAgIiAncmVhZHknIG9yICdjdXJyZW50JyBzdGF0ZSIsCiAgICAgICAgICAgICAgICB3YXlwb2ludD1zZWxmLm5hbWUsCiAgICAgICAgICAgICAgICBqZXQ9c2VsZi5qZXRfaWQubmFtZSwKICAgICAgICAgICAgICAgIHByZXZpb3VzX3dheXBvaW50PXByZXZpb3VzX3dheXBvaW50Lm5hbWUsCiAgICAgICAgICAgICkKICAgICAgICAgICAgX2xvZ2dlci5lcnJvcihlcnJvcikKICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKGVycm9yKQoKICAgICAgICAjIE1hcmsgZGVzdGluYXRpb24gZmlyc3Q7IHN3aXRjaCB0byBhcnJpdmluZyBvbmx5IGFmdGVyIGxlYXZlIHN1Y2NlZWRzLgogICAgICAgIGlmIG5vdCBzZWxmLmlzX2Rlc3RpbmF0aW9uOgogICAgICAgICAgICBzZWxmLndyaXRlKHsiaXNfZGVzdGluYXRpb24iOiBUcnVlfSkKCiAgICAgICAgIyBMZWF2ZSB0aGUgcHJldmlvdXMgd2F5cG9pbnQgKHRoaXMgd2lsbCBzYXZlIGl0cyB2YXJpYWJsZSB2YWx1ZXMpCiAgICAgICAgcHJldmlvdXNfd2F5cG9pbnQuX2xlYXZlKCkKICAgICAgICBpZiBwcmV2aW91c193YXlwb2ludC5zdGF0ZSA9PSAiZXJyb3IiOgogICAgICAgICAgICAjIFJvbGwgYmFjayBkZXN0aW5hdGlvbiB3aGVuIHNvdXJjZSBsZWF2ZSBmYWlscyBpbW1lZGlhdGVseS4KICAgICAgICAgICAgc2VsZi53cml0ZSh7ImlzX2Rlc3RpbmF0aW9uIjogRmFsc2V9KQogICAgICAgICAgICBzZWxmLl9maW5hbGl6ZV9jcmVhdGVfd2F5cG9pbnRfY29tbWFuZF9sb2coCiAgICAgICAgICAgICAgICBzdWNjZXNzPUZhbHNlLAogICAgICAgICAgICAgICAgZXJyb3I9XygiRmFpbGVkIHRvIGxlYXZlIGN1cnJlbnQgd2F5cG9pbnQuIiksCiAgICAgICAgICAgICkKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgIyBJZiBsZWF2aW5nIGNvbXBsZXRlZCBpbW1lZGlhdGVseSAobm8gcGxhbl9sZWF2ZV9pZCksCiAgICAgICAgIyBhcnJpdmUgYXQgdGhlIG5ldyB3YXlwb2ludCAod2hpY2ggd2lsbCByZXN0b3JlIHZhcmlhYmxlIHZhbHVlcykKICAgICAgICBpZiBzZWxmLnN0YXRlID09ICJyZWFkeSIgYW5kIHByZXZpb3VzX3dheXBvaW50LnN0YXRlIGluIFsicmVhZHkiLCAiY3VycmVudCJdOgogICAgICAgICAgICBzZWxmLndyaXRlKHsic3RhdGUiOiAiYXJyaXZpbmcifSkKICAgICAgICAgICAgc2VsZi5fYXJyaXZlKCkKICAgICAgICBfbG9nZ2VyLmluZm8oCiAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAiU3VjY2Vzc2Z1bGx5IGZsZXcgdG8gd2F5cG9pbnQgJSh3YXlwb2ludClzIG9uIGpldCAlKGpldClzIiwKICAgICAgICAgICAgICAgIHdheXBvaW50PXNlbGYubmFtZSwKICAgICAgICAgICAgICAgIGpldD1zZWxmLmpldF9pZC5uYW1lLAogICAgICAgICAgICApCiAgICAgICAgKQogICAgICAgIHJldHVybiBUcnVlCgogICAgZGVmIF9sZWF2ZShzZWxmKToKICAgICAgICAiIiIKICAgICAgICBMZWF2ZSB0aGUgd2F5cG9pbnQuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGJvb2w6IFRydWUgaWYgZXZlbnQgd2FzIGhhbmRsZWQgZWxzZSBGYWxzZQogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgaWYgc2VsZi5zdGF0ZSBub3QgaW4gWyJyZWFkeSIsICJjdXJyZW50Il06CiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIHNlbGYud3JpdGUoeyJzdGF0ZSI6ICJsZWF2aW5nIn0pCiAgICAgICAgcGxhbl9sZWF2ZSA9IHNlbGYud2F5cG9pbnRfdGVtcGxhdGVfaWQucGxhbl9sZWF2ZV9pZAogICAgICAgIGlmIHBsYW5fbGVhdmU6CiAgICAgICAgICAgIHdpdGggc2VsZi5lbnYuY3Iuc2F2ZXBvaW50KCk6CiAgICAgICAgICAgICAgICBzZWxmLmpldF9pZC5zZXJ2ZXJfaWQuc3VkbygpLnJ1bl9mbGlnaHRfcGxhbigKICAgICAgICAgICAgICAgICAgICBqZXQ9c2VsZi5qZXRfaWQsCiAgICAgICAgICAgICAgICAgICAgZmxpZ2h0X3BsYW49cGxhbl9sZWF2ZSwKICAgICAgICAgICAgICAgICAgICBwbGFuX2xvZz17CiAgICAgICAgICAgICAgICAgICAgICAgICJ3YXlwb2ludF9pZCI6IHNlbGYuaWQsCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZV92YWx1ZXM9c2VsZi5fZ2V0X2N1c3RvbV92YXJpYWJsZV92YWx1ZXMoKSwKICAgICAgICAgICAgICAgICkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLndyaXRlKHsic3RhdGUiOiAicmVhZHkifSkKICAgICAgICAgICAgIyBTYXZlIGpldCB2YXJpYWJsZSB2YWx1ZXMKICAgICAgICAgICAgc2VsZi5fc2F2ZV92YXJpYWJsZV92YWx1ZXMoKQogICAgICAgIHJldHVybiBUcnVlCgogICAgZGVmIF9hcnJpdmUoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQXJyaXZlIGF0IHRoZSB3YXlwb2ludC4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgYm9vbDogVHJ1ZSBpZiBldmVudCB3YXMgaGFuZGxlZCBlbHNlIEZhbHNlCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBpZiBub3Qgc2VsZi5zdGF0ZSA9PSAiYXJyaXZpbmciOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICAjIFJlc3RvcmUgdmFyaWFibGUgdmFsdWVzIGJlZm9yZSBydW5uaW5nIHRoZSBhcnJpdmUgcGxhbgogICAgICAgIHNlbGYuX3Jlc3RvcmVfdmFyaWFibGVfdmFsdWVzKCkKICAgICAgICBwbGFuX2Fycml2ZSA9IHNlbGYud2F5cG9pbnRfdGVtcGxhdGVfaWQucGxhbl9hcnJpdmVfaWQKICAgICAgICBpZiBwbGFuX2Fycml2ZToKICAgICAgICAgICAgc2VsZi5qZXRfaWQuc2VydmVyX2lkLnN1ZG8oKS5ydW5fZmxpZ2h0X3BsYW4oCiAgICAgICAgICAgICAgICBqZXQ9c2VsZi5qZXRfaWQsCiAgICAgICAgICAgICAgICBmbGlnaHRfcGxhbj1wbGFuX2Fycml2ZSwKICAgICAgICAgICAgICAgIHBsYW5fbG9nPXsKICAgICAgICAgICAgICAgICAgICAid2F5cG9pbnRfaWQiOiBzZWxmLmlkLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHZhcmlhYmxlX3ZhbHVlcz1zZWxmLl9nZXRfY3VzdG9tX3ZhcmlhYmxlX3ZhbHVlcygpLAogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBDbGVhciBkZXN0aW5hdGlvbiBmbGFnIHdoZW4gYXJyaXZpbmcgd2l0aG91dCBwbGFuCiAgICAgICAgICAgIHNlbGYud3JpdGUoeyJpc19kZXN0aW5hdGlvbiI6IEZhbHNlLCAic3RhdGUiOiAiY3VycmVudCJ9KQogICAgICAgICAgICBzZWxmLmpldF9pZC53cml0ZSh7IndheXBvaW50X2lkIjogc2VsZi5pZH0pCiAgICAgICAgICAgIHNlbGYuamV0X2lkLmludmFsaWRhdGVfcmVjb3Jkc2V0KFsid2F5cG9pbnRfaWQiXSkKICAgICAgICAgICAgc2VsZi5fZmluYWxpemVfY3JlYXRlX3dheXBvaW50X2NvbW1hbmRfbG9nKHN1Y2Nlc3M9VHJ1ZSkKICAgICAgICAgICAgIyBSZWZyZXNoIHRoZSBmcm9udGVuZCB2aWV3cwogICAgICAgICAgICBzZWxmLmVudi51c2VyLnJlbG9hZF92aWV3cyhtb2RlbD0iY3gudG93ZXIuamV0IiwgcmVjX2lkcz1bc2VsZi5qZXRfaWQuaWRdKQogICAgICAgIHJldHVybiBUcnVlCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tIEhvb2tzIC0tLS0tLS0tLQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGRlZiBfZmluYWxpemVfY3JlYXRlX3dheXBvaW50X2NvbW1hbmRfbG9nKHNlbGYsIHN1Y2Nlc3M9VHJ1ZSwgZXJyb3I9Tm9uZSk6CiAgICAgICAgIiIiRmluaXNoIHRoZSBjb21tYW5kIGxvZyB0aGF0IGNyZWF0ZWQgdGhpcyB3YXlwb2ludCwgaWYgYW55LgoKICAgICAgICBDYWxsZWQgd2hlbiB0aGUgd2F5cG9pbnQgcmVhY2hlcyByZWFkeS9jdXJyZW50IChzdWNjZXNzKSBvciBlcnJvci4KICAgICAgICBPbmx5IGNhbGxzIGZpbmlzaCgpIGlmIHRoZSBsb2cgaXMgbm90IGFscmVhZHkgZmluaXNoZWQgKGd1YXJkIGFnYWluc3QKICAgICAgICBkb3VibGUtZmluaXNoKS4gRG9lcyBub3QgY2xlYXIgY3JlYXRlZF9mcm9tX2NvbW1hbmRfbG9nX2lkLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBzdWNjZXNzIChib29sKTogVHJ1ZSBpZiB3YXlwb2ludCByZWFjaGVkIHJlYWR5L2N1cnJlbnQuCiAgICAgICAgICAgIGVycm9yIChzdHIsIG9wdGlvbmFsKTogRXJyb3IgbWVzc2FnZSB3aGVuIHN1Y2Nlc3MgaXMgRmFsc2UuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGJvb2w6IFRydWUgaWYgY29tbWFuZCBsb2cgd2FzIGZpbmlzaGVkLCBGYWxzZSBvdGhlcndpc2UuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBsb2dfcmVjb3JkID0gc2VsZi5jcmVhdGVkX2Zyb21fY29tbWFuZF9sb2dfaWQKICAgICAgICBpZiBub3QgbG9nX3JlY29yZDoKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgaWYgbG9nX3JlY29yZC5maW5pc2hfZGF0ZToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgc3RhdHVzID0gMCBpZiBzdWNjZXNzIGVsc2UgKFdBWVBPSU5UX0NSRUFURV9GQUlMRUQgaWYgZXJyb3IgZWxzZSBHRU5FUkFMX0VSUk9SKQogICAgICAgIHJlc3BvbnNlID0gXygiV2F5cG9pbnQgcmVhY2hlZCAlcyIsIHNlbGYuc3RhdGUpIGlmIHN1Y2Nlc3MgZWxzZSBOb25lCiAgICAgICAgbG9nX3JlY29yZC5maW5pc2goCiAgICAgICAgICAgIHN0YXR1cz1zdGF0dXMsCiAgICAgICAgICAgIHJlc3BvbnNlPXJlc3BvbnNlLAogICAgICAgICAgICBlcnJvcj1lcnJvciwKICAgICAgICApCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBkZWYgX3BsYW5fZmluaXNoZWQoc2VsZiwgcGxhbl9sb2cpOgogICAgICAgICIiIgogICAgICAgIEhhbmRsZSB0aGUgcGxhbiBmaW5pc2hlZCBldmVudAoKICAgICAgICBBcmdzOgogICAgICAgICAgICBwbGFuX2xvZyAoY3gudG93ZXIucGxhbi5sb2cpOiBQbGFuIGxvZyByZWNvcmQKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgYm9vbDogVHJ1ZSBpZiBldmVudCB3YXMgaGFuZGxlZAogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgaWYgcGxhbl9sb2cucGxhbl9zdGF0dXMgPT0gMDoKICAgICAgICAgICAgIyBTdWNjZXNzZnVsbHkgZmluaXNoZWQgdGhlIHBsYW4KICAgICAgICAgICAgamV0ID0gc2VsZi5qZXRfaWQgICMgcHJlc2VydmUgaW4gY2FzZSBvZiBkZWxldGluZwoKICAgICAgICAgICAgaWYgc2VsZi5zdGF0ZSA9PSAiYXJyaXZpbmciOgogICAgICAgICAgICAgICAgIyBTZXQgdGhlIHdheXBvaW50IGFzIHRoZSBjdXJyZW50IHdheXBvaW50CiAgICAgICAgICAgICAgICAjIHdoZW4gc3VjY2Vzc2Z1bGx5IGFycml2aW5nCiAgICAgICAgICAgICAgICBzZWxmLmpldF9pZC53cml0ZSh7IndheXBvaW50X2lkIjogc2VsZi5pZH0pCiAgICAgICAgICAgICAgICBzZWxmLmpldF9pZC5pbnZhbGlkYXRlX3JlY29yZHNldChbIndheXBvaW50X2lkIl0pCiAgICAgICAgICAgICAgICAjIENsZWFyIGRlc3RpbmF0aW9uIGZsYWcgd2hlbiBzdWNjZXNzZnVsbHkgYXJyaXZlZAogICAgICAgICAgICAgICAgc2VsZi53cml0ZSh7InN0YXRlIjogImN1cnJlbnQiLCAiaXNfZGVzdGluYXRpb24iOiBGYWxzZX0pCiAgICAgICAgICAgICAgICBzZWxmLl9maW5hbGl6ZV9jcmVhdGVfd2F5cG9pbnRfY29tbWFuZF9sb2coc3VjY2Vzcz1UcnVlKQogICAgICAgICAgICAgICAgX2xvZ2dlci5pbmZvKAogICAgICAgICAgICAgICAgICAgIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICJTdWNjZXNzZnVsbHkgYXJyaXZlZCBhdCB3YXlwb2ludCAlKHdheXBvaW50KXMgb24gamV0ICUoamV0KXMiLAogICAgICAgICAgICAgICAgICAgICAgICB3YXlwb2ludD1zZWxmLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGpldD1zZWxmLmpldF9pZC5uYW1lLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgZWxpZiBzZWxmLnN0YXRlID09ICJkZWxldGluZyI6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHsic3RhdGUiOiAiZGVsZXRlZCJ9KQogICAgICAgICAgICAgICAgd2F5cG9pbnRfbmFtZSA9IHNlbGYubmFtZQogICAgICAgICAgICAgICAgamV0X25hbWUgPSBzZWxmLmpldF9pZC5uYW1lCiAgICAgICAgICAgICAgICBzZWxmLnVubGluaygpCiAgICAgICAgICAgICAgICBfbG9nZ2VyLmluZm8oCiAgICAgICAgICAgICAgICAgICAgXygKICAgICAgICAgICAgICAgICAgICAgICAgIlN1Y2Nlc3NmdWxseSBkZWxldGVkIHdheXBvaW50ICUod2F5cG9pbnQpcyBvbiBqZXQgJShqZXQpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdheXBvaW50PXdheXBvaW50X25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGpldD1qZXRfbmFtZSwKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIGVsaWYgc2VsZi5zdGF0ZSBpbiBbImxlYXZpbmciLCAicHJlcGFyaW5nIl06CiAgICAgICAgICAgICAgICAjIFNhdmUgamV0IHZhcmlhYmxlIHZhbHVlcwogICAgICAgICAgICAgICAgc2VsZi5fc2F2ZV92YXJpYWJsZV92YWx1ZXMoKQoKICAgICAgICAgICAgICAgICMgQXJyaXZlIGF0IHRoZSBkZXN0aW5hdGlvbiB3YXlwb2ludAogICAgICAgICAgICAgICAgIyBpZiB0aGVyZSBpcyBhbnkgaW4gdGhlIGFycml2aW5nIHN0YXRlIChvbmx5IGZvciBsZWF2aW5nKQogICAgICAgICAgICAgICAgaWYgc2VsZi5zdGF0ZSA9PSAibGVhdmluZyI6CiAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb25fd2F5cG9pbnQgPSBzZWxmLmpldF9pZC53YXlwb2ludF9pZHMuZmlsdGVyZWQoCiAgICAgICAgICAgICAgICAgICAgICAgICJpc19kZXN0aW5hdGlvbiIKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgaWYgZGVzdGluYXRpb25fd2F5cG9pbnQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uX3dheXBvaW50LndyaXRlKHsic3RhdGUiOiAiYXJyaXZpbmcifSkKICAgICAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb25fd2F5cG9pbnQuX2Fycml2ZSgpCgogICAgICAgICAgICAgICAgIyBTZXQgdGhlIHdheXBvaW50IHN0YXRlIHRvIHJlYWR5IGFmdGVyIGxlYXZpbmcgb3IgcHJlcGFyaW5nCiAgICAgICAgICAgICAgICBwcmVwYXJlZCA9IHNlbGYuc3RhdGUgPT0gInByZXBhcmluZyIKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoeyJzdGF0ZSI6ICJyZWFkeSJ9KQogICAgICAgICAgICAgICAgIyBGbHkgdG8gdGhpcyB3YXlwb2ludCBpZiBzZXQgYXMgZGVzdGluYXRpb24KICAgICAgICAgICAgICAgIGlmIHNlbGYuaXNfZGVzdGluYXRpb24gYW5kIHByZXBhcmVkOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmx5X3RvKCkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZmluYWxpemVfY3JlYXRlX3dheXBvaW50X2NvbW1hbmRfbG9nKHN1Y2Nlc3M9VHJ1ZSkKCiAgICAgICAgICAgICMgUmVmcmVzaCB0aGUgZnJvbnRlbmQgdmlld3MKICAgICAgICAgICAgc2VsZi5lbnYudXNlci5yZWxvYWRfdmlld3MobW9kZWw9ImN4LnRvd2VyLmpldCIsIHJlY19pZHM9W2pldC5pZF0pCiAgICAgICAgICAgIHJldHVybiBUcnVlCgogICAgICAgICMgRmFpbGVkIHRvIGZpbmlzaCB0aGUgcGxhbgogICAgICAgICMgLSByZXN0b3JlIHZhcmlhYmxlIHZhbHVlcyBmcm9tIGN1cnJlbnQgd2F5cG9pbnQKICAgICAgICAjIC0gc2V0IHRoZSB3YXlwb2ludCBzdGF0ZSB0byBlcnJvcgogICAgICAgIGlmIHNlbGYuc3RhdGUgPT0gImFycml2aW5nIjoKICAgICAgICAgICAgIyBSZXN0b3JlIHZhcmlhYmxlIHZhbHVlcyBmcm9tIGpldCdzIGN1cnJlbnQgd2F5cG9pbnQKICAgICAgICAgICAgY3VycmVudF93YXlwb2ludCA9IHNlbGYuamV0X2lkLndheXBvaW50X2lkCiAgICAgICAgICAgIGlmIGN1cnJlbnRfd2F5cG9pbnQ6CiAgICAgICAgICAgICAgICBjdXJyZW50X3dheXBvaW50Ll9yZXN0b3JlX3ZhcmlhYmxlX3ZhbHVlcygpCiAgICAgICAgICAgICAgICAjIFNldCBjdXJyZW50IHdheXBvaW50IHN0YXRlIHRvICJjdXJyZW50IgogICAgICAgICAgICAgICAgY3VycmVudF93YXlwb2ludC53cml0ZSh7InN0YXRlIjogImN1cnJlbnQifSkKICAgICAgICAgICAgIyBDbGVhciBkZXN0aW5hdGlvbiBmbGFnIHdoZW4gYXJyaXZpbmcgZmFpbHMKICAgICAgICAgICAgc2VsZi53cml0ZSh7ImlzX2Rlc3RpbmF0aW9uIjogRmFsc2UsICJzdGF0ZSI6ICJlcnJvciJ9KQogICAgICAgICAgICBzZWxmLl9maW5hbGl6ZV9jcmVhdGVfd2F5cG9pbnRfY29tbWFuZF9sb2coCiAgICAgICAgICAgICAgICBzdWNjZXNzPUZhbHNlLCBlcnJvcj1fKCJQbGFuIGZhaWxlZCB3aGlsZSBhcnJpdmluZy4iKQogICAgICAgICAgICApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgc2VsZi5zdGF0ZSA9PSAibGVhdmluZyI6CiAgICAgICAgICAgICAgICAjIENhbmNlbCBwZW5kaW5nIGRlc3RpbmF0aW9uIHdoZW4gbGVhdmUgcGxhbiBmYWlscy4KICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uX3dheXBvaW50ID0gc2VsZi5qZXRfaWQud2F5cG9pbnRfaWRzLmZpbHRlcmVkKAogICAgICAgICAgICAgICAgICAgIGxhbWJkYSB3OiB3LmlzX2Rlc3RpbmF0aW9uIGFuZCB3LmlkICE9IHNlbGYuaWQKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGlmIGRlc3RpbmF0aW9uX3dheXBvaW50OgogICAgICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uX3dheXBvaW50LndyaXRlKHsiaXNfZGVzdGluYXRpb24iOiBGYWxzZX0pCiAgICAgICAgICAgICAgICAgICAgZGVzdGluYXRpb25fd2F5cG9pbnQuX2ZpbmFsaXplX2NyZWF0ZV93YXlwb2ludF9jb21tYW5kX2xvZygKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzcz1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I9XygiRmFpbGVkIHRvIGxlYXZlIGN1cnJlbnQgd2F5cG9pbnQuIiksCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICBzZWxmLndyaXRlKHsic3RhdGUiOiAiZXJyb3IiLCAiaXNfZGVzdGluYXRpb24iOiBGYWxzZX0pCiAgICAgICAgICAgIHNlbGYuX2ZpbmFsaXplX2NyZWF0ZV93YXlwb2ludF9jb21tYW5kX2xvZygKICAgICAgICAgICAgICAgIHN1Y2Nlc3M9RmFsc2UsIGVycm9yPV8oIlBsYW4gZmFpbGVkLiIpCiAgICAgICAgICAgICkKCiAgICAgICAgIyBSZWZyZXNoIHRoZSBmcm9udGVuZCB2aWV3cwogICAgICAgIHNlbGYuZW52LnVzZXIucmVsb2FkX3ZpZXdzKG1vZGVsPSJjeC50b3dlci5qZXQiLCByZWNfaWRzPVtzZWxmLmpldF9pZC5pZF0pCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIC0tLS0tLS0tLSBIZWxwZXIgTWV0aG9kcyAtLS0tLS0tLS0KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGRlZiBfc2F2ZV92YXJpYWJsZV92YWx1ZXMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgU2F2ZSBjdXJyZW50IGpldCB2YXJpYWJsZSB2YWx1ZXMgdG8gdGhlIHdheXBvaW50LgogICAgICAgIE9ubHkgamV0LXNwZWNpZmljIHZhbHVlcyBhcmUgc2F2ZWQgKG5vdCB0ZW1wbGF0ZS9zZXJ2ZXIvZ2xvYmFsIHZhbHVlcykuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGJvb2w6IFRydWUgaWYgdmFsdWVzIHdlcmUgc2F2ZWQKICAgICAgICAiIiIKICAgICAgICBzZWxmLmVuc3VyZV9vbmUoKQoKICAgICAgICAjIEdldCBhbGwgdmFyaWFibGUgdmFsdWVzIHRoYXQgYmVsb25nIHRvIHRoaXMgamV0IHNwZWNpZmljYWxseQogICAgICAgICMgKG5vdCB0ZW1wbGF0ZS9zZXJ2ZXIvZ2xvYmFsIHZhbHVlcykKICAgICAgICAjIFVzZSB2YXJpYWJsZV92YWx1ZV9pZHMgZmllbGQgZnJvbSB2YXJpYWJsZSBtaXhpbgogICAgICAgIGpldF92YXJpYWJsZV92YWx1ZXMgPSBzZWxmLmpldF9pZC52YXJpYWJsZV92YWx1ZV9pZHMKCiAgICAgICAgIyBCdWlsZCBkaWN0aW9uYXJ5IG1hcHBpbmcgdmFyaWFibGVfcmVmZXJlbmNlIHRvIHZhbHVlX2NoYXIKICAgICAgICB2YXJpYWJsZV92YWx1ZXNfZGljdCA9IHt9CiAgICAgICAgZm9yIHZhcl92YWx1ZSBpbiBqZXRfdmFyaWFibGVfdmFsdWVzOgogICAgICAgICAgICB2YXJpYWJsZV92YWx1ZXNfZGljdFt2YXJfdmFsdWUudmFyaWFibGVfcmVmZXJlbmNlXSA9ICgKICAgICAgICAgICAgICAgIHZhcl92YWx1ZS52YWx1ZV9jaGFyIG9yICIiCiAgICAgICAgICAgICkKCiAgICAgICAgIyBTYXZlIHRvIHdheXBvaW50J3MgdmFyaWFibGVfdmFsdWVzIGZpZWxkCiAgICAgICAgc2VsZi53cml0ZSh7InZhcmlhYmxlX3ZhbHVlcyI6IHZhcmlhYmxlX3ZhbHVlc19kaWN0fSkKICAgICAgICBzZWxmLmludmFsaWRhdGVfcmVjb3Jkc2V0KFsidmFyaWFibGVfdmFsdWVzIl0pCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBkZWYgX3Jlc3RvcmVfdmFyaWFibGVfdmFsdWVzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlc3RvcmUgdmFyaWFibGUgdmFsdWVzIGZyb20gdGhlIHdheXBvaW50IHRvIHRoZSBqZXQuCiAgICAgICAgLSBSZW1vdmVzIGFsbCB2YXJpYWJsZSB2YWx1ZXMgdGhhdCBhcmUgbm90IHNhdmVkIGluIHRoZSB3YXlwb2ludAoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBib29sOiBUcnVlIGlmIHZhbHVlcyB3ZXJlIHJlc3RvcmVkCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICBpZiBub3Qgc2VsZi52YXJpYWJsZV92YWx1ZXM6CiAgICAgICAgICAgICMgUmVtb3ZlIGFsbCBqZXQgdmFyaWFibGUgdmFsdWVzIGlmIHdheXBvaW50IGhhcyBubyBzYXZlZCB2YWx1ZXMKICAgICAgICAgICAgc2VsZi5qZXRfaWQudmFyaWFibGVfdmFsdWVfaWRzLnVubGluaygpCiAgICAgICAgICAgIHJldHVybiBUcnVlCgogICAgICAgICMgR2V0IGFsbCBjdXJyZW50IGpldCB2YXJpYWJsZSB2YWx1ZXMKICAgICAgICBjdXJyZW50X2pldF92YWx1ZXMgPSBzZWxmLmpldF9pZC52YXJpYWJsZV92YWx1ZV9pZHMKICAgICAgICBzYXZlZF9yZWZlcmVuY2VzID0gc2V0KHNlbGYudmFyaWFibGVfdmFsdWVzLmtleXMoKSkKCiAgICAgICAgIyBSZW1vdmUgdmFyaWFibGUgdmFsdWVzIHRoYXQgYXJlIG5vdCBpbiB0aGUgc2F2ZWQgd2F5cG9pbnQgdmFsdWVzCiAgICAgICAgdmFsdWVzX3RvX3JlbW92ZSA9IGN1cnJlbnRfamV0X3ZhbHVlcy5maWx0ZXJlZCgKICAgICAgICAgICAgbGFtYmRhIHY6IHYudmFyaWFibGVfcmVmZXJlbmNlIG5vdCBpbiBzYXZlZF9yZWZlcmVuY2VzCiAgICAgICAgKQogICAgICAgIGlmIHZhbHVlc190b19yZW1vdmU6CiAgICAgICAgICAgIHZhbHVlc190b19yZW1vdmUudW5saW5rKCkKCiAgICAgICAgIyBSZXN0b3JlIGVhY2ggdmFyaWFibGUgdmFsdWUgZnJvbSB0aGUgc2F2ZWQgZGljdGlvbmFyeQogICAgICAgICMgVmFyaWFibGUgbWl4aW4gaGFuZGxlcyBjaGVja2luZyBpZiB2YWx1ZSBpcyB0aGUgc2FtZQogICAgICAgIGZvciB2YXJpYWJsZV9yZWZlcmVuY2UsIHNhdmVkX3ZhbHVlIGluIHNlbGYudmFyaWFibGVfdmFsdWVzLml0ZW1zKCk6CiAgICAgICAgICAgIHNlbGYuamV0X2lkLnNldF92YXJpYWJsZV92YWx1ZSh2YXJpYWJsZV9yZWZlcmVuY2UsIHNhdmVkX3ZhbHVlKQoKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfZ2V0X2N1c3RvbV92YXJpYWJsZV92YWx1ZXMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgUHJlcGFyZSBjdXN0b20gdmFyaWFibGUgdmFsdWVzIHRvIHBhc3Mgd2l0aCBmbGlnaHQgcGxhbnMuCiAgICAgICAgRm9sbG93aW5nIGN1c3RvbSB2YWx1ZXMgYXJlIGF2YWlsYWJsZToKCiAgICAgICAgX193YXlwb2ludDogd2F5cG9pbnQgcmVmZXJlbmNlCiAgICAgICAgX193YXlwb2ludF90eXBlOiB3YXlwb2ludCB0ZW1wbGF0ZSByZWZlcmVuY2UKICAgICAgICBfX3dheXBvaW50X3N0YXRlOiB3YXlwb2ludCBzdGF0ZQogICAgICAgIF9fd2F5cG9pbnRfPG1ldGFkYXRhX2tleT46IHdheXBvaW50IG1ldGFkYXRhCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IEN1c3RvbSB2YXJpYWJsZSB2YWx1ZXMgdG8gcGFzcyB3aXRoIGZsaWdodCBwbGFucwogICAgICAgICIiIgogICAgICAgIHNlbGYuZW5zdXJlX29uZSgpCiAgICAgICAgY3VzdG9tX3ZhbHVlcyA9IHsKICAgICAgICAgICAgIl9fd2F5cG9pbnQiOiBzZWxmLnJlZmVyZW5jZSwKICAgICAgICAgICAgIl9fd2F5cG9pbnRfdHlwZSI6IHNlbGYud2F5cG9pbnRfdGVtcGxhdGVfaWQucmVmZXJlbmNlLAogICAgICAgICAgICAiX193YXlwb2ludF9zdGF0ZSI6IHNlbGYuc3RhdGUsCiAgICAgICAgfQogICAgICAgIGlmIHNlbGYubWV0YWRhdGE6CiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIHNlbGYubWV0YWRhdGEuaXRlbXMoKToKICAgICAgICAgICAgICAgIGN1c3RvbV92YWx1ZXNbZiJfX3dheXBvaW50X3trZXl9Il0gPSB2YWx1ZQogICAgICAgIHJldHVybiBjdXN0b21fdmFsdWVzCg== \ No newline at end of file