IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHRhcmZpbGUucHkKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBDb3B5cmlnaHQgKEMpIDIwMDIgTGFycyBHdXN05GJlbCA8bGFyc0BndXN0YWViZWwuZGU+CiMgQWxsIHJpZ2h0cyByZXNlcnZlZC4KIwojIFBlcm1pc3Npb24gIGlzICBoZXJlYnkgZ3JhbnRlZCwgIGZyZWUgIG9mIGNoYXJnZSwgIHRvICBhbnkgcGVyc29uCiMgb2J0YWluaW5nIGEgIGNvcHkgb2YgIHRoaXMgc29mdHdhcmUgIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24KIyBmaWxlcyAgKHRoZSAgIlNvZnR3YXJlIiksICB0byAgIGRlYWwgIGluICB0aGUgIFNvZnR3YXJlICAgd2l0aG91dAojIHJlc3RyaWN0aW9uLCAgaW5jbHVkaW5nICB3aXRob3V0IGxpbWl0YXRpb24gIHRoZSAgcmlnaHRzIHRvICB1c2UsCiMgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKIyBjb3BpZXMgIG9mICB0aGUgIFNvZnR3YXJlLCAgYW5kIHRvICBwZXJtaXQgIHBlcnNvbnMgIHRvICB3aG9tIHRoZQojIFNvZnR3YXJlICBpcyAgZnVybmlzaGVkICB0byAgZG8gIHNvLCAgc3ViamVjdCAgdG8gIHRoZSAgZm9sbG93aW5nCiMgY29uZGl0aW9uczoKIwojIFRoZSBhYm92ZSBjb3B5cmlnaHQgIG5vdGljZSBhbmQgdGhpcyAgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgIGJlCiMgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiMKIyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTICBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZICBLSU5ELAojIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HICBCVVQgTk9UIExJTUlURUQgVE8gIFRIRSBXQVJSQU5USUVTCiMgT0YgIE1FUkNIQU5UQUJJTElUWSwgIEZJVE5FU1MgICBGT1IgIEEgIFBBUlRJQ1VMQVIgICBQVVJQT1NFICBBTkQKIyBOT05JTkZSSU5HRU1FTlQuICBJTiAgTk8gIEVWRU5UIFNIQUxMICBUSEUgIEFVVEhPUlMgIE9SIENPUFlSSUdIVAojIEhPTERFUlMgIEJFIExJQUJMRSAgRk9SIEFOWSAgQ0xBSU0sIERBTUFHRVMgIE9SIE9USEVSICBMSUFCSUxJVFksCiMgV0hFVEhFUiAgSU4gQU4gIEFDVElPTiBPRiAgQ09OVFJBQ1QsIFRPUlQgIE9SIE9USEVSV0lTRSwgIEFSSVNJTkcKIyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SCiMgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgojCiIiIlJlYWQgZnJvbSBhbmQgd3JpdGUgdG8gdGFyIGZvcm1hdCBhcmNoaXZlcy4KIiIiCgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb246IDg1MjEzICQiCiMgJFNvdXJjZSQKCnZlcnNpb24gICAgID0gIjAuOS4wIgpfX2F1dGhvcl9fICA9ICJMYXJzIEd1c3TkYmVsIChsYXJzQGd1c3RhZWJlbC5kZSkiCl9fZGF0ZV9fICAgID0gIiREYXRlJCIKX19jdnNpZF9fICAgPSAiJElkJCIKX19jcmVkaXRzX18gPSAiR3VzdGF2byBOaWVtZXllciwgTmllbHMgR3VzdORiZWwsIFJpY2hhcmQgVG93bnNlbmQuIgoKIy0tLS0tLS0tLQojIEltcG9ydHMKIy0tLS0tLS0tLQpmcm9tIF9fYnVpbHRpbl9fIGltcG9ydCBvcGVuIGFzIGJsdG5fb3BlbgppbXBvcnQgc3lzCmltcG9ydCBvcwppbXBvcnQgc2h1dGlsCmltcG9ydCBzdGF0CmltcG9ydCBlcnJubwppbXBvcnQgdGltZQppbXBvcnQgc3RydWN0CmltcG9ydCBjb3B5CmltcG9ydCByZQppbXBvcnQgb3BlcmF0b3IKCnRyeToKICAgIGltcG9ydCBncnAsIHB3ZApleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBncnAgPSBwd2QgPSBOb25lCgojIGZyb20gdGFyZmlsZSBpbXBvcnQgKgpfX2FsbF9fID0gWyJUYXJGaWxlIiwgIlRhckluZm8iLCAiaXNfdGFyZmlsZSIsICJUYXJFcnJvciJdCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyIGNvbnN0YW50cwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk5VTCA9ICJcMCIgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgbnVsbCBjaGFyYWN0ZXIKQkxPQ0tTSVpFID0gNTEyICAgICAgICAgICAgICAgICAjIGxlbmd0aCBvZiBwcm9jZXNzaW5nIGJsb2NrcwpSRUNPUkRTSVpFID0gQkxPQ0tTSVpFICogMjAgICAgICMgbGVuZ3RoIG9mIHJlY29yZHMKR05VX01BR0lDID0gInVzdGFyICBcMCIgICAgICAgICAjIG1hZ2ljIGdudSB0YXIgc3RyaW5nClBPU0lYX01BR0lDID0gInVzdGFyXHgwMDAwIiAgICAgIyBtYWdpYyBwb3NpeCB0YXIgc3RyaW5nCgpMRU5HVEhfTkFNRSA9IDEwMCAgICAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBmaWxlbmFtZQpMRU5HVEhfTElOSyA9IDEwMCAgICAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgYSBsaW5rbmFtZQpMRU5HVEhfUFJFRklYID0gMTU1ICAgICAgICAgICAgICMgbWF4aW11bSBsZW5ndGggb2YgdGhlIHByZWZpeCBmaWVsZAoKUkVHVFlQRSA9ICIwIiAgICAgICAgICAgICAgICAgICAjIHJlZ3VsYXIgZmlsZQpBUkVHVFlQRSA9ICJcMCIgICAgICAgICAgICAgICAgICMgcmVndWxhciBmaWxlCkxOS1RZUEUgPSAiMSIgICAgICAgICAgICAgICAgICAgIyBsaW5rIChpbnNpZGUgdGFyZmlsZSkKU1lNVFlQRSA9ICIyIiAgICAgICAgICAgICAgICAgICAjIHN5bWJvbGljIGxpbmsKQ0hSVFlQRSA9ICIzIiAgICAgICAgICAgICAgICAgICAjIGNoYXJhY3RlciBzcGVjaWFsIGRldmljZQpCTEtUWVBFID0gIjQiICAgICAgICAgICAgICAgICAgICMgYmxvY2sgc3BlY2lhbCBkZXZpY2UKRElSVFlQRSA9ICI1IiAgICAgICAgICAgICAgICAgICAjIGRpcmVjdG9yeQpGSUZPVFlQRSA9ICI2IiAgICAgICAgICAgICAgICAgICMgZmlmbyBzcGVjaWFsIGRldmljZQpDT05UVFlQRSA9ICI3IiAgICAgICAgICAgICAgICAgICMgY29udGlndW91cyBmaWxlCgpHTlVUWVBFX0xPTkdOQU1FID0gIkwiICAgICAgICAgICMgR05VIHRhciBsb25nbmFtZQpHTlVUWVBFX0xPTkdMSU5LID0gIksiICAgICAgICAgICMgR05VIHRhciBsb25nbGluawpHTlVUWVBFX1NQQVJTRSA9ICJTIiAgICAgICAgICAgICMgR05VIHRhciBzcGFyc2UgZmlsZQoKWEhEVFlQRSA9ICJ4IiAgICAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMjAwMSBleHRlbmRlZCBoZWFkZXIKWEdMVFlQRSA9ICJnIiAgICAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMjAwMSBnbG9iYWwgaGVhZGVyClNPTEFSSVNfWEhEVFlQRSA9ICJYIiAgICAgICAgICAgIyBTb2xhcmlzIGV4dGVuZGVkIGhlYWRlcgoKVVNUQVJfRk9STUFUID0gMCAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMTk4OCAodXN0YXIpIGZvcm1hdApHTlVfRk9STUFUID0gMSAgICAgICAgICAgICAgICAgICMgR05VIHRhciBmb3JtYXQKUEFYX0ZPUk1BVCA9IDIgICAgICAgICAgICAgICAgICAjIFBPU0lYLjEtMjAwMSAocGF4KSBmb3JtYXQKREVGQVVMVF9GT1JNQVQgPSBHTlVfRk9STUFUCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgdGFyZmlsZSBjb25zdGFudHMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEZpbGUgdHlwZXMgdGhhdCB0YXJmaWxlIHN1cHBvcnRzOgpTVVBQT1JURURfVFlQRVMgPSAoUkVHVFlQRSwgQVJFR1RZUEUsIExOS1RZUEUsCiAgICAgICAgICAgICAgICAgICBTWU1UWVBFLCBESVJUWVBFLCBGSUZPVFlQRSwKICAgICAgICAgICAgICAgICAgIENPTlRUWVBFLCBDSFJUWVBFLCBCTEtUWVBFLAogICAgICAgICAgICAgICAgICAgR05VVFlQRV9MT05HTkFNRSwgR05VVFlQRV9MT05HTElOSywKICAgICAgICAgICAgICAgICAgIEdOVVRZUEVfU1BBUlNFKQoKIyBGaWxlIHR5cGVzIHRoYXQgd2lsbCBiZSB0cmVhdGVkIGFzIGEgcmVndWxhciBmaWxlLgpSRUdVTEFSX1RZUEVTID0gKFJFR1RZUEUsIEFSRUdUWVBFLAogICAgICAgICAgICAgICAgIENPTlRUWVBFLCBHTlVUWVBFX1NQQVJTRSkKCiMgRmlsZSB0eXBlcyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBHTlUgdGFyIGZvcm1hdC4KR05VX1RZUEVTID0gKEdOVVRZUEVfTE9OR05BTUUsIEdOVVRZUEVfTE9OR0xJTkssCiAgICAgICAgICAgICBHTlVUWVBFX1NQQVJTRSkKCiMgRmllbGRzIGZyb20gYSBwYXggaGVhZGVyIHRoYXQgb3ZlcnJpZGUgYSBUYXJJbmZvIGF0dHJpYnV0ZS4KUEFYX0ZJRUxEUyA9ICgicGF0aCIsICJsaW5rcGF0aCIsICJzaXplIiwgIm10aW1lIiwKICAgICAgICAgICAgICAidWlkIiwgImdpZCIsICJ1bmFtZSIsICJnbmFtZSIpCgojIEZpZWxkcyBpbiBhIHBheCBoZWFkZXIgdGhhdCBhcmUgbnVtYmVycywgYWxsIG90aGVyIGZpZWxkcwojIGFyZSB0cmVhdGVkIGFzIHN0cmluZ3MuClBBWF9OVU1CRVJfRklFTERTID0gewogICAgImF0aW1lIjogZmxvYXQsCiAgICAiY3RpbWUiOiBmbG9hdCwKICAgICJtdGltZSI6IGZsb2F0LAogICAgInVpZCI6IGludCwKICAgICJnaWQiOiBpbnQsCiAgICAic2l6ZSI6IGludAp9CgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQml0cyB1c2VkIGluIHRoZSBtb2RlIGZpZWxkLCB2YWx1ZXMgaW4gb2N0YWwuCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU19JRkxOSyA9IDAxMjAwMDAgICAgICAgICMgc3ltYm9saWMgbGluawpTX0lGUkVHID0gMDEwMDAwMCAgICAgICAgIyByZWd1bGFyIGZpbGUKU19JRkJMSyA9IDAwNjAwMDAgICAgICAgICMgYmxvY2sgZGV2aWNlClNfSUZESVIgPSAwMDQwMDAwICAgICAgICAjIGRpcmVjdG9yeQpTX0lGQ0hSID0gMDAyMDAwMCAgICAgICAgIyBjaGFyYWN0ZXIgZGV2aWNlClNfSUZJRk8gPSAwMDEwMDAwICAgICAgICAjIGZpZm8KClRTVUlEICAgPSAwNDAwMCAgICAgICAgICAjIHNldCBVSUQgb24gZXhlY3V0aW9uClRTR0lEICAgPSAwMjAwMCAgICAgICAgICAjIHNldCBHSUQgb24gZXhlY3V0aW9uClRTVlRYICAgPSAwMTAwMCAgICAgICAgICAjIHJlc2VydmVkCgpUVVJFQUQgID0gMDQwMCAgICAgICAgICAgIyByZWFkIGJ5IG93bmVyClRVV1JJVEUgPSAwMjAwICAgICAgICAgICAjIHdyaXRlIGJ5IG93bmVyClRVRVhFQyAgPSAwMTAwICAgICAgICAgICAjIGV4ZWN1dGUvc2VhcmNoIGJ5IG93bmVyClRHUkVBRCAgPSAwMDQwICAgICAgICAgICAjIHJlYWQgYnkgZ3JvdXAKVEdXUklURSA9IDAwMjAgICAgICAgICAgICMgd3JpdGUgYnkgZ3JvdXAKVEdFWEVDICA9IDAwMTAgICAgICAgICAgICMgZXhlY3V0ZS9zZWFyY2ggYnkgZ3JvdXAKVE9SRUFEICA9IDAwMDQgICAgICAgICAgICMgcmVhZCBieSBvdGhlcgpUT1dSSVRFID0gMDAwMiAgICAgICAgICAgIyB3cml0ZSBieSBvdGhlcgpUT0VYRUMgID0gMDAwMSAgICAgICAgICAgIyBleGVjdXRlL3NlYXJjaCBieSBvdGhlcgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGluaXRpYWxpemF0aW9uCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRU5DT0RJTkcgPSBzeXMuZ2V0ZmlsZXN5c3RlbWVuY29kaW5nKCkKaWYgRU5DT0RJTkcgaXMgTm9uZToKICAgIEVOQ09ESU5HID0gc3lzLmdldGRlZmF1bHRlbmNvZGluZygpCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU29tZSB1c2VmdWwgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBzdG4ocywgbGVuZ3RoKToKICAgICIiIkNvbnZlcnQgYSBweXRob24gc3RyaW5nIHRvIGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBidWZmZXIuCiAgICAiIiIKICAgIHJldHVybiBzWzpsZW5ndGhdICsgKGxlbmd0aCAtIGxlbihzKSkgKiBOVUwKCmRlZiBudHMocyk6CiAgICAiIiJDb252ZXJ0IGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZyBmaWVsZCB0byBhIHB5dGhvbiBzdHJpbmcuCiAgICAiIiIKICAgICMgVXNlIHRoZSBzdHJpbmcgdXAgdG8gdGhlIGZpcnN0IG51bGwgY2hhci4KICAgIHAgPSBzLmZpbmQoIlwwIikKICAgIGlmIHAgPT0gLTE6CiAgICAgICAgcmV0dXJuIHMKICAgIHJldHVybiBzWzpwXQoKZGVmIG50aShzKToKICAgICIiIkNvbnZlcnQgYSBudW1iZXIgZmllbGQgdG8gYSBweXRob24gbnVtYmVyLgogICAgIiIiCiAgICAjIFRoZXJlIGFyZSB0d28gcG9zc2libGUgZW5jb2RpbmdzIGZvciBhIG51bWJlciBmaWVsZCwgc2VlCiAgICAjIGl0bigpIGJlbG93LgogICAgaWYgc1swXSAhPSBjaHIoMDIwMCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBuID0gaW50KG50cyhzKS5zdHJpcCgpIG9yICIwIiwgOCkKICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgcmFpc2UgSW52YWxpZEhlYWRlckVycm9yKCJpbnZhbGlkIGhlYWRlciIpCiAgICBlbHNlOgogICAgICAgIG4gPSAwTAogICAgICAgIGZvciBpIGluIHhyYW5nZShsZW4ocykgLSAxKToKICAgICAgICAgICAgbiA8PD0gOAogICAgICAgICAgICBuICs9IG9yZChzW2kgKyAxXSkKICAgIHJldHVybiBuCgpkZWYgaXRuKG4sIGRpZ2l0cz04LCBmb3JtYXQ9REVGQVVMVF9GT1JNQVQpOgogICAgIiIiQ29udmVydCBhIHB5dGhvbiBudW1iZXIgdG8gYSBudW1iZXIgZmllbGQuCiAgICAiIiIKICAgICMgUE9TSVggMTAwMy4xLTE5ODggcmVxdWlyZXMgbnVtYmVycyB0byBiZSBlbmNvZGVkIGFzIGEgc3RyaW5nIG9mCiAgICAjIG9jdGFsIGRpZ2l0cyBmb2xsb3dlZCBieSBhIG51bGwtYnl0ZSwgdGhpcyBhbGxvd3MgdmFsdWVzIHVwIHRvCiAgICAjICg4KiooZGlnaXRzLTEpKS0xLiBHTlUgdGFyIGFsbG93cyBzdG9yaW5nIG51bWJlcnMgZ3JlYXRlciB0aGFuCiAgICAjIHRoYXQgaWYgbmVjZXNzYXJ5LiBBIGxlYWRpbmcgMDIwMCBieXRlIGluZGljYXRlcyB0aGlzIHBhcnRpY3VsYXIKICAgICMgZW5jb2RpbmcsIHRoZSBmb2xsb3dpbmcgZGlnaXRzLTEgYnl0ZXMgYXJlIGEgYmlnLWVuZGlhbgogICAgIyByZXByZXNlbnRhdGlvbi4gVGhpcyBhbGxvd3MgdmFsdWVzIHVwIHRvICgyNTYqKihkaWdpdHMtMSkpLTEuCiAgICBpZiAwIDw9IG4gPCA4ICoqIChkaWdpdHMgLSAxKToKICAgICAgICBzID0gIiUwKm8iICUgKGRpZ2l0cyAtIDEsIG4pICsgTlVMCiAgICBlbHNlOgogICAgICAgIGlmIGZvcm1hdCAhPSBHTlVfRk9STUFUIG9yIG4gPj0gMjU2ICoqIChkaWdpdHMgLSAxKToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigib3ZlcmZsb3cgaW4gbnVtYmVyIGZpZWxkIikKCiAgICAgICAgaWYgbiA8IDA6CiAgICAgICAgICAgICMgWFhYIFdlIG1pbWljIEdOVSB0YXIncyBiZWhhdmlvdXIgd2l0aCBuZWdhdGl2ZSBudW1iZXJzLAogICAgICAgICAgICAjIHRoaXMgY291bGQgcmFpc2UgT3ZlcmZsb3dFcnJvci4KICAgICAgICAgICAgbiA9IHN0cnVjdC51bnBhY2soIkwiLCBzdHJ1Y3QucGFjaygibCIsIG4pKVswXQoKICAgICAgICBzID0gIiIKICAgICAgICBmb3IgaSBpbiB4cmFuZ2UoZGlnaXRzIC0gMSk6CiAgICAgICAgICAgIHMgPSBjaHIobiAmIDAzNzcpICsgcwogICAgICAgICAgICBuID4+PSA4CiAgICAgICAgcyA9IGNocigwMjAwKSArIHMKICAgIHJldHVybiBzCgpkZWYgdXRzKHMsIGVuY29kaW5nLCBlcnJvcnMpOgogICAgIiIiQ29udmVydCBhIHVuaWNvZGUgb2JqZWN0IHRvIGEgc3RyaW5nLgogICAgIiIiCiAgICBpZiBlcnJvcnMgPT0gInV0Zi04IjoKICAgICAgICAjIEFuIGV4dHJhIGVycm9yIGhhbmRsZXIgc2ltaWxhciB0byB0aGUgLW8gaW52YWxpZD1VVEYtOCBvcHRpb24KICAgICAgICAjIGluIFBPU0lYLjEtMjAwMS4gUmVwbGFjZSB1bnRyYW5zbGF0YWJsZSBjaGFyYWN0ZXJzIHdpdGggdGhlaXIKICAgICAgICAjIFVURi04IHJlcHJlc2VudGF0aW9uLgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIHMuZW5jb2RlKGVuY29kaW5nLCAic3RyaWN0IikKICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOgogICAgICAgICAgICB4ID0gW10KICAgICAgICAgICAgZm9yIGMgaW4gczoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB4LmFwcGVuZChjLmVuY29kZShlbmNvZGluZywgInN0cmljdCIpKQogICAgICAgICAgICAgICAgZXhjZXB0IFVuaWNvZGVFbmNvZGVFcnJvcjoKICAgICAgICAgICAgICAgICAgICB4LmFwcGVuZChjLmVuY29kZSgidXRmOCIpKQogICAgICAgICAgICByZXR1cm4gIiIuam9pbih4KQogICAgZWxzZToKICAgICAgICByZXR1cm4gcy5lbmNvZGUoZW5jb2RpbmcsIGVycm9ycykKCmRlZiBjYWxjX2Noa3N1bXMoYnVmKToKICAgICIiIkNhbGN1bGF0ZSB0aGUgY2hlY2tzdW0gZm9yIGEgbWVtYmVyJ3MgaGVhZGVyIGJ5IHN1bW1pbmcgdXAgYWxsCiAgICAgICBjaGFyYWN0ZXJzIGV4Y2VwdCBmb3IgdGhlIGNoa3N1bSBmaWVsZCB3aGljaCBpcyB0cmVhdGVkIGFzIGlmCiAgICAgICBpdCB3YXMgZmlsbGVkIHdpdGggc3BhY2VzLiBBY2NvcmRpbmcgdG8gdGhlIEdOVSB0YXIgc291cmNlcywKICAgICAgIHNvbWUgdGFycyAoU3VuIGFuZCBOZVhUKSBjYWxjdWxhdGUgY2hrc3VtIHdpdGggc2lnbmVkIGNoYXIsCiAgICAgICB3aGljaCB3aWxsIGJlIGRpZmZlcmVudCBpZiB0aGVyZSBhcmUgY2hhcnMgaW4gdGhlIGJ1ZmZlciB3aXRoCiAgICAgICB0aGUgaGlnaCBiaXQgc2V0LiBTbyB3ZSBjYWxjdWxhdGUgdHdvIGNoZWNrc3VtcywgdW5zaWduZWQgYW5kCiAgICAgICBzaWduZWQuCiAgICAiIiIKICAgIHVuc2lnbmVkX2Noa3N1bSA9IDI1NiArIHN1bShzdHJ1Y3QudW5wYWNrKCIxNDhCIiwgYnVmWzoxNDhdKSArIHN0cnVjdC51bnBhY2soIjM1NkIiLCBidWZbMTU2OjUxMl0pKQogICAgc2lnbmVkX2Noa3N1bSA9IDI1NiArIHN1bShzdHJ1Y3QudW5wYWNrKCIxNDhiIiwgYnVmWzoxNDhdKSArIHN0cnVjdC51bnBhY2soIjM1NmIiLCBidWZbMTU2OjUxMl0pKQogICAgcmV0dXJuIHVuc2lnbmVkX2Noa3N1bSwgc2lnbmVkX2Noa3N1bQoKZGVmIGNvcHlmaWxlb2JqKHNyYywgZHN0LCBsZW5ndGg9Tm9uZSk6CiAgICAiIiJDb3B5IGxlbmd0aCBieXRlcyBmcm9tIGZpbGVvYmogc3JjIHRvIGZpbGVvYmogZHN0LgogICAgICAgSWYgbGVuZ3RoIGlzIE5vbmUsIGNvcHkgdGhlIGVudGlyZSBjb250ZW50LgogICAgIiIiCiAgICBpZiBsZW5ndGggPT0gMDoKICAgICAgICByZXR1cm4KICAgIGlmIGxlbmd0aCBpcyBOb25lOgogICAgICAgIHNodXRpbC5jb3B5ZmlsZW9iaihzcmMsIGRzdCkKICAgICAgICByZXR1cm4KCiAgICBCVUZTSVpFID0gMTYgKiAxMDI0CiAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW5ndGgsIEJVRlNJWkUpCiAgICBmb3IgYiBpbiB4cmFuZ2UoYmxvY2tzKToKICAgICAgICBidWYgPSBzcmMucmVhZChCVUZTSVpFKQogICAgICAgIGlmIGxlbihidWYpIDwgQlVGU0laRToKICAgICAgICAgICAgcmFpc2UgSU9FcnJvcigiZW5kIG9mIGZpbGUgcmVhY2hlZCIpCiAgICAgICAgZHN0LndyaXRlKGJ1ZikKCiAgICBpZiByZW1haW5kZXIgIT0gMDoKICAgICAgICBidWYgPSBzcmMucmVhZChyZW1haW5kZXIpCiAgICAgICAgaWYgbGVuKGJ1ZikgPCByZW1haW5kZXI6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImVuZCBvZiBmaWxlIHJlYWNoZWQiKQogICAgICAgIGRzdC53cml0ZShidWYpCiAgICByZXR1cm4KCmZpbGVtb2RlX3RhYmxlID0gKAogICAgKChTX0lGTE5LLCAgICAgICJsIiksCiAgICAgKFNfSUZSRUcsICAgICAgIi0iKSwKICAgICAoU19JRkJMSywgICAgICAiYiIpLAogICAgIChTX0lGRElSLCAgICAgICJkIiksCiAgICAgKFNfSUZDSFIsICAgICAgImMiKSwKICAgICAoU19JRklGTywgICAgICAicCIpKSwKCiAgICAoKFRVUkVBRCwgICAgICAgInIiKSwpLAogICAgKChUVVdSSVRFLCAgICAgICJ3IiksKSwKICAgICgoVFVFWEVDfFRTVUlELCAicyIpLAogICAgIChUU1VJRCwgICAgICAgICJTIiksCiAgICAgKFRVRVhFQywgICAgICAgIngiKSksCgogICAgKChUR1JFQUQsICAgICAgICJyIiksKSwKICAgICgoVEdXUklURSwgICAgICAidyIpLCksCiAgICAoKFRHRVhFQ3xUU0dJRCwgInMiKSwKICAgICAoVFNHSUQsICAgICAgICAiUyIpLAogICAgIChUR0VYRUMsICAgICAgICJ4IikpLAoKICAgICgoVE9SRUFELCAgICAgICAiciIpLCksCiAgICAoKFRPV1JJVEUsICAgICAgInciKSwpLAogICAgKChUT0VYRUN8VFNWVFgsICJ0IiksCiAgICAgKFRTVlRYLCAgICAgICAgIlQiKSwKICAgICAoVE9FWEVDLCAgICAgICAieCIpKQopCgpkZWYgZmlsZW1vZGUobW9kZSk6CiAgICAiIiJDb252ZXJ0IGEgZmlsZSdzIG1vZGUgdG8gYSBzdHJpbmcgb2YgdGhlIGZvcm0KICAgICAgIC1yd3hyd3hyd3guCiAgICAgICBVc2VkIGJ5IFRhckZpbGUubGlzdCgpCiAgICAiIiIKICAgIHBlcm0gPSBbXQogICAgZm9yIHRhYmxlIGluIGZpbGVtb2RlX3RhYmxlOgogICAgICAgIGZvciBiaXQsIGNoYXIgaW4gdGFibGU6CiAgICAgICAgICAgIGlmIG1vZGUgJiBiaXQgPT0gYml0OgogICAgICAgICAgICAgICAgcGVybS5hcHBlbmQoY2hhcikKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcGVybS5hcHBlbmQoIi0iKQogICAgcmV0dXJuICIiLmpvaW4ocGVybSkKCmNsYXNzIFRhckVycm9yKEV4Y2VwdGlvbik6CiAgICAiIiJCYXNlIGV4Y2VwdGlvbi4iIiIKICAgIHBhc3MKY2xhc3MgRXh0cmFjdEVycm9yKFRhckVycm9yKToKICAgICIiIkdlbmVyYWwgZXhjZXB0aW9uIGZvciBleHRyYWN0IGVycm9ycy4iIiIKICAgIHBhc3MKY2xhc3MgUmVhZEVycm9yKFRhckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgdW5yZWFkYWJsZSB0YXIgYXJjaGl2ZXMuIiIiCiAgICBwYXNzCmNsYXNzIENvbXByZXNzaW9uRXJyb3IoVGFyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB1bmF2YWlsYWJsZSBjb21wcmVzc2lvbiBtZXRob2RzLiIiIgogICAgcGFzcwpjbGFzcyBTdHJlYW1FcnJvcihUYXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIHVuc3VwcG9ydGVkIG9wZXJhdGlvbnMgb24gc3RyZWFtLWxpa2UgVGFyRmlsZXMuIiIiCiAgICBwYXNzCmNsYXNzIEhlYWRlckVycm9yKFRhckVycm9yKToKICAgICIiIkJhc2UgZXhjZXB0aW9uIGZvciBoZWFkZXIgZXJyb3JzLiIiIgogICAgcGFzcwpjbGFzcyBFbXB0eUhlYWRlckVycm9yKEhlYWRlckVycm9yKToKICAgICIiIkV4Y2VwdGlvbiBmb3IgZW1wdHkgaGVhZGVycy4iIiIKICAgIHBhc3MKY2xhc3MgVHJ1bmNhdGVkSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciB0cnVuY2F0ZWQgaGVhZGVycy4iIiIKICAgIHBhc3MKY2xhc3MgRU9GSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciBlbmQgb2YgZmlsZSBoZWFkZXJzLiIiIgogICAgcGFzcwpjbGFzcyBJbnZhbGlkSGVhZGVyRXJyb3IoSGVhZGVyRXJyb3IpOgogICAgIiIiRXhjZXB0aW9uIGZvciBpbnZhbGlkIGhlYWRlcnMuIiIiCiAgICBwYXNzCmNsYXNzIFN1YnNlcXVlbnRIZWFkZXJFcnJvcihIZWFkZXJFcnJvcik6CiAgICAiIiJFeGNlcHRpb24gZm9yIG1pc3NpbmcgYW5kIGludmFsaWQgZXh0ZW5kZWQgaGVhZGVycy4iIiIKICAgIHBhc3MKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBpbnRlcm5hbCBzdHJlYW0gaW50ZXJmYWNlCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgX0xvd0xldmVsRmlsZToKICAgICIiIkxvdy1sZXZlbCBmaWxlIG9iamVjdC4gU3VwcG9ydHMgcmVhZGluZyBhbmQgd3JpdGluZy4KICAgICAgIEl0IGlzIHVzZWQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgZmlsZSBvYmplY3QgZm9yIHN0cmVhbWluZwogICAgICAgYWNjZXNzLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUpOgogICAgICAgIG1vZGUgPSB7CiAgICAgICAgICAgICJyIjogb3MuT19SRE9OTFksCiAgICAgICAgICAgICJ3Ijogb3MuT19XUk9OTFkgfCBvcy5PX0NSRUFUIHwgb3MuT19UUlVOQywKICAgICAgICB9W21vZGVdCiAgICAgICAgaWYgaGFzYXR0cihvcywgIk9fQklOQVJZIik6CiAgICAgICAgICAgIG1vZGUgfD0gb3MuT19CSU5BUlkKICAgICAgICBzZWxmLmZkID0gb3Mub3BlbihuYW1lLCBtb2RlLCAwNjY2KQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBvcy5jbG9zZShzZWxmLmZkKQoKICAgIGRlZiByZWFkKHNlbGYsIHNpemUpOgogICAgICAgIHJldHVybiBvcy5yZWFkKHNlbGYuZmQsIHNpemUpCgogICAgZGVmIHdyaXRlKHNlbGYsIHMpOgogICAgICAgIG9zLndyaXRlKHNlbGYuZmQsIHMpCgpjbGFzcyBfU3RyZWFtOgogICAgIiIiQ2xhc3MgdGhhdCBzZXJ2ZXMgYXMgYW4gYWRhcHRlciBiZXR3ZWVuIFRhckZpbGUgYW5kCiAgICAgICBhIHN0cmVhbS1saWtlIG9iamVjdC4gIFRoZSBzdHJlYW0tbGlrZSBvYmplY3Qgb25seQogICAgICAgbmVlZHMgdG8gaGF2ZSBhIHJlYWQoKSBvciB3cml0ZSgpIG1ldGhvZCBhbmQgaXMgYWNjZXNzZWQKICAgICAgIGJsb2Nrd2lzZS4gIFVzZSBvZiBnemlwIG9yIGJ6aXAyIGNvbXByZXNzaW9uIGlzIHBvc3NpYmxlLgogICAgICAgQSBzdHJlYW0tbGlrZSBvYmplY3QgY291bGQgYmUgZm9yIGV4YW1wbGU6IHN5cy5zdGRpbiwKICAgICAgIHN5cy5zdGRvdXQsIGEgc29ja2V0LCBhIHRhcGUgZGV2aWNlIGV0Yy4KCiAgICAgICBfU3RyZWFtIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb25seSBpbnRlcm5hbGx5LgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIG1vZGUsIGNvbXB0eXBlLCBmaWxlb2JqLCBidWZzaXplKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBfU3RyZWFtIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9leHRmaWxlb2JqID0gVHJ1ZQogICAgICAgIGlmIGZpbGVvYmogaXMgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IF9Mb3dMZXZlbEZpbGUobmFtZSwgbW9kZSkKICAgICAgICAgICAgc2VsZi5fZXh0ZmlsZW9iaiA9IEZhbHNlCgogICAgICAgIGlmIGNvbXB0eXBlID09ICcqJzoKICAgICAgICAgICAgIyBFbmFibGUgdHJhbnNwYXJlbnQgY29tcHJlc3Npb24gZGV0ZWN0aW9uIGZvciB0aGUKICAgICAgICAgICAgIyBzdHJlYW0gaW50ZXJmYWNlCiAgICAgICAgICAgIGZpbGVvYmogPSBfU3RyZWFtUHJveHkoZmlsZW9iaikKICAgICAgICAgICAgY29tcHR5cGUgPSBmaWxlb2JqLmdldGNvbXB0eXBlKCkKCiAgICAgICAgc2VsZi5uYW1lICAgICA9IG5hbWUgb3IgIiIKICAgICAgICBzZWxmLm1vZGUgICAgID0gbW9kZQogICAgICAgIHNlbGYuY29tcHR5cGUgPSBjb21wdHlwZQogICAgICAgIHNlbGYuZmlsZW9iaiAgPSBmaWxlb2JqCiAgICAgICAgc2VsZi5idWZzaXplICA9IGJ1ZnNpemUKICAgICAgICBzZWxmLmJ1ZiAgICAgID0gIiIKICAgICAgICBzZWxmLnBvcyAgICAgID0gMEwKICAgICAgICBzZWxmLmNsb3NlZCAgID0gRmFsc2UKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiBjb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGltcG9ydCB6bGliCiAgICAgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiemxpYiBtb2R1bGUgaXMgbm90IGF2YWlsYWJsZSIpCiAgICAgICAgICAgICAgICBzZWxmLnpsaWIgPSB6bGliCiAgICAgICAgICAgICAgICBzZWxmLmNyYyA9IHpsaWIuY3JjMzIoIiIpICYgMHhmZmZmZmZmZkwKICAgICAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfcmVhZF9neigpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2luaXRfd3JpdGVfZ3ooKQoKICAgICAgICAgICAgZWxpZiBjb21wdHlwZSA9PSAiYnoyIjoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBpbXBvcnQgYnoyCiAgICAgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKICAgICAgICAgICAgICAgIGlmIG1vZGUgPT0gInIiOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZGJ1ZiA9ICIiCiAgICAgICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyRGVjb21wcmVzc29yKCkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5jbXAgPSBiejIuQloyQ29tcHJlc3NvcigpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQogICAgICAgICAgICByYWlzZQoKICAgIGRlZiBfX2RlbF9fKHNlbGYpOgogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgImNsb3NlZCIpIGFuZCBub3Qgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHNlbGYuY2xvc2UoKQoKICAgIGRlZiBfaW5pdF93cml0ZV9neihzZWxmKToKICAgICAgICAiIiJJbml0aWFsaXplIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNtcCA9IHNlbGYuemxpYi5jb21wcmVzc29iaig5LCBzZWxmLnpsaWIuREVGTEFURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLXNlbGYuemxpYi5NQVhfV0JJVFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi56bGliLkRFRl9NRU1fTEVWRUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCkKICAgICAgICB0aW1lc3RhbXAgPSBzdHJ1Y3QucGFjaygiPEwiLCBsb25nKHRpbWUudGltZSgpKSkKICAgICAgICBzZWxmLl9fd3JpdGUoIlwwMzdcMjEzXDAxMFwwMTAlc1wwMDJcMzc3IiAlIHRpbWVzdGFtcCkKICAgICAgICBpZiB0eXBlKHNlbGYubmFtZSkgaXMgdW5pY29kZToKICAgICAgICAgICAgc2VsZi5uYW1lID0gc2VsZi5uYW1lLmVuY29kZSgiaXNvLTg4NTktMSIsICJyZXBsYWNlIikKICAgICAgICBpZiBzZWxmLm5hbWUuZW5kc3dpdGgoIi5neiIpOgogICAgICAgICAgICBzZWxmLm5hbWUgPSBzZWxmLm5hbWVbOi0zXQogICAgICAgIHNlbGYuX193cml0ZShzZWxmLm5hbWUgKyBOVUwpCgogICAgZGVmIHdyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSA9PSAiZ3oiOgogICAgICAgICAgICBzZWxmLmNyYyA9IHNlbGYuemxpYi5jcmMzMihzLCBzZWxmLmNyYykgJiAweGZmZmZmZmZmTAogICAgICAgIHNlbGYucG9zICs9IGxlbihzKQogICAgICAgIGlmIHNlbGYuY29tcHR5cGUgIT0gInRhciI6CiAgICAgICAgICAgIHMgPSBzZWxmLmNtcC5jb21wcmVzcyhzKQogICAgICAgIHNlbGYuX193cml0ZShzKQoKICAgIGRlZiBfX3dyaXRlKHNlbGYsIHMpOgogICAgICAgICIiIldyaXRlIHN0cmluZyBzIHRvIHRoZSBzdHJlYW0gaWYgYSB3aG9sZSBuZXcgYmxvY2sKICAgICAgICAgICBpcyByZWFkeSB0byBiZSB3cml0dGVuLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYnVmICs9IHMKICAgICAgICB3aGlsZSBsZW4oc2VsZi5idWYpID4gc2VsZi5idWZzaXplOgogICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWZbOnNlbGYuYnVmc2l6ZV0pCiAgICAgICAgICAgIHNlbGYuYnVmID0gc2VsZi5idWZbc2VsZi5idWZzaXplOl0KCiAgICBkZWYgY2xvc2Uoc2VsZik6CiAgICAgICAgIiIiQ2xvc2UgdGhlIF9TdHJlYW0gb2JqZWN0LiBObyBvcGVyYXRpb24gc2hvdWxkIGJlCiAgICAgICAgICAgZG9uZSBvbiBpdCBhZnRlcndhcmRzLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiBzZWxmLm1vZGUgPT0gInciIGFuZCBzZWxmLmNvbXB0eXBlICE9ICJ0YXIiOgogICAgICAgICAgICAgICAgc2VsZi5idWYgKz0gc2VsZi5jbXAuZmx1c2goKQoKICAgICAgICAgICAgaWYgc2VsZi5tb2RlID09ICJ3IiBhbmQgc2VsZi5idWY6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoc2VsZi5idWYpCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZiA9ICIiCiAgICAgICAgICAgICAgICBpZiBzZWxmLmNvbXB0eXBlID09ICJneiI6CiAgICAgICAgICAgICAgICAgICAgIyBUaGUgbmF0aXZlIHpsaWIgY3JjIGlzIGFuIHVuc2lnbmVkIDMyLWJpdCBpbnRlZ2VyLCBidXQKICAgICAgICAgICAgICAgICAgICAjIHRoZSBQeXRob24gd3JhcHBlciBpbXBsaWNpdGx5IGNhc3RzIHRoYXQgdG8gYSBzaWduZWQgQwogICAgICAgICAgICAgICAgICAgICMgbG9uZy4gIFNvLCBvbiBhIDMyLWJpdCBib3ggc2VsZi5jcmMgbWF5ICJsb29rIG5lZ2F0aXZlIiwKICAgICAgICAgICAgICAgICAgICAjIHdoaWxlIHRoZSBzYW1lIGNyYyBvbiBhIDY0LWJpdCBib3ggbWF5ICJsb29rIHBvc2l0aXZlIi4KICAgICAgICAgICAgICAgICAgICAjIFRvIGF2b2lkIGlya3NvbWUgd2FybmluZ3MgZnJvbSB0aGUgYHN0cnVjdGAgbW9kdWxlLCBmb3JjZQogICAgICAgICAgICAgICAgICAgICMgaXQgdG8gbG9vayBwb3NpdGl2ZSBvbiBhbGwgYm94ZXMuCiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHN0cnVjdC5wYWNrKCI8TCIsIHNlbGYuY3JjICYgMHhmZmZmZmZmZkwpKQogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShzdHJ1Y3QucGFjaygiPEwiLCBzZWxmLnBvcyAmIDB4ZmZmZkZGRkZMKSkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCgogICAgZGVmIF9pbml0X3JlYWRfZ3ooc2VsZik6CiAgICAgICAgIiIiSW5pdGlhbGl6ZSBmb3IgcmVhZGluZyBhIGd6aXAgY29tcHJlc3NlZCBmaWxlb2JqLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY21wID0gc2VsZi56bGliLmRlY29tcHJlc3NvYmooLXNlbGYuemxpYi5NQVhfV0JJVFMpCiAgICAgICAgc2VsZi5kYnVmID0gIiIKCiAgICAgICAgIyB0YWtlbiBmcm9tIGd6aXAuR3ppcEZpbGUgd2l0aCBzb21lIGFsdGVyYXRpb25zCiAgICAgICAgaWYgc2VsZi5fX3JlYWQoMikgIT0gIlwwMzdcMjEzIjoKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJub3QgYSBnemlwIGZpbGUiKQogICAgICAgIGlmIHNlbGYuX19yZWFkKDEpICE9ICJcMDEwIjoKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigidW5zdXBwb3J0ZWQgY29tcHJlc3Npb24gbWV0aG9kIikKCiAgICAgICAgZmxhZyA9IG9yZChzZWxmLl9fcmVhZCgxKSkKICAgICAgICBzZWxmLl9fcmVhZCg2KQoKICAgICAgICBpZiBmbGFnICYgNDoKICAgICAgICAgICAgeGxlbiA9IG9yZChzZWxmLl9fcmVhZCgxKSkgKyAyNTYgKiBvcmQoc2VsZi5fX3JlYWQoMSkpCiAgICAgICAgICAgIHNlbGYucmVhZCh4bGVuKQogICAgICAgIGlmIGZsYWcgJiA4OgogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgcyA9IHNlbGYuX19yZWFkKDEpCiAgICAgICAgICAgICAgICBpZiBub3QgcyBvciBzID09IE5VTDoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIGZsYWcgJiAxNjoKICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIHMgPSBzZWxmLl9fcmVhZCgxKQogICAgICAgICAgICAgICAgaWYgbm90IHMgb3IgcyA9PSBOVUw6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBmbGFnICYgMjoKICAgICAgICAgICAgc2VsZi5fX3JlYWQoMikKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIHN0cmVhbSdzIGZpbGUgcG9pbnRlciBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3MKCiAgICBkZWYgc2VlayhzZWxmLCBwb3M9MCk6CiAgICAgICAgIiIiU2V0IHRoZSBzdHJlYW0ncyBmaWxlIHBvaW50ZXIgdG8gcG9zLiBOZWdhdGl2ZSBzZWVraW5nCiAgICAgICAgICAgaXMgZm9yYmlkZGVuLgogICAgICAgICIiIgogICAgICAgIGlmIHBvcyAtIHNlbGYucG9zID49IDA6CiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHBvcyAtIHNlbGYucG9zLCBzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZShibG9ja3MpOgogICAgICAgICAgICAgICAgc2VsZi5yZWFkKHNlbGYuYnVmc2l6ZSkKICAgICAgICAgICAgc2VsZi5yZWFkKHJlbWFpbmRlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTdHJlYW1FcnJvcigic2Vla2luZyBiYWNrd2FyZHMgaXMgbm90IGFsbG93ZWQiKQogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiByZWFkKHNlbGYsIHNpemU9Tm9uZSk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBuZXh0IHNpemUgbnVtYmVyIG9mIGJ5dGVzIGZyb20gdGhlIHN0cmVhbS4KICAgICAgICAgICBJZiBzaXplIGlzIG5vdCBkZWZpbmVkLCByZXR1cm4gYWxsIGJ5dGVzIG9mIHRoZSBzdHJlYW0KICAgICAgICAgICB1cCB0byBFT0YuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2l6ZSBpcyBOb25lOgogICAgICAgICAgICB0ID0gW10KICAgICAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuX3JlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICAgICAgaWYgbm90IGJ1ZjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBidWYgPSAiIi5qb2luKHQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYnVmID0gc2VsZi5fcmVhZChzaXplKQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBfcmVhZChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZXR1cm4gc2l6ZSBieXRlcyBmcm9tIHRoZSBzdHJlYW0uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jb21wdHlwZSA9PSAidGFyIjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKHNpemUpCgogICAgICAgIGMgPSBsZW4oc2VsZi5kYnVmKQogICAgICAgIHQgPSBbc2VsZi5kYnVmXQogICAgICAgIHdoaWxlIGMgPCBzaXplOgogICAgICAgICAgICBidWYgPSBzZWxmLl9fcmVhZChzZWxmLmJ1ZnNpemUpCiAgICAgICAgICAgIGlmIG5vdCBidWY6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmNtcC5kZWNvbXByZXNzKGJ1ZikKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImludmFsaWQgY29tcHJlc3NlZCBkYXRhIikKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmRidWYgPSB0W3NpemU6XQogICAgICAgIHJldHVybiB0WzpzaXplXQoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmV0dXJuIHNpemUgYnl0ZXMgZnJvbSBzdHJlYW0uIElmIGludGVybmFsIGJ1ZmZlciBpcyBlbXB0eSwKICAgICAgICAgICByZWFkIGFub3RoZXIgYmxvY2sgZnJvbSB0aGUgc3RyZWFtLgogICAgICAgICIiIgogICAgICAgIGMgPSBsZW4oc2VsZi5idWYpCiAgICAgICAgdCA9IFtzZWxmLmJ1Zl0KICAgICAgICB3aGlsZSBjIDwgc2l6ZToKICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5idWZzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgdC5hcHBlbmQoYnVmKQogICAgICAgICAgICBjICs9IGxlbihidWYpCiAgICAgICAgdCA9ICIiLmpvaW4odCkKICAgICAgICBzZWxmLmJ1ZiA9IHRbc2l6ZTpdCiAgICAgICAgcmV0dXJuIHRbOnNpemVdCiMgY2xhc3MgX1N0cmVhbQoKY2xhc3MgX1N0cmVhbVByb3h5KG9iamVjdCk6CiAgICAiIiJTbWFsbCBwcm94eSBjbGFzcyB0aGF0IGVuYWJsZXMgdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgIGRldGVjdGlvbiBmb3IgdGhlIFN0cmVhbSBpbnRlcmZhY2UgKG1vZGUgJ3J8KicpLgogICAgIiIiCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVvYmopOgogICAgICAgIHNlbGYuZmlsZW9iaiA9IGZpbGVvYmoKICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuZmlsZW9iai5yZWFkKEJMT0NLU0laRSkKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToKICAgICAgICBzZWxmLnJlYWQgPSBzZWxmLmZpbGVvYmoucmVhZAogICAgICAgIHJldHVybiBzZWxmLmJ1ZgoKICAgIGRlZiBnZXRjb21wdHlwZShzZWxmKToKICAgICAgICBpZiBzZWxmLmJ1Zi5zdGFydHN3aXRoKCJcMDM3XDIxM1wwMTAiKToKICAgICAgICAgICAgcmV0dXJuICJneiIKICAgICAgICBpZiBzZWxmLmJ1ZlswOjNdID09ICJCWmgiIGFuZCBzZWxmLmJ1Zls0OjEwXSA9PSAiMUFZJlNZIjoKICAgICAgICAgICAgcmV0dXJuICJiejIiCiAgICAgICAgcmV0dXJuICJ0YXIiCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiMgY2xhc3MgU3RyZWFtUHJveHkKCmNsYXNzIF9CWjJQcm94eShvYmplY3QpOgogICAgIiIiU21hbGwgcHJveHkgY2xhc3MgdGhhdCBlbmFibGVzIGV4dGVybmFsIGZpbGUgb2JqZWN0CiAgICAgICBzdXBwb3J0IGZvciAicjpiejIiIGFuZCAidzpiejIiIG1vZGVzLiBUaGlzIGlzIGFjdHVhbGx5CiAgICAgICBhIHdvcmthcm91bmQgZm9yIGEgbGltaXRhdGlvbiBpbiBiejIgbW9kdWxlJ3MgQloyRmlsZQogICAgICAgY2xhc3Mgd2hpY2ggKHVubGlrZSBnemlwLkd6aXBGaWxlKSBoYXMgbm8gc3VwcG9ydCBmb3IKICAgICAgIGEgZmlsZSBvYmplY3QgYXJndW1lbnQuCiAgICAiIiIKCiAgICBibG9ja3NpemUgPSAxNiAqIDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgbW9kZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLm5hbWUgPSBnZXRhdHRyKHNlbGYuZmlsZW9iaiwgIm5hbWUiLCBOb25lKQogICAgICAgIHNlbGYuaW5pdCgpCgogICAgZGVmIGluaXQoc2VsZik6CiAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgIHNlbGYucG9zID0gMAogICAgICAgIGlmIHNlbGYubW9kZSA9PSAiciI6CiAgICAgICAgICAgIHNlbGYuYnoyb2JqID0gYnoyLkJaMkRlY29tcHJlc3NvcigpCiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKDApCiAgICAgICAgICAgIHNlbGYuYnVmID0gIiIKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmJ6Mm9iaiA9IGJ6Mi5CWjJDb21wcmVzc29yKCkKCiAgICBkZWYgcmVhZChzZWxmLCBzaXplKToKICAgICAgICBiID0gW3NlbGYuYnVmXQogICAgICAgIHggPSBsZW4oc2VsZi5idWYpCiAgICAgICAgd2hpbGUgeCA8IHNpemU6CiAgICAgICAgICAgIHJhdyA9IHNlbGYuZmlsZW9iai5yZWFkKHNlbGYuYmxvY2tzaXplKQogICAgICAgICAgICBpZiBub3QgcmF3OgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZGF0YSA9IHNlbGYuYnoyb2JqLmRlY29tcHJlc3MocmF3KQogICAgICAgICAgICBiLmFwcGVuZChkYXRhKQogICAgICAgICAgICB4ICs9IGxlbihkYXRhKQogICAgICAgIHNlbGYuYnVmID0gIiIuam9pbihiKQoKICAgICAgICBidWYgPSBzZWxmLmJ1Zls6c2l6ZV0KICAgICAgICBzZWxmLmJ1ZiA9IHNlbGYuYnVmW3NpemU6XQogICAgICAgIHNlbGYucG9zICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcyk6CiAgICAgICAgaWYgcG9zIDwgc2VsZi5wb3M6CiAgICAgICAgICAgIHNlbGYuaW5pdCgpCiAgICAgICAgc2VsZi5yZWFkKHBvcyAtIHNlbGYucG9zKQoKICAgIGRlZiB0ZWxsKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnBvcwoKICAgIGRlZiB3cml0ZShzZWxmLCBkYXRhKToKICAgICAgICBzZWxmLnBvcyArPSBsZW4oZGF0YSkKICAgICAgICByYXcgPSBzZWxmLmJ6Mm9iai5jb21wcmVzcyhkYXRhKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShyYXcpCgogICAgZGVmIGNsb3NlKHNlbGYpOgogICAgICAgIGlmIHNlbGYubW9kZSA9PSAidyI6CiAgICAgICAgICAgIHJhdyA9IHNlbGYuYnoyb2JqLmZsdXNoKCkKICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKHJhdykKIyBjbGFzcyBfQloyUHJveHkKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBFeHRyYWN0aW9uIGZpbGUgb2JqZWN0CiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgX0ZpbGVJbkZpbGUob2JqZWN0KToKICAgICIiIkEgdGhpbiB3cmFwcGVyIGFyb3VuZCBhbiBleGlzdGluZyBmaWxlIG9iamVjdCB0aGF0CiAgICAgICBwcm92aWRlcyBhIHBhcnQgb2YgaXRzIGRhdGEgYXMgYW4gaW5kaXZpZHVhbCBmaWxlCiAgICAgICBvYmplY3QuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW9iaiwgb2Zmc2V0LCBzaXplLCBzcGFyc2U9Tm9uZSk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagogICAgICAgIHNlbGYub2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgc2VsZi5zaXplID0gc2l6ZQogICAgICAgIHNlbGYuc3BhcnNlID0gc3BhcnNlCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDAKCiAgICBkZWYgdGVsbChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbi4KICAgICAgICAiIiIKICAgICAgICByZXR1cm4gc2VsZi5wb3NpdGlvbgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvc2l0aW9uKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IHBvc2l0aW9uCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIGRhdGEgZnJvbSB0aGUgZmlsZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzaXplIGlzIE5vbmU6CiAgICAgICAgICAgIHNpemUgPSBzZWxmLnNpemUgLSBzZWxmLnBvc2l0aW9uCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWxmLnNpemUgLSBzZWxmLnBvc2l0aW9uKQoKICAgICAgICBpZiBzZWxmLnNwYXJzZSBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gc2VsZi5yZWFkbm9ybWFsKHNpemUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucmVhZHNwYXJzZShzaXplKQoKICAgIGRlZiBfX3JlYWQoc2VsZiwgc2l6ZSk6CiAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSkKICAgICAgICBpZiBsZW4oYnVmKSAhPSBzaXplOgogICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoInVuZXhwZWN0ZWQgZW5kIG9mIGRhdGEiKQogICAgICAgIHJldHVybiBidWYKCiAgICBkZWYgcmVhZG5vcm1hbChzZWxmLCBzaXplKToKICAgICAgICAiIiJSZWFkIG9wZXJhdGlvbiBmb3IgcmVndWxhciBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCArIHNlbGYucG9zaXRpb24pCiAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgcmV0dXJuIHNlbGYuX19yZWFkKHNpemUpCgogICAgZGVmIHJlYWRzcGFyc2Uoc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBvcGVyYXRpb24gZm9yIHNwYXJzZSBmaWxlcy4KICAgICAgICAiIiIKICAgICAgICBkYXRhID0gW10KICAgICAgICB3aGlsZSBzaXplID4gMDoKICAgICAgICAgICAgYnVmID0gc2VsZi5yZWFkc3BhcnNlc2VjdGlvbihzaXplKQogICAgICAgICAgICBpZiBub3QgYnVmOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgc2l6ZSAtPSBsZW4oYnVmKQogICAgICAgICAgICBkYXRhLmFwcGVuZChidWYpCiAgICAgICAgcmV0dXJuICIiLmpvaW4oZGF0YSkKCiAgICBkZWYgcmVhZHNwYXJzZXNlY3Rpb24oc2VsZiwgc2l6ZSk6CiAgICAgICAgIiIiUmVhZCBhIHNpbmdsZSBzZWN0aW9uIG9mIGEgc3BhcnNlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgc2VjdGlvbiA9IHNlbGYuc3BhcnNlLmZpbmQoc2VsZi5wb3NpdGlvbikKCiAgICAgICAgaWYgc2VjdGlvbiBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gIiIKCiAgICAgICAgc2l6ZSA9IG1pbihzaXplLCBzZWN0aW9uLm9mZnNldCArIHNlY3Rpb24uc2l6ZSAtIHNlbGYucG9zaXRpb24pCgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VjdGlvbiwgX2RhdGEpOgogICAgICAgICAgICByZWFscG9zID0gc2VjdGlvbi5yZWFscG9zICsgc2VsZi5wb3NpdGlvbiAtIHNlY3Rpb24ub2Zmc2V0CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0ICsgcmVhbHBvcykKICAgICAgICAgICAgc2VsZi5wb3NpdGlvbiArPSBzaXplCiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fcmVhZChzaXplKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gKz0gc2l6ZQogICAgICAgICAgICByZXR1cm4gTlVMICogc2l6ZQojY2xhc3MgX0ZpbGVJbkZpbGUKCgpjbGFzcyBFeEZpbGVPYmplY3Qob2JqZWN0KToKICAgICIiIkZpbGUtbGlrZSBvYmplY3QgZm9yIHJlYWRpbmcgYW4gYXJjaGl2ZSBtZW1iZXIuCiAgICAgICBJcyByZXR1cm5lZCBieSBUYXJGaWxlLmV4dHJhY3RmaWxlKCkuCiAgICAiIiIKICAgIGJsb2Nrc2l6ZSA9IDEwMjQKCiAgICBkZWYgX19pbml0X18oc2VsZiwgdGFyZmlsZSwgdGFyaW5mbyk6CiAgICAgICAgc2VsZi5maWxlb2JqID0gX0ZpbGVJbkZpbGUodGFyZmlsZS5maWxlb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8ub2Zmc2V0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldGF0dHIodGFyaW5mbywgInNwYXJzZSIsIE5vbmUpKQogICAgICAgIHNlbGYubmFtZSA9IHRhcmluZm8ubmFtZQogICAgICAgIHNlbGYubW9kZSA9ICJyIgogICAgICAgIHNlbGYuY2xvc2VkID0gRmFsc2UKICAgICAgICBzZWxmLnNpemUgPSB0YXJpbmZvLnNpemUKCiAgICAgICAgc2VsZi5wb3NpdGlvbiA9IDAKICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCgogICAgZGVmIHJlYWQoc2VsZiwgc2l6ZT1Ob25lKToKICAgICAgICAiIiJSZWFkIGF0IG1vc3Qgc2l6ZSBieXRlcyBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIG5vdAogICAgICAgICAgIHByZXNlbnQgb3IgTm9uZSwgcmVhZCBhbGwgZGF0YSB1bnRpbCBFT0YgaXMgcmVhY2hlZC4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpCgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgaWYgc2VsZi5idWZmZXI6CiAgICAgICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyCiAgICAgICAgICAgICAgICBzZWxmLmJ1ZmZlciA9ICIiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBidWYgPSBzZWxmLmJ1ZmZlcls6c2l6ZV0KICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gc2VsZi5idWZmZXJbc2l6ZTpdCgogICAgICAgIGlmIHNpemUgaXMgTm9uZToKICAgICAgICAgICAgYnVmICs9IHNlbGYuZmlsZW9iai5yZWFkKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgKz0gc2VsZi5maWxlb2JqLnJlYWQoc2l6ZSAtIGxlbihidWYpKQoKICAgICAgICBzZWxmLnBvc2l0aW9uICs9IGxlbihidWYpCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIGRlZiByZWFkbGluZShzZWxmLCBzaXplPS0xKToKICAgICAgICAiIiJSZWFkIG9uZSBlbnRpcmUgbGluZSBmcm9tIHRoZSBmaWxlLiBJZiBzaXplIGlzIHByZXNlbnQKICAgICAgICAgICBhbmQgbm9uLW5lZ2F0aXZlLCByZXR1cm4gYSBzdHJpbmcgd2l0aCBhdCBtb3N0IHRoYXQKICAgICAgICAgICBzaXplLCB3aGljaCBtYXkgYmUgYW4gaW5jb21wbGV0ZSBsaW5lLgogICAgICAgICIiIgogICAgICAgIGlmIHNlbGYuY2xvc2VkOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJJL08gb3BlcmF0aW9uIG9uIGNsb3NlZCBmaWxlIikKCiAgICAgICAgaWYgIlxuIiBpbiBzZWxmLmJ1ZmZlcjoKICAgICAgICAgICAgcG9zID0gc2VsZi5idWZmZXIuZmluZCgiXG4iKSArIDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWZmZXJzID0gW3NlbGYuYnVmZmVyXQogICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgYnVmID0gc2VsZi5maWxlb2JqLnJlYWQoc2VsZi5ibG9ja3NpemUpCiAgICAgICAgICAgICAgICBidWZmZXJzLmFwcGVuZChidWYpCiAgICAgICAgICAgICAgICBpZiBub3QgYnVmIG9yICJcbiIgaW4gYnVmOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYnVmZmVyID0gIiIuam9pbihidWZmZXJzKQogICAgICAgICAgICAgICAgICAgIHBvcyA9IHNlbGYuYnVmZmVyLmZpbmQoIlxuIikgKyAxCiAgICAgICAgICAgICAgICAgICAgaWYgcG9zID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICMgbm8gbmV3bGluZSBmb3VuZC4KICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gbGVuKHNlbGYuYnVmZmVyKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIHNpemUgIT0gLTE6CiAgICAgICAgICAgIHBvcyA9IG1pbihzaXplLCBwb3MpCgogICAgICAgIGJ1ZiA9IHNlbGYuYnVmZmVyWzpwb3NdCiAgICAgICAgc2VsZi5idWZmZXIgPSBzZWxmLmJ1ZmZlcltwb3M6XQogICAgICAgIHNlbGYucG9zaXRpb24gKz0gbGVuKGJ1ZikKICAgICAgICByZXR1cm4gYnVmCgogICAgZGVmIHJlYWRsaW5lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBsaXN0IHdpdGggYWxsIHJlbWFpbmluZyBsaW5lcy4KICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBbXQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGxpbmUgPSBzZWxmLnJlYWRsaW5lKCkKICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobGluZSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHRlbGwoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBjdXJyZW50IGZpbGUgcG9zaXRpb24uCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICByZXR1cm4gc2VsZi5wb3NpdGlvbgoKICAgIGRlZiBzZWVrKHNlbGYsIHBvcywgd2hlbmNlPW9zLlNFRUtfU0VUKToKICAgICAgICAiIiJTZWVrIHRvIGEgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIkkvTyBvcGVyYXRpb24gb24gY2xvc2VkIGZpbGUiKQoKICAgICAgICBpZiB3aGVuY2UgPT0gb3MuU0VFS19TRVQ6CiAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4obWF4KHBvcywgMCksIHNlbGYuc2l6ZSkKICAgICAgICBlbGlmIHdoZW5jZSA9PSBvcy5TRUVLX0NVUjoKICAgICAgICAgICAgaWYgcG9zIDwgMDoKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtYXgoc2VsZi5wb3NpdGlvbiArIHBvcywgMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYucG9zaXRpb24gPSBtaW4oc2VsZi5wb3NpdGlvbiArIHBvcywgc2VsZi5zaXplKQogICAgICAgIGVsaWYgd2hlbmNlID09IG9zLlNFRUtfRU5EOgogICAgICAgICAgICBzZWxmLnBvc2l0aW9uID0gbWF4KG1pbihzZWxmLnNpemUgKyBwb3MsIHNlbGYuc2l6ZSksIDApCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiSW52YWxpZCBhcmd1bWVudCIpCgogICAgICAgIHNlbGYuYnVmZmVyID0gIiIKICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLnBvc2l0aW9uKQoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgZmlsZSBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jbG9zZWQgPSBUcnVlCgogICAgZGVmIF9faXRlcl9fKHNlbGYpOgogICAgICAgICIiIkdldCBhbiBpdGVyYXRvciBvdmVyIHRoZSBmaWxlJ3MgbGluZXMuCiAgICAgICAgIiIiCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbGluZSA9IHNlbGYucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHlpZWxkIGxpbmUKI2NsYXNzIEV4RmlsZU9iamVjdAoKIy0tLS0tLS0tLS0tLS0tLS0tLQojIEV4cG9ydGVkIENsYXNzZXMKIy0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBUYXJJbmZvKG9iamVjdCk6CiAgICAiIiJJbmZvcm1hdGlvbmFsIGNsYXNzIHdoaWNoIGhvbGRzIHRoZSBkZXRhaWxzIGFib3V0IGFuCiAgICAgICBhcmNoaXZlIG1lbWJlciBnaXZlbiBieSBhIHRhciBoZWFkZXIgYmxvY2suCiAgICAgICBUYXJJbmZvIG9iamVjdHMgYXJlIHJldHVybmVkIGJ5IFRhckZpbGUuZ2V0bWVtYmVyKCksCiAgICAgICBUYXJGaWxlLmdldG1lbWJlcnMoKSBhbmQgVGFyRmlsZS5nZXR0YXJpbmZvKCkgYW5kIGFyZQogICAgICAgdXN1YWxseSBjcmVhdGVkIGludGVybmFsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZT0iIik6CiAgICAgICAgIiIiQ29uc3RydWN0IGEgVGFySW5mbyBvYmplY3QuIG5hbWUgaXMgdGhlIG9wdGlvbmFsIG5hbWUKICAgICAgICAgICBvZiB0aGUgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIHNlbGYubmFtZSA9IG5hbWUgICAgICAgICMgbWVtYmVyIG5hbWUKICAgICAgICBzZWxmLm1vZGUgPSAwNjQ0ICAgICAgICAjIGZpbGUgcGVybWlzc2lvbnMKICAgICAgICBzZWxmLnVpZCA9IDAgICAgICAgICAgICAjIHVzZXIgaWQKICAgICAgICBzZWxmLmdpZCA9IDAgICAgICAgICAgICAjIGdyb3VwIGlkCiAgICAgICAgc2VsZi5zaXplID0gMCAgICAgICAgICAgIyBmaWxlIHNpemUKICAgICAgICBzZWxmLm10aW1lID0gMCAgICAgICAgICAjIG1vZGlmaWNhdGlvbiB0aW1lCiAgICAgICAgc2VsZi5jaGtzdW0gPSAwICAgICAgICAgIyBoZWFkZXIgY2hlY2tzdW0KICAgICAgICBzZWxmLnR5cGUgPSBSRUdUWVBFICAgICAjIG1lbWJlciB0eXBlCiAgICAgICAgc2VsZi5saW5rbmFtZSA9ICIiICAgICAgIyBsaW5rIG5hbWUKICAgICAgICBzZWxmLnVuYW1lID0gIiIgICAgICAgICAjIHVzZXIgbmFtZQogICAgICAgIHNlbGYuZ25hbWUgPSAiIiAgICAgICAgICMgZ3JvdXAgbmFtZQogICAgICAgIHNlbGYuZGV2bWFqb3IgPSAwICAgICAgICMgZGV2aWNlIG1ham9yIG51bWJlcgogICAgICAgIHNlbGYuZGV2bWlub3IgPSAwICAgICAgICMgZGV2aWNlIG1pbm9yIG51bWJlcgoKICAgICAgICBzZWxmLm9mZnNldCA9IDAgICAgICAgICAjIHRoZSB0YXIgaGVhZGVyIHN0YXJ0cyBoZXJlCiAgICAgICAgc2VsZi5vZmZzZXRfZGF0YSA9IDAgICAgIyB0aGUgZmlsZSdzIGRhdGEgc3RhcnRzIGhlcmUKCiAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHt9ICAgIyBwYXggaGVhZGVyIGluZm9ybWF0aW9uCgogICAgIyBJbiBwYXggaGVhZGVycyB0aGUgIm5hbWUiIGFuZCAibGlua25hbWUiIGZpZWxkIGFyZSBjYWxsZWQKICAgICMgInBhdGgiIGFuZCAibGlua3BhdGgiLgogICAgZGVmIF9nZXRwYXRoKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLm5hbWUKICAgIGRlZiBfc2V0cGF0aChzZWxmLCBuYW1lKToKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCiAgICBwYXRoID0gcHJvcGVydHkoX2dldHBhdGgsIF9zZXRwYXRoKQoKICAgIGRlZiBfZ2V0bGlua3BhdGgoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYubGlua25hbWUKICAgIGRlZiBfc2V0bGlua3BhdGgoc2VsZiwgbGlua25hbWUpOgogICAgICAgIHNlbGYubGlua25hbWUgPSBsaW5rbmFtZQogICAgbGlua3BhdGggPSBwcm9wZXJ0eShfZ2V0bGlua3BhdGgsIF9zZXRsaW5rcGF0aCkKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgcmV0dXJuICI8JXMgJXIgYXQgJSN4PiIgJSAoc2VsZi5fX2NsYXNzX18uX19uYW1lX18sc2VsZi5uYW1lLGlkKHNlbGYpKQoKICAgIGRlZiBnZXRfaW5mbyhzZWxmLCBlbmNvZGluZywgZXJyb3JzKToKICAgICAgICAiIiJSZXR1cm4gdGhlIFRhckluZm8ncyBhdHRyaWJ1dGVzIGFzIGEgZGljdGlvbmFyeS4KICAgICAgICAiIiIKICAgICAgICBpbmZvID0gewogICAgICAgICAgICAibmFtZSI6ICAgICBzZWxmLm5hbWUsCiAgICAgICAgICAgICJtb2RlIjogICAgIHNlbGYubW9kZSAmIDA3Nzc3LAogICAgICAgICAgICAidWlkIjogICAgICBzZWxmLnVpZCwKICAgICAgICAgICAgImdpZCI6ICAgICAgc2VsZi5naWQsCiAgICAgICAgICAgICJzaXplIjogICAgIHNlbGYuc2l6ZSwKICAgICAgICAgICAgIm10aW1lIjogICAgc2VsZi5tdGltZSwKICAgICAgICAgICAgImNoa3N1bSI6ICAgc2VsZi5jaGtzdW0sCiAgICAgICAgICAgICJ0eXBlIjogICAgIHNlbGYudHlwZSwKICAgICAgICAgICAgImxpbmtuYW1lIjogc2VsZi5saW5rbmFtZSwKICAgICAgICAgICAgInVuYW1lIjogICAgc2VsZi51bmFtZSwKICAgICAgICAgICAgImduYW1lIjogICAgc2VsZi5nbmFtZSwKICAgICAgICAgICAgImRldm1ham9yIjogc2VsZi5kZXZtYWpvciwKICAgICAgICAgICAgImRldm1pbm9yIjogc2VsZi5kZXZtaW5vcgogICAgICAgIH0KCiAgICAgICAgaWYgaW5mb1sidHlwZSJdID09IERJUlRZUEUgYW5kIG5vdCBpbmZvWyJuYW1lIl0uZW5kc3dpdGgoIi8iKToKICAgICAgICAgICAgaW5mb1sibmFtZSJdICs9ICIvIgoKICAgICAgICBmb3Iga2V5IGluICgibmFtZSIsICJsaW5rbmFtZSIsICJ1bmFtZSIsICJnbmFtZSIpOgogICAgICAgICAgICBpZiB0eXBlKGluZm9ba2V5XSkgaXMgdW5pY29kZToKICAgICAgICAgICAgICAgIGluZm9ba2V5XSA9IGluZm9ba2V5XS5lbmNvZGUoZW5jb2RpbmcsIGVycm9ycykKCiAgICAgICAgcmV0dXJuIGluZm8KCiAgICBkZWYgdG9idWYoc2VsZiwgZm9ybWF0PURFRkFVTFRfRk9STUFULCBlbmNvZGluZz1FTkNPRElORywgZXJyb3JzPSJzdHJpY3QiKToKICAgICAgICAiIiJSZXR1cm4gYSB0YXIgaGVhZGVyIGFzIGEgc3RyaW5nIG9mIDUxMiBieXRlIGJsb2Nrcy4KICAgICAgICAiIiIKICAgICAgICBpbmZvID0gc2VsZi5nZXRfaW5mbyhlbmNvZGluZywgZXJyb3JzKQoKICAgICAgICBpZiBmb3JtYXQgPT0gVVNUQVJfRk9STUFUOgogICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVfdXN0YXJfaGVhZGVyKGluZm8pCiAgICAgICAgZWxpZiBmb3JtYXQgPT0gR05VX0ZPUk1BVDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlX2dudV9oZWFkZXIoaW5mbykKICAgICAgICBlbGlmIGZvcm1hdCA9PSBQQVhfRk9STUFUOgogICAgICAgICAgICByZXR1cm4gc2VsZi5jcmVhdGVfcGF4X2hlYWRlcihpbmZvLCBlbmNvZGluZywgZXJyb3JzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImludmFsaWQgZm9ybWF0IikKCiAgICBkZWYgY3JlYXRlX3VzdGFyX2hlYWRlcihzZWxmLCBpbmZvKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG9iamVjdCBhcyBhIHVzdGFyIGhlYWRlciBibG9jay4KICAgICAgICAiIiIKICAgICAgICBpbmZvWyJtYWdpYyJdID0gUE9TSVhfTUFHSUMKCiAgICAgICAgaWYgbGVuKGluZm9bImxpbmtuYW1lIl0pID4gTEVOR1RIX0xJTks6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoImxpbmtuYW1lIGlzIHRvbyBsb25nIikKCiAgICAgICAgaWYgbGVuKGluZm9bIm5hbWUiXSkgPiBMRU5HVEhfTkFNRToKICAgICAgICAgICAgaW5mb1sicHJlZml4Il0sIGluZm9bIm5hbWUiXSA9IHNlbGYuX3Bvc2l4X3NwbGl0X25hbWUoaW5mb1sibmFtZSJdKQoKICAgICAgICByZXR1cm4gc2VsZi5fY3JlYXRlX2hlYWRlcihpbmZvLCBVU1RBUl9GT1JNQVQpCgogICAgZGVmIGNyZWF0ZV9nbnVfaGVhZGVyKHNlbGYsIGluZm8pOgogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgR05VIGhlYWRlciBibG9jayBzZXF1ZW5jZS4KICAgICAgICAiIiIKICAgICAgICBpbmZvWyJtYWdpYyJdID0gR05VX01BR0lDCgogICAgICAgIGJ1ZiA9ICIiCiAgICAgICAgaWYgbGVuKGluZm9bImxpbmtuYW1lIl0pID4gTEVOR1RIX0xJTks6CiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLl9jcmVhdGVfZ251X2xvbmdfaGVhZGVyKGluZm9bImxpbmtuYW1lIl0sIEdOVVRZUEVfTE9OR0xJTkspCgogICAgICAgIGlmIGxlbihpbmZvWyJuYW1lIl0pID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgIGJ1ZiArPSBzZWxmLl9jcmVhdGVfZ251X2xvbmdfaGVhZGVyKGluZm9bIm5hbWUiXSwgR05VVFlQRV9MT05HTkFNRSkKCiAgICAgICAgcmV0dXJuIGJ1ZiArIHNlbGYuX2NyZWF0ZV9oZWFkZXIoaW5mbywgR05VX0ZPUk1BVCkKCiAgICBkZWYgY3JlYXRlX3BheF9oZWFkZXIoc2VsZiwgaW5mbywgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBvYmplY3QgYXMgYSB1c3RhciBoZWFkZXIgYmxvY2suIElmIGl0IGNhbm5vdCBiZQogICAgICAgICAgIHJlcHJlc2VudGVkIHRoaXMgd2F5LCBwcmVwZW5kIGEgcGF4IGV4dGVuZGVkIGhlYWRlciBzZXF1ZW5jZQogICAgICAgICAgIHdpdGggc3VwcGxlbWVudCBpbmZvcm1hdGlvbi4KICAgICAgICAiIiIKICAgICAgICBpbmZvWyJtYWdpYyJdID0gUE9TSVhfTUFHSUMKICAgICAgICBwYXhfaGVhZGVycyA9IHNlbGYucGF4X2hlYWRlcnMuY29weSgpCgogICAgICAgICMgVGVzdCBzdHJpbmcgZmllbGRzIGZvciB2YWx1ZXMgdGhhdCBleGNlZWQgdGhlIGZpZWxkIGxlbmd0aCBvciBjYW5ub3QKICAgICAgICAjIGJlIHJlcHJlc2VudGVkIGluIEFTQ0lJIGVuY29kaW5nLgogICAgICAgIGZvciBuYW1lLCBobmFtZSwgbGVuZ3RoIGluICgKICAgICAgICAgICAgICAgICgibmFtZSIsICJwYXRoIiwgTEVOR1RIX05BTUUpLCAoImxpbmtuYW1lIiwgImxpbmtwYXRoIiwgTEVOR1RIX0xJTkspLAogICAgICAgICAgICAgICAgKCJ1bmFtZSIsICJ1bmFtZSIsIDMyKSwgKCJnbmFtZSIsICJnbmFtZSIsIDMyKSk6CgogICAgICAgICAgICBpZiBobmFtZSBpbiBwYXhfaGVhZGVyczoKICAgICAgICAgICAgICAgICMgVGhlIHBheCBoZWFkZXIgaGFzIHByaW9yaXR5LgogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIHZhbCA9IGluZm9bbmFtZV0uZGVjb2RlKGVuY29kaW5nLCBlcnJvcnMpCgogICAgICAgICAgICAjIFRyeSB0byBlbmNvZGUgdGhlIHN0cmluZyBhcyBBU0NJSS4KICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdmFsLmVuY29kZSgiYXNjaWkiKQogICAgICAgICAgICBleGNlcHQgVW5pY29kZUVuY29kZUVycm9yOgogICAgICAgICAgICAgICAgcGF4X2hlYWRlcnNbaG5hbWVdID0gdmFsCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgaWYgbGVuKGluZm9bbmFtZV0pID4gbGVuZ3RoOgogICAgICAgICAgICAgICAgcGF4X2hlYWRlcnNbaG5hbWVdID0gdmFsCgogICAgICAgICMgVGVzdCBudW1iZXIgZmllbGRzIGZvciB2YWx1ZXMgdGhhdCBleGNlZWQgdGhlIGZpZWxkIGxpbWl0IG9yIHZhbHVlcwogICAgICAgICMgdGhhdCBsaWtlIHRvIGJlIHN0b3JlZCBhcyBmbG9hdC4KICAgICAgICBmb3IgbmFtZSwgZGlnaXRzIGluICgoInVpZCIsIDgpLCAoImdpZCIsIDgpLCAoInNpemUiLCAxMiksICgibXRpbWUiLCAxMikpOgogICAgICAgICAgICBpZiBuYW1lIGluIHBheF9oZWFkZXJzOgogICAgICAgICAgICAgICAgIyBUaGUgcGF4IGhlYWRlciBoYXMgcHJpb3JpdHkuIEF2b2lkIG92ZXJmbG93LgogICAgICAgICAgICAgICAgaW5mb1tuYW1lXSA9IDAKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICB2YWwgPSBpbmZvW25hbWVdCiAgICAgICAgICAgIGlmIG5vdCAwIDw9IHZhbCA8IDggKiogKGRpZ2l0cyAtIDEpIG9yIGlzaW5zdGFuY2UodmFsLCBmbG9hdCk6CiAgICAgICAgICAgICAgICBwYXhfaGVhZGVyc1tuYW1lXSA9IHVuaWNvZGUodmFsKQogICAgICAgICAgICAgICAgaW5mb1tuYW1lXSA9IDAKCiAgICAgICAgIyBDcmVhdGUgYSBwYXggZXh0ZW5kZWQgaGVhZGVyIGlmIG5lY2Vzc2FyeS4KICAgICAgICBpZiBwYXhfaGVhZGVyczoKICAgICAgICAgICAgYnVmID0gc2VsZi5fY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihwYXhfaGVhZGVycykKICAgICAgICBlbHNlOgogICAgICAgICAgICBidWYgPSAiIgoKICAgICAgICByZXR1cm4gYnVmICsgc2VsZi5fY3JlYXRlX2hlYWRlcihpbmZvLCBVU1RBUl9GT1JNQVQpCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgY3JlYXRlX3BheF9nbG9iYWxfaGVhZGVyKGNscywgcGF4X2hlYWRlcnMpOgogICAgICAgICIiIlJldHVybiB0aGUgb2JqZWN0IGFzIGEgcGF4IGdsb2JhbCBoZWFkZXIgYmxvY2sgc2VxdWVuY2UuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIGNscy5fY3JlYXRlX3BheF9nZW5lcmljX2hlYWRlcihwYXhfaGVhZGVycywgdHlwZT1YR0xUWVBFKQoKICAgIGRlZiBfcG9zaXhfc3BsaXRfbmFtZShzZWxmLCBuYW1lKToKICAgICAgICAiIiJTcGxpdCBhIG5hbWUgbG9uZ2VyIHRoYW4gMTAwIGNoYXJzIGludG8gYSBwcmVmaXgKICAgICAgICAgICBhbmQgYSBuYW1lIHBhcnQuCiAgICAgICAgIiIiCiAgICAgICAgcHJlZml4ID0gbmFtZVs6TEVOR1RIX1BSRUZJWCArIDFdCiAgICAgICAgd2hpbGUgcHJlZml4IGFuZCBwcmVmaXhbLTFdICE9ICIvIjoKICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4WzotMV0KCiAgICAgICAgbmFtZSA9IG5hbWVbbGVuKHByZWZpeCk6XQogICAgICAgIHByZWZpeCA9IHByZWZpeFs6LTFdCgogICAgICAgIGlmIG5vdCBwcmVmaXggb3IgbGVuKG5hbWUpID4gTEVOR1RIX05BTUU6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5hbWUgaXMgdG9vIGxvbmciKQogICAgICAgIHJldHVybiBwcmVmaXgsIG5hbWUKCiAgICBAc3RhdGljbWV0aG9kCiAgICBkZWYgX2NyZWF0ZV9oZWFkZXIoaW5mbywgZm9ybWF0KToKICAgICAgICAiIiJSZXR1cm4gYSBoZWFkZXIgYmxvY2suIGluZm8gaXMgYSBkaWN0aW9uYXJ5IHdpdGggZmlsZQogICAgICAgICAgIGluZm9ybWF0aW9uLCBmb3JtYXQgbXVzdCBiZSBvbmUgb2YgdGhlICpfRk9STUFUIGNvbnN0YW50cy4KICAgICAgICAiIiIKICAgICAgICBwYXJ0cyA9IFsKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJuYW1lIiwgIiIpLCAxMDApLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoIm1vZGUiLCAwKSAmIDA3Nzc3LCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoInVpZCIsIDApLCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoImdpZCIsIDApLCA4LCBmb3JtYXQpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoInNpemUiLCAwKSwgMTIsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgibXRpbWUiLCAwKSwgMTIsIGZvcm1hdCksCiAgICAgICAgICAgICIgICAgICAgICIsICMgY2hlY2tzdW0gZmllbGQKICAgICAgICAgICAgaW5mby5nZXQoInR5cGUiLCBSRUdUWVBFKSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJsaW5rbmFtZSIsICIiKSwgMTAwKSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJtYWdpYyIsIFBPU0lYX01BR0lDKSwgOCksCiAgICAgICAgICAgIHN0bihpbmZvLmdldCgidW5hbWUiLCAiIiksIDMyKSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJnbmFtZSIsICIiKSwgMzIpLAogICAgICAgICAgICBpdG4oaW5mby5nZXQoImRldm1ham9yIiwgMCksIDgsIGZvcm1hdCksCiAgICAgICAgICAgIGl0bihpbmZvLmdldCgiZGV2bWlub3IiLCAwKSwgOCwgZm9ybWF0KSwKICAgICAgICAgICAgc3RuKGluZm8uZ2V0KCJwcmVmaXgiLCAiIiksIDE1NSkKICAgICAgICBdCgogICAgICAgIGJ1ZiA9IHN0cnVjdC5wYWNrKCIlZHMiICUgQkxPQ0tTSVpFLCAiIi5qb2luKHBhcnRzKSkKICAgICAgICBjaGtzdW0gPSBjYWxjX2Noa3N1bXMoYnVmWy1CTE9DS1NJWkU6XSlbMF0KICAgICAgICBidWYgPSBidWZbOi0zNjRdICsgIiUwNm9cMCIgJSBjaGtzdW0gKyBidWZbLTM1NzpdCiAgICAgICAgcmV0dXJuIGJ1ZgoKICAgIEBzdGF0aWNtZXRob2QKICAgIGRlZiBfY3JlYXRlX3BheWxvYWQocGF5bG9hZCk6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBzdHJpbmcgcGF5bG9hZCBmaWxsZWQgd2l0aCB6ZXJvIGJ5dGVzCiAgICAgICAgICAgdXAgdG8gdGhlIG5leHQgNTEyIGJ5dGUgYm9yZGVyLgogICAgICAgICIiIgogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGxlbihwYXlsb2FkKSwgQkxPQ0tTSVpFKQogICAgICAgIGlmIHJlbWFpbmRlciA+IDA6CiAgICAgICAgICAgIHBheWxvYWQgKz0gKEJMT0NLU0laRSAtIHJlbWFpbmRlcikgKiBOVUwKICAgICAgICByZXR1cm4gcGF5bG9hZAoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIF9jcmVhdGVfZ251X2xvbmdfaGVhZGVyKGNscywgbmFtZSwgdHlwZSk6CiAgICAgICAgIiIiUmV0dXJuIGEgR05VVFlQRV9MT05HTkFNRSBvciBHTlVUWVBFX0xPTkdMSU5LIHNlcXVlbmNlCiAgICAgICAgICAgZm9yIG5hbWUuCiAgICAgICAgIiIiCiAgICAgICAgbmFtZSArPSBOVUwKCiAgICAgICAgaW5mbyA9IHt9CiAgICAgICAgaW5mb1sibmFtZSJdID0gIi4vLi9ATG9uZ0xpbmsiCiAgICAgICAgaW5mb1sidHlwZSJdID0gdHlwZQogICAgICAgIGluZm9bInNpemUiXSA9IGxlbihuYW1lKQogICAgICAgIGluZm9bIm1hZ2ljIl0gPSBHTlVfTUFHSUMKCiAgICAgICAgIyBjcmVhdGUgZXh0ZW5kZWQgaGVhZGVyICsgbmFtZSBibG9ja3MuCiAgICAgICAgcmV0dXJuIGNscy5fY3JlYXRlX2hlYWRlcihpbmZvLCBVU1RBUl9GT1JNQVQpICsgXAogICAgICAgICAgICAgICAgY2xzLl9jcmVhdGVfcGF5bG9hZChuYW1lKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIF9jcmVhdGVfcGF4X2dlbmVyaWNfaGVhZGVyKGNscywgcGF4X2hlYWRlcnMsIHR5cGU9WEhEVFlQRSk6CiAgICAgICAgIiIiUmV0dXJuIGEgUE9TSVguMS0yMDAxIGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIgc2VxdWVuY2UKICAgICAgICAgICB0aGF0IGNvbnRhaW5zIGEgbGlzdCBvZiBrZXl3b3JkLCB2YWx1ZSBwYWlycy4gVGhlIHZhbHVlcwogICAgICAgICAgIG11c3QgYmUgdW5pY29kZSBvYmplY3RzLgogICAgICAgICIiIgogICAgICAgIHJlY29yZHMgPSBbXQogICAgICAgIGZvciBrZXl3b3JkLCB2YWx1ZSBpbiBwYXhfaGVhZGVycy5pdGVyaXRlbXMoKToKICAgICAgICAgICAga2V5d29yZCA9IGtleXdvcmQuZW5jb2RlKCJ1dGY4IikKICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5lbmNvZGUoInV0ZjgiKQogICAgICAgICAgICBsID0gbGVuKGtleXdvcmQpICsgbGVuKHZhbHVlKSArIDMgICAjICcgJyArICc9JyArICdcbicKICAgICAgICAgICAgbiA9IHAgPSAwCiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBuID0gbCArIGxlbihzdHIocCkpCiAgICAgICAgICAgICAgICBpZiBuID09IHA6CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgIHAgPSBuCiAgICAgICAgICAgIHJlY29yZHMuYXBwZW5kKCIlZCAlcz0lc1xuIiAlIChwLCBrZXl3b3JkLCB2YWx1ZSkpCiAgICAgICAgcmVjb3JkcyA9ICIiLmpvaW4ocmVjb3JkcykKCiAgICAgICAgIyBXZSB1c2UgYSBoYXJkY29kZWQgIi4vLi9AUGF4SGVhZGVyIiBuYW1lIGxpa2Ugc3RhciBkb2VzCiAgICAgICAgIyBpbnN0ZWFkIG9mIHRoZSBvbmUgdGhhdCBQT1NJWCByZWNvbW1lbmRzLgogICAgICAgIGluZm8gPSB7fQogICAgICAgIGluZm9bIm5hbWUiXSA9ICIuLy4vQFBheEhlYWRlciIKICAgICAgICBpbmZvWyJ0eXBlIl0gPSB0eXBlCiAgICAgICAgaW5mb1sic2l6ZSJdID0gbGVuKHJlY29yZHMpCiAgICAgICAgaW5mb1sibWFnaWMiXSA9IFBPU0lYX01BR0lDCgogICAgICAgICMgQ3JlYXRlIHBheCBoZWFkZXIgKyByZWNvcmQgYmxvY2tzLgogICAgICAgIHJldHVybiBjbHMuX2NyZWF0ZV9oZWFkZXIoaW5mbywgVVNUQVJfRk9STUFUKSArIFwKICAgICAgICAgICAgICAgIGNscy5fY3JlYXRlX3BheWxvYWQocmVjb3JkcykKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBmcm9tYnVmKGNscywgYnVmKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJbmZvIG9iamVjdCBmcm9tIGEgNTEyIGJ5dGUgc3RyaW5nIGJ1ZmZlci4KICAgICAgICAiIiIKICAgICAgICBpZiBsZW4oYnVmKSA9PSAwOgogICAgICAgICAgICByYWlzZSBFbXB0eUhlYWRlckVycm9yKCJlbXB0eSBoZWFkZXIiKQogICAgICAgIGlmIGxlbihidWYpICE9IEJMT0NLU0laRToKICAgICAgICAgICAgcmFpc2UgVHJ1bmNhdGVkSGVhZGVyRXJyb3IoInRydW5jYXRlZCBoZWFkZXIiKQogICAgICAgIGlmIGJ1Zi5jb3VudChOVUwpID09IEJMT0NLU0laRToKICAgICAgICAgICAgcmFpc2UgRU9GSGVhZGVyRXJyb3IoImVuZCBvZiBmaWxlIGhlYWRlciIpCgogICAgICAgIGNoa3N1bSA9IG50aShidWZbMTQ4OjE1Nl0pCiAgICAgICAgaWYgY2hrc3VtIG5vdCBpbiBjYWxjX2Noa3N1bXMoYnVmKToKICAgICAgICAgICAgcmFpc2UgSW52YWxpZEhlYWRlckVycm9yKCJiYWQgY2hlY2tzdW0iKQoKICAgICAgICBvYmogPSBjbHMoKQogICAgICAgIG9iai5idWYgPSBidWYKICAgICAgICBvYmoubmFtZSA9IG50cyhidWZbMDoxMDBdKQogICAgICAgIG9iai5tb2RlID0gbnRpKGJ1ZlsxMDA6MTA4XSkKICAgICAgICBvYmoudWlkID0gbnRpKGJ1ZlsxMDg6MTE2XSkKICAgICAgICBvYmouZ2lkID0gbnRpKGJ1ZlsxMTY6MTI0XSkKICAgICAgICBvYmouc2l6ZSA9IG50aShidWZbMTI0OjEzNl0pCiAgICAgICAgb2JqLm10aW1lID0gbnRpKGJ1ZlsxMzY6MTQ4XSkKICAgICAgICBvYmouY2hrc3VtID0gY2hrc3VtCiAgICAgICAgb2JqLnR5cGUgPSBidWZbMTU2OjE1N10KICAgICAgICBvYmoubGlua25hbWUgPSBudHMoYnVmWzE1NzoyNTddKQogICAgICAgIG9iai51bmFtZSA9IG50cyhidWZbMjY1OjI5N10pCiAgICAgICAgb2JqLmduYW1lID0gbnRzKGJ1ZlsyOTc6MzI5XSkKICAgICAgICBvYmouZGV2bWFqb3IgPSBudGkoYnVmWzMyOTozMzddKQogICAgICAgIG9iai5kZXZtaW5vciA9IG50aShidWZbMzM3OjM0NV0pCiAgICAgICAgcHJlZml4ID0gbnRzKGJ1ZlszNDU6NTAwXSkKCiAgICAgICAgIyBPbGQgVjcgdGFyIGZvcm1hdCByZXByZXNlbnRzIGEgZGlyZWN0b3J5IGFzIGEgcmVndWxhcgogICAgICAgICMgZmlsZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2guCiAgICAgICAgaWYgb2JqLnR5cGUgPT0gQVJFR1RZUEUgYW5kIG9iai5uYW1lLmVuZHN3aXRoKCIvIik6CiAgICAgICAgICAgIG9iai50eXBlID0gRElSVFlQRQoKICAgICAgICAjIFJlbW92ZSByZWR1bmRhbnQgc2xhc2hlcyBmcm9tIGRpcmVjdG9yaWVzLgogICAgICAgIGlmIG9iai5pc2RpcigpOgogICAgICAgICAgICBvYmoubmFtZSA9IG9iai5uYW1lLnJzdHJpcCgiLyIpCgogICAgICAgICMgUmVjb25zdHJ1Y3QgYSB1c3RhciBsb25nbmFtZS4KICAgICAgICBpZiBwcmVmaXggYW5kIG9iai50eXBlIG5vdCBpbiBHTlVfVFlQRVM6CiAgICAgICAgICAgIG9iai5uYW1lID0gcHJlZml4ICsgIi8iICsgb2JqLm5hbWUKICAgICAgICByZXR1cm4gb2JqCgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgZnJvbXRhcmZpbGUoY2xzLCB0YXJmaWxlKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgVGFySW5mbyBvYmplY3QgZnJvbSBUYXJGaWxlIG9iamVjdAogICAgICAgICAgIHRhcmZpbGUuCiAgICAgICAgIiIiCiAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgIG9iaiA9IGNscy5mcm9tYnVmKGJ1ZikKICAgICAgICBvYmoub2Zmc2V0ID0gdGFyZmlsZS5maWxlb2JqLnRlbGwoKSAtIEJMT0NLU0laRQogICAgICAgIHJldHVybiBvYmouX3Byb2NfbWVtYmVyKHRhcmZpbGUpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBmb2xsb3dpbmcgYXJlIG1ldGhvZHMgdGhhdCBhcmUgY2FsbGVkIGRlcGVuZGluZyBvbiB0aGUgdHlwZSBvZiBhCiAgICAjIG1lbWJlci4gVGhlIGVudHJ5IHBvaW50IGlzIF9wcm9jX21lbWJlcigpIHdoaWNoIGNhbiBiZSBvdmVycmlkZGVuIGluIGEKICAgICMgc3ViY2xhc3MgdG8gYWRkIGN1c3RvbSBfcHJvY18qKCkgbWV0aG9kcy4gQSBfcHJvY18qKCkgbWV0aG9kIE1VU1QKICAgICMgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcKICAgICMgb3BlcmF0aW9uczoKICAgICMgMS4gU2V0IHNlbGYub2Zmc2V0X2RhdGEgdG8gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBkYXRhIGJsb2NrcyBiZWdpbiwKICAgICMgICAgaWYgdGhlcmUgaXMgZGF0YSB0aGF0IGZvbGxvd3MuCiAgICAjIDIuIFNldCB0YXJmaWxlLm9mZnNldCB0byB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIG5leHQgbWVtYmVyJ3MgaGVhZGVyIHdpbGwKICAgICMgICAgYmVnaW4uCiAgICAjIDMuIFJldHVybiBzZWxmIG9yIGFub3RoZXIgdmFsaWQgVGFySW5mbyBvYmplY3QuCiAgICBkZWYgX3Byb2NfbWVtYmVyKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIkNob29zZSB0aGUgcmlnaHQgcHJvY2Vzc2luZyBtZXRob2QgZGVwZW5kaW5nIG9uCiAgICAgICAgICAgdGhlIHR5cGUgYW5kIGNhbGwgaXQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi50eXBlIGluIChHTlVUWVBFX0xPTkdOQU1FLCBHTlVUWVBFX0xPTkdMSU5LKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfZ251bG9uZyh0YXJmaWxlKQogICAgICAgIGVsaWYgc2VsZi50eXBlID09IEdOVVRZUEVfU1BBUlNFOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fcHJvY19zcGFyc2UodGFyZmlsZSkKICAgICAgICBlbGlmIHNlbGYudHlwZSBpbiAoWEhEVFlQRSwgWEdMVFlQRSwgU09MQVJJU19YSERUWVBFKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfcGF4KHRhcmZpbGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3Byb2NfYnVpbHRpbih0YXJmaWxlKQoKICAgIGRlZiBfcHJvY19idWlsdGluKHNlbGYsIHRhcmZpbGUpOgogICAgICAgICIiIlByb2Nlc3MgYSBidWlsdGluIHR5cGUgb3IgYW4gdW5rbm93biB0eXBlIHdoaWNoCiAgICAgICAgICAgd2lsbCBiZSB0cmVhdGVkIGFzIGEgcmVndWxhciBmaWxlLgogICAgICAgICIiIgogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpCiAgICAgICAgb2Zmc2V0ID0gc2VsZi5vZmZzZXRfZGF0YQogICAgICAgIGlmIHNlbGYuaXNyZWcoKSBvciBzZWxmLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBTa2lwIHRoZSBmb2xsb3dpbmcgZGF0YSBibG9ja3MuCiAgICAgICAgICAgIG9mZnNldCArPSBzZWxmLl9ibG9jayhzZWxmLnNpemUpCiAgICAgICAgdGFyZmlsZS5vZmZzZXQgPSBvZmZzZXQKCiAgICAgICAgIyBQYXRjaCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCBzYXZlZCBnbG9iYWwKICAgICAgICAjIGhlYWRlciBpbmZvcm1hdGlvbi4KICAgICAgICBzZWxmLl9hcHBseV9wYXhfaW5mbyh0YXJmaWxlLnBheF9oZWFkZXJzLCB0YXJmaWxlLmVuY29kaW5nLCB0YXJmaWxlLmVycm9ycykKCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgX3Byb2NfZ251bG9uZyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIHRoZSBibG9ja3MgdGhhdCBob2xkIGEgR05VIGxvbmduYW1lCiAgICAgICAgICAgb3IgbG9uZ2xpbmsgbWVtYmVyLgogICAgICAgICIiIgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkpCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyIGFuZCBwcm9jZXNzIGl0LgogICAgICAgIHRyeToKICAgICAgICAgICAgbmV4dCA9IHNlbGYuZnJvbXRhcmZpbGUodGFyZmlsZSkKICAgICAgICBleGNlcHQgSGVhZGVyRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFN1YnNlcXVlbnRIZWFkZXJFcnJvcigibWlzc2luZyBvciBiYWQgc3Vic2VxdWVudCBoZWFkZXIiKQoKICAgICAgICAjIFBhdGNoIHRoZSBUYXJJbmZvIG9iamVjdCBmcm9tIHRoZSBuZXh0IGhlYWRlciB3aXRoCiAgICAgICAgIyB0aGUgbG9uZ25hbWUgaW5mb3JtYXRpb24uCiAgICAgICAgbmV4dC5vZmZzZXQgPSBzZWxmLm9mZnNldAogICAgICAgIGlmIHNlbGYudHlwZSA9PSBHTlVUWVBFX0xPTkdOQU1FOgogICAgICAgICAgICBuZXh0Lm5hbWUgPSBudHMoYnVmKQogICAgICAgIGVsaWYgc2VsZi50eXBlID09IEdOVVRZUEVfTE9OR0xJTks6CiAgICAgICAgICAgIG5leHQubGlua25hbWUgPSBudHMoYnVmKQoKICAgICAgICByZXR1cm4gbmV4dAoKICAgIGRlZiBfcHJvY19zcGFyc2Uoc2VsZiwgdGFyZmlsZSk6CiAgICAgICAgIiIiUHJvY2VzcyBhIEdOVSBzcGFyc2UgaGVhZGVyIHBsdXMgZXh0cmEgaGVhZGVycy4KICAgICAgICAiIiIKICAgICAgICBidWYgPSBzZWxmLmJ1ZgogICAgICAgIHNwID0gX3JpbmdidWZmZXIoKQogICAgICAgIHBvcyA9IDM4NgogICAgICAgIGxhc3Rwb3MgPSAwTAogICAgICAgIHJlYWxwb3MgPSAwTAogICAgICAgICMgVGhlcmUgYXJlIDQgcG9zc2libGUgc3BhcnNlIHN0cnVjdHMgaW4gdGhlCiAgICAgICAgIyBmaXJzdCBoZWFkZXIuCiAgICAgICAgZm9yIGkgaW4geHJhbmdlKDQpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBudGkoYnVmW3Bvczpwb3MgKyAxMl0pCiAgICAgICAgICAgICAgICBudW1ieXRlcyA9IG50aShidWZbcG9zICsgMTI6cG9zICsgMjRdKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlmIG9mZnNldCA+IGxhc3Rwb3M6CiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgIHNwLmFwcGVuZChfZGF0YShvZmZzZXQsIG51bWJ5dGVzLCByZWFscG9zKSkKICAgICAgICAgICAgcmVhbHBvcyArPSBudW1ieXRlcwogICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgcG9zICs9IDI0CgogICAgICAgIGlzZXh0ZW5kZWQgPSBvcmQoYnVmWzQ4Ml0pCiAgICAgICAgb3JpZ3NpemUgPSBudGkoYnVmWzQ4Mzo0OTVdKQoKICAgICAgICAjIElmIHRoZSBpc2V4dGVuZGVkIGZsYWcgaXMgZ2l2ZW4sCiAgICAgICAgIyB0aGVyZSBhcmUgZXh0cmEgaGVhZGVycyB0byBwcm9jZXNzLgogICAgICAgIHdoaWxlIGlzZXh0ZW5kZWQgPT0gMToKICAgICAgICAgICAgYnVmID0gdGFyZmlsZS5maWxlb2JqLnJlYWQoQkxPQ0tTSVpFKQogICAgICAgICAgICBwb3MgPSAwCiAgICAgICAgICAgIGZvciBpIGluIHhyYW5nZSgyMSk6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbnRpKGJ1Zltwb3M6cG9zICsgMTJdKQogICAgICAgICAgICAgICAgICAgIG51bWJ5dGVzID0gbnRpKGJ1Zltwb3MgKyAxMjpwb3MgKyAyNF0pCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgaWYgb2Zmc2V0ID4gbGFzdHBvczoKICAgICAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2hvbGUobGFzdHBvcywgb2Zmc2V0IC0gbGFzdHBvcykpCiAgICAgICAgICAgICAgICBzcC5hcHBlbmQoX2RhdGEob2Zmc2V0LCBudW1ieXRlcywgcmVhbHBvcykpCiAgICAgICAgICAgICAgICByZWFscG9zICs9IG51bWJ5dGVzCiAgICAgICAgICAgICAgICBsYXN0cG9zID0gb2Zmc2V0ICsgbnVtYnl0ZXMKICAgICAgICAgICAgICAgIHBvcyArPSAyNAogICAgICAgICAgICBpc2V4dGVuZGVkID0gb3JkKGJ1Zls1MDRdKQoKICAgICAgICBpZiBsYXN0cG9zIDwgb3JpZ3NpemU6CiAgICAgICAgICAgIHNwLmFwcGVuZChfaG9sZShsYXN0cG9zLCBvcmlnc2l6ZSAtIGxhc3Rwb3MpKQoKICAgICAgICBzZWxmLnNwYXJzZSA9IHNwCgogICAgICAgIHNlbGYub2Zmc2V0X2RhdGEgPSB0YXJmaWxlLmZpbGVvYmoudGVsbCgpCiAgICAgICAgdGFyZmlsZS5vZmZzZXQgPSBzZWxmLm9mZnNldF9kYXRhICsgc2VsZi5fYmxvY2soc2VsZi5zaXplKQogICAgICAgIHNlbGYuc2l6ZSA9IG9yaWdzaXplCgogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9wcm9jX3BheChzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJQcm9jZXNzIGFuIGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIgYXMgZGVzY3JpYmVkIGluCiAgICAgICAgICAgUE9TSVguMS0yMDAxLgogICAgICAgICIiIgogICAgICAgICMgUmVhZCB0aGUgaGVhZGVyIGluZm9ybWF0aW9uLgogICAgICAgIGJ1ZiA9IHRhcmZpbGUuZmlsZW9iai5yZWFkKHNlbGYuX2Jsb2NrKHNlbGYuc2l6ZSkpCgogICAgICAgICMgQSBwYXggaGVhZGVyIHN0b3JlcyBzdXBwbGVtZW50YWwgaW5mb3JtYXRpb24gZm9yIGVpdGhlcgogICAgICAgICMgdGhlIGZvbGxvd2luZyBmaWxlIChleHRlbmRlZCkgb3IgYWxsIGZvbGxvd2luZyBmaWxlcwogICAgICAgICMgKGdsb2JhbCkuCiAgICAgICAgaWYgc2VsZi50eXBlID09IFhHTFRZUEU6CiAgICAgICAgICAgIHBheF9oZWFkZXJzID0gdGFyZmlsZS5wYXhfaGVhZGVycwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHBheF9oZWFkZXJzID0gdGFyZmlsZS5wYXhfaGVhZGVycy5jb3B5KCkKCiAgICAgICAgIyBQYXJzZSBwYXggaGVhZGVyIGluZm9ybWF0aW9uLiBBIHJlY29yZCBsb29rcyBsaWtlIHRoYXQ6CiAgICAgICAgIyAiJWQgJXM9JXNcbiIgJSAobGVuZ3RoLCBrZXl3b3JkLCB2YWx1ZSkuIGxlbmd0aCBpcyB0aGUgc2l6ZQogICAgICAgICMgb2YgdGhlIGNvbXBsZXRlIHJlY29yZCBpbmNsdWRpbmcgdGhlIGxlbmd0aCBmaWVsZCBpdHNlbGYgYW5kCiAgICAgICAgIyB0aGUgbmV3bGluZS4ga2V5d29yZCBhbmQgdmFsdWUgYXJlIGJvdGggVVRGLTggZW5jb2RlZCBzdHJpbmdzLgogICAgICAgIHJlZ2V4ID0gcmUuY29tcGlsZShyIihcZCspIChbXj1dKyk9IiwgcmUuVSkKICAgICAgICBwb3MgPSAwCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgbWF0Y2ggPSByZWdleC5tYXRjaChidWYsIHBvcykKICAgICAgICAgICAgaWYgbm90IG1hdGNoOgogICAgICAgICAgICAgICAgYnJlYWsKCiAgICAgICAgICAgIGxlbmd0aCwga2V5d29yZCA9IG1hdGNoLmdyb3VwcygpCiAgICAgICAgICAgIGxlbmd0aCA9IGludChsZW5ndGgpCiAgICAgICAgICAgIHZhbHVlID0gYnVmW21hdGNoLmVuZCgyKSArIDE6bWF0Y2guc3RhcnQoMSkgKyBsZW5ndGggLSAxXQoKICAgICAgICAgICAga2V5d29yZCA9IGtleXdvcmQuZGVjb2RlKCJ1dGY4IikKICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5kZWNvZGUoInV0ZjgiKQoKICAgICAgICAgICAgcGF4X2hlYWRlcnNba2V5d29yZF0gPSB2YWx1ZQogICAgICAgICAgICBwb3MgKz0gbGVuZ3RoCgogICAgICAgICMgRmV0Y2ggdGhlIG5leHQgaGVhZGVyLgogICAgICAgIHRyeToKICAgICAgICAgICAgbmV4dCA9IHNlbGYuZnJvbXRhcmZpbGUodGFyZmlsZSkKICAgICAgICBleGNlcHQgSGVhZGVyRXJyb3I6CiAgICAgICAgICAgIHJhaXNlIFN1YnNlcXVlbnRIZWFkZXJFcnJvcigibWlzc2luZyBvciBiYWQgc3Vic2VxdWVudCBoZWFkZXIiKQoKICAgICAgICBpZiBzZWxmLnR5cGUgaW4gKFhIRFRZUEUsIFNPTEFSSVNfWEhEVFlQRSk6CiAgICAgICAgICAgICMgUGF0Y2ggdGhlIFRhckluZm8gb2JqZWN0IHdpdGggdGhlIGV4dGVuZGVkIGhlYWRlciBpbmZvLgogICAgICAgICAgICBuZXh0Ll9hcHBseV9wYXhfaW5mbyhwYXhfaGVhZGVycywgdGFyZmlsZS5lbmNvZGluZywgdGFyZmlsZS5lcnJvcnMpCiAgICAgICAgICAgIG5leHQub2Zmc2V0ID0gc2VsZi5vZmZzZXQKCiAgICAgICAgICAgIGlmICJzaXplIiBpbiBwYXhfaGVhZGVyczoKICAgICAgICAgICAgICAgICMgSWYgdGhlIGV4dGVuZGVkIGhlYWRlciByZXBsYWNlcyB0aGUgc2l6ZSBmaWVsZCwKICAgICAgICAgICAgICAgICMgd2UgbmVlZCB0byByZWNhbGN1bGF0ZSB0aGUgb2Zmc2V0IHdoZXJlIHRoZSBuZXh0CiAgICAgICAgICAgICAgICAjIGhlYWRlciBzdGFydHMuCiAgICAgICAgICAgICAgICBvZmZzZXQgPSBuZXh0Lm9mZnNldF9kYXRhCiAgICAgICAgICAgICAgICBpZiBuZXh0LmlzcmVnKCkgb3IgbmV4dC50eXBlIG5vdCBpbiBTVVBQT1JURURfVFlQRVM6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ICs9IG5leHQuX2Jsb2NrKG5leHQuc2l6ZSkKICAgICAgICAgICAgICAgIHRhcmZpbGUub2Zmc2V0ID0gb2Zmc2V0CgogICAgICAgIHJldHVybiBuZXh0CgogICAgZGVmIF9hcHBseV9wYXhfaW5mbyhzZWxmLCBwYXhfaGVhZGVycywgZW5jb2RpbmcsIGVycm9ycyk6CiAgICAgICAgIiIiUmVwbGFjZSBmaWVsZHMgd2l0aCBzdXBwbGVtZW50YWwgaW5mb3JtYXRpb24gZnJvbSBhIHByZXZpb3VzCiAgICAgICAgICAgcGF4IGV4dGVuZGVkIG9yIGdsb2JhbCBoZWFkZXIuCiAgICAgICAgIiIiCiAgICAgICAgZm9yIGtleXdvcmQsIHZhbHVlIGluIHBheF9oZWFkZXJzLml0ZXJpdGVtcygpOgogICAgICAgICAgICBpZiBrZXl3b3JkIG5vdCBpbiBQQVhfRklFTERTOgogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIGlmIGtleXdvcmQgPT0gInBhdGgiOgogICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yc3RyaXAoIi8iKQoKICAgICAgICAgICAgaWYga2V5d29yZCBpbiBQQVhfTlVNQkVSX0ZJRUxEUzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFBBWF9OVU1CRVJfRklFTERTW2tleXdvcmRdKHZhbHVlKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAwCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHV0cyh2YWx1ZSwgZW5jb2RpbmcsIGVycm9ycykKCiAgICAgICAgICAgIHNldGF0dHIoc2VsZiwga2V5d29yZCwgdmFsdWUpCgogICAgICAgIHNlbGYucGF4X2hlYWRlcnMgPSBwYXhfaGVhZGVycy5jb3B5KCkKCiAgICBkZWYgX2Jsb2NrKHNlbGYsIGNvdW50KToKICAgICAgICAiIiJSb3VuZCB1cCBhIGJ5dGUgY291bnQgYnkgQkxPQ0tTSVpFIGFuZCByZXR1cm4gaXQsCiAgICAgICAgICAgZS5nLiBfYmxvY2soODM0KSA9PiAxMDI0LgogICAgICAgICIiIgogICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKGNvdW50LCBCTE9DS1NJWkUpCiAgICAgICAgaWYgcmVtYWluZGVyOgogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHJldHVybiBibG9ja3MgKiBCTE9DS1NJWkUKCiAgICBkZWYgaXNyZWcoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSBpbiBSRUdVTEFSX1RZUEVTCiAgICBkZWYgaXNmaWxlKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmlzcmVnKCkKICAgIGRlZiBpc2RpcihzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IERJUlRZUEUKICAgIGRlZiBpc3N5bShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IFNZTVRZUEUKICAgIGRlZiBpc2xuayhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IExOS1RZUEUKICAgIGRlZiBpc2NocihzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IENIUlRZUEUKICAgIGRlZiBpc2JsayhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlID09IEJMS1RZUEUKICAgIGRlZiBpc2ZpZm8oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYudHlwZSA9PSBGSUZPVFlQRQogICAgZGVmIGlzc3BhcnNlKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnR5cGUgPT0gR05VVFlQRV9TUEFSU0UKICAgIGRlZiBpc2RldihzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi50eXBlIGluIChDSFJUWVBFLCBCTEtUWVBFLCBGSUZPVFlQRSkKIyBjbGFzcyBUYXJJbmZvCgpjbGFzcyBUYXJGaWxlKG9iamVjdCk6CiAgICAiIiJUaGUgVGFyRmlsZSBDbGFzcyBwcm92aWRlcyBhbiBpbnRlcmZhY2UgdG8gdGFyIGFyY2hpdmVzLgogICAgIiIiCgogICAgZGVidWcgPSAwICAgICAgICAgICAgICAgICAgICMgTWF5IGJlIHNldCBmcm9tIDAgKG5vIG1zZ3MpIHRvIDMgKGFsbCBtc2dzKQoKICAgIGRlcmVmZXJlbmNlID0gRmFsc2UgICAgICAgICAjIElmIHRydWUsIGFkZCBjb250ZW50IG9mIGxpbmtlZCBmaWxlIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGFyIGZpbGUsIGVsc2UgdGhlIGxpbmsuCgogICAgaWdub3JlX3plcm9zID0gRmFsc2UgICAgICAgICMgSWYgdHJ1ZSwgc2tpcHMgZW1wdHkgb3IgaW52YWxpZCBibG9ja3MgYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjb250aW51ZXMgcHJvY2Vzc2luZy4KCiAgICBlcnJvcmxldmVsID0gMSAgICAgICAgICAgICAgIyBJZiAwLCBmYXRhbCBlcnJvcnMgb25seSBhcHBlYXIgaW4gZGVidWcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lc3NhZ2VzIChpZiBkZWJ1ZyA+PSAwKS4gSWYgPiAwLCBlcnJvcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGFyZSBwYXNzZWQgdG8gdGhlIGNhbGxlciBhcyBleGNlcHRpb25zLgoKICAgIGZvcm1hdCA9IERFRkFVTFRfRk9STUFUICAgICAjIFRoZSBmb3JtYXQgdG8gdXNlIHdoZW4gY3JlYXRpbmcgYW4gYXJjaGl2ZS4KCiAgICBlbmNvZGluZyA9IEVOQ09ESU5HICAgICAgICAgIyBFbmNvZGluZyBmb3IgOC1iaXQgY2hhcmFjdGVyIHN0cmluZ3MuCgogICAgZXJyb3JzID0gTm9uZSAgICAgICAgICAgICAgICMgRXJyb3IgaGFuZGxlciBmb3IgdW5pY29kZSBjb252ZXJzaW9uLgoKICAgIHRhcmluZm8gPSBUYXJJbmZvICAgICAgICAgICAjIFRoZSBkZWZhdWx0IFRhckluZm8gY2xhc3MgdG8gdXNlLgoKICAgIGZpbGVvYmplY3QgPSBFeEZpbGVPYmplY3QgICAjIFRoZSBkZWZhdWx0IEV4RmlsZU9iamVjdCBjbGFzcyB0byB1c2UuCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWU9Tm9uZSwgbW9kZT0iciIsIGZpbGVvYmo9Tm9uZSwgZm9ybWF0PU5vbmUsCiAgICAgICAgICAgIHRhcmluZm89Tm9uZSwgZGVyZWZlcmVuY2U9Tm9uZSwgaWdub3JlX3plcm9zPU5vbmUsIGVuY29kaW5nPU5vbmUsCiAgICAgICAgICAgIGVycm9ycz1Ob25lLCBwYXhfaGVhZGVycz1Ob25lLCBkZWJ1Zz1Ob25lLCBlcnJvcmxldmVsPU5vbmUpOgogICAgICAgICIiIk9wZW4gYW4gKHVuY29tcHJlc3NlZCkgdGFyIGFyY2hpdmUgYG5hbWUnLiBgbW9kZScgaXMgZWl0aGVyICdyJyB0bwogICAgICAgICAgIHJlYWQgZnJvbSBhbiBleGlzdGluZyBhcmNoaXZlLCAnYScgdG8gYXBwZW5kIGRhdGEgdG8gYW4gZXhpc3RpbmcKICAgICAgICAgICBmaWxlIG9yICd3JyB0byBjcmVhdGUgYSBuZXcgZmlsZSBvdmVyd3JpdGluZyBhbiBleGlzdGluZyBvbmUuIGBtb2RlJwogICAgICAgICAgIGRlZmF1bHRzIHRvICdyJy4KICAgICAgICAgICBJZiBgZmlsZW9iaicgaXMgZ2l2ZW4sIGl0IGlzIHVzZWQgZm9yIHJlYWRpbmcgb3Igd3JpdGluZyBkYXRhLiBJZiBpdAogICAgICAgICAgIGNhbiBiZSBkZXRlcm1pbmVkLCBgbW9kZScgaXMgb3ZlcnJpZGRlbiBieSBgZmlsZW9iaidzIG1vZGUuCiAgICAgICAgICAgYGZpbGVvYmonIGlzIG5vdCBjbG9zZWQsIHdoZW4gVGFyRmlsZSBpcyBjbG9zZWQuCiAgICAgICAgIiIiCiAgICAgICAgbW9kZXMgPSB7InIiOiAicmIiLCAiYSI6ICJyK2IiLCAidyI6ICJ3YiJ9CiAgICAgICAgaWYgbW9kZSBub3QgaW4gbW9kZXM6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicsICdhJyBvciAndyciKQogICAgICAgIHNlbGYubW9kZSA9IG1vZGUKICAgICAgICBzZWxmLl9tb2RlID0gbW9kZXNbbW9kZV0KCiAgICAgICAgaWYgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiYSIgYW5kIG5vdCBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAgICAgICAgICMgQ3JlYXRlIG5vbmV4aXN0ZW50IGZpbGVzIGluIGFwcGVuZCBtb2RlLgogICAgICAgICAgICAgICAgc2VsZi5tb2RlID0gInciCiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gIndiIgogICAgICAgICAgICBmaWxlb2JqID0gYmx0bl9vcGVuKG5hbWUsIHNlbGYuX21vZGUpCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIG5hbWUgaXMgTm9uZSBhbmQgaGFzYXR0cihmaWxlb2JqLCAibmFtZSIpOgogICAgICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQogICAgICAgICAgICBpZiBoYXNhdHRyKGZpbGVvYmosICJtb2RlIik6CiAgICAgICAgICAgICAgICBzZWxmLl9tb2RlID0gZmlsZW9iai5tb2RlCiAgICAgICAgICAgIHNlbGYuX2V4dGZpbGVvYmogPSBUcnVlCiAgICAgICAgc2VsZi5uYW1lID0gb3MucGF0aC5hYnNwYXRoKG5hbWUpIGlmIG5hbWUgZWxzZSBOb25lCiAgICAgICAgc2VsZi5maWxlb2JqID0gZmlsZW9iagoKICAgICAgICAjIEluaXQgYXR0cmlidXRlcy4KICAgICAgICBpZiBmb3JtYXQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZm9ybWF0ID0gZm9ybWF0CiAgICAgICAgaWYgdGFyaW5mbyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi50YXJpbmZvID0gdGFyaW5mbwogICAgICAgIGlmIGRlcmVmZXJlbmNlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlcmVmZXJlbmNlID0gZGVyZWZlcmVuY2UKICAgICAgICBpZiBpZ25vcmVfemVyb3MgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuaWdub3JlX3plcm9zID0gaWdub3JlX3plcm9zCiAgICAgICAgaWYgZW5jb2RpbmcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmcgPSBlbmNvZGluZwoKICAgICAgICBpZiBlcnJvcnMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuZXJyb3JzID0gZXJyb3JzCiAgICAgICAgZWxpZiBtb2RlID09ICJyIjoKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAidXRmLTgiCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5lcnJvcnMgPSAic3RyaWN0IgoKICAgICAgICBpZiBwYXhfaGVhZGVycyBpcyBub3QgTm9uZSBhbmQgc2VsZi5mb3JtYXQgPT0gUEFYX0ZPUk1BVDoKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wYXhfaGVhZGVycyA9IHt9CgogICAgICAgIGlmIGRlYnVnIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmRlYnVnID0gZGVidWcKICAgICAgICBpZiBlcnJvcmxldmVsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLmVycm9ybGV2ZWwgPSBlcnJvcmxldmVsCgogICAgICAgICMgSW5pdCBkYXRhc3RydWN0dXJlcy4KICAgICAgICBzZWxmLmNsb3NlZCA9IEZhbHNlCiAgICAgICAgc2VsZi5tZW1iZXJzID0gW10gICAgICAgIyBsaXN0IG9mIG1lbWJlcnMgYXMgVGFySW5mbyBvYmplY3RzCiAgICAgICAgc2VsZi5fbG9hZGVkID0gRmFsc2UgICAgIyBmbGFnIGlmIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkCiAgICAgICAgc2VsZi5vZmZzZXQgPSBzZWxmLmZpbGVvYmoudGVsbCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBhcmNoaXZlIGZpbGUKICAgICAgICBzZWxmLmlub2RlcyA9IHt9ICAgICAgICAjIGRpY3Rpb25hcnkgY2FjaGluZyB0aGUgaW5vZGVzIG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhcmNoaXZlIG1lbWJlcnMgYWxyZWFkeSBhZGRlZAoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIHNlbGYubW9kZSA9PSAiciI6CiAgICAgICAgICAgICAgICBzZWxmLmZpcnN0bWVtYmVyID0gTm9uZQogICAgICAgICAgICAgICAgc2VsZi5maXJzdG1lbWJlciA9IHNlbGYubmV4dCgpCgogICAgICAgICAgICBpZiBzZWxmLm1vZGUgPT0gImEiOgogICAgICAgICAgICAgICAgIyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIGFyY2hpdmUsCiAgICAgICAgICAgICAgICAjIGJlZm9yZSB0aGUgZmlyc3QgZW1wdHkgYmxvY2suCiAgICAgICAgICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0KQogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyaW5mby5mcm9tdGFyZmlsZShzZWxmKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IEVPRkhlYWRlckVycm9yOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouc2VlayhzZWxmLm9mZnNldCkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICBleGNlcHQgSGVhZGVyRXJyb3IsIGU6CiAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcihzdHIoZSkpCgogICAgICAgICAgICBpZiBzZWxmLm1vZGUgaW4gImF3IjoKICAgICAgICAgICAgICAgIHNlbGYuX2xvYWRlZCA9IFRydWUKCiAgICAgICAgICAgICAgICBpZiBzZWxmLnBheF9oZWFkZXJzOgogICAgICAgICAgICAgICAgICAgIGJ1ZiA9IHNlbGYudGFyaW5mby5jcmVhdGVfcGF4X2dsb2JhbF9oZWFkZXIoc2VsZi5wYXhfaGVhZGVycy5jb3B5KCkpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKGJ1ZikKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBsZW4oYnVmKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgaWYgbm90IHNlbGYuX2V4dGZpbGVvYmo6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmouY2xvc2UoKQogICAgICAgICAgICBzZWxmLmNsb3NlZCA9IFRydWUKICAgICAgICAgICAgcmFpc2UKCiAgICBkZWYgX2dldHBvc2l4KHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLmZvcm1hdCA9PSBVU1RBUl9GT1JNQVQKICAgIGRlZiBfc2V0cG9zaXgoc2VsZiwgdmFsdWUpOgogICAgICAgIGltcG9ydCB3YXJuaW5ncwogICAgICAgIHdhcm5pbmdzLndhcm4oInVzZSB0aGUgZm9ybWF0IGF0dHJpYnV0ZSBpbnN0ZWFkIiwgRGVwcmVjYXRpb25XYXJuaW5nLAogICAgICAgICAgICAgICAgICAgICAgMikKICAgICAgICBpZiB2YWx1ZToKICAgICAgICAgICAgc2VsZi5mb3JtYXQgPSBVU1RBUl9GT1JNQVQKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLmZvcm1hdCA9IEdOVV9GT1JNQVQKICAgIHBvc2l4ID0gcHJvcGVydHkoX2dldHBvc2l4LCBfc2V0cG9zaXgpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIEJlbG93IGFyZSB0aGUgY2xhc3NtZXRob2RzIHdoaWNoIGFjdCBhcyBhbHRlcm5hdGUgY29uc3RydWN0b3JzIHRvIHRoZQogICAgIyBUYXJGaWxlIGNsYXNzLiBUaGUgb3BlbigpIG1ldGhvZCBpcyB0aGUgb25seSBvbmUgdGhhdCBpcyBuZWVkZWQgZm9yCiAgICAjIHB1YmxpYyB1c2U7IGl0IGlzIHRoZSAic3VwZXIiLWNvbnN0cnVjdG9yIGFuZCBpcyBhYmxlIHRvIHNlbGVjdCBhbgogICAgIyBhZGVxdWF0ZSAic3ViIi1jb25zdHJ1Y3RvciBmb3IgYSBwYXJ0aWN1bGFyIGNvbXByZXNzaW9uIHVzaW5nIHRoZSBtYXBwaW5nCiAgICAjIGZyb20gT1BFTl9NRVRILgogICAgIwogICAgIyBUaGlzIGNvbmNlcHQgYWxsb3dzIG9uZSB0byBzdWJjbGFzcyBUYXJGaWxlIHdpdGhvdXQgbG9zaW5nIHRoZSBjb21mb3J0IG9mCiAgICAjIHRoZSBzdXBlci1jb25zdHJ1Y3Rvci4gQSBzdWItY29uc3RydWN0b3IgaXMgcmVnaXN0ZXJlZCBhbmQgbWFkZSBhdmFpbGFibGUKICAgICMgYnkgYWRkaW5nIGl0IHRvIHRoZSBtYXBwaW5nIGluIE9QRU5fTUVUSC4KCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBvcGVuKGNscywgbmFtZT1Ob25lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBidWZzaXplPVJFQ09SRFNJWkUsICoqa3dhcmdzKToKICAgICAgICAiIiJPcGVuIGEgdGFyIGFyY2hpdmUgZm9yIHJlYWRpbmcsIHdyaXRpbmcgb3IgYXBwZW5kaW5nLiBSZXR1cm4KICAgICAgICAgICBhbiBhcHByb3ByaWF0ZSBUYXJGaWxlIGNsYXNzLgoKICAgICAgICAgICBtb2RlOgogICAgICAgICAgICdyJyBvciAncjoqJyBvcGVuIGZvciByZWFkaW5nIHdpdGggdHJhbnNwYXJlbnQgY29tcHJlc3Npb24KICAgICAgICAgICAncjonICAgICAgICAgb3BlbiBmb3IgcmVhZGluZyBleGNsdXNpdmVseSB1bmNvbXByZXNzZWQKICAgICAgICAgICAncjpneicgICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGd6aXAgY29tcHJlc3Npb24KICAgICAgICAgICAncjpiejInICAgICAgb3BlbiBmb3IgcmVhZGluZyB3aXRoIGJ6aXAyIGNvbXByZXNzaW9uCiAgICAgICAgICAgJ2EnIG9yICdhOicgIG9wZW4gZm9yIGFwcGVuZGluZywgY3JlYXRpbmcgdGhlIGZpbGUgaWYgbmVjZXNzYXJ5CiAgICAgICAgICAgJ3cnIG9yICd3OicgIG9wZW4gZm9yIHdyaXRpbmcgd2l0aG91dCBjb21wcmVzc2lvbgogICAgICAgICAgICd3Omd6JyAgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggZ3ppcCBjb21wcmVzc2lvbgogICAgICAgICAgICd3OmJ6MicgICAgICBvcGVuIGZvciB3cml0aW5nIHdpdGggYnppcDIgY29tcHJlc3Npb24KCiAgICAgICAgICAgJ3J8KicgICAgICAgIG9wZW4gYSBzdHJlYW0gb2YgdGFyIGJsb2NrcyB3aXRoIHRyYW5zcGFyZW50IGNvbXByZXNzaW9uCiAgICAgICAgICAgJ3J8JyAgICAgICAgIG9wZW4gYW4gdW5jb21wcmVzc2VkIHN0cmVhbSBvZiB0YXIgYmxvY2tzIGZvciByZWFkaW5nCiAgICAgICAgICAgJ3J8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAncnxiejInICAgICAgb3BlbiBhIGJ6aXAyIGNvbXByZXNzZWQgc3RyZWFtIG9mIHRhciBibG9ja3MKICAgICAgICAgICAnd3wnICAgICAgICAgb3BlbiBhbiB1bmNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8Z3onICAgICAgIG9wZW4gYSBnemlwIGNvbXByZXNzZWQgc3RyZWFtIGZvciB3cml0aW5nCiAgICAgICAgICAgJ3d8YnoyJyAgICAgIG9wZW4gYSBiemlwMiBjb21wcmVzc2VkIHN0cmVhbSBmb3Igd3JpdGluZwogICAgICAgICIiIgoKICAgICAgICBpZiBub3QgbmFtZSBhbmQgbm90IGZpbGVvYmo6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm5vdGhpbmcgdG8gb3BlbiIpCgogICAgICAgIGlmIG1vZGUgaW4gKCJyIiwgInI6KiIpOgogICAgICAgICAgICAjIEZpbmQgb3V0IHdoaWNoICpvcGVuKCkgaXMgYXBwcm9wcmlhdGUgZm9yIG9wZW5pbmcgdGhlIGZpbGUuCiAgICAgICAgICAgIGZvciBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgc2F2ZWRfcG9zID0gZmlsZW9iai50ZWxsKCkKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuYyhuYW1lLCAiciIsIGZpbGVvYmosICoqa3dhcmdzKQogICAgICAgICAgICAgICAgZXhjZXB0IChSZWFkRXJyb3IsIENvbXByZXNzaW9uRXJyb3IpLCBlOgogICAgICAgICAgICAgICAgICAgIGlmIGZpbGVvYmogaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVvYmouc2VlayhzYXZlZF9wb3MpCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJmaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQgc3VjY2Vzc2Z1bGx5IikKCiAgICAgICAgZWxpZiAiOiIgaW4gbW9kZToKICAgICAgICAgICAgZmlsZW1vZGUsIGNvbXB0eXBlID0gbW9kZS5zcGxpdCgiOiIsIDEpCiAgICAgICAgICAgIGZpbGVtb2RlID0gZmlsZW1vZGUgb3IgInIiCiAgICAgICAgICAgIGNvbXB0eXBlID0gY29tcHR5cGUgb3IgInRhciIKCiAgICAgICAgICAgICMgU2VsZWN0IHRoZSAqb3BlbigpIGZ1bmN0aW9uIGFjY29yZGluZyB0bwogICAgICAgICAgICAjIGdpdmVuIGNvbXByZXNzaW9uLgogICAgICAgICAgICBpZiBjb21wdHlwZSBpbiBjbHMuT1BFTl9NRVRIOgogICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIoY2xzLCBjbHMuT1BFTl9NRVRIW2NvbXB0eXBlXSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJhaXNlIENvbXByZXNzaW9uRXJyb3IoInVua25vd24gY29tcHJlc3Npb24gdHlwZSAlciIgJSBjb21wdHlwZSkKICAgICAgICAgICAgcmV0dXJuIGZ1bmMobmFtZSwgZmlsZW1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQoKICAgICAgICBlbGlmICJ8IiBpbiBtb2RlOgogICAgICAgICAgICBmaWxlbW9kZSwgY29tcHR5cGUgPSBtb2RlLnNwbGl0KCJ8IiwgMSkKICAgICAgICAgICAgZmlsZW1vZGUgPSBmaWxlbW9kZSBvciAiciIKICAgICAgICAgICAgY29tcHR5cGUgPSBjb21wdHlwZSBvciAidGFyIgoKICAgICAgICAgICAgaWYgZmlsZW1vZGUgbm90IGluICgiciIsICJ3Iik6CiAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJtb2RlIG11c3QgYmUgJ3InIG9yICd3JyIpCgogICAgICAgICAgICBzdHJlYW0gPSBfU3RyZWFtKG5hbWUsIGZpbGVtb2RlLCBjb21wdHlwZSwgZmlsZW9iaiwgYnVmc2l6ZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdCA9IGNscyhuYW1lLCBmaWxlbW9kZSwgc3RyZWFtLCAqKmt3YXJncykKICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgc3RyZWFtLmNsb3NlKCkKICAgICAgICAgICAgICAgIHJhaXNlCiAgICAgICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gdAoKICAgICAgICBlbGlmIG1vZGUgaW4gKCJhIiwgInciKToKICAgICAgICAgICAgcmV0dXJuIGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ1bmRpc2Nlcm5pYmxlIG1vZGUiKQoKICAgIEBjbGFzc21ldGhvZAogICAgZGVmIHRhcm9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCAqKmt3YXJncyk6CiAgICAgICAgIiIiT3BlbiB1bmNvbXByZXNzZWQgdGFyIGFyY2hpdmUgbmFtZSBmb3IgcmVhZGluZyBvciB3cml0aW5nLgogICAgICAgICIiIgogICAgICAgIGlmIG1vZGUgbm90IGluICgiciIsICJhIiwgInciKToKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigibW9kZSBtdXN0IGJlICdyJywgJ2EnIG9yICd3JyIpCiAgICAgICAgcmV0dXJuIGNscyhuYW1lLCBtb2RlLCBmaWxlb2JqLCAqKmt3YXJncykKCiAgICBAY2xhc3NtZXRob2QKICAgIGRlZiBnem9wZW4oY2xzLCBuYW1lLCBtb2RlPSJyIiwgZmlsZW9iaj1Ob25lLCBjb21wcmVzc2xldmVsPTksICoqa3dhcmdzKToKICAgICAgICAiIiJPcGVuIGd6aXAgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIG1vZGUgbm90IGluICgiciIsICJ3Iik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpbXBvcnQgZ3ppcAogICAgICAgICAgICBnemlwLkd6aXBGaWxlCiAgICAgICAgZXhjZXB0IChJbXBvcnRFcnJvciwgQXR0cmlidXRlRXJyb3IpOgogICAgICAgICAgICByYWlzZSBDb21wcmVzc2lvbkVycm9yKCJnemlwIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlb2JqID0gZ3ppcC5HemlwRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsLCBmaWxlb2JqKQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBpZiBmaWxlb2JqIGlzIG5vdCBOb25lIGFuZCBtb2RlID09ICdyJzoKICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICAgICAgcmFpc2UKCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0ID0gY2xzLnRhcm9wZW4obmFtZSwgbW9kZSwgZmlsZW9iaiwgKiprd2FyZ3MpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIGZpbGVvYmouY2xvc2UoKQogICAgICAgICAgICBpZiBtb2RlID09ICdyJzoKICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcigibm90IGEgZ3ppcCBmaWxlIikKICAgICAgICAgICAgcmFpc2UKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIGZpbGVvYmouY2xvc2UoKQogICAgICAgICAgICByYWlzZQogICAgICAgIHQuX2V4dGZpbGVvYmogPSBGYWxzZQogICAgICAgIHJldHVybiB0CgogICAgQGNsYXNzbWV0aG9kCiAgICBkZWYgYnoyb3BlbihjbHMsIG5hbWUsIG1vZGU9InIiLCBmaWxlb2JqPU5vbmUsIGNvbXByZXNzbGV2ZWw9OSwgKiprd2FyZ3MpOgogICAgICAgICIiIk9wZW4gYnppcDIgY29tcHJlc3NlZCB0YXIgYXJjaGl2ZSBuYW1lIGZvciByZWFkaW5nIG9yIHdyaXRpbmcuCiAgICAgICAgICAgQXBwZW5kaW5nIGlzIG5vdCBhbGxvd2VkLgogICAgICAgICIiIgogICAgICAgIGlmIG1vZGUgbm90IGluICgiciIsICJ3Iik6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoIm1vZGUgbXVzdCBiZSAncicgb3IgJ3cnLiIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgaW1wb3J0IGJ6MgogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgcmFpc2UgQ29tcHJlc3Npb25FcnJvcigiYnoyIG1vZHVsZSBpcyBub3QgYXZhaWxhYmxlIikKCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgZmlsZW9iaiA9IF9CWjJQcm94eShmaWxlb2JqLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGZpbGVvYmogPSBiejIuQloyRmlsZShuYW1lLCBtb2RlLCBjb21wcmVzc2xldmVsPWNvbXByZXNzbGV2ZWwpCgogICAgICAgIHRyeToKICAgICAgICAgICAgdCA9IGNscy50YXJvcGVuKG5hbWUsIG1vZGUsIGZpbGVvYmosICoqa3dhcmdzKQogICAgICAgIGV4Y2VwdCAoSU9FcnJvciwgRU9GRXJyb3IpOgogICAgICAgICAgICBmaWxlb2JqLmNsb3NlKCkKICAgICAgICAgICAgaWYgbW9kZSA9PSAncic6CiAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoIm5vdCBhIGJ6aXAyIGZpbGUiKQogICAgICAgICAgICByYWlzZQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgZmlsZW9iai5jbG9zZSgpCiAgICAgICAgICAgIHJhaXNlCiAgICAgICAgdC5fZXh0ZmlsZW9iaiA9IEZhbHNlCiAgICAgICAgcmV0dXJuIHQKCiAgICAjIEFsbCAqb3BlbigpIG1ldGhvZHMgYXJlIHJlZ2lzdGVyZWQgaGVyZS4KICAgIE9QRU5fTUVUSCA9IHsKICAgICAgICAidGFyIjogInRhcm9wZW4iLCAgICMgdW5jb21wcmVzc2VkIHRhcgogICAgICAgICJneiI6ICAiZ3pvcGVuIiwgICAgIyBnemlwIGNvbXByZXNzZWQgdGFyCiAgICAgICAgImJ6MiI6ICJiejJvcGVuIiAgICAjIGJ6aXAyIGNvbXByZXNzZWQgdGFyCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIFRoZSBwdWJsaWMgbWV0aG9kcyB3aGljaCBUYXJGaWxlIHByb3ZpZGVzOgoKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICAiIiJDbG9zZSB0aGUgVGFyRmlsZS4gSW4gd3JpdGUtbW9kZSwgdHdvIGZpbmlzaGluZyB6ZXJvIGJsb2NrcyBhcmUKICAgICAgICAgICBhcHBlbmRlZCB0byB0aGUgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiBzZWxmLmNsb3NlZDoKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQogICAgICAgIHRyeToKICAgICAgICAgICAgaWYgc2VsZi5tb2RlIGluICJhdyI6CiAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKEJMT0NLU0laRSAqIDIpKQogICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gKEJMT0NLU0laRSAqIDIpCiAgICAgICAgICAgICAgICAjIGZpbGwgdXAgdGhlIGVuZCB3aXRoIHplcm8tYmxvY2tzCiAgICAgICAgICAgICAgICAjIChsaWtlIG9wdGlvbiAtYjIwIGZvciB0YXIgZG9lcykKICAgICAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHNlbGYub2Zmc2V0LCBSRUNPUkRTSVpFKQogICAgICAgICAgICAgICAgaWYgcmVtYWluZGVyID4gMDoKICAgICAgICAgICAgICAgICAgICBzZWxmLmZpbGVvYmoud3JpdGUoTlVMICogKFJFQ09SRFNJWkUgLSByZW1haW5kZXIpKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9leHRmaWxlb2JqOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLmNsb3NlKCkKCiAgICBkZWYgZ2V0bWVtYmVyKHNlbGYsIG5hbWUpOgogICAgICAgICIiIlJldHVybiBhIFRhckluZm8gb2JqZWN0IGZvciBtZW1iZXIgYG5hbWUnLiBJZiBgbmFtZScgY2FuIG5vdCBiZQogICAgICAgICAgIGZvdW5kIGluIHRoZSBhcmNoaXZlLCBLZXlFcnJvciBpcyByYWlzZWQuIElmIGEgbWVtYmVyIG9jY3VycyBtb3JlCiAgICAgICAgICAgdGhhbiBvbmNlIGluIHRoZSBhcmNoaXZlLCBpdHMgbGFzdCBvY2N1cnJlbmNlIGlzIGFzc3VtZWQgdG8gYmUgdGhlCiAgICAgICAgICAgbW9zdCB1cC10by1kYXRlIHZlcnNpb24uCiAgICAgICAgIiIiCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuX2dldG1lbWJlcihuYW1lKQogICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgcmFpc2UgS2V5RXJyb3IoImZpbGVuYW1lICVyIG5vdCBmb3VuZCIgJSBuYW1lKQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGdldG1lbWJlcnMoc2VsZik6CiAgICAgICAgIiIiUmV0dXJuIHRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGFzIGEgbGlzdCBvZiBUYXJJbmZvIG9iamVjdHMuIFRoZQogICAgICAgICAgIGxpc3QgaGFzIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBtZW1iZXJzIGluIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKICAgICAgICBpZiBub3Qgc2VsZi5fbG9hZGVkOiAgICAjIGlmIHdlIHdhbnQgdG8gb2J0YWluIGEgbGlzdCBvZgogICAgICAgICAgICBzZWxmLl9sb2FkKCkgICAgICAgICMgYWxsIG1lbWJlcnMsIHdlIGZpcnN0IGhhdmUgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNjYW4gdGhlIHdob2xlIGFyY2hpdmUuCiAgICAgICAgcmV0dXJuIHNlbGYubWVtYmVycwoKICAgIGRlZiBnZXRuYW1lcyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG1lbWJlcnMgb2YgdGhlIGFyY2hpdmUgYXMgYSBsaXN0IG9mIHRoZWlyIG5hbWVzLiBJdCBoYXMKICAgICAgICAgICB0aGUgc2FtZSBvcmRlciBhcyB0aGUgbGlzdCByZXR1cm5lZCBieSBnZXRtZW1iZXJzKCkuCiAgICAgICAgIiIiCiAgICAgICAgcmV0dXJuIFt0YXJpbmZvLm5hbWUgZm9yIHRhcmluZm8gaW4gc2VsZi5nZXRtZW1iZXJzKCldCgogICAgZGVmIGdldHRhcmluZm8oc2VsZiwgbmFtZT1Ob25lLCBhcmNuYW1lPU5vbmUsIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQ3JlYXRlIGEgVGFySW5mbyBvYmplY3QgZnJvbSB0aGUgcmVzdWx0IG9mIG9zLnN0YXQgb3IgZXF1aXZhbGVudAogICAgICAgICAgIG9uIGFuIGV4aXN0aW5nIGZpbGUuIFRoZSBmaWxlIGlzIGVpdGhlciBuYW1lZCBieSBgbmFtZScsIG9yCiAgICAgICAgICAgc3BlY2lmaWVkIGFzIGEgZmlsZSBvYmplY3QgYGZpbGVvYmonIHdpdGggYSBmaWxlIGRlc2NyaXB0b3IuIElmCiAgICAgICAgICAgZ2l2ZW4sIGBhcmNuYW1lJyBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRpdmUgbmFtZSBmb3IgdGhlIGZpbGUgaW4gdGhlCiAgICAgICAgICAgYXJjaGl2ZSwgb3RoZXJ3aXNlLCB0aGUgbmFtZSBpcyB0YWtlbiBmcm9tIHRoZSAnbmFtZScgYXR0cmlidXRlIG9mCiAgICAgICAgICAgJ2ZpbGVvYmonLCBvciB0aGUgJ25hbWUnIGFyZ3VtZW50LgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgICMgV2hlbiBmaWxlb2JqIGlzIGdpdmVuLCByZXBsYWNlIG5hbWUgYnkKICAgICAgICAjIGZpbGVvYmoncyByZWFsIG5hbWUuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgbmFtZSA9IGZpbGVvYmoubmFtZQoKICAgICAgICAjIEJ1aWxkaW5nIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgaW4gdGhlIGFyY2hpdmUuCiAgICAgICAgIyBCYWNrd2FyZCBzbGFzaGVzIGFyZSBjb252ZXJ0ZWQgdG8gZm9yd2FyZCBzbGFzaGVzLAogICAgICAgICMgQWJzb2x1dGUgcGF0aHMgYXJlIHR1cm5lZCB0byByZWxhdGl2ZSBwYXRocy4KICAgICAgICBpZiBhcmNuYW1lIGlzIE5vbmU6CiAgICAgICAgICAgIGFyY25hbWUgPSBuYW1lCiAgICAgICAgZHJ2LCBhcmNuYW1lID0gb3MucGF0aC5zcGxpdGRyaXZlKGFyY25hbWUpCiAgICAgICAgYXJjbmFtZSA9IGFyY25hbWUucmVwbGFjZShvcy5zZXAsICIvIikKICAgICAgICBhcmNuYW1lID0gYXJjbmFtZS5sc3RyaXAoIi8iKQoKICAgICAgICAjIE5vdywgZmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aAogICAgICAgICMgaW5mb3JtYXRpb24gc3BlY2lmaWMgZm9yIHRoZSBmaWxlLgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmluZm8oKQogICAgICAgIHRhcmluZm8udGFyZmlsZSA9IHNlbGYgICMgTm90IG5lZWRlZAoKICAgICAgICAjIFVzZSBvcy5zdGF0IG9yIG9zLmxzdGF0LCBkZXBlbmRpbmcgb24gcGxhdGZvcm0KICAgICAgICAjIGFuZCBpZiBzeW1saW5rcyBzaGFsbCBiZSByZXNvbHZlZC4KICAgICAgICBpZiBmaWxlb2JqIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJsc3RhdCIpIGFuZCBub3Qgc2VsZi5kZXJlZmVyZW5jZToKICAgICAgICAgICAgICAgIHN0YXRyZXMgPSBvcy5sc3RhdChuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc3RhdHJlcyA9IG9zLnN0YXQobmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzdGF0cmVzID0gb3MuZnN0YXQoZmlsZW9iai5maWxlbm8oKSkKICAgICAgICBsaW5rbmFtZSA9ICIiCgogICAgICAgIHN0bWQgPSBzdGF0cmVzLnN0X21vZGUKICAgICAgICBpZiBzdGF0LlNfSVNSRUcoc3RtZCk6CiAgICAgICAgICAgIGlub2RlID0gKHN0YXRyZXMuc3RfaW5vLCBzdGF0cmVzLnN0X2RldikKICAgICAgICAgICAgaWYgbm90IHNlbGYuZGVyZWZlcmVuY2UgYW5kIHN0YXRyZXMuc3RfbmxpbmsgPiAxIGFuZCBcCiAgICAgICAgICAgICAgICAgICAgaW5vZGUgaW4gc2VsZi5pbm9kZXMgYW5kIGFyY25hbWUgIT0gc2VsZi5pbm9kZXNbaW5vZGVdOgogICAgICAgICAgICAgICAgIyBJcyBpdCBhIGhhcmRsaW5rIHRvIGFuIGFscmVhZHkKICAgICAgICAgICAgICAgICMgYXJjaGl2ZWQgZmlsZT8KICAgICAgICAgICAgICAgIHR5cGUgPSBMTktUWVBFCiAgICAgICAgICAgICAgICBsaW5rbmFtZSA9IHNlbGYuaW5vZGVzW2lub2RlXQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBUaGUgaW5vZGUgaXMgYWRkZWQgb25seSBpZiBpdHMgdmFsaWQuCiAgICAgICAgICAgICAgICAjIEZvciB3aW4zMiBpdCBpcyBhbHdheXMgMC4KICAgICAgICAgICAgICAgIHR5cGUgPSBSRUdUWVBFCiAgICAgICAgICAgICAgICBpZiBpbm9kZVswXToKICAgICAgICAgICAgICAgICAgICBzZWxmLmlub2Rlc1tpbm9kZV0gPSBhcmNuYW1lCiAgICAgICAgZWxpZiBzdGF0LlNfSVNESVIoc3RtZCk6CiAgICAgICAgICAgIHR5cGUgPSBESVJUWVBFCiAgICAgICAgZWxpZiBzdGF0LlNfSVNGSUZPKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gRklGT1RZUEUKICAgICAgICBlbGlmIHN0YXQuU19JU0xOSyhzdG1kKToKICAgICAgICAgICAgdHlwZSA9IFNZTVRZUEUKICAgICAgICAgICAgbGlua25hbWUgPSBvcy5yZWFkbGluayhuYW1lKQogICAgICAgIGVsaWYgc3RhdC5TX0lTQ0hSKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQ0hSVFlQRQogICAgICAgIGVsaWYgc3RhdC5TX0lTQkxLKHN0bWQpOgogICAgICAgICAgICB0eXBlID0gQkxLVFlQRQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICMgRmlsbCB0aGUgVGFySW5mbyBvYmplY3Qgd2l0aCBhbGwKICAgICAgICAjIGluZm9ybWF0aW9uIHdlIGNhbiBnZXQuCiAgICAgICAgdGFyaW5mby5uYW1lID0gYXJjbmFtZQogICAgICAgIHRhcmluZm8ubW9kZSA9IHN0bWQKICAgICAgICB0YXJpbmZvLnVpZCA9IHN0YXRyZXMuc3RfdWlkCiAgICAgICAgdGFyaW5mby5naWQgPSBzdGF0cmVzLnN0X2dpZAogICAgICAgIGlmIHR5cGUgPT0gUkVHVFlQRToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gc3RhdHJlcy5zdF9zaXplCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mby5zaXplID0gMEwKICAgICAgICB0YXJpbmZvLm10aW1lID0gc3RhdHJlcy5zdF9tdGltZQogICAgICAgIHRhcmluZm8udHlwZSA9IHR5cGUKICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbGlua25hbWUKICAgICAgICBpZiBwd2Q6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8udW5hbWUgPSBwd2QuZ2V0cHd1aWQodGFyaW5mby51aWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBpZiBncnA6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgPSBncnAuZ2V0Z3JnaWQodGFyaW5mby5naWQpWzBdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgaWYgdHlwZSBpbiAoQ0hSVFlQRSwgQkxLVFlQRSk6CiAgICAgICAgICAgIGlmIGhhc2F0dHIob3MsICJtYWpvciIpIGFuZCBoYXNhdHRyKG9zLCAibWlub3IiKToKICAgICAgICAgICAgICAgIHRhcmluZm8uZGV2bWFqb3IgPSBvcy5tYWpvcihzdGF0cmVzLnN0X3JkZXYpCiAgICAgICAgICAgICAgICB0YXJpbmZvLmRldm1pbm9yID0gb3MubWlub3Ioc3RhdHJlcy5zdF9yZGV2KQogICAgICAgIHJldHVybiB0YXJpbmZvCgogICAgZGVmIGxpc3Qoc2VsZiwgdmVyYm9zZT1UcnVlKToKICAgICAgICAiIiJQcmludCBhIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN5cy5zdGRvdXQuIElmIGB2ZXJib3NlJyBpcyBGYWxzZSwgb25seQogICAgICAgICAgIHRoZSBuYW1lcyBvZiB0aGUgbWVtYmVycyBhcmUgcHJpbnRlZC4gSWYgaXQgaXMgVHJ1ZSwgYW4gYGxzIC1sJy1saWtlCiAgICAgICAgICAgb3V0cHV0IGlzIHByb2R1Y2VkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCkKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZjoKICAgICAgICAgICAgaWYgdmVyYm9zZToKICAgICAgICAgICAgICAgIHByaW50IGZpbGVtb2RlKHRhcmluZm8ubW9kZSksCiAgICAgICAgICAgICAgICBwcmludCAiJXMvJXMiICUgKHRhcmluZm8udW5hbWUgb3IgdGFyaW5mby51aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmluZm8uZ25hbWUgb3IgdGFyaW5mby5naWQpLAogICAgICAgICAgICAgICAgaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAiJTEwcyIgJSAoIiVkLCVkIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgKHRhcmluZm8uZGV2bWFqb3IsIHRhcmluZm8uZGV2bWlub3IpKSwKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIiUxMGQiICUgdGFyaW5mby5zaXplLAogICAgICAgICAgICAgICAgcHJpbnQgIiVkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCIgXAogICAgICAgICAgICAgICAgICAgICAgJSB0aW1lLmxvY2FsdGltZSh0YXJpbmZvLm10aW1lKVs6Nl0sCgogICAgICAgICAgICBwcmludCB0YXJpbmZvLm5hbWUgKyAoIi8iIGlmIHRhcmluZm8uaXNkaXIoKSBlbHNlICIiKSwKCiAgICAgICAgICAgIGlmIHZlcmJvc2U6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgIi0+IiwgdGFyaW5mby5saW5rbmFtZSwKICAgICAgICAgICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAibGluayB0byIsIHRhcmluZm8ubGlua25hbWUsCiAgICAgICAgICAgIHByaW50CgogICAgZGVmIGFkZChzZWxmLCBuYW1lLCBhcmNuYW1lPU5vbmUsIHJlY3Vyc2l2ZT1UcnVlLCBleGNsdWRlPU5vbmUsIGZpbHRlcj1Ob25lKToKICAgICAgICAiIiJBZGQgdGhlIGZpbGUgYG5hbWUnIHRvIHRoZSBhcmNoaXZlLiBgbmFtZScgbWF5IGJlIGFueSB0eXBlIG9mIGZpbGUKICAgICAgICAgICAoZGlyZWN0b3J5LCBmaWZvLCBzeW1ib2xpYyBsaW5rLCBldGMuKS4gSWYgZ2l2ZW4sIGBhcmNuYW1lJwogICAgICAgICAgIHNwZWNpZmllcyBhbiBhbHRlcm5hdGl2ZSBuYW1lIGZvciB0aGUgZmlsZSBpbiB0aGUgYXJjaGl2ZS4KICAgICAgICAgICBEaXJlY3RvcmllcyBhcmUgYWRkZWQgcmVjdXJzaXZlbHkgYnkgZGVmYXVsdC4gVGhpcyBjYW4gYmUgYXZvaWRlZCBieQogICAgICAgICAgIHNldHRpbmcgYHJlY3Vyc2l2ZScgdG8gRmFsc2UuIGBleGNsdWRlJyBpcyBhIGZ1bmN0aW9uIHRoYXQgc2hvdWxkCiAgICAgICAgICAgcmV0dXJuIFRydWUgZm9yIGVhY2ggZmlsZW5hbWUgdG8gYmUgZXhjbHVkZWQuIGBmaWx0ZXInIGlzIGEgZnVuY3Rpb24KICAgICAgICAgICB0aGF0IGV4cGVjdHMgYSBUYXJJbmZvIG9iamVjdCBhcmd1bWVudCBhbmQgcmV0dXJucyB0aGUgY2hhbmdlZAogICAgICAgICAgIFRhckluZm8gb2JqZWN0LCBpZiBpdCByZXR1cm5zIE5vbmUgdGhlIFRhckluZm8gb2JqZWN0IHdpbGwgYmUKICAgICAgICAgICBleGNsdWRlZCBmcm9tIHRoZSBhcmNoaXZlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuX2NoZWNrKCJhdyIpCgogICAgICAgIGlmIGFyY25hbWUgaXMgTm9uZToKICAgICAgICAgICAgYXJjbmFtZSA9IG5hbWUKCiAgICAgICAgIyBFeGNsdWRlIHBhdGhuYW1lcy4KICAgICAgICBpZiBleGNsdWRlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBpbXBvcnQgd2FybmluZ3MKICAgICAgICAgICAgd2FybmluZ3Mud2FybigidXNlIHRoZSBmaWx0ZXIgYXJndW1lbnQgaW5zdGVhZCIsCiAgICAgICAgICAgICAgICAgICAgRGVwcmVjYXRpb25XYXJuaW5nLCAyKQogICAgICAgICAgICBpZiBleGNsdWRlKG5hbWUpOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDIsICJ0YXJmaWxlOiBFeGNsdWRlZCAlciIgJSBuYW1lKQogICAgICAgICAgICAgICAgcmV0dXJuCgogICAgICAgICMgU2tpcCBpZiBzb21lYm9keSB0cmllcyB0byBhcmNoaXZlIHRoZSBhcmNoaXZlLi4uCiAgICAgICAgaWYgc2VsZi5uYW1lIGlzIG5vdCBOb25lIGFuZCBvcy5wYXRoLmFic3BhdGgobmFtZSkgPT0gc2VsZi5uYW1lOgogICAgICAgICAgICBzZWxmLl9kYmcoMiwgInRhcmZpbGU6IFNraXBwZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIHNlbGYuX2RiZygxLCBuYW1lKQoKICAgICAgICAjIENyZWF0ZSBhIFRhckluZm8gb2JqZWN0IGZyb20gdGhlIGZpbGUuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0dGFyaW5mbyhuYW1lLCBhcmNuYW1lKQoKICAgICAgICBpZiB0YXJpbmZvIGlzIE5vbmU6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogVW5zdXBwb3J0ZWQgdHlwZSAlciIgJSBuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBDaGFuZ2Ugb3IgZXhjbHVkZSB0aGUgVGFySW5mbyBvYmplY3QuCiAgICAgICAgaWYgZmlsdGVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICB0YXJpbmZvID0gZmlsdGVyKHRhcmluZm8pCiAgICAgICAgICAgIGlmIHRhcmluZm8gaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAidGFyZmlsZTogRXhjbHVkZWQgJXIiICUgbmFtZSkKICAgICAgICAgICAgICAgIHJldHVybgoKICAgICAgICAjIEFwcGVuZCB0aGUgdGFyIGhlYWRlciBhbmQgZGF0YSB0byB0aGUgYXJjaGl2ZS4KICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHdpdGggYmx0bl9vcGVuKG5hbWUsICJyYiIpIGFzIGY6CiAgICAgICAgICAgICAgICBzZWxmLmFkZGZpbGUodGFyaW5mbywgZikKCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQogICAgICAgICAgICBpZiByZWN1cnNpdmU6CiAgICAgICAgICAgICAgICBmb3IgZiBpbiBvcy5saXN0ZGlyKG5hbWUpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWRkKG9zLnBhdGguam9pbihuYW1lLCBmKSwgb3MucGF0aC5qb2luKGFyY25hbWUsIGYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaXZlLCBleGNsdWRlLCBmaWx0ZXIpCgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuYWRkZmlsZSh0YXJpbmZvKQoKICAgIGRlZiBhZGRmaWxlKHNlbGYsIHRhcmluZm8sIGZpbGVvYmo9Tm9uZSk6CiAgICAgICAgIiIiQWRkIHRoZSBUYXJJbmZvIG9iamVjdCBgdGFyaW5mbycgdG8gdGhlIGFyY2hpdmUuIElmIGBmaWxlb2JqJyBpcwogICAgICAgICAgIGdpdmVuLCB0YXJpbmZvLnNpemUgYnl0ZXMgYXJlIHJlYWQgZnJvbSBpdCBhbmQgYWRkZWQgdG8gdGhlIGFyY2hpdmUuCiAgICAgICAgICAgWW91IGNhbiBjcmVhdGUgVGFySW5mbyBvYmplY3RzIGRpcmVjdGx5LCBvciBieSB1c2luZyBnZXR0YXJpbmZvKCkuCiAgICAgICAgICAgT24gV2luZG93cyBwbGF0Zm9ybXMsIGBmaWxlb2JqJyBzaG91bGQgYWx3YXlzIGJlIG9wZW5lZCB3aXRoIG1vZGUKICAgICAgICAgICAncmInIHRvIGF2b2lkIGlycml0YXRpb24gYWJvdXQgdGhlIGZpbGUgc2l6ZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiYXciKQoKICAgICAgICB0YXJpbmZvID0gY29weS5jb3B5KHRhcmluZm8pCgogICAgICAgIGJ1ZiA9IHRhcmluZm8udG9idWYoc2VsZi5mb3JtYXQsIHNlbGYuZW5jb2RpbmcsIHNlbGYuZXJyb3JzKQogICAgICAgIHNlbGYuZmlsZW9iai53cml0ZShidWYpCiAgICAgICAgc2VsZi5vZmZzZXQgKz0gbGVuKGJ1ZikKCiAgICAgICAgIyBJZiB0aGVyZSdzIGRhdGEgdG8gZm9sbG93LCBhcHBlbmQgaXQuCiAgICAgICAgaWYgZmlsZW9iaiBpcyBub3QgTm9uZToKICAgICAgICAgICAgY29weWZpbGVvYmooZmlsZW9iaiwgc2VsZi5maWxlb2JqLCB0YXJpbmZvLnNpemUpCiAgICAgICAgICAgIGJsb2NrcywgcmVtYWluZGVyID0gZGl2bW9kKHRhcmluZm8uc2l6ZSwgQkxPQ0tTSVpFKQogICAgICAgICAgICBpZiByZW1haW5kZXIgPiAwOgogICAgICAgICAgICAgICAgc2VsZi5maWxlb2JqLndyaXRlKE5VTCAqIChCTE9DS1NJWkUgLSByZW1haW5kZXIpKQogICAgICAgICAgICAgICAgYmxvY2tzICs9IDEKICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gYmxvY2tzICogQkxPQ0tTSVpFCgogICAgICAgIHNlbGYubWVtYmVycy5hcHBlbmQodGFyaW5mbykKCiAgICBkZWYgZXh0cmFjdGFsbChzZWxmLCBwYXRoPSIuIiwgbWVtYmVycz1Ob25lKToKICAgICAgICAiIiJFeHRyYWN0IGFsbCBtZW1iZXJzIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZwogICAgICAgICAgIGRpcmVjdG9yeSBhbmQgc2V0IG93bmVyLCBtb2RpZmljYXRpb24gdGltZSBhbmQgcGVybWlzc2lvbnMgb24KICAgICAgICAgICBkaXJlY3RvcmllcyBhZnRlcndhcmRzLiBgcGF0aCcgc3BlY2lmaWVzIGEgZGlmZmVyZW50IGRpcmVjdG9yeQogICAgICAgICAgIHRvIGV4dHJhY3QgdG8uIGBtZW1iZXJzJyBpcyBvcHRpb25hbCBhbmQgbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUKICAgICAgICAgICBsaXN0IHJldHVybmVkIGJ5IGdldG1lbWJlcnMoKS4KICAgICAgICAiIiIKICAgICAgICBkaXJlY3RvcmllcyA9IFtdCgogICAgICAgIGlmIG1lbWJlcnMgaXMgTm9uZToKICAgICAgICAgICAgbWVtYmVycyA9IHNlbGYKCiAgICAgICAgZm9yIHRhcmluZm8gaW4gbWVtYmVyczoKICAgICAgICAgICAgaWYgdGFyaW5mby5pc2RpcigpOgogICAgICAgICAgICAgICAgIyBFeHRyYWN0IGRpcmVjdG9yaWVzIHdpdGggYSBzYWZlIG1vZGUuCiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5hcHBlbmQodGFyaW5mbykKICAgICAgICAgICAgICAgIHRhcmluZm8gPSBjb3B5LmNvcHkodGFyaW5mbykKICAgICAgICAgICAgICAgIHRhcmluZm8ubW9kZSA9IDA3MDAKICAgICAgICAgICAgc2VsZi5leHRyYWN0KHRhcmluZm8sIHBhdGgpCgogICAgICAgICMgUmV2ZXJzZSBzb3J0IGRpcmVjdG9yaWVzLgogICAgICAgIGRpcmVjdG9yaWVzLnNvcnQoa2V5PW9wZXJhdG9yLmF0dHJnZXR0ZXIoJ25hbWUnKSkKICAgICAgICBkaXJlY3Rvcmllcy5yZXZlcnNlKCkKCiAgICAgICAgIyBTZXQgY29ycmVjdCBvd25lciwgbXRpbWUgYW5kIGZpbGVtb2RlIG9uIGRpcmVjdG9yaWVzLgogICAgICAgIGZvciB0YXJpbmZvIGluIGRpcmVjdG9yaWVzOgogICAgICAgICAgICBkaXJwYXRoID0gb3MucGF0aC5qb2luKHBhdGgsIHRhcmluZm8ubmFtZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICAgICAgc2VsZi5jaG1vZCh0YXJpbmZvLCBkaXJwYXRoKQogICAgICAgICAgICBleGNlcHQgRXh0cmFjdEVycm9yLCBlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5lcnJvcmxldmVsID4gMToKICAgICAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUpCgogICAgZGVmIGV4dHJhY3Qoc2VsZiwgbWVtYmVyLCBwYXRoPSIiKToKICAgICAgICAiIiJFeHRyYWN0IGEgbWVtYmVyIGZyb20gdGhlIGFyY2hpdmUgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksCiAgICAgICAgICAgdXNpbmcgaXRzIGZ1bGwgbmFtZS4gSXRzIGZpbGUgaW5mb3JtYXRpb24gaXMgZXh0cmFjdGVkIGFzIGFjY3VyYXRlbHkKICAgICAgICAgICBhcyBwb3NzaWJsZS4gYG1lbWJlcicgbWF5IGJlIGEgZmlsZW5hbWUgb3IgYSBUYXJJbmZvIG9iamVjdC4gWW91IGNhbgogICAgICAgICAgIHNwZWNpZnkgYSBkaWZmZXJlbnQgZGlyZWN0b3J5IHVzaW5nIGBwYXRoJy4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygiciIpCgogICAgICAgIGlmIGlzaW5zdGFuY2UobWVtYmVyLCBiYXNlc3RyaW5nKToKICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYuZ2V0bWVtYmVyKG1lbWJlcikKICAgICAgICBlbHNlOgogICAgICAgICAgICB0YXJpbmZvID0gbWVtYmVyCgogICAgICAgICMgUHJlcGFyZSB0aGUgbGluayB0YXJnZXQgZm9yIG1ha2VsaW5rKCkuCiAgICAgICAgaWYgdGFyaW5mby5pc2xuaygpOgogICAgICAgICAgICB0YXJpbmZvLl9saW5rX3RhcmdldCA9IG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLmxpbmtuYW1lKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHRhcmluZm8sIG9zLnBhdGguam9pbihwYXRoLCB0YXJpbmZvLm5hbWUpKQogICAgICAgIGV4Y2VwdCBFbnZpcm9ubWVudEVycm9yLCBlOgogICAgICAgICAgICBpZiBzZWxmLmVycm9ybGV2ZWwgPiAwOgogICAgICAgICAgICAgICAgcmFpc2UKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIGUuZmlsZW5hbWUgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6ICVzIiAlIGUuc3RyZXJyb3IpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygxLCAidGFyZmlsZTogJXMgJXIiICUgKGUuc3RyZXJyb3IsIGUuZmlsZW5hbWUpKQogICAgICAgIGV4Y2VwdCBFeHRyYWN0RXJyb3IsIGU6CiAgICAgICAgICAgIGlmIHNlbGYuZXJyb3JsZXZlbCA+IDE6CiAgICAgICAgICAgICAgICByYWlzZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fZGJnKDEsICJ0YXJmaWxlOiAlcyIgJSBlKQoKICAgIGRlZiBleHRyYWN0ZmlsZShzZWxmLCBtZW1iZXIpOgogICAgICAgICIiIkV4dHJhY3QgYSBtZW1iZXIgZnJvbSB0aGUgYXJjaGl2ZSBhcyBhIGZpbGUgb2JqZWN0LiBgbWVtYmVyJyBtYXkgYmUKICAgICAgICAgICBhIGZpbGVuYW1lIG9yIGEgVGFySW5mbyBvYmplY3QuIElmIGBtZW1iZXInIGlzIGEgcmVndWxhciBmaWxlLCBhCiAgICAgICAgICAgZmlsZS1saWtlIG9iamVjdCBpcyByZXR1cm5lZC4gSWYgYG1lbWJlcicgaXMgYSBsaW5rLCBhIGZpbGUtbGlrZQogICAgICAgICAgIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBsaW5rJ3MgdGFyZ2V0LiBJZiBgbWVtYmVyJyBpcyBub25lIG9mCiAgICAgICAgICAgdGhlIGFib3ZlLCBOb25lIGlzIHJldHVybmVkLgogICAgICAgICAgIFRoZSBmaWxlLWxpa2Ugb2JqZWN0IGlzIHJlYWQtb25seSBhbmQgcHJvdmlkZXMgdGhlIGZvbGxvd2luZwogICAgICAgICAgIG1ldGhvZHM6IHJlYWQoKSwgcmVhZGxpbmUoKSwgcmVhZGxpbmVzKCksIHNlZWsoKSBhbmQgdGVsbCgpCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5fY2hlY2soInIiKQoKICAgICAgICBpZiBpc2luc3RhbmNlKG1lbWJlciwgYmFzZXN0cmluZyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLmdldG1lbWJlcihtZW1iZXIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGFyaW5mbyA9IG1lbWJlcgoKICAgICAgICBpZiB0YXJpbmZvLmlzcmVnKCk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpbGVvYmplY3Qoc2VsZiwgdGFyaW5mbykKCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgIyBJZiBhIG1lbWJlcidzIHR5cGUgaXMgdW5rbm93biwgaXQgaXMgdHJlYXRlZCBhcyBhCiAgICAgICAgICAgICMgcmVndWxhciBmaWxlLgogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlb2JqZWN0KHNlbGYsIHRhcmluZm8pCgogICAgICAgIGVsaWYgdGFyaW5mby5pc2xuaygpIG9yIHRhcmluZm8uaXNzeW0oKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLmZpbGVvYmosIF9TdHJlYW0pOgogICAgICAgICAgICAgICAgIyBBIHNtYWxsIGJ1dCB1Z2x5IHdvcmthcm91bmQgZm9yIHRoZSBjYXNlIHRoYXQgc29tZW9uZSB0cmllcwogICAgICAgICAgICAgICAgIyB0byBleHRyYWN0IGEgKHN5bSlsaW5rIGFzIGEgZmlsZS1vYmplY3QgZnJvbSBhIG5vbi1zZWVrYWJsZQogICAgICAgICAgICAgICAgIyBzdHJlYW0gb2YgdGFyIGJsb2Nrcy4KICAgICAgICAgICAgICAgIHJhaXNlIFN0cmVhbUVycm9yKCJjYW5ub3QgZXh0cmFjdCAoc3ltKWxpbmsgYXMgZmlsZSBvYmplY3QiKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBBIChzeW0pbGluaydzIGZpbGUgb2JqZWN0IGlzIGl0cyB0YXJnZXQncyBmaWxlIG9iamVjdC4KICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLmV4dHJhY3RmaWxlKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBJZiB0aGVyZSdzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZW1iZXIgKGRpcmVjdG9yeSwgY2hyZGV2LAogICAgICAgICAgICAjIGJsa2RldiwgZXRjLiksIHJldHVybiBOb25lIGluc3RlYWQgb2YgYSBmaWxlIG9iamVjdC4KICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICBkZWYgX2V4dHJhY3RfbWVtYmVyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIkV4dHJhY3QgdGhlIFRhckluZm8gb2JqZWN0IHRhcmluZm8gdG8gYSBwaHlzaWNhbAogICAgICAgICAgIGZpbGUgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgIyBGZXRjaCB0aGUgVGFySW5mbyBvYmplY3QgZm9yIHRoZSBnaXZlbiBuYW1lCiAgICAgICAgIyBhbmQgYnVpbGQgdGhlIGRlc3RpbmF0aW9uIHBhdGhuYW1lLCByZXBsYWNpbmcKICAgICAgICAjIGZvcndhcmQgc2xhc2hlcyB0byBwbGF0Zm9ybSBzcGVjaWZpYyBzZXBhcmF0b3JzLgogICAgICAgIHRhcmdldHBhdGggPSB0YXJnZXRwYXRoLnJzdHJpcCgiLyIpCiAgICAgICAgdGFyZ2V0cGF0aCA9IHRhcmdldHBhdGgucmVwbGFjZSgiLyIsIG9zLnNlcCkKCiAgICAgICAgIyBDcmVhdGUgYWxsIHVwcGVyIGRpcmVjdG9yaWVzLgogICAgICAgIHVwcGVyZGlycyA9IG9zLnBhdGguZGlybmFtZSh0YXJnZXRwYXRoKQogICAgICAgIGlmIHVwcGVyZGlycyBhbmQgbm90IG9zLnBhdGguZXhpc3RzKHVwcGVyZGlycyk6CiAgICAgICAgICAgICMgQ3JlYXRlIGRpcmVjdG9yaWVzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBhcmNoaXZlIHdpdGgKICAgICAgICAgICAgIyBkZWZhdWx0IHBlcm1pc3Npb25zLgogICAgICAgICAgICBvcy5tYWtlZGlycyh1cHBlcmRpcnMpCgogICAgICAgIGlmIHRhcmluZm8uaXNsbmsoKSBvciB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuX2RiZygxLCAiJXMgLT4gJXMiICUgKHRhcmluZm8ubmFtZSwgdGFyaW5mby5saW5rbmFtZSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fZGJnKDEsIHRhcmluZm8ubmFtZSkKCiAgICAgICAgaWYgdGFyaW5mby5pc3JlZygpOgogICAgICAgICAgICBzZWxmLm1ha2VmaWxlKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzZGlyKCk6CiAgICAgICAgICAgIHNlbGYubWFrZWRpcih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2ZpZm8oKToKICAgICAgICAgICAgc2VsZi5tYWtlZmlmbyh0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsaWYgdGFyaW5mby5pc2NocigpIG9yIHRhcmluZm8uaXNibGsoKToKICAgICAgICAgICAgc2VsZi5tYWtlZGV2KHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLmlzbG5rKCkgb3IgdGFyaW5mby5pc3N5bSgpOgogICAgICAgICAgICBzZWxmLm1ha2VsaW5rKHRhcmluZm8sIHRhcmdldHBhdGgpCiAgICAgICAgZWxpZiB0YXJpbmZvLnR5cGUgbm90IGluIFNVUFBPUlRFRF9UWVBFUzoKICAgICAgICAgICAgc2VsZi5tYWtldW5rbm93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKCiAgICAgICAgc2VsZi5jaG93bih0YXJpbmZvLCB0YXJnZXRwYXRoKQogICAgICAgIGlmIG5vdCB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgIHNlbGYuY2htb2QodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICAgICAgc2VsZi51dGltZSh0YXJpbmZvLCB0YXJnZXRwYXRoKQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBCZWxvdyBhcmUgdGhlIGRpZmZlcmVudCBmaWxlIG1ldGhvZHMuIFRoZXkgYXJlIGNhbGxlZCB2aWEKICAgICMgX2V4dHJhY3RfbWVtYmVyKCkgd2hlbiBleHRyYWN0KCkgaXMgY2FsbGVkLiBUaGV5IGNhbiBiZSByZXBsYWNlZCBpbiBhCiAgICAjIHN1YmNsYXNzIHRvIGltcGxlbWVudCBvdGhlciBmdW5jdGlvbmFsaXR5LgoKICAgIGRlZiBtYWtlZGlyKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBkaXJlY3RvcnkgY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIFVzZSBhIHNhZmUgbW9kZSBmb3IgdGhlIGRpcmVjdG9yeSwgdGhlIHJlYWwgbW9kZSBpcyBzZXQKICAgICAgICAgICAgIyBsYXRlciBpbiBfZXh0cmFjdF9tZW1iZXIoKS4KICAgICAgICAgICAgb3MubWtkaXIodGFyZ2V0cGF0aCwgMDcwMCkKICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgaWYgZS5lcnJubyAhPSBlcnJuby5FRVhJU1Q6CiAgICAgICAgICAgICAgICByYWlzZQoKICAgIGRlZiBtYWtlZmlsZShzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBjYWxsZWQgdGFyZ2V0cGF0aC4KICAgICAgICAiIiIKICAgICAgICBzb3VyY2UgPSBzZWxmLmV4dHJhY3RmaWxlKHRhcmluZm8pCiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIGJsdG5fb3Blbih0YXJnZXRwYXRoLCAid2IiKSBhcyB0YXJnZXQ6CiAgICAgICAgICAgICAgICBjb3B5ZmlsZW9iaihzb3VyY2UsIHRhcmdldCkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBzb3VyY2UuY2xvc2UoKQoKICAgIGRlZiBtYWtldW5rbm93bihzZWxmLCB0YXJpbmZvLCB0YXJnZXRwYXRoKToKICAgICAgICAiIiJNYWtlIGEgZmlsZSBmcm9tIGEgVGFySW5mbyBvYmplY3Qgd2l0aCBhbiB1bmtub3duIHR5cGUKICAgICAgICAgICBhdCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIHNlbGYubWFrZWZpbGUodGFyaW5mbywgdGFyZ2V0cGF0aCkKICAgICAgICBzZWxmLl9kYmcoMSwgInRhcmZpbGU6IFVua25vd24gZmlsZSB0eXBlICVyLCAiIFwKICAgICAgICAgICAgICAgICAgICAgImV4dHJhY3RlZCBhcyByZWd1bGFyIGZpbGUuIiAlIHRhcmluZm8udHlwZSkKCiAgICBkZWYgbWFrZWZpZm8oc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIGZpZm8gY2FsbGVkIHRhcmdldHBhdGguCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgIm1rZmlmbyIpOgogICAgICAgICAgICBvcy5ta2ZpZm8odGFyZ2V0cGF0aCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImZpZm8gbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgIGRlZiBtYWtlZGV2KHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIk1ha2UgYSBjaGFyYWN0ZXIgb3IgYmxvY2sgZGV2aWNlIGNhbGxlZCB0YXJnZXRwYXRoLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAibWtub2QiKSBvciBub3QgaGFzYXR0cihvcywgIm1ha2VkZXYiKToKICAgICAgICAgICAgcmFpc2UgRXh0cmFjdEVycm9yKCJzcGVjaWFsIGRldmljZXMgbm90IHN1cHBvcnRlZCBieSBzeXN0ZW0iKQoKICAgICAgICBtb2RlID0gdGFyaW5mby5tb2RlCiAgICAgICAgaWYgdGFyaW5mby5pc2JsaygpOgogICAgICAgICAgICBtb2RlIHw9IHN0YXQuU19JRkJMSwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG1vZGUgfD0gc3RhdC5TX0lGQ0hSCgogICAgICAgIG9zLm1rbm9kKHRhcmdldHBhdGgsIG1vZGUsCiAgICAgICAgICAgICAgICAgb3MubWFrZWRldih0YXJpbmZvLmRldm1ham9yLCB0YXJpbmZvLmRldm1pbm9yKSkKCiAgICBkZWYgbWFrZWxpbmsoc2VsZiwgdGFyaW5mbywgdGFyZ2V0cGF0aCk6CiAgICAgICAgIiIiTWFrZSBhIChzeW1ib2xpYykgbGluayBjYWxsZWQgdGFyZ2V0cGF0aC4gSWYgaXQgY2Fubm90IGJlIGNyZWF0ZWQKICAgICAgICAgIChwbGF0Zm9ybSBsaW1pdGF0aW9uKSwgd2UgdHJ5IHRvIG1ha2UgYSBjb3B5IG9mIHRoZSByZWZlcmVuY2VkIGZpbGUKICAgICAgICAgIGluc3RlYWQgb2YgYSBsaW5rLgogICAgICAgICIiIgogICAgICAgIGlmIGhhc2F0dHIob3MsICJzeW1saW5rIikgYW5kIGhhc2F0dHIob3MsICJsaW5rIik6CiAgICAgICAgICAgICMgRm9yIHN5c3RlbXMgdGhhdCBzdXBwb3J0IHN5bWJvbGljIGFuZCBoYXJkIGxpbmtzLgogICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmxleGlzdHModGFyZ2V0cGF0aCk6CiAgICAgICAgICAgICAgICAgICAgb3MudW5saW5rKHRhcmdldHBhdGgpCiAgICAgICAgICAgICAgICBvcy5zeW1saW5rKHRhcmluZm8ubGlua25hbWUsIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIFNlZSBleHRyYWN0KCkuCiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh0YXJpbmZvLl9saW5rX3RhcmdldCk6CiAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5sZXhpc3RzKHRhcmdldHBhdGgpOgogICAgICAgICAgICAgICAgICAgICAgICBvcy51bmxpbmsodGFyZ2V0cGF0aCkKICAgICAgICAgICAgICAgICAgICBvcy5saW5rKHRhcmluZm8uX2xpbmtfdGFyZ2V0LCB0YXJnZXRwYXRoKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9leHRyYWN0X21lbWJlcihzZWxmLl9maW5kX2xpbmtfdGFyZ2V0KHRhcmluZm8pLCB0YXJnZXRwYXRoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuX2V4dHJhY3RfbWVtYmVyKHNlbGYuX2ZpbmRfbGlua190YXJnZXQodGFyaW5mbyksIHRhcmdldHBhdGgpCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigidW5hYmxlIHRvIHJlc29sdmUgbGluayBpbnNpZGUgYXJjaGl2ZSIpCgogICAgZGVmIGNob3duKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBvd25lciBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIHB3ZCBhbmQgaGFzYXR0cihvcywgImdldGV1aWQiKSBhbmQgb3MuZ2V0ZXVpZCgpID09IDA6CiAgICAgICAgICAgICMgV2UgaGF2ZSB0byBiZSByb290IHRvIGRvIHNvLgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBnID0gZ3JwLmdldGdybmFtKHRhcmluZm8uZ25hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIGcgPSB0YXJpbmZvLmdpZAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB1ID0gcHdkLmdldHB3bmFtKHRhcmluZm8udW5hbWUpWzJdCiAgICAgICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgICAgIHUgPSB0YXJpbmZvLnVpZAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCkgYW5kIGhhc2F0dHIob3MsICJsY2hvd24iKToKICAgICAgICAgICAgICAgICAgICBvcy5sY2hvd24odGFyZ2V0cGF0aCwgdSwgZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICJvczJlbXgiOgogICAgICAgICAgICAgICAgICAgICAgICBvcy5jaG93bih0YXJnZXRwYXRoLCB1LCBnKQogICAgICAgICAgICBleGNlcHQgRW52aXJvbm1lbnRFcnJvciwgZToKICAgICAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBvd25lciIpCgogICAgZGVmIGNobW9kKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBmaWxlIHBlcm1pc3Npb25zIG9mIHRhcmdldHBhdGggYWNjb3JkaW5nIHRvIHRhcmluZm8uCiAgICAgICAgIiIiCiAgICAgICAgaWYgaGFzYXR0cihvcywgJ2NobW9kJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9zLmNobW9kKHRhcmdldHBhdGgsIHRhcmluZm8ubW9kZSkKICAgICAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBFeHRyYWN0RXJyb3IoImNvdWxkIG5vdCBjaGFuZ2UgbW9kZSIpCgogICAgZGVmIHV0aW1lKHNlbGYsIHRhcmluZm8sIHRhcmdldHBhdGgpOgogICAgICAgICIiIlNldCBtb2RpZmljYXRpb24gdGltZSBvZiB0YXJnZXRwYXRoIGFjY29yZGluZyB0byB0YXJpbmZvLgogICAgICAgICIiIgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG9zLCAndXRpbWUnKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51dGltZSh0YXJnZXRwYXRoLCAodGFyaW5mby5tdGltZSwgdGFyaW5mby5tdGltZSkpCiAgICAgICAgZXhjZXB0IEVudmlyb25tZW50RXJyb3IsIGU6CiAgICAgICAgICAgIHJhaXNlIEV4dHJhY3RFcnJvcigiY291bGQgbm90IGNoYW5nZSBtb2RpZmljYXRpb24gdGltZSIpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgbWVtYmVyIG9mIHRoZSBhcmNoaXZlIGFzIGEgVGFySW5mbyBvYmplY3QsIHdoZW4KICAgICAgICAgICBUYXJGaWxlIGlzIG9wZW5lZCBmb3IgcmVhZGluZy4gUmV0dXJuIE5vbmUgaWYgdGhlcmUgaXMgbm8gbW9yZQogICAgICAgICAgIGF2YWlsYWJsZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLl9jaGVjaygicmEiKQogICAgICAgIGlmIHNlbGYuZmlyc3RtZW1iZXIgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIG0gPSBzZWxmLmZpcnN0bWVtYmVyCiAgICAgICAgICAgIHNlbGYuZmlyc3RtZW1iZXIgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBtCgogICAgICAgICMgQWR2YW5jZSB0aGUgZmlsZSBwb2ludGVyLgogICAgICAgIGlmIHNlbGYub2Zmc2V0ICE9IHNlbGYuZmlsZW9iai50ZWxsKCk6CiAgICAgICAgICAgIHNlbGYuZmlsZW9iai5zZWVrKHNlbGYub2Zmc2V0IC0gMSkKICAgICAgICAgICAgaWYgbm90IHNlbGYuZmlsZW9iai5yZWFkKDEpOgogICAgICAgICAgICAgICAgcmFpc2UgUmVhZEVycm9yKCJ1bmV4cGVjdGVkIGVuZCBvZiBkYXRhIikKCiAgICAgICAgIyBSZWFkIHRoZSBuZXh0IGJsb2NrLgogICAgICAgIHRhcmluZm8gPSBOb25lCiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyaW5mby5mcm9tdGFyZmlsZShzZWxmKQogICAgICAgICAgICBleGNlcHQgRU9GSGVhZGVyRXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmlnbm9yZV96ZXJvczoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYmcoMiwgIjB4JVg6ICVzIiAlIChzZWxmLm9mZnNldCwgZSkpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5vZmZzZXQgKz0gQkxPQ0tTSVpFCiAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZXhjZXB0IEludmFsaWRIZWFkZXJFcnJvciwgZToKICAgICAgICAgICAgICAgIGlmIHNlbGYuaWdub3JlX3plcm9zOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2RiZygyLCAiMHglWDogJXMiICUgKHNlbGYub2Zmc2V0LCBlKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLm9mZnNldCArPSBCTE9DS1NJWkUKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgZWxpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcihzdHIoZSkpCiAgICAgICAgICAgIGV4Y2VwdCBFbXB0eUhlYWRlckVycm9yOgogICAgICAgICAgICAgICAgaWYgc2VsZi5vZmZzZXQgPT0gMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3IoImVtcHR5IGZpbGUiKQogICAgICAgICAgICBleGNlcHQgVHJ1bmNhdGVkSGVhZGVyRXJyb3IsIGU6CiAgICAgICAgICAgICAgICBpZiBzZWxmLm9mZnNldCA9PSAwOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFJlYWRFcnJvcihzdHIoZSkpCiAgICAgICAgICAgIGV4Y2VwdCBTdWJzZXF1ZW50SGVhZGVyRXJyb3IsIGU6CiAgICAgICAgICAgICAgICByYWlzZSBSZWFkRXJyb3Ioc3RyKGUpKQogICAgICAgICAgICBicmVhawoKICAgICAgICBpZiB0YXJpbmZvIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLm1lbWJlcnMuYXBwZW5kKHRhcmluZm8pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fbG9hZGVkID0gVHJ1ZQoKICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBMaXR0bGUgaGVscGVyIG1ldGhvZHM6CgogICAgZGVmIF9nZXRtZW1iZXIoc2VsZiwgbmFtZSwgdGFyaW5mbz1Ob25lLCBub3JtYWxpemU9RmFsc2UpOgogICAgICAgICIiIkZpbmQgYW4gYXJjaGl2ZSBtZW1iZXIgYnkgbmFtZSBmcm9tIGJvdHRvbSB0byB0b3AuCiAgICAgICAgICAgSWYgdGFyaW5mbyBpcyBnaXZlbiwgaXQgaXMgdXNlZCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuCiAgICAgICAgIiIiCiAgICAgICAgIyBFbnN1cmUgdGhhdCBhbGwgbWVtYmVycyBoYXZlIGJlZW4gbG9hZGVkLgogICAgICAgIG1lbWJlcnMgPSBzZWxmLmdldG1lbWJlcnMoKQoKICAgICAgICAjIExpbWl0IHRoZSBtZW1iZXIgc2VhcmNoIGxpc3QgdXAgdG8gdGFyaW5mby4KICAgICAgICBpZiB0YXJpbmZvIGlzIG5vdCBOb25lOgogICAgICAgICAgICBtZW1iZXJzID0gbWVtYmVyc1s6bWVtYmVycy5pbmRleCh0YXJpbmZvKV0KCiAgICAgICAgaWYgbm9ybWFsaXplOgogICAgICAgICAgICBuYW1lID0gb3MucGF0aC5ub3JtcGF0aChuYW1lKQoKICAgICAgICBmb3IgbWVtYmVyIGluIHJldmVyc2VkKG1lbWJlcnMpOgogICAgICAgICAgICBpZiBub3JtYWxpemU6CiAgICAgICAgICAgICAgICBtZW1iZXJfbmFtZSA9IG9zLnBhdGgubm9ybXBhdGgobWVtYmVyLm5hbWUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBtZW1iZXJfbmFtZSA9IG1lbWJlci5uYW1lCgogICAgICAgICAgICBpZiBuYW1lID09IG1lbWJlcl9uYW1lOgogICAgICAgICAgICAgICAgcmV0dXJuIG1lbWJlcgoKICAgIGRlZiBfbG9hZChzZWxmKToKICAgICAgICAiIiJSZWFkIHRocm91Z2ggdGhlIGVudGlyZSBhcmNoaXZlIGZpbGUgYW5kIGxvb2sgZm9yIHJlYWRhYmxlCiAgICAgICAgICAgbWVtYmVycy4KICAgICAgICAiIiIKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgdGFyaW5mbyBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBzZWxmLl9sb2FkZWQgPSBUcnVlCgogICAgZGVmIF9jaGVjayhzZWxmLCBtb2RlPU5vbmUpOgogICAgICAgICIiIkNoZWNrIGlmIFRhckZpbGUgaXMgc3RpbGwgb3BlbiwgYW5kIGlmIHRoZSBvcGVyYXRpb24ncyBtb2RlCiAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gVGFyRmlsZSdzIG1vZGUuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jbG9zZWQ6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoIiVzIGlzIGNsb3NlZCIgJSBzZWxmLl9fY2xhc3NfXy5fX25hbWVfXykKICAgICAgICBpZiBtb2RlIGlzIG5vdCBOb25lIGFuZCBzZWxmLm1vZGUgbm90IGluIG1vZGU6CiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoImJhZCBvcGVyYXRpb24gZm9yIG1vZGUgJXIiICUgc2VsZi5tb2RlKQoKICAgIGRlZiBfZmluZF9saW5rX3RhcmdldChzZWxmLCB0YXJpbmZvKToKICAgICAgICAiIiJGaW5kIHRoZSB0YXJnZXQgbWVtYmVyIG9mIGEgc3ltbGluayBvciBoYXJkbGluayBtZW1iZXIgaW4gdGhlCiAgICAgICAgICAgYXJjaGl2ZS4KICAgICAgICAiIiIKICAgICAgICBpZiB0YXJpbmZvLmlzc3ltKCk6CiAgICAgICAgICAgICMgQWx3YXlzIHNlYXJjaCB0aGUgZW50aXJlIGFyY2hpdmUuCiAgICAgICAgICAgIGxpbmtuYW1lID0gIi8iLmpvaW4oZmlsdGVyKE5vbmUsIChvcy5wYXRoLmRpcm5hbWUodGFyaW5mby5uYW1lKSwgdGFyaW5mby5saW5rbmFtZSkpKQogICAgICAgICAgICBsaW1pdCA9IE5vbmUKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIFNlYXJjaCB0aGUgYXJjaGl2ZSBiZWZvcmUgdGhlIGxpbmssIGJlY2F1c2UgYSBoYXJkIGxpbmsgaXMKICAgICAgICAgICAgIyBqdXN0IGEgcmVmZXJlbmNlIHRvIGFuIGFscmVhZHkgYXJjaGl2ZWQgZmlsZS4KICAgICAgICAgICAgbGlua25hbWUgPSB0YXJpbmZvLmxpbmtuYW1lCiAgICAgICAgICAgIGxpbWl0ID0gdGFyaW5mbwoKICAgICAgICBtZW1iZXIgPSBzZWxmLl9nZXRtZW1iZXIobGlua25hbWUsIHRhcmluZm89bGltaXQsIG5vcm1hbGl6ZT1UcnVlKQogICAgICAgIGlmIG1lbWJlciBpcyBOb25lOgogICAgICAgICAgICByYWlzZSBLZXlFcnJvcigibGlua25hbWUgJXIgbm90IGZvdW5kIiAlIGxpbmtuYW1lKQogICAgICAgIHJldHVybiBtZW1iZXIKCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgIiIiUHJvdmlkZSBhbiBpdGVyYXRvciBvYmplY3QuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5fbG9hZGVkOgogICAgICAgICAgICByZXR1cm4gaXRlcihzZWxmLm1lbWJlcnMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIFRhckl0ZXIoc2VsZikKCiAgICBkZWYgX2RiZyhzZWxmLCBsZXZlbCwgbXNnKToKICAgICAgICAiIiJXcml0ZSBkZWJ1Z2dpbmcgb3V0cHV0IHRvIHN5cy5zdGRlcnIuCiAgICAgICAgIiIiCiAgICAgICAgaWYgbGV2ZWwgPD0gc2VsZi5kZWJ1ZzoKICAgICAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgbXNnCgogICAgZGVmIF9fZW50ZXJfXyhzZWxmKToKICAgICAgICBzZWxmLl9jaGVjaygpCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgX19leGl0X18oc2VsZiwgdHlwZSwgdmFsdWUsIHRyYWNlYmFjayk6CiAgICAgICAgaWYgdHlwZSBpcyBOb25lOgogICAgICAgICAgICBzZWxmLmNsb3NlKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIEFuIGV4Y2VwdGlvbiBvY2N1cnJlZC4gV2UgbXVzdCBub3QgY2FsbCBjbG9zZSgpIGJlY2F1c2UKICAgICAgICAgICAgIyBpdCB3b3VsZCB0cnkgdG8gd3JpdGUgZW5kLW9mLWFyY2hpdmUgYmxvY2tzIGFuZCBwYWRkaW5nLgogICAgICAgICAgICBpZiBub3Qgc2VsZi5fZXh0ZmlsZW9iajoKICAgICAgICAgICAgICAgIHNlbGYuZmlsZW9iai5jbG9zZSgpCiAgICAgICAgICAgIHNlbGYuY2xvc2VkID0gVHJ1ZQojIGNsYXNzIFRhckZpbGUKCmNsYXNzIFRhckl0ZXI6CiAgICAiIiJJdGVyYXRvciBDbGFzcy4KCiAgICAgICBmb3IgdGFyaW5mbyBpbiBUYXJGaWxlKC4uLik6CiAgICAgICAgICAgc3VpdGUuLi4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXJmaWxlKToKICAgICAgICAiIiJDb25zdHJ1Y3QgYSBUYXJJdGVyIG9iamVjdC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLnRhcmZpbGUgPSB0YXJmaWxlCiAgICAgICAgc2VsZi5pbmRleCA9IDAKICAgIGRlZiBfX2l0ZXJfXyhzZWxmKToKICAgICAgICAiIiJSZXR1cm4gaXRlcmF0b3Igb2JqZWN0LgogICAgICAgICIiIgogICAgICAgIHJldHVybiBzZWxmCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICAiIiJSZXR1cm4gdGhlIG5leHQgaXRlbSB1c2luZyBUYXJGaWxlJ3MgbmV4dCgpIG1ldGhvZC4KICAgICAgICAgICBXaGVuIGFsbCBtZW1iZXJzIGhhdmUgYmVlbiByZWFkLCBzZXQgVGFyRmlsZSBhcyBfbG9hZGVkLgogICAgICAgICIiIgogICAgICAgICMgRml4IGZvciBTRiAjMTEwMDQyOTogVW5kZXIgcmFyZSBjaXJjdW1zdGFuY2VzIGl0IGNhbgogICAgICAgICMgaGFwcGVuIHRoYXQgZ2V0bWVtYmVycygpIGlzIGNhbGxlZCBkdXJpbmcgaXRlcmF0aW9uLAogICAgICAgICMgd2hpY2ggd2lsbCBjYXVzZSBUYXJJdGVyIHRvIHN0b3AgcHJlbWF0dXJlbHkuCgogICAgICAgIGlmIHNlbGYuaW5kZXggPT0gMCBhbmQgc2VsZi50YXJmaWxlLmZpcnN0bWVtYmVyIGlzIG5vdCBOb25lOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQogICAgICAgIGVsaWYgc2VsZi5pbmRleCA8IGxlbihzZWxmLnRhcmZpbGUubWVtYmVycyk6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhcmZpbGUubWVtYmVyc1tzZWxmLmluZGV4XQogICAgICAgIGVsaWYgbm90IHNlbGYudGFyZmlsZS5fbG9hZGVkOgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXJmaWxlLm5leHQoKQogICAgICAgICAgICBpZiBub3QgdGFyaW5mbzoKICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5fbG9hZGVkID0gVHJ1ZQogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFN0b3BJdGVyYXRpb24KICAgICAgICBzZWxmLmluZGV4ICs9IDEKICAgICAgICByZXR1cm4gdGFyaW5mbwoKIyBIZWxwZXIgY2xhc3NlcyBmb3Igc3BhcnNlIGZpbGUgc3VwcG9ydApjbGFzcyBfc2VjdGlvbjoKICAgICIiIkJhc2UgY2xhc3MgZm9yIF9kYXRhIGFuZCBfaG9sZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSk6CiAgICAgICAgc2VsZi5vZmZzZXQgPSBvZmZzZXQKICAgICAgICBzZWxmLnNpemUgPSBzaXplCiAgICBkZWYgX19jb250YWluc19fKHNlbGYsIG9mZnNldCk6CiAgICAgICAgcmV0dXJuIHNlbGYub2Zmc2V0IDw9IG9mZnNldCA8IHNlbGYub2Zmc2V0ICsgc2VsZi5zaXplCgpjbGFzcyBfZGF0YShfc2VjdGlvbik6CiAgICAiIiJSZXByZXNlbnQgYSBkYXRhIHNlY3Rpb24gaW4gYSBzcGFyc2UgZmlsZS4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9mZnNldCwgc2l6ZSwgcmVhbHBvcyk6CiAgICAgICAgX3NlY3Rpb24uX19pbml0X18oc2VsZiwgb2Zmc2V0LCBzaXplKQogICAgICAgIHNlbGYucmVhbHBvcyA9IHJlYWxwb3MKCmNsYXNzIF9ob2xlKF9zZWN0aW9uKToKICAgICIiIlJlcHJlc2VudCBhIGhvbGUgc2VjdGlvbiBpbiBhIHNwYXJzZSBmaWxlLgogICAgIiIiCiAgICBwYXNzCgpjbGFzcyBfcmluZ2J1ZmZlcihsaXN0KToKICAgICIiIlJpbmdidWZmZXIgY2xhc3Mgd2hpY2ggaW5jcmVhc2VzIHBlcmZvcm1hbmNlCiAgICAgICBvdmVyIGEgcmVndWxhciBsaXN0LgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi5pZHggPSAwCiAgICBkZWYgZmluZChzZWxmLCBvZmZzZXQpOgogICAgICAgIGlkeCA9IHNlbGYuaWR4CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgaXRlbSA9IHNlbGZbaWR4XQogICAgICAgICAgICBpZiBvZmZzZXQgaW4gaXRlbToKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGlkeCArPSAxCiAgICAgICAgICAgIGlmIGlkeCA9PSBsZW4oc2VsZik6CiAgICAgICAgICAgICAgICBpZHggPSAwCiAgICAgICAgICAgIGlmIGlkeCA9PSBzZWxmLmlkeDoKICAgICAgICAgICAgICAgICMgRW5kIG9mIEZpbGUKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgc2VsZi5pZHggPSBpZHgKICAgICAgICByZXR1cm4gaXRlbQoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIHppcGZpbGUgY29tcGF0aWJsZSBUYXJGaWxlIGNsYXNzCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVEFSX1BMQUlOID0gMCAgICAgICAgICAgIyB6aXBmaWxlLlpJUF9TVE9SRUQKVEFSX0daSVBQRUQgPSA4ICAgICAgICAgIyB6aXBmaWxlLlpJUF9ERUZMQVRFRApjbGFzcyBUYXJGaWxlQ29tcGF0OgogICAgIiIiVGFyRmlsZSBjbGFzcyBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgbW9kdWxlIHppcGZpbGUncwogICAgICAgWmlwRmlsZSBjbGFzcy4KICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIG1vZGU9InIiLCBjb21wcmVzc2lvbj1UQVJfUExBSU4pOgogICAgICAgIGZyb20gd2FybmluZ3MgaW1wb3J0IHdhcm5weTNrCiAgICAgICAgd2FybnB5M2soInRoZSBUYXJGaWxlQ29tcGF0IGNsYXNzIGhhcyBiZWVuIHJlbW92ZWQgaW4gUHl0aG9uIDMuMCIsCiAgICAgICAgICAgICAgICBzdGFja2xldmVsPTIpCiAgICAgICAgaWYgY29tcHJlc3Npb24gPT0gVEFSX1BMQUlOOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLnRhcm9wZW4oZmlsZSwgbW9kZSkKICAgICAgICBlbGlmIGNvbXByZXNzaW9uID09IFRBUl9HWklQUEVEOgogICAgICAgICAgICBzZWxmLnRhcmZpbGUgPSBUYXJGaWxlLmd6b3BlbihmaWxlLCBtb2RlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoInVua25vd24gY29tcHJlc3Npb24gY29uc3RhbnQiKQogICAgICAgIGlmIG1vZGVbMDoxXSA9PSAiciI6CiAgICAgICAgICAgIG1lbWJlcnMgPSBzZWxmLnRhcmZpbGUuZ2V0bWVtYmVycygpCiAgICAgICAgICAgIGZvciBtIGluIG1lbWJlcnM6CiAgICAgICAgICAgICAgICBtLmZpbGVuYW1lID0gbS5uYW1lCiAgICAgICAgICAgICAgICBtLmZpbGVfc2l6ZSA9IG0uc2l6ZQogICAgICAgICAgICAgICAgbS5kYXRlX3RpbWUgPSB0aW1lLmdtdGltZShtLm10aW1lKVs6Nl0KICAgIGRlZiBuYW1lbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gbWFwKGxhbWJkYSBtOiBtLm5hbWUsIHNlbGYuaW5mb2xpc3QoKSkKICAgIGRlZiBpbmZvbGlzdChzZWxmKToKICAgICAgICByZXR1cm4gZmlsdGVyKGxhbWJkYSBtOiBtLnR5cGUgaW4gUkVHVUxBUl9UWVBFUywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYudGFyZmlsZS5nZXRtZW1iZXJzKCkpCiAgICBkZWYgcHJpbnRkaXIoc2VsZik6CiAgICAgICAgc2VsZi50YXJmaWxlLmxpc3QoKQogICAgZGVmIHRlc3R6aXAoc2VsZik6CiAgICAgICAgcmV0dXJuCiAgICBkZWYgZ2V0aW5mbyhzZWxmLCBuYW1lKToKICAgICAgICByZXR1cm4gc2VsZi50YXJmaWxlLmdldG1lbWJlcihuYW1lKQogICAgZGVmIHJlYWQoc2VsZiwgbmFtZSk6CiAgICAgICAgcmV0dXJuIHNlbGYudGFyZmlsZS5leHRyYWN0ZmlsZShzZWxmLnRhcmZpbGUuZ2V0bWVtYmVyKG5hbWUpKS5yZWFkKCkKICAgIGRlZiB3cml0ZShzZWxmLCBmaWxlbmFtZSwgYXJjbmFtZT1Ob25lLCBjb21wcmVzc190eXBlPU5vbmUpOgogICAgICAgIHNlbGYudGFyZmlsZS5hZGQoZmlsZW5hbWUsIGFyY25hbWUpCiAgICBkZWYgd3JpdGVzdHIoc2VsZiwgemluZm8sIGJ5dGVzKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICAgICAgZnJvbSBTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KICAgICAgICBpbXBvcnQgY2FsZW5kYXIKICAgICAgICB0aW5mbyA9IFRhckluZm8oemluZm8uZmlsZW5hbWUpCiAgICAgICAgdGluZm8uc2l6ZSA9IGxlbihieXRlcykKICAgICAgICB0aW5mby5tdGltZSA9IGNhbGVuZGFyLnRpbWVnbSh6aW5mby5kYXRlX3RpbWUpCiAgICAgICAgc2VsZi50YXJmaWxlLmFkZGZpbGUodGluZm8sIFN0cmluZ0lPKGJ5dGVzKSkKICAgIGRlZiBjbG9zZShzZWxmKToKICAgICAgICBzZWxmLnRhcmZpbGUuY2xvc2UoKQojY2xhc3MgVGFyRmlsZUNvbXBhdAoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZXhwb3J0ZWQgZnVuY3Rpb25zCiMtLS0tLS0tLS0tLS0tLS0tLS0tLQpkZWYgaXNfdGFyZmlsZShuYW1lKToKICAgICIiIlJldHVybiBUcnVlIGlmIG5hbWUgcG9pbnRzIHRvIGEgdGFyIGFyY2hpdmUgdGhhdCB3ZQogICAgICAgYXJlIGFibGUgdG8gaGFuZGxlLCBlbHNlIHJldHVybiBGYWxzZS4KICAgICIiIgogICAgdHJ5OgogICAgICAgIHQgPSBvcGVuKG5hbWUpCiAgICAgICAgdC5jbG9zZSgpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBUYXJFcnJvcjoKICAgICAgICByZXR1cm4gRmFsc2UKCm9wZW4gPSBUYXJGaWxlLm9wZW4K