Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqICBGYXN0IE1QRUcgQUFDIEF1ZGlvIEVuY29kZXIgICoqKioqKioqKioqKioqKioqKioqKioKCiAgIEluaXRpYWwgYXV0aG9yOiAgICAgICBNLiBTY2h1ZyAvIEEuIEdyb2VzY2hlbAogICBjb250ZW50cy9kZXNjcmlwdGlvbjogZmFzdCBhYWMgY29kZXIgZnVuY3Rpb25zCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jLmgiCgojaW5jbHVkZSAiYml0ZW5jLmgiCiNpbmNsdWRlICJpbnRlcmZhY2UuaCIKI2luY2x1ZGUgInBzeV9jb25maWd1cmF0aW9uLmgiCiNpbmNsdWRlICJwc3lfbWFpbi5oIgojaW5jbHVkZSAicWNfbWFpbi5oIgojaW5jbHVkZSAiYmFuZHdpZHRoLmgiCiNpbmNsdWRlICJjaGFubmVsX21hcC5oIgojaW5jbHVkZSAidG5zX2Z1bmMuaCIKI2luY2x1ZGUgImFhY0VuY19yYW0uaCIKCiNpbmNsdWRlICJnZW5lcmljU3Rkcy5oIgoKCgoKI2RlZmluZSBNSU5fQlVGU0laRV9QRVJfRUZGX0NIQU4gNjE0NAoKc3RhdGljIEFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19Jbml0Q2hlY2tBbmNpbGxhcnkoSU5UIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBmcmFtZWxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGFuY2lsbGFyeVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqYW5jaWxsYXJ5Qml0c1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSk7CgpJTlQgRkRLYWFjRW5jX0xpbWl0Qml0cmF0ZSgKICAgICAgICBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywKICAgICAgICBJTlQgY29yZVNhbXBsaW5nUmF0ZSwKICAgICAgICBJTlQgZnJhbWVMZW5ndGgsCiAgICAgICAgSU5UIG5DaGFubmVscywKICAgICAgICBJTlQgbkNoYW5uZWxzRWZmLAogICAgICAgIElOVCBiaXRSYXRlLAogICAgICAgIElOVCBhdmVyYWdlQml0cywKICAgICAgICBJTlQgKnBBdmVyYWdlQml0c1BlckZyYW1lLAogICAgICAgIElOVCBiaXRyYXRlTW9kZSwKICAgICAgICBJTlQgblN1YkZyYW1lcwogICAgICAgICkKewogIElOVCB0cmFuc3BvcnRCaXRzLCBwcmV2Qml0UmF0ZSwgYXZlcmFnZUJpdHNQZXJGcmFtZSwgc2hpZnQgPSAwLCBpdGVyPTA7CgogIHdoaWxlICggKGZyYW1lTGVuZ3RoICYgfigoMTw8KHNoaWZ0KzEpKS0xKSkgPT0gZnJhbWVMZW5ndGgKICAgICYmIChjb3JlU2FtcGxpbmdSYXRlICYgfigoMTw8KHNoaWZ0KzEpKS0xKSkgPT0gY29yZVNhbXBsaW5nUmF0ZSApCiAgewogICAgc2hpZnQgKys7CiAgfQoKICBkbyB7CiAgICBwcmV2Qml0UmF0ZSA9IGJpdFJhdGU7CiAgICAgYXZlcmFnZUJpdHNQZXJGcmFtZSA9IChiaXRSYXRlKihmcmFtZUxlbmd0aD4+c2hpZnQpKSAvIChjb3JlU2FtcGxpbmdSYXRlPj5zaGlmdCkgLyBuU3ViRnJhbWVzOwoKICAgIGlmIChwQXZlcmFnZUJpdHNQZXJGcmFtZSAhPSBOVUxMKSB7CiAgICAgICpwQXZlcmFnZUJpdHNQZXJGcmFtZSA9IGF2ZXJhZ2VCaXRzUGVyRnJhbWU7CiAgICB9CgogICAgaWYgKGhUcEVuYyAhPSBOVUxMKSB7CiAgICAgIHRyYW5zcG9ydEJpdHMgPSB0cmFuc3BvcnRFbmNfR2V0U3RhdGljQml0cyhoVHBFbmMsIGF2ZXJhZ2VCaXRzUGVyRnJhbWUpOwogICAgfSBlbHNlIHsKICAgICAgLyogQXNzdW1lIHNvbWUgd29yc3QgY2FzZSAqLwogICAgICB0cmFuc3BvcnRCaXRzID0gMjA4OwogICAgfQoKICAgIGJpdFJhdGUgPSBGREttYXgoYml0UmF0ZSwgKCgoKDQwICogbkNoYW5uZWxzKSArIHRyYW5zcG9ydEJpdHMgKyBmcmFtZUxlbmd0aCkgKiAoY29yZVNhbXBsaW5nUmF0ZSkpIC8gZnJhbWVMZW5ndGgpICk7CiAgICBGREtfQVNTRVJUKGJpdFJhdGUgPj0gMCk7CgogICAgYml0UmF0ZSA9IEZES21pbihiaXRSYXRlLCAoKG5DaGFubmVsc0VmZiAqIE1JTl9CVUZTSVpFX1BFUl9FRkZfQ0hBTikqKGNvcmVTYW1wbGluZ1JhdGU+PnNoaWZ0KSkgLyAoZnJhbWVMZW5ndGg+PnNoaWZ0KSkgOwogICAgRkRLX0FTU0VSVChiaXRSYXRlID49IDApOwoKICB9IHdoaWxlIChwcmV2Qml0UmF0ZSAhPSBiaXRSYXRlICYmIGl0ZXIrKyA8IDMpIDsKCiAgcmV0dXJuIGJpdFJhdGU7Cn0KCgp0eXBlZGVmIHN0cnVjdAp7CiAgQUFDRU5DX0JJVFJBVEVfTU9ERSBiaXRyYXRlTW9kZTsKICBpbnQgY2hhbkJpdHJhdGVbMl07IC8qIG1vbm8vc3RlcmVvIHNldHRpbmdzICovCn0gQ09ORklHX1RBQl9FTlRSWV9WQlI7CgpzdGF0aWMgY29uc3QgQ09ORklHX1RBQl9FTlRSWV9WQlIgY29uZmlnVGFiVkJSW10gPSB7CiAge0FBQ0VOQ19CUl9NT0RFX0NCUiwgICB7ICAgICAwLCAgICAgMH19ICwKICB7QUFDRU5DX0JSX01PREVfVkJSXzEsIHsgMzIwMDAsIDIwMDAwfX0gLAogIHtBQUNFTkNfQlJfTU9ERV9WQlJfMiwgeyA0MDAwMCwgMzIwMDB9fSAsCiAge0FBQ0VOQ19CUl9NT0RFX1ZCUl8zLCB7IDU2MDAwLCA0ODAwMH19ICwKICB7QUFDRU5DX0JSX01PREVfVkJSXzQsIHsgNzIwMDAsIDY0MDAwfX0gLAogIHtBQUNFTkNfQlJfTU9ERV9WQlJfNSwgezExMjAwMCwgOTYwMDB9fQp9OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19HZXRWQlJCaXRyYXRlCiAgICAgZGVzY3JpcHRpb246ICBHZXQgVkJSIGJpdHJhdGUgZnJvbSB2YnIgcXVhbGl0eQogICAgIGlucHV0IHBhcmFtczogaW50IHZiclF1YWxpdHkgKFZCUjAsIFZCUjEsIFZCUjIpCiAgICAgICAgICAgICAgICAgICBjaGFubmVsTW9kZQogICAgIHJldHVybnM6ICAgICAgdmJyIGJpdHJhdGUKCiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpJTlQgRkRLYWFjRW5jX0dldFZCUkJpdHJhdGUoSU5UIGJpdHJhdGVNb2RlLCBDSEFOTkVMX01PREUgY2hhbm5lbE1vZGUpCnsKICBJTlQgYml0cmF0ZSA9IDA7CiAgSU5UIG1vbm9TdGVyZW9Nb2RlID0gMDsgLyogZGVmYXVsdCBtb25vICovCgogIGlmIChGREthYWNFbmNfR2V0TW9ub1N0ZXJlb01vZGUoY2hhbm5lbE1vZGUpPT1FTF9NT0RFX1NURVJFTykgewogICAgICBtb25vU3RlcmVvTW9kZSA9IDE7CiAgfQoKICBzd2l0Y2goKEFBQ0VOQ19CSVRSQVRFX01PREUpYml0cmF0ZU1vZGUpewogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzE6CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfMjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8zOgogIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzQ6CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfNToKICAgIGJpdHJhdGUgPSBjb25maWdUYWJWQlJbYml0cmF0ZU1vZGVdLmNoYW5CaXRyYXRlW21vbm9TdGVyZW9Nb2RlXTsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfSU5WQUxJRDoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0NCUjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1NGUjoKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0ZGOgogIGRlZmF1bHQ6CiAgICBiaXRyYXRlID0gMDsKICAgIGJyZWFrOwogIH0KCiAgLyogY29udmVydCBjaGFubmVsIGJpdHJhdGUgdG8gb3ZlcmFsbCBiaXRyYXRlKi8KICBiaXRyYXRlICo9IEZES2FhY0VuY19HZXRDaGFubmVsTW9kZUNvbmZpZ3VyYXRpb24oY2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmY7CgogIHJldHVybiBiaXRyYXRlOwp9CgovKioKICogXGJyaWVmICBDb252ZXJ0IGVuY29kZXIgYml0cmVzZXJ2b2lyIHZhbHVlIGZvciB0cmFuc3BvcnQgbGlicmFyeS4KICoKICogXHBhcmFtIGJpdHJhdGVNb2RlICAgICAgICAgICBCaXRyYXRlbW9kZSB1c2VkIGluIGN1cnJlbnQgZW5jb2RlciBpbnN0YW5jZS4gU2UgOjpBQUNFTkNfQklUUkFURV9NT0RFCiAqIFxwYXJhbSBiaXRyZXNUb3RhbCAgICAgICAgICAgRW5jb2RlciBiaXRyZXNlcnZvaXIgbGV2ZWwgaW4gYml0cy4KICoKICogXHJldHVybiAgQ29ycmVjdGVkIGJpdHJlc2Vydm9pciBsZXZlbCB1c2VkIGluIHRyYW5zcG9ydCBsaWJyYXJ5LgogKi8Kc3RhdGljIElOVCBGREthYWNFbmNfRW5jQml0cmVzVG9UcEJpdHJlcygKICAgICAgICBjb25zdCBBQUNFTkNfQklUUkFURV9NT0RFIGJpdHJhdGVNb2RlLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgYml0cmVzVG90YWwKICAgICAgICApCnsKICBJTlQgdHJhbnNwb3JCaXRyZXNlcnZvaXIgPSAwOwoKICBzd2l0Y2ggKGJpdHJhdGVNb2RlKSB7CiAgICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0NCUjoKICAgICAgdHJhbnNwb3JCaXRyZXNlcnZvaXIgPSBiaXRyZXNUb3RhbDsgLyogZW5jb2RlciBiaXRyZXNlcnZvaXIgbGV2ZWwgKi8KICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8xOgogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfMjoKICAgIGNhc2UgQUFDRU5DX0JSX01PREVfVkJSXzM6CiAgICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl80OgogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9WQlJfNToKICAgICAgdHJhbnNwb3JCaXRyZXNlcnZvaXIgPSBGREtfSU5UX01BWDsgLyogc2lnbmFsIHZhcmlhYmxlIGJpdHJhdGUgKi8KICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CUl9NT0RFX0ZGOgogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9TRlI6CiAgICAgIHRyYW5zcG9yQml0cmVzZXJ2b2lyID0gMDsgICAgICAgICAgIC8qIHN1cGVyIGZyYW1pbmcgYW5kIGZpeGVkIGZyYW1pbmcgKi8KICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogd2l0aG91dCBiaXRyZXNlcnZvaXIgc2lnbmFsaW5nICovCiAgICBkZWZhdWx0OgogICAgY2FzZSBBQUNFTkNfQlJfTU9ERV9JTlZBTElEOgogICAgICB0cmFuc3BvckJpdHJlc2Vydm9pciA9IDA7ICAgICAgICAgICAvKiBpbnZhbGlkIGNvbmZpZ3VyYXRpb24qLwogICAgICBGREtfQVNTRVJUKDApOwogIH0KCiAgcmV0dXJuIHRyYW5zcG9yQml0cmVzZXJ2b2lyOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX0FhY0luaXREZWZhdWx0Q29uZmlnCiAgICAgZGVzY3JpcHRpb246ICBnaXZlcyByZWFzb25hYmxlIGRlZmF1bHQgY29uZmlndXJhdGlvbgogICAgIHJldHVybnM6ICAgICAgLS0tCgogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBGREthYWNFbmNfQWFjSW5pdERlZmF1bHRDb25maWcoQUFDRU5DX0NPTkZJRyAqY29uZmlnKQp7CiAgICAvKiBtYWtlIHRoZXByZSBpbml0aWFsaXphdGlvbiBvZiB0aGUgc3RydWN0cyBmbGV4aWJsZSAqLwogICAgRkRLbWVtY2xlYXIoY29uZmlnLCBzaXplb2YoQUFDRU5DX0NPTkZJRykpOwoKICAgIC8qIGRlZmF1bHQgYW5jaWxsYXJ5ICovCiAgICBjb25maWctPmFuY19SYXRlID0gMDsgICAgICAgICAvKiBubyBhbmNpbGxhcnkgZGF0YSAqLwogICAgY29uZmlnLT5hbmNEYXRhQml0UmF0ZSA9IDA7ICAgLyogbm8gYWRkaXRpb25hbCBjb25zdW1lZCBiaXRyYXRlICovCgogICAgLyogZGVmYXVsdCBjb25maWd1cmF0aW9ucyAqLwogICAgY29uZmlnLT5iaXRSYXRlICAgICAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogYml0cmF0ZSBtdXN0IGJlIHNldCovCiAgICBjb25maWctPmF2ZXJhZ2VCaXRzICAgICA9IC0xOyAgICAgICAgICAgICAgICAgICAvKiBpbnN0ZWFkIG9mIGJpdHJhdGUvcyB3ZSBjYW4gY29uZmlndXJlIGJpdHMvc3VwZXJmcmFtZSAqLwogICAgY29uZmlnLT5iaXRyYXRlTW9kZSAgICAgPSAwOwogICAgY29uZmlnLT5iYW5kV2lkdGggICAgICAgPSAwOyAgICAgICAgICAgICAgICAgICAgLyogZ2V0IGJhbmR3aWR0aCBmcm9tIHRhYmxlICovCiAgICBjb25maWctPnVzZVRucyAgICAgICAgICA9IFROU19FTkFCTEVfTUFTSzsgICAgICAvKiB0bnMgZW5hYmxlZCBjb21wbGV0bHkgKi8KICAgIGNvbmZpZy0+dXNlUG5zICAgICAgICAgID0gMTsgICAgICAgICAgICAgICAgICAgIC8qIGRlcGVuZGluZyBvbiBjaGFubmVsQml0cmF0ZSB0aGlzIG1pZ2h0IGJlIHNldCB0byAwIGxhdGVyICovCiAgICBjb25maWctPnVzZUlTICAgICAgICAgICA9IDE7ICAgICAgICAgICAgICAgICAgICAvKiBJbnRlbnNpdHkgU3RlcmVvIENvbmZpZ3VyYXRpb24gKi8KICAgIGNvbmZpZy0+ZnJhbWVsZW5ndGggICAgID0gREVGQVVMVF9GUkFNRUxFTkdUSDsgIC8qIHVzZWQgZnJhbWUgc2l6ZSAqLwogICAgY29uZmlnLT5zeW50YXhGbGFncyAgICAgPSAwOyAgICAgICAgICAgICAgICAgICAgLyogZGVmYXVsdCBzeW50YXggd2l0aCBubyBzcGVjaWFsaXRpZXMgKi8KICAgIGNvbmZpZy0+ZXBDb25maWcgICAgICAgID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIG5vIEVSIHN5bnRheCAtPiBubyBhZGRpdGlvbmFsIGVycm9yIHByb3RlY3Rpb24gKi8KICAgIGNvbmZpZy0+blN1YkZyYW1lcyAgICAgID0gMTsgICAgICAgICAgICAgICAgICAgIC8qIGRlZmF1bHQsIG5vIHN1YiBmcmFtZXMgKi8KICAgIGNvbmZpZy0+Y2hhbm5lbE9yZGVyICAgID0gQ0hfT1JERVJfTVBFRzsgICAgICAgIC8qIFVzZSBNUEVHIGNoYW5uZWwgb3JkZXJpbmcuICovCiAgICBjb25maWctPmNoYW5uZWxNb2RlICAgICA9IE1PREVfVU5LTk9XTjsKICAgIGNvbmZpZy0+bWluQml0c1BlckZyYW1lID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIG1pbnVtIG51bWJlciBvZiBiaXRzIGluIGVhY2ggQVUgKi8KICAgIGNvbmZpZy0+bWF4Qml0c1BlckZyYW1lID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIG1pbnVtIG51bWJlciBvZiBiaXRzIGluIGVhY2ggQVUgKi8KICAgIGNvbmZpZy0+Yml0cmVzZXJ2b2lyICAgID0gLTE7ICAgICAgICAgICAgICAgICAgIC8qIGRlZmF1bHQsIHVuaW5pdGlhbGl6ZWQgdmFsdWUgKi8KCiAgICAvKiBpbml0IHRhYnMgaW4gZml4cG9pbnRfbWF0aCAqLwogICAgSW5pdExkSW50KCk7CiAgICBJbml0SW52U3FydFRhYigpOwp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19PcGVuCiAgICBkZXNjcmlwdGlvbjogIGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgbmV3IGVuY29kZXIgaW5zdGFuY2UKICAgIHJldHVybnM6ICAgICAgZXJyb3IgY29kZQoKICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfT3BlbihIQU5ETEVfQUFDX0VOQyAgKnBoQWFjRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgIG5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgblN1YkZyYW1lcykKewogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzOwogIEFBQ19FTkMgICAgICAgICAgICpoQWFjRW5jID0gTlVMTDsKICBVQ0hBUiAgICAgICAgICAgICAqZHluYW1pY1JBTSA9IE5VTEw7CgogIGlmIChwaEFhY0VuYz09TlVMTCkgewogICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9IQU5ETEU7CiAgfQoKICAvKiBhbGxvY2F0ZSBlbmNvZGVyIHN0cnVjdHVyZSAqLwogIGhBYWNFbmMgPSBHZXRSYW1fYWFjRW5jX0FhY0VuY29kZXIoKTsKICBpZiAoaEFhY0VuYyA9PSBOVUxMKSB7CiAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfTk9fTUVNT1JZOwogICAgZ290byBiYWlsOwogIH0KICBGREttZW1jbGVhcihoQWFjRW5jLCBzaXplb2YoQUFDX0VOQykpOwoKICBoQWFjRW5jLT5keW5hbWljX1JBTSA9IEdldEFBQ2R5bmFtaWNfUkFNKCk7CiAgZHluYW1pY1JBTSA9IChVQ0hBUiopaEFhY0VuYy0+ZHluYW1pY19SQU07CgogIC8qIGFsbG9jYXRlIHRoZSBQc3kgYXVkIFBzeSBPdXQgc3RydWN0dXJlICovCiAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1BzeU5ldygmaEFhY0VuYy0+cHN5S2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkNoYW5uZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxkeW5hbWljUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgIGdvdG8gYmFpbDsKCiAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1BzeU91dE5ldyhoQWFjRW5jLT5wc3lPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuU3ViRnJhbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxkeW5hbWljUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgIGdvdG8gYmFpbDsKCiAgLyogYWxsb2NhdGUgdGhlIFEmQyBPdXQgc3RydWN0dXJlICovCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNPdXROZXcoaEFhY0VuYy0+cWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuU3ViRnJhbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZHluYW1pY1JBTQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIC8qIGFsbG9jYXRlIHRoZSBRJkMga2VybmVsICovCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNOZXcoJmhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuRWxlbWVudHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsZHluYW1pY1JBTQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIGhBYWNFbmMtPm1heENoYW5uZWxzID0gbkNoYW5uZWxzOwogIGhBYWNFbmMtPm1heEVsZW1lbnRzID0gbkVsZW1lbnRzOwogIGhBYWNFbmMtPm1heEZyYW1lcyAgID0gblN1YkZyYW1lczsKCmJhaWw6CiAgKnBoQWFjRW5jID0gaEFhY0VuYzsKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCgpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfSW5pdGlhbGl6ZShIQU5ETEVfQUFDX0VOQyAgICAgIGhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFBQ0VOQ19DT05GSUcgICAgICAqY29uZmlnLCAgICAgLyogcHJlLWluaXRpYWxpemVkIGNvbmZpZyBzdHJ1Y3QgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1RSQU5TUE9SVEVOQyBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICAgICAgICAgICAgICAgaW5pdEZsYWdzKQp7CiAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CiAgSU5UIHBzeUJpdHJhdGUsIHRuc01hc2s7IC8vSU5UIHByb2ZpbGUgPSAxOwogIENIQU5ORUxfTUFQUElORyAgICpjbSA9IE5VTEw7CgogIElOVCBxbWJmYWMsIHFidzsKICBGSVhQX0RCTCBtYmZhYywgYndfcmF0aW87CiAgUUNfSU5JVCBxY0luaXQ7CiAgSU5UIGF2ZXJhZ2VCaXRzUGVyRnJhbWUgPSAwOwoKICBpZiAoY29uZmlnPT1OVUxMKQogICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9IQU5ETEU7CgogIC8qKioqKioqKioqKioqKioqKioqIHNhbml0eSBjaGVja3MgKioqKioqKioqKioqKioqKioqKi8KCiAgLyogY2hlY2sgY29uZmlnIHN0cnVjdHVyZSAqLwogIGlmIChjb25maWctPm5DaGFubmVscyAgPCAxIHx8IGNvbmZpZy0+bkNoYW5uZWxzID4gKDYpKSB7CiAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogIH0KCiAgLyogY2hlY2sgc2FtcGxlIHJhdGUgKi8KICBzd2l0Y2ggKGNvbmZpZy0+c2FtcGxlUmF0ZSkKICB7CiAgICBjYXNlIDgwMDA6CiAgICBjYXNlIDExMDI1OgogICAgY2FzZSAxMjAwMDoKICAgIGNhc2UgMTYwMDA6CiAgICBjYXNlIDIyMDUwOgogICAgY2FzZSAyNDAwMDoKICAgIGNhc2UgMzIwMDA6CiAgICBjYXNlIDQ0MTAwOgogICAgY2FzZSA0ODAwMDoKICAgIGNhc2UgNjQwMDA6CiAgICBjYXNlIDg4MjAwOgogICAgY2FzZSA5NjAwMDoKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9TQU1QTElOR1JBVEU7CiAgfQoKICAvKiBiaXRyYXRlIGhhcyB0byBiZSBzZXQgKi8KICBpZiAoY29uZmlnLT5iaXRSYXRlPT0tMSkgewogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9CSVRSQVRFOwogIH0KCiAgLyogY2hlY2sgYml0IHJhdGUgKi8KCiAgaWYgKEZES2FhY0VuY19MaW1pdEJpdHJhdGUoCiAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICBjb25maWctPnNhbXBsZVJhdGUsCiAgICAgICAgICBjb25maWctPmZyYW1lbGVuZ3RoLAogICAgICAgICAgY29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKGNvbmZpZy0+Y2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmYsCiAgICAgICAgICBjb25maWctPmJpdFJhdGUsCiAgICAgICAgICBjb25maWctPmF2ZXJhZ2VCaXRzLAogICAgICAgICAmYXZlcmFnZUJpdHNQZXJGcmFtZSwKICAgICAgICAgIGNvbmZpZy0+Yml0cmF0ZU1vZGUsCiAgICAgICAgICBjb25maWctPm5TdWJGcmFtZXMKICAgICAgICAgICkgIT0gY29uZmlnLT5iaXRSYXRlICkKICB7CiAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9CSVRSQVRFOwogIH0KCiAgaWYgKGNvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9WQ0IxMSkgewogICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9FUl9GT1JNQVQ7CiAgfQogIGlmIChjb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSB7CiAgICAgIHJldHVybiBBQUNfRU5DX1VOU1VQUE9SVEVEX0VSX0ZPUk1BVDsKICB9CgogIC8qIGNoZWNrIGZyYW1lIGxlbmd0aCAqLwogIHN3aXRjaCAoY29uZmlnLT5mcmFtZWxlbmd0aCkKICB7CiAgICBjYXNlIDEwMjQ6CiAgICAgIGlmICggY29uZmlnLT5hdWRpb09iamVjdFR5cGUgIT0gQU9UX0FBQ19MQwogICAgICAgICYmIGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlICE9IEFPVF9TQlIKICAgICAgICAmJiBjb25maWctPmF1ZGlvT2JqZWN0VHlwZSAhPSBBT1RfUFMKICAgICAgICAmJiBjb25maWctPmF1ZGlvT2JqZWN0VHlwZSAhPSBBT1RfRVJfQUFDX0xDCiAgICAgICAgJiYgY29uZmlnLT5hdWRpb09iamVjdFR5cGUgIT0gQU9UX0FBQ19TQ0FMICkKICAgICAgewogICAgICAgIHJldHVybiBBQUNfRU5DX0lOVkFMSURfRlJBTUVfTEVOR1RIOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSA1MTI6CiAgICBjYXNlIDQ4MDoKICAgICAgaWYgKCBjb25maWctPmF1ZGlvT2JqZWN0VHlwZSAhPSBBT1RfRVJfQUFDX0xECiAgICAgICAgJiYgY29uZmlnLT5hdWRpb09iamVjdFR5cGUgIT0gQU9UX0VSX0FBQ19FTEQgKQogICAgICB7CiAgICAgICAgcmV0dXJuIEFBQ19FTkNfSU5WQUxJRF9GUkFNRV9MRU5HVEg7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gQUFDX0VOQ19JTlZBTElEX0ZSQU1FX0xFTkdUSDsKICB9CgogIGlmIChjb25maWctPmFuY19SYXRlICE9IDApIHsKCiAgICAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfSW5pdENoZWNrQW5jaWxsYXJ5KGNvbmZpZy0+Yml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5mcmFtZWxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5hbmNfUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0VuYy0+YW5jaWxsYXJ5Qml0c1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnNhbXBsZVJhdGUpOwogICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgICAgZ290byBiYWlsOwoKCiAgICAgLyogdXBkYXRlIGVzdGltYXRlZCBjb25zdW1lZCBiaXRyYXRlICovCiAgICAgY29uZmlnLT5hbmNEYXRhQml0UmF0ZSArPSAoIChoQWFjRW5jLT5hbmNpbGxhcnlCaXRzUGVyRnJhbWUgKiBjb25maWctPnNhbXBsZVJhdGUpIC8gY29uZmlnLT5mcmFtZWxlbmd0aCApOwoKICB9CgogIC8qIG1heGltYWwgYWxsb3dlZCBEU0UgYnl0ZXMgaW4gZnJhbWUgKi8KICB7CiAgLyogZml4cG9pbnQgY2FsY3VsYXRpb24qLwogIElOVCBxX3JlcywgZW5jQml0cmF0ZSwgc2M7CiAgRklYUF9EQkwgdG1wID0gZkRpdk5vcm0oY29uZmlnLT5mcmFtZWxlbmd0aCwgY29uZmlnLT5zYW1wbGVSYXRlLCAmcV9yZXMpOwogIGVuY0JpdHJhdGUgPSAoY29uZmlnLT5iaXRSYXRlLyotY29uZmlnLT5hbmNEYXRhQml0UmF0ZSovKS0gKElOVCkoY29uZmlnLT5uQ2hhbm5lbHMqODAwMCk7CiAgc2MgPSBDb3VudExlYWRpbmdCaXRzKGVuY0JpdHJhdGUpOwogIGNvbmZpZy0+bWF4QW5jQnl0ZXNQZXJBVSA9IEZES21pbiggKDI1NiksIEZES21heCgwLChJTlQpKGZNdWx0RGl2Mih0bXAsIChGSVhQX0RCTCkoZW5jQml0cmF0ZTw8c2MpKT4+KC1xX3JlcytzYy0xKzMpKSkgKTsKICB9CgogIC8qIGJpbmQgY29uZmlnIHRvIGhBYWNFbmMtPmNvbmZpZyAqLwogIGhBYWNFbmMtPmNvbmZpZyA9IGNvbmZpZzsKCiAgLyogc2V0IGhBYWNFbmMtPmJpdHJhdGVNb2RlICovCiAgaEFhY0VuYy0+Yml0cmF0ZU1vZGUgPSAoQUFDRU5DX0JJVFJBVEVfTU9ERSljb25maWctPmJpdHJhdGVNb2RlOwoKICBoQWFjRW5jLT5lbmNvZGVyTW9kZSA9IGNvbmZpZy0+Y2hhbm5lbE1vZGU7CgogIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0luaXRDaGFubmVsTWFwcGluZyhoQWFjRW5jLT5lbmNvZGVyTW9kZSwgY29uZmlnLT5jaGFubmVsT3JkZXIsICZoQWFjRW5jLT5jaGFubmVsTWFwcGluZyk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIGNtID0gJmhBYWNFbmMtPmNoYW5uZWxNYXBwaW5nOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19EZXRlcm1pbmVCYW5kV2lkdGgoJmhBYWNFbmMtPmNvbmZpZy0+YmFuZFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPmJhbmRXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5iaXRSYXRlIC0gY29uZmlnLT5hbmNEYXRhQml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Yml0cmF0ZU1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5mcmFtZWxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmVuY29kZXJNb2RlKTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgIGdvdG8gYmFpbDsKCiAgaEFhY0VuYy0+YmFuZHdpZHRoOTBkQiA9IChJTlQpaEFhY0VuYy0+Y29uZmlnLT5iYW5kV2lkdGg7CgogIHRuc01hc2sgPSBjb25maWctPnVzZVRucyA/IFROU19FTkFCTEVfTUFTSyA6IDB4MDsKICBwc3lCaXRyYXRlID0gY29uZmlnLT5iaXRSYXRlIC0gY29uZmlnLT5hbmNEYXRhQml0UmF0ZTsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfcHN5SW5pdChoQWFjRW5jLT5wc3lLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5wc3lPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5tYXhGcmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5tYXhDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+YXVkaW9PYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20pOwogIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgZ290byBiYWlsOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19wc3lNYWluSW5pdChoQWFjRW5jLT5wc3lLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5hdWRpb09iamVjdFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+ZnJhbWVsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5Qml0cmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bnNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmJhbmR3aWR0aDkwZEIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT51c2VQbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT51c2VJUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRGbGFncyk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX1FDT3V0SW5pdChoQWFjRW5jLT5xY091dCwgaEFhY0VuYy0+bWF4RnJhbWVzLCBjbSk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICBnb3RvIGJhaWw7CgoKCiAgcWNJbml0LmNoYW5uZWxNYXBwaW5nICAgICAgPSAmaEFhY0VuYy0+Y2hhbm5lbE1hcHBpbmc7CiAgcWNJbml0LnNjZUNwZSAgICAgICAgICAgICAgPSAwOwoKICB7CiAgICAgIGludCBtYXhCaXRyZXM7CiAgICAgIHFjSW5pdC5hdmVyYWdlQml0cyAgICAgPSAoYXZlcmFnZUJpdHNQZXJGcmFtZSs3KSZ+NzsKICAgICAgbWF4Qml0cmVzICAgICAgICAgICAgICA9IChNSU5fQlVGU0laRV9QRVJfRUZGX0NIQU4qY20tPm5DaGFubmVsc0VmZikgLSBxY0luaXQuYXZlcmFnZUJpdHM7CiAgICAgIHFjSW5pdC5iaXRSZXMgICAgICAgICAgPSAoY29uZmlnLT5iaXRyZXNlcnZvaXIhPS0xKSA/IEZES21pbihjb25maWctPmJpdHJlc2Vydm9pciwgbWF4Qml0cmVzKSA6IG1heEJpdHJlczsKCiAgICAgIHFjSW5pdC5tYXhCaXRzICAgICAgICAgPSBmaXhNaW4oTUlOX0JVRlNJWkVfUEVSX0VGRl9DSEFOKmNtLT5uQ2hhbm5lbHNFZmYsICgoYXZlcmFnZUJpdHNQZXJGcmFtZSs3KSZ+NykrcWNJbml0LmJpdFJlcyk7CiAgICAgIHFjSW5pdC5tYXhCaXRzICAgICAgICAgPSAoY29uZmlnLT5tYXhCaXRzUGVyRnJhbWUhPS0xKSA/IGZpeE1pbihxY0luaXQubWF4Qml0cywgY29uZmlnLT5tYXhCaXRzUGVyRnJhbWUpIDogcWNJbml0Lm1heEJpdHM7CgogICAgICBxY0luaXQubWluQml0cyAgICAgICAgID0gZml4TWF4KDAsICgoYXZlcmFnZUJpdHNQZXJGcmFtZS0xKSZ+NyktcWNJbml0LmJpdFJlcy10cmFuc3BvcnRFbmNfR2V0U3RhdGljQml0cyhoVHBFbmMsICgoYXZlcmFnZUJpdHNQZXJGcmFtZSs3KSZ+NykrcWNJbml0LmJpdFJlcykpOwogICAgICBxY0luaXQubWluQml0cyAgICAgICAgID0gKGNvbmZpZy0+bWluQml0c1BlckZyYW1lIT0tMSkgPyBmaXhNYXgocWNJbml0Lm1pbkJpdHMsIGNvbmZpZy0+bWluQml0c1BlckZyYW1lKSA6IHFjSW5pdC5taW5CaXRzOwogIH0KCiAgcWNJbml0Lm5TdWJGcmFtZXMgICAgICAgICAgPSBjb25maWctPm5TdWJGcmFtZXM7CiAgcWNJbml0LnBhZGRpbmcucGFkZGluZ1Jlc3QgPSBjb25maWctPnNhbXBsZVJhdGU7CgogIC8qIENhbGMgbWVhblBlICovCiAgYndfcmF0aW8gPSBmRGl2Tm9ybSgoRklYUF9EQkwpaEFhY0VuYy0+YmFuZHdpZHRoOTBkQiwgKEZJWFBfREJMKShjb25maWctPnNhbXBsZVJhdGU+PjEpLCAmcWJ3KTsKICBxYncgPSBERlJBQ1RfQklUUy0xLXFidzsKICAvKiBxY0luaXQubWVhblBlID0gMTAuMGYgKiBGUkFNRV9MRU5fTE9ORyAqIGhBYWNFbmMtPmJhbmR3aWR0aDkwZEIvKGNvbmZpZy0+c2FtcGxlUmF0ZS8yLjBmKTsgKi8KICBxY0luaXQubWVhblBlID0gZk11bHQoYndfcmF0aW8sIChGSVhQX0RCTCkoKDEwKmNvbmZpZy0+ZnJhbWVsZW5ndGgpPDwxNikpID4+IChxYnctMTUpOwoKICAvKiBDYWxjIG1heEJpdEZhYyAqLwogIG1iZmFjID0gZkRpdk5vcm0oKE1JTl9CVUZTSVpFX1BFUl9FRkZfQ0hBTi03NDQpKmNtLT5uQ2hhbm5lbHNFZmYsIHFjSW5pdC5hdmVyYWdlQml0cy9xY0luaXQublN1YkZyYW1lcywgJnFtYmZhYyk7CiAgcW1iZmFjID0gREZSQUNUX0JJVFMtMS1xbWJmYWM7CiAgcWNJbml0Lm1heEJpdEZhYyA9IChxbWJmYWMgPiAyNCkgPyAobWJmYWMgPj4gKHFtYmZhYyAtIDI0KSk6KG1iZmFjIDw8ICgyNCAtIHFtYmZhYykpOwoKICBzd2l0Y2goY29uZmlnLT5iaXRyYXRlTW9kZSl7CiAgY2FzZSBBQUNFTkNfQlJfTU9ERV9DQlI6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9DQlI7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8xOgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfVkJSXzE7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8yOgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfVkJSXzI7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl8zOgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfVkJSXzM7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl80OgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfVkJSXzQ7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1ZCUl81OgogICAgcWNJbml0LmJpdHJhdGVNb2RlID0gUUNEQVRBX0JSX01PREVfVkJSXzU7CiAgICBicmVhazsKICBjYXNlIEFBQ0VOQ19CUl9NT0RFX1NGUjoKICAgIHFjSW5pdC5iaXRyYXRlTW9kZSA9IFFDREFUQV9CUl9NT0RFX1NGUjsKICAgIGJyZWFrOwogIGNhc2UgQUFDRU5DX0JSX01PREVfRkY6CiAgICBxY0luaXQuYml0cmF0ZU1vZGUgPSBRQ0RBVEFfQlJfTU9ERV9GRjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfVU5TVVBQT1JURURfQklUUkFURV9NT0RFOwogICAgZ290byBiYWlsOwogIH0KCiAgcWNJbml0LmludlF1YW50ID0gKGNvbmZpZy0+dXNlUmVxdWFudCk/MjowOwoKICAvKiBtYXhJdGVyYXRpb25zIHNob3VsZCBiZSBzZXQgdG8gdGhlIG1heGltdW0gbnVtYmVyIG9mIHJlcXVhbnRpemF0aW9uIGl0ZXJhdGlvbnMgdGhhdCBhcmUKICAgKiBhbGxvd2VkIGJlZm9yZSB0aGUgY3Jhc2ggcmVjb3ZlcnkgZnVuY3Rpb25hbGl0eSBpcyBhY3RpdmF0ZWQuIFRoaXMgc2V0dGluZyBzaG91bGQgYmUgYWRqdXN0ZWQKICAgKiB0byB0aGUgcHJvY2Vzc2luZyBwb3dlciBhdmFpbGFibGUsIGkuZS4gdG8gdGhlIHByb2Nlc3NpbmcgcG93ZXIgaGVhZHJvb20gaW4gb25lIGZyYW1lIHRoYXQgaXMKICAgKiBzdGlsbCBsZWZ0IGFmdGVyIG5vcm1hbCBlbmNvZGluZyB3aXRob3V0IHJlcXVhbnRpemF0aW9uLiBQbGVhc2Ugbm90ZSB0aGF0IGlmIGFjdGl2YXRlZCB0aGlzCiAgICogZnVuY3Rpb25hbGl0eSBpcyB1c2VkIG1vc3QgbGlrZWx5IG9ubHkgaW4gY2FzZXMgd2hlcmUgdGhlIGVuY29kZXIgaXMgb3BlcmF0aW5nIGJleW9uZAogICAqIHJlY29tbWVuZGVkIHNldHRpbmdzLCBpLmUuIHRoZSBhdWRpbyBxdWFsaXR5IGlzIHN1Ym9wdGltYWwgYW55d2F5LiBBY3RpdmF0aW5nIHRoZSBjcmFzaAogICAqIHJlY292ZXJ5IGRvZXMgbm90IGZ1cnRoZXIgcmVkdWNlIGF1ZGlvIHF1YWxpdHkgc2lnbmlmaWNhbnRseSBpbiB0aGVzZSBjYXNlcy4gKi8KICBpZiAoIChjb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0xEKSB8fCAoY29uZmlnLT5hdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0FBQ19FTEQpICkgewogICAgcWNJbml0Lm1heEl0ZXJhdGlvbnMgPSAyOwogIH0KICBlbHNlCiAgewogICAgcWNJbml0Lm1heEl0ZXJhdGlvbnMgPSA1OwogIH0KCiAgcWNJbml0LmJpdHJhdGUgPSBjb25maWctPmJpdFJhdGUgLSBjb25maWctPmFuY0RhdGFCaXRSYXRlOwoKICBxY0luaXQuc3RhdGljQml0cyA9IHRyYW5zcG9ydEVuY19HZXRTdGF0aWNCaXRzKGhUcEVuYywgcWNJbml0LmF2ZXJhZ2VCaXRzL3FjSW5pdC5uU3ViRnJhbWVzKTsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNJbml0KGhBYWNFbmMtPnFjS2VybmVsLCAmcWNJbml0KTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgIGdvdG8gYmFpbDsKCiAgLyogTWFwIHZpcnR1YWwgYW90J3MgdG8gaW50ZXJuIGFvdCB1c2VkIGluIGJpdHN0cmVhbSB3cml0ZXIuICovCiAgc3dpdGNoIChoQWFjRW5jLT5jb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgewogICAgY2FzZSBBT1RfTVAyX0FBQ19MQzoKICAgIGNhc2UgQU9UX0RBQlBMVVNfQUFDX0xDOgogICAgICBoQWFjRW5jLT5hb3QgPSBBT1RfQUFDX0xDOwogICAgICBicmVhazsKICAgIGNhc2UgQU9UX01QMl9TQlI6CiAgICBjYXNlIEFPVF9EQUJQTFVTX1NCUjoKICAgICAgaEFhY0VuYy0+YW90ID0gQU9UX1NCUjsKICAgICAgYnJlYWs7CiAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICBjYXNlIEFPVF9EQUJQTFVTX1BTOgogICAgICBoQWFjRW5jLT5hb3QgPSBBT1RfUFM7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgaEFhY0VuYy0+YW90ID0gaEFhY0VuYy0+Y29uZmlnLT5hdWRpb09iamVjdFR5cGU7CiAgfQoKICAvKiBjb21tb24gdGhpbmdzICovCgogIHJldHVybiBBQUNfRU5DX09LOwoKYmFpbDoKCiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19FbmNvZGVGcmFtZQogICAgZGVzY3JpcHRpb246ICBlbmNvZGVzIG9uZSBmcmFtZQogICAgcmV0dXJuczogICAgICBlcnJvciBjb2RlCgogIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCkFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19FbmNvZGVGcmFtZSggSEFORExFX0FBQ19FTkMgICAgICAgaEFhY0VuYywgICAgICAgICAgLyogZW5jb2RlciBoYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfVFJBTlNQT1JURU5DICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UX1BDTSogUkVTVFJJQ1QgICAgaW5wdXRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UKiAgICAgICAgICAgICAgICAgbk91dEJ5dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFBQ0VOQ19FWFRfUEFZTE9BRCAgIGV4dFBheWxvYWRbTUFYX1RPVEFMX0VYVF9QQVlMT0FEU10KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgICBBQUNfRU5DT0RFUl9FUlJPUiBFcnJvclN0YXR1czsKICAgIGludCAgICBlbCwgbiwgYz0wOwogICAgVUNIQVIgIGV4dFBheWxvYWRVc2VkW01BWF9UT1RBTF9FWFRfUEFZTE9BRFNdOwoKICAgIENIQU5ORUxfTUFQUElORyAqY20gICAgICA9ICZoQWFjRW5jLT5jaGFubmVsTWFwcGluZzsKCgoKICAgIFBTWV9PVVQgKnBzeU91dCA9IGhBYWNFbmMtPnBzeU91dFtjXTsKICAgIFFDX09VVCAgKnFjT3V0ICA9IGhBYWNFbmMtPnFjT3V0W2NdOwoKICAgIEZES21lbWNsZWFyKGV4dFBheWxvYWRVc2VkLCBNQVhfVE9UQUxfRVhUX1BBWUxPQURTICogc2l6ZW9mKFVDSEFSKSk7CgogICAgcWNPdXQtPmVsZW1lbnRFeHRCaXRzID0gMDsgLyogc3VtIHVwIGFsbCBleHRlbmRlZCBiaXQgb2YgZWFjaCBlbGVtZW50ICovCiAgICBxY091dC0+c3RhdGljQml0cyAgICAgPSAwOyAvKiBzdW0gdXAgc2lkZSBpbmZvIGJpdHMgb2YgZWFjaCBlbGVtZW50ICovCiAgICBxY091dC0+dG90YWxOb1JlZFBlICAgPSAwOyAvKiBzdW0gdXAgUEUgKi8KCiAgICAvKiBhZHZhbmNlIHBzeWNob2Fjb3VzdGljcyAqLwogICAgZm9yIChlbD0wOyBlbDxjbS0+bkVsZW1lbnRzOyBlbCsrKSB7CiAgICAgICAgRUxFTUVOVF9JTkZPIGVsSW5mbyA9IGNtLT5lbEluZm9bZWxdOwoKICAgICAgICBpZiAoIChlbEluZm8uZWxUeXBlID09IElEX1NDRSkKICAgICAgICAgIHx8IChlbEluZm8uZWxUeXBlID09IElEX0NQRSkKICAgICAgICAgIHx8IChlbEluZm8uZWxUeXBlID09IElEX0xGRSkgKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGNoOwoKICAgICAgICAgICAgLyogdXBkYXRlIHBvaW50ZXIhKi8KICAgICAgICAgICAgZm9yKGNoPTA7Y2g8ZWxJbmZvLm5DaGFubmVsc0luRWw7Y2grKykgewogICAgICAgICAgICAgICAgUFNZX09VVF9DSEFOTkVMICpwc3lPdXRDaGFuID0gcHN5T3V0LT5wc3lPdXRFbGVtZW50W2VsXS0+cHN5T3V0Q2hhbm5lbFtjaF07CiAgICAgICAgICAgICAgICBRQ19PVVRfQ0hBTk5FTCAgKnFjT3V0Q2hhbiA9IHFjT3V0LT5xY0VsZW1lbnRbZWxdLT5xY091dENoYW5uZWxbY2hdOwoKICAgICAgICAgICAgICAgIHBzeU91dENoYW4tPm1kY3RTcGVjdHJ1bSAgICAgICA9IHFjT3V0Q2hhbi0+bWRjdFNwZWN0cnVtOwogICAgICAgICAgICAgICAgcHN5T3V0Q2hhbi0+c2ZiU3ByZWFkRW5lcmd5ICA9IHFjT3V0Q2hhbi0+c2ZiU3ByZWFkRW5lcmd5OwogICAgICAgICAgICAgICAgcHN5T3V0Q2hhbi0+c2ZiRW5lcmd5ICAgICAgICAgID0gcWNPdXRDaGFuLT5zZmJFbmVyZ3k7CiAgICAgICAgICAgICAgICBwc3lPdXRDaGFuLT5zZmJFbmVyZ3lMZERhdGEgICAgPSBxY091dENoYW4tPnNmYkVuZXJneUxkRGF0YTsKICAgICAgICAgICAgICAgIHBzeU91dENoYW4tPnNmYk1pblNuckxkRGF0YSAgICA9IHFjT3V0Q2hhbi0+c2ZiTWluU25yTGREYXRhOwogICAgICAgICAgICAgICAgcHN5T3V0Q2hhbi0+c2ZiVGhyZXNob2xkTGREYXRhID0gcWNPdXRDaGFuLT5zZmJUaHJlc2hvbGRMZERhdGE7CgogICAgICAgICAgICB9CgogICAgICAgICAgICBGREthYWNFbmNfcHN5TWFpbihlbEluZm8ubkNoYW5uZWxzSW5FbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cHN5S2VybmVsLT5wc3lFbGVtZW50W2VsXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cHN5S2VybmVsLT5wc3lEeW5hbWljLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5wc3lLZXJuZWwtPnBzeUNvbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dC0+cHN5T3V0RWxlbWVudFtlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbS0+ZWxJbmZvW2VsXS5DaGFubmVsSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLT5uQ2hhbm5lbHMKCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIC8qIEZvcm1GYWN0b3IsIFBlIGFuZCBzdGF0aWNCaXREZW1hbmQgY2FsY3VsYXRpb24gKi8KICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfUUNNYWluUHJlcGFyZSgmZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5xY0tlcm5lbC0+aEFkalRoci0+YWRqVGhyU3RhdGVFbGVtW2VsXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0LT5wc3lPdXRFbGVtZW50W2VsXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5zeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5lcENvbmZpZyk7CgogICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgICAgICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgogICAgICAgICAgICBxY091dC0+cWNFbGVtZW50W2VsXS0+ZXh0Qml0c1VzZWQgPSAwOwogICAgICAgICAgICBxY091dC0+cWNFbGVtZW50W2VsXS0+bkV4dGVuc2lvbnMgPSAwOwogICAgICAgICAgICAvKiByZXNldCBleHRlbnNpb24gcGF5bG9hZCAqLwogICAgICAgICAgICBGREttZW1jbGVhcigmcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dGVuc2lvbiwgKDEpKnNpemVvZihRQ19PVVRfRVhURU5TSU9OKSk7CgogICAgICAgICAgICBmb3IgKCBuID0gMDsgbiA8IE1BWF9UT1RBTF9FWFRfUEFZTE9BRFM7IG4rKyApIHsKICAgICAgICAgICAgICAgIGlmICggIWV4dFBheWxvYWRVc2VkW25dCiAgICAgICAgICAgICAgICAgICYmIChleHRQYXlsb2FkW25dLmFzc29jaWF0ZWRDaEVsZW1lbnQgPT0gZWwpCiAgICAgICAgICAgICAgICAgICYmIChleHRQYXlsb2FkW25dLmRhdGFTaXplID4gMCkKICAgICAgICAgICAgICAgICAgJiYgKGV4dFBheWxvYWRbbl0ucERhdGEgIT0gTlVMTCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBpZHggPSBxY091dC0+cWNFbGVtZW50W2VsXS0+bkV4dGVuc2lvbnMrKzsKCiAgICAgICAgICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dGVuc2lvbltpZHhdLnR5cGUgICAgICAgICA9IGV4dFBheWxvYWRbbl0uZGF0YVR5cGU7ICAgLyogUGVyZm9ybSBhIHNhbml0eSBjaGVjayBvbiB0aGUgdHlwZT8gKi8KICAgICAgICAgICAgICAgICAgICBxY091dC0+cWNFbGVtZW50W2VsXS0+ZXh0ZW5zaW9uW2lkeF0ublBheWxvYWRCaXRzID0gZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZTsKICAgICAgICAgICAgICAgICAgICBxY091dC0+cWNFbGVtZW50W2VsXS0+ZXh0ZW5zaW9uW2lkeF0ucFBheWxvYWQgPSBleHRQYXlsb2FkW25dLnBEYXRhOwogICAgICAgICAgICAgICAgICAgIC8qIE5vdyBhc2sgdGhlIGJpdHN0cmVhbSBlbmNvZGVyIGhvdyBtYW55IGJpdHMgd2UgbmVlZCB0byBlbmNvZGUgdGhlIGRhdGEgd2l0aCB0aGUgY3VycmVudCBiaXRzdHJlYW0gc3ludGF4OiAqLwogICAgICAgICAgICAgICAgICAgIHFjT3V0LT5xY0VsZW1lbnRbZWxdLT5leHRCaXRzVXNlZCArPQogICAgICAgICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY193cml0ZUV4dGVuc2lvbkRhdGEoIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXQtPnFjRWxlbWVudFtlbF0tPmV4dGVuc2lvbltpZHhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5zeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5hb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5lcENvbmZpZyApOwogICAgICAgICAgICAgICAgICAgIGV4dFBheWxvYWRVc2VkW25dID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogc3VtIHVwIGV4dGVuc2lvbiBhbmQgc3RhdGljIGJpdHMgZm9yIGFsbCBjaGFubmVsIGVsZW1lbnRzICovCiAgICAgICAgICAgIHFjT3V0LT5lbGVtZW50RXh0Qml0cyArPSBxY091dC0+cWNFbGVtZW50W2VsXS0+ZXh0Qml0c1VzZWQ7CiAgICAgICAgICAgIHFjT3V0LT5zdGF0aWNCaXRzICAgKz0gcWNPdXQtPnFjRWxlbWVudFtlbF0tPnN0YXRpY0JpdHNVc2VkOwoKICAgICAgICAgICAgLyogc3VtIHVwIHBlICovCiAgICAgICAgICAgIHFjT3V0LT50b3RhbE5vUmVkUGUgKz0gcWNPdXQtPnFjRWxlbWVudFtlbF0tPnBlRGF0YS5wZTsKICAgICAgICB9CiAgICB9CgogICAgcWNPdXQtPm5FeHRlbnNpb25zICAgPSAwOwogICAgcWNPdXQtPmdsb2JhbEV4dEJpdHMgPSAwOwoKICAgIC8qIHJlc2V0IGV4dGVuc2lvbiBwYXlsb2FkICovCiAgICBGREttZW1jbGVhcigmcWNPdXQtPmV4dGVuc2lvbiwgKDIrMikqc2l6ZW9mKFFDX09VVF9FWFRFTlNJT04pKTsKCiAgICAvKiBBZGQgZXh0ZW5zaW9uIHBheWxvYWQgbm90IGFzc2lnbmVkIHRvIGFuIGNoYW5uZWwgZWxlbWVudAogICAgICAoQW5jaWxsYXJ5IGRhdGEgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIHR5cGUgdXAgdG8gbm93KSAqLwogICAgZm9yICggbiA9IDA7IG4gPCBNQVhfVE9UQUxfRVhUX1BBWUxPQURTOyBuKysgKSB7CiAgICAgICAgaWYgKCAhZXh0UGF5bG9hZFVzZWRbbl0KICAgICAgICAgICYmIChleHRQYXlsb2FkW25dLmFzc29jaWF0ZWRDaEVsZW1lbnQgPT0gLTEpCiAgICAgICAgICAmJiAoZXh0UGF5bG9hZFtuXS5wRGF0YSAhPSBOVUxMKSApCiAgICAgICAgewogICAgICAgICAgICBVSU5UIHBheWxvYWRCaXRzID0gMDsKCiAgICAgICAgICAgIGlmIChleHRQYXlsb2FkW25dLmRhdGFUeXBlID09IEVYVF9EQVRBX0VMRU1FTlQpIHsKICAgICAgICAgICAgICAgIGlmIChoQWFjRW5jLT5hbmNpbGxhcnlCaXRzUGVyRnJhbWUpIHsKICAgICAgICAgICAgICAgICAgICAvKiBncmFudGVkIGZyYW1lIGRzZSBiaXRyYXRlICovCiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZEJpdHMgPSBoQWFjRW5jLT5hbmNpbGxhcnlCaXRzUGVyRnJhbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiB3cml0ZSBhbmMgZGF0YSBpZiBiaXRyYXRlIGNvbnN0cmFpbnQgZnVsZmlsbGVkICovCiAgICAgICAgICAgICAgICAgICAgaWYgKChleHRQYXlsb2FkW25dLmRhdGFTaXplPj4zKSA8PSBoQWFjRW5jLT5jb25maWctPm1heEFuY0J5dGVzUGVyQVUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZEJpdHMgPSBleHRQYXlsb2FkW25dLmRhdGFTaXplOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHBheWxvYWRCaXRzID0gZml4TWluKCBleHRQYXlsb2FkW25dLmRhdGFTaXplLCBwYXlsb2FkQml0cyApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGF5bG9hZEJpdHMgPSBleHRQYXlsb2FkW25dLmRhdGFTaXplOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGF5bG9hZEJpdHMgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgaWR4ID0gcWNPdXQtPm5FeHRlbnNpb25zKys7CgogICAgICAgICAgICAgICAgcWNPdXQtPmV4dGVuc2lvbltpZHhdLnR5cGUgICAgICAgICA9IGV4dFBheWxvYWRbbl0uZGF0YVR5cGU7ICAgLyogUGVyZm9ybSBhIHNhbml0eSBjaGVjayBvbiB0aGUgdHlwZT8gKi8KICAgICAgICAgICAgICAgIHFjT3V0LT5leHRlbnNpb25baWR4XS5uUGF5bG9hZEJpdHMgPSBwYXlsb2FkQml0czsKICAgICAgICAgICAgICAgIHFjT3V0LT5leHRlbnNpb25baWR4XS5wUGF5bG9hZCA9IGV4dFBheWxvYWRbbl0ucERhdGE7CiAgICAgICAgICAgICAgICAvKiBOb3cgYXNrIHRoZSBiaXRzdHJlYW0gZW5jb2RlciBob3cgbWFueSBiaXRzIHdlIG5lZWQgdG8gZW5jb2RlIHRoZSBkYXRhIHdpdGggdGhlIGN1cnJlbnQgYml0c3RyZWFtIHN5bnRheDogKi8KICAgICAgICAgICAgICAgIHFjT3V0LT5nbG9iYWxFeHRCaXRzICs9IEZES2FhY0VuY193cml0ZUV4dGVuc2lvbkRhdGEoIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZxY091dC0+ZXh0ZW5zaW9uW2lkeF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5zeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcgKTsKICAgICAgICAgICAgICAgIGlmIChleHRQYXlsb2FkW25dLmRhdGFUeXBlID09IEVYVF9EQVRBX0VMRU1FTlQpIHsKICAgICAgICAgICAgICAgICAgICAvKiBzdWJzdHJhY3QgdGhlIHByb2Nlc3NlZCBiaXRzICovCiAgICAgICAgICAgICAgICAgICAgZXh0UGF5bG9hZFtuXS5kYXRhU2l6ZSAtPSBwYXlsb2FkQml0czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGV4dFBheWxvYWRVc2VkW25dID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIShoQWFjRW5jLT5jb25maWctPnN5bnRheEZsYWdzICYgKEFDX1NDQUxBQkxFfEFDX0VSKSkpIHsKICAgICAgcWNPdXQtPmdsb2JhbEV4dEJpdHMgKz0gRUxfSURfQklUUzsgIC8qIGFkZCBiaXRzIGZvciBJRF9FTkQgKi8KICAgIH0KCiAgICAvKiBidWlsZCBiaXRzdHJlYW0gYWxsIG5TdWJGcmFtZXMgKi8KICAgIHsKICAgICAgICBJTlQgdG90YWxCaXRzICAgID0gMDsgICAvKiBUb3RhbCBBVSBiaXRzICovOwogICAgICAgIElOVCBhdmdUb3RhbEJpdHMgPSAwOwoKICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgLyogR2V0IGF2ZXJhZ2UgdG90YWwgYml0cyAqLwogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICB7CiAgICAgICAgICAgIC8qIGZyYW1lIHdpc2UgYml0cmF0ZSBhZGFwdGlvbiAqLwogICAgICAgICAgICBGREthYWNFbmNfQWRqdXN0Qml0cmF0ZShoQWFjRW5jLT5xY0tlcm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF2Z1RvdGFsQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5iaXRSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPnNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZnJhbWVsZW5ndGgpOwoKICAgICAgICAgICAgLyogYWRqdXN0IHN1cGVyIGZyYW1lIGJpdHJhdGUgKi8KICAgICAgICAgICAgYXZnVG90YWxCaXRzICo9IGhBYWNFbmMtPmNvbmZpZy0+blN1YkZyYW1lczsKICAgICAgICB9CgogICAgICAgIC8qIE1ha2UgZmlyc3QgZXN0aW1hdGUgb2YgdHJhbnNwb3J0IGhlYWRlciBvdmVyaGVhZC4KICAgICAgICAgICBUYWtlIG1heGltdW0gcG9zc2libGUgZnJhbWUgc2l6ZSBpbnRvIGFjY291bnQgdG8gcHJldmVudCBiaXRyZXNlcnZvaXIgdW5kZXJydW4uICovCiAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwtPmdsb2JIZHJCaXRzID0gdHJhbnNwb3J0RW5jX0dldFN0YXRpY0JpdHMoaFRwRW5jLCBhdmdUb3RhbEJpdHMgKyBoQWFjRW5jLT5xY0tlcm5lbC0+Yml0UmVzVG90KTsKCgogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19RQ01haW4oaEFhY0VuYy0+cWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnBzeU91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1RvdGFsQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsaEFhY0VuYy0+YW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPnN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPmVwQ29uZmlnKTsKCiAgICAgICAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgogICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY191cGRhdGVGaWxsQml0cyhjbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5xY0tlcm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5xY0tlcm5lbC0+ZWxlbWVudEJpdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNPdXQpOwogICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgICAgICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgICAgIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0ZpbmFsaXplQml0Q29uc3VtcHRpb24oY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+cWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXQtPnFjRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+YW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+c3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuYy0+Y29uZmlnLT5lcENvbmZpZyk7CiAgICAgICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgICAgICAgICAgICAgcmV0dXJuIEVycm9yU3RhdHVzOwogICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgICAgIHRvdGFsQml0cyArPSBxY091dC0+dG90YWxCaXRzOwoKCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIEZES2FhY0VuY191cGRhdGVCaXRyZXMoY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5xY0tlcm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjT3V0KTsKCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKICAgICAgICAvKiBmb3IgKCBhbGwgc3ViIGZyYW1lcyApIC4uLiAqLwogICAgICAgICAgICAgIC8qIHdyaXRlIGJpdHN0cmVhbSBoZWFkZXIgKi8KICAgICAgICAgICAgICB0cmFuc3BvcnRFbmNfV3JpdGVBY2Nlc3NVbml0KAogICAgICAgICAgICAgICAgICAgIGhUcEVuYywKICAgICAgICAgICAgICAgICAgICB0b3RhbEJpdHMsCiAgICAgICAgICAgICAgICAgICAgRkRLYWFjRW5jX0VuY0JpdHJlc1RvVHBCaXRyZXMoaEFhY0VuYy0+Yml0cmF0ZU1vZGUsIGhBYWNFbmMtPnFjS2VybmVsLT5iaXRSZXNUb3QpLAogICAgICAgICAgICAgICAgICAgIGNtLT5uQ2hhbm5lbHNFZmYpOwoKICAgICAgICAgICAgICAvKiB3cml0ZSBiaXRzdHJlYW0gKi8KICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Xcml0ZUJpdHN0cmVhbSgKICAgICAgICAgICAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgY20sCiAgICAgICAgICAgICAgICAgICAgcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgcHN5T3V0LAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPnFjS2VybmVsLAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmFvdCwKICAgICAgICAgICAgICAgICAgICBoQWFjRW5jLT5jb25maWctPnN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgIGhBYWNFbmMtPmNvbmZpZy0+ZXBDb25maWcpOwoKICAgICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgICAgICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKCiAgICAgICAgICAgICAgLyogdHJhbnNwb3J0RW5jX0VuZEFjY2Vzc1VuaXQoKSBpcyBiZWluZyBjYWxsZWQgaW5zaWRlIEZES2FhY0VuY19Xcml0ZUJpdHN0cmVhbSgpICovCiAgICAgICAgICAgICAgdHJhbnNwb3J0RW5jX0dldEZyYW1lKGhUcEVuYywgbk91dEJ5dGVzKTsKCiAgICB9IC8qIC1lbmQtIGlmIChjdXJGcmFtZT09aEFhY0VuYy0+cWNLZXJuZWwtPm5TdWJGcmFtZXMpICovCgoKICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfQ2xvc2UKICAgIGRlc2NyaXB0aW9uOiBkZWxldGUgZW5jb2RlciBpbnN0YW5jZQogICAgcmV0dXJuczoKCiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnZvaWQgRkRLYWFjRW5jX0Nsb3NlKCBIQU5ETEVfQUFDX0VOQyogIHBoQWFjRW5jKSAgIC8qIGVuY29kZXIgaGFuZGxlICovCnsKICAgIGlmICgqcGhBYWNFbmMgPT0gTlVMTCkgewogICAgICByZXR1cm47CiAgICB9CiAgICBBQUNfRU5DICpoQWFjRW5jID0gKEFBQ19FTkMqKSpwaEFhY0VuYzsKCiAgIGlmIChoQWFjRW5jLT5keW5hbWljX1JBTSAhPSBOVUxMKQogICAgICAgRnJlZUFBQ2R5bmFtaWNfUkFNKCZoQWFjRW5jLT5keW5hbWljX1JBTSk7CgogICAgRkRLYWFjRW5jX1BzeUNsb3NlKCZoQWFjRW5jLT5wc3lLZXJuZWwsaEFhY0VuYy0+cHN5T3V0KTsKCiAgICBGREthYWNFbmNfUUNDbG9zZSgmaEFhY0VuYy0+cWNLZXJuZWwsIGhBYWNFbmMtPnFjT3V0KTsKCiAgICBGcmVlUmFtX2FhY0VuY19BYWNFbmNvZGVyKHBoQWFjRW5jKTsKfQoKCi8qIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbiB0aGlzIHNvdXJjZSBmaWxlIG9ubHkgZm9yIGNvbnZlbmllbmNlIGFuZCAqLwovKiBuZWVkIG5vdCBiZSB2aXNpYmxlIG91dHNpZGUgb2YgYSBwb3NzaWJsZSBlbmNvZGVyIGxpYnJhcnkuICovCgovKiBiYXNpYyBkZWZpbmVzIGZvciBhbmNpbGxhcnkgZGF0YSAqLwojZGVmaW5lIE1BWF9BTkNSQVRFIDE5MjAwICAgICAgICAgICAgLyogYW5jaWxsYXJ5IHJhdGUgPj0gMTkyMDAgaXNuJ3QgdmFsaWQgKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZnVuY3Rpb25uYW1lOiAgRkRLYWFjRW5jX0luaXRDaGVja0FuY2lsbGFyeQogICAgZGVzY3JpcHRpb246ICAgaW5pdGlhbGl6ZSBhbmQgY2hlY2sgYW5jaWxsYXJ5IGRhdGEgc3RydWN0CiAgICByZXR1cm46ICAgICAgICBpZiBzdWNjZXNzIG9yIE5VTEwgaWYgZXJyb3IKCiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIEFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19Jbml0Q2hlY2tBbmNpbGxhcnkoSU5UIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBmcmFtZWxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGFuY2lsbGFyeVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqYW5jaWxsYXJ5Qml0c1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSkKewogIElOVCBkaWZmVG9CeXRlQWxpZ247CgogIC8qIGRvbid0IHVzZSBuZWdhdGl2ZSBhbmNpbGxhcnkgcmF0ZXMgKi8KICBpZiAoIGFuY2lsbGFyeVJhdGUgPCAtMSApCiAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9BTkNfQklUUkFURTsKCiAgLyogY2hlY2sgaWYgYW5jaWxsYXJ5IHJhdGUgaXMgb2sgKi8KICBpZiAoIChhbmNpbGxhcnlSYXRlICE9ICgtMSkpICYmIChhbmNpbGxhcnlSYXRlICE9IDApICkgewogICAgLyogYW5jUmF0ZSA8PSAxNSUgb2YgYml0cmF0ZSAmJiBhbmNSYXRlIDwgMTkyMDAgKi8KICAgIGlmICggKCBhbmNpbGxhcnlSYXRlID49IE1BWF9BTkNSQVRFICkgfHwKICAgICAgICAgKCAoYW5jaWxsYXJ5UmF0ZSAqIDIwKSA+IChiaXRSYXRlICogMykgKSApIHsKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5TVVBQT1JURURfQU5DX0JJVFJBVEU7CiAgICB9CiAgfQogIGVsc2UgaWYgKGFuY2lsbGFyeVJhdGUgPT0gLTEpIHsKICAgIC8qIGlmIG5vIHNwZWNpYWwgYW5jUmF0ZSBpcyByZXF1ZXN0ZWQgYnV0IGEgYW5jaWxsYXJ5IGZpbGUgaXMKICAgICAgIHN0YXRlZCwgdGhlbiBnZW5lcmF0ZSBhIGFuY2lsbGFyeSByYXRlIG1hdGNoaW5nIHRvIHRoZSBiaXRyYXRlICovCiAgICBpZiAoYml0UmF0ZSA+PSAoTUFYX0FOQ1JBVEUgKiAxMCkpIHsKICAgICAgLyogYW5jaWxsYXJ5IHJhdGUgaXMgMTkxOTkgKi8KICAgICAgYW5jaWxsYXJ5UmF0ZSA9IChNQVhfQU5DUkFURSAtIDEpOwogICAgfQogICAgZWxzZSB7IC8qIDEwJSBvZiBiaXRyYXRlICovCiAgICAgIGFuY2lsbGFyeVJhdGUgPSBiaXRSYXRlIC8gMTA7CiAgICB9CiAgfQoKICAvKiBtYWtlIGFuY2lsbGFyeUJpdHNQZXJGcmFtZSBieXRlIGFsaWduICovCiAgKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSA9IChhbmNpbGxhcnlSYXRlICogZnJhbWVsZW5ndGggKSAvIHNhbXBsZVJhdGU7CiAgZGlmZlRvQnl0ZUFsaWduID0gKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSAlIDg7CiAgKmFuY2lsbGFyeUJpdHNQZXJGcmFtZSA9ICphbmNpbGxhcnlCaXRzUGVyRnJhbWUgLSBkaWZmVG9CeXRlQWxpZ247CgogIHJldHVybiBBQUNfRU5DX09LOwp9Cg==