IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogaXNvLTg4NTktMSAtKi0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlLnB5CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29weXJpZ2h0IChDKSAyMDAyIExhcnMgR3VzdORiZWwgPGxhcnNAZ3VzdGFlYmVsLmRlPgojIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMKIyBQZXJtaXNzaW9uICBpcyAgaGVyZWJ5IGdyYW50ZWQsICBmcmVlICBvZiBjaGFyZ2UsICB0byAgYW55IHBlcnNvbgojIG9idGFpbmluZyBhICBjb3B5IG9mICB0aGlzIHNvZnR3YXJlICBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uCiMgZmlsZXMgICh0aGUgICJTb2Z0d2FyZSIpLCAgdG8gICBkZWFsICBpbiAgdGhlICBTb2Z0d2FyZSAgIHdpdGhvdXQKIyByZXN0cmljdGlvbiwgIGluY2x1ZGluZyAgd2l0aG91dCBsaW1pdGF0aW9uICB0aGUgIHJpZ2h0cyB0byAgdXNlLAojIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiMgY29waWVzICBvZiAgdGhlICBTb2Z0d2FyZSwgIGFuZCB0byAgcGVybWl0ICBwZXJzb25zICB0byAgd2hvbSB0aGUKIyBTb2Z0d2FyZSAgaXMgIGZ1cm5pc2hlZCAgdG8gIGRvICBzbywgIHN1YmplY3QgIHRvICB0aGUgIGZvbGxvd2luZwojIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0ICBub3RpY2UgYW5kIHRoaXMgIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsICBiZQojIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyAgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSAgS0lORCwKIyBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyAgQlVUIE5PVCBMSU1JVEVEIFRPICBUSEUgV0FSUkFOVElFUwojIE9GICBNRVJDSEFOVEFCSUxJVFksICBGSVRORVNTICAgRk9SICBBICBQQVJUSUNVTEFSICAgUFVSUE9TRSAgQU5ECiMgTk9OSU5GUklOR0VNRU5ULiAgSU4gIE5PICBFVkVOVCBTSEFMTCAgVEhFICBBVVRIT1JTICBPUiBDT1BZUklHSFQKIyBIT0xERVJTICBCRSBMSUFCTEUgIEZPUiBBTlkgIENMQUlNLCBEQU1BR0VTICBPUiBPVEhFUiAgTElBQklMSVRZLAojIFdIRVRIRVIgIElOIEFOICBBQ1RJT04gT0YgIENPTlRSQUNULCBUT1JUICBPUiBPVEhFUldJU0UsICBBUklTSU5HCiMgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUgojIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KIwoiIiJSZWFkIGZyb20gYW5kIHdyaXRlIHRvIHRhciBmb3JtYXQgYXJjaGl2ZXMuCiIiIgoKX192ZXJzaW9uX18gPSAiJFJldmlzaW9uJCIKIyAkU291cmNlJAoKdmVyc2lvbiAgICAgPSAiMC44LjAiCl9fYXV0aG9yX18gID0gIkxhcnMgR3VzdORiZWwgKGxhcnNAZ3VzdGFlYmVsLmRlKSIKX19kYXRlX18gICAgPSAiJERhdGUkIgpfX2N2c2lkX18gICA9ICIkSWQkIgpfX2NyZWRpdHNfXyA9ICJHdXN0YXZvIE5pZW1leWVyLCBOaWVscyBHdXN05GJlbCwgUmljaGFyZCBUb3duc2VuZC4iCgojLS0tLS0tLS0tCiMgSW1wb3J0cwojLS0tLS0tLS0tCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHN0YXQKaW1wb3J0IGVycm5vCmltcG9ydCB0aW1lCmltcG9ydCBzdHJ1Y3QKaW1wb3J0IGNvcHkKCmlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICMgVGhpcyBtb2R1bGUgbmVlZHMgd29yayBmb3IgTWFjT1M5LCBlc3BlY2lhbGx5IGluIHRoZSBhcmVhIG9mIHBhdGhuYW1lCiAgICAjIGhhbmRsaW5nLiBJbiBtYW55IHBsYWNlcyBpdCBpcyBhc3N1bWVkIGEgc2ltcGxlIHN1YnN0aXR1dGlvbiBvZiAvIGJ5IHRoZQogICAgIyBsb2NhbCBvcy5wYXRoLnNlcCBpcyBnb29kIGVub3VnaCB0byBjb252ZXJ0IHBhdGhuYW1lcywgYnV0IHRoaXMgZG9lcyBub3QKICAgICMgd29yayB3aXRoIHRoZSBtYWMgcm9vdGVkOnBhdGg6bmFtZSB2ZXJzdXMgOm5vbnJvb3RlZDpwYXRoOm5hbWUgc3ludGF4CiAgICByYWlzZSBJbXBvcnRFcnJvciwgInRhcmZpbGUgZG9lcyBub3Qgd29yayBmb3IgcGxhdGZvcm09PW1hYyIKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCAgICAgICAgPSAiXDAiICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFICA9IDUxMiAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKTUFHSUMgICAgICA9ICJ1c3RhciIgICAgICAgICAgICAjIG1hZ2ljIHRhciBzdHJpbmcKVkVSU0lPTiAgICA9ICIwMCIgICAgICAgICAgICAgICAjIHZlcnNpb24gbnVtYmVyCgpMRU5HVEhfTkFNRSAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyAgICA9IDEwMCAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYICA9IDE1NSAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZApNQVhTSVpFX01FTUJFUiA9IDA3Nzc3Nzc3Nzc3N0wgICMgbWF4aW11bSBzaXplIG9mIGEgZmlsZSAoMTEgb2N0YWwgZGlnaXRzKQoKUkVHVFlQRSAgPSAiMCIgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgID0gIjEiICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSAgPSAiMiIgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSAgPSAiMyIgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFICA9ICI0IiAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSAgPSAiNSIgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmduYW1lcwpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBleHRlbnNpb24gZm9yIGxvbmdsaW5rCkdOVVRZUEVfU1BBUlNFICAgPSAiUyIgICAgICAgICAgIyBHTlUgdGFyIGV4dGVuc2lvbiBmb3Igc3BhcnNlIGZpbGUKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB0YXJmaWxlIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNVUFBPUlRFRF9UWVBFUyA9IChSRUdUWVBFLCBBUkVHVFlQRSwgTE5LVFlQRSwgICMgZmlsZSB0eXBlcyB0aGF0IHRhcmZpbGUKICAgICAgICAgICAgICAgICAgIFNZTVRZUEUsIERJUlRZUEUsIEZJRk9UWVBFLCAgIyBjYW4gY29wZSB3aXRoLgogICAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIENIUlRZUEUsIEJMS1RZUEUsCiAgICAgICAgICAgICAgICAgICBHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9TUEFSU0UpCgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLCAgICAgICAgICAgICAjIGZpbGUgdHlwZXMgdGhhdCBzb21laG93CiAgICAgICAgICAgICAgICAgQ09OVFRZUEUsIEdOVVRZUEVfU1BBUlNFKSAgICAgICMgcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBCaXRzIHVzZWQgaW4gdGhlIG1vZGUgZmllbGQsIHZhbHVlcyBpbiBvY3RhbC4KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTX0lGTE5LID0gMDEyMDAwMCAgICAgICAgIyBzeW1ib2xpYyBsaW5rClNfSUZSRUcgPSAwMTAwMDAwICAgICAgICAjIHJlZ3VsYXIgZmlsZQpTX0lGQkxLID0gMDA2MDAwMCAgICAgICAgIyBibG9jayBkZXZpY2UKU19JRkRJUiA9IDAwNDAwMDAgICAgICAgICMgZGlyZWN0b3J5ClNfSUZDSFIgPSAwMDIwMDAwICAgICAgICAjIGNoYXJhY3RlciBkZXZpY2UKU19JRklGTyA9IDAwMTAwMDAgICAgICAgICMgZmlmbwoKVFNVSUQgICA9IDA0MDAwICAgICAgICAgICMgc2V0IFVJRCBvbiBleGVjdXRpb24KVFNHSUQgICA9IDAyMDAwICAgICAgICAgICMgc2V0IEdJRCBvbiBleGVjdXRpb24KVFNWVFggICA9IDAxMDAwICAgICAgICAgICMgcmVzZXJ2ZWQKClRVUkVBRCAgPSAwNDAwICAgICAgICAgICAjIHJlYWQgYnkgb3duZXIKVFVXUklURSA9IDAyMDAgICAgICAgICAgICMgd3JpdGUgYnkgb3duZXIKVFVFWEVDICA9IDAxMDAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgb3duZXIKVEdSRUFEICA9IDAwNDAgICAgICAgICAgICMgcmVhZCBieSBncm91cApUR1dSSVRFID0gMDAyMCAgICAgICAgICAgIyB3cml0ZSBieSBncm91cApUR0VYRUMgID0gMDAxMCAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBncm91cApUT1JFQUQgID0gMDAwNCAgICAgICAgICAgIyByZWFkIGJ5IG90aGVyClRPV1JJVEUgPSAwMDAyICAgICAgICAgICAjIHdyaXRlIGJ5IG90aGVyClRPRVhFQyAgPSAwMDAxICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG90aGVyCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBzdG4ocywgbGVuZ3RoKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gc3RyaW5nIHRvIGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBidWZmZXIuCiAgICAiIiIKICAgIHJldHVybiBzWzpsZW5ndGhdICsgKGxlbmd0aCAtIGxlbihzKSkgKiBOVUwKCmRlZiBudGkocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVtYmVyIGZpZWxkIHRvIGEgcHl0aG9uIG51bWJlci4KICAgICIiIgogICAgIyBUaGVyZSBhcmUgdHdvIHBvc3NpYmxlIGVuY29kaW5ncyBmb3IgYSBudW1iZXIgZmllbGQsIHNlZQogICAgIyBpdG4oKSBiZWxvdy4KICAgIGlmIHNbMF0gIT0gY2hyKDAyMDApOgogICAgICAgIHRyeToKICAgICAgICAgICAgbiA9IGludChzLnJzdHJpcChOVUwgKyAiICIpIG9yICIwIiwgOCkKICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgcmFpc2UgSGVhZGVyRXJyb3IoImludmFsaWQgaGVhZGVyIikKICAgIGVsc2U6CiAgICAgICAgbiA9IDBMCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGxlbihzKSAtIDEpOgogICAgICAgICAgICBuIDw8PSA4CiAgICAgICAgICAgIG4gKz0gb3JkKHNbaSArIDFdKQogICAgcmV0dXJuIG4KCmRlZiBpdG4obiwgZGlnaXRzPTgsIHBvc2l4PUZhbHNlKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gbnVtYmVyIHRvIGEgbnVtYmVyIGZpZWxkLgogICAgIiIiCiAgICAjIFBPU0lYIDEwMDMuMS0xOTg4IHJlcXVpcmVzIG51bWJlcnMgdG8gYmUgZW5jb2RlZCBhcyBhIHN0cmluZyBvZgogICAgIyBvY3RhbCBkaWdpdHMgZm9sbG93ZWQgYnkgYSBudWxsLWJ5dGUsIHRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0bwogICAgIyAoOCoqKGRpZ2l0cy0xKSktMS4gR05VIHRhciBhbGxvd3Mgc3RvcmluZyBudW1iZXJzIGdyZWF0ZXIgdGhhbgogICAgIyB0aGF0IGlmIG5lY2Vzc2FyeS4gQSBsZWFkaW5nIDAyMDAgYnl0ZSBpbmRpY2F0ZXMgdGhpcyBwYXJ0aWN1bGFyCiAgICAjIGVuY29kaW5nLCB0aGUgZm9sbG93aW5nIGRpZ2l0cy0xIGJ5dGVzIGFyZSBhIGJpZy1lbmRpYW4KICAgICMgcmVwcmVzZW50YXRpb24uIFRoaXMgYWxsb3dzIHZhbHVlcyB1cCB0byAoMjU2KiooZGlnaXRzLTEpKS0xLgogICAgaWYgMCA8PSBuIDwgOCAqKiAoZGlnaXRzIC0gMSk6CiAgICAgICAgcyA9ICIlMCpvIiAlIChkaWdpdHMgLSAxLCBuKSArIE5VTAogICAgZWxzZToKICAgICAgICBpZiBwb3NpeDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigib3ZlcmZsb3cgaW4gbnVtYmVyIGZpZWxkIikKCiAgICAgICAgaWYgbiA8IDA6CiAgICAgICAgICAgICMgWFhYIFdlIG1pbWljIEdOVSB0YXIncyBiZWhhdmlvdXIgd2l0aCBuZWdhdGl2ZSBudW1iZXJzLAogICAgICAgICAgICAjIHRoaXMgY291bGQgcmFpc2UgT3ZlcmZsb3dFcnJvci4KICAgICAgICAgICAgbiA9IHN0cnVjdC51bnBhY2soIkwiLCBzdHJ1Y3QucGFjaygibCIsIG4pKVswXQoKICAgICAgICBzID0gIiIKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZGlnaXRzIC0gMSk6CiAgICAgICAgICAgIHMgPSBjaHIobiAmIDAzNzcpICsgcwogICAgICAgICAgICBuID4+PSA4CiAgICAgICAgcyA9IGNocigwMjAwKSArIHMKICAgIHJldHVybiBzCgpkZWYgY2FsY19jaGtzdW1zKGJ1Zik6CiAgICAiIiJDYWxjdWxhdGUgdGhlIGNoZWNrc3VtIGZvciBhIG1lbWJlcidzIGhlYWRlciBieSBzdW1taW5nIHVwIGFsbAogICAgICAgY2hhcmFjdGVycyBleGNlcHQgZm9yIHRoZSBjaGtzdW0gZmllbGQgd2hpY2ggaXMgdHJlYXRlZCBhcyBpZgogICAgICAgaXQgd2FzIGZpbGxlZCB3aXRoIHNwYWNlcy4gQWNjb3JkaW5nIHRvIHRoZSBHTlUgdGFyIHNvdXJjZXMsCiAgICAgICBzb21lIHRhcnMgKFN1biBhbmQgTmVYVCkgY2FsY3VsYXRlIGNoa3N1bSB3aXRoIHNpZ25lZCBjaGFyLAogICAgICAgd2hpY2ggd2lsbCBiZSBkaWZmZXJlbnQgaWYgdGhlcmUgYXJlIGNoYXJzIGluIHRoZSBidWZmZXIgd2l0aAogICAgICAgdGhlIGhpZ2ggYml0IHNldC4gU28gd2UgY2FsY3VsYXRlIHR3byBjaGVja3N1bXMsIHVuc2lnbmVkIGFuZAogICAgICAgc2lnbmVkLgogICAgIiIiCiAgICB1bnNpZ25lZF9jaGtzdW0gPSAyNTYgKyBzdW0oc3RydWN0LnVucGFjaygiMTQ4QiIsIGJ1Zls6MTQ4XSkgKyBzdHJ1Y3QudW5wYWNrKCIzNTZCIiwgYnVmWzE1Njo1MTJdKSkKICAgIHNpZ25lZF9jaGtzdW0gPSAyNTYgKyBzdW0oc3RydWN0LnVucGFjaygiMTQ4YiIsIGJ1Zls6MTQ4XSkgKyBzdHJ1Y3QudW5wYWNrKCIzNTZiIiwgYnVmWzE1Njo1MTJdKSkKICAgIHJldHVybiB1bnNpZ25lZF9jaGtzdW0sIHNpZ25lZF9jaGtzdW0KCmRlZiBjb3B5ZmlsZW9iaihzcmMsIGRzdCwgbGVuZ3RoPU5vbmUpOgogICAgIiIiQ29weSBsZW5ndGggYnl0ZXMgZnJvbSBmaWxlb2JqIHNyYyB0byBmaWxlb2JqIGRzdC4KICAgICAgIElmIGxlbmd0aCBpcyBOb25lLCBjb3B5IHRoZSBlbnRpcmUgY29udGVudC4KICAgICIiIgogICAgaWYgbGVuZ3RoID09IDA6CiAgICAgICAgcmV0dXJuCiAgICBpZiBsZW5ndGggaXMgTm9uZToKICAgICAgICBzaHV0aWwuY29weWZpbGVvYmooc3JjLCBkc3QpCiAgICAgICAgcmV0dXJuCgogICAgQlVGU0laRSA9IDE2ICogMTAyNAogICAgYmxvY2tzLCByZW1haW5kZXIgPSBkaXZtb2QobGVuZ3RoLCBCVUZTSVpFKQogICAgZm9yIGIgaW4geHJhbmdlKGJsb2Nrcyk6CiAgICAgICAgYnVmID0gc3JjLnJlYWQoQlVGU0laRSkKICAgICAgICBpZiBsZW4oYnVmKSA8IEJVRlNJWkU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImVuZCBvZiBmaWxlIHJlYWNoZWQiKQogICAgICAgIGRzdC53cml0ZShidWYpCgogICAgaWYgcmVtYWluZGVyICE9IDA6CiAgICAgICAgYnVmID0gc3JjLnJlYWQocmVtYWluZGVyKQogICAgICAgIGlmIGxlbihidWYpIDwgcmVtYWluZGVyOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJlbmQgb2YgZmlsZSByZWFjaGVkIikKICAgICAgICBkc3Qud3JpdGUoYnVmKQogICAgcmV0dXJuCgpmaWxlbW9kZV90YWJsZSA9ICgKICAgICgoU19JRkxOSywgICAgICAibCIpLAogICAgIChTX0lGUkVHLCAgICAgICItIiksCiAgICAgKFNfSUZCTEssICAgICAgImIiKSwKICAgICAoU19JRkRJUiwgICAgICAiZCIpLAogICAgIChTX0lGQ0hSLCAgICAgICJjIiksCiAgICAgKFNfSUZJRk8sICAgICAgInAiKSksCgogICAgKChUVVJFQUQsICAgICAgICJyIiksKSwKICAgICgoVFVXUklURSwgICAgICAidyIpLCksCiAgICAoKFRVRVhFQ3xUU1VJRCwgInMiKSwKICAgICAoVFNVSUQsICAgICAgICAiUyIpLAogICAgIChUVUVYRUMsICAgICAgICJ4IikpLAoKICAgICgoVEdSRUFELCAgICAgICAiciIpLCksCiAgICAoKFRHV1JJVEUsICAgICAgInciKSwpLAogICAgKChUR0VYRUN8VFNHSUQsICJzIiksCiAgICAgKFRTR0lELCAgICAgICAgIlMiKSwKICAgICAoVEdFWEVDLCAgICAgICAieCIpKSwKCiAgICAoKFRPUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUT1dSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVE9FWEVDfFRTVlRYLCAidCIpLAogICAgIChUU1ZUWCwgICAgICAgICJUIiksCiAgICAgKFRPRVhFQywgICAgICAgIngiKSkKKQoKZGVmIGZpbGVtb2RlKG1vZGUpOgogICAgIiIiQ29udmVydCBhIGZpbGUncyBtb2RlIHRvIGEgc3RyaW5nIG9mIHRoZSBmb3JtCiAgICAgICAtcnd4cnd4cnd4LgogICAgICAgVXNlZCBieSBUYXJGaWxlLmxpc3QoKQogICAgIiIiCiAgICBwZXJtID0gW10KICAgIGZvciB0YWJsZSBpbiBmaWxlbW9kZV90YWJsZToKICAgICAgICBmb3IgYml0LCBjaGFyIGluIHRhYmxlOgogICAgICAgICAgICBpZiBtb2RlICYgYml0ID09IGJpdDoKICAgICAgICAgICAgICAgIHBlcm0uYXBwZW5kKGNoYXIpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHBlcm0uYXBwZW5kKCItIikKICAgIHJldHVybiAiIi5qb2luKHBlcm0pCgppZiBvcy5zZXAgIT0gIi8iOgogICAgbm9ybXBhdGggPSBsYW1iZGEgcGF0aDogb3MucGF0aC5ub3JtcGF0aChwYXRoKS5yZXBsYWNlKG9zLnNlcCwgIi8iKQplbHNlOgogICAgbm9ybXBhdGggPSBvcy5wYXRoLm5vcm1wYXRoCgpjbGFzcyBUYXJFcnJvcihFeGNlcHRpb24pOgogICAgIiIiQmFzZSBleGNlcHRpb24uIiIiCiAgICBwYXNzCmNsYXNzIEV4dHJhY3RFcnJvcihUYXJFcnJvcik6CiAgICAiIiJHZW5lcmFsIGV4Y2VwdGlvbiBmb3IgZXh0cmFjdCBlcnJvcnMuIiIiCiAgICBwYXNzCmNsYXNzIFJlYWRFcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVucmVhZGJsZSB0YXIgYXJjaGl2ZXMuIiIiCiAgICBwYXNzCmNsYXNzIENvbXByZXNzaW9uRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bmF2YWlsYWJsZSBjb21wcmVzc2lvbiBtZXRob2RzLiIiIgogICAgcGFzcwpjbGFzcyBTdHJlYW1FcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVuc3VwcG9ydGVkIG9wZXJhdGlvbnMgb24gc3RyZWFtLWxpa2UgVGFyRmlsZXMuIiIiCiAgICBwYXNzCmNsYXNzIEhlYWRlckVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgaW52YWxpZCBoZWFkZXJzLiIiIgogICAgcGFzcwoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGludGVybmFsIHN0cmVhbSBpbnRlcmZhY2UKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBfTG93TGV2ZWxGaWxlOgogICAgIiIiTG93LWxldmVsIGZpbGUgb2JqZWN0LiBTdXBwb3J0cyByZWFkaW5nIGFuZCB3cml0aW5nLgogICAgICAgSXQgaXMgdXNlZCBpbnN0ZWFkIG9mIGEgcmVndWxhciBmaWxlIG9iamVjdCBmb3Igc3RyZWFtaW5nCiAgICAgICBhY2Nlc3MuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSk6CiAgICAgICAgbW9kZSA9IHsKICAgICAgICAgICAgInIiOiBvcy5PX1JET05MWSwKICAgICAgICAgICAgInciOiBvcy5PX1dST05MWSB8IG9zLk9fQ1JFQVQgfCBvcy5PX1RSVU5DLAogICAgICAgIH1bbW9kZV0KICAgICAgICBpZiBoYXNhdHRyKG9zLCAiT19CSU5BUlkiKToKICAgICAgICAgICAgbW9kZSB8PSBvcy5PX0JJTkFSWQogICAgICAgIHNlbGYuZmQgPSBvcy5vcGVuKG5hbWUsIG1vZGUpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIG9zLmNsb3NlKHNlbGYuZmQpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgcmV0dXJuIG9zLnJlYWQoc2VsZi5mZCwgc2l6ZSkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgb3Mud3JpdGUoc2VsZi5mZCwgcykKCmNsYXNzIF9TdHJlYW06CiAgICAiIiJDbGFzcyB0aGF0IHNlcnZlcyBhcyBhbiBhZGFwdGVyIGJldHdlZW4gVGFyRmlsZSBhbmQKICAgICAgIGEgc3RyZWFtLWxpa2Ugb2JqZWN0LiAgVGhlIHN0cmVhbS1saWtlIG9iamVjdCBvbmx5CiAgICAgICBuZWVkcyB0byBoYXZlIGEgcmVhZCgpIG9yIHdyaXRlKCkgbWV0aG9kIGFuZCBpcyBhY2Nlc3NlZAogICAgICAgYmxvY2t3aXNlLiAgVXNlIG9mIGd6aXAgb3IgYnppcDIgY29tcHJlc3Npb24gaXMgcG9zc2libGUuCiAgICAgICBBIHN0cmVhbS1saWtlIG9iamVjdCBjb3VsZCBiZSBmb3IgZXhhbXBsZTogc3lzLnN0ZGluLAogICAgICAgc3lzLnN0ZG91dCwgYSBzb2NrZXQsIGEgdGFwZSBkZXZpY2UgZXRjLgoKICAgICAgIF9TdHJlYW0gaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbmx5IGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgbW9kZSwgY29tcHR5cGUsIGZpbGVvYmosIGJ1ZnNpemUpOgogICAgICAgICIiIkNvbnN0cnVjdCBhIF9TdHJlYW0gb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBmaWxlb2JqID0gX0xvd0xldmVsRmlsZShuYW1lLCBtb2RlKQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gRmFsc2UKCiAgICAgICAgaWYgY29tcHR5cGUgPT0gJyonOgogICAgICAgICAgICAjIEVuYWJsZSB0cmFuc3BhcmVudCBjb21wcmVzc2lvbiBkZXRlY3Rpb24gZm9yIHRoZQogICAgICAgICAgICAjIHN0cmVhbSBpbnRlcmZhY2UKICAgICAgICAgICAgZmlsZW9iaiA9IF9TdHJlYW1Qcm94eShmaWxlb2JqKQogICAgICAgICAgICBjb21wdHlwZSA9IGZpbGVvYmouZ2V0Y29tcHR5cGUoKQoKICAgICAgICBzZWxmLm5hbWUgICAgID0gbmFtZSBvciAiIgogICAgICAgIHNlbGYubW9kZSAgICAgPSBtb2RlCiAgICAgICAgc2VsZi5jb21wdHlwZSA9IGNvbXB0eXBlCiAgICAgICAgc2VsZi5maWxlb2JqICA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZnNpemUgID0gYnVmc2l6ZQogICAgICAgIHNlbGYuYnVmICAgICAgPSAiIgogICAgICAgIHNlbGYucG9zICAgICAgPSAwTAogICAgICAgIHNlbGYuY2xvc2VkICAgPSBGYWxzZQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgemxpYgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJ6bGliIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgc2VsZi56bGliID0gemxpYgogICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpCiAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgc2VsZi5faW5pdF9yZWFkX2d6KCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICBpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJiejIgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQogICAgICAgICAgICBpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBzZWxmLmNtcCA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCAiY2xvc2VkIikgYW5kIG5vdCBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgc2VsZi5jbG9zZSgpCgogICAgZGVmIF9pbml0X3dyaXRlX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHdyaXRpbmcgd2l0aCBnemlwIGNvbXByZXNzaW9uLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmNvbXByZXNzb2JqKDksIHNlbGYuemxpYi5ERUZMQVRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtc2VsZi56bGliLk1BWF9XQklUUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnpsaWIuREVGX01FTV9MRVZFTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKQogICAgICAgIHRpbWVzdGFtcCA9IHN0cnVjdC5wYWNrKCI8TCIsIGxvbmcodGltZS50aW1lKCkpKQogICAgICAgIHNlbGYuX193cml0ZSgiXDAzN1wyMTNcMDEwXDAxMCVzXDAwMlwzNzciICUgdGltZXN0YW1wKQogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLmd6Iik6CiAgICAgICAgICAgIHNlbGYubmFtZSA9IHNlbGYubmFtZVs6LTNdCiAgICAgICAgc2VsZi5fX3dyaXRlKHNlbGYubmFtZSArIE5VTCkKCiAgICBkZWYgd3JpdGUoc2VsZiwgcyk6CiAgICAgICAgIiIiV3JpdGUgc3RyaW5nIHMgdG8gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgIHNlbGYuY3JjID0gc2VsZi56bGliLmNyYzMyKHMsIHNlbGYuY3JjKQogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5jb21wdHlwZSAhPSAidGFyIjoKICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmJ1ZjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHNlbGYuYnVmKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gImd6IjoKICAgICAgICAgICAgICAgICMgVGhlIG5hdGl2ZSB6bGliIGNyYyBpcyBhbiB1bnNpZ25lZCAzMi1iaXQgaW50ZWdlciwgYnV0CiAgICAgICAgICAgICAgICAjIHRoZSBQeXRob24gd3JhcHBlciBpbXBsaWNpdGx5IGNhc3RzIHRoYXQgdG8gYSBzaWduZWQgQwogICAgICAgICAgICAgICAgIyBsb25nLiAgU28sIG9uIGEgMzItYml0IGJveCBzZWxmLmNyYyBtYXkgImxvb2sgbmVnYXRpdmUiLAogICAgICAgICAgICAgICAgIyB3aGlsZSB0aGUgc2FtZSBjcmMgb24gYSA2NC1iaXQgYm94IG1heSAibG9vayBwb3NpdGl2ZSIuCiAgICAgICAgICAgICAgICAjIFRvIGF2b2lkIGlya3NvbWUgd2FybmluZ3MgZnJvbSB0aGUgYHN0cnVjdGAgbW9kdWxlLCBmb3JjZQogICAgICAgICAgICAgICAgIyBpdCB0byBsb29rIHBvc2l0aXZlIG9uIGFsbCBib3hlcy4KICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLmNyYyAmIDB4ZmZmZmZmZmZMKSkKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcyAmIDB4ZmZmZkZGRkZMKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQoKICAgIGRlZiBfaW5pdF9yZWFkX2d6KHNlbGYpOgogICAgICAgICIiIkluaXRpYWxpemUgZm9yIHJlYWRpbmcgYSBnemlwIGNvbXByZXNzZWQgZmlsZW9iai4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5kZWNvbXByZXNzb2JqKC1zZWxmLnpsaWIuTUFYX1dCSVRTKQogICAgICAgIHNlbGYuZGJ1ZiA9ICIiCgogICAgICAgICMgdGFrZW4gZnJvbSBnemlwLkd6aXBGaWxlIHdpdGggc29tZSBhbHRlcmF0aW9ucwogICAgICAgIGlmIHNlbGYuX19yZWFkKDIpICE9ICJcMDM3XDIxMyI6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICBpZiBzZWxmLl9fcmVhZCgxKSAhPSAiXDAxMCI6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVuc3VwcG9ydGVkIGNvbXByZXNzaW9uIG1ldGhvZCIpCgogICAgICAgIGZsYWcgPSBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgc2VsZi5fX3JlYWQoNikKCiAgICAgICAgaWYgZmxhZyAmIDQ6CiAgICAgICAgICAgIHhsZW4gPSBvcmQoc2VsZi5fX3JlYWQoMSkpICsgMjU2ICogb3JkKHNlbGYuX19yZWFkKDEpKQogICAgICAgICAgICBzZWxmLnJlYWQoeGxlbikKICAgICAgICBpZiBmbGFnICYgODoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMTY6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBzID0gc2VsZi5fX3JlYWQoMSkKICAgICAgICAgICAgICAgIGlmIG5vdCBzIG9yIHMgPT0gTlVMOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgZmxhZyAmIDI6CiAgICAgICAgICAgIHNlbGYuX19yZWFkKDIpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zPTApOgogICAgICAgICIiIlNldCB0aGUgc3RyZWFtJ3MgZmlsZSBwb2ludGVyIHRvIHBvcy4gTmVnYXRpdmUgc2Vla2luZwogICAgICAgICAgIGlzIGZvcmJpZGRlbi4KICAgICAgICAiIiIKICAgICAgICBpZiBwb3MgLSBzZWxmLnBvcyA+PSAwOgogICAgICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChwb3MgLSBzZWxmLnBvcywgc2VsZi5idWZzaXplKQogICAgICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoYmxvY2tzKToKICAgICAgICAgICAgICAgIHNlbGYucmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIHNlbGYucmVhZChyZW1haW5kZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoInNlZWtpbmcgYmFja3dhcmRzIGlzIG5vdCBhbGxvd2VkIikKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplPU5vbmUpOgogICAgICAgICIiIlJldHVybiB0aGUgbmV4dCBzaXplIG51bWJlciBvZiBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgICAgSWYgc2l6ZSBpcyBub3QgZGVmaW5lZCwgcmV0dXJuIGFsbCBieXRlcyBvZiB0aGUgc3RyZWFtCiAgICAgICAgICAgdXAgdG8gRU9GLgogICAgICAgICIiIgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgdCA9IFtdCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLl9yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYnVmID0gIiIuam9pbih0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2l6ZSkKICAgICAgICBzZWxmLnBvcyArPSBsZW4oYnVmKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgPT0gInRhciI6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQoKICAgICAgICBjID0gbGVuKHNlbGYuZGJ1ZikKICAgICAgICB0ID0gW3NlbGYuZGJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgYnVmID0gc2VsZi5jbXAuZGVjb21wcmVzcyhidWYpCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5kYnVmID0gdFtzaXplOl0KICAgICAgICByZXR1cm4gdFs6c2l6ZV0KCiAgICBkZWYgX19yZWFkKHNlbGYsIHNpemUpOgogICAgICAgICIiIlJldHVybiBzaXplIGJ5dGVzIGZyb20gc3RyZWFtLiBJZiBpbnRlcm5hbCBidWZmZXIgaXMgZW1wdHksCiAgICAgICAgICAgcmVhZCBhbm90aGVyIGJsb2NrIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAiIiIKICAgICAgICBjID0gbGVuKHNlbGYuYnVmKQogICAgICAgIHQgPSBbc2VsZi5idWZdCiAgICAgICAgd2hpbGUgYyA8IHNpemU6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHQuYXBwZW5kKGJ1ZikKICAgICAgICAgICAgYyArPSBsZW4oYnVmKQogICAgICAgIHQgPSAiIi5qb2luKHQpCiAgICAgICAgc2VsZi5idWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQojIGNsYXNzIF9TdHJlYW0KCmNsYXNzIF9TdHJlYW1Qcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICBkZXRlY3Rpb24gZm9yIHRoZSBTdHJlYW0gaW50ZXJmYWNlIChtb2RlICdyfConKS4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlb2JqKToKICAgICAgICBzZWxmLmZpbGVvYmogPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWYgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgc2VsZi5yZWFkID0gc2VsZi5maWxlb2JqLnJlYWQKICAgICAgICByZXR1cm4gc2VsZi5idWYKCiAgICBkZWYgZ2V0Y29tcHR5cGUoc2VsZik6CiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiXDAzN1wyMTNcMDEwIik6CiAgICAgICAgICAgIHJldHVybiAiZ3oiCiAgICAgICAgaWYgc2VsZi5idWYuc3RhcnRzd2l0aCgiQlpoOTEiKToKICAgICAgICAgICAgcmV0dXJuICJiejIiCiAgICAgICAgcmV0dXJuICJ0YXIiCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgU3RyZWFtUHJveHkKCmNsYXNzIF9CWjJQcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIGV4dGVybmFsIGZpbGUgb2JqZWN0CiAgICAgICBzdXBwb3J0IGZvciAicjpiejIiIGFuZCAidzpiejIiIG1vZGVzLiBUaGlzIGlzIGFjdHVhbGx5CiAgICAgICBhIHdvcmthcm91bmQgZm9yIGEgbGltaXRhdGlvbiBpbiBiejIgbW9kdWxlJ3MgQloyRmlsZQogICAgICAgY2xhc3Mgd2hpY2ggKHVubGlrZSBnemlwLkd6aXBGaWxlKSBoYXMgbm8gc3VwcG9ydCBmb3IKICAgICAgIGEgZmlsZSBvYmplY3QgYXJndW1lbnQuCiAgICAiIiIKCiAgICBibG9ja3NpemUgPSAxNiAqIDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgbW9kZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLmluaXQoKQoKICAgIGRlZiBpbml0KHNlbGYpOgogICAgICAgIGltcG9ydCBiejIKICAgICAgICBzZWxmLnBvcyA9IDAKICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInIiOgogICAgICAgICAgICBzZWxmLmJ6Mm9iaiA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlaygwKQogICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5iejJvYmogPSBiejIuQloyQ29tcHJlc3NvcigpCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgYiA9IFtzZWxmLmJ1Zl0KICAgICAgICB4ID0gbGVuKHNlbGYuYnVmKQogICAgICAgIHdoaWxlIHggPCBzaXplOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByYXcgPSBzZWxmLmZpbGVvYmoucmVhZChzZWxmLmJsb2Nrc2l6ZSkKICAgICAgICAgICAgICAgIGRhdGEgPSBzZWxmLmJ6Mm9iai5kZWNvbXByZXNzKHJhdykKICAgICAgICAgICAgICAgIGIuYXBwZW5kKGRhdGEpCiAgICAgICAgICAgIGV4Y2VwdCBFT0ZFcnJvcjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHggKz0gbGVuKGRhdGEpCiAgICAgICAgc2VsZi5idWYgPSAiIi5qb2luKGIpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmWzpzaXplXQogICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2l6ZTpdCiAgICAgICAgc2VsZi5wb3MgKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHNlZWsoc2VsZiwgcG9zKToKICAgICAgICBpZiBwb3MgPCBzZWxmLnBvczoKICAgICAgICAgICAgc2VsZi5pbml0KCkKICAgICAgICBzZWxmLnJlYWQocG9zIC0gc2VsZi5wb3MpCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYucG9zCgogICAgZGVmIHdyaXRlKHNlbGYsIGRhdGEpOgogICAgICAgIHNlbGYucG9zICs9IGxlbihkYXRhKQogICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmNvbXByZXNzKGRhdGEpCiAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IjoKICAgICAgICAgICAgcmF3ID0gc2VsZi5iejJvYmouZmx1c2goKQogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUocmF3KQogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgX0JaMlByb3h5CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgRXh0cmFjdGlvbiBmaWxlIG9iamVjdAojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNsYXNzIF9GaWxlSW5GaWxlKG9iamVjdCk6CiAgICAiIiJBIHRoaW4gd3JhcHBlciBhcm91bmQgYW4gZXhpc3RpbmcgZmlsZSBvYmplY3QgdGhhdAogICAgICAgcHJvdmlkZXMgYSBwYXJ0IG9mIGl0cyBkYXRhIGFzIGFuIGluZGl2aWR1YWwgZmlsZQogICAgICAgb2JqZWN0LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmosIG9mZnNldCwgc2l6ZSwgc3BhcnNlPU5vbmUpOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLm9mZnNldCA9IG9mZnNldAogICAgICAgIHNlbGYuc2l6ZSA9IHNpemUKICAgICAgICBzZWxmLnNwYXJzZSA9IHNwYXJzZQogICAgICAgIHNlbGYucG9zaXRpb24gPSAwCgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIHNlbGYucG9zaXRpb24KCiAgICBkZWYgc2VlayhzZWxmLCBwb3NpdGlvbik6CiAgICAgICAgIiIiU2VlayB0byBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYucG9zaXRpb24gPSBwb3NpdGlvbgoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmVhZCBkYXRhIGZyb20gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICBzaXplID0gc2VsZi5zaXplIC0gc2VsZi5wb3NpdGlvbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNpemUgPSBtaW4oc2l6ZSwgc2VsZi5zaXplIC0gc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgc2VsZi5zcGFyc2UgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucmVhZG5vcm1hbChzaXplKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnJlYWRzcGFyc2Uoc2l6ZSkKCiAgICBkZWYgcmVhZG5vcm1hbChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3IgcmVndWxhciBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHNlbGYucG9zaXRpb24pCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iai5yZWFkKHNpemUpCgogICAgZGVmIHJlYWRzcGFyc2Uoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5yZWFkc3BhcnNlc2VjdGlvbihzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oYnVmKQogICAgICAgICAgICBkYXRhLmFwcGVuZChidWYpCiAgICAgICAgcmV0dXJuICIiLmpvaW4oZGF0YSkKCiAgICBkZWYgcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBhIHNpbmdsZSBzZWN0aW9uIG9mIGEgc3BhcnNlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3NpdGlvbiAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgcmVhbHBvcykKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmoucmVhZChzaXplKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgICAgICByZXR1cm4gTlVMICogc2l6ZQojY2xhc3MgX0ZpbGVJbkZpbGUKCgpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuCiAgICAiIiIKICAgIGJsb2Nrc2l6ZSA9IDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gX0ZpbGVJbkZpbGUodGFyZmlsZS5maWxlb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldGF0dHIodGFyaW5mbywgInNwYXJzZSIsIE5vbmUpKQogICAgICAgIHNlbGYubmFtZSA9IHRhcmluZm8ubmFtZQogICAgICAgIHNlbGYubW9kZSA9ICJyIgogICAgICAgIHNlbGYuY2xvc2VkID0gRmFsc2UKICAgICAgICBzZWxmLnNpemUgPSB0YXJpbmZvLnNpemUKCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDAKICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIGF0IG1vc3Qgc2l6ZSBieXRlcyBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIG5vdAogICAgICAgICAgIHByZXNlbnQgb3IgTm9uZSwgcmVhZCBhbGwgZGF0YSB1bnRpbCBFT0YgaXMgcmVhY2hlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgaWYgc2VsZi5idWZmZXI6CiAgICAgICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6c2l6ZV0KICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gc2VsZi5idWZmZXJbc2l6ZTpdCgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnVmICs9IHNlbGYuZmlsZW9iai5yZWFkKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgKz0gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSAtIGxlbihidWYpKQoKICAgICAgICBzZWxmLnBvc2l0aW9uICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIG9uZSBlbnRpcmUgbGluZSBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIHByZXNlbnQKICAgICAgICAgICBhbmQgbm9uLW5lZ2F0aXZlLCByZXR1cm4gYSBzdHJpbmcgd2l0aCBhdCBtb3N0IHRoYXQKICAgICAgICAgICBzaXplLCB3aGljaCBtYXkgYmUgYW4gaW5jb21wbGV0ZSBsaW5lLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgaWYgIlxuIiBpbiBzZWxmLmJ1ZmZlcjoKICAgICAgICAgICAgcG9zID0gc2VsZi5idWZmZXIuZmluZCgiXG4iKSArIDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWZmZXJzID0gW3NlbGYuYnVmZmVyXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBidWZmZXJzLmFwcGVuZChidWYpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmIG9yICJcbiIgaW4gYnVmOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gIiIuam9pbihidWZmZXJzKQogICAgICAgICAgICAgICAgICAgIHBvcyA9IHNlbGYuYnVmZmVyLmZpbmQoIlxuIikgKyAxCiAgICAgICAgICAgICAgICAgICAgaWYgcG9zID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICMgbm8gbmV3bGluZSBmb3VuZC4KICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gbGVuKHNlbGYuYnVmZmVyKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNpemUgIT0gLTE6CiAgICAgICAgICAgIHBvcyA9IG1pbihzaXplLCBwb3MpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyWzpwb3NdCiAgICAgICAgc2VsZi5idWZmZXIgPSBzZWxmLmJ1ZmZlcltwb3M6XQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IHdpdGggYWxsIHJlbWFpbmluZyBsaW5lcy4KICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBbXQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICByZXR1cm4gc2VsZi5wb3NpdGlvbgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcywgd2hlbmNlPW9zLlNFRUtfU0VUKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBpZiB3aGVuY2UgPT0gb3MuU0VFS19TRVQ6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0NVUjoKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtYXgoc2VsZi5wb3NpdGlvbiArIHBvcywgMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4oc2VsZi5wb3NpdGlvbiArIHBvcywgc2VsZi5zaXplKQogICAgICAgIGVsaWYgd2hlbmNlID09IG9zLlNFRUtfRU5EOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KG1pbihzZWxmLnNpemUgKyBwb3MsIHNlbGYuc2l6ZSksIDApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSW52YWxpZCBhcmd1bWVudCIpCgogICAgICAgIHNlbGYuYnVmZmVyID0gIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLnBvc2l0aW9uKQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgZmlsZSBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIkdldCBhbiBpdGVyYXRvciBvdmVyIHRoZSBmaWxlJ3MgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHlpZWxkIGxpbmUKI2NsYXNzIEV4RmlsZU9iamVjdAoKIy0tLS0tLS0tLS0tLS0tLS0tLQojIEV4cG9ydGVkIENsYXNzZXMKIy0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBUYXJJbmZvKG9iamVjdCk6CiAgICAiIiJJbmZvcm1hdGlvbmFsIGNsYXNzIHdoaWNoIGhvbGRzIHRoZSBkZXRhaWxzIGFib3V0IGFuCiAgICAgICBhcmNoaXZlIG1lbWJlciBnaXZlbiBieSBhIHRhciBoZWFkZXIgYmxvY2suCiAgICAgICBUYXJJbmZvIG9iamVjdHMgYXJlIHJldHVybmVkIGJ5IFRhckZpbGUuZ2V0bWVtYmVyKCksCiAgICAgICBUYXJGaWxlLmdldG1lbWJlcnMoKSBhbmQgVGFyRmlsZS5nZXR0YXJpbmZvKCkgYW5kIGFyZQogICAgICAgdXN1YWxseSBjcmVhdGVkIGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT0iIik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QuIG5hbWUgaXMgdGhlIG9wdGlvbmFsIG5hbWUKICAgICAgICAgICBvZiB0aGUgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUgICAgICAgICMgbWVtYmVyIG5hbWUgKGRpcm5hbWVzIG11c3QgZW5kIHdpdGggJy8nKQogICAgICAgIHNlbGYubW9kZSA9IDA2NjYgICAgICAgICMgZmlsZSBwZXJtaXNzaW9ucwogICAgICAgIHNlbGYudWlkID0gMCAgICAgICAgICAgICMgdXNlciBpZAogICAgICAgIHNlbGYuZ2lkID0gMCAgICAgICAgICAgICMgZ3JvdXAgaWQKICAgICAgICBzZWxmLnNpemUgPSAwICAgICAgICAgICAjIGZpbGUgc2l6ZQogICAgICAgIHNlbGYubXRpbWUgPSAwICAgICAgICAgICMgbW9kaWZpY2F0aW9uIHRpbWUKICAgICAgICBzZWxmLmNoa3N1bSA9IDAgICAgICAgICAjIGhlYWRlciBjaGVja3N1bQogICAgICAgIHNlbGYudHlwZSA9IFJFR1RZUEUgICAgICMgbWVtYmVyIHR5cGUKICAgICAgICBzZWxmLmxpbmtuYW1lID0gIiIgICAgICAjIGxpbmsgbmFtZQogICAgICAgIHNlbGYudW5hbWUgPSAidXNlciIgICAgICMgdXNlciBuYW1lCiAgICAgICAgc2VsZi5nbmFtZSA9ICJncm91cCIgICAgIyBncm91cCBuYW1lCiAgICAgICAgc2VsZi5kZXZtYWpvciA9IDAgICAgICAgIyBkZXZpY2UgbWFqb3IgbnVtYmVyCiAgICAgICAgc2VsZi5kZXZtaW5vciA9IDAgICAgICAgIyBkZXZpY2UgbWlub3IgbnVtYmVyCgogICAgICAgIHNlbGYub2Zmc2V0ID0gMCAgICAgICAgICMgdGhlIHRhciBoZWFkZXIgc3RhcnRzIGhlcmUKICAgICAgICBzZWxmLm9mZnNldF9kYXRhID0gMCAgICAjIHRoZSBmaWxlJ3MgZGF0YSBzdGFydHMgaGVyZQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIjwlcyAlciBhdCAlI3g+IiAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXyxzZWxmLm5hbWUsaWQoc2VsZikpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbWJ1ZihjbHMsIGJ1Zik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QgZnJvbSBhIDUxMiBieXRlIHN0cmluZyBidWZmZXIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGVuKGJ1ZikgIT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigidHJ1bmNhdGVkIGhlYWRlciIpCiAgICAgICAgaWYgYnVmLmNvdW50KE5VTCkgPT0gQkxPQ0tTSVpFOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigiZW1wdHkgaGVhZGVyIikKCiAgICAgICAgY2hrc3VtID0gbnRpKGJ1ZlsxNDg6MTU2XSkKICAgICAgICBpZiBjaGtzdW0gbm90IGluIGNhbGNfY2hrc3VtcyhidWYpOgogICAgICAgICAgICByYWlzZSBIZWFkZXJFcnJvcigiYmFkIGNoZWNrc3VtIikKCiAgICAgICAgdGFyaW5mbyA9IGNscygpCiAgICAgICAgdGFyaW5mby5idWYgPSBidWYKICAgICAgICB0YXJpbmZvLm5hbWUgPSBidWZbMDoxMDBdLnJzdHJpcChOVUwpCiAgICAgICAgdGFyaW5mby5tb2RlID0gbnRpKGJ1ZlsxMDA6MTA4XSkKICAgICAgICB0YXJpbmZvLnVpZCA9IG50aShidWZbMTA4OjExNl0pCiAgICAgICAgdGFyaW5mby5naWQgPSBudGkoYnVmWzExNjoxMjRdKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG50aShidWZbMTI0OjEzNl0pCiAgICAgICAgdGFyaW5mby5tdGltZSA9IG50aShidWZbMTM2OjE0OF0pCiAgICAgICAgdGFyaW5mby5jaGtzdW0gPSBjaGtzdW0KICAgICAgICB0YXJpbmZvLnR5cGUgPSBidWZbMTU2OjE1N10KICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gYnVmWzE1NzoyNTddLnJzdHJpcChOVUwpCiAgICAgICAgdGFyaW5mby51bmFtZSA9IGJ1ZlsyNjU6Mjk3XS5yc3RyaXAoTlVMKQogICAgICAgIHRhcmluZm8uZ25hbWUgPSBidWZbMjk3OjMyOV0ucnN0cmlwKE5VTCkKICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gbnRpKGJ1ZlszMjk6MzM3XSkKICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gbnRpKGJ1ZlszMzc6MzQ1XSkKICAgICAgICBwcmVmaXggPSBidWZbMzQ1OjUwMF0ucnN0cmlwKE5VTCkKCiAgICAgICAgaWYgcHJlZml4IGFuZCBub3QgdGFyaW5mby5pc3NwYXJzZSgpOgogICAgICAgICAgICB0YXJpbmZvLm5hbWUgPSBwcmVmaXggKyAiLyIgKyB0YXJpbmZvLm5hbWUKCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgdG9idWYoc2VsZiwgcG9zaXg9RmFsc2UpOgogICAgICAgICIiIlJldHVybiBhIHRhciBoZWFkZXIgYXMgYSBzdHJpbmcgb2YgNTEyIGJ5dGUgYmxvY2tzLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgdHlwZSA9IHNlbGYudHlwZQogICAgICAgIHByZWZpeCA9ICIiCgogICAgICAgIGlmIHNlbGYubmFtZS5lbmRzd2l0aCgiLyIpOgogICAgICAgICAgICB0eXBlID0gRElSVFlQRQoKICAgICAgICBpZiB0eXBlIGluIChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LKToKICAgICAgICAgICAgIyBQcmV2ZW50ICIuLy4vQExvbmdMaW5rIiBmcm9tIGJlaW5nIG5vcm1hbGl6ZWQuCiAgICAgICAgICAgIG5hbWUgPSBzZWxmLm5hbWUKICAgICAgICBlbHNlOgogICAgICAgICAgICBuYW1lID0gbm9ybXBhdGgoc2VsZi5uYW1lKQoKICAgICAgICBpZiB0eXBlID09IERJUlRZUEU6CiAgICAgICAgICAgICMgZGlyZWN0b3JpZXMgc2hvdWxkIGVuZCB3aXRoICcvJwogICAgICAgICAgICBuYW1lICs9ICIvIgoKICAgICAgICBsaW5rbmFtZSA9IHNlbGYubGlua25hbWUKICAgICAgICBpZiBsaW5rbmFtZToKICAgICAgICAgICAgIyBpZiBsaW5rbmFtZSBpcyBlbXB0eSB3ZSBlbmQgdXAgd2l0aCBhICcuJwogICAgICAgICAgICBsaW5rbmFtZSA9IG5vcm1wYXRoKGxpbmtuYW1lKQoKICAgICAgICBpZiBwb3NpeDoKICAgICAgICAgICAgaWYgc2VsZi5zaXplID4gTUFYU0laRV9NRU1CRVI6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJmaWxlIGlzIHRvbyBsYXJnZSAoPj0gOCBHQikiKQoKICAgICAgICAgICAgaWYgbGVuKHNlbGYubGlua25hbWUpID4gTEVOR1RIX0xJTks6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJsaW5rbmFtZSBpcyB0b28gbG9uZyAoPiVkKSIgJSAoTEVOR1RIX0xJTkspKQoKICAgICAgICAgICAgaWYgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgICAgICBwcmVmaXggPSBuYW1lWzpMRU5HVEhfUFJFRklYICsgMV0KICAgICAgICAgICAgICAgIHdoaWxlIHByZWZpeCBhbmQgcHJlZml4Wy0xXSAhPSAiLyI6CiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZVtsZW4ocHJlZml4KTpdCiAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXhbOi0xXQoKICAgICAgICAgICAgICAgIGlmIG5vdCBwcmVmaXggb3IgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibmFtZSBpcyB0b28gbG9uZyIpCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIGxlbihzZWxmLmxpbmtuYW1lKSA+IExFTkdUSF9MSU5LOgogICAgICAgICAgICAgICAgYnVmICs9IHNlbGYuX2NyZWF0ZV9nbnVsb25nKHNlbGYubGlua25hbWUsIEdOVVRZUEVfTE9OR0xJTkspCgogICAgICAgICAgICBpZiBsZW4obmFtZSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgICAgIGJ1ZiArPSBzZWxmLl9jcmVhdGVfZ251bG9uZyhuYW1lLCBHTlVUWVBFX0xPTkdOQU1FKQoKICAgICAgICBwYXJ0cyA9IFsKICAgICAgICAgICAgc3RuKG5hbWUsIDEwMCksCiAgICAgICAgICAgIGl0bihzZWxmLm1vZGUgJiAwNzc3NywgOCwgcG9zaXgpLAogICAgICAgICAgICBpdG4oc2VsZi51aWQsIDgsIHBvc2l4KSwKICAgICAgICAgICAgaXRuKHNlbGYuZ2lkLCA4LCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLnNpemUsIDEyLCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLm10aW1lLCAxMiwgcG9zaXgpLAogICAgICAgICAgICAiICAgICAgICAiLCAjIGNoZWNrc3VtIGZpZWxkCiAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgIHN0bihzZWxmLmxpbmtuYW1lLCAxMDApLAogICAgICAgICAgICBzdG4oTUFHSUMsIDYpLAogICAgICAgICAgICBzdG4oVkVSU0lPTiwgMiksCiAgICAgICAgICAgIHN0bihzZWxmLnVuYW1lLCAzMiksCiAgICAgICAgICAgIHN0bihzZWxmLmduYW1lLCAzMiksCiAgICAgICAgICAgIGl0bihzZWxmLmRldm1ham9yLCA4LCBwb3NpeCksCiAgICAgICAgICAgIGl0bihzZWxmLmRldm1pbm9yLCA4LCBwb3NpeCksCiAgICAgICAgICAgIHN0bihwcmVmaXgsIDE1NSkKICAgICAgICBdCgogICAgICAgIGJ1ZiArPSBzdHJ1Y3QucGFjaygiJWRzIiAlIEJMT0NLU0laRSwgIiIuam9pbihwYXJ0cykpCiAgICAgICAgY2hrc3VtID0gY2FsY19jaGtzdW1zKGJ1ZlstQkxPQ0tTSVpFOl0pWzBdCiAgICAgICAgYnVmID0gYnVmWzotMzY0XSArICIlMDZvXDAiICUgY2hrc3VtICsgYnVmWy0zNTc6XQogICAgICAgIHNlbGYuYnVmID0gYnVmCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBfY3JlYXRlX2dudWxvbmcoc2VsZiwgbmFtZSwgdHlwZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgR05VIGxvbmduYW1lL2xvbmdsaW5rIGhlYWRlciBmcm9tIG5hbWUuCiAgICAgICAgICAgSXQgY29uc2lzdHMgb2YgYW4gZXh0ZW5kZWQgdGFyIGhlYWRlciwgd2l0aCB0aGUgbGVuZ3RoCiAgICAgICAgICAgb2YgdGhlIGxvbmduYW1lIGFzIHNpemUsIGZvbGxvd2VkIGJ5IGRhdGEgYmxvY2tzLAogICAgICAgICAgIHdoaWNoIGNvbnRhaW4gdGhlIGxvbmduYW1lIGFzIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZy4KICAgICAgICAiIiIKICAgICAgICBuYW1lICs9IE5VTAoKICAgICAgICB0YXJpbmZvID0gc2VsZi5fX2NsYXNzX18oKQogICAgICAgIHRhcmluZm8ubmFtZSA9ICIuLy4vQExvbmdMaW5rIgogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLm1vZGUgPSAwCiAgICAgICAgdGFyaW5mby5zaXplID0gbGVuKG5hbWUpCgogICAgICAgICMgY3JlYXRlIGV4dGVuZGVkIGhlYWRlcgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoKQogICAgICAgICMgY3JlYXRlIG5hbWUgYmxvY2tzCiAgICAgICAgYnVmICs9IG5hbWUKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4obmFtZSksIEJMT0NLU0laRSkKICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICBidWYgKz0gKEJMT0NLU0laRSAtIHJlbWFpbmRlcikgKiBOVUwKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIGlzcmVnKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgaW4gUkVHVUxBUl9UWVBFUwogICAgZGVmIGlzZmlsZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pc3JlZygpCiAgICBkZWYgaXNkaXIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBESVJUWVBFCiAgICBkZWYgaXNzeW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBTWU1UWVBFCiAgICBkZWYgaXNsbmsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBMTktUWVBFCiAgICBkZWYgaXNjaHIoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBDSFJUWVBFCiAgICBkZWYgaXNibGsoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBCTEtUWVBFCiAgICBkZWYgaXNmaWZvKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gRklGT1RZUEUKICAgIGRlZiBpc3NwYXJzZShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFCiAgICBkZWYgaXNkZXYoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSwgRklGT1RZUEUpCiMgY2xhc3MgVGFySW5mbwoKY2xhc3MgVGFyRmlsZShvYmplY3QpOgogICAgIiIiVGhlIFRhckZpbGUgQ2xhc3MgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRvIHRhciBhcmNoaXZlcy4KICAgICIiIgoKICAgIGRlYnVnID0gMCAgICAgICAgICAgICAgICAgICAjIE1heSBiZSBzZXQgZnJvbSAwIChubyBtc2dzKSB0byAzIChhbGwgbXNncykKCiAgICBkZXJlZmVyZW5jZSA9IEZhbHNlICAgICAgICAgIyBJZiB0cnVlLCBhZGQgY29udGVudCBvZiBsaW5rZWQgZmlsZSB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRhciBmaWxlLCBlbHNlIHRoZSBsaW5rLgoKICAgIGlnbm9yZV96ZXJvcyA9IEZhbHNlICAgICAgICAjIElmIHRydWUsIHNraXBzIGVtcHR5IG9yIGludmFsaWQgYmxvY2tzIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29udGludWVzIHByb2Nlc3NpbmcuCgogICAgZXJyb3JsZXZlbCA9IDAgICAgICAgICAgICAgICMgSWYgMCwgZmF0YWwgZXJyb3JzIG9ubHkgYXBwZWFyIGluIGRlYnVnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBtZXNzYWdlcyAoaWYgZGVidWcgPj0gMCkuIElmID4gMCwgZXJyb3JzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgYXMgZXhjZXB0aW9ucy4KCiAgICBwb3NpeCA9IEZhbHNlICAgICAgICAgICAgICAgIyBJZiBUcnVlLCBnZW5lcmF0ZXMgUE9TSVguMS0xOTkwLWNvbXBsaWFudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZXMgKG5vIEdOVSBleHRlbnNpb25zISkKCiAgICBmaWxlb2JqZWN0ID0gRXhGaWxlT2JqZWN0CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiT3BlbiBhbiAodW5jb21wcmVzc2VkKSB0YXIgYXJjaGl2ZSBgbmFtZScuIGBtb2RlJyBpcyBlaXRoZXIgJ3InIHRvCiAgICAgICAgICAgcmVhZCBmcm9tIGFuIGV4aXN0aW5nIGFyY2hpdmUsICdhJyB0byBhcHBlbmQgZGF0YSB0byBhbiBleGlzdGluZwogICAgICAgICAgIGZpbGUgb3IgJ3cnIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIG92ZXJ3cml0aW5nIGFuIGV4aXN0aW5nIG9uZS4gYG1vZGUnCiAgICAgICAgICAgZGVmYXVsdHMgdG8gJ3InLgogICAgICAgICAgIElmIGBmaWxlb2JqJyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBmb3IgcmVhZGluZyBvciB3cml0aW5nIGRhdGEuIElmIGl0CiAgICAgICAgICAgY2FuIGJlIGRldGVybWluZWQsIGBtb2RlJyBpcyBvdmVycmlkZGVuIGJ5IGBmaWxlb2JqJ3MgbW9kZS4KICAgICAgICAgICBgZmlsZW9iaicgaXMgbm90IGNsb3NlZCwgd2hlbiBUYXJGaWxlIGlzIGNsb3NlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLm5hbWUgPSBvcy5wYXRoLmFic3BhdGgobmFtZSkKCiAgICAgICAgaWYgbGVuKG1vZGUpID4gMSBvciBtb2RlIG5vdCBpbiAicmF3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIpCiAgICAgICAgc2VsZi5fbW9kZSA9IG1vZGUKICAgICAgICBzZWxmLm1vZGUgPSB7InIiOiAicmIiLCAiYSI6ICJyK2IiLCAidyI6ICJ3YiJ9W21vZGVdCgogICAgICAgIGlmIG5vdCBmaWxlb2JqOgogICAgICAgICAgICBmaWxlb2JqID0gZmlsZShzZWxmLm5hbWUsIHNlbGYubW9kZSkKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgc2VsZi5uYW1lIGlzIE5vbmUgYW5kIGhhc2F0dHIoZmlsZW9iaiwgIm5hbWUiKToKICAgICAgICAgICAgICAgIHNlbGYubmFtZSA9IG9zLnBhdGguYWJzcGF0aChmaWxlb2JqLm5hbWUpCiAgICAgICAgICAgIGlmIGhhc2F0dHIoZmlsZW9iaiwgIm1vZGUiKToKICAgICAgICAgICAgICAgIHNlbGYubW9kZSA9IGZpbGVvYmoubW9kZQogICAgICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKCiAgICAgICAgIyBJbml0IGRhdGFzdHJ1Y3R1cmVzCiAgICAgICAgc2VsZi5jbG9zZWQgPSBGYWxzZQogICAgICAgIHNlbGYubWVtYmVycyA9IFtdICAgICAgICMgbGlzdCBvZiBtZW1iZXJzIGFzIFRhckluZm8gb2JqZWN0cwogICAgICAgIHNlbGYuX2xvYWRlZCA9IEZhbHNlICAgICMgZmxhZyBpZiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZAogICAgICAgIHNlbGYub2Zmc2V0ID0gMEwgICAgICAgICMgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgYXJjaGl2ZSBmaWxlCiAgICAgICAgc2VsZi5pbm9kZXMgPSB7fSAgICAgICAgIyBkaWN0aW9uYXJ5IGNhY2hpbmcgdGhlIGlub2RlcyBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYXJjaGl2ZSBtZW1iZXJzIGFscmVhZHkgYWRkZWQKCiAgICAgICAgaWYgc2VsZi5fbW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBzZWxmLm5leHQoKQoKICAgICAgICBpZiBzZWxmLl9tb2RlID09ICJhIjoKICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICMgYmVmb3JlIHRoZSBmaXJzdCBlbXB0eSBibG9jay4KICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IE5vbmUKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBSZWFkRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoMCkKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKC0gQkxPQ0tTSVpFLCAxKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGNsYXNzbWV0aG9kcyB3aGljaCBhY3QgYXMgYWx0ZXJuYXRlIGNvbnN0cnVjdG9ycyB0byB0aGUKICAgICMgVGFyRmlsZSBjbGFzcy4gVGhlIG9wZW4oKSBtZXRob2QgaXMgdGhlIG9ubHkgb25lIHRoYXQgaXMgbmVlZGVkIGZvcgogICAgIyBwdWJsaWMgdXNlOyBpdCBpcyB0aGUgInN1cGVyIi1jb25zdHJ1Y3RvciBhbmQgaXMgYWJsZSB0byBzZWxlY3QgYW4KICAgICMgYWRlcXVhdGUgInN1YiItY29uc3RydWN0b3IgZm9yIGEgcGFydGljdWxhciBjb21wcmVzc2lvbiB1c2luZyB0aGUgbWFwcGluZwogICAgIyBmcm9tIE9QRU5fTUVUSC4KICAgICMKICAgICMgVGhpcyBjb25jZXB0IGFsbG93cyBvbmUgdG8gc3ViY2xhc3MgVGFyRmlsZSB3aXRob3V0IGxvc2luZyB0aGUgY29tZm9ydCBvZgogICAgIyB0aGUgc3VwZXItY29uc3RydWN0b3IuIEEgc3ViLWNvbnN0cnVjdG9yIGlzIHJlZ2lzdGVyZWQgYW5kIG1hZGUgYXZhaWxhYmxlCiAgICAjIGJ5IGFkZGluZyBpdCB0byB0aGUgbWFwcGluZyBpbiBPUEVOX01FVEguCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgb3BlbihjbHMsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgYnVmc2l6ZT0yMCo1MTIpOgogICAgICAgICIiIk9wZW4gYSB0YXIgYXJjaGl2ZSBmb3IgcmVhZGluZywgd3JpdGluZyBvciBhcHBlbmRpbmcuIFJldHVybgogICAgICAgICAgIGFuIGFwcHJvcHJpYXRlIFRhckZpbGUgY2xhc3MuCgogICAgICAgICAgIG1vZGU6CiAgICAgICAgICAgJ3InIG9yICdyOionIG9wZW4gZm9yIHJlYWRpbmcgd2l0aCB0cmFuc3BhcmVudCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOicgICAgICAgICBvcGVuIGZvciByZWFkaW5nIGV4Y2x1c2l2ZWx5IHVuY29tcHJlc3NlZAogICAgICAgICAgICdyOmd6JyAgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICdyOmJ6MicgICAgICBvcGVuIGZvciByZWFkaW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KICAgICAgICAgICAnYScgb3IgJ2E6JyAgb3BlbiBmb3IgYXBwZW5kaW5nCiAgICAgICAgICAgJ3cnIG9yICd3OicgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aG91dCBjb21wcmVzc2lvbgogICAgICAgICAgICd3Omd6JyAgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICd3OmJ6MicgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KCiAgICAgICAgICAgJ3J8KicgICAgICAgIG9wZW4gYSBzdHJlYW0gb2YgdGFyIGJsb2NrcyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3J8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzIGZvciByZWFkaW5nCiAgICAgICAgICAgJ3J8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAncnxiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAnd3wnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICIiIgoKICAgICAgICBpZiBub3QgbmFtZSBhbmQgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5vdGhpbmcgdG8gb3BlbiIpCgogICAgICAgIGlmIG1vZGUgaW4gKCJyIiwgInI6KiIpOgogICAgICAgICAgICAjIEZpbmQgb3V0IHdoaWNoICpvcGVuKCkgaXMgYXBwcm9wcmlhdGUgZm9yIG9wZW5pbmcgdGhlIGZpbGUuCiAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2F2ZWRfcG9zID0gZmlsZW9iai50ZWxsKCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCAiciIsIGZpbGVvYmopCiAgICAgICAgICAgICAgICBleGNlcHQgKFJlYWRFcnJvciwgQ29tcHJlc3Npb25FcnJvcik6CiAgICAgICAgICAgICAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9iai5zZWVrKHNhdmVkX3BvcykKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImZpbGUgY291bGQgbm90IGJlIG9wZW5lZCBzdWNjZXNzZnVsbHkiKQoKICAgICAgICBlbGlmICI6IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCI6IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgIyBTZWxlY3QgdGhlICpvcGVuKCkgZnVuY3Rpb24gYWNjb3JkaW5nIHRvCiAgICAgICAgICAgICMgZ2l2ZW4gY29tcHJlc3Npb24uCiAgICAgICAgICAgIGlmIGNvbXB0eXBlIGluIGNscy5PUEVOX01FVEg6CiAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cihjbHMsIGNscy5PUEVOX01FVEhbY29tcHR5cGVdKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5rbm93biBjb21wcmVzc2lvbiB0eXBlICVyIiAlIGNvbXB0eXBlKQogICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCBmaWxlbW9kZSwgZmlsZW9iaikKCiAgICAgICAgZWxpZiAifCIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgifCIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgIGlmIGZpbGVtb2RlIG5vdCBpbiAicnciOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwKICAgICAgICAgICAgICAgICAgICBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkpCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgaW4gImF3IjoKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVuZGlzY2VybmlibGUgbW9kZSIpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgdGFyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUpOgogICAgICAgICIiIk9wZW4gdW5jb21wcmVzc2VkIHRhciBhcmNoaXZlIG5hbWUgZm9yIHJlYWRpbmcgb3Igd3JpdGluZy4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJyYXciOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InLCAnYScgb3IgJ3cnIikKICAgICAgICByZXR1cm4gY2xzKG5hbWUsIG1vZGUsIGZpbGVvYmopCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZ3pvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIGxlbihtb2RlKSA+IDEgb3IgbW9kZSBub3QgaW4gInJ3IjoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJyBvciAndyciKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltcG9ydCBnemlwCiAgICAgICAgICAgIGd6aXAuR3ppcEZpbGUKICAgICAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoImd6aXAgbW9kdWxlIGlzIG5vdCBhdmFpbGFibGUiKQoKICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGZpbGVvYmogPSBmaWxlKG5hbWUsIG1vZGUgKyAiYiIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKG5hbWUsIG1vZGUsCiAgICAgICAgICAgICAgICBnemlwLkd6aXBGaWxlKG5hbWUsIG1vZGUsIGNvbXByZXNzbGV2ZWwsIGZpbGVvYmopKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGd6aXAgZmlsZSIpCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBiejJvcGVuKGNscywgbmFtZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgY29tcHJlc3NsZXZlbD05KToKICAgICAgICAiIiJPcGVuIGJ6aXAyIGNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLgogICAgICAgICAgIEFwcGVuZGluZyBpcyBub3QgYWxsb3dlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4obW9kZSkgPiAxIG9yIG1vZGUgbm90IGluICJydyI6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnLiIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IF9CWjJQcm94eShmaWxlb2JqLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGZpbGVvYmogPSBiejIuQloyRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsPWNvbXByZXNzbGV2ZWwpCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmopCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgYnppcDIgZmlsZSIpCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KICAgIE9QRU5fTUVUSCA9IHsKICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcgogICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCiAgICAgICAgImJ6MiI6ICJiejJvcGVuIiAgICAjIGJ6aXAyIGNvbXByZXNzZWQgdGFyCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUKICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGlmIHNlbGYuX21vZGUgaW4gImF3IjoKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgKiAyKSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gKEJMT0NLU0laRSAqIDIpCiAgICAgICAgICAgICMgZmlsbCB1cCB0aGUgZW5kIHdpdGggemVyby1ibG9ja3MKICAgICAgICAgICAgIyAobGlrZSBvcHRpb24gLWIyMCBmb3IgdGFyIGRvZXMpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHNlbGYub2Zmc2V0LCBSRUNPUkRTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChSRUNPUkRTSVpFIC0gcmVtYWluZGVyKSkKCiAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIGdldG1lbWJlcihzZWxmLCBuYW1lKToKICAgICAgICAiIiJSZXR1cm4gYSBUYXJJbmZvIG9iamVjdCBmb3IgbWVtYmVyIGBuYW1lJy4gSWYgYG5hbWUnIGNhbiBub3QgYmUKICAgICAgICAgICBmb3VuZCBpbiB0aGUgYXJjaGl2ZSwgS2V5RXJyb3IgaXMgcmFpc2VkLiBJZiBhIG1lbWJlciBvY2N1cnMgbW9yZQogICAgICAgICAgIHRoYW4gb25jZSBpbiB0aGUgYXJjaGl2ZSwgaXRzIGxhc3Qgb2NjdXJlbmNlIGlzIGFzc3VtZWQgdG8gYmUgdGhlCiAgICAgICAgICAgbW9zdCB1cC10by1kYXRlIHZlcnNpb24uCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuX2dldG1lbWJlcihuYW1lKQogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoImZpbGVuYW1lICVyIG5vdCBmb3VuZCIgJSBuYW1lKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGdldG1lbWJlcnMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiBUYXJJbmZvIG9iamVjdHMuIFRoZQogICAgICAgICAgIGxpc3QgaGFzIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBtZW1iZXJzIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOiAgICAjIGlmIHdlIHdhbnQgdG8gb2J0YWluIGEgbGlzdCBvZgogICAgICAgICAgICBzZWxmLl9sb2FkKCkgICAgICAgICMgYWxsIG1lbWJlcnMsIHdlIGZpcnN0IGhhdmUgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNjYW4gdGhlIHdob2xlIGFyY2hpdmUuCiAgICAgICAgcmV0dXJuIHNlbGYubWVtYmVycwoKICAgIGRlZiBnZXRuYW1lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIHRoZWlyIG5hbWVzLiBJdCBoYXMKICAgICAgICAgICB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIFt0YXJpbmZvLm5hbWUgZm9yIHRhcmluZm8gaW4gc2VsZi5nZXRtZW1iZXJzKCldCgogICAgZGVmIGdldHRhcmluZm8oc2VsZiwgbmFtZT1Ob25lLCBhcmNuYW1lPU5vbmUsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZm9yIGVpdGhlciB0aGUgZmlsZSBgbmFtZScgb3IgdGhlIGZpbGUKICAgICAgICAgICBvYmplY3QgYGZpbGVvYmonICh1c2luZyBvcy5mc3RhdCBvbiBpdHMgZmlsZSBkZXNjcmlwdG9yKS4gWW91IGNhbgogICAgICAgICAgIG1vZGlmeSBzb21lIG9mIHRoZSBUYXJJbmZvJ3MgYXR0cmlidXRlcyBiZWZvcmUgeW91IGFkZCBpdCB1c2luZwogICAgICAgICAgIGFkZGZpbGUoKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJyBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlCiAgICAgICAgICAgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICAjIFdoZW4gZmlsZW9iaiBpcyBnaXZlbiwgcmVwbGFjZSBuYW1lIGJ5CiAgICAgICAgIyBmaWxlb2JqJ3MgcmVhbCBuYW1lLgogICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG5hbWUgPSBmaWxlb2JqLm5hbWUKCiAgICAgICAgIyBCdWlsZGluZyB0aGUgbmFtZSBvZiB0aGUgbWVtYmVyIGluIHRoZSBhcmNoaXZlLgogICAgICAgICMgQmFja3dhcmQgc2xhc2hlcyBhcmUgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlcywKICAgICAgICAjIEFic29sdXRlIHBhdGhzIGFyZSB0dXJuZWQgdG8gcmVsYXRpdmUgcGF0aHMuCiAgICAgICAgaWYgYXJjbmFtZSBpcyBOb25lOgogICAgICAgICAgICBhcmNuYW1lID0gbmFtZQogICAgICAgIGFyY25hbWUgPSBub3JtcGF0aChhcmNuYW1lKQogICAgICAgIGRydiwgYXJjbmFtZSA9IG9zLnBhdGguc3BsaXRkcml2ZShhcmNuYW1lKQogICAgICAgIHdoaWxlIGFyY25hbWVbMDoxXSA9PSAiLyI6CiAgICAgICAgICAgIGFyY25hbWUgPSBhcmNuYW1lWzE6XQoKICAgICAgICAjIE5vdywgZmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aAogICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBUYXJJbmZvKCkKCiAgICAgICAgIyBVc2Ugb3Muc3RhdCBvciBvcy5sc3RhdCwgZGVwZW5kaW5nIG9uIHBsYXRmb3JtCiAgICAgICAgIyBhbmQgaWYgc3ltbGlua3Mgc2hhbGwgYmUgcmVzb2x2ZWQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBOb25lOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibHN0YXQiKSBhbmQgbm90IHNlbGYuZGVyZWZlcmVuY2U6CiAgICAgICAgICAgICAgICBzdGF0cmVzID0gb3MubHN0YXQobmFtZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5zdGF0KG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3RhdHJlcyA9IG9zLmZzdGF0KGZpbGVvYmouZmlsZW5vKCkpCiAgICAgICAgbGlua25hbWUgPSAiIgoKICAgICAgICBzdG1kID0gc3RhdHJlcy5zdF9tb2RlCiAgICAgICAgaWYgc3RhdC5TX0lTUkVHKHN0bWQpOgogICAgICAgICAgICBpbm9kZSA9IChzdGF0cmVzLnN0X2lubywgc3RhdHJlcy5zdF9kZXYpCiAgICAgICAgICAgIGlmIG5vdCBzZWxmLmRlcmVmZXJlbmNlIGFuZCBcCiAgICAgICAgICAgICAgICAgICAgc3RhdHJlcy5zdF9ubGluayA+IDEgYW5kIGlub2RlIGluIHNlbGYuaW5vZGVzOgogICAgICAgICAgICAgICAgIyBJcyBpdCBhIGhhcmRsaW5rIHRvIGFuIGFscmVhZHkKICAgICAgICAgICAgICAgICMgYXJjaGl2ZWQgZmlsZT8KICAgICAgICAgICAgICAgIHR5cGUgPSBMTktUWVBFCiAgICAgICAgICAgICAgICBsaW5rbmFtZSA9IHNlbGYuaW5vZGVzW2lub2RlXQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBUaGUgaW5vZGUgaXMgYWRkZWQgb25seSBpZiBpdHMgdmFsaWQuCiAgICAgICAgICAgICAgICAjIEZvciB3aW4zMiBpdCBpcyBhbHdheXMgMC4KICAgICAgICAgICAgICAgIHR5cGUgPSBSRUdUWVBFCiAgICAgICAgICAgICAgICBpZiBpbm9kZVswXToKICAgICAgICAgICAgICAgICAgICBzZWxmLmlub2Rlc1tpbm9kZV0gPSBhcmNuYW1lCiAgICAgICAgZWxpZiBzdGF0LlNfSVNESVIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBESVJUWVBFCiAgICAgICAgICAgIGlmIGFyY25hbWVbLTE6XSAhPSAiLyI6CiAgICAgICAgICAgICAgICBhcmNuYW1lICs9ICIvIgogICAgICAgIGVsaWYgc3RhdC5TX0lTRklGTyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IEZJRk9UWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNMTksoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBTWU1UWVBFCiAgICAgICAgICAgIGxpbmtuYW1lID0gb3MucmVhZGxpbmsobmFtZSkKICAgICAgICBlbGlmIHN0YXQuU19JU0NIUihzdG1kKToKICAgICAgICAgICAgdHlwZSA9IENIUlRZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0JMSyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IEJMS1RZUEUKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICAjIEZpbGwgdGhlIFRhckluZm8gb2JqZWN0IHdpdGggYWxsCiAgICAgICAgIyBpbmZvcm1hdGlvbiB3ZSBjYW4gZ2V0LgogICAgICAgIHRhcmluZm8ubmFtZSA9IGFyY25hbWUKICAgICAgICB0YXJpbmZvLm1vZGUgPSBzdG1kCiAgICAgICAgdGFyaW5mby51aWQgPSBzdGF0cmVzLnN0X3VpZAogICAgICAgIHRhcmluZm8uZ2lkID0gc3RhdHJlcy5zdF9naWQKICAgICAgICBpZiBzdGF0LlNfSVNSRUcoc3RtZCk6CiAgICAgICAgICAgIHRhcmluZm8uc2l6ZSA9IHN0YXRyZXMuc3Rfc2l6ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8uc2l6ZSA9IDBMCiAgICAgICAgdGFyaW5mby5tdGltZSA9IHN0YXRyZXMuc3RfbXRpbWUKICAgICAgICB0YXJpbmZvLnR5cGUgPSB0eXBlCiAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IGxpbmtuYW1lCiAgICAgICAgaWYgcHdkOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvLnVuYW1lID0gcHdkLmdldHB3dWlkKHRhcmluZm8udWlkKVswXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgaWYgZ3JwOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lID0gZ3JwLmdldGdyZ2lkKHRhcmluZm8uZ2lkKVswXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGlmIHR5cGUgaW4gKENIUlRZUEUsIEJMS1RZUEUpOgogICAgICAgICAgICBpZiBoYXNhdHRyKG9zLCAibWFqb3IiKSBhbmQgaGFzYXR0cihvcywgIm1pbm9yIik6CiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1ham9yID0gb3MubWFqb3Ioc3RhdHJlcy5zdF9yZGV2KQogICAgICAgICAgICAgICAgdGFyaW5mby5kZXZtaW5vciA9IG9zLm1pbm9yKHN0YXRyZXMuc3RfcmRldikKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgIGRlZiBsaXN0KHNlbGYsIHZlcmJvc2U9VHJ1ZSk6CiAgICAgICAgIiIiUHJpbnQgYSB0YWJsZSBvZiBjb250ZW50cyB0byBzeXMuc3Rkb3V0LiBJZiBgdmVyYm9zZScgaXMgRmFsc2UsIG9ubHkKICAgICAgICAgICB0aGUgbmFtZXMgb2YgdGhlIG1lbWJlcnMgYXJlIHByaW50ZWQuIElmIGl0IGlzIFRydWUsIGFuIGBscyAtbCctbGlrZQogICAgICAgICAgIG91dHB1dCBpcyBwcm9kdWNlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygpCgogICAgICAgIGZvciB0YXJpbmZvIGluIHNlbGY6CiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludCBmaWxlbW9kZSh0YXJpbmZvLm1vZGUpLAogICAgICAgICAgICAgICAgcHJpbnQgIiVzLyVzIiAlICh0YXJpbmZvLnVuYW1lIG9yIHRhcmluZm8udWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJpbmZvLmduYW1lIG9yIHRhcmluZm8uZ2lkKSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNjaHIoKSBvciB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMHMiICUgKCIlZCwlZCIgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlICh0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSksCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHByaW50ICIlMTBkIiAlIHRhcmluZm8uc2l6ZSwKICAgICAgICAgICAgICAgIHByaW50ICIlZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiIFwKICAgICAgICAgICAgICAgICAgICAgICUgdGltZS5sb2NhbHRpbWUodGFyaW5mby5tdGltZSlbOjZdLAoKICAgICAgICAgICAgcHJpbnQgdGFyaW5mby5uYW1lLAoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgICAgICBwcmludCAiLT4iLCB0YXJpbmZvLmxpbmtuYW1lLAogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICJsaW5rIHRvIiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgcHJpbnQKCiAgICBkZWYgYWRkKHNlbGYsIG5hbWUsIGFyY25hbWU9Tm9uZSwgcmVjdXJzaXZlPVRydWUpOgogICAgICAgICIiIkFkZCB0aGUgZmlsZSBgbmFtZScgdG8gdGhlIGFyY2hpdmUuIGBuYW1lJyBtYXkgYmUgYW55IHR5cGUgb2YgZmlsZQogICAgICAgICAgIChkaXJlY3RvcnksIGZpZm8sIHN5bWJvbGljIGxpbmssIGV0Yy4pLiBJZiBnaXZlbiwgYGFyY25hbWUnCiAgICAgICAgICAgc3BlY2lmaWVzIGFuIGFsdGVybmF0aXZlIG5hbWUgZm9yIHRoZSBmaWxlIGluIHRoZSBhcmNoaXZlLgogICAgICAgICAgIERpcmVjdG9yaWVzIGFyZSBhZGRlZCByZWN1cnNpdmVseSBieSBkZWZhdWx0LiBUaGlzIGNhbiBiZSBhdm9pZGVkIGJ5CiAgICAgICAgICAgc2V0dGluZyBgcmVjdXJzaXZlJyB0byBGYWxzZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCgogICAgICAgICMgU2tpcCBpZiBzb21lYm9keSB0cmllcyB0byBhcmNoaXZlIHRoZSBhcmNoaXZlLi4uCiAgICAgICAgaWYgc2VsZi5uYW1lIGlzIG5vdCBOb25lIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gc2VsZi5uYW1lOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IFNraXBwZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU3BlY2lhbCBjYXNlOiBUaGUgdXNlciB3YW50cyB0byBhZGQgdGhlIGN1cnJlbnQKICAgICAgICAjIHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICAgIGlmIG5hbWUgPT0gIi4iOgogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBpZiBhcmNuYW1lID09ICIuIjoKICAgICAgICAgICAgICAgICAgICBhcmNuYW1lID0gIiIKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIoIi4iKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkZChmLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLl9kYmcoMSwgbmFtZSkKCiAgICAgICAgIyBDcmVhdGUgYSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLmdldHRhcmluZm8obmFtZSwgYXJjbmFtZSkKCiAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVuc3VwcG9ydGVkIHR5cGUgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgQXBwZW5kIHRoZSB0YXIgaGVhZGVyIGFuZCBkYXRhIHRvIHRoZSBhcmNoaXZlLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgZiA9IGZpbGUobmFtZSwgInJiIikKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8sIGYpCiAgICAgICAgICAgIGYuY2xvc2UoKQoKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5hZGRmaWxlKHRhcmluZm8pCiAgICAgICAgICAgIGlmIHJlY3Vyc2l2ZToKICAgICAgICAgICAgICAgIGZvciBmIGluIG9zLmxpc3RkaXIobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZGQob3MucGF0aC5qb2luKG5hbWUsIGYpLCBvcy5wYXRoLmpvaW4oYXJjbmFtZSwgZikpCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQoKICAgIGRlZiBhZGRmaWxlKHNlbGYsIHRhcmluZm8sIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQWRkIHRoZSBUYXJJbmZvIG9iamVjdCBgdGFyaW5mbycgdG8gdGhlIGFyY2hpdmUuIElmIGBmaWxlb2JqJyBpcwogICAgICAgICAgIGdpdmVuLCB0YXJpbmZvLnNpemUgYnl0ZXMgYXJlIHJlYWQgZnJvbSBpdCBhbmQgYWRkZWQgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgWW91IGNhbiBjcmVhdGUgVGFySW5mbyBvYmplY3RzIHVzaW5nIGdldHRhcmluZm8oKS4KICAgICAgICAgICBPbiBXaW5kb3dzIHBsYXRmb3JtcywgYGZpbGVvYmonIHNob3VsZCBhbHdheXMgYmUgb3BlbmVkIHdpdGggbW9kZQogICAgICAgICAgICdyYicgdG8gYXZvaWQgaXJyaXRhdGlvbiBhYm91dCB0aGUgZmlsZSBzaXplLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIHRhcmluZm8gPSBjb3B5LmNvcHkodGFyaW5mbykKCiAgICAgICAgYnVmID0gdGFyaW5mby50b2J1ZihzZWxmLnBvc2l4KQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShidWYpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikKCiAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToKICAgICAgICAiIiJFeHRyYWN0IGFsbCBtZW1iZXJzIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZwogICAgICAgICAgIGRpcmVjdG9yeSBhbmQgc2V0IG93bmVyLCBtb2RpZmljYXRpb24gdGltZSBhbmQgcGVybWlzc2lvbnMgb24KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQogICAgICAgICAgIHRvIGV4dHJhY3QgdG8uIGBtZW1iZXJzJyBpcyBvcHRpb25hbCBhbmQgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUKICAgICAgICAgICBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICBkaXJlY3RvcmllcyA9IFtdCgogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAgICAgIyBFeHRyYWN0IGRpcmVjdG9yeSB3aXRoIGEgc2FmZSBtb2RlLCBzbyB0aGF0CiAgICAgICAgICAgICAgICAjIGFsbCBmaWxlcyBiZWxvdyBjYW4gYmUgZXh0cmFjdGVkIGFzIHdlbGwuCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb3MubWFrZWRpcnMob3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSksIDA3NzcpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvcjoKICAgICAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5hcHBlbmQodGFyaW5mbykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuZXh0cmFjdCh0YXJpbmZvLCBwYXRoKQoKICAgICAgICAjIFJldmVyc2Ugc29ydCBkaXJlY3Rvcmllcy4KICAgICAgICBkaXJlY3Rvcmllcy5zb3J0KGxhbWJkYSBhLCBiOiBjbXAoYS5uYW1lLCBiLm5hbWUpKQogICAgICAgIGRpcmVjdG9yaWVzLnJldmVyc2UoKQoKICAgICAgICAjIFNldCBjb3JyZWN0IG93bmVyLCBtdGltZSBhbmQgZmlsZW1vZGUgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgZm9yIHRhcmluZm8gaW4gZGlyZWN0b3JpZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ocGF0aCwgdGFyaW5mby5uYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgICAgICBzZWxmLmNobW9kKHRhcmluZm8sIHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAxOgogICAgICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZSkKCiAgICBkZWYgZXh0cmFjdChzZWxmLCBtZW1iZXIsIHBhdGg9IiIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSwKICAgICAgICAgICB1c2luZyBpdHMgZnVsbCBuYW1lLiBJdHMgZmlsZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQgYXMgYWNjdXJhdGVseQogICAgICAgICAgIGFzIHBvc3NpYmxlLiBgbWVtYmVyJyBtYXkgYmUgYSBmaWxlbmFtZSBvciBhIFRhckluZm8gb2JqZWN0LiBZb3UgY2FuCiAgICAgICAgICAgc3BlY2lmeSBhIGRpZmZlcmVudCBkaXJlY3RvcnkgdXNpbmcgYHBhdGgnLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJyIikKCiAgICAgICAgaWYgaXNpbnN0YW5jZShtZW1iZXIsIFRhckluZm8pOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKCiAgICAgICAgIyBQcmVwYXJlIHRoZSBsaW5rIHRhcmdldCBmb3IgbWFrZWxpbmsoKS4KICAgICAgICBpZiB0YXJpbmZvLmlzbG5rKCk6CiAgICAgICAgICAgIHRhcmluZm8uX2xpbmtfdGFyZ2V0ID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubGlua25hbWUpCgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGFyaW5mbywgb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDA6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgZS5maWxlbmFtZSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMiICUgZS5zdHJlcnJvcikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyAlciIgJSAoZS5zdHJlcnJvciwgZS5maWxlbmFtZSkpCiAgICAgICAgZXhjZXB0IEV4dHJhY3RFcnJvciwgZToKICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3RmaWxlKHNlbGYsIG1lbWJlcik6CiAgICAgICAgIiIiRXh0cmFjdCBhIG1lbWJlciBmcm9tIHRoZSBhcmNoaXZlIGFzIGEgZmlsZSBvYmplY3QuIGBtZW1iZXInIG1heSBiZQogICAgICAgICAgIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gSWYgYG1lbWJlcicgaXMgYSByZWd1bGFyIGZpbGUsIGEKICAgICAgICAgICBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJldHVybmVkLiBJZiBgbWVtYmVyJyBpcyBhIGxpbmssIGEgZmlsZS1saWtlCiAgICAgICAgICAgb2JqZWN0IGlzIGNvbnN0cnVjdGVkIGZyb20gdGhlIGxpbmsncyB0YXJnZXQuIElmIGBtZW1iZXInIGlzIG5vbmUgb2YKICAgICAgICAgICB0aGUgYWJvdmUsIE5vbmUgaXMgcmV0dXJuZWQuCiAgICAgICAgICAgVGhlIGZpbGUtbGlrZSBvYmplY3QgaXMgcmVhZC1vbmx5IGFuZCBwcm92aWRlcyB0aGUgZm9sbG93aW5nCiAgICAgICAgICAgbWV0aG9kczogcmVhZCgpLCByZWFkbGluZSgpLCByZWFkbGluZXMoKSwgc2VlaygpIGFuZCB0ZWxsKCkKICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBUYXJJbmZvKToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZmlsZW9iamVjdChzZWxmLCB0YXJpbmZvKQoKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICAjIElmIGEgbWVtYmVyJ3MgdHlwZSBpcyB1bmtub3duLCBpdCBpcyB0cmVhdGVkIGFzIGEKICAgICAgICAgICAgIyByZWd1bGFyIGZpbGUuCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYuZmlsZW9iaiwgX1N0cmVhbSk6CiAgICAgICAgICAgICAgICAjIEEgc21hbGwgYnV0IHVnbHkgd29ya2Fyb3VuZCBmb3IgdGhlIGNhc2UgdGhhdCBzb21lb25lIHRyaWVzCiAgICAgICAgICAgICAgICAjIHRvIGV4dHJhY3QgYSAoc3ltKWxpbmsgYXMgYSBmaWxlLW9iamVjdCBmcm9tIGEgbm9uLXNlZWthYmxlCiAgICAgICAgICAgICAgICAjIHN0cmVhbSBvZiB0YXIgYmxvY2tzLgogICAgICAgICAgICAgICAgcmFpc2UgU3RyZWFtRXJyb3IoImNhbm5vdCBleHRyYWN0IChzeW0pbGluayBhcyBmaWxlIG9iamVjdCIpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIEEgKHN5bSlsaW5rJ3MgZmlsZSBvYmplY3QgaXMgaXRzIHRhcmdldCdzIGZpbGUgb2JqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXh0cmFjdGZpbGUoc2VsZi5fZ2V0bWVtYmVyKHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIGlmIHRhcmdldHBhdGhbLTE6XSA9PSAiLyI6CiAgICAgICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoWzotMV0KICAgICAgICB0YXJnZXRwYXRoID0gb3MucGF0aC5ub3JtcGF0aCh0YXJnZXRwYXRoKQoKICAgICAgICAjIENyZWF0ZSBhbGwgdXBwZXIgZGlyZWN0b3JpZXMuCiAgICAgICAgdXBwZXJkaXJzID0gb3MucGF0aC5kaXJuYW1lKHRhcmdldHBhdGgpCiAgICAgICAgaWYgdXBwZXJkaXJzIGFuZCBub3Qgb3MucGF0aC5leGlzdHModXBwZXJkaXJzKToKICAgICAgICAgICAgdGkgPSBUYXJJbmZvKCkKICAgICAgICAgICAgdGkubmFtZSAgPSB1cHBlcmRpcnMKICAgICAgICAgICAgdGkudHlwZSAgPSBESVJUWVBFCiAgICAgICAgICAgIHRpLm1vZGUgID0gMDc3NwogICAgICAgICAgICB0aS5tdGltZSA9IHRhcmluZm8ubXRpbWUKICAgICAgICAgICAgdGkudWlkICAgPSB0YXJpbmZvLnVpZAogICAgICAgICAgICB0aS5naWQgICA9IHRhcmluZm8uZ2lkCiAgICAgICAgICAgIHRpLnVuYW1lID0gdGFyaW5mby51bmFtZQogICAgICAgICAgICB0aS5nbmFtZSA9IHRhcmluZm8uZ25hbWUKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIodGksIHRpLm5hbWUpCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsICIlcyAtPiAlcyIgJSAodGFyaW5mby5uYW1lLCB0YXJpbmZvLmxpbmtuYW1lKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9kYmcoMSwgdGFyaW5mby5uYW1lKQoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNkaXIoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGlyKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZmlmbygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWZvKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzY2hyKCkgb3IgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBzZWxmLm1ha2VkZXYodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWxpbmsodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSBub3QgaW4gU1VQUE9SVEVEX1RZUEVTOgogICAgICAgICAgICBzZWxmLm1ha2V1bmtub3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICAgICBzZWxmLmNob3duKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgaWYgbm90IHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBzZWxmLnV0aW1lKHRhcmluZm8sIHRhcmdldHBhdGgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgZGlmZmVyZW50IGZpbGUgbWV0aG9kcy4gVGhleSBhcmUgY2FsbGVkIHZpYQogICAgIyBfZXh0cmFjdF9tZW1iZXIoKSB3aGVuIGV4dHJhY3QoKSBpcyBjYWxsZWQuIFRoZXkgY2FuIGJlIHJlcGxhY2VkIGluIGEKICAgICMgc3ViY2xhc3MgdG8gaW1wbGVtZW50IG90aGVyIGZ1bmN0aW9uYWxpdHkuCgogICAgZGVmIG1ha2VkaXIoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGRpcmVjdG9yeSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLm1rZGlyKHRhcmdldHBhdGgpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIGUuZXJybm8gIT0gZXJybm8uRUVYSVNUOgogICAgICAgICAgICAgICAgcmFpc2UKCiAgICBkZWYgbWFrZWZpbGUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgc291cmNlID0gc2VsZi5leHRyYWN0ZmlsZSh0YXJpbmZvKQogICAgICAgIHRhcmdldCA9IGZpbGUodGFyZ2V0cGF0aCwgIndiIikKICAgICAgICBjb3B5ZmlsZW9iaihzb3VyY2UsIHRhcmdldCkKICAgICAgICBzb3VyY2UuY2xvc2UoKQogICAgICAgIHRhcmdldC5jbG9zZSgpCgogICAgZGVmIG1ha2V1bmtub3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBmaWxlIGZyb20gYSBUYXJJbmZvIG9iamVjdCB3aXRoIGFuIHVua25vd24gdHlwZQogICAgICAgICAgIGF0IHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5tYWtlZmlsZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5rbm93biBmaWxlIHR5cGUgJXIsICIgXAogICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdGVkIGFzIHJlZ3VsYXIgZmlsZS4iICUgdGFyaW5mby50eXBlKQoKICAgIGRlZiBtYWtlZmlmbyhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlmbyBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAibWtmaWZvIik6CiAgICAgICAgICAgIG9zLm1rZmlmbyh0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiZmlmbyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIpCgogICAgZGVmIG1ha2VkZXYoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGNoYXJhY3RlciBvciBibG9jayBkZXZpY2UgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICJta25vZCIpIG9yIG5vdCBoYXNhdHRyKG9zLCAibWFrZWRldiIpOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoInNwZWNpYWwgZGV2aWNlcyBub3Qgc3VwcG9ydGVkIGJ5IHN5c3RlbSIpCgogICAgICAgIG1vZGUgPSB0YXJpbmZvLm1vZGUKICAgICAgICBpZiB0YXJpbmZvLmlzYmxrKCk6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQkxLCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbW9kZSB8PSBzdGF0LlNfSUZDSFIKCiAgICAgICAgb3MubWtub2QodGFyZ2V0cGF0aCwgbW9kZSwKICAgICAgICAgICAgICAgICBvcy5tYWtlZGV2KHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKQoKICAgIGRlZiBtYWtlbGluayhzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgKHN5bWJvbGljKSBsaW5rIGNhbGxlZCB0YXJnZXRwYXRoLiBJZiBpdCBjYW5ub3QgYmUgY3JlYXRlZAogICAgICAgICAgKHBsYXRmb3JtIGxpbWl0YXRpb24pLCB3ZSB0cnkgdG8gbWFrZSBhIGNvcHkgb2YgdGhlIHJlZmVyZW5jZWQgZmlsZQogICAgICAgICAgaW5zdGVhZCBvZiBhIGxpbmsuCiAgICAgICAgIiIiCiAgICAgICAgbGlua3BhdGggPSB0YXJpbmZvLmxpbmtuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKGxpbmtwYXRoLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBTZWUgZXh0cmFjdCgpLgogICAgICAgICAgICAgICAgb3MubGluayh0YXJpbmZvLl9saW5rX3RhcmdldCwgdGFyZ2V0cGF0aCkKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5qb2luKG9zLnBhdGguZGlybmFtZSh0YXJpbmZvLm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlua3BhdGgpCiAgICAgICAgICAgICAgICBsaW5rcGF0aCA9IG5vcm1wYXRoKGxpbmtwYXRoKQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5fZXh0cmFjdF9tZW1iZXIoc2VsZi5nZXRtZW1iZXIobGlua3BhdGgpLCB0YXJnZXRwYXRoKQogICAgICAgICAgICBleGNlcHQgKEVudmlyb25tZW50RXJyb3IsIEtleUVycm9yKSwgZToKICAgICAgICAgICAgICAgIGxpbmtwYXRoID0gb3MucGF0aC5ub3JtcGF0aChsaW5rcGF0aCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBzaHV0aWwuY29weTIobGlua3BhdGgsIHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBJT0Vycm9yKCJsaW5rIGNvdWxkIG5vdCBiZSBjcmVhdGVkIikKCiAgICBkZWYgY2hvd24oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG93bmVyIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgcHdkIGFuZCBoYXNhdHRyKG9zLCAiZ2V0ZXVpZCIpIGFuZCBvcy5nZXRldWlkKCkgPT0gMDoKICAgICAgICAgICAgIyBXZSBoYXZlIHRvIGJlIHJvb3QgdG8gZG8gc28uCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JuYW0odGFyaW5mby5nbmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGcgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgZyA9IG9zLmdldGdpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHduYW0odGFyaW5mby51bmFtZSlbMl0KICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzJdCiAgICAgICAgICAgICAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgdSA9IG9zLmdldHVpZCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNzeW0oKSBhbmQgaGFzYXR0cihvcywgImxjaG93biIpOgogICAgICAgICAgICAgICAgICAgIG9zLmxjaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gIm9zMmVteCI6CiAgICAgICAgICAgICAgICAgICAgICAgIG9zLmNob3duKHRhcmdldHBhdGgsIHUsIGcpCiAgICAgICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJjb3VsZCBub3QgY2hhbmdlIG93bmVyIikKCiAgICBkZWYgY2htb2Qoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IGZpbGUgcGVybWlzc2lvbnMgb2YgdGFyZ2V0cGF0aCBhY2NvcmRpbmcgdG8gdGFyaW5mby4KICAgICAgICAiIiIKICAgICAgICBpZiBoYXNhdHRyKG9zLCAnY2htb2QnKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3MuY2htb2QodGFyZ2V0cGF0aCwgdGFyaW5mby5tb2RlKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RlIikKCiAgICBkZWYgdXRpbWUoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiU2V0IG1vZGlmaWNhdGlvbiB0aW1lIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IGhhc2F0dHIob3MsICd1dGltZScpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gIndpbjMyIiBhbmQgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAjIEFjY29yZGluZyB0byBtc2RuLm1pY3Jvc29mdC5jb20sIGl0IGlzIGFuIGVycm9yIChFQUNDRVMpCiAgICAgICAgICAgICMgdG8gdXNlIHV0aW1lKCkgb24gZGlyZWN0b3JpZXMuCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MudXRpbWUodGFyZ2V0cGF0aCwgKHRhcmluZm8ubXRpbWUsIHRhcmluZm8ubXRpbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2UgbW9kaWZpY2F0aW9uIHRpbWUiKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IG1lbWJlciBvZiB0aGUgYXJjaGl2ZSBhcyBhIFRhckluZm8gb2JqZWN0LCB3aGVuCiAgICAgICAgICAgVGFyRmlsZSBpcyBvcGVuZWQgZm9yIHJlYWRpbmcuIFJldHVybiBOb25lIGlmIHRoZXJlIGlzIG5vIG1vcmUKICAgICAgICAgICBhdmFpbGFibGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInJhIikKICAgICAgICBpZiBzZWxmLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICBtID0gc2VsZi5maXJzdG1lbWJlcgogICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICByZXR1cm4gbQoKICAgICAgICAjIFJlYWQgdGhlIG5leHQgYmxvY2suCiAgICAgICAgc2VsZi5maWxlb2JqLnNlZWsoc2VsZi5vZmZzZXQpCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBUYXJJbmZvLmZyb21idWYoYnVmKQoKICAgICAgICAgICAgICAgICMgU2V0IHRoZSBUYXJJbmZvIG9iamVjdCdzIG9mZnNldCB0byB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUKICAgICAgICAgICAgICAgICMgVGFyRmlsZSBhbmQgc2V0IHNlbGYub2Zmc2V0IHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MKICAgICAgICAgICAgICAgICMgc2hvdWxkIGJlZ2luLgogICAgICAgICAgICAgICAgdGFyaW5mby5vZmZzZXQgPSBzZWxmLm9mZnNldAogICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYucHJvY19tZW1iZXIodGFyaW5mbykKCiAgICAgICAgICAgIGV4Y2VwdCBIZWFkZXJFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMiICUgKHNlbGYub2Zmc2V0LCBlKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3Ioc3RyKGUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgICMgU29tZSBvbGQgdGFyIHByb2dyYW1zIHJlcHJlc2VudCBhIGRpcmVjdG9yeSBhcyBhIHJlZ3VsYXIKICAgICAgICAjIGZpbGUgd2l0aCBhIHRyYWlsaW5nIHNsYXNoLgogICAgICAgIGlmIHRhcmluZm8uaXNyZWcoKSBhbmQgdGFyaW5mby5uYW1lLmVuZHN3aXRoKCIvIik6CiAgICAgICAgICAgIHRhcmluZm8udHlwZSA9IERJUlRZUEUKCiAgICAgICAgIyBEaXJlY3RvcnkgbmFtZXMgc2hvdWxkIGhhdmUgYSAnLycgYXQgdGhlIGVuZC4KICAgICAgICBpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHRhcmluZm8ubmFtZSArPSAiLyIKCiAgICAgICAgc2VsZi5tZW1iZXJzLmFwcGVuZCh0YXJpbmZvKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBmb2xsb3dpbmcgYXJlIG1ldGhvZHMgdGhhdCBhcmUgY2FsbGVkIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBhCiAgICAjIG1lbWJlci4gVGhlIGVudHJ5IHBvaW50IGlzIHByb2NfbWVtYmVyKCkgd2hpY2ggaXMgY2FsbGVkIHdpdGggYSBUYXJJbmZvCiAgICAjIG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIGhlYWRlciBibG9jayBmcm9tIHRoZSBjdXJyZW50IG9mZnNldC4gVGhlCiAgICAjIHByb2NfbWVtYmVyKCkgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGluIGEgc3ViY2xhc3MgdG8gYWRkIGN1c3RvbQogICAgIyBwcm9jXyooKSBtZXRob2RzLiBBIHByb2NfKigpIG1ldGhvZCBNVVNUIGltcGxlbWVudCB0aGUgZm9sbG93aW5nCiAgICAjIG9wZXJhdGlvbnM6CiAgICAjIDEuIFNldCB0YXJpbmZvLm9mZnNldF9kYXRhIHRvIHRoZSBwb3NpdGlvbiB3aGVyZSB0aGUgZGF0YSBibG9ja3MgYmVnaW4sCiAgICAjICAgIGlmIHRoZXJlIGlzIGRhdGEgdGhhdCBmb2xsb3dzLgogICAgIyAyLiBTZXQgc2VsZi5vZmZzZXQgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBuZXh0IG1lbWJlcidzIGhlYWRlciB3aWxsCiAgICAjICAgIGJlZ2luLgogICAgIyAzLiBSZXR1cm4gdGFyaW5mbyBvciBhbm90aGVyIHZhbGlkIFRhckluZm8gb2JqZWN0LgogICAgZGVmIHByb2NfbWVtYmVyKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIkNob29zZSB0aGUgcmlnaHQgcHJvY2Vzc2luZyBtZXRob2QgZm9yIHRhcmluZm8gZGVwZW5kaW5nCiAgICAgICAgICAgb24gaXRzIHR5cGUgYW5kIGNhbGwgaXQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgdGFyaW5mby50eXBlIGluIChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJvY19nbnVsb25nKHRhcmluZm8pCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgPT0gR05VVFlQRV9TUEFSU0U6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByb2Nfc3BhcnNlKHRhcmluZm8pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJvY19idWlsdGluKHRhcmluZm8pCgogICAgZGVmIHByb2NfYnVpbHRpbihzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJQcm9jZXNzIGEgYnVpbHRpbiB0eXBlIG1lbWJlciBvciBhbiB1bmtub3duIG1lbWJlcgogICAgICAgICAgIHdoaWNoIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHJlZ3VsYXIgZmlsZS4KICAgICAgICAiIiIKICAgICAgICB0YXJpbmZvLm9mZnNldF9kYXRhID0gc2VsZi5vZmZzZXQKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCkgb3IgdGFyaW5mby50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICMgU2tpcCB0aGUgZm9sbG93aW5nIGRhdGEgYmxvY2tzLgogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBzZWxmLl9ibG9jayh0YXJpbmZvLnNpemUpCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiAgICBkZWYgcHJvY19nbnVsb25nKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIlByb2Nlc3MgdGhlIGJsb2NrcyB0aGF0IGhvbGQgYSBHTlUgbG9uZ25hbWUKICAgICAgICAgICBvciBsb25nbGluayBtZW1iZXIuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gIiIKICAgICAgICBjb3VudCA9IHRhcmluZm8uc2l6ZQogICAgICAgIHdoaWxlIGNvdW50ID4gMDoKICAgICAgICAgICAgYmxvY2sgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgICAgIGJ1ZiArPSBibG9jawogICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgY291bnQgLT0gQkxPQ0tTSVpFCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyIGFuZCBwcm9jZXNzIGl0LgogICAgICAgIGIgPSBzZWxmLmZpbGVvYmoucmVhZChCTE9DS1NJWkUpCiAgICAgICAgdCA9IFRhckluZm8uZnJvbWJ1ZihiKQogICAgICAgIHQub2Zmc2V0ID0gc2VsZi5vZmZzZXQKICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICBuZXh0ID0gc2VsZi5wcm9jX21lbWJlcih0KQoKICAgICAgICAjIFBhdGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBuZXh0IGhlYWRlciB3aXRoCiAgICAgICAgIyB0aGUgbG9uZ25hbWUgaW5mb3JtYXRpb24uCiAgICAgICAgbmV4dC5vZmZzZXQgPSB0YXJpbmZvLm9mZnNldAogICAgICAgIGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdOQU1FOgogICAgICAgICAgICBuZXh0Lm5hbWUgPSBidWYucnN0cmlwKE5VTCkKICAgICAgICBlbGlmIHRhcmluZm8udHlwZSA9PSBHTlVUWVBFX0xPTkdMSU5LOgogICAgICAgICAgICBuZXh0LmxpbmtuYW1lID0gYnVmLnJzdHJpcChOVUwpCgogICAgICAgIHJldHVybiBuZXh0CgogICAgZGVmIHByb2Nfc3BhcnNlKHNlbGYsIHRhcmluZm8pOgogICAgICAgICIiIlByb2Nlc3MgYSBHTlUgc3BhcnNlIGhlYWRlciBwbHVzIGV4dHJhIGhlYWRlcnMuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gdGFyaW5mby5idWYKICAgICAgICBzcCA9IF9yaW5nYnVmZmVyKCkKICAgICAgICBwb3MgPSAzODYKICAgICAgICBsYXN0cG9zID0gMEwKICAgICAgICByZWFscG9zID0gMEwKICAgICAgICAjIFRoZXJlIGFyZSA0IHBvc3NpYmxlIHNwYXJzZSBzdHJ1Y3RzIGluIHRoZQogICAgICAgICMgZmlyc3QgaGVhZGVyLgogICAgICAgIGZvciBpIGluIHhyYW5nZSg0KToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBudGkoYnVmW3BvcyArIDEyOnBvcyArIDI0XSkKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9mZnNldCAtIGxhc3Rwb3MpKQogICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgbGFzdHBvcyA9IG9mZnNldCArIG51bWJ5dGVzCiAgICAgICAgICAgIHBvcyArPSAyNAoKICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls0ODJdKQogICAgICAgIG9yaWdzaXplID0gbnRpKGJ1Zls0ODM6NDk1XSkKCiAgICAgICAgIyBJZiB0aGUgaXNleHRlbmRlZCBmbGFnIGlzIGdpdmVuLAogICAgICAgICMgdGhlcmUgYXJlIGV4dHJhIGhlYWRlcnMgdG8gcHJvY2Vzcy4KICAgICAgICB3aGlsZSBpc2V4dGVuZGVkID09IDE6CiAgICAgICAgICAgIGJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgIHBvcyA9IDAKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKDIxKToKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pCiAgICAgICAgICAgICAgICAgICAgbnVtYnl0ZXMgPSBudGkoYnVmW3BvcyArIDEyOnBvcyArIDI0XSkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBpZiBvZmZzZXQgPiBsYXN0cG9zOgogICAgICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvZmZzZXQgLSBsYXN0cG9zKSkKICAgICAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgICAgIHJlYWxwb3MgKz0gbnVtYnl0ZXMKICAgICAgICAgICAgICAgIGxhc3Rwb3MgPSBvZmZzZXQgKyBudW1ieXRlcwogICAgICAgICAgICAgICAgcG9zICs9IDI0CiAgICAgICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzUwNF0pCgogICAgICAgIGlmIGxhc3Rwb3MgPCBvcmlnc2l6ZToKICAgICAgICAgICAgc3AuYXBwZW5kKF9ob2xlKGxhc3Rwb3MsIG9yaWdzaXplIC0gbGFzdHBvcykpCgogICAgICAgIHRhcmluZm8uc3BhcnNlID0gc3AKCiAgICAgICAgdGFyaW5mby5vZmZzZXRfZGF0YSA9IHNlbGYub2Zmc2V0CiAgICAgICAgc2VsZi5vZmZzZXQgKz0gc2VsZi5fYmxvY2sodGFyaW5mby5zaXplKQogICAgICAgIHRhcmluZm8uc2l6ZSA9IG9yaWdzaXplCgogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIExpdHRsZSBoZWxwZXIgbWV0aG9kczoKCiAgICBkZWYgX2Jsb2NrKHNlbGYsIGNvdW50KToKICAgICAgICAiIiJSb3VuZCB1cCBhIGJ5dGUgY291bnQgYnkgQkxPQ0tTSVpFIGFuZCByZXR1cm4gaXQsCiAgICAgICAgICAgZS5nLiBfYmxvY2soODM0KSA9PiAxMDI0LgogICAgICAgICIiIgogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGNvdW50LCBCTE9DS1NJWkUpCiAgICAgICAgaWYgcmVtYWluZGVyOgogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHJldHVybiBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICBkZWYgX2dldG1lbWJlcihzZWxmLCBuYW1lLCB0YXJpbmZvPU5vbmUpOgogICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuCiAgICAgICAgICAgSWYgdGFyaW5mbyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuCiAgICAgICAgIiIiCiAgICAgICAgIyBFbnN1cmUgdGhhdCBhbGwgbWVtYmVycyBoYXZlIGJlZW4gbG9hZGVkLgogICAgICAgIG1lbWJlcnMgPSBzZWxmLmdldG1lbWJlcnMoKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIGVuZCA9IGxlbihtZW1iZXJzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGVuZCA9IG1lbWJlcnMuaW5kZXgodGFyaW5mbykKCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKGVuZCAtIDEsIC0xLCAtMSk6CiAgICAgICAgICAgIGlmIG5hbWUgPT0gbWVtYmVyc1tpXS5uYW1lOgogICAgICAgICAgICAgICAgcmV0dXJuIG1lbWJlcnNbaV0KCiAgICBkZWYgX2xvYWQoc2VsZik6CiAgICAgICAgIiIiUmVhZCB0aHJvdWdoIHRoZSBlbnRpcmUgYXJjaGl2ZSBmaWxlIGFuZCBsb29rIGZvciByZWFkYWJsZQogICAgICAgICAgIG1lbWJlcnMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgIGRlZiBfY2hlY2soc2VsZiwgbW9kZT1Ob25lKToKICAgICAgICAiIiJDaGVjayBpZiBUYXJGaWxlIGlzIHN0aWxsIG9wZW4sIGFuZCBpZiB0aGUgb3BlcmF0aW9uJ3MgbW9kZQogICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIFRhckZpbGUncyBtb2RlLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBJT0Vycm9yKCIlcyBpcyBjbG9zZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18pCiAgICAgICAgaWYgbW9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5fbW9kZSBub3QgaW4gbW9kZToKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiYmFkIG9wZXJhdGlvbiBmb3IgbW9kZSAlciIgJSBzZWxmLl9tb2RlKQoKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJQcm92aWRlIGFuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLl9sb2FkZWQ6CiAgICAgICAgICAgIHJldHVybiBpdGVyKHNlbGYubWVtYmVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gVGFySXRlcihzZWxmKQoKICAgIGRlZiBfZGJnKHNlbGYsIGxldmVsLCBtc2cpOgogICAgICAgICIiIldyaXRlIGRlYnVnZ2luZyBvdXRwdXQgdG8gc3lzLnN0ZGVyci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZXZlbCA8PSBzZWxmLmRlYnVnOgogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBtc2cKIyBjbGFzcyBUYXJGaWxlCgpjbGFzcyBUYXJJdGVyOgogICAgIiIiSXRlcmF0b3IgQ2xhc3MuCgogICAgICAgZm9yIHRhcmluZm8gaW4gVGFyRmlsZSguLi4pOgogICAgICAgICAgIHN1aXRlLi4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySXRlciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi50YXJmaWxlID0gdGFyZmlsZQogICAgICAgIHNlbGYuaW5kZXggPSAwCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIGl0ZXJhdG9yIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IGl0ZW0gdXNpbmcgVGFyRmlsZSdzIG5leHQoKSBtZXRob2QuCiAgICAgICAgICAgV2hlbiBhbGwgbWVtYmVycyBoYXZlIGJlZW4gcmVhZCwgc2V0IFRhckZpbGUgYXMgX2xvYWRlZC4KICAgICAgICAiIiIKICAgICAgICAjIEZpeCBmb3IgU0YgIzExMDA0Mjk6IFVuZGVyIHJhcmUgY2lyY3Vtc3RhbmNlcyBpdCBjYW4KICAgICAgICAjIGhhcHBlbiB0aGF0IGdldG1lbWJlcnMoKSBpcyBjYWxsZWQgZHVyaW5nIGl0ZXJhdGlvbiwKICAgICAgICAjIHdoaWNoIHdpbGwgY2F1c2UgVGFySXRlciB0byBzdG9wIHByZW1hdHVyZWx5LgogICAgICAgIGlmIG5vdCBzZWxmLnRhcmZpbGUuX2xvYWRlZDoKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyZmlsZS5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IHRhcmluZm86CiAgICAgICAgICAgICAgICBzZWxmLnRhcmZpbGUuX2xvYWRlZCA9IFRydWUKICAgICAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBlbHNlOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm1lbWJlcnNbc2VsZi5pbmRleF0KICAgICAgICAgICAgZXhjZXB0IEluZGV4RXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgc2VsZi5pbmRleCArPSAxCiAgICAgICAgcmV0dXJuIHRhcmluZm8KCiMgSGVscGVyIGNsYXNzZXMgZm9yIHNwYXJzZSBmaWxlIHN1cHBvcnQKY2xhc3MgX3NlY3Rpb246CiAgICAiIiJCYXNlIGNsYXNzIGZvciBfZGF0YSBhbmQgX2hvbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUpOgogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgZGVmIF9fY29udGFpbnNfXyhzZWxmLCBvZmZzZXQpOgogICAgICAgIHJldHVybiBzZWxmLm9mZnNldCA8PSBvZmZzZXQgPCBzZWxmLm9mZnNldCArIHNlbGYuc2l6ZQoKY2xhc3MgX2RhdGEoX3NlY3Rpb24pOgogICAgIiIiUmVwcmVzZW50IGEgZGF0YSBzZWN0aW9uIGluIGEgc3BhcnNlIGZpbGUuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvZmZzZXQsIHNpemUsIHJlYWxwb3MpOgogICAgICAgIF9zZWN0aW9uLl9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSkKICAgICAgICBzZWxmLnJlYWxwb3MgPSByZWFscG9zCgpjbGFzcyBfaG9sZShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBob2xlIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgcGFzcwoKY2xhc3MgX3JpbmdidWZmZXIobGlzdCk6CiAgICAiIiJSaW5nYnVmZmVyIGNsYXNzIHdoaWNoIGluY3JlYXNlcyBwZXJmb3JtYW5jZQogICAgICAgb3ZlciBhIHJlZ3VsYXIgbGlzdC4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuaWR4ID0gMAogICAgZGVmIGZpbmQoc2VsZiwgb2Zmc2V0KToKICAgICAgICBpZHggPSBzZWxmLmlkeAogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGl0ZW0gPSBzZWxmW2lkeF0KICAgICAgICAgICAgaWYgb2Zmc2V0IGluIGl0ZW06CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZHggKz0gMQogICAgICAgICAgICBpZiBpZHggPT0gbGVuKHNlbGYpOgogICAgICAgICAgICAgICAgaWR4ID0gMAogICAgICAgICAgICBpZiBpZHggPT0gc2VsZi5pZHg6CiAgICAgICAgICAgICAgICAjIEVuZCBvZiBGaWxlCiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIHNlbGYuaWR4ID0gaWR4CiAgICAgICAgcmV0dXJuIGl0ZW0KCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyB6aXBmaWxlIGNvbXBhdGlibGUgVGFyRmlsZSBjbGFzcwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRBUl9QTEFJTiA9IDAgICAgICAgICAgICMgemlwZmlsZS5aSVBfU1RPUkVEClRBUl9HWklQUEVEID0gOCAgICAgICAgICMgemlwZmlsZS5aSVBfREVGTEFURUQKY2xhc3MgVGFyRmlsZUNvbXBhdDoKICAgICIiIlRhckZpbGUgY2xhc3MgY29tcGF0aWJsZSB3aXRoIHN0YW5kYXJkIG1vZHVsZSB6aXBmaWxlJ3MKICAgICAgIFppcEZpbGUgY2xhc3MuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBtb2RlPSJyIiwgY29tcHJlc3Npb249VEFSX1BMQUlOKToKICAgICAgICBpZiBjb21wcmVzc2lvbiA9PSBUQVJfUExBSU46CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUudGFyb3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsaWYgY29tcHJlc3Npb24gPT0gVEFSX0daSVBQRUQ6CiAgICAgICAgICAgIHNlbGYudGFyZmlsZSA9IFRhckZpbGUuZ3pvcGVuKGZpbGUsIG1vZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigidW5rbm93biBjb21wcmVzc2lvbiBjb25zdGFudCIpCiAgICAgICAgaWYgbW9kZVswOjFdID09ICJyIjoKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkKICAgICAgICAgICAgZm9yIG0gaW4gbWVtYmVyczoKICAgICAgICAgICAgICAgIG0uZmlsZW5hbWUgPSBtLm5hbWUKICAgICAgICAgICAgICAgIG0uZmlsZV9zaXplID0gbS5zaXplCiAgICAgICAgICAgICAgICBtLmRhdGVfdGltZSA9IHRpbWUuZ210aW1lKG0ubXRpbWUpWzo2XQogICAgZGVmIG5hbWVsaXN0KHNlbGYpOgogICAgICAgIHJldHVybiBtYXAobGFtYmRhIG06IG0ubmFtZSwgc2VsZi5pbmZvbGlzdCgpKQogICAgZGVmIGluZm9saXN0KHNlbGYpOgogICAgICAgIHJldHVybiBmaWx0ZXIobGFtYmRhIG06IG0udHlwZSBpbiBSRUdVTEFSX1RZUEVTLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi50YXJmaWxlLmdldG1lbWJlcnMoKSkKICAgIGRlZiBwcmludGRpcihzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUubGlzdCgpCiAgICBkZWYgdGVzdHppcChzZWxmKToKICAgICAgICByZXR1cm4KICAgIGRlZiBnZXRpbmZvKHNlbGYsIG5hbWUpOgogICAgICAgIHJldHVybiBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpCiAgICBkZWYgcmVhZChzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmV4dHJhY3RmaWxlKHNlbGYudGFyZmlsZS5nZXRtZW1iZXIobmFtZSkpLnJlYWQoKQogICAgZGVmIHdyaXRlKHNlbGYsIGZpbGVuYW1lLCBhcmNuYW1lPU5vbmUsIGNvbXByZXNzX3R5cGU9Tm9uZSk6CiAgICAgICAgc2VsZi50YXJmaWxlLmFkZChmaWxlbmFtZSwgYXJjbmFtZSkKICAgIGRlZiB3cml0ZXN0cihzZWxmLCB6aW5mbywgYnl0ZXMpOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnJvbSBjU3RyaW5nSU8gaW1wb3J0IFN0cmluZ0lPCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBmcm9tIFN0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGltcG9ydCBjYWxlbmRhcgogICAgICAgIHppbmZvLm5hbWUgPSB6aW5mby5maWxlbmFtZQogICAgICAgIHppbmZvLnNpemUgPSB6aW5mby5maWxlX3NpemUKICAgICAgICB6aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUoemluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCm9wZW4gPSBUYXJGaWxlLm9wZW4K