IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgYXMgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKQXQgdGhlIHNoZWxsIGNvbW1hbmQgbGluZSBvdXRzaWRlIG9mIFB5dGhvbiwgcnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cKZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlIHRoZSBuYW1lIG9mIGEgUHl0aG9uIGZ1bmN0aW9uLAptb2R1bGUsIHBhY2thZ2UsIG9yIGEgZG90dGVkIHJlZmVyZW5jZSB0byBhIGNsYXNzIG9yIGZ1bmN0aW9uIHdpdGhpbiBhCm1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgQWx0ZXJuYXRpdmVseSwgdGhlIGFyZ3VtZW50IGNhbiBiZSB0aGUKcGF0aCB0byBhIFB5dGhvbiBzb3VyY2UgZmlsZS4KCk9yLCBhdCB0aGUgc2hlbGwgcHJvbXB0LCBydW4gInB5ZG9jIC1rIDxrZXl3b3JkPiIgdG8gc2VhcmNoIGZvciBhIGtleXdvcmQKaW4gdGhlIG9uZS1saW5lIGRlc2NyaXB0aW9ucyBvZiBtb2R1bGVzLgoKT3IsIGF0IHRoZSBzaGVsbCBwcm9tcHQsIHJ1biAicHlkb2MgLXAgPHBvcnQ+IiB0byBzdGFydCBhbiBIVFRQIHNlcnZlcgpvbiBhIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbiB3ZWIgcGFnZXMuCgpPciwgYXQgdGhlIHNoZWxsIHByb21wdCwgcnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTApkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSB0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KCkluIHRoZSBQeXRob24gaW50ZXJwcmV0ZXIsIGRvICJmcm9tIHB5ZG9jIGltcG9ydCBoZWxwIiB0byBwcm92aWRlIG9ubGluZQpoZWxwLiAgQ2FsbGluZyBoZWxwKHRoaW5nKSBvbiBhIFB5dGhvbiBvYmplY3QgZG9jdW1lbnRzIHRoZSBvYmplY3QuIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgppbXBvcnQgc3lzLCBpbXAsIG9zLCBzdGF0LCByZSwgdHlwZXMsIGluc3BlY3QKZnJvbSByZXByIGltcG9ydCBSZXByCmZyb20gc3RyaW5nIGltcG9ydCBleHBhbmR0YWJzLCBmaW5kLCBqb2luLCBsb3dlciwgc3BsaXQsIHN0cmlwLCByc3RyaXAKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1vbiByb3V0aW5lcwoKZGVmIHN5bm9wc2lzKGZpbGVuYW1lLCBjYWNoZT17fSk6CiAgICAiIiJHZXQgdGhlIG9uZS1saW5lIHN1bW1hcnkgb3V0IG9mIGEgbW9kdWxlIGZpbGUuIiIiCiAgICBtdGltZSA9IG9zLnN0YXQoZmlsZW5hbWUpW3N0YXQuU1RfTVRJTUVdCiAgICBsYXN0dXBkYXRlLCByZXN1bHQgPSBjYWNoZS5nZXQoZmlsZW5hbWUsICgwLCBOb25lKSkKICAgIGlmIGxhc3R1cGRhdGUgPCBtdGltZToKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgd2hpbGUgbGluZVs6MV0gPT0gJyMnIG9yIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgIGlmIGxpbmVbLTI6XSA9PSAnXFxcbic6CiAgICAgICAgICAgIGxpbmUgPSBsaW5lWzotMl0gKyBmaWxlLnJlYWRsaW5lKCkKICAgICAgICBsaW5lID0gc3RyaXAobGluZSkKICAgICAgICBpZiBsaW5lWzozXSA9PSAnIiIiJzoKICAgICAgICAgICAgbGluZSA9IGxpbmVbMzpdCiAgICAgICAgICAgIHdoaWxlIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdCA9IHNwbGl0KGxpbmUsICciIiInKVswXQogICAgICAgIGVsc2U6IHJlc3VsdCA9IE5vbmUKICAgICAgICBmaWxlLmNsb3NlKCkKICAgICAgICBjYWNoZVtmaWxlbmFtZV0gPSAobXRpbWUsIHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQKCmRlZiBpbmRleChkaXIpOgogICAgIiIiUmV0dXJuIGEgbGlzdCBvZiAobW9kdWxlLW5hbWUsIHN5bm9wc2lzKSBwYWlycyBmb3IgYSBkaXJlY3RvcnkgdHJlZS4iIiIKICAgIHJlc3VsdHMgPSBbXQogICAgZm9yIGVudHJ5IGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZW50cnkpCiAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICByZXN1bHRzLmV4dGVuZChtYXAoCiAgICAgICAgICAgICAgICBsYW1iZGEgKG0sIHMpLCBwa2c9ZW50cnk6IChwa2cgKyAnLicgKyBtLCBzKSwgaW5kZXgocGF0aCkpKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIGVudHJ5Wy0zOl0gPT0gJy5weSc6CiAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKChlbnRyeVs6LTNdLCBzeW5vcHNpcyhwYXRoKSkpCiAgICByZXR1cm4gcmVzdWx0cwoKZGVmIHBhdGhkaXJzKCk6CiAgICAiIiJDb252ZXJ0IHN5cy5wYXRoIGludG8gYSBsaXN0IG9mIGFic29sdXRlLCBleGlzdGluZywgdW5pcXVlIHBhdGhzLiIiIgogICAgZGlycyA9IFtdCiAgICBmb3IgZGlyIGluIHN5cy5wYXRoOgogICAgICAgIGRpciA9IG9zLnBhdGguYWJzcGF0aChkaXIgb3IgJy4nKQogICAgICAgIGlmIGRpciBub3QgaW4gZGlycyBhbmQgb3MucGF0aC5pc2RpcihkaXIpOgogICAgICAgICAgICBkaXJzLmFwcGVuZChkaXIpCiAgICByZXR1cm4gZGlycwoKZGVmIGdldGRvYyhvYmplY3QpOgogICAgIiIiR2V0IHRoZSBkb2Mgc3RyaW5nIG9yIGNvbW1lbnRzIGZvciBhbiBvYmplY3QuIiIiCiAgICByZXN1bHQgPSBpbnNwZWN0LmdldGRvYyhvYmplY3QpCiAgICBpZiBub3QgcmVzdWx0OgogICAgICAgIHRyeTogcmVzdWx0ID0gaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICAgICAgZXhjZXB0OiBwYXNzCiAgICByZXR1cm4gcmVzdWx0IGFuZCByc3RyaXAocmVzdWx0KSBvciAnJwoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICBmb3Igb2xkLCBuZXcgaW4gcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgb2xkKSwgbmV3KQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIGNsZWFuaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgcmV0dXJuIHJlLnN1YignIGF0IDB4WzAtOWEtZl17NSx9PiQnLCAnPicsIHRleHQpCgpkZWYgbW9kdWxlbmFtZShwYXRoKToKICAgICIiIlJldHVybiB0aGUgUHl0aG9uIG1vZHVsZSBuYW1lIGZvciBhIGdpdmVuIHBhdGgsIG9yIE5vbmUuIiIiCiAgICBmaWxlbmFtZSA9IG9zLnBhdGguYmFzZW5hbWUocGF0aCkKICAgIGlmIGxvd2VyKGZpbGVuYW1lWy0zOl0pID09ICcucHknOgogICAgICAgIHJldHVybiBmaWxlbmFtZVs6LTNdCiAgICBlbGlmIGxvd2VyKGZpbGVuYW1lWy00Ol0pID09ICcucHljJzoKICAgICAgICByZXR1cm4gZmlsZW5hbWVbOi00XQogICAgZWxpZiBsb3dlcihmaWxlbmFtZVstMTE6XSkgPT0gJ21vZHVsZS5zbyc6CiAgICAgICAgcmV0dXJuIGZpbGVuYW1lWzotMTFdCiAgICBlbGlmIGxvd2VyKGZpbGVuYW1lWy0xMzpdKSA9PSAnbW9kdWxlLnNvLjEnOgogICAgICAgIHJldHVybiBmaWxlbmFtZVs6LTEzXQoKY2xhc3MgRG9jSW1wb3J0RXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkNsYXNzIGZvciBlcnJvcnMgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIGV0eXBlLCBldmFsdWUpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXR5cGUgPSBldHlwZQogICAgICAgIHNlbGYuZXZhbHVlID0gZXZhbHVlCiAgICAgICAgaWYgdHlwZShldHlwZSkgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBldHlwZSA9IGV0eXBlLl9fbmFtZV9fCiAgICAgICAgc2VsZi5hcmdzID0gJyVzOiAlcycgJSAoZXR5cGUsIGV2YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKHBhdGgsIHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSkKICAgIGZpbGUuY2xvc2UoKQogICAgcmV0dXJuIG1vZHVsZQoKZGVmIGlzcGFja2FnZShwYXRoKToKICAgICIiIkd1ZXNzIHdoZXRoZXIgYSBwYXRoIHJlZmVycyB0byBhIHBhY2thZ2UgZGlyZWN0b3J5LiIiIgogICAgaWYgb3MucGF0aC5pc2RpcihwYXRoKToKICAgICAgICBpbml0ID0gb3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXy5weScpCiAgICAgICAgaW5pdGMgPSBvcy5wYXRoLmpvaW4ocGF0aCwgJ19faW5pdF9fLnB5YycpCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUoaW5pdCkgb3Igb3MucGF0aC5pc2ZpbGUoaW5pdGMpOgogICAgICAgICAgICByZXR1cm4gMQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCAqYXJncyk6CiAgICAgICAgIiIiR2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBmb3IgYW4gb2JqZWN0LiIiIgogICAgICAgIGFyZ3MgPSAob2JqZWN0LCkgKyBhcmdzCiAgICAgICAgaWYgaW5zcGVjdC5pc21vZHVsZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Ntb2R1bGUsIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc2NsYXNzKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2NsYXNzLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbWV0aG9kLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2J1aWx0aW4sIGFyZ3MpCiAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKG9iamVjdCk6IHJldHVybiBhcHBseShzZWxmLmRvY2Z1bmN0aW9uLCBhcmdzKQogICAgICAgIHJhaXNlIFR5cGVFcnJvciwgImRvbid0IGtub3cgaG93IHRvIGRvY3VtZW50IG9iamVjdHMgb2YgdHlwZSAiICsgXAogICAgICAgICAgICB0eXBlKG9iamVjdCkuX19uYW1lX18KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gNTAKCiAgICBkZWYgZXNjYXBlKHNlbGYsIHRleHQpOgogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnJicsICcmYW1wOycpLCAoJzwnLCAnJmx0OycpLCAoJz4nLCAnJmd0OycpKQoKICAgIGRlZiByZXByKHNlbGYsIG9iamVjdCk6CiAgICAgICAgcmVzdWx0ID0gUmVwci5yZXByKHNlbGYsIG9iamVjdCkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShjbGVhbmlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKSkKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShjcmFtKHgsIHNlbGYubWF4c3RyaW5nKSkKICAgICAgICByZXR1cm4gcmUuc3ViKHInKChcXFtcXGFiZm5ydHZdfFxceC4ufFxcdS4uLi4pKyknLAogICAgICAgICAgICAgICAgICAgICAgcic8Zm9udCBjb2xvcj0iI2MwNDBjMCI+XDE8L2ZvbnQ+JywgcmVwcih0ZXh0KSkKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gY3JhbShjbGVhbmlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmVzY2FwZSgnPCVzIGluc3RhbmNlPicgJSB4Ll9fY2xhc3NfXy5fX25hbWVfXykKCiAgICByZXByX3VuaWNvZGUgPSByZXByX3N0cmluZwoKY2xhc3MgSFRNTERvYyhEb2MpOgogICAgIiIiRm9ybWF0dGVyIGNsYXNzIGZvciBIVE1MIGRvY3VtZW50YXRpb24uIiIiCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhUTUwgZm9ybWF0dGluZyB1dGlsaXRpZXMKCiAgICBfcmVwcl9pbnN0YW5jZSA9IEhUTUxSZXByKCkKICAgIHJlcHIgPSBfcmVwcl9pbnN0YW5jZS5yZXByCiAgICBlc2NhcGUgPSBfcmVwcl9pbnN0YW5jZS5lc2NhcGUKCiAgICBkZWYgcHJlZm9ybWF0KHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBsaXRlcmFsIHByZWZvcm1hdHRlZCB0ZXh0LiIiIgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShleHBhbmR0YWJzKHRleHQpKQogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnXG5cbicsICdcbiBcbicpLCAoJ1xuXG4nLCAnXG4gXG4nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJyAnLCAnJm5ic3A7JyksICgnXG4nLCAnPGJyPlxuJykpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwoKICAgICAgICBmb3IgY29sIGluIHJhbmdlKGNvbHMpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIlZCUlIiB2YWxpZ249dG9wPicgJSAoMTAwL2NvbHMpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKHJvd3MqY29sLCByb3dzKmNvbCtyb3dzKToKICAgICAgICAgICAgICAgIGlmIGkgPCBsZW4obGlzdCk6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgZm9ybWF0KGxpc3RbaV0pICsgJzxicj4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8L3RkPicKICAgICAgICByZXR1cm4gJzx0YWJsZSB3aWR0aD0iMTAwJSUiPjx0cj4lczwvdHI+PC90YWJsZT4nICUgcmVzdWx0CgogICAgZGVmIGhlYWRpbmcoc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgZXh0cmFzPScnKToKICAgICAgICAiIiJGb3JtYXQgYSBwYWdlIGhlYWRpbmcuIiIiCiAgICAgICAgcmV0dXJuICIiIgo8cD48dGFibGUgd2lkdGg9IjEwMCUlIiBjZWxsc3BhY2luZz0wIGNlbGxwYWRkaW5nPTAgYm9yZGVyPTA+Cjx0ciBiZ2NvbG9yPSIlcyI+PHRkIGNvbHNwYW49MyB2YWxpZ249Ym90dG9tPjxzbWFsbD48c21hbGw+PGJyPjwvc21hbGw+PC9zbWFsbAo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4mbmJzcDslczwvZm9udD48L3RkCj48dGQgYWxpZ249cmlnaHQgdmFsaWduPWJvdHRvbQo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4mbmJzcDslczwvZm9udD48L3RkPjwvdHI+PC90YWJsZT4KICAgICIiIiAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlLCBmZ2NvbCwgZXh0cmFzKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGNvbnRlbnRzLCB3aWR0aD0yMCwKICAgICAgICAgICAgICAgIHByZWx1ZGU9JycsIG1hcmdpbmFsaWE9Tm9uZSwgZ2FwPScmbmJzcDsmbmJzcDsmbmJzcDsnKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBoZWFkaW5nLiIiIgogICAgICAgIGlmIG1hcmdpbmFsaWEgaXMgTm9uZToKICAgICAgICAgICAgbWFyZ2luYWxpYSA9ICcmbmJzcDsnICogd2lkdGgKICAgICAgICByZXN1bHQgPSAiIiIKPHA+PHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0wIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPjx0ZCBjb2xzcGFuPTMgdmFsaWduPWJvdHRvbT48c21hbGw+PHNtYWxsPjxicj48L3NtYWxsPjwvc21hbGwKPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+Jm5ic3A7JXM8L2ZvbnQ+PC90ZD48L3RyPgogICAgIiIiICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUpCiAgICAgICAgaWYgcHJlbHVkZToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgIiIiCjx0cj48dGQgYmdjb2xvcj0iJXMiPiVzPC90ZD4KPHRkIGJnY29sb3I9IiVzIiBjb2xzcGFuPTI+JXM8L3RkPjwvdHI+CiAgICAiIiIgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIGJnY29sLCBwcmVsdWRlKQogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICIiIgo8dHI+PHRkIGJnY29sb3I9IiVzIj4lczwvdGQ+PHRkPiVzPC90ZD4KICAgICIiIiAlIChiZ2NvbCwgbWFyZ2luYWxpYSwgZ2FwKQoKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIxMDAlJSI+JXM8L3RkPjwvdHI+PC90YWJsZT4nICUgY29udGVudHMKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGJpZ3NlY3Rpb24oc2VsZiwgdGl0bGUsICphcmdzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBiaWcgaGVhZGluZy4iIiIKICAgICAgICB0aXRsZSA9ICc8YmlnPjxzdHJvbmc+JXM8L3N0cm9uZz48L2JpZz4nICUgdGl0bGUKICAgICAgICByZXR1cm4gYXBwbHkoc2VsZi5zZWN0aW9uLCAodGl0bGUsKSArIGFyZ3MpCgogICAgZGVmIGZvb3RlcihzZWxmKToKICAgICAgICByZXR1cm4gIiIiCjx0YWJsZSB3aWR0aD0iMTAwJSI+PHRyPjx0ZCBhbGlnbj1yaWdodD4KPGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHNtYWxsPjxzbWFsbD5nZW5lcmF0ZWQgd2l0aAo8c3Ryb25nPmh0bWxkb2M8L3N0cm9uZz4gYnkgS2EtUGluZyBZZWU8L2E+PC9zbWFsbD48L3NtYWxsPjwvZm9udD4KPC90ZD48L3RyPjwvdGFibGU+CiAgICAiIiIKCiAgICBkZWYgbmFtZWxpbmsoc2VsZiwgbmFtZSwgKmRpY3RzKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYW4gaWRlbnRpZmllciwgZ2l2ZW4gbmFtZS10by1VUkwgbWFwcGluZ3MuIiIiCiAgICAgICAgZm9yIGRpY3QgaW4gZGljdHM6CiAgICAgICAgICAgIGlmIGRpY3QuaGFzX2tleShuYW1lKToKICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAoZGljdFtuYW1lXSwgbmFtZSkKICAgICAgICByZXR1cm4gbmFtZQoKICAgIGRlZiBjbGFzc2xpbmsoc2VsZiwgb2JqZWN0LCBtb2RuYW1lLCAqZGljdHMpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIGNsYXNzLiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBpZiBvYmplY3QuX19tb2R1bGVfXyAhPSBtb2RuYW1lOgogICAgICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICAgICAgZm9yIGRpY3QgaW4gZGljdHM6CiAgICAgICAgICAgIGlmIGRpY3QuaGFzX2tleShvYmplY3QpOgogICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlIChkaWN0W29iamVjdF0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgbW9kdWxlbGluayhzZWxmLCBvYmplY3QpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIG1vZHVsZS4iIiIKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAob2JqZWN0Ll9fbmFtZV9fLCBvYmplY3QuX19uYW1lX18pCgogICAgZGVmIG1vZHBrZ2xpbmsoc2VsZiwgKG5hbWUsIHBhdGgsIGlzcGFja2FnZSwgc2hhZG93ZWQpKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUgb3IgcGFja2FnZSB0byBkaXNwbGF5IGluIGFuIGluZGV4LiIiIgogICAgICAgIGlmIHNoYWRvd2VkOgogICAgICAgICAgICByZXR1cm4gJzxmb250IGNvbG9yPSIjOTA5MDkwIj4lczwvZm9udD4nICUgbmFtZQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIHVybCA9ICclcy4lcy5odG1sJyAlIChwYXRoLCBuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHVybCA9ICclcy5odG1sJyAlIG5hbWUKICAgICAgICBpZiBpc3BhY2thZ2U6CiAgICAgICAgICAgIHRleHQgPSAnPHN0cm9uZz4lczwvc3Ryb25nPiZuYnNwOyhwYWNrYWdlKScgJSBuYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGV4dCA9IG5hbWUKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgdGV4dCkKCiAgICBkZWYgbWFya3VwKHNlbGYsIHRleHQsIGVzY2FwZT1Ob25lLCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSk6CiAgICAgICAgIiIiTWFyayB1cCBzb21lIHBsYWluIHRleHQsIGdpdmVuIGEgY29udGV4dCBvZiBzeW1ib2xzIHRvIGxvb2sgZm9yLgogICAgICAgIEVhY2ggY29udGV4dCBkaWN0aW9uYXJ5IG1hcHMgb2JqZWN0IG5hbWVzIHRvIGFuY2hvciBuYW1lcy4iIiIKICAgICAgICBlc2NhcGUgPSBlc2NhcGUgb3Igc2VsZi5lc2NhcGUKICAgICAgICByZXN1bHRzID0gW10KICAgICAgICBoZXJlID0gMAogICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHInXGIoKChodHRwfGZ0cCk6Ly9cUytbXHcvXSl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInKFJGQ1stIF0/KFxkKykpfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJyhzZWxmXC4pPyhcdyspKVxiJykKICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICBtYXRjaCA9IHBhdHRlcm4uc2VhcmNoKHRleHQsIGhlcmUpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDogYnJlYWsKICAgICAgICAgICAgc3RhcnQsIGVuZCA9IG1hdGNoLnNwYW4oKQogICAgICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOnN0YXJ0XSkpCgogICAgICAgICAgICBhbGwsIHVybCwgc2NoZW1lLCByZmMsIHJmY251bSwgc2VsZmRvdCwgbmFtZSA9IG1hdGNoLmdyb3VwcygpCiAgICAgICAgICAgIGlmIHVybDoKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZSh1cmwpKSkKICAgICAgICAgICAgZWxpZiByZmM6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjJXMudHh0JyAlIHJmY251bQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKHJmYykpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgdGV4dFtlbmQ6ZW5kKzFdID09ICcoJzoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgICAgIGVsaWYgc2VsZmRvdDoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnc2VsZi48c3Ryb25nPiVzPC9zdHJvbmc+JyAlIG5hbWUpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKHNlbGYubmFtZWxpbmsobmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgIGhlcmUgPSBlbmQKICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOl0pKQogICAgICAgIHJldHVybiBqb2luKHJlc3VsdHMsICcnKQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGRvY3RyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgY2xhc3Nlcz17fSwgcGFyZW50PU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBmb3IgYSBjbGFzcyB0cmVlIGFzIGdpdmVuIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPGR0Pjxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzbWFsbD4nCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmNsYXNzbGluayhjLCBtb2RuYW1lLCBjbGFzc2VzKQogICAgICAgICAgICAgICAgaWYgYmFzZXMgYW5kIGJhc2VzICE9IChwYXJlbnQsKToKICAgICAgICAgICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgICAgICAgICBmb3IgYmFzZSBpbiBiYXNlczoKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgbW9kbmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJygnICsgam9pbihwYXJlbnRzLCAnLCAnKSArICcpJwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJ1xuPC9zbWFsbD48L2ZvbnQ+PC9kdD4nCiAgICAgICAgICAgIGVsaWYgdHlwZShlbnRyeSkgaXMgdHlwZShbXSk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBcCiAgICAgICAgICAgICAgICAgICAgJzxkZD5cbiVzPC9kZD5cbicgJSBzZWxmLmRvY3RyZWUoZW50cnksIG1vZG5hbWUsIGNsYXNzZXMsIGMpCiAgICAgICAgcmV0dXJuICc8ZGw+XG4lczwvZGw+XG4nICUgcmVzdWx0CgogICAgZGVmIGRvY21vZHVsZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSBvYmplY3QuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgaGVhZCA9ICc8YnI+PGJpZz48YmlnPjxzdHJvbmc+Jm5ic3A7JXM8L3N0cm9uZz48L2JpZz48L2JpZz4nICUgbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IGluc3BlY3QuZ2V0c291cmNlZmlsZShvYmplY3QpCiAgICAgICAgICAgIGZpbGVsaW5rID0gJzxhIGhyZWY9ImZpbGU6JXMiPiVzPC9hPicgJSAoZmlsZSwgZmlsZSkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlbGluayA9ICcoYnVpbHQtaW4pJwogICAgICAgIGluZm8gPSBbXQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIGluZm8uYXBwZW5kKCd2ZXJzaW9uOiAlcycgJSBzZWxmLmVzY2FwZSh2ZXJzaW9uKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIGluZm8uYXBwZW5kKHNlbGYuZXNjYXBlKHN0cihvYmplY3QuX19kYXRlX18pKSkKICAgICAgICBpZiBpbmZvOgogICAgICAgICAgICBoZWFkID0gaGVhZCArICcgKCVzKScgJSBqb2luKGluZm8sICcsICcpCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5oZWFkaW5nKAogICAgICAgICAgICBoZWFkLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgJzxhIGhyZWY9Ii4iPmluZGV4PC9hPjxicj4nICsgZmlsZWxpbmspCgogICAgICAgIHNlY29uZCA9IGxhbWJkYSBsaXN0OiBsaXN0WzFdCiAgICAgICAgbW9kdWxlcyA9IG1hcChzZWNvbmQsIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtb2R1bGUpKQoKICAgICAgICBjbGFzc2VzLCBjZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFt2YWx1ZV0gPSAnIycgKyBrZXkKICAgICAgICBmdW5jcywgZmRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICAgICAgZmRpY3Rba2V5XSA9ICcjLScgKyBrZXkKICAgICAgICAgICAgICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih2YWx1ZSk6IGZkaWN0W3ZhbHVlXSA9IGZkaWN0W2tleV0KICAgICAgICBmb3IgYyBpbiBjbGFzc2VzOgogICAgICAgICAgICBmb3IgYmFzZSBpbiBjLl9fYmFzZXNfXzoKICAgICAgICAgICAgICAgIGtleSwgbW9kbmFtZSA9IGJhc2UuX19uYW1lX18sIGJhc2UuX19tb2R1bGVfXwogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSBuYW1lIGFuZCBzeXMubW9kdWxlcy5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIG1vZHVsZSA9IHN5cy5tb2R1bGVzW21vZG5hbWVdCiAgICAgICAgICAgICAgICAgICAgaWYgaGFzYXR0cihtb2R1bGUsIGtleSkgYW5kIGdldGF0dHIobW9kdWxlLCBrZXkpIGlzIGJhc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBjZGljdC5oYXNfa2V5KGtleSk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbYmFzZV0gPSBtb2RuYW1lICsgJy5odG1sIycgKyBrZXkKICAgICAgICBjb25zdGFudHMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzY29uc3RhbnQpOgogICAgICAgICAgICBpZiBrZXlbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgIGNvbnN0YW50cy5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZkaWN0LCBjZGljdCkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHA+PHNtYWxsPiVzPC9zbWFsbD48L3A+XG4nICUgZG9jCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIG1vZG5hbWVzID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihvYmplY3QuX19wYXRoX19bMF0pOgogICAgICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChtb2RuYW1lLCBuYW1lLCAwLCAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgbW9kbmFtZXMuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChmaWxlLCBuYW1lLCAxLCAwKSkKICAgICAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ1BhY2thZ2UgQ29udGVudHMnLCAnI2ZmZmZmZicsICcjYWE1NWNjJywgY29udGVudHMpCgogICAgICAgIGVsaWYgbW9kdWxlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHVsZXMsIHNlbGYubW9kdWxlbGluaykKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ01vZHVsZXMnLCAnI2ZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLmRvY3RyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2VzLCAxKSwgbmFtZSwgY2RpY3QpCiAgICAgICAgICAgIGZvciBpdGVtIGluIGNsYXNzZXM6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtLCBmZGljdCwgY2RpY3QpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDbGFzc2VzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKQogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBpdGVtIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoaXRlbSwgZmRpY3QsIGNkaWN0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnRnVuY3Rpb25zJywgJyNmZmZmZmYnLCAnI2VlYWE3NycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjb25zdGFudHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY29uc3RhbnRzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArICgnPGJyPjxzdHJvbmc+JXM8L3N0cm9uZz4gPSAlcycgJQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5LCBzZWxmLnJlcHIodmFsdWUpKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NvbnN0YW50cycsICcjZmZmZmZmJywgJyM1NWFhNTUnLCBjb250ZW50cykKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2F1dGhvcl9fJyk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tYXJrdXAoc3RyKG9iamVjdC5fX2F1dGhvcl9fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdBdXRob3InLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgY29udGVudHMpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDcmVkaXRzJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgZnVuY3M9e30sIGNsYXNzZXM9e30pOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCiAgICAgICAgY29udGVudHMgPSAnJwoKICAgICAgICBtZXRob2RzLCBtZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtZXRob2QpOgogICAgICAgICAgICBtZXRob2RzLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgbWRpY3Rba2V5XSA9IG1kaWN0W3ZhbHVlXSA9ICcjJyArIG5hbWUgKyAnLScgKyBrZXkKICAgICAgICBmb3IgaXRlbSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudCgKICAgICAgICAgICAgICAgIGl0ZW0sIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCwgbmFtZSkKCiAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPmNsYXNzIDxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlIChuYW1lLCBuYW1lKQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBvYmplY3QuX19tb2R1bGVfXywgY2xhc3NlcykpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCkKICAgICAgICBpZiBkb2M6IGRvYyA9ICc8c21hbGw+PHR0PicgKyBkb2MgKyAnPGJyPiZuYnNwOzwvdHQ+PC9zbWFsbD4nCiAgICAgICAgcmV0dXJuIHNlbGYuc2VjdGlvbih0aXRsZSwgJyMwMDAwMDAnLCAnI2ZmYzhkOCcsIGNvbnRlbnRzLCAxMCwgZG9jKQoKICAgIGRlZiBkb2NtZXRob2Qoc2VsZiwgb2JqZWN0LCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSwgY2xuYW1lPScnKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJldHVybiBzZWxmLmRvY3VtZW50KAogICAgICAgICAgICBvYmplY3QuaW1fZnVuYywgZnVuY3MsIGNsYXNzZXMsIG1ldGhvZHMsIGNsbmFtZSkKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiAoJzxzbWFsbD48Zm9udCBjb2xvcj0iIzkwOTA5MCI+PSVzPC9mb250Pjwvc21hbGw+JyAlCiAgICAgICAgICAgICAgICBzZWxmLnJlcHIob2JqZWN0KSkKCiAgICBkZWYgZG9jZnVuY3Rpb24oc2VsZiwgb2JqZWN0LCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSwgY2xuYW1lPScnKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvYmplY3QuIiIiCiAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMsIGZvcm1hdHZhbHVlPXNlbGYuZm9ybWF0dmFsdWUpCgogICAgICAgIGlmIG9iamVjdC5fX25hbWVfXyA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICBkZWNsID0gJzxlbT5sYW1iZGE8L2VtPiAnICsgYXJnc3BlY1sxOi0xXQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGFuY2hvciA9IGNsbmFtZSArICctJyArIG9iamVjdC5fX25hbWVfXwogICAgICAgICAgICBkZWNsID0gJzxhIG5hbWU9IiVzIlxuPjxzdHJvbmc+JXM8L3N0cm9uZz4lczwvYT5cbicgJSAoCiAgICAgICAgICAgICAgICBhbmNob3IsIG9iamVjdC5fX25hbWVfXywgYXJnc3BlYykKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3MsIGNsYXNzZXMsIG1ldGhvZHMpCiAgICAgICAgZG9jID0gcmVwbGFjZShkb2MsICgnPGJyPlxuJywgJzwvdHQ+PC9zbWFsbFxuPjxkZD48c21hbGw+PHR0PicpKQogICAgICAgIGRvYyA9IGRvYyBhbmQgJzx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgIHJldHVybiAnPGRsPjxkdD4lczxkZD48c21hbGw+JXM8L3NtYWxsPjwvZGw+JyAlIChkZWNsLCBkb2MpCgogICAgZGVmIGRvY2J1aWx0aW4oc2VsZiwgb2JqZWN0LCAqZXh0cmFzKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBidWlsdC1pbiBmdW5jdGlvbi4iIiIKICAgICAgICByZXR1cm4gJzxkbD48ZHQ+PHN0cm9uZz4lczwvc3Ryb25nPiguLi4pPC9kbD4nICUgb2JqZWN0Ll9fbmFtZV9fCgogICAgZGVmIHBhZ2Uoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIGEgY29tcGxldGUgSFRNTCBwYWdlIG9mIGRvY3VtZW50YXRpb24gZm9yIGFuIG9iamVjdC4iIiIKICAgICAgICByZXR1cm4gJycnPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPgo8Ym9keSBiZ2NvbG9yPSIjZmZmZmZmIj4KJXMKPC9ib2R5PjwvaHRtbD4KJycnICUgKGRlc2NyaWJlKG9iamVjdCksIHNlbGYuZG9jdW1lbnQob2JqZWN0KSkKCiAgICBkZWYgaW5kZXgoc2VsZiwgZGlyLCBzaGFkb3dlZD1Ob25lKToKICAgICAgICAiIiJHZW5lcmF0ZSBhbiBIVE1MIGluZGV4IGZvciBhIGRpcmVjdG9yeSBvZiBtb2R1bGVzLiIiIgogICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgIGlmIHNoYWRvd2VkIGlzIE5vbmU6IHNoYWRvd2VkID0ge30KICAgICAgICBzZWVuID0ge30KICAgICAgICBmaWxlcyA9IG9zLmxpc3RkaXIoZGlyKQoKICAgICAgICBkZWYgZm91bmQobmFtZSwgaXNwYWNrYWdlLAogICAgICAgICAgICAgICAgICBtb2Rwa2dzPW1vZHBrZ3MsIHNoYWRvd2VkPXNoYWRvd2VkLCBzZWVuPXNlZW4pOgogICAgICAgICAgICBpZiBub3Qgc2Vlbi5oYXNfa2V5KG5hbWUpOgogICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG5hbWUsICcnLCBpc3BhY2thZ2UsIHNoYWRvd2VkLmhhc19rZXkobmFtZSkpKQogICAgICAgICAgICAgICAgc2VlbltuYW1lXSA9IDEKICAgICAgICAgICAgICAgIHNoYWRvd2VkW25hbWVdID0gMQoKICAgICAgICAjIFBhY2thZ2Ugc3BhbS9fX2luaXRfXy5weSB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgbW9kdWxlIHNwYW0ucHkuCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6IGZvdW5kKGZpbGUsIDEpCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBmaWxlWzoxXSAhPSAnXycgYW5kIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWU6IGZvdW5kKG1vZG5hbWUsIDApCgogICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICByZXR1cm4gc2VsZi5iaWdzZWN0aW9uKGRpciwgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yCgpjbGFzcyBUZXh0UmVwcihSZXByKToKICAgICIiIkNsYXNzIGZvciBzYWZlbHkgbWFraW5nIGEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiBhIFB5dGhvbiBvYmplY3QuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgUmVwci5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYubWF4bGlzdCA9IHNlbGYubWF4dHVwbGUgPSBzZWxmLm1heGRpY3QgPSAxMAogICAgICAgIHNlbGYubWF4c3RyaW5nID0gc2VsZi5tYXhvdGhlciA9IDUwCgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gY3JhbShjbGVhbmlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKQoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKGNsZWFuaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuICc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fCgpjbGFzcyBUZXh0RG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIHRleHQgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gVGV4dFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKCiAgICBkZWYgYm9sZChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgYSBzdHJpbmcgaW4gYm9sZCBieSBvdmVyc3RyaWtpbmcuIiIiCiAgICAgICAgcmV0dXJuIGpvaW4obWFwKGxhbWJkYSBjaDogY2ggKyAnXGInICsgY2gsIHRleHQpLCAnJykKCiAgICBkZWYgaW5kZW50KHNlbGYsIHRleHQsIHByZWZpeD0nICAgICcpOgogICAgICAgICIiIkluZGVudCB0ZXh0IGJ5IHByZXBlbmRpbmcgYSBnaXZlbiBwcmVmaXggdG8gZWFjaCBsaW5lLiIiIgogICAgICAgIGlmIG5vdCB0ZXh0OiByZXR1cm4gJycKICAgICAgICBsaW5lcyA9IHNwbGl0KHRleHQsICdcbicpCiAgICAgICAgbGluZXMgPSBtYXAobGFtYmRhIGxpbmUsIHByZWZpeD1wcmVmaXg6IHByZWZpeCArIGxpbmUsIGxpbmVzKQogICAgICAgIGlmIGxpbmVzOiBsaW5lc1stMV0gPSByc3RyaXAobGluZXNbLTFdKQogICAgICAgIHJldHVybiBqb2luKGxpbmVzLCAnXG4nKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgZ2l2ZW4gaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gc2VsZi5ib2xkKHRpdGxlKSArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoY29udGVudHMpKSArICdcblxuJwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGRvY3RyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgcGFyZW50PU5vbmUsIHByZWZpeD0nJyk6CiAgICAgICAgIiIiUmVuZGVyIGluIHRleHQgYSBjbGFzcyB0cmVlIGFzIHJldHVybmVkIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjbCwgYmFzZXMgPSBlbnRyeQogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgcHJlZml4ICsgY2xhc3NuYW1lKGNsLCBtb2RuYW1lKQogICAgICAgICAgICAgICAgaWYgYmFzZXMgYW5kIGJhc2VzICE9IChwYXJlbnQsKToKICAgICAgICAgICAgICAgICAgICBwYXJlbnRzID0gbWFwKGxhbWJkYSBjbCwgbT1tb2RuYW1lOiBjbGFzc25hbWUoY2wsIG0pLCBiYXNlcykKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnXG4nCiAgICAgICAgICAgIGVsaWYgdHlwZShlbnRyeSkgaXMgdHlwZShbXSk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmRvY3RyZWUoCiAgICAgICAgICAgICAgICAgICAgZW50cnksIG1vZG5hbWUsIGNsLCBwcmVmaXggKyAnICAgICcpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIHJlc3VsdCA9ICcnCgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBsaW5lcyA9IHNwbGl0KHN0cmlwKGdldGRvYyhvYmplY3QpKSwgJ1xuJykKICAgICAgICBpZiBsZW4obGluZXMpID09IDE6CiAgICAgICAgICAgIGlmIGxpbmVzWzBdOiBuYW1lID0gbmFtZSArICcgLSAnICsgbGluZXNbMF0KICAgICAgICAgICAgbGluZXMgPSBbXQogICAgICAgIGVsaWYgbGVuKGxpbmVzKSA+PSAyIGFuZCBub3QgcnN0cmlwKGxpbmVzWzFdKToKICAgICAgICAgICAgaWYgbGluZXNbMF06IG5hbWUgPSBuYW1lICsgJyAtICcgKyBsaW5lc1swXQogICAgICAgICAgICBsaW5lcyA9IGxpbmVzWzI6XQogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignTkFNRScsIG5hbWUpCiAgICAgICAgdHJ5OiBmaWxlID0gaW5zcGVjdC5nZXRmaWxlKG9iamVjdCkgIyBYWFggb3IgZ2V0c291cmNlZmlsZT8KICAgICAgICBleGNlcHQgVHlwZUVycm9yOiBmaWxlID0gTm9uZQogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRklMRScsIGZpbGUgb3IgJyhidWlsdC1pbiknKQogICAgICAgIGlmIGxpbmVzOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RFU0NSSVBUSU9OJywgam9pbihsaW5lcywgJ1xuJykpCgogICAgICAgIGNsYXNzZXMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCh2YWx1ZSkKICAgICAgICBmdW5jcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc3JvdXRpbmUpOgogICAgICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih2YWx1ZSkgb3IgaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGZ1bmNzLmFwcGVuZCh2YWx1ZSkKICAgICAgICBjb25zdGFudHMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzY29uc3RhbnQpOgogICAgICAgICAgICBpZiBrZXlbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgIGNvbnN0YW50cy5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBpZiBmaWxlWzoxXSAhPSAnXyc6CiAgICAgICAgICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihvYmplY3QuX19wYXRoX19bMF0sIGZpbGUpCiAgICAgICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgICAgICBpZiBtb2RuYW1lIGFuZCBtb2RuYW1lIG5vdCBpbiBtb2Rwa2dzOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZChtb2RuYW1lKQogICAgICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZChmaWxlICsgJyAocGFja2FnZSknKQogICAgICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oCiAgICAgICAgICAgICAgICAnUEFDS0FHRSBDT05URU5UUycsIGpvaW4obW9kcGtncywgJ1xuJykpCgogICAgICAgIGlmIGNsYXNzZXM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5kb2N0cmVlKAogICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRjbGFzc3RyZWUoY2xhc3NlcywgMSksIG9iamVjdC5fX25hbWVfXykgKyAnXG4nCiAgICAgICAgICAgIGZvciBpdGVtIGluIGNsYXNzZXM6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtKSArICdcbicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDTEFTU0VTJywgY29udGVudHMpCgogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBpdGVtIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoaXRlbSkgKyAnXG4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRlVOQ1RJT05TJywgY29udGVudHMpCgogICAgICAgIGlmIGNvbnN0YW50czoKICAgICAgICAgICAgY29udGVudHMgPSAnJwogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjb25zdGFudHM6CiAgICAgICAgICAgICAgICBsaW5lID0ga2V5ICsgJyA9ICcgKyBzZWxmLnJlcHIodmFsdWUpCiAgICAgICAgICAgICAgICBjaG9wID0gNzAgLSBsZW4obGluZSkKICAgICAgICAgICAgICAgIGxpbmUgPSBzZWxmLmJvbGQoa2V5KSArICcgPSAnICsgc2VsZi5yZXByKHZhbHVlKQogICAgICAgICAgICAgICAgaWYgY2hvcCA8IDA6IGxpbmUgPSBsaW5lWzpjaG9wXSArICcuLi4nCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgbGluZSArICdcbicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDT05TVEFOVFMnLCBjb250ZW50cykKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3ZlcnNpb25fXycpOgogICAgICAgICAgICB2ZXJzaW9uID0gc3RyKG9iamVjdC5fX3ZlcnNpb25fXykKICAgICAgICAgICAgaWYgdmVyc2lvbls6MTFdID09ICckUmV2aXNpb24kJzoKICAgICAgICAgICAgICAgIHZlcnNpb24gPSB2ZXJzaW9uWzExOi0xXQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ1ZFUlNJT04nLCB2ZXJzaW9uKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdEQVRFJywgc3RyKG9iamVjdC5fX2RhdGVfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2F1dGhvcl9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQVVUSE9SJywgc3RyKG9iamVjdC5fX2F1dGhvcl9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ1JFRElUUycsIHN0cihvYmplY3QuX19jcmVkaXRzX18pKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jY2xhc3Moc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwoKICAgICAgICB0aXRsZSA9ICdjbGFzcyAnICsgc2VsZi5ib2xkKG5hbWUpCiAgICAgICAgaWYgYmFzZXM6CiAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobGFtYmRhIGMsIG09b2JqZWN0Ll9fbW9kdWxlX186IGNsYXNzbmFtZShjLCBtKSwgYmFzZXMpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCgogICAgICAgIGRvYyA9IGdldGRvYyhvYmplY3QpCiAgICAgICAgY29udGVudHMgPSBkb2MgYW5kIGRvYyArICdcbicKICAgICAgICBtZXRob2RzID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21ldGhvZCkpCiAgICAgICAgZm9yIGl0ZW0gaW4gbWV0aG9kczoKICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArICdcbicgKyBzZWxmLmRvY3VtZW50KGl0ZW0pCgogICAgICAgIGlmIG5vdCBjb250ZW50czogcmV0dXJuIHRpdGxlICsgJ1xuJwogICAgICAgIHJldHVybiB0aXRsZSArICdcbicgKyBzZWxmLmluZGVudChyc3RyaXAoY29udGVudHMpLCAnIHwgICcpICsgJ1xuJwoKICAgIGRlZiBkb2NtZXRob2Qoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJldHVybiBzZWxmLmRvY3VtZW50KG9iamVjdC5pbV9mdW5jKQoKICAgIGRlZiBmb3JtYXR2YWx1ZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIkZvcm1hdCBhbiBhcmd1bWVudCBkZWZhdWx0IHZhbHVlIGFzIHRleHQuIiIiCiAgICAgICAgcmV0dXJuICc9JyArIHNlbGYucmVwcihvYmplY3QpCgogICAgZGVmIGRvY2Z1bmN0aW9uKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZnVuY3Rpb24gb2JqZWN0LiIiIgogICAgICAgIHRyeToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBhcmdzcGVjID0gJyguLi4pJwoKICAgICAgICBpZiBvYmplY3QuX19uYW1lX18gPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgZGVjbCA9ICc8bGFtYmRhPiAnICsgYXJnc3BlY1sxOi0xXQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGRlY2wgPSBzZWxmLmJvbGQob2JqZWN0Ll9fbmFtZV9fKSArIGFyZ3NwZWMKICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KQogICAgICAgIGlmIGRvYzoKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nICsgcnN0cmlwKHNlbGYuaW5kZW50KGRvYykpICsgJ1xuJwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBkZWNsICsgJ1xuJwoKICAgIGRlZiBkb2NidWlsdGluKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgYnVpbHQtaW4gZnVuY3Rpb24gb2JqZWN0LiIiIgogICAgICAgIHJldHVybiAoc2VsZi5ib2xkKG9iamVjdC5fX25hbWVfXykgKyAnKC4uLilcbicgKwogICAgICAgICAgICAgICAgcnN0cmlwKHNlbGYuaW5kZW50KG9iamVjdC5fX2RvY19fKSkgKyAnXG4nKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdXNlciBpbnRlcmZhY2VzCgpkZWYgcGFnZXIodGV4dCk6CiAgICAiIiJUaGUgZmlyc3QgdGltZSB0aGlzIGlzIGNhbGxlZCwgZGV0ZXJtaW5lIHdoYXQga2luZCBvZiBwYWdlciB0byB1c2UuIiIiCiAgICBnbG9iYWwgcGFnZXIKICAgIHBhZ2VyID0gZ2V0cGFnZXIoKQogICAgcGFnZXIodGV4dCkKCmRlZiBnZXRwYWdlcigpOgogICAgIiIiRGVjaWRlIHdoYXQgbWV0aG9kIHRvIHVzZSBmb3IgcGFnaW5nIHRocm91Z2ggdGV4dC4iIiIKICAgIGlmIHR5cGUoc3lzLnN0ZG91dCkgaXMgbm90IHR5cGVzLkZpbGVUeXBlOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBub3Qgc3lzLnN0ZGluLmlzYXR0eSgpIG9yIG5vdCBzeXMuc3Rkb3V0LmlzYXR0eSgpOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBvcy5lbnZpcm9uLmhhc19rZXkoJ1BBR0VSJyk6CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiBwaXBlcGFnZXIoYSwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgIGlmIHN5cy5wbGF0Zm9ybSBpbiBbJ3dpbicsICd3aW4zMicsICdudCddOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogdGVtcGZpbGVwYWdlcihhLCAnbW9yZScpCiAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbGVzcyAyPi9kZXYvbnVsbCcpID09IDA6CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiBwaXBlcGFnZXIoYSwgJ2xlc3MnKQoKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgZmlsZW5hbWUgPSB0ZW1wZmlsZS5ta3RlbXAoKQogICAgb3BlbihmaWxlbmFtZSwgJ3cnKS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ21vcmUgJXMnICUgZmlsZW5hbWUpID09IDA6CiAgICAgICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogcGlwZXBhZ2VyKHRleHQsICdtb3JlJykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gdHR5cGFnZXIKICAgIGZpbmFsbHk6CiAgICAgICAgb3MudW5saW5rKGZpbGVuYW1lKQoKZGVmIHBpcGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgZmVlZGluZyBpdCB0byBhbm90aGVyIHByb2dyYW0uIiIiCiAgICBwaXBlID0gb3MucG9wZW4oY21kLCAndycpCiAgICB0cnk6CiAgICAgICAgcGlwZS53cml0ZSh0ZXh0KQogICAgICAgIHBpcGUuY2xvc2UoKQogICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgIyBJZ25vcmUgYnJva2VuIHBpcGVzIGNhdXNlZCBieSBxdWl0dGluZyB0aGUgcGFnZXIgcHJvZ3JhbS4KICAgICAgICBwYXNzCgpkZWYgdGVtcGZpbGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgaW52b2tpbmcgYSBwcm9ncmFtIG9uIGEgdGVtcG9yYXJ5IGZpbGUuIiIiCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBmaWxlLndyaXRlKHRleHQpCiAgICBmaWxlLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBvcy5zeXN0ZW0oY21kICsgJyAnICsgZmlsZW5hbWUpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwbGFpbih0ZXh0KToKICAgICIiIlJlbW92ZSBib2xkZmFjZSBmb3JtYXR0aW5nIGZyb20gdGV4dC4iIiIKICAgIHJldHVybiByZS5zdWIoJy5cYicsICcnLCB0ZXh0KQoKZGVmIHR0eXBhZ2VyKHRleHQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgb24gYSB0ZXh0IHRlcm1pbmFsLiIiIgogICAgbGluZXMgPSBzcGxpdChwbGFpbih0ZXh0KSwgJ1xuJykKICAgIHRyeToKICAgICAgICBpbXBvcnQgdHR5CiAgICAgICAgZmQgPSBzeXMuc3RkaW4uZmlsZW5vKCkKICAgICAgICBvbGQgPSB0dHkudGNnZXRhdHRyKGZkKQogICAgICAgIHR0eS5zZXRjYnJlYWsoZmQpCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWQoMSkKICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgICAgICB0dHkgPSBOb25lCiAgICAgICAgZ2V0Y2hhciA9IGxhbWJkYTogc3lzLnN0ZGluLnJlYWRsaW5lKClbOi0xXVs6MV0KCiAgICB0cnk6CiAgICAgICAgciA9IGluYyA9IG9zLmVudmlyb24uZ2V0KCdMSU5FUycsIDI1KSAtIDEKICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKGpvaW4obGluZXNbOmluY10sICdcbicpICsgJ1xuJykKICAgICAgICB3aGlsZSBsaW5lc1tyOl06CiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJy0tIG1vcmUgLS0nKQogICAgICAgICAgICBzeXMuc3Rkb3V0LmZsdXNoKCkKICAgICAgICAgICAgYyA9IGdldGNoYXIoKQoKICAgICAgICAgICAgaWYgYyBpbiBbJ3EnLCAnUSddOgogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXHIgICAgICAgICAgXHInKQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZWxpZiBjIGluIFsnXHInLCAnXG4nXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJyArIGxpbmVzW3JdICsgJ1xuJykKICAgICAgICAgICAgICAgIHIgPSByICsgMQogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgaWYgYyBpbiBbJ2InLCAnQicsICdceDFiJ106CiAgICAgICAgICAgICAgICByID0gciAtIGluYyAtIGluYwogICAgICAgICAgICAgICAgaWYgciA8IDA6IHIgPSAwCiAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xuJyArIGpvaW4obGluZXNbcjpyK2luY10sICdcbicpICsgJ1xuJykKICAgICAgICAgICAgciA9IHIgKyBpbmMKCiAgICBmaW5hbGx5OgogICAgICAgIGlmIHR0eToKICAgICAgICAgICAgdHR5LnRjc2V0YXR0cihmZCwgdHR5LlRDU0FGTFVTSCwgb2xkKQoKZGVmIHBsYWlucGFnZXIodGV4dCk6CiAgICAiIiJTaW1wbHkgcHJpbnQgdW5mb3JtYXR0ZWQgdGV4dC4gIFRoaXMgaXMgdGhlIHVsdGltYXRlIGZhbGxiYWNrLiIiIgogICAgc3lzLnN0ZG91dC53cml0ZShwbGFpbih0ZXh0KSkKCmRlZiBkZXNjcmliZSh0aGluZyk6CiAgICAiIiJQcm9kdWNlIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGdpdmVuIGtpbmQgb2YgdGhpbmcuIiIiCiAgICBpZiBpbnNwZWN0LmlzbW9kdWxlKHRoaW5nKToKICAgICAgICBpZiB0aGluZy5fX25hbWVfXyBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CiAgICAgICAgICAgIHJldHVybiAnYnVpbHQtaW4gbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGlmIGhhc2F0dHIodGhpbmcsICdfX3BhdGhfXycpOgogICAgICAgICAgICByZXR1cm4gJ3BhY2thZ2UgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuICdtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdidWlsdC1pbiBmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNjbGFzcyh0aGluZyk6CiAgICAgICAgcmV0dXJuICdjbGFzcyAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNtZXRob2QodGhpbmcpOgogICAgICAgIHJldHVybiAnbWV0aG9kICcgKyB0aGluZy5fX25hbWVfXwogICAgcmV0dXJuIHJlcHIodGhpbmcpCgpkZWYgbG9jYXRlKHBhdGgpOgogICAgIiIiTG9jYXRlIGFuIG9iamVjdCBieSBuYW1lIChvciBkb3R0ZWQgcGF0aCksIGltcG9ydGluZyBhcyBuZWNlc3NhcnkuIiIiCiAgICBpZiBub3QgcGF0aDogIyBzcGVjaWFsIGNhc2U6IGltcC5maW5kX21vZHVsZSgnJykgc3RyYW5nZWx5IHN1Y2NlZWRzCiAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUKICAgIGlmIHR5cGUocGF0aCkgaXMgbm90IHR5cGVzLlN0cmluZ1R5cGU6CiAgICAgICAgcmV0dXJuIE5vbmUsIHBhdGgKICAgIGlmIGhhc2F0dHIoX19idWlsdGluc19fLCBwYXRoKToKICAgICAgICByZXR1cm4gTm9uZSwgZ2V0YXR0cihfX2J1aWx0aW5zX18sIHBhdGgpCiAgICBwYXJ0cyA9IHNwbGl0KHBhdGgsICcuJykKICAgIG4gPSAxCiAgICB3aGlsZSBuIDw9IGxlbihwYXJ0cyk6CiAgICAgICAgcGF0aCA9IGpvaW4ocGFydHNbOm5dLCAnLicpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBtb2R1bGUgPSBfX2ltcG9ydF9fKHBhdGgpCiAgICAgICAgICAgIG1vZHVsZSA9IHJlbG9hZChtb2R1bGUpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAjIERpZCB0aGUgZXJyb3Igb2NjdXIgYmVmb3JlIG9yIGFmdGVyIHdlIGZvdW5kIHRoZSBtb2R1bGU/CiAgICAgICAgICAgIGlmIHN5cy5tb2R1bGVzLmhhc19rZXkocGF0aCk6CiAgICAgICAgICAgICAgICBmaWxlbmFtZSA9IHN5cy5tb2R1bGVzW3BhdGhdLl9fZmlsZV9fCiAgICAgICAgICAgIGVsaWYgc3lzLmV4Y190eXBlIGlzIFN5bnRheEVycm9yOgogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBzeXMuZXhjX3ZhbHVlLmZpbGVuYW1lCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIG1vZHVsZSBub3QgZm91bmQsIHNvIHN0b3AgbG9va2luZwogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgIyBlcnJvciBvY2N1cnJlZCBpbiB0aGUgaW1wb3J0ZWQgbW9kdWxlLCBzbyByZXBvcnQgaXQKICAgICAgICAgICAgcmFpc2UgRG9jSW1wb3J0RXJyb3IoZmlsZW5hbWUsIHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHggPSBtb2R1bGUKICAgICAgICAgICAgZm9yIHAgaW4gcGFydHNbMTpdOgogICAgICAgICAgICAgICAgeCA9IGdldGF0dHIoeCwgcCkKICAgICAgICAgICAgcmV0dXJuIGpvaW4ocGFydHNbOi0xXSwgJy4nKSwgeAogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgbiA9IG4gKyAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICByZXR1cm4gTm9uZSwgTm9uZQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaW50ZXJhY3RpdmUgaW50ZXJwcmV0ZXIgaW50ZXJmYWNlCgp0ZXh0ID0gVGV4dERvYygpCmh0bWwgPSBIVE1MRG9jKCkKCmRlZiBkb2ModGhpbmcpOgogICAgIiIiRGlzcGxheSBkb2N1bWVudGF0aW9uIG9uIGFuIG9iamVjdCAoZm9yIGludGVyYWN0aXZlIHVzZSkuIiIiCiAgICBpZiB0eXBlKHRoaW5nKSBpcyB0eXBlKCIiKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhdGgsIHggPSBsb2NhdGUodGhpbmcpCiAgICAgICAgZXhjZXB0IERvY0ltcG9ydEVycm9yLCB2YWx1ZToKICAgICAgICAgICAgcHJpbnQgJ3Byb2JsZW0gaW4gJXMgLSAlcycgJSAodmFsdWUuZmlsZW5hbWUsIHZhbHVlLmFyZ3MpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHg6CiAgICAgICAgICAgIHRoaW5nID0geAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50ICdjb3VsZCBub3QgZmluZCBvciBpbXBvcnQgJXMnICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCgogICAgZGVzYyA9IGRlc2NyaWJlKHRoaW5nKQogICAgbW9kdWxlID0gaW5zcGVjdC5nZXRtb2R1bGUodGhpbmcpCiAgICBpZiBtb2R1bGUgYW5kIG1vZHVsZSBpcyBub3QgdGhpbmc6CiAgICAgICAgZGVzYyA9IGRlc2MgKyAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcignSGVscCBvbiAlczpcblxuJyAlIGRlc2MgKyB0ZXh0LmRvY3VtZW50KHRoaW5nKSkKCmRlZiB3cml0ZWRvY3MocGF0aCwgcGtncGF0aD0nJyk6CiAgICBpZiBvcy5wYXRoLmlzZGlyKHBhdGgpOgogICAgICAgIGRpciA9IHBhdGgKICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKHBhdGgpOgogICAgICAgICAgICAgICAgd3JpdGVkb2NzKHBhdGgsIGZpbGUgKyAnLicgKyBwa2dwYXRoKQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgICAgIHdyaXRlZG9jcyhwYXRoLCBwa2dwYXRoKQogICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCk6CiAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUocGF0aCkKICAgICAgICBpZiBtb2RuYW1lOgogICAgICAgICAgICB3cml0ZWRvYyhwa2dwYXRoICsgbW9kbmFtZSkKCmRlZiB3cml0ZWRvYyhrZXkpOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICBwYXRoLCBvYmplY3QgPSBsb2NhdGUoa2V5KQogICAgaWYgb2JqZWN0OgogICAgICAgIGZpbGUgPSBvcGVuKGtleSArICcuaHRtbCcsICd3JykKICAgICAgICBmaWxlLndyaXRlKGh0bWwucGFnZShvYmplY3QpKQogICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgIHByaW50ICd3cm90ZScsIGtleSArICcuaHRtbCcKCmNsYXNzIEhlbHBlcjoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIiIiVG8gZ2V0IGhlbHAgb24gYSBQeXRob24gb2JqZWN0LCBjYWxsIGhlbHAob2JqZWN0KS4KVG8gZ2V0IGhlbHAgb24gYSBtb2R1bGUgb3IgcGFja2FnZSwgZWl0aGVyIGltcG9ydCBpdCBiZWZvcmUgY2FsbGluZwpoZWxwKG1vZHVsZSkgb3IgY2FsbCBoZWxwKCdtb2R1bGVuYW1lJykuIiIiCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzKToKICAgICAgICBpZiBhcmdzOgogICAgICAgICAgICBkb2MoYXJnc1swXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCByZXByKHNlbGYpCgpoZWxwID0gSGVscGVyKCkKCmRlZiBtYW4oa2V5KToKICAgICIiIkRpc3BsYXkgZG9jdW1lbnRhdGlvbiBvbiBhbiBvYmplY3QgaW4gYSBmb3JtIHNpbWlsYXIgdG8gbWFuKDEpLiIiIgogICAgcGF0aCwgb2JqZWN0ID0gbG9jYXRlKGtleSkKICAgIGlmIG9iamVjdDoKICAgICAgICB0aXRsZSA9ICdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAnICsgZGVzY3JpYmUob2JqZWN0KQogICAgICAgIGlmIHBhdGg6IHRpdGxlID0gdGl0bGUgKyAnIGluICcgKyBwYXRoCiAgICAgICAgcGFnZXIoJ1xuJyArIHRpdGxlICsgJ1xuXG4nICsgdGV4dC5kb2N1bWVudChvYmplY3QpKQogICAgICAgIGZvdW5kID0gMQogICAgZWxzZToKICAgICAgICBwcmludCAnY291bGQgbm90IGZpbmQgb3IgaW1wb3J0ICVzJyAlIHJlcHIoa2V5KQoKZGVmIGFwcm9wb3Moa2V5KToKICAgICIiIlByaW50IGFsbCB0aGUgb25lLWxpbmUgbW9kdWxlIHN1bW1hcmllcyB0aGF0IGNvbnRhaW4gYSBzdWJzdHJpbmcuIiIiCiAgICBrZXkgPSBsb3dlcihrZXkpCiAgICBmb3IgbW9kdWxlIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICBkZXNjID0gX19pbXBvcnRfXyhtb2R1bGUpLl9fZG9jX18gb3IgJycKICAgICAgICBkZXNjID0gc3BsaXQoZGVzYywgJ1xuJylbMF0KICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZHVsZSArICcgJyArIGRlc2MpLCBrZXkpID49IDA6CiAgICAgICAgICAgIHByaW50IG1vZHVsZSwgJy0nLCBkZXNjIG9yICcobm8gZGVzY3JpcHRpb24pJwogICAgbW9kdWxlcyA9IFtdCiAgICBmb3IgZGlyIGluIHBhdGhkaXJzKCk6CiAgICAgICAgZm9yIG1vZHVsZSwgZGVzYyBpbiBpbmRleChkaXIpOgogICAgICAgICAgICBkZXNjID0gZGVzYyBvciAnJwogICAgICAgICAgICBpZiBtb2R1bGUgbm90IGluIG1vZHVsZXM6CiAgICAgICAgICAgICAgICBtb2R1bGVzLmFwcGVuZChtb2R1bGUpCiAgICAgICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZHVsZSArICcgJyArIGRlc2MpLCBrZXkpID49IDA6CiAgICAgICAgICAgICAgICAgICAgZGVzYyA9IGRlc2Mgb3IgJyhubyBkZXNjcmlwdGlvbiknCiAgICAgICAgICAgICAgICAgICAgaWYgbW9kdWxlWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50IG1vZHVsZVs6LTldLCAnKHBhY2thZ2UpIC0nLCBkZXNjCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgbW9kdWxlLCAnLScsIGRlc2MKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHdlYiBicm93c2VyIGludGVyZmFjZQoKZGVmIHNlcnZlKGFkZHJlc3MsIGNhbGxiYWNrPU5vbmUpOgogICAgaW1wb3J0IEJhc2VIVFRQU2VydmVyLCBtaW1ldG9vbHMKCiAgICAjIFBhdGNoIHVwIG1pbWV0b29scy5NZXNzYWdlIHNvIGl0IGRvZXNuJ3QgYnJlYWsgaWYgcmZjODIyIGlzIHJlbG9hZGVkLgogICAgY2xhc3MgTWVzc2FnZShtaW1ldG9vbHMuTWVzc2FnZSk6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZT0xKToKICAgICAgICAgICAgTWVzc2FnZSA9IHNlbGYuX19jbGFzc19fCiAgICAgICAgICAgIE1lc3NhZ2UuX19iYXNlc19fWzBdLl9fYmFzZXNfX1swXS5fX2luaXRfXyhzZWxmLCBmcCwgc2Vla2FibGUpCiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmdoZWFkZXIgPSBzZWxmLmdldGhlYWRlcignY29udGVudC10cmFuc2Zlci1lbmNvZGluZycpCiAgICAgICAgICAgIHNlbGYudHlwZWhlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXR5cGUnKQogICAgICAgICAgICBzZWxmLnBhcnNldHlwZSgpCiAgICAgICAgICAgIHNlbGYucGFyc2VwbGlzdCgpCgogICAgY2xhc3MgRG9jSGFuZGxlcihCYXNlSFRUUFNlcnZlci5CYXNlSFRUUFJlcXVlc3RIYW5kbGVyKToKICAgICAgICBkZWYgc2VuZF9kb2N1bWVudChzZWxmLCB0aXRsZSwgY29udGVudHMpOgogICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJykKICAgICAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgICAgIHNlbGYud2ZpbGUud3JpdGUoCicnJzwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPjx0aXRsZT5QeXRob246ICVzPC90aXRsZT48Ym9keSBiZ2NvbG9yPSIjZmZmZmZmIj4nJycgJSB0aXRsZSkKICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZShjb250ZW50cykKICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZSgnPC9ib2R5PjwvaHRtbD4nKQoKICAgICAgICBkZWYgZG9fR0VUKHNlbGYpOgogICAgICAgICAgICBwYXRoID0gc2VsZi5wYXRoCiAgICAgICAgICAgIGlmIHBhdGhbLTU6XSA9PSAnLmh0bWwnOiBwYXRoID0gcGF0aFs6LTVdCiAgICAgICAgICAgIGlmIHBhdGhbOjFdID09ICcvJzogcGF0aCA9IHBhdGhbMTpdCiAgICAgICAgICAgIGlmIHBhdGggYW5kIHBhdGggIT0gJy4nOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHAsIHggPSBsb2NhdGUocGF0aCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KHBhdGgsIGh0bWwuZXNjYXBlKAogICAgICAgICAgICAgICAgICAgICAgICAncHJvYmxlbSB3aXRoICVzIC0gJXMnICUgKHZhbHVlLmZpbGVuYW1lLCB2YWx1ZS5hcmdzKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBpZiB4OgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChkZXNjcmliZSh4KSwgaHRtbC5kb2N1bWVudCh4KSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KHBhdGgsCidUaGVyZSBpcyBubyBQeXRob24gbW9kdWxlIG9yIG9iamVjdCBuYW1lZCAiJXMiLicgJSBwYXRoKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaGVhZGluZyA9IGh0bWwuaGVhZGluZygKICAgICAgICAgICAgICAgICAgICAnPGJyPjxiaWc+PGJpZz48c3Ryb25nPiZuYnNwOycKICAgICAgICAgICAgICAgICAgICAnUHl0aG9uOiBJbmRleCBvZiBNb2R1bGVzJwogICAgICAgICAgICAgICAgICAgICc8L3N0cm9uZz48L2JpZz48L2JpZz4nLAogICAgICAgICAgICAgICAgICAgICcjZmZmZmZmJywgJyM3Nzk5ZWUnKQogICAgICAgICAgICAgICAgYnVpbHRpbnMgPSBbXQogICAgICAgICAgICAgICAgZm9yIG5hbWUgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICAgICAgICAgIGJ1aWx0aW5zLmFwcGVuZCgnPGEgaHJlZj0iJXMuaHRtbCI+JXM8L2E+JyAlIChuYW1lLCBuYW1lKSkKICAgICAgICAgICAgICAgIGluZGljZXMgPSBbJzxwPkJ1aWx0LWluIG1vZHVsZXM6ICcgKyBqb2luKGJ1aWx0aW5zLCAnLCAnKV0KICAgICAgICAgICAgICAgIHNlZW4gPSB7fQogICAgICAgICAgICAgICAgZm9yIGRpciBpbiBwYXRoZGlycygpOgogICAgICAgICAgICAgICAgICAgIGluZGljZXMuYXBwZW5kKGh0bWwuaW5kZXgoZGlyLCBzZWVuKSkKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudCgnSW5kZXggb2YgTW9kdWxlcycsIGhlYWRpbmcgKyBqb2luKGluZGljZXMpKQoKICAgICAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgKmFyZ3MpOiBwYXNzCgogICAgY2xhc3MgRG9jU2VydmVyKEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBhZGRyZXNzLCBjYWxsYmFjayk6CiAgICAgICAgICAgIHNlbGYuY2FsbGJhY2sgPSBjYWxsYmFjawogICAgICAgICAgICBzZWxmLmJhc2UuX19pbml0X18oc2VsZiwgYWRkcmVzcywgc2VsZi5oYW5kbGVyKQoKICAgICAgICBkZWYgc2VydmVyX2FjdGl2YXRlKHNlbGYpOgogICAgICAgICAgICBzZWxmLmJhc2Uuc2VydmVyX2FjdGl2YXRlKHNlbGYpCiAgICAgICAgICAgIGlmIHNlbGYuY2FsbGJhY2s6IHNlbGYuY2FsbGJhY2soKQoKICAgIERvY1NlcnZlci5iYXNlID0gQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcgogICAgRG9jU2VydmVyLmhhbmRsZXIgPSBEb2NIYW5kbGVyCiAgICBEb2NIYW5kbGVyLk1lc3NhZ2VDbGFzcyA9IE1lc3NhZ2UKICAgIHRyeToKICAgICAgICBEb2NTZXJ2ZXIoYWRkcmVzcywgY2FsbGJhY2spLnNlcnZlX2ZvcmV2ZXIoKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHByaW50ICdzZXJ2ZXIgc3RvcHBlZCcKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29tbWFuZC1saW5lIGludGVyZmFjZQoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIGltcG9ydCBnZXRvcHQKICAgIGNsYXNzIEJhZFVzYWdlOiBwYXNzCgogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KHN5cy5hcmd2WzE6XSwgJ2s6cDp3JykKICAgICAgICB3cml0aW5nID0gMAoKICAgICAgICBmb3Igb3B0LCB2YWwgaW4gb3B0czoKICAgICAgICAgICAgaWYgb3B0ID09ICctayc6CiAgICAgICAgICAgICAgICBhcHJvcG9zKGxvd2VyKHZhbCkpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBpZiBvcHQgPT0gJy1wJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwb3J0ID0gaW50KHZhbCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEJhZFVzYWdlCiAgICAgICAgICAgICAgICBkZWYgcmVhZHkocG9ydD1wb3J0KToKICAgICAgICAgICAgICAgICAgICBwcmludCAnc2VydmVyIHJlYWR5IGF0IGh0dHA6Ly8xMjcuMC4wLjE6JWQvJyAlIHBvcnQKICAgICAgICAgICAgICAgIHNlcnZlKCgnMTI3LjAuMC4xJywgcG9ydCksIHJlYWR5KQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgaWYgb3B0ID09ICctdyc6CiAgICAgICAgICAgICAgICBpZiBub3QgYXJnczogcmFpc2UgQmFkVXNhZ2UKICAgICAgICAgICAgICAgIHdyaXRpbmcgPSAxCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgYXJnczoKICAgICAgICAgICAgICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKGFyZyk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBpbXBvcnRmaWxlKGFyZykKICAgICAgICAgICAgICAgICAgICAgICAgaWYgd3JpdGluZzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIoYXJnKTogd3JpdGVkb2NzKGFyZykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6IHdyaXRlZG9jKGFyZykKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZTogbWFuKGFyZykKICAgICAgICAgICAgICAgICAgICBleGNlcHQgRG9jSW1wb3J0RXJyb3IsIHZhbHVlOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludCAncHJvYmxlbSBpbiAlcyAtICVzJyAlICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmZpbGVuYW1lLCB2YWx1ZS5hcmdzKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtIGluIFsnbWFjJywgJ3dpbicsICd3aW4zMicsICdudCddOgogICAgICAgICAgICAgICAgICAgICMgR1VJIHBsYXRmb3JtcyB3aXRoIHRocmVhZGluZwogICAgICAgICAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgICAgICAgICByZWFkeSA9IHRocmVhZGluZy5FdmVudCgpCiAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyA9ICgnMTI3LjAuMC4xJywgMTIzNDYpCiAgICAgICAgICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCgKICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0PXNlcnZlLCBhcmdzPShhZGRyZXNzLCByZWFkeS5zZXQpKS5zdGFydCgpCiAgICAgICAgICAgICAgICAgICAgcmVhZHkud2FpdCgpCiAgICAgICAgICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgICAgICAgICB3ZWJicm93c2VyLm9wZW4oJ2h0dHA6Ly8xMjcuMC4wLjE6MTIzNDYvJykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQmFkVXNhZ2UKCiAgICBleGNlcHQgKGdldG9wdC5lcnJvciwgQmFkVXNhZ2UpOgogICAgICAgIHByaW50ICIiIiVzIDxuYW1lPiAuLi4KICAgIFNob3cgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuCiAgICA8bmFtZT4gbWF5IGJlIHRoZSBuYW1lIG9mIGEgUHl0aG9uIGZ1bmN0aW9uLCBtb2R1bGUsIG9yIHBhY2thZ2UsCiAgICBvciBhIGRvdHRlZCByZWZlcmVuY2UgdG8gYSBjbGFzcyBvciBmdW5jdGlvbiB3aXRoaW4gYSBtb2R1bGUgb3IKICAgIG1vZHVsZSBpbiBhIHBhY2thZ2UsIG9yIHRoZSBmaWxlbmFtZSBvZiBhIFB5dGhvbiBtb2R1bGUgdG8gaW1wb3J0LgoKJXMgLWsgPGtleXdvcmQ+CiAgICBTZWFyY2ggZm9yIGEga2V5d29yZCBpbiB0aGUgc3lub3BzaXMgbGluZXMgb2YgYWxsIG1vZHVsZXMuCgolcyAtcCA8cG9ydD4KICAgIFN0YXJ0IGFuIEhUVFAgc2VydmVyIG9uIHRoZSBnaXZlbiBwb3J0IG9uIHRoZSBsb2NhbCBtYWNoaW5lLgoKJXMgLXcgPG1vZHVsZT4gLi4uCiAgICBXcml0ZSBvdXQgdGhlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgdG8gYSBmaWxlLgoKJXMgLXcgPG1vZHVsZWRpcj4KICAgIFdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhbGwgbW9kdWxlcyBpbiB0aGUgdHJlZQogICAgdW5kZXIgYSBnaXZlbiBkaXJlY3RvcnkgdG8gZmlsZXMgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LgoiIiIgJSAoKHN5cy5hcmd2WzBdLCkgKiA1KQo=