{"id":"CVE-2012-5783","description":"Apache Commons HttpClient 3.x, as used in Amazon Flexible Payments Service (FPS) merchant Java SDK and other products, does not verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate, which allows man-in-the-middle attackers to spoof SSL servers via an arbitrary valid certificate.","cvssScore":5.8,"cvssVersion":"2.0","cvssVector":"AV:N/AC:M/Au:N/C:P/I:P/A:N","cvssMetrics":[{"version":"2.0","score":5.8,"vector":"AV:N/AC:M/Au:N/C:P/I:P/A:N","source":"nvd@nist.gov","sourceName":"NVD","type":"Primary"}],"cwes":["CWE-295"],"resolved":"MITIGATED-BY-RASP","published":"2012-11-04","lastModified":"2026-06-16","affectedProducts":[{"vendor":"apache","product":"httpclient","version":"3.1"},{"vendor":"canonical","product":"ubuntu linux","version":"12.04"},{"vendor":"canonical","product":"ubuntu linux","version":"14.04"},{"vendor":"canonical","product":"ubuntu linux","version":"15.04"}],"totalAffectedProducts":2,"references":[{"url":"https://access.redhat.com/errata/RHSA-2017:0868","source":"osv","tags":["WEB"]},{"url":"https://exchange.xforce.ibmcloud.com/vulnerabilities/79984","source":"osv","tags":["WEB"]},{"url":"https://github.com/apache/httpcomponents-client","source":"osv","tags":["PACKAGE"]},{"url":"https://issues.apache.org/jira/browse/HTTPCLIENT-1265","source":"osv","tags":["WEB"]},{"url":"http://lists.opensuse.org/opensuse-updates/2013-02/msg00078.html","source":"osv","tags":["WEB"]},{"url":"http://lists.opensuse.org/opensuse-updates/2013-04/msg00040.html","source":"osv","tags":["WEB"]},{"url":"http://lists.opensuse.org/opensuse-updates/2013-04/msg00041.html","source":"osv","tags":["WEB"]},{"url":"http://lists.opensuse.org/opensuse-updates/2013-04/msg00053.html","source":"osv","tags":["WEB"]},{"url":"http://rhn.redhat.com/errata/RHSA-2013-0270.html","source":"osv","tags":["WEB"]},{"url":"http://rhn.redhat.com/errata/RHSA-2013-0679.html","source":"osv","tags":["WEB"]}],"reasoning":{"decidingSource":"armr-patch-file","decidingReason":"CVE has an ARMR patch rule that provides mitigation","verdicts":[{"rule":"rejected","stage":"identity","outcome":"no-match"},{"rule":"armr-patch-file","stage":"scope","outcome":"matched","status":"MITIGATED-BY-RASP","detail":"ARMR patch file exists for this CVE","decisive":true}],"affectedPackages":[{"name":"commons-httpclient:commons-httpclient","introduced":"3.0"}]},"relatedFiles":{"patchFiles":[{"path":"rules/libraries/apache/commons/CVE-2012-5783/patch/2.6/CVE-2012-5783.armr","url":"https://github.com/waratek/java-patches/blob/develop/rules/libraries/apache/commons/CVE-2012-5783/patch/2.6/CVE-2012-5783.armr","created":"2020-06-25T21:16:55Z","updated":"2026-03-04T16:48:46Z","content":"YXBwKCJBUEFDSEUgQ09NTU9OUyIpOgogICAgcmVxdWlyZXModmVyc2lvbjogIkFSTVIvMi42IikKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgQ1ZFLTIwMTItNTc4MyAoQVBBQ0hFIENPTU1PTlMpCgogICAgICAgIENWU1MgMi4wIG1ldHJpY3M6CiAgICAgICAgICAgIEJhc2UgU2NvcmUgICAgICAgICAgfCA1LjggTUVESVVNCiAgICAgICAgICAgIEFjY2VzcyBWZWN0b3IgICAgICAgfCBOZXR3b3JrCiAgICAgICAgICAgIEFjY2VzcyBDb21wbGV4aXR5ICAgfCBNZWRpdW0KICAgICAgICAgICAgQXV0aGVudGljYXRpb24gICAgICB8IE5vbmUKICAgICAgICAgICAgQ29uZmlkZW50aWFsaXR5ICAgICB8IFBhcnRpYWwKICAgICAgICAgICAgSW50ZWdyaXR5ICAgICAgICAgICB8IFBhcnRpYWwKICAgICAgICAgICAgQXZhaWxhYmlsaXR5ICAgICAgICB8IE5vbmUKCiAgICAgICAgRGVzY3JpcHRpb246CiAgICAgICAgICAgIEFwYWNoZSBDb21tb25zIEh0dHBDbGllbnQgMy54LCBhcyB1c2VkIGluIEFtYXpvbiBGbGV4aWJsZSBQYXltZW50cwogICAgICAgICAgICBTZXJ2aWNlIChGUFMpIG1lcmNoYW50IEphdmEgU0RLIGFuZCBvdGhlciBwcm9kdWN0cywgZG9lcyBub3QgdmVyaWZ5IHRoYXQKICAgICAgICAgICAgdGhlIHNlcnZlciBob3N0bmFtZSBtYXRjaGVzIGEgZG9tYWluIG5hbWUgaW4gdGhlIHN1YmplY3QncyBDb21tb24gTmFtZQogICAgICAgICAgICAoQ04pIG9yIHN1YmplY3RBbHROYW1lIGZpZWxkIG9mIHRoZSBYLjUwOSBjZXJ0aWZpY2F0ZSwgd2hpY2ggYWxsb3dzCiAgICAgICAgICAgIG1hbi1pbi10aGUtbWlkZGxlIGF0dGFja2VycyB0byBzcG9vZiBTU0wgc2VydmVycyB2aWEgYW4gYXJiaXRyYXJ5IHZhbGlkCiAgICAgICAgICAgIGNlcnRpZmljYXRlLgoKICAgICAgICBSZXNvdXJjZXM6CiAgICAgICAgICAgIGh0dHBzOi8vYnVnemlsbGEucmVkaGF0LmNvbS9zaG93X2J1Zy5jZ2k/aWQ9ODczMzE3CiAgICAgICAgICAgIGh0dHBzOi8vaXNzdWVzLmFwYWNoZS5vcmcvamlyYS9icm93c2UvSFRUUENMSUVOVC0xMjY1CiAgICAgICAgICAgIGh0dHA6Ly9zdm4uYXBhY2hlLm9yZy92aWV3dmMvaHR0cGNvbXBvbmVudHMvb2FjLmhjM3gvdHJ1bmsvc3JjL2phdmEvb3JnL2FwYWNoZS9jb21tb25zL2h0dHBjbGllbnQvcHJvdG9jb2wvU1NMUHJvdG9jb2xTb2NrZXRGYWN0b3J5LmphdmE/dmlldz1tYXJrdXAKICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICBDVkUtMjAxMi02MTUzIChBUEFDSEUgQ09NTU9OUykKCiAgICAgICAgQ1ZTUyAyLjAgbWV0cmljczoKICAgICAgICAgICAgQmFzZSBTY29yZSAgICAgICAgfCA0LjMgTUVESVVNCiAgICAgICAgICAgIEFjY2VzcyBWZWN0b3IgICAgIHwgTmV0d29yawogICAgICAgICAgICBBY2Nlc3MgQ29tcGxleGl0eSB8IE1lZGl1bQogICAgICAgICAgICBBdXRoZW50aWNhdGlvbiAgICB8IE5vbmUKICAgICAgICAgICAgQ29uZmlkZW50aWFsaXR5ICAgfCBOb25lCiAgICAgICAgICAgIEludGVncml0eSAgICAgICAgIHwgUGFydGlhbAogICAgICAgICAgICBBdmFpbGFiaWxpdHkgICAgICB8IE5vbmUKCiAgICAgICAgRGVzY3JpcHRpb246CiAgICAgICAgICAgIGh0dHAvY29ubi9zc2wvQWJzdHJhY3RWZXJpZmllci5qYXZhIGluIEFwYWNoZSBDb21tb25zIEh0dHBDbGllbnQgYmVmb3JlCiAgICAgICAgICAgIDQuMi4zIGRvZXMgbm90IHByb3Blcmx5IHZlcmlmeSB0aGF0IHRoZSBzZXJ2ZXIgaG9zdG5hbWUgbWF0Y2hlcyBhIGRvbWFpbgogICAgICAgICAgICBuYW1lIGluIHRoZSBzdWJqZWN0J3MgQ29tbW9uIE5hbWUgKENOKSBvciBzdWJqZWN0QWx0TmFtZSBmaWVsZCBvZiB0aGUKICAgICAgICAgICAgWC41MDkgY2VydGlmaWNhdGUsIHdoaWNoIGFsbG93cyBtYW4taW4tdGhlLW1pZGRsZSBhdHRhY2tlcnMgdG8gc3Bvb2YgU1NMCiAgICAgICAgICAgIHNlcnZlcnMgdmlhIGEgY2VydGlmaWNhdGUgd2l0aCBhIHN1YmplY3QgdGhhdCBzcGVjaWZpZXMgYSBjb21tb24gbmFtZSBpbgogICAgICAgICAgICBhIGZpZWxkIHRoYXQgaXMgbm90IHRoZSBDTiBmaWVsZC4gTk9URTogdGhpcyBpc3N1ZSBleGlzdHMgYmVjYXVzZSBvZiBhbgogICAgICAgICAgICBpbmNvbXBsZXRlIGZpeCBmb3IgQ1ZFLTIwMTItNTc4My4KCiAgICAgICAgUmVzb3VyY2VzOgogICAgICAgICAgICBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hvd19idWcuY2dpP2lkPTExMjk5MTYKICAgICAgICAgICAgaHR0cDovL3N2bi5hcGFjaGUub3JnL3ZpZXd2Yz92aWV3PXJldmlzaW9uJnJldmlzaW9uPTE0MTE3MDUKICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICBDVkUtMjAxNC0zNTc3IChBUEFDSEUgQ09NTU9OUykKCiAgICAgICAgQ1ZTUyAyLjAgbWV0cmljczoKICAgICAgICAgICAgQmFzZSBTY29yZSAgICAgICAgfCA1LjggTUVESVVNCiAgICAgICAgICAgIEFjY2VzcyBWZWN0b3IgICAgIHwgTmV0d29yawogICAgICAgICAgICBBY2Nlc3MgQ29tcGxleGl0eSB8IE1lZGl1bQogICAgICAgICAgICBBdXRoZW50aWNhdGlvbiAgICB8IE5vbmUKICAgICAgICAgICAgQ29uZmlkZW50aWFsaXR5ICAgfCBQYXJ0aWFsCiAgICAgICAgICAgIEludGVncml0eSAgICAgICAgIHwgUGFydGlhbAogICAgICAgICAgICBBdmFpbGFiaWxpdHkgICAgICB8IE5vbmUKCiAgICAgICAgRGVzY3JpcHRpb246CiAgICAgICAgICAgIG9yZy5hcGFjaGUuaHR0cC5jb25uLnNzbC5BYnN0cmFjdFZlcmlmaWVyIGluIEFwYWNoZSBIdHRwQ29tcG9uZW50cwogICAgICAgICAgICBIdHRwQ2xpZW50IGJlZm9yZSA0LjMuNSBhbmQgSHR0cEFzeW5jQ2xpZW50IGJlZm9yZSA0LjAuMiBkb2VzIG5vdAogICAgICAgICAgICBwcm9wZXJseSB2ZXJpZnkgdGhhdCB0aGUgc2VydmVyIGhvc3RuYW1lIG1hdGNoZXMgYSBkb21haW4gbmFtZSBpbiB0aGUKICAgICAgICAgICAgc3ViamVjdCdzIENvbW1vbiBOYW1lIChDTikgb3Igc3ViamVjdEFsdE5hbWUgZmllbGQgb2YgdGhlIFguNTA5CiAgICAgICAgICAgIGNlcnRpZmljYXRlLCB3aGljaCBhbGxvd3MgbWFuLWluLXRoZS1taWRkbGUgYXR0YWNrZXJzIHRvIHNwb29mIFNTTAogICAgICAgICAgICBzZXJ2ZXJzIHZpYSBhICJDTj0iIHN0cmluZyBpbiBhIGZpZWxkIGluIHRoZSBkaXN0aW5ndWlzaGVkIG5hbWUgKEROKSBvZgogICAgICAgICAgICBhIGNlcnRpZmljYXRlLCBhcyBkZW1vbnN0cmF0ZWQgYnkgdGhlICJmb28sQ049d3d3LmFwYWNoZS5vcmciIHN0cmluZwogICAgICAgICAgICBpbiB0aGUgTyBmaWVsZC4KCiAgICAgICAgUmVzb3VyY2VzOgogICAgICAgICAgICBodHRwczovL2J1Z3ppbGxhLnJlZGhhdC5jb20vc2hvd19idWcuY2dpP2lkPTExMjkwNzQKICAgICAgICAgICAgaHR0cDovL3N2bi5hcGFjaGUub3JnL3ZpZXd2Yz92aWV3PXJldmlzaW9uJnJldmlzaW9uPTE2MTQwNjQKICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICBBZmZlY3RlZCBPcGVyYXRpbmcgU3lzdGVtczoKICAgICAgICAgICAgQW55CgogICAgICAgIEFmZmVjdGVkIFZlcnNpb25zOgogICAgICAgICAgICBBcGFjaGUgY29tbW9ucy1odHRwY2xpZW50IDMueAoKICAgICAgICBUZXN0ZWQgVmVyc2lvbnM6CiAgICAgICAgICAgIDMuMQoKICAgICAgICBQcm90ZWN0aW9uIFByb3ZpZGVkOgogICAgICAgICAgICBGdW5jdGlvbmFsCgogICAgICAgIFBhdGNoIFZlcnNpb246CiAgICAgICAgICAgIDEuMAogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIHBhdGNoKCJDVkUtMjAxMi01NzgzIDowMSIpOgogICAgICAgIGZ1bmN0aW9uKCJvcmcvYXBhY2hlL2NvbW1vbnMvaHR0cGNsaWVudC9wcm90b2NvbC9TU0xQcm90b2NvbFNvY2tldEZhY3RvcnkuY3JlYXRlU29ja2V0KExqYXZhL2xhbmcvU3RyaW5nO0lMamF2YS9uZXQvSW5ldEFkZHJlc3M7SUxvcmcvYXBhY2hlL2NvbW1vbnMvaHR0cGNsaWVudC9wYXJhbXMvSHR0cENvbm5lY3Rpb25QYXJhbXM7KUxqYXZhL25ldC9Tb2NrZXQ7IiwKICAgICAgICAgICAgY2hlY2tzdW1zOiBbIjQ2NGViOWZkNjgiXSkgIC8vIGNvbW1vbnMtaHR0cGNsaWVudDozLjEKICAgICAgICBleGl0KCkKCiAgICAgICAgY29kZShsYW5ndWFnZTogamF2YSwgICBpbXBvcnQ6IFsiamF2YXgubmFtaW5nLkludmFsaWROYW1lRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC5uYW1pbmcuTmFtaW5nRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC5uYW1pbmcuZGlyZWN0b3J5LkF0dHJpYnV0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmRpcmVjdG9yeS5BdHRyaWJ1dGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC5uYW1pbmcubGRhcC5MZGFwTmFtZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmxkYXAuUmRuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC5uZXQuc3NsLlNTTEV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xTZXNzaW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZheC5uZXQuc3NsLlNTTFNvY2tldCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5JT0V4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5pby5JbnB1dFN0cmVhbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5uZXQuSW5ldEFkZHJlc3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuc2VjdXJpdHkuY2VydC5DZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuc2VjdXJpdHkuY2VydC5YNTA5Q2VydGlmaWNhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5BcnJheUxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5BcnJheXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Db2xsZWN0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuSXRlcmF0b3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5MaW5rZWRMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkxvY2FsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLk5vU3VjaEVsZW1lbnRFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5yZWdleC5QYXR0ZXJuIl0pOgogICAgICAgICAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmdbXSBCQURfQ09VTlRSWV8yTERTID0KICAgICAgICAgICAgICAgICAgICB7ImFjIiwgImNvIiwgImNvbSIsICJlZCIsICJlZHUiLCAiZ28iLCAiZ291diIsICJnb3YiLCAiaW5mbyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGciLCAibmUiLCAibmV0IiwgIm9yIiwgIm9yZyJ9OwoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBJUFY0X1BBVFRFUk4gPQogICAgICAgICAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiXigyNVswLTVdfDJbMC00XVxcZHxbMC0xXT9cXGQ/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8WzAtMV0/XFxkP1xcZCkpezN9JCIpOwoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBJUFY2X1NURF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oPzpbMC05YS1mQS1GXXsxLDR9Oil7N31bMC05YS1mQS1GXXsxLDR9JCIpOwoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBJUFY2X0hFWF9DT01QUkVTU0VEX1BBVFRFUk4gPQogICAgICAgICAgICAgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiXigoPzpbMC05QS1GYS1mXXsxLDR9KD86OlswLTlBLUZhLWZdezEsNH0pKik/KTo6KCg/OlswLTlBLUZhLWZdezEsNH0oPzo6WzAtOUEtRmEtZl17MSw0fSkqKT8pJCIpOwoKICAgICAgICAgICAgcHVibGljIHZvaWQgcGF0Y2goSmF2YUZyYW1lIGZyYW1lKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgaG9zdCA9IGZyYW1lLmxvYWRTdHJpbmdWYXJpYWJsZSgxKTsKICAgICAgICAgICAgICAgIFNTTFNvY2tldCBzc2xTb2NrZXQgPSAoU1NMU29ja2V0KSBmcmFtZS5sb2FkT2JqZWN0T3BlcmFuZCgwKTsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHZlcmlmeUhvc3ROYW1lKGhvc3QsIHNzbFNvY2tldCk7CiAgICAgICAgICAgICAgICAgICAgZnJhbWUucmV0dXJuT2JqZWN0KHNzbFNvY2tldCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIGZyYW1lLnJhaXNlRXhjZXB0aW9uKGV4KTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbihleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmVyaWZ5SG9zdE5hbWUoU3RyaW5nIGhvc3QsIFNTTFNvY2tldCBzc2wpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIGlmIChob3N0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJob3N0IHRvIHZlcmlmeSB3YXMgbnVsbCIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFNTTFNlc3Npb24gc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgSW5wdXRTdHJlYW0gaW4gPSBzc2wuZ2V0SW5wdXRTdHJlYW0oKTsKICAgICAgICAgICAgICAgICAgICBpbi5hdmFpbGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uID0gc3NsLmdldFNlc3Npb24oKTsKICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNzbC5zdGFydEhhbmRzaGFrZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uID0gc3NsLmdldFNlc3Npb24oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVbXSBjZXJ0cyA9IHNlc3Npb24uZ2V0UGVlckNlcnRpZmljYXRlcygpOwogICAgICAgICAgICAgICAgdmVyaWZ5SG9zdE5hbWUoaG9zdC50cmltKCkudG9Mb3dlckNhc2UoTG9jYWxlLlVTKSwgKFg1MDlDZXJ0aWZpY2F0ZSkgY2VydHNbMF0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeUhvc3ROYW1lKGZpbmFsIFN0cmluZyBob3N0LCBYNTA5Q2VydGlmaWNhdGUgY2VydCkKICAgICAgICAgICAgICAgICAgICB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIFN0cmluZ1tdIGNucyA9IGdldENOcyhjZXJ0KTsKICAgICAgICAgICAgICAgIFN0cmluZ1tdIHN1YmplY3RBbHRzID0gZ2V0U3ViamVjdEFsdHMoY2VydCwgaG9zdCk7CiAgICAgICAgICAgICAgICB2ZXJpZnlIb3N0TmFtZShob3N0LCBjbnMsIHN1YmplY3RBbHRzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2ZXJpZnlIb3N0TmFtZShmaW5hbCBTdHJpbmcgaG9zdCwgU3RyaW5nW10gY25zLCBTdHJpbmdbXSBzdWJqZWN0QWx0cykKICAgICAgICAgICAgICAgICAgICB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKCiAgICAgICAgICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PFN0cmluZz4gbmFtZXMgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICBpZiAoY25zICE9IG51bGwgJiYgY25zLmxlbmd0aCA+IDAgJiYgY25zWzBdICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lcy5hZGQoY25zWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdWJqZWN0QWx0cyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChmaW5hbCBTdHJpbmcgc3ViamVjdEFsdCA6IHN1YmplY3RBbHRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdWJqZWN0QWx0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmFkZChzdWJqZWN0QWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAobmFtZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG1zZyA9ICJDZXJ0aWZpY2F0ZSBmb3IgPCIgKyBob3N0ICsgIj4gZG9lc24ndCBjb250YWluIENOIG9yIEROUyBzdWJqZWN0QWx0IjsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU1NMRXhjZXB0aW9uKG1zZyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBob3N0TmFtZSA9IG5vcm1hbGlzZUlQdjZBZGRyZXNzKGhvc3QudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5FTkdMSVNIKSk7CiAgICAgICAgICAgICAgICBib29sZWFuIG1hdGNoID0gZmFsc2U7CgogICAgICAgICAgICAgICAgZm9yIChmaW5hbCBJdGVyYXRvcjxTdHJpbmc+IGl0ID0gbmFtZXMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY24gPSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgY24gPSBjbi50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiIDwiKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGNuKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCc+Jyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0Lmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIgT1IiKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHBhcnRzID0gY24uc3BsaXQoIlxcLiIpOwogICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gZG9XaWxkY2FyZCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0cy5sZW5ndGggPj0gMyAmJiBwYXJ0c1swXS5lbmRzV2l0aCgiKiIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkQ291bnRyeVdpbGRjYXJkKGNuKSAmJiAhaXNJUEFkZHJlc3MoaG9zdCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChkb1dpbGRjYXJkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBmaXJzdHBhcnQgPSBwYXJ0c1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0cGFydC5sZW5ndGgoKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSBmaXJzdHBhcnQuc3Vic3RyaW5nKDAsIGZpcnN0cGFydC5sZW5ndGgoKSAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN1ZmZpeCA9IGNuLnN1YnN0cmluZyhmaXJzdHBhcnQubGVuZ3RoKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGhvc3RTdWZmaXggPSBob3N0TmFtZS5zdWJzdHJpbmcocHJlZml4Lmxlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gaG9zdE5hbWUuc3RhcnRzV2l0aChwcmVmaXgpICYmIGhvc3RTdWZmaXguZW5kc1dpdGgoc3VmZml4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gaG9zdE5hbWUuZW5kc1dpdGgoY24uc3Vic3RyaW5nKDEpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gY291bnREb3RzKGhvc3ROYW1lKSA9PSBjb3VudERvdHMoY24pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBob3N0TmFtZS5lcXVhbHMobm9ybWFsaXNlSVB2NkFkZHJlc3MoY24pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU1NMRXhjZXB0aW9uKCJob3N0bmFtZSBpbiBjZXJ0aWZpY2F0ZSBkaWRuJ3QgbWF0Y2g6IDwiICsgaG9zdCArICI+ICE9IiArIGJ1Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUEFkZHJlc3MoZmluYWwgU3RyaW5nIGhvc3RuYW1lKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWUgIT0gbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAmJiAoCiAgICAgICAgICAgICAgICAgICAgICAgIElQVjRfUEFUVEVSTi5tYXRjaGVyKGhvc3RuYW1lKS5tYXRjaGVzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBJUFY2X1NURF9QQVRURVJOLm1hdGNoZXIoaG9zdG5hbWUpLm1hdGNoZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IElQVjZfSEVYX0NPTVBSRVNTRURfUEFUVEVSTi5tYXRjaGVyKGhvc3RuYW1lKS5tYXRjaGVzKCkKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBpbnQgY291bnREb3RzKGZpbmFsIFN0cmluZyBkYXRhKSB7CiAgICAgICAgICAgICAgICBpbnQgZG90cyA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmNoYXJBdChpKSA9PSAnLicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG90cyArPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBkb3RzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHZhbGlkQ291bnRyeVdpbGRjYXJkKGZpbmFsIFN0cmluZyBjbikgewogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gcGFydHMgPSBjbi5zcGxpdCgiXFwuIik7CiAgICAgICAgICAgICAgICBpZiAocGFydHMubGVuZ3RoICE9IDMgfHwgcGFydHNbMl0ubGVuZ3RoKCkgIT0gMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIEFycmF5cy5iaW5hcnlTZWFyY2goQkFEX0NPVU5UUllfMkxEUywgcGFydHNbMV0pIDwgMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZ2V0Q05zKGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0KSB7CiAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc3ViamVjdFByaW5jaXBhbCA9IGNlcnQuZ2V0U3ViamVjdFg1MDBQcmluY2lwYWwoKS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0cmFjdENOcyhzdWJqZWN0UHJpbmNpcGFsKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFNTTEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmdbXSBleHRyYWN0Q05zKGZpbmFsIFN0cmluZyBzdWJqZWN0UHJpbmNpcGFsKSB0aHJvd3MgU1NMRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIGlmIChzdWJqZWN0UHJpbmNpcGFsID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZpbmFsIExpc3Q8U3RyaW5nPiBjbnMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgTGRhcE5hbWUgc3ViamVjdEROID0gbmV3IExkYXBOYW1lKHN1YmplY3RQcmluY2lwYWwpOwogICAgICAgICAgICAgICAgICAgIGZpbmFsIExpc3Q8UmRuPiByZG5zID0gc3ViamVjdEROLmdldFJkbnMoKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gcmRucy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBSZG4gcmRzID0gcmRucy5nZXQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcyA9IHJkcy50b0F0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQXR0cmlidXRlIGNuID0gYXR0cmlidXRlcy5nZXQoImNuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE9iamVjdCB2YWx1ZSA9IGNuLmdldCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNucy5hZGQodmFsdWUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiBpZ25vcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5hbWluZ0V4Y2VwdGlvbiBpZ25vcmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludmFsaWROYW1lRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU1NMRXhjZXB0aW9uKHN1YmplY3RQcmluY2lwYWwgKyAiIGlzIG5vdCBhIHZhbGlkIFg1MDAgZGlzdGluZ3Vpc2hlZCBuYW1lIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gY25zLmlzRW1wdHkoKSA/IG51bGwgOiBjbnMudG9BcnJheShuZXcgU3RyaW5nWzBdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZ2V0U3ViamVjdEFsdHMoCiAgICAgICAgICAgICAgICAgICAgZmluYWwgWDUwOUNlcnRpZmljYXRlIGNlcnQsIGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgZmluYWwgaW50IHN1YmplY3RUeXBlOwogICAgICAgICAgICAgICAgaWYgKGlzSVBBZGRyZXNzKGhvc3RuYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHN1YmplY3RUeXBlID0gNzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3ViamVjdFR5cGUgPSAyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZpbmFsIExpbmtlZExpc3Q8U3RyaW5nPiBzdWJqZWN0QWx0TGlzdCA9IG5ldyBMaW5rZWRMaXN0PFN0cmluZz4oKTsKICAgICAgICAgICAgICAgIENvbGxlY3Rpb248TGlzdDw/Pj4gYyA9IG51bGw7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGMgPSBjZXJ0LmdldFN1YmplY3RBbHRlcm5hdGl2ZU5hbWVzKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBDZXJ0aWZpY2F0ZVBhcnNpbmdFeGNlcHRpb24gY3BlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChmaW5hbCBMaXN0PD8+IGFDIDogYykgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PD8+IGxpc3QgPSBhQzsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGUgPSAoSW50ZWdlcikgbGlzdC5nZXQoMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09IHN1YmplY3RUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcyA9IChTdHJpbmcpIGxpc3QuZ2V0KDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViamVjdEFsdExpc3QuYWRkKHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFzdWJqZWN0QWx0TGlzdC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBzdWJqZWN0QWx0cyA9IG5ldyBTdHJpbmdbc3ViamVjdEFsdExpc3Quc2l6ZSgpXTsKICAgICAgICAgICAgICAgICAgICBzdWJqZWN0QWx0TGlzdC50b0FycmF5KHN1YmplY3RBbHRzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ViamVjdEFsdHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgbm9ybWFsaXNlSVB2NkFkZHJlc3MoZmluYWwgU3RyaW5nIGhvc3RuYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAoaG9zdG5hbWUgPT0gbnVsbCB8fCAhaXNJUHY2QWRkcmVzcyhob3N0bmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIEluZXRBZGRyZXNzIGluZXRBZGRyZXNzID0gSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKGhvc3RuYW1lKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5ldEFkZHJlc3MuZ2V0SG9zdEFkZHJlc3MoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGZpbmFsIFVua25vd25Ib3N0RXhjZXB0aW9uIHVoZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBob3N0bmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0lQdjZBZGRyZXNzKGZpbmFsIFN0cmluZyBpbnB1dCkgewogICAgICAgICAgICAgICAgcmV0dXJuIElQVjZfU1REX1BBVFRFUk4ubWF0Y2hlcihpbnB1dCkubWF0Y2hlcygpIHx8IGlzSVB2NkhleENvbXByZXNzZWRBZGRyZXNzKGlucHV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0lQdjZIZXhDb21wcmVzc2VkQWRkcmVzcyhmaW5hbCBTdHJpbmcgaW5wdXQpIHsKICAgICAgICAgICAgICAgIGludCBjb2xvbkNvdW50ID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5jaGFyQXQoaSkgPT0gJzonKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9uQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gIGNvbG9uQ291bnQgPD0gNyAmJiBJUFY2X0hFWF9DT01QUkVTU0VEX1BBVFRFUk4ubWF0Y2hlcihpbnB1dCkubWF0Y2hlcygpOwogICAgICAgICAgICB9CiAgICAgICAgZW5kY29kZQogICAgZW5kcGF0Y2gKCiAgICBwYXRjaCgiQ1ZFLTIwMTItNTc4MyA6MDIiKToKICAgICAgICBmdW5jdGlvbigib3JnL2FwYWNoZS9jb21tb25zL2h0dHBjbGllbnQvcHJvdG9jb2wvU1NMUHJvdG9jb2xTb2NrZXRGYWN0b3J5LmNyZWF0ZVNvY2tldChMamF2YS9sYW5nL1N0cmluZztJTGphdmEvbmV0L0luZXRBZGRyZXNzO0lMb3JnL2FwYWNoZS9jb21tb25zL2h0dHBjbGllbnQvcGFyYW1zL0h0dHBDb25uZWN0aW9uUGFyYW1zOylMamF2YS9uZXQvU29ja2V0OyIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI0NjRlYjlmZDY4Il0pICAvLyBjb21tb25zLWh0dHBjbGllbnQ6My4xCiAgICAgICAgZXhpdCgpCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsICAgaW1wb3J0OiBbImphdmF4Lm5hbWluZy5JbnZhbGlkTmFtZUV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLk5hbWluZ0V4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmRpcmVjdG9yeS5BdHRyaWJ1dGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5kaXJlY3RvcnkuQXR0cmlidXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmxkYXAuTGRhcE5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5sZGFwLlJkbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xTb2NrZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSU9FeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSW5wdXRTdHJlYW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubmV0LkluZXRBZGRyZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQ29sbGVjdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkl0ZXJhdG9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuTGlua2VkTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Mb2NhbGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwucmVnZXguUGF0dGVybiJdKToKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gQkFEX0NPVU5UUllfMkxEUyA9CiAgICAgICAgICAgICAgICAgICAgeyJhYyIsICJjbyIsICJjb20iLCAiZWQiLCAiZWR1IiwgImdvIiwgImdvdXYiLCAiZ292IiwgImluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImxnIiwgIm5lIiwgIm5ldCIsICJvciIsICJvcmcifTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oMjVbMC01XXwyWzAtNF1cXGR8WzAtMV0/XFxkP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfFswLTFdP1xcZD9cXGQpKXszfSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9TVERfUEFUVEVSTiA9CiAgICAgICAgICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKCJeKD86WzAtOWEtZkEtRl17MSw0fTopezd9WzAtOWEtZkEtRl17MSw0fSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oKD86WzAtOUEtRmEtZl17MSw0fSg/OjpbMC05QS1GYS1mXXsxLDR9KSopPyk6OigoPzpbMC05QS1GYS1mXXsxLDR9KD86OlswLTlBLUZhLWZdezEsNH0pKik/KSQiKTsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGhvc3QgPSBmcmFtZS5sb2FkU3RyaW5nVmFyaWFibGUoMSk7CiAgICAgICAgICAgICAgICBTU0xTb2NrZXQgc3NsU29ja2V0ID0gKFNTTFNvY2tldCkgZnJhbWUubG9hZE9iamVjdE9wZXJhbmQoMCk7CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2ZXJpZnlIb3N0TmFtZShob3N0LCAoU1NMU29ja2V0KSBzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybk9iamVjdChzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbihleCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeUhvc3ROYW1lKFN0cmluZyBob3N0LCBTU0xTb2NrZXQgc3NsKQogICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoaG9zdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaG9zdCB0byB2ZXJpZnkgd2FzIG51bGwiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBzc2wuZ2V0U2Vzc2lvbigpOwogICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gc3NsLmdldElucHV0U3RyZWFtKCk7CiAgICAgICAgICAgICAgICAgICAgaW4uYXZhaWxhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzc2wuc3RhcnRIYW5kc2hha2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBzZXNzaW9uLmdldFBlZXJDZXJ0aWZpY2F0ZXMoKTsKICAgICAgICAgICAgICAgIHZlcmlmeUhvc3ROYW1lKGhvc3QudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5VUyksIChYNTA5Q2VydGlmaWNhdGUpIGNlcnRzWzBdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2ZXJpZnlIb3N0TmFtZShmaW5hbCBTdHJpbmcgaG9zdCwgWDUwOUNlcnRpZmljYXRlIGNlcnQpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBjbnMgPSBnZXRDTnMoY2VydCk7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBzdWJqZWN0QWx0cyA9IGdldFN1YmplY3RBbHRzKGNlcnQsIGhvc3QpOwogICAgICAgICAgICAgICAgdmVyaWZ5SG9zdE5hbWUoaG9zdCwgY25zLCBzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmVyaWZ5SG9zdE5hbWUoZmluYWwgU3RyaW5nIGhvc3QsIFN0cmluZ1tdIGNucywgU3RyaW5nW10gc3ViamVjdEFsdHMpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CgogICAgICAgICAgICAgICAgZmluYWwgTGlua2VkTGlzdDxTdHJpbmc+IG5hbWVzID0gbmV3IExpbmtlZExpc3Q8U3RyaW5nPigpOwogICAgICAgICAgICAgICAgaWYgKGNucyAhPSBudWxsICYmIGNucy5sZW5ndGggPiAwICYmIGNuc1swXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZXMuYWRkKGNuc1swXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIHN1YmplY3RBbHQgOiBzdWJqZWN0QWx0cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5hZGQoc3ViamVjdEFsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKG5hbWVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtc2cgPSAiQ2VydGlmaWNhdGUgZm9yIDwiICsgaG9zdCArICI+IGRvZXNuJ3QgY29udGFpbiBDTiBvciBETlMgc3ViamVjdEFsdCI7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihtc2cpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgaG9zdE5hbWUgPSBub3JtYWxpc2VJUHY2QWRkcmVzcyhob3N0LnRyaW0oKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIGZvciAoZmluYWwgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IG5hbWVzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNuID0gaXQubmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGNuID0gY24udG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiA8Iik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjbik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnPicpOwogICAgICAgICAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiIE9SIik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBwYXJ0cyA9IGNuLnNwbGl0KCJcXC4iKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGRvV2lsZGNhcmQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMubGVuZ3RoID49IDMgJiYgcGFydHNbMF0uZW5kc1dpdGgoIioiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZENvdW50cnlXaWxkY2FyZChjbikgJiYgIWlzSVBBZGRyZXNzKGhvc3QpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoZG9XaWxkY2FyZCkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZmlyc3RwYXJ0ID0gcGFydHNbMF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdHBhcnQubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gZmlyc3RwYXJ0LnN1YnN0cmluZygwLCBmaXJzdHBhcnQubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBzdWZmaXggPSBjbi5zdWJzdHJpbmcoZmlyc3RwYXJ0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBob3N0U3VmZml4ID0gaG9zdE5hbWUuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLnN0YXJ0c1dpdGgocHJlZml4KSAmJiBob3N0U3VmZml4LmVuZHNXaXRoKHN1ZmZpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLmVuZHNXaXRoKGNuLnN1YnN0cmluZygxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGNvdW50RG90cyhob3N0TmFtZSkgPT0gY291bnREb3RzKGNuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gaG9zdE5hbWUuZXF1YWxzKG5vcm1hbGlzZUlQdjZBZGRyZXNzKGNuKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbigiaG9zdG5hbWUgaW4gY2VydGlmaWNhdGUgZGlkbid0IG1hdGNoOiA8IiArIGhvc3QgKyAiPiAhPSIgKyBidWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSVBBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lICE9IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKAogICAgICAgICAgICAgICAgICAgICAgICBJUFY0X1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgSVBWNl9TVERfUEFUVEVSTi5tYXRjaGVyKGhvc3RuYW1lKS5tYXRjaGVzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBJUFY2X0hFWF9DT01QUkVTU0VEX1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50RG90cyhmaW5hbCBTdHJpbmcgZGF0YSkgewogICAgICAgICAgICAgICAgaW50IGRvdHMgPSAwOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5jaGFyQXQoaSkgPT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdHMgKz0gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZG90czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB2YWxpZENvdW50cnlXaWxkY2FyZChmaW5hbCBTdHJpbmcgY24pIHsKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHBhcnRzID0gY24uc3BsaXQoIlxcLiIpOwogICAgICAgICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAzIHx8IHBhcnRzWzJdLmxlbmd0aCgpICE9IDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuYmluYXJ5U2VhcmNoKEJBRF9DT1VOVFJZXzJMRFMsIHBhcnRzWzFdKSA8IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldENOcyhmaW5hbCBYNTA5Q2VydGlmaWNhdGUgY2VydCkgewogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN1YmplY3RQcmluY2lwYWwgPSBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dHJhY3RDTnMoc3ViamVjdFByaW5jaXBhbCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZXh0cmFjdENOcyhmaW5hbCBTdHJpbmcgc3ViamVjdFByaW5jaXBhbCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdFByaW5jaXBhbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gY25zID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIExkYXBOYW1lIHN1YmplY3RETiA9IG5ldyBMZGFwTmFtZShzdWJqZWN0UHJpbmNpcGFsKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFJkbj4gcmRucyA9IHN1YmplY3RETi5nZXRSZG5zKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHJkbnMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUmRuIHJkcyA9IHJkbnMuZ2V0KGkpOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSByZHMudG9BdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEF0dHJpYnV0ZSBjbiA9IGF0dHJpYnV0ZXMuZ2V0KCJjbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBjbi5nZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbnMuYWRkKHZhbHVlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChOYW1pbmdFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkTmFtZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihzdWJqZWN0UHJpbmNpcGFsICsgIiBpcyBub3QgYSB2YWxpZCBYNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNucy5pc0VtcHR5KCkgPyBudWxsIDogY25zLnRvQXJyYXkobmV3IFN0cmluZ1swXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldFN1YmplY3RBbHRzKAogICAgICAgICAgICAgICAgICAgIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0LCBmaW5hbCBTdHJpbmcgaG9zdG5hbWUpIHsKICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWJqZWN0VHlwZTsKICAgICAgICAgICAgICAgIGlmIChpc0lQQWRkcmVzcyhob3N0bmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdWJqZWN0VHlwZSA9IDc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN1YmplY3RUeXBlID0gMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PFN0cmluZz4gc3ViamVjdEFsdExpc3QgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IGMgPSBudWxsOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjID0gY2VydC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIGNwZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgTGlzdDw/PiBhQyA6IGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdDw/PiBsaXN0ID0gYUM7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gKEludGVnZXIpIGxpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBzdWJqZWN0VHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHMgPSAoU3RyaW5nKSBsaXN0LmdldCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmplY3RBbHRMaXN0LmFkZChzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghc3ViamVjdEFsdExpc3QuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gc3ViamVjdEFsdHMgPSBuZXcgU3RyaW5nW3N1YmplY3RBbHRMaXN0LnNpemUoKV07CiAgICAgICAgICAgICAgICAgICAgc3ViamVjdEFsdExpc3QudG9BcnJheShzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YmplY3RBbHRzOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG5vcm1hbGlzZUlQdjZBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGhvc3RuYW1lID09IG51bGwgfHwgIWlzSVB2NkFkZHJlc3MoaG9zdG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZXRBZGRyZXNzLmdldEhvc3RBZGRyZXNzKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVbmtub3duSG9zdEV4Y2VwdGlvbiB1aGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2QWRkcmVzcyhmaW5hbCBTdHJpbmcgaW5wdXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBJUFY2X1NURF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKSB8fCBpc0lQdjZIZXhDb21wcmVzc2VkQWRkcmVzcyhpbnB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2SGV4Q29tcHJlc3NlZEFkZHJlc3MoZmluYWwgU3RyaW5nIGlucHV0KSB7CiAgICAgICAgICAgICAgICBpbnQgY29sb25Db3VudCA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuY2hhckF0KGkpID09ICc6JykgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xvbkNvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICBjb2xvbkNvdW50IDw9IDcgJiYgSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDEyLTU3ODMgOjAzIik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY29tbW9ucy9odHRwY2xpZW50L3Byb3RvY29sL1NTTFByb3RvY29sU29ja2V0RmFjdG9yeS5jcmVhdGVTb2NrZXQoTGphdmEvbGFuZy9TdHJpbmc7SSlMamF2YS9uZXQvU29ja2V0OyIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI0NjRlYjlmZDY4Il0pICAvLyBjb21tb25zLWh0dHBjbGllbnQ6My4xCiAgICAgICAgZXhpdCgpCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsICAgaW1wb3J0OiBbImphdmF4Lm5hbWluZy5JbnZhbGlkTmFtZUV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLk5hbWluZ0V4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmRpcmVjdG9yeS5BdHRyaWJ1dGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5kaXJlY3RvcnkuQXR0cmlidXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmxkYXAuTGRhcE5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5sZGFwLlJkbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xTb2NrZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSU9FeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSW5wdXRTdHJlYW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubmV0LkluZXRBZGRyZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQ29sbGVjdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkl0ZXJhdG9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuTGlua2VkTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Mb2NhbGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwucmVnZXguUGF0dGVybiJdKToKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gQkFEX0NPVU5UUllfMkxEUyA9CiAgICAgICAgICAgICAgICAgICAgeyJhYyIsICJjbyIsICJjb20iLCAiZWQiLCAiZWR1IiwgImdvIiwgImdvdXYiLCAiZ292IiwgImluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImxnIiwgIm5lIiwgIm5ldCIsICJvciIsICJvcmcifTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oMjVbMC01XXwyWzAtNF1cXGR8WzAtMV0/XFxkP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfFswLTFdP1xcZD9cXGQpKXszfSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9TVERfUEFUVEVSTiA9CiAgICAgICAgICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKCJeKD86WzAtOWEtZkEtRl17MSw0fTopezd9WzAtOWEtZkEtRl17MSw0fSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oKD86WzAtOUEtRmEtZl17MSw0fSg/OjpbMC05QS1GYS1mXXsxLDR9KSopPyk6OigoPzpbMC05QS1GYS1mXXsxLDR9KD86OlswLTlBLUZhLWZdezEsNH0pKik/KSQiKTsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGhvc3QgPSBmcmFtZS5sb2FkU3RyaW5nVmFyaWFibGUoMSk7CiAgICAgICAgICAgICAgICBTU0xTb2NrZXQgc3NsU29ja2V0ID0gKFNTTFNvY2tldCkgZnJhbWUubG9hZE9iamVjdE9wZXJhbmQoMCk7CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2ZXJpZnlIb3N0TmFtZShob3N0LCAoU1NMU29ja2V0KSBzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybk9iamVjdChzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbihleCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeUhvc3ROYW1lKFN0cmluZyBob3N0LCBTU0xTb2NrZXQgc3NsKQogICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoaG9zdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaG9zdCB0byB2ZXJpZnkgd2FzIG51bGwiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBzc2wuZ2V0U2Vzc2lvbigpOwogICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gc3NsLmdldElucHV0U3RyZWFtKCk7CiAgICAgICAgICAgICAgICAgICAgaW4uYXZhaWxhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzc2wuc3RhcnRIYW5kc2hha2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBzZXNzaW9uLmdldFBlZXJDZXJ0aWZpY2F0ZXMoKTsKICAgICAgICAgICAgICAgIHZlcmlmeUhvc3ROYW1lKGhvc3QudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5VUyksIChYNTA5Q2VydGlmaWNhdGUpIGNlcnRzWzBdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2ZXJpZnlIb3N0TmFtZShmaW5hbCBTdHJpbmcgaG9zdCwgWDUwOUNlcnRpZmljYXRlIGNlcnQpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBjbnMgPSBnZXRDTnMoY2VydCk7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBzdWJqZWN0QWx0cyA9IGdldFN1YmplY3RBbHRzKGNlcnQsIGhvc3QpOwogICAgICAgICAgICAgICAgdmVyaWZ5SG9zdE5hbWUoaG9zdCwgY25zLCBzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmVyaWZ5SG9zdE5hbWUoZmluYWwgU3RyaW5nIGhvc3QsIFN0cmluZ1tdIGNucywgU3RyaW5nW10gc3ViamVjdEFsdHMpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CgogICAgICAgICAgICAgICAgZmluYWwgTGlua2VkTGlzdDxTdHJpbmc+IG5hbWVzID0gbmV3IExpbmtlZExpc3Q8U3RyaW5nPigpOwogICAgICAgICAgICAgICAgaWYgKGNucyAhPSBudWxsICYmIGNucy5sZW5ndGggPiAwICYmIGNuc1swXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZXMuYWRkKGNuc1swXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIHN1YmplY3RBbHQgOiBzdWJqZWN0QWx0cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5hZGQoc3ViamVjdEFsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKG5hbWVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtc2cgPSAiQ2VydGlmaWNhdGUgZm9yIDwiICsgaG9zdCArICI+IGRvZXNuJ3QgY29udGFpbiBDTiBvciBETlMgc3ViamVjdEFsdCI7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihtc2cpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgaG9zdE5hbWUgPSBub3JtYWxpc2VJUHY2QWRkcmVzcyhob3N0LnRyaW0oKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIGZvciAoZmluYWwgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IG5hbWVzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNuID0gaXQubmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGNuID0gY24udG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiA8Iik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjbik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnPicpOwogICAgICAgICAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiIE9SIik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBwYXJ0cyA9IGNuLnNwbGl0KCJcXC4iKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGRvV2lsZGNhcmQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMubGVuZ3RoID49IDMgJiYgcGFydHNbMF0uZW5kc1dpdGgoIioiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZENvdW50cnlXaWxkY2FyZChjbikgJiYgIWlzSVBBZGRyZXNzKGhvc3QpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoZG9XaWxkY2FyZCkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZmlyc3RwYXJ0ID0gcGFydHNbMF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdHBhcnQubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gZmlyc3RwYXJ0LnN1YnN0cmluZygwLCBmaXJzdHBhcnQubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBzdWZmaXggPSBjbi5zdWJzdHJpbmcoZmlyc3RwYXJ0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBob3N0U3VmZml4ID0gaG9zdE5hbWUuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLnN0YXJ0c1dpdGgocHJlZml4KSAmJiBob3N0U3VmZml4LmVuZHNXaXRoKHN1ZmZpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLmVuZHNXaXRoKGNuLnN1YnN0cmluZygxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGNvdW50RG90cyhob3N0TmFtZSkgPT0gY291bnREb3RzKGNuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gaG9zdE5hbWUuZXF1YWxzKG5vcm1hbGlzZUlQdjZBZGRyZXNzKGNuKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbigiaG9zdG5hbWUgaW4gY2VydGlmaWNhdGUgZGlkbid0IG1hdGNoOiA8IiArIGhvc3QgKyAiPiAhPSIgKyBidWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSVBBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lICE9IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKAogICAgICAgICAgICAgICAgICAgICAgICBJUFY0X1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgSVBWNl9TVERfUEFUVEVSTi5tYXRjaGVyKGhvc3RuYW1lKS5tYXRjaGVzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBJUFY2X0hFWF9DT01QUkVTU0VEX1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50RG90cyhmaW5hbCBTdHJpbmcgZGF0YSkgewogICAgICAgICAgICAgICAgaW50IGRvdHMgPSAwOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5jaGFyQXQoaSkgPT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdHMgKz0gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZG90czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB2YWxpZENvdW50cnlXaWxkY2FyZChmaW5hbCBTdHJpbmcgY24pIHsKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHBhcnRzID0gY24uc3BsaXQoIlxcLiIpOwogICAgICAgICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAzIHx8IHBhcnRzWzJdLmxlbmd0aCgpICE9IDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuYmluYXJ5U2VhcmNoKEJBRF9DT1VOVFJZXzJMRFMsIHBhcnRzWzFdKSA8IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldENOcyhmaW5hbCBYNTA5Q2VydGlmaWNhdGUgY2VydCkgewogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN1YmplY3RQcmluY2lwYWwgPSBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dHJhY3RDTnMoc3ViamVjdFByaW5jaXBhbCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZXh0cmFjdENOcyhmaW5hbCBTdHJpbmcgc3ViamVjdFByaW5jaXBhbCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdFByaW5jaXBhbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gY25zID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIExkYXBOYW1lIHN1YmplY3RETiA9IG5ldyBMZGFwTmFtZShzdWJqZWN0UHJpbmNpcGFsKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFJkbj4gcmRucyA9IHN1YmplY3RETi5nZXRSZG5zKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHJkbnMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUmRuIHJkcyA9IHJkbnMuZ2V0KGkpOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSByZHMudG9BdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEF0dHJpYnV0ZSBjbiA9IGF0dHJpYnV0ZXMuZ2V0KCJjbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBjbi5nZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbnMuYWRkKHZhbHVlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChOYW1pbmdFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkTmFtZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihzdWJqZWN0UHJpbmNpcGFsICsgIiBpcyBub3QgYSB2YWxpZCBYNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNucy5pc0VtcHR5KCkgPyBudWxsIDogY25zLnRvQXJyYXkobmV3IFN0cmluZ1swXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldFN1YmplY3RBbHRzKAogICAgICAgICAgICAgICAgICAgIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0LCBmaW5hbCBTdHJpbmcgaG9zdG5hbWUpIHsKICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWJqZWN0VHlwZTsKICAgICAgICAgICAgICAgIGlmIChpc0lQQWRkcmVzcyhob3N0bmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdWJqZWN0VHlwZSA9IDc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN1YmplY3RUeXBlID0gMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PFN0cmluZz4gc3ViamVjdEFsdExpc3QgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IGMgPSBudWxsOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjID0gY2VydC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIGNwZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgTGlzdDw/PiBhQyA6IGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdDw/PiBsaXN0ID0gYUM7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gKEludGVnZXIpIGxpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBzdWJqZWN0VHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHMgPSAoU3RyaW5nKSBsaXN0LmdldCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmplY3RBbHRMaXN0LmFkZChzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghc3ViamVjdEFsdExpc3QuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gc3ViamVjdEFsdHMgPSBuZXcgU3RyaW5nW3N1YmplY3RBbHRMaXN0LnNpemUoKV07CiAgICAgICAgICAgICAgICAgICAgc3ViamVjdEFsdExpc3QudG9BcnJheShzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YmplY3RBbHRzOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG5vcm1hbGlzZUlQdjZBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGhvc3RuYW1lID09IG51bGwgfHwgIWlzSVB2NkFkZHJlc3MoaG9zdG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZXRBZGRyZXNzLmdldEhvc3RBZGRyZXNzKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVbmtub3duSG9zdEV4Y2VwdGlvbiB1aGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2QWRkcmVzcyhmaW5hbCBTdHJpbmcgaW5wdXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBJUFY2X1NURF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKSB8fCBpc0lQdjZIZXhDb21wcmVzc2VkQWRkcmVzcyhpbnB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2SGV4Q29tcHJlc3NlZEFkZHJlc3MoZmluYWwgU3RyaW5nIGlucHV0KSB7CiAgICAgICAgICAgICAgICBpbnQgY29sb25Db3VudCA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuY2hhckF0KGkpID09ICc6JykgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xvbkNvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICBjb2xvbkNvdW50IDw9IDcgJiYgSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgogICAgcGF0Y2goIkNWRS0yMDEyLTU3ODMgOjA0Iik6CiAgICAgICAgZnVuY3Rpb24oIm9yZy9hcGFjaGUvY29tbW9ucy9odHRwY2xpZW50L3Byb3RvY29sL1NTTFByb3RvY29sU29ja2V0RmFjdG9yeS5jcmVhdGVTb2NrZXQoTGphdmEvbmV0L1NvY2tldDtMamF2YS9sYW5nL1N0cmluZztJWilMamF2YS9uZXQvU29ja2V0OyIsCiAgICAgICAgICAgIGNoZWNrc3VtczogWyI0NjRlYjlmZDY4Il0pICAvLyBjb21tb25zLWh0dHBjbGllbnQ6My4xCiAgICAgICAgZXhpdCgpCgogICAgICAgIGNvZGUobGFuZ3VhZ2U6IGphdmEsICAgaW1wb3J0OiBbImphdmF4Lm5hbWluZy5JbnZhbGlkTmFtZUV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLk5hbWluZ0V4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmRpcmVjdG9yeS5BdHRyaWJ1dGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5kaXJlY3RvcnkuQXR0cmlidXRlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmFtaW5nLmxkYXAuTGRhcE5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5hbWluZy5sZGFwLlJkbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xFeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmF4Lm5ldC5zc2wuU1NMU2Vzc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YXgubmV0LnNzbC5TU0xTb2NrZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSU9FeGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEuaW8uSW5wdXRTdHJlYW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEubmV0LkluZXRBZGRyZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLm5ldC5Vbmtub3duSG9zdEV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS5zZWN1cml0eS5jZXJ0LkNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5LmNlcnQuWDUwOUNlcnRpZmljYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlMaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQXJyYXlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuQ29sbGVjdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkl0ZXJhdG9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwuTGlua2VkTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiamF2YS51dGlsLkxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Mb2NhbGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqYXZhLnV0aWwucmVnZXguUGF0dGVybiJdKToKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gQkFEX0NPVU5UUllfMkxEUyA9CiAgICAgICAgICAgICAgICAgICAgeyJhYyIsICJjbyIsICJjb20iLCAiZWQiLCAiZWR1IiwgImdvIiwgImdvdXYiLCAiZ292IiwgImluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImxnIiwgIm5lIiwgIm5ldCIsICJvciIsICJvcmcifTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oMjVbMC01XXwyWzAtNF1cXGR8WzAtMV0/XFxkP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfFswLTFdP1xcZD9cXGQpKXszfSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9TVERfUEFUVEVSTiA9CiAgICAgICAgICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKCJeKD86WzAtOWEtZkEtRl17MSw0fTopezd9WzAtOWEtZkEtRl17MSw0fSQiKTsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOID0KICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIl4oKD86WzAtOUEtRmEtZl17MSw0fSg/OjpbMC05QS1GYS1mXXsxLDR9KSopPyk6OigoPzpbMC05QS1GYS1mXXsxLDR9KD86OlswLTlBLUZhLWZdezEsNH0pKik/KSQiKTsKCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHBhdGNoKEphdmFGcmFtZSBmcmFtZSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGhvc3QgPSBmcmFtZS5sb2FkU3RyaW5nVmFyaWFibGUoMSk7CiAgICAgICAgICAgICAgICBTU0xTb2NrZXQgc3NsU29ja2V0ID0gKFNTTFNvY2tldCkgZnJhbWUubG9hZE9iamVjdE9wZXJhbmQoMCk7CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2ZXJpZnlIb3N0TmFtZShob3N0LCAoU1NMU29ja2V0KSBzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgICAgIGZyYW1lLnJldHVybk9iamVjdChzc2xTb2NrZXQpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICBmcmFtZS5yYWlzZUV4Y2VwdGlvbihleCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgZnJhbWUucmFpc2VFeGNlcHRpb24oZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZlcmlmeUhvc3ROYW1lKFN0cmluZyBob3N0LCBTU0xTb2NrZXQgc3NsKQogICAgICAgICAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoaG9zdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaG9zdCB0byB2ZXJpZnkgd2FzIG51bGwiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBTU0xTZXNzaW9uIHNlc3Npb24gPSBzc2wuZ2V0U2Vzc2lvbigpOwogICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIElucHV0U3RyZWFtIGluID0gc3NsLmdldElucHV0U3RyZWFtKCk7CiAgICAgICAgICAgICAgICAgICAgaW4uYXZhaWxhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzc2wuc3RhcnRIYW5kc2hha2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9IHNzbC5nZXRTZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIENlcnRpZmljYXRlW10gY2VydHMgPSBzZXNzaW9uLmdldFBlZXJDZXJ0aWZpY2F0ZXMoKTsKICAgICAgICAgICAgICAgIHZlcmlmeUhvc3ROYW1lKGhvc3QudHJpbSgpLnRvTG93ZXJDYXNlKExvY2FsZS5VUyksIChYNTA5Q2VydGlmaWNhdGUpIGNlcnRzWzBdKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2ZXJpZnlIb3N0TmFtZShmaW5hbCBTdHJpbmcgaG9zdCwgWDUwOUNlcnRpZmljYXRlIGNlcnQpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBjbnMgPSBnZXRDTnMoY2VydCk7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBzdWJqZWN0QWx0cyA9IGdldFN1YmplY3RBbHRzKGNlcnQsIGhvc3QpOwogICAgICAgICAgICAgICAgdmVyaWZ5SG9zdE5hbWUoaG9zdCwgY25zLCBzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmVyaWZ5SG9zdE5hbWUoZmluYWwgU3RyaW5nIGhvc3QsIFN0cmluZ1tdIGNucywgU3RyaW5nW10gc3ViamVjdEFsdHMpCiAgICAgICAgICAgICAgICAgICAgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CgogICAgICAgICAgICAgICAgZmluYWwgTGlua2VkTGlzdDxTdHJpbmc+IG5hbWVzID0gbmV3IExpbmtlZExpc3Q8U3RyaW5nPigpOwogICAgICAgICAgICAgICAgaWYgKGNucyAhPSBudWxsICYmIGNucy5sZW5ndGggPiAwICYmIGNuc1swXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZXMuYWRkKGNuc1swXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgU3RyaW5nIHN1YmplY3RBbHQgOiBzdWJqZWN0QWx0cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ViamVjdEFsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5hZGQoc3ViamVjdEFsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKG5hbWVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBtc2cgPSAiQ2VydGlmaWNhdGUgZm9yIDwiICsgaG9zdCArICI+IGRvZXNuJ3QgY29udGFpbiBDTiBvciBETlMgc3ViamVjdEFsdCI7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihtc2cpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgaG9zdE5hbWUgPSBub3JtYWxpc2VJUHY2QWRkcmVzcyhob3N0LnRyaW0oKS50b0xvd2VyQ2FzZShMb2NhbGUuRU5HTElTSCkpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBtYXRjaCA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIGZvciAoZmluYWwgSXRlcmF0b3I8U3RyaW5nPiBpdCA9IG5hbWVzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTsgKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNuID0gaXQubmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGNuID0gY24udG9Mb3dlckNhc2UoTG9jYWxlLkVOR0xJU0gpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiA8Iik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjbik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnPicpOwogICAgICAgICAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiIE9SIik7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBwYXJ0cyA9IGNuLnNwbGl0KCJcXC4iKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIGRvV2lsZGNhcmQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMubGVuZ3RoID49IDMgJiYgcGFydHNbMF0uZW5kc1dpdGgoIioiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZENvdW50cnlXaWxkY2FyZChjbikgJiYgIWlzSVBBZGRyZXNzKGhvc3QpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoZG9XaWxkY2FyZCkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgZmlyc3RwYXJ0ID0gcGFydHNbMF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdHBhcnQubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJlZml4ID0gZmlyc3RwYXJ0LnN1YnN0cmluZygwLCBmaXJzdHBhcnQubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBzdWZmaXggPSBjbi5zdWJzdHJpbmcoZmlyc3RwYXJ0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBob3N0U3VmZml4ID0gaG9zdE5hbWUuc3Vic3RyaW5nKHByZWZpeC5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLnN0YXJ0c1dpdGgocHJlZml4KSAmJiBob3N0U3VmZml4LmVuZHNXaXRoKHN1ZmZpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGhvc3ROYW1lLmVuZHNXaXRoKGNuLnN1YnN0cmluZygxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGNvdW50RG90cyhob3N0TmFtZSkgPT0gY291bnREb3RzKGNuKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoID0gaG9zdE5hbWUuZXF1YWxzKG5vcm1hbGlzZUlQdjZBZGRyZXNzKGNuKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbigiaG9zdG5hbWUgaW4gY2VydGlmaWNhdGUgZGlkbid0IG1hdGNoOiA8IiArIGhvc3QgKyAiPiAhPSIgKyBidWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzSVBBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lICE9IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKAogICAgICAgICAgICAgICAgICAgICAgICBJUFY0X1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgSVBWNl9TVERfUEFUVEVSTi5tYXRjaGVyKGhvc3RuYW1lKS5tYXRjaGVzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBJUFY2X0hFWF9DT01QUkVTU0VEX1BBVFRFUk4ubWF0Y2hlcihob3N0bmFtZSkubWF0Y2hlcygpCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGNvdW50RG90cyhmaW5hbCBTdHJpbmcgZGF0YSkgewogICAgICAgICAgICAgICAgaW50IGRvdHMgPSAwOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5jaGFyQXQoaSkgPT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdHMgKz0gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZG90czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB2YWxpZENvdW50cnlXaWxkY2FyZChmaW5hbCBTdHJpbmcgY24pIHsKICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIHBhcnRzID0gY24uc3BsaXQoIlxcLiIpOwogICAgICAgICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPSAzIHx8IHBhcnRzWzJdLmxlbmd0aCgpICE9IDIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBBcnJheXMuYmluYXJ5U2VhcmNoKEJBRF9DT1VOVFJZXzJMRFMsIHBhcnRzWzFdKSA8IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldENOcyhmaW5hbCBYNTA5Q2VydGlmaWNhdGUgY2VydCkgewogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHN1YmplY3RQcmluY2lwYWwgPSBjZXJ0LmdldFN1YmplY3RYNTAwUHJpbmNpcGFsKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dHJhY3RDTnMoc3ViamVjdFByaW5jaXBhbCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChTU0xFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nW10gZXh0cmFjdENOcyhmaW5hbCBTdHJpbmcgc3ViamVjdFByaW5jaXBhbCkgdGhyb3dzIFNTTEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdFByaW5jaXBhbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gY25zID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZpbmFsIExkYXBOYW1lIHN1YmplY3RETiA9IG5ldyBMZGFwTmFtZShzdWJqZWN0UHJpbmNpcGFsKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFJkbj4gcmRucyA9IHN1YmplY3RETi5nZXRSZG5zKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IHJkbnMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgUmRuIHJkcyA9IHJkbnMuZ2V0KGkpOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSByZHMudG9BdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEF0dHJpYnV0ZSBjbiA9IGF0dHJpYnV0ZXMuZ2V0KCJjbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBjbi5nZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbnMuYWRkKHZhbHVlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChOYW1pbmdFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkTmFtZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNTTEV4Y2VwdGlvbihzdWJqZWN0UHJpbmNpcGFsICsgIiBpcyBub3QgYSB2YWxpZCBYNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNucy5pc0VtcHR5KCkgPyBudWxsIDogY25zLnRvQXJyYXkobmV3IFN0cmluZ1swXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldFN1YmplY3RBbHRzKAogICAgICAgICAgICAgICAgICAgIGZpbmFsIFg1MDlDZXJ0aWZpY2F0ZSBjZXJ0LCBmaW5hbCBTdHJpbmcgaG9zdG5hbWUpIHsKICAgICAgICAgICAgICAgIGZpbmFsIGludCBzdWJqZWN0VHlwZTsKICAgICAgICAgICAgICAgIGlmIChpc0lQQWRkcmVzcyhob3N0bmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdWJqZWN0VHlwZSA9IDc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN1YmplY3RUeXBlID0gMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmaW5hbCBMaW5rZWRMaXN0PFN0cmluZz4gc3ViamVjdEFsdExpc3QgPSBuZXcgTGlua2VkTGlzdDxTdHJpbmc+KCk7CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPExpc3Q8Pz4+IGMgPSBudWxsOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjID0gY2VydC5nZXRTdWJqZWN0QWx0ZXJuYXRpdmVOYW1lcygpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZmluYWwgQ2VydGlmaWNhdGVQYXJzaW5nRXhjZXB0aW9uIGNwZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoZmluYWwgTGlzdDw/PiBhQyA6IGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdDw/PiBsaXN0ID0gYUM7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlID0gKEludGVnZXIpIGxpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBzdWJqZWN0VHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHMgPSAoU3RyaW5nKSBsaXN0LmdldCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmplY3RBbHRMaXN0LmFkZChzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghc3ViamVjdEFsdExpc3QuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gc3ViamVjdEFsdHMgPSBuZXcgU3RyaW5nW3N1YmplY3RBbHRMaXN0LnNpemUoKV07CiAgICAgICAgICAgICAgICAgICAgc3ViamVjdEFsdExpc3QudG9BcnJheShzdWJqZWN0QWx0cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YmplY3RBbHRzOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG5vcm1hbGlzZUlQdjZBZGRyZXNzKGZpbmFsIFN0cmluZyBob3N0bmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGhvc3RuYW1lID09IG51bGwgfHwgIWlzSVB2NkFkZHJlc3MoaG9zdG5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RuYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBJbmV0QWRkcmVzcyBpbmV0QWRkcmVzcyA9IEluZXRBZGRyZXNzLmdldEJ5TmFtZShob3N0bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZXRBZGRyZXNzLmdldEhvc3RBZGRyZXNzKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChmaW5hbCBVbmtub3duSG9zdEV4Y2VwdGlvbiB1aGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaG9zdG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2QWRkcmVzcyhmaW5hbCBTdHJpbmcgaW5wdXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBJUFY2X1NURF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKSB8fCBpc0lQdjZIZXhDb21wcmVzc2VkQWRkcmVzcyhpbnB1dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNJUHY2SGV4Q29tcHJlc3NlZEFkZHJlc3MoZmluYWwgU3RyaW5nIGlucHV0KSB7CiAgICAgICAgICAgICAgICBpbnQgY29sb25Db3VudCA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuY2hhckF0KGkpID09ICc6JykgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xvbkNvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICBjb2xvbkNvdW50IDw9IDcgJiYgSVBWNl9IRVhfQ09NUFJFU1NFRF9QQVRURVJOLm1hdGNoZXIoaW5wdXQpLm1hdGNoZXMoKTsKICAgICAgICAgICAgfQogICAgICAgIGVuZGNvZGUKICAgIGVuZHBhdGNoCgplbmRhcHAK"}]},"assessment":{"record":{"state":"active"},"protection":{"level":"full","mechanisms":["patch-rule"]},"action":{"state":"available","type":"patch-rule"},"review":{"state":"human","basis":"armr-file"}},"signals":{"hasPOC":false,"pocCount":0},"kev":{"inKEV":false},"epss":{"available":true,"score":0.09254,"percentile":0.95074},"ssvc":{"available":false},"lastActivity":"2026-03-04T16:48:46Z"}