LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAibnRzdGF0dXMuaCIKI2RlZmluZSBXSU4zMl9OT19TVEFUVVMKI2luY2x1ZGUgImRiZ2hlbHBfcHJpdmF0ZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRiZ2hlbHApOwoKZW51bSBzdF9tb2RlIHtzdG1fc3RhcnQsIHN0bV8zMmJpdCwgc3RtXzE2Yml0LCBzdG1fZG9uZX07CgpzdGF0aWMgY29uc3QgY2hhciogd2luZV9kYmdzdHJfYWRkcihjb25zdCBBRERSRVNTKiBhZGRyKQp7CiAgICBpZiAoIWFkZHIpIHJldHVybiAiKG51bGwpIjsKICAgIHN3aXRjaCAoYWRkci0+TW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCJmbGF0PCUwOHg+IiwgYWRkci0+T2Zmc2V0KTsKICAgIGNhc2UgQWRkck1vZGUxNjE2OgogICAgICAgIHJldHVybiB3aW5lX2RiZ19zcHJpbnRmKCIxNjE2PCUwNHg6JTA0eD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MzI6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MzI8JTA0eDolMDh4PiIsIGFkZHItPlNlZ21lbnQsIGFkZHItPk9mZnNldCk7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigicmVhbDwlMDR4OiUwNHg+IiwgYWRkci0+U2VnbWVudCwgYWRkci0+T2Zmc2V0KTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuICJ1bmtub3duIjsKICAgIH0KfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgcmVhZF9tZW0oSEFORExFIGhQcm9jZXNzLCBEV09SRCBhZGRyLCB2b2lkKiBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUsIExQRFdPUkQgbnJlYWQpCnsKICAgIFNJWkVfVCAgICAgIHI7CiAgICBpZiAoIVJlYWRQcm9jZXNzTWVtb3J5KGhQcm9jZXNzLCAodm9pZCopYWRkciwgYnVmZmVyLCBzaXplLCAmcikpIHJldHVybiBGQUxTRTsKICAgICpucmVhZCA9IHI7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgcmVhZF9tZW02NChIQU5ETEUgaFByb2Nlc3MsIERXT1JENjQgYWRkciwgdm9pZCogYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUsIExQRFdPUkQgbnJlYWQpCnsKICAgIFNJWkVfVCAgICAgIHI7CiAgICBpZiAoIVJlYWRQcm9jZXNzTWVtb3J5KGhQcm9jZXNzLCAodm9pZCopKERXT1JEX1BUUilhZGRyLCBidWZmZXIsIHNpemUsICZyKSkgcmV0dXJuIEZBTFNFOwogICAgKm5yZWFkID0gcjsKICAgIHJldHVybiBUUlVFOwp9CgovKiBpbmRleGVzIGluIFJlc2VydmVkIGFycmF5ICovCiNkZWZpbmUgX19DdXJyZW50TW9kZSAgICAgMAojZGVmaW5lIF9fQ3VycmVudFN3aXRjaCAgIDEKI2RlZmluZSBfX05leHRTd2l0Y2ggICAgICAyCgojZGVmaW5lIGN1cnJfbW9kZSAgIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50TW9kZV0pCiNkZWZpbmUgY3Vycl9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRTd2l0Y2hdKQojZGVmaW5lIG5leHRfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19OZXh0U3dpdGNoXSkKCnN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrCnsKICAgIEhBTkRMRSAgICAgIGhQcm9jZXNzOwogICAgSEFORExFICAgICAgaFRocmVhZDsKICAgIEJPT0wgICAgICAgIGlzMzI7CiAgICB1bmlvbgogICAgewogICAgICAgIHN0cnVjdAogICAgICAgIHsKICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORSAgICAgICAgZl9yZWFkX21lbTsKICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkUgICAgICAgICAgZl94bGF0X2FkcjsKICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FICAgICAgZl90YWJsX2FjczsKICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FICAgICAgICAgICAgZl9tb2RsX2JhczsKICAgICAgICB9IHMzMjsKICAgICAgICBzdHJ1Y3QKICAgICAgICB7CiAgICAgICAgICAgIFBSRUFEX1BST0NFU1NfTUVNT1JZX1JPVVRJTkU2NCAgICAgIGZfcmVhZF9tZW07CiAgICAgICAgICAgIFBUUkFOU0xBVEVfQUREUkVTU19ST1VUSU5FNjQgICAgICAgIGZfeGxhdF9hZHI7CiAgICAgICAgICAgIFBGVU5DVElPTl9UQUJMRV9BQ0NFU1NfUk9VVElORTY0ICAgIGZfdGFibF9hY3M7CiAgICAgICAgICAgIFBHRVRfTU9EVUxFX0JBU0VfUk9VVElORTY0ICAgICAgICAgIGZfbW9kbF9iYXM7CiAgICAgICAgfSBzNjQ7CiAgICB9IHU7Cn07CgpzdGF0aWMgaW5saW5lIHZvaWQgYWRkcl8zMnRvNjQoY29uc3QgQUREUkVTUyogYWRkcjMyLCBBRERSRVNTNjQqIGFkZHI2NCkKewogICAgYWRkcjY0LT5PZmZzZXQgPSAoVUxPTkc2NClhZGRyMzItPk9mZnNldDsKICAgIGFkZHI2NC0+U2VnbWVudCA9IGFkZHIzMi0+U2VnbWVudDsKICAgIGFkZHI2NC0+TW9kZSA9IGFkZHIzMi0+TW9kZTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGFkZHJfNjR0bzMyKGNvbnN0IEFERFJFU1M2NCogYWRkcjY0LCBBRERSRVNTKiBhZGRyMzIpCnsKICAgIGFkZHIzMi0+T2Zmc2V0ID0gKFVMT05HKWFkZHI2NC0+T2Zmc2V0OwogICAgYWRkcjMyLT5TZWdtZW50ID0gYWRkcjY0LT5TZWdtZW50OwogICAgYWRkcjMyLT5Nb2RlID0gYWRkcjY0LT5Nb2RlOwp9CgpzdGF0aWMgaW5saW5lIEJPT0wgc3dfcmVhZF9tZW0oc3RydWN0IHN0YWNrX3dhbGtfY2FsbGJhY2sqIGNiLCBEV09SRCBhZGRyLCB2b2lkKiBwdHIsIERXT1JEIHN6KQp7CiAgICBpZiAoY2ItPmlzMzIpCiAgICAgICAgcmV0dXJuIGNiLT51LnMzMi5mX3JlYWRfbWVtKGNiLT5oUHJvY2VzcywgYWRkciwgcHRyLCBzeiwgTlVMTCk7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX3JlYWRfbWVtKGNiLT5oUHJvY2VzcywgYWRkciwgcHRyLCBzeiwgTlVMTCk7Cn0KCnN0YXRpYyBpbmxpbmUgRFdPUkQgc3dfeGxhdF9hZGRyKHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrKiBjYiwgQUREUkVTUyogYWRkcikKewogICAgaWYgKGFkZHItPk1vZGUgPT0gQWRkck1vZGVGbGF0KSByZXR1cm4gYWRkci0+T2Zmc2V0OwogICAgaWYgKGNiLT5pczMyKSByZXR1cm4gY2ItPnUuczMyLmZfeGxhdF9hZHIoY2ItPmhQcm9jZXNzLCBjYi0+aFRocmVhZCwgYWRkcik7CiAgICBpZiAoY2ItPnUuczY0LmZfeGxhdF9hZHIpCiAgICB7CiAgICAgICAgQUREUkVTUzY0ICAgICAgIGFkZHI2NDsKCiAgICAgICAgYWRkcl8zMnRvNjQoYWRkciwgJmFkZHI2NCk7CiAgICAgICAgcmV0dXJuIGNiLT51LnM2NC5mX3hsYXRfYWRyKGNiLT5oUHJvY2VzcywgY2ItPmhUaHJlYWQsICZhZGRyNjQpOwogICAgfQogICAgcmV0dXJuIGFkZHJfdG9fbGluZWFyKGNiLT5oUHJvY2VzcywgY2ItPmhUaHJlYWQsIGFkZHIpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQqIHN3X3RhYmxfYWNzKHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrKiBjYiwgRFdPUkQgYWRkcikKewogICAgaWYgKGNiLT5pczMyKQogICAgICAgIHJldHVybiBjYi0+dS5zMzIuZl90YWJsX2FjcyhjYi0+aFByb2Nlc3MsIGFkZHIpOwogICAgZWxzZQogICAgICAgIHJldHVybiBjYi0+dS5zNjQuZl90YWJsX2FjcyhjYi0+aFByb2Nlc3MsIGFkZHIpOwp9CgpzdGF0aWMgaW5saW5lIERXT1JEIHN3X21vZGxfYmFzKHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrKiBjYiwgRFdPUkQgYWRkcikKewogICAgaWYgKGNiLT5pczMyKQogICAgICAgIHJldHVybiBjYi0+dS5zMzIuZl9tb2RsX2JhcyhjYi0+aFByb2Nlc3MsIGFkZHIpOwogICAgZWxzZQogICAgICAgIHJldHVybiBjYi0+dS5zNjQuZl9tb2RsX2JhcyhjYi0+aFByb2Nlc3MsIGFkZHIpOwp9CgpzdGF0aWMgQk9PTCBzdGFja193YWxrKHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrKiBjYiwgTFBTVEFDS0ZSQU1FIGZyYW1lKQp7CiAgICBTVEFDSzMyRlJBTUUgICAgICAgIGZyYW1lMzI7CiAgICBTVEFDSzE2RlJBTUUgICAgICAgIGZyYW1lMTY7CiAgICBjaGFyICAgICAgICAgICAgICAgIGNoOwogICAgQUREUkVTUyAgICAgICAgICAgICB0bXA7CiAgICBEV09SRCAgICAgICAgICAgICAgIHA7CiAgICBXT1JEICAgICAgICAgICAgICAgIHZhbDsKICAgIEJPT0wgICAgICAgICAgICAgICAgZG9fc3dpdGNoOwoKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKGN1cnJfbW9kZSA+PSBzdG1fZG9uZSkgcmV0dXJuIEZBTFNFOwoKICAgIFRSQUNFKCJFbnRlcjogUEM9JXMgRnJhbWU9JXMgUmV0dXJuPSVzIFN0YWNrPSVzIE1vZGU9JXMgY1N3aXRjaD0lMDh4IG5Td2l0Y2g9JTA4eFxuIiwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUEMpLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclJldHVybiksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclN0YWNrKSwgCiAgICAgICAgICBjdXJyX21vZGUgPT0gc3RtX3N0YXJ0ID8gInN0YXJ0IiA6IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0ID8gIjE2Yml0IiA6ICIzMmJpdCIpLAogICAgICAgICAgY3Vycl9zd2l0Y2gsIG5leHRfc3dpdGNoKTsKCiAgICBpZiAoY3Vycl9tb2RlID09IHN0bV9zdGFydCkKICAgIHsKICAgICAgICBUSFJFQURfQkFTSUNfSU5GT1JNQVRJT04gaW5mbzsKCiAgICAgICAgaWYgKChmcmFtZS0+QWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSAmJgogICAgICAgICAgICAoZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJCYWQgQWRkclBDLk1vZGUgLyBBZGRyRnJhbWUuTW9kZSBjb21iaW5hdGlvblxuIik7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQoKICAgICAgICAvKiBJbml0IGRvbmUgKi8KICAgICAgICBjdXJyX21vZGUgPSAoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgPyAKICAgICAgICAgICAgc3RtXzMyYml0IDogc3RtXzE2Yml0OwoKICAgICAgICAvKiBjdXJfc3dpdGNoIGhvbGRzIGFkZHJlc3Mgb2YgV09XMzJSZXNlcnZlZCBmaWVsZCBpbiBURUIgaW4gZGVidWdnZWUKICAgICAgICAgKiBhZGRyZXNzIHNwYWNlCiAgICAgICAgICovCiAgICAgICAgaWYgKE50UXVlcnlJbmZvcm1hdGlvblRocmVhZChjYi0+aFRocmVhZCwgVGhyZWFkQmFzaWNJbmZvcm1hdGlvbiwgJmluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoaW5mbyksIE5VTEwpID09IFNUQVRVU19TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAodW5zaWduZWQgbG9uZylpbmZvLlRlYkJhc2VBZGRyZXNzICsgRklFTERfT0ZGU0VUKFRFQiwgV09XMzJSZXNlcnZlZCk7CiAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIGN1cnJfc3dpdGNoLCAmbmV4dF9zd2l0Y2gsIHNpemVvZihuZXh0X3N3aXRjaCkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQVJOKCJDYW4ndCByZWFkIFRFQjpXT1czMlJlc2VydmVkXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIG5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKGZyYW1lMzIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgc3dfeGxhdF9hZGRyKGNiLCAmdG1wKSwgJmNoLCBzaXplb2YoY2gpKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZ0bXApOwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4eFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBjdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyB3aWxsIGFsbG93IHRvIHdvcmsgd2hlbiB3ZSdyZSBub3QgYXR0YWNoZWQgdG8gYSBsaXZlIHRhcmdldCwgCiAgICAgICAgICAgICAqIGJ1dCB0aGUgMTYgPD0+IDMyIHN3aXRjaCBmYWNpbGl0eSB3b24ndCBiZSBhdmFpbGFibGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDA7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSA9IGZyYW1lLT5BZGRyU3RhY2suTW9kZSA9IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KSA/IEFkZHJNb2RlMTYxNiA6IEFkZHJNb2RlRmxhdDsKICAgICAgICAvKiBkb24ndCBzZXQgdXAgQWRkclN0YWNrIG9uIGZpcnN0IGNhbGwuIEVpdGhlciB0aGUgY2FsbGVyIGhhcyBzZXQgaXQgdXAsIG9yCiAgICAgICAgICogd2Ugd2lsbCBnZXQgaXQgaW4gdGhlIG5leHQgZnJhbWUKICAgICAgICAgKi8KICAgICAgICBtZW1zZXQoJmZyYW1lLT5BZGRyQlN0b3JlLCAwLCBzaXplb2YoZnJhbWUtPkFkZHJCU3RvcmUpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPT0gMCkgZ290byBkb25lX2VycjsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5Nb2RlID09IEFkZHJNb2RlRmxhdCkKICAgICAgICB7CiAgICAgICAgICAgIGFzc2VydChjdXJyX21vZGUgPT0gc3RtXzMyYml0KTsKICAgICAgICAgICAgZG9fc3dpdGNoID0gY3Vycl9zd2l0Y2ggJiYgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPj0gY3Vycl9zd2l0Y2g7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGFzc2VydChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KTsKICAgICAgICAgICAgZG9fc3dpdGNoID0gY3Vycl9zd2l0Y2ggJiYgCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgPT0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCkgJiYKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICB9CgkgICAKICAgICAgICBpZiAoZG9fc3dpdGNoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIG5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKGZyYW1lMzIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk1vZGUgICAgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgID0gZnJhbWUzMi5yZXRhZGRyOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgICA9IGZyYW1lMzIuZWJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gMDsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmdG1wKTsKCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzMyYml0OwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmdG1wKTsKCiAgICAgICAgICAgICAgICBpZiAoIXN3X3JlYWRfbWVtKGNiLCBwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFRSQUNFKCJHb3QgYSAxNiBiaXQgc3RhY2sgc3dpdGNoOiIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZnJhbWUzMjogJTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGVkeDolMDh4IGVjeDolMDh4IGVicDolMDh4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRkczolMDR4IGVzOiUwNHggZnM6JTA0eCBnczolMDR4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRjYWxsX2Zyb21faXA6JTA4eCBtb2R1bGVfY3M6JTA0eCByZWxheT0lMDh4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlbnRyeV9pcDolMDR4IGVudHJ5X3BvaW50OiUwOHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGJwOiUwNHggaXA6JTA0eCBjczolMDR4XG4iLAogICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpZnJhbWUxNi5mcmFtZTMyLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lZHgsIGZyYW1lMTYuZWN4LCBmcmFtZTE2LmVicCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZHMsIGZyYW1lMTYuZXMsIGZyYW1lMTYuZnMsIGZyYW1lMTYuZ3MsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmNhbGxmcm9tX2lwLCBmcmFtZTE2Lm1vZHVsZV9jcywgZnJhbWUxNi5yZWxheSwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZW50cnlfaXAsIGZyYW1lMTYuZW50cnlfcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmJwLCBmcmFtZTE2LmlwLCBmcmFtZTE2LmNzKTsKCiAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuTW9kZSAgICAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICA9IGZyYW1lMTYuY3M7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgPSBmcmFtZTE2LmlwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgID0gZnJhbWUxNi5icDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IGZyYW1lMTYuY3M7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIG5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKGZyYW1lMzIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDh4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHN3X3hsYXRfYWRkcihjYiwgJnRtcCksICZjaCwgc2l6ZW9mKGNoKSkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAwOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzE2Yml0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMgPSBmcmFtZS0+QWRkclJldHVybjsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgQlAgdmFsdWUgKi8KICAgICAgICAgICAgICAgIGlmICghc3dfcmVhZF9tZW0oY2IsIHN3X3hsYXRfYWRkcihjYiwgJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCkpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEVCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIHNpemVvZihEV09SRCkpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICB7CiAgICAgICAgaW50ICAgICBpOwoKICAgICAgICBwID0gc3dfeGxhdF9hZGRyKGNiLCAmZnJhbWUtPkFkZHJGcmFtZSk7CiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCArIHNpemVvZihXT1JEKSwgJnZhbCwgc2l6ZW9mKFdPUkQpKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBmcmFtZS0+QWRkclJldHVybi5PZmZzZXQgPSB2YWw7CiAgICAgICAgLyogZ2V0IHBvdGVudGlhbCBjcyBpZiBhIGZhciBjYWxsIHdhcyB1c2VkICovCiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgcCArIDIgKiBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZihXT1JEKSkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICYgMSkKICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IHZhbDsgLyogZmFyIGNhbGwgYXNzdW1lZCAqLwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIG5vdCBleHBsaWNpdGx5IG1hcmtlZCBhcyBmYXIgY2FsbCwgCiAgICAgICAgICAgICAqIGJ1dCBjaGVjayB3aGV0aGVyIGl0IGNvdWxkIGJlIGFueXdheQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCh2YWwgJiA3KSA9PSA3ICYmIHZhbCAhPSBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMRFRfRU5UUlkJbGU7CgogICAgICAgICAgICAgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoY2ItPmhUaHJlYWQsIHZhbCwgJmxlKSAmJgogICAgICAgICAgICAgICAgICAgIChsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgLyogY29kZSBzZWdtZW50ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCiAgICAgICAgICAgICAgICAgICAgICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCX0KICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmPSB+MTsKICAgICAgICAvKiB3ZSAicG9wIiBwYXJhbWV0ZXJzIGFzIDE2IGJpdCBlbnRpdGllcy4uLiBvZiBjb3Vyc2UsIHRoaXMgd29uJ3QKICAgICAgICAgKiB3b3JrIGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW4gZmFjdCBiaWdnZXIgdGhhbiAxNmJpdCwgYnV0CiAgICAgICAgICogdGhlcmUncyBubyB3YXkgdG8ga25vdyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpIC8gc2l6ZW9mKGZyYW1lLT5QYXJhbXNbMF0pOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBzd19yZWFkX21lbShjYiwgcCArICgyICsgaSkgKiBzaXplb2YoV09SRCksICZ2YWwsIHNpemVvZih2YWwpKTsKICAgICAgICAgICAgZnJhbWUtPlBhcmFtc1tpXSA9IHZhbDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCFzd19yZWFkX21lbShjYiwgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyBzaXplb2YoRFdPUkQpLAogICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyUmV0dXJuLk9mZnNldCwgc2l6ZW9mKERXT1JEKSkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDYW5ub3QgcmVhZCBuZXcgZnJhbWUgb2Zmc2V0ICUwOHhcbiIsIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgKGludClzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICB9CiAgICAgICAgc3dfcmVhZF9tZW0oY2IsIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCksCiAgICAgICAgICAgICAgICAgICAgZnJhbWUtPlBhcmFtcywgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpKTsKICAgIH0KCiAgICBmcmFtZS0+RmFyID0gVFJVRTsKICAgIGZyYW1lLT5WaXJ0dWFsID0gVFJVRTsKICAgIHAgPSBzd194bGF0X2FkZHIoY2IsICZmcmFtZS0+QWRkclBDKTsKICAgIGlmIChwICYmIHN3X21vZGxfYmFzKGNiLCBwKSkKICAgICAgICBmcmFtZS0+RnVuY1RhYmxlRW50cnkgPSBzd190YWJsX2FjcyhjYiwgcCk7CiAgICBlbHNlCiAgICAgICAgZnJhbWUtPkZ1bmNUYWJsZUVudHJ5ID0gTlVMTDsKCiAgICBUUkFDRSgiTGVhdmU6IFBDPSVzIEZyYW1lPSVzIFJldHVybj0lcyBTdGFjaz0lcyBNb2RlPSVzIGNTd2l0Y2g9JTA4eCBuU3dpdGNoPSUwOHggRnVuY1RhYmxlPSVwXG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJQQyksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gsIGZyYW1lLT5GdW5jVGFibGVFbnRyeSk7CgogICAgcmV0dXJuIFRSVUU7CmRvbmVfZXJyOgogICAgY3Vycl9tb2RlID0gc3RtX2RvbmU7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrIChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGsoRFdPUkQgTWFjaGluZVR5cGUsIEhBTkRMRSBoUHJvY2VzcywgSEFORExFIGhUaHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUUgZnJhbWUsIExQVk9JRCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FIGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgR2V0TW9kdWxlQmFzZVJvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSBmX3hsYXRfYWRyKQp7CiAgICBzdHJ1Y3Qgc3RhY2tfd2Fsa19jYWxsYmFjayAgc3djYjsKCiAgICBUUkFDRSgiKCVkLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXApXG4iLAogICAgICAgICAgTWFjaGluZVR5cGUsIGhQcm9jZXNzLCBoVGhyZWFkLCBmcmFtZSwgY3R4LAogICAgICAgICAgZl9yZWFkX21lbSwgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICBHZXRNb2R1bGVCYXNlUm91dGluZSwgZl94bGF0X2Fkcik7CgogICAgaWYgKE1hY2hpbmVUeXBlICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHN3Y2IuaFByb2Nlc3MgPSBoUHJvY2VzczsKICAgIHN3Y2IuaFRocmVhZCA9IGhUaHJlYWQ7CiAgICBzd2NiLmlzMzIgPSBUUlVFOwogICAgLyogc2lnaC4uLiBNUyBpc24ndCBldmVuIGNvbnNpc3RlbnQgaW4gdGhlIGZ1bmMgcHJvdG90eXBlcyAqLwogICAgc3djYi51LnMzMi5mX3JlYWRfbWVtID0gKGZfcmVhZF9tZW0pID8gZl9yZWFkX21lbSA6IHJlYWRfbWVtOwogICAgc3djYi51LnMzMi5mX3hsYXRfYWRyID0gKGZfeGxhdF9hZHIpID8gZl94bGF0X2FkciA6IGFkZHJfdG9fbGluZWFyOwogICAgc3djYi51LnMzMi5mX3RhYmxfYWNzID0gKEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lKSA/IEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lIDogU3ltRnVuY3Rpb25UYWJsZUFjY2VzczsKICAgIHN3Y2IudS5zMzIuZl9tb2RsX2JhcyA9IChHZXRNb2R1bGVCYXNlUm91dGluZSkgPyBHZXRNb2R1bGVCYXNlUm91dGluZSA6IFN5bUdldE1vZHVsZUJhc2U7CgogICAgcmV0dXJuIHN0YWNrX3dhbGsoJnN3Y2IsIGZyYW1lKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrNjQgKERCR0hFTFAuQCkKICovCkJPT0wgV0lOQVBJIFN0YWNrV2FsazY0KERXT1JEIE1hY2hpbmVUeXBlLCBIQU5ETEUgaFByb2Nlc3MsIEhBTkRMRSBoVGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUU2NCBmcmFtZTY0LCBMUFZPSUQgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FNjQgZl9yZWFkX21lbSwKICAgICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FNjQgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgIFBHRVRfTU9EVUxFX0JBU0VfUk9VVElORTY0IEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORTY0IGZfeGxhdF9hZHIpCnsKICAgIHN0cnVjdCBzdGFja193YWxrX2NhbGxiYWNrICBzd2NiOwogICAgU1RBQ0tGUkFNRSAgICAgICAgICAgICAgICAgIGZyYW1lMzI7CiAgICBCT09MICAgICAgICAgICAgICAgICAgICAgICAgcmV0OwoKICAgIFRSQUNFKCIoJWQsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcClcbiIsCiAgICAgICAgICBNYWNoaW5lVHlwZSwgaFByb2Nlc3MsIGhUaHJlYWQsIGZyYW1lNjQsIGN0eCwKICAgICAgICAgIGZfcmVhZF9tZW0sIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgR2V0TW9kdWxlQmFzZVJvdXRpbmUsIGZfeGxhdF9hZHIpOwoKICAgIGlmIChNYWNoaW5lVHlwZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkclBDLCAgICAgJmZyYW1lMzIuQWRkclBDKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyUmV0dXJuLCAmZnJhbWUzMi5BZGRyUmV0dXJuKTsKICAgIGFkZHJfNjR0bzMyKCZmcmFtZTY0LT5BZGRyRnJhbWUsICAmZnJhbWUzMi5BZGRyRnJhbWUpOwogICAgYWRkcl82NHRvMzIoJmZyYW1lNjQtPkFkZHJTdGFjaywgICZmcmFtZTMyLkFkZHJTdGFjayk7CiAgICBhZGRyXzY0dG8zMigmZnJhbWU2NC0+QWRkckJTdG9yZSwgJmZyYW1lMzIuQWRkckJTdG9yZSk7CiAgICBmcmFtZTMyLkZ1bmNUYWJsZUVudHJ5ID0gZnJhbWU2NC0+RnVuY1RhYmxlRW50cnk7IC8qIEZJWE1FICovCiAgICBmcmFtZTMyLkZhciA9IGZyYW1lNjQtPkZhcjsKICAgIGZyYW1lMzIuVmlydHVhbCA9IGZyYW1lNjQtPlZpcnR1YWw7CiAgICBmcmFtZTMyLlJlc2VydmVkWzBdID0gKFVMT05HKWZyYW1lNjQtPlJlc2VydmVkWzBdOwogICAgZnJhbWUzMi5SZXNlcnZlZFsxXSA9IChVTE9ORylmcmFtZTY0LT5SZXNlcnZlZFsxXTsKICAgIGZyYW1lMzIuUmVzZXJ2ZWRbMl0gPSAoVUxPTkcpZnJhbWU2NC0+UmVzZXJ2ZWRbMl07CiAgICAvKiB3ZSBkb24ndCBoYW5kbGUgS2RIZWxwICovCgogICAgc3djYi5oUHJvY2VzcyA9IGhQcm9jZXNzOwogICAgc3djYi5oVGhyZWFkID0gaFRocmVhZDsKICAgIHN3Y2IuaXMzMiA9IEZBTFNFOwogICAgLyogc2lnaC4uLiBNUyBpc24ndCBldmVuIGNvbnNpc3RlbnQgaW4gdGhlIGZ1bmMgcHJvdG90eXBlcyAqLwogICAgc3djYi51LnM2NC5mX3JlYWRfbWVtID0gKGZfcmVhZF9tZW0pID8gZl9yZWFkX21lbSA6IHJlYWRfbWVtNjQ7CiAgICBzd2NiLnUuczY0LmZfeGxhdF9hZHIgPSBmX3hsYXRfYWRyOwogICAgc3djYi51LnM2NC5mX3RhYmxfYWNzID0gKEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lKSA/IEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lIDogU3ltRnVuY3Rpb25UYWJsZUFjY2VzczY0OwogICAgc3djYi51LnM2NC5mX21vZGxfYmFzID0gKEdldE1vZHVsZUJhc2VSb3V0aW5lKSA/IEdldE1vZHVsZUJhc2VSb3V0aW5lIDogU3ltR2V0TW9kdWxlQmFzZTY0OwoKICAgIHJldCA9IHN0YWNrX3dhbGsoJnN3Y2IsICZmcmFtZTMyKTsKCiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyUEMsICAgICAmZnJhbWU2NC0+QWRkclBDKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJSZXR1cm4sICZmcmFtZTY0LT5BZGRyUmV0dXJuKTsKICAgIGFkZHJfMzJ0bzY0KCZmcmFtZTMyLkFkZHJGcmFtZSwgICZmcmFtZTY0LT5BZGRyRnJhbWUpOwogICAgYWRkcl8zMnRvNjQoJmZyYW1lMzIuQWRkclN0YWNrLCAgJmZyYW1lNjQtPkFkZHJTdGFjayk7CiAgICBhZGRyXzMydG82NCgmZnJhbWUzMi5BZGRyQlN0b3JlLCAmZnJhbWU2NC0+QWRkckJTdG9yZSk7CiAgICBmcmFtZTY0LT5GdW5jVGFibGVFbnRyeSA9IGZyYW1lMzIuRnVuY1RhYmxlRW50cnk7IC8qIEZJWE1FICovCiAgICBmcmFtZTY0LT5QYXJhbXNbMF0gPSAoVUxPTkcpZnJhbWUzMi5QYXJhbXNbMF07CiAgICBmcmFtZTY0LT5QYXJhbXNbMV0gPSAoVUxPTkcpZnJhbWUzMi5QYXJhbXNbMV07CiAgICBmcmFtZTY0LT5QYXJhbXNbMl0gPSAoVUxPTkcpZnJhbWUzMi5QYXJhbXNbMl07CiAgICBmcmFtZTY0LT5QYXJhbXNbM10gPSAoVUxPTkcpZnJhbWUzMi5QYXJhbXNbM107CiAgICBmcmFtZTY0LT5GYXIgPSBmcmFtZTMyLkZhcjsKICAgIGZyYW1lNjQtPlZpcnR1YWwgPSBmcmFtZTMyLlZpcnR1YWw7CiAgICBmcmFtZTY0LT5SZXNlcnZlZFswXSA9IChVTE9ORylmcmFtZTMyLlJlc2VydmVkWzBdOwogICAgZnJhbWU2NC0+UmVzZXJ2ZWRbMV0gPSAoVUxPTkcpZnJhbWUzMi5SZXNlcnZlZFsxXTsKICAgIGZyYW1lNjQtPlJlc2VydmVkWzJdID0gKFVMT05HKWZyYW1lMzIuUmVzZXJ2ZWRbMl07CiAgICAvKiB3ZSBkb24ndCBoYW5kbGUgS2RIZWxwICovCiAgICBmcmFtZTY0LT5LZEhlbHAuVGhyZWFkID0gMHhDMDAwRkFERTsKICAgIGZyYW1lNjQtPktkSGVscC5UaENhbGxiYWNrU3RhY2sgPSAweDEwOwogICAgZnJhbWU2NC0+S2RIZWxwLlRoQ2FsbGJhY2tCU3RvcmUgPSAwOwogICAgZnJhbWU2NC0+S2RIZWxwLk5leHRDYWxsYmFjayA9IDA7CiAgICBmcmFtZTY0LT5LZEhlbHAuRnJhbWVQb2ludGVyID0gMDsKICAgIGZyYW1lNjQtPktkSGVscC5LaUNhbGxVc2VyTW9kZSA9IDB4RDAwMERBRkU7CiAgICBmcmFtZTY0LT5LZEhlbHAuS2VVc2VyQ2FsbGJhY2tEaXNwYXRjaGVyID0gMHhFMDAwRjAwMDsKICAgIGZyYW1lNjQtPktkSGVscC5TeXN0ZW1SYW5nZVN0YXJ0ID0gMHhDMDAwMDAwMDsKICAgIGZyYW1lNjQtPktkSGVscC5SZXNlcnZlZFswXSAvKiBLaVVzZXJFeGNlcHRpb25EaXNwYXRjaGVyICovID0gMHhFMDAwNTAwMDsKCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTeW1SZWdpc3RlckZ1bmN0aW9uRW50cnlDYWxsYmFjayAoREJHSEVMUC5AKQogKgogKgogKi8KQk9PTCBXSU5BUEkgU3ltUmVnaXN0ZXJGdW5jdGlvbkVudHJ5Q2FsbGJhY2soSEFORExFIGhQcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lNQk9MX0ZVTkNFTlRSWV9DQUxMQkFDSyBjYiwgUFZPSUQgdXNlcikKewogICAgRklYTUUoIiglcCAlcCAlcCk6IHN0dWIhXG4iLCBoUHJvYywgY2IsIHVzZXIpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0NBTExfTk9UX0lNUExFTUVOVEVEKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3ltUmVnaXN0ZXJGdW5jdGlvbkVudHJ5Q2FsbGJhY2s2NCAoREJHSEVMUC5AKQogKgogKgogKi8KQk9PTCBXSU5BUEkgU3ltUmVnaXN0ZXJGdW5jdGlvbkVudHJ5Q2FsbGJhY2s2NChIQU5ETEUgaFByb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZTUJPTF9GVU5DRU5UUllfQ0FMTEJBQ0s2NCBjYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORzY0IHVzZXIpCnsKICAgIEZJWE1FKCIoJXAgJXAgJXMpOiBzdHViIVxuIiwgaFByb2MsIGNiLCB3aW5lX2RiZ3N0cl9sb25nbG9uZyh1c2VyKSk7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQ0FMTF9OT1RfSU1QTEVNRU5URUQpOwogICAgcmV0dXJuIEZBTFNFOwp9Cg==