Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqICBGYXN0IE1QRUcgQUFDIEF1ZGlvIEVuY29kZXIgICoqKioqKioqKioqKioqKioqKioqKioKCiAgIEluaXRpYWwgYXV0aG9yOiAgICAgICBNLiBTY2h1ZyAvIEEuIEdyb2VzY2hlbAogICBjb250ZW50cy9kZXNjcmlwdGlvbjogZmFzdCBhYWMgY29kZXIgZnVuY3Rpb25zCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jLmgiCgojaW5jbHVkZSAiYml0ZW5jLmgiCiNpbmNsdWRlICJpbnRlcmZhY2UuaCIKI2luY2x1ZGUgInBzeV9jb25maWd1cmF0aW9uLmgiCiNpbmNsdWRlICJwc3lfbWFpbi5oIgojaW5jbHVkZSAicWNfbWFpbi5oIgojaW5jbHVkZSAiYmFuZHdpZHRoLmgiCiNpbmNsdWRlICJjaGFubmVsX21hcC5oIgojaW5jbHVkZSAidG5zX2Z1bmMuaCIKI2luY2x1ZGUgImFhY0VuY19yYW0uaCIKCiNpbmNsdWRlICJnZW5lcmljU3Rkcy5oIgoKCgoKI2RlZmluZSBNSU5fQlVGU0laRV9QRVJfRUZGX0NIQU4gNjE0NAoKSU5UIEZES2FhY0VuY19DYWxjQml0c1BlckZyYW1lKAogICAgICAgIGNvbnN0IElOVCBiaXRSYXRlLAogICAgICAgIGNvbnN0IElOVCBmcmFtZUxlbmd0aCwKICAgICAgICBjb25zdCBJTlQgc2FtcGxpbmdSYXRlCiAgICAgICAgKQp7CiAgICBpbnQgc2hpZnQgPSAwOwogICAgd2hpbGUgKChmcmFtZUxlbmd0aCAmIH4oKDEgPDwgKHNoaWZ0ICsgMSkpIC0gMSkpID09IGZyYW1lTGVuZ3RoCiAgICAgICAgJiYgKHNhbXBsaW5nUmF0ZSAmIH4oKDEgPDwgKHNoaWZ0ICsgMSkpIC0gMSkpID09IHNhbXBsaW5nUmF0ZSkKICAgIHsKICAgICAgc2hpZnQrKzsKICAgIH0KCiAgICByZXR1cm4gKGJpdFJhdGUqKGZyYW1lTGVuZ3RoPj5zaGlmdCkpIC8gKHNhbXBsaW5nUmF0ZT4+c2hpZnQpOwp9CgpJTlQgRkRLYWFjRW5jX0NhbGNCaXRyYXRlKAogICAgICAgIGNvbnN0IElOVCBiaXRzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgSU5UIGZyYW1lTGVuZ3RoLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGluZ1JhdGUKICAgICAgICApCnsKICAgIGludCBzaGlmdCA9IDA7CiAgICB3aGlsZSAoKGZyYW1lTGVuZ3RoICYgfigoMSA8PCAoc2hpZnQgKyAxKSkgLSAxKSkgPT0gZnJhbWVMZW5ndGgKICAgICAgICAmJiAoc2FtcGxpbmdSYXRlICYgfigoMSA8PCAoc2hpZnQgKyAxKSkgLSAxKSkgPT0gc2FtcGxpbmdSYXRlKQogICAgewogICAgICBzaGlmdCsrOwogICAgfQoKICAgIHJldHVybiAoYml0c1BlckZyYW1lICogKHNhbXBsaW5nUmF0ZT4+c2hpZnQpKSAvICggZnJhbWVMZW5ndGg+PnNoaWZ0KSA7Cgp9CgpzdGF0aWMgQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX0luaXRDaGVja0FuY2lsbGFyeShJTlQgYml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGZyYW1lbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgYW5jaWxsYXJ5UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICphbmNpbGxhcnlCaXRzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzYW1wbGVSYXRlKTsKCklOVCBGREthYWNFbmNfTGltaXRCaXRyYXRlKAogICAgICAgIEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwRW5jLAogICAgICAgIElOVCBjb3JlU2FtcGxpbmdSYXRlLAogICAgICAgIElOVCBmcmFtZUxlbmd0aCwKICAgICAgICBJTlQgbkNoYW5uZWxzLAogICAgICAgIElOVCBuQ2hhbm5lbHNFZmYsCiAgICAgICAgSU5UIGJpdFJhdGUsCiAgICAgICAgSU5UIGF2ZXJhZ2VCaXRzLAogICAgICAgIElOVCAqcEF2ZXJhZ2VCaXRzUGVyRnJhbWUsCiAgICAgICAgSU5UIGJpdHJhdGVNb2RlLAogICAgICAgIElOVCBuU3ViRnJhbWVzCiAgICAgICAgKQp7CiAgSU5UIHRyYW5zcG9ydEJpdHMsIHByZXZCaXRSYXRlLCBhdmVyYWdlQml0c1BlckZyYW1lLCBzaGlmdCA9IDAsIGl0ZXI9MDsKCiAgd2hpbGUgKCAoZnJhbWVMZW5ndGggJiB+KCgxPDwoc2hpZnQrMSkpLTEpKSA9PSBmcmFtZUxlbmd0aAogICAgJiYgKGNvcmVTYW1wbGluZ1JhdGUgJiB+KCgxPDwoc2hpZnQrMSkpLTEpKSA9PSBjb3JlU2FtcGxpbmdSYXRlICkKICB7CiAgICBzaGlmdCArKzsKICB9CgogIGRvIHsKICAgIHByZXZCaXRSYXRlID0gYml0UmF0ZTsKICAgICBhdmVyYWdlQml0c1BlckZyYW1lID0gKGJpdFJhdGUqKGZyYW1lTGVuZ3RoPj5zaGlmdCkpIC8gKGNvcmVTYW1wbGluZ1JhdGU+PnNoaWZ0KSAvIG5TdWJGcmFtZXM7CgogICAgaWYgKHBBdmVyYWdlQml0c1BlckZyYW1lICE9IE5VTEwpIHsKICAgICAgKnBBdmVyYWdlQml0c1BlckZyYW1lID0gYXZlcmFnZUJpdHNQZXJGcmFtZTsKICAgIH0KCiAgICBpZiAoaFRwRW5jICE9IE5VTEwpIHsKICAgICAgdHJhbnNwb3J0Qml0cyA9IHRyYW5zcG9ydEVuY19HZXRTdGF0aWNCaXRzKGhUcEVuYywgYXZlcmFnZUJpdHNQZXJGcmFtZSk7CiAgICB9IGVsc2UgewogICAgICAvKiBBc3N1bWUgc29tZSB3b3JzdCBjYXNlICovCiAgICAgIHRyYW5zcG9ydEJpdHMgPSAyMDg7CiAgICB9CgogICAgYml0UmF0ZSA9IEZES21heChiaXRSYXRlLCAoKCgoNDAgKiBuQ2hhbm5lbHMpICsgdHJhbnNwb3J0Qml0cykgKiAoY29yZVNhbXBsaW5nUmF0ZSkpIC8gZnJhbWVMZW5ndGgpICk7CiAgICBGREtfQVNTRVJUKGJpdFJhdGUgPj0gMCk7CgogICAgYml0UmF0ZSA9IEZES21pbihiaXRSYXRlLCAoKG5DaGFubmVsc0VmZiAqIE1JTl9CVUZTSVpFX1BFUl9FRkZfQ0hBTikqKGNvcmVTYW1wbGluZ1JhdGU+PnNoaWZ0KSkgLyAoZnJhbWVMZW5ndGg+PnNoaWZ0KSkgOwogICAgRkRLX0FTU0VSVChiaXRSYXRlID49IDApOwoKICB9IHdoaWxlIChwcmV2Qml0UmF0ZSAhPSBiaXRSYXRlICYmIGl0ZXIrKyA8IDMpIDsKCiAgcmV0dXJuIGJpdFJhdGU7Cn0KCgp0eXBlZGVmIHN0cnVjdAp7CiAgQUFDRU5DX0JJVFJBVEVfTU9ERSBiaXRyYXRlTW9kZTsKICBpbnQgY2hhbkJpdHJhdGVbMl07IC8qIG1vbm8vc3RlcmVvIHNldHRpbmdzICovCn0gQ09ORklHX1RBQl9FTlRSWV9WQlI7CgpzdGF0aWMgY29uc3QgQ09ORklHX1RBQl9FTlRSWV9WQlIgY29uZmlnVGFiVkJSW10gPSB7CiAge0FBQ0VOQ19CUl9NT0RFX0NCUiwgICB7ICAgICAwLCAgICAgMH19ICwKICB7QUFDRU5DX0JSX01PREVfVkJSXzEsIHsgMzIwMDAsIDIwMDAwfX0gLAogIHtBQUNFTkNfQlJfTU9ERV9WQlJfMiwgeyA0MDAwMCwgMzIwMDB9fSAsCiAge0FBQ0VOQ19CUl9NT0RFX1ZCUl8zLCB7IDU2MDAwLCA0ODAwMH19ICwKICB7QUFDRU5DX0JSX01PREVfVkJSXzQsIHsgNzIwMDAsIDY0MDAwfX0gLAogIHtBQUNFTkNfQlJfTU9ERV9WQlJfNSwgezExMjAwMCwgOTYwMDB9fQp9OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19HZXRWQlJCaXRyYXRlCiAgICAgZGVzY3JpcHRpb246ICBHZXQgVkJSIGJpdHJhdGUgZnJvbSB2YnIgcXVhbGl0eQogICAgIGlucHV0IHBhcmFtczogaW50IHZiclF1YWxpdHkgKFZCUjAsIFZCUjEsIFZCUjIpCiAgICAgICAgICAgICAgICAgICBjaGFubmVsTW9kZQogICAgIHJldHVybnM6ICAgICAgdmJyIGJpdHJhdGUKCiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpJTlQgRkRLYWFjRW5jX0dldFZCUkJpdHJhdGUoSU5UIGJpdHJhdGVNb2RlLCBDSEFOTkVMX01PREUgY2hhbm5lbE1vZGUpCnsKICBJTlQgYml0cmF0ZSA9IDA7CiAgSU5UIG1vbm9TdGVyZW9Nb2RlID0gMDsgLyogZGVmYXVsdCBtb25vICovCgogIGlmIChGREthYWNFbmNfR2V0TW9ub1N0ZXJlb01vZGUoY2hhbm5lbE1vZGUpPT1FTF9NT0RFX1NURVJFTykgewogICAgICBtb25vU3RlcmVvTW9kZSA9IDE7CiAgfQoKICBzd2l0Y2goKEFBQ0VOQ19CSVRSQVRFX01PREUpYml0cmF0ZU1vZGUpewogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzE6CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfMjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8zOgogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzQ6CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfNToKICAgIGJpdHJhdGUgPSBjb25maWdUYWJWQlJbYml0cmF0ZU1vZGVdLmNoYW5CaXRyYXRlW21vbm9TdGVyZW9Nb2RlXTsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfSU5WQUxJRDoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0NCUjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1NGUjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0ZGOgogIGRlZmF1bHQ6CiAgICBiaXRyYXRlID0gMDsKICAgIGJyZWFrOwogIH0KCiAgLyogY29udmVydCBjaGFubmVsIGJpdHJhdGUgdG8gb3ZlcmFsbCBiaXRyYXRlKi8KICBiaXRyYXRlICo9IEZES2FhY0VuY19HZXRDaGFubmVsTW9kZUNvbmZpZ3VyYXRpb24oY2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmY7CgogIHJldHVybiBiaXRyYXRlOwp9CgovKioKICogXGJyaWVmICBDb252ZXJ0IGVuY29kZXIgYml0cmVzZXJ2b2lyIHZhbHVlIGZvciB0cmFuc3BvcnQgbGlicmFyeS4KICoKICogXHBhcmFtIGhBYWNFbmMgICAgICAgICAgICAgICBFbmNvZGVyIGhhbmRsZQogKgogKiBccmV0dXJuICBDb3JyZWN0ZWQgYml0cmVzZXJ2b2lyIGxldmVsIHVzZWQgaW4gdHJhbnNwb3J0IGxpYnJhcnkuCiAqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19FbmNCaXRyZXNUb1RwQml0cmVzKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNfRU5DICAgICAgaEFhY0VuYwogICAgICAgICkKewogIElOVCB0cmFuc3BvckJpdHJlc2Vydm9pciA9IDA7CgogIHN3aXRjaCAoaEFhY0VuYy0+Yml0cmF0ZU1vZGUpIHsKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfQ0JSOgogICAgICB0cmFuc3BvckJpdHJlc2Vydm9pciA9IGhBYWNFbmMtPnFjS2VybmVsLT5iaXRSZXNUb3Q7IC8qIGVuY29kZXIgYml0cmVzZXJ2b2lyIGxldmVsICovCiAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfMToKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzI6CiAgICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8zOgogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfNDoKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzU6CiAgICAgIHRyYW5zcG9yQml0cmVzZXJ2b2lyID0gRkRLX0lOVF9NQVg7IC8qIHNpZ25hbCB2YXJpYWJsZSBiaXRyYXRlICovCiAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9GRjoKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfU0ZSOgogICAgICB0cmFuc3BvckJpdHJlc2Vydm9pciA9IDA7ICAgICAgICAgICAvKiBzdXBlciBmcmFtaW5nIGFuZCBmaXhlZCBmcmFtaW5nICovCiAgICAgIGJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHdpdGhvdXQgYml0cmVzZXJ2b2lyIHNpZ25hbGluZyAqLwogICAgZGVmYXVsdDoKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfSU5WQUxJRDoKICAgICAgdHJhbnNwb3JCaXRyZXNlcnZvaXIgPSAwOyAgICAgICAgICAgLyogaW52YWxpZCBjb25maWd1cmF0aW9uKi8KICAgICAgRkRLX0FTU0VSVCgwKTsKICB9CgogIGlmIChoQWFjRW5jLT5jb25maWctPmF1ZGlvTXV4VmVyc2lvbj09MikgewogICAgdHJhbnNwb3JCaXRyZXNlcnZvaXIgPSBNSU5fQlVGU0laRV9QRVJfRUZGX0NIQU4gKiBoQWFjRW5jLT5jaGFubmVsTWFwcGluZy5uQ2hhbm5lbHNFZmY7CiAgfQoKICByZXR1cm4gdHJhbnNwb3JCaXRyZXNlcnZvaXI7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfQWFjSW5pdERlZmF1bHRDb25maWcKICAgICBkZXNjcmlwdGlvbjogIGdpdmVzIHJlYXNvbmFibGUgZGVmYXVsdCBjb25maWd1cmF0aW9uCiAgICAgcmV0dXJuczogICAgICAtLS0KCiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIEZES2FhY0VuY19BYWNJbml0RGVmYXVsdENvbmZpZyhBQUNFTkNfQ09ORklHICpjb25maWcpCnsKICAgIC8qIG1ha2UgdGhlcHJlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBzdHJ1Y3RzIGZsZXhpYmxlICovCiAgICBGREttZW1jbGVhcihjb25maWcsIHNpemVvZihBQUNFTkNfQ09ORklHKSk7CgogICAgLyogZGVmYXVsdCBhbmNpbGxhcnkgKi8KICAgIGNvbmZpZy0+YW5jX1JhdGUgPSAwOyAgICAgICAgIC8qIG5vIGFuY2lsbGFyeSBkYXRhICovCiAgICBjb25maWctPmFuY0RhdGFCaXRSYXRlID0gMDsgICAvKiBubyBhZGRpdGlvbmFsIGNvbnN1bWVkIGJpdHJhdGUgKi8KCiAgICAvKiBkZWZhdWx0IGNvbmZpZ3VyYXRpb25zICovCiAgICBjb25maWctPmJpdFJhdGUgICAgICAgICA9IC0xOyAgICAgICAgICAgICAgICAgICAvKiBiaXRyYXRlIG11c3QgYmUgc2V0Ki8KICAgIGNvbmZpZy0+YXZlcmFnZUJpdHMgICAgID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIGluc3RlYWQgb2YgYml0cmF0ZS9zIHdlIGNhbiBjb25maWd1cmUgYml0cy9zdXBlcmZyYW1lICovCiAgICBjb25maWctPmJpdHJhdGVNb2RlICAgICA9IDA7CiAgICBjb25maWctPmJhbmRXaWR0aCAgICAgICA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBnZXQgYmFuZHdpZHRoIGZyb20gdGFibGUgKi8KICAgIGNvbmZpZy0+dXNlVG5zICAgICAgICAgID0gVE5TX0VOQUJMRV9NQVNLOyAgICAgIC8qIHRucyBlbmFibGVkIGNvbXBsZXRseSAqLwogICAgY29uZmlnLT51c2VQbnMgICAgICAgICAgPSAxOyAgICAgICAgICAgICAgICAgICAgLyogZGVwZW5kaW5nIG9uIGNoYW5uZWxCaXRyYXRlIHRoaXMgbWlnaHQgYmUgc2V0IHRvIDAgbGF0ZXIgKi8KICAgIGNvbmZpZy0+dXNlSVMgICAgICAgICAgID0gMTsgICAgICAgICAgICAgICAgICAgIC8qIEludGVuc2l0eSBTdGVyZW8gQ29uZmlndXJhdGlvbiAqLwogICAgY29uZmlnLT5mcmFtZWxlbmd0aCAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogRnJhbWVzaXplIG5vdCBjb25maWd1cmVkICovCiAgICBjb25maWctPnN5bnRheEZsYWdzICAgICA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBkZWZhdWx0IHN5bnRheCB3aXRoIG5vIHNwZWNpYWxpdGllcyAqLwogICAgY29uZmlnLT5lcENvbmZpZyAgICAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogbm8gRVIgc3ludGF4IC0+IG5vIGFkZGl0aW9uYWwgZXJyb3IgcHJvdGVjdGlvbiAqLwogICAgY29uZmlnLT5uU3ViRnJhbWVzICAgICAgPSAxOyAgICAgICAgICAgICAgICAgICAgLyogZGVmYXVsdCwgbm8gc3ViIGZyYW1lcyAqLwogICAgY29uZmlnLT5jaGFubmVsT3JkZXIgICAgPSBDSF9PUkRFUl9NUEVHOyAgICAgICAgLyogVXNlIE1QRUcgY2hhbm5lbCBvcmRlcmluZy4gKi8KICAgIGNvbmZpZy0+Y2hhbm5lbE1vZGUgICAgID0gTU9ERV9VTktOT1dOOwogICAgY29uZmlnLT5taW5CaXRzUGVyRnJhbWUgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogbWludW0gbnVtYmVyIG9mIGJpdHMgaW4gZWFjaCBBVSAqLwogICAgY29uZmlnLT5tYXhCaXRzUGVyRnJhbWUgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogbWludW0gbnVtYmVyIG9mIGJpdHMgaW4gZWFjaCBBVSAqLwogICAgY29uZmlnLT5iaXRyZXNlcnZvaXIgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogZGVmYXVsdCwgdW5pbml0aWFsaXplZCB2YWx1ZSAqLwogICAgY29uZmlnLT5hdWRpb011eFZlcnNpb24gPSAtMTsgICAgICAgICAgICAgICAgICAgLyogYXVkaW8gbXV4IHZlcnNpb24gbm90IGNvbmZpZ3VyZWQgKi8KCiAgICAvKiBpbml0IHRhYnMgaW4gZml4cG9pbnRfbWF0aCAqLwogICAgSW5pdExkSW50KCk7CiAgICBJbml0SW52U3FydFRhYigpOwp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19PcGVuCiAgICBkZXNjcmlwdGlvbjogIGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgbmV3IGVuY29kZXIgaW5zdGFuY2UKICAgIHJldHVybnM6ICAgICAgZXJyb3IgY29kZQoKICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfT3BlbihIQU5ETEVfQUFDX0VOQyAgKnBoQWFjRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgIG5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgblN1YkZyYW1lcykKewogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzOwogIEFBQ19FTkMgICAgICAgICAgICpoQWFjRW5jID0gTlVMTDsKICBVQ0hBUiAgICAgICAgICAgICAqZHluYW1pY1JBTSA9IE5VTEw7CgogIGlmIChwaEFhY0VuYz09TlVMTCkgewogICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9IQU5ETEU7CiAgfQoKICAvKiBhbGxvY2F0ZSBlbmNvZGVyIHN0cnVjdHVyZSAqLwogIGhBYWNFbmMgPSBHZXRSYW1fYWFjRW5jX0FhY0VuY29kZXIoKTsKICBpZiAoaEFhY0VuYyA9PSBOVUxMKSB7CiAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfTk9fTUVNT1JZOwogICAgZ290byBiYWlsOwogIH0KICBGREttZW1jbGVhcihoQWFjRW5jLCBzaXplb2YoQUFDX0VOQykpOwoKICBoQWFjRW5jLT5keW5hbWljX1JBTSA9IEdldEFBQ2R5bmFtaWNfUkFNKCk7CiAgZHluYW1pY1JBTSA9IChVQ0hBUiopaEFhY0VuYy0+ZHluYW1pY19SQU07CgogIC8qIGFsbG9jYXRlIHRoZSBQc3kgYXVkIFBzeSBPdXQgc3RydWN0dXJlICovCiAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1BzeU5ldygmaEFhY0VuYy0+cHN5S2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkNoYW5uZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxkeW5hbWljUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgIGdvdG8gYmFpbDsKCiAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1BzeU91dE5ldyhoQWFjRW5jLT5wc3lPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuU3ViRnJhbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxkeW5hbWljUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgIGdvdG8gYmFpbDsKCiAgLyogYWxsb2NhdGUgdGhlIFEmQyBPdXQgc3RydWN0dXJlICovCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNPdXROZXcoaEFhY0VuYy0+cWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuU3ViRnJhbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZHluYW1pY1JBTQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIC8qIGFsbG9jYXRlIHRoZSBRJkMga2VybmVsICovCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNOZXcoJmhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuRWxlbWVudHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZHluYW1pY1JBTQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIGhBYWNFbmMtPm1heENoYW5uZWxzID0gbkNoYW5uZWxzOwogIGhBYWNFbmMtPm1heEVsZW1lbnRzID0gbkVsZW1lbnRzOwogIGhBYWNFbmMtPm1heEZyYW1lcyAgID0gblN1YkZyYW1lczsKCmJhaWw6CiAgKnBoQWFjRW5jID0gaEFhY0VuYzsKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCgpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfSW5pdGlhbGl6ZShIQU5ETEVfQUFDX0VOQyAgICAgIGhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFBQ0VOQ19DT05GSUcgICAgICAqY29uZmlnLCAgICAgLyogcHJlLWluaXRpYWxpemVkIGNvbmZpZyBzdHJ1Y3QgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1RSQU5TUE9SVEVOQyBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICAgICAgICAgICAgICAgaW5pdEZsYWdzKQp7CiAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CiAgSU5UIHBzeUJpdHJhdGUsIHRuc01hc2s7IC8vSU5UIHByb2ZpbGUgPSAxOwogIENIQU5ORUxfTUFQUElORyAgICpjbSA9IE5VTEw7CgogIElOVCBxbWJmYWMsIHFidzsKICBGSVhQX0RCTCBtYmZhYywgYndfcmF0aW87CiAgUUNfSU5JVCBxY0luaXQ7CiAgSU5UIGF2ZXJhZ2VCaXRzUGVyRnJhbWUgPSAwOwoKICBpZiAoY29uZmlnPT1OVUxMKQogICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9IQU5ETEU7CgogIC8qKioqKioqKioqKioqKioqKioqIHNhbml0eSBjaGVja3MgKioqKioqKioqKioqKioqKioqKi8KCiAgLyogY2hlY2sgY29uZmlnIHN0cnVjdHVyZSAqLwogIGlmIChjb25maWctPm5DaGFubmVscyAgPCAxIHx8IGNvbmZpZy0+bkNoYW5uZWxzID4gKDgpKSB7CiAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogIH0KCiAgLyogY2hlY2sgc2FtcGxlIHJhdGUgKi8KICBzd2l0Y2ggKGNvbmZpZy0+c2FtcGxlUmF0ZSkKICB7CiAgICBjYXNlIDgwMDA6CiAgICBjYXNlIDExMDI1OgogICAgY2FzZSAxMjAwMDoKICAgIGNhc2UgMTYwMDA6CiAgICBjYXNlIDIyMDUwOgogICAgY2FzZSAyNDAwMDoKICAgIGNhc2UgMzIwMDA6CiAgICBjYXNlIDQ0MTAwOgogICAgY2FzZSA0ODAwMDoKICAgIGNhc2UgNjQwMDA6CiAgICBjYXNlIDg4MjAwOgogICAgY2FzZSA5NjAwMDoKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9TQU1QTElOR1JBVEU7CiAgfQoKICAvKiBiaXRyYXRlIGhhcyB0byBiZSBzZXQgKi8KICBpZiAoY29uZmlnLT5iaXRSYXRlPT0tMSkgewogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9CSVRSQVRFOwogIH0KCiAgLyogY2hlY2sgYml0IHJhdGUgKi8KCiAgaWYgKEZES2FhY0VuY19MaW1pdEJpdHJhdGUoCiAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICBjb25maWctPnNhbXBsZVJhdGUsCiAgICAgICAgICBjb25maWctPmZyYW1lbGVuZ3RoLAogICAgICAgICAgY29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKGNvbmZpZy0+Y2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmYsCiAgICAgICAgICBjb25maWctPmJpdFJhdGUsCiAgICAgICAgICBjb25maWctPmF2ZXJhZ2VCaXRzLAogICAgICAgICAmYXZlcmFnZUJpdHNQZXJGcmFtZSwKICAgICAgICAgIGNvbmZpZy0+Yml0cmF0ZU1vZGUsCiAgICAgICAgICBjb25maWctPm5TdWJGcmFtZXMKICAgICAgICAgICkgIT0gY29uZmlnLT5iaXRSYXRlCiAgICAgICYmICEoKGNvbmZpZy0+Yml0cmF0ZU1vZGU+PTEpICYmIChjb25maWctPmJpdHJhdGVNb2RlPD01KSkKICAgICApCiAgewogICAgcmV0dXJuIEFBQ19FTkNfVU5TVVBQT1JURURfQklUUkFURTsKICB9CgogIGlmIChjb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpIHsKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5TVVBQT1JURURfRVJfRk9STUFUOwogIH0KICBpZiAoY29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX0hDUikgewogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9FUl9GT1JNQVQ7CiAgfQoKICAvKiBjaGVjayBmcmFtZSBsZW5ndGggKi8KICBzd2l0Y2ggKGNvbmZpZy0+ZnJhbWVsZW5ndGgpCiAgewogICAgY2FzZSAxMDI0OgogICAgICBpZiAoIGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfTEQKICAgICAgICB8fCBjb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCApCiAgICAgIHsKICAgICAgICByZXR1cm4gQUFDX0VOQ19JTlZBTElEX0ZSQU1FX0xFTkdUSDsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgNTEyOgogICAgY2FzZSA0ODA6CiAgICAgIGlmICggY29uZmlnLT5hdWRpb09iamVjdFR5cGUgIT0gQU9UX0VSX0FBQ19MRAogICAgICAgICYmIGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlICE9IEFPVF9FUl9BQUNfRUxEICkKICAgICAgewogICAgICAgIHJldHVybiBBQUNfRU5DX0lOVkFMSURfRlJBTUVfTEVOR1RIOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9GUkFNRV9MRU5HVEg7CiAgfQoKICBpZiAoY29uZmlnLT5hbmNfUmF0ZSAhPSAwKSB7CgogICAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0luaXRDaGVja0FuY2lsbGFyeShjb25maWctPmJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+ZnJhbWVsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+YW5jX1JhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNFbmMtPmFuY2lsbGFyeUJpdHNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5zYW1wbGVSYXRlKTsKICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgIGdvdG8gYmFpbDsKCgogICAgIC8qIHVwZGF0ZSBlc3RpbWF0ZWQgY29uc3VtZWQgYml0cmF0ZSAqLwogICAgIGNvbmZpZy0+YW5jRGF0YUJpdFJhdGUgKz0gKCAoaEFhY0VuYy0+YW5jaWxsYXJ5Qml0c1BlckZyYW1lICogY29uZmlnLT5zYW1wbGVSYXRlKSAvIGNvbmZpZy0+ZnJhbWVsZW5ndGggKTsKCiAgfQoKICAvKiBtYXhpbWFsIGFsbG93ZWQgRFNFIGJ5dGVzIGluIGZyYW1lICovCiAgewogIC8qIGZpeHBvaW50IGNhbGN1bGF0aW9uKi8KICBJTlQgcV9yZXMsIGVuY0JpdHJhdGUsIHNjOwogIEZJWFBfREJMIHRtcCA9IGZEaXZOb3JtKGNvbmZpZy0+ZnJhbWVsZW5ndGgsIGNvbmZpZy0+c2FtcGxlUmF0ZSwgJnFfcmVzKTsKICBlbmNCaXRyYXRlID0gKGNvbmZpZy0+Yml0UmF0ZS8qLWNvbmZpZy0+YW5jRGF0YUJpdFJhdGUqLyktIChJTlQpKGNvbmZpZy0+bkNoYW5uZWxzKjgwMDApOwogIHNjID0gQ291bnRMZWFkaW5nQml0cyhlbmNCaXRyYXRlKTsKICBjb25maWctPm1heEFuY0J5dGVzUGVyQVUgPSBGREttaW4oICgyNTYpLCBGREttYXgoMCwoSU5UKShmTXVsdERpdjIodG1wLCAoRklYUF9EQkwpKGVuY0JpdHJhdGU8PHNjKSk+PigtcV9yZXMrc2MtMSszKSkpICk7CiAgfQoKICAvKiBiaW5kIGNvbmZpZyB0byBoQWFjRW5jLT5jb25maWcgKi8KICBoQWFjRW5jLT5jb25maWcgPSBjb25maWc7CgogIC8qIHNldCBoQWFjRW5jLT5iaXRyYXRlTW9kZSAqLwogIGhBYWNFbmMtPmJpdHJhdGVNb2RlID0gKEFBQ0VOQ19CSVRSQVRFX01PREUpY29uZmlnLT5iaXRyYXRlTW9kZTsKCiAgaEFhY0VuYy0+ZW5jb2Rlck1vZGUgPSBjb25maWctPmNoYW5uZWxNb2RlOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Jbml0Q2hhbm5lbE1hcHBpbmcoaEFhY0VuYy0+ZW5jb2Rlck1vZGUsIGNvbmZpZy0+Y2hhbm5lbE9yZGVyLCAmaEFhY0VuYy0+Y2hhbm5lbE1hcHBpbmcpOwogIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgZ290byBiYWlsOwoKICBjbSA9ICZoQWFjRW5jLT5jaGFubmVsTWFwcGluZzsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfRGV0ZXJtaW5lQmFuZFdpZHRoKCZoQWFjRW5jLT5jb25maWctPmJhbmRXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5iYW5kV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+Yml0UmF0ZSAtIGNvbmZpZy0+YW5jRGF0YUJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmJpdHJhdGVNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+ZnJhbWVsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5lbmNvZGVyTW9kZSk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIGhBYWNFbmMtPmJhbmR3aWR0aDkwZEIgPSAoSU5UKWhBYWNFbmMtPmNvbmZpZy0+YmFuZFdpZHRoOwoKICB0bnNNYXNrID0gY29uZmlnLT51c2VUbnMgPyBUTlNfRU5BQkxFX01BU0sgOiAweDA7CiAgcHN5Qml0cmF0ZSA9IGNvbmZpZy0+Yml0UmF0ZSAtIGNvbmZpZy0+YW5jRGF0YUJpdFJhdGU7CgogIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX3BzeUluaXQoaEFhY0VuYy0+cHN5S2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cHN5T3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+bWF4RnJhbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+bWF4Q2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPmF1ZGlvT2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtKTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgIGdvdG8gYmFpbDsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfcHN5TWFpbkluaXQoaEFhY0VuYy0+cHN5S2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPmZyYW1lbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeUJpdHJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG5zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5iYW5kd2lkdGg5MGRCLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlUG5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlSVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5zeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0RmxhZ3MpOwogIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgZ290byBiYWlsOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19RQ091dEluaXQoaEFhY0VuYy0+cWNPdXQsIGhBYWNFbmMtPm1heEZyYW1lcywgY20pOwogIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgZ290byBiYWlsOwoKCgogIHFjSW5pdC5jaGFubmVsTWFwcGluZyAgICAgID0gJmhBYWNFbmMtPmNoYW5uZWxNYXBwaW5nOwogIHFjSW5pdC5zY2VDcGUgICAgICAgICAgICAgID0gMDsKCiAgaWYgKChjb25maWctPmJpdHJhdGVNb2RlPj0xKSAmJiAoY29uZmlnLT5iaXRyYXRlTW9kZTw9NSkpIHsKICAgICAgcWNJbml0LmF2ZXJhZ2VCaXRzICAgICA9IChhdmVyYWdlQml0c1BlckZyYW1lKzcpJn43OwogICAgICBxY0luaXQuYml0UmVzICAgICAgICAgID0gTUlOX0JVRlNJWkVfUEVSX0VGRl9DSEFOKmNtLT5uQ2hhbm5lbHNFZmY7CiAgICAgIHFjSW5pdC5tYXhCaXRzICAgICAgICAgPSBNSU5fQlVGU0laRV9QRVJfRUZGX0NIQU4qY20tPm5DaGFubmVsc0VmZjsKICAgICAgcWNJbml0Lm1heEJpdHMgICAgICAgICA9IChjb25maWctPm1heEJpdHNQZXJGcmFtZSE9LTEpID8gZml4TWluKHFjSW5pdC5tYXhCaXRzLCBjb25maWctPm1heEJpdHNQZXJGcmFtZSkgOiBxY0luaXQubWF4Qml0czsKICAgICAgcWNJbml0Lm1heEJpdHMgICAgICAgICA9IGZpeE1heChxY0luaXQubWF4Qml0cywgKGF2ZXJhZ2VCaXRzUGVyRnJhbWUrNykmfjcpOwogICAgICBxY0luaXQubWluQml0cyAgICAgICAgID0gKGNvbmZpZy0+bWluQml0c1BlckZyYW1lIT0tMSkgPyBjb25maWctPm1pbkJpdHNQZXJGcmFtZSA6IDA7CiAgICAgIHFjSW5pdC5taW5CaXRzICAgICAgICAgPSBmaXhNaW4ocWNJbml0Lm1pbkJpdHMsIGF2ZXJhZ2VCaXRzUGVyRnJhbWUmfjcpOwogIH0KICBlbHNlCiAgewogICAgICBpbnQgbWF4Qml0cmVzOwogICAgICBxY0luaXQuYXZlcmFnZUJpdHMgICAgID0gKGF2ZXJhZ2VCaXRzUGVyRnJhbWUrNykmfjc7CiAgICAgIG1heEJpdHJlcyAgICAgICAgICAgICAgPSAoTUlOX0JVRlNJWkVfUEVSX0VGRl9DSEFOKmNtLT5uQ2hhbm5lbHNFZmYpIC0gcWNJbml0LmF2ZXJhZ2VCaXRzOwogICAgICBxY0luaXQuYml0UmVzICAgICAgICAgID0gKGNvbmZpZy0+Yml0cmVzZXJ2b2lyIT0tMSkgPyBGREttaW4oY29uZmlnLT5iaXRyZXNlcnZvaXIsIG1heEJpdHJlcykgOiBtYXhCaXRyZXM7CgogICAgICBxY0luaXQubWF4Qml0cyAgICAgICAgID0gZml4TWluKE1JTl9CVUZTSVpFX1BFUl9FRkZfQ0hBTipjbS0+bkNoYW5uZWxzRWZmLCAoKGF2ZXJhZ2VCaXRzUGVyRnJhbWUrNykmfjcpK3FjSW5pdC5iaXRSZXMpOwogICAgICBxY0luaXQubWF4Qml0cyAgICAgICAgID0gKGNvbmZpZy0+bWF4Qml0c1BlckZyYW1lIT0tMSkgPyBmaXhNaW4ocWNJbml0Lm1heEJpdHMsIGNvbmZpZy0+bWF4Qml0c1BlckZyYW1lKSA6IHFjSW5pdC5tYXhCaXRzOwogICAgICBxY0luaXQubWF4Qml0cyAgICAgICAgID0gZml4TWluKE1JTl9CVUZTSVpFX1BFUl9FRkZfQ0hBTipjbS0+bkNoYW5uZWxzRWZmLCBmaXhNYXgocWNJbml0Lm1heEJpdHMsIChhdmVyYWdlQml0c1BlckZyYW1lKzcrOCkmfjcpKTsKCiAgICAgIHFjSW5pdC5taW5CaXRzICAgICAgICAgPSBmaXhNYXgoMCwgKChhdmVyYWdlQml0c1BlckZyYW1lLTEpJn43KS1xY0luaXQuYml0UmVzLXRyYW5zcG9ydEVuY19HZXRTdGF0aWNCaXRzKGhUcEVuYywgKChhdmVyYWdlQml0c1BlckZyYW1lKzcpJn43KStxY0luaXQuYml0UmVzKSk7CiAgICAgIHFjSW5pdC5taW5CaXRzICAgICAgICAgPSAoY29uZmlnLT5taW5CaXRzUGVyRnJhbWUhPS0xKSA/IGZpeE1heChxY0luaXQubWluQml0cywgY29uZmlnLT5taW5CaXRzUGVyRnJhbWUpIDogcWNJbml0Lm1pbkJpdHM7CiAgICAgIHFjSW5pdC5taW5CaXRzICAgICAgICAgPSBmaXhNaW4ocWNJbml0Lm1pbkJpdHMsIChhdmVyYWdlQml0c1BlckZyYW1lIC0gdHJhbnNwb3J0RW5jX0dldFN0YXRpY0JpdHMoaFRwRW5jLCBxY0luaXQubWF4Qml0cykpJn43KTsKICB9CgogIHFjSW5pdC5zYW1wbGVSYXRlICAgICAgICAgID0gY29uZmlnLT5zYW1wbGVSYXRlOwogIHFjSW5pdC5hZHZhbmNlZEJpdHNUb1BlICAgID0gaXNMb3dEZWxheShjb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgPyAxIDogMCA7CiAgcWNJbml0Lm5TdWJGcmFtZXMgICAgICAgICAgPSBjb25maWctPm5TdWJGcmFtZXM7CiAgcWNJbml0LnBhZGRpbmcucGFkZGluZ1Jlc3QgPSBjb25maWctPnNhbXBsZVJhdGU7CgogIC8qIENhbGMgbWVhblBlOiBxY0luaXQubWVhblBlID0gMTAuMGYgKiBGUkFNRV9MRU5fTE9ORyAqIGhBYWNFbmMtPmJhbmR3aWR0aDkwZEIvKGNvbmZpZy0+c2FtcGxlUmF0ZS8yLjBmKTsgKi8KICBid19yYXRpbyA9IGZEaXZOb3JtKChGSVhQX0RCTCkoMTAqY29uZmlnLT5mcmFtZWxlbmd0aCpoQWFjRW5jLT5iYW5kd2lkdGg5MGRCKSwgKEZJWFBfREJMKShjb25maWctPnNhbXBsZVJhdGUpLCAmcWJ3KTsKICBxY0luaXQubWVhblBlID0gRkRLbWF4KChJTlQpc2NhbGVWYWx1ZShid19yYXRpbywgcWJ3KzEtKERGUkFDVF9CSVRTLTEpKSwgMSk7CgogIC8qIENhbGMgbWF4Qml0RmFjICovCiAgbWJmYWMgPSBmRGl2Tm9ybSgoTUlOX0JVRlNJWkVfUEVSX0VGRl9DSEFOLTc0NCkqY20tPm5DaGFubmVsc0VmZiwgcWNJbml0LmF2ZXJhZ2VCaXRzL3FjSW5pdC5uU3ViRnJhbWVzLCAmcW1iZmFjKTsKICBxbWJmYWMgPSBERlJBQ1RfQklUUy0xLXFtYmZhYzsKICBxY0luaXQubWF4Qml0RmFjID0gKHFtYmZhYyA+IDI0KSA/IChtYmZhYyA+PiAocW1iZmFjIC0gMjQpKToobWJmYWMgPDwgKDI0IC0gcW1iZmFjKSk7CgogIHN3aXRjaChjb25maWctPmJpdHJhdGVNb2RlKXsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0NCUjoKICAgIHFjSW5pdC5iaXRyYXRlTW9kZSA9IFFDREFUQV9CUl9NT0RFX0NCUjsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzE6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9WQlJfMTsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzI6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9WQlJfMjsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzM6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9WQlJfMzsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzQ6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9WQlJfNDsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzU6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9WQlJfNTsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfU0ZSOgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfU0ZSOwogICAgYnJlYWs7CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9GRjoKICAgIHFjSW5pdC5iaXRyYXRlTW9kZSA9IFFDREFUQV9CUl9NT0RFX0ZGOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEVycm9yU3RhdHVzID0gQUFDX0VOQ19VTlNVUFBPUlRFRF9CSVRSQVRFX01PREU7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBxY0luaXQuaW52UXVhbnQgPSAoY29uZmlnLT51c2VSZXF1YW50KT8yOjA7CgogIC8qIG1heEl0ZXJhdGlvbnMgc2hvdWxkIGJlIHNldCB0byB0aGUgbWF4aW11bSBudW1iZXIgb2YgcmVxdWFudGl6YXRpb24gaXRlcmF0aW9ucyB0aGF0IGFyZQogICAqIGFsbG93ZWQgYmVmb3JlIHRoZSBjcmFzaCByZWNvdmVyeSBmdW5jdGlvbmFsaXR5IGlzIGFjdGl2YXRlZC4gVGhpcyBzZXR0aW5nIHNob3VsZCBiZSBhZGp1c3RlZAogICAqIHRvIHRoZSBwcm9jZXNzaW5nIHBvd2VyIGF2YWlsYWJsZSwgaS5lLiB0byB0aGUgcHJvY2Vzc2luZyBwb3dlciBoZWFkcm9vbSBpbiBvbmUgZnJhbWUgdGhhdCBpcwogICAqIHN0aWxsIGxlZnQgYWZ0ZXIgbm9ybWFsIGVuY29kaW5nIHdpdGhvdXQgcmVxdWFudGl6YXRpb24uIFBsZWFzZSBub3RlIHRoYXQgaWYgYWN0aXZhdGVkIHRoaXMKICAgKiBmdW5jdGlvbmFsaXR5IGlzIHVzZWQgbW9zdCBsaWtlbHkgb25seSBpbiBjYXNlcyB3aGVyZSB0aGUgZW5jb2RlciBpcyBvcGVyYXRpbmcgYmV5b25kCiAgICogcmVjb21tZW5kZWQgc2V0dGluZ3MsIGkuZS4gdGhlIGF1ZGlvIHF1YWxpdHkgaXMgc3Vib3B0aW1hbCBhbnl3YXkuIEFjdGl2YXRpbmcgdGhlIGNyYXNoCiAgICogcmVjb3ZlcnkgZG9lcyBub3QgZnVydGhlciByZWR1Y2UgYXVkaW8gcXVhbGl0eSBzaWduaWZpY2FudGx5IGluIHRoZXNlIGNhc2VzLiAqLwogIGlmICggKGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfTEQpIHx8IChjb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCkgKSB7CiAgICBxY0luaXQubWF4SXRlcmF0aW9ucyA9IDI7CiAgfQogIGVsc2UKICB7CiAgICBxY0luaXQubWF4SXRlcmF0aW9ucyA9IDU7CiAgfQoKICBxY0luaXQuYml0cmF0ZSA9IGNvbmZpZy0+Yml0UmF0ZSAtIGNvbmZpZy0+YW5jRGF0YUJpdFJhdGU7CgogIHFjSW5pdC5zdGF0aWNCaXRzID0gdHJhbnNwb3J0RW5jX0dldFN0YXRpY0JpdHMoaFRwRW5jLCBxY0luaXQuYXZlcmFnZUJpdHMvcWNJbml0Lm5TdWJGcmFtZXMpOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19RQ0luaXQoaEFhY0VuYy0+cWNLZXJuZWwsICZxY0luaXQpOwogIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgZ290byBiYWlsOwoKICBoQWFjRW5jLT5hb3QgPSBoQWFjRW5jLT5jb25maWctPmF1ZGlvT2JqZWN0VHlwZTsKCiAgLyogY29tbW9uIHRoaW5ncyAqLwoKICByZXR1cm4gQUFDX0VOQ19PSzsKCmJhaWw6CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfRW5jb2RlRnJhbWUKICAgIGRlc2NyaXB0aW9uOiAgZW5jb2RlcyBvbmUgZnJhbWUKICAgIHJldHVybnM6ICAgICAgZXJyb3IgY29kZQoKICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfRW5jb2RlRnJhbWUoIEhBTkRMRV9BQUNfRU5DICAgICAgIGhBYWNFbmMsICAgICAgICAgIC8qIGVuY29kZXIgaGFuZGxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1RSQU5TUE9SVEVOQyAgaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00qIFJFU1RSSUNUICAgIGlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCogICAgICAgICAgICAgICAgIG5PdXRCeXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQUNFTkNfRVhUX1BBWUxPQUQgICBleHRQYXlsb2FkW01BWF9UT1RBTF9FWFRfUEFZTE9BRFNdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogICAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CiAgICBpbnQgICAgZWwsIG4sIGM9MDsKICAgIFVDSEFSICBleHRQYXlsb2FkVXNlZFtNQVhfVE9UQUxfRVhUX1BBWUxPQURTXTsKCiAgICBDSEFOTkVMX01BUFBJTkcgKmNtICAgICAgPSAmaEFhY0VuYy0+Y2hhbm5lbE1hcHBpbmc7CgoKCiAgICBQU1lfT1VUICpwc3lPdXQgPSBoQWFjRW5jLT5wc3lPdXRbY107CiAgICBRQ19PVVQgICpxY091dCAgPSBoQWFjRW5jLT5xY091dFtjXTsKCiAgICBGREttZW1jbGVhcihleHRQYXlsb2FkVXNlZCwgTUFYX1RPVEFMX0VYVF9QQVlMT0FEUyAqIHNpemVvZihVQ0hBUikpOwoKICAgIHFjT3V0LT5lbGVtZW50RXh0Qml0cyA9IDA7IC8qIHN1bSB1cCBhbGwgZXh0ZW5kZWQgYml0IG9mIGVhY2ggZWxlbWVudCAqLwogICAgcWNPdXQtPnN0YXRpY0JpdHMgICAgID0gMDsgLyogc3VtIHVwIHNpZGUgaW5mbyBiaXRzIG9mIGVhY2ggZWxlbWVudCAqLwogICAgcWNPdXQtPnRvdGFsTm9SZWRQZSAgID0gMDsgLyogc3VtIHVwIFBFICovCgogICAgLyogYWR2YW5jZSBwc3ljaG9hY291c3RpY3MgKi8KICAgIGZvciAoZWw9MDsgZWw8Y20tPm5FbGVtZW50czsgZWwrKykgewogICAgICAgIEVMRU1FTlRfSU5GTyBlbEluZm8gPSBjbS0+ZWxJbmZvW2VsXTsKCiAgICAgICAgaWYgKCAoZWxJbmZvLmVsVHlwZSA9PSBJRF9TQ0UpCiAgICAgICAgICB8fCAoZWxJbmZvLmVsVHlwZSA9PSBJRF9DUEUpCiAgICAgICAgICB8fCAoZWxJbmZvLmVsVHlwZSA9PSBJRF9MRkUpICkKICAgICAgICB7CiAgICAgICAgICAgIGludCBjaDsKCiAgICAgICAgICAgIC8qIHVwZGF0ZSBwb2ludGVyISovCiAgICAgICAgICAgIGZvcihjaD0wO2NoPGVsSW5mby5uQ2hhbm5lbHNJbkVsO2NoKyspIHsKICAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAqcHN5T3V0Q2hhbiA9IHBzeU91dC0+cHN5T3V0RWxlbWVudFtlbF0tPnBzeU91dENoYW5uZWxbY2hdOwogICAgICAgICAgICAgICAgUUNfT1VUX0NIQU5ORUwgICpxY091dENoYW4gPSBxY091dC0+cWNFbGVtZW50W2VsXS0+cWNPdXRDaGFubmVsW2NoXTsKCiAgICAgICAgICAgICAgICBwc3lPdXRDaGFuLT5tZGN0U3BlY3RydW0gICAgICAgPSBxY091dENoYW4tPm1kY3RTcGVjdHJ1bTsKICAgICAgICAgICAgICAgIHBzeU91dENoYW4tPnNmYlNwcmVhZEVuZXJneSAgPSBxY091dENoYW4tPnNmYlNwcmVhZEVuZXJneTsKICAgICAgICAgICAgICAgIHBzeU91dENoYW4tPnNmYkVuZXJneSAgICAgICAgICA9IHFjT3V0Q2hhbi0+c2ZiRW5lcmd5OwogICAgICAgICAgICAgICAgcHN5T3V0Q2hhbi0+c2ZiRW5lcmd5TGREYXRhICAgID0gcWNPdXRDaGFuLT5zZmJFbmVyZ3lMZERhdGE7CiAgICAgICAgICAgICAgICBwc3lPdXRDaGFuLT5zZmJNaW5TbnJMZERhdGEgICAgPSBxY091dENoYW4tPnNmYk1pblNuckxkRGF0YTsKICAgICAgICAgICAgICAgIHBzeU91dENoYW4tPnNmYlRocmVzaG9sZExkRGF0YSA9IHFjT3V0Q2hhbi0+c2ZiVGhyZXNob2xkTGREYXRhOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgRkRLYWFjRW5jX3BzeU1haW4oZWxJbmZvLm5DaGFubmVsc0luRWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnBzeUtlcm5lbC0+cHN5RWxlbWVudFtlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnBzeUtlcm5lbC0+cHN5RHluYW1pYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cHN5S2VybmVsLT5wc3lDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXQtPnBzeU91dEVsZW1lbnRbZWxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20tPmVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbS0+bkNoYW5uZWxzCgogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAvKiBGb3JtRmFjdG9yLCBQZSBhbmQgc3RhdGljQml0RGVtYW5kIGNhbGN1bGF0aW9uICovCiAgICAgICAgICAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1FDTWFpblByZXBhcmUoJmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwtPmhBZGpUaHItPmFkalRoclN0YXRlRWxlbVtlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dC0+cHN5T3V0RWxlbWVudFtlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0LT5xY0VsZW1lbnRbZWxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5hb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+c3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcpOwoKICAgICAgICAgICAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICAgICAgICAgICAgcmV0dXJuIEVycm9yU3RhdHVzOwoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dEJpdHNVc2VkID0gMDsKICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0tPm5FeHRlbnNpb25zID0gMDsKICAgICAgICAgICAgLyogcmVzZXQgZXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgICAgICAgICAgRkRLbWVtY2xlYXIoJnFjT3V0LT5xY0VsZW1lbnRbZWxdLT5leHRlbnNpb24sICgxKSpzaXplb2YoUUNfT1VUX0VYVEVOU0lPTikpOwoKICAgICAgICAgICAgZm9yICggbiA9IDA7IG4gPCBNQVhfVE9UQUxfRVhUX1BBWUxPQURTOyBuKysgKSB7CiAgICAgICAgICAgICAgICBpZiAoICFleHRQYXlsb2FkVXNlZFtuXQogICAgICAgICAgICAgICAgICAmJiAoZXh0UGF5bG9hZFtuXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID09IGVsKQogICAgICAgICAgICAgICAgICAmJiAoZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZSA+IDApCiAgICAgICAgICAgICAgICAgICYmIChleHRQYXlsb2FkW25dLnBEYXRhICE9IE5VTEwpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgaWR4ID0gcWNPdXQtPnFjRWxlbWVudFtlbF0tPm5FeHRlbnNpb25zKys7CgogICAgICAgICAgICAgICAgICAgIHFjT3V0LT5xY0VsZW1lbnRbZWxdLT5leHRlbnNpb25baWR4XS50eXBlICAgICAgICAgPSBleHRQYXlsb2FkW25dLmRhdGFUeXBlOyAgIC8qIFBlcmZvcm0gYSBzYW5pdHkgY2hlY2sgb24gdGhlIHR5cGU/ICovCiAgICAgICAgICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dGVuc2lvbltpZHhdLm5QYXlsb2FkQml0cyA9IGV4dFBheWxvYWRbbl0uZGF0YVNpemU7CiAgICAgICAgICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dGVuc2lvbltpZHhdLnBQYXlsb2FkID0gZXh0UGF5bG9hZFtuXS5wRGF0YTsKICAgICAgICAgICAgICAgICAgICAvKiBOb3cgYXNrIHRoZSBiaXRzdHJlYW0gZW5jb2RlciBob3cgbWFueSBiaXRzIHdlIG5lZWQgdG8gZW5jb2RlIHRoZSBkYXRhIHdpdGggdGhlIGN1cnJlbnQgYml0c3RyZWFtIHN5bnRheDogKi8KICAgICAgICAgICAgICAgICAgICBxY091dC0+cWNFbGVtZW50W2VsXS0+ZXh0Qml0c1VzZWQgKz0KICAgICAgICAgICAgICAgICAgICAgICAgICBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25EYXRhKCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnFjT3V0LT5xY0VsZW1lbnRbZWxdLT5leHRlbnNpb25baWR4XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+c3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+YW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcgKTsKICAgICAgICAgICAgICAgICAgICBleHRQYXlsb2FkVXNlZFtuXSA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIHN1bSB1cCBleHRlbnNpb24gYW5kIHN0YXRpYyBiaXRzIGZvciBhbGwgY2hhbm5lbCBlbGVtZW50cyAqLwogICAgICAgICAgICBxY091dC0+ZWxlbWVudEV4dEJpdHMgKz0gcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dEJpdHNVc2VkOwogICAgICAgICAgICBxY091dC0+c3RhdGljQml0cyAgICs9IHFjT3V0LT5xY0VsZW1lbnRbZWxdLT5zdGF0aWNCaXRzVXNlZDsKCiAgICAgICAgICAgIC8qIHN1bSB1cCBwZSAqLwogICAgICAgICAgICBxY091dC0+dG90YWxOb1JlZFBlICs9IHFjT3V0LT5xY0VsZW1lbnRbZWxdLT5wZURhdGEucGU7CiAgICAgICAgfQogICAgfQoKICAgIHFjT3V0LT5uRXh0ZW5zaW9ucyAgID0gMDsKICAgIHFjT3V0LT5nbG9iYWxFeHRCaXRzID0gMDsKCiAgICAvKiByZXNldCBleHRlbnNpb24gcGF5bG9hZCAqLwogICAgRkRLbWVtY2xlYXIoJnFjT3V0LT5leHRlbnNpb24sICgyKzIpKnNpemVvZihRQ19PVVRfRVhURU5TSU9OKSk7CgogICAgLyogQWRkIGV4dGVuc2lvbiBwYXlsb2FkIG5vdCBhc3NpZ25lZCB0byBhbiBjaGFubmVsIGVsZW1lbnQKICAgICAgKEFuY2lsbGFyeSBkYXRhIGlzIHRoZSBvbmx5IHN1cHBvcnRlZCB0eXBlIHVwIHRvIG5vdykgKi8KICAgIGZvciAoIG4gPSAwOyBuIDwgTUFYX1RPVEFMX0VYVF9QQVlMT0FEUzsgbisrICkgewogICAgICAgIGlmICggIWV4dFBheWxvYWRVc2VkW25dCiAgICAgICAgICAmJiAoZXh0UGF5bG9hZFtuXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID09IC0xKQogICAgICAgICAgJiYgKGV4dFBheWxvYWRbbl0ucERhdGEgIT0gTlVMTCkgKQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBwYXlsb2FkQml0cyA9IDA7CgogICAgICAgICAgICBpZiAoZXh0UGF5bG9hZFtuXS5kYXRhVHlwZSA9PSBFWFRfREFUQV9FTEVNRU5UKSB7CiAgICAgICAgICAgICAgICBpZiAoaEFhY0VuYy0+YW5jaWxsYXJ5Qml0c1BlckZyYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZ3JhbnRlZCBmcmFtZSBkc2UgYml0cmF0ZSAqLwogICAgICAgICAgICAgICAgICAgIHBheWxvYWRCaXRzID0gaEFhY0VuYy0+YW5jaWxsYXJ5Qml0c1BlckZyYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogd3JpdGUgYW5jIGRhdGEgaWYgYml0cmF0ZSBjb25zdHJhaW50IGZ1bGZpbGxlZCAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZT4+MykgPD0gaEFhY0VuYy0+Y29uZmlnLT5tYXhBbmNCeXRlc1BlckFVKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWRCaXRzID0gZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwYXlsb2FkQml0cyA9IGZpeE1pbiggZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZSwgcGF5bG9hZEJpdHMgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBheWxvYWRCaXRzID0gZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHBheWxvYWRCaXRzID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGlkeCA9IHFjT3V0LT5uRXh0ZW5zaW9ucysrOwoKICAgICAgICAgICAgICAgIHFjT3V0LT5leHRlbnNpb25baWR4XS50eXBlICAgICAgICAgPSBleHRQYXlsb2FkW25dLmRhdGFUeXBlOyAgIC8qIFBlcmZvcm0gYSBzYW5pdHkgY2hlY2sgb24gdGhlIHR5cGU/ICovCiAgICAgICAgICAgICAgICBxY091dC0+ZXh0ZW5zaW9uW2lkeF0ublBheWxvYWRCaXRzID0gcGF5bG9hZEJpdHM7CiAgICAgICAgICAgICAgICBxY091dC0+ZXh0ZW5zaW9uW2lkeF0ucFBheWxvYWQgPSBleHRQYXlsb2FkW25dLnBEYXRhOwogICAgICAgICAgICAgICAgLyogTm93IGFzayB0aGUgYml0c3RyZWFtIGVuY29kZXIgaG93IG1hbnkgYml0cyB3ZSBuZWVkIHRvIGVuY29kZSB0aGUgZGF0YSB3aXRoIHRoZSBjdXJyZW50IGJpdHN0cmVhbSBzeW50YXg6ICovCiAgICAgICAgICAgICAgICBxY091dC0+Z2xvYmFsRXh0Qml0cyArPSBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25EYXRhKCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXQtPmV4dGVuc2lvbltpZHhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+c3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5hb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPmVwQ29uZmlnICk7CiAgICAgICAgICAgICAgICBpZiAoZXh0UGF5bG9hZFtuXS5kYXRhVHlwZSA9PSBFWFRfREFUQV9FTEVNRU5UKSB7CiAgICAgICAgICAgICAgICAgICAgLyogc3Vic3RyYWN0IHRoZSBwcm9jZXNzZWQgYml0cyAqLwogICAgICAgICAgICAgICAgICAgIGV4dFBheWxvYWRbbl0uZGF0YVNpemUgLT0gcGF5bG9hZEJpdHM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBleHRQYXlsb2FkVXNlZFtuXSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKCEoaEFhY0VuYy0+Y29uZmlnLT5zeW50YXhGbGFncyAmIChBQ19TQ0FMQUJMRXxBQ19FUikpKSB7CiAgICAgIHFjT3V0LT5nbG9iYWxFeHRCaXRzICs9IEVMX0lEX0JJVFM7ICAvKiBhZGQgYml0cyBmb3IgSURfRU5EICovCiAgICB9CgogICAgLyogYnVpbGQgYml0c3RyZWFtIGFsbCBuU3ViRnJhbWVzICovCiAgICB7CiAgICAgICAgSU5UIHRvdGFsQml0cyAgICA9IDA7ICAgLyogVG90YWwgQVUgYml0cyAqLzsKICAgICAgICBJTlQgYXZnVG90YWxCaXRzID0gMDsKCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIC8qIEdldCBhdmVyYWdlIHRvdGFsIGJpdHMgKi8KICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgewogICAgICAgICAgICAvKiBmcmFtZSB3aXNlIGJpdHJhdGUgYWRhcHRpb24gKi8KICAgICAgICAgICAgRkRLYWFjRW5jX0FkanVzdEJpdHJhdGUoaEFhY0VuYy0+cWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdmdUb3RhbEJpdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+Yml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPmZyYW1lbGVuZ3RoKTsKCiAgICAgICAgICAgIC8qIGFkanVzdCBzdXBlciBmcmFtZSBiaXRyYXRlICovCiAgICAgICAgICAgIGF2Z1RvdGFsQml0cyAqPSBoQWFjRW5jLT5jb25maWctPm5TdWJGcmFtZXM7CiAgICAgICAgfQoKICAgICAgICAvKiBNYWtlIGZpcnN0IGVzdGltYXRlIG9mIHRyYW5zcG9ydCBoZWFkZXIgb3ZlcmhlYWQuCiAgICAgICAgICAgVGFrZSBtYXhpbXVtIHBvc3NpYmxlIGZyYW1lIHNpemUgaW50byBhY2NvdW50IHRvIHByZXZlbnQgYml0cmVzZXJ2b2lyIHVuZGVycnVuLiAqLwogICAgICAgIGhBYWNFbmMtPnFjS2VybmVsLT5nbG9iSGRyQml0cyA9IHRyYW5zcG9ydEVuY19HZXRTdGF0aWNCaXRzKGhUcEVuYywgYXZnVG90YWxCaXRzICsgaEFhY0VuYy0+cWNLZXJuZWwtPmJpdFJlc1RvdCk7CgoKICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiAgICAgICAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNNYWluKGhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5wc3lPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmdUb3RhbEJpdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5zeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5lcENvbmZpZyk7CgogICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgICAgICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfdXBkYXRlRmlsbEJpdHMoY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwtPmVsZW1lbnRCaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjT3V0KTsKICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgICAgICAgcmV0dXJuIEVycm9yU3RhdHVzOwoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19GaW5hbGl6ZUJpdENvbnN1bXB0aW9uKGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0LT5xY0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPnN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcpOwogICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICB0b3RhbEJpdHMgKz0gcWNPdXQtPnRvdGFsQml0czsKCgogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICBGREthYWNFbmNfdXBkYXRlQml0cmVzKGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5xY091dCk7CgogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiAgICAgICAgLyogZm9yICggYWxsIHN1YiBmcmFtZXMgKSAuLi4gKi8KICAgICAgICAgICAgICAvKiB3cml0ZSBiaXRzdHJlYW0gaGVhZGVyICovCiAgICAgICAgICAgICAgdHJhbnNwb3J0RW5jX1dyaXRlQWNjZXNzVW5pdCgKICAgICAgICAgICAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgdG90YWxCaXRzLAogICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19FbmNCaXRyZXNUb1RwQml0cmVzKGhBYWNFbmMpLAogICAgICAgICAgICAgICAgICAgIGNtLT5uQ2hhbm5lbHNFZmYpOwoKICAgICAgICAgICAgICAvKiB3cml0ZSBiaXRzdHJlYW0gKi8KICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Xcml0ZUJpdHN0cmVhbSgKICAgICAgICAgICAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgY20sCiAgICAgICAgICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgcHN5T3V0LAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPnN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcpOwoKICAgICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKCiAgICAgICAgICAgICAgLyogdHJhbnNwb3J0RW5jX0VuZEFjY2Vzc1VuaXQoKSBpcyBiZWluZyBjYWxsZWQgaW5zaWRlIEZES2FhY0VuY19Xcml0ZUJpdHN0cmVhbSgpICovCiAgICAgICAgICAgICAgdHJhbnNwb3J0RW5jX0dldEZyYW1lKGhUcEVuYywgbk91dEJ5dGVzKTsKCiAgICB9IC8qIC1lbmQtIGlmIChjdXJGcmFtZT09aEFhY0VuYy0+cWNLZXJuZWwtPm5TdWJGcmFtZXMpICovCgoKICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfQ2xvc2UKICAgIGRlc2NyaXB0aW9uOiBkZWxldGUgZW5jb2RlciBpbnN0YW5jZQogICAgcmV0dXJuczoKCiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnZvaWQgRkRLYWFjRW5jX0Nsb3NlKCBIQU5ETEVfQUFDX0VOQyogIHBoQWFjRW5jKSAgIC8qIGVuY29kZXIgaGFuZGxlICovCnsKICAgIGlmICgqcGhBYWNFbmMgPT0gTlVMTCkgewogICAgICByZXR1cm47CiAgICB9CiAgICBBQUNfRU5DICpoQWFjRW5jID0gKEFBQ19FTkMqKSpwaEFhY0VuYzsKCiAgIGlmIChoQWFjRW5jLT5keW5hbWljX1JBTSAhPSBOVUxMKQogICAgICAgRnJlZUFBQ2R5bmFtaWNfUkFNKCZoQWFjRW5jLT5keW5hbWljX1JBTSk7CgogICAgRkRLYWFjRW5jX1BzeUNsb3NlKCZoQWFjRW5jLT5wc3lLZXJuZWwsaEFhY0VuYy0+cHN5T3V0KTsKCiAgICBGREthYWNFbmNfUUNDbG9zZSgmaEFhY0VuYy0+cWNLZXJuZWwsIGhBYWNFbmMtPnFjT3V0KTsKCiAgICBGcmVlUmFtX2FhY0VuY19BYWNFbmNvZGVyKHBoQWFjRW5jKTsKfQoKCi8qIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbiB0aGlzIHNvdXJjZSBmaWxlIG9ubHkgZm9yIGNvbnZlbmllbmNlIGFuZCAqLwovKiBuZWVkIG5vdCBiZSB2aXNpYmxlIG91dHNpZGUgb2YgYSBwb3NzaWJsZSBlbmNvZGVyIGxpYnJhcnkuICovCgovKiBiYXNpYyBkZWZpbmVzIGZvciBhbmNpbGxhcnkgZGF0YSAqLwojZGVmaW5lIE1BWF9BTkNSQVRFIDE5MjAwICAgICAgICAgICAgLyogYW5jaWxsYXJ5IHJhdGUgPj0gMTkyMDAgaXNuJ3QgdmFsaWQgKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZnVuY3Rpb25uYW1lOiAgRkRLYWFjRW5jX0luaXRDaGVja0FuY2lsbGFyeQogICAgZGVzY3JpcHRpb246ICAgaW5pdGlhbGl6ZSBhbmQgY2hlY2sgYW5jaWxsYXJ5IGRhdGEgc3RydWN0CiAgICByZXR1cm46ICAgICAgICBpZiBzdWNjZXNzIG9yIE5VTEwgaWYgZXJyb3IKCiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIEFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19Jbml0Q2hlY2tBbmNpbGxhcnkoSU5UIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBmcmFtZWxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGFuY2lsbGFyeVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqYW5jaWxsYXJ5Qml0c1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSkKewogIElOVCBkaWZmVG9CeXRlQWxpZ247CgogIC8qIGRvbid0IHVzZSBuZWdhdGl2ZSBhbmNpbGxhcnkgcmF0ZXMgKi8KICBpZiAoIGFuY2lsbGFyeVJhdGUgPCAtMSApCiAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9BTkNfQklUUkFURTsKCiAgLyogY2hlY2sgaWYgYW5jaWxsYXJ5IHJhdGUgaXMgb2sgKi8KICBpZiAoIChhbmNpbGxhcnlSYXRlICE9ICgtMSkpICYmIChhbmNpbGxhcnlSYXRlICE9IDApICkgewogICAgLyogYW5jUmF0ZSA8PSAxNSUgb2YgYml0cmF0ZSAmJiBhbmNSYXRlIDwgMTkyMDAgKi8KICAgIGlmICggKCBhbmNpbGxhcnlSYXRlID49IE1BWF9BTkNSQVRFICkgfHwKICAgICAgICAgKCAoYW5jaWxsYXJ5UmF0ZSAqIDIwKSA+IChiaXRSYXRlICogMykgKSApIHsKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5TVVBQT1JURURfQU5DX0JJVFJBVEU7CiAgICB9CiAgfQogIGVsc2UgaWYgKGFuY2lsbGFyeVJhdGUgPT0gLTEpIHsKICAgIC8qIGlmIG5vIHNwZWNpYWwgYW5jUmF0ZSBpcyByZXF1ZXN0ZWQgYnV0IGEgYW5jaWxsYXJ5IGZpbGUgaXMKICAgICAgIHN0YXRlZCwgdGhlbiBnZW5lcmF0ZSBhIGFuY2lsbGFyeSByYXRlIG1hdGNoaW5nIHRvIHRoZSBiaXRyYXRlICovCiAgICBpZiAoYml0UmF0ZSA+PSAoTUFYX0FOQ1JBVEUgKiAxMCkpIHsKICAgICAgLyogYW5jaWxsYXJ5IHJhdGUgaXMgMTkxOTkgKi8KICAgICAgYW5jaWxsYXJ5UmF0ZSA9IChNQVhfQU5DUkFURSAtIDEpOwogICAgfQogICAgZWxzZSB7IC8qIDEwJSBvZiBiaXRyYXRlICovCiAgICAgIGFuY2lsbGFyeVJhdGUgPSBiaXRSYXRlIC8gMTA7CiAgICB9CiAgfQoKICAvKiBtYWtlIGFuY2lsbGFyeUJpdHNQZXJGcmFtZSBieXRlIGFsaWduICovCiAgKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSA9IChhbmNpbGxhcnlSYXRlICogZnJhbWVsZW5ndGggKSAvIHNhbXBsZVJhdGU7CiAgZGlmZlRvQnl0ZUFsaWduID0gKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSAlIDg7CiAgKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSA9ICphbmNpbGxhcnlCaXRzUGVyRnJhbWUgLSBkaWZmVG9CeXRlQWxpZ247CgogIHJldHVybiBBQUNfRU5DX09LOwp9Cg==