LyoqDQogKiANCiAqIENvcHlyaWdodCAyMDA3DQogKiANCiAqIFBhdWxpdXMgVXphDQogKiBodHRwOi8vd3d3LnV6YS5sdA0KICogDQogKiBEYW4gRmxvcmlvDQogKiBodHRwOi8vd3d3LnBvbHlnZWVrLmNvbQ0KICogDQogKiBQcm9qZWN0IHdlYnNpdGU6DQogKiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvY3VzdG9tLWNvbnRleHQtbWVudS8NCiAqIA0KICogLS0NCiAqIFJpZ2h0Q2xpY2sgZm9yIEZsYXNoIFBsYXllci4gDQogKiBWZXJzaW9uIDAuNi4yDQogKiANCiAqLw0KDQp2YXIgUmlnaHRDbGljayA9IHsNCgkvKioNCgkgKiAgQ29uc3RydWN0b3INCgkgKi8gDQoJaW5pdDogZnVuY3Rpb24gKCkgeyANCgkJdGhpcy5GbGFzaE9iamVjdElEID0gIkNhcHRpdmF0ZSI7DQoJCXRoaXMuRmxhc2hDb250YWluZXJJRCA9ICJDYXB0aXZhdGVDb250ZW50IjsNCgkJdGhpcy5DYWNoZSA9IHRoaXMuRmxhc2hPYmplY3RJRDsNCgkJaWYod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpew0KCQkJIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLCB0aGlzLm9uR2Vja29Nb3VzZSgpLCB0cnVlKTsNCgkJfSBlbHNlIHsNCgkJCWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuRmxhc2hDb250YWluZXJJRCkub25tb3VzZXVwID0gZnVuY3Rpb24oKSB7IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFJpZ2h0Q2xpY2suRmxhc2hDb250YWluZXJJRCkucmVsZWFzZUNhcHR1cmUoKTsgfQ0KCQkJZG9jdW1lbnQub25jb250ZXh0bWVudSA9IGZ1bmN0aW9uKCl7IGlmKHdpbmRvdy5ldmVudC5zcmNFbGVtZW50LmlkID09IFJpZ2h0Q2xpY2suRmxhc2hPYmplY3RJRCkgeyByZXR1cm4gZmFsc2U7IH0gZWxzZSB7IFJpZ2h0Q2xpY2suQ2FjaGUgPSAibmFuIjsgfX0NCgkJCWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuRmxhc2hDb250YWluZXJJRCkub25tb3VzZWRvd24gPSBSaWdodENsaWNrLm9uSUVNb3VzZTsNCgkJfQ0KCX0sDQoJLyoqDQoJICogR0VDS08gLyBXRUJLSVQgZXZlbnQgb3ZlcmtpbGwNCgkgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRPYmplY3QNCgkgKi8NCglraWxsRXZlbnRzOiBmdW5jdGlvbihldmVudE9iamVjdCkgew0KCQlpZihldmVudE9iamVjdCkgew0KCQkJaWYgKGV2ZW50T2JqZWN0LnN0b3BQcm9wYWdhdGlvbikgZXZlbnRPYmplY3Quc3RvcFByb3BhZ2F0aW9uKCk7DQoJCQlpZiAoZXZlbnRPYmplY3QucHJldmVudERlZmF1bHQpIGV2ZW50T2JqZWN0LnByZXZlbnREZWZhdWx0KCk7DQoJCQlpZiAoZXZlbnRPYmplY3QucHJldmVudENhcHR1cmUpIGV2ZW50T2JqZWN0LnByZXZlbnRDYXB0dXJlKCk7DQoJICAgCQlpZiAoZXZlbnRPYmplY3QucHJldmVudEJ1YmJsZSkgZXZlbnRPYmplY3QucHJldmVudEJ1YmJsZSgpOw0KCQl9DQoJfSwNCgkvKioNCgkgKiBHRUNLTyAvIFdFQktJVCBjYWxsIHJpZ2h0IGNsaWNrDQoJICogQHBhcmFtIHtPYmplY3R9IGV2DQoJICovDQoJb25HZWNrb01vdXNlOiBmdW5jdGlvbihldikgew0KCSAgCXJldHVybiBmdW5jdGlvbihldikgew0KCSAgICBpZiAoZXYuYnV0dG9uID09IDIpIHsNCgkJCVJpZ2h0Q2xpY2sua2lsbEV2ZW50cyhldik7DQoJCQlpZihldi50YXJnZXQuaWQgPT0gUmlnaHRDbGljay5GbGFzaE9iamVjdElEICYmIFJpZ2h0Q2xpY2suQ2FjaGUgPT0gUmlnaHRDbGljay5GbGFzaE9iamVjdElEKSB7DQoJICAgIAkJUmlnaHRDbGljay5jYWxsKCk7DQoJCQl9DQoJCQlSaWdodENsaWNrLkNhY2hlID0gZXYudGFyZ2V0LmlkOw0KCQl9DQoJICB9DQoJfSwNCgkvKioNCgkgKiBJRSBjYWxsIHJpZ2h0IGNsaWNrDQoJICogQHBhcmFtIHtPYmplY3R9IGV2DQoJICovDQoJb25JRU1vdXNlOiBmdW5jdGlvbigpIHsNCgkgIAlpZiAoZXZlbnQuYnV0dG9uID09IDIpIHsNCgkJCWlmKHdpbmRvdy5ldmVudC5zcmNFbGVtZW50LmlkID09IFJpZ2h0Q2xpY2suRmxhc2hPYmplY3RJRCAmJiBSaWdodENsaWNrLkNhY2hlID09IFJpZ2h0Q2xpY2suRmxhc2hPYmplY3RJRCkgew0KCQkJCVJpZ2h0Q2xpY2suY2FsbCgpOyANCgkJCX0NCgkJCWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFJpZ2h0Q2xpY2suRmxhc2hDb250YWluZXJJRCkuc2V0Q2FwdHVyZSgpOw0KCQkJaWYod2luZG93LmV2ZW50LnNyY0VsZW1lbnQuaWQpDQoJCQlSaWdodENsaWNrLkNhY2hlID0gd2luZG93LmV2ZW50LnNyY0VsZW1lbnQuaWQ7DQoJCX0NCgl9LA0KCS8qKg0KCSAqIE1haW4gY2FsbCB0byBGbGFzaCBFeHRlcm5hbCBJbnRlcmZhY2UNCgkgKi8NCgljYWxsOiBmdW5jdGlvbigpIHsNCgkJZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5GbGFzaE9iamVjdElEKS5yaWdodENsaWNrKCk7DQoJfQ0KfQ0KDQovKioNCiAqIFNXRk9iamVjdCB2MS41OiBGbGFzaCBQbGF5ZXIgZGV0ZWN0aW9uIGFuZCBlbWJlZCAtIGh0dHA6Ly9ibG9nLmRlY29uY2VwdC5jb20vc3dmb2JqZWN0Lw0KICoNCiAqIFNXRk9iamVjdCBpcyAoYykgMjAwNyBHZW9mZiBTdGVhcm5zIGFuZCBpcyByZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2U6DQogKiBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocA0KICoNCiAqLw0KDQoNCmlmKHR5cGVvZiBkZWNvbmNlcHQ9PSJ1bmRlZmluZWQiKXt2YXIgZGVjb25jZXB0PW5ldyBPYmplY3QoKTt9aWYodHlwZW9mIGRlY29uY2VwdC51dGlsPT0idW5kZWZpbmVkIil7ZGVjb25jZXB0LnV0aWw9bmV3IE9iamVjdCgpO31pZih0eXBlb2YgZGVjb25jZXB0LlNXRk9iamVjdFV0aWw9PSJ1bmRlZmluZWQiKXtkZWNvbmNlcHQuU1dGT2JqZWN0VXRpbD1uZXcgT2JqZWN0KCk7fWRlY29uY2VwdC5TV0ZPYmplY3Q9ZnVuY3Rpb24oXzEsaWQsdyxoLF81LGMsXzcsXzgsXzksX2Epe2lmKCFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCl7cmV0dXJuO310aGlzLkRFVEVDVF9LRVk9X2E/X2E6ImRldGVjdGZsYXNoIjt0aGlzLnNraXBEZXRlY3Q9ZGVjb25jZXB0LnV0aWwuZ2V0UmVxdWVzdFBhcmFtZXRlcih0aGlzLkRFVEVDVF9LRVkpO3RoaXMucGFyYW1zPW5ldyBPYmplY3QoKTt0aGlzLnZhcmlhYmxlcz1uZXcgT2JqZWN0KCk7dGhpcy5hdHRyaWJ1dGVzPW5ldyBBcnJheSgpO2lmKF8xKXt0aGlzLnNldEF0dHJpYnV0ZSgic3dmIixfMSk7fWlmKGlkKXt0aGlzLnNldEF0dHJpYnV0ZSgiaWQiLGlkKTt9aWYodyl7dGhpcy5zZXRBdHRyaWJ1dGUoIndpZHRoIix3KTt9aWYoaCl7dGhpcy5zZXRBdHRyaWJ1dGUoImhlaWdodCIsaCk7fWlmKF81KXt0aGlzLnNldEF0dHJpYnV0ZSgidmVyc2lvbiIsbmV3IGRlY29uY2VwdC5QbGF5ZXJWZXJzaW9uKF81LnRvU3RyaW5nKCkuc3BsaXQoIi4iKSkpO310aGlzLmluc3RhbGxlZFZlcj1kZWNvbmNlcHQuU1dGT2JqZWN0VXRpbC5nZXRQbGF5ZXJWZXJzaW9uKCk7aWYoIXdpbmRvdy5vcGVyYSYmZG9jdW1lbnQuYWxsJiZ0aGlzLmluc3RhbGxlZFZlci5tYWpvcj43KXtkZWNvbmNlcHQuU1dGT2JqZWN0LmRvUHJlcFVubG9hZD10cnVlO31pZihjKXt0aGlzLmFkZFBhcmFtKCJiZ2NvbG9yIixjKTt9dmFyIHE9Xzc/Xzc6ImhpZ2giO3RoaXMuYWRkUGFyYW0oInF1YWxpdHkiLHEpO3RoaXMuc2V0QXR0cmlidXRlKCJ1c2VFeHByZXNzSW5zdGFsbCIsZmFsc2UpO3RoaXMuc2V0QXR0cmlidXRlKCJkb0V4cHJlc3NJbnN0YWxsIixmYWxzZSk7dmFyIF9jPShfOCk/Xzg6d2luZG93LmxvY2F0aW9uO3RoaXMuc2V0QXR0cmlidXRlKCJ4aVJlZGlyZWN0VXJsIixfYyk7dGhpcy5zZXRBdHRyaWJ1dGUoInJlZGlyZWN0VXJsIiwiIik7aWYoXzkpe3RoaXMuc2V0QXR0cmlidXRlKCJyZWRpcmVjdFVybCIsXzkpO319O2RlY29uY2VwdC5TV0ZPYmplY3QucHJvdG90eXBlPXt1c2VFeHByZXNzSW5zdGFsbDpmdW5jdGlvbihfZCl7dGhpcy54aVNXRlBhdGg9IV9kPyJleHByZXNzaW5zdGFsbC5zd2YiOl9kO3RoaXMuc2V0QXR0cmlidXRlKCJ1c2VFeHByZXNzSW5zdGFsbCIsdHJ1ZSk7fSxzZXRBdHRyaWJ1dGU6ZnVuY3Rpb24oX2UsX2Ype3RoaXMuYXR0cmlidXRlc1tfZV09X2Y7fSxnZXRBdHRyaWJ1dGU6ZnVuY3Rpb24oXzEwKXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW18xMF07fSxhZGRQYXJhbTpmdW5jdGlvbihfMTEsXzEyKXt0aGlzLnBhcmFtc1tfMTFdPV8xMjt9LGdldFBhcmFtczpmdW5jdGlvbigpe3JldHVybiB0aGlzLnBhcmFtczt9LGFkZFZhcmlhYmxlOmZ1bmN0aW9uKF8xMyxfMTQpe3RoaXMudmFyaWFibGVzW18xM109XzE0O30sZ2V0VmFyaWFibGU6ZnVuY3Rpb24oXzE1KXtyZXR1cm4gdGhpcy52YXJpYWJsZXNbXzE1XTt9LGdldFZhcmlhYmxlczpmdW5jdGlvbigpe3JldHVybiB0aGlzLnZhcmlhYmxlczt9LGdldFZhcmlhYmxlUGFpcnM6ZnVuY3Rpb24oKXt2YXIgXzE2PW5ldyBBcnJheSgpO3ZhciBrZXk7dmFyIF8xOD10aGlzLmdldFZhcmlhYmxlcygpO2ZvcihrZXkgaW4gXzE4KXtfMTZbXzE2Lmxlbmd0aF09a2V5KyI9IitfMThba2V5XTt9cmV0dXJuIF8xNjt9LGdldFNXRkhUTUw6ZnVuY3Rpb24oKXt2YXIgXzE5PSIiO2lmKG5hdmlnYXRvci5wbHVnaW5zJiZuYXZpZ2F0b3IubWltZVR5cGVzJiZuYXZpZ2F0b3IubWltZVR5cGVzLmxlbmd0aCl7aWYodGhpcy5nZXRBdHRyaWJ1dGUoImRvRXhwcmVzc0luc3RhbGwiKSl7dGhpcy5hZGRWYXJpYWJsZSgiTU1wbGF5ZXJUeXBlIiwiUGx1Z0luIik7dGhpcy5zZXRBdHRyaWJ1dGUoInN3ZiIsdGhpcy54aVNXRlBhdGgpO31fMTk9IjxlbWJlZCB0eXBlPVwiYXBwbGljYXRpb24veC1zaG9ja3dhdmUtZmxhc2hcIiBzcmM9XCIiK3RoaXMuZ2V0QXR0cmlidXRlKCJzd2YiKSsiXCIgd2lkdGg9XCIiK3RoaXMuZ2V0QXR0cmlidXRlKCJ3aWR0aCIpKyJcIiBoZWlnaHQ9XCIiK3RoaXMuZ2V0QXR0cmlidXRlKCJoZWlnaHQiKSsiXCIgc3R5bGU9XCIiK3RoaXMuZ2V0QXR0cmlidXRlKCJzdHlsZSIpKyJcIiI7XzE5Kz0iIGlkPVwiIit0aGlzLmdldEF0dHJpYnV0ZSgiaWQiKSsiXCIgbmFtZT1cIiIrdGhpcy5nZXRBdHRyaWJ1dGUoImlkIikrIlwiICI7dmFyIF8xYT10aGlzLmdldFBhcmFtcygpO2Zvcih2YXIga2V5IGluIF8xYSl7XzE5Kz1ba2V5XSsiPVwiIitfMWFba2V5XSsiXCIgIjt9dmFyIF8xYz10aGlzLmdldFZhcmlhYmxlUGFpcnMoKS5qb2luKCImIik7aWYoXzFjLmxlbmd0aD4wKXtfMTkrPSJmbGFzaHZhcnM9XCIiK18xYysiXCIiO31fMTkrPSIvPiI7fWVsc2V7aWYodGhpcy5nZXRBdHRyaWJ1dGUoImRvRXhwcmVzc0luc3RhbGwiKSl7dGhpcy5hZGRWYXJpYWJsZSgiTU1wbGF5ZXJUeXBlIiwiQWN0aXZlWCIpO3RoaXMuc2V0QXR0cmlidXRlKCJzd2YiLHRoaXMueGlTV0ZQYXRoKTt9XzE5PSI8b2JqZWN0IGlkPVwiIit0aGlzLmdldEF0dHJpYnV0ZSgiaWQiKSsiXCIgY2xhc3NpZD1cImNsc2lkOkQyN0NEQjZFLUFFNkQtMTFjZi05NkI4LTQ0NDU1MzU0MDAwMFwiIHdpZHRoPVwiIit0aGlzLmdldEF0dHJpYnV0ZSgid2lkdGgiKSsiXCIgaGVpZ2h0PVwiIit0aGlzLmdldEF0dHJpYnV0ZSgiaGVpZ2h0IikrIlwiIHN0eWxlPVwiIit0aGlzLmdldEF0dHJpYnV0ZSgic3R5bGUiKSsiXCI+IjtfMTkrPSI8cGFyYW0gbmFtZT1cIm1vdmllXCIgdmFsdWU9XCIiK3RoaXMuZ2V0QXR0cmlidXRlKCJzd2YiKSsiXCIgLz4iO3ZhciBfMWQ9dGhpcy5nZXRQYXJhbXMoKTtmb3IodmFyIGtleSBpbiBfMWQpe18xOSs9IjxwYXJhbSBuYW1lPVwiIitrZXkrIlwiIHZhbHVlPVwiIitfMWRba2V5XSsiXCIgLz4iO312YXIgXzFmPXRoaXMuZ2V0VmFyaWFibGVQYWlycygpLmpvaW4oIiYiKTtpZihfMWYubGVuZ3RoPjApe18xOSs9IjxwYXJhbSBuYW1lPVwiZmxhc2h2YXJzXCIgdmFsdWU9XCIiK18xZisiXCIgLz4iO31fMTkrPSI8L29iamVjdD4iO31yZXR1cm4gXzE5O30sd3JpdGU6ZnVuY3Rpb24oXzIwKXtpZih0aGlzLmdldEF0dHJpYnV0ZSgidXNlRXhwcmVzc0luc3RhbGwiKSl7dmFyIF8yMT1uZXcgZGVjb25jZXB0LlBsYXllclZlcnNpb24oWzYsMCw2NV0pO2lmKHRoaXMuaW5zdGFsbGVkVmVyLnZlcnNpb25Jc1ZhbGlkKF8yMSkmJiF0aGlzLmluc3RhbGxlZFZlci52ZXJzaW9uSXNWYWxpZCh0aGlzLmdldEF0dHJpYnV0ZSgidmVyc2lvbiIpKSl7dGhpcy5zZXRBdHRyaWJ1dGUoImRvRXhwcmVzc0luc3RhbGwiLHRydWUpO3RoaXMuYWRkVmFyaWFibGUoIk1NcmVkaXJlY3RVUkwiLGVzY2FwZSh0aGlzLmdldEF0dHJpYnV0ZSgieGlSZWRpcmVjdFVybCIpKSk7ZG9jdW1lbnQudGl0bGU9ZG9jdW1lbnQudGl0bGUuc2xpY2UoMCw0NykrIiAtIEZsYXNoIFBsYXllciBJbnN0YWxsYXRpb24iO3RoaXMuYWRkVmFyaWFibGUoIk1NZG9jdGl0bGUiLGRvY3VtZW50LnRpdGxlKTt9fWlmKHRoaXMuc2tpcERldGVjdHx8dGhpcy5nZXRBdHRyaWJ1dGUoImRvRXhwcmVzc0luc3RhbGwiKXx8dGhpcy5pbnN0YWxsZWRWZXIudmVyc2lvbklzVmFsaWQodGhpcy5nZXRBdHRyaWJ1dGUoInZlcnNpb24iKSkpe3ZhciBuPSh0eXBlb2YgXzIwPT0ic3RyaW5nIik/ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXzIwKTpfMjA7bi5pbm5lckhUTUw9dGhpcy5nZXRTV0ZIVE1MKCk7cmV0dXJuIHRydWU7fWVsc2V7aWYodGhpcy5nZXRBdHRyaWJ1dGUoInJlZGlyZWN0VXJsIikhPSIiKXtkb2N1bWVudC5sb2NhdGlvbi5yZXBsYWNlKHRoaXMuZ2V0QXR0cmlidXRlKCJyZWRpcmVjdFVybCIpKTt9fXJldHVybiBmYWxzZTt9fTtkZWNvbmNlcHQuU1dGT2JqZWN0VXRpbC5nZXRQbGF5ZXJWZXJzaW9uPWZ1bmN0aW9uKCl7dmFyIF8yMz1uZXcgZGVjb25jZXB0LlBsYXllclZlcnNpb24oWzAsMCwwXSk7aWYobmF2aWdhdG9yLnBsdWdpbnMmJm5hdmlnYXRvci5taW1lVHlwZXMubGVuZ3RoKXt2YXIgeD1uYXZpZ2F0b3IucGx1Z2luc1siU2hvY2t3YXZlIEZsYXNoIl07aWYoeCYmeC5kZXNjcmlwdGlvbil7XzIzPW5ldyBkZWNvbmNlcHQuUGxheWVyVmVyc2lvbih4LmRlc2NyaXB0aW9uLnJlcGxhY2UoLyhbYS16QS1aXXxccykrLywiIikucmVwbGFjZSgvKFxzK3J8XHMrYlswLTldKykvLCIuIikuc3BsaXQoIi4iKSk7fX1lbHNle2lmKG5hdmlnYXRvci51c2VyQWdlbnQmJm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiV2luZG93cyBDRSIpPj0wKXt2YXIgYXhvPTE7dmFyIF8yNj0zO3doaWxlKGF4byl7dHJ5e18yNisrO2F4bz1uZXcgQWN0aXZlWE9iamVjdCgiU2hvY2t3YXZlRmxhc2guU2hvY2t3YXZlRmxhc2guIitfMjYpO18yMz1uZXcgZGVjb25jZXB0LlBsYXllclZlcnNpb24oW18yNiwwLDBdKTt9Y2F0Y2goZSl7YXhvPW51bGw7fX19ZWxzZXt0cnl7dmFyIGF4bz1uZXcgQWN0aXZlWE9iamVjdCgiU2hvY2t3YXZlRmxhc2guU2hvY2t3YXZlRmxhc2guNyIpO31jYXRjaChlKXt0cnl7dmFyIGF4bz1uZXcgQWN0aXZlWE9iamVjdCgiU2hvY2t3YXZlRmxhc2guU2hvY2t3YXZlRmxhc2guNiIpO18yMz1uZXcgZGVjb25jZXB0LlBsYXllclZlcnNpb24oWzYsMCwyMV0pO2F4by5BbGxvd1NjcmlwdEFjY2Vzcz0iYWx3YXlzIjt9Y2F0Y2goZSl7aWYoXzIzLm1ham9yPT02KXtyZXR1cm4gXzIzO319dHJ5e2F4bz1uZXcgQWN0aXZlWE9iamVjdCgiU2hvY2t3YXZlRmxhc2guU2hvY2t3YXZlRmxhc2giKTt9Y2F0Y2goZSl7fX1pZihheG8hPW51bGwpe18yMz1uZXcgZGVjb25jZXB0LlBsYXllclZlcnNpb24oYXhvLkdldFZhcmlhYmxlKCIkdmVyc2lvbiIpLnNwbGl0KCIgIilbMV0uc3BsaXQoIiwiKSk7fX19cmV0dXJuIF8yMzt9O2RlY29uY2VwdC5QbGF5ZXJWZXJzaW9uPWZ1bmN0aW9uKF8yOSl7dGhpcy5tYWpvcj1fMjlbMF0hPW51bGw/cGFyc2VJbnQoXzI5WzBdKTowO3RoaXMubWlub3I9XzI5WzFdIT1udWxsP3BhcnNlSW50KF8yOVsxXSk6MDt0aGlzLnJldj1fMjlbMl0hPW51bGw/cGFyc2VJbnQoXzI5WzJdKTowO307ZGVjb25jZXB0LlBsYXllclZlcnNpb24ucHJvdG90eXBlLnZlcnNpb25Jc1ZhbGlkPWZ1bmN0aW9uKGZ2KXtpZih0aGlzLm1ham9yPGZ2Lm1ham9yKXtyZXR1cm4gZmFsc2U7fWlmKHRoaXMubWFqb3I+ZnYubWFqb3Ipe3JldHVybiB0cnVlO31pZih0aGlzLm1pbm9yPGZ2Lm1pbm9yKXtyZXR1cm4gZmFsc2U7fWlmKHRoaXMubWlub3I+ZnYubWlub3Ipe3JldHVybiB0cnVlO31pZih0aGlzLnJldjxmdi5yZXYpe3JldHVybiBmYWxzZTt9cmV0dXJuIHRydWU7fTtkZWNvbmNlcHQudXRpbD17Z2V0UmVxdWVzdFBhcmFtZXRlcjpmdW5jdGlvbihfMmIpe3ZhciBxPWRvY3VtZW50LmxvY2F0aW9uLnNlYXJjaHx8ZG9jdW1lbnQubG9jYXRpb24uaGFzaDtpZihfMmI9PW51bGwpe3JldHVybiBxO31pZihxKXt2YXIgXzJkPXEuc3Vic3RyaW5nKDEpLnNwbGl0KCImIik7Zm9yKHZhciBpPTA7aTxfMmQubGVuZ3RoO2krKyl7aWYoXzJkW2ldLnN1YnN0cmluZygwLF8yZFtpXS5pbmRleE9mKCI9IikpPT1fMmIpe3JldHVybiBfMmRbaV0uc3Vic3RyaW5nKChfMmRbaV0uaW5kZXhPZigiPSIpKzEpKTt9fX1yZXR1cm4gIiI7fX07ZGVjb25jZXB0LlNXRk9iamVjdFV0aWwuY2xlYW51cFNXRnM9ZnVuY3Rpb24oKXt2YXIgXzJmPWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJPQkpFQ1QiKTtmb3IodmFyIGk9XzJmLmxlbmd0aC0xO2k+PTA7aS0tKXtfMmZbaV0uc3R5bGUuZGlzcGxheT0ibm9uZSI7Zm9yKHZhciB4IGluIF8yZltpXSl7aWYodHlwZW9mIF8yZltpXVt4XT09ImZ1bmN0aW9uIil7XzJmW2ldW3hdPWZ1bmN0aW9uKCl7fTt9fX19O2lmKGRlY29uY2VwdC5TV0ZPYmplY3QuZG9QcmVwVW5sb2FkKXtpZighZGVjb25jZXB0LnVubG9hZFNldCl7ZGVjb25jZXB0LlNXRk9iamVjdFV0aWwucHJlcFVubG9hZD1mdW5jdGlvbigpe19fZmxhc2hfdW5sb2FkSGFuZGxlcj1mdW5jdGlvbigpe307X19mbGFzaF9zYXZlZFVubG9hZEhhbmRsZXI9ZnVuY3Rpb24oKXt9O3dpbmRvdy5hdHRhY2hFdmVudCgib251bmxvYWQiLGRlY29uY2VwdC5TV0ZPYmplY3RVdGlsLmNsZWFudXBTV0ZzKTt9O3dpbmRvdy5hdHRhY2hFdmVudCgib25iZWZvcmV1bmxvYWQiLGRlY29uY2VwdC5TV0ZPYmplY3RVdGlsLnByZXBVbmxvYWQpO2RlY29uY2VwdC51bmxvYWRTZXQ9dHJ1ZTt9fWlmKCFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCYmZG9jdW1lbnQuYWxsKXtkb2N1bWVudC5nZXRFbGVtZW50QnlJZD1mdW5jdGlvbihpZCl7cmV0dXJuIGRvY3VtZW50LmFsbFtpZF07fTt9dmFyIGdldFF1ZXJ5UGFyYW1WYWx1ZT1kZWNvbmNlcHQudXRpbC5nZXRSZXF1ZXN0UGFyYW1ldGVyO3ZhciBGbGFzaE9iamVjdD1kZWNvbmNlcHQuU1dGT2JqZWN0O3ZhciBTV0ZPYmplY3Q9ZGVjb25jZXB0LlNXRk9iamVjdDsNCg0KDQoNCi8vQ29weXJpZ2h0IDIwMDYgQWRvYmUgU3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLy8NCi8vVGhpcyBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgaW1wbGVtZW50aW5nIGFuIEFjdGl2ZSBDb250ZW50IGV4dGVuc2lvbiAtLSBhIHBpZWNlIG9mIGNvZGUgdGhhdCBrbm93cyBob3cgdG8gcmV3cml0ZSBPQkpFQ1QgdGFncyBzbyB0aGF0IHRoZXkgY29tcGx5IHRvIHRoZSBFb2xhcyBwYXRlbnQgd2l0aG91dCBtYWtpbmcgdGhlIGJyb3dzZXIgZGlzcGxheSB0aGUgIlByZXNzIE9LIHRvIGNvbnRpbnVlIGxvYWRpbmcgdGhlIGNvbnRlbnQgb2YgdGhpcyBwYWdlIiBtZXNzYWdlIGJveC4NCi8vDQovLyBXaGVuIHRoZSB1c2VyIGhvdmVycyB0aGUgbW91c2Ugb3ZlciBhbiBBY3RpdmVYIGNvbnRyb2wgaW4gSW50ZXJuZXQgRXhwbG9yZXIgNiB1cGRhdGVkIHdpdGggKEFwcmlsIDIwMDYpIEN1bXVsYXRpdmUgU2VjdXJpdHkgVXBkYXRlICg5MTI4MTIpIG9yIEludGVybmV0IEV4cGxvcmVyIDcsIHRoZSBmb2xsb3dpbmcgbWVzc2FnZSBpcyBkaXNwbGF5ZWQ6DQovLyCTUHJlc3MgU3BhY2ViYXIgb3IgRW50ZXIgdG8gYWN0aXZhdGUgYW5kIHVzZSB0aGlzIGNvbnRyb2wulA0KLy8gVGhlIHVzZXIgY2FuIG5vdyBjbGljayB0aGUgbW91c2UgYW55d2hlcmUgaW5zaWRlIHRoZSBBY3RpdmVYIGNvbnRyb2wgYXJlYSwgb3IgcHJlc3MgdGhlIFNwYWNlYmFyIG9yIEVudGVyIGtleSB0byBhY3RpdmF0ZSB0aGUgY29udHJvbC4NCi8vIFRoZSBzdGFuZGFyZC5qcyBmaWxlIGhhcyBiZWVuIGludHJvZHVjZWQgdG8gcmV0YWluIHRoZSBlYXJsaWVyIGJlaGF2aW9yIHdoZXJlIHRoZSBjb250cm9sIHJlbWFpbnMgaW50ZXJhY3RpdmUgZnJvbSB0aGUgZmlyc3QgY2xpY2sgdG8gdGhlIGxhc3QuDQoNCmZ1bmN0aW9uIHdyaXRlRG9jdW1lbnQocyl7ZG9jdW1lbnQud3JpdGUocyk7fQ0K