IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogTGF0aW4tMSAtKi0KIiIiR2VuZXJhdGUgUHl0aG9uIGRvY3VtZW50YXRpb24gaW4gSFRNTCBvciB0ZXh0IGZvciBpbnRlcmFjdGl2ZSB1c2UuCgpJbiB0aGUgUHl0aG9uIGludGVycHJldGVyLCBkbyAiZnJvbSBweWRvYyBpbXBvcnQgaGVscCIgdG8gcHJvdmlkZSBvbmxpbmUKaGVscC4gIENhbGxpbmcgaGVscCh0aGluZykgb24gYSBQeXRob24gb2JqZWN0IGRvY3VtZW50cyB0aGUgb2JqZWN0LgoKT3IsIGF0IHRoZSBzaGVsbCBjb21tYW5kIGxpbmUgb3V0c2lkZSBvZiBQeXRob246CgpSdW4gInB5ZG9jIDxuYW1lPiIgdG8gc2hvdyBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4gIDxuYW1lPiBtYXkgYmUKdGhlIG5hbWUgb2YgYSBmdW5jdGlvbiwgbW9kdWxlLCBwYWNrYWdlLCBvciBhIGRvdHRlZCByZWZlcmVuY2UgdG8gYQpjbGFzcyBvciBmdW5jdGlvbiB3aXRoaW4gYSBtb2R1bGUgb3IgbW9kdWxlIGluIGEgcGFja2FnZS4gIElmIHRoZQphcmd1bWVudCBjb250YWlucyBhIHBhdGggc2VnbWVudCBkZWxpbWl0ZXIgKGUuZy4gc2xhc2ggb24gVW5peCwKYmFja3NsYXNoIG9uIFdpbmRvd3MpIGl0IGlzIHRyZWF0ZWQgYXMgdGhlIHBhdGggdG8gYSBQeXRob24gc291cmNlIGZpbGUuCgpSdW4gInB5ZG9jIC1rIDxrZXl3b3JkPiIgdG8gc2VhcmNoIGZvciBhIGtleXdvcmQgaW4gdGhlIHN5bm9wc2lzIGxpbmVzCm9mIGFsbCBhdmFpbGFibGUgbW9kdWxlcy4KClJ1biAicHlkb2MgLXAgPHBvcnQ+IiB0byBzdGFydCBhbiBIVFRQIHNlcnZlciBvbiBhIGdpdmVuIHBvcnQgb24gdGhlCmxvY2FsIG1hY2hpbmUgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbiB3ZWIgcGFnZXMuCgpGb3IgcGxhdGZvcm1zIHdpdGhvdXQgYSBjb21tYW5kIGxpbmUsICJweWRvYyAtZyIgc3RhcnRzIHRoZSBIVFRQIHNlcnZlcgphbmQgYWxzbyBwb3BzIHVwIGEgbGl0dGxlIHdpbmRvdyBmb3IgY29udHJvbGxpbmcgaXQuCgpSdW4gInB5ZG9jIC13IDxuYW1lPiIgdG8gd3JpdGUgb3V0IHRoZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlCnRvIGEgZmlsZSBuYW1lZCAiPG5hbWU+Lmh0bWwiLgoiIiIKCl9fYXV0aG9yX18gPSAiS2EtUGluZyBZZWUgPHBpbmdAbGZ3Lm9yZz4iCl9fZGF0ZV9fID0gIjI2IEZlYnJ1YXJ5IDIwMDEiCl9fdmVyc2lvbl9fID0gIiRSZXZpc2lvbiQiCl9fY3JlZGl0c19fID0gIiIiR3VpZG8gdmFuIFJvc3N1bSwgZm9yIGFuIGV4Y2VsbGVudCBwcm9ncmFtbWluZyBsYW5ndWFnZS4KVG9tbXkgQnVybmV0dGUsIHRoZSBvcmlnaW5hbCBjcmVhdG9yIG9mIG1hbnB5LgpQYXVsIFByZXNjb2QsIGZvciBhbGwgaGlzIHdvcmsgb24gb25saW5laGVscC4KUmljaGFyZCBDaGFtYmVybGFpbiwgZm9yIHRoZSBmaXJzdCBpbXBsZW1lbnRhdGlvbiBvZiB0ZXh0ZG9jLgoKTXluZCB5b3UsIG34+HNlIGJpdGVzIEthbiBiZSBwcmV0dHkgbmFzdGkuLi4iIiIKCiMgS25vd24gYnVncyB0aGF0IGNhbid0IGJlIGZpeGVkIGhlcmU6CiMgICAtIGltcC5sb2FkX21vZHVsZSgpIGNhbm5vdCBiZSBwcmV2ZW50ZWQgZnJvbSBjbG9iYmVyaW5nIGV4aXN0aW5nCiMgICAgIGxvYWRlZCBtb2R1bGVzLCBzbyBjYWxsaW5nIHN5bm9wc2lzKCkgb24gYSBiaW5hcnkgbW9kdWxlIGZpbGUKIyAgICAgY2hhbmdlcyB0aGUgY29udGVudHMgb2YgYW55IGV4aXN0aW5nIG1vZHVsZSB3aXRoIHRoZSBzYW1lIG5hbWUuCiMgICAtIElmIHRoZSBfX2ZpbGVfXyBhdHRyaWJ1dGUgb24gYSBtb2R1bGUgaXMgYSByZWxhdGl2ZSBwYXRoIGFuZAojICAgICB0aGUgY3VycmVudCBkaXJlY3RvcnkgaXMgY2hhbmdlZCB3aXRoIG9zLmNoZGlyKCksIGFuIGluY29ycmVjdAojICAgICBwYXRoIHdpbGwgYmUgZGlzcGxheWVkLgoKaW1wb3J0IHN5cywgaW1wLCBvcywgcmUsIHR5cGVzLCBpbnNwZWN0LCBfX2J1aWx0aW5fXwpmcm9tIHJlcHIgaW1wb3J0IFJlcHIKZnJvbSBzdHJpbmcgaW1wb3J0IGV4cGFuZHRhYnMsIGZpbmQsIGpvaW4sIGxvd2VyLCBzcGxpdCwgc3RyaXAsIHJmaW5kLCByc3RyaXAKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbW1vbiByb3V0aW5lcwoKZGVmIHBhdGhkaXJzKCk6CiAgICAiIiJDb252ZXJ0IHN5cy5wYXRoIGludG8gYSBsaXN0IG9mIGFic29sdXRlLCBleGlzdGluZywgdW5pcXVlIHBhdGhzLiIiIgogICAgZGlycyA9IFtdCiAgICBub3JtZGlycyA9IFtdCiAgICBmb3IgZGlyIGluIHN5cy5wYXRoOgogICAgICAgIGRpciA9IG9zLnBhdGguYWJzcGF0aChkaXIgb3IgJy4nKQogICAgICAgIG5vcm1kaXIgPSBvcy5wYXRoLm5vcm1jYXNlKGRpcikKICAgICAgICBpZiBub3JtZGlyIG5vdCBpbiBub3JtZGlycyBhbmQgb3MucGF0aC5pc2RpcihkaXIpOgogICAgICAgICAgICBkaXJzLmFwcGVuZChkaXIpCiAgICAgICAgICAgIG5vcm1kaXJzLmFwcGVuZChub3JtZGlyKQogICAgcmV0dXJuIGRpcnMKCmRlZiBnZXRkb2Mob2JqZWN0KToKICAgICIiIkdldCB0aGUgZG9jIHN0cmluZyBvciBjb21tZW50cyBmb3IgYW4gb2JqZWN0LiIiIgogICAgcmVzdWx0ID0gaW5zcGVjdC5nZXRkb2Mob2JqZWN0KSBvciBpbnNwZWN0LmdldGNvbW1lbnRzKG9iamVjdCkKICAgIHJldHVybiByZXN1bHQgYW5kIHJlLnN1YignXiAqXG4nLCAnJywgcnN0cmlwKHJlc3VsdCkpIG9yICcnCgpkZWYgc3BsaXRkb2MoZG9jKToKICAgICIiIlNwbGl0IGEgZG9jIHN0cmluZyBpbnRvIGEgc3lub3BzaXMgbGluZSAoaWYgYW55KSBhbmQgdGhlIHJlc3QuIiIiCiAgICBsaW5lcyA9IHNwbGl0KHN0cmlwKGRvYyksICdcbicpCiAgICBpZiBsZW4obGluZXMpID09IDE6CiAgICAgICAgcmV0dXJuIGxpbmVzWzBdLCAnJwogICAgZWxpZiBsZW4obGluZXMpID49IDIgYW5kIG5vdCByc3RyaXAobGluZXNbMV0pOgogICAgICAgIHJldHVybiBsaW5lc1swXSwgam9pbihsaW5lc1syOl0sICdcbicpCiAgICByZXR1cm4gJycsIGpvaW4obGluZXMsICdcbicpCgpkZWYgY2xhc3NuYW1lKG9iamVjdCwgbW9kbmFtZSk6CiAgICAiIiJHZXQgYSBjbGFzcyBuYW1lIGFuZCBxdWFsaWZ5IGl0IHdpdGggYSBtb2R1bGUgbmFtZSBpZiBuZWNlc3NhcnkuIiIiCiAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fCiAgICBpZiBvYmplY3QuX19tb2R1bGVfXyAhPSBtb2RuYW1lOgogICAgICAgIG5hbWUgPSBvYmplY3QuX19tb2R1bGVfXyArICcuJyArIG5hbWUKICAgIHJldHVybiBuYW1lCgpkZWYgaXNkYXRhKG9iamVjdCk6CiAgICAiIiJDaGVjayBpZiBhbiBvYmplY3QgaXMgb2YgYSB0eXBlIHRoYXQgcHJvYmFibHkgbWVhbnMgaXQncyBkYXRhLiIiIgogICAgcmV0dXJuIG5vdCAoaW5zcGVjdC5pc21vZHVsZShvYmplY3QpIG9yIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpIG9yCiAgICAgICAgICAgICAgICBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpIG9yIGluc3BlY3QuaXNmcmFtZShvYmplY3QpIG9yCiAgICAgICAgICAgICAgICBpbnNwZWN0LmlzdHJhY2ViYWNrKG9iamVjdCkgb3IgaW5zcGVjdC5pc2NvZGUob2JqZWN0KSkKCmRlZiByZXBsYWNlKHRleHQsICpwYWlycyk6CiAgICAiIiJEbyBhIHNlcmllcyBvZiBnbG9iYWwgcmVwbGFjZW1lbnRzIG9uIGEgc3RyaW5nLiIiIgogICAgd2hpbGUgcGFpcnM6CiAgICAgICAgdGV4dCA9IGpvaW4oc3BsaXQodGV4dCwgcGFpcnNbMF0pLCBwYWlyc1sxXSkKICAgICAgICBwYWlycyA9IHBhaXJzWzI6XQogICAgcmV0dXJuIHRleHQKCmRlZiBjcmFtKHRleHQsIG1heGxlbik6CiAgICAiIiJPbWl0IHBhcnQgb2YgYSBzdHJpbmcgaWYgbmVlZGVkIHRvIG1ha2UgaXQgZml0IGluIGEgbWF4aW11bSBsZW5ndGguIiIiCiAgICBpZiBsZW4odGV4dCkgPiBtYXhsZW46CiAgICAgICAgcHJlID0gbWF4KDAsIChtYXhsZW4tMykvLzIpCiAgICAgICAgcG9zdCA9IG1heCgwLCBtYXhsZW4tMy1wcmUpCiAgICAgICAgcmV0dXJuIHRleHRbOnByZV0gKyAnLi4uJyArIHRleHRbbGVuKHRleHQpLXBvc3Q6XQogICAgcmV0dXJuIHRleHQKCmRlZiBzdHJpcGlkKHRleHQpOgogICAgIiIiUmVtb3ZlIHRoZSBoZXhhZGVjaW1hbCBpZCBmcm9tIGEgUHl0aG9uIG9iamVjdCByZXByZXNlbnRhdGlvbi4iIiIKICAgICMgVGhlIGJlaGF2aW91ciBvZiAlcCBpcyBpbXBsZW1lbnRhdGlvbi1kZXBlbmRlbnQ7IHdlIGNoZWNrIHR3byBjYXNlcy4KICAgIGZvciBwYXR0ZXJuIGluIFsnIGF0IDB4WzAtOWEtZl17Nix9KD4rKSQnLCAnIGF0IFswLTlBLUZdezgsfSg+KykkJ106CiAgICAgICAgaWYgcmUuc2VhcmNoKHBhdHRlcm4sIHJlcHIoRXhjZXB0aW9uKSk6CiAgICAgICAgICAgIHJldHVybiByZS5zdWIocGF0dGVybiwgJ1xcMScsIHRleHQpCiAgICByZXR1cm4gdGV4dAoKZGVmIF9pc19zb21lX21ldGhvZChvYmplY3QpOgogICAgcmV0dXJuIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KSBvciBpbnNwZWN0LmlzbWV0aG9kZGVzY3JpcHRvcihvYmplY3QpCgpkZWYgYWxsbWV0aG9kcyhjbCk6CiAgICBtZXRob2RzID0ge30KICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhjbCwgX2lzX3NvbWVfbWV0aG9kKToKICAgICAgICBtZXRob2RzW2tleV0gPSAxCiAgICBmb3IgYmFzZSBpbiBjbC5fX2Jhc2VzX186CiAgICAgICAgbWV0aG9kcy51cGRhdGUoYWxsbWV0aG9kcyhiYXNlKSkgIyBhbGwgeW91ciBiYXNlIGFyZSBiZWxvbmcgdG8gdXMKICAgIGZvciBrZXkgaW4gbWV0aG9kcy5rZXlzKCk6CiAgICAgICAgbWV0aG9kc1trZXldID0gZ2V0YXR0cihjbCwga2V5KQogICAgcmV0dXJuIG1ldGhvZHMKCmRlZiBfc3BsaXRfbGlzdChzLCBwcmVkaWNhdGUpOgogICAgIiIiU3BsaXQgc2VxdWVuY2UgcyB2aWEgcHJlZGljYXRlLCBhbmQgcmV0dXJuIHBhaXIgKFt0cnVlXSwgW2ZhbHNlXSkuCgogICAgVGhlIHJldHVybiB2YWx1ZSBpcyBhIDItdHVwbGUgb2YgbGlzdHMsCiAgICAgICAgKFt4IGZvciB4IGluIHMgaWYgcHJlZGljYXRlKHgpXSwKICAgICAgICAgW3ggZm9yIHggaW4gcyBpZiBub3QgcHJlZGljYXRlKHgpXSkKICAgICIiIgoKICAgIHllcyA9IFtdCiAgICBubyA9IFtdCiAgICBmb3IgeCBpbiBzOgogICAgICAgIGlmIHByZWRpY2F0ZSh4KToKICAgICAgICAgICAgeWVzLmFwcGVuZCh4KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG5vLmFwcGVuZCh4KQogICAgcmV0dXJuIHllcywgbm8KCmRlZiB2aXNpYmxlbmFtZShuYW1lKToKICAgICIiIkRlY2lkZSB3aGV0aGVyIHRvIHNob3cgZG9jdW1lbnRhdGlvbiBvbiBhIHZhcmlhYmxlLiIiIgogICAgIyBDZXJ0YWluIHNwZWNpYWwgbmFtZXMgYXJlIHJlZHVuZGFudC4KICAgIGlmIG5hbWUgaW4gWydfX2J1aWx0aW5zX18nLCAnX19kb2NfXycsICdfX2ZpbGVfXycsICdfX3BhdGhfXycsCiAgICAgICAgICAgICAgICAnX19tb2R1bGVfXycsICdfX25hbWVfXyddOiByZXR1cm4gMAogICAgIyBQcml2YXRlIG5hbWVzIGFyZSBoaWRkZW4sIGJ1dCBzcGVjaWFsIG5hbWVzIGFyZSBkaXNwbGF5ZWQuCiAgICBpZiBuYW1lLnN0YXJ0c3dpdGgoJ19fJykgYW5kIG5hbWUuZW5kc3dpdGgoJ19fJyk6IHJldHVybiAxCiAgICByZXR1cm4gbm90IG5hbWUuc3RhcnRzd2l0aCgnXycpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIG1vZHVsZSBtYW5pcHVsYXRpb24KCmRlZiBpc3BhY2thZ2UocGF0aCk6CiAgICAiIiJHdWVzcyB3aGV0aGVyIGEgcGF0aCByZWZlcnMgdG8gYSBwYWNrYWdlIGRpcmVjdG9yeS4iIiIKICAgIGlmIG9zLnBhdGguaXNkaXIocGF0aCk6CiAgICAgICAgZm9yIGV4dCBpbiBbJy5weScsICcucHljJywgJy5weW8nXToKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUob3MucGF0aC5qb2luKHBhdGgsICdfX2luaXRfXycgKyBleHQpKToKICAgICAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICByZXR1cm4gRmFsc2UKCmRlZiBzeW5vcHNpcyhmaWxlbmFtZSwgY2FjaGU9e30pOgogICAgIiIiR2V0IHRoZSBvbmUtbGluZSBzdW1tYXJ5IG91dCBvZiBhIG1vZHVsZSBmaWxlLiIiIgogICAgbXRpbWUgPSBvcy5zdGF0KGZpbGVuYW1lKS5zdF9tdGltZQogICAgbGFzdHVwZGF0ZSwgcmVzdWx0ID0gY2FjaGUuZ2V0KGZpbGVuYW1lLCAoMCwgTm9uZSkpCiAgICBpZiBsYXN0dXBkYXRlIDwgbXRpbWU6CiAgICAgICAgaW5mbyA9IGluc3BlY3QuZ2V0bW9kdWxlaW5mbyhmaWxlbmFtZSkKICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBpZiBpbmZvIGFuZCAnYicgaW4gaW5mb1syXTogIyBiaW5hcnkgbW9kdWxlcyBoYXZlIHRvIGJlIGltcG9ydGVkCiAgICAgICAgICAgIHRyeTogbW9kdWxlID0gaW1wLmxvYWRfbW9kdWxlKCdfX3RlbXBfXycsIGZpbGUsIGZpbGVuYW1lLCBpbmZvWzE6XSkKICAgICAgICAgICAgZXhjZXB0OiByZXR1cm4gTm9uZQogICAgICAgICAgICByZXN1bHQgPSBzcGxpdChtb2R1bGUuX19kb2NfXyBvciAnJywgJ1xuJylbMF0KICAgICAgICAgICAgZGVsIHN5cy5tb2R1bGVzWydfX3RlbXBfXyddCiAgICAgICAgZWxzZTogIyB0ZXh0IG1vZHVsZXMgY2FuIGJlIGRpcmVjdGx5IGV4YW1pbmVkCiAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgd2hpbGUgbGluZVs6MV0gPT0gJyMnIG9yIG5vdCBzdHJpcChsaW5lKToKICAgICAgICAgICAgICAgIGxpbmUgPSBmaWxlLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICBsaW5lID0gc3RyaXAobGluZSkKICAgICAgICAgICAgaWYgbGluZVs6NF0gPT0gJ3IiIiInOiBsaW5lID0gbGluZVsxOl0KICAgICAgICAgICAgaWYgbGluZVs6M10gPT0gJyIiIic6CiAgICAgICAgICAgICAgICBsaW5lID0gbGluZVszOl0KICAgICAgICAgICAgICAgIGlmIGxpbmVbLTE6XSA9PSAnXFwnOiBsaW5lID0gbGluZVs6LTFdCiAgICAgICAgICAgICAgICB3aGlsZSBub3Qgc3RyaXAobGluZSk6CiAgICAgICAgICAgICAgICAgICAgbGluZSA9IGZpbGUucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOiBicmVhawogICAgICAgICAgICAgICAgcmVzdWx0ID0gc3RyaXAoc3BsaXQobGluZSwgJyIiIicpWzBdKQogICAgICAgICAgICBlbHNlOiByZXN1bHQgPSBOb25lCiAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgY2FjaGVbZmlsZW5hbWVdID0gKG10aW1lLCByZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0CgpjbGFzcyBFcnJvckR1cmluZ0ltcG9ydChFeGNlcHRpb24pOgogICAgIiIiRXJyb3JzIHRoYXQgb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGltcG9ydCBzb21ldGhpbmcgdG8gZG9jdW1lbnQgaXQuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgZmlsZW5hbWUsIChleGMsIHZhbHVlLCB0YikpOgogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuZXhjID0gZXhjCiAgICAgICAgc2VsZi52YWx1ZSA9IHZhbHVlCiAgICAgICAgc2VsZi50YiA9IHRiCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgZXhjID0gc2VsZi5leGMKICAgICAgICBpZiB0eXBlKGV4YykgaXMgdHlwZXMuQ2xhc3NUeXBlOgogICAgICAgICAgICBleGMgPSBleGMuX19uYW1lX18KICAgICAgICByZXR1cm4gJ3Byb2JsZW0gaW4gJXMgLSAlczogJXMnICUgKHNlbGYuZmlsZW5hbWUsIGV4Yywgc2VsZi52YWx1ZSkKCmRlZiBpbXBvcnRmaWxlKHBhdGgpOgogICAgIiIiSW1wb3J0IGEgUHl0aG9uIHNvdXJjZSBmaWxlIG9yIGNvbXBpbGVkIGZpbGUgZ2l2ZW4gaXRzIHBhdGguIiIiCiAgICBtYWdpYyA9IGltcC5nZXRfbWFnaWMoKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgaWYgZmlsZS5yZWFkKGxlbihtYWdpYykpID09IG1hZ2ljOgogICAgICAgIGtpbmQgPSBpbXAuUFlfQ09NUElMRUQKICAgIGVsc2U6CiAgICAgICAga2luZCA9IGltcC5QWV9TT1VSQ0UKICAgIGZpbGUuY2xvc2UoKQogICAgZmlsZW5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCiAgICBuYW1lLCBleHQgPSBvcy5wYXRoLnNwbGl0ZXh0KGZpbGVuYW1lKQogICAgZmlsZSA9IG9wZW4ocGF0aCwgJ3InKQogICAgdHJ5OgogICAgICAgIG1vZHVsZSA9IGltcC5sb2FkX21vZHVsZShuYW1lLCBmaWxlLCBwYXRoLCAoZXh0LCAncicsIGtpbmQpKQogICAgZXhjZXB0OgogICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHBhdGgsIHN5cy5leGNfaW5mbygpKQogICAgZmlsZS5jbG9zZSgpCiAgICByZXR1cm4gbW9kdWxlCgpkZWYgc2FmZWltcG9ydChwYXRoLCBmb3JjZWxvYWQ9MCwgY2FjaGU9e30pOgogICAgIiIiSW1wb3J0IGEgbW9kdWxlOyBoYW5kbGUgZXJyb3JzOyByZXR1cm4gTm9uZSBpZiB0aGUgbW9kdWxlIGlzbid0IGZvdW5kLgoKICAgIElmIHRoZSBtb2R1bGUgKmlzKiBmb3VuZCBidXQgYW4gZXhjZXB0aW9uIG9jY3VycywgaXQncyB3cmFwcGVkIGluIGFuCiAgICBFcnJvckR1cmluZ0ltcG9ydCBleGNlcHRpb24gYW5kIHJlcmFpc2VkLiAgVW5saWtlIF9faW1wb3J0X18sIGlmIGEKICAgIHBhY2thZ2UgcGF0aCBpcyBzcGVjaWZpZWQsIHRoZSBtb2R1bGUgYXQgdGhlIGVuZCBvZiB0aGUgcGF0aCBpcyByZXR1cm5lZCwKICAgIG5vdCB0aGUgcGFja2FnZSBhdCB0aGUgYmVnaW5uaW5nLiAgSWYgdGhlIG9wdGlvbmFsICdmb3JjZWxvYWQnIGFyZ3VtZW50CiAgICBpcyAxLCB3ZSByZWxvYWQgdGhlIG1vZHVsZSBmcm9tIGRpc2sgKHVubGVzcyBpdCdzIGEgZHluYW1pYyBleHRlbnNpb24pLiIiIgogICAgaWYgZm9yY2Vsb2FkIGFuZCBwYXRoIGluIHN5cy5tb2R1bGVzOgogICAgICAgICMgVGhpcyBpcyB0aGUgb25seSB3YXkgdG8gYmUgc3VyZS4gIENoZWNraW5nIHRoZSBtdGltZSBvZiB0aGUgZmlsZQogICAgICAgICMgaXNuJ3QgZ29vZCBlbm91Z2ggKGUuZy4gd2hhdCBpZiB0aGUgbW9kdWxlIGNvbnRhaW5zIGEgY2xhc3MgdGhhdAogICAgICAgICMgaW5oZXJpdHMgZnJvbSBhbm90aGVyIG1vZHVsZSB0aGF0IGhhcyBjaGFuZ2VkPykuCiAgICAgICAgaWYgcGF0aCBub3QgaW4gc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzOgogICAgICAgICAgICAjIFB5dGhvbiBuZXZlciBsb2FkcyBhIGR5bmFtaWMgZXh0ZW5zaW9uIGEgc2Vjb25kIHRpbWUgZnJvbSB0aGUKICAgICAgICAgICAgIyBzYW1lIHBhdGgsIGV2ZW4gaWYgdGhlIGZpbGUgaXMgY2hhbmdlZCBvciBtaXNzaW5nLiAgRGVsZXRpbmcKICAgICAgICAgICAgIyB0aGUgZW50cnkgaW4gc3lzLm1vZHVsZXMgZG9lc24ndCBoZWxwIGZvciBkeW5hbWljIGV4dGVuc2lvbnMsCiAgICAgICAgICAgICMgc28gd2UncmUgbm90IGV2ZW4gZ29pbmcgdG8gdHJ5IHRvIGtlZXAgdGhlbSB1cCB0byBkYXRlLgogICAgICAgICAgICBpbmZvID0gaW5zcGVjdC5nZXRtb2R1bGVpbmZvKHN5cy5tb2R1bGVzW3BhdGhdLl9fZmlsZV9fKQogICAgICAgICAgICBpZiBpbmZvWzNdICE9IGltcC5DX0VYVEVOU0lPTjoKICAgICAgICAgICAgICAgIGNhY2hlW3BhdGhdID0gc3lzLm1vZHVsZXNbcGF0aF0gIyBwcmV2ZW50IG1vZHVsZSBmcm9tIGNsZWFyaW5nCiAgICAgICAgICAgICAgICBkZWwgc3lzLm1vZHVsZXNbcGF0aF0KICAgIHRyeToKICAgICAgICBtb2R1bGUgPSBfX2ltcG9ydF9fKHBhdGgpCiAgICBleGNlcHQ6CiAgICAgICAgIyBEaWQgdGhlIGVycm9yIG9jY3VyIGJlZm9yZSBvciBhZnRlciB0aGUgbW9kdWxlIHdhcyBmb3VuZD8KICAgICAgICAoZXhjLCB2YWx1ZSwgdGIpID0gaW5mbyA9IHN5cy5leGNfaW5mbygpCiAgICAgICAgaWYgcGF0aCBpbiBzeXMubW9kdWxlczoKICAgICAgICAgICAgIyBBbiBlcnJvciBvY2N1cmVkIHdoaWxlIGV4ZWN1dGluZyB0aGUgaW1wb3J0ZWQgbW9kdWxlLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChzeXMubW9kdWxlc1twYXRoXS5fX2ZpbGVfXywgaW5mbykKICAgICAgICBlbGlmIGV4YyBpcyBTeW50YXhFcnJvcjoKICAgICAgICAgICAgIyBBIFN5bnRheEVycm9yIG9jY3VycmVkIGJlZm9yZSB3ZSBjb3VsZCBleGVjdXRlIHRoZSBtb2R1bGUuCiAgICAgICAgICAgIHJhaXNlIEVycm9yRHVyaW5nSW1wb3J0KHZhbHVlLmZpbGVuYW1lLCBpbmZvKQogICAgICAgIGVsaWYgZXhjIGlzIEltcG9ydEVycm9yIGFuZCBcCiAgICAgICAgICAgICBzcGxpdChsb3dlcihzdHIodmFsdWUpKSlbOjJdID09IFsnbm8nLCAnbW9kdWxlJ106CiAgICAgICAgICAgICMgVGhlIG1vZHVsZSB3YXMgbm90IGZvdW5kLgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgU29tZSBvdGhlciBlcnJvciBvY2N1cnJlZCBkdXJpbmcgdGhlIGltcG9ydGluZyBwcm9jZXNzLgogICAgICAgICAgICByYWlzZSBFcnJvckR1cmluZ0ltcG9ydChwYXRoLCBzeXMuZXhjX2luZm8oKSkKICAgIGZvciBwYXJ0IGluIHNwbGl0KHBhdGgsICcuJylbMTpdOgogICAgICAgIHRyeTogbW9kdWxlID0gZ2V0YXR0cihtb2R1bGUsIHBhcnQpCiAgICAgICAgZXhjZXB0IEF0dHJpYnV0ZUVycm9yOiByZXR1cm4gTm9uZQogICAgcmV0dXJuIG1vZHVsZQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvcm1hdHRlciBiYXNlIGNsYXNzCgpjbGFzcyBEb2M6CiAgICBkZWYgZG9jdW1lbnQoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsICphcmdzKToKICAgICAgICAiIiJHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGZvciBhbiBvYmplY3QuIiIiCiAgICAgICAgYXJncyA9IChvYmplY3QsIG5hbWUpICsgYXJncwogICAgICAgIGlmIGluc3BlY3QuaXNtb2R1bGUob2JqZWN0KTogcmV0dXJuIHNlbGYuZG9jbW9kdWxlKCphcmdzKQogICAgICAgIGlmIGluc3BlY3QuaXNjbGFzcyhvYmplY3QpOiByZXR1cm4gc2VsZi5kb2NjbGFzcygqYXJncykKICAgICAgICBpZiBpbnNwZWN0Lmlzcm91dGluZShvYmplY3QpOiByZXR1cm4gc2VsZi5kb2Nyb3V0aW5lKCphcmdzKQogICAgICAgIHJldHVybiBzZWxmLmRvY290aGVyKCphcmdzKQoKICAgIGRlZiBmYWlsKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCAqYXJncyk6CiAgICAgICAgIiIiUmFpc2UgYW4gZXhjZXB0aW9uIGZvciB1bmltcGxlbWVudGVkIHR5cGVzLiIiIgogICAgICAgIG1lc3NhZ2UgPSAiZG9uJ3Qga25vdyBob3cgdG8gZG9jdW1lbnQgb2JqZWN0JXMgb2YgdHlwZSAlcyIgJSAoCiAgICAgICAgICAgIG5hbWUgYW5kICcgJyArIHJlcHIobmFtZSksIHR5cGUob2JqZWN0KS5fX25hbWVfXykKICAgICAgICByYWlzZSBUeXBlRXJyb3IsIG1lc3NhZ2UKCiAgICBkb2Ntb2R1bGUgPSBkb2NjbGFzcyA9IGRvY3JvdXRpbmUgPSBkb2NvdGhlciA9IGZhaWwKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFRNTCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcgoKY2xhc3MgSFRNTFJlcHIoUmVwcik6CiAgICAiIiJDbGFzcyBmb3Igc2FmZWx5IG1ha2luZyBhbiBIVE1MIHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IDIwCiAgICAgICAgc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSAxMDAKCiAgICBkZWYgZXNjYXBlKHNlbGYsIHRleHQpOgogICAgICAgIHJldHVybiByZXBsYWNlKHRleHQsICcmJywgJyZhbXA7JywgJzwnLCAnJmx0OycsICc+JywgJyZndDsnKQoKICAgIGRlZiByZXByKHNlbGYsIG9iamVjdCk6CiAgICAgICAgcmV0dXJuIFJlcHIucmVwcihzZWxmLCBvYmplY3QpCgogICAgZGVmIHJlcHIxKHNlbGYsIHgsIGxldmVsKToKICAgICAgICBtZXRob2RuYW1lID0gJ3JlcHJfJyArIGpvaW4oc3BsaXQodHlwZSh4KS5fX25hbWVfXyksICdfJykKICAgICAgICBpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSh4LCBsZXZlbCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heG90aGVyKSkKCiAgICBkZWYgcmVwcl9zdHJpbmcoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIHRlc3QgPSBjcmFtKHgsIHNlbGYubWF4c3RyaW5nKQogICAgICAgIHRlc3RyZXByID0gcmVwcih0ZXN0KQogICAgICAgIGlmICdcXCcgaW4gdGVzdCBhbmQgJ1xcJyBub3QgaW4gcmVwbGFjZSh0ZXN0cmVwciwgcidcXCcsICcnKToKICAgICAgICAgICAgIyBCYWNrc2xhc2hlcyBhcmUgb25seSBsaXRlcmFsIGluIHRoZSBzdHJpbmcgYW5kIGFyZSBuZXZlcgogICAgICAgICAgICAjIG5lZWRlZCB0byBtYWtlIGFueSBzcGVjaWFsIGNoYXJhY3RlcnMsIHNvIHNob3cgYSByYXcgc3RyaW5nLgogICAgICAgICAgICByZXR1cm4gJ3InICsgdGVzdHJlcHJbMF0gKyBzZWxmLmVzY2FwZSh0ZXN0KSArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHJlLnN1YihyJygoXFxbXFxhYmZucnR2XCciXXxcXFswLTldLi58XFx4Li58XFx1Li4uLikrKScsCiAgICAgICAgICAgICAgICAgICAgICByJzxmb250IGNvbG9yPSIjYzA0MGMwIj5cMTwvZm9udD4nLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi5lc2NhcGUodGVzdHJlcHIpKQoKICAgIHJlcHJfc3RyID0gcmVwcl9zdHJpbmcKCiAgICBkZWYgcmVwcl9pbnN0YW5jZShzZWxmLCB4LCBsZXZlbCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoY3JhbShzdHJpcGlkKHJlcHIoeCkpLCBzZWxmLm1heHN0cmluZykpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICByZXR1cm4gc2VsZi5lc2NhcGUoJzwlcyBpbnN0YW5jZT4nICUgeC5fX2NsYXNzX18uX19uYW1lX18pCgogICAgcmVwcl91bmljb2RlID0gcmVwcl9zdHJpbmcKCmNsYXNzIEhUTUxEb2MoRG9jKToKICAgICIiIkZvcm1hdHRlciBjbGFzcyBmb3IgSFRNTCBkb2N1bWVudGF0aW9uLiIiIgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVE1MIGZvcm1hdHRpbmcgdXRpbGl0aWVzCgogICAgX3JlcHJfaW5zdGFuY2UgPSBIVE1MUmVwcigpCiAgICByZXByID0gX3JlcHJfaW5zdGFuY2UucmVwcgogICAgZXNjYXBlID0gX3JlcHJfaW5zdGFuY2UuZXNjYXBlCgogICAgZGVmIHBhZ2Uoc2VsZiwgdGl0bGUsIGNvbnRlbnRzKToKICAgICAgICAiIiJGb3JtYXQgYW4gSFRNTCBwYWdlLiIiIgogICAgICAgIHJldHVybiAnJycKPCFkb2N0eXBlIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwvL0VOIj4KPGh0bWw+PGhlYWQ+PHRpdGxlPlB5dGhvbjogJXM8L3RpdGxlPgo8L2hlYWQ+PGJvZHkgYmdjb2xvcj0iI2YwZjBmOCI+CiVzCjwvYm9keT48L2h0bWw+JycnICUgKHRpdGxlLCBjb250ZW50cykKCiAgICBkZWYgaGVhZGluZyhzZWxmLCB0aXRsZSwgZmdjb2wsIGJnY29sLCBleHRyYXM9JycpOgogICAgICAgICIiIkZvcm1hdCBhIHBhZ2UgaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gJycnCjx0YWJsZSB3aWR0aD0iMTAwJSUiIGNlbGxzcGFjaW5nPTAgY2VsbHBhZGRpbmc9MiBib3JkZXI9MCBzdW1tYXJ5PSJoZWFkaW5nIj4KPHRyIGJnY29sb3I9IiVzIj4KPHRkIHZhbGlnbj1ib3R0b20+Jm5ic3A7PGJyPgo8Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiZuYnNwOzxicj4lczwvZm9udD48L3RkCj48dGQgYWxpZ249cmlnaHQgdmFsaWduPWJvdHRvbQo+PGZvbnQgY29sb3I9IiVzIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj4lczwvZm9udD48L3RkPjwvdHI+PC90YWJsZT4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlLCBmZ2NvbCwgZXh0cmFzIG9yICcmbmJzcDsnKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBmZ2NvbCwgYmdjb2wsIGNvbnRlbnRzLCB3aWR0aD02LAogICAgICAgICAgICAgICAgcHJlbHVkZT0nJywgbWFyZ2luYWxpYT1Ob25lLCBnYXA9JyZuYnNwOycpOgogICAgICAgICIiIkZvcm1hdCBhIHNlY3Rpb24gd2l0aCBhIGhlYWRpbmcuIiIiCiAgICAgICAgaWYgbWFyZ2luYWxpYSBpcyBOb25lOgogICAgICAgICAgICBtYXJnaW5hbGlhID0gJzx0dD4nICsgJyZuYnNwOycgKiB3aWR0aCArICc8L3R0PicKICAgICAgICByZXN1bHQgPSAnJyc8cD4KPHRhYmxlIHdpZHRoPSIxMDAlJSIgY2VsbHNwYWNpbmc9MCBjZWxscGFkZGluZz0yIGJvcmRlcj0wIHN1bW1hcnk9InNlY3Rpb24iPgo8dHIgYmdjb2xvcj0iJXMiPgo8dGQgY29sc3Bhbj0zIHZhbGlnbj1ib3R0b20+Jm5ic3A7PGJyPgo8Zm9udCBjb2xvcj0iJXMiIGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PjwvdGQ+PC90cj4KICAgICcnJyAlIChiZ2NvbCwgZmdjb2wsIHRpdGxlKQogICAgICAgIGlmIHByZWx1ZGU6CiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcnJwo8dHIgYmdjb2xvcj0iJXMiPjx0ZCByb3dzcGFuPTI+JXM8L3RkPgo8dGQgY29sc3Bhbj0yPiVzPC90ZD48L3RyPgo8dHI+PHRkPiVzPC90ZD4nJycgJSAoYmdjb2wsIG1hcmdpbmFsaWEsIHByZWx1ZGUsIGdhcCkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyAnJycKPHRyPjx0ZCBiZ2NvbG9yPSIlcyI+JXM8L3RkPjx0ZD4lczwvdGQ+JycnICUgKGJnY29sLCBtYXJnaW5hbGlhLCBnYXApCgogICAgICAgIHJldHVybiByZXN1bHQgKyAnXG48dGQgd2lkdGg9IjEwMCUlIj4lczwvdGQ+PC90cj48L3RhYmxlPicgJSBjb250ZW50cwoKICAgIGRlZiBiaWdzZWN0aW9uKHNlbGYsIHRpdGxlLCAqYXJncyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgYmlnIGhlYWRpbmcuIiIiCiAgICAgICAgdGl0bGUgPSAnPGJpZz48c3Ryb25nPiVzPC9zdHJvbmc+PC9iaWc+JyAlIHRpdGxlCiAgICAgICAgcmV0dXJuIHNlbGYuc2VjdGlvbih0aXRsZSwgKmFyZ3MpCgogICAgZGVmIHByZWZvcm1hdChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgbGl0ZXJhbCBwcmVmb3JtYXR0ZWQgdGV4dC4iIiIKICAgICAgICB0ZXh0ID0gc2VsZi5lc2NhcGUoZXhwYW5kdGFicyh0ZXh0KSkKICAgICAgICByZXR1cm4gcmVwbGFjZSh0ZXh0LCAnXG5cbicsICdcbiBcbicsICdcblxuJywgJ1xuIFxuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnICcsICcmbmJzcDsnLCAnXG4nLCAnPGJyPlxuJykKCiAgICBkZWYgbXVsdGljb2x1bW4oc2VsZiwgbGlzdCwgZm9ybWF0LCBjb2xzPTQpOgogICAgICAgICIiIkZvcm1hdCBhIGxpc3Qgb2YgaXRlbXMgaW50byBhIG11bHRpLWNvbHVtbiBsaXN0LiIiIgogICAgICAgIHJlc3VsdCA9ICcnCiAgICAgICAgcm93cyA9IChsZW4obGlzdCkrY29scy0xKS9jb2xzCiAgICAgICAgZm9yIGNvbCBpbiByYW5nZShjb2xzKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgJzx0ZCB3aWR0aD0iJWQlJSIgdmFsaWduPXRvcD4nICUgKDEwMC9jb2xzKQogICAgICAgICAgICBmb3IgaSBpbiByYW5nZShyb3dzKmNvbCwgcm93cypjb2wrcm93cyk6CiAgICAgICAgICAgICAgICBpZiBpIDwgbGVuKGxpc3QpOgogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIGZvcm1hdChsaXN0W2ldKSArICc8YnI+XG4nCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8L3RkPicKICAgICAgICByZXR1cm4gJzx0YWJsZSB3aWR0aD0iMTAwJSUiIHN1bW1hcnk9Imxpc3QiPjx0cj4lczwvdHI+PC90YWJsZT4nICUgcmVzdWx0CgogICAgZGVmIGdyZXkoc2VsZiwgdGV4dCk6IHJldHVybiAnPGZvbnQgY29sb3I9IiM5MDkwOTAiPiVzPC9mb250PicgJSB0ZXh0CgogICAgZGVmIG5hbWVsaW5rKHNlbGYsIG5hbWUsICpkaWN0cyk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGFuIGlkZW50aWZpZXIsIGdpdmVuIG5hbWUtdG8tVVJMIG1hcHBpbmdzLiIiIgogICAgICAgIGZvciBkaWN0IGluIGRpY3RzOgogICAgICAgICAgICBpZiBuYW1lIGluIGRpY3Q6CiAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKGRpY3RbbmFtZV0sIG5hbWUpCiAgICAgICAgcmV0dXJuIG5hbWUKCiAgICBkZWYgY2xhc3NsaW5rKHNlbGYsIG9iamVjdCwgbW9kbmFtZSk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgY2xhc3MuIiIiCiAgICAgICAgbmFtZSwgbW9kdWxlID0gb2JqZWN0Ll9fbmFtZV9fLCBzeXMubW9kdWxlcy5nZXQob2JqZWN0Ll9fbW9kdWxlX18pCiAgICAgICAgaWYgaGFzYXR0cihtb2R1bGUsIG5hbWUpIGFuZCBnZXRhdHRyKG1vZHVsZSwgbmFtZSkgaXMgb2JqZWN0OgogICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IiVzLmh0bWwjJXMiPiVzPC9hPicgJSAoCiAgICAgICAgICAgICAgICBtb2R1bGUuX19uYW1lX18sIG5hbWUsIGNsYXNzbmFtZShvYmplY3QsIG1vZG5hbWUpKQogICAgICAgIHJldHVybiBjbGFzc25hbWUob2JqZWN0LCBtb2RuYW1lKQoKICAgIGRlZiBtb2R1bGVsaW5rKHNlbGYsIG9iamVjdCk6CiAgICAgICAgIiIiTWFrZSBhIGxpbmsgZm9yIGEgbW9kdWxlLiIiIgogICAgICAgIHJldHVybiAnPGEgaHJlZj0iJXMuaHRtbCI+JXM8L2E+JyAlIChvYmplY3QuX19uYW1lX18sIG9iamVjdC5fX25hbWVfXykKCiAgICBkZWYgbW9kcGtnbGluayhzZWxmLCAobmFtZSwgcGF0aCwgaXNwYWNrYWdlLCBzaGFkb3dlZCkpOgogICAgICAgICIiIk1ha2UgYSBsaW5rIGZvciBhIG1vZHVsZSBvciBwYWNrYWdlIHRvIGRpc3BsYXkgaW4gYW4gaW5kZXguIiIiCiAgICAgICAgaWYgc2hhZG93ZWQ6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmdyZXkobmFtZSkKICAgICAgICBpZiBwYXRoOgogICAgICAgICAgICB1cmwgPSAnJXMuJXMuaHRtbCcgJSAocGF0aCwgbmFtZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB1cmwgPSAnJXMuaHRtbCcgJSBuYW1lCiAgICAgICAgaWYgaXNwYWNrYWdlOgogICAgICAgICAgICB0ZXh0ID0gJzxzdHJvbmc+JXM8L3N0cm9uZz4mbmJzcDsocGFja2FnZSknICUgbmFtZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRleHQgPSBuYW1lCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIHRleHQpCgogICAgZGVmIG1hcmt1cChzZWxmLCB0ZXh0LCBlc2NhcGU9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30pOgogICAgICAgICIiIk1hcmsgdXAgc29tZSBwbGFpbiB0ZXh0LCBnaXZlbiBhIGNvbnRleHQgb2Ygc3ltYm9scyB0byBsb29rIGZvci4KICAgICAgICBFYWNoIGNvbnRleHQgZGljdGlvbmFyeSBtYXBzIG9iamVjdCBuYW1lcyB0byBhbmNob3IgbmFtZXMuIiIiCiAgICAgICAgZXNjYXBlID0gZXNjYXBlIG9yIHNlbGYuZXNjYXBlCiAgICAgICAgcmVzdWx0cyA9IFtdCiAgICAgICAgaGVyZSA9IDAKICAgICAgICBwYXR0ZXJuID0gcmUuY29tcGlsZShyJ1xiKChodHRwfGZ0cCk6Ly9cUytbXHcvXXwnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcidSRkNbLSBdPyhcZCspfCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ1BFUFstIF0/KFxkKyl8JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInKHNlbGZcLik/KFx3KykpJykKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBtYXRjaCA9IHBhdHRlcm4uc2VhcmNoKHRleHQsIGhlcmUpCiAgICAgICAgICAgIGlmIG5vdCBtYXRjaDogYnJlYWsKICAgICAgICAgICAgc3RhcnQsIGVuZCA9IG1hdGNoLnNwYW4oKQogICAgICAgICAgICByZXN1bHRzLmFwcGVuZChlc2NhcGUodGV4dFtoZXJlOnN0YXJ0XSkpCgogICAgICAgICAgICBhbGwsIHNjaGVtZSwgcmZjLCBwZXAsIHNlbGZkb3QsIG5hbWUgPSBtYXRjaC5ncm91cHMoKQogICAgICAgICAgICBpZiBzY2hlbWU6CiAgICAgICAgICAgICAgICB1cmwgPSBlc2NhcGUoYWxsKS5yZXBsYWNlKCciJywgJyZxdW90OycpCiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZCgnPGEgaHJlZj0iJXMiPiVzPC9hPicgJSAodXJsLCB1cmwpKQogICAgICAgICAgICBlbGlmIHJmYzoKICAgICAgICAgICAgICAgIHVybCA9ICdodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmMlZC50eHQnICUgaW50KHJmYykKICAgICAgICAgICAgICAgIHJlc3VsdHMuYXBwZW5kKCc8YSBocmVmPSIlcyI+JXM8L2E+JyAlICh1cmwsIGVzY2FwZShhbGwpKSkKICAgICAgICAgICAgZWxpZiBwZXA6CiAgICAgICAgICAgICAgICB1cmwgPSAnaHR0cDovL3d3dy5weXRob24ub3JnL3BlcHMvcGVwLSUwNGQuaHRtbCcgJSBpbnQocGVwKQogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJzxhIGhyZWY9IiVzIj4lczwvYT4nICUgKHVybCwgZXNjYXBlKGFsbCkpKQogICAgICAgICAgICBlbGlmIHRleHRbZW5kOmVuZCsxXSA9PSAnKCc6CiAgICAgICAgICAgICAgICByZXN1bHRzLmFwcGVuZChzZWxmLm5hbWVsaW5rKG5hbWUsIG1ldGhvZHMsIGZ1bmNzLCBjbGFzc2VzKSkKICAgICAgICAgICAgZWxpZiBzZWxmZG90OgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoJ3NlbGYuPHN0cm9uZz4lczwvc3Ryb25nPicgJSBuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoc2VsZi5uYW1lbGluayhuYW1lLCBjbGFzc2VzKSkKICAgICAgICAgICAgaGVyZSA9IGVuZAogICAgICAgIHJlc3VsdHMuYXBwZW5kKGVzY2FwZSh0ZXh0W2hlcmU6XSkpCiAgICAgICAgcmV0dXJuIGpvaW4ocmVzdWx0cywgJycpCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGUtc3BlY2lmaWMgcm91dGluZXMKCiAgICBkZWYgZm9ybWF0dHJlZShzZWxmLCB0cmVlLCBtb2RuYW1lLCBwYXJlbnQ9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGZvciBhIGNsYXNzIHRyZWUgYXMgZ2l2ZW4gYnkgaW5zcGVjdC5nZXRjbGFzc3RyZWUoKS4iIiIKICAgICAgICByZXN1bHQgPSAnJwogICAgICAgIGZvciBlbnRyeSBpbiB0cmVlOgogICAgICAgICAgICBpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKCgpKToKICAgICAgICAgICAgICAgIGMsIGJhc2VzID0gZW50cnkKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZHQ+PGZvbnQgZmFjZT0iaGVsdmV0aWNhLCBhcmlhbCI+JwogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5jbGFzc2xpbmsoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IFtdCiAgICAgICAgICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMuYXBwZW5kKHNlbGYuY2xhc3NsaW5rKGJhc2UsIG1vZG5hbWUpKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJyArIGpvaW4ocGFyZW50cywgJywgJykgKyAnKScKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbjwvZm9udD48L2R0PicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8ZGQ+XG4lczwvZGQ+XG4nICUgc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2RuYW1lLCBjKQogICAgICAgIHJldHVybiAnPGRsPlxuJXM8L2RsPlxuJyAlIHJlc3VsdAoKICAgIGRlZiBkb2Ntb2R1bGUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCAqaWdub3JlZCk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fICMgaWdub3JlIHRoZSBwYXNzZWQtaW4gbmFtZQogICAgICAgIHBhcnRzID0gc3BsaXQobmFtZSwgJy4nKQogICAgICAgIGxpbmtzID0gW10KICAgICAgICBmb3IgaSBpbiByYW5nZShsZW4ocGFydHMpLTEpOgogICAgICAgICAgICBsaW5rcy5hcHBlbmQoCiAgICAgICAgICAgICAgICAnPGEgaHJlZj0iJXMuaHRtbCI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPiVzPC9mb250PjwvYT4nICUKICAgICAgICAgICAgICAgIChqb2luKHBhcnRzWzppKzFdLCAnLicpLCBwYXJ0c1tpXSkpCiAgICAgICAgbGlua2VkbmFtZSA9IGpvaW4obGlua3MgKyBwYXJ0c1stMTpdLCAnLicpCiAgICAgICAgaGVhZCA9ICc8YmlnPjxiaWc+PHN0cm9uZz4lczwvc3Ryb25nPjwvYmlnPjwvYmlnPicgJSBsaW5rZWRuYW1lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBwYXRoID0gaW5zcGVjdC5nZXRhYnNmaWxlKG9iamVjdCkKICAgICAgICAgICAgdXJsID0gcGF0aAogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgIGltcG9ydCBudHVybDJwYXRoCiAgICAgICAgICAgICAgICB1cmwgPSBudHVybDJwYXRoLnBhdGhuYW1lMnVybChwYXRoKQogICAgICAgICAgICBmaWxlbGluayA9ICc8YSBocmVmPSJmaWxlOiVzIj4lczwvYT4nICUgKHVybCwgcGF0aCkKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICBmaWxlbGluayA9ICcoYnVpbHQtaW4pJwogICAgICAgIGluZm8gPSBbXQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIGluZm8uYXBwZW5kKCd2ZXJzaW9uICVzJyAlIHNlbGYuZXNjYXBlKHZlcnNpb24pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19kYXRlX18nKToKICAgICAgICAgICAgaW5mby5hcHBlbmQoc2VsZi5lc2NhcGUoc3RyKG9iamVjdC5fX2RhdGVfXykpKQogICAgICAgIGlmIGluZm86CiAgICAgICAgICAgIGhlYWQgPSBoZWFkICsgJyAoJXMpJyAlIGpvaW4oaW5mbywgJywgJykKICAgICAgICByZXN1bHQgPSBzZWxmLmhlYWRpbmcoCiAgICAgICAgICAgIGhlYWQsICcjZmZmZmZmJywgJyM3Nzk5ZWUnLCAnPGEgaHJlZj0iLiI+aW5kZXg8L2E+PGJyPicgKyBmaWxlbGluaykKCiAgICAgICAgbW9kdWxlcyA9IGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNtb2R1bGUpCgogICAgICAgIGNsYXNzZXMsIGNkaWN0ID0gW10sIHt9CiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc2NsYXNzKToKICAgICAgICAgICAgaWYgKGluc3BlY3QuZ2V0bW9kdWxlKHZhbHVlKSBvciBvYmplY3QpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGlmIHZpc2libGVuYW1lKGtleSk6CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgICAgICAgICAgICAgIGNkaWN0W2tleV0gPSBjZGljdFt2YWx1ZV0gPSAnIycgKyBrZXkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBjbGFzc2VzOgogICAgICAgICAgICBmb3IgYmFzZSBpbiB2YWx1ZS5fX2Jhc2VzX186CiAgICAgICAgICAgICAgICBrZXksIG1vZG5hbWUgPSBiYXNlLl9fbmFtZV9fLCBiYXNlLl9fbW9kdWxlX18KICAgICAgICAgICAgICAgIG1vZHVsZSA9IHN5cy5tb2R1bGVzLmdldChtb2RuYW1lKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSBuYW1lIGFuZCBtb2R1bGUgYW5kIGhhc2F0dHIobW9kdWxlLCBrZXkpOgogICAgICAgICAgICAgICAgICAgIGlmIGdldGF0dHIobW9kdWxlLCBrZXkpIGlzIGJhc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBrZXkgaW4gY2RpY3Q6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZGljdFtrZXldID0gY2RpY3RbYmFzZV0gPSBtb2RuYW1lICsgJy5odG1sIycgKyBrZXkKICAgICAgICBmdW5jcywgZmRpY3QgPSBbXSwge30KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpbnNwZWN0Lmlzcm91dGluZSk6CiAgICAgICAgICAgIGlmIGluc3BlY3QuaXNidWlsdGluKHZhbHVlKSBvciBpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgaWYgdmlzaWJsZW5hbWUoa2V5KToKICAgICAgICAgICAgICAgICAgICBmdW5jcy5hcHBlbmQoKGtleSwgdmFsdWUpKQogICAgICAgICAgICAgICAgICAgIGZkaWN0W2tleV0gPSAnIy0nICsga2V5CiAgICAgICAgICAgICAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKHZhbHVlKTogZmRpY3RbdmFsdWVdID0gZmRpY3Rba2V5XQogICAgICAgIGRhdGEgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGlzZGF0YSk6CiAgICAgICAgICAgIGlmIHZpc2libGVuYW1lKGtleSk6CiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgoa2V5LCB2YWx1ZSkpCgogICAgICAgIGRvYyA9IHNlbGYubWFya3VwKGdldGRvYyhvYmplY3QpLCBzZWxmLnByZWZvcm1hdCwgZmRpY3QsIGNkaWN0KQogICAgICAgIGRvYyA9IGRvYyBhbmQgJzx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICc8cD4lczwvcD5cbicgJSBkb2MKCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX3BhdGhfXycpOgogICAgICAgICAgICBtb2Rwa2dzID0gW10KICAgICAgICAgICAgbW9kbmFtZXMgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgIT0gJ19faW5pdF9fJzoKICAgICAgICAgICAgICAgICAgICBpZiBtb2RuYW1lIGFuZCBtb2RuYW1lIG5vdCBpbiBtb2RuYW1lczoKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKG1vZG5hbWUsIG5hbWUsIDAsIDApKQogICAgICAgICAgICAgICAgICAgICAgICBtb2RuYW1lcy5hcHBlbmQobW9kbmFtZSkKICAgICAgICAgICAgICAgICAgICBlbGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgICAgICAgICAgICAgbW9kcGtncy5hcHBlbmQoKGZpbGUsIG5hbWUsIDEsIDApKQogICAgICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnUGFja2FnZSBDb250ZW50cycsICcjZmZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKICAgICAgICBlbGlmIG1vZHVsZXM6CiAgICAgICAgICAgIGNvbnRlbnRzID0gc2VsZi5tdWx0aWNvbHVtbigKICAgICAgICAgICAgICAgIG1vZHVsZXMsIGxhbWJkYSAoa2V5LCB2YWx1ZSksIHM9c2VsZjogcy5tb2R1bGVsaW5rKHZhbHVlKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ01vZHVsZXMnLCAnI2ZmZmZmJywgJyNhYTU1Y2MnLCBjb250ZW50cykKCiAgICAgICAgaWYgY2xhc3NlczoKICAgICAgICAgICAgY2xhc3NsaXN0ID0gbWFwKGxhbWJkYSAoa2V5LCB2YWx1ZSk6IHZhbHVlLCBjbGFzc2VzKQogICAgICAgICAgICBjb250ZW50cyA9IFsKICAgICAgICAgICAgICAgIHNlbGYuZm9ybWF0dHJlZShpbnNwZWN0LmdldGNsYXNzdHJlZShjbGFzc2xpc3QsIDEpLCBuYW1lKV0KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gY2xhc3NlczoKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY3VtZW50KHZhbHVlLCBrZXksIG5hbWUsIGZkaWN0LCBjZGljdCkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDbGFzc2VzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGpvaW4oY29udGVudHMpKQogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbmFtZSwgZmRpY3QsIGNkaWN0KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0Z1bmN0aW9ucycsICcjZmZmZmZmJywgJyNlZWFhNzcnLCBqb2luKGNvbnRlbnRzKSkKICAgICAgICBpZiBkYXRhOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGRhdGE6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5KSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgJ0RhdGEnLCAnI2ZmZmZmZicsICcjNTVhYTU1Jywgam9pbihjb250ZW50cywgJzxicj5cbicpKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19hdXRob3JfXycpOgogICAgICAgICAgICBjb250ZW50cyA9IHNlbGYubWFya3VwKHN0cihvYmplY3QuX19hdXRob3JfXyksIHNlbGYucHJlZm9ybWF0KQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLmJpZ3NlY3Rpb24oCiAgICAgICAgICAgICAgICAnQXV0aG9yJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgY29udGVudHMgPSBzZWxmLm1hcmt1cChzdHIob2JqZWN0Ll9fY3JlZGl0c19fKSwgc2VsZi5wcmVmb3JtYXQpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuYmlnc2VjdGlvbigKICAgICAgICAgICAgICAgICdDcmVkaXRzJywgJyNmZmZmZmYnLCAnIzc3OTllZScsIGNvbnRlbnRzKQoKICAgICAgICByZXR1cm4gcmVzdWx0CgogICAgZGVmIGRvY2NsYXNzKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwgZnVuY3M9e30sIGNsYXNzZXM9e30sCiAgICAgICAgICAgICAgICAgKmlnbm9yZWQpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCgogICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICBwdXNoID0gY29udGVudHMuYXBwZW5kCgogICAgICAgICMgQ3V0ZSBsaXR0bGUgY2xhc3MgdG8gcHVtcCBvdXQgYSBob3Jpem9udGFsIHJ1bGUgYmV0d2VlbiBzZWN0aW9ucy4KICAgICAgICBjbGFzcyBIb3Jpem9udGFsUnVsZToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgICAgICAgICAgc2VsZi5uZWVkb25lID0gMAogICAgICAgICAgICBkZWYgbWF5YmUoc2VsZik6CiAgICAgICAgICAgICAgICBpZiBzZWxmLm5lZWRvbmU6CiAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGhyPlxuJykKICAgICAgICAgICAgICAgIHNlbGYubmVlZG9uZSA9IDEKICAgICAgICBociA9IEhvcml6b250YWxSdWxlKCkKCiAgICAgICAgIyBMaXN0IHRoZSBtcm8sIGlmIG5vbi10cml2aWFsLgogICAgICAgIG1ybyA9IGxpc3QoaW5zcGVjdC5nZXRtcm8ob2JqZWN0KSkKICAgICAgICBpZiBsZW4obXJvKSA+IDI6CiAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgcHVzaCgnPGRsPjxkdD5NZXRob2QgcmVzb2x1dGlvbiBvcmRlcjo8L2R0PlxuJykKICAgICAgICAgICAgZm9yIGJhc2UgaW4gbXJvOgogICAgICAgICAgICAgICAgcHVzaCgnPGRkPiVzPC9kZD5cbicgJSBzZWxmLmNsYXNzbGluayhiYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuX19tb2R1bGVfXykpCiAgICAgICAgICAgIHB1c2goJzwvZGw+XG4nKQoKICAgICAgICBkZWYgc3BpbGwobXNnLCBhdHRycywgcHJlZGljYXRlKToKICAgICAgICAgICAgb2ssIGF0dHJzID0gX3NwbGl0X2xpc3QoYXR0cnMsIHByZWRpY2F0ZSkKICAgICAgICAgICAgaWYgb2s6CiAgICAgICAgICAgICAgICBoci5tYXliZSgpCiAgICAgICAgICAgICAgICBwdXNoKG1zZykKICAgICAgICAgICAgICAgIGZvciBuYW1lLCBraW5kLCBob21lY2xzLCB2YWx1ZSBpbiBvazoKICAgICAgICAgICAgICAgICAgICBwdXNoKHNlbGYuZG9jdW1lbnQoZ2V0YXR0cihvYmplY3QsIG5hbWUpLCBuYW1lLCBtb2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCwgb2JqZWN0KSkKICAgICAgICAgICAgICAgICAgICBwdXNoKCdcbicpCiAgICAgICAgICAgIHJldHVybiBhdHRycwoKICAgICAgICBkZWYgc3BpbGxwcm9wZXJ0aWVzKG1zZywgYXR0cnMsIHByZWRpY2F0ZSk6CiAgICAgICAgICAgIG9rLCBhdHRycyA9IF9zcGxpdF9saXN0KGF0dHJzLCBwcmVkaWNhdGUpCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgaHIubWF5YmUoKQogICAgICAgICAgICAgICAgcHVzaChtc2cpCiAgICAgICAgICAgICAgICBmb3IgbmFtZSwga2luZCwgaG9tZWNscywgdmFsdWUgaW4gb2s6CiAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGRsPjxkdD48c3Ryb25nPiVzPC9zdHJvbmc+PC9kdD5cbicgJSBuYW1lKQogICAgICAgICAgICAgICAgICAgIGlmIHZhbHVlLl9fZG9jX18gaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGRvYyA9IHNlbGYubWFya3VwKHZhbHVlLl9fZG9jX18sIHNlbGYucHJlZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jcywgY2xhc3NlcywgbWRpY3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goJzxkZD48dHQ+JXM8L3R0PjwvZGQ+XG4nICUgZG9jKQogICAgICAgICAgICAgICAgICAgIGZvciBhdHRyLCB0YWcgaW4gWygnZmdldCcsICc8ZW0+Z2V0PC9lbT4nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ2ZzZXQnLCAnPGVtPnNldDwvZW0+JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdmZGVsJywgJzxlbT5kZWxldGU8L2VtPicpXToKICAgICAgICAgICAgICAgICAgICAgICAgZnVuYyA9IGdldGF0dHIodmFsdWUsIGF0dHIpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIGZ1bmMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gc2VsZi5kb2N1bWVudChmdW5jLCB0YWcsIG1vZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmNzLCBjbGFzc2VzLCBtZGljdCwgb2JqZWN0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGRkPiVzPC9kZD5cbicgJSBiYXNlKQogICAgICAgICAgICAgICAgICAgIHB1c2goJzwvZGw+XG4nKQogICAgICAgICAgICByZXR1cm4gYXR0cnMKCiAgICAgICAgZGVmIHNwaWxsZGF0YShtc2csIGF0dHJzLCBwcmVkaWNhdGUpOgogICAgICAgICAgICBvaywgYXR0cnMgPSBfc3BsaXRfbGlzdChhdHRycywgcHJlZGljYXRlKQogICAgICAgICAgICBpZiBvazoKICAgICAgICAgICAgICAgIGhyLm1heWJlKCkKICAgICAgICAgICAgICAgIHB1c2gobXNnKQogICAgICAgICAgICAgICAgZm9yIG5hbWUsIGtpbmQsIGhvbWVjbHMsIHZhbHVlIGluIG9rOgogICAgICAgICAgICAgICAgICAgIGJhc2UgPSBzZWxmLmRvY290aGVyKGdldGF0dHIob2JqZWN0LCBuYW1lKSwgbmFtZSwgbW9kKQogICAgICAgICAgICAgICAgICAgIGlmIGNhbGxhYmxlKHZhbHVlKToKICAgICAgICAgICAgICAgICAgICAgICAgZG9jID0gZ2V0YXR0cih2YWx1ZSwgIl9fZG9jX18iLCBOb25lKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIGRvYyA9IE5vbmUKICAgICAgICAgICAgICAgICAgICBpZiBkb2MgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCgnPGRsPjxkdD4lczwvZGw+XG4nICUgYmFzZSkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBzZWxmLm1hcmt1cChnZXRkb2ModmFsdWUpLCBzZWxmLnByZWZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3MsIGNsYXNzZXMsIG1kaWN0KQogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSAnPGRkPjx0dD4lczwvdHQ+JyAlIGRvYwogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKCc8ZGw+PGR0PiVzJXM8L2RsPlxuJyAlIChiYXNlLCBkb2MpKQogICAgICAgICAgICAgICAgICAgIHB1c2goJ1xuJykKICAgICAgICAgICAgcmV0dXJuIGF0dHJzCgogICAgICAgIGF0dHJzID0gZmlsdGVyKGxhbWJkYSAobmFtZSwga2luZCwgY2xzLCB2YWx1ZSk6IHZpc2libGVuYW1lKG5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgIGluc3BlY3QuY2xhc3NpZnlfY2xhc3NfYXR0cnMob2JqZWN0KSkKICAgICAgICBtZGljdCA9IHt9CiAgICAgICAgZm9yIGtleSwga2luZCwgaG9tZWNscywgdmFsdWUgaW4gYXR0cnM6CiAgICAgICAgICAgIG1kaWN0W2tleV0gPSBhbmNob3IgPSAnIycgKyBuYW1lICsgJy0nICsga2V5CiAgICAgICAgICAgIHZhbHVlID0gZ2V0YXR0cihvYmplY3QsIGtleSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgIyBUaGUgdmFsdWUgbWF5IG5vdCBiZSBoYXNoYWJsZSAoZS5nLiwgYSBkYXRhIGF0dHIgd2l0aAogICAgICAgICAgICAgICAgIyBhIGRpY3Qgb3IgbGlzdCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBtZGljdFt2YWx1ZV0gPSBhbmNob3IKICAgICAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgd2hpbGUgYXR0cnM6CiAgICAgICAgICAgIGlmIG1ybzoKICAgICAgICAgICAgICAgIHRoaXNjbGFzcyA9IG1yby5wb3AoMCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHRoaXNjbGFzcyA9IGF0dHJzWzBdWzJdCiAgICAgICAgICAgIGF0dHJzLCBpbmhlcml0ZWQgPSBfc3BsaXRfbGlzdChhdHRycywgbGFtYmRhIHQ6IHRbMl0gaXMgdGhpc2NsYXNzKQoKICAgICAgICAgICAgaWYgdGhpc2NsYXNzIGlzIF9fYnVpbHRpbl9fLm9iamVjdDoKICAgICAgICAgICAgICAgIGF0dHJzID0gaW5oZXJpdGVkCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBlbGlmIHRoaXNjbGFzcyBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICB0YWcgPSAnZGVmaW5lZCBoZXJlJwogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgdGFnID0gJ2luaGVyaXRlZCBmcm9tICVzJyAlIHNlbGYuY2xhc3NsaW5rKHRoaXNjbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuX19tb2R1bGVfXykKICAgICAgICAgICAgdGFnICs9ICc6PGJyPlxuJwoKICAgICAgICAgICAgIyBTb3J0IGF0dHJzIGJ5IG5hbWUuCiAgICAgICAgICAgIGF0dHJzLnNvcnQobGFtYmRhIHQxLCB0MjogY21wKHQxWzBdLCB0MlswXSkpCgogICAgICAgICAgICAjIFB1bXAgb3V0IHRoZSBhdHRycywgc2VncmVnYXRlZCBieSBraW5kLgogICAgICAgICAgICBhdHRycyA9IHNwaWxsKCdNZXRob2RzICVzJyAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHQ6IHRbMV0gPT0gJ21ldGhvZCcpCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGwoJ0NsYXNzIG1ldGhvZHMgJXMnICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAnY2xhc3MgbWV0aG9kJykKICAgICAgICAgICAgYXR0cnMgPSBzcGlsbCgnU3RhdGljIG1ldGhvZHMgJXMnICUgdGFnLCBhdHRycywKICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAnc3RhdGljIG1ldGhvZCcpCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGxwcm9wZXJ0aWVzKCdQcm9wZXJ0aWVzICVzJyAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdwcm9wZXJ0eScpCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGxkYXRhKCdEYXRhIGFuZCBvdGhlciBhdHRyaWJ1dGVzICVzJyAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdkYXRhJykKICAgICAgICAgICAgYXNzZXJ0IGF0dHJzID09IFtdCiAgICAgICAgICAgIGF0dHJzID0gaW5oZXJpdGVkCgogICAgICAgIGNvbnRlbnRzID0gJycuam9pbihjb250ZW50cykKCiAgICAgICAgaWYgbmFtZSA9PSByZWFsbmFtZToKICAgICAgICAgICAgdGl0bGUgPSAnPGEgbmFtZT0iJXMiPmNsYXNzIDxzdHJvbmc+JXM8L3N0cm9uZz48L2E+JyAlICgKICAgICAgICAgICAgICAgIG5hbWUsIHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gJzxzdHJvbmc+JXM8L3N0cm9uZz4gPSA8YSBuYW1lPSIlcyI+Y2xhc3MgJXM8L2E+JyAlICgKICAgICAgICAgICAgICAgIG5hbWUsIG5hbWUsIHJlYWxuYW1lKQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gW10KICAgICAgICAgICAgZm9yIGJhc2UgaW4gYmFzZXM6CiAgICAgICAgICAgICAgICBwYXJlbnRzLmFwcGVuZChzZWxmLmNsYXNzbGluayhiYXNlLCBvYmplY3QuX19tb2R1bGVfXykpCiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgKyAnKCVzKScgJSBqb2luKHBhcmVudHMsICcsICcpCiAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoZ2V0ZG9jKG9iamVjdCksIHNlbGYucHJlZm9ybWF0LCBmdW5jcywgY2xhc3NlcywgbWRpY3QpCiAgICAgICAgZG9jID0gZG9jIGFuZCAnPHR0PiVzPGJyPiZuYnNwOzwvdHQ+JyAlIGRvYwoKICAgICAgICByZXR1cm4gc2VsZi5zZWN0aW9uKHRpdGxlLCAnIzAwMDAwMCcsICcjZmZjOGQ4JywgY29udGVudHMsIDMsIGRvYykKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiBzZWxmLmdyZXkoJz0nICsgc2VsZi5yZXByKG9iamVjdCkpCgogICAgZGVmIGRvY3JvdXRpbmUoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLAogICAgICAgICAgICAgICAgICAgZnVuY3M9e30sIGNsYXNzZXM9e30sIG1ldGhvZHM9e30sIGNsPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIGZ1bmN0aW9uIG9yIG1ldGhvZCBvYmplY3QuIiIiCiAgICAgICAgcmVhbG5hbWUgPSBvYmplY3QuX19uYW1lX18KICAgICAgICBuYW1lID0gbmFtZSBvciByZWFsbmFtZQogICAgICAgIGFuY2hvciA9IChjbCBhbmQgY2wuX19uYW1lX18gb3IgJycpICsgJy0nICsgbmFtZQogICAgICAgIG5vdGUgPSAnJwogICAgICAgIHNraXBkb2NzID0gMAogICAgICAgIGlmIGluc3BlY3QuaXNtZXRob2Qob2JqZWN0KToKICAgICAgICAgICAgaW1jbGFzcyA9IG9iamVjdC5pbV9jbGFzcwogICAgICAgICAgICBpZiBjbDoKICAgICAgICAgICAgICAgIGlmIGltY2xhc3MgaXMgbm90IGNsOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIGZyb20gJyArIHNlbGYuY2xhc3NsaW5rKGltY2xhc3MsIG1vZCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIG9iamVjdC5pbV9zZWxmOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIG1ldGhvZCBvZiAlcyBpbnN0YW5jZScgJSBzZWxmLmNsYXNzbGluaygKICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmltX3NlbGYuX19jbGFzc19fLCBtb2QpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIHVuYm91bmQgJXMgbWV0aG9kJyAlIHNlbGYuY2xhc3NsaW5rKGltY2xhc3MsbW9kKQogICAgICAgICAgICBvYmplY3QgPSBvYmplY3QuaW1fZnVuYwoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9ICc8YSBuYW1lPSIlcyI+PHN0cm9uZz4lczwvc3Ryb25nPjwvYT4nICUgKGFuY2hvciwgcmVhbG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgKGNsIGFuZCByZWFsbmFtZSBpbiBjbC5fX2RpY3RfXyBhbmQKICAgICAgICAgICAgICAgIGNsLl9fZGljdF9fW3JlYWxuYW1lXSBpcyBvYmplY3QpOgogICAgICAgICAgICAgICAgcmVhbGxpbmsgPSAnPGEgaHJlZj0iIyVzIj4lczwvYT4nICUgKAogICAgICAgICAgICAgICAgICAgIGNsLl9fbmFtZV9fICsgJy0nICsgcmVhbG5hbWUsIHJlYWxuYW1lKQogICAgICAgICAgICAgICAgc2tpcGRvY3MgPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZWFsbGluayA9IHJlYWxuYW1lCiAgICAgICAgICAgIHRpdGxlID0gJzxhIG5hbWU9IiVzIj48c3Ryb25nPiVzPC9zdHJvbmc+PC9hPiA9ICVzJyAlICgKICAgICAgICAgICAgICAgIGFuY2hvciwgbmFtZSwgcmVhbGxpbmspCiAgICAgICAgaWYgaW5zcGVjdC5pc2Z1bmN0aW9uKG9iamVjdCk6CiAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cyA9IGluc3BlY3QuZ2V0YXJnc3BlYyhvYmplY3QpCiAgICAgICAgICAgIGFyZ3NwZWMgPSBpbnNwZWN0LmZvcm1hdGFyZ3NwZWMoCiAgICAgICAgICAgICAgICBhcmdzLCB2YXJhcmdzLCB2YXJrdywgZGVmYXVsdHMsIGZvcm1hdHZhbHVlPXNlbGYuZm9ybWF0dmFsdWUpCiAgICAgICAgICAgIGlmIHJlYWxuYW1lID09ICc8bGFtYmRhPic6CiAgICAgICAgICAgICAgICB0aXRsZSA9ICc8c3Ryb25nPiVzPC9zdHJvbmc+IDxlbT5sYW1iZGE8L2VtPiAnICUgbmFtZQogICAgICAgICAgICAgICAgYXJnc3BlYyA9IGFyZ3NwZWNbMTotMV0gIyByZW1vdmUgcGFyZW50aGVzZXMKICAgICAgICBlbHNlOgogICAgICAgICAgICBhcmdzcGVjID0gJyguLi4pJwoKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgKG5vdGUgYW5kIHNlbGYuZ3JleSgKICAgICAgICAgICAgICAgJzxmb250IGZhY2U9ImhlbHZldGljYSwgYXJpYWwiPiVzPC9mb250PicgJSBub3RlKSkKCiAgICAgICAgaWYgc2tpcGRvY3M6CiAgICAgICAgICAgIHJldHVybiAnPGRsPjxkdD4lczwvZHQ+PC9kbD5cbicgJSBkZWNsCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9jID0gc2VsZi5tYXJrdXAoCiAgICAgICAgICAgICAgICBnZXRkb2Mob2JqZWN0KSwgc2VsZi5wcmVmb3JtYXQsIGZ1bmNzLCBjbGFzc2VzLCBtZXRob2RzKQogICAgICAgICAgICBkb2MgPSBkb2MgYW5kICc8ZGQ+PHR0PiVzPC90dD48L2RkPicgJSBkb2MKICAgICAgICAgICAgcmV0dXJuICc8ZGw+PGR0PiVzPC9kdD4lczwvZGw+XG4nICUgKGRlY2wsIGRvYykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCAqaWdub3JlZCk6CiAgICAgICAgIiIiUHJvZHVjZSBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGEgZGF0YSBvYmplY3QuIiIiCiAgICAgICAgbGhzID0gbmFtZSBhbmQgJzxzdHJvbmc+JXM8L3N0cm9uZz4gPSAnICUgbmFtZSBvciAnJwogICAgICAgIHJldHVybiBsaHMgKyBzZWxmLnJlcHIob2JqZWN0KQoKICAgIGRlZiBpbmRleChzZWxmLCBkaXIsIHNoYWRvd2VkPU5vbmUpOgogICAgICAgICIiIkdlbmVyYXRlIGFuIEhUTUwgaW5kZXggZm9yIGEgZGlyZWN0b3J5IG9mIG1vZHVsZXMuIiIiCiAgICAgICAgbW9kcGtncyA9IFtdCiAgICAgICAgaWYgc2hhZG93ZWQgaXMgTm9uZTogc2hhZG93ZWQgPSB7fQogICAgICAgIHNlZW4gPSB7fQogICAgICAgIGZpbGVzID0gb3MubGlzdGRpcihkaXIpCgogICAgICAgIGRlZiBmb3VuZChuYW1lLCBpc3BhY2thZ2UsCiAgICAgICAgICAgICAgICAgIG1vZHBrZ3M9bW9kcGtncywgc2hhZG93ZWQ9c2hhZG93ZWQsIHNlZW49c2Vlbik6CiAgICAgICAgICAgIGlmIG5hbWUgbm90IGluIHNlZW46CiAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZCgobmFtZSwgJycsIGlzcGFja2FnZSwgbmFtZSBpbiBzaGFkb3dlZCkpCiAgICAgICAgICAgICAgICBzZWVuW25hbWVdID0gMQogICAgICAgICAgICAgICAgc2hhZG93ZWRbbmFtZV0gPSAxCgogICAgICAgICMgUGFja2FnZSBzcGFtL19faW5pdF9fLnB5IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBtb2R1bGUgc3BhbS5weS4KICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGlzcGFja2FnZShwYXRoKTogZm91bmQoZmlsZSwgMSkKICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IGluc3BlY3QuZ2V0bW9kdWxlbmFtZShmaWxlKQogICAgICAgICAgICAgICAgaWYgbW9kbmFtZTogZm91bmQobW9kbmFtZSwgMCkKCiAgICAgICAgbW9kcGtncy5zb3J0KCkKICAgICAgICBjb250ZW50cyA9IHNlbGYubXVsdGljb2x1bW4obW9kcGtncywgc2VsZi5tb2Rwa2dsaW5rKQogICAgICAgIHJldHVybiBzZWxmLmJpZ3NlY3Rpb24oZGlyLCAnI2ZmZmZmZicsICcjZWU3N2FhJywgY29udGVudHMpCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHRleHQgZG9jdW1lbnRhdGlvbiBnZW5lcmF0b3IKCmNsYXNzIFRleHRSZXByKFJlcHIpOgogICAgIiIiQ2xhc3MgZm9yIHNhZmVseSBtYWtpbmcgYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIGEgUHl0aG9uIG9iamVjdC4iIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBSZXByLl9faW5pdF9fKHNlbGYpCiAgICAgICAgc2VsZi5tYXhsaXN0ID0gc2VsZi5tYXh0dXBsZSA9IDIwCiAgICAgICAgc2VsZi5tYXhkaWN0ID0gMTAKICAgICAgICBzZWxmLm1heHN0cmluZyA9IHNlbGYubWF4b3RoZXIgPSAxMDAKCiAgICBkZWYgcmVwcjEoc2VsZiwgeCwgbGV2ZWwpOgogICAgICAgIG1ldGhvZG5hbWUgPSAncmVwcl8nICsgam9pbihzcGxpdCh0eXBlKHgpLl9fbmFtZV9fKSwgJ18nKQogICAgICAgIGlmIGhhc2F0dHIoc2VsZiwgbWV0aG9kbmFtZSk6CiAgICAgICAgICAgIHJldHVybiBnZXRhdHRyKHNlbGYsIG1ldGhvZG5hbWUpKHgsIGxldmVsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4b3RoZXIpCgogICAgZGVmIHJlcHJfc3RyaW5nKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0ZXN0ID0gY3JhbSh4LCBzZWxmLm1heHN0cmluZykKICAgICAgICB0ZXN0cmVwciA9IHJlcHIodGVzdCkKICAgICAgICBpZiAnXFwnIGluIHRlc3QgYW5kICdcXCcgbm90IGluIHJlcGxhY2UodGVzdHJlcHIsIHInXFwnLCAnJyk6CiAgICAgICAgICAgICMgQmFja3NsYXNoZXMgYXJlIG9ubHkgbGl0ZXJhbCBpbiB0aGUgc3RyaW5nIGFuZCBhcmUgbmV2ZXIKICAgICAgICAgICAgIyBuZWVkZWQgdG8gbWFrZSBhbnkgc3BlY2lhbCBjaGFyYWN0ZXJzLCBzbyBzaG93IGEgcmF3IHN0cmluZy4KICAgICAgICAgICAgcmV0dXJuICdyJyArIHRlc3RyZXByWzBdICsgdGVzdCArIHRlc3RyZXByWzBdCiAgICAgICAgcmV0dXJuIHRlc3RyZXByCgogICAgcmVwcl9zdHIgPSByZXByX3N0cmluZwoKICAgIGRlZiByZXByX2luc3RhbmNlKHNlbGYsIHgsIGxldmVsKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJldHVybiBjcmFtKHN0cmlwaWQocmVwcih4KSksIHNlbGYubWF4c3RyaW5nKQogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuICc8JXMgaW5zdGFuY2U+JyAlIHguX19jbGFzc19fLl9fbmFtZV9fCgpjbGFzcyBUZXh0RG9jKERvYyk6CiAgICAiIiJGb3JtYXR0ZXIgY2xhc3MgZm9yIHRleHQgZG9jdW1lbnRhdGlvbi4iIiIKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGV4dCBmb3JtYXR0aW5nIHV0aWxpdGllcwoKICAgIF9yZXByX2luc3RhbmNlID0gVGV4dFJlcHIoKQogICAgcmVwciA9IF9yZXByX2luc3RhbmNlLnJlcHIKCiAgICBkZWYgYm9sZChzZWxmLCB0ZXh0KToKICAgICAgICAiIiJGb3JtYXQgYSBzdHJpbmcgaW4gYm9sZCBieSBvdmVyc3RyaWtpbmcuIiIiCiAgICAgICAgcmV0dXJuIGpvaW4obWFwKGxhbWJkYSBjaDogY2ggKyAnXGInICsgY2gsIHRleHQpLCAnJykKCiAgICBkZWYgaW5kZW50KHNlbGYsIHRleHQsIHByZWZpeD0nICAgICcpOgogICAgICAgICIiIkluZGVudCB0ZXh0IGJ5IHByZXBlbmRpbmcgYSBnaXZlbiBwcmVmaXggdG8gZWFjaCBsaW5lLiIiIgogICAgICAgIGlmIG5vdCB0ZXh0OiByZXR1cm4gJycKICAgICAgICBsaW5lcyA9IHNwbGl0KHRleHQsICdcbicpCiAgICAgICAgbGluZXMgPSBtYXAobGFtYmRhIGxpbmUsIHByZWZpeD1wcmVmaXg6IHByZWZpeCArIGxpbmUsIGxpbmVzKQogICAgICAgIGlmIGxpbmVzOiBsaW5lc1stMV0gPSByc3RyaXAobGluZXNbLTFdKQogICAgICAgIHJldHVybiBqb2luKGxpbmVzLCAnXG4nKQoKICAgIGRlZiBzZWN0aW9uKHNlbGYsIHRpdGxlLCBjb250ZW50cyk6CiAgICAgICAgIiIiRm9ybWF0IGEgc2VjdGlvbiB3aXRoIGEgZ2l2ZW4gaGVhZGluZy4iIiIKICAgICAgICByZXR1cm4gc2VsZi5ib2xkKHRpdGxlKSArICdcbicgKyByc3RyaXAoc2VsZi5pbmRlbnQoY29udGVudHMpKSArICdcblxuJwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlLXNwZWNpZmljIHJvdXRpbmVzCgogICAgZGVmIGZvcm1hdHRyZWUoc2VsZiwgdHJlZSwgbW9kbmFtZSwgcGFyZW50PU5vbmUsIHByZWZpeD0nJyk6CiAgICAgICAgIiIiUmVuZGVyIGluIHRleHQgYSBjbGFzcyB0cmVlIGFzIHJldHVybmVkIGJ5IGluc3BlY3QuZ2V0Y2xhc3N0cmVlKCkuIiIiCiAgICAgICAgcmVzdWx0ID0gJycKICAgICAgICBmb3IgZW50cnkgaW4gdHJlZToKICAgICAgICAgICAgaWYgdHlwZShlbnRyeSkgaXMgdHlwZSgoKSk6CiAgICAgICAgICAgICAgICBjLCBiYXNlcyA9IGVudHJ5CiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBwcmVmaXggKyBjbGFzc25hbWUoYywgbW9kbmFtZSkKICAgICAgICAgICAgICAgIGlmIGJhc2VzIGFuZCBiYXNlcyAhPSAocGFyZW50LCk6CiAgICAgICAgICAgICAgICAgICAgcGFyZW50cyA9IG1hcChsYW1iZGEgYywgbT1tb2RuYW1lOiBjbGFzc25hbWUoYywgbSksIGJhc2VzKQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArICdcbicKICAgICAgICAgICAgZWxpZiB0eXBlKGVudHJ5KSBpcyB0eXBlKFtdKToKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuZm9ybWF0dHJlZSgKICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kbmFtZSwgYywgcHJlZml4ICsgJyAgICAnKQogICAgICAgIHJldHVybiByZXN1bHQKCiAgICBkZWYgZG9jbW9kdWxlKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZ2l2ZW4gbW9kdWxlIG9iamVjdC4iIiIKICAgICAgICBuYW1lID0gb2JqZWN0Ll9fbmFtZV9fICMgaWdub3JlIHRoZSBwYXNzZWQtaW4gbmFtZQogICAgICAgIHN5bm9wLCBkZXNjID0gc3BsaXRkb2MoZ2V0ZG9jKG9iamVjdCkpCiAgICAgICAgcmVzdWx0ID0gc2VsZi5zZWN0aW9uKCdOQU1FJywgbmFtZSArIChzeW5vcCBhbmQgJyAtICcgKyBzeW5vcCkpCgogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSA9IGluc3BlY3QuZ2V0YWJzZmlsZShvYmplY3QpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvcjoKICAgICAgICAgICAgZmlsZSA9ICcoYnVpbHQtaW4pJwogICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRklMRScsIGZpbGUpCiAgICAgICAgaWYgZGVzYzoKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdERVNDUklQVElPTicsIGRlc2MpCgogICAgICAgIGNsYXNzZXMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGluc3BlY3QuZ2V0bWVtYmVycyhvYmplY3QsIGluc3BlY3QuaXNjbGFzcyk6CiAgICAgICAgICAgIGlmIChpbnNwZWN0LmdldG1vZHVsZSh2YWx1ZSkgb3Igb2JqZWN0KSBpcyBvYmplY3Q6CiAgICAgICAgICAgICAgICBpZiB2aXNpYmxlbmFtZShrZXkpOgogICAgICAgICAgICAgICAgICAgIGNsYXNzZXMuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICBmdW5jcyA9IFtdCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iamVjdCwgaW5zcGVjdC5pc3JvdXRpbmUpOgogICAgICAgICAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih2YWx1ZSkgb3IgaW5zcGVjdC5nZXRtb2R1bGUodmFsdWUpIGlzIG9iamVjdDoKICAgICAgICAgICAgICAgIGlmIHZpc2libGVuYW1lKGtleSk6CiAgICAgICAgICAgICAgICAgICAgZnVuY3MuYXBwZW5kKChrZXksIHZhbHVlKSkKICAgICAgICBkYXRhID0gW10KICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBpbnNwZWN0LmdldG1lbWJlcnMob2JqZWN0LCBpc2RhdGEpOgogICAgICAgICAgICBpZiB2aXNpYmxlbmFtZShrZXkpOgogICAgICAgICAgICAgICAgZGF0YS5hcHBlbmQoKGtleSwgdmFsdWUpKQoKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fcGF0aF9fJyk6CiAgICAgICAgICAgIG1vZHBrZ3MgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKG9iamVjdC5fX3BhdGhfX1swXSk6CiAgICAgICAgICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKG9iamVjdC5fX3BhdGhfX1swXSwgZmlsZSkKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUoZmlsZSkKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgIT0gJ19faW5pdF9fJzoKICAgICAgICAgICAgICAgICAgICBpZiBtb2RuYW1lIGFuZCBtb2RuYW1lIG5vdCBpbiBtb2Rwa2dzOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZChtb2RuYW1lKQogICAgICAgICAgICAgICAgICAgIGVsaWYgaXNwYWNrYWdlKHBhdGgpOgogICAgICAgICAgICAgICAgICAgICAgICBtb2Rwa2dzLmFwcGVuZChmaWxlICsgJyAocGFja2FnZSknKQogICAgICAgICAgICBtb2Rwa2dzLnNvcnQoKQogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oCiAgICAgICAgICAgICAgICAnUEFDS0FHRSBDT05URU5UUycsIGpvaW4obW9kcGtncywgJ1xuJykpCgogICAgICAgIGlmIGNsYXNzZXM6CiAgICAgICAgICAgIGNsYXNzbGlzdCA9IG1hcChsYW1iZGEgKGtleSwgdmFsdWUpOiB2YWx1ZSwgY2xhc3NlcykKICAgICAgICAgICAgY29udGVudHMgPSBbc2VsZi5mb3JtYXR0cmVlKAogICAgICAgICAgICAgICAgaW5zcGVjdC5nZXRjbGFzc3RyZWUoY2xhc3NsaXN0LCAxKSwgbmFtZSldCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGNsYXNzZXM6CiAgICAgICAgICAgICAgICBjb250ZW50cy5hcHBlbmQoc2VsZi5kb2N1bWVudCh2YWx1ZSwga2V5LCBuYW1lKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDTEFTU0VTJywgam9pbihjb250ZW50cywgJ1xuJykpCgogICAgICAgIGlmIGZ1bmNzOgogICAgICAgICAgICBjb250ZW50cyA9IFtdCiAgICAgICAgICAgIGZvciBrZXksIHZhbHVlIGluIGZ1bmNzOgogICAgICAgICAgICAgICAgY29udGVudHMuYXBwZW5kKHNlbGYuZG9jdW1lbnQodmFsdWUsIGtleSwgbmFtZSkpCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignRlVOQ1RJT05TJywgam9pbihjb250ZW50cywgJ1xuJykpCgogICAgICAgIGlmIGRhdGE6CiAgICAgICAgICAgIGNvbnRlbnRzID0gW10KICAgICAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gZGF0YToKICAgICAgICAgICAgICAgIGNvbnRlbnRzLmFwcGVuZChzZWxmLmRvY290aGVyKHZhbHVlLCBrZXksIG5hbWUsIDcwKSkKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdEQVRBJywgam9pbihjb250ZW50cywgJ1xuJykpCgogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX192ZXJzaW9uX18nKToKICAgICAgICAgICAgdmVyc2lvbiA9IHN0cihvYmplY3QuX192ZXJzaW9uX18pCiAgICAgICAgICAgIGlmIHZlcnNpb25bOjExXSA9PSAnJCcgKyAnUmV2aXNpb246ICcgYW5kIHZlcnNpb25bLTE6XSA9PSAnJCc6CiAgICAgICAgICAgICAgICB2ZXJzaW9uID0gc3RyaXAodmVyc2lvblsxMTotMV0pCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdCArIHNlbGYuc2VjdGlvbignVkVSU0lPTicsIHZlcnNpb24pCiAgICAgICAgaWYgaGFzYXR0cihvYmplY3QsICdfX2RhdGVfXycpOgogICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBzZWxmLnNlY3Rpb24oJ0RBVEUnLCBzdHIob2JqZWN0Ll9fZGF0ZV9fKSkKICAgICAgICBpZiBoYXNhdHRyKG9iamVjdCwgJ19fYXV0aG9yX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdBVVRIT1InLCBzdHIob2JqZWN0Ll9fYXV0aG9yX18pKQogICAgICAgIGlmIGhhc2F0dHIob2JqZWN0LCAnX19jcmVkaXRzX18nKToKICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgc2VsZi5zZWN0aW9uKCdDUkVESVRTJywgc3RyKG9iamVjdC5fX2NyZWRpdHNfXykpCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgIGRlZiBkb2NjbGFzcyhzZWxmLCBvYmplY3QsIG5hbWU9Tm9uZSwgbW9kPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGdpdmVuIGNsYXNzIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgYmFzZXMgPSBvYmplY3QuX19iYXNlc19fCgogICAgICAgIGRlZiBtYWtlbmFtZShjLCBtPW9iamVjdC5fX21vZHVsZV9fKToKICAgICAgICAgICAgcmV0dXJuIGNsYXNzbmFtZShjLCBtKQoKICAgICAgICBpZiBuYW1lID09IHJlYWxuYW1lOgogICAgICAgICAgICB0aXRsZSA9ICdjbGFzcyAnICsgc2VsZi5ib2xkKHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKG5hbWUpICsgJyA9IGNsYXNzICcgKyByZWFsbmFtZQogICAgICAgIGlmIGJhc2VzOgogICAgICAgICAgICBwYXJlbnRzID0gbWFwKG1ha2VuYW1lLCBiYXNlcykKICAgICAgICAgICAgdGl0bGUgPSB0aXRsZSArICcoJXMpJyAlIGpvaW4ocGFyZW50cywgJywgJykKCiAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkKICAgICAgICBjb250ZW50cyA9IGRvYyBhbmQgW2RvYyArICdcbiddIG9yIFtdCiAgICAgICAgcHVzaCA9IGNvbnRlbnRzLmFwcGVuZAoKICAgICAgICAjIExpc3QgdGhlIG1ybywgaWYgbm9uLXRyaXZpYWwuCiAgICAgICAgbXJvID0gbGlzdChpbnNwZWN0LmdldG1ybyhvYmplY3QpKQogICAgICAgIGlmIGxlbihtcm8pID4gMjoKICAgICAgICAgICAgcHVzaCgiTWV0aG9kIHJlc29sdXRpb24gb3JkZXI6IikKICAgICAgICAgICAgZm9yIGJhc2UgaW4gbXJvOgogICAgICAgICAgICAgICAgcHVzaCgnICAgICcgKyBtYWtlbmFtZShiYXNlKSkKICAgICAgICAgICAgcHVzaCgnJykKCiAgICAgICAgIyBDdXRlIGxpdHRsZSBjbGFzcyB0byBwdW1wIG91dCBhIGhvcml6b250YWwgcnVsZSBiZXR3ZWVuIHNlY3Rpb25zLgogICAgICAgIGNsYXNzIEhvcml6b250YWxSdWxlOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgICAgICAgICBzZWxmLm5lZWRvbmUgPSAwCiAgICAgICAgICAgIGRlZiBtYXliZShzZWxmKToKICAgICAgICAgICAgICAgIGlmIHNlbGYubmVlZG9uZToKICAgICAgICAgICAgICAgICAgICBwdXNoKCctJyAqIDcwKQogICAgICAgICAgICAgICAgc2VsZi5uZWVkb25lID0gMQogICAgICAgIGhyID0gSG9yaXpvbnRhbFJ1bGUoKQoKICAgICAgICBkZWYgc3BpbGwobXNnLCBhdHRycywgcHJlZGljYXRlKToKICAgICAgICAgICAgb2ssIGF0dHJzID0gX3NwbGl0X2xpc3QoYXR0cnMsIHByZWRpY2F0ZSkKICAgICAgICAgICAgaWYgb2s6CiAgICAgICAgICAgICAgICBoci5tYXliZSgpCiAgICAgICAgICAgICAgICBwdXNoKG1zZykKICAgICAgICAgICAgICAgIGZvciBuYW1lLCBraW5kLCBob21lY2xzLCB2YWx1ZSBpbiBvazoKICAgICAgICAgICAgICAgICAgICBwdXNoKHNlbGYuZG9jdW1lbnQoZ2V0YXR0cihvYmplY3QsIG5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBtb2QsIG9iamVjdCkpCiAgICAgICAgICAgIHJldHVybiBhdHRycwoKICAgICAgICBkZWYgc3BpbGxwcm9wZXJ0aWVzKG1zZywgYXR0cnMsIHByZWRpY2F0ZSk6CiAgICAgICAgICAgIG9rLCBhdHRycyA9IF9zcGxpdF9saXN0KGF0dHJzLCBwcmVkaWNhdGUpCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgaHIubWF5YmUoKQogICAgICAgICAgICAgICAgcHVzaChtc2cpCiAgICAgICAgICAgICAgICBmb3IgbmFtZSwga2luZCwgaG9tZWNscywgdmFsdWUgaW4gb2s6CiAgICAgICAgICAgICAgICAgICAgcHVzaChuYW1lKQogICAgICAgICAgICAgICAgICAgIG5lZWRfYmxhbmtfYWZ0ZXJfZG9jID0gMAogICAgICAgICAgICAgICAgICAgIGRvYyA9IGdldGRvYyh2YWx1ZSkgb3IgJycKICAgICAgICAgICAgICAgICAgICBpZiBkb2M6CiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goc2VsZi5pbmRlbnQoZG9jKSkKICAgICAgICAgICAgICAgICAgICAgICAgbmVlZF9ibGFua19hZnRlcl9kb2MgPSAxCiAgICAgICAgICAgICAgICAgICAgZm9yIGF0dHIsIHRhZyBpbiBbKCdmZ2V0JywgJzxnZXQ+JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdmc2V0JywgJzxzZXQ+JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCdmZGVsJywgJzxkZWxldGU+JyldOgogICAgICAgICAgICAgICAgICAgICAgICBmdW5jID0gZ2V0YXR0cih2YWx1ZSwgYXR0cikKICAgICAgICAgICAgICAgICAgICAgICAgaWYgZnVuYyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5lZWRfYmxhbmtfYWZ0ZXJfZG9jOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goJycpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZF9ibGFua19hZnRlcl9kb2MgPSAwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gc2VsZi5kb2N1bWVudChmdW5jLCB0YWcsIG1vZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goc2VsZi5pbmRlbnQoYmFzZSkpCiAgICAgICAgICAgIHJldHVybiBhdHRycwoKICAgICAgICBkZWYgc3BpbGxkYXRhKG1zZywgYXR0cnMsIHByZWRpY2F0ZSk6CiAgICAgICAgICAgIG9rLCBhdHRycyA9IF9zcGxpdF9saXN0KGF0dHJzLCBwcmVkaWNhdGUpCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgaHIubWF5YmUoKQogICAgICAgICAgICAgICAgcHVzaChtc2cpCiAgICAgICAgICAgICAgICBmb3IgbmFtZSwga2luZCwgaG9tZWNscywgdmFsdWUgaW4gb2s6CiAgICAgICAgICAgICAgICAgICAgaWYgY2FsbGFibGUodmFsdWUpOgogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBnZXRhdHRyKHZhbHVlLCAiX19kb2NfXyIsIE5vbmUpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZG9jID0gTm9uZQogICAgICAgICAgICAgICAgICAgIHB1c2goc2VsZi5kb2NvdGhlcihnZXRhdHRyKG9iamVjdCwgbmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIG1vZCwgNzAsIGRvYykgKyAnXG4nKQogICAgICAgICAgICByZXR1cm4gYXR0cnMKCiAgICAgICAgYXR0cnMgPSBmaWx0ZXIobGFtYmRhIChuYW1lLCBraW5kLCBjbHMsIHZhbHVlKTogdmlzaWJsZW5hbWUobmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgaW5zcGVjdC5jbGFzc2lmeV9jbGFzc19hdHRycyhvYmplY3QpKQogICAgICAgIHdoaWxlIGF0dHJzOgogICAgICAgICAgICBpZiBtcm86CiAgICAgICAgICAgICAgICB0aGlzY2xhc3MgPSBtcm8ucG9wKDApCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB0aGlzY2xhc3MgPSBhdHRyc1swXVsyXQogICAgICAgICAgICBhdHRycywgaW5oZXJpdGVkID0gX3NwbGl0X2xpc3QoYXR0cnMsIGxhbWJkYSB0OiB0WzJdIGlzIHRoaXNjbGFzcykKCiAgICAgICAgICAgIGlmIHRoaXNjbGFzcyBpcyBfX2J1aWx0aW5fXy5vYmplY3Q6CiAgICAgICAgICAgICAgICBhdHRycyA9IGluaGVyaXRlZAogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZWxpZiB0aGlzY2xhc3MgaXMgb2JqZWN0OgogICAgICAgICAgICAgICAgdGFnID0gImRlZmluZWQgaGVyZSIKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHRhZyA9ICJpbmhlcml0ZWQgZnJvbSAlcyIgJSBjbGFzc25hbWUodGhpc2NsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuX19tb2R1bGVfXykKICAgICAgICAgICAgZmlsdGVyKGxhbWJkYSB0OiBub3QgdFswXS5zdGFydHN3aXRoKCdfJyksIGF0dHJzKQoKICAgICAgICAgICAgIyBTb3J0IGF0dHJzIGJ5IG5hbWUuCiAgICAgICAgICAgIGF0dHJzLnNvcnQoKQoKICAgICAgICAgICAgIyBQdW1wIG91dCB0aGUgYXR0cnMsIHNlZ3JlZ2F0ZWQgYnkga2luZC4KICAgICAgICAgICAgYXR0cnMgPSBzcGlsbCgiTWV0aG9kcyAlczpcbiIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSB0OiB0WzFdID09ICdtZXRob2QnKQogICAgICAgICAgICBhdHRycyA9IHNwaWxsKCJDbGFzcyBtZXRob2RzICVzOlxuIiAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHQ6IHRbMV0gPT0gJ2NsYXNzIG1ldGhvZCcpCiAgICAgICAgICAgIGF0dHJzID0gc3BpbGwoIlN0YXRpYyBtZXRob2RzICVzOlxuIiAlIHRhZywgYXR0cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhIHQ6IHRbMV0gPT0gJ3N0YXRpYyBtZXRob2QnKQogICAgICAgICAgICBhdHRycyA9IHNwaWxscHJvcGVydGllcygiUHJvcGVydGllcyAlczpcbiIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAncHJvcGVydHknKQogICAgICAgICAgICBhdHRycyA9IHNwaWxsZGF0YSgiRGF0YSBhbmQgb3RoZXIgYXR0cmlidXRlcyAlczpcbiIgJSB0YWcsIGF0dHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgdDogdFsxXSA9PSAnZGF0YScpCiAgICAgICAgICAgIGFzc2VydCBhdHRycyA9PSBbXQogICAgICAgICAgICBhdHRycyA9IGluaGVyaXRlZAoKICAgICAgICBjb250ZW50cyA9ICdcbicuam9pbihjb250ZW50cykKICAgICAgICBpZiBub3QgY29udGVudHM6CiAgICAgICAgICAgIHJldHVybiB0aXRsZSArICdcbicKICAgICAgICByZXR1cm4gdGl0bGUgKyAnXG4nICsgc2VsZi5pbmRlbnQocnN0cmlwKGNvbnRlbnRzKSwgJyB8ICAnKSArICdcbicKCiAgICBkZWYgZm9ybWF0dmFsdWUoc2VsZiwgb2JqZWN0KToKICAgICAgICAiIiJGb3JtYXQgYW4gYXJndW1lbnQgZGVmYXVsdCB2YWx1ZSBhcyB0ZXh0LiIiIgogICAgICAgIHJldHVybiAnPScgKyBzZWxmLnJlcHIob2JqZWN0KQoKICAgIGRlZiBkb2Nyb3V0aW5lKHNlbGYsIG9iamVjdCwgbmFtZT1Ob25lLCBtb2Q9Tm9uZSwgY2w9Tm9uZSk6CiAgICAgICAgIiIiUHJvZHVjZSB0ZXh0IGRvY3VtZW50YXRpb24gZm9yIGEgZnVuY3Rpb24gb3IgbWV0aG9kIG9iamVjdC4iIiIKICAgICAgICByZWFsbmFtZSA9IG9iamVjdC5fX25hbWVfXwogICAgICAgIG5hbWUgPSBuYW1lIG9yIHJlYWxuYW1lCiAgICAgICAgbm90ZSA9ICcnCiAgICAgICAgc2tpcGRvY3MgPSAwCiAgICAgICAgaWYgaW5zcGVjdC5pc21ldGhvZChvYmplY3QpOgogICAgICAgICAgICBpbWNsYXNzID0gb2JqZWN0LmltX2NsYXNzCiAgICAgICAgICAgIGlmIGNsOgogICAgICAgICAgICAgICAgaWYgaW1jbGFzcyBpcyBub3QgY2w6CiAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICcgZnJvbSAnICsgY2xhc3NuYW1lKGltY2xhc3MsIG1vZCkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmIG9iamVjdC5pbV9zZWxmOgogICAgICAgICAgICAgICAgICAgIG5vdGUgPSAnIG1ldGhvZCBvZiAlcyBpbnN0YW5jZScgJSBjbGFzc25hbWUoCiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbV9zZWxmLl9fY2xhc3NfXywgbW9kKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBub3RlID0gJyB1bmJvdW5kICVzIG1ldGhvZCcgJSBjbGFzc25hbWUoaW1jbGFzcyxtb2QpCiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5pbV9mdW5jCgogICAgICAgIGlmIG5hbWUgPT0gcmVhbG5hbWU6CiAgICAgICAgICAgIHRpdGxlID0gc2VsZi5ib2xkKHJlYWxuYW1lKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGlmIChjbCBhbmQgcmVhbG5hbWUgaW4gY2wuX19kaWN0X18gYW5kCiAgICAgICAgICAgICAgICBjbC5fX2RpY3RfX1tyZWFsbmFtZV0gaXMgb2JqZWN0KToKICAgICAgICAgICAgICAgIHNraXBkb2NzID0gMQogICAgICAgICAgICB0aXRsZSA9IHNlbGYuYm9sZChuYW1lKSArICcgPSAnICsgcmVhbG5hbWUKICAgICAgICBpZiBpbnNwZWN0LmlzZnVuY3Rpb24ob2JqZWN0KToKICAgICAgICAgICAgYXJncywgdmFyYXJncywgdmFya3csIGRlZmF1bHRzID0gaW5zcGVjdC5nZXRhcmdzcGVjKG9iamVjdCkKICAgICAgICAgICAgYXJnc3BlYyA9IGluc3BlY3QuZm9ybWF0YXJnc3BlYygKICAgICAgICAgICAgICAgIGFyZ3MsIHZhcmFyZ3MsIHZhcmt3LCBkZWZhdWx0cywgZm9ybWF0dmFsdWU9c2VsZi5mb3JtYXR2YWx1ZSkKICAgICAgICAgICAgaWYgcmVhbG5hbWUgPT0gJzxsYW1iZGE+JzoKICAgICAgICAgICAgICAgIHRpdGxlID0gJ2xhbWJkYScKICAgICAgICAgICAgICAgIGFyZ3NwZWMgPSBhcmdzcGVjWzE6LTFdICMgcmVtb3ZlIHBhcmVudGhlc2VzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYXJnc3BlYyA9ICcoLi4uKScKICAgICAgICBkZWNsID0gdGl0bGUgKyBhcmdzcGVjICsgbm90ZQoKICAgICAgICBpZiBza2lwZG9jczoKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZG9jID0gZ2V0ZG9jKG9iamVjdCkgb3IgJycKICAgICAgICAgICAgcmV0dXJuIGRlY2wgKyAnXG4nICsgKGRvYyBhbmQgcnN0cmlwKHNlbGYuaW5kZW50KGRvYykpICsgJ1xuJykKCiAgICBkZWYgZG9jb3RoZXIoc2VsZiwgb2JqZWN0LCBuYW1lPU5vbmUsIG1vZD1Ob25lLCBtYXhsZW49Tm9uZSwgZG9jPU5vbmUpOgogICAgICAgICIiIlByb2R1Y2UgdGV4dCBkb2N1bWVudGF0aW9uIGZvciBhIGRhdGEgb2JqZWN0LiIiIgogICAgICAgIHJlcHIgPSBzZWxmLnJlcHIob2JqZWN0KQogICAgICAgIGlmIG1heGxlbjoKICAgICAgICAgICAgbGluZSA9IChuYW1lIGFuZCBuYW1lICsgJyA9ICcgb3IgJycpICsgcmVwcgogICAgICAgICAgICBjaG9wID0gbWF4bGVuIC0gbGVuKGxpbmUpCiAgICAgICAgICAgIGlmIGNob3AgPCAwOiByZXByID0gcmVwcls6Y2hvcF0gKyAnLi4uJwogICAgICAgIGxpbmUgPSAobmFtZSBhbmQgc2VsZi5ib2xkKG5hbWUpICsgJyA9ICcgb3IgJycpICsgcmVwcgogICAgICAgIGlmIGRvYyBpcyBub3QgTm9uZToKICAgICAgICAgICAgbGluZSArPSAnXG4nICsgc2VsZi5pbmRlbnQoc3RyKGRvYykpCiAgICAgICAgcmV0dXJuIGxpbmUKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHVzZXIgaW50ZXJmYWNlcwoKZGVmIHBhZ2VyKHRleHQpOgogICAgIiIiVGhlIGZpcnN0IHRpbWUgdGhpcyBpcyBjYWxsZWQsIGRldGVybWluZSB3aGF0IGtpbmQgb2YgcGFnZXIgdG8gdXNlLiIiIgogICAgZ2xvYmFsIHBhZ2VyCiAgICBwYWdlciA9IGdldHBhZ2VyKCkKICAgIHBhZ2VyKHRleHQpCgpkZWYgZ2V0cGFnZXIoKToKICAgICIiIkRlY2lkZSB3aGF0IG1ldGhvZCB0byB1c2UgZm9yIHBhZ2luZyB0aHJvdWdoIHRleHQuIiIiCiAgICBpZiB0eXBlKHN5cy5zdGRvdXQpIGlzIG5vdCB0eXBlcy5GaWxlVHlwZToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgbm90IHN5cy5zdGRpbi5pc2F0dHkoKSBvciBub3Qgc3lzLnN0ZG91dC5pc2F0dHkoKToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgb3MuZW52aXJvbi5nZXQoJ1RFUk0nKSBpbiBbJ2R1bWInLCAnZW1hY3MnXToKICAgICAgICByZXR1cm4gcGxhaW5wYWdlcgogICAgaWYgJ1BBR0VSJyBpbiBvcy5lbnZpcm9uOgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOiAjIHBpcGVzIGNvbXBsZXRlbHkgYnJva2VuIGluIFdpbmRvd3MKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiB0ZW1wZmlsZXBhZ2VyKHBsYWluKHRleHQpLCBvcy5lbnZpcm9uWydQQUdFUiddKQogICAgICAgIGVsaWYgb3MuZW52aXJvbi5nZXQoJ1RFUk0nKSBpbiBbJ2R1bWInLCAnZW1hY3MnXToKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIocGxhaW4odGV4dCksIG9zLmVudmlyb25bJ1BBR0VSJ10pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgb3MuZW52aXJvblsnUEFHRVInXSkKICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInIG9yIHN5cy5wbGF0Zm9ybS5zdGFydHN3aXRoKCdvczInKToKICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHRlbXBmaWxlcGFnZXIocGxhaW4odGV4dCksICdtb3JlIDwnKQogICAgaWYgaGFzYXR0cihvcywgJ3N5c3RlbScpIGFuZCBvcy5zeXN0ZW0oJyhsZXNzKSAyPi9kZXYvbnVsbCcpID09IDA6CiAgICAgICAgcmV0dXJuIGxhbWJkYSB0ZXh0OiBwaXBlcGFnZXIodGV4dCwgJ2xlc3MnKQoKICAgIGltcG9ydCB0ZW1wZmlsZQogICAgKGZkLCBmaWxlbmFtZSkgPSB0ZW1wZmlsZS5ta3N0ZW1wKCkKICAgIG9zLmNsb3NlKGZkKQogICAgdHJ5OgogICAgICAgIGlmIGhhc2F0dHIob3MsICdzeXN0ZW0nKSBhbmQgb3Muc3lzdGVtKCdtb3JlICVzJyAlIGZpbGVuYW1lKSA9PSAwOgogICAgICAgICAgICByZXR1cm4gbGFtYmRhIHRleHQ6IHBpcGVwYWdlcih0ZXh0LCAnbW9yZScpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHR0eXBhZ2VyCiAgICBmaW5hbGx5OgogICAgICAgIG9zLnVubGluayhmaWxlbmFtZSkKCmRlZiBwbGFpbih0ZXh0KToKICAgICIiIlJlbW92ZSBib2xkZmFjZSBmb3JtYXR0aW5nIGZyb20gdGV4dC4iIiIKICAgIHJldHVybiByZS5zdWIoJy5cYicsICcnLCB0ZXh0KQoKZGVmIHBpcGVwYWdlcih0ZXh0LCBjbWQpOgogICAgIiIiUGFnZSB0aHJvdWdoIHRleHQgYnkgZmVlZGluZyBpdCB0byBhbm90aGVyIHByb2dyYW0uIiIiCiAgICBwaXBlID0gb3MucG9wZW4oY21kLCAndycpCiAgICB0cnk6CiAgICAgICAgcGlwZS53cml0ZSh0ZXh0KQogICAgICAgIHBpcGUuY2xvc2UoKQogICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgcGFzcyAjIElnbm9yZSBicm9rZW4gcGlwZXMgY2F1c2VkIGJ5IHF1aXR0aW5nIHRoZSBwYWdlciBwcm9ncmFtLgoKZGVmIHRlbXBmaWxlcGFnZXIodGV4dCwgY21kKToKICAgICIiIlBhZ2UgdGhyb3VnaCB0ZXh0IGJ5IGludm9raW5nIGEgcHJvZ3JhbSBvbiBhIHRlbXBvcmFyeSBmaWxlLiIiIgogICAgaW1wb3J0IHRlbXBmaWxlCiAgICBmaWxlbmFtZSA9IHRlbXBmaWxlLm1rdGVtcCgpCiAgICBmaWxlID0gb3BlbihmaWxlbmFtZSwgJ3cnKQogICAgZmlsZS53cml0ZSh0ZXh0KQogICAgZmlsZS5jbG9zZSgpCiAgICB0cnk6CiAgICAgICAgb3Muc3lzdGVtKGNtZCArICcgJyArIGZpbGVuYW1lKQogICAgZmluYWxseToKICAgICAgICBvcy51bmxpbmsoZmlsZW5hbWUpCgpkZWYgdHR5cGFnZXIodGV4dCk6CiAgICAiIiJQYWdlIHRocm91Z2ggdGV4dCBvbiBhIHRleHQgdGVybWluYWwuIiIiCiAgICBsaW5lcyA9IHNwbGl0KHBsYWluKHRleHQpLCAnXG4nKQogICAgdHJ5OgogICAgICAgIGltcG9ydCB0dHkKICAgICAgICBmZCA9IHN5cy5zdGRpbi5maWxlbm8oKQogICAgICAgIG9sZCA9IHR0eS50Y2dldGF0dHIoZmQpCiAgICAgICAgdHR5LnNldGNicmVhayhmZCkKICAgICAgICBnZXRjaGFyID0gbGFtYmRhOiBzeXMuc3RkaW4ucmVhZCgxKQogICAgZXhjZXB0IChJbXBvcnRFcnJvciwgQXR0cmlidXRlRXJyb3IpOgogICAgICAgIHR0eSA9IE5vbmUKICAgICAgICBnZXRjaGFyID0gbGFtYmRhOiBzeXMuc3RkaW4ucmVhZGxpbmUoKVs6LTFdWzoxXQoKICAgIHRyeToKICAgICAgICByID0gaW5jID0gb3MuZW52aXJvbi5nZXQoJ0xJTkVTJywgMjUpIC0gMQogICAgICAgIHN5cy5zdGRvdXQud3JpdGUoam9pbihsaW5lc1s6aW5jXSwgJ1xuJykgKyAnXG4nKQogICAgICAgIHdoaWxlIGxpbmVzW3I6XToKICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnLS0gbW9yZSAtLScpCiAgICAgICAgICAgIHN5cy5zdGRvdXQuZmx1c2goKQogICAgICAgICAgICBjID0gZ2V0Y2hhcigpCgogICAgICAgICAgICBpZiBjIGluIFsncScsICdRJ106CiAgICAgICAgICAgICAgICBzeXMuc3Rkb3V0LndyaXRlKCdcciAgICAgICAgICBccicpCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBlbGlmIGMgaW4gWydccicsICdcbiddOgogICAgICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXHIgICAgICAgICAgXHInICsgbGluZXNbcl0gKyAnXG4nKQogICAgICAgICAgICAgICAgciA9IHIgKyAxCiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBpZiBjIGluIFsnYicsICdCJywgJ1x4MWInXToKICAgICAgICAgICAgICAgIHIgPSByIC0gaW5jIC0gaW5jCiAgICAgICAgICAgICAgICBpZiByIDwgMDogciA9IDAKICAgICAgICAgICAgc3lzLnN0ZG91dC53cml0ZSgnXG4nICsgam9pbihsaW5lc1tyOnIraW5jXSwgJ1xuJykgKyAnXG4nKQogICAgICAgICAgICByID0gciArIGluYwoKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgdHR5OgogICAgICAgICAgICB0dHkudGNzZXRhdHRyKGZkLCB0dHkuVENTQUZMVVNILCBvbGQpCgpkZWYgcGxhaW5wYWdlcih0ZXh0KToKICAgICIiIlNpbXBseSBwcmludCB1bmZvcm1hdHRlZCB0ZXh0LiAgVGhpcyBpcyB0aGUgdWx0aW1hdGUgZmFsbGJhY2suIiIiCiAgICBzeXMuc3Rkb3V0LndyaXRlKHBsYWluKHRleHQpKQoKZGVmIGRlc2NyaWJlKHRoaW5nKToKICAgICIiIlByb2R1Y2UgYSBzaG9ydCBkZXNjcmlwdGlvbiBvZiB0aGUgZ2l2ZW4gdGhpbmcuIiIiCiAgICBpZiBpbnNwZWN0LmlzbW9kdWxlKHRoaW5nKToKICAgICAgICBpZiB0aGluZy5fX25hbWVfXyBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CiAgICAgICAgICAgIHJldHVybiAnYnVpbHQtaW4gbW9kdWxlICcgKyB0aGluZy5fX25hbWVfXwogICAgICAgIGlmIGhhc2F0dHIodGhpbmcsICdfX3BhdGhfXycpOgogICAgICAgICAgICByZXR1cm4gJ3BhY2thZ2UgJyArIHRoaW5nLl9fbmFtZV9fCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuICdtb2R1bGUgJyArIHRoaW5nLl9fbmFtZV9fCiAgICBpZiBpbnNwZWN0LmlzYnVpbHRpbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdidWlsdC1pbiBmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNjbGFzcyh0aGluZyk6CiAgICAgICAgcmV0dXJuICdjbGFzcyAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNmdW5jdGlvbih0aGluZyk6CiAgICAgICAgcmV0dXJuICdmdW5jdGlvbiAnICsgdGhpbmcuX19uYW1lX18KICAgIGlmIGluc3BlY3QuaXNtZXRob2QodGhpbmcpOgogICAgICAgIHJldHVybiAnbWV0aG9kICcgKyB0aGluZy5fX25hbWVfXwogICAgaWYgdHlwZSh0aGluZykgaXMgdHlwZXMuSW5zdGFuY2VUeXBlOgogICAgICAgIHJldHVybiAnaW5zdGFuY2Ugb2YgJyArIHRoaW5nLl9fY2xhc3NfXy5fX25hbWVfXwogICAgcmV0dXJuIHR5cGUodGhpbmcpLl9fbmFtZV9fCgpkZWYgbG9jYXRlKHBhdGgsIGZvcmNlbG9hZD0wKToKICAgICIiIkxvY2F0ZSBhbiBvYmplY3QgYnkgbmFtZSBvciBkb3R0ZWQgcGF0aCwgaW1wb3J0aW5nIGFzIG5lY2Vzc2FyeS4iIiIKICAgIHBhcnRzID0gW3BhcnQgZm9yIHBhcnQgaW4gc3BsaXQocGF0aCwgJy4nKSBpZiBwYXJ0XQogICAgbW9kdWxlLCBuID0gTm9uZSwgMAogICAgd2hpbGUgbiA8IGxlbihwYXJ0cyk6CiAgICAgICAgbmV4dG1vZHVsZSA9IHNhZmVpbXBvcnQoam9pbihwYXJ0c1s6bisxXSwgJy4nKSwgZm9yY2Vsb2FkKQogICAgICAgIGlmIG5leHRtb2R1bGU6IG1vZHVsZSwgbiA9IG5leHRtb2R1bGUsIG4gKyAxCiAgICAgICAgZWxzZTogYnJlYWsKICAgIGlmIG1vZHVsZToKICAgICAgICBvYmplY3QgPSBtb2R1bGUKICAgICAgICBmb3IgcGFydCBpbiBwYXJ0c1tuOl06CiAgICAgICAgICAgIHRyeTogb2JqZWN0ID0gZ2V0YXR0cihvYmplY3QsIHBhcnQpCiAgICAgICAgICAgIGV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjogcmV0dXJuIE5vbmUKICAgICAgICByZXR1cm4gb2JqZWN0CiAgICBlbHNlOgogICAgICAgIGlmIGhhc2F0dHIoX19idWlsdGluX18sIHBhdGgpOgogICAgICAgICAgICByZXR1cm4gZ2V0YXR0cihfX2J1aWx0aW5fXywgcGF0aCkKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGludGVyYWN0aXZlIGludGVycHJldGVyIGludGVyZmFjZQoKdGV4dCA9IFRleHREb2MoKQpodG1sID0gSFRNTERvYygpCgpkZWYgcmVzb2x2ZSh0aGluZywgZm9yY2Vsb2FkPTApOgogICAgIiIiR2l2ZW4gYW4gb2JqZWN0IG9yIGEgcGF0aCB0byBhbiBvYmplY3QsIGdldCB0aGUgb2JqZWN0IGFuZCBpdHMgbmFtZS4iIiIKICAgIGlmIGlzaW5zdGFuY2UodGhpbmcsIHN0cik6CiAgICAgICAgb2JqZWN0ID0gbG9jYXRlKHRoaW5nLCBmb3JjZWxvYWQpCiAgICAgICAgaWYgbm90IG9iamVjdDoKICAgICAgICAgICAgcmFpc2UgSW1wb3J0RXJyb3IsICdubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXInICUgdGhpbmcKICAgICAgICByZXR1cm4gb2JqZWN0LCB0aGluZwogICAgZWxzZToKICAgICAgICByZXR1cm4gdGhpbmcsIGdldGF0dHIodGhpbmcsICdfX25hbWVfXycsIE5vbmUpCgpkZWYgZG9jKHRoaW5nLCB0aXRsZT0nUHl0aG9uIExpYnJhcnkgRG9jdW1lbnRhdGlvbjogJXMnLCBmb3JjZWxvYWQ9MCk6CiAgICAiIiJEaXNwbGF5IHRleHQgZG9jdW1lbnRhdGlvbiwgZ2l2ZW4gYW4gb2JqZWN0IG9yIGEgcGF0aCB0byBhbiBvYmplY3QuIiIiCiAgICB0cnk6CiAgICAgICAgb2JqZWN0LCBuYW1lID0gcmVzb2x2ZSh0aGluZywgZm9yY2Vsb2FkKQogICAgICAgIGRlc2MgPSBkZXNjcmliZShvYmplY3QpCiAgICAgICAgbW9kdWxlID0gaW5zcGVjdC5nZXRtb2R1bGUob2JqZWN0KQogICAgICAgIGlmIG5hbWUgYW5kICcuJyBpbiBuYW1lOgogICAgICAgICAgICBkZXNjICs9ICcgaW4gJyArIG5hbWVbOm5hbWUucmZpbmQoJy4nKV0KICAgICAgICBlbGlmIG1vZHVsZSBhbmQgbW9kdWxlIGlzIG5vdCBvYmplY3Q6CiAgICAgICAgICAgIGRlc2MgKz0gJyBpbiBtb2R1bGUgJyArIG1vZHVsZS5fX25hbWVfXwogICAgICAgIHBhZ2VyKHRpdGxlICUgZGVzYyArICdcblxuJyArIHRleHQuZG9jdW1lbnQob2JqZWN0LCBuYW1lKSkKICAgIGV4Y2VwdCAoSW1wb3J0RXJyb3IsIEVycm9yRHVyaW5nSW1wb3J0KSwgdmFsdWU6CiAgICAgICAgcHJpbnQgdmFsdWUKCmRlZiB3cml0ZWRvYyh0aGluZywgZm9yY2Vsb2FkPTApOgogICAgIiIiV3JpdGUgSFRNTCBkb2N1bWVudGF0aW9uIHRvIGEgZmlsZSBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIiIiCiAgICB0cnk6CiAgICAgICAgb2JqZWN0LCBuYW1lID0gcmVzb2x2ZSh0aGluZywgZm9yY2Vsb2FkKQogICAgICAgIHBhZ2UgPSBodG1sLnBhZ2UoZGVzY3JpYmUob2JqZWN0KSwgaHRtbC5kb2N1bWVudChvYmplY3QsIG5hbWUpKQogICAgICAgIGZpbGUgPSBvcGVuKG5hbWUgKyAnLmh0bWwnLCAndycpCiAgICAgICAgZmlsZS53cml0ZShwYWdlKQogICAgICAgIGZpbGUuY2xvc2UoKQogICAgICAgIHByaW50ICd3cm90ZScsIG5hbWUgKyAnLmh0bWwnCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBFcnJvckR1cmluZ0ltcG9ydCksIHZhbHVlOgogICAgICAgIHByaW50IHZhbHVlCgpkZWYgd3JpdGVkb2NzKGRpciwgcGtncGF0aD0nJywgZG9uZT1Ob25lKToKICAgICIiIldyaXRlIG91dCBIVE1MIGRvY3VtZW50YXRpb24gZm9yIGFsbCBtb2R1bGVzIGluIGEgZGlyZWN0b3J5IHRyZWUuIiIiCiAgICBpZiBkb25lIGlzIE5vbmU6IGRvbmUgPSB7fQogICAgZm9yIGZpbGUgaW4gb3MubGlzdGRpcihkaXIpOgogICAgICAgIHBhdGggPSBvcy5wYXRoLmpvaW4oZGlyLCBmaWxlKQogICAgICAgIGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgd3JpdGVkb2NzKHBhdGgsIHBrZ3BhdGggKyBmaWxlICsgJy4nLCBkb25lKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2ZpbGUocGF0aCk6CiAgICAgICAgICAgIG1vZG5hbWUgPSBpbnNwZWN0LmdldG1vZHVsZW5hbWUocGF0aCkKICAgICAgICAgICAgaWYgbW9kbmFtZToKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgPT0gJ19faW5pdF9fJzoKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gcGtncGF0aFs6LTFdICMgcmVtb3ZlIHRyYWlsaW5nIHBlcmlvZAogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gcGtncGF0aCArIG1vZG5hbWUKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgbm90IGluIGRvbmU6CiAgICAgICAgICAgICAgICAgICAgZG9uZVttb2RuYW1lXSA9IDEKICAgICAgICAgICAgICAgICAgICB3cml0ZWRvYyhtb2RuYW1lKQoKY2xhc3MgSGVscGVyOgogICAga2V5d29yZHMgPSB7CiAgICAgICAgJ2FuZCc6ICdCT09MRUFOJywKICAgICAgICAnYXNzZXJ0JzogKCdyZWYvYXNzZXJ0JywgJycpLAogICAgICAgICdicmVhayc6ICgncmVmL2JyZWFrJywgJ3doaWxlIGZvcicpLAogICAgICAgICdjbGFzcyc6ICgncmVmL2NsYXNzJywgJ0NMQVNTRVMgU1BFQ0lBTE1FVEhPRFMnKSwKICAgICAgICAnY29udGludWUnOiAoJ3JlZi9jb250aW51ZScsICd3aGlsZSBmb3InKSwKICAgICAgICAnZGVmJzogKCdyZWYvZnVuY3Rpb24nLCAnJyksCiAgICAgICAgJ2RlbCc6ICgncmVmL2RlbCcsICdCQVNJQ01FVEhPRFMnKSwKICAgICAgICAnZWxpZic6ICdpZicsCiAgICAgICAgJ2Vsc2UnOiAoJ3JlZi9pZicsICd3aGlsZSBmb3InKSwKICAgICAgICAnZXhjZXB0JzogJ3RyeScsCiAgICAgICAgJ2V4ZWMnOiAoJ3JlZi9leGVjJywgJycpLAogICAgICAgICdmaW5hbGx5JzogJ3RyeScsCiAgICAgICAgJ2Zvcic6ICgncmVmL2ZvcicsICdicmVhayBjb250aW51ZSB3aGlsZScpLAogICAgICAgICdmcm9tJzogJ2ltcG9ydCcsCiAgICAgICAgJ2dsb2JhbCc6ICgncmVmL2dsb2JhbCcsICdOQU1FU1BBQ0VTJyksCiAgICAgICAgJ2lmJzogKCdyZWYvaWYnLCAnVFJVVEhWQUxVRScpLAogICAgICAgICdpbXBvcnQnOiAoJ3JlZi9pbXBvcnQnLCAnTU9EVUxFUycpLAogICAgICAgICdpbic6ICgncmVmL2NvbXBhcmlzb25zJywgJ1NFUVVFTkNFTUVUSE9EUzInKSwKICAgICAgICAnaXMnOiAnQ09NUEFSSVNPTicsCiAgICAgICAgJ2xhbWJkYSc6ICgncmVmL2xhbWJkYScsICdGVU5DVElPTlMnKSwKICAgICAgICAnbm90JzogJ0JPT0xFQU4nLAogICAgICAgICdvcic6ICdCT09MRUFOJywKICAgICAgICAncGFzcyc6ICdQQVNTJywKICAgICAgICAncHJpbnQnOiAoJ3JlZi9wcmludCcsICcnKSwKICAgICAgICAncmFpc2UnOiAoJ3JlZi9yYWlzZScsICdFWENFUFRJT05TJyksCiAgICAgICAgJ3JldHVybic6ICgncmVmL3JldHVybicsICdGVU5DVElPTlMnKSwKICAgICAgICAndHJ5JzogKCdyZWYvdHJ5JywgJ0VYQ0VQVElPTlMnKSwKICAgICAgICAnd2hpbGUnOiAoJ3JlZi93aGlsZScsICdicmVhayBjb250aW51ZSBpZiBUUlVUSFZBTFVFJyksCiAgICAgICAgJ3lpZWxkJzogKCdyZWYveWllbGQnLCAnJyksCiAgICB9CgogICAgdG9waWNzID0gewogICAgICAgICdUWVBFUyc6ICgncmVmL3R5cGVzJywgJ1NUUklOR1MgVU5JQ09ERSBOVU1CRVJTIFNFUVVFTkNFUyBNQVBQSU5HUyBGVU5DVElPTlMgQ0xBU1NFUyBNT0RVTEVTIEZJTEVTIGluc3BlY3QnKSwKICAgICAgICAnU1RSSU5HUyc6ICgncmVmL3N0cmluZ3MnLCAnc3RyIFVOSUNPREUgU0VRVUVOQ0VTIFNUUklOR01FVEhPRFMgRk9STUFUVElORyBUWVBFUycpLAogICAgICAgICdTVFJJTkdNRVRIT0RTJzogKCdsaWIvc3RyaW5nLW1ldGhvZHMnLCAnU1RSSU5HUyBGT1JNQVRUSU5HJyksCiAgICAgICAgJ0ZPUk1BVFRJTkcnOiAoJ2xpYi90eXBlc3NlcS1zdHJpbmdzJywgJ09QRVJBVE9SUycpLAogICAgICAgICdVTklDT0RFJzogKCdyZWYvc3RyaW5ncycsICdlbmNvZGluZ3MgdW5pY29kZSBUWVBFUyBTVFJJTkcnKSwKICAgICAgICAnTlVNQkVSUyc6ICgncmVmL251bWJlcnMnLCAnSU5URUdFUiBGTE9BVCBDT01QTEVYIFRZUEVTJyksCiAgICAgICAgJ0lOVEVHRVInOiAoJ3JlZi9pbnRlZ2VycycsICdpbnQgcmFuZ2UnKSwKICAgICAgICAnRkxPQVQnOiAoJ3JlZi9mbG9hdGluZycsICdmbG9hdCBtYXRoJyksCiAgICAgICAgJ0NPTVBMRVgnOiAoJ3JlZi9pbWFnaW5hcnknLCAnY29tcGxleCBjbWF0aCcpLAogICAgICAgICdTRVFVRU5DRVMnOiAoJ2xpYi90eXBlc3NlcScsICdTVFJJTkdNRVRIT0RTIEZPUk1BVFRJTkcgeHJhbmdlIExJU1RTJyksCiAgICAgICAgJ01BUFBJTkdTJzogJ0RJQ1RJT05BUklFUycsCiAgICAgICAgJ0ZVTkNUSU9OUyc6ICgnbGliL3R5cGVzZnVuY3Rpb25zJywgJ2RlZiBUWVBFUycpLAogICAgICAgICdNRVRIT0RTJzogKCdsaWIvdHlwZXNtZXRob2RzJywgJ2NsYXNzIGRlZiBDTEFTU0VTIFRZUEVTJyksCiAgICAgICAgJ0NPREVPQkpFQ1RTJzogKCdsaWIvYmx0aW4tY29kZS1vYmplY3RzJywgJ2NvbXBpbGUgRlVOQ1RJT05TIFRZUEVTJyksCiAgICAgICAgJ1RZUEVPQkpFQ1RTJzogKCdsaWIvYmx0aW4tdHlwZS1vYmplY3RzJywgJ3R5cGVzIFRZUEVTJyksCiAgICAgICAgJ0ZSQU1FT0JKRUNUUyc6ICdUWVBFUycsCiAgICAgICAgJ1RSQUNFQkFDS1MnOiAnVFlQRVMnLAogICAgICAgICdOT05FJzogKCdsaWIvYmx0aW4tbnVsbC1vYmplY3QnLCAnJyksCiAgICAgICAgJ0VMTElQU0lTJzogKCdsaWIvYmx0aW4tZWxsaXBzaXMtb2JqZWN0JywgJ1NMSUNJTkdTJyksCiAgICAgICAgJ0ZJTEVTJzogKCdsaWIvYmx0aW4tZmlsZS1vYmplY3RzJywgJycpLAogICAgICAgICdTUEVDSUFMQVRUUklCVVRFUyc6ICgnbGliL3NwZWNpYWxhdHRycycsICcnKSwKICAgICAgICAnQ0xBU1NFUyc6ICgncmVmL3R5cGVzJywgJ2NsYXNzIFNQRUNJQUxNRVRIT0RTIFBSSVZBVEVOQU1FUycpLAogICAgICAgICdNT0RVTEVTJzogKCdsaWIvdHlwZXNtb2R1bGVzJywgJ2ltcG9ydCcpLAogICAgICAgICdQQUNLQUdFUyc6ICdpbXBvcnQnLAogICAgICAgICdFWFBSRVNTSU9OUyc6ICgncmVmL3N1bW1hcnknLCAnbGFtYmRhIG9yIGFuZCBub3QgaW4gaXMgQk9PTEVBTiBDT01QQVJJU09OIEJJVFdJU0UgU0hJRlRJTkcgQklOQVJZIEZPUk1BVFRJTkcgUE9XRVIgVU5BUlkgQVRUUklCVVRFUyBTVUJTQ1JJUFRTIFNMSUNJTkdTIENBTExTIFRVUExFUyBMSVNUUyBESUNUSU9OQVJJRVMgQkFDS1FVT1RFUycpLAogICAgICAgICdPUEVSQVRPUlMnOiAnRVhQUkVTU0lPTlMnLAogICAgICAgICdQUkVDRURFTkNFJzogJ0VYUFJFU1NJT05TJywKICAgICAgICAnT0JKRUNUUyc6ICgncmVmL29iamVjdHMnLCAnVFlQRVMnKSwKICAgICAgICAnU1BFQ0lBTE1FVEhPRFMnOiAoJ3JlZi9zcGVjaWFsbmFtZXMnLCAnQkFTSUNNRVRIT0RTIEFUVFJJQlVURU1FVEhPRFMgQ0FMTEFCTEVNRVRIT0RTIFNFUVVFTkNFTUVUSE9EUzEgTUFQUElOR01FVEhPRFMgU0VRVUVOQ0VNRVRIT0RTMiBOVU1CRVJNRVRIT0RTIENMQVNTRVMnKSwKICAgICAgICAnQkFTSUNNRVRIT0RTJzogKCdyZWYvY3VzdG9taXphdGlvbicsICdjbXAgaGFzaCByZXByIHN0ciBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdBVFRSSUJVVEVNRVRIT0RTJzogKCdyZWYvYXR0cmlidXRlLWFjY2VzcycsICdBVFRSSUJVVEVTIFNQRUNJQUxNRVRIT0RTJyksCiAgICAgICAgJ0NBTExBQkxFTUVUSE9EUyc6ICgncmVmL2NhbGxhYmxlLXR5cGVzJywgJ0NBTExTIFNQRUNJQUxNRVRIT0RTJyksCiAgICAgICAgJ1NFUVVFTkNFTUVUSE9EUzEnOiAoJ3JlZi9zZXF1ZW5jZS10eXBlcycsICdTRVFVRU5DRVMgU0VRVUVOQ0VNRVRIT0RTMiBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdTRVFVRU5DRU1FVEhPRFMyJzogKCdyZWYvc2VxdWVuY2UtbWV0aG9kcycsICdTRVFVRU5DRVMgU0VRVUVOQ0VNRVRIT0RTMSBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdNQVBQSU5HTUVUSE9EUyc6ICgncmVmL3NlcXVlbmNlLXR5cGVzJywgJ01BUFBJTkdTIFNQRUNJQUxNRVRIT0RTJyksCiAgICAgICAgJ05VTUJFUk1FVEhPRFMnOiAoJ3JlZi9udW1lcmljLXR5cGVzJywgJ05VTUJFUlMgQVVHTUVOVEVEQVNTSUdOTUVOVCBTUEVDSUFMTUVUSE9EUycpLAogICAgICAgICdFWEVDVVRJT04nOiAoJ3JlZi9leGVjZnJhbWVzJywgJycpLAogICAgICAgICdOQU1FU1BBQ0VTJzogKCdyZWYvZXhlY2ZyYW1lcycsICdnbG9iYWwgQVNTSUdOTUVOVCBERUxFVElPTicpLAogICAgICAgICdTQ09QSU5HJzogJ05BTUVTUEFDRVMnLAogICAgICAgICdGUkFNRVMnOiAnTkFNRVNQQUNFUycsCiAgICAgICAgJ0VYQ0VQVElPTlMnOiAoJ3JlZi9leGNlcHRpb25zJywgJ3RyeSBleGNlcHQgZmluYWxseSByYWlzZScpLAogICAgICAgICdDT0VSQ0lPTlMnOiAnQ09OVkVSU0lPTlMnLAogICAgICAgICdDT05WRVJTSU9OUyc6ICgncmVmL2NvbnZlcnNpb25zJywgJycpLAogICAgICAgICdJREVOVElGSUVSUyc6ICgncmVmL2lkZW50aWZpZXJzJywgJ2tleXdvcmRzIFNQRUNJQUxJREVOVElGSUVSUycpLAogICAgICAgICdTUEVDSUFMSURFTlRJRklFUlMnOiAoJ3JlZi9pZC1jbGFzc2VzJywgJycpLAogICAgICAgICdQUklWQVRFTkFNRVMnOiAoJ3JlZi9hdG9tLWlkZW50aWZpZXJzJywgJycpLAogICAgICAgICdMSVRFUkFMUyc6ICgncmVmL2F0b20tbGl0ZXJhbHMnLCAnU1RSSU5HUyBCQUNLUVVPVEVTIE5VTUJFUlMgVFVQTEVMSVRFUkFMUyBMSVNUTElURVJBTFMgRElDVElPTkFSWUxJVEVSQUxTJyksCiAgICAgICAgJ1RVUExFUyc6ICdTRVFVRU5DRVMnLAogICAgICAgICdUVVBMRUxJVEVSQUxTJzogKCdyZWYvZXhwcmxpc3RzJywgJ1RVUExFUyBMSVRFUkFMUycpLAogICAgICAgICdMSVNUUyc6ICgnbGliL3R5cGVzc2VxLW11dGFibGUnLCAnTElTVExJVEVSQUxTJyksCiAgICAgICAgJ0xJU1RMSVRFUkFMUyc6ICgncmVmL2xpc3RzJywgJ0xJU1RTIExJVEVSQUxTJyksCiAgICAgICAgJ0RJQ1RJT05BUklFUyc6ICgnbGliL3R5cGVzbWFwcGluZycsICdESUNUSU9OQVJZTElURVJBTFMnKSwKICAgICAgICAnRElDVElPTkFSWUxJVEVSQUxTJzogKCdyZWYvZGljdCcsICdESUNUSU9OQVJJRVMgTElURVJBTFMnKSwKICAgICAgICAnQkFDS1FVT1RFUyc6ICgncmVmL3N0cmluZy1jb252ZXJzaW9ucycsICdyZXByIHN0ciBTVFJJTkdTIExJVEVSQUxTJyksCiAgICAgICAgJ0FUVFJJQlVURVMnOiAoJ3JlZi9hdHRyaWJ1dGUtcmVmZXJlbmNlcycsICdnZXRhdHRyIGhhc2F0dHIgc2V0YXR0ciBBVFRSSUJVVEVNRVRIT0RTJyksCiAgICAgICAgJ1NVQlNDUklQVFMnOiAoJ3JlZi9zdWJzY3JpcHRpb25zJywgJ1NFUVVFTkNFTUVUSE9EUzEnKSwKICAgICAgICAnU0xJQ0lOR1MnOiAoJ3JlZi9zbGljaW5ncycsICdTRVFVRU5DRU1FVEhPRFMyJyksCiAgICAgICAgJ0NBTExTJzogKCdyZWYvY2FsbHMnLCAnRVhQUkVTU0lPTlMnKSwKICAgICAgICAnUE9XRVInOiAoJ3JlZi9wb3dlcicsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdVTkFSWSc6ICgncmVmL3VuYXJ5JywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ0JJTkFSWSc6ICgncmVmL2JpbmFyeScsICdFWFBSRVNTSU9OUycpLAogICAgICAgICdTSElGVElORyc6ICgncmVmL3NoaWZ0aW5nJywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ0JJVFdJU0UnOiAoJ3JlZi9iaXR3aXNlJywgJ0VYUFJFU1NJT05TJyksCiAgICAgICAgJ0NPTVBBUklTT04nOiAoJ3JlZi9jb21wYXJpc29ucycsICdFWFBSRVNTSU9OUyBCQVNJQ01FVEhPRFMnKSwKICAgICAgICAnQk9PTEVBTic6ICgncmVmL0Jvb2xlYW5zJywgJ0VYUFJFU1NJT05TIFRSVVRIVkFMVUUnKSwKICAgICAgICAnQVNTRVJUSU9OJzogJ2Fzc2VydCcsCiAgICAgICAgJ0FTU0lHTk1FTlQnOiAoJ3JlZi9hc3NpZ25tZW50JywgJ0FVR01FTlRFREFTU0lHTk1FTlQnKSwKICAgICAgICAnQVVHTUVOVEVEQVNTSUdOTUVOVCc6ICgncmVmL2F1Z2Fzc2lnbicsICdOVU1CRVJNRVRIT0RTJyksCiAgICAgICAgJ0RFTEVUSU9OJzogJ2RlbCcsCiAgICAgICAgJ1BSSU5USU5HJzogJ3ByaW50JywKICAgICAgICAnUkVUVVJOSU5HJzogJ3JldHVybicsCiAgICAgICAgJ0lNUE9SVElORyc6ICdpbXBvcnQnLAogICAgICAgICdDT05ESVRJT05BTCc6ICdpZicsCiAgICAgICAgJ0xPT1BJTkcnOiAoJ3JlZi9jb21wb3VuZCcsICdmb3Igd2hpbGUgYnJlYWsgY29udGludWUnKSwKICAgICAgICAnVFJVVEhWQUxVRSc6ICgnbGliL3RydXRoJywgJ2lmIHdoaWxlIGFuZCBvciBub3QgQkFTSUNNRVRIT0RTJyksCiAgICAgICAgJ0RFQlVHR0lORyc6ICgnbGliL21vZHVsZS1wZGInLCAncGRiJyksCiAgICB9CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGlucHV0LCBvdXRwdXQpOgogICAgICAgIHNlbGYuaW5wdXQgPSBpbnB1dAogICAgICAgIHNlbGYub3V0cHV0ID0gb3V0cHV0CiAgICAgICAgc2VsZi5kb2NkaXIgPSBOb25lCiAgICAgICAgZXhlY2RpciA9IG9zLnBhdGguZGlybmFtZShzeXMuZXhlY3V0YWJsZSkKICAgICAgICBob21lZGlyID0gb3MuZW52aXJvbi5nZXQoJ1BZVEhPTkhPTUUnKQogICAgICAgIGZvciBkaXIgaW4gW29zLmVudmlyb24uZ2V0KCdQWVRIT05ET0NTJyksCiAgICAgICAgICAgICAgICAgICAgaG9tZWRpciBhbmQgb3MucGF0aC5qb2luKGhvbWVkaXIsICdkb2MnKSwKICAgICAgICAgICAgICAgICAgICBvcy5wYXRoLmpvaW4oZXhlY2RpciwgJ2RvYycpLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tZG9jcy0nICsgc3BsaXQoc3lzLnZlcnNpb24pWzBdLAogICAgICAgICAgICAgICAgICAgICcvdXNyL2RvYy9weXRob24tJyArIHNwbGl0KHN5cy52ZXJzaW9uKVswXSwKICAgICAgICAgICAgICAgICAgICAnL3Vzci9kb2MvcHl0aG9uLWRvY3MtJyArIHN5cy52ZXJzaW9uWzozXSwKICAgICAgICAgICAgICAgICAgICAnL3Vzci9kb2MvcHl0aG9uLScgKyBzeXMudmVyc2lvbls6M10sCiAgICAgICAgICAgICAgICAgICAgb3MucGF0aC5qb2luKHN5cy5wcmVmaXgsICdSZXNvdXJjZXMvRW5nbGlzaC5scHJvai9Eb2N1bWVudGF0aW9uJyldOgogICAgICAgICAgICBpZiBkaXIgYW5kIG9zLnBhdGguaXNkaXIob3MucGF0aC5qb2luKGRpciwgJ2xpYicpKToKICAgICAgICAgICAgICAgIHNlbGYuZG9jZGlyID0gZGlyCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIGlmIGluc3BlY3Quc3RhY2soKVsxXVszXSA9PSAnPyc6CiAgICAgICAgICAgIHNlbGYoKQogICAgICAgICAgICByZXR1cm4gJycKICAgICAgICByZXR1cm4gJzxweWRvYy5IZWxwZXIgaW5zdGFuY2U+JwoKICAgIGRlZiBfX2NhbGxfXyhzZWxmLCByZXF1ZXN0PU5vbmUpOgogICAgICAgIGlmIHJlcXVlc3QgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYuaGVscChyZXF1ZXN0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuaW50cm8oKQogICAgICAgICAgICBzZWxmLmludGVyYWN0KCkKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCllvdSBhcmUgbm93IGxlYXZpbmcgaGVscCBhbmQgcmV0dXJuaW5nIHRvIHRoZSBQeXRob24gaW50ZXJwcmV0ZXIuCklmIHlvdSB3YW50IHRvIGFzayBmb3IgaGVscCBvbiBhIHBhcnRpY3VsYXIgb2JqZWN0IGRpcmVjdGx5IGZyb20gdGhlCmludGVycHJldGVyLCB5b3UgY2FuIHR5cGUgImhlbHAob2JqZWN0KSIuICBFeGVjdXRpbmcgImhlbHAoJ3N0cmluZycpIgpoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIHR5cGluZyBhIHBhcnRpY3VsYXIgc3RyaW5nIGF0IHRoZSBoZWxwPiBwcm9tcHQuCicnJykKCiAgICBkZWYgaW50ZXJhY3Qoc2VsZik6CiAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ1xuJykKICAgICAgICB3aGlsZSBUcnVlOgogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnaGVscD4gJykKICAgICAgICAgICAgc2VsZi5vdXRwdXQuZmx1c2goKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gc2VsZi5pbnB1dC5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICBpZiBub3QgcmVxdWVzdDogYnJlYWsKICAgICAgICAgICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OiBicmVhawogICAgICAgICAgICByZXF1ZXN0ID0gc3RyaXAocmVwbGFjZShyZXF1ZXN0LCAnIicsICcnLCAiJyIsICcnKSkKICAgICAgICAgICAgaWYgbG93ZXIocmVxdWVzdCkgaW4gWydxJywgJ3F1aXQnXTogYnJlYWsKICAgICAgICAgICAgc2VsZi5oZWxwKHJlcXVlc3QpCgogICAgZGVmIGhlbHAoc2VsZiwgcmVxdWVzdCk6CiAgICAgICAgaWYgdHlwZShyZXF1ZXN0KSBpcyB0eXBlKCcnKToKICAgICAgICAgICAgaWYgcmVxdWVzdCA9PSAnaGVscCc6IHNlbGYuaW50cm8oKQogICAgICAgICAgICBlbGlmIHJlcXVlc3QgPT0gJ2tleXdvcmRzJzogc2VsZi5saXN0a2V5d29yZHMoKQogICAgICAgICAgICBlbGlmIHJlcXVlc3QgPT0gJ3RvcGljcyc6IHNlbGYubGlzdHRvcGljcygpCiAgICAgICAgICAgIGVsaWYgcmVxdWVzdCA9PSAnbW9kdWxlcyc6IHNlbGYubGlzdG1vZHVsZXMoKQogICAgICAgICAgICBlbGlmIHJlcXVlc3RbOjhdID09ICdtb2R1bGVzICc6CiAgICAgICAgICAgICAgICBzZWxmLmxpc3Rtb2R1bGVzKHNwbGl0KHJlcXVlc3QpWzFdKQogICAgICAgICAgICBlbGlmIHJlcXVlc3QgaW4gc2VsZi5rZXl3b3Jkczogc2VsZi5zaG93dG9waWMocmVxdWVzdCkKICAgICAgICAgICAgZWxpZiByZXF1ZXN0IGluIHNlbGYudG9waWNzOiBzZWxmLnNob3d0b3BpYyhyZXF1ZXN0KQogICAgICAgICAgICBlbGlmIHJlcXVlc3Q6IGRvYyhyZXF1ZXN0LCAnSGVscCBvbiAlczonKQogICAgICAgIGVsaWYgaXNpbnN0YW5jZShyZXF1ZXN0LCBIZWxwZXIpOiBzZWxmKCkKICAgICAgICBlbHNlOiBkb2MocmVxdWVzdCwgJ0hlbHAgb24gJXM6JykKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnXG4nKQoKICAgIGRlZiBpbnRybyhzZWxmKToKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKV2VsY29tZSB0byBQeXRob24gJXMhICBUaGlzIGlzIHRoZSBvbmxpbmUgaGVscCB1dGlsaXR5LgoKSWYgdGhpcyBpcyB5b3VyIGZpcnN0IHRpbWUgdXNpbmcgUHl0aG9uLCB5b3Ugc2hvdWxkIGRlZmluaXRlbHkgY2hlY2sgb3V0CnRoZSB0dXRvcmlhbCBvbiB0aGUgSW50ZXJuZXQgYXQgaHR0cDovL3d3dy5weXRob24ub3JnL2RvYy90dXQvLgoKRW50ZXIgdGhlIG5hbWUgb2YgYW55IG1vZHVsZSwga2V5d29yZCwgb3IgdG9waWMgdG8gZ2V0IGhlbHAgb24gd3JpdGluZwpQeXRob24gcHJvZ3JhbXMgYW5kIHVzaW5nIFB5dGhvbiBtb2R1bGVzLiAgVG8gcXVpdCB0aGlzIGhlbHAgdXRpbGl0eSBhbmQKcmV0dXJuIHRvIHRoZSBpbnRlcnByZXRlciwganVzdCB0eXBlICJxdWl0Ii4KClRvIGdldCBhIGxpc3Qgb2YgYXZhaWxhYmxlIG1vZHVsZXMsIGtleXdvcmRzLCBvciB0b3BpY3MsIHR5cGUgIm1vZHVsZXMiLAoia2V5d29yZHMiLCBvciAidG9waWNzIi4gIEVhY2ggbW9kdWxlIGFsc28gY29tZXMgd2l0aCBhIG9uZS1saW5lIHN1bW1hcnkKb2Ygd2hhdCBpdCBkb2VzOyB0byBsaXN0IHRoZSBtb2R1bGVzIHdob3NlIHN1bW1hcmllcyBjb250YWluIGEgZ2l2ZW4gd29yZApzdWNoIGFzICJzcGFtIiwgdHlwZSAibW9kdWxlcyBzcGFtIi4KJycnICUgc3lzLnZlcnNpb25bOjNdKQoKICAgIGRlZiBsaXN0KHNlbGYsIGl0ZW1zLCBjb2x1bW5zPTQsIHdpZHRoPTgwKToKICAgICAgICBpdGVtcyA9IGl0ZW1zWzpdCiAgICAgICAgaXRlbXMuc29ydCgpCiAgICAgICAgY29sdyA9IHdpZHRoIC8gY29sdW1ucwogICAgICAgIHJvd3MgPSAobGVuKGl0ZW1zKSArIGNvbHVtbnMgLSAxKSAvIGNvbHVtbnMKICAgICAgICBmb3Igcm93IGluIHJhbmdlKHJvd3MpOgogICAgICAgICAgICBmb3IgY29sIGluIHJhbmdlKGNvbHVtbnMpOgogICAgICAgICAgICAgICAgaSA9IGNvbCAqIHJvd3MgKyByb3cKICAgICAgICAgICAgICAgIGlmIGkgPCBsZW4oaXRlbXMpOgogICAgICAgICAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKGl0ZW1zW2ldKQogICAgICAgICAgICAgICAgICAgIGlmIGNvbCA8IGNvbHVtbnMgLSAxOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnICcgKyAnICcgKiAoY29sdy0xIC0gbGVuKGl0ZW1zW2ldKSkpCiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdcbicpCgogICAgZGVmIGxpc3RrZXl3b3JkcyhzZWxmKToKICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnJycKSGVyZSBpcyBhIGxpc3Qgb2YgdGhlIFB5dGhvbiBrZXl3b3Jkcy4gIEVudGVyIGFueSBrZXl3b3JkIHRvIGdldCBtb3JlIGhlbHAuCgonJycpCiAgICAgICAgc2VsZi5saXN0KHNlbGYua2V5d29yZHMua2V5cygpKQoKICAgIGRlZiBsaXN0dG9waWNzKHNlbGYpOgogICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpIZXJlIGlzIGEgbGlzdCBvZiBhdmFpbGFibGUgdG9waWNzLiAgRW50ZXIgYW55IHRvcGljIG5hbWUgdG8gZ2V0IG1vcmUgaGVscC4KCicnJykKICAgICAgICBzZWxmLmxpc3Qoc2VsZi50b3BpY3Mua2V5cygpKQoKICAgIGRlZiBzaG93dG9waWMoc2VsZiwgdG9waWMpOgogICAgICAgIGlmIG5vdCBzZWxmLmRvY2RpcjoKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnClNvcnJ5LCB0b3BpYyBhbmQga2V5d29yZCBkb2N1bWVudGF0aW9uIGlzIG5vdCBhdmFpbGFibGUgYmVjYXVzZSB0aGUgUHl0aG9uCkhUTUwgZG9jdW1lbnRhdGlvbiBmaWxlcyBjb3VsZCBub3QgYmUgZm91bmQuICBJZiB5b3UgaGF2ZSBpbnN0YWxsZWQgdGhlbSwKcGxlYXNlIHNldCB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgUFlUSE9ORE9DUyB0byBpbmRpY2F0ZSB0aGVpciBsb2NhdGlvbi4KJycnKQogICAgICAgICAgICByZXR1cm4KICAgICAgICB0YXJnZXQgPSBzZWxmLnRvcGljcy5nZXQodG9waWMsIHNlbGYua2V5d29yZHMuZ2V0KHRvcGljKSkKICAgICAgICBpZiBub3QgdGFyZ2V0OgogICAgICAgICAgICBzZWxmLm91dHB1dC53cml0ZSgnbm8gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXNcbicgJSByZXByKHRvcGljKSkKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgdHlwZSh0YXJnZXQpIGlzIHR5cGUoJycpOgogICAgICAgICAgICByZXR1cm4gc2VsZi5zaG93dG9waWModGFyZ2V0KQoKICAgICAgICBmaWxlbmFtZSwgeHJlZnMgPSB0YXJnZXQKICAgICAgICBmaWxlbmFtZSA9IHNlbGYuZG9jZGlyICsgJy8nICsgZmlsZW5hbWUgKyAnLmh0bWwnCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlID0gb3BlbihmaWxlbmFtZSkKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCdjb3VsZCBub3QgcmVhZCBkb2NzIGZyb20gJXNcbicgJSBmaWxlbmFtZSkKICAgICAgICAgICAgcmV0dXJuCgogICAgICAgIGRpdnBhdCA9IHJlLmNvbXBpbGUoJzxkaXZbXj5dKm5hdmlnYXQuKj88L2Rpdi4qPz4nLCByZS5JIHwgcmUuUykKICAgICAgICBhZGRycGF0ID0gcmUuY29tcGlsZSgnPGFkZHJlc3MuKj8+Lio/PC9hZGRyZXNzLio/PicsIHJlLkkgfCByZS5TKQogICAgICAgIGRvY3VtZW50ID0gcmUuc3ViKGFkZHJwYXQsICcnLCByZS5zdWIoZGl2cGF0LCAnJywgZmlsZS5yZWFkKCkpKQogICAgICAgIGZpbGUuY2xvc2UoKQoKICAgICAgICBpbXBvcnQgaHRtbGxpYiwgZm9ybWF0dGVyLCBTdHJpbmdJTwogICAgICAgIGJ1ZmZlciA9IFN0cmluZ0lPLlN0cmluZ0lPKCkKICAgICAgICBwYXJzZXIgPSBodG1sbGliLkhUTUxQYXJzZXIoCiAgICAgICAgICAgIGZvcm1hdHRlci5BYnN0cmFjdEZvcm1hdHRlcihmb3JtYXR0ZXIuRHVtYldyaXRlcihidWZmZXIpKSkKICAgICAgICBwYXJzZXIuc3RhcnRfdGFibGUgPSBwYXJzZXIuZG9fcAogICAgICAgIHBhcnNlci5lbmRfdGFibGUgPSBsYW1iZGEgcGFyc2VyPXBhcnNlcjogcGFyc2VyLmRvX3Aoe30pCiAgICAgICAgcGFyc2VyLnN0YXJ0X3RyID0gcGFyc2VyLmRvX2JyCiAgICAgICAgcGFyc2VyLnN0YXJ0X3RkID0gcGFyc2VyLnN0YXJ0X3RoID0gbGFtYmRhIGEsIGI9YnVmZmVyOiBiLndyaXRlKCdcdCcpCiAgICAgICAgcGFyc2VyLmZlZWQoZG9jdW1lbnQpCiAgICAgICAgYnVmZmVyID0gcmVwbGFjZShidWZmZXIuZ2V0dmFsdWUoKSwgJ1x4YTAnLCAnICcsICdcbicsICdcbiAgJykKICAgICAgICBwYWdlcignICAnICsgc3RyaXAoYnVmZmVyKSArICdcbicpCiAgICAgICAgaWYgeHJlZnM6CiAgICAgICAgICAgIGJ1ZmZlciA9IFN0cmluZ0lPLlN0cmluZ0lPKCkKICAgICAgICAgICAgZm9ybWF0dGVyLkR1bWJXcml0ZXIoYnVmZmVyKS5zZW5kX2Zsb3dpbmdfZGF0YSgKICAgICAgICAgICAgICAgICdSZWxhdGVkIGhlbHAgdG9waWNzOiAnICsgam9pbihzcGxpdCh4cmVmcyksICcsICcpICsgJ1xuJykKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJ1xuJXNcbicgJSBidWZmZXIuZ2V0dmFsdWUoKSkKCiAgICBkZWYgbGlzdG1vZHVsZXMoc2VsZiwga2V5PScnKToKICAgICAgICBpZiBrZXk6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpIZXJlIGlzIGEgbGlzdCBvZiBtYXRjaGluZyBtb2R1bGVzLiAgRW50ZXIgYW55IG1vZHVsZSBuYW1lIHRvIGdldCBtb3JlIGhlbHAuCgonJycpCiAgICAgICAgICAgIGFwcm9wb3Moa2V5KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYub3V0cHV0LndyaXRlKCcnJwpQbGVhc2Ugd2FpdCBhIG1vbWVudCB3aGlsZSBJIGdhdGhlciBhIGxpc3Qgb2YgYWxsIGF2YWlsYWJsZSBtb2R1bGVzLi4uCgonJycpCiAgICAgICAgICAgIG1vZHVsZXMgPSB7fQogICAgICAgICAgICBkZWYgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgZGVzYywgbW9kdWxlcz1tb2R1bGVzKToKICAgICAgICAgICAgICAgIGlmIG1vZG5hbWUgYW5kIG1vZG5hbWVbLTk6XSA9PSAnLl9faW5pdF9fJzoKICAgICAgICAgICAgICAgICAgICBtb2RuYW1lID0gbW9kbmFtZVs6LTldICsgJyAocGFja2FnZSknCiAgICAgICAgICAgICAgICBpZiBmaW5kKG1vZG5hbWUsICcuJykgPCAwOgogICAgICAgICAgICAgICAgICAgIG1vZHVsZXNbbW9kbmFtZV0gPSAxCiAgICAgICAgICAgIE1vZHVsZVNjYW5uZXIoKS5ydW4oY2FsbGJhY2spCiAgICAgICAgICAgIHNlbGYubGlzdChtb2R1bGVzLmtleXMoKSkKICAgICAgICAgICAgc2VsZi5vdXRwdXQud3JpdGUoJycnCkVudGVyIGFueSBtb2R1bGUgbmFtZSB0byBnZXQgbW9yZSBoZWxwLiAgT3IsIHR5cGUgIm1vZHVsZXMgc3BhbSIgdG8gc2VhcmNoCmZvciBtb2R1bGVzIHdob3NlIGRlc2NyaXB0aW9ucyBjb250YWluIHRoZSB3b3JkICJzcGFtIi4KJycnKQoKaGVscCA9IEhlbHBlcihzeXMuc3RkaW4sIHN5cy5zdGRvdXQpCgpjbGFzcyBTY2FubmVyOgogICAgIiIiQSBnZW5lcmljIHRyZWUgaXRlcmF0b3IuIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgcm9vdHMsIGNoaWxkcmVuLCBkZXNjZW5kcCk6CiAgICAgICAgc2VsZi5yb290cyA9IHJvb3RzWzpdCiAgICAgICAgc2VsZi5zdGF0ZSA9IFtdCiAgICAgICAgc2VsZi5jaGlsZHJlbiA9IGNoaWxkcmVuCiAgICAgICAgc2VsZi5kZXNjZW5kcCA9IGRlc2NlbmRwCgogICAgZGVmIG5leHQoc2VsZik6CiAgICAgICAgaWYgbm90IHNlbGYuc3RhdGU6CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLnJvb3RzOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgcm9vdCA9IHNlbGYucm9vdHMucG9wKDApCiAgICAgICAgICAgIHNlbGYuc3RhdGUgPSBbKHJvb3QsIHNlbGYuY2hpbGRyZW4ocm9vdCkpXQogICAgICAgIG5vZGUsIGNoaWxkcmVuID0gc2VsZi5zdGF0ZVstMV0KICAgICAgICBpZiBub3QgY2hpbGRyZW46CiAgICAgICAgICAgIHNlbGYuc3RhdGUucG9wKCkKICAgICAgICAgICAgcmV0dXJuIHNlbGYubmV4dCgpCiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbi5wb3AoMCkKICAgICAgICBpZiBzZWxmLmRlc2NlbmRwKGNoaWxkKToKICAgICAgICAgICAgc2VsZi5zdGF0ZS5hcHBlbmQoKGNoaWxkLCBzZWxmLmNoaWxkcmVuKGNoaWxkKSkpCiAgICAgICAgcmV0dXJuIGNoaWxkCgpjbGFzcyBNb2R1bGVTY2FubmVyKFNjYW5uZXIpOgogICAgIiIiQW4gaW50ZXJydXB0aWJsZSBzY2FubmVyIHRoYXQgc2VhcmNoZXMgbW9kdWxlIHN5bm9wc2VzLiIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHJvb3RzID0gbWFwKGxhbWJkYSBkaXI6IChkaXIsICcnKSwgcGF0aGRpcnMoKSkKICAgICAgICBTY2FubmVyLl9faW5pdF9fKHNlbGYsIHJvb3RzLCBzZWxmLnN1Ym1vZHVsZXMsIHNlbGYuaXNuZXdwYWNrYWdlKQogICAgICAgIHNlbGYuaW5vZGVzID0gbWFwKGxhbWJkYSAoZGlyLCBwa2cpOiBvcy5zdGF0KGRpcikuc3RfaW5vLCByb290cykKCiAgICBkZWYgc3VibW9kdWxlcyhzZWxmLCAoZGlyLCBwYWNrYWdlKSk6CiAgICAgICAgY2hpbGRyZW4gPSBbXQogICAgICAgIGZvciBmaWxlIGluIG9zLmxpc3RkaXIoZGlyKToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihkaXIsIGZpbGUpCiAgICAgICAgICAgIGlmIGlzcGFja2FnZShwYXRoKToKICAgICAgICAgICAgICAgIGNoaWxkcmVuLmFwcGVuZCgocGF0aCwgcGFja2FnZSArIChwYWNrYWdlIGFuZCAnLicpICsgZmlsZSkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBjaGlsZHJlbi5hcHBlbmQoKHBhdGgsIHBhY2thZ2UpKQogICAgICAgIGNoaWxkcmVuLnNvcnQoKSAjIHNvIHRoYXQgc3BhbS5weSBjb21lcyBiZWZvcmUgc3BhbS5weWMgb3Igc3BhbS5weW8KICAgICAgICByZXR1cm4gY2hpbGRyZW4KCiAgICBkZWYgaXNuZXdwYWNrYWdlKHNlbGYsIChkaXIsIHBhY2thZ2UpKToKICAgICAgICBpbm9kZSA9IG9zLnBhdGguZXhpc3RzKGRpcikgYW5kIG9zLnN0YXQoZGlyKS5zdF9pbm8KICAgICAgICBpZiBub3QgKG9zLnBhdGguaXNsaW5rKGRpcikgYW5kIGlub2RlIGluIHNlbGYuaW5vZGVzKToKICAgICAgICAgICAgc2VsZi5pbm9kZXMuYXBwZW5kKGlub2RlKSAjIGRldGVjdCBjaXJjdWxhciBzeW1ib2xpYyBsaW5rcwogICAgICAgICAgICByZXR1cm4gaXNwYWNrYWdlKGRpcikKICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgcnVuKHNlbGYsIGNhbGxiYWNrLCBrZXk9Tm9uZSwgY29tcGxldGVyPU5vbmUpOgogICAgICAgIGlmIGtleToga2V5ID0gbG93ZXIoa2V5KQogICAgICAgIHNlbGYucXVpdCA9IEZhbHNlCiAgICAgICAgc2VlbiA9IHt9CgogICAgICAgIGZvciBtb2RuYW1lIGluIHN5cy5idWlsdGluX21vZHVsZV9uYW1lczoKICAgICAgICAgICAgaWYgbW9kbmFtZSAhPSAnX19tYWluX18nOgogICAgICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEKICAgICAgICAgICAgICAgIGlmIGtleSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKE5vbmUsIG1vZG5hbWUsICcnKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBkZXNjID0gc3BsaXQoX19pbXBvcnRfXyhtb2RuYW1lKS5fX2RvY19fIG9yICcnLCAnXG4nKVswXQogICAgICAgICAgICAgICAgICAgIGlmIGZpbmQobG93ZXIobW9kbmFtZSArICcgLSAnICsgZGVzYyksIGtleSkgPj0gMDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soTm9uZSwgbW9kbmFtZSwgZGVzYykKCiAgICAgICAgd2hpbGUgbm90IHNlbGYucXVpdDoKICAgICAgICAgICAgbm9kZSA9IHNlbGYubmV4dCgpCiAgICAgICAgICAgIGlmIG5vdCBub2RlOiBicmVhawogICAgICAgICAgICBwYXRoLCBwYWNrYWdlID0gbm9kZQogICAgICAgICAgICBtb2RuYW1lID0gaW5zcGVjdC5nZXRtb2R1bGVuYW1lKHBhdGgpCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHBhdGgpIGFuZCBtb2RuYW1lOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IHBhY2thZ2UgKyAocGFja2FnZSBhbmQgJy4nKSArIG1vZG5hbWUKICAgICAgICAgICAgICAgIGlmIG5vdCBtb2RuYW1lIGluIHNlZW46CiAgICAgICAgICAgICAgICAgICAgc2Vlblttb2RuYW1lXSA9IDEgIyBpZiB3ZSBzZWUgc3BhbS5weSwgc2tpcCBzcGFtLnB5YwogICAgICAgICAgICAgICAgICAgIGlmIGtleSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCAnJykKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBkZXNjID0gc3lub3BzaXMocGF0aCkgb3IgJycKICAgICAgICAgICAgICAgICAgICAgICAgaWYgZmluZChsb3dlcihtb2RuYW1lICsgJyAtICcgKyBkZXNjKSwga2V5KSA+PSAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2socGF0aCwgbW9kbmFtZSwgZGVzYykKICAgICAgICBpZiBjb21wbGV0ZXI6IGNvbXBsZXRlcigpCgpkZWYgYXByb3BvcyhrZXkpOgogICAgIiIiUHJpbnQgYWxsIHRoZSBvbmUtbGluZSBtb2R1bGUgc3VtbWFyaWVzIHRoYXQgY29udGFpbiBhIHN1YnN0cmluZy4iIiIKICAgIGRlZiBjYWxsYmFjayhwYXRoLCBtb2RuYW1lLCBkZXNjKToKICAgICAgICBpZiBtb2RuYW1lWy05Ol0gPT0gJy5fX2luaXRfXyc6CiAgICAgICAgICAgIG1vZG5hbWUgPSBtb2RuYW1lWzotOV0gKyAnIChwYWNrYWdlKScKICAgICAgICBwcmludCBtb2RuYW1lLCBkZXNjIGFuZCAnLSAnICsgZGVzYwogICAgdHJ5OiBpbXBvcnQgd2FybmluZ3MKICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjogcGFzcwogICAgZWxzZTogd2FybmluZ3MuZmlsdGVyd2FybmluZ3MoJ2lnbm9yZScpICMgaWdub3JlIHByb2JsZW1zIGR1cmluZyBpbXBvcnQKICAgIE1vZHVsZVNjYW5uZXIoKS5ydW4oY2FsbGJhY2ssIGtleSkKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHdlYiBicm93c2VyIGludGVyZmFjZQoKZGVmIHNlcnZlKHBvcnQsIGNhbGxiYWNrPU5vbmUsIGNvbXBsZXRlcj1Ob25lKToKICAgIGltcG9ydCBCYXNlSFRUUFNlcnZlciwgbWltZXRvb2xzLCBzZWxlY3QKCiAgICAjIFBhdGNoIHVwIG1pbWV0b29scy5NZXNzYWdlIHNvIGl0IGRvZXNuJ3QgYnJlYWsgaWYgcmZjODIyIGlzIHJlbG9hZGVkLgogICAgY2xhc3MgTWVzc2FnZShtaW1ldG9vbHMuTWVzc2FnZSk6CiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGZwLCBzZWVrYWJsZT0xKToKICAgICAgICAgICAgTWVzc2FnZSA9IHNlbGYuX19jbGFzc19fCiAgICAgICAgICAgIE1lc3NhZ2UuX19iYXNlc19fWzBdLl9fYmFzZXNfX1swXS5fX2luaXRfXyhzZWxmLCBmcCwgc2Vla2FibGUpCiAgICAgICAgICAgIHNlbGYuZW5jb2RpbmdoZWFkZXIgPSBzZWxmLmdldGhlYWRlcignY29udGVudC10cmFuc2Zlci1lbmNvZGluZycpCiAgICAgICAgICAgIHNlbGYudHlwZWhlYWRlciA9IHNlbGYuZ2V0aGVhZGVyKCdjb250ZW50LXR5cGUnKQogICAgICAgICAgICBzZWxmLnBhcnNldHlwZSgpCiAgICAgICAgICAgIHNlbGYucGFyc2VwbGlzdCgpCgogICAgY2xhc3MgRG9jSGFuZGxlcihCYXNlSFRUUFNlcnZlci5CYXNlSFRUUFJlcXVlc3RIYW5kbGVyKToKICAgICAgICBkZWYgc2VuZF9kb2N1bWVudChzZWxmLCB0aXRsZSwgY29udGVudHMpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmLnNlbmRfcmVzcG9uc2UoMjAwKQogICAgICAgICAgICAgICAgc2VsZi5zZW5kX2hlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpCiAgICAgICAgICAgICAgICBzZWxmLmVuZF9oZWFkZXJzKCkKICAgICAgICAgICAgICAgIHNlbGYud2ZpbGUud3JpdGUoaHRtbC5wYWdlKHRpdGxlLCBjb250ZW50cykpCiAgICAgICAgICAgIGV4Y2VwdCBJT0Vycm9yOiBwYXNzCgogICAgICAgIGRlZiBkb19HRVQoc2VsZik6CiAgICAgICAgICAgIHBhdGggPSBzZWxmLnBhdGgKICAgICAgICAgICAgaWYgcGF0aFstNTpdID09ICcuaHRtbCc6IHBhdGggPSBwYXRoWzotNV0KICAgICAgICAgICAgaWYgcGF0aFs6MV0gPT0gJy8nOiBwYXRoID0gcGF0aFsxOl0KICAgICAgICAgICAgaWYgcGF0aCBhbmQgcGF0aCAhPSAnLic6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgb2JqID0gbG9jYXRlKHBhdGgsIGZvcmNlbG9hZD0xKQogICAgICAgICAgICAgICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnNlbmRfZG9jdW1lbnQocGF0aCwgaHRtbC5lc2NhcGUoc3RyKHZhbHVlKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBpZiBvYmo6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KGRlc2NyaWJlKG9iaiksIGh0bWwuZG9jdW1lbnQob2JqLCBwYXRoKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZW5kX2RvY3VtZW50KHBhdGgsCidubyBQeXRob24gZG9jdW1lbnRhdGlvbiBmb3VuZCBmb3IgJXMnICUgcmVwcihwYXRoKSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGhlYWRpbmcgPSBodG1sLmhlYWRpbmcoCic8YmlnPjxiaWc+PHN0cm9uZz5QeXRob246IEluZGV4IG9mIE1vZHVsZXM8L3N0cm9uZz48L2JpZz48L2JpZz4nLAonI2ZmZmZmZicsICcjNzc5OWVlJykKICAgICAgICAgICAgICAgIGRlZiBibHRpbmxpbmsobmFtZSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSIlcy5odG1sIj4lczwvYT4nICUgKG5hbWUsIG5hbWUpCiAgICAgICAgICAgICAgICBuYW1lcyA9IGZpbHRlcihsYW1iZGEgeDogeCAhPSAnX19tYWluX18nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzLmJ1aWx0aW5fbW9kdWxlX25hbWVzKQogICAgICAgICAgICAgICAgY29udGVudHMgPSBodG1sLm11bHRpY29sdW1uKG5hbWVzLCBibHRpbmxpbmspCiAgICAgICAgICAgICAgICBpbmRpY2VzID0gWyc8cD4nICsgaHRtbC5iaWdzZWN0aW9uKAogICAgICAgICAgICAgICAgICAgICdCdWlsdC1pbiBNb2R1bGVzJywgJyNmZmZmZmYnLCAnI2VlNzdhYScsIGNvbnRlbnRzKV0KCiAgICAgICAgICAgICAgICBzZWVuID0ge30KICAgICAgICAgICAgICAgIGZvciBkaXIgaW4gcGF0aGRpcnMoKToKICAgICAgICAgICAgICAgICAgICBpbmRpY2VzLmFwcGVuZChodG1sLmluZGV4KGRpciwgc2VlbikpCiAgICAgICAgICAgICAgICBjb250ZW50cyA9IGhlYWRpbmcgKyBqb2luKGluZGljZXMpICsgJycnPHAgYWxpZ249cmlnaHQ+Cjxmb250IGNvbG9yPSIjOTA5MDkwIiBmYWNlPSJoZWx2ZXRpY2EsIGFyaWFsIj48c3Ryb25nPgpweWRvYzwvc3Ryb25nPiBieSBLYS1QaW5nIFllZSAmbHQ7cGluZ0BsZncub3JnJmd0OzwvZm9udD4nJycKICAgICAgICAgICAgICAgIHNlbGYuc2VuZF9kb2N1bWVudCgnSW5kZXggb2YgTW9kdWxlcycsIGNvbnRlbnRzKQoKICAgICAgICBkZWYgbG9nX21lc3NhZ2Uoc2VsZiwgKmFyZ3MpOiBwYXNzCgogICAgY2xhc3MgRG9jU2VydmVyKEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIpOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBwb3J0LCBjYWxsYmFjayk6CiAgICAgICAgICAgIGhvc3QgPSAoc3lzLnBsYXRmb3JtID09ICdtYWMnKSBhbmQgJzEyNy4wLjAuMScgb3IgJ2xvY2FsaG9zdCcKICAgICAgICAgICAgc2VsZi5hZGRyZXNzID0gKCcnLCBwb3J0KQogICAgICAgICAgICBzZWxmLnVybCA9ICdodHRwOi8vJXM6JWQvJyAlIChob3N0LCBwb3J0KQogICAgICAgICAgICBzZWxmLmNhbGxiYWNrID0gY2FsbGJhY2sKICAgICAgICAgICAgc2VsZi5iYXNlLl9faW5pdF9fKHNlbGYsIHNlbGYuYWRkcmVzcywgc2VsZi5oYW5kbGVyKQoKICAgICAgICBkZWYgc2VydmVfdW50aWxfcXVpdChzZWxmKToKICAgICAgICAgICAgaW1wb3J0IHNlbGVjdAogICAgICAgICAgICBzZWxmLnF1aXQgPSBGYWxzZQogICAgICAgICAgICB3aGlsZSBub3Qgc2VsZi5xdWl0OgogICAgICAgICAgICAgICAgcmQsIHdyLCBleCA9IHNlbGVjdC5zZWxlY3QoW3NlbGYuc29ja2V0LmZpbGVubygpXSwgW10sIFtdLCAxKQogICAgICAgICAgICAgICAgaWYgcmQ6IHNlbGYuaGFuZGxlX3JlcXVlc3QoKQoKICAgICAgICBkZWYgc2VydmVyX2FjdGl2YXRlKHNlbGYpOgogICAgICAgICAgICBzZWxmLmJhc2Uuc2VydmVyX2FjdGl2YXRlKHNlbGYpCiAgICAgICAgICAgIGlmIHNlbGYuY2FsbGJhY2s6IHNlbGYuY2FsbGJhY2soc2VsZikKCiAgICBEb2NTZXJ2ZXIuYmFzZSA9IEJhc2VIVFRQU2VydmVyLkhUVFBTZXJ2ZXIKICAgIERvY1NlcnZlci5oYW5kbGVyID0gRG9jSGFuZGxlcgogICAgRG9jSGFuZGxlci5NZXNzYWdlQ2xhc3MgPSBNZXNzYWdlCiAgICB0cnk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBEb2NTZXJ2ZXIocG9ydCwgY2FsbGJhY2spLnNlcnZlX3VudGlsX3F1aXQoKQogICAgICAgIGV4Y2VwdCAoS2V5Ym9hcmRJbnRlcnJ1cHQsIHNlbGVjdC5lcnJvcik6CiAgICAgICAgICAgIHBhc3MKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgY29tcGxldGVyOiBjb21wbGV0ZXIoKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBncmFwaGljYWwgaW50ZXJmYWNlCgpkZWYgZ3VpKCk6CiAgICAiIiJHcmFwaGljYWwgaW50ZXJmYWNlIChzdGFydHMgd2ViIHNlcnZlciBhbmQgcG9wcyB1cCBhIGNvbnRyb2wgd2luZG93KS4iIiIKICAgIGNsYXNzIEdVSToKICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgd2luZG93LCBwb3J0PTc0NjQpOgogICAgICAgICAgICBzZWxmLndpbmRvdyA9IHdpbmRvdwogICAgICAgICAgICBzZWxmLnNlcnZlciA9IE5vbmUKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQoKICAgICAgICAgICAgaW1wb3J0IFRraW50ZXIKICAgICAgICAgICAgc2VsZi5zZXJ2ZXJfZnJtID0gVGtpbnRlci5GcmFtZSh3aW5kb3cpCiAgICAgICAgICAgIHNlbGYudGl0bGVfbGJsID0gVGtpbnRlci5MYWJlbChzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdTdGFydGluZyBzZXJ2ZXIuLi5cbiAnKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuID0gVGtpbnRlci5CdXR0b24oc2VsZi5zZXJ2ZXJfZnJtLAogICAgICAgICAgICAgICAgdGV4dD0nb3BlbiBicm93c2VyJywgY29tbWFuZD1zZWxmLm9wZW4sIHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIHNlbGYucXVpdF9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnNlcnZlcl9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdxdWl0IHNlcnZpbmcnLCBjb21tYW5kPXNlbGYucXVpdCwgc3RhdGU9J2Rpc2FibGVkJykKCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2ZybSA9IFRraW50ZXIuRnJhbWUod2luZG93KQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwgPSBUa2ludGVyLkxhYmVsKHNlbGYuc2VhcmNoX2ZybSwgdGV4dD0nU2VhcmNoIGZvcicpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudCA9IFRraW50ZXIuRW50cnkoc2VsZi5zZWFyY2hfZnJtKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuYmluZCgnPFJldHVybj4nLCBzZWxmLnNlYXJjaCkKICAgICAgICAgICAgc2VsZi5zdG9wX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYuc2VhcmNoX2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J3N0b3AnLCBwYWR5PTAsIGNvbW1hbmQ9c2VsZi5zdG9wLCBzdGF0ZT0nZGlzYWJsZWQnKQogICAgICAgICAgICBpZiBzeXMucGxhdGZvcm0gPT0gJ3dpbjMyJzoKICAgICAgICAgICAgICAgICMgVHJ5aW5nIHRvIGhpZGUgYW5kIHNob3cgdGhpcyBidXR0b24gY3Jhc2hlcyB1bmRlciBXaW5kb3dzLgogICAgICAgICAgICAgICAgc2VsZi5zdG9wX2J0bi5wYWNrKHNpZGU9J3JpZ2h0JykKCiAgICAgICAgICAgIHNlbGYud2luZG93LnRpdGxlKCdweWRvYycpCiAgICAgICAgICAgIHNlbGYud2luZG93LnByb3RvY29sKCdXTV9ERUxFVEVfV0lORE9XJywgc2VsZi5xdWl0KQogICAgICAgICAgICBzZWxmLnRpdGxlX2xibC5wYWNrKHNpZGU9J3RvcCcsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuLnBhY2soc2lkZT0nbGVmdCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5xdWl0X2J0bi5wYWNrKHNpZGU9J3JpZ2h0JywgZmlsbD0neCcsIGV4cGFuZD0xKQogICAgICAgICAgICBzZWxmLnNlcnZlcl9mcm0ucGFjayhzaWRlPSd0b3AnLCBmaWxsPSd4JykKCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2xibC5wYWNrKHNpZGU9J2xlZnQnKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtLnBhY2soc2lkZT0ndG9wJywgZmlsbD0neCcpCiAgICAgICAgICAgIHNlbGYuc2VhcmNoX2VudC5mb2N1c19zZXQoKQoKICAgICAgICAgICAgZm9udCA9ICgnaGVsdmV0aWNhJywgc3lzLnBsYXRmb3JtID09ICd3aW4zMicgYW5kIDggb3IgMTApCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdCA9IFRraW50ZXIuTGlzdGJveCh3aW5kb3csIGZvbnQ9Zm9udCwgaGVpZ2h0PTYpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5iaW5kKCc8QnV0dG9uLTE+Jywgc2VsZi5zZWxlY3QpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5iaW5kKCc8RG91YmxlLUJ1dHRvbi0xPicsIHNlbGYuZ290bykKICAgICAgICAgICAgc2VsZi5yZXN1bHRfc2NyID0gVGtpbnRlci5TY3JvbGxiYXIod2luZG93LAogICAgICAgICAgICAgICAgb3JpZW50PSd2ZXJ0aWNhbCcsIGNvbW1hbmQ9c2VsZi5yZXN1bHRfbHN0Lnl2aWV3KQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuY29uZmlnKHlzY3JvbGxjb21tYW5kPXNlbGYucmVzdWx0X3Njci5zZXQpCgogICAgICAgICAgICBzZWxmLnJlc3VsdF9mcm0gPSBUa2ludGVyLkZyYW1lKHdpbmRvdykKICAgICAgICAgICAgc2VsZi5nb3RvX2J0biA9IFRraW50ZXIuQnV0dG9uKHNlbGYucmVzdWx0X2ZybSwKICAgICAgICAgICAgICAgIHRleHQ9J2dvIHRvIHNlbGVjdGVkJywgY29tbWFuZD1zZWxmLmdvdG8pCiAgICAgICAgICAgIHNlbGYuaGlkZV9idG4gPSBUa2ludGVyLkJ1dHRvbihzZWxmLnJlc3VsdF9mcm0sCiAgICAgICAgICAgICAgICB0ZXh0PSdoaWRlIHJlc3VsdHMnLCBjb21tYW5kPXNlbGYuaGlkZSkKICAgICAgICAgICAgc2VsZi5nb3RvX2J0bi5wYWNrKHNpZGU9J2xlZnQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYuaGlkZV9idG4ucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3gnLCBleHBhbmQ9MSkKCiAgICAgICAgICAgIHNlbGYud2luZG93LnVwZGF0ZSgpCiAgICAgICAgICAgIHNlbGYubWlud2lkdGggPSBzZWxmLndpbmRvdy53aW5mb193aWR0aCgpCiAgICAgICAgICAgIHNlbGYubWluaGVpZ2h0ID0gc2VsZi53aW5kb3cud2luZm9faGVpZ2h0KCkKICAgICAgICAgICAgc2VsZi5iaWdtaW5oZWlnaHQgPSAoc2VsZi5zZXJ2ZXJfZnJtLndpbmZvX3JlcWhlaWdodCgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zZWFyY2hfZnJtLndpbmZvX3JlcWhlaWdodCgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHRfbHN0LndpbmZvX3JlcWhlaWdodCgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLndpbmZvX3JlcWhlaWdodCgpKQogICAgICAgICAgICBzZWxmLmJpZ3dpZHRoLCBzZWxmLmJpZ2hlaWdodCA9IHNlbGYubWlud2lkdGgsIHNlbGYuYmlnbWluaGVpZ2h0CiAgICAgICAgICAgIHNlbGYuZXhwYW5kZWQgPSAwCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5taW53aWR0aCwgc2VsZi5taW5oZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLndpbmRvdy50ay53aWxsZGlzcGF0Y2goKQoKICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZwogICAgICAgICAgICB0aHJlYWRpbmcuVGhyZWFkKAogICAgICAgICAgICAgICAgdGFyZ2V0PXNlcnZlLCBhcmdzPShwb3J0LCBzZWxmLnJlYWR5LCBzZWxmLnF1aXQpKS5zdGFydCgpCgogICAgICAgIGRlZiByZWFkeShzZWxmLCBzZXJ2ZXIpOgogICAgICAgICAgICBzZWxmLnNlcnZlciA9IHNlcnZlcgogICAgICAgICAgICBzZWxmLnRpdGxlX2xibC5jb25maWcoCiAgICAgICAgICAgICAgICB0ZXh0PSdQeXRob24gZG9jdW1lbnRhdGlvbiBzZXJ2ZXIgYXRcbicgKyBzZXJ2ZXIudXJsKQogICAgICAgICAgICBzZWxmLm9wZW5fYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKICAgICAgICAgICAgc2VsZi5xdWl0X2J0bi5jb25maWcoc3RhdGU9J25vcm1hbCcpCgogICAgICAgIGRlZiBvcGVuKHNlbGYsIGV2ZW50PU5vbmUsIHVybD1Ob25lKToKICAgICAgICAgICAgdXJsID0gdXJsIG9yIHNlbGYuc2VydmVyLnVybAogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbXBvcnQgd2ViYnJvd3NlcgogICAgICAgICAgICAgICAgd2ViYnJvd3Nlci5vcGVuKHVybCkKICAgICAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOiAjIHByZS13ZWJicm93c2VyLnB5IGNvbXBhdGliaWxpdHkKICAgICAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInOgogICAgICAgICAgICAgICAgICAgIG9zLnN5c3RlbSgnc3RhcnQgIiVzIicgJSB1cmwpCiAgICAgICAgICAgICAgICBlbGlmIHN5cy5wbGF0Zm9ybSA9PSAnbWFjJzoKICAgICAgICAgICAgICAgICAgICB0cnk6IGltcG9ydCBpYwogICAgICAgICAgICAgICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjogcGFzcwogICAgICAgICAgICAgICAgICAgIGVsc2U6IGljLmxhdW5jaHVybCh1cmwpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJjID0gb3Muc3lzdGVtKCduZXRzY2FwZSAtcmVtb3RlICJvcGVuVVJMKCVzKSIgJicgJSB1cmwpCiAgICAgICAgICAgICAgICAgICAgaWYgcmM6IG9zLnN5c3RlbSgnbmV0c2NhcGUgIiVzIiAmJyAlIHVybCkKCiAgICAgICAgZGVmIHF1aXQoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGlmIHNlbGYuc2VydmVyOgogICAgICAgICAgICAgICAgc2VsZi5zZXJ2ZXIucXVpdCA9IDEKICAgICAgICAgICAgc2VsZi53aW5kb3cucXVpdCgpCgogICAgICAgIGRlZiBzZWFyY2goc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGtleSA9IHNlbGYuc2VhcmNoX2VudC5nZXQoKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLnBhY2soc2lkZT0ncmlnaHQnKQogICAgICAgICAgICBzZWxmLnN0b3BfYnRuLmNvbmZpZyhzdGF0ZT0nbm9ybWFsJykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLmNvbmZpZyh0ZXh0PSdTZWFyY2hpbmcgZm9yICIlcyIuLi4nICUga2V5KQogICAgICAgICAgICBzZWxmLnNlYXJjaF9lbnQuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5zZWFyY2hfbGJsLnBhY2soc2lkZT0nbGVmdCcpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2xzdC5kZWxldGUoMCwgJ2VuZCcpCiAgICAgICAgICAgIHNlbGYuZ290b19idG4uY29uZmlnKHN0YXRlPSdkaXNhYmxlZCcpCiAgICAgICAgICAgIHNlbGYuZXhwYW5kKCkKCiAgICAgICAgICAgIGltcG9ydCB0aHJlYWRpbmcKICAgICAgICAgICAgaWYgc2VsZi5zY2FubmVyOgogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyLnF1aXQgPSAxCiAgICAgICAgICAgIHNlbGYuc2Nhbm5lciA9IE1vZHVsZVNjYW5uZXIoKQogICAgICAgICAgICB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1zZWxmLnNjYW5uZXIucnVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3M9KHNlbGYudXBkYXRlLCBrZXksIHNlbGYuZG9uZSkpLnN0YXJ0KCkKCiAgICAgICAgZGVmIHVwZGF0ZShzZWxmLCBwYXRoLCBtb2RuYW1lLCBkZXNjKToKICAgICAgICAgICAgaWYgbW9kbmFtZVstOTpdID09ICcuX19pbml0X18nOgogICAgICAgICAgICAgICAgbW9kbmFtZSA9IG1vZG5hbWVbOi05XSArICcgKHBhY2thZ2UpJwogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuaW5zZXJ0KCdlbmQnLAogICAgICAgICAgICAgICAgbW9kbmFtZSArICcgLSAnICsgKGRlc2Mgb3IgJyhubyBkZXNjcmlwdGlvbiknKSkKCiAgICAgICAgZGVmIHN0b3Aoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIGlmIHNlbGYuc2Nhbm5lcjoKICAgICAgICAgICAgICAgIHNlbGYuc2Nhbm5lci5xdWl0ID0gMQogICAgICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQoKICAgICAgICBkZWYgZG9uZShzZWxmKToKICAgICAgICAgICAgc2VsZi5zY2FubmVyID0gTm9uZQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwuY29uZmlnKHRleHQ9J1NlYXJjaCBmb3InKQogICAgICAgICAgICBzZWxmLnNlYXJjaF9sYmwucGFjayhzaWRlPSdsZWZ0JykKICAgICAgICAgICAgc2VsZi5zZWFyY2hfZW50LnBhY2soc2lkZT0ncmlnaHQnLCBmaWxsPSd4JywgZXhwYW5kPTEpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAnd2luMzInOiBzZWxmLnN0b3BfYnRuLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYuc3RvcF9idG4uY29uZmlnKHN0YXRlPSdkaXNhYmxlZCcpCgogICAgICAgIGRlZiBzZWxlY3Qoc2VsZiwgZXZlbnQ9Tm9uZSk6CiAgICAgICAgICAgIHNlbGYuZ290b19idG4uY29uZmlnKHN0YXRlPSdub3JtYWwnKQoKICAgICAgICBkZWYgZ290byhzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZWN0aW9uID0gc2VsZi5yZXN1bHRfbHN0LmN1cnNlbGVjdGlvbigpCiAgICAgICAgICAgIGlmIHNlbGVjdGlvbjoKICAgICAgICAgICAgICAgIG1vZG5hbWUgPSBzcGxpdChzZWxmLnJlc3VsdF9sc3QuZ2V0KHNlbGVjdGlvblswXSkpWzBdCiAgICAgICAgICAgICAgICBzZWxmLm9wZW4odXJsPXNlbGYuc2VydmVyLnVybCArIG1vZG5hbWUgKyAnLmh0bWwnKQoKICAgICAgICBkZWYgY29sbGFwc2Uoc2VsZik6CiAgICAgICAgICAgIGlmIG5vdCBzZWxmLmV4cGFuZGVkOiByZXR1cm4KICAgICAgICAgICAgc2VsZi5yZXN1bHRfZnJtLmZvcmdldCgpCiAgICAgICAgICAgIHNlbGYucmVzdWx0X3Njci5mb3JnZXQoKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QuZm9yZ2V0KCkKICAgICAgICAgICAgc2VsZi5iaWd3aWR0aCA9IHNlbGYud2luZG93LndpbmZvX3dpZHRoKCkKICAgICAgICAgICAgc2VsZi5iaWdoZWlnaHQgPSBzZWxmLndpbmRvdy53aW5mb19oZWlnaHQoKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9nZW9tZXRyeSgnJWR4JWQnICUgKHNlbGYubWlud2lkdGgsIHNlbGYubWluaGVpZ2h0KSkKICAgICAgICAgICAgc2VsZi53aW5kb3cud21fbWluc2l6ZShzZWxmLm1pbndpZHRoLCBzZWxmLm1pbmhlaWdodCkKICAgICAgICAgICAgc2VsZi5leHBhbmRlZCA9IDAKCiAgICAgICAgZGVmIGV4cGFuZChzZWxmKToKICAgICAgICAgICAgaWYgc2VsZi5leHBhbmRlZDogcmV0dXJuCiAgICAgICAgICAgIHNlbGYucmVzdWx0X2ZybS5wYWNrKHNpZGU9J2JvdHRvbScsIGZpbGw9J3gnKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9zY3IucGFjayhzaWRlPSdyaWdodCcsIGZpbGw9J3knKQogICAgICAgICAgICBzZWxmLnJlc3VsdF9sc3QucGFjayhzaWRlPSd0b3AnLCBmaWxsPSdib3RoJywgZXhwYW5kPTEpCiAgICAgICAgICAgIHNlbGYud2luZG93LndtX2dlb21ldHJ5KCclZHglZCcgJSAoc2VsZi5iaWd3aWR0aCwgc2VsZi5iaWdoZWlnaHQpKQogICAgICAgICAgICBzZWxmLndpbmRvdy53bV9taW5zaXplKHNlbGYubWlud2lkdGgsIHNlbGYuYmlnbWluaGVpZ2h0KQogICAgICAgICAgICBzZWxmLmV4cGFuZGVkID0gMQoKICAgICAgICBkZWYgaGlkZShzZWxmLCBldmVudD1Ob25lKToKICAgICAgICAgICAgc2VsZi5zdG9wKCkKICAgICAgICAgICAgc2VsZi5jb2xsYXBzZSgpCgogICAgaW1wb3J0IFRraW50ZXIKICAgIHRyeToKICAgICAgICBndWkgPSBHVUkoVGtpbnRlci5UaygpKQogICAgICAgIFRraW50ZXIubWFpbmxvb3AoKQogICAgZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgogICAgICAgIHBhc3MKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29tbWFuZC1saW5lIGludGVyZmFjZQoKZGVmIGlzcGF0aCh4KToKICAgIHJldHVybiBpc2luc3RhbmNlKHgsIHN0cikgYW5kIGZpbmQoeCwgb3Muc2VwKSA+PSAwCgpkZWYgY2xpKCk6CiAgICAiIiJDb21tYW5kLWxpbmUgaW50ZXJmYWNlIChsb29rcyBhdCBzeXMuYXJndiB0byBkZWNpZGUgd2hhdCB0byBkbykuIiIiCiAgICBpbXBvcnQgZ2V0b3B0CiAgICBjbGFzcyBCYWRVc2FnZTogcGFzcwoKICAgICMgU2NyaXB0cyBkb24ndCBnZXQgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IGluIHRoZWlyIHBhdGggYnkgZGVmYXVsdC4KICAgIHNjcmlwdGRpciA9IG9zLnBhdGguZGlybmFtZShzeXMuYXJndlswXSkKICAgIGlmIHNjcmlwdGRpciBpbiBzeXMucGF0aDoKICAgICAgICBzeXMucGF0aC5yZW1vdmUoc2NyaXB0ZGlyKQogICAgc3lzLnBhdGguaW5zZXJ0KDAsICcuJykKCiAgICB0cnk6CiAgICAgICAgb3B0cywgYXJncyA9IGdldG9wdC5nZXRvcHQoc3lzLmFyZ3ZbMTpdLCAnZ2s6cDp3JykKICAgICAgICB3cml0aW5nID0gMAoKICAgICAgICBmb3Igb3B0LCB2YWwgaW4gb3B0czoKICAgICAgICAgICAgaWYgb3B0ID09ICctZyc6CiAgICAgICAgICAgICAgICBndWkoKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLWsnOgogICAgICAgICAgICAgICAgYXByb3Bvcyh2YWwpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgaWYgb3B0ID09ICctcCc6CiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgcG9ydCA9IGludCh2YWwpCiAgICAgICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgICAgICByYWlzZSBCYWRVc2FnZQogICAgICAgICAgICAgICAgZGVmIHJlYWR5KHNlcnZlcik6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgJ3B5ZG9jIHNlcnZlciByZWFkeSBhdCAlcycgJSBzZXJ2ZXIudXJsCiAgICAgICAgICAgICAgICBkZWYgc3RvcHBlZCgpOgogICAgICAgICAgICAgICAgICAgIHByaW50ICdweWRvYyBzZXJ2ZXIgc3RvcHBlZCcKICAgICAgICAgICAgICAgIHNlcnZlKHBvcnQsIHJlYWR5LCBzdG9wcGVkKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlmIG9wdCA9PSAnLXcnOgogICAgICAgICAgICAgICAgd3JpdGluZyA9IDEKCiAgICAgICAgaWYgbm90IGFyZ3M6IHJhaXNlIEJhZFVzYWdlCiAgICAgICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgICAgICBpZiBpc3BhdGgoYXJnKSBhbmQgbm90IG9zLnBhdGguZXhpc3RzKGFyZyk6CiAgICAgICAgICAgICAgICBwcmludCAnZmlsZSAlciBkb2VzIG5vdCBleGlzdCcgJSBhcmcKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlmIGlzcGF0aChhcmcpIGFuZCBvcy5wYXRoLmlzZmlsZShhcmcpOgogICAgICAgICAgICAgICAgICAgIGFyZyA9IGltcG9ydGZpbGUoYXJnKQogICAgICAgICAgICAgICAgaWYgd3JpdGluZzoKICAgICAgICAgICAgICAgICAgICBpZiBpc3BhdGgoYXJnKSBhbmQgb3MucGF0aC5pc2RpcihhcmcpOgogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZWRvY3MoYXJnKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlZG9jKGFyZykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgZG9jKGFyZykKICAgICAgICAgICAgZXhjZXB0IEVycm9yRHVyaW5nSW1wb3J0LCB2YWx1ZToKICAgICAgICAgICAgICAgIHByaW50IHZhbHVlCgogICAgZXhjZXB0IChnZXRvcHQuZXJyb3IsIEJhZFVzYWdlKToKICAgICAgICBjbWQgPSBzeXMuYXJndlswXQogICAgICAgIHByaW50ICIiInB5ZG9jIC0gdGhlIFB5dGhvbiBkb2N1bWVudGF0aW9uIHRvb2wKCiVzIDxuYW1lPiAuLi4KICAgIFNob3cgdGV4dCBkb2N1bWVudGF0aW9uIG9uIHNvbWV0aGluZy4gIDxuYW1lPiBtYXkgYmUgdGhlIG5hbWUgb2YgYQogICAgZnVuY3Rpb24sIG1vZHVsZSwgb3IgcGFja2FnZSwgb3IgYSBkb3R0ZWQgcmVmZXJlbmNlIHRvIGEgY2xhc3Mgb3IKICAgIGZ1bmN0aW9uIHdpdGhpbiBhIG1vZHVsZSBvciBtb2R1bGUgaW4gYSBwYWNrYWdlLiAgSWYgPG5hbWU+IGNvbnRhaW5zCiAgICBhICclcycsIGl0IGlzIHVzZWQgYXMgdGhlIHBhdGggdG8gYSBQeXRob24gc291cmNlIGZpbGUgdG8gZG9jdW1lbnQuCgolcyAtayA8a2V5d29yZD4KICAgIFNlYXJjaCBmb3IgYSBrZXl3b3JkIGluIHRoZSBzeW5vcHNpcyBsaW5lcyBvZiBhbGwgYXZhaWxhYmxlIG1vZHVsZXMuCgolcyAtcCA8cG9ydD4KICAgIFN0YXJ0IGFuIEhUVFAgc2VydmVyIG9uIHRoZSBnaXZlbiBwb3J0IG9uIHRoZSBsb2NhbCBtYWNoaW5lLgoKJXMgLWcKICAgIFBvcCB1cCBhIGdyYXBoaWNhbCBpbnRlcmZhY2UgZm9yIGZpbmRpbmcgYW5kIHNlcnZpbmcgZG9jdW1lbnRhdGlvbi4KCiVzIC13IDxuYW1lPiAuLi4KICAgIFdyaXRlIG91dCB0aGUgSFRNTCBkb2N1bWVudGF0aW9uIGZvciBhIG1vZHVsZSB0byBhIGZpbGUgaW4gdGhlIGN1cnJlbnQKICAgIGRpcmVjdG9yeS4gIElmIDxuYW1lPiBjb250YWlucyBhICclcycsIGl0IGlzIHRyZWF0ZWQgYXMgYSBmaWxlbmFtZTsgaWYKICAgIGl0IG5hbWVzIGEgZGlyZWN0b3J5LCBkb2N1bWVudGF0aW9uIGlzIHdyaXR0ZW4gZm9yIGFsbCB0aGUgY29udGVudHMuCiIiIiAlIChjbWQsIG9zLnNlcCwgY21kLCBjbWQsIGNtZCwgY21kLCBvcy5zZXApCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOiBjbGkoKQo=