Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgU0JSIGRlY29kZXIgZnJvbnRlbmQgIAogIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgZnJvbnRlbmQgdG8gdGhlIFNCUiBkZWNvZGVyLiBUaGUgZnVuY3Rpb24gb3BlblNCUigpIGlzIGNhbGxlZCBmb3IKICBpbml0aWFsaXphdGlvbi4gVGhlIGZ1bmN0aW9uIHNickRlY29kZXJfQXBwbHkoKSBpcyBjYWxsZWQgZm9yIGVhY2ggZnJhbWUuIHNicl9BcHBseSgpIHdpbGwgY2FsbCB0aGUKICByZXF1aXJlZCBmdW5jdGlvbnMgdG8gZGVjb2RlIHRoZSByYXcgU0JSIGRhdGEgKHByb3ZpZGVkIGJ5IGVudl9leHRyLmNwcCksIHRvIGRlY29kZSB0aGUgZW52ZWxvcGUgZGF0YSBhbmQgbm9pc2UgZmxvb3IgbGV2ZWxzIFtkZWNvZGVTYnJEYXRhKCldLAogIGFuZCB0byBmaW5hbGx5IGFwcGx5IFNCUiB0byB0aGUgY3VycmVudCBmcmFtZSBbc2JyX2RlYygpXS4KCiAgXHNhIHNickRlY29kZXJfQXBwbHkoKSwgXHJlZiBkb2N1bWVudGF0aW9uT3ZlcnZpZXcKKi8KCi8qIQogIFxwYWdlIGRvY3VtZW50YXRpb25PdmVydmlldyBPdmVydmlldyBvZiBpbXBvcnRhbnQgaW5mb3JtYXRpb24gcmVzb3VyY2VzIGFuZCBzb3VyY2UgY29kZSBkb2N1bWVudGF0aW9uCgogIFRoZSBwcmltYXJ5IHNvdXJjZSBjb2RlIGRvY3VtZW50YXRpb24gaXMgYmFzZWQgb24gZ2VuZXJhdGVkIGFuZCBjcm9zcy1yZWZlcmVuY2VkIEhUTUwgZmlsZXMgdXNpbmcKICA8YSBIUkVGPSJodHRwOi8vd3d3LmRveHlnZW4ub3JnIj5kb3h5Z2VuPC9hPi4gQXMgcGFydCBvZiB0aGlzIGRvY3VtZW50YXRpb24KICB5b3UgY2FuIGZpbmQgbW9yZSBleHRlbnNpdmUgZGVzY3JpcHRpb25zIGFib3V0IGtleSBjb25jZXB0cyBhbmQgYWxnb3JpdGhtcyBhdCB0aGUgZm9sbG93aW5nIGxvY2F0aW9uczoKCiAgPGgyPlByb2dyYW1taW5nPC9oMj4KCiAgXGxpIEJ1ZmZlciBtYW5hZ2VtZW50OiBzYnJEZWNvZGVyX0FwcGx5KCkgYW5kIHNicl9kZWMoKQogIFxsaSBJbnRlcm5hbCBzY2FsZSBmYWN0b3JzIHRvIG1heGltaXplIFNOUiBvbiBmaXhlZCBwb2ludCBwcm9jZXNzb3JzOiAjUU1GX1NDQUxFX0ZBQ1RPUgogIFxsaSBTcGVjaWFsIG1hbnRpc3NhLWV4cG9uZW50IGZvcm1hdDogQ3JlYXRlZCBpbiByZXF1YW50aXplRW52ZWxvcGVEYXRhKCkgYW5kIHVzZWQgaW4gY2FsY3VsYXRlU2JyRW52ZWxvcGUoKQoKICA8aDI+QWxnb3JpdGhtaWMgZGV0YWlsczwvaDI+CiAgXGxpIEFib3V0IHRoZSBTQlIgZGF0YSBmb3JtYXQ6IFxyZWYgU0JSX0hFQURFUl9FTEVNRU5UIGFuZCBccmVmIFNCUl9TVEFOREFSRF9FTEVNRU5UCiAgXGxpIERldGFpbHMgYWJvdXQgdGhlIGJpdHN0cmVhbSBkZWNvZGVyOiBlbnZfZXh0ci5jcHAKICBcbGkgRGV0YWlscyBhYm91dCB0aGUgUU1GIGZpbHRlcmJhbmsgYW5kIHRoZSBwcm92aWRlZCBwb2x5cGhhc2UgaW1wbGVtZW50YXRpb246IHFtZl9kZWMuY3BwCiAgXGxpIERldGFpbHMgYWJvdXQgdGhlIHRyYW5zcG9zZXI6IGxwcF90cmFuLmNwcAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSBlbnZlbG9wZSBhZGp1c3RlcjogZW52X2NhbGMuY3BwCgoqLwoKI2luY2x1ZGUgInNicmRlY29kZXIuaCIKCiNpbmNsdWRlICJGREtfYml0c3RyZWFtLmgiCgojaW5jbHVkZSAic2JyZGVjX2ZyZXFfc2NhLmgiCiNpbmNsdWRlICJlbnZfZXh0ci5oIgojaW5jbHVkZSAic2JyX2RlYy5oIgojaW5jbHVkZSAiZW52X2RlYy5oIgojaW5jbHVkZSAic2JyX2NyYy5oIgojaW5jbHVkZSAic2JyX3JhbS5oIgojaW5jbHVkZSAic2JyX3JvbS5oIgojaW5jbHVkZSAibHBwX3RyYW4uaCIKI2luY2x1ZGUgInRyYW5zY2VuZGVudC5oIgoKCiNpbmNsdWRlICJzYnJkZWNfZHJjLmgiCgojaW5jbHVkZSAicHNiaXRkZWMuaCIKCgovKiBEZWNvZGVyIGxpYnJhcnkgaW5mbyAqLwojZGVmaW5lIFNCUkRFQ09ERVJfTElCX1ZMMCAyCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfVkwxIDEKI2RlZmluZSBTQlJERUNPREVSX0xJQl9WTDIgMgojZGVmaW5lIFNCUkRFQ09ERVJfTElCX1RJVExFICJTQlIgRGVjb2RlciIKI2RlZmluZSBTQlJERUNPREVSX0xJQl9CVUlMRF9EQVRFIF9fREFURV9fCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfQlVJTERfVElNRSBfX1RJTUVfXwoKCgoKc3RhdGljIFVDSEFSIGdldEhlYWRlclNsb3QoIFVDSEFSIGN1cnJlbnRTbG90LCBVQ0hBUiBoZHJTbG90VXNhZ2VbKDEpKzFdICkKewogIFVJTlQgIG9jY3VwaWVkID0gMDsKICBpbnQgICBzOwogIFVDSEFSIHNsb3QgPSBoZHJTbG90VXNhZ2VbY3VycmVudFNsb3RdOwoKICBGREtfQVNTRVJUKCgxKSsxIDwgMzIpOwoKICBmb3IgKHMgPSAwOyBzIDwgKDEpKzE7IHMrKykgewogICAgaWYgKCAoaGRyU2xvdFVzYWdlW3NdID09IHNsb3QpCiAgICAgICYmIChzICE9IHNsb3QpICkgewogICAgICBvY2N1cGllZCA9IDE7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKG9jY3VwaWVkKSB7CiAgICBvY2N1cGllZCA9IDA7CgogICAgZm9yIChzID0gMDsgcyA8ICgxKSsxOyBzKyspIHsKICAgICAgb2NjdXBpZWQgfD0gMSA8PCBoZHJTbG90VXNhZ2Vbc107CiAgICB9CiAgICBmb3IgKHMgPSAwOyBzIDwgKDEpKzE7IHMrKykgewogICAgICBpZiAoICEob2NjdXBpZWQgJiAweDEpICkgewogICAgICAgIHNsb3QgPSBzOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIG9jY3VwaWVkID4+PSAxOwogICAgfQogIH0KCiAgcmV0dXJuIHNsb3Q7Cn0KCnN0YXRpYyB2b2lkIGNvcHlTYnJIZWFkZXIoIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaERzdCwgY29uc3QgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU3JjICkKewogIC8qIGNvcHkgdGhlIHdob2xlIGhlYWRlciBtZW1vcnkgKGluY2x1ZGluZyBwb2ludGVycykgKi8KICBGREttZW1jcHkoIGhEc3QsIGhTcmMsIHNpemVvZihTQlJfSEVBREVSX0RBVEEpICk7CgogIC8qIHVwZGF0ZSBwb2ludGVycyAqLwogIGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlWzBdICA9IGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlTG87CiAgaERzdC0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVbMV0gPSBoRHN0LT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZUhpOwp9CgoKLyohCiAgXGJyaWVmIFJlc2V0IFNCUiBkZWNvZGVyLgoKICBSZXNldCBzaG91bGQgb25seSBiZSBjYWxsZWQgaWYgU0JSIGhhcyBiZWVuIHN1Y2Vzc2Z1bGx5IGRldGVjdGVkIGJ5CiAgYW4gYXBwcm9wcmlhdGUgY2hlY2tGb3JQYXlsb2FkKCkgZnVuY3Rpb24uCgogIFxyZXR1cm4gRXJyb3IgY29kZS4KKi8Kc3RhdGljClNCUl9FUlJPUiBzYnJEZWNvZGVyX1Jlc2V0RWxlbWVudCAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgc2VsZiwKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZU91dCwKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgTVA0X0VMRU1FTlRfSUQgZWxlbWVudElELAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIGVsZW1lbnRJbmRleCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBvdmVybGFwCiAgICAgICAgKQp7CiAgU0JSX0VSUk9SIHNickVycm9yID0gU0JSREVDX09LOwogIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNickhlYWRlcjsKICBVSU5UIHFtZkZsYWdzID0gMDsKCiAgaW50IGksIHN5bkRvd25zYW1wbGVGYWM7CgogIC8qIENoZWNrIGluL291dCBzYW1wbGVyYXRlcyAqLwogIGlmICggc2FtcGxlUmF0ZUluIDwgNjQwMAogICAgfHwgc2FtcGxlUmF0ZUluID4gMjQwMDAKICAgICApCiAgewogICAgc2JyRXJyb3IgPSBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgZ290byBiYWlsOwogIH0KCiAgaWYgKCBzYW1wbGVSYXRlT3V0ID4gNDgwMDAgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qIFNldCBRTUYgbW9kZSBmbGFncyAqLwogIGlmIChzZWxmLT5mbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIpCiAgICBxbWZGbGFncyB8PSBRTUZfRkxBR19MUDsKCiAgaWYgKHNlbGYtPmNvcmVDb2RlYyA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgaWYgKHNlbGYtPmZsYWdzICYgU0JSREVDX0xEX01QU19RTUYpIHsKICAgICAgcW1mRmxhZ3MgfD0gIFFNRl9GTEFHX01QU0xERkI7CiAgICB9IGVsc2UgewogICAgICBxbWZGbGFncyB8PSAgUU1GX0ZMQUdfQ0xERkI7CiAgICB9CiAgfQoKICAvKiBTZXQgZG93bnNhbXBsaW5nIGZhY3RvciBmb3Igc3ludGhlc2lzIGZpbHRlciBiYW5rICovCiAgaWYgKHNhbXBsZVJhdGVPdXQgPT0gMCkKICB7CiAgICAvKiBubyBzaW5nbGUgcmF0ZSBtb2RlICovCiAgICAgIHNhbXBsZVJhdGVPdXQgPSBzYW1wbGVSYXRlSW48PDE7IC8qIEluIGNhc2Ugb2YgaW1wbGljaXQgc2lnbmFsbGluZywgYXNzdW1lIGR1YWwgcmF0ZSBTQlIgKi8KICB9CgogIGlmICggc2FtcGxlUmF0ZUluID09IHNhbXBsZVJhdGVPdXQgKSB7CiAgICBzeW5Eb3duc2FtcGxlRmFjID0gMjsKICB9IGVsc2UgewogICAgc3luRG93bnNhbXBsZUZhYyA9IDE7CiAgfQoKICBzZWxmLT5zeW5Eb3duc2FtcGxlRmFjID0gc3luRG93bnNhbXBsZUZhYzsKICBzZWxmLT5zYW1wbGVSYXRlT3V0ID0gc2FtcGxlUmF0ZU91dDsKCiAgewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8ICgxKSsxOyBpKyspCiAgICB7CiAgICAgIGhTYnJIZWFkZXIgPSAmKHNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2ldKTsKCiAgICAgIC8qIGluaXQgYSBkZWZhdWx0IGhlYWRlciBzdWNoIHRoYXQgd2UgY2FuIGF0IGxlYXN0IGRvIHVwc2FtcGxpbmcgbGF0ZXIgKi8KICAgICAgc2JyRXJyb3IgPSBpbml0SGVhZGVyRGF0YSgKICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgICAgICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgICAgICk7CiAgICB9CiAgfQoKICBpZiAoc2JyRXJyb3IgIT0gU0JSREVDX09LKSB7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKiBJbml0IFNCUiBjaGFubmVscyBnb2luZyB0byBiZSBhc3NpZ25lZCB0byBhIFNCUiBlbGVtZW50ICovCiAgewogICAgaW50IGNoOwoKICAgIGZvciAoY2g9MDsgY2g8c2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+bkNoYW5uZWxzOyBjaCsrKQogICAgewogICAgICAvKiBhbmQgY3JlYXRlIHNickRlYyAqLwogICAgICBzYnJFcnJvciA9IGNyZWF0ZVNickRlYyAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dHJhbnNwb3NlclNldHRpbmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN5bkRvd25zYW1wbGVGYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcW1mRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxhcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaCApOwoKICAgICAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgfQogIH0KCiAgLy9GREttZW1jbGVhcihzYnJfT3ZlcmxhcEJ1ZmZlciwgc2l6ZW9mKHNicl9PdmVybGFwQnVmZmVyKSk7CgogIGlmIChzZWxmLT5udW1TYnJFbGVtZW50cyA9PSAxKSB7CiAgICBzd2l0Y2ggKCBzZWxmLT5jb3JlQ29kZWMgKSB7CiAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICBjYXNlIEFPVF9TQlI6CiAgICBjYXNlIEFPVF9QUzoKICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgY2FzZSBBT1RfRFJNX0FBQzoKICAgIGNhc2UgQU9UX0RSTV9TVVJST1VORDoKICAgICAgaWYgKENyZWF0ZVBzRGVjICggJnNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLCBzYW1wbGVzUGVyRnJhbWUgKSkgewogICAgICAgIHNickVycm9yID0gU0JSREVDX0NSRUFURV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICAgIH0KICB9CgogIC8qIEluaXQgZnJhbWUgZGVsYXkgc2xvdCBoYW5kbGluZyAqLwogIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUZyYW1lU2xvdCA9IDA7CiAgZm9yIChpID0gMDsgaSA8ICgoMSkrMSk7IGkrKykgewogICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlSGVhZGVyU2xvdFtpXSA9IGk7CiAgfQoKYmFpbDoKCiAgcmV0dXJuIHNickVycm9yOwp9CgoKU0JSX0VSUk9SIHNickRlY29kZXJfT3BlbiAoIEhBTkRMRV9TQlJERUNPREVSICAqIHBTZWxmICkKewogIEhBTkRMRV9TQlJERUNPREVSICAgIHNlbGYgPSBOVUxMOwogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKCiAgLyogR2V0IG1lbW9yeSBmb3IgdGhpcyBpbnN0YW5jZSAqLwogIHNlbGYgPSBHZXRSYW1fU2JyRGVjb2RlcigpOwogIGlmIChzZWxmID09IE5VTEwpIHsKICAgIHNickVycm9yID0gU0JSREVDX01FTV9BTExPQ19GQUlMRUQ7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBzZWxmLT53b3JrQnVmZmVyMSA9IEdldFJhbV9TYnJEZWNXb3JrQnVmZmVyMSgpOwogIHNlbGYtPndvcmtCdWZmZXIyID0gR2V0UmFtX1NickRlY1dvcmtCdWZmZXIyKCk7CgogIGlmICggIHNlbGYtPndvcmtCdWZmZXIxID09IE5VTEwKICAgICB8fCBzZWxmLT53b3JrQnVmZmVyMiA9PSBOVUxMICkKICB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgZ290byBiYWlsOwogIH0KCiAgLyoKICBBbHJlYWR5IHplcm8gYmVjYXVzZSBvZiBjYWxsb2MKICBzZWxmLT5udW1TYnJFbGVtZW50cyA9IDA7CiAgc2VsZi0+bnVtU2JyQ2hhbm5lbHMgPSAwOwogIHNlbGYtPmNvZGVjRnJhbWVTaXplID0gMDsKICAqLwoKICBzZWxmLT5udW1EZWxheUZyYW1lcyA9ICgxKTsgIC8qIHNldCB0byB0aGUgbWF4IHZhbHVlIGJ5IGRlZmF1bHQgKi8KCiAgKnBTZWxmID0gc2VsZjsKCmJhaWw6CiAgcmV0dXJuIHNickVycm9yOwp9CgovKioKICogXGJyaWVmIGRldGVybWluZSBpZiB0aGUgZ2l2ZW4gY29yZSBjb2RlYyBBT1QgY2FuIGJlIHByb2Nlc3NlZCBvciBub3QuCiAqIFxwYXJhbSBjb3JlQ29kZWMgY29yZSBjb2RlYyBhdWRpbyBvYmplY3QgdHlwZS4KICogXHJldHVybiAxIGlmIFNCUiBjYW4gYmUgcHJvY2Vzc2VkLCAwIGlmIFNCUiBjYW5ub3QgYmUgcHJvY2Vzc2VkL2FwcGxpZWQuCiAqLwpzdGF0aWMKaW50IHNickRlY29kZXJfaXNDb3JlQ29kZWNWYWxpZChBVURJT19PQkpFQ1RfVFlQRSBjb3JlQ29kZWMpCnsKICBzd2l0Y2ggKGNvcmVDb2RlYykgewogICAgY2FzZSBBT1RfQUFDX0xDOgogICAgY2FzZSBBT1RfU0JSOgogICAgY2FzZSBBT1RfUFM6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgIHJldHVybiAxOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIDA7CiAgfQp9CgpzdGF0aWMKdm9pZCBzYnJEZWNvZGVyX0Rlc3Ryb3lFbGVtZW50ICgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiAgICAgICBzZWxmLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIGVsZW1lbnRJbmRleAogICAgICAgICkKewogIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICE9IE5VTEwpIHsKICAgIGludCBjaDsKCiAgICBmb3IgKGNoPTA7IGNoPFNCUkRFQ19NQVhfQ0hfUEVSX0VMRU1FTlQ7IGNoKyspIHsKICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSAhPSBOVUxMKSB7CiAgICAgICAgZGVsZXRlU2JyRGVjKCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gKTsKICAgICAgICBGcmVlUmFtX1NickRlY0NoYW5uZWwoICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gKTsKICAgICAgICBzZWxmLT5udW1TYnJDaGFubmVscyAtPSAxOwogICAgICB9CiAgICB9CiAgICBGcmVlUmFtX1NickRlY0VsZW1lbnQoICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICk7CiAgICBzZWxmLT5udW1TYnJFbGVtZW50cyAtPSAxOwogIH0KfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX0luaXRFbGVtZW50ICgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiAgICAgICBzZWxmLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBjb3JlQ29kZWMsCiAgICAgICAgY29uc3QgTVA0X0VMRU1FTlRfSUQgICAgZWxlbWVudElELAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIGVsZW1lbnRJbmRleAogICAgICAgICkKewogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICBpbnQgY2hDbnQ9MDsKICBpbnQgblNickVsZW1lbnRzU3RhcnQgPSBzZWxmLT5udW1TYnJFbGVtZW50czsKCiAgLyogQ2hlY2sgY29yZSBjb2RlYyBBT1QgKi8KICBpZiAoISBzYnJEZWNvZGVyX2lzQ29yZUNvZGVjVmFsaWQoY29yZUNvZGVjKSB8fCBlbGVtZW50SW5kZXggPj0gKDQpKSB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBpZiAoIGVsZW1lbnRJRCAhPSBJRF9TQ0UgJiYgZWxlbWVudElEICE9IElEX0NQRSAmJiBlbGVtZW50SUQgIT0gSURfTEZFICkKICB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBpZiAoICBzZWxmLT5zYW1wbGVSYXRlSW4gPT0gc2FtcGxlUmF0ZUluCiAgICAgJiYgc2VsZi0+Y29kZWNGcmFtZVNpemUgPT0gc2FtcGxlc1BlckZyYW1lCiAgICAgJiYgc2VsZi0+Y29yZUNvZGVjID09IGNvcmVDb2RlYwogICAgICYmIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gIT0gTlVMTAogICAgICYmIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmVsZW1lbnRJRCA9PSBlbGVtZW50SUQKICAgICApCiAgewogICAgIC8qIE5vdGhpbmcgdG8gZG8gKi8KICAgICByZXR1cm4gU0JSREVDX09LOwogIH0KCiAgc2VsZi0+c2FtcGxlUmF0ZUluID0gc2FtcGxlUmF0ZUluOwogIHNlbGYtPmNvZGVjRnJhbWVTaXplID0gc2FtcGxlc1BlckZyYW1lOwogIHNlbGYtPmNvcmVDb2RlYyA9IGNvcmVDb2RlYzsKCiAgc2VsZi0+ZmxhZ3MgPSAwOwogIHNlbGYtPmZsYWdzIHw9IChjb3JlQ29kZWMgPT0gQU9UX0VSX0FBQ19FTEQpID8gU0JSREVDX0VMRF9HUklEIDogMDsKCiAgLyogSW5pdCBTQlIgZWxlbWVudHMgKi8KICB7CiAgICBpbnQgZWxDaGFubmVscywgY2g7CgogICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gPT0gTlVMTCkgewogICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID0gR2V0UmFtX1NickRlY0VsZW1lbnQoZWxlbWVudEluZGV4KTsKICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gPT0gTlVMTCkgewogICAgICAgIHNickVycm9yID0gU0JSREVDX01FTV9BTExPQ19GQUlMRUQ7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICAgIHNlbGYtPm51bVNickVsZW1lbnRzICsrOwogICAgfSBlbHNlIHsKICAgICAgc2VsZi0+bnVtU2JyQ2hhbm5lbHMgLT0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+bkNoYW5uZWxzOwogICAgfQoKICAgIC8qIFNhdmUgZWxlbWVudCBJRCBmb3Igc2FuaXR5IGNoZWNrcyBhbmQgdG8gaGF2ZSBhIGZhbGxiYWNrIGZvciBjb25jZWFsbWVudC4gKi8KICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmVsZW1lbnRJRCA9IGVsZW1lbnRJRDsKCiAgICAvKiBEZXRlcm1pbmUgYW1vdW50IG9mIGNoYW5uZWxzIGZvciB0aGlzIGVsZW1lbnQgKi8KICAgIHN3aXRjaCAoZWxlbWVudElEKSB7CiAgICAgIGNhc2UgSURfTk9ORToKICAgICAgY2FzZSBJRF9DUEU6IGVsQ2hhbm5lbHM9MjsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgIGNhc2UgSURfU0NFOiBlbENoYW5uZWxzPTE7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6IGVsQ2hhbm5lbHM9MDsKICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBIYW5kbGUgY2FzZSBvZiBQYXJhbWV0cmljIFN0ZXJlbyAqLwogICAgaWYgKCBlbGVtZW50SW5kZXggPT0gMCAmJiBlbGVtZW50SUQgPT0gSURfU0NFICkgewogICAgICBzd2l0Y2ggKGNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgICBjYXNlIEFPVF9TQlI6CiAgICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICAgICAgY2FzZSBBT1RfRFJNX0FBQzoKICAgICAgICBjYXNlIEFPVF9EUk1fU1VSUk9VTkQ6CiAgICAgICAgICBlbENoYW5uZWxzID0gMjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfQoKICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPm5DaGFubmVscyA9IGVsQ2hhbm5lbHM7CgogICAgZm9yIChjaD0wOyBjaDxlbENoYW5uZWxzOyBjaCsrKQogICAgewogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdID09IE5VTEwpIHsKICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gPSBHZXRSYW1fU2JyRGVjQ2hhbm5lbChjaENudCk7CiAgICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgfQogICAgICBzZWxmLT5udW1TYnJDaGFubmVscyArKzsKCiAgICAgIHNickRlY29kZXJfZHJjSW5pdENoYW5uZWwoICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0tPlNickRlYy5zYnJEcmNDaGFubmVsICk7CgogICAgICAvKiBBZGQgcmVmZXJlbmNlIHBvaW50ZXIgdG8gd29ya2J1ZmZlcnMuICovCiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXS0+U2JyRGVjLldvcmtCdWZmZXIxID0gc2VsZi0+d29ya0J1ZmZlcjE7CiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXS0+U2JyRGVjLldvcmtCdWZmZXIyID0gc2VsZi0+d29ya0J1ZmZlcjI7CiAgICAgIGNoQ250Kys7CiAgICB9CiAgICBpZiAoZWxDaGFubmVscyA9PSAxICYmIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSAhPSBOVUxMKSB7CiAgICAgIGRlbGV0ZVNickRlYyggc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICk7CiAgICAgIEZyZWVSYW1fU2JyRGVjQ2hhbm5lbCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgfQogIH0KCiAgLyogY2xlYXIgZXJyb3IgZmxhZ3MgZm9yIGFsbCBkZWxheSBzbG90cyAqLwogIEZES21lbWNsZWFyKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnLCAoKDEpKzEpKnNpemVvZihVQ0hBUikpOwoKICAvKiBJbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgKi8KICBzYnJFcnJvciA9IHNickRlY29kZXJfUmVzZXRFbGVtZW50KCAKICAgICAgICAgIHNlbGYsCiAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgZWxlbWVudElELAogICAgICAgICAgZWxlbWVudEluZGV4LAogICAgICAgICAgKGNvcmVDb2RlYyA9PSBBT1RfRVJfQUFDX0VMRCkgPyAwIDogKDYpCiAgICAgICAgICApOwoKCgpiYWlsOgogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgIGlmIChuU2JyRWxlbWVudHNTdGFydCA8IHNlbGYtPm51bVNickVsZW1lbnRzKSB7CiAgICAgIC8qIEZyZWUgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIHRoaXMgZWxlbWVudCAqLwogICAgICBzYnJEZWNvZGVyX0Rlc3Ryb3lFbGVtZW50KCBzZWxmLCBlbGVtZW50SW5kZXggKTsKICAgIH0gZWxzZSBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMKSB7CiAgICAgIC8qIFNldCBlcnJvciBmbGFnIHRvIHRyaWdnZXIgY29uY2VhbG1lbnQgKi8KICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZnJhbWVFcnJvckZsYWdbc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlRnJhbWVTbG90XSA9IDE7OwogICAgfQogIH0KCiAgcmV0dXJuIHNickVycm9yOwp9CgovKioKICogXGJyaWVmIEFwcGx5IGRlY29kZWQgU0JSIGhlYWRlciBmb3Igb25lIGVsZW1lbnQuCiAqIFxwYXJhbSBzZWxmIFNCUiBkZWNvZGVyIGluc3RhbmNlIGhhbmRsZQogKiBccGFyYW0gaFNickhlYWRlciBTQlIgaGVhZGVyIGhhbmRsZSB0byBiZSBwcm9jZXNzZWQuCiAqIFxwYXJhbSBoU2JyQ2hhbm5lbCBwb2ludGVyIGFycmF5IHRvIHRoZSBTQlIgZWxlbWVudCBjaGFubmVscyBjb3JyZXNwb25kaW5nIHRvIHRoZSBTQlIgaGVhZGVyLgogKiBccGFyYW0gaGVhZGVyU3RhdHVzIGhlYWRlciBzdGF0dXMgdmFsdWUgcmV0dXJuZWQgZnJvbSBTQlIgaGVhZGVyIHBhcnNlci4KICogXHBhcmFtIG51bUVsZW1lbnRDaGFubmVscyBhbW91bnQgb2YgY2hhbm5lbHMgZm9yIHRoZSBTQlIgZWxlbWVudCB3aG9zIGhlYWRlciBpcyB0byBiZSBwcm9jZXNzZWQuCiAqLwpzdGF0aWMKU0JSX0VSUk9SIHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSIHNlbGYsCiAgICAgICAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyLAogICAgICAgIFNCUl9IRUFERVJfU1RBVFVTIGhlYWRlclN0YXR1cywKICAgICAgICBIQU5ETEVfU0JSX0NIQU5ORUwgaFNickNoYW5uZWxbXSwKICAgICAgICBjb25zdCBpbnQgbnVtRWxlbWVudENoYW5uZWxzCiAgICAgICAgKQp7CiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwogCiAgLyoKICAgIGNoYW5nZSBvZiBjb250cm9sIGRhdGEsIHJlc2V0IGRlY29kZXIKICAqLwogIGVycm9yU3RhdHVzID0gcmVzZXRGcmVxQmFuZFRhYmxlcyhoU2JySGVhZGVyLCBzZWxmLT5mbGFncyk7CgogIGlmIChlcnJvclN0YXR1cyA9PSBTQlJERUNfT0spIHsKICAgIGlmIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gVVBTQU1QTElORyAmJiBoZWFkZXJTdGF0dXMgIT0gSEVBREVSX1JFU0VUKQogICAgewogICAgICAvKiBBcyB0aGUgZGVmYXVsdCBoZWFkZXIgd291bGQgbGltaXQgdGhlIGZyZXF1ZW5jeSByYW5nZSwKICAgICAgICAgbG93U3ViYmFuZCBhbmQgaGlnaFN1YmJhbmQgbXVzdCBiZSBwYXRjaGVkLiAqLwogICAgICBoU2JySGVhZGVyLT5mcmVxQmFuZERhdGEubG93U3ViYmFuZCA9IGhTYnJIZWFkZXItPm51bWJlck9mQW5hbHlzaXNCYW5kczsKICAgICAgaFNickhlYWRlci0+ZnJlcUJhbmREYXRhLmhpZ2hTdWJiYW5kID0gaFNickhlYWRlci0+bnVtYmVyT2ZBbmFseXNpc0JhbmRzOwogICAgfQoKICAgIC8qIFRyaWdnZXIgYSByZXNldCBiZWZvcmUgcHJvY2Vzc2luZyB0aGlzIHNsb3QgKi8KICAgIGhTYnJIZWFkZXItPnN0YXR1cyB8PSBTQlJERUNfSERSX1NUQVRfUkVTRVQ7CiAgfQoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCklOVCBzYnJEZWNvZGVyX0hlYWRlciAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgICAgc2VsZiwKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgICBoQnMsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZVJhdGVJbiwKICAgICAgICBjb25zdCBJTlQgc2FtcGxlUmF0ZU91dCwKICAgICAgICBjb25zdCBJTlQgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IEFVRElPX09CSkVDVF9UWVBFIGNvcmVDb2RlYywKICAgICAgICBjb25zdCBNUDRfRUxFTUVOVF9JRCAgICBlbGVtZW50SUQsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgU0JSX0hFQURFUl9TVEFUVVMgaGVhZGVyU3RhdHVzOwogIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNickhlYWRlcjsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CiAgaW50IGhlYWRlckluZGV4OwoKICBpZiAoIHNlbGYgPT0gTlVMTCB8fCBlbGVtZW50SW5kZXggPiAoNCkgKQogIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgaWYgKCEgc2JyRGVjb2Rlcl9pc0NvcmVDb2RlY1ZhbGlkKGNvcmVDb2RlYykpIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0luaXRFbGVtZW50KAogICAgICAgICAgc2VsZiwKICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICBjb3JlQ29kZWMsCiAgICAgICAgICBlbGVtZW50SUQsCiAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICAgICk7CgogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgIGdvdG8gYmFpbDsKICB9CgogIGhlYWRlckluZGV4ID0gZ2V0SGVhZGVyU2xvdChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUhlYWRlclNsb3QpOwogIGhTYnJIZWFkZXIgPSAmKHNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hlYWRlckluZGV4XSk7CgogIGhlYWRlclN0YXR1cyA9IHNickdldEhlYWRlckRhdGEgKCBoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCgogIHsKICAgIFNCUl9ERUNPREVSX0VMRU1FTlQgKnBTYnJFbGVtZW50OwoKICAgIHBTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKCiAgICAvKiBTYW5pdHkgY2hlY2sgKi8KICAgIGlmIChwU2JyRWxlbWVudCAhPSBOVUxMKSB7CiAgICAgIGlmICggKGVsZW1lbnRJRCA9PSBJRF9DUEUgJiYgcFNickVsZW1lbnQtPm5DaGFubmVscyAhPSAyKQogICAgICAgIHx8IChlbGVtZW50SUQgIT0gSURfQ1BFICYmIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMgIT0gMSkgKQogICAgICB7CiAgICAgICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICAgIH0KICAgICAgaWYgKCBoZWFkZXJTdGF0dXMgPT0gSEVBREVSX1JFU0VUICkgewoKICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICBoZWFkZXJTdGF0dXMsCiAgICAgICAgICAgICAgcFNickVsZW1lbnQtPnBTYnJDaGFubmVsLAogICAgICAgICAgICAgIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMKICAgICAgICAgICAgICApOwoKICAgICAgICBpZiAoc2JyRXJyb3IgPT0gU0JSREVDX09LKSB7CiAgICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfSEVBREVSOwogICAgICAgICAgaFNickhlYWRlci0+c3RhdHVzICAgfD0gU0JSREVDX0hEUl9TVEFUX1VQREFURTsKICAgICAgICB9CiAgICAgICAgLyogZWxzZSB7CiAgICAgICAgICBTaW5jZSB3ZSBhbHJlYWR5IGhhdmUgb3ZlcndyaXR0ZW4gdGhlIG9sZCBTQlIgaGVhZGVyIHRoZSBvbmx5IHdheSBvdXQgaXMgVVBTQU1QTElORyEKICAgICAgICAgIFRoaXMgd2lsbCBiZSBwcmVwYXJlZCBpbiB0aGUgbmV4dCBzdGVwLgogICAgICAgIH0gKi8KICAgICAgfQogICAgfQogIH0KYmFpbDoKICByZXR1cm4gc2JyRXJyb3I7Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9TZXRQYXJhbSAoSEFORExFX1NCUkRFQ09ERVIgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0JSREVDX1BBUkFNICBwYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgdmFsdWUgKQp7CiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICAvKiBjb25maWd1cmUgdGhlIHN1YnN5c3RlbXMgKi8KICBzd2l0Y2ggKHBhcmFtKQogIHsKICBjYXNlIFNCUl9TWVNURU1fQklUU1RSRUFNX0RFTEFZOgogICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+ICgxKSkgewogICAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPm51bURlbGF5RnJhbWVzID0gKFVDSEFSKXZhbHVlOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfUU1GX01PREU6CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh2YWx1ZSA9PSAxKSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gU0JSREVDX0xPV19QT1dFUjsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX0xPV19QT1dFUjsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfTERfUU1GX1RJTUVfQUxJR046CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh2YWx1ZSA9PSAxKSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gU0JSREVDX0xEX01QU19RTUY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19MRF9NUFNfUU1GOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIFNCUl9CU19JTlRFUlJVUFRJT046CiAgICB7CiAgICAgIGludCBlbGVtZW50SW5kZXg7CiAgICAgIC8qIExvb3Agb3ZlciBTQlIgZWxlbWVudHMgKi8KICAgICAgZm9yIChlbGVtZW50SW5kZXggPSAwOyBlbGVtZW50SW5kZXggPCBzZWxmLT5udW1TYnJFbGVtZW50czsgZWxlbWVudEluZGV4KyspCiAgICAgIHsKICAgICAgICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgICAgICAgaW50IGhlYWRlckluZGV4ID0gZ2V0SGVhZGVyU2xvdChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VIZWFkZXJTbG90KTsKCiAgICAgICAgaFNickhlYWRlciA9ICYoc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baGVhZGVySW5kZXhdKTsKCiAgICAgICAgLyogU2V0IHN5bmMgc3RhdGUgVVBTQU1QTElORyBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgc2xvdC4KICAgICAgICAgICBUaGlzIHN3aXRjaGVzIG9mZiBiaXRzdHJlYW0gcGFyc2luZyB1bnRpbCBhIG5ldyBoZWFkZXIgYXJyaXZlcy4gKi8KICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBVUFNBTVBMSU5HOwogICAgICAgIGhTYnJIZWFkZXItPnN0YXR1cyAgIHw9IFNCUkRFQ19IRFJfU1RBVF9VUERBVEU7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19TRVRfUEFSQU1fRkFJTDsKICAgIGJyZWFrOwogIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCiAgcmV0dXJuIChlcnJvclN0YXR1cyk7Cn0KCnN0YXRpYwpTQlJERUNfRFJDX0NIQU5ORUwgKiBzYnJEZWNvZGVyX2RyY0dldENoYW5uZWwoIGNvbnN0IEhBTkRMRV9TQlJERUNPREVSIHNlbGYsIGNvbnN0IElOVCBjaGFubmVsICkKewogIFNCUkRFQ19EUkNfQ0hBTk5FTCAqcFNickRyY0NoYW5uZWxEYXRhID0gTlVMTDsKICBpbnQgZWxlbWVudEluZGV4LCBlbENoYW5JZHg9MCwgbnVtQ2g9MDsKCiAgZm9yIChlbGVtZW50SW5kZXggPSAwOyAoZWxlbWVudEluZGV4IDwgKDQpKSAmJiAobnVtQ2ggPD0gY2hhbm5lbCk7IGVsZW1lbnRJbmRleCsrKQogIHsKICAgIFNCUl9ERUNPREVSX0VMRU1FTlQgKnBTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKICAgIGludCBjLCBlbENoYW5uZWxzOwoKICAgIGVsQ2hhbklkeCA9IDA7CiAgICBpZiAocFNickVsZW1lbnQgPT0gTlVMTCkgYnJlYWs7CgogICAgLyogRGV0ZXJtaW5lIGFtb3VudCBvZiBjaGFubmVscyBmb3IgdGhpcyBlbGVtZW50ICovCiAgICBzd2l0Y2ggKHBTYnJFbGVtZW50LT5lbGVtZW50SUQpIHsKICAgICAgY2FzZSBJRF9DUEU6IGVsQ2hhbm5lbHMgPSAyOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIElEX0xGRToKICAgICAgY2FzZSBJRF9TQ0U6IGVsQ2hhbm5lbHMgPSAxOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIElEX05PTkU6CiAgICAgIGRlZmF1bHQ6IGVsQ2hhbm5lbHMgPSAwOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIExpbWl0IHdpdGggYWN0dWFsIGFsbG9jYXRlZCBlbGVtZW50IGNoYW5uZWxzICovCiAgICBlbENoYW5uZWxzID0gRkRLbWluKGVsQ2hhbm5lbHMsIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMpOwoKICAgIGZvciAoYyA9IDA7IChjIDwgZWxDaGFubmVscykgJiYgKG51bUNoIDw9IGNoYW5uZWwpOyBjKyspIHsKICAgICAgaWYgKHBTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFtlbENoYW5JZHhdICE9IE5VTEwpIHsKICAgICAgICBudW1DaCsrOwogICAgICAgIGVsQ2hhbklkeCsrOwogICAgICB9CiAgICB9CiAgfQogIGVsZW1lbnRJbmRleCAtPSAxOwogIGVsQ2hhbklkeCAtPSAxOwoKICBpZiAoZWxDaGFuSWR4IDwgMCB8fCBlbGVtZW50SW5kZXggPCAwKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIGlmICggc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMICkgewogICAgaWYgKCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtlbENoYW5JZHhdICE9IE5VTEwgKQogICAgewogICAgICBwU2JyRHJjQ2hhbm5lbERhdGEgPSAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbZWxDaGFuSWR4XS0+U2JyRGVjLnNickRyY0NoYW5uZWw7CiAgICB9CiAgfQoKICByZXR1cm4gKHBTYnJEcmNDaGFubmVsRGF0YSk7Cn0KClNCUl9FUlJPUiBzYnJEZWNvZGVyX2RyY0ZlZWRDaGFubmVsICggSEFORExFX1NCUkRFQ09ERVIgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICBudW1CYW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICAgICAgICAqcE5leHRGYWN0X21hZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgbmV4dEZhY3RfZXhwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICAgICAgICAgICAgICBkcmNJbnRlcnBvbGF0aW9uU2NoZW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICB3aW5TZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0hPUlQgICAgICAgICAgICAqcEJhbmRUb3AgKQp7CiAgU0JSREVDX0RSQ19DSEFOTkVMICpwU2JyRHJjQ2hhbm5lbERhdGEgPSBOVUxMOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm4gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICB9CiAgaWYgKGNoID4gKDYpIHx8IHBOZXh0RmFjdF9tYWcgPT0gTlVMTCkgewogICAgcmV0dXJuIFNCUkRFQ19TRVRfUEFSQU1fRkFJTDsKICB9CgogIC8qIEZpbmQgdGhlIHJpZ2h0IFNCUiBjaGFubmVsICovCiAgcFNickRyY0NoYW5uZWxEYXRhID0gc2JyRGVjb2Rlcl9kcmNHZXRDaGFubmVsKCBzZWxmLCBjaCApOwoKICBpZiAoIHBTYnJEcmNDaGFubmVsRGF0YSAhPSBOVUxMICkgewogICAgaW50IGk7CgogICAgcFNickRyY0NoYW5uZWxEYXRhLT5lbmFibGUgICA9IDE7CiAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPm51bUJhbmRzTmV4dCA9IG51bUJhbmRzOwoKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+d2luU2VxdWVuY2VOZXh0ICAgICAgICAgICAgPSB3aW5TZXF1ZW5jZTsKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+ZHJjSW50ZXJwb2xhdGlvblNjaGVtZU5leHQgPSBkcmNJbnRlcnBvbGF0aW9uU2NoZW1lOwogICAgcFNickRyY0NoYW5uZWxEYXRhLT5uZXh0RmFjdF9leHAgICAgICAgICAgICAgICA9IG5leHRGYWN0X2V4cDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgKGludCludW1CYW5kczsgaSsrKSB7CiAgICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+YmFuZFRvcE5leHRbaV0gID0gcEJhbmRUb3BbaV07CiAgICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+bmV4dEZhY3RfbWFnW2ldID0gcE5leHRGYWN0X21hZ1tpXTsKICAgIH0KICB9CgogIHJldHVybiBTQlJERUNfT0s7Cn0KCgp2b2lkIHNickRlY29kZXJfZHJjRGlzYWJsZSAoIEhBTkRMRV9TQlJERUNPREVSICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICBjaCApCnsKICBTQlJERUNfRFJDX0NIQU5ORUwgKnBTYnJEcmNDaGFubmVsRGF0YSA9IE5VTEw7CgogIGlmICggKHNlbGYgPT0gTlVMTCkKICAgIHx8IChjaCA+ICg2KSkKICAgIHx8IChzZWxmLT5udW1TYnJFbGVtZW50cyA9PSAwKQogICAgfHwgKHNlbGYtPm51bVNickNoYW5uZWxzID09IDApICkgewogICAgcmV0dXJuOwogIH0KCiAgLyogRmluZCB0aGUgcmlnaHQgU0JSIGNoYW5uZWwgKi8KICBwU2JyRHJjQ2hhbm5lbERhdGEgPSBzYnJEZWNvZGVyX2RyY0dldENoYW5uZWwoIHNlbGYsIGNoICk7CgogIGlmICggcFNickRyY0NoYW5uZWxEYXRhICE9IE5VTEwgKSB7CiAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPmVuYWJsZSA9IDA7CiAgfQp9CgoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX1BhcnNlKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gIGhCcywKICAgICAgICBpbnQgKmNvdW50LAogICAgICAgIGludCAgYnNQYXlMZW4sCiAgICAgICAgaW50ICBjcmNGbGFnLAogICAgICAgIE1QNF9FTEVNRU5UX0lEIHByZXZFbGVtZW50LAogICAgICAgIGludCBlbGVtZW50SW5kZXgsCiAgICAgICAgaW50IGZHbG9iYWxJbmRlcGVuZGVuY3lGbGFnCiAgICAgICAgKQp7CiAgU0JSX0RFQ09ERVJfRUxFTUVOVCAgICpoU2JyRWxlbWVudDsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgSEFORExFX1NCUl9DSEFOTkVMICAgICpwU2JyQ2hhbm5lbDsKCiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFMZWZ0OwogIFNCUl9GUkFNRV9EQVRBICpoRnJhbWVEYXRhUmlnaHQ7CgogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKICBTQlJfU1lOQ19TVEFURSBpbml0aWFsU3luY1N0YXRlOwogIFNCUl9IRUFERVJfU1RBVFVTIGhlYWRlclN0YXR1cyA9IEhFQURFUl9OT1RfUFJFU0VOVDsKCiAgSU5UICBzdGFydFBvczsKICBJTlQgIENSQ0xlbiA9IDA7CgogIGludCAgc3RlcmVvOwogIGludCAgZkRvRGVjb2RlU2JyRGF0YSA9IDE7CgogIGludCBsYXN0U2xvdCwgbGFzdEhkclNsb3QgPSAwLCB0aGlzSGRyU2xvdDsKCiAgLyogUmVtZW1iZXIgc3RhcnQgcG9zaXRpb24gb2YgIFNCUiBlbGVtZW50ICovCiAgc3RhcnRQb3MgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgLyogU0JSIHNhbml0eSBjaGVja3MgKi8KICBpZiAoIHNlbGYgPT0gTlVMTCB8fCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID09IE5VTEwgKSB7CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19OT1RfSU5JVElBTElaRUQ7CiAgICBnb3RvIGJhaWw7CiAgfSAKCiAgaFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwoKICBsYXN0U2xvdCAgICA9IChoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID4gMCkgPyBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90LTEgOiBzZWxmLT5udW1EZWxheUZyYW1lczsKICBsYXN0SGRyU2xvdCA9ICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtsYXN0U2xvdF07CiAgdGhpc0hkclNsb3QgPSAgZ2V0SGVhZGVyU2xvdCggaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCwgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3QgKTsgIC8qIEdldCBhIGZyZWUgaGVhZGVyIHNsb3Qgbm90IHVzZWQgYnkgZnJhbWVzIG5vdCBwcm9jZXNzZWQgeWV0LiAqLwoKICAvKiBBc3NpZ24gdGhlIGZyZWUgc2xvdCB0byBzdG9yZSBhIG5ldyBoZWFkZXIgaWYgdGhlcmUgaXMgb25lLiAqLwogIGhTYnJIZWFkZXIgPSAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1bdGhpc0hkclNsb3RdOwoKICBwU2JyQ2hhbm5lbCA9IGhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbDsKICBzdGVyZW8gPSAoaFNickVsZW1lbnQtPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMSA6IDA7CgogIGhGcmFtZURhdGFMZWZ0ICA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFswXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwogIGhGcmFtZURhdGFSaWdodCA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICBpbml0aWFsU3luY1N0YXRlID0gaFNickhlYWRlci0+c3luY1N0YXRlOwoKICAvKiByZXNldCBQUyBmbGFnOyB3aWxsIGJlIHNldCBhZnRlciBQUyB3YXMgZm91bmQgKi8KICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX1BTX0RFQ09ERUQ7CgogIGlmIChoU2JySGVhZGVyLT5zdGF0dXMgJiBTQlJERUNfSERSX1NUQVRfVVBEQVRFKSB7CiAgICAvKiBHb3QgYSBuZXcgaGVhZGVyIGZyb20gZXh0ZXJuIChlLmcuIGZyb20gYW4gQVNDKSAqLwogICAgaGVhZGVyU3RhdHVzID0gSEVBREVSX09LOwogICAgaFNickhlYWRlci0+c3RhdHVzICY9IH5TQlJERUNfSERSX1NUQVRfVVBEQVRFOwogIH0KICBlbHNlIGlmICh0aGlzSGRyU2xvdCAhPSBsYXN0SGRyU2xvdCkgewogICAgLyogQ29weSB0aGUgbGFzdCBoZWFkZXIgaW50byB0aGlzIHNsb3Qgb3RoZXJ3aXNlIHRoZQogICAgICAgaGVhZGVyIGNvbXBhcmUgd2lsbCB0cmlnZ2VyIG1vcmUgSEVBREVSX1JFU0VUcyB0aGFuIG5lZWRlZC4gKi8KICAgIGNvcHlTYnJIZWFkZXIoIGhTYnJIZWFkZXIsICZzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtsYXN0SGRyU2xvdF0gKTsKICB9CgogIC8qCiAgICAgQ2hlY2sgaWYgYml0IHN0cmVhbSBkYXRhIGlzIHZhbGlkIGFuZCBtYXRjaGVzIHRoZSBlbGVtZW50IGNvbnRleHQKICAqLwogIGlmICggKChwcmV2RWxlbWVudCAhPSBJRF9TQ0UpICYmIChwcmV2RWxlbWVudCAhPSBJRF9DUEUpKSB8fCBwcmV2RWxlbWVudCAhPSBoU2JyRWxlbWVudC0+ZWxlbWVudElEKSB7CiAgICAvKiBJbiBjYXNlIG9mIExGRSB3ZSBhbHNvIGxhbmQgaGVyZSwgc2luY2UgdGhlcmUgaXMgbm8gTEZFIFNCUiBlbGVtZW50IChkbyB1cHNhbXBsaW5nIG9ubHkpICovCiAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICB9CgogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpIDw9IDApIHsKICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICB9CiAgfQoKICAvKgogICAgIFNCUiBDUkMtY2hlY2sKICAqLwogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGlmIChjcmNGbGFnID09IDEpIHsKICAgICAgc3dpdGNoIChzZWxmLT5jb3JlQ29kZWMpIHsKICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICBGREtwdXNoRm9yIChoQnMsIDEwKTsKICAgICAgICAvKiBjaGVjayBzYnJjcmMgbGF0ZXI6IHdlIGRvbid0IGtub3cgdGhlIHBheWxvYWQgbGVuZ3RoIG5vdyAqLwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIENSQ0xlbiA9IGJzUGF5TGVuIC0gMTA7ICAgICAgICAgICAgICAgICAgICAgLyogY2hhbmdlOiAwID0+IGkgKi8KICAgICAgICBpZiAoQ1JDTGVuIDwgMCkgewogICAgICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgPSBTYnJDcmNDaGVjayAoaEJzLCBDUkNMZW4pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0gLyogaWYgKGZEb0RlY29kZVNickRhdGEpICovCgogIC8qCiAgICAgUmVhZCBpbiB0aGUgaGVhZGVyIGRhdGEgYW5kIGlzc3VlIGEgcmVzZXQgaWYgY2hhbmdlIG9jY3VyZWQKICAqLwogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGludCBzYnJIZWFkZXJQcmVzZW50OwoKICAgIHsKICAgICAgc2JySGVhZGVyUHJlc2VudCA9IEZES3JlYWRCaXQoaEJzKTsKICAgIH0KCiAgICBpZiAoIHNickhlYWRlclByZXNlbnQgKSB7CiAgICAgIGhlYWRlclN0YXR1cyA9IHNickdldEhlYWRlckRhdGEgKGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpOwogICAgfQoKICAgIGlmIChoZWFkZXJTdGF0dXMgPT0gSEVBREVSX1JFU0VUKQogICAgewogICAgICBlcnJvclN0YXR1cyA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBoZWFkZXJTdGF0dXMsCiAgICAgICAgICAgIHBTYnJDaGFubmVsLAogICAgICAgICAgICBoU2JyRWxlbWVudC0+bkNoYW5uZWxzIAogICAgICAgICAgICApOwoKICAgICAgaWYgKGVycm9yU3RhdHVzID09IFNCUkRFQ19PSykgewogICAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9IRUFERVI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gU0JSX05PVF9JTklUSUFMSVpFRDsKICAgICAgfQogICAgfQoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICB9CiAgfSAvKiBpZiAoZkRvRGVjb2RlU2JyRGF0YSkgKi8KCiAgLyoKICAgIFByaW50IGRlYnVnZ2luZyBvdXRwdXQgb25seSBpZiBzdGF0ZSBoYXMgY2hhbmdlZAogICovCgogIC8qIHJlYWQgZnJhbWUgZGF0YSAqLwogIGlmICgoaFNickhlYWRlci0+c3luY1N0YXRlID49IFNCUl9IRUFERVIpICYmIGZEb0RlY29kZVNickRhdGEpIHsKICAgIGludCBzYnJGcmFtZU9rOwogICAgLyogcmVhZCB0aGUgU0JSIGVsZW1lbnQgZGF0YSAqLwogICAgaWYgKHN0ZXJlbykgewogICAgICBzYnJGcmFtZU9rID0gc2JyR2V0Q2hhbm5lbFBhaXJFbGVtZW50KGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YVJpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT50cmFuc3Bvc2VyU2V0dGluZ3Mub3ZlcmxhcCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgaWYgKHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjICE9IE5VTEwpIHsKICAgICAgICAvKiB1cGRhdGUgc2xvdCBpbmRleCBmb3IgUFMgYml0c3RyZWFtIHBhcnNpbmcgKi8KICAgICAgICBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYy0+YnNMYXN0U2xvdCA9IHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic1JlYWRTbG90OwogICAgICAgIHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic1JlYWRTbG90ID0gaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdDsKICAgICAgfQogICAgICBzYnJGcmFtZU9rID0gc2JyR2V0U2luZ2xlQ2hhbm5lbEVsZW1lbnQoaFNickhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhGcmFtZURhdGFMZWZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnRyYW5zcG9zZXJTZXR0aW5ncy5vdmVybGFwKTsKICAgIH0KICAgIGlmICghc2JyRnJhbWVPaykgewogICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgIH0KICAgIGVsc2UgewogICAgICBJTlQgdmFsQml0czsKCiAgICAgIGlmIChic1BheUxlbiA+IDApIHsKICAgICAgICB2YWxCaXRzID0gYnNQYXlMZW4gLSAoKElOVClzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhbEJpdHMgPSAoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpOwogICAgICB9CgogICAgICBpZiAoIGNyY0ZsYWcgPT0gMSApIHsKICAgICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIGxhdGUgY3JjIGNoZWNrIGZvciBlbGQgKi8KICAgICAgICAgICAgSU5UIHBheWxvYWRiaXRzID0gKElOVClzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBzdGFydFBvczsKICAgICAgICAgICAgSU5UIGNyY0xlbiAgICAgID0gcGF5bG9hZGJpdHMgLSAxMDsKICAgICAgICAgICAgRkRLcHVzaEJhY2soaEJzLCBwYXlsb2FkYml0cyk7CiAgICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgICAgICA9IFNickNyY0NoZWNrIChoQnMsIGNyY0xlbik7CiAgICAgICAgICAgIEZES3B1c2hGb3IoaEJzLCBjcmNMZW4pOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogc2FuaXR5IGNoZWNrIG9mIHJlbWFpbmluZyBiaXRzICovCiAgICAgIGlmICh2YWxCaXRzIDwgMCkgewogICAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIHN3aXRjaCAoc2VsZi0+Y29yZUNvZGVjKSB7CiAgICAgICAgY2FzZSBBT1RfU0JSOgogICAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgICAgIHsKICAgICAgICAgICAgLyogVGhpcyBzYW5pdHkgY2hlY2sgaXMgb25seSBtZWFuaW5nZnVsIHdpdGggR2VuZXJhbCBBdWRpbyBiaXRzdHJlYW1zICovCiAgICAgICAgICAgIGludCBhbGlnbkJpdHMgPSB2YWxCaXRzICYgMHg3OwoKICAgICAgICAgICAgaWYgKHZhbEJpdHMgPiBhbGlnbkJpdHMpIHsKICAgICAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIC8qIE5vIHNhbml0eSBjaGVjayBhdmFpbGFibGUgKi8KICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgaWYgKCFmRG9EZWNvZGVTYnJEYXRhKSB7CiAgICAvKiBTZXQgZXJyb3IgZmxhZyBmb3IgdGhpcyBzbG90IHRvIHRyaWdnZXIgY29uY2VhbG1lbnQgKi8KICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdID0gMTsKICAgIGVycm9yU3RhdHVzID0gU0JSREVDX1BBUlNFX0VSUk9SOwogIH0gZWxzZSB7CiAgICAvKiBFdmVyeXRoaW5nIHNlZW1zIHRvIGJlIG9rIHNvIGNsZWFyIHRoZSBlcnJvciBmbGFnICovCiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5mcmFtZUVycm9yRmxhZ1toU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XSA9IDA7CiAgfQoKICBpZiAoIXN0ZXJlbykgewogICAgLyogVHVybiBjb3VwbGluZyBvZmYgZXhwbGljaXRlbHkgdG8gYXZvaWQgYWNjZXNzIHRvIGFic2VudCByaWdodCBmcmFtZSBkYXRhCiAgICAgICB0aGF0IG1pZ2h0IG9jY3VyIHdpdGggY29ycnVwdCBiaXRzdHJlYW1zLiAqLwogICAgaEZyYW1lRGF0YUxlZnQtPmNvdXBsaW5nID0gQ09VUExJTkdfT0ZGOwogIH0KCmJhaWw6CiAgaWYgKGVycm9yU3RhdHVzID09IFNCUkRFQ19PSykgewogICAgaWYgKGhlYWRlclN0YXR1cyA9PSBIRUFERVJfTk9UX1BSRVNFTlQpIHsKICAgICAgLyogVXNlIHRoZSBvbGQgaGVhZGVyIGZvciB0aGlzIGZyYW1lICovCiAgICAgIGhTYnJFbGVtZW50LT51c2VIZWFkZXJTbG90W2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdID0gbGFzdEhkclNsb3Q7CiAgICB9IGVsc2UgewogICAgICAvKiBVc2UgdGhlIG5ldyBoZWFkZXIgZm9yIHRoaXMgZnJhbWUgKi8KICAgICAgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSB0aGlzSGRyU2xvdDsKICAgIH0KCiAgICAvKiBNb3ZlIGZyYW1lIHBvaW50ZXIgdG8gdGhlIG5leHQgc2xvdCB3aGljaCBpcyB1cCB0byBiZSBkZWNvZGVkL2FwcGxpZWQgbmV4dCAqLwogICAgaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCA9IChoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90KzEpICUgKHNlbGYtPm51bURlbGF5RnJhbWVzKzEpOwogIH0KCiAgKmNvdW50IC09IHN0YXJ0UG9zIC0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKCi8qKgogKiBcYnJpZWYgUmVuZGVyIG9uZSBTQlIgZWxlbWVudCBpbnRvIHRpbWUgZG9tYWluIHNpZ25hbC4KICogXHBhcmFtIHNlbGYgU0JSIGRlY29kZXIgaGFuZGxlCiAqIFxwYXJhbSB0aW1lRGF0YSBwb2ludGVyIHRvIG91dHB1dCBidWZmZXIKICogXHBhcmFtIGludGVybGVhdmVkIGZsYWcgaW5kaWNhdGluZyBpbnRlcmxlYXZlZCBjaGFubmVsIG91dHB1dAogKiBccGFyYW0gY2hhbm5lbE1hcHBpbmcgcG9pbnRlciB0byBVQ0hBUiBhcnJheSB3aGVyZSBuZXh0IDIgY2hhbm5lbCBvZmZzZXRzIGFyZSBzdG9yZWQuIAogKiBccGFyYW0gZWxlbWVudEluZGV4IGVudW1lcmF0aW5nIGluZGV4IG9mIHRoZSBTQlIgZWxlbWVudCB0byByZW5kZXIuCiAqIFxwYXJhbSBudW1JbkNoYW5uZWxzIG51bWJlciBvZiBjaGFubmVscyBmcm9tIGNvcmUgY29kZXIgKHJlYWRpbmcgc3RyaWRlKS4KICogXHBhcmFtIG51bU91dENoYW5uZWxzIHBvaW50ZXIgdG8gYSBsb2NhdGlvbiB0byByZXR1cm4gbnVtYmVyIG9mIG91dHB1dCBjaGFubmVscy4KICogXHBhcmFtIHBzUG9zc2libGUgZmxhZyBpbmRpY2F0aW5nIGlmIFBTIGlzIHBvc3NpYmxlIG9yIG5vdC4KICogXHJldHVybiBTQlJERUNfT0sgaWYgc3VjY2Vzc2Z1bGwsIGVsc2UgZXJyb3IgY29kZQogKi8Kc3RhdGljIFNCUl9FUlJPUgpzYnJEZWNvZGVyX0RlY29kZUVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgIHNlbGYsCiAgICAgICAgSU5UX1BDTSAgICAgICAgICAgICAqdGltZURhdGEsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgY29uc3QgVUNIQVIgICAgICAgICAqY2hhbm5lbE1hcHBpbmcsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgZWxlbWVudEluZGV4LAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIG51bUluQ2hhbm5lbHMsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAqbnVtT3V0Q2hhbm5lbHMsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgcHNQb3NzaWJsZQogICAgICAgICkKewogIFNCUl9ERUNPREVSX0VMRU1FTlQgKmhTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKICBIQU5ETEVfU0JSX0NIQU5ORUwgICAgKnBTYnJDaGFubmVsID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWw7CiAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyID0gJnNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hTYnJFbGVtZW50LT51c2VIZWFkZXJTbG90W2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdXTsKICBIQU5ETEVfUFNfREVDIGhfcHNfZCA9IHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmcmFtZSBkYXRhIGZyb20gc2NyYXRjaCAqLwogIFNCUl9GUkFNRV9EQVRBICpoRnJhbWVEYXRhTGVmdCAgPSAmaFNickVsZW1lbnQtPnBTYnJDaGFubmVsWzBdLT5mcmFtZURhdGFbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF07CiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFSaWdodCA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMV0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKCiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKCiAgSU5UICBzdHJpZGVJbiwgc3RyaWRlT3V0LCBvZmZzZXQwLCBvZmZzZXQxOwogIElOVCAgY29kZWNGcmFtZVNpemUgPSBzZWxmLT5jb2RlY0ZyYW1lU2l6ZTsKCiAgaW50ICBzdGVyZW8gPSAoaFNickVsZW1lbnQtPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMSA6IDA7CiAgaW50ICBudW1FbGVtZW50Q2hhbm5lbHMgPSBoU2JyRWxlbWVudC0+bkNoYW5uZWxzOyAvKiBOdW1iZXIgb2YgY2hhbm5lbHMgb2YgdGhlIGN1cnJlbnQgU0JSIGVsZW1lbnQgKi8KCiAgLyogVXBkYXRlIHRoZSBoZWFkZXIgZXJyb3IgZmxhZyAqLwogIGhTYnJIZWFkZXItPmZyYW1lRXJyb3JGbGFnID0gaFNickVsZW1lbnQtPmZyYW1lRXJyb3JGbGFnW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICAvKgogICAgIFByZXBhcmUgZmlsdGVyYmFuayBmb3IgdXBzYW1wbGluZyBpZiBubyB2YWxpZCBiaXQgc3RyZWFtIGRhdGEgaXMgYXZhaWxhYmxlLgogICAqLwogIGlmICggaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9OT1RfSU5JVElBTElaRUQgKQogIHsKICAgIGVycm9yU3RhdHVzID0gaW5pdEhlYWRlckRhdGEoCiAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgIHNlbGYtPnNhbXBsZVJhdGVJbiwKICAgICAgICAgICAgc2VsZi0+c2FtcGxlUmF0ZU91dCwKICAgICAgICAgICAgY29kZWNGcmFtZVNpemUsCiAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICAgICk7CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICByZXR1cm4gZXJyb3JTdGF0dXM7CiAgICB9CgogICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gVVBTQU1QTElORzsKCiAgICBlcnJvclN0YXR1cyA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBIRUFERVJfTk9UX1BSRVNFTlQsCiAgICAgICAgICAgIHBTYnJDaGFubmVsLAogICAgICAgICAgICBoU2JyRWxlbWVudC0+bkNoYW5uZWxzCiAgICAgICAgICAgICk7CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfTk9UX0lOSVRJQUxJWkVEOwogICAgICByZXR1cm4gZXJyb3JTdGF0dXM7CiAgICB9CiAgfQoKICAvKiByZXNldCAqLwogIGlmIChoU2JySGVhZGVyLT5zdGF0dXMgJiBTQlJERUNfSERSX1NUQVRfUkVTRVQpIHsKICAgIGludCBjaDsKICAgIGZvciAoY2ggPSAwIDsgY2ggPCBudW1FbGVtZW50Q2hhbm5lbHM7IGNoKyspIHsKICAgICAgU0JSX0VSUk9SIGVycm9yU3RhdHVzVG1wID0gU0JSREVDX09LOwoKICAgICAgZXJyb3JTdGF0dXNUbXAgPSByZXNldFNickRlYyAoCiAgICAgICAgICAgICAmcFNickNoYW5uZWxbY2hdLT5TYnJEZWMsCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFtjaF0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSLAogICAgICAgICAgICAgIHNlbGYtPnN5bkRvd25zYW1wbGVGYWMKICAgICAgICAgICAgICApOwoKICAgICAgaWYgKGVycm9yU3RhdHVzVG1wICE9IFNCUkRFQ19PSykgewogICAgICAgIGVycm9yU3RhdHVzID0gZXJyb3JTdGF0dXNUbXA7CiAgICAgIH0KICAgIH0KICAgIGhTYnJIZWFkZXItPnN0YXR1cyAmPSB+U0JSREVDX0hEUl9TVEFUX1JFU0VUOwogIH0KCiAgLyogZGVjb2RpbmcgKi8KICBpZiAoIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0FDVElWRSkKICAgIHx8ICgoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9IRUFERVIpICYmIChoU2JySGVhZGVyLT5mcmFtZUVycm9yRmxhZyA9PSAwKSkgKQogIHsKICAgIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICAgIGRlY29kZVNickRhdGEgKGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAgICAgICAgJnBTYnJDaGFubmVsWzBdLT5wcmV2RnJhbWVEYXRhLAogICAgICAgICAgICAgICAgICAgKHN0ZXJlbykgPyBoRnJhbWVEYXRhUmlnaHQgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgKHN0ZXJlbykgPyAmcFNickNoYW5uZWxbMV0tPnByZXZGcmFtZURhdGEgOiBOVUxMKTsKCgogICAgLyogTm93IHdlIGhhdmUgYSBmdWxsIHBhcmFtZXRlciBzZXQgYW5kIGNhbiBkbyBwYXJhbWV0ZXIKICAgICAgIGJhc2VkIGNvbmNlYWxtZW50IGluc3RlYWQgb2YgcGxhaW4gdXBzYW1wbGluZy4gKi8KICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9BQ1RJVkU7CiAgfQoKICAvKiBkZWNvZGUgUFMgZGF0YSBpZiBhdmFpbGFibGUgKi8KICBpZiAoaF9wc19kICE9IE5VTEwgJiYgcHNQb3NzaWJsZSkgewogICAgaW50IGFwcGx5UHMgPSAxOwoKICAgIC8qIGRlZmluZSB3aGljaCBmcmFtZSBkZWxheSBsaW5lIHNsb3QgdG8gcHJvY2VzcyAqLwogICAgaF9wc19kLT5wcm9jZXNzU2xvdCA9IGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3Q7CgogICAgYXBwbHlQcyA9IERlY29kZVBzKGhfcHNfZCwgaFNickhlYWRlci0+ZnJhbWVFcnJvckZsYWcpOwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFwcGx5UHMpID8gU0JSREVDX1BTX0RFQ09ERUQgOiAwOwogIH0KCiAgLyogU2V0IHN0cmlkZXMgZm9yIHJlYWRpbmcgYW5kIHdyaXRpbmcgKi8KICBpZiAoaW50ZXJsZWF2ZWQpIHsKICAgIHN0cmlkZUluID0gbnVtSW5DaGFubmVsczsKICAgIGlmICggcHNQb3NzaWJsZSApCiAgICAgIHN0cmlkZU91dCA9IChudW1JbkNoYW5uZWxzIDwgMikgPyAyIDogbnVtSW5DaGFubmVsczsKICAgIGVsc2UKICAgICAgc3RyaWRlT3V0ID0gbnVtSW5DaGFubmVsczsKICAgIG9mZnNldDAgPSBjaGFubmVsTWFwcGluZ1swXTsKICAgIG9mZnNldDEgPSBjaGFubmVsTWFwcGluZ1sxXTsKICB9IGVsc2UgewogICAgc3RyaWRlSW4gID0gMTsKICAgIHN0cmlkZU91dCA9IDE7CiAgICBvZmZzZXQwID0gY2hhbm5lbE1hcHBpbmdbMF0qMipjb2RlY0ZyYW1lU2l6ZTsKICAgIG9mZnNldDEgPSBjaGFubmVsTWFwcGluZ1sxXSoyKmNvZGVjRnJhbWVTaXplOwogIH0KCiAgLyogdXNlIHNhbWUgYnVmZmVycyBmb3IgbGVmdCBhbmQgcmlnaHQgY2hhbm5lbCBhbmQgYXBwbHkgUFMgcGVyIHRpbWVzbG90ICovCiAgLyogUHJvY2VzcyBsZWZ0IGNoYW5uZWwgKi8KLy9GREtwcmludGYoInNlbGYtPmNvZGVjRnJhbWVTaXplICVkXHQlZFxuIixzZWxmLT5jb2RlY0ZyYW1lU2l6ZSxzZWxmLT5zYW1wbGVSYXRlSW4pOwogIHNicl9kZWMgKCZwU2JyQ2hhbm5lbFswXS0+U2JyRGVjLAogICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDAsCiAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MCwKICAgICAgICAgICAmcFNickNoYW5uZWxbMV0tPlNickRlYywKICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQxLAogICAgICAgICAgICBzdHJpZGVJbiwKICAgICAgICAgICAgc3RyaWRlT3V0LAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAmcFNickNoYW5uZWxbMF0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0FDVElWRSksCiAgICAgICAgICAgIGhfcHNfZCwKICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICk7CgogIGlmIChzdGVyZW8pIHsKICAgIC8qIFByb2Nlc3MgcmlnaHQgY2hhbm5lbCAqLwogICAgc2JyX2RlYyAoJnBTYnJDaGFubmVsWzFdLT5TYnJEZWMsCiAgICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQxLAogICAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MSwKICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgc3RyaWRlSW4sCiAgICAgICAgICAgICAgc3RyaWRlT3V0LAogICAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgaEZyYW1lRGF0YVJpZ2h0LAogICAgICAgICAgICAgJnBTYnJDaGFubmVsWzFdLT5wcmV2RnJhbWVEYXRhLAogICAgICAgICAgICAgIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0FDVElWRSksCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgICApOwogIH0KCiAgaWYgKGhfcHNfZCAhPSBOVUxMKSB7CiAgICAvKiBzYXZlIFBTIHN0YXR1cyBmb3IgbmV4dCBydW4gKi8KICAgIGhfcHNfZC0+cHNEZWNvZGVkUHJ2ID0gKHNlbGYtPmZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpID8gMSA6IDAgOwogIH0KCiAgaWYgKCBwc1Bvc3NpYmxlIAogICAgKQogIHsKICAgIEZES19BU1NFUlQoc3RyaWRlT3V0ID4gMSk7CiAgICBpZiAoICEoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfUFNfREVDT0RFRCkgKSB7CiAgICAgIC8qIEEgZGVjb2RlciB3aGljaCBpcyBhYmxlIHRvIGRlY29kZSBQUyBoYXMgdG8gcHJvZHVjZSBhIHN0ZXJlbyBvdXRwdXQgZXZlbiBpZiBubyBQUyBkYXRhIGlzIGF2YWlsYmxlLiAqLwogICAgICAvKiBTbyBjb3B5IGxlZnQgY2hhbm5lbCB0byByaWdodCBjaGFubmVsLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgaWYgKGludGVybGVhdmVkKSB7CiAgICAgICAgSU5UX1BDTSAqcHRyOwogICAgICAgIElOVCBpOwogICAgICAgIEZES19BU1NFUlQoc3RyaWRlT3V0ID09IDIpOwoKICAgICAgICBwdHIgPSB0aW1lRGF0YTsKICAgICAgICBmb3IgKGkgPSBjb2RlY0ZyYW1lU2l6ZTsgaS0tOyApIAogICAgICAgIHsKICAgICAgICAgIElOVF9QQ00gdG1wOyAvKiBUaGlzIHRlbXBvcmFsIHZhcmlhYmxlIGlzIHJlcXVpcmVkIGJlY2F1c2Ugc29tZSBjb21waWxlcnMgY2FuJ3QgZG8gKnB0cisrID0gKnB0cisrIGNvcnJlY3RseS4gKi8KICAgICAgICAgIHRtcCA9ICpwdHIrKzsgKnB0cisrID0gdG1wOwogICAgICAgICAgdG1wID0gKnB0cisrOyAqcHRyKysgPSB0bXA7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIEZES21lbWNweSggdGltZURhdGErMipjb2RlY0ZyYW1lU2l6ZSwgdGltZURhdGEsIDIqY29kZWNGcmFtZVNpemUqc2l6ZW9mKElOVF9QQ00pICk7CiAgICAgIH0KICAgIH0KICAgICpudW1PdXRDaGFubmVscyA9IDI7ICAvKiBPdXRwdXQgbWluaW11bSB0d28gY2hhbm5lbHMgd2hlbiBQUyBpcyBlbmFibGVkLiAqLwogIH0KCiAgcmV0dXJuIGVycm9yU3RhdHVzOwp9CgoKU0JSX0VSUk9SIHNickRlY29kZXJfQXBwbHkgKCBIQU5ETEVfU0JSREVDT0RFUiAgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UX1BDTSAgICAgICAgICAgICp0aW1lRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgKm51bUNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAqc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAgICAgICAgIGNoYW5uZWxNYXBwaW5nWyg2KV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ICAgICAgICAgICBpbnRlcmxlYXZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgICAgICAgICAgIGNvcmVEZWNvZGVkT2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgICAgICAgICAgICAgICpwc0RlY29kZWQgKQp7CiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICBpbnQgICBwc1Bvc3NpYmxlID0gMDsKICBpbnQgICBzYnJFbGVtZW50TnVtOwogIGludCAgIG51bUNvcmVDaGFubmVscyA9ICpudW1DaGFubmVsczsKICBpbnQgICBudW1TYnJDaGFubmVscyAgPSAwOwoKICBwc1Bvc3NpYmxlID0gKnBzRGVjb2RlZDsKCiAgaWYgKHNlbGYtPm51bVNickVsZW1lbnRzIDwgMSkgewogICAgLyogZXhpdCBpbW1lZGlhdGVseSB0byBhdm9pZCBhY2Nlc3MgdmlvbGF0aW9ucyAqLwogICAgcmV0dXJuIFNCUkRFQ19DUkVBVEVfRVJST1I7CiAgfQoKICAvKiBTYW5pdHkgY2hlY2sgb2YgYWxsb2NhdGVkIFNCUiBlbGVtZW50cy4gKi8KICBmb3IgKHNickVsZW1lbnROdW09MDsgc2JyRWxlbWVudE51bTxzZWxmLT5udW1TYnJFbGVtZW50czsgc2JyRWxlbWVudE51bSsrKSB7CiAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0gPT0gTlVMTCkgewogICAgICByZXR1cm4gU0JSREVDX0NSRUFURV9FUlJPUjsKICAgIH0KICB9CgogIGlmIChzZWxmLT5udW1TYnJFbGVtZW50cyAhPSAxIHx8IHNlbGYtPnBTYnJFbGVtZW50WzBdLT5lbGVtZW50SUQgIT0gSURfU0NFKSB7CiAgICBwc1Bvc3NpYmxlID0gMDsKICB9CgoKICAvKiBJbiBjYXNlIG9mIG5vbi1pbnRlcmxlYXZlZCB0aW1lIGRvbWFpbiBkYXRhIGFuZCB1cHNhbXBsaW5nLCBtYWtlIHJvb20gZm9yIGJpZ2dlciBTQlIgb3V0cHV0LiAqLwogIGlmIChzZWxmLT5zeW5Eb3duc2FtcGxlRmFjID09IDEgJiYgaW50ZXJsZWF2ZWQgPT0gMCkgewogICAgaW50IGMsIG91dHB1dEZyYW1lU2l6ZTsKCiAgICBvdXRwdXRGcmFtZVNpemUgPQogICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFswXS0+cFNickNoYW5uZWxbMF0tPlNickRlYy5TeW50aGVzaXNRTUYubm9fY2hhbm5lbHMKICAgICAgICAgICAgKiBzZWxmLT5wU2JyRWxlbWVudFswXS0+cFNickNoYW5uZWxbMF0tPlNickRlYy5TeW50aGVzaXNRTUYubm9fY29sOwoKICAgIGZvciAoYz1udW1Db3JlQ2hhbm5lbHMtMTsgYz4wOyBjLS0pIHsKICAgICAgRkRLbWVtbW92ZSh0aW1lRGF0YSArIGMqb3V0cHV0RnJhbWVTaXplLCB0aW1lRGF0YSArIGMqc2VsZi0+Y29kZWNGcmFtZVNpemUgLCBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSpzaXplb2YoSU5UX1BDTSkpOwogICAgfQogIH0KCgogIC8qIE1ha2Ugc3VyZSB0aGF0IGV2ZW4gaWYgbm8gU0JSIGRhdGEgd2FzIGZvdW5kL3BhcnNlZCAqcHNEZWNvZGVkIGlzIHJldHVybmVkIDEgaWYgcHNQb3NzaWJsZSB3YXMgMC4gKi8KICBpZiAocHNQb3NzaWJsZSA9PSAwKSB7CiAgICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX1BTX0RFQ09ERUQ7CiAgfQoKICAvKiBMb29wIG92ZXIgU0JSIGVsZW1lbnRzICovCiAgZm9yIChzYnJFbGVtZW50TnVtID0gMDsgc2JyRWxlbWVudE51bTxzZWxmLT5udW1TYnJFbGVtZW50czsgc2JyRWxlbWVudE51bSsrKQogIHsKICAgIGludCBudW1FbGVtZW50Q2hhbjsKCiAgICBpZiAocHNQb3NzaWJsZSAmJiBzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXS0+cFNickNoYW5uZWxbMV0gPT0gTlVMTCkgewogICAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBudW1FbGVtZW50Q2hhbiA9IChzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXS0+ZWxlbWVudElEID09IElEX0NQRSkgPyAyIDogMTsKCiAgICAvKiBJZiBjb3JlIHNpZ25hbCBpcyBiYWQgdGhlbiBmb3JjZSB1cHNhbXBsaW5nICovCiAgICBpZiAoICEgY29yZURlY29kZWRPayApIHsKICAgICAgc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0tPmZyYW1lRXJyb3JGbGFnW3NlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT51c2VGcmFtZVNsb3RdID0gMTsKICAgIH0KCiAgICBlcnJvclN0YXR1cyA9IHNickRlY29kZXJfRGVjb2RlRWxlbWVudCAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmxlYXZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNickVsZW1lbnROdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bUNvcmVDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtRWxlbWVudENoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzUG9zc2libGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgbnVtU2JyQ2hhbm5lbHMgKz0gbnVtRWxlbWVudENoYW47CiAgICBjaGFubmVsTWFwcGluZyArPSBudW1FbGVtZW50Q2hhbjsKCiAgICBpZiAobnVtU2JyQ2hhbm5lbHMgPj0gbnVtQ29yZUNoYW5uZWxzKSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgLyogVXBkYXRlIG51bUNoYW5uZWxzIGFuZCBzYW1wbGVyYXRlICovCiAgKm51bUNoYW5uZWxzID0gbnVtU2JyQ2hhbm5lbHM7CiAgKnNhbXBsZVJhdGUgPSBzZWxmLT5zYW1wbGVSYXRlT3V0OwogICpwc0RlY29kZWQgPSAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfUFNfREVDT0RFRCkgPyAxIDogMDsKCgoKYmFpbDoKCiAgcmV0dXJuIGVycm9yU3RhdHVzOwp9CgoKU0JSX0VSUk9SIHNickRlY29kZXJfQ2xvc2UgKCBIQU5ETEVfU0JSREVDT0RFUiAqcFNlbGYgKQp7CiAgSEFORExFX1NCUkRFQ09ERVIgc2VsZiA9ICpwU2VsZjsKICBpbnQgaTsKCiAgaWYgKHNlbGYgIT0gTlVMTCkKICB7CiAgICBpZiAoc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMgIT0gTlVMTCkgewogICAgICBEZWxldGVQc0RlYyAoICZzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYyApOwogICAgfQoKICAgIGlmIChzZWxmLT53b3JrQnVmZmVyMSAhPSBOVUxMKSB7CiAgICAgIEZyZWVSYW1fU2JyRGVjV29ya0J1ZmZlcjEoJnNlbGYtPndvcmtCdWZmZXIxKTsKICAgIH0KICAgIGlmIChzZWxmLT53b3JrQnVmZmVyMiAhPSBOVUxMKSB7CiAgICAgIEZyZWVSYW1fU2JyRGVjV29ya0J1ZmZlcjIoJnNlbGYtPndvcmtCdWZmZXIyKTsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgKDQpOyBpKyspIHsKICAgICAgc2JyRGVjb2Rlcl9EZXN0cm95RWxlbWVudCggc2VsZiwgaSApOwogICAgfQoKICAgIEZyZWVSYW1fU2JyRGVjb2RlcihwU2VsZik7CiAgfQoKICByZXR1cm4gU0JSREVDX09LOwp9CgoKSU5UIHNickRlY29kZXJfR2V0TGliSW5mbyggTElCX0lORk8gKmluZm8gKQp7CiAgaW50IGk7CgogIGlmIChpbmZvID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CgogIC8qIHNlYXJjaCBmb3IgbmV4dCBmcmVlIHRhYiAqLwogIGZvciAoaSA9IDA7IGkgPCBGREtfTU9EVUxFX0xBU1Q7IGkrKykgewogICAgaWYgKGluZm9baV0ubW9kdWxlX2lkID09IEZES19OT05FKQogICAgICBicmVhazsKICB9CiAgaWYgKGkgPT0gRkRLX01PRFVMRV9MQVNUKQogICAgcmV0dXJuIC0xOwogIGluZm8gKz0gaTsKCiAgaW5mby0+bW9kdWxlX2lkID0gRkRLX1NCUkRFQzsKICBpbmZvLT52ZXJzaW9uID0gTElCX1ZFUlNJT04oU0JSREVDT0RFUl9MSUJfVkwwLCBTQlJERUNPREVSX0xJQl9WTDEsIFNCUkRFQ09ERVJfTElCX1ZMMik7CiAgTElCX1ZFUlNJT05fU1RSSU5HKGluZm8pOwogIGluZm8tPmJ1aWxkX2RhdGUgPSAoY2hhciAqKVNCUkRFQ09ERVJfTElCX0JVSUxEX0RBVEU7CiAgaW5mby0+YnVpbGRfdGltZSA9IChjaGFyICopU0JSREVDT0RFUl9MSUJfQlVJTERfVElNRTsKICBpbmZvLT50aXRsZSAgICAgID0gKGNoYXIgKilTQlJERUNPREVSX0xJQl9USVRMRTsKCiAgLyogU2V0IGZsYWdzICovCiAgaW5mby0+ZmxhZ3MgPSAwCiAgICB8IENBUEZfU0JSX0hRCiAgICB8IENBUEZfU0JSX0xQCiAgICB8IENBUEZfU0JSX1BTX01QRUcKICAgIHwgQ0FQRl9TQlJfQ09OQ0VBTE1FTlQKICAgIHwgQ0FQRl9TQlJfRFJDCiAgICAgIDsKICAvKiBFbmQgb2YgZmxhZ3MgKi8KCiAgcmV0dXJuIDA7Cn0KCg==