IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC44LjAiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKCmlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICMgVGhpcyBtb2R1bGUgbmVlZHMgd29yayBmb3IgTWFjT1M5LCBlc3BlY2lhbGx5IGluIHRoZSBhcmVhIG9mIHBhdGhuYW1lCiAgICAjIGhhbmRsaW5nLiBJbiBtYW55IHBsYWNlcyBpdCBpcyBhc3N1bWVkIGEgc2ltcGxlIHN1YnN0aXR1dGlvbiBvZiAvIGJ5IHRoZQogICAgIyBsb2NhbCBvcy5wYXRoLnNlcCBpcyBnb29kIGVub3VnaCB0byBjb252ZXJ0IHBhdGhuYW1lcywgYnV0IHRoaXMgZG9lcyBub3QKICAgICMgd29yayB3aXRoIHRoZSBtYWMgcm9vdGVkOnBhdGg6bmFtZSB2ZXJzdXMgOm5vbnJvb3RlZDpwYXRoOm5hbWUgc3ludGF4CiAgICByYWlzZSBJbXBvcnRFcnJvciwgInRhcmZpbGUgZG9lcyBub3Qgd29yayBmb3IgcGxhdGZvcm09PW1hYyIKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBzdG4ocywgbGVuZ3RoKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gc3RyaW5nIHRvIGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBidWZmZXIuCiAgICAiIiIKICAgIHJldHVybiBzWzpsZW5ndGgtMV0gKyAobGVuZ3RoIC0gbGVuKHMpIC0gMSkgKiBOVUwgKyBOVUwKCmRlZiBudGkocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4KICAgICIiIgogICAgIyBUaGVyZSBhcmUgdHdvIHBvc3NpYmxlIGVuY29kaW5ncyBmb3IgYSBudW1iZXIgZmllbGQsIHNlZQogICAgIyBpdG4oKSBiZWxvdy4KICAgIGlmIHNbMF0gIT0gY2hyKDAyMDApOgogICAgICAgIG4gPSBpbnQocy5yc3RyaXAoTlVMKSBvciAiMCIsIDgpCiAgICBlbHNlOgogICAgICAgIG4gPSAwTAogICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4ocykgLSAxKToKICAgICAgICAgICAgbiA8PD0gOAogICAgICAgICAgICBuICs9IG9yZChzW2kgKyAxXSkKICAgIHJldHVybiBuCgpkZWYgaXRuKG4sIGRpZ2l0cz04LCBwb3NpeD1GYWxzZSk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIG51bWJlciB0byBhIG51bWJlciBmaWVsZC4KICAgICIiIgogICAgIyBQT1NJWCAxMDAzLjEtMTk4OCByZXF1aXJlcyBudW1iZXJzIHRvIGJlIGVuY29kZWQgYXMgYSBzdHJpbmcgb2YKICAgICMgb2N0YWwgZGlnaXRzIGZvbGxvd2VkIGJ5IGEgbnVsbC1ieXRlLCB0aGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8KICAgICMgKDgqKihkaWdpdHMtMSkpLTEuIEdOVSB0YXIgYWxsb3dzIHN0b3JpbmcgbnVtYmVycyBncmVhdGVyIHRoYW4KICAgICMgdGhhdCBpZiBuZWNlc3NhcnkuIEEgbGVhZGluZyAwMjAwIGJ5dGUgaW5kaWNhdGVzIHRoaXMgcGFydGljdWxhcgogICAgIyBlbmNvZGluZywgdGhlIGZvbGxvd2luZyBkaWdpdHMtMSBieXRlcyBhcmUgYSBiaWctZW5kaWFuCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4KICAgIGlmIDAgPD0gbiA8IDggKiogKGRpZ2l0cyAtIDEpOgogICAgICAgIHMgPSAiJTAqbyIgJSAoZGlnaXRzIC0gMSwgbikgKyBOVUwKICAgIGVsc2U6CiAgICAgICAgaWYgcG9zaXg6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm92ZXJmbG93IGluIG51bWJlciBmaWVsZCIpCgogICAgICAgIGlmIG4gPCAwOgogICAgICAgICAgICAjIFhYWCBXZSBtaW1pYyBHTlUgdGFyJ3MgYmVoYXZpb3VyIHdpdGggbmVnYXRpdmUgbnVtYmVycywKICAgICAgICAgICAgIyB0aGlzIGNvdWxkIHJhaXNlIE92ZXJmbG93RXJyb3IuCiAgICAgICAgICAgIG4gPSBzdHJ1Y3QudW5wYWNrKCJMIiwgc3RydWN0LnBhY2soImwiLCBuKSlbMF0KCiAgICAgICAgcyA9ICIiCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICBzID0gY2hyKG4gJiAwMzc3KSArIHMKICAgICAgICAgICAgbiA+Pj0gOAogICAgICAgIHMgPSBjaHIoMDIwMCkgKyBzCiAgICByZXR1cm4gcwoKZGVmIGNhbGNfY2hrc3VtcyhidWYpOgogICAgIiIiQ2FsY3VsYXRlIHRoZSBjaGVja3N1bSBmb3IgYSBtZW1iZXIncyBoZWFkZXIgYnkgc3VtbWluZyB1cCBhbGwKICAgICAgIGNoYXJhY3RlcnMgZXhjZXB0IGZvciB0aGUgY2hrc3VtIGZpZWxkIHdoaWNoIGlzIHRyZWF0ZWQgYXMgaWYKICAgICAgIGl0IHdhcyBmaWxsZWQgd2l0aCBzcGFjZXMuIEFjY29yZGluZyB0byB0aGUgR05VIHRhciBzb3VyY2VzLAogICAgICAgc29tZSB0YXJzIChTdW4gYW5kIE5lWFQpIGNhbGN1bGF0ZSBjaGtzdW0gd2l0aCBzaWduZWQgY2hhciwKICAgICAgIHdoaWNoIHdpbGwgYmUgZGlmZmVyZW50IGlmIHRoZXJlIGFyZSBjaGFycyBpbiB0aGUgYnVmZmVyIHdpdGgKICAgICAgIHRoZSBoaWdoIGJpdCBzZXQuIFNvIHdlIGNhbGN1bGF0ZSB0d28gY2hlY2tzdW1zLCB1bnNpZ25lZCBhbmQKICAgICAgIHNpZ25lZC4KICAgICIiIgogICAgdW5zaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OEIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2QiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICBzaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OGIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2YiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICByZXR1cm4gdW5zaWduZWRfY2hrc3VtLCBzaWduZWRfY2hrc3VtCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuKHNlbGYuYnVmKSwgc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5idWYgKz0gTlVMICogKHNlbGYuYnVmc2l6ZSAtIHJlbWFpbmRlcikKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPGwiLCBzZWxmLmNyYykpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5wb3MgJiAweGZmZmZGRkZGTCkpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQoKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX2luaXRfcmVhZF9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciByZWFkaW5nIGEgZ3ppcCBjb21wcmVzc2VkIGZpbGVvYmouCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuZGVjb21wcmVzc29iaigtc2VsZi56bGliLk1BWF9XQklUUykKICAgICAgICBzZWxmLmRidWYgPSAiIgoKICAgICAgICAjIHRha2VuIGZyb20gZ3ppcC5HemlwRmlsZSB3aXRoIHNvbWUgYWx0ZXJhdGlvbnMKICAgICAgICBpZiBzZWxmLl9fcmVhZCgyKSAhPSAiXDAzN1wyMTMiOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMSkgIT0gIlwwMTAiOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QiKQoKICAgICAgICBmbGFnID0gb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgIHNlbGYuX19yZWFkKDYpCgogICAgICAgIGlmIGZsYWcgJiA0OgogICAgICAgICAgICB4bGVuID0gb3JkKHNlbGYuX19yZWFkKDEpKSArIDI1NiAqIG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICAgICAgc2VsZi5yZWFkKHhsZW4pCiAgICAgICAgaWYgZmxhZyAmIDg6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDE2OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAyOgogICAgICAgICAgICBzZWxmLl9fcmVhZCgyKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcz0wKToKICAgICAgICAiIiJTZXQgdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciB0byBwb3MuIE5lZ2F0aXZlIHNlZWtpbmcKICAgICAgICAgICBpcyBmb3JiaWRkZW4uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcG9zIC0gc2VsZi5wb3MgPj0gMDoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QocG9zIC0gc2VsZi5wb3MsIHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgICAgICAgICBzZWxmLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBzZWxmLnJlYWQocmVtYWluZGVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJzZWVraW5nIGJhY2t3YXJkcyBpcyBub3QgYWxsb3dlZCIpCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgc2l6ZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICAgIElmIHNpemUgaXMgbm90IGRlZmluZWQsIHJldHVybiBhbGwgYnl0ZXMgb2YgdGhlIHN0cmVhbQogICAgICAgICAgIHVwIHRvIEVPRi4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHQgPSBbXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGJ1ZiA9ICIiLmpvaW4odCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNpemUpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIF9yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJ0YXIiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoc2l6ZSkKCiAgICAgICAgYyA9IGxlbihzZWxmLmRidWYpCiAgICAgICAgdCA9IFtzZWxmLmRidWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX19yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuY21wLmRlY29tcHJlc3MoYnVmKQogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuZGJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAogICAgICAgICAgIHJlYWQgYW5vdGhlciBibG9jayBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB0ID0gW3NlbGYuYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KIyBjbGFzcyBfU3RyZWFtCgpjbGFzcyBfU3RyZWFtUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgZGV0ZWN0aW9uIGZvciB0aGUgU3RyZWFtIGludGVyZmFjZSAobW9kZSAncnwqJykuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaik6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYuYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHNlbGYucmVhZCA9IHNlbGYuZmlsZW9iai5yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuYnVmCgogICAgZGVmIGdldGNvbXB0eXBlKHNlbGYpOgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIlwwMzdcMjEzXDAxMCIpOgogICAgICAgICAgICByZXR1cm4gImd6IgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIkJaaDkxIik6CiAgICAgICAgICAgIHJldHVybiAiYnoyIgogICAgICAgIHJldHVybiAidGFyIgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIFN0cmVhbVByb3h5CgpjbGFzcyBfQloyUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyBleHRlcm5hbCBmaWxlIG9iamVjdAogICAgICAgc3VwcG9ydCBmb3IgInI6YnoyIiBhbmQgInc6YnoyIiBtb2Rlcy4gVGhpcyBpcyBhY3R1YWxseQogICAgICAgYSB3b3JrYXJvdW5kIGZvciBhIGxpbWl0YXRpb24gaW4gYnoyIG1vZHVsZSdzIEJaMkZpbGUKICAgICAgIGNsYXNzIHdoaWNoICh1bmxpa2UgZ3ppcC5HemlwRmlsZSkgaGFzIG5vIHN1cHBvcnQgZm9yCiAgICAgICBhIGZpbGUgb2JqZWN0IGFyZ3VtZW50LgogICAgIiIiCgogICAgYmxvY2tzaXplID0gMTYgKiAxMDI0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmosIG1vZGUpOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLm1vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5pbml0KCkKCiAgICBkZWYgaW5pdChzZWxmKToKICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgc2VsZi5wb3MgPSAwCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgc2VsZi5idWYgPSAiIgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkNvbXByZXNzb3IoKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIGIgPSBbc2VsZi5idWZdCiAgICAgICAgeCA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB3aGlsZSB4IDwgc2l6ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcmF3ID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBkYXRhID0gc2VsZi5iejJvYmouZGVjb21wcmVzcyhyYXcpCiAgICAgICAgICAgICAgICBiLmFwcGVuZChkYXRhKQogICAgICAgICAgICBleGNlcHQgRU9GRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB4ICs9IGxlbihkYXRhKQogICAgICAgIHNlbGYuYnVmID0gIiIuam9pbihiKQoKICAgICAgICBidWYgPSBzZWxmLmJ1Zls6c2l6ZV0KICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NpemU6XQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcyk6CiAgICAgICAgaWYgcG9zIDwgc2VsZi5wb3M6CiAgICAgICAgICAgIHNlbGYuaW5pdCgpCiAgICAgICAgc2VsZi5yZWFkKHBvcyAtIHNlbGYucG9zKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiB3cml0ZShzZWxmLCBkYXRhKToKICAgICAgICBzZWxmLnBvcyArPSBsZW4oZGF0YSkKICAgICAgICByYXcgPSBzZWxmLmJ6Mm9iai5jb21wcmVzcyhkYXRhKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyI6CiAgICAgICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmZsdXNoKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIF9CWjJQcm94eQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuIFN1cHBvcnQgZm9yCiAgICAgICBzcGFyc2UgZmlsZXMgaW5jbHVkZWQuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gdGFyZmlsZS5maWxlb2JqCiAgICAgICAgc2VsZi5uYW1lICAgID0gdGFyaW5mby5uYW1lCiAgICAgICAgc2VsZi5tb2RlICAgID0gInIiCiAgICAgICAgc2VsZi5jbG9zZWQgID0gRmFsc2UKICAgICAgICBzZWxmLm9mZnNldCAgPSB0YXJpbmZvLm9mZnNldF9kYXRhCiAgICAgICAgc2VsZi5zaXplICAgID0gdGFyaW5mby5zaXplCiAgICAgICAgc2VsZi5wb3MgICAgID0gMEwKICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgIGlmIHRhcmluZm8uaXNzcGFyc2UoKToKICAgICAgICAgICAgc2VsZi5zcGFyc2UgPSB0YXJpbmZvLnNwYXJzZQogICAgICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLl9yZWFkc3BhcnNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5fcmVhZG5vcm1hbAoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiT3ZlcmxvYWRhYmxlIHJlYWQgbWV0aG9kLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIGEgbGluZSB3aXRoIGFwcHJveC4gc2l6ZS4gSWYgc2l6ZSBpcyBuZWdhdGl2ZSwKICAgICAgICAgICByZWFkIGEgd2hvbGUgbGluZS4gcmVhZGxpbmUoKSBhbmQgcmVhZCgpIG11c3Qgbm90CiAgICAgICAgICAgYmUgbWl4ZWQgdXAgKCEpLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgPCAwOgogICAgICAgICAgICBzaXplID0gc3lzLm1heGludAoKICAgICAgICBubCA9IHNlbGYubGluZWJ1ZmZlci5maW5kKCJcbiIpCiAgICAgICAgaWYgbmwgPj0gMDoKICAgICAgICAgICAgbmwgPSBtaW4obmwsIHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oc2VsZi5saW5lYnVmZmVyKQogICAgICAgICAgICB3aGlsZSAobmwgPCAwIGFuZCBzaXplID4gMCk6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLnJlYWQobWluKHNpemUsIDEwMCkpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgKz0gYnVmCiAgICAgICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgICAgICBubCA9IHNlbGYubGluZWJ1ZmZlci5maW5kKCJcbiIpCiAgICAgICAgICAgIGlmIG5sID09IC0xOgogICAgICAgICAgICAgICAgcyA9IHNlbGYubGluZWJ1ZmZlcgogICAgICAgICAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKICAgICAgICAgICAgICAgIHJldHVybiBzCiAgICAgICAgYnVmID0gc2VsZi5saW5lYnVmZmVyWzpubF0KICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSBzZWxmLmxpbmVidWZmZXJbbmwgKyAxOl0KICAgICAgICB3aGlsZSBidWZbLTE6XSA9PSAiXHIiOgogICAgICAgICAgICBidWYgPSBidWZbOi0xXQogICAgICAgIHJldHVybiBidWYgKyAiXG4iCgogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IHdpdGggYWxsIChmb2xsb3dpbmcpIGxpbmVzLgogICAgICAgICIiIgogICAgICAgIHJlc3VsdCA9IFtdCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChsaW5lKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgX3JlYWRub3JtYWwoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3IgcmVndWxhciBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiZmlsZSBpcyBjbG9zZWQiKQogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgc2VsZi5wb3MpCiAgICAgICAgYnl0ZXNsZWZ0ID0gc2VsZi5zaXplIC0gc2VsZi5wb3MKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIGJ5dGVzdG9yZWFkID0gYnl0ZXNsZWZ0CiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnl0ZXN0b3JlYWQgPSBtaW4oc2l6ZSwgYnl0ZXNsZWZ0KQogICAgICAgIHNlbGYucG9zICs9IGJ5dGVzdG9yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKGJ5dGVzdG9yZWFkKQoKICAgIGRlZiBfcmVhZHNwYXJzZShzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciBzcGFyc2UgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImZpbGUgaXMgY2xvc2VkIikKCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICBzaXplID0gc2VsZi5zaXplIC0gc2VsZi5wb3MKCiAgICAgICAgZGF0YSA9IFtdCiAgICAgICAgd2hpbGUgc2l6ZSA+IDA6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWRzcGFyc2VzZWN0aW9uKHNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgIGRhdGEuYXBwZW5kKGJ1ZikKICAgICAgICByZXR1cm4gIiIuam9pbihkYXRhKQoKICAgIGRlZiBfcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBhIHNpbmdsZSBzZWN0aW9uIG9mIGEgc3BhcnNlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3MpCgogICAgICAgIGlmIHNlY3Rpb24gaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuICIiCgogICAgICAgIHRvcmVhZCA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zKQogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3MgLSBzZWN0aW9uLm9mZnNldAogICAgICAgICAgICBzZWxmLnBvcyArPSB0b3JlYWQKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyByZWFscG9zKQogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQodG9yZWFkKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAogICAgICAgICAgICByZXR1cm4gTlVMICogdG9yZWFkCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zLCB3aGVuY2U9MCk6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCiAgICAgICAgaWYgd2hlbmNlID09IDA6CiAgICAgICAgICAgIHNlbGYucG9zID0gbWluKG1heChwb3MsIDApLCBzZWxmLnNpemUpCiAgICAgICAgaWYgd2hlbmNlID09IDE6CiAgICAgICAgICAgIGlmIHBvcyA8IDA6CiAgICAgICAgICAgICAgICBzZWxmLnBvcyA9IG1heChzZWxmLnBvcyArIHBvcywgMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWluKHNlbGYucG9zICsgcG9zLCBzZWxmLnNpemUpCiAgICAgICAgaWYgd2hlbmNlID09IDI6CiAgICAgICAgICAgIHNlbGYucG9zID0gbWF4KG1pbihzZWxmLnNpemUgKyBwb3MsIHNlbGYuc2l6ZSksIDApCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBmaWxlIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiR2V0IGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIkdldCB0aGUgbmV4dCBpdGVtIGZyb20gdGhlIGZpbGUgaXRlcmF0b3IuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgaWYgbm90IHJlc3VsdDoKICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIHJldHVybiByZXN1bHQKCiNjbGFzcyBFeEZpbGVPYmplY3QKCiMtLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHBvcnRlZCBDbGFzc2VzCiMtLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgVGFySW5mbyhvYmplY3QpOgogICAgIiIiSW5mb3JtYXRpb25hbCBjbGFzcyB3aGljaCBob2xkcyB0aGUgZGV0YWlscyBhYm91dCBhbgogICAgICAgYXJjaGl2ZSBtZW1iZXIgZ2l2ZW4gYnkgYSB0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgVGFySW5mbyBvYmplY3RzIGFyZSByZXR1cm5lZCBieSBUYXJGaWxlLmdldG1lbWJlcigpLAogICAgICAgVGFyRmlsZS5nZXRtZW1iZXJzKCkgYW5kIFRhckZpbGUuZ2V0dGFyaW5mbygpIGFuZCBhcmUKICAgICAgIHVzdWFsbHkgY3JlYXRlZCBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9IiIpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0LiBuYW1lIGlzIHRoZSBvcHRpb25hbCBuYW1lCiAgICAgICAgICAgb2YgdGhlIG1lbWJlci4KICAgICAgICAiIiIKCiAgICAgICAgc2VsZi5uYW1lID0gbmFtZSAgICAgICAgIyBtZW1iZXIgbmFtZSAoZGlybmFtZXMgbXVzdCBlbmQgd2l0aCAnLycpCiAgICAgICAgc2VsZi5tb2RlID0gMDY2NiAgICAgICAgIyBmaWxlIHBlcm1pc3Npb25zCiAgICAgICAgc2VsZi51aWQgPSAwICAgICAgICAgICAgIyB1c2VyIGlkCiAgICAgICAgc2VsZi5naWQgPSAwICAgICAgICAgICAgIyBncm91cCBpZAogICAgICAgIHNlbGYuc2l6ZSA9IDAgICAgICAgICAgICMgZmlsZSBzaXplCiAgICAgICAgc2VsZi5tdGltZSA9IDAgICAgICAgICAgIyBtb2RpZmljYXRpb24gdGltZQogICAgICAgIHNlbGYuY2hrc3VtID0gMCAgICAgICAgICMgaGVhZGVyIGNoZWNrc3VtCiAgICAgICAgc2VsZi50eXBlID0gUkVHVFlQRSAgICAgIyBtZW1iZXIgdHlwZQogICAgICAgIHNlbGYubGlua25hbWUgPSAiIiAgICAgICMgbGluayBuYW1lCiAgICAgICAgc2VsZi51bmFtZSA9ICJ1c2VyIiAgICAgIyB1c2VyIG5hbWUKICAgICAgICBzZWxmLmduYW1lID0gImdyb3VwIiAgICAjIGdyb3VwIG5hbWUKICAgICAgICBzZWxmLmRldm1ham9yID0gMCAgICAgICAjIGRldmljZSBtYWpvciBudW1iZXIKICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAjIGRldmljZSBtaW5vciBudW1iZXIKICAgICAgICBzZWxmLnByZWZpeCA9ICIiICAgICAgICAjIHByZWZpeCB0byBmaWxlbmFtZSBvciBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWJvdXQgc3BhcnNlIGZpbGVzCgogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgIT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikKICAgICAgICBpZiBidWYuY291bnQoTlVMKSA9PSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImVtcHR5IGhlYWRlciIpCgogICAgICAgIHRhcmluZm8gPSBjbHMoKQogICAgICAgIHRhcmluZm8uYnVmID0gYnVmCiAgICAgICAgdGFyaW5mby5uYW1lID0gYnVmWzA6MTAwXS5yc3RyaXAoTlVMKQogICAgICAgIHRhcmluZm8ubW9kZSA9IG50aShidWZbMTAwOjEwOF0pCiAgICAgICAgdGFyaW5mby51aWQgPSBudGkoYnVmWzEwODoxMTZdKQogICAgICAgIHRhcmluZm8uZ2lkID0gbnRpKGJ1ZlsxMTY6MTI0XSkKICAgICAgICB0YXJpbmZvLnNpemUgPSBudGkoYnVmWzEyNDoxMzZdKQogICAgICAgIHRhcmluZm8ubXRpbWUgPSBudGkoYnVmWzEzNjoxNDhdKQogICAgICAgIHRhcmluZm8uY2hrc3VtID0gbnRpKGJ1ZlsxNDg6MTU2XSkKICAgICAgICB0YXJpbmZvLnR5cGUgPSBidWZbMTU2OjE1N10KICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gYnVmWzE1NzoyNTddLnJzdHJpcChOVUwpCiAgICAgICAgdGFyaW5mby51bmFtZSA9IGJ1ZlsyNjU6Mjk3XS5yc3RyaXAoTlVMKQogICAgICAgIHRhcmluZm8uZ25hbWUgPSBidWZbMjk3OjMyOV0ucnN0cmlwKE5VTCkKICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkKICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gbnRpKGJ1ZlszMzc6MzQ1XSkKICAgICAgICB0YXJpbmZvLnByZWZpeCA9IGJ1ZlszNDU6NTAwXQoKICAgICAgICBpZiB0YXJpbmZvLmNoa3N1bSBub3QgaW4gY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImludmFsaWQgaGVhZGVyIikKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiB0b2J1ZihzZWxmLCBwb3NpeD1GYWxzZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgdGFyIGhlYWRlciBibG9jayBhcyBhIDUxMiBieXRlIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBwYXJ0cyA9IFsKICAgICAgICAgICAgc3RuKHNlbGYubmFtZSwgMTAwKSwKICAgICAgICAgICAgaXRuKHNlbGYubW9kZSAmIDA3Nzc3LCA4LCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLnVpZCwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5naWQsIDgsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYuc2l6ZSwgMTIsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYubXRpbWUsIDEyLCBwb3NpeCksCiAgICAgICAgICAgICIgICAgICAgICIsICMgY2hlY2tzdW0gZmllbGQKICAgICAgICAgICAgc2VsZi50eXBlLAogICAgICAgICAgICBzdG4oc2VsZi5saW5rbmFtZSwgMTAwKSwKICAgICAgICAgICAgc3RuKE1BR0lDLCA2KSwKICAgICAgICAgICAgc3RuKFZFUlNJT04sIDIpLAogICAgICAgICAgICBzdG4oc2VsZi51bmFtZSwgMzIpLAogICAgICAgICAgICBzdG4oc2VsZi5nbmFtZSwgMzIpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtYWpvciwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtaW5vciwgOCwgcG9zaXgpLAogICAgICAgICAgICBzdG4oc2VsZi5wcmVmaXgsIDE1NSkKICAgICAgICBdCgogICAgICAgIGJ1ZiA9IHN0cnVjdC5wYWNrKCIlZHMiICUgQkxPQ0tTSVpFLCAiIi5qb2luKHBhcnRzKSkKICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bXMoYnVmKVswXQogICAgICAgIGJ1ZiA9IGJ1Zls6MTQ4XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWzE1NTpdCiAgICAgICAgc2VsZi5idWYgPSBidWYKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IEZhbHNlICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQogICAgICAgIHNlbGYuX21vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5tb2RlID0geyJyIjogInJiIiwgImEiOiAicitiIiwgInciOiAid2IifVttb2RlXQoKICAgICAgICBpZiBub3QgZmlsZW9iajoKICAgICAgICAgICAgZmlsZW9iaiA9IGZpbGUoc2VsZi5uYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIHNlbGYubmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBzZWxmLm5hbWUgPSBmaWxlb2JqLm5hbWUKICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgZGF0YXN0cnVjdHVyZXMKICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkCiAgICAgICAgc2VsZi5vZmZzZXQgPSAwTCAgICAgICAgIyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBhcmNoaXZlIGZpbGUKICAgICAgICBzZWxmLmlub2RlcyA9IHt9ICAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmNoaXZlIG1lbWJlcnMgYWxyZWFkeSBhZGRlZAoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IHNlbGYubmV4dCgpCgogICAgICAgIGlmIHNlbGYuX21vZGUgPT0gImEiOgogICAgICAgICAgICAjIE1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSwKICAgICAgICAgICAgIyBiZWZvcmUgdGhlIGZpcnN0IGVtcHR5IGJsb2NrLgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLm5leHQoKQogICAgICAgICAgICAgICAgZXhjZXB0IFJlYWRFcnJvcjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygwKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoLSBCTE9DS1NJWkUsIDEpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgaWYgc2VsZi5fbW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgY2xhc3NtZXRob2RzIHdoaWNoIGFjdCBhcyBhbHRlcm5hdGUgY29uc3RydWN0b3JzIHRvIHRoZQogICAgIyBUYXJGaWxlIGNsYXNzLiBUaGUgb3BlbigpIG1ldGhvZCBpcyB0aGUgb25seSBvbmUgdGhhdCBpcyBuZWVkZWQgZm9yCiAgICAjIHB1YmxpYyB1c2U7IGl0IGlzIHRoZSAic3VwZXIiLWNvbnN0cnVjdG9yIGFuZCBpcyBhYmxlIHRvIHNlbGVjdCBhbgogICAgIyBhZGVxdWF0ZSAic3ViIi1jb25zdHJ1Y3RvciBmb3IgYSBwYXJ0aWN1bGFyIGNvbXByZXNzaW9uIHVzaW5nIHRoZSBtYXBwaW5nCiAgICAjIGZyb20gT1BFTl9NRVRILgogICAgIwogICAgIyBUaGlzIGNvbmNlcHQgYWxsb3dzIG9uZSB0byBzdWJjbGFzcyBUYXJGaWxlIHdpdGhvdXQgbG9zaW5nIHRoZSBjb21mb3J0IG9mCiAgICAjIHRoZSBzdXBlci1jb25zdHJ1Y3Rvci4gQSBzdWItY29uc3RydWN0b3IgaXMgcmVnaXN0ZXJlZCBhbmQgbWFkZSBhdmFpbGFibGUKICAgICMgYnkgYWRkaW5nIGl0IHRvIHRoZSBtYXBwaW5nIGluIE9QRU5fTUVUSC4KCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBvcGVuKGNscywgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBidWZzaXplPTIwKjUxMik6CiAgICAgICAgIiIiT3BlbiBhIHRhciBhcmNoaXZlIGZvciByZWFkaW5nLCB3cml0aW5nIG9yIGFwcGVuZGluZy4gUmV0dXJuCiAgICAgICAgICAgYW4gYXBwcm9wcmlhdGUgVGFyRmlsZSBjbGFzcy4KCiAgICAgICAgICAgbW9kZToKICAgICAgICAgICAncicgb3IgJ3I6Kicgb3BlbiBmb3IgcmVhZGluZyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6JyAgICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgZXhjbHVzaXZlbHkgdW5jb21wcmVzc2VkCiAgICAgICAgICAgJ3I6Z3onICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6YnoyJyAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgogICAgICAgICAgICdhJyBvciAnYTonICBvcGVuIGZvciBhcHBlbmRpbmcKICAgICAgICAgICAndycgb3IgJ3c6JyAgb3BlbiBmb3Igd3JpdGluZyB3aXRob3V0IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6Z3onICAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6YnoyJyAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgoKICAgICAgICAgICAncnwqJyAgICAgICAgb3BlbiBhIHN0cmVhbSBvZiB0YXIgYmxvY2tzIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcKICAgICAgICAgICAncnxneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgIiIiCgogICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibm90aGluZyB0byBvcGVuIikKCiAgICAgICAgaWYgbW9kZSBpbiAoInIiLCAicjoqIik6CiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KICAgICAgICAgICAgZm9yIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaikKICAgICAgICAgICAgICAgIGV4Y2VwdCAoUmVhZEVycm9yLCBDb21wcmVzc2lvbkVycm9yKToKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaikKCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgifCIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgIGlmIGZpbGVtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwKICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50Z3oiOgogICAgICAgICAgICBleHQgPSAiLnRhciIKICAgICAgICBpZiBleHQgPT0gIi5neiI6CiAgICAgICAgICAgIGV4dCA9ICIiCiAgICAgICAgdGFybmFtZSA9IHByZSArIGV4dAoKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKG5hbWUsIG1vZGUgKyAiYiIpCgogICAgICAgIGlmIG1vZGUgIT0gInIiOgogICAgICAgICAgICBuYW1lID0gdGFybmFtZQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLAogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKQogICAgICAgICAgICApCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGJ6Mm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTkpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndycuIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50YnoyIjoKICAgICAgICAgICAgZXh0ID0gIi50YXIiCiAgICAgICAgaWYgZXh0ID09ICIuYnoyIjoKICAgICAgICAgICAgZXh0ID0gIiIKICAgICAgICB0YXJuYW1lID0gcHJlICsgZXh0CgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlb2JqID0gYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLCBmaWxlb2JqKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGJ6aXAyIGZpbGUiKQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgIyBBbGwgKm9wZW4oKSBtZXRob2RzIGFyZSByZWdpc3RlcmVkIGhlcmUuCiAgICBPUEVOX01FVEggPSB7CiAgICAgICAgInRhciI6ICJ0YXJvcGVuIiwgICAjIHVuY29tcHJlc3NlZCB0YXIKICAgICAgICAiZ3oiOiAgImd6b3BlbiIsICAgICMgZ3ppcCBjb21wcmVzc2VkIHRhcgogICAgICAgICJiejIiOiAiYnoyb3BlbiIgICAgIyBiemlwMiBjb21wcmVzc2VkIHRhcgogICAgfQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgcHVibGljIG1ldGhvZHMgd2hpY2ggVGFyRmlsZSBwcm92aWRlczoKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIFRhckZpbGUuIEluIHdyaXRlLW1vZGUsIHR3byBmaW5pc2hpbmcgemVybyBibG9ja3MgYXJlCiAgICAgICAgICAgYXBwZW5kZWQgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBzZWxmLl9tb2RlIGluICJhdyI6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFICogMikpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQogICAgICAgICAgICAjIGZpbGwgdXAgdGhlIGVuZCB3aXRoIHplcm8tYmxvY2tzCiAgICAgICAgICAgICMgKGxpa2Ugb3B0aW9uIC1iMjAgZm9yIHRhciBkb2VzKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoUkVDT1JEU0laRSAtIHJlbWFpbmRlcikpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBnZXRtZW1iZXIoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlCiAgICAgICAgICAgZm91bmQgaW4gdGhlIGFyY2hpdmUsIEtleUVycm9yIGlzIHJhaXNlZC4gSWYgYSBtZW1iZXIgb2NjdXJzIG1vcmUKICAgICAgICAgICB0aGFuIG9uY2UgaW4gdGhlIGFyY2hpdmUsIGl0cyBsYXN0IG9jY3VyZW5jZSBpcyBhc3N1bWVkIHRvIGJlIHRoZQogICAgICAgICAgIG1vc3QgdXAtdG8tZGF0ZSB2ZXJzaW9uLgogICAgICAgICIiIgogICAgICAgIHRhcmluZm8gPSBzZWxmLl9nZXRtZW1iZXIobmFtZSkKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCJmaWxlbmFtZSAlciBub3QgZm91bmQiICUgbmFtZSkKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiBnZXRtZW1iZXJzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgVGFySW5mbyBvYmplY3RzLiBUaGUKICAgICAgICAgICBsaXN0IGhhcyB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbWVtYmVycyBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygpCiAgICAgICAgaWYgbm90IHNlbGYuX2xvYWRlZDogICAgIyBpZiB3ZSB3YW50IHRvIG9idGFpbiBhIGxpc3Qgb2YKICAgICAgICAgICAgc2VsZi5fbG9hZCgpICAgICAgICAjIGFsbCBtZW1iZXJzLCB3ZSBmaXJzdCBoYXZlIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzY2FuIHRoZSB3aG9sZSBhcmNoaXZlLgogICAgICAgIHJldHVybiBzZWxmLm1lbWJlcnMKCiAgICBkZWYgZ2V0bmFtZXMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiB0aGVpciBuYW1lcy4gSXQgaGFzCiAgICAgICAgICAgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBbdGFyaW5mby5uYW1lIGZvciB0YXJpbmZvIGluIHNlbGYuZ2V0bWVtYmVycygpXQoKICAgIGRlZiBnZXR0YXJpbmZvKHNlbGYsIG5hbWU9Tm9uZSwgYXJjbmFtZT1Ob25lLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkNyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZvciBlaXRoZXIgdGhlIGZpbGUgYG5hbWUnIG9yIHRoZSBmaWxlCiAgICAgICAgICAgb2JqZWN0IGBmaWxlb2JqJyAodXNpbmcgb3MuZnN0YXQgb24gaXRzIGZpbGUgZGVzY3JpcHRvcikuIFlvdSBjYW4KICAgICAgICAgICBtb2RpZnkgc29tZSBvZiB0aGUgVGFySW5mbydzIGF0dHJpYnV0ZXMgYmVmb3JlIHlvdSBhZGQgaXQgdXNpbmcKICAgICAgICAgICBhZGRmaWxlKCkuIElmIGdpdmVuLCBgYXJjbmFtZScgc3BlY2lmaWVzIGFuIGFsdGVybmF0aXZlIG5hbWUgZm9yIHRoZQogICAgICAgICAgIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgIyBXaGVuIGZpbGVvYmogaXMgZ2l2ZW4sIHJlcGxhY2UgbmFtZSBieQogICAgICAgICMgZmlsZW9iaidzIHJlYWwgbmFtZS4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lCgogICAgICAgICMgQnVpbGRpbmcgdGhlIG5hbWUgb2YgdGhlIG1lbWJlciBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAjIEJhY2t3YXJkIHNsYXNoZXMgYXJlIGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXMsCiAgICAgICAgIyBBYnNvbHV0ZSBwYXRocyBhcmUgdHVybmVkIHRvIHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKICAgICAgICBhcmNuYW1lID0gbm9ybXBhdGgoYXJjbmFtZSkKICAgICAgICBkcnYsIGFyY25hbWUgPSBvcy5wYXRoLnNwbGl0ZHJpdmUoYXJjbmFtZSkKICAgICAgICB3aGlsZSBhcmNuYW1lWzA6MV0gPT0gIi8iOgogICAgICAgICAgICBhcmNuYW1lID0gYXJjbmFtZVsxOl0KCiAgICAgICAgIyBOb3csIGZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGgKICAgICAgICAjIGluZm9ybWF0aW9uIHNwZWNpZmljIGZvciB0aGUgZmlsZS4KICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCgogICAgICAgICMgVXNlIG9zLnN0YXQgb3Igb3MubHN0YXQsIGRlcGVuZGluZyBvbiBwbGF0Zm9ybQogICAgICAgICMgYW5kIGlmIHN5bWxpbmtzIHNoYWxsIGJlIHJlc29sdmVkLgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgImxzdGF0IikgYW5kIG5vdCBzZWxmLmRlcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmxzdGF0KG5hbWUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3Muc3RhdChuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5mc3RhdChmaWxlb2JqLmZpbGVubygpKQogICAgICAgIGxpbmtuYW1lID0gIiIKCiAgICAgICAgc3RtZCA9IHN0YXRyZXMuc3RfbW9kZQogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQogICAgICAgICAgICBpZiBub3Qgc2VsZi5kZXJlZmVyZW5jZSBhbmQgXAogICAgICAgICAgICAgICAgICAgIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBpbm9kZSBpbiBzZWxmLmlub2RlczoKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICAgICAgYXJjbmFtZSArPSAiLyIKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgPSBhcmNuYW1lCiAgICAgICAgdGFyaW5mby5tb2RlID0gc3RtZAogICAgICAgIHRhcmluZm8udWlkID0gc3RhdHJlcy5zdF91aWQKICAgICAgICB0YXJpbmZvLmdpZCA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSBzdGF0cmVzLnN0X3NpemUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKICAgICAgICAgICAgICAgIHByaW50ICIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwZCIgJSB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICBwcmludCAiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKCiAgICAgICAgICAgIHByaW50IHRhcmluZm8ubmFtZSwKCiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAibGluayB0byIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgIHByaW50CgogICAgZGVmIGFkZChzZWxmLCBuYW1lLCBhcmNuYW1lPU5vbmUsIHJlY3Vyc2l2ZT1UcnVlKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBcCiAgICAgICAgICAgIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gb3MucGF0aC5hYnNwYXRoKHNlbGYubmFtZSk6CiAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogU2tpcHBlZCAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBTcGVjaWFsIGNhc2U6IFRoZSB1c2VyIHdhbnRzIHRvIGFkZCB0aGUgY3VycmVudAogICAgICAgICMgd29ya2luZyBkaXJlY3RvcnkuCiAgICAgICAgaWYgbmFtZSA9PSAiLiI6CiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGlmIGFyY25hbWUgPT0gIi4iOgogICAgICAgICAgICAgICAgICAgIGFyY25hbWUgPSAiIgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcigiLiIpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKGYsIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNlbGYuX2RiZygxLCBuYW1lKQoKICAgICAgICAjIENyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0dGFyaW5mbyhuYW1lLCBhcmNuYW1lKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5zdXBwb3J0ZWQgdHlwZSAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBBcHBlbmQgdGhlIHRhciBoZWFkZXIgYW5kIGRhdGEgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBmID0gZmlsZShuYW1lLCAicmIiKQogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKICAgICAgICAgICAgZi5jbG9zZSgpCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChvcy5wYXRoLmpvaW4obmFtZSwgZiksIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCgogICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIFRhckluZm8gb2JqZWN0IGB0YXJpbmZvJyB0byB0aGUgYXJjaGl2ZS4gSWYgYGZpbGVvYmonIGlzCiAgICAgICAgICAgZ2l2ZW4sIHRhcmluZm8uc2l6ZSBieXRlcyBhcmUgcmVhZCBmcm9tIGl0IGFuZCBhZGRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLgogICAgICAgICAgIE9uIFdpbmRvd3MgcGxhdGZvcm1zLCBgZmlsZW9iaicgc2hvdWxkIGFsd2F5cyBiZSBvcGVuZWQgd2l0aCBtb2RlCiAgICAgICAgICAgJ3JiJyB0byBhdm9pZCBpcnJpdGF0aW9uIGFib3V0IHRoZSBmaWxlIHNpemUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgdGFyaW5mby5uYW1lID0gbm9ybXBhdGgodGFyaW5mby5uYW1lKQogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgIyBkaXJlY3RvcmllcyBzaG91bGQgZW5kIHdpdGggJy8nCiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKCiAgICAgICAgaWYgdGFyaW5mby5saW5rbmFtZToKICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IG5vcm1wYXRoKHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIGlmIHRhcmluZm8uc2l6ZSA+IE1BWFNJWkVfTUVNQkVSOgogICAgICAgICAgICBpZiBzZWxmLnBvc2l4OgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiZmlsZSBpcyB0b28gbGFyZ2UgKD49IDggR0IpIikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGxhcmdlZmlsZSBoZWFkZXIiKQoKCiAgICAgICAgaWYgbGVuKHRhcmluZm8ubGlua25hbWUpID4gTEVOR1RIX0xJTks6CiAgICAgICAgICAgIGlmIHNlbGYucG9zaXg6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJsaW5rbmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgJSAoTEVOR1RIX0xJTkspKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fY3JlYXRlX2dudWxvbmcodGFyaW5mby5saW5rbmFtZSwgR05VVFlQRV9MT05HTElOSykKICAgICAgICAgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSB0YXJpbmZvLmxpbmtuYW1lWzpMRU5HVEhfTElOSyAtMV0KICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTElOSyIpCgogICAgICAgIGlmIGxlbih0YXJpbmZvLm5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgIGlmIHNlbGYucG9zaXg6CiAgICAgICAgICAgICAgICBwcmVmaXggPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQogICAgICAgICAgICAgICAgd2hpbGUgcHJlZml4IGFuZCBwcmVmaXhbLTFdICE9ICIvIjoKICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICAgICAgICAgIG5hbWUgPSB0YXJpbmZvLm5hbWVbbGVuKHByZWZpeCk6XQogICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5hbWUgaXMgdG9vIGxvbmcgKD4lZCkiICUgKExFTkdUSF9OQU1FKSkKCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgICA9IG5hbWUKICAgICAgICAgICAgICAgIHRhcmluZm8ucHJlZml4ID0gcHJlZml4CiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9jcmVhdGVfZ251bG9uZyh0YXJpbmZvLm5hbWUsIEdOVVRZUEVfTE9OR05BTUUpCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9OQU1FIC0gMV0KICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTkFNRSIpCgogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZSh0YXJpbmZvLnRvYnVmKHNlbGYucG9zaXgpKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAjIElmIHRoZXJlJ3MgZGF0YSB0byBmb2xsb3csIGFwcGVuZCBpdC4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBjb3B5ZmlsZW9iaihmaWxlb2JqLCBzZWxmLmZpbGVvYmosIHRhcmluZm8uc2l6ZSkKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCiAgICAgICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQoKICAgIGRlZiBleHRyYWN0YWxsKHNlbGYsIHBhdGg9Ii4iLCBtZW1iZXJzPU5vbmUpOgogICAgICAgICIiIkV4dHJhY3QgYWxsIG1lbWJlcnMgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nCiAgICAgICAgICAgZGlyZWN0b3J5IGFuZCBzZXQgb3duZXIsIG1vZGlmaWNhdGlvbiB0aW1lIGFuZCBwZXJtaXNzaW9ucyBvbgogICAgICAgICAgIGRpcmVjdG9yaWVzIGFmdGVyd2FyZHMuIGBwYXRoJyBzcGVjaWZpZXMgYSBkaWZmZXJlbnQgZGlyZWN0b3J5CiAgICAgICAgICAgdG8gZXh0cmFjdCB0by4gYG1lbWJlcnMnIGlzIG9wdGlvbmFsIGFuZCBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZQogICAgICAgICAgIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgogICAgICAgICIiIgogICAgICAgIGRpcmVjdG9yaWVzID0gW10KCiAgICAgICAgaWYgbWVtYmVycyBpcyBOb25lOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZgoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBtZW1iZXJzOgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICAgICAjIEV4dHJhY3QgZGlyZWN0b3J5IHdpdGggYSBzYWZlIG1vZGUsIHNvIHRoYXQKICAgICAgICAgICAgICAgICMgYWxsIGZpbGVzIGJlbG93IGNhbiBiZSBleHRyYWN0ZWQgYXMgd2VsbC4KICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvcy5tYWtlZGlycyhvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKSwgMDc3NykKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yOgogICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5leHRyYWN0KHRhcmluZm8sIHBhdGgpCgogICAgICAgICMgUmV2ZXJzZSBzb3J0IGRpcmVjdG9yaWVzLgogICAgICAgIGRpcmVjdG9yaWVzLnNvcnQobGFtYmRhIGEsIGI6IGNtcChhLm5hbWUsIGIubmFtZSkpCiAgICAgICAgZGlyZWN0b3JpZXMucmV2ZXJzZSgpCgogICAgICAgICMgU2V0IGNvcnJlY3Qgb3duZXIsIG10aW1lIGFuZCBmaWxlbW9kZSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICBmb3IgdGFyaW5mbyBpbiBkaXJlY3RvcmllczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0KHNlbGYsIG1lbWJlciwgcGF0aD0iIik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LAogICAgICAgICAgIHVzaW5nIGl0cyBmdWxsIG5hbWUuIEl0cyBmaWxlIGluZm9ybWF0aW9uIGlzIGV4dHJhY3RlZCBhcyBhY2N1cmF0ZWx5CiAgICAgICAgICAgYXMgcG9zc2libGUuIGBtZW1iZXInIG1heSBiZSBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIFlvdSBjYW4KICAgICAgICAgICBzcGVjaWZ5IGEgZGlmZmVyZW50IGRpcmVjdG9yeSB1c2luZyBgcGF0aCcuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgVGFySW5mbyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQoKICAgICAgICAjIFByZXBhcmUgdGhlIGxpbmsgdGFyZ2V0IGZvciBtYWtlbGluaygpLgogICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgdGFyaW5mby5fbGlua190YXJnZXQgPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5saW5rbmFtZSkKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0YXJpbmZvLCBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKSkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMDoKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBlLmZpbGVuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlLnN0cmVycm9yKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzICVyIiAlIChlLnN0cmVycm9yLCBlLmZpbGVuYW1lKSkKICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yLCBlOgogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdGZpbGUoc2VsZiwgbWVtYmVyKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgYXMgYSBmaWxlIG9iamVjdC4gYG1lbWJlcicgbWF5IGJlCiAgICAgICAgICAgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBJZiBgbWVtYmVyJyBpcyBhIHJlZ3VsYXIgZmlsZSwgYQogICAgICAgICAgIGZpbGUtbGlrZSBvYmplY3QgaXMgcmV0dXJuZWQuIElmIGBtZW1iZXInIGlzIGEgbGluaywgYSBmaWxlLWxpa2UKICAgICAgICAgICBvYmplY3QgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgbGluaydzIHRhcmdldC4gSWYgYG1lbWJlcicgaXMgbm9uZSBvZgogICAgICAgICAgIHRoZSBhYm92ZSwgTm9uZSBpcyByZXR1cm5lZC4KICAgICAgICAgICBUaGUgZmlsZS1saWtlIG9iamVjdCBpcyByZWFkLW9ubHkgYW5kIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcKICAgICAgICAgICBtZXRob2RzOiByZWFkKCksIHJlYWRsaW5lKCksIHJlYWRsaW5lcygpLCBzZWVrKCkgYW5kIHRlbGwoKQogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIFRhckluZm8pOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgSWYgYSBtZW1iZXIncyB0eXBlIGlzIHVua25vd24sIGl0IGlzIHRyZWF0ZWQgYXMgYQogICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZS4KICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5maWxlb2JqLCBfU3RyZWFtKToKICAgICAgICAgICAgICAgICMgQSBzbWFsbCBidXQgdWdseSB3b3JrYXJvdW5kIGZvciB0aGUgY2FzZSB0aGF0IHNvbWVvbmUgdHJpZXMKICAgICAgICAgICAgICAgICMgdG8gZXh0cmFjdCBhIChzeW0pbGluayBhcyBhIGZpbGUtb2JqZWN0IGZyb20gYSBub24tc2Vla2FibGUKICAgICAgICAgICAgICAgICMgc3RyZWFtIG9mIHRhciBibG9ja3MuCiAgICAgICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvcigiY2Fubm90IGV4dHJhY3QgKHN5bSlsaW5rIGFzIGZpbGUgb2JqZWN0IikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgQSAoc3ltKWxpbmsncyBmaWxlIG9iamVjdCBpcyBpdHMgdGFyZ2V0J3MgZmlsZSBvYmplY3QuCiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5leHRyYWN0ZmlsZShzZWxmLl9nZXRtZW1iZXIodGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIElmIHRoZXJlJ3Mgbm8gZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIG1lbWJlciAoZGlyZWN0b3J5LCBjaHJkZXYsCiAgICAgICAgICAgICMgYmxrZGV2LCBldGMuKSwgcmV0dXJuIE5vbmUgaW5zdGVhZCBvZiBhIGZpbGUgb2JqZWN0LgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfZXh0cmFjdF9tZW1iZXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiRXh0cmFjdCB0aGUgVGFySW5mbyBvYmplY3QgdGFyaW5mbyB0byBhIHBoeXNpY2FsCiAgICAgICAgICAgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICAjIEZldGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmb3IgdGhlIGdpdmVuIG5hbWUKICAgICAgICAjIGFuZCBidWlsZCB0aGUgZGVzdGluYXRpb24gcGF0aG5hbWUsIHJlcGxhY2luZwogICAgICAgICMgZm9yd2FyZCBzbGFzaGVzIHRvIHBsYXRmb3JtIHNwZWNpZmljIHNlcGFyYXRvcnMuCiAgICAgICAgaWYgdGFyZ2V0cGF0aFstMTpdID09ICIvIjoKICAgICAgICAgICAgdGFyZ2V0cGF0aCA9IHRhcmdldHBhdGhbOi0xXQogICAgICAgIHRhcmdldHBhdGggPSBvcy5wYXRoLm5vcm1wYXRoKHRhcmdldHBhdGgpCgogICAgICAgICMgQ3JlYXRlIGFsbCB1cHBlciBkaXJlY3Rvcmllcy4KICAgICAgICB1cHBlcmRpcnMgPSBvcy5wYXRoLmRpcm5hbWUodGFyZ2V0cGF0aCkKICAgICAgICBpZiB1cHBlcmRpcnMgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyh1cHBlcmRpcnMpOgogICAgICAgICAgICB0aSA9IFRhckluZm8oKQogICAgICAgICAgICB0aS5uYW1lICA9IHVwcGVyZGlycwogICAgICAgICAgICB0aS50eXBlICA9IERJUlRZUEUKICAgICAgICAgICAgdGkubW9kZSAgPSAwNzc3CiAgICAgICAgICAgIHRpLm10aW1lID0gdGFyaW5mby5tdGltZQogICAgICAgICAgICB0aS51aWQgICA9IHRhcmluZm8udWlkCiAgICAgICAgICAgIHRpLmdpZCAgID0gdGFyaW5mby5naWQKICAgICAgICAgICAgdGkudW5hbWUgPSB0YXJpbmZvLnVuYW1lCiAgICAgICAgICAgIHRpLmduYW1lID0gdGFyaW5mby5nbmFtZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0aSwgdGkubmFtZSkKICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgIiVzIC0+ICVzIiAlICh0YXJpbmZvLm5hbWUsIHRhcmluZm8ubGlua25hbWUpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCB0YXJpbmZvLm5hbWUpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLm1ha2VkaXIodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNmaWZvKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpZm8odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRldih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5tYWtlbGluayh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgIHNlbGYubWFrZXVua25vd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBpZiBub3QgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBkaWZmZXJlbnQgZmlsZSBtZXRob2RzLiBUaGV5IGFyZSBjYWxsZWQgdmlhCiAgICAjIF9leHRyYWN0X21lbWJlcigpIHdoZW4gZXh0cmFjdCgpIGlzIGNhbGxlZC4gVGhleSBjYW4gYmUgcmVwbGFjZWQgaW4gYQogICAgIyBzdWJjbGFzcyB0byBpbXBsZW1lbnQgb3RoZXIgZnVuY3Rpb25hbGl0eS4KCiAgICBkZWYgbWFrZWRpcihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZGlyZWN0b3J5IGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MubWtkaXIodGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdGFyZ2V0ID0gZmlsZSh0YXJnZXRwYXRoLCAid2IiKQogICAgICAgIGNvcHlmaWxlb2JqKHNvdXJjZSwgdGFyZ2V0KQogICAgICAgIHNvdXJjZS5jbG9zZSgpCiAgICAgICAgdGFyZ2V0LmNsb3NlKCkKCiAgICBkZWYgbWFrZXVua25vd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpbGUgZnJvbSBhIFRhckluZm8gb2JqZWN0IHdpdGggYW4gdW5rbm93biB0eXBlCiAgICAgICAgICAgYXQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbmtub3duIGZpbGUgdHlwZSAlciwgIiBcCiAgICAgICAgICAgICAgICAgICAgICJleHRyYWN0ZWQgYXMgcmVndWxhciBmaWxlLiIgJSB0YXJpbmZvLnR5cGUpCgogICAgZGVmIG1ha2VmaWZvKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWZvIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICJta2ZpZm8iKToKICAgICAgICAgICAgb3MubWtmaWZvKHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJmaWZvIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIikKCiAgICBkZWYgbWFrZWRldihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgY2hhcmFjdGVyIG9yIGJsb2NrIGRldmljZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgIm1rbm9kIikgb3Igbm90IGhhc2F0dHIob3MsICJtYWtlZGV2Iik6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigic3BlY2lhbCBkZXZpY2VzIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIikKCiAgICAgICAgbW9kZSA9IHRhcmluZm8ubW9kZQogICAgICAgIGlmIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZCTEsKICAgICAgICBlbHNlOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkNIUgoKICAgICAgICBvcy5ta25vZCh0YXJnZXRwYXRoLCBtb2RlLAogICAgICAgICAgICAgICAgIG9zLm1ha2VkZXYodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpCgogICAgZGVmIG1ha2VsaW5rKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSAoc3ltYm9saWMpIGxpbmsgY2FsbGVkIHRhcmdldHBhdGguIElmIGl0IGNhbm5vdCBiZSBjcmVhdGVkCiAgICAgICAgICAocGxhdGZvcm0gbGltaXRhdGlvbiksIHdlIHRyeSB0byBtYWtlIGEgY29weSBvZiB0aGUgcmVmZXJlbmNlZCBmaWxlCiAgICAgICAgICBpbnN0ZWFkIG9mIGEgbGluay4KICAgICAgICAiIiIKICAgICAgICBsaW5rcGF0aCA9IHRhcmluZm8ubGlua25hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIG9zLnN5bWxpbmsobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFNlZSBleHRyYWN0KCkuCiAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5kaXJuYW1lKHRhcmluZm8ubmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rcGF0aCkKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gbm9ybXBhdGgobGlua3BhdGgpCgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcihzZWxmLmdldG1lbWJlcihsaW5rcGF0aCksIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCAoRW52aXJvbm1lbnRFcnJvciwgS2V5RXJyb3IpLCBlOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLm5vcm1wYXRoKGxpbmtwYXRoKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHNodXRpbC5jb3B5MihsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQiKQoKICAgIGRlZiBjaG93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgb3duZXIgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBwd2QgYW5kIGhhc2F0dHIob3MsICJnZXRldWlkIikgYW5kIG9zLmdldGV1aWQoKSA9PSAwOgogICAgICAgICAgICAjIFdlIGhhdmUgdG8gYmUgcm9vdCB0byBkbyBzby4KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncm5hbSh0YXJpbmZvLmduYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICBnID0gb3MuZ2V0Z2lkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd25hbSh0YXJpbmZvLnVuYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICB1ID0gb3MuZ2V0dWlkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpIGFuZCBoYXNhdHRyKG9zLCAibGNob3duIik6CiAgICAgICAgICAgICAgICAgICAgb3MubGNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAib3MyZW14IjoKICAgICAgICAgICAgICAgICAgICAgICAgb3MuY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2Ugb3duZXIiKQoKICAgIGRlZiBjaG1vZChzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgZmlsZSBwZXJtaXNzaW9ucyBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICdjaG1vZCcpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvcy5jaG1vZCh0YXJnZXRwYXRoLCB0YXJpbmZvLm1vZGUpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG1vZGUiKQoKICAgIGRlZiB1dGltZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgbW9kaWZpY2F0aW9uIHRpbWUgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgJ3V0aW1lJyk6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiIGFuZCB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICMgQWNjb3JkaW5nIHRvIG1zZG4ubWljcm9zb2Z0LmNvbSwgaXQgaXMgYW4gZXJyb3IgKEVBQ0NFUykKICAgICAgICAgICAgIyB0byB1c2UgdXRpbWUoKSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgbWVtYmVyIG9mIHRoZSBhcmNoaXZlIGFzIGEgVGFySW5mbyBvYmplY3QsIHdoZW4KICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQogICAgICAgICAgIGF2YWlsYWJsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygicmEiKQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG0gPSBzZWxmLmZpcnN0bWVtYmVyCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBtCgogICAgICAgICMgUmVhZCB0aGUgbmV4dCBibG9jay4KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IFRhckluZm8uZnJvbWJ1ZihidWYpCgogICAgICAgICAgICAgICAgIyBXZSBzaG91bGRuJ3QgcmVseSBvbiB0aGlzIGNoZWNrc3VtLCBiZWNhdXNlIHNvbWUgdGFyIHByb2dyYW1zCiAgICAgICAgICAgICAgICAjIGNhbGN1bGF0ZSBpdCBkaWZmZXJlbnRseSBhbmQgaXQgaXMgbWVyZWx5IHZhbGlkYXRpbmcgdGhlCiAgICAgICAgICAgICAgICAjIGhlYWRlciBibG9jay4gV2UgY291bGQganVzdCBhcyB3ZWxsIHNraXAgdGhpcyBwYXJ0LCB3aGljaCB3b3VsZAogICAgICAgICAgICAgICAgIyBoYXZlIGEgc2xpZ2h0IGVmZmVjdCBvbiBwZXJmb3JtYW5jZS4uLgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5jaGtzdW0gbm90IGluIGNhbGNfY2hrc3VtcyhidWYpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogQmFkIENoZWNrc3VtICVyIiAlIHRhcmluZm8ubmFtZSkKCiAgICAgICAgICAgICAgICAjIFNldCB0aGUgVGFySW5mbyBvYmplY3QncyBvZmZzZXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlCiAgICAgICAgICAgICAgICAjIFRhckZpbGUgYW5kIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzCiAgICAgICAgICAgICAgICAjIHNob3VsZCBiZWdpbi4KICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnByb2NfbWVtYmVyKHRhcmluZm8pCgogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogZW1wdHkgb3IgaW52YWxpZCBibG9jazogJXMiICUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGYub2Zmc2V0LCBlKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImVtcHR5LCB1bnJlYWRhYmxlIG9yIGNvbXByZXNzZWQgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpbGU6ICVzIiAlIGUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgIyBTb21lIG9sZCB0YXIgcHJvZ3JhbXMgcmVwcmVzZW50IGEgZGlyZWN0b3J5IGFzIGEgcmVndWxhcgogICAgICAgICMgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIGFuZCB0YXJpbmZvLm5hbWUuZW5kc3dpdGgoIi8iKToKICAgICAgICAgICAgdGFyaW5mby50eXBlID0gRElSVFlQRQoKICAgICAgICAjIFRoZSBwcmVmaXggZmllbGQgaXMgdXNlZCBmb3IgZmlsZW5hbWVzID4gMTAwIGluCiAgICAgICAgIyB0aGUgUE9TSVggc3RhbmRhcmQuCiAgICAgICAgIyBuYW1lID0gcHJlZml4ICsgJy8nICsgbmFtZQogICAgICAgIHRhcmluZm8ubmFtZSA9IG5vcm1wYXRoKG9zLnBhdGguam9pbih0YXJpbmZvLnByZWZpeC5yc3RyaXAoTlVMKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5uYW1lKSkKCiAgICAgICAgIyBEaXJlY3RvcnkgbmFtZXMgc2hvdWxkIGhhdmUgYSAnLycgYXQgdGhlIGVuZC4KICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBmb2xsb3dpbmcgYXJlIG1ldGhvZHMgdGhhdCBhcmUgY2FsbGVkIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBhCiAgICAjIG1lbWJlci4gVGhlIGVudHJ5IHBvaW50IGlzIHByb2NfbWVtYmVyKCkgd2hpY2ggaXMgY2FsbGVkIHdpdGggYSBUYXJJbmZvCiAgICAjIG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIGhlYWRlciBibG9jayBmcm9tIHRoZSBjdXJyZW50IG9mZnNldC4gVGhlCiAgICAjIHByb2NfbWVtYmVyKCkgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGluIGEgc3ViY2xhc3MgdG8gYWRkIGN1c3RvbQogICAgIyBwcm9jXyooKSBtZXRob2RzLiBBIHByb2NfKigpIG1ldGhvZCBNVVNUIGltcGxlbWVudCB0aGUgZm9sbG93aW5nCiAgICAjIG9wZXJhdGlvbnM6CiAgICAjIDEuIFNldCB0YXJpbmZvLm9mZnNldF9kYXRhIHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MgYmVnaW4sCiAgICAjICAgIGlmIHRoZXJlIGlzIGRhdGEgdGhhdCBmb2xsb3dzLgogICAgIyAyLiBTZXQgc2VsZi5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsCiAgICAjICAgIGJlZ2luLgogICAgIyAzLiBSZXR1cm4gdGFyaW5mbyBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgogICAgZGVmIHByb2NfbWVtYmVyKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIkNob29zZSB0aGUgcmlnaHQgcHJvY2Vzc2luZyBtZXRob2QgZm9yIHRhcmluZm8gZGVwZW5kaW5nCiAgICAgICAgICAgb24gaXRzIHR5cGUgYW5kIGNhbGwgaXQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgdGFyaW5mby50eXBlIGluIChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJvY19nbnVsb25nKHRhcmluZm8pCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9TUEFSU0U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2Nfc3BhcnNlKHRhcmluZm8pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJvY19idWlsdGluKHRhcmluZm8pCgogICAgZGVmIHByb2NfYnVpbHRpbihzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJQcm9jZXNzIGEgYnVpbHRpbiB0eXBlIG1lbWJlciBvciBhbiB1bmtub3duIG1lbWJlcgogICAgICAgICAgIHdoaWNoIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhID0gc2VsZi5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgb3IgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBzZWxmLl9ibG9jayh0YXJpbmZvLnNpemUpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgcHJvY19nbnVsb25nKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIlByb2Nlc3MgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKICAgICAgICAgICBvciBsb25nbGluayBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gIiIKICAgICAgICBjb3VudCA9IHRhcmluZm8uc2l6ZQogICAgICAgIHdoaWxlIGNvdW50ID4gMDoKICAgICAgICAgICAgYmxvY2sgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGJ1ZiArPSBibG9jawogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgY291bnQgLT0gQkxPQ0tTSVpFCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyIGFuZCBwcm9jZXNzIGl0LgogICAgICAgIGIgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgdCA9IFRhckluZm8uZnJvbWJ1ZihiKQogICAgICAgIHQub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICBuZXh0ID0gc2VsZi5wcm9jX21lbWJlcih0KQoKICAgICAgICAjIFBhdGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBuZXh0IGhlYWRlciB3aXRoCiAgICAgICAgIyB0aGUgbG9uZ25hbWUgaW5mb3JtYXRpb24uCiAgICAgICAgbmV4dC5vZmZzZXQgPSB0YXJpbmZvLm9mZnNldAogICAgICAgIGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdOQU1FOgogICAgICAgICAgICBuZXh0Lm5hbWUgPSBidWYucnN0cmlwKE5VTCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gYnVmLnJzdHJpcChOVUwpCgogICAgICAgIHJldHVybiBuZXh0CgogICAgZGVmIHByb2Nfc3BhcnNlKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIlByb2Nlc3MgYSBHTlUgc3BhcnNlIGhlYWRlciBwbHVzIGV4dHJhIGhlYWRlcnMuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gdGFyaW5mby5idWYKICAgICAgICBzcCA9IF9yaW5nYnVmZmVyKCkKICAgICAgICBwb3MgPSAzODYKICAgICAgICBsYXN0cG9zID0gMEwKICAgICAgICByZWFscG9zID0gMEwKICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQogICAgICAgICMgZmlyc3QgaGVhZGVyLgogICAgICAgIGZvciBpIGluIHhyYW5nZSg0KToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBudGkoYnVmW3BvcyArIDEyOnBvcyArIDI0XSkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgIHBvcyArPSAyNAoKICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQogICAgICAgIG9yaWdzaXplID0gbnRpKGJ1Zls0ODM6NDk1XSkKCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLAogICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KICAgICAgICB3aGlsZSBpc2V4dGVuZGVkID09IDE6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIHBvcyA9IDAKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKDIxKToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pCiAgICAgICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBudGkoYnVmW3BvcyArIDEyOnBvcyArIDI0XSkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICAgICAgcG9zICs9IDI0CiAgICAgICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzUwNF0pCgogICAgICAgIGlmIGxhc3Rwb3MgPCBvcmlnc2l6ZToKICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9yaWdzaXplIC0gbGFzdHBvcykpCgogICAgICAgIHRhcmluZm8uc3BhcnNlID0gc3AKCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG9yaWdzaXplCgogICAgICAgICMgQ2xlYXIgdGhlIHByZWZpeCBmaWVsZCBzbyB0aGF0IGl0IGlzIG5vdCB1c2VkCiAgICAgICAgIyBhcyBhIHBhdGhuYW1lIGluIG5leHQoKS4KICAgICAgICB0YXJpbmZvLnByZWZpeCA9ICIiCgogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIExpdHRsZSBoZWxwZXIgbWV0aG9kczoKCiAgICBkZWYgX2Jsb2NrKHNlbGYsIGNvdW50KToKICAgICAgICAiIiJSb3VuZCB1cCBhIGJ5dGUgY291bnQgYnkgQkxPQ0tTSVpFIGFuZCByZXR1cm4gaXQsCiAgICAgICAgICAgZS5nLiBfYmxvY2soODM0KSA9PiAxMDI0LgogICAgICAgICIiIgogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGNvdW50LCBCTE9DS1NJWkUpCiAgICAgICAgaWYgcmVtYWluZGVyOgogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHJldHVybiBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICBkZWYgX2dldG1lbWJlcihzZWxmLCBuYW1lLCB0YXJpbmZvPU5vbmUpOgogICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuCiAgICAgICAgICAgSWYgdGFyaW5mbyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuCiAgICAgICAgIiIiCiAgICAgICAgIyBFbnN1cmUgdGhhdCBhbGwgbWVtYmVycyBoYXZlIGJlZW4gbG9hZGVkLgogICAgICAgIG1lbWJlcnMgPSBzZWxmLmdldG1lbWJlcnMoKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIGVuZCA9IGxlbihtZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGVuZCA9IG1lbWJlcnMuaW5kZXgodGFyaW5mbykKCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGVuZCAtIDEsIC0xLCAtMSk6CiAgICAgICAgICAgIGlmIG5hbWUgPT0gbWVtYmVyc1tpXS5uYW1lOgogICAgICAgICAgICAgICAgcmV0dXJuIG1lbWJlcnNbaV0KCiAgICBkZWYgX2xvYWQoc2VsZik6CiAgICAgICAgIiIiUmVhZCB0aHJvdWdoIHRoZSBlbnRpcmUgYXJjaGl2ZSBmaWxlIGFuZCBsb29rIGZvciByZWFkYWJsZQogICAgICAgICAgIG1lbWJlcnMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgIGRlZiBfY2hlY2soc2VsZiwgbW9kZT1Ob25lKToKICAgICAgICAiIiJDaGVjayBpZiBUYXJGaWxlIGlzIHN0aWxsIG9wZW4sIGFuZCBpZiB0aGUgb3BlcmF0aW9uJ3MgbW9kZQogICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIFRhckZpbGUncyBtb2RlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18pCiAgICAgICAgaWYgbW9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5fbW9kZSBub3QgaW4gbW9kZToKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiYmFkIG9wZXJhdGlvbiBmb3IgbW9kZSAlciIgJSBzZWxmLl9tb2RlKQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJQcm92aWRlIGFuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHJldHVybiBpdGVyKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQoKICAgIGRlZiBfY3JlYXRlX2dudWxvbmcoc2VsZiwgbmFtZSwgdHlwZSk6CiAgICAgICAgIiIiV3JpdGUgYSBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgbWVtYmVyIHRvIHRoZSBUYXJGaWxlLgogICAgICAgICAgIEl0IGNvbnNpc3RzIG9mIGFuIGV4dGVuZGVkIHRhciBoZWFkZXIsIHdpdGggdGhlIGxlbmd0aAogICAgICAgICAgIG9mIHRoZSBsb25nbmFtZSBhcyBzaXplLCBmb2xsb3dlZCBieSBkYXRhIGJsb2NrcywKICAgICAgICAgICB3aGljaCBjb250YWluIHRoZSBsb25nbmFtZSBhcyBhIG51bGwgdGVybWluYXRlZCBzdHJpbmcuCiAgICAgICAgIiIiCiAgICAgICAgbmFtZSArPSBOVUwKCiAgICAgICAgdGFyaW5mbyA9IFRhckluZm8oKQogICAgICAgIHRhcmluZm8ubmFtZSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLm1vZGUgPSAwCiAgICAgICAgdGFyaW5mby5zaXplID0gbGVuKG5hbWUpCgogICAgICAgICMgd3JpdGUgZXh0ZW5kZWQgaGVhZGVyCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHRhcmluZm8udG9idWYoKSkKICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAjIHdyaXRlIG5hbWUgYmxvY2tzCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKG5hbWUpCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCiAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHNlbGYub2Zmc2V0ICs9IGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBtc2cKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgICAgIHNlbGYuaW5kZXggPSAwCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4KICAgICAgICAiIiIKICAgICAgICAjIEZpeCBmb3IgU0YgIzExMDA0Mjk6IFVuZGVyIHJhcmUgY2lyY3Vtc3RhbmNlcyBpdCBjYW4KICAgICAgICAjIGhhcHBlbiB0aGF0IGdldG1lbWJlcnMoKSBpcyBjYWxsZWQgZHVyaW5nIGl0ZXJhdGlvbiwKICAgICAgICAjIHdoaWNoIHdpbGwgY2F1c2UgVGFySXRlciB0byBzdG9wIHByZW1hdHVyZWx5LgogICAgICAgIGlmIG5vdCBzZWxmLnRhcmZpbGUuX2xvYWRlZDoKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IHRhcmluZm86CiAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuX2xvYWRlZCA9IFRydWUKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm1lbWJlcnNbc2VsZi5pbmRleF0KICAgICAgICAgICAgZXhjZXB0IEluZGV4RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgc2VsZi5pbmRleCArPSAxCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiMgSGVscGVyIGNsYXNzZXMgZm9yIHNwYXJzZSBmaWxlIHN1cHBvcnQKY2xhc3MgX3NlY3Rpb246CiAgICAiIiJCYXNlIGNsYXNzIGZvciBfZGF0YSBhbmQgX2hvbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpOgogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgZGVmIF9fY29udGFpbnNfXyhzZWxmLCBvZmZzZXQpOgogICAgICAgIHJldHVybiBzZWxmLm9mZnNldCA8PSBvZmZzZXQgPCBzZWxmLm9mZnNldCArIHNlbGYuc2l6ZQoKY2xhc3MgX2RhdGEoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgZGF0YSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUsIHJlYWxwb3MpOgogICAgICAgIF9zZWN0aW9uLl9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSkKICAgICAgICBzZWxmLnJlYWxwb3MgPSByZWFscG9zCgpjbGFzcyBfaG9sZShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBob2xlIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgcGFzcwoKY2xhc3MgX3JpbmdidWZmZXIobGlzdCk6CiAgICAiIiJSaW5nYnVmZmVyIGNsYXNzIHdoaWNoIGluY3JlYXNlcyBwZXJmb3JtYW5jZQogICAgICAgb3ZlciBhIHJlZ3VsYXIgbGlzdC4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuaWR4ID0gMAogICAgZGVmIGZpbmQoc2VsZiwgb2Zmc2V0KToKICAgICAgICBpZHggPSBzZWxmLmlkeAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmW2lkeF0KICAgICAgICAgICAgaWYgb2Zmc2V0IGluIGl0ZW06CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZHggKz0gMQogICAgICAgICAgICBpZiBpZHggPT0gbGVuKHNlbGYpOgogICAgICAgICAgICAgICAgaWR4ID0gMAogICAgICAgICAgICBpZiBpZHggPT0gc2VsZi5pZHg6CiAgICAgICAgICAgICAgICAjIEVuZCBvZiBGaWxlCiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIHNlbGYuaWR4ID0gaWR4CiAgICAgICAgcmV0dXJuIGl0ZW0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB6aXBmaWxlIGNvbXBhdGlibGUgVGFyRmlsZSBjbGFzcwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRBUl9QTEFJTiA9IDAgICAgICAgICAgICMgemlwZmlsZS5aSVBfU1RPUkVEClRBUl9HWklQUEVEID0gOCAgICAgICAgICMgemlwZmlsZS5aSVBfREVGTEFURUQKY2xhc3MgVGFyRmlsZUNvbXBhdDoKICAgICIiIlRhckZpbGUgY2xhc3MgY29tcGF0aWJsZSB3aXRoIHN0YW5kYXJkIG1vZHVsZSB6aXBmaWxlJ3MKICAgICAgIFppcEZpbGUgY2xhc3MuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBtb2RlPSJyIiwgY29tcHJlc3Npb249VEFSX1BMQUlOKToKICAgICAgICBpZiBjb21wcmVzc2lvbiA9PSBUQVJfUExBSU46CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUudGFyb3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsaWYgY29tcHJlc3Npb24gPT0gVEFSX0daSVBQRUQ6CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUuZ3pvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIpCiAgICAgICAgaWYgbW9kZVswOjFdID09ICJyIjoKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkKICAgICAgICAgICAgZm9yIG0gaW4gbWVtYmVyczoKICAgICAgICAgICAgICAgIG0uZmlsZW5hbWUgPSBtLm5hbWUKICAgICAgICAgICAgICAgIG0uZmlsZV9zaXplID0gbS5zaXplCiAgICAgICAgICAgICAgICBtLmRhdGVfdGltZSA9IHRpbWUuZ210aW1lKG0ubXRpbWUpWzo2XQogICAgZGVmIG5hbWVsaXN0KHNlbGYpOgogICAgICAgIHJldHVybiBtYXAobGFtYmRhIG06IG0ubmFtZSwgc2VsZi5pbmZvbGlzdCgpKQogICAgZGVmIGluZm9saXN0KHNlbGYpOgogICAgICAgIHJldHVybiBmaWx0ZXIobGFtYmRhIG06IG0udHlwZSBpbiBSRUdVTEFSX1RZUEVTLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKSkKICAgIGRlZiBwcmludGRpcihzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUubGlzdCgpCiAgICBkZWYgdGVzdHppcChzZWxmKToKICAgICAgICByZXR1cm4KICAgIGRlZiBnZXRpbmZvKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpCiAgICBkZWYgcmVhZChzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmV4dHJhY3RmaWxlKHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkpLnJlYWQoKQogICAgZGVmIHdyaXRlKHNlbGYsIGZpbGVuYW1lLCBhcmNuYW1lPU5vbmUsIGNvbXByZXNzX3R5cGU9Tm9uZSk6CiAgICAgICAgc2VsZi50YXJmaWxlLmFkZChmaWxlbmFtZSwgYXJjbmFtZSkKICAgIGRlZiB3cml0ZXN0cihzZWxmLCB6aW5mbywgYnl0ZXMpOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnJvbSBjU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBmcm9tIFN0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGltcG9ydCBjYWxlbmRhcgogICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQogICAgICAgIHppbmZvLnNpemUgPSB6aW5mby5maWxlX3NpemUKICAgICAgICB6aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCm9wZW4gPSBUYXJGaWxlLm9wZW4K