Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSAibWhfZGV0LmgiCgojaW5jbHVkZSAic2JyX3JhbS5oIgojaW5jbHVkZSAic2JyX21pc2MuaCIKCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCiNkZWZpbmUgU0ZNX1NISUZUIDIgICAgIC8qIEF0dGVudGlvbjogU0ZNX1NDQUxFIGRlcGVuZHMgb24gU0ZNX1NISUZUICovCiNkZWZpbmUgU0ZNX1NDQUxFIChNQVhWQUxfREJMID4+IFNGTV9TSElGVCkgICAvKiAxLjAgPj4gU0ZNX1NISUZUICovCgoKLyohPCBEZXRlY3RvciBQYXJhbWV0ZXJzIGZvciBBQUMgY29yZSBjb2RlYy4gKi8Kc3RhdGljIGNvbnN0IERFVEVDVE9SX1BBUkFNRVRFUlNfTUggcGFyYW1zQWFjID0gewo5LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgZGVsdGFUaW1lICovCnsKRkwyRlhDT05TVF9EQkwoMjAuMGYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmYgKi8KRkwyRlhDT05TVF9EQkwoMS4yNmYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmZHdWlkZSAqLwpGTDJGWENPTlNUX0RCTCgxNS4wZipSRUxBWEFUSU9OX0ZMT0FUKSwgICAgICAgIC8qITwgdGhyZXNIb2xkVG9uZSAqLwpGTDJGWENPTlNUX0RCTCgoMS4wZi8xNS4wZikqUkVMQVhBVElPTl9GTE9BVCksIC8qITwgaW52VGhyZXNIb2xkVG9uZSAqLwpGTDJGWENPTlNUX0RCTCgxLjI2ZipSRUxBWEFUSU9OX0ZMT0FUKSwgICAgICAgIC8qITwgdGhyZXNIb2xkVG9uZUd1aWRlICovCkZMMkZYQ09OU1RfREJMKDAuM2YpPj5TRk1fU0hJRlQsICAgICAgICAgICAgICAgLyohPCBzZm1UaHJlc1NiciAqLwpGTDJGWENPTlNUX0RCTCgwLjFmKT4+U0ZNX1NISUZULCAgICAgICAgICAgICAgIC8qITwgc2ZtVGhyZXNPcmlnICovCkZMMkZYQ09OU1RfREJMKDAuM2YpLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBkZWNheUd1aWRlT3JpZyAqLwpGTDJGWENPTlNUX0RCTCgwLjVmKSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgZGVjYXlHdWlkZURpZmYgKi8KRkwyRlhDT05TVF9EQkwoLTAuMDAwMTEyOTkzMjY5KSwgIC8qIExENjQoRkwyRlhDT05TVF9EQkwoMC45OTVmKSkgKi8gLyohPCBkZXJpdlRocmVzTWF4TEQ2NCAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAvKiE8IGRlcml2VGhyZXNCZWxvd0xENjQgKi8KRkwyRlhDT05TVF9EQkwoLTAuMDA1MDMwMTI2NDgzZikgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjhmKSkgKi8gICAgLyohPCBkZXJpdlRocmVzQWJvdmVMRDY0ICovCn0sCjUwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBtYXhDb21wICovCn07CgovKiE8IERldGVjdG9yIFBhcmFtZXRlcnMgZm9yIEFBQyBMRCBjb3JlIGNvZGVjLiAqLwpzdGF0aWMgY29uc3QgREVURUNUT1JfUEFSQU1FVEVSU19NSCBwYXJhbXNBYWNMZCA9IHsKMTYsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IERlbHRhIHRpbWUuICovCnsKRkwyRlhDT05TVF9EQkwoMjUuMGYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmYgKi8KRkwyRlhDT05TVF9EQkwoMS4yNmYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRyZXNIb2xkRGlmZkd1aWRlICovCkZMMkZYQ09OU1RfREJMKDE1LjBmKlJFTEFYQVRJT05fRkxPQVQpLCAgICAgICAgLyohPCB0aHJlc0hvbGRUb25lICovCkZMMkZYQ09OU1RfREJMKCgxLjBmLzE1LjBmKSpSRUxBWEFUSU9OX0ZMT0FUKSwgLyohPCBpbnZUaHJlc0hvbGRUb25lICovCkZMMkZYQ09OU1RfREJMKDEuMjZmKlJFTEFYQVRJT05fRkxPQVQpLCAgICAgICAgLyohPCB0aHJlc0hvbGRUb25lR3VpZGUgKi8KRkwyRlhDT05TVF9EQkwoMC4zZik+PlNGTV9TSElGVCwgICAgICAgICAgICAgICAvKiE8IHNmbVRocmVzU2JyICovCkZMMkZYQ09OU1RfREJMKDAuMWYpPj5TRk1fU0hJRlQsICAgICAgICAgICAgICAgLyohPCBzZm1UaHJlc09yaWcgKi8KRkwyRlhDT05TVF9EQkwoMC4zZiksICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IGRlY2F5R3VpZGVPcmlnICovCkZMMkZYQ09OU1RfREJMKDAuMmYpLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBkZWNheUd1aWRlRGlmZiAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAgLyohPCBkZXJpdlRocmVzTWF4TEQ2NCAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAgLyohPCBkZXJpdlRocmVzQmVsb3dMRDY0ICovCkZMMkZYQ09OU1RfREJMKC0wLjAwNTAzMDEyNjQ4M2YpIC8qIExENjQoRkwyRlhDT05TVF9EQkwoMC44ZikpICovICAgICAvKiE8IGRlcml2VGhyZXNBYm92ZUxENjQgKi8KfSwKNTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IG1heENvbXAgKi8KfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlcyB0aGUgZGlmZmVyZW5jZSBpbiB0b25hbGl0eSBiZXR3ZWVuIG9yaWdpbmFsIGFuZCBTQlIKICAgICAgICAgICAgIGZvciBhIGdpdmVuIHRpbWUgYW5kIGZyZXF1ZW5jeSByZWdpb24uCgogICAgICAgICAgICAgVGhlIHZhbHVlcyBmb3IgcERpZmZNYXBwZWQyU2NmYiBhcmUgc2NhbGVkIGJ5IFJFTEFYQVRJT04KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBkaWZmKEZJWFBfREJMICpSRVNUUklDVCBwVG9uYWxpdHlPcmlnLAogICAgICAgICAgICAgICAgIEZJWFBfREJMICpwRGlmZk1hcHBlZDJTY2ZiLAogICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICpSRVNUUklDVCBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICBJTlQgICAgICAgblNjZmIsCiAgICAgICAgICAgICAgICAgU0NIQVIgICAgKmluZGV4VmVjdG9yKQp7CiAgVUNIQVIgaSwgbGwsIGx1LCBrOwogIEZJWFBfREJMIG1heFZhbE9yaWcsIG1heFZhbFNiciwgdG1wOwogIElOVCBzY2FsZTsKCiAgZm9yKGk9MDsgaSA8IG5TY2ZiOyBpKyspewogICAgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIGx1ID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICBtYXhWYWxPcmlnID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICBtYXhWYWxTYnIgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKCiAgICBmb3Ioaz1sbDtrPGx1O2srKyl7CiAgICAgIG1heFZhbE9yaWcgPSBmaXhNYXgobWF4VmFsT3JpZywgcFRvbmFsaXR5T3JpZ1trXSk7CiAgICAgIG1heFZhbFNiciA9IGZpeE1heChtYXhWYWxTYnIsIHBUb25hbGl0eU9yaWdbaW5kZXhWZWN0b3Jba11dKTsKICAgIH0KCiAgICBpZiAoKG1heFZhbFNiciA+PSBSRUxBWEFUSU9OKSkgewogICAgICAgIHRtcCA9IGZEaXZOb3JtKG1heFZhbE9yaWcsIG1heFZhbFNiciwgJnNjYWxlKTsKICAgICAgICBwRGlmZk1hcHBlZDJTY2ZiW2ldID0gc2NhbGVWYWx1ZShmTXVsdCh0bXAsUkVMQVhBVElPTl9GUkFDVCksIGZpeE1heCgtKERGUkFDVF9CSVRTLTEpLChzY2FsZS1SRUxBWEFUSU9OX1NISUZUKSkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcERpZmZNYXBwZWQyU2NmYltpXSA9IG1heFZhbE9yaWc7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIENhbGN1bGF0ZXMgYSBmbGF0bmVzcyBtZWFzdXJlIG9mIHRoZSB0b25hbGl0eSBtZWFzdXJlcy4KCiAgQ2FsY3VsYXRpb24gb2YgdGhlIHBvd2VyIGZ1bmN0aW9uIGFuZCB1c2luZyBzY2FsZWZhY3RvciBmb3IgYmFzaXM6CiAgICBVc2luZyBsb2cyOgogICAgeiAgPSAoMl5rICogeCleeTsKICAgIHonID0gQ2FsY0xkKHopID0geSpDYWxjTGQoeCkgKyB5Kms7CiAgICB6ICA9IENhbGNJbnZMZCh6Jyk7CgogICAgVXNpbmcgbGQ2NDoKICAgIHogID0gKDJeayAqIHgpXnk7CiAgICB6JyA9IENhbGNMZDY0KHopID0geSpDYWxjTGQ2NCh4KS82NCArIHkqay82NDsKICAgIHogID0gQ2FsY0ludkxkNjQoeicpOwoKICBUaGUgdmFsdWVzIHBTZm1PcmlnVmVjIGFuZCBwU2ZtU2JyVmVjIGFyZSBzY2FsZWQgYnkgdGhlIGZhY3RvciAxLzQuMAoKICBccmV0dXJuICAgIG5vbmUuCgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIGNhbGN1bGF0ZUZsYXRuZXNzTWVhc3VyZShGSVhQX0RCTCAqcFF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgKmluZGV4VmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBTZm1PcmlnVmVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBTZm1TYnJWZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgblNmYikKewogIElOVCBpLGo7CiAgRklYUF9EQkwgaW52QmFuZHMsdG1wMSx0bXAyOwogIElOVCBzaGlmdEZhYzAsc2hpZnRGYWNTdW0wOwogIElOVCBzaGlmdEZhYzEsc2hpZnRGYWNTdW0xOwogIEZJWFBfREJMIGFjY3U7CgogIGZvcihpPTA7aTxuU2ZiO2krKykKICB7CiAgICBJTlQgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIElOVCBsdSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CiAgICBwU2ZtT3JpZ1ZlY1tpXSA9IChGSVhQX0RCTCkoTUFYVkFMX0RCTD4+Mik7CiAgICBwU2ZtU2JyVmVjW2ldICA9IChGSVhQX0RCTCkoTUFYVkFMX0RCTD4+Mik7CgogICAgaWYobHUgLSBsbCA+IDEpewogICAgICBGSVhQX0RCTCBhbU9yaWcsYW1UcmFuc3AsZ21PcmlnLGdtVHJhbnNwLHNmbU9yaWcsc2ZtVHJhbnNwOwogICAgICBpbnZCYW5kcyA9IEdldEludkludChsdS1sbCk7CiAgICAgIHNoaWZ0RmFjU3VtMCA9IDA7CiAgICAgIHNoaWZ0RmFjU3VtMSA9IDA7CiAgICAgIGFtT3JpZyA9IGFtVHJhbnNwID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgIGdtT3JpZyA9IGdtVHJhbnNwID0gKEZJWFBfREJMKU1BWFZBTF9EQkw7CgogICAgICBmb3Ioaj0gbGw7IGo8bHU7IGorKykgewogICAgICAgIHNmbU9yaWcgICA9IHBRdW90YUJ1ZmZlcltqXTsKICAgICAgICBzZm1UcmFuc3AgPSBwUXVvdGFCdWZmZXJbaW5kZXhWZWN0b3Jbal1dOwoKICAgICAgICBhbU9yaWcgICArPSBmTXVsdChzZm1PcmlnLCBpbnZCYW5kcyk7CiAgICAgICAgYW1UcmFuc3AgKz0gZk11bHQoc2ZtVHJhbnNwLCBpbnZCYW5kcyk7CgogICAgICAgIHNoaWZ0RmFjMCA9IENvdW50TGVhZGluZ0JpdHMoc2ZtT3JpZyk7CiAgICAgICAgc2hpZnRGYWMxID0gQ291bnRMZWFkaW5nQml0cyhzZm1UcmFuc3ApOwoKICAgICAgICBnbU9yaWcgICA9IGZNdWx0KGdtT3JpZywgc2ZtT3JpZzw8c2hpZnRGYWMwKTsKICAgICAgICBnbVRyYW5zcCA9IGZNdWx0KGdtVHJhbnNwLCBzZm1UcmFuc3A8PHNoaWZ0RmFjMSk7CgogICAgICAgIHNoaWZ0RmFjU3VtMCArPSBzaGlmdEZhYzA7CiAgICAgICAgc2hpZnRGYWNTdW0xICs9IHNoaWZ0RmFjMTsKICAgICAgfQoKICAgICAgaWYgKGdtT3JpZyA+IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CgogICAgICAgIHRtcDEgPSBDYWxjTGREYXRhKGdtT3JpZyk7ICAgICAgLyogQ2FsY0xkNjQoeCkvNjQgKi8KICAgICAgICB0bXAxID0gZk11bHQoaW52QmFuZHMsIHRtcDEpOyAgIC8qIHkqQ2FsY0xkNjQoeCkvNjQgKi8KCiAgICAgICAgLyogeSprLzY0ICovCiAgICAgICAgYWNjdSA9IChGSVhQX0RCTCktc2hpZnRGYWNTdW0wIDw8IChERlJBQ1RfQklUUy0xLTgpOwogICAgICAgIHRtcDIgPSBmTXVsdERpdjIoaW52QmFuZHMsIGFjY3UpIDw8ICgyKzEpOwoKICAgICAgICB0bXAyID0gdG1wMSArIHRtcDI7ICAgICAgICAgICAgIC8qIHkqQ2FsY0xkNjQoeCkvNjQgKyB5KmsvNjQgKi8KICAgICAgICBnbU9yaWcgPSBDYWxjSW52TGREYXRhKHRtcDIpOyAgIC8qIENhbGNJbnZMZDY0KHonKTsgKi8KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBnbU9yaWcgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgfQoKICAgICAgaWYgKGdtVHJhbnNwID4gRkwyRlhDT05TVF9EQkwoMC4wZikpIHsKCiAgICAgICAgdG1wMSA9IENhbGNMZERhdGEoZ21UcmFuc3ApOyAgICAvKiBDYWxjTGQ2NCh4KS82NCAqLwogICAgICAgIHRtcDEgPSBmTXVsdChpbnZCYW5kcywgdG1wMSk7ICAgLyogeSpDYWxjTGQ2NCh4KS82NCAqLwoKICAgICAgICAvKiB5KmsvNjQgKi8KICAgICAgICBhY2N1ID0gKEZJWFBfREJMKS1zaGlmdEZhY1N1bTEgPDwgKERGUkFDVF9CSVRTLTEtOCk7CiAgICAgICAgdG1wMiA9IGZNdWx0RGl2MihpbnZCYW5kcywgYWNjdSkgPDwgKDIrMSk7CgogICAgICAgIHRtcDIgPSB0bXAxICsgdG1wMjsgICAgICAgICAgICAgLyogeSpDYWxjTGQ2NCh4KS82NCArIHkqay82NCAqLwogICAgICAgIGdtVHJhbnNwID0gQ2FsY0ludkxkRGF0YSh0bXAyKTsgLyogQ2FsY0ludkxkNjQoeicpOyAqLwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIGdtVHJhbnNwID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgIH0KICAgICAgaWYgKCBhbU9yaWcgIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgKQogICAgICAgIHBTZm1PcmlnVmVjW2ldID0gRkRLc2JyRW5jX0xTSV9kaXZpZGVfc2NhbGVfZnJhY3QoZ21PcmlnLGFtT3JpZyxTRk1fU0NBTEUpOwoKICAgICAgaWYgKCBhbVRyYW5zcCAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSApCiAgICAgICAgcFNmbVNiclZlY1tpXSA9IEZES3NickVuY19MU0lfZGl2aWRlX3NjYWxlX2ZyYWN0KGdtVHJhbnNwLGFtVHJhbnNwLFNGTV9TQ0FMRSk7CiAgICB9CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlcyB0aGUgaW5wdXQgdG8gdGhlIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdGlvbi4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgY2FsY3VsYXRlRGV0ZWN0b3JJbnB1dChGSVhQX0RCTCAqKlJFU1RSSUNUIHBRdW90YUJ1ZmZlciwgIC8qITwgUG9pbnRlciB0byB0b25hbGl0eSBtYXRyaXguICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgICpSRVNUUklDVCBpbmRleFZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKlJFU1RSSUNUIHRvbmFsaXR5RGlmZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKlJFU1RSSUNUIHBTZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICoqUkVTVFJJQ1QgcFNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbW92ZSkKewogIElOVCBlc3Q7CgogIC8qCiAgTmV3IGVzdGltYXRlLgogICovCiAgZm9yIChlc3Q9MDsgZXN0IDwgbm9Fc3RQZXJGcmFtZTsgZXN0KyspIHsKCiAgICBkaWZmKHBRdW90YUJ1ZmZlcltlc3QrbW92ZV0sCiAgICAgICAgIHRvbmFsaXR5RGlmZltlc3QrbW92ZV0sCiAgICAgICAgIGZyZXFCYW5kVGFibGUsCiAgICAgICAgIG5TZmIsCiAgICAgICAgIGluZGV4VmVjdG9yKTsKCiAgICBjYWxjdWxhdGVGbGF0bmVzc01lYXN1cmUocFF1b3RhQnVmZmVyW2VzdCsgbW92ZV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmbU9yaWdbZXN0ICsgbW92ZV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmbVNicltlc3QgKyBtb3ZlXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmIpOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDaGVja3MgdGhhdCB0aGUgZGV0ZWN0aW9uIGlzIG5vdCBkdWUgdG8gYSBMUCBmaWx0ZXIKCiAgVGhpcyBmdW5jdGlvbiBkZXRlcm1pbmVzIGlmIGEgbmV3bHkgZGV0ZWN0ZWQgbWlzc2luZyBoYXJtb25pY3MgaXMgbm90CiAgaW4gZmFjdCBqdXN0IGEgbG93LXBhc3MgZmlsdGVyZSBpbnB1dCBzaWduYWwuIElmIHNvLCB0aGUgZGV0ZWN0aW9uIGlzCiAgcmVtb3ZlZC4KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCByZW1vdmVMb3dQYXNzRGV0ZWN0aW9uKFVDSEFSICpSRVNUUklDVCBwQWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqKlJFU1RSSUNUIHBEZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc3RvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqUkVTVFJJQ1QgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEhSRVNfSE9MRFMgbWhUaHJlc2gpCgp7CiAgSU5UIGksZXN0OwogIElOVCBtYXhEZXJpdlBvcyA9IHBGcmVxQmFuZFRhYmxlW25TZmJdOwogIElOVCBudW1CYW5kcyA9IHBGcmVxQmFuZFRhYmxlW25TZmJdOwogIEZJWFBfREJMIG5yZ0xvdyxucmdIaWdoOwogIEZJWFBfREJMIG5yZ0xENjQsbnJnTG93TEQ2NCxucmdIaWdoTEQ2NCxucmdEaWZmTEQ2NDsKICBGSVhQX0RCTCB2YWxMRDY0LG1heFZhbExENjQsbWF4VmFsQWJvdmVMRDY0OwogIElOVCBiTFBzaWduYWwgPSAwOwoKICBtYXhWYWxMRDY0ID0gRkwyRlhDT05TVF9EQkwoLTEuMGYpOwogIGZvcihpID0gbnVtQmFuZHMgLSAxIC0gMjsgaSA+IHBGcmVxQmFuZFRhYmxlWzBdO2ktLSl7CiAgICBucmdMb3cgID0gcE5yZ1ZlY3RvcltpXTsKICAgIG5yZ0hpZ2ggPSBwTnJnVmVjdG9yW2kgKyAyXTsKCiAgICBpZihucmdMb3cgIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgJiYgbnJnTG93ID4gbnJnSGlnaCl7CiAgICAgIG5yZ0xvd0xENjQgPSBDYWxjTGREYXRhKG5yZ0xvdz4+MSk7CiAgICAgIG5yZ0RpZmZMRDY0ID0gQ2FsY0xkRGF0YSgobnJnTG93Pj4xKS0obnJnSGlnaD4+MSkpOwogICAgICB2YWxMRDY0ID0gbnJnRGlmZkxENjQtbnJnTG93TEQ2NDsKICAgICAgaWYodmFsTEQ2NCA+IG1heFZhbExENjQpewogICAgICAgIG1heERlcml2UG9zID0gaTsKICAgICAgICBtYXhWYWxMRDY0ID0gdmFsTEQ2NDsKICAgICAgfQogICAgICBpZihtYXhWYWxMRDY0ID4gbWhUaHJlc2guZGVyaXZUaHJlc01heExENjQpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgLyogRmluZCB0aGUgbGFyZ2VzdCAiZ3JhZGllbnQiIGFib3ZlLiAoc2hvdWxkIGJlIHJlbGF0aXZlbHkgZmxhdCwgaGVuY2Ugd2UgZXhwZWN0IGEgbG93IHZhbHVlCiAgICAgaWYgdGhlIHNpZ25hbCBpcyBMUC4qLwogIG1heFZhbEFib3ZlTEQ2NCA9IEZMMkZYQ09OU1RfREJMKC0xLjBmKTsKICBmb3IoaSA9IG51bUJhbmRzIC0gMSAtIDI7IGkgPiBtYXhEZXJpdlBvcyArIDI7aS0tKXsKICAgIG5yZ0xvdyAgPSBwTnJnVmVjdG9yW2ldOwogICAgbnJnSGlnaCA9IHBOcmdWZWN0b3JbaSArIDJdOwoKICAgIGlmKG5yZ0xvdyAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSAmJiBucmdMb3cgPiBucmdIaWdoKXsKCQkgICBucmdMb3dMRDY0ID0gQ2FsY0xkRGF0YShucmdMb3c+PjEpOwoJCSAgIG5yZ0RpZmZMRDY0ID0gQ2FsY0xkRGF0YSgobnJnTG93Pj4xKS0obnJnSGlnaD4+MSkpOwoJCQkgdmFsTEQ2NCA9IG5yZ0RpZmZMRDY0LW5yZ0xvd0xENjQ7CiAgICAgIGlmKHZhbExENjQgPiBtYXhWYWxBYm92ZUxENjQpewogICAgICAgIG1heFZhbEFib3ZlTEQ2NCA9IHZhbExENjQ7CiAgICAgIH0KICAgIH0KCQkgZWxzZSB7CiAgICAgIGlmKG5yZ0hpZ2ggIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgJiYgbnJnSGlnaCA+IG5yZ0xvdyl7CgkJICAgICBucmdIaWdoTEQ2NCA9IENhbGNMZERhdGEobnJnSGlnaD4+MSk7CgkJICAgICBucmdEaWZmTEQ2NCA9IENhbGNMZERhdGEoKG5yZ0hpZ2g+PjEpLShucmdMb3c+PjEpKTsKCQkJICAgdmFsTEQ2NCA9IG5yZ0RpZmZMRDY0LW5yZ0hpZ2hMRDY0OwogICAgICAgIGlmKHZhbExENjQgPiBtYXhWYWxBYm92ZUxENjQpewogICAgICAgICAgbWF4VmFsQWJvdmVMRDY0ID0gdmFsTEQ2NDsKICAgICAgICB9CiAgICAgIH0KCQkgfQogIH0KCiAgaWYobWF4VmFsTEQ2NCA+IG1oVGhyZXNoLmRlcml2VGhyZXNNYXhMRDY0ICYmIG1heFZhbEFib3ZlTEQ2NCA8IG1oVGhyZXNoLmRlcml2VGhyZXNBYm92ZUxENjQpewogICAgYkxQc2lnbmFsID0gMTsKCiAgICBmb3IoaSA9IG1heERlcml2UG9zIC0gMTsgaSA+IG1heERlcml2UG9zIC0gNSAmJiBpID49IDAgOyBpLS0pewogICAgICBpZihwTnJnVmVjdG9yW2ldICE9IEZMMkZYQ09OU1RfREJMKDAuMGYpICYmIHBOcmdWZWN0b3JbaV0gPiBwTnJnVmVjdG9yW21heERlcml2UG9zICsgMl0pewoJCSAgICAgbnJnRGlmZkxENjQgPSBDYWxjTGREYXRhKChwTnJnVmVjdG9yW2ldPj4xKS0ocE5yZ1ZlY3RvclttYXhEZXJpdlBvcyArIDJdPj4xKSk7CgkJCQkgbnJnTEQ2NCA9IENhbGNMZERhdGEocE5yZ1ZlY3RvcltpXT4+MSk7CiAgCQkJIHZhbExENjQgPSBucmdEaWZmTEQ2NC1ucmdMRDY0OwogICAgICAgIGlmKHZhbExENjQgPCBtaFRocmVzaC5kZXJpdlRocmVzQmVsb3dMRDY0KSB7CiAgICAgICAgICBiTFBzaWduYWwgPSAwOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2V7CiAgICAgICAgYkxQc2lnbmFsID0gMDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgaWYoYkxQc2lnbmFsKXsKICAgIGZvcihpPTA7aTxuU2ZiO2krKyl7CiAgICAgIGlmKG1heERlcml2UG9zID49IHBGcmVxQmFuZFRhYmxlW2ldICYmIG1heERlcml2UG9zIDwgcEZyZXFCYW5kVGFibGVbaSsxXSkKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZihwQWRkSGFybVNmYltpXSl7CiAgICAgIHBBZGRIYXJtU2ZiW2ldID0gMDsKICAgICAgZm9yKGVzdCA9IHN0YXJ0OyBlc3QgPCBzdG9wIDsgZXN0KyspewogICAgICAgIHBEZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICB9CiAgICB9CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2hlY2tzIGlmIGl0IGlzIGFsbG93ZWQgdG8gZGV0ZWN0IGEgbWlzc2luZyB0b25lLCB0aGF0IHdhc24ndAogICAgICAgICAgICAgZGV0ZWN0ZWQgcHJldmlvdXNseS4KCgogIFxyZXR1cm4gICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCBmbGFnLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UIGlzRGV0ZWN0aW9uT2ZOZXdUb25lQWxsb3dlZChjb25zdCBTQlJfRlJBTUVfSU5GTyAqcEZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpwRGV0ZWN0aW9uU3RhcnRQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcHJldlRyYW5zaWVudEZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcHJldlRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHByZXZUcmFuc2llbnRGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdHJhbnNpZW50UG9zT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdHJhbnNpZW50RmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGRlbHRhVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvcikKewogIElOVCB0cmFuc2llbnRGcmFtZSwgbmV3RGV0ZWN0aW9uQWxsb3dlZDsKCgogIC8qIERldGVybWluZSBpZiB0aGlzIGlzIGEgZnJhbWUgd2hlcmUgYSB0cmFuc2llbnQgc3RhcnRzLi4uCiAgICogSWYgdGhlIHRyYW5zaWVudCBmbGFnIHdhcyBzZXQgdGhlIHByZXZpb3VzIGZyYW1lIGJ1dCBub3QgdGhlCiAgICogdHJhbnNpZW50IGZyYW1lIGZsYWcsIHRoZSB0cmFuc2llbnQgZnJhbWUgZmxhZyBpcyBzZXQgaW4gdGhlIGN1cnJlbnQgZnJhbWUuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogIHRyYW5zaWVudEZyYW1lID0gMDsKICBpZih0cmFuc2llbnRGbGFnKXsKICAgIGlmKHRyYW5zaWVudFBvcyArIHRyYW5zaWVudFBvc09mZnNldCA8IHBGcmFtZUluZm8tPmJvcmRlcnNbcEZyYW1lSW5mby0+bkVudmVsb3Blc10pCiAgICAgIHRyYW5zaWVudEZyYW1lID0gMTsKICAgICAgaWYobm9Fc3RQZXJGcmFtZSA+IDEpewogICAgICAgIGlmKHRyYW5zaWVudFBvcyArIHRyYW5zaWVudFBvc09mZnNldCA+IGhfc2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT50aW1lU2xvdHMgPj4gMSl7CiAgICAgICAgICAqcERldGVjdGlvblN0YXJ0UG9zID0gbm9Fc3RQZXJGcmFtZTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICpwRGV0ZWN0aW9uU3RhcnRQb3MgPSBub0VzdFBlckZyYW1lID4+IDE7CiAgICAgICAgfQoKICAgICAgfQogICAgICBlbHNlewogICAgICAgICpwRGV0ZWN0aW9uU3RhcnRQb3MgPSBub0VzdFBlckZyYW1lOwogICAgICB9CiAgfQogIGVsc2V7CiAgICBpZihwcmV2VHJhbnNpZW50RmxhZyAmJiAhcHJldlRyYW5zaWVudEZyYW1lKXsKICAgICAgdHJhbnNpZW50RnJhbWUgPSAxOwogICAgICAqcERldGVjdGlvblN0YXJ0UG9zID0gMDsKICAgIH0KICB9CgogIC8qCiAgICogRGV0ZXJtaW5lIGlmIGRldGVjdGlvbiBvZiBuZXcgbWlzc2luZyBoYXJtb25pY3MgYXJlIGFsbG93ZWQuCiAgICogSWYgdGhlIGZyYW1lIGNvbnRhaW5zIGEgdHJhbnNpZW50IGl0J3Mgb2suIElmIHRoZSBwcmV2aW91cwogICAqIGZyYW1lIGNvbnRhaW5lZCBhIHRyYW5zaWVudCBpdCBuZWVkcyB0byBiZSBzdWZmaWNpZW50bHkgY2xvc2UKICAgKiB0byB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgZnJhbWUuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgbmV3RGV0ZWN0aW9uQWxsb3dlZCA9IDA7CiAgaWYodHJhbnNpZW50RnJhbWUpewogICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCA9IDE7CiAgfQogIGVsc2UgewogICAgaWYocHJldlRyYW5zaWVudEZyYW1lICYmCiAgICAgICBmaXhwX2FicyhwRnJhbWVJbmZvLT5ib3JkZXJzWzBdIC0gKHByZXZUcmFuc2llbnRQb3MgKyB0cmFuc2llbnRQb3NPZmZzZXQgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnRpbWVTbG90cykpIDwgZGVsdGFUaW1lKQogICAgICBuZXdEZXRlY3Rpb25BbGxvd2VkID0gMTsKICAgICAgKnBEZXRlY3Rpb25TdGFydFBvcyA9IDA7CiAgfQoKICBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldmlvdXNUcmFuc2llbnRGbGFnICA9IHRyYW5zaWVudEZsYWc7CiAgaF9zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnByZXZpb3VzVHJhbnNpZW50RnJhbWUgPSB0cmFuc2llbnRGcmFtZTsKICBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldmlvdXNUcmFuc2llbnRQb3MgICA9IHRyYW5zaWVudFBvczsKCiAgcmV0dXJuIChuZXdEZXRlY3Rpb25BbGxvd2VkKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDbGVhbnMgdXAgdGhlIGRldGVjdGlvbiBhZnRlciBhIHRyYW5zaWVudC4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgdHJhbnNpZW50Q2xlYW5VcChGSVhQX0RCTCAqKnF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICoqZGV0ZWN0aW9uVmVjdG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqcEFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBQcmV2QWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKiogc2lnbkJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuZXdEZXRlY3Rpb25BbGxvd2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpwTnJnVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRIUkVTX0hPTERTIG1oVGhyZXNoKQp7CiAgSU5UIGksaixsaSwgdWksZXN0OwoKICBmb3IoZXN0PXN0YXJ0OyBlc3QgPCBzdG9wOyBlc3QrKykgewogICAgZm9yKGk9MDsgaTxuU2ZiOyBpKyspIHsKICAgICAgcEFkZEhhcm1TZmJbaV0gPSBwQWRkSGFybVNmYltpXSB8fCBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV07CiAgICB9CiAgfQoKICBpZihuZXdEZXRlY3Rpb25BbGxvd2VkID09IDEpewogICAgLyoKICAgICAqIENoZWNrIGZvciBkdXBsaWNhdGlvbiBvZiBzaW5lcyBsb2NhdGVkCiAgICAgKiBvbiB0aGUgYm9yZGVyIG9mIHR3byBzY2YtYmFuZHMuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGZvcihpPTA7aTxuU2ZiLTE7aSsrKSB7CiAgICAgIGxpID0gcEZyZXFCYW5kVGFibGVbaV07CiAgICAgIHVpID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICAgIC8qIGRldGVjdGlvbiBpbiBhZGphY2VudCBjaGFubmVscy4qLwogICAgICBpZihwQWRkSGFybVNmYltpXSAmJiBwQWRkSGFybVNmYltpKzFdKSB7CiAgICAgICAgRklYUF9EQkwgbWF4VmFsMSwgbWF4VmFsMjsKICAgICAgICBJTlQgbWF4UG9zMSwgbWF4UG9zMiwgbWF4UG9zVGltZTEsIG1heFBvc1RpbWUyOwoKICAgICAgICBsaSA9IHBGcmVxQmFuZFRhYmxlW2ldOwogICAgICAgIHVpID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICAgICAgLyogRmluZCBtYXhpbXVtIHRvbmFsaXR5IGluIHRoZSB0aGUgdHdvIHNjZiBiYW5kcy4qLwogICAgICAgIG1heFBvc1RpbWUxID0gc3RhcnQ7CiAgICAgICAgbWF4UG9zMSA9IGxpOwogICAgICAgIG1heFZhbDEgPSBxdW90YUJ1ZmZlcltzdGFydF1bbGldOwogICAgICAgIGZvcihlc3QgPSBzdGFydDsgZXN0IDwgc3RvcDsgZXN0KyspewogICAgICAgICAgZm9yKGogPSBsaTsgajx1aTsgaisrKXsKICAgICAgICAgICAgaWYocXVvdGFCdWZmZXJbZXN0XVtqXSA+IG1heFZhbDEpewogICAgICAgICAgICAgIG1heFZhbDEgPSBxdW90YUJ1ZmZlcltlc3RdW2pdOwogICAgICAgICAgICAgIG1heFBvczEgPSBqOwogICAgICAgICAgICAgIG1heFBvc1RpbWUxID0gZXN0OwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsaSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CiAgICAgICAgdWkgPSBwRnJlcUJhbmRUYWJsZVtpKzJdOwoKICAgICAgICAvKiBGaW5kIG1heGltdW0gdG9uYWxpdHkgaW4gdGhlIHRoZSB0d28gc2NmIGJhbmRzLiovCiAgICAgICAgbWF4UG9zVGltZTIgPSBzdGFydDsKICAgICAgICBtYXhQb3MyID0gbGk7CiAgICAgICAgbWF4VmFsMiA9IHF1b3RhQnVmZmVyW3N0YXJ0XVtsaV07CiAgICAgICAgZm9yKGVzdCA9IHN0YXJ0OyBlc3QgPCBzdG9wOyBlc3QrKyl7CiAgICAgICAgICBmb3IoaiA9IGxpOyBqPHVpOyBqKyspewogICAgICAgICAgICBpZihxdW90YUJ1ZmZlcltlc3RdW2pdID4gbWF4VmFsMil7CiAgICAgICAgICAgICAgbWF4VmFsMiA9IHF1b3RhQnVmZmVyW2VzdF1bal07CiAgICAgICAgICAgICAgbWF4UG9zMiA9IGo7CiAgICAgICAgICAgICAgbWF4UG9zVGltZTIgPSBlc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIElmIHRoZSBtYXhpbXVtIHZhbHVlcyBhcmUgaW4gYWRqYWNlbnQgUU1GLWNoYW5uZWxzLCB3ZSBuZWVkIHRvIHJlbW92ZQogICAgICAgICAgIHRoZSBsb3dlc3Qgb2YgdGhlIHR3by4qLwogICAgICAgIGlmKG1heFBvczItbWF4UG9zMSA8IDIpewoKICAgICAgICAgIGlmKHBQcmV2QWRkSGFybVNmYltpXSA9PSAxICYmIHBQcmV2QWRkSGFybVNmYltpKzFdID09IDApewogICAgICAgICAgICAvKiBLZWVwIHRoZSBsb3dlciwgcmVtb3ZlIHRoZSB1cHBlci4qLwogICAgICAgICAgICBwQWRkSGFybVNmYltpKzFdID0gMDsKICAgICAgICAgICAgZm9yKGVzdD1zdGFydDsgZXN0PHN0b3A7IGVzdCsrKXsKICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baSsxXSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgIGlmKHBQcmV2QWRkSGFybVNmYltpXSA9PSAwICYmIHBQcmV2QWRkSGFybVNmYltpKzFdID09IDEpewogICAgICAgICAgICAgIC8qIEtlZXAgdGhlIHVwcGVyLCByZW1vdmUgdGhlIGxvd2VyLiovCiAgICAgICAgICAgICAgcEFkZEhhcm1TZmJbaV0gPSAwOwogICAgICAgICAgICAgIGZvcihlc3Q9c3RhcnQ7IGVzdDxzdG9wOyBlc3QrKyl7CiAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgLyogSWYgdGhlIG1heGltdW0gdmFsdWVzIGFyZSBpbiBhZGphY2VudCBRTUYtY2hhbm5lbHMsIGFuZCBpZiB0aGUgc2lnbnMgaW5kaWNhdGUgdGhhdCBpdCBpcyB0aGUgc2FtZSBzaW5lLAogICAgICAgICAgICAgICAgd2UgbmVlZCB0byByZW1vdmUgdGhlIGxvd2VzdCBvZiB0aGUgdHdvLiovCiAgICAgICAgICAgICAgaWYobWF4VmFsMSA+IG1heFZhbDIpewogICAgICAgICAgICAgICAgaWYoc2lnbkJ1ZmZlclttYXhQb3NUaW1lMV1bbWF4UG9zMl0gPCAwICYmIHNpZ25CdWZmZXJbbWF4UG9zVGltZTFdW21heFBvczFdID4gMCl7CiAgICAgICAgICAgICAgICAgIC8qIEtlZXAgdGhlIGxvd2VyLCByZW1vdmUgdGhlIHVwcGVyLiovCiAgICAgICAgICAgICAgICAgIHBBZGRIYXJtU2ZiW2krMV0gPSAwOwogICAgICAgICAgICAgICAgICBmb3IoZXN0PXN0YXJ0OyBlc3Q8c3RvcDsgZXN0KyspewogICAgICAgICAgICAgICAgICAgIGRldGVjdGlvblZlY3RvcnNbZXN0XVtpKzFdID0gMDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgaWYoc2lnbkJ1ZmZlclttYXhQb3NUaW1lMl1bbWF4UG9zMl0gPCAwICYmIHNpZ25CdWZmZXJbbWF4UG9zVGltZTJdW21heFBvczFdID4gMCl7CiAgICAgICAgICAgICAgICAgIC8qIEtlZXAgdGhlIHVwcGVyLCByZW1vdmUgdGhlIGxvd2VyLiovCiAgICAgICAgICAgICAgICAgIHBBZGRIYXJtU2ZiW2ldID0gMDsKICAgICAgICAgICAgICAgICAgZm9yKGVzdD1zdGFydDsgZXN0PHN0b3A7IGVzdCsrKXsKICAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIGRldGVjdGlvbiBpcyBub3QgdGhlIGN1dC1vZmYgb2YgYSBsb3cgcGFzcyBmaWx0ZXIuICovCiAgICByZW1vdmVMb3dQYXNzRGV0ZWN0aW9uKHBBZGRIYXJtU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1oVGhyZXNoKTsKICB9CiAgZWxzZSB7CiAgIC8qCiAgICAqIElmIGEgbWlzc2luZyBoYXJtb25pYyB3YXNuJ3QgbWlzc2luZyB0aGUgcHJldmlvdXMgZnJhbWUKICAgICogdGhlIHRyYW5zaWVudC1mbGFnIG5lZWRzIHRvIGJlIHNldCBpbiBvcmRlciB0byBiZSBhbGxvd2VkIHRvIGRldGVjdCBpdC4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBmb3IoaT0wO2k8blNmYjtpKyspewogICAgICBpZihwQWRkSGFybVNmYltpXSAtIHBQcmV2QWRkSGFybVNmYltpXSA+IDApCiAgICAgICAgcEFkZEhhcm1TZmJbaV0gPSAwOwogICAgfQogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBEbyBkZXRlY3Rpb24gZm9yIG9uZSB0b25hbGl0eSBlc3RpbWF0ZS4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgZGV0ZWN0aW9uKEZJWFBfREJMICpxdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpwRGlmZlZlY1NjZmIsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICpwSGFybVZlYywKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICpwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgIEdVSURFX1ZFQ1RPUlMgZ3VpZGVWZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgR1VJREVfVkVDVE9SUyBuZXdHdWlkZVZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICAgICBUSFJFU19IT0xEUyBtaFRocmVzaCkKewoKICBJTlQgaSxqLGxsLCBsdTsKICBGSVhQX0RCTCB0aHJlc1RlbXAsdGhyZXNPcmlnOwoKICAvKgogICAqIERvIGRldGVjdGlvbiBvbiB0aGUgZGlmZmVyZW5jZSB2ZWN0b3IsIGkuZS4gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbgogICAqIHRoZSBvcmlnaW5hbCBhbmQgdGhlIHRyYW5zcG9zZWQuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICBmb3IoaT0wO2k8blNmYjtpKyspewoKICAgIHRocmVzVGVtcCA9IChndWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JEaWZmW2ldICE9IEZMMkZYQ09OU1RfREJMKDAuMGYpKQogICAgICAgICAgICAgICAgICA/IGZpeE1heChmTXVsdChtaFRocmVzaC5kZWNheUd1aWRlRGlmZixndWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JEaWZmW2ldKSwgbWhUaHJlc2gudGhyZXNIb2xkRGlmZkd1aWRlKQogICAgICAgICAgICAgICAgICA6IG1oVGhyZXNoLnRocmVzSG9sZERpZmY7CgogICAgdGhyZXNUZW1wID0gZml4TWluKHRocmVzVGVtcCwgbWhUaHJlc2gudGhyZXNIb2xkRGlmZik7CgogICAgaWYocERpZmZWZWNTY2ZiW2ldID4gdGhyZXNUZW1wKXsKICAgICAgcEhhcm1WZWNbaV0gPSAxOwogICAgICBuZXdHdWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JEaWZmW2ldID0gcERpZmZWZWNTY2ZiW2ldOwogICAgfQogICAgZWxzZXsKICAgICAgLyogSWYgdGhlIGd1aWRlIHdhc24ndCB6ZXJvLCBidXQgdGhlIGN1cnJlbnQgbGV2ZWwgaXMgdG8gbG93LAogICAgICAgICBzdGFydCB0cmFja2luZyB0aGUgZGVjYXkgb24gdGhlIHRvbmUgaW4gdGhlIG9yaWdpbmFsIHJhdGhlcgogICAgICAgICB0aGFuIHRoZSBkaWZmZXJlbmNlLiovCiAgICAgIGlmKGd1aWRlVmVjdG9ycy5ndWlkZVZlY3RvckRpZmZbaV0gIT0gRkwyRlhDT05TVF9EQkwoMC4wZikpewogICAgICAgIGd1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gPSBtaFRocmVzaC50aHJlc0hvbGRUb25lR3VpZGU7CiAgICAgIH0KICAgIH0KICB9CgogIC8qCiAgICogVHJhY2UgdG9uZXMgaW4gdGhlIG9yaWdpbmFsIHNpZ25hbCB0aGF0IGF0IG9uZSBwb2ludAogICAqIGhhdmUgYmVlbiBkZXRlY3RlZCBiZWNhdXNlIHRoZXkgd2lsbCBiZSByZXBsYWNlZCBieQogICAqIG11bHRpcGxlIHRvbmVzIGluIHRoZSBzYnIgc2lnbmFsLgogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICBmb3IoaT0wO2k8blNmYjtpKyspewogICAgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIGx1ID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICB0aHJlc09yaWcgPSBmaXhNYXgoZk11bHQoZ3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSwgbWhUaHJlc2guZGVjYXlHdWlkZU9yaWcpLCBtaFRocmVzaC50aHJlc0hvbGRUb25lR3VpZGUpOwogICAgdGhyZXNPcmlnID0gZml4TWluKHRocmVzT3JpZywgbWhUaHJlc2gudGhyZXNIb2xkVG9uZSk7CgogICAgaWYoZ3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSl7CiAgICAgIGZvcihqPSBsbDtqPGx1O2orKyl7CiAgICAgICAgaWYocXVvdGFCdWZmZXJbal0gPiB0aHJlc09yaWcpewogICAgICAgICAgcEhhcm1WZWNbaV0gPSAxOwogICAgICAgICAgbmV3R3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IHF1b3RhQnVmZmVyW2pdOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgLyoKICAgKiBDaGVjayBmb3IgbXVsdGlwbGUgc2luZXMgaW4gdGhlIHRyYW5zcG9zZWQgc2lnbmFsLAogICAqIHdoZXJlIHRoZXJlIGlzIG9ubHkgb25lIGluIHRoZSBvcmlnaW5hbC4KICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICB0aHJlc09yaWcgPSBtaFRocmVzaC50aHJlc0hvbGRUb25lOwoKICBmb3IoaT0wO2k8blNmYjtpKyspewogICAgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIGx1ID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICBpZihwSGFybVZlY1tpXSA9PSAwKXsKICAgICAgaWYobHUgLWxsID4gMSl7CiAgICAgICAgZm9yKGo9IGxsO2o8bHU7aisrKXsKICAgICAgICAgIGlmKHF1b3RhQnVmZmVyW2pdID4gdGhyZXNPcmlnICYmIChzZm1TYnJbaV0gPiBtaFRocmVzaC5zZm1UaHJlc1NiciAmJiBzZm1PcmlnW2ldIDwgbWhUaHJlc2guc2ZtVGhyZXNPcmlnKSl7CiAgICAgICAgICAgIHBIYXJtVmVjW2ldID0gMTsKICAgICAgICAgICAgbmV3R3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IHF1b3RhQnVmZmVyW2pdOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlewogICAgICAgIGlmKGkgPCBuU2ZiIC0xKXsKICAgICAgICAgIGxsID0gcEZyZXFCYW5kVGFibGVbaV07CgogICAgICAgICAgaWYoaT4wKXsKICAgICAgICAgICAgaWYocXVvdGFCdWZmZXJbbGxdID4gbWhUaHJlc2gudGhyZXNIb2xkVG9uZSAmJiAocERpZmZWZWNTY2ZiW2krMV0gPCBtaFRocmVzaC5pbnZUaHJlc0hvbGRUb25lIHx8IHBEaWZmVmVjU2NmYltpLTFdIDwgbWhUaHJlc2guaW52VGhyZXNIb2xkVG9uZSkpewogICAgICAgICAgICAgICAgcEhhcm1WZWNbaV0gPSAxOwogICAgICAgICAgICAgICAgbmV3R3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IHF1b3RhQnVmZmVyW2xsXTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgZWxzZXsKICAgICAgICAgICAgaWYocXVvdGFCdWZmZXJbbGxdID4gbWhUaHJlc2gudGhyZXNIb2xkVG9uZSAmJiBwRGlmZlZlY1NjZmJbaSsxXSA8IG1oVGhyZXNoLmludlRocmVzSG9sZFRvbmUpewogICAgICAgICAgICAgICAgcEhhcm1WZWNbaV0gPSAxOwogICAgICAgICAgICAgICAgbmV3R3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IHF1b3RhQnVmZmVyW2xsXTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBEbyBkZXRlY3Rpb24gZm9yIGV2ZXJ5IHRvbmFsaXR5IGVzdGltYXRlLCB1c2luZyBmb3J3YXJkIHByZWRpY3Rpb24uCgoKICBccmV0dXJuICAgIG5vbmUuCgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIGRldGVjdGlvbldpdGhQcmVkaWN0aW9uKEZJWFBfREJMICoqcXVvdGFCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICoqcERpZmZWZWNTY2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKiogc2lnbkJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG5TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSKiBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKipzZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKnNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKipkZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqcFByZXZBZGRIYXJtU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHVUlERV9WRUNUT1JTICpndWlkZVZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZGV0ZWN0aW9uU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCB0b3ROb0VzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG5ld0RldGVjdGlvbkFsbG93ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqcEFkZEhhcm1GbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqcEFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpwTnJnVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBERVRFQ1RPUl9QQVJBTUVURVJTX01IICptaFBhcmFtcykKewogIElOVCBlc3QgPSAwLGk7CiAgSU5UIHN0YXJ0OwoKICBGREttZW1jbGVhcihwQWRkSGFybVNmYixuU2ZiKnNpemVvZihVQ0hBUikpOwoKICBpZihuZXdEZXRlY3Rpb25BbGxvd2VkKXsKCiAgICBpZih0b3ROb0VzdCA+IDEpewogICAgICBzdGFydCA9IGRldGVjdGlvblN0YXJ0OwoKICAgICAgaWYgKHN0YXJ0ICE9IDApIHsKICAgICAgICBGREttZW1jcHkoZ3VpZGVWZWN0b3JzW3N0YXJ0XS5ndWlkZVZlY3RvckRpZmYsZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZixuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICAgIEZES21lbWNweShndWlkZVZlY3RvcnNbc3RhcnRdLmd1aWRlVmVjdG9yT3JpZyxndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JPcmlnLG5TZmIqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgICAgRkRLbWVtY2xlYXIoZ3VpZGVWZWN0b3JzW3N0YXJ0LTFdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQsblNmYipzaXplb2YoVUNIQVIpKTsKICAgICAgfQogICAgfQogICAgZWxzZXsKICAgICAgc3RhcnQgPSAwOwogICAgfQogIH0KICBlbHNlewogICAgc3RhcnQgPSAwOwogIH0KCgogIGZvcihlc3QgPSBzdGFydDsgZXN0IDwgdG90Tm9Fc3Q7IGVzdCsrKXsKCiAgICAvKgogICAgKiBEbyBkZXRlY3Rpb24gb24gdGhlIGN1cnJlbnQgZnJhbWUgdXNpbmcKICAgICogZ3VpZGUtaW5mbyBmcm9tIHRoZSBwcmV2aW91cy4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBpZihlc3QgPiAwKXsKICAgICAgRkRLbWVtY3B5KGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQsZGV0ZWN0aW9uVmVjdG9yc1tlc3QtMV0sblNmYipzaXplb2YoVUNIQVIpKTsKICAgIH0KCiAgICBGREttZW1jbGVhcihkZXRlY3Rpb25WZWN0b3JzW2VzdF0sIG5TZmIqc2l6ZW9mKFVDSEFSKSk7CgogICAgaWYoZXN0IDwgdG90Tm9Fc3QtMSl7CiAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tlc3QrMV0uZ3VpZGVWZWN0b3JEaWZmLG5TZmIqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tlc3QrMV0uZ3VpZGVWZWN0b3JPcmlnLG5TZmIqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tlc3QrMV0uZ3VpZGVWZWN0b3JEZXRlY3RlZCxuU2ZiKnNpemVvZihVQ0hBUikpOwoKICAgICAgZGV0ZWN0aW9uKHF1b3RhQnVmZmVyW2VzdF0sCiAgICAgICAgICAgICAgICBwRGlmZlZlY1NjZmJbZXN0XSwKICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF0sCiAgICAgICAgICAgICAgICBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgIHNmbU9yaWdbZXN0XSwKICAgICAgICAgICAgICAgIHNmbVNicltlc3RdLAogICAgICAgICAgICAgICAgZ3VpZGVWZWN0b3JzW2VzdF0sCiAgICAgICAgICAgICAgICBndWlkZVZlY3RvcnNbZXN0KzFdLAogICAgICAgICAgICAgICAgbWhQYXJhbXMtPnRocmVzSG9sZHMpOwogICAgfQogICAgZWxzZXsKICAgICAgRkRLbWVtY2xlYXIoZ3VpZGVWZWN0b3JzW2VzdF0uZ3VpZGVWZWN0b3JEaWZmLG5TZmIqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yT3JpZyxuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICBGREttZW1jbGVhcihndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3RvckRldGVjdGVkLG5TZmIqc2l6ZW9mKFVDSEFSKSk7CgogICAgICBkZXRlY3Rpb24ocXVvdGFCdWZmZXJbZXN0XSwKICAgICAgICAgICAgICAgIHBEaWZmVmVjU2NmYltlc3RdLAogICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgIGRldGVjdGlvblZlY3RvcnNbZXN0XSwKICAgICAgICAgICAgICAgIHBGcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgc2ZtT3JpZ1tlc3RdLAogICAgICAgICAgICAgICAgc2ZtU2JyW2VzdF0sCiAgICAgICAgICAgICAgICBndWlkZVZlY3RvcnNbZXN0XSwKICAgICAgICAgICAgICAgIGd1aWRlVmVjdG9yc1tlc3RdLAogICAgICAgICAgICAgICAgbWhQYXJhbXMtPnRocmVzSG9sZHMpOwogICAgfQogIH0KCgogIC8qIENsZWFuIHVwIHRoZSBkZXRlY3Rpb24uKi8KICB0cmFuc2llbnRDbGVhblVwKHF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgICAgIGRldGVjdGlvblZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICBwQWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgIHBQcmV2QWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgIHNpZ25CdWZmZXIsCiAgICAgICAgICAgICAgICAgICBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgdG90Tm9Fc3QsCiAgICAgICAgICAgICAgICAgICBuZXdEZXRlY3Rpb25BbGxvd2VkLAogICAgICAgICAgICAgICAgICAgcE5yZ1ZlY3RvciwKICAgICAgICAgICAgICAgICAgIG1oUGFyYW1zLT50aHJlc0hvbGRzKTsKCgogIC8qIFNldCBmbGFnLi4uICovCiAgKnBBZGRIYXJtRmxhZyA9IDA7CiAgZm9yKGk9MDsgaTxuU2ZiOyBpKyspewogICAgaWYocEFkZEhhcm1TZmJbaV0pewogICAgICAqcEFkZEhhcm1GbGFnID0gMTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICBGREttZW1jcHkocFByZXZBZGRIYXJtU2ZiLCBwQWRkSGFybVNmYiwgblNmYipzaXplb2YoVUNIQVIpKTsKICBGREttZW1jcHkoZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQscEFkZEhhcm1TZmIsblNmYipzaXplb2YoSU5UKSk7CgogIGZvcihpPTA7IGk8blNmYiA7IGkrKyl7CgogICAgZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZltpXSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwoKICAgIGlmKHBBZGRIYXJtU2ZiW2ldID09IDEpewogICAgICAvKiBJZiB3ZSBoYWQgYSBkZXRlY3Rpb24gdXNlIHRoZSBndWlkZS12YWx1ZSBpbiB0aGUgbmV4dCBmcmFtZSBmcm9tIHRoZSBsYXN0IGVzdGltYXRlIHdlcmUgdGhlIGRldGVjdGlvbgogICAgICB3YXMgZG9uZS4qLwogICAgICBmb3IoZXN0PXN0YXJ0OyBlc3QgPCB0b3ROb0VzdDsgZXN0KyspewogICAgICAgIGlmKGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yRGlmZltpXSAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSl7CiAgICAgICAgICBndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmW2ldID0gZ3VpZGVWZWN0b3JzW2VzdF0uZ3VpZGVWZWN0b3JEaWZmW2ldOwogICAgICAgIH0KICAgICAgICBpZihndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3Rvck9yaWdbaV0gIT0gRkwyRlhDT05TVF9EQkwoMC4wZikpewogICAgICAgICAgZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yT3JpZ1tpXTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIENhbGN1bGF0ZXMgYSBjb21wZW5zYXRpb24gdmVjdG9yIGZvciB0aGUgZW5lcmd5IGRhdGEuCgogIFRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyBhIGNvbXBlbnNhdGlvbiB2ZWN0b3IgZm9yIHRoZSBlbmVyZ3kgZGF0YSAoaS5lLgogIGVudmVsb3BlIGRhdGEpIHRoYXQgaXMgY2FsY3VsYXRlZCBlbHNld2hlcmUuIFRoaXMgaXMgc2luY2UsIG9uZSBzaW5lIG9uCiAgdGhlIGJvcmRlciBvZiB0d28gc2NhbGVmYWN0b3IgYmFuZHMsIHdpbGwgYmUgcmVwbGFjZSBieSBvbmUgc2luZSBpbiB0aGUKICBtaWRkbGUgb2YgZWl0aGVyIHNjYWxlZmFjdG9yIGJhbmQuIEhvd2V2ZXIsIHNpbmNlIHRoZSBzaW5lIHRoYXQgaXMgcmVwbGFjZWQKICB3aWxsIGluZmx1ZW5jZSB0aGUgZW5lcmd5IGVzdGltYXRlIGluIGJvdGggc2NhbGVmYWN0b3IgYmFuZHMgKGluIHRoZSBlbnZlbG9wcwogIGNhbGN1bGF0aW9uIGZ1bmN0aW9uKSBhIGNvbXBlbnNhdGlvbiB2YWx1ZSBpcyByZXF1aXJlZCBpbiBvcmRlciB0byBhdm9pZAogIG5vaXNlIHN1YnN0aXR1dGlvbiBpbiB0aGUgZGVjb2RlciBuZXh0IHRvIHRoZSBzeW50aGV0aWMgc2luZS4KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBjYWxjdWxhdGVDb21wVmVjdG9yKFVDSEFSICpwQWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKnBUb25hbGl0eU1hdHJpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKiogcFNpZ25NYXRyaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBFbnZDb21wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICpmcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCB0b3ROb0VzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbWF4Q29tcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqcFByZXZFbnZDb21wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuZXdEZXRlY3Rpb25BbGxvd2VkKQp7CgogIElOVCBzY2ZCYW5kLGVzdCxsLGxsLGx1LG1heFBvc0YsbWF4UG9zVDsKICBGSVhQX0RCTCBtYXhWYWw7CiAgSU5UIGNvbXBWYWx1ZTsKICBGSVhQX0RCTCB0bXA7CgogIEZES21lbWNsZWFyKHBFbnZDb21wLG5TZmIqc2l6ZW9mKFVDSEFSKSk7CgogIGZvcihzY2ZCYW5kPTA7IHNjZkJhbmQgPCBuU2ZiOyBzY2ZCYW5kKyspewoKICAgIGlmKHBBZGRIYXJtU2ZiW3NjZkJhbmRdKXsgLyogQSBtaXNzaW5nIHNpbmUgd2FzIGRldGVjdGVkICovCiAgICAgIGxsID0gZnJlcUJhbmRUYWJsZVtzY2ZCYW5kXTsKICAgICAgbHUgPSBmcmVxQmFuZFRhYmxlW3NjZkJhbmQrMV07CgogICAgICBtYXhQb3NGID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAvKiBGaXJzdCBmaW5kIHRoZSBtYXhpbXVtKi8KICAgICAgbWF4UG9zVCA9IDA7CiAgICAgIG1heFZhbCA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwoKICAgICAgZm9yKGVzdD0wO2VzdDx0b3ROb0VzdDtlc3QrKyl7CiAgICAgICAgZm9yKGw9bGw7IGw8bHU7IGwrKyl7CiAgICAgICAgICBpZihwVG9uYWxpdHlNYXRyaXhbZXN0XVtsXSA+IG1heFZhbCl7CiAgICAgICAgICAgIG1heFZhbCA9IHBUb25hbGl0eU1hdHJpeFtlc3RdW2xdOwogICAgICAgICAgICBtYXhQb3NGID0gbDsKICAgICAgICAgICAgbWF4UG9zVCA9IGVzdDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qCiAgICAgICAqIElmIHRoZSBtYXhpbXVtIHRvbmFsaXR5IGlzIGF0IHRoZSBsb3dlciBib3JkZXIgb2YgdGhlCiAgICAgICAqIHNjYWxlZmFjdG9yIGJhbmQsIHdlIGNoZWNrIHRoZSBzaWduIG9mIHRoZSBhZGphY2VudCBjaGFubmVscwogICAgICAgKiB0byBzZWUgaWYgdGhpcyBzaW5lIGlzIHNoYXJlZCBieSB0aGUgbG93ZXIgY2hhbm5lbC4gSWYgc28sIHRoZQogICAgICAgKiBlbmVyZ3kgb2YgdGhlIHNpbmdsZSBzaW5lIHdpbGwgYmUgcHJlc2VudCBpbiB0d28gc2NhbGVmYWN0b3IgYmFuZHMKICAgICAgICogaW4gdGhlIFNCUiBkYXRhLCB3aGljaCB3aWxsIGNhdXNlIHByb2JsZW1zIGluIHRoZSBkZWNvZGVyLCB3aGVuIHdlCiAgICAgICAqIGFkZCBhIHNpbmUgdG8ganVzdCBvbmUgb2YgdGhlIGNoYW5uZWxzLgogICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgICBpZihtYXhQb3NGID09IGxsICYmIHNjZkJhbmQpewogICAgICAgIGlmKCFwQWRkSGFybVNmYltzY2ZCYW5kIC0gMV0pIHsgICAgIC8qIE5vIGRldGVjdGlvbiBiZWxvdyovCiAgICAgICAgICBpZiAocFNpZ25NYXRyaXhbbWF4UG9zVF1bbWF4UG9zRiAtIDFdID4gMCAmJiBwU2lnbk1hdHJpeFttYXhQb3NUXVttYXhQb3NGXSA8IDApIHsKICAgICAgICAgICAgLyogVGhlIGNvbXAgdmFsdWUgaXMgY2FsdWxhdGVkIGFzIHRoZSB0b25hbGxpdHkgdmFsdWUsIGkuZSB3ZSB3YW50IHRvCiAgICAgICAgICAgICAgIHJlZHVjZSB0aGUgZW52ZWxvcGUgZGF0YSBmb3IgdGhpcyBjaGFubmVsIHdpdGggYXMgbXVjaCBhcyB0aGUgdG9uYWxpdHkKICAgICAgICAgICAgICAgdGhhdCBpcyBzcHJlYWQgZnJvbSB0aGUgY2hhbm5lbCBhYm92ZS4gKGxkNjQoUkVMQVhBVElPTikgPSAwLjMxMTQzMDc1ODg5KSAqLwogICAgICAgICAgICB0bXAgPSBmaXhwX2FicygoRklYUF9EQkwpQ2FsY0xkRGF0YShwVG9uYWxpdHlNYXRyaXhbbWF4UG9zVF1bbWF4UG9zRiAtIDFdKSArIFJFTEFYQVRJT05fTEQ2NCk7CiAgICAgICAgICAgIHRtcCA9ICh0bXAgPj4gKERGUkFDVF9CSVRTLTEtTERfREFUQV9TSElGVC0xKSkgKyAoRklYUF9EQkwpMTsgIC8qIHNoaWZ0IG9uZSBiaXQgbGVzcyBmb3Igcm91bmRpbmcgKi8KICAgICAgICAgICAgY29tcFZhbHVlID0gKChJTlQpKExPTkcpdG1wKSA+PiAxOwoKCQkJCQkJICAgICAgLyogbGltaXQgdGhlIGNvbXAtdmFsdWUqLwogICAgICAgICAgICBpZiAoY29tcFZhbHVlID4gbWF4Q29tcCkKICAgICAgICAgICAgICBjb21wVmFsdWUgPSBtYXhDb21wOwoKICAgICAgICAgICAgcEVudkNvbXBbc2NmQmFuZC0xXSA9IGNvbXBWYWx1ZTsKCQkJCQkgICAgIH0KCQkJCSAgICB9CiAgICAgIH0KCiAgICAgIC8qCiAgICAgICAqIFNhbWUgYXMgYWJvdmUsIGJ1dCBmb3IgdGhlIHVwcGVyIGVuZCBvZiB0aGUgc2NhbGVmYWN0b3ItYmFuZC4KICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgaWYobWF4UG9zRiA9PSBsdS0xICYmIHNjZkJhbmQrMSA8IG5TZmIpeyAgICAgICAgLyogVXBwZXIgYm9yZGVyKi8KICAgICAgICBpZighcEFkZEhhcm1TZmJbc2NmQmFuZCArIDFdKSB7CiAgICAgICAgICBpZiAocFNpZ25NYXRyaXhbbWF4UG9zVF1bbWF4UG9zRl0gPiAwICYmIHBTaWduTWF0cml4W21heFBvc1RdW21heFBvc0YgKyAxXSA8IDApIHsKICAgICAgICAgICAgdG1wID0gZml4cF9hYnMoKEZJWFBfREJMKUNhbGNMZERhdGEocFRvbmFsaXR5TWF0cml4W21heFBvc1RdW21heFBvc0YgKyAxXSkgKyBSRUxBWEFUSU9OX0xENjQpOwogICAgICAgICAgICB0bXAgPSAodG1wID4+IChERlJBQ1RfQklUUy0xLUxEX0RBVEFfU0hJRlQtMSkpICsgKEZJWFBfREJMKTE7ICAvKiBzaGlmdCBvbmUgYml0IGxlc3MgZm9yIHJvdW5kaW5nICovCiAgICAgICAgICAgIGNvbXBWYWx1ZSA9ICgoSU5UKShMT05HKXRtcCkgPj4gMTsKCiAgICAgICAgICAgIGlmIChjb21wVmFsdWUgPiBtYXhDb21wKQogICAgICAgICAgICAgIGNvbXBWYWx1ZSA9IG1heENvbXA7CgogICAgICAgICAgICBwRW52Q29tcFtzY2ZCYW5kKzFdID0gY29tcFZhbHVlOwoJCQkJCSB9CgkJCQkgfQogICAgICB9CgkJIH0KCSB9CgogIGlmKG5ld0RldGVjdGlvbkFsbG93ZWQgPT0gMCl7CiAgICBmb3Ioc2NmQmFuZD0wO3NjZkJhbmQ8blNmYjtzY2ZCYW5kKyspewogICAgICBpZihwRW52Q29tcFtzY2ZCYW5kXSAhPSAwICYmIHBQcmV2RW52Q29tcFtzY2ZCYW5kXSA9PSAwKQogICAgICAgIHBFbnZDb21wW3NjZkJhbmRdID0gMDsKICAgIH0KICB9CgogIC8qIHJlbWVtYmVyIHRoZSB2YWx1ZSBmb3IgdGhlIG5leHQgZnJhbWUuKi8KICBGREttZW1jcHkocFByZXZFbnZDb21wLHBFbnZDb21wLG5TZmIqc2l6ZW9mKFVDSEFSKSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgRGV0ZWN0cyB3aGVyZSBzdHJvbmcgdG9uYWwgY29tcG9uZW50cyB3aWxsIGJlIG1pc3NpbmcgYWZ0ZXIKICAgICAgICAgICAgIEhGUiBpbiB0aGUgZGVjb2Rlci4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZApGREtzYnJFbmNfU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yUW1mKEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaF9zYnJNSERldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICoqIHBRdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqKiBwU2lnbkJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSKiBpbmRleFZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNCUl9GUkFNRV9JTkZPICpwRnJhbWVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNIQVIqIHBUcmFuSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCogcEFkZEhhcm1vbmljc0ZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiogcEFkZEhhcm1vbmljc1NjYWxlRmFjdG9yQmFuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiogZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIqIGVudmVsb3BlQ29tcGVuc2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBOcmdWZWN0b3IpCnsKICBJTlQgdHJhbnNpZW50RmxhZyA9IHBUcmFuSW5mb1sxXTsKICBJTlQgdHJhbnNpZW50UG9zICA9IHBUcmFuSW5mb1swXTsKICBJTlQgbmV3RGV0ZWN0aW9uQWxsb3dlZDsKICBJTlQgdHJhbnNpZW50RGV0U3RhcnQgPSAwOwoKICBVQ0hBUiAqKiBkZXRlY3Rpb25WZWN0b3JzICA9IGhfc2JyTUhEZXQtPmRldGVjdGlvblZlY3RvcnM7CiAgSU5UIG1vdmUgICAgICAgICAgICAgICAgPSBoX3Nick1IRGV0LT5tb3ZlOwogIElOVCBub0VzdFBlckZyYW1lICAgICAgID0gaF9zYnJNSERldC0+bm9Fc3RQZXJGcmFtZTsKICBJTlQgdG90Tm9Fc3QgICAgICAgICAgICA9IGhfc2JyTUhEZXQtPnRvdE5vRXN0OwogIElOVCBwcmV2VHJhbnNpZW50RmxhZyAgID0gaF9zYnJNSERldC0+cHJldmlvdXNUcmFuc2llbnRGbGFnOwogIElOVCBwcmV2VHJhbnNpZW50RnJhbWUgID0gaF9zYnJNSERldC0+cHJldmlvdXNUcmFuc2llbnRGcmFtZTsKICBJTlQgdHJhbnNpZW50UG9zT2Zmc2V0ICA9IGhfc2JyTUhEZXQtPnRyYW5zaWVudFBvc09mZnNldDsKICBJTlQgcHJldlRyYW5zaWVudFBvcyAgICA9IGhfc2JyTUhEZXQtPnByZXZpb3VzVHJhbnNpZW50UG9zOwogIEdVSURFX1ZFQ1RPUlMqIGd1aWRlVmVjdG9ycyA9IGhfc2JyTUhEZXQtPmd1aWRlVmVjdG9yczsKICBJTlQgZGVsdGFUaW1lID0gaF9zYnJNSERldC0+bWhQYXJhbXMtPmRlbHRhVGltZTsKICBJTlQgbWF4Q29tcCA9IGhfc2JyTUhEZXQtPm1oUGFyYW1zLT5tYXhDb21wOwoKICBpbnQgZXN0OwoKICAvKgogIEJ1ZmZlciB2YWx1ZXMuCiAgKi8KICBGREtfQVNTRVJUKG1vdmU8PShNQVhfTk9fT0ZfRVNUSU1BVEVTPj4xKSk7CiAgRkRLX0FTU0VSVChub0VzdFBlckZyYW1lPD0oTUFYX05PX09GX0VTVElNQVRFUz4+MSkpOwoKICBGSVhQX0RCTCAqc2ZtU2JyW01BWF9OT19PRl9FU1RJTUFURVNdOwogIEZJWFBfREJMICpzZm1PcmlnW01BWF9OT19PRl9FU1RJTUFURVNdOwogIEZJWFBfREJMICp0b25hbGl0eURpZmZbTUFYX05PX09GX0VTVElNQVRFU107CgogIGZvciAoZXN0PTA7IGVzdCA8IE1BWF9OT19PRl9FU1RJTUFURVMvMjsgZXN0KyspIHsKICAgIHNmbVNicltlc3RdICAgICAgID0gaF9zYnJNSERldC0+c2ZtU2JyW2VzdF07CiAgICBzZm1PcmlnW2VzdF0gICAgICA9IGhfc2JyTUhEZXQtPnNmbU9yaWdbZXN0XTsKICAgIHRvbmFsaXR5RGlmZltlc3RdID0gaF9zYnJNSERldC0+dG9uYWxpdHlEaWZmW2VzdF07CiAgfQoKICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQoc2NyYXRjaF9tZW0sIEZJWFBfREJMLCAoMypNQVhfTk9fT0ZfRVNUSU1BVEVTLzIqTUFYX0ZSRVFfQ09FRkZTKSk7CiAgRklYUF9EQkwgKnNjcmF0Y2ggPSBzY3JhdGNoX21lbTsKICBmb3IgKDsgZXN0IDwgTUFYX05PX09GX0VTVElNQVRFUzsgZXN0KyspIHsKICAgIHNmbVNicltlc3RdICAgICAgID0gc2NyYXRjaDsgc2NyYXRjaCs9TUFYX0ZSRVFfQ09FRkZTOwogICAgc2ZtT3JpZ1tlc3RdICAgICAgPSBzY3JhdGNoOyBzY3JhdGNoKz1NQVhfRlJFUV9DT0VGRlM7CiAgICB0b25hbGl0eURpZmZbZXN0XSA9IHNjcmF0Y2g7IHNjcmF0Y2grPU1BWF9GUkVRX0NPRUZGUzsKICB9CgoKCiAgLyogRGV0ZXJtaW5lIGlmIHdlJ3JlIGFsbG93ZWQgdG8gZGV0ZWN0ICJtaXNzaW5nIGhhcm1vbmljcyIgdGhhdCB3YXNuJ3QgZGV0ZWN0ZWQgYmVmb3JlLgogICAgIEluIG9yZGVyIHRvIGJlIGFsbG93ZWQgdG8gZG8gbmV3IGRldGVjdGlvbiwgdGhlcmUgbXVzdCBiZSBhIHRyYW5zaWVudCBpbiB0aGUgY3VycmVudAogICAgIGZyYW1lLCBvciBhIHRyYW5zaWVudCBpbiB0aGUgcHJldmlvdXMgZnJhbWUgc3VmZmljaWVudGx5IGNsb3NlIHRvIHRoZSBjdXJyZW50IGZyYW1lLiAqLwogIG5ld0RldGVjdGlvbkFsbG93ZWQgPSBpc0RldGVjdGlvbk9mTmV3VG9uZUFsbG93ZWQocEZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0cmFuc2llbnREZXRTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vRXN0UGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2VHJhbnNpZW50RnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2VHJhbnNpZW50UG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldlRyYW5zaWVudEZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2llbnRQb3NPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2llbnRGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpZW50UG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsdGFUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJNSERldCk7CgogIC8qIENhbHVsYXRlIHRoZSB2YXJpYWJsZXMgdGhhdCB3aWxsIGJlIHVzZWQgc3Vic2VxdWVudGx5IGZvciB0aGUgYWN0dWFsIGRldGVjdGlvbiAqLwogIGNhbGN1bGF0ZURldGVjdG9ySW5wdXQocFF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICB0b25hbGl0eURpZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICBzZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgc2ZtU2JyLAogICAgICAgICAgICAgICAgICAgICAgICAgZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgbW92ZSk7CgogIC8qIERvIHRoZSBhY3R1YWwgZGV0ZWN0aW9uIHVzaW5nIGluZm9ybWF0aW9uIGZyb20gcHJldmlvdXMgZGV0ZWN0aW9ucyAqLwogIGRldGVjdGlvbldpdGhQcmVkaWN0aW9uKHBRdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICB0b25hbGl0eURpZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNpZ25CdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNmbU9yaWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZtU2JyLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRldGVjdGlvblZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJNSERldC0+Z3VpZGVTY2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlVmVjdG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaWVudERldFN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdE5vRXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RldGVjdGlvbkFsbG93ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcEFkZEhhcm1vbmljc0ZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcEFkZEhhcm1vbmljc1NjYWxlRmFjdG9yQmFuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcE5yZ1ZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICBoX3Nick1IRGV0LT5taFBhcmFtcyk7CgogIC8qIENhbGN1bGF0ZSB0aGUgY29tcCB2ZWN0b3IsIHNvIHRoYXQgdGhlIGVuZXJneSBjYW4gYmUKICAgICBjb21wZW5zYXRlZCBmb3IgYSBzaW5lIGJldHdlZW4gdHdvIFFNRi1iYW5kcy4gKi8KICBjYWxjdWxhdGVDb21wVmVjdG9yKHBBZGRIYXJtb25pY3NTY2FsZUZhY3RvckJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgcFF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgcFNpZ25CdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICBlbnZlbG9wZUNvbXBlbnNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICAgICAgICBmcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgdG90Tm9Fc3QsCiAgICAgICAgICAgICAgICAgICAgICBtYXhDb21wLAogICAgICAgICAgICAgICAgICAgICAgaF9zYnJNSERldC0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCk7CgogIGZvciAoZXN0PTA7IGVzdCA8IG1vdmU7IGVzdCsrKSB7CiAgICBGREttZW1jcHkodG9uYWxpdHlEaWZmW2VzdF0sIHRvbmFsaXR5RGlmZltlc3QgKyBub0VzdFBlckZyYW1lXSwgc2l6ZW9mKEZJWFBfREJMKSpNQVhfRlJFUV9DT0VGRlMpOwogICAgRkRLbWVtY3B5KHNmbU9yaWdbZXN0XSwgc2ZtT3JpZ1tlc3QgKyBub0VzdFBlckZyYW1lXSwgc2l6ZW9mKEZJWFBfREJMKSpNQVhfRlJFUV9DT0VGRlMpOwogICAgRkRLbWVtY3B5KHNmbVNicltlc3RdLCBzZm1TYnJbZXN0ICsgbm9Fc3RQZXJGcmFtZV0sIHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICB9CiAgQ19BTExPQ19TQ1JBVENIX0VORChzY3JhdGNoLCBGSVhQX0RCTCwgKDMqTUFYX05PX09GX0VTVElNQVRFUy8yKk1BWF9GUkVRX0NPRUZGUykpOwoKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBJbml0aWFsaXplIGFuIGluc3RhbmNlIG9mIHRoZSBtaXNzaW5nIGhhcm1vbmljcyBkZXRlY3Rvci4KCgogIFxyZXR1cm4gICAgZXJyb3JDb2RlLCBub0Vycm9yIGlmIE9LLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQKRkRLc2JyRW5jX0NyZWF0ZVNick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvciAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBoU2JyTUhEZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGNoYW4pCnsKICBIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhzID0gaFNick1IRGV0OwogIElOVCBpOwoKICBVQ0hBUiogZGV0ZWN0aW9uVmVjdG9ycyAgICA9IEdldFJhbV9TYnJfZGV0ZWN0aW9uVmVjdG9ycyhjaGFuKTsKICBVQ0hBUiogZ3VpZGVWZWN0b3JEZXRlY3RlZCA9IEdldFJhbV9TYnJfZ3VpZGVWZWN0b3JEZXRlY3RlZChjaGFuKTsKICBGSVhQX0RCTCogZ3VpZGVWZWN0b3JEaWZmICA9IEdldFJhbV9TYnJfZ3VpZGVWZWN0b3JEaWZmKGNoYW4pOwogIEZJWFBfREJMKiBndWlkZVZlY3Rvck9yaWcgID0gR2V0UmFtX1Nicl9ndWlkZVZlY3Rvck9yaWcoY2hhbik7CgogIEZES21lbWNsZWFyIChocyxzaXplb2YoU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SKSk7CgogIGhzLT5wcmV2RW52ZWxvcGVDb21wZW5zYXRpb24gPSBHZXRSYW1fU2JyX3ByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbihjaGFuKTsKICBocy0+Z3VpZGVTY2ZiICAgICAgICAgICAgICAgID0gR2V0UmFtX1Nicl9ndWlkZVNjZmIoY2hhbik7CgogIGZvcihpPTA7IGk8TUFYX05PX09GX0VTVElNQVRFUzsgaSsrKSB7CiAgICBocy0+Z3VpZGVWZWN0b3JzW2ldLmd1aWRlVmVjdG9yRGlmZiA9IGd1aWRlVmVjdG9yRGlmZiArIChpKk1BWF9GUkVRX0NPRUZGUyk7CiAgICBocy0+Z3VpZGVWZWN0b3JzW2ldLmd1aWRlVmVjdG9yT3JpZyA9IGd1aWRlVmVjdG9yT3JpZyArIChpKk1BWF9GUkVRX0NPRUZGUyk7CiAgICBocy0+ZGV0ZWN0aW9uVmVjdG9yc1tpXSA9IGRldGVjdGlvblZlY3RvcnMgKyAoaSpNQVhfRlJFUV9DT0VGRlMpOwogICAgaHMtPmd1aWRlVmVjdG9yc1tpXS5ndWlkZVZlY3RvckRldGVjdGVkID0gZ3VpZGVWZWN0b3JEZXRlY3RlZCArIChpKk1BWF9GUkVRX0NPRUZGUyk7CiAgfQoKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBJbml0aWFsaXplIGFuIGluc3RhbmNlIG9mIHRoZSBtaXNzaW5nIGhhcm1vbmljcyBkZXRlY3Rvci4KCgogIFxyZXR1cm4gICAgZXJyb3JDb2RlLCBub0Vycm9yIGlmIE9LLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQKRkRLc2JyRW5jX0luaXRTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaFNick1IRGV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzYW1wbGVGcmVxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBmcmFtZVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG5TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHFtZk5vQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHRvdE5vRXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBtb3ZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgc2JyU3ludGF4RmxhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaHMgPSBoU2JyTUhEZXQ7CiAgaW50IGk7CgogIEZES19BU1NFUlQodG90Tm9Fc3QgPD0gTUFYX05PX09GX0VTVElNQVRFUyk7CgogIGlmIChzYnJTeW50YXhGbGFncyAmIFNCUl9TWU5UQVhfTE9XX0RFTEFZKQogIHsKICAgIHN3aXRjaChmcmFtZVNpemUpewogICAgY2FzZSAxMDI0OgogICAgY2FzZSA1MTI6CiAgICAgICAgaHMtPnRyYW5zaWVudFBvc09mZnNldCA9IEZSQU1FX01JRERMRV9TTE9UXzUxMkxEOwogICAgICAgIGhzLT50aW1lU2xvdHMgICAgICAgICAgPSAxNjsKICAgICAgICBicmVhazsKICAgIGNhc2UgOTYwOgogICAgY2FzZSA0ODA6CiAgICAgICAgaHMtPnRyYW5zaWVudFBvc09mZnNldCA9IEZSQU1FX01JRERMRV9TTE9UXzUxMkxEOwogICAgICAgIGhzLT50aW1lU2xvdHMgICAgICAgICAgPSAxNTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogIH0gZWxzZQogIHsKICAgIHN3aXRjaChmcmFtZVNpemUpewogICAgY2FzZSAyMDQ4OgogICAgY2FzZSAxMDI0OgogICAgICAgIGhzLT50cmFuc2llbnRQb3NPZmZzZXQgPSBGUkFNRV9NSURETEVfU0xPVF8yMDQ4OwogICAgICAgIGhzLT50aW1lU2xvdHMgICAgICAgICAgPSBOVU1CRVJfVElNRV9TTE9UU18yMDQ4OwogICAgICAgIGJyZWFrOwogICAgY2FzZSAxOTIwOgogICAgY2FzZSA5NjA6CiAgICAgICAgaHMtPnRyYW5zaWVudFBvc09mZnNldCA9IEZSQU1FX01JRERMRV9TTE9UXzE5MjA7CiAgICAgICAgaHMtPnRpbWVTbG90cyAgICAgICAgICA9IE5VTUJFUl9USU1FX1NMT1RTXzE5MjA7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAtMTsKICAgIH0KICB9CgogIGlmIChzYnJTeW50YXhGbGFncyAmIFNCUl9TWU5UQVhfTE9XX0RFTEFZKSB7CiAgICBocy0+bWhQYXJhbXMgPSAmcGFyYW1zQWFjTGQ7CiAgfSBlbHNlCiAgaHMtPm1oUGFyYW1zID0gJnBhcmFtc0FhYzsKCiAgaHMtPnFtZk5vQ2hhbm5lbHMgPSBxbWZOb0NoYW5uZWxzOwogIGhzLT5zYW1wbGVGcmVxID0gc2FtcGxlRnJlcTsKICBocy0+blNmYiA9IG5TZmI7CgogIGhzLT50b3ROb0VzdCA9IHRvdE5vRXN0OwogIGhzLT5tb3ZlID0gbW92ZTsKICBocy0+bm9Fc3RQZXJGcmFtZSA9IG5vRXN0UGVyRnJhbWU7CgogIGZvcihpPTA7IGk8dG90Tm9Fc3Q7IGkrKykgewogICAgRkRLbWVtY2xlYXIgKGhzLT5ndWlkZVZlY3RvcnNbaV0uZ3VpZGVWZWN0b3JEaWZmLHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNsZWFyIChocy0+Z3VpZGVWZWN0b3JzW2ldLmd1aWRlVmVjdG9yT3JpZyxzaXplb2YoRklYUF9EQkwpKk1BWF9GUkVRX0NPRUZGUyk7CiAgICBGREttZW1jbGVhciAoaHMtPmRldGVjdGlvblZlY3RvcnNbaV0sc2l6ZW9mKFVDSEFSKSpNQVhfRlJFUV9DT0VGRlMpOwogICAgRkRLbWVtY2xlYXIgKGhzLT5ndWlkZVZlY3RvcnNbaV0uZ3VpZGVWZWN0b3JEZXRlY3RlZCxzaXplb2YoVUNIQVIpKk1BWF9GUkVRX0NPRUZGUyk7CiAgfQoKICAvL2ZvcihpPTA7IGk8dG90Tm9Fc3QvMjsgaSsrKSB7CiAgZm9yKGk9MDsgaTxNQVhfTk9fT0ZfRVNUSU1BVEVTLzI7IGkrKykgewogICAgRkRLbWVtY2xlYXIgKGhzLT50b25hbGl0eURpZmZbaV0sc2l6ZW9mKEZJWFBfREJMKSpNQVhfRlJFUV9DT0VGRlMpOwogICAgRkRLbWVtY2xlYXIgKGhzLT5zZm1PcmlnW2ldLHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNsZWFyIChocy0+c2ZtU2JyW2ldLHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICB9CgogIEZES21lbWNsZWFyICggaHMtPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbiwgc2l6ZW9mKFVDSEFSKSpNQVhfRlJFUV9DT0VGRlMpOwogIEZES21lbWNsZWFyICggaHMtPmd1aWRlU2NmYiwgc2l6ZW9mKFVDSEFSKSpNQVhfRlJFUV9DT0VGRlMpOwoKICBocy0+cHJldmlvdXNUcmFuc2llbnRGbGFnID0gMDsKICBocy0+cHJldmlvdXNUcmFuc2llbnRGcmFtZSA9IDA7CiAgaHMtPnByZXZpb3VzVHJhbnNpZW50UG9zID0gMDsKCiAgcmV0dXJuICgwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIERlbGV0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdG9yLgoKCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkCkZES3NickVuY19EZWxldGVTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IoSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBoU2JyTUhEZXQpCnsKICBpZiAoaFNick1IRGV0KSB7CiAgICBIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhzID0gaFNick1IRGV0OwoKICAgIEZyZWVSYW1fU2JyX2RldGVjdGlvblZlY3RvcnMoJmhzLT5kZXRlY3Rpb25WZWN0b3JzWzBdKTsKICAgIEZyZWVSYW1fU2JyX2d1aWRlVmVjdG9yRGV0ZWN0ZWQoJmhzLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEZXRlY3RlZCk7CiAgICBGcmVlUmFtX1Nicl9ndWlkZVZlY3RvckRpZmYoJmhzLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmKTsKICAgIEZyZWVSYW1fU2JyX2d1aWRlVmVjdG9yT3JpZygmaHMtPmd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3Rvck9yaWcpOwogICAgRnJlZVJhbV9TYnJfcHJldkVudmVsb3BlQ29tcGVuc2F0aW9uKCZocy0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uKTsKICAgIEZyZWVSYW1fU2JyX2d1aWRlU2NmYigmaHMtPmd1aWRlU2NmYik7CgogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIFJlc2V0cyBhbiBpbnN0YW5jZSBvZiB0aGUgbWlzc2luZyBoYXJtb25pY3MgZGV0ZWN0b3IuCgoKICBccmV0dXJuICAgIGVycm9yIGNvZGUsIG5vRXJyb3IgaWYgT0suCgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCklOVApGREtzYnJFbmNfUmVzZXRTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IgKEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiKQp7CiAgaW50IGk7CiAgRklYUF9EQkwgdGVtcEd1aWRlW01BWF9GUkVRX0NPRUZGU107CiAgVUNIQVIgdGVtcEd1aWRlSW50W01BWF9GUkVRX0NPRUZGU107CiAgSU5UIG5TZmJQcmV2OwoKICBuU2ZiUHJldiA9IGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPm5TZmI7CiAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+blNmYiA9IG5TZmI7CgogIEZES21lbWNweSggdGVtcEd1aWRlSW50LCBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVNjZmIsIG5TZmJQcmV2ICogc2l6ZW9mKFVDSEFSKSApOwoKICBpZiAoIG5TZmIgPiBuU2ZiUHJldiApIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgKG5TZmIgLSBuU2ZiUHJldik7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVTY2ZiW2ldID0gMDsKICAgIH0KCiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmJQcmV2OyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPmd1aWRlU2NmYltpICsgKG5TZmIgLSBuU2ZiUHJldildID0gdGVtcEd1aWRlSW50W2ldOwogICAgfQogIH0KICBlbHNlIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVNjZmJbaV0gPSB0ZW1wR3VpZGVJbnRbaSArIChuU2ZiUHJldi1uU2ZiKV07CiAgICB9CiAgfQoKICBGREttZW1jcHkgKCB0ZW1wR3VpZGUsIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPmd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3RvckRpZmYsIG5TZmJQcmV2ICogc2l6ZW9mKEZJWFBfREJMKSApOwoKICBpZiAoblNmYiA+IG5TZmJQcmV2ICkgewogICAgZm9yICggaSA9IDA7IGkgPCAoblNmYiAtIG5TZmJQcmV2KTsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmW2ldID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICB9CgogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiUHJldjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmW2kgKyAoblNmYiAtIG5TZmJQcmV2KV0gPSB0ZW1wR3VpZGVbaV07CiAgICB9CiAgfQogIGVsc2UgewogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiOyBpKysgICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmW2ldID0gdGVtcEd1aWRlW2kgKyAoblNmYlByZXYtblNmYildOwogICAgfQogIH0KCiAgRkRLbWVtY3B5ICggdGVtcEd1aWRlLCBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JPcmlnLCBuU2ZiUHJldiAqIHNpemVvZihGSVhQX0RCTCkgKTsKCiAgaWYgKCBuU2ZiID4gblNmYlByZXYgKSB7CiAgICBmb3IgKCBpID0gMDsgaTwgKG5TZmIgLSBuU2ZiUHJldik7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgfQoKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYlByZXY7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZ1tpICsgKG5TZmIgLSBuU2ZiUHJldildID0gdGVtcEd1aWRlW2ldOwogICAgfQogIH0KICBlbHNlIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JPcmlnW2ldID0gdGVtcEd1aWRlW2kgKyAoblNmYlByZXYtblNmYildOwogICAgfQogIH0KCiAgRkRLbWVtY3B5ICggdGVtcEd1aWRlSW50LCBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEZXRlY3RlZCwgblNmYlByZXYgKiBzaXplb2YoVUNIQVIpICk7CgogIGlmICggblNmYiA+IG5TZmJQcmV2ICkgewogICAgZm9yICggaSA9IDA7IGkgPCAoblNmYiAtIG5TZmJQcmV2KTsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEZXRlY3RlZFtpXSA9IDA7CiAgICB9CgogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiUHJldjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEZXRlY3RlZFtpICsgKG5TZmIgLSBuU2ZiUHJldildID0gdGVtcEd1aWRlSW50W2ldOwogICAgfQogIH0KICBlbHNlIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEZXRlY3RlZFtpXSA9IHRlbXBHdWlkZUludFtpICsgKG5TZmJQcmV2LW5TZmIpXTsKICAgIH0KICB9CgogIEZES21lbWNweSAoIHRlbXBHdWlkZUludCwgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uLCBuU2ZiUHJldiAqIHNpemVvZihVQ0hBUikgKTsKCiAgaWYgKCBuU2ZiID4gblNmYlByZXYgKSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IChuU2ZiIC0gblNmYlByZXYpOyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbltpXSA9IDA7CiAgICB9CgogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiUHJldjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5wcmV2RW52ZWxvcGVDb21wZW5zYXRpb25baSArIChuU2ZiIC0gblNmYlByZXYpXSA9IHRlbXBHdWlkZUludFtpXTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmI7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uW2ldID0gdGVtcEd1aWRlSW50W2kgKyAoblNmYlByZXYtblNmYildOwogICAgfQogIH0KCiAgcmV0dXJuIDA7Cn0KCg==