Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gV2VybmVyCiAgIGNvbnRlbnRzL2Rlc2NyaXB0aW9uOiBRdWFudGl6aW5nICYgY29kaW5nCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAicWNfbWFpbi5oIgojaW5jbHVkZSAicXVhbnRpemUuaCIKI2luY2x1ZGUgImludGVyZmFjZS5oIgojaW5jbHVkZSAiYWRqX3Roci5oIgojaW5jbHVkZSAic2ZfZXN0aW0uaCIKI2luY2x1ZGUgImJpdF9jbnQuaCIKI2luY2x1ZGUgImR5bl9iaXRzLmgiCiNpbmNsdWRlICJjaGFubmVsX21hcC5oIgojaW5jbHVkZSAiYWFjRW5jX3JhbS5oIgoKI2luY2x1ZGUgImdlbmVyaWNTdGRzLmgiCgoKdHlwZWRlZiBzdHJ1Y3QgewogIFFDREFUQV9CUl9NT0RFIGJpdHJhdGVNb2RlOwogIExPTkcgdmJyUXVhbEZhY3RvcjsKfSBUQUJfVkJSX1FVQUxfRkFDVE9SOwoKc3RhdGljIGNvbnN0IFRBQl9WQlJfUVVBTF9GQUNUT1IgdGFibGVWYnJRdWFsRmFjdG9yW10gPSB7CiAge1FDREFUQV9CUl9NT0RFX1ZCUl8xLCBGTDJGWENPTlNUX0RCTCgwLjE2MGYpfSwgLyogMzIga2JwcyBtb25vICAgQUFDLUxDICsgU0JSICsgUFMgKi8KICB7UUNEQVRBX0JSX01PREVfVkJSXzIsIEZMMkZYQ09OU1RfREJMKDAuMTQ4Zil9LCAvKiA2NCBrYnBzIHN0ZXJlbyBBQUMtTEMgKyBTQlIgICAgICAqLwogIHtRQ0RBVEFfQlJfTU9ERV9WQlJfMywgRkwyRlhDT05TVF9EQkwoMC4xMzVmKX0sIC8qIDgwIC0gOTYga2JwcyBzdGVyZW8gQUFDLUxDICAgICAgICovCiAge1FDREFUQV9CUl9NT0RFX1ZCUl80LCBGTDJGWENPTlNUX0RCTCgwLjExMWYpfSwgLyogMTI4IGticHMgc3RlcmVvIEFBQy1MQyAgICAgICAgICAgKi8KICB7UUNEQVRBX0JSX01PREVfVkJSXzUsIEZMMkZYQ09OU1RfREJMKDAuMDcwZil9ICAvKiAxOTIga2JwcyBzdGVyZW8gQUFDLUxDICAgICAgICAgICAqLwp9OwoKc3RhdGljIElOVCBpc0NvbnN0YW50Qml0cmF0ZU1vZGUoCiAgICAgICAgY29uc3QgUUNEQVRBX0JSX01PREUgYml0cmF0ZU1vZGUKICAgICAgICApCnsKICByZXR1cm4gKCAoKGJpdHJhdGVNb2RlPT1RQ0RBVEFfQlJfTU9ERV9DQlIpIHx8IChiaXRyYXRlTW9kZT09UUNEQVRBX0JSX01PREVfU0ZSKSB8fCAoYml0cmF0ZU1vZGU9PVFDREFUQV9CUl9NT0RFX0ZGKSkgPyAxIDogMCApOwp9CgoKCnR5cGVkZWYgZW51bXsKICAgIEZSQU1FX0xFTl9CWVRFU19NT0RVTE8gPSAgMSwKICAgIEZSQU1FX0xFTl9CWVRFU19JTlQgICAgPSAgMgp9RlJBTUVfTEVOX1JFU1VMVF9NT0RFOwoKLyogZm9yd2FyZCBkZWNsYXJhdGlvbnMgKi8KCnN0YXRpYyBJTlQgRkRLYWFjRW5jX2NhbGNNYXhWYWx1ZUluU2ZiKElOVCAgIHNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICBtYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICBzZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICpSRVNUUklDVCBzZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKlJFU1RSSUNUIHF1YW50U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAqUkVTVFJJQ1QgbWF4VmFsdWUpOwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX2NyYXNoUmVjb3ZlcnkoSU5UICAgICAgICAgICAgICAgbkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfRUxFTUVOVCogIHBzeU91dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUKiAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0VMRU1FTlQgICAqcWNFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgIGJpdHNUb1NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgQVVESU9fT0JKRUNUX1RZUEUgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICAgICAgICAgIGVwQ29uZmlnKTsKCnN0YXRpYwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfcmVkdWNlQml0Q29uc3VtcHRpb24oaW50KiAgICAgICAgICAgICBpdGVyYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgICAgICAgIG1heEl0ZXJhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgZ2FpbkFkanVzdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCogICAgICAgICAgICAgY2hDb25zdHJhaW50c0Z1bGZpbGxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KiAgICAgICAgICAgICBjYWxjdWxhdGVRdWFudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfRUxFTUVOVCogcHN5T3V0RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUKiAgICAgICAgICBxY091dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0VMRU1FTlQqICBxY091dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1FTlRfQklUUyogICAgZWxCaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgICAgICAgIGVwQ29uZmlnKTsKCgp2b2lkICBGREthYWNFbmNfUUNDbG9zZSAoUUNfU1RBVEUgICoqcGhRQ3N0YXRlLCBRQ19PVVQgKipwaFFDKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX2NhbGNGcmFtZUxlbgogICAgZGVzY3JpcHRpb246CiAgICByZXR1cm5zOgogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfY2FsY0ZyYW1lTGVuKElOVCBiaXRSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FX0xFTl9SRVNVTFRfTU9ERSBtb2RlKQp7CgogICBJTlQgcmVzdWx0OwoKICAgcmVzdWx0ID0gKChncmFudWxlTGVuZ3RoKT4+MykqKGJpdFJhdGUpOwoKICAgc3dpdGNoKG1vZGUpIHsKICAgICBjYXNlIEZSQU1FX0xFTl9CWVRFU19NT0RVTE86CiAgICAgICAgIHJlc3VsdCAlPSBzYW1wbGVSYXRlOwogICAgIGJyZWFrOwogICAgIGNhc2UgRlJBTUVfTEVOX0JZVEVTX0lOVDoKICAgICAgICAgcmVzdWx0IC89IHNhbXBsZVJhdGU7CiAgICAgYnJlYWs7CiAgIH0KICAgcmV0dXJuKHJlc3VsdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfZnJhbWVQYWRkaW5nCiAgICBkZXNjcmlwdGlvbjogQ2FsY3VsYXRlcyBpZiBwYWRkaW5nIGlzIG5lZWRlZCBmb3IgYWN0dWFsIGZyYW1lCiAgICByZXR1cm5zOgogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZnJhbWVQYWRkaW5nKElOVCBiaXRSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqcGFkZGluZ1Jlc3QpCnsKICBJTlQgcGFkZGluZ09uOwogIElOVCBkaWZmZXJlbmNlOwoKICBwYWRkaW5nT24gPSAwOwoKICBkaWZmZXJlbmNlID0gRkRLYWFjRW5jX2NhbGNGcmFtZUxlbiggYml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVfTEVOX0JZVEVTX01PRFVMTyApOwogICpwYWRkaW5nUmVzdC09ZGlmZmVyZW5jZTsKCiAgaWYgKCpwYWRkaW5nUmVzdCA8PSAwICkgewogICAgcGFkZGluZ09uID0gMTsKICAgICpwYWRkaW5nUmVzdCArPSBzYW1wbGVSYXRlOwogIH0KCiAgcmV0dXJuKCBwYWRkaW5nT24gKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAgICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX1FDT3V0TmV3CiAgICAgICAgIGRlc2NyaXB0aW9uOgogICAgICAgICByZXR1cm46CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfUUNPdXROZXcoUUNfT1VUICAgICoqcGhRQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIG5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIG5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIG5TdWJGcmFtZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLFVDSEFSICAgICAgKmR5bmFtaWNfUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzOwogIGludCBuLCBpOwogIGludCBlbEluYyA9IDAsIGNoSW5jID0gMDsKCiAgZm9yIChuPTA7IG48blN1YkZyYW1lczsgbisrKSB7CiAgICBwaFFDW25dID0gR2V0UmFtX2FhY0VuY19RQ291dChuKTsKICAgIGlmIChwaFFDW25dID09IE5VTEwpIHsKICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgICAgZ290byBRQ091dE5ld19iYWlsOwogICAgfQoKICAgIGZvciAoaT0wOyBpPG5DaGFubmVsczsgaSsrKSB7CiAgICAgIHBoUUNbbl0tPnBRY091dENoYW5uZWxzW2ldID0gR2V0UmFtX2FhY0VuY19RQ2NoYW5uZWwoY2hJbmMsIGR5bmFtaWNfUkFNKTsKICAgICAgaWYgKCBwaFFDW25dLT5wUWNPdXRDaGFubmVsc1tpXSA9PSBOVUxMCiAgICAgICAgICkKICAgICAgewogICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfTk9fTUVNT1JZOwogICAgICAgICBnb3RvIFFDT3V0TmV3X2JhaWw7CiAgICAgIH0KICAgICAgY2hJbmMrKzsKICAgIH0gLyogbkNoYW5uZWxzICovCgogICAgZm9yIChpPTA7IGk8bkVsZW1lbnRzOyBpKyspIHsKICAgICAgcGhRQ1tuXS0+cWNFbGVtZW50W2ldICAgICAgPSBHZXRSYW1fYWFjRW5jX1FDZWxlbWVudChlbEluYyk7CiAgICAgIGlmIChwaFFDW25dLT5xY0VsZW1lbnRbaV0gPT0gTlVMTCkKICAgICAgewogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0VOQ19OT19NRU1PUlk7CiAgICAgICAgZ290byBRQ091dE5ld19iYWlsOwogICAgICB9CiAgICAgIGVsSW5jKys7CiAgICB9IC8qIG5FbGVtZW50cyAqLwoKICB9IC8qIG5TdWJGcmFtZXMgKi8KCgogIHJldHVybiBBQUNfRU5DX09LOwoKUUNPdXROZXdfYmFpbDoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAgICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX1FDT3V0SW5pdAogICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgcmV0dXJuOgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX1FDT3V0SW5pdChRQ19PVVQgICAgICAgICAgKnBoUUNbKDEpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgIG5TdWJGcmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0hBTk5FTF9NQVBQSU5HICpjbSkKewogIElOVCBuLGksY2g7CgogIGZvciAobj0wOyBuPG5TdWJGcmFtZXM7IG4rKykgewogICAgSU5UIGNoSW5jID0gMDsKICAgIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykgewogICAgICBmb3IgKGNoPTA7IGNoPGNtLT5lbEluZm9baV0ubkNoYW5uZWxzSW5FbDsgY2grKykgewogICAgICAgIHBoUUNbbl0tPnFjRWxlbWVudFtpXS0+cWNPdXRDaGFubmVsW2NoXSA9IHBoUUNbbl0tPnBRY091dENoYW5uZWxzW2NoSW5jXTsKICAgICAgICBjaEluYysrOwogICAgICB9IC8qIGNoSW5FbCAqLwogICAgfSAvKiBuRWxlbWVudHMgKi8KICB9IC8qIG5TdWJGcmFtZXMgKi8KCiAgcmV0dXJuIEFBQ19FTkNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAgICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX1FDTmV3CiAgICAgICAgIGRlc2NyaXB0aW9uOgogICAgICAgICByZXR1cm46CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfUUNOZXcoUUNfU1RBVEUgICoqcGhRQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgIG5FbGVtZW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsVUNIQVIqICAgICAgZHluYW1pY19SQU0KICAgICAgICAgICApCnsKICBBQUNfRU5DT0RFUl9FUlJPUiBFcnJvclN0YXR1czsKICBpbnQgaTsKCiAgUUNfU1RBVEUqIGhRQyA9IEdldFJhbV9hYWNFbmNfUUNzdGF0ZSgpOwogICpwaFFDID0gaFFDOwogIGlmIChoUUMgPT0gTlVMTCkgewogICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgIGdvdG8gUUNOZXdfYmFpbDsKICB9CgogIGlmIChGREthYWNFbmNfQWRqVGhyTmV3KCZoUUMtPmhBZGpUaHIsIG5FbGVtZW50cykpIHsKICAgIEVycm9yU3RhdHVzID0gQUFDX0VOQ19OT19NRU1PUlk7CiAgICBnb3RvIFFDTmV3X2JhaWw7CiAgfQoKICBpZiAoRkRLYWFjRW5jX0JDTmV3KCYoaFFDLT5oQml0Q291bnRlciksIGR5bmFtaWNfUkFNKSkgewogICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgIGdvdG8gUUNOZXdfYmFpbDsKICB9CgogIGZvciAoaT0wOyBpPG5FbGVtZW50czsgaSsrKSB7CiAgICBoUUMtPmVsZW1lbnRCaXRzW2ldID0gR2V0UmFtX2FhY0VuY19FbGVtZW50Qml0cyhpKTsKICAgIGlmIChoUUMtPmVsZW1lbnRCaXRzW2ldID09IE5VTEwpIHsKICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgICAgZ290byBRQ05ld19iYWlsOwogICAgfQogIH0KCiAgcmV0dXJuIEFBQ19FTkNfT0s7CgpRQ05ld19iYWlsOgogIEZES2FhY0VuY19RQ0Nsb3NlKHBoUUMsIE5VTEwpOwogIHJldHVybiBFcnJvclN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgICAgICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfUUNJbml0CiAgICAgICAgIGRlc2NyaXB0aW9uOgogICAgICAgICByZXR1cm46CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfUUNJbml0KFFDX1NUQVRFICpoUUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IFFDX0lOSVQgKmluaXQpCnsKICBpbnQgaTsKICBoUUMtPm1heEJpdHNQZXJGcmFtZSA9IGluaXQtPm1heEJpdHM7CiAgaFFDLT5taW5CaXRzUGVyRnJhbWUgPSBpbml0LT5taW5CaXRzOwogIGhRQy0+bkVsZW1lbnRzICAgICAgID0gaW5pdC0+Y2hhbm5lbE1hcHBpbmctPm5FbGVtZW50czsKICBoUUMtPmJpdFJlc1RvdE1heCAgICA9IGluaXQtPmJpdFJlczsKICBoUUMtPmJpdFJlc1RvdCAgICAgICA9IGluaXQtPmJpdFJlczsKICBoUUMtPm1heEJpdEZhYyAgICAgICA9IGluaXQtPm1heEJpdEZhYzsKICBoUUMtPmJpdHJhdGVNb2RlICAgICA9IGluaXQtPmJpdHJhdGVNb2RlOwogIGhRQy0+aW52UXVhbnQgICAgICAgID0gaW5pdC0+aW52UXVhbnQ7CiAgaFFDLT5tYXhJdGVyYXRpb25zICAgPSBpbml0LT5tYXhJdGVyYXRpb25zOwoKICBpZiAoIGlzQ29uc3RhbnRCaXRyYXRlTW9kZShoUUMtPmJpdHJhdGVNb2RlKSApIHsKICAgIElOVCBiaXRyZXNQZXJDaGFubmVsID0gKGhRQy0+Yml0UmVzVG90TWF4IC8gaW5pdC0+Y2hhbm5lbE1hcHBpbmctPm5DaGFubmVsc0VmZik7CiAgICAvKiAwOiBmdWxsIGJpdHJlc2Vydm9pciwgMTogcmVkdWNlZCBiaXRyZXNlcnZvaXIsIDI6IGRpc2FibGVkIGJpdHJlc2Vydm9pciAqLwogICAgaFFDLT5iaXREaXN0cmlidXRpb25Nb2RlID0gKGJpdHJlc1BlckNoYW5uZWw+MTAwKSA/IDAgOiAoYml0cmVzUGVyQ2hhbm5lbD4wKSA/IDEgOiAyOwogIH0KICBlbHNlIHsKICAgIGhRQy0+Yml0RGlzdHJpYnV0aW9uTW9kZSA9IDA7IC8qIGZ1bGwgYml0cmVzZXJ2b2lyICovCiAgfQoKCiAgaFFDLT5wYWRkaW5nLnBhZGRpbmdSZXN0ID0gaW5pdC0+cGFkZGluZy5wYWRkaW5nUmVzdDsKCiAgaFFDLT5nbG9iSGRyQml0cyA9IGluaXQtPnN0YXRpY0JpdHM7IC8qIEJpdCBvdmVyaGVhZCBkdWUgdG8gdHJhbnNwb3J0ICovCgogIEZES2FhY0VuY19Jbml0RWxlbWVudEJpdHMoaFFDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdC0+Y2hhbm5lbE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LT5iaXRyYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGluaXQtPmF2ZXJhZ2VCaXRzL2luaXQtPm5TdWJGcmFtZXMpIC0gaFFDLT5nbG9iSGRyQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhRQy0+bWF4Qml0c1BlckZyYW1lL2luaXQtPmNoYW5uZWxNYXBwaW5nLT5uQ2hhbm5lbHNFZmYpOwoKICBoUUMtPnZiclF1YWxGYWN0b3IgPSBGTDJGWENPTlNUX0RCTCgwLmYpOwogIGZvciAoaT0wOyBpPChpbnQpKHNpemVvZih0YWJsZVZiclF1YWxGYWN0b3IpL3NpemVvZihUQUJfVkJSX1FVQUxfRkFDVE9SKSk7IGkrKykgewogICAgaWYgKGhRQy0+Yml0cmF0ZU1vZGU9PXRhYmxlVmJyUXVhbEZhY3RvcltpXS5iaXRyYXRlTW9kZSkgewogICAgICBoUUMtPnZiclF1YWxGYWN0b3IgPSAoRklYUF9EQkwpdGFibGVWYnJRdWFsRmFjdG9yW2ldLnZiclF1YWxGYWN0b3I7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgRkRLYWFjRW5jX0FkalRockluaXQoCiAgICAgICAgaFFDLT5oQWRqVGhyLAogICAgICAgIGluaXQtPm1lYW5QZSwKICAgICAgICBoUUMtPmVsZW1lbnRCaXRzLCAgICAgICAgICAgICAgICAgLyogb3IgY2hhbm5lbEJpdHJhdGVzLCB3YXM6IGNoYW5uZWxCaXRyYXRlICovCiAgICAgICAgaFFDLT5pbnZRdWFudCwKICAgICAgICBpbml0LT5jaGFubmVsTWFwcGluZy0+bkVsZW1lbnRzLAogICAgICAgIGluaXQtPmNoYW5uZWxNYXBwaW5nLT5uQ2hhbm5lbHNFZmYsCiAgICAgICAgaW5pdC0+c2FtcGxlUmF0ZSwgICAgICAgICAgICAgICAgIC8qIG91dHB1dCBzYW1wbGUgcmF0ZSAqLwogICAgICAgIGluaXQtPmFkdmFuY2VkQml0c1RvUGUsICAgICAgICAgICAvKiBpZiBzZXQsIGNhbGMgYml0czJQRSBmYWN0b3IgZGVwZW5kaW5nIG9uIHNhbXBsZXJhdGUgKi8KICAgICAgICBoUUMtPnZiclF1YWxGYWN0b3IKICAgICAgICApOwoKICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgICAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19RQ01haW5QcmVwYXJlCiAgICAgICAgIGRlc2NyaXB0aW9uOgogICAgICAgICByZXR1cm46CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfUUNNYWluUHJlcGFyZShFTEVNRU5UX0lORk8gICAgICAgICAgICAgICplbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUU19FTEVNRU5UKiBSRVNUUklDVCAgICAgIGFkalRoclN0YXRlRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZX09VVF9FTEVNRU5UKiBSRVNUUklDVCAgcHN5T3V0RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0VMRU1FTlQqIFJFU1RSSUNUICAgcWNPdXRFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSAgICAgICAgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgICBlcENvbmZpZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzID0gQUFDX0VOQ19PSzsKICBJTlQgIG5DaGFubmVscyA9IGVsSW5mby0+bkNoYW5uZWxzSW5FbDsKCiAgUFNZX09VVF9DSEFOTkVMKiogUkVTVFJJQ1QgcHN5T3V0Q2hhbm5lbCA9IHBzeU91dEVsZW1lbnQtPnBzeU91dENoYW5uZWw7ICAgIC8qIG1heSBiZSBtb2RpZmllZCBpbi1wbGFjZSAqLwoKICBGREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3IocWNPdXRFbGVtZW50LT5xY091dENoYW5uZWwsIHBzeU91dENoYW5uZWwsIG5DaGFubmVscyk7CgogIC8qIHByZXBhcmUgYW5kIGNhbGN1bGF0ZSBQRSB3aXRob3V0IHJlZHVjdGlvbiAqLwogIEZES2FhY0VuY19wZUNhbGN1bGF0aW9uKCZxY091dEVsZW1lbnQtPnBlRGF0YSwgcHN5T3V0Q2hhbm5lbCwgcWNPdXRFbGVtZW50LT5xY091dENoYW5uZWwsICZwc3lPdXRFbGVtZW50LT50b29sc0luZm8sIGFkalRoclN0YXRlRWxlbWVudCwgbkNoYW5uZWxzKTsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfQ2hhbm5lbEVsZW1lbnRXcml0ZSggTlVMTCwgZWxJbmZvLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0RWxlbWVudC0+cHN5T3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXRFbGVtZW50LT5zdGF0aWNCaXRzVXNlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwICk7CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgICAgICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfQWRqdXN0Qml0cmF0ZQogICAgICAgICBkZXNjcmlwdGlvbjogIGFkanVzdHMgZnJhbWVsZW5ndGggdmlhIHBhZGRpbmcgb24gYSBmcmFtZSB0byBmcmFtZSBiYXNpcywKICAgICAgICAgICAgICAgICAgICAgICB0byBhY2hpZXZlIGEgYml0cmF0ZSB0aGF0IGRlbWFuZHMgYSBub24gYnl0ZSBhbGlnbmVkCiAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVsZW5ndGgKICAgICAgICAgcmV0dXJuOiAgICAgICBlcnJvcmNvZGUKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19BZGp1c3RCaXRyYXRlKFFDX1NUQVRFICAgICAgICAqUkVTVFJJQ1QgaFFDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFOTkVMX01BUFBJTkcgKlJFU1RSSUNUIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgKmF2Z1RvdGFsQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICBiaXRSYXRlLCAgICAgICAvKiB0b3RhbCBiaXRyYXRlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgc2FtcGxlUmF0ZSwgICAgLyogb3V0cHV0IHNhbXBsaW5nIHJhdGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICBncmFudWxlTGVuZ3RoKSAvKiBmcmFtZSBsZW5ndGggKi8KewogIElOVCBwYWRkaW5nT247CiAgSU5UIGZyYW1lTGVuOwoKICAvKiBEbyB3ZSBuZWVkIGFuIGV4dHJhIHBhZGRpbmcgYnl0ZT8gKi8KICBwYWRkaW5nT24gPSBGREthYWNFbmNfZnJhbWVQYWRkaW5nKGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJmhRQy0+cGFkZGluZy5wYWRkaW5nUmVzdCk7CgogIGZyYW1lTGVuID0gcGFkZGluZ09uICsgRkRLYWFjRW5jX2NhbGNGcmFtZUxlbihiaXRSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUkFNRV9MRU5fQllURVNfSU5UKTsKCiAgKmF2Z1RvdGFsQml0cyA9IGZyYW1lTGVuPDwzOwoKICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKc3RhdGljIEFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19kaXN0cmlidXRlRWxlbWVudER5bkJpdHMoUUNfU1RBVEUqICAgICAgICAgaFFDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9FTEVNRU5UKiAgIHFjRWxlbWVudFsoOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5ORUxfTUFQUElORyogIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgIGNvZGVCaXRzKQp7CgogIElOVCBpLCBmaXJzdEVsID0gY20tPm5FbGVtZW50cy0xOwogIElOVCB0b3RhbEJpdHMgPSAwOwoKICBmb3IgKGk9KGNtLT5uRWxlbWVudHMtMSk7IGk+PTA7IGktLSkgewogICAgaWYgKChjbS0+ZWxJbmZvW2ldLmVsVHlwZSA9PSBJRF9TQ0UpIHx8IChjbS0+ZWxJbmZvW2ldLmVsVHlwZSA9PSBJRF9DUEUpIHx8CiAgICAgICAgKGNtLT5lbEluZm9baV0uZWxUeXBlID09IElEX0xGRSkpCiAgICB7CiAgICAgIHFjRWxlbWVudFtpXS0+Z3JhbnRlZER5bkJpdHMgPSAgKElOVClmTXVsdChoUUMtPmVsZW1lbnRCaXRzW2ldLT5yZWxhdGl2ZUJpdHNFbCwgKEZJWFBfREJMKWNvZGVCaXRzKTsKICAgICAgdG90YWxCaXRzICs9IHFjRWxlbWVudFtpXS0+Z3JhbnRlZER5bkJpdHM7CiAgICAgIGZpcnN0RWwgPSBpOwogICAgfQogIH0KICBxY0VsZW1lbnRbZmlyc3RFbF0tPmdyYW50ZWREeW5CaXRzICs9IGNvZGVCaXRzIC0gdG90YWxCaXRzOwoKICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKLyoqCiAqIFxicmllZiAgVmVyaWZ5IHdoZXRoZXIgbWluQml0c1BlckZyYW1lIGNyaXRlcmlvbiBjYW4gYmUgc2F0aXNmaWVkLgogKgogKiBUaGlzIGZ1bmN0aW9uIGV2YWx1YXRlcyB0aGUgYml0IGNvbnN1bXB0aW9uIG9ubHkgaWYgbWluQml0c1BlckZyYW1lIHBhcmFtZXRlciBpcyBub3QgMC4KICogSW4gaHlwZXJmcmFtaW5nIG1vZGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBncmFudGVkRHluQml0cyBhbmQgdXNlZER5bkJpdHMgb2YgYWxsIHN1YiBmcmFtZXMKICogcmVzdWx0cyB0aGUgbnVtYmVyIG9mIGZpbGxiaXRzIHRvIGJlIHdyaXR0ZW4uCiAqIFRoaXMgYml0cyBjYW4gYmUgZGlzdHJ1Yml0dWVkIGluIHN1cGVyZnJhbWUgdG8gcmVhY2ggbWluQml0c1BlckZyYW1lIGJpdCBjb25zdW1wdGlvbiBpbiBzaW5nbGUgQVUncy4KICogVGhlIHJldHVybiB2YWx1ZSBkZW5vdGVzIGlmIGVub3VnaCBkZXNpcmVkIGZpbGwgYml0cyBhcmUgYXZhaWxhYmxlIHRvIGFjaGlldmUgbWluQml0c1BlckZyYW1lIGluIGFsbCBmcmFtZXMuCiAqIFRoaXMgY2hlY2sgY2FuIG9ubHkgYmUgdXNlZCB3aXRoaW4gc3VwZXJmcmFtZXMuCiAqCiAqIFxwYXJhbSBxY091dCAgICAgICAgICAgIFBvaW50ZXIgdG8gY29kaW5nIGRhdGEgc3RydWN0LgogKiBccGFyYW0gbWluQml0c1BlckZyYW1lICBNaW5pbWFsIG51bWJlciBvZiBiaXRzIHRvIGJlIGNvbnN1bWVkIGluIGVhY2ggZnJhbWUuCiAqIFxwYXJhbSBuU3ViRnJhbWVzICAgICAgIE51bWJlciBvZiBmcmFtZXMgaW4gc3VwZXJmcmFtZQogKgogKiBccmV0dXJuCiAqICAgICAgICAgIC0gMTogYWxsIGZpbmUKICogICAgICAgICAgLSAwOiBjcml0ZXJpb24gbm90IGZ1bGZpbGxlZAogKi8Kc3RhdGljIGludCBjaGVja01pbkZyYW1lQml0c0RlbWFuZCgKICAgICAgICBRQ19PVVQqKiAgICAgICAgICAgICAgICAgIHFjT3V0LAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgbWluQml0c1BlckZyYW1lLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgblN1YkZyYW1lcwogICAgICAgICkKewogIGludCByZXN1bHQgPSAxOyAvKiBhbGwgZmluZSovCiAgcmV0dXJuIHJlc3VsdDsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAgICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX2dldE1pbmltYWxTdGF0aWNCaXRkZW1hbmQKICAgICAgICAgZGVzY3JpcHRpb246ICBjYWxjdWxhdGUgbWlubWFsIHNpemUgb2Ygc3RhdGljIGJpdHMgYnkgcmVkdWN0aW9uICwKICAgICAgICAgICAgICAgICAgICAgICB0byB6ZXJvIHNwZWN0cnVtIGFuZCBkZWFjdGl2YXRpbmcgdG5zIGFuZCBNUwogICAgICAgICByZXR1cm46ICAgICAgIG51bWJlciBvZiBzdGF0aWMgYml0cwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGludCBGREthYWNFbmNfZ2V0TWluaW1hbFN0YXRpY0JpdGRlbWFuZChDSEFOTkVMX01BUFBJTkcqICAgICBjbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUKiogICAgICAgICAgICBwc3lPdXQpCnsKICBBVURJT19PQkpFQ1RfVFlQRSBhb3QgPSBBT1RfQUFDX0xDOwogIFVJTlQgIHN5bnRheEZsYWdzID0gMDsKICBTQ0hBUiBlcENvbmZpZyA9IC0xOwogIGludCBpLCBiaXRjb3VudCA9IDA7CgogIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykgewogICAgICBFTEVNRU5UX0lORk8gZWxJbmZvID0gY20tPmVsSW5mb1tpXTsKCiAgICAgIGlmICggKGVsSW5mby5lbFR5cGUgPT0gSURfU0NFKQogICAgICAgIHx8IChlbEluZm8uZWxUeXBlID09IElEX0NQRSkKICAgICAgICB8fCAoZWxJbmZvLmVsVHlwZSA9PSBJRF9MRkUpICkKICAgICAgewogICAgICAgIElOVCBtaW5FbEJpdHMgPSAwOwoKICAgICAgICBGREthYWNFbmNfQ2hhbm5lbEVsZW1lbnRXcml0ZSggTlVMTCwgJmVsSW5mbywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0WzBdLT5wc3lPdXRFbGVtZW50W2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRbMF0tPnBzeU91dEVsZW1lbnRbaV0tPnBzeU91dENoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtaW5FbEJpdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKTsKICAgICAgICBiaXRjb3VudCArPSBtaW5FbEJpdHM7CiAgICAgIH0KICB9CgogIHJldHVybiBiaXRjb3VudDsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCnN0YXRpYyBBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfcHJlcGFyZUJpdERpc3RyaWJ1dGlvbihRQ19TVEFURSogICAgICAgICAgICBoUUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVQqKiAgICAgICAgICAgIHBzeU91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUKiogICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5ORUxfTUFQUElORyogICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfRUxFTUVOVCogICAgICBxY0VsZW1lbnRbKDEpXVsoOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgICBhdmdUb3RhbEJpdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICAgKnRvdGFsQXZhaWxhYmxlQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgICAqYXZnVG90YWxEeW5CaXRzKQp7CiAgICBpbnQgaTsKICAgICAgLyogZ2V0IG1heGltYWwgYWxsb3dlZCBkeW5hbWljIGJpdHMgKi8KICAgICAgcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzID0gIChmaXhNaW4oaFFDLT5tYXhCaXRzUGVyRnJhbWUsIGF2Z1RvdGFsQml0cykgLSBoUUMtPmdsb2JIZHJCaXRzKSZ+NzsKICAgICAgcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzIC09IChxY091dFswXS0+Z2xvYmFsRXh0Qml0cyArIHFjT3V0WzBdLT5zdGF0aWNCaXRzICsgcWNPdXRbMF0tPmVsZW1lbnRFeHRCaXRzKTsKICAgICAgcWNPdXRbMF0tPm1heER5bkJpdHMgPSAoKGhRQy0+bWF4Qml0c1BlckZyYW1lKSZ+NykgLSAocWNPdXRbMF0tPmdsb2JhbEV4dEJpdHMgKyBxY091dFswXS0+c3RhdGljQml0cyArIHFjT3V0WzBdLT5lbGVtZW50RXh0Qml0cyk7CiAgICAgIC8qIGFzc3VyZSB0aGF0IGVub3VnaCBiaXRzIGFyZSBhdmFpbGFibGUgKi8KICAgICAgaWYgKChxY091dFswXS0+Z3JhbnRlZER5bkJpdHMraFFDLT5iaXRSZXNUb3QpIDwgMCkgewogICAgICAgIC8qIGNyYXNoIHJlY292ZXJ5IGFsbG93cyB0byByZWR1Y2Ugc3RhdGljIGJpdHMgdG8gYSBtaW5pbXVtICovCiAgICAgICAgaWYgKCAocWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzK2hRQy0+Yml0UmVzVG90KSA8IChGREthYWNFbmNfZ2V0TWluaW1hbFN0YXRpY0JpdGRlbWFuZChjbSwgcHN5T3V0KS1xY091dFswXS0+c3RhdGljQml0cykgKQogICAgICAgICAgcmV0dXJuIEFBQ19FTkNfQklUUkVTX1RPT19MT1c7CiAgICAgIH0KCiAgICAgIC8qIGRpc3RyaWJ1dGUgZHluYW1pYyBiaXRzIHRvIGVhY2ggZWxlbWVudCAqLwogICAgICBGREthYWNFbmNfZGlzdHJpYnV0ZUVsZW1lbnREeW5CaXRzKGhRQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjRWxlbWVudFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzKTsKCiAgICAgICphdmdUb3RhbER5bkJpdHMgPSAwOyAvKmZyYW1lRHluQml0czsqLwoKICAgICp0b3RhbEF2YWlsYWJsZUJpdHMgPSBhdmdUb3RhbEJpdHM7CgogICAgLyogc3VtIHVwIGNvcnJlY3RlZCBncmFudGVkIFBFICovCiAgICBxY091dFswXS0+dG90YWxHcmFudGVkUGVDb3JyID0gMDsKCiAgICBmb3IgKGk9MDsgaTxjbS0+bkVsZW1lbnRzOyBpKyspCiAgICB7CiAgICAgICAgRUxFTUVOVF9JTkZPIGVsSW5mbyA9IGNtLT5lbEluZm9baV07CiAgICAgICAgaW50IG5DaGFubmVscyA9IGVsSW5mby5uQ2hhbm5lbHNJbkVsOwoKICAgICAgICBpZiAoKGVsSW5mby5lbFR5cGUgPT0gSURfU0NFKSB8fCAoZWxJbmZvLmVsVHlwZSA9PSBJRF9DUEUpIHx8CiAgICAgICAgICAgIChlbEluZm8uZWxUeXBlID09IElEX0xGRSkpCiAgICAgICAgewogICAgICAgICAgICAgICAgLyogZm9yICggYWxsIHN1YiBmcmFtZXMgKSAuLi4gKi8KICAgICAgICAgICAgICAgIEZES2FhY0VuY19EaXN0cmlidXRlQml0cyhoUUMtPmhBZGpUaHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFFDLT5oQWRqVGhyLT5hZGpUaHJTdGF0ZUVsZW1baV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0WzBdLT5wc3lPdXRFbGVtZW50W2ldLT5wc3lPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnFjRWxlbWVudFswXVtpXS0+cGVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnFjRWxlbWVudFswXVtpXS0+Z3JhbnRlZFBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnFjRWxlbWVudFswXVtpXS0+Z3JhbnRlZFBlQ29yciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0WzBdLT5wc3lPdXRFbGVtZW50W2ldLT5jb21tb25XaW5kb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNFbGVtZW50WzBdW2ldLT5ncmFudGVkRHluQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUUMtPmVsZW1lbnRCaXRzW2ldLT5iaXRSZXNMZXZlbEVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhRQy0+ZWxlbWVudEJpdHNbaV0tPm1heEJpdFJlc0JpdHNFbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUUMtPm1heEJpdEZhYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUUMtPmJpdERpc3RyaWJ1dGlvbk1vZGUpOwoKICAgICAgICAgICAgICAgICp0b3RhbEF2YWlsYWJsZUJpdHMgKz0gaFFDLT5lbGVtZW50Qml0c1tpXS0+Yml0UmVzTGV2ZWxFbDsKICAgICAgICAvKiBnZXQgdG90YWwgY29ycmVjdGVkIGdyYW50ZWQgUEUgKi8KICAgICAgICBxY091dFswXS0+dG90YWxHcmFudGVkUGVDb3JyICs9IHFjRWxlbWVudFswXVtpXS0+Z3JhbnRlZFBlQ29ycjsKICAgICAgICB9ICAvKiAgLWVuZC0gaWYoSURfU0NFIHx8IElEX0NQRSB8fCBJRF9MRkUpICovCgogICAgfSAgLyogLWVuZC0gZWxlbWVudCBsb29wICovCgogICAgKnRvdGFsQXZhaWxhYmxlQml0cyA9IEZES21pbihoUUMtPm1heEJpdHNQZXJGcmFtZSwgKCp0b3RhbEF2YWlsYWJsZUJpdHMpKTsKCiAgICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8Kc3RhdGljIEFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY191cGRhdGVVc2VkRHluQml0cyhJTlQqICAgICAgICAgICAgICAgc3VtRHluQml0c0NvbnN1bWVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9FTEVNRU5UKiAgICBxY0VsZW1lbnRbKDgpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFOTkVMX01BUFBJTkcqICAgY20pCnsKICBJTlQgaTsKCiAgKnN1bUR5bkJpdHNDb25zdW1lZCA9IDA7CgogIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykKICB7CiAgICAgIEVMRU1FTlRfSU5GTyBlbEluZm8gPSBjbS0+ZWxJbmZvW2ldOwoKICAgICAgaWYgKChlbEluZm8uZWxUeXBlID09IElEX1NDRSkgfHwgKGVsSW5mby5lbFR5cGUgPT0gSURfQ1BFKSB8fAogICAgICAgICAgKGVsSW5mby5lbFR5cGUgPT0gSURfTEZFKSkKICAgICAgewogICAgICAgICAgLyogc3VtIHVwIGJpdHMgY29uc3VtZWQgKi8KICAgICAgICAgICpzdW1EeW5CaXRzQ29uc3VtZWQgICs9IHFjRWxlbWVudFtpXS0+ZHluQml0c1VzZWQ7CiAgICAgIH0gIC8qICAtZW5kLSBpZihJRF9TQ0UgfHwgSURfQ1BFIHx8IElEX0xGRSkgKi8KCiAgfSAgLyogLWVuZC0gZWxlbWVudCBsb29wICovCgogIHJldHVybiBBQUNfRU5DX09LOwp9CgoKc3RhdGljIElOVCBGREthYWNFbmNfZ2V0VG90YWxDb25zdW1lZER5bkJpdHMoUUNfT1VUKiogcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG5TdWJGcmFtZXMpCnsKICAgIElOVCBjLCB0b3RhbEJpdHM9MDsKCiAgICAvKiBzdW0gdXAgYml0IGNvbnN1bXB0aW9uIGZvciBhbGwgc3ViIGZyYW1lcyAqLwogICAgZm9yIChjPTA7IGM8blN1YkZyYW1lczsgYysrKQogICAgewogICAgICAgIC8qIGJpdCBjb25zdW1wdGlvbiBub3QgdmFsaWQgaWYgZHluYW1pYyBiaXRzCiAgICAgICAgICAgbm90IGF2YWlsYWJsZSBpbiBvbmUgc3ViIGZyYW1lICovCiAgICAgICAgaWYgKHFjT3V0W2NdLT51c2VkRHluQml0cz09LTEpIHJldHVybiAtMTsKICAgICAgICB0b3RhbEJpdHMgKz0gcWNPdXRbY10tPnVzZWREeW5CaXRzOwogICAgfQoKICAgIHJldHVybiB0b3RhbEJpdHM7Cgp9CgpzdGF0aWMgSU5UIEZES2FhY0VuY19nZXRUb3RhbENvbnN1bWVkQml0cyhRQ19PVVQqKiAgICAgICAgICBxY091dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfRUxFTUVOVCogICBxY0VsZW1lbnRbKDEpXVsoOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5ORUxfTUFQUElORyogIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgIGdsb2JIZHJCaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgIG5TdWJGcmFtZXMpCnsKICAgIGludCBjLCBpOwogICAgaW50IHRvdGFsVXNlZEJpdHMgPSAwOwoKICAgIGZvciAoYyA9IDAgOyBjIDwgblN1YkZyYW1lcyA7IGMrKyApCiAgICB7CiAgICAgICAgaW50IGRhdGFCaXRzID0gMDsKICAgICAgICBmb3IgKGk9MDsgaTxjbS0+bkVsZW1lbnRzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAoKGNtLT5lbEluZm9baV0uZWxUeXBlID09IElEX1NDRSkgfHwgKGNtLT5lbEluZm9baV0uZWxUeXBlID09IElEX0NQRSkgfHwKICAgICAgICAgICAgICAgIChjbS0+ZWxJbmZvW2ldLmVsVHlwZSA9PSBJRF9MRkUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBkYXRhQml0cyArPSBxY0VsZW1lbnRbY11baV0tPmR5bkJpdHNVc2VkICsgcWNFbGVtZW50W2NdW2ldLT5zdGF0aWNCaXRzVXNlZCArIHFjRWxlbWVudFtjXVtpXS0+ZXh0Qml0c1VzZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZGF0YUJpdHMgKz0gcWNPdXRbY10tPmdsb2JhbEV4dEJpdHM7CgogICAgICAgIHRvdGFsVXNlZEJpdHMgKz0gKDggLSAoZGF0YUJpdHMpICUgOCkgJSA4OwogICAgICAgIHRvdGFsVXNlZEJpdHMgKz0gZGF0YUJpdHMgKyBnbG9iSGRyQml0czsgIC8qIGhlYWRlciBiaXRzIGZvciBldmVyeSBmcmFtZSAqLwogICAgfQogICAgcmV0dXJuIHRvdGFsVXNlZEJpdHM7Cn0KCnN0YXRpYyBBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfQml0UmVzUmVkaXN0cmlidXRpb24oCiAgICAgICAgUUNfU1RBVEUgKmNvbnN0ICAgICAgICAgICAgICBoUUMsCiAgICAgICAgY29uc3QgQ0hBTk5FTF9NQVBQSU5HICpjb25zdCBjbSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgIGF2Z1RvdGFsQml0cwogICAgICAgICkKewogICAgLyogY2hlY2sgYml0cmVzZXJ2b2lyIGZpbGwgbGV2ZWwgKi8KICAgIGlmIChoUUMtPmJpdFJlc1RvdCA8IDApIHsKICAgICAgcmV0dXJuIEFBQ19FTkNfQklUUkVTX1RPT19MT1c7CiAgICB9CiAgICBlbHNlIGlmIChoUUMtPmJpdFJlc1RvdCA+IGhRQy0+Yml0UmVzVG90TWF4KSB7CiAgICAgIHJldHVybiBBQUNfRU5DX0JJVFJFU19UT09fSElHSDsKICAgIH0KICAgIGVsc2UgewogICAgICBJTlQgaSwgZmlyc3RFbCA9IGNtLT5uRWxlbWVudHMtMTsKICAgICAgSU5UIHRvdGFsQml0cyA9IDAsIHRvdGFsQml0c19tYXggPSAwOwoKICAgICAgaW50IHRvdGFsQml0cmVzZXJ2b2lyICAgID0gRkRLbWluKGhRQy0+Yml0UmVzVG90LCAoaFFDLT5tYXhCaXRzUGVyRnJhbWUtYXZnVG90YWxCaXRzKSk7CiAgICAgIGludCB0b3RhbEJpdHJlc2Vydm9pck1heCA9IEZES21pbihoUUMtPmJpdFJlc1RvdE1heCwgKGhRQy0+bWF4Qml0c1BlckZyYW1lLWF2Z1RvdGFsQml0cykpOwoKICAgICAgaW50IHNjX2JpdFJlc1RvdCA9IENvdW50TGVhZGluZ0JpdHModG90YWxCaXRyZXNlcnZvaXIpOwogICAgICBpbnQgc2NfYml0UmVzVG90TWF4ID0gQ291bnRMZWFkaW5nQml0cyh0b3RhbEJpdHJlc2Vydm9pck1heCk7CgogICAgICBmb3IgKGk9KGNtLT5uRWxlbWVudHMtMSk7IGk+PTA7IGktLSkgewogICAgICAgIGlmICgoY20tPmVsSW5mb1tpXS5lbFR5cGUgPT0gSURfU0NFKSB8fCAoY20tPmVsSW5mb1tpXS5lbFR5cGUgPT0gSURfQ1BFKSB8fAogICAgICAgICAgICAoY20tPmVsSW5mb1tpXS5lbFR5cGUgPT0gSURfTEZFKSkKICAgICAgICB7CiAgICAgICAgICBoUUMtPmVsZW1lbnRCaXRzW2ldLT5iaXRSZXNMZXZlbEVsID0gKElOVClmTXVsdChoUUMtPmVsZW1lbnRCaXRzW2ldLT5yZWxhdGl2ZUJpdHNFbCwgKEZJWFBfREJMKSh0b3RhbEJpdHJlc2Vydm9pcjw8c2NfYml0UmVzVG90KSk+PnNjX2JpdFJlc1RvdDsKICAgICAgICAgIHRvdGFsQml0cyArPSBoUUMtPmVsZW1lbnRCaXRzW2ldLT5iaXRSZXNMZXZlbEVsOwoKICAgICAgICAgIGhRQy0+ZWxlbWVudEJpdHNbaV0tPm1heEJpdFJlc0JpdHNFbCA9IChJTlQpZk11bHQoaFFDLT5lbGVtZW50Qml0c1tpXS0+cmVsYXRpdmVCaXRzRWwsIChGSVhQX0RCTCkodG90YWxCaXRyZXNlcnZvaXJNYXg8PHNjX2JpdFJlc1RvdE1heCkpPj5zY19iaXRSZXNUb3RNYXg7CiAgICAgICAgICB0b3RhbEJpdHNfbWF4ICs9IGhRQy0+ZWxlbWVudEJpdHNbaV0tPm1heEJpdFJlc0JpdHNFbDsKCiAgICAgICAgICBmaXJzdEVsID0gaTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaFFDLT5lbGVtZW50Qml0c1tmaXJzdEVsXS0+Yml0UmVzTGV2ZWxFbCAgICs9IHRvdGFsQml0cmVzZXJ2b2lyIC0gdG90YWxCaXRzOwogICAgICBoUUMtPmVsZW1lbnRCaXRzW2ZpcnN0RWxdLT5tYXhCaXRSZXNCaXRzRWwgKz0gdG90YWxCaXRyZXNlcnZvaXJNYXggLSB0b3RhbEJpdHNfbWF4OwogICAgfQoKICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX1FDTWFpbihRQ19TVEFURSogUkVTVFJJQ1QgICAgICAgICBoUUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZX09VVCoqICAgICAgICAgICAgICAgICAgcHN5T3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVCoqICAgICAgICAgICAgICAgICAgIHFjT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1RvdGFsQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSEFOTkVMX01BUFBJTkcqICAgICAgICAgICBjbQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLEFVRElPX09CSkVDVF9UWVBFICAgICAgICAgIGFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgICBlcENvbmZpZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgaW50IGksIGM7CiAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX09LOwogIElOVCBhdmdUb3RhbER5bkJpdHMgPSAwOyAvKiBtYXhpbWFsIGFsbG93ZWQgZHluYW1pYyBiaXRzIGZvciBhbGwgZnJhbWVzICovCiAgSU5UIHRvdGFsQXZhaWxhYmxlQml0cyA9IDA7CiAgSU5UIG5TdWJGcmFtZXMgPSAxOwoKICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgLyogcmVkaXN0cmlidXRlIHRvdGFsIGJpdHJlc2Vydm9pciB0byBlbGVtZW50cyAqLwogIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0JpdFJlc1JlZGlzdHJpYnV0aW9uKGhRQywgY20sIGF2Z1RvdGFsQml0cyk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spIHsKICAgIHJldHVybiBFcnJvclN0YXR1czsKICB9CgogIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAvKiBmYXN0ZW5jIG5lZWRzIG9uZSB0aW1lIHRocmVzaG9sZCBzaW11bGF0aW9uLAogICAgIGluIGNhc2Ugb2YgbXVsdGlwbGUgZnJhbWVzLCBvbmUgbW9yZSBndWVzcyBoYXMgdG8gYmUgY2FsY3VsYXRlZCAqLwoKICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAvKiBoZWxwZXIgcG9pbnRlciAqLwogICAgICBRQ19PVVRfRUxFTUVOVCogIHFjRWxlbWVudFsoMSldWyg4KV07CgogICAgICAvKiB3b3JrIG9uIGEgY29weSBvZiBxY0NoYW5uZWwgYW5kIHFjRWxlbWVudCAqLwogICAgICBmb3IgKGk9MDsgaTxjbS0+bkVsZW1lbnRzOyBpKyspCiAgICAgIHsKICAgICAgICAgIEVMRU1FTlRfSU5GTyBlbEluZm8gPSBjbS0+ZWxJbmZvW2ldOwoKICAgICAgICAgIGlmICgoZWxJbmZvLmVsVHlwZSA9PSBJRF9TQ0UpIHx8IChlbEluZm8uZWxUeXBlID09IElEX0NQRSkgfHwKICAgICAgICAgICAgICAoZWxJbmZvLmVsVHlwZSA9PSBJRF9MRkUpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8qIGZvciAoIGFsbCBzdWIgZnJhbWVzICkgLi4uICovCiAgICAgICAgICAgICAgZm9yIChjID0gMCA7IGMgPCBuU3ViRnJhbWVzIDsgYysrICkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIHFjRWxlbWVudFtjXVtpXSA9IHFjT3V0W2NdLT5xY0VsZW1lbnRbaV07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICBpZiAoIGlzQ29uc3RhbnRCaXRyYXRlTW9kZShoUUMtPmJpdHJhdGVNb2RlKSApCiAgICAgIHsKICAgICAgICAgIC8qIGNhbGMgZ3JhbnRlZCBkeW5hbWljIGJpdHMgZm9yIHN1YiBmcmFtZSBhbmQKICAgICAgICAgICAgIGRpc3RyaWJ1dGUgaXQgdG8gZWFjaCBlbGVtZW50ICovCiAgICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19wcmVwYXJlQml0RGlzdHJpYnV0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1RvdGFsQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdG90YWxBdmFpbGFibGVCaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdmdUb3RhbER5bkJpdHMpOwoKICAgICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKSB7CiAgICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKICAgICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAgIHFjT3V0WzBdLT5ncmFudGVkRHluQml0cyA9ICgoaFFDLT5tYXhCaXRzUGVyRnJhbWUgLSAoaFFDLT5nbG9iSGRyQml0cykpJn43KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gKHFjT3V0WzBdLT5nbG9iYWxFeHRCaXRzICsgcWNPdXRbMF0tPnN0YXRpY0JpdHMgKyBxY091dFswXS0+ZWxlbWVudEV4dEJpdHMpOwogICAgICAgICAgcWNPdXRbMF0tPm1heER5bkJpdHMgICAgID0gcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzOwoKICAgICAgICAgIHRvdGFsQXZhaWxhYmxlQml0cyA9IGhRQy0+bWF4Qml0c1BlckZyYW1lOwogICAgICAgICAgYXZnVG90YWxEeW5CaXRzID0gMDsKICAgICAgfQoKI2lmZGVmIFBOU19QUkVDT1VOVF9FTkFCTEUKICAgICAgLyogQ2FsY3VsYXRlIGVzdGltYXRlZCBwbnMgYml0cyBhbmQgc3Vic3RyYWN0IHRoZW0gZnJvbSBncmFudGVkRHluQml0cyB0byBnZXQgYSBtb3JlIGFjY3VyYXRlIG51bWJlciBvZiBhdmFpbGFibGUgYml0cy4gKi8KICAgICAgaWYgKHN5bnRheEZsYWdzICYgKEFDX0xEfEFDX0VMRCkpCiAgICAgIHsKICAgICAgICBpbnQgZXN0aW1hdGVkUG5zQml0cyA9IDAsIGNoOwoKICAgICAgICBmb3IgKGNoPTA7IGNoPGNtLT5uQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgICAgIHFjT3V0WzBdLT5wUWNPdXRDaGFubmVsc1tjaF0tPnNlY3Rpb25EYXRhLm5vaXNlTnJnQml0cyA9IG5vaXNlUHJlQ291bnQocHN5T3V0WzBdLT5wUHN5T3V0Q2hhbm5lbHNbY2hdLT5ub2lzZU5yZywgcHN5T3V0WzBdLT5wUHN5T3V0Q2hhbm5lbHNbY2hdLT5tYXhTZmJQZXJHcm91cCk7CiAgICAgICAgICBlc3RpbWF0ZWRQbnNCaXRzICs9IHFjT3V0WzBdLT5wUWNPdXRDaGFubmVsc1tjaF0tPnNlY3Rpb25EYXRhLm5vaXNlTnJnQml0czsKICAgICAgICB9CiAgICAgICAgcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzIC09IGVzdGltYXRlZFBuc0JpdHM7CiAgICAgIH0KI2VuZGlmCgogICAgICAvKiBmb3IgKCBhbGwgc3ViIGZyYW1lcyApIC4uLiAqLwogICAgICBmb3IgKGMgPSAwIDsgYyA8IG5TdWJGcmFtZXMgOyBjKysgKQogICAgICB7CiAgICAgICAgICAvKiBmb3IgQ0JSIGFuZCBWQlIgbW9kZSAqLwogICAgICAgICAgRkRLYWFjRW5jX0FkanVzdFRocmVzaG9sZHMoaFFDLT5oQWRqVGhyLT5hZGpUaHJTdGF0ZUVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY0VsZW1lbnRbY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dFtjXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dFtjXS0+cHN5T3V0RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ29uc3RhbnRCaXRyYXRlTW9kZShoUUMtPmJpdHJhdGVNb2RlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtKTsKCiAgICAgIH0gLyogLWVuZC0gc3ViIGZyYW1lIGNvdW50ZXIgKi8KCiAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgSU5UIGl0ZXJhdGlvbnNbKDEpXVsoOCldOwogICAgICBJTlQgY2hDb25zdHJhaW50c0Z1bGZpbGxlZFsoMSldWyg4KV1bKDIpXTsKICAgICAgSU5UIGNhbGN1bGF0ZVF1YW50WygxKV1bKDgpXVsoMildOwogICAgICBJTlQgY29uc3RyYWludHNGdWxmaWxsZWRbKDEpXVsoOCldOwogICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKICAgICAgLyogZm9yICggYWxsIHN1YiBmcmFtZXMgKSAuLi4gKi8KICAgICAgZm9yIChjID0gMCA7IGMgPCBuU3ViRnJhbWVzIDsgYysrICkKICAgICAgewogICAgICAgICAgZm9yIChpPTA7IGk8Y20tPm5FbGVtZW50czsgaSsrKQogICAgICAgICAgewogICAgICAgICAgICAgIEVMRU1FTlRfSU5GTyBlbEluZm8gPSBjbS0+ZWxJbmZvW2ldOwogICAgICAgICAgICAgIElOVCBjaCwgbkNoYW5uZWxzID0gZWxJbmZvLm5DaGFubmVsc0luRWw7CgogICAgICAgICAgICAgIGlmICgoZWxJbmZvLmVsVHlwZSA9PSBJRF9TQ0UpIHx8IChlbEluZm8uZWxUeXBlID09IElEX0NQRSkgfHwKICAgICAgICAgICAgICAgICAgKGVsSW5mby5lbFR5cGUgPT0gSURfTEZFKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAvKiBUdXJuIHRocmVzaG9sZHMgaW50byBzY2FsZWZhY3RvcnMsIG9wdGltaXplIGJpdCBjb25zdW1wdGlvbiBhbmQgdmVyaWZ5IGNvbmZvcm1hbmNlICovCiAgICAgICAgICAgICAgICAgICAgICBGREthYWNFbmNfRXN0aW1hdGVTY2FsZUZhY3RvcnMocHN5T3V0W2NdLT5wc3lPdXRFbGVtZW50W2ldLT5wc3lPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjRWxlbWVudFtjXVtpXS0+cWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhRQy0+aW52UXVhbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20tPmVsSW5mb1tpXS5uQ2hhbm5lbHNJbkVsKTsKCgogICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNGdWxmaWxsZWRbY11baV0gPSAxOwogICAgICAgICAgICAgICAgICAgICAgaXRlcmF0aW9uc1tjXVtpXSA9IDAgOwoKICAgICAgICAgICAgICAgICAgICAgIGZvciAoY2ggPSAwOyBjaCA8IG5DaGFubmVsczsgY2grKykKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjaENvbnN0cmFpbnRzRnVsZmlsbGVkW2NdW2ldW2NoXSA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsY3VsYXRlUXVhbnRbY11baV1bY2hdID0gMTsKICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgogICAgICAgICAgICAgIH0gIC8qICAtZW5kLSBpZihJRF9TQ0UgfHwgSURfQ1BFIHx8IElEX0xGRSkgKi8KCiAgICAgICAgICB9ICAvKiAtZW5kLSBlbGVtZW50IGxvb3AgKi8KCiAgICAgICAgICBxY091dFtjXS0+dXNlZER5bkJpdHMgPSAtMTsKCiAgICAgIH0gLyogLWVuZC0gc3ViIGZyYW1lIGNvdW50ZXIgKi8KCgoKICAgICAgSU5UIHF1YW50aXphdGlvbkRvbmUgPSAwOwogICAgICBJTlQgc3VtRHluQml0c0NvbnN1bWVkVG90YWwgID0gMDsKICAgICAgSU5UIGRlY3JlYXNlQml0Q29uc3VtcHRpb24gPSAtMTsgLyogbm8gZGlyZWN0aW9uIHlldCEgKi8KCiAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgLyogLXN0YXJ0LSBRdWFudGl6YXRpb24gbG9vcCAuLi4gICAgICAgICAgICAgICAqLwogICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgIGRvIC8qIHVudGlsIG1heCBhbGxvd2VkIGJpdHMgcGVyIGZyYW1lIGFuZCBtYXhEeW5CaXRzIT0tMSovCiAgICAgIHsKICAgICAgICAgIHF1YW50aXphdGlvbkRvbmUgPSAwOwoKICAgICAgICAgICAgICBjID0gMDsgICAgICAgICAgICAgIC8qIGdldCBmcmFtZSB0byBwcm9jZXNzICovCgogICAgICAgICAgICAgIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIEVMRU1FTlRfSU5GTyBlbEluZm8gPSBjbS0+ZWxJbmZvW2ldOwogICAgICAgICAgICAgICAgICBJTlQgY2gsIG5DaGFubmVscyA9IGVsSW5mby5uQ2hhbm5lbHNJbkVsOwoKICAgICAgICAgICAgICAgICAgaWYgKChlbEluZm8uZWxUeXBlID09IElEX1NDRSkgfHwgKGVsSW5mby5lbFR5cGUgPT0gSURfQ1BFKSB8fAogICAgICAgICAgICAgICAgICAgICAgKGVsSW5mby5lbFR5cGUgPT0gSURfTEZFKSkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgZG8gLyogdW50aWwgc3BlY3RyYWwgdmFsdWVzIDwgTUFYX1FVQU5UICovCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29uc3RyYWludHNGdWxmaWxsZWRbY11baV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGREthYWNFbmNfcmVkdWNlQml0Q29uc3VtcHRpb24oJml0ZXJhdGlvbnNbY11baV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUUMtPm1heEl0ZXJhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGVjcmVhc2VCaXRDb25zdW1wdGlvbikgPyAxIDogLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaENvbnN0cmFpbnRzRnVsZmlsbGVkW2NdW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsY3VsYXRlUXVhbnRbY11baV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRbY10tPnBzeU91dEVsZW1lbnRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dFtjXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjRWxlbWVudFtjXVtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhRQy0+ZWxlbWVudEJpdHNbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwQ29uZmlnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNGdWxmaWxsZWRbY11baV0gPSAxIDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHF1YW50aXplIHNwZWN0cnVtIChwZXIgZWFjaCBjaGFubmVsKSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY2ggPSAwOyBjaCA8IG5DaGFubmVsczsgY2grKykKICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hDb25zdHJhaW50c0Z1bGZpbGxlZFtjXVtpXVtjaF0gPSAxOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGN1bGF0ZVF1YW50W2NdW2ldW2NoXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0NIQU5ORUwqIHFjT3V0Q2ggPSBxY0VsZW1lbnRbY11baV0tPnFjT3V0Q2hhbm5lbFtjaF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUX0NIQU5ORUwqIHBzeU91dENoID0gcHN5T3V0W2NdLT5wc3lPdXRFbGVtZW50W2ldLT5wc3lPdXRDaGFubmVsW2NoXTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxjdWxhdGVRdWFudFtjXVtpXVtjaF0gPSAwOyAvKiBjYWxjdWxhdGUgcXVhbnRpemF0aW9uIG9ubHkgaWYgbmVjZXNzYXJ5ICovCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkRLYWFjRW5jX1F1YW50aXplU3BlY3RydW0ocHN5T3V0Q2gtPnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5tYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5zZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5zZmJPZmZzZXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRDaC0+bWRjdFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRDaC0+Z2xvYmFsR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2gtPnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2gtPnF1YW50U3BlYykgOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChGREthYWNFbmNfY2FsY01heFZhbHVlSW5TZmIocHN5T3V0Q2gtPnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaC0+bWF4U2ZiUGVyR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2gtPnNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5zZmJPZmZzZXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2gtPnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dENoLT5tYXhWYWx1ZUluU2ZiKSA+IE1BWF9RVUFOVCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hDb25zdHJhaW50c0Z1bGZpbGxlZFtjXVtpXVtjaF0gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0Z1bGZpbGxlZFtjXVtpXSA9IDAgOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpZiBxdWFuaXp0ZWQgdmFsdWUgb3V0IG9mIHJhbmdlOyBpbmNyZWFzZSBnbG9iYWwgZ2FpbiEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VCaXRDb25zdW1wdGlvbiA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSAvKiBpZiBjYWxjdWxhdGVRdWFudFtjXVtpXVtjaF0gKi8KCiAgICAgICAgICAgICAgICAgICAgICAgICAgfSAvKiBjaGFubmVsIGxvb3AgKi8KCiAgICAgICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHF1YW50aXplIHNwZWN0cnVtIChwZXIgZWFjaCBjaGFubmVsKSAqLwoKICAgICAgICAgICAgICAgICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgogICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoIWNvbnN0cmFpbnRzRnVsZmlsbGVkW2NdW2ldKSA7IC8qIGRvZXMgbm90IHJlZ2FyZCBiaXQgY29uc3VtcHRpb24gKi8KCgogICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgICAgICAgICAgICAgICAgcWNFbGVtZW50W2NdW2ldLT5keW5CaXRzVXNlZCA9IDAgOyAvKiByZXNldCBkeW5hbWljIGJpdHMgKi8KCiAgICAgICAgICAgICAgICAgICAgICAvKiBxdWFudGl6YXRpb24gdmFsaWQgaW4gY3VycmVudCBjaGFubmVsISAqLwogICAgICAgICAgICAgICAgICAgICAgZm9yIChjaCA9IDA7IGNoIDwgbkNoYW5uZWxzOyBjaCsrKQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMKiBxY091dENoID0gcWNFbGVtZW50W2NdW2ldLT5xY091dENoYW5uZWxbY2hdOwogICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAqcHN5T3V0Q2ggPSBwc3lPdXRbY10tPnBzeU91dEVsZW1lbnRbaV0tPnBzeU91dENoYW5uZWxbY2hdOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3VudCBkeW5hbWljIGJpdHMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgY2hEeW5CaXRzID0gRkRLYWFjRW5jX2R5bkJpdENvdW50KGhRQy0+aEJpdENvdW50ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dENoLT5xdWFudFNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dENoLT5tYXhWYWx1ZUluU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRDaC0+c2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2gtPmxhc3RXaW5kb3dTZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5zZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaC0+bWF4U2ZiUGVyR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaC0+c2ZiUGVyR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaC0+c2ZiT2Zmc2V0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZxY091dENoLT5zZWN0aW9uRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5ub2lzZU5yZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoLT5pc0Jvb2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaC0+aXNTY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzKSA7CgogICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN1bSB1cCBkeW5hbWljIGNoYW5uZWwgYml0cyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIHFjRWxlbWVudFtjXVtpXS0+ZHluQml0c1VzZWQgKz0gY2hEeW5CaXRzOwogICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgIC8qIHNhdmUgZHluQml0c1VzZWQgZm9yIGNvcnJlY3Rpb24gb2YgYml0czJwZSByZWxhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgaWYoaFFDLT5oQWRqVGhyLT5hZGpUaHJTdGF0ZUVsZW1baV0tPmR5bkJpdHNMYXN0PT0tMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGhRQy0+aEFkalRoci0+YWRqVGhyU3RhdGVFbGVtW2ldLT5keW5CaXRzTGFzdCA9IHFjRWxlbWVudFtjXVtpXS0+ZHluQml0c1VzZWQ7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0gIC8qICAtZW5kLSBpZihJRF9TQ0UgfHwgSURfQ1BFIHx8IElEX0xGRSkgKi8KCiAgICAgICAgICAgICAgfSAgLyogLWVuZC0gZWxlbWVudCBsb29wICovCgogICAgICAgICAgICAgIC8qIHVwZGF0ZSBkeW5CaXRzIG9mIGN1cnJlbnQgc3ViRnJhbWUgKi8KICAgICAgICAgICAgICBGREthYWNFbmNfdXBkYXRlVXNlZER5bkJpdHMoJnFjT3V0W2NdLT51c2VkRHluQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNFbGVtZW50W2NdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbSk7CgogICAgICAgICAgICAgIC8qIGdldCB0b3RhbCBjb25zdW1lZCBiaXRzLCBkeW4gYml0cyBpbiBhbGwgc3ViIGZyYW1lcyBoYXZlIHRvIGJlIHZhbGlkICovCiAgICAgICAgICAgICAgc3VtRHluQml0c0NvbnN1bWVkVG90YWwgPSBGREthYWNFbmNfZ2V0VG90YWxDb25zdW1lZER5bkJpdHMocWNPdXQsIG5TdWJGcmFtZXMpOwoKICAgICAgICAgICAgICBpZiAoc3VtRHluQml0c0NvbnN1bWVkVG90YWw9PS0xKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgcXVhbnRpemF0aW9uRG9uZSA9IDA7IC8qIGJpdCBjb25zdW1wdGlvbiBub3QgdmFsaWQgaW4gYWxsIHN1YiBmcmFtZXMgKi8KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBzdW1CaXRzQ29uc3VtZWRUb3RhbCA9IEZES2FhY0VuY19nZXRUb3RhbENvbnN1bWVkQml0cyhxY091dCwgcWNFbGVtZW50LCBjbSwgaFFDLT5nbG9iSGRyQml0cywgblN1YkZyYW1lcyk7CgogICAgICAgICAgICAgICAgLyogaW4gYWxsIGZyYW1lcyBhcmUgdmFsaWQgZHluYW1pYyBiaXRzICovCiAgICAgICAgICAgICAgICBpZiAoICgoc3VtQml0c0NvbnN1bWVkVG90YWwgPCB0b3RhbEF2YWlsYWJsZUJpdHMpIHx8IHFjT3V0W2NdLT51c2VkRHluQml0cz09MCkgJiYgKGRlY3JlYXNlQml0Q29uc3VtcHRpb249PTEpICYmIGNoZWNrTWluRnJhbWVCaXRzRGVtYW5kKHFjT3V0LGhRQy0+bWluQml0c1BlckZyYW1lLG5TdWJGcmFtZXMpCiAgICAgICAgICAgICAgICAgICAgICAvKigpKi8gICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBxdWFudGl6YXRpb25Eb25lID0gMTsgLyogZXhpdCBiaXQgYWRqdXN0bWVudCAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN1bUJpdHNDb25zdW1lZFRvdGFsID4gdG90YWxBdmFpbGFibGVCaXRzICYmIChkZWNyZWFzZUJpdENvbnN1bXB0aW9uPT0wKSApCi8vICAgICAgICAgICAgICAgICAgICAgIC8qKCkqLyAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHF1YW50aXphdGlvbkRvbmUgPSAwOyAvKiByZXNldCEgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgoKICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiAgICAgICAgICAgICAgaW50IGVtZXJnZW5jeUl0ZXJhdGlvbnMgPSAxOwogICAgICAgICAgICAgIGludCBkeW5CaXRzT3ZlcnNob290ICAgID0gMDsKCiAgICAgICAgICAgICAgZm9yIChjID0gMCA7IGMgPCBuU3ViRnJhbWVzIDsgYysrICkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgRUxFTUVOVF9JTkZPIGVsSW5mbyA9IGNtLT5lbEluZm9baV07CgogICAgICAgICAgICAgICAgICAgICAgaWYgKChlbEluZm8uZWxUeXBlID09IElEX1NDRSkgfHwgKGVsSW5mby5lbFR5cGUgPT0gSURfQ1BFKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgIChlbEluZm8uZWxUeXBlID09IElEX0xGRSkpCiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZXJhdGlvbiBsaW1pdGF0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGVtZXJnZW5jeUl0ZXJhdGlvbnMgJj0gKChpdGVyYXRpb25zW2NdW2ldIDwgaFFDLT5tYXhJdGVyYXRpb25zKSA/IDAgOiAxKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvKiBkZXRlY3Rpb24gaWYgdXNlZCBkeW4gYml0cyBleGNlZWRzIHRoZSBtYXhpbWFsIGFsbG93ZWQgY3JpdGVyaW9uICovCiAgICAgICAgICAgICAgICAgIGR5bkJpdHNPdmVyc2hvb3QgfD0gKChxY091dFtjXS0+dXNlZER5bkJpdHMgPiBxY091dFtjXS0+bWF4RHluQml0cykgPyAxIDogMCk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBpZiAocXVhbnRpemF0aW9uRG9uZT09MCB8fCBkeW5CaXRzT3ZlcnNob290KQogICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgIGludCBzdW1CaXRzQ29uc3VtZWRUb3RhbCA9IEZES2FhY0VuY19nZXRUb3RhbENvbnN1bWVkQml0cyhxY091dCwgcWNFbGVtZW50LCBjbSwgaFFDLT5nbG9iSGRyQml0cywgblN1YkZyYW1lcyk7CgogICAgICAgICAgICAgICAgICBpZiAoIChzdW1EeW5CaXRzQ29uc3VtZWRUb3RhbCA+PSBhdmdUb3RhbER5bkJpdHMpIHx8IChzdW1EeW5CaXRzQ29uc3VtZWRUb3RhbD09MCkgKSB7CiAgICAgICAgICAgICAgICAgICAgICBxdWFudGl6YXRpb25Eb25lID0gMTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZW1lcmdlbmN5SXRlcmF0aW9ucyAmJiAoc3VtQml0c0NvbnN1bWVkVG90YWwgPCB0b3RhbEF2YWlsYWJsZUJpdHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICBxdWFudGl6YXRpb25Eb25lID0gMTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoKHN1bUJpdHNDb25zdW1lZFRvdGFsID4gdG90YWxBdmFpbGFibGVCaXRzKSB8fCAhY2hlY2tNaW5GcmFtZUJpdHNEZW1hbmQocWNPdXQsaFFDLT5taW5CaXRzUGVyRnJhbWUsblN1YkZyYW1lcykpIHsKICAgICAgICAgICAgICAgICAgICAgIHF1YW50aXphdGlvbkRvbmUgPSAwOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmICgoc3VtQml0c0NvbnN1bWVkVG90YWwgPCB0b3RhbEF2YWlsYWJsZUJpdHMpICYmIGNoZWNrTWluRnJhbWVCaXRzRGVtYW5kKHFjT3V0LGhRQy0+bWluQml0c1BlckZyYW1lLG5TdWJGcmFtZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzZUJpdENvbnN1bXB0aW9uID0gMDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIGRlY3JlYXNlQml0Q29uc3VtcHRpb24gPSAxOwogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICBpZiAoZHluQml0c092ZXJzaG9vdCkgewogICAgICAgICAgICAgICAgICAgICBxdWFudGl6YXRpb25Eb25lID0gMDsKICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VCaXRDb25zdW1wdGlvbiA9IDE7CiAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgIC8qIHJlc2V0IGNvbnN0cmFpbnRzIGZ1bGxmaWxsZWQgZmxhZ3MgKi8KICAgICAgICAgICAgICAgICAgRkRLbWVtY2xlYXIoY29uc3RyYWludHNGdWxmaWxsZWQsIHNpemVvZihjb25zdHJhaW50c0Z1bGZpbGxlZCkpOwogICAgICAgICAgICAgICAgICBGREttZW1jbGVhcihjaENvbnN0cmFpbnRzRnVsZmlsbGVkLCBzaXplb2YoY2hDb25zdHJhaW50c0Z1bGZpbGxlZCkpOwoKCiAgICAgICAgICAgICAgfS8qIHF1YW50aXphdGlvbkRvbmUgKi8KCiAgICAgIH0gd2hpbGUgKCFxdWFudGl6YXRpb25Eb25lKSA7CgogICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgIC8qIC4uLiAtZW5kLSBRdWFudGl6YXRpb24gbG9vcCAgICAgICAgICAgICAgICAgKi8KICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKCnN0YXRpYyBBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfcmVkdWNlQml0Q29uc3VtcHRpb24oaW50KiAgICAgICAgICAgICBpdGVyYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ICAgICAgICBtYXhJdGVyYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICBnYWluQWRqdXN0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCogICAgICAgICAgICAgY2hDb25zdHJhaW50c0Z1bGZpbGxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCogICAgICAgICAgICAgY2FsY3VsYXRlUXVhbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfRUxFTUVOVCogcHN5T3V0RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVCogICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfRUxFTUVOVCogIHFjT3V0RWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1FTlRfQklUUyogICAgZWxCaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVVESU9fT0JKRUNUX1RZUEUgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICAgICAgICAgZXBDb25maWcpCnsKICBpbnQgY2g7CgogIC8qKiBTT0xWSU5HIFBST0JMRU0gKiovCiAgaWYgKCgqaXRlcmF0aW9ucykrKyA+PSBtYXhJdGVyYXRpb25zKQogIHsKICAgIGlmIChxY091dEVsZW1lbnQtPmR5bkJpdHNVc2VkPT0wKSB7CiAgICB9CiAgICAvKiBjcmFzaCByZWNvdmVyeSAqLwogICAgZWxzZSB7CiAgICAgIElOVCBiaXRzVG9TYXZlID0gMDsKICAgICAgaWYgKCAoYml0c1RvU2F2ZSA9IGZpeE1heCgocWNPdXRFbGVtZW50LT5keW5CaXRzVXNlZCArIDgpIC0gKGVsQml0cy0+Yml0UmVzTGV2ZWxFbCArIHFjT3V0RWxlbWVudC0+Z3JhbnRlZER5bkJpdHMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChxY091dEVsZW1lbnQtPmR5bkJpdHNVc2VkICsgcWNPdXRFbGVtZW50LT5zdGF0aWNCaXRzVXNlZCArIDgpIC0gKGVsQml0cy0+bWF4Qml0c0VsKSkpID4gMCApCiAgICAgIHsKICAgICAgICBGREthYWNFbmNfY3Jhc2hSZWNvdmVyeShuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICBxY091dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICBiaXRzVG9TYXZlLAogICAgICAgICAgICAgICAgICAgICAgYW90LAogICAgICAgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICBlcENvbmZpZykgOwogICAgfQogICAgZWxzZQogICAgewogICAgICBmb3IgKGNoID0gMDsgY2ggPCBuQ2hhbm5lbHM7IGNoKyspCiAgICAgIHsKICAgICAgICAgIHFjT3V0RWxlbWVudC0+cWNPdXRDaGFubmVsW2NoXS0+Z2xvYmFsR2FpbiArPSAxOwogICAgICB9CiAgICB9CiAgICBmb3IgKGNoID0gMDsgY2ggPCBuQ2hhbm5lbHM7IGNoKyspCiAgICB7CiAgICAgIGNhbGN1bGF0ZVF1YW50W2NoXSA9IDE7CiAgICB9CiAgfQogIH0KICBlbHNlIC8qIGl0ZXJhdGlvbnMgPj0gbWF4SXRlcmF0aW9ucyAqLwogIHsKICAgIC8qIGluY3JlYXNlIGdhaW4gKCsgbmV4dCBpdGVyYXRpb24pICovCiAgICBmb3IgKGNoID0gMDsgY2ggPCBuQ2hhbm5lbHM7IGNoKyspCiAgICB7CiAgICAgIGlmKCFjaENvbnN0cmFpbnRzRnVsZmlsbGVkW2NoXSkKICAgICAgewogICAgICAgICAgcWNPdXRFbGVtZW50LT5xY091dENoYW5uZWxbY2hdLT5nbG9iYWxHYWluICs9IGdhaW5BZGp1c3RtZW50IDsKICAgICAgICAgIGNhbGN1bGF0ZVF1YW50W2NoXSA9IDE7IC8qIGdsb2JhbCBnYWluIGhhcyBjaGFuZ2VkLCByZWNhbGN1bGF0ZSBxdWFudGl6YXRpb24gaW4gbmV4dCBpdGVyYXRpb24hICovCiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBBQUNfRU5DX09LOwp9CgpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfdXBkYXRlRmlsbEJpdHMoQ0hBTk5FTF9NQVBQSU5HKiAgICAgICAgICBjbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX1NUQVRFKiAgICAgICAgICAgICAgICAgcWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTEVNRU5UX0JJVFMqIFJFU1RSSUNUICAgIGVsQml0c1soOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUKiogICAgICAgICAgICAgICAgICBxY091dCkKewogIHN3aXRjaCAocWNLZXJuZWwtPmJpdHJhdGVNb2RlKSB7CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX1NGUjoKICAgICAgYnJlYWs7CgogICAgY2FzZSBRQ0RBVEFfQlJfTU9ERV9GRjoKICAgICAgIGJyZWFrOwoKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfVkJSXzE6CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX1ZCUl8yOgogICAgY2FzZSBRQ0RBVEFfQlJfTU9ERV9WQlJfMzoKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfVkJSXzQ6CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX1ZCUl81OgogICAgICBxY091dFswXS0+dG90RmlsbEJpdHMgPSAocWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzIC0gcWNPdXRbMF0tPnVzZWREeW5CaXRzKSY3OyAvKiBwcmVjYWxjdWxhdGUgYWxpZ25tZW50IGJpdHMgKi8KICAgICAgcWNPdXRbMF0tPnRvdGFsQml0cyA9IHFjT3V0WzBdLT5zdGF0aWNCaXRzICsgcWNPdXRbMF0tPnVzZWREeW5CaXRzICsgcWNPdXRbMF0tPnRvdEZpbGxCaXRzICsgcWNPdXRbMF0tPmVsZW1lbnRFeHRCaXRzICsgcWNPdXRbMF0tPmdsb2JhbEV4dEJpdHM7CiAgICAgIHFjT3V0WzBdLT50b3RGaWxsQml0cyArPSAoIGZpeE1heCgwLCBxY0tlcm5lbC0+bWluQml0c1BlckZyYW1lIC0gcWNPdXRbMF0tPnRvdGFsQml0cykgKyA3KSAmIH43OwogICAgICBicmVhazsKCiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX0NCUjoKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfSU5WQUxJRDoKICAgIGRlZmF1bHQ6CiAgICAgIElOVCBiaXRSZXNTcGFjZSA9IHFjS2VybmVsLT5iaXRSZXNUb3RNYXggLSBxY0tlcm5lbC0+Yml0UmVzVG90IDsKICAgICAgLyogcHJvY2Vzc2luZyBmaWxsLWJpdHMgKi8KICAgICAgSU5UIGRlbHRhQml0UmVzID0gcWNPdXRbMF0tPmdyYW50ZWREeW5CaXRzIC0gcWNPdXRbMF0tPnVzZWREeW5CaXRzIDsKICAgICAgcWNPdXRbMF0tPnRvdEZpbGxCaXRzID0gZml4TWF4KChkZWx0YUJpdFJlcyY3KSwgKGRlbHRhQml0UmVzIC0gKGZpeE1heCgwLGJpdFJlc1NwYWNlLTcpJn43KSkpOwogICAgICBxY091dFswXS0+dG90YWxCaXRzID0gcWNPdXRbMF0tPnN0YXRpY0JpdHMgKyBxY091dFswXS0+dXNlZER5bkJpdHMgKyBxY091dFswXS0+dG90RmlsbEJpdHMgKyBxY091dFswXS0+ZWxlbWVudEV4dEJpdHMgKyBxY091dFswXS0+Z2xvYmFsRXh0Qml0czsKICAgICAgcWNPdXRbMF0tPnRvdEZpbGxCaXRzICs9ICggZml4TWF4KDAsIHFjS2VybmVsLT5taW5CaXRzUGVyRnJhbWUgLSBxY091dFswXS0+dG90YWxCaXRzKSArIDcpICYgfjc7CiAgICAgIGJyZWFrOwogIH0gLyogc3dpdGNoIChxY0tlcm5lbC0+Yml0cmF0ZU1vZGUpICovCgogIHJldHVybiBBQUNfRU5DX09LOwp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgICAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19jYWxjTWF4VmFsdWVJblNmYgogICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgcmV0dXJuOgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBJTlQgRkRLYWFjRW5jX2NhbGNNYXhWYWx1ZUluU2ZiKElOVCAgIHNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICBtYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICBzZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICpSRVNUUklDVCBzZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKlJFU1RSSUNUIHF1YW50U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAqUkVTVFJJQ1QgbWF4VmFsdWUpCnsKICBJTlQgc2ZiT2ZmcyxzZmI7CiAgSU5UIG1heFZhbHVlQWxsID0gMDsKCiAgZm9yIChzZmJPZmZzPTA7c2ZiT2ZmczxzZmJDbnQ7c2ZiT2Zmcys9c2ZiUGVyR3JvdXApCiAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IG1heFNmYlBlckdyb3VwOyBzZmIrKykKICAgIHsKICAgICAgSU5UIGxpbmU7CiAgICAgIElOVCBtYXhUaGlzU2ZiID0gMDsKICAgICAgZm9yIChsaW5lID0gc2ZiT2Zmc2V0W3NmYk9mZnMrc2ZiXTsgbGluZSA8IHNmYk9mZnNldFtzZmJPZmZzK3NmYisxXTsgbGluZSsrKQogICAgICB7CiAgICAgICAgSU5UIHRtcCA9IGZpeHBfYWJzKHF1YW50U3BlY3RydW1bbGluZV0pOwogICAgICAgIG1heFRoaXNTZmIgPSBmaXhNYXgodG1wLCBtYXhUaGlzU2ZiKTsKICAgICAgfQoKICAgICAgbWF4VmFsdWVbc2ZiT2ZmcytzZmJdID0gbWF4VGhpc1NmYjsKICAgICAgbWF4VmFsdWVBbGwgPSBmaXhNYXgobWF4VGhpc1NmYiwgbWF4VmFsdWVBbGwpOwogICAgfQogIHJldHVybiBtYXhWYWx1ZUFsbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICAgICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX3VwZGF0ZUJpdHJlcwogICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgcmV0dXJuOgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBGREthYWNFbmNfdXBkYXRlQml0cmVzKENIQU5ORUxfTUFQUElORyAqY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19TVEFURSogcWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVQqKiBxY091dCkKewogIHN3aXRjaCAocWNLZXJuZWwtPmJpdHJhdGVNb2RlKSB7CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX0ZGOgogICAgY2FzZSBRQ0RBVEFfQlJfTU9ERV9WQlJfMToKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfVkJSXzI6CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX1ZCUl8zOgogICAgY2FzZSBRQ0RBVEFfQlJfTU9ERV9WQlJfNDoKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfVkJSXzU6CiAgICAgIC8qIHZhcmlhYmxlIGJpdHJhdGUgKi8KICAgICAgcWNLZXJuZWwtPmJpdFJlc1RvdCA9IEZES21pbihxY0tlcm5lbC0+bWF4Qml0c1BlckZyYW1lLCBxY0tlcm5lbC0+Yml0UmVzVG90TWF4KTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBRQ0RBVEFfQlJfTU9ERV9DQlI6CiAgICBjYXNlIFFDREFUQV9CUl9NT0RFX1NGUjoKICAgIGNhc2UgUUNEQVRBX0JSX01PREVfSU5WQUxJRDoKICAgIGRlZmF1bHQ6CiAgICAgIGludCBjID0gMDsKICAgICAgLyogY29uc3RhbnQgYml0cmF0ZSAqLwogICAgICB7CiAgICAgICAgcWNLZXJuZWwtPmJpdFJlc1RvdCArPSBxY091dFtjXS0+Z3JhbnRlZER5bkJpdHMgLSAocWNPdXRbY10tPnVzZWREeW5CaXRzICsgcWNPdXRbY10tPnRvdEZpbGxCaXRzICsgcWNPdXRbY10tPmFsaWduQml0cyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgICAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19GaW5hbGl6ZUJpdENvbnN1bXB0aW9uCiAgICAgICAgIGRlc2NyaXB0aW9uOgogICAgICAgICByZXR1cm46CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfRmluYWxpemVCaXRDb25zdW1wdGlvbihDSEFOTkVMX01BUFBJTkcgKmNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19TVEFURSAqcWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVCAqcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9FTEVNRU5UKiogcWNFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVVESU9fT0JKRUNUX1RZUEUgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICAgICAgICAgICAgZXBDb25maWcpCnsKICBRQ19PVVRfRVhURU5TSU9OIGZpbGxFeHRQYXlsb2FkOwogIElOVCB0b3RGaWxsQml0cywgYWxpZ25CaXRzOwoKICAvKiBHZXQgdG90YWwgY29uc3VtZWQgYml0cyBpbiBBVSAqLwogIHFjT3V0LT50b3RhbEJpdHMgPSBxY091dC0+c3RhdGljQml0cyArIHFjT3V0LT51c2VkRHluQml0cyAgKyBxY091dC0+dG90RmlsbEJpdHMgKwogICAgICAgICAgICAgICAgICAgICBxY091dC0+ZWxlbWVudEV4dEJpdHMgKyBxY091dC0+Z2xvYmFsRXh0Qml0czsKCiAgaWYgKHFjS2VybmVsLT5iaXRyYXRlTW9kZT09UUNEQVRBX0JSX01PREVfQ0JSKSB7CgogICAgLyogTm93IHdlIGNhbiBnZXQgdGhlIGV4YWN0IHRyYW5zcG9ydCBiaXQgYW1vdW50LCBhbmQgaG9wZWZ1bGx5IGl0IGlzIGVxdWFsIHRvIHRoZSBlc3RpbWF0ZWQgdmFsdWUgKi8KICAgIElOVCBleGFjdFRwQml0cyA9IHRyYW5zcG9ydEVuY19HZXRTdGF0aWNCaXRzKGhUcEVuYywgcWNPdXQtPnRvdGFsQml0cyk7CgogICAgaWYgKGV4YWN0VHBCaXRzICE9IHFjS2VybmVsLT5nbG9iSGRyQml0cykgewogICAgICBJTlQgZGlmZkZpbGxCaXRzID0gMDsKCiAgICAgIC8qIEhvdyBtYW55IGJpdHMgY2FuIGJlIHRha2VuIGJ5IGJpdHJlc2Vydm9pciAqLwogICAgICBjb25zdCBJTlQgYml0cmVzU3BhY2UgPSBxY0tlcm5lbC0+Yml0UmVzVG90TWF4IC0gKHFjS2VybmVsLT5iaXRSZXNUb3QgKyAocWNPdXQtPmdyYW50ZWREeW5CaXRzIC0gKHFjT3V0LT51c2VkRHluQml0cyArIHFjT3V0LT50b3RGaWxsQml0cykgKSApOwoKICAgICAgLyogTnVtYmVyIG9mIGJpdHMgd2hpY2ggY2FuIGJlIG1vdmVkIHRvIGJpdHJlc2Vydm9pci4gKi8KICAgICAgY29uc3QgSU5UIGJpdHNUb0JpdHJlcyA9IHFjS2VybmVsLT5nbG9iSGRyQml0cyAtIGV4YWN0VHBCaXRzOwogICAgICBGREtfQVNTRVJUKGJpdHNUb0JpdHJlcz49MCk7IC8qIGlzIGFsd2F5cyBwb3NpdGl2ZSAqLwoKICAgICAgLyogSWYgYml0cmVzZXJ2b2lyIGNhbiBub3QgdGFrZSBhbGwgYml0cywgbW92ZSByYW1haW5pbmcgYml0cyB0byBmaWxsYml0cyAqLwogICAgICBkaWZmRmlsbEJpdHMgPSBGREttYXgoMCwgYml0c1RvQml0cmVzIC0gYml0cmVzU3BhY2UpOwoKICAgICAgLyogQXNzdXJlIHByZXZpb3VzIGFsaWdubWVudCAqLwogICAgICBkaWZmRmlsbEJpdHMgPSAoZGlmZkZpbGxCaXRzKzcpJn43OwoKICAgICAgLyogTW92ZSBhcyBtYW55IGJpdHMgYXMgcG9zc2libGUgdG8gYml0cmVzZXJ2b2lyICovCiAgICAgIHFjS2VybmVsLT5iaXRSZXNUb3QgICAgKz0gKGJpdHNUb0JpdHJlcy1kaWZmRmlsbEJpdHMpOwoKICAgICAgLyogV3JpdGUgcmVtYWluZyBiaXRzIGFzIGZpbGwgYml0cyAqLwogICAgICBxY091dC0+dG90RmlsbEJpdHMgICAgICs9IGRpZmZGaWxsQml0czsKICAgICAgcWNPdXQtPnRvdGFsQml0cyAgICAgICArPSBkaWZmRmlsbEJpdHM7CiAgICAgIHFjT3V0LT5ncmFudGVkRHluQml0cyAgKz0gZGlmZkZpbGxCaXRzOwoKICAgICAgLyogR2V0IG5ldyBoZWFkZXIgYml0cyAqLwogICAgICBxY0tlcm5lbC0+Z2xvYkhkckJpdHMgPSB0cmFuc3BvcnRFbmNfR2V0U3RhdGljQml0cyhoVHBFbmMsIHFjT3V0LT50b3RhbEJpdHMpOwoKICAgICAgaWYgKHFjS2VybmVsLT5nbG9iSGRyQml0cyAhPSBleGFjdFRwQml0cykgewogICAgICAgIC8qIEluIHByZXZpb3VzIHN0ZXAsIGZpbGwgYml0cyBhbmQgY29ycmVzcG9uZGluZyB0b3RhbCBiaXRzIHdlcmUgY2hhbmdlZCB3aGVuIGJpdHJlc2Vydm9pciB3YXMgY29tcGxldGVseSBmaWxsZWQuCiAgICAgICAgICAgTm93IHdlIGNhbiB0YWtlIHRoZSB0b28gbXVjaCB0YWtlbiBiaXRzIGNhdXNlZCBieSBoZWFkZXIgb3ZlcmhlYWQgZnJvbSBiaXRyZXNlcnZvaXIuCiAgICAgICAgICovCiAgICAgICAgcWNLZXJuZWwtPmJpdFJlc1RvdCAtPSAocWNLZXJuZWwtPmdsb2JIZHJCaXRzIC0gZXhhY3RUcEJpdHMpOwogICAgICB9CiAgICB9CgogIH0gLyogTU9ERV9DQlIgKi8KCiAgLyogVXBkYXRlIGV4YWN0IG51bWJlciBvZiBjb25zdW1lZCBoZWFkZXIgYml0cy4gKi8KICBxY0tlcm5lbC0+Z2xvYkhkckJpdHMgPSB0cmFuc3BvcnRFbmNfR2V0U3RhdGljQml0cyhoVHBFbmMsIHFjT3V0LT50b3RhbEJpdHMpOwoKICAvKiBTYXZlIHRvdGFsIGZpbGwgYml0cyBhbmQgZGlzdHJpYnV0IHRvIGFsaWdubWVudCBhbmQgZmlsbCBiaXRzICovCiAgdG90RmlsbEJpdHMgPSBxY091dC0+dG90RmlsbEJpdHM7CgogIC8qIGZha2UgYSBmaWxsIGV4dGVuc2lvbiBwYXlsb2FkICovCiAgRkRLbWVtY2xlYXIoJmZpbGxFeHRQYXlsb2FkLCBzaXplb2YoUUNfT1VUX0VYVEVOU0lPTikpOwoKICBmaWxsRXh0UGF5bG9hZC50eXBlID0gRVhUX0ZJTExfREFUQTsKICBmaWxsRXh0UGF5bG9hZC5uUGF5bG9hZEJpdHMgPSB0b3RGaWxsQml0czsKCiAgLyogYXNrIGJpdHN0cmVhbSBlbmNvZGVyIGhvdyBtYW55IG9mIHRoYXQgYml0cyBjYW4gYmUgd3JpdHRlbiBpbiBhIGZpbGwgZXh0ZW5zaW9uIGRhdGEgZW50aXR5ICovCiAgcWNPdXQtPnRvdEZpbGxCaXRzID0gRkRLYWFjRW5jX3dyaXRlRXh0ZW5zaW9uRGF0YSggTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmaWxsRXh0UGF5bG9hZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcENvbmZpZyApOwoKICAvKiBub3cgZGlzdHJpYnV0ZSBleHRyYSBmaWxsYml0cyBhbmQgYWxpZ25iaXRzICovCiAgYWxpZ25CaXRzID0gNyAtIChxY091dC0+c3RhdGljQml0cyArIHFjT3V0LT51c2VkRHluQml0cyArIHFjT3V0LT5lbGVtZW50RXh0Qml0cwogICAgICAgICAgICAgICAgICAgKyBxY091dC0+dG90RmlsbEJpdHMgKyBxY091dC0+Z2xvYmFsRXh0Qml0cyAtMSklODsKCiAgLyogTWF5YmUgd2UgY291bGQgcmVtb3ZlIHRoaXMgKi8KICBpZiggKChhbGlnbkJpdHMgKyBxY091dC0+dG90RmlsbEJpdHMgLSB0b3RGaWxsQml0cyk9PTgpICYmIChxY091dC0+dG90RmlsbEJpdHM+OCkgKQogICAgICAgIHFjT3V0LT50b3RGaWxsQml0cyAtPSA4OwoKICBxY091dC0+dG90YWxCaXRzID0gcWNPdXQtPnN0YXRpY0JpdHMgKyBxY091dC0+dXNlZER5bkJpdHMgKyBxY091dC0+dG90RmlsbEJpdHMgKwogICAgICAgICAgICAgICAgICAgICBhbGlnbkJpdHMgKyBxY091dC0+ZWxlbWVudEV4dEJpdHMgKyBxY091dC0+Z2xvYmFsRXh0Qml0czsKCiAgaWYgKCAocWNPdXQtPnRvdGFsQml0cz5xY0tlcm5lbC0+bWF4Qml0c1BlckZyYW1lKSB8fCAocWNPdXQtPnRvdGFsQml0czxxY0tlcm5lbC0+bWluQml0c1BlckZyYW1lKSApIHsKICAgIHJldHVybiBBQUNfRU5DX1FVQU5UX0VSUk9SOwogIH0KCiAgcWNPdXQtPmFsaWduQml0cyA9IGFsaWduQml0czsKCiAgcmV0dXJuIEFBQ19FTkNfT0s7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgICAgICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfY3Jhc2hSZWNvdmVyeQogICAgICAgICBkZXNjcmlwdGlvbjogIGZ1bGZpbGxzIGNvbnN0cmFpbnRzIGJ5IG1lYW5zIG9mIGJydXRlIGZvcmNlLi4uCiAgICAgICAgICAgICAgICAgICAgICAgPT4gYml0cyBhcmUgc2F2ZWQgYnkgY2FuY2VsbGluZyBvdXQgc3BlY3RyYWwgbGluZXMhIQogICAgICAgICAgICAgICAgICAgICAgICAgIChiZWdpbm5pbmcgYXQgdGhlIGhpZ2hlc3QgZnJlcXVlbmNpZXMpCiAgICAgICAgIHJldHVybjogICAgICAgZXJyb3Jjb2RlCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX2NyYXNoUmVjb3ZlcnkoSU5UICAgICAgICAgICAgICAgbkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfRUxFTUVOVCogIHBzeU91dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUKiAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0VMRU1FTlQgICAqcWNFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgIGJpdHNUb1NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgQVVESU9fT0JKRUNUX1RZUEUgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICAgICAgICAgIGVwQ29uZmlnKQp7CiAgSU5UIGNoIDsKICBJTlQgc2F2ZWRCaXRzID0gMCA7CiAgSU5UIHNmYiwgc2ZiR3JwIDsKICBJTlQgYml0c1BlclNjZlsoMildW01BWF9HUk9VUEVEX1NGQl0gOwogIElOVCBzZWN0aW9uVG9TY2ZbKDIpXVtNQVhfR1JPVVBFRF9TRkJdIDsKICBJTlQgKnNmYk9mZnNldCA7CiAgSU5UIHNlY3QsIHN0YXRCaXRzTmV3IDsKICBRQ19PVVRfQ0hBTk5FTCAqKnFjQ2hhbm5lbCA9IHFjRWxlbWVudC0+cWNPdXRDaGFubmVsOwogIFBTWV9PVVRfQ0hBTk5FTCAqKnBzeUNoYW5uZWwgPSBwc3lPdXRFbGVtZW50LT5wc3lPdXRDaGFubmVsOwoKICAvKiBjcmVhdGUgYSB0YWJsZSB3aGljaCBjb252ZXJ0cyBmcnEtYmlucyB0byBiaXQtZGVtYW5kLi4uICAgIFtiaXRzUGVyU2NmXSAqLwogIC8qIC4uLmFuZCBhbm90aGVyIG9uZSB3aGljaCBob2xkcyB0aGUgY29ycmVzcG9uZGluZyBzZWN0aW9ucyBbc2VjdGlvblRvU2NmXSAqLwogIGZvciAoY2ggPSAwOyBjaCA8IG5DaGFubmVsczsgY2grKykKICB7CiAgICBzZmJPZmZzZXQgPSBwc3lDaGFubmVsW2NoXS0+c2ZiT2Zmc2V0cyA7CgogICAgZm9yIChzZWN0ID0gMDsgc2VjdCA8IHFjQ2hhbm5lbFtjaF0tPnNlY3Rpb25EYXRhLm5vT2ZTZWN0aW9uczsgc2VjdCsrKQogICAgewogICAgICBJTlQgc2ZiIDsKICAgICAgSU5UIGNvZGVCb29rID0gcWNDaGFubmVsW2NoXS0+c2VjdGlvbkRhdGEuaHVmZnNlY3Rpb25bc2VjdF0uY29kZUJvb2sgOwoKICAgICAgZm9yIChzZmIgPSBxY0NoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5odWZmc2VjdGlvbltzZWN0XS5zZmJTdGFydDsKICAgICAgICAgICBzZmIgPCBxY0NoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5odWZmc2VjdGlvbltzZWN0XS5zZmJTdGFydCArCiAgICAgICAgICAgICAgICAgcWNDaGFubmVsW2NoXS0+c2VjdGlvbkRhdGEuaHVmZnNlY3Rpb25bc2VjdF0uc2ZiQ250OwogICAgICAgICAgIHNmYisrKQogICAgICB7CiAgICAgICAgYml0c1BlclNjZltjaF1bc2ZiXSA9IDA7CiAgICAgICAgaWYgKCAoY29kZUJvb2sgIT0gQ09ERV9CT09LX1BOU19OTykgLyomJgogICAgICAgICAgICAgKHNmYiA8IChxY0NoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5ub09mR3JvdXBzKnFjQ2hhbm5lbFtjaF0tPnNlY3Rpb25EYXRhLm1heFNmYlBlckdyb3VwKSkqLyApCiAgICAgICAgewogICAgICAgICAgICBJTlQgc2ZiU3RhcnRMaW5lID0gc2ZiT2Zmc2V0W3NmYl0gOwogICAgICAgICAgICBJTlQgbm9PZkxpbmVzICAgID0gc2ZiT2Zmc2V0W3NmYisxXSAtIHNmYlN0YXJ0TGluZSA7CiAgICAgICAgICAgIGJpdHNQZXJTY2ZbY2hdW3NmYl0gPSBGREthYWNFbmNfY291bnRWYWx1ZXMoJihxY0NoYW5uZWxbY2hdLT5xdWFudFNwZWNbc2ZiU3RhcnRMaW5lXSksIG5vT2ZMaW5lcywgY29kZUJvb2spIDsKICAgICAgICB9CiAgICAgICAgc2VjdGlvblRvU2NmW2NoXVtzZmJdID0gc2VjdCA7CiAgICAgIH0KCiAgICB9CiAgfQoKICAvKiBMT1dFUiBbbWF4U2ZiXSBJTiBCT1RIIENIQU5ORUxTISEgKi8KICAvKiBBdHRlbnRpb246IGluIGNhc2Ugb2Ygc3RlcmVvOiBtYXhTZmJMID09IG1heFNmYlIsIEdyb3VwaW5nTCA9PSBHcm91cGluZ1IgOyAqLwoKICBmb3IgKHNmYiA9IHFjQ2hhbm5lbFswXS0+c2VjdGlvbkRhdGEubWF4U2ZiUGVyR3JvdXAtMTsgc2ZiID49IDA7IHNmYi0tKQogIHsKICAgIGZvciAoc2ZiR3JwID0gMDsgc2ZiR3JwIDwgcHN5Q2hhbm5lbFswXS0+c2ZiQ250OyBzZmJHcnAgKz0gcHN5Q2hhbm5lbFswXS0+c2ZiUGVyR3JvdXApCiAgICB7CiAgICAgIGZvciAoY2ggPSAwOyBjaCA8IG5DaGFubmVsczsgY2grKykKICAgICAgewogICAgICAgIGludCBzZWN0ID0gc2VjdGlvblRvU2NmW2NoXVtzZmJHcnArc2ZiXTsKICAgICAgICBxY0NoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5odWZmc2VjdGlvbltzZWN0XS5zZmJDbnQtLSA7CiAgICAgICAgc2F2ZWRCaXRzICs9IGJpdHNQZXJTY2ZbY2hdW3NmYkdycCtzZmJdIDsKCiAgICAgICAgaWYgKHFjQ2hhbm5lbFtjaF0tPnNlY3Rpb25EYXRhLmh1ZmZzZWN0aW9uW3NlY3RdLnNmYkNudCA9PSAwKSB7CiAgICAgICAgICBzYXZlZEJpdHMgKz0gKHBzeUNoYW5uZWxbY2hdLT5sYXN0V2luZG93U2VxdWVuY2UhPVNIT1JUX1dJTkRPVykgPyBGREthYWNFbmNfc2lkZUluZm9UYWJMb25nWzBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEZES2FhY0VuY19zaWRlSW5mb1RhYlNob3J0WzBdOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8qIC4uLmhhdmUgZW5vdWdoIGJpdHMgYmVlbiBzYXZlZD8gKi8KICAgIGlmIChzYXZlZEJpdHMgPj0gYml0c1RvU2F2ZSkKICAgICAgYnJlYWsgOwoKICB9IC8qIHNmYiBsb29wICovCgogIC8qIGlmIG5vdCBlbm91Z2ggYml0cyBzYXZlZCwKICAgICBjbGVhbiB3aG9sZSBzcGVjdHJ1bSBhbmQgcmVtb3ZlIHNpZGUgaW5mbyBvdmVyaGVhZCAqLwogIGlmIChzZmIgPT0gLTEpIHsKICAgIHNmYiA9IDAgOwogIH0KCiAgZm9yIChjaCA9IDA7IGNoIDwgbkNoYW5uZWxzOyBjaCsrKQogIHsKICAgIHFjQ2hhbm5lbFtjaF0tPnNlY3Rpb25EYXRhLm1heFNmYlBlckdyb3VwID0gc2ZiIDsKICAgIHBzeUNoYW5uZWxbY2hdLT5tYXhTZmJQZXJHcm91cCA9IHNmYiA7CiAgICAvKiB3aGVuIG5vIHNwZWN0cnVtIGlzIGNvZGVkIHNhdmUgdG9vbHMgaW5mbyBpbiBiaXRzdHJlYW0gKi8KICAgIGlmKHNmYj09MCkgewogICAgICBGREttZW1jbGVhcigmcHN5Q2hhbm5lbFtjaF0tPnRuc0luZm8sIHNpemVvZihUTlNfSU5GTykpOwogICAgICBGREttZW1jbGVhcigmcHN5T3V0RWxlbWVudC0+dG9vbHNJbmZvLCBzaXplb2YoVE9PTFNJTkZPKSk7CiAgICB9CiAgfQogIC8qIGR5bmFtaWMgYml0cyB3aWxsIGJlIHVwZGF0ZWQgaW4gaXRlcmF0aW9uIGxvb3AgKi8KCiAgeyAvKiBpZiBzdG9wIHNmYiBoYXMgY2hhbmdlZCBzYXZlIGJpdHMgaW4gc2lkZSBpbmZvLCBlLmcuIE1TIG9yIFROUyBjb2RpbmcgKi8KICAgIEVMRU1FTlRfSU5GTyBlbEluZm87CgogICAgRkRLbWVtY2xlYXIoJmVsSW5mbywgc2l6ZW9mKEVMRU1FTlRfSU5GTykpOwogICAgZWxJbmZvLm5DaGFubmVsc0luRWwgPSBuQ2hhbm5lbHM7CiAgICBlbEluZm8uZWxUeXBlID0gKG5DaGFubmVscyA9PSAyKSA/IElEX0NQRSA6IElEX1NDRTsKCiAgICBGREthYWNFbmNfQ2hhbm5lbEVsZW1lbnRXcml0ZSggTlVMTCwgJmVsSW5mbywgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRFbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeUNoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXRCaXRzTmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgKTsKICB9CgogIHNhdmVkQml0cyA9IHFjRWxlbWVudC0+c3RhdGljQml0c1VzZWQgLSBzdGF0Qml0c05ldzsKCiAgLyogdXBkYXRlIHN0YXRpYyBhbmQgZHluYW1pYyBiaXRzICovCiAgcWNFbGVtZW50LT5zdGF0aWNCaXRzVXNlZCAtPSBzYXZlZEJpdHM7CiAgcWNFbGVtZW50LT5ncmFudGVkRHluQml0cyArPSBzYXZlZEJpdHM7CgogIHFjT3V0LT5zdGF0aWNCaXRzICAgICAtPSBzYXZlZEJpdHM7CiAgcWNPdXQtPmdyYW50ZWREeW5CaXRzICs9IHNhdmVkQml0czsKICBxY091dC0+bWF4RHluQml0cyAgICAgKz0gc2F2ZWRCaXRzOwoKCn0KCgoKdm9pZCAgRkRLYWFjRW5jX1FDQ2xvc2UgKFFDX1NUQVRFICAqKnBoUUNzdGF0ZSwgUUNfT1VUICoqcGhRQykKewogIGludCBuLCBpOwoKICBpZiAocGhRQyE9TlVMTCkgewoKICAgIGZvciAobj0wO248KDEpO24rKykgewogICAgICBpZiAocGhRQ1tuXSAhPSBOVUxMKSB7CiAgICAgICAgUUNfT1VUICAgICpoUUMgICAgICA9IHBoUUNbbl07CiAgICAgICAgZm9yIChpPTA7IGk8KDgpOyBpKyspIHsKICAgICAgICB9CgogICAgICAgIGZvciAoaT0wOyBpPCg4KTsgaSsrKSB7CiAgICAgICAgICBpZiAoaFFDLT5xY0VsZW1lbnRbaV0pCiAgICAgICAgICAgIEZyZWVSYW1fYWFjRW5jX1FDZWxlbWVudCgmaFFDLT5xY0VsZW1lbnRbaV0pOwogICAgICAgIH0KCiAgICAgICAgRnJlZVJhbV9hYWNFbmNfUUNvdXQoJnBoUUNbbl0pOwogICAgICB9CiAgICB9CiAgfQoKICBpZiAocGhRQ3N0YXRlIT1OVUxMKSB7CiAgICBpZiAoKnBoUUNzdGF0ZSAhPSBOVUxMKSB7CiAgICAgIFFDX1NUQVRFICAqaFFDc3RhdGUgPSAqcGhRQ3N0YXRlOwoKICAgICAgaWYgKGhRQ3N0YXRlLT5oQWRqVGhyICE9IE5VTEwpCiAgICAgICAgRkRLYWFjRW5jX0FkalRockNsb3NlKCZoUUNzdGF0ZS0+aEFkalRocik7CgogICAgICBpZiAoaFFDc3RhdGUtPmhCaXRDb3VudGVyICE9IE5VTEwpCiAgICAgICAgRkRLYWFjRW5jX0JDQ2xvc2UoJmhRQ3N0YXRlLT5oQml0Q291bnRlcik7CgogICAgICBmb3IgKGk9MDsgaTwoOCk7IGkrKykgewogICAgICAgIGlmIChoUUNzdGF0ZS0+ZWxlbWVudEJpdHNbaV0hPU5VTEwpIHsKICAgICAgICAgIEZyZWVSYW1fYWFjRW5jX0VsZW1lbnRCaXRzKCZoUUNzdGF0ZS0+ZWxlbWVudEJpdHNbaV0pOwogICAgICAgIH0KICAgICAgfQogICAgICBGcmVlUmFtX2FhY0VuY19RQ3N0YXRlKHBoUUNzdGF0ZSk7CiAgICB9CiAgfQp9Cgo=