Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBDaHJpc3RpYW4gR3JpZWJlbAogICBEZXNjcmlwdGlvbjogRHluYW1pYyByYW5nZSBjb250cm9sIChEUkMpIGRlY29kZXIgdG9vbCBmb3IgQUFDCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZGVjX2RyYy5oIgoKCiNpbmNsdWRlICJjaGFubmVsaW5mby5oIgojaW5jbHVkZSAiYWFjX3JvbS5oIgoKICNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgovKgogKiBEeW5hbWljIFJhbmdlIENvbnRyb2wKICovCgovKiBGb3IgcGFyYW1ldGVyIGNvbnZlcnNpb24gKi8KI2RlZmluZSBEUkNfUEFSQU1FVEVSX0JJVFMgICAgICAgICggNyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9TVEVQUyAgICAgICAoIDE8PERSQ19QQVJBTUVURVJfQklUUyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9GQUNUT1IgICAgICAoIERSQ19NQVhfUVVBTlRfU1RFUFMtMSApCiNkZWZpbmUgRFJDX1BBUkFNX1FVQU5UX1NURVAgICAgICAoIEZMMkZYQ09OU1RfREJMKDEuMGYvKGZsb2F0KURSQ19NQVhfUVVBTlRfRkFDVE9SKSApCiNkZWZpbmUgRFJDX1BBUkFNX1NDQUxFICAgICAgICAgICAoIDEgKQoKI2RlZmluZSBNQVhfUkVGRVJFTkNFX0xFVkVMICAgICAgICggMTI3ICkKCiAjZGVmaW5lIERWQl9BTkNfREFUQV9TWU5DX0JZVEUgICAoIDB4QkMgKSAgICAvKiBEVkIgYW5jaWxsYXJ5IGRhdGEgc3luYyBieXRlLiAqLwoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgRFJDIGluZm9ybWF0aW9uCgogIFxzZWxmIEhhbmRsZSBvZiBEUkMgaW5mbwoKICBccmV0dXJuIG5vbmUKKi8Kdm9pZCBhYWNEZWNvZGVyX2RyY0luaXQgKAogICAgSEFORExFX0FBQ19EUkMgc2VsZiApCnsKICBDRHJjUGFyYW1zICpwUGFyYW1zOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBpbml0IGNvbnRyb2wgZmllbGRzICovCiAgc2VsZi0+ZW5hYmxlID0gMDsKICBzZWxmLT5udW1UaHJlYWRzID0gMDsKCiAgLyogaW5pdCBwYXJhbXMgKi8KICBwUGFyYW1zID0gJnNlbGYtPnBhcmFtczsKICBwUGFyYW1zLT5ic0RlbGF5RW5hYmxlID0gMDsKICBwUGFyYW1zLT5jdXQgICAgICA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIHBQYXJhbXMtPnVzckN1dCAgID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgcFBhcmFtcy0+Ym9vc3QgICAgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBwUGFyYW1zLT51c3JCb29zdCA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIHBQYXJhbXMtPnRhcmdldFJlZkxldmVsID0gLTE7CiAgcFBhcmFtcy0+ZXhwaXJ5RnJhbWUgPSBBQUNERUNfRFJDX0RGTFRfRVhQSVJZX0ZSQU1FUzsKICBwUGFyYW1zLT5hcHBseURpZ2l0YWxOb3JtID0gMDsKICBwUGFyYW1zLT5hcHBseUhlYXZ5Q29tcHJlc3Npb24gPSAwOwoKICAvKiBpbml0aWFsIHByb2dyYW0gcmVmIGxldmVsID0gdGFyZ2V0IHJlZiBsZXZlbCAqLwogIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBQYXJhbXMtPnRhcmdldFJlZkxldmVsOwp9CgoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgRFJDIGNvbnRyb2wgZGF0YSBmb3Igb25lIGNoYW5uZWwKCiAgXHNlbGYgSGFuZGxlIG9mIERSQyBpbmZvCgogIFxyZXR1cm4gbm9uZQoqLwp2b2lkIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhICgKICAgIENEcmNDaGFubmVsRGF0YSAqcERyY0NoRGF0YSApCnsKICBpZiAocERyY0NoRGF0YSAhPSBOVUxMKSB7CiAgICBwRHJjQ2hEYXRhLT5leHBpcnlDb3VudCA9IDA7CiAgICBwRHJjQ2hEYXRhLT5udW1CYW5kcyAgICA9IDE7CiAgICBwRHJjQ2hEYXRhLT5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKICAgIHBEcmNDaERhdGEtPmRyY1ZhbHVlWzBdID0gMDsKICAgIHBEcmNDaERhdGEtPmRyY0ludGVycG9sYXRpb25TY2hlbWUgPSAwOwogICAgcERyY0NoRGF0YS0+ZHJjRGF0YVR5cGUgPSBVTktOT1dOX1BBWUxPQUQ7CiAgfQp9CgoKLyohCiAgXGJyaWVmICBTZXQgb25lIHNpbmdsZSBEUkMgcGFyYW1ldGVyCgogIFxzZWxmICAgSGFuZGxlIG9mIERSQyBpbmZvLgogIFxwYXJhbSAgUGFyYW1ldGVyIHRvIGJlIHNldC4KICBcdmFsdWUgIFZhbHVlIHRvIGJlIHNldC4KCiAgXHJldHVybiBhbiBlcnJvciBjb2RlLgoqLwpBQUNfREVDT0RFUl9FUlJPUiBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgIEhBTkRMRV9BQUNfRFJDICAgIHNlbGYsCiAgICBBQUNERUNfRFJDX1BBUkFNICBwYXJhbSwKICAgIElOVCAgICAgICAgICAgICAgIHZhbHVlICkKewogIEFBQ19ERUNPREVSX0VSUk9SIEVycm9yU3RhdHVzID0gQUFDX0RFQ19PSzsKCiAgc3dpdGNoIChwYXJhbSkKICB7CiAgY2FzZSBEUkNfQ1VUX1NDQUxFOgogICAgLyogc2V0IGF0dGVudWF0aW9uIHNjYWxlIGZhY3RvciAqLwogICAgaWYgKCAodmFsdWUgPCAwKQogICAgICB8fCAodmFsdWUgPiBEUkNfTUFYX1FVQU5UX0ZBQ1RPUikgKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPnBhcmFtcy51c3JDdXQgPSAoRklYUF9EQkwpKChJTlQpKERSQ19QQVJBTV9RVUFOVF9TVEVQPj5EUkNfUEFSQU1fU0NBTEUpICogKElOVCl2YWx1ZSk7CiAgICBpZiAoc2VsZi0+cGFyYW1zLmFwcGx5SGVhdnlDb21wcmVzc2lvbiA9PSAwKQogICAgICBzZWxmLT5wYXJhbXMuY3V0ID0gc2VsZi0+cGFyYW1zLnVzckN1dDsKICAgIGJyZWFrOwogIGNhc2UgRFJDX0JPT1NUX1NDQUxFOgogICAgLyogc2V0IGJvb3N0IGZhY3RvciAqLwogICAgaWYgKCAodmFsdWUgPCAwKQogICAgICB8fCAodmFsdWUgPiBEUkNfTUFYX1FVQU5UX0ZBQ1RPUikgKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPnBhcmFtcy51c3JCb29zdCA9IChGSVhQX0RCTCkoKElOVCkoRFJDX1BBUkFNX1FVQU5UX1NURVA+PkRSQ19QQVJBTV9TQ0FMRSkgKiAoSU5UKXZhbHVlKTsKICAgIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uID09IDApCiAgICAgIHNlbGYtPnBhcmFtcy5ib29zdCA9IHNlbGYtPnBhcmFtcy51c3JCb29zdDsKICAgIGJyZWFrOwogIGNhc2UgVEFSR0VUX1JFRl9MRVZFTDoKICAgIGlmICggdmFsdWUgPiAgTUFYX1JFRkVSRU5DRV9MRVZFTAogICAgICB8fCB2YWx1ZSA8IC1NQVhfUkVGRVJFTkNFX0xFVkVMICkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CiAgICBpZiAodmFsdWUgPCAwKSB7CiAgICAgIHNlbGYtPnBhcmFtcy5hcHBseURpZ2l0YWxOb3JtID0gMDsKICAgICAgc2VsZi0+cGFyYW1zLnRhcmdldFJlZkxldmVsID0gLTE7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogcmVmX2xldmVsIG11c3QgYmUgYmV0d2VlbiAwIGFuZCBNQVhfUkVGRVJFTkNFX0xFVkVMLCBpbmNsdXNpdmUgKi8KICAgICAgc2VsZi0+cGFyYW1zLmFwcGx5RGlnaXRhbE5vcm0gPSAxOwogICAgICBpZiAoc2VsZi0+cGFyYW1zLnRhcmdldFJlZkxldmVsICE9IChTQ0hBUil2YWx1ZSkgewogICAgICAgIHNlbGYtPnBhcmFtcy50YXJnZXRSZWZMZXZlbCA9IChTQ0hBUil2YWx1ZTsKICAgICAgICBzZWxmLT5wcm9nUmVmTGV2ZWwgPSAoU0NIQVIpdmFsdWU7ICAvKiBBbHdheXMgc2V0IHRoZSBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCBlcXVhbCB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgbGV2ZWwgYWNjb3JkaW5nIHRvIDQuNS4yLjcuMyBvZiBJU08vSUVDIDE0NDk2LTMuICovCiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgQVBQTFlfTk9STUFMSVpBVElPTjoKICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIC8qIFN0b3JlIG5ldyBwYXJhbWV0ZXIgdmFsdWUgKi8KICAgIHNlbGYtPnBhcmFtcy5hcHBseURpZ2l0YWxOb3JtID0gKFVDSEFSKXZhbHVlOwogICAgYnJlYWs7CiAgY2FzZSBBUFBMWV9IRUFWWV9DT01QUkVTU0lPTjoKICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uICE9IChVQ0hBUil2YWx1ZSkgewogICAgICBpZiAodmFsdWUgPT0gMSkgewogICAgICAgIC8qIERpc2FibGUgc2NhbGluZyBvZiBEUkMgdmFsdWVzIGJ5IHNldHRpbmcgdGhlIG1heCB2YWx1ZXMgKi8KICAgICAgICBzZWxmLT5wYXJhbXMuYm9vc3QgPSBGTDJGWENPTlNUX0RCTCgxLjBmLyhmbG9hdCkoMTw8RFJDX1BBUkFNX1NDQUxFKSk7CiAgICAgICAgc2VsZi0+cGFyYW1zLmN1dCAgID0gRkwyRlhDT05TVF9EQkwoMS4wZi8oZmxvYXQpKDE8PERSQ19QQVJBTV9TQ0FMRSkpOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIFJlc3RvcmUgdGhlIHVzZXIgcGFyYW1zICovCiAgICAgICAgc2VsZi0+cGFyYW1zLmJvb3N0ID0gc2VsZi0+cGFyYW1zLnVzckJvb3N0OwogICAgICAgIHNlbGYtPnBhcmFtcy5jdXQgICA9IHNlbGYtPnBhcmFtcy51c3JDdXQ7CiAgICAgIH0KICAgICAgLyogU3RvcmUgbmV3IHBhcmFtZXRlciB2YWx1ZSAqLwogICAgICBzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uID0gKFVDSEFSKXZhbHVlOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBEUkNfQlNfREVMQVk6CiAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gMSkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CiAgICBzZWxmLT5wYXJhbXMuYnNEZWxheUVuYWJsZSA9IHZhbHVlOwogICAgYnJlYWs7CiAgY2FzZSBEUkNfREFUQV9FWFBJUllfRlJBTUU6CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+cGFyYW1zLmV4cGlyeUZyYW1lID0gKFVJTlQpdmFsdWU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKICAvKiBzd2l0Y2ggb24vb2ZmIHByb2Nlc3NpbmcgKi8KICBzZWxmLT5lbmFibGUgPSAoIChzZWxmLT5wYXJhbXMuYm9vc3QgPiAoRklYUF9EQkwpMCkKICAgICAgICAgICAgICAgIHx8IChzZWxmLT5wYXJhbXMuY3V0ICAgPiAoRklYUF9EQkwpMCkKICAgICAgICAgICAgICAgIHx8IChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uICE9IDApCiAgICAgICAgICAgICAgICB8fCAoc2VsZi0+cGFyYW1zLnRhcmdldFJlZkxldmVsID49IDApICk7CgoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCgpzdGF0aWMgaW50IHBhcnNlRXhjbHVkZWRDaGFubmVscyggVUlOVCAqZXhjbHVkZWRDaG5zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzICkKewogIFVJTlQgZXhjbHVkZU1hc2sgPSAwOwogIFVJTlQgaSwgajsKICBpbnQgIGJpdENudCA9IDk7CgogIGZvciAoaSA9IDAsIGogPSAxOyBpIDwgNzsgaSsrLCBqPDw9MSkgewogICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7CiAgICAgIGV4Y2x1ZGVNYXNrIHw9IGo7CiAgICB9CiAgfQoKICAvKiBhZGRpdGlvbmFsX2V4Y2x1ZGVkX2NobnMgKi8KICB3aGlsZSAoRkRLcmVhZEJpdHMoYnMsMSkpIHsKICAgIGZvciAoaSA9IDA7IGkgPCA3OyBpKyssIGo8PD0xKSB7CiAgICAgIGlmIChGREtyZWFkQml0cyhicywxKSkgewogICAgICAgIGV4Y2x1ZGVNYXNrIHw9IGo7CiAgICAgIH0KICAgIH0KICAgIGJpdENudCArPSA5OwogICAgRkRLX0FTU0VSVChqIDwgKFVJTlQpLTEpOwogIH0KCiAgKmV4Y2x1ZGVkQ2huc01hc2sgPSBleGNsdWRlTWFzazsKCiAgcmV0dXJuIChiaXRDbnQpOwp9CgoKLyohCiAgXGJyaWVmIFNhdmUgRFJDIHBheWxvYWQgYml0c3RyZWFtIHBvc2l0aW9uCgogIFxzZWxmIEhhbmRsZSBvZiBEUkMgaW5mbwogIFxicyBIYW5kbGUgb2YgRkRLIGJpdHN0cmVhbQoKICBccmV0dXJuIFRoZSBudW1iZXIgb2YgRFJDIHBheWxvYWQgYml0cwoqLwppbnQgYWFjRGVjb2Rlcl9kcmNNYXJrUGF5bG9hZCAoCiAgICBIQU5ETEVfQUFDX0RSQyBzZWxmLAogICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICBBQUNERUNfRFJDX1BBWUxPQURfVFlQRSB0eXBlICkKewogIFVJTlQgYnNTdGFydFBvczsKICBpbnQgIGksIG51bUJhbmRzID0gMSwgYml0Q250ID0gMDsKCiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgcmV0dXJuIDA7CiAgfQoKICBic1N0YXJ0UG9zID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIE1QRUdfRFJDX0VYVF9EQVRBOgogICAgewogICAgICBiaXRDbnQgPSA0OwoKICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7ICAgICAgICAgIC8qIHBjZV90YWdfcHJlc2VudCAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLDgpOyAgICAgICAgICAgICAgLyogcGNlX2luc3RhbmNlX3RhZyArIGRyY190YWdfcmVzZXJ2ZWRfYml0cyAqLwogICAgICAgIGJpdENudCs9ODsKICAgICAgfQoKICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7ICAgICAgICAgIC8qIGV4Y2x1ZGVkX2NobnNfcHJlc2VudCAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLDcpOyAgICAgICAgICAgICAgLyogZXhjbHVkZSBtYXNrIFswLi43XSAqLwogICAgICAgIGJpdENudCs9ODsKICAgICAgICB3aGlsZSAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgIC8qIGFkZGl0aW9uYWxfZXhjbHVkZWRfY2hucyAqLwogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsNyk7ICAgICAgICAgICAgLyogZXhjbHVkZSBtYXNrIFt4Li55XSAqLwogICAgICAgICAgYml0Q250Kz04OwogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7ICAgICAgICAgIC8qIGRyY19iYW5kc19wcmVzZW50ICovCiAgICAgICAgbnVtQmFuZHMgKz0gRkRLcmVhZEJpdHMoYnMsIDQpOyAvKiBkcmNfYmFuZF9pbmNyICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsNCk7ICAgICAgICAgICAgICAvKiByZXNlcnZlZCAqLwogICAgICAgIGJpdENudCs9ODsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgewogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgLyogZHJjX2JhbmRfdG9wW2ldICovCiAgICAgICAgICBiaXRDbnQrPTg7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogcHJvZ19yZWZfbGV2ZWxfcHJlc2VudCAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLDgpOyAgICAgICAgICAgICAgLyogcHJvZ19yZWZfbGV2ZWwgKyBwcm9nX3JlZl9sZXZlbF9yZXNlcnZlZF9iaXRzICovCiAgICAgICAgYml0Q250Kz04OwogICAgICB9CgogICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykgewogICAgICAgIEZES3JlYWRCaXRzKGJzLDgpOyAgICAgICAgICAgICAgLyogZHluX3JuZ19zZ25baV0gKyBkeW5fcm5nX2N0bFtpXSAqLwogICAgICAgIGJpdENudCs9ODsKICAgICAgfQoKICAgICAgaWYgKCAoc2VsZi0+bnVtUGF5bG9hZHMgPCBNQVhfRFJDX1RIUkVBRFMpCiAgICAgICAgJiYgKChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKSA+PSAwKSApCiAgICAgIHsKICAgICAgICBzZWxmLT5kcmNQYXlsb2FkUG9zaXRpb25bc2VsZi0+bnVtUGF5bG9hZHMrK10gPSBic1N0YXJ0UG9zOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgICBjYXNlIERWQl9EUkNfQU5DX0RBVEE6CiAgICAgIGJpdENudCArPSA4OwogICAgICAvKiBjaGVjayBzeW5jIHdvcmQgKi8KICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLCA4KSA9PSBEVkJfQU5DX0RBVEFfU1lOQ19CWVRFKQogICAgICB7CiAgICAgICAgaW50IGRteExldmVsc1ByZXNlbnQsIGNvbXByZXNzaW9uUHJlc2VudDsKICAgICAgICBpbnQgY29hcnNlR3JhaW5UY1ByZXNlbnQsIGZpbmVHcmFpblRjUHJlc2VudDsKCiAgICAgICAgLyogYnNfaW5mbyBmaWVsZCAqLyAKICAgICAgICBGREtyZWFkQml0cyhicywgOCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtcGVnX2F1ZGlvX3R5cGUsIGRvbGJ5X3N1cnJvdW5kX21vZGUsIHByZXNlbnRhdGlvbl9tb2RlICovCiAgICAgICAgYml0Q250Kz04OwoKICAgICAgICAvKiBFdmFsdWF0ZSBhbmNpbGxhcnlfZGF0YV9zdGF0dXMgKi8KICAgICAgICBGREtyZWFkQml0cyhicywgMyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiByZXNlcnZlZCwgc2V0IHRvIDAgKi8KICAgICAgICBkbXhMZXZlbHNQcmVzZW50ID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNF9zdGF0dXMgKi8KICAgICAgICBGREtyZWFkQml0cyhicywgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiByZXNlcnZlZCwgc2V0IHRvIDAgKi8KICAgICAgICBjb21wcmVzc2lvblByZXNlbnQgICA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBhdWRpb19jb2RpbmdfbW9kZV9hbmRfY29tcHJlc3Npb24gc3RhdHVzICovCiAgICAgICAgY29hcnNlR3JhaW5UY1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogY29hcnNlX2dyYWluX3RpbWVjb2RlX3N0YXR1cyAqLwogICAgICAgIGZpbmVHcmFpblRjUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGZpbmVfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgICAgICAgYml0Q250Kz04OwoKICAgICAgICAvKiBNUEVHNCBkb3dubWl4aW5nIGxldmVscyAqLwogICAgICAgIGlmIChkbXhMZXZlbHNQcmVzZW50KSB7CiAgICAgICAgICBGREtyZWFkQml0cyhicywgOCk7ICAgICAgICAgICAgICAgICAgICAgICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzQgKi8KICAgICAgICAgIGJpdENudCs9ODsKICAgICAgICB9CiAgICAgICAgLyogYXVkaW8gY29kaW5nIG1vZGUgYW5kIGNvbXByZXNzaW9uIHN0YXR1cyAqLwogICAgICAgIGlmIChjb21wcmVzc2lvblByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgICAgICAgICAgICAgICAgICAgLyogYXVkaW9fY29kaW5nX21vZGUsIENvbXByZXNzaW9uX3ZhbHVlICovCiAgICAgICAgICBiaXRDbnQrPTE2OwogICAgICAgIH0KICAgICAgICAvKiBjb2Fyc2UgZ3JhaW4gdGltZWNvZGUgKi8KICAgICAgICBpZiAoY29hcnNlR3JhaW5UY1ByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgICAgICAgICAgICAgICAgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGUgKi8KICAgICAgICAgIGJpdENudCs9MTY7CiAgICAgICAgfQogICAgICAgIC8qIGZpbmUgZ3JhaW4gdGltZWNvZGUgKi8KICAgICAgICBpZiAoZmluZUdyYWluVGNQcmVzZW50KSB7CiAgICAgICAgICBGREtyZWFkQml0cyhicywgMTYpOyAgICAgICAgICAgICAgICAgICAgICAgLyogZmluZV9ncmFpbl90aW1lY29kZSAqLwogICAgICAgICAgYml0Q250Kz0xNjsKICAgICAgICB9CiAgICAgICAgaWYgKCAhc2VsZi0+ZHZiQW5jRGF0YUF2YWlsYWJsZQogICAgICAgICAgJiYgKChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKSA+PSAwKSApCiAgICAgICAgewogICAgICAgICAgc2VsZi0+ZHZiQW5jRGF0YVBvc2l0aW9uICA9IGJzU3RhcnRQb3M7CiAgICAgICAgICBzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlID0gMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICByZXR1cm4gKGJpdENudCk7Cn0KCgovKiEKICBcYnJpZWYgUGFyc2UgRFJDIHBhcmFtZXRlcnMgZnJvbSBiaXRzdHJlYW0KCiAgXGJzIEhhbmRsZSBvZiBGREsgYml0c3RyZWFtIChpbikKICBccERyY0JzIFBvaW50ZXIgdG8gRFJDIHBheWxvYWQgZGF0YSBjb250YWluZXIgKG91dCkKICBccGF5bG9hZFBvc2l0aW9uIEJpdHN0cmVhbSBwb3NpdGlvbiBvZiBNUEVHIERSQyBkYXRhIGp1bmsgKGluKQoKICBccmV0dXJuIE51bWJlciBvZiBiaXRzIHJlYWQgKDAgaW4gY2FzZSBvZiBhIHBhcnNlIGVycm9yKQoqLwpzdGF0aWMgaW50IGFhY0RlY29kZXJfZHJjUGFyc2UgKAogICAgSEFORExFX0ZES19CSVRTVFJFQU0gIGJzLAogICAgQ0RyY1BheWxvYWQgICAgICAgICAgKnBEcmNCcywKICAgIFVJTlQgICAgICAgICAgICAgICAgICBwYXlsb2FkUG9zaXRpb24gKQp7CiAgaW50IGksIG51bUJhbmRzLCBiaXRDbnQgPSA0OwoKICAvKiBNb3ZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIERSQyBwYXlsb2FkIGZpZWxkICovCiAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIEZES2dldFZhbGlkQml0cyhicyktcGF5bG9hZFBvc2l0aW9uKTsKCiAgLyogcGNlX3RhZ19wcmVzZW50ICovCiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKQogIHsKICAgIHBEcmNCcy0+cGNlSW5zdGFuY2VUYWcgPSBGREtyZWFkQml0cyhicywgNCk7ICAvKiBwY2VfaW5zdGFuY2VfdGFnICovCiAgICAvKiBvbmx5IG9uZSBwcm9ncmFtIHN1cHBvcnRlZCAqLwogICAgRkRLcmVhZEJpdHMoYnMsIDQpOyAgLyogZHJjX3RhZ19yZXNlcnZlZF9iaXRzICovCiAgICBiaXRDbnQgKz0gODsKICB9IGVsc2UgewogICAgcERyY0JzLT5wY2VJbnN0YW5jZVRhZyA9IC0xOyAgLyogbm90IHByZXNlbnQgKi8KICB9CgogIGlmIChGREtyZWFkQml0cyhicywxKSkgeyAgICAgICAgLyogZXhjbHVkZWRfY2huc19wcmVzZW50ICovCiAgICAvKiBnZXQgZXhjbHVkZWRfY2huX21hc2sgKi8KICAgIGJpdENudCArPSBwYXJzZUV4Y2x1ZGVkQ2hhbm5lbHMoJnBEcmNCcy0+ZXhjbHVkZWRDaG5zTWFzaywgYnMpOwogIH0gZWxzZSB7CiAgICBwRHJjQnMtPmV4Y2x1ZGVkQ2huc01hc2sgPSAwOwogIH0KCiAgbnVtQmFuZHMgPSAxOwogIGlmIChGREtyZWFkQml0cyhicywxKSkgIC8qIGRyY19iYW5kc19wcmVzZW50ICovCiAgewogICAgLyogZ2V0IGJhbmRfaW5jciAqLwogICAgbnVtQmFuZHMgKz0gRkRLcmVhZEJpdHMoYnMsIDQpOyAgLyogZHJjX2JhbmRfaW5jciAqLwogICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNJbnRlcnBvbGF0aW9uU2NoZW1lID0gRkRLcmVhZEJpdHMoYnMsIDQpOyAgLyogZHJjX2ludGVycG9sYXRpb25fc2NoZW1lICovCiAgICBiaXRDbnQgKz0gODsKICAgIC8qIGJhbmRfdG9wICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQmFuZHM7IGkrKykKICAgIHsKICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5iYW5kVG9wW2ldID0gRkRLcmVhZEJpdHMoYnMsIDgpOyAgLyogZHJjX2JhbmRfdG9wW2ldICovCiAgICAgIGJpdENudCArPSA4OwogICAgfQogIH0KICBlbHNlIHsKICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuYmFuZFRvcFswXSA9ICgxMDI0ID4+IDIpIC0gMTsgIC8qIC4uLiBjb21wcmlzaW5nIHRoZSB3aG9sZSBzcGVjdHJ1bS4gKi87CiAgfQoKICBwRHJjQnMtPmNoYW5uZWxEYXRhLm51bUJhbmRzID0gbnVtQmFuZHM7CgogIGlmIChGREtyZWFkQml0cyhicywxKSkgICAgICAgICAgICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9wcmVzZW50ICovCiAgewogICAgcERyY0JzLT5wcm9nUmVmTGV2ZWwgPSBGREtyZWFkQml0cyhicywgNyk7ICAvKiBwcm9nX3JlZl9sZXZlbCAqLwogICAgRkRLcmVhZEJpdHMoYnMsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9yZXNlcnZlZF9iaXRzICovCiAgICBiaXRDbnQgKz0gODsKICB9IGVsc2UgewogICAgcERyY0JzLT5wcm9nUmVmTGV2ZWwgPSAtMTsKICB9CgogIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKQogIHsKICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjVmFsdWVbaV0gID0gRkRLcmVhZEJpdHMoYnMsIDEpIDw8IDc7ICAgLyogZHluX3JuZ19zZ25baV0gKi8KICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjVmFsdWVbaV0gfD0gRkRLcmVhZEJpdHMoYnMsIDcpICYgMHg3RjsgLyogZHluX3JuZ19jdGxbaV0gKi8KICAgIGJpdENudCArPSA4OwogIH0KCiAgLyogU2V0IERSQyBwYXlsb2FkIHR5cGUgKi8KICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlID0gTVBFR19EUkNfRVhUX0RBVEE7CgogIHJldHVybiAoYml0Q250KTsKfQoKCi8qIQogIFxicmllZiBQYXJzZSBoZWF2eSBjb21wcmVzc2lvbiB2YWx1ZSB0cmFuc3BvcnRlZCBpbiBEU0VzIG9mIERWQiBzdHJlYW1zIHdpdGggTVBFRy00IGNvbnRlbnQuCgogIFxicyBIYW5kbGUgb2YgRkRLIGJpdHN0cmVhbSAoaW4pCiAgXHBEcmNCcyBQb2ludGVyIHRvIERSQyBwYXlsb2FkIGRhdGEgY29udGFpbmVyIChvdXQpCiAgXHBheWxvYWRQb3NpdGlvbiBCaXRzdHJlYW0gcG9zaXRpb24gb2YgRFZCIGFuY2lsbGFyeSBkYXRhIGp1bmsKCiAgXHJldHVybiBOdW1iZXIgb2YgYml0cyByZWFkICgwIGluIGNhc2Ugb2YgYSBwYXJzZSBlcnJvcikKKi8KI2RlZmluZSBEVkJfQ09NUFJFU1NJT05fU0NBTEUgICAoIDggKSAgICAgICAvKiA0OCwxNjQgZEIgKi8KCnN0YXRpYyBpbnQgYWFjRGVjb2Rlcl9kcmNSZWFkQ29tcHJlc3Npb24gKAogICAgSEFORExFX0ZES19CSVRTVFJFQU0gIGJzLAogICAgQ0RyY1BheWxvYWQgICAgICAgICAgKnBEcmNCcywKICAgIFVJTlQgICAgICAgICAgICAgICAgICBwYXlsb2FkUG9zaXRpb24gKQp7CiAgaW50ICBiaXRDbnQgPSAwOwogIGludCAgZG14TGV2ZWxzUHJlc2VudCwgZXh0ZW5zaW9uUHJlc2VudCwgY29tcHJlc3Npb25QcmVzZW50OwogIGludCAgY29hcnNlR3JhaW5UY1ByZXNlbnQsIGZpbmVHcmFpblRjUHJlc2VudDsKCiAgLyogTW92ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBEUkMgcGF5bG9hZCBmaWVsZCAqLwogIEZES3B1c2hCaURpcmVjdGlvbmFsKGJzLCBGREtnZXRWYWxpZEJpdHMoYnMpLXBheWxvYWRQb3NpdGlvbik7CgogIC8qIFNhbml0eSBjaGVja3MgKi8KICBpZiAoIEZES2dldFZhbGlkQml0cyhicykgPCAyNCApIHsKICAgIHJldHVybiAwOwogIH0KCiAgLyogQ2hlY2sgc3luYyB3b3JkICovCiAgaWYgKEZES3JlYWRCaXRzKGJzLCA4KSAhPSBEVkJfQU5DX0RBVEFfU1lOQ19CWVRFKSB7CiAgICByZXR1cm4gMDsKICB9CgogIC8qIEV2YWx1YXRlIGJzX2luZm8gZmllbGQgKi8gCiAgaWYgKEZES3JlYWRCaXRzKGJzLCAyKSAhPSAzKSB7ICAgICAgICAgICAgICAgLyogbXBlZ19hdWRpb190eXBlICovCiAgICAvKiBObyBNUEVHLTQgYXVkaW8gZGF0YSAqLwogICAgcmV0dXJuIDA7CiAgfQogIEZES3JlYWRCaXRzKGJzLCAyKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRvbGJ5X3N1cnJvdW5kX21vZGUgKi8KICBGREtyZWFkQml0cyhicywgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBwcmVzZW50YXRpb25fbW9kZSAqLwogIEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0ZXJlb19kb3dubWl4X21vZGUgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsIDEpICE9IDApIHsgICAgICAgICAgICAgICAvKiByZXNlcnZlZCwgc2V0IHRvIDAgKi8KICAgIHJldHVybiAwOwogIH0KCiAgLyogRXZhbHVhdGUgYW5jaWxsYXJ5X2RhdGFfc3RhdHVzICovCiAgaWYgKEZES3JlYWRCaXRzKGJzLCAzKSAhPSAwKSB7ICAgICAgICAgICAgICAgLyogcmVzZXJ2ZWQsIHNldCB0byAwICovCiAgICByZXR1cm4gMDsKICB9CiAgZG14TGV2ZWxzUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzRfc3RhdHVzICovCiAgZXh0ZW5zaW9uUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgLyogYW5jaWxsYXJ5X2RhdGFfZXh0ZW5zaW9uX3N0YXR1czsgKi8KICBjb21wcmVzc2lvblByZXNlbnQgICA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBhdWRpb19jb2RpbmdfbW9kZV9hbmRfY29tcHJlc3Npb24gc3RhdHVzICovCiAgY29hcnNlR3JhaW5UY1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogY29hcnNlX2dyYWluX3RpbWVjb2RlX3N0YXR1cyAqLwogIGZpbmVHcmFpblRjUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGZpbmVfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgYml0Q250ICs9IDI0OwoKICBpZiAoZG14TGV2ZWxzUHJlc2VudCkgewogICAgRkRLcmVhZEJpdHMoYnMsIDgpOyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRvd25taXhpbmdfbGV2ZWxzX01QRUc0ICovCiAgICBiaXRDbnQgKz0gODsKICB9CgogIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbl9zdGF0dXMgKi8KICBpZiAoY29tcHJlc3Npb25QcmVzZW50KQogIHsKICAgIFVDSEFSIGNvbXByZXNzaW9uT24sIGNvbXByZXNzaW9uVmFsdWU7CgogICAgLyogYXVkaW9fY29kaW5nX21vZGUgKi8KICAgIGlmICggRkRLcmVhZEJpdHMoYnMsIDcpICE9IDAgKSB7ICAvKiBUaGUgcmVzZXJ2ZWQgYml0cyBzaGFsbCBiZSBzZXQgdG8gIjAiLiAqLwogICAgICByZXR1cm4gMDsKICAgIH0KICAgIGNvbXByZXNzaW9uT24gICAgPSAoVUNIQVIpRkRLcmVhZEJpdHMoYnMsIDEpOyAgLyogY29tcHJlc3Npb25fb24gKi8KICAgIGNvbXByZXNzaW9uVmFsdWUgPSAoVUNIQVIpRkRLcmVhZEJpdHMoYnMsIDgpOyAgLyogQ29tcHJlc3Npb25fdmFsdWUgKi8KICAgIGJpdENudCArPSAxNjsKCiAgICBpZiAoIGNvbXByZXNzaW9uT24gKSB7CiAgICAgIC8qIEEgY29tcHJlc3Npb24gdmFsdWUgaXMgYXZhaWxhYmxlIHNvIHN0b3JlIHRoZSBkYXRhIGp1c3QgbGlrZSBNUEVHIERSQyBkYXRhICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEubnVtQmFuZHMgICAgPSAgMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogT25lIGJhbmQgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjVmFsdWVbMF0gPSAgY29tcHJlc3Npb25WYWx1ZTsgICAgICAgICAgICAgLyogLi4uIHdpdGggb25lIHZhbHVlIC4uLiAqLwogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmJhbmRUb3BbMF0gID0gKDEwMjQgPj4gMikgLSAxOyAgLyogLi4uIGNvbXByaXNpbmcgdGhlIHdob2xlIHNwZWN0cnVtLiAqLwogICAgICBwRHJjQnMtPnBjZUluc3RhbmNlVGFnICAgICAgICAgID0gLTE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vdCBwcmVzZW50ICovCiAgICAgIHBEcmNCcy0+cHJvZ1JlZkxldmVsICAgICAgICAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm90IHByZXNlbnQgKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNEYXRhVHlwZSA9ICBEVkJfRFJDX0FOQ19EQVRBOyAgICAgICAgICAgICAvKiBTZXQgRFJDIHBheWxvYWQgdHlwZSB0byBEVkIuICovCiAgICB9IGVsc2UgewogICAgICAvKiBObyBjb21wcmVzc2lvbiB2YWx1ZSBhdmFpbGFibGUgKi8KICAgICAgLyogQ0FVVElPTjogSXQgaXMgbm90IGNsZWFybHkgZGVmaW5lZCBieSBzdGFuZGFyZCBob3cgdG8gcmVhY3QgaW4gdGhpcyBzaXR1YXRpb24uICovCiAgICAgIC8qIFR1cm4gZG93biB0aGUgY29tcHJlc3Npb24gdmFsdWUgdG8gYXByb3guIDBkQiAqLwogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLm51bUJhbmRzICAgID0gIDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE9uZSBiYW5kIC4uLiAqLwogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY1ZhbHVlWzBdID0gIDB4ODA7ICAgICAgICAgICAgICAgICAgICAgICAgIC8qIC4uLiB3aXRoIGFwcm94LiAwZEIgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuYmFuZFRvcFswXSAgPSAoMTAyNCA+PiAyKSAtIDE7ICAvKiAuLi4gY29tcHJpc2luZyB0aGUgd2hvbGUgc3BlY3RydW0uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUgPSAgRFZCX0RSQ19BTkNfREFUQTsgICAgICAgICAgICAgLyogU2V0IERSQyBwYXlsb2FkIHR5cGUgdG8gRFZCLiAqLwoKICAgICAgLyogSWYgY29tcHJlc3Npb25fb24gZmllbGQgaXMgc2V0IHRvICIwIiB0aGUgY29tcHJlc3Npb25fdmFsdWUgZmllbGQgc2hhbGwgYmUgIjAwMDAgMDAwMCIuICovCiAgICAgIGlmIChjb21wcmVzc2lvblZhbHVlICE9IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgfQogIH0KCiAgLyogUmVhZCB0aW1lY29kZXMgaWYgYXZhaWxhYmxlIGp1c3QgdG8gZ2V0IHRoZSByaWdodCBhbW91bnQgb2YgYml0cy4gKi8KICBpZiAoY29hcnNlR3JhaW5UY1ByZXNlbnQpIHsKICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgLyogY29hcnNlX2dyYWluX3RpbWVjb2RlICovCiAgICBiaXRDbnQgKz0gMTY7CiAgfQogIGlmIChmaW5lR3JhaW5UY1ByZXNlbnQpIHsKICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgLyogZmluZV9ncmFpbl90aW1lY29kZSAqLwogICAgYml0Q250ICs9IDE2OwogIH0KCiAgLyogUmVhZCBleHRlbnNpb24ganVzdCB0byBnZXQgdGhlIHJpZ2h0IGFtb3VudCBvZiBiaXRzLiAqLwogIGlmIChleHRlbnNpb25QcmVzZW50KSB7CiAgICBpbnQgIGV4dEJpdHMgPSA4OwoKICAgIEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgICAgICAgICAgICAgICAvKiByZXNlcnZlZCwgc2V0IHRvIDAgKi8KICAgIGlmIChGREtyZWFkQml0cyhicywgMSkpIGV4dEJpdHMgKz0gODsgICAvKiBleHRfZG93bm1peGluZ19sZXZlbHNfc3RhdHVzICovCiAgICBpZiAoRkRLcmVhZEJpdHMoYnMsIDEpKSBleHRCaXRzICs9IDE2OyAgLyogZXh0X2Rvd25taXhpbmdfZ2xvYmFsX2dhaW5zX3N0YXR1cyAqLwogICAgaWYgKEZES3JlYWRCaXRzKGJzLCAxKSkgZXh0Qml0cyArPSA4OyAgIC8qIGV4dF9kb3dubWl4aW5nX2xmZV9sZXZlbF9zdGF0dXMgKi8KCiAgICBGREtwdXNoRm9yKGJzLCBleHRCaXRzIC0gNCk7ICAgICAgICAgICAgLyogc2tpcCB0aGUgZXh0ZW5zaW9uIHBheWxvYWQgcmVtYWluZGVyLiAqLwogICAgYml0Q250ICs9IGV4dEJpdHM7CiAgfQoKICByZXR1cm4gKGJpdENudCk7Cn0KCgovKiAKICogUHJlcGFyZSBEUkMgcHJvY2Vzc2luZwogKi8Kc3RhdGljIGludCBhYWNEZWNvZGVyX2RyY0V4dHJhY3RBbmRNYXAgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW10sCiAgICAgICAgVUNIQVIgIHBjZUluc3RhbmNlVGFnLAogICAgICAgIFVDSEFSICBjaGFubmVsTWFwcGluZ1tdLCAvKiBDaGFubmVsIG1hcHBpbmcgdHJhbnNsYXRpbmcgZHJjQ2hhbm5lbCBpbmRleCB0byBjYW5vbmljYWwgY2hhbm5lbCBpbmRleCAqLwogICAgICAgIGludCAgICB2YWxpZENoYW5uZWxzICkKewogIENEcmNQYXlsb2FkICB0aHJlYWRCc1tNQVhfRFJDX1RIUkVBRFNdOwogIENEcmNQYXlsb2FkICp2YWxpZFRocmVhZEJzW01BWF9EUkNfVEhSRUFEU107CiAgQ0RyY1BhcmFtcyAgKnBQYXJhbXM7CiAgVUlOVCBiYWNrdXBCc1Bvc2l0aW9uOwogIGludCAgaSwgdGhyZWFkLCB2YWxpZFRocmVhZHMgPSAwOwogIGludCAgbnVtRXhjbHVkZWRDaG5zW01BWF9EUkNfVEhSRUFEU107CgogIEZES19BU1NFUlQoc2VsZiAhPSBOVUxMKTsKICBGREtfQVNTRVJUKGhCcyAhPSBOVUxMKTsKICBGREtfQVNTRVJUKHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gIT0gTlVMTCk7CgogIHBQYXJhbXMgPSAmc2VsZi0+cGFyYW1zOwoKICBzZWxmLT5udW1UaHJlYWRzID0gMDsKICBiYWNrdXBCc1Bvc2l0aW9uID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogIGZvciAoaSA9IDA7IGkgPCBzZWxmLT5udW1QYXlsb2FkcyAmJiBzZWxmLT5udW1UaHJlYWRzIDwgTUFYX0RSQ19USFJFQURTOyBpKyspIHsKICAgIGludCBiaXRzUGFyc2VkOwoKICAgIC8qIEluaXQgcGF5bG9hZCBkYXRhIGNodW5rLiBUaGUgbWVtY2xlYXIgaXMgdmVyeSBpbXBvcnRhbnQgYmVjYXVzZSBpdCBpbml0aWFsaXplcwogICAgICAgdGhlIG1vc3QgdmFsdWVzLiBXaXRob3V0IGl0IHRoZSBtb2R1bGUgd291bGRuJ3Qgd29yayBwcm9wZXJseSBvciBjcmFzaC4gKi8KICAgIEZES21lbWNsZWFyKCZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwgc2l6ZW9mKENEcmNQYXlsb2FkKSk7CiAgICB0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXS5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKCiAgICAvKiBFeHRyYWN0IHBheWxvYWQgKi8KICAgIGJpdHNQYXJzZWQgPSBhYWNEZWNvZGVyX2RyY1BhcnNlKCBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGhyZWFkQnNbc2VsZi0+bnVtVGhyZWFkc10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZHJjUGF5bG9hZFBvc2l0aW9uW2ldICk7CiAgICBpZiAoYml0c1BhcnNlZCA+IDApIHsKICAgICAgc2VsZi0+bnVtVGhyZWFkcysrOwogICAgfQogIH0KICBzZWxmLT5udW1QYXlsb2FkcyA9IDA7CgogIGlmIChzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlKQogIHsgLyogQXBwZW5kIGEgRFZCIGhlYXZ5IGNvbXByZXNzaW9uIHBheWxvYWQgdGhyZWFkIGlmIGF2YWlsYWJsZS4gKi8KICAgIGludCBiaXRzUGFyc2VkOwoKICAgIC8qIEluaXQgcGF5bG9hZCBkYXRhIGNodW5rLiBUaGUgbWVtY2xlYXIgaXMgdmVyeSBpbXBvcnRhbnQgYmVjYXVzZSBpdCBpbml0aWFsaXplcwogICAgICAgdGhlIG1vc3QgdmFsdWVzLiBXaXRob3V0IGl0IHRoZSBtb2R1bGUgd291bGRuJ3Qgd29yayBwcm9wZXJseSBvciBjcmFzaC4gKi8KICAgIEZES21lbWNsZWFyKCZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwgc2l6ZW9mKENEcmNQYXlsb2FkKSk7CiAgICB0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXS5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKCiAgICAvKiBFeHRyYWN0IHBheWxvYWQgKi8KICAgIGJpdHNQYXJzZWQgPSBhYWNEZWNvZGVyX2RyY1JlYWRDb21wcmVzc2lvbiggaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZHZiQW5jRGF0YVBvc2l0aW9uICk7CiAgICBpZiAoYml0c1BhcnNlZCA+IDApIHsKICAgICAgc2VsZi0+bnVtVGhyZWFkcysrOwogICAgfQogIH0KICBzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlID0gMDsKCiAgLyogUmVzZXQgdGhlIGJpdGJ1ZmZmZXIgKi8KICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsIEZES2dldFZhbGlkQml0cyhoQnMpIC0gYmFja3VwQnNQb3NpdGlvbik7CgogIC8qIGNhbGN1bGF0ZSBudW1iZXIgb2YgdmFsaWQgYml0cyBpbiBleGNsX2Nobl9tYXNrICovCgogIC8qIGNvdXBsaW5nIGNoYW5uZWxzIG5vdCBzdXBwb3J0ZWQgKi8KCiAgLyogY2hlY2sgZm9yIHZhbGlkIHRocmVhZHMgKi8KICBmb3IgKHRocmVhZCA9IDA7IHRocmVhZCA8IHNlbGYtPm51bVRocmVhZHM7IHRocmVhZCsrKSB7CiAgICBDRHJjUGF5bG9hZCAqcFRocmVhZEJzID0gJnRocmVhZEJzW3RocmVhZF07CiAgICBpbnQgbnVtRXhjbENobnMgPSAwOwoKICAgIHN3aXRjaCAoKEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFKXBUaHJlYWRCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUpIHsKICAgICAgZGVmYXVsdDoKICAgICAgICBjb250aW51ZTsKICAgICAgY2FzZSBNUEVHX0RSQ19FWFRfREFUQToKICAgICAgY2FzZSBEVkJfRFJDX0FOQ19EQVRBOgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChwVGhyZWFkQnMtPnBjZUluc3RhbmNlVGFnID49IDApIHsgIC8qIGlmIFBDRSB0YWcgcHJlc2VudCAqLwogICAgICBpZiAocFRocmVhZEJzLT5wY2VJbnN0YW5jZVRhZyAhPSBwY2VJbnN0YW5jZVRhZykgewogICAgICAgIGNvbnRpbnVlOyAgLyogZG9uJ3QgYWNjZXB0ICovCiAgICAgIH0KICAgIH0KCiAgICAvKiBjYWxjdWxhdGUgbnVtYmVyIG9mIGV4Y2x1ZGVkIGNoYW5uZWxzICovCiAgICBpZiAocFRocmVhZEJzLT5leGNsdWRlZENobnNNYXNrID4gMCkgewogICAgICBJTlQgZXhjbE1hc2sgPSBwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2s7CiAgICAgIGludCBjaDsKICAgICAgZm9yIChjaCA9IDA7IGNoIDwgdmFsaWRDaGFubmVsczsgY2grKykgewogICAgICAgIG51bUV4Y2xDaG5zICs9IGV4Y2xNYXNrICYgMHgxOwogICAgICAgIGV4Y2xNYXNrID4+PSAxOwogICAgICB9CiAgICB9CiAgICBpZiAobnVtRXhjbENobnMgPCB2YWxpZENoYW5uZWxzKSB7CiAgICAgIHZhbGlkVGhyZWFkQnNbdmFsaWRUaHJlYWRzXSAgID0gcFRocmVhZEJzOwogICAgICBudW1FeGNsdWRlZENobnNbdmFsaWRUaHJlYWRzXSA9IG51bUV4Y2xDaG5zOwogICAgICB2YWxpZFRocmVhZHMrKzsKICAgIH0KICB9CgogIGlmICh2YWxpZFRocmVhZHMgPiAxKSB7CiAgICBpbnQgY2g7CgogICAgLyogY2hlY2sgY29uc2lzdGVuY3kgb2YgZXhjbF9jaG5fbWFzayBhbW9uZ3N0IHZhbGlkIERSQyB0aHJlYWRzICovCiAgICBmb3IgKGNoID0gMDsgY2ggPCB2YWxpZENoYW5uZWxzOyBjaCsrKSB7CiAgICAgIGludCBwcmVzZW50ID0gMDsKCiAgICAgIGZvciAodGhyZWFkID0gMDsgdGhyZWFkIDwgdmFsaWRUaHJlYWRzOyB0aHJlYWQrKykgewogICAgICAgIENEcmNQYXlsb2FkICpwVGhyZWFkQnMgPSB2YWxpZFRocmVhZEJzW3RocmVhZF07CgoKICAgICAgICAvKiB0aHJlYWQgYXBwbGllcyB0byB0aGlzIGNoYW5uZWwgKi8KICAgICAgICBpZiAoIChwVGhyZWFkQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgICAgICAgJiYgKCAobnVtRXhjbHVkZWRDaG5zW3RocmVhZF0gPT0gMCkKICAgICAgICAgICAgfHwgKCEocFRocmVhZEJzLT5leGNsdWRlZENobnNNYXNrICYgKDE8PGNoKSkpICkgKSB7CiAgICAgICAgICBwcmVzZW50Kys7CiAgICAgICAgfQogICAgICB9CgoKICAgICAgaWYgKHByZXNlbnQgPiAxKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgICB9CiAgICB9CiAgfQoKICAvKiBtYXAgRFJDIGJpdHN0cmVhbSBpbmZvcm1hdGlvbiBvbnRvIERSQyBjaGFubmVsIGluZm9ybWF0aW9uICovCiAgZm9yICh0aHJlYWQgPSAwOyB0aHJlYWQgPCB2YWxpZFRocmVhZHM7IHRocmVhZCsrKQogIHsKICAgIENEcmNQYXlsb2FkICpwVGhyZWFkQnMgPSB2YWxpZFRocmVhZEJzW3RocmVhZF07CiAgICBJTlQgZXhjbE1hc2sgPSBwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2s7CiAgICBBQUNERUNfRFJDX1BBWUxPQURfVFlQRSBkcmNQYXlsb2FkVHlwZSA9IChBQUNERUNfRFJDX1BBWUxPQURfVFlQRSlwVGhyZWFkQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlOwogICAgaW50IGNoOwoKICAgIC8qIGxhc3QgcHJvZ1JlZkxldmVsIHRyYW5zbWl0dGVkIGlzIHRoZSBvbmUgdGhhdCBpcyB1c2VkCiAgICAgKiAoYnV0IGl0IHNob3VsZCByZWFsbHkgb25seSBiZSB0cmFuc21pdHRlZCBvbmNlIHBlciBibG9jayEpCiAgICAgKi8KICAgIGlmIChwVGhyZWFkQnMtPnByb2dSZWZMZXZlbCA+PSAwKSB7CiAgICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBUaHJlYWRCcy0+cHJvZ1JlZkxldmVsOwogICAgICBzZWxmLT5wcmxFeHBpcnlDb3VudCA9IDA7ICAvKiBHb3QgYSBuZXcgdmFsdWUgLT4gUmVzZXQgY291bnRlciAqLwogICAgfQoKICAgIC8qIFNDRSwgQ1BFIGFuZCBMRkUgKi8KICAgIGZvciAoY2ggPSAwOyBjaCA8IHZhbGlkQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgaW50IG1hcGVkQ2hhbm5lbCA9IGNoYW5uZWxNYXBwaW5nW2NoXTsKCiAgICAgIGlmICggKChleGNsTWFzayAmICgxPDxtYXBlZENoYW5uZWwpKSA9PSAwKQogICAgICAgICYmICggKGRyY1BheWxvYWRUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgICAgICAgfHwgKChkcmNQYXlsb2FkVHlwZSA9PSBEVkJfRFJDX0FOQ19EQVRBKSAmJiBzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uKQogICAgICAgICApICkgewogICAgICAgIC8qIGNvcHkgdGhyZWFkIHRvIGNoYW5uZWwgKi8KICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+ZHJjRGF0YSA9IHBUaHJlYWRCcy0+Y2hhbm5lbERhdGE7CiAgICAgIH0KICAgIH0KICAgIC8qIENDRXMgbm90IHN1cHBvcnRlZCBieSBub3cgKi8KICB9CgogIC8qIEluY3JlbWVudCBhbmQgY2hlY2sgZXhwaXJ5IGNvdW50ZXIgZm9yIHRoZSBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbDogKi8KICBpZiAoIChwUGFyYW1zLT5leHBpcnlGcmFtZSA+IDApCiAgICAmJiAoc2VsZi0+cHJsRXhwaXJ5Q291bnQrKyA+IHBQYXJhbXMtPmV4cGlyeUZyYW1lKSApCiAgeyAvKiBUaGUgcHJvZ3JhbSByZWZlcmVuY2UgbGV2ZWwgaXMgdG9vIG9sZCwgc28gc2V0IGl0IGJhY2sgdG8gdGhlIHRhcmdldCBsZXZlbC4gKi8KICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBQYXJhbXMtPnRhcmdldFJlZkxldmVsOwogICAgc2VsZi0+cHJsRXhwaXJ5Q291bnQgPSAwOwogIH0KCiAgcmV0dXJuIDA7Cn0KCgp2b2lkIGFhY0RlY29kZXJfZHJjQXBwbHkgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICAgICAgICAgIHNlbGYsCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAqcFNickRlYywKICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgIENEcmNDaGFubmVsRGF0YSAgICAgICAgKnBEcmNDaERhdGEsCiAgICAgICAgRklYUF9EQkwgICAgICAgICAgICAgICAqZXh0R2FpbiwKICAgICAgICBpbnQgIGNoLCAgIC8qIG5lZWRlZCBvbmx5IGZvciBTQlIgKi8KICAgICAgICBpbnQgIGFhY0ZyYW1lU2l6ZSwKICAgICAgICBpbnQgIGJTYnJQcmVzZW50ICkKewogIGludCBiYW5kLCB0b3AsIGJpbiwgbnVtQmFuZHM7CiAgaW50IGJvdHRvbSA9IDA7CiAgaW50IG1vZGlmeUJpbnMgPSAwOwoKICBGSVhQX0RCTCBtYXhfbWFudGlzc2E7CiAgSU5UIG1heF9leHBvbmVudDsKCiAgRklYUF9EQkwgbm9ybV9tYW50aXNzYSA9IEZMMkZYQ09OU1RfREJMKDAuNWYpOwogIElOVCAgbm9ybV9leHBvbmVudCA9IDE7CgogIEZJWFBfREJMIGZhY3RfbWFudGlzc2FbTUFYX0RSQ19CQU5EU107CiAgSU5UICBmYWN0X2V4cG9uZW50W01BWF9EUkNfQkFORFNdOwoKICBDRHJjUGFyYW1zICAqcFBhcmFtcyA9ICZzZWxmLT5wYXJhbXM7CgogIEZJWFBfREJMICAgICpwU3BlY3RyYWxDb2VmZmljaWVudCAgPSAgU1BFQ19MT05HKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50KTsKICBDSWNzSW5mbyAgICAqcEljc0luZm8gICAgICAgICAgICAgID0gJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm87CiAgU0hPUlQgICAgICAgKnBTcGVjU2NhbGUgICAgICAgICAgICA9ICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5zcGVjU2NhbGU7CgogIGludCB3aW5TZXEgPSBwSWNzSW5mby0+V2luZG93U2VxdWVuY2U7CgogIC8qIEluY3JlbWVudCBhbmQgY2hlY2sgZXhwaXJ5IGNvdW50ZXIgKi8KICBpZiAoIChwUGFyYW1zLT5leHBpcnlGcmFtZSA+IDApCiAgICAmJiAoKytwRHJjQ2hEYXRhLT5leHBpcnlDb3VudCA+IHBQYXJhbXMtPmV4cGlyeUZyYW1lKSApCiAgeyAvKiBUaGUgRFJDIGRhdGEgaXMgdG9vIG9sZCwgc28gZGVsZXRlIGl0LiAqLwogICAgYWFjRGVjb2Rlcl9kcmNJbml0Q2hhbm5lbERhdGEoIHBEcmNDaERhdGEgKTsKICB9CgogIGlmICghc2VsZi0+ZW5hYmxlKSB7CiAgICBzYnJEZWNvZGVyX2RyY0Rpc2FibGUoIChIQU5ETEVfU0JSREVDT0RFUilwU2JyRGVjLCBjaCApOwogICAgaWYgKGV4dEdhaW4gIT0gTlVMTCkgewogICAgICBJTlQgZ2FpblNjYWxlID0gKElOVCkqZXh0R2FpbjsKICAgICAgLyogVGhlIGdhaW4gc2NhbGluZyBtdXN0IGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gaW4gdGhlIGJ1ZmZlciBwb2ludGVkIG9uIGJ5IGV4dEdhaW4uICovCiAgICAgIGlmIChnYWluU2NhbGUgPj0gMCAmJiBnYWluU2NhbGUgPD0gREZSQUNUX0JJVFMpIHsKICAgICAgICAqZXh0R2FpbiA9IHNjYWxlVmFsdWUobm9ybV9tYW50aXNzYSwgbm9ybV9leHBvbmVudC1nYWluU2NhbGUpOwogICAgICB9IGVsc2UgewogICAgICAgIEZES19BU1NFUlQoMCk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybjsKICB9CgogIG51bUJhbmRzID0gcERyY0NoRGF0YS0+bnVtQmFuZHM7CiAgdG9wID0gRkRLbWF4KDAsIG51bUJhbmRzLTEpOwoKICBwRHJjQ2hEYXRhLT5iYW5kVG9wWzBdID0gZml4TWluKHBEcmNDaERhdGEtPmJhbmRUb3BbMF0sIChhYWNGcmFtZVNpemUgPj4gMikgLSAxKTsKCiAgLyogSWYgcHJvZ3JhbSByZWZlcmVuY2Ugbm9ybWFsaXphdGlvbiBpcyBkb25lIGluIHRoZSBkaWdpdGFsIGRvbWFpbiwKICBtb2RpZnkgZmFjdG9yIHRvIHBlcmZvcm0gbm9ybWFsaXphdGlvbi4gIHByb2dfcmVmX2xldmVsIGNhbgogIGFsdGVybmF0aXZlbHkgYmUgcGFzc2VkIHRvIHRoZSBzeXN0ZW0gZm9yIG1vZGlmaWNhdGlvbiBvZiB0aGUgbGV2ZWwgaW4KICB0aGUgYW5hbG9nIGRvbWFpbi4gIEFuYWxvZyBsZXZlbCBtb2RpZmljYXRpb24gYXZvaWRzIHByb2JsZW1zIHdpdGgKICByZWR1Y2VkIERBQyBTTlIgKGlmIHNpZ25hbCBpcyBhdHRlbnVhdGVkKSBvciBjbGlwcGluZyAoaWYgc2lnbmFsIGlzCiAgYm9vc3RlZCkgKi8KCiAgaWYgKHBQYXJhbXMtPnRhcmdldFJlZkxldmVsID49IDApCiAgewogICAgLyogMC41XigodGFyZ2V0UmVmTGV2ZWwgLSBwcm9nUmVmTGV2ZWwpLzI0KSAqLwogICAgbm9ybV9tYW50aXNzYSA9IGZMZFBvdygKICAgICAgICAgICAgRkwyRlhDT05TVF9EQkwoLTEuMCksIC8qIGxvZzIoMC41KSAqLwogICAgICAgICAgICAwLAogICAgICAgICAgICAoRklYUF9EQkwpKChJTlQpKEZMMkZYQ09OU1RfREJMKDEuMGYvMjQuMCk+PjMpICogKElOVCkocFBhcmFtcy0+dGFyZ2V0UmVmTGV2ZWwtc2VsZi0+cHJvZ1JlZkxldmVsKSksCiAgICAgICAgICAgIDMsCiAgICAgICAgICAgJm5vcm1fZXhwb25lbnQgKTsKICB9CiAgLyogQWx3YXlzIGV4cG9ydCB0aGUgbm9ybWFsaXphdGlvbiBnYWluIChpZiBwb3NzaWJsZSkuICovCiAgaWYgKGV4dEdhaW4gIT0gTlVMTCkgewogICAgSU5UIGdhaW5TY2FsZSA9IChJTlQpKmV4dEdhaW47CiAgICAvKiBUaGUgZ2FpbiBzY2FsaW5nIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiBpbiB0aGUgYnVmZmVyIHBvaW50ZWQgb24gYnkgZXh0R2Fpbi4gKi8KICAgIGlmIChnYWluU2NhbGUgPj0gMCAmJiBnYWluU2NhbGUgPD0gREZSQUNUX0JJVFMpIHsKICAgICAgKmV4dEdhaW4gPSBzY2FsZVZhbHVlKG5vcm1fbWFudGlzc2EsIG5vcm1fZXhwb25lbnQtZ2FpblNjYWxlKTsKICAgIH0gZWxzZSB7CiAgICAgIEZES19BU1NFUlQoMCk7CiAgICB9CiAgfQogIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlEaWdpdGFsTm9ybSA9PSAwKSB7CiAgICAvKiBSZXNldCBub3JtYWxpemF0aW9uIGdhaW4gc2luY2UgdGhpcyBtb2R1bGUgbXVzdCBub3QgYXBwbHkgaXQgKi8KICAgIG5vcm1fbWFudGlzc2EgPSBGTDJGWENPTlNUX0RCTCgwLjVmKTsKICAgIG5vcm1fZXhwb25lbnQgPSAxOwogIH0KCgogIC8qIGNhbGMgc2NhbGUgZmFjdG9ycyAqLwogIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCsrKQogIHsKICAgIFVDSEFSIGRyY1ZhbCA9IHBEcmNDaERhdGEtPmRyY1ZhbHVlW2JhbmRdOwogICAgdG9wID0gZml4TWluKChpbnQpKCAocERyY0NoRGF0YS0+YmFuZFRvcFtiYW5kXSsxKTw8MiApLCBhYWNGcmFtZVNpemUpOwoKICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPSBGTDJGWENPTlNUX0RCTCgwLjVmKTsKICAgIGZhY3RfZXhwb25lbnRbYmFuZF0gPSAxOwoKICAgIGlmICggIHBQYXJhbXMtPmFwcGx5SGVhdnlDb21wcmVzc2lvbgogICAgICAmJiAoKEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFKXBEcmNDaERhdGEtPmRyY0RhdGFUeXBlID09IERWQl9EUkNfQU5DX0RBVEEpICkKICAgIHsKICAgICAgSU5UIGNvbXByZXNzaW9uRmFjdG9yVmFsX2U7CiAgICAgIGludCB2YWxYLCB2YWxZOwoKICAgICAgdmFsWCA9IGRyY1ZhbCA+PiA0OwogICAgICB2YWxZID0gZHJjVmFsICYgMHgwRjsKCiAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgdW5zY2FsZWQgaGVhdnkgY29tcHJlc3Npb24gZmFjdG9yLgogICAgICAgICBjb21wcmVzc2lvbkZhY3RvciA9IDQ4LjE2NCAtIDYuMDIwNip2YWxYIC0gMC40MDE0KnZhbFkgZEIKICAgICAgICAgcmFuZ2U6IC00OC4xNjYgZEIgdG8gNDguMTY0IGRCICovCiAgICAgIGlmICggZHJjVmFsICE9IDB4N0YgKSB7CiAgICAgICAgZmFjdF9tYW50aXNzYVtiYW5kXSA9CiAgICAgICAgICBmUG93SW50KCBGTDJGWENPTlNUX0RCTCgwLjk1NDgzODY3MTgxKSwgLyogLTAuNDAxNGRCID0gMC45NTQ4Mzg2NzE4MSAqLwogICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgIHZhbFksCiAgICAgICAgICAgICAgICAgICZjb21wcmVzc2lvbkZhY3RvclZhbF9lICk7CgogICAgICAgIC8qIC0wLjAwMDhkQiAoNDguMTY0IC0gNi4wMjA2KjggPSAtMC4wMDA4KSAqLwogICAgICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPSBmTXVsdChGTDJGWENPTlNUX0RCTCgwLjk5OTkwNzkwMDg0KSwgZmFjdF9tYW50aXNzYVtiYW5kXSk7CgogICAgICAgIGZhY3RfZXhwb25lbnRbYmFuZF0gPSBEVkJfQ09NUFJFU1NJT05fU0NBTEUgLSB2YWxYICsgY29tcHJlc3Npb25GYWN0b3JWYWxfZTsKICAgICAgfQogICAgfSBlbHNlCiAgICBpZiAoKEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFKXBEcmNDaERhdGEtPmRyY0RhdGFUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgewogICAgLyogYXBwbHkgdGhlIHNjYWxlZCBkeW5hbWljIHJhbmdlIGNvbnRyb2wgd29yZHMgdG8gZmFjdG9yLgogICAgICogaWYgc2NhbGluZyBkcmNfY3V0IChvciBkcmNfYm9vc3QpLCBvciBjb250cm9sIHdvcmQgZHJjX21hbnRpc3NhIGlzIDAKICAgICAqIHRoZW4gdGhlcmUgaXMgbm8gZHluYW1pYyByYW5nZSBjb21wcmVzc2lvbgogICAgICoKICAgICAqIGlmIHBEcmNDaERhdGEtPmRyY1NnbltiYW5kXSBpcyAKICAgICAqICAxIHRoZW4gZ2FpbiBpcyA8IDEgOiAgZmFjdG9yID0gMl4oLXNlbGYtPmN1dCAgICogcERyY0NoRGF0YS0+ZHJjTWFnW2JhbmRdIC8gMjQpCiAgICAgKiAgMCB0aGVuIGdhaW4gaXMgPiAxIDogIGZhY3RvciA9IDJeKCBzZWxmLT5ib29zdCAqIHBEcmNDaERhdGEtPmRyY01hZ1tiYW5kXSAvIDI0KQogICAgICovCgogICAgaWYgKChkcmNWYWwmMHg3RikgPiAwKSB7CiAgICAgIEZJWFBfREJMIHRQYXJhbVZhbCA9IChkcmNWYWwgJiAweDgwKSA/IC1wUGFyYW1zLT5jdXQgOiBwUGFyYW1zLT5ib29zdDsKCiAgICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPQogICAgICAgIGYyUG93KCAoRklYUF9EQkwpKChJTlQpZk11bHQoRkwyRlhDT05TVF9EQkwoMS4wZi8xOTIuMGYpLCB0UGFyYW1WYWwpICogKGRyY1ZhbCYweDdGKSksCiAgICAgICAgICAgICAgICAgMytEUkNfUEFSQU1fU0NBTEUsCiAgICAgICAgICAgICAgICAmZmFjdF9leHBvbmVudFtiYW5kXSApOwogICAgfQogICAgfQoKICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gID0gZk11bHQoZmFjdF9tYW50aXNzYVtiYW5kXSwgbm9ybV9tYW50aXNzYSk7CiAgICBmYWN0X2V4cG9uZW50W2JhbmRdICs9IG5vcm1fZXhwb25lbnQ7CgoKICAgIGJvdHRvbSA9IHRvcDsKCiAgfSAgLyogZW5kIGxvb3Agb3ZlciBiYW5kcyAqLwoKCiAgLyogbm9ybWFsaXphdGlvbnMgKi8KICB7CiAgICBpbnQgcmVzOwoKICAgIG1heF9tYW50aXNzYSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgbWF4X2V4cG9uZW50ID0gMDsKICAgIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCsrKSB7CiAgICAgIG1heF9tYW50aXNzYSA9IGZpeE1heChtYXhfbWFudGlzc2EsIGZhY3RfbWFudGlzc2FbYmFuZF0pOwogICAgICBtYXhfZXhwb25lbnQgPSBmaXhNYXgobWF4X2V4cG9uZW50LCBmYWN0X2V4cG9uZW50W2JhbmRdKTsKICAgIH0KCiAgICAvKiBsZWZ0IHNoaWZ0IGZhY3RvcnMgdG8gZ2FpbiBhY2N1cmFuY3kgKi8KICAgIHJlcyA9IENudExlYWRpbmdaZXJvcyhtYXhfbWFudGlzc2EpIC0gMTsKCiAgICAvKiBhYm92ZSB0b3Btb3N0IERSQyBiYW5kIGdhaW4gZmFjdG9yIGlzIDEgKi8KICAgIGlmICgoKHBEcmNDaERhdGEtPmJhbmRUb3BbbnVtQmFuZHMtMV0rMSk8PDIpIDwgYWFjRnJhbWVTaXplKSByZXMgPSAwOwoKICAgIGlmIChyZXMgPiAwKSB7CiAgICAgIHJlcyA9IGZpeE1pbihyZXMsIG1heF9leHBvbmVudCk7CiAgICAgIG1heF9leHBvbmVudCAtPSByZXM7CgogICAgICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbnVtQmFuZHM7IGJhbmQrKykgewogICAgICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPDw9IHJlczsKICAgICAgICBmYWN0X2V4cG9uZW50W2JhbmRdICAtPSByZXM7CiAgICAgIH0KICAgIH0KCiAgICAvKiBub3JtYWxpemUgbWFnbml0dWRlcyB0byBvbmUgc2NhbGUgZmFjdG9yICovCiAgICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbnVtQmFuZHM7IGJhbmQrKykgewogICAgICBpZiAoZmFjdF9leHBvbmVudFtiYW5kXSA8IG1heF9leHBvbmVudCkgewogICAgICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPj49IG1heF9leHBvbmVudCAtIGZhY3RfZXhwb25lbnRbYmFuZF07CiAgICAgIH0KICAgICAgaWYgKGZhY3RfbWFudGlzc2FbYmFuZF0gIT0gRkwyRlhDT05TVF9EQkwoMC41ZikpIHsKICAgICAgICBtb2RpZnlCaW5zID0gMTsKICAgICAgfQogICAgfQogICAgaWYgKG1heF9leHBvbmVudCAhPSAxKSB7CiAgICAgIG1vZGlmeUJpbnMgPSAxOwogICAgfQogIH0KCiAgLyogIGFwcGx5IGZhY3RvciB0byBzcGVjdHJhbCBsaW5lcwogICAqICBzaG9ydCBibG9ja3MgbXVzdCB0YWtlIGNhcmUgdGhhdCBiYW5kcyBmYWxsIG9uIAogICAqICBibG9jayBib3VuZGFyaWVzIQogICAqLwogIGlmICghYlNiclByZXNlbnQpCiAgewogICAgYm90dG9tID0gMDsKCiAgICBpZiAoIW1vZGlmeUJpbnMpIHsKICAgICAgLyogV2UgZG9uJ3QgaGF2ZSB0byBtb2RpZnkgdGhlIHNwZWN0cmFsIGJpbnMgYmVjYXVzZSB0aGUgZnJhY3Rpb25hbCBwYXJ0IG9mIGFsbCBmYWN0b3JzIGlzIDAuNS4KICAgICAgICAgSW4gb3JkZXIgdG8ga2VlcCBhY2N1cmFuY3kgd2UgZG9uJ3QgYXBwbHkgdGhlIGZhY3RvciBidXQgZGVjcmVhc2UgdGhlIGV4cG9uZW50IGluc3RlYWQuICovCiAgICAgIG1heF9leHBvbmVudCAtPSAxOwogICAgfSBlbHNlCiAgICB7CiAgICAgIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCsrKQogICAgICB7CiAgICAgICAgdG9wID0gZml4TWluKChpbnQpKCAocERyY0NoRGF0YS0+YmFuZFRvcFtiYW5kXSsxKTw8MiApLCBhYWNGcmFtZVNpemUpOyAgIC8qIC4uLiAqIERSQ19CQU5EX01VTFQ7ICovCgogICAgICAgIGZvciAoYmluID0gYm90dG9tOyBiaW4gPCB0b3A7IGJpbisrKSB7CiAgICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudFtiaW5dID0gZk11bHQocFNwZWN0cmFsQ29lZmZpY2llbnRbYmluXSwgZmFjdF9tYW50aXNzYVtiYW5kXSk7CiAgICAgICAgfQoKICAgICAgICBib3R0b20gPSB0b3A7CiAgICAgIH0KICAgIH0KCiAgICAvKiBhYm92ZSB0b3Btb3N0IERSQyBiYW5kIGdhaW4gZmFjdG9yIGlzIDEgKi8KICAgIGlmIChtYXhfZXhwb25lbnQgPiAwKSB7CiAgICAgIGZvciAoYmluID0gYm90dG9tOyBiaW4gPCBhYWNGcmFtZVNpemU7IGJpbis9MSkgewogICAgICAgIHBTcGVjdHJhbENvZWZmaWNpZW50W2Jpbl0gPj49IG1heF9leHBvbmVudDsKICAgICAgfQogICAgfQoKICAgIC8qIGFkanVzdCBzY2FsaW5nICovCiAgICBwU3BlY1NjYWxlWzBdICs9IG1heF9leHBvbmVudDsKCiAgICBpZiAod2luU2VxID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSkgewogICAgICBpbnQgd2luOwogICAgICBmb3IgKHdpbiA9IDE7IHdpbiA8IDg7IHdpbisrKSB7CiAgICAgICAgcFNwZWNTY2FsZVt3aW5dICs9IG1heF9leHBvbmVudDsKICAgICAgfQogICAgfQogIH0KICBlbHNlIHsKICAgIEhBTkRMRV9TQlJERUNPREVSIGhTYnJEZWNvZGVyID0gKEhBTkRMRV9TQlJERUNPREVSKXBTYnJEZWM7CiAgICBVSU5UIG51bUJhbmRzID0gcERyY0NoRGF0YS0+bnVtQmFuZHM7CgogICAgLyogZmVlZCBmYWN0b3JzIGludG8gU0JSIGRlY29kZXIgZm9yIGFwcGxpY2F0aW9uIGluIFFNRiBkb21haW4uICovCiAgICBzYnJEZWNvZGVyX2RyY0ZlZWRDaGFubmVsICgKICAgICAgICAgICAgaFNickRlY29kZXIsCiAgICAgICAgICAgIGNoLAogICAgICAgICAgICBudW1CYW5kcywKICAgICAgICAgICAgZmFjdF9tYW50aXNzYSwKICAgICAgICAgICAgbWF4X2V4cG9uZW50LAogICAgICAgICAgICBwRHJjQ2hEYXRhLT5kcmNJbnRlcnBvbGF0aW9uU2NoZW1lLAogICAgICAgICAgICB3aW5TZXEsCiAgICAgICAgICAgIHBEcmNDaERhdGEtPmJhbmRUb3AKICAgICAgICAgICk7CiAgfQoKICByZXR1cm47Cn0KCgovKiAKICogUHJlcGFyZSBEUkMgcHJvY2Vzc2luZwogKi8KaW50IGFhY0RlY29kZXJfZHJjUHJvbG9nICgKICAgICAgICBIQU5ETEVfQUFDX0RSQyAgc2VsZiwKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tdLAogICAgICAgIFVDSEFSICBwY2VJbnN0YW5jZVRhZywKICAgICAgICBVQ0hBUiAgY2hhbm5lbE1hcHBpbmdbXSwgLyogQ2hhbm5lbCBtYXBwaW5nIHRyYW5zbGF0aW5nIGRyY0NoYW5uZWwgaW5kZXggdG8gY2Fub25pY2FsIGNoYW5uZWwgaW5kZXggKi8KICAgICAgICBpbnQgICAgdmFsaWRDaGFubmVscyApCnsKICBpbnQgZXJyID0gMDsKCiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYgKCFzZWxmLT5wYXJhbXMuYnNEZWxheUVuYWJsZSkKICB7CiAgICBlcnIgPSBhYWNEZWNvZGVyX2RyY0V4dHJhY3RBbmRNYXAgKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoQnMsCiAgICAgICAgICAgIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8sCiAgICAgICAgICAgIHBjZUluc3RhbmNlVGFnLAogICAgICAgICAgICBjaGFubmVsTWFwcGluZywKICAgICAgICAgICAgdmFsaWRDaGFubmVscyApOwogIH0KCiAgcmV0dXJuIGVycjsKfQoKCi8qIAogKiBGaW5hbGl6ZSBEUkMgcHJvY2Vzc2luZwogKi8KaW50IGFhY0RlY29kZXJfZHJjRXBpbG9nICgKICAgICAgICBIQU5ETEVfQUFDX0RSQyAgc2VsZiwKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tdLAogICAgICAgIFVDSEFSICBwY2VJbnN0YW5jZVRhZywKICAgICAgICBVQ0hBUiAgY2hhbm5lbE1hcHBpbmdbXSwgLyogQ2hhbm5lbCBtYXBwaW5nIHRyYW5zbGF0aW5nIGRyY0NoYW5uZWwgaW5kZXggdG8gY2Fub25pY2FsIGNoYW5uZWwgaW5kZXggKi8KICAgICAgICBpbnQgICAgdmFsaWRDaGFubmVscyApCnsKICBpbnQgZXJyID0gMDsKCiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYgKHNlbGYtPnBhcmFtcy5ic0RlbGF5RW5hYmxlKQogIHsKICAgIGVyciA9IGFhY0RlY29kZXJfZHJjRXh0cmFjdEFuZE1hcCAoCiAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgcGNlSW5zdGFuY2VUYWcsCiAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLAogICAgICAgICAgICB2YWxpZENoYW5uZWxzICk7CiAgfQoKICByZXR1cm4gZXJyOwp9Cgo=