IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC45LjAiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKaW1wb3J0IGNvcHkKaW1wb3J0IHJlCgppZiBzeXMucGxhdGZvcm0gPT0gJ21hYyc6CiAgICAjIFRoaXMgbW9kdWxlIG5lZWRzIHdvcmsgZm9yIE1hY09TOSwgZXNwZWNpYWxseSBpbiB0aGUgYXJlYSBvZiBwYXRobmFtZQogICAgIyBoYW5kbGluZy4gSW4gbWFueSBwbGFjZXMgaXQgaXMgYXNzdW1lZCBhIHNpbXBsZSBzdWJzdGl0dXRpb24gb2YgLyBieSB0aGUKICAgICMgbG9jYWwgb3MucGF0aC5zZXAgaXMgZ29vZCBlbm91Z2ggdG8gY29udmVydCBwYXRobmFtZXMsIGJ1dCB0aGlzIGRvZXMgbm90CiAgICAjIHdvcmsgd2l0aCB0aGUgbWFjIHJvb3RlZDpwYXRoOm5hbWUgdmVyc3VzIDpub25yb290ZWQ6cGF0aDpuYW1lIHN5bnRheAogICAgcmFpc2UgSW1wb3J0RXJyb3IsICJ0YXJmaWxlIGRvZXMgbm90IHdvcmsgZm9yIHBsYXRmb3JtPT1tYWMiCgp0cnk6CiAgICBpbXBvcnQgZ3JwLCBwd2QKZXhjZXB0IEltcG9ydEVycm9yOgogICAgZ3JwID0gcHdkID0gTm9uZQoKIyBmcm9tIHRhcmZpbGUgaW1wb3J0ICoKX19hbGxfXyA9IFsiVGFyRmlsZSIsICJUYXJJbmZvIiwgImlzX3RhcmZpbGUiLCAiVGFyRXJyb3IiXQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhciBjb25zdGFudHMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpOVUwgPSAiXDAiICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG51bGwgY2hhcmFjdGVyCkJMT0NLU0laRSA9IDUxMiAgICAgICAgICAgICAgICAgIyBsZW5ndGggb2YgcHJvY2Vzc2luZyBibG9ja3MKUkVDT1JEU0laRSA9IEJMT0NLU0laRSAqIDIwICAgICAjIGxlbmd0aCBvZiByZWNvcmRzCkdOVV9NQUdJQyA9ICJ1c3RhciAgXDAiICAgICAgICAgIyBtYWdpYyBnbnUgdGFyIHN0cmluZwpQT1NJWF9NQUdJQyA9ICJ1c3Rhclx4MDAwMCIgICAgICMgbWFnaWMgcG9zaXggdGFyIHN0cmluZwoKTEVOR1RIX05BTUUgPSAxMDAgICAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIGEgZmlsZW5hbWUKTEVOR1RIX0xJTksgPSAxMDAgICAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIGEgbGlua25hbWUKTEVOR1RIX1BSRUZJWCA9IDE1NSAgICAgICAgICAgICAjIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBwcmVmaXggZmllbGQKClJFR1RZUEUgPSAiMCIgICAgICAgICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUKQVJFR1RZUEUgPSAiXDAiICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpMTktUWVBFID0gIjEiICAgICAgICAgICAgICAgICAgICMgbGluayAoaW5zaWRlIHRhcmZpbGUpClNZTVRZUEUgPSAiMiIgICAgICAgICAgICAgICAgICAgIyBzeW1ib2xpYyBsaW5rCkNIUlRZUEUgPSAiMyIgICAgICAgICAgICAgICAgICAgIyBjaGFyYWN0ZXIgc3BlY2lhbCBkZXZpY2UKQkxLVFlQRSA9ICI0IiAgICAgICAgICAgICAgICAgICAjIGJsb2NrIHNwZWNpYWwgZGV2aWNlCkRJUlRZUEUgPSAiNSIgICAgICAgICAgICAgICAgICAgIyBkaXJlY3RvcnkKRklGT1RZUEUgPSAiNiIgICAgICAgICAgICAgICAgICAjIGZpZm8gc3BlY2lhbCBkZXZpY2UKQ09OVFRZUEUgPSAiNyIgICAgICAgICAgICAgICAgICAjIGNvbnRpZ3VvdXMgZmlsZQoKR05VVFlQRV9MT05HTkFNRSA9ICJMIiAgICAgICAgICAjIEdOVSB0YXIgbG9uZ25hbWUKR05VVFlQRV9MT05HTElOSyA9ICJLIiAgICAgICAgICAjIEdOVSB0YXIgbG9uZ2xpbmsKR05VVFlQRV9TUEFSU0UgPSAiUyIgICAgICAgICAgICAjIEdOVSB0YXIgc3BhcnNlIGZpbGUKClhIRFRZUEUgPSAieCIgICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgZXh0ZW5kZWQgaGVhZGVyClhHTFRZUEUgPSAiZyIgICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgZ2xvYmFsIGhlYWRlcgpTT0xBUklTX1hIRFRZUEUgPSAiWCIgICAgICAgICAgICMgU29sYXJpcyBleHRlbmRlZCBoZWFkZXIKClVTVEFSX0ZPUk1BVCA9IDAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTE5ODggKHVzdGFyKSBmb3JtYXQKR05VX0ZPUk1BVCA9IDEgICAgICAgICAgICAgICAgICAjIEdOVSB0YXIgZm9ybWF0ClBBWF9GT1JNQVQgPSAyICAgICAgICAgICAgICAgICAgIyBQT1NJWC4xLTIwMDEgKHBheCkgZm9ybWF0CkRFRkFVTFRfRk9STUFUID0gR05VX0ZPUk1BVAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhcmZpbGUgY29uc3RhbnRzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBGaWxlIHR5cGVzIHRoYXQgdGFyZmlsZSBzdXBwb3J0czoKU1VQUE9SVEVEX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCBMTktUWVBFLAogICAgICAgICAgICAgICAgICAgU1lNVFlQRSwgRElSVFlQRSwgRklGT1RZUEUsCiAgICAgICAgICAgICAgICAgICBDT05UVFlQRSwgQ0hSVFlQRSwgQkxLVFlQRSwKICAgICAgICAgICAgICAgICAgIEdOVVRZUEVfTE9OR05BTUUsIEdOVVRZUEVfTE9OR0xJTkssCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkKCiMgRmlsZSB0eXBlcyB0aGF0IHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KUkVHVUxBUl9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwKICAgICAgICAgICAgICAgICBDT05UVFlQRSwgR05VVFlQRV9TUEFSU0UpCgojIEZpbGUgdHlwZXMgdGhhdCBhcmUgcGFydCBvZiB0aGUgR05VIHRhciBmb3JtYXQuCkdOVV9UWVBFUyA9IChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgojIEZpZWxkcyBmcm9tIGEgcGF4IGhlYWRlciB0aGF0IG92ZXJyaWRlIGEgVGFySW5mbyBhdHRyaWJ1dGUuClBBWF9GSUVMRFMgPSAoInBhdGgiLCAibGlua3BhdGgiLCAic2l6ZSIsICJtdGltZSIsCiAgICAgICAgICAgICAgInVpZCIsICJnaWQiLCAidW5hbWUiLCAiZ25hbWUiKQoKIyBGaWVsZHMgaW4gYSBwYXggaGVhZGVyIHRoYXQgYXJlIG51bWJlcnMsIGFsbCBvdGhlciBmaWVsZHMKIyBhcmUgdHJlYXRlZCBhcyBzdHJpbmdzLgpQQVhfTlVNQkVSX0ZJRUxEUyA9IHsKICAgICJhdGltZSI6IGZsb2F0LAogICAgImN0aW1lIjogZmxvYXQsCiAgICAibXRpbWUiOiBmbG9hdCwKICAgICJ1aWQiOiBpbnQsCiAgICAiZ2lkIjogaW50LAogICAgInNpemUiOiBpbnQKfQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEJpdHMgdXNlZCBpbiB0aGUgbW9kZSBmaWVsZCwgdmFsdWVzIGluIG9jdGFsLgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNfSUZMTksgPSAwMTIwMDAwICAgICAgICAjIHN5bWJvbGljIGxpbmsKU19JRlJFRyA9IDAxMDAwMDAgICAgICAgICMgcmVndWxhciBmaWxlClNfSUZCTEsgPSAwMDYwMDAwICAgICAgICAjIGJsb2NrIGRldmljZQpTX0lGRElSID0gMDA0MDAwMCAgICAgICAgIyBkaXJlY3RvcnkKU19JRkNIUiA9IDAwMjAwMDAgICAgICAgICMgY2hhcmFjdGVyIGRldmljZQpTX0lGSUZPID0gMDAxMDAwMCAgICAgICAgIyBmaWZvCgpUU1VJRCAgID0gMDQwMDAgICAgICAgICAgIyBzZXQgVUlEIG9uIGV4ZWN1dGlvbgpUU0dJRCAgID0gMDIwMDAgICAgICAgICAgIyBzZXQgR0lEIG9uIGV4ZWN1dGlvbgpUU1ZUWCAgID0gMDEwMDAgICAgICAgICAgIyByZXNlcnZlZAoKVFVSRUFEICA9IDA0MDAgICAgICAgICAgICMgcmVhZCBieSBvd25lcgpUVVdSSVRFID0gMDIwMCAgICAgICAgICAgIyB3cml0ZSBieSBvd25lcgpUVUVYRUMgID0gMDEwMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvd25lcgpUR1JFQUQgID0gMDA0MCAgICAgICAgICAgIyByZWFkIGJ5IGdyb3VwClRHV1JJVEUgPSAwMDIwICAgICAgICAgICAjIHdyaXRlIGJ5IGdyb3VwClRHRVhFQyAgPSAwMDEwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IGdyb3VwClRPUkVBRCAgPSAwMDA0ICAgICAgICAgICAjIHJlYWQgYnkgb3RoZXIKVE9XUklURSA9IDAwMDIgICAgICAgICAgICMgd3JpdGUgYnkgb3RoZXIKVE9FWEVDICA9IDAwMDEgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3RoZXIKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBpbml0aWFsaXphdGlvbgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkVOQ09ESU5HID0gc3lzLmdldGZpbGVzeXN0ZW1lbmNvZGluZygpCmlmIEVOQ09ESU5HIGlzIE5vbmU6CiAgICBFTkNPRElORyA9IHN5cy5nZXRkZWZhdWx0ZW5jb2RpbmcoKQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNvbWUgdXNlZnVsIGZ1bmN0aW9ucwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgc3RuKHMsIGxlbmd0aCk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIHN0cmluZyB0byBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgYnVmZmVyLgogICAgIiIiCiAgICByZXR1cm4gc1s6bGVuZ3RoXSArIChsZW5ndGggLSBsZW4ocykpICogTlVMCgpkZWYgbnRzKHMpOgogICAgIiIiQ29udmVydCBhIG51bGwtdGVybWluYXRlZCBzdHJpbmcgZmllbGQgdG8gYSBweXRob24gc3RyaW5nLgogICAgIiIiCiAgICAjIFVzZSB0aGUgc3RyaW5nIHVwIHRvIHRoZSBmaXJzdCBudWxsIGNoYXIuCiAgICBwID0gcy5maW5kKCJcMCIpCiAgICBpZiBwID09IC0xOgogICAgICAgIHJldHVybiBzCiAgICByZXR1cm4gc1s6cF0KCmRlZiBudGkocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4KICAgICIiIgogICAgIyBUaGVyZSBhcmUgdHdvIHBvc3NpYmxlIGVuY29kaW5ncyBmb3IgYSBudW1iZXIgZmllbGQsIHNlZQogICAgIyBpdG4oKSBiZWxvdy4KICAgIGlmIHNbMF0gIT0gY2hyKDAyMDApOgogICAgICAgIHRyeToKICAgICAgICAgICAgbiA9IGludChudHMocykgb3IgIjAiLCA4KQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigiaW52YWxpZCBoZWFkZXIiKQogICAgZWxzZToKICAgICAgICBuID0gMEwKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UobGVuKHMpIC0gMSk6CiAgICAgICAgICAgIG4gPDw9IDgKICAgICAgICAgICAgbiArPSBvcmQoc1tpICsgMV0pCiAgICByZXR1cm4gbgoKZGVmIGl0bihuLCBkaWdpdHM9OCwgZm9ybWF0PURFRkFVTFRfRk9STUFUKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gbnVtYmVyIHRvIGEgbnVtYmVyIGZpZWxkLgogICAgIiIiCiAgICAjIFBPU0lYIDEwMDMuMS0xOTg4IHJlcXVpcmVzIG51bWJlcnMgdG8gYmUgZW5jb2RlZCBhcyBhIHN0cmluZyBvZgogICAgIyBvY3RhbCBkaWdpdHMgZm9sbG93ZWQgYnkgYSBudWxsLWJ5dGUsIHRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0bwogICAgIyAoOCoqKGRpZ2l0cy0xKSktMS4gR05VIHRhciBhbGxvd3Mgc3RvcmluZyBudW1iZXJzIGdyZWF0ZXIgdGhhbgogICAgIyB0aGF0IGlmIG5lY2Vzc2FyeS4gQSBsZWFkaW5nIDAyMDAgYnl0ZSBpbmRpY2F0ZXMgdGhpcyBwYXJ0aWN1bGFyCiAgICAjIGVuY29kaW5nLCB0aGUgZm9sbG93aW5nIGRpZ2l0cy0xIGJ5dGVzIGFyZSBhIGJpZy1lbmRpYW4KICAgICMgcmVwcmVzZW50YXRpb24uIFRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0byAoMjU2KiooZGlnaXRzLTEpKS0xLgogICAgaWYgMCA8PSBuIDwgOCAqKiAoZGlnaXRzIC0gMSk6CiAgICAgICAgcyA9ICIlMCpvIiAlIChkaWdpdHMgLSAxLCBuKSArIE5VTAogICAgZWxzZToKICAgICAgICBpZiBmb3JtYXQgIT0gR05VX0ZPUk1BVCBvciBuID49IDI1NiAqKiAoZGlnaXRzIC0gMSk6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm92ZXJmbG93IGluIG51bWJlciBmaWVsZCIpCgogICAgICAgIGlmIG4gPCAwOgogICAgICAgICAgICAjIFhYWCBXZSBtaW1pYyBHTlUgdGFyJ3MgYmVoYXZpb3VyIHdpdGggbmVnYXRpdmUgbnVtYmVycywKICAgICAgICAgICAgIyB0aGlzIGNvdWxkIHJhaXNlIE92ZXJmbG93RXJyb3IuCiAgICAgICAgICAgIG4gPSBzdHJ1Y3QudW5wYWNrKCJMIiwgc3RydWN0LnBhY2soImwiLCBuKSlbMF0KCiAgICAgICAgcyA9ICIiCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICBzID0gY2hyKG4gJiAwMzc3KSArIHMKICAgICAgICAgICAgbiA+Pj0gOAogICAgICAgIHMgPSBjaHIoMDIwMCkgKyBzCiAgICByZXR1cm4gcwoKZGVmIHV0cyhzLCBlbmNvZGluZywgZXJyb3JzKToKICAgICIiIkNvbnZlcnQgYSB1bmljb2RlIG9iamVjdCB0byBhIHN0cmluZy4KICAgICIiIgogICAgaWYgZXJyb3JzID09ICJ1dGYtOCI6CiAgICAgICAgIyBBbiBleHRyYSBlcnJvciBoYW5kbGVyIHNpbWlsYXIgdG8gdGhlIC1vIGludmFsaWQ9VVRGLTggb3B0aW9uCiAgICAgICAgIyBpbiBQT1NJWC4xLTIwMDEuIFJlcGxhY2UgdW50cmFuc2xhdGFibGUgY2hhcmFjdGVycyB3aXRoIHRoZWlyCiAgICAgICAgIyBVVEYtOCByZXByZXNlbnRhdGlvbi4KICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBzLmVuY29kZShlbmNvZGluZywgInN0cmljdCIpCiAgICAgICAgZXhjZXB0IFVuaWNvZGVFbmNvZGVFcnJvcjoKICAgICAgICAgICAgeCA9IFtdCiAgICAgICAgICAgIGZvciBjIGluIHM6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgeC5hcHBlbmQoYy5lbmNvZGUoZW5jb2RpbmcsICJzdHJpY3QiKSkKICAgICAgICAgICAgICAgIGV4Y2VwdCBVbmljb2RlRW5jb2RlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgeC5hcHBlbmQoYy5lbmNvZGUoInV0ZjgiKSkKICAgICAgICAgICAgcmV0dXJuICIiLmpvaW4oeCkKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIHMuZW5jb2RlKGVuY29kaW5nLCBlcnJvcnMpCgpkZWYgY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAiIiJDYWxjdWxhdGUgdGhlIGNoZWNrc3VtIGZvciBhIG1lbWJlcidzIGhlYWRlciBieSBzdW1taW5nIHVwIGFsbAogICAgICAgY2hhcmFjdGVycyBleGNlcHQgZm9yIHRoZSBjaGtzdW0gZmllbGQgd2hpY2ggaXMgdHJlYXRlZCBhcyBpZgogICAgICAgaXQgd2FzIGZpbGxlZCB3aXRoIHNwYWNlcy4gQWNjb3JkaW5nIHRvIHRoZSBHTlUgdGFyIHNvdXJjZXMsCiAgICAgICBzb21lIHRhcnMgKFN1biBhbmQgTmVYVCkgY2FsY3VsYXRlIGNoa3N1bSB3aXRoIHNpZ25lZCBjaGFyLAogICAgICAgd2hpY2ggd2lsbCBiZSBkaWZmZXJlbnQgaWYgdGhlcmUgYXJlIGNoYXJzIGluIHRoZSBidWZmZXIgd2l0aAogICAgICAgdGhlIGhpZ2ggYml0IHNldC4gU28gd2UgY2FsY3VsYXRlIHR3byBjaGVja3N1bXMsIHVuc2lnbmVkIGFuZAogICAgICAgc2lnbmVkLgogICAgIiIiCiAgICB1bnNpZ25lZF9jaGtzdW0gPSAyNTYgKyBzdW0oc3RydWN0LnVucGFjaygiMTQ4QiIsIGJ1Zls6MTQ4XSkgKyBzdHJ1Y3QudW5wYWNrKCIzNTZCIiwgYnVmWzE1Njo1MTJdKSkKICAgIHNpZ25lZF9jaGtzdW0gPSAyNTYgKyBzdW0oc3RydWN0LnVucGFjaygiMTQ4YiIsIGJ1Zls6MTQ4XSkgKyBzdHJ1Y3QudW5wYWNrKCIzNTZiIiwgYnVmWzE1Njo1MTJdKSkKICAgIHJldHVybiB1bnNpZ25lZF9jaGtzdW0sIHNpZ25lZF9jaGtzdW0KCmRlZiBjb3B5ZmlsZW9iaihzcmMsIGRzdCwgbGVuZ3RoPU5vbmUpOgogICAgIiIiQ29weSBsZW5ndGggYnl0ZXMgZnJvbSBmaWxlb2JqIHNyYyB0byBmaWxlb2JqIGRzdC4KICAgICAgIElmIGxlbmd0aCBpcyBOb25lLCBjb3B5IHRoZSBlbnRpcmUgY29udGVudC4KICAgICIiIgogICAgaWYgbGVuZ3RoID09IDA6CiAgICAgICAgcmV0dXJuCiAgICBpZiBsZW5ndGggaXMgTm9uZToKICAgICAgICBzaHV0aWwuY29weWZpbGVvYmooc3JjLCBkc3QpCiAgICAgICAgcmV0dXJuCgogICAgQlVGU0laRSA9IDE2ICogMTAyNAogICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuZ3RoLCBCVUZTSVpFKQogICAgZm9yIGIgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgYnVmID0gc3JjLnJlYWQoQlVGU0laRSkKICAgICAgICBpZiBsZW4oYnVmKSA8IEJVRlNJWkU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImVuZCBvZiBmaWxlIHJlYWNoZWQiKQogICAgICAgIGRzdC53cml0ZShidWYpCgogICAgaWYgcmVtYWluZGVyICE9IDA6CiAgICAgICAgYnVmID0gc3JjLnJlYWQocmVtYWluZGVyKQogICAgICAgIGlmIGxlbihidWYpIDwgcmVtYWluZGVyOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQogICAgcmV0dXJuCgpmaWxlbW9kZV90YWJsZSA9ICgKICAgICgoU19JRkxOSywgICAgICAibCIpLAogICAgIChTX0lGUkVHLCAgICAgICItIiksCiAgICAgKFNfSUZCTEssICAgICAgImIiKSwKICAgICAoU19JRkRJUiwgICAgICAiZCIpLAogICAgIChTX0lGQ0hSLCAgICAgICJjIiksCiAgICAgKFNfSUZJRk8sICAgICAgInAiKSksCgogICAgKChUVVJFQUQsICAgICAgICJyIiksKSwKICAgICgoVFVXUklURSwgICAgICAidyIpLCksCiAgICAoKFRVRVhFQ3xUU1VJRCwgInMiKSwKICAgICAoVFNVSUQsICAgICAgICAiUyIpLAogICAgIChUVUVYRUMsICAgICAgICJ4IikpLAoKICAgICgoVEdSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRHV1JJVEUsICAgICAgInciKSwpLAogICAgKChUR0VYRUN8VFNHSUQsICJzIiksCiAgICAgKFRTR0lELCAgICAgICAgIlMiKSwKICAgICAoVEdFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRPUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUT1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVE9FWEVDfFRTVlRYLCAidCIpLAogICAgIChUU1ZUWCwgICAgICAgICJUIiksCiAgICAgKFRPRVhFQywgICAgICAgIngiKSkKKQoKZGVmIGZpbGVtb2RlKG1vZGUpOgogICAgIiIiQ29udmVydCBhIGZpbGUncyBtb2RlIHRvIGEgc3RyaW5nIG9mIHRoZSBmb3JtCiAgICAgICAtcnd4cnd4cnd4LgogICAgICAgVXNlZCBieSBUYXJGaWxlLmxpc3QoKQogICAgIiIiCiAgICBwZXJtID0gW10KICAgIGZvciB0YWJsZSBpbiBmaWxlbW9kZV90YWJsZToKICAgICAgICBmb3IgYml0LCBjaGFyIGluIHRhYmxlOgogICAgICAgICAgICBpZiBtb2RlICYgYml0ID09IGJpdDoKICAgICAgICAgICAgICAgIHBlcm0uYXBwZW5kKGNoYXIpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHBlcm0uYXBwZW5kKCItIikKICAgIHJldHVybiAiIi5qb2luKHBlcm0pCgppZiBvcy5zZXAgIT0gIi8iOgogICAgbm9ybXBhdGggPSBsYW1iZGEgcGF0aDogb3MucGF0aC5ub3JtcGF0aChwYXRoKS5yZXBsYWNlKG9zLnNlcCwgIi8iKQplbHNlOgogICAgbm9ybXBhdGggPSBvcy5wYXRoLm5vcm1wYXRoCgpjbGFzcyBUYXJFcnJvcihFeGNlcHRpb24pOgogICAgIiIiQmFzZSBleGNlcHRpb24uIiIiCiAgICBwYXNzCmNsYXNzIEV4dHJhY3RFcnJvcihUYXJFcnJvcik6CiAgICAiIiJHZW5lcmFsIGV4Y2VwdGlvbiBmb3IgZXh0cmFjdCBlcnJvcnMuIiIiCiAgICBwYXNzCmNsYXNzIFJlYWRFcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVucmVhZGJsZSB0YXIgYXJjaGl2ZXMuIiIiCiAgICBwYXNzCmNsYXNzIENvbXByZXNzaW9uRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bmF2YWlsYWJsZSBjb21wcmVzc2lvbiBtZXRob2RzLiIiIgogICAgcGFzcwpjbGFzcyBTdHJlYW1FcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVuc3VwcG9ydGVkIG9wZXJhdGlvbnMgb24gc3RyZWFtLWxpa2UgVGFyRmlsZXMuIiIiCiAgICBwYXNzCmNsYXNzIEhlYWRlckVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgaW52YWxpZCBoZWFkZXJzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgICMgVGhlIG5hdGl2ZSB6bGliIGNyYyBpcyBhbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgYnV0CiAgICAgICAgICAgICAgICAjIHRoZSBQeXRob24gd3JhcHBlciBpbXBsaWNpdGx5IGNhc3RzIHRoYXQgdG8gYSBzaWduZWQgQwogICAgICAgICAgICAgICAgIyBsb25nLiAgU28sIG9uIGEgMzItYml0IGJveCBzZWxmLmNyYyBtYXkgImxvb2sgbmVnYXRpdmUiLAogICAgICAgICAgICAgICAgIyB3aGlsZSB0aGUgc2FtZSBjcmMgb24gYSA2NC1iaXQgYm94IG1heSAibG9vayBwb3NpdGl2ZSIuCiAgICAgICAgICAgICAgICAjIFRvIGF2b2lkIGlya3NvbWUgd2FybmluZ3MgZnJvbSB0aGUgYHN0cnVjdGAgbW9kdWxlLCBmb3JjZQogICAgICAgICAgICAgICAgIyBpdCB0byBsb29rIHBvc2l0aXZlIG9uIGFsbCBib3hlcy4KICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLmNyYyAmIDB4ZmZmZmZmZmZMKSkKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcyAmIDB4ZmZmZkZGRkZMKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfaW5pdF9yZWFkX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5kZWNvbXByZXNzb2JqKC1zZWxmLnpsaWIuTUFYX1dCSVRTKQogICAgICAgIHNlbGYuZGJ1ZiA9ICIiCgogICAgICAgICMgdGFrZW4gZnJvbSBnemlwLkd6aXBGaWxlIHdpdGggc29tZSBhbHRlcmF0aW9ucwogICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICBpZiBzZWxmLl9fcmVhZCgxKSAhPSAiXDAxMCI6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCIpCgogICAgICAgIGZsYWcgPSBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgc2VsZi5fX3JlYWQoNikKCiAgICAgICAgaWYgZmxhZyAmIDQ6CiAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikKICAgICAgICBpZiBmbGFnICYgODoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMTY6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDI6CiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zPTApOgogICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZwogICAgICAgICAgIGlzIGZvcmJpZGRlbi4KICAgICAgICAiIiIKICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoYmxvY2tzKToKICAgICAgICAgICAgICAgIHNlbGYucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIHNlbGYucmVhZChyZW1haW5kZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoInNlZWtpbmcgYmFja3dhcmRzIGlzIG5vdCBhbGxvd2VkIikKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBzaXplIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgICAgSWYgc2l6ZSBpcyBub3QgZGVmaW5lZCwgcmV0dXJuIGFsbCBieXRlcyBvZiB0aGUgc3RyZWFtCiAgICAgICAgICAgdXAgdG8gRU9GLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgdCA9IFtdCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYnVmID0gIiIuam9pbih0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2l6ZSkKICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gInRhciI6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQoKICAgICAgICBjID0gbGVuKHNlbGYuZGJ1ZikKICAgICAgICB0ID0gW3NlbGYuZGJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5jbXAuZGVjb21wcmVzcyhidWYpCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJpbnZhbGlkIGNvbXByZXNzZWQgZGF0YSIpCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5kYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KCiAgICBkZWYgX19yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gc3RyZWFtLiBJZiBpbnRlcm5hbCBidWZmZXIgaXMgZW1wdHksCiAgICAgICAgICAgcmVhZCBhbm90aGVyIGJsb2NrIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBjID0gbGVuKHNlbGYuYnVmKQogICAgICAgIHQgPSBbc2VsZi5idWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5idWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQojIGNsYXNzIF9TdHJlYW0KCmNsYXNzIF9TdHJlYW1Qcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICBkZXRlY3Rpb24gZm9yIHRoZSBTdHJlYW0gaW50ZXJmYWNlIChtb2RlICdyfConKS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5maWxlb2JqLnJlYWQKICAgICAgICByZXR1cm4gc2VsZi5idWYKCiAgICBkZWYgZ2V0Y29tcHR5cGUoc2VsZik6CiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiXDAzN1wyMTNcMDEwIik6CiAgICAgICAgICAgIHJldHVybiAiZ3oiCiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiQlpoOTEiKToKICAgICAgICAgICAgcmV0dXJuICJiejIiCiAgICAgICAgcmV0dXJuICJ0YXIiCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgU3RyZWFtUHJveHkKCmNsYXNzIF9CWjJQcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIGV4dGVybmFsIGZpbGUgb2JqZWN0CiAgICAgICBzdXBwb3J0IGZvciAicjpiejIiIGFuZCAidzpiejIiIG1vZGVzLiBUaGlzIGlzIGFjdHVhbGx5CiAgICAgICBhIHdvcmthcm91bmQgZm9yIGEgbGltaXRhdGlvbiBpbiBiejIgbW9kdWxlJ3MgQloyRmlsZQogICAgICAgY2xhc3Mgd2hpY2ggKHVubGlrZSBnemlwLkd6aXBGaWxlKSBoYXMgbm8gc3VwcG9ydCBmb3IKICAgICAgIGEgZmlsZSBvYmplY3QgYXJndW1lbnQuCiAgICAiIiIKCiAgICBibG9ja3NpemUgPSAxNiAqIDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgbW9kZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLm5hbWUgPSBnZXRhdHRyKHNlbGYuZmlsZW9iaiwgIm5hbWUiLCBOb25lKQogICAgICAgIHNlbGYuaW5pdCgpCgogICAgZGVmIGluaXQoc2VsZik6CiAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgIHNlbGYucG9zID0gMAogICAgICAgIGlmIHNlbGYubW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkRlY29tcHJlc3NvcigpCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKDApCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiIKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmJ6Mm9iaiA9IGJ6Mi5CWjJDb21wcmVzc29yKCkKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToKICAgICAgICBiID0gW3NlbGYuYnVmXQogICAgICAgIHggPSBsZW4oc2VsZi5idWYpCiAgICAgICAgd2hpbGUgeCA8IHNpemU6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJhdyA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYmxvY2tzaXplKQogICAgICAgICAgICAgICAgZGF0YSA9IHNlbGYuYnoyb2JqLmRlY29tcHJlc3MocmF3KQogICAgICAgICAgICAgICAgYi5hcHBlbmQoZGF0YSkKICAgICAgICAgICAgZXhjZXB0IEVPRkVycm9yOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgeCArPSBsZW4oZGF0YSkKICAgICAgICBzZWxmLmJ1ZiA9ICIiLmpvaW4oYikKCiAgICAgICAgYnVmID0gc2VsZi5idWZbOnNpemVdCiAgICAgICAgc2VsZi5idWYgPSBzZWxmLmJ1ZltzaXplOl0KICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgc2VlayhzZWxmLCBwb3MpOgogICAgICAgIGlmIHBvcyA8IHNlbGYucG9zOgogICAgICAgICAgICBzZWxmLmluaXQoKQogICAgICAgIHNlbGYucmVhZChwb3MgLSBzZWxmLnBvcykKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgd3JpdGUoc2VsZiwgZGF0YSk6CiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGRhdGEpCiAgICAgICAgcmF3ID0gc2VsZi5iejJvYmouY29tcHJlc3MoZGF0YSkKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUocmF3KQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciOgogICAgICAgICAgICByYXcgPSBzZWxmLmJ6Mm9iai5mbHVzaCgpCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpCiAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKIyBjbGFzcyBfQloyUHJveHkKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHRyYWN0aW9uIGZpbGUgb2JqZWN0CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgX0ZpbGVJbkZpbGUob2JqZWN0KToKICAgICIiIkEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhbiBleGlzdGluZyBmaWxlIG9iamVjdCB0aGF0CiAgICAgICBwcm92aWRlcyBhIHBhcnQgb2YgaXRzIGRhdGEgYXMgYW4gaW5kaXZpZHVhbCBmaWxlCiAgICAgICBvYmplY3QuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgb2Zmc2V0LCBzaXplLCBzcGFyc2U9Tm9uZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgICAgIHNlbGYuc3BhcnNlID0gc3BhcnNlCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDAKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3NpdGlvbgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvc2l0aW9uKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IHBvc2l0aW9uCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIGRhdGEgZnJvbSB0aGUgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHNpemUgPSBzZWxmLnNpemUgLSBzZWxmLnBvc2l0aW9uCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWxmLnNpemUgLSBzZWxmLnBvc2l0aW9uKQoKICAgICAgICBpZiBzZWxmLnNwYXJzZSBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkbm9ybWFsKHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucmVhZHNwYXJzZShzaXplKQoKICAgIGRlZiByZWFkbm9ybWFsKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciByZWd1bGFyIGZpbGVzLgogICAgICAgICIiIgogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgc2VsZi5wb3NpdGlvbikKICAgICAgICBzZWxmLnBvc2l0aW9uICs9IHNpemUKICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSkKCiAgICBkZWYgcmVhZHNwYXJzZShzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3Igc3BhcnNlIGZpbGVzLgogICAgICAgICIiIgogICAgICAgIGRhdGEgPSBbXQogICAgICAgIHdoaWxlIHNpemUgPiAwOgogICAgICAgICAgICBidWYgPSBzZWxmLnJlYWRzcGFyc2VzZWN0aW9uKHNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgIGRhdGEuYXBwZW5kKGJ1ZikKICAgICAgICByZXR1cm4gIiIuam9pbihkYXRhKQoKICAgIGRlZiByZWFkc3BhcnNlc2VjdGlvbihzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIGEgc2luZ2xlIHNlY3Rpb24gb2YgYSBzcGFyc2UgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWN0aW9uID0gc2VsZi5zcGFyc2UuZmluZChzZWxmLnBvc2l0aW9uKQoKICAgICAgICBpZiBzZWN0aW9uIGlzIE5vbmU6CiAgICAgICAgICAgIHJldHVybiAiIgoKICAgICAgICBzaXplID0gbWluKHNpemUsIHNlY3Rpb24ub2Zmc2V0ICsgc2VjdGlvbi5zaXplIC0gc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWN0aW9uLCBfZGF0YSk6CiAgICAgICAgICAgIHJlYWxwb3MgPSBzZWN0aW9uLnJlYWxwb3MgKyBzZWxmLnBvc2l0aW9uIC0gc2VjdGlvbi5vZmZzZXQKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyByZWFscG9zKQogICAgICAgICAgICBzZWxmLnBvc2l0aW9uICs9IHNpemUKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iai5yZWFkKHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgICAgIHJldHVybiBOVUwgKiBzaXplCiNjbGFzcyBfRmlsZUluRmlsZQoKCmNsYXNzIEV4RmlsZU9iamVjdChvYmplY3QpOgogICAgIiIiRmlsZS1saWtlIG9iamVjdCBmb3IgcmVhZGluZyBhbiBhcmNoaXZlIG1lbWJlci4KICAgICAgIElzIHJldHVybmVkIGJ5IFRhckZpbGUuZXh0cmFjdGZpbGUoKS4KICAgICIiIgogICAgYmxvY2tzaXplID0gMTAyNAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlLCB0YXJpbmZvKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBfRmlsZUluRmlsZSh0YXJmaWxlLmZpbGVvYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0YXR0cih0YXJpbmZvLCAic3BhcnNlIiwgTm9uZSkpCiAgICAgICAgc2VsZi5uYW1lID0gdGFyaW5mby5uYW1lCiAgICAgICAgc2VsZi5tb2RlID0gInIiCiAgICAgICAgc2VsZi5jbG9zZWQgPSBGYWxzZQogICAgICAgIHNlbGYuc2l6ZSA9IHRhcmluZm8uc2l6ZQoKICAgICAgICBzZWxmLnBvc2l0aW9uID0gMAogICAgICAgIHNlbGYuYnVmZmVyID0gIiIKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgYXQgbW9zdCBzaXplIGJ5dGVzIGZyb20gdGhlIGZpbGUuIElmIHNpemUgaXMgbm90CiAgICAgICAgICAgcHJlc2VudCBvciBOb25lLCByZWFkIGFsbCBkYXRhIHVudGlsIEVPRiBpcyByZWFjaGVkLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgYnVmID0gIiIKICAgICAgICBpZiBzZWxmLmJ1ZmZlcjoKICAgICAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5idWZmZXIKICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gIiIKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyWzpzaXplXQogICAgICAgICAgICAgICAgc2VsZi5idWZmZXIgPSBzZWxmLmJ1ZmZlcltzaXplOl0KCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICBidWYgKz0gc2VsZi5maWxlb2JqLnJlYWQoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLmZpbGVvYmoucmVhZChzaXplIC0gbGVuKGJ1ZikpCgogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9LTEpOgogICAgICAgICIiIlJlYWQgb25lIGVudGlyZSBsaW5lIGZyb20gdGhlIGZpbGUuIElmIHNpemUgaXMgcHJlc2VudAogICAgICAgICAgIGFuZCBub24tbmVnYXRpdmUsIHJldHVybiBhIHN0cmluZyB3aXRoIGF0IG1vc3QgdGhhdAogICAgICAgICAgIHNpemUsIHdoaWNoIG1heSBiZSBhbiBpbmNvbXBsZXRlIGxpbmUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBpZiAiXG4iIGluIHNlbGYuYnVmZmVyOgogICAgICAgICAgICBwb3MgPSBzZWxmLmJ1ZmZlci5maW5kKCJcbiIpICsgMQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZmZlcnMgPSBbc2VsZi5idWZmZXJdCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJsb2Nrc2l6ZSkKICAgICAgICAgICAgICAgIGJ1ZmZlcnMuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgICAgIGlmIG5vdCBidWYgb3IgIlxuIiBpbiBidWY6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5idWZmZXIgPSAiIi5qb2luKGJ1ZmZlcnMpCiAgICAgICAgICAgICAgICAgICAgcG9zID0gc2VsZi5idWZmZXIuZmluZCgiXG4iKSArIDEKICAgICAgICAgICAgICAgICAgICBpZiBwb3MgPT0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgIyBubyBuZXdsaW5lIGZvdW5kLgogICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBsZW4oc2VsZi5idWZmZXIpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgaWYgc2l6ZSAhPSAtMToKICAgICAgICAgICAgcG9zID0gbWluKHNpemUsIHBvcykKCiAgICAgICAgYnVmID0gc2VsZi5idWZmZXJbOnBvc10KICAgICAgICBzZWxmLmJ1ZmZlciA9IHNlbGYuYnVmZmVyW3BvczpdCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgcmVhZGxpbmVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiBhIGxpc3Qgd2l0aCBhbGwgcmVtYWluaW5nIGxpbmVzLgogICAgICAgICIiIgogICAgICAgIHJlc3VsdCA9IFtdCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChsaW5lKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIHJldHVybiBzZWxmLnBvc2l0aW9uCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zLCB3aGVuY2U9b3MuU0VFS19TRVQpOgogICAgICAgICIiIlNlZWsgdG8gYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGlmIHdoZW5jZSA9PSBvcy5TRUVLX1NFVDoKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiA9IG1pbihtYXgocG9zLCAwKSwgc2VsZi5zaXplKQogICAgICAgIGVsaWYgd2hlbmNlID09IG9zLlNFRUtfQ1VSOgogICAgICAgICAgICBpZiBwb3MgPCAwOgogICAgICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiA9IG1heChzZWxmLnBvc2l0aW9uICsgcG9zLCAwKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiA9IG1pbihzZWxmLnBvc2l0aW9uICsgcG9zLCBzZWxmLnNpemUpCiAgICAgICAgZWxpZiB3aGVuY2UgPT0gb3MuU0VFS19FTkQ6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJbnZhbGlkIGFyZ3VtZW50IikKCiAgICAgICAgc2VsZi5idWZmZXIgPSAiIgogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYucG9zaXRpb24pCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBmaWxlIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiR2V0IGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGZpbGUncyBsaW5lcy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgeWllbGQgbGluZQojY2xhc3MgRXhGaWxlT2JqZWN0CgojLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXhwb3J0ZWQgQ2xhc3NlcwojLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIFRhckluZm8ob2JqZWN0KToKICAgICIiIkluZm9ybWF0aW9uYWwgY2xhc3Mgd2hpY2ggaG9sZHMgdGhlIGRldGFpbHMgYWJvdXQgYW4KICAgICAgIGFyY2hpdmUgbWVtYmVyIGdpdmVuIGJ5IGEgdGFyIGhlYWRlciBibG9jay4KICAgICAgIFRhckluZm8gb2JqZWN0cyBhcmUgcmV0dXJuZWQgYnkgVGFyRmlsZS5nZXRtZW1iZXIoKSwKICAgICAgIFRhckZpbGUuZ2V0bWVtYmVycygpIGFuZCBUYXJGaWxlLmdldHRhcmluZm8oKSBhbmQgYXJlCiAgICAgICB1c3VhbGx5IGNyZWF0ZWQgaW50ZXJuYWxseS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPSIiKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJbmZvIG9iamVjdC4gbmFtZSBpcyB0aGUgb3B0aW9uYWwgbmFtZQogICAgICAgICAgIG9mIHRoZSBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5uYW1lID0gbmFtZSAgICAgICAgIyBtZW1iZXIgbmFtZQogICAgICAgIHNlbGYubW9kZSA9IDA2NDQgICAgICAgICMgZmlsZSBwZXJtaXNzaW9ucwogICAgICAgIHNlbGYudWlkID0gMCAgICAgICAgICAgICMgdXNlciBpZAogICAgICAgIHNlbGYuZ2lkID0gMCAgICAgICAgICAgICMgZ3JvdXAgaWQKICAgICAgICBzZWxmLnNpemUgPSAwICAgICAgICAgICAjIGZpbGUgc2l6ZQogICAgICAgIHNlbGYubXRpbWUgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUKICAgICAgICBzZWxmLmNoa3N1bSA9IDAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQogICAgICAgIHNlbGYudHlwZSA9IFJFR1RZUEUgICAgICMgbWVtYmVyIHR5cGUKICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAjIGxpbmsgbmFtZQogICAgICAgIHNlbGYudW5hbWUgPSAicm9vdCIgICAgICMgdXNlciBuYW1lCiAgICAgICAgc2VsZi5nbmFtZSA9ICJyb290IiAgICAgIyBncm91cCBuYW1lCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgIyBkZXZpY2UgbWFqb3IgbnVtYmVyCiAgICAgICAgc2VsZi5kZXZtaW5vciA9IDAgICAgICAgIyBkZXZpY2UgbWlub3IgbnVtYmVyCgogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgICAgICBzZWxmLnBheF9oZWFkZXJzID0ge30gICAjIHBheCBoZWFkZXIgaW5mb3JtYXRpb24KCiAgICAjIEluIHBheCBoZWFkZXJzIHRoZSAibmFtZSIgYW5kICJsaW5rbmFtZSIgZmllbGQgYXJlIGNhbGxlZAogICAgIyAicGF0aCIgYW5kICJsaW5rcGF0aCIuCiAgICBkZWYgX2dldHBhdGgoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYubmFtZQogICAgZGVmIF9zZXRwYXRoKHNlbGYsIG5hbWUpOgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUKICAgIHBhdGggPSBwcm9wZXJ0eShfZ2V0cGF0aCwgX3NldHBhdGgpCgogICAgZGVmIF9nZXRsaW5rcGF0aChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5saW5rbmFtZQogICAgZGVmIF9zZXRsaW5rcGF0aChzZWxmLCBsaW5rbmFtZSk6CiAgICAgICAgc2VsZi5saW5rbmFtZSA9IGxpbmtuYW1lCiAgICBsaW5rcGF0aCA9IHByb3BlcnR5KF9nZXRsaW5rcGF0aCwgX3NldGxpbmtwYXRoKQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgZGVmIGdldF9pbmZvKHNlbGYsIGVuY29kaW5nLCBlcnJvcnMpOgogICAgICAgICIiIlJldHVybiB0aGUgVGFySW5mbydzIGF0dHJpYnV0ZXMgYXMgYSBkaWN0aW9uYXJ5LgogICAgICAgICIiIgogICAgICAgIGluZm8gPSB7CiAgICAgICAgICAgICJuYW1lIjogICAgIG5vcm1wYXRoKHNlbGYubmFtZSksCiAgICAgICAgICAgICJtb2RlIjogICAgIHNlbGYubW9kZSAmIDA3Nzc3LAogICAgICAgICAgICAidWlkIjogICAgICBzZWxmLnVpZCwKICAgICAgICAgICAgImdpZCI6ICAgICAgc2VsZi5naWQsCiAgICAgICAgICAgICJzaXplIjogICAgIHNlbGYuc2l6ZSwKICAgICAgICAgICAgIm10aW1lIjogICAgc2VsZi5tdGltZSwKICAgICAgICAgICAgImNoa3N1bSI6ICAgc2VsZi5jaGtzdW0sCiAgICAgICAgICAgICJ0eXBlIjogICAgIHNlbGYudHlwZSwKICAgICAgICAgICAgImxpbmtuYW1lIjogbm9ybXBhdGgoc2VsZi5saW5rbmFtZSkgaWYgc2VsZi5saW5rbmFtZSBlbHNlICIiLAogICAgICAgICAgICAidW5hbWUiOiAgICBzZWxmLnVuYW1lLAogICAgICAgICAgICAiZ25hbWUiOiAgICBzZWxmLmduYW1lLAogICAgICAgICAgICAiZGV2bWFqb3IiOiBzZWxmLmRldm1ham9yLAogICAgICAgICAgICAiZGV2bWlub3IiOiBzZWxmLmRldm1pbm9yCiAgICAgICAgfQoKICAgICAgICBpZiBpbmZvWyJ0eXBlIl0gPT0gRElSVFlQRSBhbmQgbm90IGluZm9bIm5hbWUiXS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICBpbmZvWyJuYW1lIl0gKz0gIi8iCgogICAgICAgIGZvciBrZXkgaW4gKCJuYW1lIiwgImxpbmtuYW1lIiwgInVuYW1lIiwgImduYW1lIik6CiAgICAgICAgICAgIGlmIHR5cGUoaW5mb1trZXldKSBpcyB1bmljb2RlOgogICAgICAgICAgICAgICAgaW5mb1trZXldID0gaW5mb1trZXldLmVuY29kZShlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICByZXR1cm4gaW5mbwoKICAgIGRlZiB0b2J1ZihzZWxmLCBmb3JtYXQ9REVGQVVMVF9GT1JNQVQsIGVuY29kaW5nPUVOQ09ESU5HLCBlcnJvcnM9InN0cmljdCIpOgogICAgICAgICIiIlJldHVybiBhIHRhciBoZWFkZXIgYXMgYSBzdHJpbmcgb2YgNTEyIGJ5dGUgYmxvY2tzLgogICAgICAgICIiIgogICAgICAgIGluZm8gPSBzZWxmLmdldF9pbmZvKGVuY29kaW5nLCBlcnJvcnMpCgogICAgICAgIGlmIGZvcm1hdCA9PSBVU1RBUl9GT1JNQVQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV91c3Rhcl9oZWFkZXIoaW5mbykKICAgICAgICBlbGlmIGZvcm1hdCA9PSBHTlVfRk9STUFUOgogICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVfZ251X2hlYWRlcihpbmZvKQogICAgICAgIGVsaWYgZm9ybWF0ID09IFBBWF9GT1JNQVQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZV9wYXhfaGVhZGVyKGluZm8sIGVuY29kaW5nLCBlcnJvcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBmb3JtYXQiKQoKICAgIGRlZiBjcmVhdGVfdXN0YXJfaGVhZGVyKHNlbGYsIGluZm8pOgogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgdXN0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwoKICAgICAgICBpZiBsZW4oaW5mb1sibGlua25hbWUiXSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibGlua25hbWUgaXMgdG9vIGxvbmciKQoKICAgICAgICBpZiBsZW4oaW5mb1sibmFtZSJdKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICBpbmZvWyJwcmVmaXgiXSwgaW5mb1sibmFtZSJdID0gc2VsZi5fcG9zaXhfc3BsaXRfbmFtZShpbmZvWyJuYW1lIl0pCgogICAgICAgIHJldHVybiBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkKCiAgICBkZWYgY3JlYXRlX2dudV9oZWFkZXIoc2VsZiwgaW5mbyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSBHTlUgaGVhZGVyIGJsb2NrIHNlcXVlbmNlLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBHTlVfTUFHSUMKCiAgICAgICAgYnVmID0gIiIKICAgICAgICBpZiBsZW4oaW5mb1sibGlua25hbWUiXSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibGlua25hbWUiXSwgR05VVFlQRV9MT05HTElOSykKCiAgICAgICAgaWYgbGVuKGluZm9bIm5hbWUiXSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVfbG9uZ19oZWFkZXIoaW5mb1sibmFtZSJdLCBHTlVUWVBFX0xPTkdOQU1FKQoKICAgICAgICByZXR1cm4gYnVmICsgc2VsZi5fY3JlYXRlX2hlYWRlcihpbmZvLCBHTlVfRk9STUFUKQoKICAgIGRlZiBjcmVhdGVfcGF4X2hlYWRlcihzZWxmLCBpbmZvLCBlbmNvZGluZywgZXJyb3JzKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIHVzdGFyIGhlYWRlciBibG9jay4gSWYgaXQgY2Fubm90IGJlCiAgICAgICAgICAgcmVwcmVzZW50ZWQgdGhpcyB3YXksIHByZXBlbmQgYSBwYXggZXh0ZW5kZWQgaGVhZGVyIHNlcXVlbmNlCiAgICAgICAgICAgd2l0aCBzdXBwbGVtZW50IGluZm9ybWF0aW9uLgogICAgICAgICIiIgogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwogICAgICAgIHBheF9oZWFkZXJzID0gc2VsZi5wYXhfaGVhZGVycy5jb3B5KCkKCiAgICAgICAgIyBUZXN0IHN0cmluZyBmaWVsZHMgZm9yIHZhbHVlcyB0aGF0IGV4Y2VlZCB0aGUgZmllbGQgbGVuZ3RoIG9yIGNhbm5vdAogICAgICAgICMgYmUgcmVwcmVzZW50ZWQgaW4gQVNDSUkgZW5jb2RpbmcuCiAgICAgICAgZm9yIG5hbWUsIGhuYW1lLCBsZW5ndGggaW4gKAogICAgICAgICAgICAgICAgKCJuYW1lIiwgInBhdGgiLCBMRU5HVEhfTkFNRSksICgibGlua25hbWUiLCAibGlua3BhdGgiLCBMRU5HVEhfTElOSyksCiAgICAgICAgICAgICAgICAoInVuYW1lIiwgInVuYW1lIiwgMzIpLCAoImduYW1lIiwgImduYW1lIiwgMzIpKToKCiAgICAgICAgICAgIGlmIGhuYW1lIGluIHBheF9oZWFkZXJzOgogICAgICAgICAgICAgICAgIyBUaGUgcGF4IGhlYWRlciBoYXMgcHJpb3JpdHkuCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgdmFsID0gaW5mb1tuYW1lXS5kZWNvZGUoZW5jb2RpbmcsIGVycm9ycykKCiAgICAgICAgICAgICMgVHJ5IHRvIGVuY29kZSB0aGUgc3RyaW5nIGFzIEFTQ0lJLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB2YWwuZW5jb2RlKCJhc2NpaSIpCiAgICAgICAgICAgIGV4Y2VwdCBVbmljb2RlRW5jb2RlRXJyb3I6CiAgICAgICAgICAgICAgICBwYXhfaGVhZGVyc1tobmFtZV0gPSB2YWwKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBpZiBsZW4oaW5mb1tuYW1lXSkgPiBsZW5ndGg6CiAgICAgICAgICAgICAgICBwYXhfaGVhZGVyc1tobmFtZV0gPSB2YWwKCiAgICAgICAgIyBUZXN0IG51bWJlciBmaWVsZHMgZm9yIHZhbHVlcyB0aGF0IGV4Y2VlZCB0aGUgZmllbGQgbGltaXQgb3IgdmFsdWVzCiAgICAgICAgIyB0aGF0IGxpa2UgdG8gYmUgc3RvcmVkIGFzIGZsb2F0LgogICAgICAgIGZvciBuYW1lLCBkaWdpdHMgaW4gKCgidWlkIiwgOCksICgiZ2lkIiwgOCksICgic2l6ZSIsIDEyKSwgKCJtdGltZSIsIDEyKSk6CiAgICAgICAgICAgIGlmIG5hbWUgaW4gcGF4X2hlYWRlcnM6CiAgICAgICAgICAgICAgICAjIFRoZSBwYXggaGVhZGVyIGhhcyBwcmlvcml0eS4gQXZvaWQgb3ZlcmZsb3cuCiAgICAgICAgICAgICAgICBpbmZvW25hbWVdID0gMAogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIHZhbCA9IGluZm9bbmFtZV0KICAgICAgICAgICAgaWYgbm90IDAgPD0gdmFsIDwgOCAqKiAoZGlnaXRzIC0gMSkgb3IgaXNpbnN0YW5jZSh2YWwsIGZsb2F0KToKICAgICAgICAgICAgICAgIHBheF9oZWFkZXJzW25hbWVdID0gdW5pY29kZSh2YWwpCiAgICAgICAgICAgICAgICBpbmZvW25hbWVdID0gMAoKICAgICAgICAjIENyZWF0ZSBhIHBheCBleHRlbmRlZCBoZWFkZXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIGlmIHBheF9oZWFkZXJzOgogICAgICAgICAgICBidWYgPSBzZWxmLl9jcmVhdGVfcGF4X2dlbmVyaWNfaGVhZGVyKHBheF9oZWFkZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiA9ICIiCgogICAgICAgIHJldHVybiBidWYgKyBzZWxmLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBjcmVhdGVfcGF4X2dsb2JhbF9oZWFkZXIoY2xzLCBwYXhfaGVhZGVycyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSBwYXggZ2xvYmFsIGhlYWRlciBibG9jayBzZXF1ZW5jZS4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gY2xzLl9jcmVhdGVfcGF4X2dlbmVyaWNfaGVhZGVyKHBheF9oZWFkZXJzLCB0eXBlPVhHTFRZUEUpCgogICAgZGVmIF9wb3NpeF9zcGxpdF9uYW1lKHNlbGYsIG5hbWUpOgogICAgICAgICIiIlNwbGl0IGEgbmFtZSBsb25nZXIgdGhhbiAxMDAgY2hhcnMgaW50byBhIHByZWZpeAogICAgICAgICAgIGFuZCBhIG5hbWUgcGFydC4KICAgICAgICAiIiIKICAgICAgICBwcmVmaXggPSBuYW1lWzpMRU5HVEhfUFJFRklYICsgMV0KICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gIT0gIi8iOgogICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICBuYW1lID0gbmFtZVtsZW4ocHJlZml4KTpdCiAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgaWYgbm90IHByZWZpeCBvciBsZW4obmFtZSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibmFtZSBpcyB0b28gbG9uZyIpCiAgICAgICAgcmV0dXJuIHByZWZpeCwgbmFtZQoKICAgIEBzdGF0aWNtZXRob2QKICAgIGRlZiBfY3JlYXRlX2hlYWRlcihpbmZvLCBmb3JtYXQpOgogICAgICAgICIiIlJldHVybiBhIGhlYWRlciBibG9jay4gaW5mbyBpcyBhIGRpY3Rpb25hcnkgd2l0aCBmaWxlCiAgICAgICAgICAgaW5mb3JtYXRpb24sIGZvcm1hdCBtdXN0IGJlIG9uZSBvZiB0aGUgKl9GT1JNQVQgY29uc3RhbnRzLgogICAgICAgICIiIgogICAgICAgIHBhcnRzID0gWwogICAgICAgICAgICBzdG4oaW5mby5nZXQoIm5hbWUiLCAiIiksIDEwMCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgibW9kZSIsIDApICYgMDc3NzcsIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgidWlkIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgiZ2lkIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgic2l6ZSIsIDApLCAxMiwgZm9ybWF0KSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJtdGltZSIsIDApLCAxMiwgZm9ybWF0KSwKICAgICAgICAgICAgIiAgICAgICAgIiwgIyBjaGVja3N1bSBmaWVsZAogICAgICAgICAgICBpbmZvLmdldCgidHlwZSIsIFJFR1RZUEUpLAogICAgICAgICAgICBzdG4oaW5mby5nZXQoImxpbmtuYW1lIiwgIiIpLCAxMDApLAogICAgICAgICAgICBzdG4oaW5mby5nZXQoIm1hZ2ljIiwgUE9TSVhfTUFHSUMpLCA4KSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJ1bmFtZSIsICJyb290IiksIDMyKSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJnbmFtZSIsICJyb290IiksIDMyKSwKICAgICAgICAgICAgaXRuKGluZm8uZ2V0KCJkZXZtYWpvciIsIDApLCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1pbm9yIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgicHJlZml4IiwgIiIpLCAxNTUpCiAgICAgICAgXQoKICAgICAgICBidWYgPSBzdHJ1Y3QucGFjaygiJWRzIiAlIEJMT0NLU0laRSwgIiIuam9pbihwYXJ0cykpCiAgICAgICAgY2hrc3VtID0gY2FsY19jaGtzdW1zKGJ1ZlstQkxPQ0tTSVpFOl0pWzBdCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQogICAgICAgIHJldHVybiBidWYKCiAgICBAc3RhdGljbWV0aG9kCiAgICBkZWYgX2NyZWF0ZV9wYXlsb2FkKHBheWxvYWQpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyaW5nIHBheWxvYWQgZmlsbGVkIHdpdGggemVybyBieXRlcwogICAgICAgICAgIHVwIHRvIHRoZSBuZXh0IDUxMiBieXRlIGJvcmRlci4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4ocGF5bG9hZCksIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBwYXlsb2FkICs9IChCTE9DS1NJWkUgLSByZW1haW5kZXIpICogTlVMCiAgICAgICAgcmV0dXJuIHBheWxvYWQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX2dudV9sb25nX2hlYWRlcihjbHMsIG5hbWUsIHR5cGUpOgogICAgICAgICIiIlJldHVybiBhIEdOVVRZUEVfTE9OR05BTUUgb3IgR05VVFlQRV9MT05HTElOSyBzZXF1ZW5jZQogICAgICAgICAgIGZvciBuYW1lLgogICAgICAgICIiIgogICAgICAgIG5hbWUgKz0gTlVMCgogICAgICAgIGluZm8gPSB7fQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIGluZm9bInR5cGUiXSA9IHR5cGUKICAgICAgICBpbmZvWyJzaXplIl0gPSBsZW4obmFtZSkKICAgICAgICBpbmZvWyJtYWdpYyJdID0gR05VX01BR0lDCgogICAgICAgICMgY3JlYXRlIGV4dGVuZGVkIGhlYWRlciArIG5hbWUgYmxvY2tzLgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwKICAgICAgICAgICAgICAgIGNscy5fY3JlYXRlX3BheWxvYWQobmFtZSkKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBfY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihjbHMsIHBheF9oZWFkZXJzLCB0eXBlPVhIRFRZUEUpOgogICAgICAgICIiIlJldHVybiBhIFBPU0lYLjEtMjAwMSBleHRlbmRlZCBvciBnbG9iYWwgaGVhZGVyIHNlcXVlbmNlCiAgICAgICAgICAgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Yga2V5d29yZCwgdmFsdWUgcGFpcnMuIFRoZSB2YWx1ZXMKICAgICAgICAgICBtdXN0IGJlIHVuaWNvZGUgb2JqZWN0cy4KICAgICAgICAiIiIKICAgICAgICByZWNvcmRzID0gW10KICAgICAgICBmb3Iga2V5d29yZCwgdmFsdWUgaW4gcGF4X2hlYWRlcnMuaXRlcml0ZW1zKCk6CiAgICAgICAgICAgIGtleXdvcmQgPSBrZXl3b3JkLmVuY29kZSgidXRmOCIpCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuZW5jb2RlKCJ1dGY4IikKICAgICAgICAgICAgbCA9IGxlbihrZXl3b3JkKSArIGxlbih2YWx1ZSkgKyAzICAgIyAnICcgKyAnPScgKyAnXG4nCiAgICAgICAgICAgIG4gPSBwID0gMAogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgbiA9IGwgKyBsZW4oc3RyKHApKQogICAgICAgICAgICAgICAgaWYgbiA9PSBwOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBwID0gbgogICAgICAgICAgICByZWNvcmRzLmFwcGVuZCgiJWQgJXM9JXNcbiIgJSAocCwga2V5d29yZCwgdmFsdWUpKQogICAgICAgIHJlY29yZHMgPSAiIi5qb2luKHJlY29yZHMpCgogICAgICAgICMgV2UgdXNlIGEgaGFyZGNvZGVkICIuLy4vQFBheEhlYWRlciIgbmFtZSBsaWtlIHN0YXIgZG9lcwogICAgICAgICMgaW5zdGVhZCBvZiB0aGUgb25lIHRoYXQgUE9TSVggcmVjb21tZW5kcy4KICAgICAgICBpbmZvID0ge30KICAgICAgICBpbmZvWyJuYW1lIl0gPSAiLi8uL0BQYXhIZWFkZXIiCiAgICAgICAgaW5mb1sidHlwZSJdID0gdHlwZQogICAgICAgIGluZm9bInNpemUiXSA9IGxlbihyZWNvcmRzKQogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBQT1NJWF9NQUdJQwoKICAgICAgICAjIENyZWF0ZSBwYXggaGVhZGVyICsgcmVjb3JkIGJsb2Nrcy4KICAgICAgICByZXR1cm4gY2xzLl9jcmVhdGVfaGVhZGVyKGluZm8sIFVTVEFSX0ZPUk1BVCkgKyBcCiAgICAgICAgICAgICAgICBjbHMuX2NyZWF0ZV9wYXlsb2FkKHJlY29yZHMpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgIT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigidHJ1bmNhdGVkIGhlYWRlciIpCiAgICAgICAgaWYgYnVmLmNvdW50KE5VTCkgPT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigiZW1wdHkgaGVhZGVyIikKCiAgICAgICAgY2hrc3VtID0gbnRpKGJ1ZlsxNDg6MTU2XSkKICAgICAgICBpZiBjaGtzdW0gbm90IGluIGNhbGNfY2hrc3VtcyhidWYpOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigiYmFkIGNoZWNrc3VtIikKCiAgICAgICAgb2JqID0gY2xzKCkKICAgICAgICBvYmouYnVmID0gYnVmCiAgICAgICAgb2JqLm5hbWUgPSBudHMoYnVmWzA6MTAwXSkKICAgICAgICBvYmoubW9kZSA9IG50aShidWZbMTAwOjEwOF0pCiAgICAgICAgb2JqLnVpZCA9IG50aShidWZbMTA4OjExNl0pCiAgICAgICAgb2JqLmdpZCA9IG50aShidWZbMTE2OjEyNF0pCiAgICAgICAgb2JqLnNpemUgPSBudGkoYnVmWzEyNDoxMzZdKQogICAgICAgIG9iai5tdGltZSA9IG50aShidWZbMTM2OjE0OF0pCiAgICAgICAgb2JqLmNoa3N1bSA9IGNoa3N1bQogICAgICAgIG9iai50eXBlID0gYnVmWzE1NjoxNTddCiAgICAgICAgb2JqLmxpbmtuYW1lID0gbnRzKGJ1ZlsxNTc6MjU3XSkKICAgICAgICBvYmoudW5hbWUgPSBudHMoYnVmWzI2NToyOTddKQogICAgICAgIG9iai5nbmFtZSA9IG50cyhidWZbMjk3OjMyOV0pCiAgICAgICAgb2JqLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkKICAgICAgICBvYmouZGV2bWlub3IgPSBudGkoYnVmWzMzNzozNDVdKQogICAgICAgIHByZWZpeCA9IG50cyhidWZbMzQ1OjUwMF0pCgogICAgICAgICMgT2xkIFY3IHRhciBmb3JtYXQgcmVwcmVzZW50cyBhIGRpcmVjdG9yeSBhcyBhIHJlZ3VsYXIKICAgICAgICAjIGZpbGUgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLgogICAgICAgIGlmIG9iai50eXBlID09IEFSRUdUWVBFIGFuZCBvYmoubmFtZS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICBvYmoudHlwZSA9IERJUlRZUEUKCiAgICAgICAgIyBSZW1vdmUgcmVkdW5kYW50IHNsYXNoZXMgZnJvbSBkaXJlY3Rvcmllcy4KICAgICAgICBpZiBvYmouaXNkaXIoKToKICAgICAgICAgICAgb2JqLm5hbWUgPSBvYmoubmFtZS5yc3RyaXAoIi8iKQoKICAgICAgICAjIFJlY29uc3RydWN0IGEgdXN0YXIgbG9uZ25hbWUuCiAgICAgICAgaWYgcHJlZml4IGFuZCBvYmoudHlwZSBub3QgaW4gR05VX1RZUEVTOgogICAgICAgICAgICBvYmoubmFtZSA9IHByZWZpeCArICIvIiArIG9iai5uYW1lCiAgICAgICAgcmV0dXJuIG9iagoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGZyb210YXJmaWxlKGNscywgdGFyZmlsZSk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IFRhckluZm8gb2JqZWN0IGZyb20gVGFyRmlsZSBvYmplY3QKICAgICAgICAgICB0YXJmaWxlLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBvYmogPSBjbHMuZnJvbWJ1ZihidWYpCiAgICAgICAgb2JqLm9mZnNldCA9IHRhcmZpbGUuZmlsZW9iai50ZWxsKCkgLSBCTE9DS1NJWkUKICAgICAgICByZXR1cm4gb2JqLl9wcm9jX21lbWJlcih0YXJmaWxlKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgZm9sbG93aW5nIGFyZSBtZXRob2RzIHRoYXQgYXJlIGNhbGxlZCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgYQogICAgIyBtZW1iZXIuIFRoZSBlbnRyeSBwb2ludCBpcyBfcHJvY19tZW1iZXIoKSB3aGljaCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBhCiAgICAjIHN1YmNsYXNzIHRvIGFkZCBjdXN0b20gX3Byb2NfKigpIG1ldGhvZHMuIEEgX3Byb2NfKigpIG1ldGhvZCBNVVNUCiAgICAjIGltcGxlbWVudCB0aGUgZm9sbG93aW5nCiAgICAjIG9wZXJhdGlvbnM6CiAgICAjIDEuIFNldCBzZWxmLm9mZnNldF9kYXRhIHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MgYmVnaW4sCiAgICAjICAgIGlmIHRoZXJlIGlzIGRhdGEgdGhhdCBmb2xsb3dzLgogICAgIyAyLiBTZXQgdGFyZmlsZS5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsCiAgICAjICAgIGJlZ2luLgogICAgIyAzLiBSZXR1cm4gc2VsZiBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgogICAgZGVmIF9wcm9jX21lbWJlcihzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDaG9vc2UgdGhlIHJpZ2h0IHByb2Nlc3NpbmcgbWV0aG9kIGRlcGVuZGluZyBvbgogICAgICAgICAgIHRoZSB0eXBlIGFuZCBjYWxsIGl0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYudHlwZSBpbiAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX2dudWxvbmcodGFyZmlsZSkKICAgICAgICBlbGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2Nfc3BhcnNlKHRhcmZpbGUpCiAgICAgICAgZWxpZiBzZWxmLnR5cGUgaW4gKFhIRFRZUEUsIFhHTFRZUEUsIFNPTEFSSVNfWEhEVFlQRSk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX3BheCh0YXJmaWxlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9wcm9jX2J1aWx0aW4odGFyZmlsZSkKCiAgICBkZWYgX3Byb2NfYnVpbHRpbihzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIGEgYnVpbHRpbiB0eXBlIG9yIGFuIHVua25vd24gdHlwZSB3aGljaAogICAgICAgICAgIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKQogICAgICAgIG9mZnNldCA9IHNlbGYub2Zmc2V0X2RhdGEKICAgICAgICBpZiBzZWxmLmlzcmVnKCkgb3Igc2VsZi50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICBvZmZzZXQgKz0gc2VsZi5fYmxvY2soc2VsZi5zaXplKQogICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gb2Zmc2V0CgogICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IHdpdGggc2F2ZWQgZ2xvYmFsCiAgICAgICAgIyBoZWFkZXIgaW5mb3JtYXRpb24uCiAgICAgICAgc2VsZi5fYXBwbHlfcGF4X2luZm8odGFyZmlsZS5wYXhfaGVhZGVycywgdGFyZmlsZS5lbmNvZGluZywgdGFyZmlsZS5lcnJvcnMpCgogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9wcm9jX2dudWxvbmcoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyB0aGUgYmxvY2tzIHRoYXQgaG9sZCBhIEdOVSBsb25nbmFtZQogICAgICAgICAgIG9yIGxvbmdsaW5rIG1lbWJlci4KICAgICAgICAiIiIKICAgICAgICBidWYgPSB0YXJmaWxlLmZpbGVvYmoucmVhZChzZWxmLl9ibG9jayhzZWxmLnNpemUpKQoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlciBhbmQgcHJvY2VzcyBpdC4KICAgICAgICBuZXh0ID0gc2VsZi5mcm9tdGFyZmlsZSh0YXJmaWxlKQogICAgICAgIGlmIG5leHQgaXMgTm9uZToKICAgICAgICAgICAgcmFpc2UgSGVhZGVyRXJyb3IoIm1pc3Npbmcgc3Vic2VxdWVudCBoZWFkZXIiKQoKICAgICAgICAjIFBhdGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBuZXh0IGhlYWRlciB3aXRoCiAgICAgICAgIyB0aGUgbG9uZ25hbWUgaW5mb3JtYXRpb24uCiAgICAgICAgbmV4dC5vZmZzZXQgPSBzZWxmLm9mZnNldAogICAgICAgIGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX0xPTkdOQU1FOgogICAgICAgICAgICBuZXh0Lm5hbWUgPSBudHMoYnVmKQogICAgICAgIGVsaWYgc2VsZi50eXBlID09IEdOVVRZUEVfTE9OR0xJTks6CiAgICAgICAgICAgIG5leHQubGlua25hbWUgPSBudHMoYnVmKQoKICAgICAgICByZXR1cm4gbmV4dAoKICAgIGRlZiBfcHJvY19zcGFyc2Uoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSBzZWxmLmJ1ZgogICAgICAgIHNwID0gX3JpbmdidWZmZXIoKQogICAgICAgIHBvcyA9IDM4NgogICAgICAgIGxhc3Rwb3MgPSAwTAogICAgICAgIHJlYWxwb3MgPSAwTAogICAgICAgICMgVGhlcmUgYXJlIDQgcG9zc2libGUgc3BhcnNlIHN0cnVjdHMgaW4gdGhlCiAgICAgICAgIyBmaXJzdCBoZWFkZXIuCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKDQpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pCiAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgcG9zICs9IDI0CgogICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzQ4Ml0pCiAgICAgICAgb3JpZ3NpemUgPSBudGkoYnVmWzQ4Mzo0OTVdKQoKICAgICAgICAjIElmIHRoZSBpc2V4dGVuZGVkIGZsYWcgaXMgZ2l2ZW4sCiAgICAgICAgIyB0aGVyZSBhcmUgZXh0cmEgaGVhZGVycyB0byBwcm9jZXNzLgogICAgICAgIHdoaWxlIGlzZXh0ZW5kZWQgPT0gMToKICAgICAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBwb3MgPSAwCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZSgyMSk6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgICAgIHBvcyArPSAyNAogICAgICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls1MDRdKQoKICAgICAgICBpZiBsYXN0cG9zIDwgb3JpZ3NpemU6CiAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvcmlnc2l6ZSAtIGxhc3Rwb3MpKQoKICAgICAgICBzZWxmLnNwYXJzZSA9IHNwCgogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpCiAgICAgICAgdGFyZmlsZS5vZmZzZXQgPSBzZWxmLm9mZnNldF9kYXRhICsgc2VsZi5fYmxvY2soc2VsZi5zaXplKQogICAgICAgIHNlbGYuc2l6ZSA9IG9yaWdzaXplCgogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9wcm9jX3BheChzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIGFuIGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIgYXMgZGVzY3JpYmVkIGluCiAgICAgICAgICAgUE9TSVguMS0yMDAxLgogICAgICAgICIiIgogICAgICAgICMgUmVhZCB0aGUgaGVhZGVyIGluZm9ybWF0aW9uLgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkpCgogICAgICAgICMgQSBwYXggaGVhZGVyIHN0b3JlcyBzdXBwbGVtZW50YWwgaW5mb3JtYXRpb24gZm9yIGVpdGhlcgogICAgICAgICMgdGhlIGZvbGxvd2luZyBmaWxlIChleHRlbmRlZCkgb3IgYWxsIGZvbGxvd2luZyBmaWxlcwogICAgICAgICMgKGdsb2JhbCkuCiAgICAgICAgaWYgc2VsZi50eXBlID09IFhHTFRZUEU6CiAgICAgICAgICAgIHBheF9oZWFkZXJzID0gdGFyZmlsZS5wYXhfaGVhZGVycwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHBheF9oZWFkZXJzID0gdGFyZmlsZS5wYXhfaGVhZGVycy5jb3B5KCkKCiAgICAgICAgIyBQYXJzZSBwYXggaGVhZGVyIGluZm9ybWF0aW9uLiBBIHJlY29yZCBsb29rcyBsaWtlIHRoYXQ6CiAgICAgICAgIyAiJWQgJXM9JXNcbiIgJSAobGVuZ3RoLCBrZXl3b3JkLCB2YWx1ZSkuIGxlbmd0aCBpcyB0aGUgc2l6ZQogICAgICAgICMgb2YgdGhlIGNvbXBsZXRlIHJlY29yZCBpbmNsdWRpbmcgdGhlIGxlbmd0aCBmaWVsZCBpdHNlbGYgYW5kCiAgICAgICAgIyB0aGUgbmV3bGluZS4ga2V5d29yZCBhbmQgdmFsdWUgYXJlIGJvdGggVVRGLTggZW5jb2RlZCBzdHJpbmdzLgogICAgICAgIHJlZ2V4ID0gcmUuY29tcGlsZShyIihcZCspIChbXj1dKyk9IiwgcmUuVSkKICAgICAgICBwb3MgPSAwCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbWF0Y2ggPSByZWdleC5tYXRjaChidWYsIHBvcykKICAgICAgICAgICAgaWYgbm90IG1hdGNoOgogICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgICAgIGxlbmd0aCwga2V5d29yZCA9IG1hdGNoLmdyb3VwcygpCiAgICAgICAgICAgIGxlbmd0aCA9IGludChsZW5ndGgpCiAgICAgICAgICAgIHZhbHVlID0gYnVmW21hdGNoLmVuZCgyKSArIDE6bWF0Y2guc3RhcnQoMSkgKyBsZW5ndGggLSAxXQoKICAgICAgICAgICAga2V5d29yZCA9IGtleXdvcmQuZGVjb2RlKCJ1dGY4IikKICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5kZWNvZGUoInV0ZjgiKQoKICAgICAgICAgICAgcGF4X2hlYWRlcnNba2V5d29yZF0gPSB2YWx1ZQogICAgICAgICAgICBwb3MgKz0gbGVuZ3RoCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyLgogICAgICAgIG5leHQgPSBzZWxmLmZyb210YXJmaWxlKHRhcmZpbGUpCgogICAgICAgIGlmIHNlbGYudHlwZSBpbiAoWEhEVFlQRSwgU09MQVJJU19YSERUWVBFKToKICAgICAgICAgICAgaWYgbmV4dCBpcyBOb25lOgogICAgICAgICAgICAgICAgcmFpc2UgSGVhZGVyRXJyb3IoIm1pc3Npbmcgc3Vic2VxdWVudCBoZWFkZXIiKQoKICAgICAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCB0aGUgZXh0ZW5kZWQgaGVhZGVyIGluZm8uCiAgICAgICAgICAgIG5leHQuX2FwcGx5X3BheF9pbmZvKHBheF9oZWFkZXJzLCB0YXJmaWxlLmVuY29kaW5nLCB0YXJmaWxlLmVycm9ycykKICAgICAgICAgICAgbmV4dC5vZmZzZXQgPSBzZWxmLm9mZnNldAoKICAgICAgICAgICAgaWYgcGF4X2hlYWRlcnMuaGFzX2tleSgic2l6ZSIpOgogICAgICAgICAgICAgICAgIyBJZiB0aGUgZXh0ZW5kZWQgaGVhZGVyIHJlcGxhY2VzIHRoZSBzaXplIGZpZWxkLAogICAgICAgICAgICAgICAgIyB3ZSBuZWVkIHRvIHJlY2FsY3VsYXRlIHRoZSBvZmZzZXQgd2hlcmUgdGhlIG5leHQKICAgICAgICAgICAgICAgICMgaGVhZGVyIHN0YXJ0cy4KICAgICAgICAgICAgICAgIG9mZnNldCA9IG5leHQub2Zmc2V0X2RhdGEKICAgICAgICAgICAgICAgIGlmIG5leHQuaXNyZWcoKSBvciBuZXh0LnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbmV4dC5fYmxvY2sobmV4dC5zaXplKQogICAgICAgICAgICAgICAgdGFyZmlsZS5vZmZzZXQgPSBvZmZzZXQKCiAgICAgICAgcmV0dXJuIG5leHQKCiAgICBkZWYgX2FwcGx5X3BheF9pbmZvKHNlbGYsIHBheF9oZWFkZXJzLCBlbmNvZGluZywgZXJyb3JzKToKICAgICAgICAiIiJSZXBsYWNlIGZpZWxkcyB3aXRoIHN1cHBsZW1lbnRhbCBpbmZvcm1hdGlvbiBmcm9tIGEgcHJldmlvdXMKICAgICAgICAgICBwYXggZXh0ZW5kZWQgb3IgZ2xvYmFsIGhlYWRlci4KICAgICAgICAiIiIKICAgICAgICBmb3Iga2V5d29yZCwgdmFsdWUgaW4gcGF4X2hlYWRlcnMuaXRlcml0ZW1zKCk6CiAgICAgICAgICAgIGlmIGtleXdvcmQgbm90IGluIFBBWF9GSUVMRFM6CiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgaWYga2V5d29yZCA9PSAicGF0aCI6CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJzdHJpcCgiLyIpCgogICAgICAgICAgICBpZiBrZXl3b3JkIGluIFBBWF9OVU1CRVJfRklFTERTOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gUEFYX05VTUJFUl9GSUVMRFNba2V5d29yZF0odmFsdWUpCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IDAKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHZhbHVlID0gdXRzKHZhbHVlLCBlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICAgICAgc2V0YXR0cihzZWxmLCBrZXl3b3JkLCB2YWx1ZSkKCiAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzLmNvcHkoKQoKICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwKICAgICAgICAgICBlLmcuIF9ibG9jayg4MzQpID0+IDEwMjQuCiAgICAgICAgIiIiCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXI6CiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBpc3JlZyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIFJFR1VMQVJfVFlQRVMKICAgIGRlZiBpc2ZpbGUoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuaXNyZWcoKQogICAgZGVmIGlzZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRElSVFlQRQogICAgZGVmIGlzc3ltKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gU1lNVFlQRQogICAgZGVmIGlzbG5rKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gTE5LVFlQRQogICAgZGVmIGlzY2hyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQ0hSVFlQRQogICAgZGVmIGlzYmxrKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQkxLVFlQRQogICAgZGVmIGlzZmlmbyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEZJRk9UWVBFCiAgICBkZWYgaXNzcGFyc2Uoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRQogICAgZGVmIGlzZGV2KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUsIEZJRk9UWVBFKQojIGNsYXNzIFRhckluZm8KCmNsYXNzIFRhckZpbGUob2JqZWN0KToKICAgICIiIlRoZSBUYXJGaWxlIENsYXNzIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byB0YXIgYXJjaGl2ZXMuCiAgICAiIiIKCiAgICBkZWJ1ZyA9IDAgICAgICAgICAgICAgICAgICAgIyBNYXkgYmUgc2V0IGZyb20gMCAobm8gbXNncykgdG8gMyAoYWxsIG1zZ3MpCgogICAgZGVyZWZlcmVuY2UgPSBGYWxzZSAgICAgICAgICMgSWYgdHJ1ZSwgYWRkIGNvbnRlbnQgb2YgbGlua2VkIGZpbGUgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0YXIgZmlsZSwgZWxzZSB0aGUgbGluay4KCiAgICBpZ25vcmVfemVyb3MgPSBGYWxzZSAgICAgICAgIyBJZiB0cnVlLCBza2lwcyBlbXB0eSBvciBpbnZhbGlkIGJsb2NrcyBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNvbnRpbnVlcyBwcm9jZXNzaW5nLgoKICAgIGVycm9ybGV2ZWwgPSAwICAgICAgICAgICAgICAjIElmIDAsIGZhdGFsIGVycm9ycyBvbmx5IGFwcGVhciBpbiBkZWJ1ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVzc2FnZXMgKGlmIGRlYnVnID49IDApLiBJZiA+IDAsIGVycm9ycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIGFzIGV4Y2VwdGlvbnMuCgogICAgZm9ybWF0ID0gREVGQVVMVF9GT1JNQVQgICAgICMgVGhlIGZvcm1hdCB0byB1c2Ugd2hlbiBjcmVhdGluZyBhbiBhcmNoaXZlLgoKICAgIGVuY29kaW5nID0gRU5DT0RJTkcgICAgICAgICAjIEVuY29kaW5nIGZvciA4LWJpdCBjaGFyYWN0ZXIgc3RyaW5ncy4KCiAgICBlcnJvcnMgPSBOb25lICAgICAgICAgICAgICAgIyBFcnJvciBoYW5kbGVyIGZvciB1bmljb2RlIGNvbnZlcnNpb24uCgogICAgdGFyaW5mbyA9IFRhckluZm8gICAgICAgICAgICMgVGhlIGRlZmF1bHQgVGFySW5mbyBjbGFzcyB0byB1c2UuCgogICAgZmlsZW9iamVjdCA9IEV4RmlsZU9iamVjdCAgICMgVGhlIGRlZmF1bHQgRXhGaWxlT2JqZWN0IGNsYXNzIHRvIHVzZS4KCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBmb3JtYXQ9Tm9uZSwKICAgICAgICAgICAgdGFyaW5mbz1Ob25lLCBkZXJlZmVyZW5jZT1Ob25lLCBpZ25vcmVfemVyb3M9Tm9uZSwgZW5jb2Rpbmc9Tm9uZSwKICAgICAgICAgICAgZXJyb3JzPU5vbmUsIHBheF9oZWFkZXJzPU5vbmUsIGRlYnVnPU5vbmUsIGVycm9ybGV2ZWw9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICBzZWxmLm1vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5fbW9kZSA9IHsiciI6ICJyYiIsICJhIjogInIrYiIsICJ3IjogIndiIn1bbW9kZV0KCiAgICAgICAgaWYgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiYSIgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAgICAgICAgICMgQ3JlYXRlIG5vbmV4aXN0ZW50IGZpbGVzIGluIGFwcGVuZCBtb2RlLgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gInciCiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gIndiIgogICAgICAgICAgICBmaWxlb2JqID0gYmx0bl9vcGVuKG5hbWUsIHNlbGYuX21vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIG5hbWUgaXMgTm9uZSBhbmQgaGFzYXR0cihmaWxlb2JqLCAibmFtZSIpOgogICAgICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQogICAgICAgICAgICBpZiBoYXNhdHRyKGZpbGVvYmosICJtb2RlIik6CiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5uYW1lID0gb3MucGF0aC5hYnNwYXRoKG5hbWUpIGlmIG5hbWUgZWxzZSBOb25lCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgYXR0cmlidXRlcy4KICAgICAgICBpZiBmb3JtYXQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gZm9ybWF0CiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi50YXJpbmZvID0gdGFyaW5mbwogICAgICAgIGlmIGRlcmVmZXJlbmNlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlcmVmZXJlbmNlID0gZGVyZWZlcmVuY2UKICAgICAgICBpZiBpZ25vcmVfemVyb3MgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuaWdub3JlX3plcm9zID0gaWdub3JlX3plcm9zCiAgICAgICAgaWYgZW5jb2RpbmcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmcgPSBlbmNvZGluZwoKICAgICAgICBpZiBlcnJvcnMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZXJyb3JzID0gZXJyb3JzCiAgICAgICAgZWxpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAidXRmLTgiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAic3RyaWN0IgoKICAgICAgICBpZiBwYXhfaGVhZGVycyBpcyBub3QgTm9uZSBhbmQgc2VsZi5mb3JtYXQgPT0gUEFYX0ZPUk1BVDoKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHt9CgogICAgICAgIGlmIGRlYnVnIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlYnVnID0gZGVidWcKICAgICAgICBpZiBlcnJvcmxldmVsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmVycm9ybGV2ZWwgPSBlcnJvcmxldmVsCgogICAgICAgICMgSW5pdCBkYXRhc3RydWN0dXJlcy4KICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkCiAgICAgICAgc2VsZi5vZmZzZXQgPSBzZWxmLmZpbGVvYmoudGVsbCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBhcmNoaXZlIGZpbGUKICAgICAgICBzZWxmLmlub2RlcyA9IHt9ICAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmNoaXZlIG1lbWJlcnMgYWxyZWFkeSBhZGRlZAoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInIiOgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gc2VsZi5uZXh0KCkKCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJhIjoKICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGlmIHNlbGYubmV4dCgpIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgaWYgc2VsZi5vZmZzZXQgPiAwOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygtIEJMT0NLU0laRSwgMSkKICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICBpZiBzZWxmLm1vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICAgICAgICAgaWYgc2VsZi5wYXhfaGVhZGVyczoKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYudGFyaW5mby5jcmVhdGVfcGF4X2dsb2JhbF9oZWFkZXIoc2VsZi5wYXhfaGVhZGVycy5jb3B5KCkpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoYnVmKQogICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikKCiAgICBkZWYgX2dldHBvc2l4KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmZvcm1hdCA9PSBVU1RBUl9GT1JNQVQKICAgIGRlZiBfc2V0cG9zaXgoc2VsZiwgdmFsdWUpOgogICAgICAgIGltcG9ydCB3YXJuaW5ncwogICAgICAgIHdhcm5pbmdzLndhcm4oInVzZSB0aGUgZm9ybWF0IGF0dHJpYnV0ZSBpbnN0ZWFkIiwgRGVwcmVjYXRpb25XYXJuaW5nKQogICAgICAgIGlmIHZhbHVlOgogICAgICAgICAgICBzZWxmLmZvcm1hdCA9IFVTVEFSX0ZPUk1BVAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gR05VX0ZPUk1BVAogICAgcG9zaXggPSBwcm9wZXJ0eShfZ2V0cG9zaXgsIF9zZXRwb3NpeCkKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBjbGFzc21ldGhvZHMgd2hpY2ggYWN0IGFzIGFsdGVybmF0ZSBjb25zdHJ1Y3RvcnMgdG8gdGhlCiAgICAjIFRhckZpbGUgY2xhc3MuIFRoZSBvcGVuKCkgbWV0aG9kIGlzIHRoZSBvbmx5IG9uZSB0aGF0IGlzIG5lZWRlZCBmb3IKICAgICMgcHVibGljIHVzZTsgaXQgaXMgdGhlICJzdXBlciItY29uc3RydWN0b3IgYW5kIGlzIGFibGUgdG8gc2VsZWN0IGFuCiAgICAjIGFkZXF1YXRlICJzdWIiLWNvbnN0cnVjdG9yIGZvciBhIHBhcnRpY3VsYXIgY29tcHJlc3Npb24gdXNpbmcgdGhlIG1hcHBpbmcKICAgICMgZnJvbSBPUEVOX01FVEguCiAgICAjCiAgICAjIFRoaXMgY29uY2VwdCBhbGxvd3Mgb25lIHRvIHN1YmNsYXNzIFRhckZpbGUgd2l0aG91dCBsb3NpbmcgdGhlIGNvbWZvcnQgb2YKICAgICMgdGhlIHN1cGVyLWNvbnN0cnVjdG9yLiBBIHN1Yi1jb25zdHJ1Y3RvciBpcyByZWdpc3RlcmVkIGFuZCBtYWRlIGF2YWlsYWJsZQogICAgIyBieSBhZGRpbmcgaXQgdG8gdGhlIG1hcHBpbmcgaW4gT1BFTl9NRVRILgoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIG9wZW4oY2xzLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGJ1ZnNpemU9UkVDT1JEU0laRSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gYSB0YXIgYXJjaGl2ZSBmb3IgcmVhZGluZywgd3JpdGluZyBvciBhcHBlbmRpbmcuIFJldHVybgogICAgICAgICAgIGFuIGFwcHJvcHJpYXRlIFRhckZpbGUgY2xhc3MuCgogICAgICAgICAgIG1vZGU6CiAgICAgICAgICAgJ3InIG9yICdyOionIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAogICAgICAgICAgICdyOmd6JyAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOmJ6MicgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nLCBjcmVhdGluZyB0aGUgZmlsZSBpZiBuZWNlc3NhcnkKICAgICAgICAgICAndycgb3IgJ3c6JyAgb3BlbiBmb3Igd3JpdGluZyB3aXRob3V0IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6Z3onICAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6YnoyJyAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgoKICAgICAgICAgICAncnwqJyAgICAgICAgb3BlbiBhIHN0cmVhbSBvZiB0YXIgYmxvY2tzIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcKICAgICAgICAgICAncnxneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgIiIiCgogICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibm90aGluZyB0byBvcGVuIikKCiAgICAgICAgaWYgbW9kZSBpbiAoInIiLCAicjoqIik6CiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KICAgICAgICAgICAgZm9yIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBzYXZlZF9wb3MgPSBmaWxlb2JqLnRlbGwoKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaiwgKiprd2FyZ3MpCiAgICAgICAgICAgICAgICBleGNlcHQgKFJlYWRFcnJvciwgQ29tcHJlc3Npb25FcnJvciksIGU6CiAgICAgICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9iai5zZWVrKHNhdmVkX3BvcykKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpCgogICAgICAgIGVsaWYgInwiIGluIG1vZGU6CiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoInwiLCAxKQogICAgICAgICAgICBmaWxlbW9kZSA9IGZpbGVtb2RlIG9yICJyIgogICAgICAgICAgICBjb21wdHlwZSA9IGNvbXB0eXBlIG9yICJ0YXIiCgogICAgICAgICAgICBpZiBmaWxlbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIikKCiAgICAgICAgICAgIHQgPSBjbHMobmFtZSwgZmlsZW1vZGUsCiAgICAgICAgICAgICAgICAgICAgX1N0cmVhbShuYW1lLCBmaWxlbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpLAogICAgICAgICAgICAgICAgICAgICoqa3dhcmdzKQogICAgICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICAgICAgcmV0dXJuIHQKCiAgICAgICAgZWxpZiBtb2RlIGluICJhdyI6CiAgICAgICAgICAgIHJldHVybiBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKCiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5kaXNjZXJuaWJsZSBtb2RlIikKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiB0YXJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGd6b3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gZ3ppcCBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3JyIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IGd6aXAKICAgICAgICAgICAgZ3ppcC5HemlwRmlsZQogICAgICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiZ3ppcCBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IGJsdG5fb3BlbihuYW1lLCBtb2RlICsgImIiKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3BlbihuYW1lLCBtb2RlLAogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKSwKICAgICAgICAgICAgICAgICoqa3dhcmdzKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBiejJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05LCAqKmt3YXJncyk6CiAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3Jy4iKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiejIKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlb2JqID0gYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBiemlwMiBmaWxlIikKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgICMgQWxsICpvcGVuKCkgbWV0aG9kcyBhcmUgcmVnaXN0ZXJlZCBoZXJlLgogICAgT1BFTl9NRVRIID0gewogICAgICAgICJ0YXIiOiAidGFyb3BlbiIsICAgIyB1bmNvbXByZXNzZWQgdGFyCiAgICAgICAgImd6IjogICJnem9wZW4iLCAgICAjIGd6aXAgY29tcHJlc3NlZCB0YXIKICAgICAgICAiYnoyIjogImJ6Mm9wZW4iICAgICMgYnppcDIgY29tcHJlc3NlZCB0YXIKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgVGhlIHB1YmxpYyBtZXRob2RzIHdoaWNoIFRhckZpbGUgcHJvdmlkZXM6CgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBUYXJGaWxlLiBJbiB3cml0ZS1tb2RlLCB0d28gZmluaXNoaW5nIHplcm8gYmxvY2tzIGFyZQogICAgICAgICAgIGFwcGVuZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlIGluICJhdyI6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFICogMikpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQogICAgICAgICAgICAjIGZpbGwgdXAgdGhlIGVuZCB3aXRoIHplcm8tYmxvY2tzCiAgICAgICAgICAgICMgKGxpa2Ugb3B0aW9uIC1iMjAgZm9yIHRhciBkb2VzKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoUkVDT1JEU0laRSAtIHJlbWFpbmRlcikpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBnZXRtZW1iZXIoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlCiAgICAgICAgICAgZm91bmQgaW4gdGhlIGFyY2hpdmUsIEtleUVycm9yIGlzIHJhaXNlZC4gSWYgYSBtZW1iZXIgb2NjdXJzIG1vcmUKICAgICAgICAgICB0aGFuIG9uY2UgaW4gdGhlIGFyY2hpdmUsIGl0cyBsYXN0IG9jY3VyZW5jZSBpcyBhc3N1bWVkIHRvIGJlIHRoZQogICAgICAgICAgIG1vc3QgdXAtdG8tZGF0ZSB2ZXJzaW9uLgogICAgICAgICIiIgogICAgICAgIHRhcmluZm8gPSBzZWxmLl9nZXRtZW1iZXIobmFtZSkKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCJmaWxlbmFtZSAlciBub3QgZm91bmQiICUgbmFtZSkKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiBnZXRtZW1iZXJzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgVGFySW5mbyBvYmplY3RzLiBUaGUKICAgICAgICAgICBsaXN0IGhhcyB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbWVtYmVycyBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygpCiAgICAgICAgaWYgbm90IHNlbGYuX2xvYWRlZDogICAgIyBpZiB3ZSB3YW50IHRvIG9idGFpbiBhIGxpc3Qgb2YKICAgICAgICAgICAgc2VsZi5fbG9hZCgpICAgICAgICAjIGFsbCBtZW1iZXJzLCB3ZSBmaXJzdCBoYXZlIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzY2FuIHRoZSB3aG9sZSBhcmNoaXZlLgogICAgICAgIHJldHVybiBzZWxmLm1lbWJlcnMKCiAgICBkZWYgZ2V0bmFtZXMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiB0aGVpciBuYW1lcy4gSXQgaGFzCiAgICAgICAgICAgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBbdGFyaW5mby5uYW1lIGZvciB0YXJpbmZvIGluIHNlbGYuZ2V0bWVtYmVycygpXQoKICAgIGRlZiBnZXR0YXJpbmZvKHNlbGYsIG5hbWU9Tm9uZSwgYXJjbmFtZT1Ob25lLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkNyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZvciBlaXRoZXIgdGhlIGZpbGUgYG5hbWUnIG9yIHRoZSBmaWxlCiAgICAgICAgICAgb2JqZWN0IGBmaWxlb2JqJyAodXNpbmcgb3MuZnN0YXQgb24gaXRzIGZpbGUgZGVzY3JpcHRvcikuIFlvdSBjYW4KICAgICAgICAgICBtb2RpZnkgc29tZSBvZiB0aGUgVGFySW5mbydzIGF0dHJpYnV0ZXMgYmVmb3JlIHlvdSBhZGQgaXQgdXNpbmcKICAgICAgICAgICBhZGRmaWxlKCkuIElmIGdpdmVuLCBgYXJjbmFtZScgc3BlY2lmaWVzIGFuIGFsdGVybmF0aXZlIG5hbWUgZm9yIHRoZQogICAgICAgICAgIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgIyBXaGVuIGZpbGVvYmogaXMgZ2l2ZW4sIHJlcGxhY2UgbmFtZSBieQogICAgICAgICMgZmlsZW9iaidzIHJlYWwgbmFtZS4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lCgogICAgICAgICMgQnVpbGRpbmcgdGhlIG5hbWUgb2YgdGhlIG1lbWJlciBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAjIEJhY2t3YXJkIHNsYXNoZXMgYXJlIGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXMsCiAgICAgICAgIyBBYnNvbHV0ZSBwYXRocyBhcmUgdHVybmVkIHRvIHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKICAgICAgICBhcmNuYW1lID0gbm9ybXBhdGgoYXJjbmFtZSkKICAgICAgICBkcnYsIGFyY25hbWUgPSBvcy5wYXRoLnNwbGl0ZHJpdmUoYXJjbmFtZSkKICAgICAgICB3aGlsZSBhcmNuYW1lWzA6MV0gPT0gIi8iOgogICAgICAgICAgICBhcmNuYW1lID0gYXJjbmFtZVsxOl0KCiAgICAgICAgIyBOb3csIGZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGgKICAgICAgICAjIGluZm9ybWF0aW9uIHNwZWNpZmljIGZvciB0aGUgZmlsZS4KICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJpbmZvKCkKICAgICAgICB0YXJpbmZvLnRhcmZpbGUgPSBzZWxmCgogICAgICAgICMgVXNlIG9zLnN0YXQgb3Igb3MubHN0YXQsIGRlcGVuZGluZyBvbiBwbGF0Zm9ybQogICAgICAgICMgYW5kIGlmIHN5bWxpbmtzIHNoYWxsIGJlIHJlc29sdmVkLgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgImxzdGF0IikgYW5kIG5vdCBzZWxmLmRlcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmxzdGF0KG5hbWUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3Muc3RhdChuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5mc3RhdChmaWxlb2JqLmZpbGVubygpKQogICAgICAgIGxpbmtuYW1lID0gIiIKCiAgICAgICAgc3RtZCA9IHN0YXRyZXMuc3RfbW9kZQogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQogICAgICAgICAgICBpZiBub3Qgc2VsZi5kZXJlZmVyZW5jZSBhbmQgc3RhdHJlcy5zdF9ubGluayA+IDEgYW5kIFwKICAgICAgICAgICAgICAgICAgICBpbm9kZSBpbiBzZWxmLmlub2RlcyBhbmQgYXJjbmFtZSAhPSBzZWxmLmlub2Rlc1tpbm9kZV06CiAgICAgICAgICAgICAgICAjIElzIGl0IGEgaGFyZGxpbmsgdG8gYW4gYWxyZWFkeQogICAgICAgICAgICAgICAgIyBhcmNoaXZlZCBmaWxlPwogICAgICAgICAgICAgICAgdHlwZSA9IExOS1RZUEUKICAgICAgICAgICAgICAgIGxpbmtuYW1lID0gc2VsZi5pbm9kZXNbaW5vZGVdCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFRoZSBpbm9kZSBpcyBhZGRlZCBvbmx5IGlmIGl0cyB2YWxpZC4KICAgICAgICAgICAgICAgICMgRm9yIHdpbjMyIGl0IGlzIGFsd2F5cyAwLgogICAgICAgICAgICAgICAgdHlwZSA9IFJFR1RZUEUKICAgICAgICAgICAgICAgIGlmIGlub2RlWzBdOgogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5vZGVzW2lub2RlXSA9IGFyY25hbWUKICAgICAgICBlbGlmIHN0YXQuU19JU0RJUihzdG1kKToKICAgICAgICAgICAgdHlwZSA9IERJUlRZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgPSBhcmNuYW1lCiAgICAgICAgdGFyaW5mby5tb2RlID0gc3RtZAogICAgICAgIHRhcmluZm8udWlkID0gc3RhdHJlcy5zdF91aWQKICAgICAgICB0YXJpbmZvLmdpZCA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSBzdGF0cmVzLnN0X3NpemUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKICAgICAgICAgICAgICAgIHByaW50ICIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwZCIgJSB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICBwcmludCAiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKCiAgICAgICAgICAgIHByaW50IHRhcmluZm8ubmFtZSArICgiLyIgaWYgdGFyaW5mby5pc2RpcigpIGVsc2UgIiIpLAoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgICAgICBwcmludCAiLT4iLCB0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICJsaW5rIHRvIiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgcHJpbnQKCiAgICBkZWYgYWRkKHNlbGYsIG5hbWUsIGFyY25hbWU9Tm9uZSwgcmVjdXJzaXZlPVRydWUsIGV4Y2x1ZGU9Tm9uZSk6CiAgICAgICAgIiIiQWRkIHRoZSBmaWxlIGBuYW1lJyB0byB0aGUgYXJjaGl2ZS4gYG5hbWUnIG1heSBiZSBhbnkgdHlwZSBvZiBmaWxlCiAgICAgICAgICAgKGRpcmVjdG9yeSwgZmlmbywgc3ltYm9saWMgbGluaywgZXRjLikuIElmIGdpdmVuLCBgYXJjbmFtZScKICAgICAgICAgICBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgRGlyZWN0b3JpZXMgYXJlIGFkZGVkIHJlY3Vyc2l2ZWx5IGJ5IGRlZmF1bHQuIFRoaXMgY2FuIGJlIGF2b2lkZWQgYnkKICAgICAgICAgICBzZXR0aW5nIGByZWN1cnNpdmUnIHRvIEZhbHNlLiBgZXhjbHVkZScgaXMgYSBmdW5jdGlvbiB0aGF0IHNob3VsZAogICAgICAgICAgIHJldHVybiBUcnVlIGZvciBlYWNoIGZpbGVuYW1lIHRvIGJlIGV4Y2x1ZGVkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKCiAgICAgICAgIyBFeGNsdWRlIHBhdGhuYW1lcy4KICAgICAgICBpZiBleGNsdWRlIGlzIG5vdCBOb25lIGFuZCBleGNsdWRlKG5hbWUpOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IEV4Y2x1ZGVkICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IHNlbGYubmFtZToKICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBTa2lwcGVkICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIFNwZWNpYWwgY2FzZTogVGhlIHVzZXIgd2FudHMgdG8gYWRkIHRoZSBjdXJyZW50CiAgICAgICAgIyB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAgICBpZiBuYW1lID09ICIuIjoKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgaWYgYXJjbmFtZSA9PSAiLiI6CiAgICAgICAgICAgICAgICAgICAgYXJjbmFtZSA9ICIiCiAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKG5hbWUpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKGYsIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSwgcmVjdXJzaXZlLCBleGNsdWRlKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgc2VsZi5fZGJnKDEsIG5hbWUpCgogICAgICAgICMgQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgZmlsZS4KICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXR0YXJpbmZvKG5hbWUsIGFyY25hbWUpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbnN1cHBvcnRlZCB0eXBlICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIEFwcGVuZCB0aGUgdGFyIGhlYWRlciBhbmQgZGF0YSB0byB0aGUgYXJjaGl2ZS4KICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIGYgPSBibHRuX29wZW4obmFtZSwgInJiIikKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8sIGYpCiAgICAgICAgICAgIGYuY2xvc2UoKQoKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQob3MucGF0aC5qb2luKG5hbWUsIGYpLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZiksIHJlY3Vyc2l2ZSwgZXhjbHVkZSkKCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCgogICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIFRhckluZm8gb2JqZWN0IGB0YXJpbmZvJyB0byB0aGUgYXJjaGl2ZS4gSWYgYGZpbGVvYmonIGlzCiAgICAgICAgICAgZ2l2ZW4sIHRhcmluZm8uc2l6ZSBieXRlcyBhcmUgcmVhZCBmcm9tIGl0IGFuZCBhZGRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLgogICAgICAgICAgIE9uIFdpbmRvd3MgcGxhdGZvcm1zLCBgZmlsZW9iaicgc2hvdWxkIGFsd2F5cyBiZSBvcGVuZWQgd2l0aCBtb2RlCiAgICAgICAgICAgJ3JiJyB0byBhdm9pZCBpcnJpdGF0aW9uIGFib3V0IHRoZSBmaWxlIHNpemUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgdGFyaW5mbyA9IGNvcHkuY29weSh0YXJpbmZvKQoKICAgICAgICBidWYgPSB0YXJpbmZvLnRvYnVmKHNlbGYuZm9ybWF0LCBzZWxmLmVuY29kaW5nLCBzZWxmLmVycm9ycykKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoYnVmKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IGxlbihidWYpCgogICAgICAgICMgSWYgdGhlcmUncyBkYXRhIHRvIGZvbGxvdywgYXBwZW5kIGl0LgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGNvcHlmaWxlb2JqKGZpbGVvYmosIHNlbGYuZmlsZW9iaiwgdGFyaW5mby5zaXplKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFIC0gcmVtYWluZGVyKSkKICAgICAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQoKICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCgogICAgZGVmIGV4dHJhY3RhbGwoc2VsZiwgcGF0aD0iLiIsIG1lbWJlcnM9Tm9uZSk6CiAgICAgICAgIiIiRXh0cmFjdCBhbGwgbWVtYmVycyBmcm9tIHRoZSBhcmNoaXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcKICAgICAgICAgICBkaXJlY3RvcnkgYW5kIHNldCBvd25lciwgbW9kaWZpY2F0aW9uIHRpbWUgYW5kIHBlcm1pc3Npb25zIG9uCiAgICAgICAgICAgZGlyZWN0b3JpZXMgYWZ0ZXJ3YXJkcy4gYHBhdGgnIHNwZWNpZmllcyBhIGRpZmZlcmVudCBkaXJlY3RvcnkKICAgICAgICAgICB0byBleHRyYWN0IHRvLiBgbWVtYmVycycgaXMgb3B0aW9uYWwgYW5kIG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlCiAgICAgICAgICAgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgZGlyZWN0b3JpZXMgPSBbXQoKICAgICAgICBpZiBtZW1iZXJzIGlzIE5vbmU6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmCgogICAgICAgIGZvciB0YXJpbmZvIGluIG1lbWJlcnM6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgICAgICMgRXh0cmFjdCBkaXJlY3RvcmllcyB3aXRoIGEgc2FmZSBtb2RlLgogICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCiAgICAgICAgICAgICAgICB0YXJpbmZvLm1vZGUgPSAwNzAwCiAgICAgICAgICAgIHNlbGYuZXh0cmFjdCh0YXJpbmZvLCBwYXRoKQoKICAgICAgICAjIFJldmVyc2Ugc29ydCBkaXJlY3Rvcmllcy4KICAgICAgICBkaXJlY3Rvcmllcy5zb3J0KGxhbWJkYSBhLCBiOiBjbXAoYS5uYW1lLCBiLm5hbWUpKQogICAgICAgIGRpcmVjdG9yaWVzLnJldmVyc2UoKQoKICAgICAgICAjIFNldCBjb3JyZWN0IG93bmVyLCBtdGltZSBhbmQgZmlsZW1vZGUgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yIHRhcmluZm8gaW4gZGlyZWN0b3JpZXM6CiAgICAgICAgICAgIGRpcnBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwKICAgICAgICAgICB1c2luZyBpdHMgZnVsbCBuYW1lLiBJdHMgZmlsZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQgYXMgYWNjdXJhdGVseQogICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIGJhc2VzdHJpbmcpOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4KICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgIHRhcmluZm8uX2xpbmtfdGFyZ2V0ID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZS5zdHJlcnJvcikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCiAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3RmaWxlKHNlbGYsIG1lbWJlcik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQogICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKICAgICAgICAgICBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZiBgbWVtYmVyJyBpcyBhIGxpbmssIGEgZmlsZS1saWtlCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YKICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCiAgICAgICAgICAgVGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgcmVhZC1vbmx5IGFuZCBwcm92aWRlcyB0aGUgZm9sbG93aW5nCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkKICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBiYXNlc3RyaW5nKToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUuCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6CiAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCiAgICAgICAgICAgICAgICAjIHRvIGV4dHJhY3QgYSAoc3ltKWxpbmsgYXMgYSBmaWxlLW9iamVjdCBmcm9tIGEgbm9uLXNlZWthYmxlCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLgogICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoImNhbm5vdCBleHRyYWN0IChzeW0pbGluayBhcyBmaWxlIG9iamVjdCIpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXRzIHRhcmdldCdzIGZpbGUgb2JqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXh0cmFjdGZpbGUoc2VsZi5fZ2V0bWVtYmVyKHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIGlmIHRhcmdldHBhdGhbLTE6XSA9PSAiLyI6CiAgICAgICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoWzotMV0KICAgICAgICB0YXJnZXRwYXRoID0gb3MucGF0aC5ub3JtcGF0aCh0YXJnZXRwYXRoKQoKICAgICAgICAjIENyZWF0ZSBhbGwgdXBwZXIgZGlyZWN0b3JpZXMuCiAgICAgICAgdXBwZXJkaXJzID0gb3MucGF0aC5kaXJuYW1lKHRhcmdldHBhdGgpCiAgICAgICAgaWYgdXBwZXJkaXJzIGFuZCBub3Qgb3MucGF0aC5leGlzdHModXBwZXJkaXJzKToKICAgICAgICAgICAgIyBDcmVhdGUgZGlyZWN0b3JpZXMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIGFyY2hpdmUgd2l0aAogICAgICAgICAgICAjIGRlZmF1bHQgcGVybWlzc2lvbnMuCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKHVwcGVyZGlycykKCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICIlcyAtPiAlcyIgJSAodGFyaW5mby5uYW1lLCB0YXJpbmZvLmxpbmtuYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGlyKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWZvKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWxpbmsodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICBzZWxmLm1ha2V1bmtub3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgZGlmZmVyZW50IGZpbGUgbWV0aG9kcy4gVGhleSBhcmUgY2FsbGVkIHZpYQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKICAgICMgc3ViY2xhc3MgdG8gaW1wbGVtZW50IG90aGVyIGZ1bmN0aW9uYWxpdHkuCgogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGRpcmVjdG9yeSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgVXNlIGEgc2FmZSBtb2RlIGZvciB0aGUgZGlyZWN0b3J5LCB0aGUgcmVhbCBtb2RlIGlzIHNldAogICAgICAgICAgICAjIGxhdGVyIGluIF9leHRyYWN0X21lbWJlcigpLgogICAgICAgICAgICBvcy5ta2Rpcih0YXJnZXRwYXRoLCAwNzAwKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBlLmVycm5vICE9IGVycm5vLkVFWElTVDoKICAgICAgICAgICAgICAgIHJhaXNlCgogICAgZGVmIG1ha2VmaWxlKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNvdXJjZSA9IHNlbGYuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICB0YXJnZXQgPSBibHRuX29wZW4odGFyZ2V0cGF0aCwgIndiIikKICAgICAgICBjb3B5ZmlsZW9iaihzb3VyY2UsIHRhcmdldCkKICAgICAgICBzb3VyY2UuY2xvc2UoKQogICAgICAgIHRhcmdldC5jbG9zZSgpCgogICAgZGVmIG1ha2V1bmtub3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGZyb20gYSBUYXJJbmZvIG9iamVjdCB3aXRoIGFuIHVua25vd24gdHlwZQogICAgICAgICAgIGF0IHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5rbm93biBmaWxlIHR5cGUgJXIsICIgXAogICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdGVkIGFzIHJlZ3VsYXIgZmlsZS4iICUgdGFyaW5mby50eXBlKQoKICAgIGRlZiBtYWtlZmlmbyhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlmbyBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAibWtmaWZvIik6CiAgICAgICAgICAgIG9zLm1rZmlmbyh0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiZmlmbyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIpCgogICAgZGVmIG1ha2VkZXYoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGNoYXJhY3RlciBvciBibG9jayBkZXZpY2UgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICJta25vZCIpIG9yIG5vdCBoYXNhdHRyKG9zLCAibWFrZWRldiIpOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoInNwZWNpYWwgZGV2aWNlcyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIpCgogICAgICAgIG1vZGUgPSB0YXJpbmZvLm1vZGUKICAgICAgICBpZiB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQkxLCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZDSFIKCiAgICAgICAgb3MubWtub2QodGFyZ2V0cGF0aCwgbW9kZSwKICAgICAgICAgICAgICAgICBvcy5tYWtlZGV2KHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKQoKICAgIGRlZiBtYWtlbGluayhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgKHN5bWJvbGljKSBsaW5rIGNhbGxlZCB0YXJnZXRwYXRoLiBJZiBpdCBjYW5ub3QgYmUgY3JlYXRlZAogICAgICAgICAgKHBsYXRmb3JtIGxpbWl0YXRpb24pLCB3ZSB0cnkgdG8gbWFrZSBhIGNvcHkgb2YgdGhlIHJlZmVyZW5jZWQgZmlsZQogICAgICAgICAgaW5zdGVhZCBvZiBhIGxpbmsuCiAgICAgICAgIiIiCiAgICAgICAgbGlua3BhdGggPSB0YXJpbmZvLmxpbmtuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBTZWUgZXh0cmFjdCgpLgogICAgICAgICAgICAgICAgb3MubGluayh0YXJpbmZvLl9saW5rX3RhcmdldCwgdGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5qb2luKG9zLnBhdGguZGlybmFtZSh0YXJpbmZvLm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua3BhdGgpCiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG5vcm1wYXRoKGxpbmtwYXRoKQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIoc2VsZi5nZXRtZW1iZXIobGlua3BhdGgpLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBleGNlcHQgKEVudmlyb25tZW50RXJyb3IsIEtleUVycm9yKSwgZToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5ub3JtcGF0aChsaW5rcGF0aCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBzaHV0aWwuY29weTIobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJsaW5rIGNvdWxkIG5vdCBiZSBjcmVhdGVkIikKCiAgICBkZWYgY2hvd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG93bmVyIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcHdkIGFuZCBoYXNhdHRyKG9zLCAiZ2V0ZXVpZCIpIGFuZCBvcy5nZXRldWlkKCkgPT0gMDoKICAgICAgICAgICAgIyBXZSBoYXZlIHRvIGJlIHJvb3QgdG8gZG8gc28uCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JuYW0odGFyaW5mby5nbmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgZyA9IG9zLmdldGdpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHduYW0odGFyaW5mby51bmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgdSA9IG9zLmdldHVpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKSBhbmQgaGFzYXR0cihvcywgImxjaG93biIpOgogICAgICAgICAgICAgICAgICAgIG9zLmxjaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gIm9zMmVteCI6CiAgICAgICAgICAgICAgICAgICAgICAgIG9zLmNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG93bmVyIikKCiAgICBkZWYgY2htb2Qoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IGZpbGUgcGVybWlzc2lvbnMgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAnY2htb2QnKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0cGF0aCwgdGFyaW5mby5tb2RlKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RlIikKCiAgICBkZWYgdXRpbWUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICd1dGltZScpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gIndpbjMyIiBhbmQgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAjIEFjY29yZGluZyB0byBtc2RuLm1pY3Jvc29mdC5jb20sIGl0IGlzIGFuIGVycm9yIChFQUNDRVMpCiAgICAgICAgICAgICMgdG8gdXNlIHV0aW1lKCkgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MudXRpbWUodGFyZ2V0cGF0aCwgKHRhcmluZm8ubXRpbWUsIHRhcmluZm8ubXRpbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2UgbW9kaWZpY2F0aW9uIHRpbWUiKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lbWJlciBvZiB0aGUgYXJjaGl2ZSBhcyBhIFRhckluZm8gb2JqZWN0LCB3aGVuCiAgICAgICAgICAgVGFyRmlsZSBpcyBvcGVuZWQgZm9yIHJlYWRpbmcuIFJldHVybiBOb25lIGlmIHRoZXJlIGlzIG5vIG1vcmUKICAgICAgICAgICBhdmFpbGFibGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInJhIikKICAgICAgICBpZiBzZWxmLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICBtID0gc2VsZi5maXJzdG1lbWJlcgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICByZXR1cm4gbQoKICAgICAgICAjIFJlYWQgdGhlIG5leHQgYmxvY2suCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQpCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyaW5mby5mcm9tdGFyZmlsZShzZWxmKQogICAgICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQoKICAgICAgICAgICAgZXhjZXB0IEhlYWRlckVycm9yLCBlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5pZ25vcmVfemVyb3M6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICIweCVYOiAlcyIgJSAoc2VsZi5vZmZzZXQsIGUpKQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYub2Zmc2V0ID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcihzdHIoZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgTGl0dGxlIGhlbHBlciBtZXRob2RzOgoKICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSk6CiAgICAgICAgIiIiRmluZCBhbiBhcmNoaXZlIG1lbWJlciBieSBuYW1lIGZyb20gYm90dG9tIHRvIHRvcC4KICAgICAgICAgICBJZiB0YXJpbmZvIGlzIGdpdmVuLCBpdCBpcyB1c2VkIGFzIHRoZSBzdGFydGluZyBwb2ludC4KICAgICAgICAiIiIKICAgICAgICAjIEVuc3VyZSB0aGF0IGFsbCBtZW1iZXJzIGhhdmUgYmVlbiBsb2FkZWQuCiAgICAgICAgbWVtYmVycyA9IHNlbGYuZ2V0bWVtYmVycygpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgZW5kID0gbGVuKG1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZW5kID0gbWVtYmVycy5pbmRleCh0YXJpbmZvKQoKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZW5kIC0gMSwgLTEsIC0xKToKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJzW2ldLm5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyc1tpXQoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoIiVzIGlzIGNsb3NlZCIgJSBzZWxmLl9fY2xhc3NfXy5fX25hbWVfXykKICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLm1vZGUgbm90IGluIG1vZGU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5tb2RlKQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJQcm92aWRlIGFuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHJldHVybiBpdGVyKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQoKICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBtc2cKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgICAgIHNlbGYuaW5kZXggPSAwCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4KICAgICAgICAiIiIKICAgICAgICAjIEZpeCBmb3IgU0YgIzExMDA0Mjk6IFVuZGVyIHJhcmUgY2lyY3Vtc3RhbmNlcyBpdCBjYW4KICAgICAgICAjIGhhcHBlbiB0aGF0IGdldG1lbWJlcnMoKSBpcyBjYWxsZWQgZHVyaW5nIGl0ZXJhdGlvbiwKICAgICAgICAjIHdoaWNoIHdpbGwgY2F1c2UgVGFySXRlciB0byBzdG9wIHByZW1hdHVyZWx5LgogICAgICAgIGlmIG5vdCBzZWxmLnRhcmZpbGUuX2xvYWRlZDoKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IHRhcmluZm86CiAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuX2xvYWRlZCA9IFRydWUKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm1lbWJlcnNbc2VsZi5pbmRleF0KICAgICAgICAgICAgZXhjZXB0IEluZGV4RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgc2VsZi5pbmRleCArPSAxCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiMgSGVscGVyIGNsYXNzZXMgZm9yIHNwYXJzZSBmaWxlIHN1cHBvcnQKY2xhc3MgX3NlY3Rpb246CiAgICAiIiJCYXNlIGNsYXNzIGZvciBfZGF0YSBhbmQgX2hvbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpOgogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgZGVmIF9fY29udGFpbnNfXyhzZWxmLCBvZmZzZXQpOgogICAgICAgIHJldHVybiBzZWxmLm9mZnNldCA8PSBvZmZzZXQgPCBzZWxmLm9mZnNldCArIHNlbGYuc2l6ZQoKY2xhc3MgX2RhdGEoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgZGF0YSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUsIHJlYWxwb3MpOgogICAgICAgIF9zZWN0aW9uLl9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSkKICAgICAgICBzZWxmLnJlYWxwb3MgPSByZWFscG9zCgpjbGFzcyBfaG9sZShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBob2xlIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgcGFzcwoKY2xhc3MgX3JpbmdidWZmZXIobGlzdCk6CiAgICAiIiJSaW5nYnVmZmVyIGNsYXNzIHdoaWNoIGluY3JlYXNlcyBwZXJmb3JtYW5jZQogICAgICAgb3ZlciBhIHJlZ3VsYXIgbGlzdC4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuaWR4ID0gMAogICAgZGVmIGZpbmQoc2VsZiwgb2Zmc2V0KToKICAgICAgICBpZHggPSBzZWxmLmlkeAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmW2lkeF0KICAgICAgICAgICAgaWYgb2Zmc2V0IGluIGl0ZW06CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZHggKz0gMQogICAgICAgICAgICBpZiBpZHggPT0gbGVuKHNlbGYpOgogICAgICAgICAgICAgICAgaWR4ID0gMAogICAgICAgICAgICBpZiBpZHggPT0gc2VsZi5pZHg6CiAgICAgICAgICAgICAgICAjIEVuZCBvZiBGaWxlCiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIHNlbGYuaWR4ID0gaWR4CiAgICAgICAgcmV0dXJuIGl0ZW0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB6aXBmaWxlIGNvbXBhdGlibGUgVGFyRmlsZSBjbGFzcwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRBUl9QTEFJTiA9IDAgICAgICAgICAgICMgemlwZmlsZS5aSVBfU1RPUkVEClRBUl9HWklQUEVEID0gOCAgICAgICAgICMgemlwZmlsZS5aSVBfREVGTEFURUQKY2xhc3MgVGFyRmlsZUNvbXBhdDoKICAgICIiIlRhckZpbGUgY2xhc3MgY29tcGF0aWJsZSB3aXRoIHN0YW5kYXJkIG1vZHVsZSB6aXBmaWxlJ3MKICAgICAgIFppcEZpbGUgY2xhc3MuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBtb2RlPSJyIiwgY29tcHJlc3Npb249VEFSX1BMQUlOKToKICAgICAgICBpZiBjb21wcmVzc2lvbiA9PSBUQVJfUExBSU46CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUudGFyb3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsaWYgY29tcHJlc3Npb24gPT0gVEFSX0daSVBQRUQ6CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUuZ3pvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIpCiAgICAgICAgaWYgbW9kZVswOjFdID09ICJyIjoKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkKICAgICAgICAgICAgZm9yIG0gaW4gbWVtYmVyczoKICAgICAgICAgICAgICAgIG0uZmlsZW5hbWUgPSBtLm5hbWUKICAgICAgICAgICAgICAgIG0uZmlsZV9zaXplID0gbS5zaXplCiAgICAgICAgICAgICAgICBtLmRhdGVfdGltZSA9IHRpbWUuZ210aW1lKG0ubXRpbWUpWzo2XQogICAgZGVmIG5hbWVsaXN0KHNlbGYpOgogICAgICAgIHJldHVybiBtYXAobGFtYmRhIG06IG0ubmFtZSwgc2VsZi5pbmZvbGlzdCgpKQogICAgZGVmIGluZm9saXN0KHNlbGYpOgogICAgICAgIHJldHVybiBmaWx0ZXIobGFtYmRhIG06IG0udHlwZSBpbiBSRUdVTEFSX1RZUEVTLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKSkKICAgIGRlZiBwcmludGRpcihzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUubGlzdCgpCiAgICBkZWYgdGVzdHppcChzZWxmKToKICAgICAgICByZXR1cm4KICAgIGRlZiBnZXRpbmZvKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpCiAgICBkZWYgcmVhZChzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmV4dHJhY3RmaWxlKHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkpLnJlYWQoKQogICAgZGVmIHdyaXRlKHNlbGYsIGZpbGVuYW1lLCBhcmNuYW1lPU5vbmUsIGNvbXByZXNzX3R5cGU9Tm9uZSk6CiAgICAgICAgc2VsZi50YXJmaWxlLmFkZChmaWxlbmFtZSwgYXJjbmFtZSkKICAgIGRlZiB3cml0ZXN0cihzZWxmLCB6aW5mbywgYnl0ZXMpOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnJvbSBjU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBmcm9tIFN0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGltcG9ydCBjYWxlbmRhcgogICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQogICAgICAgIHppbmZvLnNpemUgPSB6aW5mby5maWxlX3NpemUKICAgICAgICB6aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCmJsdG5fb3BlbiA9IG9wZW4Kb3BlbiA9IFRhckZpbGUub3Blbgo=