Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgUlZMQyBEZWNvZGVyCiAgXGF1dGhvciBSb2JlcnQgV2VpZG5lcgoqLwoKI2luY2x1ZGUgInJ2bGMuaCIKCgojaW5jbHVkZSAiYmxvY2suaCIKCiNpbmNsdWRlICJhYWNfcm9tLmgiCiNpbmNsdWRlICJydmxjYml0LmgiCiNpbmNsdWRlICJydmxjY29uY2VhbC5oIgojaW5jbHVkZSAiYWFjZGVjX2hjci5oIgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBmdW5jdGlvbjogICAgIHJ2bGNJbml0CgogICAgIGRlc2NyaXB0aW9uOiAgaW5pdCBSVkxDIGJ5IGRhdGEgZnJvbSBjaGFubmVsaW5mbywgd2hpY2ggd2FzIGRlY29kZWQgcHJldmlvdXNseSBhbmQKICAgICAgICAgICAgICAgICAgIHNldCB1cCBwb2ludGVycwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlucHV0OiAgICAgLSBwb2ludGVyIHJ2bGMgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgICAtIHBvaW50ZXIgY2hhbm5lbCBpbmZvIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgLSBwb2ludGVyIGJpdHN0cmVhbSBzdHJ1Y3R1cmUKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgIC0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYwp2b2lkIHJ2bGNJbml0IChDRXJSdmxjSW5mbyAgICAgICAgICAgICpwUnZsYywKICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICAgYnMpCnsKICAvKiBSVkxDIGNvbW1vbiBpbml0aWFsaXphdGlvbiBwYXJ0IDIgb2YgMiAqLwogIFNIT1JUICAgICAqcFNjZkVzYyA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT5vdmVybGF5LmFhYy5hUnZsY1NjZkVzYzsKICBTSE9SVCAgICAgKnBTY2ZGd2QgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+b3ZlcmxheS5hYWMuYVJ2bGNTY2ZGd2Q7CiAgU0hPUlQgICAgICpwU2NmQndkID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cENvbURhdGEtPm92ZXJsYXkuYWFjLmFSdmxjU2NmQndkOwogIFNIT1JUICAgICAqcFNjYWxlRmFjdG9yID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTY2FsZUZhY3RvcjsKICBpbnQgYm5kczsKCiAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLnJ2bGNJbnRlbnNpdHlVc2VkID0gMDsKCiAgcFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0VzYyA9IDA7CiAgcFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0Z3ZCA9IDA7CiAgcFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0J3ZCA9IDA7CgogIHBSdmxjLT5pbnRlbnNpdHlfdXNlZCA9IDA7CiAgcFJ2bGMtPmVycm9yTG9nUnZsYyAgID0gMDsKCiAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gQ09OQ0VBTF9NQVhfSU5JVDsKICBwUnZsYy0+Y29uY2VhbF9taW4gPSBDT05DRUFMX01JTl9JTklUOwoKICBwUnZsYy0+Y29uY2VhbF9tYXhfZXNjID0gQ09OQ0VBTF9NQVhfSU5JVDsKICBwUnZsYy0+Y29uY2VhbF9taW5fZXNjID0gQ09OQ0VBTF9NSU5fSU5JVDsKCiAgcFJ2bGMtPnBIdWZmVHJlZVJ2bGNFc2NhcGUgID0gYUh1ZmZUcmVlUnZsY0VzY2FwZTsKICBwUnZsYy0+cEh1ZmZUcmVlUnZsQ29kZXdkcyAgPSBhSHVmZlRyZWVSdmxDb2Rld2RzOwoKICAvKiBpbml0IHNjZiBhcnJheXMgKGZvciBzYXZldHkgKGluIGNhc2Ugb2YgdGhlcmUgYXJlIG9ubHkgemVybyBjb2RlYm9va3MpKSAqLwogIGZvciAoYm5kcyA9IDA7IGJuZHMgPCBSVkxDX01BWF9TRkI7IGJuZHMrKykgewogICAgcFNjZkZ3ZFtibmRzXSA9IDA7CiAgICBwU2NmQndkW2JuZHNdID0gMDsKICAgIHBTY2ZFc2NbYm5kc10gPSAwOwogICAgcFNjYWxlRmFjdG9yW2JuZHNdID0gMDsKICB9CgogIC8qIHNldCBiYXNlIGJpdHN0cmVhbSBwdHIgdG8gdGhlIFJWTC1jb2RlZCBwYXJ0IChzdGFydCBvZiBSVkxDIGRhdGEgKEVTQyAyKSkgKi8KICBGREtzeW5jQ2FjaGUgKGJzKTsKCiAgcFJ2bGMtPmJpdHN0cmVhbUluZGV4UnZsRndkID0gRkRLZ2V0Qml0Q250KGJzKTsgLyogZmlyc3QgYml0IHdpdGhpbiBSVkwgY29kZWQgYmxvY2sgYXMgc3RhcnQgYWRkcmVzcyBmb3IgIGZvcndhcmQgZGVjb2RpbmcgKi8KICBwUnZsYy0+Yml0c3RyZWFtSW5kZXhSdmxCd2QgPSBGREtnZXRCaXRDbnQoYnMpICsgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmIC0gMTsgLyogbGFzdCBiaXQgd2l0aGluIFJWTCBjb2RlZCBibG9jayBhcyBzdGFydCBhZGRyZXNzIGZvciBiYWNrd2FyZCBkZWNvZGluZyAqLwoKICAvKiBza2lwIFJWTEMtYml0c3RyZWFtLXBhcnQgLS0gcG9pbnRpbmcgbm93IHRvIGVzY2FwZXMgKGlmIHByZXNlbnQpIG9yIHRvIFROUyBkYXRhIChpZiBwcmVzZW50KSAqLwogIEZES3B1c2hGb3IgKGJzLCBwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2YpOwoKICBpZiAoIHBSdmxjLT5zZl9lc2NhcGVzX3ByZXNlbnQgIT0gMCApIHsKCiAgICAvKiBsb2NhdGUgaW50ZXJuYWwgYml0c3RyZWFtIHB0ciBhdCBlc2NhcGVzICh3aGljaCBpcyB0aGUgc2Vjb25kIHBhcnQpICovCiAgICBGREtzeW5jQ2FjaGUgKGJzKTsKICAgIHBSdmxjLT5iaXRzdHJlYW1JbmRleEVzYyA9IEZES2dldEJpdENudChicyk7CgogICAgLyogc2tpcCBlc2NhcGVSVkxDLWJpdHN0cmVhbS1wYXJ0IC0tIHBvaW50aW5nIHRvIFROUyBkYXRhIChpZiBwcmVzZW50KSAgIHRvIG1ha2UgZGVjb2RlciBjb250aW51ZSAqLwogICAgLyogZGVjb2Rpbmcgb2YgUlZMQyBzaG91bGQgd29yayBkZXNwaXRlIHRoaXMgc2Vjb25kIHB1c2hGb3IgZHVyaW5nIGluaXRpYWxpemF0aW9uIGJlY2F1c2UgICAgICAgICovCiAgICAvKiBiaXRzdHJlYW0gaW5pdGlhbGl6YXRpb24gaXMgdmFsaWQgZm9yIGJvdGggRVNDMiBkYXRhIHBhcnRzIChSVkwtY29kZWQgdmFsdWVzIGFuZCBFU0MtY29kZWQgdmFsdWVzKSAqLwogICAgRkRLcHVzaEZvciAoYnMsIHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKTsKICB9CgojaWYgVkVSQk9TRV9SVkxDX0lOSVQKICBEZWJ1Z091dHB1dEluaXQocFJ2bGMscEFhY0RlY29kZXJDaGFubmVsSW5mbyk7CiNlbmRpZgp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBmdW5jdGlvbjogICAgIHJ2bGNDaGVja0ludGVuc2l0eUNiCgogICAgIGRlc2NyaXB0aW9uOiAgQ2hlY2sgaWYgYSBpbnRlbnNpdHkgY29kZWJvb2sgaXMgdXNlZCBpbiB0aGUgY3VycmVudCBjaGFubmVsLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlucHV0OiAgICAgLSBwb2ludGVyIHJ2bGMgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgICAtIHBvaW50ZXIgY2hhbm5lbCBpbmZvIHN0cnVjdHVyZQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIG91dHB1dDogICAgLSBpbnRlbnNpdHlfdXNlZDogMCBubyBpbnRlbnNpdHkgY29kZWJvb2sgaXMgdXNlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSBpbnRlbnNpdHkgY29kZWJvb2sgaXMgdXNlZAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHJldHVybjogICAgLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljCnZvaWQgcnZsY0NoZWNrSW50ZW5zaXR5Q2IgKENFclJ2bGNJbmZvICAgICAgICAgICAgKnBSdmxjLAogICAgICAgICAgICAgICAgICAgICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvKQp7CiAgaW50IGdyb3VwLCBiYW5kLCBibmRzOwoKICBwUnZsYy0+aW50ZW5zaXR5X3VzZWQgPSAwOwoKICBmb3IgKGdyb3VwPTA7IGdyb3VwIDwgcFJ2bGMtPm51bVdpbmRvd0dyb3VwczsgZ3JvdXArKykgewogICAgZm9yIChiYW5kPTA7IGJhbmQgPCBwUnZsYy0+bWF4U2ZiVHJhbnNtaXR0ZWQ7IGJhbmQrKykgewogICAgICBibmRzID0gMTYqZ3JvdXArYmFuZDsKICAgICAgaWYgKCAocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9va1tibmRzXSA9PSBJTlRFTlNJVFlfSENCKSB8fCAocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9va1tibmRzXSA9PSBJTlRFTlNJVFlfSENCMikgKSB7CiAgICAgICAgcFJ2bGMtPmludGVuc2l0eV91c2VkID0gMTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgZnVuY3Rpb246ICAgICBydmxjRGVjb2RlRXNjYXBlV29yZAoKICAgICBkZXNjcmlwdGlvbjogIERlY29kZSBhIGh1ZmZtYW4gY29kZWQgUlZMQyBFc2NhcGUtd29yZC4gVGhpcyB2YWx1ZSBpcyBwYXJ0IG9mIGEgRFBDTSBjb2RlZAogICAgICAgICAgICAgICAgICAgc2NhbGVmYWN0b3IuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgaW5wdXQ6ICAgICAtIHBvaW50ZXIgcnZsYyBzdHJ1Y3R1cmUKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgIC0gYSBzaW5nbGUgUlZMQy1Fc2NhcGUgdmFsdWUgd2hpY2ggaGFkIHRvIGJlIGFwcGxpZWQgdG8gYSBEUENNIHZhbHVlICh3aGljaAogICAgICAgICAgICAgICAgICAgICBoYXMgYSBhYnNvbHV0ZSB2YWx1ZSBvZiA3KQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljClNDSEFSIHJ2bGNEZWNvZGVFc2NhcGVXb3JkIChDRXJSdmxjSW5mbyAgICAgICAgICAqcFJ2bGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMpCnsKICBpbnQgICAgICAgICAgIGk7CiAgU0NIQVIgICAgICAgICB2YWx1ZTsKICBVQ0hBUiAgICAgICAgIGNhcnJ5Qml0OwogIFVJTlQgICAgICAgICAgdHJlZU5vZGU7CiAgVUlOVCAgICAgICAgICBicmFuY2hWYWx1ZTsKICBVSU5UICAgICAgICAgIGJyYW5jaE5vZGU7CgogIFVTSE9SVCogICAgICAgcEJpdHN0cmVhbUluZGV4RXNjOwogIGNvbnN0IFVJTlQqICAgcEVzY1RyZWU7CgogIHBFc2NUcmVlID0gcFJ2bGMtPnBIdWZmVHJlZVJ2bGNFc2NhcGU7CiAgcEJpdHN0cmVhbUluZGV4RXNjID0gJihwUnZsYy0+Yml0c3RyZWFtSW5kZXhFc2MpOwogIHRyZWVOb2RlID0gKnBFc2NUcmVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluaXQgYXQgc3RhcnRpbmcgbm9kZSAqLwoKICBmb3IgKGk9TUFYX0xFTl9SVkxDX0VTQ0FQRV9XT1JELTE7IGkgPj0gMDsgaS0tKSB7CiAgICBjYXJyeUJpdCA9IHJ2bGNSZWFkQml0RnJvbUJpdHN0cmVhbShicywgICAgICAgICAgICAgICAgICAgICAgICAgLyogZ2V0IG5leHQgYml0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQml0c3RyZWFtSW5kZXhFc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGV0QpOwoKICAgIENhcnJ5Qml0VG9CcmFuY2hWYWx1ZShjYXJyeUJpdCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBodWZmbWFuIGRlY29kaW5nLCBkbyBhIHNpbmdsZSBzdGVwIGluIGh1ZmZtYW4gZGVjb2RpbmcgdHJlZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWVOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICZicmFuY2hWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAmYnJhbmNoTm9kZSk7CgogICAgaWYgKChicmFuY2hOb2RlICYgVEVTVF9CSVRfMTApID09IFRFU1RfQklUXzEwKSB7ICAgICAgICAgICAgICAgIC8qIHRlc3QgYml0IDEwIDsgaWYgc2V0IC0tPiBhIFJWTEMtZXNjYXBlLXdvcmQgaXMgY29tcGxldGVseSBkZWNvZGVkICovCiAgICAgIHZhbHVlID0gKFNDSEFSKSBicmFuY2hOb2RlICYgQ0xSX0JJVF8xMDsKICAgICAgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX2VzY2FwZXMgLT0gKE1BWF9MRU5fUlZMQ19FU0NBUEVfV09SRCAtIGkpOwoKICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzIDwgMCkgewogICAgICAgIHBSdmxjLT5lcnJvckxvZ1J2bGMgfD0gUlZMQ19FUlJPUl9BTExfRVNDQVBFX1dPUkRTX0lOVkFMSUQ7CiAgICAgICAgdmFsdWUgPSAtMTsKICAgICAgfQoKICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQogICAgZWxzZSB7CiAgICAgIHRyZWVOb2RlID0gKihwRXNjVHJlZSArIGJyYW5jaFZhbHVlKTsgICAgICAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlIHRyZWVOb2RlIGZvciBmdXJ0aGVyIHN0ZXAgaW4gZGVjb2RpbmcgdHJlZSAqLwogICAgfQogIH0KCiAgcFJ2bGMtPmVycm9yTG9nUnZsYyB8PSBSVkxDX0VSUk9SX0FMTF9FU0NBUEVfV09SRFNfSU5WQUxJRDsKCiAgcmV0dXJuIC0xOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2hvdWxkIG5vdCBiZSByZWFjaGVkICovCn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGZ1bmN0aW9uOiAgICAgcnZsY0RlY29kZUVzY2FwZXMKCiAgICAgZGVzY3JpcHRpb246ICBEZWNvZGVzIGFsbCBodWZmbWFuIGNvZGVkIFJWTEMgRXNjYXBlIFdvcmRzLgogICAgICAgICAgICAgICAgICAgSGVyZSBhIGRpZmZlcmVuY2UgdG8gdGhlIHBzZXVkby1jb2RlLWltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgY2FuIGJlIAogICAgICAgICAgICAgICAgICAgZm91bmQuIEEgd2hpbGUgbG9vcCAoYW5kIG5vdCB0d28gbmVzdGVkIGZvciBsb29wcykgaXMgdXNlZCBmb3IgdHdvIHJlYXNvbnM6CgogICAgICAgICAgICAgICAgICAgMS4gVGhlIHBsYWluIGh1ZmZtYW4gZW5jb2RlZCBlc2NhcGVzIGFyZSBkZWNvZGVkIGJlZm9yZSB0aGUgUlZMLWNvZGVkIAogICAgICAgICAgICAgICAgICAgICAgc2NhbGVmYWN0b3JzLiBUaGVyZWZvcmUgdGhlIGVzY2FwZXMgYXJlIHByZXNlbnQgaW4gdGhlIHNlY29uZCBzdGVwIAogICAgICAgICAgICAgICAgICAgICAgd2hlbiBkZWNvZGluZyB0aGUgUlZMLWNvZGVkLXNjYWxlZmFjdG9yIHZhbHVlcyBpbiBmb3J3YXJkIGFuZCAKICAgICAgICAgICAgICAgICAgICAgIGJhY2t3YXJkIGRpcmVjdGlvbi4KCiAgICAgICAgICAgICAgICAgICAgICBXaGVuIHRoZSBSVkwtY29kZWQgc2NhbGVmYWN0b3JzIGFyZSBkZWNvZGVkIGFuZCB0aGVyZSBhIGVzY2FwZSBpcyAKICAgICAgICAgICAgICAgICAgICAgIG5lZWRlZCwgdGhlbiBpdCBpcyBqdXN0IHRha2VuIG91dCBvZiB0aGUgYXJyYXkgaW4gYXNjZW5kaW5nIG9yZGVyLgoKICAgICAgICAgICAgICAgICAgIDIuIEl0J3MgZmFzdGVyLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlucHV0OiAgICAgLSBwb2ludGVyIHJ2bGMgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgICAtIGhhbmRsZSB0byBGREsgYml0c3RyZWFtCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgICAtIDAgb2sgICAgIHRoZSBkZWNvZGVkIGVzY2FwZXMgc2VlbSB0byBiZSB2YWxpZAogICAgICAgICAgICAgICAgICAgLSAxIGVycm9yICB0aGVyZSB3YXMgYSBlcnJvciBkZXRlY3RlZCBkdXJpbmcgZGVjb2RpbmcgZXNjYXBlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4gYWxsIGVzY2FwZXMgYXJlIGludmFsaWQKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYwp2b2lkIHJ2bGNEZWNvZGVFc2NhcGVzIChDRXJSdmxjSW5mbyAgICAgICAgICAqcFJ2bGMsCiAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICAgICAgICAgICAgICAgICpwRXNjLAogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMpCnsKICBTQ0hBUiAgZXNjV29yZDsKICBTQ0hBUiAgZXNjQ250PTA7CiAgU0hPUlQqIHBFc2NCaXRDbnRTdW07CgogIHBFc2NCaXRDbnRTdW0gPSAmKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKTsKCiAgLyogRGVjb2RlIGFsbCBSVkxDLUVzY2FwZSB3b3JkcyB3aXRoIGEgcGxhaW4gSHVmZm1hbi1EZWNvZGVyICovCiAgd2hpbGUgKCAqcEVzY0JpdENudFN1bSA+IDAgKSB7CiAgICBlc2NXb3JkID0gcnZsY0RlY29kZUVzY2FwZVdvcmQocFJ2bGMsIGJzKTsKCiAgICBpZiAoZXNjV29yZCA+PSAwKSB7CgogICAgICBwRXNjW2VzY0NudF0gPSBlc2NXb3JkOwogICAgICBlc2NDbnQrKzsKICAgIH0KICAgIGVsc2UgewogICAgICBwUnZsYy0+ZXJyb3JMb2dSdmxjIHw9IFJWTENfRVJST1JfQUxMX0VTQ0FQRV9XT1JEU19JTlZBTElEOwogICAgICBwUnZsYy0+bnVtRGVjb2RlZEVzY2FwZVdvcmRzRXNjID0gZXNjQ250OwoKICAgICAgcmV0dXJuOwogICAgfQogIH0gLyogYWxsIFJWTEMgZXNjYXBlcyBkZWNvZGVkICovCgogIHBSdmxjLT5udW1EZWNvZGVkRXNjYXBlV29yZHNFc2MgPSBlc2NDbnQ7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGZ1bmN0aW9uOiAgICAgZGVjb2RlUlZMQ29kZXdvcmQKCiAgICAgZGVzY3JpcHRpb246ICBEZWNvZGVzIGEgUlZMLWNvZGVkIGRwY20td29yZCAoLXBhcnQpLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlucHV0OiAgICAgLSBGREsgYml0c3RyZWFtIGhhbmRsZQogICAgICAgICAgICAgICAgICAgLSBwb2ludGVyIHJ2bGMgc3RydWN0dXJlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgICAtIGEgZHBjbSB2YWx1ZSB3aGljaCBpcyB3aXRoaW4gcmFuZ2UgWzAsMSwuLiwxNF0gaW4gY2FzZSBvZiBubyBlcnJvcnMuCiAgICAgICAgICAgICAgICAgICAgIFRoZSBvZmZzZXQgb2YgNyBtdXN0IGJlIHN1YnRyYWN0ZWQgdG8gZ2V0IGEgdmFsaWQgZHBjbSBzY2FsZWZhY3RvciB2YWx1ZS4KICAgICAgICAgICAgICAgICAgICAgSW4gY2FzZSBvZiBlcnJvcnMgYSBmb3JiaWRkZW4gY29kZXdvcmQgaXMgZGV0ZWN0ZWQgLS0+IHJldHVybmluZyAtMQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKU0NIQVIgZGVjb2RlUlZMQ29kZXdvcmQgKEhBTkRMRV9GREtfQklUU1RSRUFNICBicywgQ0VyUnZsY0luZm8gKnBSdmxjKQp7CiAgaW50ICAgICBpOwogIFNDSEFSICAgdmFsdWU7CiAgVUNIQVIgICBjYXJyeUJpdDsKICBVSU5UICAgIGJyYW5jaFZhbHVlOwogIFVJTlQgICAgYnJhbmNoTm9kZTsKCiAgY29uc3QgVUlOVCAqcFJ2bENvZGVUcmVlID0gcFJ2bGMtPnBIdWZmVHJlZVJ2bENvZGV3ZHM7CiAgVUNIQVIgICBkaXJlY3Rpb24gICAgICAgID0gcFJ2bGMtPmRpcmVjdGlvbjsKICBVU0hPUlQgKnBCaXRzdHJJbmR4UnZsICAgPSBwUnZsYy0+cEJpdHN0ckluZHhSdmxfUlZMOwogIFVJTlQgICAgdHJlZU5vZGUgICAgICAgICA9ICpwUnZsQ29kZVRyZWU7CgogIGZvciAoaT1NQVhfTEVOX1JWTENfQ09ERV9XT1JELTE7IGkgPj0gMDsgaS0tKSB7IAogICAgY2FycnlCaXQgPSBydmxjUmVhZEJpdEZyb21CaXRzdHJlYW0oYnMsICAgICAgICAgICAgIC8qIGdldCBuZXh0IGJpdCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEJpdHN0ckluZHhSdmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24pOwoKICAgIENhcnJ5Qml0VG9CcmFuY2hWYWx1ZShjYXJyeUJpdCwgICAgICAgICAgICAgICAgICAgICAvKiBodWZmbWFuIGRlY29kaW5nLCBkbyBhIHNpbmdsZSBzdGVwIGluIGh1ZmZtYW4gZGVjb2RpbmcgdHJlZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWVOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICZicmFuY2hWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAmYnJhbmNoTm9kZSk7CgogICAgaWYgKChicmFuY2hOb2RlICYgVEVTVF9CSVRfMTApID09IFRFU1RfQklUXzEwKSB7ICAgIC8qIHRlc3QgYml0IDEwIDsgaWYgc2V0IC0tPiBhIFJWTEMtY29kZXdvcmQgaXMgY29tcGxldGVseSBkZWNvZGVkICovCiAgICAgIHZhbHVlID0gKFNDSEFSKSAoYnJhbmNoTm9kZSAmIENMUl9CSVRfMTApOwogICAgICAqcFJ2bGMtPnBSdmxCaXRDbnRfUlZMIC09IChNQVhfTEVOX1JWTENfQ09ERV9XT1JEIC0gaSk7ICAKICAgICAgCiAgICAgIC8qIGNoZWNrIGF2YWlsYWJsZSBiaXRzIGZvciBkZWNvZGluZyAqLwogICAgICBpZiAoKnBSdmxjLT5wUnZsQml0Q250X1JWTCA8IDApIHsKICAgICAgICBpZiAoZGlyZWN0aW9uID09ICBGV0QpIHsgCiAgICAgICAgICBwUnZsYy0+ZXJyb3JMb2dSdmxjIHw9IFJWTENfRVJST1JfUlZMX1NVTV9CSVRfQ09VTlRFUl9CRUxPV19aRVJPX0ZXRDsgfQogICAgICAgIGVsc2UgeyAKICAgICAgICAgIHBSdmxjLT5lcnJvckxvZ1J2bGMgfD0gUlZMQ19FUlJPUl9SVkxfU1VNX0JJVF9DT1VOVEVSX0JFTE9XX1pFUk9fQldEOyB9CiAgICAgICAgdmFsdWUgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2lnbmFsaXplIGFuIGVycm9yIGluIHJldHVybiB2YWx1ZSwgYmVjYXVzZSB0b28gbWFueSBiaXRzIHdhcyBkZWNvZGVkICovCiAgICAgIH0KICAgICAgCiAgICAgIC8qIGNoZWNrIG1heCB2YWx1ZSBvZiBkcGNtIHZhbHVlICovCiAgICAgIGlmICh2YWx1ZSA+IE1BWF9BTExPV0VEX0RQQ01fSU5ERVgpIHsKICAgICAgICBpZiAoZGlyZWN0aW9uID09ICBGV0QpIHsgCiAgICAgICAgICBwUnZsYy0+ZXJyb3JMb2dSdmxjIHw9IFJWTENfRVJST1JfRk9SQklEREVOX0NXX0RFVEVDVEVEX0ZXRDsgCiAgICAgICAgfQogICAgICAgIGVsc2UgeyAKICAgICAgICAgIHBSdmxjLT5lcnJvckxvZ1J2bGMgfD0gUlZMQ19FUlJPUl9GT1JCSURERU5fQ1dfREVURUNURURfQldEOyAKICAgICAgICB9CiAgICAgICAgdmFsdWUgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2lnbmFsaXplIGFuIGVycm9yIGluIHJldHVybiB2YWx1ZSwgYmVjYXVzZSBhIGZvcmJpZGRlbiBjdyB3YXMgZGV0ZWN0ZWQqLwogICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKICAgICAgcmV0dXJuIHZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiByZXR1cm4gYSBkcGNtIHZhbHVlIHdpdGggb2Zmc2V0ICs3IG9yIGFuIGVycm9yIHN0YXR1cyAqLwogICAgfQogICAgZWxzZSB7CiAgICAgIHRyZWVOb2RlID0gKihwUnZsQ29kZVRyZWUgKyBicmFuY2hWYWx1ZSk7ICAgICAgICAgLyogdXBkYXRlIHRyZWVOb2RlIGZvciBmdXJ0aGVyIHN0ZXAgaW4gZGVjb2RpbmcgdHJlZSAqLwogICAgfQogIH0KICAKICByZXR1cm4gLTE7ICAKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgZnVuY3Rpb246ICAgICBydmxjRGVjb2RlRm9yd2FyZAoKICAgICBkZXNjcmlwdGlvbjogIERlY29kZSBSVkwtY29kZWQgY29kZXdvcmRzIGluIGZvcndhcmQgZGlyZWN0aW9uLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlucHV0OiAgICAgLSBwb2ludGVyIHJ2bGMgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgICAtIHBvaW50ZXIgY2hhbm5lbCBpbmZvIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgLSBoYW5kbGUgdG8gRkRLIGJpdHN0cmVhbQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIHJldHVybjogICAgLQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljCnZvaWQgcnZsY0RlY29kZUZvcndhcmQgKENFclJ2bGNJbmZvICAgICAgICAgICAgKnBSdmxjLAogICAgICAgICAgICAgICAgICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgICBicykKewogIGludCBiYW5kICA9IDA7CiAgaW50IGdyb3VwID0gMDsKICBpbnQgYm5kcyAgPSAwOwoKICBTSE9SVCBkcGNtOwoKICBTSE9SVCAgZmFjdG9yICAgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uR2xvYmFsR2FpbiAtIFNGX09GRlNFVDsKICBTSE9SVCAgcG9zaXRpb24gPSAtIFNGX09GRlNFVDsKICBTSE9SVCAgbm9pc2VucmcgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uR2xvYmFsR2FpbiAtIFNGX09GRlNFVCAtIDkwIC0gMjU2OwoKICBTSE9SVCogcFNjZkZ3ZCA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT5vdmVybGF5LmFhYy5hUnZsY1NjZkZ3ZDsKICBTSE9SVCogcFNjZkVzYyA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT5vdmVybGF5LmFhYy5hUnZsY1NjZkVzYzsKICBVQ0hBUiogcEVzY0Z3ZENudCA9ICYocFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0Z3ZCk7CiAgCiAgcFJ2bGMtPnBSdmxCaXRDbnRfUlZMID0gJihwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2ZfZndkKTsKICBwUnZsYy0+cEJpdHN0ckluZHhSdmxfUlZMID0gJihwUnZsYy0+Yml0c3RyZWFtSW5kZXhSdmxGd2QpOwoKICAqcEVzY0Z3ZENudCAgICAgICA9IDA7CiAgcFJ2bGMtPmRpcmVjdGlvbiAgPSBGV0Q7CiAgcFJ2bGMtPm5vaXNlX3VzZWQgPSAwOwogIHBSdmxjLT5zZl91c2VkICAgID0gMDsKICBwUnZsYy0+bGFzdFNjZiAgICA9IDA7CiAgcFJ2bGMtPmxhc3ROcmcgICAgPSAwOwogIHBSdmxjLT5sYXN0SXMgICAgID0gMDsgICAgICAgICAKCiAgcnZsY0NoZWNrSW50ZW5zaXR5Q2IocFJ2bGMscEFhY0RlY29kZXJDaGFubmVsSW5mbyk7CgogIC8qIG1haW4gbG9vcCBmd2QgbG9uZyAqLwogIGZvciAoZ3JvdXA9MDsgZ3JvdXAgPCBwUnZsYy0+bnVtV2luZG93R3JvdXBzOyBncm91cCsrKSB7CiAgICBmb3IgKGJhbmQ9MDsgYmFuZCA8IHBSdmxjLT5tYXhTZmJUcmFuc21pdHRlZDsgYmFuZCsrKSB7CiAgICAgIGJuZHMgPSAxNipncm91cCtiYW5kOwoKICAgICAgc3dpdGNoIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YUNvZGVCb29rW2JuZHNdKSB7CgogICAgICBjYXNlIFpFUk9fSENCIDoKICAgICAgICBwU2NmRndkW2JuZHNdID0gMDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSU5URU5TSVRZX0hDQjIgOgogICAgICBjYXNlIElOVEVOU0lUWV9IQ0IgIDoKICAgICAgICAvKiBzdG9yZSBkcGNtX2lzX3Bvc2l0aW9uICovCiAgICAgICAgZHBjbSA9IGRlY29kZVJWTENvZGV3b3JkKGJzLCBwUnZsYyk7CiAgICAgICAgaWYgKCBkcGNtIDwgMCApIHsKICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21heCA9IGJuZHM7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGRwY20gLT0gVEFCTEVfT0ZGU0VUOwogICAgICAgIGlmICgoZHBjbSA9PSBNSU5fUlZMKSB8fCAoZHBjbSA9PSBNQVhfUlZMKSkgewogICAgICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21heCA9IGJuZHM7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICBpZiAoZHBjbSA9PSBNSU5fUlZMKSB7IAogICAgICAgICAgICAgIGRwY20gLT0gKnBTY2ZFc2MrKzsgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7IAogICAgICAgICAgICAgIGRwY20gKz0gKnBTY2ZFc2MrKzsgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgKCpwRXNjRndkQ250KSsrOwogICAgICAgICAgICBpZiAocFJ2bGMtPmNvbmNlYWxfbWF4X2VzYyA9PSBDT05DRUFMX01BWF9JTklUKSB7CiAgICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4X2VzYyA9IGJuZHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcG9zaXRpb24gKz0gZHBjbTsKICAgICAgICBwU2NmRndkW2JuZHNdID0gcG9zaXRpb247CiAgICAgICAgcFJ2bGMtPmxhc3RJcyA9IHBvc2l0aW9uOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBOT0lTRV9IQ0IgOgogICAgICAgIGlmIChwUnZsYy0+bm9pc2VfdXNlZCA9PSAwKSB7CiAgICAgICAgICBwUnZsYy0+bm9pc2VfdXNlZCA9IDE7CiAgICAgICAgICBwUnZsYy0+Zmlyc3Rfbm9pc2VfYmFuZCA9IGJuZHM7CiAgICAgICAgICBub2lzZW5yZyArPSBwUnZsYy0+ZHBjbV9ub2lzZV9ucmc7CiAgICAgICAgICBwU2NmRndkW2JuZHNdID0gMTAwICsgbm9pc2Vucmc7ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICBwUnZsYy0+bGFzdE5yZyA9IG5vaXNlbnJnOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIGRwY20gPSBkZWNvZGVSVkxDb2Rld29yZChicywgcFJ2bGMpOwogICAgICAgICAgaWYgKCBkcGNtIDwgMCApIHsKICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgZHBjbSAtPSBUQUJMRV9PRkZTRVQ7CiAgICAgICAgICBpZiAoKGRwY20gPT0gTUlOX1JWTCkgfHwgKGRwY20gPT0gTUFYX1JWTCkpIHsKICAgICAgICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGRwY20gPT0gTUlOX1JWTCkgeyAKICAgICAgICAgICAgICAgIGRwY20gLT0gKnBTY2ZFc2MrKzsgCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UgeyAKICAgICAgICAgICAgICAgIGRwY20gKz0gKnBTY2ZFc2MrKzsgCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICgqcEVzY0Z3ZENudCkrKzsKICAgICAgICAgICAgICBpZiAocFJ2bGMtPmNvbmNlYWxfbWF4X2VzYyA9PSBDT05DRUFMX01BWF9JTklUKSB7CiAgICAgICAgICAgICAgICBwUnZsYy0+Y29uY2VhbF9tYXhfZXNjID0gYm5kczsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIG5vaXNlbnJnICs9IGRwY207CiAgICAgICAgICBwU2NmRndkW2JuZHNdID0gMTAwICsgbm9pc2Vucmc7CiAgICAgICAgICBwUnZsYy0+bGFzdE5yZyA9IG5vaXNlbnJnOyAgICAgICAgIAogICAgICAgIH0KICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5kYXRhLmFhYy5QbnNEYXRhLnBuc1VzZWRbYm5kc10gPSAxOwogICAgICAgIGJyZWFrIDsKCiAgICAgIGRlZmF1bHQgOgogICAgICAgIHBSdmxjLT5zZl91c2VkID0gMTsKICAgICAgICBkcGNtID0gZGVjb2RlUlZMQ29kZXdvcmQoYnMsIHBSdmxjKTsKICAgICAgICBpZiAoIGRwY20gPCAwICkgewogICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZHBjbSAtPSBUQUJMRV9PRkZTRVQ7CiAgICAgICAgaWYgKChkcGNtID09IE1JTl9SVkwpIHx8IChkcGNtID09IE1BWF9SVkwpKSB7CiAgICAgICAgICBpZiAocFJ2bGMtPmxlbmd0aF9vZl9ydmxjX2VzY2FwZXMpIHsKICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChkcGNtID09IE1JTl9SVkwpIHsgCiAgICAgICAgICAgICAgZHBjbSAtPSAqcFNjZkVzYysrOyB9CiAgICAgICAgICAgIGVsc2UgeyAKICAgICAgICAgICAgICBkcGNtICs9ICpwU2NmRXNjKys7IAogICAgICAgICAgICB9CiAgICAgICAgICAgICgqcEVzY0Z3ZENudCkrKzsKICAgICAgICAgICAgaWYgKHBSdmxjLT5jb25jZWFsX21heF9lc2MgPT0gQ09OQ0VBTF9NQVhfSU5JVCkgewogICAgICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21heF9lc2MgPSBibmRzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZhY3RvciArPSBkcGNtOwogICAgICAgIHBTY2ZGd2RbYm5kc10gPSBmYWN0b3I7CiAgICAgICAgcFJ2bGMtPmxhc3RTY2YgPSBmYWN0b3I7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIHBvc3RmZXRjaCBmd2QgbG9uZyAqLwogIGlmIChwUnZsYy0+aW50ZW5zaXR5X3VzZWQpIHsKICAgIGRwY20gPSBkZWNvZGVSVkxDb2Rld29yZChicywgcFJ2bGMpOyAgICAgIC8qIGRwY21faXNfbGFzdF9wb3NpdGlvbiAqLwogICAgaWYgKCBkcGNtIDwgMCApIHsKICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgcmV0dXJuOwogICAgfQogICAgZHBjbSAtPSBUQUJMRV9PRkZTRVQ7CiAgICBpZiAoKGRwY20gPT0gTUlOX1JWTCkgfHwgKGRwY20gPT0gTUFYX1JWTCkpIHsKICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWF4ID0gYm5kczsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgaWYgKGRwY20gPT0gTUlOX1JWTCkgeyAKICAgICAgICAgIGRwY20gLT0gKnBTY2ZFc2MrKzsgCiAgICAgICAgfQogICAgICAgIGVsc2UgeyAKICAgICAgICAgIGRwY20gKz0gKnBTY2ZFc2MrKzsgCiAgICAgICAgfQogICAgICAgICgqcEVzY0Z3ZENudCkrKzsgIAogICAgICAgIGlmIChwUnZsYy0+Y29uY2VhbF9tYXhfZXNjID09IENPTkNFQUxfTUFYX0lOSVQpIHsKICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21heF9lc2MgPSBibmRzOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcFJ2bGMtPmRwY21faXNfbGFzdF9wb3NpdGlvbiA9IGRwY207CiAgfQp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBmdW5jdGlvbjogICAgIHJ2bGNEZWNvZGVCYWNrd2FyZAoKICAgICBkZXNjcmlwdGlvbjogIERlY29kZSBSVkwtY29kZWQgY29kZXdvcmRzIGluIGJhY2t3YXJkIGRpcmVjdGlvbi4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBpbnB1dDogICAgIC0gcG9pbnRlciBydmxjIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgLSBwb2ludGVyIGNoYW5uZWwgaW5mbyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgIC0gaGFuZGxlIEZESyBiaXRzdHJlYW0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICByZXR1cm46ICAgIC0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYwp2b2lkIHJ2bGNEZWNvZGVCYWNrd2FyZCAoQ0VyUnZsY0luZm8gICAgICAgICAgICAqcFJ2bGMsCiAgICAgICAgICAgICAgICAgICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICAgYnMpCnsKICBTSE9SVCAgYmFuZCwgZ3JvdXAsIGRwY20sIG9mZnNldDsKICBTSE9SVCAgYm5kcyA9IHBSdmxjLT5tYXhTZmJUcmFuc21pdHRlZC0xOwoKICBTSE9SVCAgZmFjdG9yICAgICA9IHBSdmxjLT5yZXZfZ2xvYmFsX2dhaW4gLSBTRl9PRkZTRVQ7CiAgU0hPUlQgIHBvc2l0aW9uICAgPSBwUnZsYy0+ZHBjbV9pc19sYXN0X3Bvc2l0aW9uIC0gU0ZfT0ZGU0VUOwogIFNIT1JUICBub2lzZW5yZyAgID0gcFJ2bGMtPnJldl9nbG9iYWxfZ2FpbiArIHBSdmxjLT5kcGNtX25vaXNlX2xhc3RfcG9zaXRpb24gLSBTRl9PRkZTRVQgLSA5MCAtIDI1NjsKCiAgU0hPUlQgKnBTY2ZCd2QgICAgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+b3ZlcmxheS5hYWMuYVJ2bGNTY2ZCd2Q7CiAgU0hPUlQgKnBTY2ZFc2MgICAgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+b3ZlcmxheS5hYWMuYVJ2bGNTY2ZFc2M7CiAgVUNIQVIgKnBFc2NFc2NDbnQgPSAmKHBSdmxjLT5udW1EZWNvZGVkRXNjYXBlV29yZHNFc2MpOwogIFVDSEFSICpwRXNjQndkQ250ID0gJihwUnZsYy0+bnVtRGVjb2RlZEVzY2FwZVdvcmRzQndkKTsKCiAgcFJ2bGMtPnBSdmxCaXRDbnRfUlZMID0gJihwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2ZfYndkKTsKICBwUnZsYy0+cEJpdHN0ckluZHhSdmxfUlZMID0gJihwUnZsYy0+Yml0c3RyZWFtSW5kZXhSdmxCd2QpOwoKICAqcEVzY0J3ZENudCA9IDA7CiAgcFJ2bGMtPmRpcmVjdGlvbiA9IEJXRDsKICBwU2NmRXNjICs9ICpwRXNjRXNjQ250IC0gMTsgICAgICAgICAgICAgLyogc2V0IHBTY2ZFc2MgdG8gbGFzdCBlbnRyeSAqLwogIHBSdmxjLT5maXJzdFNjZiA9IDA7CiAgcFJ2bGMtPmZpcnN0TnJnID0gMDsKICBwUnZsYy0+Zmlyc3RJcyA9IDA7CgogIC8qIHByZWZldGNoIGxvbmcgQldEICovCiAgaWYgKHBSdmxjLT5pbnRlbnNpdHlfdXNlZCkgewogICAgZHBjbSA9IGRlY29kZVJWTENvZGV3b3JkKGJzLCBwUnZsYyk7ICAgICAgLyogZHBjbV9pc19sYXN0X3Bvc2l0aW9uICovCiAgICBpZiAoIGRwY20gPCAwICkgewogICAgICBwUnZsYy0+ZHBjbV9pc19sYXN0X3Bvc2l0aW9uID0gMDsKICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gYm5kczsKICAgICAgcmV0dXJuOwogICAgfQogICAgZHBjbSAtPSBUQUJMRV9PRkZTRVQ7CiAgICBpZiAoKGRwY20gPT0gTUlOX1JWTCkgfHwgKGRwY20gPT0gTUFYX1JWTCkpIHsKICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gYm5kczsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgaWYgKGRwY20gPT0gTUlOX1JWTCkgewogICAgICAgICAgZHBjbSAtPSAqcFNjZkVzYy0tOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIGRwY20gKz0gKnBTY2ZFc2MtLTsKICAgICAgICB9CiAgICAgICAgKCpwRXNjQndkQ250KSsrOyAgCiAgICAgICAgaWYgKHBSdmxjLT5jb25jZWFsX21pbl9lc2MgPT0gQ09OQ0VBTF9NSU5fSU5JVCkgewogICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluX2VzYyA9IGJuZHM7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBwUnZsYy0+ZHBjbV9pc19sYXN0X3Bvc2l0aW9uID0gZHBjbTsKICB9CgogIC8qIG1haW4gbG9vcCBsb25nIEJXRCAqLwogIGZvciAoZ3JvdXA9cFJ2bGMtPm51bVdpbmRvd0dyb3Vwcy0xOyBncm91cCA+PSAwOyBncm91cC0tKSB7CiAgICBmb3IgKGJhbmQ9cFJ2bGMtPm1heFNmYlRyYW5zbWl0dGVkLTE7IGJhbmQgPj0gMDsgYmFuZC0tKSB7CiAgICAgIGJuZHMgPSAxNipncm91cCtiYW5kOwogICAgICBpZiAoKGJhbmQgPT0gMCkgJiYgKHBSdmxjLT5udW1XaW5kb3dHcm91cHMgIT0gMSkpCiAgICAgICAgb2Zmc2V0ID0gMTYgLSBwUnZsYy0+bWF4U2ZiVHJhbnNtaXR0ZWQgKyAxOwogICAgICBlbHNlCiAgICAgICAgb2Zmc2V0ID0gMTsKCiAgICAgIHN3aXRjaCAocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9va1tibmRzXSkgewoKICAgICAgY2FzZSBaRVJPX0hDQiA6CiAgICAgICAgcFNjZkJ3ZFtibmRzXSA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElOVEVOU0lUWV9IQ0IyIDoKICAgICAgY2FzZSBJTlRFTlNJVFlfSENCICA6CiAgICAgICAgLyogc3RvcmUgZHBjbV9pc19wb3NpdGlvbiAqLwogICAgICAgIGRwY20gPSBkZWNvZGVSVkxDb2Rld29yZChicywgcFJ2bGMpOwogICAgICAgIGlmICggZHBjbSA8IDAgKSB7CiAgICAgICAgICBwU2NmQndkW2JuZHNdID0gcG9zaXRpb247CiAgICAgICAgICBwUnZsYy0+Y29uY2VhbF9taW4gPSBGREttYXgoMCxibmRzLW9mZnNldCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGRwY20gLT0gVEFCTEVfT0ZGU0VUOwogICAgICAgIGlmICgoZHBjbSA9PSBNSU5fUlZMKSB8fCAoZHBjbSA9PSBNQVhfUlZMKSkgewogICAgICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBwb3NpdGlvbjsKICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gRkRLbWF4KDAsYm5kcy1vZmZzZXQpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaWYgKGRwY20gPT0gTUlOX1JWTCkgewogICAgICAgICAgICAgIGRwY20gLT0gKnBTY2ZFc2MtLTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICBkcGNtICs9ICpwU2NmRXNjLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKCpwRXNjQndkQ250KSsrOwogICAgICAgICAgICBpZiAocFJ2bGMtPmNvbmNlYWxfbWluX2VzYyA9PSBDT05DRUFMX01JTl9JTklUKSB7CiAgICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluX2VzYyA9IEZES21heCgwLGJuZHMtb2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwU2NmQndkW2JuZHNdID0gcG9zaXRpb247CiAgICAgICAgcG9zaXRpb24gLT0gZHBjbTsgIAogICAgICAgIHBSdmxjLT5maXJzdElzID0gcG9zaXRpb247IAogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBOT0lTRV9IQ0IgOgogICAgICAgIGlmICggYm5kcyA9PSBwUnZsYy0+Zmlyc3Rfbm9pc2VfYmFuZCApIHsKICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBwUnZsYy0+ZHBjbV9ub2lzZV9ucmcgKyBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uR2xvYmFsR2FpbiAtIFNGX09GRlNFVCAtIDkwIC0gMjU2OyAgICAgICAgIAogICAgICAgICAgcFJ2bGMtPmZpcnN0TnJnID0gcFNjZkJ3ZFtibmRzXTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBkcGNtID0gZGVjb2RlUlZMQ29kZXdvcmQoYnMsIHBSdmxjKTsKICAgICAgICAgIGlmICggZHBjbSA8IDAgKSB7CiAgICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBub2lzZW5yZzsKICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gRkRLbWF4KDAsYm5kcy1vZmZzZXQpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBkcGNtIC09IFRBQkxFX09GRlNFVDsKICAgICAgICAgIGlmICgoZHBjbSA9PSBNSU5fUlZMKSB8fCAoZHBjbSA9PSBNQVhfUlZMKSkgewogICAgICAgICAgICBpZiAocFJ2bGMtPmxlbmd0aF9vZl9ydmxjX2VzY2FwZXMpIHsKICAgICAgICAgICAgICBwU2NmQndkW2JuZHNdID0gbm9pc2Vucmc7CiAgICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gRkRLbWF4KDAsYm5kcy1vZmZzZXQpOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICBpZiAoZHBjbSA9PSBNSU5fUlZMKSB7CiAgICAgICAgICAgICAgICBkcGNtIC09ICpwU2NmRXNjLS07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgZHBjbSArPSAqcFNjZkVzYy0tOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAoKnBFc2NCd2RDbnQpKys7CiAgICAgICAgICAgICAgaWYgKHBSdmxjLT5jb25jZWFsX21pbl9lc2MgPT0gQ09OQ0VBTF9NSU5fSU5JVCkgewogICAgICAgICAgICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluX2VzYyA9IEZES21heCgwLGJuZHMtb2Zmc2V0KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBub2lzZW5yZzsKICAgICAgICAgIG5vaXNlbnJnIC09IGRwY207CiAgICAgICAgICBwUnZsYy0+Zmlyc3ROcmcgPSBub2lzZW5yZzsKICAgICAgICB9CiAgICAgICAgYnJlYWsgOwoKICAgICAgZGVmYXVsdCA6CiAgICAgICAgZHBjbSA9IGRlY29kZVJWTENvZGV3b3JkKGJzLCBwUnZsYyk7CiAgICAgICAgaWYgKCBkcGNtIDwgMCApIHsKICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBmYWN0b3I7CiAgICAgICAgICBwUnZsYy0+Y29uY2VhbF9taW4gPSBGREttYXgoMCxibmRzLW9mZnNldCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGRwY20gLT0gVEFCTEVfT0ZGU0VUOwogICAgICAgIGlmICgoZHBjbSA9PSBNSU5fUlZMKSB8fCAoZHBjbSA9PSBNQVhfUlZMKSkgewogICAgICAgICAgaWYgKHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzKSB7CiAgICAgICAgICAgIHBTY2ZCd2RbYm5kc10gPSBmYWN0b3I7CiAgICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21pbiA9IEZES21heCgwLGJuZHMtb2Zmc2V0KTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChkcGNtID09IE1JTl9SVkwpIHsKICAgICAgICAgICAgICBkcGNtIC09ICpwU2NmRXNjLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgZHBjbSArPSAqcFNjZkVzYy0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgICgqcEVzY0J3ZENudCkrKzsKICAgICAgICAgICAgaWYgKHBSdmxjLT5jb25jZWFsX21pbl9lc2MgPT0gQ09OQ0VBTF9NSU5fSU5JVCkgewogICAgICAgICAgICAgIHBSdmxjLT5jb25jZWFsX21pbl9lc2MgPSBGREttYXgoMCxibmRzLW9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcFNjZkJ3ZFtibmRzXSA9IGZhY3RvcjsKICAgICAgICBmYWN0b3IgLT0gZHBjbTsKICAgICAgICBwUnZsYy0+Zmlyc3RTY2YgPSBmYWN0b3I7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGZ1bmN0aW9uOiAgICAgcnZsY0ZpbmFsRXJyb3JEZXRlY3Rpb24gICAgICAgICAgICAgCgogICAgIGRlc2NyaXB0aW9uOiAgQ2FsbCBSVkxDIGNvbmNlYWxtZW50IGlmIGVycm9yIHdhcyBkZXRlY3RlZCBpbiBkZWNvZGluZyBwcm9jZXNzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgaW5wdXQ6ICAgICAtIHBvaW50ZXIgcnZsYyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgIC0gcG9pbnRlciBjaGFubmVsIGluZm8gc3RydWN0dXJlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgICAtCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMKdm9pZCBydmxjRmluYWxFcnJvckRldGVjdGlvbiAoQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAgKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8pCnsKICBDRXJSdmxjSW5mbyAqcFJ2bGMgPSAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cENvbURhdGEtPm92ZXJsYXkuYWFjLmVyUnZsY0luZm87CiAgVUNIQVIgRXJyb3JTdGF0dXNDb21wbGV0ZSAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMZW5ndGhGd2QgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMZW5ndGhCd2QgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMZW5ndGhFc2NhcGVzICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNGaXJzdFNjZiAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMYXN0U2NmICAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNGaXJzdE5yZyAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMYXN0TnJnICAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNGaXJzdElzICAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNMYXN0SXMgICAgICAgICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNGb3JiaWRkZW5Dd0Z3ZCA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNGb3JiaWRkZW5Dd0J3ZCA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNOdW1Fc2NhcGVzRndkICA9IDA7CiAgVUNIQVIgRXJyb3JTdGF0dXNOdW1Fc2NhcGVzQndkICA9IDA7CiAgVUNIQVIgQ29uY2VhbFN0YXR1cyAgICAgICAgICAgICA9IDE7CiAgVUNIQVIgY3VycmVudEJsb2NrVHlwZTsgIC8qIHNob3J0OiAwLCBub3Qgc2hvcnQ6IDEqLwoKI2lmIFZFUkJPU0VfUlZMQ19PVVRQVVQKICBDSEFSICBTdHJhdGVneVs2MF09Ik5vIjsKICBTSE9SVCBjb25jZWFsX21heDsKICBTSE9SVCBjb25jZWFsX21pbjsKI2VuZGlmCgogIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5ydmxjQ3VycmVudFNjYWxlRmFjdG9yT0sgPSAxOwoKICAvKiBpbnZhbGlkIGVzY2FwZSB3b3JkcywgYml0IGNvdW50ZXIgdW5lcXVhbCB6ZXJvLCBmb3JiaWRkZW4gY29kZXdvcmQgZGV0ZWN0ZWQgKi8KICBpZiAocFJ2bGMtPmVycm9yTG9nUnZsYyAmIFJWTENfRVJST1JfRk9SQklEREVOX0NXX0RFVEVDVEVEX0ZXRCkKICAgIEVycm9yU3RhdHVzRm9yYmlkZGVuQ3dGd2QgPSAxOwoKICBpZiAocFJ2bGMtPmVycm9yTG9nUnZsYyAmIFJWTENfRVJST1JfRk9SQklEREVOX0NXX0RFVEVDVEVEX0JXRCkKICAgIEVycm9yU3RhdHVzRm9yYmlkZGVuQ3dCd2QgPSAxOwoKICAvKiBiaXQgY291bnRlciBmb3J3YXJkIHVuZXF1YWwgemVybyAqLwogIGlmIChwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2ZfZndkKQogICAgRXJyb3JTdGF0dXNMZW5ndGhGd2QgPSAxOwoKICAvKiBiaXQgY291bnRlciBiYWNrd2FyZCB1bmVxdWFsIHplcm8gKi8KICBpZiAocFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmX2J3ZCkKICAgIEVycm9yU3RhdHVzTGVuZ3RoQndkID0gMTsKCiAgLyogYml0IGNvdW50ZXIgZXNjYXBlIHNlcXVlbmNlcyB1bmVxdWFsIHplcm8gKi8KICBpZiAocFJ2bGMtPnNmX2VzY2FwZXNfcHJlc2VudCkKICAgIGlmIChwUnZsYy0+bGVuZ3RoX29mX3J2bGNfZXNjYXBlcykKICAgICAgRXJyb3JTdGF0dXNMZW5ndGhFc2NhcGVzID0gMTsKCiAgaWYgKHBSdmxjLT5zZl91c2VkKSB7CiAgICAvKiBmaXJzdCBkZWNvZGVkIHNjZiBkb2VzIG5vdCBtYXRjaCB0byBnbG9iYWwgZ2FpbiBpbiBiYWNrd2FyZCBkaXJlY3Rpb24gKi8KICAgIGlmIChwUnZsYy0+Zmlyc3RTY2YgIT0gKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5HbG9iYWxHYWluIC0gU0ZfT0ZGU0VUKSApIAogICAgICBFcnJvclN0YXR1c0ZpcnN0U2NmID0gMTsKCiAgICAvKiBsYXN0IGRlY29kZWQgc2NmIGRvZXMgbm90IG1hdGNoIHRvIHJldiBnbG9iYWwgZ2FpbiBpbiBmb3J3YXJkIGRpcmVjdGlvbiAqLwogICAgaWYgKHBSdmxjLT5sYXN0U2NmICE9IChwUnZsYy0+cmV2X2dsb2JhbF9nYWluIC0gU0ZfT0ZGU0VUKSApIAogICAgICBFcnJvclN0YXR1c0xhc3RTY2YgPSAxOwogIH0KCiAgaWYgKHBSdmxjLT5ub2lzZV91c2VkKSB7CiAgICAvKiBmaXJzdCBkZWNvZGVkIG5yZyBkb2VzIG5vdCBtYXRjaCB0byBkcGNtX25vaXNlX25yZyBpbiBiYWNrd2FyZCBkaXJlY3Rpb24gKi8KICAgIGlmIChwUnZsYy0+Zmlyc3ROcmcgIT0gKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5HbG9iYWxHYWluICsgcFJ2bGMtPmRwY21fbm9pc2VfbnJnIC0gU0ZfT0ZGU0VUIC05MCAtIDI1NikgKSAKICAgICAgRXJyb3JTdGF0dXNGaXJzdE5yZyA9IDE7CgogICAgLyogbGFzdCBkZWNvZGVkIG5yZyBkb2VzIG5vdCBtYXRjaCB0byBkcGNtX25vaXNlX2xhc3RfcG9zaXRpb24gaW4gZm9yd2FyZCBkaXJlY3Rpb24gKi8KICAgIGlmIChwUnZsYy0+bGFzdE5yZyAhPSAocFJ2bGMtPnJldl9nbG9iYWxfZ2FpbiArIHBSdmxjLT5kcGNtX25vaXNlX2xhc3RfcG9zaXRpb24gLSBTRl9PRkZTRVQgLSA5MCAtIDI1NikgKSAKICAgICAgRXJyb3JTdGF0dXNMYXN0TnJnID0gMTsKICB9CgogIGlmIChwUnZsYy0+aW50ZW5zaXR5X3VzZWQpIHsKICAgIC8qIGZpcnN0IGRlY29kZWQgaXMgcG9zaXRpb24gZG9lcyBub3QgbWF0Y2ggaW4gYmFja3dhcmQgZGlyZWN0aW9uICovCiAgICBpZiAocFJ2bGMtPmZpcnN0SXMgIT0gKC1TRl9PRkZTRVQpICkgCiAgICAgIEVycm9yU3RhdHVzRmlyc3RJcyA9IDE7CgogICAgLyogbGFzdCBkZWNvZGVkIGlzIHBvc2l0aW9uIGRvZXMgbm90IG1hdGNoIGluIGZvcndhcmQgZGlyZWN0aW9uICovCiAgICBpZiAocFJ2bGMtPmxhc3RJcyAhPSAocFJ2bGMtPmRwY21faXNfbGFzdF9wb3NpdGlvbiAtIFNGX09GRlNFVCkgKSAKICAgICAgRXJyb3JTdGF0dXNMYXN0SXMgPSAxOwogIH0KCiAgLyogZGVjb2RlZCBlc2NhcGVzIGFuZCB1c2VkIGVzY2FwZXMgaW4gZm9yd2FyZCBkaXJlY3Rpb24gZG8gbm90IGZpdCAqLwogIGlmICgocFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0Z3ZCAhPSBwUnZsYy0+bnVtRGVjb2RlZEVzY2FwZVdvcmRzRXNjKSAmJiAocFJ2bGMtPmNvbmNlYWxfbWF4ID09IENPTkNFQUxfTUFYX0lOSVQpKSB7CiAgICBFcnJvclN0YXR1c051bUVzY2FwZXNGd2QgPSAxOwogIH0KCiAgLyogZGVjb2RlZCBlc2NhcGVzIGFuZCB1c2VkIGVzY2FwZXMgaW4gYmFja3dhcmQgZGlyZWN0aW9uIGRvIG5vdCBmaXQgKi8KICBpZiAoKHBSdmxjLT5udW1EZWNvZGVkRXNjYXBlV29yZHNCd2QgIT0gcFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0VzYykgJiYgKHBSdmxjLT5jb25jZWFsX21pbiA9PSBDT05DRUFMX01JTl9JTklUKSkgewogICAgRXJyb3JTdGF0dXNOdW1Fc2NhcGVzQndkID0gMTsKICB9CgojaWYgVkVSQk9TRV9SVkxDX09VVFBVVAogIGNvbmNlYWxfbWF4ID0gcFJ2bGMtPmNvbmNlYWxfbWF4OwogIGNvbmNlYWxfbWluID0gcFJ2bGMtPmNvbmNlYWxfbWluOwojZW5kaWYKCiAgaWYgKCAgICBFcnJvclN0YXR1c0xlbmd0aEVzY2FwZXMKICAgICAgfHwgKCAKICAgICAgICAgICAoICAgKHBSdmxjLT5jb25jZWFsX21heCA9PSBDT05DRUFMX01BWF9JTklUKSAKICAgICAgICAgICAgJiYgKHBSdmxjLT5udW1EZWNvZGVkRXNjYXBlV29yZHNGd2QgIT0gcFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0VzYykKICAgICAgICAgICAgJiYgKEVycm9yU3RhdHVzTGFzdFNjZiB8fCBFcnJvclN0YXR1c0xhc3ROcmcgfHwgRXJyb3JTdGF0dXNMYXN0SXMpICkKICAgICAgICAgICAKICAgICAgICAgICAgJiYgCgogICAgICAgICAgICggICAocFJ2bGMtPmNvbmNlYWxfbWluID09IENPTkNFQUxfTUlOX0lOSVQpIAogICAgICAgICAgICAmJiAocFJ2bGMtPm51bURlY29kZWRFc2NhcGVXb3Jkc0J3ZCAhPSBwUnZsYy0+bnVtRGVjb2RlZEVzY2FwZVdvcmRzRXNjKQogICAgICAgICAgICAmJiAoRXJyb3JTdGF0dXNGaXJzdFNjZiB8fCBFcnJvclN0YXR1c0ZpcnN0TnJnIHx8IEVycm9yU3RhdHVzRmlyc3RJcykgKSAKICAgICAgICAgKSAgICAKICAgICAgfHwgKCAgIChwUnZsYy0+Y29uY2VhbF9tYXggPT0gQ09OQ0VBTF9NQVhfSU5JVCkgCiAgICAgICAgICAmJiAoKHBSdmxjLT5yZXZfZ2xvYmFsX2dhaW4gLSBTRl9PRkZTRVQgLSBwUnZsYy0+bGFzdFNjZikgPCAtMTUpCiAgICAgICAgICkKICAgICAgfHwgKCAgIChwUnZsYy0+Y29uY2VhbF9taW4gPT0gQ09OQ0VBTF9NSU5fSU5JVCkgCiAgICAgICAgICAmJiAoKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5HbG9iYWxHYWluIC0gU0ZfT0ZGU0VUIC0gcFJ2bGMtPmZpcnN0U2NmKSA8IC0xNSkKICAgICAgICAgKQogICAgICkgewogICAgaWYgKChwUnZsYy0+Y29uY2VhbF9tYXggPT0gQ09OQ0VBTF9NQVhfSU5JVCkgfHwgKHBSdmxjLT5jb25jZWFsX21pbiA9PSBDT05DRUFMX01JTl9JTklUKSkgewogICAgICBwUnZsYy0+Y29uY2VhbF9tYXggPSAwOyAKICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gRkRLbWF4KDAsIChwUnZsYy0+bnVtV2luZG93R3JvdXBzLTEpKjE2K3BSdmxjLT5tYXhTZmJUcmFuc21pdHRlZC0xKTsKICAgIH0KICAgIGVsc2UgewogICAgICBwUnZsYy0+Y29uY2VhbF9tYXggPSBGREttaW4ocFJ2bGMtPmNvbmNlYWxfbWF4LHBSdmxjLT5jb25jZWFsX21heF9lc2MpOyAKICAgICAgcFJ2bGMtPmNvbmNlYWxfbWluID0gRkRLbWF4KHBSdmxjLT5jb25jZWFsX21pbixwUnZsYy0+Y29uY2VhbF9taW5fZXNjKTsKICAgIH0KICB9CgogIEVycm9yU3RhdHVzQ29tcGxldGUgPSAgICBFcnJvclN0YXR1c0xhc3RTY2YgfHwgRXJyb3JTdGF0dXNGaXJzdFNjZiB8fCBFcnJvclN0YXR1c0xhc3ROcmcgfHwgRXJyb3JTdGF0dXNGaXJzdE5yZwogICAgICAgICAgICAgICAgICAgICAgICB8fCBFcnJvclN0YXR1c0xhc3RJcyB8fCBFcnJvclN0YXR1c0ZpcnN0SXMgfHwgRXJyb3JTdGF0dXNGb3JiaWRkZW5Dd0Z3ZCB8fCBFcnJvclN0YXR1c0ZvcmJpZGRlbkN3QndkIAogICAgICAgICAgICAgICAgICAgICAgICB8fCBFcnJvclN0YXR1c0xlbmd0aEZ3ZCB8fCBFcnJvclN0YXR1c0xlbmd0aEJ3ZCB8fCBFcnJvclN0YXR1c0xlbmd0aEVzY2FwZXMgfHwgRXJyb3JTdGF0dXNOdW1Fc2NhcGVzRndkIAogICAgICAgICAgICAgICAgICAgICAgICB8fCBFcnJvclN0YXR1c051bUVzY2FwZXNCd2Q7CgogIGN1cnJlbnRCbG9ja1R5cGUgPSAoR2V0V2luZG93U2VxdWVuY2UoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSkgPyAwIDogMTsKCiAgIAogIGlmICghRXJyb3JTdGF0dXNDb21wbGV0ZSkgewogICAgaW50IGJhbmQ7CiAgICBpbnQgZ3JvdXA7CiAgICBpbnQgYm5kczsKICAgIGludCBsYXN0U2ZiSW5kZXg7CgogICAgbGFzdFNmYkluZGV4ID0gKHBSdmxjLT5udW1XaW5kb3dHcm91cHMgPiAxKSA/IDE2IDogNjQ7CgogICAgZm9yIChncm91cD0wOyBncm91cCA8IHBSdmxjLT5udW1XaW5kb3dHcm91cHM7IGdyb3VwKyspIHsKICAgICAgZm9yIChiYW5kPTA7IGJhbmQ8cFJ2bGMtPm1heFNmYlRyYW5zbWl0dGVkOyBiYW5kKyspIHsKICAgICAgICBibmRzID0gMTYqZ3JvdXArYmFuZDsKICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YVNjYWxlRmFjdG9yW2JuZHNdID0gcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mby0+Y29uY2VhbG1lbnRJbmZvLmFSdmxjUHJldmlvdXNTY2FsZUZhY3RvcltibmRzXSA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT5vdmVybGF5LmFhYy5hUnZsY1NjZkZ3ZFtibmRzXTsKICAgICAgfQogICAgfQoKICAgIGZvciAoZ3JvdXA9MDsgZ3JvdXAgPCBwUnZsYy0+bnVtV2luZG93R3JvdXBzOyBncm91cCsrKQogICAgewogICAgICBmb3IgKGJhbmQ9MDsgYmFuZDxwUnZsYy0+bWF4U2ZiVHJhbnNtaXR0ZWQ7IGJhbmQrKykgewogICAgICAgIGJuZHMgPSAxNipncm91cCtiYW5kOwogICAgICAgIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8tPmNvbmNlYWxtZW50SW5mby5hUnZsY1ByZXZpb3VzQ29kZWJvb2tbYm5kc10gPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YUNvZGVCb29rW2JuZHNdOwogICAgICB9CiAgICAgIGZvciAoOyBiYW5kIDxsYXN0U2ZiSW5kZXg7IGJhbmQrKykgewogICAgICAgIGJuZHMgPSAxNipncm91cCtiYW5kOwogICAgICAgIEZES19BU1NFUlQoYm5kcyA+PSAwICYmIGJuZHMgPCBSVkxDX01BWF9TRkIpOwogICAgICAgIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8tPmNvbmNlYWxtZW50SW5mby5hUnZsY1ByZXZpb3VzQ29kZWJvb2tbYm5kc10gPSBaRVJPX0hDQjsKICAgICAgfQogICAgfQogIH0KICBlbHNlIHsKICAgIGludCBiYW5kOwogICAgaW50IGdyb3VwOwoKICAgIC8qIEEgc2luZ2xlIGJpdCBlcnJvciB3YXMgZGV0ZWN0ZWQgaW4gZGVjb2Rpbmcgb2YgZHBjbSB2YWx1ZXMuIEl0IGFsc28gY291bGQgYmUgYW4gZXJyb3Igd2l0aCBtb3JlIGJpdHMgaW4gZGVjb2RpbmcKICAgICAgIG9mIGVzY2FwZXMgYW5kIGRwY20gdmFsdWVzIHdoZXJlYnkgYW4gaWxsZWdhbCBjb2Rld29yZCBmb2xsb3dlZCBub3QgZGlyZWN0bHkgYWZ0ZXIgdGhlIGNvcnJ1cHRlZCBiaXRzIGJ1dCBqdXN0IAogICAgICAgYWZ0ZXIgZGVjb2Rpbmcgc29tZSBtb3JlICh3cm9uZykgc2NhbGVmYWN0b3JzLiBVc2UgdGhlIHNtYWxsZXIgc2NhbGVmYWN0b3IgZnJvbSBmb3J3YXJkIGRlY29kaW5nLCBiYWNrd2FyZCBkZWNvZGluZwogICAgICAgYW5kIHByZXZpb3VzIGZyYW1lLiAqLwogICAgaWYgKCAgICgocFJ2bGMtPmNvbmNlYWxfbWluICE9IENPTkNFQUxfTUlOX0lOSVQpIHx8IChwUnZsYy0+Y29uY2VhbF9tYXggIT0gQ09OQ0VBTF9NQVhfSU5JVCkpICYmIChwUnZsYy0+Y29uY2VhbF9taW4gPD0gcFJ2bGMtPmNvbmNlYWxfbWF4KSAKICAgICAgICAmJiAocEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mby0+Y29uY2VhbG1lbnRJbmZvLnJ2bGNQcmV2aW91c0Jsb2NrVHlwZSA9PSBjdXJyZW50QmxvY2tUeXBlKSAmJiBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLT5jb25jZWFsbWVudEluZm8ucnZsY1ByZXZpb3VzU2NhbGVGYWN0b3JPSwogICAgICAgICYmIHBSdmxjLT5zZl9jb25jZWFsbWVudCAmJiBDb25jZWFsU3RhdHVzICkKICAgIHsKICAgICAgQmlkaXJlY3Rpb25hbEVzdGltYXRpb25fVXNlU2NmT2ZQcmV2RnJhbWVBc1JlZmVyZW5jZSAocEFhY0RlY29kZXJDaGFubmVsSW5mbywgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyk7CiAgICAgIENvbmNlYWxTdGF0dXM9MDsKI2lmIFZFUkJPU0VfUlZMQ19PVVRQVVQKICAgICAgRkRLc3RyY3B5KFN0cmF0ZWd5LCJZZXMgKEJpZGlyZWN0aW9uYWxFc3RpbWF0aW9uX1VzZVNjZk9mUHJldkZyYW1lQXNSZWZlcmVuY2UpIik7CiNlbmRpZgogICAgfQoKICAgIC8qIEEgc2luZ2xlIGJpdCBlcnJvciB3YXMgZGV0ZWN0ZWQgaW4gZGVjb2Rpbmcgb2YgZHBjbSB2YWx1ZXMuIEl0IGFsc28gY291bGQgYmUgYW4gZXJyb3Igd2l0aCBtb3JlIGJpdHMgaW4gZGVjb2RpbmcKICAgICAgIG9mIGVzY2FwZXMgYW5kIGRwY20gdmFsdWVzIHdoZXJlYnkgYW4gaWxsZWdhbCBjb2Rld29yZCBmb2xsb3dlZCBub3QgZGlyZWN0bHkgYWZ0ZXIgdGhlIGNvcnJ1cHRlZCBiaXRzIGJ1dCBqdXN0IAogICAgICAgYWZ0ZXIgZGVjb2Rpbmcgc29tZSBtb3JlICh3cm9uZykgc2NhbGVmYWN0b3JzLiBVc2UgdGhlIHNtYWxsZXIgc2NhbGVmYWN0b3IgZnJvbSBmb3J3YXJkIGFuZCBiYWNrd2FyZCBkZWNvZGluZy4gKi8KICAgIGlmICggICAocFJ2bGMtPmNvbmNlYWxfbWluIDw9IHBSdmxjLT5jb25jZWFsX21heCkgICYmICgocFJ2bGMtPmNvbmNlYWxfbWluICE9IENPTkNFQUxfTUlOX0lOSVQpIHx8IChwUnZsYy0+Y29uY2VhbF9tYXggIT0gQ09OQ0VBTF9NQVhfSU5JVCkpCiAgICAgICAgJiYgIShwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLT5jb25jZWFsbWVudEluZm8ucnZsY1ByZXZpb3VzU2NhbGVGYWN0b3JPSyAmJiBwUnZsYy0+c2ZfY29uY2VhbG1lbnQgJiYgKHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8tPmNvbmNlYWxtZW50SW5mby5ydmxjUHJldmlvdXNCbG9ja1R5cGUgPT0gY3VycmVudEJsb2NrVHlwZSkpCiAgICAgICAgJiYgQ29uY2VhbFN0YXR1cyApCiAgICB7CiAgICAgIEJpZGlyZWN0aW9uYWxFc3RpbWF0aW9uX1VzZUxvd2VyU2NmT2ZDdXJyZW50RnJhbWUgKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8pOwogICAgICBDb25jZWFsU3RhdHVzPTA7CiNpZiBWRVJCT1NFX1JWTENfT1VUUFVUCiAgICAgIEZES3N0cmNweShTdHJhdGVneSwiWWVzIChCaWRpcmVjdGlvbmFsRXN0aW1hdGlvbl9Vc2VMb3dlclNjZk9mQ3VycmVudEZyYW1lKSIpOwojZW5kaWYKICAgIH0KCiAgICAvKiBObyBlcnJvcnMgd2VyZSBkZXRlY3RlZCBpbiBkZWNvZGluZyBvZiBlc2NhcGVzIGFuZCBkcGNtIHZhbHVlcyBob3dldmVyIHRoZSBmaXJzdCBhbmQgbGFzdCB2YWx1ZSAKICAgICAgIG9mIGEgZ3JvdXAgKGlzLG5yZyxzZikgaXMgaW5jb3JyZWN0ICovICAgICAgICAgICAgICAgICAgICAgICAgCiAgICBpZiAoICAgKHBSdmxjLT5jb25jZWFsX21pbiA8PSBwUnZsYy0+Y29uY2VhbF9tYXgpICAmJiAoKEVycm9yU3RhdHVzTGFzdFNjZiAmJiBFcnJvclN0YXR1c0ZpcnN0U2NmKSAKICAgICAgICB8fCAoRXJyb3JTdGF0dXNMYXN0TnJnICYmIEVycm9yU3RhdHVzRmlyc3ROcmcpIHx8IChFcnJvclN0YXR1c0xhc3RJcyAmJiBFcnJvclN0YXR1c0ZpcnN0SXMpKSAKICAgICAgICAmJiAhKEVycm9yU3RhdHVzRm9yYmlkZGVuQ3dGd2QgfHwgRXJyb3JTdGF0dXNGb3JiaWRkZW5Dd0J3ZCB8fCBFcnJvclN0YXR1c0xlbmd0aEVzY2FwZXMgKSAmJiBDb25jZWFsU3RhdHVzKQogICAgewogICAgICBTdGF0aXN0aWNhbEVzdGltYXRpb24gKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8pOwogICAgICBDb25jZWFsU3RhdHVzPTA7CiNpZiBWRVJCT1NFX1JWTENfT1VUUFVUCiAgICAgIEZES3N0cmNweShTdHJhdGVneSwiWWVzIChTdGF0aXN0aWNhbEVzdGltYXRpb24pIik7CiNlbmRpZgogICAgfQoKICAgIC8qIEEgZXJyb3Igd2l0aCBtb3JlIGJpdHMgaW4gZGVjb2Rpbmcgb2YgZXNjYXBlcyBhbmQgZHBjbSB2YWx1ZXMgd2FzIGRldGVjdGVkLiBVc2UgdGhlIHNtYWxsZXIgc2NhbGVmYWN0b3IgZnJvbSBmb3J3YXJkIAogICAgICAgZGVjb2RpbmcsIGJhY2t3YXJkIGRlY29kaW5nIGFuZCBwcmV2aW91cyBmcmFtZS4gKi8KICAgIGlmICggICAocFJ2bGMtPmNvbmNlYWxfbWluIDw9IHBSdmxjLT5jb25jZWFsX21heCkgJiYgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mby0+Y29uY2VhbG1lbnRJbmZvLnJ2bGNQcmV2aW91c1NjYWxlRmFjdG9yT0sgJiYgcFJ2bGMtPnNmX2NvbmNlYWxtZW50CiAgICAgICAgJiYgKHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8tPmNvbmNlYWxtZW50SW5mby5ydmxjUHJldmlvdXNCbG9ja1R5cGUgPT0gY3VycmVudEJsb2NrVHlwZSkgJiYgQ29uY2VhbFN0YXR1cyApCiAgICB7CiAgICAgIFByZWRpY3RpdmVJbnRlcnBvbGF0aW9uKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8pOwogICAgICBDb25jZWFsU3RhdHVzPTA7CiNpZiBWRVJCT1NFX1JWTENfT1VUUFVUCiAgICAgIEZES3N0cmNweShTdHJhdGVneSwiWWVzIChQcmVkaWN0aXZlSW50ZXJwb2xhdGlvbikiKTsKI2VuZGlmCiAgICB9CgogICAgLyogQ2FsbCBmcmFtZSBjb25jZWFsbWVudCwgYmVjYXVzZSBubyBiZXR0ZXIgc3RyYXRlZ3kgd2FzIGZvdW5kLiBTZXR0aW5nIHRoZSBzY2FsZWZhY3RvcnMgdG8gemVybyBpcyBkb25lIGZvciBkZWJ1Z2dpbmcgCiAgICAgICBwdXJwb3NlcyAqLwogICAgaWYgKENvbmNlYWxTdGF0dXMpIHsKICAgICAgZm9yIChncm91cD0wOyBncm91cCA8IHBSdmxjLT5udW1XaW5kb3dHcm91cHM7IGdyb3VwKyspIHsKICAgICAgICBmb3IgKGJhbmQ9MDsgYmFuZDxwUnZsYy0+bWF4U2ZiVHJhbnNtaXR0ZWQ7IGJhbmQrKykgewogICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTY2FsZUZhY3RvclsxNipncm91cCtiYW5kXSA9IDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5ydmxjQ3VycmVudFNjYWxlRmFjdG9yT0sgPSAwOwojaWYgVkVSQk9TRV9SVkxDX09VVFBVVAogICAgICBGREtzdHJjcHkoU3RyYXRlZ3ksIlllcyAoRnJhbWVDb25jZWFsbWVudCkiKTsKI2VuZGlmCiAgICB9CiAgfQoKI2lmIFZFUkJPU0VfUlZMQ19PVVRQVVQKICBEZWJ1Z091dHB1dERpc3RvcnRlZEJpdHN0cmVhbXMocFJ2bGMscEFhY0RlY29kZXJDaGFubmVsSW5mbyxFcnJvclN0YXR1c0xlbmd0aEZ3ZCxFcnJvclN0YXR1c0xlbmd0aEJ3ZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JTdGF0dXNMZW5ndGhFc2NhcGVzLEVycm9yU3RhdHVzRmlyc3RTY2YsRXJyb3JTdGF0dXNMYXN0U2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvclN0YXR1c0ZpcnN0TnJnLEVycm9yU3RhdHVzTGFzdE5yZyxFcnJvclN0YXR1c0ZpcnN0SXMsRXJyb3JTdGF0dXNMYXN0SXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yU3RhdHVzRm9yYmlkZGVuQ3dGd2QsRXJyb3JTdGF0dXNGb3JiaWRkZW5Dd0J3ZCxFcnJvclN0YXR1c051bUVzY2FwZXNGd2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yU3RhdHVzTnVtRXNjYXBlc0J3ZCxjb25jZWFsX21heCxjb25jZWFsX21pbixTdHJhdGVneSk7CiNlbmRpZgp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICBmdW5jdGlvbjogICAgIENSdmxjX1JlYWQgICAgICAgICAgICAgCgogICAgIGRlc2NyaXB0aW9uOiAgUmVhZCBSVkxDIEVTQzEgZGF0YSAoc2lkZSBpbmZvKSBmcm9tIGJpdHN0cmVhbS4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBpbnB1dDogICAgIC0gcG9pbnRlciBydmxjIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgLSBwb2ludGVyIGNoYW5uZWwgaW5mbyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgIC0gcG9pbnRlciBiaXRzdHJlYW0gc3RydWN0dXJlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgICAtCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgp2b2lkIENSdmxjX1JlYWQgKAogICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICAgYnMpCnsKICBDRXJSdmxjSW5mbyAqcFJ2bGMgPSAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cENvbURhdGEtPm92ZXJsYXkuYWFjLmVyUnZsY0luZm87CgogIGludCAgZ3JvdXAsYmFuZDsKCiAgLyogUlZMQyBsb25nIHNwZWNpZmljIGluaXRpYWxpemF0aW9uICBJbml0IHBhcnQgMSBvZiAyICovCiAgcFJ2bGMtPm51bVdpbmRvd0dyb3VwcyAgID0gR2V0V2luZG93R3JvdXBzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBwUnZsYy0+bWF4U2ZiVHJhbnNtaXR0ZWQgPSBHZXRTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOwogIHBSdmxjLT5ub2lzZV91c2VkICAgICAgICAgICAgICAgPSAgMDsgICAgICAgICAgICAgICAgICAvKiBub2lzZSBkZXRlY3Rpb24gKi8KICBwUnZsYy0+ZHBjbV9ub2lzZV9ucmcgICAgICAgICAgID0gIDA7ICAgICAgICAgICAgICAgICAgLyogb25seSBmb3IgZGVidWdnaW5nICovCiAgcFJ2bGMtPmRwY21fbm9pc2VfbGFzdF9wb3NpdGlvbiA9ICAwOyAgICAgICAgICAgICAgICAgIC8qIG9ubHkgZm9yIGRlYnVnZ2luZyAqLwogIHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19lc2NhcGVzICAgPSAtMTsgLyogZGVmYXVsdCB2YWx1ZSBpcyB1c2VkIGZvciBlcnJvciBkZXRlY3Rpb24gYW5kIGNvbmNlYWxtZW50ICovCgogIC8qIHJlYWQgb25seSBlcnJvciBzZW5zaXRpdml0eSBjbGFzcyAxIGRhdGEgKEVTQyAxIC0gZGF0YSkgKi8KICBwUnZsYy0+c2ZfY29uY2VhbG1lbnQgICAgPSBGREtyZWFkQml0cyhicywxKTsgICAgICAgICAgICAgICAgICAgIC8qICMxICovCiAgcFJ2bGMtPnJldl9nbG9iYWxfZ2FpbiAgID0gRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAgICAgICAvKiAjMiAqLwoKICBpZiAoR2V0V2luZG93U2VxdWVuY2UoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSkgewogICAgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmID0gRkRLcmVhZEJpdHMoYnMsMTEpOyAgICAgICAgICAgICAgICAgLyogIzMgKi8KICB9ICAgICAgICAgICAgCiAgZWxzZSB7CiAgICBwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2YgPSBGREtyZWFkQml0cyhicyw5KTsgICAgICAgICAgICAgICAgICAvKiAjMyAqLwogIH0KCiAgLyogY2hlY2sgaWYgbm9pc2UgY29kZWJvb2sgaXMgdXNlZCAqLwogIGZvciAoZ3JvdXAgPSAwOyBncm91cCA8IHBSdmxjLT5udW1XaW5kb3dHcm91cHM7IGdyb3VwKyspIHsKICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgcFJ2bGMtPm1heFNmYlRyYW5zbWl0dGVkOyBiYW5kKyspIHsKICAgICAgaWYgKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hQ29kZUJvb2tbMTYqZ3JvdXArYmFuZF0gPT0gTk9JU0VfSENCKSB7CiAgICAgICAgcFJ2bGMtPm5vaXNlX3VzZWQgPSAxOwogICAgICAgIGJyZWFrOyAgCiAgICAgIH0KICAgIH0KICB9CgogIGlmIChwUnZsYy0+bm9pc2VfdXNlZCkgCiAgICBwUnZsYy0+ZHBjbV9ub2lzZV9ucmcgPSBGREtyZWFkQml0cyhicywgOSk7ICAgICAgICAgICAgICAvKiAjNCAgUE5TICovICAgIAoKICBwUnZsYy0+c2ZfZXNjYXBlc19wcmVzZW50ID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAgICAgIC8qICM1ICAgICAgKi8KCiAgaWYgKCBwUnZsYy0+c2ZfZXNjYXBlc19wcmVzZW50KSB7CiAgICBwUnZsYy0+bGVuZ3RoX29mX3J2bGNfZXNjYXBlcyA9IEZES3JlYWRCaXRzKGJzLCA4KTsgICAgICAvKiAjNiAgICAgICovCiAgfQoKICBpZiAocFJ2bGMtPm5vaXNlX3VzZWQpIHsgCiAgICBwUnZsYy0+ZHBjbV9ub2lzZV9sYXN0X3Bvc2l0aW9uID0gRkRLcmVhZEJpdHMoYnMsIDkpOyAgICAvKiAjNyAgUE5TICovICAgIAogICAgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmIC09IDk7CiAgfQoKICBwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2ZfZndkID0gcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmOwogIHBSdmxjLT5sZW5ndGhfb2ZfcnZsY19zZl9id2QgPSBwUnZsYy0+bGVuZ3RoX29mX3J2bGNfc2Y7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIGZ1bmN0aW9uOiAgICAgQ1J2bGNfRGVjb2RlICAgICAgICAgICAgIAoKICAgICBkZXNjcmlwdGlvbjogIERlY29kZSBydmxjIGRhdGEKICAgICAgICAgICAgICAgICAgIFRoZSBmdW5jdGlvbiByZWFkcyBib3RoIHRoZSBlc2NhcGUgc2VxdWVuY2VzIGFuZCB0aGUgc2NhbGVmYWN0b3JzIGluIGZvcndhcmQKICAgICAgICAgICAgICAgICAgIGFuZCBiYWNrd2FyZCBkaXJlY3Rpb24uIElmIGFuIGVycm9yIG9jY3VyZWQgZHVyaW5nIGRlY29kaW5nIHByb2Nlc3Mgd2hpY2ggY2FuIAogICAgICAgICAgICAgICAgICAgbm90IGJlIGNvbmNlYWxlZCB3aXRoIHRoZSBydmxjIGNvbmNlYWxtZW50IGZyYW1lIGNvbmNlYWxtZW50IHdpbGwgYmUgaW5pdGlhdGVkLiAKICAgICAgICAgICAgICAgICAgIFRoZW4gdGhlIGVsZW1lbnQgInJ2bGNDdXJyZW50U2NhbGVGYWN0b3JPSyIgaW4gdGhlIGRlY29kZXIgY2hhbm5lbCBpbmZvIGlzIHNldCAKICAgICAgICAgICAgICAgICAgIHRvIDAgb3RoZXJ3aXNlIGl0IGlzIHNldCB0byAxLiAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBpbnB1dDogICAgIC0gcG9pbnRlciBydmxjIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgLSBwb2ludGVyIGNoYW5uZWwgaW5mbyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgIC0gcG9pbnRlciB0byBwZXJzaXN0ZW50IGNoYW5uZWwgaW5mbyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgIC0gcG9pbnRlciBiaXRzdHJlYW0gc3RydWN0dXJlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgcmV0dXJuOiAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfT0sKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnZvaWQgQ1J2bGNfRGVjb2RlICgKICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgICBicwogICAgICAgICkKewogIENFclJ2bGNJbmZvICpwUnZsYyA9ICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+b3ZlcmxheS5hYWMuZXJSdmxjSW5mbzsKICBJTlQgIGJpdENudE9mZnN0OwogIFVJTlQgc2F2ZUJpdENudDsKCiAgcnZsY0luaXQocFJ2bGMscEFhY0RlY29kZXJDaGFubmVsSW5mbyxicyk7ICAKCiAgLyogc2F2ZSBiaXRzdHJlYW0gcG9zaXRpb24gKi8KICBzYXZlQml0Q250ID0gRkRLZ2V0Qml0Q250KGJzKTsKCiNpZiBSVkxDX0FEVkFOQ0VEX0JJVFNUUkVBTV9FUlJPUl9HRU5FUkFUT1JfU0YKICBHZW5lcmF0ZVNpbmdsZUJpdEVycm9yKHBSdmxjLAogICAgICAgICAgICAgICAgICAgICAgICAgJihwUnZsYy0+Yml0c3RyZWFtSW5kZXhSdmxGd2QpLAogICAgICAgICAgICAgICAgICAgICAgICAgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX3NmLAogICAgICAgICAgICAgICAgICAgICAgICAgMCk7CiNlbmRpZgoKI2lmIFJWTENfQURWQU5DRURfQklUU1RSRUFNX0VSUk9SX0dFTkVSQVRPUl9FU0MKICBpZiAocFJ2bGMtPnNmX2VzY2FwZXNfcHJlc2VudCkKICAgIEdlbmVyYXRlU2luZ2xlQml0RXJyb3IocFJ2bGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICYocFJ2bGMtPmJpdHN0cmVhbUluZGV4RXNjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFJ2bGMtPmxlbmd0aF9vZl9ydmxjX2VzY2FwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpOwojZW5kaWYKCiAgaWYgKCBwUnZsYy0+c2ZfZXNjYXBlc19wcmVzZW50KQogICAgcnZsY0RlY29kZUVzY2FwZXMocFJ2bGMsIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT5vdmVybGF5LmFhYy5hUnZsY1NjZkVzYywgYnMpOwoKICBydmxjRGVjb2RlRm9yd2FyZChwUnZsYyxwQWFjRGVjb2RlckNoYW5uZWxJbmZvLCBicyk7ICAgIAogIHJ2bGNEZWNvZGVCYWNrd2FyZChwUnZsYyxwQWFjRGVjb2RlckNoYW5uZWxJbmZvLCBicyk7CiAgcnZsY0ZpbmFsRXJyb3JEZXRlY3Rpb24ocEFhY0RlY29kZXJDaGFubmVsSW5mbywgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyk7CgogIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5ydmxjSW50ZW5zaXR5VXNlZCA9IHBSdmxjLT5pbnRlbnNpdHlfdXNlZDsKICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5kYXRhLmFhYy5QbnNEYXRhLlBuc0FjdGl2ZSA9IHBSdmxjLT5ub2lzZV91c2VkOwoKICAvKiByZXN0b3JlIGJpdHN0cmVhbSBwb3NpdGlvbiAqLwogIGJpdENudE9mZnN0ID0gc2F2ZUJpdENudCAtIEZES2dldEJpdENudChicyk7CiAgaWYoIGJpdENudE9mZnN0ICkgewogICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIGJpdENudE9mZnN0KTsKICB9Cn0KCnZvaWQgQ1J2bGNfRWxlbWVudENoZWNrICgKICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvW10sCiAgICAgICAgQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tdLAogICAgICAgIGNvbnN0IFVJTlQgZmxhZ3MsCiAgICAgICAgY29uc3QgSU5UIGVsQ2hhbm5lbHMKICAgICAgICApCnsKICBpbnQgY2g7CgogIC8qIFJlcXVpcmVkIGZvciBNUFMgcmVzaWR1YWxzLiAqLwogIGlmIChwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvID09IE5VTEwpIHsKICAgIHJldHVybjsKICB9CgogIC8qIFJWTEMgc3BlY2lmaWMgc2FuaXR5IGNoZWNrcyAqLwogIGlmICggKGZsYWdzICYgQUNfRVJfUlZMQykgJiYgKGVsQ2hhbm5lbHMgPT0gMikpIHsgLyogdG8gYmUgcmV2aWV3ZWQgKi8KICAgIGlmICggKCAocEFhY0RlY29kZXJDaGFubmVsSW5mb1swXS0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLnJ2bGNDdXJyZW50U2NhbGVGYWN0b3JPSyA9PSAwKSB8fAogICAgICAgICAgIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvWzFdLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMucnZsY0N1cnJlbnRTY2FsZUZhY3Rvck9LID09IDApICkKICAgICAgICAmJiAgcEFhY0RlY29kZXJDaGFubmVsSW5mb1swXS0+cENvbURhdGEtPmpvaW50U3RlcmVvRGF0YS5Nc01hc2tQcmVzZW50ICApIHsKICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mb1swXS0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLnJ2bGNDdXJyZW50U2NhbGVGYWN0b3JPSyA9IDA7CiAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bMV0tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5ydmxjQ3VycmVudFNjYWxlRmFjdG9yT0sgPSAwOwogICAgfQoKICAgIGlmICggICAocEFhY0RlY29kZXJDaGFubmVsSW5mb1swXS0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLnJ2bGNDdXJyZW50U2NhbGVGYWN0b3JPSyA9PSAwKQogICAgICAgICYmIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvWzFdLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMucnZsY0N1cnJlbnRTY2FsZUZhY3Rvck9LID09IDEpCiAgICAgICAgJiYgKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bMV0tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5ydmxjSW50ZW5zaXR5VXNlZCA9PSAxKSApewogICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvWzFdLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMucnZsY0N1cnJlbnRTY2FsZUZhY3Rvck9LID0gMDsKICAgIH0KICB9CgogIGZvciAoY2ggPSAwOyBjaCA8IGVsQ2hhbm5lbHM7IGNoICsrKQogIHsKICAgIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5jb25jZWFsbWVudEluZm8ucnZsY1ByZXZpb3VzQmxvY2tUeXBlID0gKEdldFdpbmRvd1NlcXVlbmNlKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+aWNzSW5mbykgPT0gRWlnaHRTaG9ydFNlcXVlbmNlKSA/IDAgOiAxOwogICAgaWYgKGZsYWdzICYgQUNfRVJfUlZMQykgewogICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLnJ2bGNQcmV2aW91c1NjYWxlRmFjdG9yT0sgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLnJ2bGNDdXJyZW50U2NhbGVGYWN0b3JPSzsKICAgIH0KICAgIGVsc2UgewogICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLnJ2bGNQcmV2aW91c1NjYWxlRmFjdG9yT0sgPSAwOwogICAgfQogIH0KfQoKCg==