IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCk9yLCBhdCB0aGUgc2hlbGwgY29tbWFuZCBsaW5lIG91dHNpZGUgb2YgUHl0aG9uOgoKUnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlCnRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKY2xhc3Mgb3IgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiB0aGUKYXJndW1lbnQgY29udGFpbnMgYSBwYXRoIHNlZ21lbnQgZGVsaW1pdGVyIChlLmcuIHNsYXNoIG9uIFVuaXgsCmJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKUnVuICJweWRvYyAtayA8a2V5d29yZD4iIHRvIHNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcwpvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgpSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQpsb2NhbCBtYWNoaW5lIHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gd2ViIHBhZ2VzLgoKRm9yIHBsYXRmb3JtcyB3aXRob3V0IGEgY29tbWFuZCBsaW5lLCAicHlkb2MgLWciIHN0YXJ0cyB0aGUgSFRUUCBzZXJ2ZXIKYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKUnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZQp0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgojIE5vdGU6IHRoaXMgbW9kdWxlIGlzIGRlc2lnbmVkIHRvIGRlcGxveSBpbnN0YW50bHkgYW5kIHJ1biB1bmRlciBhbnkKIyB2ZXJzaW9uIG9mIFB5dGhvbiBmcm9tIDEuNSBhbmQgdXAuICBUaGF0J3Mgd2h5IGl0J3MgYSBzaW5nbGUgZmlsZSBhbmQKIyBzb21lIDIuMCBmZWF0dXJlcyAobGlrZSBzdHJpbmcgbWV0aG9kcykgYXJlIGNvbnNwaWN1b3VzbHkgYXZvaWRlZC4KCmltcG9ydCBzeXMsIGltcCwgb3MsIHN0YXQsIHJlLCB0eXBlcywgaW5zcGVjdApmcm9tIHJlcHIgaW1wb3J0IFJlcHIKZnJvbSBzdHJpbmcgaW1wb3J0IGV4cGFuZHRhYnMsIGZpbmQsIGpvaW4sIGxvd2VyLCBzcGxpdCwgc3RyaXAsIHJzdHJpcAoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29tbW9uIHJvdXRpbmVzCgpkZWYgc3lub3BzaXMoZmlsZW5hbWUsIGNhY2hlPXt9KToKICAgICIiIkdldCB0aGUgb25lLWxpbmUgc3VtbWFyeSBvdXQgb2YgYSBtb2R1bGUgZmlsZS4iIiIKICAgIG10aW1lID0gb3Muc3RhdChmaWxlbmFtZSlbc3RhdC5TVF9NVElNRV0KICAgIGxhc3R1cGRhdGUsIHJlc3VsdCA9IGNhY2hlLmdldChmaWxlbmFtZSwgKDAsIE5vbmUpKQogICAgIyBYWFggd2hhdCBpZiBleHQgaXMgJ3JiJyB0eXBlIGluIGltcF9nZXRzdWZmaXhlcz8KICAgIGlmIGxhc3R1cGRhdGUgPCBtdGltZToKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgd2hpbGUgbGluZVs6MV0gPT0gJyMnIG9yIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICBsaW5lID0gZmlsZS5yZWFkbGluZSgpCiAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgIGlmIGxpbmVbLTI6XSA9PSAnXFxcbic6CiAgICAgICAgICAgIGxpbmUgPSBsaW5lWzotMl0gKyBmaWxlLnJlYWRsaW5lKCkKICAgICAgICBsaW5lID0gc3RyaXAobGluZSkKICAgICAgICBpZiBsaW5lWzozXSA9PSAnIiIiJzoKICAgICAgICAgICAgbGluZSA9IGxpbmVbMzpdCiAgICAgICAgICAgIHdoaWxlIHN0cmlwKGxpbmUpID09ICcnOgogICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6IGJyZWFrCiAgICAgICAgICAgIHJlc3VsdCA9IHN0cmlwKHNwbGl0KGxpbmUsICciIiInKVswXSkKICAgICAgICBlbHNlOiByZXN1bHQgPSBOb25lCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgY2FjaGVbZmlsZW5hbWVdID0gKG10aW1lLCByZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0CgpkZWYgcGF0aGRpcnMoKToKICAgICIiIkNvbnZlcnQgc3lzLnBhdGggaW50byBhIGxpc3Qgb2YgYWJzb2x1dGUsIGV4aXN0aW5nLCB1bmlxdWUgcGF0aHMuIiIiCiAgICBkaXJzID0gW10KICAgIG5vcm1kaXJzID0gW10KICAgIGZvciBkaXIgaW4gc3lzLnBhdGg6CiAgICAgICAgZGlyID0gb3MucGF0aC5hYnNwYXRoKGRpciBvciAnLicpCiAgICAgICAgbm9ybWRpciA9IG9zLnBhdGgubm9ybWNhc2UoZGlyKQogICAgICAgIGlmIG5vcm1kaXIgbm90IGluIG5vcm1kaXJzIGFuZCBvcy5wYXRoLmlzZGlyKGRpcik6CiAgICAgICAgICAgIGRpcnMuYXBwZW5kKGRpcikKICAgICAgICAgICAgbm9ybWRpcnMuYXBwZW5kKG5vcm1kaXIpCiAgICByZXR1cm4gZGlycwoKZGVmIGdldGRvYyhvYmplY3QpOgogICAgIiIiR2V0IHRoZSBkb2Mgc3RyaW5nIG9yIGNvbW1lbnRzIGZvciBhbiBvYmplY3QuIiIiCiAgICByZXN1bHQgPSBpbnNwZWN0LmdldGRvYyhvYmplY3QpCiAgICBpZiBub3QgcmVzdWx0OgogICAgICAgIHRyeTogcmVzdWx0ID0gaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICAgICAgZXhjZXB0OiBwYXNzCiAgICByZXR1cm4gcmVzdWx0IGFuZCByZS5zdWIoJ14gKlxuJywgJycsIHJzdHJpcChyZXN1bHQpKSBvciAnJwoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICBmb3Igb2xkLCBuZXcgaW4gcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgb2xkKSwgbmV3KQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIHN0cmlwaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgIyBUaGUgYmVoYXZpb3VyIG9mICVwIGlzIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudCwgc28gd2UgbmVlZCBhbiBleGFtcGxlLgogICAgZm9yIHBhdHRlcm4gaW4gWycgYXQgMHhbMC05YS1mXXs2LH0+JCcsICcgYXQgWzAtOUEtRl17OCx9PiQnXToKICAgICAgICBpZiByZS5zZWFyY2gocGF0dGVybiwgcmVwcihFeGNlcHRpb24pKToKICAgICAgICAgICAgcmV0dXJuIHJlLnN1YihwYXR0ZXJuLCAnPicsIHRleHQpCiAgICByZXR1cm4gdGV4dAoKZGVmIG1vZHVsZW5hbWUocGF0aCk6CiAgICAiIiJSZXR1cm4gdGhlIFB5dGhvbiBtb2R1bGUgbmFtZSBmb3IgYSBnaXZlbiBwYXRoLCBvciBOb25lLiIiIgogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBzdWZmaXhlcyA9IG1hcChsYW1iZGEgKHN1ZmZpeCwgbW9kZSwga2luZCk6IChsZW4oc3VmZml4KSwgc3VmZml4KSwKICAgICAgICAgICAgICAgICAgIGltcC5nZXRfc3VmZml4ZXMoKSkKICAgIHN1ZmZpeGVzLnNvcnQoKQogICAgc3VmZml4ZXMucmV2ZXJzZSgpICMgdHJ5IGxvbmdlc3Qgc3VmZml4ZXMgZmlyc3QsIGluIGNhc2UgdGhleSBvdmVybGFwCiAgICBmb3IgbGVuZ3RoLCBzdWZmaXggaW4gc3VmZml4ZXM6CiAgICAgICAgaWYgbGVuKGZpbGVuYW1lKSA+IGxlbmd0aCBhbmQgZmlsZW5hbWVbLWxlbmd0aDpdID09IHN1ZmZpeDoKICAgICAgICAgICAgcmV0dXJuIGZpbGVuYW1lWzotbGVuZ3RoXQoKY2xhc3MgRG9jSW1wb3J0RXJyb3IoRXhjZXB0aW9uKToKICAgICIiIkNsYXNzIGZvciBlcnJvcnMgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsICh0eXBlLCB2YWx1ZSwgdGIpKToKICAgICAgICBzZWxmLmZpbGVuYW1lID0gZmlsZW5hbWUKICAgICAgICBzZWxmLnR5cGUgPSB0eXBlCiAgICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgc2VsZi50YiA9IHRiCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgdCA9IHNlbGYudHlwZQogICAgICAgIGlmIHR5cGUodCkgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICB0ID0gdC5fX25hbWVfXwogICAgICAgIHJldHVybiAncHJvYmxlbSBpbiAlcyAtICVzOiAlcycgJSAoc2VsZi5maWxlbmFtZSwgdCwgc2VsZi52YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKHBhdGgsIHN5cy5leGNfaW5mbygpKQogICAgZmlsZS5jbG9zZSgpCiAgICByZXR1cm4gbW9kdWxlCgpkZWYgaXNwYWNrYWdlKHBhdGgpOgogICAgIiIiR3Vlc3Mgd2hldGhlciBhIHBhdGggcmVmZXJzIHRvIGEgcGFja2FnZSBkaXJlY3RvcnkuIiIiCiAgICBpZiBvcy5wYXRoLmlzZGlyKHBhdGgpOgogICAgICAgIGZvciBleHQgaW4gWycucHknLCAnLnB5YycsICcucHlvJ106CiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKG9zLnBhdGguam9pbihwYXRoLCAnX19pbml0X18nICsgZXh0KSk6CiAgICAgICAgICAgICAgICByZXR1cm4gMQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsICphcmdzKToKICAgICAgICAiIiJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgYXJncyA9IChvYmplY3QsIG5hbWUpICsgYXJncwogICAgICAgIGlmIGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbW9kdWxlLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2NjbGFzcywgYXJncykKICAgICAgICBpZiBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Nyb3V0aW5lLCBhcmdzKQogICAgICAgIHJldHVybiBhcHBseShzZWxmLmRvY290aGVyLCBhcmdzKQoKICAgIGRlZiBmYWlsKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCAqYXJncyk6CiAgICAgICAgIiIiUmFpc2UgYW4gZXhjZXB0aW9uIGZvciB1bmltcGxlbWVudGVkIHR5cGVzLiIiIgogICAgICAgIG1lc3NhZ2UgPSAiZG9uJ3Qga25vdyBob3cgdG8gZG9jdW1lbnQgb2JqZWN0JXMgb2YgdHlwZSAlcyIgJSAoCiAgICAgICAgICAgIG5hbWUgYW5kICcgJyArIHJlcHIobmFtZSksIHR5cGUob2JqZWN0KS5fX25hbWVfXykKICAgICAgICByYWlzZSBUeXBlRXJyb3IsIG1lc3NhZ2UKCiAgICBkb2Ntb2R1bGUgPSBkb2NjbGFzcyA9IGRvY3JvdXRpbmUgPSBkb2NvdGhlciA9IGZhaWwKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gMTAwCgogICAgZGVmIGVzY2FwZShzZWxmLCB0ZXh0KToKICAgICAgICByZXR1cm4gcmVwbGFjZSh0ZXh0LCAoJyYnLCAnJmFtcDsnKSwgKCc8JywgJyZsdDsnKSwgKCc+JywgJyZndDsnKSkKCiAgICBkZWYgcmVwcihzZWxmLCBvYmplY3QpOgogICAgICAgIHJldHVybiBSZXByLnJlcHIoc2VsZiwgb2JqZWN0KQoKICAgIGRlZiByZXByMShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgbWV0aG9kbmFtZSA9ICdyZXByXycgKyBqb2luKHNwbGl0KHR5cGUoeCkuX19uYW1lX18pLCAnXycpCiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKICAgICAgICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkoeCwgbGV2ZWwpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhvdGhlcikpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIChyJ1xcJywgJycpKToKICAgICAgICAgICAgIyBCYWNrc2xhc2hlcyBhcmUgb25seSBsaXRlcmFsIGluIHRoZSBzdHJpbmcgYW5kIGFyZSBuZXZlcgogICAgICAgICAgICAjIG5lZWRlZCB0byBtYWtlIGFueSBzcGVjaWFsIGNoYXJhY3RlcnMsIHNvIHNob3cgYSByYXcgc3RyaW5nLgogICAgICAgICAgICByZXR1cm4gJ3InICsgdGVzdHJlcHJbMF0gKyBzZWxmLmVzY2FwZSh0ZXN0KSArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHJlLnN1YihyJygoXFxbXFxhYmZucnR2XCciXXxcXHguLnxcXHUuLi4uKSspJywKICAgICAgICAgICAgICAgICAgICAgIHInPGZvbnQgY29sb3I9IiNjMDQwYzAiPlwxPC9mb250PicsCiAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVzY2FwZSh0ZXN0cmVwcikpCgogICAgZGVmIHJlcHJfaW5zdGFuY2Uoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhzdHJpbmcpKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZXNjYXBlKCc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fKQoKICAgIHJlcHJfdW5pY29kZSA9IHJlcHJfc3RyaW5nCgpjbGFzcyBIVE1MRG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIEhUTUwgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gSFRNTFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKICAgIGVzY2FwZSA9IF9yZXByX2luc3RhbmNlLmVzY2FwZQoKICAgIGRlZiBwYWdlKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGFuIEhUTUwgcGFnZS4iIiIKICAgICAgICByZXR1cm4gJycnCjwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vVzNDLy9EVEQgSFRNTCA0LjAgVHJhbnNpdGlvbmFsLy9FTiI+CjxodG1sPjx0aXRsZT5QeXRob246ICVzPC90aXRsZT48Ym9keSBiZ2NvbG9yPSIjZjBmMGY4Ij4KJXMKPC9ib2R5PjwvaHRtbD4nJycgJSAodGl0bGUsIGNvbnRlbnRzKQoKICAgIGRlZiBoZWFkaW5nKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGV4dHJhcz0nJyk6CiAgICAgICAgIiIiRm9ybWF0IGEgcGFnZSBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiAnJycKPHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgdmFsaWduPWJvdHRvbT48c21hbGw+Jm5ic3A7PGJyPjwvc21hbGwKPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhIj4mbmJzcDs8YnI+JXM8L2ZvbnQ+PC90ZAo+PHRkIGFsaWduPXJpZ2h0IHZhbGlnbj1ib3R0b20KPjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhIj4lczwvZm9udD48L3RkPjwvdHI+PC90YWJsZT4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlLCBmZ2NvbCwgZXh0cmFzIG9yICcmbmJzcDsnKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGNvbnRlbnRzLCB3aWR0aD0yMCwKICAgICAgICAgICAgICAgIHByZWx1ZGU9JycsIG1hcmdpbmFsaWE9Tm9uZSwgZ2FwPScmbmJzcDsmbmJzcDsnKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBoZWFkaW5nLiIiIgogICAgICAgIGlmIG1hcmdpbmFsaWEgaXMgTm9uZToKICAgICAgICAgICAgbWFyZ2luYWxpYSA9ICcmbmJzcDsnICogd2lkdGgKICAgICAgICByZXN1bHQgPSAnJycKPHA+PHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgY29sc3Bhbj0zIHZhbGlnbj1ib3R0b20+PHNtYWxsPjxzbWFsbD4mbmJzcDs8YnI+PC9zbWFsbD48L3NtYWxsCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlKQogICAgICAgIGlmIHByZWx1ZGU6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcnJwo8dHIgYmdjb2xvcj0iJXMiPjx0ZD4lczwvdGQ+Cjx0ZCBjb2xzcGFuPTI+JXM8L3RkPjwvdHI+CiAgICAnJycgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIHByZWx1ZGUpCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJycnCjx0cj48dGQgYmdjb2xvcj0iJXMiPiVzPC90ZD48dGQ+JXM8L3RkPgogICAgJycnICUgKGJnY29sLCBtYXJnaW5hbGlhLCBnYXApCgogICAgICAgIHJldHVybiByZXN1bHQgKyAnPHRkIHdpZHRoPSIxMDAlJSI+JXM8L3RkPjwvdHI+PC90YWJsZT4nICUgY29udGVudHMKCiAgICBkZWYgYmlnc2VjdGlvbihzZWxmLCB0aXRsZSwgKmFyZ3MpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGJpZyBoZWFkaW5nLiIiIgogICAgICAgIHRpdGxlID0gJzxiaWc+PHN0cm9uZz4lczwvc3Ryb25nPjwvYmlnPicgJSB0aXRsZQogICAgICAgIHJldHVybiBhcHBseShzZWxmLnNlY3Rpb24sICh0aXRsZSwpICsgYXJncykKCiAgICBkZWYgcHJlZm9ybWF0KHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBsaXRlcmFsIHByZWZvcm1hdHRlZCB0ZXh0LiIiIgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShleHBhbmR0YWJzKHRleHQpKQogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnXG5cbicsICdcbiBcbicpLCAoJ1xuXG4nLCAnXG4gXG4nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJyAnLCAnJm5ic3A7JyksICgnXG4nLCAnPGJyPlxuJykpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwogICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29scyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8dGQgd2lkdGg9IiVkJSUiIHZhbGlnbj10b3A+JyAlICgxMDAvY29scykKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2Uocm93cypjb2wsIHJvd3MqY29sK3Jvd3MpOgogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihsaXN0KToKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBmb3JtYXQobGlzdFtpXSkgKyAnPGJyPicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzwvdGQ+JwogICAgICAgIHJldHVybiAnPHRhYmxlIHdpZHRoPSIxMDAlJSI+PHRyPiVzPC90cj48L3RhYmxlPicgJSByZXN1bHQKCiAgICBkZWYgc21hbGwoc2VsZiwgdGV4dCk6IHJldHVybiAnPHNtYWxsPiVzPC9zbWFsbD4nICUgdGV4dAogICAgZGVmIGdyZXkoc2VsZiwgdGV4dCk6IHJldHVybiAnPGZvbnQgY29sb3I9IiM5MDkwOTAiPiVzPC9mb250PicgJSB0ZXh0CgogICAgZGVmIG5hbWVsaW5rKHNlbGYsIG5hbWUsICpkaWN0cyk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGFuIGlkZW50aWZpZXIsIGdpdmVuIG5hbWUtdG8tVVJMIG1hcHBpbmdzLiIiIgogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBkaWN0Lmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGRpY3RbbmFtZV0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgY2xhc3NsaW5rKHNlbGYsIG9iamVjdCwgbW9kbmFtZSwgKmRpY3RzKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBjbGFzcy4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICAgICAgbmFtZSA9IG9iamVjdC5fX21vZHVsZV9fICsgJy4nICsgbmFtZQogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBkaWN0Lmhhc19rZXkob2JqZWN0KToKICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAoZGljdFtvYmplY3RdLCBuYW1lKQogICAgICAgIHJldHVybiBuYW1lCgogICAgZGVmIG1vZHVsZWxpbmsoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUuIiIiCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG9iamVjdC5fX25hbWVfXywgb2JqZWN0Ll9fbmFtZV9fKQoKICAgIGRlZiBtb2Rwa2dsaW5rKHNlbGYsIChuYW1lLCBwYXRoLCBpc3BhY2thZ2UsIHNoYWRvd2VkKSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlIG9yIHBhY2thZ2UgdG8gZGlzcGxheSBpbiBhbiBpbmRleC4iIiIKICAgICAgICBpZiBzaGFkb3dlZDoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuZ3JleShuYW1lKQogICAgICAgIGlmIHBhdGg6CiAgICAgICAgICAgIHVybCA9ICclcy4lcy5odG1sJyAlIChwYXRoLCBuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHVybCA9ICclcy5odG1sJyAlIG5hbWUKICAgICAgICBpZiBpc3BhY2thZ2U6CiAgICAgICAgICAgIHRleHQgPSAnPHN0cm9uZz4lczwvc3Ryb25nPiZuYnNwOyhwYWNrYWdlKScgJSBuYW1lCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGV4dCA9IG5hbWUKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgdGV4dCkKCiAgICBkZWYgbWFya3VwKHNlbGYsIHRleHQsIGVzY2FwZT1Ob25lLCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSk6CiAgICAgICAgIiIiTWFyayB1cCBzb21lIHBsYWluIHRleHQsIGdpdmVuIGEgY29udGV4dCBvZiBzeW1ib2xzIHRvIGxvb2sgZm9yLgogICAgICAgIEVhY2ggY29udGV4dCBkaWN0aW9uYXJ5IG1hcHMgb2JqZWN0IG5hbWVzIHRvIGFuY2hvciBuYW1lcy4iIiIKICAgICAgICBlc2NhcGUgPSBlc2NhcGUgb3Igc2VsZi5lc2NhcGUKICAgICAgICByZXN1bHRzID0gW10KICAgICAgICBoZXJlID0gMAogICAgICAgIHBhdHRlcm4gPSByZS5jb21waWxlKHInXGIoKChodHRwfGZ0cCk6Ly9cUytbXHcvXSl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInKFJGQ1stIF0/KFxkKykpfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJyhzZWxmXC4pPyhcdyspKVxiJykKICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICBtYXRjaCA9IHBhdHRlcm4uc2VhcmNoKHRleHQsIGhlcmUpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDogYnJlYWsKICAgICAgICAgICAgc3RhcnQsIGVuZCA9IG1hdGNoLnNwYW4oKQogICAgICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOnN0YXJ0XSkpCgogICAgICAgICAgICBhbGwsIHVybCwgc2NoZW1lLCByZmMsIHJmY251bSwgc2VsZmRvdCwgbmFtZSA9IG1hdGNoLmdyb3VwcygpCiAgICAgICAgICAgIGlmIHVybDoKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZSh1cmwpKSkKICAgICAgICAgICAgZWxpZiByZmM6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjJXMudHh0JyAlIHJmY251bQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKHJmYykpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgdGV4dFtlbmQ6ZW5kKzFdID09ICcoJzoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgICAgIGVsaWYgc2VsZmRvdDoKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnc2VsZi48c3Ryb25nPiVzPC9zdHJvbmc+JyAlIG5hbWUpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKHNlbGYubmFtZWxpbmsobmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgIGhlcmUgPSBlbmQKICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOl0pKQogICAgICAgIHJldHVybiBqb2luKHJlc3VsdHMsICcnKQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGZvcm1hdHRyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgY2xhc3Nlcz17fSwgcGFyZW50PU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBmb3IgYSBjbGFzcyB0cmVlIGFzIGdpdmVuIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPGR0Pjxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzbWFsbD4nCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmNsYXNzbGluayhjLCBtb2RuYW1lLCBjbGFzc2VzKQogICAgICAgICAgICAgICAgaWYgYmFzZXMgYW5kIGJhc2VzICE9IChwYXJlbnQsKToKICAgICAgICAgICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgICAgICAgICBmb3IgYmFzZSBpbiBiYXNlczoKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5hcHBlbmQoc2VsZi5jbGFzc2xpbmsoYmFzZSwgbW9kbmFtZSwgY2xhc3NlcykpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJygnICsgam9pbihwYXJlbnRzLCAnLCAnKSArICcpJwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJ1xuPC9zbWFsbD48L2ZvbnQ+PC9kdD4nCiAgICAgICAgICAgIGVsaWYgdHlwZShlbnRyeSkgaXMgdHlwZShbXSk6CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPGRkPlxuJXM8L2RkPlxuJyAlIHNlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgY2xhc3NlcywgYykKICAgICAgICByZXR1cm4gJzxkbD5cbiVzPC9kbD5cbicgJSByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18gIyBpZ25vcmUgdGhlIHBhc3NlZC1pbiBuYW1lCiAgICAgICAgcGFydHMgPSBzcGxpdChuYW1lLCAnLicpCiAgICAgICAgbGlua3MgPSBbXQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihwYXJ0cyktMSk6CiAgICAgICAgICAgIGxpbmtzLmFwcGVuZCgKICAgICAgICAgICAgICAgICc8YSBocmVmPSIlcy5odG1sIj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+JXM8L2ZvbnQ+PC9hPicgJQogICAgICAgICAgICAgICAgKGpvaW4ocGFydHNbOmkrMV0sICcuJyksIHBhcnRzW2ldKSkKICAgICAgICBsaW5rZWRuYW1lID0gam9pbihsaW5rcyArIHBhcnRzWy0xOl0sICcuJykKICAgICAgICBoZWFkID0gJzxiaWc+PGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+PC9iaWc+JyAlIGxpbmtlZG5hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhdGggPSBpbnNwZWN0LmdldGFic2ZpbGUob2JqZWN0KQogICAgICAgICAgICBmaWxlbGluayA9ICc8YSBocmVmPSJmaWxlOiVzIj4lczwvYT4nICUgKHBhdGgsIHBhdGgpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZWxpbmsgPSAnKGJ1aWx0LWluKScKICAgICAgICBpbmZvID0gW10KICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyQnICsgJ1JldmlzaW9uOiAnIGFuZCB2ZXJzaW9uWy0xOl0gPT0gJyQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0cmlwKHZlcnNpb25bMTE6LTFdKQogICAgICAgICAgICBpbmZvLmFwcGVuZCgndmVyc2lvbiAlcycgJSBzZWxmLmVzY2FwZSh2ZXJzaW9uKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIGluZm8uYXBwZW5kKHNlbGYuZXNjYXBlKHN0cihvYmplY3QuX19kYXRlX18pKSkKICAgICAgICBpZiBpbmZvOgogICAgICAgICAgICBoZWFkID0gaGVhZCArICcgKCVzKScgJSBqb2luKGluZm8sICcsICcpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5oZWFkaW5nKAogICAgICAgICAgICBoZWFkLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgJzxhIGhyZWY9Ii4iPmluZGV4PC9hPjxicj4nICsgZmlsZWxpbmspCgogICAgICAgIG1vZHVsZXMgPSBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0LmlzbW9kdWxlKQoKICAgICAgICBpZiAwIGFuZCBoYXNhdHRyKG9iamVjdCwgJ19fYWxsX18nKToKICAgICAgICAgICAgdmlzaWJsZSA9IGxhbWJkYSBrZXksIGFsbD1vYmplY3QuX19hbGxfXzoga2V5IGluIGFsbAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHZpc2libGUgPSBsYW1iZGEga2V5OiBrZXlbOjFdICE9ICdfJwoKICAgICAgICBjbGFzc2VzLCBjZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIHZpc2libGUoa2V5KSBhbmQgKAogICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIG9yIG9iamVjdCkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgICAgICAgICAgY2RpY3Rba2V5XSA9IGNkaWN0W3ZhbHVlXSA9ICcjJyArIGtleQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNsYXNzZXM6CiAgICAgICAgICAgIGZvciBiYXNlIGluIHZhbHVlLl9fYmFzZXNfXzoKICAgICAgICAgICAgICAgIGtleSwgbW9kbmFtZSA9IGJhc2UuX19uYW1lX18sIGJhc2UuX19tb2R1bGVfXwogICAgICAgICAgICAgICAgbW9kdWxlID0gc3lzLm1vZHVsZXMuZ2V0KG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBtb2RuYW1lICE9IG5hbWUgYW5kIG1vZHVsZSBhbmQgaGFzYXR0cihtb2R1bGUsIGtleSk6CiAgICAgICAgICAgICAgICAgICAgaWYgZ2V0YXR0cihtb2R1bGUsIGtleSkgaXMgYmFzZToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IGNkaWN0Lmhhc19rZXkoa2V5KToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFtiYXNlXSA9IG1vZG5hbWUgKyAnLmh0bWwjJyArIGtleQogICAgICAgIGZ1bmNzLCBmZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgdmlzaWJsZShrZXkpIGFuZCAoaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3QpOgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICAgICAgICAgIGZkaWN0W2tleV0gPSAnIy0nICsga2V5CiAgICAgICAgICAgICAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24odmFsdWUpOiBmZGljdFt2YWx1ZV0gPSBmZGljdFtrZXldCiAgICAgICAgY29uc3RhbnRzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpc2NvbnN0YW50KToKICAgICAgICAgICAgaWYgdmlzaWJsZShrZXkpOgogICAgICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwgZmRpY3QsIGNkaWN0KQogICAgICAgIGRvYyA9IGRvYyBhbmQgJzx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8cD4lc1xuJyAlIHNlbGYuc21hbGwoZG9jKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBtb2RuYW1lcyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIGlmIGZpbGVbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZG5hbWVzOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgobW9kbmFtZSwgbmFtZSwgMCwgMCkpCiAgICAgICAgICAgICAgICAgICAgICAgIG1vZG5hbWVzLmFwcGVuZChtb2RuYW1lKQogICAgICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgoZmlsZSwgbmFtZSwgMSwgMCkpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbihtb2Rwa2dzLCBzZWxmLm1vZHBrZ2xpbmspCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdQYWNrYWdlIENvbnRlbnRzJywgJyNmZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQogICAgICAgIGVsaWYgbW9kdWxlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKAogICAgICAgICAgICAgICAgbW9kdWxlcywgbGFtYmRhIChrZXksIHZhbHVlKSwgcz1zZWxmOiBzLm1vZHVsZWxpbmsodmFsdWUpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnTW9kdWxlcycsICcjZmZmZmYnLCAnI2FhNTVjYycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjbGFzc2VzOgogICAgICAgICAgICBjbGFzc2xpc3QgPSBtYXAobGFtYmRhIChrZXksIHZhbHVlKTogdmFsdWUsIGNsYXNzZXMpCiAgICAgICAgICAgIGNvbnRlbnRzID0gW3NlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgIGluc3BlY3QuZ2V0Y2xhc3N0cmVlKGNsYXNzbGlzdCwgMSksIG5hbWUsIGNkaWN0KV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIGZkaWN0LCBjZGljdCkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDbGFzc2VzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGpvaW4oY29udGVudHMpKQogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgZmRpY3QsIGNkaWN0KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0Z1bmN0aW9ucycsICcjZmZmZmZmJywgJyNlZWFhNzcnLCBqb2luKGNvbnRlbnRzKSkKICAgICAgICBpZiBjb25zdGFudHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY29uc3RhbnRzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDb25zdGFudHMnLCAnI2ZmZmZmZicsICcjNTVhYTU1Jywgam9pbihjb250ZW50cywgJzxicj4nKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fYXV0aG9yX18pLCBzZWxmLnByZWZvcm1hdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0F1dGhvcicsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tYXJrdXAoc3RyKG9iamVjdC5fX2NyZWRpdHNfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ3JlZGl0cycsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30pOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCiAgICAgICAgY29udGVudHMgPSAnJwoKICAgICAgICBtZXRob2RzLCBtZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtZXRob2QpOgogICAgICAgICAgICBtZXRob2RzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgICAgIG1kaWN0W2tleV0gPSBtZGljdFt2YWx1ZV0gPSAnIycgKyBuYW1lICsgJy0nICsga2V5CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gbWV0aG9kczoKICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoCiAgICAgICAgICAgICAgICB2YWx1ZSwga2V5LCBmdW5jcywgY2xhc3NlcywgbWRpY3QsIG5hbWUpCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj5jbGFzcyA8c3Ryb25nPiVzPC9zdHJvbmc+PC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCByZWFsbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB0aXRsZSA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+ID0gPGEgbmFtZT0iJXMiPmNsYXNzICVzPC9hPicgJSAoCiAgICAgICAgICAgICAgICBuYW1lLCBuYW1lLCByZWFsbmFtZSkKCiAgICAgICAgaWYgYmFzZXM6CiAgICAgICAgICAgIHBhcmVudHMgPSBbXQogICAgICAgICAgICBmb3IgYmFzZSBpbiBiYXNlczoKICAgICAgICAgICAgICAgIHBhcmVudHMuYXBwZW5kKAogICAgICAgICAgICAgICAgICAgIHNlbGYuY2xhc3NsaW5rKGJhc2UsIG9iamVjdC5fX21vZHVsZV9fLCBjbGFzc2VzKSkKICAgICAgICAgICAgdGl0bGUgPSB0aXRsZSArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cCgKICAgICAgICAgICAgZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmdW5jcywgY2xhc3NlcywgbWRpY3QpCiAgICAgICAgaWYgZG9jOiBkb2MgPSBzZWxmLnNtYWxsKCc8dHQ+JXM8L3R0PicgJSBkb2MpCiAgICAgICAgcmV0dXJuIHNlbGYuc2VjdGlvbih0aXRsZSwgJyMwMDAwMDAnLCAnI2ZmYzhkOCcsIGNvbnRlbnRzLCAxMCwgZG9jKQoKICAgIGRlZiBmb3JtYXR2YWx1ZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIkZvcm1hdCBhbiBhcmd1bWVudCBkZWZhdWx0IHZhbHVlIGFzIHRleHQuIiIiCiAgICAgICAgcmV0dXJuIHNlbGYuc21hbGwoc2VsZi5ncmV5KCc9JyArIHNlbGYucmVwcihvYmplY3QpKSkKCiAgICBkZWYgZG9jcm91dGluZShzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwKICAgICAgICAgICAgICAgICAgIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9LCBjbG5hbWU9JycpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGFuY2hvciA9IGNsbmFtZSArICctJyArIHJlYWxuYW1lCiAgICAgICAgbm90ZSA9ICcnCiAgICAgICAgaWYgaW5zcGVjdC5pc21ldGhvZChvYmplY3QpOgogICAgICAgICAgICBpZiBub3QgY2xuYW1lOgogICAgICAgICAgICAgICAgbm90ZSA9IHNlbGYuc21hbGwoc2VsZi5ncmV5KAogICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbV9zZWxmIGFuZAogICAgICAgICAgICAgICAgICAgICAgICAnbWV0aG9kIG9mICcgKyBzZWxmLnJlcHIob2JqZWN0LmltX3NlbGYpIG9yCiAgICAgICAgICAgICAgICAgICAgICAgICcgdW5ib3VuZCAlcyBtZXRob2QnICUgb2JqZWN0LmltX2NsYXNzLl9fbmFtZV9fKSkKICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPjxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlIChhbmNob3IsIHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gJzxzdHJvbmc+JXM8L3N0cm9uZz4gPSA8YSBuYW1lPSIlcyI+JXM8L2E+JyAlICgKICAgICAgICAgICAgICAgIG5hbWUsIGFuY2hvciwgcmVhbG5hbWUpCiAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4ob2JqZWN0KToKICAgICAgICAgICAgYXJnc3BlYyA9ICcoLi4uKScKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiByZWFsbmFtZSA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgZGVjbCA9ICc8ZW0+bGFtYmRhPC9lbT4nCiAgICAgICAgICAgICAgICBhcmdzcGVjID0gYXJnc3BlY1sxOi0xXSAjIHJlbW92ZSBwYXJlbnRoZXNlcwoKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgbm90ZQoKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cCgKICAgICAgICAgICAgZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmdW5jcywgY2xhc3NlcywgbWV0aG9kcykKICAgICAgICBkb2MgPSByZXBsYWNlKGRvYywgKCc8YnI+XG4nLCAnPC90dD48L3NtYWxsXG4+PGRkPjxzbWFsbD48dHQ+JykpCiAgICAgICAgZG9jID0gZG9jIGFuZCAnPHR0PiVzPC90dD4nICUgZG9jCiAgICAgICAgcmV0dXJuICc8ZGw+PGR0PiVzPGRkPiVzPC9kbD4nICUgKGRlY2wsIHNlbGYuc21hbGwoZG9jKSkKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGRhdGEgb2JqZWN0LiIiIgogICAgICAgIHJldHVybiAnPHN0cm9uZz4lczwvc3Ryb25nPiA9ICVzJyAlIChuYW1lLCBzZWxmLnJlcHIob2JqZWN0KSkKCiAgICBkZWYgaW5kZXgoc2VsZiwgZGlyLCBzaGFkb3dlZD1Ob25lKToKICAgICAgICAiIiJHZW5lcmF0ZSBhbiBIVE1MIGluZGV4IGZvciBhIGRpcmVjdG9yeSBvZiBtb2R1bGVzLiIiIgogICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgIGlmIHNoYWRvd2VkIGlzIE5vbmU6IHNoYWRvd2VkID0ge30KICAgICAgICBzZWVuID0ge30KICAgICAgICBmaWxlcyA9IG9zLmxpc3RkaXIoZGlyKQoKICAgICAgICBkZWYgZm91bmQobmFtZSwgaXNwYWNrYWdlLAogICAgICAgICAgICAgICAgICBtb2Rwa2dzPW1vZHBrZ3MsIHNoYWRvd2VkPXNoYWRvd2VkLCBzZWVuPXNlZW4pOgogICAgICAgICAgICBpZiBub3Qgc2Vlbi5oYXNfa2V5KG5hbWUpOgogICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG5hbWUsICcnLCBpc3BhY2thZ2UsIHNoYWRvd2VkLmhhc19rZXkobmFtZSkpKQogICAgICAgICAgICAgICAgc2VlbltuYW1lXSA9IDEKICAgICAgICAgICAgICAgIHNoYWRvd2VkW25hbWVdID0gMQoKICAgICAgICAjIFBhY2thZ2Ugc3BhbS9fX2luaXRfXy5weSB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgbW9kdWxlIHNwYW0ucHkuCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6IGZvdW5kKGZpbGUsIDEpCiAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBmaWxlWzoxXSAhPSAnXycgYW5kIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWU6IGZvdW5kKG1vZG5hbWUsIDApCgogICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICByZXR1cm4gc2VsZi5iaWdzZWN0aW9uKGRpciwgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGRvY3VtZW50YXRpb24gZ2VuZXJhdG9yCgpjbGFzcyBUZXh0UmVwcihSZXByKToKICAgICIiIkNsYXNzIGZvciBzYWZlbHkgbWFraW5nIGEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiBhIFB5dGhvbiBvYmplY3QuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgUmVwci5fX2luaXRfXyhzZWxmKQogICAgICAgIHNlbGYubWF4bGlzdCA9IHNlbGYubWF4dHVwbGUgPSBzZWxmLm1heGRpY3QgPSAxMAogICAgICAgIHNlbGYubWF4c3RyaW5nID0gc2VsZi5tYXhvdGhlciA9IDEwMAoKICAgIGRlZiByZXByMShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgbWV0aG9kbmFtZSA9ICdyZXByXycgKyBqb2luKHNwbGl0KHR5cGUoeCkuX19uYW1lX18pLCAnXycpCiAgICAgICAgaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKICAgICAgICAgICAgcmV0dXJuIGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkoeCwgbGV2ZWwpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhvdGhlcikKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRlc3QgPSBjcmFtKHgsIHNlbGYubWF4c3RyaW5nKQogICAgICAgIHRlc3RyZXByID0gcmVwcih0ZXN0KQogICAgICAgIGlmICdcXCcgaW4gdGVzdCBhbmQgJ1xcJyBub3QgaW4gcmVwbGFjZSh0ZXN0cmVwciwgKHInXFwnLCAnJykpOgogICAgICAgICAgICAjIEJhY2tzbGFzaGVzIGFyZSBvbmx5IGxpdGVyYWwgaW4gdGhlIHN0cmluZyBhbmQgYXJlIG5ldmVyCiAgICAgICAgICAgICMgbmVlZGVkIHRvIG1ha2UgYW55IHNwZWNpYWwgY2hhcmFjdGVycywgc28gc2hvdyBhIHJhdyBzdHJpbmcuCiAgICAgICAgICAgIHJldHVybiAncicgKyB0ZXN0cmVwclswXSArIHRlc3QgKyB0ZXN0cmVwclswXQogICAgICAgIHJldHVybiB0ZXN0cmVwcgoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuICc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fCgpjbGFzcyBUZXh0RG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIHRleHQgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gVGV4dFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKCiAgICBkZWYgYm9sZChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgYSBzdHJpbmcgaW4gYm9sZCBieSBvdmVyc3RyaWtpbmcuIiIiCiAgICAgICAgcmV0dXJuIGpvaW4obWFwKGxhbWJkYSBjaDogY2ggKyAnXGInICsgY2gsIHRleHQpLCAnJykKCiAgICBkZWYgaW5kZW50KHNlbGYsIHRleHQsIHByZWZpeD0nICAgICcpOgogICAgICAgICIiIkluZGVudCB0ZXh0IGJ5IHByZXBlbmRpbmcgYSBnaXZlbiBwcmVmaXggdG8gZWFjaCBsaW5lLiIiIgogICAgICAgIGlmIG5vdCB0ZXh0OiByZXR1cm4gJycKICAgICAgICBsaW5lcyA9IHNwbGl0KHRleHQsICdcbicpCiAgICAgICAgbGluZXMgPSBtYXAobGFtYmRhIGxpbmUsIHByZWZpeD1wcmVmaXg6IHByZWZpeCArIGxpbmUsIGxpbmVzKQogICAgICAgIGlmIGxpbmVzOiBsaW5lc1stMV0gPSByc3RyaXAobGluZXNbLTFdKQogICAgICAgIHJldHVybiBqb2luKGxpbmVzLCAnXG4nKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgZ2l2ZW4gaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gc2VsZi5ib2xkKHRpdGxlKSArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoY29udGVudHMpKSArICdcblxuJwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGZvcm1hdHRyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgcGFyZW50PU5vbmUsIHByZWZpeD0nJyk6CiAgICAgICAgIiIiUmVuZGVyIGluIHRleHQgYSBjbGFzcyB0cmVlIGFzIHJldHVybmVkIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1tb2RuYW1lOiBjbGFzc25hbWUoYywgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgYywgcHJlZml4ICsgJyAgICAnKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBtb2R1bGUgb2JqZWN0LiIiIgogICAgICAgIG5hbWUgPSBvYmplY3QuX19uYW1lX18gIyBpZ25vcmUgdGhlIHBhc3NlZC1pbiBuYW1lCiAgICAgICAgbGluZXMgPSBzcGxpdChzdHJpcChnZXRkb2Mob2JqZWN0KSksICdcbicpCiAgICAgICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgICAgICBpZiBsaW5lc1swXTogbmFtZSA9IG5hbWUgKyAnIC0gJyArIGxpbmVzWzBdCiAgICAgICAgICAgIGxpbmVzID0gW10KICAgICAgICBlbGlmIGxlbihsaW5lcykgPj0gMiBhbmQgbm90IHJzdHJpcChsaW5lc1sxXSk6CiAgICAgICAgICAgIGlmIGxpbmVzWzBdOiBuYW1lID0gbmFtZSArICcgLSAnICsgbGluZXNbMF0KICAgICAgICAgICAgbGluZXMgPSBsaW5lc1syOl0KICAgICAgICByZXN1bHQgPSBzZWxmLnNlY3Rpb24oJ05BTUUnLCBuYW1lKQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZpbGUgPSBpbnNwZWN0LmdldGFic2ZpbGUob2JqZWN0KQogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgIGZpbGUgPSAnKGJ1aWx0LWluKScKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0ZJTEUnLCBmaWxlKQogICAgICAgIGlmIGxpbmVzOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RFU0NSSVBUSU9OJywgam9pbihsaW5lcywgJ1xuJykpCgogICAgICAgIGNsYXNzZXMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgZnVuY3MgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgIGNvbnN0YW50cyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNjb25zdGFudCk6CiAgICAgICAgICAgIGlmIGtleVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIGlmIGZpbGVbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZHBrZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKGZpbGUgKyAnIChwYWNrYWdlKScpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbigKICAgICAgICAgICAgICAgICdQQUNLQUdFIENPTlRFTlRTJywgam9pbihtb2Rwa2dzLCAnXG4nKSkKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY2xhc3NsaXN0ID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLCBjbGFzc2VzKQogICAgICAgICAgICBjb250ZW50cyA9IFtzZWxmLmZvcm1hdHRyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2xpc3QsIDEpLCBuYW1lKV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXkpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NMQVNTRVMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGVU5DVElPTlMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgY29uc3RhbnRzOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNvbnN0YW50czoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY290aGVyKHZhbHVlLCBrZXksIDcwKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDT05TVEFOVFMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3ZlcnNpb25fXycpOgogICAgICAgICAgICB2ZXJzaW9uID0gc3RyKG9iamVjdC5fX3ZlcnNpb25fXykKICAgICAgICAgICAgaWYgdmVyc2lvbls6MTFdID09ICckJyArICdSZXZpc2lvbjogJyBhbmQgdmVyc2lvblstMTpdID09ICckJzoKICAgICAgICAgICAgICAgIHZlcnNpb24gPSBzdHJpcCh2ZXJzaW9uWzExOi0xXSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdWRVJTSU9OJywgdmVyc2lvbikKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignREFURScsIHN0cihvYmplY3QuX19kYXRlX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0FVVEhPUicsIHN0cihvYmplY3QuX19hdXRob3JfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2NyZWRpdHNfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NSRURJVFMnLCBzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9ICdjbGFzcyAnICsgc2VsZi5ib2xkKHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9IGNsYXNzICcgKyByZWFsbmFtZQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gbWFwKGxhbWJkYSBjLCBtPW9iamVjdC5fX21vZHVsZV9fOiBjbGFzc25hbWUoYywgbSksIGJhc2VzKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQoKICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KQogICAgICAgIGNvbnRlbnRzID0gZG9jIGFuZCBkb2MgKyAnXG4nCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21ldGhvZCk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyAnXG4nICsgc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lKQoKICAgICAgICBpZiBub3QgY29udGVudHM6IHJldHVybiB0aXRsZSArICdcbicKICAgICAgICByZXR1cm4gdGl0bGUgKyAnXG4nICsgc2VsZi5pbmRlbnQocnN0cmlwKGNvbnRlbnRzKSwgJyB8ICAnKSArICdcbicKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiAnPScgKyBzZWxmLnJlcHIob2JqZWN0KQoKICAgIGRlZiBkb2Nyb3V0aW5lKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBjbG5hbWU9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZnVuY3Rpb24gb3IgbWV0aG9kIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgbm90ZSA9ICcnCiAgICAgICAgaWYgaW5zcGVjdC5pc21ldGhvZChvYmplY3QpOgogICAgICAgICAgICBpZiBub3QgY2xuYW1lOgogICAgICAgICAgICAgICAgaWYgb2JqZWN0LmltX3NlbGY6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgbWV0aG9kIG9mICVzJyAlIHNlbGYucmVwcihvYmplY3QuaW1fc2VsZikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgdW5ib3VuZCAlcyBtZXRob2QnICUgb2JqZWN0LmltX2NsYXNzLl9fbmFtZV9fCiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5pbV9mdW5jCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9ICcgKyByZWFsbmFtZQogICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKG9iamVjdCk6CiAgICAgICAgICAgIGFyZ3NwZWMgPSAnKC4uLiknCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKICAgICAgICAgICAgaWYgcmVhbG5hbWUgPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgICAgIHRpdGxlID0gJ2xhbWJkYScKICAgICAgICAgICAgICAgIGFyZ3NwZWMgPSBhcmdzcGVjWzE6LTFdICMgcmVtb3ZlIHBhcmVudGhlc2VzCiAgICAgICAgZGVjbCA9IHRpdGxlICsgYXJnc3BlYyArIG5vdGUKCiAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkKICAgICAgICBpZiBkb2M6CiAgICAgICAgICAgIHJldHVybiBkZWNsICsgJ1xuJyArIHJzdHJpcChzZWxmLmluZGVudChkb2MpKSArICdcbicKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gZGVjbCArICdcbicKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1heGxlbj1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBkYXRhIG9iamVjdC4iIiIKICAgICAgICByZXByID0gc2VsZi5yZXByKG9iamVjdCkKICAgICAgICBpZiBtYXhsZW46CiAgICAgICAgICAgIGxpbmUgPSBuYW1lICsgJyA9ICcgKyByZXByCiAgICAgICAgICAgIGNob3AgPSBtYXhsZW4gLSBsZW4obGluZSkKICAgICAgICAgICAgaWYgY2hvcCA8IDA6IHJlcHIgPSByZXByWzpjaG9wXSArICcuLi4nCiAgICAgICAgbGluZSA9IHNlbGYuYm9sZChuYW1lKSArICcgPSAnICsgcmVwcgogICAgICAgIHJldHVybiBsaW5lCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB1c2VyIGludGVyZmFjZXMKCmRlZiBwYWdlcih0ZXh0KToKICAgICIiIlRoZSBmaXJzdCB0aW1lIHRoaXMgaXMgY2FsbGVkLCBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIHBhZ2VyIHRvIHVzZS4iIiIKICAgIGdsb2JhbCBwYWdlcgogICAgcGFnZXIgPSBnZXRwYWdlcigpCiAgICBwYWdlcih0ZXh0KQoKZGVmIGdldHBhZ2VyKCk6CiAgICAiIiJEZWNpZGUgd2hhdCBtZXRob2QgdG8gdXNlIGZvciBwYWdpbmcgdGhyb3VnaCB0ZXh0LiIiIgogICAgaWYgdHlwZShzeXMuc3Rkb3V0KSBpcyBub3QgdHlwZXMuRmlsZVR5cGU6CiAgICAgICAgcmV0dXJuIHBsYWlucGFnZXIKICAgIGlmIG5vdCBzeXMuc3RkaW4uaXNhdHR5KCkgb3Igbm90IHN5cy5zdGRvdXQuaXNhdHR5KCk6CiAgICAgICAgcmV0dXJuIHBsYWlucGFnZXIKICAgIGlmIG9zLmVudmlyb24uaGFzX2tleSgnUEFHRVInKToKICAgICAgICByZXR1cm4gbGFtYmRhIGE6IHBpcGVwYWdlcihhLCBvcy5lbnZpcm9uWydQQUdFUiddKQogICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMic6CiAgICAgICAgcmV0dXJuIGxhbWJkYSBhOiB0ZW1wZmlsZXBhZ2VyKGEsICdtb3JlIDwnKQogICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ2xlc3MgMj4vZGV2L251bGwnKSA9PSAwOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogcGlwZXBhZ2VyKGEsICdsZXNzJykKCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIG9wZW4oZmlsZW5hbWUsICd3JykuY2xvc2UoKQogICAgdHJ5OgogICAgICAgIGlmIGhhc2F0dHIob3MsICdzeXN0ZW0nKSBhbmQgb3Muc3lzdGVtKCdtb3JlICVzJyAlIGZpbGVuYW1lKSA9PSAwOgogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHBpcGVwYWdlcih0ZXh0LCAnbW9yZScpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHR0eXBhZ2VyCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwaXBlcGFnZXIodGV4dCwgY21kKToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IGJ5IGZlZWRpbmcgaXQgdG8gYW5vdGhlciBwcm9ncmFtLiIiIgogICAgcGlwZSA9IG9zLnBvcGVuKGNtZCwgJ3cnKQogICAgdHJ5OgogICAgICAgIHBpcGUud3JpdGUodGV4dCkKICAgICAgICBwaXBlLmNsb3NlKCkKICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICMgSWdub3JlIGJyb2tlbiBwaXBlcyBjYXVzZWQgYnkgcXVpdHRpbmcgdGhlIHBhZ2VyIHByb2dyYW0uCiAgICAgICAgcGFzcwoKZGVmIHRlbXBmaWxlcGFnZXIodGV4dCwgY21kKToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IGJ5IGludm9raW5nIGEgcHJvZ3JhbSBvbiBhIHRlbXBvcmFyeSBmaWxlLiIiIgogICAgaW1wb3J0IHRlbXBmaWxlCiAgICBmaWxlbmFtZSA9IHRlbXBmaWxlLm1rdGVtcCgpCiAgICBmaWxlID0gb3BlbihmaWxlbmFtZSwgJ3cnKQogICAgZmlsZS53cml0ZSh0ZXh0KQogICAgZmlsZS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgb3Muc3lzdGVtKGNtZCArICcgJyArIGZpbGVuYW1lKQogICAgZmluYWxseToKICAgICAgICBvcy51bmxpbmsoZmlsZW5hbWUpCgpkZWYgcGxhaW4odGV4dCk6CiAgICAiIiJSZW1vdmUgYm9sZGZhY2UgZm9ybWF0dGluZyBmcm9tIHRleHQuIiIiCiAgICByZXR1cm4gcmUuc3ViKCcuXGInLCAnJywgdGV4dCkKCmRlZiB0dHlwYWdlcih0ZXh0KToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IG9uIGEgdGV4dCB0ZXJtaW5hbC4iIiIKICAgIGxpbmVzID0gc3BsaXQocGxhaW4odGV4dCksICdcbicpCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHR0eQogICAgICAgIGZkID0gc3lzLnN0ZGluLmZpbGVubygpCiAgICAgICAgb2xkID0gdHR5LnRjZ2V0YXR0cihmZCkKICAgICAgICB0dHkuc2V0Y2JyZWFrKGZkKQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkKDEpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgdHR5ID0gTm9uZQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkbGluZSgpWzotMV1bOjFdCgogICAgdHJ5OgogICAgICAgIHIgPSBpbmMgPSBvcy5lbnZpcm9uLmdldCgnTElORVMnLCAyNSkgLSAxCiAgICAgICAgc3lzLnN0ZG91dC53cml0ZShqb2luKGxpbmVzWzppbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgd2hpbGUgbGluZXNbcjpdOgogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCctLSBtb3JlIC0tJykKICAgICAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCiAgICAgICAgICAgIGMgPSBnZXRjaGFyKCkKCiAgICAgICAgICAgIGlmIGMgaW4gWydxJywgJ1EnXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJykKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGVsaWYgYyBpbiBbJ1xyJywgJ1xuJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicgKyBsaW5lc1tyXSArICdcbicpCiAgICAgICAgICAgICAgICByID0gciArIDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIGMgaW4gWydiJywgJ0InLCAnXHgxYiddOgogICAgICAgICAgICAgICAgciA9IHIgLSBpbmMgLSBpbmMKICAgICAgICAgICAgICAgIGlmIHIgPCAwOiByID0gMAogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcbicgKyBqb2luKGxpbmVzW3I6citpbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgICAgIHIgPSByICsgaW5jCgogICAgZmluYWxseToKICAgICAgICBpZiB0dHk6CiAgICAgICAgICAgIHR0eS50Y3NldGF0dHIoZmQsIHR0eS5UQ1NBRkxVU0gsIG9sZCkKCmRlZiBwbGFpbnBhZ2VyKHRleHQpOgogICAgIiIiU2ltcGx5IHByaW50IHVuZm9ybWF0dGVkIHRleHQuICBUaGlzIGlzIHRoZSB1bHRpbWF0ZSBmYWxsYmFjay4iIiIKICAgIHN5cy5zdGRvdXQud3JpdGUocGxhaW4odGV4dCkpCgpkZWYgZGVzY3JpYmUodGhpbmcpOgogICAgIiIiUHJvZHVjZSBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBnaXZlbiBraW5kIG9mIHRoaW5nLiIiIgogICAgaWYgaW5zcGVjdC5pc21vZHVsZSh0aGluZyk6CiAgICAgICAgaWYgdGhpbmcuX19uYW1lX18gaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICByZXR1cm4gJ2J1aWx0LWluIG1vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBpZiBoYXNhdHRyKHRoaW5nLCAnX19wYXRoX18nKToKICAgICAgICAgICAgcmV0dXJuICdwYWNrYWdlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiAnbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odGhpbmcpOgogICAgICAgIHJldHVybiAnYnVpbHQtaW4gZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzY2xhc3ModGhpbmcpOgogICAgICAgIHJldHVybiAnY2xhc3MgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24odGhpbmcpOgogICAgICAgIHJldHVybiAnZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKHRoaW5nKToKICAgICAgICByZXR1cm4gJ21ldGhvZCAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIHR5cGUodGhpbmcpIGlzIHR5cGVzLkluc3RhbmNlVHlwZToKICAgICAgICByZXR1cm4gJ2luc3RhbmNlIG9mICcgKyB0aGluZy5fX2NsYXNzX18uX19uYW1lX18KICAgIHJldHVybiB0eXBlKHRoaW5nKS5fX25hbWVfXwoKZGVmIGZyZXNoaW1wKHBhdGgsIGNhY2hlPXt9KToKICAgICIiIkltcG9ydCBhIG1vZHVsZSwgcmVsb2FkaW5nIGl0IGlmIHRoZSBzb3VyY2UgZmlsZSBoYXMgY2hhbmdlZC4iIiIKICAgIG1vZHVsZSA9IF9faW1wb3J0X18ocGF0aCkKICAgIGlmIGhhc2F0dHIobW9kdWxlLCAnX19maWxlX18nKToKICAgICAgICBmaWxlID0gbW9kdWxlLl9fZmlsZV9fCiAgICAgICAgaW5mbyA9IChmaWxlLCBvcy5wYXRoLmdldG10aW1lKGZpbGUpLCBvcy5wYXRoLmdldHNpemUoZmlsZSkpCiAgICAgICAgaWYgY2FjaGUuaGFzX2tleShwYXRoKToKICAgICAgICAgICAgaWYgY2FjaGVbcGF0aF0gIT0gaW5mbzoKICAgICAgICAgICAgICAgIG1vZHVsZSA9IHJlbG9hZChtb2R1bGUpCiAgICAgICAgY2FjaGVbcGF0aF0gPSBpbmZvCiAgICByZXR1cm4gbW9kdWxlCgpkZWYgbG9jYXRlKHBhdGgpOgogICAgIiIiTG9jYXRlIGFuIG9iamVjdCBieSBuYW1lIChvciBkb3R0ZWQgcGF0aCksIGltcG9ydGluZyBhcyBuZWNlc3NhcnkuIiIiCiAgICBpZiBub3QgcGF0aDogIyBzcGVjaWFsIGNhc2U6IGltcC5maW5kX21vZHVsZSgnJykgc3RyYW5nZWx5IHN1Y2NlZWRzCiAgICAgICAgcmV0dXJuIE5vbmUsIE5vbmUKICAgIGlmIHR5cGUocGF0aCkgaXMgbm90IHR5cGVzLlN0cmluZ1R5cGU6CiAgICAgICAgcmV0dXJuIE5vbmUsIHBhdGgKICAgIHBhcnRzID0gc3BsaXQocGF0aCwgJy4nKQogICAgbiA9IDEKICAgIHdoaWxlIG4gPD0gbGVuKHBhcnRzKToKICAgICAgICBwYXRoID0gam9pbihwYXJ0c1s6bl0sICcuJykKICAgICAgICB0cnk6CiAgICAgICAgICAgIG1vZHVsZSA9IGZyZXNoaW1wKHBhdGgpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAjIGRldGVybWluZSBpZiBlcnJvciBvY2N1cnJlZCBiZWZvcmUgb3IgYWZ0ZXIgbW9kdWxlIHdhcyBmb3VuZAogICAgICAgICAgICBpZiBzeXMubW9kdWxlcy5oYXNfa2V5KHBhdGgpOgogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXwogICAgICAgICAgICBlbGlmIHN5cy5leGNfdHlwZSBpcyBTeW50YXhFcnJvcjoKICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gc3lzLmV4Y192YWx1ZS5maWxlbmFtZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBtb2R1bGUgbm90IGZvdW5kLCBzbyBzdG9wIGxvb2tpbmcKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICMgZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGltcG9ydGVkIG1vZHVsZSwgc28gcmVwb3J0IGl0CiAgICAgICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKGZpbGVuYW1lLCBzeXMuZXhjX2luZm8oKSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHggPSBtb2R1bGUKICAgICAgICAgICAgZm9yIHAgaW4gcGFydHNbMTpdOgogICAgICAgICAgICAgICAgeCA9IGdldGF0dHIoeCwgcCkKICAgICAgICAgICAgcmV0dXJuIGpvaW4ocGFydHNbOi0xXSwgJy4nKSwgeAogICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKICAgICAgICAgICAgbiA9IG4gKyAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICBpZiBoYXNhdHRyKF9fYnVpbHRpbnNfXywgcGF0aCk6CiAgICAgICAgcmV0dXJuIE5vbmUsIGdldGF0dHIoX19idWlsdGluc19fLCBwYXRoKQogICAgcmV0dXJuIE5vbmUsIE5vbmUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGludGVyYWN0aXZlIGludGVycHJldGVyIGludGVyZmFjZQoKdGV4dCA9IFRleHREb2MoKQpodG1sID0gSFRNTERvYygpCgpkZWYgZG9jKHRoaW5nKToKICAgICIiIkRpc3BsYXkgZG9jdW1lbnRhdGlvbiBvbiBhbiBvYmplY3QgKGZvciBpbnRlcmFjdGl2ZSB1c2UpLiIiIgogICAgaWYgdHlwZSh0aGluZykgaXMgdHlwZSgiIik6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBwYXRoLCB4ID0gbG9jYXRlKHRoaW5nKQogICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgIHByaW50IHZhbHVlCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIHg6CiAgICAgICAgICAgIHRoaW5nID0geAogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50ICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCgogICAgZGVzYyA9IGRlc2NyaWJlKHRoaW5nKQogICAgbW9kdWxlID0gaW5zcGVjdC5nZXRtb2R1bGUodGhpbmcpCiAgICBpZiBtb2R1bGUgYW5kIG1vZHVsZSBpcyBub3QgdGhpbmc6CiAgICAgICAgZGVzYyA9IGRlc2MgKyAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcignSGVscCBvbiAlczpcblxuJyAlIGRlc2MgKyB0ZXh0LmRvY3VtZW50KHRoaW5nKSkKCmRlZiB3cml0ZWRvYyhrZXkpOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICB0cnk6CiAgICAgICAgcGF0aCwgb2JqZWN0ID0gbG9jYXRlKGtleSkKICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgcHJpbnQgdmFsdWUKICAgIGVsc2U6CiAgICAgICAgaWYgb2JqZWN0OgogICAgICAgICAgICBwYWdlID0gaHRtbC5wYWdlKCdQeXRob246ICcgKyBkZXNjcmliZShvYmplY3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwuZG9jdW1lbnQob2JqZWN0LCBvYmplY3QuX19uYW1lX18pKQogICAgICAgICAgICBmaWxlID0gb3BlbihrZXkgKyAnLmh0bWwnLCAndycpCiAgICAgICAgICAgIGZpbGUud3JpdGUocGFnZSkKICAgICAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgICAgIHByaW50ICd3cm90ZScsIGtleSArICcuaHRtbCcKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCAnbm8gUHl0aG9uIGRvY3VtZW50YXRpb24gZm91bmQgZm9yICVzJyAlIHJlcHIoa2V5KQoKZGVmIHdyaXRlZG9jcyhkaXIsIHBrZ3BhdGg9JycsIGRvbmU9e30pOgogICAgIiIiV3JpdGUgb3V0IEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYWxsIG1vZHVsZXMgaW4gYSBkaXJlY3RvcnkgdHJlZS4iIiIKICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKGRpciwgZmlsZSkKICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgIHdyaXRlZG9jcyhwYXRoLCBwa2dwYXRoICsgZmlsZSArICcuJykKICAgICAgICBlbGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBrZ3BhdGggKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3QgZG9uZS5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIGRvbmVbbW9kbmFtZV0gPSAxCiAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MobW9kbmFtZSkKCmNsYXNzIEhlbHBlcjoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gJycnVG8gZ2V0IGhlbHAgb24gYSBQeXRob24gb2JqZWN0LCBjYWxsIGhlbHAob2JqZWN0KS4KVG8gZ2V0IGhlbHAgb24gYSBtb2R1bGUgb3IgcGFja2FnZSwgZWl0aGVyIGltcG9ydCBpdCBiZWZvcmUgY2FsbGluZwpoZWxwKG1vZHVsZSkgb3IgY2FsbCBoZWxwKCdtb2R1bGVuYW1lJykuJycnCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzKToKICAgICAgICBpZiBhcmdzOgogICAgICAgICAgICBkb2MoYXJnc1swXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCByZXByKHNlbGYpCgpoZWxwID0gSGVscGVyKCkKCmRlZiBtYW4oa2V5KToKICAgICIiIkRpc3BsYXkgZG9jdW1lbnRhdGlvbiBvbiBhbiBvYmplY3QgaW4gYSBmb3JtIHNpbWlsYXIgdG8gbWFuKDEpLiIiIgogICAgcGF0aCwgb2JqZWN0ID0gbG9jYXRlKGtleSkKICAgIGlmIG9iamVjdDoKICAgICAgICB0aXRsZSA9ICdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAnICsgZGVzY3JpYmUob2JqZWN0KQogICAgICAgIGlmIHBhdGg6IHRpdGxlID0gdGl0bGUgKyAnIGluICcgKyBwYXRoCiAgICAgICAgcGFnZXIoJ1xuJyArIHRpdGxlICsgJ1xuXG4nICsgdGV4dC5kb2N1bWVudChvYmplY3QsIGtleSkpCiAgICAgICAgZm91bmQgPSAxCiAgICBlbHNlOgogICAgICAgIHByaW50ICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcihrZXkpCgpjbGFzcyBTY2FubmVyOgogICAgIiIiQSBnZW5lcmljIHRyZWUgaXRlcmF0b3IuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgcm9vdHMsIGNoaWxkcmVuLCByZWN1cnNlKToKICAgICAgICBzZWxmLnJvb3RzID0gcm9vdHNbOl0KICAgICAgICBzZWxmLnN0YXRlID0gW10KICAgICAgICBzZWxmLmNoaWxkcmVuID0gY2hpbGRyZW4KICAgICAgICBzZWxmLnJlY3Vyc2UgPSByZWN1cnNlCgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuc3RhdGU6CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLnJvb3RzOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgcm9vdCA9IHNlbGYucm9vdHMucG9wKDApCiAgICAgICAgICAgIHNlbGYuc3RhdGUgPSBbKHJvb3QsIHNlbGYuY2hpbGRyZW4ocm9vdCkpXQogICAgICAgIG5vZGUsIGNoaWxkcmVuID0gc2VsZi5zdGF0ZVstMV0KICAgICAgICBpZiBub3QgY2hpbGRyZW46CiAgICAgICAgICAgIHNlbGYuc3RhdGUucG9wKCkKICAgICAgICAgICAgcmV0dXJuIHNlbGYubmV4dCgpCiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbi5wb3AoMCkKICAgICAgICBpZiBzZWxmLnJlY3Vyc2UoY2hpbGQpOgogICAgICAgICAgICBzZWxmLnN0YXRlLmFwcGVuZCgoY2hpbGQsIHNlbGYuY2hpbGRyZW4oY2hpbGQpKSkKICAgICAgICByZXR1cm4gY2hpbGQKCmNsYXNzIE1vZHVsZVNjYW5uZXIoU2Nhbm5lcik6CiAgICAiIiJBbiBpbnRlcnJ1cHRpYmxlIHNjYW5uZXIgdGhhdCBzZWFyY2hlcyBtb2R1bGUgc3lub3BzZXMuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgcm9vdHMgPSBtYXAobGFtYmRhIGRpcjogKGRpciwgJycpLCBwYXRoZGlycygpKQogICAgICAgIFNjYW5uZXIuX19pbml0X18oc2VsZiwgcm9vdHMsIHNlbGYuc3VibW9kdWxlcywgc2VsZi5pc3BhY2thZ2UpCgogICAgZGVmIHN1Ym1vZHVsZXMoc2VsZiwgKGRpciwgcGFja2FnZSkpOgogICAgICAgIGNoaWxkcmVuID0gW10KICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIGZpbGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW4uYXBwZW5kKChwYXRoLCBwYWNrYWdlKSkKICAgICAgICBjaGlsZHJlbi5zb3J0KCkKICAgICAgICByZXR1cm4gY2hpbGRyZW4KCiAgICBkZWYgaXNwYWNrYWdlKHNlbGYsIChkaXIsIHBhY2thZ2UpKToKICAgICAgICByZXR1cm4gaXNwYWNrYWdlKGRpcikKCiAgICBkZWYgcnVuKHNlbGYsIGtleSwgY2FsbGJhY2ssIGNvbXBsZXRlcj1Ob25lKToKICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgc2VlbiA9IHt9CgogICAgICAgIGZvciBtb2RuYW1lIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSAnX19tYWluX18nOgogICAgICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEKICAgICAgICAgICAgICAgIGRlc2MgPSBzcGxpdChmcmVzaGltcChtb2RuYW1lKS5fX2RvY19fIG9yICcnLCAnXG4nKVswXQogICAgICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwgbG93ZXIoa2V5KSkgPj0gMDoKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhOb25lLCBtb2RuYW1lLCBkZXNjKQoKICAgICAgICB3aGlsZSBub3Qgc2VsZi5xdWl0OgogICAgICAgICAgICBub2RlID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IG5vZGU6IGJyZWFrCiAgICAgICAgICAgIHBhdGgsIHBhY2thZ2UgPSBub2RlCiAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKHBhdGgpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpIGFuZCBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIG1vZG5hbWUKICAgICAgICAgICAgICAgIGlmIG5vdCBzZWVuLmhhc19rZXkobW9kbmFtZSk6CiAgICAgICAgICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEKICAgICAgICAgICAgICAgICAgICBkZXNjID0gc3lub3BzaXMocGF0aCkgb3IgJycKICAgICAgICAgICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZG5hbWUgKyAnIC0gJyArIGRlc2MpLCBsb3dlcihrZXkpKSA+PSAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjKQogICAgICAgIGlmIGNvbXBsZXRlcjogY29tcGxldGVyKCkKCmRlZiBhcHJvcG9zKGtleSk6CiAgICAiIiJQcmludCBhbGwgdGhlIG9uZS1saW5lIG1vZHVsZSBzdW1tYXJpZXMgdGhhdCBjb250YWluIGEgc3Vic3RyaW5nLiIiIgogICAgZGVmIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgIGlmIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgbW9kbmFtZSA9IG1vZG5hbWVbOi05XSArICcgKHBhY2thZ2UpJwogICAgICAgIHByaW50IG1vZG5hbWUsICctJywgZGVzYyBvciAnKG5vIGRlc2NyaXB0aW9uKScKICAgIE1vZHVsZVNjYW5uZXIoKS5ydW4oa2V5LCBjYWxsYmFjaykKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHdlYiBicm93c2VyIGludGVyZmFjZQoKZGVmIHNlcnZlKHBvcnQsIGNhbGxiYWNrPU5vbmUpOgogICAgaW1wb3J0IEJhc2VIVFRQU2VydmVyLCBtaW1ldG9vbHMsIHNlbGVjdAoKICAgICMgUGF0Y2ggdXAgbWltZXRvb2xzLk1lc3NhZ2Ugc28gaXQgZG9lc24ndCBicmVhayBpZiByZmM4MjIgaXMgcmVsb2FkZWQuCiAgICBjbGFzcyBNZXNzYWdlKG1pbWV0b29scy5NZXNzYWdlKToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlPTEpOgogICAgICAgICAgICBNZXNzYWdlID0gc2VsZi5fX2NsYXNzX18KICAgICAgICAgICAgTWVzc2FnZS5fX2Jhc2VzX19bMF0uX19iYXNlc19fWzBdLl9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZSkKICAgICAgICAgICAgc2VsZi5lbmNvZGluZ2hlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nJykKICAgICAgICAgICAgc2VsZi50eXBlaGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHlwZScpCiAgICAgICAgICAgIHNlbGYucGFyc2V0eXBlKCkKICAgICAgICAgICAgc2VsZi5wYXJzZXBsaXN0KCkKCiAgICBjbGFzcyBEb2NIYW5kbGVyKEJhc2VIVFRQU2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIpOgogICAgICAgIGRlZiBzZW5kX2RvY3VtZW50KHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSgyMDApCiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJykKICAgICAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZShodG1sLnBhZ2UodGl0bGUsIGNvbnRlbnRzKSkKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6IHBhc3MKCiAgICAgICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICAgICAgcGF0aCA9IHNlbGYucGF0aAogICAgICAgICAgICBpZiBwYXRoWy01Ol0gPT0gJy5odG1sJzogcGF0aCA9IHBhdGhbOi01XQogICAgICAgICAgICBpZiBwYXRoWzoxXSA9PSAnLyc6IHBhdGggPSBwYXRoWzE6XQogICAgICAgICAgICBpZiBwYXRoIGFuZCBwYXRoICE9ICcuJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwLCB4ID0gbG9jYXRlKHBhdGgpCiAgICAgICAgICAgICAgICBleGNlcHQgRG9jSW1wb3J0RXJyb3IsIHZhbHVlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChwYXRoLCBodG1sLmVzY2FwZShzdHIodmFsdWUpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIHg6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KGRlc2NyaWJlKHgpLCBodG1sLmRvY3VtZW50KHgsIHBhdGgpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwKJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKHBhdGgpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaGVhZGluZyA9IGh0bWwuaGVhZGluZygKJzxiaWc+PGJpZz48c3Ryb25nPlB5dGhvbjogSW5kZXggb2YgTW9kdWxlczwvc3Ryb25nPjwvYmlnPjwvYmlnPicsCicjZmZmZmZmJywgJyM3Nzk5ZWUnKQogICAgICAgICAgICAgICAgZGVmIGJsdGlubGluayhuYW1lKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAobmFtZSwgbmFtZSkKICAgICAgICAgICAgICAgIG5hbWVzID0gZmlsdGVyKGxhbWJkYSB4OiB4ICE9ICdfX21haW5fXycsIHN5cy5idWlsdGluX21vZHVsZV9uYW1lcykKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gaHRtbC5tdWx0aWNvbHVtbihuYW1lcywgYmx0aW5saW5rKQogICAgICAgICAgICAgICAgaW5kaWNlcyA9IFsnPHA+JyArIGh0bWwuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICAgICAnQnVpbHQtaW4gTW9kdWxlcycsICcjZmZmZmZmJywgJyNlZTc3YWEnLCBjb250ZW50cyldCgogICAgICAgICAgICAgICAgIyBmb3Igc2tpcCBpbiBbJycsICcuJywgb3MuZ2V0Y3dkKCksIG9zLnBhdGguZGlybmFtZShzeXMuYXJndlswXSldOgogICAgICAgICAgICAgICAgIyAgICAgaWYgc2tpcCBpbiBzeXMucGF0aDogc3lzLnBhdGgucmVtb3ZlKHNraXApCiAgICAgICAgICAgICAgICBzZWVuID0ge30KICAgICAgICAgICAgICAgIGZvciBkaXIgaW4gcGF0aGRpcnMoKToKICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLmFwcGVuZChodG1sLmluZGV4KGRpciwgc2VlbikpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGhlYWRpbmcgKyBqb2luKGluZGljZXMpICsgJycnPHAgYWxpZ249cmlnaHQ+CjxzbWFsbD48c21hbGw+PGZvbnQgY29sb3I9IiM5MDkwOTAiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzdHJvbmc+CnB5ZG9jPC9zdHJvbmc+IGJ5IEthLVBpbmcgWWVlICZsdDtwaW5nQGxmdy5vcmcmZ3Q7PC9mb250Pjwvc21hbGw+PC9zbWFsbD4nJycKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudCgnSW5kZXggb2YgTW9kdWxlcycsIGNvbnRlbnRzKQoKICAgICAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgKmFyZ3MpOiBwYXNzCgogICAgY2xhc3MgRG9jU2VydmVyKEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwb3J0LCBjYWxsYmFjayk6CiAgICAgICAgICAgIGhvc3QgPSAoc3lzLnBsYXRmb3JtID09ICdtYWMnKSBhbmQgJzEyNy4wLjAuMScgb3IgJ2xvY2FsaG9zdCcKICAgICAgICAgICAgc2VsZi5hZGRyZXNzID0gKCcnLCBwb3J0KQogICAgICAgICAgICBzZWxmLnVybCA9ICdodHRwOi8vJXM6JWQvJyAlIChob3N0LCBwb3J0KQogICAgICAgICAgICBzZWxmLmNhbGxiYWNrID0gY2FsbGJhY2sKICAgICAgICAgICAgc2VsZi5iYXNlLl9faW5pdF9fKHNlbGYsIHNlbGYuYWRkcmVzcywgc2VsZi5oYW5kbGVyKQoKICAgICAgICBkZWYgc2VydmVfdW50aWxfcXVpdChzZWxmKToKICAgICAgICAgICAgaW1wb3J0IHNlbGVjdAogICAgICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgICAgIHdoaWxlIG5vdCBzZWxmLnF1aXQ6CiAgICAgICAgICAgICAgICByZCwgd3IsIGV4ID0gc2VsZWN0LnNlbGVjdChbc2VsZi5zb2NrZXQuZmlsZW5vKCldLCBbXSwgW10sIDEpCiAgICAgICAgICAgICAgICBpZiByZDogc2VsZi5oYW5kbGVfcmVxdWVzdCgpCgogICAgICAgIGRlZiBzZXJ2ZXJfYWN0aXZhdGUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuYmFzZS5zZXJ2ZXJfYWN0aXZhdGUoc2VsZikKICAgICAgICAgICAgaWYgc2VsZi5jYWxsYmFjazogc2VsZi5jYWxsYmFjayhzZWxmKQoKICAgIERvY1NlcnZlci5iYXNlID0gQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcgogICAgRG9jU2VydmVyLmhhbmRsZXIgPSBEb2NIYW5kbGVyCiAgICBEb2NIYW5kbGVyLk1lc3NhZ2VDbGFzcyA9IE1lc3NhZ2UKICAgIHRyeToKICAgICAgICBEb2NTZXJ2ZXIocG9ydCwgY2FsbGJhY2spLnNlcnZlX3VudGlsX3F1aXQoKQogICAgZXhjZXB0IChLZXlib2FyZEludGVycnVwdCwgc2VsZWN0LmVycm9yKToKICAgICAgICBwYXNzCiAgICBwcmludCAnc2VydmVyIHN0b3BwZWQnCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGdyYXBoaWNhbCBpbnRlcmZhY2UKCmRlZiBndWkoKToKICAgICIiIkdyYXBoaWNhbCBpbnRlcmZhY2UgKHN0YXJ0cyB3ZWIgc2VydmVyIGFuZCBwb3BzIHVwIGEgY29udHJvbCB3aW5kb3cpLiIiIgogICAgY2xhc3MgR1VJOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCB3aW5kb3csIHBvcnQ9NzQ2NCk6CiAgICAgICAgICAgIHNlbGYud2luZG93ID0gd2luZG93CiAgICAgICAgICAgIHNlbGYuc2VydmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgICAgICBpbXBvcnQgVGtpbnRlcgogICAgICAgICAgICBzZWxmLnNlcnZlcl9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwgPSBUa2ludGVyLkxhYmVsKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J1N0YXJ0aW5nIHNlcnZlci4uLlxuICcpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdvcGVuIGJyb3dzZXInLCBjb21tYW5kPXNlbGYub3Blbiwgc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5xdWl0X2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J3F1aXQgc2VydmluZycsIGNvbW1hbmQ9c2VsZi5xdWl0LCBzdGF0ZT0nZGlzYWJsZWQnKQoKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibCA9IFRraW50ZXIuTGFiZWwoc2VsZi5zZWFyY2hfZnJtLCB0ZXh0PSdTZWFyY2ggZm9yJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50ID0gVGtpbnRlci5FbnRyeShzZWxmLnNlYXJjaF9mcm0pCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5iaW5kKCc8UmV0dXJuPicsIHNlbGYuc2VhcmNoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZWFyY2hfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nc3RvcCcsIHBhZHk9MCwgY29tbWFuZD1zZWxmLnN0b3AsIHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgICAgICAgICAgIyBUcnlpbmcgdG8gaGlkZSBhbmQgc2hvdyB0aGlzIGJ1dHRvbiBjcmFzaGVzIHVuZGVyIFdpbmRvd3MuCiAgICAgICAgICAgICAgICBzZWxmLnN0b3BfYnRuLnBhY2soc2lkZT0ncmlnaHQnKQoKICAgICAgICAgICAgc2VsZi53aW5kb3cudGl0bGUoJ3B5ZG9jJykKICAgICAgICAgICAgc2VsZi53aW5kb3cucHJvdG9jb2woJ1dNX0RFTEVURV9XSU5ET1cnLCBzZWxmLnF1aXQpCiAgICAgICAgICAgIHNlbGYudGl0bGVfbGJsLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYub3Blbl9idG4ucGFjayhzaWRlPSdsZWZ0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnF1aXRfYnRuLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuc2VydmVyX2ZybS5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQoKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0ucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmZvY3VzX3NldCgpCgogICAgICAgICAgICBmb250ID0gKCdoZWx2ZXRpY2EnLCBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJyBhbmQgOCBvciAxMCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0ID0gVGtpbnRlci5MaXN0Ym94KHdpbmRvdywgZm9udD1mb250LCBoZWlnaHQ9NikKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxCdXR0b24tMT4nLCBzZWxmLnNlbGVjdCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxEb3VibGUtQnV0dG9uLTE+Jywgc2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IgPSBUa2ludGVyLlNjcm9sbGJhcih3aW5kb3csCiAgICAgICAgICAgICAgICBvcmllbnQ9J3ZlcnRpY2FsJywgY29tbWFuZD1zZWxmLnJlc3VsdF9sc3QueXZpZXcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5jb25maWcoeXNjcm9sbGNvbW1hbmQ9c2VsZi5yZXN1bHRfc2NyLnNldCkKCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nZ28gdG8gc2VsZWN0ZWQnLCBjb21tYW5kPXNlbGYuZ290bykKICAgICAgICAgICAgc2VsZi5oaWRlX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYucmVzdWx0X2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J2hpZGUgcmVzdWx0cycsIGNvbW1hbmQ9c2VsZi5oaWRlKQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLnBhY2soc2lkZT0nbGVmdCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5oaWRlX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQoKICAgICAgICAgICAgc2VsZi53aW5kb3cudXBkYXRlKCkKICAgICAgICAgICAgc2VsZi5taW53aWR0aCA9IHNlbGYud2luZG93LndpbmZvX3dpZHRoKCkKICAgICAgICAgICAgc2VsZi5taW5oZWlnaHQgPSBzZWxmLndpbmRvdy53aW5mb19oZWlnaHQoKQogICAgICAgICAgICBzZWxmLmJpZ21pbmhlaWdodCA9IChzZWxmLnNlcnZlcl9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3Qud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkpCiAgICAgICAgICAgIHNlbGYuYmlnd2lkdGgsIHNlbGYuYmlnaGVpZ2h0ID0gc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDAKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpCgogICAgICAgICAgICBpbXBvcnQgdGhyZWFkaW5nCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNlcnZlLCBhcmdzPShwb3J0LCBzZWxmLnJlYWR5KSkuc3RhcnQoKQoKICAgICAgICBkZWYgcmVhZHkoc2VsZiwgc2VydmVyKToKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBzZXJ2ZXIKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwuY29uZmlnKAogICAgICAgICAgICAgICAgdGV4dD0nUHl0aG9uIGRvY3VtZW50YXRpb24gc2VydmVyIGF0XG4nICsgc2VydmVyLnVybCkKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgb3BlbihzZWxmLCBldmVudD1Ob25lLCB1cmw9Tm9uZSk6CiAgICAgICAgICAgIHVybCA9IHVybCBvciBzZWxmLnNlcnZlci51cmwKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgICAgIHdlYmJyb3dzZXIub3Blbih1cmwpCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjogIyBwcmUtd2ViYnJvd3Nlci5weSBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgICAgICBvcy5zeXN0ZW0oJ3N0YXJ0ICIlcyInICUgdXJsKQogICAgICAgICAgICAgICAgZWxpZiBzeXMucGxhdGZvcm0gPT0gJ21hYyc6CiAgICAgICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgICAgICBpbXBvcnQgaWMKICAgICAgICAgICAgICAgICAgICAgICAgaWMubGF1bmNodXJsKHVybCkKICAgICAgICAgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6IHBhc3MKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmMgPSBvcy5zeXN0ZW0oJ25ldHNjYXBlIC1yZW1vdGUgIm9wZW5VUkwoJXMpIiAmJyAlIHVybCkKICAgICAgICAgICAgICAgICAgICBpZiByYzogb3Muc3lzdGVtKCduZXRzY2FwZSAiJXMiICYnICUgdXJsKQoKICAgICAgICBkZWYgcXVpdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zZXJ2ZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNlcnZlci5xdWl0ID0gMQogICAgICAgICAgICBzZWxmLndpbmRvdy5xdWl0KCkKCiAgICAgICAgZGVmIHNlYXJjaChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAga2V5ID0gc2VsZi5zZWFyY2hfZW50LmdldCgpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwuY29uZmlnKHRleHQ9J1NlYXJjaGluZyBmb3IgIiVzIi4uLicgJSBrZXkpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmRlbGV0ZSgwLCAnZW5kJykKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgc2VsZi5leHBhbmQoKQoKICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZwogICAgICAgICAgICBpZiBzZWxmLnNjYW5uZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIucXVpdCA9IDEKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTW9kdWxlU2Nhbm5lcigpCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNlbGYuc2Nhbm5lci5ydW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncz0oa2V5LCBzZWxmLnVwZGF0ZSwgc2VsZi5kb25lKSkuc3RhcnQoKQoKICAgICAgICBkZWYgdXBkYXRlKHNlbGYsIHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgICAgICBpZiBtb2RuYW1lWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5pbnNlcnQoJ2VuZCcsCiAgICAgICAgICAgICAgICBtb2RuYW1lICsgJyAtICcgKyAoZGVzYyBvciAnKG5vIGRlc2NyaXB0aW9uKScpKQoKICAgICAgICBkZWYgc3RvcChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaWYgc2VsZi5zY2FubmVyOgogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyLnF1aXQgPSAxCiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCgogICAgICAgIGRlZiBkb25lKHNlbGYpOgogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5jb25maWcodGV4dD0nU2VhcmNoIGZvcicpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtICE9ICd3aW4zMic6IHNlbGYuc3RvcF9idG4uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5jb25maWcoc3RhdGU9J2Rpc2FibGVkJykKCiAgICAgICAgZGVmIHNlbGVjdChzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCgogICAgICAgIGRlZiBnb3RvKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxlY3Rpb24gPSBzZWxmLnJlc3VsdF9sc3QuY3Vyc2VsZWN0aW9uKCkKICAgICAgICAgICAgaWYgc2VsZWN0aW9uOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHNwbGl0KHNlbGYucmVzdWx0X2xzdC5nZXQoc2VsZWN0aW9uWzBdKSlbMF0KICAgICAgICAgICAgICAgIHNlbGYub3Blbih1cmw9c2VsZi5zZXJ2ZXIudXJsICsgbW9kbmFtZSArICcuaHRtbCcpCgogICAgICAgIGRlZiBjb2xsYXBzZShzZWxmKToKICAgICAgICAgICAgaWYgbm90IHNlbGYuZXhwYW5kZWQ6IHJldHVybgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0uZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLmJpZ3dpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLmJpZ2hlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAoKICAgICAgICBkZWYgZXhwYW5kKHNlbGYpOgogICAgICAgICAgICBpZiBzZWxmLmV4cGFuZGVkOiByZXR1cm4KICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLnBhY2soc2lkZT0nYm90dG9tJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3Njci5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neScpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J2JvdGgnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLmJpZ3dpZHRoLCBzZWxmLmJpZ2hlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAxCgogICAgICAgIGRlZiBoaWRlKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxmLnN0b3AoKQogICAgICAgICAgICBzZWxmLmNvbGxhcHNlKCkKCiAgICBpbXBvcnQgVGtpbnRlcgogICAgdHJ5OgogICAgICAgIGd1aSA9IEdVSShUa2ludGVyLlRrKCkpCiAgICAgICAgVGtpbnRlci5tYWlubG9vcCgpCiAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CiAgICAgICAgcGFzcwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tYW5kLWxpbmUgaW50ZXJmYWNlCgpkZWYgaXNwYXRoKHgpOgogICAgcmV0dXJuIHR5cGUoeCkgaXMgdHlwZXMuU3RyaW5nVHlwZSBhbmQgZmluZCh4LCBvcy5zZXApID49IDAKCmRlZiBjbGkoKToKICAgICIiIkNvbW1hbmQtbGluZSBpbnRlcmZhY2UgKGxvb2tzIGF0IHN5cy5hcmd2IHRvIGRlY2lkZSB3aGF0IHRvIGRvKS4iIiIKICAgIGltcG9ydCBnZXRvcHQKICAgIGNsYXNzIEJhZFVzYWdlOiBwYXNzCgogICAgdHJ5OgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSBpbiBbJ21hYycsICd3aW4zMiddIGFuZCBub3Qgc3lzLmFyZ3ZbMTpdOgogICAgICAgICAgICAjIGdyYXBoaWNhbCBwbGF0Zm9ybXMgd2l0aCB0aHJlYWRpbmcgKGFuZCBubyBDTEkpCiAgICAgICAgICAgIGd1aSgpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBvcHRzLCBhcmdzID0gZ2V0b3B0LmdldG9wdChzeXMuYXJndlsxOl0sICdnazpwOncnKQogICAgICAgIHdyaXRpbmcgPSAwCgogICAgICAgIGZvciBvcHQsIHZhbCBpbiBvcHRzOgogICAgICAgICAgICBpZiBvcHQgPT0gJy1nJzoKICAgICAgICAgICAgICAgIGd1aSgpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctayc6CiAgICAgICAgICAgICAgICBhcHJvcG9zKHZhbCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy1wJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBwb3J0ID0gaW50KHZhbCkKICAgICAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEJhZFVzYWdlCiAgICAgICAgICAgICAgICBkZWYgcmVhZHkoc2VydmVyKToKICAgICAgICAgICAgICAgICAgICBwcmludCAnc2VydmVyIHJlYWR5IGF0ICVzJyAlIHNlcnZlci51cmwKICAgICAgICAgICAgICAgIHNlcnZlKHBvcnQsIHJlYWR5KQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXcnOgogICAgICAgICAgICAgICAgd3JpdGluZyA9IDEKCiAgICAgICAgaWYgbm90IGFyZ3M6IHJhaXNlIEJhZFVzYWdlCiAgICAgICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpZiBpc3BhdGgoYXJnKSBhbmQgb3MucGF0aC5pc2ZpbGUoYXJnKToKICAgICAgICAgICAgICAgICAgICBhcmcgPSBpbXBvcnRmaWxlKGFyZykKICAgICAgICAgICAgICAgIGlmIHdyaXRpbmc6CiAgICAgICAgICAgICAgICAgICAgaWYgaXNwYXRoKGFyZykgYW5kIG9zLnBhdGguaXNkaXIoYXJnKToKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2NzKGFyZykKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZWRvYyhhcmcpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG1hbihhcmcpCiAgICAgICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgICAgICBwcmludCB2YWx1ZQoKICAgIGV4Y2VwdCAoZ2V0b3B0LmVycm9yLCBCYWRVc2FnZSk6CiAgICAgICAgY21kID0gc3lzLmFyZ3ZbMF0KICAgICAgICBwcmludCAiIiJweWRvYyAtIHRoZSBQeXRob24gZG9jdW1lbnRhdGlvbiB0b29sCgolcyA8bmFtZT4gLi4uCiAgICBTaG93IHRleHQgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlIHRoZSBuYW1lIG9mIGEKICAgIGZ1bmN0aW9uLCBtb2R1bGUsIG9yIHBhY2thZ2UsIG9yIGEgZG90dGVkIHJlZmVyZW5jZSB0byBhIGNsYXNzIG9yCiAgICBmdW5jdGlvbiB3aXRoaW4gYSBtb2R1bGUgb3IgbW9kdWxlIGluIGEgcGFja2FnZS4gIElmIDxuYW1lPiBjb250YWlucwogICAgYSAnJXMnLCBpdCBpcyB1c2VkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlIHRvIGRvY3VtZW50LgoKJXMgLWsgPGtleXdvcmQ+CiAgICBTZWFyY2ggZm9yIGEga2V5d29yZCBpbiB0aGUgc3lub3BzaXMgbGluZXMgb2YgYWxsIGF2YWlsYWJsZSBtb2R1bGVzLgoKJXMgLXAgPHBvcnQ+CiAgICBTdGFydCBhbiBIVFRQIHNlcnZlciBvbiB0aGUgZ2l2ZW4gcG9ydCBvbiB0aGUgbG9jYWwgbWFjaGluZS4KCiVzIC1nCiAgICBQb3AgdXAgYSBncmFwaGljYWwgaW50ZXJmYWNlIGZvciBzZXJ2aW5nIGFuZCBmaW5kaW5nIGRvY3VtZW50YXRpb24uCgolcyAtdyA8bmFtZT4gLi4uCiAgICBXcml0ZSBvdXQgdGhlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUgdG8gYSBmaWxlIGluIHRoZSBjdXJyZW50CiAgICBkaXJlY3RvcnkuICBJZiA8bmFtZT4gY29udGFpbnMgYSAnJXMnLCBpdCBpcyB0cmVhdGVkIGFzIGEgZmlsZW5hbWUuCiIiIiAlIChjbWQsIG9zLnNlcCwgY21kLCBjbWQsIGNtZCwgY21kLCBvcy5zZXApCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOiBjbGkoKQo=