LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAiZGJnaGVscF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIgLyogRklYTUU6IG11c3QgYmUgaW5jbHVkZWQgYmVmb3JlIHdpbnRlcm5sLmggKi8KI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJzdGFja2ZyYW1lLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkYmdoZWxwKTsKCmVudW0gc3RfbW9kZSB7c3RtX3N0YXJ0LCBzdG1fMzJiaXQsIHN0bV8xNmJpdCwgc3RtX2RvbmV9OwoKc3RhdGljIGNvbnN0IGNoYXIqIHdpbmVfZGJnc3RyX2FkZHIoY29uc3QgQUREUkVTUyogYWRkcikKewogICAgaWYgKCFhZGRyKSByZXR1cm4gIihudWxsKSI7CiAgICBzd2l0Y2ggKGFkZHItPk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiZmxhdDwlMDhseD4iLCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MTY6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MTY8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MzI6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MzI8JTA0eDolMDhseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoInJlYWw8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gInVua25vd24iOwogICAgfQp9CgovKiBpbmRleGVzIGluIFJlc2VydmVkIGFycmF5ICovCiNkZWZpbmUgX19DdXJyZW50TW9kZSAgICAgMAojZGVmaW5lIF9fQ3VycmVudFN3aXRjaCAgIDEKI2RlZmluZSBfX05leHRTd2l0Y2ggICAgICAyCgojZGVmaW5lIGN1cnJfbW9kZSAgIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50TW9kZV0pCiNkZWZpbmUgY3Vycl9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRTd2l0Y2hdKQojZGVmaW5lIG5leHRfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19OZXh0U3dpdGNoXSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrIChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGsoRFdPUkQgTWFjaGluZVR5cGUsIEhBTkRMRSBoUHJvY2VzcywgSEFORExFIGhUaHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUUgZnJhbWUsIExQVk9JRCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FIGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgR2V0TW9kdWxlQmFzZVJvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSBmX3hsYXRfYWRyKQp7CiAgICBTVEFDSzMyRlJBTUUgICAgICAgIGZyYW1lMzI7CiAgICBTVEFDSzE2RlJBTUUgICAgICAgIGZyYW1lMTY7CiAgICBjaGFyICAgICAgICAgICAgICAgIGNoOwogICAgQUREUkVTUyAgICAgICAgICAgICB0bXA7CiAgICBEV09SRCAgICAgICAgICAgICAgIHA7CiAgICBXT1JEICAgICAgICAgICAgICAgIHZhbDsKICAgIEJPT0wgICAgICAgICAgICAgICAgZG9fc3dpdGNoOwoKICAgIFRSQUNFKCIoJWxkLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXApXG4iLAogICAgICAgICAgTWFjaGluZVR5cGUsIGhQcm9jZXNzLCBoVGhyZWFkLCBmcmFtZSwgY3R4LAogICAgICAgICAgZl9yZWFkX21lbSwgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICBHZXRNb2R1bGVCYXNlUm91dGluZSwgZl94bGF0X2Fkcik7CgogICAgaWYgKE1hY2hpbmVUeXBlICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKGN1cnJfbW9kZSA+PSBzdG1fZG9uZSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghZl9yZWFkX21lbSkgZl9yZWFkX21lbSA9IFJlYWRQcm9jZXNzTWVtb3J5OwogICAgaWYgKCFmX3hsYXRfYWRyKSBmX3hsYXRfYWRyID0gYWRkcl90b19saW5lYXI7CgogICAgVFJBQ0UoIkVudGVyOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtX3N0YXJ0KQogICAgewogICAgICAgIFRIUkVBRF9CQVNJQ19JTkZPUk1BVElPTiBpbmZvOwoKICAgICAgICAvKiBJbml0IGRvbmUgKi8KICAgICAgICBjdXJyX21vZGUgPSAoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgPyAKICAgICAgICAgICAgc3RtXzMyYml0IDogc3RtXzE2Yml0OwoKICAgICAgICAvKiBjdXJfc3dpdGNoIGhvbGRzIGFkZHJlc3Mgb2YgY3Vycl9zdGFjaydzIGZpZWxkIGluIFRFQiBpbiBkZWJ1Z2dlZQogICAgICAgICAqIGFkZHJlc3Mgc3BhY2UKICAgICAgICAgKi8KICAgICAgICBpZiAoTnRRdWVyeUluZm9ybWF0aW9uVGhyZWFkKGhUaHJlYWQsIFRocmVhZEJhc2ljSW5mb3JtYXRpb24sICZpbmZvLCAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihpbmZvKSwgTlVMTCkgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgY3Vycl9zd2l0Y2ggPSAodW5zaWduZWQgbG9uZylpbmZvLlRlYkJhc2VBZGRyZXNzICsgRklFTERfT0ZGU0VUKFRFQiwgY3VyX3N0YWNrKTsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKiljdXJyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCAKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5leHRfc3dpdGNoKSwgTlVMTCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDYW4ndCByZWFkIFRFQjpjdXJfc3RhY2tcbiIpOwogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIH0KICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZnJhbWUzMiksIE5VTEwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7CiAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2gsIHNpemVvZihjaCksIE5VTEwpKQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlID0gZnJhbWUtPkFkZHJTdGFjay5Nb2RlID0gQWRkck1vZGUxNjE2OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKTsKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBwKTsKICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwoKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgfQogICAgICAgIC8qIGRvbid0IHNldCB1cCBBZGRyU3RhY2sgb24gZmlyc3QgY2FsbC4gRWl0aGVyIHRoZSBjYWxsZXIgaGFzIHNldCBpdCB1cCwgb3IKICAgICAgICAgKiB3ZSB3aWxsIGdldCBpdCBpbiB0aGUgbmV4dCBmcmFtZQogICAgICAgICAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9PSAwKSBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgPT0gQWRkck1vZGVGbGF0KQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMzJiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBjdXJyX3N3aXRjaCAmJiBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA+PSBjdXJyX3N3aXRjaDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBPRkZTRVRPRihjdXJyX3N3aXRjaCkgJiYgCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgPT0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCkgJiYKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICB9CgkgICAKICAgICAgICBpZiAoZG9fc3dpdGNoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGZyYW1lMzIpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5PZmZzZXQgICAgICA9IGZyYW1lMzIucmV0YWRkcjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICAgPSBmcmFtZTMyLmVicDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5TZWdtZW50ICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IDA7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApOwoKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNiksIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzMyYml0OwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBhIDE2IGJpdCBzdGFjayBzd2l0Y2g6IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRmcmFtZTMyOiAlMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZWR4OiUwOGx4IGVjeDolMDhseCBlYnA6JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGRzOiUwNHggZXM6JTA0eCBmczolMDR4IGdzOiUwNHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGNhbGxfZnJvbV9pcDolMDhseCBtb2R1bGVfY3M6JTA0bHggcmVsYXk9JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGVudHJ5X2lwOiUwNHggZW50cnlfcG9pbnQ6JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGJwOiUwNHggaXA6JTA0eCBjczolMDR4XG4iLAogICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpZnJhbWUxNi5mcmFtZTMyLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lZHgsIGZyYW1lMTYuZWN4LCBmcmFtZTE2LmVicCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZHMsIGZyYW1lMTYuZXMsIGZyYW1lMTYuZnMsIGZyYW1lMTYuZ3MsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmNhbGxmcm9tX2lwLCBmcmFtZTE2Lm1vZHVsZV9jcywgZnJhbWUxNi5yZWxheSwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZW50cnlfaXAsIGZyYW1lMTYuZW50cnlfcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmJwLCBmcmFtZTE2LmlwLCBmcmFtZTE2LmNzKTsKCiAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuTW9kZSAgICAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICA9IGZyYW1lMTYuY3M7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgPSBmcmFtZTE2LmlwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgID0gZnJhbWUxNi5icDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IGZyYW1lMTYuY3M7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKGZyYW1lMzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzE2Yml0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMgPSBmcmFtZS0+QWRkclJldHVybjsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgQlAgdmFsdWUgKi8KICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKWZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEVCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgc2l6ZW9mKERXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgIHsKICAgICAgICBpbnQgICAgIGk7CgogICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmZnJhbWUtPkFkZHJGcmFtZSk7CiAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopKHAgKyBzaXplb2YoV09SRCkpLCAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk9mZnNldCA9IHZhbDsKICAgICAgICAvKiBnZXQgcG90ZW50aWFsIGNzIGlmIGEgZmFyIGNhbGwgd2FzIHVzZWQgKi8KICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKikocCArIDIgKiBzaXplb2YoV09SRCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJiAxKQogICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOyAvKiBmYXIgY2FsbCBhc3N1bWVkICovCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogbm90IGV4cGxpY2l0bHkgbWFya2VkIGFzIGZhciBjYWxsLCAKICAgICAgICAgICAgICogYnV0IGNoZWNrIHdoZXRoZXIgaXQgY291bGQgYmUgYW55d2F5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHZhbCAmIDcpID09IDcgJiYgdmFsICE9IGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExEVF9FTlRSWQlsZTsKCiAgICAgICAgICAgICAgICBpZiAoR2V0VGhyZWFkU2VsZWN0b3JFbnRyeShoVGhyZWFkLCB2YWwsICZsZSkgJiYKICAgICAgICAgICAgICAgICAgICAobGUuSGlnaFdvcmQuQml0cy5UeXBlICYgMHgwOCkpIC8qIGNvZGUgc2VnbWVudCAqLwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGl0IGlzIHZlcnkgdW5jb21tb24gdG8gcHVzaCBhIGNvZGUgc2VnbWVudCBjcyBhcwogICAgICAgICAgICAgICAgICAgICAqIGEgcGFyYW1ldGVyLCBzbyB0aGlzIHNob3VsZCB3b3JrIGluIG1vc3QgY2FzZXMgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KCSAgICB9Cgl9CiAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJj0gfjE7CiAgICAgICAgLyogd2UgInBvcCIgcGFyYW1ldGVycyBhcyAxNiBiaXQgZW50aXRpZXMuLi4gb2YgY291cnNlLCB0aGlzIHdvbid0CiAgICAgICAgICogd29yayBpZiB0aGUgcGFyYW1ldGVyIGlzIGluIGZhY3QgYmlnZ2VyIHRoYW4gMTZiaXQsIGJ1dAogICAgICAgICAqIHRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cgdGhhdCBoZXJlCiAgICAgICAgICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVvZihmcmFtZS0+UGFyYW1zKSAvIHNpemVvZihmcmFtZS0+UGFyYW1zWzBdKTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKShwICsgKDIgKyBpKSAqIHNpemVvZihXT1JEKSksIAogICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZih2YWwpLCBOVUxMKTsKICAgICAgICAgICAgZnJhbWUtPlBhcmFtc1tpXSA9IHZhbDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKShmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIHNpemVvZihEV09SRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICh2b2lkKikoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSksIAogICAgICAgICAgICAgICAgICAgZnJhbWUtPlBhcmFtcywgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpLCBOVUxMKTsKICAgIH0KCiAgICBmcmFtZS0+RmFyID0gRkFMU0U7CiAgICBmcmFtZS0+VmlydHVhbCA9IEZBTFNFOwoKICAgIFRSQUNFKCJMZWF2ZTogUEM9JXMgRnJhbWU9JXMgUmV0dXJuPSVzIFN0YWNrPSVzIE1vZGU9JXMgY1N3aXRjaD0lMDhseCBuU3dpdGNoPSUwOGx4XG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJQQyksIAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclJldHVybiksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclN0YWNrKSwgCiAgICAgICAgICBjdXJyX21vZGUgPT0gc3RtX3N0YXJ0ID8gInN0YXJ0IiA6IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0ID8gIjE2Yml0IiA6ICIzMmJpdCIpLAogICAgICAgICAgY3Vycl9zd2l0Y2gsIG5leHRfc3dpdGNoKTsKCiAgICByZXR1cm4gVFJVRTsKZG9uZV9lcnI6CiAgICBjdXJyX21vZGUgPSBzdG1fZG9uZTsKICAgIHJldHVybiBGQUxTRTsKfQo=