Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBEYW5pZWwgSG9tbQogICBEZXNjcmlwdGlvbjoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJ0cGRlY19sYXRtLmgiCgoKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKCgojZGVmaW5lIFRQREVDX1RSQUNLSU5ERVgocCxsKSAoMioocCkgKyAobCkpCgpzdGF0aWMKVUlOVCBDTGF0bURlbXV4X0dldFZhbHVlKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzKQp7CiAgVUNIQVIgYnl0ZXNGb3JWYWx1ZSA9IDAsIHRtcCA9IDA7CiAgaW50IHZhbHVlID0gMDsKCiAgYnl0ZXNGb3JWYWx1ZSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CgogIGZvciAoVUlOVCBpPTA7IGk8PWJ5dGVzRm9yVmFsdWU7IGkrKykgewogICAgdmFsdWUgPDw9IDg7CiAgICB0bXAgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDgpOwogICAgdmFsdWUgKz0gdG1wOwogIH0KCiAgcmV0dXJuIHZhbHVlOwp9CgoKc3RhdGljClRSQU5TUE9SVERFQ19FUlJPUiBDTGF0bURlbXV4X1JlYWRBdWRpb011eEVsZW1lbnQoCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgQ0xhdG1EZW11eCAqcExhdG1EZW11eCwKICAgICAgICBpbnQgbV9tdXhDb25maWdQcmVzZW50LAogICAgICAgIENTVHBDYWxsQmFja3MgKnBUcERlY0NhbGxiYWNrcywKICAgICAgICBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKnBBc2MsCiAgICAgICAgaW50ICpwZkNvbmZpZ0ZvdW5kCiAgICAgICAgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX09LOwoKICBpZiAobV9tdXhDb25maWdQcmVzZW50KSB7CiAgICBwTGF0bURlbXV4LT5tX3VzZVNhbWVTdHJlYW1NdXggPSBGREtyZWFkQml0cyhicywxKTsKCiAgICBpZiAoIXBMYXRtRGVtdXgtPm1fdXNlU2FtZVN0cmVhbU11eCkgewogICAgICBpZiAoKEVycm9yU3RhdHVzID0gQ0xhdG1EZW11eF9SZWFkU3RyZWFtTXV4Q29uZmlnKGJzLCBwTGF0bURlbXV4LCBwVHBEZWNDYWxsYmFja3MsIHBBc2MsIHBmQ29uZmlnRm91bmQpKSkgewogICAgICAgIHJldHVybiAoRXJyb3JTdGF0dXMpOwogICAgICB9CiAgICB9CiAgfQoKICAvKiBJZiB0aGVyZSB3YXMgbm8gY29uZmlndXJhdGlvbiByZWFkLCBpdHMgbm90IHBvc3NpYmxlIHRvIHBhcnNlIFBheWxvYWRMZW5ndGhJbmZvIGJlbG93LiAqLwogIGlmICghICpwZkNvbmZpZ0ZvdW5kKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgfQoKICBpZiAocExhdG1EZW11eC0+bV9BdWRpb011eFZlcnNpb25BID09IDApIHsKICAgIC8qIERvIG9ubHkgb25jZSBwZXIgY2FsbCwgYmVjYXVzZSBwYXJzaW5nIGFuZCBkZWNvZGluZyBpcyBkb25lIGluLWxpbmUuICovCiAgICBpZiAoKEVycm9yU3RhdHVzID0gQ0xhdG1EZW11eF9SZWFkUGF5bG9hZExlbmd0aEluZm8oYnMscExhdG1EZW11eCkpKSB7CiAgICAgIHJldHVybiAoRXJyb3JTdGF0dXMpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBhdWRpb011eFZlcnNpb25BID4gMCBpcyByZXNlcnZlZCBmb3IgZnV0dXJlIGV4dGVuc2lvbnMgKi8KICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICB9CgogIHJldHVybiAoRXJyb3JTdGF0dXMpOwp9CgpUUkFOU1BPUlRERUNfRVJST1IgQ0xhdG1EZW11eF9SZWFkKAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgIENMYXRtRGVtdXggKnBMYXRtRGVtdXgsCiAgICAgICAgVFJBTlNQT1JUX1RZUEUgdHQsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAqcFRwRGVjQ2FsbGJhY2tzLAogICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqcEFzYywKICAgICAgICBpbnQgKnBmQ29uZmlnRm91bmQsCiAgICAgICAgY29uc3QgSU5UIGlnbm9yZUJ1ZmZlckZ1bGxuZXNzCiAgICAgICAgKQp7CiAgVUlOVCBjbnRCaXRzOwogIFVJTlQgY21wQnVmZmVyRnVsbG5lc3M7CiAgVUlOVCBhdWRpb011eExlbmd0aEJ5dGVzTGFzdCA9IDA7CiAgVFJBTlNQT1JUREVDX0VSUk9SIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX09LOwoKICBjbnRCaXRzID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgaWYgKChJTlQpY250Qml0cyA8IE1JTl9MQVRNX0hFQURFUkxFTkdUSCkgewogICAgcmV0dXJuIFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFM7CiAgfQoKICBpZiAoKEVycm9yU3RhdHVzID0gQ0xhdG1EZW11eF9SZWFkQXVkaW9NdXhFbGVtZW50KGJzLCBwTGF0bURlbXV4LCAodHQgIT0gVFRfTVA0X0xBVE1fTUNQMCksIHBUcERlY0NhbGxiYWNrcywgcEFzYywgcGZDb25maWdGb3VuZCkpKQogICAgcmV0dXJuIChFcnJvclN0YXR1cyk7CgogIGlmICghaWdub3JlQnVmZmVyRnVsbG5lc3MpCiAgewogICAgY21wQnVmZmVyRnVsbG5lc3MgPSAgIDI0K2F1ZGlvTXV4TGVuZ3RoQnl0ZXNMYXN0KjgKICAgICAgICAgICAgICAgICAgICAgICAgKyBwTGF0bURlbXV4LT5tX2xpbmZvWzBdWzBdLm1fYnVmZmVyRnVsbG5lc3MqIHBBc2NbVFBERUNfVFJBQ0tJTkRFWCgwLDApXS5tX2NoYW5uZWxDb25maWd1cmF0aW9uKjMyOwoKICAgIC8qIGV2YWx1YXRlIGJ1ZmZlciBmdWxsbmVzcyAqLwoKICAgIGlmIChwTGF0bURlbXV4LT5tX2xpbmZvWzBdWzBdLm1fYnVmZmVyRnVsbG5lc3MgIT0gMHhGRikKICAgIHsKICAgICAgaWYgKCFwTGF0bURlbXV4LT5CdWZmZXJGdWxsbmVzc0FjaGlldmVkKQogICAgICB7CiAgICAgICAgaWYgKGNudEJpdHMgPCBjbXBCdWZmZXJGdWxsbmVzcykKICAgICAgICB7CiAgICAgICAgICAvKiBjb25kaXRpb24gZm9yIHN0YXJ0IG9mIGRlY29kaW5nIGlzIG5vdCBmdWxmaWxsZWQgKi8KCiAgICAgICAgICAvKiB0aGUgY3VycmVudCBmcmFtZSB3aWxsIG5vdCBiZSBkZWNvZGVkICovCiAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgIHBMYXRtRGVtdXgtPkJ1ZmZlckZ1bGxuZXNzQWNoaWV2ZWQgPSAxOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KCgpUUkFOU1BPUlRERUNfRVJST1IgQ0xhdG1EZW11eF9SZWFkU3RyZWFtTXV4Q29uZmlnKAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgIENMYXRtRGVtdXggKnBMYXRtRGVtdXgsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAqcFRwRGVjQ2FsbGJhY2tzLAogICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqcEFzYywKICAgICAgICBpbnQgKiBwZkNvbmZpZ0ZvdW5kCiAgICAgICAgKQp7CiAgTEFUTV9MQVlFUl9JTkZPICpwX2xpbmZvID0gTlVMTDsKICBUUkFOU1BPUlRERUNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRERUNfT0s7CgogIHBMYXRtRGVtdXgtPm1fQXVkaW9NdXhWZXJzaW9uID0gRkRLcmVhZEJpdHMoYnMsMSk7CgogIGlmIChwTGF0bURlbXV4LT5tX0F1ZGlvTXV4VmVyc2lvbiA9PSAwKSB7CiAgICBwTGF0bURlbXV4LT5tX0F1ZGlvTXV4VmVyc2lvbkEgPSAwOwogIH0gZWxzZSB7CiAgICBwTGF0bURlbXV4LT5tX0F1ZGlvTXV4VmVyc2lvbkEgPSBGREtyZWFkQml0cyhicywxKTsKICB9CgogIGlmIChwTGF0bURlbXV4LT5tX0F1ZGlvTXV4VmVyc2lvbkEgPT0gMCkgewogICAgaWYgKHBMYXRtRGVtdXgtPm1fQXVkaW9NdXhWZXJzaW9uID09IDEpIHsKICAgICAgcExhdG1EZW11eC0+bV90YXJhQnVmZmVyRnVsbG5lc3MgPSBDTGF0bURlbXV4X0dldFZhbHVlKGJzKTsKICAgIH0KICAgIHBMYXRtRGVtdXgtPm1fYWxsU3RyZWFtc1NhbWVUaW1lRnJhbWluZyA9IEZES3JlYWRCaXRzKGJzLDEpOwogICAgcExhdG1EZW11eC0+bV9ub1N1YkZyYW1lcyA9IEZES3JlYWRCaXRzKGJzLDYpICsgMTsKICAgIHBMYXRtRGVtdXgtPm1fbnVtUHJvZ3JhbSAgPSBGREtyZWFkQml0cyhicyw0KSArIDE7CgogICAgaWYgKHBMYXRtRGVtdXgtPm1fbnVtUHJvZ3JhbSA+IDEpIHsKICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9CgogICAgaW50IGlkQ250ID0gMDsKICAgIGZvciAoVUlOVCBwcm9nID0gMDsgcHJvZyA8IHBMYXRtRGVtdXgtPm1fbnVtUHJvZ3JhbTsgcHJvZysrKSB7CiAgICAgIHBMYXRtRGVtdXgtPm1fbnVtTGF5ZXIgPSBGREtyZWFkQml0cyhicywzKSArIDE7CiAgICAgIGlmIChwTGF0bURlbXV4LT5tX251bUxheWVyID4gMikgewogICAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfVU5TVVBQT1JURURfRk9STUFUOwogICAgICB9CgogICAgICBmb3IgKFVJTlQgbGF5ID0gMDsgbGF5IDwgcExhdG1EZW11eC0+bV9udW1MYXllcjsgbGF5KyspIHsKICAgICAgICBwX2xpbmZvID0gJnBMYXRtRGVtdXgtPm1fbGluZm9bcHJvZ11bbGF5XTsKCiAgICAgICAgcF9saW5mby0+bV9zdHJlYW1JRCA9IGlkQ250Kys7CiAgICAgICAgcF9saW5mby0+bV9mcmFtZUxlbmd0aEluQml0cyA9IDA7CgogICAgICAgIGlmKCAocHJvZyA9PSAwKSAmJiAobGF5ID09IDApICkgewogICAgICAgICAgcExhdG1EZW11eC0+bV91c2VTYW1lQ29uZmlnID0gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcExhdG1EZW11eC0+bV91c2VTYW1lQ29uZmlnID0gRkRLcmVhZEJpdHMoYnMsMSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocExhdG1EZW11eC0+bV91c2VTYW1lQ29uZmlnKSB7CiAgICAgICAgICBpZiAobGF5ID4gMSkgewogICAgICAgICAgICBGREttZW1jcHkoJnBBc2NbVFBERUNfVFJBQ0tJTkRFWChwcm9nLGxheSldLCAmcEFzY1tUUERFQ19UUkFDS0lOREVYKHByb2csbGF5LTEpXSwgc2l6ZW9mKENTQXVkaW9TcGVjaWZpY0NvbmZpZykpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHBMYXRtRGVtdXgtPm1fQXVkaW9NdXhWZXJzaW9uID09IDEpCiAgICAgICAgICB7CiAgICAgICAgICAgIEZES19CSVRTVFJFQU0gdG1wQnM7CiAgICAgICAgICAgIFVJTlQgYXNjU3RhcnRQb3MsIGFzY0xlbj0wOwoKICAgICAgICAgICAgYXNjTGVuID0gQ0xhdG1EZW11eF9HZXRWYWx1ZShicyk7CiAgICAgICAgICAgIGFzY1N0YXJ0UG9zID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKICAgICAgICAgICAgdG1wQnMgPSAqYnM7CiAgICAgICAgICAgIEZES3N5bmNDYWNoZSgmdG1wQnMpOwogICAgICAgICAgICB0bXBCcy5oQml0QnVmLlZhbGlkQml0cyA9IGFzY0xlbjsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIFJlYWQgQVNDICovCiAgICAgICAgICAgIGlmICgoRXJyb3JTdGF0dXMgPSBBdWRpb1NwZWNpZmljQ29uZmlnX1BhcnNlKCZwQXNjW1RQREVDX1RSQUNLSU5ERVgocHJvZyxsYXkpXSwgJnRtcEJzLCAxLCBwVHBEZWNDYWxsYmFja3MpKSkgewogICAgICAgICAgICAgIHJldHVybiAoRXJyb3JTdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICpwZkNvbmZpZ0ZvdW5kID0gMTsKCiAgICAgICAgICAgIC8qIFRoZSBmaWVsZCBwX2xpbmZvLT5tX2FzY0xlbiBjb3VsZCBiZSB3cm9uZywgc28gY2hlY2sgaWYgKi8KICAgICAgICAgICAgaWYgKCAwID4gKElOVClGREtnZXRWYWxpZEJpdHMoJnRtcEJzKSkgewogICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRkRLcHVzaEZvcihicywgYXNjTGVuKTsgLyogcG9zaXRpb24gYml0c3RyZWFtIGFmdGVyIEFTQyAqLwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qIFJlYWQgQVNDICovCiAgICAgICAgICAgIGlmICgoRXJyb3JTdGF0dXMgPSBBdWRpb1NwZWNpZmljQ29uZmlnX1BhcnNlKCZwQXNjW1RQREVDX1RSQUNLSU5ERVgocHJvZyxsYXkpXSwgYnMsIDAsIHBUcERlY0NhbGxiYWNrcykpKSB7CiAgICAgICAgICAgICAgcmV0dXJuIChFcnJvclN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHsKICAgICAgICAgICAgaW50IGNiRXJyb3I7CgogICAgICAgICAgICBjYkVycm9yID0gcFRwRGVjQ2FsbGJhY2tzLT5jYlVwZGF0ZUNvbmZpZyhwVHBEZWNDYWxsYmFja3MtPmNiVXBkYXRlQ29uZmlnRGF0YSwgJnBBc2NbVFBERUNfVFJBQ0tJTkRFWChwcm9nLGxheSldKTsKICAgICAgICAgICAgaWYgKGNiRXJyb3IgIT0gMCkgewogICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfVU5LT1dOX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgICAgICpwZkNvbmZpZ0ZvdW5kID0gMTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHBfbGluZm8tPm1fZnJhbWVMZW5ndGhUeXBlID0gRkRLcmVhZEJpdHMoYnMsMyk7CiAgICAgICAgc3dpdGNoKCBwX2xpbmZvLT5tX2ZyYW1lTGVuZ3RoVHlwZSApIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICBwX2xpbmZvLT5tX2J1ZmZlckZ1bGxuZXNzID0gRkRLcmVhZEJpdHMoYnMsOCk7CgogICAgICAgICAgaWYgKCFwTGF0bURlbXV4LT5tX2FsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcpIHsKICAgICAgICAgICAgaWYgKChsYXkgPiAwKSAmJiAocEFzY1tUUERFQ19UUkFDS0lOREVYKHByb2csbGF5KV0ubV9hb3QgPT0gQU9UX0FBQ19TQ0FMIHx8IHBBc2NbVFBERUNfVFJBQ0tJTkRFWChwcm9nLGxheSldLm1fYW90ID09IEFPVF9FUl9BQUNfU0NBTCkpIHsKICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgLyogZnJhbWVMZW5ndGggPSBGREtyZWFkQml0cyhicyw5KTsgKi8KICAgICAgICBjYXNlIDM6CiAgICAgICAgY2FzZSA0OgogICAgICAgIGNhc2UgNToKICAgICAgICAgIC8qIENFTFAgKi8KICAgICAgICBjYXNlIDY6CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgLyogSFZYQyAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOyAvL19MQVRNX0lOVkFMSURGUkFNRUxFTkdUSFRZUEU7CgogICAgICAgIH0gIC8qIHN3aXRjaCBmcmFtZWxlbmd0aHR5cGUqLwoKICAgICAgfSAgLyogbGF5ZXIgbG9vcCAqLwogICAgfSAgLyogcHJvZyBsb29wICovCgogICAgcExhdG1EZW11eC0+bV9vdGhlckRhdGFQcmVzZW50ID0gRkRLcmVhZEJpdHMoYnMsMSk7CiAgICBwTGF0bURlbXV4LT5tX290aGVyRGF0YUxlbmd0aCAgPSAwOwoKICAgIGlmIChwTGF0bURlbXV4LT5tX290aGVyRGF0YVByZXNlbnQpIHsKICAgICAgaW50IG90aGVyRGF0YUxlbkVzYyAgPSAwOwogICAgICBkbyB7CiAgICAgICAgcExhdG1EZW11eC0+bV9vdGhlckRhdGFMZW5ndGggPDw9IDg7ICAgLy8gKj0gMjU2CiAgICAgICAgb3RoZXJEYXRhTGVuRXNjID0gRkRLcmVhZEJpdHMoYnMsMSk7CiAgICAgICAgcExhdG1EZW11eC0+bV9vdGhlckRhdGFMZW5ndGggKz0gRkRLcmVhZEJpdHMoYnMsOCk7CiAgICAgIH0gd2hpbGUgKG90aGVyRGF0YUxlbkVzYyk7CiAgICB9CgogICAgcExhdG1EZW11eC0+bV9jcmNDaGVja1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywxKTsKICAgIHBMYXRtRGVtdXgtPm1fY3JjQ2hlY2tTdW0gICAgID0gMDsKCiAgICBpZiAocExhdG1EZW11eC0+bV9jcmNDaGVja1ByZXNlbnQpIHsKICAgICAgcExhdG1EZW11eC0+bV9jcmNDaGVja1N1bSA9IEZES3JlYWRCaXRzKGJzLDgpOwogICAgfQoKICB9CiAgZWxzZSB7CiAgICAvKiBhdWRpb011eFZlcnNpb25BID4gMCBpcyByZXNlcnZlZCBmb3IgZnV0dXJlIGV4dGVuc2lvbnMgKi8KICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICB9CiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KClRSQU5TUE9SVERFQ19FUlJPUiBDTGF0bURlbXV4X1JlYWRQYXlsb2FkTGVuZ3RoSW5mbyhIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywgQ0xhdG1EZW11eCAqcExhdG1EZW11eCkKewogIFRSQU5TUE9SVERFQ19FUlJPUiBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVERFQ19PSzsKICBpbnQgdG90YWxQYXlsb2FkQml0cyA9IDA7CgogIGlmKCBwTGF0bURlbXV4LT5tX2FsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgPT0gMSApIHsKICAgIGZvciAoVUlOVCBwcm9nPTA7IHByb2c8cExhdG1EZW11eC0+bV9udW1Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICAgIGZvciAoVUlOVCBsYXk9MDsgbGF5PHBMYXRtRGVtdXgtPm1fbnVtTGF5ZXI7IGxheSsrICkgewogICAgICAgIExBVE1fTEFZRVJfSU5GTyAqcF9saW5mbyA9ICZwTGF0bURlbXV4LT5tX2xpbmZvW3Byb2ddW2xheV07CgogICAgICAgIHN3aXRjaCAocF9saW5mby0+bV9mcmFtZUxlbmd0aFR5cGUgKSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgcF9saW5mby0+bV9mcmFtZUxlbmd0aEluQml0cyA9IENMYXRtRGVtdXhfUmVhZEF1Q2h1bmtMZW5ndGhJbmZvKGJzKTsKICAgICAgICAgIHRvdGFsUGF5bG9hZEJpdHMgKz0gcF9saW5mby0+bV9mcmFtZUxlbmd0aEluQml0czsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICBjYXNlIDU6CiAgICAgICAgY2FzZSA3OgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOyAvL0FBQ19ERUNfTEFUTV9JTlZBTElERlJBTUVMRU5HVEhUWVBFOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICBlbHNlIHsKICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOyAvL0FBQ19ERUNfTEFUTV9USU1FRlJBTUlORzsKICB9CiAgaWYgKHBMYXRtRGVtdXgtPm1fYXVkaW9NdXhMZW5ndGhCeXRlcyA+IChVSU5UKTAgJiYgdG90YWxQYXlsb2FkQml0cyA+IChpbnQpcExhdG1EZW11eC0+bV9hdWRpb011eExlbmd0aEJ5dGVzKjgpIHsKICAgIHJldHVybiBUUkFOU1BPUlRERUNfUEFSU0VfRVJST1I7CiAgfQogIHJldHVybiAoRXJyb3JTdGF0dXMpOwp9CgppbnQgQ0xhdG1EZW11eF9SZWFkQXVDaHVua0xlbmd0aEluZm8oSEFORExFX0ZES19CSVRTVFJFQU0gYnMpCnsKICBVQ0hBUiBlbmRGbGFnOwogIGludCBsZW4gPSAwOwoKICBkbyB7CiAgICBVQ0hBUiB0bXAgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDgpOwogICAgZW5kRmxhZyA9ICh0bXAgPCAyNTUpOwoKICAgIGxlbiArPSB0bXA7CgogIH0gd2hpbGUoIGVuZEZsYWcgPT0gMCApOwoKICBsZW4gPDw9IDM7ICAvKiBjb252ZXJ0IGZyb20gYnl0ZXMgdG8gYml0cyAqLwoKICByZXR1cm4gbGVuOwp9CgppbnQgQ0xhdG1EZW11eF9HZXRGcmFtZUxlbmd0aEluQml0cyhDTGF0bURlbXV4ICpwTGF0bURlbXV4KQp7CiAgcmV0dXJuIHBMYXRtRGVtdXgtPm1fbGluZm9bMF1bMF0ubV9mcmFtZUxlbmd0aEluQml0czsKfQoKaW50IENMYXRtRGVtdXhfR2V0T3RoZXJEYXRhUHJlc2VudEZsYWcoQ0xhdG1EZW11eCAqcExhdG1EZW11eCkKewogIHJldHVybiBwTGF0bURlbXV4LT5tX290aGVyRGF0YVByZXNlbnQgPyAxIDogMDsKfQoKaW50IENMYXRtRGVtdXhfR2V0T3RoZXJEYXRhTGVuZ3RoKENMYXRtRGVtdXggKnBMYXRtRGVtdXgpCnsKICByZXR1cm4gcExhdG1EZW11eC0+bV9vdGhlckRhdGFMZW5ndGg7Cn0KClVJTlQgQ0xhdG1EZW11eF9HZXROck9mU3ViRnJhbWVzKENMYXRtRGVtdXggKnBMYXRtRGVtdXgpCnsKICByZXR1cm4gcExhdG1EZW11eC0+bV9ub1N1YkZyYW1lczsKfQoK