Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IHBlcmNlcHR1YWwgbm9pc2Ugc3Vic3RpdHV0aW9uIHRvb2wKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJhYWNkZWNfcG5zLmgiCgoKI2luY2x1ZGUgImFhY19yYW0uaCIKI2luY2x1ZGUgImFhY19yb20uaCIKI2luY2x1ZGUgImNoYW5uZWxpbmZvLmgiCiNpbmNsdWRlICJibG9jay5oIgojaW5jbHVkZSAiRkRLX2JpdHN0cmVhbS5oIgoKI2luY2x1ZGUgImdlbmVyaWNTdGRzLmgiCgoKI2RlZmluZSBOT0lTRV9PRkZTRVQgOTAgICAgICAgICAgIC8qIGNmLiBJU08gMTQ0OTYtMyBwLiAxNzUgKi8KCi8qIQogIFxicmllZiBSZXNldCBJbnRlckNoYW5uZWwgYW5kIFBOUyBkYXRhCgogIFRoZSBmdW5jdGlvbiByZXNldHMgdGhlIEludGVyQ2hhbm5lbCBhbmQgUE5TIGRhdGEKKi8Kdm9pZCBDUG5zX1Jlc2V0RGF0YSgKICAgIENQbnNEYXRhICpwUG5zRGF0YSwKICAgIENQbnNJbnRlckNoYW5uZWxEYXRhICpwUG5zSW50ZXJDaGFubmVsRGF0YQogICAgKQp7CiAgLyogQXNzaWduIHBvaW50ZXIgYWx3YXlzLCBzaW5jZSBwUG5zRGF0YSBpcyBub3QgcGVyc2lzdGVudCBkYXRhICovCiAgcFBuc0RhdGEtPnBQbnNJbnRlckNoYW5uZWxEYXRhID0gcFBuc0ludGVyQ2hhbm5lbERhdGE7CiAgcFBuc0RhdGEtPlBuc0FjdGl2ZSA9IDA7CiAgcFBuc0RhdGEtPkN1cnJlbnRFbmVyZ3kgPSAwOwoKICBGREttZW1jbGVhcihwUG5zRGF0YS0+cG5zVXNlZCwoOCoxNikqc2l6ZW9mKFVDSEFSKSk7CiAgRkRLbWVtY2xlYXIocFBuc0ludGVyQ2hhbm5lbERhdGEtPmNvcnJlbGF0ZWQsKDgqMTYpKnNpemVvZihVQ0hBUikpOwp9CgovKiEKICBcYnJpZWYgSW5pdGlhbGl6ZSBQTlMgZGF0YQoKICBUaGUgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIFBOUyBkYXRhCiovCnZvaWQgQ1Buc19Jbml0UG5zKAogICAgQ1Buc0RhdGEgKnBQbnNEYXRhLAogICAgQ1Buc0ludGVyQ2hhbm5lbERhdGEgKnBQbnNJbnRlckNoYW5uZWxEYXRhLAogICAgSU5UKiBjdXJyZW50U2VlZCwgSU5UKiByYW5kb21TZWVkKQp7CiAgLyogc2F2ZSBwb2ludGVyIHRvIGludGVyIGNoYW5uZWwgZGF0YSAqLwogIHBQbnNEYXRhLT5wUG5zSW50ZXJDaGFubmVsRGF0YSA9IHBQbnNJbnRlckNoYW5uZWxEYXRhOwoKICAvKiB1c2UgcG9pbnRlciBiZWNhdXNlIHNlZWQgaGFzIHRvIGJlCiAgICAgc2FtZSwgbGVmdCBhbmQgcmlnaHQgY2hhbm5lbCAhICovCiAgcFBuc0RhdGEtPmN1cnJlbnRTZWVkID0gY3VycmVudFNlZWQ7CiAgcFBuc0RhdGEtPnJhbmRvbVNlZWQgID0gcmFuZG9tU2VlZDsKfQoKLyohCiAgXGJyaWVmIEluZGljYXRlcyBpZiBQTlMgaXMgdXNlZAoKICBUaGUgZnVuY3Rpb24gcmV0dXJucyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciBQTlMgaXMgdXNlZCBvciBub3QKICBhY29yZGRpbmcgdG8gdGhlIG5vaXNlIGVuZXJneQoKICBccmV0dXJuICBQTlMgdXNlZAoqLwppbnQgQ1Buc19Jc1Buc1VzZWQgKGNvbnN0IENQbnNEYXRhICpwUG5zRGF0YSwKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGJhbmQpCnsKICB1bnNpZ25lZCBwbnNfYmFuZCA9IGdyb3VwKjE2K2JhbmQ7CgogIHJldHVybiBwUG5zRGF0YS0+cG5zVXNlZFtwbnNfYmFuZF0gJiAoVUNIQVIpMTsKfQoKLyohCiAgXGJyaWVmIFNldCBjb3JyZWxhdGlvbgoKICBUaGUgZnVuY3Rpb24gYWN0aXZhdGVzIHRoZSBub2lzZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBjaGFubmVsIHBhaXIKKi8Kdm9pZCBDUG5zX1NldENvcnJlbGF0aW9uKENQbnNEYXRhICpwUG5zRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBncm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBiYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG91dG9mcGhhc2UpCnsKICBDUG5zSW50ZXJDaGFubmVsRGF0YSAqcEludGVyQ2hhbm5lbERhdGEgPSBwUG5zRGF0YS0+cFBuc0ludGVyQ2hhbm5lbERhdGE7CiAgdW5zaWduZWQgcG5zX2JhbmQgPSBncm91cCoxNitiYW5kOwoKICBwSW50ZXJDaGFubmVsRGF0YS0+Y29ycmVsYXRlZFtwbnNfYmFuZF0gPSAob3V0b2ZwaGFzZSkgPyAzIDogMTsKfQoKLyohCiAgXGJyaWVmIEluZGljYXRlcyBpZiBjb3JyZWxhdGlvbiBpcyB1c2VkCgogIFRoZSBmdW5jdGlvbiBpbmRpY2F0ZXMgaWYgdGhlIG5vaXNlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIGNoYW5uZWwgcGFpcgogIGlzIGFjdGl2YXRlZAoKICBccmV0dXJuICBQTlMgaXMgY29ycmVsYXRlZAoqLwpzdGF0aWMKaW50IENQbnNfSXNDb3JyZWxhdGVkKGNvbnN0IENQbnNEYXRhICpwUG5zRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBncm91cCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBiYW5kKQp7CiAgQ1Buc0ludGVyQ2hhbm5lbERhdGEgKnBJbnRlckNoYW5uZWxEYXRhID0gcFBuc0RhdGEtPnBQbnNJbnRlckNoYW5uZWxEYXRhOwogIHVuc2lnbmVkIHBuc19iYW5kID0gZ3JvdXAqMTYrYmFuZDsKCiAgcmV0dXJuIChwSW50ZXJDaGFubmVsRGF0YS0+Y29ycmVsYXRlZFtwbnNfYmFuZF0gJiAweDAxKSA/IDEgOiAwOwp9CgovKiEKICBcYnJpZWYgSW5kaWNhdGVzIGlmIGNvcnJlbGF0ZWQgb3V0IG9mIHBoYXNlIG1vZGUgaXMgdXNlZC4KCiAgVGhlIGZ1bmN0aW9uIGluZGljYXRlcyBpZiB0aGUgbm9pc2UgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgY2hhbm5lbCBwYWlyCiAgaXMgYWN0aXZhdGVkIGluIG91dC1vZi1waGFzZSBtb2RlLgoKICBccmV0dXJuICBQTlMgaXMgb3V0LW9mLXBoYXNlCiovCnN0YXRpYwppbnQgQ1Buc19Jc091dE9mUGhhc2UoY29uc3QgQ1Buc0RhdGEgKnBQbnNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGJhbmQpCnsKICBDUG5zSW50ZXJDaGFubmVsRGF0YSAqcEludGVyQ2hhbm5lbERhdGEgPSBwUG5zRGF0YS0+cFBuc0ludGVyQ2hhbm5lbERhdGE7CiAgdW5zaWduZWQgcG5zX2JhbmQgPSBncm91cCoxNitiYW5kOwoKICByZXR1cm4gKHBJbnRlckNoYW5uZWxEYXRhLT5jb3JyZWxhdGVkW3Buc19iYW5kXSAmIDB4MDIpID8gMSA6IDA7Cn0KCi8qIQogIFxicmllZiBSZWFkIFBOUyBpbmZvcm1hdGlvbgoKICBUaGUgZnVuY3Rpb24gcmVhZHMgdGhlIFBOUyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBiaXRzdHJlYW0KKi8Kdm9pZCBDUG5zX1JlYWQgKENQbnNEYXRhICpwUG5zRGF0YSwKICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgICAgICAgICAgY29uc3QgQ29kZUJvb2tEZXNjcmlwdGlvbiAqaGNiLAogICAgICAgICAgICAgICAgU0hPUlQgKnBTY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIFVDSEFSIGdsb2JhbF9nYWluLAogICAgICAgICAgICAgICAgaW50IGJhbmQsCiAgICAgICAgICAgICAgICBpbnQgZ3JvdXAgLyogPSAwICovKQp7CiAgaW50IGRlbHRhIDsKICBVSU5UIHBuc19iYW5kID0gZ3JvdXAqMTYrYmFuZDsKCiAgaWYgKHBQbnNEYXRhLT5QbnNBY3RpdmUpIHsKICAgIC8qIE5leHQgUE5TIGJhbmQgY2FzZSAqLwogICAgZGVsdGEgPSBDQmxvY2tfRGVjb2RlSHVmZm1hbldvcmQgKGJzLCBoY2IpIC0gNjA7CiAgfSBlbHNlIHsKICAgIC8qIEZpcnN0IFBOUyBiYW5kIGNhc2UgKi8KICAgIGludCBub2lzZVN0YXJ0VmFsdWUgPSBGREtyZWFkQml0cyhicyw5KTsKCiAgICBkZWx0YSA9IG5vaXNlU3RhcnRWYWx1ZSAtIDI1NiA7CiAgICBwUG5zRGF0YS0+UG5zQWN0aXZlID0gMTsKICAgIHBQbnNEYXRhLT5DdXJyZW50RW5lcmd5ID0gZ2xvYmFsX2dhaW4gLSBOT0lTRV9PRkZTRVQ7CiAgfQoKICBwUG5zRGF0YS0+Q3VycmVudEVuZXJneSArPSBkZWx0YSA7CiAgcFNjYWxlRmFjdG9yW3Buc19iYW5kXSA9IHBQbnNEYXRhLT5DdXJyZW50RW5lcmd5OwoKICBwUG5zRGF0YS0+cG5zVXNlZFtwbnNfYmFuZF0gPSAxOwp9CgoKLyoqCiAqIFxicmllZiBHZW5lcmF0ZSBhIHZlY3RvciBvZiBub2lzZSBvZiBnaXZlbiBsZW5ndGguIFRoZSBub2lzZSB2YWx1ZXMgYXJlCiAqICAgICAgICBzY2FsZWQgaW4gb3JkZXIgdG8geWllbGQgYSBub2lzZSBlbmVyZ3kgb2YgMS4wCiAqIFxwYXJhbSBzcGVjIHBvaW50ZXIgdG8gd2VyZSB0aGUgbm9pc2UgdmFsdWVzIHdpbGwgYmUgd3JpdHRlbiB0by4KICogXHBhcmFtIHNpemUgYW1vdW50IG9mIG5vaXNlIHZhbHVlcyB0byBiZSBnZW5lcmF0ZWQuCiAqIFxwYXJhbSBwUmFuZG9tU3RhdGUgcG9pbnRlciB0byB0aGUgc3RhdGUgb2YgdGhlIHJhbmRvbSBnZW5lcmF0b3IgYmVpbmcgdXNlZC4KICogXHJldHVybiBleHBvbmVudCBvZiBnZW5lcmF0ZWQgbm9pc2UgdmVjdG9yLgogKi8Kc3RhdGljIGludCBHZW5lcmF0ZVJhbmRvbVZlY3RvciAoRklYUF9EQkwgKlJFU1RSSUNUIHNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqcFJhbmRvbVN0YXRlKQp7CiAgaW50IGksIGludk5yZ19lID0gMCwgbnJnX2UgPSAwOwogIEZJWFBfREJMIGludk5yZ19tLCBucmdfbSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpIDsKICBGSVhQX0RCTCAqUkVTVFJJQ1QgcHRyID0gc3BlYzsKICBpbnQgcmFuZG9tU3RhdGUgPSAqcFJhbmRvbVN0YXRlOwoKI2RlZmluZSBHRU5fTk9JU0VfTlJHX1NDQUxFIDcKCiAgLyogR2VuZXJhdGUgbm9pc2UgYW5kIGNhbGN1bGF0ZSBlbmVyZ3kuICovCiAgZm9yIChpPTA7IGk8c2l6ZTsgaSsrKQogIHsKICAgIHJhbmRvbVN0YXRlID0gKDE2NjQ1MjVMICogcmFuZG9tU3RhdGUpICsgMTAxMzkwNDIyM0w7IC8vIE51bWVyaWNhbCBSZWNpcGVzCiAgICBucmdfbSA9IGZQb3cyQWRkRGl2MihucmdfbSwgKEZJWFBfREJMKXJhbmRvbVN0YXRlPj5HRU5fTk9JU0VfTlJHX1NDQUxFKTsKICAgICpwdHIrKyA9IChGSVhQX0RCTClyYW5kb21TdGF0ZTsKICB9CiAgbnJnX2UgPSBHRU5fTk9JU0VfTlJHX1NDQUxFKjIgKyAxOwoKICAvKiB3ZWlnaHQgbm9pc2Ugd2l0aCA9IDEgLyBzcXJ0X25yZzsgKi8KICBpbnZOcmdfbSA9IGludlNxcnROb3JtMihucmdfbTw8MSwgJmludk5yZ19lKTsKICBpbnZOcmdfZSArPSAtKChucmdfZS0xKT4+MSk7CgogIGZvciAoaT1zaXplOyBpLS07ICkKICB7CiAgICBzcGVjW2ldID0gZk11bHQoc3BlY1tpXSwgaW52TnJnX20pOwogIH0KCiAgLyogU3RvcmUgcmFuZG9tIHN0YXRlICovCiAgKnBSYW5kb21TdGF0ZSA9IHJhbmRvbVN0YXRlOwoKICByZXR1cm4gaW52TnJnX2U7Cn0KCnN0YXRpYyB2b2lkIFNjYWxlQmFuZCAoRklYUF9EQkwgKlJFU1RSSUNUIHNwZWMsIGludCBzaXplLCBpbnQgc2NhbGVGYWN0b3IsIGludCBzcGVjU2NhbGUsIGludCBub2lzZV9lLCBpbnQgb3V0X29mX3BoYXNlKQp7CiAgaW50IGksIHNoaWZ0LCBzZkV4cG9uZW50OwogIEZJWFBfREJMIHNmTWF0aXNzYTsKCiAgLyogR2V0IGdhaW4gZnJvbSBzY2FsZSBmYWN0b3IgdmFsdWUgPSAyXihzY2FsZUZhY3RvciAqIDAuMjUpICovCiAgc2ZNYXRpc3NhID0gTWFudGlzc2FUYWJsZVtzY2FsZUZhY3RvciAmIDB4MDNdWzBdOwogIC8qIHNmRXhwb25lbnQgPSAoc2NhbGVGYWN0b3IgPj4gMikgKyBFeHBvbmVudFRhYmxlW3NjYWxlRmFjdG9yICYgMHgwM11bMF07ICovCiAgLyogTm90ZTogIEV4cG9uZW50VGFibGVbc2NhbGVGYWN0b3IgJiAweDAzXVswXSBpcyBhbHdheXMgMS4gKi8KICBzZkV4cG9uZW50ID0gKHNjYWxlRmFjdG9yID4+IDIpICsgMTsKCiAgaWYgKG91dF9vZl9waGFzZSAhPSAwKSB7CiAgICBzZk1hdGlzc2EgPSAtc2ZNYXRpc3NhOwogIH0KCiAgLyogKzEgYmVjYXVzZSBvZiBmTXVsdERpdjIgYmVsb3cuICovCiAgc2hpZnQgPSBzZkV4cG9uZW50IC0gc3BlY1NjYWxlICsgMSArIG5vaXNlX2U7CgogIC8qIEFwcGx5IGdhaW4gdG8gbm9pc2UgdmFsdWVzICovCiAgaWYgKHNoaWZ0Pj0wKSB7CiAgICBzaGlmdCA9IGZpeE1pbiggc2hpZnQsIERGUkFDVF9CSVRTLTEgKTsKICAgIGZvciAoaSA9IHNpemUgOyBpLS0gIT0gMDsgKSB7CiAgICAgIHNwZWMgW2ldID0gZk11bHREaXYyIChzcGVjIFtpXSwgc2ZNYXRpc3NhKSA8PCBzaGlmdDsKICAgIH0KICB9IGVsc2UgewogICAgc2hpZnQgPSBmaXhNaW4oIC1zaGlmdCwgREZSQUNUX0JJVFMtMSApOwogICAgZm9yIChpID0gc2l6ZSA7IGktLSAhPSAwOyApIHsKICAgICAgc3BlYyBbaV0gPSBmTXVsdERpdjIgKHNwZWMgW2ldLCBzZk1hdGlzc2EpID4+IHNoaWZ0OwogICAgfQogIH0KfQoKCi8qIQogIFxicmllZiBBcHBseSBQTlMKCiAgVGhlIGZ1bmN0aW9uIGFwcGxpZXMgUE5TIChpLmUuIGl0IGdlbmVyYXRlcyBub2lzZSkgb24gdGhlIGJhbmRzCiAgZmxhZ2dlZCBhcyBub2lzeSBiYW5kcwoKKi8Kdm9pZCBDUG5zX0FwcGx5IChjb25zdCBDUG5zRGF0YSAqcFBuc0RhdGEsCiAgICAgICAgICAgICAgICAgY29uc3QgQ0ljc0luZm8gKnBJY3NJbmZvLAogICAgICAgICAgICAgICAgIFNQRUNUUkFMX1BUUiBwU3BlY3RydW0sCiAgICAgICAgICAgICAgICAgY29uc3QgU0hPUlQgICAgKnBTcGVjU2NhbGUsCiAgICAgICAgICAgICAgICAgY29uc3QgU0hPUlQgICAgKnBTY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICBjb25zdCBJTlQgZ3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICBjb25zdCBpbnQgY2hhbm5lbCkKewogIGlmIChwUG5zRGF0YS0+UG5zQWN0aXZlKSB7CiAgICBjb25zdCBzaG9ydCAqQmFuZE9mZnNldHMgPSBHZXRTY2FsZUZhY3RvckJhbmRPZmZzZXRzKHBJY3NJbmZvLCBwU2FtcGxpbmdSYXRlSW5mbyk7CgogICAgaW50IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCA9IEdldFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZChwSWNzSW5mbyk7CgogICAgZm9yIChpbnQgd2luZG93ID0gMCwgZ3JvdXAgPSAwOyBncm91cCA8IEdldFdpbmRvd0dyb3VwcyhwSWNzSW5mbyk7IGdyb3VwKyspIHsKICAgICAgZm9yIChpbnQgZ3JvdXB3aW4gPSAwOyBncm91cHdpbiA8IEdldFdpbmRvd0dyb3VwTGVuZ3RoKHBJY3NJbmZvLCBncm91cCk7IGdyb3Vwd2luKyssIHdpbmRvdysrKSB7CiAgICAgICAgRklYUF9EQkwgKnNwZWN0cnVtID0gU1BFQyhwU3BlY3RydW0sIHdpbmRvdywgZ3JhbnVsZUxlbmd0aCk7CgogICAgICAgIGZvciAoaW50IGJhbmQgPSAwIDsgYmFuZCA8IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZDsgYmFuZCsrKSB7CiAgICAgICAgICBpZiAoQ1Buc19Jc1Buc1VzZWQgKHBQbnNEYXRhLCBncm91cCwgYmFuZCkpIHsKICAgICAgICAgICAgVUlOVCBwbnNfYmFuZCA9IGdyb3VwKjE2K2JhbmQ7CgogICAgICAgICAgICBpbnQgYmFuZFdpZHRoID0gQmFuZE9mZnNldHMgW2JhbmQgKyAxXSAtIEJhbmRPZmZzZXRzIFtiYW5kXSA7CiAgICAgICAgICAgIGludCBub2lzZV9lOwoKICAgICAgICAgICAgRkRLX0FTU0VSVChiYW5kV2lkdGggPj0gMCk7CgogICAgICAgICAgICBpZiAoY2hhbm5lbCA+IDAgJiYgQ1Buc19Jc0NvcnJlbGF0ZWQocFBuc0RhdGEsIGdyb3VwLCBiYW5kKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgIG5vaXNlX2UgPSBHZW5lcmF0ZVJhbmRvbVZlY3RvciAoc3BlY3RydW0gKyBCYW5kT2Zmc2V0cyBbYmFuZF0sIGJhbmRXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBQbnNEYXRhLT5yYW5kb21TZWVkIFtwbnNfYmFuZF0pIDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBwUG5zRGF0YS0+cmFuZG9tU2VlZCBbcG5zX2JhbmRdID0gKnBQbnNEYXRhLT5jdXJyZW50U2VlZCA7CgogICAgICAgICAgICAgIG5vaXNlX2UgPSBHZW5lcmF0ZVJhbmRvbVZlY3RvciAoc3BlY3RydW0gKyBCYW5kT2Zmc2V0cyBbYmFuZF0sIGJhbmRXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBuc0RhdGEtPmN1cnJlbnRTZWVkKSA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGludCBvdXRPZlBoYXNlICA9IENQbnNfSXNPdXRPZlBoYXNlIChwUG5zRGF0YSwgZ3JvdXAsIGJhbmQpOwoKICAgICAgICAgICAgU2NhbGVCYW5kIChzcGVjdHJ1bSArIEJhbmRPZmZzZXRzIFtiYW5kXSwgYmFuZFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgIHBTY2FsZUZhY3RvcltwbnNfYmFuZF0sCiAgICAgICAgICAgICAgICAgICAgICAgcFNwZWNTY2FsZVt3aW5kb3ddLCBub2lzZV9lLCBvdXRPZlBoYXNlKSA7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9Cg==