LyoNCglDb3B5cmlnaHQgKGMpIDIwMDYtMjAwNywgVGhlIFhvb2tpIHByb2plY3QNCglodHRwOi8veG9va2kuc291cmNlZm9yZ2UubmV0Lw0KDQogICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsNCiAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4NCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdA0KDQogICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQoNCiAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCiAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCiAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCiAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KCQ0KCVNvbWUgY29kZSBpcyBsYXJnZWx5IGluc3BpcmVkIGJ5IGNvZGUgZm91bmQgaW4gdGhlIGRvam8gdG9vbGtpdCwgDQoJc2VlIGh0dHA6Ly9kb2pvdG9vbGtpdC5vcmcvIGZvciBtb3JlIGluZm9ybWF0aW9uLg0KKi8NCg0KLyoNClRoaXMgc2NyaXB0IGNhbiBiZSBlaXRoZXIgZW1iZWRkZWQgaW4gYSB4b29raSBwYWdlIGZvciBpbiBicm93c2VyIHByb2Nlc3NpbmcsIG9yIHVzZWQgaW4gYmF0Y2ggdXNpbmcgcmhpbm8gb3IgamF2YSA2IGphdmFzY3JpcHQgdG9vbDoNCmpydW5zY3JpcHQgcGF0aC90by94b29raS5qcyBpbnB1dEZpbGVGcm9tWG9va2lTaXRlLmh0bWwgW3BhdGgvdG8vZGlyL3RvL3B1dC9nZW5lcmF0ZWQvZmlsZV0NCg0KQmUgc3VyZSB0byBiZSBpbiB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBodG1sIGlucHV0IHRvIHByb2Nlc3MgaXMgd2hlbiBydW5uaW5nIHRoaXMgY29tbWFuZC4NCiAqLw0KdmFyIGJhdGNoTW9kZSA9ICh0eXBlb2YgYXJndW1lbnRzICE9ICd1bmRlZmluZWQnKTsNCg0KdmFyIHhvb2tpID0ge307DQp4b29raS5jb25zb2xlID0gIiI7IC8vIHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlIG9ubHksIGFuZCBvbmx5IHdoZW4gdGhlIGRlYnVnIGRpdiBpcyBub3QgeWV0IGNyZWF0ZWQNCnhvb2tpLmNvbmZpZyA9IHt9Ow0KeG9va2kuYyA9IHhvb2tpLmNvbmZpZzsNCg0KZnVuY3Rpb24gdChtc2cpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBpbnRlcm5hdGlvbmFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtZXNzYWdlLCBvciB0aGUgbWVzc2FnZSBpZiBubyB0cmFuc2xhdGlvbiBpcyBhdmFpbGFibGUNCiAgICAvLyB0IHN0YW5kcyBmb3IgdHJhbnNsYXRlDQovLyBGSVhNRQ0KLy8gICAgaWYgKHR5cGVvZiB4b29raS5jID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzID09ICJvYmplY3QiIA0KLy8gICAgICAgICYmIHR5cGVvZiB4b29raS5jLm1lc3NhZ2VzW21zZ10gPT0gInN0cmluZyIpIHsNCi8vICAgICAgICBtc2cgPSB4b29raS5jLm1lc3NhZ2VzW21zZ107DQovLyAgICB9DQogICAgdmFyIGFyciA9IFtdOw0KICAgIGZvciAodmFyIGk9MTsgaTxhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgYXJyLnB1c2goYXJndW1lbnRzW2ldKTsNCiAgICB9DQogICAgcmV0dXJuIHhvb2tpLnN0cmluZy5zdWJzdGl0dXRlUGFyYW1zKG1zZywgYXJyKTsNCn0NCg0KZnVuY3Rpb24gY3NzKGNsc3MpIHsNCiAgICAvLyByZXR1cm5zIHRoZSBjc3MgY2xhc3Mgb3IgaWQgY29uZmlndXJlZCwgb3IgdGhlIGdpdmVuIGNsYXNzIChvciBpZCkgaWYgbm8gb25lIGlzIGNvbmZpZ3VyZWQNCiAgICBpZiAodHlwZW9mIHhvb2tpLmMuY3NzW2Nsc3NdICE9ICJ1bmRlZmluZWQiKSB7DQogICAgICAgIHJldHVybiB4b29raS5jLmNzc1tjbHNzXTsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4gY2xzczsNCiAgICB9IA0KfQ0KZnVuY3Rpb24gdShwYXRoKSB7DQogIC8vIGNvbnZlcnQgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSByb290IHRvIGEgZnVsbCBVUkwNCiAgLy8gdSBzdGFuZHMgZm9yIFVybA0KICBpZiAoYmF0Y2hNb2RlKSB7DQoJcmV0dXJuIHhvb2tpLmMucmVsYXRpdmVSb290K3BhdGg7DQogIH0gZWxzZSB7DQoJcmV0dXJuIHhvb2tpLmMucm9vdCArIHBhdGg7DQogIH0NCn0NCmZ1bmN0aW9uIGx1KHBhdGgpIHsNCiAgLy8gY29udmVydCBhIHBhdGggcmVsYXRpdmUgdG8gdGhlIGxvY2FsIHJvb3QgdG8gYSBmdWxsIFVSTA0KICAvLyBsIHN0YW5kcyBmb3IgbG9jYWwsIHUgc3RhbmRzIGZvciBVcmwNCiAgaWYgKGJhdGNoTW9kZSkgew0KCXJldHVybiB4b29raS5jLmxvY2FsUmVsYXRpdmVSb290K3BhdGg7DQogIH0gZWxzZSB7DQoJcmV0dXJuIHhvb2tpLmMubG9jYWxSb290ICsgcGF0aDsNCiAgfQ0KfQ0KZnVuY3Rpb24gY3UodXJsQ2ZnUHJvcCkgew0KICAvLyBnZXQgYSBwYXRoIGZyb20gYSBjb25maWd1cmF0aW9uIHBhdGggYW5kIGNvbnZlcnQgaXQgdG8gYW4gVVJMDQogIC8vIGN1IHN0YW5kcyBmb3IgQ29uZmlndXJlZCBVcmwNCiAgaWYgKHR5cGVvZiB4b29raS5jLnBhdGhbdXJsQ2ZnUHJvcF0gPT0gInVuZGVmaW5lZCIpIHsNCiAgICB4b29raS53YXJuKHQoInBhdGggbm90IGNvbmZpZ3VyZWQgaW4geG9va2k6ICckezB9JyIsIHVybENmZ1Byb3ApKTsNCiAgICByZXR1cm4gIiI7DQogIH0NCiAgcmV0dXJuIHUoeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdKTsNCn0NCmZ1bmN0aW9uIHB1KGlkKSB7DQogIC8vIHJldHVybnMgdGhlIHVybCBvZiB0aGUgcGFnZSBpZGVudGlmaWVkIGJ5IGlkDQogIC8vIHB1IHN0YW5kcyBmb3IgUGFnZSBVcmwNCiAgcmV0dXJuIHUoaWQrIi5odG1sIik7DQp9DQp4b29raS5wID0gZnVuY3Rpb24ocGF0aCkgew0KICAvLyBnZXQgYSB4b29raSBmdWxsIHBhdGggZnJvbSBhIHhvb2tpIHJlbGF0aXZlIHBhdGgNCiAgLy8gcCBzdGFuZHMgZm9yIHBhdGgNCiAgcmV0dXJuIHhvb2tpLmMucGF0aC5pbnN0YWxsKyIvIitwYXRoOw0KfQ0KeG9va2kudSA9IGZ1bmN0aW9uKHBhdGgpIHsNCiAgLy8gY29udmVydCBhIHBhdGggcmVsYXRpdmUgdG8gdGhlIHhvb2tpIGluc3RhbGxhdGlvbiBkaXIgdG8gYSBmdWxsIFVSTA0KICByZXR1cm4gdSh4b29raS5wKHBhdGgpKTsNCn0NCnhvb2tpLmN1ID0gZnVuY3Rpb24odXJsQ2ZnUHJvcCkgew0KICAvLyBnZXQgYSB4b29raSBwYXRoIGZyb20gYSBjb25maWd1cmF0aW9uIHBhdGggYW5kIGNvbnZlcnQgaXQgdG8gYW4gVVJMDQogIGlmICh0eXBlb2YgeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdID09ICJ1bmRlZmluZWQiKSB7DQogICAgeG9va2kud2Fybih0KCJwYXRoIG5vdCBjb25maWd1cmVkIGluIHhvb2tpOiAnJHswfSciLCB1cmxDZmdQcm9wKSk7DQogIH0NCiAgcmV0dXJuIHhvb2tpLnUoeG9va2kuYy5wYXRoW3VybENmZ1Byb3BdKTsNCn0NCg0KeG9va2kudXRpbCA9IHsNCiAgICBpc0FycmF5OiBmdW5jdGlvbihpdCkgew0KICAgIAlyZXR1cm4gKGl0ICYmIGl0IGluc3RhbmNlb2YgQXJyYXkgfHwgdHlwZW9mIGl0ID09ICJhcnJheSIpOyAvLyBCb29sZWFuDQogICAgfSwNCiAgICBtaXg6IGZ1bmN0aW9uKHNyYywgaW50bywgb3ZlcnJpZGUpIHsNCiAgICAgICAgaWYgKHR5cGVvZiBvdmVycmlkZSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgb3ZlcnJpZGUgPSB0cnVlOw0KICAgICAgICB9DQogICAgICAgIGlmICh0eXBlb2YgaW50byA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgaW50byA9IHt9Ow0KICAgICAgICB9DQogICAgICAgIGZvciAodmFyIGsgaW4gc3JjKSB7DQogICAgICAgICAgICBpZiAodHlwZW9mIHNyY1trXSA9PSAib2JqZWN0IiAmJiAheG9va2kudXRpbC5pc0FycmF5KHNyY1trXSkpIHsNCiAgICAgICAgICAgICAgICBpZiAob3ZlcnJpZGUgfHwgdHlwZW9mIGludG9ba10gPT0gIm9iamVjdCIgfHwgdHlwZW9mIGludG9ba10gPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnRvW2tdICE9ICJvYmplY3QiKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpbnRvW2tdID0ge307DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeG9va2kudXRpbC5taXgoc3JjW2tdLCBpbnRvW2tdLCBvdmVycmlkZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSBlbHNlIGlmIChvdmVycmlkZSB8fCB0eXBlb2YgaW50b1trXSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIGludG9ba10gPSBzcmNba107DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIGludG87DQogICAgfSwNCiAgICBpbml0QXJyYXk6IGZ1bmN0aW9uKGEpIHsNCiAgICAgICAgaWYgKHRoaXMuaXNBcnJheShhKSkgcmV0dXJuIGE7DQogICAgICAgIGVsc2UgcmV0dXJuIHt9Ow0KICAgIH0NCn0NCg0KeG9va2kudXJsID0gew0KICAgICAgICBuZXdYbWxIdHRwUmVxdWVzdDogZnVuY3Rpb24oKSB7DQogICAgICAgIC8vIHdlIGZpcnN0IHRyeSB0byB1c2UgQWN0aXZlWCwgYmVjYXVzZSBJRTcgaGFzIGEgZGlyZWN0IHN1cHBvcnQgZm9yIFhtbEh0dHBSZXF1ZXN0IG9iamVjdCwgDQogICAgICAgIC8vIGJ1dCB3aGljaCBkb2Vzbid0IHdvcmsgd2l0aCBmaWxlIHVybHMNCiAgICAgICAgCWlmKHdpbmRvdy5BY3RpdmVYT2JqZWN0KQ0KICAgICAgICAJew0KICAgICAgICAJCXRyeSB7IHJlcSA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNc3htbDIuWE1MSFRUUCIpOw0KICAgICAgICAJCX0gY2F0Y2goZSkgew0KICAgICAgICAJCQl0cnkgeyByZXEgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKTsNCiAgICAgICAgCQkJfSBjYXRjaChlKSB7IHJlcSA9IGZhbHNlOyB9DQogICAgICAgIAkJfQ0KICAgICAgICAJfQ0KICAgICAgICAJZWxzZSBpZih3aW5kb3cuWE1MSHR0cFJlcXVlc3QpIHsNCiAgICAgICAgCQl0cnkgeyByZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsNCiAgICAgICAgCQl9IGNhdGNoKGUpIHsgcmVxID0gZmFsc2U7IH0NCiAgICAgICAgCX0NCiAgICAgICAgDQogICAgICAgIAlyZXR1cm4gcmVxOwkNCiAgICAgICAgfSwNCiAgICAgICAgICAgICAgICANCiAgICAgICAgbG9hZFVSTDogZnVuY3Rpb24oIHVybCwgd2Fybk9uRXJyb3IgKSB7DQogICAgICAgIAlyZXEgPSB0aGlzLm5ld1htbEh0dHBSZXF1ZXN0KCk7DQogICAgICAgIAlpZihyZXEpIHsNCiAgICAgICAgCQl0cnkgew0KICAgICAgICAJCQlyZXEub3BlbigiR0VUIiwgdXJsLCBmYWxzZSk7DQogICAgICAgIAkJCXJlcS5zZW5kKCIiKTsNCiAgICAgICAgCQ0KICAgICAgICAJCQlyZXR1cm4gcmVxLnJlc3BvbnNlVGV4dDsNCiAgICAgICAgCQl9IGNhdGNoIChlKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh3YXJuT25FcnJvciAhPSBmYWxzZSkNCiAgICAgICAgICAgICAgICAgICAgICAgIHhvb2tpLmVycm9yKGUsIHQoInByb2JsZW0gd2hpbGUgbG9hZGluZyBVUkwgJHswfSIsIHVybCkpOw0KICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICB4b29raS5kZWJ1Zyh0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH06ICR7MX0iLCB1cmwsIGUpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgCXJldHVybiBudWxsOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgYXN5bmNMb2FkVVJMOiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjaywgb2JqICkgew0KICAgICAgICAJdmFyIHJlcSA9IHRoaXMubmV3WG1sSHR0cFJlcXVlc3QoKTsNCiAgICAgICAgCWlmKHJlcSkgew0KICAgICAgICAJCXRyeSB7DQogICAgICAgIAkJCXJlcS5vcGVuKCJHRVQiLCB1cmwsIHRydWUpOw0KCQkJCSAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCkgew0KCQkJCSAgICAgICAgaWYgKHJlcS5yZWFkeVN0YXRlID09IDQpIHsNCgkJCQkgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09IDIwMCB8fCByZXEuc3RhdHVzID09IDApIHsNCgkJCQkgICAgICAgICAgICAgIGNhbGxiYWNrKHJlcS5yZXNwb25zZVRleHQsIG9iaik7DQoJCQkJICAgICAgICAgICB9DQoJCQkJICAgICAgICB9DQoJCQkJICAgICB9OyAgCQkJDQoJCQkJICAgICByZXEuc2VuZCgiIik7DQogICAgICAgIAkJfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJwcm9ibGVtIHdoaWxlIGxvYWRpbmcgVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9CQkNCiAgICAgICAgCX0NCiAgICAgICAgfSwNCg0KICAgICAgICBpbmNsdWRlOiBmdW5jdGlvbihzY3JpcHRfZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCc8JyArICdzY3JpcHQnKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgbGFuZ3VhZ2U9ImphdmFzY3JpcHQiJyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnIHR5cGU9InRleHQvamF2YXNjcmlwdCInKTsNCiAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKCcgc3JjPSInICsgeG9va2kudShzY3JpcHRfZmlsZW5hbWUpICsgJyI+Jyk7DQogICAgICAgICAgICBkb2N1bWVudC53cml0ZSgnPC8nICsgJ3NjcmlwdCcgKyAnPicpOw0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgZXZhbFVSTDogZnVuY3Rpb24oIHVybCwgd2Fybk9uRXJyb3JVcmwgKSB7DQogICAgICAgICAgICBzY3JpcHQgPSB0aGlzLmxvYWRVUkwodXJsLCB3YXJuT25FcnJvclVybCk7DQogICAgICAgICAgICBpZiAoc2NyaXB0ICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgICAgICBldmFsKHNjcmlwdCk7DQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgew0KICAgICAgICAJCQl4b29raS5lcnJvcihlLCB0KCJlcnJvciB3aGlsZSBleGVjdXRpbmcgc2NyaXB0IGZyb20gVVJMICR7MH0iLCB1cmwpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0sDQoNCiAgICAgICAgYWN0aW9uOiBmdW5jdGlvbihhY3Rpb24pIHsgICAgICAgIA0KICAgICAgICAgICAgLy8gcmV0dXJucyB0aGUgdXJsIGZvciBhbiBhY3Rpb24gb24gdGhlIHNhbWUgcGFnZQ0KICAgICAgICAgICAgbG9jID0gYmF0Y2hNb2RlPycnOnhvb2tpLnBhZ2VVUkw7DQogICAgICAgICAgICBpZiAobG9jLmluZGV4T2YoIiMiKSAhPSAtMSkgew0KICAgICAgICAgICAgICAgIGxvYyA9IGxvYy5zdWJzdHJpbmcoMCwgbG9jLmluZGV4T2YoIiMiKSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gbG9jKyI/YWN0aW9uPSIrYWN0aW9uOw0KICAgICAgICB9DQoNCiAgICB9Ow0KICAgIA0KeG9va2kuc3RyaW5nID0gew0KDQogICAgc3Vic3RpdHV0ZVBhcmFtczogZnVuY3Rpb24oLypzdHJpbmcqL3RlbXBsYXRlLCAvKiBvYmplY3QgLSBvcHRpb25hbCBvciAuLi4gKi9oYXNoKSB7DQogICAgLy8gYm9ycm93ZWQgZnJvbSBkb2pvDQogICAgLy8gc3VtbWFyeToNCiAgICAvLwlQZXJmb3JtcyBwYXJhbWV0ZXJpemVkIHN1YnN0aXR1dGlvbnMgb24gYSBzdHJpbmcuIFRocm93cyBhbiBleGNlcHRpb24gaWYgYW55IHBhcmFtZXRlciBpcyB1bm1hdGNoZWQuDQogICAgLy8NCiAgICAvLyBkZXNjcmlwdGlvbjoNCiAgICAvLwlGb3IgZXhhbXBsZSwNCiAgICAvLwkJZG9qby5zdHJpbmcuc3Vic3RpdHV0ZVBhcmFtcygiRmlsZSAnJHswfScgaXMgbm90IGZvdW5kIGluIGRpcmVjdG9yeSAnJHsxfScuIiwiZm9vLmh0bWwiLCIvdGVtcCIpOw0KICAgIC8vCXJldHVybnMNCiAgICAvLwkJIkZpbGUgJ2Zvby5odG1sJyBpcyBub3QgZm91bmQgaW4gZGlyZWN0b3J5ICcvdGVtcCcuIg0KICAgIC8vDQogICAgLy8gdGVtcGxhdGU6IHRoZSBvcmlnaW5hbCBzdHJpbmcgdGVtcGxhdGUgd2l0aCAke3ZhbHVlc30gdG8gYmUgcmVwbGFjZWQNCiAgICAvLyBoYXNoOiBuYW1lL3ZhbHVlIHBhaXJzICh0eXBlIG9iamVjdCkgdG8gcHJvdmlkZSBzdWJzdGl0dXRpb25zLiAgQWx0ZXJuYXRpdmVseSwgc3Vic3RpdHV0aW9ucyBtYXkgYmUNCiAgICAvLwlpbmNsdWRlZCBhcyBhbiBhcnJheQ0KICAgIA0KICAgICAgICB2YXIgbWFwOw0KICAgICAgICBpZiAodHlwZW9mIGhhc2ggPT0gIm9iamVjdCIgJiYgaGFzaC5sZW5ndGgpIHsgLy8gYXJyYXkNCiAgICAgICAgICAgIG1hcCA9IHt9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBoYXNoKSB7DQogICAgICAgICAgICAgICAgbWFwW2krIiJdID0gaGFzaFtpXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG1hcCA9IGhhc2g7DQogICAgICAgIH0NCiAgICANCiAgICAJcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL1wkXHsoXHcrKVx9L2csIGZ1bmN0aW9uKG1hdGNoLCBrZXkpew0KICAgIAkJaWYodHlwZW9mKG1hcFtrZXldKSAhPSAidW5kZWZpbmVkIiAmJiBtYXBba2V5XSAhPSBudWxsKXsNCiAgICAJCQlyZXR1cm4gbWFwW2tleV07DQogICAgCQl9DQogICAgCQl4b29raS53YXJuKCJTdWJzdGl0dXRpb24gbm90IGZvdW5kOiAiICsga2V5KTsNCiAgICAJCXJldHVybiBrZXk7DQogICAgCX0pOyAvLyBzdHJpbmcNCgl9LA0KCQ0KCXByb2Nlc3NUZW1wbGF0ZTogZnVuY3Rpb24oLypzdHJpbmcqL3RlbXBsYXRlLCAvKiBvYmplY3QgKi9oYXNoKSB7DQoJICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZS5wcm9jZXNzID09ICJmdW5jdGlvbiIpIHsNCgkgICAgICAgcmV0dXJuIHRlbXBsYXRlLnByb2Nlc3MoaGFzaCk7DQogICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YnN0aXR1dGVQYXJhbXModGVtcGxhdGUsIGhhc2gpOw0KICAgICAgIH0NCiAgICB9LA0KDQogICAgZXhjZXB0aW9uVGV4dDogZnVuY3Rpb24oZSwgbWVzc2FnZSkgew0KICAgIAl2YXIgcyA9IGUuZGVzY3JpcHRpb24gPyBlLmRlc2NyaXB0aW9uIDogZS50b1N0cmluZygpOw0KICAgIAlyZXR1cm4gbWVzc2FnZSA/IG1lc3NhZ2UrIjpcbiIrcyA6IHM7DQogICAgfSwNCiAgICANCiAgICBmaW5kWG1sU2VjdGlvbjogZnVuY3Rpb24oc3RyLCBlbGVtZW50LCBmcm9tKSB7DQogICAgICAgIHJldHVybiB0aGlzLmZpbmRTZWN0aW9uKHN0ciwgbmV3IFJlZ0V4cCgnPCcrZWxlbWVudCsnKFxccypcXHcrPSJbXFx3XFxzXSoiKSo+JyksIG5ldyBSZWdFeHAoJzwvJytlbGVtZW50Kyc+JyksIGZyb20pOw0KICAgIH0sDQogICAgDQogICAgZmluZDogZnVuY3Rpb24oLypzdHJpbmcqL3N0ciwgLypzdHJpbmcgb3IgcmVnZXhwKi9leHAsIC8qbnVtYmVyLCBvcHRpb25hbCovZnJvbSkgew0KICAgICAgICAvLyBmaW5kIGFuIGV4cHJlc3Npb24gKHN0cmluZyBvciByZWdleHApIGluIGEgc3RyaW5nLCBmcm9tIGFuIG9wdGlvbmFsIGluZGV4DQogICAgICAgIC8vIHRoZSBvYmplY3QgcmV0dXJuZWQgaGFzIHR3byBwcm9wZXJ0aWVzOg0KICAgICAgICAvLyBiZWdpbjogdGhlIGluZGV4IGluIHN0ciBvZiB0aGUgbWF0Y2hpbmcgZmluZA0KICAgICAgICAvLyBlbmQ6IHRoZSBpbmRleCBpbiBzdHIgb2YgdGhlIGVuZCBvZiB0aGUgbWF0Y2hpbmcgZmluZA0KICAgICAgICAvLyByZXR1cm5zIG51bGwgaWYgbm8gbWF0Y2ggaXMgZm91bmQNCiAgICAgICAgaWYgKHR5cGVvZiBmcm9tICE9ICJudW1iZXIiKSB7DQogICAgICAgICAgICBmcm9tID0gMDsNCiAgICAgICAgfQ0KICAgICAgICBpZiAodHlwZW9mIGV4cCA9PSAic3RyaW5nIikgew0KICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9Ow0KICAgICAgICAgICAgcmVzdWx0LmJlZ2luID0gc3RyLmluZGV4T2YoZXhwLGZyb20pOw0KICAgICAgICAgICAgaWYgKHJlc3VsdC5iZWdpbiA+PSAwKSB7DQogICAgICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHJlc3VsdC5iZWdpbiArIGV4cC5sZW5ndGg7DQogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIHZhciBtOw0KICAgICAgICAgICAgaWYgKGZyb20gPiAwKSB7DQogICAgICAgICAgICAgICAgLy8gSSBoYXZlbid0IGZvdW5kIGFueSBvdGhlciB3YXkgdG8gc3RhcnQgZnJvbSB0aGUgZ2l2ZW4gaW5kZXgNCiAgICAgICAgICAgICAgICBtID0gZXhwLmV4ZWMoc3RyLnN1YnN0cmluZyhmcm9tKSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG0gPSBleHAuZXhlYyhzdHIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKG0gIT0gbnVsbCkgeyAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ge307DQogICAgICAgICAgICAgICAgcmVzdWx0LmJlZ2luID0gbS5pbmRleCArIGZyb207DQogICAgICAgICAgICAgICAgcmVzdWx0LmVuZCA9IHJlc3VsdC5iZWdpbiArIG1bMF0ubGVuZ3RoOw0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG51bGw7DQogICAgfSwNCiAgICANCiAgICBmaW5kU2VjdGlvbjogZnVuY3Rpb24oLypzdHJpbmcqL3N0ciwgLypzdHJpbmcgb3IgcmVnZXhwKi9vcGVuLCAvKnN0cmluZyBvciByZWdleHAqL2Nsb3NlLCAvKm51bWJlciwgb3B0aW9uYWwqL2Zyb20pIHsNCiAgICAgICAgLy8gZmluZHMgYSBzZWN0aW9uIGRlbGltaXRlZCBieSBvcGVuIGFuZCBjbG9zZSB0b2tlbnMgaW4gdGhlIGdpdmVuIHN0cmluZw0KICAgICAgICAvLyB0aGUgYWxnb3JpdGhtIGxvb2tzIGZvciBtYXRjaGluZyBvcGVuIGFuZCBjbG9zZSB0b2tlbnMNCiAgICAgICAgLy8gdGhlIHJldHVybmVkIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOg0KICAgICAgICAvLyAgIG91dGVyU3RhcnQ6IHRoZSBpbmRleCBpbiBzdHIgd2hlcmUgdGhlIGZpcnN0IG9wZW4gdG9rZW4gd2FzIGZvdW5kDQogICAgICAgIC8vICAgaW5uZXJTdGFydDogdGhlIGluZGV4IGluIHN0ciBqdXN0IGFmdGVyIHRoZSBmb3VuZCBvcGVuIHRva2VuDQogICAgICAgIC8vICAgaW5uZXJFbmQ6IHRoZSBpbmRleCBpbiBzdHIgd2hlcmUgdGhlIG1hdGNoaW5nIGNsb3NlIHRva2VuIHdhcyBmb3VuZA0KICAgICAgICAvLyAgIG91dGVyRW5kOiB0aGUgaW5kZXggaW4gc3RyIGp1c3QgYWZ0ZXIgdGhlIG1hdGNoaW5nIGNsb3NlIHRva2VuDQogICAgICAgIC8vICAgY2hpbGRyZW46IGFuIGFycmF5IG9mIHNpbWlsYXIgb2JqZWN0cyBpZiBuZXN0ZWQgc2VjdGlvbnMgd2hlcmUgZm91bmQNCiAgICAgICAgLy8gaWYgbm8gc2VjdGlvbiBpcyBmb3VuZCAobm8gb3BlbiB0b2tlbiwgYW4gb3BlbiB0b2tlbiB3aXRoIG5vIG1hdGNoaW5nIA0KICAgICAgICAvLyBjbG9zZSB0b2tlbiwgb3IgYSBjbG9zZSB0b2tlbiBiZWZvcmUgYW4gb3BlbiB0b2tlbiksIG51bGwgaXMgcmV0dXJuZWQNCiAgICAgICAgLy8NCiAgICAgICAgLy8gZm9yIGluc3RhbmNlIGlmIG9wZW49PScoJyBhbmQgY2xvc2U9PScpJyB0aGVuIHRoZSBzZWN0aW9uIHdpbGwgZmluZA0KICAgICAgICAvLyBhIHNlY3Rpb24gZGVsaW1pdGVkIGJ5IHRoZSBmaXJzdCBmb3VuZCBvcGVuIHBhcmVudGhlc2lzIGFuZCB0aGUgbWF0Y2hpbmcNCiAgICAgICAgLy8gY2xvc2UgcGFyZW50ZXRoaXMsIHRha2luZyBpbnRvIGFjY291bnQgb3RoZXIgb3BlbmluZyBwYXJlbnRldGhpcw0KICAgICAgICAvLyBleGFtcGxlczoNCiAgICAgICAgLy8gZmluZFNlY3Rpb24oImEodGVzdCliIiwgIigiLCAiKSIpID09IHtvdXRlclN0YXJ0OiAxLCBpbm5lclN0YXJ0OjIsIGlubmVyRW5kOjYsIG91dGVyRW5kOjcsIGNoaWxkcmVuOltdfQ0KICAgICAgICAvLyBmaW5kU2VjdGlvbigiYSh0ZShzKSh0KSliIiwgIigiLCAiKSIpID09IHtvdXRlclN0YXJ0OiAxLCBpbm5lclN0YXJ0OjIsIGlubmVyRW5kOjEwLCBvdXRlckVuZDoxMSwgDQogICAgICAgIC8vICAgICAgY2hpbGRyZW46Ww0KICAgICAgICAvLyAgICAgICAgICB7b3V0ZXJTdGFydDogNCwgaW5uZXJTdGFydDo1LCBpbm5lckVuZDo2LCBvdXRlckVuZDo3LCBjaGlsZHJlbjpbXX0sDQogICAgICAgIC8vICAgICAgICAgIHtvdXRlclN0YXJ0OiA3LCBpbm5lclN0YXJ0OjgsIGlubmVyRW5kOjksIG91dGVyRW5kOjEwLCBjaGlsZHJlbjpbXX0NCiAgICAgICAgLy8gICAgICBdfQ0KICAgICAgICANCiAgICAgICAgdmFyIG9wZW5SZXN1bHQgPSB0aGlzLmZpbmQoc3RyLCBvcGVuLCBmcm9tKTsgICAgICAgIA0KICAgICAgICBpZiAob3BlblJlc3VsdCA9PSBudWxsKSB7DQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KICAgICAgICB2YXIgY2xvc2VSZXN1bHQgPSB0aGlzLmZpbmQoc3RyLCBjbG9zZSwgZnJvbSk7ICAgICAgICANCiAgICAgICAgaWYgKGNsb3NlUmVzdWx0ID09IG51bGwgfHwgY2xvc2VSZXN1bHQuYmVnaW4gPCBvcGVuUmVzdWx0LmVuZCkgew0KICAgICAgICAgICAgcmV0dXJuIG51bGw7DQogICAgICAgIH0NCiAgICAgICAgaWYgKG9wZW5SZXN1bHQuZW5kIDw9IG9wZW5SZXN1bHQuYmVnaW4gfHwgY2xvc2VSZXN1bHQuZW5kIDw9IGNsb3NlUmVzdWx0LmJlZ2luKSB7DQogICAgICAgICAgICAvLyBlbXB0eSBtYXRjaCBhcmUgbm90IGFsbG93ZWQNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTsNCiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5maW5kU2VjdGlvbihzdHIsIG9wZW4sIGNsb3NlLCBvcGVuUmVzdWx0LmVuZCk7DQogICAgICAgIHdoaWxlIChjaGlsZCAhPSBudWxsKSB7DQogICAgICAgICAgICBpZiAoY2hpbGQub3V0ZXJFbmQgPiBjbG9zZVJlc3VsdC5iZWdpbikgew0KICAgICAgICAgICAgICAgIGNsb3NlUmVzdWx0ID0gdGhpcy5maW5kKHN0ciwgY2xvc2UsIGNoaWxkLm91dGVyRW5kKTsgICAgICAgIA0KICAgICAgICAgICAgICAgIGlmIChjbG9zZVJlc3VsdCA9PSBudWxsKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIHVubWF0Y2hlZCBvcGVuIHRva2VuDQogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hpbGQpOw0KICAgICAgICAgICAgY2hpbGQgPSB0aGlzLmZpbmRTZWN0aW9uKHN0ciwgb3BlbiwgY2xvc2UsIGNoaWxkLm91dGVyRW5kKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHJldHVybiB7DQogICAgICAgICAgICBvdXRlclN0YXJ0OiBvcGVuUmVzdWx0LmJlZ2luLA0KICAgICAgICAgICAgaW5uZXJTdGFydDogb3BlblJlc3VsdC5lbmQsDQogICAgICAgICAgICBpbm5lckVuZDogY2xvc2VSZXN1bHQuYmVnaW4sDQogICAgICAgICAgICBvdXRlckVuZDogY2xvc2VSZXN1bHQuZW5kLA0KICAgICAgICAgICAgY2hpbGRyZW46IGNoaWxkcmVuDQogICAgICAgIH07ICAgICAgICANCiAgICB9LA0KICAgIA0KICAgIG11bDogZnVuY3Rpb24gKC8qc3RyaW5nKi8gcywgLyppbnQqLyBuKSB7DQogICAgICAgIHIgPSAnJzsNCiAgICAgICAgZm9yICh2YXIgaT0wOyBpIDwgbjsgaSsrKSB7DQogICAgCQlyICs9IHM7DQogICAgCX0NCiAgICAgICAgcmV0dXJuIHI7DQogICAgfQ0KfTsNCiAgICANCnhvb2tpLmpzb24gPSB7DQogICAgICAgIGV2YWxKc29uOiBmdW5jdGlvbiAoc3RyKSB7DQogICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgIHJldHVybiBldmFsKCIoIitzdHIrIikiKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGxvYWRVUkw6IGZ1bmN0aW9uICh1cmwpIHsNCiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2YWxKc29uKHhvb2tpLnVybC5sb2FkVVJMKHVybCkpOw0KICAgICAgICB9DQogICAgfTsNCg0KLy8gRGlzcGxheXMgYW4gYWxlcnQgb2YgYW4gZXhjZXB0aW9uIGRlc2NyaXB0aW9uIHdpdGggb3B0aW9uYWwgbWVzc2FnZQ0KeG9va2kud2FybiA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2VlY2NjYyIpOw0KfQ0KDQovLyBEaXNwbGF5cyBhbiBhbGVydCBvZiBhbiBleGNlcHRpb24gZGVzY3JpcHRpb24gd2l0aCBvcHRpb25hbCBtZXNzYWdlDQp4b29raS5lcnJvciA9IGZ1bmN0aW9uKGUsIG1lc3NhZ2UpIHsNCiAgICB4b29raS5kaXNwbGF5KHhvb2tpLnN0cmluZy5leGNlcHRpb25UZXh0KGUsIG1lc3NhZ2UpLCAiI2ZmZGRkZCIpOw0KfQ0KDQp4b29raS5pbmZvID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHhvb2tpLmRpc3BsYXkobWVzc2FnZSwgIiNkZGRkZmYiKTsNCn0NCg0KeG9va2kuZGlzcGxheSA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGJhY2tncm91bmQpIHsNCiAgICB2YXIgbWVzc2FnZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktbWVzc2FnZXMnKTsNCiAgICBpZiAobWVzc2FnZXMpIHsNCiAgICAgICAgbWVzc2FnZXMuaW5uZXJIVE1MID0gJzx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIj48dHI+PHRkIGFsaWduPSJjZW50ZXIiPicrbWVzc2FnZSsnPC90ZD48L3RyPjwvdGFibGU+JzsNCiAgICAgICAgbWVzc2FnZXMuc3R5bGUuYmFja2dyb3VuZCA9IGJhY2tncm91bmQ7DQogICAgICAgIG1lc3NhZ2VzLnN0eWxlLmRpc3BsYXkgPSAiaW5saW5lIjsNCiAgICB9IGVsc2Ugew0KICAgICAgICBhbGVydChtZXNzYWdlKTsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnID0gZnVuY3Rpb24obWVzc2FnZSkgew0KICAgIHZhciBjb25zb2xlID0gdHlwZW9mIGRvY3VtZW50ID09ICd1bmRlZmluZWQnID8gZmFsc2UgOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktY29uc29sZScpOw0KICAgIGlmIChjb25zb2xlKSB7DQogICAgICAgIGNvbnNvbGUudmFsdWUgKz0gbWVzc2FnZSArICJcbiI7DQogICAgfSBlbHNlIHsNCiAgICAgICAgeG9va2kuY29uc29sZSArPSBtZXNzYWdlICsgIlxuIjsNCiAgICB9DQp9DQoNCnhvb2tpLmRlYnVnU2hvd0RldGFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7DQogICAgdmFyIGRldGFpbCA9IHR5cGVvZiBkb2N1bWVudCA9PSAndW5kZWZpbmVkJyA/IGZhbHNlIDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3hvb2tpLWRlYnVnLWRldGFpbCcpOw0KICAgIGlmIChkZXRhaWwpIHsNCiAgICAgICAgZGV0YWlsLnZhbHVlPW1lc3NhZ2U7DQogICAgfSBlbHNlIHsNCiAgICAgICAgYWxlcnQobWVzc2FnZSk7DQogICAgfQ0KfQ0KDQoNCnhvb2tpLmh0bWwgPSB7DQogICAgaGlkZTogZnVuY3Rpb24oZGl2aWQpIHsNCgkgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkaXZpZCkuc3R5bGUuZGlzcGxheSA9ICdub25lJzsNCiAgICB9LA0KDQogICAgc2hvdzogZnVuY3Rpb24gKGRpdmlkKSB7DQoJICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZGl2aWQpLnN0eWxlLmRpc3BsYXkgPSAnJzsNCiAgICB9LA0KICAgIA0KICAgIHBhZ2VMaW5rOiBmdW5jdGlvbihwYWdlKSB7DQogICAgCWlmIChwYWdlLmlzQWJzdHJhY3QpIHsNCiAgICAJCXJldHVybiBwYWdlLnRpdGxlOw0KICAgIAl9IGVsc2Ugew0KICAgIAkJcmV0dXJuICc8YSBocmVmPSInK3B1KHBhZ2UuaWQpKyciICcrKHBhZ2UuaWQgPT0geG9va2kucGFnZS5pZD8nY2xhc3M9ImN1cnJlbnQiJzonJykrJz4nK3BhZ2UudGl0bGUrJzwvYT4nOw0KICAgIAl9DQogICAgfSwNCgkNCgkvLyBpbnNlcnQgIHRoZSBnaXZlbiAgaGVhZGVyIGluIHRoZSBodG1sIGhlYWQNCgkvLyBjYW4gYmUgdXNlZCBvbmx5IHdoZW4gdGhlIGJyb3dzZXIgaXMgc3RpbGwgaW4gdGhlIGhlYWQgIQ0KCWFkZEhlYWRlcjogZnVuY3Rpb24oLyogc3RyaW5nICovIGhlYWQpIHsNCgkJZG9jdW1lbnQud3JpdGUoaGVhZCk7DQoJfSwNCgkNCglzZXRCb2R5OiBmdW5jdGlvbiggLyogc3RyaW5nICovIGJvZHkpIHsNCgkJZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBib2R5Ow0KCX0NCn07DQoNCnhvb2tpLmNvbXBvbmVudCA9IHsNCiAgICBjaGlsZHJlbkxpc3Q6IGZ1bmN0aW9uICgpIHsNCiAgICAJaWYgKHhvb2tpLnBhZ2UuY2hpbGRyZW4ubGVuZ3RoID4gMCkgew0KICAgIAkJY2hpbGRyZW5MaXN0ID0gJzx1bCBjbGFzcz0iJytjc3MoJ2NoaWxkcmVuTGlzdCcpKyciPic7DQogICAgCQlmb3IgKHZhciBpIGluIHhvb2tpLnBhZ2UuY2hpbGRyZW4pIHsNCiAgICAJCQljaGlsZHJlbkxpc3QrPSc8bGk+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHhvb2tpLnBhZ2UuY2hpbGRyZW5baV0pKyc8L2xpPic7DQogICAgCQl9DQogICAgCQljaGlsZHJlbkxpc3QgKz0gIjwvdWw+IjsNCiAgICAJCXJldHVybiBjaGlsZHJlbkxpc3Q7DQogICAgCX0gZWxzZSB7DQogICAgCSAgIHJldHVybiAiIjsNCiAgICAgICAgfQ0KICAgIH0sDQogICAgDQogICAgbWVudTogZnVuY3Rpb24gKCkgew0KICAgIAl2YXIgbWVudSA9ICc8dWwgaWQ9IicrY3NzKCJ0cmVlbWVudSIpKyciIGNsYXNzPSJ0cmVldmlldyI+JzsNCiAgICAJbWVudSArPSAoZnVuY3Rpb24gKHBhZ2UpIHsNCiAgICAgICAgCXZhciBtZW51ID0gJyc7DQogICAgICAgIAlmb3IgKHZhciBpIGluIHBhZ2UuY2hpbGRyZW4pIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhZ2UuY2hpbGRyZW5baV0gPT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgIAkJc21lbnUgPSBhcmd1bWVudHMuY2FsbGVlKHBhZ2UuY2hpbGRyZW5baV0pOw0KICAgICAgICAgICAgCQlpZiAoc21lbnUgIT0gJycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnUgKz0gJzxsaSBpZD0ieG9va2ktJytwYWdlLmNoaWxkcmVuW2ldLmlkKyciIGNsYXNzPSJzdWJtZW51Ij4nK3hvb2tpLmh0bWwucGFnZUxpbmsocGFnZS5jaGlsZHJlbltpXSk7DQogICAgICAgICAgICAJCQlpZiAoc21lbnUuaW5kZXhPZignaWQ9Inhvb2tpLScreG9va2kucGFnZS5pZCsnIicpICE9IC0xIA0KICAgICAgICAgICAgCQkJCXx8IHBhZ2UuY2hpbGRyZW5baV0uaWQgPT0geG9va2kucGFnZS5pZCkgew0KICAgICAgICAgICAgCQkJCS8vIGVpdGhlciBhIGRlc2NlbmRhbnQgb3IgdGhlIG5vZGUgcHJvY2Vzc2VkIGlzIHRoZSBjdXJyZW50IHBhZ2Ugbm9kZQ0KICAgICAgICAgICAgCQkJCS8vIHdlIHNwZWNpZnkgdGhhdCB0aGUgbWVudSBtdXN0IGJlIG9wZW5lZCBieSBkZWZhdWx0DQogICAgICAgICAgICAJCQkJbWVudSArPSAnPHVsIGNsYXNzPSJvcGVuIic7DQogICAgCSAgICAgICAgCQkJbWVudSArPSAnPicrc21lbnUrJzwvdWw+JzsNCiAgICAgICAgICAgIAkJCX0gZWxzZSB7DQogICAgCQkJCQkJbWVudSArPSAnPHVsIGNsYXNzPSJjbG9zZWQiJzsNCiAgICAJICAgICAgICAJCQltZW51ICs9ICc+JytzbWVudSsnPC91bD4nOw0KICAgIAkJCQkJfQ0KICAgICAgICAgICAgCQl9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVudSArPSAnPGxpIGlkPSJ4b29raS0nK3BhZ2UuY2hpbGRyZW5baV0uaWQrJyI+Jyt4b29raS5odG1sLnBhZ2VMaW5rKHBhZ2UuY2hpbGRyZW5baV0pOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAJCW1lbnUgKz0gJzwvbGk+JzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgIAl9DQogICAgICAgIAlyZXR1cm4gbWVudTsNCiAgICAgICAgfSkoeG9va2kudG9jKTsNCiAgICAJbWVudSArPSAnPC91bD4nOw0KICAgIAlyZXR1cm4gbWVudTsNCiAgICB9LA0KICAgIA0KICAgIG1lc3NhZ2VzOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktbWVzc2FnZXMiIG9uY2xpY2s9Inhvb2tpLmh0bWwuaGlkZShcJ3hvb2tpLW1lc3NhZ2VzXCcpIiBzdHlsZT0iekluZGV4Ojk5OTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7dG9wOjMwcHg7cGFkZGluZzoxMHB4O2JvcmRlci1zdHlsZTpzb2xpZDtiYWNrZ3JvdW5kOiNlZWVlZWU7Ij48L2Rpdj4nOw0KICAgIH0sDQoNCiAgICBkZWJ1Z1BhbmVsOiBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiAnPGRpdiBpZD0ieG9va2ktZGVidWciIHN0eWxlPSJkaXNwbGF5Om5vbmU7bWFyZ2luLXRvcDoxNXB4O3BhZGRpbmc6MTBweDtib3JkZXItc3R5bGU6c29saWQ7YmFja2dyb3VuZDojZWVlZWVlOyI+PHN0cm9uZz5Yb29raSBDb25zb2xlPC9zdHJvbmc+PGJyLz48dGV4dGFyZWEgY29scz0iMTAwIiByb3dzPSIxNSIgaWQ9Inhvb2tpLWNvbnNvbGUiPicreG9va2kuY29uc29sZSsnPC90ZXh0YXJlYT48aHIvPjxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuZGVidWdTaG93RGV0YWlsKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwneG9va2ktYm9keVwnKS5pbm5lckhUTUwpIj5jb250ZW50PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbCh4b29raS5jLmJvZHkpIj54b29raSBib2R5PC9hPiA8YSBocmVmPSJqYXZhc2NyaXB0Onhvb2tpLmRlYnVnU2hvd0RldGFpbChkb2N1bWVudC5ib2R5LmlubmVySFRNTCkiPndob2xlIGJvZHk8L2E+IDxhIGhyZWY9ImphdmFzY3JpcHQ6eG9va2kuYWN0aW9uLmV2YWx1YXRlKCkiPmV2YWx1YXRlPC9hPjxici8+PHRleHRhcmVhIGNvbHM9IjEwMCIgcm93cz0iMTUiIGlkPSJ4b29raS1kZWJ1Zy1kZXRhaWwiPjwvdGV4dGFyZWE+PC9kaXY+JzsNCiAgICB9LA0KDQogICAgcHJpbnRlckZyaWVuZGx5TG9jYXRpb246IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuIHhvb2tpLnVybC5hY3Rpb24oInByaW50Iik7DQogICAgfSwNCg0KICAgIHByaW50ZXJGcmllbmRseUxpbms6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3RoaXMucHJpbnRlckZyaWVuZGx5TG9jYXRpb24oKSsnIj4nK3QoJ1ByaW50ZXIgRnJpZW5kbHknKSsnPC9hPic7DQogICAgfSwNCg0KICAgIGJyZWFkQ3J1bWI6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgdmFyIGJyZWFkQ3J1bWIgPSAnPHNwYW4gY2xhc3M9ImJyZWFkQ3J1bWIiPic7DQoJCWJyZWFkQ3J1bWIgKz0gKGZ1bmN0aW9uIChwYWdlKSB7DQogICAgICAgIAl2YXIgYnJlYWRDcnVtYiA9IHhvb2tpLmh0bWwucGFnZUxpbmsocGFnZSk7DQoJCQlpZiAocGFnZS5tZXRhLmxldmVsID49IDEpIHsNCgkJCQlicmVhZENydW1iID0gYXJndW1lbnRzLmNhbGxlZShwYWdlLm1ldGEucGFyZW50KSArICIgJmd0OyAiICsgYnJlYWRDcnVtYjsNCgkJCX0NCiAgICAgICAgCXJldHVybiBicmVhZENydW1iOw0KICAgICAgICB9KSh4b29raS5wYWdlKTsNCgkJYnJlYWRDcnVtYiArPSAnPC9zcGFuPic7DQoJCXJldHVybiBicmVhZENydW1iOw0KICAgIH0NCn07DQoNCnhvb2tpLnJlbmRlciA9IHt9Ow0KeG9va2kucmVuZGVyLnByaW50ZXJGcmllbmRseUFzeW5jTG9hZGVyID0gZnVuY3Rpb24oc291cmNlLCBhcnIpIHsNCgl2YXIgcm9vdCA9IGFyclswXTsNCgl2YXIgcGFnZSA9IGFyclsxXTsNCiAgICBpZiAoc291cmNlID09IG51bGwpIHsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCgl2YXIgbGV2ZWwgPSBwYWdlLm1ldGEubGV2ZWwgLSByb290Lm1ldGEubGV2ZWwgKyAxOw0KCQ0KICAgIC8vIGNvbXB1dGUgcHJpbnRlciBmcmllbmRseSBibG9jaw0KICAgIHZhciBiZWdpbkluZGV4ID0gc291cmNlLmluZGV4T2YoJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nKTsNCiAgICBiZWdpbkluZGV4ICs9ICc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jy5sZW5ndGg7DQogICAgdmFyIGVuZEluZGV4ID0gc291cmNlLmxhc3RJbmRleE9mKCc8L3RleHRhcmVhPicpOw0KICAgIHNvdXJjZSA9IHNvdXJjZS5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpOw0KICAgIA0KICAgIHZhciBwcmludGVyRnJpZW5kbHkgPSAiPGgiK2xldmVsKyI+IitwYWdlLnRpdGxlKyI8L2giK2xldmVsKyI+IjsNCiAgICBwcmludGVyRnJpZW5kbHkgKz0geG9va2kuaW5wdXQuZm9ybWF0Lm1haW4oc291cmNlKSArICI8aHIvPiI7DQogICAgLy8gaW5qZWN0IGJsb2NrIGluIHBhZ2UNCiAgICB2YXIgcGYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktcHJpbnRlckZyaWVuZGx5Jyk7DQogICAgcGYuaW5uZXJIVE1MICs9IHByaW50ZXJGcmllbmRseTsgICAgDQogICAgDQogICAgLy8gY29udGludWUgcmVjdXJzaXZlIGxvYWRpbmcNCiAgIAl2YXIgbmV4dFBhZ2UgPSB4b29raS50b2MuZ2V0TmV4dFBhZ2UocGFnZSwgcm9vdCk7DQogICAJaWYgKG5leHRQYWdlICE9IG51bGwpIHsNCiAgICAJeG9va2kudXJsLmFzeW5jTG9hZFVSTChwdShuZXh0UGFnZS5pZCksIHhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHlBc3luY0xvYWRlciwgW3Jvb3QsIG5leHRQYWdlXSk7DQogICAJfQ0KfTsNCg0KeG9va2kucmVuZGVyLnByaW50ZXJGcmllbmRseUFzeW5jID0gZnVuY3Rpb24oKSB7DQoJeG9va2kuYy5ib2R5ID0geG9va2kuYy5tZXNzYWdlcw0KCSsgIjxkaXYgaWQ9J3hvb2tpLXByaW50ZXJGcmllbmRseSc+PC9kaXY+IiAvLyBkaXYgd2hlcmUgcHJpbnRlciBmcmllbmRseSBjb250ZW50IHdpbGwgYmUgcHV0DQogICAgKyB4b29raS5jLmRlYnVnUGFuZWw7DQogICAgDQogICAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSB4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpOw0KICAgIA0KICAgIC8vIHN0YXJ0IGFzeW5jIGxvYWRpbmcgb2YgY29udGVudA0KICAgIHhvb2tpLnVybC5hc3luY0xvYWRVUkwocHUoeG9va2kucGFnZS5pZCksIHhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHlBc3luY0xvYWRlciwgW3hvb2tpLnBhZ2UsIHhvb2tpLnBhZ2VdKTsNCn07DQoNCnhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHlTeW5jID0gZnVuY3Rpb24oKSB7DQoJeG9va2kuYy5ib2R5ID0geG9va2kuYy5tZXNzYWdlcw0KICAgICsgKGZ1bmN0aW9uIChwYWdlLCBsZXZlbCkgew0KICAgICAgICB2YXIgc291cmNlID0geG9va2kudXJsLmxvYWRVUkwocHUocGFnZS5pZCkpOw0KICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsNCiAgICAgICAgICAgIHJldHVybiAiIjsNCiAgICAgICAgfQ0KICAgICAgICB2YXIgYmVnaW5JbmRleCA9IHNvdXJjZS5pbmRleE9mKCc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jyk7DQogICAgICAgIGJlZ2luSW5kZXggKz0gJzx0ZXh0YXJlYSBpZD0ieG9va2ktc291cmNlIj4nLmxlbmd0aDsNCiAgICAgICAgdmFyIGVuZEluZGV4ID0gc291cmNlLmxhc3RJbmRleE9mKCc8L3RleHRhcmVhPicpOw0KICAgICAgICBzb3VyY2UgPSBzb3VyY2Uuc3Vic3RyaW5nKGJlZ2luSW5kZXgsIGVuZEluZGV4KTsNCiAgICAgICAgDQogICAgICAgIHZhciBwcmludGVyRnJpZW5kbHkgPSAiPGRpdiBjbGFzcz0ndG9jLXRpdGxlIHRvYy10aXRsZS0iK2xldmVsKyInPiIrcGFnZS50aXRsZSsiPC9kaXY+IjsNCiAgICAgICAgcHJpbnRlckZyaWVuZGx5ICs9IHhvb2tpLmlucHV0LmZvcm1hdC5tYWluKHNvdXJjZSk7DQogICAgICAgIGZvciAodmFyIGk9MDsgaSA8cGFnZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgcHJpbnRlckZyaWVuZGx5ICs9ICI8aHIvPiI7DQogICAgICAgICAgICBwcmludGVyRnJpZW5kbHkgKz0gYXJndW1lbnRzLmNhbGxlZShwYWdlLmNoaWxkcmVuW2ldLCBsZXZlbCsxKTsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcHJpbnRlckZyaWVuZGx5Ow0KICAgIH0pKHhvb2tpLnBhZ2UsIDEpOw0KICAgIA0KICAgIHhvb2tpLmh0bWwuc2V0Qm9keSh4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmJvZHksIHhvb2tpLmMpKTsNCn07DQoNCnhvb2tpLnJlbmRlci5wcmludGVyRnJpZW5kbHkgPSBmdW5jdGlvbigpIHsNCiAgICBmb3IgKHZhciBrIGluIHhvb2tpLmNvbXBvbmVudCkgew0KICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQogICAgfQ0KICAgIA0KCWlmIChiYXRjaE1vZGUpIHsNCgkJeG9va2kucmVuZGVyLnByaW50ZXJGcmllbmRseVN5bmMoKTsNCgl9IGVsc2Ugew0KCQl4b29raS5yZW5kZXIucHJpbnRlckZyaWVuZGx5QXN5bmMoKTsNCgl9DQp9Ow0KDQoNCnhvb2tpLnJlbmRlci5wYWdlID0gZnVuY3Rpb24oKSB7DQogICAgLy8gcmVhbGl6ZSBhbGwgY29tcG9uZW50cyBhdmFpbGFibGUNCiAgICBmb3IgKHZhciBrIGluIHhvb2tpLmNvbXBvbmVudCkgew0KICAgICAgICB4b29raS5jW2tdID0geG9va2kuY29tcG9uZW50W2tdKCk7DQogICAgfQ0KICAgIA0KICAgIHhvb2tpLmlucHV0LnNvdXJjZSgpOw0KICAgIA0KICAgIGlmICh4b29raS5jLmFsbG93RWRpdCkgew0KICAgIAl4b29raS5jLmJvZHkgPSB4b29raS5jLm1lc3NhZ2VzDQogICAgICAgICAgICArIHhvb2tpLmMudG9vbGJhcg0KICAgICAgICAgICAgKyAnPGRpdiBpZD0ieG9va2ktY29udGVudCI+JyANCiAgICAgICAgICAgICAgICArICc8ZGl2IGlkPSJ4b29raS1ib2R5Ij48L2Rpdj4nDQogICAgICAgICAgICArICc8L2Rpdj4nDQogICAgICAgICAgICArIHhvb2tpLmMuZWRpdFpvbmUNCiAgICAgICAgICAgICsgeG9va2kuYy5kZWJ1Z1BhbmVsOw0KICAgIH0gZWxzZSB7DQogICAgCXhvb2tpLmMuYm9keSA9IHhvb2tpLmMubWVzc2FnZXMNCiAgICAgICAgICAgICsgJzxkaXYgaWQ9Inhvb2tpLWNvbnRlbnQiPicgDQogICAgICAgICAgICAgICAgKyAnPGRpdiBpZD0ieG9va2ktYm9keSI+PC9kaXY+Jw0KICAgICAgICAgICAgKyAnPC9kaXY+Jw0KICAgICAgICAgICAgKyB4b29raS5jLmRlYnVnUGFuZWw7DQogICAgfQ0KDQogICAgeG9va2kuaHRtbC5zZXRCb2R5KHhvb2tpLnN0cmluZy5wcm9jZXNzVGVtcGxhdGUoeG9va2kudGVtcGxhdGUuYm9keSwgeG9va2kuYykpOw0KICAgIA0KICAgIHhvb2tpLmlucHV0LmFwcGx5Q2hhbmdlcygpOw0KfTsNCg0KeG9va2kucmVuZGVyLm1haW4gPSBmdW5jdGlvbigpIHsNCiAgICBpZiAoeG9va2kuYy5hY3Rpb24gPT0gInByaW50Iikgew0KICAgICAgICAvLyByZW5kZXIgdGhlIHByaW50ZXIgZnJpZW5kbHkgdmVyc2lvbiBvZiB0aGUgcGFnZQ0KICAgICAgICB0aGlzLnByaW50ZXJGcmllbmRseSgpOw0KICAgIH0gZWxzZSB7DQogICAgICAgIC8vIHJlbmRlciB0aGUgcGFnZSBub3JtYWxseQ0KICAgICAgICB0aGlzLnBhZ2UoKTsNCiAgICB9DQp9Ow0KDQp4b29raS5pbnB1dCA9IHsNCiAgICBzb3VyY2U6IGZ1bmN0aW9uKCkgew0KICAgICAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9ICd1bmRlZmluZWQnICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd4b29raS1zb3VyY2UnKSAhPSBudWxsKSB7DQogICAgICAgICAgICB0aGlzLl9zb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgneG9va2ktc291cmNlJykudmFsdWU7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZTsNCiAgICB9LA0KICAgIHByb2Nlc3NlZDogZnVuY3Rpb24oKSB7DQogICAgICAgIHJldHVybiB0aGlzLmZvcm1hdC5tYWluKHRoaXMuc291cmNlKCkpOw0KICAgIH0sDQogICAgDQogICAgZm9ybWF0OiB7DQogICAgICAgIGdldElucHV0RmlsdGVyczogZnVuY3Rpb24gKGlucHV0Rm9ybWF0KSB7DQogICAgICAgICAgICByZXR1cm4geG9va2kuY1tpbnB1dEZvcm1hdCsiSW5wdXRGb3JtYXQiXTsNCiAgICAgICAgfSwNCiAgICAgICAgZGVmaW5lOiBmdW5jdGlvbiAoaW5wdXRGb3JtYXQsIGZpbHRlcnMpIHsNCiAgICAgICAgICAgIC8vIGRlZmluZSBhIG5ldyBpbnB1dEZvcm1hdA0KICAgICAgICAgICAgLy8gaW5wdXRGb3JtYXQ6IHRoZSBuZXcgaW5wdXQgZm9ybWF0IG5hbWUNCiAgICAgICAgICAgIC8vIGZpbHRlcnM6IGFuIGFycmF5IG9mIGlucHV0IGZpbHRlciBuYW1lcw0KICAgICAgICAgICAgeG9va2kuY1tpbnB1dEZvcm1hdCsiSW5wdXRGb3JtYXQiXSA9IGZpbHRlcnM7DQogICAgICAgIH0sDQogICAgICAgIG1haW46IGZ1bmN0aW9uKHNvdXJjZSkgew0KICAgICAgICAgICAgLy8gZm9ybWF0cyBhbiBpbnB1dCBzb3VyY2UNCiAgICAgICAgICAgIGlmICh4b29raS5jLmlucHV0Rm9ybWF0ICYmIHR5cGVvZiB0aGlzLmdldElucHV0RmlsdGVycyh4b29raS5jLmlucHV0Rm9ybWF0KSAhPSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIGZvcm1hdCA9IHhvb2tpLmMuaW5wdXRGb3JtYXQ7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGZvcm1hdCA9IHhvb2tpLmMuZGVmYXVsdElucHV0Rm9ybWF0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmlsdGVycyA9IHRoaXMuZ2V0SW5wdXRGaWx0ZXJzKGZvcm1hdCk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGZpbHRlcnMpIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZpbHRlcnNbaV0gPT0gJ3N0cmluZycpIHsNCiAgICAJCQkJeG9va2kuZGVidWcoJ3Byb2Nlc3NpbmcgZmlsdGVyICcrZmlsdGVyc1tpXSk7DQogICAgICAgICAgICAgICAgICAgIGYgPSB4b29raS5pbnB1dC5maWx0ZXJzW2ZpbHRlcnNbaV1dOw0KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGYgPT0gImZ1bmN0aW9uIikgew0KICAgICAgICAgICAgICAgICAgICAJdHJ5IHsNCiAgICAgICAgICAgICAgICAgICAgICAgIAlzb3VyY2UgPSBmKHNvdXJjZSk7IC8vIHByb2Nlc3MgZmlsdGVyDQogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7DQogICAgCSAgICAgICAgICAgICAgICAgICAgeG9va2kuZXJyb3IoZSwgdCgiZXJyb3Igb2NjdXJlZCB3aGlsZSBwcm9jZXNzaW5nIGZpbHRlciAkezB9IiwgZmlsdGVyc1tpXSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgeG9va2kuZXJyb3IodCgidW5rbm93biBmaWx0ZXIgJHswfSB1c2VkIGluIGlucHV0IGZvcm1hdCAkezF9IiwgZmlsdGVyc1tpXSwgZm9ybWF0KSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gc291cmNlOw0KICAgICAgICB9DQogICAgfSwgDQogICAgDQogICAgZmlsdGVyczogew0KICAgICAgICB1cmw6IGZ1bmN0aW9uIChpbnB1dCkgew0KICAgICAgICAgICAgLy8gaGFuZGxlIHVybHMNCiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIig/OmZpbGV8aHR0cHxodHRwc3xtYWlsdG98ZnRwKTpbXlxccydcIl0rKD86L3xcXGIpIiwgImciKSwgZnVuY3Rpb24gKHN0ciwgb2Zmc2V0LCBzKSB7DQogICAgICAgICAgICAgICAgdmFyIGJlZm9yZSA9IHMuc3Vic3RyaW5nKDAsb2Zmc2V0KTsNCiAgICAgICAgICAgICAgICBpZiAoYmVmb3JlLm1hdGNoKC8oaHJlZnxzcmMpPSIkLykpIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9Iicrc3RyKyciPicrc3RyKyc8L2E+JzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIHNob3J0Y3V0czogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgICAgICAvLyBoYW5kbGUgc2hvcnRjdXQgbGlua3MgbGlrZSB0aGlzOg0KICAgICAgICAgICAgLy8gICAgW1tzdm46YnVpbGQueG1sXV0gPT4gPGEgaHJlZj0iaHR0cHM6Ly94b29raS5zdm4uc291cmNlZm9yZ2UubmV0L3N2bnJvb3QveG9va2kvdHJ1bmsvYnVpbGQueG1sIj5idWlsZC54bWw8L2E+DQogICAgICAgICAgICAvLyAgICBbW3N2bjp0ZXN0L2V4YW1wbGUuanMgYSBnb29kIGV4YW1wbGVdXSA9PiA8YSBocmVmPSJodHRwczovL3hvb2tpLnN2bi5zb3VyY2Vmb3JnZS5uZXQvc3Zucm9vdC94b29raS90cnVuay90ZXN0L2V4YW1wbGUuanMiPmEgZ29vZCBleGFtcGxlPC9hPg0KICAgICAgICAgICAgLy8gbmVlZHMgdG8gYmUgY29uZmlndXJlZCBpbiB4b29raSBjb25maWcgbGlrZSB0aGlzDQogICAgICAgICAgICAvLyAgICAgIHhvb2tpLmMuc2hvcnRjdXRzLjxhbnkgc2hvcnRjdXQ+LnVybCA9IGJhc2UgdXJsIG9mIHRoZSBzaG9ydGN1dC4gDQogICAgICAgICAgICAvLyAgICAgIGV4OiB4b29raS5jLnNob3J0Y3V0cy5zdm4udXJsID0gaHR0cHM6Ly94b29raS5zdm4uc291cmNlZm9yZ2UubmV0L3N2bnJvb3QveG9va2kvdHJ1bmsvDQogICAgICAgICAgICByZXR1cm4gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJcXFtcXFsoW146XG5dKyk6KFteXFxdXG5dKylcXF1cXF0iLCAiZyIpLCBmdW5jdGlvbiAoc3RyLCBwcmVmaXgsIGNvZGUsIG9mZnNldCwgcykgew0KICAgICAgICAgICAgCWlmICh0eXBlb2YgeG9va2kuYy5zaG9ydGN1dHMgPT0gInVuZGVmaW5lZCIgfHwgdHlwZW9mIHhvb2tpLmMuc2hvcnRjdXRzW3ByZWZpeF0gPT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgICAgICAgeG9va2kuZGVidWcoJ3Vua25vd24gc2hvcnRjdXQgJytwcmVmaXgpOw0KICAgICAgICAgICAgCQlyZXR1cm4gc3RyOw0KICAgICAgICAgICAgCX0NCiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBjb2RlLmluZGV4T2YoJyAnKTsNCiAgICAgICAgICAgICAgICB2YXIgcGF0aCA9IGluZGV4PjA/Y29kZS5zdWJzdHJpbmcoMCxpbmRleCk6Y29kZTsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICB2YXIgdGl0bGUgPSBpbmRleD4wP2NvZGUuc3Vic3RyaW5nKGluZGV4KzEpOnBhdGg7DQogICAgICAgICAgICAgICAgdmFyIHByZSA9IHR5cGVvZiB4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnByZSA9PSAidW5kZWZpbmVkIj8nJzp4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnByZTsNCiAgICAgICAgICAgICAgICB2YXIgcG9zdCA9IHR5cGVvZiB4b29raS5jLnNob3J0Y3V0c1twcmVmaXhdLnBvc3QgPT0gInVuZGVmaW5lZCI/Jyc6eG9va2kuYy5zaG9ydGN1dHNbcHJlZml4XS5wb3N0Ow0KICAgICAgICAgICAgICAgIHJldHVybiAnPGEgaHJlZj0iJytwcmUrcGF0aCtwb3N0KyciPicrdGl0bGUrJzwvYT4nOw0KICAgICAgICAgICAgfSk7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICB4b29raUxpbmtzOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgICAgIC8vIGhhbmRsZSB4b29raSBsaW5rcyBsaWtlIHRoaXM6DQogICAgICAgICAgICAvLyAgICBbW3BhZ2UvaWRdXQ0KICAgICAgICAgICAgLy8gICAgW1twYWdlL2lkIE15IFRpdGxlXV0NCiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIlxcW1xcWyhbXlxcXV0rKVxcXVxcXSIsICJnIiksIGZ1bmN0aW9uIChzdHIsIGNvZGUsIG9mZnNldCwgcykgew0KICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGNvZGUuaW5kZXhPZignICcpOw0KICAgICAgICAgICAgICAgIHZhciBpZCA9IChpbmRleD4wP2NvZGUuc3Vic3RyaW5nKDAsaW5kZXgpOmNvZGUpOw0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciB0aXRsZTsNCiAgICAgICAgICAgICAgICB2YXIgdXJsOw0KICAgICAgICAgICAgICAgIHZhciBpbnZhbGlkID0gZmFsc2U7DQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB4b29raS50b2MucGFnZXNbeG9va2kudG9jLmltcG9ydFJvb3QgKyBpZF0gIT0gInVuZGVmaW5lZCIpIHsNCiAgICAgICAgICAgICAgIAkgICAgdGl0bGUgPSB4b29raS50b2MucGFnZXNbeG9va2kudG9jLmltcG9ydFJvb3QgKyBpZF0udGl0bGU7DQogICAgICAgICAgICAgICAgICAgIHVybCA9IHB1KHhvb2tpLnRvYy5pbXBvcnRSb290ICsgaWQpOw0KICAgICAgICAgICAgICAgCX0gZWxzZSBpZiAoeG9va2kudG9jLmltcG9ydFJvb3QubGVuZ3RoID4gMCAmJiB0eXBlb2YgeG9va2kudG9jLnBhZ2VzW2lkXSAhPSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgCSAgICB0aXRsZSA9IHhvb2tpLnRvYy5wYWdlc1tpZF0udGl0bGU7DQogICAgICAgICAgICAgICAgICAgIHVybCA9IHB1KGlkKTsNCiAgICAgICAgICAgICAgIAl9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBpbnZhbGlkID0gdHJ1ZTsNCiAgICAgICAgICAgICAgIAkJdGl0bGUgPSBjb2RlOw0KICAgICAgICAgICAgICAgCQl1cmwgPSB1KGlkKTsNCiAgICAgICAgICAgICAgIAl9DQogICAgICAgICAgICAgICAgaWYgKGluZGV4PjApIHsNCiAgICAgICAgICAgICAgICAJdGl0bGUgPSBjb2RlLnN1YnN0cmluZyhpbmRleCsxKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGludmFsaWQpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGJhdGNoTW9kZSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90IG91dHB1dCBpbnZhbGlkIGxpbmtzIGFzIGxpbmtzIGluIGJhdGNoIG1vZGUNCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aXRsZTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aXRsZSsnPGEgaHJlZj0iJyt1cmwrJyI+PzwvYT4nOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8YSBocmVmPSInK3VybCsnIj4nK3RpdGxlKyc8L2E+JzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIHdpa2lNYXJrdXA6IGZ1bmN0aW9uIChpbnB1dCkgeyANCiAgICAgICAgICAgIC8vIGhhbmRsZSBib2xkDQogICAgICAgICAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UobmV3IFJlZ0V4cCgiXFwqKFteXG5dKylcXCoiLCAiZyIpLCAiPGI+JDE8L2I+Iik7DQogICAgICAgICAgICANCiAgICAgICAgICAgIC8vIGhhbmRsZSBpdGFsaWMNCiAgICAgICAgICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCJcXF8oW15cbl0rKVxcXyIsICJnIiksICI8ZW0+JDE8L2VtPiIpOw0KICAgICAgICAgICAgDQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0sDQogICAgICAgIA0KICAgICAgICBqaXJhOiBmdW5jdGlvbiAoaW5wdXQpIHsgDQogICAgICAgICAgICAvLyBhdXRvIHJlcGxhY2UgamlyYSBpc3N1ZSBpZHMgKGxpa2UgSVZZLTEyKSBieSBhIGxpbmsgdG8gdGhlIGlzc3VlDQogICAgICAgICAgICAvLyBuZWVkcyB0byBiZSBjb25maWd1cmVkIGluIHhvb2tpIGNvbmZpZyBsaWtlIHRoaXMNCiAgICAgICAgICAgIC8vICAgICAgeG9va2kuYy5qaXJhLmlkcyA9IGFuIGFycmF5IG9mIGppcmEgcHJvamVjdHMgaWRzIChleDogWyJJVlkiLCAiQU5UIl0pDQogICAgICAgICAgICAvLyAgICAgIHhvb2tpLmMuamlyYS51cmwgPSB0aGUgdXJsIG9mIHRoZSBqaXJhIHNlcnZlciAoZXg6ICJodHRwOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYSIpDQogICAgICAgICAgICBpZiAodHlwZW9mIHhvb2tpLmMuamlyYSAhPSAib2JqZWN0Iikgew0KICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZShuZXcgUmVnRXhwKCIoKCIreG9va2kuYy5qaXJhLmlkcy5qb2luKCJ8IikrIiktXFxkKykoW15cIlxcZF0pIiwgImciKSwgJzxhIGhyZWY9IicreG9va2kuYy5qaXJhLnVybCsnL2Jyb3dzZS8kMSI+JDE8L2E+JDMnKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgY29kZTogZnVuY3Rpb24gKGlucHV0KSB7DQogICAgICAgICAgICBjb2RlU2VjdGlvbiA9IHhvb2tpLnN0cmluZy5maW5kWG1sU2VjdGlvbihpbnB1dCwgImNvZGUiKTsNCiAgICAgICAgICAgIGZyb20gPSAwOw0KICAgICAgICAgICAgd2hpbGUgKGNvZGVTZWN0aW9uICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICBwcm9jZXNzZWRTZWN0aW9uID0gIjxwcmU+IiANCiAgICAgICAgICAgICAgICAgICAgKyBpbnB1dC5zdWJzdHJpbmcoY29kZVNlY3Rpb24uaW5uZXJTdGFydCwgY29kZVNlY3Rpb24uaW5uZXJFbmQpLnJlcGxhY2UoLzwvZywgIiZsdDsiKS5yZXBsYWNlKC8+L2csICImZ3Q7IikgLy8gLnJlcGxhY2UoL1xuL2csICI8YnIvPiIpDQogICAgICAgICAgICAgICAgICAgICsgIjwvcHJlPiI7DQogICAgICAgICAgICAgICAgaW5wdXQgPSBpbnB1dC5zdWJzdHJpbmcoMCwgY29kZVNlY3Rpb24ub3V0ZXJTdGFydCkNCiAgICAgICAgICAgICAgICAgICAgKyBwcm9jZXNzZWRTZWN0aW9uDQogICAgICAgICAgICAgICAgICAgICsgaW5wdXQuc3Vic3RyaW5nKGNvZGVTZWN0aW9uLm91dGVyRW5kKTsNCiAgICAgICAgICAgICAgICBmcm9tID0gY29kZVNlY3Rpb24ub3V0ZXJTdGFydCArIHByb2Nlc3NlZFNlY3Rpb24ubGVuZ3RoOw0KICAgIA0KICAgICAgICAgICAgICAgIGNvZGVTZWN0aW9uID0geG9va2kuc3RyaW5nLmZpbmRYbWxTZWN0aW9uKGlucHV0LCAiY29kZSIsIGZyb20pOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICB9LA0KICAgICAgICANCiAgICAgICAgbGluZUJyZWFrOiBmdW5jdGlvbiAoaW5wdXQpIHsNCiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKG5ldyBSZWdFeHAoIlxyP1xuIiwgImciKSwgZnVuY3Rpb24gKHN0ciwgb2Zmc2V0LCBzKSB7DQogICAgICAgICAgICAgICAgdmFyIGJlZm9yZSA9IHMuc3Vic3RyaW5nKDAsb2Zmc2V0KTsNCiAgICAgICAgICAgICAgICB2YXIgYWZ0ZXIgPSBzLnN1YnN0cmluZyhvZmZzZXQrc3RyLmxlbmd0aCk7DQogICAgICAgICAgICAgICAgaWYgKGFmdGVyLm1hdGNoKC9ePFwvPyh1bHx0YWJsZXxsaXxwcmV8ZGl2KShccypcdys9IlteIl0rIikqXHMqPi9pKSB8fCAoYmVmb3JlLm1hdGNoKC88XC8/XHcrKFxzKlx3Kz0iW14iXSsiKSpccypcLz8+XHMqJC9pKSAmJiAhYmVmb3JlLm1hdGNoKC88XC8/KGF8YnxzdHJvbmd8ZW18aXxiaWd8YnIgY2xhc3M9Inhvb2tpLWJyIikoXHMqXHcrPSJbXiJdKyIpKlxzKlwvPz5ccyokL2kpKSkgeyANCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdcbic7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8YnIgY2xhc3M9Inhvb2tpLWJyIi8+JzsgLy8gdGhlIGNsYXNzIGlzIG5vdCByZWFsbHkgbmVjZXNzYXJ5IGJ1dCBhbGxvdyB0byBkaXN0aW5ndWlzaCBnZW5lcmF0ZWQgYnIgZnJvbSBpbnB1dCBvbmUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9KTsNCiAgICAgICAgfSwNCiAgICAgICAgDQogICAgICAgIGluY2x1ZGVzOiBmdW5jdGlvbiAoaW5wdXQpIHsNCgkgICAgICAgIC8vWzx1cmw+XSByZXBsYWNlZCBieSB0aGUgY29udGVudCBvZiB0aGUgdXJsDQoJICAgICAgICByZXN1bHQgPSAiIjsNCgkgICAgICAgIGxhc3RTdGFydCA9IDA7DQoJICAgICAgICBuZXh0UG9zID0gaW5wdXQuaW5kZXhPZigiWzwiICwgbGFzdFN0YXJ0KTsNCgkgICAgICAgIHdoaWxlKCBuZXh0UG9zID4gMCApIHsNCgkJICAgICAgICByZXN1bHQgPSByZXN1bHQgKyBpbnB1dC5zbGljZShsYXN0U3RhcnQsbmV4dFBvcyk7DQoJCSAgICAgICAgbGFzdFN0YXJ0ID0gbmV4dFBvczsNCgkJICAgICAgICBuZXh0UG9zID0gaW5wdXQuaW5kZXhPZigiPl0iICwgbGFzdFN0YXJ0KTsNCgkJICAgICAgICByZXN1bHQgPSByZXN1bHQgKyB4b29raS51cmwubG9hZFVSTChsdShpbnB1dC5zbGljZShsYXN0U3RhcnQrMixuZXh0UG9zKSkpOw0KCQkgICAgICAgIGxhc3RTdGFydCA9IG5leHRQb3MgKyAyOw0KCQkgICAgICAgIG5leHRQb3MgPSBpbnB1dC5pbmRleE9mKCJbPCIgLCBsYXN0U3RhcnQpOw0KCSAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCArIGlucHV0LnNsaWNlKGxhc3RTdGFydCk7DQogICAgICAgIH0NCiAgICB9LA0KICAgIA0KICAgIA0KICAgIGFwcGx5Q2hhbmdlczogZnVuY3Rpb24oKSB7DQogICAgCWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd4b29raS1ib2R5JykuaW5uZXJIVE1MID0geG9va2kuaW5wdXQucHJvY2Vzc2VkKCk7DQogICAgfQ0KfTsNCg0KDQp4b29raS5wb3N0UHJvY2VzcyA9IGZ1bmN0aW9uKCkgew0KCXhvb2tpLnJlbmRlci5tYWluKCk7DQoJd2luZG93Lm9ua2V5cHJlc3MgPSBrZXlDdHJsOw0KfTsNCg0KDQppZiAodHlwZW9mIHhvb2tpLmlvID09ICJ1bmRlZmluZWQiKSB7DQogICAgeG9va2kuaW8gPSB7fTsNCn0NCg0KDQp4b29raS5hY3Rpb24gPSB7fQ0KeG9va2kuYWN0aW9uLnRvZ2dsZURlYnVnID0gZnVuY3Rpb24oKSB7DQogICAgaWYgKHhvb2tpLmMuZGVidWcpIHsNCiAgICAJaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd4b29raS1kZWJ1ZycpLnN0eWxlLmRpc3BsYXkgPT0gJ25vbmUnKSB7DQogICAgCQl4b29raS5odG1sLnNob3coJ3hvb2tpLWRlYnVnJyk7DQogICAgCX0gZWxzZSB7DQogICAgCQl4b29raS5odG1sLmhpZGUoJ3hvb2tpLWRlYnVnJyk7DQogICAgCX0NCgl9DQp9DQp4b29raS5hY3Rpb24uZXZhbHVhdGUgPSBmdW5jdGlvbiAoKSB7DQogICAgdmFyIGV4cCA9IHByb21wdCgiUGxlYXNlIGVudGVyIGphdmFzY3JpcHQgZXhwcmVzc2lvbiB0byBldmFsdWF0ZSIpOw0KICAgIHhvb2tpLmRlYnVnU2hvd0RldGFpbChldmFsKGV4cCkpOw0KfQ0KDQovLyBUT0RPLCByZXZpZXcgdXNlIHJlZ2lzdHJhdGlvbg0KZnVuY3Rpb24ga2V5Q3RybChldnQpIHsNCgl2YXIgY29kZSA9IHhvb2tpLmMuYnJvd3Nlci5OUyA/IGV2dC53aGljaCA6IGV2ZW50LmtleUNvZGU7DQoJdmFyIGN0cmwgPSB4b29raS5jLmJyb3dzZXIuTlMgPyBldnQuY3RybEtleSA6IGV2ZW50LmN0cmxLZXk7DQogIAl2YXIga2V5ID0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTsNCglpZiAoeG9va2kuYy5kZWJ1ZyAmJiBjdHJsICYmICJkIiA9PSBrZXkpIHsNCgkJeG9va2kuYWN0aW9uLnRvZ2dsZURlYnVnKCk7DQoJCXJldHVybiBmYWxzZTsNCgl9DQoJaWYgKHhvb2tpLmMuYWxsb3dFZGl0ICYmIGN0cmwgJiYgInMiID09IGtleSkgew0KCQl4b29raS5hY3Rpb24uc2F2ZUNoYW5nZXMoKTsNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCglpZiAoeG9va2kuYy5hbGxvd0VkaXQgJiYgY3RybCAmJiAiZSIgPT0ga2V5KSB7DQoJCXhvb2tpLmFjdGlvbi50b2dnbGVFZGl0KCk7DQoJCXJldHVybiBmYWxzZTsNCgl9DQp9DQoNCi8vIHhvb2tpIGVuZ2luZSBpbml0IGZ1bmN0aW9uDQp4b29raS5pbml0ID0gZnVuY3Rpb24oKSB7DQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBjb25maWcgaW5pdA0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICBpbml0Q29uZmlnUHJvcGVydHkgPSBmdW5jdGlvbihwcm9wLCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7DQogICAgICAgIGlmICh0eXBlb2YgdGhpc1twcm9wXSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAidW5kZWZpbmVkIikgew0KICAgICAgICAgICAgICAgIHRoaXNbcHJvcF0gPSBkZWZhdWx0VmFsdWU7DQogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PSAiZnVuY3Rpb24iKSB7DQogICAgICAgICAgICAgICAgdGhpc1twcm9wXSA9IHZhbHVlKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRoaXNbcHJvcF0gPSB2YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH07DQogICAgaWYgKHR5cGVvZiB4b29raUNvbmZpZyAhPSAidW5kZWZpbmVkIikge3hvb2tpLnV0aWwubWl4KHhvb2tpQ29uZmlnLCB4b29raS5jb25maWcpO30NCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSA9IGluaXRDb25maWdQcm9wZXJ0eTsNCiAgICB4b29raS5jLmNvbXB1dGVSb290ID0gZnVuY3Rpb24oKSB7DQogICAgCXJvb3QgPSB4b29raS5wYWdlVVJMOw0KICAgIAkvLyByZW1vdmUgdHJhaWxpbmcgcGFydHMgb2YgdGhlIFVSTCB0byBnbyB0aGUgcm9vdCBkZXBlbmRpbmcgb24gbGV2ZWwNCiAgICAJZm9yICh2YXIgaT0wOyBpIDwgeG9va2kuYy5sZXZlbCArIDE7IGkrKykgew0KICAgIAkJcm9vdCA9IHJvb3Quc3Vic3RyaW5nKDAsIHJvb3QubGFzdEluZGV4T2YoJy8nKSk7DQogICAgCX0NCiAgICAJcmV0dXJuIHJvb3QgKyAnLyc7DQogICAgfTsNCiAgICB4b29raS5jLmNvbXB1dGVSZWxhdGl2ZVJvb3QgPSBmdW5jdGlvbigpIHsNCiAgICAJcmV0dXJuIHhvb2tpLnN0cmluZy5tdWwoJy4uLycsIHhvb2tpLmMubGV2ZWwpOw0KICAgIH07DQogICAgeG9va2kuYy5zZXRJbXBvcnRMZXZlbCA9IGZ1bmN0aW9uKGxldmVsKSB7DQogICAgICAgIC8vIGNvbXB1dGUgcm9vdHMgd2l0aCBvbGQgbGV2ZWwgdmFsdWUsIGZvciBwYXRocyByZWxhdGl2ZSB0byB0aGUgbG9jYWwgKG5vbiBpbXBvcnRlZCkgcm9vdA0KICAgICAgICB0aGlzLmxvY2FsUm9vdCA9IHRoaXMuY29tcHV0ZVJvb3QoKTsNCiAgICAgICAgdGhpcy5sb2NhbFJlbGF0aXZlUm9vdCA9IHRoaXMuY29tcHV0ZVJlbGF0aXZlUm9vdCgpOw0KICAgICAgICAvLyBjaGFuZ2UgbGV2ZWwgYW5kIHVwZGF0ZSByb290cw0KICAgICAgICB0aGlzLmxldmVsKz1sZXZlbDsNCiAgICAgICAgdGhpcy5yb290ID0gdGhpcy5jb21wdXRlUm9vdCgpOw0KICAgICAgICB0aGlzLnJlbGF0aXZlUm9vdCA9IHRoaXMuY29tcHV0ZVJlbGF0aXZlUm9vdCgpOw0KICAgIH07DQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoImxldmVsIiwgMCk7DQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoInJvb3QiLCB4b29raS5jLmNvbXB1dGVSb290KTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgicmVsYXRpdmVSb290IiwgeG9va2kuYy5jb21wdXRlUmVsYXRpdmVSb290KTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgibG9jYWxSb290IiwgeG9va2kuYy5yb290KTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgibG9jYWxSZWxhdGl2ZVJvb3QiLCB4b29raS5jLnJlbGF0aXZlUm9vdCk7DQogICAgZ2xvYmFsQ29uZmlnID0geG9va2kudXJsLmxvYWRVUkwodSgiY29uZmlnLmpzb24iKSwgZmFsc2UpOw0KICAgIGlmIChnbG9iYWxDb25maWcgIT0gbnVsbCkgew0KICAgICAgICBnbG9iYWxDb25maWcgPSBldmFsKCcoJytnbG9iYWxDb25maWcrJyknKTsNCiAgICAgICAgeG9va2kudXRpbC5taXgoZ2xvYmFsQ29uZmlnLCB4b29raS5jLCBmYWxzZSk7DQogICAgfQ0KICAgIHhvb2tpLnVybC5ldmFsVVJMKHUoImNvbmZpZy5qcyIpLCBmYWxzZSk7DQogICAgeG9va2kudXJsLmV2YWxVUkwodSgiY29uZmlnLmV4dHJhLmpzIiksIGZhbHNlKTsNCg0KDQogICAgeG9va2kuYy5pbml0UHJvcGVydHkoImRlZmF1bHRJbnB1dEZvcm1hdCIsICJ4b29raSIpOw0KICAgIHhvb2tpLmMuaW5pdFByb3BlcnR5KCJ4b29raUlucHV0Rm9ybWF0IiwgWyJ4b29raSJdKTsNCiAgICB4b29raS5jLmluaXRQcm9wZXJ0eSgiYWxsb3dFZGl0IiwgIWJhdGNoTW9kZSAmJiB4b29raS5wYWdlVVJMLnN1YnN0cigwLDUpID09ICJmaWxlOiIpOw0KICAgIA0KICAgIHhvb2tpLmlucHV0LmZvcm1hdC5kZWZpbmUoInhvb2tpIiwgWyJjb2RlIiwgInNob3J0Y3V0cyIsICJ1cmwiLCAieG9va2lMaW5rcyIsICJqaXJhIiwgImxpbmVCcmVhayIgLCAiaW5jbHVkZXMiXSk7DQogICAgDQogICAgeG9va2kuYy5wYXRoID0gKHR5cGVvZiB4b29raS5jLnBhdGggIT0gInVuZGVmaW5lZCIpP3hvb2tpLmMucGF0aDp7fTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5ID0gaW5pdENvbmZpZ1Byb3BlcnR5Ow0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoImluc3RhbGwiLCAieG9va2kiKTsNCiAgICB4b29raS5jLnBhdGguaW5pdFByb3BlcnR5KCJtZXNzYWdlcyIsIHhvb2tpLnAoIm1lc3NhZ2VzLmpzb24iKSk7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidGVtcGxhdGUiLCAidGVtcGxhdGUuaHRtbCIpOw0KICAgIHhvb2tpLmMucGF0aC5pbml0UHJvcGVydHkoInByaW50VGVtcGxhdGUiLCAicHJpbnRUZW1wbGF0ZS5odG1sIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgidG9jIiwgInRvYy5qc29uIik7DQogICAgeG9va2kuYy5wYXRoLmluaXRQcm9wZXJ0eSgiYmxhbmtQYWdlVHBsIiwgeG9va2kucCgiYmxhbmtQYWdlVHBsLmh0bWwiKSk7DQogICAgDQogICAgDQogICAgeG9va2kuYy5jc3MgPSAodHlwZW9mIHhvb2tpLmMuY3NzICE9ICJ1bmRlZmluZWQiKT94b29raS5jLmNzczp7fTsgICAgDQogICAgICAgIA0KICAgIHhvb2tpLmMubWVzc2FnZXMgPSB4b29raS5qc29uLmxvYWRVUkwoY3UoIm1lc3NhZ2VzIikpOyANCglpZiAoIWJhdGNoTW9kZSkgew0KCSAgICB4b29raS5jLmJyb3dzZXIgPSB7DQoJICAgICAgICBOUzogKHdpbmRvdy5FdmVudCkgPyAxIDogMA0KCSAgICB9Ow0KICAgIA0KCSAgICAvLyBhY3Rpb24NCgkgICAgaWYgKCEgeG9va2kuYy5hY3Rpb24pIHhvb2tpLmMuYWN0aW9uID0gJ3JlbmRlcic7DQoJICAgIC8vIFRPRE86IGJldHRlciBoYW5kbGUgYWN0aW9uIGV4dHJhY3Rpb24NCgkJeG9va2kuYy5hY3Rpb24gPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoID09ICc/YWN0aW9uPXByaW50Jz8ncHJpbnQnOnhvb2tpLmMuYWN0aW9uOw0KCX0NCgkNCgl2YXIgbWF0Y2ggPSBuZXcgUmVnRXhwKCJeLipcXC8oKD86LipcXC8peyIreG9va2kuYy5sZXZlbCsifVteXFwvXSopKD86XFwuXFx3KykoPzpcXD8uKyk/JCIsICJnIikuZXhlYyh4b29raS5wYWdlVVJMKTsNCglpZiAobWF0Y2ggPT0gbnVsbCB8fCBtYXRjaFsxXSA9PSAnJykgew0KCQl4b29raS5jLmN1clBhZ2VJZCA9ICJpbmRleCI7DQoJfSBlbHNlIHsNCgkJeG9va2kuYy5jdXJQYWdlSWQgPSBtYXRjaFsxXTsNCgl9DQogICAgDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBUT0MgaW5pdA0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICB4b29raS50b2MgPSB4b29raS5qc29uLmxvYWRVUkwoY3UoInRvYyIpKTsNCiAgICB4b29raS50b2MudXJsID0gY3UoInRvYyIpOw0KICAgIHhvb2tpLnRvYy5wYWdlcyA9IHt9OyAvLyB0byBzdG9yZSBhIGJ5IGlkIG1hcCBvZiBwYWdlcyBvYmplY3RzDQogICAgeG9va2kudG9jLmltcG9ydFJvb3QgPSAnJzsNCiAgICB4b29raS50b2MuYWN0dWFsUm9vdCA9IHhvb2tpLnRvYzsgLy8gdGhpcyBpcyB0aGUgcmVhbCByb290IG9mIHRoZSBUT0MsIGluIGNhc2Ugb2YgYSBUT0MgaW1wb3J0ZWQsIGl0IHdpbGwgcG9pbnQgdG8gdGhlIHJvb3Qgb2YgdGhlIFRPQyBvbiB3aGljaCBpbXBvcnQgaGFzIGJlZW4gcGVyZm9ybWVkDQoNCgkvLyBwb3B1bGF0ZSBtZXRhIGRhdGENCgkoZnVuY3Rpb24ocGFnZSwgcGFyZW50LCBpbmRleCwgbGV2ZWwsIHByZWZpeCkgew0KICAgICAgICBpZiAocHJlZml4Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgIHBhZ2UubWV0YSA9IHhvb2tpLnV0aWwubWl4KHtpZDogcGFnZS5pZH0sIHBhZ2UubWV0YSk7DQogICAgICAgICAgICBwYWdlLmlkID0gcHJlZml4ICsgcGFnZS5pZDsNCiAgICAgICAgfQ0KICAgICAgICB4b29raS50b2MucGFnZXNbcGFnZS5pZF0gPSBwYWdlOw0KICAgICAgICANCiAgICAgICAgcGFnZS5tZXRhID0geG9va2kudXRpbC5taXgoew0KICAgICAgICAgICAgaW5kZXg6IGluZGV4LA0KICAgICAgICAgICAgbGV2ZWw6IGxldmVsLA0KICAgICAgICAgICAgZ2V0U2VyaWFsaXplVmFsdWU6IGZ1bmN0aW9uKG8sIGspIHsNCiAgICAgICAgICAgICAgICBpZiAoayA9PSAnaWQnICYmIHR5cGVvZiB0aGlzLmlkICE9ICd1bmRlZmluZWQnKSB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlkOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiBvW2tdOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfSwgcGFnZS5tZXRhKTsNCiAgICAgICAgcGFnZS5tZXRhLnBhcmVudCA9IHBhcmVudDsNCiAgICAgICAgaWYgKHR5cGVvZiBwYWdlLmltcG9ydE5vZGUgIT0gJ3VuZGVmaW5lZCcgJiYgIXBhZ2UuaXNJbXBvcnRlZCkgew0KICAgICAgICAgICAgLy8gdGhpcyBub2RlIHJlcXVpcmVzIHRvIGltcG9ydCBhbm90aGVyIHhvb2tpIFRPQw0KICAgICAgICAgICAgaW1wb3J0ZWRUb2NVcmwgPSB1KHBhZ2UuaW1wb3J0Um9vdCArICcvdG9jLmpzb24nKTsNCiAgICAgICAgICAgIGltcG9ydGVkVG9jID0geG9va2kuanNvbi5sb2FkVVJMKGltcG9ydGVkVG9jVXJsKTsNCiAgICAgICAgICAgIC8vIGxvb2sgZm9yIHRoZSBpbXBvcnRlZCBub2RlIGluIHRoZSBpbXBvcnRlZFRPQyBhbmQgaW1wb3J0IGl0IGluIG1haW4gVE9DDQogICAgICAgICAgICAoZnVuY3Rpb24ocGFnZSwgcGFyZW50LCBpbmRleCwgbGV2ZWwsIHByZWZpeCwgaW1wb3J0ZWRUb2MsIG5vZGUsIGlkLCBwb3B1bGF0ZUZ1bmN0aW9uKSB7DQogICAgICAgICAgICAgICAgaWYgKG5vZGUuaWQgPT0gaWQpIHsNCiAgICAgICAgICAgICAgICAgICAgeG9va2kudXRpbC5taXgobm9kZSwgcGFnZSwgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICBwYWdlLmlkID0gaWQ7DQogICAgICAgICAgICAgICAgICAgIHBhZ2UuaXNJbXBvcnRlZCA9IHRydWU7DQogICAgICAgICAgICAgICAgICAgIHBhZ2UubWV0YSA9IHhvb2tpLnV0aWwubWl4KHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlzVHJhbnNpZW50OiBmdW5jdGlvbihrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSB0aXRsZSwgaW1wb3J0Um9vdCBhbmQgaW1wb3J0Tm9kZSBzaG91bGQgYmUgc2VyaWFsaXplZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBrICE9ICd0aXRsZScgJiYgayAhPSAnaW1wb3J0Um9vdCcgJiYgayAhPSAnaW1wb3J0Tm9kZSc7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0sIHBhZ2UubWV0YSk7DQogICAgICAgICAgICAgICAgICAgIGlmICh4b29raS5jLmN1clBhZ2VJZC5pbmRleE9mKHByZWZpeCkgPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgcGFnZSBpcyBpbiB0aGlzIGltcG9ydGVkIFRPQw0KICAgICAgICAgICAgICAgICAgICAgICAgeG9va2kudG9jLmFjdHVhbFJvb3QgPSBpbXBvcnRlZFRvYzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHhvb2tpLnRvYy51cmwgPSB1KHBhZ2UuaW1wb3J0Um9vdCArICcvdG9jLmpzb24nKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHhvb2tpLnRvYy5pbXBvcnRSb290ID0gcHJlZml4Ow0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHBvcHVsYXRlRnVuY3Rpb24ocGFnZSwgcGFyZW50LCBpbmRleCwgbGV2ZWwsIHByZWZpeCk7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5vZGUuY2hpbGRyZW4gIT0gJ3VuZGVmaW5lZCcpIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmd1bWVudHMuY2FsbGVlKHBhZ2UsIHBhcmVudCwgaW5kZXgsIGxldmVsLCBwcmVmaXgsIGltcG9ydGVkVG9jLCBub2RlLmNoaWxkcmVuW2ldLCBpZCwgcG9wdWxhdGVGdW5jdGlvbikpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgICAgICB9KShwYWdlLCBwYXJlbnQsIGluZGV4LCBsZXZlbCwgcGFnZS5pbXBvcnRSb290KycvJywgaW1wb3J0ZWRUb2MsIGltcG9ydGVkVG9jLCBwYWdlLmltcG9ydE5vZGUsIGFyZ3VtZW50cy5jYWxsZWUpOw0KICAgICAgICB9DQogICAgICAgIGlmICh0eXBlb2YgcGFnZS5jaGlsZHJlbiA9PSAndW5kZWZpbmVkJykgew0KICAgICAgICAgICAgcGFnZS5jaGlsZHJlbiA9IFtdOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPHBhZ2UuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICBhcmd1bWVudHMuY2FsbGVlKHBhZ2UuY2hpbGRyZW5baV0sIHBhZ2UsIGksIGxldmVsKzEsIHByZWZpeCk7IC8vIHJlY3Vyc2UNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0pKHhvb2tpLnRvYywgbnVsbCwgMCwgLTEsICcnKTsNCiAgICANCiAgICB4b29raS50b2MuZ2V0TmV4dFBhZ2UgPSBmdW5jdGlvbihwYWdlLCByb290KSB7DQogICAgICAgIGlmIChwYWdlLmNoaWxkcmVuLmxlbmd0aCA+IDApIHsNCiAgICAgICAgCXJldHVybiBwYWdlLmNoaWxkcmVuWzBdOw0KICAgICAgICB9IGVsc2UgaWYgKHBhZ2UubWV0YS5wYXJlbnQgIT0gbnVsbCkgew0KICAgICAgICAJdmFyIGN1ciA9IHBhZ2U7DQogICAgICAgIAl2YXIgbmV4dCA9IHhvb2tpLnRvYy5nZXROZXh0U2libGluZyhjdXIpOw0KICAgICAgICAJd2hpbGUgKG5leHQgPT0gbnVsbCkgew0KICAgICAgICAJCWN1ciA9IGN1ci5tZXRhLnBhcmVudDsNCiAgICAgICAgCQlpZiAoY3VyID09IG51bGwgfHwgY3VyID09IHJvb3QpIHsNCiAgICAgICAgCQkJcmV0dXJuIG51bGw7DQogICAgICAgIAkJfQ0KICAgICAgICAJCW5leHQgPSB4b29raS50b2MuZ2V0TmV4dFNpYmxpbmcoY3VyKTsNCiAgICAgICAgCX0NCiAgICAgICAJCXJldHVybiBuZXh0Ow0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAJcmV0dXJuIG51bGw7DQogICAgICAgIH0NCiAgICB9Ow0KICAgIHhvb2tpLnRvYy5nZXROZXh0U2libGluZyA9IGZ1bmN0aW9uKHBhZ2UpIHsNCiAgICAJaWYgKHBhZ2UubWV0YS5wYXJlbnQgPT0gbnVsbCkgew0KICAgIAkJcmV0dXJuIG51bGw7DQogICAgCX0NCiAgICAgICAJaWYgKHBhZ2UubWV0YS5wYXJlbnQuY2hpbGRyZW4ubGVuZ3RoID4gcGFnZS5tZXRhLmluZGV4KSB7DQogICAgICAgCQlyZXR1cm4gcGFnZS5tZXRhLnBhcmVudC5jaGlsZHJlbltwYWdlLm1ldGEuaW5kZXgrMV07DQogICAgICAgCX0gZWxzZSB7DQogICAgICAgCQlyZXR1cm4gbnVsbDsNCiAgICAgICAJfQ0KICAgIH07DQoJeG9va2kucGFnZSA9IHhvb2tpLnRvYy5wYWdlc1t4b29raS5jLmN1clBhZ2VJZF07DQoNCglpZiAoeG9va2kucGFnZSA9PSBudWxsKSB7DQoJCXhvb2tpLndhcm4odCgncGFnZSBpZCBub3QgZm91bmQgaW4gVE9DOiAkezB9Jyx4b29raS5jLmN1clBhZ2VJZCkpOw0KCQl4b29raS5wYWdlID0geG9va2kudG9jLmNoaWxkcmVuWzBdOw0KCX0gDQoJaWYgKHR5cGVvZiB4b29raS5jb25maWcudGl0bGUgPT0gJ3VuZGVmaW5lZCcpIHsNCgkJeG9va2kuY29uZmlnLnRpdGxlID0geG9va2kucGFnZS50aXRsZTsNCgl9CQkNCgl4b29raS5jb25maWcucGFnZSA9IHhvb2tpLnBhZ2U7DQoJDQogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLyBtYWluIHRlbXBsYXRlIGxvYWRpbmcgKyBoZWFkIG91dHB1dA0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCgl4b29raS50ZW1wbGF0ZSA9IHt9Ow0KICAgIHhvb2tpLnRlbXBsYXRlLnNvdXJjZSA9IHhvb2tpLnVybC5sb2FkVVJMKHhvb2tpLmMuYWN0aW9uID09ICJwcmludCI/Y3UoInByaW50VGVtcGxhdGUiKTpjdSgidGVtcGxhdGUiKSk7DQoJaWYoeG9va2kudGVtcGxhdGUuc291cmNlICE9IG51bGwpIHsNCgkJeG9va2kudGVtcGxhdGUuaGVhZCA9IHhvb2tpLnRlbXBsYXRlLnNvdXJjZS5tYXRjaCgvPGhlYWQ+KFtep10qKTxcL2hlYWQ+L2ltKVsxXTsNCgkJdmFyIHJvb3QgPSBiYXRjaE1vZGU/eG9va2kuYy5yZWxhdGl2ZVJvb3Q6eG9va2kuYy5yb290Ow0KCQkNCiAgICAgICAgdmFyIGhlYWQgPSB4b29raS5zdHJpbmcucHJvY2Vzc1RlbXBsYXRlKHhvb2tpLnRlbXBsYXRlLmhlYWQsIHhvb2tpLmNvbmZpZyk7DQoJCWhlYWQgPSBoZWFkLnJlcGxhY2UoL2hyZWY9IihbXlxcJDoiXSspIi9nLCAnaHJlZj0iJytyb290KyckMSInKTsNCgkJaGVhZCA9IGhlYWQucmVwbGFjZSgvc3JjPSIoW15cXCQ6Il0rKSIvZywgJ3NyYz0iJytyb290KyckMSInKTsNCgkJeG9va2kuaHRtbC5hZGRIZWFkZXIoaGVhZCk7DQoNCgkJdmFyIGJvZHkgPSB4b29raS50ZW1wbGF0ZS5zb3VyY2UubWF0Y2goLzxib2R5PihbXqddKik8XC9ib2R5Pi9pbSlbMV07DQoJCWJvZHkgPSBib2R5LnJlcGxhY2UoL2hyZWY9IihbXlxcJDoiXSspIi9nLCAnaHJlZj0iJytyb290KyckMSInKTsNCgkJeG9va2kudGVtcGxhdGUuYm9keSA9IGJvZHkucmVwbGFjZSgvc3JjPSIoW15cXCQ6Il0rKSIvZywgJ3NyYz0iJytyb290KyckMSInKTsJCQ0KCX0NCgkNCg0KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8gaW5jbHVkZXMNCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQoJaWYgKGJhdGNoTW9kZSkgew0KCQl4b29raS5odG1sLmFkZEhlYWRlcignPHNjcmlwdCBsYW5ndWFnZT0iamF2YXNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij54b29raSA9IHt1OiBmdW5jdGlvbih1cmwpIHtyZXR1cm4gIicreG9va2kuYy5yZWxhdGl2ZVJvb3QrJ3hvb2tpLyIrdXJsO319Ozwvc2NyaXB0PicpOw0KCX0NCiAgICBpZiAoeG9va2kuYy5hbGxvd0VkaXQpIHsNCiAgICAgICAgeG9va2kudXJsLmluY2x1ZGUoInhvb2tpRWRpdC5qcyIpOw0KICAgIH0NCg0KICAgIGZvciAodmFyIGsgaW4geG9va2kuYykgew0KICAgICAgICBpZiAodHlwZW9mIHhvb2tpLmNba10gPT0gInN0cmluZyIgfHwgdHlwZW9mIHhvb2tpLmNba10gPT0gIm51bWJlciIgfHwgdHlwZW9mIHhvb2tpLmNba10gPT0gImJvb2xlYW4iKSB7DQogICAgICAgICAgICB4b29raS5kZWJ1ZyhrKyI6ICIreG9va2kuY1trXSk7DQogICAgICAgIH0NCiAgICB9DQp9Ow0KDQppZiAoYmF0Y2hNb2RlKSB7DQoJaW1wb3J0UGFja2FnZShqYXZhLmlvKTsNCgkNCgl4b29raS5pby5sb2FkRmlsZSA9IGZ1bmN0aW9uKCB1cmwsIHdhcm5PbkVycm9yICkgew0KCSAgdmFyIHN0ciA9ICcnOw0KCSAgdHJ5IHsNCiAgICAgIHZhciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKHVybCkpOw0KCSAgbGluZSA9IHIucmVhZExpbmUoKTsNCgkgIHdoaWxlIChsaW5lICE9IG51bGwpIHsNCgkJc3RyICs9IGxpbmUgKyAnXG4nOw0KCQlsaW5lID0gci5yZWFkTGluZSgpOw0KCSAgfQ0KCSAgci5jbG9zZSgpOw0KCSAgfSBjYXRjaCAoZSkgew0KCSAgCWlmICh3YXJuT25FcnJvcikgew0KCSAgCQl0aHJvdyBlOw0KCSAgCX0gZWxzZSB7DQoJICAJCXhvb2tpLmRlYnVnKCJlcnJvciBvY2N1cmVkIHdoaWxlIGxvYWRpbmcgIit1cmwpOw0KCSAgCX0NCgkgIH0NCgkgIHJldHVybiBzdHI7DQogICAgfTsNCgkNCgl4b29raS5pby5zYXZlRmlsZSA9IGZ1bmN0aW9uIChmaWxlVXJsLCBjb250ZW50KSB7DQoJCXAgPSBuZXcgRmlsZShmaWxlVXJsKS5nZXRQYXJlbnRGaWxlKCk7DQoJCWlmIChwICE9IG51bGwpIHsNCgkJCXAubWtkaXJzKCk7DQoJCX0NCgkJcHcgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVXcml0ZXIoZmlsZVVybCkpOw0KCQlwdy53cml0ZShjb250ZW50KTsNCgkJcHcuY2xvc2UoKTsNCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQogICAgeG9va2kudXJsLmxvYWRVUkwgPSBmdW5jdGlvbiggdXJsLCB3YXJuT25FcnJvciApIHsNCgkJcmV0dXJuIHhvb2tpLmlvLmxvYWRGaWxlKHVybCwgd2Fybk9uRXJyb3IgKTsNCgl9Ow0KCQ0KCXhvb2tpLmh0bWwuYWRkSGVhZGVyID0gZnVuY3Rpb24gKGhlYWQpIHsNCgkJeG9va2kucGFnZUNvbnRlbnQgPSB4b29raS5wYWdlQ29udGVudC5yZXBsYWNlKC88XC9oZWFkPi8sIGhlYWQrJ1xuPC9oZWFkPicpOw0KCX07DQoJDQoJeG9va2kuaHRtbC5zZXRCb2R5ID0gZnVuY3Rpb24oYm9keSkgew0KCQl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLnBhZ2VDb250ZW50LnJlcGxhY2UoLzxib2R5PigufFteLF0pKjxcL2JvZHk+L2dtLCAnPGJvZHk+Jytib2R5Kyc8L2JvZHk+Jyk7DQoJfQ0KCQ0KCXhvb2tpLnVybC5pbmNsdWRlID0gZnVuY3Rpb24oc2NyaXB0X2ZpbGVuYW1lKSB7DQoJCXhvb2tpLmh0bWwuYWRkSGVhZGVyKCc8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iJyt4b29raS5jLnJlbGF0aXZlUm9vdCsneG9va2kvJytzY3JpcHRfZmlsZW5hbWUrJyI+PC9zY3JpcHQ+Jyk7DQoJfTsNCgkNCgl4b29raS5pbnB1dC5zb3VyY2UgPSBmdW5jdGlvbigpIHsNCgkJaWYgKHR5cGVvZiB0aGlzLl9zb3VyY2UgPT0gJ3VuZGVmaW5lZCcpIHsNCgkJCXhvb2tpLmRlYnVnKCdzZWFyY2hpbmcgc291cmNlJyk7DQoJCQl2YXIgYmVnID0geG9va2kucGFnZUNvbnRlbnQuaW5kZXhPZignPHRleHRhcmVhIGlkPSJ4b29raS1zb3VyY2UiPicpOw0KCQkJYmVnICs9ICc8dGV4dGFyZWEgaWQ9Inhvb2tpLXNvdXJjZSI+Jy5sZW5ndGg7DQoJCQl2YXIgZW5kID0geG9va2kucGFnZUNvbnRlbnQubGFzdEluZGV4T2YoJzwvdGV4dGFyZWE+Jyk7DQoJCQl0aGlzLl9zb3VyY2UgPSB4b29raS5wYWdlQ29udGVudC5zdWJzdHJpbmcoYmVnLCBlbmQpOw0KCQkJeG9va2kuZGVidWcoJ3NvdXJjZSBmb3VuZCcpOw0KCQl9DQoJCXJldHVybiB0aGlzLl9zb3VyY2U7DQoJfQ0KCQ0KCXhvb2tpLnJlbmRlci5wYWdlID0gZnVuY3Rpb24oKSB7DQoJICAgIC8vIHJlYWxpemUgYWxsIGNvbXBvbmVudHMgYXZhaWxhYmxlDQoJCXhvb2tpLmRlYnVnKCdyZWFsaXppbmcgY29tcG9uZW50cycpOw0KCSAgICBmb3IgKHZhciBrIGluIHhvb2tpLmNvbXBvbmVudCkgew0KCSAgICAgICAgeG9va2kuY1trXSA9IHhvb2tpLmNvbXBvbmVudFtrXSgpOw0KCSAgICB9DQoJICAgIA0KCQl4b29raS5kZWJ1ZygncHJvY2Vzc2luZyBib2R5Jyk7DQoJCXhvb2tpLmMuYm9keSA9IHhvb2tpLmlucHV0LnByb2Nlc3NlZCgpOw0KDQoJCXhvb2tpLmRlYnVnKCd1cGRhdGluZyBib2R5Jyk7DQoJCXZhciBib2R5ID0geG9va2kuc3RyaW5nLnByb2Nlc3NUZW1wbGF0ZSh4b29raS50ZW1wbGF0ZS5ib2R5LCB4b29raS5jKTsNCgkgICAgeG9va2kuaHRtbC5zZXRCb2R5KGJvZHkpOw0KCX07DQoNCgl4b29raS5kaXNwbGF5ID0gZnVuY3Rpb24obWVzc2FnZSwgYmFja2dyb3VuZCkgew0KCQlwcmludChtZXNzYWdlKTsNCgl9Ow0KCQ0KCXhvb2tpLmRlYnVnID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHsNCgkJaWYgKHhvb2tpLmMuZGVidWcpIHsNCgkJCXByaW50KG1lc3NhZ2UrJ1xuJyk7DQoJCX0NCgl9Ow0KCXZhciBpPTA7DQoJaWYgKGFyZ3VtZW50cy5sZW5ndGggPiBpICYmIGFyZ3VtZW50c1swXSA9PSAnLWRlYnVnJykgew0KCQl4b29raS5jLmRlYnVnID0gdHJ1ZTsNCgkJaSsrOw0KCX0gZWxzZSB7DQoJCXhvb2tpLmMuZGVidWcgPSBmYWxzZTsNCgl9DQoJDQoJdmFyIGZpbGUgPSAnaW5kZXguaHRtbCc7DQoJaWYgKGFyZ3VtZW50cy5sZW5ndGggPiBpKSB7DQoJCWZpbGUgPSBhcmd1bWVudHNbaV07DQoJCWkrKzsNCgl9DQoJdmFyIGdlbmVyYXRlVG8gPSAiZ2VuIjsNCglpZiAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIHsNCgkJZ2VuZXJhdGVUbyA9IGFyZ3VtZW50c1tpXTsNCgkJaSsrOw0KCX0NCgl4b29raS5jLmFjdGlvbiA9ICdyZW5kZXInOw0KCWlmIChhcmd1bWVudHMubGVuZ3RoID4gaSkgew0KCQl4b29raS5jLmFjdGlvbiA9IGFyZ3VtZW50c1tpXTsNCgkJaSsrOw0KCX0NCg0KCXhvb2tpLnBhZ2VVUkwgPSBuZXcgRmlsZShmaWxlKS50b1VSTCgpLnRvRXh0ZXJuYWxGb3JtKCk7DQoJDQoJcHJpbnQoJ3Byb2Nlc3NpbmcgJytuZXcgRmlsZShmaWxlKS5nZXRBYnNvbHV0ZVBhdGgoKSsnLi4uXG4nKTsNCgl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLmlvLmxvYWRGaWxlKGZpbGUpOw0KICAgIA0KICAgIGlmICh4b29raS5wYWdlQ29udGVudC5tYXRjaCgvPHRleHRhcmVhXHMraWQ9Inhvb2tpXC1zb3VyY2UiPi8pID09IG51bGwpIHsNCiAgICAgICAgcHJpbnQoZmlsZSArICcgaXMgbm90IGEgdmFsaWQgeG9va2kgc291cmNlLiBpZ25vcmVkLicpOw0KICAgIH0gZWxzZSB7CQ0KICAgIAl2YXIgbSA9IC92YXJccyt4b29raUNvbmZpZ1xzKz1ccyt7Lip9Oy8uZXhlYyh4b29raS5wYWdlQ29udGVudCk7DQogICAgCWlmICh0eXBlb2YgbSAhPSAndW5kZWZpbmVkJyAmJiBtICE9IG51bGwpIHsNCiAgICAJCWV2YWwobVswXSk7DQogICAgCX0NCg0KICAgICAgICB4b29raS5pbml0KCk7DQogICAgICAgIA0KICAgIAl4b29raS5wYWdlQ29udGVudCA9IHhvb2tpLnBhZ2VDb250ZW50LnJlcGxhY2UoLzxzY3JpcHQgdHlwZT0idGV4dFwvamF2YXNjcmlwdCIgc3JjPSJbXiJdKnhvb2tpLmpzIj48XC9zY3JpcHQ+L2csICcnKTsNCiAgICAJDQogICAgCXhvb2tpLnJlbmRlci5tYWluKCk7DQoNCgkJdmFyIGRlc3QgPSBnZW5lcmF0ZVRvLmVuZHNXaXRoKCIuaHRtbCIpID8gZ2VuZXJhdGVUbyA6IGdlbmVyYXRlVG8rJy8nK2ZpbGU7DQogICAgCXByaW50KCdnZW5lcmF0aW5nIHRvICcrZGVzdCk7DQogICAgCXhvb2tpLmlvLnNhdmVGaWxlKGRlc3QsIHhvb2tpLnBhZ2VDb250ZW50KTsNCiAgICB9DQp9IGVsc2Ugew0KCXhvb2tpLnBhZ2VVUkwgPSB3aW5kb3cubG9jYXRpb24udG9TdHJpbmcoKTsNCiAgICB4b29raS5pbml0KCk7DQp9DQoNCg==