IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC44LjAiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKCmlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICMgVGhpcyBtb2R1bGUgbmVlZHMgd29yayBmb3IgTWFjT1M5LCBlc3BlY2lhbGx5IGluIHRoZSBhcmVhIG9mIHBhdGhuYW1lCiAgICAjIGhhbmRsaW5nLiBJbiBtYW55IHBsYWNlcyBpdCBpcyBhc3N1bWVkIGEgc2ltcGxlIHN1YnN0aXR1dGlvbiBvZiAvIGJ5IHRoZQogICAgIyBsb2NhbCBvcy5wYXRoLnNlcCBpcyBnb29kIGVub3VnaCB0byBjb252ZXJ0IHBhdGhuYW1lcywgYnV0IHRoaXMgZG9lcyBub3QKICAgICMgd29yayB3aXRoIHRoZSBtYWMgcm9vdGVkOnBhdGg6bmFtZSB2ZXJzdXMgOm5vbnJvb3RlZDpwYXRoOm5hbWUgc3ludGF4CiAgICByYWlzZSBJbXBvcnRFcnJvciwgInRhcmZpbGUgZG9lcyBub3Qgd29yayBmb3IgcGxhdGZvcm09PW1hYyIKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBzdG4ocywgbGVuZ3RoKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gc3RyaW5nIHRvIGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBidWZmZXIuCiAgICAiIiIKICAgIHJldHVybiBzWzpsZW5ndGgtMV0gKyAobGVuZ3RoIC0gbGVuKHMpIC0gMSkgKiBOVUwgKyBOVUwKCmRlZiBudGkocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4KICAgICIiIgogICAgIyBUaGVyZSBhcmUgdHdvIHBvc3NpYmxlIGVuY29kaW5ncyBmb3IgYSBudW1iZXIgZmllbGQsIHNlZQogICAgIyBpdG4oKSBiZWxvdy4KICAgIGlmIHNbMF0gIT0gY2hyKDAyMDApOgogICAgICAgIG4gPSBpbnQocy5yc3RyaXAoTlVMKSBvciAiMCIsIDgpCiAgICBlbHNlOgogICAgICAgIG4gPSAwTAogICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4ocykgLSAxKToKICAgICAgICAgICAgbiA8PD0gOAogICAgICAgICAgICBuICs9IG9yZChzW2kgKyAxXSkKICAgIHJldHVybiBuCgpkZWYgaXRuKG4sIGRpZ2l0cz04LCBwb3NpeD1GYWxzZSk6CiAgICAiIiJDb252ZXJ0IGEgcHl0aG9uIG51bWJlciB0byBhIG51bWJlciBmaWVsZC4KICAgICIiIgogICAgIyBQT1NJWCAxMDAzLjEtMTk4OCByZXF1aXJlcyBudW1iZXJzIHRvIGJlIGVuY29kZWQgYXMgYSBzdHJpbmcgb2YKICAgICMgb2N0YWwgZGlnaXRzIGZvbGxvd2VkIGJ5IGEgbnVsbC1ieXRlLCB0aGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8KICAgICMgKDgqKihkaWdpdHMtMSkpLTEuIEdOVSB0YXIgYWxsb3dzIHN0b3JpbmcgbnVtYmVycyBncmVhdGVyIHRoYW4KICAgICMgdGhhdCBpZiBuZWNlc3NhcnkuIEEgbGVhZGluZyAwMjAwIGJ5dGUgaW5kaWNhdGVzIHRoaXMgcGFydGljdWxhcgogICAgIyBlbmNvZGluZywgdGhlIGZvbGxvd2luZyBkaWdpdHMtMSBieXRlcyBhcmUgYSBiaWctZW5kaWFuCiAgICAjIHJlcHJlc2VudGF0aW9uLiBUaGlzIGFsbG93cyB2YWx1ZXMgdXAgdG8gKDI1NioqKGRpZ2l0cy0xKSktMS4KICAgIGlmIDAgPD0gbiA8IDggKiogKGRpZ2l0cyAtIDEpOgogICAgICAgIHMgPSAiJTAqbyIgJSAoZGlnaXRzIC0gMSwgbikgKyBOVUwKICAgIGVsc2U6CiAgICAgICAgaWYgcG9zaXg6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm92ZXJmbG93IGluIG51bWJlciBmaWVsZCIpCgogICAgICAgIGlmIG4gPCAwOgogICAgICAgICAgICAjIFhYWCBXZSBtaW1pYyBHTlUgdGFyJ3MgYmVoYXZpb3VyIHdpdGggbmVnYXRpdmUgbnVtYmVycywKICAgICAgICAgICAgIyB0aGlzIGNvdWxkIHJhaXNlIE92ZXJmbG93RXJyb3IuCiAgICAgICAgICAgIG4gPSBzdHJ1Y3QudW5wYWNrKCJMIiwgc3RydWN0LnBhY2soImwiLCBuKSlbMF0KCiAgICAgICAgcyA9ICIiCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGRpZ2l0cyAtIDEpOgogICAgICAgICAgICBzID0gY2hyKG4gJiAwMzc3KSArIHMKICAgICAgICAgICAgbiA+Pj0gOAogICAgICAgIHMgPSBjaHIoMDIwMCkgKyBzCiAgICByZXR1cm4gcwoKZGVmIGNhbGNfY2hrc3VtcyhidWYpOgogICAgIiIiQ2FsY3VsYXRlIHRoZSBjaGVja3N1bSBmb3IgYSBtZW1iZXIncyBoZWFkZXIgYnkgc3VtbWluZyB1cCBhbGwKICAgICAgIGNoYXJhY3RlcnMgZXhjZXB0IGZvciB0aGUgY2hrc3VtIGZpZWxkIHdoaWNoIGlzIHRyZWF0ZWQgYXMgaWYKICAgICAgIGl0IHdhcyBmaWxsZWQgd2l0aCBzcGFjZXMuIEFjY29yZGluZyB0byB0aGUgR05VIHRhciBzb3VyY2VzLAogICAgICAgc29tZSB0YXJzIChTdW4gYW5kIE5lWFQpIGNhbGN1bGF0ZSBjaGtzdW0gd2l0aCBzaWduZWQgY2hhciwKICAgICAgIHdoaWNoIHdpbGwgYmUgZGlmZmVyZW50IGlmIHRoZXJlIGFyZSBjaGFycyBpbiB0aGUgYnVmZmVyIHdpdGgKICAgICAgIHRoZSBoaWdoIGJpdCBzZXQuIFNvIHdlIGNhbGN1bGF0ZSB0d28gY2hlY2tzdW1zLCB1bnNpZ25lZCBhbmQKICAgICAgIHNpZ25lZC4KICAgICIiIgogICAgdW5zaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OEIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2QiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICBzaWduZWRfY2hrc3VtID0gMjU2ICsgc3VtKHN0cnVjdC51bnBhY2soIjE0OGIiLCBidWZbOjE0OF0pICsgc3RydWN0LnVucGFjaygiMzU2YiIsIGJ1ZlsxNTY6NTEyXSkpCiAgICByZXR1cm4gdW5zaWduZWRfY2hrc3VtLCBzaWduZWRfY2hrc3VtCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuKHNlbGYuYnVmKSwgc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5idWYgKz0gTlVMICogKHNlbGYuYnVmc2l6ZSAtIHJlbWFpbmRlcikKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPGwiLCBzZWxmLmNyYykpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5wb3MgJiAweGZmZmZGRkZGTCkpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQoKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX2luaXRfcmVhZF9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciByZWFkaW5nIGEgZ3ppcCBjb21wcmVzc2VkIGZpbGVvYmouCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuZGVjb21wcmVzc29iaigtc2VsZi56bGliLk1BWF9XQklUUykKICAgICAgICBzZWxmLmRidWYgPSAiIgoKICAgICAgICAjIHRha2VuIGZyb20gZ3ppcC5HemlwRmlsZSB3aXRoIHNvbWUgYWx0ZXJhdGlvbnMKICAgICAgICBpZiBzZWxmLl9fcmVhZCgyKSAhPSAiXDAzN1wyMTMiOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMSkgIT0gIlwwMTAiOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ1bnN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2QiKQoKICAgICAgICBmbGFnID0gb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgIHNlbGYuX19yZWFkKDYpCgogICAgICAgIGlmIGZsYWcgJiA0OgogICAgICAgICAgICB4bGVuID0gb3JkKHNlbGYuX19yZWFkKDEpKSArIDI1NiAqIG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICAgICAgc2VsZi5yZWFkKHhsZW4pCiAgICAgICAgaWYgZmxhZyAmIDg6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDE2OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAyOgogICAgICAgICAgICBzZWxmLl9fcmVhZCgyKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcz0wKToKICAgICAgICAiIiJTZXQgdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciB0byBwb3MuIE5lZ2F0aXZlIHNlZWtpbmcKICAgICAgICAgICBpcyBmb3JiaWRkZW4uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcG9zIC0gc2VsZi5wb3MgPj0gMDoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QocG9zIC0gc2VsZi5wb3MsIHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgICAgICAgICBzZWxmLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBzZWxmLnJlYWQocmVtYWluZGVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJzZWVraW5nIGJhY2t3YXJkcyBpcyBub3QgYWxsb3dlZCIpCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgc2l6ZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICAgIElmIHNpemUgaXMgbm90IGRlZmluZWQsIHJldHVybiBhbGwgYnl0ZXMgb2YgdGhlIHN0cmVhbQogICAgICAgICAgIHVwIHRvIEVPRi4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHQgPSBbXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGJ1ZiA9ICIiLmpvaW4odCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNpemUpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIF9yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJ0YXIiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoc2l6ZSkKCiAgICAgICAgYyA9IGxlbihzZWxmLmRidWYpCiAgICAgICAgdCA9IFtzZWxmLmRidWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX19yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuY21wLmRlY29tcHJlc3MoYnVmKQogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuZGJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAogICAgICAgICAgIHJlYWQgYW5vdGhlciBibG9jayBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB0ID0gW3NlbGYuYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KIyBjbGFzcyBfU3RyZWFtCgpjbGFzcyBfU3RyZWFtUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgZGV0ZWN0aW9uIGZvciB0aGUgU3RyZWFtIGludGVyZmFjZSAobW9kZSAncnwqJykuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaik6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYuYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHNlbGYucmVhZCA9IHNlbGYuZmlsZW9iai5yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuYnVmCgogICAgZGVmIGdldGNvbXB0eXBlKHNlbGYpOgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIlwwMzdcMjEzXDAxMCIpOgogICAgICAgICAgICByZXR1cm4gImd6IgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIkJaaDkxIik6CiAgICAgICAgICAgIHJldHVybiAiYnoyIgogICAgICAgIHJldHVybiAidGFyIgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIFN0cmVhbVByb3h5CgpjbGFzcyBfQloyUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyBleHRlcm5hbCBmaWxlIG9iamVjdAogICAgICAgc3VwcG9ydCBmb3IgInI6YnoyIiBhbmQgInc6YnoyIiBtb2Rlcy4gVGhpcyBpcyBhY3R1YWxseQogICAgICAgYSB3b3JrYXJvdW5kIGZvciBhIGxpbWl0YXRpb24gaW4gYnoyIG1vZHVsZSdzIEJaMkZpbGUKICAgICAgIGNsYXNzIHdoaWNoICh1bmxpa2UgZ3ppcC5HemlwRmlsZSkgaGFzIG5vIHN1cHBvcnQgZm9yCiAgICAgICBhIGZpbGUgb2JqZWN0IGFyZ3VtZW50LgogICAgIiIiCgogICAgYmxvY2tzaXplID0gMTYgKiAxMDI0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmosIG1vZGUpOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLm1vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5pbml0KCkKCiAgICBkZWYgaW5pdChzZWxmKToKICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgc2VsZi5wb3MgPSAwCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgc2VsZi5idWYgPSAiIgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkNvbXByZXNzb3IoKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIGIgPSBbc2VsZi5idWZdCiAgICAgICAgeCA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB3aGlsZSB4IDwgc2l6ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgcmF3ID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBkYXRhID0gc2VsZi5iejJvYmouZGVjb21wcmVzcyhyYXcpCiAgICAgICAgICAgICAgICBiLmFwcGVuZChkYXRhKQogICAgICAgICAgICBleGNlcHQgRU9GRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB4ICs9IGxlbihkYXRhKQogICAgICAgIHNlbGYuYnVmID0gIiIuam9pbihiKQoKICAgICAgICBidWYgPSBzZWxmLmJ1Zls6c2l6ZV0KICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NpemU6XQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcyk6CiAgICAgICAgaWYgcG9zIDwgc2VsZi5wb3M6CiAgICAgICAgICAgIHNlbGYuaW5pdCgpCiAgICAgICAgc2VsZi5yZWFkKHBvcyAtIHNlbGYucG9zKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiB3cml0ZShzZWxmLCBkYXRhKToKICAgICAgICBzZWxmLnBvcyArPSBsZW4oZGF0YSkKICAgICAgICByYXcgPSBzZWxmLmJ6Mm9iai5jb21wcmVzcyhkYXRhKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyI6CiAgICAgICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmZsdXNoKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIF9CWjJQcm94eQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEV4dHJhY3Rpb24gZmlsZSBvYmplY3QKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuIFN1cHBvcnQgZm9yCiAgICAgICBzcGFyc2UgZmlsZXMgaW5jbHVkZWQuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gdGFyZmlsZS5maWxlb2JqCiAgICAgICAgc2VsZi5uYW1lICAgID0gdGFyaW5mby5uYW1lCiAgICAgICAgc2VsZi5tb2RlICAgID0gInIiCiAgICAgICAgc2VsZi5jbG9zZWQgID0gRmFsc2UKICAgICAgICBzZWxmLm9mZnNldCAgPSB0YXJpbmZvLm9mZnNldF9kYXRhCiAgICAgICAgc2VsZi5zaXplICAgID0gdGFyaW5mby5zaXplCiAgICAgICAgc2VsZi5wb3MgICAgID0gMEwKICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgIGlmIHRhcmluZm8uaXNzcGFyc2UoKToKICAgICAgICAgICAgc2VsZi5zcGFyc2UgPSB0YXJpbmZvLnNwYXJzZQogICAgICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLl9yZWFkc3BhcnNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5fcmVhZG5vcm1hbAoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiT3ZlcmxvYWRhYmxlIHJlYWQgbWV0aG9kLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIGEgbGluZSB3aXRoIGFwcHJveC4gc2l6ZS4gSWYgc2l6ZSBpcyBuZWdhdGl2ZSwKICAgICAgICAgICByZWFkIGEgd2hvbGUgbGluZS4gcmVhZGxpbmUoKSBhbmQgcmVhZCgpIG11c3Qgbm90CiAgICAgICAgICAgYmUgbWl4ZWQgdXAgKCEpLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgPCAwOgogICAgICAgICAgICBzaXplID0gc3lzLm1heGludAoKICAgICAgICBubCA9IHNlbGYubGluZWJ1ZmZlci5maW5kKCJcbiIpCiAgICAgICAgaWYgbmwgPj0gMDoKICAgICAgICAgICAgbmwgPSBtaW4obmwsIHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oc2VsZi5saW5lYnVmZmVyKQogICAgICAgICAgICB3aGlsZSAobmwgPCAwIGFuZCBzaXplID4gMCk6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLnJlYWQobWluKHNpemUsIDEwMCkpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgKz0gYnVmCiAgICAgICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgICAgICBubCA9IHNlbGYubGluZWJ1ZmZlci5maW5kKCJcbiIpCiAgICAgICAgICAgIGlmIG5sID09IC0xOgogICAgICAgICAgICAgICAgcyA9IHNlbGYubGluZWJ1ZmZlcgogICAgICAgICAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKICAgICAgICAgICAgICAgIHJldHVybiBzCiAgICAgICAgYnVmID0gc2VsZi5saW5lYnVmZmVyWzpubF0KICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSBzZWxmLmxpbmVidWZmZXJbbmwgKyAxOl0KICAgICAgICB3aGlsZSBidWZbLTE6XSA9PSAiXHIiOgogICAgICAgICAgICBidWYgPSBidWZbOi0xXQogICAgICAgIHJldHVybiBidWYgKyAiXG4iCgogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IHdpdGggYWxsIChmb2xsb3dpbmcpIGxpbmVzLgogICAgICAgICIiIgogICAgICAgIHJlc3VsdCA9IFtdCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChsaW5lKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgX3JlYWRub3JtYWwoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3IgcmVndWxhciBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiZmlsZSBpcyBjbG9zZWQiKQogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgc2VsZi5wb3MpCiAgICAgICAgYnl0ZXNsZWZ0ID0gc2VsZi5zaXplIC0gc2VsZi5wb3MKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIGJ5dGVzdG9yZWFkID0gYnl0ZXNsZWZ0CiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnl0ZXN0b3JlYWQgPSBtaW4oc2l6ZSwgYnl0ZXNsZWZ0KQogICAgICAgIHNlbGYucG9zICs9IGJ5dGVzdG9yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKGJ5dGVzdG9yZWFkKQoKICAgIGRlZiBfcmVhZHNwYXJzZShzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciBzcGFyc2UgZmlsZXMuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImZpbGUgaXMgY2xvc2VkIikKCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICBzaXplID0gc2VsZi5zaXplIC0gc2VsZi5wb3MKCiAgICAgICAgZGF0YSA9IFtdCiAgICAgICAgd2hpbGUgc2l6ZSA+IDA6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWRzcGFyc2VzZWN0aW9uKHNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBzaXplIC09IGxlbihidWYpCiAgICAgICAgICAgIGRhdGEuYXBwZW5kKGJ1ZikKICAgICAgICByZXR1cm4gIiIuam9pbihkYXRhKQoKICAgIGRlZiBfcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBhIHNpbmdsZSBzZWN0aW9uIG9mIGEgc3BhcnNlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3MpCgogICAgICAgIGlmIHNlY3Rpb24gaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuICIiCgogICAgICAgIHRvcmVhZCA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zKQogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3MgLSBzZWN0aW9uLm9mZnNldAogICAgICAgICAgICBzZWxmLnBvcyArPSB0b3JlYWQKICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyByZWFscG9zKQogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQodG9yZWFkKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAogICAgICAgICAgICByZXR1cm4gTlVMICogdG9yZWFkCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zLCB3aGVuY2U9MCk6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCiAgICAgICAgaWYgd2hlbmNlID09IDA6CiAgICAgICAgICAgIHNlbGYucG9zID0gbWluKG1heChwb3MsIDApLCBzZWxmLnNpemUpCiAgICAgICAgaWYgd2hlbmNlID09IDE6CiAgICAgICAgICAgIGlmIHBvcyA8IDA6CiAgICAgICAgICAgICAgICBzZWxmLnBvcyA9IG1heChzZWxmLnBvcyArIHBvcywgMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWluKHNlbGYucG9zICsgcG9zLCBzZWxmLnNpemUpCiAgICAgICAgaWYgd2hlbmNlID09IDI6CiAgICAgICAgICAgIHNlbGYucG9zID0gbWF4KG1pbihzZWxmLnNpemUgKyBwb3MsIHNlbGYuc2l6ZSksIDApCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBmaWxlIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiR2V0IGFuIGl0ZXJhdG9yIG92ZXIgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIkdldCB0aGUgbmV4dCBpdGVtIGZyb20gdGhlIGZpbGUgaXRlcmF0b3IuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgaWYgbm90IHJlc3VsdDoKICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIHJldHVybiByZXN1bHQKCiNjbGFzcyBFeEZpbGVPYmplY3QKCiMtLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHBvcnRlZCBDbGFzc2VzCiMtLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgVGFySW5mbyhvYmplY3QpOgogICAgIiIiSW5mb3JtYXRpb25hbCBjbGFzcyB3aGljaCBob2xkcyB0aGUgZGV0YWlscyBhYm91dCBhbgogICAgICAgYXJjaGl2ZSBtZW1iZXIgZ2l2ZW4gYnkgYSB0YXIgaGVhZGVyIGJsb2NrLgogICAgICAgVGFySW5mbyBvYmplY3RzIGFyZSByZXR1cm5lZCBieSBUYXJGaWxlLmdldG1lbWJlcigpLAogICAgICAgVGFyRmlsZS5nZXRtZW1iZXJzKCkgYW5kIFRhckZpbGUuZ2V0dGFyaW5mbygpIGFuZCBhcmUKICAgICAgIHVzdWFsbHkgY3JlYXRlZCBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9IiIpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0LiBuYW1lIGlzIHRoZSBvcHRpb25hbCBuYW1lCiAgICAgICAgICAgb2YgdGhlIG1lbWJlci4KICAgICAgICAiIiIKCiAgICAgICAgc2VsZi5uYW1lID0gbmFtZSAgICAgICAgIyBtZW1iZXIgbmFtZSAoZGlybmFtZXMgbXVzdCBlbmQgd2l0aCAnLycpCiAgICAgICAgc2VsZi5tb2RlID0gMDY2NiAgICAgICAgIyBmaWxlIHBlcm1pc3Npb25zCiAgICAgICAgc2VsZi51aWQgPSAwICAgICAgICAgICAgIyB1c2VyIGlkCiAgICAgICAgc2VsZi5naWQgPSAwICAgICAgICAgICAgIyBncm91cCBpZAogICAgICAgIHNlbGYuc2l6ZSA9IDAgICAgICAgICAgICMgZmlsZSBzaXplCiAgICAgICAgc2VsZi5tdGltZSA9IDAgICAgICAgICAgIyBtb2RpZmljYXRpb24gdGltZQogICAgICAgIHNlbGYuY2hrc3VtID0gMCAgICAgICAgICMgaGVhZGVyIGNoZWNrc3VtCiAgICAgICAgc2VsZi50eXBlID0gUkVHVFlQRSAgICAgIyBtZW1iZXIgdHlwZQogICAgICAgIHNlbGYubGlua25hbWUgPSAiIiAgICAgICMgbGluayBuYW1lCiAgICAgICAgc2VsZi51bmFtZSA9ICJ1c2VyIiAgICAgIyB1c2VyIG5hbWUKICAgICAgICBzZWxmLmduYW1lID0gImdyb3VwIiAgICAjIGdyb3VwIG5hbWUKICAgICAgICBzZWxmLmRldm1ham9yID0gMCAgICAgICAjIGRldmljZSBtYWpvciBudW1iZXIKICAgICAgICBzZWxmLmRldm1pbm9yID0gMCAgICAgICAjIGRldmljZSBtaW5vciBudW1iZXIKICAgICAgICBzZWxmLnByZWZpeCA9ICIiICAgICAgICAjIHByZWZpeCB0byBmaWxlbmFtZSBvciBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWJvdXQgc3BhcnNlIGZpbGVzCgogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgIT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ0cnVuY2F0ZWQgaGVhZGVyIikKICAgICAgICBpZiBidWYuY291bnQoTlVMKSA9PSBCTE9DS1NJWkU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImVtcHR5IGhlYWRlciIpCgogICAgICAgIHRhcmluZm8gPSBjbHMoKQogICAgICAgIHRhcmluZm8uYnVmID0gYnVmCiAgICAgICAgdGFyaW5mby5uYW1lID0gYnVmWzA6MTAwXS5yc3RyaXAoTlVMKQogICAgICAgIHRhcmluZm8ubW9kZSA9IG50aShidWZbMTAwOjEwOF0pCiAgICAgICAgdGFyaW5mby51aWQgPSBudGkoYnVmWzEwODoxMTZdKQogICAgICAgIHRhcmluZm8uZ2lkID0gbnRpKGJ1ZlsxMTY6MTI0XSkKICAgICAgICB0YXJpbmZvLnNpemUgPSBudGkoYnVmWzEyNDoxMzZdKQogICAgICAgIHRhcmluZm8ubXRpbWUgPSBudGkoYnVmWzEzNjoxNDhdKQogICAgICAgIHRhcmluZm8uY2hrc3VtID0gbnRpKGJ1ZlsxNDg6MTU2XSkKICAgICAgICB0YXJpbmZvLnR5cGUgPSBidWZbMTU2OjE1N10KICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gYnVmWzE1NzoyNTddLnJzdHJpcChOVUwpCiAgICAgICAgdGFyaW5mby51bmFtZSA9IGJ1ZlsyNjU6Mjk3XS5yc3RyaXAoTlVMKQogICAgICAgIHRhcmluZm8uZ25hbWUgPSBidWZbMjk3OjMyOV0ucnN0cmlwKE5VTCkKICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkKICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gbnRpKGJ1ZlszMzc6MzQ1XSkKICAgICAgICB0YXJpbmZvLnByZWZpeCA9IGJ1ZlszNDU6NTAwXQoKICAgICAgICBpZiB0YXJpbmZvLmNoa3N1bSBub3QgaW4gY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImludmFsaWQgaGVhZGVyIikKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiB0b2J1ZihzZWxmLCBwb3NpeD1GYWxzZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgdGFyIGhlYWRlciBibG9jayBhcyBhIDUxMiBieXRlIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBwYXJ0cyA9IFsKICAgICAgICAgICAgc3RuKHNlbGYubmFtZSwgMTAwKSwKICAgICAgICAgICAgaXRuKHNlbGYubW9kZSAmIDA3Nzc3LCA4LCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLnVpZCwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5naWQsIDgsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYuc2l6ZSwgMTIsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYubXRpbWUsIDEyLCBwb3NpeCksCiAgICAgICAgICAgICIgICAgICAgICIsICMgY2hlY2tzdW0gZmllbGQKICAgICAgICAgICAgc2VsZi50eXBlLAogICAgICAgICAgICBzdG4oc2VsZi5saW5rbmFtZSwgMTAwKSwKICAgICAgICAgICAgc3RuKE1BR0lDLCA2KSwKICAgICAgICAgICAgc3RuKFZFUlNJT04sIDIpLAogICAgICAgICAgICBzdG4oc2VsZi51bmFtZSwgMzIpLAogICAgICAgICAgICBzdG4oc2VsZi5nbmFtZSwgMzIpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtYWpvciwgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi5kZXZtaW5vciwgOCwgcG9zaXgpLAogICAgICAgICAgICBzdG4oc2VsZi5wcmVmaXgsIDE1NSkKICAgICAgICBdCgogICAgICAgIGJ1ZiA9IHN0cnVjdC5wYWNrKCIlZHMiICUgQkxPQ0tTSVpFLCAiIi5qb2luKHBhcnRzKSkKICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bXMoYnVmKVswXQogICAgICAgIGJ1ZiA9IGJ1Zls6MTQ4XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWzE1NTpdCiAgICAgICAgc2VsZi5idWYgPSBidWYKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IEZhbHNlICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQogICAgICAgIHNlbGYuX21vZGUgPSBtb2RlCiAgICAgICAgc2VsZi5tb2RlID0geyJyIjogInJiIiwgImEiOiAicitiIiwgInciOiAid2IifVttb2RlXQoKICAgICAgICBpZiBub3QgZmlsZW9iajoKICAgICAgICAgICAgZmlsZW9iaiA9IGZpbGUoc2VsZi5uYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIHNlbGYubmFtZSBpcyBOb25lIGFuZCBoYXNhdHRyKGZpbGVvYmosICJuYW1lIik6CiAgICAgICAgICAgICAgICBzZWxmLm5hbWUgPSBmaWxlb2JqLm5hbWUKICAgICAgICAgICAgaWYgaGFzYXR0cihmaWxlb2JqLCAibW9kZSIpOgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgZGF0YXN0cnVjdHVyZXMKICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkCiAgICAgICAgc2VsZi5vZmZzZXQgPSAwTCAgICAgICAgIyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBhcmNoaXZlIGZpbGUKICAgICAgICBzZWxmLmlub2RlcyA9IHt9ICAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmNoaXZlIG1lbWJlcnMgYWxyZWFkeSBhZGRlZAoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IHNlbGYubmV4dCgpCgogICAgICAgIGlmIHNlbGYuX21vZGUgPT0gImEiOgogICAgICAgICAgICAjIE1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgYXJjaGl2ZSwKICAgICAgICAgICAgIyBiZWZvcmUgdGhlIGZpcnN0IGVtcHR5IGJsb2NrLgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLm5leHQoKQogICAgICAgICAgICAgICAgZXhjZXB0IFJlYWRFcnJvcjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygwKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoLSBCTE9DS1NJWkUsIDEpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgaWYgc2VsZi5fbW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgY2xhc3NtZXRob2RzIHdoaWNoIGFjdCBhcyBhbHRlcm5hdGUgY29uc3RydWN0b3JzIHRvIHRoZQogICAgIyBUYXJGaWxlIGNsYXNzLiBUaGUgb3BlbigpIG1ldGhvZCBpcyB0aGUgb25seSBvbmUgdGhhdCBpcyBuZWVkZWQgZm9yCiAgICAjIHB1YmxpYyB1c2U7IGl0IGlzIHRoZSAic3VwZXIiLWNvbnN0cnVjdG9yIGFuZCBpcyBhYmxlIHRvIHNlbGVjdCBhbgogICAgIyBhZGVxdWF0ZSAic3ViIi1jb25zdHJ1Y3RvciBmb3IgYSBwYXJ0aWN1bGFyIGNvbXByZXNzaW9uIHVzaW5nIHRoZSBtYXBwaW5nCiAgICAjIGZyb20gT1BFTl9NRVRILgogICAgIwogICAgIyBUaGlzIGNvbmNlcHQgYWxsb3dzIG9uZSB0byBzdWJjbGFzcyBUYXJGaWxlIHdpdGhvdXQgbG9zaW5nIHRoZSBjb21mb3J0IG9mCiAgICAjIHRoZSBzdXBlci1jb25zdHJ1Y3Rvci4gQSBzdWItY29uc3RydWN0b3IgaXMgcmVnaXN0ZXJlZCBhbmQgbWFkZSBhdmFpbGFibGUKICAgICMgYnkgYWRkaW5nIGl0IHRvIHRoZSBtYXBwaW5nIGluIE9QRU5fTUVUSC4KCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBvcGVuKGNscywgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBidWZzaXplPTIwKjUxMik6CiAgICAgICAgIiIiT3BlbiBhIHRhciBhcmNoaXZlIGZvciByZWFkaW5nLCB3cml0aW5nIG9yIGFwcGVuZGluZy4gUmV0dXJuCiAgICAgICAgICAgYW4gYXBwcm9wcmlhdGUgVGFyRmlsZSBjbGFzcy4KCiAgICAgICAgICAgbW9kZToKICAgICAgICAgICAncicgb3IgJ3I6Kicgb3BlbiBmb3IgcmVhZGluZyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6JyAgICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgZXhjbHVzaXZlbHkgdW5jb21wcmVzc2VkCiAgICAgICAgICAgJ3I6Z3onICAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3I6YnoyJyAgICAgIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgogICAgICAgICAgICdhJyBvciAnYTonICBvcGVuIGZvciBhcHBlbmRpbmcKICAgICAgICAgICAndycgb3IgJ3c6JyAgb3BlbiBmb3Igd3JpdGluZyB3aXRob3V0IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6Z3onICAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3c6YnoyJyAgICAgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aCBiemlwMiBjb21wcmVzc2lvbgoKICAgICAgICAgICAncnwqJyAgICAgICAgb3BlbiBhIHN0cmVhbSBvZiB0YXIgYmxvY2tzIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncnwnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MgZm9yIHJlYWRpbmcKICAgICAgICAgICAncnxneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICdyfGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcwogICAgICAgICAgICd3fCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xneicgICAgICAgb3BlbiBhIGd6aXAgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAgICAnd3xiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgIiIiCgogICAgICAgIGlmIG5vdCBuYW1lIGFuZCBub3QgZmlsZW9iajoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibm90aGluZyB0byBvcGVuIikKCiAgICAgICAgaWYgbW9kZSBpbiAoInIiLCAicjoqIik6CiAgICAgICAgICAgICMgRmluZCBvdXQgd2hpY2ggKm9wZW4oKSBpcyBhcHByb3ByaWF0ZSBmb3Igb3BlbmluZyB0aGUgZmlsZS4KICAgICAgICAgICAgZm9yIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsICJyIiwgZmlsZW9iaikKICAgICAgICAgICAgICAgIGV4Y2VwdCAoUmVhZEVycm9yLCBDb21wcmVzc2lvbkVycm9yKToKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaikKCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgifCIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgIGlmIGZpbGVtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwKICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50Z3oiOgogICAgICAgICAgICBleHQgPSAiLnRhciIKICAgICAgICBpZiBleHQgPT0gIi5neiI6CiAgICAgICAgICAgIGV4dCA9ICIiCiAgICAgICAgdGFybmFtZSA9IHByZSArIGV4dAoKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKG5hbWUsIG1vZGUgKyAiYiIpCgogICAgICAgIGlmIG1vZGUgIT0gInIiOgogICAgICAgICAgICBuYW1lID0gdGFybmFtZQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLAogICAgICAgICAgICAgICAgZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKQogICAgICAgICAgICApCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGJ6Mm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTkpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndycuIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBwcmUsIGV4dCA9IG9zLnBhdGguc3BsaXRleHQobmFtZSkKICAgICAgICBwcmUgPSBvcy5wYXRoLmJhc2VuYW1lKHByZSkKICAgICAgICBpZiBleHQgPT0gIi50YnoyIjoKICAgICAgICAgICAgZXh0ID0gIi50YXIiCiAgICAgICAgaWYgZXh0ID09ICIuYnoyIjoKICAgICAgICAgICAgZXh0ID0gIiIKICAgICAgICB0YXJuYW1lID0gcHJlICsgZXh0CgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBfQloyUHJveHkoZmlsZW9iaiwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlb2JqID0gYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHQgPSBjbHMudGFyb3Blbih0YXJuYW1lLCBtb2RlLCBmaWxlb2JqKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGJ6aXAyIGZpbGUiKQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgIyBBbGwgKm9wZW4oKSBtZXRob2RzIGFyZSByZWdpc3RlcmVkIGhlcmUuCiAgICBPUEVOX01FVEggPSB7CiAgICAgICAgInRhciI6ICJ0YXJvcGVuIiwgICAjIHVuY29tcHJlc3NlZCB0YXIKICAgICAgICAiZ3oiOiAgImd6b3BlbiIsICAgICMgZ3ppcCBjb21wcmVzc2VkIHRhcgogICAgICAgICJiejIiOiAiYnoyb3BlbiIgICAgIyBiemlwMiBjb21wcmVzc2VkIHRhcgogICAgfQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgcHVibGljIG1ldGhvZHMgd2hpY2ggVGFyRmlsZSBwcm92aWRlczoKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIFRhckZpbGUuIEluIHdyaXRlLW1vZGUsIHR3byBmaW5pc2hpbmcgemVybyBibG9ja3MgYXJlCiAgICAgICAgICAgYXBwZW5kZWQgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiBzZWxmLl9tb2RlIGluICJhdyI6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFICogMikpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IChCTE9DS1NJWkUgKiAyKQogICAgICAgICAgICAjIGZpbGwgdXAgdGhlIGVuZCB3aXRoIHplcm8tYmxvY2tzCiAgICAgICAgICAgICMgKGxpa2Ugb3B0aW9uIC1iMjAgZm9yIHRhciBkb2VzKQogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChzZWxmLm9mZnNldCwgUkVDT1JEU0laRSkKICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoUkVDT1JEU0laRSAtIHJlbWFpbmRlcikpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBnZXRtZW1iZXIoc2VsZiwgbmFtZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgVGFySW5mbyBvYmplY3QgZm9yIG1lbWJlciBgbmFtZScuIElmIGBuYW1lJyBjYW4gbm90IGJlCiAgICAgICAgICAgZm91bmQgaW4gdGhlIGFyY2hpdmUsIEtleUVycm9yIGlzIHJhaXNlZC4gSWYgYSBtZW1iZXIgb2NjdXJzIG1vcmUKICAgICAgICAgICB0aGFuIG9uY2UgaW4gdGhlIGFyY2hpdmUsIGl0cyBsYXN0IG9jY3VyZW5jZSBpcyBhc3N1bWVkIHRvIGJlIHRoZQogICAgICAgICAgIG1vc3QgdXAtdG8tZGF0ZSB2ZXJzaW9uLgogICAgICAgICIiIgogICAgICAgIHRhcmluZm8gPSBzZWxmLl9nZXRtZW1iZXIobmFtZSkKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIEtleUVycm9yKCJmaWxlbmFtZSAlciBub3QgZm91bmQiICUgbmFtZSkKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiBnZXRtZW1iZXJzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgVGFySW5mbyBvYmplY3RzLiBUaGUKICAgICAgICAgICBsaXN0IGhhcyB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbWVtYmVycyBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygpCiAgICAgICAgaWYgbm90IHNlbGYuX2xvYWRlZDogICAgIyBpZiB3ZSB3YW50IHRvIG9idGFpbiBhIGxpc3Qgb2YKICAgICAgICAgICAgc2VsZi5fbG9hZCgpICAgICAgICAjIGFsbCBtZW1iZXJzLCB3ZSBmaXJzdCBoYXZlIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzY2FuIHRoZSB3aG9sZSBhcmNoaXZlLgogICAgICAgIHJldHVybiBzZWxmLm1lbWJlcnMKCiAgICBkZWYgZ2V0bmFtZXMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiB0aGVpciBuYW1lcy4gSXQgaGFzCiAgICAgICAgICAgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBbdGFyaW5mby5uYW1lIGZvciB0YXJpbmZvIGluIHNlbGYuZ2V0bWVtYmVycygpXQoKICAgIGRlZiBnZXR0YXJpbmZvKHNlbGYsIG5hbWU9Tm9uZSwgYXJjbmFtZT1Ob25lLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIkNyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZvciBlaXRoZXIgdGhlIGZpbGUgYG5hbWUnIG9yIHRoZSBmaWxlCiAgICAgICAgICAgb2JqZWN0IGBmaWxlb2JqJyAodXNpbmcgb3MuZnN0YXQgb24gaXRzIGZpbGUgZGVzY3JpcHRvcikuIFlvdSBjYW4KICAgICAgICAgICBtb2RpZnkgc29tZSBvZiB0aGUgVGFySW5mbydzIGF0dHJpYnV0ZXMgYmVmb3JlIHlvdSBhZGQgaXQgdXNpbmcKICAgICAgICAgICBhZGRmaWxlKCkuIElmIGdpdmVuLCBgYXJjbmFtZScgc3BlY2lmaWVzIGFuIGFsdGVybmF0aXZlIG5hbWUgZm9yIHRoZQogICAgICAgICAgIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgIyBXaGVuIGZpbGVvYmogaXMgZ2l2ZW4sIHJlcGxhY2UgbmFtZSBieQogICAgICAgICMgZmlsZW9iaidzIHJlYWwgbmFtZS4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBuYW1lID0gZmlsZW9iai5uYW1lCgogICAgICAgICMgQnVpbGRpbmcgdGhlIG5hbWUgb2YgdGhlIG1lbWJlciBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAjIEJhY2t3YXJkIHNsYXNoZXMgYXJlIGNvbnZlcnRlZCB0byBmb3J3YXJkIHNsYXNoZXMsCiAgICAgICAgIyBBYnNvbHV0ZSBwYXRocyBhcmUgdHVybmVkIHRvIHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKICAgICAgICBhcmNuYW1lID0gbm9ybXBhdGgoYXJjbmFtZSkKICAgICAgICBkcnYsIGFyY25hbWUgPSBvcy5wYXRoLnNwbGl0ZHJpdmUoYXJjbmFtZSkKICAgICAgICB3aGlsZSBhcmNuYW1lWzA6MV0gPT0gIi8iOgogICAgICAgICAgICBhcmNuYW1lID0gYXJjbmFtZVsxOl0KCiAgICAgICAgIyBOb3csIGZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGgKICAgICAgICAjIGluZm9ybWF0aW9uIHNwZWNpZmljIGZvciB0aGUgZmlsZS4KICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCgogICAgICAgICMgVXNlIG9zLnN0YXQgb3Igb3MubHN0YXQsIGRlcGVuZGluZyBvbiBwbGF0Zm9ybQogICAgICAgICMgYW5kIGlmIHN5bWxpbmtzIHNoYWxsIGJlIHJlc29sdmVkLgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgImxzdGF0IikgYW5kIG5vdCBzZWxmLmRlcmVmZXJlbmNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmxzdGF0KG5hbWUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3Muc3RhdChuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5mc3RhdChmaWxlb2JqLmZpbGVubygpKQogICAgICAgIGxpbmtuYW1lID0gIiIKCiAgICAgICAgc3RtZCA9IHN0YXRyZXMuc3RfbW9kZQogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgaW5vZGUgPSAoc3RhdHJlcy5zdF9pbm8sIHN0YXRyZXMuc3RfZGV2KQogICAgICAgICAgICBpZiBub3Qgc2VsZi5kZXJlZmVyZW5jZSBhbmQgXAogICAgICAgICAgICAgICAgICAgIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBpbm9kZSBpbiBzZWxmLmlub2RlczoKICAgICAgICAgICAgICAgICMgSXMgaXQgYSBoYXJkbGluayB0byBhbiBhbHJlYWR5CiAgICAgICAgICAgICAgICAjIGFyY2hpdmVkIGZpbGU/CiAgICAgICAgICAgICAgICB0eXBlID0gTE5LVFlQRQogICAgICAgICAgICAgICAgbGlua25hbWUgPSBzZWxmLmlub2Rlc1tpbm9kZV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgVGhlIGlub2RlIGlzIGFkZGVkIG9ubHkgaWYgaXRzIHZhbGlkLgogICAgICAgICAgICAgICAgIyBGb3Igd2luMzIgaXQgaXMgYWx3YXlzIDAuCiAgICAgICAgICAgICAgICB0eXBlID0gUkVHVFlQRQogICAgICAgICAgICAgICAgaWYgaW5vZGVbMF06CiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbm9kZXNbaW5vZGVdID0gYXJjbmFtZQogICAgICAgIGVsaWYgc3RhdC5TX0lTRElSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQogICAgICAgICAgICBpZiBhcmNuYW1lWy0xOl0gIT0gIi8iOgogICAgICAgICAgICAgICAgYXJjbmFtZSArPSAiLyIKICAgICAgICBlbGlmIHN0YXQuU19JU0ZJRk8oc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBGSUZPVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTTE5LKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gU1lNVFlQRQogICAgICAgICAgICBsaW5rbmFtZSA9IG9zLnJlYWRsaW5rKG5hbWUpCiAgICAgICAgZWxpZiBzdGF0LlNfSVNDSFIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBDSFJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNCTEsoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBCTEtUWVBFCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgIyBGaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoIGFsbAogICAgICAgICMgaW5mb3JtYXRpb24gd2UgY2FuIGdldC4KICAgICAgICB0YXJpbmZvLm5hbWUgPSBhcmNuYW1lCiAgICAgICAgdGFyaW5mby5tb2RlID0gc3RtZAogICAgICAgIHRhcmluZm8udWlkID0gc3RhdHJlcy5zdF91aWQKICAgICAgICB0YXJpbmZvLmdpZCA9IHN0YXRyZXMuc3RfZ2lkCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSBzdGF0cmVzLnN0X3NpemUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvLnNpemUgPSAwTAogICAgICAgIHRhcmluZm8ubXRpbWUgPSBzdGF0cmVzLnN0X210aW1lCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBsaW5rbmFtZQogICAgICAgIGlmIHB3ZDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIGlmIGdycDoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMF0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFKToKICAgICAgICAgICAgaWYgaGFzYXR0cihvcywgIm1ham9yIikgYW5kIGhhc2F0dHIob3MsICJtaW5vciIpOgogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IG9zLm1ham9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBvcy5taW5vcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgbGlzdChzZWxmLCB2ZXJib3NlPVRydWUpOgogICAgICAgICIiIlByaW50IGEgdGFibGUgb2YgY29udGVudHMgdG8gc3lzLnN0ZG91dC4gSWYgYHZlcmJvc2UnIGlzIEZhbHNlLCBvbmx5CiAgICAgICAgICAgdGhlIG5hbWVzIG9mIHRoZSBtZW1iZXJzIGFyZSBwcmludGVkLiBJZiBpdCBpcyBUcnVlLCBhbiBgbHMgLWwnLWxpa2UKICAgICAgICAgICBvdXRwdXQgaXMgcHJvZHVjZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBzZWxmOgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgZmlsZW1vZGUodGFyaW5mby5tb2RlKSwKICAgICAgICAgICAgICAgIHByaW50ICIlcy8lcyIgJSAodGFyaW5mby51bmFtZSBvciB0YXJpbmZvLnVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5nbmFtZSBvciB0YXJpbmZvLmdpZCksCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBzIiAlICgiJWQsJWQiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpLAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwZCIgJSB0YXJpbmZvLnNpemUsCiAgICAgICAgICAgICAgICBwcmludCAiJWQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkIiBcCiAgICAgICAgICAgICAgICAgICAgICAlIHRpbWUubG9jYWx0aW1lKHRhcmluZm8ubXRpbWUpWzo2XSwKCiAgICAgICAgICAgIHByaW50IHRhcmluZm8ubmFtZSwKCiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAibGluayB0byIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgIHByaW50CgogICAgZGVmIGFkZChzZWxmLCBuYW1lLCBhcmNuYW1lPU5vbmUsIHJlY3Vyc2l2ZT1UcnVlKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQoKICAgICAgICAjIFNraXAgaWYgc29tZWJvZHkgdHJpZXMgdG8gYXJjaGl2ZSB0aGUgYXJjaGl2ZS4uLgogICAgICAgIGlmIHNlbGYubmFtZSBpcyBub3QgTm9uZSBcCiAgICAgICAgICAgIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gb3MucGF0aC5hYnNwYXRoKHNlbGYubmFtZSk6CiAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogU2tpcHBlZCAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBTcGVjaWFsIGNhc2U6IFRoZSB1c2VyIHdhbnRzIHRvIGFkZCB0aGUgY3VycmVudAogICAgICAgICMgd29ya2luZyBkaXJlY3RvcnkuCiAgICAgICAgaWYgbmFtZSA9PSAiLiI6CiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGlmIGFyY25hbWUgPT0gIi4iOgogICAgICAgICAgICAgICAgICAgIGFyY25hbWUgPSAiIgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcigiLiIpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKGYsIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNlbGYuX2RiZygxLCBuYW1lKQoKICAgICAgICAjIENyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0dGFyaW5mbyhuYW1lLCBhcmNuYW1lKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5zdXBwb3J0ZWQgdHlwZSAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBBcHBlbmQgdGhlIHRhciBoZWFkZXIgYW5kIGRhdGEgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBmID0gZmlsZShuYW1lLCAicmIiKQogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKICAgICAgICAgICAgZi5jbG9zZSgpCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbykKICAgICAgICAgICAgaWYgcmVjdXJzaXZlOgogICAgICAgICAgICAgICAgZm9yIGYgaW4gb3MubGlzdGRpcihuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChvcy5wYXRoLmpvaW4obmFtZSwgZiksIG9zLnBhdGguam9pbihhcmNuYW1lLCBmKSkKCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCgogICAgZGVmIGFkZGZpbGUoc2VsZiwgdGFyaW5mbywgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIFRhckluZm8gb2JqZWN0IGB0YXJpbmZvJyB0byB0aGUgYXJjaGl2ZS4gSWYgYGZpbGVvYmonIGlzCiAgICAgICAgICAgZ2l2ZW4sIHRhcmluZm8uc2l6ZSBieXRlcyBhcmUgcmVhZCBmcm9tIGl0IGFuZCBhZGRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBZb3UgY2FuIGNyZWF0ZSBUYXJJbmZvIG9iamVjdHMgdXNpbmcgZ2V0dGFyaW5mbygpLgogICAgICAgICAgIE9uIFdpbmRvd3MgcGxhdGZvcm1zLCBgZmlsZW9iaicgc2hvdWxkIGFsd2F5cyBiZSBvcGVuZWQgd2l0aCBtb2RlCiAgICAgICAgICAgJ3JiJyB0byBhdm9pZCBpcnJpdGF0aW9uIGFib3V0IHRoZSBmaWxlIHNpemUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soImF3IikKCiAgICAgICAgdGFyaW5mby5uYW1lID0gbm9ybXBhdGgodGFyaW5mby5uYW1lKQogICAgICAgIGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgIyBkaXJlY3RvcmllcyBzaG91bGQgZW5kIHdpdGggJy8nCiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKCiAgICAgICAgaWYgdGFyaW5mby5saW5rbmFtZToKICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IG5vcm1wYXRoKHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIGlmIHRhcmluZm8uc2l6ZSA+IE1BWFNJWkVfTUVNQkVSOgogICAgICAgICAgICBpZiBzZWxmLnBvc2l4OgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiZmlsZSBpcyB0b28gbGFyZ2UgKD49IDggR0IpIikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGxhcmdlZmlsZSBoZWFkZXIiKQoKCiAgICAgICAgaWYgbGVuKHRhcmluZm8ubGlua25hbWUpID4gTEVOR1RIX0xJTks6CiAgICAgICAgICAgIGlmIHNlbGYucG9zaXg6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJsaW5rbmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgJSAoTEVOR1RIX0xJTkspKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fY3JlYXRlX2dudWxvbmcodGFyaW5mby5saW5rbmFtZSwgR05VVFlQRV9MT05HTElOSykKICAgICAgICAgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSB0YXJpbmZvLmxpbmtuYW1lWzpMRU5HVEhfTElOSyAtMV0KICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTElOSyIpCgogICAgICAgIGlmIGxlbih0YXJpbmZvLm5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgIGlmIHNlbGYucG9zaXg6CiAgICAgICAgICAgICAgICBwcmVmaXggPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9QUkVGSVggKyAxXQogICAgICAgICAgICAgICAgd2hpbGUgcHJlZml4IGFuZCBwcmVmaXhbLTFdICE9ICIvIjoKICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICAgICAgICAgIG5hbWUgPSB0YXJpbmZvLm5hbWVbbGVuKHByZWZpeCk6XQogICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBpZiBub3QgcHJlZml4IG9yIGxlbihuYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5hbWUgaXMgdG9vIGxvbmcgKD4lZCkiICUgKExFTkdUSF9OQU1FKSkKCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgICA9IG5hbWUKICAgICAgICAgICAgICAgIHRhcmluZm8ucHJlZml4ID0gcHJlZml4CiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9jcmVhdGVfZ251bG9uZyh0YXJpbmZvLm5hbWUsIEdOVVRZUEVfTE9OR05BTUUpCiAgICAgICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSB0YXJpbmZvLm5hbWVbOkxFTkdUSF9OQU1FIC0gMV0KICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogQ3JlYXRlZCBHTlUgdGFyIGV4dGVuc2lvbiBMT05HTkFNRSIpCgogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZSh0YXJpbmZvLnRvYnVmKHNlbGYucG9zaXgpKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQoKICAgICAgICAjIElmIHRoZXJlJ3MgZGF0YSB0byBmb2xsb3csIGFwcGVuZCBpdC4KICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lOgogICAgICAgICAgICBjb3B5ZmlsZW9iaihmaWxlb2JqLCBzZWxmLmZpbGVvYmosIHRhcmluZm8uc2l6ZSkKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QodGFyaW5mby5zaXplLCBCTE9DS1NJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCiAgICAgICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQoKICAgIGRlZiBleHRyYWN0YWxsKHNlbGYsIHBhdGg9Ii4iLCBtZW1iZXJzPU5vbmUpOgogICAgICAgICIiIkV4dHJhY3QgYWxsIG1lbWJlcnMgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nCiAgICAgICAgICAgZGlyZWN0b3J5IGFuZCBzZXQgb3duZXIsIG1vZGlmaWNhdGlvbiB0aW1lIGFuZCBwZXJtaXNzaW9ucyBvbgogICAgICAgICAgIGRpcmVjdG9yaWVzIGFmdGVyd2FyZHMuIGBwYXRoJyBzcGVjaWZpZXMgYSBkaWZmZXJlbnQgZGlyZWN0b3J5CiAgICAgICAgICAgdG8gZXh0cmFjdCB0by4gYG1lbWJlcnMnIGlzIG9wdGlvbmFsIGFuZCBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZQogICAgICAgICAgIGxpc3QgcmV0dXJuZWQgYnkgZ2V0bWVtYmVycygpLgogICAgICAgICIiIgogICAgICAgIGRpcmVjdG9yaWVzID0gW10KCiAgICAgICAgaWYgbWVtYmVycyBpcyBOb25lOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZgoKICAgICAgICBmb3IgdGFyaW5mbyBpbiBtZW1iZXJzOgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICAgICAjIEV4dHJhY3QgZGlyZWN0b3J5IHdpdGggYSBzYWZlIG1vZGUsIHNvIHRoYXQKICAgICAgICAgICAgICAgICMgYWxsIGZpbGVzIGJlbG93IGNhbiBiZSBleHRyYWN0ZWQgYXMgd2VsbC4KICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvcy5tYWtlZGlycyhvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKSwgMDc3NykKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yOgogICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgIGRpcmVjdG9yaWVzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5leHRyYWN0KHRhcmluZm8sIHBhdGgpCgogICAgICAgICMgUmV2ZXJzZSBzb3J0IGRpcmVjdG9yaWVzLgogICAgICAgIGRpcmVjdG9yaWVzLnNvcnQobGFtYmRhIGEsIGI6IGNtcChhLm5hbWUsIGIubmFtZSkpCiAgICAgICAgZGlyZWN0b3JpZXMucmV2ZXJzZSgpCgogICAgICAgICMgU2V0IGNvcnJlY3Qgb3duZXIsIG10aW1lIGFuZCBmaWxlbW9kZSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICBmb3IgdGFyaW5mbyBpbiBkaXJlY3RvcmllczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgcGF0aCkKICAgICAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0KHNlbGYsIG1lbWJlciwgcGF0aD0iIik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIHRvIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LAogICAgICAgICAgIHVzaW5nIGl0cyBmdWxsIG5hbWUuIEl0cyBmaWxlIGluZm9ybWF0aW9uIGlzIGV4dHJhY3RlZCBhcyBhY2N1cmF0ZWx5CiAgICAgICAgICAgYXMgcG9zc2libGUuIGBtZW1iZXInIG1heSBiZSBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIFlvdSBjYW4KICAgICAgICAgICBzcGVjaWZ5IGEgZGlmZmVyZW50IGRpcmVjdG9yeSB1c2luZyBgcGF0aCcuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgVGFySW5mbyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBtZW1iZXIKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5nZXRtZW1iZXIobWVtYmVyKQoKICAgICAgICAjIFByZXBhcmUgdGhlIGxpbmsgdGFyZ2V0IGZvciBtYWtlbGluaygpLgogICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgdGFyaW5mby5fbGlua190YXJnZXQgPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5saW5rbmFtZSkKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0YXJpbmZvLCBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKSkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMDoKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBlLmZpbGVuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlLnN0cmVycm9yKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzICVyIiAlIChlLnN0cmVycm9yLCBlLmZpbGVuYW1lKSkKICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yLCBlOgogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdGZpbGUoc2VsZiwgbWVtYmVyKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgYXMgYSBmaWxlIG9iamVjdC4gYG1lbWJlcicgbWF5IGJlCiAgICAgICAgICAgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBJZiBgbWVtYmVyJyBpcyBhIHJlZ3VsYXIgZmlsZSwgYQogICAgICAgICAgIGZpbGUtbGlrZSBvYmplY3QgaXMgcmV0dXJuZWQuIElmIGBtZW1iZXInIGlzIGEgbGluaywgYSBmaWxlLWxpa2UKICAgICAgICAgICBvYmplY3QgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgbGluaydzIHRhcmdldC4gSWYgYG1lbWJlcicgaXMgbm9uZSBvZgogICAgICAgICAgIHRoZSBhYm92ZSwgTm9uZSBpcyByZXR1cm5lZC4KICAgICAgICAgICBUaGUgZmlsZS1saWtlIG9iamVjdCBpcyByZWFkLW9ubHkgYW5kIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcKICAgICAgICAgICBtZXRob2RzOiByZWFkKCksIHJlYWRsaW5lKCksIHJlYWRsaW5lcygpLCBzZWVrKCkgYW5kIHRlbGwoKQogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIFRhckluZm8pOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgSWYgYSBtZW1iZXIncyB0eXBlIGlzIHVua25vd24sIGl0IGlzIHRyZWF0ZWQgYXMgYQogICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZS4KICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5maWxlb2JqLCBfU3RyZWFtKToKICAgICAgICAgICAgICAgICMgQSBzbWFsbCBidXQgdWdseSB3b3JrYXJvdW5kIGZvciB0aGUgY2FzZSB0aGF0IHNvbWVvbmUgdHJpZXMKICAgICAgICAgICAgICAgICMgdG8gZXh0cmFjdCBhIChzeW0pbGluayBhcyBhIGZpbGUtb2JqZWN0IGZyb20gYSBub24tc2Vla2FibGUKICAgICAgICAgICAgICAgICMgc3RyZWFtIG9mIHRhciBibG9ja3MuCiAgICAgICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvcigiY2Fubm90IGV4dHJhY3QgKHN5bSlsaW5rIGFzIGZpbGUgb2JqZWN0IikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICMgQSAoc3ltKWxpbmsncyBmaWxlIG9iamVjdCBpcyBpdHMgdGFyZ2V0J3MgZmlsZSBvYmplY3QuCiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5leHRyYWN0ZmlsZShzZWxmLl9nZXRtZW1iZXIodGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIElmIHRoZXJlJ3Mgbm8gZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIG1lbWJlciAoZGlyZWN0b3J5LCBjaHJkZXYsCiAgICAgICAgICAgICMgYmxrZGV2LCBldGMuKSwgcmV0dXJuIE5vbmUgaW5zdGVhZCBvZiBhIGZpbGUgb2JqZWN0LgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBfZXh0cmFjdF9tZW1iZXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiRXh0cmFjdCB0aGUgVGFySW5mbyBvYmplY3QgdGFyaW5mbyB0byBhIHBoeXNpY2FsCiAgICAgICAgICAgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICAjIEZldGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmb3IgdGhlIGdpdmVuIG5hbWUKICAgICAgICAjIGFuZCBidWlsZCB0aGUgZGVzdGluYXRpb24gcGF0aG5hbWUsIHJlcGxhY2luZwogICAgICAgICMgZm9yd2FyZCBzbGFzaGVzIHRvIHBsYXRmb3JtIHNwZWNpZmljIHNlcGFyYXRvcnMuCiAgICAgICAgaWYgdGFyZ2V0cGF0aFstMTpdID09ICIvIjoKICAgICAgICAgICAgdGFyZ2V0cGF0aCA9IHRhcmdldHBhdGhbOi0xXQogICAgICAgIHRhcmdldHBhdGggPSBvcy5wYXRoLm5vcm1wYXRoKHRhcmdldHBhdGgpCgogICAgICAgICMgQ3JlYXRlIGFsbCB1cHBlciBkaXJlY3Rvcmllcy4KICAgICAgICB1cHBlcmRpcnMgPSBvcy5wYXRoLmRpcm5hbWUodGFyZ2V0cGF0aCkKICAgICAgICBpZiB1cHBlcmRpcnMgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyh1cHBlcmRpcnMpOgogICAgICAgICAgICB0aSA9IFRhckluZm8oKQogICAgICAgICAgICB0aS5uYW1lICA9IHVwcGVyZGlycwogICAgICAgICAgICB0aS50eXBlICA9IERJUlRZUEUKICAgICAgICAgICAgdGkubW9kZSAgPSAwNzc3CiAgICAgICAgICAgIHRpLm10aW1lID0gdGFyaW5mby5tdGltZQogICAgICAgICAgICB0aS51aWQgICA9IHRhcmluZm8udWlkCiAgICAgICAgICAgIHRpLmdpZCAgID0gdGFyaW5mby5naWQKICAgICAgICAgICAgdGkudW5hbWUgPSB0YXJpbmZvLnVuYW1lCiAgICAgICAgICAgIHRpLmduYW1lID0gdGFyaW5mby5nbmFtZQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcih0aSwgdGkubmFtZSkKICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgIiVzIC0+ICVzIiAlICh0YXJpbmZvLm5hbWUsIHRhcmluZm8ubGlua25hbWUpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCB0YXJpbmZvLm5hbWUpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICBzZWxmLm1ha2VkaXIodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNmaWZvKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpZm8odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRldih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5tYWtlbGluayh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgIHNlbGYubWFrZXVua25vd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgICAgIHNlbGYuY2hvd24odGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBpZiBub3QgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgICAgIHNlbGYudXRpbWUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBkaWZmZXJlbnQgZmlsZSBtZXRob2RzLiBUaGV5IGFyZSBjYWxsZWQgdmlhCiAgICAjIF9leHRyYWN0X21lbWJlcigpIHdoZW4gZXh0cmFjdCgpIGlzIGNhbGxlZC4gVGhleSBjYW4gYmUgcmVwbGFjZWQgaW4gYQogICAgIyBzdWJjbGFzcyB0byBpbXBsZW1lbnQgb3RoZXIgZnVuY3Rpb25hbGl0eS4KCiAgICBkZWYgbWFrZWRpcihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZGlyZWN0b3J5IGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MubWtkaXIodGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdGFyZ2V0ID0gZmlsZSh0YXJnZXRwYXRoLCAid2IiKQogICAgICAgIGNvcHlmaWxlb2JqKHNvdXJjZSwgdGFyZ2V0KQogICAgICAgIHNvdXJjZS5jbG9zZSgpCiAgICAgICAgdGFyZ2V0LmNsb3NlKCkKCiAgICBkZWYgbWFrZXVua25vd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpbGUgZnJvbSBhIFRhckluZm8gb2JqZWN0IHdpdGggYW4gdW5rbm93biB0eXBlCiAgICAgICAgICAgYXQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiBVbmtub3duIGZpbGUgdHlwZSAlciwgIiBcCiAgICAgICAgICAgICAgICAgICAgICJleHRyYWN0ZWQgYXMgcmVndWxhciBmaWxlLiIgJSB0YXJpbmZvLnR5cGUpCgogICAgZGVmIG1ha2VmaWZvKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWZvIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICJta2ZpZm8iKToKICAgICAgICAgICAgb3MubWtmaWZvKHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJmaWZvIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIikKCiAgICBkZWYgbWFrZWRldihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgY2hhcmFjdGVyIG9yIGJsb2NrIGRldmljZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgIm1rbm9kIikgb3Igbm90IGhhc2F0dHIob3MsICJtYWtlZGV2Iik6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigic3BlY2lhbCBkZXZpY2VzIG5vdCBzdXBwb3J0ZWQgYnkgc3lzdGVtIikKCiAgICAgICAgbW9kZSA9IHRhcmluZm8ubW9kZQogICAgICAgIGlmIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZCTEsKICAgICAgICBlbHNlOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkNIUgoKICAgICAgICBvcy5ta25vZCh0YXJnZXRwYXRoLCBtb2RlLAogICAgICAgICAgICAgICAgIG9zLm1ha2VkZXYodGFyaW5mby5kZXZtYWpvciwgdGFyaW5mby5kZXZtaW5vcikpCgogICAgZGVmIG1ha2VsaW5rKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSAoc3ltYm9saWMpIGxpbmsgY2FsbGVkIHRhcmdldHBhdGguIElmIGl0IGNhbm5vdCBiZSBjcmVhdGVkCiAgICAgICAgICAocGxhdGZvcm0gbGltaXRhdGlvbiksIHdlIHRyeSB0byBtYWtlIGEgY29weSBvZiB0aGUgcmVmZXJlbmNlZCBmaWxlCiAgICAgICAgICBpbnN0ZWFkIG9mIGEgbGluay4KICAgICAgICAiIiIKICAgICAgICBsaW5rcGF0aCA9IHRhcmluZm8ubGlua25hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIG9zLnN5bWxpbmsobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFNlZSBleHRyYWN0KCkuCiAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5kaXJuYW1lKHRhcmluZm8ubmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rcGF0aCkKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gbm9ybXBhdGgobGlua3BhdGgpCgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcihzZWxmLmdldG1lbWJlcihsaW5rcGF0aCksIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCAoRW52aXJvbm1lbnRFcnJvciwgS2V5RXJyb3IpLCBlOgogICAgICAgICAgICAgICAgbGlua3BhdGggPSBvcy5wYXRoLm5vcm1wYXRoKGxpbmtwYXRoKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHNodXRpbC5jb3B5MihsaW5rcGF0aCwgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQiKQoKICAgIGRlZiBjaG93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgb3duZXIgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBwd2QgYW5kIGhhc2F0dHIob3MsICJnZXRldWlkIikgYW5kIG9zLmdldGV1aWQoKSA9PSAwOgogICAgICAgICAgICAjIFdlIGhhdmUgdG8gYmUgcm9vdCB0byBkbyBzby4KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncm5hbSh0YXJpbmZvLmduYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgZyA9IGdycC5nZXRncmdpZCh0YXJpbmZvLmdpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICBnID0gb3MuZ2V0Z2lkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd25hbSh0YXJpbmZvLnVuYW1lKVsyXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdSA9IHB3ZC5nZXRwd3VpZCh0YXJpbmZvLnVpZClbMl0KICAgICAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgICAgICB1ID0gb3MuZ2V0dWlkKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpIGFuZCBoYXNhdHRyKG9zLCAibGNob3duIik6CiAgICAgICAgICAgICAgICAgICAgb3MubGNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAib3MyZW14IjoKICAgICAgICAgICAgICAgICAgICAgICAgb3MuY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2Ugb3duZXIiKQoKICAgIGRlZiBjaG1vZChzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgZmlsZSBwZXJtaXNzaW9ucyBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICdjaG1vZCcpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvcy5jaG1vZCh0YXJnZXRwYXRoLCB0YXJpbmZvLm1vZGUpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG1vZGUiKQoKICAgIGRlZiB1dGltZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJTZXQgbW9kaWZpY2F0aW9uIHRpbWUgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBub3QgaGFzYXR0cihvcywgJ3V0aW1lJyk6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiIGFuZCB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICMgQWNjb3JkaW5nIHRvIG1zZG4ubWljcm9zb2Z0LmNvbSwgaXQgaXMgYW4gZXJyb3IgKEVBQ0NFUykKICAgICAgICAgICAgIyB0byB1c2UgdXRpbWUoKSBvbiBkaXJlY3Rvcmllcy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgbWVtYmVyIG9mIHRoZSBhcmNoaXZlIGFzIGEgVGFySW5mbyBvYmplY3QsIHdoZW4KICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQogICAgICAgICAgIGF2YWlsYWJsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygicmEiKQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG0gPSBzZWxmLmZpcnN0bWVtYmVyCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBtCgogICAgICAgICMgUmVhZCB0aGUgbmV4dCBibG9jay4KICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IFRhckluZm8uZnJvbWJ1ZihidWYpCgogICAgICAgICAgICAgICAgIyBTZXQgdGhlIFRhckluZm8gb2JqZWN0J3Mgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZQogICAgICAgICAgICAgICAgIyBUYXJGaWxlIGFuZCBzZXQgc2VsZi5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcwogICAgICAgICAgICAgICAgIyBzaG91bGQgYmVnaW4uCiAgICAgICAgICAgICAgICB0YXJpbmZvLm9mZnNldCA9IHNlbGYub2Zmc2V0CiAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKCiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5wcm9jX21lbWJlcih0YXJpbmZvKQoKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmlnbm9yZV96ZXJvczoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgIjB4JVg6IGVtcHR5IG9yIGludmFsaWQgYmxvY2s6ICVzIiAlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxmLm9mZnNldCwgZSkpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgc2VsZi5vZmZzZXQgPT0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJlbXB0eSwgdW5yZWFkYWJsZSBvciBjb21wcmVzc2VkICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWxlOiAlcyIgJSBlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgICMgU29tZSBvbGQgdGFyIHByb2dyYW1zIHJlcHJlc2VudCBhIGRpcmVjdG9yeSBhcyBhIHJlZ3VsYXIKICAgICAgICAjIGZpbGUgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKSBhbmQgdGFyaW5mby5uYW1lLmVuZHN3aXRoKCIvIik6CiAgICAgICAgICAgIHRhcmluZm8udHlwZSA9IERJUlRZUEUKCiAgICAgICAgIyBUaGUgcHJlZml4IGZpZWxkIGlzIHVzZWQgZm9yIGZpbGVuYW1lcyA+IDEwMCBpbgogICAgICAgICMgdGhlIFBPU0lYIHN0YW5kYXJkLgogICAgICAgICMgbmFtZSA9IHByZWZpeCArICcvJyArIG5hbWUKICAgICAgICB0YXJpbmZvLm5hbWUgPSBub3JtcGF0aChvcy5wYXRoLmpvaW4odGFyaW5mby5wcmVmaXgucnN0cmlwKE5VTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8ubmFtZSkpCgogICAgICAgICMgRGlyZWN0b3J5IG5hbWVzIHNob3VsZCBoYXZlIGEgJy8nIGF0IHRoZSBlbmQuCiAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgKz0gIi8iCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBUaGUgZm9sbG93aW5nIGFyZSBtZXRob2RzIHRoYXQgYXJlIGNhbGxlZCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgYQogICAgIyBtZW1iZXIuIFRoZSBlbnRyeSBwb2ludCBpcyBwcm9jX21lbWJlcigpIHdoaWNoIGlzIGNhbGxlZCB3aXRoIGEgVGFySW5mbwogICAgIyBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBoZWFkZXIgYmxvY2sgZnJvbSB0aGUgY3VycmVudCBvZmZzZXQuIFRoZQogICAgIyBwcm9jX21lbWJlcigpIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBhIHN1YmNsYXNzIHRvIGFkZCBjdXN0b20KICAgICMgcHJvY18qKCkgbWV0aG9kcy4gQSBwcm9jXyooKSBtZXRob2QgTVVTVCBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZwogICAgIyBvcGVyYXRpb25zOgogICAgIyAxLiBTZXQgdGFyaW5mby5vZmZzZXRfZGF0YSB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGRhdGEgYmxvY2tzIGJlZ2luLAogICAgIyAgICBpZiB0aGVyZSBpcyBkYXRhIHRoYXQgZm9sbG93cy4KICAgICMgMi4gU2V0IHNlbGYub2Zmc2V0IHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgbmV4dCBtZW1iZXIncyBoZWFkZXIgd2lsbAogICAgIyAgICBiZWdpbi4KICAgICMgMy4gUmV0dXJuIHRhcmluZm8gb3IgYW5vdGhlciB2YWxpZCBUYXJJbmZvIG9iamVjdC4KICAgIGRlZiBwcm9jX21lbWJlcihzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJDaG9vc2UgdGhlIHJpZ2h0IHByb2Nlc3NpbmcgbWV0aG9kIGZvciB0YXJpbmZvIGRlcGVuZGluZwogICAgICAgICAgIG9uIGl0cyB0eXBlIGFuZCBjYWxsIGl0LgogICAgICAgICIiIgogICAgICAgIGlmIHRhcmluZm8udHlwZSBpbiAoR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2NfZ251bG9uZyh0YXJpbmZvKQogICAgICAgIGVsaWYgdGFyaW5mby50eXBlID09IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICByZXR1cm4gc2VsZi5wcm9jX3NwYXJzZSh0YXJpbmZvKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2NfYnVpbHRpbih0YXJpbmZvKQoKICAgIGRlZiBwcm9jX2J1aWx0aW4oc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiUHJvY2VzcyBhIGJ1aWx0aW4gdHlwZSBtZW1iZXIgb3IgYW4gdW5rbm93biBtZW1iZXIKICAgICAgICAgICB3aGljaCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSByZWd1bGFyIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIFNraXAgdGhlIGZvbGxvd2luZyBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIHByb2NfZ251bG9uZyhzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJQcm9jZXNzIHRoZSBibG9ja3MgdGhhdCBob2xkIGEgR05VIGxvbmduYW1lCiAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgY291bnQgPSB0YXJpbmZvLnNpemUKICAgICAgICB3aGlsZSBjb3VudCA+IDA6CiAgICAgICAgICAgIGJsb2NrID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBidWYgKz0gYmxvY2sKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIGNvdW50IC09IEJMT0NLU0laRQoKICAgICAgICAjIEZldGNoIHRoZSBuZXh0IGhlYWRlciBhbmQgcHJvY2VzcyBpdC4KICAgICAgICBiID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgIHQgPSBUYXJJbmZvLmZyb21idWYoYikKICAgICAgICB0Lm9mZnNldCA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgbmV4dCA9IHNlbGYucHJvY19tZW1iZXIodCkKCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgbmV4dCBoZWFkZXIgd2l0aAogICAgICAgICMgdGhlIGxvbmduYW1lIGluZm9ybWF0aW9uLgogICAgICAgIG5leHQub2Zmc2V0ID0gdGFyaW5mby5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToKICAgICAgICAgICAgbmV4dC5uYW1lID0gYnVmLnJzdHJpcChOVUwpCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9MT05HTElOSzoKICAgICAgICAgICAgbmV4dC5saW5rbmFtZSA9IGJ1Zi5yc3RyaXAoTlVMKQoKICAgICAgICByZXR1cm4gbmV4dAoKICAgIGRlZiBwcm9jX3NwYXJzZShzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJQcm9jZXNzIGEgR05VIHNwYXJzZSBoZWFkZXIgcGx1cyBleHRyYSBoZWFkZXJzLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHRhcmluZm8uYnVmCiAgICAgICAgc3AgPSBfcmluZ2J1ZmZlcigpCiAgICAgICAgcG9zID0gMzg2CiAgICAgICAgbGFzdHBvcyA9IDBMCiAgICAgICAgcmVhbHBvcyA9IDBMCiAgICAgICAgIyBUaGVyZSBhcmUgNCBwb3NzaWJsZSBzcGFyc2Ugc3RydWN0cyBpbiB0aGUKICAgICAgICAjIGZpcnN0IGhlYWRlci4KICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoNCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9mZnNldCA9IG50aShidWZbcG9zOnBvcyArIDEyXSkKICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgc3AuYXBwZW5kKF9kYXRhKG9mZnNldCwgbnVtYnl0ZXMsIHJlYWxwb3MpKQogICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICBwb3MgKz0gMjQKCiAgICAgICAgaXNleHRlbmRlZCA9IG9yZChidWZbNDgyXSkKICAgICAgICBvcmlnc2l6ZSA9IG50aShidWZbNDgzOjQ5NV0pCgogICAgICAgICMgSWYgdGhlIGlzZXh0ZW5kZWQgZmxhZyBpcyBnaXZlbiwKICAgICAgICAjIHRoZXJlIGFyZSBleHRyYSBoZWFkZXJzIHRvIHByb2Nlc3MuCiAgICAgICAgd2hpbGUgaXNleHRlbmRlZCA9PSAxOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICBwb3MgPSAwCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZSgyMSk6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgICAgIHBvcyArPSAyNAogICAgICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls1MDRdKQoKICAgICAgICBpZiBsYXN0cG9zIDwgb3JpZ3NpemU6CiAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvcmlnc2l6ZSAtIGxhc3Rwb3MpKQoKICAgICAgICB0YXJpbmZvLnNwYXJzZSA9IHNwCgogICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEgPSBzZWxmLm9mZnNldAogICAgICAgIHNlbGYub2Zmc2V0ICs9IHNlbGYuX2Jsb2NrKHRhcmluZm8uc2l6ZSkKICAgICAgICB0YXJpbmZvLnNpemUgPSBvcmlnc2l6ZQoKICAgICAgICAjIENsZWFyIHRoZSBwcmVmaXggZmllbGQgc28gdGhhdCBpdCBpcyBub3QgdXNlZAogICAgICAgICMgYXMgYSBwYXRobmFtZSBpbiBuZXh0KCkuCiAgICAgICAgdGFyaW5mby5wcmVmaXggPSAiIgoKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBMaXR0bGUgaGVscGVyIG1ldGhvZHM6CgogICAgZGVmIF9ibG9jayhzZWxmLCBjb3VudCk6CiAgICAgICAgIiIiUm91bmQgdXAgYSBieXRlIGNvdW50IGJ5IEJMT0NLU0laRSBhbmQgcmV0dXJuIGl0LAogICAgICAgICAgIGUuZy4gX2Jsb2NrKDgzNCkgPT4gMTAyNC4KICAgICAgICAiIiIKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChjb3VudCwgQkxPQ0tTSVpFKQogICAgICAgIGlmIHJlbWFpbmRlcjoKICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICByZXR1cm4gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgZGVmIF9nZXRtZW1iZXIoc2VsZiwgbmFtZSwgdGFyaW5mbz1Ob25lKToKICAgICAgICAiIiJGaW5kIGFuIGFyY2hpdmUgbWVtYmVyIGJ5IG5hbWUgZnJvbSBib3R0b20gdG8gdG9wLgogICAgICAgICAgIElmIHRhcmluZm8gaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgYXMgdGhlIHN0YXJ0aW5nIHBvaW50LgogICAgICAgICIiIgogICAgICAgICMgRW5zdXJlIHRoYXQgYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIGxvYWRlZC4KICAgICAgICBtZW1iZXJzID0gc2VsZi5nZXRtZW1iZXJzKCkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBlbmQgPSBsZW4obWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICBlbmQgPSBtZW1iZXJzLmluZGV4KHRhcmluZm8pCgogICAgICAgIGZvciBpIGluIHhyYW5nZShlbmQgLSAxLCAtMSwgLTEpOgogICAgICAgICAgICBpZiBuYW1lID09IG1lbWJlcnNbaV0ubmFtZToKICAgICAgICAgICAgICAgIHJldHVybiBtZW1iZXJzW2ldCgogICAgZGVmIF9sb2FkKHNlbGYpOgogICAgICAgICIiIlJlYWQgdGhyb3VnaCB0aGUgZW50aXJlIGFyY2hpdmUgZmlsZSBhbmQgbG9vayBmb3IgcmVhZGFibGUKICAgICAgICAgICBtZW1iZXJzLgogICAgICAgICIiIgogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLm5leHQoKQogICAgICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKCiAgICBkZWYgX2NoZWNrKHNlbGYsIG1vZGU9Tm9uZSk6CiAgICAgICAgIiIiQ2hlY2sgaWYgVGFyRmlsZSBpcyBzdGlsbCBvcGVuLCBhbmQgaWYgdGhlIG9wZXJhdGlvbidzIG1vZGUKICAgICAgICAgICBjb3JyZXNwb25kcyB0byBUYXJGaWxlJ3MgbW9kZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiJXMgaXMgY2xvc2VkIiAlIHNlbGYuX19jbGFzc19fLl9fbmFtZV9fKQogICAgICAgIGlmIG1vZGUgaXMgbm90IE5vbmUgYW5kIHNlbGYuX21vZGUgbm90IGluIG1vZGU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5fbW9kZSkKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUHJvdmlkZSBhbiBpdGVyYXRvciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5fbG9hZGVkOgogICAgICAgICAgICByZXR1cm4gaXRlcihzZWxmLm1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIFRhckl0ZXIoc2VsZikKCiAgICBkZWYgX2NyZWF0ZV9nbnVsb25nKHNlbGYsIG5hbWUsIHR5cGUpOgogICAgICAgICIiIldyaXRlIGEgR05VIGxvbmduYW1lL2xvbmdsaW5rIG1lbWJlciB0byB0aGUgVGFyRmlsZS4KICAgICAgICAgICBJdCBjb25zaXN0cyBvZiBhbiBleHRlbmRlZCB0YXIgaGVhZGVyLCB3aXRoIHRoZSBsZW5ndGgKICAgICAgICAgICBvZiB0aGUgbG9uZ25hbWUgYXMgc2l6ZSwgZm9sbG93ZWQgYnkgZGF0YSBibG9ja3MsCiAgICAgICAgICAgd2hpY2ggY29udGFpbiB0aGUgbG9uZ25hbWUgYXMgYSBudWxsIHRlcm1pbmF0ZWQgc3RyaW5nLgogICAgICAgICIiIgogICAgICAgIG5hbWUgKz0gTlVMCgogICAgICAgIHRhcmluZm8gPSBUYXJJbmZvKCkKICAgICAgICB0YXJpbmZvLm5hbWUgPSAiLi8uL0BMb25nTGluayIKICAgICAgICB0YXJpbmZvLnR5cGUgPSB0eXBlCiAgICAgICAgdGFyaW5mby5tb2RlID0gMAogICAgICAgIHRhcmluZm8uc2l6ZSA9IGxlbihuYW1lKQoKICAgICAgICAjIHdyaXRlIGV4dGVuZGVkIGhlYWRlcgogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZSh0YXJpbmZvLnRvYnVmKCkpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgIyB3cml0ZSBuYW1lIGJsb2NrcwogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShuYW1lKQogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShOVUwgKiAoQkxPQ0tTSVpFIC0gcmVtYWluZGVyKSkKICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICBzZWxmLm9mZnNldCArPSBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICBkZWYgX2RiZyhzZWxmLCBsZXZlbCwgbXNnKToKICAgICAgICAiIiJXcml0ZSBkZWJ1Z2dpbmcgb3V0cHV0IHRvIHN5cy5zdGRlcnIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGV2ZWwgPD0gc2VsZi5kZWJ1ZzoKICAgICAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgbXNnCiMgY2xhc3MgVGFyRmlsZQoKY2xhc3MgVGFySXRlcjoKICAgICIiIkl0ZXJhdG9yIENsYXNzLgoKICAgICAgIGZvciB0YXJpbmZvIGluIFRhckZpbGUoLi4uKToKICAgICAgICAgICBzdWl0ZS4uLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckl0ZXIgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYudGFyZmlsZSA9IHRhcmZpbGUKICAgICAgICBzZWxmLmluZGV4ID0gMAogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlJldHVybiBpdGVyYXRvciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBpdGVtIHVzaW5nIFRhckZpbGUncyBuZXh0KCkgbWV0aG9kLgogICAgICAgICAgIFdoZW4gYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQsIHNldCBUYXJGaWxlIGFzIF9sb2FkZWQuCiAgICAgICAgIiIiCiAgICAgICAgIyBGaXggZm9yIFNGICMxMTAwNDI5OiBVbmRlciByYXJlIGNpcmN1bXN0YW5jZXMgaXQgY2FuCiAgICAgICAgIyBoYXBwZW4gdGhhdCBnZXRtZW1iZXJzKCkgaXMgY2FsbGVkIGR1cmluZyBpdGVyYXRpb24sCiAgICAgICAgIyB3aGljaCB3aWxsIGNhdXNlIFRhckl0ZXIgdG8gc3RvcCBwcmVtYXR1cmVseS4KICAgICAgICBpZiBub3Qgc2VsZi50YXJmaWxlLl9sb2FkZWQ6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmZpbGUubmV4dCgpCiAgICAgICAgICAgIGlmIG5vdCB0YXJpbmZvOgogICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLl9sb2FkZWQgPSBUcnVlCiAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5tZW1iZXJzW3NlbGYuaW5kZXhdCiAgICAgICAgICAgIGV4Y2VwdCBJbmRleEVycm9yOgogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIHNlbGYuaW5kZXggKz0gMQogICAgICAgIHJldHVybiB0YXJpbmZvCgojIEhlbHBlciBjbGFzc2VzIGZvciBzcGFyc2UgZmlsZSBzdXBwb3J0CmNsYXNzIF9zZWN0aW9uOgogICAgIiIiQmFzZSBjbGFzcyBmb3IgX2RhdGEgYW5kIF9ob2xlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKToKICAgICAgICBzZWxmLm9mZnNldCA9IG9mZnNldAogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKICAgIGRlZiBfX2NvbnRhaW5zX18oc2VsZiwgb2Zmc2V0KToKICAgICAgICByZXR1cm4gc2VsZi5vZmZzZXQgPD0gb2Zmc2V0IDwgc2VsZi5vZmZzZXQgKyBzZWxmLnNpemUKCmNsYXNzIF9kYXRhKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGRhdGEgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplLCByZWFscG9zKToKICAgICAgICBfc2VjdGlvbi5fX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpCiAgICAgICAgc2VsZi5yZWFscG9zID0gcmVhbHBvcwoKY2xhc3MgX2hvbGUoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgaG9sZSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIHBhc3MKCmNsYXNzIF9yaW5nYnVmZmVyKGxpc3QpOgogICAgIiIiUmluZ2J1ZmZlciBjbGFzcyB3aGljaCBpbmNyZWFzZXMgcGVyZm9ybWFuY2UKICAgICAgIG92ZXIgYSByZWd1bGFyIGxpc3QuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLmlkeCA9IDAKICAgIGRlZiBmaW5kKHNlbGYsIG9mZnNldCk6CiAgICAgICAgaWR4ID0gc2VsZi5pZHgKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBpdGVtID0gc2VsZltpZHhdCiAgICAgICAgICAgIGlmIG9mZnNldCBpbiBpdGVtOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWR4ICs9IDEKICAgICAgICAgICAgaWYgaWR4ID09IGxlbihzZWxmKToKICAgICAgICAgICAgICAgIGlkeCA9IDAKICAgICAgICAgICAgaWYgaWR4ID09IHNlbGYuaWR4OgogICAgICAgICAgICAgICAgIyBFbmQgb2YgRmlsZQogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICBzZWxmLmlkeCA9IGlkeAogICAgICAgIHJldHVybiBpdGVtCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgemlwZmlsZSBjb21wYXRpYmxlIFRhckZpbGUgY2xhc3MKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpUQVJfUExBSU4gPSAwICAgICAgICAgICAjIHppcGZpbGUuWklQX1NUT1JFRApUQVJfR1pJUFBFRCA9IDggICAgICAgICAjIHppcGZpbGUuWklQX0RFRkxBVEVECmNsYXNzIFRhckZpbGVDb21wYXQ6CiAgICAiIiJUYXJGaWxlIGNsYXNzIGNvbXBhdGlibGUgd2l0aCBzdGFuZGFyZCBtb2R1bGUgemlwZmlsZSdzCiAgICAgICBaaXBGaWxlIGNsYXNzLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZSwgbW9kZT0iciIsIGNvbXByZXNzaW9uPVRBUl9QTEFJTik6CiAgICAgICAgaWYgY29tcHJlc3Npb24gPT0gVEFSX1BMQUlOOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLnRhcm9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbGlmIGNvbXByZXNzaW9uID09IFRBUl9HWklQUEVEOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLmd6b3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVua25vd24gY29tcHJlc3Npb24gY29uc3RhbnQiKQogICAgICAgIGlmIG1vZGVbMDoxXSA9PSAiciI6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpCiAgICAgICAgICAgIGZvciBtIGluIG1lbWJlcnM6CiAgICAgICAgICAgICAgICBtLmZpbGVuYW1lID0gbS5uYW1lCiAgICAgICAgICAgICAgICBtLmZpbGVfc2l6ZSA9IG0uc2l6ZQogICAgICAgICAgICAgICAgbS5kYXRlX3RpbWUgPSB0aW1lLmdtdGltZShtLm10aW1lKVs6Nl0KICAgIGRlZiBuYW1lbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gbWFwKGxhbWJkYSBtOiBtLm5hbWUsIHNlbGYuaW5mb2xpc3QoKSkKICAgIGRlZiBpbmZvbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gZmlsdGVyKGxhbWJkYSBtOiBtLnR5cGUgaW4gUkVHVUxBUl9UWVBFUywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkpCiAgICBkZWYgcHJpbnRkaXIoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmxpc3QoKQogICAgZGVmIHRlc3R6aXAoc2VsZik6CiAgICAgICAgcmV0dXJuCiAgICBkZWYgZ2V0aW5mbyhzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKQogICAgZGVmIHJlYWQoc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5leHRyYWN0ZmlsZShzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpKS5yZWFkKCkKICAgIGRlZiB3cml0ZShzZWxmLCBmaWxlbmFtZSwgYXJjbmFtZT1Ob25lLCBjb21wcmVzc190eXBlPU5vbmUpOgogICAgICAgIHNlbGYudGFyZmlsZS5hZGQoZmlsZW5hbWUsIGFyY25hbWUpCiAgICBkZWYgd3JpdGVzdHIoc2VsZiwgemluZm8sIGJ5dGVzKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgZnJvbSBTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBpbXBvcnQgY2FsZW5kYXIKICAgICAgICB6aW5mby5uYW1lID0gemluZm8uZmlsZW5hbWUKICAgICAgICB6aW5mby5zaXplID0gemluZm8uZmlsZV9zaXplCiAgICAgICAgemluZm8ubXRpbWUgPSBjYWxlbmRhci50aW1lZ20oemluZm8uZGF0ZV90aW1lKQogICAgICAgIHNlbGYudGFyZmlsZS5hZGRmaWxlKHppbmZvLCBTdHJpbmdJTyhieXRlcykpCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmNsb3NlKCkKI2NsYXNzIFRhckZpbGVDb21wYXQKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQojIGV4cG9ydGVkIGZ1bmN0aW9ucwojLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIGlzX3RhcmZpbGUobmFtZSk6CiAgICAiIiJSZXR1cm4gVHJ1ZSBpZiBuYW1lIHBvaW50cyB0byBhIHRhciBhcmNoaXZlIHRoYXQgd2UKICAgICAgIGFyZSBhYmxlIHRvIGhhbmRsZSwgZWxzZSByZXR1cm4gRmFsc2UuCiAgICAiIiIKICAgIHRyeToKICAgICAgICB0ID0gb3BlbihuYW1lKQogICAgICAgIHQuY2xvc2UoKQogICAgICAgIHJldHVybiBUcnVlCiAgICBleGNlcHQgVGFyRXJyb3I6CiAgICAgICAgcmV0dXJuIEZhbHNlCgpvcGVuID0gVGFyRmlsZS5vcGVuCg==