1 line
37 KiB
Python
1 line
37 KiB
Python
IyBDb3B5cmlnaHQgKEMpIDIwMjQgQ2V0bWl4IE/DnAojIExpY2Vuc2UgQUdQTC0zLjAgb3IgbGF0ZXIgKGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsKS4KCmltcG9ydCBjb3B5CmltcG9ydCBsb2dnaW5nCgppbXBvcnQgeWFtbAoKZnJvbSBvZG9vIGltcG9ydCBfLCBhcGksIGZpZWxkcywgbW9kZWxzCmZyb20gb2Rvby5leGNlcHRpb25zIGltcG9ydCBBY2Nlc3NFcnJvciwgVmFsaWRhdGlvbkVycm9yCgpfbG9nZ2VyID0gbG9nZ2luZy5nZXRMb2dnZXIoX19uYW1lX18pCkRFRkVSUkVEX00yT19JTVBPUlQgPSBvYmplY3QoKQoKCmNsYXNzIEN1c3RvbUR1bXBlcih5YW1sLkR1bXBlcik6CiAgICAiIiJDdXN0b20gZHVtcGVyIHRvIGVuc3VyZXMgY29kZQogICAgaXMgcHJvcGVybHkgZHVtcGVkIGluIFlBTUwKICAgICIiIgoKICAgIGRlZiByZXByZXNlbnRfc2NhbGFyKHNlbGYsIHRhZywgdmFsdWUsIHN0eWxlPU5vbmUpOgogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIHN0cikgYW5kICJcbiIgaW4gdmFsdWU6CiAgICAgICAgICAgIHN0eWxlID0gInwiCiAgICAgICAgcmV0dXJuIHN1cGVyKCkucmVwcmVzZW50X3NjYWxhcih0YWcsIHZhbHVlLCBzdHlsZSkKCgpjbGFzcyBZYW1sRXhwb3J0Q29sbGVjdG9yOgogICAgIiIiCiAgICBDb2xsZWN0b3IgZm9yIFlBTUwgZXhwb3J0LgogICAgVHJhY2tzIHVuaXF1ZSByZWNvcmRzIGJ5IHRoZWlyIChtb2RlbF9uYW1lLCByZWZlcmVuY2UpIHR1cGxlIHRvIGF2b2lkIGR1cGxpY2F0ZXMuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgSW5pdGlhbGl6ZSB0aGUgY29sbGVjdG9yLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYWRkZWRfcmVmZXJlbmNlcyA9IHNldCgpCgogICAgZGVmIGFkZChzZWxmLCBrZXkpOgogICAgICAgICIiIgogICAgICAgIEFkZCBhIHJlY29yZCB0byB0aGUgY29sbGVjdG9yIGlmIGl0cyByZWZlcmVuY2UgaXMgdW5pcXVlLgogICAgICAgIDpwYXJhbSBrZXk6IHR1cGxlLCBrZXkgb2YgdGhlIHJlY29yZAogICAgICAgICIiIgogICAgICAgIGlmIGtleSBhbmQga2V5IG5vdCBpbiBzZWxmLmFkZGVkX3JlZmVyZW5jZXM6CiAgICAgICAgICAgIHNlbGYuYWRkZWRfcmVmZXJlbmNlcy5hZGQoa2V5KQoKICAgIGRlZiBpc19hZGRlZChzZWxmLCBrZXkpOgogICAgICAgICIiIgogICAgICAgIENoZWNrIGJ5IChtb2RlbCwgcmVmZXJlbmNlKSB0dXBsZS4KICAgICAgICA6cGFyYW0ga2V5OiB0dXBsZSwga2V5IG9mIHRoZSByZWNvcmQKICAgICAgICA6cmV0dXJuOiBib29sCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIGtleSBpbiBzZWxmLmFkZGVkX3JlZmVyZW5jZXMKCgpjbGFzcyBDeFRvd2VyWWFtbE1peGluKG1vZGVscy5BYnN0cmFjdE1vZGVsKToKICAgICIiIlVzZWQgdG8gaW1wbGVtZW50IFlBTUwgcmVuZGVyaW5nIGZ1bmN0aW9ucy4KICAgIEluaGVyaXQgaW4geW91ciBtb2RlbCBpbiBjYXNlIHlvdSB3YW50IHRvIFlBTUwgaW5zdGFuY2Ugb2YgdGhlIHJlY29yZHMuCiAgICAiIiIKCiAgICBfbmFtZSA9ICJjeC50b3dlci55YW1sLm1peGluIgogICAgX2Rlc2NyaXB0aW9uID0gIkNldG1peCBUb3dlciBZQU1MIHJlbmRlcmluZyBtaXhpbiIKCiAgICAjIEZpbGUgZm9ybWF0IHZlcnNpb24gaW4gb3JkZXIgdG8gdHJhY2sgY29tcGF0aWJpbGl0eQogICAgQ0VUTUlYX1RPV0VSX1lBTUxfVkVSU0lPTiA9IDEKCiAgICAjIFRPX1lBTUxfKiB1c2VkIHRvIGNvbnZlcnQgZnJvbSBPZG9vIGZpZWxkIHZhbHVlcyB0byBZQU1MCiAgICBUT19ZQU1MX0FDQ0VTU19MRVZFTCA9IHsiMSI6ICJ1c2VyIiwgIjIiOiAibWFuYWdlciIsICIzIjogInJvb3QifQoKICAgICMgVE9fVE9XRVJfKiB1c2VkIHRvIGNvbnZlcnQgZnJvbSBZQU1MIGZpZWxkIHZhbHVlcyB0byBUb3dlciBvbmVzCiAgICBUT19UT1dFUl9BQ0NFU1NfTEVWRUwgPSB7InVzZXIiOiAiMSIsICJtYW5hZ2VyIjogIjIiLCAicm9vdCI6ICIzIn0KCiAgICB5YW1sX2NvZGUgPSBmaWVsZHMuVGV4dCgKICAgICAgICBjb21wdXRlPSJfY29tcHV0ZV95YW1sX2NvZGUiLAogICAgICAgIGludmVyc2U9Il9pbnZlcnNlX3lhbWxfY29kZSIsCiAgICAgICAgZ3JvdXBzPSJjZXRtaXhfdG93ZXJfeWFtbC5ncm91cF9leHBvcnQsY2V0bWl4X3Rvd2VyX3lhbWwuZ3JvdXBfaW1wb3J0IiwKICAgICkKCiAgICBkZWYgX2NvbXB1dGVfeWFtbF9jb2RlKHNlbGYpOgogICAgICAgICIiIkNvbXB1dGUgWUFNTCBjb2RlIGJhc2VkIG9uIG1vZGVsIHJlY29yZCBkYXRhIiIiCiAgICAgICAgIyBUaGlzIGlzIHVzZWQgZm9yIHRoZSBmaWxlIG5hbWUuCiAgICAgICAgIyBFZyBjeC50b3dlci5jb21tYW5kIHJlY29yZCB3aWxsIGhhdmUgJ2NvbW1hbmRfJyBwcmVmaXguCiAgICAgICAgZm9yIHJlY29yZCBpbiBzZWxmOgogICAgICAgICAgICAjIFVzZSBhIHNoYXJlZCBjb2xsZWN0b3IgZnJvbSBjb250ZXh0IHdoZW4gb25lIGlzIHByb3ZpZGVkIChlLmcuIGJ5CiAgICAgICAgICAgICMgdGhlIGV4cG9ydCB3aXphcmQgZm9yIGNyb3NzLXJlY29yZCBkZWR1cGxpY2F0aW9uKTsgb3RoZXJ3aXNlIHVzZSBhCiAgICAgICAgICAgICMgZnJlc2ggcGVyLXJlY29yZCBjb2xsZWN0b3Igc28gdGhhdCBlYWNoIHJlY29yZCdzIHlhbWxfY29kZSBpcwogICAgICAgICAgICAjIGRldGVybWluaXN0aWMgcmVnYXJkbGVzcyBvZiB3aGljaCBzaWJsaW5nIHJlY29yZHMgYXJlIGJhdGNoZWQuCiAgICAgICAgICAgIGNvbGxlY3RvciA9IHJlY29yZC5fY29udGV4dC5nZXQoInlhbWxfY29sbGVjdG9yIikgb3IgWWFtbEV4cG9ydENvbGxlY3RvcigpCiAgICAgICAgICAgICMgV2UgYXJlIHJlYWRpbmcgZmllbGQgbGlzdCBmb3IgZWFjaCByZWNvcmQKICAgICAgICAgICAgIyBiZWNhdXNlIGxpc3Qgb2YgZmllbGRzIGNhbiBkaWZmZXIgZnJvbSByZWNvcmQgdG8gcmVjb3JkCiAgICAgICAgICAgIHJlY29yZC55YW1sX2NvZGUgPSBzZWxmLl9jb252ZXJ0X2RpY3RfdG9feWFtbCgKICAgICAgICAgICAgICAgIHJlY29yZC53aXRoX2NvbnRleHQoeWFtbF9jb2xsZWN0b3I9Y29sbGVjdG9yKS5fcHJlcGFyZV9yZWNvcmRfZm9yX3lhbWwoKQogICAgICAgICAgICApCgogICAgZGVmIF9pbnZlcnNlX3lhbWxfY29kZShzZWxmKToKICAgICAgICAiIiJDb21wb3NlIHJlY29yZCBiYXNlZCBvbiBwcm92aWRlZCBZQU1MIiIiCiAgICAgICAgZm9yIHJlY29yZCBpbiBzZWxmOgogICAgICAgICAgICBpZiByZWNvcmQueWFtbF9jb2RlOgogICAgICAgICAgICAgICAgcmVjb3JkX3lhbWxfZGljdCA9IHlhbWwuc2FmZV9sb2FkKHJlY29yZC55YW1sX2NvZGUpCiAgICAgICAgICAgICAgICByZWNvcmRfdmFscyA9IHJlY29yZC5fcG9zdF9wcm9jZXNzX3lhbWxfZGljdF92YWx1ZXMocmVjb3JkX3lhbWxfZGljdCkKICAgICAgICAgICAgICAgIHJlY29yZC51cGRhdGUocmVjb3JkX3ZhbHMpCgogICAgQGFwaS5jb25zdHJhaW5zKCJ5YW1sX2NvZGUiKQogICAgZGVmIF9jaGVja195YW1sX2NvZGVfd3JpdGVfYWNjZXNzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENoZWNrIGlmIHVzZXIgaGFzIGFjY2VzcyB0byBjcmVhdGUgcmVjb3JkcyBmcm9tIFlBTUwuCiAgICAgICAgVGhpcyBpcyBjaGVja2VkIG9ubHkgd2hlbiB1c2VyIGFscmVhZHkgaGFzIGFjY2VzcyB0byBleHBvcnQgWUFNTC4KICAgICAgICBPdGhlcndpc2UsIHRoZSBmaWVsZCBpcyBub3QgYWNjZXNzaWJsZSBkdWUgdG8gc2VjdXJpdHkgZ3JvdXAuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5lbnYudXNlci5oYXNfZ3JvdXAoImNldG1peF90b3dlcl95YW1sLmdyb3VwX2V4cG9ydCIpIGFuZCAoCiAgICAgICAgICAgIG5vdCBzZWxmLmVudi51c2VyLmhhc19ncm91cCgiY2V0bWl4X3Rvd2VyX3lhbWwuZ3JvdXBfaW1wb3J0IikKICAgICAgICAgICAgYW5kIG5vdCBzZWxmLmVudi51c2VyLl9pc19zdXBlcnVzZXIoKQogICAgICAgICk6CiAgICAgICAgICAgIHJhaXNlIEFjY2Vzc0Vycm9yKF8oIllvdSBhcmUgbm90IGFsbG93ZWQgdG8gY3JlYXRlIHJlY29yZHMgZnJvbSBZQU1MIikpCgogICAgQGFwaS5tb2RlbF9jcmVhdGVfbXVsdGkKICAgIGRlZiBjcmVhdGUoc2VsZiwgdmFsc19saXN0KToKICAgICAgICAjIEhhbmRsZSB2YWxpZGF0aW9uIGVycm9yIHdoZW4gZmllbGQgdmFsdWVzIGFyZSBub3QgdmFsaWQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBzdXBlcigpLmNyZWF0ZSh2YWxzX2xpc3QpCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3IgYXMgZToKICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKHN0cihlKSkgZnJvbSBlCgogICAgZGVmIHdyaXRlKHNlbGYsIHZhbHMpOgogICAgICAgICMgSGFuZGxlIHZhbGlkYXRpb24gZXJyb3Igd2hlbiBmaWVsZCB2YWx1ZXMgYXJlIG5vdCB2YWxpZAogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIHN1cGVyKCkud3JpdGUodmFscykKICAgICAgICBleGNlcHQgVmFsdWVFcnJvciBhcyBlOgogICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3Ioc3RyKGUpKSBmcm9tIGUKCiAgICBkZWYgYWN0aW9uX29wZW5feWFtbF9leHBvcnRfd2l6YXJkKHNlbGYpOgogICAgICAgICIiIk9wZW4gWUFNTCBleHBvcnQgd2l6YXJkIiIiCgogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICJ0eXBlIjogImlyLmFjdGlvbnMuYWN0X3dpbmRvdyIsCiAgICAgICAgICAgICJyZXNfbW9kZWwiOiAiY3gudG93ZXIueWFtbC5leHBvcnQud2l6IiwKICAgICAgICAgICAgInZpZXdfbW9kZSI6ICJmb3JtIiwKICAgICAgICAgICAgInRhcmdldCI6ICJuZXciLAogICAgICAgIH0KCiAgICBkZWYgX2NvbnZlcnRfZGljdF90b195YW1sKHNlbGYsIHZhbHVlcyk6CiAgICAgICAgIiIiQ29udmVydHMgUHl0aG9uIGRpY3Rpb25hcnkgdG8gWUFNTCBzdHJpbmcuCgogICAgICAgIFRoaXMgaXMgYSBoZWxwZXIgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkCiAgICAgICAgYnkgYW55IG1vZGVscyB0aGF0IG5lZWQgdG8gY29udmVydCBhIGRpY3Rpb25hcnkgdG8gWUFNTC4KCiAgICAgICAgICAgQXJnczoKICAgICAgICAgICAgICAgdmFsdWVzIChEaWN0KTogRGljdGlvbmFyeSBjb250YWluaW5nIGRhdGEKICAgICAgICAgICAgICAgICAgICB0byBiZSBjb252ZXJ0ZWQgdG8gWUFNTCBmb3JtYXQKICAgICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICAgICBUZXh0OiBZQU1MIHN0cmluZwogICAgICAgICAgIFJhaXNlczoKICAgICAgICAgICAgICAgVmFsaWRhdGlvbkVycm9yOiBJZiB2YWx1ZXMgaXMgbm90IGEgZGljdGlvbmFyeQogICAgICAgICAgICAgICAgICAgb3IgWUFNTCBjb252ZXJzaW9uIGZhaWxzCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UodmFsdWVzLCBkaWN0KToKICAgICAgICAgICAgcmFpc2UgVmFsaWRhdGlvbkVycm9yKF8oIlZhbHVlcyBtdXN0IGJlIGEgZGljdGlvbmFyeSIpKQogICAgICAgIHRyeToKICAgICAgICAgICAgeWFtbF9jb2RlID0geWFtbC5kdW1wKAogICAgICAgICAgICAgICAgdmFsdWVzLAogICAgICAgICAgICAgICAgRHVtcGVyPUN1c3RvbUR1bXBlciwKICAgICAgICAgICAgICAgIGRlZmF1bHRfZmxvd19zdHlsZT1GYWxzZSwKICAgICAgICAgICAgICAgIHNvcnRfa2V5cz1GYWxzZSwKICAgICAgICAgICAgKQogICAgICAgICAgICByZXR1cm4geWFtbF9jb2RlCiAgICAgICAgZXhjZXB0ICh5YW1sLllBTUxFcnJvciwgVW5pY29kZUVuY29kZUVycm9yKSBhcyBlOgogICAgICAgICAgICByYWlzZSBWYWxpZGF0aW9uRXJyb3IoCiAgICAgICAgICAgICAgICBfKAogICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gY29udmVydCBkaWN0aW9uYXJ5IiAiIHRvIFlBTUw6ICUoZXJyb3IpcyIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3I9c3RyKGUpLAogICAgICAgICAgICAgICAgKQogICAgICAgICAgICApIGZyb20gZQoKICAgIGRlZiBfcHJlcGFyZV9yZWNvcmRfZm9yX3lhbWwoc2VsZik6CiAgICAgICAgIiIiUmVhZHMgYW5kIHByb2Nlc3NlcyBjdXJyZW50IHJlY29yZCBiZWZvcmUgY29udmVydGluZyBpdCB0byBZQU1MCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IHZhbHVlcyByZWFkeSBmb3IgWUFNTCBjb252ZXJzaW9uCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5lbnN1cmVfb25lKCkKICAgICAgICB5YW1sX2tleXMgPSBzZWxmLl9nZXRfZmllbGRzX2Zvcl95YW1sKCkKICAgICAgICByZWNvcmRfZGljdCA9IHNlbGYucmVhZChmaWVsZHM9eWFtbF9rZXlzKVswXQogICAgICAgIHJldHVybiBzZWxmLl9wb3N0X3Byb2Nlc3NfcmVjb3JkX3ZhbHVlcyhyZWNvcmRfZGljdCkKCiAgICBkZWYgX2dldF9maWVsZHNfZm9yX3lhbWwoc2VsZik6CiAgICAgICAgIiIiR2V0IGlzdCBvZiBmaWVsZCB0byBiZSBwcmVzZW50IGluIFlBTUwKCiAgICAgICAgU2V0ICdub195YW1sX3NlcnZpY2VfZmllbGRzJyBjb250ZXh0IGtleSB0byBza2lwCiAgICAgICAgICAgIHNlcnZpY2UgZmllbGRzIGNyZWF0aW9uIChjZXRtaXhfdG93ZXJfeWFtbF92ZXJzaW9uLCBjZXRtaXhfdG93ZXJfbW9kZWwpCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGxpc3QoKTogbGlzdCBvZiBmaWVsZHMgdG8gYmUgdXNlZCBhcyBZQU1MIGtleXMKICAgICAgICAiIiIKICAgICAgICByZXR1cm4gWyJyZWZlcmVuY2UiXQoKICAgIGRlZiBfZ2V0X2ZvcmNlX3gybV9yZXNvbHZlX21vZGVscyhzZWxmKToKICAgICAgICAiIiJMaXN0IG9mIG1vZGVscyB0aGF0IHdpbGwgYWx3YXlzIHRyeSB0byBiZSByZXNvbHZlZAogICAgICAgIHdoZW4gcmVmZXJlbmNlZCBpbiB4Mm0gcmVsYXRlZCBmaWVsZHMuCgogICAgICAgIFRoaXMgaXMgdXNlZnVsIGZvciBtb2RlbHMgdGhhdCBzaG91bGQgYWx3YXlzIHVzZSBleGlzdGluZyByZWNvcmRzCiAgICAgICAgaW5zdGVhZCBvZiBjcmVhdGluZyBuZXcgb25lcyB3aGVuIHJlZmVyZW5jZWQgaW4geDJtIHJlbGF0ZWQgZmllbGRzLgogICAgICAgIFN1Y2ggYXMgdmFyaWFibGVzIG9yIHRhZ3MuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIExpc3Q6IGxpc3Qgb2YgbW9kZWxzIHRoYXQgd2lsbCBhbHdheXMgdHJ5IHRvIGJlIHJlc29sdmVkCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgICAgImN4LnRvd2VyLnZhcmlhYmxlIiwKICAgICAgICAgICAgImN4LnRvd2VyLnZhcmlhYmxlLm9wdGlvbiIsCiAgICAgICAgICAgICJjeC50b3dlci50YWciLAogICAgICAgICAgICAiY3gudG93ZXIub3MiLAogICAgICAgICAgICAiY3gudG93ZXIua2V5IiwKICAgICAgICBdCgogICAgZGVmIF9nZXRfZGVmZXJyZWRfbTJvX2ltcG9ydF9maWVsZHMoc2VsZik6CiAgICAgICAgIiIiTWFwIG0ybyBmaWVsZHMgdGhhdCBzaG91bGQgYmUgcmVzb2x2ZWQgYWZ0ZXIgdGhlIG1haW4gaW1wb3J0IHBhc3MuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IEZpZWxkIG5hbWUgdG8gZXhwZWN0ZWQgdGFyZ2V0IG1vZGVsIG1hcHBpbmcuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHt9CgogICAgZGVmIF9nZXRfZGVmZXJyZWRfeDJtX2ltcG9ydF9maWVsZHMoc2VsZik6CiAgICAgICAgIiIiTWFwIHgybSBjaGlsZCByZWNvcmRzIHRoYXQgc2hvdWxkIGJlIGNyZWF0ZWQgYWZ0ZXIgdGhlIG1haW4gaW1wb3J0IHBhc3MuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3Q6IFBhcmVudCBmaWVsZCBuYW1lIHRvIGRlZmVycmVkIGNoaWxkIHNwZWMgbWFwcGluZy4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4ge30KCiAgICBkZWYgX2hhc19tZWFuaW5nZnVsX3lhbWxfdmFsdWUoc2VsZiwgdmFsdWUpOgogICAgICAgICIiIlJldHVybiB3aGV0aGVyIGEgWUFNTCB2YWx1ZSBjb250YWlucyBtZWFuaW5nZnVsIHBheWxvYWQuIiIiCiAgICAgICAgaWYgdmFsdWUgaXMgRmFsc2Ugb3IgdmFsdWUgaXMgTm9uZSBvciB2YWx1ZSA9PSAiIjoKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgaWYgaXNpbnN0YW5jZSh2YWx1ZSwgZGljdCk6CiAgICAgICAgICAgIGlmIHNldCh2YWx1ZS5rZXlzKCkpID09IHsicmVmZXJlbmNlIn06CiAgICAgICAgICAgICAgICByZXR1cm4gYm9vbCh2YWx1ZS5nZXQoInJlZmVyZW5jZSIpKQogICAgICAgICAgICByZXR1cm4gYW55KAogICAgICAgICAgICAgICAgc2VsZi5faGFzX21lYW5pbmdmdWxfeWFtbF92YWx1ZShpdGVtKQogICAgICAgICAgICAgICAgZm9yIGtleSwgaXRlbSBpbiB2YWx1ZS5pdGVtcygpCiAgICAgICAgICAgICAgICBpZiBrZXkgIT0gInJlZmVyZW5jZSIKICAgICAgICAgICAgKQogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIGxpc3QpOgogICAgICAgICAgICByZXR1cm4gYW55KHNlbGYuX2hhc19tZWFuaW5nZnVsX3lhbWxfdmFsdWUoaXRlbSkgZm9yIGl0ZW0gaW4gdmFsdWUpCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBkZWYgX2dldF9yZWZlcmVuY2Vfb25seV95YW1sX3JlbGF0aW9uX3JlZmVyZW5jZShzZWxmLCB2YWx1ZSk6CiAgICAgICAgIiIiUmV0dXJuIHJlZmVyZW5jZSBmb3IgcmVmZXJlbmNlLW9ubHkgWUFNTCByZWxhdGlvbiB2YWx1ZXMuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHZhbHVlIChzdHIgfCBkaWN0KTogWUFNTCByZWxhdGlvbiB2YWx1ZS4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgc3RyIHwgYm9vbDogUmVmZXJlbmNlIGlmIHRoZSB2YWx1ZSBpcyByZWZlcmVuY2Utb25seSwgb3RoZXJ3aXNlIEZhbHNlLgogICAgICAgICIiIgogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIHN0cik6CiAgICAgICAgICAgIHJldHVybiB2YWx1ZQogICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpIGFuZCBzZXQodmFsdWUua2V5cygpKSA9PSB7InJlZmVyZW5jZSJ9OgogICAgICAgICAgICByZXR1cm4gdmFsdWUuZ2V0KCJyZWZlcmVuY2UiKSBvciBGYWxzZQogICAgICAgIHJldHVybiBGYWxzZQoKICAgIGRlZiBfcXVldWVfZGVmZXJyZWRfbTJvX2ltcG9ydChzZWxmLCBmaWVsZCwgY29tb2RlbCwgdmFsdWUpOgogICAgICAgICIiIlF1ZXVlIHVucmVzb2x2ZWQgbTJvIHJlbGF0aW9uIGZvciB0aGUgZGVmZXJyZWQgaW1wb3J0IHBhc3MuCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIGZpZWxkIChzdHIpOiBPd25lciBmaWVsZCBuYW1lLgogICAgICAgICAgICBjb21vZGVsIChCYXNlTW9kZWwpOiBSZWxhdGVkIG1vZGVsLgogICAgICAgICAgICB2YWx1ZSAoc3RyIHwgZGljdCk6IFlBTUwgcmVsYXRpb24gdmFsdWUuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGJvb2w6IFRydWUgd2hlbiB0aGUgcmVsYXRpb24gd2FzIHF1ZXVlZCBmb3IgZGVmZXJyZWQgcmVzb2x1dGlvbi4KICAgICAgICAiIiIKICAgICAgICBxdWV1ZSA9IHNlbGYuX2NvbnRleHQuZ2V0KCJ5YW1sX2RlZmVycmVkX20yb19xdWV1ZSIpCiAgICAgICAgaWYgcXVldWUgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgICAgIGRlZmVycmVkX2ZpZWxkcyA9IHNlbGYuX2dldF9kZWZlcnJlZF9tMm9faW1wb3J0X2ZpZWxkcygpCiAgICAgICAgZXhwZWN0ZWRfbW9kZWwgPSBkZWZlcnJlZF9maWVsZHMuZ2V0KGZpZWxkKQogICAgICAgIGlmIG5vdCBleHBlY3RlZF9tb2RlbCBvciBleHBlY3RlZF9tb2RlbCAhPSBjb21vZGVsLl9uYW1lOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICAgICAgdGFyZ2V0X3JlZmVyZW5jZSA9IHNlbGYuX2dldF9yZWZlcmVuY2Vfb25seV95YW1sX3JlbGF0aW9uX3JlZmVyZW5jZSh2YWx1ZSkKICAgICAgICBpZiBub3QgdGFyZ2V0X3JlZmVyZW5jZSBvciBjb21vZGVsLmdldF9ieV9yZWZlcmVuY2UodGFyZ2V0X3JlZmVyZW5jZSk6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICByZWNvcmRfcmVmZXJlbmNlID0gc2VsZi5fY29udGV4dC5nZXQoInlhbWxfaW1wb3J0X3JlY29yZF9yZWZlcmVuY2UiKQogICAgICAgIGlmIG5vdCByZWNvcmRfcmVmZXJlbmNlOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICAgICAgcXVldWUuYXBwZW5kKAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAicmVjb3JkX21vZGVsIjogc2VsZi5fbmFtZSwKICAgICAgICAgICAgICAgICJyZWNvcmRfcmVmZXJlbmNlIjogcmVjb3JkX3JlZmVyZW5jZSwKICAgICAgICAgICAgICAgICJmaWVsZF9uYW1lIjogZmllbGQsCiAgICAgICAgICAgICAgICAidGFyZ2V0X21vZGVsIjogY29tb2RlbC5fbmFtZSwKICAgICAgICAgICAgICAgICJ0YXJnZXRfcmVmZXJlbmNlIjogdGFyZ2V0X3JlZmVyZW5jZSwKICAgICAgICAgICAgfQogICAgICAgICkKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBfcXVldWVfZGVmZXJyZWRfeDJtX2ltcG9ydChzZWxmLCBmaWVsZCwgY29tb2RlbCwgdmFsdWUpOgogICAgICAgICIiIlF1ZXVlIHVucmVzb2x2ZWQgeDJtIGNoaWxkIHJlY29yZCBmb3IgdGhlIGRlZmVycmVkIGltcG9ydCBwYXNzLgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBmaWVsZCAoc3RyKTogT3duZXIgeDJtIGZpZWxkIG5hbWUuCiAgICAgICAgICAgIGNvbW9kZWwgKEJhc2VNb2RlbCk6IFJlbGF0ZWQgY2hpbGQgbW9kZWwuCiAgICAgICAgICAgIHZhbHVlIChkaWN0KTogWUFNTCBjaGlsZCByZWNvcmQgdmFsdWUuCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGJvb2w6IFRydWUgd2hlbiB0aGUgY2hpbGQgd2FzIHF1ZXVlZCBmb3IgZGVmZXJyZWQgY3JlYXRpb24gb3IKICAgICAgICAgICAgICAgICAgc2hvdWxkIGJlIHNraXBwZWQgKGUuZy4sIGVtcHR5IHZhbHVlIHdpdGggc2tpcF9lbXB0eT1UcnVlKS4KICAgICAgICAiIiIKICAgICAgICBxdWV1ZSA9IHNlbGYuX2NvbnRleHQuZ2V0KCJ5YW1sX2RlZmVycmVkX3gybV9xdWV1ZSIpCiAgICAgICAgaWYgcXVldWUgaXMgTm9uZSBvciBub3QgaXNpbnN0YW5jZSh2YWx1ZSwgZGljdCk6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICBkZWZlcnJlZF9maWVsZHMgPSBzZWxmLl9nZXRfZGVmZXJyZWRfeDJtX2ltcG9ydF9maWVsZHMoKQogICAgICAgIHNwZWMgPSBkZWZlcnJlZF9maWVsZHMuZ2V0KGZpZWxkKSBvciB7fQogICAgICAgIGlmIHNwZWMuZ2V0KCJjaGlsZF9tb2RlbCIpICE9IGNvbW9kZWwuX25hbWU6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICBpZiBzcGVjLmdldCgic2tpcF9lbXB0eSIpIGFuZCBub3Qgc2VsZi5faGFzX21lYW5pbmdmdWxfeWFtbF92YWx1ZSh2YWx1ZSk6CiAgICAgICAgICAgIHJldHVybiBUcnVlCgogICAgICAgIGRlZmVycmVkX2ZpZWxkID0gc3BlYy5nZXQoImRlZmVycmVkX2ZpZWxkIikKICAgICAgICBpZiBub3QgZGVmZXJyZWRfZmllbGQ6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICB0YXJnZXRfbW9kZWwgPSBzcGVjLmdldCgidGFyZ2V0X21vZGVsIikKICAgICAgICB0YXJnZXRfdmFsdWUgPSB2YWx1ZS5nZXQoZGVmZXJyZWRfZmllbGQpCiAgICAgICAgdGFyZ2V0X3JlZmVyZW5jZSA9IHNlbGYuX2dldF9yZWZlcmVuY2Vfb25seV95YW1sX3JlbGF0aW9uX3JlZmVyZW5jZSgKICAgICAgICAgICAgdGFyZ2V0X3ZhbHVlCiAgICAgICAgKQogICAgICAgIGlmIG5vdCB0YXJnZXRfbW9kZWwgb3Igbm90IHRhcmdldF9yZWZlcmVuY2U6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICB0YXJnZXRfcmVjb3JkID0gc2VsZi5lbnZbdGFyZ2V0X21vZGVsXS5nZXRfYnlfcmVmZXJlbmNlKHRhcmdldF9yZWZlcmVuY2UpCiAgICAgICAgaWYgdGFyZ2V0X3JlY29yZDoKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgICAgIHJlY29yZF9yZWZlcmVuY2UgPSBzZWxmLl9jb250ZXh0LmdldCgieWFtbF9pbXBvcnRfcmVjb3JkX3JlZmVyZW5jZSIpCiAgICAgICAgaWYgbm90IHJlY29yZF9yZWZlcmVuY2U6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICBxdWV1ZS5hcHBlbmQoCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJyZWNvcmRfbW9kZWwiOiBzZWxmLl9uYW1lLAogICAgICAgICAgICAgICAgInJlY29yZF9yZWZlcmVuY2UiOiByZWNvcmRfcmVmZXJlbmNlLAogICAgICAgICAgICAgICAgImZpZWxkX25hbWUiOiBmaWVsZCwKICAgICAgICAgICAgICAgICJjaGlsZF9tb2RlbCI6IGNvbW9kZWwuX25hbWUsCiAgICAgICAgICAgICAgICAiZGVmZXJyZWRfZmllbGQiOiBkZWZlcnJlZF9maWVsZCwKICAgICAgICAgICAgICAgICJ0YXJnZXRfbW9kZWwiOiB0YXJnZXRfbW9kZWwsCiAgICAgICAgICAgICAgICAidGFyZ2V0X3JlZmVyZW5jZSI6IHRhcmdldF9yZWZlcmVuY2UsCiAgICAgICAgICAgICAgICAidmFsdWVzIjogY29weS5kZWVwY29weSh2YWx1ZSksCiAgICAgICAgICAgIH0KICAgICAgICApCiAgICAgICAgcmV0dXJuIFRydWUKCiAgICBkZWYgX2dldF95YW1sX2R1cGxpY2F0ZV9yZWZlcmVuY2VfZGljdChzZWxmLCByZWYsIHZhbHVlcyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHViIGVtaXR0ZWQgd2hlbiBhIHJlY29yZCBoYXMgYWxyZWFkeSBiZWVuIHNlcmlhbGl6ZWQuCgogICAgICAgIFRoZSBjb2xsZWN0b3IgZGVkdXBsaWNhdGVzIGJ5IChtb2RlbCwgcmVmZXJlbmNlKTsgc3Vic2VxdWVudCBvY2N1cnJlbmNlcwogICAgICAgIGFyZSBjb2xsYXBzZWQgdG8gYSByZWZlcmVuY2Utb25seSBkaWN0LiBJbXBvcnQgbXVzdCBuZXZlciBhdHRlbXB0IHRvIGNyZWF0ZQogICAgICAgIGZyb20gdGhpcyBzdHViIOKAlCBpdCBtdXN0IHJlc29sdmUgdGhlIHJlY29yZCBieSByZWZlcmVuY2UgaW5zdGVhZC4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgcmVmIChzdHIpOiBSZWNvcmQgcmVmZXJlbmNlLgogICAgICAgICAgICB2YWx1ZXMgKGRpY3QpOiBSYXcgdmFsdWVzICh1bnVzZWQ7IGtlcHQgZm9yIHNpZ25hdHVyZSBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpbiBjYXNlIHN1YmNsYXNzZXMgbmVlZCB0aGVtKS4KCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgZGljdDogYGB7InJlZmVyZW5jZSI6IHJlZn1gYCBvbmx5LgogICAgICAgICIiIgogICAgICAgIHJldHVybiB7InJlZmVyZW5jZSI6IHJlZn0KCiAgICBkZWYgX3Bvc3RfcHJvY2Vzc19yZWNvcmRfdmFsdWVzKHNlbGYsIHZhbHVlcyk6CiAgICAgICAgIiIiUG9zdCBwcm9jZXNzIHJlY29yZCB2YWx1ZXMKICAgICAgICAgICAgYmVmb3JlIGNvbnZlcnRpbmcgdGhlbSB0byBZQU1MCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHZhbHVlcyAoZGljdCk6IHZhbHVlcyByZXR1cm5lZCBieSAncmVhZCcgbWV0aG9kCgogICAgICAgIENvbnRleHQ6CiAgICAgICAgICAgIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQ6IGlmIHNldCB3aWxsIHJldHVybiBlbnRpcmUgcmVjb3JkIGRpY3Rpb25hcnkKICAgICAgICAgICAgICAgIG5vdCBqdXN0IGEgcmVmZXJlbmNlCiAgICAgICAgICAgIHJlbW92ZV9lbXB0eV92YWx1ZXM6IGlmIHNldCB3aWxsIHJlbW92ZSBlbXB0eSB2YWx1ZXMgZnJvbSB0aGUgcmVjb3JkCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogcHJvY2Vzc2VkIHZhbHVlcwogICAgICAgICIiIgogICAgICAgIGNvbGxlY3RvciA9IHNlbGYuX2NvbnRleHQuZ2V0KCJ5YW1sX2NvbGxlY3RvciIpCiAgICAgICAgcmVmID0gdmFsdWVzLmdldCgicmVmZXJlbmNlIikKICAgICAgICBjb2xsZWN0b3Jfa2V5ID0gKHNlbGYuX25hbWUsIHJlZikgaWYgcmVmIGVsc2UgTm9uZQoKICAgICAgICBpZiBjb2xsZWN0b3IgYW5kIGNvbGxlY3Rvcl9rZXkgYW5kIGNvbGxlY3Rvci5pc19hZGRlZChjb2xsZWN0b3Jfa2V5KToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2dldF95YW1sX2R1cGxpY2F0ZV9yZWZlcmVuY2VfZGljdChyZWYsIHZhbHVlcykKCiAgICAgICAgaWYgY29sbGVjdG9yIGFuZCBjb2xsZWN0b3Jfa2V5OgogICAgICAgICAgICBjb2xsZWN0b3IuYWRkKGNvbGxlY3Rvcl9rZXkpCgogICAgICAgICMgV2UgZG9uJ3QgbmVlZCBpZCBiZWNhdXNlIHdlIGFyZSBub3QgdXNpbmcgaXQKICAgICAgICB2YWx1ZXMucG9wKCJpZCIsIE5vbmUpCgogICAgICAgICMgQWRkIFlBTUwgZm9ybWF0IHZlcnNpb24gYW5kIG1vZGVsCiAgICAgICAgaWYgbm90IHNlbGYuX2NvbnRleHQuZ2V0KCJub195YW1sX3NlcnZpY2VfZmllbGRzIik6CiAgICAgICAgICAgIG1vZGVsX25hbWUgPSBzZWxmLl9uYW1lLnJlcGxhY2UoImN4LnRvd2VyLiIsICIiKS5yZXBsYWNlKCIuIiwgIl8iKQogICAgICAgICAgICBtb2RlbF92YWx1ZXMgPSB7CiAgICAgICAgICAgICAgICAiY2V0bWl4X3Rvd2VyX21vZGVsIjogbW9kZWxfbmFtZSwKICAgICAgICAgICAgfQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGVsX3ZhbHVlcyA9IHt9CgogICAgICAgICMgUGFyc2UgYWNjZXNzIGxldmVsCiAgICAgICAgYWNjZXNzX2xldmVsID0gdmFsdWVzLnBvcCgiYWNjZXNzX2xldmVsIiwgTm9uZSkKICAgICAgICBpZiBhY2Nlc3NfbGV2ZWw6CiAgICAgICAgICAgIG1vZGVsX3ZhbHVlcy51cGRhdGUoCiAgICAgICAgICAgICAgICB7ImFjY2Vzc19sZXZlbCI6IHNlbGYuVE9fWUFNTF9BQ0NFU1NfTEVWRUxbYWNjZXNzX2xldmVsXX0KICAgICAgICAgICAgKQoKICAgICAgICB2YWx1ZXMgPSB7Kiptb2RlbF92YWx1ZXMsICoqdmFsdWVzfQogICAgICAgICMgQ29weSB2YWx1ZXMgdG8gYXZvaWQgbW9kaWZ5aW5nIHRoZSBvcmlnaW5hbCB2YWx1ZXMKICAgICAgICBuZXdfdmFsdWVzID0gdmFsdWVzLmNvcHkoKQoKICAgICAgICAjIENoZWNrIGlmIHdlIG5lZWQgdG8gcmV0dXJuIGEgcmVjb3JkIGRpY3Qgb3IganVzdCBhIHJlZmVyZW5jZQogICAgICAgICMgVXNlIGNvbnRleHQgdmFsdWUgZmlyc3QsIHJldmVydCB0byB0aGUgcmVjb3JkIHNldHRpbmcgaWYgbm90IGRlZmluZWQKICAgICAgICBleHBsb2RlX3JlbGF0ZWRfcmVjb3JkID0gc2VsZi5fY29udGV4dC5nZXQoImV4cGxvZGVfcmVsYXRlZF9yZWNvcmQiKQoKICAgICAgICAjIENoZWNrIGlmIHdlIG5lZWQgdG8gcmVtb3ZlIGVtcHR5IHZhbHVlcwogICAgICAgICMgQ3VycmVudGx5IG9ubHkgeDJtIGZpZWxkcyBhcmUgc3VwcG9ydGVkCiAgICAgICAgcmVtb3ZlX2VtcHR5X3ZhbHVlcyA9IHNlbGYuX2NvbnRleHQuZ2V0KCJyZW1vdmVfZW1wdHlfdmFsdWVzIikKCiAgICAgICAgIyBQb3N0IHByb2Nlc3MgbTJvIGFuZCB4Mm0gZmllbGRzCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gdmFsdWVzLml0ZW1zKCk6CiAgICAgICAgICAgICMgSU1QT1JUQU5UOiBPZG9vIG5hbWluZyBwYXR0ZXJucyBtdXN0IGJlIGZvbGxvd2VkIGZvciByZWxhdGVkIGZpZWxkcy4KICAgICAgICAgICAgIyBUaGlzIGlzIHdoeSB3ZSBhcmUgY2hlY2tpbmcgZm9yIHRoZSBmaWVsZCBuYW1lIGVuZGluZyBoZXJlLgogICAgICAgICAgICAjIEZ1cnRoZXIgY2hlY2tzIGZvciB0aGUgZmllbGQgdHlwZSBhcmUgZG9uZQogICAgICAgICAgICAjICBpbiBfcHJvY2Vzc19yZWxhdGlvbl9maWVsZF92YWx1ZSgpCiAgICAgICAgICAgIGlmIGtleS5lbmRzd2l0aCgiX2lkIikgb3Iga2V5LmVuZHN3aXRoKCJfaWRzIik6CiAgICAgICAgICAgICAgICBpZiBub3QgdmFsdWUgYW5kIHJlbW92ZV9lbXB0eV92YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgZGVsIG5ld192YWx1ZXNba2V5XQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRfdmFsdWUgPSBzZWxmLndpdGhfY29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgZXhwbG9kZV9yZWxhdGVkX3JlY29yZD1leHBsb2RlX3JlbGF0ZWRfcmVjb3JkCiAgICAgICAgICAgICAgICAgICAgKS5fcHJvY2Vzc19yZWxhdGlvbl9maWVsZF92YWx1ZShrZXksIHZhbHVlLCByZWNvcmRfbW9kZT1UcnVlKQogICAgICAgICAgICAgICAgICAgIG5ld192YWx1ZXMudXBkYXRlKHtrZXk6IHByb2Nlc3NlZF92YWx1ZX0pCgogICAgICAgIHJldHVybiBuZXdfdmFsdWVzCgogICAgZGVmIF9wb3N0X3Byb2Nlc3NfeWFtbF9kaWN0X3ZhbHVlcyhzZWxmLCB2YWx1ZXMpOgogICAgICAgICIiIlBvc3QgcHJvY2VzcyBkaWN0aW9uYXJ5IHZhbHVlcyBnZW5lcmF0ZWQgZnJvbSBZQU1MIGNvZGUKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgdmFsdWVzIChkaWN0KTogRGljdGlvbmFyeSBnZW5lcmF0ZWQgZnJvbSBZQU1MCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKTogUG9zdC1wcm9jZXNzZWQgdmFsdWVzCiAgICAgICAgIiIiCgogICAgICAgICMgUmVtb3ZlIG1vZGVsIGRhdGEgYmVjYXVzZSBpdCBpcyBub3QgYSBmaWVsZAogICAgICAgIGlmICJjZXRtaXhfdG93ZXJfbW9kZWwiIGluIHZhbHVlczoKICAgICAgICAgICAgdmFsdWVzLnBvcCgiY2V0bWl4X3Rvd2VyX21vZGVsIikKCiAgICAgICAgIyBQYXJzZSBhY2Nlc3MgbGV2ZWwKICAgICAgICBpZiAiYWNjZXNzX2xldmVsIiBpbiB2YWx1ZXM6CiAgICAgICAgICAgIHZhbHVlc19hY2Nlc3NfbGV2ZWwgPSB2YWx1ZXNbImFjY2Vzc19sZXZlbCJdCiAgICAgICAgICAgIGFjY2Vzc19sZXZlbCA9IHNlbGYuVE9fVE9XRVJfQUNDRVNTX0xFVkVMLmdldCh2YWx1ZXNfYWNjZXNzX2xldmVsKQogICAgICAgICAgICBpZiBhY2Nlc3NfbGV2ZWw6CiAgICAgICAgICAgICAgICB2YWx1ZXMudXBkYXRlKHsiYWNjZXNzX2xldmVsIjogYWNjZXNzX2xldmVsfSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJhaXNlIFZhbGlkYXRpb25FcnJvcigKICAgICAgICAgICAgICAgICAgICBfKAogICAgICAgICAgICAgICAgICAgICAgICAiV3JvbmcgdmFsdWUgZm9yICdhY2Nlc3NfbGV2ZWwnIGtleTogJShhY3YpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGFjdj12YWx1ZXNfYWNjZXNzX2xldmVsLAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCiAgICAgICAgIyBMZWF2ZSBzdXBwb3J0ZWQga2V5cyBvbmx5CiAgICAgICAgc3VwcG9ydGVkX2tleXMgPSBzZWxmLl9nZXRfZmllbGRzX2Zvcl95YW1sKCkKICAgICAgICBmaWx0ZXJlZF92YWx1ZXMgPSB7azogdiBmb3IgaywgdiBpbiB2YWx1ZXMuaXRlbXMoKSBpZiBrIGluIHN1cHBvcnRlZF9rZXlzfQoKICAgICAgICAjIFBvc3QgcHJvY2VzcyBtMm8gZmllbGRzCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gbGlzdChmaWx0ZXJlZF92YWx1ZXMuaXRlbXMoKSk6CiAgICAgICAgICAgICMgSU1QT1JUQU5UOiBPZG9vIG5hbWluZyBwYXR0ZXJucyBtdXN0IGJlIGZvbGxvd2VkIGZvciByZWxhdGVkIGZpZWxkcy4KICAgICAgICAgICAgIyBUaGlzIGlzIHdoeSB3ZSBhcmUgY2hlY2tpbmcgZm9yIHRoZSBmaWVsZCBuYW1lIGVuZGluZyBoZXJlLgogICAgICAgICAgICAjIEZ1cnRoZXIgY2hlY2tzIGZvciB0aGUgZmllbGQgdHlwZSBhcmUgZG9uZQogICAgICAgICAgICAjIGluIF9wcm9jZXNzX3JlbGF0aW9uX2ZpZWxkX3ZhbHVlKCkKICAgICAgICAgICAgaWYga2V5LmVuZHN3aXRoKCJfaWQiKSBvciBrZXkuZW5kc3dpdGgoIl9pZHMiKToKICAgICAgICAgICAgICAgIHByb2Nlc3NlZF92YWx1ZSA9IHNlbGYud2l0aF9jb250ZXh0KAogICAgICAgICAgICAgICAgICAgIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQ9VHJ1ZSwKICAgICAgICAgICAgICAgICAgICB5YW1sX2ltcG9ydF9yZWNvcmRfcmVmZXJlbmNlPWZpbHRlcmVkX3ZhbHVlcy5nZXQoInJlZmVyZW5jZSIpLAogICAgICAgICAgICAgICAgKS5fcHJvY2Vzc19yZWxhdGlvbl9maWVsZF92YWx1ZShrZXksIHZhbHVlLCByZWNvcmRfbW9kZT1GYWxzZSkKICAgICAgICAgICAgICAgIGlmIHByb2Nlc3NlZF92YWx1ZSBpcyBERUZFUlJFRF9NMk9fSU1QT1JUOgogICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkX3ZhbHVlcy5wb3Aoa2V5LCBOb25lKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZF92YWx1ZXMudXBkYXRlKHtrZXk6IHByb2Nlc3NlZF92YWx1ZX0pCgogICAgICAgIHJldHVybiBmaWx0ZXJlZF92YWx1ZXMKCiAgICBkZWYgX3Byb2Nlc3NfcmVsYXRpb25fZmllbGRfdmFsdWUoc2VsZiwgZmllbGQsIHZhbHVlLCByZWNvcmRfbW9kZT1GYWxzZSk6CiAgICAgICAgIiIiUG9zdCBwcm9jZXNzIE9uZTJtYW55LCBNYW55Mm1hbnkgb3IgTWFueTJvbmUgdmFsdWUKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgZmllbGQgKENoYXIpOiBGaWVsZCB0aGUgdmFsdWUgYmVsb25ncyB0bwogICAgICAgICAgICB2YWx1ZSAoQ2hhcik6IFZhbHVlIHRvIHByb2Nlc3MKICAgICAgICAgICAgcmVjb3JkX21vZGUgKEJvb2wpOiBJZiBUcnVlIHByb2Nlc3MgdmFsdWUgYXMgYSByZWNvcmQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHByb2Nlc3MgdmFsdWUgYXMgYSBZQU1MIHZhbHVlCiAgICAgICAgICAgIENvbnRleHQ6CiAgICAgICAgICAgICAgICBleHBsb2RlX3JlbGF0ZWRfcmVjb3JkOiBpZiBzZXQgd2lsbCByZXR1cm4gZW50aXJlIHJlY29yZCBkaWN0aW9uYXJ5CiAgICAgICAgICAgICAgICAgICAgbm90IGp1c3QgYSByZWZlcmVuY2UKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICBkaWN0KCkgb3IgQ2hhcjogcmVjb3JkIGRpY3Rpb25hcnkgaWYgZmV0Y2hfcmVjb3JkIGVsc2UgcmVmZXJlbmNlCiAgICAgICAgIiIiCiAgICAgICAgIyBTdGVwIDE6IFJldHVybiBGYWxzZSBpZiB0aGUgdmFsdWUgaXMgbm90IHNldCBvciB0aGUgZmllbGQgaXMgbm90IGZvdW5kCiAgICAgICAgaWYgbm90IHZhbHVlOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICAgICAgZmllbGRfb2JqID0gc2VsZi5fZmllbGRzLmdldChmaWVsZCkKICAgICAgICBpZiBub3QgZmllbGRfb2JqOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICAgICAgIyBTdGVwIDI6IFJldHVybiBGYWxzZSBpZiB0aGUgZmllbGQgdHlwZSBkb2Vzbid0IG1hdGNoCiAgICAgICAgIyBvciBjb21vZGVsIGlzIG5vdCBkZWZpbmVkCiAgICAgICAgZmllbGRfdHlwZSA9IGZpZWxkX29iai50eXBlCiAgICAgICAgaWYgKAogICAgICAgICAgICBmaWVsZF90eXBlIG5vdCBpbiBbIm9uZTJtYW55IiwgIm1hbnkybWFueSIsICJtYW55Mm9uZSJdCiAgICAgICAgICAgIG9yIG5vdCBmaWVsZF9vYmouY29tb2RlbF9uYW1lCiAgICAgICAgKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCgogICAgICAgIGNvbW9kZWwgPSBzZWxmLmVudltmaWVsZF9vYmouY29tb2RlbF9uYW1lXQogICAgICAgIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQgPSBzZWxmLl9jb250ZXh0LmdldCgiZXhwbG9kZV9yZWxhdGVkX3JlY29yZCIpCgogICAgICAgICMgU3RlcCAzOiBwcm9jZXNzIHZhbHVlIGJhc2VkIG9uIHRoZSBmaWVsZCB0eXBlCiAgICAgICAgaWYgZmllbGRfdHlwZSA9PSAibWFueTJvbmUiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fcHJvY2Vzc19tMm9fdmFsdWUoCiAgICAgICAgICAgICAgICBmaWVsZCwgY29tb2RlbCwgdmFsdWUsIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQsIHJlY29yZF9tb2RlCiAgICAgICAgICAgICkKICAgICAgICBpZiBmaWVsZF90eXBlIGluIFsib25lMm1hbnkiLCAibWFueTJtYW55Il06CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jZXNzX3gybV92YWx1ZXMoCiAgICAgICAgICAgICAgICBmaWVsZCwgY29tb2RlbCwgZmllbGRfdHlwZSwgdmFsdWUsIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQsIHJlY29yZF9tb2RlCiAgICAgICAgICAgICkKCiAgICAgICAgIyBTdGVwIDQ6IGZhbGwgYmFjayBpZiBmaWVsZCB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgX3Byb2Nlc3NfbTJvX3ZhbHVlKAogICAgICAgIHNlbGYsIGZpZWxkLCBjb21vZGVsLCB2YWx1ZSwgZXhwbG9kZV9yZWxhdGVkX3JlY29yZCwgcmVjb3JkX21vZGU9RmFsc2UKICAgICk6CiAgICAgICAgIiIiUG9zdCBwcm9jZXNzIG1hbnkyb25lIHZhbHVlCiAgICAgICAgQXJnczoKICAgICAgICAgICAgZmllbGQgKENoYXIpOiBGaWVsZCB0aGUgdmFsdWUgYmVsb25ncyB0bwogICAgICAgICAgICBjb21vZGVsIChCYXNlQ2xhc3MpOiBNb2RlbCB0aGUgdmFsdWUgYmVsb25ncyB0bwogICAgICAgICAgICB2YWx1ZSAoQ2hhcik6IFZhbHVlIHRvIHByb2Nlc3MKICAgICAgICAgICAgZXhwbG9kZV9yZWxhdGVkX3JlY29yZCAoQm9vbCk6IElmIFRydWUgcmV0dXJuIGVudGlyZSByZWNvcmQgZGljdAogICAgICAgICAgICAgICAgaW5zdGVhZCBvZiBhIHJlZmVyZW5jZQogICAgICAgICAgICByZWNvcmRfbW9kZSAoQm9vbCk6IElmIFRydWUgcHJvY2VzcyB2YWx1ZSBhcyBhIHJlY29yZCB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgcHJvY2VzcyB2YWx1ZSBhcyBhIFlBTUwgdmFsdWUKCiAgICAgICAgUmV0dXJuczoKICAgICAgICAgICAgZGljdCgpIG9yIENoYXI6IHJlY29yZCBkaWN0aW9uYXJ5IGlmIGZldGNoX3JlY29yZCBlbHNlIHJlZmVyZW5jZQogICAgICAgICIiIgoKICAgICAgICAjIC0tIChSZWNvcmQgLT4gWUFNTCkKICAgICAgICBpZiByZWNvcmRfbW9kZToKICAgICAgICAgICAgIyBSZXRyaWV2ZSB0aGUgcmVjb3JkIGJhc2VkIG9uIHRoZSBJRCBwcm92aWRlZCBpbiB0aGUgdmFsdWUKICAgICAgICAgICAgcmVjb3JkID0gY29tb2RlbC5icm93c2UodmFsdWVbMF0pCgogICAgICAgICAgICAjIElmIHRoZSBjb250ZXh0IHNwZWNpZmllcyB0byBleHBsb2RlIHRoZSByZWxhdGVkIHJlY29yZCwKICAgICAgICAgICAgIyByZXR1cm4gaXRzIGRpY3Rpb25hcnkgcmVwcmVzZW50YXRpb24KICAgICAgICAgICAgaWYgZXhwbG9kZV9yZWxhdGVkX3JlY29yZDoKICAgICAgICAgICAgICAgIHJldHVybiAoCiAgICAgICAgICAgICAgICAgICAgcmVjb3JkLndpdGhfY29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgbm9feWFtbF9zZXJ2aWNlX2ZpZWxkcz1UcnVlCiAgICAgICAgICAgICAgICAgICAgKS5fcHJlcGFyZV9yZWNvcmRfZm9yX3lhbWwoKQogICAgICAgICAgICAgICAgICAgIGlmIHJlY29yZAogICAgICAgICAgICAgICAgICAgIGVsc2UgRmFsc2UKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgT3RoZXJ3aXNlLCByZXR1cm4ganVzdCB0aGUgcmVmZXJlbmNlIChvciBGYWxzZSBpZiByZWNvcmQgZG9lcyBub3QgZXhpc3QpCiAgICAgICAgICAgIHJldHVybiByZWNvcmQucmVmZXJlbmNlIGlmIHJlY29yZCBlbHNlIEZhbHNlCgogICAgICAgICMgLS0gKFlBTUwgLT4gUmVjb3JkKQogICAgICAgICMgU3RlcCAxOiBQcm9jZXNzIHZhbHVlIGluIG5vcm1hbCBtb2RlCiAgICAgICAgcmVjb3JkID0gRmFsc2UKICAgICAgICBpZiBzZWxmLl9xdWV1ZV9kZWZlcnJlZF9tMm9faW1wb3J0KGZpZWxkLCBjb21vZGVsLCB2YWx1ZSk6CiAgICAgICAgICAgIHJldHVybiBERUZFUlJFRF9NMk9fSU1QT1JUCgogICAgICAgICMgSWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nLCBpdCBpcyB0cmVhdGVkIGFzIGEgcmVmZXJlbmNlCiAgICAgICAgaWYgaXNpbnN0YW5jZSh2YWx1ZSwgc3RyKToKICAgICAgICAgICAgcmVmZXJlbmNlID0gdmFsdWUKCiAgICAgICAgIyBJZiB0aGUgdmFsdWUgaXMgYSBkaWN0aW9uYXJ5LCBleHRyYWN0IHRoZSByZWZlcmVuY2UgZnJvbSBpdAogICAgICAgIGVsaWYgaXNpbnN0YW5jZSh2YWx1ZSwgZGljdCk6CiAgICAgICAgICAgIHJlZmVyZW5jZSA9IHZhbHVlLmdldCgicmVmZXJlbmNlIikKICAgICAgICAgICAgaWYgc2VsZi5fZ2V0X3JlZmVyZW5jZV9vbmx5X3lhbWxfcmVsYXRpb25fcmVmZXJlbmNlKHZhbHVlKToKICAgICAgICAgICAgICAgIHJlY29yZCA9IEZhbHNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZWNvcmQgPSBzZWxmLl91cGRhdGVfb3JfY3JlYXRlX3JlbGF0ZWRfcmVjb3JkKAogICAgICAgICAgICAgICAgICAgIGNvbW9kZWwsIHJlZmVyZW5jZSwgdmFsdWUsIGNyZWF0ZV9pbW1lZGlhdGVseT1UcnVlCiAgICAgICAgICAgICAgICApCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICAjIFN0ZXAgMjogRmluYWwgZmFsbGJhY2s6IGF0dGVtcHQgdG8gcmV0cmlldmUgdGhlIHJlY29yZCBieSByZWZlcmVuY2UgaWYgc2V0LAogICAgICAgICMgIHJldHVybiBpdHMgSUQgb3IgRmFsc2UKICAgICAgICBpZiBub3QgcmVjb3JkIGFuZCByZWZlcmVuY2U6CiAgICAgICAgICAgIHJlY29yZCA9IGNvbW9kZWwuZ2V0X2J5X3JlZmVyZW5jZShyZWZlcmVuY2UpCiAgICAgICAgcmV0dXJuIHJlY29yZC5pZCBpZiByZWNvcmQgZWxzZSBGYWxzZQoKICAgIGRlZiBfcHJvY2Vzc194Mm1fdmFsdWVzKAogICAgICAgIHNlbGYsCiAgICAgICAgZmllbGQsCiAgICAgICAgY29tb2RlbCwKICAgICAgICBmaWVsZF90eXBlLAogICAgICAgIHZhbHVlcywKICAgICAgICBleHBsb2RlX3JlbGF0ZWRfcmVjb3JkLAogICAgICAgIHJlY29yZF9tb2RlPUZhbHNlLAogICAgKToKICAgICAgICAiIiJQb3N0IHByb2Nlc3MgbWFueTJtYW55IHZhbHVlCiAgICAgICAgQXJnczoKICAgICAgICAgICAgZmllbGQgKENoYXIpOiBGaWVsZCB0aGUgdmFsdWUgYmVsb25ncyB0bwogICAgICAgICAgICBjb21vZGVsIChCYXNlQ2xhc3MpOiBNb2RlbCB0aGUgdmFsdWUgYmVsb25ncyB0bwogICAgICAgICAgICBmaWVsZF90eXBlIChDaGFyKTogRmllbGQgdHlwZQogICAgICAgICAgICB2YWx1ZXMgKGxpc3QoKSk6IFZhbHVlcyB0byBwcm9jZXNzCiAgICAgICAgICAgIGV4cGxvZGVfcmVsYXRlZF9yZWNvcmQgKEJvb2wpOiBJZiBUcnVlIHJldHVybiBlbnRpcmUgcmVjb3JkIGRpY3QKICAgICAgICAgICAgICAgIGluc3RlYWQgb2YgYSByZWZlcmVuY2UKICAgICAgICAgICAgcmVjb3JkX21vZGUgKEJvb2wpOiBJZiBUcnVlIHByb2Nlc3MgdmFsdWUgYXMgYSByZWNvcmQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHByb2Nlc3MgdmFsdWUgYXMgYSBZQU1MIHZhbHVlCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIGRpY3QoKSBvciBDaGFyOiByZWNvcmQgZGljdGlvbmFyeSBpZiBmZXRjaF9yZWNvcmQgZWxzZSByZWZlcmVuY2UKICAgICAgICAiIiIKCiAgICAgICAgIyAtLSAoUmVjb3JkIC0+IFlBTUwpCiAgICAgICAgaWYgcmVjb3JkX21vZGU6CiAgICAgICAgICAgIHJlY29yZF9saXN0ID0gW10KICAgICAgICAgICAgZm9yIHZhbHVlIGluIHZhbHVlczoKICAgICAgICAgICAgICAgICMgUmV0cmlldmUgdGhlIHJlY29yZCBiYXNlZCBvbiB0aGUgSUQgcHJvdmlkZWQgaW4gdGhlIHZhbHVlCiAgICAgICAgICAgICAgICByZWNvcmQgPSBjb21vZGVsLmJyb3dzZSh2YWx1ZSkKCiAgICAgICAgICAgICAgICAjIElmIHRoZSBjb250ZXh0IHNwZWNpZmllcyB0byBleHBsb2RlIHRoZSByZWxhdGVkIHJlY29yZCwKICAgICAgICAgICAgICAgICMgcmV0dXJuIGl0cyBkaWN0aW9uYXJ5IHJlcHJlc2VudGF0aW9uCiAgICAgICAgICAgICAgICBpZiBleHBsb2RlX3JlbGF0ZWRfcmVjb3JkOgogICAgICAgICAgICAgICAgICAgIHJlY29yZF9saXN0LmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgcmVjb3JkLndpdGhfY29udGV4dCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vX3lhbWxfc2VydmljZV9maWVsZHM9VHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICApLl9wcmVwYXJlX3JlY29yZF9mb3JfeWFtbCgpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlY29yZAogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIEZhbHNlCiAgICAgICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgICAgICMgT3RoZXJ3aXNlLCByZXR1cm4ganVzdCB0aGUgcmVmZXJlbmNlCiAgICAgICAgICAgICAgICAjIChvciBGYWxzZSBpZiByZWNvcmQgZG9lcyBub3QgZXhpc3QpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlY29yZF9saXN0LmFwcGVuZChyZWNvcmQucmVmZXJlbmNlIGlmIHJlY29yZCBlbHNlIEZhbHNlKQoKICAgICAgICAgICAgcmV0dXJuIHJlY29yZF9saXN0CgogICAgICAgICMgLS0gKFlBTUwgLT4gUmVjb3JkKQogICAgICAgICMgU3RlcCAxOiBQcm9jZXNzIHZhbHVlIGluIG5vcm1hbCBtb2RlCiAgICAgICAgcmVjb3JkX2lkcyA9IFtdCgogICAgICAgIGZvciB2YWx1ZSBpbiB2YWx1ZXM6CiAgICAgICAgICAgIHJlY29yZCA9IEZhbHNlCiAgICAgICAgICAgICMgSWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nLCBpdCBpcyB0cmVhdGVkIGFzIGEgcmVmZXJlbmNlCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UodmFsdWUsIHN0cik6CiAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSB2YWx1ZQoKICAgICAgICAgICAgIyBJZiB0aGUgdmFsdWUgaXMgYSBkaWN0aW9uYXJ5LCBleHRyYWN0IHRoZSByZWZlcmVuY2UgZnJvbSBpdAogICAgICAgICAgICBlbGlmIGlzaW5zdGFuY2UodmFsdWUsIGRpY3QpOgogICAgICAgICAgICAgICAgaWYgc2VsZi5fcXVldWVfZGVmZXJyZWRfeDJtX2ltcG9ydChmaWVsZCwgY29tb2RlbCwgdmFsdWUpOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICByZWZlcmVuY2UgPSB2YWx1ZS5nZXQoInJlZmVyZW5jZSIpCiAgICAgICAgICAgICAgICByZWNvcmQgPSBzZWxmLl91cGRhdGVfb3JfY3JlYXRlX3JlbGF0ZWRfcmVjb3JkKAogICAgICAgICAgICAgICAgICAgIGNvbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlLAogICAgICAgICAgICAgICAgICAgIHZhbHVlLAogICAgICAgICAgICAgICAgICAgIGNyZWF0ZV9pbW1lZGlhdGVseT1maWVsZF90eXBlID09ICJtYW55Mm1hbnkiLAogICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgIyBTdGVwIDI6IEZpbmFsIGZhbGxiYWNrOiBhdHRlbXB0IHRvIHJldHJpZXZlIHRoZSByZWNvcmQgYnkgcmVmZXJlbmNlCiAgICAgICAgICAgICMgUmV0dXJuIHJlY29yZCBJRCBvciBGYWxzZSBpZiByZWZlcmVuY2UgaXMgbm90IGRlZmluZWQKICAgICAgICAgICAgaWYgbm90IHJlY29yZCBhbmQgcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgcmVjb3JkID0gY29tb2RlbC5nZXRfYnlfcmVmZXJlbmNlKHJlZmVyZW5jZSkKCiAgICAgICAgICAgICMgU2F2ZSByZWNvcmQgZGF0YQogICAgICAgICAgICBpZiByZWNvcmQ6CiAgICAgICAgICAgICAgICByZWNvcmRfaWRzLmFwcGVuZCgKICAgICAgICAgICAgICAgICAgICByZWNvcmQgaWYgaXNpbnN0YW5jZShyZWNvcmQsIHR1cGxlKSBlbHNlICg0LCByZWNvcmQuaWQpCiAgICAgICAgICAgICAgICApCgogICAgICAgIHJldHVybiByZWNvcmRfaWRzCgogICAgZGVmIF91cGRhdGVfb3JfY3JlYXRlX3JlbGF0ZWRfcmVjb3JkKAogICAgICAgIHNlbGYsIG1vZGVsLCByZWZlcmVuY2UsIHZhbHVlcywgY3JlYXRlX2ltbWVkaWF0ZWx5PUZhbHNlCiAgICApOgogICAgICAgICIiIlVwZGF0ZSByZWxhdGVkIHJlY29yZCB3aXRoIHByb3ZpZGVkIHZhbHVlcyBvciBjcmVhdGUgYSBuZXcgb25lCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIG1vZGVsIChCYXNlTW9kZWwpOiBSZWxhdGVkIHJlY29yZCBtb2RlbAogICAgICAgICAgICB2YWx1ZXMgKGRpY3QoKSk6IFZhbHVlcyB0byB1cGRhdGUgZXhpc3RpbmcvY3JlYXRlIG5ldyByZWNvcmQKICAgICAgICAgICAgcmVmZXJlbmNlIChDaGFyKTogUmVjb3JkIHJlZmVyZW5jZQogICAgICAgICAgICBjcmVhdGVfaW1tZWRpYXRlbHkgKEJvb2wpOiBJZiBUcnVlIGNyZWF0ZSBhIG5ldyByZWNvcmQgaW1tZWRpYXRlbHkuCiAgICAgICAgICAgICAgICBVc2VkIGZvciBNYW55Mm9uZSBmaWVsZHMuCgogICAgICAgIENvbnRleHQ6CiAgICAgICAgICAgIGZvcmNlX2NyZWF0ZV9yZWxhdGVkX3JlY29yZCAoQm9vbCk6IElmIFRydWUsIGNyZWF0ZSBhIG5ldyByZWNvcmQKICAgICAgICAgICAgICAgIGV2ZW4gaWYgcmVmZXJlbmNlIGlzIHByb3ZpZGVkLgoKICAgICAgICBSZXR1cm5zOgogICAgICAgICAgICByZWNvcmQ6IEV4aXN0aW5nIHJlY29yZCBvciBuZXcgcmVjb3JkIHR1cGxlCiAgICAgICAgIiIiCgogICAgICAgICMgSWYgcmVmZXJlbmNlIGlzIGZvdW5kLCByZXRyaWV2ZSB0aGUgY29ycmVzcG9uZGluZyByZWNvcmQKICAgICAgICBpZiByZWZlcmVuY2UgYW5kICgKICAgICAgICAgICAgbW9kZWwuX25hbWUgaW4gc2VsZi5fZ2V0X2ZvcmNlX3gybV9yZXNvbHZlX21vZGVscygpCiAgICAgICAgICAgIG9yIG5vdCBzZWxmLl9jb250ZXh0LmdldCgiZm9yY2VfY3JlYXRlX3JlbGF0ZWRfcmVjb3JkIikKICAgICAgICApOgogICAgICAgICAgICByZWNvcmQgPSBtb2RlbC5nZXRfYnlfcmVmZXJlbmNlKHJlZmVyZW5jZSkKICAgICAgICAgICAgIyBJZiB0aGUgcmVjb3JkIGV4aXN0cywgdXBkYXRlIGl0IHdpdGggdGhlIHZhbHVlcyBmcm9tIHRoZSBkaWN0aW9uYXJ5CiAgICAgICAgICAgIGlmIHJlY29yZDoKICAgICAgICAgICAgICAgICMgUmVtb3ZlIHJlZmVyZW5jZSBmcm9tIHZhbHVlcyB0byBhdm9pZCBwb3NzaWJsZSBjb25zZXF1ZW5jZXMKICAgICAgICAgICAgICAgIHZhbHVlcy5wb3AoInJlZmVyZW5jZSIsIE5vbmUpCiAgICAgICAgICAgICAgICByZWNvcmQud2l0aF9jb250ZXh0KGZyb21feWFtbD1UcnVlKS53cml0ZSgKICAgICAgICAgICAgICAgICAgICByZWNvcmQuX3Bvc3RfcHJvY2Vzc195YW1sX2RpY3RfdmFsdWVzKHZhbHVlcykKICAgICAgICAgICAgICAgICkKCiAgICAgICAgICAgICMgSWYgdGhlIHJlY29yZCBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGEgbmV3IG9uZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgc2V0KHZhbHVlcy5rZXlzKCkpID09IHsicmVmZXJlbmNlIn06CiAgICAgICAgICAgICAgICAgICAgX2xvZ2dlci53YXJuaW5nKAogICAgICAgICAgICAgICAgICAgICAgICAiQXR0ZW1wdGVkIHRvIGltcG9ydCBhIHJlY29yZCBmb3IgbW9kZWwgJyVzJyAiCiAgICAgICAgICAgICAgICAgICAgICAgICJ3aXRoIHJlZmVyZW5jZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICInJXMnLCBidXQgb25seSB0aGUgJ3JlZmVyZW5jZScgZmllbGQgd2FzIHByb3ZpZGVkLiAiCiAgICAgICAgICAgICAgICAgICAgICAgICJDcmVhdGlvbiB3aWxsIGJlIHNraXBwZWQgdW50aWwgdGhlIHRhcmdldCByZWNvcmQgIgogICAgICAgICAgICAgICAgICAgICAgICAiZXhpc3RzLiIsCiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsLl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2UsCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgICAgICAgICAgaWYgY3JlYXRlX2ltbWVkaWF0ZWx5OgogICAgICAgICAgICAgICAgICAgIHJlY29yZCA9IG1vZGVsLndpdGhfY29udGV4dChmcm9tX3lhbWw9VHJ1ZSkuY3JlYXRlKAogICAgICAgICAgICAgICAgICAgICAgICBtb2RlbC5fcG9zdF9wcm9jZXNzX3lhbWxfZGljdF92YWx1ZXModmFsdWVzKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgIyBVc2UgIkNyZWF0ZSIgc2VydmljZSBjb21tYW5kIHR1cGxlCiAgICAgICAgICAgICAgICAgICAgcmVjb3JkID0gKDAsIDAsIG1vZGVsLl9wb3N0X3Byb2Nlc3NfeWFtbF9kaWN0X3ZhbHVlcyh2YWx1ZXMpKQoKICAgICAgICAjIElmIHRoZXJlJ3Mgbm8gcmVmZXJlbmNlIGJ1dCB2YWx1ZSBpcyBhIGRpY3QsIGNyZWF0ZSBhIG5ldyByZWNvcmQKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIE9ubHkgJ3JlZmVyZW5jZScgcHJvdmlkZWQsIG5vIG90aGVyIGRhdGE6IGRvIG5vdCBjcmVhdGUsCiAgICAgICAgICAgICMganVzdCBsb2cgd2FybmluZwogICAgICAgICAgICBpZiBzZXQodmFsdWVzLmtleXMoKSkgPT0geyJyZWZlcmVuY2UifToKICAgICAgICAgICAgICAgIF9sb2dnZXIud2FybmluZygKICAgICAgICAgICAgICAgICAgICAiQXR0ZW1wdGVkIHRvIGltcG9ydCBhIHJlY29yZCBmb3IgbW9kZWwgJyVzJyB3aXRoIHJlZmVyZW5jZSAiCiAgICAgICAgICAgICAgICAgICAgIiclcycsIGJ1dCBvbmx5IHRoZSAncmVmZXJlbmNlJyBmaWVsZCB3YXMgcHJvdmlkZWQuICIKICAgICAgICAgICAgICAgICAgICAiSXQgaXMgcG9zc2libGUgdGhhdCB0aGlzIHJlY29yZCBoYXMgYWxyZWFkeSBiZWVuIGltcG9ydGVkLiAiCiAgICAgICAgICAgICAgICAgICAgIkNyZWF0aW9uIHdpbGwgYmUgc2tpcHBlZC4iLAogICAgICAgICAgICAgICAgICAgIG1vZGVsLl9uYW1lLAogICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICAgICAgaWYgY3JlYXRlX2ltbWVkaWF0ZWx5OgogICAgICAgICAgICAgICAgcmVjb3JkID0gbW9kZWwud2l0aF9jb250ZXh0KGZyb21feWFtbD1UcnVlKS5jcmVhdGUoCiAgICAgICAgICAgICAgICAgICAgbW9kZWwuX3Bvc3RfcHJvY2Vzc195YW1sX2RpY3RfdmFsdWVzKHZhbHVlcykKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVXNlICJDcmVhdGUiIHNlcnZpY2UgY29tbWFuZCB0dXBsZQogICAgICAgICAgICAgICAgcmVjb3JkID0gKDAsIDAsIG1vZGVsLl9wb3N0X3Byb2Nlc3NfeWFtbF9kaWN0X3ZhbHVlcyh2YWx1ZXMpKQoKICAgICAgICAjIFJldHVybiB0aGUgcmVjb3JkJ3MgSUQgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgcmV0dXJuIEZhbHNlCiAgICAgICAgcmV0dXJuIHJlY29yZCBvciBGYWxzZQo= |