LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAiZGJnaGVscF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIgLyogRklYTUU6IG11c3QgYmUgaW5jbHVkZWQgYmVmb3JlIHdpbnRlcm5sLmggKi8KI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJzdGFja2ZyYW1lLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkYmdoZWxwKTsKCmVudW0gc3RfbW9kZSB7c3RtX3N0YXJ0LCBzdG1fMzJiaXQsIHN0bV8xNmJpdCwgc3RtX2RvbmV9OwoKc3RhdGljIGNvbnN0IGNoYXIqIHdpbmVfZGJnc3RyX2FkZHIoY29uc3QgQUREUkVTUyogYWRkcikKewogICAgaWYgKCFhZGRyKSByZXR1cm4gIihudWxsKSI7CiAgICBzd2l0Y2ggKGFkZHItPk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiZmxhdDwlMDhseD4iLCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MTY6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MTY8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MzI6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MzI8JTA0eDolMDhseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoInJlYWw8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gInVua25vd24iOwogICAgfQp9CgovKiBpbmRleGVzIGluIFJlc2VydmVkIGFycmF5ICovCiNkZWZpbmUgX19DdXJyZW50TW9kZSAgICAgMAojZGVmaW5lIF9fQ3VycmVudFN3aXRjaCAgIDEKI2RlZmluZSBfX05leHRTd2l0Y2ggICAgICAyCgojZGVmaW5lIGN1cnJfbW9kZSAgIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50TW9kZV0pCiNkZWZpbmUgY3Vycl9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRTd2l0Y2hdKQojZGVmaW5lIG5leHRfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19OZXh0U3dpdGNoXSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrIChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGsoRFdPUkQgTWFjaGluZVR5cGUsIEhBTkRMRSBoUHJvY2VzcywgSEFORExFIGhUaHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUUgZnJhbWUsIExQVk9JRCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICBQUkVBRF9QUk9DRVNTX01FTU9SWV9ST1VUSU5FIGZfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICBQRlVOQ1RJT05fVEFCTEVfQUNDRVNTX1JPVVRJTkUgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQR0VUX01PRFVMRV9CQVNFX1JPVVRJTkUgR2V0TW9kdWxlQmFzZVJvdXRpbmUsCiAgICAgICAgICAgICAgICAgICAgICBQVFJBTlNMQVRFX0FERFJFU1NfUk9VVElORSBmX3hsYXRfYWRyKQp7CiAgICBTVEFDSzMyRlJBTUUgICAgICAgIGZyYW1lMzI7CiAgICBTVEFDSzE2RlJBTUUgICAgICAgIGZyYW1lMTY7CiAgICBjaGFyICAgICAgICAgICAgICAgIGNoOwogICAgQUREUkVTUyAgICAgICAgICAgICB0bXA7CiAgICBEV09SRCAgICAgICAgICAgICAgIHA7CiAgICBXT1JEICAgICAgICAgICAgICAgIHZhbDsKICAgIEJPT0wgICAgICAgICAgICAgICAgZG9fc3dpdGNoOwoKICAgIFRSQUNFKCIoJWxkLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcCwgJXApXG4iLAogICAgICAgICAgTWFjaGluZVR5cGUsIGhQcm9jZXNzLCBoVGhyZWFkLCBmcmFtZSwgY3R4LAogICAgICAgICAgZl9yZWFkX21lbSwgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICBHZXRNb2R1bGVCYXNlUm91dGluZSwgZl94bGF0X2Fkcik7CgogICAgaWYgKE1hY2hpbmVUeXBlICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKGN1cnJfbW9kZSA+PSBzdG1fZG9uZSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghZl9yZWFkX21lbSkgZl9yZWFkX21lbSA9IFJlYWRQcm9jZXNzTWVtb3J5OwogICAgaWYgKCFmX3hsYXRfYWRyKSBmX3hsYXRfYWRyID0gYWRkcl90b19saW5lYXI7CgogICAgVFJBQ0UoIkVudGVyOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtX3N0YXJ0KQogICAgewogICAgICAgIFRIUkVBRF9CQVNJQ19JTkZPUk1BVElPTiBpbmZvOwoKICAgICAgICBpZiAoKGZyYW1lLT5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpICYmCiAgICAgICAgICAgIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgIT0gQWRkck1vZGVGbGF0KSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkJhZCBBZGRyUEMuTW9kZSAvIEFkZHJGcmFtZS5Nb2RlIGNvbWJpbmF0aW9uXG4iKTsKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICB9CgogICAgICAgIC8qIEluaXQgZG9uZSAqLwogICAgICAgIGN1cnJfbW9kZSA9IChmcmFtZS0+QWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSA/IAogICAgICAgICAgICBzdG1fMzJiaXQgOiBzdG1fMTZiaXQ7CgogICAgICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBjdXJyX3N0YWNrJ3MgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlCiAgICAgICAgICogYWRkcmVzcyBzcGFjZQogICAgICAgICAqLwogICAgICAgIGlmIChOdFF1ZXJ5SW5mb3JtYXRpb25UaHJlYWQoaFRocmVhZCwgVGhyZWFkQmFzaWNJbmZvcm1hdGlvbiwgJmluZm8sICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGluZm8pLCBOVUxMKSAhPSBTVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBjdXJyX3N3aXRjaCA9ICh1bnNpZ25lZCBsb25nKWluZm8uVGViQmFzZUFkZHJlc3MgKyBGSUVMRF9PRkZTRVQoVEVCLCBjdXJfc3RhY2spOwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWN1cnJfc3dpdGNoLCAmbmV4dF9zd2l0Y2gsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobmV4dF9zd2l0Y2gpLCBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOmN1cl9zdGFja1xuIik7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihmcmFtZTMyKSwgTlVMTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApOwogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CgogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKiljdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uTW9kZSA9IGZyYW1lLT5BZGRyU3RhY2suTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgICAgICB9CiAgICAgICAgLyogZG9uJ3Qgc2V0IHVwIEFkZHJTdGFjayBvbiBmaXJzdCBjYWxsLiBFaXRoZXIgdGhlIGNhbGxlciBoYXMgc2V0IGl0IHVwLCBvcgogICAgICAgICAqIHdlIHdpbGwgZ2V0IGl0IGluIHRoZSBuZXh0IGZyYW1lCiAgICAgICAgICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID09IDApIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgaWYgKGZyYW1lLT5BZGRyRnJhbWUuTW9kZSA9PSBBZGRyTW9kZUZsYXQpCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8zMmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IGN1cnJfc3dpdGNoICYmIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IGN1cnJfc3dpdGNoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBhc3NlcnQoY3Vycl9tb2RlID09IHN0bV8xNmJpdCk7CiAgICAgICAgICAgIGRvX3N3aXRjaCA9IE9GRlNFVE9GKGN1cnJfc3dpdGNoKSAmJiAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9PSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKSAmJgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgPj0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgIH0KCSAgIAogICAgICAgIGlmIChkb19zd2l0Y2gpCiAgICAgICAgewogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZnJhbWUzMiksIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk1vZGUgICAgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgID0gZnJhbWUzMi5yZXRhZGRyOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgICA9IGZyYW1lMzIuZWJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gMDsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IChEV09SRClmcmFtZTE2LmZyYW1lMzI7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMzJiaXQ7CiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKiljdXJyX3N3aXRjaCwgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICB0bXAuT2Zmc2V0ICA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKTsKCiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKGZyYW1lMTYpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUUkFDRSgiR290IGEgMTYgYml0IHN0YWNrIHN3aXRjaDoiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGZyYW1lMzI6ICUwOGx4IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRlZHg6JTA4bHggZWN4OiUwOGx4IGVicDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZHM6JTA0eCBlczolMDR4IGZzOiUwNHggZ3M6JTA0eCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0Y2FsbF9mcm9tX2lwOiUwOGx4IG1vZHVsZV9jczolMDRseCByZWxheT0lMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZW50cnlfaXA6JTA0eCBlbnRyeV9wb2ludDolMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0YnA6JTA0eCBpcDolMDR4IGNzOiUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylmcmFtZTE2LmZyYW1lMzIsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmVkeCwgZnJhbWUxNi5lY3gsIGZyYW1lMTYuZWJwLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5kcywgZnJhbWUxNi5lcywgZnJhbWUxNi5mcywgZnJhbWUxNi5ncywKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuY2FsbGZyb21faXAsIGZyYW1lMTYubW9kdWxlX2NzLCBmcmFtZTE2LnJlbGF5LAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lbnRyeV9pcCwgZnJhbWUxNi5lbnRyeV9wb2ludCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuYnAsIGZyYW1lMTYuaXAsIGZyYW1lMTYuY3MpOwoKICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5TZWdtZW50ICAgID0gZnJhbWUxNi5jczsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuT2Zmc2V0ICAgICA9IGZyYW1lMTYuaXA7CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAgPSBmcmFtZTE2LmJwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gZnJhbWUxNi5jczsKCiAgICAgICAgICAgICAgICBuZXh0X3N3aXRjaCA9IGN1cnJfc3dpdGNoOwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoZnJhbWUzMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihjdXJyX3N3aXRjaCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNoLCBzaXplb2YoY2gpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgICAgICBjdXJyX21vZGUgPSBzdG1fMTZiaXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgZnJhbWUtPkFkZHJQQyA9IGZyYW1lLT5BZGRyUmV0dXJuOwogICAgICAgICAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoV09SRCk7CiAgICAgICAgICAgICAgICAvKiAicG9wIHVwIiBwcmV2aW91cyBCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJmZyYW1lLT5BZGRyRnJhbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID0gdmFsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5PZmZzZXQgPSBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgRUJQIHZhbHVlICovCiAgICAgICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgewogICAgICAgIGludCAgICAgaTsKCiAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKTsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKikocCArIHNpemVvZihXT1JEKSksICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0ID0gdmFsOwogICAgICAgIC8qIGdldCBwb3RlbnRpYWwgY3MgaWYgYSBmYXIgY2FsbCB3YXMgdXNlZCAqLwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKShwICsgMiAqIHNpemVvZihXT1JEKSksIAogICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmIDEpCiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQgPSB2YWw7IC8qIGZhciBjYWxsIGFzc3VtZWQgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsIAogICAgICAgICAgICAgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgodmFsICYgNykgPT0gNyAmJiB2YWwgIT0gZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTERUX0VOVFJZCWxlOwoKICAgICAgICAgICAgICAgIGlmIChHZXRUaHJlYWRTZWxlY3RvckVudHJ5KGhUaHJlYWQsIHZhbCwgJmxlKSAmJgogICAgICAgICAgICAgICAgICAgIChsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgLyogY29kZSBzZWdtZW50ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCiAgICAgICAgICAgICAgICAgICAgICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQoJICAgIH0KCX0KICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCAmPSB+MTsKICAgICAgICAvKiB3ZSAicG9wIiBwYXJhbWV0ZXJzIGFzIDE2IGJpdCBlbnRpdGllcy4uLiBvZiBjb3Vyc2UsIHRoaXMgd29uJ3QKICAgICAgICAgKiB3b3JrIGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW4gZmFjdCBiaWdnZXIgdGhhbiAxNmJpdCwgYnV0CiAgICAgICAgICogdGhlcmUncyBubyB3YXkgdG8ga25vdyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpIC8gc2l6ZW9mKGZyYW1lLT5QYXJhbXNbMF0pOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopKHAgKyAoMiArIGkpICogc2l6ZW9mKFdPUkQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKHZhbCksIE5VTEwpOwogICAgICAgICAgICBmcmFtZS0+UGFyYW1zW2ldID0gdmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAodm9pZCopKGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSksCiAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkclJldHVybi5PZmZzZXQsIHNpemVvZihEV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGZfcmVhZF9tZW0oaFByb2Nlc3MsIAogICAgICAgICAgICAgICAgICAgKHZvaWQqKShmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpKSwgCiAgICAgICAgICAgICAgICAgICBmcmFtZS0+UGFyYW1zLCBzaXplb2YoZnJhbWUtPlBhcmFtcyksIE5VTEwpOwogICAgfQoKICAgIGZyYW1lLT5GYXIgPSBGQUxTRTsKICAgIGZyYW1lLT5WaXJ0dWFsID0gRkFMU0U7CgogICAgVFJBQ0UoIkxlYXZlOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIHJldHVybiBUUlVFOwpkb25lX2VycjoKICAgIGN1cnJfbW9kZSA9IHN0bV9kb25lOwogICAgcmV0dXJuIEZBTFNFOwp9Cg==