Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBDaHJpc3RpYW4gR3JpZWJlbAogICBEZXNjcmlwdGlvbjogRHluYW1pYyByYW5nZSBjb250cm9sIChEUkMpIGRlY29kZXIgdG9vbCBmb3IgQUFDCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZGVjX2RyYy5oIgoKCiNpbmNsdWRlICJjaGFubmVsaW5mby5oIgojaW5jbHVkZSAiYWFjX3JvbS5oIgoKICNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgovKgogKiBEeW5hbWljIFJhbmdlIENvbnRyb2wKICovCgovKiBGb3IgcGFyYW1ldGVyIGNvbnZlcnNpb24gKi8KI2RlZmluZSBEUkNfUEFSQU1FVEVSX0JJVFMgICAgICAgICggNyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9TVEVQUyAgICAgICAoIDE8PERSQ19QQVJBTUVURVJfQklUUyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9GQUNUT1IgICAgICAoIERSQ19NQVhfUVVBTlRfU1RFUFMtMSApCiNkZWZpbmUgRFJDX1BBUkFNX1FVQU5UX1NURVAgICAgICAoIEZMMkZYQ09OU1RfREJMKDEuMGYvKGZsb2F0KURSQ19NQVhfUVVBTlRfRkFDVE9SKSApCiNkZWZpbmUgRFJDX1BBUkFNX1NDQUxFICAgICAgICAgICAoIDEgKQoKI2RlZmluZSBNQVhfUkVGRVJFTkNFX0xFVkVMICAgICAgICggMTI3ICkKCiAjZGVmaW5lIERWQl9BTkNfREFUQV9TWU5DX0JZVEUgICAoIDB4QkMgKSAgICAvKiBEVkIgYW5jaWxsYXJ5IGRhdGEgc3luYyBieXRlLiAqLwoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgRFJDIGluZm9ybWF0aW9uCgogIFxzZWxmIEhhbmRsZSBvZiBEUkMgaW5mbwoKICBccmV0dXJuIG5vbmUKKi8Kdm9pZCBhYWNEZWNvZGVyX2RyY0luaXQgKAogICAgSEFORExFX0FBQ19EUkMgc2VsZiApCnsKICBDRHJjUGFyYW1zICpwUGFyYW1zOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBpbml0IGNvbnRyb2wgZmllbGRzICovCiAgc2VsZi0+ZW5hYmxlID0gMDsKICBzZWxmLT5udW1UaHJlYWRzID0gMDsKCiAgLyogaW5pdCBwYXJhbXMgKi8KICBwUGFyYW1zID0gJnNlbGYtPnBhcmFtczsKICBwUGFyYW1zLT5ic0RlbGF5RW5hYmxlID0gMDsKICBwUGFyYW1zLT5jdXQgICAgICA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIHBQYXJhbXMtPnVzckN1dCAgID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgcFBhcmFtcy0+Ym9vc3QgICAgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBwUGFyYW1zLT51c3JCb29zdCA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIHBQYXJhbXMtPnRhcmdldFJlZkxldmVsID0gLTE7CiAgcFBhcmFtcy0+ZXhwaXJ5RnJhbWUgPSBBQUNERUNfRFJDX0RGTFRfRVhQSVJZX0ZSQU1FUzsKICBwUGFyYW1zLT5hcHBseURpZ2l0YWxOb3JtID0gMDsKICBwUGFyYW1zLT5hcHBseUhlYXZ5Q29tcHJlc3Npb24gPSAwOwoKICAvKiBpbml0aWFsIHByb2dyYW0gcmVmIGxldmVsID0gdGFyZ2V0IHJlZiBsZXZlbCAqLwogIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBQYXJhbXMtPnRhcmdldFJlZkxldmVsOwogIHNlbGYtPnByb2dSZWZMZXZlbFByZXNlbnQgPSAwOwogIHNlbGYtPnByZXNNb2RlID0gLTE7Cn0KCgovKiEKICBcYnJpZWYgSW5pdGlhbGl6ZSBEUkMgY29udHJvbCBkYXRhIGZvciBvbmUgY2hhbm5lbAoKICBcc2VsZiBIYW5kbGUgb2YgRFJDIGluZm8KCiAgXHJldHVybiBub25lCiovCnZvaWQgYWFjRGVjb2Rlcl9kcmNJbml0Q2hhbm5lbERhdGEgKAogICAgQ0RyY0NoYW5uZWxEYXRhICpwRHJjQ2hEYXRhICkKewogIGlmIChwRHJjQ2hEYXRhICE9IE5VTEwpIHsKICAgIHBEcmNDaERhdGEtPmV4cGlyeUNvdW50ID0gMDsKICAgIHBEcmNDaERhdGEtPm51bUJhbmRzICAgID0gMTsKICAgIHBEcmNDaERhdGEtPmJhbmRUb3BbMF0gID0gKDEwMjQgPj4gMikgLSAxOwogICAgcERyY0NoRGF0YS0+ZHJjVmFsdWVbMF0gPSAwOwogICAgcERyY0NoRGF0YS0+ZHJjSW50ZXJwb2xhdGlvblNjaGVtZSA9IDA7CiAgICBwRHJjQ2hEYXRhLT5kcmNEYXRhVHlwZSA9IFVOS05PV05fUEFZTE9BRDsKICB9Cn0KCgovKiEKICBcYnJpZWYgIFNldCBvbmUgc2luZ2xlIERSQyBwYXJhbWV0ZXIKCiAgXHNlbGYgICBIYW5kbGUgb2YgRFJDIGluZm8uCiAgXHBhcmFtICBQYXJhbWV0ZXIgdG8gYmUgc2V0LgogIFx2YWx1ZSAgVmFsdWUgdG8gYmUgc2V0LgoKICBccmV0dXJuIGFuIGVycm9yIGNvZGUuCiovCkFBQ19ERUNPREVSX0VSUk9SIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgSEFORExFX0FBQ19EUkMgICAgc2VsZiwKICAgIEFBQ0RFQ19EUkNfUEFSQU0gIHBhcmFtLAogICAgSU5UICAgICAgICAgICAgICAgdmFsdWUgKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgRXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwoKICBzd2l0Y2ggKHBhcmFtKQogIHsKICBjYXNlIERSQ19DVVRfU0NBTEU6CiAgICAvKiBzZXQgYXR0ZW51YXRpb24gc2NhbGUgZmFjdG9yICovCiAgICBpZiAoICh2YWx1ZSA8IDApCiAgICAgIHx8ICh2YWx1ZSA+IERSQ19NQVhfUVVBTlRfRkFDVE9SKSApIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+cGFyYW1zLnVzckN1dCA9IChGSVhQX0RCTCkoKElOVCkoRFJDX1BBUkFNX1FVQU5UX1NURVA+PkRSQ19QQVJBTV9TQ0FMRSkgKiAoSU5UKXZhbHVlKTsKICAgIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uID09IDApCiAgICAgIHNlbGYtPnBhcmFtcy5jdXQgPSBzZWxmLT5wYXJhbXMudXNyQ3V0OwogICAgYnJlYWs7CiAgY2FzZSBEUkNfQk9PU1RfU0NBTEU6CiAgICAvKiBzZXQgYm9vc3QgZmFjdG9yICovCiAgICBpZiAoICh2YWx1ZSA8IDApCiAgICAgIHx8ICh2YWx1ZSA+IERSQ19NQVhfUVVBTlRfRkFDVE9SKSApIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+cGFyYW1zLnVzckJvb3N0ID0gKEZJWFBfREJMKSgoSU5UKShEUkNfUEFSQU1fUVVBTlRfU1RFUD4+RFJDX1BBUkFNX1NDQUxFKSAqIChJTlQpdmFsdWUpOwogICAgaWYgKHNlbGYtPnBhcmFtcy5hcHBseUhlYXZ5Q29tcHJlc3Npb24gPT0gMCkKICAgICAgc2VsZi0+cGFyYW1zLmJvb3N0ID0gc2VsZi0+cGFyYW1zLnVzckJvb3N0OwogICAgYnJlYWs7CiAgY2FzZSBUQVJHRVRfUkVGX0xFVkVMOgogICAgaWYgKCB2YWx1ZSA+ICBNQVhfUkVGRVJFTkNFX0xFVkVMCiAgICAgIHx8IHZhbHVlIDwgLU1BWF9SRUZFUkVOQ0VfTEVWRUwgKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIGlmICh2YWx1ZSA8IDApIHsKICAgICAgc2VsZi0+cGFyYW1zLmFwcGx5RGlnaXRhbE5vcm0gPSAwOwogICAgICBzZWxmLT5wYXJhbXMudGFyZ2V0UmVmTGV2ZWwgPSAtMTsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiByZWZfbGV2ZWwgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIE1BWF9SRUZFUkVOQ0VfTEVWRUwsIGluY2x1c2l2ZSAqLwogICAgICBzZWxmLT5wYXJhbXMuYXBwbHlEaWdpdGFsTm9ybSA9IDE7CiAgICAgIGlmIChzZWxmLT5wYXJhbXMudGFyZ2V0UmVmTGV2ZWwgIT0gKFNDSEFSKXZhbHVlKSB7CiAgICAgICAgc2VsZi0+cGFyYW1zLnRhcmdldFJlZkxldmVsID0gKFNDSEFSKXZhbHVlOwogICAgICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IChTQ0hBUil2YWx1ZTsgIC8qIEFsd2F5cyBzZXQgdGhlIHByb2dyYW0gcmVmZXJlbmNlIGxldmVsIGVxdWFsIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCBsZXZlbCBhY2NvcmRpbmcgdG8gNC41LjIuNy4zIG9mIElTTy9JRUMgMTQ0OTYtMy4gKi8KICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBBUFBMWV9OT1JNQUxJWkFUSU9OOgogICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgLyogU3RvcmUgbmV3IHBhcmFtZXRlciB2YWx1ZSAqLwogICAgc2VsZi0+cGFyYW1zLmFwcGx5RGlnaXRhbE5vcm0gPSAoVUNIQVIpdmFsdWU7CiAgICBicmVhazsKICBjYXNlIEFQUExZX0hFQVZZX0NPTVBSRVNTSU9OOgogICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgaWYgKHNlbGYtPnBhcmFtcy5hcHBseUhlYXZ5Q29tcHJlc3Npb24gIT0gKFVDSEFSKXZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSAxKSB7CiAgICAgICAgLyogRGlzYWJsZSBzY2FsaW5nIG9mIERSQyB2YWx1ZXMgYnkgc2V0dGluZyB0aGUgbWF4IHZhbHVlcyAqLwogICAgICAgIHNlbGYtPnBhcmFtcy5ib29zdCA9IEZMMkZYQ09OU1RfREJMKDEuMGYvKGZsb2F0KSgxPDxEUkNfUEFSQU1fU0NBTEUpKTsKICAgICAgICBzZWxmLT5wYXJhbXMuY3V0ICAgPSBGTDJGWENPTlNUX0RCTCgxLjBmLyhmbG9hdCkoMTw8RFJDX1BBUkFNX1NDQUxFKSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogUmVzdG9yZSB0aGUgdXNlciBwYXJhbXMgKi8KICAgICAgICBzZWxmLT5wYXJhbXMuYm9vc3QgPSBzZWxmLT5wYXJhbXMudXNyQm9vc3Q7CiAgICAgICAgc2VsZi0+cGFyYW1zLmN1dCAgID0gc2VsZi0+cGFyYW1zLnVzckN1dDsKICAgICAgfQogICAgICAvKiBTdG9yZSBuZXcgcGFyYW1ldGVyIHZhbHVlICovCiAgICAgIHNlbGYtPnBhcmFtcy5hcHBseUhlYXZ5Q29tcHJlc3Npb24gPSAoVUNIQVIpdmFsdWU7CiAgICB9CiAgICBicmVhazsKICBjYXNlIERSQ19CU19ERUxBWToKICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPnBhcmFtcy5ic0RlbGF5RW5hYmxlID0gdmFsdWU7CiAgICBicmVhazsKICBjYXNlIERSQ19EQVRBX0VYUElSWV9GUkFNRToKICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CiAgICBzZWxmLT5wYXJhbXMuZXhwaXJ5RnJhbWUgPSAoVUlOVCl2YWx1ZTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICB9ICAvKiBzd2l0Y2gocGFyYW0pICovCgogIC8qIHN3aXRjaCBvbi9vZmYgcHJvY2Vzc2luZyAqLwogIHNlbGYtPmVuYWJsZSA9ICggKHNlbGYtPnBhcmFtcy5ib29zdCA+IChGSVhQX0RCTCkwKQogICAgICAgICAgICAgICAgfHwgKHNlbGYtPnBhcmFtcy5jdXQgICA+IChGSVhQX0RCTCkwKQogICAgICAgICAgICAgICAgfHwgKHNlbGYtPnBhcmFtcy5hcHBseUhlYXZ5Q29tcHJlc3Npb24gIT0gMCkKICAgICAgICAgICAgICAgIHx8IChzZWxmLT5wYXJhbXMudGFyZ2V0UmVmTGV2ZWwgPj0gMCkgKTsKCgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCnN0YXRpYyBpbnQgcGFyc2VFeGNsdWRlZENoYW5uZWxzKCBVSU5UICpleGNsdWRlZENobnNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMgKQp7CiAgVUlOVCBleGNsdWRlTWFzayA9IDA7CiAgVUlOVCBpLCBqOwogIGludCAgYml0Q250ID0gOTsKCiAgZm9yIChpID0gMCwgaiA9IDE7IGkgPCA3OyBpKyssIGo8PD0xKSB7CiAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsKICAgICAgZXhjbHVkZU1hc2sgfD0gajsKICAgIH0KICB9CgogIC8qIGFkZGl0aW9uYWxfZXhjbHVkZWRfY2hucyAqLwogIHdoaWxlIChGREtyZWFkQml0cyhicywxKSkgewogICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKywgajw8PTEpIHsKICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7CiAgICAgICAgZXhjbHVkZU1hc2sgfD0gajsKICAgICAgfQogICAgfQogICAgYml0Q250ICs9IDk7CiAgICBGREtfQVNTRVJUKGogPCAoVUlOVCktMSk7CiAgfQoKICAqZXhjbHVkZWRDaG5zTWFzayA9IGV4Y2x1ZGVNYXNrOwoKICByZXR1cm4gKGJpdENudCk7Cn0KCgovKiEKICBcYnJpZWYgU2F2ZSBEUkMgcGF5bG9hZCBiaXRzdHJlYW0gcG9zaXRpb24KCiAgXHNlbGYgSGFuZGxlIG9mIERSQyBpbmZvCiAgXGJzIEhhbmRsZSBvZiBGREsgYml0c3RyZWFtCgogIFxyZXR1cm4gVGhlIG51bWJlciBvZiBEUkMgcGF5bG9hZCBiaXRzCiovCmludCBhYWNEZWNvZGVyX2RyY01hcmtQYXlsb2FkICgKICAgIEhBTkRMRV9BQUNfRFJDIHNlbGYsCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgIEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFIHR5cGUgKQp7CiAgVUlOVCBic1N0YXJ0UG9zOwogIGludCAgaSwgbnVtQmFuZHMgPSAxLCBiaXRDbnQgPSAwOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm4gMDsKICB9CgogIGJzU3RhcnRQb3MgPSBGREtnZXRWYWxpZEJpdHMoYnMpOwoKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgTVBFR19EUkNfRVhUX0RBVEE6CiAgICB7CiAgICAgIGJpdENudCA9IDQ7CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogcGNlX3RhZ19wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBwY2VfaW5zdGFuY2VfdGFnICsgZHJjX3RhZ19yZXNlcnZlZF9iaXRzICovCiAgICAgICAgYml0Q250Kz04OwogICAgICB9CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogZXhjbHVkZWRfY2huc19wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsNyk7ICAgICAgICAgICAgICAvKiBleGNsdWRlIG1hc2sgWzAuLjddICovCiAgICAgICAgYml0Q250Kz04OwogICAgICAgIHdoaWxlIChGREtyZWFkQml0cyhicywxKSkgeyAgICAgLyogYWRkaXRpb25hbF9leGNsdWRlZF9jaG5zICovCiAgICAgICAgICBGREtyZWFkQml0cyhicyw3KTsgICAgICAgICAgICAvKiBleGNsdWRlIG1hc2sgW3guLnldICovCiAgICAgICAgICBiaXRDbnQrPTg7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogZHJjX2JhbmRzX3ByZXNlbnQgKi8KICAgICAgICBudW1CYW5kcyArPSBGREtyZWFkQml0cyhicywgNCk7IC8qIGRyY19iYW5kX2luY3IgKi8KICAgICAgICBGREtyZWFkQml0cyhicyw0KTsgICAgICAgICAgICAgIC8qIHJlc2VydmVkICovCiAgICAgICAgYml0Q250Kz04OwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CiAgICAgICAgICBGREtyZWFkQml0cyhicyw4KTsgICAgICAgICAgICAvKiBkcmNfYmFuZF90b3BbaV0gKi8KICAgICAgICAgIGJpdENudCs9ODsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChGREtyZWFkQml0cyhicywxKSkgeyAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbCArIHByb2dfcmVmX2xldmVsX3Jlc2VydmVkX2JpdHMgKi8KICAgICAgICBiaXRDbnQrPTg7CiAgICAgIH0KCiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBkeW5fcm5nX3NnbltpXSArIGR5bl9ybmdfY3RsW2ldICovCiAgICAgICAgYml0Q250Kz04OwogICAgICB9CgogICAgICBpZiAoIChzZWxmLT5udW1QYXlsb2FkcyA8IE1BWF9EUkNfVEhSRUFEUykKICAgICAgICAmJiAoKElOVClGREtnZXRWYWxpZEJpdHMoYnMpID49IDApICkKICAgICAgewogICAgICAgIHNlbGYtPmRyY1BheWxvYWRQb3NpdGlvbltzZWxmLT5udW1QYXlsb2FkcysrXSA9IGJzU3RhcnRQb3M7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwoKICAgIGNhc2UgRFZCX0RSQ19BTkNfREFUQToKICAgICAgYml0Q250ICs9IDg7CiAgICAgIC8qIGNoZWNrIHN5bmMgd29yZCAqLwogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsIDgpID09IERWQl9BTkNfREFUQV9TWU5DX0JZVEUpCiAgICAgIHsKICAgICAgICBpbnQgZG14TGV2ZWxzUHJlc2VudCwgY29tcHJlc3Npb25QcmVzZW50OwogICAgICAgIGludCBjb2Fyc2VHcmFpblRjUHJlc2VudCwgZmluZUdyYWluVGNQcmVzZW50OwoKICAgICAgICAvKiBic19pbmZvIGZpZWxkICovIAogICAgICAgIEZES3JlYWRCaXRzKGJzLCA4KTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1wZWdfYXVkaW9fdHlwZSwgZG9sYnlfc3Vycm91bmRfbW9kZSwgcHJlc2VudGF0aW9uX21vZGUgKi8KICAgICAgICBiaXRDbnQrPTg7CgogICAgICAgIC8qIEV2YWx1YXRlIGFuY2lsbGFyeV9kYXRhX3N0YXR1cyAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgICAgIGRteExldmVsc1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywgMSk7ICAgICAgIC8qIGRvd25taXhpbmdfbGV2ZWxzX01QRUc0X3N0YXR1cyAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgICAgIGNvbXByZXNzaW9uUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbiBzdGF0dXMgKi8KICAgICAgICBjb2Fyc2VHcmFpblRjUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgICAgICAgZmluZUdyYWluVGNQcmVzZW50ICAgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogZmluZV9ncmFpbl90aW1lY29kZV9zdGF0dXMgKi8KICAgICAgICBiaXRDbnQrPTg7CgogICAgICAgIC8qIE1QRUc0IGRvd25taXhpbmcgbGV2ZWxzICovCiAgICAgICAgaWYgKGRteExldmVsc1ByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCA4KTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNCAqLwogICAgICAgICAgYml0Q250Kz04OwogICAgICAgIH0KICAgICAgICAvKiBhdWRpbyBjb2RpbmcgbW9kZSBhbmQgY29tcHJlc3Npb24gc3RhdHVzICovCiAgICAgICAgaWYgKGNvbXByZXNzaW9uUHJlc2VudCkgewogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBhdWRpb19jb2RpbmdfbW9kZSwgQ29tcHJlc3Npb25fdmFsdWUgKi8KICAgICAgICAgIGJpdENudCs9MTY7CiAgICAgICAgfQogICAgICAgIC8qIGNvYXJzZSBncmFpbiB0aW1lY29kZSAqLwogICAgICAgIGlmIChjb2Fyc2VHcmFpblRjUHJlc2VudCkgewogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvYXJzZV9ncmFpbl90aW1lY29kZSAqLwogICAgICAgICAgYml0Q250Kz0xNjsKICAgICAgICB9CiAgICAgICAgLyogZmluZSBncmFpbiB0aW1lY29kZSAqLwogICAgICAgIGlmIChmaW5lR3JhaW5UY1ByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgICAgICAgICAgICAgICAgICAvKiBmaW5lX2dyYWluX3RpbWVjb2RlICovCiAgICAgICAgICBiaXRDbnQrPTE2OwogICAgICAgIH0KICAgICAgICBpZiAoICFzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlCiAgICAgICAgICAmJiAoKElOVClGREtnZXRWYWxpZEJpdHMoYnMpID49IDApICkKICAgICAgICB7CiAgICAgICAgICBzZWxmLT5kdmJBbmNEYXRhUG9zaXRpb24gID0gYnNTdGFydFBvczsKICAgICAgICAgIHNlbGYtPmR2YkFuY0RhdGFBdmFpbGFibGUgPSAxOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIHJldHVybiAoYml0Q250KTsKfQoKCi8qIQogIFxicmllZiBQYXJzZSBEUkMgcGFyYW1ldGVycyBmcm9tIGJpdHN0cmVhbQoKICBcYnMgSGFuZGxlIG9mIEZESyBiaXRzdHJlYW0gKGluKQogIFxwRHJjQnMgUG9pbnRlciB0byBEUkMgcGF5bG9hZCBkYXRhIGNvbnRhaW5lciAob3V0KQogIFxwYXlsb2FkUG9zaXRpb24gQml0c3RyZWFtIHBvc2l0aW9uIG9mIE1QRUcgRFJDIGRhdGEganVuayAoaW4pCgogIFxyZXR1cm4gTnVtYmVyIG9mIGJpdHMgcmVhZCAoMCBpbiBjYXNlIG9mIGEgcGFyc2UgZXJyb3IpCiovCnN0YXRpYyBpbnQgYWFjRGVjb2Rlcl9kcmNQYXJzZSAoCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMsCiAgICBDRHJjUGF5bG9hZCAgICAgICAgICAqcERyY0JzLAogICAgVUlOVCAgICAgICAgICAgICAgICAgIHBheWxvYWRQb3NpdGlvbiApCnsKICBpbnQgaSwgbnVtQmFuZHMsIGJpdENudCA9IDQ7CgogIC8qIE1vdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgRFJDIHBheWxvYWQgZmllbGQgKi8KICBGREtwdXNoQmlEaXJlY3Rpb25hbChicywgRkRLZ2V0VmFsaWRCaXRzKGJzKS1wYXlsb2FkUG9zaXRpb24pOwoKICAvKiBwY2VfdGFnX3ByZXNlbnQgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpCiAgewogICAgcERyY0JzLT5wY2VJbnN0YW5jZVRhZyA9IEZES3JlYWRCaXRzKGJzLCA0KTsgIC8qIHBjZV9pbnN0YW5jZV90YWcgKi8KICAgIC8qIG9ubHkgb25lIHByb2dyYW0gc3VwcG9ydGVkICovCiAgICBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfdGFnX3Jlc2VydmVkX2JpdHMgKi8KICAgIGJpdENudCArPSA4OwogIH0gZWxzZSB7CiAgICBwRHJjQnMtPnBjZUluc3RhbmNlVGFnID0gLTE7ICAvKiBub3QgcHJlc2VudCAqLwogIH0KCiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7ICAgICAgICAvKiBleGNsdWRlZF9jaG5zX3ByZXNlbnQgKi8KICAgIC8qIGdldCBleGNsdWRlZF9jaG5fbWFzayAqLwogICAgYml0Q250ICs9IHBhcnNlRXhjbHVkZWRDaGFubmVscygmcERyY0JzLT5leGNsdWRlZENobnNNYXNrLCBicyk7CiAgfSBlbHNlIHsKICAgIHBEcmNCcy0+ZXhjbHVkZWRDaG5zTWFzayA9IDA7CiAgfQoKICBudW1CYW5kcyA9IDE7CiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSAgLyogZHJjX2JhbmRzX3ByZXNlbnQgKi8KICB7CiAgICAvKiBnZXQgYmFuZF9pbmNyICovCiAgICBudW1CYW5kcyArPSBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfYmFuZF9pbmNyICovCiAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY0ludGVycG9sYXRpb25TY2hlbWUgPSBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWUgKi8KICAgIGJpdENudCArPSA4OwogICAgLyogYmFuZF90b3AgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKQogICAgewogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmJhbmRUb3BbaV0gPSBGREtyZWFkQml0cyhicywgOCk7ICAvKiBkcmNfYmFuZF90b3BbaV0gKi8KICAgICAgYml0Q250ICs9IDg7CiAgICB9CiAgfQogIGVsc2UgewogICAgcERyY0JzLT5jaGFubmVsRGF0YS5iYW5kVG9wWzBdID0gKDEwMjQgPj4gMikgLSAxOyAgLyogLi4uIGNvbXByaXNpbmcgdGhlIHdob2xlIHNwZWN0cnVtLiAqLzsKICB9CgogIHBEcmNCcy0+Y2hhbm5lbERhdGEubnVtQmFuZHMgPSBudW1CYW5kczsKCiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3ByZXNlbnQgKi8KICB7CiAgICBwRHJjQnMtPnByb2dSZWZMZXZlbCA9IEZES3JlYWRCaXRzKGJzLCA3KTsgIC8qIHByb2dfcmVmX2xldmVsICovCiAgICBGREtyZWFkQml0cyhicywgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3Jlc2VydmVkX2JpdHMgKi8KICAgIGJpdENudCArPSA4OwogIH0gZWxzZSB7CiAgICBwRHJjQnMtPnByb2dSZWZMZXZlbCA9IC0xOwogIH0KCiAgZm9yIChpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspCiAgewogICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVtpXSAgPSBGREtyZWFkQml0cyhicywgMSkgPDwgNzsgICAvKiBkeW5fcm5nX3NnbltpXSAqLwogICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVtpXSB8PSBGREtyZWFkQml0cyhicywgNykgJiAweDdGOyAvKiBkeW5fcm5nX2N0bFtpXSAqLwogICAgYml0Q250ICs9IDg7CiAgfQoKICAvKiBTZXQgRFJDIHBheWxvYWQgdHlwZSAqLwogIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUgPSBNUEVHX0RSQ19FWFRfREFUQTsKCiAgcmV0dXJuIChiaXRDbnQpOwp9CgoKLyohCiAgXGJyaWVmIFBhcnNlIGhlYXZ5IGNvbXByZXNzaW9uIHZhbHVlIHRyYW5zcG9ydGVkIGluIERTRXMgb2YgRFZCIHN0cmVhbXMgd2l0aCBNUEVHLTQgY29udGVudC4KCiAgXGJzIEhhbmRsZSBvZiBGREsgYml0c3RyZWFtIChpbikKICBccERyY0JzIFBvaW50ZXIgdG8gRFJDIHBheWxvYWQgZGF0YSBjb250YWluZXIgKG91dCkKICBccGF5bG9hZFBvc2l0aW9uIEJpdHN0cmVhbSBwb3NpdGlvbiBvZiBEVkIgYW5jaWxsYXJ5IGRhdGEganVuawoKICBccmV0dXJuIE51bWJlciBvZiBiaXRzIHJlYWQgKDAgaW4gY2FzZSBvZiBhIHBhcnNlIGVycm9yKQoqLwojZGVmaW5lIERWQl9DT01QUkVTU0lPTl9TQ0FMRSAgICggOCApICAgICAgIC8qIDQ4LDE2NCBkQiAqLwoKc3RhdGljIGludCBhYWNEZWNvZGVyX2RyY1JlYWRDb21wcmVzc2lvbiAoCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMsCiAgICBDRHJjUGF5bG9hZCAgICAgICAgICAqcERyY0JzLAogICAgVUlOVCAgICAgICAgICAgICAgICAgIHBheWxvYWRQb3NpdGlvbiApCnsKICBpbnQgIGJpdENudCA9IDA7CiAgaW50ICBkbXhMZXZlbHNQcmVzZW50LCBleHRlbnNpb25QcmVzZW50LCBjb21wcmVzc2lvblByZXNlbnQ7CiAgaW50ICBjb2Fyc2VHcmFpblRjUHJlc2VudCwgZmluZUdyYWluVGNQcmVzZW50OwoKICAvKiBNb3ZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIERSQyBwYXlsb2FkIGZpZWxkICovCiAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIEZES2dldFZhbGlkQml0cyhicyktcGF5bG9hZFBvc2l0aW9uKTsKCiAgLyogU2FuaXR5IGNoZWNrcyAqLwogIGlmICggRkRLZ2V0VmFsaWRCaXRzKGJzKSA8IDI0ICkgewogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBDaGVjayBzeW5jIHdvcmQgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsIDgpICE9IERWQl9BTkNfREFUQV9TWU5DX0JZVEUpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLyogRXZhbHVhdGUgYnNfaW5mbyBmaWVsZCAqLyAKICBpZiAoRkRLcmVhZEJpdHMoYnMsIDIpICE9IDMpIHsgICAgICAgICAgICAgICAvKiBtcGVnX2F1ZGlvX3R5cGUgKi8KICAgIC8qIE5vIE1QRUctNCBhdWRpbyBkYXRhICovCiAgICByZXR1cm4gMDsKICB9CiAgRkRLcmVhZEJpdHMoYnMsIDIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZG9sYnlfc3Vycm91bmRfbW9kZSAqLwogIHBEcmNCcy0+cHJlc01vZGUgPSBGREtyZWFkQml0cyhicywgMik7ICAgICAgIC8qIHByZXNlbnRhdGlvbl9tb2RlICovCiAgRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RlcmVvX2Rvd25taXhfbW9kZSAqLwogIGlmIChGREtyZWFkQml0cyhicywgMSkgIT0gMCkgeyAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBFdmFsdWF0ZSBhbmNpbGxhcnlfZGF0YV9zdGF0dXMgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsIDMpICE9IDApIHsgICAgICAgICAgICAgICAvKiByZXNlcnZlZCwgc2V0IHRvIDAgKi8KICAgIHJldHVybiAwOwogIH0KICBkbXhMZXZlbHNQcmVzZW50ID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNF9zdGF0dXMgKi8KICBleHRlbnNpb25QcmVzZW50ID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAvKiBhbmNpbGxhcnlfZGF0YV9leHRlbnNpb25fc3RhdHVzOyAqLwogIGNvbXByZXNzaW9uUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbiBzdGF0dXMgKi8KICBjb2Fyc2VHcmFpblRjUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgZmluZUdyYWluVGNQcmVzZW50ICAgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogZmluZV9ncmFpbl90aW1lY29kZV9zdGF0dXMgKi8KICBiaXRDbnQgKz0gMjQ7CgogIGlmIChkbXhMZXZlbHNQcmVzZW50KSB7CiAgICBGREtyZWFkQml0cyhicywgOCk7ICAgICAgICAgICAgICAgICAgICAgICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzQgKi8KICAgIGJpdENudCArPSA4OwogIH0KCiAgLyogYXVkaW9fY29kaW5nX21vZGVfYW5kX2NvbXByZXNzaW9uX3N0YXR1cyAqLwogIGlmIChjb21wcmVzc2lvblByZXNlbnQpCiAgewogICAgVUNIQVIgY29tcHJlc3Npb25PbiwgY29tcHJlc3Npb25WYWx1ZTsKCiAgICAvKiBhdWRpb19jb2RpbmdfbW9kZSAqLwogICAgaWYgKCBGREtyZWFkQml0cyhicywgNykgIT0gMCApIHsgIC8qIFRoZSByZXNlcnZlZCBiaXRzIHNoYWxsIGJlIHNldCB0byAiMCIuICovCiAgICAgIHJldHVybiAwOwogICAgfQogICAgY29tcHJlc3Npb25PbiAgICA9IChVQ0hBUilGREtyZWFkQml0cyhicywgMSk7ICAvKiBjb21wcmVzc2lvbl9vbiAqLwogICAgY29tcHJlc3Npb25WYWx1ZSA9IChVQ0hBUilGREtyZWFkQml0cyhicywgOCk7ICAvKiBDb21wcmVzc2lvbl92YWx1ZSAqLwogICAgYml0Q250ICs9IDE2OwoKICAgIGlmICggY29tcHJlc3Npb25PbiApIHsKICAgICAgLyogQSBjb21wcmVzc2lvbiB2YWx1ZSBpcyBhdmFpbGFibGUgc28gc3RvcmUgdGhlIGRhdGEganVzdCBsaWtlIE1QRUcgRFJDIGRhdGEgKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5udW1CYW5kcyAgICA9ICAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBPbmUgYmFuZCAuLi4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVswXSA9ICBjb21wcmVzc2lvblZhbHVlOyAgICAgICAgICAgICAvKiAuLi4gd2l0aCBvbmUgdmFsdWUgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuYmFuZFRvcFswXSAgPSAoMTAyNCA+PiAyKSAtIDE7ICAvKiAuLi4gY29tcHJpc2luZyB0aGUgd2hvbGUgc3BlY3RydW0uICovCiAgICAgIHBEcmNCcy0+cGNlSW5zdGFuY2VUYWcgICAgICAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm90IHByZXNlbnQgKi8KICAgICAgcERyY0JzLT5wcm9nUmVmTGV2ZWwgICAgICAgICAgICA9IC0xOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBOb3QgcHJlc2VudCAqLwogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlID0gIERWQl9EUkNfQU5DX0RBVEE7ICAgICAgICAgICAgIC8qIFNldCBEUkMgcGF5bG9hZCB0eXBlIHRvIERWQi4gKi8KICAgIH0gZWxzZSB7CiAgICAgIC8qIE5vIGNvbXByZXNzaW9uIHZhbHVlIGF2YWlsYWJsZSAqLwogICAgICAvKiBDQVVUSU9OOiBJdCBpcyBub3QgY2xlYXJseSBkZWZpbmVkIGJ5IHN0YW5kYXJkIGhvdyB0byByZWFjdCBpbiB0aGlzIHNpdHVhdGlvbi4gKi8KICAgICAgLyogVHVybiBkb3duIHRoZSBjb21wcmVzc2lvbiB2YWx1ZSB0byBhcHJveC4gMGRCICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEubnVtQmFuZHMgICAgPSAgMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogT25lIGJhbmQgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjVmFsdWVbMF0gPSAgMHg4MDsgICAgICAgICAgICAgICAgICAgICAgICAgLyogLi4uIHdpdGggYXByb3guIDBkQiAuLi4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsgIC8qIC4uLiBjb21wcmlzaW5nIHRoZSB3aG9sZSBzcGVjdHJ1bS4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNEYXRhVHlwZSA9ICBEVkJfRFJDX0FOQ19EQVRBOyAgICAgICAgICAgICAvKiBTZXQgRFJDIHBheWxvYWQgdHlwZSB0byBEVkIuICovCgogICAgICAvKiBJZiBjb21wcmVzc2lvbl9vbiBmaWVsZCBpcyBzZXQgdG8gIjAiIHRoZSBjb21wcmVzc2lvbl92YWx1ZSBmaWVsZCBzaGFsbCBiZSAiMDAwMCAwMDAwIi4gKi8KICAgICAgaWYgKGNvbXByZXNzaW9uVmFsdWUgIT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICB9CiAgfQoKICAvKiBSZWFkIHRpbWVjb2RlcyBpZiBhdmFpbGFibGUganVzdCB0byBnZXQgdGhlIHJpZ2h0IGFtb3VudCBvZiBiaXRzLiAqLwogIGlmIChjb2Fyc2VHcmFpblRjUHJlc2VudCkgewogICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGUgKi8KICAgIGJpdENudCArPSAxNjsKICB9CiAgaWYgKGZpbmVHcmFpblRjUHJlc2VudCkgewogICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAvKiBmaW5lX2dyYWluX3RpbWVjb2RlICovCiAgICBiaXRDbnQgKz0gMTY7CiAgfQoKICAvKiBSZWFkIGV4dGVuc2lvbiBqdXN0IHRvIGdldCB0aGUgcmlnaHQgYW1vdW50IG9mIGJpdHMuICovCiAgaWYgKGV4dGVuc2lvblByZXNlbnQpIHsKICAgIGludCAgZXh0Qml0cyA9IDg7CgogICAgRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgaWYgKEZES3JlYWRCaXRzKGJzLCAxKSkgZXh0Qml0cyArPSA4OyAgIC8qIGV4dF9kb3dubWl4aW5nX2xldmVsc19zdGF0dXMgKi8KICAgIGlmIChGREtyZWFkQml0cyhicywgMSkpIGV4dEJpdHMgKz0gMTY7ICAvKiBleHRfZG93bm1peGluZ19nbG9iYWxfZ2FpbnNfc3RhdHVzICovCiAgICBpZiAoRkRLcmVhZEJpdHMoYnMsIDEpKSBleHRCaXRzICs9IDg7ICAgLyogZXh0X2Rvd25taXhpbmdfbGZlX2xldmVsX3N0YXR1cyAqLwoKICAgIEZES3B1c2hGb3IoYnMsIGV4dEJpdHMgLSA0KTsgICAgICAgICAgICAvKiBza2lwIHRoZSBleHRlbnNpb24gcGF5bG9hZCByZW1haW5kZXIuICovCiAgICBiaXRDbnQgKz0gZXh0Qml0czsKICB9CgogIHJldHVybiAoYml0Q250KTsKfQoKCi8qIAogKiBQcmVwYXJlIERSQyBwcm9jZXNzaW5nCiAqLwpzdGF0aWMgaW50IGFhY0RlY29kZXJfZHJjRXh0cmFjdEFuZE1hcCAoCiAgICAgICAgSEFORExFX0FBQ19EUkMgIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bXSwKICAgICAgICBVQ0hBUiAgcGNlSW5zdGFuY2VUYWcsCiAgICAgICAgVUNIQVIgIGNoYW5uZWxNYXBwaW5nW10sIC8qIENoYW5uZWwgbWFwcGluZyB0cmFuc2xhdGluZyBkcmNDaGFubmVsIGluZGV4IHRvIGNhbm9uaWNhbCBjaGFubmVsIGluZGV4ICovCiAgICAgICAgaW50ICAgIHZhbGlkQ2hhbm5lbHMgKQp7CiAgQ0RyY1BheWxvYWQgIHRocmVhZEJzW01BWF9EUkNfVEhSRUFEU107CiAgQ0RyY1BheWxvYWQgKnZhbGlkVGhyZWFkQnNbTUFYX0RSQ19USFJFQURTXTsKICBDRHJjUGFyYW1zICAqcFBhcmFtczsKICBVSU5UIGJhY2t1cEJzUG9zaXRpb247CiAgaW50ICBpLCB0aHJlYWQsIHZhbGlkVGhyZWFkcyA9IDA7CiAgaW50ICBudW1FeGNsdWRlZENobnNbTUFYX0RSQ19USFJFQURTXTsKCiAgRkRLX0FTU0VSVChzZWxmICE9IE5VTEwpOwogIEZES19BU1NFUlQoaEJzICE9IE5VTEwpOwogIEZES19BU1NFUlQocEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAhPSBOVUxMKTsKCiAgcFBhcmFtcyA9ICZzZWxmLT5wYXJhbXM7CgogIHNlbGYtPm51bVRocmVhZHMgPSAwOwogIGJhY2t1cEJzUG9zaXRpb24gPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgZm9yIChpID0gMDsgaSA8IHNlbGYtPm51bVBheWxvYWRzICYmIHNlbGYtPm51bVRocmVhZHMgPCBNQVhfRFJDX1RIUkVBRFM7IGkrKykgewogICAgaW50IGJpdHNQYXJzZWQ7CgogICAgLyogSW5pdCBwYXlsb2FkIGRhdGEgY2h1bmsuIFRoZSBtZW1jbGVhciBpcyB2ZXJ5IGltcG9ydGFudCBiZWNhdXNlIGl0IGluaXRpYWxpemVzCiAgICAgICB0aGUgbW9zdCB2YWx1ZXMuIFdpdGhvdXQgaXQgdGhlIG1vZHVsZSB3b3VsZG4ndCB3b3JrIHByb3Blcmx5IG9yIGNyYXNoLiAqLwogICAgRkRLbWVtY2xlYXIoJnRocmVhZEJzW3NlbGYtPm51bVRocmVhZHNdLCBzaXplb2YoQ0RyY1BheWxvYWQpKTsKICAgIHRocmVhZEJzW3NlbGYtPm51bVRocmVhZHNdLmNoYW5uZWxEYXRhLmJhbmRUb3BbMF0gID0gKDEwMjQgPj4gMikgLSAxOwoKICAgIC8qIEV4dHJhY3QgcGF5bG9hZCAqLwogICAgYml0c1BhcnNlZCA9IGFhY0RlY29kZXJfZHJjUGFyc2UoIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5kcmNQYXlsb2FkUG9zaXRpb25baV0gKTsKICAgIGlmIChiaXRzUGFyc2VkID4gMCkgewogICAgICBzZWxmLT5udW1UaHJlYWRzKys7CiAgICB9CiAgfQogIHNlbGYtPm51bVBheWxvYWRzID0gMDsKCiAgaWYgKHNlbGYtPmR2YkFuY0RhdGFBdmFpbGFibGUpCiAgeyAvKiBBcHBlbmQgYSBEVkIgaGVhdnkgY29tcHJlc3Npb24gcGF5bG9hZCB0aHJlYWQgaWYgYXZhaWxhYmxlLiAqLwogICAgaW50IGJpdHNQYXJzZWQ7CgogICAgLyogSW5pdCBwYXlsb2FkIGRhdGEgY2h1bmsuIFRoZSBtZW1jbGVhciBpcyB2ZXJ5IGltcG9ydGFudCBiZWNhdXNlIGl0IGluaXRpYWxpemVzCiAgICAgICB0aGUgbW9zdCB2YWx1ZXMuIFdpdGhvdXQgaXQgdGhlIG1vZHVsZSB3b3VsZG4ndCB3b3JrIHByb3Blcmx5IG9yIGNyYXNoLiAqLwogICAgRkRLbWVtY2xlYXIoJnRocmVhZEJzW3NlbGYtPm51bVRocmVhZHNdLCBzaXplb2YoQ0RyY1BheWxvYWQpKTsKICAgIHRocmVhZEJzW3NlbGYtPm51bVRocmVhZHNdLmNoYW5uZWxEYXRhLmJhbmRUb3BbMF0gID0gKDEwMjQgPj4gMikgLSAxOwoKICAgIC8qIEV4dHJhY3QgcGF5bG9hZCAqLwogICAgYml0c1BhcnNlZCA9IGFhY0RlY29kZXJfZHJjUmVhZENvbXByZXNzaW9uKCBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRocmVhZEJzW3NlbGYtPm51bVRocmVhZHNdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5kdmJBbmNEYXRhUG9zaXRpb24gKTsKICAgIGlmIChiaXRzUGFyc2VkID4gMCkgewogICAgICBzZWxmLT5udW1UaHJlYWRzKys7CiAgICB9CiAgfQogIHNlbGYtPmR2YkFuY0RhdGFBdmFpbGFibGUgPSAwOwoKICAvKiBSZXNldCB0aGUgYml0YnVmZmZlciAqLwogIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBiYWNrdXBCc1Bvc2l0aW9uKTsKCiAgLyogY2FsY3VsYXRlIG51bWJlciBvZiB2YWxpZCBiaXRzIGluIGV4Y2xfY2huX21hc2sgKi8KCiAgLyogY291cGxpbmcgY2hhbm5lbHMgbm90IHN1cHBvcnRlZCAqLwoKICAvKiBjaGVjayBmb3IgdmFsaWQgdGhyZWFkcyAqLwogIGZvciAodGhyZWFkID0gMDsgdGhyZWFkIDwgc2VsZi0+bnVtVGhyZWFkczsgdGhyZWFkKyspIHsKICAgIENEcmNQYXlsb2FkICpwVGhyZWFkQnMgPSAmdGhyZWFkQnNbdGhyZWFkXTsKICAgIGludCBudW1FeGNsQ2hucyA9IDA7CgogICAgc3dpdGNoICgoQUFDREVDX0RSQ19QQVlMT0FEX1RZUEUpcFRocmVhZEJzLT5jaGFubmVsRGF0YS5kcmNEYXRhVHlwZSkgewogICAgICBkZWZhdWx0OgogICAgICAgIGNvbnRpbnVlOwogICAgICBjYXNlIE1QRUdfRFJDX0VYVF9EQVRBOgogICAgICBjYXNlIERWQl9EUkNfQU5DX0RBVEE6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHBUaHJlYWRCcy0+cGNlSW5zdGFuY2VUYWcgPj0gMCkgeyAgLyogaWYgUENFIHRhZyBwcmVzZW50ICovCiAgICAgIGlmIChwVGhyZWFkQnMtPnBjZUluc3RhbmNlVGFnICE9IHBjZUluc3RhbmNlVGFnKSB7CiAgICAgICAgY29udGludWU7ICAvKiBkb24ndCBhY2NlcHQgKi8KICAgICAgfQogICAgfQoKICAgIC8qIGNhbGN1bGF0ZSBudW1iZXIgb2YgZXhjbHVkZWQgY2hhbm5lbHMgKi8KICAgIGlmIChwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2sgPiAwKSB7CiAgICAgIElOVCBleGNsTWFzayA9IHBUaHJlYWRCcy0+ZXhjbHVkZWRDaG5zTWFzazsKICAgICAgaW50IGNoOwogICAgICBmb3IgKGNoID0gMDsgY2ggPCB2YWxpZENoYW5uZWxzOyBjaCsrKSB7CiAgICAgICAgbnVtRXhjbENobnMgKz0gZXhjbE1hc2sgJiAweDE7CiAgICAgICAgZXhjbE1hc2sgPj49IDE7CiAgICAgIH0KICAgIH0KICAgIGlmIChudW1FeGNsQ2hucyA8IHZhbGlkQ2hhbm5lbHMpIHsKICAgICAgdmFsaWRUaHJlYWRCc1t2YWxpZFRocmVhZHNdICAgPSBwVGhyZWFkQnM7CiAgICAgIG51bUV4Y2x1ZGVkQ2huc1t2YWxpZFRocmVhZHNdID0gbnVtRXhjbENobnM7CiAgICAgIHZhbGlkVGhyZWFkcysrOwogICAgfQogIH0KCiAgaWYgKHZhbGlkVGhyZWFkcyA+IDEpIHsKICAgIGludCBjaDsKCiAgICAvKiBjaGVjayBjb25zaXN0ZW5jeSBvZiBleGNsX2Nobl9tYXNrIGFtb25nc3QgdmFsaWQgRFJDIHRocmVhZHMgKi8KICAgIGZvciAoY2ggPSAwOyBjaCA8IHZhbGlkQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgaW50IHByZXNlbnQgPSAwOwoKICAgICAgZm9yICh0aHJlYWQgPSAwOyB0aHJlYWQgPCB2YWxpZFRocmVhZHM7IHRocmVhZCsrKSB7CiAgICAgICAgQ0RyY1BheWxvYWQgKnBUaHJlYWRCcyA9IHZhbGlkVGhyZWFkQnNbdGhyZWFkXTsKCgogICAgICAgIC8qIHRocmVhZCBhcHBsaWVzIHRvIHRoaXMgY2hhbm5lbCAqLwogICAgICAgIGlmICggKHBUaHJlYWRCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUgPT0gTVBFR19EUkNfRVhUX0RBVEEpCiAgICAgICAgICAmJiAoIChudW1FeGNsdWRlZENobnNbdGhyZWFkXSA9PSAwKQogICAgICAgICAgICB8fCAoIShwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2sgJiAoMTw8Y2gpKSkgKSApIHsKICAgICAgICAgIHByZXNlbnQrKzsKICAgICAgICB9CiAgICAgIH0KCgogICAgICBpZiAocHJlc2VudCA+IDEpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIG1hcCBEUkMgYml0c3RyZWFtIGluZm9ybWF0aW9uIG9udG8gRFJDIGNoYW5uZWwgaW5mb3JtYXRpb24gKi8KICBmb3IgKHRocmVhZCA9IDA7IHRocmVhZCA8IHZhbGlkVGhyZWFkczsgdGhyZWFkKyspCiAgewogICAgQ0RyY1BheWxvYWQgKnBUaHJlYWRCcyA9IHZhbGlkVGhyZWFkQnNbdGhyZWFkXTsKICAgIElOVCBleGNsTWFzayA9IHBUaHJlYWRCcy0+ZXhjbHVkZWRDaG5zTWFzazsKICAgIEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFIGRyY1BheWxvYWRUeXBlID0gKEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFKXBUaHJlYWRCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGU7CiAgICBpbnQgY2g7CgogICAgLyogbGFzdCBwcm9nUmVmTGV2ZWwgdHJhbnNtaXR0ZWQgaXMgdGhlIG9uZSB0aGF0IGlzIHVzZWQKICAgICAqIChidXQgaXQgc2hvdWxkIHJlYWxseSBvbmx5IGJlIHRyYW5zbWl0dGVkIG9uY2UgcGVyIGJsb2NrISkKICAgICAqLwogICAgaWYgKHBUaHJlYWRCcy0+cHJvZ1JlZkxldmVsID49IDApIHsKICAgICAgc2VsZi0+cHJvZ1JlZkxldmVsID0gcFRocmVhZEJzLT5wcm9nUmVmTGV2ZWw7CiAgICAgIHNlbGYtPnByb2dSZWZMZXZlbFByZXNlbnQgPSAxOwogICAgICBzZWxmLT5wcmxFeHBpcnlDb3VudCA9IDA7ICAvKiBHb3QgYSBuZXcgdmFsdWUgLT4gUmVzZXQgY291bnRlciAqLwogICAgfQoKICAgIGlmIChkcmNQYXlsb2FkVHlwZSA9PSBEVkJfRFJDX0FOQ19EQVRBKSB7CiAgICAgIC8qIEFubm91bmNlIHRoZSBwcmVzZW50YXRpb24gbW9kZSBvZiB0aGlzIHZhbGlkIHRocmVhZC4gKi8KICAgICAgc2VsZi0+cHJlc01vZGUgPSBwVGhyZWFkQnMtPnByZXNNb2RlOwogICAgfQoKICAgIC8qIFNDRSwgQ1BFIGFuZCBMRkUgKi8KICAgIGZvciAoY2ggPSAwOyBjaCA8IHZhbGlkQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgaW50IG1hcGVkQ2hhbm5lbCA9IGNoYW5uZWxNYXBwaW5nW2NoXTsKCiAgICAgIGlmICggKChleGNsTWFzayAmICgxPDxtYXBlZENoYW5uZWwpKSA9PSAwKQogICAgICAgICYmICggKGRyY1BheWxvYWRUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgICAgICAgfHwgKChkcmNQYXlsb2FkVHlwZSA9PSBEVkJfRFJDX0FOQ19EQVRBKSAmJiBzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uKQogICAgICAgICApICkgewogICAgICAgIC8qIGNvcHkgdGhyZWFkIHRvIGNoYW5uZWwgKi8KICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+ZHJjRGF0YSA9IHBUaHJlYWRCcy0+Y2hhbm5lbERhdGE7CiAgICAgIH0KICAgIH0KICAgIC8qIENDRXMgbm90IHN1cHBvcnRlZCBieSBub3cgKi8KICB9CgogIC8qIEluY3JlbWVudCBhbmQgY2hlY2sgZXhwaXJ5IGNvdW50ZXIgZm9yIHRoZSBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbDogKi8KICBpZiAoIChwUGFyYW1zLT5leHBpcnlGcmFtZSA+IDApCiAgICAmJiAoc2VsZi0+cHJsRXhwaXJ5Q291bnQrKyA+IHBQYXJhbXMtPmV4cGlyeUZyYW1lKSApCiAgeyAvKiBUaGUgcHJvZ3JhbSByZWZlcmVuY2UgbGV2ZWwgaXMgdG9vIG9sZCwgc28gc2V0IGl0IGJhY2sgdG8gdGhlIHRhcmdldCBsZXZlbC4gKi8KICAgIHNlbGYtPnByb2dSZWZMZXZlbFByZXNlbnQgPSAwOwogICAgc2VsZi0+cHJvZ1JlZkxldmVsID0gcFBhcmFtcy0+dGFyZ2V0UmVmTGV2ZWw7CiAgICBzZWxmLT5wcmxFeHBpcnlDb3VudCA9IDA7CiAgfQoKICByZXR1cm4gMDsKfQoKCnZvaWQgYWFjRGVjb2Rlcl9kcmNBcHBseSAoCiAgICAgICAgSEFORExFX0FBQ19EUkMgICAgICAgICAgc2VsZiwKICAgICAgICB2b2lkICAgICAgICAgICAgICAgICAgICpwU2JyRGVjLAogICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgQ0RyY0NoYW5uZWxEYXRhICAgICAgICAqcERyY0NoRGF0YSwKICAgICAgICBGSVhQX0RCTCAgICAgICAgICAgICAgICpleHRHYWluLAogICAgICAgIGludCAgY2gsICAgLyogbmVlZGVkIG9ubHkgZm9yIFNCUiAqLwogICAgICAgIGludCAgYWFjRnJhbWVTaXplLAogICAgICAgIGludCAgYlNiclByZXNlbnQgKQp7CiAgaW50IGJhbmQsIHRvcCwgYmluLCBudW1CYW5kczsKICBpbnQgYm90dG9tID0gMDsKICBpbnQgbW9kaWZ5QmlucyA9IDA7CgogIEZJWFBfREJMIG1heF9tYW50aXNzYTsKICBJTlQgbWF4X2V4cG9uZW50OwoKICBGSVhQX0RCTCBub3JtX21hbnRpc3NhID0gRkwyRlhDT05TVF9EQkwoMC41Zik7CiAgSU5UICBub3JtX2V4cG9uZW50ID0gMTsKCiAgRklYUF9EQkwgZmFjdF9tYW50aXNzYVtNQVhfRFJDX0JBTkRTXTsKICBJTlQgIGZhY3RfZXhwb25lbnRbTUFYX0RSQ19CQU5EU107CgogIENEcmNQYXJhbXMgICpwUGFyYW1zID0gJnNlbGYtPnBhcmFtczsKCiAgRklYUF9EQkwgICAgKnBTcGVjdHJhbENvZWZmaWNpZW50ICA9ICBTUEVDX0xPTkcocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQpOwogIENJY3NJbmZvICAgICpwSWNzSW5mbyAgICAgICAgICAgICAgPSAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbzsKICBTSE9SVCAgICAgICAqcFNwZWNTY2FsZSAgICAgICAgICAgID0gIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnNwZWNTY2FsZTsKCiAgaW50IHdpblNlcSA9IHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZTsKCiAgLyogSW5jcmVtZW50IGFuZCBjaGVjayBleHBpcnkgY291bnRlciAqLwogIGlmICggKHBQYXJhbXMtPmV4cGlyeUZyYW1lID4gMCkKICAgICYmICgrK3BEcmNDaERhdGEtPmV4cGlyeUNvdW50ID4gcFBhcmFtcy0+ZXhwaXJ5RnJhbWUpICkKICB7IC8qIFRoZSBEUkMgZGF0YSBpcyB0b28gb2xkLCBzbyBkZWxldGUgaXQuICovCiAgICBhYWNEZWNvZGVyX2RyY0luaXRDaGFubmVsRGF0YSggcERyY0NoRGF0YSApOwogIH0KCiAgaWYgKCFzZWxmLT5lbmFibGUpIHsKICAgIHNickRlY29kZXJfZHJjRGlzYWJsZSggKEhBTkRMRV9TQlJERUNPREVSKXBTYnJEZWMsIGNoICk7CiAgICBpZiAoZXh0R2FpbiAhPSBOVUxMKSB7CiAgICAgIElOVCBnYWluU2NhbGUgPSAoSU5UKSpleHRHYWluOwogICAgICAvKiBUaGUgZ2FpbiBzY2FsaW5nIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiBpbiB0aGUgYnVmZmVyIHBvaW50ZWQgb24gYnkgZXh0R2Fpbi4gKi8KICAgICAgaWYgKGdhaW5TY2FsZSA+PSAwICYmIGdhaW5TY2FsZSA8PSBERlJBQ1RfQklUUykgewogICAgICAgICpleHRHYWluID0gc2NhbGVWYWx1ZShub3JtX21hbnRpc3NhLCBub3JtX2V4cG9uZW50LWdhaW5TY2FsZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgRkRLX0FTU0VSVCgwKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuOwogIH0KCiAgbnVtQmFuZHMgPSBwRHJjQ2hEYXRhLT5udW1CYW5kczsKICB0b3AgPSBGREttYXgoMCwgbnVtQmFuZHMtMSk7CgogIHBEcmNDaERhdGEtPmJhbmRUb3BbMF0gPSBmaXhNaW4ocERyY0NoRGF0YS0+YmFuZFRvcFswXSwgKGFhY0ZyYW1lU2l6ZSA+PiAyKSAtIDEpOwoKICAvKiBJZiBwcm9ncmFtIHJlZmVyZW5jZSBub3JtYWxpemF0aW9uIGlzIGRvbmUgaW4gdGhlIGRpZ2l0YWwgZG9tYWluLAogIG1vZGlmeSBmYWN0b3IgdG8gcGVyZm9ybSBub3JtYWxpemF0aW9uLiAgcHJvZ19yZWZfbGV2ZWwgY2FuCiAgYWx0ZXJuYXRpdmVseSBiZSBwYXNzZWQgdG8gdGhlIHN5c3RlbSBmb3IgbW9kaWZpY2F0aW9uIG9mIHRoZSBsZXZlbCBpbgogIHRoZSBhbmFsb2cgZG9tYWluLiAgQW5hbG9nIGxldmVsIG1vZGlmaWNhdGlvbiBhdm9pZHMgcHJvYmxlbXMgd2l0aAogIHJlZHVjZWQgREFDIFNOUiAoaWYgc2lnbmFsIGlzIGF0dGVudWF0ZWQpIG9yIGNsaXBwaW5nIChpZiBzaWduYWwgaXMKICBib29zdGVkKSAqLwoKICBpZiAocFBhcmFtcy0+dGFyZ2V0UmVmTGV2ZWwgPj0gMCkKICB7CiAgICAvKiAwLjVeKCh0YXJnZXRSZWZMZXZlbCAtIHByb2dSZWZMZXZlbCkvMjQpICovCiAgICBub3JtX21hbnRpc3NhID0gZkxkUG93KAogICAgICAgICAgICBGTDJGWENPTlNUX0RCTCgtMS4wKSwgLyogbG9nMigwLjUpICovCiAgICAgICAgICAgIDAsCiAgICAgICAgICAgIChGSVhQX0RCTCkoKElOVCkoRkwyRlhDT05TVF9EQkwoMS4wZi8yNC4wKT4+MykgKiAoSU5UKShwUGFyYW1zLT50YXJnZXRSZWZMZXZlbC1zZWxmLT5wcm9nUmVmTGV2ZWwpKSwKICAgICAgICAgICAgMywKICAgICAgICAgICAmbm9ybV9leHBvbmVudCApOwogIH0KICAvKiBBbHdheXMgZXhwb3J0IHRoZSBub3JtYWxpemF0aW9uIGdhaW4gKGlmIHBvc3NpYmxlKS4gKi8KICBpZiAoZXh0R2FpbiAhPSBOVUxMKSB7CiAgICBJTlQgZ2FpblNjYWxlID0gKElOVCkqZXh0R2FpbjsKICAgIC8qIFRoZSBnYWluIHNjYWxpbmcgbXVzdCBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIGluIHRoZSBidWZmZXIgcG9pbnRlZCBvbiBieSBleHRHYWluLiAqLwogICAgaWYgKGdhaW5TY2FsZSA+PSAwICYmIGdhaW5TY2FsZSA8PSBERlJBQ1RfQklUUykgewogICAgICAqZXh0R2FpbiA9IHNjYWxlVmFsdWUobm9ybV9tYW50aXNzYSwgbm9ybV9leHBvbmVudC1nYWluU2NhbGUpOwogICAgfSBlbHNlIHsKICAgICAgRkRLX0FTU0VSVCgwKTsKICAgIH0KICB9CiAgaWYgKHNlbGYtPnBhcmFtcy5hcHBseURpZ2l0YWxOb3JtID09IDApIHsKICAgIC8qIFJlc2V0IG5vcm1hbGl6YXRpb24gZ2FpbiBzaW5jZSB0aGlzIG1vZHVsZSBtdXN0IG5vdCBhcHBseSBpdCAqLwogICAgbm9ybV9tYW50aXNzYSA9IEZMMkZYQ09OU1RfREJMKDAuNWYpOwogICAgbm9ybV9leHBvbmVudCA9IDE7CiAgfQoKCiAgLyogY2FsYyBzY2FsZSBmYWN0b3JzICovCiAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kKyspCiAgewogICAgVUNIQVIgZHJjVmFsID0gcERyY0NoRGF0YS0+ZHJjVmFsdWVbYmFuZF07CiAgICB0b3AgPSBmaXhNaW4oKGludCkoIChwRHJjQ2hEYXRhLT5iYW5kVG9wW2JhbmRdKzEpPDwyICksIGFhY0ZyYW1lU2l6ZSk7CgogICAgZmFjdF9tYW50aXNzYVtiYW5kXSA9IEZMMkZYQ09OU1RfREJMKDAuNWYpOwogICAgZmFjdF9leHBvbmVudFtiYW5kXSA9IDE7CgogICAgaWYgKCAgcFBhcmFtcy0+YXBwbHlIZWF2eUNvbXByZXNzaW9uCiAgICAgICYmICgoQUFDREVDX0RSQ19QQVlMT0FEX1RZUEUpcERyY0NoRGF0YS0+ZHJjRGF0YVR5cGUgPT0gRFZCX0RSQ19BTkNfREFUQSkgKQogICAgewogICAgICBJTlQgY29tcHJlc3Npb25GYWN0b3JWYWxfZTsKICAgICAgaW50IHZhbFgsIHZhbFk7CgogICAgICB2YWxYID0gZHJjVmFsID4+IDQ7CiAgICAgIHZhbFkgPSBkcmNWYWwgJiAweDBGOwoKICAgICAgLyogY2FsY3VsYXRlIHRoZSB1bnNjYWxlZCBoZWF2eSBjb21wcmVzc2lvbiBmYWN0b3IuCiAgICAgICAgIGNvbXByZXNzaW9uRmFjdG9yID0gNDguMTY0IC0gNi4wMjA2KnZhbFggLSAwLjQwMTQqdmFsWSBkQgogICAgICAgICByYW5nZTogLTQ4LjE2NiBkQiB0byA0OC4xNjQgZEIgKi8KICAgICAgaWYgKCBkcmNWYWwgIT0gMHg3RiApIHsKICAgICAgICBmYWN0X21hbnRpc3NhW2JhbmRdID0KICAgICAgICAgIGZQb3dJbnQoIEZMMkZYQ09OU1RfREJMKDAuOTU0ODM4NjcxODEpLCAvKiAtMC40MDE0ZEIgPSAwLjk1NDgzODY3MTgxICovCiAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgdmFsWSwKICAgICAgICAgICAgICAgICAgJmNvbXByZXNzaW9uRmFjdG9yVmFsX2UgKTsKCiAgICAgICAgLyogLTAuMDAwOGRCICg0OC4xNjQgLSA2LjAyMDYqOCA9IC0wLjAwMDgpICovCiAgICAgICAgZmFjdF9tYW50aXNzYVtiYW5kXSA9IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuOTk5OTA3OTAwODQpLCBmYWN0X21hbnRpc3NhW2JhbmRdKTsKCiAgICAgICAgZmFjdF9leHBvbmVudFtiYW5kXSA9IERWQl9DT01QUkVTU0lPTl9TQ0FMRSAtIHZhbFggKyBjb21wcmVzc2lvbkZhY3RvclZhbF9lOwogICAgICB9CiAgICB9IGVsc2UKICAgIGlmICgoQUFDREVDX0RSQ19QQVlMT0FEX1RZUEUpcERyY0NoRGF0YS0+ZHJjRGF0YVR5cGUgPT0gTVBFR19EUkNfRVhUX0RBVEEpCiAgICB7CiAgICAvKiBhcHBseSB0aGUgc2NhbGVkIGR5bmFtaWMgcmFuZ2UgY29udHJvbCB3b3JkcyB0byBmYWN0b3IuCiAgICAgKiBpZiBzY2FsaW5nIGRyY19jdXQgKG9yIGRyY19ib29zdCksIG9yIGNvbnRyb2wgd29yZCBkcmNfbWFudGlzc2EgaXMgMAogICAgICogdGhlbiB0aGVyZSBpcyBubyBkeW5hbWljIHJhbmdlIGNvbXByZXNzaW9uCiAgICAgKgogICAgICogaWYgcERyY0NoRGF0YS0+ZHJjU2duW2JhbmRdIGlzIAogICAgICogIDEgdGhlbiBnYWluIGlzIDwgMSA6ICBmYWN0b3IgPSAyXigtc2VsZi0+Y3V0ICAgKiBwRHJjQ2hEYXRhLT5kcmNNYWdbYmFuZF0gLyAyNCkKICAgICAqICAwIHRoZW4gZ2FpbiBpcyA+IDEgOiAgZmFjdG9yID0gMl4oIHNlbGYtPmJvb3N0ICogcERyY0NoRGF0YS0+ZHJjTWFnW2JhbmRdIC8gMjQpCiAgICAgKi8KCiAgICBpZiAoKGRyY1ZhbCYweDdGKSA+IDApIHsKICAgICAgRklYUF9EQkwgdFBhcmFtVmFsID0gKGRyY1ZhbCAmIDB4ODApID8gLXBQYXJhbXMtPmN1dCA6IHBQYXJhbXMtPmJvb3N0OwoKICAgICAgZmFjdF9tYW50aXNzYVtiYW5kXSA9CiAgICAgICAgZjJQb3coIChGSVhQX0RCTCkoKElOVClmTXVsdChGTDJGWENPTlNUX0RCTCgxLjBmLzE5Mi4wZiksIHRQYXJhbVZhbCkgKiAoZHJjVmFsJjB4N0YpKSwKICAgICAgICAgICAgICAgICAzK0RSQ19QQVJBTV9TQ0FMRSwKICAgICAgICAgICAgICAgICZmYWN0X2V4cG9uZW50W2JhbmRdICk7CiAgICB9CiAgICB9CgogICAgZmFjdF9tYW50aXNzYVtiYW5kXSAgPSBmTXVsdChmYWN0X21hbnRpc3NhW2JhbmRdLCBub3JtX21hbnRpc3NhKTsKICAgIGZhY3RfZXhwb25lbnRbYmFuZF0gKz0gbm9ybV9leHBvbmVudDsKCgogICAgYm90dG9tID0gdG9wOwoKICB9ICAvKiBlbmQgbG9vcCBvdmVyIGJhbmRzICovCgoKICAvKiBub3JtYWxpemF0aW9ucyAqLwogIHsKICAgIGludCByZXM7CgogICAgbWF4X21hbnRpc3NhID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICBtYXhfZXhwb25lbnQgPSAwOwogICAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kKyspIHsKICAgICAgbWF4X21hbnRpc3NhID0gZml4TWF4KG1heF9tYW50aXNzYSwgZmFjdF9tYW50aXNzYVtiYW5kXSk7CiAgICAgIG1heF9leHBvbmVudCA9IGZpeE1heChtYXhfZXhwb25lbnQsIGZhY3RfZXhwb25lbnRbYmFuZF0pOwogICAgfQoKICAgIC8qIGxlZnQgc2hpZnQgZmFjdG9ycyB0byBnYWluIGFjY3VyYW5jeSAqLwogICAgcmVzID0gQ250TGVhZGluZ1plcm9zKG1heF9tYW50aXNzYSkgLSAxOwoKICAgIC8qIGFib3ZlIHRvcG1vc3QgRFJDIGJhbmQgZ2FpbiBmYWN0b3IgaXMgMSAqLwogICAgaWYgKCgocERyY0NoRGF0YS0+YmFuZFRvcFtudW1CYW5kcy0xXSsxKTw8MikgPCBhYWNGcmFtZVNpemUpIHJlcyA9IDA7CgogICAgaWYgKHJlcyA+IDApIHsKICAgICAgcmVzID0gZml4TWluKHJlcywgbWF4X2V4cG9uZW50KTsKICAgICAgbWF4X2V4cG9uZW50IC09IHJlczsKCiAgICAgIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCsrKSB7CiAgICAgICAgZmFjdF9tYW50aXNzYVtiYW5kXSA8PD0gcmVzOwogICAgICAgIGZhY3RfZXhwb25lbnRbYmFuZF0gIC09IHJlczsKICAgICAgfQogICAgfQoKICAgIC8qIG5vcm1hbGl6ZSBtYWduaXR1ZGVzIHRvIG9uZSBzY2FsZSBmYWN0b3IgKi8KICAgIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCsrKSB7CiAgICAgIGlmIChmYWN0X2V4cG9uZW50W2JhbmRdIDwgbWF4X2V4cG9uZW50KSB7CiAgICAgICAgZmFjdF9tYW50aXNzYVtiYW5kXSA+Pj0gbWF4X2V4cG9uZW50IC0gZmFjdF9leHBvbmVudFtiYW5kXTsKICAgICAgfQogICAgICBpZiAoZmFjdF9tYW50aXNzYVtiYW5kXSAhPSBGTDJGWENPTlNUX0RCTCgwLjVmKSkgewogICAgICAgIG1vZGlmeUJpbnMgPSAxOwogICAgICB9CiAgICB9CiAgICBpZiAobWF4X2V4cG9uZW50ICE9IDEpIHsKICAgICAgbW9kaWZ5QmlucyA9IDE7CiAgICB9CiAgfQoKICAvKiAgYXBwbHkgZmFjdG9yIHRvIHNwZWN0cmFsIGxpbmVzCiAgICogIHNob3J0IGJsb2NrcyBtdXN0IHRha2UgY2FyZSB0aGF0IGJhbmRzIGZhbGwgb24gCiAgICogIGJsb2NrIGJvdW5kYXJpZXMhCiAgICovCiAgaWYgKCFiU2JyUHJlc2VudCkKICB7CiAgICBib3R0b20gPSAwOwoKICAgIGlmICghbW9kaWZ5QmlucykgewogICAgICAvKiBXZSBkb24ndCBoYXZlIHRvIG1vZGlmeSB0aGUgc3BlY3RyYWwgYmlucyBiZWNhdXNlIHRoZSBmcmFjdGlvbmFsIHBhcnQgb2YgYWxsIGZhY3RvcnMgaXMgMC41LgogICAgICAgICBJbiBvcmRlciB0byBrZWVwIGFjY3VyYW5jeSB3ZSBkb24ndCBhcHBseSB0aGUgZmFjdG9yIGJ1dCBkZWNyZWFzZSB0aGUgZXhwb25lbnQgaW5zdGVhZC4gKi8KICAgICAgbWF4X2V4cG9uZW50IC09IDE7CiAgICB9IGVsc2UKICAgIHsKICAgICAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kKyspCiAgICAgIHsKICAgICAgICB0b3AgPSBmaXhNaW4oKGludCkoIChwRHJjQ2hEYXRhLT5iYW5kVG9wW2JhbmRdKzEpPDwyICksIGFhY0ZyYW1lU2l6ZSk7ICAgLyogLi4uICogRFJDX0JBTkRfTVVMVDsgKi8KCiAgICAgICAgZm9yIChiaW4gPSBib3R0b207IGJpbiA8IHRvcDsgYmluKyspIHsKICAgICAgICAgIHBTcGVjdHJhbENvZWZmaWNpZW50W2Jpbl0gPSBmTXVsdChwU3BlY3RyYWxDb2VmZmljaWVudFtiaW5dLCBmYWN0X21hbnRpc3NhW2JhbmRdKTsKICAgICAgICB9CgogICAgICAgIGJvdHRvbSA9IHRvcDsKICAgICAgfQogICAgfQoKICAgIC8qIGFib3ZlIHRvcG1vc3QgRFJDIGJhbmQgZ2FpbiBmYWN0b3IgaXMgMSAqLwogICAgaWYgKG1heF9leHBvbmVudCA+IDApIHsKICAgICAgZm9yIChiaW4gPSBib3R0b207IGJpbiA8IGFhY0ZyYW1lU2l6ZTsgYmluKz0xKSB7CiAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnRbYmluXSA+Pj0gbWF4X2V4cG9uZW50OwogICAgICB9CiAgICB9CgogICAgLyogYWRqdXN0IHNjYWxpbmcgKi8KICAgIHBTcGVjU2NhbGVbMF0gKz0gbWF4X2V4cG9uZW50OwoKICAgIGlmICh3aW5TZXEgPT0gRWlnaHRTaG9ydFNlcXVlbmNlKSB7CiAgICAgIGludCB3aW47CiAgICAgIGZvciAod2luID0gMTsgd2luIDwgODsgd2luKyspIHsKICAgICAgICBwU3BlY1NjYWxlW3dpbl0gKz0gbWF4X2V4cG9uZW50OwogICAgICB9CiAgICB9CiAgfQogIGVsc2UgewogICAgSEFORExFX1NCUkRFQ09ERVIgaFNickRlY29kZXIgPSAoSEFORExFX1NCUkRFQ09ERVIpcFNickRlYzsKICAgIFVJTlQgbnVtQmFuZHMgPSBwRHJjQ2hEYXRhLT5udW1CYW5kczsKCiAgICAvKiBmZWVkIGZhY3RvcnMgaW50byBTQlIgZGVjb2RlciBmb3IgYXBwbGljYXRpb24gaW4gUU1GIGRvbWFpbi4gKi8KICAgIHNickRlY29kZXJfZHJjRmVlZENoYW5uZWwgKAogICAgICAgICAgICBoU2JyRGVjb2RlciwKICAgICAgICAgICAgY2gsCiAgICAgICAgICAgIG51bUJhbmRzLAogICAgICAgICAgICBmYWN0X21hbnRpc3NhLAogICAgICAgICAgICBtYXhfZXhwb25lbnQsCiAgICAgICAgICAgIHBEcmNDaERhdGEtPmRyY0ludGVycG9sYXRpb25TY2hlbWUsCiAgICAgICAgICAgIHdpblNlcSwKICAgICAgICAgICAgcERyY0NoRGF0YS0+YmFuZFRvcAogICAgICAgICAgKTsKICB9CgogIHJldHVybjsKfQoKCi8qIAogKiBQcmVwYXJlIERSQyBwcm9jZXNzaW5nCiAqLwppbnQgYWFjRGVjb2Rlcl9kcmNQcm9sb2cgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW10sCiAgICAgICAgVUNIQVIgIHBjZUluc3RhbmNlVGFnLAogICAgICAgIFVDSEFSICBjaGFubmVsTWFwcGluZ1tdLCAvKiBDaGFubmVsIG1hcHBpbmcgdHJhbnNsYXRpbmcgZHJjQ2hhbm5lbCBpbmRleCB0byBjYW5vbmljYWwgY2hhbm5lbCBpbmRleCAqLwogICAgICAgIGludCAgICB2YWxpZENoYW5uZWxzICkKewogIGludCBlcnIgPSAwOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm4gLTE7CiAgfQoKICBpZiAoIXNlbGYtPnBhcmFtcy5ic0RlbGF5RW5hYmxlKQogIHsKICAgIGVyciA9IGFhY0RlY29kZXJfZHJjRXh0cmFjdEFuZE1hcCAoCiAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgcGNlSW5zdGFuY2VUYWcsCiAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLAogICAgICAgICAgICB2YWxpZENoYW5uZWxzICk7CiAgfQoKICByZXR1cm4gZXJyOwp9CgoKLyogCiAqIEZpbmFsaXplIERSQyBwcm9jZXNzaW5nCiAqLwppbnQgYWFjRGVjb2Rlcl9kcmNFcGlsb2cgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW10sCiAgICAgICAgVUNIQVIgIHBjZUluc3RhbmNlVGFnLAogICAgICAgIFVDSEFSICBjaGFubmVsTWFwcGluZ1tdLCAvKiBDaGFubmVsIG1hcHBpbmcgdHJhbnNsYXRpbmcgZHJjQ2hhbm5lbCBpbmRleCB0byBjYW5vbmljYWwgY2hhbm5lbCBpbmRleCAqLwogICAgICAgIGludCAgICB2YWxpZENoYW5uZWxzICkKewogIGludCBlcnIgPSAwOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm4gLTE7CiAgfQoKICBpZiAoc2VsZi0+cGFyYW1zLmJzRGVsYXlFbmFibGUpCiAgewogICAgZXJyID0gYWFjRGVjb2Rlcl9kcmNFeHRyYWN0QW5kTWFwICgKICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgaEJzLAogICAgICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgICAgICBwY2VJbnN0YW5jZVRhZywKICAgICAgICAgICAgY2hhbm5lbE1hcHBpbmcsCiAgICAgICAgICAgIHZhbGlkQ2hhbm5lbHMgKTsKICB9CgogIHJldHVybiBlcnI7Cn0KCi8qCiAqIEV4cG9ydCByZWxldmFudCBtZXRhZGF0YSBpbmZvIGZyb20gYml0c3RyZWFtIHBheWxvYWQuCiAqLwp2b2lkIGFhY0RlY29kZXJfZHJjR2V0SW5mbyAoCiAgICAgICAgSEFORExFX0FBQ19EUkMgIHNlbGYsCiAgICAgICAgU0NIQVIgICAgICAgICAgKnBQcmVzTW9kZSwKICAgICAgICBTQ0hBUiAgICAgICAgICAqcFByb2dSZWZMZXZlbCApCnsKICBpZiAoc2VsZiAhPSBOVUxMKSB7CiAgICBpZiAocFByZXNNb2RlICE9IE5VTEwpIHsKICAgICAgKnBQcmVzTW9kZSA9IHNlbGYtPnByZXNNb2RlOwogICAgfQogICAgaWYgKHBQcm9nUmVmTGV2ZWwgIT0gTlVMTCkgewogICAgICBpZiAoc2VsZi0+cHJvZ1JlZkxldmVsUHJlc2VudCkgewogICAgICAgICpwUHJvZ1JlZkxldmVsID0gc2VsZi0+cHJvZ1JlZkxldmVsOwogICAgICB9IGVsc2UgewogICAgICAgICpwUHJvZ1JlZkxldmVsID0gLTE7CiAgICAgIH0KICAgIH0KICB9Cn0K