LyoqIEBuYW1lIHVpbWF0ZXN0X2xhbmd1YWdlLmNwcAoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQogKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQogKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCiAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCiAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQogKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucwogKiB1bmRlciB0aGUgTGljZW5zZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiAgICAgICBJbmNsdWRlIGRlcGVuZGVuY2llcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojaW5jbHVkZSAidWltYS9hc3NlcnRtc2cuaCIKI2luY2x1ZGUgInVpbWEvY29uc29sZXVpLmhwcCIKCiNpbmNsdWRlICJ1aW1hL2Z0b29scy5ocHAiCiNpbmNsdWRlICJ1aW1hL2Vycl9pZHMuaCIKI2luY2x1ZGUgInVpbWEvc3RydG9vbHMuaHBwIgojaW5jbHVkZSAidWltYS9zdHJjb252ZXJ0LmhwcCIKI2luY2x1ZGUgInVpbWEvbGFuZ3VhZ2UuaHBwIgoKdXNpbmcgbmFtZXNwYWNlIHVpbWE7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiAgICAgICBDb25zdGFudHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBNQUlOX1RJVExFICAgICAgICAgICAgX1RFWFQoIkxhbmd1YWdlIENsYXNzIFVuaXQgVGVzdGVyIikKCmNvbnN0IFRDSEFSICogZ3Nfc3pVc2FnZSA9IF9URVhUKCJcdFstLXZlcmJvc2VdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgpzdGF0aWMgY29uc3QgVENIQVIgKiAgICAgICAgICBnc19zekhlbHAgPSBfVEVYVCgiXHQiCiAgICAiUGVyZm9ybSBzb21lIHRlc3Qgd2l0aCB0aGUgTGFuZ3VhZ2UgY2xhc3MuXG5cdCIKICAgICJcblx0IgogICAgIlstLXZlcmJvc2VdICAgICAgICAgICAgICAgICB2ZXJib3NlIGRpc3BsYXkgbW9kZVxuXHQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCnN0YXRpYyBib29sICAgICAgICAgICAgICAgICAgIGdzX2JWZXJib3NlID0gZmFsc2U7CgojZGVmaW5lIEFTU0VSVCh4KSBpZiAoISh4KSkgeyBjZXJyIDw8ICJGQUlMRUQgQVNTRVJUSU9OICciIDw8IFVJTUFfU1RSSU5HSUZZKHgpIFwKIDw8ICInIGluICIgPDwgX19GSUxFX18gPDwgIiBhdCBsaW5lICIgPDwgX19MSU5FX18gPDwgZW5kbDsgZXhpdCgxKTsgfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogICAgICAgVHlwZXMgLyBDbGFzc2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgICAgIEltcGxlbWVudGF0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgp2b2lkIG1haW5EaXNwbGF5KHV0aWw6OkNvbnNvbGVVSSAmIHJjbENvbnNvbGUsIExhbmd1YWdlICYgcmNsTGFuZykKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KewogIGNoYXIgICBzMVs1MF07CiAgc3RyaW5nIHN0cjI7CiAgaW50IGlkID0gcmNsTGFuZy5hc051bWJlcigpOwogIHNwcmludGYoczEsIjB4JTA4eCAlZCIsaWQsaWQpOwogIGlmIChyY2xMYW5nLmhhc0xhbmd1YWdlKCkpCiAgICBzdHIyID0gcmNsTGFuZy5nZXRMYW5ndWFnZUNvZGUoKTsKICBlbHNlCiAgICBzdHIyID0gIioqIjsKICBpZiAoIHJjbExhbmcuaGFzVGVycml0b3J5KCkgKQogICAgc3RyMiArPSAiIC0gIiArIChzdHJpbmcpcmNsTGFuZy5nZXRUZXJyaXRvcnlDb2RlKCk7CgogIHJjbENvbnNvbGUuZm9ybWF0KHMxLCBzdHIyLmNfc3RyKCkpOwp9CgovLyBEaXNwbGF5IGFuIGFycmF5IG9mIFVuaWNvZGUgY2hhcmFjdGVycwp2b2lkIHVjaGFyRGlzcGxheSh1dGlsOjpDb25zb2xlVUkgJiByY2xDb25zb2xlLCBjaGFyKiB0YWcsIGNvbnN0IFVDaGFyKiB1Y2J1ZmYsIGludCBsZW4pIHsKICBjaGFyIGNidWZbMTAyNF07CiAgY2hhciogcyA9IGNidWY7CiAgKnMrKyA9ICdcIic7CiAgZm9yICggaW50IGkgPSAwOyBpIDwgbGVuOyArK2kgKSB7CiAgICBpZiAodWNidWZmW2ldIDwgMTI4KQogICAgICBzICs9IHNwcmludGYocywiJWMiLHVjYnVmZltpXSk7CiAgICBlbHNlCiAgICAgIHMgKz0gc3ByaW50ZihzLCJcXHUlMDR4Iix1Y2J1ZmZbaV0pOwogIH0KICAqcysrID0gJ1wiJzsKICAqcyA9ICdcMCc7CiAgcmNsQ29uc29sZS5mb3JtYXQodGFnLCBjYnVmKTsKfQoKClR5RXJyb3JJZAptYWluVGVzdCgKICB1dGlsOjpDb25zb2xlVUkgJiAgICAgICByY2xDb25zb2xlLAogIGJvb2wgICAgICAgICAgICAgICAgICBiVmVyYm9zZQopIHsKICBUeUVycm9ySWQgICAgICAgICAgICAgICBlbkVycm9ySWQgPSBVSU1BX0VSUl9OT05FOwoKICByY2xDb25zb2xlLmZvcm1hdEhlYWRlcihfVEVYVCgiUGVyZm9ybWluZyBsYW5ndWFnZSB0ZXN0czoiKSk7CgogIExhbmd1YWdlIGNsVGVzdExhbmcxKCJlbi1VUyIpOwogIExhbmd1YWdlIGNsVGVzdExhbmcyKCJFbl91cyIpOwogIExhbmd1YWdlIGNsVGVzdExhbmczKCJlbi1HQiIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc0KCJlbiIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc1KCJmciIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc2OwoKICBMYW5ndWFnZSBjbEludmFsaWQxKCJmb28iKTsKICBMYW5ndWFnZSBjbEludmFsaWQyKCJmdS1iYXIiKTsKICBMYW5ndWFnZSBjbEludmFsaWQzKCJmMC1iYSIpOwogIExhbmd1YWdlIGNsSW52YWxpZDQoImVuIHVzIik7CiAgTGFuZ3VhZ2UgY2xJbnZhbGlkNSgi6XMtY2EiKTsKCiAgQVNTRVJUKCAhY2xJbnZhbGlkMS5pc1ZhbGlkKCkpOwogIEFTU0VSVCggIWNsSW52YWxpZDIuaXNWYWxpZCgpKTsKICBBU1NFUlQoICFjbEludmFsaWQzLmlzVmFsaWQoKSk7CiAgQVNTRVJUKCAhY2xJbnZhbGlkNC5pc1ZhbGlkKCkpOwogIEFTU0VSVCggIWNsSW52YWxpZDUuaXNWYWxpZCgpKTsKICBBU1NFUlQoIGNsVGVzdExhbmcxLmlzVmFsaWQoKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMy5oYXNUZXJyaXRvcnkoKSk7CiAgQVNTRVJUKCFjbFRlc3RMYW5nNC5oYXNUZXJyaXRvcnkoKSk7CgogIG1haW5EaXNwbGF5ICggcmNsQ29uc29sZSwgY2xUZXN0TGFuZzEgKTsKICBtYWluRGlzcGxheSAoIHJjbENvbnNvbGUsIGNsVGVzdExhbmcyICk7CiAgbWFpbkRpc3BsYXkgKCByY2xDb25zb2xlLCBjbFRlc3RMYW5nMyApOwogIG1haW5EaXNwbGF5ICggcmNsQ29uc29sZSwgY2xUZXN0TGFuZzQgKTsKICBtYWluRGlzcGxheSAoIHJjbENvbnNvbGUsIGNsVGVzdExhbmc1ICk7CiAgbWFpbkRpc3BsYXkgKCByY2xDb25zb2xlLCBjbFRlc3RMYW5nNiApOwoKICByY2xDb25zb2xlLmZvcm1hdCgiY29uc3RydWN0IHRlc3RzIiwgIk9LIik7CgogIC8vIFRlc3QgdGhlIHByZWZpeC1tYXRjaCBjb25jZXB0LCBlLmcuICJlbiIgbWF0Y2hlcyAiZW4tVVMiCiAgQVNTRVJUKCFjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmczKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmcyKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc0KSk7CiAgQVNTRVJUKCFjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc1KSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc2KSk7CgogIHJjbENvbnNvbGUuZm9ybWF0KCJtYXRjaCB0ZXN0cyIsICJPSyIpOwoKICAvLyBUZXN0IHRoZSBjb21wYXJpc29uIG9wZXJhdG9ycwogIEFTU0VSVChjbFRlc3RMYW5nMSA9PSBjbFRlc3RMYW5nMik7CiAgQVNTRVJUKGNsVGVzdExhbmcxICE9IGNsVGVzdExhbmczKTsKICBBU1NFUlQoY2xUZXN0TGFuZzQgPCBjbFRlc3RMYW5nMyk7CiAgQVNTRVJUKGNsVGVzdExhbmczIDwgY2xUZXN0TGFuZzEpOwoKICByY2xDb25zb2xlLmZvcm1hdCgiY29tcGFyaXNvbiB0ZXN0cyIsICJPSyIpOwoKICAvLyBUZXN0IHRoZSBjb25zdHJ1Y3Rpb24gZnJvbSB0aGUgbnVtZXJpYyBmb3JtCiAgTGFuZ3VhZ2UgY2xUZXN0TGFuZzcoY2xUZXN0TGFuZzEuYXNOdW1iZXIoKSk7CiAgQVNTRVJUKGNsVGVzdExhbmc3ID09IGNsVGVzdExhbmcxKTsKCiAgLy8gVGVzdCB0aGUgY29uc3RydWN0aW9uIG9mIG9uZSBmcm9tIGp1c3QgdGhlIGxhbmd1YWdlIHBhcnQgb2YgYW5vdGhlcgogIExhbmd1YWdlIGNsVGVzdExhbmc4KGNsVGVzdExhbmcxLmdldExhbmd1YWdlQ29kZSgpKTsKICBBU1NFUlQoY2xUZXN0TGFuZzEubWF0Y2hlcyhjbFRlc3RMYW5nOCkpOwogIEFTU0VSVChjbFRlc3RMYW5nOCA9PSBjbFRlc3RMYW5nNCk7CgogIC8vIFNhbWUgdGVzdCBidXQgY29uc3RydWN0IGZyb20gdGhlIG51bWVyaWMgZm9ybSBvZiB0aGUgbGFuZ3VhZ2UKICBMYW5ndWFnZSBjbFRlc3RMYW5nOShjbFRlc3RMYW5nMS5nZXRMYW5ndWFnZSgpKTsKICBBU1NFUlQoY2xUZXN0TGFuZzEubWF0Y2hlcyhjbFRlc3RMYW5nOSkpOwogIEFTU0VSVChjbFRlc3RMYW5nOSA9PSBjbFRlc3RMYW5nNCk7CgogIHJjbENvbnNvbGUuZm9ybWF0KCJudW1lcmljIGNvbnN0cnVjdCB0ZXN0cyIsICJPSyIpOwoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFRlc3Qgc29tZSBVbmljb2RlU3RyaW5nUmVmIGNvcHkgZnVuY3Rpb25zCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgaW50IGxlbjsKICBVQ2hhciB1Y2J1ZlsxMDBdOwogIFVFcnJvckNvZGUgZXJyOwogIHN0ZDo6c3RyaW5nIHNzOwoKICBjaGFyKiBjc3RyID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ5enl6IDAxMjM0NTY3ODkiOwogIFVuaWNvZGVTdHJpbmcgdXMxKGNzdHIpOwogIFVuaWNvZGVTdHJpbmdSZWYgdXNyKHVzMSk7CgogIC8vIGludG8gc3RkOjpzdHJpbmcgd2l0aCBkZWZhdWx0IGNvbnZlcnNpb24KICB1c3IuZXh0cmFjdChzcyk7CiAgaWYgKGJWZXJib3NlKSByY2xDb25zb2xlLmZvcm1hdCgiZXh0cmFjdCB0byBzdGQ6OnN0cmluZyIsc3MuY19zdHIoKSk7CiAgQVNTRVJUIChzdHJsZW4oY3N0cikgPT0gc3MubGVuZ3RoKCkpOwoKICAvLyBzdWJzdHJpbmcgaW50byBVbmljb2RlU3RyaW5nCiAgVW5pY29kZVN0cmluZyB1czIoImluaXRpYWxWYWx1ZSIpOwogIFVuaWNvZGVTdHJpbmcgdXMzKCJ6IDAiKTsKICB1c3IuZXh0cmFjdEJldHdlZW4oMjUsMjgsdXMyKTsgICAgICAgICAgICAgICAvLyBTaG91bGQgYmUgInogMCIKICBpZiAoYlZlcmJvc2UpIHVjaGFyRGlzcGxheShyY2xDb25zb2xlLCAiZXh0cmFjdEJldHdlZW4gaW50byBVQ2hhciBidWZmZXIiLCB1czIuZ2V0QnVmZmVyKCksIHVzMi5sZW5ndGgoKSk7CiAgQVNTRVJUICggdXMyID09IHVzMyApOwoKICAvLyBzdWJzdHJpbmcgaW50byBVQ2hhciBidWZmZXIKICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgbGVuID0gdXMxLmV4dHJhY3QodWNidWYsMTAwLGVycik7ICAgICAgICAgLy8gUHJlLWZpbGwgYnVmZmVyCgogIHVzci5leHRyYWN0KDI3LDMsdWNidWYsNSk7ICAgICAgICAgICAgICAgIC8vIGV4dHJhY3QgcGFydCBvZiBVU1IgaW50byB0aGUgYnVmZmVyCiAgVW5pY29kZVN0cmluZyB1czQoImFiY2RlMDEyaWprbG0iKTsKICBpZiAoYlZlcmJvc2UpIHVjaGFyRGlzcGxheShyY2xDb25zb2xlLCAiZXh0cmFjdCBpbnRvIFVDaGFyIGJ1ZmZlciIsIHVjYnVmLCAxMyk7CiAgQVNTRVJUICggdXM0LmNvbXBhcmUodWNidWYsMTMpID09IDAgKTsKCiAgLy8gZXh0cmFjdCBpbnRvIHRvby1zbWFsbCBVQ2hhciBidWZmZXIKICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgbGVuID0gdXNyLmV4dHJhY3QodWNidWYsMzYsZXJyKTsgICAgICAgICAgICAgICAgLy8gdG9vIHNtYWxsCiAgQVNTRVJUKGVyciA9PSBVX0JVRkZFUl9PVkVSRkxPV19FUlJPUik7CiAgZXJyID0gVV9aRVJPX0VSUk9SOwogIGxlbiA9IHVzci5leHRyYWN0KHVjYnVmLDM3LGVycik7ICAgICAgICAgICAgICAgIC8vIG5vIHJvb20gZm9yIGZpbmFsIDAKICBBU1NFUlQoZXJyID09IFVfU1RSSU5HX05PVF9URVJNSU5BVEVEX1dBUk5JTkcpOwogIGVyciA9IFVfWkVST19FUlJPUjsKICBsZW4gPSB1c3IuZXh0cmFjdCh1Y2J1ZiwzOCxlcnIpOyAgICAgICAgICAgICAgICAvLyBqdXN0IHJpZ2h0CiAgQVNTRVJUKGVyciA9PSBVX1pFUk9fRVJST1IpOwogIGlmIChiVmVyYm9zZSkgdWNoYXJEaXNwbGF5KHJjbENvbnNvbGUsICJleHRyYWN0IGludG8gVUNoYXIgYnVmZmVyIiwgdWNidWYsIGxlbik7CiAgQVNTRVJUICggdXMxLmNvbXBhcmUodWNidWYsbGVuKSA9PSAwICk7CgoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFRlc3Qgc29tZSBVbmljb2RlU3RyaW5nUmVmIGNvbnZlcnNpb24gZnVuY3Rpb25zCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8gQ3JlYXRlIGEgVW5pY29kZVN0cmluZyB3aXRoIDggQXJhYmljIGNoYXJhY3RlcnMgZm9sbG93ZWQgYnkgYSBibGFuay4KICAvLyBBbHNvIGdldCB0aGUgdXRmLTggZm9ybSBhcyBhIHJlZmVyZW5jZQogIFVDaGFyIHVjW10gPSB7MHgwNjJjLCAweDA2NDgsIDB4MDYzMSwgMHgwNjJjLCAweDA2MmEsIDB4MDYyNywgMHgwNjQ4LCAweDA2NDYsIDB4MDAyMH07CiAgaW50IG5jaGFycyA9IHNpemVvZih1Yykvc2l6ZW9mKFVDaGFyKTsKICBVbmljb2RlU3RyaW5nIFVTMSh1YywgbmNoYXJzKTsKICBjaGFyIHU4WzEwMF07CiAgVVMxLmV4dHJhY3QoMCwgVVMxLmxlbmd0aCgpLCB1OCwgMTAwLCAidXRmLTgiKTsKCiAgLy8gQ3JlYXRlIHR3byBVbmljb2RlU3RyaW5nUmVmIGFuZCBjb21wYXJlIHRoZW0KICBVbmljb2RlU3RyaW5nUmVmIFVTUjEoVVMxKTsKICBVbmljb2RlU3RyaW5nUmVmIFVTUjIodWMsIG5jaGFycyk7CiAgaWYgKGJWZXJib3NlKSB1Y2hhckRpc3BsYXkocmNsQ29uc29sZSwgIkNvbnN0cnVjdCBmcm9tIFVuaWNvZGVTdHJpbmciLCBVU1IxLmdldEJ1ZmZlcigpLCBVU1IxLmxlbmd0aCgpKTsKICBpZiAoYlZlcmJvc2UpIHVjaGFyRGlzcGxheShyY2xDb25zb2xlLCAiQ29uc3RydWN0IGZyb20gVUNoYXIgYXJyYXkiLCAgIFVTUjIuZ2V0QnVmZmVyKCksIFVTUjIubGVuZ3RoKCkpOwogIEFTU0VSVCAoIFVTUjEuY29tcGFyZShVUzEpID09IDAgKTsKCiAgLy8gRXh0cmFjdCBpbnRvIGEgYnVmZmVyIHVzaW5nIHRoZSB1dGYtOCBjb252ZXJ0ZXIKICBjaGFyIGNidWZbMTAwXTsKICAqY2J1ZiA9IDA7CiAgbGVuID0gVVNSMS5leHRyYWN0KDAsIFVTUjEubGVuZ3RoKCksIGNidWYsIDEwMCwgInV0Zi04Iik7CiAgaWYgKGJWZXJib3NlKSByY2xDb25zb2xlLmZvcm1hdCgiZXh0cmFjdCBpbnRvIGJ1ZmZlciB3aXRoIHV0Zi04IGNvbnZlcnRlciIsIGNidWYpOwogIEFTU0VSVCAoIHN0cmNtcCh1OCxjYnVmKSA9PSAwICk7CgogIC8vIEV4dHJhY3QgaW50byBhIHN0cmluZyB1c2luZyB0aGUgdXRmLTggY29udmVydGVyCiAgVVNSMS5leHRyYWN0KHNzLCAidXRmLTgiKTsKICBpZiAoYlZlcmJvc2UpIHJjbENvbnNvbGUuZm9ybWF0KCJleHRyYWN0IGludG8gc3RyaW5nIHdpdGggdXRmLTggY29udmVydGVyIiwgc3MuY19zdHIoKSk7CiAgQVNTRVJUICggc3RybGVuKHU4KSA9PSBzcy5sZW5ndGgoKSApOwogIEFTU0VSVCAoIHN0cm5jbXAodTgsc3MuZGF0YSgpLHN0cmxlbih1OCkpID09IDAgKTsKCiAgLy8gVGVzdCB0aGUgInJlLXRyeSB3aGVuIG92ZXJmbG93cyIgbG9naWMgaW4gdW5pc3RycmVmLmNwcAogIC8vIENyZWF0ZSBhIHN0cmluZyB0aGF0IGNvbnZlcnRzIHRvID4yNTUgY2hhcnMKICBVbmljb2RlU3RyaW5nIFVTMih1YywgbmNoYXJzKTsKICBmb3IgKCBpbnQgaT0wOyBpIDwgMTU7ICsraSApCiAgICBVUzIuYXBwZW5kKHVjLCBuY2hhcnMpOwoKICAvLyBFeHRyYWN0IHRoZSAxMnRoIHJlcGVhdAogIFVuaWNvZGVTdHJpbmdSZWYgVVNSMyhVUzIpOwogIFVTUjMuZXh0cmFjdCgxMSpuY2hhcnMsIG5jaGFycywgc3MsICJ1dGYtOCIpOwogIGlmIChiVmVyYm9zZSkgcmNsQ29uc29sZS5mb3JtYXQoImV4dHJhY3QgcGFydCBpbnRvIHN0cmluZyB3aXRoIHV0Zi04IGNvbnZlcnRlciIsIHNzLmNfc3RyKCkpOwogIEFTU0VSVCAoIHN0cmxlbih1OCkgPT0gc3MubGVuZ3RoKCkgKTsKCiAgLy8gRXh0cmFjdCBhbGwgdG8gc3RyaW5nIHdpdGggY29udmVydGVyCiAgVVNSMy5leHRyYWN0KHNzLCAidXRmLTgiKTsKICBBU1NFUlQgKCAxNipzdHJsZW4odTgpID09IHNzLmxlbmd0aCgpICk7CgogIC8vIEV4cGxpY2l0IGV4dHJhY3QgdG8gdXRmLTggKG5vIElDVSBjb252ZXJ0ZXIpCiAgc3RkOjpzdHJpbmcgc3MyOwogIFVTUjMuZXh0cmFjdFVURjgoc3MyKTsKICBBU1NFUlQgKCBzczIgPT0gc3MgKTsKCiAgLy8gQ29udmVydCB0byB1dGYtOCAobm8gSUNVIGNvbnZlcnRlcikKICBzdGQ6OnN0cmluZyBzczMgPSBVU1IzLmFzVVRGOCgpOwogIEFTU0VSVCAoIHNzMyA9PSBzcyApOwoKICByY2xDb25zb2xlLmZvcm1hdCgiVW5pY29kZVN0cmluZ1JlZiB0ZXN0cyIsICJPSyIpOwoKICByZXR1cm4gZW5FcnJvcklkOwp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqIGFyZ3ZbXSkgLyoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwp7CiAgdXRpbDo6Q29uc29sZVVJICAgICAgICAgY2xDb25zb2xlKGFyZ2MsIGFyZ3YsIE1BSU5fVElUTEUsICIiKTsKICBUeUVycm9ySWQgICAgICAgICAgICAgICBlbkVycm9ySWQ7CgogIGNsQ29uc29sZS5oYW5kbGVVc2FnZUhlbHAoZ3Nfc3pVc2FnZSwgZ3Nfc3pIZWxwKTsKICBnc19iVmVyYm9zZSA9IGNsQ29uc29sZS5oYXNBcmdTd2l0Y2goX1RFWFQoInZlcmJvc2UiKSk7CgogIGVuRXJyb3JJZCA9IG1haW5UZXN0KGNsQ29uc29sZSwgZ3NfYlZlcmJvc2UpOwoKICBpZiAoZW5FcnJvcklkID09IFVJTUFfRVJSX05PTkUpIHsKICAgIGNsQ29uc29sZS5pbmZvKF9URVhUKCJUaGUgcHJvZ3JhbSB0ZXJtaW5hdGVkIHN1Y2Nlc3NmdWxseS4iKSk7CiAgfSBlbHNlIHsKICAgIGNsQ29uc29sZS5pbmZvKF9URVhUKCJUaGUgcHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggYW4gZXJyb3IuIikpOwogIH0KICByZXR1cm4oaW50KSBlbkVycm9ySWQ7Cn0gLy9saW50ICFlNTI5IHJjbFJlc01nciBub3Qgc3Vic2VxdWVudGx5IHJlZmVyZW5jZWQKCi8qIDxFT0Y+ICovCgo=