LyoKICogU3RhY2sgd2Fsa2luZwogKgogKiBDb3B5cmlnaHQgMTk5NSBBbGV4YW5kcmUgSnVsbGlhcmQKICogQ29weXJpZ2h0IDE5OTYgRXJpYyBZb3VuZ2RhbGUKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDA0IEVyaWMgUG91ZWNoCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAiZGJnaGVscF9wcml2YXRlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIm50c3RhdHVzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIgLyogRklYTUU6IG11c3QgYmUgaW5jbHVkZWQgYmVmb3JlIHdpbnRlcm5sLmggKi8KI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJzdGFja2ZyYW1lLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkYmdoZWxwKTsKCmVudW0gc3RfbW9kZSB7c3RtX3N0YXJ0LCBzdG1fMzJiaXQsIHN0bV8xNmJpdCwgc3RtX2RvbmV9OwoKc3RhdGljIGNvbnN0IGNoYXIqIHdpbmVfZGJnc3RyX2FkZHIoY29uc3QgQUREUkVTUyogYWRkcikKewogICAgaWYgKCFhZGRyKSByZXR1cm4gIihudWxsKSI7CiAgICBzd2l0Y2ggKGFkZHItPk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDoKICAgICAgICByZXR1cm4gd2luZV9kYmdfc3ByaW50ZigiZmxhdDwlMDhseD4iLCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MTY6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MTY8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZTE2MzI6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoIjE2MzI8JTA0eDolMDhseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6CiAgICAgICAgcmV0dXJuIHdpbmVfZGJnX3NwcmludGYoInJlYWw8JTA0eDolMDRseD4iLCBhZGRyLT5TZWdtZW50LCBhZGRyLT5PZmZzZXQpOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gInVua25vd24iOwogICAgfQp9CgovKiBpbmRleGVzIGluIFJlc2VydmVkIGFycmF5ICovCiNkZWZpbmUgX19DdXJyZW50TW9kZSAgICAgMAojZGVmaW5lIF9fQ3VycmVudFN3aXRjaCAgIDEKI2RlZmluZSBfX05leHRTd2l0Y2ggICAgICAyCgojZGVmaW5lIGN1cnJfbW9kZSAgIChmcmFtZS0+UmVzZXJ2ZWRbX19DdXJyZW50TW9kZV0pCiNkZWZpbmUgY3Vycl9zd2l0Y2ggKGZyYW1lLT5SZXNlcnZlZFtfX0N1cnJlbnRTd2l0Y2hdKQojZGVmaW5lIG5leHRfc3dpdGNoIChmcmFtZS0+UmVzZXJ2ZWRbX19OZXh0U3dpdGNoXSkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU3RhY2tXYWxrIChEQkdIRUxQLkApCiAqLwpCT09MIFdJTkFQSSBTdGFja1dhbGsoRFdPUkQgTWFjaGluZVR5cGUsIEhBTkRMRSBoUHJvY2VzcywgSEFORExFIGhUaHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICBMUFNUQUNLRlJBTUUgZnJhbWUsIExQVk9JRCBfY3R4LAogICAgICAgICAgICAgICAgICAgICAgUFJFQURfUFJPQ0VTU19NRU1PUllfUk9VVElORSBmX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgUEZVTkNUSU9OX1RBQkxFX0FDQ0VTU19ST1VUSU5FIEZ1bmN0aW9uVGFibGVBY2Nlc3NSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUEdFVF9NT0RVTEVfQkFTRV9ST1VUSU5FIEdldE1vZHVsZUJhc2VSb3V0aW5lLAogICAgICAgICAgICAgICAgICAgICAgUFRSQU5TTEFURV9BRERSRVNTX1JPVVRJTkUgZl94bGF0X2FkcikKewogICAgQ09OVEVYVCogICAgICAgICAgICBjdHggPSAoQ09OVEVYVCopX2N0eDsKICAgIFNUQUNLMzJGUkFNRSAgICAgICAgZnJhbWUzMjsKICAgIFNUQUNLMTZGUkFNRSAgICAgICAgZnJhbWUxNjsKICAgIGNoYXIgICAgICAgICAgICAgICAgY2g7CiAgICBBRERSRVNTICAgICAgICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgICAgICAgICAgcDsKICAgIFdPUkQgICAgICAgICAgICAgICAgdmFsOwogICAgQk9PTCAgICAgICAgICAgICAgICBkb19zd2l0Y2g7CgogICAgVFJBQ0UoIiglbGQsICVwLCAlcCwgJXAsICVwLCAlcCwgJXAsICVwLCAlcClcbiIsCiAgICAgICAgICBNYWNoaW5lVHlwZSwgaFByb2Nlc3MsIGhUaHJlYWQsIGZyYW1lLCBfY3R4LAogICAgICAgICAgZl9yZWFkX21lbSwgRnVuY3Rpb25UYWJsZUFjY2Vzc1JvdXRpbmUsCiAgICAgICAgICBHZXRNb2R1bGVCYXNlUm91dGluZSwgZl94bGF0X2Fkcik7CgogICAgaWYgKE1hY2hpbmVUeXBlICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIC8qIHNhbml0eSBjaGVjayAqLwogICAgaWYgKGN1cnJfbW9kZSA+PSBzdG1fZG9uZSkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghZl9yZWFkX21lbSkgZl9yZWFkX21lbSA9IFJlYWRQcm9jZXNzTWVtb3J5OwogICAgaWYgKCFmX3hsYXRfYWRyKSBmX3hsYXRfYWRyID0gYWRkcl90b19saW5lYXI7CgogICAgVFJBQ0UoIkVudGVyOiBQQz0lcyBGcmFtZT0lcyBSZXR1cm49JXMgU3RhY2s9JXMgTW9kZT0lcyBjU3dpdGNoPSUwOGx4IG5Td2l0Y2g9JTA4bHhcbiIsCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclBDKSwgCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyUmV0dXJuKSwKICAgICAgICAgIHdpbmVfZGJnc3RyX2FkZHIoJmZyYW1lLT5BZGRyU3RhY2spLCAKICAgICAgICAgIGN1cnJfbW9kZSA9PSBzdG1fc3RhcnQgPyAic3RhcnQiIDogKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQgPyAiMTZiaXQiIDogIjMyYml0IiksCiAgICAgICAgICBjdXJyX3N3aXRjaCwgbmV4dF9zd2l0Y2gpOwoKICAgIGlmIChjdXJyX21vZGUgPT0gc3RtX3N0YXJ0KQogICAgewogICAgICAgIFRIUkVBRF9CQVNJQ19JTkZPUk1BVElPTiBpbmZvOwoKICAgICAgICAvKiBJbml0IGRvbmUgKi8KICAgICAgICBjdXJyX21vZGUgPSAoZnJhbWUtPkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgPyAKICAgICAgICAgICAgc3RtXzMyYml0IDogc3RtXzE2Yml0OwoKICAgICAgICAvKiBHZXQgdGhlIGN1cnJlbnQgRVNQIChkb24ndCBrbm93IGlmIHRoaXMgaXMgdmFsaWQpICovCiAgICAgICAgaWYgKGN0eCkKICAgICAgICB7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suU2VnbWVudCA9IDA7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ICA9IGN0eC0+RXNwOwogICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgfQogICAgICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBjdXJyX3N0YWNrJ3MgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlCiAgICAgICAgICogYWRkcmVzcyBzcGFjZQogICAgICAgICAqLwogICAgICAgIGlmIChOdFF1ZXJ5SW5mb3JtYXRpb25UaHJlYWQoaFRocmVhZCwgVGhyZWFkQmFzaWNJbmZvcm1hdGlvbiwgJmluZm8sICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGluZm8pLCBOVUxMKSAhPSBTVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBjdXJyX3N3aXRjaCA9ICh1bnNpZ25lZCBsb25nKWluZm8uVGViQmFzZUFkZHJlc3MgKyBGSUVMRF9PRkZTRVQoVEVCLCBjdXJfc3RhY2spOwogICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWN1cnJfc3dpdGNoLCAmbmV4dF9zd2l0Y2gsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobmV4dF9zd2l0Y2gpLCBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkNhbid0IHJlYWQgVEVCOmN1cl9zdGFja1xuIik7CiAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyX21vZGUgPT0gc3RtXzE2Yml0KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihmcmFtZTMyKSwgTlVMTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCk7CiAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwogICAgICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKilmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmdG1wKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICBjdXJyX3N3aXRjaCA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk1vZGUgPSBmcmFtZS0+QWRkclN0YWNrLk1vZGUgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEJQIHZhbHVlICovCiAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZihXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgIHRtcC5TZWdtZW50ID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CiAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNiksIE5VTEwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgcCk7CiAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCiAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWN1cnJfc3dpdGNoLCAmY2gsIHNpemVvZihjaCksIE5VTEwpKQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlID0gZnJhbWUtPkFkZHJTdGFjay5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAvKiAicG9wIHVwIiBwcmV2aW91cyBFQlAgdmFsdWUgKi8KICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9PSAwKSBnb3RvIGRvbmVfZXJyOwogICAgICAgIGlmIChmcmFtZS0+QWRkckZyYW1lLk1vZGUgPT0gQWRkck1vZGVGbGF0KQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMzJiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBjdXJyX3N3aXRjaCAmJiBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA+PSBjdXJyX3N3aXRjaDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpOwogICAgICAgICAgICBkb19zd2l0Y2ggPSBPRkZTRVRPRihjdXJyX3N3aXRjaCkgJiYgCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgPT0gU0VMRUNUT1JPRihjdXJyX3N3aXRjaCkgJiYKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ID49IE9GRlNFVE9GKGN1cnJfc3dpdGNoKTsKICAgICAgICB9CgkgICAKICAgICAgICBpZiAoZG9fc3dpdGNoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGZyYW1lMzIpLCBOVUxMKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgbmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5Nb2RlICAgICAgICA9IEFkZHJNb2RlRmxhdDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICAgPSAwOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJQQy5PZmZzZXQgICAgICA9IGZyYW1lMzIucmV0YWRkcjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICAgPSBBZGRyTW9kZUZsYXQ7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLlNlZ21lbnQgID0gMDsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuT2Zmc2V0ICAgPSBmcmFtZTMyLmVicDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJTdGFjay5TZWdtZW50ICA9IDA7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGVGbGF0OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IDA7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgcCA9IGZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApOwoKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoZnJhbWUxNiksIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzMyYml0OwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopY3Vycl9zd2l0Y2gsICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG1wLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICB0bXAuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgdG1wLk9mZnNldCAgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICBwID0gZl94bGF0X2FkcihoUHJvY2VzcywgaFRocmVhZCwgJnRtcCk7CgogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihmcmFtZTE2KSwgTlVMTCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIHApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBhIDE2IGJpdCBzdGFjayBzd2l0Y2g6IgogICAgICAgICAgICAgICAgICAgICAgIlxuXHRmcmFtZTMyOiAlMDhseCIKICAgICAgICAgICAgICAgICAgICAgICJcblx0ZWR4OiUwOGx4IGVjeDolMDhseCBlYnA6JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGRzOiUwNHggZXM6JTA0eCBmczolMDR4IGdzOiUwNHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGNhbGxfZnJvbV9pcDolMDhseCBtb2R1bGVfY3M6JTA0bHggcmVsYXk9JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGVudHJ5X2lwOiUwNHggZW50cnlfcG9pbnQ6JTA4bHgiCiAgICAgICAgICAgICAgICAgICAgICAiXG5cdGJwOiUwNHggaXA6JTA0eCBjczolMDR4XG4iLAogICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpZnJhbWUxNi5mcmFtZTMyLAogICAgICAgICAgICAgICAgICAgICAgZnJhbWUxNi5lZHgsIGZyYW1lMTYuZWN4LCBmcmFtZTE2LmVicCwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZHMsIGZyYW1lMTYuZXMsIGZyYW1lMTYuZnMsIGZyYW1lMTYuZ3MsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmNhbGxmcm9tX2lwLCBmcmFtZTE2Lm1vZHVsZV9jcywgZnJhbWUxNi5yZWxheSwKICAgICAgICAgICAgICAgICAgICAgIGZyYW1lMTYuZW50cnlfaXAsIGZyYW1lMTYuZW50cnlfcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICBmcmFtZTE2LmJwLCBmcmFtZTE2LmlwLCBmcmFtZTE2LmNzKTsKCiAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuTW9kZSAgICAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMuU2VnbWVudCAgICA9IGZyYW1lMTYuY3M7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclBDLk9mZnNldCAgICAgPSBmcmFtZTE2LmlwOwoKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuTW9kZSAgICA9IEFkZHJNb2RlMTYxNjsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyRnJhbWUuU2VnbWVudCA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgID0gZnJhbWUxNi5icDsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLk1vZGUgICAgPSBBZGRyTW9kZTE2MTY7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclN0YWNrLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IGZyYW1lMTYuY3M7CgogICAgICAgICAgICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJyX3N3aXRjaDsKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKGZyYW1lMzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCBuZXh0X3N3aXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKICAgICAgICAgICAgICAgIHRtcC5Nb2RlICAgID0gQWRkck1vZGUxNjE2OwogICAgICAgICAgICAgICAgdG1wLlNlZ21lbnQgPSBTRUxFQ1RPUk9GKGN1cnJfc3dpdGNoKTsKICAgICAgICAgICAgICAgIHRtcC5PZmZzZXQgID0gT0ZGU0VUT0YoY3Vycl9zd2l0Y2gpOwoKICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKWZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZ0bXApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaCwgc2l6ZW9mKGNoKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgY3Vycl9zd2l0Y2ggPSAweEZGRkZGRkZGOwogICAgICAgICAgICAgICAgY3Vycl9tb2RlID0gc3RtXzE2Yml0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGZyYW1lLT5BZGRyUEMgPSBmcmFtZS0+QWRkclJldHVybjsKICAgICAgICAgICAgaWYgKGN1cnJfbW9kZSA9PSBzdG1fMTZiaXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKFdPUkQpOwogICAgICAgICAgICAgICAgLyogInBvcCB1cCIgcHJldmlvdXMgQlAgdmFsdWUgKi8KICAgICAgICAgICAgICAgIGlmICghZl9yZWFkX21lbShoUHJvY2VzcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKWZfeGxhdF9hZHIoaFByb2Nlc3MsIGhUaHJlYWQsICZmcmFtZS0+QWRkckZyYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICAgICAgICAgIGdvdG8gZG9uZV9lcnI7CiAgICAgICAgICAgICAgICBmcmFtZS0+QWRkckZyYW1lLk9mZnNldCA9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZyYW1lLT5BZGRyU3RhY2suT2Zmc2V0ID0gZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIC8qICJwb3AgdXAiIHByZXZpb3VzIEVCUCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZS0+QWRkckZyYW1lLk9mZnNldCwgc2l6ZW9mKERXT1JEKSwgTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY3Vycl9tb2RlID09IHN0bV8xNmJpdCkKICAgIHsKICAgICAgICBpbnQgICAgIGk7CgogICAgICAgIHAgPSBmX3hsYXRfYWRyKGhQcm9jZXNzLCBoVGhyZWFkLCAmZnJhbWUtPkFkZHJGcmFtZSk7CiAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAodm9pZCopKHAgKyBzaXplb2YoV09SRCkpLCAmdmFsLCBzaXplb2YoV09SRCksIE5VTEwpKQogICAgICAgICAgICBnb3RvIGRvbmVfZXJyOwogICAgICAgIGZyYW1lLT5BZGRyUmV0dXJuLk9mZnNldCA9IHZhbDsKICAgICAgICAvKiBnZXQgcG90ZW50aWFsIGNzIGlmIGEgZmFyIGNhbGwgd2FzIHVzZWQgKi8KICAgICAgICBpZiAoIWZfcmVhZF9tZW0oaFByb2Nlc3MsICh2b2lkKikocCArIDIgKiBzaXplb2YoV09SRCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgJnZhbCwgc2l6ZW9mKFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBpZiAoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJiAxKQogICAgICAgICAgICBmcmFtZS0+QWRkclJldHVybi5TZWdtZW50ID0gdmFsOyAvKiBmYXIgY2FsbCBhc3N1bWVkICovCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogbm90IGV4cGxpY2l0bHkgbWFya2VkIGFzIGZhciBjYWxsLCAKICAgICAgICAgICAgICogYnV0IGNoZWNrIHdoZXRoZXIgaXQgY291bGQgYmUgYW55d2F5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHZhbCAmIDcpID09IDcgJiYgdmFsICE9IGZyYW1lLT5BZGRyUmV0dXJuLlNlZ21lbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExEVF9FTlRSWQlsZTsKCiAgICAgICAgICAgICAgICBpZiAoR2V0VGhyZWFkU2VsZWN0b3JFbnRyeShoVGhyZWFkLCB2YWwsICZsZSkgJiYKICAgICAgICAgICAgICAgICAgICAobGUuSGlnaFdvcmQuQml0cy5UeXBlICYgMHgwOCkpIC8qIGNvZGUgc2VnbWVudCAqLwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGl0IGlzIHZlcnkgdW5jb21tb24gdG8gcHVzaCBhIGNvZGUgc2VnbWVudCBjcyBhcwogICAgICAgICAgICAgICAgICAgICAqIGEgcGFyYW1ldGVyLCBzbyB0aGlzIHNob3VsZCB3b3JrIGluIG1vc3QgY2FzZXMgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgZnJhbWUtPkFkZHJSZXR1cm4uU2VnbWVudCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KCSAgICB9Cgl9CiAgICAgICAgZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgJj0gfjE7CiAgICAgICAgLyogd2UgInBvcCIgcGFyYW1hdGVycyBhcyAxNiBiaXQgZW50aXRpZXMuLi4gb2YgY291cnNlLCB0aGlzIHdvbid0CiAgICAgICAgICogd29yayBpZiB0aGUgcGFyYW1ldGVyIGlzIGluIGZhY3QgYmlnZ2VyIHRoYW4gMTZiaXQsIGJ1dAogICAgICAgICAqIHRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cgdGhhdCBoZXJlCiAgICAgICAgICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVvZihmcmFtZS0+UGFyYW1zKSAvIHNpemVvZihmcmFtZS0+UGFyYW1zWzBdKTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgZl9yZWFkX21lbShoUHJvY2VzcywgKHZvaWQqKShwICsgKDIgKyBpKSAqIHNpemVvZihXT1JEKSksIAogICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHNpemVvZih2YWwpLCBOVUxMKTsKICAgICAgICAgICAgZnJhbWUtPlBhcmFtc1tpXSA9IHZhbDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCFmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKShmcmFtZS0+QWRkckZyYW1lLk9mZnNldCArIHNpemVvZihEV09SRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWUtPkFkZHJSZXR1cm4uT2Zmc2V0LCBzaXplb2YoRFdPUkQpLCBOVUxMKSkKICAgICAgICAgICAgZ290byBkb25lX2VycjsKICAgICAgICBmX3JlYWRfbWVtKGhQcm9jZXNzLCAKICAgICAgICAgICAgICAgICAgICh2b2lkKikoZnJhbWUtPkFkZHJGcmFtZS5PZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSksIAogICAgICAgICAgICAgICAgICAgZnJhbWUtPlBhcmFtcywgc2l6ZW9mKGZyYW1lLT5QYXJhbXMpLCBOVUxMKTsKICAgIH0KCiAgICBmcmFtZS0+RmFyID0gRkFMU0U7CiAgICBmcmFtZS0+VmlydHVhbCA9IEZBTFNFOwoKICAgIFRSQUNFKCJMZWF2ZTogUEM9JXMgRnJhbWU9JXMgUmV0dXJuPSVzIFN0YWNrPSVzIE1vZGU9JXMgY1N3aXRjaD0lMDhseCBuU3dpdGNoPSUwOGx4XG4iLAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJQQyksIAogICAgICAgICAgd2luZV9kYmdzdHJfYWRkcigmZnJhbWUtPkFkZHJGcmFtZSksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclJldHVybiksCiAgICAgICAgICB3aW5lX2RiZ3N0cl9hZGRyKCZmcmFtZS0+QWRkclN0YWNrKSwgCiAgICAgICAgICBjdXJyX21vZGUgPT0gc3RtX3N0YXJ0ID8gInN0YXJ0IiA6IChjdXJyX21vZGUgPT0gc3RtXzE2Yml0ID8gIjE2Yml0IiA6ICIzMmJpdCIpLAogICAgICAgICAgY3Vycl9zd2l0Y2gsIG5leHRfc3dpdGNoKTsKCiAgICByZXR1cm4gVFJVRTsKZG9uZV9lcnI6CiAgICBjdXJyX21vZGUgPSBzdG1fZG9uZTsKICAgIHJldHVybiBGQUxTRTsKfQo=