Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKiAgRnJhdW5ob2ZlciBJSVMgRkRLIEFBQyBFbmNvZGVyIGxpYiAgKioqKioqKioqKioqKioqKioqCgogICBBdXRob3Iocyk6IFYuIEJhY2lnYWx1cG8KICAgRGVzY3JpcHRpb246IE1ldGFkYXRhIEVuY29kZXIgbGlicmFyeSBpbnRlcmZhY2UgZnVuY3Rpb25zCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKI2luY2x1ZGUgIm1ldGFkYXRhX21haW4uaCIKI2luY2x1ZGUgIm1ldGFkYXRhX2NvbXByZXNzb3IuaCIKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKI2luY2x1ZGUgIkZES19hdWRpby5oIgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCi8qLS0tLS0tLS0tLS0tLS0tLS0gZGVmaW5lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KI2RlZmluZSBNQVhfRFJDX0JBTkRTICAgICAgICAoMTw8NCkKI2RlZmluZSBNQVhfRFJDX0NIQU5ORUxTICAgICAgICAoOCkKI2RlZmluZSBNQVhfRFJDX0ZSQU1FTEVOICAgKDIqMTAyNCkKCi8qLS0tLS0tLS0tLS0tLS0tIHN0cnVjdHVyZSBkZWZpbml0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp0eXBlZGVmIHN0cnVjdCBBQUNfTUVUQURBVEEKewogIC8qIE1QRUc6IER5bmFtaWMgUmFuZ2UgQ29udHJvbCAqLwogIHN0cnVjdCB7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBwcm9nX3JlZl9sZXZlbF9wcmVzZW50OwogICAgU0NIQVIgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ19yZWZfbGV2ZWw7CgogICAgVUNIQVIgICAgICAgICAgICAgICAgICAgICAgICAgZHluX3JuZ19zZ25bTUFYX0RSQ19CQU5EU107CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkeW5fcm5nX2N0bFtNQVhfRFJDX0JBTkRTXTsKCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfYmFuZHNfcHJlc2VudDsKICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGRyY19iYW5kX2luY3I7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfYmFuZF90b3BbTUFYX0RSQ19CQU5EU107CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWU7CiAgICBBQUNFTkNfTUVUQURBVEFfRFJDX1BST0ZJTEUgICBkcmNfcHJvZmlsZTsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyY19UYXJnZXRSZWZMZXZlbDsgICAgLyogdXNlZCBmb3IgTGltaXRlciAqLwoKICAgIC8qIGV4Y2x1ZGVkIGNoYW5uZWxzICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlZF9jaG5zX3ByZXNlbnQ7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlX21hc2tbMl07ICAgICAgIC8qIE1BWF9OVU1CRVJfQ0hBTk5FTFMvOCAqLwogIH0gbXBlZ0RyYzsKCiAgLyogRVRTSTogYWRkdGwgYW5jaWxsYXJ5IGRhdGEgKi8KICBzdHJ1Y3QgewogICAgLyogSGVhdnkgQ29tcHJlc3Npb24gKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uX29uOyAgICAgICAgLyogZmxhZywgaWYgY29tcHJlc3Npb24gdmFsdWUgc2hvdWxkIGJlIHdyaXR0ZW4gKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uX3ZhbHVlOyAgICAgLyogY29tcHJlc3Npb24gdmFsdWUgKi8KICAgIEFBQ0VOQ19NRVRBREFUQV9EUkNfUFJPRklMRSAgIGNvbXBfcHJvZmlsZTsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBfVGFyZ2V0UmVmTGV2ZWw7ICAgLyogdXNlZCBmb3IgTGltaXRlciAqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWNvZGVfY29hcnNlX3N0YXR1czsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVjb2RlX2ZpbmVfc3RhdHVzOwogIH0gZXRzaUFuY0RhdGE7CgogIFNDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlck1peExldmVsOyAgICAgICAgICAvKiBjZW50ZXIgZG93bm1peCBsZXZlbCAoMC4uLjcsIGFjY29yZGluZyB0byB0YWJsZSkgKi8KICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBzdXJyb3VuZE1peExldmVsOyAgICAgICAgLyogc3Vycm91bmQgZG93bm1peCBsZXZlbCAoMC4uLjcsIGFjY29yZGluZyB0byB0YWJsZSkgKi8KICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVBDRU1peER3bklkeDsgICAgICAgLyogZmxhZyAqLwogIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIERteEx2bF9PbjsgICAgICAgICAgICAgICAvKiBmbGFnICovCgogIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGRvbGJ5U3Vycm91bmRNb2RlOwoKICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YU1vZGU7ICAgICAgICAgICAgLyogaW5kaWNhdGUgbWV0YSBkYXRhIG1vZGUgaW4gY3VycmVudCBmcmFtZSAoZGVsYXkgbGluZSkgKi8KCn0gQUFDX01FVEFEQVRBOwoKc3RydWN0IEZES19NRVRBREFUQV9FTkNPREVSCnsKICBJTlQgICAgICAgICAgICAgICAgbWV0YWRhdGFNb2RlOwogIEhEUkNfQ09NUCAgICAgICAgICBoRHJjQ29tcDsKICBBQUNFTkNfTWV0YURhdGEgICAgc3VibWl0dGVkTWV0YURhdGE7CgogIElOVCAgICAgICAgICAgICAgICBuQXVkaW9EYXRhRGVsYXk7CiAgSU5UICAgICAgICAgICAgICAgIG5NZXRhRGF0YURlbGF5OwogIElOVCAgICAgICAgICAgICAgICBuQ2hhbm5lbHM7CgogIElOVF9QQ00gICAgICAgICAgICBhdWRpb0RlbGF5QnVmZmVyW01BWF9EUkNfQ0hBTk5FTFMqTUFYX0RSQ19GUkFNRUxFTl07CiAgaW50ICAgICAgICAgICAgICAgIGF1ZGlvRGVsYXlJZHg7CgogIEFBQ19NRVRBREFUQSAgICAgICBtZXRhRGF0YUJ1ZmZlclszXTsKICBpbnQgICAgICAgICAgICAgICAgbWV0YURhdGFEZWxheUlkeDsKCiAgVUNIQVIgICAgICAgICAgICAgIGRyY0luZm9QYXlsb2FkWzEyXTsKICBVQ0hBUiAgICAgICAgICAgICAgZHJjRHNlUGF5bG9hZFs4XTsKCiAgSU5UICAgICAgICAgICAgICAgIG1hdHJpeF9taXhkb3duX2lkeDsKICBBQUNFTkNfRVhUX1BBWUxPQUQgZXhQYXlsb2FkWzJdOwogIElOVCAgICAgICAgICAgICAgICBuRXh0ZW5zaW9uczsKCiAgSU5UICAgICAgICAgICAgICAgIGZpbmFsaXplTWV0YURhdGE7ICAgICAgICAgICAgICAgICAgIC8qIERlbGF5IHN3aXRjaCBvZmYgYnkgb25lIGZyYW1lIGFuZCB3cml0ZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemUgdGhlIG1ldGFkYXRhIHNldHVwLiAqLwp9OwoKCi8qLS0tLS0tLS0tLS0tLS0tLSBjb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgY29uc3QgQUFDRU5DX01ldGFEYXRhIGRlZmF1bHRNZXRhRGF0YVNldHVwID0gewogICAgQUFDRU5DX01FVEFEQVRBX0RSQ19OT05FLAogICAgQUFDRU5DX01FVEFEQVRBX0RSQ19OT05FLAogICAgLSgzMTw8MTYpLAogICAgLSgzMTw8MTYpLAogICAgMCwKICAgIC0oMzE8PDE2KSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAwCn07CgpzdGF0aWMgY29uc3QgRklYUF9EQkwgZG14VGFibGVbOF0gPSB7CiAgICAoKEZJWFBfREJMKU1BWFZBTF9EQkwpLCBGTDJGWENPTlNUX0RCTCgwLjg0MWYpLCBGTDJGWENPTlNUX0RCTCgwLjcwN2YpLCBGTDJGWENPTlNUX0RCTCgwLjU5NmYpLAogICAgRkwyRlhDT05TVF9EQkwoMC41MDBmKSwgRkwyRlhDT05TVF9EQkwoMC40MjJmKSwgRkwyRlhDT05TVF9EQkwoMC4zNTVmKSwgRkwyRlhDT05TVF9EQkwoMC4wMDBmKQp9OwoKc3RhdGljIGNvbnN0IFVDSEFSIHN1cm1peDJtYXRyaXhfbWl4ZG93bl9pZHhbOF0gPSB7CiAgICAwLCAwLCAwLCAxLCAxLCAyLCAyLCAzCn07CgoKLyotLS0tLS0tLS0tLS0tLS0gZnVuY3Rpb24gZGVjbGFyYXRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIEZES19NRVRBREFUQV9FUlJPUiBXcml0ZU1ldGFkYXRhUGF5bG9hZCgKICAgICAgICBjb25zdCBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgaE1ldGFEYXRhLAogICAgICAgIGNvbnN0IEFBQ19NRVRBREFUQSAqIGNvbnN0ICBwTWV0YWRhdGEKICAgICAgICApOwoKc3RhdGljIElOVCBXcml0ZUR5bmFtaWNSYW5nZUluZm9QYXlsb2FkKAogICAgICAgIGNvbnN0IEFBQ19NRVRBREFUQSogY29uc3QgcE1ldGFkYXRhLAogICAgICAgIFVDSEFSKiBjb25zdCAgICAgICAgICAgICAgcEV4dGVuc2lvblBheWxvYWQKICAgICAgICApOwoKc3RhdGljIElOVCBXcml0ZUV0c2lBbmNpbGxhcnlEYXRhUGF5bG9hZCgKICAgICAgICBjb25zdCBBQUNfTUVUQURBVEEqIGNvbnN0IHBNZXRhZGF0YSwKICAgICAgICBVQ0hBUiogY29uc3QgICAgICAgICAgICAgIHBFeHRlbnNpb25QYXlsb2FkCiAgICAgICAgKTsKCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgQ29tcGVuc2F0ZUF1ZGlvRGVsYXkoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSIGhNZXRhRGF0YUVuYywKICAgICAgICBJTlRfUENNICogY29uc3QgICAgICAgICAgICAgcEF1ZGlvU2FtcGxlcywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgbkF1ZGlvU2FtcGxlcwogICAgICAgICk7CgpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIExvYWRTdWJtaXR0ZWRNZXRhZGF0YSgKICAgICAgICBjb25zdCBBQUNFTkNfTWV0YURhdGEgKiAgIGNvbnN0IGhNZXRhZGF0YSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICBBQUNfTUVUQURBVEEgKiBjb25zdCAgICAgICAgICAgIHBBYWNNZXRhRGF0YQogICAgICAgICk7CgpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIFByb2Nlc3NDb21wcmVzc29yKAogICAgICAgIEFBQ19NRVRBREFUQSAgICAgICAgICAgICAgICAgICAgKnBNZXRhZGF0YSwKICAgICAgICBIRFJDX0NPTVAgICAgICAgICAgICAgICAgICAgICAgICBoRHJjQ29tcCwKICAgICAgICBjb25zdCBJTlRfUENNICogY29uc3QgICAgICAgICAgICBwU2FtcGxlcywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlcwogICAgICAgICk7CgovKi0tLS0tLS0tLS0tLS0gZnVuY3Rpb24gZGVmaW5pdGlvbnMgLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgRFJDX1BST0ZJTEUgY29udmVydFByb2ZpbGUoQUFDRU5DX01FVEFEQVRBX0RSQ19QUk9GSUxFIGFhY1Byb2ZpbGUpCnsKICAgIERSQ19QUk9GSUxFIGRyY1Byb2ZpbGUgPSBEUkNfTk9ORTsKCiAgICBzd2l0Y2goYWFjUHJvZmlsZSkgewogICAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9EUkNfTk9ORTogICAgICAgICAgZHJjUHJvZmlsZSA9IERSQ19OT05FOyAgICAgICAgICBicmVhazsKICAgICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfRFJDX0ZJTE1TVEFOREFSRDogIGRyY1Byb2ZpbGUgPSBEUkNfRklMTVNUQU5EQVJEOyAgYnJlYWs7CiAgICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX0RSQ19GSUxNTElHSFQ6ICAgICBkcmNQcm9maWxlID0gRFJDX0ZJTE1MSUdIVDsgICAgIGJyZWFrOwogICAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9EUkNfTVVTSUNTVEFOREFSRDogZHJjUHJvZmlsZSA9IERSQ19NVVNJQ1NUQU5EQVJEOyBicmVhazsKICAgICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfRFJDX01VU0lDTElHSFQ6ICAgIGRyY1Byb2ZpbGUgPSBEUkNfTVVTSUNMSUdIVDsgICAgYnJlYWs7CiAgICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX0RSQ19TUEVFQ0g6ICAgICAgICBkcmNQcm9maWxlID0gRFJDX1NQRUVDSDsgICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJjUHJvZmlsZSA9IERSQ19OT05FOyAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBkcmNQcm9maWxlOwp9CgoKLyogY29udmVydCBkaWFsb2cgbm9ybWFsaXphdGlvbiB0byBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCAqLwovKiBOT1RFOiB0aGlzIG9ubHkgaXMgY29ycmVjdCwgaWYgdGhlIGRlY29kZXIgdGFyZ2V0IGxldmVsIGlzIHNldCB0byAtMzFkQiBmb3IgbGluZSBtb2RlIC8gLTIwZEIgZm9yIFJGIG1vZGUgKi8Kc3RhdGljIFVDSEFSIGRpYWxub3JtMnByb2dyZWZsdmwoY29uc3QgSU5UIGQpCnsKICAgIHJldHVybiAoKFVDSEFSKUZES21heCgwLCBGREttaW4oKC1kICsgKDE8PDEzKSkgPj4gMTQsIDEyNykpKTsKfQoKLyogY29udmVydCBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCB0byBkaWFsb2cgbm9ybWFsaXphdGlvbiAqLwpzdGF0aWMgSU5UIHByb2dyZWZsdmwyZGlhbG5vcm0oY29uc3QgVUNIQVIgcCkKewogICAgcmV0dXJuIC0oKElOVCkocDw8KDE2LTIpKSk7Cn0KCi8qIGVuY29kZSBkb3dubWl4IGxldmVscyB0byBEb3dubWl4aW5nX2xldmVsc19NUEVHNCAqLwpzdGF0aWMgU0NIQVIgZW5jb2RlRG14THZscyhjb25zdCBTQ0hBUiBjbWl4bGV2LCBjb25zdCBTQ0hBUiBzdXJtaXhsZXYpCnsKICAgIFNDSEFSIGRteEx2bHMgPSAwOwogICAgZG14THZscyB8PSAweDgwIHwgKGNtaXhsZXYgPDwgNCk7IC8qIGNlbnRlcl9taXhfbGV2ZWxfb24gKi8KICAgIGRteEx2bHMgfD0gMHgwOCB8IHN1cm1peGxldjsgICAgICAvKiBzdXJyb3VuZF9taXhfbGV2ZWxfb24gKi8KCiAgICByZXR1cm4gZG14THZsczsKfQoKLyogZW5jb2RlIEFBQyBEUkMgZ2FpbiAoSVNPL0lFQyAxNDQ5Ni0zOjIwMDUgIDQuNS4yLjcpICovCnN0YXRpYyB2b2lkIGVuY29kZUR5bnJuZyhJTlQgZ2FpbiwgVUNIQVIqIGNvbnN0IGR5bl9ybmdfY3RsLCBVQ0hBUiogY29uc3QgZHluX3JuZ19zZ24gKQp7CiAgICBpZihnYWluIDwgMCkKICAgIHsKICAgICAgKmR5bl9ybmdfc2duID0gMTsKICAgICAgZ2FpbiA9IC1nYWluOwogICAgfQogICAgZWxzZQogICAgewogICAgICAqZHluX3JuZ19zZ24gPSAwOwogICAgfQogICAgZ2FpbiA9IEZES21pbihnYWluLCgxMjc8PDE0KSk7CgogICAgKmR5bl9ybmdfY3RsID0gKFVDSEFSKSgoZ2FpbiArICgxPDwxMykpID4+IDE0KTsKfQoKLyogZGVjb2RlIEFBQyBEUkMgZ2FpbiAoSVNPL0lFQyAxNDQ5Ni0zOjIwMDUgIDQuNS4yLjcpICovCnN0YXRpYyBJTlQgZGVjb2RlRHlucm5nKGNvbnN0IFVDSEFSIGR5bl9ybmdfY3RsLCBjb25zdCBVQ0hBUiBkeW5fcm5nX3NnbikKewogICAgSU5UIHRtcCA9ICgoSU5UKWR5bl9ybmdfY3RsIDw8ICgxNi0yKSk7CiAgICBpZiAoZHluX3JuZ19zZ24pIHRtcCA9IC10bXA7CgogICAgcmV0dXJuIHRtcDsKfQoKLyogZW5jb2RlIEFBQyBjb21wcmVzc2lvbiB2YWx1ZSAoRVRTSSBUUyAxMDEgMTU0IHBhZ2UgOTkpICovCnN0YXRpYyBVQ0hBUiBlbmNvZGVDb21wcihJTlQgZ2FpbikKewogICAgVUNIQVIgeCwgeTsKICAgIElOVCB0bXA7CgogICAgLyogdG1wID0gKGludCkoKDQ4LjE2NGYgLSBnYWluKSAvIDYuMDIwNmYgKiAxNSArIDAuNWYpOyAqLwogICAgdG1wID0gKCgzMTU2NDc2IC0gZ2FpbikgKiAxNSArIDE5NzI4MykgLyAzOTQ1NjY7CgogICAgaWYgKHRtcCA+PSAyNDApIHsKICAgICAgICByZXR1cm4gMHhGRjsKICAgIH0KICAgIGVsc2UgaWYgKHRtcCA8IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHggPSB0bXAgLyAxNTsKICAgICAgICB5ID0gdG1wICUgMTU7CiAgICB9CgogICAgcmV0dXJuICh4IDw8IDQpIHwgeTsKfQoKLyogZGVjb2RlIEFBQyBjb21wcmVzc2lvbiB2YWx1ZSAoRVRTSSBUUyAxMDEgMTU0IHBhZ2UgOTkpICovCnN0YXRpYyBJTlQgZGVjb2RlQ29tcHIoY29uc3QgVUNIQVIgY29tcHIpCnsKICAgIElOVCBnYWluOwogICAgU0NIQVIgeCA9IGNvbXByID4+IDQ7ICAgICAvKiA0IE1TQiBvZiBjb21wciAqLwogICAgVUNIQVIgeSA9IChjb21wciAmIDB4MEYpOyAvKiA0IExTQiBvZiBjb21wciAqLwoKICAgIC8qIGdhaW4gPSAoSU5UKSgoNDguMTY0ZiAtIDYuMDIwNmYgKiB4IC0gMC40MDE0ZiAqIHkpICk7ICovCiAgICBnYWluID0gKElOVCkoIHNjYWxlVmFsdWUoKChMT05HKUZMMkZYQ09OU1RfREJMKDYuMDIwNmYvMTI4LmYpKig4LXgpIC0gKExPTkcpRkwyRlhDT05TVF9EQkwoMC40MDE0Zi8xMjguZikqeSksIC0oREZSQUNUX0JJVFMtMS03LTE2KSkgKTsKCiAgICByZXR1cm4gZ2FpbjsKfQoKCkZES19NRVRBREFUQV9FUlJPUiBGREtfTWV0YWRhdGFFbmNfT3BlbigKICAgICAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgKnBoTWV0YURhdGEKICAgICAgICApCnsKICAgIEZES19NRVRBREFUQV9FUlJPUiBlcnIgPSBNRVRBREFUQV9PSzsKICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiBoTWV0YURhdGEgPSBOVUxMOwoKICAgIGlmIChwaE1ldGFEYXRhID09IE5VTEwpIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5WQUxJRF9IQU5ETEU7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgKi8KICAgIGhNZXRhRGF0YSA9IChIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIpIEZES2NhbGxvYygxLCBzaXplb2YoRkRLX01FVEFEQVRBX0VOQ09ERVIpICk7CgogICAgaWYgKGhNZXRhRGF0YSA9PSBOVUxMKSB7CiAgICAgIGVyciA9IE1FVEFEQVRBX01FTU9SWV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIEZES21lbWNsZWFyKGhNZXRhRGF0YSwgc2l6ZW9mKEZES19NRVRBREFUQV9FTkNPREVSKSk7CgogICAgLyogQWxsb2NhdGUgRFJDIENvbXByZXNzb3IuICovCiAgICBpZiAoRkRLX0RSQ19HZW5lcmF0b3JfT3BlbigmaE1ldGFEYXRhLT5oRHJjQ29tcCkhPTApIHsKICAgICAgZXJyID0gTUVUQURBVEFfTUVNT1JZX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogUmV0dXJuIG1ldGFkYXRhIGluc3RhbmNlICovCiAgICAqcGhNZXRhRGF0YSA9IGhNZXRhRGF0YTsKCiAgICByZXR1cm4gZXJyOwoKYmFpbDoKICAgIEZES19NZXRhZGF0YUVuY19DbG9zZSgmaE1ldGFEYXRhKTsKICAgIHJldHVybiBlcnI7Cn0KCkZES19NRVRBREFUQV9FUlJPUiBGREtfTWV0YWRhdGFFbmNfQ2xvc2UoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSICpwaE1ldGFEYXRhCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKHBoTWV0YURhdGEgPT0gTlVMTCkgewogICAgICBlcnIgPSBNRVRBREFUQV9JTlZBTElEX0hBTkRMRTsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGlmICgqcGhNZXRhRGF0YSAhPSBOVUxMKSB7CiAgICAgIEZES19EUkNfR2VuZXJhdG9yX0Nsb3NlKCYoKnBoTWV0YURhdGEpLT5oRHJjQ29tcCk7CiAgICAgIEZES2ZyZWUoKnBoTWV0YURhdGEpOwogICAgICAqcGhNZXRhRGF0YSA9IE5VTEw7CiAgICB9CmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpGREtfTUVUQURBVEFfRVJST1IgRkRLX01ldGFkYXRhRW5jX0luaXQoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSIGhNZXRhRGF0YSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgcmVzZXRTdGF0ZXMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgYXVkaW9EZWxheSwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGgsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGUsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICBjb25zdCBDSEFOTkVMX01PREUgICAgICAgICAgY2hhbm5lbE1vZGUsCiAgICAgICAgY29uc3QgQ0hBTk5FTF9PUkRFUiAgICAgICAgIGNoYW5uZWxPcmRlcgogICAgICAgICkKewogICAgRkRLX01FVEFEQVRBX0VSUk9SIGVyciA9IE1FVEFEQVRBX09LOwogICAgaW50IGksIG5GcmFtZXMsIGRlbGF5OwoKICAgIGlmIChoTWV0YURhdGE9PU5VTEwpIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5WQUxJRF9IQU5ETEU7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBEZXRlcm1pbmUgdmFsdWVzIGZvciBkZWxheSBjb21wZW5zYXRpb24uICovCiAgICBmb3IgKG5GcmFtZXM9MCwgZGVsYXk9YXVkaW9EZWxheS1mcmFtZUxlbmd0aDsgZGVsYXk+MDsgZGVsYXktPWZyYW1lTGVuZ3RoLCBuRnJhbWVzKyspOwoKICAgIGlmICggKGhNZXRhRGF0YS0+bkNoYW5uZWxzPk1BWF9EUkNfQ0hBTk5FTFMpIHx8ICgoLWRlbGF5KT5NQVhfRFJDX0ZSQU1FTEVOKSApIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5JVF9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgd2l0aCBkZWZhdWx0IHNldHVwLiAqLwogICAgRkRLbWVtY3B5KCZoTWV0YURhdGEtPnN1Ym1pdHRlZE1ldGFEYXRhLCAmZGVmYXVsdE1ldGFEYXRhU2V0dXAsICBzaXplb2YoQUFDRU5DX01ldGFEYXRhKSk7CgogICAgaE1ldGFEYXRhLT5maW5hbGl6ZU1ldGFEYXRhID0gMDsgLyogZmluYWxpemUgbWV0YSBkYXRhIG9ubHkgd2hpbGUgb24vb2ZmIHN3aXRjaGluZywgZWxzZSBkaXNhYmxlZCAqLwoKICAgIC8qIFJlc2V0IGRlbGF5IGxpbmVzLiAqLwogICAgaWYgKCByZXNldFN0YXRlcyB8fCAoaE1ldGFEYXRhLT5uQXVkaW9EYXRhRGVsYXkhPS1kZWxheSkgfHwgKGhNZXRhRGF0YS0+bkNoYW5uZWxzIT0oSU5UKW5DaGFubmVscykgKQogICAgewogICAgICBGREttZW1jbGVhcihoTWV0YURhdGEtPmF1ZGlvRGVsYXlCdWZmZXIsIHNpemVvZihoTWV0YURhdGEtPmF1ZGlvRGVsYXlCdWZmZXIpKTsKICAgICAgRkRLbWVtY2xlYXIoaE1ldGFEYXRhLT5tZXRhRGF0YUJ1ZmZlciwgc2l6ZW9mKGhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXIpKTsKICAgICAgaE1ldGFEYXRhLT5hdWRpb0RlbGF5SWR4ID0gMDsKICAgICAgaE1ldGFEYXRhLT5tZXRhRGF0YURlbGF5SWR4ID0gMDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBFbmFibGUgbWV0YSBkYXRhLiAqLwogICAgICBpZiAoIChoTWV0YURhdGEtPm1ldGFkYXRhTW9kZT09MCkgJiYgKG1ldGFkYXRhTW9kZSE9MCkgKSB7CiAgICAgICAgLyogZGlzYWJsZSBtZXRhIGRhdGEgaW4gYWxsIGRlbGF5IGxpbmVzICovCiAgICAgICAgZm9yIChpPTA7IGk8KGludCkoc2l6ZW9mKGhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXIpL3NpemVvZihBQUNfTUVUQURBVEEpKTsgaSsrKSB7CiAgICAgICAgICBMb2FkU3VibWl0dGVkTWV0YWRhdGEoJmhNZXRhRGF0YS0+c3VibWl0dGVkTWV0YURhdGEsIG5DaGFubmVscywgMCwgJmhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXJbaV0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogRGlzYWJsZSBtZXRhIGRhdGEuKi8KICAgICAgaWYgKCAoaE1ldGFEYXRhLT5tZXRhZGF0YU1vZGUhPTApICYmIChtZXRhZGF0YU1vZGU9PTApICkgewogICAgICAgIGhNZXRhRGF0YS0+ZmluYWxpemVNZXRhRGF0YSA9IGhNZXRhRGF0YS0+bWV0YWRhdGFNb2RlOwogICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBkZWxheS4gKi8KICAgIGhNZXRhRGF0YS0+bkF1ZGlvRGF0YURlbGF5ID0gLWRlbGF5OwogICAgaE1ldGFEYXRhLT5uTWV0YURhdGFEZWxheSAgPSBuRnJhbWVzOwogICAgaE1ldGFEYXRhLT5uQ2hhbm5lbHMgICAgICAgPSBuQ2hhbm5lbHM7CiAgICBoTWV0YURhdGEtPm1ldGFkYXRhTW9kZSAgICA9IG1ldGFkYXRhTW9kZTsKCiAgICAvKiBJbml0aWFsaXplIGNvbXByZXNzb3IuICovCiAgICBpZiAobWV0YWRhdGFNb2RlICE9IDApIHsKICAgICAgICBpZiAoIEZES19EUkNfR2VuZXJhdG9yX0luaXRpYWxpemUoCiAgICAgICAgICAgICAgICAgICAgICAgICBoTWV0YURhdGEtPmhEcmNDb21wLAogICAgICAgICAgICAgICAgICAgICAgICAgRFJDX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICBEUkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbE9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgMSkgIT0gMCkKICAgICAgICB7CiAgICAgICAgICBlcnIgPSBNRVRBREFUQV9JTklUX0VSUk9SOwogICAgICAgIH0KICAgIH0KYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgUHJvY2Vzc0NvbXByZXNzb3IoCiAgICAgICAgQUFDX01FVEFEQVRBICAgICAgICAgICAgICAgICAgICAqcE1ldGFkYXRhLAogICAgICAgIEhEUkNfQ09NUCAgICAgICAgICAgICAgICAgICAgICAgIGhEcmNDb21wLAogICAgICAgIGNvbnN0IElOVF9QQ00gKiBjb25zdCAgICAgICAgICAgIHBTYW1wbGVzLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgICAgIG5TYW1wbGVzCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKCAocE1ldGFkYXRhPT1OVUxMKSB8fCAoaERyY0NvbXA9PU5VTEwpICkgewogICAgICBlcnIgPSBNRVRBREFUQV9JTlZBTElEX0hBTkRMRTsKICAgICAgcmV0dXJuIGVycjsKICAgIH0KICAgIERSQ19QUk9GSUxFIHByb2ZpbGVEcmMgID0gY29udmVydFByb2ZpbGUocE1ldGFkYXRhLT5tcGVnRHJjLmRyY19wcm9maWxlKTsKICAgIERSQ19QUk9GSUxFIHByb2ZpbGVDb21wID0gY29udmVydFByb2ZpbGUocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wX3Byb2ZpbGUpOwoKICAgIC8qIGZpcnN0LCBjaGVjayBpZiBwcm9maWxlIGlzIHNhbWUgYXMgbGFzdCBmcmFtZQogICAgICogb3RoZXJ3aXNlLCB1cGRhdGUgc2V0dXAgKi8KICAgIGlmICggKHByb2ZpbGVEcmMgIT0gRkRLX0RSQ19HZW5lcmF0b3JfZ2V0RHJjUHJvZmlsZShoRHJjQ29tcCkpCiAgICAgIHx8IChwcm9maWxlQ29tcCAhPSBGREtfRFJDX0dlbmVyYXRvcl9nZXRDb21wUHJvZmlsZShoRHJjQ29tcCkpICkKICAgIHsKICAgICAgRkRLX0RSQ19HZW5lcmF0b3Jfc2V0RHJjUHJvZmlsZShoRHJjQ29tcCwgcHJvZmlsZURyYywgcHJvZmlsZUNvbXApOwogICAgfQoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYgKHByb2ZpbGVDb21wID09IERSQ19OT05FKSB7CiAgICAgIHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcHJlc3Npb25fdmFsdWUgPSAweDgwOyAgLyogdG8gZW5zdXJlIG5vIGV4dGVybmFsIHZhbHVlcyB3aWxsIGJlIHdyaXR0ZW4gaWYgbm90IGNvbmZpZ3VyZWQgKi8KICAgIH0KCiAgICAvKiBpbiBjYXNlIG9mIGVtYmVkZGluZyBleHRlcm5hbCB2YWx1ZXMsIGNvcHkgdGhpcyBub3cgKGxpbWl0ZXIgbWF5IG92ZXJ3cml0ZSB0aGVtKSAqLwogICAgSU5UIGR5bnJuZyA9IGRlY29kZUR5bnJuZyhwTWV0YWRhdGEtPm1wZWdEcmMuZHluX3JuZ19jdGxbMF0sIHBNZXRhZGF0YS0+bXBlZ0RyYy5keW5fcm5nX3NnblswXSk7CiAgICBJTlQgY29tcHIgID0gZGVjb2RlQ29tcHIocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wcmVzc2lvbl92YWx1ZSk7CgogICAgLyogQ2FsbCBjb21wcmVzc29yICovCiAgICBpZiAoRkRLX0RSQ19HZW5lcmF0b3JfQ2FsYyhoRHJjQ29tcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZWZsdmwyZGlhbG5vcm0ocE1ldGFkYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19UYXJnZXRSZWZMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wX1RhcmdldFJlZkxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkbXhUYWJsZVtwTWV0YWRhdGEtPmNlbnRlck1peExldmVsXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZG14VGFibGVbcE1ldGFkYXRhLT5zdXJyb3VuZE1peExldmVsXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmR5bnJuZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvbXByKSAhPSAwKQogICAgewogICAgICBlcnIgPSBNRVRBREFUQV9FTkNPREVfRVJST1I7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBXcml0ZSBEUkMgdmFsdWVzICovCiAgICBwTWV0YWRhdGEtPm1wZWdEcmMuZHJjX2JhbmRfaW5jciA9IDA7CiAgICBlbmNvZGVEeW5ybmcoZHlucm5nLCBwTWV0YWRhdGEtPm1wZWdEcmMuZHluX3JuZ19jdGwsIHBNZXRhZGF0YS0+bXBlZ0RyYy5keW5fcm5nX3Nnbik7CiAgICBwTWV0YWRhdGEtPmV0c2lBbmNEYXRhLmNvbXByZXNzaW9uX3ZhbHVlID0gZW5jb2RlQ29tcHIoY29tcHIpOwoKYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KCkZES19NRVRBREFUQV9FUlJPUiBGREtfTWV0YWRhdGFFbmNfUHJvY2VzcygKICAgICAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgICAgICBoTWV0YURhdGFFbmMsCiAgICAgICAgSU5UX1BDTSAqIGNvbnN0ICAgICAgICAgICAgICAgICAgcEF1ZGlvU2FtcGxlcywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgICBuQXVkaW9TYW1wbGVzLAogICAgICAgIGNvbnN0IEFBQ0VOQ19NZXRhRGF0YSAqIGNvbnN0ICAgIHBNZXRhZGF0YSwKICAgICAgICBBQUNFTkNfRVhUX1BBWUxPQUQgKiogICAgICAgICAgICBwcE1ldGFEYXRhRXh0UGF5bG9hZCwKICAgICAgICBVSU5UICogICAgICAgICAgICAgICAgICAgICAgICAgICBuTWV0YURhdGFFeHRlbnNpb25zLAogICAgICAgIElOVCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeF9taXhkb3duX2lkeAogICAgICAgICkKewogICAgRkRLX01FVEFEQVRBX0VSUk9SIGVyciA9IE1FVEFEQVRBX09LOwogICAgaW50IG1ldGFEYXRhRGVsYXlXcml0ZUlkeCwgbWV0YURhdGFEZWxheVJlYWRJZHgsIG1ldGFkYXRhTW9kZTsKCiAgICAvKiBXaGVyZSB0byB3cml0ZSBuZXcgbWV0YSBkYXRhIGluZm8gKi8KICAgIG1ldGFEYXRhRGVsYXlXcml0ZUlkeCA9IGhNZXRhRGF0YUVuYy0+bWV0YURhdGFEZWxheUlkeDsKCiAgICAvKiBIb3cgdG8gd3JpdGUgdGhlIGRhdGEgKi8KICAgIG1ldGFkYXRhTW9kZSA9IGhNZXRhRGF0YUVuYy0+bWV0YWRhdGFNb2RlOwoKICAgIC8qIENvbXBlbnNhdGUgbWV0YSBkYXRhIGRlbGF5LiAqLwogICAgaE1ldGFEYXRhRW5jLT5tZXRhRGF0YURlbGF5SWR4Kys7CiAgICBpZiAoaE1ldGFEYXRhRW5jLT5tZXRhRGF0YURlbGF5SWR4ID4gaE1ldGFEYXRhRW5jLT5uTWV0YURhdGFEZWxheSkgaE1ldGFEYXRhRW5jLT5tZXRhRGF0YURlbGF5SWR4ID0gMDsKCiAgICAvKiBXaGVyZSB0byByZWFkIHBlbmRpbmcgbWV0YSBkYXRhIGluZm8gZnJvbS4gKi8KICAgIG1ldGFEYXRhRGVsYXlSZWFkSWR4ID0gaE1ldGFEYXRhRW5jLT5tZXRhRGF0YURlbGF5SWR4OwoKICAgIC8qIFN1Ym1pdCBuZXcgZGF0YSBpZiBhdmFpbGFibGUuICovCiAgICBpZiAocE1ldGFkYXRhIT1OVUxMKSB7CiAgICAgICAgRkRLbWVtY3B5KCZoTWV0YURhdGFFbmMtPnN1Ym1pdHRlZE1ldGFEYXRhLCBwTWV0YWRhdGEsIHNpemVvZihBQUNFTkNfTWV0YURhdGEpKTsKICAgIH0KCiAgICAvKiBXcml0ZSBvbmUgYWRkaXRpb25hbCBmcmFtZSB3aXRoIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvZiBtZXRhIGRhdGEuIEVuc3VyZSBkZWZpbmVkIGJlaGF2aW91ciBvbiBkZWNvZGVyIHNpZGUuICovCiAgICBpZiAoIChoTWV0YURhdGFFbmMtPmZpbmFsaXplTWV0YURhdGEhPTApICYmIChoTWV0YURhdGFFbmMtPm1ldGFkYXRhTW9kZT09MCkpIHsKICAgICAgRkRLbWVtY3B5KCZoTWV0YURhdGFFbmMtPnN1Ym1pdHRlZE1ldGFEYXRhLCAmZGVmYXVsdE1ldGFEYXRhU2V0dXAsICBzaXplb2YoQUFDRU5DX01ldGFEYXRhKSk7CiAgICAgIG1ldGFkYXRhTW9kZSA9IGhNZXRhRGF0YUVuYy0+ZmluYWxpemVNZXRhRGF0YTsKICAgICAgaE1ldGFEYXRhRW5jLT5maW5hbGl6ZU1ldGFEYXRhID0gMDsKICAgIH0KCiAgICAvKiBHZXQgbGFzdCBzdWJtaXR0ZWQgZGF0YS4gKi8KICAgIGlmICggKGVyciA9IExvYWRTdWJtaXR0ZWRNZXRhZGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgJmhNZXRhRGF0YUVuYy0+c3VibWl0dGVkTWV0YURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBoTWV0YURhdGFFbmMtPm5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgJmhNZXRhRGF0YUVuYy0+bWV0YURhdGFCdWZmZXJbbWV0YURhdGFEZWxheVdyaXRlSWR4XSkpICE9IE1FVEFEQVRBX09LICkKICAgIHsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogQ2FsY3VsYXRlIGNvbXByZXNzb3IgaWYgbmVjZXNzYXJ5IGFuZCB1cGRhdGEgbWV0YSBkYXRhIGluZm8gKi8KICAgIGlmIChoTWV0YURhdGFFbmMtPm1ldGFEYXRhQnVmZmVyW21ldGFEYXRhRGVsYXlXcml0ZUlkeF0ubWV0YWRhdGFNb2RlICE9IDApIHsKICAgICAgaWYgKCAoZXJyID0gUHJvY2Vzc0NvbXByZXNzb3IoCiAgICAgICAgICAgICAgICAgICAgICAgICZoTWV0YURhdGFFbmMtPm1ldGFEYXRhQnVmZmVyW21ldGFEYXRhRGVsYXlXcml0ZUlkeF0sCiAgICAgICAgICAgICAgICAgICAgICAgICBoTWV0YURhdGFFbmMtPmhEcmNDb21wLAogICAgICAgICAgICAgICAgICAgICAgICAgcEF1ZGlvU2FtcGxlcywKICAgICAgICAgICAgICAgICAgICAgICAgIG5BdWRpb1NhbXBsZXMpKSAhPSBNRVRBREFUQV9PSykKICAgICAgewogICAgICAgIC8qIEdldCBsYXN0IHN1Ym1pdHRlZCBkYXRhIGFnYWluLiAqLwogICAgICAgIExvYWRTdWJtaXR0ZWRNZXRhZGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgJmhNZXRhRGF0YUVuYy0+c3VibWl0dGVkTWV0YURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBoTWV0YURhdGFFbmMtPm5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgJmhNZXRhRGF0YUVuYy0+bWV0YURhdGFCdWZmZXJbbWV0YURhdGFEZWxheVdyaXRlSWR4XSk7CiAgICAgIH0KICAgIH0KCiAgICAvKiBDb252ZXJ0IE1ldGEgRGF0YSBzaWRlIGluZm8gdG8gYml0c3RyZWFtIGRhdGEuICovCiAgICBpZiAoIChlcnIgPSBXcml0ZU1ldGFkYXRhUGF5bG9hZChoTWV0YURhdGFFbmMsICZoTWV0YURhdGFFbmMtPm1ldGFEYXRhQnVmZmVyW21ldGFEYXRhRGVsYXlSZWFkSWR4XSkpICE9IE1FVEFEQVRBX09LICkgewogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogQXNzaWduIG1ldGEgZGF0YSB0byBvdXRwdXQgKi8KICAgICpwcE1ldGFEYXRhRXh0UGF5bG9hZCA9IGhNZXRhRGF0YUVuYy0+ZXhQYXlsb2FkOwogICAgKm5NZXRhRGF0YUV4dGVuc2lvbnMgID0gaE1ldGFEYXRhRW5jLT5uRXh0ZW5zaW9uczsKICAgICptYXRyaXhfbWl4ZG93bl9pZHggICA9IGhNZXRhRGF0YUVuYy0+bWF0cml4X21peGRvd25faWR4OwoKYmFpbDoKICAgIC8qIENvbXBlbnNhdGUgYXVkaW8gZGVsYXksIHJlc2V0IGVyciBzdGF0dXMuICovCiAgICBlcnIgPSBDb21wZW5zYXRlQXVkaW9EZWxheShoTWV0YURhdGFFbmMsIHBBdWRpb1NhbXBsZXMsIG5BdWRpb1NhbXBsZXMpOwoKICAgIHJldHVybiBlcnI7Cn0KCgpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIENvbXBlbnNhdGVBdWRpb0RlbGF5KAogICAgICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiBoTWV0YURhdGFFbmMsCiAgICAgICAgSU5UX1BDTSAqIGNvbnN0ICAgICAgICAgICAgIHBBdWRpb1NhbXBsZXMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgIG5BdWRpb1NhbXBsZXMKICAgICAgICApCnsKICAgIEZES19NRVRBREFUQV9FUlJPUiBlcnIgPSBNRVRBREFUQV9PSzsKCiAgICBpZiAoaE1ldGFEYXRhRW5jLT5uQXVkaW9EYXRhRGVsYXkpIHsKICAgICAgaW50IGksIGRlbGF5U2FtcGxlcyA9IGhNZXRhRGF0YUVuYy0+bkF1ZGlvRGF0YURlbGF5KmhNZXRhRGF0YUVuYy0+bkNoYW5uZWxzOwoKICAgICAgZm9yIChpID0gMDsgaSA8IG5BdWRpb1NhbXBsZXM7IGkrKykgewogICAgICAgIElOVF9QQ00gdG1wID0gcEF1ZGlvU2FtcGxlc1tpXTsKICAgICAgICBwQXVkaW9TYW1wbGVzW2ldID0gaE1ldGFEYXRhRW5jLT5hdWRpb0RlbGF5QnVmZmVyW2hNZXRhRGF0YUVuYy0+YXVkaW9EZWxheUlkeF07CiAgICAgICAgaE1ldGFEYXRhRW5jLT5hdWRpb0RlbGF5QnVmZmVyW2hNZXRhRGF0YUVuYy0+YXVkaW9EZWxheUlkeF0gPSB0bXA7CgogICAgICAgIGhNZXRhRGF0YUVuYy0+YXVkaW9EZWxheUlkeCsrOwogICAgICAgIGlmIChoTWV0YURhdGFFbmMtPmF1ZGlvRGVsYXlJZHggPj0gZGVsYXlTYW1wbGVzKSBoTWV0YURhdGFFbmMtPmF1ZGlvRGVsYXlJZHggPSAwOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBmdW5jdGlvbm5hbWU6IFdyaXRlTWV0YWRhdGFQYXlsb2FkCiAgZGVzY3JpcHRpb246ICBmaWxscyBhbmMgZGF0YSBhbmQgZXh0ZW5zaW9uIHBheWxvYWQKICByZXR1cm5zOiAgICAgIEVycm9yIHN0YXR1cwoKIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgV3JpdGVNZXRhZGF0YVBheWxvYWQoCiAgICAgICAgY29uc3QgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSIGhNZXRhRGF0YSwKICAgICAgICBjb25zdCBBQUNfTUVUQURBVEEgKiBjb25zdCAgICAgICAgcE1ldGFkYXRhCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKCAoaE1ldGFEYXRhPT1OVUxMKSB8fCAocE1ldGFkYXRhPT1OVUxMKSApIHsKICAgICAgICBlcnIgPSBNRVRBREFUQV9JTlZBTElEX0hBTkRMRTsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgaE1ldGFEYXRhLT5uRXh0ZW5zaW9ucyA9IDA7CiAgICBoTWV0YURhdGEtPm1hdHJpeF9taXhkb3duX2lkeCA9IC0xOwoKICAgIC8qIEFBQy1EUkMgKi8KICAgIGlmIChwTWV0YWRhdGEtPm1ldGFkYXRhTW9kZSAhPSAwKQogICAgewogICAgICAgIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLnBEYXRhICAgICAgICAgICAgICAgPSBoTWV0YURhdGEtPmRyY0luZm9QYXlsb2FkOwogICAgICAgIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLmRhdGFUeXBlICAgICAgICAgICAgPSBFWFRfRFlOQU1JQ19SQU5HRTsKICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID0gLTE7CgogICAgICAgIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLmRhdGFTaXplID0KICAgICAgICAgICAgICBXcml0ZUR5bmFtaWNSYW5nZUluZm9QYXlsb2FkKHBNZXRhZGF0YSwgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10ucERhdGEpOwoKICAgICAgICBoTWV0YURhdGEtPm5FeHRlbnNpb25zKys7CgogICAgICAgIC8qIE1hdHJpeCBNaXhkb3duIENvZWZmaWNpZW50IGluIFBDRSAqLwogICAgICAgIGlmIChwTWV0YWRhdGEtPldyaXRlUENFTWl4RHduSWR4KSB7CiAgICAgICAgICAgIGhNZXRhRGF0YS0+bWF0cml4X21peGRvd25faWR4ID0gc3VybWl4Mm1hdHJpeF9taXhkb3duX2lkeFtwTWV0YWRhdGEtPnN1cnJvdW5kTWl4TGV2ZWxdOwogICAgICAgIH0KCiAgICAgICAgLyogRVRTSSBUUyAxMDEgMTU0IChEVkIpIC0gTVBFRzQgYW5jaWxsYXJ5X2RhdGEoKSAqLwogICAgICAgIGlmIChwTWV0YWRhdGEtPm1ldGFkYXRhTW9kZSA9PSAyKSAvKiBNUDRfTUVUQURBVEFfTVBFR19FVFNJICovCiAgICAgICAgewogICAgICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5wRGF0YSAgICAgICAgICAgICAgID0gaE1ldGFEYXRhLT5kcmNEc2VQYXlsb2FkOwogICAgICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5kYXRhVHlwZSAgICAgICAgICAgID0gRVhUX0RBVEFfRUxFTUVOVDsKICAgICAgICAgICAgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10uYXNzb2NpYXRlZENoRWxlbWVudCA9IC0xOwoKICAgICAgICAgICAgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10uZGF0YVNpemUgPQogICAgICAgICAgICAgICAgIFdyaXRlRXRzaUFuY2lsbGFyeURhdGFQYXlsb2FkKHBNZXRhZGF0YSxoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5wRGF0YSk7CgogICAgICAgICAgICBoTWV0YURhdGEtPm5FeHRlbnNpb25zKys7CiAgICAgICAgfSAvKiBtZXRhZGF0YU1vZGUgPT0gMiAqLwoKICAgIH0gLyogbWV0YWRhdGFNb2RlICE9IDAgKi8KCmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpzdGF0aWMgSU5UIFdyaXRlRHluYW1pY1JhbmdlSW5mb1BheWxvYWQoCiAgICAgICAgY29uc3QgQUFDX01FVEFEQVRBKiBjb25zdCBwTWV0YWRhdGEsCiAgICAgICAgVUNIQVIqIGNvbnN0ICAgICAgICAgICAgICBwRXh0ZW5zaW9uUGF5bG9hZAogICAgICAgICkKewogICAgY29uc3QgSU5UIHBjZV90YWdfcHJlc2VudCA9IDA7ICAgICAgICAvKiB5ZXQgZml4ZWQgc2V0dGluZyEgKi8KICAgIGNvbnN0IElOVCBwcm9nX3JlZl9sZXZfcmVzX2JpdHMgPSAwOwogICAgSU5UIGksIGRyY19udW1fYmFuZHMgPSAxOwoKICAgIEZES19CSVRTVFJFQU0gYnNXcml0ZXI7CiAgICBGREtpbml0Qml0U3RyZWFtKCZic1dyaXRlciwgcEV4dGVuc2lvblBheWxvYWQsIDE2LCAwLCBCU19XUklURVIpOwoKICAgIC8qIGR5bmFtaWNfcmFuZ2VfaW5mbygpICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBwY2VfdGFnX3ByZXNlbnQsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcGNlX3RhZ19wcmVzZW50ICovCiAgICBpZiAocGNlX3RhZ19wcmVzZW50KSB7CiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIDB4MCwgNCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcGNlX2luc3RhbmNlX3RhZyAqLwogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDAsIDQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRyY190YWdfcmVzZXJ2ZWRfYml0cyAqLwogICB9CgogICAgLyogRXhjbHVkZSBjaGFubmVscyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgKHBNZXRhZGF0YS0+bXBlZ0RyYy5leGNsdWRlZF9jaG5zX3ByZXNlbnQpID8gMSA6IDAsIDEpOyAgICAgIC8qIGV4Y2x1ZGVkX2NobnNfcHJlc2VudCovCgogICAgLyogTXVsdGliYW5kIERSQyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgKHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfYmFuZHNfcHJlc2VudCkgPyAxIDogMCwgMSk7ICAgICAgICAgIC8qIGRyY19iYW5kc19wcmVzZW50ICovCiAgICBpZiAocE1ldGFkYXRhLT5tcGVnRHJjLmRyY19iYW5kc19wcmVzZW50KQogICAgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBwTWV0YWRhdGEtPm1wZWdEcmMuZHJjX2JhbmRfaW5jciwgNCk7ICAgICAgICAgICAgICAgICAgICAgIC8qIGRyY19iYW5kX2luY3IgKi8KICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19pbnRlcnBvbGF0aW9uX3NjaGVtZSwgNCk7ICAgICAgICAgICAvKiBkcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWUgKi8KICAgICAgZHJjX251bV9iYW5kcyArPSBwTWV0YWRhdGEtPm1wZWdEcmMuZHJjX2JhbmRfaW5jcjsKICAgICAgZm9yIChpPTA7IGk8ZHJjX251bV9iYW5kczsgaSsrKSB7CiAgICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19iYW5kX3RvcFtpXSwgOCk7ICAgICAgICAgICAgICAgICAgLyogZHJjX2JhbmRfdG9wICovCiAgICAgIH0KICAgIH0KCiAgICAvKiBQcm9ncmFtIFJlZmVyZW5jZSBMZXZlbCAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsX3ByZXNlbnQsIDEpOyAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3ByZXNlbnQgKi8KICAgIGlmIChwTWV0YWRhdGEtPm1wZWdEcmMucHJvZ19yZWZfbGV2ZWxfcHJlc2VudCkKICAgIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsLCA3KTsgICAgICAgICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbCAqLwogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBwcm9nX3JlZl9sZXZfcmVzX2JpdHMsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3Jlc2VydmVkX2JpdHMgKi8KICAgIH0KCiAgICAvKiBEUkMgVmFsdWVzICovCiAgICBmb3IgKGk9MDsgaTxkcmNfbnVtX2JhbmRzOyBpKyspIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgKHBNZXRhZGF0YS0+bXBlZ0RyYy5keW5fcm5nX3NnbltpXSkgPyAxIDogMCwgMSk7ICAgICAgICAgICAvKiBkeW5fcm5nX3NnblsgKi8KICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLmR5bl9ybmdfY3RsW2ldLCA3KTsgICAgICAgICAgICAgICAgICAgICAvKiBkeW5fcm5nX2N0bCAqLwogICAgfQoKICAgIC8qIHJldHVybiBudW1iZXIgb2YgdmFsaWQgYml0cyBpbiBleHRlbnNpb24gcGF5bG9hZC4gKi8KICAgIHJldHVybiBGREtnZXRWYWxpZEJpdHMoJmJzV3JpdGVyKTsKfQoKc3RhdGljIElOVCBXcml0ZUV0c2lBbmNpbGxhcnlEYXRhUGF5bG9hZCgKICAgICAgICBjb25zdCBBQUNfTUVUQURBVEEqIGNvbnN0IHBNZXRhZGF0YSwKICAgICAgICBVQ0hBUiogY29uc3QgICAgICAgICAgICAgIHBFeHRlbnNpb25QYXlsb2FkCiAgICAgICAgKQp7CiAgICBGREtfQklUU1RSRUFNIGJzV3JpdGVyOwogICAgRkRLaW5pdEJpdFN0cmVhbSgmYnNXcml0ZXIsIHBFeHRlbnNpb25QYXlsb2FkLCAxNiwgMCwgQlNfV1JJVEVSKTsKCiAgICAvKiBhbmNpbGxhcnlfZGF0YV9zeW5jICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweEJDLCA4KTsKCiAgICAvKiBic19pbmZvICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDMsIDIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbXBlZ19hdWRpb190eXBlICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBwTWV0YWRhdGEtPmRvbGJ5U3Vycm91bmRNb2RlLCAyKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZG9sYnlfc3Vycm91bmRfbW9kZSAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMHgwLCA0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkICovCgogICAgLyogYW5jaWxsYXJ5X2RhdGFfc3RhdHVzICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAwLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogMyBiaXQgUmVzZXJ2ZWQsIHNldCB0byAiMCIgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPkRteEx2bF9PbikgPyAxIDogMCwgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNF9zdGF0dXMgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIDAsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBSZXNlcnZlZCwgc2V0IHRvICIwIiAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcHJlc3Npb25fb24pID8gMSA6IDAsIDEpOyAgICAgICAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbiBzdGF0dXMgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPmV0c2lBbmNEYXRhLnRpbWVjb2RlX2NvYXJzZV9zdGF0dXMpID8gMSA6IDAsIDEpOyAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9maW5lX3N0YXR1cykgPyAxIDogMCwgMSk7ICAgLyogZmluZV9ncmFpbl90aW1lY29kZV9zdGF0dXMgKi8KCiAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNF9zdGF0dXMgKi8KICAgIGlmIChwTWV0YWRhdGEtPkRteEx2bF9PbikgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBlbmNvZGVEbXhMdmxzKHBNZXRhZGF0YS0+Y2VudGVyTWl4TGV2ZWwsIHBNZXRhZGF0YS0+c3Vycm91bmRNaXhMZXZlbCksIDgpOwogICAgfQoKICAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbl9zdGF0dXMgKi8KICAgIGlmIChwTWV0YWRhdGEtPmV0c2lBbmNEYXRhLmNvbXByZXNzaW9uX29uKSB7CiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIDB4MDEsIDgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYXVkaW8gY29kaW5nIG1vZGUgKi8KICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wcmVzc2lvbl92YWx1ZSwgOCk7ICAgICAgICAgICAgICAvKiBjb21wcmVzc2lvbiB2YWx1ZSAqLwogICAgfQoKICAgIC8qIGdyYWluLXRpbWVjb2RlIGNvYXJzZS9maW5lICovCiAgICBpZiAocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9jb2Fyc2Vfc3RhdHVzKSB7CiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIDB4MCwgMTYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbm90IHlldCBzdXBwb3J0ZWQgKi8KICAgIH0KCiAgICBpZiAocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9maW5lX3N0YXR1cykgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDAsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vdCB5ZXQgc3VwcG9ydGVkICovCiAgICB9CgogICAgcmV0dXJuIEZES2dldFZhbGlkQml0cygmYnNXcml0ZXIpOwp9CgoKc3RhdGljIEZES19NRVRBREFUQV9FUlJPUiBMb2FkU3VibWl0dGVkTWV0YWRhdGEoCiAgICAgICAgY29uc3QgQUFDRU5DX01ldGFEYXRhICogY29uc3QgICBoTWV0YWRhdGEsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YU1vZGUsCiAgICAgICAgQUFDX01FVEFEQVRBICogY29uc3QgICAgICAgICAgICBwQWFjTWV0YURhdGEKICAgICAgICApCnsKICAgIEZES19NRVRBREFUQV9FUlJPUiBlcnIgPSBNRVRBREFUQV9PSzsKCiAgICBpZiAocEFhY01ldGFEYXRhPT1OVUxMKSB7CiAgICAgIGVyciA9IE1FVEFEQVRBX0lOVkFMSURfSEFORExFOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIGluaXQgc3RydWN0ICovCiAgICAgIEZES21lbWNsZWFyKHBBYWNNZXRhRGF0YSwgc2l6ZW9mKEFBQ19NRVRBREFUQSkpOwoKICAgICAgaWYgKGhNZXRhZGF0YSE9TlVMTCkgewogICAgICAgIC8qIGNvbnZlcnQgZGF0YSAqLwogICAgICAgIHBBYWNNZXRhRGF0YS0+bXBlZ0RyYy5kcmNfcHJvZmlsZSAgICAgICAgICAgID0gaE1ldGFkYXRhLT5kcmNfcHJvZmlsZTsKICAgICAgICBwQWFjTWV0YURhdGEtPmV0c2lBbmNEYXRhLmNvbXBfcHJvZmlsZSAgICAgICA9IGhNZXRhZGF0YS0+Y29tcF9wcm9maWxlOwogICAgICAgIHBBYWNNZXRhRGF0YS0+bXBlZ0RyYy5kcmNfVGFyZ2V0UmVmTGV2ZWwgICAgID0gaE1ldGFkYXRhLT5kcmNfVGFyZ2V0UmVmTGV2ZWw7CiAgICAgICAgcEFhY01ldGFEYXRhLT5ldHNpQW5jRGF0YS5jb21wX1RhcmdldFJlZkxldmVsPSBoTWV0YWRhdGEtPmNvbXBfVGFyZ2V0UmVmTGV2ZWw7CiAgICAgICAgcEFhY01ldGFEYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsX3ByZXNlbnQgPSBoTWV0YWRhdGEtPnByb2dfcmVmX2xldmVsX3ByZXNlbnQ7CiAgICAgICAgcEFhY01ldGFEYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsICAgICAgICAgPSBkaWFsbm9ybTJwcm9ncmVmbHZsKGhNZXRhZGF0YS0+cHJvZ19yZWZfbGV2ZWwpOwoKICAgICAgICBwQWFjTWV0YURhdGEtPmNlbnRlck1peExldmVsICAgICAgICAgICAgICAgICA9IGhNZXRhZGF0YS0+Y2VudGVyTWl4TGV2ZWw7CiAgICAgICAgcEFhY01ldGFEYXRhLT5zdXJyb3VuZE1peExldmVsICAgICAgICAgICAgICAgPSBoTWV0YWRhdGEtPnN1cnJvdW5kTWl4TGV2ZWw7CiAgICAgICAgcEFhY01ldGFEYXRhLT5Xcml0ZVBDRU1peER3bklkeCAgICAgICAgICAgICAgPSBoTWV0YWRhdGEtPlBDRV9taXhkb3duX2lkeF9wcmVzZW50OwogICAgICAgIHBBYWNNZXRhRGF0YS0+RG14THZsX09uICAgICAgICAgICAgICAgICAgICAgID0gaE1ldGFkYXRhLT5FVFNJX0RteEx2bF9wcmVzZW50OwoKICAgICAgICBwQWFjTWV0YURhdGEtPmV0c2lBbmNEYXRhLmNvbXByZXNzaW9uX29uID0gMTsKCgogICAgICAgIGlmIChuQ2hhbm5lbHMgPT0gMikgewogICAgICAgICAgcEFhY01ldGFEYXRhLT5kb2xieVN1cnJvdW5kTW9kZSA9IGhNZXRhZGF0YS0+ZG9sYnlTdXJyb3VuZE1vZGU7ICAgICAvKiBkb2xieV9zdXJyb3VuZF9tb2RlICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBBYWNNZXRhRGF0YS0+ZG9sYnlTdXJyb3VuZE1vZGUgPSAwOwogICAgICAgIH0KCiAgICAgICAgcEFhY01ldGFEYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9jb2Fyc2Vfc3RhdHVzID0gMDsgLyogbm90IHlldCBzdXBwb3J0ZWQgLSBhdHRlbnRpb246IFVwZGF0ZSBHZXRFc3RNZXRhZGF0YUJ5dGVzUGVyRnJhbWUoKSBpZiBlbmFibGUgdGhpcyEgKi8KICAgICAgICBwQWFjTWV0YURhdGEtPmV0c2lBbmNEYXRhLnRpbWVjb2RlX2ZpbmVfc3RhdHVzICAgPSAwOyAvKiBub3QgeWV0IHN1cHBvcnRlZCAtIGF0dGVudGlvbjogVXBkYXRlIEdldEVzdE1ldGFkYXRhQnl0ZXNQZXJGcmFtZSgpIGlmIGVuYWJsZSB0aGlzISAqLwoKICAgICAgICBwQWFjTWV0YURhdGEtPm1ldGFkYXRhTW9kZSA9IG1ldGFkYXRhTW9kZTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBwQWFjTWV0YURhdGEtPm1ldGFkYXRhTW9kZSA9IDA7ICAgICAgICAgICAgICAgICAgICAgIC8qIHRoZXJlIGlzIG5vIGNvbmZpZ3VyYXRpb24gYXZhaWxhYmxlICovCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZXJyOwp9CgpJTlQgRkRLX01ldGFkYXRhRW5jX0dldERlbGF5KAogICAgICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiBoTWV0YWRhdGFFbmMKICAgICAgICApCnsKICAgIElOVCBkZWxheSA9IDA7CgogICAgaWYgKGhNZXRhZGF0YUVuYyE9TlVMTCkgewogICAgICAgIGRlbGF5ID0gaE1ldGFkYXRhRW5jLT5uQXVkaW9EYXRhRGVsYXk7CiAgICB9CgogICAgcmV0dXJuIGRlbGF5Owp9CgoK