Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBNYW51ZWwgSmFuZGVyCiAgIERlc2NyaXB0aW9uOgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2RlY29kZXJfbGliLmgiCgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiYWFjZGVjb2Rlci5oIgojaW5jbHVkZSAidHBkZWNfbGliLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbiBpbmZvICovCgoKICNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgoKCgojaW5jbHVkZSAiY29uY2VhbC5oIgoKICNpbmNsdWRlICJhYWNkZWNfZHJjLmgiCgoKCi8qIERlY29kZXIgbGlicmFyeSBpbmZvICovCiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfVkwwIDIKI2RlZmluZSBBQUNERUNPREVSX0xJQl9WTDEgNQojZGVmaW5lIEFBQ0RFQ09ERVJfTElCX1ZMMiA5CiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfVElUTEUgIkFBQyBEZWNvZGVyIExpYiIKI2RlZmluZSBBQUNERUNPREVSX0xJQl9CVUlMRF9EQVRFIF9fREFURV9fCiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfQlVJTERfVElNRSBfX1RJTUVfXwoKc3RhdGljIEFBQ19ERUNPREVSX0VSUk9SCnNldENvbmNlYWxNZXRob2QgKCBjb25zdCBIQU5ETEVfQUFDREVDT0RFUiAgc2VsZiwKICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICBtZXRob2QgKTsKCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9HZXRGcmVlQnl0ZXMgKCBjb25zdCBIQU5ETEVfQUFDREVDT0RFUiAgc2VsZiwgVUlOVCAqcEZyZWVCeXRlcyl7CgogIC8qIHJlc2V0IGZyZWUgYnl0ZXMgKi8KICAqcEZyZWVCeXRlcyA9IDA7CgogIC8qIGNoZWNrIGhhbmRsZSAqLwogIGlmKCFzZWxmKQogICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CgogIC8qIHJldHVybiBuciBvZiBmcmVlIGJ5dGVzICovCiAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzID0gdHJhbnNwb3J0RGVjX0dldEJpdHN0cmVhbShzZWxmLT5oSW5wdXQsIDApOwogICpwRnJlZUJ5dGVzID0gRkRLZ2V0RnJlZUJpdHMoaEJzKSA+PiAzOwoKICAvKiBzdWNjZXNzICovCiAgcmV0dXJuIEFBQ19ERUNfT0s7Cn0KCi8qKgogKiBDb25maWcgRGVjb2RlciB1c2luZyBhIENTQXVkaW9TcGVjaWZpY0NvbmZpZyBzdHJ1Y3QuCiAqLwpzdGF0aWMKTElOS1NQRUNfQ1BQIEFBQ19ERUNPREVSX0VSUk9SIGFhY0RlY29kZXJfQ29uZmlnKEhBTkRMRV9BQUNERUNPREVSIHNlbGYsIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqcEFzY1N0cnVjdCkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycjsKCiAgLyogSW5pdGlhbGl6ZSBBQUMgY29yZSBkZWNvZGVyLCBhbmQgdXBkYXRlIHNlbGYtPnN0cmVhbWluZm8gKi8KICBlcnIgPSBDQWFjRGVjb2Rlcl9Jbml0KHNlbGYsIHBBc2NTdHJ1Y3QpOwoKICByZXR1cm4gZXJyOwp9CgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9Db25maWdSYXcgKAogICAgICAgIEhBTkRMRV9BQUNERUNPREVSIHNlbGYsCiAgICAgICAgVUNIQVIgKmNvbmZbXSwKICAgICAgICBjb25zdCBVSU5UIGxlbmd0aFtdICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVyciA9IEFBQ19ERUNfT0s7CiAgVFJBTlNQT1JUREVDX0VSUk9SICAgZXJyVHA7CiAgVUlOVCBsYXllciwgbnJPZkxheWVycyA9IHNlbGYtPm5yT2ZMYXllcnM7CgogIGZvcihsYXllciA9IDA7IGxheWVyIDwgbnJPZkxheWVyczsgbGF5ZXIrKyl7CiAgICBpZihsZW5ndGhbbGF5ZXJdID4gMCl7CiAgICAgIGVyclRwID0gdHJhbnNwb3J0RGVjX091dE9mQmFuZENvbmZpZyhzZWxmLT5oSW5wdXQsIGNvbmZbbGF5ZXJdLCBsZW5ndGhbbGF5ZXJdLCBsYXllcik7CiAgICAgIGlmIChlcnJUcCAhPSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICBzd2l0Y2ggKGVyclRwKSB7CiAgICAgICAgY2FzZSBUUkFOU1BPUlRERUNfTkVFRF9UT19SRVNUQVJUOgogICAgICAgICAgZXJyID0gQUFDX0RFQ19ORUVEX1RPX1JFU1RBUlQ7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ6CiAgICAgICAgICBlcnIgPSBBQUNfREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBlcnIgPSBBQUNfREVDX1VOS05PV047CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogaWYgYmFzZWxheWVyIGlzIE9LIHdlIGNvbnRpbnVlIGRlY29kaW5nICovCiAgICAgICAgaWYobGF5ZXIgID49IDEpewogICAgICAgICAgc2VsZi0+bnJPZkxheWVycyA9IGxheWVyOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGVycjsKfQoKCgpzdGF0aWMgSU5UIGFhY0RlY29kZXJfQ29uZmlnQ2FsbGJhY2sodm9pZCAqaGFuZGxlLCBjb25zdCBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKnBBc2NTdHJ1Y3QpCnsKICBIQU5ETEVfQUFDREVDT0RFUiBzZWxmID0gKEhBTkRMRV9BQUNERUNPREVSKWhhbmRsZTsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnIgPSBBQUNfREVDX09LOwogIFRSQU5TUE9SVERFQ19FUlJPUiBlcnJUcDsKCiAgewogICAgewogICAgICBlcnIgPSBhYWNEZWNvZGVyX0NvbmZpZyhzZWxmLCBwQXNjU3RydWN0KTsKICAgIH0KICB9CiAgaWYgKGVyciA9PSBBQUNfREVDX09LKSB7CiAgICBpZiAoIHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0xEfEFDX0VMRCkKICAgICAgJiYgQ0NvbmNlYWxtZW50X0dldERlbGF5KCZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSkgPiAwICkKICAgIHsKICAgICAgLyogUmV2ZXJ0IHRvIGVycm9yIGNvbmNlYWxtZW50IG1ldGhvZCBOb2lzZSBTdWJzdGl0dXRpb24uCiAgICAgICAgIEJlY2F1c2UgaW50ZXJwb2xhdGlvbiBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIFVTQUMvUlNWRDUwIG9yCiAgICAgICAgIHRoZSBhZGRpdGlvbmFsIGRlbGF5IGlzIHVud2FudGVkIGZvciBsb3cgZGVsYXkgY29kZWNzLiAqLwogICAgICBzZXRDb25jZWFsTWV0aG9kKHNlbGYsIDEpOwojaWZkZWYgREVCVUcKICAgICAgRkRLcHJpbnRmKCIgIENvbmNlYWxtZW50IG1ldGhvZCB3YXMgcmV2ZXJ0ZWQgdG8gMSAhXG4iKTsKI2VuZGlmCiAgICB9CiAgICBlcnJUcCA9IFRSQU5TUE9SVERFQ19PSzsKICB9IGVsc2UgewogICAgaWYgKElTX0lOSVRfRVJST1IoZXJyKSkgewogICAgICBlcnJUcCA9IFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9IC8qIEZhdGFsIGVycm9ycyAqLwogICAgZWxzZSBpZiAoZXJyID09IEFBQ19ERUNfTkVFRF9UT19SRVNUQVJUKSB7CiAgICAgIGVyclRwID0gVFJBTlNQT1JUREVDX05FRURfVE9fUkVTVEFSVDsKICAgIH0gZWxzZSB7CiAgICAgIGVyclRwID0gVFJBTlNQT1JUREVDX1VOS09XTl9FUlJPUjsKICAgIH0KICB9CgogIHJldHVybiBlcnJUcDsKfQoKCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IKYWFjRGVjb2Rlcl9BbmNEYXRhSW5pdCAoIEhBTkRMRV9BQUNERUNPREVSIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgKQp7CiAgQ0FuY0RhdGEgKmFuY0RhdGEgPSAmc2VsZi0+YW5jRGF0YTsKCiAgcmV0dXJuIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KGFuY0RhdGEsIGJ1ZmZlciwgc2l6ZSk7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IKYWFjRGVjb2Rlcl9BbmNEYXRhR2V0ICggSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKipwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAqc2l6ZSApCnsKICBDQW5jRGF0YSAqYW5jRGF0YSA9ICZzZWxmLT5hbmNEYXRhOwoKICByZXR1cm4gQ0FhY0RlY29kZXJfQW5jRGF0YUdldChhbmNEYXRhLCBpbmRleCwgcHRyLCBzaXplKTsKfQoKCnN0YXRpYyBBQUNfREVDT0RFUl9FUlJPUgpzZXRDb25jZWFsTWV0aG9kICggY29uc3QgSEFORExFX0FBQ0RFQ09ERVIgIHNlbGYsICAgLyohPCBIYW5kbGUgb2YgdGhlIGRlY29kZXIgaW5zdGFuY2UgKi8KICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICBtZXRob2QgKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwogIENDb25jZWFsUGFyYW1zICAqcENvbmNlYWxEYXRhID0gTlVMTDsKICBIQU5ETEVfU0JSREVDT0RFUiBoU2JyRGVjID0gTlVMTDsKICBIQU5ETEVfQUFDX0RSQyBoRHJjSW5mbyA9IE5VTEw7CiAgSEFORExFX1BDTV9ET1dOTUlYIGhQY21EbXggPSBOVUxMOwogIENDb25jZWFsbWVudE1ldGhvZCBiYWNrdXBNZXRob2QgPSBDb25jZWFsTWV0aG9kTm9uZTsKICBpbnQgYmFja3VwRGVsYXkgPSAwOwogIGludCBic0RlbGF5ID0gMDsKCiAgLyogY2hlY2sgZGVjb2RlciBoYW5kbGUgKi8KICBpZiAoc2VsZiAhPSBOVUxMKSB7CiAgICBwQ29uY2VhbERhdGEgPSAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGE7CiAgICBoU2JyRGVjID0gc2VsZi0+aFNickRlY29kZXI7CiAgICBoRHJjSW5mbyA9IHNlbGYtPmhEcmNJbmZvOwogICAgaFBjbURteCA9IHNlbGYtPmhQY21VdGlsczsKICB9CgoKICAvKiBHZXQgY3VycmVudCBtZXRob2QvZGVsYXkgKi8KICBiYWNrdXBNZXRob2QgPSBDQ29uY2VhbG1lbnRfR2V0TWV0aG9kKHBDb25jZWFsRGF0YSk7CiAgYmFja3VwRGVsYXkgID0gQ0NvbmNlYWxtZW50X0dldERlbGF5KHBDb25jZWFsRGF0YSk7CgogIC8qIEJlIHN1cmUgdG8gc2V0IEFBQyBhbmQgU0JSIGNvbmNlYWxtZW50IG1ldGhvZCBzaW11bHRhbmVvdXNseSEgKi8KICBlcnJvclN0YXR1cyA9CiAgICBDQ29uY2VhbG1lbnRfU2V0UGFyYW1zKAogICAgICBwQ29uY2VhbERhdGEsCiAgICAgIChpbnQpbWV0aG9kLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25jZWFsTWV0aG9kCiAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQsICAvLyBjb25jZWFsRmFkZU91dFNsb3BlCiAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQsICAvLyBjb25jZWFsRmFkZUluU2xvcGUKICAgICAgQUFDREVDX0NPTkNFQUxfUEFSQU1fTk9UX1NQRUNJRklFRCwgIC8vIGNvbmNlYWxNdXRlUmVsZWFzZQogICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVEICAgLy8gY29uY2VhbENvbWZOb2lzZUxldmVsCiAgICApOwogIGlmICggKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfT0spCiAgICAmJiAoZXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19JTlZBTElEX0hBTkRMRSkgKSB7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKiBHZXQgbmV3IGRlbGF5ICovCiAgYnNEZWxheSA9IENDb25jZWFsbWVudF9HZXREZWxheShwQ29uY2VhbERhdGEpOwoKICB7CiAgICBTQlJfRVJST1Igc2JyRXJyID0gU0JSREVDX09LOwoKICAgIC8qIHNldCBTQlIgYml0c3RyZWFtIGRlbGF5ICovCiAgICBzYnJFcnIgPSBzYnJEZWNvZGVyX1NldFBhcmFtICgKICAgICAgaFNickRlYywKICAgICAgU0JSX1NZU1RFTV9CSVRTVFJFQU1fREVMQVksCiAgICAgIGJzRGVsYXkKICAgICk7CgogICAgc3dpdGNoIChzYnJFcnIpIHsKICAgIGNhc2UgU0JSREVDX09LOgogICAgY2FzZSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOgogICAgICBpZiAoc2VsZiAhPSBOVUxMKSB7CiAgICAgICAgLyogc2F2ZSB0aGUgcGFyYW0gdmFsdWUgYW5kIHNldCBsYXRlcgogICAgICAgICAgICh3aGVuIFNCUiBoYXMgYmVlbiBpbml0aWFsaXplZCkgKi8KICAgICAgICBzZWxmLT5zYnJQYXJhbXMuYnNEZWxheSA9IGJzRGVsYXk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBlcnJvclN0YXR1cyA9IEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KICB9CgogIGVycm9yU3RhdHVzID0KICAgIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICBoRHJjSW5mbywKICAgICAgRFJDX0JTX0RFTEFZLAogICAgICBic0RlbGF5CiAgICApOwogIGlmICggKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfT0spCiAgICAmJiAoZXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19JTlZBTElEX0hBTkRMRSkgKSB7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBpZiAoZXJyb3JTdGF0dXMgPT0gQUFDX0RFQ19PSykgewogICAgUENNRE1YX0VSUk9SIGVyciA9CiAgICAgIHBjbURteF9TZXRQYXJhbSAoCiAgICAgICAgaFBjbURteCwKICAgICAgICBETVhfQlNfREFUQV9ERUxBWSwKICAgICAgICBic0RlbGF5CiAgICAgICk7CiAgICBzd2l0Y2ggKGVycikgewogICAgY2FzZSBQQ01ETVhfSU5WQUxJRF9IQU5ETEU6CiAgICAgIGVycm9yU3RhdHVzID0gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIGNhc2UgUENNRE1YX09LOgogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGVycm9yU3RhdHVzID0gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgZ290byBiYWlsOwogICAgfQogIH0KCgpiYWlsOgogIGlmICggKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfT0spCiAgICAmJiAoZXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19JTlZBTElEX0hBTkRMRSkgKQogIHsKICAgIC8qIFJldmVydCB0byB0aGUgaW5pdGlhbCBzdGF0ZSAqLwogICAgQ0NvbmNlYWxtZW50X1NldFBhcmFtcyAoCiAgICAgICAgcENvbmNlYWxEYXRhLAogICAgICAgIChpbnQpYmFja3VwTWV0aG9kLAogICAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQsCiAgICAgICAgQUFDREVDX0NPTkNFQUxfUEFSQU1fTk9UX1NQRUNJRklFRCwKICAgICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVELAogICAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQKICAgICAgKTsKICAgIC8qIFJldmVydCBTQlIgYml0c3RyZWFtIGRlbGF5ICovCiAgICBzYnJEZWNvZGVyX1NldFBhcmFtICgKICAgICAgICBoU2JyRGVjLAogICAgICAgIFNCUl9TWVNURU1fQklUU1RSRUFNX0RFTEFZLAogICAgICAgIGJhY2t1cERlbGF5CiAgICAgICk7CiAgICAvKiBSZXZlcnQgRFJDIGJpdHN0cmVhbSBkZWxheSAqLwogICAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSAoCiAgICAgICAgaERyY0luZm8sCiAgICAgICAgRFJDX0JTX0RFTEFZLAogICAgICAgIGJhY2t1cERlbGF5CiAgICAgICk7CiAgICAvKiBSZXZlcnQgUENNIG1peGRvd24gYml0c3RyZWFtIGRlbGF5ICovCiAgICBwY21EbXhfU2V0UGFyYW0gKAogICAgICAgIGhQY21EbXgsCiAgICAgICAgRE1YX0JTX0RBVEFfREVMQVksCiAgICAgICAgYmFja3VwRGVsYXkKICAgICAgKTsKICB9CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKCkxJTktTUEVDX0NQUCBBQUNfREVDT0RFUl9FUlJPUgphYWNEZWNvZGVyX1NldFBhcmFtICggY29uc3QgSEFORExFX0FBQ0RFQ09ERVIgIHNlbGYsICAgLyohPCBIYW5kbGUgb2YgdGhlIGRlY29kZXIgaW5zdGFuY2UgKi8KICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFBQ0RFQ19QQVJBTSAgICAgICBwYXJhbSwgIC8qITwgUGFyYW1ldGVyIHRvIHNldCAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgdmFsdWUpICAvKiE8IFBhcmFtZXRlciB2YWx1ZWQgICAgICAgICAgICAgICAqLwp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwogIENDb25jZWFsUGFyYW1zICAqcENvbmNlYWxEYXRhID0gTlVMTDsKICBIQU5ETEVfQUFDX0RSQyBoRHJjSW5mbyA9IE5VTEw7CiAgSEFORExFX1BDTV9ET1dOTUlYIGhQY21EbXggPSBOVUxMOwogIFRETGltaXRlclB0ciBoUGNtVGRsID0gTlVMTDsKCiAgLyogY2hlY2sgZGVjb2RlciBoYW5kbGUgKi8KICBpZiAoc2VsZiAhPSBOVUxMKSB7CiAgICBwQ29uY2VhbERhdGEgPSAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGE7CiAgICBoRHJjSW5mbyA9IHNlbGYtPmhEcmNJbmZvOwogICAgaFBjbURteCA9IHNlbGYtPmhQY21VdGlsczsKICAgIGhQY21UZGwgPSBzZWxmLT5oTGltaXRlcjsKICB9IGVsc2UgewogICAgZXJyb3JTdGF0dXMgPSBBQUNfREVDX0lOVkFMSURfSEFORExFOwogIH0KCiAgLyogY29uZmlndXJlIHRoZSBzdWJzeXN0ZW1zICovCiAgc3dpdGNoIChwYXJhbSkKICB7CiAgY2FzZSBBQUNfUENNX09VVFBVVF9JTlRFUkxFQVZFRDoKICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPm91dHB1dEludGVybGVhdmVkID0gdmFsdWU7CiAgICBicmVhazsKCiAgY2FzZSBBQUNfUENNX01JTl9PVVRQVVRfQ0hBTk5FTFM6CiAgICBpZiAodmFsdWUgPCAtMSB8fCB2YWx1ZSA+ICg4KSkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIHsKICAgICAgUENNRE1YX0VSUk9SIGVycjsKCiAgICAgIGVyciA9IHBjbURteF9TZXRQYXJhbSAoCiAgICAgICAgICAgICAgaFBjbURteCwKICAgICAgICAgICAgICBNSU5fTlVNQkVSX09GX09VVFBVVF9DSEFOTkVMUywKICAgICAgICAgICAgICB2YWx1ZSApOwoKICAgICAgc3dpdGNoIChlcnIpIHsKICAgICAgY2FzZSBQQ01ETVhfT0s6CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgUENNRE1YX0lOVkFMSURfSEFORExFOgogICAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBBQUNfUENNX01BWF9PVVRQVVRfQ0hBTk5FTFM6CiAgICBpZiAodmFsdWUgPCAtMSB8fCB2YWx1ZSA+ICg4KSkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIHsKICAgICAgUENNRE1YX0VSUk9SIGVycjsKCiAgICAgIGVyciA9IHBjbURteF9TZXRQYXJhbSAoCiAgICAgICAgICAgICAgaFBjbURteCwKICAgICAgICAgICAgICBNQVhfTlVNQkVSX09GX09VVFBVVF9DSEFOTkVMUywKICAgICAgICAgICAgICB2YWx1ZSApOwoKICAgICAgc3dpdGNoIChlcnIpIHsKICAgICAgY2FzZSBQQ01ETVhfT0s6CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgUENNRE1YX0lOVkFMSURfSEFORExFOgogICAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBBQUNfUENNX0RVQUxfQ0hBTk5FTF9PVVRQVVRfTU9ERToKICAgIHsKICAgICAgUENNRE1YX0VSUk9SIGVycjsKCiAgICAgIGVyciA9IHBjbURteF9TZXRQYXJhbSAoCiAgICAgICAgICAgICAgaFBjbURteCwKICAgICAgICAgICAgICBETVhfRFVBTF9DSEFOTkVMX01PREUsCiAgICAgICAgICAgICAgdmFsdWUgKTsKCiAgICAgIHN3aXRjaCAoZXJyKSB7CiAgICAgIGNhc2UgUENNRE1YX09LOgogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFBDTURNWF9JTlZBTElEX0hBTkRMRToKICAgICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgoKICBjYXNlIEFBQ19QQ01fTElNSVRFUl9FTkFCTEU6CiAgICBpZiAodmFsdWUgPCAtMSB8fCB2YWx1ZSA+IDEpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+bGltaXRlckVuYWJsZVVzZXIgPSB2YWx1ZTsKICAgIGJyZWFrOwoKICBjYXNlIEFBQ19QQ01fTElNSVRFUl9BVFRBQ0tfVElNRToKICAgIGlmICh2YWx1ZSA8PSAwKSB7ICAvKiBtb2R1bGUgZnVuY3Rpb24gY29udmVydHMgdmFsdWUgdG8gdW5zaWduZWQgKi8KICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBzd2l0Y2ggKHNldExpbWl0ZXJBdHRhY2soaFBjbVRkbCwgdmFsdWUpKSB7CiAgICBjYXNlIFRETElNSVRfT0s6CiAgICAgIGJyZWFrOwogICAgY2FzZSBURExJTUlUX0lOVkFMSURfSEFORExFOgogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIGNhc2UgVERMSU1JVF9JTlZBTElEX1BBUkFNRVRFUjoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQUFDX1BDTV9MSU1JVEVSX1JFTEVBU19USU1FOgogICAgaWYgKHZhbHVlIDw9IDApIHsgIC8qIG1vZHVsZSBmdW5jdGlvbiBjb252ZXJ0cyB2YWx1ZSB0byB1bnNpZ25lZCAqLwogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIHN3aXRjaCAoc2V0TGltaXRlclJlbGVhc2UoaFBjbVRkbCwgdmFsdWUpKSB7CiAgICBjYXNlIFRETElNSVRfT0s6CiAgICAgIGJyZWFrOwogICAgY2FzZSBURExJTUlUX0lOVkFMSURfSEFORExFOgogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIGNhc2UgVERMSU1JVF9JTlZBTElEX1BBUkFNRVRFUjoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQUFDX1BDTV9PVVRQVVRfQ0hBTk5FTF9NQVBQSU5HOgogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDA6CiAgICAgICAgaWYgKHNlbGYgIT0gTlVMTCkgewogICAgICAgICAgc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmcgPSBjaGFubmVsTWFwcGluZ1RhYmxlUGFzc3Rocm91Z2g7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE6CiAgICAgICAgaWYgKHNlbGYgIT0gTlVMTCkgewogICAgICAgICAgc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmcgPSBjaGFubmVsTWFwcGluZ1RhYmxlV0FWOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBlcnJvclN0YXR1cyA9IEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBicmVhazsKCgogIGNhc2UgQUFDX1FNRl9MT1dQT1dFUjoKICAgIGlmICh2YWx1ZSA8IC0xIHx8IHZhbHVlID4gMSkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgUU1GIG1vZGUgKG1pZ2h0IGJlIG92ZXJyaWRlbikKICAgICAqICAwOkhRIChjb21wbGV4KQogICAgICogIDE6TFAgKHBhcnRpYWxseSBjb21wbGV4KQogICAgICovCiAgICBzZWxmLT5xbWZNb2RlVXNlciA9IChRTUZfTU9ERSl2YWx1ZTsKICAgIGJyZWFrOwoKCiAgY2FzZSBBQUNfRFJDX0FUVEVOVUFUSU9OX0ZBQ1RPUjoKICAgIC8qIERSQyBjb21wcmVzc2lvbiBmYWN0b3IgKHdoZXJlIDAgaXMgbm8gYW5kIDEyNyBpcyBtYXggY29tcHJlc3Npb24pICovCiAgICBlcnJvclN0YXR1cyA9CiAgICAgIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICAgIGhEcmNJbmZvLAogICAgICAgIERSQ19DVVRfU0NBTEUsCiAgICAgICAgdmFsdWUKICAgICAgKTsKICAgIGJyZWFrOwoKICBjYXNlIEFBQ19EUkNfQk9PU1RfRkFDVE9SOgogICAgLyogRFJDIGJvb3N0IGZhY3RvciAod2hlcmUgMCBpcyBubyBhbmQgMTI3IGlzIG1heCBib29zdCkgKi8KICAgIGVycm9yU3RhdHVzID0KICAgICAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSAoCiAgICAgICAgaERyY0luZm8sCiAgICAgICAgRFJDX0JPT1NUX1NDQUxFLAogICAgICAgIHZhbHVlCiAgICAgICk7CiAgICBicmVhazsKCiAgY2FzZSBBQUNfRFJDX1JFRkVSRU5DRV9MRVZFTDoKICAgIC8qIERSQyByZWZlcmVuY2UgbGV2ZWwgcXVhbnRpemVkIGluIDAuMjVkQiBzdGVwcyB1c2luZyB2YWx1ZXMgWzAuLjEyN10gaXQgaXMgJy0nIGZvciBhbmFsb2cgc2NhbGluZyAqLwogICAgZXJyb3JTdGF0dXMgPQogICAgICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgICAgICBoRHJjSW5mbywKICAgICAgICBUQVJHRVRfUkVGX0xFVkVMLAogICAgICAgIHZhbHVlCiAgICAgICk7CiAgICBicmVhazsKCiAgY2FzZSBBQUNfRFJDX0hFQVZZX0NPTVBSRVNTSU9OOgogICAgLyogRG9uJ3QgbmVlZCB0byBvdmVyd3JpdGUgY3V0L2Jvb3N0IHZhbHVlcyAqLwogICAgZXJyb3JTdGF0dXMgPQogICAgICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgICAgICBoRHJjSW5mbywKICAgICAgICBBUFBMWV9IRUFWWV9DT01QUkVTU0lPTiwKICAgICAgICB2YWx1ZQogICAgICApOwogICAgYnJlYWs7CgoKICBjYXNlIEFBQ19UUERFQ19DTEVBUl9CVUZGRVI6CiAgICB0cmFuc3BvcnREZWNfU2V0UGFyYW0oc2VsZi0+aElucHV0LCBUUERFQ19QQVJBTV9SRVNFVCwgMSk7CiAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUxvc3RBY2Nlc3NVbml0cyA9IDA7CiAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUJhZEJ5dGVzID0gMDsKICAgIHNlbGYtPnN0cmVhbUluZm8ubnVtVG90YWxCeXRlcyA9IDA7CiAgICAvKiBhYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihzZWxmKTsgKi8KICAgIGJyZWFrOwoKICBjYXNlIEFBQ19DT05DRUFMX01FVEhPRDoKICAgIC8qIENoYW5naW5nIHRoZSBjb25jZWFsbWVudCBtZXRob2QgY2FuIGludHJvZHVjZSBhZGRpdGlvbmFsIGJpdHN0cmVhbSBkZWxheS4gQW5kCiAgICAgICB0aGF0IGluIHR1cm4gYWZmZWN0cyBzdWIgbGlicmFyaWVzIGFuZCBtb2R1bGVzIHdoaWNoIG1ha2VzIHRoZSB3aG9sZSB0aGluZyBxdWl0ZQogICAgICAgY29tcGxleC4gIFNvIHRoZSBjb21wbGV0ZSBjaGFuZ2luZyByb3V0aW5lIGlzIHBhY2tlZCBpbnRvIGEgaGVscGVyIGZ1bmN0aW9uIHdoaWNoCiAgICAgICBrZWVwcyBhbGwgbW9kdWxlcyBhbmQgbGlicyBpbiBhIGNvbnNpc3RlbnQgc3RhdGUgZXZlbiBpbiB0aGUgY2FzZSBhbiBlcnJvciBvY2N1cmVzLiAqLwogICAgZXJyb3JTdGF0dXMgPSBzZXRDb25jZWFsTWV0aG9kICggc2VsZiwgdmFsdWUgKTsKICAgIGJyZWFrOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKICByZXR1cm4gKGVycm9yU3RhdHVzKTsKfQoKCkxJTktTUEVDX0NQUCBIQU5ETEVfQUFDREVDT0RFUiBhYWNEZWNvZGVyX09wZW4oVFJBTlNQT1JUX1RZUEUgdHJhbnNwb3J0Rm10LCBVSU5UIG5yT2ZMYXllcnMpCnsKICBBQUNfREVDT0RFUl9JTlNUQU5DRSAqYWFjRGVjID0gTlVMTDsKICBIQU5ETEVfVFJBTlNQT1JUREVDIHBJbjsKICBpbnQgZXJyID0gMDsKCiAgLyogQWxsb2NhdGUgdHJhbnNwb3J0IGxheWVyIHN0cnVjdC4gKi8KICBwSW4gPSB0cmFuc3BvcnREZWNfT3Blbih0cmFuc3BvcnRGbXQsIFRQX0ZMQUdfTVBFRzQpOwogIGlmIChwSW4gPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICB0cmFuc3BvcnREZWNfU2V0UGFyYW0ocEluLCBUUERFQ19QQVJBTV9JR05PUkVfQlVGRkVSRlVMTE5FU1MsIDEpOwoKICAvKiBBbGxvY2F0ZSBBQUMgZGVjb2RlciBjb3JlIHN0cnVjdC4gKi8KICBhYWNEZWMgPSBDQWFjRGVjb2Rlcl9PcGVuKHRyYW5zcG9ydEZtdCk7CgogIGlmIChhYWNEZWMgPT0gTlVMTCkgewogICAgdHJhbnNwb3J0RGVjX0Nsb3NlKCZwSW4pOwogICAgZ290byBiYWlsOwogIH0KICBhYWNEZWMtPmhJbnB1dCA9IHBJbjsKCiAgYWFjRGVjLT5uck9mTGF5ZXJzID0gbnJPZkxheWVyczsKCiAgYWFjRGVjLT5jaGFubmVsT3V0cHV0TWFwcGluZyA9IGNoYW5uZWxNYXBwaW5nVGFibGVXQVY7CgogIC8qIFJlZ2lzdGVyIENvbmZpZyBVcGRhdGUgY2FsbGJhY2suICovCiAgdHJhbnNwb3J0RGVjX1JlZ2lzdGVyQXNjQ2FsbGJhY2socEluLCBhYWNEZWNvZGVyX0NvbmZpZ0NhbGxiYWNrLCAodm9pZCopYWFjRGVjKTsKCiAgLyogb3BlbiBTQlIgZGVjb2RlciAqLwogIGlmICggU0JSREVDX09LICE9IHNickRlY29kZXJfT3BlbiAoICZhYWNEZWMtPmhTYnJEZWNvZGVyICkpIHsKICAgIGVyciA9IC0xOwogICAgZ290byBiYWlsOwogIH0KICBhYWNEZWMtPnFtZk1vZGVVc2VyID0gTk9UX0RFRklORUQ7CiAgdHJhbnNwb3J0RGVjX1JlZ2lzdGVyU2JyQ2FsbGJhY2soYWFjRGVjLT5oSW5wdXQsIChjYlNicl90KXNickRlY29kZXJfSGVhZGVyLCAodm9pZCopYWFjRGVjLT5oU2JyRGVjb2Rlcik7CgoKICBwY21EbXhfT3BlbiggJmFhY0RlYy0+aFBjbVV0aWxzICk7CiAgaWYgKGFhY0RlYy0+aFBjbVV0aWxzID09IE5VTEwpIHsKICAgIGVyciA9IC0xOwogICAgZ290byBiYWlsOwogIH0KCiAgYWFjRGVjLT5oTGltaXRlciA9IGNyZWF0ZUxpbWl0ZXIoVERMX0FUVEFDS19ERUZBVUxUX01TLCBURExfUkVMRUFTRV9ERUZBVUxUX01TLCBTQU1QTEVfTUFYLCAoOCksIDk2MDAwKTsKICBpZiAoTlVMTCA9PSBhYWNEZWMtPmhMaW1pdGVyKSB7CiAgICBlcnIgPSAtMTsKICAgIGdvdG8gYmFpbDsKICB9CiAgYWFjRGVjLT5saW1pdGVyRW5hYmxlVXNlciA9IChVQ0hBUiktMTsKICBhYWNEZWMtPmxpbWl0ZXJFbmFibGVDdXJyID0gMDsKCgoKICAvKiBBc3N1cmUgdGhhdCBhbGwgbW9kdWxlcyBoYXZlIHNhbWUgZGVsYXkgKi8KICBpZiAoIHNldENvbmNlYWxNZXRob2QoYWFjRGVjLCBDQ29uY2VhbG1lbnRfR2V0TWV0aG9kKCZhYWNEZWMtPmNvbmNlYWxDb21tb25EYXRhKSkgKSB7CiAgICBlcnIgPSAtMTsKICAgIGdvdG8gYmFpbDsKICB9CgpiYWlsOgogIGlmIChlcnIgPT0gLTEpIHsKICAgIGFhY0RlY29kZXJfQ2xvc2UoYWFjRGVjKTsKICAgIGFhY0RlYyA9IE5VTEw7CiAgfQogIHJldHVybiBhYWNEZWM7Cn0KCkxJTktTUEVDX0NQUCBBQUNfREVDT0RFUl9FUlJPUiBhYWNEZWNvZGVyX0ZpbGwoCiAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgICBzZWxmLAogICAgICAgIFVDSEFSICAgICAgICAgICAgICAqcEJ1ZmZlcltdLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgYnVmZmVyU2l6ZVtdLAogICAgICAgIFVJTlQgICAgICAgICAgICAgICAqcEJ5dGVzVmFsaWQKICAgICAgICApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgdHBFcnI7CiAgLyogbG9vcCBjb3VudGVyIGZvciBsYXllcnM7IGlmIG5vdCBUVF9NUDRfUkFXUEFDS0VUUyB1c2VkIGFzIGluZGV4IGZvciBvbmx5IAogICAgIGF2YWlsYWJsZSBsYXllciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICBJTlQgbGF5ZXIgICAgICA9IDA7CiAgSU5UIG5yT2ZMYXllcnMgPSBzZWxmLT5uck9mTGF5ZXJzOwoKICB7CiAgICBmb3IgKGxheWVyID0gMDsgbGF5ZXIgPCBuck9mTGF5ZXJzOyBsYXllcisrKXsKICAgICAgewogICAgICAgIHRwRXJyID0gdHJhbnNwb3J0RGVjX0ZpbGxEYXRhKCBzZWxmLT5oSW5wdXQsIHBCdWZmZXJbbGF5ZXJdLCBidWZmZXJTaXplW2xheWVyXSwgJnBCeXRlc1ZhbGlkW2xheWVyXSwgbGF5ZXIgKTsKICAgICAgICBpZiAodHBFcnIgIT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICAgICAgICByZXR1cm4gQUFDX0RFQ19VTktOT1dOOyAgLyogTXVzdCBiZSBhbiBpbnRlcm5hbCBlcnJvciAqLwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIEFBQ19ERUNfT0s7Cn0KCgpzdGF0aWMgdm9pZCBhYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CiAgQ0FhY0RlY29kZXJfU2lnbmFsSW50ZXJydXB0aW9uKHNlbGYpOwoKICBpZiAoIHNlbGYtPmhTYnJEZWNvZGVyICE9IE5VTEwgKSB7CiAgICBzYnJEZWNvZGVyX1NldFBhcmFtKHNlbGYtPmhTYnJEZWNvZGVyLCBTQlJfQlNfSU5URVJSVVBUSU9OLCAwKTsKICB9Cn0KCnN0YXRpYyB2b2lkIGFhY0RlY29kZXJfVXBkYXRlQml0U3RyZWFtQ291bnRlcnMoQ1N0cmVhbUluZm8gKnBTaSwgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLCBpbnQgbkJpdHMsIEFBQ19ERUNPREVSX0VSUk9SIEVycm9yU3RhdHVzKQp7CiAgLyogY2FsY3VsYXRlIGJpdCBkaWZmZXJlbmNlIChhbW91bnQgb2YgYml0cyBtb3ZlZCBmb3J3YXJkKSAqLwogIG5CaXRzID0gbkJpdHMgLSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgLyogTm90ZTogVGhlIGFtb3VudCBvZiBiaXRzIGNvbnN1bWVkIG1pZ2h0IGJlY29tZSBuZWdhdGl2ZSB3aGVuIHBhcnNpbmcgYQogICAgIGJpdCBzdHJlYW0gd2l0aCBzZXZlcmFsIHN1YiBmcmFtZXMsIGFuZCB3ZSBmaW5kIG91dCBhdCB0aGUgbGFzdCBzdWIgZnJhbWUKICAgICB0aGF0IHRoZSB0b3RhbCBmcmFtZSBsZW5ndGggZG9lcyBub3QgbWF0Y2ggdGhlIHN1bSBvZiBzdWIgZnJhbWUgbGVuZ3RoLiAKICAgICBJZiB0aGlzIGhhcHBlbnMsIHRoZSB0cmFuc3BvcnQgZGVjb2RlciBtaWdodCB3YW50IHRvIHJld2luZCB0byB0aGUgc3VwcG9zZWQKICAgICBlbmRpbmcgb2YgdGhlIHRyYW5zcG9ydCBmcmFtZSwgYW5kIHRoaXMgcG9zaXRpb24gbWlnaHQgYmUgYmVmb3JlIHRoZSBsYXN0CiAgICAgYWNjZXNzIHVuaXQgYmVnaW5uaW5nLiAqLwoKICAvKiBDYWxjIGJpdHJhdGUuICovCiAgaWYgKHBTaS0+ZnJhbWVTaXplID4gMCkgewogICAgcFNpLT5iaXRSYXRlID0gKG5CaXRzICogcFNpLT5zYW1wbGVSYXRlKS9wU2ktPmZyYW1lU2l6ZTsKICB9CgogIC8qIGJpdC9ieXRlIGNvdW50ZXJzICovCiAgewogICAgaW50IG5CeXRlczsKCiAgICBuQnl0ZXMgPSBuQml0cz4+MzsKICAgIHBTaS0+bnVtVG90YWxCeXRlcyArPSBuQnl0ZXM7CiAgICBpZiAoSVNfT1VUUFVUX1ZBTElEKEVycm9yU3RhdHVzKSkgewogICAgICBwU2ktPm51bVRvdGFsQWNjZXNzVW5pdHMrKzsKICAgIH0KICAgIGlmIChJU19ERUNPREVfRVJST1IoRXJyb3JTdGF0dXMpKSB7CiAgICAgIHBTaS0+bnVtQmFkQnl0ZXMgKz0gbkJ5dGVzOwogICAgICBwU2ktPm51bUJhZEFjY2Vzc1VuaXRzKys7CiAgICB9CiAgfQp9CgpzdGF0aWMgSU5UIGFhY0RlY29kZXJfRXN0aW1hdGVOdW1iZXJPZkxvc3RGcmFtZXMoSEFORExFX0FBQ0RFQ09ERVIgc2VsZikKewogIElOVCBuOwoKICB0cmFuc3BvcnREZWNfR2V0TWlzc2luZ0FjY2Vzc1VuaXRDb3VudCggJm4sIHNlbGYtPmhJbnB1dCk7CgogIHJldHVybiBuOwp9CgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9EZWNvZGVGcmFtZSgKICAgICAgICBIQU5ETEVfQUFDREVDT0RFUiAgc2VsZiwKICAgICAgICBJTlRfUENNICAgICAgICAgICAqcFRpbWVEYXRhLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICB0aW1lRGF0YVNpemUsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgIGZsYWdzKQp7CiAgICBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1czsKICAgIElOVCBsYXllcjsKICAgIElOVCBuQml0czsKICAgIElOVCBpbnRlcmxlYXZlZCA9IHNlbGYtPm91dHB1dEludGVybGVhdmVkOwogICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzOwogICAgaW50IGZUcEludGVycnVwdGlvbiA9IDA7ICAvKiBUcmFuc3BvcnQgb3JpZ2luYXRlZCBpbnRlcnJ1cHRpb24gZGV0ZWN0aW9uLiAqLwogICAgaW50IGZUcENvbmNlYWwgPSAwOyAgICAgICAvKiBUcmFuc3BvcnQgb3JpZ2luYXRlZCBjb25jZWFsbWVudC4gKi8KCgogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICBpZiAoZmxhZ3MgJiBBQUNERUNfSU5UUikgewogICAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUxvc3RBY2Nlc3NVbml0cyA9IDA7CiAgICB9CgogICAgaEJzID0gdHJhbnNwb3J0RGVjX0dldEJpdHN0cmVhbShzZWxmLT5oSW5wdXQsIDApOwoKICAgIC8qIEdldCBjdXJyZW50IGJpdHMgcG9zaXRpb24gZm9yIGJpdHJhdGUgY2FsY3VsYXRpb24uICovCiAgICBuQml0cyA9IEZES2dldFZhbGlkQml0cyhoQnMpOwogICAgaWYgKCEgKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMIHwgQUFDREVDX0ZMVVNIKSApICkKICAgIHsKICAgICAgVFJBTlNQT1JUREVDX0VSUk9SIGVycjsKCiAgICAgIGZvcihsYXllciA9IDA7IGxheWVyIDwgc2VsZi0+bnJPZkxheWVyczsgbGF5ZXIrKykKICAgICAgewogICAgICAgIGVyciA9IHRyYW5zcG9ydERlY19SZWFkQWNjZXNzVW5pdChzZWxmLT5oSW5wdXQsIGxheWVyKTsKICAgICAgICBpZiAoZXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgICAgc3dpdGNoIChlcnIpIHsKICAgICAgICAgIGNhc2UgVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzoKICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX05PVF9FTk9VR0hfQklUUzsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgY2FzZSBUUkFOU1BPUlRERUNfU1lOQ19FUlJPUjoKICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5udW1Mb3N0QWNjZXNzVW5pdHMgPSBhYWNEZWNvZGVyX0VzdGltYXRlTnVtYmVyT2ZMb3N0RnJhbWVzKHNlbGYpOwogICAgICAgICAgICBmVHBJbnRlcnJ1cHRpb24gPSAxOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgVFJBTlNQT1JUREVDX05FRURfVE9fUkVTVEFSVDoKICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX05FRURfVE9fUkVTVEFSVDsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgY2FzZSBUUkFOU1BPUlRERUNfQ1JDX0VSUk9SOgogICAgICAgICAgICBmVHBDb25jZWFsID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfVU5LTk9XTjsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKHNlbGYtPnN0cmVhbUluZm8ubnVtTG9zdEFjY2Vzc1VuaXRzID4gMCkgewogICAgICAgIHNlbGYtPnN0cmVhbUluZm8ubnVtTG9zdEFjY2Vzc1VuaXRzLS07CiAgICAgIH0KICAgIH0KCiAgICAvKiBTaWduYWwgYml0IHN0cmVhbSBpbnRlcnJ1cHRpb24gdG8gb3RoZXIgbW9kdWxlcyBpZiByZXF1aXJlZC4gKi8KICAgIGlmICggZlRwSW50ZXJydXB0aW9uIHx8IChmbGFncyAmIChBQUNERUNfSU5UUnxBQUNERUNfQ0xSSElTVCkpICkKICAgIHsKICAgICAgc2JyRGVjb2Rlcl9TZXRQYXJhbShzZWxmLT5oU2JyRGVjb2RlciwgU0JSX0NMRUFSX0hJU1RPUlksIChmbGFncyZBQUNERUNfQ0xSSElTVCkpOwogICAgICBhYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihzZWxmKTsKICAgICAgaWYgKCAhIChmbGFncyAmIEFBQ0RFQ19JTlRSKSApIHsKICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfVFJBTlNQT1JUX1NZTkNfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9CgogICAgLyogRW1wdHkgYml0IGJ1ZmZlciBpbiBjYXNlIG9mIGZsdXNoIHJlcXVlc3QuICovCiAgICBpZiAoZmxhZ3MgJiBBQUNERUNfRkxVU0gpCiAgICB7CiAgICAgIHRyYW5zcG9ydERlY19TZXRQYXJhbShzZWxmLT5oSW5wdXQsIFRQREVDX1BBUkFNX1JFU0VULCAxKTsKICAgICAgc2VsZi0+c3RyZWFtSW5mby5udW1Mb3N0QWNjZXNzVW5pdHMgPSAwOwogICAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUJhZEJ5dGVzID0gMDsKICAgICAgc2VsZi0+c3RyZWFtSW5mby5udW1Ub3RhbEJ5dGVzID0gMDsKICAgIH0KICAgIC8qIFJlc2V0IHRoZSBvdXRwdXQgZGVsYXkgZmllbGQuIFRoZSBtb2R1bGVzIHdpbGwgYWRkIHRoZWlyIGZpZ3VyZXMgb25lIGFmdGVyIGFub3RoZXIuICovCiAgICBzZWxmLT5zdHJlYW1JbmZvLm91dHB1dERlbGF5ID0gMDsKCiAgICBpZiAoc2VsZi0+bGltaXRlckVuYWJsZVVzZXI9PShVQ0hBUiktMSkgewogICAgICAvKiBFbmJhbGUgbGltaXRlciBmb3IgYWxsIG5vbi1sb3dkZWxheSBBT1Qncy4gKi8KICAgICAgc2VsZi0+bGltaXRlckVuYWJsZUN1cnIgPSAoIHNlbGYtPmZsYWdzICYgKEFDX0xEfEFDX0VMRCkgKSA/IDAgOiAxOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIFVzZSBsaW1pdGVyIGNvbmZpZ3VyYXRpb24gYXMgcmVxdWVzdGVkLiAqLwogICAgICBzZWxmLT5saW1pdGVyRW5hYmxlQ3VyciA9IHNlbGYtPmxpbWl0ZXJFbmFibGVVc2VyOwogICAgfQogICAgLyogcmVzZXQgbGltaXRlciBnYWluIG9uIGEgcGVyIGZyYW1lIGJhc2lzICovCiAgICBzZWxmLT5leHRHYWluWzBdID0gRkwyRlhDT05TVF9EQkwoMS4wZi8oZmxvYXQpKDE8PFRETF9HQUlOX1NDQUxJTkcpKTsKCgogICAgRXJyb3JTdGF0dXMgPSBDQWFjRGVjb2Rlcl9EZWNvZGVGcmFtZShzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGFncyB8IChmVHBDb25jZWFsID8gQUFDREVDX0NPTkNFQUwgOiAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFRpbWVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lRGF0YVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybGVhdmVkKTsKCiAgICBpZiAoIShmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSkgewogICAgICBUUkFOU1BPUlRERUNfRVJST1IgdHBFcnI7CiAgICAgIHRwRXJyID0gdHJhbnNwb3J0RGVjX0VuZEFjY2Vzc1VuaXQoc2VsZi0+aElucHV0KTsKICAgICAgaWYgKHRwRXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICB9CiAgICB9CgogICAgLyogSWYgdGhlIGN1cnJlbnQgcFRpbWVEYXRhIGRvZXMgbm90IGNvbnRhaW4gYSB2YWxpZCBzaWduYWwsIHRoZXJlIG5vdGhpbmcgZWxzZSB3ZSBjYW4gZG8sIHNvIGJhaWwuICovCiAgICBpZiAoICEgSVNfT1VUUFVUX1ZBTElEKEVycm9yU3RhdHVzKSApIHsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIHsKICAgICAgLyogRXhwb3J0IGRhdGEgaW50byBzdHJlYW1pbmZvIHN0cnVjdHVyZSAqLwogICAgICBzZWxmLT5zdHJlYW1JbmZvLnNhbXBsZVJhdGUgPSBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGU7CiAgICAgIHNlbGYtPnN0cmVhbUluZm8uZnJhbWVTaXplICA9IHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lOwogICAgfQogICAgc2VsZi0+c3RyZWFtSW5mby5udW1DaGFubmVscyA9IHNlbGYtPnN0cmVhbUluZm8uYWFjTnVtQ2hhbm5lbHM7CgoKCiAgICBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShzZWxmKTsKCi8qIHNiciBkZWNvZGVyICovCgogICAgaWYgKEVycm9yU3RhdHVzIHx8IChmbGFncyAmIEFBQ0RFQ19DT05DRUFMKSB8fCBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvWzBdLT5jb25jZWFsbWVudEluZm8uY29uY2VhbFN0YXRlID4gQ29uY2VhbFN0YXRlX0ZhZGVJbikKICAgIHsKICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7ICAvKiBpZiBhbiBlcnJvciBoYXMgb2NjdXJlZCBkbyBjb25jZWFsbWVudCBpbiB0aGUgU0JSIGRlY29kZXIgdG9vICovCiAgICB9CgogICAgaWYgKHNlbGYtPnNickVuYWJsZWQpCiAgICB7CiAgICAgIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICAgICAgaW50IGNoT3V0TWFwSWR4ID0gKChzZWxmLT5jaE1hcEluZGV4PT0wKSAmJiAoc2VsZi0+c3RyZWFtSW5mby5udW1DaGFubmVsczw3KSkgPyBzZWxmLT5zdHJlYW1JbmZvLm51bUNoYW5uZWxzIDogc2VsZi0+Y2hNYXBJbmRleDsKCiAgICAgIC8qIHNldCBwYXJhbXMgKi8KICAgICAgc2JyRGVjb2Rlcl9TZXRQYXJhbSAoIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU0JSX1NZU1RFTV9CSVRTVFJFQU1fREVMQVksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zYnJQYXJhbXMuYnNEZWxheSk7CiAgICAgIHNickRlY29kZXJfU2V0UGFyYW0gKCBzZWxmLT5oU2JyRGVjb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNCUl9GTFVTSF9EQVRBLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzICYgQUFDREVDX0ZMVVNIKSApOwoKICAgICAgaWYgKCBzZWxmLT5zdHJlYW1JbmZvLmFvdCA9PSBBT1RfRVJfQUFDX0VMRCApIHsKICAgICAgICAvKiBDb25maWd1cmUgUU1GICovCiAgICAgICAgc2JyRGVjb2Rlcl9TZXRQYXJhbSAoIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQlJfTERfUU1GX1RJTUVfQUxJR04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxmLT5mbGFncyAmIEFDX0xEX01QUykgPyAxIDogMCApOwogICAgICB9CgogICAgICB7CiAgICAgICAgUENNRE1YX0VSUk9SIGRteEVycjsKICAgICAgICBJTlQgIG1heE91dENoID0gMDsKCiAgICAgICAgZG14RXJyID0gcGNtRG14X0dldFBhcmFtKHNlbGYtPmhQY21VdGlscywgTUFYX05VTUJFUl9PRl9PVVRQVVRfQ0hBTk5FTFMsICZtYXhPdXRDaCk7CiAgICAgICAgaWYgKCAoZG14RXJyID09IFBDTURNWF9PSykgJiYgKG1heE91dENoID09IDEpICkgewogICAgICAgICAgLyogRGlzYWJsZSBQUyBwcm9jZXNzaW5nIGlmIHdlIGhhdmUgdG8gY3JlYXRlIGEgbW9ubyBvdXRwdXQgc2lnbmFsLiAqLwogICAgICAgICAgc2VsZi0+cHNQb3NzaWJsZSA9IDA7CiAgICAgICAgfQogICAgICB9CgoKICAgICAgLyogYXBwbHkgU0JSIHByb2Nlc3NpbmcgKi8KICAgICAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0FwcGx5ICggc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBUaW1lRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5udW1DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1tjaE91dE1hcElkeF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybGVhdmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mcmFtZU9LLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5wc1Bvc3NpYmxlKTsKCgogICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKCiAgICAgICAvKiBVcGRhdGUgZGF0YSBpbiBzdHJlYW1pbmZvIHN0cnVjdHVyZS4gQXNzdW1lIHRoYXQgdGhlIFNCUiB1cHNhbXBsaW5nIGZhY3RvciBpcyBlaXRoZXIgMSBvciAyICovCiAgICAgICBzZWxmLT5mbGFncyB8PSBBQ19TQlJfUFJFU0VOVDsKICAgICAgIGlmIChzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUgIT0gc2VsZi0+c3RyZWFtSW5mby5zYW1wbGVSYXRlKSB7CiAgICAgICAgIGlmIChzZWxmLT5zdHJlYW1JbmZvLmZyYW1lU2l6ZSA9PSA3NjgpIHsKICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmZyYW1lU2l6ZSA9ICAoc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgKiA4KSAvIDM7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5mcmFtZVNpemUgPSAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgPDwgMTsKICAgICAgICAgfQogICAgICAgfQogICAgICAgLyogQ29ycmVjdCB0aGUgYWRkaXRpb25hbCBjb25jZWFsbWVudCBkZWxheSBmaWd1cmVzICovCiAgICAgICBzZWxmLT5zdHJlYW1JbmZvLm91dHB1dERlbGF5IC09IHNlbGYtPnNiclBhcmFtcy5ic0RlbGF5ICogc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWU7CiAgICAgICBzZWxmLT5zdHJlYW1JbmZvLm91dHB1dERlbGF5ICs9IHNlbGYtPnNiclBhcmFtcy5ic0RlbGF5ICogc2VsZi0+c3RyZWFtSW5mby5mcmFtZVNpemU7CgogICAgICAgaWYgKHNlbGYtPnBzUG9zc2libGUpIHsKICAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gQUNfUFNfUFJFU0VOVDsKICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGVbMF0gPSBBQ1RfRlJPTlQ7CiAgICAgICAgIHNlbGYtPmNoYW5uZWxUeXBlWzFdID0gQUNUX0ZST05UOwogICAgICAgICBzZWxmLT5jaGFubmVsSW5kaWNlc1swXSA9IDA7CiAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzWzFdID0gMTsKICAgICAgIH0KICAgICB9CiAgIH0KCgogICAgewogICAgSU5UIHBjbUxpbWl0ZXJTY2FsZSA9IDA7CiAgICBQQ01ETVhfRVJST1IgZG14RXJyID0gUENNRE1YX09LOwogICAgaWYgKCBmbGFncyAmIChBQUNERUNfSU5UUiB8IEFBQ0RFQ19DTFJISVNUKSApIHsKICAgICAgLyogZGVsZXRlIGRhdGEgZnJvbSB0aGUgcGFzdCAoZS5nLiBtaXhkb3duIGNvZWZpY2llbnRzKSAqLwogICAgICBwY21EbXhfUmVzZXQoIHNlbGYtPmhQY21VdGlscywgUENNRE1YX1JFU0VUX0JTX0RBVEEgKTsKICAgIH0KICAgIC8qIGRvIFBDTSBwb3N0IHByb2Nlc3NpbmcgKi8KICAgIGRteEVyciA9IHBjbURteF9BcHBseUZyYW1lICgKICAgICAgICAgICAgc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICBwVGltZURhdGEsCiAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZnJhbWVTaXplLAogICAgICAgICAgICZzZWxmLT5zdHJlYW1JbmZvLm51bUNoYW5uZWxzLAogICAgICAgICAgICBpbnRlcmxlYXZlZCwKICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGUsCiAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZywKICAgICAgICAgICAgKHNlbGYtPmxpbWl0ZXJFbmFibGVDdXJyKSA/ICZwY21MaW1pdGVyU2NhbGUgOiBOVUxMCiAgICAgICk7CiAgICBpZiAoZG14RXJyID09IFBDTURNWF9JTlZBTElEX01PREUpIHsKICAgICAgLyogQW5ub3VuY2UgdGhlIGZyYW1ld29yayB0aGF0IHRoZSBjdXJyZW50IGNvbWJpbmF0aW9uIG9mIGNoYW5uZWwgY29uZmlndXJhdGlvbiBhbmQgZG93bm1peAogICAgICAgKiBzZXR0aW5ncyBhcmUgbm90IGtub3cgdG8gcHJvZHVjZSBhIHByZWRpY3RhYmxlIGJlaGF2aW9yIGFuZCB0aHVzIG1heWJlIHByb2R1Y2Ugc3RyYW5nZSBvdXRwdXQuICovCiAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICB9CgogICAgaWYgKCBmbGFncyAmIEFBQ0RFQ19DTFJISVNUICkgewogICAgICAvKiBEZWxldGUgdGhlIGRlbGF5ZWQgc2lnbmFsLiAqLwogICAgICByZXNldExpbWl0ZXIoc2VsZi0+aExpbWl0ZXIpOwogICAgfQogICAgaWYgKHNlbGYtPmxpbWl0ZXJFbmFibGVDdXJyKQogICAgewogICAgICAvKiBTZXQgYWN0dWFsIHNpZ25hbCBwYXJhbWV0ZXJzICovCiAgICAgIHNldExpbWl0ZXJOQ2hhbm5lbHMoc2VsZi0+aExpbWl0ZXIsIHNlbGYtPnN0cmVhbUluZm8ubnVtQ2hhbm5lbHMpOwogICAgICBzZXRMaW1pdGVyU2FtcGxlUmF0ZShzZWxmLT5oTGltaXRlciwgc2VsZi0+c3RyZWFtSW5mby5zYW1wbGVSYXRlKTsKCiAgICAgIGFwcGx5TGltaXRlcigKICAgICAgICAgICAgICBzZWxmLT5oTGltaXRlciwKICAgICAgICAgICAgICBwVGltZURhdGEsCiAgICAgICAgICAgICAgc2VsZi0+ZXh0R2FpbiwKICAgICAgICAgICAgICZwY21MaW1pdGVyU2NhbGUsCiAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICBzZWxmLT5leHRHYWluRGVsYXksCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5mcmFtZVNpemUKICAgICAgICAgICAgICApOwoKICAgICAgLyogQW5ub3VuY2UgdGhlIGFkZGl0aW9uYWwgbGltaXRlciBvdXRwdXQgZGVsYXkgKi8KICAgICAgc2VsZi0+c3RyZWFtSW5mby5vdXRwdXREZWxheSArPSBnZXRMaW1pdGVyRGVsYXkoc2VsZi0+aExpbWl0ZXIpOwogICAgfQogICAgfQoKCiAgICAvKiBTaWduYWwgaW50ZXJydXB0aW9uIHRvIHRha2UgZWZmZWN0IGluIG5leHQgZnJhbWUuICovCiAgICBpZiAoIGZsYWdzICYgQUFDREVDX0ZMVVNIICkgewogICAgICBhYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihzZWxmKTsKICAgIH0KCiAgICAvKiBVcGRhdGUgZXh0ZXJuYWxseSB2aXNpYmxlIGNvcHkgb2YgZmxhZ3MgKi8KICAgIHNlbGYtPnN0cmVhbUluZm8uZmxhZ3MgPSBzZWxmLT5mbGFnczsKCmJhaWw6CgogICAgLyogVXBkYXRlIFN0YXRpc3RpY3MgKi8KICAgIGFhY0RlY29kZXJfVXBkYXRlQml0U3RyZWFtQ291bnRlcnMoJnNlbGYtPnN0cmVhbUluZm8sIGhCcywgbkJpdHMsIEVycm9yU3RhdHVzKTsKCiAgICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCkxJTktTUEVDX0NQUCB2b2lkIGFhY0RlY29kZXJfQ2xvc2UgKCBIQU5ETEVfQUFDREVDT0RFUiBzZWxmICkKewogIGlmIChzZWxmID09IE5VTEwpCiAgICByZXR1cm47CgoKICBpZiAoc2VsZi0+aExpbWl0ZXIgIT0gTlVMTCkgewogICAgZGVzdHJveUxpbWl0ZXIoc2VsZi0+aExpbWl0ZXIpOwogIH0KCiAgaWYgKHNlbGYtPmhQY21VdGlscyAhPSBOVUxMKSB7CiAgICBwY21EbXhfQ2xvc2UoICZzZWxmLT5oUGNtVXRpbHMgKTsKICB9CgoKCiAgaWYgKHNlbGYtPmhTYnJEZWNvZGVyICE9IE5VTEwpIHsKICAgIHNickRlY29kZXJfQ2xvc2UoJnNlbGYtPmhTYnJEZWNvZGVyKTsKICB9CgogIGlmIChzZWxmLT5oSW5wdXQgIT0gTlVMTCkgewogICAgdHJhbnNwb3J0RGVjX0Nsb3NlKCZzZWxmLT5oSW5wdXQpOwogIH0KCiAgQ0FhY0RlY29kZXJfQ2xvc2Uoc2VsZik7Cn0KCgpMSU5LU1BFQ19DUFAgQ1N0cmVhbUluZm8qIGFhY0RlY29kZXJfR2V0U3RyZWFtSW5mbyAoIEhBTkRMRV9BQUNERUNPREVSIHNlbGYgKQp7CiAgcmV0dXJuIENBYWNEZWNvZGVyX0dldFN0cmVhbUluZm8oc2VsZik7Cn0KCkxJTktTUEVDX0NQUCBJTlQgYWFjRGVjb2Rlcl9HZXRMaWJJbmZvICggTElCX0lORk8gKmluZm8gKQp7CiAgaW50IGk7CgogIGlmIChpbmZvID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CgogIHNickRlY29kZXJfR2V0TGliSW5mbyggaW5mbyApOwogIHRyYW5zcG9ydERlY19HZXRMaWJJbmZvKCBpbmZvICk7CiAgRkRLX3Rvb2xzR2V0TGliSW5mbyggaW5mbyApOwogIHBjbURteF9HZXRMaWJJbmZvKCBpbmZvICk7CgogIC8qIHNlYXJjaCBmb3IgbmV4dCBmcmVlIHRhYiAqLwogIGZvciAoaSA9IDA7IGkgPCBGREtfTU9EVUxFX0xBU1Q7IGkrKykgewogICAgaWYgKGluZm9baV0ubW9kdWxlX2lkID09IEZES19OT05FKSBicmVhazsKICB9CiAgaWYgKGkgPT0gRkRLX01PRFVMRV9MQVNUKSB7CiAgICByZXR1cm4gLTE7CiAgfQogIGluZm8gKz0gaTsKCiAgaW5mby0+bW9kdWxlX2lkID0gRkRLX0FBQ0RFQzsKICAvKiBidWlsZCBvd24gbGlicmFyeSBpbmZvICovCiAgaW5mby0+dmVyc2lvbiA9IExJQl9WRVJTSU9OKEFBQ0RFQ09ERVJfTElCX1ZMMCwgQUFDREVDT0RFUl9MSUJfVkwxLCBBQUNERUNPREVSX0xJQl9WTDIpOwogIExJQl9WRVJTSU9OX1NUUklORyhpbmZvKTsKICBpbmZvLT5idWlsZF9kYXRlID0gQUFDREVDT0RFUl9MSUJfQlVJTERfREFURTsKICBpbmZvLT5idWlsZF90aW1lID0gQUFDREVDT0RFUl9MSUJfQlVJTERfVElNRTsKICBpbmZvLT50aXRsZSA9IEFBQ0RFQ09ERVJfTElCX1RJVExFOwoKICAvKiBTZXQgZmxhZ3MgKi8KICBpbmZvLT5mbGFncyA9IDAKICAgICAgfCBDQVBGX0FBQ19MQwogICAgICB8IENBUEZfQUFDX1ZDQjExCiAgICAgIHwgQ0FQRl9BQUNfSENSCiAgICAgIHwgQ0FQRl9BQUNfUlZMQwogICAgICB8IENBUEZfRVJfQUFDX0xECiAgICAgIHwgQ0FQRl9FUl9BQUNfRUxECiAgICAgIHwgQ0FQRl9BQUNfQ09OQ0VBTE1FTlQKICAgICAgfCBDQVBGX0FBQ19EUkMKCiAgICAgIHwgQ0FQRl9BQUNfTVBFRzQKCgogICAgICB8IENBUEZfQUFDXzEwMjQKICAgICAgfCBDQVBGX0FBQ185NjAKCiAgICAgIHwgQ0FQRl9BQUNfNTEyCgogICAgICB8IENBUEZfQUFDXzQ4MAoKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gMDsKfQoKCgoK