IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uOiA2MDczMCAkIgojICRTb3VyY2UkCgp2ZXJzaW9uICAgICA9ICIwLjguMCIKX19hdXRob3JfXyAgPSAiTGFycyBHdXN05GJlbCAobGFyc0BndXN0YWViZWwuZGUpIgpfX2RhdGVfXyAgICA9ICIkRGF0ZTogMjAwOC0wMi0xMSAxMDozNjowNyAtMDgwMCAoTW9uLCAxMSBGZWIgMjAwOCkgJCIKX19jdnNpZF9fICAgPSAiJElkOiB0YXJmaWxlLnB5IDYwNzMwIDIwMDgtMDItMTEgMTg6MzY6MDdaIGxhcnMuZ3VzdGFlYmVsICQiCl9fY3JlZGl0c19fID0gIkd1c3Rhdm8gTmllbWV5ZXIsIE5pZWxzIEd1c3TkYmVsLCBSaWNoYXJkIFRvd25zZW5kLiIKCiMtLS0tLS0tLS0KIyBJbXBvcnRzCiMtLS0tLS0tLS0KaW1wb3J0IHN5cwppbXBvcnQgb3MKaW1wb3J0IHNodXRpbAppbXBvcnQgc3RhdAppbXBvcnQgZXJybm8KaW1wb3J0IHRpbWUKaW1wb3J0IHN0cnVjdAppbXBvcnQgY29weQoKaWYgc3lzLnBsYXRmb3JtID09ICdtYWMnOgogICAgIyBUaGlzIG1vZHVsZSBuZWVkcyB3b3JrIGZvciBNYWNPUzksIGVzcGVjaWFsbHkgaW4gdGhlIGFyZWEgb2YgcGF0aG5hbWUKICAgICMgaGFuZGxpbmcuIEluIG1hbnkgcGxhY2VzIGl0IGlzIGFzc3VtZWQgYSBzaW1wbGUgc3Vic3RpdHV0aW9uIG9mIC8gYnkgdGhlCiAgICAjIGxvY2FsIG9zLnBhdGguc2VwIGlzIGdvb2QgZW5vdWdoIHRvIGNvbnZlcnQgcGF0aG5hbWVzLCBidXQgdGhpcyBkb2VzIG5vdAogICAgIyB3b3JrIHdpdGggdGhlIG1hYyByb290ZWQ6cGF0aDpuYW1lIHZlcnN1cyA6bm9ucm9vdGVkOnBhdGg6bmFtZSBzeW50YXgKICAgIHJhaXNlIEltcG9ydEVycm9yLCAidGFyZmlsZSBkb2VzIG5vdCB3b3JrIGZvciBwbGF0Zm9ybT09bWFjIgoKdHJ5OgogICAgaW1wb3J0IGdycCwgcHdkCmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgIGdycCA9IHB3ZCA9IE5vbmUKCiMgZnJvbSB0YXJmaWxlIGltcG9ydCAqCl9fYWxsX18gPSBbIlRhckZpbGUiLCAiVGFySW5mbyIsICJpc190YXJmaWxlIiwgIlRhckVycm9yIl0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXIgY29uc3RhbnRzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KTlVMICAgICAgICA9ICJcMCIgICAgICAgICAgICAgICAjIHRoZSBudWxsIGNoYXJhY3RlcgpCTE9DS1NJWkUgID0gNTEyICAgICAgICAgICAgICAgICMgbGVuZ3RoIG9mIHByb2Nlc3NpbmcgYmxvY2tzClJFQ09SRFNJWkUgPSBCTE9DS1NJWkUgKiAyMCAgICAgIyBsZW5ndGggb2YgcmVjb3JkcwpNQUdJQyAgICAgID0gInVzdGFyIiAgICAgICAgICAgICMgbWFnaWMgdGFyIHN0cmluZwpWRVJTSU9OICAgID0gIjAwIiAgICAgICAgICAgICAgICMgdmVyc2lvbiBudW1iZXIKCkxFTkdUSF9OQU1FICAgID0gMTAwICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiBhIGZpbGVuYW1lCkxFTkdUSF9MSU5LICAgID0gMTAwICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiBhIGxpbmtuYW1lCkxFTkdUSF9QUkVGSVggID0gMTU1ICAgICAgICAgICAgIyBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgcHJlZml4IGZpZWxkCk1BWFNJWkVfTUVNQkVSID0gMDc3Nzc3Nzc3Nzc3TCAgIyBtYXhpbXVtIHNpemUgb2YgYSBmaWxlICgxMSBvY3RhbCBkaWdpdHMpCgpSRUdUWVBFICA9ICIwIiAgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkFSRUdUWVBFID0gIlwwIiAgICAgICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUKTE5LVFlQRSAgPSAiMSIgICAgICAgICAgICAgICAgICAjIGxpbmsgKGluc2lkZSB0YXJmaWxlKQpTWU1UWVBFICA9ICIyIiAgICAgICAgICAgICAgICAgICMgc3ltYm9saWMgbGluawpDSFJUWVBFICA9ICIzIiAgICAgICAgICAgICAgICAgICMgY2hhcmFjdGVyIHNwZWNpYWwgZGV2aWNlCkJMS1RZUEUgID0gIjQiICAgICAgICAgICAgICAgICAgIyBibG9jayBzcGVjaWFsIGRldmljZQpESVJUWVBFICA9ICI1IiAgICAgICAgICAgICAgICAgICMgZGlyZWN0b3J5CkZJRk9UWVBFID0gIjYiICAgICAgICAgICAgICAgICAgIyBmaWZvIHNwZWNpYWwgZGV2aWNlCkNPTlRUWVBFID0gIjciICAgICAgICAgICAgICAgICAgIyBjb250aWd1b3VzIGZpbGUKCkdOVVRZUEVfTE9OR05BTUUgPSAiTCIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3IgbG9uZ25hbWVzCkdOVVRZUEVfTE9OR0xJTksgPSAiSyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3IgbG9uZ2xpbmsKR05VVFlQRV9TUEFSU0UgICA9ICJTIiAgICAgICAgICAjIEdOVSB0YXIgZXh0ZW5zaW9uIGZvciBzcGFyc2UgZmlsZQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhcmZpbGUgY29uc3RhbnRzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU1VQUE9SVEVEX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCBMTktUWVBFLCAgIyBmaWxlIHR5cGVzIHRoYXQgdGFyZmlsZQogICAgICAgICAgICAgICAgICAgU1lNVFlQRSwgRElSVFlQRSwgRklGT1RZUEUsICAjIGNhbiBjb3BlIHdpdGguCiAgICAgICAgICAgICAgICAgICBDT05UVFlQRSwgQ0hSVFlQRSwgQkxLVFlQRSwKICAgICAgICAgICAgICAgICAgIEdOVVRZUEVfTE9OR05BTUUsIEdOVVRZUEVfTE9OR0xJTkssCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkKClJFR1VMQVJfVFlQRVMgPSAoUkVHVFlQRSwgQVJFR1RZUEUsICAgICAgICAgICAgICMgZmlsZSB0eXBlcyB0aGF0IHNvbWVob3cKICAgICAgICAgICAgICAgICBDT05UVFlQRSwgR05VVFlQRV9TUEFSU0UpICAgICAgIyByZXByZXNlbnQgcmVndWxhciBmaWxlcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEJpdHMgdXNlZCBpbiB0aGUgbW9kZSBmaWVsZCwgdmFsdWVzIGluIG9jdGFsLgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNfSUZMTksgPSAwMTIwMDAwICAgICAgICAjIHN5bWJvbGljIGxpbmsKU19JRlJFRyA9IDAxMDAwMDAgICAgICAgICMgcmVndWxhciBmaWxlClNfSUZCTEsgPSAwMDYwMDAwICAgICAgICAjIGJsb2NrIGRldmljZQpTX0lGRElSID0gMDA0MDAwMCAgICAgICAgIyBkaXJlY3RvcnkKU19JRkNIUiA9IDAwMjAwMDAgICAgICAgICMgY2hhcmFjdGVyIGRldmljZQpTX0lGSUZPID0gMDAxMDAwMCAgICAgICAgIyBmaWZvCgpUU1VJRCAgID0gMDQwMDAgICAgICAgICAgIyBzZXQgVUlEIG9uIGV4ZWN1dGlvbgpUU0dJRCAgID0gMDIwMDAgICAgICAgICAgIyBzZXQgR0lEIG9uIGV4ZWN1dGlvbgpUU1ZUWCAgID0gMDEwMDAgICAgICAgICAgIyByZXNlcnZlZAoKVFVSRUFEICA9IDA0MDAgICAgICAgICAgICMgcmVhZCBieSBvd25lcgpUVVdSSVRFID0gMDIwMCAgICAgICAgICAgIyB3cml0ZSBieSBvd25lcgpUVUVYRUMgID0gMDEwMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvd25lcgpUR1JFQUQgID0gMDA0MCAgICAgICAgICAgIyByZWFkIGJ5IGdyb3VwClRHV1JJVEUgPSAwMDIwICAgICAgICAgICAjIHdyaXRlIGJ5IGdyb3VwClRHRVhFQyAgPSAwMDEwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IGdyb3VwClRPUkVBRCAgPSAwMDA0ICAgICAgICAgICAjIHJlYWQgYnkgb3RoZXIKVE9XUklURSA9IDAwMDIgICAgICAgICAgICMgd3JpdGUgYnkgb3RoZXIKVE9FWEVDICA9IDAwMDEgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3RoZXIKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBTb21lIHVzZWZ1bCBmdW5jdGlvbnMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVmIHN0bihzLCBsZW5ndGgpOgogICAgIiIiQ29udmVydCBhIHB5dGhvbiBzdHJpbmcgdG8gYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlci4KICAgICIiIgogICAgcmV0dXJuIHNbOmxlbmd0aF0gKyAobGVuZ3RoIC0gbGVuKHMpKSAqIE5VTAoKZGVmIG50cyhzKToKICAgICIiIkNvbnZlcnQgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGZpZWxkIHRvIGEgcHl0aG9uIHN0cmluZy4KICAgICIiIgogICAgIyBVc2UgdGhlIHN0cmluZyB1cCB0byB0aGUgZmlyc3QgbnVsbCBjaGFyLgogICAgcCA9IHMuZmluZCgiXDAiKQogICAgaWYgcCA9PSAtMToKICAgICAgICByZXR1cm4gcwogICAgcmV0dXJuIHNbOnBdCgpkZWYgbnRpKHMpOgogICAgIiIiQ29udmVydCBhIG51bWJlciBmaWVsZCB0byBhIHB5dGhvbiBudW1iZXIuCiAgICAiIiIKICAgICMgVGhlcmUgYXJlIHR3byBwb3NzaWJsZSBlbmNvZGluZ3MgZm9yIGEgbnVtYmVyIGZpZWxkLCBzZWUKICAgICMgaXRuKCkgYmVsb3cuCiAgICBpZiBzWzBdICE9IGNocigwMjAwKToKICAgICAgICBuID0gaW50KG50cyhzKSBvciAiMCIsIDgpCiAgICBlbHNlOgogICAgICAgIG4gPSAwTAogICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4ocykgLSAxKToKICAgICAgICAgICAgbiA8PD0gOAogICAgICAgICAgICBuICs9IG9yZChzW2kgKyAxXSkKICAgIHJldHVybiBuCgpkZWYgaXRuKG4sIGRpZ2l0cz04LCBwb3NpeD1GYWxzZSk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIG51bWJlciB0byBhIG51bWJlciBmaWVsZC4KICAgICIiIgogICAgIyBQT1NJWCAxMDAzLjEtMTk4OCByZXF1aXJlcyBudW1iZXJzIHRvIGJlIGVuY29kZWQgYXMgYSBzdHJpbmcgb2YKICAgICMgb2N0YWwgZGlnaXRzIGZvbGxvd2VkIGJ5IGEgbnVsbC1ieXRlLCB0aGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8KICAgICMgKDgqKihkaWdpdHMtMSkpLTEuIEdOVSB0YXIgYWxsb3dzIHN0b3JpbmcgbnVtYmVycyBncmVhdGVyIHRoYW4KICAgICMgdGhhdCBpZiBuZWNlc3NhcnkuIEEgbGVhZGluZyAwMjAwIGJ5dGUgaW5kaWNhdGVzIHRoaXMgcGFydGljdWxhcgogICAgIyBlbmNvZGluZywgdGhlIGZvbGxvd2luZyBkaWdpdHMtMSBieXRlcyBhcmUgYSBiaWctZW5kaWFuCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4KICAgIGlmIDAgPD0gbiA8IDggKiogKGRpZ2l0cyAtIDEpOgogICAgICAgIHMgPSAiJTAqbyIgJSAoZGlnaXRzIC0gMSwgbikgKyBOVUwKICAgIGVsc2U6CiAgICAgICAgaWYgcG9zaXg6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm92ZXJmbG93IGluIG51bWJlciBmaWVsZCIpCgogICAgICAgIGlmIG4gPCAwOgogICAgICAgICAgICAjIFhYWCBXZSBtaW1pYyBHTlUgdGFyJ3MgYmVoYXZpb3VyIHdpdGggbmVnYXRpdmUgbnVtYmVycywKICAgICAgICAgICAgIyB0aGlzIGNvdWxkIHJhaXNlIE92ZXJmbG93RXJyb3IuCiAgICAgICAgICAgIG4gPSBzdHJ1Y3QudW5wYWNrKCJMIiwgc3RydWN0LnBhY2soImwiLCBuKSlbMF0KCiAgICAgICAgcyA9ICIiCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICBzID0gY2hyKG4gJiAwMzc3KSArIHMKICAgICAgICAgICAgbiA+Pj0gOAogICAgICAgIHMgPSBjaHIoMDIwMCkgKyBzCiAgICByZXR1cm4gcwoKZGVmIGNhbGNfY2hrc3VtcyhidWYpOgogICAgIiIiQ2FsY3VsYXRlIHRoZSBjaGVja3N1bSBmb3IgYSBtZW1iZXIncyBoZWFkZXIgYnkgc3VtbWluZyB1cCBhbGwKICAgICAgIGNoYXJhY3RlcnMgZXhjZXB0IGZvciB0aGUgY2hrc3VtIGZpZWxkIHdoaWNoIGlzIHRyZWF0ZWQgYXMgaWYKICAgICAgIGl0IHdhcyBmaWxsZWQgd2l0aCBzcGFjZXMuIEFjY29yZGluZyB0byB0aGUgR05VIHRhciBzb3VyY2VzLAogICAgICAgc29tZSB0YXJzIChTdW4gYW5kIE5lWFQpIGNhbGN1bGF0ZSBjaGtzdW0gd2l0aCBzaWduZWQgY2hhciwKICAgICAgIHdoaWNoIHdpbGwgYmUgZGlmZmVyZW50IGlmIHRoZXJlIGFyZSBjaGFycyBpbiB0aGUgYnVmZmVyIHdpdGgKICAgICAgIHRoZSBoaWdoIGJpdCBzZXQuIFNvIHdlIGNhbGN1bGF0ZSB0d28gY2hlY2tzdW1zLCB1bnNpZ25lZCBhbmQKICAgICAgIHNpZ25lZC4KICAgICIiIgogICAgdW5zaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OEIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2QiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICBzaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OGIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2YiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICByZXR1cm4gdW5zaWduZWRfY2hrc3VtLCBzaWduZWRfY2hrc3VtCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgICMgVGhlIG5hdGl2ZSB6bGliIGNyYyBpcyBhbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgYnV0CiAgICAgICAgICAgICAgICAjIHRoZSBQeXRob24gd3JhcHBlciBpbXBsaWNpdGx5IGNhc3RzIHRoYXQgdG8gYSBzaWduZWQgQwogICAgICAgICAgICAgICAgIyBsb25nLiAgU28sIG9uIGEgMzItYml0IGJveCBzZWxmLmNyYyBtYXkgImxvb2sgbmVnYXRpdmUiLAogICAgICAgICAgICAgICAgIyB3aGlsZSB0aGUgc2FtZSBjcmMgb24gYSA2NC1iaXQgYm94IG1heSAibG9vayBwb3NpdGl2ZSIuCiAgICAgICAgICAgICAgICAjIFRvIGF2b2lkIGlya3NvbWUgd2FybmluZ3MgZnJvbSB0aGUgYHN0cnVjdGAgbW9kdWxlLCBmb3JjZQogICAgICAgICAgICAgICAgIyBpdCB0byBsb29rIHBvc2l0aXZlIG9uIGFsbCBib3hlcy4KICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLmNyYyAmIDB4ZmZmZmZmZmZMKSkKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcyAmIDB4ZmZmZkZGRkZMKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfaW5pdF9yZWFkX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5kZWNvbXByZXNzb2JqKC1zZWxmLnpsaWIuTUFYX1dCSVRTKQogICAgICAgIHNlbGYuZGJ1ZiA9ICIiCgogICAgICAgICMgdGFrZW4gZnJvbSBnemlwLkd6aXBGaWxlIHdpdGggc29tZSBhbHRlcmF0aW9ucwogICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICBpZiBzZWxmLl9fcmVhZCgxKSAhPSAiXDAxMCI6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCIpCgogICAgICAgIGZsYWcgPSBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgc2VsZi5fX3JlYWQoNikKCiAgICAgICAgaWYgZmxhZyAmIDQ6CiAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikKICAgICAgICBpZiBmbGFnICYgODoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMTY6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDI6CiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zPTApOgogICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZwogICAgICAgICAgIGlzIGZvcmJpZGRlbi4KICAgICAgICAiIiIKICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoYmxvY2tzKToKICAgICAgICAgICAgICAgIHNlbGYucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIHNlbGYucmVhZChyZW1haW5kZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoInNlZWtpbmcgYmFja3dhcmRzIGlzIG5vdCBhbGxvd2VkIikKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBzaXplIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgICAgSWYgc2l6ZSBpcyBub3QgZGVmaW5lZCwgcmV0dXJuIGFsbCBieXRlcyBvZiB0aGUgc3RyZWFtCiAgICAgICAgICAgdXAgdG8gRU9GLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgdCA9IFtdCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYnVmID0gIiIuam9pbih0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2l6ZSkKICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gInRhciI6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQoKICAgICAgICBjID0gbGVuKHNlbGYuZGJ1ZikKICAgICAgICB0ID0gW3NlbGYuZGJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgYnVmID0gc2VsZi5jbXAuZGVjb21wcmVzcyhidWYpCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5kYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KCiAgICBkZWYgX19yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gc3RyZWFtLiBJZiBpbnRlcm5hbCBidWZmZXIgaXMgZW1wdHksCiAgICAgICAgICAgcmVhZCBhbm90aGVyIGJsb2NrIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBjID0gbGVuKHNlbGYuYnVmKQogICAgICAgIHQgPSBbc2VsZi5idWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5idWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQojIGNsYXNzIF9TdHJlYW0KCmNsYXNzIF9TdHJlYW1Qcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICBkZXRlY3Rpb24gZm9yIHRoZSBTdHJlYW0gaW50ZXJmYWNlIChtb2RlICdyfConKS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5maWxlb2JqLnJlYWQKICAgICAgICByZXR1cm4gc2VsZi5idWYKCiAgICBkZWYgZ2V0Y29tcHR5cGUoc2VsZik6CiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiXDAzN1wyMTNcMDEwIik6CiAgICAgICAgICAgIHJldHVybiAiZ3oiCiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiQlpoOTEiKToKICAgICAgICAgICAgcmV0dXJuICJiejIiCiAgICAgICAgcmV0dXJuICJ0YXIiCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgU3RyZWFtUHJveHkKCmNsYXNzIF9CWjJQcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIGV4dGVybmFsIGZpbGUgb2JqZWN0CiAgICAgICBzdXBwb3J0IGZvciAicjpiejIiIGFuZCAidzpiejIiIG1vZGVzLiBUaGlzIGlzIGFjdHVhbGx5CiAgICAgICBhIHdvcmthcm91bmQgZm9yIGEgbGltaXRhdGlvbiBpbiBiejIgbW9kdWxlJ3MgQloyRmlsZQogICAgICAgY2xhc3Mgd2hpY2ggKHVubGlrZSBnemlwLkd6aXBGaWxlKSBoYXMgbm8gc3VwcG9ydCBmb3IKICAgICAgIGEgZmlsZSBvYmplY3QgYXJndW1lbnQuCiAgICAiIiIKCiAgICBibG9ja3NpemUgPSAxNiAqIDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgbW9kZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLmluaXQoKQoKICAgIGRlZiBpbml0KHNlbGYpOgogICAgICAgIGltcG9ydCBiejIKICAgICAgICBzZWxmLnBvcyA9IDAKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInIiOgogICAgICAgICAgICBzZWxmLmJ6Mm9iaiA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygwKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgYiA9IFtzZWxmLmJ1Zl0KICAgICAgICB4ID0gbGVuKHNlbGYuYnVmKQogICAgICAgIHdoaWxlIHggPCBzaXplOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByYXcgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJsb2Nrc2l6ZSkKICAgICAgICAgICAgICAgIGRhdGEgPSBzZWxmLmJ6Mm9iai5kZWNvbXByZXNzKHJhdykKICAgICAgICAgICAgICAgIGIuYXBwZW5kKGRhdGEpCiAgICAgICAgICAgIGV4Y2VwdCBFT0ZFcnJvcjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHggKz0gbGVuKGRhdGEpCiAgICAgICAgc2VsZi5idWYgPSAiIi5qb2luKGIpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmWzpzaXplXQogICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2l6ZTpdCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zKToKICAgICAgICBpZiBwb3MgPCBzZWxmLnBvczoKICAgICAgICAgICAgc2VsZi5pbml0KCkKICAgICAgICBzZWxmLnJlYWQocG9zIC0gc2VsZi5wb3MpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHdyaXRlKHNlbGYsIGRhdGEpOgogICAgICAgIHNlbGYucG9zICs9IGxlbihkYXRhKQogICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmNvbXByZXNzKGRhdGEpCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IjoKICAgICAgICAgICAgcmF3ID0gc2VsZi5iejJvYmouZmx1c2goKQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUocmF3KQogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgX0JaMlByb3h5CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXh0cmFjdGlvbiBmaWxlIG9iamVjdAojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIF9GaWxlSW5GaWxlKG9iamVjdCk6CiAgICAiIiJBIHRoaW4gd3JhcHBlciBhcm91bmQgYW4gZXhpc3RpbmcgZmlsZSBvYmplY3QgdGhhdAogICAgICAgcHJvdmlkZXMgYSBwYXJ0IG9mIGl0cyBkYXRhIGFzIGFuIGluZGl2aWR1YWwgZmlsZQogICAgICAgb2JqZWN0LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmosIG9mZnNldCwgc2l6ZSwgc3BhcnNlPU5vbmUpOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLm9mZnNldCA9IG9mZnNldAogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKICAgICAgICBzZWxmLnNwYXJzZSA9IHNwYXJzZQogICAgICAgIHNlbGYucG9zaXRpb24gPSAwCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zaXRpb24KCiAgICBkZWYgc2VlayhzZWxmLCBwb3NpdGlvbik6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYucG9zaXRpb24gPSBwb3NpdGlvbgoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBkYXRhIGZyb20gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICBzaXplID0gc2VsZi5zaXplIC0gc2VsZi5wb3NpdGlvbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNpemUgPSBtaW4oc2l6ZSwgc2VsZi5zaXplIC0gc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgc2VsZi5zcGFyc2UgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucmVhZG5vcm1hbChzaXplKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnJlYWRzcGFyc2Uoc2l6ZSkKCiAgICBkZWYgcmVhZG5vcm1hbChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3IgcmVndWxhciBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHNlbGYucG9zaXRpb24pCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iai5yZWFkKHNpemUpCgogICAgZGVmIHJlYWRzcGFyc2Uoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5yZWFkc3BhcnNlc2VjdGlvbihzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oYnVmKQogICAgICAgICAgICBkYXRhLmFwcGVuZChidWYpCiAgICAgICAgcmV0dXJuICIiLmpvaW4oZGF0YSkKCiAgICBkZWYgcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBhIHNpbmdsZSBzZWN0aW9uIG9mIGEgc3BhcnNlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3NpdGlvbiAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgcmVhbHBvcykKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgICAgICByZXR1cm4gTlVMICogc2l6ZQojY2xhc3MgX0ZpbGVJbkZpbGUKCgpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuCiAgICAiIiIKICAgIGJsb2Nrc2l6ZSA9IDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gX0ZpbGVJbkZpbGUodGFyZmlsZS5maWxlb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldGF0dHIodGFyaW5mbywgInNwYXJzZSIsIE5vbmUpKQogICAgICAgIHNlbGYubmFtZSA9IHRhcmluZm8ubmFtZQogICAgICAgIHNlbGYubW9kZSA9ICJyIgogICAgICAgIHNlbGYuY2xvc2VkID0gRmFsc2UKICAgICAgICBzZWxmLnNpemUgPSB0YXJpbmZvLnNpemUKCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDAKICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIGF0IG1vc3Qgc2l6ZSBieXRlcyBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIG5vdAogICAgICAgICAgIHByZXNlbnQgb3IgTm9uZSwgcmVhZCBhbGwgZGF0YSB1bnRpbCBFT0YgaXMgcmVhY2hlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgaWYgc2VsZi5idWZmZXI6CiAgICAgICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6c2l6ZV0KICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gc2VsZi5idWZmZXJbc2l6ZTpdCgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnVmICs9IHNlbGYuZmlsZW9iai5yZWFkKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgKz0gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSAtIGxlbihidWYpKQoKICAgICAgICBzZWxmLnBvc2l0aW9uICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIG9uZSBlbnRpcmUgbGluZSBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIHByZXNlbnQKICAgICAgICAgICBhbmQgbm9uLW5lZ2F0aXZlLCByZXR1cm4gYSBzdHJpbmcgd2l0aCBhdCBtb3N0IHRoYXQKICAgICAgICAgICBzaXplLCB3aGljaCBtYXkgYmUgYW4gaW5jb21wbGV0ZSBsaW5lLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgaWYgIlxuIiBpbiBzZWxmLmJ1ZmZlcjoKICAgICAgICAgICAgcG9zID0gc2VsZi5idWZmZXIuZmluZCgiXG4iKSArIDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWZmZXJzID0gW3NlbGYuYnVmZmVyXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBidWZmZXJzLmFwcGVuZChidWYpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmIG9yICJcbiIgaW4gYnVmOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gIiIuam9pbihidWZmZXJzKQogICAgICAgICAgICAgICAgICAgIHBvcyA9IHNlbGYuYnVmZmVyLmZpbmQoIlxuIikgKyAxCiAgICAgICAgICAgICAgICAgICAgaWYgcG9zID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICMgbm8gbmV3bGluZSBmb3VuZC4KICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gbGVuKHNlbGYuYnVmZmVyKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNpemUgIT0gLTE6CiAgICAgICAgICAgIHBvcyA9IG1pbihzaXplLCBwb3MpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyWzpwb3NdCiAgICAgICAgc2VsZi5idWZmZXIgPSBzZWxmLmJ1ZmZlcltwb3M6XQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IHdpdGggYWxsIHJlbWFpbmluZyBsaW5lcy4KICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBbXQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICByZXR1cm4gc2VsZi5wb3NpdGlvbgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcywgd2hlbmNlPW9zLlNFRUtfU0VUKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBpZiB3aGVuY2UgPT0gb3MuU0VFS19TRVQ6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0NVUjoKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtYXgoc2VsZi5wb3NpdGlvbiArIHBvcywgMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4oc2VsZi5wb3NpdGlvbiArIHBvcywgc2VsZi5zaXplKQogICAgICAgIGVsaWYgd2hlbmNlID09IG9zLlNFRUtfRU5EOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KG1pbihzZWxmLnNpemUgKyBwb3MsIHNlbGYuc2l6ZSksIDApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSW52YWxpZCBhcmd1bWVudCIpCgogICAgICAgIHNlbGYuYnVmZmVyID0gIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLnBvc2l0aW9uKQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgZmlsZSBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIkdldCBhbiBpdGVyYXRvciBvdmVyIHRoZSBmaWxlJ3MgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHlpZWxkIGxpbmUKI2NsYXNzIEV4RmlsZU9iamVjdAoKIy0tLS0tLS0tLS0tLS0tLS0tLQojIEV4cG9ydGVkIENsYXNzZXMKIy0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBUYXJJbmZvKG9iamVjdCk6CiAgICAiIiJJbmZvcm1hdGlvbmFsIGNsYXNzIHdoaWNoIGhvbGRzIHRoZSBkZXRhaWxzIGFib3V0IGFuCiAgICAgICBhcmNoaXZlIG1lbWJlciBnaXZlbiBieSBhIHRhciBoZWFkZXIgYmxvY2suCiAgICAgICBUYXJJbmZvIG9iamVjdHMgYXJlIHJldHVybmVkIGJ5IFRhckZpbGUuZ2V0bWVtYmVyKCksCiAgICAgICBUYXJGaWxlLmdldG1lbWJlcnMoKSBhbmQgVGFyRmlsZS5nZXR0YXJpbmZvKCkgYW5kIGFyZQogICAgICAgdXN1YWxseSBjcmVhdGVkIGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT0iIik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QuIG5hbWUgaXMgdGhlIG9wdGlvbmFsIG5hbWUKICAgICAgICAgICBvZiB0aGUgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUgICAgICAgICMgbWVtYmVyIG5hbWUgKGRpcm5hbWVzIG11c3QgZW5kIHdpdGggJy8nKQogICAgICAgIHNlbGYubW9kZSA9IDA2NjYgICAgICAgICMgZmlsZSBwZXJtaXNzaW9ucwogICAgICAgIHNlbGYudWlkID0gMCAgICAgICAgICAgICMgdXNlciBpZAogICAgICAgIHNlbGYuZ2lkID0gMCAgICAgICAgICAgICMgZ3JvdXAgaWQKICAgICAgICBzZWxmLnNpemUgPSAwICAgICAgICAgICAjIGZpbGUgc2l6ZQogICAgICAgIHNlbGYubXRpbWUgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUKICAgICAgICBzZWxmLmNoa3N1bSA9IDAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQogICAgICAgIHNlbGYudHlwZSA9IFJFR1RZUEUgICAgICMgbWVtYmVyIHR5cGUKICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAjIGxpbmsgbmFtZQogICAgICAgIHNlbGYudW5hbWUgPSAidXNlciIgICAgICMgdXNlciBuYW1lCiAgICAgICAgc2VsZi5nbmFtZSA9ICJncm91cCIgICAgIyBncm91cCBuYW1lCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgIyBkZXZpY2UgbWFqb3IgbnVtYmVyCiAgICAgICAgc2VsZi5kZXZtaW5vciA9IDAgICAgICAgIyBkZXZpY2UgbWlub3IgbnVtYmVyCgogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgIT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikKICAgICAgICBpZiBidWYuY291bnQoTlVMKSA9PSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImVtcHR5IGhlYWRlciIpCgogICAgICAgIHRhcmluZm8gPSBjbHMoKQogICAgICAgIHRhcmluZm8uYnVmID0gYnVmCiAgICAgICAgdGFyaW5mby5uYW1lID0gbnRzKGJ1ZlswOjEwMF0pCiAgICAgICAgdGFyaW5mby5tb2RlID0gbnRpKGJ1ZlsxMDA6MTA4XSkKICAgICAgICB0YXJpbmZvLnVpZCA9IG50aShidWZbMTA4OjExNl0pCiAgICAgICAgdGFyaW5mby5naWQgPSBudGkoYnVmWzExNjoxMjRdKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG50aShidWZbMTI0OjEzNl0pCiAgICAgICAgdGFyaW5mby5tdGltZSA9IG50aShidWZbMTM2OjE0OF0pCiAgICAgICAgdGFyaW5mby5jaGtzdW0gPSBudGkoYnVmWzE0ODoxNTZdKQogICAgICAgIHRhcmluZm8udHlwZSA9IGJ1ZlsxNTY6MTU3XQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBudHMoYnVmWzE1NzoyNTddKQogICAgICAgIHRhcmluZm8udW5hbWUgPSBudHMoYnVmWzI2NToyOTddKQogICAgICAgIHRhcmluZm8uZ25hbWUgPSBudHMoYnVmWzI5NzozMjldKQogICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSBudGkoYnVmWzMyOTozMzddKQogICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBudGkoYnVmWzMzNzozNDVdKQogICAgICAgIHByZWZpeCA9IG50cyhidWZbMzQ1OjUwMF0pCgogICAgICAgIGlmIHByZWZpeCBhbmQgbm90IHRhcmluZm8uaXNzcGFyc2UoKToKICAgICAgICAgICAgdGFyaW5mby5uYW1lID0gcHJlZml4ICsgIi8iICsgdGFyaW5mby5uYW1lCgogICAgICAgIGlmIHRhcmluZm8uY2hrc3VtIG5vdCBpbiBjYWxjX2Noa3N1bXMoYnVmKToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiaW52YWxpZCBoZWFkZXIiKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIHRvYnVmKHNlbGYsIHBvc2l4PUZhbHNlKToKICAgICAgICAiIiJSZXR1cm4gYSB0YXIgaGVhZGVyIGFzIGEgc3RyaW5nIG9mIDUxMiBieXRlIGJsb2Nrcy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSAiIgogICAgICAgIHR5cGUgPSBzZWxmLnR5cGUKICAgICAgICBwcmVmaXggPSAiIgoKICAgICAgICBpZiBzZWxmLm5hbWUuZW5kc3dpdGgoIi8iKToKICAgICAgICAgICAgdHlwZSA9IERJUlRZUEUKCiAgICAgICAgaWYgdHlwZSBpbiAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSyk6CiAgICAgICAgICAgICMgUHJldmVudCAiLi8uL0BMb25nTGluayIgZnJvbSBiZWluZyBub3JtYWxpemVkLgogICAgICAgICAgICBuYW1lID0gc2VsZi5uYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbmFtZSA9IG5vcm1wYXRoKHNlbGYubmFtZSkKCiAgICAgICAgaWYgdHlwZSA9PSBESVJUWVBFOgogICAgICAgICAgICAjIGRpcmVjdG9yaWVzIHNob3VsZCBlbmQgd2l0aCAnLycKICAgICAgICAgICAgbmFtZSArPSAiLyIKCiAgICAgICAgbGlua25hbWUgPSBzZWxmLmxpbmtuYW1lCiAgICAgICAgaWYgbGlua25hbWU6CiAgICAgICAgICAgICMgaWYgbGlua25hbWUgaXMgZW1wdHkgd2UgZW5kIHVwIHdpdGggYSAnLicKICAgICAgICAgICAgbGlua25hbWUgPSBub3JtcGF0aChsaW5rbmFtZSkKCiAgICAgICAgaWYgcG9zaXg6CiAgICAgICAgICAgIGlmIHNlbGYuc2l6ZSA+IE1BWFNJWkVfTUVNQkVSOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiZmlsZSBpcyB0b28gbGFyZ2UgKD49IDggR0IpIikKCiAgICAgICAgICAgIGlmIGxlbihzZWxmLmxpbmtuYW1lKSA+IExFTkdUSF9MSU5LOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibGlua25hbWUgaXMgdG9vIGxvbmcgKD4lZCkiICUgKExFTkdUSF9MSU5LKSkKCiAgICAgICAgICAgIGlmIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZVs6TEVOR1RIX1BSRUZJWCArIDFdCiAgICAgICAgICAgICAgICB3aGlsZSBwcmVmaXggYW5kIHByZWZpeFstMV0gIT0gIi8iOgogICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWVbbGVuKHByZWZpeCk6XQogICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5hbWUgaXMgdG9vIGxvbmciKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBsZW4oc2VsZi5saW5rbmFtZSkgPiBMRU5HVEhfTElOSzoKICAgICAgICAgICAgICAgIGJ1ZiArPSBzZWxmLl9jcmVhdGVfZ251bG9uZyhzZWxmLmxpbmtuYW1lLCBHTlVUWVBFX0xPTkdMSU5LKQoKICAgICAgICAgICAgaWYgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgICAgICBidWYgKz0gc2VsZi5fY3JlYXRlX2dudWxvbmcobmFtZSwgR05VVFlQRV9MT05HTkFNRSkKCiAgICAgICAgcGFydHMgPSBbCiAgICAgICAgICAgIHN0bihuYW1lLCAxMDApLAogICAgICAgICAgICBpdG4oc2VsZi5tb2RlICYgMDc3NzcsIDgsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYudWlkLCA4LCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLmdpZCwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5zaXplLCAxMiwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5tdGltZSwgMTIsIHBvc2l4KSwKICAgICAgICAgICAgIiAgICAgICAgIiwgIyBjaGVja3N1bSBmaWVsZAogICAgICAgICAgICB0eXBlLAogICAgICAgICAgICBzdG4oc2VsZi5saW5rbmFtZSwgMTAwKSwKICAgICAgICAgICAgc3RuKE1BR0lDLCA2KSwKICAgICAgICAgICAgc3RuKFZFUlNJT04sIDIpLAogICAgICAgICAgICBzdG4oc2VsZi51bmFtZSwgMzIpLAogICAgICAgICAgICBzdG4oc2VsZi5nbmFtZSwgMzIpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtYWpvciwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtaW5vciwgOCwgcG9zaXgpLAogICAgICAgICAgICBzdG4ocHJlZml4LCAxNTUpCiAgICAgICAgXQoKICAgICAgICBidWYgKz0gIiIuam9pbihwYXJ0cykubGp1c3QoQkxPQ0tTSVpFLCBOVUwpCiAgICAgICAgY2hrc3VtID0gY2FsY19jaGtzdW1zKGJ1ZlstQkxPQ0tTSVpFOl0pWzBdCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQogICAgICAgIHNlbGYuYnVmID0gYnVmCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBfY3JlYXRlX2dudWxvbmcoc2VsZiwgbmFtZSwgdHlwZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgR05VIGxvbmduYW1lL2xvbmdsaW5rIGhlYWRlciBmcm9tIG5hbWUuCiAgICAgICAgICAgSXQgY29uc2lzdHMgb2YgYW4gZXh0ZW5kZWQgdGFyIGhlYWRlciwgd2l0aCB0aGUgbGVuZ3RoCiAgICAgICAgICAgb2YgdGhlIGxvbmduYW1lIGFzIHNpemUsIGZvbGxvd2VkIGJ5IGRhdGEgYmxvY2tzLAogICAgICAgICAgIHdoaWNoIGNvbnRhaW4gdGhlIGxvbmduYW1lIGFzIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBuYW1lICs9IE5VTAoKICAgICAgICB0YXJpbmZvID0gc2VsZi5fX2NsYXNzX18oKQogICAgICAgIHRhcmluZm8ubmFtZSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLm1vZGUgPSAwCiAgICAgICAgdGFyaW5mby5zaXplID0gbGVuKG5hbWUpCgogICAgICAgICMgY3JlYXRlIGV4dGVuZGVkIGhlYWRlcgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoKQogICAgICAgICMgY3JlYXRlIG5hbWUgYmxvY2tzCiAgICAgICAgYnVmICs9IG5hbWUKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4obmFtZSksIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBidWYgKz0gKEJMT0NLU0laRSAtIHJlbWFpbmRlcikgKiBOVUwKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IEZhbHNlICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICBzZWxmLl9tb2RlID0gbW9kZQogICAgICAgIHNlbGYubW9kZSA9IHsiciI6ICJyYiIsICJhIjogInIrYiIsICJ3IjogIndiIn1bbW9kZV0KCiAgICAgICAgaWYgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKG5hbWUsIHNlbGYubW9kZSkKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgbmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lCiAgICAgICAgICAgIGlmIGhhc2F0dHIoZmlsZW9iaiwgIm1vZGUiKToKICAgICAgICAgICAgICAgIHNlbGYubW9kZSA9IGZpbGVvYmoubW9kZQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQogICAgICAgIHNlbGYubmFtZSA9IG9zLnBhdGguYWJzcGF0aChuYW1lKSBpZiBuYW1lIGVsc2UgTm9uZQogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKCiAgICAgICAgIyBJbml0IGRhdGFzdHJ1Y3R1cmVzCiAgICAgICAgc2VsZi5jbG9zZWQgPSBGYWxzZQogICAgICAgIHNlbGYubWVtYmVycyA9IFtdICAgICAgICMgbGlzdCBvZiBtZW1iZXJzIGFzIFRhckluZm8gb2JqZWN0cwogICAgICAgIHNlbGYuX2xvYWRlZCA9IEZhbHNlICAgICMgZmxhZyBpZiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZAogICAgICAgIHNlbGYub2Zmc2V0ID0gc2VsZi5maWxlb2JqLnRlbGwoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgYXJjaGl2ZSBmaWxlCiAgICAgICAgc2VsZi5pbm9kZXMgPSB7fSAgICAgICAgIyBkaWN0aW9uYXJ5IGNhY2hpbmcgdGhlIGlub2RlcyBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZSBtZW1iZXJzIGFscmVhZHkgYWRkZWQKCiAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBzZWxmLm5leHQoKQoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJhIjoKICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBSZWFkRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGNsYXNzbWV0aG9kcyB3aGljaCBhY3QgYXMgYWx0ZXJuYXRlIGNvbnN0cnVjdG9ycyB0byB0aGUKICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcgogICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KICAgICMgYWRlcXVhdGUgInN1YiItY29uc3RydWN0b3IgZm9yIGEgcGFydGljdWxhciBjb21wcmVzc2lvbiB1c2luZyB0aGUgbWFwcGluZwogICAgIyBmcm9tIE9QRU5fTUVUSC4KICAgICMKICAgICMgVGhpcyBjb25jZXB0IGFsbG93cyBvbmUgdG8gc3ViY2xhc3MgVGFyRmlsZSB3aXRob3V0IGxvc2luZyB0aGUgY29tZm9ydCBvZgogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlCiAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgb3BlbihjbHMsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgYnVmc2l6ZT0yMCo1MTIpOgogICAgICAgICIiIk9wZW4gYSB0YXIgYXJjaGl2ZSBmb3IgcmVhZGluZywgd3JpdGluZyBvciBhcHBlbmRpbmcuIFJldHVybgogICAgICAgICAgIGFuIGFwcHJvcHJpYXRlIFRhckZpbGUgY2xhc3MuCgogICAgICAgICAgIG1vZGU6CiAgICAgICAgICAgJ3InIG9yICdyOionIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAogICAgICAgICAgICdyOmd6JyAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOmJ6MicgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nCiAgICAgICAgICAgJ3cnIG9yICd3OicgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aG91dCBjb21wcmVzc2lvbgogICAgICAgICAgICd3Omd6JyAgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICd3OmJ6MicgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KCiAgICAgICAgICAgJ3J8KicgICAgICAgIG9wZW4gYSBzdHJlYW0gb2YgdGFyIGJsb2NrcyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3J8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzIGZvciByZWFkaW5nCiAgICAgICAgICAgJ3J8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAncnxiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAnd3wnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICIiIgoKICAgICAgICBpZiBub3QgbmFtZSBhbmQgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5vdGhpbmcgdG8gb3BlbiIpCgogICAgICAgIGlmIG1vZGUgaW4gKCJyIiwgInI6KiIpOgogICAgICAgICAgICAjIEZpbmQgb3V0IHdoaWNoICpvcGVuKCkgaXMgYXBwcm9wcmlhdGUgZm9yIG9wZW5pbmcgdGhlIGZpbGUuCiAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2F2ZWRfcG9zID0gZmlsZW9iai50ZWxsKCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCAiciIsIGZpbGVvYmopCiAgICAgICAgICAgICAgICBleGNlcHQgKFJlYWRFcnJvciwgQ29tcHJlc3Npb25FcnJvcik6CiAgICAgICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9iai5zZWVrKHNhdmVkX3BvcykKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaikKCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgifCIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgIGlmIGZpbGVtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwKICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBmaWxlb2JqID0gZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICBmaWxlb2JqLmNsb3NlKCkKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBnemlwIGZpbGUiKQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgYnoyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSk6CiAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3Jy4iKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiejIKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImJ6MiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkKICAgICAgICAgICAgZXh0ZmlsZW9iaiA9IFRydWUKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlb2JqID0gYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKQogICAgICAgICAgICBleHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwgZmlsZW9iaikKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgaWYgbm90IGV4dGZpbGVvYmo6CiAgICAgICAgICAgICAgICBmaWxlb2JqLmNsb3NlKCkKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBiemlwMiBmaWxlIikKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgICMgQWxsICpvcGVuKCkgbWV0aG9kcyBhcmUgcmVnaXN0ZXJlZCBoZXJlLgogICAgT1BFTl9NRVRIID0gewogICAgICAgICJ0YXIiOiAidGFyb3BlbiIsICAgIyB1bmNvbXByZXNzZWQgdGFyCiAgICAgICAgImd6IjogICJnem9wZW4iLCAgICAjIGd6aXAgY29tcHJlc3NlZCB0YXIKICAgICAgICAiYnoyIjogImJ6Mm9wZW4iICAgICMgYnppcDIgY29tcHJlc3NlZCB0YXIKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgVGhlIHB1YmxpYyBtZXRob2RzIHdoaWNoIFRhckZpbGUgcHJvdmlkZXM6CgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBUYXJGaWxlLiBJbiB3cml0ZS1tb2RlLCB0d28gZmluaXNoaW5nIHplcm8gYmxvY2tzIGFyZQogICAgICAgICAgIGFwcGVuZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5fbW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAqIDIpKQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSAoQkxPQ0tTSVpFICogMikKICAgICAgICAgICAgIyBmaWxsIHVwIHRoZSBlbmQgd2l0aCB6ZXJvLWJsb2NrcwogICAgICAgICAgICAjIChsaWtlIG9wdGlvbiAtYjIwIGZvciB0YXIgZG9lcykKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2Qoc2VsZi5vZmZzZXQsIFJFQ09SRFNJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKFJFQ09SRFNJWkUgLSByZW1haW5kZXIpKQoKICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgZ2V0bWVtYmVyKHNlbGYsIG5hbWUpOgogICAgICAgICIiIlJldHVybiBhIFRhckluZm8gb2JqZWN0IGZvciBtZW1iZXIgYG5hbWUnLiBJZiBgbmFtZScgY2FuIG5vdCBiZQogICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlCiAgICAgICAgICAgdGhhbiBvbmNlIGluIHRoZSBhcmNoaXZlLCBpdHMgbGFzdCBvY2N1cmVuY2UgaXMgYXNzdW1lZCB0byBiZSB0aGUKICAgICAgICAgICBtb3N0IHVwLXRvLWRhdGUgdmVyc2lvbi4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvID0gc2VsZi5fZ2V0bWVtYmVyKG5hbWUpCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBLZXlFcnJvcigiZmlsZW5hbWUgJXIgbm90IGZvdW5kIiAlIG5hbWUpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgZ2V0bWVtYmVycyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIFRhckluZm8gb2JqZWN0cy4gVGhlCiAgICAgICAgICAgbGlzdCBoYXMgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG1lbWJlcnMgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6ICAgICMgaWYgd2Ugd2FudCB0byBvYnRhaW4gYSBsaXN0IG9mCiAgICAgICAgICAgIHNlbGYuX2xvYWQoKSAgICAgICAgIyBhbGwgbWVtYmVycywgd2UgZmlyc3QgaGF2ZSB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2NhbiB0aGUgd2hvbGUgYXJjaGl2ZS4KICAgICAgICByZXR1cm4gc2VsZi5tZW1iZXJzCgogICAgZGVmIGdldG5hbWVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgdGhlaXIgbmFtZXMuIEl0IGhhcwogICAgICAgICAgIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gW3RhcmluZm8ubmFtZSBmb3IgdGFyaW5mbyBpbiBzZWxmLmdldG1lbWJlcnMoKV0KCiAgICBkZWYgZ2V0dGFyaW5mbyhzZWxmLCBuYW1lPU5vbmUsIGFyY25hbWU9Tm9uZSwgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmb3IgZWl0aGVyIHRoZSBmaWxlIGBuYW1lJyBvciB0aGUgZmlsZQogICAgICAgICAgIG9iamVjdCBgZmlsZW9iaicgKHVzaW5nIG9zLmZzdGF0IG9uIGl0cyBmaWxlIGRlc2NyaXB0b3IpLiBZb3UgY2FuCiAgICAgICAgICAgbW9kaWZ5IHNvbWUgb2YgdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGJlZm9yZSB5b3UgYWRkIGl0IHVzaW5nCiAgICAgICAgICAgYWRkZmlsZSgpLiBJZiBnaXZlbiwgYGFyY25hbWUnIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUKICAgICAgICAgICBmaWxlIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQoKICAgICAgICAjIEJ1aWxkaW5nIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4KICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCiAgICAgICAgYXJjbmFtZSA9IG5vcm1wYXRoKGFyY25hbWUpCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpCiAgICAgICAgd2hpbGUgYXJjbmFtZVswOjFdID09ICIvIjoKICAgICAgICAgICAgYXJjbmFtZSA9IGFyY25hbWVbMTpdCgogICAgICAgICMgTm93LCBmaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoCiAgICAgICAgIyBpbmZvcm1hdGlvbiBzcGVjaWZpYyBmb3IgdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IFRhckluZm8oKQoKICAgICAgICAjIFVzZSBvcy5zdGF0IG9yIG9zLmxzdGF0LCBkZXBlbmRpbmcgb24gcGxhdGZvcm0KICAgICAgICAjIGFuZCBpZiBzeW1saW5rcyBzaGFsbCBiZSByZXNvbHZlZC4KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJsc3RhdCIpIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5sc3RhdChuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLnN0YXQobmFtZSkKICAgICAgICBlbGlmIGhhc2F0dHIob3MsICdmc3RhdCcpOgogICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBOb3RJbXBsZW1lbnRlZEVycm9yKCdmaWxlb2JqIGFyZ3VtZW50IG5vdCBzdXBwb3J0ZWQgb24gdGhpcyAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BsYXRmb3JtIChubyBvcy5mc3RhdCknKQogICAgICAgIGxpbmtuYW1lID0gIiIKCiAgICAgICAgc3RtZCA9IHN0YXRyZXMuc3RfbW9kZQogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQogICAgICAgICAgICBpZiBub3Qgc2VsZi5kZXJlZmVyZW5jZSBhbmQgXAogICAgICAgICAgICAgICAgICAgIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBpbm9kZSBpbiBzZWxmLmlub2RlczoKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICAgICAgYXJjbmFtZSArPSAiLyIKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgPSBhcmNuYW1lCiAgICAgICAgdGFyaW5mby5tb2RlID0gc3RtZAogICAgICAgIHRhcmluZm8udWlkID0gc3RhdHJlcy5zdF91aWQKICAgICAgICB0YXJpbmZvLmdpZCA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSBzdGF0cmVzLnN0X3NpemUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKICAgICAgICAgICAgICAgIHByaW50ICIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwZCIgJSB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICBwcmludCAiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKCiAgICAgICAgICAgIHByaW50IHRhcmluZm8ubmFtZSwKCiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAibGluayB0byIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgIHByaW50CgogICAgZGVmIGFkZChzZWxmLCBuYW1lLCBhcmNuYW1lPU5vbmUsIHJlY3Vyc2l2ZT1UcnVlKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IHNlbGYubmFtZToKICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBTa2lwcGVkICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIFNwZWNpYWwgY2FzZTogVGhlIHVzZXIgd2FudHMgdG8gYWRkIHRoZSBjdXJyZW50CiAgICAgICAgIyB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAgICBpZiBuYW1lID09ICIuIjoKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgaWYgYXJjbmFtZSA9PSAiLiI6CiAgICAgICAgICAgICAgICAgICAgYXJjbmFtZSA9ICIiCiAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKCIuIik6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQoZiwgb3MucGF0aC5qb2luKGFyY25hbWUsIGYpKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgc2VsZi5fZGJnKDEsIG5hbWUpCgogICAgICAgICMgQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgZmlsZS4KICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXR0YXJpbmZvKG5hbWUsIGFyY25hbWUpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbnN1cHBvcnRlZCB0eXBlICVyIiAlIG5hbWUpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIEFwcGVuZCB0aGUgdGFyIGhlYWRlciBhbmQgZGF0YSB0byB0aGUgYXJjaGl2ZS4KICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIGYgPSBmaWxlKG5hbWUsICJyYiIpCiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvLCBmKQogICAgICAgICAgICBmLmNsb3NlKCkKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKG5hbWUpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKG9zLnBhdGguam9pbihuYW1lLCBmKSwgb3MucGF0aC5qb2luKGFyY25hbWUsIGYpKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKCiAgICBkZWYgYWRkZmlsZShzZWxmLCB0YXJpbmZvLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkFkZCB0aGUgVGFySW5mbyBvYmplY3QgYHRhcmluZm8nIHRvIHRoZSBhcmNoaXZlLiBJZiBgZmlsZW9iaicgaXMKICAgICAgICAgICBnaXZlbiwgdGFyaW5mby5zaXplIGJ5dGVzIGFyZSByZWFkIGZyb20gaXQgYW5kIGFkZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICAgIFlvdSBjYW4gY3JlYXRlIFRhckluZm8gb2JqZWN0cyB1c2luZyBnZXR0YXJpbmZvKCkuCiAgICAgICAgICAgT24gV2luZG93cyBwbGF0Zm9ybXMsIGBmaWxlb2JqJyBzaG91bGQgYWx3YXlzIGJlIG9wZW5lZCB3aXRoIG1vZGUKICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoc2VsZi5wb3NpeCkKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoYnVmKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IGxlbihidWYpCgogICAgICAgICMgSWYgdGhlcmUncyBkYXRhIHRvIGZvbGxvdywgYXBwZW5kIGl0LgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGNvcHlmaWxlb2JqKGZpbGVvYmosIHNlbGYuZmlsZW9iaiwgdGFyaW5mby5zaXplKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFIC0gcmVtYWluZGVyKSkKICAgICAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQoKICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCgogICAgZGVmIGV4dHJhY3RhbGwoc2VsZiwgcGF0aD0iLiIsIG1lbWJlcnM9Tm9uZSk6CiAgICAgICAgIiIiRXh0cmFjdCBhbGwgbWVtYmVycyBmcm9tIHRoZSBhcmNoaXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcKICAgICAgICAgICBkaXJlY3RvcnkgYW5kIHNldCBvd25lciwgbW9kaWZpY2F0aW9uIHRpbWUgYW5kIHBlcm1pc3Npb25zIG9uCiAgICAgICAgICAgZGlyZWN0b3JpZXMgYWZ0ZXJ3YXJkcy4gYHBhdGgnIHNwZWNpZmllcyBhIGRpZmZlcmVudCBkaXJlY3RvcnkKICAgICAgICAgICB0byBleHRyYWN0IHRvLiBgbWVtYmVycycgaXMgb3B0aW9uYWwgYW5kIG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlCiAgICAgICAgICAgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgZGlyZWN0b3JpZXMgPSBbXQoKICAgICAgICBpZiBtZW1iZXJzIGlzIE5vbmU6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmCgogICAgICAgIGZvciB0YXJpbmZvIGluIG1lbWJlcnM6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgICAgICMgRXh0cmFjdCBkaXJlY3RvcmllcyB3aXRoIGEgc2FmZSBtb2RlLgogICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCiAgICAgICAgICAgICAgICB0YXJpbmZvLm1vZGUgPSAwNzAwCiAgICAgICAgICAgIHNlbGYuZXh0cmFjdCh0YXJpbmZvLCBwYXRoKQoKICAgICAgICAjIFJldmVyc2Ugc29ydCBkaXJlY3Rvcmllcy4KICAgICAgICBkaXJlY3Rvcmllcy5zb3J0KGxhbWJkYSBhLCBiOiBjbXAoYS5uYW1lLCBiLm5hbWUpKQogICAgICAgIGRpcmVjdG9yaWVzLnJldmVyc2UoKQoKICAgICAgICAjIFNldCBjb3JyZWN0IG93bmVyLCBtdGltZSBhbmQgZmlsZW1vZGUgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yIHRhcmluZm8gaW4gZGlyZWN0b3JpZXM6CiAgICAgICAgICAgIGRpcnBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIGRpcnBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwKICAgICAgICAgICB1c2luZyBpdHMgZnVsbCBuYW1lLiBJdHMgZmlsZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQgYXMgYWNjdXJhdGVseQogICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIFRhckluZm8pOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4KICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgIHRhcmluZm8uX2xpbmtfdGFyZ2V0ID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZS5zdHJlcnJvcikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCiAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3RmaWxlKHNlbGYsIG1lbWJlcik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQogICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKICAgICAgICAgICBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZiBgbWVtYmVyJyBpcyBhIGxpbmssIGEgZmlsZS1saWtlCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YKICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCiAgICAgICAgICAgVGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgcmVhZC1vbmx5IGFuZCBwcm92aWRlcyB0aGUgZm9sbG93aW5nCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkKICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUuCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6CiAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCiAgICAgICAgICAgICAgICAjIHRvIGV4dHJhY3QgYSAoc3ltKWxpbmsgYXMgYSBmaWxlLW9iamVjdCBmcm9tIGEgbm9uLXNlZWthYmxlCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLgogICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoImNhbm5vdCBleHRyYWN0IChzeW0pbGluayBhcyBmaWxlIG9iamVjdCIpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXRzIHRhcmdldCdzIGZpbGUgb2JqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXh0cmFjdGZpbGUoc2VsZi5fZ2V0bWVtYmVyKHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIGlmIHRhcmdldHBhdGhbLTE6XSA9PSAiLyI6CiAgICAgICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoWzotMV0KICAgICAgICB0YXJnZXRwYXRoID0gb3MucGF0aC5ub3JtcGF0aCh0YXJnZXRwYXRoKQoKICAgICAgICAjIENyZWF0ZSBhbGwgdXBwZXIgZGlyZWN0b3JpZXMuCiAgICAgICAgdXBwZXJkaXJzID0gb3MucGF0aC5kaXJuYW1lKHRhcmdldHBhdGgpCiAgICAgICAgaWYgdXBwZXJkaXJzIGFuZCBub3Qgb3MucGF0aC5leGlzdHModXBwZXJkaXJzKToKICAgICAgICAgICAgIyBDcmVhdGUgZGlyZWN0b3JpZXMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIGFyY2hpdmUgd2l0aAogICAgICAgICAgICAjIGRlZmF1bHQgcGVybWlzc2lvbnMuCiAgICAgICAgICAgIG9zLm1ha2VkaXJzKHVwcGVyZGlycykKCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICIlcyAtPiAlcyIgJSAodGFyaW5mby5uYW1lLCB0YXJpbmZvLmxpbmtuYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGlyKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWZvKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWxpbmsodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICBzZWxmLm1ha2V1bmtub3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgZGlmZmVyZW50IGZpbGUgbWV0aG9kcy4gVGhleSBhcmUgY2FsbGVkIHZpYQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKICAgICMgc3ViY2xhc3MgdG8gaW1wbGVtZW50IG90aGVyIGZ1bmN0aW9uYWxpdHkuCgogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGRpcmVjdG9yeSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgICMgVXNlIGEgc2FmZSBtb2RlIGZvciB0aGUgZGlyZWN0b3J5LCB0aGUgcmVhbCBtb2RlIGlzIHNldAogICAgICAgICAgICAjIGxhdGVyIGluIF9leHRyYWN0X21lbWJlcigpLgogICAgICAgICAgICBvcy5ta2Rpcih0YXJnZXRwYXRoLCAwNzAwKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBlLmVycm5vICE9IGVycm5vLkVFWElTVDoKICAgICAgICAgICAgICAgIHJhaXNlCgogICAgZGVmIG1ha2VmaWxlKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNvdXJjZSA9IHNlbGYuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICB0YXJnZXQgPSBmaWxlKHRhcmdldHBhdGgsICJ3YiIpCiAgICAgICAgY29weWZpbGVvYmooc291cmNlLCB0YXJnZXQpCiAgICAgICAgc291cmNlLmNsb3NlKCkKICAgICAgICB0YXJnZXQuY2xvc2UoKQoKICAgIGRlZiBtYWtldW5rbm93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKICAgICAgICAgICBhdCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwKICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCBhcyByZWd1bGFyIGZpbGUuIiAlIHRhcmluZm8udHlwZSkKCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpZm8gY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOgogICAgICAgICAgICBvcy5ta2ZpZm8odGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkJMSwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSCgogICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkKCiAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQKICAgICAgICAgIChwbGF0Zm9ybSBsaW1pdGF0aW9uKSwgd2UgdHJ5IHRvIG1ha2UgYSBjb3B5IG9mIHRoZSByZWZlcmVuY2VkIGZpbGUKICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgogICAgICAgICIiIgogICAgICAgIGxpbmtwYXRoID0gdGFyaW5mby5saW5rbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgb3Muc3ltbGluayhsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgU2VlIGV4dHJhY3QoKS4KICAgICAgICAgICAgICAgIG9zLmxpbmsodGFyaW5mby5fbGlua190YXJnZXQsIHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG9zLnBhdGguam9pbihvcy5wYXRoLmRpcm5hbWUodGFyaW5mby5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmtwYXRoKQogICAgICAgICAgICAgICAgbGlua3BhdGggPSBub3JtcGF0aChsaW5rcGF0aCkKCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuZ2V0bWVtYmVyKGxpbmtwYXRoKSwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgZXhjZXB0IChFbnZpcm9ubWVudEVycm9yLCBLZXlFcnJvciksIGU6CiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG9zLnBhdGgubm9ybXBhdGgobGlua3BhdGgpCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2h1dGlsLmNvcHkyKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQogICAgICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigibGluayBjb3VsZCBub3QgYmUgY3JlYXRlZCIpCgogICAgZGVmIGNob3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBvd25lciBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIHB3ZCBhbmQgaGFzYXR0cihvcywgImdldGV1aWQiKSBhbmQgb3MuZ2V0ZXVpZCgpID09IDA6CiAgICAgICAgICAgICMgV2UgaGF2ZSB0byBiZSByb290IHRvIGRvIHNvLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdybmFtKHRhcmluZm8uZ25hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVsyXQogICAgICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgICAgIGcgPSBvcy5nZXRnaWQoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3bmFtKHRhcmluZm8udW5hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3dWlkKHRhcmluZm8udWlkKVsyXQogICAgICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgICAgIHUgPSBvcy5nZXR1aWQoKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCkgYW5kIGhhc2F0dHIob3MsICJsY2hvd24iKToKICAgICAgICAgICAgICAgICAgICBvcy5sY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICJvczJlbXgiOgogICAgICAgICAgICAgICAgICAgICAgICBvcy5jaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBvd25lciIpCgogICAgZGVmIGNobW9kKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBmaWxlIHBlcm1pc3Npb25zIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgJ2NobW9kJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLmNobW9kKHRhcmdldHBhdGgsIHRhcmluZm8ubW9kZSkKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2UgbW9kZSIpCgogICAgZGVmIHV0aW1lKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBtb2RpZmljYXRpb24gdGltZSBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAndXRpbWUnKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgc3lzLnBsYXRmb3JtID09ICJ3aW4zMiIgYW5kIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgIyBBY2NvcmRpbmcgdG8gbXNkbi5taWNyb3NvZnQuY29tLCBpdCBpcyBhbiBlcnJvciAoRUFDQ0VTKQogICAgICAgICAgICAjIHRvIHVzZSB1dGltZSgpIG9uIGRpcmVjdG9yaWVzLgogICAgICAgICAgICByZXR1cm4KICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLnV0aW1lKHRhcmdldHBhdGgsICh0YXJpbmZvLm10aW1lLCB0YXJpbmZvLm10aW1lKSkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG1vZGlmaWNhdGlvbiB0aW1lIikKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBtZW1iZXIgb2YgdGhlIGFyY2hpdmUgYXMgYSBUYXJJbmZvIG9iamVjdCwgd2hlbgogICAgICAgICAgIFRhckZpbGUgaXMgb3BlbmVkIGZvciByZWFkaW5nLiBSZXR1cm4gTm9uZSBpZiB0aGVyZSBpcyBubyBtb3JlCiAgICAgICAgICAgYXZhaWxhYmxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyYSIpCiAgICAgICAgaWYgc2VsZi5maXJzdG1lbWJlciBpcyBub3QgTm9uZToKICAgICAgICAgICAgbSA9IHNlbGYuZmlyc3RtZW1iZXIKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgcmV0dXJuIG0KCiAgICAgICAgIyBSZWFkIHRoZSBuZXh0IGJsb2NrLgogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvID0gVGFySW5mby5mcm9tYnVmKGJ1ZikKCiAgICAgICAgICAgICAgICAjIFNldCB0aGUgVGFySW5mbyBvYmplY3QncyBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlCiAgICAgICAgICAgICAgICAjIFRhckZpbGUgYW5kIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzCiAgICAgICAgICAgICAgICAjIHNob3VsZCBiZWdpbi4KICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnByb2NfbWVtYmVyKHRhcmluZm8pCgogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogZW1wdHkgb3IgaW52YWxpZCBibG9jazogJXMiICUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGYub2Zmc2V0LCBlKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImVtcHR5LCB1bnJlYWRhYmxlIG9yIGNvbXByZXNzZWQgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpbGU6ICVzIiAlIGUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgIyBTb21lIG9sZCB0YXIgcHJvZ3JhbXMgcmVwcmVzZW50IGEgZGlyZWN0b3J5IGFzIGEgcmVndWxhcgogICAgICAgICMgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIGFuZCB0YXJpbmZvLm5hbWUuZW5kc3dpdGgoIi8iKToKICAgICAgICAgICAgdGFyaW5mby50eXBlID0gRElSVFlQRQoKICAgICAgICAjIERpcmVjdG9yeSBuYW1lcyBzaG91bGQgaGF2ZSBhICcvJyBhdCB0aGUgZW5kLgogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKSBhbmQgbm90IHRhcmluZm8ubmFtZS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgKz0gIi8iCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgZm9sbG93aW5nIGFyZSBtZXRob2RzIHRoYXQgYXJlIGNhbGxlZCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgYQogICAgIyBtZW1iZXIuIFRoZSBlbnRyeSBwb2ludCBpcyBwcm9jX21lbWJlcigpIHdoaWNoIGlzIGNhbGxlZCB3aXRoIGEgVGFySW5mbwogICAgIyBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBoZWFkZXIgYmxvY2sgZnJvbSB0aGUgY3VycmVudCBvZmZzZXQuIFRoZQogICAgIyBwcm9jX21lbWJlcigpIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBhIHN1YmNsYXNzIHRvIGFkZCBjdXN0b20KICAgICMgcHJvY18qKCkgbWV0aG9kcy4gQSBwcm9jXyooKSBtZXRob2QgTVVTVCBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZwogICAgIyBvcGVyYXRpb25zOgogICAgIyAxLiBTZXQgdGFyaW5mby5vZmZzZXRfZGF0YSB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzIGJlZ2luLAogICAgIyAgICBpZiB0aGVyZSBpcyBkYXRhIHRoYXQgZm9sbG93cy4KICAgICMgMi4gU2V0IHNlbGYub2Zmc2V0IHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgbmV4dCBtZW1iZXIncyBoZWFkZXIgd2lsbAogICAgIyAgICBiZWdpbi4KICAgICMgMy4gUmV0dXJuIHRhcmluZm8gb3IgYW5vdGhlciB2YWxpZCBUYXJJbmZvIG9iamVjdC4KICAgIGRlZiBwcm9jX21lbWJlcihzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJDaG9vc2UgdGhlIHJpZ2h0IHByb2Nlc3NpbmcgbWV0aG9kIGZvciB0YXJpbmZvIGRlcGVuZGluZwogICAgICAgICAgIG9uIGl0cyB0eXBlIGFuZCBjYWxsIGl0LgogICAgICAgICIiIgogICAgICAgIGlmIHRhcmluZm8udHlwZSBpbiAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2NfZ251bG9uZyh0YXJpbmZvKQogICAgICAgIGVsaWYgdGFyaW5mby50eXBlID09IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICByZXR1cm4gc2VsZi5wcm9jX3NwYXJzZSh0YXJpbmZvKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2NfYnVpbHRpbih0YXJpbmZvKQoKICAgIGRlZiBwcm9jX2J1aWx0aW4oc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiUHJvY2VzcyBhIGJ1aWx0aW4gdHlwZSBtZW1iZXIgb3IgYW4gdW5rbm93biBtZW1iZXIKICAgICAgICAgICB3aGljaCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSByZWd1bGFyIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIFNraXAgdGhlIGZvbGxvd2luZyBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIHByb2NfZ251bG9uZyhzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJQcm9jZXNzIHRoZSBibG9ja3MgdGhhdCBob2xkIGEgR05VIGxvbmduYW1lCiAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgY291bnQgPSB0YXJpbmZvLnNpemUKICAgICAgICB3aGlsZSBjb3VudCA+IDA6CiAgICAgICAgICAgIGJsb2NrID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBidWYgKz0gYmxvY2sKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIGNvdW50IC09IEJMT0NLU0laRQoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlciBhbmQgcHJvY2VzcyBpdC4KICAgICAgICBiID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgIHQgPSBUYXJJbmZvLmZyb21idWYoYikKICAgICAgICB0Lm9mZnNldCA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgbmV4dCA9IHNlbGYucHJvY19tZW1iZXIodCkKCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgbmV4dCBoZWFkZXIgd2l0aAogICAgICAgICMgdGhlIGxvbmduYW1lIGluZm9ybWF0aW9uLgogICAgICAgIG5leHQub2Zmc2V0ID0gdGFyaW5mby5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToKICAgICAgICAgICAgbmV4dC5uYW1lID0gbnRzKGJ1ZikKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gbnRzKGJ1ZikKCiAgICAgICAgcmV0dXJuIG5leHQKCiAgICBkZWYgcHJvY19zcGFyc2Uoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiUHJvY2VzcyBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSB0YXJpbmZvLmJ1ZgogICAgICAgIHNwID0gX3JpbmdidWZmZXIoKQogICAgICAgIHBvcyA9IDM4NgogICAgICAgIGxhc3Rwb3MgPSAwTAogICAgICAgIHJlYWxwb3MgPSAwTAogICAgICAgICMgVGhlcmUgYXJlIDQgcG9zc2libGUgc3BhcnNlIHN0cnVjdHMgaW4gdGhlCiAgICAgICAgIyBmaXJzdCBoZWFkZXIuCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKDQpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pCiAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgcG9zICs9IDI0CgogICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzQ4Ml0pCiAgICAgICAgb3JpZ3NpemUgPSBudGkoYnVmWzQ4Mzo0OTVdKQoKICAgICAgICAjIElmIHRoZSBpc2V4dGVuZGVkIGZsYWcgaXMgZ2l2ZW4sCiAgICAgICAgIyB0aGVyZSBhcmUgZXh0cmEgaGVhZGVycyB0byBwcm9jZXNzLgogICAgICAgIHdoaWxlIGlzZXh0ZW5kZWQgPT0gMToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgcG9zID0gMAogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoMjEpOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkKICAgICAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgICAgICBwb3MgKz0gMjQKICAgICAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNTA0XSkKCiAgICAgICAgaWYgbGFzdHBvcyA8IG9yaWdzaXplOgogICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb3JpZ3NpemUgLSBsYXN0cG9zKSkKCiAgICAgICAgdGFyaW5mby5zcGFyc2UgPSBzcAoKICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhID0gc2VsZi5vZmZzZXQKICAgICAgICBzZWxmLm9mZnNldCArPSBzZWxmLl9ibG9jayh0YXJpbmZvLnNpemUpCiAgICAgICAgdGFyaW5mby5zaXplID0gb3JpZ3NpemUKCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgTGl0dGxlIGhlbHBlciBtZXRob2RzOgoKICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwKICAgICAgICAgICBlLmcuIF9ibG9jayg4MzQpID0+IDEwMjQuCiAgICAgICAgIiIiCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXI6CiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSk6CiAgICAgICAgIiIiRmluZCBhbiBhcmNoaXZlIG1lbWJlciBieSBuYW1lIGZyb20gYm90dG9tIHRvIHRvcC4KICAgICAgICAgICBJZiB0YXJpbmZvIGlzIGdpdmVuLCBpdCBpcyB1c2VkIGFzIHRoZSBzdGFydGluZyBwb2ludC4KICAgICAgICAiIiIKICAgICAgICAjIEVuc3VyZSB0aGF0IGFsbCBtZW1iZXJzIGhhdmUgYmVlbiBsb2FkZWQuCiAgICAgICAgbWVtYmVycyA9IHNlbGYuZ2V0bWVtYmVycygpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgZW5kID0gbGVuKG1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZW5kID0gbWVtYmVycy5pbmRleCh0YXJpbmZvKQoKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZW5kIC0gMSwgLTEsIC0xKToKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJzW2ldLm5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyc1tpXQoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoIiVzIGlzIGNsb3NlZCIgJSBzZWxmLl9fY2xhc3NfXy5fX25hbWVfXykKICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLl9tb2RlIG5vdCBpbiBtb2RlOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJiYWQgb3BlcmF0aW9uIGZvciBtb2RlICVyIiAlIHNlbGYuX21vZGUpCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlByb3ZpZGUgYW4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuX2xvYWRlZDoKICAgICAgICAgICAgcmV0dXJuIGl0ZXIoc2VsZi5tZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBUYXJJdGVyKHNlbGYpCgogICAgZGVmIF9kYmcoc2VsZiwgbGV2ZWwsIG1zZyk6CiAgICAgICAgIiIiV3JpdGUgZGVidWdnaW5nIG91dHB1dCB0byBzeXMuc3RkZXJyLgogICAgICAgICIiIgogICAgICAgIGlmIGxldmVsIDw9IHNlbGYuZGVidWc6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwojIGNsYXNzIFRhckZpbGUKCmNsYXNzIFRhckl0ZXI6CiAgICAiIiJJdGVyYXRvciBDbGFzcy4KCiAgICAgICBmb3IgdGFyaW5mbyBpbiBUYXJGaWxlKC4uLik6CiAgICAgICAgICAgc3VpdGUuLi4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJdGVyIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnRhcmZpbGUgPSB0YXJmaWxlCiAgICAgICAgc2VsZi5pbmRleCA9IDAKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgaXRlbSB1c2luZyBUYXJGaWxlJ3MgbmV4dCgpIG1ldGhvZC4KICAgICAgICAgICBXaGVuIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkLCBzZXQgVGFyRmlsZSBhcyBfbG9hZGVkLgogICAgICAgICIiIgogICAgICAgICMgRml4IGZvciBTRiAjMTEwMDQyOTogVW5kZXIgcmFyZSBjaXJjdW1zdGFuY2VzIGl0IGNhbgogICAgICAgICMgaGFwcGVuIHRoYXQgZ2V0bWVtYmVycygpIGlzIGNhbGxlZCBkdXJpbmcgaXRlcmF0aW9uLAogICAgICAgICMgd2hpY2ggd2lsbCBjYXVzZSBUYXJJdGVyIHRvIHN0b3AgcHJlbWF0dXJlbHkuCiAgICAgICAgaWYgbm90IHNlbGYudGFyZmlsZS5fbG9hZGVkOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQogICAgICAgICAgICBpZiBub3QgdGFyaW5mbzoKICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5fbG9hZGVkID0gVHJ1ZQogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmZpbGUubWVtYmVyc1tzZWxmLmluZGV4XQogICAgICAgICAgICBleGNlcHQgSW5kZXhFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBzZWxmLmluZGV4ICs9IDEKICAgICAgICByZXR1cm4gdGFyaW5mbwoKIyBIZWxwZXIgY2xhc3NlcyBmb3Igc3BhcnNlIGZpbGUgc3VwcG9ydApjbGFzcyBfc2VjdGlvbjoKICAgICIiIkJhc2UgY2xhc3MgZm9yIF9kYXRhIGFuZCBfaG9sZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSk6CiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG9mZnNldCk6CiAgICAgICAgcmV0dXJuIHNlbGYub2Zmc2V0IDw9IG9mZnNldCA8IHNlbGYub2Zmc2V0ICsgc2VsZi5zaXplCgpjbGFzcyBfZGF0YShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBkYXRhIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSwgcmVhbHBvcyk6CiAgICAgICAgX3NlY3Rpb24uX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKQogICAgICAgIHNlbGYucmVhbHBvcyA9IHJlYWxwb3MKCmNsYXNzIF9ob2xlKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGhvbGUgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBwYXNzCgpjbGFzcyBfcmluZ2J1ZmZlcihsaXN0KToKICAgICIiIlJpbmdidWZmZXIgY2xhc3Mgd2hpY2ggaW5jcmVhc2VzIHBlcmZvcm1hbmNlCiAgICAgICBvdmVyIGEgcmVndWxhciBsaXN0LgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi5pZHggPSAwCiAgICBkZWYgZmluZChzZWxmLCBvZmZzZXQpOgogICAgICAgIGlkeCA9IHNlbGYuaWR4CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaXRlbSA9IHNlbGZbaWR4XQogICAgICAgICAgICBpZiBvZmZzZXQgaW4gaXRlbToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlkeCArPSAxCiAgICAgICAgICAgIGlmIGlkeCA9PSBsZW4oc2VsZik6CiAgICAgICAgICAgICAgICBpZHggPSAwCiAgICAgICAgICAgIGlmIGlkeCA9PSBzZWxmLmlkeDoKICAgICAgICAgICAgICAgICMgRW5kIG9mIEZpbGUKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgc2VsZi5pZHggPSBpZHgKICAgICAgICByZXR1cm4gaXRlbQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHppcGZpbGUgY29tcGF0aWJsZSBUYXJGaWxlIGNsYXNzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVEFSX1BMQUlOID0gMCAgICAgICAgICAgIyB6aXBmaWxlLlpJUF9TVE9SRUQKVEFSX0daSVBQRUQgPSA4ICAgICAgICAgIyB6aXBmaWxlLlpJUF9ERUZMQVRFRApjbGFzcyBUYXJGaWxlQ29tcGF0OgogICAgIiIiVGFyRmlsZSBjbGFzcyBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgbW9kdWxlIHppcGZpbGUncwogICAgICAgWmlwRmlsZSBjbGFzcy4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIG1vZGU9InIiLCBjb21wcmVzc2lvbj1UQVJfUExBSU4pOgogICAgICAgIGlmIGNvbXByZXNzaW9uID09IFRBUl9QTEFJTjoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS50YXJvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxpZiBjb21wcmVzc2lvbiA9PSBUQVJfR1pJUFBFRDoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS5nem9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ1bmtub3duIGNvbXByZXNzaW9uIGNvbnN0YW50IikKICAgICAgICBpZiBtb2RlWzA6MV0gPT0gInIiOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKQogICAgICAgICAgICBmb3IgbSBpbiBtZW1iZXJzOgogICAgICAgICAgICAgICAgbS5maWxlbmFtZSA9IG0ubmFtZQogICAgICAgICAgICAgICAgbS5maWxlX3NpemUgPSBtLnNpemUKICAgICAgICAgICAgICAgIG0uZGF0ZV90aW1lID0gdGltZS5nbXRpbWUobS5tdGltZSlbOjZdCiAgICBkZWYgbmFtZWxpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgbTogbS5uYW1lLCBzZWxmLmluZm9saXN0KCkpCiAgICBkZWYgaW5mb2xpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIGZpbHRlcihsYW1iZGEgbTogbS50eXBlIGluIFJFR1VMQVJfVFlQRVMsCiAgICAgICAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpKQogICAgZGVmIHByaW50ZGlyKHNlbGYpOgogICAgICAgIHNlbGYudGFyZmlsZS5saXN0KCkKICAgIGRlZiB0ZXN0emlwKHNlbGYpOgogICAgICAgIHJldHVybgogICAgZGVmIGdldGluZm8oc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkKICAgIGRlZiByZWFkKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZXh0cmFjdGZpbGUoc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKSkucmVhZCgpCiAgICBkZWYgd3JpdGUoc2VsZiwgZmlsZW5hbWUsIGFyY25hbWU9Tm9uZSwgY29tcHJlc3NfdHlwZT1Ob25lKToKICAgICAgICBzZWxmLnRhcmZpbGUuYWRkKGZpbGVuYW1lLCBhcmNuYW1lKQogICAgZGVmIHdyaXRlc3RyKHNlbGYsIHppbmZvLCBieXRlcyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBmcm9tIGNTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIGZyb20gU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgaW1wb3J0IGNhbGVuZGFyCiAgICAgICAgemluZm8ubmFtZSA9IHppbmZvLmZpbGVuYW1lCiAgICAgICAgemluZm8uc2l6ZSA9IHppbmZvLmZpbGVfc2l6ZQogICAgICAgIHppbmZvLm10aW1lID0gY2FsZW5kYXIudGltZWdtKHppbmZvLmRhdGVfdGltZSkKICAgICAgICBzZWxmLnRhcmZpbGUuYWRkZmlsZSh6aW5mbywgU3RyaW5nSU8oYnl0ZXMpKQogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYudGFyZmlsZS5jbG9zZSgpCiNjbGFzcyBUYXJGaWxlQ29tcGF0CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBleHBvcnRlZCBmdW5jdGlvbnMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCmRlZiBpc190YXJmaWxlKG5hbWUpOgogICAgIiIiUmV0dXJuIFRydWUgaWYgbmFtZSBwb2ludHMgdG8gYSB0YXIgYXJjaGl2ZSB0aGF0IHdlCiAgICAgICBhcmUgYWJsZSB0byBoYW5kbGUsIGVsc2UgcmV0dXJuIEZhbHNlLgogICAgIiIiCiAgICB0cnk6CiAgICAgICAgdCA9IG9wZW4obmFtZSkKICAgICAgICB0LmNsb3NlKCkKICAgICAgICByZXR1cm4gVHJ1ZQogICAgZXhjZXB0IFRhckVycm9yOgogICAgICAgIHJldHVybiBGYWxzZQoKb3BlbiA9IFRhckZpbGUub3Blbgo=