IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiIiIkdlbmVyYXRlIFB5dGhvbiBkb2N1bWVudGF0aW9uIGluIEhUTUwgb3IgdGV4dCBmb3IgaW50ZXJhY3RpdmUgdXNlLgoKSW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlciwgZG8gImZyb20gcHlkb2MgaW1wb3J0IGhlbHAiIHRvIHByb3ZpZGUgb25saW5lCmhlbHAuICBDYWxsaW5nIGhlbHAodGhpbmcpIG9uIGEgUHl0aG9uIG9iamVjdCBkb2N1bWVudHMgdGhlIG9iamVjdC4KCk9yLCBhdCB0aGUgc2hlbGwgY29tbWFuZCBsaW5lIG91dHNpZGUgb2YgUHl0aG9uOgoKUnVuICJweWRvYyA8bmFtZT4iIHRvIHNob3cgZG9jdW1lbnRhdGlvbiBvbiBzb21ldGhpbmcuICA8bmFtZT4gbWF5IGJlCnRoZSBuYW1lIG9mIGEgZnVuY3Rpb24sIG1vZHVsZSwgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEKY2xhc3Mgb3IgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiB0aGUKYXJndW1lbnQgY29udGFpbnMgYSBwYXRoIHNlZ21lbnQgZGVsaW1pdGVyIChlLmcuIHNsYXNoIG9uIFVuaXgsCmJhY2tzbGFzaCBvbiBXaW5kb3dzKSBpdCBpcyB0cmVhdGVkIGFzIHRoZSBwYXRoIHRvIGEgUHl0aG9uIHNvdXJjZSBmaWxlLgoKUnVuICJweWRvYyAtayA8a2V5d29yZD4iIHRvIHNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcwpvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgpSdW4gInB5ZG9jIC1wIDxwb3J0PiIgdG8gc3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gYSBnaXZlbiBwb3J0IG9uIHRoZQpsb2NhbCBtYWNoaW5lIHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gd2ViIHBhZ2VzLgoKRm9yIHBsYXRmb3JtcyB3aXRob3V0IGEgY29tbWFuZCBsaW5lLCAicHlkb2MgLWciIHN0YXJ0cyB0aGUgSFRUUCBzZXJ2ZXIKYW5kIGFsc28gcG9wcyB1cCBhIGxpdHRsZSB3aW5kb3cgZm9yIGNvbnRyb2xsaW5nIGl0LgoKUnVuICJweWRvYyAtdyA8bmFtZT4iIHRvIHdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZQp0byBhIGZpbGUgbmFtZWQgIjxuYW1lPi5odG1sIi4KIiIiCgpfX2F1dGhvcl9fID0gIkthLVBpbmcgWWVlIDxwaW5nQGxmdy5vcmc+IgpfX2RhdGVfXyA9ICIyNiBGZWJydWFyeSAyMDAxIgpfX3ZlcnNpb25fXyA9ICIkUmV2aXNpb24kIgpfX2NyZWRpdHNfXyA9ICIiIkd1aWRvIHZhbiBSb3NzdW0sIGZvciBhbiBleGNlbGxlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuClRvbW15IEJ1cm5ldHRlLCB0aGUgb3JpZ2luYWwgY3JlYXRvciBvZiBtYW5weS4KUGF1bCBQcmVzY29kLCBmb3IgYWxsIGhpcyB3b3JrIG9uIG9ubGluZWhlbHAuClJpY2hhcmQgQ2hhbWJlcmxhaW4sIGZvciB0aGUgZmlyc3QgaW1wbGVtZW50YXRpb24gb2YgdGV4dGRvYy4KCk15bmQgeW91LCBt+PhzZSBiaXRlcyBLYW4gYmUgcHJldHR5IG5hc3RpLi4uIiIiCgojIEtub3duIGJ1Z3MgdGhhdCBjYW4ndCBiZSBmaXhlZCBoZXJlOgojICAgLSBpbXAubG9hZF9tb2R1bGUoKSBjYW5ub3QgYmUgcHJldmVudGVkIGZyb20gY2xvYmJlcmluZyBleGlzdGluZwojICAgICBsb2FkZWQgbW9kdWxlcywgc28gY2FsbGluZyBzeW5vcHNpcygpIG9uIGEgYmluYXJ5IG1vZHVsZSBmaWxlCiMgICAgIGNoYW5nZXMgdGhlIGNvbnRlbnRzIG9mIGFueSBleGlzdGluZyBtb2R1bGUgd2l0aCB0aGUgc2FtZSBuYW1lLgojICAgLSBJZiB0aGUgX19maWxlX18gYXR0cmlidXRlIG9uIGEgbW9kdWxlIGlzIGEgcmVsYXRpdmUgcGF0aCBhbmQKIyAgICAgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IGlzIGNoYW5nZWQgd2l0aCBvcy5jaGRpcigpLCBhbiBpbmNvcnJlY3QKIyAgICAgcGF0aCB3aWxsIGJlIGRpc3BsYXllZC4KCmltcG9ydCBzeXMsIGltcCwgb3MsIHN0YXQsIHJlLCB0eXBlcywgaW5zcGVjdApmcm9tIHJlcHIgaW1wb3J0IFJlcHIKZnJvbSBzdHJpbmcgaW1wb3J0IGV4cGFuZHRhYnMsIGZpbmQsIGpvaW4sIGxvd2VyLCBzcGxpdCwgc3RyaXAsIHJmaW5kLCByc3RyaXAKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1vbiByb3V0aW5lcwoKZGVmIHBhdGhkaXJzKCk6CiAgICAiIiJDb252ZXJ0IHN5cy5wYXRoIGludG8gYSBsaXN0IG9mIGFic29sdXRlLCBleGlzdGluZywgdW5pcXVlIHBhdGhzLiIiIgogICAgZGlycyA9IFtdCiAgICBub3JtZGlycyA9IFtdCiAgICBmb3IgZGlyIGluIHN5cy5wYXRoOgogICAgICAgIGRpciA9IG9zLnBhdGguYWJzcGF0aChkaXIgb3IgJy4nKQogICAgICAgIG5vcm1kaXIgPSBvcy5wYXRoLm5vcm1jYXNlKGRpcikKICAgICAgICBpZiBub3JtZGlyIG5vdCBpbiBub3JtZGlycyBhbmQgb3MucGF0aC5pc2RpcihkaXIpOgogICAgICAgICAgICBkaXJzLmFwcGVuZChkaXIpCiAgICAgICAgICAgIG5vcm1kaXJzLmFwcGVuZChub3JtZGlyKQogICAgcmV0dXJuIGRpcnMKCmRlZiBnZXRkb2Mob2JqZWN0KToKICAgICIiIkdldCB0aGUgZG9jIHN0cmluZyBvciBjb21tZW50cyBmb3IgYW4gb2JqZWN0LiIiIgogICAgcmVzdWx0ID0gaW5zcGVjdC5nZXRkb2Mob2JqZWN0KSBvciBpbnNwZWN0LmdldGNvbW1lbnRzKG9iamVjdCkKICAgIHJldHVybiByZXN1bHQgYW5kIHJlLnN1YignXiAqXG4nLCAnJywgcnN0cmlwKHJlc3VsdCkpIG9yICcnCgpkZWYgc3BsaXRkb2MoZG9jKToKICAgICIiIlNwbGl0IGEgZG9jIHN0cmluZyBpbnRvIGEgc3lub3BzaXMgbGluZSAoaWYgYW55KSBhbmQgdGhlIHJlc3QuIiIiCiAgICBsaW5lcyA9IHNwbGl0KHN0cmlwKGRvYyksICdcbicpCiAgICBpZiBsZW4obGluZXMpID09IDE6CiAgICAgICAgcmV0dXJuIGxpbmVzWzBdLCAnJwogICAgZWxpZiBsZW4obGluZXMpID49IDIgYW5kIG5vdCByc3RyaXAobGluZXNbMV0pOgogICAgICAgIHJldHVybiBsaW5lc1swXSwgam9pbihsaW5lc1syOl0sICdcbicpCiAgICByZXR1cm4gJycsIGpvaW4obGluZXMsICdcbicpCgpkZWYgY2xhc3NuYW1lKG9iamVjdCwgbW9kbmFtZSk6CiAgICAiIiJHZXQgYSBjbGFzcyBuYW1lIGFuZCBxdWFsaWZ5IGl0IHdpdGggYSBtb2R1bGUgbmFtZSBpZiBuZWNlc3NhcnkuIiIiCiAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICBpZiBvYmplY3QuX19tb2R1bGVfXyAhPSBtb2RuYW1lOgogICAgICAgIG5hbWUgPSBvYmplY3QuX19tb2R1bGVfXyArICcuJyArIG5hbWUKICAgIHJldHVybiBuYW1lCgpkZWYgaXNkYXRhKG9iamVjdCk6CiAgICAiIiJDaGVjayBpZiBhbiBvYmplY3QgaXMgb2YgYSB0eXBlIHRoYXQgcHJvYmFibHkgbWVhbnMgaXQncyBkYXRhLiIiIgogICAgcmV0dXJuIG5vdCAoaW5zcGVjdC5pc21vZHVsZShvYmplY3QpIG9yIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpIG9yCiAgICAgICAgICAgICAgICBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpIG9yIGluc3BlY3QuaXNmcmFtZShvYmplY3QpIG9yCiAgICAgICAgICAgICAgICBpbnNwZWN0LmlzdHJhY2ViYWNrKG9iamVjdCkgb3IgaW5zcGVjdC5pc2NvZGUob2JqZWN0KSkKCmRlZiByZXBsYWNlKHRleHQsICpwYWlycyk6CiAgICAiIiJEbyBhIHNlcmllcyBvZiBnbG9iYWwgcmVwbGFjZW1lbnRzIG9uIGEgc3RyaW5nLiIiIgogICAgd2hpbGUgcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgcGFpcnNbMF0pLCBwYWlyc1sxXSkKICAgICAgICBwYWlycyA9IHBhaXJzWzI6XQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvMikKICAgICAgICBwb3N0ID0gbWF4KDAsIG1heGxlbi0zLXByZSkKICAgICAgICByZXR1cm4gdGV4dFs6cHJlXSArICcuLi4nICsgdGV4dFtsZW4odGV4dCktcG9zdDpdCiAgICByZXR1cm4gdGV4dAoKZGVmIHN0cmlwaWQodGV4dCk6CiAgICAiIiJSZW1vdmUgdGhlIGhleGFkZWNpbWFsIGlkIGZyb20gYSBQeXRob24gb2JqZWN0IHJlcHJlc2VudGF0aW9uLiIiIgogICAgIyBUaGUgYmVoYXZpb3VyIG9mICVwIGlzIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudDsgd2UgY2hlY2sgdHdvIGNhc2VzLgogICAgZm9yIHBhdHRlcm4gaW4gWycgYXQgMHhbMC05YS1mXXs2LH0+JCcsICcgYXQgWzAtOUEtRl17OCx9PiQnXToKICAgICAgICBpZiByZS5zZWFyY2gocGF0dGVybiwgcmVwcihFeGNlcHRpb24pKToKICAgICAgICAgICAgcmV0dXJuIHJlLnN1YihwYXR0ZXJuLCAnPicsIHRleHQpCiAgICByZXR1cm4gdGV4dAoKZGVmIF9pc19zb21lX21ldGhvZChvYmplY3QpOgogICAgcmV0dXJuIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KSBvciBpbnNwZWN0LmlzbWV0aG9kZGVzY3JpcHRvcihvYmplY3QpCgpkZWYgYWxsbWV0aG9kcyhjbCk6CiAgICBtZXRob2RzID0ge30KICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhjbCwgX2lzX3NvbWVfbWV0aG9kKToKICAgICAgICBtZXRob2RzW2tleV0gPSAxCiAgICBmb3IgYmFzZSBpbiBjbC5fX2Jhc2VzX186CiAgICAgICAgbWV0aG9kcy51cGRhdGUoYWxsbWV0aG9kcyhiYXNlKSkgIyBhbGwgeW91ciBiYXNlIGFyZSBiZWxvbmcgdG8gdXMKICAgIGZvciBrZXkgaW4gbWV0aG9kcy5rZXlzKCk6CiAgICAgICAgbWV0aG9kc1trZXldID0gZ2V0YXR0cihjbCwga2V5KQogICAgcmV0dXJuIG1ldGhvZHMKCmRlZiBfc3BsaXRfbGlzdChzLCBwcmVkaWNhdGUpOgogICAgIiIiU3BsaXQgc2VxdWVuY2UgcyB2aWEgcHJlZGljYXRlLCBhbmQgcmV0dXJuIHBhaXIgKFt0cnVlXSwgW2ZhbHNlXSkuCgogICAgVGhlIHJldHVybiB2YWx1ZSBpcyBhIDItdHVwbGUgb2YgbGlzdHMsCiAgICAgICAgKFt4IGZvciB4IGluIHMgaWYgcHJlZGljYXRlKHgpXSwKICAgICAgICAgW3ggZm9yIHggaW4gcyBpZiBub3QgcHJlZGljYXRlKHgpXSkKICAgICIiIgoKICAgIHllcyA9IFtdCiAgICBubyA9IFtdCiAgICBmb3IgeCBpbiBzOgogICAgICAgIGlmIHByZWRpY2F0ZSh4KToKICAgICAgICAgICAgeWVzLmFwcGVuZCh4KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG5vLmFwcGVuZCh4KQogICAgcmV0dXJuIHllcywgbm8KCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gbW9kdWxlIG1hbmlwdWxhdGlvbgoKZGVmIGlzcGFja2FnZShwYXRoKToKICAgICIiIkd1ZXNzIHdoZXRoZXIgYSBwYXRoIHJlZmVycyB0byBhIHBhY2thZ2UgZGlyZWN0b3J5LiIiIgogICAgaWYgb3MucGF0aC5pc2RpcihwYXRoKToKICAgICAgICBmb3IgZXh0IGluIFsnLnB5JywgJy5weWMnLCAnLnB5byddOgogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShvcy5wYXRoLmpvaW4ocGF0aCwgJ19faW5pdF9fJyArIGV4dCkpOgogICAgICAgICAgICAgICAgcmV0dXJuIDEKCmRlZiBzeW5vcHNpcyhmaWxlbmFtZSwgY2FjaGU9e30pOgogICAgIiIiR2V0IHRoZSBvbmUtbGluZSBzdW1tYXJ5IG91dCBvZiBhIG1vZHVsZSBmaWxlLiIiIgogICAgbXRpbWUgPSBvcy5zdGF0KGZpbGVuYW1lKVtzdGF0LlNUX01USU1FXQogICAgbGFzdHVwZGF0ZSwgcmVzdWx0ID0gY2FjaGUuZ2V0KGZpbGVuYW1lLCAoMCwgTm9uZSkpCiAgICBpZiBsYXN0dXBkYXRlIDwgbXRpbWU6CiAgICAgICAgaW5mbyA9IGluc3BlY3QuZ2V0bW9kdWxlaW5mbyhmaWxlbmFtZSkKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBpZiBpbmZvIGFuZCAnYicgaW4gaW5mb1syXTogIyBiaW5hcnkgbW9kdWxlcyBoYXZlIHRvIGJlIGltcG9ydGVkCiAgICAgICAgICAgIHRyeTogbW9kdWxlID0gaW1wLmxvYWRfbW9kdWxlKCdfX3RlbXBfXycsIGZpbGUsIGZpbGVuYW1lLCBpbmZvWzE6XSkKICAgICAgICAgICAgZXhjZXB0OiByZXR1cm4gTm9uZQogICAgICAgICAgICByZXN1bHQgPSBzcGxpdChtb2R1bGUuX19kb2NfXyBvciAnJywgJ1xuJylbMF0KICAgICAgICAgICAgZGVsIHN5cy5tb2R1bGVzWydfX3RlbXBfXyddCiAgICAgICAgZWxzZTogIyB0ZXh0IG1vZHVsZXMgY2FuIGJlIGRpcmVjdGx5IGV4YW1pbmVkCiAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgd2hpbGUgbGluZVs6MV0gPT0gJyMnIG9yIG5vdCBzdHJpcChsaW5lKToKICAgICAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICBsaW5lID0gc3RyaXAobGluZSkKICAgICAgICAgICAgaWYgbGluZVs6NF0gPT0gJ3IiIiInOiBsaW5lID0gbGluZVsxOl0KICAgICAgICAgICAgaWYgbGluZVs6M10gPT0gJyIiIic6CiAgICAgICAgICAgICAgICBsaW5lID0gbGluZVszOl0KICAgICAgICAgICAgICAgIGlmIGxpbmVbLTE6XSA9PSAnXFwnOiBsaW5lID0gbGluZVs6LTFdCiAgICAgICAgICAgICAgICB3aGlsZSBub3Qgc3RyaXAobGluZSk6CiAgICAgICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICAgICAgcmVzdWx0ID0gc3RyaXAoc3BsaXQobGluZSwgJyIiIicpWzBdKQogICAgICAgICAgICBlbHNlOiByZXN1bHQgPSBOb25lCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgY2FjaGVbZmlsZW5hbWVdID0gKG10aW1lLCByZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0CgpjbGFzcyBFcnJvckR1cmluZ0ltcG9ydChFeGNlcHRpb24pOgogICAgIiIiRXJyb3JzIHRoYXQgb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIChleGMsIHZhbHVlLCB0YikpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXhjID0gZXhjCiAgICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgc2VsZi50YiA9IHRiCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgZXhjID0gc2VsZi5leGMKICAgICAgICBpZiB0eXBlKGV4YykgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBleGMgPSBleGMuX19uYW1lX18KICAgICAgICByZXR1cm4gJ3Byb2JsZW0gaW4gJXMgLSAlczogJXMnICUgKHNlbGYuZmlsZW5hbWUsIGV4Yywgc2VsZi52YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHBhdGgsIHN5cy5leGNfaW5mbygpKQogICAgZmlsZS5jbG9zZSgpCiAgICByZXR1cm4gbW9kdWxlCgpkZWYgc2FmZWltcG9ydChwYXRoLCBmb3JjZWxvYWQ9MCwgY2FjaGU9e30pOgogICAgIiIiSW1wb3J0IGEgbW9kdWxlOyBoYW5kbGUgZXJyb3JzOyByZXR1cm4gTm9uZSBpZiB0aGUgbW9kdWxlIGlzbid0IGZvdW5kLgoKICAgIElmIHRoZSBtb2R1bGUgKmlzKiBmb3VuZCBidXQgYW4gZXhjZXB0aW9uIG9jY3VycywgaXQncyB3cmFwcGVkIGluIGFuCiAgICBFcnJvckR1cmluZ0ltcG9ydCBleGNlcHRpb24gYW5kIHJlcmFpc2VkLiAgVW5saWtlIF9faW1wb3J0X18sIGlmIGEKICAgIHBhY2thZ2UgcGF0aCBpcyBzcGVjaWZpZWQsIHRoZSBtb2R1bGUgYXQgdGhlIGVuZCBvZiB0aGUgcGF0aCBpcyByZXR1cm5lZCwKICAgIG5vdCB0aGUgcGFja2FnZSBhdCB0aGUgYmVnaW5uaW5nLiAgSWYgdGhlIG9wdGlvbmFsICdmb3JjZWxvYWQnIGFyZ3VtZW50CiAgICBpcyAxLCB3ZSByZWxvYWQgdGhlIG1vZHVsZSBmcm9tIGRpc2sgKHVubGVzcyBpdCdzIGEgZHluYW1pYyBleHRlbnNpb24pLiIiIgogICAgaWYgZm9yY2Vsb2FkIGFuZCBzeXMubW9kdWxlcy5oYXNfa2V5KHBhdGgpOgogICAgICAgICMgVGhpcyBpcyB0aGUgb25seSB3YXkgdG8gYmUgc3VyZS4gIENoZWNraW5nIHRoZSBtdGltZSBvZiB0aGUgZmlsZQogICAgICAgICMgaXNuJ3QgZ29vZCBlbm91Z2ggKGUuZy4gd2hhdCBpZiB0aGUgbW9kdWxlIGNvbnRhaW5zIGEgY2xhc3MgdGhhdAogICAgICAgICMgaW5oZXJpdHMgZnJvbSBhbm90aGVyIG1vZHVsZSB0aGF0IGhhcyBjaGFuZ2VkPykuCiAgICAgICAgaWYgcGF0aCBub3QgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICAjIFB5dGhvbiBuZXZlciBsb2FkcyBhIGR5bmFtaWMgZXh0ZW5zaW9uIGEgc2Vjb25kIHRpbWUgZnJvbSB0aGUKICAgICAgICAgICAgIyBzYW1lIHBhdGgsIGV2ZW4gaWYgdGhlIGZpbGUgaXMgY2hhbmdlZCBvciBtaXNzaW5nLiAgRGVsZXRpbmcKICAgICAgICAgICAgIyB0aGUgZW50cnkgaW4gc3lzLm1vZHVsZXMgZG9lc24ndCBoZWxwIGZvciBkeW5hbWljIGV4dGVuc2lvbnMsCiAgICAgICAgICAgICMgc28gd2UncmUgbm90IGV2ZW4gZ29pbmcgdG8gdHJ5IHRvIGtlZXAgdGhlbSB1cCB0byBkYXRlLgogICAgICAgICAgICBpbmZvID0gaW5zcGVjdC5nZXRtb2R1bGVpbmZvKHN5cy5tb2R1bGVzW3BhdGhdLl9fZmlsZV9fKQogICAgICAgICAgICBpZiBpbmZvWzNdICE9IGltcC5DX0VYVEVOU0lPTjoKICAgICAgICAgICAgICAgIGNhY2hlW3BhdGhdID0gc3lzLm1vZHVsZXNbcGF0aF0gIyBwcmV2ZW50IG1vZHVsZSBmcm9tIGNsZWFyaW5nCiAgICAgICAgICAgICAgICBkZWwgc3lzLm1vZHVsZXNbcGF0aF0KICAgIHRyeToKICAgICAgICBtb2R1bGUgPSBfX2ltcG9ydF9fKHBhdGgpCiAgICBleGNlcHQ6CiAgICAgICAgIyBEaWQgdGhlIGVycm9yIG9jY3VyIGJlZm9yZSBvciBhZnRlciB0aGUgbW9kdWxlIHdhcyBmb3VuZD8KICAgICAgICAoZXhjLCB2YWx1ZSwgdGIpID0gaW5mbyA9IHN5cy5leGNfaW5mbygpCiAgICAgICAgaWYgc3lzLm1vZHVsZXMuaGFzX2tleShwYXRoKToKICAgICAgICAgICAgIyBBbiBlcnJvciBvY2N1cmVkIHdoaWxlIGV4ZWN1dGluZyB0aGUgaW1wb3J0ZWQgbW9kdWxlLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXywgaW5mbykKICAgICAgICBlbGlmIGV4YyBpcyBTeW50YXhFcnJvcjoKICAgICAgICAgICAgIyBBIFN5bnRheEVycm9yIG9jY3VycmVkIGJlZm9yZSB3ZSBjb3VsZCBleGVjdXRlIHRoZSBtb2R1bGUuCiAgICAgICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHZhbHVlLmZpbGVuYW1lLCBpbmZvKQogICAgICAgIGVsaWYgZXhjIGlzIEltcG9ydEVycm9yIGFuZCBcCiAgICAgICAgICAgICBzcGxpdChsb3dlcihzdHIodmFsdWUpKSlbOjJdID09IFsnbm8nLCAnbW9kdWxlJ106CiAgICAgICAgICAgICMgVGhlIG1vZHVsZSB3YXMgbm90IGZvdW5kLgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgU29tZSBvdGhlciBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGltcG9ydGluZyBwcm9jZXNzLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChwYXRoLCBzeXMuZXhjX2luZm8oKSkKICAgIGZvciBwYXJ0IGluIHNwbGl0KHBhdGgsICcuJylbMTpdOgogICAgICAgIHRyeTogbW9kdWxlID0gZ2V0YXR0cihtb2R1bGUsIHBhcnQpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgcmV0dXJuIG1vZHVsZQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsICphcmdzKToKICAgICAgICAiIiJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgYXJncyA9IChvYmplY3QsIG5hbWUpICsgYXJncwogICAgICAgIGlmIGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KTogcmV0dXJuIGFwcGx5KHNlbGYuZG9jbW9kdWxlLCBhcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2NjbGFzcywgYXJncykKICAgICAgICBpZiBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpOiByZXR1cm4gYXBwbHkoc2VsZi5kb2Nyb3V0aW5lLCBhcmdzKQogICAgICAgIHJldHVybiBhcHBseShzZWxmLmRvY290aGVyLCBhcmdzKQoKICAgIGRlZiBmYWlsKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCAqYXJncyk6CiAgICAgICAgIiIiUmFpc2UgYW4gZXhjZXB0aW9uIGZvciB1bmltcGxlbWVudGVkIHR5cGVzLiIiIgogICAgICAgIG1lc3NhZ2UgPSAiZG9uJ3Qga25vdyBob3cgdG8gZG9jdW1lbnQgb2JqZWN0JXMgb2YgdHlwZSAlcyIgJSAoCiAgICAgICAgICAgIG5hbWUgYW5kICcgJyArIHJlcHIobmFtZSksIHR5cGUob2JqZWN0KS5fX25hbWVfXykKICAgICAgICByYWlzZSBUeXBlRXJyb3IsIG1lc3NhZ2UKCiAgICBkb2Ntb2R1bGUgPSBkb2NjbGFzcyA9IGRvY3JvdXRpbmUgPSBkb2NvdGhlciA9IGZhaWwKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IDIwCiAgICAgICAgc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSAxMDAKCiAgICBkZWYgZXNjYXBlKHNlbGYsIHRleHQpOgogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICcmJywgJyZhbXA7JywgJzwnLCAnJmx0OycsICc+JywgJyZndDsnKQoKICAgIGRlZiByZXByKHNlbGYsIG9iamVjdCk6CiAgICAgICAgcmV0dXJuIFJlcHIucmVwcihzZWxmLCBvYmplY3QpCgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKSkKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRlc3QgPSBjcmFtKHgsIHNlbGYubWF4c3RyaW5nKQogICAgICAgIHRlc3RyZXByID0gcmVwcih0ZXN0KQogICAgICAgIGlmICdcXCcgaW4gdGVzdCBhbmQgJ1xcJyBub3QgaW4gcmVwbGFjZSh0ZXN0cmVwciwgcidcXCcsICcnKToKICAgICAgICAgICAgIyBCYWNrc2xhc2hlcyBhcmUgb25seSBsaXRlcmFsIGluIHRoZSBzdHJpbmcgYW5kIGFyZSBuZXZlcgogICAgICAgICAgICAjIG5lZWRlZCB0byBtYWtlIGFueSBzcGVjaWFsIGNoYXJhY3RlcnMsIHNvIHNob3cgYSByYXcgc3RyaW5nLgogICAgICAgICAgICByZXR1cm4gJ3InICsgdGVzdHJlcHJbMF0gKyBzZWxmLmVzY2FwZSh0ZXN0KSArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHJlLnN1YihyJygoXFxbXFxhYmZucnR2XCciXXxcXFswLTldLi58XFx4Li58XFx1Li4uLikrKScsCiAgICAgICAgICAgICAgICAgICAgICByJzxmb250IGNvbG9yPSIjYzA0MGMwIj5cMTwvZm9udD4nLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi5lc2NhcGUodGVzdHJlcHIpKQoKICAgIHJlcHJfc3RyID0gcmVwcl9zdHJpbmcKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18pCgogICAgcmVwcl91bmljb2RlID0gcmVwcl9zdHJpbmcKCmNsYXNzIEhUTUxEb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgSFRNTCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVE1MIGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBIVE1MUmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgogICAgZXNjYXBlID0gX3JlcHJfaW5zdGFuY2UuZXNjYXBlCgogICAgZGVmIHBhZ2Uoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYW4gSFRNTCBwYWdlLiIiIgogICAgICAgIHJldHVybiAnJycKPCFkb2N0eXBlIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PGhlYWQ+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhLS0KVFQgeyBmb250LWZhbWlseTogbHVjaWRhdHlwZXdyaXRlciwgbHVjaWRhIGNvbnNvbGUsIGNvdXJpZXIgfQotLT48L3N0eWxlPjwvaGVhZD48Ym9keSBiZ2NvbG9yPSIjZjBmMGY4Ij4KJXMKPC9ib2R5PjwvaHRtbD4nJycgJSAodGl0bGUsIGNvbnRlbnRzKQoKICAgIGRlZiBoZWFkaW5nKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGV4dHJhcz0nJyk6CiAgICAgICAgIiIiRm9ybWF0IGEgcGFnZSBoZWFkaW5nLiIiIgogICAgICAgIHJldHVybiAnJycKPHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wIHN1bW1hcnk9ImhlYWRpbmciPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgdmFsaWduPWJvdHRvbT4mbmJzcDs8YnI+Cjxmb250IGNvbG9yPSIlcyIgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+Jm5ic3A7PGJyPiVzPC9mb250PjwvdGQKPjx0ZCBhbGlnbj1yaWdodCB2YWxpZ249Ym90dG9tCj48Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj48L3RhYmxlPgogICAgJycnICUgKGJnY29sLCBmZ2NvbCwgdGl0bGUsIGZnY29sLCBleHRyYXMgb3IgJyZuYnNwOycpCgogICAgZGVmIHNlY3Rpb24oc2VsZiwgdGl0bGUsIGZnY29sLCBiZ2NvbCwgY29udGVudHMsIHdpZHRoPTEwLAogICAgICAgICAgICAgICAgcHJlbHVkZT0nJywgbWFyZ2luYWxpYT1Ob25lLCBnYXA9JyZuYnNwOyZuYnNwOycpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGhlYWRpbmcuIiIiCiAgICAgICAgaWYgbWFyZ2luYWxpYSBpcyBOb25lOgogICAgICAgICAgICBtYXJnaW5hbGlhID0gJzx0dD4nICsgJyZuYnNwOycgKiB3aWR0aCArICc8L3R0PicKICAgICAgICByZXN1bHQgPSAnJycKPHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wIHN1bW1hcnk9InNlY3Rpb24iPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgY29sc3Bhbj0zIHZhbGlnbj1ib3R0b20+Jm5ic3A7PGJyPgo8Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlKQogICAgICAgIGlmIHByZWx1ZGU6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcnJwo8dHIgYmdjb2xvcj0iJXMiPjx0ZCByb3dzcGFuPTI+JXM8L3RkPgo8dGQgY29sc3Bhbj0yPiVzPC90ZD48L3RyPgo8dHI+PHRkPiVzPC90ZD4nJycgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIHByZWx1ZGUsIGdhcCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnJycKPHRyPjx0ZCBiZ2NvbG9yPSIlcyI+JXM8L3RkPjx0ZD4lczwvdGQ+JycnICUgKGJnY29sLCBtYXJnaW5hbGlhLCBnYXApCgogICAgICAgIHJldHVybiByZXN1bHQgKyAnXG48dGQgd2lkdGg9IjEwMCUlIj4lczwvdGQ+PC90cj48L3RhYmxlPicgJSBjb250ZW50cwoKICAgIGRlZiBiaWdzZWN0aW9uKHNlbGYsIHRpdGxlLCAqYXJncyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgYmlnIGhlYWRpbmcuIiIiCiAgICAgICAgdGl0bGUgPSAnPGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+JyAlIHRpdGxlCiAgICAgICAgcmV0dXJuIGFwcGx5KHNlbGYuc2VjdGlvbiwgKHRpdGxlLCkgKyBhcmdzKQoKICAgIGRlZiBwcmVmb3JtYXQoc2VsZiwgdGV4dCk6CiAgICAgICAgIiIiRm9ybWF0IGxpdGVyYWwgcHJlZm9ybWF0dGVkIHRleHQuIiIiCiAgICAgICAgdGV4dCA9IHNlbGYuZXNjYXBlKGV4cGFuZHRhYnModGV4dCkpCiAgICAgICAgcmV0dXJuIHJlcGxhY2UodGV4dCwgJ1xuXG4nLCAnXG4gXG4nLCAnXG5cbicsICdcbiBcbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyAnLCAnJm5ic3A7JywgJ1xuJywgJzxicj5cbicpCgogICAgZGVmIG11bHRpY29sdW1uKHNlbGYsIGxpc3QsIGZvcm1hdCwgY29scz00KToKICAgICAgICAiIiJGb3JtYXQgYSBsaXN0IG9mIGl0ZW1zIGludG8gYSBtdWx0aS1jb2x1bW4gbGlzdC4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIHJvd3MgPSAobGVuKGxpc3QpK2NvbHMtMSkvY29scwogICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29scyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8dGQgd2lkdGg9IiVkJSUiIHZhbGlnbj10b3A+JyAlICgxMDAvY29scykKICAgICAgICAgICAgZm9yIGkgaW4gcmFuZ2Uocm93cypjb2wsIHJvd3MqY29sK3Jvd3MpOgogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihsaXN0KToKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBmb3JtYXQobGlzdFtpXSkgKyAnPGJyPlxuJwogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnPC90ZD4nCiAgICAgICAgcmV0dXJuICc8dGFibGUgd2lkdGg9IjEwMCUlIiBzdW1tYXJ5PSJsaXN0Ij48dHI+JXM8L3RyPjwvdGFibGU+JyAlIHJlc3VsdAoKICAgIGRlZiBncmV5KHNlbGYsIHRleHQpOiByZXR1cm4gJzxmb250IGNvbG9yPSIjOTA5MDkwIj4lczwvZm9udD4nICUgdGV4dAoKICAgIGRlZiBuYW1lbGluayhzZWxmLCBuYW1lLCAqZGljdHMpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhbiBpZGVudGlmaWVyLCBnaXZlbiBuYW1lLXRvLVVSTCBtYXBwaW5ncy4iIiIKICAgICAgICBmb3IgZGljdCBpbiBkaWN0czoKICAgICAgICAgICAgaWYgZGljdC5oYXNfa2V5KG5hbWUpOgogICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlIChkaWN0W25hbWVdLCBuYW1lKQogICAgICAgIHJldHVybiBuYW1lCgogICAgZGVmIGNsYXNzbGluayhzZWxmLCBvYmplY3QsIG1vZG5hbWUpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIGNsYXNzLiIiIgogICAgICAgIG5hbWUsIG1vZHVsZSA9IG9iamVjdC5fX25hbWVfXywgc3lzLm1vZHVsZXMuZ2V0KG9iamVjdC5fX21vZHVsZV9fKQogICAgICAgIGlmIGhhc2F0dHIobW9kdWxlLCBuYW1lKSBhbmQgZ2V0YXR0cihtb2R1bGUsIG5hbWUpIGlzIG9iamVjdDoKICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIyVzIj4lczwvYT4nICUgKAogICAgICAgICAgICAgICAgbW9kdWxlLl9fbmFtZV9fLCBuYW1lLCBjbGFzc25hbWUob2JqZWN0LCBtb2RuYW1lKSkKICAgICAgICByZXR1cm4gY2xhc3NuYW1lKG9iamVjdCwgbW9kbmFtZSkKCiAgICBkZWYgbW9kdWxlbGluayhzZWxmLCBvYmplY3QpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIG1vZHVsZS4iIiIKICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAob2JqZWN0Ll9fbmFtZV9fLCBvYmplY3QuX19uYW1lX18pCgogICAgZGVmIG1vZHBrZ2xpbmsoc2VsZiwgKG5hbWUsIHBhdGgsIGlzcGFja2FnZSwgc2hhZG93ZWQpKToKICAgICAgICAiIiJNYWtlIGEgbGluayBmb3IgYSBtb2R1bGUgb3IgcGFja2FnZSB0byBkaXNwbGF5IGluIGFuIGluZGV4LiIiIgogICAgICAgIGlmIHNoYWRvd2VkOgogICAgICAgICAgICByZXR1cm4gc2VsZi5ncmV5KG5hbWUpCiAgICAgICAgaWYgcGF0aDoKICAgICAgICAgICAgdXJsID0gJyVzLiVzLmh0bWwnICUgKHBhdGgsIG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdXJsID0gJyVzLmh0bWwnICUgbmFtZQogICAgICAgIGlmIGlzcGFja2FnZToKICAgICAgICAgICAgdGV4dCA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+Jm5ic3A7KHBhY2thZ2UpJyAlIG5hbWUKICAgICAgICBlbHNlOgogICAgICAgICAgICB0ZXh0ID0gbmFtZQogICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAodXJsLCB0ZXh0KQoKICAgIGRlZiBtYXJrdXAoc2VsZiwgdGV4dCwgZXNjYXBlPU5vbmUsIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LCBtZXRob2RzPXt9KToKICAgICAgICAiIiJNYXJrIHVwIHNvbWUgcGxhaW4gdGV4dCwgZ2l2ZW4gYSBjb250ZXh0IG9mIHN5bWJvbHMgdG8gbG9vayBmb3IuCiAgICAgICAgRWFjaCBjb250ZXh0IGRpY3Rpb25hcnkgbWFwcyBvYmplY3QgbmFtZXMgdG8gYW5jaG9yIG5hbWVzLiIiIgogICAgICAgIGVzY2FwZSA9IGVzY2FwZSBvciBzZWxmLmVzY2FwZQogICAgICAgIHJlc3VsdHMgPSBbXQogICAgICAgIGhlcmUgPSAwCiAgICAgICAgcGF0dGVybiA9IHJlLmNvbXBpbGUocidcYigoaHR0cHxmdHApOi8vXFMrW1x3L118JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInUkZDWy0gXT8oXGQrKXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcidQRVBbLSBdPyhcZCspfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJyhzZWxmXC4pPyhcdyspKScpCiAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgbWF0Y2ggPSBwYXR0ZXJuLnNlYXJjaCh0ZXh0LCBoZXJlKQogICAgICAgICAgICBpZiBub3QgbWF0Y2g6IGJyZWFrCiAgICAgICAgICAgIHN0YXJ0LCBlbmQgPSBtYXRjaC5zcGFuKCkKICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoZXNjYXBlKHRleHRbaGVyZTpzdGFydF0pKQoKICAgICAgICAgICAgYWxsLCBzY2hlbWUsIHJmYywgcGVwLCBzZWxmZG90LCBuYW1lID0gbWF0Y2guZ3JvdXBzKCkKICAgICAgICAgICAgaWYgc2NoZW1lOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGFsbCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHJmYzoKICAgICAgICAgICAgICAgIHVybCA9ICdodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmMlZC50eHQnICUgaW50KHJmYykKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZShhbGwpKSkKICAgICAgICAgICAgZWxpZiBwZXA6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5weXRob24ub3JnL3BlcHMvcGVwLSUwNGQuaHRtbCcgJSBpbnQocGVwKQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHRleHRbZW5kOmVuZCsxXSA9PSAnKCc6CiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgZWxpZiBzZWxmZG90OgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJ3NlbGYuPHN0cm9uZz4lczwvc3Ryb25nPicgJSBuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgaGVyZSA9IGVuZAogICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6XSkpCiAgICAgICAgcmV0dXJuIGpvaW4ocmVzdWx0cywgJycpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZm9ybWF0dHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGZvciBhIGNsYXNzIHRyZWUgYXMgZ2l2ZW4gYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZHQ+PGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+JwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5jbGFzc2xpbmsoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMuYXBwZW5kKHNlbGYuY2xhc3NsaW5rKGJhc2UsIG1vZG5hbWUpKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJyArIGpvaW4ocGFyZW50cywgJywgJykgKyAnKScKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbjwvZm9udD48L2R0PicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZGQ+XG4lczwvZGQ+XG4nICUgc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjKQogICAgICAgIHJldHVybiAnPGRsPlxuJXM8L2RsPlxuJyAlIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCAqaWdub3JlZCk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fICMgaWdub3JlIHRoZSBwYXNzZWQtaW4gbmFtZQogICAgICAgIHBhcnRzID0gc3BsaXQobmFtZSwgJy4nKQogICAgICAgIGxpbmtzID0gW10KICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4ocGFydHMpLTEpOgogICAgICAgICAgICBsaW5rcy5hcHBlbmQoCiAgICAgICAgICAgICAgICAnPGEgaHJlZj0iJXMuaHRtbCI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPiVzPC9mb250PjwvYT4nICUKICAgICAgICAgICAgICAgIChqb2luKHBhcnRzWzppKzFdLCAnLicpLCBwYXJ0c1tpXSkpCiAgICAgICAgbGlua2VkbmFtZSA9IGpvaW4obGlua3MgKyBwYXJ0c1stMTpdLCAnLicpCiAgICAgICAgaGVhZCA9ICc8YmlnPjxiaWc+PHN0cm9uZz4lczwvc3Ryb25nPjwvYmlnPjwvYmlnPicgJSBsaW5rZWRuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBwYXRoID0gaW5zcGVjdC5nZXRhYnNmaWxlKG9iamVjdCkKICAgICAgICAgICAgdXJsID0gcGF0aAogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgIGltcG9ydCBudHVybDJwYXRoCiAgICAgICAgICAgICAgICB1cmwgPSBudHVybDJwYXRoLnBhdGhuYW1lMnVybChwYXRoKQogICAgICAgICAgICBmaWxlbGluayA9ICc8YSBocmVmPSJmaWxlOiVzIj4lczwvYT4nICUgKHVybCwgcGF0aCkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlbGluayA9ICcoYnVpbHQtaW4pJwogICAgICAgIGluZm8gPSBbXQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIGluZm8uYXBwZW5kKCd2ZXJzaW9uICVzJyAlIHNlbGYuZXNjYXBlKHZlcnNpb24pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgaW5mby5hcHBlbmQoc2VsZi5lc2NhcGUoc3RyKG9iamVjdC5fX2RhdGVfXykpKQogICAgICAgIGlmIGluZm86CiAgICAgICAgICAgIGhlYWQgPSBoZWFkICsgJyAoJXMpJyAlIGpvaW4oaW5mbywgJywgJykKICAgICAgICByZXN1bHQgPSBzZWxmLmhlYWRpbmcoCiAgICAgICAgICAgIGhlYWQsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCAnPGEgaHJlZj0iLiI+aW5kZXg8L2E+PGJyPicgKyBmaWxlbGluaykKCiAgICAgICAgbW9kdWxlcyA9IGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtb2R1bGUpCgogICAgICAgIGNsYXNzZXMsIGNkaWN0ID0gW10sIHt9CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFt2YWx1ZV0gPSAnIycgKyBrZXkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjbGFzc2VzOgogICAgICAgICAgICBmb3IgYmFzZSBpbiB2YWx1ZS5fX2Jhc2VzX186CiAgICAgICAgICAgICAgICBrZXksIG1vZG5hbWUgPSBiYXNlLl9fbmFtZV9fLCBiYXNlLl9fbW9kdWxlX18KICAgICAgICAgICAgICAgIG1vZHVsZSA9IHN5cy5tb2R1bGVzLmdldChtb2RuYW1lKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSBuYW1lIGFuZCBtb2R1bGUgYW5kIGhhc2F0dHIobW9kdWxlLCBrZXkpOgogICAgICAgICAgICAgICAgICAgIGlmIGdldGF0dHIobW9kdWxlLCBrZXkpIGlzIGJhc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBjZGljdC5oYXNfa2V5KGtleSk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbYmFzZV0gPSBtb2RuYW1lICsgJy5odG1sIycgKyBrZXkKICAgICAgICBmdW5jcywgZmRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICAgICAgICAgIGZkaWN0W2tleV0gPSAnIy0nICsga2V5CiAgICAgICAgICAgICAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24odmFsdWUpOiBmZGljdFt2YWx1ZV0gPSBmZGljdFtrZXldCiAgICAgICAgZGF0YSA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaXNkYXRhKToKICAgICAgICAgICAgaWYga2V5IG5vdCBpbiBbJ19fYnVpbHRpbnNfXycsICdfX2RvY19fJ106CiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwgZmRpY3QsIGNkaWN0KQogICAgICAgIGRvYyA9IGRvYyBhbmQgJzx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8cD4lczwvcD5cbicgJSBkb2MKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3BhdGhfXycpOgogICAgICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICAgICAgbW9kbmFtZXMgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZG5hbWVzOgogICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChtb2RuYW1lLCBuYW1lLCAwLCAwKSkKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lcy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKChmaWxlLCBuYW1lLCAxLCAwKSkKICAgICAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm11bHRpY29sdW1uKG1vZHBrZ3MsIHNlbGYubW9kcGtnbGluaykKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ1BhY2thZ2UgQ29udGVudHMnLCAnI2ZmZmZmZicsICcjYWE1NWNjJywgY29udGVudHMpCiAgICAgICAgZWxpZiBtb2R1bGVzOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4oCiAgICAgICAgICAgICAgICBtb2R1bGVzLCBsYW1iZGEgKGtleSwgdmFsdWUpLCBzPXNlbGY6IHMubW9kdWxlbGluayh2YWx1ZSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdNb2R1bGVzJywgJyNmZmZmZicsICcjYWE1NWNjJywgY29udGVudHMpCgogICAgICAgIGlmIGNsYXNzZXM6CiAgICAgICAgICAgIGNsYXNzbGlzdCA9IG1hcChsYW1iZGEgKGtleSwgdmFsdWUpOiB2YWx1ZSwgY2xhc3NlcykKICAgICAgICAgICAgY29udGVudHMgPSBbCiAgICAgICAgICAgICAgICBzZWxmLmZvcm1hdHRyZWUoaW5zcGVjdC5nZXRjbGFzc3RyZWUoY2xhc3NsaXN0LCAxKSwgbmFtZSldCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNsYXNzZXM6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lLCBmZGljdCwgY2RpY3QpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ2xhc3NlcycsICcjZmZmZmZmJywgJyNlZTc3YWEnLCBqb2luKGNvbnRlbnRzKSkKICAgICAgICBpZiBmdW5jczoKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBmdW5jczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUsIGZkaWN0LCBjZGljdCkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdGdW5jdGlvbnMnLCAnI2ZmZmZmZicsICcjZWVhYTc3Jywgam9pbihjb250ZW50cykpCiAgICAgICAgaWYgZGF0YToKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBkYXRhOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdEYXRhJywgJyNmZmZmZmYnLCAnIzU1YWE1NScsIGpvaW4oY29udGVudHMsICc8YnI+XG4nKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fYXV0aG9yX18pLCBzZWxmLnByZWZvcm1hdCkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0F1dGhvcicsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fY3JlZGl0c19fJyk6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tYXJrdXAoc3RyKG9iamVjdC5fX2NyZWRpdHNfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQ3JlZGl0cycsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCBjb250ZW50cykKCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgbW9kPU5vbmUsIGZ1bmNzPXt9LCBjbGFzc2VzPXt9LAogICAgICAgICAgICAgICAgICppZ25vcmVkKToKICAgICAgICAiIiJQcm9kdWNlIEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYSBjbGFzcyBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGJhc2VzID0gb2JqZWN0Ll9fYmFzZXNfXwoKICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgcHVzaCA9IGNvbnRlbnRzLmFwcGVuZAoKICAgICAgICAjIEN1dGUgbGl0dGxlIGNsYXNzIHRvIHB1bXAgb3V0IGEgaG9yaXpvbnRhbCBydWxlIGJldHdlZW4gc2VjdGlvbnMuCiAgICAgICAgY2xhc3MgSG9yaXpvbnRhbFJ1bGU6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICAgICAgICAgIHNlbGYubmVlZG9uZSA9IDAKICAgICAgICAgICAgZGVmIG1heWJlKHNlbGYpOgogICAgICAgICAgICAgICAgaWYgc2VsZi5uZWVkb25lOgogICAgICAgICAgICAgICAgICAgIHB1c2goJzxocj5cbicpCiAgICAgICAgICAgICAgICBzZWxmLm5lZWRvbmUgPSAxCiAgICAgICAgaHIgPSBIb3Jpem9udGFsUnVsZSgpCgogICAgICAgICMgTGlzdCB0aGUgbXJvLCBpZiBub24tdHJpdmlhbC4KICAgICAgICBtcm8gPSBsaXN0KGluc3BlY3QuZ2V0bXJvKG9iamVjdCkpCiAgICAgICAgaWYgbGVuKG1ybykgPiAyOgogICAgICAgICAgICBoci5tYXliZSgpCiAgICAgICAgICAgIHB1c2goJzxkbD48ZHQ+TWV0aG9kIHJlc29sdXRpb24gb3JkZXI6PC9kdD5cbicpCiAgICAgICAgICAgIGZvciBiYXNlIGluIG1ybzoKICAgICAgICAgICAgICAgIHB1c2goJzxkZD4lczwvZGQ+XG4nICUgc2VsZi5jbGFzc2xpbmsoYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0Ll9fbW9kdWxlX18pKQogICAgICAgICAgICBwdXNoKCc8L2RsPlxuJykKCiAgICAgICAgZGVmIHNwaWxsKG1zZywgYXR0cnMsIHByZWRpY2F0ZSk6CiAgICAgICAgICAgIG9rLCBhdHRycyA9IF9zcGxpdF9saXN0KGF0dHJzLCBwcmVkaWNhdGUpCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgaHIubWF5YmUoKQogICAgICAgICAgICAgICAgcHVzaChtc2cpCiAgICAgICAgICAgICAgICBmb3IgbmFtZSwga2luZCwgaG9tZWNscywgdmFsdWUgaW4gb2s6CiAgICAgICAgICAgICAgICAgICAgcHVzaChzZWxmLmRvY3VtZW50KGdldGF0dHIob2JqZWN0LCBuYW1lKSwgbmFtZSwgbW9kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jcywgY2xhc3NlcywgbWRpY3QsIG9iamVjdCkpCiAgICAgICAgICAgICAgICAgICAgcHVzaCgnXG4nKQogICAgICAgICAgICByZXR1cm4gYXR0cnMKCiAgICAgICAgZGVmIHNwaWxscHJvcGVydGllcyhtc2csIGF0dHJzLCBwcmVkaWNhdGUpOgogICAgICAgICAgICBvaywgYXR0cnMgPSBfc3BsaXRfbGlzdChhdHRycywgcHJlZGljYXRlKQogICAgICAgICAgICBpZiBvazoKICAgICAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgICAgIHB1c2gobXNnKQogICAgICAgICAgICAgICAgZm9yIG5hbWUsIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIG9rOgogICAgICAgICAgICAgICAgICAgIHB1c2goJzxkbD48ZHQ+PHN0cm9uZz4lczwvc3Ryb25nPjwvZHQ+XG4nICUgbmFtZSkKICAgICAgICAgICAgICAgICAgICBpZiB2YWx1ZS5fX2RvY19fIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cCh2YWx1ZS5fX2RvY19fLCBzZWxmLnByZWZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3MsIGNsYXNzZXMsIG1kaWN0KQogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKCc8ZGQ+PHR0PiVzPC90dD48L2RkPlxuJyAlIGRvYykKICAgICAgICAgICAgICAgICAgICBmb3IgYXR0ciwgdGFnIGluIFsoImZnZXQiLCAiIGdldHRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgiZnNldCIsICIgc2V0dGVyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJmZGVsIiwgIiBkZWxldGVyIildOgogICAgICAgICAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cih2YWx1ZSwgYXR0cikKICAgICAgICAgICAgICAgICAgICAgICAgaWYgZnVuYyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPSBzZWxmLmRvY3VtZW50KGZ1bmMsIG5hbWUgKyB0YWcsIG1vZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCwgb2JqZWN0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGRkPiVzPC9kZD5cbicgJSBiYXNlKQogICAgICAgICAgICAgICAgICAgIHB1c2goJzwvZGw+XG4nKQogICAgICAgICAgICByZXR1cm4gYXR0cnMKCiAgICAgICAgZGVmIHNwaWxsZGF0YShtc2csIGF0dHJzLCBwcmVkaWNhdGUpOgogICAgICAgICAgICBvaywgYXR0cnMgPSBfc3BsaXRfbGlzdChhdHRycywgcHJlZGljYXRlKQogICAgICAgICAgICBpZiBvazoKICAgICAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgICAgIHB1c2gobXNnKQogICAgICAgICAgICAgICAgZm9yIG5hbWUsIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIG9rOgogICAgICAgICAgICAgICAgICAgIGJhc2UgPSBzZWxmLmRvY290aGVyKGdldGF0dHIob2JqZWN0LCBuYW1lKSwgbmFtZSwgbW9kKQogICAgICAgICAgICAgICAgICAgIGRvYyA9IGdldGF0dHIodmFsdWUsICJfX2RvY19fIiwgTm9uZSkKICAgICAgICAgICAgICAgICAgICBpZiBkb2MgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGRsPjxkdD4lczwvZGw+XG4nICUgYmFzZSkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2ModmFsdWUpLCBzZWxmLnByZWZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3MsIGNsYXNzZXMsIG1kaWN0KQogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSAnPGRkPjx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKCc8ZGw+PGR0PiVzJXM8L2RsPlxuJyAlIChiYXNlLCBkb2MpKQogICAgICAgICAgICAgICAgICAgIHB1c2goJ1xuJykKICAgICAgICAgICAgcmV0dXJuIGF0dHJzCgogICAgICAgIGF0dHJzID0gaW5zcGVjdC5jbGFzc2lmeV9jbGFzc19hdHRycyhvYmplY3QpCiAgICAgICAgbWRpY3QgPSB7fQogICAgICAgIGZvciBrZXksIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIGF0dHJzOgogICAgICAgICAgICBtZGljdFtrZXldID0gYW5jaG9yID0gJyMnICsgbmFtZSArICctJyArIGtleQogICAgICAgICAgICB2YWx1ZSA9IGdldGF0dHIob2JqZWN0LCBrZXkpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICMgVGhlIHZhbHVlIG1heSBub3QgYmUgaGFzaGFibGUgKGUuZy4sIGEgZGF0YSBhdHRyIHdpdGgKICAgICAgICAgICAgICAgICMgYSBkaWN0IG9yIGxpc3QgdmFsdWUpLgogICAgICAgICAgICAgICAgbWRpY3RbdmFsdWVdID0gYW5jaG9yCiAgICAgICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIHdoaWxlIGF0dHJzOgogICAgICAgICAgICBpZiBtcm86CiAgICAgICAgICAgICAgICB0aGlzY2xhc3MgPSBtcm8ucG9wKDApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB0aGlzY2xhc3MgPSBhdHRyc1swXVsyXQogICAgICAgICAgICBhdHRycywgaW5oZXJpdGVkID0gX3NwbGl0X2xpc3QoYXR0cnMsIGxhbWJkYSB0OiB0WzJdIGlzIHRoaXNjbGFzcykKCiAgICAgICAgICAgIGlmIHRoaXNjbGFzcyBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICB0YWcgPSAiZGVmaW5lZCBoZXJlIgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgdGFnID0gImluaGVyaXRlZCBmcm9tICVzIiAlIHNlbGYuY2xhc3NsaW5rKHRoaXNjbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5fX21vZHVsZV9fKQogICAgICAgICAgICB0YWcgKz0gJzo8YnI+XG4nCgogICAgICAgICAgICAjIFNvcnQgYXR0cnMgYnkgbmFtZS4KICAgICAgICAgICAgYXR0cnMuc29ydChsYW1iZGEgdDEsIHQyOiBjbXAodDFbMF0sIHQyWzBdKSkKCiAgICAgICAgICAgICMgUHVtcCBvdXQgdGhlIGF0dHJzLCBzZWdyZWdhdGVkIGJ5IGtpbmQuCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGwoIk1ldGhvZHMgJXMiICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAnbWV0aG9kJykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbCgiQ2xhc3MgbWV0aG9kcyAlcyIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdjbGFzcyBtZXRob2QnKQogICAgICAgICAgICBhdHRycyA9IHNwaWxsKCJTdGF0aWMgbWV0aG9kcyAlcyIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdzdGF0aWMgbWV0aG9kJykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbHByb3BlcnRpZXMoIlByb3BlcnRpZXMgJXMiICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHQ6IHRbMV0gPT0gJ3Byb3BlcnR5JykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbGRhdGEoIkRhdGEgYW5kIG5vbi1tZXRob2QgZnVuY3Rpb25zICVzIiAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdkYXRhJykKICAgICAgICAgICAgYXNzZXJ0IGF0dHJzID09IFtdCiAgICAgICAgICAgIGF0dHJzID0gaW5oZXJpdGVkCgogICAgICAgIGNvbnRlbnRzID0gJycuam9pbihjb250ZW50cykKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPmNsYXNzIDxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlICgKICAgICAgICAgICAgICAgIG5hbWUsIHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gJzxzdHJvbmc+JXM8L3N0cm9uZz4gPSA8YSBuYW1lPSIlcyI+Y2xhc3MgJXM8L2E+JyAlICgKICAgICAgICAgICAgICAgIG5hbWUsIG5hbWUsIHJlYWxuYW1lKQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBvYmplY3QuX19tb2R1bGVfXykpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmdW5jcywgY2xhc3NlcywgbWRpY3QpCiAgICAgICAgZG9jID0gZG9jIGFuZCAnPHR0PiVzPGJyPiZuYnNwOzwvdHQ+JyAlIGRvYyBvciAnJm5ic3A7JwoKICAgICAgICByZXR1cm4gc2VsZi5zZWN0aW9uKHRpdGxlLCAnIzAwMDAwMCcsICcjZmZjOGQ4JywgY29udGVudHMsIDUsIGRvYykKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiBzZWxmLmdyZXkoJz0nICsgc2VsZi5yZXByKG9iamVjdCkpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLAogICAgICAgICAgICAgICAgICAgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30sIGNsPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGFuY2hvciA9IChjbCBhbmQgY2wuX19uYW1lX18gb3IgJycpICsgJy0nICsgbmFtZQogICAgICAgIG5vdGUgPSAnJwogICAgICAgIHNraXBkb2NzID0gMAogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KToKICAgICAgICAgICAgaW1jbGFzcyA9IG9iamVjdC5pbV9jbGFzcwogICAgICAgICAgICBpZiBjbDoKICAgICAgICAgICAgICAgIGlmIGltY2xhc3MgaXMgbm90IGNsOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIGZyb20gJyArIHNlbGYuY2xhc3NsaW5rKGltY2xhc3MsIG1vZCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIG9iamVjdC5pbV9zZWxmOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIG1ldGhvZCBvZiAlcyBpbnN0YW5jZScgJSBzZWxmLmNsYXNzbGluaygKICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmltX3NlbGYuX19jbGFzc19fLCBtb2QpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIHVuYm91bmQgJXMgbWV0aG9kJyAlIHNlbGYuY2xhc3NsaW5rKGltY2xhc3MsbW9kKQogICAgICAgICAgICBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9ICc8YSBuYW1lPSIlcyI+PHN0cm9uZz4lczwvc3Ryb25nPjwvYT4nICUgKGFuY2hvciwgcmVhbG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgKGNsIGFuZCBjbC5fX2RpY3RfXy5oYXNfa2V5KHJlYWxuYW1lKSBhbmQKICAgICAgICAgICAgICAgIGNsLl9fZGljdF9fW3JlYWxuYW1lXSBpcyBvYmplY3QpOgogICAgICAgICAgICAgICAgcmVhbGxpbmsgPSAnPGEgaHJlZj0iIyVzIj4lczwvYT4nICUgKAogICAgICAgICAgICAgICAgICAgIGNsLl9fbmFtZV9fICsgJy0nICsgcmVhbG5hbWUsIHJlYWxuYW1lKQogICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZWFsbGluayA9IHJlYWxuYW1lCiAgICAgICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj48c3Ryb25nPiVzPC9zdHJvbmc+PC9hPiA9ICVzJyAlICgKICAgICAgICAgICAgICAgIGFuY2hvciwgbmFtZSwgcmVhbGxpbmspCiAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKG9iamVjdCk6CiAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cyA9IGluc3BlY3QuZ2V0YXJnc3BlYyhvYmplY3QpCiAgICAgICAgICAgIGFyZ3NwZWMgPSBpbnNwZWN0LmZvcm1hdGFyZ3NwZWMoCiAgICAgICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMsIGZvcm1hdHZhbHVlPXNlbGYuZm9ybWF0dmFsdWUpCiAgICAgICAgICAgIGlmIHJlYWxuYW1lID09ICc8bGFtYmRhPic6CiAgICAgICAgICAgICAgICB0aXRsZSA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+IDxlbT5sYW1iZGE8L2VtPiAnICUgbmFtZQogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzcGVjID0gJyguLi4pJwoKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgKG5vdGUgYW5kIHNlbGYuZ3JleSgKICAgICAgICAgICAgICAgJzxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PicgJSBub3RlKSkKCiAgICAgICAgaWYgc2tpcGRvY3M6CiAgICAgICAgICAgIHJldHVybiAnPGRsPjxkdD4lczwvZHQ+PC9kbD5cbicgJSBkZWNsCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoCiAgICAgICAgICAgICAgICBnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZ1bmNzLCBjbGFzc2VzLCBtZXRob2RzKQogICAgICAgICAgICBkb2MgPSBkb2MgYW5kICc8ZGQ+PHR0PiVzPC90dD48L2RkPicgJSBkb2MKICAgICAgICAgICAgcmV0dXJuICc8ZGw+PGR0PiVzPC9kdD4lczwvZGw+XG4nICUgKGRlY2wsIGRvYykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCAqaWdub3JlZCk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgZGF0YSBvYmplY3QuIiIiCiAgICAgICAgbGhzID0gbmFtZSBhbmQgJzxzdHJvbmc+JXM8L3N0cm9uZz4gPSAnICUgbmFtZSBvciAnJwogICAgICAgIHJldHVybiBsaHMgKyBzZWxmLnJlcHIob2JqZWN0KQoKICAgIGRlZiBpbmRleChzZWxmLCBkaXIsIHNoYWRvd2VkPU5vbmUpOgogICAgICAgICIiIkdlbmVyYXRlIGFuIEhUTUwgaW5kZXggZm9yIGEgZGlyZWN0b3J5IG9mIG1vZHVsZXMuIiIiCiAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgaWYgc2hhZG93ZWQgaXMgTm9uZTogc2hhZG93ZWQgPSB7fQogICAgICAgIHNlZW4gPSB7fQogICAgICAgIGZpbGVzID0gb3MubGlzdGRpcihkaXIpCgogICAgICAgIGRlZiBmb3VuZChuYW1lLCBpc3BhY2thZ2UsCiAgICAgICAgICAgICAgICAgIG1vZHBrZ3M9bW9kcGtncywgc2hhZG93ZWQ9c2hhZG93ZWQsIHNlZW49c2Vlbik6CiAgICAgICAgICAgIGlmIG5vdCBzZWVuLmhhc19rZXkobmFtZSk6CiAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgobmFtZSwgJycsIGlzcGFja2FnZSwgc2hhZG93ZWQuaGFzX2tleShuYW1lKSkpCiAgICAgICAgICAgICAgICBzZWVuW25hbWVdID0gMQogICAgICAgICAgICAgICAgc2hhZG93ZWRbbmFtZV0gPSAxCgogICAgICAgICMgUGFja2FnZSBzcGFtL19faW5pdF9fLnB5IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBtb2R1bGUgc3BhbS5weS4KICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGlzcGFja2FnZShwYXRoKTogZm91bmQoZmlsZSwgMSkKICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZTogZm91bmQobW9kbmFtZSwgMCkKCiAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgIHJldHVybiBzZWxmLmJpZ3NlY3Rpb24oZGlyLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHRleHQgZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IKCmNsYXNzIFRleHRSZXByKFJlcHIpOgogICAgIiIiQ2xhc3MgZm9yIHNhZmVseSBtYWtpbmcgYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IDIwCiAgICAgICAgc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSAxMDAKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIHInXFwnLCAnJyk6CiAgICAgICAgICAgICMgQmFja3NsYXNoZXMgYXJlIG9ubHkgbGl0ZXJhbCBpbiB0aGUgc3RyaW5nIGFuZCBhcmUgbmV2ZXIKICAgICAgICAgICAgIyBuZWVkZWQgdG8gbWFrZSBhbnkgc3BlY2lhbCBjaGFyYWN0ZXJzLCBzbyBzaG93IGEgcmF3IHN0cmluZy4KICAgICAgICAgICAgcmV0dXJuICdyJyArIHRlc3RyZXByWzBdICsgdGVzdCArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHRlc3RyZXByCgogICAgcmVwcl9zdHIgPSByZXByX3N0cmluZwoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuICc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fCgpjbGFzcyBUZXh0RG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIHRleHQgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gVGV4dFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKCiAgICBkZWYgYm9sZChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgYSBzdHJpbmcgaW4gYm9sZCBieSBvdmVyc3RyaWtpbmcuIiIiCiAgICAgICAgcmV0dXJuIGpvaW4obWFwKGxhbWJkYSBjaDogY2ggKyAnXGInICsgY2gsIHRleHQpLCAnJykKCiAgICBkZWYgaW5kZW50KHNlbGYsIHRleHQsIHByZWZpeD0nICAgICcpOgogICAgICAgICIiIkluZGVudCB0ZXh0IGJ5IHByZXBlbmRpbmcgYSBnaXZlbiBwcmVmaXggdG8gZWFjaCBsaW5lLiIiIgogICAgICAgIGlmIG5vdCB0ZXh0OiByZXR1cm4gJycKICAgICAgICBsaW5lcyA9IHNwbGl0KHRleHQsICdcbicpCiAgICAgICAgbGluZXMgPSBtYXAobGFtYmRhIGxpbmUsIHByZWZpeD1wcmVmaXg6IHByZWZpeCArIGxpbmUsIGxpbmVzKQogICAgICAgIGlmIGxpbmVzOiBsaW5lc1stMV0gPSByc3RyaXAobGluZXNbLTFdKQogICAgICAgIHJldHVybiBqb2luKGxpbmVzLCAnXG4nKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgZ2l2ZW4gaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gc2VsZi5ib2xkKHRpdGxlKSArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoY29udGVudHMpKSArICdcblxuJwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGZvcm1hdHRyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgcGFyZW50PU5vbmUsIHByZWZpeD0nJyk6CiAgICAgICAgIiIiUmVuZGVyIGluIHRleHQgYSBjbGFzcyB0cmVlIGFzIHJldHVybmVkIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1tb2RuYW1lOiBjbGFzc25hbWUoYywgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgYywgcHJlZml4ICsgJyAgICAnKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fICMgaWdub3JlIHRoZSBwYXNzZWQtaW4gbmFtZQogICAgICAgIHN5bm9wLCBkZXNjID0gc3BsaXRkb2MoZ2V0ZG9jKG9iamVjdCkpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5zZWN0aW9uKCdOQU1FJywgbmFtZSArIChzeW5vcCBhbmQgJyAtICcgKyBzeW5vcCkpCgogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IGluc3BlY3QuZ2V0YWJzZmlsZShvYmplY3QpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZSA9ICcoYnVpbHQtaW4pJwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRklMRScsIGZpbGUpCiAgICAgICAgaWYgZGVzYzoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdERVNDUklQVElPTicsIGRlc2MpCgogICAgICAgIGNsYXNzZXMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAgZnVuY3MgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNyb3V0aW5lKToKICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2J1aWx0aW4odmFsdWUpIG9yIGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgIGRhdGEgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzZGF0YSk6CiAgICAgICAgICAgIGlmIGtleSBub3QgaW4gWydfX2J1aWx0aW5zX18nLCAnX19kb2NfXyddOgogICAgICAgICAgICAgICAgZGF0YS5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWUgbm90IGluIG1vZHBrZ3M6CiAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgIG1vZHBrZ3MuYXBwZW5kKGZpbGUgKyAnIChwYWNrYWdlKScpCiAgICAgICAgICAgIG1vZHBrZ3Muc29ydCgpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbigKICAgICAgICAgICAgICAgICdQQUNLQUdFIENPTlRFTlRTJywgam9pbihtb2Rwa2dzLCAnXG4nKSkKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY2xhc3NsaXN0ID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLCBjbGFzc2VzKQogICAgICAgICAgICBjb250ZW50cyA9IFtzZWxmLmZvcm1hdHRyZWUoCiAgICAgICAgICAgICAgICBpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2xpc3QsIDEpLCBuYW1lKV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUpKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NMQVNTRVMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgZnVuY3M6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gZnVuY3M6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdGVU5DVElPTlMnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgZGF0YToKICAgICAgICAgICAgY29udGVudHMgPSBbXQogICAgICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBkYXRhOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jb3RoZXIodmFsdWUsIGtleSwgbmFtZSwgNzApKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RBVEEnLCBqb2luKGNvbnRlbnRzLCAnXG4nKSkKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3ZlcnNpb25fXycpOgogICAgICAgICAgICB2ZXJzaW9uID0gc3RyKG9iamVjdC5fX3ZlcnNpb25fXykKICAgICAgICAgICAgaWYgdmVyc2lvbls6MTFdID09ICckJyArICdSZXZpc2lvbjogJyBhbmQgdmVyc2lvblstMTpdID09ICckJzoKICAgICAgICAgICAgICAgIHZlcnNpb24gPSBzdHJpcCh2ZXJzaW9uWzExOi0xXSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdWRVJTSU9OJywgdmVyc2lvbikKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fZGF0ZV9fJyk6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignREFURScsIHN0cihvYmplY3QuX19kYXRlX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0FVVEhPUicsIHN0cihvYmplY3QuX19hdXRob3JfXykpCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2NyZWRpdHNfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0NSRURJVFMnLCBzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSkKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gY2xhc3Mgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBiYXNlcyA9IG9iamVjdC5fX2Jhc2VzX18KCiAgICAgICAgZGVmIG1ha2VuYW1lKGMsIG09b2JqZWN0Ll9fbW9kdWxlX18pOgogICAgICAgICAgICByZXR1cm4gY2xhc3NuYW1lKGMsIG0pCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gJ2NsYXNzICcgKyBzZWxmLmJvbGQocmVhbG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgdGl0bGUgPSBzZWxmLmJvbGQobmFtZSkgKyAnID0gY2xhc3MgJyArIHJlYWxuYW1lCiAgICAgICAgaWYgYmFzZXM6CiAgICAgICAgICAgIHBhcmVudHMgPSBtYXAobWFrZW5hbWUsIGJhc2VzKQogICAgICAgICAgICB0aXRsZSA9IHRpdGxlICsgJyglcyknICUgam9pbihwYXJlbnRzLCAnLCAnKQoKICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KQogICAgICAgIGNvbnRlbnRzID0gZG9jIGFuZCBbZG9jICsgJ1xuJ10gb3IgW10KICAgICAgICBwdXNoID0gY29udGVudHMuYXBwZW5kCgogICAgICAgICMgTGlzdCB0aGUgbXJvLCBpZiBub24tdHJpdmlhbC4KICAgICAgICBtcm8gPSBsaXN0KGluc3BlY3QuZ2V0bXJvKG9iamVjdCkpCiAgICAgICAgaWYgbGVuKG1ybykgPiAyOgogICAgICAgICAgICBwdXNoKCJNZXRob2QgcmVzb2x1dGlvbiBvcmRlcjoiKQogICAgICAgICAgICBmb3IgYmFzZSBpbiBtcm86CiAgICAgICAgICAgICAgICBwdXNoKCcgICAgJyArIG1ha2VuYW1lKGJhc2UpKQogICAgICAgICAgICBwdXNoKCcnKQoKICAgICAgICAjIEN1dGUgbGl0dGxlIGNsYXNzIHRvIHB1bXAgb3V0IGEgaG9yaXpvbnRhbCBydWxlIGJldHdlZW4gc2VjdGlvbnMuCiAgICAgICAgY2xhc3MgSG9yaXpvbnRhbFJ1bGU6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICAgICAgICAgIHNlbGYubmVlZG9uZSA9IDAKICAgICAgICAgICAgZGVmIG1heWJlKHNlbGYpOgogICAgICAgICAgICAgICAgaWYgc2VsZi5uZWVkb25lOgogICAgICAgICAgICAgICAgICAgIHB1c2goJy0nICogNzApCiAgICAgICAgICAgICAgICBzZWxmLm5lZWRvbmUgPSAxCiAgICAgICAgaHIgPSBIb3Jpem9udGFsUnVsZSgpCgogICAgICAgIGRlZiBzcGlsbChtc2csIGF0dHJzLCBwcmVkaWNhdGUpOgogICAgICAgICAgICBvaywgYXR0cnMgPSBfc3BsaXRfbGlzdChhdHRycywgcHJlZGljYXRlKQogICAgICAgICAgICBpZiBvazoKICAgICAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgICAgIHB1c2gobXNnKQogICAgICAgICAgICAgICAgZm9yIG5hbWUsIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIG9rOgogICAgICAgICAgICAgICAgICAgIHB1c2goc2VsZi5kb2N1bWVudChnZXRhdHRyKG9iamVjdCwgbmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIG1vZCwgb2JqZWN0KSkKICAgICAgICAgICAgcmV0dXJuIGF0dHJzCgogICAgICAgIGRlZiBzcGlsbHByb3BlcnRpZXMobXNnLCBhdHRycywgcHJlZGljYXRlKToKICAgICAgICAgICAgb2ssIGF0dHJzID0gX3NwbGl0X2xpc3QoYXR0cnMsIHByZWRpY2F0ZSkKICAgICAgICAgICAgaWYgb2s6CiAgICAgICAgICAgICAgICBoci5tYXliZSgpCiAgICAgICAgICAgICAgICBwdXNoKG1zZykKICAgICAgICAgICAgICAgIGZvciBuYW1lLCBraW5kLCBob21lY2xzLCB2YWx1ZSBpbiBvazoKICAgICAgICAgICAgICAgICAgICBwdXNoKG5hbWUpCiAgICAgICAgICAgICAgICAgICAgbmVlZF9ibGFua19hZnRlcl9kb2MgPSAwCiAgICAgICAgICAgICAgICAgICAgZG9jID0gZ2V0ZG9jKHZhbHVlKSBvciAnJwogICAgICAgICAgICAgICAgICAgIGlmIGRvYzoKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaChzZWxmLmluZGVudChkb2MpKQogICAgICAgICAgICAgICAgICAgICAgICBuZWVkX2JsYW5rX2FmdGVyX2RvYyA9IDEKICAgICAgICAgICAgICAgICAgICBmb3IgYXR0ciwgdGFnIGluIFsoImZnZXQiLCAiIGdldHRlciIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgiZnNldCIsICIgc2V0dGVyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCJmZGVsIiwgIiBkZWxldGVyIildOgogICAgICAgICAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cih2YWx1ZSwgYXR0cikKICAgICAgICAgICAgICAgICAgICAgICAgaWYgZnVuYyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5lZWRfYmxhbmtfYWZ0ZXJfZG9jOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goJycpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZF9ibGFua19hZnRlcl9kb2MgPSAwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gc2VsZi5kb2NvdGhlcihmdW5jLCBuYW1lICsgdGFnLCBtb2QsIDcwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVzaChzZWxmLmluZGVudChiYXNlKSkKICAgICAgICAgICAgICAgICAgICBwdXNoKCcnKQogICAgICAgICAgICByZXR1cm4gYXR0cnMKCiAgICAgICAgZGVmIHNwaWxsZGF0YShtc2csIGF0dHJzLCBwcmVkaWNhdGUpOgogICAgICAgICAgICBvaywgYXR0cnMgPSBfc3BsaXRfbGlzdChhdHRycywgcHJlZGljYXRlKQogICAgICAgICAgICBpZiBvazoKICAgICAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgICAgIHB1c2gobXNnKQogICAgICAgICAgICAgICAgZm9yIG5hbWUsIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIG9rOgogICAgICAgICAgICAgICAgICAgIGRvYyA9IGdldGF0dHIodmFsdWUsICJfX2RvY19fIiwgTm9uZSkKICAgICAgICAgICAgICAgICAgICBwdXNoKHNlbGYuZG9jb3RoZXIoZ2V0YXR0cihvYmplY3QsIG5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBtb2QsIDcwLCBkb2MpICsgJ1xuJykKICAgICAgICAgICAgcmV0dXJuIGF0dHJzCgogICAgICAgIGF0dHJzID0gaW5zcGVjdC5jbGFzc2lmeV9jbGFzc19hdHRycyhvYmplY3QpCiAgICAgICAgd2hpbGUgYXR0cnM6CiAgICAgICAgICAgIGlmIG1ybzoKICAgICAgICAgICAgICAgIHRoaXNjbGFzcyA9IG1yby5wb3AoMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHRoaXNjbGFzcyA9IGF0dHJzWzBdWzJdCiAgICAgICAgICAgIGF0dHJzLCBpbmhlcml0ZWQgPSBfc3BsaXRfbGlzdChhdHRycywgbGFtYmRhIHQ6IHRbMl0gaXMgdGhpc2NsYXNzKQoKICAgICAgICAgICAgaWYgdGhpc2NsYXNzIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIHRhZyA9ICJkZWZpbmVkIGhlcmUiCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB0YWcgPSAiaW5oZXJpdGVkIGZyb20gJXMiICUgY2xhc3NuYW1lKHRoaXNjbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0Ll9fbW9kdWxlX18pCgogICAgICAgICAgICAjIFNvcnQgYXR0cnMgYnkgbmFtZS4KICAgICAgICAgICAgYXR0cnMuc29ydChsYW1iZGEgdDEsIHQyOiBjbXAodDFbMF0sIHQyWzBdKSkKCiAgICAgICAgICAgICMgUHVtcCBvdXQgdGhlIGF0dHJzLCBzZWdyZWdhdGVkIGJ5IGtpbmQuCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGwoIk1ldGhvZHMgJXM6XG4iICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAnbWV0aG9kJykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbCgiQ2xhc3MgbWV0aG9kcyAlczpcbiIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdjbGFzcyBtZXRob2QnKQogICAgICAgICAgICBhdHRycyA9IHNwaWxsKCJTdGF0aWMgbWV0aG9kcyAlczpcbiIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdzdGF0aWMgbWV0aG9kJykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbHByb3BlcnRpZXMoIlByb3BlcnRpZXMgJXM6XG4iICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHQ6IHRbMV0gPT0gJ3Byb3BlcnR5JykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbGRhdGEoIkRhdGEgYW5kIG5vbi1tZXRob2QgZnVuY3Rpb25zICVzOlxuIiAlIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnMsIGxhbWJkYSB0OiB0WzFdID09ICdkYXRhJykKICAgICAgICAgICAgYXNzZXJ0IGF0dHJzID09IFtdCiAgICAgICAgICAgIGF0dHJzID0gaW5oZXJpdGVkCgogICAgICAgIGNvbnRlbnRzID0gJ1xuJy5qb2luKGNvbnRlbnRzKQogICAgICAgIGlmIG5vdCBjb250ZW50czoKICAgICAgICAgICAgcmV0dXJuIHRpdGxlICsgJ1xuJwogICAgICAgIHJldHVybiB0aXRsZSArICdcbicgKyBzZWxmLmluZGVudChyc3RyaXAoY29udGVudHMpLCAnIHwgICcpICsgJ1xuJwoKICAgIGRlZiBmb3JtYXR2YWx1ZShzZWxmLCBvYmplY3QpOgogICAgICAgICIiIkZvcm1hdCBhbiBhcmd1bWVudCBkZWZhdWx0IHZhbHVlIGFzIHRleHQuIiIiCiAgICAgICAgcmV0dXJuICc9JyArIHNlbGYucmVwcihvYmplY3QpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCBjbD1Ob25lKToKICAgICAgICAiIiJQcm9kdWNlIHRleHQgZG9jdW1lbnRhdGlvbiBmb3IgYSBmdW5jdGlvbiBvciBtZXRob2Qgb2JqZWN0LiIiIgogICAgICAgIHJlYWxuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICAgICAgbmFtZSA9IG5hbWUgb3IgcmVhbG5hbWUKICAgICAgICBub3RlID0gJycKICAgICAgICBza2lwZG9jcyA9IDAKICAgICAgICBpZiBpbnNwZWN0LmlzbWV0aG9kKG9iamVjdCk6CiAgICAgICAgICAgIGltY2xhc3MgPSBvYmplY3QuaW1fY2xhc3MKICAgICAgICAgICAgaWYgY2w6CiAgICAgICAgICAgICAgICBpZiBpbWNsYXNzIGlzIG5vdCBjbDoKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyBmcm9tICcgKyBjbGFzc25hbWUoaW1jbGFzcywgbW9kKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaWYgb2JqZWN0LmltX3NlbGY6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgbWV0aG9kIG9mICVzIGluc3RhbmNlJyAlIGNsYXNzbmFtZSgKICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmltX3NlbGYuX19jbGFzc19fLCBtb2QpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIHVuYm91bmQgJXMgbWV0aG9kJyAlIGNsYXNzbmFtZShpbWNsYXNzLG1vZCkKICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LmltX2Z1bmMKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSBzZWxmLmJvbGQocmVhbG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgKGNsIGFuZCBjbC5fX2RpY3RfXy5oYXNfa2V5KHJlYWxuYW1lKSBhbmQKICAgICAgICAgICAgICAgIGNsLl9fZGljdF9fW3JlYWxuYW1lXSBpcyBvYmplY3QpOgogICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9ICcgKyByZWFsbmFtZQogICAgICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbihvYmplY3QpOgogICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMgPSBpbnNwZWN0LmdldGFyZ3NwZWMob2JqZWN0KQogICAgICAgICAgICBhcmdzcGVjID0gaW5zcGVjdC5mb3JtYXRhcmdzcGVjKAogICAgICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzLCBmb3JtYXR2YWx1ZT1zZWxmLmZvcm1hdHZhbHVlKQogICAgICAgICAgICBpZiByZWFsbmFtZSA9PSAnPGxhbWJkYT4nOgogICAgICAgICAgICAgICAgdGl0bGUgPSAnbGFtYmRhJwogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzcGVjID0gJyguLi4pJwogICAgICAgIGRlY2wgPSB0aXRsZSArIGFyZ3NwZWMgKyBub3RlCgogICAgICAgIGlmIHNraXBkb2NzOgogICAgICAgICAgICByZXR1cm4gZGVjbCArICdcbicKICAgICAgICBlbHNlOgogICAgICAgICAgICBkb2MgPSBnZXRkb2Mob2JqZWN0KSBvciAnJwogICAgICAgICAgICByZXR1cm4gZGVjbCArICdcbicgKyAoZG9jIGFuZCByc3RyaXAoc2VsZi5pbmRlbnQoZG9jKSkgKyAnXG4nKQoKICAgIGRlZiBkb2NvdGhlcihzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgbW9kPU5vbmUsIG1heGxlbj1Ob25lLCBkb2M9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZGF0YSBvYmplY3QuIiIiCiAgICAgICAgcmVwciA9IHNlbGYucmVwcihvYmplY3QpCiAgICAgICAgaWYgbWF4bGVuOgogICAgICAgICAgICBsaW5lID0gKG5hbWUgYW5kIG5hbWUgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgICAgIGNob3AgPSBtYXhsZW4gLSBsZW4obGluZSkKICAgICAgICAgICAgaWYgY2hvcCA8IDA6IHJlcHIgPSByZXByWzpjaG9wXSArICcuLi4nCiAgICAgICAgbGluZSA9IChuYW1lIGFuZCBzZWxmLmJvbGQobmFtZSkgKyAnID0gJyBvciAnJykgKyByZXByCiAgICAgICAgaWYgZG9jIGlzIG5vdCBOb25lOgogICAgICAgICAgICBsaW5lICs9ICdcbicgKyBzZWxmLmluZGVudChzdHIoZG9jKSkKICAgICAgICByZXR1cm4gbGluZQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdXNlciBpbnRlcmZhY2VzCgpkZWYgcGFnZXIodGV4dCk6CiAgICAiIiJUaGUgZmlyc3QgdGltZSB0aGlzIGlzIGNhbGxlZCwgZGV0ZXJtaW5lIHdoYXQga2luZCBvZiBwYWdlciB0byB1c2UuIiIiCiAgICBnbG9iYWwgcGFnZXIKICAgIHBhZ2VyID0gZ2V0cGFnZXIoKQogICAgcGFnZXIodGV4dCkKCmRlZiBnZXRwYWdlcigpOgogICAgIiIiRGVjaWRlIHdoYXQgbWV0aG9kIHRvIHVzZSBmb3IgcGFnaW5nIHRocm91Z2ggdGV4dC4iIiIKICAgIGlmIHR5cGUoc3lzLnN0ZG91dCkgaXMgbm90IHR5cGVzLkZpbGVUeXBlOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBub3Qgc3lzLnN0ZGluLmlzYXR0eSgpIG9yIG5vdCBzeXMuc3Rkb3V0LmlzYXR0eSgpOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBvcy5lbnZpcm9uLmdldCgnVEVSTScpIGluIFsnZHVtYicsICdlbWFjcyddOgogICAgICAgIHJldHVybiBwbGFpbnBhZ2VyCiAgICBpZiBvcy5lbnZpcm9uLmhhc19rZXkoJ1BBR0VSJyk6CiAgICAgICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMic6ICMgcGlwZXMgY29tcGxldGVseSBicm9rZW4gaW4gV2luZG93cwogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHRlbXBmaWxlcGFnZXIocGxhaW4odGV4dCksIG9zLmVudmlyb25bJ1BBR0VSJ10pCiAgICAgICAgZWxpZiBvcy5lbnZpcm9uLmdldCgnVEVSTScpIGluIFsnZHVtYicsICdlbWFjcyddOgogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHBpcGVwYWdlcihwbGFpbih0ZXh0KSwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHBpcGVwYWdlcih0ZXh0LCBvcy5lbnZpcm9uWydQQUdFUiddKQogICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMicgb3Igc3lzLnBsYXRmb3JtLnN0YXJ0c3dpdGgoJ29zMicpOgogICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogdGVtcGZpbGVwYWdlcihwbGFpbih0ZXh0KSwgJ21vcmUgPCcpCiAgICBpZiBoYXNhdHRyKG9zLCAnc3lzdGVtJykgYW5kIG9zLnN5c3RlbSgnbGVzcyAyPi9kZXYvbnVsbCcpID09IDA6CiAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgJ2xlc3MnKQoKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgZmlsZW5hbWUgPSB0ZW1wZmlsZS5ta3RlbXAoKQogICAgb3BlbihmaWxlbmFtZSwgJ3cnKS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJ21vcmUgJXMnICUgZmlsZW5hbWUpID09IDA6CiAgICAgICAgICAgIHJldHVybiBsYW1iZGEgdGV4dDogcGlwZXBhZ2VyKHRleHQsICdtb3JlJykKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gdHR5cGFnZXIKICAgIGZpbmFsbHk6CiAgICAgICAgb3MudW5saW5rKGZpbGVuYW1lKQoKZGVmIHBsYWluKHRleHQpOgogICAgIiIiUmVtb3ZlIGJvbGRmYWNlIGZvcm1hdHRpbmcgZnJvbSB0ZXh0LiIiIgogICAgcmV0dXJuIHJlLnN1YignLlxiJywgJycsIHRleHQpCgpkZWYgcGlwZXBhZ2VyKHRleHQsIGNtZCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBieSBmZWVkaW5nIGl0IHRvIGFub3RoZXIgcHJvZ3JhbS4iIiIKICAgIHBpcGUgPSBvcy5wb3BlbihjbWQsICd3JykKICAgIHRyeToKICAgICAgICBwaXBlLndyaXRlKHRleHQpCiAgICAgICAgcGlwZS5jbG9zZSgpCiAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICBwYXNzICMgSWdub3JlIGJyb2tlbiBwaXBlcyBjYXVzZWQgYnkgcXVpdHRpbmcgdGhlIHBhZ2VyIHByb2dyYW0uCgpkZWYgdGVtcGZpbGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgaW52b2tpbmcgYSBwcm9ncmFtIG9uIGEgdGVtcG9yYXJ5IGZpbGUuIiIiCiAgICBpbXBvcnQgdGVtcGZpbGUKICAgIGZpbGVuYW1lID0gdGVtcGZpbGUubWt0ZW1wKCkKICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lLCAndycpCiAgICBmaWxlLndyaXRlKHRleHQpCiAgICBmaWxlLmNsb3NlKCkKICAgIHRyeToKICAgICAgICBvcy5zeXN0ZW0oY21kICsgJyAnICsgZmlsZW5hbWUpCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiB0dHlwYWdlcih0ZXh0KToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IG9uIGEgdGV4dCB0ZXJtaW5hbC4iIiIKICAgIGxpbmVzID0gc3BsaXQocGxhaW4odGV4dCksICdcbicpCiAgICB0cnk6CiAgICAgICAgaW1wb3J0IHR0eQogICAgICAgIGZkID0gc3lzLnN0ZGluLmZpbGVubygpCiAgICAgICAgb2xkID0gdHR5LnRjZ2V0YXR0cihmZCkKICAgICAgICB0dHkuc2V0Y2JyZWFrKGZkKQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkKDEpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgdHR5ID0gTm9uZQogICAgICAgIGdldGNoYXIgPSBsYW1iZGE6IHN5cy5zdGRpbi5yZWFkbGluZSgpWzotMV1bOjFdCgogICAgdHJ5OgogICAgICAgIHIgPSBpbmMgPSBvcy5lbnZpcm9uLmdldCgnTElORVMnLCAyNSkgLSAxCiAgICAgICAgc3lzLnN0ZG91dC53cml0ZShqb2luKGxpbmVzWzppbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgd2hpbGUgbGluZXNbcjpdOgogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCctLSBtb3JlIC0tJykKICAgICAgICAgICAgc3lzLnN0ZG91dC5mbHVzaCgpCiAgICAgICAgICAgIGMgPSBnZXRjaGFyKCkKCiAgICAgICAgICAgIGlmIGMgaW4gWydxJywgJ1EnXToKICAgICAgICAgICAgICAgIHN5cy5zdGRvdXQud3JpdGUoJ1xyICAgICAgICAgIFxyJykKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIGVsaWYgYyBpbiBbJ1xyJywgJ1xuJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicgKyBsaW5lc1tyXSArICdcbicpCiAgICAgICAgICAgICAgICByID0gciArIDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmIGMgaW4gWydiJywgJ0InLCAnXHgxYiddOgogICAgICAgICAgICAgICAgciA9IHIgLSBpbmMgLSBpbmMKICAgICAgICAgICAgICAgIGlmIHIgPCAwOiByID0gMAogICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcbicgKyBqb2luKGxpbmVzW3I6citpbmNdLCAnXG4nKSArICdcbicpCiAgICAgICAgICAgIHIgPSByICsgaW5jCgogICAgZmluYWxseToKICAgICAgICBpZiB0dHk6CiAgICAgICAgICAgIHR0eS50Y3NldGF0dHIoZmQsIHR0eS5UQ1NBRkxVU0gsIG9sZCkKCmRlZiBwbGFpbnBhZ2VyKHRleHQpOgogICAgIiIiU2ltcGx5IHByaW50IHVuZm9ybWF0dGVkIHRleHQuICBUaGlzIGlzIHRoZSB1bHRpbWF0ZSBmYWxsYmFjay4iIiIKICAgIHN5cy5zdGRvdXQud3JpdGUocGxhaW4odGV4dCkpCgpkZWYgZGVzY3JpYmUodGhpbmcpOgogICAgIiIiUHJvZHVjZSBhIHNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBnaXZlbiB0aGluZy4iIiIKICAgIGlmIGluc3BlY3QuaXNtb2R1bGUodGhpbmcpOgogICAgICAgIGlmIHRoaW5nLl9fbmFtZV9fIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgcmV0dXJuICdidWlsdC1pbiBtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgaWYgaGFzYXR0cih0aGluZywgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIHJldHVybiAncGFja2FnZSAnICsgdGhpbmcuX19uYW1lX18KICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gJ21vZHVsZSAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2J1aWx0LWluIGZ1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2NsYXNzKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2NsYXNzICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHRoaW5nKToKICAgICAgICByZXR1cm4gJ2Z1bmN0aW9uICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgaW5zcGVjdC5pc21ldGhvZCh0aGluZyk6CiAgICAgICAgcmV0dXJuICdtZXRob2QgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiB0eXBlKHRoaW5nKSBpcyB0eXBlcy5JbnN0YW5jZVR5cGU6CiAgICAgICAgcmV0dXJuICdpbnN0YW5jZSBvZiAnICsgdGhpbmcuX19jbGFzc19fLl9fbmFtZV9fCiAgICByZXR1cm4gdHlwZSh0aGluZykuX19uYW1lX18KCmRlZiBsb2NhdGUocGF0aCwgZm9yY2Vsb2FkPTApOgogICAgIiIiTG9jYXRlIGFuIG9iamVjdCBieSBuYW1lIG9yIGRvdHRlZCBwYXRoLCBpbXBvcnRpbmcgYXMgbmVjZXNzYXJ5LiIiIgogICAgcGFydHMgPSBzcGxpdChwYXRoLCAnLicpCiAgICBtb2R1bGUsIG4gPSBOb25lLCAwCiAgICB3aGlsZSBuIDwgbGVuKHBhcnRzKToKICAgICAgICBuZXh0bW9kdWxlID0gc2FmZWltcG9ydChqb2luKHBhcnRzWzpuKzFdLCAnLicpLCBmb3JjZWxvYWQpCiAgICAgICAgaWYgbmV4dG1vZHVsZTogbW9kdWxlLCBuID0gbmV4dG1vZHVsZSwgbiArIDEKICAgICAgICBlbHNlOiBicmVhawogICAgaWYgbW9kdWxlOgogICAgICAgIG9iamVjdCA9IG1vZHVsZQogICAgICAgIGZvciBwYXJ0IGluIHBhcnRzW246XToKICAgICAgICAgICAgdHJ5OiBvYmplY3QgPSBnZXRhdHRyKG9iamVjdCwgcGFydCkKICAgICAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgICAgIHJldHVybiBvYmplY3QKICAgIGVsc2U6CiAgICAgICAgaW1wb3J0IF9fYnVpbHRpbl9fCiAgICAgICAgaWYgaGFzYXR0cihfX2J1aWx0aW5fXywgcGF0aCk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKF9fYnVpbHRpbl9fLCBwYXRoKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaW50ZXJhY3RpdmUgaW50ZXJwcmV0ZXIgaW50ZXJmYWNlCgp0ZXh0ID0gVGV4dERvYygpCmh0bWwgPSBIVE1MRG9jKCkKCmRlZiBkb2ModGhpbmcsIHRpdGxlPSdQeXRob24gTGlicmFyeSBEb2N1bWVudGF0aW9uOiAlcycsIGZvcmNlbG9hZD0wKToKICAgICIiIkRpc3BsYXkgdGV4dCBkb2N1bWVudGF0aW9uLCBnaXZlbiBhbiBvYmplY3Qgb3IgYSBwYXRoIHRvIGFuIG9iamVjdC4iIiIKICAgIHN1ZmZpeCwgbmFtZSA9ICcnLCBOb25lCiAgICBpZiB0eXBlKHRoaW5nKSBpcyB0eXBlKCcnKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9iamVjdCA9IGxvY2F0ZSh0aGluZywgZm9yY2Vsb2FkKQogICAgICAgIGV4Y2VwdCBFcnJvckR1cmluZ0ltcG9ydCwgdmFsdWU6CiAgICAgICAgICAgIHByaW50IHZhbHVlCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGlmIG5vdCBvYmplY3Q6CiAgICAgICAgICAgIHByaW50ICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcih0aGluZykKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgcGFydHMgPSBzcGxpdCh0aGluZywgJy4nKQogICAgICAgIGlmIGxlbihwYXJ0cykgPiAxOiBzdWZmaXggPSAnIGluICcgKyBqb2luKHBhcnRzWzotMV0sICcuJykKICAgICAgICBuYW1lID0gcGFydHNbLTFdCiAgICAgICAgdGhpbmcgPSBvYmplY3QKCiAgICBkZXNjID0gZGVzY3JpYmUodGhpbmcpCiAgICBtb2R1bGUgPSBpbnNwZWN0LmdldG1vZHVsZSh0aGluZykKICAgIGlmIG5vdCBzdWZmaXggYW5kIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCB0aGluZzoKICAgICAgICBzdWZmaXggPSAnIGluIG1vZHVsZSAnICsgbW9kdWxlLl9fbmFtZV9fCiAgICBwYWdlcih0aXRsZSAlIChkZXNjICsgc3VmZml4KSArICdcblxuJyArIHRleHQuZG9jdW1lbnQodGhpbmcsIG5hbWUpKQoKZGVmIHdyaXRlZG9jKGtleSwgZm9yY2Vsb2FkPTApOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICB0cnk6CiAgICAgICAgb2JqZWN0ID0gbG9jYXRlKGtleSwgZm9yY2Vsb2FkKQogICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICBwcmludCB2YWx1ZQogICAgZWxzZToKICAgICAgICBpZiBvYmplY3Q6CiAgICAgICAgICAgIHBhZ2UgPSBodG1sLnBhZ2UoZGVzY3JpYmUob2JqZWN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodG1sLmRvY3VtZW50KG9iamVjdCwgb2JqZWN0Ll9fbmFtZV9fKSkKICAgICAgICAgICAgZmlsZSA9IG9wZW4oa2V5ICsgJy5odG1sJywgJ3cnKQogICAgICAgICAgICBmaWxlLndyaXRlKHBhZ2UpCiAgICAgICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgICAgICBwcmludCAnd3JvdGUnLCBrZXkgKyAnLmh0bWwnCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQgJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKGtleSkKCmRlZiB3cml0ZWRvY3MoZGlyLCBwa2dwYXRoPScnLCBkb25lPU5vbmUpOgogICAgIiIiV3JpdGUgb3V0IEhUTUwgZG9jdW1lbnRhdGlvbiBmb3IgYWxsIG1vZHVsZXMgaW4gYSBkaXJlY3RvcnkgdHJlZS4iIiIKICAgIGlmIGRvbmUgaXMgTm9uZTogZG9uZSA9IHt9CiAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICB3cml0ZWRvY3MocGF0aCwgcGtncGF0aCArIGZpbGUgKyAnLicsIGRvbmUpCiAgICAgICAgZWxpZiBvcy5wYXRoLmlzZmlsZShwYXRoKToKICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShwYXRoKQogICAgICAgICAgICBpZiBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBrZ3BhdGggKyBtb2RuYW1lCiAgICAgICAgICAgICAgICBpZiBub3QgZG9uZS5oYXNfa2V5KG1vZG5hbWUpOgogICAgICAgICAgICAgICAgICAgIGRvbmVbbW9kbmFtZV0gPSAxCiAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MobW9kbmFtZSkKCmNsYXNzIEhlbHBlcjoKICAgIGtleXdvcmRzID0gewogICAgICAgICdhbmQnOiAnQk9PTEVBTicsCiAgICAgICAgJ2Fzc2VydCc6ICgncmVmL2Fzc2VydCcsICcnKSwKICAgICAgICAnYnJlYWsnOiAoJ3JlZi9icmVhaycsICd3aGlsZSBmb3InKSwKICAgICAgICAnY2xhc3MnOiAoJ3JlZi9jbGFzcycsICdDTEFTU0VTIFNQRUNJQUxNRVRIT0RTJyksCiAgICAgICAgJ2NvbnRpbnVlJzogKCdyZWYvY29udGludWUnLCAnd2hpbGUgZm9yJyksCiAgICAgICAgJ2RlZic6ICgncmVmL2Z1bmN0aW9uJywgJycpLAogICAgICAgICdkZWwnOiAoJ3JlZi9kZWwnLCAnQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ2VsaWYnOiAnaWYnLAogICAgICAgICdlbHNlJzogKCdyZWYvaWYnLCAnd2hpbGUgZm9yJyksCiAgICAgICAgJ2V4Y2VwdCc6ICd0cnknLAogICAgICAgICdleGVjJzogKCdyZWYvZXhlYycsICcnKSwKICAgICAgICAnZmluYWxseSc6ICd0cnknLAogICAgICAgICdmb3InOiAoJ3JlZi9mb3InLCAnYnJlYWsgY29udGludWUgd2hpbGUnKSwKICAgICAgICAnZnJvbSc6ICdpbXBvcnQnLAogICAgICAgICdnbG9iYWwnOiAoJ3JlZi9nbG9iYWwnLCAnTkFNRVNQQUNFUycpLAogICAgICAgICdpZic6ICgncmVmL2lmJywgJ1RSVVRIVkFMVUUnKSwKICAgICAgICAnaW1wb3J0JzogKCdyZWYvaW1wb3J0JywgJ01PRFVMRVMnKSwKICAgICAgICAnaW4nOiAoJ3JlZi9jb21wYXJpc29ucycsICdTRVFVRU5DRU1FVEhPRFMyJyksCiAgICAgICAgJ2lzJzogJ0NPTVBBUklTT04nLAogICAgICAgICdsYW1iZGEnOiAoJ3JlZi9sYW1iZGEnLCAnRlVOQ1RJT05TJyksCiAgICAgICAgJ25vdCc6ICdCT09MRUFOJywKICAgICAgICAnb3InOiAnQk9PTEVBTicsCiAgICAgICAgJ3Bhc3MnOiAnUEFTUycsCiAgICAgICAgJ3ByaW50JzogKCdyZWYvcHJpbnQnLCAnJyksCiAgICAgICAgJ3JhaXNlJzogKCdyZWYvcmFpc2UnLCAnRVhDRVBUSU9OUycpLAogICAgICAgICdyZXR1cm4nOiAoJ3JlZi9yZXR1cm4nLCAnRlVOQ1RJT05TJyksCiAgICAgICAgJ3RyeSc6ICgncmVmL3RyeScsICdFWENFUFRJT05TJyksCiAgICAgICAgJ3doaWxlJzogKCdyZWYvd2hpbGUnLCAnYnJlYWsgY29udGludWUgaWYgVFJVVEhWQUxVRScpLAogICAgfQoKICAgIHRvcGljcyA9IHsKICAgICAgICAnVFlQRVMnOiAoJ3JlZi90eXBlcycsICdTVFJJTkdTIFVOSUNPREUgTlVNQkVSUyBTRVFVRU5DRVMgTUFQUElOR1MgRlVOQ1RJT05TIENMQVNTRVMgTU9EVUxFUyBGSUxFUyBpbnNwZWN0JyksCiAgICAgICAgJ1NUUklOR1MnOiAoJ3JlZi9zdHJpbmdzJywgJ3N0ciBVTklDT0RFIFNFUVVFTkNFUyBTVFJJTkdNRVRIT0RTIEZPUk1BVFRJTkcgVFlQRVMnKSwKICAgICAgICAnU1RSSU5HTUVUSE9EUyc6ICgnbGliL3N0cmluZy1tZXRob2RzJywgJ1NUUklOR1MgRk9STUFUVElORycpLAogICAgICAgICdGT1JNQVRUSU5HJzogKCdsaWIvdHlwZXNzZXEtc3RyaW5ncycsICdPUEVSQVRPUlMnKSwKICAgICAgICAnVU5JQ09ERSc6ICgncmVmL3VuaWNvZGUnLCAnZW5jb2RpbmdzIHVuaWNvZGUgVFlQRVMgU1RSSU5HJyksCiAgICAgICAgJ05VTUJFUlMnOiAoJ3JlZi9udW1iZXJzJywgJ0lOVEVHRVIgRkxPQVQgQ09NUExFWCBUWVBFUycpLAogICAgICAgICdJTlRFR0VSJzogKCdyZWYvaW50ZWdlcnMnLCAnaW50IHJhbmdlJyksCiAgICAgICAgJ0ZMT0FUJzogKCdyZWYvZmxvYXRpbmcnLCAnZmxvYXQgbWF0aCcpLAogICAgICAgICdDT01QTEVYJzogKCdyZWYvaW1hZ2luYXJ5JywgJ2NvbXBsZXggY21hdGgnKSwKICAgICAgICAnU0VRVUVOQ0VTJzogKCdsaWIvdHlwZXNzZXEnLCAnU1RSSU5HTUVUSE9EUyBGT1JNQVRUSU5HIHhyYW5nZSBMSVNUUycpLAogICAgICAgICdNQVBQSU5HUyc6ICdESUNUSU9OQVJJRVMnLAogICAgICAgICdGVU5DVElPTlMnOiAoJ2xpYi90eXBlc2Z1bmN0aW9ucycsICdkZWYgVFlQRVMnKSwKICAgICAgICAnTUVUSE9EUyc6ICgnbGliL3R5cGVzbWV0aG9kcycsICdjbGFzcyBkZWYgQ0xBU1NFUyBUWVBFUycpLAogICAgICAgICdDT0RFT0JKRUNUUyc6ICgnbGliL2JsdGluLWNvZGUtb2JqZWN0cycsICdjb21waWxlIEZVTkNUSU9OUyBUWVBFUycpLAogICAgICAgICdUWVBFT0JKRUNUUyc6ICgnbGliL2JsdGluLXR5cGUtb2JqZWN0cycsICd0eXBlcyBUWVBFUycpLAogICAgICAgICdGUkFNRU9CSkVDVFMnOiAnVFlQRVMnLAogICAgICAgICdUUkFDRUJBQ0tTJzogJ1RZUEVTJywKICAgICAgICAnTk9ORSc6ICgnbGliL2JsdGluLW51bGwtb2JqZWN0JywgJycpLAogICAgICAgICdFTExJUFNJUyc6ICgnbGliL2JsdGluLWVsbGlwc2lzLW9iamVjdCcsICdTTElDSU5HUycpLAogICAgICAgICdGSUxFUyc6ICgnbGliL2JsdGluLWZpbGUtb2JqZWN0cycsICcnKSwKICAgICAgICAnU1BFQ0lBTEFUVFJJQlVURVMnOiAoJ2xpYi9zcGVjaWFsYXR0cnMnLCAnJyksCiAgICAgICAgJ0NMQVNTRVMnOiAoJ3JlZi90eXBlcycsICdjbGFzcyBTUEVDSUFMTUVUSE9EUyBQUklWQVRFTkFNRVMnKSwKICAgICAgICAnTU9EVUxFUyc6ICgnbGliL3R5cGVzbW9kdWxlcycsICdpbXBvcnQnKSwKICAgICAgICAnUEFDS0FHRVMnOiAnaW1wb3J0JywKICAgICAgICAnRVhQUkVTU0lPTlMnOiAoJ3JlZi9zdW1tYXJ5JywgJ2xhbWJkYSBvciBhbmQgbm90IGluIGlzIEJPT0xFQU4gQ09NUEFSSVNPTiBCSVRXSVNFIFNISUZUSU5HIEJJTkFSWSBGT1JNQVRUSU5HIFBPV0VSIFVOQVJZIEFUVFJJQlVURVMgU1VCU0NSSVBUUyBTTElDSU5HUyBDQUxMUyBUVVBMRVMgTElTVFMgRElDVElPTkFSSUVTIEJBQ0tRVU9URVMnKSwKICAgICAgICAnT1BFUkFUT1JTJzogJ0VYUFJFU1NJT05TJywKICAgICAgICAnUFJFQ0VERU5DRSc6ICdFWFBSRVNTSU9OUycsCiAgICAgICAgJ09CSkVDVFMnOiAoJ3JlZi9vYmplY3RzJywgJ1RZUEVTJyksCiAgICAgICAgJ1NQRUNJQUxNRVRIT0RTJzogKCdyZWYvc3BlY2lhbG5hbWVzJywgJ0JBU0lDTUVUSE9EUyBBVFRSSUJVVEVNRVRIT0RTIENBTExBQkxFTUVUSE9EUyBTRVFVRU5DRU1FVEhPRFMxIE1BUFBJTkdNRVRIT0RTIFNFUVVFTkNFTUVUSE9EUzIgTlVNQkVSTUVUSE9EUyBDTEFTU0VTJyksCiAgICAgICAgJ0JBU0lDTUVUSE9EUyc6ICgncmVmL2N1c3RvbWl6YXRpb24nLCAnY21wIGhhc2ggcmVwciBzdHIgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnQVRUUklCVVRFTUVUSE9EUyc6ICgncmVmL2F0dHJpYnV0ZS1hY2Nlc3MnLCAnQVRUUklCVVRFUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdDQUxMQUJMRU1FVEhPRFMnOiAoJ3JlZi9jYWxsYWJsZS10eXBlcycsICdDQUxMUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdTRVFVRU5DRU1FVEhPRFMxJzogKCdyZWYvc2VxdWVuY2UtdHlwZXMnLCAnU0VRVUVOQ0VTIFNFUVVFTkNFTUVUSE9EUzIgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnU0VRVUVOQ0VNRVRIT0RTMic6ICgncmVmL3NlcXVlbmNlLW1ldGhvZHMnLCAnU0VRVUVOQ0VTIFNFUVVFTkNFTUVUSE9EUzEgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnTUFQUElOR01FVEhPRFMnOiAoJ3JlZi9zZXF1ZW5jZS10eXBlcycsICdNQVBQSU5HUyBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdOVU1CRVJNRVRIT0RTJzogKCdyZWYvbnVtZXJpYy10eXBlcycsICdOVU1CRVJTIEFVR01FTlRFREFTU0lHTk1FTlQgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnRVhFQ1VUSU9OJzogKCdyZWYvZXhlY2ZyYW1lcycsICcnKSwKICAgICAgICAnTkFNRVNQQUNFUyc6ICgncmVmL2V4ZWNmcmFtZXMnLCAnZ2xvYmFsIEFTU0lHTk1FTlQgREVMRVRJT04nKSwKICAgICAgICAnU0NPUElORyc6ICdOQU1FU1BBQ0VTJywKICAgICAgICAnRlJBTUVTJzogJ05BTUVTUEFDRVMnLAogICAgICAgICdFWENFUFRJT05TJzogKCdyZWYvZXhjZXB0aW9ucycsICd0cnkgZXhjZXB0IGZpbmFsbHkgcmFpc2UnKSwKICAgICAgICAnQ09FUkNJT05TJzogJ0NPTlZFUlNJT05TJywKICAgICAgICAnQ09OVkVSU0lPTlMnOiAoJ3JlZi9jb252ZXJzaW9ucycsICcnKSwKICAgICAgICAnSURFTlRJRklFUlMnOiAoJ3JlZi9pZGVudGlmaWVycycsICdrZXl3b3JkcyBTUEVDSUFMSURFTlRJRklFUlMnKSwKICAgICAgICAnU1BFQ0lBTElERU5USUZJRVJTJzogKCdyZWYvaWQtY2xhc3NlcycsICcnKSwKICAgICAgICAnUFJJVkFURU5BTUVTJzogKCdyZWYvYXRvbS1pZGVudGlmaWVycycsICcnKSwKICAgICAgICAnTElURVJBTFMnOiAoJ3JlZi9hdG9tLWxpdGVyYWxzJywgJ1NUUklOR1MgQkFDS1FVT1RFUyBOVU1CRVJTIFRVUExFTElURVJBTFMgTElTVExJVEVSQUxTIERJQ1RJT05BUllMSVRFUkFMUycpLAogICAgICAgICdUVVBMRVMnOiAnU0VRVUVOQ0VTJywKICAgICAgICAnVFVQTEVMSVRFUkFMUyc6ICgncmVmL2V4cHJsaXN0cycsICdUVVBMRVMgTElURVJBTFMnKSwKICAgICAgICAnTElTVFMnOiAoJ2xpYi90eXBlc3NlcS1tdXRhYmxlJywgJ0xJU1RMSVRFUkFMUycpLAogICAgICAgICdMSVNUTElURVJBTFMnOiAoJ3JlZi9saXN0cycsICdMSVNUUyBMSVRFUkFMUycpLAogICAgICAgICdESUNUSU9OQVJJRVMnOiAoJ2xpYi90eXBlc21hcHBpbmcnLCAnRElDVElPTkFSWUxJVEVSQUxTJyksCiAgICAgICAgJ0RJQ1RJT05BUllMSVRFUkFMUyc6ICgncmVmL2RpY3QnLCAnRElDVElPTkFSSUVTIExJVEVSQUxTJyksCiAgICAgICAgJ0JBQ0tRVU9URVMnOiAoJ3JlZi9zdHJpbmctY29udmVyc2lvbnMnLCAncmVwciBzdHIgU1RSSU5HUyBMSVRFUkFMUycpLAogICAgICAgICdBVFRSSUJVVEVTJzogKCdyZWYvYXR0cmlidXRlLXJlZmVyZW5jZXMnLCAnZ2V0YXR0ciBoYXNhdHRyIHNldGF0dHIgQVRUUklCVVRFTUVUSE9EUycpLAogICAgICAgICdTVUJTQ1JJUFRTJzogKCdyZWYvc3Vic2NyaXB0aW9ucycsICdTRVFVRU5DRU1FVEhPRFMxJyksCiAgICAgICAgJ1NMSUNJTkdTJzogKCdyZWYvc2xpY2luZ3MnLCAnU0VRVUVOQ0VNRVRIT0RTMicpLAogICAgICAgICdDQUxMUyc6ICgncmVmL2NhbGxzJywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ1BPV0VSJzogKCdyZWYvcG93ZXInLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnVU5BUlknOiAoJ3JlZi91bmFyeScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSU5BUlknOiAoJ3JlZi9iaW5hcnknLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnU0hJRlRJTkcnOiAoJ3JlZi9zaGlmdGluZycsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdCSVRXSVNFJzogKCdyZWYvYml0d2lzZScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdDT01QQVJJU09OJzogKCdyZWYvY29tcGFyaXNvbnMnLCAnRVhQUkVTU0lPTlMgQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ0JPT0xFQU4nOiAoJ3JlZi9sYW1iZGEnLCAnRVhQUkVTU0lPTlMgVFJVVEhWQUxVRScpLAogICAgICAgICdBU1NFUlRJT04nOiAnYXNzZXJ0JywKICAgICAgICAnQVNTSUdOTUVOVCc6ICgncmVmL2Fzc2lnbm1lbnQnLCAnQVVHTUVOVEVEQVNTSUdOTUVOVCcpLAogICAgICAgICdBVUdNRU5URURBU1NJR05NRU5UJzogKCdyZWYvYXVnYXNzaWduJywgJ05VTUJFUk1FVEhPRFMnKSwKICAgICAgICAnREVMRVRJT04nOiAnZGVsJywKICAgICAgICAnUFJJTlRJTkcnOiAncHJpbnQnLAogICAgICAgICdSRVRVUk5JTkcnOiAncmV0dXJuJywKICAgICAgICAnSU1QT1JUSU5HJzogJ2ltcG9ydCcsCiAgICAgICAgJ0NPTkRJVElPTkFMJzogJ2lmJywKICAgICAgICAnTE9PUElORyc6ICgncmVmL2NvbXBvdW5kJywgJ2ZvciB3aGlsZSBicmVhayBjb250aW51ZScpLAogICAgICAgICdUUlVUSFZBTFVFJzogKCdsaWIvdHJ1dGgnLCAnaWYgd2hpbGUgYW5kIG9yIG5vdCBCQVNJQ01FVEhPRFMnKSwKICAgICAgICAnREVCVUdHSU5HJzogKCdsaWIvbW9kdWxlLXBkYicsICdwZGInKSwKICAgIH0KCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5wdXQsIG91dHB1dCk6CiAgICAgICAgc2VsZi5pbnB1dCA9IGlucHV0CiAgICAgICAgc2VsZi5vdXRwdXQgPSBvdXRwdXQKICAgICAgICBzZWxmLmRvY2RpciA9IE5vbmUKICAgICAgICBleGVjZGlyID0gb3MucGF0aC5kaXJuYW1lKHN5cy5leGVjdXRhYmxlKQogICAgICAgIGhvbWVkaXIgPSBvcy5lbnZpcm9uLmdldCgnUFlUSE9OSE9NRScpCiAgICAgICAgZm9yIGRpciBpbiBbb3MuZW52aXJvbi5nZXQoJ1BZVEhPTkRPQ1MnKSwKICAgICAgICAgICAgICAgICAgICBob21lZGlyIGFuZCBvcy5wYXRoLmpvaW4oaG9tZWRpciwgJ2RvYycpLAogICAgICAgICAgICAgICAgICAgIG9zLnBhdGguam9pbihleGVjZGlyLCAnZG9jJyksCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi1kb2NzLScgKyBzcGxpdChzeXMudmVyc2lvbilbMF0sCiAgICAgICAgICAgICAgICAgICAgJy91c3IvZG9jL3B5dGhvbi0nICsgc3BsaXQoc3lzLnZlcnNpb24pWzBdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tZG9jcy0nICsgc3lzLnZlcnNpb25bOjNdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tJyArIHN5cy52ZXJzaW9uWzozXV06CiAgICAgICAgICAgIGlmIGRpciBhbmQgb3MucGF0aC5pc2Rpcihvcy5wYXRoLmpvaW4oZGlyLCAnbGliJykpOgogICAgICAgICAgICAgICAgc2VsZi5kb2NkaXIgPSBkaXIKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgaWYgaW5zcGVjdC5zdGFjaygpWzFdWzNdID09ICc/JzoKICAgICAgICAgICAgc2VsZigpCiAgICAgICAgICAgIHJldHVybiAnJwogICAgICAgIHJldHVybiAnPHB5ZG9jLkhlbHBlciBpbnN0YW5jZT4nCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIHJlcXVlc3Q9Tm9uZSk6CiAgICAgICAgaWYgcmVxdWVzdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5oZWxwKHJlcXVlc3QpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5pbnRybygpCiAgICAgICAgICAgIHNlbGYuaW50ZXJhY3QoKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKWW91IGFyZSBub3cgbGVhdmluZyBoZWxwIGFuZCByZXR1cm5pbmcgdG8gdGhlIFB5dGhvbiBpbnRlcnByZXRlci4KSWYgeW91IHdhbnQgdG8gYXNrIGZvciBoZWxwIG9uIGEgcGFydGljdWxhciBvYmplY3QgZGlyZWN0bHkgZnJvbSB0aGUKaW50ZXJwcmV0ZXIsIHlvdSBjYW4gdHlwZSAiaGVscChvYmplY3QpIi4gIEV4ZWN1dGluZyAiaGVscCgnc3RyaW5nJykiCmhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgdHlwaW5nIGEgcGFydGljdWxhciBzdHJpbmcgYXQgdGhlIGhlbHA+IHByb21wdC4KJycnKQoKICAgIGRlZiBpbnRlcmFjdChzZWxmKToKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4nKQogICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdoZWxwPiAnKQogICAgICAgICAgICBzZWxmLm91dHB1dC5mbHVzaCgpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHJlcXVlc3QgPSBzZWxmLmlucHV0LnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCByZXF1ZXN0OiBicmVhawogICAgICAgICAgICBleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6IGJyZWFrCiAgICAgICAgICAgIHJlcXVlc3QgPSBzdHJpcChyZXBsYWNlKHJlcXVlc3QsICciJywgJycsICInIiwgJycpKQogICAgICAgICAgICBpZiBsb3dlcihyZXF1ZXN0KSBpbiBbJ3EnLCAncXVpdCddOiBicmVhawogICAgICAgICAgICBzZWxmLmhlbHAocmVxdWVzdCkKCiAgICBkZWYgaGVscChzZWxmLCByZXF1ZXN0KToKICAgICAgICBpZiB0eXBlKHJlcXVlc3QpIGlzIHR5cGUoJycpOgogICAgICAgICAgICBpZiByZXF1ZXN0ID09ICdoZWxwJzogc2VsZi5pbnRybygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdCA9PSAna2V5d29yZHMnOiBzZWxmLmxpc3RrZXl3b3JkcygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdCA9PSAndG9waWNzJzogc2VsZi5saXN0dG9waWNzKCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0ID09ICdtb2R1bGVzJzogc2VsZi5saXN0bW9kdWxlcygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdFs6OF0gPT0gJ21vZHVsZXMgJzoKICAgICAgICAgICAgICAgIHNlbGYubGlzdG1vZHVsZXMoc3BsaXQocmVxdWVzdClbMV0pCiAgICAgICAgICAgIGVsaWYgc2VsZi5rZXl3b3Jkcy5oYXNfa2V5KHJlcXVlc3QpOiBzZWxmLnNob3d0b3BpYyhyZXF1ZXN0KQogICAgICAgICAgICBlbGlmIHNlbGYudG9waWNzLmhhc19rZXkocmVxdWVzdCk6IHNlbGYuc2hvd3RvcGljKHJlcXVlc3QpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdDogZG9jKHJlcXVlc3QsICdIZWxwIG9uICVzOicpCiAgICAgICAgZWxpZiBpc2luc3RhbmNlKHJlcXVlc3QsIEhlbHBlcik6IHNlbGYoKQogICAgICAgIGVsc2U6IGRvYyhyZXF1ZXN0LCAnSGVscCBvbiAlczonKQogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdcbicpCgogICAgZGVmIGludHJvKHNlbGYpOgogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpXZWxjb21lIHRvIFB5dGhvbiAlcyEgIFRoaXMgaXMgdGhlIG9ubGluZSBoZWxwIHV0aWxpdHkuCgpJZiB0aGlzIGlzIHlvdXIgZmlyc3QgdGltZSB1c2luZyBQeXRob24sIHlvdSBzaG91bGQgZGVmaW5pdGVseSBjaGVjayBvdXQKdGhlIHR1dG9yaWFsIG9uIHRoZSBJbnRlcm5ldCBhdCBodHRwOi8vd3d3LnB5dGhvbi5vcmcvZG9jL3R1dC8uCgpFbnRlciB0aGUgbmFtZSBvZiBhbnkgbW9kdWxlLCBrZXl3b3JkLCBvciB0b3BpYyB0byBnZXQgaGVscCBvbiB3cml0aW5nClB5dGhvbiBwcm9ncmFtcyBhbmQgdXNpbmcgUHl0aG9uIG1vZHVsZXMuICBUbyBxdWl0IHRoaXMgaGVscCB1dGlsaXR5IGFuZApyZXR1cm4gdG8gdGhlIGludGVycHJldGVyLCBqdXN0IHR5cGUgInF1aXQiLgoKVG8gZ2V0IGEgbGlzdCBvZiBhdmFpbGFibGUgbW9kdWxlcywga2V5d29yZHMsIG9yIHRvcGljcywgdHlwZSAibW9kdWxlcyIsCiJrZXl3b3JkcyIsIG9yICJ0b3BpY3MiLiAgRWFjaCBtb2R1bGUgYWxzbyBjb21lcyB3aXRoIGEgb25lLWxpbmUgc3VtbWFyeQpvZiB3aGF0IGl0IGRvZXM7IHRvIGxpc3QgdGhlIG1vZHVsZXMgd2hvc2Ugc3VtbWFyaWVzIGNvbnRhaW4gYSBnaXZlbiB3b3JkCnN1Y2ggYXMgInNwYW0iLCB0eXBlICJtb2R1bGVzIHNwYW0iLgonJycgJSBzeXMudmVyc2lvbls6M10pCgogICAgZGVmIGxpc3Qoc2VsZiwgaXRlbXMsIGNvbHVtbnM9NCwgd2lkdGg9ODApOgogICAgICAgIGl0ZW1zID0gaXRlbXNbOl0KICAgICAgICBpdGVtcy5zb3J0KCkKICAgICAgICBjb2x3ID0gd2lkdGggLyBjb2x1bW5zCiAgICAgICAgcm93cyA9IChsZW4oaXRlbXMpICsgY29sdW1ucyAtIDEpIC8gY29sdW1ucwogICAgICAgIGZvciByb3cgaW4gcmFuZ2Uocm93cyk6CiAgICAgICAgICAgIGZvciBjb2wgaW4gcmFuZ2UoY29sdW1ucyk6CiAgICAgICAgICAgICAgICBpID0gY29sICogcm93cyArIHJvdwogICAgICAgICAgICAgICAgaWYgaSA8IGxlbihpdGVtcyk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoaXRlbXNbaV0pCiAgICAgICAgICAgICAgICAgICAgaWYgY29sIDwgY29sdW1ucyAtIDE6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcgJyArICcgJyAqIChjb2x3LTEgLSBsZW4oaXRlbXNbaV0pKSkKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ1xuJykKCiAgICBkZWYgbGlzdGtleXdvcmRzKHNlbGYpOgogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpIZXJlIGlzIGEgbGlzdCBvZiB0aGUgUHl0aG9uIGtleXdvcmRzLiAgRW50ZXIgYW55IGtleXdvcmQgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICBzZWxmLmxpc3Qoc2VsZi5rZXl3b3Jkcy5rZXlzKCkpCgogICAgZGVmIGxpc3R0b3BpY3Moc2VsZik6CiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIGF2YWlsYWJsZSB0b3BpY3MuICBFbnRlciBhbnkgdG9waWMgbmFtZSB0byBnZXQgbW9yZSBoZWxwLgoKJycnKQogICAgICAgIHNlbGYubGlzdChzZWxmLnRvcGljcy5rZXlzKCkpCgogICAgZGVmIHNob3d0b3BpYyhzZWxmLCB0b3BpYyk6CiAgICAgICAgaWYgbm90IHNlbGYuZG9jZGlyOgogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKU29ycnksIHRvcGljIGFuZCBrZXl3b3JkIGRvY3VtZW50YXRpb24gaXMgbm90IGF2YWlsYWJsZSBiZWNhdXNlIHRoZSBQeXRob24KSFRNTCBkb2N1bWVudGF0aW9uIGZpbGVzIGNvdWxkIG5vdCBiZSBmb3VuZC4gIElmIHlvdSBoYXZlIGluc3RhbGxlZCB0aGVtLApwbGVhc2Ugc2V0IHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBQWVRIT05ET0NTIHRvIGluZGljYXRlIHRoZWlyIGxvY2F0aW9uLgonJycpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIHRhcmdldCA9IHNlbGYudG9waWNzLmdldCh0b3BpYywgc2VsZi5rZXl3b3Jkcy5nZXQodG9waWMpKQogICAgICAgIGlmIG5vdCB0YXJnZXQ6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdubyBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlc1xuJyAlIHJlcHIodG9waWMpKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiB0eXBlKHRhcmdldCkgaXMgdHlwZSgnJyk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnNob3d0b3BpYyh0YXJnZXQpCgogICAgICAgIGZpbGVuYW1lLCB4cmVmcyA9IHRhcmdldAogICAgICAgIGZpbGVuYW1lID0gc2VsZi5kb2NkaXIgKyAnLycgKyBmaWxlbmFtZSArICcuaHRtbCcKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZpbGUgPSBvcGVuKGZpbGVuYW1lKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ2NvdWxkIG5vdCByZWFkIGRvY3MgZnJvbSAlc1xuJyAlIGZpbGVuYW1lKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgZGl2cGF0ID0gcmUuY29tcGlsZSgnPGRpdltePl0qbmF2aWdhdC4qPzwvZGl2Lio/PicsIHJlLkkgfCByZS5TKQogICAgICAgIGFkZHJwYXQgPSByZS5jb21waWxlKCc8YWRkcmVzcy4qPz4uKj88L2FkZHJlc3MuKj8+JywgcmUuSSB8IHJlLlMpCiAgICAgICAgZG9jdW1lbnQgPSByZS5zdWIoYWRkcnBhdCwgJycsIHJlLnN1YihkaXZwYXQsICcnLCBmaWxlLnJlYWQoKSkpCiAgICAgICAgZmlsZS5jbG9zZSgpCgogICAgICAgIGltcG9ydCBodG1sbGliLCBmb3JtYXR0ZXIsIFN0cmluZ0lPCiAgICAgICAgYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAgICAgIHBhcnNlciA9IGh0bWxsaWIuSFRNTFBhcnNlcigKICAgICAgICAgICAgZm9ybWF0dGVyLkFic3RyYWN0Rm9ybWF0dGVyKGZvcm1hdHRlci5EdW1iV3JpdGVyKGJ1ZmZlcikpKQogICAgICAgIHBhcnNlci5zdGFydF90YWJsZSA9IHBhcnNlci5kb19wCiAgICAgICAgcGFyc2VyLmVuZF90YWJsZSA9IGxhbWJkYSBwYXJzZXI9cGFyc2VyOiBwYXJzZXIuZG9fcCh7fSkKICAgICAgICBwYXJzZXIuc3RhcnRfdHIgPSBwYXJzZXIuZG9fYnIKICAgICAgICBwYXJzZXIuc3RhcnRfdGQgPSBwYXJzZXIuc3RhcnRfdGggPSBsYW1iZGEgYSwgYj1idWZmZXI6IGIud3JpdGUoJ1x0JykKICAgICAgICBwYXJzZXIuZmVlZChkb2N1bWVudCkKICAgICAgICBidWZmZXIgPSByZXBsYWNlKGJ1ZmZlci5nZXR2YWx1ZSgpLCAnXHhhMCcsICcgJywgJ1xuJywgJ1xuICAnKQogICAgICAgIHBhZ2VyKCcgICcgKyBzdHJpcChidWZmZXIpICsgJ1xuJykKICAgICAgICBpZiB4cmVmczoKICAgICAgICAgICAgYnVmZmVyID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAgICAgICAgICBmb3JtYXR0ZXIuRHVtYldyaXRlcihidWZmZXIpLnNlbmRfZmxvd2luZ19kYXRhKAogICAgICAgICAgICAgICAgJ1JlbGF0ZWQgaGVscCB0b3BpY3M6ICcgKyBqb2luKHNwbGl0KHhyZWZzKSwgJywgJykgKyAnXG4nKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4lc1xuJyAlIGJ1ZmZlci5nZXR2YWx1ZSgpKQoKICAgIGRlZiBsaXN0bW9kdWxlcyhzZWxmLCBrZXk9JycpOgogICAgICAgIGlmIGtleToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkhlcmUgaXMgYSBsaXN0IG9mIG1hdGNoaW5nIG1vZHVsZXMuICBFbnRlciBhbnkgbW9kdWxlIG5hbWUgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICAgICAgYXByb3BvcyhrZXkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnClBsZWFzZSB3YWl0IGEgbW9tZW50IHdoaWxlIEkgZ2F0aGVyIGEgbGlzdCBvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuLi4KCicnJykKICAgICAgICAgICAgbW9kdWxlcyA9IHt9CiAgICAgICAgICAgIGRlZiBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjLCBtb2R1bGVzPW1vZHVsZXMpOgogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSBhbmQgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICAgICAgICAgIGlmIGZpbmQobW9kbmFtZSwgJy4nKSA8IDA6CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlc1ttb2RuYW1lXSA9IDEKICAgICAgICAgICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihjYWxsYmFjaykKICAgICAgICAgICAgc2VsZi5saXN0KG1vZHVsZXMua2V5cygpKQogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKRW50ZXIgYW55IG1vZHVsZSBuYW1lIHRvIGdldCBtb3JlIGhlbHAuICBPciwgdHlwZSAibW9kdWxlcyBzcGFtIiB0byBzZWFyY2gKZm9yIG1vZHVsZXMgd2hvc2UgZGVzY3JpcHRpb25zIGNvbnRhaW4gdGhlIHdvcmQgInNwYW0iLgonJycpCgpoZWxwID0gSGVscGVyKHN5cy5zdGRpbiwgc3lzLnN0ZG91dCkKCmNsYXNzIFNjYW5uZXI6CiAgICAiIiJBIGdlbmVyaWMgdHJlZSBpdGVyYXRvci4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmLCByb290cywgY2hpbGRyZW4sIGRlc2NlbmRwKToKICAgICAgICBzZWxmLnJvb3RzID0gcm9vdHNbOl0KICAgICAgICBzZWxmLnN0YXRlID0gW10KICAgICAgICBzZWxmLmNoaWxkcmVuID0gY2hpbGRyZW4KICAgICAgICBzZWxmLmRlc2NlbmRwID0gZGVzY2VuZHAKCiAgICBkZWYgbmV4dChzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5zdGF0ZToKICAgICAgICAgICAgaWYgbm90IHNlbGYucm9vdHM6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICByb290ID0gc2VsZi5yb290cy5wb3AoMCkKICAgICAgICAgICAgc2VsZi5zdGF0ZSA9IFsocm9vdCwgc2VsZi5jaGlsZHJlbihyb290KSldCiAgICAgICAgbm9kZSwgY2hpbGRyZW4gPSBzZWxmLnN0YXRlWy0xXQogICAgICAgIGlmIG5vdCBjaGlsZHJlbjoKICAgICAgICAgICAgc2VsZi5zdGF0ZS5wb3AoKQogICAgICAgICAgICByZXR1cm4gc2VsZi5uZXh0KCkKICAgICAgICBjaGlsZCA9IGNoaWxkcmVuLnBvcCgwKQogICAgICAgIGlmIHNlbGYuZGVzY2VuZHAoY2hpbGQpOgogICAgICAgICAgICBzZWxmLnN0YXRlLmFwcGVuZCgoY2hpbGQsIHNlbGYuY2hpbGRyZW4oY2hpbGQpKSkKICAgICAgICByZXR1cm4gY2hpbGQKCmNsYXNzIE1vZHVsZVNjYW5uZXIoU2Nhbm5lcik6CiAgICAiIiJBbiBpbnRlcnJ1cHRpYmxlIHNjYW5uZXIgdGhhdCBzZWFyY2hlcyBtb2R1bGUgc3lub3BzZXMuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgcm9vdHMgPSBtYXAobGFtYmRhIGRpcjogKGRpciwgJycpLCBwYXRoZGlycygpKQogICAgICAgIFNjYW5uZXIuX19pbml0X18oc2VsZiwgcm9vdHMsIHNlbGYuc3VibW9kdWxlcywgc2VsZi5pc25ld3BhY2thZ2UpCiAgICAgICAgc2VsZi5pbm9kZXMgPSBtYXAobGFtYmRhIChkaXIsIHBrZyk6IG9zLnN0YXQoZGlyKVsxXSwgcm9vdHMpCgogICAgZGVmIHN1Ym1vZHVsZXMoc2VsZiwgKGRpciwgcGFja2FnZSkpOgogICAgICAgIGNoaWxkcmVuID0gW10KICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGRpcik6CiAgICAgICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgICAgICBpZiBpc3BhY2thZ2UocGF0aCk6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIGZpbGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW4uYXBwZW5kKChwYXRoLCBwYWNrYWdlKSkKICAgICAgICBjaGlsZHJlbi5zb3J0KCkgIyBzbyB0aGF0IHNwYW0ucHkgY29tZXMgYmVmb3JlIHNwYW0ucHljIG9yIHNwYW0ucHlvCiAgICAgICAgcmV0dXJuIGNoaWxkcmVuCgogICAgZGVmIGlzbmV3cGFja2FnZShzZWxmLCAoZGlyLCBwYWNrYWdlKSk6CiAgICAgICAgaW5vZGUgPSBvcy5wYXRoLmV4aXN0cyhkaXIpIGFuZCBvcy5zdGF0KGRpcilbMV0KICAgICAgICBpZiBub3QgKG9zLnBhdGguaXNsaW5rKGRpcikgYW5kIGlub2RlIGluIHNlbGYuaW5vZGVzKToKICAgICAgICAgICAgc2VsZi5pbm9kZXMuYXBwZW5kKGlub2RlKSAjIGRldGVjdCBjaXJjdWxhciBzeW1ib2xpYyBsaW5rcwogICAgICAgICAgICByZXR1cm4gaXNwYWNrYWdlKGRpcikKCiAgICBkZWYgcnVuKHNlbGYsIGNhbGxiYWNrLCBrZXk9Tm9uZSwgY29tcGxldGVyPU5vbmUpOgogICAgICAgIGlmIGtleToga2V5ID0gbG93ZXIoa2V5KQogICAgICAgIHNlbGYucXVpdCA9IDAKICAgICAgICBzZWVuID0ge30KCiAgICAgICAgZm9yIG1vZG5hbWUgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICBpZiBtb2RuYW1lICE9ICdfX21haW5fXyc6CiAgICAgICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMQogICAgICAgICAgICAgICAgaWYga2V5IGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soTm9uZSwgbW9kbmFtZSwgJycpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIGRlc2MgPSBzcGxpdChfX2ltcG9ydF9fKG1vZG5hbWUpLl9fZG9jX18gb3IgJycsICdcbicpWzBdCiAgICAgICAgICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwga2V5KSA+PSAwOgogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhOb25lLCBtb2RuYW1lLCBkZXNjKQoKICAgICAgICB3aGlsZSBub3Qgc2VsZi5xdWl0OgogICAgICAgICAgICBub2RlID0gc2VsZi5uZXh0KCkKICAgICAgICAgICAgaWYgbm90IG5vZGU6IGJyZWFrCiAgICAgICAgICAgIHBhdGgsIHBhY2thZ2UgPSBub2RlCiAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUocGF0aCkKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocGF0aCkgYW5kIG1vZG5hbWU6CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gcGFja2FnZSArIChwYWNrYWdlIGFuZCAnLicpICsgbW9kbmFtZQogICAgICAgICAgICAgICAgaWYgbm90IHNlZW4uaGFzX2tleShtb2RuYW1lKToKICAgICAgICAgICAgICAgICAgICBzZWVuW21vZG5hbWVdID0gMSAjIGlmIHdlIHNlZSBzcGFtLnB5LCBza2lwIHNwYW0ucHljCiAgICAgICAgICAgICAgICAgICAgaWYga2V5IGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsICcnKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MgPSBzeW5vcHNpcyhwYXRoKSBvciAnJwogICAgICAgICAgICAgICAgICAgICAgICBpZiBmaW5kKGxvd2VyKG1vZG5hbWUgKyAnIC0gJyArIGRlc2MpLCBrZXkpID49IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjKQogICAgICAgIGlmIGNvbXBsZXRlcjogY29tcGxldGVyKCkKCmRlZiBhcHJvcG9zKGtleSk6CiAgICAiIiJQcmludCBhbGwgdGhlIG9uZS1saW5lIG1vZHVsZSBzdW1tYXJpZXMgdGhhdCBjb250YWluIGEgc3Vic3RyaW5nLiIiIgogICAgZGVmIGNhbGxiYWNrKHBhdGgsIG1vZG5hbWUsIGRlc2MpOgogICAgICAgIGlmIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgbW9kbmFtZSA9IG1vZG5hbWVbOi05XSArICcgKHBhY2thZ2UpJwogICAgICAgIHByaW50IG1vZG5hbWUsIGRlc2MgYW5kICctICcgKyBkZXNjCiAgICB0cnk6IGltcG9ydCB3YXJuaW5ncwogICAgZXhjZXB0IEltcG9ydEVycm9yOiBwYXNzCiAgICBlbHNlOiB3YXJuaW5ncy5maWx0ZXJ3YXJuaW5ncygnaWdub3JlJykgIyBpZ25vcmUgcHJvYmxlbXMgZHVyaW5nIGltcG9ydAogICAgTW9kdWxlU2Nhbm5lcigpLnJ1bihjYWxsYmFjaywga2V5KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gd2ViIGJyb3dzZXIgaW50ZXJmYWNlCgpkZWYgc2VydmUocG9ydCwgY2FsbGJhY2s9Tm9uZSwgY29tcGxldGVyPU5vbmUpOgogICAgaW1wb3J0IEJhc2VIVFRQU2VydmVyLCBtaW1ldG9vbHMsIHNlbGVjdAoKICAgICMgUGF0Y2ggdXAgbWltZXRvb2xzLk1lc3NhZ2Ugc28gaXQgZG9lc24ndCBicmVhayBpZiByZmM4MjIgaXMgcmVsb2FkZWQuCiAgICBjbGFzcyBNZXNzYWdlKG1pbWV0b29scy5NZXNzYWdlKToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgZnAsIHNlZWthYmxlPTEpOgogICAgICAgICAgICBNZXNzYWdlID0gc2VsZi5fX2NsYXNzX18KICAgICAgICAgICAgTWVzc2FnZS5fX2Jhc2VzX19bMF0uX19iYXNlc19fWzBdLl9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZSkKICAgICAgICAgICAgc2VsZi5lbmNvZGluZ2hlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXRyYW5zZmVyLWVuY29kaW5nJykKICAgICAgICAgICAgc2VsZi50eXBlaGVhZGVyID0gc2VsZi5nZXRoZWFkZXIoJ2NvbnRlbnQtdHlwZScpCiAgICAgICAgICAgIHNlbGYucGFyc2V0eXBlKCkKICAgICAgICAgICAgc2VsZi5wYXJzZXBsaXN0KCkKCiAgICBjbGFzcyBEb2NIYW5kbGVyKEJhc2VIVFRQU2VydmVyLkJhc2VIVFRQUmVxdWVzdEhhbmRsZXIpOgogICAgICAgIGRlZiBzZW5kX2RvY3VtZW50KHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9yZXNwb25zZSgyMDApCiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfaGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJykKICAgICAgICAgICAgICAgIHNlbGYuZW5kX2hlYWRlcnMoKQogICAgICAgICAgICAgICAgc2VsZi53ZmlsZS53cml0ZShodG1sLnBhZ2UodGl0bGUsIGNvbnRlbnRzKSkKICAgICAgICAgICAgZXhjZXB0IElPRXJyb3I6IHBhc3MKCiAgICAgICAgZGVmIGRvX0dFVChzZWxmKToKICAgICAgICAgICAgcGF0aCA9IHNlbGYucGF0aAogICAgICAgICAgICBpZiBwYXRoWy01Ol0gPT0gJy5odG1sJzogcGF0aCA9IHBhdGhbOi01XQogICAgICAgICAgICBpZiBwYXRoWzoxXSA9PSAnLyc6IHBhdGggPSBwYXRoWzE6XQogICAgICAgICAgICBpZiBwYXRoIGFuZCBwYXRoICE9ICcuJzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICBvYmogPSBsb2NhdGUocGF0aCwgZm9yY2Vsb2FkPTEpCiAgICAgICAgICAgICAgICBleGNlcHQgRXJyb3JEdXJpbmdJbXBvcnQsIHZhbHVlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudChwYXRoLCBodG1sLmVzY2FwZShzdHIodmFsdWUpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIG9iajoKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQoZGVzY3JpYmUob2JqKSwgaHRtbC5kb2N1bWVudChvYmosIHBhdGgpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwKJ25vIFB5dGhvbiBkb2N1bWVudGF0aW9uIGZvdW5kIGZvciAlcycgJSByZXByKHBhdGgpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgaGVhZGluZyA9IGh0bWwuaGVhZGluZygKJzxiaWc+PGJpZz48c3Ryb25nPlB5dGhvbjogSW5kZXggb2YgTW9kdWxlczwvc3Ryb25nPjwvYmlnPjwvYmlnPicsCicjZmZmZmZmJywgJyM3Nzk5ZWUnKQogICAgICAgICAgICAgICAgZGVmIGJsdGlubGluayhuYW1lKToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwiPiVzPC9hPicgJSAobmFtZSwgbmFtZSkKICAgICAgICAgICAgICAgIG5hbWVzID0gZmlsdGVyKGxhbWJkYSB4OiB4ICE9ICdfX21haW5fXycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXMpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGh0bWwubXVsdGljb2x1bW4obmFtZXMsIGJsdGlubGluaykKICAgICAgICAgICAgICAgIGluZGljZXMgPSBbJzxwPicgKyBodG1sLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgJ0J1aWx0LWluIE1vZHVsZXMnLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpXQoKICAgICAgICAgICAgICAgIHNlZW4gPSB7fQogICAgICAgICAgICAgICAgZm9yIGRpciBpbiBwYXRoZGlycygpOgogICAgICAgICAgICAgICAgICAgIGluZGljZXMuYXBwZW5kKGh0bWwuaW5kZXgoZGlyLCBzZWVuKSkKICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gaGVhZGluZyArIGpvaW4oaW5kaWNlcykgKyAnJyc8cCBhbGlnbj1yaWdodD4KPGZvbnQgY29sb3I9IiM5MDkwOTAiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPjxzdHJvbmc+CnB5ZG9jPC9zdHJvbmc+IGJ5IEthLVBpbmcgWWVlICZsdDtwaW5nQGxmdy5vcmcmZ3Q7PC9mb250PicnJwogICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KCdJbmRleCBvZiBNb2R1bGVzJywgY29udGVudHMpCgogICAgICAgIGRlZiBsb2dfbWVzc2FnZShzZWxmLCAqYXJncyk6IHBhc3MKCiAgICBjbGFzcyBEb2NTZXJ2ZXIoQmFzZUhUVFBTZXJ2ZXIuSFRUUFNlcnZlcik6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIHBvcnQsIGNhbGxiYWNrKToKICAgICAgICAgICAgaG9zdCA9IChzeXMucGxhdGZvcm0gPT0gJ21hYycpIGFuZCAnMTI3LjAuMC4xJyBvciAnbG9jYWxob3N0JwogICAgICAgICAgICBzZWxmLmFkZHJlc3MgPSAoJycsIHBvcnQpCiAgICAgICAgICAgIHNlbGYudXJsID0gJ2h0dHA6Ly8lczolZC8nICUgKGhvc3QsIHBvcnQpCiAgICAgICAgICAgIHNlbGYuY2FsbGJhY2sgPSBjYWxsYmFjawogICAgICAgICAgICBzZWxmLmJhc2UuX19pbml0X18oc2VsZiwgc2VsZi5hZGRyZXNzLCBzZWxmLmhhbmRsZXIpCgogICAgICAgIGRlZiBzZXJ2ZV91bnRpbF9xdWl0KHNlbGYpOgogICAgICAgICAgICBpbXBvcnQgc2VsZWN0CiAgICAgICAgICAgIHNlbGYucXVpdCA9IDAKICAgICAgICAgICAgd2hpbGUgbm90IHNlbGYucXVpdDoKICAgICAgICAgICAgICAgIHJkLCB3ciwgZXggPSBzZWxlY3Quc2VsZWN0KFtzZWxmLnNvY2tldC5maWxlbm8oKV0sIFtdLCBbXSwgMSkKICAgICAgICAgICAgICAgIGlmIHJkOiBzZWxmLmhhbmRsZV9yZXF1ZXN0KCkKCiAgICAgICAgZGVmIHNlcnZlcl9hY3RpdmF0ZShzZWxmKToKICAgICAgICAgICAgc2VsZi5iYXNlLnNlcnZlcl9hY3RpdmF0ZShzZWxmKQogICAgICAgICAgICBpZiBzZWxmLmNhbGxiYWNrOiBzZWxmLmNhbGxiYWNrKHNlbGYpCgogICAgRG9jU2VydmVyLmJhc2UgPSBCYXNlSFRUUFNlcnZlci5IVFRQU2VydmVyCiAgICBEb2NTZXJ2ZXIuaGFuZGxlciA9IERvY0hhbmRsZXIKICAgIERvY0hhbmRsZXIuTWVzc2FnZUNsYXNzID0gTWVzc2FnZQogICAgdHJ5OgogICAgICAgIHRyeToKICAgICAgICAgICAgRG9jU2VydmVyKHBvcnQsIGNhbGxiYWNrKS5zZXJ2ZV91bnRpbF9xdWl0KCkKICAgICAgICBleGNlcHQgKEtleWJvYXJkSW50ZXJydXB0LCBzZWxlY3QuZXJyb3IpOgogICAgICAgICAgICBwYXNzCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNvbXBsZXRlcjogY29tcGxldGVyKCkKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZ3JhcGhpY2FsIGludGVyZmFjZQoKZGVmIGd1aSgpOgogICAgIiIiR3JhcGhpY2FsIGludGVyZmFjZSAoc3RhcnRzIHdlYiBzZXJ2ZXIgYW5kIHBvcHMgdXAgYSBjb250cm9sIHdpbmRvdykuIiIiCiAgICBjbGFzcyBHVUk6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIHdpbmRvdywgcG9ydD03NDY0KToKICAgICAgICAgICAgc2VsZi53aW5kb3cgPSB3aW5kb3cKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBOb25lCiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKCiAgICAgICAgICAgIGltcG9ydCBUa2ludGVyCiAgICAgICAgICAgIHNlbGYuc2VydmVyX2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLnRpdGxlX2xibCA9IFRraW50ZXIuTGFiZWwoc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nU3RhcnRpbmcgc2VydmVyLi4uXG4gJykKICAgICAgICAgICAgc2VsZi5vcGVuX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VydmVyX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J29wZW4gYnJvd3NlcicsIGNvbW1hbmQ9c2VsZi5vcGVuLCBzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBzZWxmLnF1aXRfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0ncXVpdCBzZXJ2aW5nJywgY29tbWFuZD1zZWxmLnF1aXQsIHN0YXRlPSdkaXNhYmxlZCcpCgogICAgICAgICAgICBzZWxmLnNlYXJjaF9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsID0gVGtpbnRlci5MYWJlbChzZWxmLnNlYXJjaF9mcm0sIHRleHQ9J1NlYXJjaCBmb3InKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQgPSBUa2ludGVyLkVudHJ5KHNlbGYuc2VhcmNoX2ZybSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmJpbmQoJzxSZXR1cm4+Jywgc2VsZi5zZWFyY2gpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlYXJjaF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdzdG9wJywgcGFkeT0wLCBjb21tYW5kPXNlbGYuc3RvcCwgc3RhdGU9J2Rpc2FibGVkJykKICAgICAgICAgICAgaWYgc3lzLnBsYXRmb3JtID09ICd3aW4zMic6CiAgICAgICAgICAgICAgICAjIFRyeWluZyB0byBoaWRlIGFuZCBzaG93IHRoaXMgYnV0dG9uIGNyYXNoZXMgdW5kZXIgV2luZG93cy4KICAgICAgICAgICAgICAgIHNlbGYuc3RvcF9idG4ucGFjayhzaWRlPSdyaWdodCcpCgogICAgICAgICAgICBzZWxmLndpbmRvdy50aXRsZSgncHlkb2MnKQogICAgICAgICAgICBzZWxmLndpbmRvdy5wcm90b2NvbCgnV01fREVMRVRFX1dJTkRPVycsIHNlbGYucXVpdCkKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5wYWNrKHNpZGU9J2xlZnQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4ucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5zZXJ2ZXJfZnJtLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCgogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuZm9jdXNfc2V0KCkKCiAgICAgICAgICAgIGZvbnQgPSAoJ2hlbHZldGljYScsIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInIGFuZCA4IG9yIDEwKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QgPSBUa2ludGVyLkxpc3Rib3god2luZG93LCBmb250PWZvbnQsIGhlaWdodD02KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPEJ1dHRvbi0xPicsIHNlbGYuc2VsZWN0KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuYmluZCgnPERvdWJsZS1CdXR0b24tMT4nLCBzZWxmLmdvdG8pCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3NjciA9IFRraW50ZXIuU2Nyb2xsYmFyKHdpbmRvdywKICAgICAgICAgICAgICAgIG9yaWVudD0ndmVydGljYWwnLCBjb21tYW5kPXNlbGYucmVzdWx0X2xzdC55dmlldykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmNvbmZpZyh5c2Nyb2xsY29tbWFuZD1zZWxmLnJlc3VsdF9zY3Iuc2V0KQoKICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnJlc3VsdF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdnbyB0byBzZWxlY3RlZCcsIGNvbW1hbmQ9c2VsZi5nb3RvKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5yZXN1bHRfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0naGlkZSByZXN1bHRzJywgY29tbWFuZD1zZWxmLmhpZGUpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4ucGFjayhzaWRlPSdsZWZ0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLmhpZGVfYnRuLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCgogICAgICAgICAgICBzZWxmLndpbmRvdy51cGRhdGUoKQogICAgICAgICAgICBzZWxmLm1pbndpZHRoID0gc2VsZi53aW5kb3cud2luZm9fd2lkdGgoKQogICAgICAgICAgICBzZWxmLm1pbmhlaWdodCA9IHNlbGYud2luZG93LndpbmZvX2hlaWdodCgpCiAgICAgICAgICAgIHNlbGYuYmlnbWluaGVpZ2h0ID0gKHNlbGYuc2VydmVyX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybS53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC53aW5mb19yZXFoZWlnaHQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS53aW5mb19yZXFoZWlnaHQoKSkKICAgICAgICAgICAgc2VsZi5iaWd3aWR0aCwgc2VsZi5iaWdoZWlnaHQgPSBzZWxmLm1pbndpZHRoLCBzZWxmLmJpZ21pbmhlaWdodAogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMAogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkKCiAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCgKICAgICAgICAgICAgICAgIHRhcmdldD1zZXJ2ZSwgYXJncz0ocG9ydCwgc2VsZi5yZWFkeSwgc2VsZi5xdWl0KSkuc3RhcnQoKQoKICAgICAgICBkZWYgcmVhZHkoc2VsZiwgc2VydmVyKToKICAgICAgICAgICAgc2VsZi5zZXJ2ZXIgPSBzZXJ2ZXIKICAgICAgICAgICAgc2VsZi50aXRsZV9sYmwuY29uZmlnKAogICAgICAgICAgICAgICAgdGV4dD0nUHl0aG9uIGRvY3VtZW50YXRpb24gc2VydmVyIGF0XG4nICsgc2VydmVyLnVybCkKICAgICAgICAgICAgc2VsZi5vcGVuX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgb3BlbihzZWxmLCBldmVudD1Ob25lLCB1cmw9Tm9uZSk6CiAgICAgICAgICAgIHVybCA9IHVybCBvciBzZWxmLnNlcnZlci51cmwKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW1wb3J0IHdlYmJyb3dzZXIKICAgICAgICAgICAgICAgIHdlYmJyb3dzZXIub3Blbih1cmwpCiAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjogIyBwcmUtd2ViYnJvd3Nlci5weSBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgICAgICBvcy5zeXN0ZW0oJ3N0YXJ0ICIlcyInICUgdXJsKQogICAgICAgICAgICAgICAgZWxpZiBzeXMucGxhdGZvcm0gPT0gJ21hYyc6CiAgICAgICAgICAgICAgICAgICAgdHJ5OiBpbXBvcnQgaWMKICAgICAgICAgICAgICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6IHBhc3MKICAgICAgICAgICAgICAgICAgICBlbHNlOiBpYy5sYXVuY2h1cmwodXJsKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYyA9IG9zLnN5c3RlbSgnbmV0c2NhcGUgLXJlbW90ZSAib3BlblVSTCglcykiICYnICUgdXJsKQogICAgICAgICAgICAgICAgICAgIGlmIHJjOiBvcy5zeXN0ZW0oJ25ldHNjYXBlICIlcyIgJicgJSB1cmwpCgogICAgICAgIGRlZiBxdWl0KHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBpZiBzZWxmLnNlcnZlcjoKICAgICAgICAgICAgICAgIHNlbGYuc2VydmVyLnF1aXQgPSAxCiAgICAgICAgICAgIHNlbGYud2luZG93LnF1aXQoKQoKICAgICAgICBkZWYgc2VhcmNoKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBrZXkgPSBzZWxmLnNlYXJjaF9lbnQuZ2V0KCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JykKICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5jb25maWcodGV4dD0nU2VhcmNoaW5nIGZvciAiJXMiLi4uJyAlIGtleSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuZGVsZXRlKDAsICdlbmQnKQogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLmNvbmZpZyhzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBzZWxmLmV4cGFuZCgpCgogICAgICAgICAgICBpbXBvcnQgdGhyZWFkaW5nCiAgICAgICAgICAgIGlmIHNlbGYuc2Nhbm5lcjoKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lci5xdWl0ID0gMQogICAgICAgICAgICBzZWxmLnNjYW5uZXIgPSBNb2R1bGVTY2FubmVyKCkKICAgICAgICAgICAgdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9c2VsZi5zY2FubmVyLnJ1biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzPShzZWxmLnVwZGF0ZSwga2V5LCBzZWxmLmRvbmUpKS5zdGFydCgpCgogICAgICAgIGRlZiB1cGRhdGUoc2VsZiwgcGF0aCwgbW9kbmFtZSwgZGVzYyk6CiAgICAgICAgICAgIGlmIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0Lmluc2VydCgnZW5kJywKICAgICAgICAgICAgICAgIG1vZG5hbWUgKyAnIC0gJyArIChkZXNjIG9yICcobm8gZGVzY3JpcHRpb24pJykpCgogICAgICAgIGRlZiBzdG9wKHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBpZiBzZWxmLnNjYW5uZXI6CiAgICAgICAgICAgICAgICBzZWxmLnNjYW5uZXIucXVpdCA9IDEKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKCiAgICAgICAgZGVmIGRvbmUoc2VsZik6CiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLmNvbmZpZyh0ZXh0PSdTZWFyY2ggZm9yJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gIT0gJ3dpbjMyJzogc2VsZi5zdG9wX2J0bi5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLmNvbmZpZyhzdGF0ZT0nZGlzYWJsZWQnKQoKICAgICAgICBkZWYgc2VsZWN0KHNlbGYsIGV2ZW50PU5vbmUpOgogICAgICAgICAgICBzZWxmLmdvdG9fYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKCiAgICAgICAgZGVmIGdvdG8oc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGVjdGlvbiA9IHNlbGYucmVzdWx0X2xzdC5jdXJzZWxlY3Rpb24oKQogICAgICAgICAgICBpZiBzZWxlY3Rpb246CiAgICAgICAgICAgICAgICBtb2RuYW1lID0gc3BsaXQoc2VsZi5yZXN1bHRfbHN0LmdldChzZWxlY3Rpb25bMF0pKVswXQogICAgICAgICAgICAgICAgc2VsZi5vcGVuKHVybD1zZWxmLnNlcnZlci51cmwgKyBtb2RuYW1lICsgJy5odG1sJykKCiAgICAgICAgZGVmIGNvbGxhcHNlKHNlbGYpOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5leHBhbmRlZDogcmV0dXJuCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuYmlnd2lkdGggPSBzZWxmLndpbmRvdy53aW5mb193aWR0aCgpCiAgICAgICAgICAgIHNlbGYuYmlnaGVpZ2h0ID0gc2VsZi53aW5kb3cud2luZm9faGVpZ2h0KCkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fZ2VvbWV0cnkoJyVkeCVkJyAlIChzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX21pbnNpemUoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAwCgogICAgICAgIGRlZiBleHBhbmQoc2VsZik6CiAgICAgICAgICAgIGlmIHNlbGYuZXhwYW5kZWQ6IHJldHVybgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0ucGFjayhzaWRlPSdib3R0b20nLCBmaWxsPSd4JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyLnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd5JykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LnBhY2soc2lkZT0ndG9wJywgZmlsbD0nYm90aCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYuYmlnd2lkdGgsIHNlbGYuYmlnaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLmJpZ21pbmhlaWdodCkKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDEKCiAgICAgICAgZGVmIGhpZGUoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGYuc3RvcCgpCiAgICAgICAgICAgIHNlbGYuY29sbGFwc2UoKQoKICAgIGltcG9ydCBUa2ludGVyCiAgICB0cnk6CiAgICAgICAgZ3VpID0gR1VJKFRraW50ZXIuVGsoKSkKICAgICAgICBUa2ludGVyLm1haW5sb29wKCkKICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdDoKICAgICAgICBwYXNzCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1hbmQtbGluZSBpbnRlcmZhY2UKCmRlZiBpc3BhdGgoeCk6CiAgICByZXR1cm4gdHlwZSh4KSBpcyB0eXBlcy5TdHJpbmdUeXBlIGFuZCBmaW5kKHgsIG9zLnNlcCkgPj0gMAoKZGVmIGNsaSgpOgogICAgIiIiQ29tbWFuZC1saW5lIGludGVyZmFjZSAobG9va3MgYXQgc3lzLmFyZ3YgdG8gZGVjaWRlIHdoYXQgdG8gZG8pLiIiIgogICAgaW1wb3J0IGdldG9wdAogICAgY2xhc3MgQmFkVXNhZ2U6IHBhc3MKCiAgICAjIFNjcmlwdHMgZG9uJ3QgZ2V0IHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpbiB0aGVpciBwYXRoIGJ5IGRlZmF1bHQuCiAgICBzY3JpcHRkaXIgPSBvcy5wYXRoLmRpcm5hbWUoc3lzLmFyZ3ZbMF0pCiAgICBpZiBzY3JpcHRkaXIgaW4gc3lzLnBhdGg6CiAgICAgICAgc3lzLnBhdGgucmVtb3ZlKHNjcmlwdGRpcikKICAgIHN5cy5wYXRoLmluc2VydCgwLCAnLicpCgogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KHN5cy5hcmd2WzE6XSwgJ2drOnA6dycpCiAgICAgICAgd3JpdGluZyA9IDAKCiAgICAgICAgZm9yIG9wdCwgdmFsIGluIG9wdHM6CiAgICAgICAgICAgIGlmIG9wdCA9PSAnLWcnOgogICAgICAgICAgICAgICAgZ3VpKCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy1rJzoKICAgICAgICAgICAgICAgIGFwcm9wb3ModmFsKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXAnOgogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIHBvcnQgPSBpbnQodmFsKQogICAgICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQmFkVXNhZ2UKICAgICAgICAgICAgICAgIGRlZiByZWFkeShzZXJ2ZXIpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICdweWRvYyBzZXJ2ZXIgcmVhZHkgYXQgJXMnICUgc2VydmVyLnVybAogICAgICAgICAgICAgICAgZGVmIHN0b3BwZWQoKToKICAgICAgICAgICAgICAgICAgICBwcmludCAncHlkb2Mgc2VydmVyIHN0b3BwZWQnCiAgICAgICAgICAgICAgICBzZXJ2ZShwb3J0LCByZWFkeSwgc3RvcHBlZCkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBvcHQgPT0gJy13JzoKICAgICAgICAgICAgICAgIHdyaXRpbmcgPSAxCgogICAgICAgIGlmIG5vdCBhcmdzOiByYWlzZSBCYWRVc2FnZQogICAgICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaWYgaXNwYXRoKGFyZykgYW5kIG9zLnBhdGguaXNmaWxlKGFyZyk6CiAgICAgICAgICAgICAgICAgICAgYXJnID0gaW1wb3J0ZmlsZShhcmcpCiAgICAgICAgICAgICAgICBpZiB3cml0aW5nOgogICAgICAgICAgICAgICAgICAgIGlmIGlzcGF0aChhcmcpIGFuZCBvcy5wYXRoLmlzZGlyKGFyZyk6CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlZG9jcyhhcmcpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVkb2MoYXJnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBkb2MoYXJnKQogICAgICAgICAgICBleGNlcHQgRXJyb3JEdXJpbmdJbXBvcnQsIHZhbHVlOgogICAgICAgICAgICAgICAgcHJpbnQgdmFsdWUKCiAgICBleGNlcHQgKGdldG9wdC5lcnJvciwgQmFkVXNhZ2UpOgogICAgICAgIGNtZCA9IHN5cy5hcmd2WzBdCiAgICAgICAgcHJpbnQgIiIicHlkb2MgLSB0aGUgUHl0aG9uIGRvY3VtZW50YXRpb24gdG9vbAoKJXMgPG5hbWU+IC4uLgogICAgU2hvdyB0ZXh0IGRvY3VtZW50YXRpb24gb24gc29tZXRoaW5nLiAgPG5hbWU+IG1heSBiZSB0aGUgbmFtZSBvZiBhCiAgICBmdW5jdGlvbiwgbW9kdWxlLCBvciBwYWNrYWdlLCBvciBhIGRvdHRlZCByZWZlcmVuY2UgdG8gYSBjbGFzcyBvcgogICAgZnVuY3Rpb24gd2l0aGluIGEgbW9kdWxlIG9yIG1vZHVsZSBpbiBhIHBhY2thZ2UuICBJZiA8bmFtZT4gY29udGFpbnMKICAgIGEgJyVzJywgaXQgaXMgdXNlZCBhcyB0aGUgcGF0aCB0byBhIFB5dGhvbiBzb3VyY2UgZmlsZSB0byBkb2N1bWVudC4KCiVzIC1rIDxrZXl3b3JkPgogICAgU2VhcmNoIGZvciBhIGtleXdvcmQgaW4gdGhlIHN5bm9wc2lzIGxpbmVzIG9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KCiVzIC1wIDxwb3J0PgogICAgU3RhcnQgYW4gSFRUUCBzZXJ2ZXIgb24gdGhlIGdpdmVuIHBvcnQgb24gdGhlIGxvY2FsIG1hY2hpbmUuCgolcyAtZwogICAgUG9wIHVwIGEgZ3JhcGhpY2FsIGludGVyZmFjZSBmb3IgZmluZGluZyBhbmQgc2VydmluZyBkb2N1bWVudGF0aW9uLgoKJXMgLXcgPG5hbWU+IC4uLgogICAgV3JpdGUgb3V0IHRoZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudAogICAgZGlyZWN0b3J5LiAgSWYgPG5hbWU+IGNvbnRhaW5zIGEgJyVzJywgaXQgaXMgdHJlYXRlZCBhcyBhIGZpbGVuYW1lOyBpZgogICAgaXQgbmFtZXMgYSBkaXJlY3RvcnksIGRvY3VtZW50YXRpb24gaXMgd3JpdHRlbiBmb3IgYWxsIHRoZSBjb250ZW50cy4KIiIiICUgKGNtZCwgb3Muc2VwLCBjbWQsIGNtZCwgY21kLCBjbWQsIG9zLnNlcCkKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6IGNsaSgpCg==