IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCkF0IHRoZSBzaGVsbCBjb21tYW5kIGxpbmUgb3V0c2lkZSBvZiBQeXRob246CiAgICBSdW4gInB5ZG9jIDxuYW1lPiIgdG8gc2hvdyBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4gIDxuYW1lPiBtYXkgYmUKICAgIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKICAgIGNsYXNzIG9yIGZ1bmN0aW9uIHdpdGhpbiBhIG1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgSWYgdGhlCiAgICBhcmd1bWVudCBjb250YWlucyBhIHBhdGggc2VnbWVudCBkZWxpbWl0ZXIgKGUuZy4gc2xhc2ggb24gVW5peCwKICAgIGJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKICAgIFJ1biAicHlkb2MgLWsgPGtleXdvcmQ+IiB0byBzZWFyY2ggZm9yIGEga2V5d29yZCBpbiB0aGUgc3lub3BzaXMgbGluZXMKICAgIG9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KCiAgICBSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQogICAgbG9jYWwgbWFjaGluZSB0byBnZW5lcmF0ZSBkb2N1bWVudGF0aW9uIHdlYiBwYWdlcy4KCiAgICBGb3IgcGxhdGZvcm1zIHdpdGhvdXQgYSBjb21tYW5kIGxpbmUsICJweWRvYyAtZyIgc3RhcnRzIHRoZSBIVFRQIHNlcnZlcgogICAgYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKICAgIFJ1biAicHlkb2MgLXcgPG5hbWU+IiB0byB3cml0ZSBvdXQgdGhlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBtb2R1bGUKICAgIHRvIGEgZmlsZSBuYW1lZCAiPG5hbWU+Lmh0bWwiLgoiIiIKCl9fYXV0aG9yX18gPSAiS2EtUGluZyBZZWUgPHBpbmdAbGZ3Lm9yZz4iCl9fZGF0ZV9fID0gIjI2IEZlYnJ1YXJ5IDIwMDEiCl9fdmVyc2lvbl9fID0gIiRSZXZpc2lvbiQiCl9fY3JlZGl0c19fID0gIiIiR3VpZG8gdmFuIFJvc3N1bSwgZm9yIGFuIGV4Y2VsbGVudCBwcm9ncmFtbWluZyBsYW5ndWFnZS4KVG9tbXkgQnVybmV0dGUsIHRoZSBvcmlnaW5hbCBjcmVhdG9yIG9mIG1hbnB5LgpQYXVsIFByZXNjb2QsIGZvciBhbGwgaGlzIHdvcmsgb24gb25saW5laGVscC4KUmljaGFyZCBDaGFtYmVybGFpbiwgZm9yIHRoZSBmaXJzdCBpbXBsZW1lbnRhdGlvbiBvZiB0ZXh0ZG9jLgoKTXluZCB5b3UsIG34+HNlIGJpdGVzIEthbiBiZSBwcmV0dHkgbmFzdGkuLi4iIiIKCiMgTm90ZTogdGhpcyBtb2R1bGUgaXMgZGVzaWduZWQgdG8gZGVwbG95IGluc3RhbnRseSBhbmQgcnVuIHVuZGVyIGFueQojIHZlcnNpb24gb2YgUHl0aG9uIGZyb20gMS41IGFuZCB1cC4gIFRoYXQncyB3aHkgaXQncyBhIHNpbmdsZSBmaWxlIGFuZAojIHNvbWUgMi4wIGZlYXR1cmVzIChsaWtlIHN0cmluZyBtZXRob2RzKSBhcmUgY29uc3BpY3VvdXNseSBhdm9pZGVkLgoKaW1wb3J0IHN5cywgaW1wLCBvcywgc3RhdCwgcmUsIHR5cGVzLCBpbnNwZWN0CmZyb20gcmVwciBpbXBvcnQgUmVwcgpmcm9tIHN0cmluZyBpbXBvcnQgZXhwYW5kdGFicywgZmluZCwgam9pbiwgbG93ZXIsIHNwbGl0LCBzdHJpcCwgcnN0cmlwCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb21tb24gcm91dGluZXMKCmRlZiBzeW5vcHNpcyhmaWxlbmFtZSwgY2FjaGU9e30pOgogICAgIiIiR2V0IHRoZSBvbmUtbGluZSBzdW1tYXJ5IG91dCBvZiBhIG1vZHVsZSBmaWxlLiIiIgogICAgbXRpbWUgPSBvcy5zdGF0KGZpbGVuYW1lKVtzdGF0LlNUX01USU1FXQogICAgbGFzdHVwZGF0ZSwgcmVzdWx0ID0gY2FjaGUuZ2V0KGZpbGVuYW1lLCAoMCwgTm9uZSkpCiAgICBpZiBsYXN0dXBkYXRlIDwgbXRpbWU6CiAgICAgICAgZmlsZSA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgIHdoaWxlIGxpbmVbOjFdID09ICcjJyBvciBzdHJpcChsaW5lKSA9PSAnJzoKICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICBpZiBub3QgbGluZTogYnJlYWsKICAgICAgICBpZiBsaW5lWy0yOl0gPT0gJ1xcXG4nOgogICAgICAgICAgICBsaW5lID0gbGluZVs6LTJdICsgZmlsZS5yZWFkbGluZSgpCiAgICAgICAgbGluZSA9IHN0cmlwKGxpbmUpCiAgICAgICAgaWYgbGluZVs6M10gPT0gJyIiIic6CiAgICAgICAgICAgIGxpbmUgPSBsaW5lWzM6XQogICAgICAgICAgICB3aGlsZSBzdHJpcChsaW5lKSA9PSAnJzoKICAgICAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICByZXN1bHQgPSBzcGxpdChsaW5lLCAnIiIiJylbMF0KICAgICAgICBlbHNlOiByZXN1bHQgPSBOb25lCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgY2FjaGVbZmlsZW5hbWVdID0gKG10aW1lLCByZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0CgpkZWYgcGF0aGRpcnMoKToKICAgICIiIkNvbnZlcnQgc3lzLnBhdGggaW50byBhIGxpc3Qgb2YgYWJzb2x1dGUsIGV4aXN0aW5nLCB1bmlxdWUgcGF0aHMuIiIiCiAgICBkaXJzID0gW10KICAgIG5vcm1kaXJzID0gW10KICAgIGZvciBkaXIgaW4gc3lzLnBhdGg6CiAgICAgICAgZGlyID0gb3MucGF0aC5hYnNwYXRoKGRpciBvciAnLicpCiAgICAgICAgbm9ybWRpciA9IG9zLnBhdGgubm9ybWNhc2UoZGlyKQogICAgICAgIGlmIG5vcm1kaXIgbm90IGluIG5vcm1kaXJzIGFuZCBvcy5wYXRoLmlzZGlyKGRpcik6CiAgICAgICAgICAgIGRpcnMuYXBwZW5kKGRpcikKICAgICAgICAgICAgbm9ybWRpcnMuYXBwZW5kKG5vcm1kaXIpCiAgICByZXR1cm4gZGlycwoKZGVmIGdldGRvYyhvYmplY3QpOgogICAgIiIiR2V0IHRoZSBkb2Mgc3RyaW5nIG9yIGNvbW1lbnRzIGZvciBhbiBvYmplY3QuIiIiCiAgICByZXN1bHQgPSBpbnNwZWN0LmdldGRvYyhvYmplY3QpCiAgICBpZiBub3QgcmVzdWx0OgogICAgICAgIHRyeTogcmVzdWx0ID0gaW5zcGVjdC5nZXRjb21tZW50cyhvYmplY3QpCiAgICAgICAgZXhjZXB0OiBwYXNzCiAgICByZXR1cm4gcmVzdWx0IGFuZCByc3RyaXAocmVzdWx0KSBvciAnJwoKZGVmIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpOgogICAgIiIiR2V0IGEgY2xhc3MgbmFtZSBhbmQgcXVhbGlmeSBpdCB3aXRoIGEgbW9kdWxlIG5hbWUgaWYgbmVjZXNzYXJ5LiIiIgogICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgaWYgb2JqZWN0Ll9fbW9kdWxlX18gIT0gbW9kbmFtZToKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbW9kdWxlX18gKyAnLicgKyBuYW1lCiAgICByZXR1cm4gbmFtZQoKZGVmIGlzY29uc3RhbnQob2JqZWN0KToKICAgICIiIkNoZWNrIGlmIGFuIG9iamVjdCBpcyBvZiBhIHR5cGUgdGhhdCBwcm9iYWJseSBtZWFucyBpdCdzIGEgY29uc3RhbnQuIiIiCiAgICByZXR1cm4gdHlwZShvYmplY3QpIGluIFsKICAgICAgICB0eXBlcy5GbG9hdFR5cGUsIHR5cGVzLkludFR5cGUsIHR5cGVzLkxpc3RUeXBlLCB0eXBlcy5Mb25nVHlwZSwKICAgICAgICB0eXBlcy5TdHJpbmdUeXBlLCB0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLlR5cGVUeXBlLAogICAgICAgIGhhc2F0dHIodHlwZXMsICdVbmljb2RlVHlwZScpIGFuZCB0eXBlcy5Vbmljb2RlVHlwZSBvciAwXQoKZGVmIHJlcGxhY2UodGV4dCwgKnBhaXJzKToKICAgICIiIkRvIGEgc2VyaWVzIG9mIGdsb2JhbCByZXBsYWNlbWVudHMgb24gYSBzdHJpbmcuIiIiCiAgICBmb3Igb2xkLCBuZXcgaW4gcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgb2xkKSwgbmV3KQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIHN0cmlwaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgIyBUaGUgYmVoYXZpb3VyIG9mICVwIGlzIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudCwgc28gd2UgbmVlZCBhbiBleGFtcGxlLgogICAgZm9yIHBhdHRlcm4gaW4gWycgYXQgMHhbMC05YS1mXXs2LH0+JCcsICcgYXQgWzAtOUEtRl17OCx9PiQnXToKICAgICAgICBpZiByZS5zZWFyY2gocGF0dGVybiwgcmVwcihFeGNlcHRpb24pKToKICAgICAgICAgICAgcmV0dXJuIHJlLnN1YihwYXR0ZXJuLCAnPicsIHRleHQpCiAgICByZXR1cm4gdGV4dAoKZGVmIG1vZHVsZW5hbWUocGF0aCk6CiAgICAiIiJSZXR1cm4gdGhlIFB5dGhvbiBtb2R1bGUgbmFtZSBmb3IgYSBnaXZlbiBwYXRoLCBvciBOb25lLiIiIgogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBpZiBsb3dlcihmaWxlbmFtZVstMzpdKSA9PSAnLnB5JzoKICAgICAgICByZXR1cm4gZmlsZW5hbWVbOi0zXQogICAgZWxpZiBsb3dlcihmaWxlbmFtZVstNDpdKSBpbiBbJy5weWMnLCAnLnB5ZCcsICcucHlvJ106CiAgICAgICAgcmV0dXJuIGZpbGVuYW1lWzotNF0KICAgIGVsaWYgbG93ZXIoZmlsZW5hbWVbLTExOl0pID09ICdtb2R1bGUuc28nOgogICAgICAgIHJldHVybiBmaWxlbmFtZVs6LTExXQogICAgZWxpZiBsb3dlcihmaWxlbmFtZVstMTM6XSkgPT0gJ21vZHVsZS5zby4xJzoKICAgICAgICByZXR1cm4gZmlsZW5hbWVbOi0xM10KCmNsYXNzIERvY0ltcG9ydEVycm9yKEV4Y2VwdGlvbik6CiAgICAiIiJDbGFzcyBmb3IgZXJyb3JzIHdoaWxlIHRyeWluZyB0byBpbXBvcnQgc29tZXRoaW5nIHRvIGRvY3VtZW50IGl0LiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGVuYW1lLCBldHlwZSwgZXZhbHVlKToKICAgICAgICBzZWxmLmZpbGVuYW1lID0gZmlsZW5hbWUKICAgICAgICBzZWxmLmV0eXBlID0gZXR5cGUKICAgICAgICBzZWxmLmV2YWx1ZSA9IGV2YWx1ZQogICAgICAgIGlmIHR5cGUoZXR5cGUpIGlzIHR5cGVzLkNsYXNzVHlwZToKICAgICAgICAgICAgZXR5cGUgPSBldHlwZS5fX25hbWVfXwogICAgICAgIHNlbGYuYXJncyA9ICclczogJXMnICUgKGV0eXBlLCBldmFsdWUpCgpkZWYgaW1wb3J0ZmlsZShwYXRoKToKICAgICIiIkltcG9ydCBhIFB5dGhvbiBzb3VyY2UgZmlsZSBvciBjb21waWxlZCBmaWxlIGdpdmVuIGl0cyBwYXRoLiIiIgogICAgbWFnaWMgPSBpbXAuZ2V0X21hZ2ljKCkKICAgIGZpbGUgPSBvcGVuKHBhdGgsICdyJykKICAgIGlmIGZpbGUucmVhZChsZW4obWFnaWMpKSA9PSBtYWdpYzoKICAgICAgICBraW5kID0gaW1wLlBZX0NPTVBJTEVECiAgICBlbHNlOgogICAgICAgIGtpbmQgPSBpbXAuUFlfU09VUkNFCiAgICBmaWxlLmNsb3NlKCkKICAgIGZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShwYXRoKQogICAgbmFtZSwgZXh0ID0gb3MucGF0aC5zcGxpdGV4dChmaWxlbmFtZSkKICAgIGZpbGUgPSBvcGVuKHBhdGgsICdyJykKICAgIHRyeToKICAgICAgICBtb2R1bGUgPSBpbXAubG9hZF9tb2R1bGUobmFtZSwgZmlsZSwgcGF0aCwgKGV4dCwgJ3InLCBraW5kKSkKICAgIGV4Y2VwdDoKICAgICAgICByYWlzZSBEb2NJbXBvcnRFcnJvcihwYXRoLCBzeXMuZXhjX3R5cGUsIHN5cy5leGNfdmFsdWUpCiAgICBmaWxlLmNsb3NlKCkKICAgIHJldHVybiBtb2R1bGUKCmRlZiBpc3BhY2thZ2UocGF0aCk6CiAgICAiIiJHdWVzcyB3aGV0aGVyIGEgcGF0aCByZWZlcnMgdG8gYSBwYWNrYWdlIGRpcmVjdG9yeS4iIiIKICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCk6CiAgICAgICAgaW5pdCA9IG9zLnBhdGguam9pbihwYXRoLCAnX19pbml0X18ucHknKQogICAgICAgIGluaXRjID0gb3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXy5weWMnKQogICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKGluaXQpIG9yIG9zLnBhdGguaXNmaWxlKGluaXRjKToKICAgICAgICAgICAgcmV0dXJuIDEKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBmb3JtYXR0ZXIgYmFzZSBjbGFzcwoKY2xhc3MgRG9jOgogICAgZGVmIGRvY3VtZW50KHNlbGYsIG9iamVjdCwgKmFyZ3MpOgogICAgICAgICIiIkdlbmVyYXRlIGRvY3VtZW50YXRpb24gZm9yIGFuIG9iamVjdC4iIiIKICAgICAgICBhcmdzID0gKG9iamVjdCwpICsgYXJncwogICAgICAgIGlmIGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbW9kdWxlLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2NjbGFzcywgYXJncykKICAgICAgICBpZiBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Nyb3V0aW5lLCBhcmdzKQogICAgICAgIHJhaXNlIFR5cGVFcnJvciwgImRvbid0IGtub3cgaG93IHRvIGRvY3VtZW50IG9iamVjdHMgb2YgdHlwZSAiICsgXAogICAgICAgICAgICB0eXBlKG9iamVjdCkuX19uYW1lX18KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gNTAKCiAgICBkZWYgZXNjYXBlKHNlbGYsIHRleHQpOgogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnJicsICcmYW1wOycpLCAoJzwnLCAnJmx0OycpLCAoJz4nLCAnJmd0OycpKQoKICAgIGRlZiByZXByKHNlbGYsIG9iamVjdCk6CiAgICAgICAgcmVzdWx0ID0gUmVwci5yZXByKHNlbGYsIG9iamVjdCkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKSkKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShjcmFtKHgsIHNlbGYubWF4c3RyaW5nKSkKICAgICAgICByZXR1cm4gcmUuc3ViKHInKChcXFtcXGFiZm5ydHZdfFxceC4ufFxcdS4uLi4pKyknLAogICAgICAgICAgICAgICAgICAgICAgcic8Zm9udCBjb2xvcj0iI2MwNDBjMCI+XDE8L2ZvbnQ+JywgcmVwcih0ZXh0KSkKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmVzY2FwZSgnPCVzIGluc3RhbmNlPicgJSB4Ll9fY2xhc3NfXy5fX25hbWVfXykKCiAgICByZXByX3VuaWNvZGUgPSByZXByX3N0cmluZwoKY2xhc3MgSFRNTERvYyhEb2MpOgogICAgIiIiRm9ybWF0dGVyIGNsYXNzIGZvciBIVE1MIGRvY3VtZW50YXRpb24uIiIiCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhUTUwgZm9ybWF0dGluZyB1dGlsaXRpZXMKCiAgICBfcmVwcl9pbnN0YW5jZSA9IEhUTUxSZXByKCkKICAgIHJlcHIgPSBfcmVwcl9pbnN0YW5jZS5yZXByCiAgICBlc2NhcGUgPSBfcmVwcl9pbnN0YW5jZS5lc2NhcGUKCiAgICBkZWYgcHJlZm9ybWF0KHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBsaXRlcmFsIHByZWZvcm1hdHRlZCB0ZXh0LiIiIgogICAgICAgIHRleHQgPSBzZWxmLmVzY2FwZShleHBhbmR0YWJzKHRleHQpKQogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICgnXG5cbicsICdcbiBcbicpLCAoJ1xuXG4nLCAnXG4gXG4nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJyAnLCAnJm5ic3A7JyksICgnXG4nLCAnPGJyPlxuJykpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwoKICAgICAgICBmb3IgY29sIGluIHJhbmdlKGNvbHMpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHRkIHdpZHRoPSIlZCUlIiB2YWxpZ249dG9wPicgJSAoMTAwL2NvbHMpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKHJvd3MqY29sLCByb3dzKmNvbCtyb3dzKToKICAgICAgICAgICAgICAgIGlmIGkgPCBsZW4obGlzdCk6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgZm9ybWF0KGxpc3RbaV0pICsgJzxicj4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8L3RkPicKICAgICAgICByZXR1cm4gJzx0YWJsZSB3aWR0aD0iMTAwJSUiPjx0cj4lczwvdHI+PC90YWJsZT4nICUgcmVzdWx0CgogICAgZGVmIGhlYWRpbmcoc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgZXh0cmFzPScnKToKICAgICAgICAiIiJGb3JtYXQgYSBwYWdlIGhlYWRpbmcuIiIiCiAgICAgICAgcmV0dXJuICIiIgo8cD48dGFibGUgd2lkdGg9IjEwMCUlIiBjZWxsc3BhY2luZz0wIGNlbGxwYWRkaW5nPTAgYm9yZGVyPTA+Cjx0ciBiZ2NvbG9yPSIlcyI+PHRkPiZuYnNwOzwvdGQ+Cjx0ZCB2YWxpZ249Ym90dG9tPjxzbWFsbD48c21hbGw+PGJyPjwvc21hbGw+PC9zbWFsbAo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EiPjxicj4mbmJzcDslczwvZm9udD48L3RkCj48dGQgYWxpZ249cmlnaHQgdmFsaWduPWJvdHRvbQo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EiPiVzPC9mb250PjwvdGQ+PHRkPiZuYnNwOzwvdGQ+PC90cj48L3RhYmxlPgogICAgIiIiICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUsIGZnY29sLCBleHRyYXMgb3IgJyZuYnNwOycpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgY29udGVudHMsIHdpZHRoPTIwLAogICAgICAgICAgICAgICAgcHJlbHVkZT0nJywgbWFyZ2luYWxpYT1Ob25lLCBnYXA9JyZuYnNwOyZuYnNwOyZuYnNwOycpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGhlYWRpbmcuIiIiCiAgICAgICAgaWYgbWFyZ2luYWxpYSBpcyBOb25lOgogICAgICAgICAgICBtYXJnaW5hbGlhID0gJyZuYnNwOycgKiB3aWR0aAogICAgICAgIHJlc3VsdCA9ICIiIgo8cD48dGFibGUgd2lkdGg9IjEwMCUlIiBjZWxsc3BhY2luZz0wIGNlbGxwYWRkaW5nPTAgYm9yZGVyPTA+Cjx0ciBiZ2NvbG9yPSIlcyI+PHRkIHJvd3NwYW49Mj4mbmJzcDs8L3RkPgo8dGQgY29sc3Bhbj0zIHZhbGlnbj1ib3R0b20+PHNtYWxsPjxzbWFsbD48YnI+PC9zbWFsbD48L3NtYWxsCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiZuYnNwOyVzPC9mb250PjwvdGQ+PC90cj4KICAgICIiIiAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlKQogICAgICAgIGlmIHByZWx1ZGU6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICIiIgo8dHI+PHRkIGJnY29sb3I9IiVzIj4lczwvdGQ+Cjx0ZCBiZ2NvbG9yPSIlcyIgY29sc3Bhbj0yPiVzPC90ZD48L3RyPgogICAgIiIiICUgKGJnY29sLCBtYXJnaW5hbGlhLCBiZ2NvbCwgcHJlbHVkZSkKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAiIiIKPHRyPjx0ZCBiZ2NvbG9yPSIlcyI+JXM8L3RkPjx0ZD4lczwvdGQ+CiAgICAiIiIgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIGdhcCkKCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzx0ZCB3aWR0aD0iMTAwJSUiPiVzPC90ZD48L3RyPjwvdGFibGU+JyAlIGNvbnRlbnRzCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBiaWdzZWN0aW9uKHNlbGYsIHRpdGxlLCAqYXJncyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgYmlnIGhlYWRpbmcuIiIiCiAgICAgICAgdGl0bGUgPSAnPGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+JyAlIHRpdGxlCiAgICAgICAgcmV0dXJuIGFwcGx5KHNlbGYuc2VjdGlvbiwgKHRpdGxlLCkgKyBhcmdzKQoKICAgIGRlZiBuYW1lbGluayhzZWxmLCBuYW1lLCAqZGljdHMpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhbiBpZGVudGlmaWVyLCBnaXZlbiBuYW1lLXRvLVVSTCBtYXBwaW5ncy4iIiIKICAgICAgICBmb3IgZGljdCBpbiBkaWN0czoKICAgICAgICAgICAgaWYgZGljdC5oYXNfa2V5KG5hbWUpOgogICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlIChkaWN0W25hbWVdLCBuYW1lKQogICAgICAgIHJldHVybiBuYW1lCgogICAgZGVmIGNsYXNzbGluayhzZWxmLCBvYmplY3QsIG1vZG5hbWUsICpkaWN0cyk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgY2xhc3MuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGlmIG9iamVjdC5fX21vZHVsZV9fICE9IG1vZG5hbWU6CiAgICAgICAgICAgIG5hbWUgPSBvYmplY3QuX19tb2R1bGVfXyArICcuJyArIG5hbWUKICAgICAgICBmb3IgZGljdCBpbiBkaWN0czoKICAgICAgICAgICAgaWYgZGljdC5oYXNfa2V5KG9iamVjdCk6CiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGRpY3Rbb2JqZWN0XSwgbmFtZSkKICAgICAgICByZXR1cm4gbmFtZQoKICAgIGRlZiBtb2R1bGVsaW5rKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlLiIiIgogICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMuaHRtbCI+JXM8L2E+JyAlIChvYmplY3QuX19uYW1lX18sIG9iamVjdC5fX25hbWVfXykKCiAgICBkZWYgbW9kcGtnbGluayhzZWxmLCAobmFtZSwgcGF0aCwgaXNwYWNrYWdlLCBzaGFkb3dlZCkpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIG1vZHVsZSBvciBwYWNrYWdlIHRvIGRpc3BsYXkgaW4gYW4gaW5kZXguIiIiCiAgICAgICAgaWYgc2hhZG93ZWQ6CiAgICAgICAgICAgIHJldHVybiAnPGZvbnQgY29sb3I9IiM5MDkwOTAiPiVzPC9mb250PicgJSBuYW1lCiAgICAgICAgaWYgcGF0aDoKICAgICAgICAgICAgdXJsID0gJyVzLiVzLmh0bWwnICUgKHBhdGgsIG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdXJsID0gJyVzLmh0bWwnICUgbmFtZQogICAgICAgIGlmIGlzcGFja2FnZToKICAgICAgICAgICAgdGV4dCA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+Jm5ic3A7KHBhY2thZ2UpJyAlIG5hbWUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0ZXh0ID0gbmFtZQogICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAodXJsLCB0ZXh0KQoKICAgIGRlZiBtYXJrdXAoc2VsZiwgdGV4dCwgZXNjYXBlPU5vbmUsIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9KToKICAgICAgICAiIiJNYXJrIHVwIHNvbWUgcGxhaW4gdGV4dCwgZ2l2ZW4gYSBjb250ZXh0IG9mIHN5bWJvbHMgdG8gbG9vayBmb3IuCiAgICAgICAgRWFjaCBjb250ZXh0IGRpY3Rpb25hcnkgbWFwcyBvYmplY3QgbmFtZXMgdG8gYW5jaG9yIG5hbWVzLiIiIgogICAgICAgIGVzY2FwZSA9IGVzY2FwZSBvciBzZWxmLmVzY2FwZQogICAgICAgIHJlc3VsdHMgPSBbXQogICAgICAgIGhlcmUgPSAwCiAgICAgICAgcGF0dGVybiA9IHJlLmNvbXBpbGUocidcYigoKGh0dHB8ZnRwKTovL1xTK1tcdy9dKXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcicoUkZDWy0gXT8oXGQrKSl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInKHNlbGZcLik/KFx3KykpXGInKQogICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgIG1hdGNoID0gcGF0dGVybi5zZWFyY2godGV4dCwgaGVyZSkKICAgICAgICAgICAgaWYgbm90IG1hdGNoOiBicmVhawogICAgICAgICAgICBzdGFydCwgZW5kID0gbWF0Y2guc3BhbigpCiAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6c3RhcnRdKSkKCiAgICAgICAgICAgIGFsbCwgdXJsLCBzY2hlbWUsIHJmYywgcmZjbnVtLCBzZWxmZG90LCBuYW1lID0gbWF0Y2guZ3JvdXBzKCkKICAgICAgICAgICAgaWYgdXJsOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKHVybCkpKQogICAgICAgICAgICBlbGlmIHJmYzoKICAgICAgICAgICAgICAgIHVybCA9ICdodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmMlcy50eHQnICUgcmZjbnVtCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAodXJsLCBlc2NhcGUocmZjKSkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiB0ZXh0W2VuZDplbmQrMV0gPT0gJygnOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKHNlbGYubmFtZWxpbmsobmFtZSwgbWV0aG9kcywgZnVuY3MsIGNsYXNzZXMpKQogICAgICAgICAgICAgICAgZWxpZiBzZWxmZG90OgogICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCdzZWxmLjxzdHJvbmc+JXM8L3N0cm9uZz4nICUgbmFtZSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgaGVyZSA9IGVuZAogICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6XSkpCiAgICAgICAgcmV0dXJuIGpvaW4ocmVzdWx0cywgJycpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZG9jdHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBjbGFzc2VzPXt9LCBwYXJlbnQ9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGZvciBhIGNsYXNzIHRyZWUgYXMgZ2l2ZW4gYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZHQ+PGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+PHNtYWxsPicKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuY2xhc3NsaW5rKGMsIG1vZG5hbWUsIGNsYXNzZXMpCiAgICAgICAgICAgICAgICBpZiBiYXNlcyBhbmQgYmFzZXMgIT0gKHBhcmVudCwpOgogICAgICAgICAgICAgICAgICAgIHBhcmVudHMgPSBbXQogICAgICAgICAgICAgICAgICAgIGZvciBiYXNlIGluIGJhc2VzOgogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBtb2RuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnKCcgKyBqb2luKHBhcmVudHMsICcsICcpICsgJyknCiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnXG48L3NtYWxsPjwvZm9udD48L2R0PicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIFwKICAgICAgICAgICAgICAgICAgICAnPGRkPlxuJXM8L2RkPlxuJyAlIHNlbGYuZG9jdHJlZShlbnRyeSwgbW9kbmFtZSwgY2xhc3NlcywgYykKICAgICAgICByZXR1cm4gJzxkbD5cbiVzPC9kbD5cbicgJSByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgcGFydHMgPSBzcGxpdChuYW1lLCAnLicpCiAgICAgICAgbGlua3MgPSBbXQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihwYXJ0cyktMSk6CiAgICAgICAgICAgIGxpbmtzLmFwcGVuZCgKICAgICAgICAgICAgICAgICc8YSBocmVmPSIlcy5odG1sIj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+JXM8L2ZvbnQ+PC9hPicgJQogICAgICAgICAgICAgICAgKGpvaW4ocGFydHNbOmkrMV0sICcuJyksIHBhcnRzW2ldKSkKICAgICAgICBsaW5rZWRuYW1lID0gam9pbihsaW5rcyArIHBhcnRzWy0xOl0sICcuJykKICAgICAgICBoZWFkID0gJzxiaWc+PGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+PC9iaWc+JyAlIGxpbmtlZG5hbWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmFic3BhdGgoaW5zcGVjdC5nZXRmaWxlKG9iamVjdCkpCiAgICAgICAgICAgIHNvdXJjZXBhdGggPSBvcy5wYXRoLmFic3BhdGgoaW5zcGVjdC5nZXRzb3VyY2VmaWxlKG9iamVjdCkpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHNvdXJjZXBhdGgpOiBwYXRoID0gc291cmNlcGF0aAogICAgICAgICAgICBmaWxlbGluayA9ICc8YSBocmVmPSJmaWxlOiVzIj4lczwvYT4nICUgKHBhdGgsIHBhdGgpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZWxpbmsgPSAnKGJ1aWx0LWluKScKICAgICAgICBpbmZvID0gW10KICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyQnICsgJ1JldmlzaW9uOiAnIGFuZCB2ZXJzaW9uWy0xOl0gPT0gJyQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0cmlwKHZlcnNpb25bMTE6LTFdKQogICAgICAgICAgICBpbmZvLmFwcGVuZCgndmVyc2lvbiAlcycgJSBzZWxmLmVzY2FwZSh2ZXJzaW9uKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIGluZm8uYXBwZW5kKHNlbGYuZXNjYXBlKHN0cihvYmplY3QuX19kYXRlX18pKSkKICAgICAgICBpZiBpbmZvOgogICAgICAgICAgICBoZWFkID0gaGVhZCArICcgKCVzKScgJSBqb2luKGluZm8sICcsICcpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5oZWFkaW5nKAogICAgICAgICAgICBoZWFkLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgJzxhIGhyZWY9Ii4iPmluZGV4PC9hPjxicj4nICsgZmlsZWxpbmspCgogICAgICAgIHNlY29uZCA9IGxhbWJkYSBsaXN0OiBsaXN0WzFdCiAgICAgICAgbW9kdWxlcyA9IG1hcChzZWNvbmQsIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtb2R1bGUpKQoKICAgICAgICBjbGFzc2VzLCBjZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFt2YWx1ZV0gPSAnIycgKyBrZXkKICAgICAgICBmdW5jcywgZmRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKHZhbHVlKQogICAgICAgICAgICAgICAgZmRpY3Rba2V5XSA9ICcjLScgKyBrZXkKICAgICAgICAgICAgICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih2YWx1ZSk6IGZkaWN0W3ZhbHVlXSA9IGZkaWN0W2tleV0KICAgICAgICBmb3IgYyBpbiBjbGFzc2VzOgogICAgICAgICAgICBmb3IgYmFzZSBpbiBjLl9fYmFzZXNfXzoKICAgICAgICAgICAgICAgIGtleSwgbW9kbmFtZSA9IGJhc2UuX19uYW1lX18sIGJhc2UuX19tb2R1bGVfXwogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSBuYW1lIGFuZCBzeXMubW9kdWxlcy5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIG1vZHVsZSA9IHN5cy5tb2R1bGVzW21vZG5hbWVdCiAgICAgICAgICAgICAgICAgICAgaWYgaGFzYXR0cihtb2R1bGUsIGtleSkgYW5kIGdldGF0dHIobW9kdWxlLCBrZXkpIGlzIGJhc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBjZGljdC5oYXNfa2V5KGtleSk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbYmFzZV0gPSBtb2RuYW1lICsgJy5odG1sIycgKyBrZXkKICAgICAgICBjb25zdGFudHMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzY29uc3RhbnQpOgogICAgICAgICAgICBpZiBrZXlbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgIGNvbnN0YW50cy5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZkaWN0LCBjZGljdCkKICAgICAgICBkb2MgPSBkb2MgYW5kICc8dHQ+JXM8L3R0PicgJSBkb2MKICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPHA+PHNtYWxsPiVzPC9zbWFsbD48L3A+XG4nICUgZG9jCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIG1vZG5hbWVzID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihvYmplY3QuX19wYXRoX19bMF0pOgogICAgICAgICAgICAgICAgaWYgZmlsZVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4ob2JqZWN0Ll9fcGF0aF9fWzBdLCBmaWxlKQogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2R1bGVuYW1lKGZpbGUpCiAgICAgICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZSBub3QgaW4gbW9kbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChtb2RuYW1lLCBuYW1lLCAwLCAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgbW9kbmFtZXMuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChmaWxlLCBuYW1lLCAxLCAwKSkKICAgICAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ1BhY2thZ2UgQ29udGVudHMnLCAnI2ZmZmZmZicsICcjYWE1NWNjJywgY29udGVudHMpCgogICAgICAgIGVsaWYgbW9kdWxlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHVsZXMsIHNlbGYubW9kdWxlbGluaykKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ01vZHVsZXMnLCAnI2ZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLmRvY3RyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2VzLCAxKSwgbmFtZSwgY2RpY3QpCiAgICAgICAgICAgIGZvciBpdGVtIGluIGNsYXNzZXM6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtLCBmZGljdCwgY2RpY3QpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDbGFzc2VzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKQogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBpdGVtIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArIHNlbGYuZG9jdW1lbnQoaXRlbSwgZmRpY3QsIGNkaWN0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnRnVuY3Rpb25zJywgJyNmZmZmZmYnLCAnI2VlYWE3NycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBjb25zdGFudHM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY29uc3RhbnRzOgogICAgICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArICgnPGJyPjxzdHJvbmc+JXM8L3N0cm9uZz4gPSAlcycgJQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5LCBzZWxmLnJlcHIodmFsdWUpKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0NvbnN0YW50cycsICcjZmZmZmZmJywgJyM1NWFhNTUnLCBjb250ZW50cykKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2F1dGhvcl9fJyk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tYXJrdXAoc3RyKG9iamVjdC5fX2F1dGhvcl9fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdBdXRob3InLCAnI2ZmZmZmZicsICcjNzc5OWVlJywgY29udGVudHMpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDcmVkaXRzJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgZnVuY3M9e30sIGNsYXNzZXM9e30pOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCiAgICAgICAgY29udGVudHMgPSAnJwoKICAgICAgICBtZXRob2RzLCBtZGljdCA9IFtdLCB7fQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtZXRob2QpOgogICAgICAgICAgICBtZXRob2RzLmFwcGVuZCh2YWx1ZSkKICAgICAgICAgICAgbWRpY3Rba2V5XSA9IG1kaWN0W3ZhbHVlXSA9ICcjJyArIG5hbWUgKyAnLScgKyBrZXkKICAgICAgICBmb3IgaXRlbSBpbiBtZXRob2RzOgogICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudCgKICAgICAgICAgICAgICAgIGl0ZW0sIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCwgbmFtZSkKCiAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPmNsYXNzIDxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlIChuYW1lLCBuYW1lKQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBvYmplY3QuX19tb2R1bGVfXywgY2xhc3NlcykpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCkKICAgICAgICBpZiBkb2M6IGRvYyA9ICc8c21hbGw+PHR0PicgKyBkb2MgKyAnPC90dD48L3NtYWxsPicKICAgICAgICByZXR1cm4gc2VsZi5zZWN0aW9uKHRpdGxlLCAnIzAwMDAwMCcsICcjZmZjOGQ4JywgY29udGVudHMsIDEwLCBkb2MpCgogICAgZGVmIGZvcm1hdHZhbHVlKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiRm9ybWF0IGFuIGFyZ3VtZW50IGRlZmF1bHQgdmFsdWUgYXMgdGV4dC4iIiIKICAgICAgICByZXR1cm4gKCc8c21hbGw+PGZvbnQgY29sb3I9IiM5MDkwOTAiPj0lczwvZm9udD48L3NtYWxsPicgJQogICAgICAgICAgICAgICAgc2VsZi5yZXByKG9iamVjdCkpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0LCBmdW5jcz17fSwgY2xhc3Nlcz17fSwgbWV0aG9kcz17fSwgY2xuYW1lPScnKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KTogb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbihvYmplY3QpOgogICAgICAgICAgICBkZWNsID0gJzxhIG5hbWU9IiVzIj48c3Ryb25nPiVzPC9zdHJvbmc+KC4uLik8L2E+XG4nICUgKAogICAgICAgICAgICAgICAgY2xuYW1lICsgJy0nICsgb2JqZWN0Ll9fbmFtZV9fLCBvYmplY3QuX19uYW1lX18pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKCiAgICAgICAgICAgIGlmIG9iamVjdC5fX25hbWVfXyA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgZGVjbCA9ICc8ZW0+bGFtYmRhPC9lbT4gJyArIGFyZ3NwZWNbMTotMV0KICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGFuY2hvciA9IGNsbmFtZSArICctJyArIG9iamVjdC5fX25hbWVfXwogICAgICAgICAgICAgICAgZGVjbCA9ICc8YSBuYW1lPSIlcyJcbj48c3Ryb25nPiVzPC9zdHJvbmc+JXM8L2E+XG4nICUgKAogICAgICAgICAgICAgICAgICAgIGFuY2hvciwgb2JqZWN0Ll9fbmFtZV9fLCBhcmdzcGVjKQogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jcywgY2xhc3NlcywgbWV0aG9kcykKICAgICAgICBkb2MgPSByZXBsYWNlKGRvYywgKCc8YnI+XG4nLCAnPC90dD48L3NtYWxsXG4+PGRkPjxzbWFsbD48dHQ+JykpCiAgICAgICAgZG9jID0gZG9jIGFuZCAnPHR0PiVzPC90dD4nICUgZG9jCiAgICAgICAgcmV0dXJuICc8ZGw+PGR0PiVzPGRkPjxzbWFsbD4lczwvc21hbGw+PC9kbD4nICUgKGRlY2wsIGRvYykKCiAgICBkZWYgcGFnZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgYSBjb21wbGV0ZSBIVE1MIHBhZ2Ugb2YgZG9jdW1lbnRhdGlvbiBmb3IgYW4gb2JqZWN0LiIiIgogICAgICAgIHJldHVybiAnJycKPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPjxib2R5IGJnY29sb3I9IiNmZmZmZmYiPgolcwo8L2JvZHk+PC9odG1sPgonJycgJSAoZGVzY3JpYmUob2JqZWN0KSwgc2VsZi5kb2N1bWVudChvYmplY3QpKQoKICAgIGRlZiBpbmRleChzZWxmLCBkaXIsIHNoYWRvd2VkPU5vbmUpOgogICAgICAgICIiIkdlbmVyYXRlIGFuIEhUTUwgaW5kZXggZm9yIGEgZGlyZWN0b3J5IG9mIG1vZHVsZXMuIiIiCiAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgaWYgc2hhZG93ZWQgaXMgTm9uZTogc2hhZG93ZWQgPSB7fQogICAgICAgIHNlZW4gPSB7fQogICAgICAgIGZpbGVzID0gb3MubGlzdGRpcihkaXIpCgogICAgICAgIGRlZiBmb3VuZChuYW1lLCBpc3BhY2thZ2UsCiAgICAgICAgICAgICAgICAgIG1vZHBrZ3M9bW9kcGtncywgc2hhZG93ZWQ9c2hhZG93ZWQsIHNlZW49c2Vlbik6CiAgICAgICAgICAgIGlmIG5vdCBzZWVuLmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgobmFtZSwgJycsIGlzcGFja2FnZSwgc2hhZG93ZWQuaGFzX2tleShuYW1lKSkpCiAgICAgICAgICAgICAgICBzZWVuW25hbWVdID0gMQogICAgICAgICAgICAgICAgc2hhZG93ZWRbbmFtZV0gPSAxCgogICAgICAgICMgUGFja2FnZSBzcGFtL19faW5pdF9fLnB5IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBtb2R1bGUgc3BhbS5weS4KICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGlzcGFja2FnZShwYXRoKTogZm91bmQoZmlsZSwgMSkKICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGZpbGVbOjFdICE9ICdfJyBhbmQgb3MucGF0aC5pc2ZpbGUocGF0aCk6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZTogZm91bmQobW9kbmFtZSwgMCkKCiAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgIHJldHVybiBzZWxmLmJpZ3NlY3Rpb24oZGlyLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHRleHQgZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IKCmNsYXNzIFRleHRSZXByKFJlcHIpOgogICAgIiIiQ2xhc3MgZm9yIHNhZmVseSBtYWtpbmcgYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IHNlbGYubWF4ZGljdCA9IDEwCiAgICAgICAgc2VsZi5tYXhzdHJpbmcgPSBzZWxmLm1heG90aGVyID0gNTAKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpCgogICAgZGVmIHJlcHJfaW5zdGFuY2Uoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcmV0dXJuIGNyYW0oc3RyaXBpZChyZXByKHgpKSwgc2VsZi5tYXhzdHJpbmcpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18KCmNsYXNzIFRleHREb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgdGV4dCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0ZXh0IGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBUZXh0UmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgoKICAgIGRlZiBib2xkKHNlbGYsIHRleHQpOgogICAgICAgICIiIkZvcm1hdCBhIHN0cmluZyBpbiBib2xkIGJ5IG92ZXJzdHJpa2luZy4iIiIKICAgICAgICByZXR1cm4gam9pbihtYXAobGFtYmRhIGNoOiBjaCArICdcYicgKyBjaCwgdGV4dCksICcnKQoKICAgIGRlZiBpbmRlbnQoc2VsZiwgdGV4dCwgcHJlZml4PScgICAgJyk6CiAgICAgICAgIiIiSW5kZW50IHRleHQgYnkgcHJlcGVuZGluZyBhIGdpdmVuIHByZWZpeCB0byBlYWNoIGxpbmUuIiIiCiAgICAgICAgaWYgbm90IHRleHQ6IHJldHVybiAnJwogICAgICAgIGxpbmVzID0gc3BsaXQodGV4dCwgJ1xuJykKICAgICAgICBsaW5lcyA9IG1hcChsYW1iZGEgbGluZSwgcHJlZml4PXByZWZpeDogcHJlZml4ICsgbGluZSwgbGluZXMpCiAgICAgICAgaWYgbGluZXM6IGxpbmVzWy0xXSA9IHJzdHJpcChsaW5lc1stMV0pCiAgICAgICAgcmV0dXJuIGpvaW4obGluZXMsICdcbicpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYSBzZWN0aW9uIHdpdGggYSBnaXZlbiBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiBzZWxmLmJvbGQodGl0bGUpICsgJ1xuJyArIHJzdHJpcChzZWxmLmluZGVudChjb250ZW50cykpICsgJ1xuXG4nCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZG9jdHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSwgcHJlZml4PScnKToKICAgICAgICAiIiJSZW5kZXIgaW4gdGV4dCBhIGNsYXNzIHRyZWUgYXMgcmV0dXJuZWQgYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGNsLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoY2wsIG1vZG5hbWUpCiAgICAgICAgICAgICAgICBpZiBiYXNlcyBhbmQgYmFzZXMgIT0gKHBhcmVudCwpOgogICAgICAgICAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobGFtYmRhIGNsLCBtPW1vZG5hbWU6IGNsYXNzbmFtZShjbCwgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZG9jdHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgY2wsIHByZWZpeCArICcgICAgJykKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY21vZHVsZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGdpdmVuIG1vZHVsZSBvYmplY3QuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGxpbmVzID0gc3BsaXQoc3RyaXAoZ2V0ZG9jKG9iamVjdCkpLCAnXG4nKQogICAgICAgIGlmIGxlbihsaW5lcykgPT0gMToKICAgICAgICAgICAgaWYgbGluZXNbMF06IG5hbWUgPSBuYW1lICsgJyAtICcgKyBsaW5lc1swXQogICAgICAgICAgICBsaW5lcyA9IFtdCiAgICAgICAgZWxpZiBsZW4obGluZXMpID49IDIgYW5kIG5vdCByc3RyaXAobGluZXNbMV0pOgogICAgICAgICAgICBpZiBsaW5lc1swXTogbmFtZSA9IG5hbWUgKyAnIC0gJyArIGxpbmVzWzBdCiAgICAgICAgICAgIGxpbmVzID0gbGluZXNbMjpdCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdOQU1FJywgbmFtZSkKICAgICAgICB0cnk6IGZpbGUgPSBpbnNwZWN0LmdldGZpbGUob2JqZWN0KSAjIFhYWCBvciBnZXRzb3VyY2VmaWxlPwogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6IGZpbGUgPSBOb25lCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGSUxFJywgZmlsZSBvciAnKGJ1aWx0LWluKScpCiAgICAgICAgaWYgbGluZXM6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignREVTQ1JJUFRJT04nLCBqb2luKGxpbmVzLCAnXG4nKSkKCiAgICAgICAgY2xhc3NlcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKHZhbHVlKQogICAgICAgIGZ1bmNzID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKHZhbHVlKQogICAgICAgIGNvbnN0YW50cyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNjb25zdGFudCk6CiAgICAgICAgICAgIGlmIGtleVs6MV0gIT0gJ18nOgogICAgICAgICAgICAgICAgY29uc3RhbnRzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19wYXRoX18nKToKICAgICAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIob2JqZWN0Ll9fcGF0aF9fWzBdKToKICAgICAgICAgICAgICAgIGlmIGZpbGVbOjFdICE9ICdfJzoKICAgICAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZHBrZ3M6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKG1vZG5hbWUpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKGZpbGUgKyAnIChwYWNrYWdlKScpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbigKICAgICAgICAgICAgICAgICdQQUNLQUdFIENPTlRFTlRTJywgam9pbihtb2Rwa2dzLCAnXG4nKSkKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLmRvY3RyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2VzLCAxKSwgb2JqZWN0Ll9fbmFtZV9fKSArICdcbicKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBzZWxmLmRvY3VtZW50KGl0ZW0pICsgJ1xuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NMQVNTRVMnLCBjb250ZW50cykKCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gJycKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGNvbnRlbnRzICsgc2VsZi5kb2N1bWVudChpdGVtKSArICdcbicKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGVU5DVElPTlMnLCBjb250ZW50cykKCiAgICAgICAgaWYgY29uc3RhbnRzOgogICAgICAgICAgICBjb250ZW50cyA9ICcnCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNvbnN0YW50czoKICAgICAgICAgICAgICAgIGxpbmUgPSBrZXkgKyAnID0gJyArIHNlbGYucmVwcih2YWx1ZSkKICAgICAgICAgICAgICAgIGNob3AgPSA3MCAtIGxlbihsaW5lKQogICAgICAgICAgICAgICAgbGluZSA9IHNlbGYuYm9sZChrZXkpICsgJyA9ICcgKyBzZWxmLnJlcHIodmFsdWUpCiAgICAgICAgICAgICAgICBpZiBjaG9wIDwgMDogbGluZSA9IGxpbmVbOmNob3BdICsgJy4uLicKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gY29udGVudHMgKyBsaW5lICsgJ1xuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NPTlNUQU5UUycsIGNvbnRlbnRzKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fdmVyc2lvbl9fJyk6CiAgICAgICAgICAgIHZlcnNpb24gPSBzdHIob2JqZWN0Ll9fdmVyc2lvbl9fKQogICAgICAgICAgICBpZiB2ZXJzaW9uWzoxMV0gPT0gJyQnICsgJ1JldmlzaW9uOiAnIGFuZCB2ZXJzaW9uWy0xOl0gPT0gJyQnOgogICAgICAgICAgICAgICAgdmVyc2lvbiA9IHN0cmlwKHZlcnNpb25bMTE6LTFdKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ1ZFUlNJT04nLCB2ZXJzaW9uKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdEQVRFJywgc3RyKG9iamVjdC5fX2RhdGVfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2F1dGhvcl9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQVVUSE9SJywgc3RyKG9iamVjdC5fX2F1dGhvcl9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignQ1JFRElUUycsIHN0cihvYmplY3QuX19jcmVkaXRzX18pKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jY2xhc3Moc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBnaXZlbiBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwoKICAgICAgICB0aXRsZSA9ICdjbGFzcyAnICsgc2VsZi5ib2xkKG5hbWUpCiAgICAgICAgaWYgYmFzZXM6CiAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobGFtYmRhIGMsIG09b2JqZWN0Ll9fbW9kdWxlX186IGNsYXNzbmFtZShjLCBtKSwgYmFzZXMpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCgogICAgICAgIGRvYyA9IGdldGRvYyhvYmplY3QpCiAgICAgICAgY29udGVudHMgPSBkb2MgYW5kIGRvYyArICdcbicKICAgICAgICBtZXRob2RzID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc21ldGhvZCkpCiAgICAgICAgZm9yIGl0ZW0gaW4gbWV0aG9kczoKICAgICAgICAgICAgY29udGVudHMgPSBjb250ZW50cyArICdcbicgKyBzZWxmLmRvY3VtZW50KGl0ZW0pCgogICAgICAgIGlmIG5vdCBjb250ZW50czogcmV0dXJuIHRpdGxlICsgJ1xuJwogICAgICAgIHJldHVybiB0aXRsZSArICdcbicgKyBzZWxmLmluZGVudChyc3RyaXAoY29udGVudHMpLCAnIHwgICcpICsgJ1xuJwoKICAgIGRlZiBmb3JtYXR2YWx1ZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIkZvcm1hdCBhbiBhcmd1bWVudCBkZWZhdWx0IHZhbHVlIGFzIHRleHQuIiIiCiAgICAgICAgcmV0dXJuICc9JyArIHNlbGYucmVwcihvYmplY3QpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KTogb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbihvYmplY3QpOgogICAgICAgICAgICBkZWNsID0gc2VsZi5ib2xkKG9iamVjdC5fX25hbWVfXykgKyAnKC4uLiknCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKICAgICAgICAgICAgaWYgb2JqZWN0Ll9fbmFtZV9fID09ICc8bGFtYmRhPic6CiAgICAgICAgICAgICAgICBkZWNsID0gJzxsYW1iZGE+ICcgKyBhcmdzcGVjWzE6LTFdCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBkZWNsID0gc2VsZi5ib2xkKG9iamVjdC5fX25hbWVfXykgKyBhcmdzcGVjCiAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkKICAgICAgICBpZiBkb2M6CiAgICAgICAgICAgIHJldHVybiBkZWNsICsgJ1xuJyArIHJzdHJpcChzZWxmLmluZGVudChkb2MpKSArICdcbicKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gZGVjbCArICdcbicKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHVzZXIgaW50ZXJmYWNlcwoKZGVmIHBhZ2VyKHRleHQpOgogICAgIiIiVGhlIGZpcnN0IHRpbWUgdGhpcyBpcyBjYWxsZWQsIGRldGVybWluZSB3aGF0IGtpbmQgb2YgcGFnZXIgdG8gdXNlLiIiIgogICAgZ2xvYmFsIHBhZ2VyCiAgICBwYWdlciA9IGdldHBhZ2VyKCkKICAgIHBhZ2VyKHRleHQpCgpkZWYgZ2V0cGFnZXIoKToKICAgICIiIkRlY2lkZSB3aGF0IG1ldGhvZCB0byB1c2UgZm9yIHBhZ2luZyB0aHJvdWdoIHRleHQuIiIiCiAgICBpZiB0eXBlKHN5cy5zdGRvdXQpIGlzIG5vdCB0eXBlcy5GaWxlVHlwZToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgbm90IHN5cy5zdGRpbi5pc2F0dHkoKSBvciBub3Qgc3lzLnN0ZG91dC5pc2F0dHkoKToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgb3MuZW52aXJvbi5oYXNfa2V5KCdQQUdFUicpOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogcGlwZXBhZ2VyKGEsIG9zLmVudmlyb25bJ1BBR0VSJ10pCiAgICBpZiBzeXMucGxhdGZvcm0gaW4gWyd3aW4nLCAnd2luMzInLCAnbnQnXToKICAgICAgICByZXR1cm4gbGFtYmRhIGE6IHRlbXBmaWxlcGFnZXIoYSwgJ21vcmUnKQogICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ2xlc3MgMj4vZGV2L251bGwnKSA9PSAwOgogICAgICAgIHJldHVybiBsYW1iZGEgYTogcGlwZXBhZ2VyKGEsICdsZXNzJykKCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIG9wZW4oZmlsZW5hbWUsICd3JykuY2xvc2UoKQogICAgdHJ5OgogICAgICAgIGlmIGhhc2F0dHIob3MsICdzeXN0ZW0nKSBhbmQgb3Muc3lzdGVtKCdtb3JlICVzJyAlIGZpbGVuYW1lKSA9PSAwOgogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHBpcGVwYWdlcih0ZXh0LCAnbW9yZScpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHR0eXBhZ2VyCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwaXBlcGFnZXIodGV4dCwgY21kKToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IGJ5IGZlZWRpbmcgaXQgdG8gYW5vdGhlciBwcm9ncmFtLiIiIgogICAgcGlwZSA9IG9zLnBvcGVuKGNtZCwgJ3cnKQogICAgdHJ5OgogICAgICAgIHBpcGUud3JpdGUodGV4dCkKICAgICAgICBwaXBlLmNsb3NlKCkKICAgIGV4Y2VwdCBJT0Vycm9yOgogICAgICAgICMgSWdub3JlIGJyb2tlbiBwaXBlcyBjYXVzZWQgYnkgcXVpdHRpbmcgdGhlIHBhZ2VyIHByb2dyYW0uCiAgICAgICAgcGFzcwoKZGVmIHRlbXBmaWxlcGFnZXIodGV4dCwgY21kKToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IGJ5IGludm9raW5nIGEgcHJvZ3JhbSBvbiBhIHRlbXBvcmFyeSBmaWxlLiIiIgogICAgaW1wb3J0IHRlbXBmaWxlCiAgICBmaWxlbmFtZSA9IHRlbXBmaWxlLm1rdGVtcCgpCiAgICBmaWxlID0gb3BlbihmaWxlbmFtZSwgJ3cnKQogICAgZmlsZS53cml0ZSh0ZXh0KQogICAgZmlsZS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgb3Muc3lzdGVtKGNtZCArICcgJyArIGZpbGVuYW1lKQogICAgZmluYWxseToKICAgICAgICBvcy51bmxpbmsoZmlsZW5hbWUpCgpkZWYgcGxhaW4odGV4dCk6CiAgICAiIiJSZW1vdmUgYm9sZGZhY2UgZm9ybWF0dGluZyBmcm9tIHRleHQuIiIiCiAgICByZXR1cm4gcmUuc3ViKCcuXGInLCAnJywgdGV4dCkKCmRlZiB0dHlwYWdlcih0ZXh0KToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IG9uIGEgdGV4dCB0ZXJtaW5hbC4iIiIKICAgIGxpbmVzID0gc3BsaXQocGxhaW4odGV4dCksICdcbicpCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHR0eQogICAgICAgIGZkID0gc3lzLnN0ZGluLmZpbGVubygpCiAgICAgICAgb2xkID0gdHR5LnRjZ2V0YXR0cihmZCkKICAgICAgICB0dHkuc2V0Y2JyZWFrKGZkKQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkKDEpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgdHR5ID0gTm9uZQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkbGluZSgpWzotMV1bOjFdCgogICAgdHJ5OgogICAgICAgIHIgPSBpbmMgPSBvcy5lbnZpcm9uLmdldCgnTElORVMnLCAyNSkgLSAxCiAgICAgICAgc3lzLnN0ZG91dC53cml0ZShqb2luKGxpbmVzWzppbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgd2hpbGUgbGluZXNbcjpdOgogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCctLSBtb3JlIC0tJykKICAgICAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCiAgICAgICAgICAgIGMgPSBnZXRjaGFyKCkKCiAgICAgICAgICAgIGlmIGMgaW4gWydxJywgJ1EnXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJykKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGVsaWYgYyBpbiBbJ1xyJywgJ1xuJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicgKyBsaW5lc1tyXSArICdcbicpCiAgICAgICAgICAgICAgICByID0gciArIDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIGMgaW4gWydiJywgJ0InLCAnXHgxYiddOgogICAgICAgICAgICAgICAgciA9IHIgLSBpbmMgLSBpbmMKICAgICAgICAgICAgICAgIGlmIHIgPCAwOiByID0gMAogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcbicgKyBqb2luKGxpbmVzW3I6citpbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgICAgIHIgPSByICsgaW5jCgogICAgZmluYWxseToKICAgICAgICBpZiB0dHk6CiAgICAgICAgICAgIHR0eS50Y3NldGF0dHIoZmQsIHR0eS5UQ1NBRkxVU0gsIG9sZCkKCmRlZiBwbGFpbnBhZ2VyKHRleHQpOgogICAgIiIiU2ltcGx5IHByaW50IHVuZm9ybWF0dGVkIHRleHQuICBUaGlzIGlzIHRoZSB1bHRpbWF0ZSBmYWxsYmFjay4iIiIKICAgIHN5cy5zdGRvdXQud3JpdGUocGxhaW4odGV4dCkpCgpkZWYgZGVzY3JpYmUodGhpbmcpOgogICAgIiIiUHJvZHVjZSBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBnaXZlbiBraW5kIG9mIHRoaW5nLiIiIgogICAgaWYgaW5zcGVjdC5pc21vZHVsZSh0aGluZyk6CiAgICAgICAgaWYgdGhpbmcuX19uYW1lX18gaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICByZXR1cm4gJ2J1aWx0LWluIG1vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBpZiBoYXNhdHRyKHRoaW5nLCAnX19wYXRoX18nKToKICAgICAgICAgICAgcmV0dXJuICdwYWNrYWdlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiAnbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odGhpbmcpOgogICAgICAgIHJldHVybiAnYnVpbHQtaW4gZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzY2xhc3ModGhpbmcpOgogICAgICAgIHJldHVybiAnY2xhc3MgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24odGhpbmcpOgogICAgICAgIHJldHVybiAnZnVuY3Rpb24gJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKHRoaW5nKToKICAgICAgICByZXR1cm4gJ21ldGhvZCAnICsgdGhpbmcuX19uYW1lX18KICAgIHJldHVybiByZXByKHRoaW5nKQoKZGVmIGxvY2F0ZShwYXRoKToKICAgICIiIkxvY2F0ZSBhbiBvYmplY3QgYnkgbmFtZSAob3IgZG90dGVkIHBhdGgpLCBpbXBvcnRpbmcgYXMgbmVjZXNzYXJ5LiIiIgogICAgaWYgbm90IHBhdGg6ICMgc3BlY2lhbCBjYXNlOiBpbXAuZmluZF9tb2R1bGUoJycpIHN0cmFuZ2VseSBzdWNjZWVkcwogICAgICAgIHJldHVybiBOb25lLCBOb25lCiAgICBpZiB0eXBlKHBhdGgpIGlzIG5vdCB0eXBlcy5TdHJpbmdUeXBlOgogICAgICAgIHJldHVybiBOb25lLCBwYXRoCiAgICBwYXJ0cyA9IHNwbGl0KHBhdGgsICcuJykKICAgIG4gPSAxCiAgICB3aGlsZSBuIDw9IGxlbihwYXJ0cyk6CiAgICAgICAgcGF0aCA9IGpvaW4ocGFydHNbOm5dLCAnLicpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBtb2R1bGUgPSBfX2ltcG9ydF9fKHBhdGgpCiAgICAgICAgICAgIG1vZHVsZSA9IHJlbG9hZChtb2R1bGUpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAjIGRldGVybWluZSBpZiBlcnJvciBvY2N1cnJlZCBiZWZvcmUgb3IgYWZ0ZXIgbW9kdWxlIHdhcyBmb3VuZAogICAgICAgICAgICBpZiBzeXMubW9kdWxlcy5oYXNfa2V5KHBhdGgpOgogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXwogICAgICAgICAgICBlbGlmIHN5cy5leGNfdHlwZSBpcyBTeW50YXhFcnJvcjoKICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gc3lzLmV4Y192YWx1ZS5maWxlbmFtZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyBtb2R1bGUgbm90IGZvdW5kLCBzbyBzdG9wIGxvb2tpbmcKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICMgZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGltcG9ydGVkIG1vZHVsZSwgc28gcmVwb3J0IGl0CiAgICAgICAgICAgIHJhaXNlIERvY0ltcG9ydEVycm9yKGZpbGVuYW1lLCBzeXMuZXhjX3R5cGUsIHN5cy5leGNfdmFsdWUpCiAgICAgICAgdHJ5OgogICAgICAgICAgICB4ID0gbW9kdWxlCiAgICAgICAgICAgIGZvciBwIGluIHBhcnRzWzE6XToKICAgICAgICAgICAgICAgIHggPSBnZXRhdHRyKHgsIHApCiAgICAgICAgICAgIHJldHVybiBqb2luKHBhcnRzWzotMV0sICcuJyksIHgKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgIG4gPSBuICsgMQogICAgICAgICAgICBjb250aW51ZQogICAgaWYgaGFzYXR0cihfX2J1aWx0aW5zX18sIHBhdGgpOgogICAgICAgIHJldHVybiBOb25lLCBnZXRhdHRyKF9fYnVpbHRpbnNfXywgcGF0aCkKICAgIHJldHVybiBOb25lLCBOb25lCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBpbnRlcmFjdGl2ZSBpbnRlcnByZXRlciBpbnRlcmZhY2UKCnRleHQgPSBUZXh0RG9jKCkKaHRtbCA9IEhUTUxEb2MoKQoKZGVmIGRvYyh0aGluZyk6CiAgICAiIiJEaXNwbGF5IGRvY3VtZW50YXRpb24gb24gYW4gb2JqZWN0IChmb3IgaW50ZXJhY3RpdmUgdXNlKS4iIiIKICAgIGlmIHR5cGUodGhpbmcpIGlzIHR5cGUoIiIpOgogICAgICAgIHRyeToKICAgICAgICAgICAgcGF0aCwgeCA9IGxvY2F0ZSh0aGluZykKICAgICAgICBleGNlcHQgRG9jSW1wb3J0RXJyb3IsIHZhbHVlOgogICAgICAgICAgICBwcmludCAnUHJvYmxlbSBpbiAlcyAtICVzJyAlICh2YWx1ZS5maWxlbmFtZSwgdmFsdWUuYXJncykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgeDoKICAgICAgICAgICAgdGhpbmcgPSB4CiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQgJ05vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcy4nICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCgogICAgZGVzYyA9IGRlc2NyaWJlKHRoaW5nKQogICAgbW9kdWxlID0gaW5zcGVjdC5nZXRtb2R1bGUodGhpbmcpCiAgICBpZiBtb2R1bGUgYW5kIG1vZHVsZSBpcyBub3QgdGhpbmc6CiAgICAgICAgZGVzYyA9IGRlc2MgKyAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcignSGVscCBvbiAlczpcblxuJyAlIGRlc2MgKyB0ZXh0LmRvY3VtZW50KHRoaW5nKSkKCmRlZiB3cml0ZWRvYyhrZXkpOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICBwYXRoLCBvYmplY3QgPSBsb2NhdGUoa2V5KQogICAgaWYgb2JqZWN0OgogICAgICAgIGZpbGUgPSBvcGVuKGtleSArICcuaHRtbCcsICd3JykKICAgICAgICBmaWxlLndyaXRlKGh0bWwucGFnZShvYmplY3QpKQogICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgIHByaW50ICd3cm90ZScsIGtleSArICcuaHRtbCcKCmNsYXNzIEhlbHBlcjoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gIiIiVG8gZ2V0IGhlbHAgb24gYSBQeXRob24gb2JqZWN0LCBjYWxsIGhlbHAob2JqZWN0KS4KVG8gZ2V0IGhlbHAgb24gYSBtb2R1bGUgb3IgcGFja2FnZSwgZWl0aGVyIGltcG9ydCBpdCBiZWZvcmUgY2FsbGluZwpoZWxwKG1vZHVsZSkgb3IgY2FsbCBoZWxwKCdtb2R1bGVuYW1lJykuIiIiCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzKToKICAgICAgICBpZiBhcmdzOgogICAgICAgICAgICBkb2MoYXJnc1swXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBwcmludCByZXByKHNlbGYpCgpoZWxwID0gSGVscGVyKCkKCmRlZiBtYW4oa2V5KToKICAgICIiIkRpc3BsYXkgZG9jdW1lbnRhdGlvbiBvbiBhbiBvYmplY3QgaW4gYSBmb3JtIHNpbWlsYXIgdG8gbWFuKDEpLiIiIgogICAgcGF0aCwgb2JqZWN0ID0gbG9jYXRlKGtleSkKICAgIGlmIG9iamVjdDoKICAgICAgICB0aXRsZSA9ICdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAnICsgZGVzY3JpYmUob2JqZWN0KQogICAgICAgIGlmIHBhdGg6IHRpdGxlID0gdGl0bGUgKyAnIGluICcgKyBwYXRoCiAgICAgICAgcGFnZXIoJ1xuJyArIHRpdGxlICsgJ1xuXG4nICsgdGV4dC5kb2N1bWVudChvYmplY3QpKQogICAgICAgIGZvdW5kID0gMQogICAgZWxzZToKICAgICAgICBwcmludCAnTm8gUHl0aG9uIGRvY3VtZW50YXRpb24gZm91bmQgZm9yICVzLicgJSByZXByKGtleSkKCmNsYXNzIFNjYW5uZXI6CiAgICAiIiJBIGdlbmVyaWMgdHJlZSBpdGVyYXRvci4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCByb290cywgY2hpbGRyZW4sIHJlY3Vyc2UpOgogICAgICAgIHNlbGYucm9vdHMgPSByb290c1s6XQogICAgICAgIHNlbGYuc3RhdGUgPSBbXQogICAgICAgIHNlbGYuY2hpbGRyZW4gPSBjaGlsZHJlbgogICAgICAgIHNlbGYucmVjdXJzZSA9IHJlY3Vyc2UKCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5zdGF0ZToKICAgICAgICAgICAgaWYgbm90IHNlbGYucm9vdHM6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICByb290ID0gc2VsZi5yb290cy5wb3AoMCkKICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFsocm9vdCwgc2VsZi5jaGlsZHJlbihyb290KSldCiAgICAgICAgbm9kZSwgY2hpbGRyZW4gPSBzZWxmLnN0YXRlWy0xXQogICAgICAgIGlmIG5vdCBjaGlsZHJlbjoKICAgICAgICAgICAgc2VsZi5zdGF0ZS5wb3AoKQogICAgICAgICAgICByZXR1cm4gc2VsZi5uZXh0KCkKICAgICAgICBjaGlsZCA9IGNoaWxkcmVuLnBvcCgwKQogICAgICAgIGlmIHNlbGYucmVjdXJzZShjaGlsZCk6CiAgICAgICAgICAgIHNlbGYuc3RhdGUuYXBwZW5kKChjaGlsZCwgc2VsZi5jaGlsZHJlbihjaGlsZCkpKQogICAgICAgIHJldHVybiBjaGlsZAoKY2xhc3MgTW9kdWxlU2Nhbm5lcihTY2FubmVyKToKICAgICIiIkFuIGludGVycnVwdGlibGUgc2Nhbm5lciB0aGF0IHNlYXJjaGVzIG1vZHVsZSBzeW5vcHNlcy4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICByb290cyA9IG1hcChsYW1iZGEgZGlyOiAoZGlyLCAnJyksIHBhdGhkaXJzKCkpCiAgICAgICAgU2Nhbm5lci5fX2luaXRfXyhzZWxmLCByb290cywgc2VsZi5zdWJtb2R1bGVzLCBzZWxmLmlzcGFja2FnZSkKCiAgICBkZWYgc3VibW9kdWxlcyhzZWxmLCAoZGlyLCBwYWNrYWdlKSk6CiAgICAgICAgY2hpbGRyZW4gPSBbXQogICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGlzcGFja2FnZShwYXRoKTogCiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIGZpbGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW4uYXBwZW5kKChwYXRoLCBwYWNrYWdlKSkKICAgICAgICBjaGlsZHJlbi5zb3J0KCkKICAgICAgICByZXR1cm4gY2hpbGRyZW4KCiAgICBkZWYgaXNwYWNrYWdlKHNlbGYsIChkaXIsIHBhY2thZ2UpKToKICAgICAgICByZXR1cm4gaXNwYWNrYWdlKGRpcikKCiAgICBkZWYgcnVuKHNlbGYsIGtleSwgY2FsbGJhY2ssIGNvbXBsZXRlcj1Ob25lKToKICAgICAgICBzZWxmLnF1aXQgPSAwCiAgICAgICAgc2VlbiA9IHt9CgogICAgICAgIGZvciBtb2RuYW1lIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEKICAgICAgICAgICAgZGVzYyA9IHNwbGl0KF9faW1wb3J0X18obW9kbmFtZSkuX19kb2NfXyBvciAnJywgJ1xuJylbMF0KICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwgbG93ZXIoa2V5KSkgPj0gMDoKICAgICAgICAgICAgICAgIGNhbGxiYWNrKE5vbmUsIG1vZG5hbWUsIGRlc2MpCgogICAgICAgIHdoaWxlIG5vdCBzZWxmLnF1aXQ6CiAgICAgICAgICAgIG5vZGUgPSBzZWxmLm5leHQoKQogICAgICAgICAgICBpZiBub3Qgbm9kZTogYnJlYWsKICAgICAgICAgICAgcGF0aCwgcGFja2FnZSA9IG5vZGUKICAgICAgICAgICAgbW9kbmFtZSA9IG1vZHVsZW5hbWUocGF0aCkKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIG1vZG5hbWU6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gcGFja2FnZSArIChwYWNrYWdlIGFuZCAnLicpICsgbW9kbmFtZQogICAgICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShtb2RuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMQogICAgICAgICAgICAgICAgICAgIGRlc2MgPSBzeW5vcHNpcyhwYXRoKSBvciAnJwogICAgICAgICAgICAgICAgICAgIGlmIGZpbmQobG93ZXIobW9kbmFtZSArICcgLSAnICsgZGVzYyksIGxvd2VyKGtleSkpID49IDA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsIGRlc2MpCiAgICAgICAgaWYgY29tcGxldGVyOiBjb21wbGV0ZXIoKQoKZGVmIGFwcm9wb3Moa2V5KToKICAgICIiIlByaW50IGFsbCB0aGUgb25lLWxpbmUgbW9kdWxlIHN1bW1hcmllcyB0aGF0IGNvbnRhaW4gYSBzdWJzdHJpbmcuIiIiCiAgICBkZWYgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgZGVzYyk6CiAgICAgICAgaWYgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgcHJpbnQgbW9kbmFtZSwgJy0nLCBkZXNjIG9yICcobm8gZGVzY3JpcHRpb24pJwogICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihrZXksIGNhbGxiYWNrKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gd2ViIGJyb3dzZXIgaW50ZXJmYWNlCgpkZWYgc2VydmUocG9ydCwgY2FsbGJhY2s9Tm9uZSk6CiAgICBpbXBvcnQgQmFzZUhUVFBTZXJ2ZXIsIG1pbWV0b29scywgc2VsZWN0CgogICAgIyBQYXRjaCB1cCBtaW1ldG9vbHMuTWVzc2FnZSBzbyBpdCBkb2Vzbid0IGJyZWFrIGlmIHJmYzgyMiBpcyByZWxvYWRlZC4KICAgIGNsYXNzIE1lc3NhZ2UobWltZXRvb2xzLk1lc3NhZ2UpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmcCwgc2Vla2FibGU9MSk6CiAgICAgICAgICAgIE1lc3NhZ2UgPSBzZWxmLl9fY2xhc3NfXwogICAgICAgICAgICBNZXNzYWdlLl9fYmFzZXNfX1swXS5fX2Jhc2VzX19bMF0uX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlKQogICAgICAgICAgICBzZWxmLmVuY29kaW5naGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHJhbnNmZXItZW5jb2RpbmcnKQogICAgICAgICAgICBzZWxmLnR5cGVoZWFkZXIgPSBzZWxmLmdldGhlYWRlcignY29udGVudC10eXBlJykKICAgICAgICAgICAgc2VsZi5wYXJzZXR5cGUoKQogICAgICAgICAgICBzZWxmLnBhcnNlcGxpc3QoKQoKICAgIGNsYXNzIERvY0hhbmRsZXIoQmFzZUhUVFBTZXJ2ZXIuQmFzZUhUVFBSZXF1ZXN0SGFuZGxlcik6CiAgICAgICAgZGVmIHNlbmRfZG9jdW1lbnQoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5zZW5kX3Jlc3BvbnNlKDIwMCkKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9oZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKQogICAgICAgICAgICAgICAgc2VsZi5lbmRfaGVhZGVycygpCiAgICAgICAgICAgICAgICBzZWxmLndmaWxlLndyaXRlKCcnJwo8IWRvY3R5cGUgaHRtbCBwdWJsaWMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgo8aHRtbD48dGl0bGU+UHl0aG9uOiAlczwvdGl0bGU+PGJvZHkgYmdjb2xvcj0iI2ZmZmZmZiI+CiVzCjwvYm9keT48L2h0bWw+JycnICUgKHRpdGxlLCBjb250ZW50cykpCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yOiBwYXNzCgogICAgICAgIGRlZiBkb19HRVQoc2VsZik6CiAgICAgICAgICAgIHBhdGggPSBzZWxmLnBhdGgKICAgICAgICAgICAgaWYgcGF0aFstNTpdID09ICcuaHRtbCc6IHBhdGggPSBwYXRoWzotNV0KICAgICAgICAgICAgaWYgcGF0aFs6MV0gPT0gJy8nOiBwYXRoID0gcGF0aFsxOl0KICAgICAgICAgICAgaWYgcGF0aCBhbmQgcGF0aCAhPSAnLic6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcCwgeCA9IGxvY2F0ZShwYXRoKQogICAgICAgICAgICAgICAgZXhjZXB0IERvY0ltcG9ydEVycm9yLCB2YWx1ZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwgaHRtbC5lc2NhcGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdQcm9ibGVtIGluICVzIC0gJXMnICUgKHZhbHVlLmZpbGVuYW1lLCB2YWx1ZS5hcmdzKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBpZiB4OgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChkZXNjcmliZSh4KSwgaHRtbC5kb2N1bWVudCh4KSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KHBhdGgsCidObyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMuJyAlIHJlcHIocGF0aCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBoZWFkaW5nID0gaHRtbC5oZWFkaW5nKAonPGJpZz48YmlnPjxzdHJvbmc+UHl0aG9uOiBJbmRleCBvZiBNb2R1bGVzPC9zdHJvbmc+PC9iaWc+PC9iaWc+JywKJyNmZmZmZmYnLCAnIzc3OTllZScpCiAgICAgICAgICAgICAgICBidWlsdGlucyA9IFtdCiAgICAgICAgICAgICAgICBmb3IgbmFtZSBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CiAgICAgICAgICAgICAgICAgICAgYnVpbHRpbnMuYXBwZW5kKCc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG5hbWUsIG5hbWUpKQogICAgICAgICAgICAgICAgaW5kaWNlcyA9IFsnPHA+QnVpbHQtaW4gbW9kdWxlczogJyArIGpvaW4oYnVpbHRpbnMsICcsICcpXQogICAgICAgICAgICAgICAgc2VlbiA9IHt9CiAgICAgICAgICAgICAgICBmb3IgZGlyIGluIHBhdGhkaXJzKCk6CiAgICAgICAgICAgICAgICAgICAgaW5kaWNlcy5hcHBlbmQoaHRtbC5pbmRleChkaXIsIHNlZW4pKQogICAgICAgICAgICAgICAgY29udGVudHMgPSBoZWFkaW5nICsgam9pbihpbmRpY2VzKSArICIiIjxwIGFsaWduPXJpZ2h0Pgo8c21hbGw+PHNtYWxsPjxmb250IGNvbG9yPSIjOTA5MDkwIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj48c3Ryb25nPgpweWRvYzwvc3Ryb25nPiBieSBLYS1QaW5nIFllZSAmbHQ7cGluZ0BsZncub3JnJmd0OzwvZm9udD48L3NtYWxsPjwvc21hbGw+IiIiCiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQoJ0luZGV4IG9mIE1vZHVsZXMnLCBjb250ZW50cykKCiAgICAgICAgZGVmIGxvZ19tZXNzYWdlKHNlbGYsICphcmdzKTogcGFzcwoKICAgIGNsYXNzIERvY1NlcnZlcihCYXNlSFRUUFNlcnZlci5IVFRQU2VydmVyKToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgcG9ydCwgY2FsbGJhY2spOgogICAgICAgICAgICBzZWxmLmFkZHJlc3MgPSAoJzEyNy4wLjAuMScsIHBvcnQpCiAgICAgICAgICAgIHNlbGYudXJsID0gJ2h0dHA6Ly8xMjcuMC4wLjE6JWQvJyAlIHBvcnQKICAgICAgICAgICAgc2VsZi5jYWxsYmFjayA9IGNhbGxiYWNrCiAgICAgICAgICAgIHNlbGYuYmFzZS5fX2luaXRfXyhzZWxmLCBzZWxmLmFkZHJlc3MsIHNlbGYuaGFuZGxlcikKCiAgICAgICAgZGVmIHNlcnZlX3VudGlsX3F1aXQoc2VsZik6CiAgICAgICAgICAgIGltcG9ydCBzZWxlY3QKICAgICAgICAgICAgc2VsZi5xdWl0ID0gMAogICAgICAgICAgICB3aGlsZSBub3Qgc2VsZi5xdWl0OgogICAgICAgICAgICAgICAgcmQsIHdyLCBleCA9IHNlbGVjdC5zZWxlY3QoW3NlbGYuc29ja2V0LmZpbGVubygpXSwgW10sIFtdLCAxKQogICAgICAgICAgICAgICAgaWYgcmQ6IHNlbGYuaGFuZGxlX3JlcXVlc3QoKQoKICAgICAgICBkZWYgc2VydmVyX2FjdGl2YXRlKHNlbGYpOgogICAgICAgICAgICBzZWxmLmJhc2Uuc2VydmVyX2FjdGl2YXRlKHNlbGYpCiAgICAgICAgICAgIGlmIHNlbGYuY2FsbGJhY2s6IHNlbGYuY2FsbGJhY2soc2VsZikKCiAgICBEb2NTZXJ2ZXIuYmFzZSA9IEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIKICAgIERvY1NlcnZlci5oYW5kbGVyID0gRG9jSGFuZGxlcgogICAgRG9jSGFuZGxlci5NZXNzYWdlQ2xhc3MgPSBNZXNzYWdlCiAgICB0cnk6CiAgICAgICAgRG9jU2VydmVyKHBvcnQsIGNhbGxiYWNrKS5zZXJ2ZV91bnRpbF9xdWl0KCkKICAgIGV4Y2VwdCAoS2V5Ym9hcmRJbnRlcnJ1cHQsIHNlbGVjdC5lcnJvcik6CiAgICAgICAgcGFzcwogICAgcHJpbnQgJ3NlcnZlciBzdG9wcGVkJwoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBncmFwaGljYWwgaW50ZXJmYWNlCgpkZWYgZ3VpKCk6CiAgICAiIiJHcmFwaGljYWwgaW50ZXJmYWNlIChzdGFydHMgd2ViIHNlcnZlciBhbmQgcG9wcyB1cCBhIGNvbnRyb2wgd2luZG93KS4iIiIKICAgIGNsYXNzIEdVSToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgd2luZG93LCBwb3J0PTc0NjQpOgogICAgICAgICAgICBzZWxmLndpbmRvdyA9IHdpbmRvdwogICAgICAgICAgICBzZWxmLnNlcnZlciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQoKICAgICAgICAgICAgaW1wb3J0IFRraW50ZXIKICAgICAgICAgICAgc2VsZi5zZXJ2ZXJfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYudGl0bGVfbGJsID0gVGtpbnRlci5MYWJlbChzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdTdGFydGluZyBzZXJ2ZXIuLi5cbiAnKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nb3BlbiBicm93c2VyJywgY29tbWFuZD1zZWxmLm9wZW4sIHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdxdWl0IHNlcnZpbmcnLCBjb21tYW5kPXNlbGYucXVpdCwgc3RhdGU9J2Rpc2FibGVkJykKCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwgPSBUa2ludGVyLkxhYmVsKHNlbGYuc2VhcmNoX2ZybSwgdGV4dD0nU2VhcmNoIGZvcicpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudCA9IFRraW50ZXIuRW50cnkoc2VsZi5zZWFyY2hfZnJtKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuYmluZCgnPFJldHVybj4nLCBzZWxmLnNlYXJjaCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VhcmNoX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J3N0b3AnLCBwYWR5PTAsIGNvbW1hbmQ9c2VsZi5zdG9wLCBzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgICMgQXR0ZW1wdGluZyB0byBoaWRlIGFuZCBzaG93IHRoaXMgYnV0dG9uIGNyYXNoZXMgdW5kZXIgV2luZG93cy4KICAgICAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCgogICAgICAgICAgICBzZWxmLndpbmRvdy50aXRsZSgncHlkb2MnKQogICAgICAgICAgICBzZWxmLndpbmRvdy5wcm90b2NvbCgnV01fREVMRVRFX1dJTkRPVycsIHNlbGYucXVpdCkKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5wYWNrKHNpZGU9J2xlZnQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4ucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5zZXJ2ZXJfZnJtLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCgogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuZm9jdXNfc2V0KCkKCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdCA9IFRraW50ZXIuTGlzdGJveCh3aW5kb3csIAogICAgICAgICAgICAgICAgZm9udD0oJ2hlbHZldGljYScsIDgpLCBoZWlnaHQ9NikKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxCdXR0b24tMT4nLCBzZWxmLnNlbGVjdCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmJpbmQoJzxEb3VibGUtQnV0dG9uLTE+Jywgc2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IgPSBUa2ludGVyLlNjcm9sbGJhcih3aW5kb3csCiAgICAgICAgICAgICAgICBvcmllbnQ9J3ZlcnRpY2FsJywgY29tbWFuZD1zZWxmLnJlc3VsdF9sc3QueXZpZXcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5jb25maWcoeXNjcm9sbGNvbW1hbmQ9c2VsZi5yZXN1bHRfc2NyLnNldCkKCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nZ28gdG8gc2VsZWN0ZWQnLCBjb21tYW5kPXNlbGYuZ290bykKICAgICAgICAgICAgc2VsZi5oaWRlX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYucmVzdWx0X2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J2hpZGUgcmVzdWx0cycsIGNvbW1hbmQ9c2VsZi5oaWRlKQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLnBhY2soc2lkZT0nbGVmdCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5oaWRlX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQoKICAgICAgICAgICAgc2VsZi53aW5kb3cudXBkYXRlKCkKICAgICAgICAgICAgc2VsZi5taW53aWR0aCA9IHNlbGYud2luZG93LndpbmZvX3dpZHRoKCkKICAgICAgICAgICAgc2VsZi5taW5oZWlnaHQgPSBzZWxmLndpbmRvdy53aW5mb19oZWlnaHQoKQogICAgICAgICAgICBzZWxmLmJpZ21pbmhlaWdodCA9IChzZWxmLnNlcnZlcl9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3Qud2luZm9fcmVxaGVpZ2h0KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0ud2luZm9fcmVxaGVpZ2h0KCkpCiAgICAgICAgICAgIHNlbGYuYmlnd2lkdGgsIHNlbGYuYmlnaGVpZ2h0ID0gc2VsZi5taW53aWR0aCwgc2VsZi5iaWdtaW5oZWlnaHQKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDAKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpCgogICAgICAgICAgICBpbXBvcnQgdGhyZWFkaW5nCiAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXNlcnZlLCBhcmdzPShwb3J0LCBzZWxmLnJlYWR5KSkuc3RhcnQoKQoKICAgICAgICBkZWYgcmVhZHkoc2VsZiwgc2VydmVyKToKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBzZXJ2ZXIKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwuY29uZmlnKAogICAgICAgICAgICAgICAgdGV4dD0nUHl0aG9uIGRvY3VtZW50YXRpb24gc2VydmVyIGF0XG4nICsgc2VydmVyLnVybCkKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgb3BlbihzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgd2ViYnJvd3Nlci5vcGVuKHNlbGYuc2VydmVyLnVybCkKCiAgICAgICAgZGVmIHF1aXQoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGlmIHNlbGYuc2VydmVyOgogICAgICAgICAgICAgICAgc2VsZi5zZXJ2ZXIucXVpdCA9IDEKICAgICAgICAgICAgc2VsZi53aW5kb3cucXVpdCgpCgogICAgICAgIGRlZiBzZWFyY2goc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGtleSA9IHNlbGYuc2VhcmNoX2VudC5nZXQoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLnBhY2soc2lkZT0ncmlnaHQnKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLmNvbmZpZyh0ZXh0PSdTZWFyY2hpbmcgZm9yICIlcyIuLi4nICUga2V5KQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5kZWxldGUoMCwgJ2VuZCcpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4uY29uZmlnKHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kKCkKCiAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgaWYgc2VsZi5zY2FubmVyOgogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyLnF1aXQgPSAxCiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE1vZHVsZVNjYW5uZXIoKQogICAgICAgICAgICB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1zZWxmLnNjYW5uZXIucnVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3M9KGtleSwgc2VsZi51cGRhdGUsIHNlbGYuZG9uZSkpLnN0YXJ0KCkKCiAgICAgICAgZGVmIHVwZGF0ZShzZWxmLCBwYXRoLCBtb2RuYW1lLCBkZXNjKToKICAgICAgICAgICAgaWYgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZG5hbWVbOi05XSArICcgKHBhY2thZ2UpJwogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuaW5zZXJ0KCdlbmQnLAogICAgICAgICAgICAgICAgbW9kbmFtZSArICcgLSAnICsgKGRlc2Mgb3IgJyhubyBkZXNjcmlwdGlvbiknKSkKCiAgICAgICAgZGVmIHN0b3Aoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGlmIHNlbGYuc2Nhbm5lcjoKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lci5xdWl0ID0gMQogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQoKICAgICAgICBkZWYgZG9uZShzZWxmKToKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwuY29uZmlnKHRleHQ9J1NlYXJjaCBmb3InKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAnd2luMzInOiBzZWxmLnN0b3BfYnRuLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4uY29uZmlnKHN0YXRlPSdkaXNhYmxlZCcpCgogICAgICAgIGRlZiBzZWxlY3Qoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGYuZ290b19idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgZ290byhzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZWN0aW9uID0gc2VsZi5yZXN1bHRfbHN0LmN1cnNlbGVjdGlvbigpCiAgICAgICAgICAgIGlmIHNlbGVjdGlvbjoKICAgICAgICAgICAgICAgIGltcG9ydCB3ZWJicm93c2VyCiAgICAgICAgICAgICAgICBtb2RuYW1lID0gc3BsaXQoc2VsZi5yZXN1bHRfbHN0LmdldChzZWxlY3Rpb25bMF0pKVswXQogICAgICAgICAgICAgICAgd2ViYnJvd3Nlci5vcGVuKHNlbGYuc2VydmVyLnVybCArIG1vZG5hbWUgKyAnLmh0bWwnKQoKICAgICAgICBkZWYgY29sbGFwc2Uoc2VsZik6CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLmV4cGFuZGVkOiByZXR1cm4KICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3Njci5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5iaWd3aWR0aCA9IHNlbGYud2luZG93LndpbmZvX3dpZHRoKCkKICAgICAgICAgICAgc2VsZi5iaWdoZWlnaHQgPSBzZWxmLndpbmRvdy53aW5mb19oZWlnaHQoKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDAKCiAgICAgICAgZGVmIGV4cGFuZChzZWxmKToKICAgICAgICAgICAgaWYgc2VsZi5leHBhbmRlZDogcmV0dXJuCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS5wYWNrKHNpZGU9J2JvdHRvbScsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3knKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QucGFjayhzaWRlPSd0b3AnLCBmaWxsPSdib3RoJywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5iaWd3aWR0aCwgc2VsZi5iaWdoZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYuYmlnbWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMQoKICAgICAgICBkZWYgaGlkZShzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZi5zdG9wKCkKICAgICAgICAgICAgc2VsZi5jb2xsYXBzZSgpCgogICAgaW1wb3J0IFRraW50ZXIKICAgIHRyeToKICAgICAgICBndWkgPSBHVUkoVGtpbnRlci5UaygpKQogICAgICAgIFRraW50ZXIubWFpbmxvb3AoKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHBhc3MKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29tbWFuZC1saW5lIGludGVyZmFjZQoKZGVmIGNsaSgpOgogICAgIiIiQ29tbWFuZC1saW5lIGludGVyZmFjZSAobG9va3MgYXQgc3lzLmFyZ3YgdG8gZGVjaWRlIHdoYXQgdG8gZG8pLiIiIgogICAgaW1wb3J0IGdldG9wdAogICAgY2xhc3MgQmFkVXNhZ2U6IHBhc3MKCiAgICB0cnk6CiAgICAgICAgaWYgc3lzLnBsYXRmb3JtIGluIFsnbWFjJywgJ3dpbicsICd3aW4zMicsICdudCddIGFuZCBub3Qgc3lzLmFyZ3ZbMTpdOgogICAgICAgICAgICAjIENMSS1sZXNzIHBsYXRmb3JtcwogICAgICAgICAgICBndWkoKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgb3B0cywgYXJncyA9IGdldG9wdC5nZXRvcHQoc3lzLmFyZ3ZbMTpdLCAnZ2s6cDp3JykKICAgICAgICB3cml0aW5nID0gMAoKICAgICAgICBmb3Igb3B0LCB2YWwgaW4gb3B0czoKICAgICAgICAgICAgaWYgb3B0ID09ICctZyc6CiAgICAgICAgICAgICAgICBndWkoKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLWsnOgogICAgICAgICAgICAgICAgYXByb3Bvcyh2YWwpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctcCc6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcG9ydCA9IGludCh2YWwpCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICByYWlzZSBCYWRVc2FnZQogICAgICAgICAgICAgICAgZGVmIHJlYWR5KHNlcnZlcik6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgJ3NlcnZlciByZWFkeSBhdCAlcycgJSBzZXJ2ZXIudXJsCiAgICAgICAgICAgICAgICBzZXJ2ZShwb3J0LCByZWFkeSkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy13JzoKICAgICAgICAgICAgICAgIHdyaXRpbmcgPSAxCgogICAgICAgIGlmIG5vdCBhcmdzOiByYWlzZSBCYWRVc2FnZQogICAgICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgZmluZChhcmcsIG9zLnNlcCkgPj0gMCBhbmQgb3MucGF0aC5pc2ZpbGUoYXJnKToKICAgICAgICAgICAgICAgICAgICBhcmcgPSBpbXBvcnRmaWxlKGFyZykKICAgICAgICAgICAgICAgIGlmIHdyaXRpbmc6IHdyaXRlZG9jKGFyZykKICAgICAgICAgICAgICAgIGVsc2U6IG1hbihhcmcpCiAgICAgICAgICAgIGV4Y2VwdCBEb2NJbXBvcnRFcnJvciwgdmFsdWU6CiAgICAgICAgICAgICAgICBwcmludCAnUHJvYmxlbSBpbiAlcyAtICVzJyAlICh2YWx1ZS5maWxlbmFtZSwgdmFsdWUuYXJncykKCiAgICBleGNlcHQgKGdldG9wdC5lcnJvciwgQmFkVXNhZ2UpOgogICAgICAgIGNtZCA9IHN5cy5hcmd2WzBdCiAgICAgICAgcHJpbnQgIiIicHlkb2MgLSB0aGUgUHl0aG9uIGRvY3VtZW50YXRpb24gdG9vbAoKJXMgPG5hbWU+IC4uLgogICAgU2hvdyB0ZXh0IGRvY3VtZW50YXRpb24gb24gc29tZXRoaW5nLiAgPG5hbWU+IG1heSBiZSB0aGUgbmFtZSBvZiBhCiAgICBmdW5jdGlvbiwgbW9kdWxlLCBvciBwYWNrYWdlLCBvciBhIGRvdHRlZCByZWZlcmVuY2UgdG8gYSBjbGFzcyBvcgogICAgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiA8bmFtZT4gY29udGFpbnMKICAgIGEgJyVzJywgaXQgaXMgdXNlZCBhcyB0aGUgcGF0aCB0byBhIFB5dGhvbiBzb3VyY2UgZmlsZSB0byBkb2N1bWVudC4KCiVzIC1rIDxrZXl3b3JkPgogICAgU2VhcmNoIGZvciBhIGtleXdvcmQgaW4gdGhlIHN5bm9wc2lzIGxpbmVzIG9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KCiVzIC1wIDxwb3J0PgogICAgU3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gdGhlIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUuCgolcyAtZwogICAgUG9wIHVwIGEgZ3JhcGhpY2FsIGludGVyZmFjZSBmb3Igc2VydmluZyBhbmQgZmluZGluZyBkb2N1bWVudGF0aW9uLgoKJXMgLXcgPG5hbWU+IC4uLgogICAgV3JpdGUgb3V0IHRoZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudAogICAgZGlyZWN0b3J5LiAgSWYgPG5hbWU+IGNvbnRhaW5zIGEgJyVzJywgaXQgaXMgdHJlYXRlZCBhcyBhIGZpbGVuYW1lLgoiIiIgJSAoY21kLCBvcy5zZXAsIGNtZCwgY21kLCBjbWQsIGNtZCwgb3Muc2VwKQoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzogY2xpKCkKCgo=