IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uOiA4NTIxMyAkIgojICRTb3VyY2UkCgp2ZXJzaW9uICAgICA9ICIwLjkuMCIKX19hdXRob3JfXyAgPSAiTGFycyBHdXN05GJlbCAobGFyc0BndXN0YWViZWwuZGUpIgpfX2RhdGVfXyAgICA9ICIkRGF0ZSQiCl9fY3ZzaWRfXyAgID0gIiRJZCQiCl9fY3JlZGl0c19fID0gIkd1c3Rhdm8gTmllbWV5ZXIsIE5pZWxzIEd1c3TkYmVsLCBSaWNoYXJkIFRvd25zZW5kLiIKCiMtLS0tLS0tLS0KIyBJbXBvcnRzCiMtLS0tLS0tLS0KaW1wb3J0IHN5cwppbXBvcnQgb3MKaW1wb3J0IHNodXRpbAppbXBvcnQgc3RhdAppbXBvcnQgZXJybm8KaW1wb3J0IHRpbWUKaW1wb3J0IHN0cnVjdAppbXBvcnQgY29weQppbXBvcnQgcmUKaW1wb3J0IG9wZXJhdG9yCgp0cnk6CiAgICBpbXBvcnQgZ3JwLCBwd2QKZXhjZXB0IEltcG9ydEVycm9yOgogICAgZ3JwID0gcHdkID0gTm9uZQoKIyBmcm9tIHRhcmZpbGUgaW1wb3J0ICoKX19hbGxfXyA9IFsiVGFyRmlsZSIsICJUYXJJbmZvIiwgImlzX3RhcmZpbGUiLCAiVGFyRXJyb3IiXQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhciBjb25zdGFudHMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpOVUwgPSAiXDAiICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG51bGwgY2hhcmFjdGVyCkJMT0NLU0laRSA9IDUxMiAgICAgICAgICAgICAgICAgIyBsZW5ndGggb2YgcHJvY2Vzc2luZyBibG9ja3MKUkVDT1JEU0laRSA9IEJMT0NLU0laRSAqIDIwICAgICAjIGxlbmd0aCBvZiByZWNvcmRzCkdOVV9NQUdJQyA9ICJ1c3RhciAgXDAiICAgICAgICAgIyBtYWdpYyBnbnUgdGFyIHN0cmluZwpQT1NJWF9NQUdJQyA9ICJ1c3Rhclx4MDAwMCIgICAgICMgbWFnaWMgcG9zaXggdGFyIHN0cmluZwoKTEVOR1RIX05BTUUgPSAxMDAgICAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIGEgZmlsZW5hbWUKTEVOR1RIX0xJTksgPSAxMDAgICAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIGEgbGlua25hbWUKTEVOR1RIX1BSRUZJWCA9IDE1NSAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBwcmVmaXggZmllbGQKClJFR1RZUEUgPSAiMCIgICAgICAgICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUKQVJFR1RZUEUgPSAiXDAiICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpMTktUWVBFID0gIjEiICAgICAgICAgICAgICAgICAgICMgbGluayAoaW5zaWRlIHRhcmZpbGUpClNZTVRZUEUgPSAiMiIgICAgICAgICAgICAgICAgICAgIyBzeW1ib2xpYyBsaW5rCkNIUlRZUEUgPSAiMyIgICAgICAgICAgICAgICAgICAgIyBjaGFyYWN0ZXIgc3BlY2lhbCBkZXZpY2UKQkxLVFlQRSA9ICI0IiAgICAgICAgICAgICAgICAgICAjIGJsb2NrIHNwZWNpYWwgZGV2aWNlCkRJUlRZUEUgPSAiNSIgICAgICAgICAgICAgICAgICAgIyBkaXJlY3RvcnkKRklGT1RZUEUgPSAiNiIgICAgICAgICAgICAgICAgICAjIGZpZm8gc3BlY2lhbCBkZXZpY2UKQ09OVFRZUEUgPSAiNyIgICAgICAgICAgICAgICAgICAjIGNvbnRpZ3VvdXMgZmlsZQoKR05VVFlQRV9MT05HTkFNRSA9ICJMIiAgICAgICAgICAjIEdOVSB0YXIgbG9uZ25hbWUKR05VVFlQRV9MT05HTElOSyA9ICJLIiAgICAgICAgICAjIEdOVSB0YXIgbG9uZ2xpbmsKR05VVFlQRV9TUEFSU0UgPSAiUyIgICAgICAgICAgICAjIEdOVSB0YXIgc3BhcnNlIGZpbGUKClhIRFRZUEUgPSAieCIgICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgZXh0ZW5kZWQgaGVhZGVyClhHTFRZUEUgPSAiZyIgICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgZ2xvYmFsIGhlYWRlcgpTT0xBUklTX1hIRFRZUEUgPSAiWCIgICAgICAgICAgICMgU29sYXJpcyBleHRlbmRlZCBoZWFkZXIKClVTVEFSX0ZPUk1BVCA9IDAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTE5ODggKHVzdGFyKSBmb3JtYXQKR05VX0ZPUk1BVCA9IDEgICAgICAgICAgICAgICAgICAjIEdOVSB0YXIgZm9ybWF0ClBBWF9GT1JNQVQgPSAyICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgKHBheCkgZm9ybWF0CkRFRkFVTFRfRk9STUFUID0gR05VX0ZPUk1BVAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhcmZpbGUgY29uc3RhbnRzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBGaWxlIHR5cGVzIHRoYXQgdGFyZmlsZSBzdXBwb3J0czoKU1VQUE9SVEVEX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCBMTktUWVBFLAogICAgICAgICAgICAgICAgICAgU1lNVFlQRSwgRElSVFlQRSwgRklGT1RZUEUsCiAgICAgICAgICAgICAgICAgICBDT05UVFlQRSwgQ0hSVFlQRSwgQkxLVFlQRSwKICAgICAgICAgICAgICAgICAgIEdOVVRZUEVfTE9OR05BTUUsIEdOVVRZUEVfTE9OR0xJTkssCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkKCiMgRmlsZSB0eXBlcyB0aGF0IHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KUkVHVUxBUl9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwKICAgICAgICAgICAgICAgICBDT05UVFlQRSwgR05VVFlQRV9TUEFSU0UpCgojIEZpbGUgdHlwZXMgdGhhdCBhcmUgcGFydCBvZiB0aGUgR05VIHRhciBmb3JtYXQuCkdOVV9UWVBFUyA9IChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgojIEZpZWxkcyBmcm9tIGEgcGF4IGhlYWRlciB0aGF0IG92ZXJyaWRlIGEgVGFySW5mbyBhdHRyaWJ1dGUuClBBWF9GSUVMRFMgPSAoInBhdGgiLCAibGlua3BhdGgiLCAic2l6ZSIsICJtdGltZSIsCiAgICAgICAgICAgICAgInVpZCIsICJnaWQiLCAidW5hbWUiLCAiZ25hbWUiKQoKIyBGaWVsZHMgaW4gYSBwYXggaGVhZGVyIHRoYXQgYXJlIG51bWJlcnMsIGFsbCBvdGhlciBmaWVsZHMKIyBhcmUgdHJlYXRlZCBhcyBzdHJpbmdzLgpQQVhfTlVNQkVSX0ZJRUxEUyA9IHsKICAgICJhdGltZSI6IGZsb2F0LAogICAgImN0aW1lIjogZmxvYXQsCiAgICAibXRpbWUiOiBmbG9hdCwKICAgICJ1aWQiOiBpbnQsCiAgICAiZ2lkIjogaW50LAogICAgInNpemUiOiBpbnQKfQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEJpdHMgdXNlZCBpbiB0aGUgbW9kZSBmaWVsZCwgdmFsdWVzIGluIG9jdGFsLgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNfSUZMTksgPSAwMTIwMDAwICAgICAgICAjIHN5bWJvbGljIGxpbmsKU19JRlJFRyA9IDAxMDAwMDAgICAgICAgICMgcmVndWxhciBmaWxlClNfSUZCTEsgPSAwMDYwMDAwICAgICAgICAjIGJsb2NrIGRldmljZQpTX0lGRElSID0gMDA0MDAwMCAgICAgICAgIyBkaXJlY3RvcnkKU19JRkNIUiA9IDAwMjAwMDAgICAgICAgICMgY2hhcmFjdGVyIGRldmljZQpTX0lGSUZPID0gMDAxMDAwMCAgICAgICAgIyBmaWZvCgpUU1VJRCAgID0gMDQwMDAgICAgICAgICAgIyBzZXQgVUlEIG9uIGV4ZWN1dGlvbgpUU0dJRCAgID0gMDIwMDAgICAgICAgICAgIyBzZXQgR0lEIG9uIGV4ZWN1dGlvbgpUU1ZUWCAgID0gMDEwMDAgICAgICAgICAgIyByZXNlcnZlZAoKVFVSRUFEICA9IDA0MDAgICAgICAgICAgICMgcmVhZCBieSBvd25lcgpUVVdSSVRFID0gMDIwMCAgICAgICAgICAgIyB3cml0ZSBieSBvd25lcgpUVUVYRUMgID0gMDEwMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvd25lcgpUR1JFQUQgID0gMDA0MCAgICAgICAgICAgIyByZWFkIGJ5IGdyb3VwClRHV1JJVEUgPSAwMDIwICAgICAgICAgICAjIHdyaXRlIGJ5IGdyb3VwClRHRVhFQyAgPSAwMDEwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IGdyb3VwClRPUkVBRCAgPSAwMDA0ICAgICAgICAgICAjIHJlYWQgYnkgb3RoZXIKVE9XUklURSA9IDAwMDIgICAgICAgICAgICMgd3JpdGUgYnkgb3RoZXIKVE9FWEVDICA9IDAwMDEgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3RoZXIKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBpbml0aWFsaXphdGlvbgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkVOQ09ESU5HID0gc3lzLmdldGZpbGVzeXN0ZW1lbmNvZGluZygpCmlmIEVOQ09ESU5HIGlzIE5vbmU6CiAgICBFTkNPRElORyA9IHN5cy5nZXRkZWZhdWx0ZW5jb2RpbmcoKQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNvbWUgdXNlZnVsIGZ1bmN0aW9ucwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgc3RuKHMsIGxlbmd0aCk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIHN0cmluZyB0byBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgYnVmZmVyLgogICAgIiIiCiAgICByZXR1cm4gc1s6bGVuZ3RoXSArIChsZW5ndGggLSBsZW4ocykpICogTlVMCgpkZWYgbnRzKHMpOgogICAgIiIiQ29udmVydCBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgZmllbGQgdG8gYSBweXRob24gc3RyaW5nLgogICAgIiIiCiAgICAjIFVzZSB0aGUgc3RyaW5nIHVwIHRvIHRoZSBmaXJzdCBudWxsIGNoYXIuCiAgICBwID0gcy5maW5kKCJcMCIpCiAgICBpZiBwID09IC0xOgogICAgICAgIHJldHVybiBzCiAgICByZXR1cm4gc1s6cF0KCmRlZiBudGkocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4KICAgICIiIgogICAgIyBUaGVyZSBhcmUgdHdvIHBvc3NpYmxlIGVuY29kaW5ncyBmb3IgYSBudW1iZXIgZmllbGQsIHNlZQogICAgIyBpdG4oKSBiZWxvdy4KICAgIGlmIHNbMF0gIT0gY2hyKDAyMDApOgogICAgICAgIHRyeToKICAgICAgICAgICAgbiA9IGludChudHMocykgb3IgIjAiLCA4KQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICByYWlzZSBJbnZhbGlkSGVhZGVyRXJyb3IoImludmFsaWQgaGVhZGVyIikKICAgIGVsc2U6CiAgICAgICAgbiA9IDBMCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGxlbihzKSAtIDEpOgogICAgICAgICAgICBuIDw8PSA4CiAgICAgICAgICAgIG4gKz0gb3JkKHNbaSArIDFdKQogICAgcmV0dXJuIG4KCmRlZiBpdG4obiwgZGlnaXRzPTgsIGZvcm1hdD1ERUZBVUxUX0ZPUk1BVCk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIG51bWJlciB0byBhIG51bWJlciBmaWVsZC4KICAgICIiIgogICAgIyBQT1NJWCAxMDAzLjEtMTk4OCByZXF1aXJlcyBudW1iZXJzIHRvIGJlIGVuY29kZWQgYXMgYSBzdHJpbmcgb2YKICAgICMgb2N0YWwgZGlnaXRzIGZvbGxvd2VkIGJ5IGEgbnVsbC1ieXRlLCB0aGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8KICAgICMgKDgqKihkaWdpdHMtMSkpLTEuIEdOVSB0YXIgYWxsb3dzIHN0b3JpbmcgbnVtYmVycyBncmVhdGVyIHRoYW4KICAgICMgdGhhdCBpZiBuZWNlc3NhcnkuIEEgbGVhZGluZyAwMjAwIGJ5dGUgaW5kaWNhdGVzIHRoaXMgcGFydGljdWxhcgogICAgIyBlbmNvZGluZywgdGhlIGZvbGxvd2luZyBkaWdpdHMtMSBieXRlcyBhcmUgYSBiaWctZW5kaWFuCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4KICAgIGlmIDAgPD0gbiA8IDggKiogKGRpZ2l0cyAtIDEpOgogICAgICAgIHMgPSAiJTAqbyIgJSAoZGlnaXRzIC0gMSwgbikgKyBOVUwKICAgIGVsc2U6CiAgICAgICAgaWYgZm9ybWF0ICE9IEdOVV9GT1JNQVQgb3IgbiA+PSAyNTYgKiogKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJvdmVyZmxvdyBpbiBudW1iZXIgZmllbGQiKQoKICAgICAgICBpZiBuIDwgMDoKICAgICAgICAgICAgIyBYWFggV2UgbWltaWMgR05VIHRhcidzIGJlaGF2aW91ciB3aXRoIG5lZ2F0aXZlIG51bWJlcnMsCiAgICAgICAgICAgICMgdGhpcyBjb3VsZCByYWlzZSBPdmVyZmxvd0Vycm9yLgogICAgICAgICAgICBuID0gc3RydWN0LnVucGFjaygiTCIsIHN0cnVjdC5wYWNrKCJsIiwgbikpWzBdCgogICAgICAgIHMgPSAiIgogICAgICAgIGZvciBpIGluIHhyYW5nZShkaWdpdHMgLSAxKToKICAgICAgICAgICAgcyA9IGNocihuICYgMDM3NykgKyBzCiAgICAgICAgICAgIG4gPj49IDgKICAgICAgICBzID0gY2hyKDAyMDApICsgcwogICAgcmV0dXJuIHMKCmRlZiB1dHMocywgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAiIiJDb252ZXJ0IGEgdW5pY29kZSBvYmplY3QgdG8gYSBzdHJpbmcuCiAgICAiIiIKICAgIGlmIGVycm9ycyA9PSAidXRmLTgiOgogICAgICAgICMgQW4gZXh0cmEgZXJyb3IgaGFuZGxlciBzaW1pbGFyIHRvIHRoZSAtbyBpbnZhbGlkPVVURi04IG9wdGlvbgogICAgICAgICMgaW4gUE9TSVguMS0yMDAxLiBSZXBsYWNlIHVudHJhbnNsYXRhYmxlIGNoYXJhY3RlcnMgd2l0aCB0aGVpcgogICAgICAgICMgVVRGLTggcmVwcmVzZW50YXRpb24uCiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gcy5lbmNvZGUoZW5jb2RpbmcsICJzdHJpY3QiKQogICAgICAgIGV4Y2VwdCBVbmljb2RlRW5jb2RlRXJyb3I6CiAgICAgICAgICAgIHggPSBbXQogICAgICAgICAgICBmb3IgYyBpbiBzOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHguYXBwZW5kKGMuZW5jb2RlKGVuY29kaW5nLCAic3RyaWN0IikpCiAgICAgICAgICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHguYXBwZW5kKGMuZW5jb2RlKCJ1dGY4IikpCiAgICAgICAgICAgIHJldHVybiAiIi5qb2luKHgpCiAgICBlbHNlOgogICAgICAgIHJldHVybiBzLmVuY29kZShlbmNvZGluZywgZXJyb3JzKQoKZGVmIGNhbGNfY2hrc3VtcyhidWYpOgogICAgIiIiQ2FsY3VsYXRlIHRoZSBjaGVja3N1bSBmb3IgYSBtZW1iZXIncyBoZWFkZXIgYnkgc3VtbWluZyB1cCBhbGwKICAgICAgIGNoYXJhY3RlcnMgZXhjZXB0IGZvciB0aGUgY2hrc3VtIGZpZWxkIHdoaWNoIGlzIHRyZWF0ZWQgYXMgaWYKICAgICAgIGl0IHdhcyBmaWxsZWQgd2l0aCBzcGFjZXMuIEFjY29yZGluZyB0byB0aGUgR05VIHRhciBzb3VyY2VzLAogICAgICAgc29tZSB0YXJzIChTdW4gYW5kIE5lWFQpIGNhbGN1bGF0ZSBjaGtzdW0gd2l0aCBzaWduZWQgY2hhciwKICAgICAgIHdoaWNoIHdpbGwgYmUgZGlmZmVyZW50IGlmIHRoZXJlIGFyZSBjaGFycyBpbiB0aGUgYnVmZmVyIHdpdGgKICAgICAgIHRoZSBoaWdoIGJpdCBzZXQuIFNvIHdlIGNhbGN1bGF0ZSB0d28gY2hlY2tzdW1zLCB1bnNpZ25lZCBhbmQKICAgICAgIHNpZ25lZC4KICAgICIiIgogICAgdW5zaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OEIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2QiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICBzaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OGIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2YiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICByZXR1cm4gdW5zaWduZWRfY2hrc3VtLCBzaWduZWRfY2hrc3VtCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRhYmxlIHRhciBhcmNoaXZlcy4iIiIKICAgIHBhc3MKY2xhc3MgQ29tcHJlc3Npb25FcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVuYXZhaWxhYmxlIGNvbXByZXNzaW9uIG1ldGhvZHMuIiIiCiAgICBwYXNzCmNsYXNzIFN0cmVhbUVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5zdXBwb3J0ZWQgb3BlcmF0aW9ucyBvbiBzdHJlYW0tbGlrZSBUYXJGaWxlcy4iIiIKICAgIHBhc3MKY2xhc3MgSGVhZGVyRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiQmFzZSBleGNlcHRpb24gZm9yIGhlYWRlciBlcnJvcnMuIiIiCiAgICBwYXNzCmNsYXNzIEVtcHR5SGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciBlbXB0eSBoZWFkZXJzLiIiIgogICAgcGFzcwpjbGFzcyBUcnVuY2F0ZWRIZWFkZXJFcnJvcihIZWFkZXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHRydW5jYXRlZCBoZWFkZXJzLiIiIgogICAgcGFzcwpjbGFzcyBFT0ZIZWFkZXJFcnJvcihIZWFkZXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIGVuZCBvZiBmaWxlIGhlYWRlcnMuIiIiCiAgICBwYXNzCmNsYXNzIEludmFsaWRIZWFkZXJFcnJvcihIZWFkZXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIGludmFsaWQgaGVhZGVycy4iIiIKICAgIHBhc3MKY2xhc3MgU3Vic2VxdWVudEhlYWRlckVycm9yKEhlYWRlckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgbWlzc2luZyBhbmQgaW52YWxpZCBleHRlbmRlZCBoZWFkZXJzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUsIDA2NjYpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpICYgMHhmZmZmZmZmZkwKICAgICAgICAgICAgaWYgbW9kZSA9PSAiciI6CiAgICAgICAgICAgICAgICBzZWxmLl9pbml0X3JlYWRfZ3ooKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF93cml0ZV9neigpCgogICAgICAgIGlmIGNvbXB0eXBlID09ICJiejIiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5kYnVmID0gIiIKICAgICAgICAgICAgICAgIHNlbGYuY21wID0gYnoyLkJaMkRlY29tcHJlc3NvcigpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJDb21wcmVzc29yKCkKCiAgICBkZWYgX19kZWxfXyhzZWxmKToKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsICJjbG9zZWQiKSBhbmQgbm90IHNlbGYuY2xvc2VkOgogICAgICAgICAgICBzZWxmLmNsb3NlKCkKCiAgICBkZWYgX2luaXRfd3JpdGVfZ3ooc2VsZik6CiAgICAgICAgIiIiSW5pdGlhbGl6ZSBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24uCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuY29tcHJlc3NvYmooOSwgc2VsZi56bGliLkRFRkxBVEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1zZWxmLnpsaWIuTUFYX1dCSVRTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuemxpYi5ERUZfTUVNX0xFVkVMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApCiAgICAgICAgdGltZXN0YW1wID0gc3RydWN0LnBhY2soIjxMIiwgbG9uZyh0aW1lLnRpbWUoKSkpCiAgICAgICAgc2VsZi5fX3dyaXRlKCJcMDM3XDIxM1wwMTBcMDEwJXNcMDAyXDM3NyIgJSB0aW1lc3RhbXApCiAgICAgICAgaWYgdHlwZShzZWxmLm5hbWUpIGlzIHVuaWNvZGU6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZS5lbmNvZGUoImlzby04ODU5LTEiLCAicmVwbGFjZSIpCiAgICAgICAgaWYgc2VsZi5uYW1lLmVuZHN3aXRoKCIuZ3oiKToKICAgICAgICAgICAgc2VsZi5uYW1lID0gc2VsZi5uYW1lWzotM10KICAgICAgICBzZWxmLl9fd3JpdGUoc2VsZi5uYW1lICsgTlVMKQoKICAgIGRlZiB3cml0ZShzZWxmLCBzKToKICAgICAgICAiIiJXcml0ZSBzdHJpbmcgcyB0byB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgc2VsZi5jcmMgPSBzZWxmLnpsaWIuY3JjMzIocywgc2VsZi5jcmMpICYgMHhmZmZmZmZmZkwKICAgICAgICBzZWxmLnBvcyArPSBsZW4ocykKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlICE9ICJ0YXIiOgogICAgICAgICAgICBzID0gc2VsZi5jbXAuY29tcHJlc3MocykKICAgICAgICBzZWxmLl9fd3JpdGUocykKCiAgICBkZWYgX193cml0ZShzZWxmLCBzKToKICAgICAgICAiIiJXcml0ZSBzdHJpbmcgcyB0byB0aGUgc3RyZWFtIGlmIGEgd2hvbGUgbmV3IGJsb2NrCiAgICAgICAgICAgaXMgcmVhZHkgdG8gYmUgd3JpdHRlbi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmJ1ZiArPSBzCiAgICAgICAgd2hpbGUgbGVuKHNlbGYuYnVmKSA+IHNlbGYuYnVmc2l6ZToKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmWzpzZWxmLmJ1ZnNpemVdKQogICAgICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NlbGYuYnVmc2l6ZTpdCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBfU3RyZWFtIG9iamVjdC4gTm8gb3BlcmF0aW9uIHNob3VsZCBiZQogICAgICAgICAgIGRvbmUgb24gaXQgYWZ0ZXJ3YXJkcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyIgYW5kIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHNlbGYuYnVmICs9IHNlbGYuY21wLmZsdXNoKCkKCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5idWY6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzZWxmLmJ1ZikKICAgICAgICAgICAgc2VsZi5idWYgPSAiIgogICAgICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgICAgICAjIFRoZSBuYXRpdmUgemxpYiBjcmMgaXMgYW4gdW5zaWduZWQgMzItYml0IGludGVnZXIsIGJ1dAogICAgICAgICAgICAgICAgIyB0aGUgUHl0aG9uIHdyYXBwZXIgaW1wbGljaXRseSBjYXN0cyB0aGF0IHRvIGEgc2lnbmVkIEMKICAgICAgICAgICAgICAgICMgbG9uZy4gIFNvLCBvbiBhIDMyLWJpdCBib3ggc2VsZi5jcmMgbWF5ICJsb29rIG5lZ2F0aXZlIiwKICAgICAgICAgICAgICAgICMgd2hpbGUgdGhlIHNhbWUgY3JjIG9uIGEgNjQtYml0IGJveCBtYXkgImxvb2sgcG9zaXRpdmUiLgogICAgICAgICAgICAgICAgIyBUbyBhdm9pZCBpcmtzb21lIHdhcm5pbmdzIGZyb20gdGhlIGBzdHJ1Y3RgIG1vZHVsZSwgZm9yY2UKICAgICAgICAgICAgICAgICMgaXQgdG8gbG9vayBwb3NpdGl2ZSBvbiBhbGwgYm94ZXMuCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5jcmMgJiAweGZmZmZmZmZmTCkpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5wb3MgJiAweGZmZmZGRkZGTCkpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQoKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX2luaXRfcmVhZF9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciByZWFkaW5nIGEgZ3ppcCBjb21wcmVzc2VkIGZpbGVvYmouCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuZGVjb21wcmVzc29iaigtc2VsZi56bGliLk1BWF9XQklUUykKICAgICAgICBzZWxmLmRidWYgPSAiIgoKICAgICAgICAjIHRha2VuIGZyb20gZ3ppcC5HemlwRmlsZSB3aXRoIHNvbWUgYWx0ZXJhdGlvbnMKICAgICAgICBpZiBzZWxmLl9fcmVhZCgyKSAhPSAiXDAzN1wyMTMiOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMSkgIT0gIlwwMTAiOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QiKQoKICAgICAgICBmbGFnID0gb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgIHNlbGYuX19yZWFkKDYpCgogICAgICAgIGlmIGZsYWcgJiA0OgogICAgICAgICAgICB4bGVuID0gb3JkKHNlbGYuX19yZWFkKDEpKSArIDI1NiAqIG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICAgICAgc2VsZi5yZWFkKHhsZW4pCiAgICAgICAgaWYgZmxhZyAmIDg6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDE2OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAyOgogICAgICAgICAgICBzZWxmLl9fcmVhZCgyKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcz0wKToKICAgICAgICAiIiJTZXQgdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciB0byBwb3MuIE5lZ2F0aXZlIHNlZWtpbmcKICAgICAgICAgICBpcyBmb3JiaWRkZW4uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcG9zIC0gc2VsZi5wb3MgPj0gMDoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QocG9zIC0gc2VsZi5wb3MsIHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgICAgICAgICBzZWxmLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBzZWxmLnJlYWQocmVtYWluZGVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJzZWVraW5nIGJhY2t3YXJkcyBpcyBub3QgYWxsb3dlZCIpCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgc2l6ZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICAgIElmIHNpemUgaXMgbm90IGRlZmluZWQsIHJldHVybiBhbGwgYnl0ZXMgb2YgdGhlIHN0cmVhbQogICAgICAgICAgIHVwIHRvIEVPRi4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHQgPSBbXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGJ1ZiA9ICIiLmpvaW4odCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNpemUpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIF9yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJ0YXIiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoc2l6ZSkKCiAgICAgICAgYyA9IGxlbihzZWxmLmRidWYpCiAgICAgICAgdCA9IFtzZWxmLmRidWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX19yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuY21wLmRlY29tcHJlc3MoYnVmKQogICAgICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigiaW52YWxpZCBjb21wcmVzc2VkIGRhdGEiKQogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuZGJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAogICAgICAgICAgIHJlYWQgYW5vdGhlciBibG9jayBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB0ID0gW3NlbGYuYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KIyBjbGFzcyBfU3RyZWFtCgpjbGFzcyBfU3RyZWFtUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgZGV0ZWN0aW9uIGZvciB0aGUgU3RyZWFtIGludGVyZmFjZSAobW9kZSAncnwqJykuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaik6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYuYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHNlbGYucmVhZCA9IHNlbGYuZmlsZW9iai5yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuYnVmCgogICAgZGVmIGdldGNvbXB0eXBlKHNlbGYpOgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIlwwMzdcMjEzXDAxMCIpOgogICAgICAgICAgICByZXR1cm4gImd6IgogICAgICAgIGlmIHNlbGYuYnVmWzA6M10gPT0gIkJaaCIgYW5kIHNlbGYuYnVmWzQ6MTBdID09ICIxQVkmU1kiOgogICAgICAgICAgICByZXR1cm4gImJ6MiIKICAgICAgICByZXR1cm4gInRhciIKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKIyBjbGFzcyBTdHJlYW1Qcm94eQoKY2xhc3MgX0JaMlByb3h5KG9iamVjdCk6CiAgICAiIiJTbWFsbCBwcm94eSBjbGFzcyB0aGF0IGVuYWJsZXMgZXh0ZXJuYWwgZmlsZSBvYmplY3QKICAgICAgIHN1cHBvcnQgZm9yICJyOmJ6MiIgYW5kICJ3OmJ6MiIgbW9kZXMuIFRoaXMgaXMgYWN0dWFsbHkKICAgICAgIGEgd29ya2Fyb3VuZCBmb3IgYSBsaW1pdGF0aW9uIGluIGJ6MiBtb2R1bGUncyBCWjJGaWxlCiAgICAgICBjbGFzcyB3aGljaCAodW5saWtlIGd6aXAuR3ppcEZpbGUpIGhhcyBubyBzdXBwb3J0IGZvcgogICAgICAgYSBmaWxlIG9iamVjdCBhcmd1bWVudC4KICAgICIiIgoKICAgIGJsb2Nrc2l6ZSA9IDE2ICogMTAyNAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqLCBtb2RlKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5tb2RlID0gbW9kZQogICAgICAgIHNlbGYubmFtZSA9IGdldGF0dHIoc2VsZi5maWxlb2JqLCAibmFtZSIsIE5vbmUpCiAgICAgICAgc2VsZi5pbml0KCkKCiAgICBkZWYgaW5pdChzZWxmKToKICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgc2VsZi5wb3MgPSAwCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgc2VsZi5idWYgPSAiIgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkNvbXByZXNzb3IoKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIGIgPSBbc2VsZi5idWZdCiAgICAgICAgeCA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB3aGlsZSB4IDwgc2l6ZToKICAgICAgICAgICAgcmF3ID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgIGlmIG5vdCByYXc6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBkYXRhID0gc2VsZi5iejJvYmouZGVjb21wcmVzcyhyYXcpCiAgICAgICAgICAgIGIuYXBwZW5kKGRhdGEpCiAgICAgICAgICAgIHggKz0gbGVuKGRhdGEpCiAgICAgICAgc2VsZi5idWYgPSAiIi5qb2luKGIpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmWzpzaXplXQogICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2l6ZTpdCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zKToKICAgICAgICBpZiBwb3MgPCBzZWxmLnBvczoKICAgICAgICAgICAgc2VsZi5pbml0KCkKICAgICAgICBzZWxmLnJlYWQocG9zIC0gc2VsZi5wb3MpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHdyaXRlKHNlbGYsIGRhdGEpOgogICAgICAgIHNlbGYucG9zICs9IGxlbihkYXRhKQogICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmNvbXByZXNzKGRhdGEpCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IjoKICAgICAgICAgICAgcmF3ID0gc2VsZi5iejJvYmouZmx1c2goKQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUocmF3KQojIGNsYXNzIF9CWjJQcm94eQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfRmlsZUluRmlsZShvYmplY3QpOgogICAgIiIiQSB0aGluIHdyYXBwZXIgYXJvdW5kIGFuIGV4aXN0aW5nIGZpbGUgb2JqZWN0IHRoYXQKICAgICAgIHByb3ZpZGVzIGEgcGFydCBvZiBpdHMgZGF0YSBhcyBhbiBpbmRpdmlkdWFsIGZpbGUKICAgICAgIG9iamVjdC4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqLCBvZmZzZXQsIHNpemUsIHNwYXJzZT1Ob25lKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICAgICAgc2VsZi5zcGFyc2UgPSBzcGFyc2UKICAgICAgICBzZWxmLnBvc2l0aW9uID0gMAoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvc2l0aW9uCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zaXRpb24pOgogICAgICAgICIiIlNlZWsgdG8gYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnBvc2l0aW9uID0gcG9zaXRpb24KCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgZGF0YSBmcm9tIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgc2l6ZSA9IHNlbGYuc2l6ZSAtIHNlbGYucG9zaXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICBzaXplID0gbWluKHNpemUsIHNlbGYuc2l6ZSAtIHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIHNlbGYuc3BhcnNlIGlzIE5vbmU6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnJlYWRub3JtYWwoc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkc3BhcnNlKHNpemUpCgogICAgZGVmIHJlYWRub3JtYWwoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHJlZ3VsYXIgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyBzZWxmLnBvc2l0aW9uKQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQoKICAgIGRlZiByZWFkc3BhcnNlKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciBzcGFyc2UgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgZGF0YSA9IFtdCiAgICAgICAgd2hpbGUgc2l6ZSA+IDA6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYucmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQogICAgICAgIHJldHVybiAiIi5qb2luKGRhdGEpCgogICAgZGVmIHJlYWRzcGFyc2VzZWN0aW9uKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJlYWQgYSBzaW5nbGUgc2VjdGlvbiBvZiBhIHNwYXJzZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlY3Rpb24gPSBzZWxmLnNwYXJzZS5maW5kKHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIHNlY3Rpb24gaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuICIiCgogICAgICAgIHNpemUgPSBtaW4oc2l6ZSwgc2VjdGlvbi5vZmZzZXQgKyBzZWN0aW9uLnNpemUgLSBzZWxmLnBvc2l0aW9uKQoKICAgICAgICBpZiBpc2luc3RhbmNlKHNlY3Rpb24sIF9kYXRhKToKICAgICAgICAgICAgcmVhbHBvcyA9IHNlY3Rpb24ucmVhbHBvcyArIHNlbGYucG9zaXRpb24gLSBzZWN0aW9uLm9mZnNldAogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpCiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uICs9IHNpemUKICAgICAgICAgICAgcmV0dXJuIE5VTCAqIHNpemUKI2NsYXNzIF9GaWxlSW5GaWxlCgoKY2xhc3MgRXhGaWxlT2JqZWN0KG9iamVjdCk6CiAgICAiIiJGaWxlLWxpa2Ugb2JqZWN0IGZvciByZWFkaW5nIGFuIGFyY2hpdmUgbWVtYmVyLgogICAgICAgSXMgcmV0dXJuZWQgYnkgVGFyRmlsZS5leHRyYWN0ZmlsZSgpLgogICAgIiIiCiAgICBibG9ja3NpemUgPSAxMDI0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRhcmZpbGUsIHRhcmluZm8pOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IF9GaWxlSW5GaWxlKHRhcmZpbGUuZmlsZW9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRhdHRyKHRhcmluZm8sICJzcGFyc2UiLCBOb25lKSkKICAgICAgICBzZWxmLm5hbWUgPSB0YXJpbmZvLm5hbWUKICAgICAgICBzZWxmLm1vZGUgPSAiciIKICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5zaXplID0gdGFyaW5mby5zaXplCgogICAgICAgIHNlbGYucG9zaXRpb24gPSAwCiAgICAgICAgc2VsZi5idWZmZXIgPSAiIgoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBhdCBtb3N0IHNpemUgYnl0ZXMgZnJvbSB0aGUgZmlsZS4gSWYgc2l6ZSBpcyBub3QKICAgICAgICAgICBwcmVzZW50IG9yIE5vbmUsIHJlYWQgYWxsIGRhdGEgdW50aWwgRU9GIGlzIHJlYWNoZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBidWYgPSAiIgogICAgICAgIGlmIHNlbGYuYnVmZmVyOgogICAgICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcgogICAgICAgICAgICAgICAgc2VsZi5idWZmZXIgPSAiIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5idWZmZXJbOnNpemVdCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9IHNlbGYuYnVmZmVyW3NpemU6XQoKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLmZpbGVvYmoucmVhZCgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmICs9IHNlbGYuZmlsZW9iai5yZWFkKHNpemUgLSBsZW4oYnVmKSkKCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgcmVhZGxpbmUoc2VsZiwgc2l6ZT0tMSk6CiAgICAgICAgIiIiUmVhZCBvbmUgZW50aXJlIGxpbmUgZnJvbSB0aGUgZmlsZS4gSWYgc2l6ZSBpcyBwcmVzZW50CiAgICAgICAgICAgYW5kIG5vbi1uZWdhdGl2ZSwgcmV0dXJuIGEgc3RyaW5nIHdpdGggYXQgbW9zdCB0aGF0CiAgICAgICAgICAgc2l6ZSwgd2hpY2ggbWF5IGJlIGFuIGluY29tcGxldGUgbGluZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGlmICJcbiIgaW4gc2VsZi5idWZmZXI6CiAgICAgICAgICAgIHBvcyA9IHNlbGYuYnVmZmVyLmZpbmQoIlxuIikgKyAxCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmZmVycyA9IFtzZWxmLmJ1ZmZlcl0KICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYmxvY2tzaXplKQogICAgICAgICAgICAgICAgYnVmZmVycy5hcHBlbmQoYnVmKQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZiBvciAiXG4iIGluIGJ1ZjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiLmpvaW4oYnVmZmVycykKICAgICAgICAgICAgICAgICAgICBwb3MgPSBzZWxmLmJ1ZmZlci5maW5kKCJcbiIpICsgMQogICAgICAgICAgICAgICAgICAgIGlmIHBvcyA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICAjIG5vIG5ld2xpbmUgZm91bmQuCiAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IGxlbihzZWxmLmJ1ZmZlcikKICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICBpZiBzaXplICE9IC0xOgogICAgICAgICAgICBwb3MgPSBtaW4oc2l6ZSwgcG9zKQoKICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6cG9zXQogICAgICAgIHNlbGYuYnVmZmVyID0gc2VsZi5idWZmZXJbcG9zOl0KICAgICAgICBzZWxmLnBvc2l0aW9uICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiByZWFkbGluZXMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGEgbGlzdCB3aXRoIGFsbCByZW1haW5pbmcgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gW10KICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgY3VycmVudCBmaWxlIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgcmV0dXJuIHNlbGYucG9zaXRpb24KCiAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT1vcy5TRUVLX1NFVCk6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgaWYgd2hlbmNlID09IG9zLlNFRUtfU0VUOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWluKG1heChwb3MsIDApLCBzZWxmLnNpemUpCiAgICAgICAgZWxpZiB3aGVuY2UgPT0gb3MuU0VFS19DVVI6CiAgICAgICAgICAgIGlmIHBvcyA8IDA6CiAgICAgICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KHNlbGYucG9zaXRpb24gKyBwb3MsIDApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWluKHNlbGYucG9zaXRpb24gKyBwb3MsIHNlbGYuc2l6ZSkKICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0VORDoKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiA9IG1heChtaW4oc2VsZi5zaXplICsgcG9zLCBzZWxmLnNpemUpLCAwKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkludmFsaWQgYXJndW1lbnQiKQoKICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5wb3NpdGlvbikKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJHZXQgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZmlsZSdzIGxpbmVzLgogICAgICAgICIiIgogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICAgICAgaWYgbm90IGxpbmU6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB5aWVsZCBsaW5lCiNjbGFzcyBFeEZpbGVPYmplY3QKCiMtLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHBvcnRlZCBDbGFzc2VzCiMtLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgVGFySW5mbyhvYmplY3QpOgogICAgIiIiSW5mb3JtYXRpb25hbCBjbGFzcyB3aGljaCBob2xkcyB0aGUgZGV0YWlscyBhYm91dCBhbgogICAgICAgYXJjaGl2ZSBtZW1iZXIgZ2l2ZW4gYnkgYSB0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgVGFySW5mbyBvYmplY3RzIGFyZSByZXR1cm5lZCBieSBUYXJGaWxlLmdldG1lbWJlcigpLAogICAgICAgVGFyRmlsZS5nZXRtZW1iZXJzKCkgYW5kIFRhckZpbGUuZ2V0dGFyaW5mbygpIGFuZCBhcmUKICAgICAgIHVzdWFsbHkgY3JlYXRlZCBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9IiIpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0LiBuYW1lIGlzIHRoZSBvcHRpb25hbCBuYW1lCiAgICAgICAgICAgb2YgdGhlIG1lbWJlci4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lICAgICAgICAjIG1lbWJlciBuYW1lCiAgICAgICAgc2VsZi5tb2RlID0gMDY0NCAgICAgICAgIyBmaWxlIHBlcm1pc3Npb25zCiAgICAgICAgc2VsZi51aWQgPSAwICAgICAgICAgICAgIyB1c2VyIGlkCiAgICAgICAgc2VsZi5naWQgPSAwICAgICAgICAgICAgIyBncm91cCBpZAogICAgICAgIHNlbGYuc2l6ZSA9IDAgICAgICAgICAgICMgZmlsZSBzaXplCiAgICAgICAgc2VsZi5tdGltZSA9IDAgICAgICAgICAgIyBtb2RpZmljYXRpb24gdGltZQogICAgICAgIHNlbGYuY2hrc3VtID0gMCAgICAgICAgICMgaGVhZGVyIGNoZWNrc3VtCiAgICAgICAgc2VsZi50eXBlID0gUkVHVFlQRSAgICAgIyBtZW1iZXIgdHlwZQogICAgICAgIHNlbGYubGlua25hbWUgPSAiIiAgICAgICMgbGluayBuYW1lCiAgICAgICAgc2VsZi51bmFtZSA9ICIiICAgICAgICAgIyB1c2VyIG5hbWUKICAgICAgICBzZWxmLmduYW1lID0gIiIgICAgICAgICAjIGdyb3VwIG5hbWUKICAgICAgICBzZWxmLmRldm1ham9yID0gMCAgICAgICAjIGRldmljZSBtYWpvciBudW1iZXIKICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAjIGRldmljZSBtaW5vciBudW1iZXIKCiAgICAgICAgc2VsZi5vZmZzZXQgPSAwICAgICAgICAgIyB0aGUgdGFyIGhlYWRlciBzdGFydHMgaGVyZQogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSAwICAgICMgdGhlIGZpbGUncyBkYXRhIHN0YXJ0cyBoZXJlCgogICAgICAgIHNlbGYucGF4X2hlYWRlcnMgPSB7fSAgICMgcGF4IGhlYWRlciBpbmZvcm1hdGlvbgoKICAgICMgSW4gcGF4IGhlYWRlcnMgdGhlICJuYW1lIiBhbmQgImxpbmtuYW1lIiBmaWVsZCBhcmUgY2FsbGVkCiAgICAjICJwYXRoIiBhbmQgImxpbmtwYXRoIi4KICAgIGRlZiBfZ2V0cGF0aChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5uYW1lCiAgICBkZWYgX3NldHBhdGgoc2VsZiwgbmFtZSk6CiAgICAgICAgc2VsZi5uYW1lID0gbmFtZQogICAgcGF0aCA9IHByb3BlcnR5KF9nZXRwYXRoLCBfc2V0cGF0aCkKCiAgICBkZWYgX2dldGxpbmtwYXRoKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmxpbmtuYW1lCiAgICBkZWYgX3NldGxpbmtwYXRoKHNlbGYsIGxpbmtuYW1lKToKICAgICAgICBzZWxmLmxpbmtuYW1lID0gbGlua25hbWUKICAgIGxpbmtwYXRoID0gcHJvcGVydHkoX2dldGxpbmtwYXRoLCBfc2V0bGlua3BhdGgpCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAiPCVzICVyIGF0ICUjeD4iICUgKHNlbGYuX19jbGFzc19fLl9fbmFtZV9fLHNlbGYubmFtZSxpZChzZWxmKSkKCiAgICBkZWYgZ2V0X2luZm8oc2VsZiwgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBhcyBhIGRpY3Rpb25hcnkuCiAgICAgICAgIiIiCiAgICAgICAgaW5mbyA9IHsKICAgICAgICAgICAgIm5hbWUiOiAgICAgc2VsZi5uYW1lLAogICAgICAgICAgICAibW9kZSI6ICAgICBzZWxmLm1vZGUgJiAwNzc3NywKICAgICAgICAgICAgInVpZCI6ICAgICAgc2VsZi51aWQsCiAgICAgICAgICAgICJnaWQiOiAgICAgIHNlbGYuZ2lkLAogICAgICAgICAgICAic2l6ZSI6ICAgICBzZWxmLnNpemUsCiAgICAgICAgICAgICJtdGltZSI6ICAgIHNlbGYubXRpbWUsCiAgICAgICAgICAgICJjaGtzdW0iOiAgIHNlbGYuY2hrc3VtLAogICAgICAgICAgICAidHlwZSI6ICAgICBzZWxmLnR5cGUsCiAgICAgICAgICAgICJsaW5rbmFtZSI6IHNlbGYubGlua25hbWUsCiAgICAgICAgICAgICJ1bmFtZSI6ICAgIHNlbGYudW5hbWUsCiAgICAgICAgICAgICJnbmFtZSI6ICAgIHNlbGYuZ25hbWUsCiAgICAgICAgICAgICJkZXZtYWpvciI6IHNlbGYuZGV2bWFqb3IsCiAgICAgICAgICAgICJkZXZtaW5vciI6IHNlbGYuZGV2bWlub3IKICAgICAgICB9CgogICAgICAgIGlmIGluZm9bInR5cGUiXSA9PSBESVJUWVBFIGFuZCBub3QgaW5mb1sibmFtZSJdLmVuZHN3aXRoKCIvIik6CiAgICAgICAgICAgIGluZm9bIm5hbWUiXSArPSAiLyIKCiAgICAgICAgZm9yIGtleSBpbiAoIm5hbWUiLCAibGlua25hbWUiLCAidW5hbWUiLCAiZ25hbWUiKToKICAgICAgICAgICAgaWYgdHlwZShpbmZvW2tleV0pIGlzIHVuaWNvZGU6CiAgICAgICAgICAgICAgICBpbmZvW2tleV0gPSBpbmZvW2tleV0uZW5jb2RlKGVuY29kaW5nLCBlcnJvcnMpCgogICAgICAgIHJldHVybiBpbmZvCgogICAgZGVmIHRvYnVmKHNlbGYsIGZvcm1hdD1ERUZBVUxUX0ZPUk1BVCwgZW5jb2Rpbmc9RU5DT0RJTkcsIGVycm9ycz0ic3RyaWN0Iik6CiAgICAgICAgIiIiUmV0dXJuIGEgdGFyIGhlYWRlciBhcyBhIHN0cmluZyBvZiA1MTIgYnl0ZSBibG9ja3MuCiAgICAgICAgIiIiCiAgICAgICAgaW5mbyA9IHNlbGYuZ2V0X2luZm8oZW5jb2RpbmcsIGVycm9ycykKCiAgICAgICAgaWYgZm9ybWF0ID09IFVTVEFSX0ZPUk1BVDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlX3VzdGFyX2hlYWRlcihpbmZvKQogICAgICAgIGVsaWYgZm9ybWF0ID09IEdOVV9GT1JNQVQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV9nbnVfaGVhZGVyKGluZm8pCiAgICAgICAgZWxpZiBmb3JtYXQgPT0gUEFYX0ZPUk1BVDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlX3BheF9oZWFkZXIoaW5mbywgZW5jb2RpbmcsIGVycm9ycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJpbnZhbGlkIGZvcm1hdCIpCgogICAgZGVmIGNyZWF0ZV91c3Rhcl9oZWFkZXIoc2VsZiwgaW5mbyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSB1c3RhciBoZWFkZXIgYmxvY2suCiAgICAgICAgIiIiCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IFBPU0lYX01BR0lDCgogICAgICAgIGlmIGxlbihpbmZvWyJsaW5rbmFtZSJdKSA+IExFTkdUSF9MSU5LOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJsaW5rbmFtZSBpcyB0b28gbG9uZyIpCgogICAgICAgIGlmIGxlbihpbmZvWyJuYW1lIl0pID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgIGluZm9bInByZWZpeCJdLCBpbmZvWyJuYW1lIl0gPSBzZWxmLl9wb3NpeF9zcGxpdF9uYW1lKGluZm9bIm5hbWUiXSkKCiAgICAgICAgcmV0dXJuIHNlbGYuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKQoKICAgIGRlZiBjcmVhdGVfZ251X2hlYWRlcihzZWxmLCBpbmZvKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIEdOVSBoZWFkZXIgYmxvY2sgc2VxdWVuY2UuCiAgICAgICAgIiIiCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IEdOVV9NQUdJQwoKICAgICAgICBidWYgPSAiIgogICAgICAgIGlmIGxlbihpbmZvWyJsaW5rbmFtZSJdKSA+IExFTkdUSF9MSU5LOgogICAgICAgICAgICBidWYgKz0gc2VsZi5fY3JlYXRlX2dudV9sb25nX2hlYWRlcihpbmZvWyJsaW5rbmFtZSJdLCBHTlVUWVBFX0xPTkdMSU5LKQoKICAgICAgICBpZiBsZW4oaW5mb1sibmFtZSJdKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICBidWYgKz0gc2VsZi5fY3JlYXRlX2dudV9sb25nX2hlYWRlcihpbmZvWyJuYW1lIl0sIEdOVVRZUEVfTE9OR05BTUUpCgogICAgICAgIHJldHVybiBidWYgKyBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIEdOVV9GT1JNQVQpCgogICAgZGVmIGNyZWF0ZV9wYXhfaGVhZGVyKHNlbGYsIGluZm8sIGVuY29kaW5nLCBlcnJvcnMpOgogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgdXN0YXIgaGVhZGVyIGJsb2NrLiBJZiBpdCBjYW5ub3QgYmUKICAgICAgICAgICByZXByZXNlbnRlZCB0aGlzIHdheSwgcHJlcGVuZCBhIHBheCBleHRlbmRlZCBoZWFkZXIgc2VxdWVuY2UKICAgICAgICAgICB3aXRoIHN1cHBsZW1lbnQgaW5mb3JtYXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IFBPU0lYX01BR0lDCiAgICAgICAgcGF4X2hlYWRlcnMgPSBzZWxmLnBheF9oZWFkZXJzLmNvcHkoKQoKICAgICAgICAjIFRlc3Qgc3RyaW5nIGZpZWxkcyBmb3IgdmFsdWVzIHRoYXQgZXhjZWVkIHRoZSBmaWVsZCBsZW5ndGggb3IgY2Fubm90CiAgICAgICAgIyBiZSByZXByZXNlbnRlZCBpbiBBU0NJSSBlbmNvZGluZy4KICAgICAgICBmb3IgbmFtZSwgaG5hbWUsIGxlbmd0aCBpbiAoCiAgICAgICAgICAgICAgICAoIm5hbWUiLCAicGF0aCIsIExFTkdUSF9OQU1FKSwgKCJsaW5rbmFtZSIsICJsaW5rcGF0aCIsIExFTkdUSF9MSU5LKSwKICAgICAgICAgICAgICAgICgidW5hbWUiLCAidW5hbWUiLCAzMiksICgiZ25hbWUiLCAiZ25hbWUiLCAzMikpOgoKICAgICAgICAgICAgaWYgaG5hbWUgaW4gcGF4X2hlYWRlcnM6CiAgICAgICAgICAgICAgICAjIFRoZSBwYXggaGVhZGVyIGhhcyBwcmlvcml0eS4KICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICB2YWwgPSBpbmZvW25hbWVdLmRlY29kZShlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICAgICAgIyBUcnkgdG8gZW5jb2RlIHRoZSBzdHJpbmcgYXMgQVNDSUkuCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHZhbC5lbmNvZGUoImFzY2lpIikKICAgICAgICAgICAgZXhjZXB0IFVuaWNvZGVFbmNvZGVFcnJvcjoKICAgICAgICAgICAgICAgIHBheF9oZWFkZXJzW2huYW1lXSA9IHZhbAogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIGlmIGxlbihpbmZvW25hbWVdKSA+IGxlbmd0aDoKICAgICAgICAgICAgICAgIHBheF9oZWFkZXJzW2huYW1lXSA9IHZhbAoKICAgICAgICAjIFRlc3QgbnVtYmVyIGZpZWxkcyBmb3IgdmFsdWVzIHRoYXQgZXhjZWVkIHRoZSBmaWVsZCBsaW1pdCBvciB2YWx1ZXMKICAgICAgICAjIHRoYXQgbGlrZSB0byBiZSBzdG9yZWQgYXMgZmxvYXQuCiAgICAgICAgZm9yIG5hbWUsIGRpZ2l0cyBpbiAoKCJ1aWQiLCA4KSwgKCJnaWQiLCA4KSwgKCJzaXplIiwgMTIpLCAoIm10aW1lIiwgMTIpKToKICAgICAgICAgICAgaWYgbmFtZSBpbiBwYXhfaGVhZGVyczoKICAgICAgICAgICAgICAgICMgVGhlIHBheCBoZWFkZXIgaGFzIHByaW9yaXR5LiBBdm9pZCBvdmVyZmxvdy4KICAgICAgICAgICAgICAgIGluZm9bbmFtZV0gPSAwCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgdmFsID0gaW5mb1tuYW1lXQogICAgICAgICAgICBpZiBub3QgMCA8PSB2YWwgPCA4ICoqIChkaWdpdHMgLSAxKSBvciBpc2luc3RhbmNlKHZhbCwgZmxvYXQpOgogICAgICAgICAgICAgICAgcGF4X2hlYWRlcnNbbmFtZV0gPSB1bmljb2RlKHZhbCkKICAgICAgICAgICAgICAgIGluZm9bbmFtZV0gPSAwCgogICAgICAgICMgQ3JlYXRlIGEgcGF4IGV4dGVuZGVkIGhlYWRlciBpZiBuZWNlc3NhcnkuCiAgICAgICAgaWYgcGF4X2hlYWRlcnM6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIocGF4X2hlYWRlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmID0gIiIKCiAgICAgICAgcmV0dXJuIGJ1ZiArIHNlbGYuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIHBheCBnbG9iYWwgaGVhZGVyIGJsb2NrIHNlcXVlbmNlLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9wYXhfZ2VuZXJpY19oZWFkZXIocGF4X2hlYWRlcnMsIHR5cGU9WEdMVFlQRSkKCiAgICBkZWYgX3Bvc2l4X3NwbGl0X25hbWUoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiU3BsaXQgYSBuYW1lIGxvbmdlciB0aGFuIDEwMCBjaGFycyBpbnRvIGEgcHJlZml4CiAgICAgICAgICAgYW5kIGEgbmFtZSBwYXJ0LgogICAgICAgICIiIgogICAgICAgIHByZWZpeCA9IG5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQogICAgICAgIHdoaWxlIHByZWZpeCBhbmQgcHJlZml4Wy0xXSAhPSAiLyI6CiAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgIG5hbWUgPSBuYW1lW2xlbihwcmVmaXgpOl0KICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJuYW1lIGlzIHRvbyBsb25nIikKICAgICAgICByZXR1cm4gcHJlZml4LCBuYW1lCgogICAgQHN0YXRpY21ldGhvZAogICAgZGVmIF9jcmVhdGVfaGVhZGVyKGluZm8sIGZvcm1hdCk6CiAgICAgICAgIiIiUmV0dXJuIGEgaGVhZGVyIGJsb2NrLiBpbmZvIGlzIGEgZGljdGlvbmFyeSB3aXRoIGZpbGUKICAgICAgICAgICBpbmZvcm1hdGlvbiwgZm9ybWF0IG11c3QgYmUgb25lIG9mIHRoZSAqX0ZPUk1BVCBjb25zdGFudHMuCiAgICAgICAgIiIiCiAgICAgICAgcGFydHMgPSBbCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgibmFtZSIsICIiKSwgMTAwKSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtb2RlIiwgMCkgJiAwNzc3NywgOCwgZm9ybWF0KSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJ1aWQiLCAwKSwgOCwgZm9ybWF0KSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJnaWQiLCAwKSwgOCwgZm9ybWF0KSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJzaXplIiwgMCksIDEyLCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoIm10aW1lIiwgMCksIDEyLCBmb3JtYXQpLAogICAgICAgICAgICAiICAgICAgICAiLCAjIGNoZWNrc3VtIGZpZWxkCiAgICAgICAgICAgIGluZm8uZ2V0KCJ0eXBlIiwgUkVHVFlQRSksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgibGlua25hbWUiLCAiIiksIDEwMCksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgibWFnaWMiLCBQT1NJWF9NQUdJQyksIDgpLAogICAgICAgICAgICBzdG4oaW5mby5nZXQoInVuYW1lIiwgIiIpLCAzMiksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgiZ25hbWUiLCAiIiksIDMyKSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJkZXZtYWpvciIsIDApLCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1pbm9yIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgicHJlZml4IiwgIiIpLCAxNTUpCiAgICAgICAgXQoKICAgICAgICBidWYgPSBzdHJ1Y3QucGFjaygiJWRzIiAlIEJMT0NLU0laRSwgIiIuam9pbihwYXJ0cykpCiAgICAgICAgY2hrc3VtID0gY2FsY19jaGtzdW1zKGJ1ZlstQkxPQ0tTSVpFOl0pWzBdCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQogICAgICAgIHJldHVybiBidWYKCiAgICBAc3RhdGljbWV0aG9kCiAgICBkZWYgX2NyZWF0ZV9wYXlsb2FkKHBheWxvYWQpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyaW5nIHBheWxvYWQgZmlsbGVkIHdpdGggemVybyBieXRlcwogICAgICAgICAgIHVwIHRvIHRoZSBuZXh0IDUxMiBieXRlIGJvcmRlci4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4ocGF5bG9hZCksIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBwYXlsb2FkICs9IChCTE9DS1NJWkUgLSByZW1haW5kZXIpICogTlVMCiAgICAgICAgcmV0dXJuIHBheWxvYWQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX2dudV9sb25nX2hlYWRlcihjbHMsIG5hbWUsIHR5cGUpOgogICAgICAgICIiIlJldHVybiBhIEdOVVRZUEVfTE9OR05BTUUgb3IgR05VVFlQRV9MT05HTElOSyBzZXF1ZW5jZQogICAgICAgICAgIGZvciBuYW1lLgogICAgICAgICIiIgogICAgICAgIG5hbWUgKz0gTlVMCgogICAgICAgIGluZm8gPSB7fQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIGluZm9bInR5cGUiXSA9IHR5cGUKICAgICAgICBpbmZvWyJzaXplIl0gPSBsZW4obmFtZSkKICAgICAgICBpbmZvWyJtYWdpYyJdID0gR05VX01BR0lDCgogICAgICAgICMgY3JlYXRlIGV4dGVuZGVkIGhlYWRlciArIG5hbWUgYmxvY2tzLgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwKICAgICAgICAgICAgICAgIGNscy5fY3JlYXRlX3BheWxvYWQobmFtZSkKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzLCB0eXBlPVhIRFRZUEUpOgogICAgICAgICIiIlJldHVybiBhIFBPU0lYLjEtMjAwMSBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyIHNlcXVlbmNlCiAgICAgICAgICAgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Yga2V5d29yZCwgdmFsdWUgcGFpcnMuIFRoZSB2YWx1ZXMKICAgICAgICAgICBtdXN0IGJlIHVuaWNvZGUgb2JqZWN0cy4KICAgICAgICAiIiIKICAgICAgICByZWNvcmRzID0gW10KICAgICAgICBmb3Iga2V5d29yZCwgdmFsdWUgaW4gcGF4X2hlYWRlcnMuaXRlcml0ZW1zKCk6CiAgICAgICAgICAgIGtleXdvcmQgPSBrZXl3b3JkLmVuY29kZSgidXRmOCIpCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuZW5jb2RlKCJ1dGY4IikKICAgICAgICAgICAgbCA9IGxlbihrZXl3b3JkKSArIGxlbih2YWx1ZSkgKyAzICAgIyAnICcgKyAnPScgKyAnXG4nCiAgICAgICAgICAgIG4gPSBwID0gMAogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgbiA9IGwgKyBsZW4oc3RyKHApKQogICAgICAgICAgICAgICAgaWYgbiA9PSBwOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBwID0gbgogICAgICAgICAgICByZWNvcmRzLmFwcGVuZCgiJWQgJXM9JXNcbiIgJSAocCwga2V5d29yZCwgdmFsdWUpKQogICAgICAgIHJlY29yZHMgPSAiIi5qb2luKHJlY29yZHMpCgogICAgICAgICMgV2UgdXNlIGEgaGFyZGNvZGVkICIuLy4vQFBheEhlYWRlciIgbmFtZSBsaWtlIHN0YXIgZG9lcwogICAgICAgICMgaW5zdGVhZCBvZiB0aGUgb25lIHRoYXQgUE9TSVggcmVjb21tZW5kcy4KICAgICAgICBpbmZvID0ge30KICAgICAgICBpbmZvWyJuYW1lIl0gPSAiLi8uL0BQYXhIZWFkZXIiCiAgICAgICAgaW5mb1sidHlwZSJdID0gdHlwZQogICAgICAgIGluZm9bInNpemUiXSA9IGxlbihyZWNvcmRzKQogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwoKICAgICAgICAjIENyZWF0ZSBwYXggaGVhZGVyICsgcmVjb3JkIGJsb2Nrcy4KICAgICAgICByZXR1cm4gY2xzLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkgKyBcCiAgICAgICAgICAgICAgICBjbHMuX2NyZWF0ZV9wYXlsb2FkKHJlY29yZHMpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgPT0gMDoKICAgICAgICAgICAgcmFpc2UgRW1wdHlIZWFkZXJFcnJvcigiZW1wdHkgaGVhZGVyIikKICAgICAgICBpZiBsZW4oYnVmKSAhPSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIFRydW5jYXRlZEhlYWRlckVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikKICAgICAgICBpZiBidWYuY291bnQoTlVMKSA9PSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIEVPRkhlYWRlckVycm9yKCJlbmQgb2YgZmlsZSBoZWFkZXIiKQoKICAgICAgICBjaGtzdW0gPSBudGkoYnVmWzE0ODoxNTZdKQogICAgICAgIGlmIGNoa3N1bSBub3QgaW4gY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAgICAgICAgIHJhaXNlIEludmFsaWRIZWFkZXJFcnJvcigiYmFkIGNoZWNrc3VtIikKCiAgICAgICAgb2JqID0gY2xzKCkKICAgICAgICBvYmouYnVmID0gYnVmCiAgICAgICAgb2JqLm5hbWUgPSBudHMoYnVmWzA6MTAwXSkKICAgICAgICBvYmoubW9kZSA9IG50aShidWZbMTAwOjEwOF0pCiAgICAgICAgb2JqLnVpZCA9IG50aShidWZbMTA4OjExNl0pCiAgICAgICAgb2JqLmdpZCA9IG50aShidWZbMTE2OjEyNF0pCiAgICAgICAgb2JqLnNpemUgPSBudGkoYnVmWzEyNDoxMzZdKQogICAgICAgIG9iai5tdGltZSA9IG50aShidWZbMTM2OjE0OF0pCiAgICAgICAgb2JqLmNoa3N1bSA9IGNoa3N1bQogICAgICAgIG9iai50eXBlID0gYnVmWzE1NjoxNTddCiAgICAgICAgb2JqLmxpbmtuYW1lID0gbnRzKGJ1ZlsxNTc6MjU3XSkKICAgICAgICBvYmoudW5hbWUgPSBudHMoYnVmWzI2NToyOTddKQogICAgICAgIG9iai5nbmFtZSA9IG50cyhidWZbMjk3OjMyOV0pCiAgICAgICAgb2JqLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkKICAgICAgICBvYmouZGV2bWlub3IgPSBudGkoYnVmWzMzNzozNDVdKQogICAgICAgIHByZWZpeCA9IG50cyhidWZbMzQ1OjUwMF0pCgogICAgICAgICMgT2xkIFY3IHRhciBmb3JtYXQgcmVwcmVzZW50cyBhIGRpcmVjdG9yeSBhcyBhIHJlZ3VsYXIKICAgICAgICAjIGZpbGUgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLgogICAgICAgIGlmIG9iai50eXBlID09IEFSRUdUWVBFIGFuZCBvYmoubmFtZS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICBvYmoudHlwZSA9IERJUlRZUEUKCiAgICAgICAgIyBSZW1vdmUgcmVkdW5kYW50IHNsYXNoZXMgZnJvbSBkaXJlY3Rvcmllcy4KICAgICAgICBpZiBvYmouaXNkaXIoKToKICAgICAgICAgICAgb2JqLm5hbWUgPSBvYmoubmFtZS5yc3RyaXAoIi8iKQoKICAgICAgICAjIFJlY29uc3RydWN0IGEgdXN0YXIgbG9uZ25hbWUuCiAgICAgICAgaWYgcHJlZml4IGFuZCBvYmoudHlwZSBub3QgaW4gR05VX1RZUEVTOgogICAgICAgICAgICBvYmoubmFtZSA9IHByZWZpeCArICIvIiArIG9iai5uYW1lCiAgICAgICAgcmV0dXJuIG9iagoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGZyb210YXJmaWxlKGNscywgdGFyZmlsZSk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IFRhckluZm8gb2JqZWN0IGZyb20gVGFyRmlsZSBvYmplY3QKICAgICAgICAgICB0YXJmaWxlLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICBvYmogPSBjbHMuZnJvbWJ1ZihidWYpCiAgICAgICAgb2JqLm9mZnNldCA9IHRhcmZpbGUuZmlsZW9iai50ZWxsKCkgLSBCTE9DS1NJWkUKICAgICAgICByZXR1cm4gb2JqLl9wcm9jX21lbWJlcih0YXJmaWxlKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgZm9sbG93aW5nIGFyZSBtZXRob2RzIHRoYXQgYXJlIGNhbGxlZCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgYQogICAgIyBtZW1iZXIuIFRoZSBlbnRyeSBwb2ludCBpcyBfcHJvY19tZW1iZXIoKSB3aGljaCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBhCiAgICAjIHN1YmNsYXNzIHRvIGFkZCBjdXN0b20gX3Byb2NfKigpIG1ldGhvZHMuIEEgX3Byb2NfKigpIG1ldGhvZCBNVVNUCiAgICAjIGltcGxlbWVudCB0aGUgZm9sbG93aW5nCiAgICAjIG9wZXJhdGlvbnM6CiAgICAjIDEuIFNldCBzZWxmLm9mZnNldF9kYXRhIHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MgYmVnaW4sCiAgICAjICAgIGlmIHRoZXJlIGlzIGRhdGEgdGhhdCBmb2xsb3dzLgogICAgIyAyLiBTZXQgdGFyZmlsZS5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsCiAgICAjICAgIGJlZ2luLgogICAgIyAzLiBSZXR1cm4gc2VsZiBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgogICAgZGVmIF9wcm9jX21lbWJlcihzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDaG9vc2UgdGhlIHJpZ2h0IHByb2Nlc3NpbmcgbWV0aG9kIGRlcGVuZGluZyBvbgogICAgICAgICAgIHRoZSB0eXBlIGFuZCBjYWxsIGl0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYudHlwZSBpbiAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX2dudWxvbmcodGFyZmlsZSkKICAgICAgICBlbGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2Nfc3BhcnNlKHRhcmZpbGUpCiAgICAgICAgZWxpZiBzZWxmLnR5cGUgaW4gKFhIRFRZUEUsIFhHTFRZUEUsIFNPTEFSSVNfWEhEVFlQRSk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX3BheCh0YXJmaWxlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX2J1aWx0aW4odGFyZmlsZSkKCiAgICBkZWYgX3Byb2NfYnVpbHRpbihzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIGEgYnVpbHRpbiB0eXBlIG9yIGFuIHVua25vd24gdHlwZSB3aGljaAogICAgICAgICAgIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKQogICAgICAgIG9mZnNldCA9IHNlbGYub2Zmc2V0X2RhdGEKICAgICAgICBpZiBzZWxmLmlzcmVnKCkgb3Igc2VsZi50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICBvZmZzZXQgKz0gc2VsZi5fYmxvY2soc2VsZi5zaXplKQogICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gb2Zmc2V0CgogICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IHdpdGggc2F2ZWQgZ2xvYmFsCiAgICAgICAgIyBoZWFkZXIgaW5mb3JtYXRpb24uCiAgICAgICAgc2VsZi5fYXBwbHlfcGF4X2luZm8odGFyZmlsZS5wYXhfaGVhZGVycywgdGFyZmlsZS5lbmNvZGluZywgdGFyZmlsZS5lcnJvcnMpCgogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9wcm9jX2dudWxvbmcoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyB0aGUgYmxvY2tzIHRoYXQgaG9sZCBhIEdOVSBsb25nbmFtZQogICAgICAgICAgIG9yIGxvbmdsaW5rIG1lbWJlci4KICAgICAgICAiIiIKICAgICAgICBidWYgPSB0YXJmaWxlLmZpbGVvYmoucmVhZChzZWxmLl9ibG9jayhzZWxmLnNpemUpKQoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlciBhbmQgcHJvY2VzcyBpdC4KICAgICAgICB0cnk6CiAgICAgICAgICAgIG5leHQgPSBzZWxmLmZyb210YXJmaWxlKHRhcmZpbGUpCiAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yOgogICAgICAgICAgICByYWlzZSBTdWJzZXF1ZW50SGVhZGVyRXJyb3IoIm1pc3Npbmcgb3IgYmFkIHN1YnNlcXVlbnQgaGVhZGVyIikKCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgbmV4dCBoZWFkZXIgd2l0aAogICAgICAgICMgdGhlIGxvbmduYW1lIGluZm9ybWF0aW9uLgogICAgICAgIG5leHQub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICBpZiBzZWxmLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToKICAgICAgICAgICAgbmV4dC5uYW1lID0gbnRzKGJ1ZikKICAgICAgICBlbGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gbnRzKGJ1ZikKCiAgICAgICAgcmV0dXJuIG5leHQKCiAgICBkZWYgX3Byb2Nfc3BhcnNlKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIlByb2Nlc3MgYSBHTlUgc3BhcnNlIGhlYWRlciBwbHVzIGV4dHJhIGhlYWRlcnMuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gc2VsZi5idWYKICAgICAgICBzcCA9IF9yaW5nYnVmZmVyKCkKICAgICAgICBwb3MgPSAzODYKICAgICAgICBsYXN0cG9zID0gMEwKICAgICAgICByZWFscG9zID0gMEwKICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQogICAgICAgICMgZmlyc3QgaGVhZGVyLgogICAgICAgIGZvciBpIGluIHhyYW5nZSg0KToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBudGkoYnVmW3BvcyArIDEyOnBvcyArIDI0XSkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgIHBvcyArPSAyNAoKICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQogICAgICAgIG9yaWdzaXplID0gbnRpKGJ1Zls0ODM6NDk1XSkKCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLAogICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KICAgICAgICB3aGlsZSBpc2V4dGVuZGVkID09IDE6CiAgICAgICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgcG9zID0gMAogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoMjEpOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkKICAgICAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgICAgICBwb3MgKz0gMjQKICAgICAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNTA0XSkKCiAgICAgICAgaWYgbGFzdHBvcyA8IG9yaWdzaXplOgogICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb3JpZ3NpemUgLSBsYXN0cG9zKSkKCiAgICAgICAgc2VsZi5zcGFyc2UgPSBzcAoKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKQogICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gc2VsZi5vZmZzZXRfZGF0YSArIHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkKICAgICAgICBzZWxmLnNpemUgPSBvcmlnc2l6ZQoKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBfcHJvY19wYXgoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyBhbiBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyIGFzIGRlc2NyaWJlZCBpbgogICAgICAgICAgIFBPU0lYLjEtMjAwMS4KICAgICAgICAiIiIKICAgICAgICAjIFJlYWQgdGhlIGhlYWRlciBpbmZvcm1hdGlvbi4KICAgICAgICBidWYgPSB0YXJmaWxlLmZpbGVvYmoucmVhZChzZWxmLl9ibG9jayhzZWxmLnNpemUpKQoKICAgICAgICAjIEEgcGF4IGhlYWRlciBzdG9yZXMgc3VwcGxlbWVudGFsIGluZm9ybWF0aW9uIGZvciBlaXRoZXIKICAgICAgICAjIHRoZSBmb2xsb3dpbmcgZmlsZSAoZXh0ZW5kZWQpIG9yIGFsbCBmb2xsb3dpbmcgZmlsZXMKICAgICAgICAjIChnbG9iYWwpLgogICAgICAgIGlmIHNlbGYudHlwZSA9PSBYR0xUWVBFOgogICAgICAgICAgICBwYXhfaGVhZGVycyA9IHRhcmZpbGUucGF4X2hlYWRlcnMKICAgICAgICBlbHNlOgogICAgICAgICAgICBwYXhfaGVhZGVycyA9IHRhcmZpbGUucGF4X2hlYWRlcnMuY29weSgpCgogICAgICAgICMgUGFyc2UgcGF4IGhlYWRlciBpbmZvcm1hdGlvbi4gQSByZWNvcmQgbG9va3MgbGlrZSB0aGF0OgogICAgICAgICMgIiVkICVzPSVzXG4iICUgKGxlbmd0aCwga2V5d29yZCwgdmFsdWUpLiBsZW5ndGggaXMgdGhlIHNpemUKICAgICAgICAjIG9mIHRoZSBjb21wbGV0ZSByZWNvcmQgaW5jbHVkaW5nIHRoZSBsZW5ndGggZmllbGQgaXRzZWxmIGFuZAogICAgICAgICMgdGhlIG5ld2xpbmUuIGtleXdvcmQgYW5kIHZhbHVlIGFyZSBib3RoIFVURi04IGVuY29kZWQgc3RyaW5ncy4KICAgICAgICByZWdleCA9IHJlLmNvbXBpbGUociIoXGQrKSAoW149XSspPSIsIHJlLlUpCiAgICAgICAgcG9zID0gMAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIG1hdGNoID0gcmVnZXgubWF0Y2goYnVmLCBwb3MpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBsZW5ndGgsIGtleXdvcmQgPSBtYXRjaC5ncm91cHMoKQogICAgICAgICAgICBsZW5ndGggPSBpbnQobGVuZ3RoKQogICAgICAgICAgICB2YWx1ZSA9IGJ1ZlttYXRjaC5lbmQoMikgKyAxOm1hdGNoLnN0YXJ0KDEpICsgbGVuZ3RoIC0gMV0KCiAgICAgICAgICAgIGtleXdvcmQgPSBrZXl3b3JkLmRlY29kZSgidXRmOCIpCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuZGVjb2RlKCJ1dGY4IikKCiAgICAgICAgICAgIHBheF9oZWFkZXJzW2tleXdvcmRdID0gdmFsdWUKICAgICAgICAgICAgcG9zICs9IGxlbmd0aAoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlci4KICAgICAgICB0cnk6CiAgICAgICAgICAgIG5leHQgPSBzZWxmLmZyb210YXJmaWxlKHRhcmZpbGUpCiAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yOgogICAgICAgICAgICByYWlzZSBTdWJzZXF1ZW50SGVhZGVyRXJyb3IoIm1pc3Npbmcgb3IgYmFkIHN1YnNlcXVlbnQgaGVhZGVyIikKCiAgICAgICAgaWYgc2VsZi50eXBlIGluIChYSERUWVBFLCBTT0xBUklTX1hIRFRZUEUpOgogICAgICAgICAgICAjIFBhdGNoIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIHRoZSBleHRlbmRlZCBoZWFkZXIgaW5mby4KICAgICAgICAgICAgbmV4dC5fYXBwbHlfcGF4X2luZm8ocGF4X2hlYWRlcnMsIHRhcmZpbGUuZW5jb2RpbmcsIHRhcmZpbGUuZXJyb3JzKQogICAgICAgICAgICBuZXh0Lm9mZnNldCA9IHNlbGYub2Zmc2V0CgogICAgICAgICAgICBpZiAic2l6ZSIgaW4gcGF4X2hlYWRlcnM6CiAgICAgICAgICAgICAgICAjIElmIHRoZSBleHRlbmRlZCBoZWFkZXIgcmVwbGFjZXMgdGhlIHNpemUgZmllbGQsCiAgICAgICAgICAgICAgICAjIHdlIG5lZWQgdG8gcmVjYWxjdWxhdGUgdGhlIG9mZnNldCB3aGVyZSB0aGUgbmV4dAogICAgICAgICAgICAgICAgIyBoZWFkZXIgc3RhcnRzLgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gbmV4dC5vZmZzZXRfZGF0YQogICAgICAgICAgICAgICAgaWYgbmV4dC5pc3JlZygpIG9yIG5leHQudHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSBuZXh0Ll9ibG9jayhuZXh0LnNpemUpCiAgICAgICAgICAgICAgICB0YXJmaWxlLm9mZnNldCA9IG9mZnNldAoKICAgICAgICByZXR1cm4gbmV4dAoKICAgIGRlZiBfYXBwbHlfcGF4X2luZm8oc2VsZiwgcGF4X2hlYWRlcnMsIGVuY29kaW5nLCBlcnJvcnMpOgogICAgICAgICIiIlJlcGxhY2UgZmllbGRzIHdpdGggc3VwcGxlbWVudGFsIGluZm9ybWF0aW9uIGZyb20gYSBwcmV2aW91cwogICAgICAgICAgIHBheCBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyLgogICAgICAgICIiIgogICAgICAgIGZvciBrZXl3b3JkLCB2YWx1ZSBpbiBwYXhfaGVhZGVycy5pdGVyaXRlbXMoKToKICAgICAgICAgICAgaWYga2V5d29yZCBub3QgaW4gUEFYX0ZJRUxEUzoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBpZiBrZXl3b3JkID09ICJwYXRoIjoKICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucnN0cmlwKCIvIikKCiAgICAgICAgICAgIGlmIGtleXdvcmQgaW4gUEFYX05VTUJFUl9GSUVMRFM6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBQQVhfTlVNQkVSX0ZJRUxEU1trZXl3b3JkXSh2YWx1ZSkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gMAogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgdmFsdWUgPSB1dHModmFsdWUsIGVuY29kaW5nLCBlcnJvcnMpCgogICAgICAgICAgICBzZXRhdHRyKHNlbGYsIGtleXdvcmQsIHZhbHVlKQoKICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0gcGF4X2hlYWRlcnMuY29weSgpCgogICAgZGVmIF9ibG9jayhzZWxmLCBjb3VudCk6CiAgICAgICAgIiIiUm91bmQgdXAgYSBieXRlIGNvdW50IGJ5IEJMT0NLU0laRSBhbmQgcmV0dXJuIGl0LAogICAgICAgICAgIGUuZy4gX2Jsb2NrKDgzNCkgPT4gMTAyNC4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChjb3VudCwgQkxPQ0tTSVpFKQogICAgICAgIGlmIHJlbWFpbmRlcjoKICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICByZXR1cm4gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDEgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBmb3JtYXQgPSBERUZBVUxUX0ZPUk1BVCAgICAgIyBUaGUgZm9ybWF0IHRvIHVzZSB3aGVuIGNyZWF0aW5nIGFuIGFyY2hpdmUuCgogICAgZW5jb2RpbmcgPSBFTkNPRElORyAgICAgICAgICMgRW5jb2RpbmcgZm9yIDgtYml0IGNoYXJhY3RlciBzdHJpbmdzLgoKICAgIGVycm9ycyA9IE5vbmUgICAgICAgICAgICAgICAjIEVycm9yIGhhbmRsZXIgZm9yIHVuaWNvZGUgY29udmVyc2lvbi4KCiAgICB0YXJpbmZvID0gVGFySW5mbyAgICAgICAgICAgIyBUaGUgZGVmYXVsdCBUYXJJbmZvIGNsYXNzIHRvIHVzZS4KCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0ICAgIyBUaGUgZGVmYXVsdCBFeEZpbGVPYmplY3QgY2xhc3MgdG8gdXNlLgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGZvcm1hdD1Ob25lLAogICAgICAgICAgICB0YXJpbmZvPU5vbmUsIGRlcmVmZXJlbmNlPU5vbmUsIGlnbm9yZV96ZXJvcz1Ob25lLCBlbmNvZGluZz1Ob25lLAogICAgICAgICAgICBlcnJvcnM9Tm9uZSwgcGF4X2hlYWRlcnM9Tm9uZSwgZGVidWc9Tm9uZSwgZXJyb3JsZXZlbD1Ob25lKToKICAgICAgICAiIiJPcGVuIGFuICh1bmNvbXByZXNzZWQpIHRhciBhcmNoaXZlIGBuYW1lJy4gYG1vZGUnIGlzIGVpdGhlciAncicgdG8KICAgICAgICAgICByZWFkIGZyb20gYW4gZXhpc3RpbmcgYXJjaGl2ZSwgJ2EnIHRvIGFwcGVuZCBkYXRhIHRvIGFuIGV4aXN0aW5nCiAgICAgICAgICAgZmlsZSBvciAndycgdG8gY3JlYXRlIGEgbmV3IGZpbGUgb3ZlcndyaXRpbmcgYW4gZXhpc3Rpbmcgb25lLiBgbW9kZScKICAgICAgICAgICBkZWZhdWx0cyB0byAncicuCiAgICAgICAgICAgSWYgYGZpbGVvYmonIGlzIGdpdmVuLCBpdCBpcyB1c2VkIGZvciByZWFkaW5nIG9yIHdyaXRpbmcgZGF0YS4gSWYgaXQKICAgICAgICAgICBjYW4gYmUgZGV0ZXJtaW5lZCwgYG1vZGUnIGlzIG92ZXJyaWRkZW4gYnkgYGZpbGVvYmoncyBtb2RlLgogICAgICAgICAgIGBmaWxlb2JqJyBpcyBub3QgY2xvc2VkLCB3aGVuIFRhckZpbGUgaXMgY2xvc2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLl9tb2RlID0geyJyIjogInJiIiwgImEiOiAicitiIiwgInciOiAid2IifVttb2RlXQoKICAgICAgICBpZiBub3QgZmlsZW9iajoKICAgICAgICAgICAgaWYgc2VsZi5tb2RlID09ICJhIiBhbmQgbm90IG9zLnBhdGguZXhpc3RzKG5hbWUpOgogICAgICAgICAgICAgICAgIyBDcmVhdGUgbm9uZXhpc3RlbnQgZmlsZXMgaW4gYXBwZW5kIG1vZGUuCiAgICAgICAgICAgICAgICBzZWxmLm1vZGUgPSAidyIKICAgICAgICAgICAgICAgIHNlbGYuX21vZGUgPSAid2IiCiAgICAgICAgICAgIGZpbGVvYmogPSBibHRuX29wZW4obmFtZSwgc2VsZi5fbW9kZSkKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgbmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lCiAgICAgICAgICAgIGlmIGhhc2F0dHIoZmlsZW9iaiwgIm1vZGUiKToKICAgICAgICAgICAgICAgIHNlbGYuX21vZGUgPSBmaWxlb2JqLm1vZGUKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IFRydWUKICAgICAgICBzZWxmLm5hbWUgPSBvcy5wYXRoLmFic3BhdGgobmFtZSkgaWYgbmFtZSBlbHNlIE5vbmUKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCgogICAgICAgICMgSW5pdCBhdHRyaWJ1dGVzLgogICAgICAgIGlmIGZvcm1hdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5mb3JtYXQgPSBmb3JtYXQKICAgICAgICBpZiB0YXJpbmZvIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLnRhcmluZm8gPSB0YXJpbmZvCiAgICAgICAgaWYgZGVyZWZlcmVuY2UgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZGVyZWZlcmVuY2UgPSBkZXJlZmVyZW5jZQogICAgICAgIGlmIGlnbm9yZV96ZXJvcyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5pZ25vcmVfemVyb3MgPSBpZ25vcmVfemVyb3MKICAgICAgICBpZiBlbmNvZGluZyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5lbmNvZGluZyA9IGVuY29kaW5nCgogICAgICAgIGlmIGVycm9ycyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSBlcnJvcnMKICAgICAgICBlbGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICBzZWxmLmVycm9ycyA9ICJ1dGYtOCIKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmVycm9ycyA9ICJzdHJpY3QiCgogICAgICAgIGlmIHBheF9oZWFkZXJzIGlzIG5vdCBOb25lIGFuZCBzZWxmLmZvcm1hdCA9PSBQQVhfRk9STUFUOgogICAgICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0gcGF4X2hlYWRlcnMKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0ge30KCiAgICAgICAgaWYgZGVidWcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZGVidWcgPSBkZWJ1ZwogICAgICAgIGlmIGVycm9ybGV2ZWwgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZXJyb3JsZXZlbCA9IGVycm9ybGV2ZWwKCiAgICAgICAgIyBJbml0IGRhdGFzdHJ1Y3R1cmVzLgogICAgICAgIHNlbGYuY2xvc2VkID0gRmFsc2UKICAgICAgICBzZWxmLm1lbWJlcnMgPSBbXSAgICAgICAjIGxpc3Qgb2YgbWVtYmVycyBhcyBUYXJJbmZvIG9iamVjdHMKICAgICAgICBzZWxmLl9sb2FkZWQgPSBGYWxzZSAgICAjIGZsYWcgaWYgYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQKICAgICAgICBzZWxmLm9mZnNldCA9IHNlbGYuZmlsZW9iai50ZWxsKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIGFyY2hpdmUgZmlsZQogICAgICAgIHNlbGYuaW5vZGVzID0ge30gICAgICAgICMgZGljdGlvbmFyeSBjYWNoaW5nIHRoZSBpbm9kZXMgb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmUgbWVtYmVycyBhbHJlYWR5IGFkZGVkCgogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gc2VsZi5uZXh0KCkKCiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiYSI6CiAgICAgICAgICAgICAgICAjIE1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSwKICAgICAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQpCiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJpbmZvLmZyb210YXJmaWxlKHNlbGYpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKICAgICAgICAgICAgICAgICAgICBleGNlcHQgRU9GSGVhZGVyRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBIZWFkZXJFcnJvciwgZToKICAgICAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkKCiAgICAgICAgICAgIGlmIHNlbGYubW9kZSBpbiAiYXciOgogICAgICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICAgICAgICAgICAgIGlmIHNlbGYucGF4X2hlYWRlcnM6CiAgICAgICAgICAgICAgICAgICAgYnVmID0gc2VsZi50YXJpbmZvLmNyZWF0ZV9wYXhfZ2xvYmFsX2hlYWRlcihzZWxmLnBheF9oZWFkZXJzLmNvcHkoKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoYnVmKQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IGxlbihidWYpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQogICAgICAgICAgICByYWlzZQoKICAgIGRlZiBfZ2V0cG9zaXgoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuZm9ybWF0ID09IFVTVEFSX0ZPUk1BVAogICAgZGVmIF9zZXRwb3NpeChzZWxmLCB2YWx1ZSk6CiAgICAgICAgaW1wb3J0IHdhcm5pbmdzCiAgICAgICAgd2FybmluZ3Mud2FybigidXNlIHRoZSBmb3JtYXQgYXR0cmlidXRlIGluc3RlYWQiLCBEZXByZWNhdGlvbldhcm5pbmcsCiAgICAgICAgICAgICAgICAgICAgICAyKQogICAgICAgIGlmIHZhbHVlOgogICAgICAgICAgICBzZWxmLmZvcm1hdCA9IFVTVEFSX0ZPUk1BVAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gR05VX0ZPUk1BVAogICAgcG9zaXggPSBwcm9wZXJ0eShfZ2V0cG9zaXgsIF9zZXRwb3NpeCkKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBjbGFzc21ldGhvZHMgd2hpY2ggYWN0IGFzIGFsdGVybmF0ZSBjb25zdHJ1Y3RvcnMgdG8gdGhlCiAgICAjIFRhckZpbGUgY2xhc3MuIFRoZSBvcGVuKCkgbWV0aG9kIGlzIHRoZSBvbmx5IG9uZSB0aGF0IGlzIG5lZWRlZCBmb3IKICAgICMgcHVibGljIHVzZTsgaXQgaXMgdGhlICJzdXBlciItY29uc3RydWN0b3IgYW5kIGlzIGFibGUgdG8gc2VsZWN0IGFuCiAgICAjIGFkZXF1YXRlICJzdWIiLWNvbnN0cnVjdG9yIGZvciBhIHBhcnRpY3VsYXIgY29tcHJlc3Npb24gdXNpbmcgdGhlIG1hcHBpbmcKICAgICMgZnJvbSBPUEVOX01FVEguCiAgICAjCiAgICAjIFRoaXMgY29uY2VwdCBhbGxvd3Mgb25lIHRvIHN1YmNsYXNzIFRhckZpbGUgd2l0aG91dCBsb3NpbmcgdGhlIGNvbWZvcnQgb2YKICAgICMgdGhlIHN1cGVyLWNvbnN0cnVjdG9yLiBBIHN1Yi1jb25zdHJ1Y3RvciBpcyByZWdpc3RlcmVkIGFuZCBtYWRlIGF2YWlsYWJsZQogICAgIyBieSBhZGRpbmcgaXQgdG8gdGhlIG1hcHBpbmcgaW4gT1BFTl9NRVRILgoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIG9wZW4oY2xzLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGJ1ZnNpemU9UkVDT1JEU0laRSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gYSB0YXIgYXJjaGl2ZSBmb3IgcmVhZGluZywgd3JpdGluZyBvciBhcHBlbmRpbmcuIFJldHVybgogICAgICAgICAgIGFuIGFwcHJvcHJpYXRlIFRhckZpbGUgY2xhc3MuCgogICAgICAgICAgIG1vZGU6CiAgICAgICAgICAgJ3InIG9yICdyOionIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAogICAgICAgICAgICdyOmd6JyAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOmJ6MicgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nLCBjcmVhdGluZyB0aGUgZmlsZSBpZiBuZWNlc3NhcnkKICAgICAgICAgICAndycgb3IgJ3c6JyAgb3BlbiBmb3Igd3JpdGluZyB3aXRob3V0IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6Z3onICAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6YnoyJyAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgoKICAgICAgICAgICAncnwqJyAgICAgICAgb3BlbiBhIHN0cmVhbSBvZiB0YXIgYmxvY2tzIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcKICAgICAgICAgICAncnxneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgIiIiCgogICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibm90aGluZyB0byBvcGVuIikKCiAgICAgICAgaWYgbW9kZSBpbiAoInIiLCAicjoqIik6CiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KICAgICAgICAgICAgZm9yIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBzYXZlZF9wb3MgPSBmaWxlb2JqLnRlbGwoKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaiwgKiprd2FyZ3MpCiAgICAgICAgICAgICAgICBleGNlcHQgKFJlYWRFcnJvciwgQ29tcHJlc3Npb25FcnJvciksIGU6CiAgICAgICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9iai5zZWVrKHNhdmVkX3BvcykKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpCgogICAgICAgIGVsaWYgInwiIGluIG1vZGU6CiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoInwiLCAxKQogICAgICAgICAgICBmaWxlbW9kZSA9IGZpbGVtb2RlIG9yICJyIgogICAgICAgICAgICBjb21wdHlwZSA9IGNvbXB0eXBlIG9yICJ0YXIiCgogICAgICAgICAgICBpZiBmaWxlbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIikKCiAgICAgICAgICAgIHQgPSBjbHMobmFtZSwgZmlsZW1vZGUsCiAgICAgICAgICAgICAgICAgICAgX1N0cmVhbShuYW1lLCBmaWxlbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpLAogICAgICAgICAgICAgICAgICAgICoqa3dhcmdzKQogICAgICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICAgICAgcmV0dXJuIHQKCiAgICAgICAgZWxpZiBtb2RlIGluICJhdyI6CiAgICAgICAgICAgIHJldHVybiBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKCiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5kaXNjZXJuaWJsZSBtb2RlIikKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiB0YXJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGd6b3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gZ3ppcCBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3JyIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IGd6aXAKICAgICAgICAgICAgZ3ppcC5HemlwRmlsZQogICAgICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiZ3ppcCBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IGJsdG5fb3BlbihuYW1lLCBtb2RlICsgImIiKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3BlbihuYW1lLCBtb2RlLAogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKSwKICAgICAgICAgICAgICAgICoqa3dhcmdzKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBiejJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05LCAqKmt3YXJncyk6CiAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3Jy4iKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiejIKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlb2JqID0gYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKICAgICAgICBleGNlcHQgKElPRXJyb3IsIEVPRkVycm9yKToKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBiemlwMiBmaWxlIikKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgICMgQWxsICpvcGVuKCkgbWV0aG9kcyBhcmUgcmVnaXN0ZXJlZCBoZXJlLgogICAgT1BFTl9NRVRIID0gewogICAgICAgICJ0YXIiOiAidGFyb3BlbiIsICAgIyB1bmNvbXByZXNzZWQgdGFyCiAgICAgICAgImd6IjogICJnem9wZW4iLCAgICAjIGd6aXAgY29tcHJlc3NlZCB0YXIKICAgICAgICAiYnoyIjogImJ6Mm9wZW4iICAgICMgYnppcDIgY29tcHJlc3NlZCB0YXIKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgVGhlIHB1YmxpYyBtZXRob2RzIHdoaWNoIFRhckZpbGUgcHJvdmlkZXM6CgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBUYXJGaWxlLiBJbiB3cml0ZS1tb2RlLCB0d28gZmluaXNoaW5nIHplcm8gYmxvY2tzIGFyZQogICAgICAgICAgIGFwcGVuZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlIGluICJhdyI6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFICogMikpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQogICAgICAgICAgICAjIGZpbGwgdXAgdGhlIGVuZCB3aXRoIHplcm8tYmxvY2tzCiAgICAgICAgICAgICMgKGxpa2Ugb3B0aW9uIC1iMjAgZm9yIHRhciBkb2VzKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoUkVDT1JEU0laRSAtIHJlbWFpbmRlcikpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBnZXRtZW1iZXIoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlCiAgICAgICAgICAgZm91bmQgaW4gdGhlIGFyY2hpdmUsIEtleUVycm9yIGlzIHJhaXNlZC4gSWYgYSBtZW1iZXIgb2NjdXJzIG1vcmUKICAgICAgICAgICB0aGFuIG9uY2UgaW4gdGhlIGFyY2hpdmUsIGl0cyBsYXN0IG9jY3VycmVuY2UgaXMgYXNzdW1lZCB0byBiZSB0aGUKICAgICAgICAgICBtb3N0IHVwLXRvLWRhdGUgdmVyc2lvbi4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvID0gc2VsZi5fZ2V0bWVtYmVyKG5hbWUpCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBLZXlFcnJvcigiZmlsZW5hbWUgJXIgbm90IGZvdW5kIiAlIG5hbWUpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgZ2V0bWVtYmVycyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIFRhckluZm8gb2JqZWN0cy4gVGhlCiAgICAgICAgICAgbGlzdCBoYXMgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG1lbWJlcnMgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6ICAgICMgaWYgd2Ugd2FudCB0byBvYnRhaW4gYSBsaXN0IG9mCiAgICAgICAgICAgIHNlbGYuX2xvYWQoKSAgICAgICAgIyBhbGwgbWVtYmVycywgd2UgZmlyc3QgaGF2ZSB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2NhbiB0aGUgd2hvbGUgYXJjaGl2ZS4KICAgICAgICByZXR1cm4gc2VsZi5tZW1iZXJzCgogICAgZGVmIGdldG5hbWVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgdGhlaXIgbmFtZXMuIEl0IGhhcwogICAgICAgICAgIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gW3RhcmluZm8ubmFtZSBmb3IgdGFyaW5mbyBpbiBzZWxmLmdldG1lbWJlcnMoKV0KCiAgICBkZWYgZ2V0dGFyaW5mbyhzZWxmLCBuYW1lPU5vbmUsIGFyY25hbWU9Tm9uZSwgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmb3IgZWl0aGVyIHRoZSBmaWxlIGBuYW1lJyBvciB0aGUgZmlsZQogICAgICAgICAgIG9iamVjdCBgZmlsZW9iaicgKHVzaW5nIG9zLmZzdGF0IG9uIGl0cyBmaWxlIGRlc2NyaXB0b3IpLiBZb3UgY2FuCiAgICAgICAgICAgbW9kaWZ5IHNvbWUgb2YgdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGJlZm9yZSB5b3UgYWRkIGl0IHVzaW5nCiAgICAgICAgICAgYWRkZmlsZSgpLiBJZiBnaXZlbiwgYGFyY25hbWUnIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUKICAgICAgICAgICBmaWxlIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQoKICAgICAgICAjIEJ1aWxkaW5nIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4KICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpCiAgICAgICAgYXJjbmFtZSA9IGFyY25hbWUucmVwbGFjZShvcy5zZXAsICIvIikKICAgICAgICBhcmNuYW1lID0gYXJjbmFtZS5sc3RyaXAoIi8iKQoKICAgICAgICAjIE5vdywgZmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aAogICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmluZm8oKQogICAgICAgIHRhcmluZm8udGFyZmlsZSA9IHNlbGYKCiAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtCiAgICAgICAgIyBhbmQgaWYgc3ltbGlua3Mgc2hhbGwgYmUgcmVzb2x2ZWQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3MubHN0YXQobmFtZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmZzdGF0KGZpbGVvYmouZmlsZW5vKCkpCiAgICAgICAgbGlua25hbWUgPSAiIgoKICAgICAgICBzdG1kID0gc3RhdHJlcy5zdF9tb2RlCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICBpbm9kZSA9IChzdGF0cmVzLnN0X2lubywgc3RhdHJlcy5zdF9kZXYpCiAgICAgICAgICAgIGlmIG5vdCBzZWxmLmRlcmVmZXJlbmNlIGFuZCBzdGF0cmVzLnN0X25saW5rID4gMSBhbmQgXAogICAgICAgICAgICAgICAgICAgIGlub2RlIGluIHNlbGYuaW5vZGVzIGFuZCBhcmNuYW1lICE9IHNlbGYuaW5vZGVzW2lub2RlXToKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTRklGTyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IEZJRk9UWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNMTksoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBTWU1UWVBFCiAgICAgICAgICAgIGxpbmtuYW1lID0gb3MucmVhZGxpbmsobmFtZSkKICAgICAgICBlbGlmIHN0YXQuU19JU0NIUihzdG1kKToKICAgICAgICAgICAgdHlwZSA9IENIUlRZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0JMSyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IEJMS1RZUEUKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAjIEZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGggYWxsCiAgICAgICAgIyBpbmZvcm1hdGlvbiB3ZSBjYW4gZ2V0LgogICAgICAgIHRhcmluZm8ubmFtZSA9IGFyY25hbWUKICAgICAgICB0YXJpbmZvLm1vZGUgPSBzdG1kCiAgICAgICAgdGFyaW5mby51aWQgPSBzdGF0cmVzLnN0X3VpZAogICAgICAgIHRhcmluZm8uZ2lkID0gc3RhdHJlcy5zdF9naWQKICAgICAgICBpZiB0eXBlID09IFJFR1RZUEU6CiAgICAgICAgICAgIHRhcmluZm8uc2l6ZSA9IHN0YXRyZXMuc3Rfc2l6ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8uc2l6ZSA9IDBMCiAgICAgICAgdGFyaW5mby5tdGltZSA9IHN0YXRyZXMuc3RfbXRpbWUKICAgICAgICB0YXJpbmZvLnR5cGUgPSB0eXBlCiAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IGxpbmtuYW1lCiAgICAgICAgaWYgcHdkOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvLnVuYW1lID0gcHdkLmdldHB3dWlkKHRhcmluZm8udWlkKVswXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgaWYgZ3JwOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVswXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGlmIHR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUpOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibWFqb3IiKSBhbmQgaGFzYXR0cihvcywgIm1pbm9yIik6CiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gb3MubWFqb3Ioc3RhdHJlcy5zdF9yZGV2KQogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtaW5vciA9IG9zLm1pbm9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiBsaXN0KHNlbGYsIHZlcmJvc2U9VHJ1ZSk6CiAgICAgICAgIiIiUHJpbnQgYSB0YWJsZSBvZiBjb250ZW50cyB0byBzeXMuc3Rkb3V0LiBJZiBgdmVyYm9zZScgaXMgRmFsc2UsIG9ubHkKICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIG1lbWJlcnMgYXJlIHByaW50ZWQuIElmIGl0IGlzIFRydWUsIGFuIGBscyAtbCctbGlrZQogICAgICAgICAgIG91dHB1dCBpcyBwcm9kdWNlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygpCgogICAgICAgIGZvciB0YXJpbmZvIGluIHNlbGY6CiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludCBmaWxlbW9kZSh0YXJpbmZvLm1vZGUpLAogICAgICAgICAgICAgICAgcHJpbnQgIiVzLyVzIiAlICh0YXJpbmZvLnVuYW1lIG9yIHRhcmluZm8udWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lIG9yIHRhcmluZm8uZ2lkKSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMHMiICUgKCIlZCwlZCIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlICh0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSksCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBkIiAlIHRhcmluZm8uc2l6ZSwKICAgICAgICAgICAgICAgIHByaW50ICIlZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiIFwKICAgICAgICAgICAgICAgICAgICAgICUgdGltZS5sb2NhbHRpbWUodGFyaW5mby5tdGltZSlbOjZdLAoKICAgICAgICAgICAgcHJpbnQgdGFyaW5mby5uYW1lICsgKCIvIiBpZiB0YXJpbmZvLmlzZGlyKCkgZWxzZSAiIiksCgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICItPiIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgImxpbmsgdG8iLCB0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICBwcmludAoKICAgIGRlZiBhZGQoc2VsZiwgbmFtZSwgYXJjbmFtZT1Ob25lLCByZWN1cnNpdmU9VHJ1ZSwgZXhjbHVkZT1Ob25lLCBmaWx0ZXI9Tm9uZSk6CiAgICAgICAgIiIiQWRkIHRoZSBmaWxlIGBuYW1lJyB0byB0aGUgYXJjaGl2ZS4gYG5hbWUnIG1heSBiZSBhbnkgdHlwZSBvZiBmaWxlCiAgICAgICAgICAgKGRpcmVjdG9yeSwgZmlmbywgc3ltYm9saWMgbGluaywgZXRjLikuIElmIGdpdmVuLCBgYXJjbmFtZScKICAgICAgICAgICBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgRGlyZWN0b3JpZXMgYXJlIGFkZGVkIHJlY3Vyc2l2ZWx5IGJ5IGRlZmF1bHQuIFRoaXMgY2FuIGJlIGF2b2lkZWQgYnkKICAgICAgICAgICBzZXR0aW5nIGByZWN1cnNpdmUnIHRvIEZhbHNlLiBgZXhjbHVkZScgaXMgYSBmdW5jdGlvbiB0aGF0IHNob3VsZAogICAgICAgICAgIHJldHVybiBUcnVlIGZvciBlYWNoIGZpbGVuYW1lIHRvIGJlIGV4Y2x1ZGVkLiBgZmlsdGVyJyBpcyBhIGZ1bmN0aW9uCiAgICAgICAgICAgdGhhdCBleHBlY3RzIGEgVGFySW5mbyBvYmplY3QgYXJndW1lbnQgYW5kIHJldHVybnMgdGhlIGNoYW5nZWQKICAgICAgICAgICBUYXJJbmZvIG9iamVjdCwgaWYgaXQgcmV0dXJucyBOb25lIHRoZSBUYXJJbmZvIG9iamVjdCB3aWxsIGJlCiAgICAgICAgICAgZXhjbHVkZWQgZnJvbSB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCgogICAgICAgICMgRXhjbHVkZSBwYXRobmFtZXMuCiAgICAgICAgaWYgZXhjbHVkZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgaW1wb3J0IHdhcm5pbmdzCiAgICAgICAgICAgIHdhcm5pbmdzLndhcm4oInVzZSB0aGUgZmlsdGVyIGFyZ3VtZW50IGluc3RlYWQiLAogICAgICAgICAgICAgICAgICAgIERlcHJlY2F0aW9uV2FybmluZywgMikKICAgICAgICAgICAgaWYgZXhjbHVkZShuYW1lKToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogRXhjbHVkZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IHNlbGYubmFtZToKICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBTa2lwcGVkICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkKCiAgICAgICAgIyBDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQ2hhbmdlIG9yIGV4Y2x1ZGUgdGhlIFRhckluZm8gb2JqZWN0LgogICAgICAgIGlmIGZpbHRlciBpcyBub3QgTm9uZToKICAgICAgICAgICAgdGFyaW5mbyA9IGZpbHRlcih0YXJpbmZvKQogICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IEV4Y2x1ZGVkICVyIiAlIG5hbWUpCiAgICAgICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBBcHBlbmQgdGhlIHRhciBoZWFkZXIgYW5kIGRhdGEgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICB3aXRoIGJsdG5fb3BlbihuYW1lLCAicmIiKSBhcyBmOgogICAgICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8sIGYpCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChvcy5wYXRoLmpvaW4obmFtZSwgZiksIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZSwgZXhjbHVkZSwgZmlsdGVyKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKCiAgICBkZWYgYWRkZmlsZShzZWxmLCB0YXJpbmZvLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkFkZCB0aGUgVGFySW5mbyBvYmplY3QgYHRhcmluZm8nIHRvIHRoZSBhcmNoaXZlLiBJZiBgZmlsZW9iaicgaXMKICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICAgIFlvdSBjYW4gY3JlYXRlIFRhckluZm8gb2JqZWN0cyB1c2luZyBnZXR0YXJpbmZvKCkuCiAgICAgICAgICAgT24gV2luZG93cyBwbGF0Zm9ybXMsIGBmaWxlb2JqJyBzaG91bGQgYWx3YXlzIGJlIG9wZW5lZCB3aXRoIG1vZGUKICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoc2VsZi5mb3JtYXQsIHNlbGYuZW5jb2RpbmcsIHNlbGYuZXJyb3JzKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShidWYpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikKCiAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToKICAgICAgICAiIiJFeHRyYWN0IGFsbCBtZW1iZXJzIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZwogICAgICAgICAgIGRpcmVjdG9yeSBhbmQgc2V0IG93bmVyLCBtb2RpZmljYXRpb24gdGltZSBhbmQgcGVybWlzc2lvbnMgb24KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQogICAgICAgICAgIHRvIGV4dHJhY3QgdG8uIGBtZW1iZXJzJyBpcyBvcHRpb25hbCBhbmQgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUKICAgICAgICAgICBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICBkaXJlY3RvcmllcyA9IFtdCgogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAgICAgIyBFeHRyYWN0IGRpcmVjdG9yaWVzIHdpdGggYSBzYWZlIG1vZGUuCiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5hcHBlbmQodGFyaW5mbykKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBjb3B5LmNvcHkodGFyaW5mbykKICAgICAgICAgICAgICAgIHRhcmluZm8ubW9kZSA9IDA3MDAKICAgICAgICAgICAgc2VsZi5leHRyYWN0KHRhcmluZm8sIHBhdGgpCgogICAgICAgICMgUmV2ZXJzZSBzb3J0IGRpcmVjdG9yaWVzLgogICAgICAgIGRpcmVjdG9yaWVzLnNvcnQoa2V5PW9wZXJhdG9yLmF0dHJnZXR0ZXIoJ25hbWUnKSkKICAgICAgICBkaXJlY3Rvcmllcy5yZXZlcnNlKCkKCiAgICAgICAgIyBTZXQgY29ycmVjdCBvd25lciwgbXRpbWUgYW5kIGZpbGVtb2RlIG9uIGRpcmVjdG9yaWVzLgogICAgICAgIGZvciB0YXJpbmZvIGluIGRpcmVjdG9yaWVzOgogICAgICAgICAgICBkaXJwYXRoID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yLCBlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3Qoc2VsZiwgbWVtYmVyLCBwYXRoPSIiKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksCiAgICAgICAgICAgdXNpbmcgaXRzIGZ1bGwgbmFtZS4gSXRzIGZpbGUgaW5mb3JtYXRpb24gaXMgZXh0cmFjdGVkIGFzIGFjY3VyYXRlbHkKICAgICAgICAgICBhcyBwb3NzaWJsZS4gYG1lbWJlcicgbWF5IGJlIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gWW91IGNhbgogICAgICAgICAgIHNwZWNpZnkgYSBkaWZmZXJlbnQgZGlyZWN0b3J5IHVzaW5nIGBwYXRoJy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBiYXNlc3RyaW5nKToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCgogICAgICAgICMgUHJlcGFyZSB0aGUgbGluayB0YXJnZXQgZm9yIG1ha2VsaW5rKCkuCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICB0YXJpbmZvLl9saW5rX3RhcmdldCA9IG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLmxpbmtuYW1lKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHRhcmluZm8sIG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAwOgogICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIGUuZmlsZW5hbWUgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUuc3RyZXJyb3IpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMgJXIiICUgKGUuc3RyZXJyb3IsIGUuZmlsZW5hbWUpKQogICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0ZmlsZShzZWxmLCBtZW1iZXIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSBhcyBhIGZpbGUgb2JqZWN0LiBgbWVtYmVyJyBtYXkgYmUKICAgICAgICAgICBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIElmIGBtZW1iZXInIGlzIGEgcmVndWxhciBmaWxlLCBhCiAgICAgICAgICAgZmlsZS1saWtlIG9iamVjdCBpcyByZXR1cm5lZC4gSWYgYG1lbWJlcicgaXMgYSBsaW5rLCBhIGZpbGUtbGlrZQogICAgICAgICAgIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBsaW5rJ3MgdGFyZ2V0LiBJZiBgbWVtYmVyJyBpcyBub25lIG9mCiAgICAgICAgICAgdGhlIGFib3ZlLCBOb25lIGlzIHJldHVybmVkLgogICAgICAgICAgIFRoZSBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJlYWQtb25seSBhbmQgcHJvdmlkZXMgdGhlIGZvbGxvd2luZwogICAgICAgICAgIG1ldGhvZHM6IHJlYWQoKSwgcmVhZGxpbmUoKSwgcmVhZGxpbmVzKCksIHNlZWsoKSBhbmQgdGVsbCgpCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgYmFzZXN0cmluZyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBJZiBhIG1lbWJlcidzIHR5cGUgaXMgdW5rbm93biwgaXQgaXMgdHJlYXRlZCBhcyBhCiAgICAgICAgICAgICMgcmVndWxhciBmaWxlLgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLmZpbGVvYmosIF9TdHJlYW0pOgogICAgICAgICAgICAgICAgIyBBIHNtYWxsIGJ1dCB1Z2x5IHdvcmthcm91bmQgZm9yIHRoZSBjYXNlIHRoYXQgc29tZW9uZSB0cmllcwogICAgICAgICAgICAgICAgIyB0byBleHRyYWN0IGEgKHN5bSlsaW5rIGFzIGEgZmlsZS1vYmplY3QgZnJvbSBhIG5vbi1zZWVrYWJsZQogICAgICAgICAgICAgICAgIyBzdHJlYW0gb2YgdGFyIGJsb2Nrcy4KICAgICAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBBIChzeW0pbGluaydzIGZpbGUgb2JqZWN0IGlzIGl0cyB0YXJnZXQncyBmaWxlIG9iamVjdC4KICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoLnJzdHJpcCgiLyIpCiAgICAgICAgdGFyZ2V0cGF0aCA9IHRhcmdldHBhdGgucmVwbGFjZSgiLyIsIG9zLnNlcCkKCiAgICAgICAgIyBDcmVhdGUgYWxsIHVwcGVyIGRpcmVjdG9yaWVzLgogICAgICAgIHVwcGVyZGlycyA9IG9zLnBhdGguZGlybmFtZSh0YXJnZXRwYXRoKQogICAgICAgIGlmIHVwcGVyZGlycyBhbmQgbm90IG9zLnBhdGguZXhpc3RzKHVwcGVyZGlycyk6CiAgICAgICAgICAgICMgQ3JlYXRlIGRpcmVjdG9yaWVzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBhcmNoaXZlIHdpdGgKICAgICAgICAgICAgIyBkZWZhdWx0IHBlcm1pc3Npb25zLgogICAgICAgICAgICBvcy5tYWtlZGlycyh1cHBlcmRpcnMpCgogICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAiJXMgLT4gJXMiICUgKHRhcmluZm8ubmFtZSwgdGFyaW5mby5saW5rbmFtZSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsIHRhcmluZm8ubmFtZSkKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRpcih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2ZpZm8oKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlmbyh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGV2KHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLm1ha2VsaW5rKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgc2VsZi5tYWtldW5rbm93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGlmIG5vdCB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGRpZmZlcmVudCBmaWxlIG1ldGhvZHMuIFRoZXkgYXJlIGNhbGxlZCB2aWEKICAgICMgX2V4dHJhY3RfbWVtYmVyKCkgd2hlbiBleHRyYWN0KCkgaXMgY2FsbGVkLiBUaGV5IGNhbiBiZSByZXBsYWNlZCBpbiBhCiAgICAjIHN1YmNsYXNzIHRvIGltcGxlbWVudCBvdGhlciBmdW5jdGlvbmFsaXR5LgoKICAgIGRlZiBtYWtlZGlyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBkaXJlY3RvcnkgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIFVzZSBhIHNhZmUgbW9kZSBmb3IgdGhlIGRpcmVjdG9yeSwgdGhlIHJlYWwgbW9kZSBpcyBzZXQKICAgICAgICAgICAgIyBsYXRlciBpbiBfZXh0cmFjdF9tZW1iZXIoKS4KICAgICAgICAgICAgb3MubWtkaXIodGFyZ2V0cGF0aCwgMDcwMCkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIGJsdG5fb3Blbih0YXJnZXRwYXRoLCAid2IiKSBhcyB0YXJnZXQ6CiAgICAgICAgICAgICAgICBjb3B5ZmlsZW9iaihzb3VyY2UsIHRhcmdldCkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBzb3VyY2UuY2xvc2UoKQoKICAgIGRlZiBtYWtldW5rbm93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKICAgICAgICAgICBhdCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwKICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCBhcyByZWd1bGFyIGZpbGUuIiAlIHRhcmluZm8udHlwZSkKCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpZm8gY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOgogICAgICAgICAgICBvcy5ta2ZpZm8odGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkJMSwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSCgogICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkKCiAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQKICAgICAgICAgIChwbGF0Zm9ybSBsaW1pdGF0aW9uKSwgd2UgdHJ5IHRvIG1ha2UgYSBjb3B5IG9mIHRoZSByZWZlcmVuY2VkIGZpbGUKICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICJzeW1saW5rIikgYW5kIGhhc2F0dHIob3MsICJsaW5rIik6CiAgICAgICAgICAgICMgRm9yIHN5c3RlbXMgdGhhdCBzdXBwb3J0IHN5bWJvbGljIGFuZCBoYXJkIGxpbmtzLgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0cGF0aCk6CiAgICAgICAgICAgICAgICAgICAgb3MudW5saW5rKHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKHRhcmluZm8ubGlua25hbWUsIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFNlZSBleHRyYWN0KCkuCiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh0YXJpbmZvLl9saW5rX3RhcmdldCk6CiAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5sZXhpc3RzKHRhcmdldHBhdGgpOgogICAgICAgICAgICAgICAgICAgICAgICBvcy51bmxpbmsodGFyZ2V0cGF0aCkKICAgICAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcihzZWxmLl9maW5kX2xpbmtfdGFyZ2V0KHRhcmluZm8pLCB0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbyksIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigidW5hYmxlIHRvIHJlc29sdmUgbGluayBpbnNpZGUgYXJjaGl2ZSIpCgogICAgZGVmIGNob3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBvd25lciBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIHB3ZCBhbmQgaGFzYXR0cihvcywgImdldGV1aWQiKSBhbmQgb3MuZ2V0ZXVpZCgpID09IDA6CiAgICAgICAgICAgICMgV2UgaGF2ZSB0byBiZSByb290IHRvIGRvIHNvLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdybmFtKHRhcmluZm8uZ25hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIGcgPSB0YXJpbmZvLmdpZAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3bmFtKHRhcmluZm8udW5hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHUgPSB0YXJpbmZvLnVpZAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCkgYW5kIGhhc2F0dHIob3MsICJsY2hvd24iKToKICAgICAgICAgICAgICAgICAgICBvcy5sY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICJvczJlbXgiOgogICAgICAgICAgICAgICAgICAgICAgICBvcy5jaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBvd25lciIpCgogICAgZGVmIGNobW9kKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBmaWxlIHBlcm1pc3Npb25zIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgJ2NobW9kJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLmNobW9kKHRhcmdldHBhdGgsIHRhcmluZm8ubW9kZSkKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2UgbW9kZSIpCgogICAgZGVmIHV0aW1lKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBtb2RpZmljYXRpb24gdGltZSBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAndXRpbWUnKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgbWVtYmVyIG9mIHRoZSBhcmNoaXZlIGFzIGEgVGFySW5mbyBvYmplY3QsIHdoZW4KICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQogICAgICAgICAgIGF2YWlsYWJsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygicmEiKQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG0gPSBzZWxmLmZpcnN0bWVtYmVyCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBtCgogICAgICAgICMgUmVhZCB0aGUgbmV4dCBibG9jay4KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkKICAgICAgICB0YXJpbmZvID0gTm9uZQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmluZm8uZnJvbXRhcmZpbGUoc2VsZikKICAgICAgICAgICAgZXhjZXB0IEVPRkhlYWRlckVycm9yLCBlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5pZ25vcmVfemVyb3M6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICIweCVYOiAlcyIgJSAoc2VsZi5vZmZzZXQsIGUpKQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGV4Y2VwdCBJbnZhbGlkSGVhZGVyRXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmlnbm9yZV96ZXJvczoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgIjB4JVg6ICVzIiAlIChzZWxmLm9mZnNldCwgZSkpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGVsaWYgc2VsZi5vZmZzZXQgPT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3Ioc3RyKGUpKQogICAgICAgICAgICBleGNlcHQgRW1wdHlIZWFkZXJFcnJvcjoKICAgICAgICAgICAgICAgIGlmIHNlbGYub2Zmc2V0ID09IDA6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJlbXB0eSBmaWxlIikKICAgICAgICAgICAgZXhjZXB0IFRydW5jYXRlZEhlYWRlckVycm9yLCBlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5vZmZzZXQgPT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3Ioc3RyKGUpKQogICAgICAgICAgICBleGNlcHQgU3Vic2VxdWVudEhlYWRlckVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKHN0cihlKSkKICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgTGl0dGxlIGhlbHBlciBtZXRob2RzOgoKICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSwgbm9ybWFsaXplPUZhbHNlKToKICAgICAgICAiIiJGaW5kIGFuIGFyY2hpdmUgbWVtYmVyIGJ5IG5hbWUgZnJvbSBib3R0b20gdG8gdG9wLgogICAgICAgICAgIElmIHRhcmluZm8gaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50LgogICAgICAgICIiIgogICAgICAgICMgRW5zdXJlIHRoYXQgYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIGxvYWRlZC4KICAgICAgICBtZW1iZXJzID0gc2VsZi5nZXRtZW1iZXJzKCkKCiAgICAgICAgIyBMaW1pdCB0aGUgbWVtYmVyIHNlYXJjaCBsaXN0IHVwIHRvIHRhcmluZm8uCiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IG1lbWJlcnNbOm1lbWJlcnMuaW5kZXgodGFyaW5mbyldCgogICAgICAgIGlmIG5vcm1hbGl6ZToKICAgICAgICAgICAgbmFtZSA9IG9zLnBhdGgubm9ybXBhdGgobmFtZSkKCiAgICAgICAgZm9yIG1lbWJlciBpbiByZXZlcnNlZChtZW1iZXJzKToKICAgICAgICAgICAgaWYgbm9ybWFsaXplOgogICAgICAgICAgICAgICAgbWVtYmVyX25hbWUgPSBvcy5wYXRoLm5vcm1wYXRoKG1lbWJlci5uYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgbWVtYmVyX25hbWUgPSBtZW1iZXIubmFtZQoKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJfbmFtZToKICAgICAgICAgICAgICAgIHJldHVybiBtZW1iZXIKCiAgICBkZWYgX2xvYWQoc2VsZik6CiAgICAgICAgIiIiUmVhZCB0aHJvdWdoIHRoZSBlbnRpcmUgYXJjaGl2ZSBmaWxlIGFuZCBsb29rIGZvciByZWFkYWJsZQogICAgICAgICAgIG1lbWJlcnMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgIGRlZiBfY2hlY2soc2VsZiwgbW9kZT1Ob25lKToKICAgICAgICAiIiJDaGVjayBpZiBUYXJGaWxlIGlzIHN0aWxsIG9wZW4sIGFuZCBpZiB0aGUgb3BlcmF0aW9uJ3MgbW9kZQogICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIFRhckZpbGUncyBtb2RlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18pCiAgICAgICAgaWYgbW9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5tb2RlIG5vdCBpbiBtb2RlOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJiYWQgb3BlcmF0aW9uIGZvciBtb2RlICVyIiAlIHNlbGYubW9kZSkKCiAgICBkZWYgX2ZpbmRfbGlua190YXJnZXQoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiRmluZCB0aGUgdGFyZ2V0IG1lbWJlciBvZiBhIHN5bWxpbmsgb3IgaGFyZGxpbmsgbWVtYmVyIGluIHRoZQogICAgICAgICAgIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAjIEFsd2F5cyBzZWFyY2ggdGhlIGVudGlyZSBhcmNoaXZlLgogICAgICAgICAgICBsaW5rbmFtZSA9ICIvIi5qb2luKGZpbHRlcihOb25lLCAob3MucGF0aC5kaXJuYW1lKHRhcmluZm8ubmFtZSksIHRhcmluZm8ubGlua25hbWUpKSkKICAgICAgICAgICAgbGltaXQgPSBOb25lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBTZWFyY2ggdGhlIGFyY2hpdmUgYmVmb3JlIHRoZSBsaW5rLCBiZWNhdXNlIGEgaGFyZCBsaW5rIGlzCiAgICAgICAgICAgICMganVzdCBhIHJlZmVyZW5jZSB0byBhbiBhbHJlYWR5IGFyY2hpdmVkIGZpbGUuCiAgICAgICAgICAgIGxpbmtuYW1lID0gdGFyaW5mby5saW5rbmFtZQogICAgICAgICAgICBsaW1pdCA9IHRhcmluZm8KCiAgICAgICAgbWVtYmVyID0gc2VsZi5fZ2V0bWVtYmVyKGxpbmtuYW1lLCB0YXJpbmZvPWxpbWl0LCBub3JtYWxpemU9VHJ1ZSkKICAgICAgICBpZiBtZW1iZXIgaXMgTm9uZToKICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoImxpbmtuYW1lICVyIG5vdCBmb3VuZCIgJSBsaW5rbmFtZSkKICAgICAgICByZXR1cm4gbWVtYmVyCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlByb3ZpZGUgYW4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuX2xvYWRlZDoKICAgICAgICAgICAgcmV0dXJuIGl0ZXIoc2VsZi5tZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBUYXJJdGVyKHNlbGYpCgogICAgZGVmIF9kYmcoc2VsZiwgbGV2ZWwsIG1zZyk6CiAgICAgICAgIiIiV3JpdGUgZGVidWdnaW5nIG91dHB1dCB0byBzeXMuc3RkZXJyLgogICAgICAgICIiIgogICAgICAgIGlmIGxldmVsIDw9IHNlbGYuZGVidWc6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwoKICAgIGRlZiBfX2VudGVyX18oc2VsZik6CiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9fZXhpdF9fKHNlbGYsIHR5cGUsIHZhbHVlLCB0cmFjZWJhY2spOgogICAgICAgIGlmIHR5cGUgaXMgTm9uZToKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBBbiBleGNlcHRpb24gb2NjdXJyZWQuIFdlIG11c3Qgbm90IGNhbGwgY2xvc2UoKSBiZWNhdXNlCiAgICAgICAgICAgICMgaXQgd291bGQgdHJ5IHRvIHdyaXRlIGVuZC1vZi1hcmNoaXZlIGJsb2NrcyBhbmQgcGFkZGluZy4KICAgICAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgICAgIHNlbGYuaW5kZXggPSAwCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4KICAgICAgICAiIiIKICAgICAgICAjIEZpeCBmb3IgU0YgIzExMDA0Mjk6IFVuZGVyIHJhcmUgY2lyY3Vtc3RhbmNlcyBpdCBjYW4KICAgICAgICAjIGhhcHBlbiB0aGF0IGdldG1lbWJlcnMoKSBpcyBjYWxsZWQgZHVyaW5nIGl0ZXJhdGlvbiwKICAgICAgICAjIHdoaWNoIHdpbGwgY2F1c2UgVGFySXRlciB0byBzdG9wIHByZW1hdHVyZWx5LgoKICAgICAgICBpZiBzZWxmLmluZGV4ID09IDAgYW5kIHNlbGYudGFyZmlsZS5maXJzdG1lbWJlciBpcyBub3QgTm9uZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICBlbGlmIHNlbGYuaW5kZXggPCBsZW4oc2VsZi50YXJmaWxlLm1lbWJlcnMpOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm1lbWJlcnNbc2VsZi5pbmRleF0KICAgICAgICBlbGlmIG5vdCBzZWxmLnRhcmZpbGUuX2xvYWRlZDoKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IHRhcmluZm86CiAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuX2xvYWRlZCA9IFRydWUKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgc2VsZi5pbmRleCArPSAxCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiMgSGVscGVyIGNsYXNzZXMgZm9yIHNwYXJzZSBmaWxlIHN1cHBvcnQKY2xhc3MgX3NlY3Rpb246CiAgICAiIiJCYXNlIGNsYXNzIGZvciBfZGF0YSBhbmQgX2hvbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpOgogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgZGVmIF9fY29udGFpbnNfXyhzZWxmLCBvZmZzZXQpOgogICAgICAgIHJldHVybiBzZWxmLm9mZnNldCA8PSBvZmZzZXQgPCBzZWxmLm9mZnNldCArIHNlbGYuc2l6ZQoKY2xhc3MgX2RhdGEoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgZGF0YSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUsIHJlYWxwb3MpOgogICAgICAgIF9zZWN0aW9uLl9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSkKICAgICAgICBzZWxmLnJlYWxwb3MgPSByZWFscG9zCgpjbGFzcyBfaG9sZShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBob2xlIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgcGFzcwoKY2xhc3MgX3JpbmdidWZmZXIobGlzdCk6CiAgICAiIiJSaW5nYnVmZmVyIGNsYXNzIHdoaWNoIGluY3JlYXNlcyBwZXJmb3JtYW5jZQogICAgICAgb3ZlciBhIHJlZ3VsYXIgbGlzdC4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuaWR4ID0gMAogICAgZGVmIGZpbmQoc2VsZiwgb2Zmc2V0KToKICAgICAgICBpZHggPSBzZWxmLmlkeAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmW2lkeF0KICAgICAgICAgICAgaWYgb2Zmc2V0IGluIGl0ZW06CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZHggKz0gMQogICAgICAgICAgICBpZiBpZHggPT0gbGVuKHNlbGYpOgogICAgICAgICAgICAgICAgaWR4ID0gMAogICAgICAgICAgICBpZiBpZHggPT0gc2VsZi5pZHg6CiAgICAgICAgICAgICAgICAjIEVuZCBvZiBGaWxlCiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIHNlbGYuaWR4ID0gaWR4CiAgICAgICAgcmV0dXJuIGl0ZW0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB6aXBmaWxlIGNvbXBhdGlibGUgVGFyRmlsZSBjbGFzcwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRBUl9QTEFJTiA9IDAgICAgICAgICAgICMgemlwZmlsZS5aSVBfU1RPUkVEClRBUl9HWklQUEVEID0gOCAgICAgICAgICMgemlwZmlsZS5aSVBfREVGTEFURUQKY2xhc3MgVGFyRmlsZUNvbXBhdDoKICAgICIiIlRhckZpbGUgY2xhc3MgY29tcGF0aWJsZSB3aXRoIHN0YW5kYXJkIG1vZHVsZSB6aXBmaWxlJ3MKICAgICAgIFppcEZpbGUgY2xhc3MuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBtb2RlPSJyIiwgY29tcHJlc3Npb249VEFSX1BMQUlOKToKICAgICAgICBmcm9tIHdhcm5pbmdzIGltcG9ydCB3YXJucHkzawogICAgICAgIHdhcm5weTNrKCJ0aGUgVGFyRmlsZUNvbXBhdCBjbGFzcyBoYXMgYmVlbiByZW1vdmVkIGluIFB5dGhvbiAzLjAiLAogICAgICAgICAgICAgICAgc3RhY2tsZXZlbD0yKQogICAgICAgIGlmIGNvbXByZXNzaW9uID09IFRBUl9QTEFJTjoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS50YXJvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxpZiBjb21wcmVzc2lvbiA9PSBUQVJfR1pJUFBFRDoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS5nem9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ1bmtub3duIGNvbXByZXNzaW9uIGNvbnN0YW50IikKICAgICAgICBpZiBtb2RlWzA6MV0gPT0gInIiOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKQogICAgICAgICAgICBmb3IgbSBpbiBtZW1iZXJzOgogICAgICAgICAgICAgICAgbS5maWxlbmFtZSA9IG0ubmFtZQogICAgICAgICAgICAgICAgbS5maWxlX3NpemUgPSBtLnNpemUKICAgICAgICAgICAgICAgIG0uZGF0ZV90aW1lID0gdGltZS5nbXRpbWUobS5tdGltZSlbOjZdCiAgICBkZWYgbmFtZWxpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgbTogbS5uYW1lLCBzZWxmLmluZm9saXN0KCkpCiAgICBkZWYgaW5mb2xpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIGZpbHRlcihsYW1iZGEgbTogbS50eXBlIGluIFJFR1VMQVJfVFlQRVMsCiAgICAgICAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpKQogICAgZGVmIHByaW50ZGlyKHNlbGYpOgogICAgICAgIHNlbGYudGFyZmlsZS5saXN0KCkKICAgIGRlZiB0ZXN0emlwKHNlbGYpOgogICAgICAgIHJldHVybgogICAgZGVmIGdldGluZm8oc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkKICAgIGRlZiByZWFkKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZXh0cmFjdGZpbGUoc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKSkucmVhZCgpCiAgICBkZWYgd3JpdGUoc2VsZiwgZmlsZW5hbWUsIGFyY25hbWU9Tm9uZSwgY29tcHJlc3NfdHlwZT1Ob25lKToKICAgICAgICBzZWxmLnRhcmZpbGUuYWRkKGZpbGVuYW1lLCBhcmNuYW1lKQogICAgZGVmIHdyaXRlc3RyKHNlbGYsIHppbmZvLCBieXRlcyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBmcm9tIGNTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIGZyb20gU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgaW1wb3J0IGNhbGVuZGFyCiAgICAgICAgdGluZm8gPSBUYXJJbmZvKHppbmZvLmZpbGVuYW1lKQogICAgICAgIHRpbmZvLnNpemUgPSBsZW4oYnl0ZXMpCiAgICAgICAgdGluZm8ubXRpbWUgPSBjYWxlbmRhci50aW1lZ20oemluZm8uZGF0ZV90aW1lKQogICAgICAgIHNlbGYudGFyZmlsZS5hZGRmaWxlKHRpbmZvLCBTdHJpbmdJTyhieXRlcykpCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmNsb3NlKCkKI2NsYXNzIFRhckZpbGVDb21wYXQKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQojIGV4cG9ydGVkIGZ1bmN0aW9ucwojLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIGlzX3RhcmZpbGUobmFtZSk6CiAgICAiIiJSZXR1cm4gVHJ1ZSBpZiBuYW1lIHBvaW50cyB0byBhIHRhciBhcmNoaXZlIHRoYXQgd2UKICAgICAgIGFyZSBhYmxlIHRvIGhhbmRsZSwgZWxzZSByZXR1cm4gRmFsc2UuCiAgICAiIiIKICAgIHRyeToKICAgICAgICB0ID0gb3BlbihuYW1lKQogICAgICAgIHQuY2xvc2UoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgVGFyRXJyb3I6CiAgICAgICAgcmV0dXJuIEZhbHNlCgpibHRuX29wZW4gPSBvcGVuCm9wZW4gPSBUYXJGaWxlLm9wZW4K