IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC42LjQiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKCmlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICMgVGhpcyBtb2R1bGUgbmVlZHMgd29yayBmb3IgTWFjT1M5LCBlc3BlY2lhbGx5IGluIHRoZSBhcmVhIG9mIHBhdGhuYW1lCiAgICAjIGhhbmRsaW5nLiBJbiBtYW55IHBsYWNlcyBpdCBpcyBhc3N1bWVkIGEgc2ltcGxlIHN1YnN0aXR1dGlvbiBvZiAvIGJ5IHRoZQogICAgIyBsb2NhbCBvcy5wYXRoLnNlcCBpcyBnb29kIGVub3VnaCB0byBjb252ZXJ0IHBhdGhuYW1lcywgYnV0IHRoaXMgZG9lcyBub3QKICAgICMgd29yayB3aXRoIHRoZSBtYWMgcm9vdGVkOnBhdGg6bmFtZSB2ZXJzdXMgOm5vbnJvb3RlZDpwYXRoOm5hbWUgc3ludGF4CiAgICByYWlzZSBJbXBvcnRFcnJvciwgInRhcmZpbGUgZG9lcyBub3Qgd29yayBmb3IgcGxhdGZvcm09PW1hYyIKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZGVmIG50cyhzKToKICAgICIiIkNvbnZlcnQgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIGJ1ZmZlciB0byBhIHB5dGhvbiBzdHJpbmcuCiAgICAiIiIKICAgIHJldHVybiBzLnJzdHJpcChOVUwpCgpkZWYgY2FsY19jaGtzdW0oYnVmKToKICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyLiBJdCdzIGEgc2ltcGxlIGFkZGl0aW9uCiAgICAgICBvZiBhbGwgYnl0ZXMsIHRyZWF0aW5nIHRoZSBjaGtzdW0gZmllbGQgYXMgaWYgZmlsbGVkIHdpdGggc3BhY2VzLgogICAgICAgYnVmIGlzIGEgNTEyIGJ5dGUgbG9uZyBzdHJpbmcgYnVmZmVyIHdoaWNoIGhvbGRzIHRoZSBoZWFkZXIuCiAgICAiIiIKICAgIGNoayA9IDI1NiAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY2hrc3VtIGZpZWxkIGlzIHRyZWF0ZWQgYXMgYmxhbmtzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzbyB0aGUgaW5pdGlhbCB2YWx1ZSBpcyA4ICogb3JkKCIgIikKICAgIGZvciBjIGluIGJ1Zls6MTQ4XTogY2hrICs9IG9yZChjKSAgICMgc3VtIHVwIGFsbCBieXRlcyBiZWZvcmUgY2hrc3VtCiAgICBmb3IgYyBpbiBidWZbMTU2Ol06IGNoayArPSBvcmQoYykgICAjIHN1bSB1cCBhbGwgYnl0ZXMgYWZ0ZXIgY2hrc3VtCiAgICByZXR1cm4gY2hrCgpkZWYgY29weWZpbGVvYmooc3JjLCBkc3QsIGxlbmd0aD1Ob25lKToKICAgICIiIkNvcHkgbGVuZ3RoIGJ5dGVzIGZyb20gZmlsZW9iaiBzcmMgdG8gZmlsZW9iaiBkc3QuCiAgICAgICBJZiBsZW5ndGggaXMgTm9uZSwgY29weSB0aGUgZW50aXJlIGNvbnRlbnQuCiAgICAiIiIKICAgIGlmIGxlbmd0aCA9PSAwOgogICAgICAgIHJldHVybgogICAgaWYgbGVuZ3RoIGlzIE5vbmU6CiAgICAgICAgc2h1dGlsLmNvcHlmaWxlb2JqKHNyYywgZHN0KQogICAgICAgIHJldHVybgoKICAgIEJVRlNJWkUgPSAxNiAqIDEwMjQKICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbmd0aCwgQlVGU0laRSkKICAgIGZvciBiIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKEJVRlNJWkUpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCBCVUZTSVpFOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiZW5kIG9mIGZpbGUgcmVhY2hlZCIKICAgICAgICBkc3Qud3JpdGUoYnVmKQoKICAgIGlmIHJlbWFpbmRlciAhPSAwOgogICAgICAgIGJ1ZiA9IHNyYy5yZWFkKHJlbWFpbmRlcikKICAgICAgICBpZiBsZW4oYnVmKSA8IHJlbWFpbmRlcjoKICAgICAgICAgICAgcmFpc2UgSU9FcnJvciwgImVuZCBvZiBmaWxlIHJlYWNoZWQiCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKICAgIHJldHVybgoKZmlsZW1vZGVfdGFibGUgPSAoCiAgICAoKFNfSUZMTkssICAgICAgImwiKSwKICAgICAoU19JRlJFRywgICAgICAiLSIpLAogICAgIChTX0lGQkxLLCAgICAgICJiIiksCiAgICAgKFNfSUZESVIsICAgICAgImQiKSwKICAgICAoU19JRkNIUiwgICAgICAiYyIpLAogICAgIChTX0lGSUZPLCAgICAgICJwIikpLAoKICAgICgoVFVSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRVV1JJVEUsICAgICAgInciKSwpLAogICAgKChUVUVYRUN8VFNVSUQsICJzIiksCiAgICAgKFRTVUlELCAgICAgICAgIlMiKSwKICAgICAoVFVFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRHUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUR1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVEdFWEVDfFRTR0lELCAicyIpLAogICAgIChUU0dJRCwgICAgICAgICJTIiksCiAgICAgKFRHRVhFQywgICAgICAgIngiKSksCgogICAgKChUT1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVE9XUklURSwgICAgICAidyIpLCksCiAgICAoKFRPRVhFQ3xUU1ZUWCwgInQiKSwKICAgICAoVFNWVFgsICAgICAgICAiVCIpLAogICAgIChUT0VYRUMsICAgICAgICJ4IikpCikKCmRlZiBmaWxlbW9kZShtb2RlKToKICAgICIiIkNvbnZlcnQgYSBmaWxlJ3MgbW9kZSB0byBhIHN0cmluZyBvZiB0aGUgZm9ybQogICAgICAgLXJ3eHJ3eHJ3eC4KICAgICAgIFVzZWQgYnkgVGFyRmlsZS5saXN0KCkKICAgICIiIgogICAgcGVybSA9IFtdCiAgICBmb3IgdGFibGUgaW4gZmlsZW1vZGVfdGFibGU6CiAgICAgICAgZm9yIGJpdCwgY2hhciBpbiB0YWJsZToKICAgICAgICAgICAgaWYgbW9kZSAmIGJpdCA9PSBiaXQ6CiAgICAgICAgICAgICAgICBwZXJtLmFwcGVuZChjaGFyKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBwZXJtLmFwcGVuZCgiLSIpCiAgICByZXR1cm4gIiIuam9pbihwZXJtKQoKaWYgb3Muc2VwICE9ICIvIjoKICAgIG5vcm1wYXRoID0gbGFtYmRhIHBhdGg6IG9zLnBhdGgubm9ybXBhdGgocGF0aCkucmVwbGFjZShvcy5zZXAsICIvIikKZWxzZToKICAgIG5vcm1wYXRoID0gb3MucGF0aC5ub3JtcGF0aAoKY2xhc3MgVGFyRXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkJhc2UgZXhjZXB0aW9uLiIiIgogICAgcGFzcwpjbGFzcyBFeHRyYWN0RXJyb3IoVGFyRXJyb3IpOgogICAgIiIiR2VuZXJhbCBleGNlcHRpb24gZm9yIGV4dHJhY3QgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBSZWFkRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnJlYWRibGUgdGFyIGFyY2hpdmVzLiIiIgogICAgcGFzcwpjbGFzcyBDb21wcmVzc2lvbkVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5hdmFpbGFibGUgY29tcHJlc3Npb24gbWV0aG9kcy4iIiIKICAgIHBhc3MKY2xhc3MgU3RyZWFtRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bnN1cHBvcnRlZCBvcGVyYXRpb25zIG9uIHN0cmVhbS1saWtlIFRhckZpbGVzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiemxpYiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIgogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuKHNlbGYuYnVmKSwgc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5idWYgKz0gTlVMICogKHNlbGYuYnVmc2l6ZSAtIHJlbWFpbmRlcikKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPGwiLCBzZWxmLmNyYykpCiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc3RydWN0LnBhY2soIjxMIiwgc2VsZi5wb3MgJiAweGZmZmZGRkZGTCkpCgogICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQoKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgX2luaXRfcmVhZF9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciByZWFkaW5nIGEgZ3ppcCBjb21wcmVzc2VkIGZpbGVvYmouCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbXAgPSBzZWxmLnpsaWIuZGVjb21wcmVzc29iaigtc2VsZi56bGliLk1BWF9XQklUUykKICAgICAgICBzZWxmLmRidWYgPSAiIgoKICAgICAgICAjIHRha2VuIGZyb20gZ3ppcC5HemlwRmlsZSB3aXRoIHNvbWUgYWx0ZXJhdGlvbnMKICAgICAgICBpZiBzZWxmLl9fcmVhZCgyKSAhPSAiXDAzN1wyMTMiOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IsICJub3QgYSBnemlwIGZpbGUiCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMSkgIT0gIlwwMTAiOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAidW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kIgoKICAgICAgICBmbGFnID0gb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgIHNlbGYuX19yZWFkKDYpCgogICAgICAgIGlmIGZsYWcgJiA0OgogICAgICAgICAgICB4bGVuID0gb3JkKHNlbGYuX19yZWFkKDEpKSArIDI1NiAqIG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICAgICAgc2VsZi5yZWFkKHhsZW4pCiAgICAgICAgaWYgZmxhZyAmIDg6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDE2OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAyOgogICAgICAgICAgICBzZWxmLl9fcmVhZCgyKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHBvc2l0aW9uLgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcz0wKToKICAgICAgICAiIiJTZXQgdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciB0byBwb3MuIE5lZ2F0aXZlIHNlZWtpbmcKICAgICAgICAgICBpcyBmb3JiaWRkZW4uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcG9zIC0gc2VsZi5wb3MgPj0gMDoKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QocG9zIC0gc2VsZi5wb3MsIHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgICAgICAgICBzZWxmLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBzZWxmLnJlYWQocmVtYWluZGVyKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yLCAic2Vla2luZyBiYWNrd2FyZHMgaXMgbm90IGFsbG93ZWQiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgc2l6ZSBudW1iZXIgb2YgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICAgIElmIHNpemUgaXMgbm90IGRlZmluZWQsIHJldHVybiBhbGwgYnl0ZXMgb2YgdGhlIHN0cmVhbQogICAgICAgICAgIHVwIHRvIEVPRi4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHQgPSBbXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGJ1ZiA9ICIiLmpvaW4odCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNpemUpCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIF9yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJ0YXIiOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoc2l6ZSkKCiAgICAgICAgYyA9IGxlbihzZWxmLmRidWYpCiAgICAgICAgdCA9IFtzZWxmLmRidWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX19yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuY21wLmRlY29tcHJlc3MoYnVmKQogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuZGJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHN0cmVhbS4gSWYgaW50ZXJuYWwgYnVmZmVyIGlzIGVtcHR5LAogICAgICAgICAgIHJlYWQgYW5vdGhlciBibG9jayBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgYyA9IGxlbihzZWxmLmJ1ZikKICAgICAgICB0ID0gW3NlbGYuYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0LmFwcGVuZChidWYpCiAgICAgICAgICAgIGMgKz0gbGVuKGJ1ZikKICAgICAgICB0ID0gIiIuam9pbih0KQogICAgICAgIHNlbGYuYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KIyBjbGFzcyBfU3RyZWFtCgpjbGFzcyBfU3RyZWFtUHJveHkob2JqZWN0KToKICAgICIiIlNtYWxsIHByb3h5IGNsYXNzIHRoYXQgZW5hYmxlcyB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgZGV0ZWN0aW9uIGZvciB0aGUgU3RyZWFtIGludGVyZmFjZSAobW9kZSAncnwqJykuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaik6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYuYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHNlbGYucmVhZCA9IHNlbGYuZmlsZW9iai5yZWFkCiAgICAgICAgcmV0dXJuIHNlbGYuYnVmCgogICAgZGVmIGdldGNvbXB0eXBlKHNlbGYpOgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIlwwMzdcMjEzXDAxMCIpOgogICAgICAgICAgICByZXR1cm4gImd6IgogICAgICAgIGlmIHNlbGYuYnVmLnN0YXJ0c3dpdGgoIkJaaDkxIik6CiAgICAgICAgICAgIHJldHVybiAiYnoyIgogICAgICAgIHJldHVybiAidGFyIgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQojIGNsYXNzIFN0cmVhbVByb3h5CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXh0cmFjdGlvbiBmaWxlIG9iamVjdAojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIEV4RmlsZU9iamVjdChvYmplY3QpOgogICAgIiIiRmlsZS1saWtlIG9iamVjdCBmb3IgcmVhZGluZyBhbiBhcmNoaXZlIG1lbWJlci4KICAgICAgIElzIHJldHVybmVkIGJ5IFRhckZpbGUuZXh0cmFjdGZpbGUoKS4gU3VwcG9ydCBmb3IKICAgICAgIHNwYXJzZSBmaWxlcyBpbmNsdWRlZC4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlLCB0YXJpbmZvKToKICAgICAgICBzZWxmLmZpbGVvYmogPSB0YXJmaWxlLmZpbGVvYmoKICAgICAgICBzZWxmLm5hbWUgICAgPSB0YXJpbmZvLm5hbWUKICAgICAgICBzZWxmLm1vZGUgICAgPSAiciIKICAgICAgICBzZWxmLmNsb3NlZCAgPSBGYWxzZQogICAgICAgIHNlbGYub2Zmc2V0ICA9IHRhcmluZm8ub2Zmc2V0X2RhdGEKICAgICAgICBzZWxmLnNpemUgICAgPSB0YXJpbmZvLnNpemUKICAgICAgICBzZWxmLnBvcyAgICAgPSAwTAogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9ICIiCiAgICAgICAgaWYgdGFyaW5mby5pc3NwYXJzZSgpOgogICAgICAgICAgICBzZWxmLnNwYXJzZSA9IHRhcmluZm8uc3BhcnNlCiAgICAgICAgICAgIHNlbGYucmVhZCA9IHNlbGYuX3JlYWRzcGFyc2UKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLl9yZWFkbm9ybWFsCgogICAgZGVmIF9fcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJPdmVybG9hZGFibGUgcmVhZCBtZXRob2QuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iai5yZWFkKHNpemUpCgogICAgZGVmIHJlYWRsaW5lKHNlbGYsIHNpemU9LTEpOgogICAgICAgICIiIlJlYWQgYSBsaW5lIHdpdGggYXBwcm94LiBzaXplLiBJZiBzaXplIGlzIG5lZ2F0aXZlLAogICAgICAgICAgIHJlYWQgYSB3aG9sZSBsaW5lLiByZWFkbGluZSgpIGFuZCByZWFkKCkgbXVzdCBub3QKICAgICAgICAgICBiZSBtaXhlZCB1cCAoISkuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSA8IDA6CiAgICAgICAgICAgIHNpemUgPSBzeXMubWF4aW50CgogICAgICAgIG5sID0gc2VsZi5saW5lYnVmZmVyLmZpbmQoIlxuIikKICAgICAgICBpZiBubCA+PSAwOgogICAgICAgICAgICBubCA9IG1pbihubCwgc2l6ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzaXplIC09IGxlbihzZWxmLmxpbmVidWZmZXIpCiAgICAgICAgICAgIHdoaWxlIChubCA8IDAgYW5kIHNpemUgPiAwKToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYucmVhZChtaW4oc2l6ZSwgMTAwKSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHNlbGYubGluZWJ1ZmZlciArPSBidWYKICAgICAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgICAgIG5sID0gc2VsZi5saW5lYnVmZmVyLmZpbmQoIlxuIikKICAgICAgICAgICAgaWYgbmwgPT0gLTE6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5saW5lYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVidWZmZXIgPSAiIgogICAgICAgICAgICAgICAgcmV0dXJuIHMKICAgICAgICBidWYgPSBzZWxmLmxpbmVidWZmZXJbOm5sXQogICAgICAgIHNlbGYubGluZWJ1ZmZlciA9IHNlbGYubGluZWJ1ZmZlcltubCArIDE6XQogICAgICAgIHdoaWxlIGJ1ZlstMTpdID09ICJcciI6CiAgICAgICAgICAgIGJ1ZiA9IGJ1Zls6LTFdCiAgICAgICAgcmV0dXJuIGJ1ZiArICJcbiIKCiAgICBkZWYgcmVhZGxpbmVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiBhIGxpc3Qgd2l0aCBhbGwgKGZvbGxvd2luZykgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gW10KICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBsaW5lID0gc2VsZi5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGxpbmUpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBfcmVhZG5vcm1hbChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJlYWQgb3BlcmF0aW9uIGZvciByZWd1bGFyIGZpbGVzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAiZmlsZSBpcyBjbG9zZWQiCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQgKyBzZWxmLnBvcykKICAgICAgICBieXRlc2xlZnQgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnl0ZXN0b3JlYWQgPSBieXRlc2xlZnQKICAgICAgICBlbHNlOgogICAgICAgICAgICBieXRlc3RvcmVhZCA9IG1pbihzaXplLCBieXRlc2xlZnQpCiAgICAgICAgc2VsZi5wb3MgKz0gYnl0ZXN0b3JlYWQKICAgICAgICByZXR1cm4gc2VsZi5fX3JlYWQoYnl0ZXN0b3JlYWQpCgogICAgZGVmIF9yZWFkc3BhcnNlKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgImZpbGUgaXMgY2xvc2VkIgoKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHNpemUgPSBzZWxmLnNpemUgLSBzZWxmLnBvcwoKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZHNwYXJzZXNlY3Rpb24oc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHNpemUgLT0gbGVuKGJ1ZikKICAgICAgICAgICAgZGF0YS5hcHBlbmQoYnVmKQogICAgICAgIHJldHVybiAiIi5qb2luKGRhdGEpCgogICAgZGVmIF9yZWFkc3BhcnNlc2VjdGlvbihzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIGEgc2luZ2xlIHNlY3Rpb24gb2YgYSBzcGFyc2UgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBzZWN0aW9uID0gc2VsZi5zcGFyc2UuZmluZChzZWxmLnBvcykKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgdG9yZWFkID0gbWluKHNpemUsIHNlY3Rpb24ub2Zmc2V0ICsgc2VjdGlvbi5zaXplIC0gc2VsZi5wb3MpCiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWN0aW9uLCBfZGF0YSk6CiAgICAgICAgICAgIHJlYWxwb3MgPSBzZWN0aW9uLnJlYWxwb3MgKyBzZWxmLnBvcyAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYucG9zICs9IHRvcmVhZAogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHJlYWxwb3MpCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZCh0b3JlYWQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wb3MgKz0gdG9yZWFkCiAgICAgICAgICAgIHJldHVybiBOVUwgKiB0b3JlYWQKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgc2VlayhzZWxmLCBwb3MsIHdoZW5jZT0wKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5saW5lYnVmZmVyID0gIiIKICAgICAgICBpZiB3aGVuY2UgPT0gMDoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMToKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zID0gbWF4KHNlbGYucG9zICsgcG9zLCAwKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5wb3MgPSBtaW4oc2VsZi5wb3MgKyBwb3MsIHNlbGYuc2l6ZSkKICAgICAgICBpZiB3aGVuY2UgPT0gMjoKICAgICAgICAgICAgc2VsZi5wb3MgPSBtYXgobWluKHNlbGYuc2l6ZSArIHBvcywgc2VsZi5zaXplKSwgMCkKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIGZpbGUgb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJHZXQgYW4gaXRlcmF0b3Igb3ZlciB0aGUgZmlsZSBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiR2V0IHRoZSBuZXh0IGl0ZW0gZnJvbSB0aGUgZmlsZSBpdGVyYXRvci4KICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICBpZiBub3QgcmVzdWx0OgogICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKI2NsYXNzIEV4RmlsZU9iamVjdAoKIy0tLS0tLS0tLS0tLS0tLS0tLQojIEV4cG9ydGVkIENsYXNzZXMKIy0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBUYXJJbmZvKG9iamVjdCk6CiAgICAiIiJJbmZvcm1hdGlvbmFsIGNsYXNzIHdoaWNoIGhvbGRzIHRoZSBkZXRhaWxzIGFib3V0IGFuCiAgICAgICBhcmNoaXZlIG1lbWJlciBnaXZlbiBieSBhIHRhciBoZWFkZXIgYmxvY2suCiAgICAgICBUYXJJbmZvIG9iamVjdHMgYXJlIHJldHVybmVkIGJ5IFRhckZpbGUuZ2V0bWVtYmVyKCksCiAgICAgICBUYXJGaWxlLmdldG1lbWJlcnMoKSBhbmQgVGFyRmlsZS5nZXR0YXJpbmZvKCkgYW5kIGFyZQogICAgICAgdXN1YWxseSBjcmVhdGVkIGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT0iIik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QuIG5hbWUgaXMgdGhlIG9wdGlvbmFsIG5hbWUKICAgICAgICAgICBvZiB0aGUgbWVtYmVyLgogICAgICAgICIiIgoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSAgICAgICAjIG1lbWJlciBuYW1lIChkaXJuYW1lcyBtdXN0IGVuZCB3aXRoICcvJykKICAgICAgICBzZWxmLm1vZGUgICAgID0gMDY2NiAgICAgICAjIGZpbGUgcGVybWlzc2lvbnMKICAgICAgICBzZWxmLnVpZCAgICAgID0gMCAgICAgICAgICAjIHVzZXIgaWQKICAgICAgICBzZWxmLmdpZCAgICAgID0gMCAgICAgICAgICAjIGdyb3VwIGlkCiAgICAgICAgc2VsZi5zaXplICAgICA9IDAgICAgICAgICAgIyBmaWxlIHNpemUKICAgICAgICBzZWxmLm10aW1lICAgID0gMCAgICAgICAgICAjIG1vZGlmaWNhdGlvbiB0aW1lCiAgICAgICAgc2VsZi5jaGtzdW0gICA9IDAgICAgICAgICAgIyBoZWFkZXIgY2hlY2tzdW0KICAgICAgICBzZWxmLnR5cGUgICAgID0gUkVHVFlQRSAgICAjIG1lbWJlciB0eXBlCiAgICAgICAgc2VsZi5saW5rbmFtZSA9ICIiICAgICAgICAgIyBsaW5rIG5hbWUKICAgICAgICBzZWxmLnVuYW1lICAgID0gInVzZXIiICAgICAjIHVzZXIgbmFtZQogICAgICAgIHNlbGYuZ25hbWUgICAgPSAiZ3JvdXAiICAgICMgZ3JvdXAgbmFtZQogICAgICAgIHNlbGYuZGV2bWFqb3IgPSAwICAgICAgICAgICMtCiAgICAgICAgc2VsZi5kZXZtaW5vciA9IDAgICAgICAgICAgIy1mb3IgdXNlIHdpdGggQ0hSVFlQRSBhbmQgQkxLVFlQRQogICAgICAgIHNlbGYucHJlZml4ICAgPSAiIiAgICAgICAgICMgcHJlZml4IHRvIGZpbGVuYW1lIG9yIGhvbGRpbmcgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFib3V0IHNwYXJzZSBmaWxlcwoKICAgICAgICBzZWxmLm9mZnNldCAgID0gMCAgICAgICAgICAjIHRoZSB0YXIgaGVhZGVyIHN0YXJ0cyBoZXJlCiAgICAgICAgc2VsZi5vZmZzZXRfZGF0YSA9IDAgICAgICAgIyB0aGUgZmlsZSdzIGRhdGEgc3RhcnRzIGhlcmUKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgcmV0dXJuICI8JXMgJXIgYXQgJSN4PiIgJSAoc2VsZi5fX2NsYXNzX18uX19uYW1lX18sc2VsZi5uYW1lLGlkKHNlbGYpKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIGZyb21idWYoY2xzLCBidWYpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIFRhckluZm8gb2JqZWN0IGZyb20gYSA1MTIgYnl0ZSBzdHJpbmcgYnVmZmVyLgogICAgICAgICIiIgogICAgICAgIHRhcmluZm8gPSBjbHMoKQogICAgICAgIHRhcmluZm8ubmFtZSAgID0gbnRzKGJ1ZlswOjEwMF0pCiAgICAgICAgdGFyaW5mby5tb2RlICAgPSBpbnQoYnVmWzEwMDoxMDhdLCA4KQogICAgICAgIHRhcmluZm8udWlkICAgID0gaW50KGJ1ZlsxMDg6MTE2XSw4KQogICAgICAgIHRhcmluZm8uZ2lkICAgID0gaW50KGJ1ZlsxMTY6MTI0XSw4KQoKICAgICAgICAjIFRoZXJlIGFyZSB0d28gcG9zc2libGUgY29kaW5ncyBmb3IgdGhlIHNpemUgZmllbGQgd2UKICAgICAgICAjIGhhdmUgdG8gZGlzY3JpbWluYXRlLCBzZWUgY29tbWVudCBpbiB0b2J1ZigpIGJlbG93LgogICAgICAgIGlmIGJ1ZlsxMjRdICE9IGNocigwMjAwKToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gbG9uZyhidWZbMTI0OjEzNl0sIDgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMEwKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTEpOgogICAgICAgICAgICAgICAgdGFyaW5mby5zaXplIDw8PSA4CiAgICAgICAgICAgICAgICB0YXJpbmZvLnNpemUgKz0gb3JkKGJ1ZlsxMjUgKyBpXSkKCiAgICAgICAgdGFyaW5mby5tdGltZSAgPSBsb25nKGJ1ZlsxMzY6MTQ4XSwgOCkKICAgICAgICB0YXJpbmZvLmNoa3N1bSA9IGludChidWZbMTQ4OjE1Nl0sIDgpCiAgICAgICAgdGFyaW5mby50eXBlICAgPSBidWZbMTU2OjE1N10KICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbnRzKGJ1ZlsxNTc6MjU3XSkKICAgICAgICB0YXJpbmZvLnVuYW1lICA9IG50cyhidWZbMjY1OjI5N10pCiAgICAgICAgdGFyaW5mby5nbmFtZSAgPSBudHMoYnVmWzI5NzozMjldKQogICAgICAgIHRyeToKICAgICAgICAgICAgdGFyaW5mby5kZXZtYWpvciA9IGludChidWZbMzI5OjMzN10sIDgpCiAgICAgICAgICAgIHRhcmluZm8uZGV2bWlub3IgPSBpbnQoYnVmWzMzNzozNDVdLCA4KQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gdGFyaW5mby5kZXZtYWpvciA9IDAKICAgICAgICB0YXJpbmZvLnByZWZpeCA9IGJ1ZlszNDU6NTAwXQoKICAgICAgICAjIFNvbWUgb2xkIHRhciBwcm9ncmFtcyByZXByZXNlbnQgYSBkaXJlY3RvcnkgYXMgYSByZWd1bGFyCiAgICAgICAgIyBmaWxlIHdpdGggYSB0cmFpbGluZyBzbGFzaC4KICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgYW5kIHRhcmluZm8ubmFtZS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICB0YXJpbmZvLnR5cGUgPSBESVJUWVBFCgogICAgICAgICMgVGhlIHByZWZpeCBmaWVsZCBpcyB1c2VkIGZvciBmaWxlbmFtZXMgPiAxMDAgaW4KICAgICAgICAjIHRoZSBQT1NJWCBzdGFuZGFyZC4KICAgICAgICAjIG5hbWUgPSBwcmVmaXggKyAnLycgKyBuYW1lCiAgICAgICAgaWYgdGFyaW5mby50eXBlICE9IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSBub3JtcGF0aChvcy5wYXRoLmpvaW4obnRzKHRhcmluZm8ucHJlZml4KSwgdGFyaW5mby5uYW1lKSkKCiAgICAgICAgIyBEaXJlY3RvcnkgbmFtZXMgc2hvdWxkIGhhdmUgYSAnLycgYXQgdGhlIGVuZC4KICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiB0b2J1ZihzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSB0YXIgaGVhZGVyIGJsb2NrIGFzIGEgNTEyIGJ5dGUgc3RyaW5nLgogICAgICAgICIiIgogICAgICAgICMgUHJlZmVyIHRoZSBzaXplIHRvIGJlIGVuY29kZWQgYXMgMTEgb2N0YWwgYXNjaWkgZGlnaXRzCiAgICAgICAgIyB3aGljaCBpcyB0aGUgbW9zdCBwb3J0YWJsZS4gSWYgdGhlIHNpemUgZXhjZWVkcyB0aGlzCiAgICAgICAgIyBsaW1pdCAoPj0gOCBHQiksIGVuY29kZSBpdCBhcyBhbiA4OC1iaXQgdmFsdWUgd2hpY2ggaXMKICAgICAgICAjIGEgR05VIHRhciBmZWF0dXJlLgogICAgICAgIGlmIHNlbGYuc2l6ZSA8PSBNQVhTSVpFX01FTUJFUjoKICAgICAgICAgICAgc2l6ZSA9ICIlMDExbyIgJSBzZWxmLnNpemUKICAgICAgICBlbHNlOgogICAgICAgICAgICBzID0gc2VsZi5zaXplCiAgICAgICAgICAgIHNpemUgPSAiIgogICAgICAgICAgICBmb3IgaSBpbiByYW5nZSgxMSk6CiAgICAgICAgICAgICAgICBzaXplID0gY2hyKHMgJiAwMzc3KSArIHNpemUKICAgICAgICAgICAgICAgIHMgPj49IDgKICAgICAgICAgICAgc2l6ZSA9IGNocigwMjAwKSArIHNpemUKCiAgICAgICAgIyBUaGUgZm9sbG93aW5nIGNvZGUgd2FzIGNvbnRyaWJ1dGVkIGJ5IERldGxlZiBMYW5uZXJ0LgogICAgICAgIHBhcnRzID0gW10KICAgICAgICBmb3IgdmFsdWUsIGZpZWxkc2l6ZSBpbiAoCiAgICAgICAgICAgICAgICAoc2VsZi5uYW1lLCAxMDApLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIChzZWxmLm1vZGUgJiAwNzc3NyksIDgpLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIHNlbGYudWlkLCA4KSwKICAgICAgICAgICAgICAgICgiJTA3byIgJSBzZWxmLmdpZCwgOCksCiAgICAgICAgICAgICAgICAoc2l6ZSwgMTIpLAogICAgICAgICAgICAgICAgKCIlMDExbyIgJSBzZWxmLm10aW1lLCAxMiksCiAgICAgICAgICAgICAgICAoIiAgICAgICAgIiwgOCksCiAgICAgICAgICAgICAgICAoc2VsZi50eXBlLCAxKSwKICAgICAgICAgICAgICAgIChzZWxmLmxpbmtuYW1lLCAxMDApLAogICAgICAgICAgICAgICAgKE1BR0lDLCA2KSwKICAgICAgICAgICAgICAgIChWRVJTSU9OLCAyKSwKICAgICAgICAgICAgICAgIChzZWxmLnVuYW1lLCAzMiksCiAgICAgICAgICAgICAgICAoc2VsZi5nbmFtZSwgMzIpLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIHNlbGYuZGV2bWFqb3IsIDgpLAogICAgICAgICAgICAgICAgKCIlMDdvIiAlIHNlbGYuZGV2bWlub3IsIDgpLAogICAgICAgICAgICAgICAgKHNlbGYucHJlZml4LCAxNTUpCiAgICAgICAgICAgICk6CiAgICAgICAgICAgIGwgPSBsZW4odmFsdWUpCiAgICAgICAgICAgIHBhcnRzLmFwcGVuZCh2YWx1ZVs6ZmllbGRzaXplXSArIChmaWVsZHNpemUgLSBsKSAqIE5VTCkKCiAgICAgICAgYnVmID0gIiIuam9pbihwYXJ0cykKICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bShidWYpCiAgICAgICAgYnVmID0gYnVmWzoxNDhdICsgIiUwNm9cMCIgJSBjaGtzdW0gKyBidWZbMTU1Ol0KICAgICAgICBidWYgKz0gKEJMT0NLU0laRSAtIGxlbihidWYpKSAqIE5VTAogICAgICAgIHNlbGYuYnVmID0gYnVmCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBpc3JlZyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIFJFR1VMQVJfVFlQRVMKICAgIGRlZiBpc2ZpbGUoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuaXNyZWcoKQogICAgZGVmIGlzZGlyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRElSVFlQRQogICAgZGVmIGlzc3ltKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gU1lNVFlQRQogICAgZGVmIGlzbG5rKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gTE5LVFlQRQogICAgZGVmIGlzY2hyKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQ0hSVFlQRQogICAgZGVmIGlzYmxrKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gQkxLVFlQRQogICAgZGVmIGlzZmlmbyhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEZJRk9UWVBFCiAgICBkZWYgaXNzcGFyc2Uoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBHTlVUWVBFX1NQQVJTRQogICAgZGVmIGlzZGV2KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUsIEZJRk9UWVBFKQojIGNsYXNzIFRhckluZm8KCmNsYXNzIFRhckZpbGUob2JqZWN0KToKICAgICIiIlRoZSBUYXJGaWxlIENsYXNzIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byB0YXIgYXJjaGl2ZXMuCiAgICAiIiIKCiAgICBkZWJ1ZyA9IDAgICAgICAgICAgICAgICAgICAgIyBNYXkgYmUgc2V0IGZyb20gMCAobm8gbXNncykgdG8gMyAoYWxsIG1zZ3MpCgogICAgZGVyZWZlcmVuY2UgPSBGYWxzZSAgICAgICAgICMgSWYgdHJ1ZSwgYWRkIGNvbnRlbnQgb2YgbGlua2VkIGZpbGUgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0YXIgZmlsZSwgZWxzZSB0aGUgbGluay4KCiAgICBpZ25vcmVfemVyb3MgPSBGYWxzZSAgICAgICAgIyBJZiB0cnVlLCBza2lwcyBlbXB0eSBvciBpbnZhbGlkIGJsb2NrcyBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNvbnRpbnVlcyBwcm9jZXNzaW5nLgoKICAgIGVycm9ybGV2ZWwgPSAwICAgICAgICAgICAgICAjIElmIDAsIGZhdGFsIGVycm9ycyBvbmx5IGFwcGVhciBpbiBkZWJ1ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVzc2FnZXMgKGlmIGRlYnVnID49IDApLiBJZiA+IDAsIGVycm9ycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIGFzIGV4Y2VwdGlvbnMuCgogICAgcG9zaXggPSBGYWxzZSAgICAgICAgICAgICAgICMgSWYgVHJ1ZSwgZ2VuZXJhdGVzIFBPU0lYLjEtMTk5MC1jb21wbGlhbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmVzIChubyBHTlUgZXh0ZW5zaW9ucyEpCgogICAgZmlsZW9iamVjdCA9IEV4RmlsZU9iamVjdAoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gYW4gKHVuY29tcHJlc3NlZCkgdGFyIGFyY2hpdmUgYG5hbWUnLiBgbW9kZScgaXMgZWl0aGVyICdyJyB0bwogICAgICAgICAgIHJlYWQgZnJvbSBhbiBleGlzdGluZyBhcmNoaXZlLCAnYScgdG8gYXBwZW5kIGRhdGEgdG8gYW4gZXhpc3RpbmcKICAgICAgICAgICBmaWxlIG9yICd3JyB0byBjcmVhdGUgYSBuZXcgZmlsZSBvdmVyd3JpdGluZyBhbiBleGlzdGluZyBvbmUuIGBtb2RlJwogICAgICAgICAgIGRlZmF1bHRzIHRvICdyJy4KICAgICAgICAgICBJZiBgZmlsZW9iaicgaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgZm9yIHJlYWRpbmcgb3Igd3JpdGluZyBkYXRhLiBJZiBpdAogICAgICAgICAgIGNhbiBiZSBkZXRlcm1pbmVkLCBgbW9kZScgaXMgb3ZlcnJpZGRlbiBieSBgZmlsZW9iaidzIG1vZGUuCiAgICAgICAgICAgYGZpbGVvYmonIGlzIG5vdCBjbG9zZWQsIHdoZW4gVGFyRmlsZSBpcyBjbG9zZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5uYW1lID0gbmFtZQoKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIKICAgICAgICBzZWxmLl9tb2RlID0gbW9kZQogICAgICAgIHNlbGYubW9kZSA9IHsiciI6ICJyYiIsICJhIjogInIrYiIsICJ3IjogIndiIn1bbW9kZV0KCiAgICAgICAgaWYgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKHNlbGYubmFtZSwgc2VsZi5tb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBzZWxmLm5hbWUgaXMgTm9uZSBhbmQgaGFzYXR0cihmaWxlb2JqLCAibmFtZSIpOgogICAgICAgICAgICAgICAgc2VsZi5uYW1lID0gZmlsZW9iai5uYW1lCiAgICAgICAgICAgIGlmIGhhc2F0dHIoZmlsZW9iaiwgIm1vZGUiKToKICAgICAgICAgICAgICAgIHNlbGYubW9kZSA9IGZpbGVvYmoubW9kZQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKCiAgICAgICAgIyBJbml0IGRhdGFzdHJ1Y3R1cmVzCiAgICAgICAgc2VsZi5jbG9zZWQgICAgICA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzICAgICA9IFtdICAgICAgICMgbGlzdCBvZiBtZW1iZXJzIGFzIFRhckluZm8gb2JqZWN0cwogICAgICAgIHNlbGYuX2xvYWRlZCAgICAgPSBGYWxzZSAgICAjIGZsYWcgaWYgYWxsIG1lbWJlcnMgaGF2ZSBiZWVuIHJlYWQKICAgICAgICBzZWxmLm9mZnNldCAgICAgID0gMEwgICAgICAgIyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBhcmNoaXZlIGZpbGUKICAgICAgICBzZWxmLmlub2RlcyAgICAgID0ge30gICAgICAgIyBkaWN0aW9uYXJ5IGNhY2hpbmcgdGhlIGlub2RlcyBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyY2hpdmUgbWVtYmVycyBhbHJlYWR5IGFkZGVkCgogICAgICAgIGlmIHNlbGYuX21vZGUgPT0gInIiOgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gc2VsZi5uZXh0KCkKCiAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiYSI6CiAgICAgICAgICAgICMgTW92ZSB0byB0aGUgZW5kIG9mIHRoZSBhcmNoaXZlLAogICAgICAgICAgICAjIGJlZm9yZSB0aGUgZmlyc3QgZW1wdHkgYmxvY2suCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgICAgICBleGNlcHQgUmVhZEVycm9yOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKDApCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygtIEJMT0NLU0laRSwgMSkKICAgICAgICAgICAgICAgICAgICBicmVhawoKICAgICAgICBpZiBzZWxmLl9tb2RlIGluICJhdyI6CiAgICAgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHRoZSBjbGFzc21ldGhvZHMgd2hpY2ggYWN0IGFzIGFsdGVybmF0ZSBjb25zdHJ1Y3RvcnMgdG8gdGhlCiAgICAjIFRhckZpbGUgY2xhc3MuIFRoZSBvcGVuKCkgbWV0aG9kIGlzIHRoZSBvbmx5IG9uZSB0aGF0IGlzIG5lZWRlZCBmb3IKICAgICMgcHVibGljIHVzZTsgaXQgaXMgdGhlICJzdXBlciItY29uc3RydWN0b3IgYW5kIGlzIGFibGUgdG8gc2VsZWN0IGFuCiAgICAjIGFkZXF1YXRlICJzdWIiLWNvbnN0cnVjdG9yIGZvciBhIHBhcnRpY3VsYXIgY29tcHJlc3Npb24gdXNpbmcgdGhlIG1hcHBpbmcKICAgICMgZnJvbSBPUEVOX01FVEguCiAgICAjCiAgICAjIFRoaXMgY29uY2VwdCBhbGxvd3Mgb25lIHRvIHN1YmNsYXNzIFRhckZpbGUgd2l0aG91dCBsb3NpbmcgdGhlIGNvbWZvcnQgb2YKICAgICMgdGhlIHN1cGVyLWNvbnN0cnVjdG9yLiBBIHN1Yi1jb25zdHJ1Y3RvciBpcyByZWdpc3RlcmVkIGFuZCBtYWRlIGF2YWlsYWJsZQogICAgIyBieSBhZGRpbmcgaXQgdG8gdGhlIG1hcHBpbmcgaW4gT1BFTl9NRVRILgoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIG9wZW4oY2xzLCBuYW1lPU5vbmUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGJ1ZnNpemU9MjAqNTEyKToKICAgICAgICAiIiJPcGVuIGEgdGFyIGFyY2hpdmUgZm9yIHJlYWRpbmcsIHdyaXRpbmcgb3IgYXBwZW5kaW5nLiBSZXR1cm4KICAgICAgICAgICBhbiBhcHByb3ByaWF0ZSBUYXJGaWxlIGNsYXNzLgoKICAgICAgICAgICBtb2RlOgogICAgICAgICAgICdyJyBvciAncjoqJyBvcGVuIGZvciByZWFkaW5nIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncjonICAgICAgICAgb3BlbiBmb3IgcmVhZGluZyBleGNsdXNpdmVseSB1bmNvbXByZXNzZWQKICAgICAgICAgICAncjpneicgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAncjpiejInICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ2EnIG9yICdhOicgIG9wZW4gZm9yIGFwcGVuZGluZwogICAgICAgICAgICd3JyBvciAndzonICBvcGVuIGZvciB3cml0aW5nIHdpdGhvdXQgY29tcHJlc3Npb24KICAgICAgICAgICAndzpneicgICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAndzpiejInICAgICAgb3BlbiBmb3Igd3JpdGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCgogICAgICAgICAgICdyfConICAgICAgICBvcGVuIGEgc3RyZWFtIG9mIHRhciBibG9ja3Mgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyfCcgICAgICAgICBvcGVuIGFuIHVuY29tcHJlc3NlZCBzdHJlYW0gb2YgdGFyIGJsb2NrcyBmb3IgcmVhZGluZwogICAgICAgICAgICdyfGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzCiAgICAgICAgICAgJ3J8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzCiAgICAgICAgICAgJ3d8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICAgICd3fGd6JyAgICAgICBvcGVuIGEgZ3ppcCBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICAgICd3fGJ6MicgICAgICBvcGVuIGEgYnppcDIgY29tcHJlc3NlZCBzdHJlYW0gZm9yIHdyaXRpbmcKICAgICAgICAiIiIKCiAgICAgICAgaWYgbm90IG5hbWUgYW5kIG5vdCBmaWxlb2JqOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibm90aGluZyB0byBvcGVuIgoKICAgICAgICBpZiBtb2RlIGluICgiciIsICJyOioiKToKICAgICAgICAgICAgIyBGaW5kIG91dCB3aGljaCAqb3BlbigpIGlzIGFwcHJvcHJpYXRlIGZvciBvcGVuaW5nIHRoZSBmaWxlLgogICAgICAgICAgICBmb3IgY29tcHR5cGUgaW4gY2xzLk9QRU5fTUVUSDoKICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMobmFtZSwgInIiLCBmaWxlb2JqKQogICAgICAgICAgICAgICAgZXhjZXB0IChSZWFkRXJyb3IsIENvbXByZXNzaW9uRXJyb3IpOgogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvciwgImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiCgogICAgICAgIGVsaWYgIjoiIGluIG1vZGU6CiAgICAgICAgICAgIGZpbGVtb2RlLCBjb21wdHlwZSA9IG1vZGUuc3BsaXQoIjoiLCAxKQogICAgICAgICAgICBmaWxlbW9kZSA9IGZpbGVtb2RlIG9yICJyIgogICAgICAgICAgICBjb21wdHlwZSA9IGNvbXB0eXBlIG9yICJ0YXIiCgogICAgICAgICAgICAjIFNlbGVjdCB0aGUgKm9wZW4oKSBmdW5jdGlvbiBhY2NvcmRpbmcgdG8KICAgICAgICAgICAgIyBnaXZlbiBjb21wcmVzc2lvbi4KICAgICAgICAgICAgaWYgY29tcHR5cGUgaW4gY2xzLk9QRU5fTUVUSDoKICAgICAgICAgICAgICAgIGZ1bmMgPSBnZXRhdHRyKGNscywgY2xzLk9QRU5fTUVUSFtjb21wdHlwZV0pCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yLCAidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlCiAgICAgICAgICAgIHJldHVybiBmdW5jKG5hbWUsIGZpbGVtb2RlLCBmaWxlb2JqKQoKICAgICAgICBlbGlmICJ8IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCJ8IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICJydyI6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJyBvciAndyciCgogICAgICAgICAgICB0ID0gY2xzKG5hbWUsIGZpbGVtb2RlLAogICAgICAgICAgICAgICAgICAgIF9TdHJlYW0obmFtZSwgZmlsZW1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKSkKICAgICAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgICAgIHJldHVybiB0CgogICAgICAgIGVsaWYgbW9kZSBpbiAiYXciOgogICAgICAgICAgICByZXR1cm4gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwgZmlsZW9iaikKCiAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgInVuZGlzY2VybmlibGUgbW9kZSIKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiB0YXJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiB1bmNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJhdyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIgogICAgICAgIHJldHVybiBjbHMobmFtZSwgbW9kZSwgZmlsZW9iaikKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBnem9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTkpOgogICAgICAgICIiIk9wZW4gZ3ppcCBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJyBvciAndyciCgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IGd6aXAKICAgICAgICAgICAgZ3ppcC5HemlwRmlsZQogICAgICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvciwgImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCgogICAgICAgIHByZSwgZXh0ID0gb3MucGF0aC5zcGxpdGV4dChuYW1lKQogICAgICAgIHByZSA9IG9zLnBhdGguYmFzZW5hbWUocHJlKQogICAgICAgIGlmIGV4dCA9PSAiLnRneiI6CiAgICAgICAgICAgIGV4dCA9ICIudGFyIgogICAgICAgIGlmIGV4dCA9PSAiLmd6IjoKICAgICAgICAgICAgZXh0ID0gIiIKICAgICAgICB0YXJuYW1lID0gcHJlICsgZXh0CgogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IGZpbGUobmFtZSwgbW9kZSArICJiIikKCiAgICAgICAgaWYgbW9kZSAhPSAiciI6CiAgICAgICAgICAgIG5hbWUgPSB0YXJuYW1lCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKHRhcm5hbWUsIG1vZGUsCiAgICAgICAgICAgICAgICBnemlwLkd6aXBGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWwsIGZpbGVvYmopCiAgICAgICAgICAgICkKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAibm90IGEgZ3ppcCBmaWxlIgogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgYnoyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSk6CiAgICAgICAgIiIiT3BlbiBiemlwMiBjb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAgICBBcHBlbmRpbmcgaXMgbm90IGFsbG93ZWQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibW9kZSBtdXN0IGJlICdyJyBvciAndycuIgoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBiejIKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IsICJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiCgogICAgICAgIHByZSwgZXh0ID0gb3MucGF0aC5zcGxpdGV4dChuYW1lKQogICAgICAgIHByZSA9IG9zLnBhdGguYmFzZW5hbWUocHJlKQogICAgICAgIGlmIGV4dCA9PSAiLnRiejIiOgogICAgICAgICAgICBleHQgPSAiLnRhciIKICAgICAgICBpZiBleHQgPT0gIi5iejIiOgogICAgICAgICAgICBleHQgPSAiIgogICAgICAgIHRhcm5hbWUgPSBwcmUgKyBleHQKCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgIm5vIHN1cHBvcnQgZm9yIGV4dGVybmFsIGZpbGUgb2JqZWN0cyIKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4odGFybmFtZSwgbW9kZSwgYnoyLkJaMkZpbGUobmFtZSwgbW9kZSwgY29tcHJlc3NsZXZlbD1jb21wcmVzc2xldmVsKSkKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCAibm90IGEgYnppcDIgZmlsZSIKICAgICAgICB0Ll9leHRmaWxlb2JqID0gRmFsc2UKICAgICAgICByZXR1cm4gdAoKICAgICMgQWxsICpvcGVuKCkgbWV0aG9kcyBhcmUgcmVnaXN0ZXJlZCBoZXJlLgogICAgT1BFTl9NRVRIID0gewogICAgICAgICJ0YXIiOiAidGFyb3BlbiIsICAgIyB1bmNvbXByZXNzZWQgdGFyCiAgICAgICAgImd6IjogICJnem9wZW4iLCAgICAjIGd6aXAgY29tcHJlc3NlZCB0YXIKICAgICAgICAiYnoyIjogImJ6Mm9wZW4iICAgICMgYnppcDIgY29tcHJlc3NlZCB0YXIKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgVGhlIHB1YmxpYyBtZXRob2RzIHdoaWNoIFRhckZpbGUgcHJvdmlkZXM6CgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgICIiIkNsb3NlIHRoZSBUYXJGaWxlLiBJbiB3cml0ZS1tb2RlLCB0d28gZmluaXNoaW5nIHplcm8gYmxvY2tzIGFyZQogICAgICAgICAgIGFwcGVuZGVkIHRvIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5fbW9kZSBpbiAiYXciOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAqIDIpKQogICAgICAgICAgICBzZWxmLm9mZnNldCArPSAoQkxPQ0tTSVpFICogMikKICAgICAgICAgICAgIyBmaWxsIHVwIHRoZSBlbmQgd2l0aCB6ZXJvLWJsb2NrcwogICAgICAgICAgICAjIChsaWtlIG9wdGlvbiAtYjIwIGZvciB0YXIgZG9lcykKICAgICAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2Qoc2VsZi5vZmZzZXQsIFJFQ09SRFNJWkUpCiAgICAgICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKFJFQ09SRFNJWkUgLSByZW1haW5kZXIpKQoKICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKCiAgICBkZWYgZ2V0bWVtYmVyKHNlbGYsIG5hbWUpOgogICAgICAgICIiIlJldHVybiBhIFRhckluZm8gb2JqZWN0IGZvciBtZW1iZXIgYG5hbWUnLiBJZiBgbmFtZScgY2FuIG5vdCBiZQogICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlCiAgICAgICAgICAgdGhhbiBvbmNlIGluIHRoZSBhcmNoaXZlLCBpdHMgbGFzdCBvY2N1cmVuY2UgaXMgYXNzdW1lZCB0byBiZSB0aGUKICAgICAgICAgICBtb3N0IHVwLXRvLWRhdGUgdmVyc2lvbi4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvID0gc2VsZi5fZ2V0bWVtYmVyKG5hbWUpCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBLZXlFcnJvciwgImZpbGVuYW1lICVyIG5vdCBmb3VuZCIgJSBuYW1lCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgZ2V0bWVtYmVycyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIFRhckluZm8gb2JqZWN0cy4gVGhlCiAgICAgICAgICAgbGlzdCBoYXMgdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG1lbWJlcnMgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soKQogICAgICAgIGlmIG5vdCBzZWxmLl9sb2FkZWQ6ICAgICMgaWYgd2Ugd2FudCB0byBvYnRhaW4gYSBsaXN0IG9mCiAgICAgICAgICAgIHNlbGYuX2xvYWQoKSAgICAgICAgIyBhbGwgbWVtYmVycywgd2UgZmlyc3QgaGF2ZSB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2NhbiB0aGUgd2hvbGUgYXJjaGl2ZS4KICAgICAgICByZXR1cm4gc2VsZi5tZW1iZXJzCgogICAgZGVmIGdldG5hbWVzKHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbWVtYmVycyBvZiB0aGUgYXJjaGl2ZSBhcyBhIGxpc3Qgb2YgdGhlaXIgbmFtZXMuIEl0IGhhcwogICAgICAgICAgIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gW3RhcmluZm8ubmFtZSBmb3IgdGFyaW5mbyBpbiBzZWxmLmdldG1lbWJlcnMoKV0KCiAgICBkZWYgZ2V0dGFyaW5mbyhzZWxmLCBuYW1lPU5vbmUsIGFyY25hbWU9Tm9uZSwgZmlsZW9iaj1Ob25lKToKICAgICAgICAiIiJDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmb3IgZWl0aGVyIHRoZSBmaWxlIGBuYW1lJyBvciB0aGUgZmlsZQogICAgICAgICAgIG9iamVjdCBgZmlsZW9iaicgKHVzaW5nIG9zLmZzdGF0IG9uIGl0cyBmaWxlIGRlc2NyaXB0b3IpLiBZb3UgY2FuCiAgICAgICAgICAgbW9kaWZ5IHNvbWUgb2YgdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGJlZm9yZSB5b3UgYWRkIGl0IHVzaW5nCiAgICAgICAgICAgYWRkZmlsZSgpLiBJZiBnaXZlbiwgYGFyY25hbWUnIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUKICAgICAgICAgICBmaWxlIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQoKICAgICAgICAjIEJ1aWxkaW5nIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4KICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCiAgICAgICAgYXJjbmFtZSA9IG5vcm1wYXRoKGFyY25hbWUpCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpCiAgICAgICAgd2hpbGUgYXJjbmFtZVswOjFdID09ICIvIjoKICAgICAgICAgICAgYXJjbmFtZSA9IGFyY25hbWVbMTpdCgogICAgICAgICMgTm93LCBmaWxsIHRoZSBUYXJJbmZvIG9iamVjdCB3aXRoCiAgICAgICAgIyBpbmZvcm1hdGlvbiBzcGVjaWZpYyBmb3IgdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IFRhckluZm8oKQoKICAgICAgICAjIFVzZSBvcy5zdGF0IG9yIG9zLmxzdGF0LCBkZXBlbmRpbmcgb24gcGxhdGZvcm0KICAgICAgICAjIGFuZCBpZiBzeW1saW5rcyBzaGFsbCBiZSByZXNvbHZlZC4KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJsc3RhdCIpIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5sc3RhdChuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLnN0YXQobmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkKICAgICAgICBsaW5rbmFtZSA9ICIiCgogICAgICAgIHN0bWQgPSBzdGF0cmVzLnN0X21vZGUKICAgICAgICBpZiBzdGF0LlNfSVNSRUcoc3RtZCk6CiAgICAgICAgICAgIGlub2RlID0gKHN0YXRyZXMuc3RfaW5vLCBzdGF0cmVzLnN0X2RldikKICAgICAgICAgICAgaWYgbm90IHNlbGYuZGVyZWZlcmVuY2UgYW5kIFwKICAgICAgICAgICAgICAgICAgICBzdGF0cmVzLnN0X25saW5rID4gMSBhbmQgaW5vZGUgaW4gc2VsZi5pbm9kZXM6CiAgICAgICAgICAgICAgICAjIElzIGl0IGEgaGFyZGxpbmsgdG8gYW4gYWxyZWFkeQogICAgICAgICAgICAgICAgIyBhcmNoaXZlZCBmaWxlPwogICAgICAgICAgICAgICAgdHlwZSA9IExOS1RZUEUKICAgICAgICAgICAgICAgIGxpbmtuYW1lID0gc2VsZi5pbm9kZXNbaW5vZGVdCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFRoZSBpbm9kZSBpcyBhZGRlZCBvbmx5IGlmIGl0cyB2YWxpZC4KICAgICAgICAgICAgICAgICMgRm9yIHdpbjMyIGl0IGlzIGFsd2F5cyAwLgogICAgICAgICAgICAgICAgdHlwZSA9IFJFR1RZUEUKICAgICAgICAgICAgICAgIGlmIGlub2RlWzBdOgogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5vZGVzW2lub2RlXSA9IGFyY25hbWUKICAgICAgICBlbGlmIHN0YXQuU19JU0RJUihzdG1kKToKICAgICAgICAgICAgdHlwZSA9IERJUlRZUEUKICAgICAgICAgICAgaWYgYXJjbmFtZVstMTpdICE9ICIvIjoKICAgICAgICAgICAgICAgIGFyY25hbWUgKz0gIi8iCiAgICAgICAgZWxpZiBzdGF0LlNfSVNGSUZPKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRklGT1RZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0xOSyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IFNZTVRZUEUKICAgICAgICAgICAgbGlua25hbWUgPSBvcy5yZWFkbGluayhuYW1lKQogICAgICAgIGVsaWYgc3RhdC5TX0lTQ0hSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQ0hSVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTQkxLKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQkxLVFlQRQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICMgRmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCBhbGwKICAgICAgICAjIGluZm9ybWF0aW9uIHdlIGNhbiBnZXQuCiAgICAgICAgdGFyaW5mby5uYW1lID0gYXJjbmFtZQogICAgICAgIHRhcmluZm8ubW9kZSA9IHN0bWQKICAgICAgICB0YXJpbmZvLnVpZCA9IHN0YXRyZXMuc3RfdWlkCiAgICAgICAgdGFyaW5mby5naWQgPSBzdGF0cmVzLnN0X2dpZAogICAgICAgIGlmIHN0YXQuU19JU1JFRyhzdG1kKToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gc3RhdHJlcy5zdF9zaXplCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMEwKICAgICAgICB0YXJpbmZvLm10aW1lID0gc3RhdHJlcy5zdF9tdGltZQogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbGlua25hbWUKICAgICAgICBpZiBwd2Q6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8udW5hbWUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBpZiBncnA6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgaWYgdHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSk6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJtYWpvciIpIGFuZCBoYXNhdHRyKG9zLCAibWlub3IiKToKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSBvcy5tYWpvcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gb3MubWlub3Ioc3RhdHJlcy5zdF9yZGV2KQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGxpc3Qoc2VsZiwgdmVyYm9zZT1UcnVlKToKICAgICAgICAiIiJQcmludCBhIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN5cy5zdGRvdXQuIElmIGB2ZXJib3NlJyBpcyBGYWxzZSwgb25seQogICAgICAgICAgIHRoZSBuYW1lcyBvZiB0aGUgbWVtYmVycyBhcmUgcHJpbnRlZC4gSWYgaXQgaXMgVHJ1ZSwgYW4gYGxzIC1sJy1saWtlCiAgICAgICAgICAgb3V0cHV0IGlzIHByb2R1Y2VkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZjoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIHByaW50IGZpbGVtb2RlKHRhcmluZm8ubW9kZSksCiAgICAgICAgICAgICAgICBwcmludCAiJXMvJXMiICUgKHRhcmluZm8udW5hbWUgb3IgdGFyaW5mby51aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgb3IgdGFyaW5mby5naWQpLAogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwcyIgJSAoIiVkLCVkIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgKHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKSwKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMGQiICUgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgcHJpbnQgIiVkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCIgXAogICAgICAgICAgICAgICAgICAgICAgJSB0aW1lLmxvY2FsdGltZSh0YXJpbmZvLm10aW1lKVs6Nl0sCgogICAgICAgICAgICBwcmludCB0YXJpbmZvLm5hbWUsCgogICAgICAgICAgICBpZiB2ZXJib3NlOgogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICItPiIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgImxpbmsgdG8iLCB0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICBwcmludAoKICAgIGRlZiBhZGQoc2VsZiwgbmFtZSwgYXJjbmFtZT1Ob25lLCByZWN1cnNpdmU9VHJ1ZSk6CiAgICAgICAgIiIiQWRkIHRoZSBmaWxlIGBuYW1lJyB0byB0aGUgYXJjaGl2ZS4gYG5hbWUnIG1heSBiZSBhbnkgdHlwZSBvZiBmaWxlCiAgICAgICAgICAgKGRpcmVjdG9yeSwgZmlmbywgc3ltYm9saWMgbGluaywgZXRjLikuIElmIGdpdmVuLCBgYXJjbmFtZScKICAgICAgICAgICBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgRGlyZWN0b3JpZXMgYXJlIGFkZGVkIHJlY3Vyc2l2ZWx5IGJ5IGRlZmF1bHQuIFRoaXMgY2FuIGJlIGF2b2lkZWQgYnkKICAgICAgICAgICBzZXR0aW5nIGByZWN1cnNpdmUnIHRvIEZhbHNlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKCiAgICAgICAgIyBTa2lwIGlmIHNvbWVib2R5IHRyaWVzIHRvIGFyY2hpdmUgdGhlIGFyY2hpdmUuLi4KICAgICAgICBpZiBzZWxmLm5hbWUgaXMgbm90IE5vbmUgXAogICAgICAgICAgICBhbmQgb3MucGF0aC5hYnNwYXRoKG5hbWUpID09IG9zLnBhdGguYWJzcGF0aChzZWxmLm5hbWUpOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IFNraXBwZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU3BlY2lhbCBjYXNlOiBUaGUgdXNlciB3YW50cyB0byBhZGQgdGhlIGN1cnJlbnQKICAgICAgICAjIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICAgIGlmIG5hbWUgPT0gIi4iOgogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBpZiBhcmNuYW1lID09ICIuIjoKICAgICAgICAgICAgICAgICAgICBhcmNuYW1lID0gIiIKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIoIi4iKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChmLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkKCiAgICAgICAgIyBDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQXBwZW5kIHRoZSB0YXIgaGVhZGVyIGFuZCBkYXRhIHRvIHRoZSBhcmNoaXZlLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgZiA9IGZpbGUobmFtZSwgInJiIikKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8sIGYpCiAgICAgICAgICAgIGYuY2xvc2UoKQoKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQob3MucGF0aC5qb2luKG5hbWUsIGYpLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQoKICAgIGRlZiBhZGRmaWxlKHNlbGYsIHRhcmluZm8sIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQWRkIHRoZSBUYXJJbmZvIG9iamVjdCBgdGFyaW5mbycgdG8gdGhlIGFyY2hpdmUuIElmIGBmaWxlb2JqJyBpcwogICAgICAgICAgIGdpdmVuLCB0YXJpbmZvLnNpemUgYnl0ZXMgYXJlIHJlYWQgZnJvbSBpdCBhbmQgYWRkZWQgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgWW91IGNhbiBjcmVhdGUgVGFySW5mbyBvYmplY3RzIHVzaW5nIGdldHRhcmluZm8oKS4KICAgICAgICAgICBPbiBXaW5kb3dzIHBsYXRmb3JtcywgYGZpbGVvYmonIHNob3VsZCBhbHdheXMgYmUgb3BlbmVkIHdpdGggbW9kZQogICAgICAgICAgICdyYicgdG8gYXZvaWQgaXJyaXRhdGlvbiBhYm91dCB0aGUgZmlsZSBzaXplLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIHRhcmluZm8ubmFtZSA9IG5vcm1wYXRoKHRhcmluZm8ubmFtZSkKICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgICMgZGlyZWN0b3JpZXMgc2hvdWxkIGVuZCB3aXRoICcvJwogICAgICAgICAgICB0YXJpbmZvLm5hbWUgKz0gIi8iCgogICAgICAgIGlmIHRhcmluZm8ubGlua25hbWU6CiAgICAgICAgICAgIHRhcmluZm8ubGlua25hbWUgPSBub3JtcGF0aCh0YXJpbmZvLmxpbmtuYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLnNpemUgPiBNQVhTSVpFX01FTUJFUjoKICAgICAgICAgICAgaWYgc2VsZi5wb3NpeDoKICAgICAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IsICJmaWxlIGlzIHRvbyBsYXJnZSAoPj0gOCBHQikiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IENyZWF0ZWQgR05VIHRhciBsYXJnZWZpbGUgaGVhZGVyIikKCgogICAgICAgIGlmIGxlbih0YXJpbmZvLmxpbmtuYW1lKSA+IExFTkdUSF9MSU5LOgogICAgICAgICAgICBpZiBzZWxmLnBvc2l4OgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvciwgImxpbmtuYW1lIGlzIHRvbyBsb25nICg+JWQpIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlIChMRU5HVEhfTElOSykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2NyZWF0ZV9nbnVsb25nKHRhcmluZm8ubGlua25hbWUsIEdOVVRZUEVfTE9OR0xJTkspCiAgICAgICAgICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gdGFyaW5mby5saW5rbmFtZVs6TEVOR1RIX0xJTksgLTFdCiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IENyZWF0ZWQgR05VIHRhciBleHRlbnNpb24gTE9OR0xJTksiKQoKICAgICAgICBpZiBsZW4odGFyaW5mby5uYW1lKSA+IExFTkdUSF9OQU1FOgogICAgICAgICAgICBpZiBzZWxmLnBvc2l4OgogICAgICAgICAgICAgICAgcHJlZml4ID0gdGFyaW5mby5uYW1lWzpMRU5HVEhfUFJFRklYICsgMV0KICAgICAgICAgICAgICAgIHdoaWxlIHByZWZpeCBhbmQgcHJlZml4Wy0xXSAhPSAiLyI6CiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBuYW1lID0gdGFyaW5mby5uYW1lW2xlbihwcmVmaXgpOl0KICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgICAgICAgICAgaWYgbm90IHByZWZpeCBvciBsZW4obmFtZSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAibmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgKExFTkdUSF9OQU1FKQoKICAgICAgICAgICAgICAgIHRhcmluZm8ubmFtZSAgID0gbmFtZQogICAgICAgICAgICAgICAgdGFyaW5mby5wcmVmaXggPSBwcmVmaXgKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2NyZWF0ZV9nbnVsb25nKHRhcmluZm8ubmFtZSwgR05VVFlQRV9MT05HTkFNRSkKICAgICAgICAgICAgICAgIHRhcmluZm8ubmFtZSA9IHRhcmluZm8ubmFtZVs6TEVOR1RIX05BTUUgLSAxXQogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBDcmVhdGVkIEdOVSB0YXIgZXh0ZW5zaW9uIExPTkdOQU1FIikKCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHRhcmluZm8udG9idWYoKSkKICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKCiAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToKICAgICAgICAiIiJFeHRyYWN0IGFsbCBtZW1iZXJzIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZwogICAgICAgICAgIGRpcmVjdG9yeSBhbmQgc2V0IG93bmVyLCBtb2RpZmljYXRpb24gdGltZSBhbmQgcGVybWlzc2lvbnMgb24KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQogICAgICAgICAgIHRvIGV4dHJhY3QgdG8uIGBtZW1iZXJzJyBpcyBvcHRpb25hbCBhbmQgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUKICAgICAgICAgICBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICBkaXJlY3RvcmllcyA9IFtdCgogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAgICAgIyBFeHRyYWN0IGRpcmVjdG9yeSB3aXRoIGEgc2FmZSBtb2RlLCBzbyB0aGF0CiAgICAgICAgICAgICAgICAjIGFsbCBmaWxlcyBiZWxvdyBjYW4gYmUgZXh0cmFjdGVkIGFzIHdlbGwuCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb3MubWFrZWRpcnMob3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSksIDA3NzcpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvcjoKICAgICAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5hcHBlbmQodGFyaW5mbykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuZXh0cmFjdCh0YXJpbmZvLCBwYXRoKQoKICAgICAgICAjIFJldmVyc2Ugc29ydCBkaXJlY3Rvcmllcy4KICAgICAgICBkaXJlY3Rvcmllcy5zb3J0KGxhbWJkYSBhLCBiOiBjbXAoYS5uYW1lLCBiLm5hbWUpKQogICAgICAgIGRpcmVjdG9yaWVzLnJldmVyc2UoKQoKICAgICAgICAjIFNldCBjb3JyZWN0IG93bmVyLCBtdGltZSBhbmQgZmlsZW1vZGUgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yIHRhcmluZm8gaW4gZGlyZWN0b3JpZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwKICAgICAgICAgICB1c2luZyBpdHMgZnVsbCBuYW1lLiBJdHMgZmlsZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQgYXMgYWNjdXJhdGVseQogICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIFRhckluZm8pOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4KICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgIHRhcmluZm8uX2xpbmtfdGFyZ2V0ID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZS5zdHJlcnJvcikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCiAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3RmaWxlKHNlbGYsIG1lbWJlcik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQogICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKICAgICAgICAgICBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZiBgbWVtYmVyJyBpcyBhIGxpbmssIGEgZmlsZS1saWtlCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YKICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCiAgICAgICAgICAgVGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgcmVhZC1vbmx5IGFuZCBwcm92aWRlcyB0aGUgZm9sbG93aW5nCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkKICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUuCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6CiAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCiAgICAgICAgICAgICAgICAjIHRvIGV4dHJhY3QgYSAoc3ltKWxpbmsgYXMgYSBmaWxlLW9iamVjdCBmcm9tIGEgbm9uLXNlZWthYmxlCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLgogICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IsICJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXRzIHRhcmdldCdzIGZpbGUgb2JqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXh0cmFjdGZpbGUoc2VsZi5fZ2V0bWVtYmVyKHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIGlmIHRhcmdldHBhdGhbLTE6XSA9PSAiLyI6CiAgICAgICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoWzotMV0KICAgICAgICB0YXJnZXRwYXRoID0gb3MucGF0aC5ub3JtcGF0aCh0YXJnZXRwYXRoKQoKICAgICAgICAjIENyZWF0ZSBhbGwgdXBwZXIgZGlyZWN0b3JpZXMuCiAgICAgICAgdXBwZXJkaXJzID0gb3MucGF0aC5kaXJuYW1lKHRhcmdldHBhdGgpCiAgICAgICAgaWYgdXBwZXJkaXJzIGFuZCBub3Qgb3MucGF0aC5leGlzdHModXBwZXJkaXJzKToKICAgICAgICAgICAgdGkgPSBUYXJJbmZvKCkKICAgICAgICAgICAgdGkubmFtZSAgPSB1cHBlcmRpcnMKICAgICAgICAgICAgdGkudHlwZSAgPSBESVJUWVBFCiAgICAgICAgICAgIHRpLm1vZGUgID0gMDc3NwogICAgICAgICAgICB0aS5tdGltZSA9IHRhcmluZm8ubXRpbWUKICAgICAgICAgICAgdGkudWlkICAgPSB0YXJpbmZvLnVpZAogICAgICAgICAgICB0aS5naWQgICA9IHRhcmluZm8uZ2lkCiAgICAgICAgICAgIHRpLnVuYW1lID0gdGFyaW5mby51bmFtZQogICAgICAgICAgICB0aS5nbmFtZSA9IHRhcmluZm8uZ25hbWUKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGksIHRpLm5hbWUpCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICIlcyAtPiAlcyIgJSAodGFyaW5mby5uYW1lLCB0YXJpbmZvLmxpbmtuYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGlyKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWZvKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWxpbmsodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICBzZWxmLm1ha2V1bmtub3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgZGlmZmVyZW50IGZpbGUgbWV0aG9kcy4gVGhleSBhcmUgY2FsbGVkIHZpYQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKICAgICMgc3ViY2xhc3MgdG8gaW1wbGVtZW50IG90aGVyIGZ1bmN0aW9uYWxpdHkuCgogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGRpcmVjdG9yeSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLm1rZGlyKHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIGUuZXJybm8gIT0gZXJybm8uRUVYSVNUOgogICAgICAgICAgICAgICAgcmFpc2UKCiAgICBkZWYgbWFrZWZpbGUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgc291cmNlID0gc2VsZi5leHRyYWN0ZmlsZSh0YXJpbmZvKQogICAgICAgIHRhcmdldCA9IGZpbGUodGFyZ2V0cGF0aCwgIndiIikKICAgICAgICBjb3B5ZmlsZW9iaihzb3VyY2UsIHRhcmdldCkKICAgICAgICBzb3VyY2UuY2xvc2UoKQogICAgICAgIHRhcmdldC5jbG9zZSgpCgogICAgZGVmIG1ha2V1bmtub3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGZyb20gYSBUYXJJbmZvIG9iamVjdCB3aXRoIGFuIHVua25vd24gdHlwZQogICAgICAgICAgIGF0IHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5rbm93biBmaWxlIHR5cGUgJXIsICIgXAogICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdGVkIGFzIHJlZ3VsYXIgZmlsZS4iICUgdGFyaW5mby50eXBlKQoKICAgIGRlZiBtYWtlZmlmbyhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlmbyBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAibWtmaWZvIik6CiAgICAgICAgICAgIG9zLm1rZmlmbyh0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iCgogICAgZGVmIG1ha2VkZXYoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGNoYXJhY3RlciBvciBibG9jayBkZXZpY2UgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICJta25vZCIpIG9yIG5vdCBoYXNhdHRyKG9zLCAibWFrZWRldiIpOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iCgogICAgICAgIG1vZGUgPSB0YXJpbmZvLm1vZGUKICAgICAgICBpZiB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQkxLCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZDSFIKCiAgICAgICAgb3MubWtub2QodGFyZ2V0cGF0aCwgbW9kZSwKICAgICAgICAgICAgICAgICBvcy5tYWtlZGV2KHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKQoKICAgIGRlZiBtYWtlbGluayhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgKHN5bWJvbGljKSBsaW5rIGNhbGxlZCB0YXJnZXRwYXRoLiBJZiBpdCBjYW5ub3QgYmUgY3JlYXRlZAogICAgICAgICAgKHBsYXRmb3JtIGxpbWl0YXRpb24pLCB3ZSB0cnkgdG8gbWFrZSBhIGNvcHkgb2YgdGhlIHJlZmVyZW5jZWQgZmlsZQogICAgICAgICAgaW5zdGVhZCBvZiBhIGxpbmsuCiAgICAgICAgIiIiCiAgICAgICAgbGlua3BhdGggPSB0YXJpbmZvLmxpbmtuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBTZWUgZXh0cmFjdCgpLgogICAgICAgICAgICAgICAgb3MubGluayh0YXJpbmZvLl9saW5rX3RhcmdldCwgdGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5qb2luKG9zLnBhdGguZGlybmFtZSh0YXJpbmZvLm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua3BhdGgpCiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG5vcm1wYXRoKGxpbmtwYXRoKQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIoc2VsZi5nZXRtZW1iZXIobGlua3BhdGgpLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBleGNlcHQgKEVudmlyb25tZW50RXJyb3IsIEtleUVycm9yKSwgZToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5ub3JtcGF0aChsaW5rcGF0aCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBzaHV0aWwuY29weTIobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAibGluayBjb3VsZCBub3QgYmUgY3JlYXRlZCIKCiAgICBkZWYgY2hvd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG93bmVyIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcHdkIGFuZCBoYXNhdHRyKG9zLCAiZ2V0ZXVpZCIpIGFuZCBvcy5nZXRldWlkKCkgPT0gMDoKICAgICAgICAgICAgIyBXZSBoYXZlIHRvIGJlIHJvb3QgdG8gZG8gc28uCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JuYW0odGFyaW5mby5nbmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgZyA9IG9zLmdldGdpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHduYW0odGFyaW5mby51bmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgdSA9IG9zLmdldHVpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKSBhbmQgaGFzYXR0cihvcywgImxjaG93biIpOgogICAgICAgICAgICAgICAgICAgIG9zLmxjaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gIm9zMmVteCI6CiAgICAgICAgICAgICAgICAgICAgICAgIG9zLmNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yLCAiY291bGQgbm90IGNoYW5nZSBvd25lciIKCiAgICBkZWYgY2htb2Qoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IGZpbGUgcGVybWlzc2lvbnMgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAnY2htb2QnKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0cGF0aCwgdGFyaW5mby5tb2RlKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvciwgImNvdWxkIG5vdCBjaGFuZ2UgbW9kZSIKCiAgICBkZWYgdXRpbWUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICd1dGltZScpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gIndpbjMyIiBhbmQgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAjIEFjY29yZGluZyB0byBtc2RuLm1pY3Jvc29mdC5jb20sIGl0IGlzIGFuIGVycm9yIChFQUNDRVMpCiAgICAgICAgICAgICMgdG8gdXNlIHV0aW1lKCkgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MudXRpbWUodGFyZ2V0cGF0aCwgKHRhcmluZm8ubXRpbWUsIHRhcmluZm8ubXRpbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IsICJjb3VsZCBub3QgY2hhbmdlIG1vZGlmaWNhdGlvbiB0aW1lIgoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBtZW1iZXIgb2YgdGhlIGFyY2hpdmUgYXMgYSBUYXJJbmZvIG9iamVjdCwgd2hlbgogICAgICAgICAgIFRhckZpbGUgaXMgb3BlbmVkIGZvciByZWFkaW5nLiBSZXR1cm4gTm9uZSBpZiB0aGVyZSBpcyBubyBtb3JlCiAgICAgICAgICAgYXZhaWxhYmxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyYSIpCiAgICAgICAgaWYgc2VsZi5maXJzdG1lbWJlciBpcyBub3QgTm9uZToKICAgICAgICAgICAgbSA9IHNlbGYuZmlyc3RtZW1iZXIKICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgcmV0dXJuIG0KCiAgICAgICAgIyBSZWFkIHRoZSBuZXh0IGJsb2NrLgogICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBUYXJJbmZvLmZyb21idWYoYnVmKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIGlmIGJ1Zi5jb3VudChOVUwpID09IEJMT0NLU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgYWRqID0gImVtcHR5IgogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGFkaiA9ICJpbnZhbGlkIgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMgYmxvY2siICUgKHNlbGYub2Zmc2V0LCBhZGopKQogICAgICAgICAgICAgICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICMgQmxvY2sgaXMgZW1wdHkgb3IgdW5yZWFkYWJsZS4KICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICAjIElmIHRoZSBmaXJzdCBibG9jayBpcyBpbnZhbGlkLiBUaGF0IGRvZXMgbm90CiAgICAgICAgICAgICAgICAgICAgICAgICMgbG9vayBsaWtlIGEgdGFyIGFyY2hpdmUgd2UgY2FuIGhhbmRsZS4KICAgICAgICAgICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yLCJlbXB0eSwgdW5yZWFkYWJsZSBvciBjb21wcmVzc2VkIGZpbGUiCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgIyBXZSBzaG91bGRuJ3QgcmVseSBvbiB0aGlzIGNoZWNrc3VtLCBiZWNhdXNlIHNvbWUgdGFyIHByb2dyYW1zCiAgICAgICAgIyBjYWxjdWxhdGUgaXQgZGlmZmVyZW50bHkgYW5kIGl0IGlzIG1lcmVseSB2YWxpZGF0aW5nIHRoZQogICAgICAgICMgaGVhZGVyIGJsb2NrLiBXZSBjb3VsZCBqdXN0IGFzIHdlbGwgc2tpcCB0aGlzIHBhcnQsIHdoaWNoIHdvdWxkCiAgICAgICAgIyBoYXZlIGEgc2xpZ2h0IGVmZmVjdCBvbiBwZXJmb3JtYW5jZS4uLgogICAgICAgIGlmIHRhcmluZm8uY2hrc3VtICE9IGNhbGNfY2hrc3VtKGJ1Zik6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogQmFkIENoZWNrc3VtICVyIiAlIHRhcmluZm8ubmFtZSkKCiAgICAgICAgIyBTZXQgdGhlIFRhckluZm8gb2JqZWN0J3Mgb2Zmc2V0IHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZQogICAgICAgICMgVGFyRmlsZSBhbmQgc2V0IHNlbGYub2Zmc2V0IHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MKICAgICAgICAjIHNob3VsZCBiZWdpbi4KICAgICAgICB0YXJpbmZvLm9mZnNldCA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCgogICAgICAgICMgQ2hlY2sgaWYgdGhlIFRhckluZm8gb2JqZWN0IGhhcyBhIHR5cGVmbGFnIGZvciB3aGljaCBhIGNhbGxiYWNrCiAgICAgICAgIyBtZXRob2QgaXMgcmVnaXN0ZXJlZCBpbiB0aGUgVFlQRV9NRVRILiBJZiBzbywgdGhlbiBjYWxsIGl0LgogICAgICAgIGlmIHRhcmluZm8udHlwZSBpbiBzZWxmLlRZUEVfTUVUSDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuVFlQRV9NRVRIW3RhcmluZm8udHlwZV0oc2VsZiwgdGFyaW5mbykKCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpIG9yIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIFNraXAgdGhlIGZvbGxvd2luZyBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQoKICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgQmVsb3cgYXJlIHNvbWUgbWV0aG9kcyB3aGljaCBhcmUgY2FsbGVkIGZvciBzcGVjaWFsIHR5cGVmbGFncyBpbiB0aGUKICAgICMgbmV4dCgpIG1ldGhvZCwgZS5nLiBmb3IgdW53cmFwcGluZyBHTlUgbG9uZ25hbWUvbG9uZ2xpbmsgYmxvY2tzLiBUaGV5CiAgICAjIGFyZSByZWdpc3RlcmVkIGluIFRZUEVfTUVUSCBiZWxvdy4gWW91IGNhbiByZWdpc3RlciB5b3VyIG93biBtZXRob2RzCiAgICAjIHdpdGggdGhpcyBtYXBwaW5nLgogICAgIyBBIHJlZ2lzdGVyZWQgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGEgVGFySW5mbyBvYmplY3QgYXMgb25seSBhcmd1bWVudC4KICAgICMKICAgICMgRHVyaW5nIGl0cyBleGVjdXRpb24gdGhlIG1ldGhvZCBNVVNUIHBlcmZvcm0gdGhlIGZvbGxvd2luZyB0YXNrczoKICAgICMgMS4gc2V0IHRhcmluZm8ub2Zmc2V0X2RhdGEgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcyBiZWdpbiwKICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0byBmb2xsb3cuCiAgICAjIDIuIHNldCBzZWxmLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIG5leHQgbWVtYmVyJ3MgaGVhZGVyIHdpbGwKICAgICMgICAgYmVnaW4uCiAgICAjIDMuIGFwcGVuZCB0aGUgdGFyaW5mbyBvYmplY3QgdG8gc2VsZi5tZW1iZXJzLCBpZiBpdCBpcyBzdXBwb3NlZCB0byBhcHBlYXIKICAgICMgICAgYXMgYSBtZW1iZXIgb2YgdGhlIFRhckZpbGUgb2JqZWN0LgogICAgIyA0LiByZXR1cm4gdGFyaW5mbyBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgoKICAgIGRlZiBwcm9jX2dudWxvbmcoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiRXZhbHVhdGUgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKICAgICAgICAgICBvciBsb25nbGluayBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gIiIKICAgICAgICBjb3VudCA9IHRhcmluZm8uc2l6ZQogICAgICAgIHdoaWxlIGNvdW50ID4gMDoKICAgICAgICAgICAgYmxvY2sgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGJ1ZiArPSBibG9jawogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgY291bnQgLT0gQkxPQ0tTSVpFCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyCiAgICAgICAgbmV4dCA9IHNlbGYubmV4dCgpCgogICAgICAgIG5leHQub2Zmc2V0ID0gdGFyaW5mby5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9MT05HTkFNRToKICAgICAgICAgICAgbmV4dC5uYW1lID0gbnRzKGJ1ZikKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gbnRzKGJ1ZikKCiAgICAgICAgcmV0dXJuIG5leHQKCiAgICBkZWYgcHJvY19zcGFyc2Uoc2VsZiwgdGFyaW5mbyk6CiAgICAgICAgIiIiQW5hbHl6ZSBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSB0YXJpbmZvLnRvYnVmKCkKICAgICAgICBzcCA9IF9yaW5nYnVmZmVyKCkKICAgICAgICBwb3MgPSAzODYKICAgICAgICBsYXN0cG9zID0gMEwKICAgICAgICByZWFscG9zID0gMEwKICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQogICAgICAgICMgZmlyc3QgaGVhZGVyLgogICAgICAgIGZvciBpIGluIHhyYW5nZSg0KToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gaW50KGJ1Zltwb3M6cG9zICsgMTJdLCA4KQogICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBpbnQoYnVmW3BvcyArIDEyOnBvcyArIDI0XSwgOCkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgIHBvcyArPSAyNAoKICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQogICAgICAgIG9yaWdzaXplID0gaW50KGJ1Zls0ODM6NDk1XSwgOCkKCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLAogICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KICAgICAgICB3aGlsZSBpc2V4dGVuZGVkID09IDE6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIHBvcyA9IDAKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKDIxKToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBpbnQoYnVmW3Bvczpwb3MgKyAxMl0sIDgpCiAgICAgICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBpbnQoYnVmW3BvcyArIDEyOnBvcyArIDI0XSwgOCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICAgICAgcG9zICs9IDI0CiAgICAgICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzUwNF0pCgogICAgICAgIGlmIGxhc3Rwb3MgPCBvcmlnc2l6ZToKICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9yaWdzaXplIC0gbGFzdHBvcykpCgogICAgICAgIHRhcmluZm8uc3BhcnNlID0gc3AKCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG9yaWdzaXplCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMgVGhlIHR5cGUgbWFwcGluZyBmb3IgdGhlIG5leHQoKSBtZXRob2QuIFRoZSBrZXlzIGFyZSBzaW5nbGUgY2hhcmFjdGVyCiAgICAjIHN0cmluZ3MsIHRoZSB0eXBlZmxhZy4gVGhlIHZhbHVlcyBhcmUgbWV0aG9kcyB3aGljaCBhcmUgY2FsbGVkIHdoZW4KICAgICMgbmV4dCgpIGVuY291bnRlcnMgc3VjaCBhIHR5cGVmbGFnLgogICAgVFlQRV9NRVRIID0gewogICAgICAgIEdOVVRZUEVfTE9OR05BTUU6IHByb2NfZ251bG9uZywKICAgICAgICBHTlVUWVBFX0xPTkdMSU5LOiBwcm9jX2dudWxvbmcsCiAgICAgICAgR05VVFlQRV9TUEFSU0U6ICAgcHJvY19zcGFyc2UKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgTGl0dGxlIGhlbHBlciBtZXRob2RzOgoKICAgIGRlZiBfYmxvY2soc2VsZiwgY291bnQpOgogICAgICAgICIiIlJvdW5kIHVwIGEgYnl0ZSBjb3VudCBieSBCTE9DS1NJWkUgYW5kIHJldHVybiBpdCwKICAgICAgICAgICBlLmcuIF9ibG9jayg4MzQpID0+IDEwMjQuCiAgICAgICAgIiIiCiAgICAgICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QoY291bnQsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXI6CiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgcmV0dXJuIGJsb2NrcyAqIEJMT0NLU0laRQoKICAgIGRlZiBfZ2V0bWVtYmVyKHNlbGYsIG5hbWUsIHRhcmluZm89Tm9uZSk6CiAgICAgICAgIiIiRmluZCBhbiBhcmNoaXZlIG1lbWJlciBieSBuYW1lIGZyb20gYm90dG9tIHRvIHRvcC4KICAgICAgICAgICBJZiB0YXJpbmZvIGlzIGdpdmVuLCBpdCBpcyB1c2VkIGFzIHRoZSBzdGFydGluZyBwb2ludC4KICAgICAgICAiIiIKICAgICAgICAjIEVuc3VyZSB0aGF0IGFsbCBtZW1iZXJzIGhhdmUgYmVlbiBsb2FkZWQuCiAgICAgICAgbWVtYmVycyA9IHNlbGYuZ2V0bWVtYmVycygpCgogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgZW5kID0gbGVuKG1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZW5kID0gbWVtYmVycy5pbmRleCh0YXJpbmZvKQoKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZW5kIC0gMSwgLTEsIC0xKToKICAgICAgICAgICAgaWYgbmFtZSA9PSBtZW1iZXJzW2ldLm5hbWU6CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyc1tpXQoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IsICIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18KICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLl9tb2RlIG5vdCBpbiBtb2RlOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yLCAiYmFkIG9wZXJhdGlvbiBmb3IgbW9kZSAlciIgJSBzZWxmLl9tb2RlCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIlByb3ZpZGUgYW4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuX2xvYWRlZDoKICAgICAgICAgICAgcmV0dXJuIGl0ZXIoc2VsZi5tZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBUYXJJdGVyKHNlbGYpCgogICAgZGVmIF9jcmVhdGVfZ251bG9uZyhzZWxmLCBuYW1lLCB0eXBlKToKICAgICAgICAiIiJXcml0ZSBhIEdOVSBsb25nbmFtZS9sb25nbGluayBtZW1iZXIgdG8gdGhlIFRhckZpbGUuCiAgICAgICAgICAgSXQgY29uc2lzdHMgb2YgYW4gZXh0ZW5kZWQgdGFyIGhlYWRlciwgd2l0aCB0aGUgbGVuZ3RoCiAgICAgICAgICAgb2YgdGhlIGxvbmduYW1lIGFzIHNpemUsIGZvbGxvd2VkIGJ5IGRhdGEgYmxvY2tzLAogICAgICAgICAgIHdoaWNoIGNvbnRhaW4gdGhlIGxvbmduYW1lIGFzIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBuYW1lICs9IE5VTAoKICAgICAgICB0YXJpbmZvID0gVGFySW5mbygpCiAgICAgICAgdGFyaW5mby5uYW1lID0gIi4vLi9ATG9uZ0xpbmsiCiAgICAgICAgdGFyaW5mby50eXBlID0gdHlwZQogICAgICAgIHRhcmluZm8ubW9kZSA9IDAKICAgICAgICB0YXJpbmZvLnNpemUgPSBsZW4obmFtZSkKCiAgICAgICAgIyB3cml0ZSBleHRlbmRlZCBoZWFkZXIKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUodGFyaW5mby50b2J1ZigpKQogICAgICAgIHNlbGYub2Zmc2V0ICs9IEJMT0NLU0laRQogICAgICAgICMgd3JpdGUgbmFtZSBibG9ja3MKICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUobmFtZSkKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZCh0YXJpbmZvLnNpemUsIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAtIHJlbWFpbmRlcikpCiAgICAgICAgICAgIGJsb2NrcyArPSAxCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgZGVmIF9kYmcoc2VsZiwgbGV2ZWwsIG1zZyk6CiAgICAgICAgIiIiV3JpdGUgZGVidWdnaW5nIG91dHB1dCB0byBzeXMuc3RkZXJyLgogICAgICAgICIiIgogICAgICAgIGlmIGxldmVsIDw9IHNlbGYuZGVidWc6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwojIGNsYXNzIFRhckZpbGUKCmNsYXNzIFRhckl0ZXI6CiAgICAiIiJJdGVyYXRvciBDbGFzcy4KCiAgICAgICBmb3IgdGFyaW5mbyBpbiBUYXJGaWxlKC4uLik6CiAgICAgICAgICAgc3VpdGUuLi4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJdGVyIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnRhcmZpbGUgPSB0YXJmaWxlCiAgICAgICAgc2VsZi5pbmRleCA9IDAKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgaXRlbSB1c2luZyBUYXJGaWxlJ3MgbmV4dCgpIG1ldGhvZC4KICAgICAgICAgICBXaGVuIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkLCBzZXQgVGFyRmlsZSBhcyBfbG9hZGVkLgogICAgICAgICIiIgogICAgICAgICMgRml4IGZvciBTRiAjMTEwMDQyOTogVW5kZXIgcmFyZSBjaXJjdW1zdGFuY2VzIGl0IGNhbgogICAgICAgICMgaGFwcGVuIHRoYXQgZ2V0bWVtYmVycygpIGlzIGNhbGxlZCBkdXJpbmcgaXRlcmF0aW9uLAogICAgICAgICMgd2hpY2ggd2lsbCBjYXVzZSBUYXJJdGVyIHRvIHN0b3AgcHJlbWF0dXJlbHkuCiAgICAgICAgaWYgbm90IHNlbGYudGFyZmlsZS5fbG9hZGVkOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQogICAgICAgICAgICBpZiBub3QgdGFyaW5mbzoKICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5fbG9hZGVkID0gVHJ1ZQogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmZpbGUubWVtYmVyc1tzZWxmLmluZGV4XQogICAgICAgICAgICBleGNlcHQgSW5kZXhFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBzZWxmLmluZGV4ICs9IDEKICAgICAgICByZXR1cm4gdGFyaW5mbwoKIyBIZWxwZXIgY2xhc3NlcyBmb3Igc3BhcnNlIGZpbGUgc3VwcG9ydApjbGFzcyBfc2VjdGlvbjoKICAgICIiIkJhc2UgY2xhc3MgZm9yIF9kYXRhIGFuZCBfaG9sZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSk6CiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG9mZnNldCk6CiAgICAgICAgcmV0dXJuIHNlbGYub2Zmc2V0IDw9IG9mZnNldCA8IHNlbGYub2Zmc2V0ICsgc2VsZi5zaXplCgpjbGFzcyBfZGF0YShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBkYXRhIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSwgcmVhbHBvcyk6CiAgICAgICAgX3NlY3Rpb24uX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKQogICAgICAgIHNlbGYucmVhbHBvcyA9IHJlYWxwb3MKCmNsYXNzIF9ob2xlKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGhvbGUgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBwYXNzCgpjbGFzcyBfcmluZ2J1ZmZlcihsaXN0KToKICAgICIiIlJpbmdidWZmZXIgY2xhc3Mgd2hpY2ggaW5jcmVhc2VzIHBlcmZvcm1hbmNlCiAgICAgICBvdmVyIGEgcmVndWxhciBsaXN0LgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi5pZHggPSAwCiAgICBkZWYgZmluZChzZWxmLCBvZmZzZXQpOgogICAgICAgIGlkeCA9IHNlbGYuaWR4CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaXRlbSA9IHNlbGZbaWR4XQogICAgICAgICAgICBpZiBvZmZzZXQgaW4gaXRlbToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlkeCArPSAxCiAgICAgICAgICAgIGlmIGlkeCA9PSBsZW4oc2VsZik6CiAgICAgICAgICAgICAgICBpZHggPSAwCiAgICAgICAgICAgIGlmIGlkeCA9PSBzZWxmLmlkeDoKICAgICAgICAgICAgICAgICMgRW5kIG9mIEZpbGUKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgc2VsZi5pZHggPSBpZHgKICAgICAgICByZXR1cm4gaXRlbQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHppcGZpbGUgY29tcGF0aWJsZSBUYXJGaWxlIGNsYXNzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVEFSX1BMQUlOID0gMCAgICAgICAgICAgIyB6aXBmaWxlLlpJUF9TVE9SRUQKVEFSX0daSVBQRUQgPSA4ICAgICAgICAgIyB6aXBmaWxlLlpJUF9ERUZMQVRFRApjbGFzcyBUYXJGaWxlQ29tcGF0OgogICAgIiIiVGFyRmlsZSBjbGFzcyBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgbW9kdWxlIHppcGZpbGUncwogICAgICAgWmlwRmlsZSBjbGFzcy4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIG1vZGU9InIiLCBjb21wcmVzc2lvbj1UQVJfUExBSU4pOgogICAgICAgIGlmIGNvbXByZXNzaW9uID09IFRBUl9QTEFJTjoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS50YXJvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxpZiBjb21wcmVzc2lvbiA9PSBUQVJfR1pJUFBFRDoKICAgICAgICAgICAgc2VsZi50YXJmaWxlID0gVGFyRmlsZS5nem9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yLCAidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIKICAgICAgICBpZiBtb2RlWzA6MV0gPT0gInIiOgogICAgICAgICAgICBtZW1iZXJzID0gc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKQogICAgICAgICAgICBmb3IgbSBpbiBtZW1iZXJzOgogICAgICAgICAgICAgICAgbS5maWxlbmFtZSA9IG0ubmFtZQogICAgICAgICAgICAgICAgbS5maWxlX3NpemUgPSBtLnNpemUKICAgICAgICAgICAgICAgIG0uZGF0ZV90aW1lID0gdGltZS5nbXRpbWUobS5tdGltZSlbOjZdCiAgICBkZWYgbmFtZWxpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIG1hcChsYW1iZGEgbTogbS5uYW1lLCBzZWxmLmluZm9saXN0KCkpCiAgICBkZWYgaW5mb2xpc3Qoc2VsZik6CiAgICAgICAgcmV0dXJuIGZpbHRlcihsYW1iZGEgbTogbS50eXBlIGluIFJFR1VMQVJfVFlQRVMsCiAgICAgICAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpKQogICAgZGVmIHByaW50ZGlyKHNlbGYpOgogICAgICAgIHNlbGYudGFyZmlsZS5saXN0KCkKICAgIGRlZiB0ZXN0emlwKHNlbGYpOgogICAgICAgIHJldHVybgogICAgZGVmIGdldGluZm8oc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkKICAgIGRlZiByZWFkKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZXh0cmFjdGZpbGUoc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKSkucmVhZCgpCiAgICBkZWYgd3JpdGUoc2VsZiwgZmlsZW5hbWUsIGFyY25hbWU9Tm9uZSwgY29tcHJlc3NfdHlwZT1Ob25lKToKICAgICAgICBzZWxmLnRhcmZpbGUuYWRkKGZpbGVuYW1lLCBhcmNuYW1lKQogICAgZGVmIHdyaXRlc3RyKHNlbGYsIHppbmZvLCBieXRlcyk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBmcm9tIGNTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIGZyb20gU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgaW1wb3J0IGNhbGVuZGFyCiAgICAgICAgemluZm8ubmFtZSA9IHppbmZvLmZpbGVuYW1lCiAgICAgICAgemluZm8uc2l6ZSA9IHppbmZvLmZpbGVfc2l6ZQogICAgICAgIHppbmZvLm10aW1lID0gY2FsZW5kYXIudGltZWdtKHppbmZvLmRhdGVfdGltZSkKICAgICAgICBzZWxmLnRhcmZpbGUuYWRkZmlsZSh6aW5mbywgU3RyaW5nSU8oYnl0ZXMpKQogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYudGFyZmlsZS5jbG9zZSgpCiNjbGFzcyBUYXJGaWxlQ29tcGF0CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBleHBvcnRlZCBmdW5jdGlvbnMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCmRlZiBpc190YXJmaWxlKG5hbWUpOgogICAgIiIiUmV0dXJuIFRydWUgaWYgbmFtZSBwb2ludHMgdG8gYSB0YXIgYXJjaGl2ZSB0aGF0IHdlCiAgICAgICBhcmUgYWJsZSB0byBoYW5kbGUsIGVsc2UgcmV0dXJuIEZhbHNlLgogICAgIiIiCiAgICB0cnk6CiAgICAgICAgdCA9IG9wZW4obmFtZSkKICAgICAgICB0LmNsb3NlKCkKICAgICAgICByZXR1cm4gVHJ1ZQogICAgZXhjZXB0IFRhckVycm9yOgogICAgICAgIHJldHVybiBGYWxzZQoKb3BlbiA9IFRhckZpbGUub3Blbgo=