Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBNUEVHLTQgSEUtQUFDIEVuY29kZXIgKioqKioqKioqKioqKioqKioqKioqKioqKgoKICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gTG9od2Fzc2VyCiAgY29udGVudHMvZGVzY3JpcHRpb246IEZESyBIRS1BQUMgRW5jb2RlciBpbnRlcmZhY2UgbGlicmFyeSBmdW5jdGlvbnMKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jX2xpYi5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCiNpbmNsdWRlICJhYWNlbmMuaCIKCiNpbmNsdWRlICJhYWNFbmNfcmFtLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbmluZyBpbmZvICovCgovKiBFbmNvZGVyIGxpYnJhcnkgaW5mbyAqLwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX1ZMMCAzCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfVkwxIDQKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9WTDIgMjIKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9USVRMRSAiQUFDIEVuY29kZXIiCiNpZmRlZiBfX0FORFJPSURfXwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX0JVSUxEX0RBVEUgIiIKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9CVUlMRF9USU1FICIiCiNlbHNlCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfQlVJTERfREFURSBfX0RBVEVfXwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX0JVSUxEX1RJTUUgX19USU1FX18KI2VuZGlmCgoKI2luY2x1ZGUgInNicl9lbmNvZGVyLmgiCiNpbmNsdWRlICIuLi9zcmMvc2JyX3JhbS5oIgojaW5jbHVkZSAiY2hhbm5lbF9tYXAuaCIKCiNpbmNsdWRlICJwc3lfY29uc3QuaCIKI2luY2x1ZGUgImJpdGVuYy5oIgoKI2luY2x1ZGUgInRwZW5jX2xpYi5oIgoKI2luY2x1ZGUgIm1ldGFkYXRhX21haW4uaCIKCiNkZWZpbmUgU0JMKGZsKSAgICAgICAgICAgIChmbC84KSAgICAgICAgICAgICAgICAgLyohPCBTaG9ydCBibG9jayBsZW5ndGggKGhhcmRjb2RlZCB0byA4IHNob3J0IGJsb2NrcyBwZXIgbG9uZyBibG9jaykgKi8KI2RlZmluZSBCU0xBKGZsKSAgICAgICAgICAgKDQqU0JMKGZsKStTQkwoZmwpLzIpICAvKiE8IEFBQyBibG9jayBzd2l0Y2hpbmcgbG9vay1haGVhZCAqLwojZGVmaW5lIERFTEFZX0FBQyhmbCkgICAgICAoZmwrQlNMQShmbCkpICAgICAgICAgIC8qITwgTURDVCArIGJsb2Nrc3dpdGNoaW5nICovCiNkZWZpbmUgREVMQVlfQUFDRUxEKGZsKSAgICgoZmwpLzIpICAgICAgICAgICAgICAgLyohPCBFTEQgRkIgZGVsYXkgKG5vIGZyYW1pbmcgZGVsYXkgaW5jbHVkZWQpICovCgojZGVmaW5lIElOUFVUQlVGRkVSX1NJWkUgKDE1MzcrMTAwKzIwNDgpCgojZGVmaW5lIERFRkFVTFRfSEVBREVSX1BFUklPRF9SRVBFVElUSU9OX1JBVEUgIDEwIC8qITwgRGVmYXVsdCBoZWFkZXIgcmVwZXRpdGlvbiByYXRlIHVzZWQgaW4gdHJhbnNwb3J0IGxpYnJhcnkgYW5kIGZvciBTQlIgaGVhZGVyLiAqLwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8qKgogKiBGbGFncyB0byBjaGFyYWN0ZXJpemUgZW5jb2RlciBtb2R1bGVzIHRvIGJlIHN1cHBvcnRlZCBpbiBwcmVzZW50IGluc3RhbmNlLgogKi8KZW51bSB7CiAgICBFTkNfTU9ERV9GTEFHX0FBQyAgPSAweDAwMDEsCiAgICBFTkNfTU9ERV9GTEFHX1NCUiAgPSAweDAwMDIsCiAgICBFTkNfTU9ERV9GTEFHX1BTICAgPSAweDAwMDQsCiAgICBFTkNfTU9ERV9GTEFHX1NBQyAgPSAweDAwMDgsCiAgICBFTkNfTU9ERV9GTEFHX01FVEEgPSAweDAwMTAKfTsKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwp0eXBlZGVmIHN0cnVjdCB7CiAgICBBVURJT19PQkpFQ1RfVFlQRSB1c2VyQU9UOyAgICAgICAgICAgICAgIC8qITwgQXVkaW8gT2JqZWN0IFR5cGUuICAgICAgICAgICAgICovCiAgICBVSU5UICAgICAgICAgICAgICB1c2VyU2FtcGxlcmF0ZTsgICAgICAgIC8qITwgU2FtcGxpbmcgZnJlcXVlbmN5LiAgICAgICAgICAgICovCiAgICBVSU5UICAgICAgICAgICAgICBuQ2hhbm5lbHM7ICAgICAgICAgICAgIC8qITwgd2lsbCBiZSBzZXQgdmlhIGNoYW5uZWxNb2RlLiAgICovCiAgICBDSEFOTkVMX01PREUgICAgICB1c2VyQ2hhbm5lbE1vZGU7CiAgICBVSU5UICAgICAgICAgICAgICB1c2VyQml0cmF0ZTsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJCaXRyYXRlTW9kZTsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJCYW5kd2lkdGg7CiAgICBVSU5UICAgICAgICAgICAgICB1c2VyQWZ0ZXJidXJuZXI7CiAgICBVSU5UICAgICAgICAgICAgICB1c2VyRnJhbWVsZW5ndGg7CiAgICBVSU5UICAgICAgICAgICAgICB1c2VyQW5jRGF0YVJhdGU7CiAgICBVSU5UICAgICAgICAgICAgICB1c2VyUGVha0JpdHJhdGU7CgogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRuczsgICAgICAgICAgICAgICAvKiE8IFVzZSBUTlMgY29kaW5nLiAqLwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclBuczsgICAgICAgICAgICAgICAvKiE8IFVzZSBQTlMgY29kaW5nLiAqLwogICAgVUNIQVIgICAgICAgICAgICAgdXNlckludGVuc2l0eTsgICAgICAgICAvKiE8IFVzZSBJbnRlbnNpdHkgY29kaW5nLiAqLwoKICAgIFRSQU5TUE9SVF9UWVBFICAgIHVzZXJUcFR5cGU7ICAgICAgICAgICAgLyohPCBUcmFuc3BvcnQgdHlwZSAqLwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwU2lnbmFsaW5nOyAgICAgICAvKiE8IEV4dGVuc2lvbiBBT1Qgc2lnbmFsaW5nIG1vZGUuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBOc3ViRnJhbWVzOyAgICAgIC8qITwgTnVtYmVyIG9mIHN1YiBmcmFtZXMgaW4gYSB0cmFuc3BvcnQgZnJhbWUgZm9yIExPQVMvTEFUTSBvciBBRFRTIChkZWZhdWx0IDEpLiAqLwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwQW14djsgICAgICAgICAgICAvKiE8IEF1ZGlvTXV4VmVyc2lvbiB0byBiZSB1c2VkIGZvciBMQVRNIChkZWZhdWx0IDApLiAqLwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwUHJvdGVjdGlvbjsKICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJUcEhlYWRlclBlcmlvZDsgICAgLyohPCBQYXJhbWV0ZXIgdXNlZCB0byBjb25maWd1cmUgTEFUTS9MT0FTIFNNQyByYXRlLiBNb3Jlb3ZlciB0aGlzIHBhcmFtZXRlcnMgaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIHRvIGNvbmZpZ3VyZSByZXBldGl0aW9uIHJhdGUgb2YgUENFIGluIHJhd19kYXRhX2Jsb2NrLiAqLwoKICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJFclRvb2xzOyAgICAgICAgICAgLyohPCBVc2UgVkNCMTEsIEhDUiBhbmQvb3IgUlZMQyBFUiB0b29sLiAqLwogICAgVUlOVCAgICAgICAgICAgICAgdXNlclBjZUFkZGl0aW9uczsgICAgICAvKiE8IENvbmZpZ3VyZSBhZGRpdGlvbmFsIGJpdHMgaW4gUENFLiAqLwoKICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJNZXRhRGF0YU1vZGU7ICAgICAgLyohPCBNZXRhIGRhdGEgbGlicmFyeSBjb25maWd1cmF0aW9uLiAqLwoKICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJTYnJFbmFibGVkOyAgICAgICAgLyohPCBFbmFibGUgU0JSIGZvciBFTEQuICovCiAgICBVSU5UICAgICAgICAgICAgICB1c2VyU2JyUmF0aW87ICAgICAgICAgIC8qITwgU0JSIHNhbXBsaW5nIHJhdGUgcmF0aW8uIER1YWwtIG9yIHNpbmdsZS1yYXRlLiAqLwoKfSBVU0VSX1BBUkFNOwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJ1Y3R1cmUgRGVmaW5pdGlvbnMKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnR5cGVkZWYgc3RydWN0ICBBQUNFTkNfQ09ORklHICAgICAqSEFORExFX0FBQ0VOQ19DT05GSUc7CgoKc3RydWN0IEFBQ0VOQ09ERVIKewogICAgVVNFUl9QQVJBTSAgICAgICAgICAgICAgIGV4dFBhcmFtOwogICAgQ09ERVJfQ09ORklHICAgICAgICAgICAgIGNvZGVyQ29uZmlnOwoKICAgIC8qIEFBQyAqLwogICAgQUFDRU5DX0NPTkZJRyAgICAgICAgICAgIGFhY0NvbmZpZzsKICAgIEhBTkRMRV9BQUNfRU5DICAgICAgICAgICBoQWFjRW5jOwoKICAgIC8qIFNCUiAqLwogICAgSEFORExFX1NCUl9FTkNPREVSICAgICAgIGhFbnZFbmM7CgogICAgLyogTWV0YSBEYXRhICovCiAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgIGhNZXRhZGF0YUVuYzsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YURhdGFBbGxvd2VkOyAvKiBTaWduYWwgd2hldGhlciBjaG9zZW4gY29uZmlndXJhdGlvbiBhbGxvd3MgbWV0YWRhdGEuIE5lY2Vzc2FyeSBmb3IgZGVsYXkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wZW5zYXRpb24uIE1ldGFkYXRhIG1vZGUgaXMgYSBzZXBhcmF0ZSBwYXJhbWV0ZXIuICovCgogICAgLyogVHJhbnNwb3J0ICovCiAgICBIQU5ETEVfVFJBTlNQT1JURU5DICAgICAgaFRwRW5jOwoKICAgIC8qIE91dHB1dCAqLwogICAgVUNIQVIgICAgICAgICAgICAgICAgICAgKm91dEJ1ZmZlcjsgICAgICAgICAvKiBJbnRlcm5hbCBiaXRzdHJlYW0gYnVmZmVyICovCiAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgb3V0QnVmZmVySW5CeXRlczsgICAvKiBTaXplIG9mIGludGVybmFsIGJpdHN0cmVhbSBidWZmZXIqLwoKICAgIC8qIElucHV0ICovCiAgICBJTlRfUENNICAgICAgICAgICAgICAgICAqaW5wdXRCdWZmZXI7ICAgICAgICAvKiBJbnRlcm5hbCBpbnB1dCBidWZmZXIuIElucHV0IHNvdXJjZSBmb3IgQUFDIGVuY29kZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBpbnB1dEJ1ZmZlck9mZnNldDsgIC8qIFdoZXJlIHRvIHdyaXRlIG5ldyBpbnB1dCBzYW1wbGVzLiAqLwoKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlc1RvUmVhZDsgICAgLyogbnVtYmVyIG9mIGlucHV0IHNhbXBsZXMgbmVlZWRlZCBmb3IgZW5jb2Rpbmcgb25lIGZyYW1lICovCiAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgblNhbXBsZXNSZWFkOyAgICAgIC8qIG51bWJlciBvZiBpbnB1dCBzYW1wbGVzIGFscmVhZHkgaW4gaW5wdXQgYnVmZmVyICovCiAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgblplcm9zQXBwZW5kZWQ7ICAgIC8qIGFwcGVuZGVkIHplcm9zIGF0IGVuZCBvZiBmaWxlKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuRGVsYXk7ICAgICAgICAgICAgLyogZW5jb2RlciBkZWxheSAqLwoKICAgIEFBQ0VOQ19FWFRfUEFZTE9BRCAgICAgICBleHRQYXlsb2FkIFtNQVhfVE9UQUxfRVhUX1BBWUxPQURTXTsKICAgIC8qIEV4dGVuc2lvbiBwYXlsb2FkICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgZXh0UGF5bG9hZERhdGEgWygxKV1bKDgpXVtNQVhfUEFZTE9BRF9TSVpFXTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICBleHRQYXlsb2FkU2l6ZSBbKDEpXVsoOCldOyAvKiBwYXlsb2FkIHNpemVzIGluIGJpdHMgKi8KCiAgICBVTE9ORyAgICAgICAgICAgICAgICAgICAgSW5pdEZsYWdzOyAgICAgICAgIC8qIGludGVybmFsIHN0YXR1cyB0byB0cmVnZ2llciByZS1pbml0aWFsaXphdGlvbiAqLwoKCiAgIC8qIE1lbW9yeSBhbGxvY2F0aW9uIGluZm8uICovCiAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbk1heEFhY0VsZW1lbnRzOwogICBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5NYXhBYWNDaGFubmVsczsKICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4U2JyRWxlbWVudHM7CiAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbk1heFNickNoYW5uZWxzOwogICBVSU5UICAgICAgICAgICAgICAgICAgICAgIG5NYXhTdWJGcmFtZXM7CgogICBVSU5UICAgICAgICAgICAgICAgICAgICAgIGVuY29kZXJfbW9kaXM7CgogICAvKiBDYXBhYmlsaXR5IGZsYWdzICovCiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgQ0FQRl90cEVuYzsKCn0gOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgVUxPTkcgICAgICAgICAgICAgICBzYW1wbGluZ1JhdGU7ICAgLyohPCBFbmNvZGVyIG91dHB1dCBzYW1wbGluZyByYXRlLiAqLwogICAgVUxPTkcgICAgICAgICAgICAgICBiaXRyYXRlUmFuZ2U7ICAgLyohPCBMb3dlciBiaXRyYXRlIHJhbmdlIGZvciBjb25maWcgZW50cnkuICovCgogICAgVUNIQVIgICAgICAgICAgICAgICBsb3dEZWxheVNicjsgICAgLyohPCAwOiBFTEQgc2JyIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTogRUxEIHNiciBvbiAqLwoKICAgIFVDSEFSICAgICAgICAgICAgICAgZG93bnNhbXBsZWRTYnI7IC8qITwgMDogRUxEIHdpdGggZHVhbHJhdGUgc2JyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOiBFTEQgd2l0aCBkb3duc2FtcGxlZCBzYnIgKi8KCn0gRUxEX1NCUl9DT05GSUdVUkFUT1I7CgovKioKICogXGJyaWVmICBUaGlzIHRhYmxlIGRlZmluZXMgRUxEL1NCUiBkZWZhdWx0IGNvbmZpZ3VyYXRpb25zLgogKi8Kc3RhdGljIGNvbnN0IEVMRF9TQlJfQ09ORklHVVJBVE9SIGVsZFNickF1dG9Db25maWdUYWJbXSA9CnsKICB7IDQ4MDAwLCAgICAgMCwgMSwgMCB9LAogIHsgNDgwMDAsIDY0MDAxLCAwLCAwIH0sCgogIHsgNDQxMDAsICAgICAwLCAxLCAwIH0sCiAgeyA0NDEwMCwgNjQwMDEsIDAsIDAgfSwKCiAgeyAzMjAwMCwgICAgIDAsIDEsIDAgfSwKICB7IDMyMDAwLCAyODAwMCwgMSwgMSB9LAogIHsgMzIwMDAsIDU2MDAwLCAwLCAwIH0sCgogIHsgMjQwMDAsICAgICAwLCAxLCAxIH0sCiAgeyAyNDAwMCwgNDAwMDAsIDAsIDAgfSwKCiAgeyAxNjAwMCwgICAgIDAsIDEsIDEgfSwKICB7IDE2MDAwLCAyODAwMCwgMCwgMCB9Cgp9OwoKLyoKICogXGJyaWVmICBDb25maWd1cmUgU0JSIGZvciBFTEQgY29uZmlndXJhdGlvbi4KICoKICogVGhpcyBmdW5jdGlvbiBmaW5kcyBkZWZhdWx0IFNCUiBjb25maWd1cmF0aW9uIGZvciBFTEQgYmFzZWQgb24gc2FtcGxpbmcgcmF0ZSBhbmQgY2hhbm5lbCBiaXRyYXRlLgogKiBPdXRwdXRwYXJhbWV0ZXJzIGFyZSBTQlIgb24vb2ZmLCBhbmQgU0JSIHJhdGlvLgogKgogKiBccGFyYW0gc2FtcGxpbmdSYXRlICAgICAgICAgIEF1ZGlvIHNpZ25hbCBzYW1wbGluZyByYXRlLgogKiBccGFyYW0gY2hhbm5lbE1vZGUgICAgICAgICAgIENoYW5uZWwgY29uZmlndXJhdGlvbiB0byBiZSB1c2VkLgogKiBccGFyYW0gdG90YWxCaXRyYXRlICAgICAgICAgIE92ZXJhbGwgYml0cmF0ZS4KICogXHBhcmFtIGVsZFNiciAgICAgICAgICAgICAgICBQb2ludGVyIHRvIGVsZFNiciBwYXJhbWV0ZXIsIGZpbGxlZCBvbiByZXR1cm4uCiAqIFxwYXJhbSBlbGRTYnJSYXRpbyAgICAgICAgICAgUG9pbnRlciB0byBlbGRTYnJSYXRpbyBwYXJhbWV0ZXIsIGZpbGxlZCBvbiByZXR1cm4uCiAqCiAqIFxyZXR1cm4gLSBBQUNFTkNfT0ssIGFsbCBmaW5lLgogKiAgICAgICAgIC0gQUFDRU5DX0lOVkFMSURfQ09ORklHLCBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIEFBQ0VOQ19FUlJPUiBlbGRTYnJDb25maWd1cmF0b3IoCiAgICAgICAgY29uc3QgVUxPTkcgICAgICAgICAgICAgICAgICAgICAgc2FtcGxpbmdSYXRlLAogICAgICAgIGNvbnN0IENIQU5ORUxfTU9ERSAgICAgICAgICAgICAgIGNoYW5uZWxNb2RlLAogICAgICAgIGNvbnN0IFVMT05HICAgICAgICAgICAgICAgICAgICAgIHRvdGFsQml0cmF0ZSwKICAgICAgICBVSU5UICogY29uc3QgICAgICAgICAgICAgICAgICAgICBlbGRTYnIsCiAgICAgICAgVUlOVCAqIGNvbnN0ICAgICAgICAgICAgICAgICAgICAgZWxkU2JyUmF0aW8KICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CiAgICBpbnQgaSwgY2ZnSWR4ID0gLTE7CiAgICBjb25zdCBVTE9ORyBjaGFubmVsQml0cmF0ZSA9IHRvdGFsQml0cmF0ZSAvIEZES2FhY0VuY19HZXRDaGFubmVsTW9kZUNvbmZpZ3VyYXRpb24oY2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmY7CgogICAgZm9yIChpPTA7IGk8KGludCkoc2l6ZW9mKGVsZFNickF1dG9Db25maWdUYWIpL3NpemVvZihFTERfU0JSX0NPTkZJR1VSQVRPUikpOyBpKyspIHsKICAgICAgaWYgKCAoc2FtcGxpbmdSYXRlIDw9IGVsZFNickF1dG9Db25maWdUYWJbaV0uc2FtcGxpbmdSYXRlKQogICAgICAgICYmIChjaGFubmVsQml0cmF0ZSA+PSBlbGRTYnJBdXRvQ29uZmlnVGFiW2ldLmJpdHJhdGVSYW5nZSkgKQogICAgICB7CiAgICAgICAgY2ZnSWR4ID0gaTsKICAgICAgfQogICAgfQoKICAgIGlmIChjZmdJZHggIT0gLTEpIHsKICAgICAgKmVsZFNiciAgICAgID0gKGVsZFNickF1dG9Db25maWdUYWJbY2ZnSWR4XS5sb3dEZWxheVNicj09MCkgPyAwIDogMTsKICAgICAgKmVsZFNiclJhdGlvID0gKGVsZFNickF1dG9Db25maWdUYWJbY2ZnSWR4XS5kb3duc2FtcGxlZFNicj09MCkgPyAyIDogMTsKICAgIH0KICAgIGVsc2UgewogICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7IC8qIG5vIGRlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgZWxkLXNiciBhdmFpbGFibGUuICovCiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKc3RhdGljIGlubGluZSBJTlQgaXNTYnJBY3RpdmUoY29uc3QgSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZykKewogICAgSU5UIHNiclVzZWQgPSAwOwoKICAgIGlmICggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUikgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKSApCiAgICB7CiAgICAgICAgc2JyVXNlZCA9IDE7CiAgICB9CiAgICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEICYmIChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX1NCUl9QUkVTRU5UKSkKICAgIHsKICAgICAgICBzYnJVc2VkID0gMTsKICAgIH0KCiAgICByZXR1cm4gKCBzYnJVc2VkICk7Cn0KCnN0YXRpYyBpbmxpbmUgSU5UIGlzUHNBY3RpdmUoY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgYXVkaW9PYmplY3RUeXBlKQp7CiAgICBJTlQgcHNVc2VkID0gMDsKCiAgICBpZiAoIChhdWRpb09iamVjdFR5cGU9PUFPVF9QUykgKQogICAgewogICAgICAgIHBzVXNlZCA9IDE7CiAgICB9CgogICAgcmV0dXJuICggcHNVc2VkICk7Cn0KCnN0YXRpYyBTQlJfUFNfU0lHTkFMSU5HIGdldFNiclNpZ25hbGluZ01vZGUoCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgICAgICAgICAgYXVkaW9PYmplY3RUeXBlLAogICAgICAgIGNvbnN0IFRSQU5TUE9SVF9UWVBFICAgICAgICAgICAgIHRyYW5zcG9ydFR5cGUsCiAgICAgICAgY29uc3QgVUNIQVIgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0U2lnbmFsaW5nLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHNiclJhdGlvCiAgICAgICAgKQoKewogIFNCUl9QU19TSUdOQUxJTkcgc2JyU2lnbmFsaW5nOwoKICBpZiAodHJhbnNwb3J0VHlwZT09VFRfVU5LTk9XTiB8fCBzYnJSYXRpbz09MCkgewogICAgc2JyU2lnbmFsaW5nID0gU0lHX1VOS05PV047IC8qIE5lZWRlZCBwYXJhbWV0ZXJzIGhhdmUgbm90IGJlZW4gc2V0ICovCiAgICByZXR1cm4gc2JyU2lnbmFsaW5nOwogIH0gZWxzZSB7CiAgICBzYnJTaWduYWxpbmcgPSBTSUdfSU1QTElDSVQ7IC8qIGRlZmF1bHQ6IGltcGxpY2l0IHNpZ25hbGluZyAqLwogIH0KCiAgaWYgKCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfQUFDX0xDKSB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfU0JSKSB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfUFMpICkgewogICAgc3dpdGNoICh0cmFuc3BvcnRUeXBlKSB7CiAgICAgIGNhc2UgVFRfTVA0X0FESUY6CiAgICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0lNUExJQ0lUOyAvKiBGb3IgTVBFRy0yIHRyYW5zcG9ydCB0eXBlcywgb25seSBpbXBsaWNpdCBzaWduYWxpbmcgaXMgcG9zc2libGUgKi8KICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgVFRfTVA0X1JBVzoKICAgICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKCB0cmFuc3BvcnRTaWduYWxpbmc9PTB4RkYgKSB7CiAgICAgICAgICAvKiBEZWZhdWx0cyAqLwogICAgICAgICAgaWYgKCBzYnJSYXRpbz09MSApIHsKICAgICAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0VYUExJQ0lUX0hJRVJBUkNISUNBTDsgLyogRm9yIGRvd25zYW1wbGVkIFNCUiwgZXhwbGljaXQgc2lnbmFsaW5nIGlzIG1hbmRhdG9yeSAqLwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0lNUExJQ0lUOyAvKiBGb3IgZHVhbC1yYXRlIFNCUiwgaW1wbGljaXQgc2lnbmFsaW5nIGlzIGRlZmF1bHQgKi8KICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogVXNlciBzZXQgcGFyYW1ldGVycyAqLwogICAgICAgICAgLyogQXR0ZW50aW9uOiBCYWNrd2FyZCBjb21wYXRpYmxlIGV4cGxpY2l0IHNpZ25hbGluZyBkb2VzIG9ubHkgd29yayB3aXRoIEFNVjEgZm9yIExBVE0vTE9BUyAqLwogICAgICAgICAgc2JyU2lnbmFsaW5nID0gKFNCUl9QU19TSUdOQUxJTkcpdHJhbnNwb3J0U2lnbmFsaW5nOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICB9CgogIHJldHVybiBzYnJTaWduYWxpbmc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGxvY2F0ZSBFbmNvZGVyCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpIX0FMTE9DX01FTSAoX0FhY0VuY29kZXIsIEFBQ0VOQ09ERVIpCkNfQUxMT0NfTUVNIChfQWFjRW5jb2RlciwgQUFDRU5DT0RFUiwgMSkKCgoKCi8qCiAqIE1hcCBFbmNvZGVyIHNwZWNpZmljIGNvbmZpZyBzdHJ1Y3R1cmVzIHRvIENPREVSX0NPTkZJRy4KICovCnN0YXRpYyB2b2lkIEZES2FhY0VuY19NYXBDb25maWcoCiAgICAgICAgQ09ERVJfQ09ORklHICpjb25zdCAgICAgICAgICAgICAgY2MsCiAgICAgICAgY29uc3QgVVNFUl9QQVJBTSAqY29uc3QgICAgICAgICAgZXh0Q2ZnLAogICAgICAgIGNvbnN0IFNCUl9QU19TSUdOQUxJTkcgICAgICAgICAgIHNiclNpZ25hbGluZywKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DX0NPTkZJRyAgICAgICBoQWFjQ29uZmlnCiAgICAgICAgKQp7CiAgQVVESU9fT0JKRUNUX1RZUEUgdHJhbnNwb3J0X0FPVCA9IEFPVF9OVUxMX09CSkVDVDsKICBGREttZW1jbGVhcihjYywgc2l6ZW9mKENPREVSX0NPTkZJRykpOwoKICBjYy0+ZmxhZ3MgPSAwOwoKICB0cmFuc3BvcnRfQU9UID0gaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlOwoKICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICBjYy0+ZmxhZ3MgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfU0JSX1BSRVNFTlQpID8gQ0NfU0JSIDogMDsKICB9CgogIC8qIHRyYW5zcG9ydCB0eXBlIGlzIHVzdWFsbHkgQUFDLUxDLiAqLwogIGlmICggKHRyYW5zcG9ydF9BT1QgPT0gQU9UX1NCUikgfHwgKHRyYW5zcG9ydF9BT1QgPT0gQU9UX1BTKSApIHsKICAgIGNjLT5hb3QgICAgICAgICAgID0gQU9UX0FBQ19MQzsKICB9CiAgZWxzZSB7CiAgICBjYy0+YW90ICAgICAgICAgICA9IHRyYW5zcG9ydF9BT1Q7CiAgfQoKICAvKiBDb25maWd1cmUgZXh0ZW5zaW9uIGFvdC4gKi8KICBpZiAoc2JyU2lnbmFsaW5nPT1TSUdfSU1QTElDSVQpIHsKICAgIGNjLT5leHRBT1QgPSBBT1RfTlVMTF9PQkpFQ1Q7ICAvKiBpbXBsaWNpdCAqLwogIH0KICBlbHNlIHsKICAgIGlmICggKHNiclNpZ25hbGluZz09U0lHX0VYUExJQ0lUX0JXX0NPTVBBVElCTEUpICYmICggKHRyYW5zcG9ydF9BT1Q9PUFPVF9TQlIpIHx8ICh0cmFuc3BvcnRfQU9UPT1BT1RfUFMpICkgKSB7CiAgICAgIGNjLT5leHRBT1QgPSBBT1RfU0JSOyAgICAgICAgLyogZXhwbGljaXQgYmFja3dhcmQgY29tcGF0aWJsZSAqLwogICAgfQogICAgZWxzZSB7CiAgICAgIGNjLT5leHRBT1QgPSB0cmFuc3BvcnRfQU9UOyAgLyogZXhwbGljaXQgaGllcmFyY2hpY2FsICovCiAgICB9CiAgfQoKICBpZiAoICh0cmFuc3BvcnRfQU9UPT1BT1RfU0JSKSB8fCAodHJhbnNwb3J0X0FPVD09QU9UX1BTKSApIHsKICAgIGNjLT5zYnJQcmVzZW50PTE7CiAgICBpZiAodHJhbnNwb3J0X0FPVD09QU9UX1BTKSB7CiAgICAgIGNjLT5wc1ByZXNlbnQ9MTsKICAgIH0KICB9CiAgY2MtPnNiclNpZ25hbGluZyAgICA9IHNiclNpZ25hbGluZzsKCiAgY2MtPmV4dFNhbXBsaW5nUmF0ZSA9IGV4dENmZy0+dXNlclNhbXBsZXJhdGU7CiAgY2MtPmJpdFJhdGUgICAgICAgICA9IGhBYWNDb25maWctPmJpdFJhdGU7CiAgY2MtPm5vQ2hhbm5lbHMgICAgICA9IGhBYWNDb25maWctPm5DaGFubmVsczsKICBjYy0+ZmxhZ3MgICAgICAgICAgfD0gQ0NfSVNfQkFTRUxBWUVSOwogIGNjLT5jaGFubmVsTW9kZSAgICAgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKCiAgY2MtPm5TdWJGcmFtZXMgPSAoaEFhY0NvbmZpZy0+blN1YkZyYW1lcyA+IDEgJiYgZXh0Q2ZnLT51c2VyVHBOc3ViRnJhbWVzID09IDEpCiAgICAgICAgICAgICAgICAgPyBoQWFjQ29uZmlnLT5uU3ViRnJhbWVzCiAgICAgICAgICAgICAgICAgOiBleHRDZmctPnVzZXJUcE5zdWJGcmFtZXM7CgogIGNjLT5mbGFncyAgICAgICAgICB8PSAoZXh0Q2ZnLT51c2VyVHBQcm90ZWN0aW9uKSA/IENDX1BST1RFQ1RJT04gOiAwOwoKICBpZiAoZXh0Q2ZnLT51c2VyVHBIZWFkZXJQZXJpb2QhPTB4RkYpIHsKICAgIGNjLT5oZWFkZXJQZXJpb2QgICAgPSBleHRDZmctPnVzZXJUcEhlYWRlclBlcmlvZDsKICB9CiAgZWxzZSB7IC8qIGF1dG8tbW9kZSAqLwogICAgc3dpdGNoIChleHRDZmctPnVzZXJUcFR5cGUpIHsKICAgICAgY2FzZSBUVF9NUDRfQURUUzoKICAgICAgY2FzZSBUVF9NUDRfTE9BUzoKICAgICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgICAgIGNjLT5oZWFkZXJQZXJpb2QgPSBERUZBVUxUX0hFQURFUl9QRVJJT0RfUkVQRVRJVElPTl9SQVRFOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGNjLT5oZWFkZXJQZXJpb2QgPSAwOwogICAgfQogIH0KCiAgY2MtPnNhbXBsZXNQZXJGcmFtZSA9IGhBYWNDb25maWctPmZyYW1lbGVuZ3RoOwogIGNjLT5zYW1wbGluZ1JhdGUgICAgPSBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwoKICAvKiBNcGVnLTQgc2lnbmFsaW5nIGZvciB0cmFuc3BvcnQgbGlicmFyeS4gKi8KICBjYy0+ZmxhZ3MgfD0gQ0NfTVBFR19JRDsKCiAgLyogRVItdG9vbHMgc2lnbmFsaW5nLiAqLwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpID8gQ0NfVkNCMTEgOiAwOwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSAgID8gQ0NfSENSIDogMDsKICBjYy0+ZmxhZ3MgICAgIHw9IChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX1JWTEMpICA/IENDX1JWTEMgOiAwOwoKICAvKiBNYXRyaXggbWl4ZG93biBjb2VmZmljaWVudCBjb25maWd1cmF0aW9uLiAqLwogIGlmICggKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucyYweDEpICYmIChoQWFjQ29uZmlnLT5lcENvbmZpZz09LTEpCiAgICAgICYmICgoY2MtPmNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yKXx8KGNjLT5jaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKQogIHsKICAgIGNjLT5tYXRyaXhNaXhkb3duQSAgICAgICA9ICgoZXh0Q2ZnLT51c2VyUGNlQWRkaXRpb25zPj4xKSYweDMpKzE7CiAgICBjYy0+ZmxhZ3MgfD0gKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucz4+MykmMHgxID8gQ0NfUFNFVURPX1NVUlJPVU5EIDogMDsKICB9CiAgZWxzZSB7CiAgICBjYy0+bWF0cml4TWl4ZG93bkEgPSAwOwogIH0KfQoKLyoKICogRXhhbWluZSBidWZmZXIgZGVzY3JpcHRvciByZWdhcmRpbmcgY2hvb3NlbiBpZGVudGlmaWVyLgogKgogKiBccGFyYW0gcEJ1ZkRlc2MgICAgICAgICAgICAgIFBvaW50ZXIgdG8gYnVmZmVyIGRlc2NyaXB0b3IKICogXHBhcmFtIGlkZW50aWZpZXIgICAgICAgICAgICBCdWZmZXIgaWRlbnRpZmllciB0byBsb29rIGZvci4KCiAqIFxyZXR1cm4gLSBCdWZmZXIgZGVzY3JpcHRvciBpbmRleC4KICogICAgICAgICAtMSwgaWYgdGhlcmUgaXMgbm8gZW50cnkgYXZhaWxhYmxlLgogKi8Kc3RhdGljIElOVCBnZXRCdWZEZXNjSWR4KAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZEZXNjICAgICAgICAgKnBCdWZEZXNjLAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZmZXJJZGVudGlmaWVyIGlkZW50aWZpZXIKKQp7CiAgICBJTlQgaSwgaWR4ID0gLTE7CgogICAgZm9yIChpPTA7IGk8cEJ1ZkRlc2MtPm51bUJ1ZnM7IGkrKykgewogICAgICBpZiAoIChBQUNFTkNfQnVmZmVySWRlbnRpZmllcilwQnVmRGVzYy0+YnVmZmVySWRlbnRpZmllcnNbaV0gPT0gaWRlbnRpZmllciApIHsKICAgICAgICBpZHggPSBpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaWR4Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbiBEZWNsYXJhdGlvbnMKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkFBQ19FTkNPREVSX0VSUk9SIGFhY0VuY0RlZmF1bHRDb25maWcoSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICpjb25maWcpCnsKICAgIC8qIG1ha2UgcmVhc29uYWJsZSBkZWZhdWx0IHNldHRpbmdzICovCiAgICBGREthYWNFbmNfQWFjSW5pdERlZmF1bHRDb25maWcgKGhBYWNDb25maWcpOwoKICAgIC8qIGNsZWFyIGNvbmZpZ3VyYXRpb24gc3RydWN0dXJlIGFuZCBjb3B5IGRlZmF1bHQgc2V0dGluZ3MgKi8KICAgIEZES21lbWNsZWFyKGNvbmZpZywgc2l6ZW9mKFVTRVJfUEFSQU0pKTsKCiAgICAvKiBjb3B5IGVuY29kZXIgY29uZmlndXJhdGlvbiBzZXR0aW5ncyAqLwogICAgY29uZmlnLT5uQ2hhbm5lbHMgICAgICAgPSBoQWFjQ29uZmlnLT5uQ2hhbm5lbHM7CiAgICBjb25maWctPnVzZXJBT1QgPSBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPSBBT1RfQUFDX0xDOwogICAgY29uZmlnLT51c2VyU2FtcGxlcmF0ZSAgPSBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwogICAgY29uZmlnLT51c2VyQ2hhbm5lbE1vZGUgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGUgICAgID0gaEFhY0NvbmZpZy0+Yml0UmF0ZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlID0gaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU7CiAgICBjb25maWctPnVzZXJQZWFrQml0cmF0ZSA9IChVSU5UKS0xOwogICAgY29uZmlnLT51c2VyQmFuZHdpZHRoICAgPSBoQWFjQ29uZmlnLT5iYW5kV2lkdGg7CiAgICBjb25maWctPnVzZXJUbnMgICAgICAgICA9IGhBYWNDb25maWctPnVzZVRuczsKICAgIGNvbmZpZy0+dXNlclBucyAgICAgICAgID0gaEFhY0NvbmZpZy0+dXNlUG5zOwogICAgY29uZmlnLT51c2VySW50ZW5zaXR5ICAgPSBoQWFjQ29uZmlnLT51c2VJUzsKICAgIGNvbmZpZy0+dXNlckFmdGVyYnVybmVyID0gaEFhY0NvbmZpZy0+dXNlUmVxdWFudDsKICAgIGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoID0gKFVJTlQpLTE7CgogICAgaWYgKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpIHsKICAgICAgY29uZmlnLT51c2VyRXJUb29scyAgfD0gMHgwMTsKICAgIH0KICAgIGlmIChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX0hDUikgewogICAgICBjb25maWctPnVzZXJFclRvb2xzICB8PSAweDAyOwogICAgfQoKICAgIC8qIGluaXRpYWxpemUgdHJhbnNwb3J0IHBhcmFtZXRlcnMgKi8KICAgIGNvbmZpZy0+dXNlclRwVHlwZSAgICAgICAgID0gVFRfVU5LTk9XTjsKICAgIGNvbmZpZy0+dXNlclRwQW14diAgICAgICAgID0gMDsKICAgIGNvbmZpZy0+dXNlclRwU2lnbmFsaW5nICAgID0gMHhGRjsgICAgLyogY2hvb3NlIHNpZ25hbGluZyBhdXRvbWF0aWNhbGx5ICovCiAgICBjb25maWctPnVzZXJUcE5zdWJGcmFtZXMgICA9IDE7CiAgICBjb25maWctPnVzZXJUcFByb3RlY3Rpb24gICA9IDA7ICAgIC8qIG5vdCBjcmMgcHJvdGVjdGVkKi8KICAgIGNvbmZpZy0+dXNlclRwSGVhZGVyUGVyaW9kID0gMHhGRjsgLyogaGVhZGVyIHBlcmlvZCBpbiBhdXRvIG1vZGUgKi8KICAgIGNvbmZpZy0+dXNlclBjZUFkZGl0aW9ucyAgID0gMDsgICAgLyogbm8gbWF0cml4IG1peGRvd24gY29lZmZpY2llbnQgKi8KICAgIGNvbmZpZy0+dXNlck1ldGFEYXRhTW9kZSAgID0gMDsgICAgLyogZG8gbm90IGVtYmVkIGFueSBtZXRhIGRhdGEgaW5mbyAqLwoKICAgIGNvbmZpZy0+dXNlckFuY0RhdGFSYXRlICAgID0gMDsKCiAgICAvKiBTQlIgcmF0ZSBpcyBzZXQgdG8gMCBoZXJlLCB3aGljaCBtZWFucyBpdCBzaG91bGQgYmUgc2V0IGF1dG9tYXRpY2FsbHkKICAgICAgIGluIEZES2FhY0VuY19BZGp1c3RFbmNTZXR0aW5ncygpIGlmIHRoZSB1c2VyIGRpZCBub3Qgc2V0IGEgcmF0ZQogICAgICAgZXhwaWxpY2l0ZWx5LiAqLwogICAgY29uZmlnLT51c2VyU2JyUmF0aW8gPSAwOwoKICAgIC8qIFNCUiBlbmFibGUgc2V0IHRvIC0xIG1lYW5zIHRvIGlucXVpcmUgRUxEIGF1ZGlvIGNvbmZpZ3VyYXRvciBmb3IgcmVhc29uYWJsZSBjb25maWd1cmF0aW9uLiAqLwogICAgY29uZmlnLT51c2VyU2JyRW5hYmxlZCAgICAgPSAtMTsKCiAgICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKc3RhdGljCnZvaWQgYWFjRW5jRGlzdHJpYnV0ZVNickJpdHMoQ0hBTk5FTF9NQVBQSU5HICpjaGFubmVsTWFwcGluZywgU0JSX0VMRU1FTlRfSU5GTyAqc2JyRWxJbmZvLCBJTlQgYml0UmF0ZSkKewogIElOVCBjb2RlYml0cyA9IGJpdFJhdGU7CiAgaW50IGVsOwoKICAvKiBDb3B5IEVsZW1lbnQgaW5mbyAqLwogIGZvciAoZWw9MDsgZWw8Y2hhbm5lbE1hcHBpbmctPm5FbGVtZW50czsgZWwrKykgewogICAgICBzYnJFbEluZm9bZWxdLkNoYW5uZWxJbmRleFswXSA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLkNoYW5uZWxJbmRleFswXTsKICAgICAgc2JyRWxJbmZvW2VsXS5DaGFubmVsSW5kZXhbMV0gPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5DaGFubmVsSW5kZXhbMV07CiAgICAgIHNickVsSW5mb1tlbF0uZWxUeXBlICAgICAgICAgID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0uZWxUeXBlOwogICAgICBzYnJFbEluZm9bZWxdLmJpdFJhdGUgICAgICAgICA9IChJTlQpKGZNdWx0Tm9ybShjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5yZWxhdGl2ZUJpdHMsIChGSVhQX0RCTCliaXRSYXRlKSk7CiAgICAgIHNickVsSW5mb1tlbF0uaW5zdGFuY2VUYWcgICAgID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0uaW5zdGFuY2VUYWc7CiAgICAgIHNickVsSW5mb1tlbF0ubkNoYW5uZWxzSW5FbCAgID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0ubkNoYW5uZWxzSW5FbDsKCiAgICAgIGNvZGViaXRzIC09IHNickVsSW5mb1tlbF0uYml0UmF0ZTsKICB9CiAgc2JyRWxJbmZvWzBdLmJpdFJhdGUgKz0gY29kZWJpdHM7Cn0KCgpzdGF0aWMKSU5UIGFhY0VuY29kZXJfTGltaXRCaXRyYXRlKAogICAgICAgIGNvbnN0IEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwRW5jLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGluZ1JhdGUsCiAgICAgICAgY29uc3QgSU5UIGZyYW1lTGVuZ3RoLAogICAgICAgIGNvbnN0IElOVCBuQ2hhbm5lbHMsCiAgICAgICAgY29uc3QgQ0hBTk5FTF9NT0RFIGNoYW5uZWxNb2RlLAogICAgICAgIElOVCBiaXRSYXRlLAogICAgICAgIGNvbnN0IElOVCBuU3ViRnJhbWVzLAogICAgICAgIGNvbnN0IElOVCBzYnJBY3RpdmUsCiAgICAgICAgY29uc3QgSU5UIHNickRvd25TYW1wbGVSYXRlLAogICAgICAgIGNvbnN0IEFVRElPX09CSkVDVF9UWVBFIGFvdAogICAgICAgICkKewogIElOVCBjb3JlU2FtcGxpbmdSYXRlOwogIENIQU5ORUxfTUFQUElORyBjbTsKCiAgRkRLYWFjRW5jX0luaXRDaGFubmVsTWFwcGluZyhjaGFubmVsTW9kZSwgQ0hfT1JERVJfTVBFRywgJmNtKTsKCiAgaWYgKHNickFjdGl2ZSkgewogICAgY29yZVNhbXBsaW5nUmF0ZSA9IHNhbXBsaW5nUmF0ZSA+PiAgKHNickVuY29kZXJfSXNTaW5nbGVSYXRlUG9zc2libGUoYW90KSA/IChzYnJEb3duU2FtcGxlUmF0ZS0xKToxKTsKICB9IGVsc2UgewogICAgY29yZVNhbXBsaW5nUmF0ZSA9IHNhbXBsaW5nUmF0ZTsKICB9CgogIC8qIENvbnNpZGVyIGJhbmR3aWR0aCBjaGFubmVsIGJpdCByYXRlIGxpbWl0IChzZWUgYmFuZHdpZHRoLmNwcDogR2V0QmFuZHdpZHRoRW50cnkoKSkgKi8KICBpZiAoYW90ID09IEFPVF9FUl9BQUNfTEQgfHwgYW90ID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICBiaXRSYXRlID0gRkRLbWluKDM2MDAwMCpuQ2hhbm5lbHMsIGJpdFJhdGUpOwogICAgYml0UmF0ZSA9IEZES21heCg4MDAwKm5DaGFubmVscywgYml0UmF0ZSk7CiAgfQoKICBpZiAoYW90ID09IEFPVF9BQUNfTEMgfHwgYW90ID09IEFPVF9TQlIgfHwgYW90ID09IEFPVF9QUykgIHsKICAgIGJpdFJhdGUgPSBGREttaW4oNTc2MDAwKm5DaGFubmVscywgYml0UmF0ZSk7CiAgICAvKmJpdFJhdGUgPSBGREttYXgoMCpuQ2hhbm5lbHMsIGJpdFJhdGUpOyovCiAgfQoKCiAgLyogTGltaXQgYml0IHJhdGUgaW4gcmVzcGVjdCB0byB0aGUgY29yZSBjb2RlciAqLwogIGJpdFJhdGUgPSBGREthYWNFbmNfTGltaXRCaXRyYXRlKAogICAgICAgICAgaFRwRW5jLAogICAgICAgICAgY29yZVNhbXBsaW5nUmF0ZSwKICAgICAgICAgIGZyYW1lTGVuZ3RoLAogICAgICAgICAgbkNoYW5uZWxzLAogICAgICAgICAgY20ubkNoYW5uZWxzRWZmLAogICAgICAgICAgYml0UmF0ZSwKICAgICAgICAgIC0xLAogICAgICAgICAgTlVMTCwKICAgICAgICAgIC0xLAogICAgICAgICAgblN1YkZyYW1lcwogICAgICAgICAgKTsKCiAgLyogTGltaXQgYml0IHJhdGUgaW4gcmVzcGVjdCB0byBhdmFpbGFibGUgU0JSIG1vZGVzIGlmIGFjdGl2ZSAqLwogIGlmIChzYnJBY3RpdmUpCiAgewogICAgaW50IG51bUl0ZXJhdGlvbnMgPSAwOwogICAgSU5UIGluaXRpYWxCaXRyYXRlLCBhZGp1c3RlZEJpdHJhdGU7CiAgICBpbml0aWFsQml0cmF0ZSA9IGFkanVzdGVkQml0cmF0ZSA9IGJpdFJhdGU7CgogICAgLyogRmluZCB0b3RhbCBiaXRyYXRlIHdoaWNoIHByb3ZpZGVzIHZhbGlkIGNvbmZpZ3VyYXRpb24gZm9yIGVhY2ggU0JSIGVsZW1lbnQuICovCiAgICBkbyB7CiAgICAgIGludCBlOwogICAgICBTQlJfRUxFTUVOVF9JTkZPIHNickVsSW5mb1soOCldOwogICAgICBGREtfQVNTRVJUKGNtLm5FbGVtZW50cyA8PSAoOCkpOwoKICAgICAgaW5pdGlhbEJpdHJhdGUgPSBhZGp1c3RlZEJpdHJhdGU7CgogICAgICAvKiBHZXQgYml0IHJhdGUgZm9yIGVhY2ggU0JSIGVsZW1lbnQgKi8KICAgICAgYWFjRW5jRGlzdHJpYnV0ZVNickJpdHMoJmNtLCBzYnJFbEluZm8sIGluaXRpYWxCaXRyYXRlKTsKCiAgICAgIGZvciAoZT0wOyBlPGNtLm5FbGVtZW50czsgZSsrKQogICAgICB7CiAgICAgICAgSU5UIHNickVsZW1lbnRCaXRSYXRlSW4sIHNickJpdFJhdGVPdXQ7CgogICAgICAgIGlmIChjbS5lbEluZm9bZV0uZWxUeXBlICE9IElEX1NDRSAmJiBjbS5lbEluZm9bZV0uZWxUeXBlICE9IElEX0NQRSkgewogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHNickVsZW1lbnRCaXRSYXRlSW4gPSBzYnJFbEluZm9bZV0uYml0UmF0ZTsKICAgICAgICBzYnJCaXRSYXRlT3V0ID0gc2JyRW5jb2Rlcl9MaW1pdEJpdFJhdGUoc2JyRWxlbWVudEJpdFJhdGVJbiAsIGNtLmVsSW5mb1tlXS5uQ2hhbm5lbHNJbkVsLCBjb3JlU2FtcGxpbmdSYXRlLCBhb3QpOwogICAgICAgIGlmIChzYnJCaXRSYXRlT3V0ID09IDApIHsKICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLyogSWYgYml0cmF0ZXMgZG9uJ3QgbWF0Y2gsIGRpc3RyaWJ1dGlvbiBhbmQgbGltaXRpbmcgbmVlZHMgdG8gYmUgZGV0ZXJtaW5lZCBhZ2Fpbi4KICAgICAgICAgICBBYm9ydCBlbGVtZW50IGxvb3AgYW5kIHJlc3RhcnQgd2l0aCBhZGFwdGVkIGJpdHJhdGUuICovCiAgICAgICAgaWYgKHNickVsZW1lbnRCaXRSYXRlSW4gIT0gc2JyQml0UmF0ZU91dCkgewoKICAgICAgICAgIGlmIChzYnJFbGVtZW50Qml0UmF0ZUluIDwgc2JyQml0UmF0ZU91dCkgewogICAgICAgICAgICBhZGp1c3RlZEJpdHJhdGUgPSBmTWF4KGluaXRpYWxCaXRyYXRlLCAoSU5UKWZEaXZOb3JtKChGSVhQX0RCTCkoc2JyQml0UmF0ZU91dCs4KSwgY20uZWxJbmZvW2VdLnJlbGF0aXZlQml0cykpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoc2JyRWxlbWVudEJpdFJhdGVJbiA+IHNickJpdFJhdGVPdXQpIHsKICAgICAgICAgICAgYWRqdXN0ZWRCaXRyYXRlID0gZk1pbihpbml0aWFsQml0cmF0ZSwgKElOVClmRGl2Tm9ybSgoRklYUF9EQkwpKHNickJpdFJhdGVPdXQtOCksIGNtLmVsSW5mb1tlXS5yZWxhdGl2ZUJpdHMpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CgogICAgICAgIH0gLyogc2JyRWxlbWVudEJpdFJhdGVJbiAhPSBzYnJCaXRSYXRlT3V0ICovCgogICAgICB9IC8qIGVsZW1lbnRzICovCgogICAgICBudW1JdGVyYXRpb25zKys7IC8qIHJlc3RyaWN0IGl0ZXJhdGlvbiB0byB3b3JzdCBjYXNlIG9mIG51bSBlbGVtZW50cyAqLwoKICAgIH0gd2hpbGUgKCAoaW5pdGlhbEJpdHJhdGUhPWFkanVzdGVkQml0cmF0ZSkgJiYgKG51bUl0ZXJhdGlvbnM8PWNtLm5FbGVtZW50cykgKTsKCiAgICAvKiBVbmVxdWFsIGJpdHJhdGVzIG1lYW4gdGhhdCBubyByZWFzb25hYmxlIGJpdHJhdGUgY29uZmlndXJhdGlvbiBmb3VuZC4gKi8KICAgIGJpdFJhdGUgPSAoaW5pdGlhbEJpdHJhdGU9PWFkanVzdGVkQml0cmF0ZSkgPyBhZGp1c3RlZEJpdHJhdGUgOiAwOwogIH0KCiAgRkRLX0FTU0VSVChiaXRSYXRlID4gMCk7CgogIHJldHVybiBiaXRSYXRlOwp9CgovKgogKiBcYnJpZWYgQ29uc2lzdGVuY3kgY2hlY2sgb2YgZ2l2ZW4gVVNFUl9QQVJBTSBzdHJ1Y3QgYW5kCiAqICAgY29weSBiYWNrIGNvbmZpZ3VyYXRpb24gZnJvbSBwdWJsaWMgc3RydWN0IGludG8gaW50ZXJuYWwKICogICBlbmNvZGVyIGNvbmZpZ3VyYXRpb24gc3RydWN0LgogKgogKiBcaEFhY0VuY29kZXIgSW50ZXJuYWwgZW5jb2RlciBjb25maWcgd2hpY2ggaXMgdG8gYmUgdXBkYXRlZAogKiBccGFyYW0gY29uZmlnIFVzZXIgcHJvdmlkZWQgY29uZmlnIChwdWJsaWMgc3RydWN0KQogKiBccmV0dXJuILRyZXR1cm5zIGFsd2F5cyBBQUNfRU5DX09LCiAqLwpzdGF0aWMKQUFDRU5DX0VSUk9SIEZES2FhY0VuY19BZGp1c3RFbmNTZXR0aW5ncyhIQU5ETEVfQUFDRU5DT0RFUiBoQWFjRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICpjb25maWcpCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgLyogR2V0IHN0cnVjdCBwb2ludGVycy4gKi8KICAgIEhBTkRMRV9BQUNFTkNfQ09ORklHICAgIGhBYWNDb25maWcgPSAmaEFhY0VuY29kZXItPmFhY0NvbmZpZzsKCiAgICBoQWFjQ29uZmlnLT5uQ2hhbm5lbHMgICAgICAgPSBjb25maWctPm5DaGFubmVsczsKCiAgICAvKiBFbmNvZGVyIHNldHRpbmdzIHVwZGF0ZS4gKi8KICAgIGhBYWNDb25maWctPnNhbXBsZVJhdGUgICAgICA9IGNvbmZpZy0+dXNlclNhbXBsZXJhdGU7CiAgICBoQWFjQ29uZmlnLT51c2VUbnMgICAgICAgICAgPSBjb25maWctPnVzZXJUbnM7CiAgICBoQWFjQ29uZmlnLT51c2VQbnMgICAgICAgICAgPSBjb25maWctPnVzZXJQbnM7CiAgICBoQWFjQ29uZmlnLT51c2VJUyAgICAgICAgICAgPSBjb25maWctPnVzZXJJbnRlbnNpdHk7CiAgICBoQWFjQ29uZmlnLT5iaXRSYXRlICAgICAgICAgPSBjb25maWctPnVzZXJCaXRyYXRlOwogICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgICAgID0gY29uZmlnLT51c2VyQ2hhbm5lbE1vZGU7CiAgICBoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZSAgICAgPSBjb25maWctPnVzZXJCaXRyYXRlTW9kZTsKICAgIGhBYWNDb25maWctPmJhbmRXaWR0aCAgICAgICA9IGNvbmZpZy0+dXNlckJhbmR3aWR0aDsKICAgIGhBYWNDb25maWctPnVzZVJlcXVhbnQgICAgICA9IGNvbmZpZy0+dXNlckFmdGVyYnVybmVyOwoKICAgIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9IGNvbmZpZy0+dXNlckFPVDsKICAgIGhBYWNDb25maWctPmFuY19SYXRlICAgICAgICA9IGNvbmZpZy0+dXNlckFuY0RhdGFSYXRlOwogICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgICAgID0gMDsKICAgIGhBYWNDb25maWctPmVwQ29uZmlnICAgICAgICA9IC0xOwoKICAgIGlmIChjb25maWctPnVzZXJUcFR5cGU9PVRUX01QNF9MQVRNX01DUDEgfHwgY29uZmlnLT51c2VyVHBUeXBlPT1UVF9NUDRfTEFUTV9NQ1AwIHx8IGNvbmZpZy0+dXNlclRwVHlwZT09VFRfTVA0X0xPQVMpIHsKICAgICAgaEFhY0NvbmZpZy0+YXVkaW9NdXhWZXJzaW9uID0gY29uZmlnLT51c2VyVHBBbXh2OwogICAgfQogICAgZWxzZSB7CiAgICAgIGhBYWNDb25maWctPmF1ZGlvTXV4VmVyc2lvbiA9IC0xOwogICAgfQoKICAgIC8qIEFkYXB0IGludGVybmFsIEFPVCB3aGVuIG5lY2Vzc2FyeS4gKi8KICAgIHN3aXRjaCAoIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSApIHsKICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICBjYXNlIEFPVF9TQlI6CiAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgICAgY29uZmlnLT51c2VyVHBUeXBlID0gKGNvbmZpZy0+dXNlclRwVHlwZSE9VFRfVU5LTk9XTikgPyBjb25maWctPnVzZXJUcFR5cGUgOiBUVF9NUDRfQURUUzsKICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoID0gKGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIT0oVUlOVCktMSkgPyBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA6IDEwMjQ7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gMTAyNCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgIGhBYWNDb25maWctPmVwQ29uZmlnID0gMDsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9IEFDX0VSfEFDX0xEOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgxKSA/IEFDX0VSX1ZDQjExIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDIpID8gQUNfRVJfSENSIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDQpID8gQUNfRVJfUlZMQyA6IDApOwogICAgICAgICAgY29uZmlnLT51c2VyVHBUeXBlID0gKGNvbmZpZy0+dXNlclRwVHlwZSE9VFRfVU5LTk9XTikgPyBjb25maWctPnVzZXJUcFR5cGUgOiBUVF9NUDRfTE9BUzsKICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoID0gKGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIT0oVUlOVCktMSkgPyBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA6IDUxMjsKICAgICAgICAgIGlmIChoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA1MTIgJiYgaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNDgwKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICAgIGhBYWNDb25maWctPmVwQ29uZmlnID0gMDsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9IEFDX0VSfEFDX0VMRDsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MSkgPyBBQ19FUl9WQ0IxMSA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgyKSA/IEFDX0VSX0hDUiA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHg0KSA/IEFDX0VSX1JWTEMgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyU2JyRW5hYmxlZD09MSkgID8gQUNfU0JSX1BSRVNFTlQgOiAwKTsKICAgICAgICAgIGNvbmZpZy0+dXNlclRwVHlwZSA9IChjb25maWctPnVzZXJUcFR5cGUhPVRUX1VOS05PV04pID8gY29uZmlnLT51c2VyVHBUeXBlIDogVFRfTVA0X0xPQVM7CiAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCA9IChjb25maWctPnVzZXJGcmFtZWxlbmd0aCE9KFVJTlQpLTEpID8gY29uZmlnLT51c2VyRnJhbWVsZW5ndGggOiA1MTI7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNTEyICYmIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDQ4MCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBzd2l0Y2ggKCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgKSB7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICBpZiAoY29uZmlnLT51c2VyQml0cmF0ZU1vZGU9PTApIHsKICAgICAgICAgIC8qIGJpdHJlc2Vydm9pciAgPSAobWF4Qml0UmVzLW1pbkJpdFJlcykvKG1heEJpdFJhdGUtbWluQml0cmF0ZSkqKGJpdFJhdGUtbWluQml0cmF0ZSkrbWluQml0UmVzOyAqLwogICAgICAgICAgaWYgKCBpc0xvd0RlbGF5KGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgKSB7CiAgICAgICAgICAgIElOVCBiaXRyZXNlcnZvaXI7CiAgICAgICAgICAgIElOVCBiclBlckNoYW5uZWwgPSBoQWFjQ29uZmlnLT5iaXRSYXRlL2hBYWNDb25maWctPm5DaGFubmVsczsKICAgICAgICAgICAgYnJQZXJDaGFubmVsICAgICA9IGZNaW4oQklUUkFURV9NQVhfTEQsIGZNYXgoQklUUkFURV9NSU5fTEQsIGJyUGVyQ2hhbm5lbCkpOwogICAgICAgICAgICBGSVhQX0RCTCBzbG9wZSAgID0gZkRpdk5vcm0oKGJyUGVyQ2hhbm5lbC1CSVRSQVRFX01JTl9MRCksIEJJVFJBVEVfTUFYX0xELUJJVFJBVEVfTUlOX0xEKTsgLyogY2FsYyBzbG9wZSBmb3IgaW50ZXJwb2xhdGlvbiAqLwogICAgICAgICAgICBiaXRyZXNlcnZvaXIgICAgID0gZk11bHRJKHNsb3BlLCAoSU5UKShCSVRSRVNfTUFYX0xELUJJVFJFU19NSU5fTEQpKSArIEJJVFJFU19NSU5fTEQ7IC8qIGludGVycG9sYXRlICovCiAgICAgICAgICAgIGhBYWNDb25maWctPmJpdHJlc2Vydm9pciA9IGJpdHJlc2Vydm9pciAmIH43OyAvKiBhbGlnbiB0byBieXRlcyAqLwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGUhPTApIHsKICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBjb25maWctPnVzZXJCaXRyYXRlOwoKICAgIC8qIGdldCBiaXRyYXRlIGluIFZCUiBjb25maWd1cmF0aW9uICovCiAgICBpZiAoIChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZT49MSkgJiYgKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPD01KSApIHsKICAgICAgICAvKiBJbiBWQlIgbW9kZTsgU0JSLW1vZHVsIGRlcGVuZHMgb24gYml0cmF0ZSwgY29yZSBlbmNvZGVyIG9uIGJpdHJhdGVNb2RlLiAqLwogICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBGREthYWNFbmNfR2V0VkJSQml0cmF0ZShoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZSwgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUpOwogICAgfQoKCgogICAgLyogU2V0IGRlZmF1bHQgYml0cmF0ZSBpZiBubyBleHRlcm5hbCBiaXRyYXRlIGRlY2xhcmVkLiAqLwogICAgaWYgKCAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU9PTApICYmIChjb25maWctPnVzZXJCaXRyYXRlPT0oVUlOVCktMSkgKSB7CiAgICAgICAgSU5UIGJpdHJhdGUgPSBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKGhBYWNDb25maWctPmNoYW5uZWxNb2RlKS0+bkNoYW5uZWxzRWZmICogaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZTsKCiAgICAgICAgaWYgKCBpc1BzQWN0aXZlKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgKSB7CiAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gKGJpdHJhdGU+PjEpOyAgICAgICAgICAgICAgICAgIC8qIDAuNSBiaXQgcGVyIHNhbXBsZSAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgKQogICAgICAgIHsKICAgICAgICAgIGlmICggKGNvbmZpZy0+dXNlclNiclJhdGlvPT0yKSB8fCAoKGNvbmZpZy0+dXNlclNiclJhdGlvPT0wKSYmKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSE9QU9UX0VSX0FBQ19FTEQpKSApIHsKICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IChiaXRyYXRlICsgKGJpdHJhdGU+PjIpKT4+MTsgLyogMC42MjUgYml0cyBwZXIgc2FtcGxlICovCiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIChjb25maWctPnVzZXJTYnJSYXRpbz09MSkgfHwgKChjb25maWctPnVzZXJTYnJSYXRpbz09MCkmJihoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9FUl9BQUNfRUxEKSkgKSB7CiAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSAoYml0cmF0ZSArIChiaXRyYXRlPj4zKSk7ICAgIC8qIDEuMTI1IGJpdHMgcGVyIHNhbXBsZSAqLwogICAgICAgICAgfQogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBiaXRyYXRlICsgKGJpdHJhdGU+PjEpOyAgICAgICAgLyogMS41IGJpdHMgcGVyIHNhbXBsZSAqLwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKGhBYWNDb25maWctPmJpdHJhdGVNb2RlID49IDApICYmIChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZSA8PSA1KSkgewogICAgICBpZiAoKElOVCljb25maWctPnVzZXJQZWFrQml0cmF0ZSAhPSAtMSkgewogICAgICAgIGhBYWNDb25maWctPm1heEJpdHNQZXJGcmFtZSA9IChGREthYWNFbmNfQ2FsY0JpdHNQZXJGcmFtZShmTWF4KGhBYWNDb25maWctPmJpdFJhdGUsIChJTlQpY29uZmlnLT51c2VyUGVha0JpdHJhdGUpLCBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCwgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSkgKyA3KSZ+NzsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBoQWFjQ29uZmlnLT5tYXhCaXRzUGVyRnJhbWUgPSAtMTsKICAgICAgfQogICAgICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9NdXhWZXJzaW9uPT0yKSB7CiAgICAgICAgaEFhY0NvbmZpZy0+bWluQml0c1BlckZyYW1lID0gZk1pbigzMio4LCBGREthYWNFbmNfQ2FsY0JpdHNQZXJGcmFtZShoQWFjQ29uZmlnLT5iaXRSYXRlLCBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCwgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSkpJn43OwogICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBTQlIgcGFyYW1ldGVycyAqLwogICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRVJfQUFDX0VMRCkKICAgICAgJiYgKGNvbmZpZy0+dXNlclNickVuYWJsZWQgPT0gKFVDSEFSKS0xKSAmJiAoY29uZmlnLT51c2VyU2JyUmF0aW89PTApICkKICAgIHsKICAgICAgVUlOVCBlbGRTYnIgPSAwOwogICAgICBVSU5UIGVsZFNiclJhdGlvID0gMDsKCiAgICAgIGlmICggQUFDRU5DX09LIT0oZXJyPWVsZFNickNvbmZpZ3VyYXRvcigKICAgICAgICAgICAgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsCiAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUsCiAgICAgICAgICAgJmVsZFNiciwKICAgICAgICAgICAmZWxkU2JyUmF0aW8pKSApCiAgICAgIHsKICAgICAgICByZXR1cm4gZXJyOwogICAgICB9CgogICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGVsZFNicikgPyBBQ19TQlJfUFJFU0VOVCA6IDApOwogICAgICBoQWFjQ29uZmlnLT5zYnJSYXRpbyA9IGVsZFNiclJhdGlvOwogICAgfQogICAgZWxzZQogICAgaWYgKCAoY29uZmlnLT51c2VyU2JyUmF0aW89PTApICYmIChpc1NickFjdGl2ZShoQWFjQ29uZmlnKSkgKSB7CiAgICAgIC8qIEF1dG9tYXRpYyBTQlIgcmF0aW8gY29uZmlndXJhdGlvbgogICAgICAgKiAtIGRvd25zYW1wbGVkIFNCUiBmb3IgRUxECiAgICAgICAqIC0gb3RoZXJ3aXNlIGFsd2F5cyBkdWFscmF0ZSBTQlIKICAgICAgICovCiAgICAgICAgaEFhY0NvbmZpZy0+c2JyUmF0aW8gPSAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRVJfQUFDX0VMRCkgPyAxIDogMjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBTQlIgcmF0aW8gaGFzIGJlZW4gc2V0IGJ5IHRoZSB1c2VyLCBzbyB1c2UgaXQuICovCiAgICAgIGhBYWNDb25maWctPnNiclJhdGlvID0gaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgPyBjb25maWctPnVzZXJTYnJSYXRpbyA6IDA7CiAgICB9CgogICAgewogICAgICBVQ0hBUiB0cFNpZ25hbGluZz1nZXRTYnJTaWduYWxpbmdNb2RlKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSwgY29uZmlnLT51c2VyVHBUeXBlLCBjb25maWctPnVzZXJUcFNpZ25hbGluZywgaEFhY0NvbmZpZy0+c2JyUmF0aW8pOwoKICAgICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfQUFDX0xDIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUiB8fCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9QUykgJiYKICAgICAgICAgICAoY29uZmlnLT51c2VyVHBUeXBlPT1UVF9NUDRfTEFUTV9NQ1AxIHx8IGNvbmZpZy0+dXNlclRwVHlwZT09VFRfTVA0X0xBVE1fTUNQMCB8fCBjb25maWctPnVzZXJUcFR5cGU9PVRUX01QNF9MT0FTKSAmJgogICAgICAgICAgICh0cFNpZ25hbGluZz09MSkgJiYgKGNvbmZpZy0+dXNlclRwQW14dj09MCkgKSB7CiAgICAgICAgICAgICAvKiBGb3IgYmFja3dhcmQgY29tcGF0aWJsZSBleHBsaWNpdCBzaWduYWxpbmcsIEFNVjEgaGFzIHRvIGJlIGFjdGl2ZSAqLwogICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgfQoKICAgICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfQUFDX0xDIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUiB8fCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9QUykgJiYKICAgICAgICAgICAodHBTaWduYWxpbmc9PTApICYmIChoQWFjQ29uZmlnLT5zYnJSYXRpbz09MSkpIHsKICAgICAgICAgICAgIC8qIERvd25zYW1wbGVkIFNCUiBoYXMgdG8gYmUgc2lnbmFsZWQgZXhwbGljaXRlbHkgKGZvciB0cmFuc21pc3Npb24gb2YgU0JSIHNhbXBsaW5nIGZlcXVlbmN5KSAqLwogICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgfQogICAgfQoKCgogICAgLyogV2UgbmVlZCB0aGUgZnJhbWUgbGVuZ3RoIHRvIGNhbGwgYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoKSAqLwogICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IGFhY0VuY29kZXJfTGltaXRCaXRyYXRlKAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5uU3ViRnJhbWVzLAogICAgICAgICAgICAgIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpLAogICAgICAgICAgICAgIGhBYWNDb25maWctPnNiclJhdGlvLAogICAgICAgICAgICAgIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZQogICAgICAgICAgICAgICk7CgogICAgLyogQ29uZmlndXJlIFBOUyAqLwogICAgaWYgKCAoKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPj0xKSAmJiAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU8PTUpKSAvKiBWQlIgd2l0aG91dCBQTlMuICovCiAgICAgICAgfHwgKGhBYWNDb25maWctPnVzZVRucyA9PSAwKSApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFROUyByZXF1aXJlZC4gKi8KICAgIHsKICAgICAgICBoQWFjQ29uZmlnLT51c2VQbnMgPSAwOwogICAgfQoKICAgIGlmIChoQWFjQ29uZmlnLT5lcENvbmZpZyA+PSAwKSB7CiAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gQUNfRVI7CiAgICAgICAgIGlmICgoKElOVCloQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA8IDEpIHx8ICgoSU5UKWhBYWNDb25maWctPmNoYW5uZWxNb2RlID4gNykpIHsKICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOyAgICAgICAgLyogQ2FubmVsIGNvbmZpZyAwIG5vdCBzdXBwb3J0ZWQuICovCiAgICAgICAgIH0KICAgIH0KCiAgICBpZiAoIEZES2FhY0VuY19EZXRlcm1pbmVFbmNvZGVyTW9kZSgmaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsIGhBYWNDb25maWctPm5DaGFubmVscykgIT0gQUFDX0VOQ19PSykgewogICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7ICAgICAgICAvKiBuQ2hhbm5lbHMgZG9lc24ndCBtYXRjaCBjaE1vZGUsIHRoaXMgaXMganVzdCBhIGNoZWNrLXVwICovCiAgICB9CgogICAgaWYgKCAoaEFhY0NvbmZpZy0+bkNoYW5uZWxzID4gaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscykKICAgICAgfHwgKCAoRkRLYWFjRW5jX0dldENoYW5uZWxNb2RlQ29uZmlndXJhdGlvbihoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSktPm5DaGFubmVsc0VmZiA+IGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMpICYmCiAgICAgICAgICAgIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICkKICAgICAgICAgKQogICAgewogICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7ICAgICAgLyogbm90IGVub3VnaCBjaGFubmVscyBhbGxvY2F0ZWQgKi8KICAgIH0KCiAgICAvKiBNZXRhIGRhdGEgcmVzdHJpY3Rpb24uICovCiAgICBzd2l0Y2ggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkKICAgIHsKICAgICAgLyogQWxsb3cgbWV0YWRhdGEgc3VwcG9ydCAqLwogICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgaEFhY0VuY29kZXItPm1ldGFEYXRhQWxsb3dlZCA9IDE7CiAgICAgICAgaWYgKCgoSU5UKWhBYWNDb25maWctPmNoYW5uZWxNb2RlIDwgMSkgfHwgKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPiA3KSkgewogICAgICAgICAgY29uZmlnLT51c2VyTWV0YURhdGFNb2RlID0gMDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIC8qIFByb2hpYml0IG1ldGFkYXRhIHN1cHBvcnQgKi8KICAgICAgZGVmYXVsdDoKICAgICAgICBoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkID0gMDsKICAgIH0KCiAgICByZXR1cm4gZXJyOwp9CgpzdGF0aWMKSU5UIGFhY2VuY19TYnJDYWxsYmFjaygKICAgICAgICB2b2lkICogICAgICAgICAgICAgICAgICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgIGhCcywKICAgICAgICBjb25zdCBJTlQgc2FtcGxlUmF0ZUluLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlT3V0LAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEICAgIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICApCnsKICBIQU5ETEVfQUFDRU5DT0RFUiBoQWFjRW5jb2RlciA9IChIQU5ETEVfQUFDRU5DT0RFUilzZWxmOwoKICBzYnJFbmNvZGVyX0dldEhlYWRlcihoQWFjRW5jb2Rlci0+aEVudkVuYywgaEJzLCBlbGVtZW50SW5kZXgsIDApOwoKICByZXR1cm4gMDsKfQoKc3RhdGljIEFBQ0VOQ19FUlJPUiBhYWNFbmNJbml0KEhBTkRMRV9BQUNFTkNPREVSICBoQWFjRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICAgICAgICAgICAgICBJbml0RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICAgICAgICAqY29uZmlnKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwoKICAgIElOVCBhYWNCdWZmZXJPZmZzZXQgPSAwOwogICAgSEFORExFX1NCUl9FTkNPREVSICAgICAqaFNickVuY29kZXIgPSAmaEFhY0VuY29kZXItPmhFbnZFbmM7CiAgICBIQU5ETEVfQUFDRU5DX0NPTkZJRyAgICBoQWFjQ29uZmlnICA9ICZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnOwoKICAgIGhBYWNFbmNvZGVyLT5uWmVyb3NBcHBlbmRlZCA9IDA7ICAgICAgICAgIC8qIGNvdW50IGFwcGVuZGVkIHplcm9zICovCgogICAgSU5UIGZyYW1lTGVuZ3RoID0gaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGg7CgogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSApCiAgICB7CiAgICAgICAgQ0hBTk5FTF9NT0RFIHByZXZDaE1vZGUgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKCiAgICAgICAgLyogVmVyaWZ5IHNldHRpbmdzIGFuZCB1cGRhdGU6IGNvbmZpZyAtPiBoZUFhY0VuY29kZXIgKi8KICAgICAgICBpZiAoIChlcnI9RkRLYWFjRW5jX0FkanVzdEVuY1NldHRpbmdzKGhBYWNFbmNvZGVyLCBjb25maWcpKSAhPSBBQUNFTkNfT0sgKSB7CiAgICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgfQogICAgICAgIGZyYW1lTGVuZ3RoID0gaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGg7IC8qIGFkYXB0IHRlbXBvcmFsIGZyYW1lbGVuZ3RoICovCgogICAgICAgIC8qIFNlYW1sZXNzIGNoYW5uZWwgcmVjb25maWd1cmF0aW9uIGluIHNiciBub3QgZnVsbHkgaW1wbGVtZW50ZWQgKi8KICAgICAgICBpZiAoIChwcmV2Q2hNb2RlIT1oQWFjQ29uZmlnLT5jaGFubmVsTW9kZSkgJiYgaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgKSB7CiAgICAgICAgICAgIEluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9TVEFURVM7CiAgICAgICAgfQogICAgfQoKICAgIC8qIENsZWFyIGlucHV0IGJ1ZmZlciAqLwogICAgaWYgKCBJbml0RmxhZ3MgPT0gQUFDRU5DX0lOSVRfQUxMICkgewogICAgICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwgc2l6ZW9mKElOVF9QQ00pKmhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMqSU5QVVRCVUZGRVJfU0laRSk7CiAgICB9CgogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSApCiAgICB7CiAgICAgICAgYWFjQnVmZmVyT2Zmc2V0ID0gMDsKICAgICAgICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uRGVsYXkgPSBERUxBWV9BQUNFTEQoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGgpOwogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSA9IERFTEFZX0FBQyhoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCk7IC8qIEFBQyBlbmNvZGVyIGRlbGF5ICovCiAgICAgICAgfQogICAgICAgIGhBYWNDb25maWctPmFuY0RhdGFCaXRSYXRlID0gMDsKICAgIH0KCiAgICBpZiAoIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICYmCiAgICAgICAgKChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpIHx8IChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpKSApCiAgICB7CiAgICAgICAgSU5UIHNickVycm9yOwogICAgICAgIFNCUl9FTEVNRU5UX0lORk8gc2JyRWxJbmZvWyg4KV07CiAgICAgICAgQ0hBTk5FTF9NQVBQSU5HIGNoYW5uZWxNYXBwaW5nOwoKICAgICAgICBpZiAoIEZES2FhY0VuY19Jbml0Q2hhbm5lbE1hcHBpbmcoaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmNoYW5uZWxPcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2hhbm5lbE1hcHBpbmcpICE9IEFBQ19FTkNfT0sgKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgcmV0dXJuIHZhbHVlIGFuZCBpZiB0aGUgU0JSIGVuY29kZXIgY2FuIGhhbmRsZSBlbm91Z2ggZWxlbWVudHMgKi8KICAgICAgICBpZiAoY2hhbm5lbE1hcHBpbmcubkVsZW1lbnRzID4gKDgpKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9FUlJPUjsKICAgICAgICB9CgogICAgICAgIGFhY0VuY0Rpc3RyaWJ1dGVTYnJCaXRzKCZjaGFubmVsTWFwcGluZywgc2JyRWxJbmZvLCBoQWFjQ29uZmlnLT5iaXRSYXRlKTsKCiAgICAgICAgVUlOVCBpbml0RmxhZyA9IDA7CiAgICAgICAgaW5pdEZsYWcgKz0gKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykgPyAxIDogMDsKCiAgICAgICAgLyogTGV0IHRoZSBTQlIgZW5jb2RlciB0YWtlIGEgbG9vayBhdCB0aGUgY29uZmlndXJhdGlvbiBhbmQgY2hhbmdlIGlmIHJlcXVpcmVkLiAqLwogICAgICAgIHNickVycm9yID0gc2JyRW5jb2Rlcl9Jbml0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpoU2JyRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2JyRWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwcGluZy5uRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+YmFuZFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhYWNCdWZmZXJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNDb25maWctPm5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+c2JyUmF0aW8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZyYW1lTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNFbmNvZGVyLT5uRGVsYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0FBQ19FTEQpID8gMSA6IFRSQU5TX0ZBQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbmZpZy0+dXNlclRwSGVhZGVyUGVyaW9kIT0weEZGKSA/IGNvbmZpZy0+dXNlclRwSGVhZGVyUGVyaW9kIDogREVGQVVMVF9IRUFERVJfUEVSSU9EX1JFUEVUSVRJT05fUkFURSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdEZsYWcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAvKiBTdXBwcmVzcyBBT1QgcmVjb25maWd1cmF0aW9uIGFuZCBjaGVjayBlcnJvciBzdGF0dXMuICovCiAgICAgICAgaWYgKHNickVycm9yKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9TQlJfRVJST1I7CiAgICAgICAgfQoKICAgICAgICBpZiAoaEFhY0NvbmZpZy0+bkNoYW5uZWxzID09IDEpIHsKICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPSBNT0RFXzE7CiAgICAgICAgfQoKICAgICAgICAvKiBOZXZlciB1c2UgUE5TIGlmIFNCUiBpcyBhY3RpdmUgKi8KICAgICAgICBpZiAoIGhBYWNDb25maWctPnVzZVBucyApIHsKICAgICAgICAgICBoQWFjQ29uZmlnLT51c2VQbnMgPSAwOwogICAgICAgIH0KCiAgICAgICAgLyogZXN0aW1hdGVkIGJpdHJhdGUgY29uc3VtZWQgYnkgU0JSIG9yIFBTICovCiAgICAgICAgaEFhY0NvbmZpZy0+YW5jRGF0YUJpdFJhdGUgPSBzYnJFbmNvZGVyX0dldEVzdGltYXRlQml0cmF0ZSgqaFNickVuY29kZXIpIDsKCiAgICB9IC8qIHNiciBpbml0aWFsaXphdGlvbiAqLwoKCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSBUcmFuc3BvcnQgLSBNb2R1bGUuCiAgICAgKi8KICAgIGlmICggKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1RSQU5TUE9SVCkgKQogICAgewogICAgICAgIFVJTlQgZmxhZ3MgPSAwOwoKICAgICAgICBGREthYWNFbmNfTWFwQ29uZmlnKAogICAgICAgICAgICAgICAgJmhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZywKICAgICAgICAgICAgICAgIGNvbmZpZywKICAgICAgICAgICAgICAgIGdldFNiclNpZ25hbGluZ01vZGUoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlLCBjb25maWctPnVzZXJUcFR5cGUsIGNvbmZpZy0+dXNlclRwU2lnbmFsaW5nLCBoQWFjQ29uZmlnLT5zYnJSYXRpbyksCiAgICAgICAgICAgICAgICBoQWFjQ29uZmlnKTsKCiAgICAgICAgLyogY3JlYXRlIGZsYWdzIGZvciB0cmFuc3BvcnQgZW5jb2RlciAqLwogICAgICAgIGlmIChjb25maWctPnVzZXJUcEFteHYgIT0gMCkgewogICAgICAgICAgICBmbGFncyB8PSBUUF9GTEFHX0xBVE1fQU1WOwogICAgICAgIH0KICAgICAgICAvKiBDbGVhciBvdXRwdXQgYnVmZmVyICovCiAgICAgICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPm91dEJ1ZmZlciwgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMqc2l6ZW9mKFVDSEFSKSk7CgogICAgICAgIC8qIEluaXRpYWxpemUgQml0c3RyZWFtIGVuY29kZXIgKi8KICAgICAgICBpZiAoIHRyYW5zcG9ydEVuY19Jbml0KGhBYWNFbmNvZGVyLT5oVHBFbmMsIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIsIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXJJbkJ5dGVzLCBjb25maWctPnVzZXJUcFR5cGUsICZoQWFjRW5jb2Rlci0+Y29kZXJDb25maWcsIGZsYWdzKSAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9UUF9FUlJPUjsKICAgICAgICB9CgogICAgfSAvKiB0cmFuc3BvcnQgaW5pdGlhbGl6YXRpb24gKi8KCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSBBQUMgLSBDb3JlLgogICAgICovCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpIHx8CiAgICAgICAgIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpICkKICAgIHsKICAgICAgICBBQUNfRU5DT0RFUl9FUlJPUiBlcnI7CiAgICAgICAgZXJyID0gRkRLYWFjRW5jX0luaXRpYWxpemUoaEFhY0VuY29kZXItPmhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpID8gMSA6IDApOwoKICAgICAgICBpZiAoZXJyICE9IEFBQ19FTkNfT0spIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX0FBQ19FUlJPUjsKICAgICAgICB9CgogICAgfSAvKiBhYWMgaW5pdGlhbGl6YXRpb24gKi8KCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSBNZXRhIERhdGEgLSBFbmNvZGVyLgogICAgICovCiAgICBpZiAoIGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMgJiYgKGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQhPTApICYmCiAgICAgICAgKChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpIHx8KEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykpICkKICAgIHsKICAgICAgICBJTlQgaW5wdXREYXRhRGVsYXkgPSBERUxBWV9BQUMoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGgpOwoKICAgICAgICBpZiAoIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICYmIGhTYnJFbmNvZGVyIT1OVUxMKSB7CiAgICAgICAgICBpbnB1dERhdGFEZWxheSA9IGhBYWNDb25maWctPnNiclJhdGlvKmlucHV0RGF0YURlbGF5ICsgc2JyRW5jb2Rlcl9HZXRJbnB1dERhdGFEZWxheSgqaFNickVuY29kZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCBGREtfTWV0YWRhdGFFbmNfSW5pdChoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEluaXRGbGFncyZBQUNFTkNfSU5JVF9TVEFURVMpID8gMSA6IDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT51c2VyTWV0YURhdGFNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXREYXRhRGVsYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlclNhbXBsZXJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPm5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlckNoYW5uZWxNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE9yZGVyKSAhPSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX01FVEFfRVJST1I7CiAgICAgICAgfQoKICAgICAgICBoQWFjRW5jb2Rlci0+bkRlbGF5ICs9IEZES19NZXRhZGF0YUVuY19HZXREZWxheShoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jKTsKICAgIH0KCiAgICAvKgogICAgICogVXBkYXRlIHBvaW50ZXIgdG8gd29ya2luZyBidWZmZXIuCiAgICAgKi8KICAgIGlmICggKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgKQogICAgewogICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlck9mZnNldCA9IGFhY0J1ZmZlck9mZnNldDsKCiAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkID0gZnJhbWVMZW5ndGggKiBjb25maWctPm5DaGFubmVsczsKCiAgICAgICAgLyogTWFrZSBuRGVsYXkgY29tcGFyaXNvbiBjb21wYXRpYmxlIHdpdGggY29uZmlnLT5uU2FtcGxlc1JlYWQgKi8KICAgICAgICBoQWFjRW5jb2Rlci0+bkRlbGF5ICo9IGNvbmZpZy0+bkNoYW5uZWxzOwoKICAgIH0gLyogcGFyYW1ldGVyIGNoYW5nZWQgKi8KCiAgICByZXR1cm4gQUFDRU5DX09LOwp9CgoKQUFDRU5DX0VSUk9SIGFhY0VuY09wZW4oCiAgICAgICAgSEFORExFX0FBQ0VOQ09ERVIgICAgICAgICpwaEFhY0VuY29kZXIsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICBlbmNNb2R1bGVzLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgbWF4Q2hhbm5lbHMKICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CiAgICBIQU5ETEVfQUFDRU5DT0RFUiAgaEFhY0VuY29kZXIgPSBOVUxMOwoKICAgIGlmIChwaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0hBTkRMRTsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogYWxsb2NhdGUgbWVtb3J5ICovCiAgICBoQWFjRW5jb2RlciA9IEdldF9BYWNFbmNvZGVyKCk7CgogICAgaWYgKGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlciwgc2l6ZW9mKEFBQ0VOQ09ERVIpKTsKCiAgICAvKiBTcGVjaWZ5IGVuY29kZXIgbW9kdWxlcyB0byBiZSBhbGxvY2F0ZWQuICovCiAgICBpZiAoZW5jTW9kdWxlcz09MCkgewogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzID0gRU5DX01PREVfRkxBR19BQUM7CiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgfD0gRU5DX01PREVfRkxBR19TQlI7CiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgfD0gRU5DX01PREVfRkxBR19QUzsKICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyB8PSBFTkNfTU9ERV9GTEFHX01FVEE7CiAgICB9CiAgICBlbHNlIHsKICAgICAgIC8qIGNvbnNpZGVyIFNBQyBhbmQgUFMgbW9kdWxlICovCiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgPSBlbmNNb2R1bGVzOwogICAgfQoKICAgIC8qIERldGVybWluZSBtYXggY2hhbm5lbCBjb25maWd1cmF0aW9uLiAqLwogICAgaWYgKG1heENoYW5uZWxzPT0wKSB7CiAgICAgICAgaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscyA9ICg4KTsKICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzID0gKDgpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscyA9IChtYXhDaGFubmVscyYweDAwRkYpOwogICAgICAgIGlmICggKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfU0JSKSApIHsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscyA9IChtYXhDaGFubmVscyYweEZGMDApID8gKG1heENoYW5uZWxzPj44KSA6IGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHM7CiAgICAgICAgfQoKICAgICAgICBpZiAoIChoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzPig4KSkgfHwgKGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHM+KDgpKSApIHsKICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgfSAvKiBtYXhDaGFubmVscz09MCAqLwoKICAgIC8qIE1heCBudW1iZXIgb2YgZWxlbWVudHMgY291bGQgYmUgdHVuZWQgYW55IG1vcmUuICovCiAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0VsZW1lbnRzID0gZml4TWluKCg4KSwgaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscyk7CiAgICBoQWFjRW5jb2Rlci0+bk1heFNickVsZW1lbnRzID0gZml4TWluKCg4KSwgaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscyk7CiAgICBoQWFjRW5jb2Rlci0+bk1heFN1YkZyYW1lcyA9ICgxKTsKCgogICAgLyogSW4gY2FzZSBvZiBtZW1vcnkgb3ZlcmxheSwgYWxsb2NhdGUgbWVtb3J5IG91dCBvZiBsaWJyYXJpZXMgKi8KCiAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIgPSAoSU5UX1BDTSopRkRLY2FsbG9jKGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMqSU5QVVRCVUZGRVJfU0laRSwgc2l6ZW9mKElOVF9QQ00pKTsKCiAgICAvKiBPcGVuIFNCUiBFbmNvZGVyICovCiAgICBpZiAoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19TQlIpIHsKICAgICAgICBpZiAoIHNickVuY29kZXJfT3BlbigmaEFhY0VuY29kZXItPmhFbnZFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfUFMpID8gMSA6IDAgKSApCiAgICAgICAgewogICAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICB9IC8qIChlbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfU0JSKSAqLwoKCiAgICAvKiBPcGVuIEFhYyBFbmNvZGVyICovCiAgICBpZiAoIEZES2FhY0VuY19PcGVuKCZoQWFjRW5jb2Rlci0+aEFhY0VuYywKICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgKDEpKSAhPSBBQUNfRU5DX09LICkKICAgIHsKICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICB7IC8qIEdldCBiaXRzdHJlYW0gb3V0cHV0YnVmZmVyIHNpemUgKi8KICAgICAgVUlOVCBsZF9NOwogICAgICBmb3IgKGxkX009MTsgKFVJTlQpKDE8PGxkX00pIDwgKGhBYWNFbmNvZGVyLT5uTWF4U3ViRnJhbWVzKmhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMqNjE0NCk+PjM7IGxkX00rKykgOwogICAgICBoQWFjRW5jb2Rlci0+b3V0QnVmZmVySW5CeXRlcyA9ICgxPDxsZF9NKTsgIC8qIGJ1ZmZlciBoYXMgdG8gYmUgMl5uICovCiAgICB9CiAgICBoQWFjRW5jb2Rlci0+b3V0QnVmZmVyID0gR2V0UmFtX2JzT3V0YnVmZmVyKCk7CiAgICBpZiAoT1VUUFVUQlVGRkVSX1NJWkUgPCBoQWFjRW5jb2Rlci0+b3V0QnVmZmVySW5CeXRlcyApIHsKICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIE9wZW4gTWV0YSBEYXRhIEVuY29kZXIgKi8KICAgIGlmIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX01FVEEpIHsKICAgICAgaWYgKCBGREtfTWV0YWRhdGFFbmNfT3BlbigmaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYykgKQogICAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgIH0gLyogKGVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19NRVRBKSAqLwoKICAgIC8qIE9wZW4gVHJhbnNwb3J0IEVuY29kZXIgKi8KICAgIGlmICggdHJhbnNwb3J0RW5jX09wZW4oJmhBYWNFbmNvZGVyLT5oVHBFbmMpICE9IDAgKQogICAgewogICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHBMaWJJbmZvLCBMSUJfSU5GTywgRkRLX01PRFVMRV9MQVNUKTsKCiAgICAgICAgRkRLaW5pdExpYkluZm8oIHBMaWJJbmZvKTsKICAgICAgICB0cmFuc3BvcnRFbmNfR2V0TGliSW5mbyggcExpYkluZm8gKTsKCiAgICAgICAgLyogR2V0IGNhcGFiaWx0eSBmbGFnIGZvciB0cmFuc3BvcnQgZW5jb2Rlci4gKi8KICAgICAgICBoQWFjRW5jb2Rlci0+Q0FQRl90cEVuYyA9IEZES2xpYkluZm9fZ2V0Q2FwYWJpbGl0aWVzKCBwTGliSW5mbywgRkRLX1RQRU5DKTsKCiAgICAgICAgQ19BTExPQ19TQ1JBVENIX0VORChwTGliSW5mbywgTElCX0lORk8sIEZES19NT0RVTEVfTEFTVCk7CiAgICB9CiAgICBpZiAoIHRyYW5zcG9ydEVuY19SZWdpc3RlclNickNhbGxiYWNrKGhBYWNFbmNvZGVyLT5oVHBFbmMsIGFhY2VuY19TYnJDYWxsYmFjaywgaEFhY0VuY29kZXIpICE9IDAgKSB7CiAgICAgIGVyciA9IEFBQ0VOQ19JTklUX1RQX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBlbmNvZGVyIGluc3RhbmNlIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzLiAqLwogICAgYWFjRW5jRGVmYXVsdENvbmZpZygmaEFhY0VuY29kZXItPmFhY0NvbmZpZywgJmhBYWNFbmNvZGVyLT5leHRQYXJhbSk7CgogICAgLyogSW5pdGlhbGl6ZSBoZWFkZXJQZXJpb2QgaW4gY29kZXJDb25maWcgZm9yIGFhY0VuY29kZXJfR2V0UGFyYW0oKS4gKi8KICAgIGhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZy5oZWFkZXJQZXJpb2QgPSBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlclRwSGVhZGVyUGVyaW9kOwoKICAgIC8qIEFsbCBlbmNvZGVyIG1vZHVsZXMgaGF2ZSB0byBiZSBpbml0aWFsaXplZCAqLwogICAgaEFhY0VuY29kZXItPkluaXRGbGFncyA9IEFBQ0VOQ19JTklUX0FMTDsKCiAgICAvKiBSZXR1cm4gZW5jb2RlciBpbnN0YW5jZSAqLwogICAgKnBoQWFjRW5jb2RlciA9IGhBYWNFbmNvZGVyOwoKICAgIHJldHVybiBlcnI7CgpiYWlsOgogICAgYWFjRW5jQ2xvc2UoJmhBYWNFbmNvZGVyKTsKCiAgICByZXR1cm4gZXJyOwp9CgoKCkFBQ0VOQ19FUlJPUiBhYWNFbmNDbG9zZShIQU5ETEVfQUFDRU5DT0RFUiAqcGhBYWNFbmNvZGVyKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwoKICAgIGlmIChwaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0hBTkRMRTsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgaWYgKCpwaEFhY0VuY29kZXIgIT0gTlVMTCkgewogICAgICAgIEhBTkRMRV9BQUNFTkNPREVSIGhBYWNFbmNvZGVyID0gKnBoQWFjRW5jb2RlcjsKCgogICAgICAgaWYgKGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciE9TlVMTCkgewogICAgICAgICAgIEZES2ZyZWUoaEFhY0VuY29kZXItPmlucHV0QnVmZmVyKTsKICAgICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIgPSBOVUxMOwogICAgICAgfQoKICAgICAgIGlmIChoQWFjRW5jb2Rlci0+b3V0QnVmZmVyKSB7CiAgICAgICAgIEZyZWVSYW1fYnNPdXRidWZmZXIoJmhBYWNFbmNvZGVyLT5vdXRCdWZmZXIpOwogICAgICAgfQoKICAgICAgICBpZiAoaEFhY0VuY29kZXItPmhFbnZFbmMpIHsKICAgICAgICAgICAgc2JyRW5jb2Rlcl9DbG9zZSAoJmhBYWNFbmNvZGVyLT5oRW52RW5jKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5oQWFjRW5jKSB7CiAgICAgICAgICAgIEZES2FhY0VuY19DbG9zZSAoJmhBYWNFbmNvZGVyLT5oQWFjRW5jKTsKICAgICAgICB9CgogICAgICAgIHRyYW5zcG9ydEVuY19DbG9zZSgmaEFhY0VuY29kZXItPmhUcEVuYyk7CgogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jKSB7CiAgICAgICAgICAgIEZES19NZXRhZGF0YUVuY19DbG9zZSAoJmhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMpOwogICAgICAgIH0KCiAgICAgICAgRnJlZV9BYWNFbmNvZGVyKHBoQWFjRW5jb2Rlcik7CiAgICB9CgpiYWlsOgogICAgcmV0dXJuIGVycjsKfQoKQUFDRU5DX0VSUk9SIGFhY0VuY0VuY29kZSgKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZEZXNjICAgICAqaW5CdWZEZXNjLAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZEZXNjICAgICAqb3V0QnVmRGVzYywKICAgICAgICBjb25zdCBBQUNFTkNfSW5BcmdzICAgICAgKmluYXJncywKICAgICAgICBBQUNFTkNfT3V0QXJncyAgICAgICAgICAgKm91dGFyZ3MKICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CiAgICBJTlQgaSwgbkJzQnl0ZXMgPSAwOwogICAgSU5UICBvdXRCeXRlc1soMSldOwogICAgaW50ICBuRXh0ZW5zaW9ucyA9IDA7CiAgICBpbnQgIGFuY0RhdGFFeHRJZHggPSAtMTsKCiAgICAvKiBkZWFsIHdpdGggdmFsaWQgZW5jb2RlciBoYW5kbGUgKi8KICAgIGlmIChoQWFjRW5jb2Rlcj09TlVMTCkgewogICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0hBTkRMRTsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgoKICAgIC8qCiAgICAgKiBBZGp1c3QgdXNlciBzZXR0aW5ncyBhbmQgdHJpZ2dlciByZWluaXRpYWxpemF0aW9uLgogICAgICovCiAgICBpZiAoaEFhY0VuY29kZXItPkluaXRGbGFncyE9MCkgewoKICAgICAgICBlcnIgPSBhYWNFbmNJbml0KGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNFbmNvZGVyLT5leHRQYXJhbSk7CgogICAgICAgIGlmIChlcnIhPUFBQ0VOQ19PSykgewogICAgICAgICAgICAvKiBrZWVwIGluaXQgZmxhZ3MgYWxpdmUhICovCiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyA9IEFBQ0VOQ19JTklUX05PTkU7CiAgICB9CgogICAgaWYgKG91dGFyZ3MhPU5VTEwpIHsKICAgICAgICBGREttZW1jbGVhcihvdXRhcmdzLCBzaXplb2YoQUFDRU5DX091dEFyZ3MpKTsKICAgIH0KCiAgICBpZiAob3V0QnVmRGVzYyE9TlVMTCkgewogICAgICBmb3IgKGk9MDsgaTxvdXRCdWZEZXNjLT5udW1CdWZzOyBpKyspIHsKICAgICAgICBpZiAob3V0QnVmRGVzYy0+YnVmc1tpXSE9TlVMTCkgewogICAgICAgICAgRkRLbWVtY2xlYXIob3V0QnVmRGVzYy0+YnVmc1tpXSwgb3V0QnVmRGVzYy0+YnVmU2l6ZXNbaV0pOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBJZiBvbmx5IGVuY29kZXIgaGFuZGxlIGdpdmVuLCBpbmRlcGVuZGVudCAocmUpaW5pdGlhbGl6YXRpb24gY2FuIGJlIHRyaWdnZXJlZC4KICAgICAqLwogICAgaWYgKCAoaEFhY0VuY29kZXIhPU5VTEwpICYgKGluQnVmRGVzYz09TlVMTCkgJiYgKG91dEJ1ZkRlc2M9PU5VTEwpICYmIChpbmFyZ3M9PU5VTEwpICYmIChvdXRhcmdzPT1OVUxMKSApIHsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogcmVzZXQgYnVmZmVyIHdpY2ggc2lnbmFscyBudW1iZXIgb2YgdmFsaWQgYnl0ZXMgaW4gb3V0cHV0IGJpdHN0cmVhbSBidWZmZXIgKi8KICAgIEZES21lbWNsZWFyKG91dEJ5dGVzLCBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLm5TdWJGcmFtZXMqc2l6ZW9mKElOVCkpOwoKICAgIC8qCiAgICAgKiBNYW5hZ2UgaW5jb21pbmcgYXVkaW8gc2FtcGxlcy4KICAgICAqLwogICAgaWYgKCAoaW5hcmdzLT5udW1JblNhbXBsZXMgPiAwKSAmJiAoZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fQVVESU9fREFUQSkgIT0gLTEpICkKICAgIHsKICAgICAgICAvKiBGZXRjaCBkYXRhIHVudGlsIG5TYW1wbGVzVG9SZWFkIHJlYWNoZWQgKi8KICAgICAgICBJTlQgaWR4ID0gZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fQVVESU9fREFUQSk7CiAgICAgICAgSU5UIG5ld1NhbXBsZXMgPSBmaXhNYXgoMCxmaXhNaW4oaW5hcmdzLT5udW1JblNhbXBsZXMsIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZC1oQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkKSk7CiAgICAgICAgSU5UX1BDTSAqcEluID0gaEFhY0VuY29kZXItPmlucHV0QnVmZmVyK2hBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlck9mZnNldCtoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkOwoKICAgICAgICAvKiBDb3B5IG5ldyBpbnB1dCBzYW1wbGVzIHRvIGludGVybmFsIGJ1ZmZlciAqLwogICAgICAgIGlmIChpbkJ1ZkRlc2MtPmJ1ZkVsU2l6ZXNbaWR4XT09KElOVClzaXplb2YoSU5UX1BDTSkpIHsKICAgICAgICAgICAgRkRLbWVtY3B5KHBJbiwgKElOVF9QQ00qKWluQnVmRGVzYy0+YnVmc1tpZHhdLCBuZXdTYW1wbGVzKnNpemVvZihJTlRfUENNKSk7ICAvKiBGYXN0IGNvcHkuICovCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGluQnVmRGVzYy0+YnVmRWxTaXplc1tpZHhdPihJTlQpc2l6ZW9mKElOVF9QQ00pKSB7CiAgICAgICAgICAgIGZvciAoaT0wOyBpPG5ld1NhbXBsZXM7IGkrKykgewogICAgICAgICAgICAgICAgcEluW2ldID0gKElOVF9QQ00pKCgoTE9ORyopaW5CdWZEZXNjLT5idWZzW2lkeF0pW2ldPj4xNik7ICAgICAgICAgICAgICAgIC8qIENvbnZlcnQgMzIgdG8gMTYgYml0LiAqLwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBmb3IgKGk9MDsgaTxuZXdTYW1wbGVzOyBpKyspIHsKICAgICAgICAgICAgICAgIHBJbltpXSA9ICgoSU5UX1BDTSkoKChTSE9SVCopaW5CdWZEZXNjLT5idWZzW2lkeF0pW2ldKSk8PDE2OyAgICAgICAgICAgICAvKiBDb252ZXJ0IDE2IHRvIDMyIGJpdC4gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkICs9IG5ld1NhbXBsZXM7CgogICAgICAgIC8qIE51bWJlciBvZiBmZXRjaGVkIGlucHV0IGJ1ZmZlciBzYW1wbGVzLiAqLwogICAgICAgIG91dGFyZ3MtPm51bUluU2FtcGxlcyA9IG5ld1NhbXBsZXM7CiAgICB9CgogICAgLyogaW5wdXQgYnVmZmVyIGNvbXBsZXRlbHkgZmlsbGVkID8gKi8KICAgIGlmIChoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkIDwgaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkKQogICAgewogICAgICAgIC8qIC0gZW9mIHJlYWNoZWQgYW5kIGZsdXNoaW5nIGVuYWJsZWQsIG9yCiAgICAgICAgICAgLSByZXR1cm4gdG8gbWFpbiBhbmQgd2FpdCBmb3IgZnVydGhlciBpbmNvbWluZyBhdWRpbyBzYW1wbGVzICovCiAgICAgICAgaWYgKGluYXJncy0+bnVtSW5TYW1wbGVzPT0tMSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggKGhBYWNFbmNvZGVyLT5uWmVyb3NBcHBlbmRlZCA8IGhBYWNFbmNvZGVyLT5uRGVsYXkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBpbnQgblplcm9zID0gaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkIC0gaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZDsKCiAgICAgICAgICAgICAgRkRLX0FTU0VSVChuWmVyb3MgPj0gMCk7CgogICAgICAgICAgICAgIC8qIGNsZWFyIG91dCB1bnRpbCBlbmQtb2YtYnVmZmVyICovCiAgICAgICAgICAgICAgaWYgKG5aZXJvcykgewogICAgICAgICAgICAgICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPmlucHV0QnVmZmVyK2hBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlck9mZnNldCtoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkLCBzaXplb2YoSU5UX1BDTSkqblplcm9zICk7CiAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+blplcm9zQXBwZW5kZWQgKz0gblplcm9zOwogICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7IC8qIGZsdXNoaW5nIGNvbXBsZXRlZCAqLwogICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRU9GOyAvKiBlb2YgcmVhY2hlZCAqLwogICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsgLyogaW5hcmdzLT5udW1JblNhbXBsZXMhPSAtMSAqLwogICAgICAgICAgICBnb3RvIGJhaWw7IC8qIG5vdCBlbm91Z2ggc2FtcGxlcyBpbiBpbnB1dCBidWZmZXIgYW5kIG5vIGZsdXNoaW5nIGVuYWJsZWQgKi8KICAgICAgICB9CiAgICB9CgogICAgLyogaW5pdCBwYXlsb2FkICovCiAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZCwgc2l6ZW9mKEFBQ0VOQ19FWFRfUEFZTE9BRCkgKiBNQVhfVE9UQUxfRVhUX1BBWUxPQURTKTsKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfVE9UQUxfRVhUX1BBWUxPQURTOyBpKyspIHsKICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbaV0uYXNzb2NpYXRlZENoRWxlbWVudCA9IC0xOwogICAgfQogICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPmV4dFBheWxvYWREYXRhLCBzaXplb2YoaEFhY0VuY29kZXItPmV4dFBheWxvYWREYXRhKSk7CiAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFNpemUsIHNpemVvZihoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFNpemUpKTsKCgogICAgLyoKICAgICAqIENhbGN1bGF0ZSBNZXRhIERhdGEgaW5mby4KICAgICAqLwogICAgaWYgKCAoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYyE9TlVMTCkgJiYgKGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQhPTApICkgewoKICAgICAgICBjb25zdCBBQUNFTkNfTWV0YURhdGEgKnBNZXRhRGF0YSA9IE5VTEw7CiAgICAgICAgQUFDRU5DX0VYVF9QQVlMT0FEICpwTWV0YURhdGFFeHRQYXlsb2FkID0gTlVMTDsKICAgICAgICBVSU5UIG5NZXRhRGF0YUV4dGVuc2lvbnMgPSAwOwogICAgICAgIElOVCAgbWF0cml4X21peGRvd25faWR4ID0gMDsKCiAgICAgICAgLyogTmV3IG1ldGEgZGF0YSBpbmZvIGF2YWlsYWJsZSA/ICovCiAgICAgICAgaWYgKCBnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9NRVRBREFUQV9TRVRVUCkgIT0gLTEgKSB7CiAgICAgICAgICBwTWV0YURhdGEgPSAoQUFDRU5DX01ldGFEYXRhKilpbkJ1ZkRlc2MtPmJ1ZnNbZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fTUVUQURBVEFfU0VUVVApXTsKICAgICAgICB9CgogICAgICAgIEZES19NZXRhZGF0YUVuY19Qcm9jZXNzKGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyK2hBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlck9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNZXRhRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTWV0YURhdGFFeHRQYXlsb2FkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5NZXRhRGF0YUV4dGVuc2lvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbWF0cml4X21peGRvd25faWR4CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgZm9yIChpPTA7IGk8KElOVCluTWV0YURhdGFFeHRlbnNpb25zOyBpKyspIHsgIC8qIEdldCBtZXRhIGRhdGEgZXh0ZW5zaW9uIHBheWxvYWQuICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zKytdID0gcE1ldGFEYXRhRXh0UGF5bG9hZFtpXTsKICAgICAgICB9CgogICAgICAgIGlmICggKG1hdHJpeF9taXhkb3duX2lkeCE9LTEpCiAgICAgICAgICAmJiAoKGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyQ2hhbm5lbE1vZGU9PU1PREVfMV8yXzIpfHwoaEFhY0VuY29kZXItPmV4dFBhcmFtLnVzZXJDaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKQogICAgICAgIHsKICAgICAgICAgIC8qIFNldCBtYXRyaXggbWl4ZG93biBjb2VmZmljaWVudC4gKi8KICAgICAgICAgIFVJTlQgcGNlVmFsdWUgPSAoVUlOVCkoICgwPDwzKSB8ICgobWF0cml4X21peGRvd25faWR4JjB4Myk8PDEpIHwgMSApOwogICAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyUGNlQWRkaXRpb25zICE9IHBjZVZhbHVlKSB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyUGNlQWRkaXRpb25zID0gcGNlVmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCgogICAgaWYgKCBpc1NickFjdGl2ZSgmaEFhY0VuY29kZXItPmFhY0NvbmZpZykgKSB7CgogICAgICAgIElOVCBuUGF5bG9hZCA9IDA7CgogICAgICAgIC8qCiAgICAgICAgICogRW5jb2RlIFNCUiBkYXRhLgogICAgICAgICAqLwogICAgICAgIGlmIChzYnJFbmNvZGVyX0VuY29kZUZyYW1lKGhBYWNFbmNvZGVyLT5oRW52RW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZVtuUGF5bG9hZF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWREYXRhW25QYXlsb2FkXQojaWYgZGVmaW5lZChFVkFMX1BBQ0tBR0VfU0lMRU5DRSkgfHwgZGVmaW5lZChFVkFMX1BBQ0tBR0VfU0JSX1NJTEVOQ0UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsaEFhY0VuY29kZXItPmhBYWNFbmMtPmNsZWFyT3V0cHV0CiNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKICAgICAgICB7CiAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRVJST1I7CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qIEFkZCBTQlIgZXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8ICg4KTsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplW25QYXlsb2FkXVtpXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10ucERhdGEgICAgPSBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZERhdGFbblBheWxvYWRdW2ldOwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhU2l6ZSA9IGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZVtuUGF5bG9hZF1baV07CiAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uYXNzb2NpYXRlZENoRWxlbWVudCA9IGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhVHlwZSA9IEVYVF9TQlJfREFUQTsgIC8qIE9uY2UgU0JSIEVuY29kZXIgc3VwcG9ydHMgU0JSIENSQyBzZXQgRVhUX1NCUl9EQVRBX0NSQyAqLwogICAgICAgICAgICAgICAgICAgIG5FeHRlbnNpb25zKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9yIEVYVF9TQlJfREFUQSBhY2NvcmRpbmcgdG8gY29uZmlndXJhdGlvbi4gKi8KICAgICAgICAgICAgICAgICAgICBGREtfQVNTRVJUKG5FeHRlbnNpb25zPD1NQVhfVE9UQUxfRVhUX1BBWUxPQURTKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBuUGF5bG9hZCsrOwogICAgICAgIH0KICAgIH0gLyogc2JyRW5hYmxlZCAqLwoKICAgIGlmICggKGluYXJncy0+bnVtQW5jQnl0ZXMgPiAwKSAmJiAoIGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX0FOQ0lMTFJZX0RBVEEpIT0tMSApICkgewogICAgICAgIElOVCBpZHggPSBnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9BTkNJTExSWV9EQVRBKTsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uZGF0YVNpemUgPSBpbmFyZ3MtPm51bUFuY0J5dGVzICogODsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10ucERhdGEgICAgPSAoVUNIQVIqKWluQnVmRGVzYy0+YnVmc1tpZHhdOwogICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhVHlwZSA9IEVYVF9EQVRBX0VMRU1FTlQ7CiAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmFzc29jaWF0ZWRDaEVsZW1lbnQgPSAtMTsKICAgICAgICBhbmNEYXRhRXh0SWR4ID0gbkV4dGVuc2lvbnM7IC8qIHN0b3JlIGluZGV4ICovCiAgICAgICAgbkV4dGVuc2lvbnMrKzsKICAgIH0KCiAgICAvKgogICAgICogRW5jb2RlIEFBQyAtIENvcmUuCiAgICAgKi8KICAgIGlmICggRkRLYWFjRW5jX0VuY29kZUZyYW1lKCBoQWFjRW5jb2Rlci0+aEFhY0VuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRCeXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgIT0gQUFDX0VOQ19PSyApCiAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX0VOQ09ERV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgaWYgKGFuY0RhdGFFeHRJZHggPj0gMCkgewogICAgICBvdXRhcmdzLT5udW1BbmNCeXRlcyA9IGluYXJncy0+bnVtQW5jQnl0ZXMgLSAoaEFhY0VuY29kZXItPmV4dFBheWxvYWRbYW5jRGF0YUV4dElkeF0uZGF0YVNpemU+PjMpOwogICAgfQoKICAgIC8qIHNhbXBsZXMgZXhoYXVzdGVkICovCiAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkIC09IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZDsKCiAgICAvKgogICAgICogRGVsYXkgYmFsYW5jaW5nIGJ1ZmZlciBoYW5kbGluZwogICAgICovCiAgICBpZiAoaXNTYnJBY3RpdmUoJmhBYWNFbmNvZGVyLT5hYWNDb25maWcpKSB7CiAgICAgICAgc2JyRW5jb2Rlcl9VcGRhdGVCdWZmZXJzKGhBYWNFbmNvZGVyLT5oRW52RW5jLCBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIpOwogICAgfQoKICAgIC8qCiAgICAgKiBNYWtlIGJpdHN0cmVhbSBwdWJsaWMKICAgICAqLwogICAgaWYgKG91dEJ1ZkRlc2MtPm51bUJ1ZnM+PTEpIHsKCiAgICAgICAgSU5UIGJzSWR4ID0gZ2V0QnVmRGVzY0lkeChvdXRCdWZEZXNjLE9VVF9CSVRTVFJFQU1fREFUQSk7CiAgICAgICAgSU5UIGF1SWR4ID0gZ2V0QnVmRGVzY0lkeChvdXRCdWZEZXNjLE9VVF9BVV9TSVpFUyk7CgogICAgICAgIGZvciAoaT0wLG5Cc0J5dGVzPTA7IGk8aEFhY0VuY29kZXItPmFhY0NvbmZpZy5uU3ViRnJhbWVzOyBpKyspIHsKICAgICAgICAgIG5Cc0J5dGVzICs9IG91dEJ5dGVzW2ldOwoKICAgICAgICAgIGlmIChhdUlkeCE9LTEpIHsKICAgICAgICAgICAoKElOVCopb3V0QnVmRGVzYy0+YnVmc1thdUlkeF0pW2ldID0gb3V0Qnl0ZXNbaV07CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIChic0lkeCE9LTEpICYmIChvdXRCdWZEZXNjLT5idWZTaXplc1tic0lkeF0+PW5Cc0J5dGVzKSApIHsKICAgICAgICAgIEZES21lbWNweShvdXRCdWZEZXNjLT5idWZzW2JzSWR4XSwgaEFhY0VuY29kZXItPm91dEJ1ZmZlciwgc2l6ZW9mKFVDSEFSKSpuQnNCeXRlcyk7CiAgICAgICAgICBvdXRhcmdzLT5udW1PdXRCeXRlcyA9IG5Cc0J5dGVzOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIC8qIG91dHB1dCBidWZmZXIgdG9vIHNtYWxsLCBjYW4ndCB3cml0ZSB2YWxpZCBiaXRzdHJlYW0gKi8KICAgICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRVJST1I7CiAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgfQoKYmFpbDoKICAgIGlmIChlcnIgPT0gQUFDRU5DX0VOQ09ERV9FUlJPUikgewogICAgICAgIC8qIEFsbCBlbmNvZGVyIG1vZHVsZXMgaGF2ZSB0byBiZSBpbml0aWFsaXplZCAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgPSBBQUNFTkNfSU5JVF9BTEw7CiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKc3RhdGljCkFBQ19FTkNPREVSX0VSUk9SIGFhY0VuY0dldENvbmYoSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICpzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICpjb25mQnVmZmVyKQp7CiAgICBGREtfQklUU1RSRUFNIHRtcENvbmY7CiAgICBVSU5UIGNvbmZUeXBlOwogICAgVUNIQVIgYnVmWzY0XTsKICAgIGludCBlcnI7CgogICAgLyogSW5pdCBiaXQgYnVmZmVyICovCiAgICBGREtpbml0Qml0U3RyZWFtKCZ0bXBDb25mLCBidWYsIDY0LCAwLCBCU19XUklURVIpOwoKICAgIC8qIHdyaXRlIGNvbmYgaW4gdG1wIGJ1ZmZlciAqLwogICAgZXJyID0gdHJhbnNwb3J0RW5jX0dldENvbmYoaEFhY0VuY29kZXItPmhUcEVuYywgJmhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZywgJnRtcENvbmYsICZjb25mVHlwZSk7CgogICAgLyogY29weSBkYXRhIHRvIG91dGJ1ZmZlcjogbGVuZ3RoIGluIGJ5dGVzICovCiAgICBGREtieXRlQWxpZ24oJnRtcENvbmYsIDApOwoKICAgIC8qIENoZWNrIGJ1ZmZlciBzaXplICovCiAgICBpZiAoRkRLZ2V0VmFsaWRCaXRzKCZ0bXBDb25mKSA+ICgoKnNpemUpPDwzKSkKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5LTk9XTjsKCiAgICBGREtmZXRjaEJ1ZmZlcigmdG1wQ29uZiwgY29uZkJ1ZmZlciwgc2l6ZSk7CgogICAgaWYgKGVyciAhPSAwKQogICAgICByZXR1cm4gQUFDX0VOQ19VTktOT1dOOwogICAgZWxzZQogICAgICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKCkFBQ0VOQ19FUlJPUiBhYWNFbmNHZXRMaWJJbmZvKExJQl9JTkZPICppbmZvKQp7CiAgaW50IGkgPSAwOwoKICBpZiAoaW5mbyA9PSBOVUxMKSB7CiAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfSEFORExFOwogIH0KCiAgRkRLX3Rvb2xzR2V0TGliSW5mbyggaW5mbyApOwogIHRyYW5zcG9ydEVuY19HZXRMaWJJbmZvKCBpbmZvICk7CgogIHNickVuY29kZXJfR2V0TGliSW5mbyggaW5mbyApOwoKICAvKiBzZWFyY2ggZm9yIG5leHQgZnJlZSB0YWIgKi8KICBmb3IgKGkgPSAwOyBpIDwgRkRLX01PRFVMRV9MQVNUOyBpKyspIHsKICAgIGlmIChpbmZvW2ldLm1vZHVsZV9pZCA9PSBGREtfTk9ORSkgYnJlYWs7CiAgfQogIGlmIChpID09IEZES19NT0RVTEVfTEFTVCkgewogICAgcmV0dXJuIEFBQ0VOQ19JTklUX0VSUk9SOwogIH0KCiAgaW5mb1tpXS5tb2R1bGVfaWQgPSBGREtfQUFDRU5DOwogIGluZm9baV0uYnVpbGRfZGF0ZSA9IChjaGFyKilBQUNFTkNPREVSX0xJQl9CVUlMRF9EQVRFOwogIGluZm9baV0uYnVpbGRfdGltZSA9IChjaGFyKilBQUNFTkNPREVSX0xJQl9CVUlMRF9USU1FOwogIGluZm9baV0udGl0bGUgPSAoY2hhciopQUFDRU5DT0RFUl9MSUJfVElUTEU7CiAgaW5mb1tpXS52ZXJzaW9uID0gTElCX1ZFUlNJT04oQUFDRU5DT0RFUl9MSUJfVkwwLCBBQUNFTkNPREVSX0xJQl9WTDEsIEFBQ0VOQ09ERVJfTElCX1ZMMik7OwogIExJQl9WRVJTSU9OX1NUUklORygmaW5mb1tpXSk7CgogIC8qIENhcGFiaWxpdHkgZmxhZ3MgKi8KICBpbmZvW2ldLmZsYWdzID0gMAogICAgfCBDQVBGX0FBQ18xMDI0IHwgQ0FQRl9BQUNfTEMKICAgIHwgQ0FQRl9BQUNfNTEyCiAgICB8IENBUEZfQUFDXzQ4MAogICAgfCBDQVBGX0FBQ19EUkMKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gQUFDRU5DX09LOwp9CgpBQUNFTkNfRVJST1IgYWFjRW5jb2Rlcl9TZXRQYXJhbSgKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IEFBQ0VOQ19QQVJBTSAgICAgICAgcGFyYW0sCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICB2YWx1ZQogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKICAgIFVTRVJfUEFSQU0gKnNldHRpbmdzID0gJmhBYWNFbmNvZGVyLT5leHRQYXJhbTsKCiAgICAvKiBjaGVjayBlbmNvZGVyIGhhbmRsZSAqLwogICAgaWYgKGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIGFwcGx5IHBhcmFtIHZhbHVlICovCiAgICBzd2l0Y2ggKHBhcmFtKQogICAgewogICAgY2FzZSBBQUNFTkNfQU9UOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckFPVCAhPSAoQVVESU9fT0JKRUNUX1RZUEUpdmFsdWUpIHsKICAgICAgICAgICAgLyogY2hlY2sgaWYgQU9UIG1hdGNoZXMgdGhlIGFsbG9jYXRlZCBtb2R1bGVzICovCiAgICAgICAgICAgIHN3aXRjaCAoIHZhbHVlICkgewogICAgICAgICAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19QUykpKSB7CiAgICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICAgICAgICAgIGlmICghKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzICYgKEVOQ19NT0RFX0ZMQUdfU0JSKSkpIHsKICAgICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19BQUMpKSkgewogICAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgIH0vKiBzd2l0Y2ggdmFsdWUgKi8KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBT1QgPSAoQVVESU9fT0JKRUNUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckJpdHJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURU1PREU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc3dpdGNoICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNhc2UgMTogY2FzZSAyOiBjYXNlIDM6IGNhc2UgNDogY2FzZSA1OgogICAgICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8qIHN3aXRjaCB2YWx1ZSAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NBTVBMRVJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2FtcGxlcmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoICh2YWx1ZT09ODAwMCkgfHwgKHZhbHVlPT0xMTAyNSkgfHwgKHZhbHVlPT0xMjAwMCkgfHwgKHZhbHVlPT0xNjAwMCkgfHwgKHZhbHVlPT0yMjA1MCkgfHwgKHZhbHVlPT0yNDAwMCkgfHwKICAgICAgICAgICAgICAgICAgICh2YWx1ZT09MzIwMDApIHx8ICh2YWx1ZT09NDQxMDApIHx8ICh2YWx1ZT09NDgwMDApIHx8ICh2YWx1ZT09NjQwMDApIHx8ICh2YWx1ZT09ODgyMDApIHx8ICh2YWx1ZT09OTYwMDApICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclNhbXBsZXJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7IC8qIHJlc2V0IGludGVybmFsIGlucHV0YnVmZmVyICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NIQU5ORUxNT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckNoYW5uZWxNb2RlICE9IChDSEFOTkVMX01PREUpdmFsdWUpIHsKICAgICAgICAgICAgY29uc3QgQ0hBTk5FTF9NT0RFX0NPTkZJR19UQUIqIHBDb25maWcgPSBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKChDSEFOTkVMX01PREUpdmFsdWUpOwogICAgICAgICAgICBpZiAocENvbmZpZz09TlVMTCkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAocENvbmZpZy0+bkVsZW1lbnRzID4gaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cykKICAgICAgICAgICAgICB8fCAocENvbmZpZy0+bkNoYW5uZWxzRWZmID4gaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscykKICAgICAgICAgICAgICB8fCAhKCgodmFsdWU+PTEpICYmICh2YWx1ZTw9NykpfHwoKHZhbHVlPj0zMykgJiYgKHZhbHVlPD0zNCkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJDaGFubmVsTW9kZSA9IChDSEFOTkVMX01PREUpdmFsdWU7CiAgICAgICAgICAgIHNldHRpbmdzLT5uQ2hhbm5lbHMgPSBwQ29uZmlnLT5uQ2hhbm5lbHM7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOyAvKiByZXNldCBpbnRlcm5hbCBpbnB1dGJ1ZmZlciAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CQU5EV0lEVEg6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQmFuZHdpZHRoICE9IHZhbHVlKSB7CiAgICAgICAgICBzZXR0aW5ncy0+dXNlckJhbmR3aWR0aCA9IHZhbHVlOwogICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ0hBTk5FTE9SREVSOgogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlciAhPSAoQ0hBTk5FTF9PUkRFUil2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5hYWNDb25maWcuY2hhbm5lbE9yZGVyID0gKENIQU5ORUxfT1JERVIpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOyAvKiByZXNldCBpbnRlcm5hbCBpbnB1dGJ1ZmZlciAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19BRlRFUkJVUk5FUjoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJBZnRlcmJ1cm5lciAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQWZ0ZXJidXJuZXIgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfR1JBTlVMRV9MRU5HVEg6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyRnJhbWVsZW5ndGggIT0gdmFsdWUpIHsKICAgICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgICAgY2FzZSAxMDI0OgogICAgICAgICAgICBjYXNlIDUxMjoKICAgICAgICAgICAgY2FzZSA0ODA6CiAgICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJGcmFtZWxlbmd0aCA9IHZhbHVlOwogICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfUkFUSU86CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2JyUmF0aW8gIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCEgKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSB8fCAodmFsdWU9PTIpKSApIHsKICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJTYnJSYXRpbyA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfTU9ERToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJTYnJFbmFibGVkICE9IHZhbHVlKSB7CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyU2JyRW5hYmxlZCA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUkFOU01VWDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcFR5cGUgIT0gKFRSQU5TUE9SVF9UWVBFKXZhbHVlKSB7CgogICAgICAgICAgICBUUkFOU1BPUlRfVFlQRSAgdHlwZSAgPSAoVFJBTlNQT1JUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIFVJTlQgICAgICAgICAgICBmbGFncyA9IGhBYWNFbmNvZGVyLT5DQVBGX3RwRW5jOwoKICAgICAgICAgICAgaWYgKCAhKCAoKHR5cGU9PVRUX01QNF9BRElGKSAgICAgICYmICAoZmxhZ3MmQ0FQRl9BRElGKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9BRFRTKSAgICAgICYmICAoZmxhZ3MmQ0FQRl9BRFRTKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9MQVRNX01DUDApICYmICgoZmxhZ3MmQ0FQRl9MQVRNKSAmJiAoZmxhZ3MmQ0FQRl9SQVdQQUNLRVRTKSkpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfTEFUTV9NQ1AxKSAmJiAoKGZsYWdzJkNBUEZfTEFUTSkgJiYgKGZsYWdzJkNBUEZfUkFXUEFDS0VUUykpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X0xPQVMpICAgICAgJiYgIChmbGFncyZDQVBGX0xPQVMpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X1JBVykgICAgICAgJiYgIChmbGFncyZDQVBGX1JBV1BBQ0tFVFMpKQogICAgICAgICAgICAgICAgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBUeXBlID0gKFRSQU5TUE9SVF9UWVBFKXZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TSUdOQUxJTkdfTU9ERToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpIHx8ICh2YWx1ZT09MikpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZyA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19QUk9URUNUSU9OOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwUHJvdGVjdGlvbiAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBQcm90ZWN0aW9uID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0hFQURFUl9QRVJJT0Q6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBIZWFkZXJQZXJpb2QgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcEhlYWRlclBlcmlvZCA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19BVURJT01VWFZFUjoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcEFteHYgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAhKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSB8fCAodmFsdWU9PTIpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBBbXh2ID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1RQU1VCRlJBTUVTOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwTnN1YkZyYW1lcyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoICh2YWx1ZT49MSkgJiYgKHZhbHVlPD00KSApICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcE5zdWJGcmFtZXMgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQU5DSUxMQVJZX0JJVFJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQW5jRGF0YVJhdGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBbmNEYXRhUmF0ZSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NPTlRST0xfU1RBVEU6CiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlJkFBQ0VOQ19SRVNFVF9JTkJVRkZFUikgewogICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX01PREU6CiAgICAgICAgaWYgKChVSU5UKXNldHRpbmdzLT51c2VyTWV0YURhdGFNb2RlICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICggISgoKElOVCl2YWx1ZT49MCkgJiYgKChJTlQpdmFsdWU8PTIpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyTWV0YURhdGFNb2RlID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1BFQUtfQklUUkFURToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJQZWFrQml0cmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclBlYWtCaXRyYXRlID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGVyciA9IEFBQ0VOQ19VTlNVUFBPUlRFRF9QQVJBTUVURVI7CiAgICAgIGJyZWFrOwogICAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KClVJTlQgYWFjRW5jb2Rlcl9HZXRQYXJhbSgKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IEFBQ0VOQ19QQVJBTSAgICAgICAgcGFyYW0KICAgICAgICApCnsKICAgIFVJTlQgdmFsdWUgPSAwOwogICAgVVNFUl9QQVJBTSAqc2V0dGluZ3MgPSAmaEFhY0VuY29kZXItPmV4dFBhcmFtOwoKICAgIC8qIGNoZWNrIGVuY29kZXIgaGFuZGxlICovCiAgICBpZiAoaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhcHBseSBwYXJhbSB2YWx1ZSAqLwogICAgc3dpdGNoIChwYXJhbSkKICAgIHsKICAgIGNhc2UgQUFDRU5DX0FPVDoKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuYXVkaW9PYmplY3RUeXBlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURToKICAgICAgICB2YWx1ZSA9IChVSU5UKSgoaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iaXRyYXRlTW9kZT09QUFDRU5DX0JSX01PREVfQ0JSKSA/IGhBYWNFbmNvZGVyLT5hYWNDb25maWcuYml0UmF0ZSA6IC0xKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEVNT0RFOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iaXRyYXRlTW9kZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NBTVBMRVJBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+Y29kZXJDb25maWcuZXh0U2FtcGxpbmdSYXRlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ0hBTk5FTE1PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxNb2RlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQkFORFdJRFRIOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iYW5kV2lkdGg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMT1JERVI6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlcjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FGVEVSQlVSTkVSOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy51c2VSZXF1YW50OwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfR1JBTlVMRV9MRU5HVEg6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmZyYW1lbGVuZ3RoOwogICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfUkFUSU86CiAgICAgICAgdmFsdWUgPSBpc1NickFjdGl2ZSgmaEFhY0VuY29kZXItPmFhY0NvbmZpZykgPyBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnNiclJhdGlvIDogMDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NCUl9NT0RFOgogICAgICAgIHZhbHVlID0gKFVJTlQpIChoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnN5bnRheEZsYWdzICYgQUNfU0JSX1BSRVNFTlQpID8gMSA6IDA7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUkFOU01VWDoKICAgICAgICB2YWx1ZSA9IChVSU5UKXNldHRpbmdzLT51c2VyVHBUeXBlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0lHTkFMSU5HX01PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVClnZXRTYnJTaWduYWxpbmdNb2RlKGhBYWNFbmNvZGVyLT5hYWNDb25maWcuYXVkaW9PYmplY3RUeXBlLCBzZXR0aW5ncy0+dXNlclRwVHlwZSwgc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZywgaEFhY0VuY29kZXItPmFhY0NvbmZpZy5zYnJSYXRpbyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19QUk9URUNUSU9OOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJUcFByb3RlY3Rpb247CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19IRUFERVJfUEVSSU9EOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLmhlYWRlclBlcmlvZDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FVRElPTVVYVkVSOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5hdWRpb011eFZlcnNpb247CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUFNVQkZSQU1FUzoKICAgICAgICB2YWx1ZSA9IChVSU5UKXNldHRpbmdzLT51c2VyVHBOc3ViRnJhbWVzOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQU5DSUxMQVJZX0JJVFJBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmFuY19SYXRlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ09OVFJPTF9TVEFURToKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5Jbml0RmxhZ3M7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9NT0RFOgogICAgICAgIHZhbHVlID0gKGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQ9PTApID8gMCA6IChVSU5UKXNldHRpbmdzLT51c2VyTWV0YURhdGFNb2RlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfUEVBS19CSVRSQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpLTE7IC8qIHBlYWsgYml0cmF0ZSBwYXJhbWV0ZXIgaXMgbWVhbmluZ2xlc3MgKi8KICAgICAgICBpZiAoICgoSU5UKWhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyUGVha0JpdHJhdGUhPS0xKSApIHsKICAgICAgICAgIHZhbHVlID0gKFVJTlQpKGZNYXgoKElOVCloQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlclBlYWtCaXRyYXRlLCBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmJpdFJhdGUpKTsgLyogcGVhayBiaXRyYXRlIHBhcmFtZXRlciBpcyBpbiB1c2UgKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAvL2VyciA9IE1QU19JTlZBTElEX1BBUkFNRVRFUjsKICAgICAgYnJlYWs7CiAgICB9ICAvKiBzd2l0Y2gocGFyYW0pICovCgpiYWlsOgogICAgcmV0dXJuIHZhbHVlOwp9CgpBQUNFTkNfRVJST1IgYWFjRW5jSW5mbygKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIEFBQ0VOQ19JbmZvU3RydWN0ICAgICAgICAqcEluZm8KICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgRkRLbWVtY2xlYXIocEluZm8sIHNpemVvZihBQUNFTkNfSW5mb1N0cnVjdCkpOwogICAgcEluZm8tPmNvbmZTaXplID0gNjQ7IC8qIHByZS1pbml0aWFsaXplICovCgogICAgcEluZm8tPm1heE91dEJ1ZkJ5dGVzICAgID0gKChoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKjYxNDQpKzcpPj4zOwogICAgcEluZm8tPm1heEFuY0J5dGVzICAgICAgID0gaEFhY0VuY29kZXItPmFhY0NvbmZpZy5tYXhBbmNCeXRlc1BlckFVOwogICAgcEluZm8tPmluQnVmRmlsbExldmVsICAgID0gaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZC9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmlucHV0Q2hhbm5lbHMgICAgID0gaEFhY0VuY29kZXItPmV4dFBhcmFtLm5DaGFubmVsczsKICAgIHBJbmZvLT5mcmFtZUxlbmd0aCAgICAgICA9IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZC9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmVuY29kZXJEZWxheSAgICAgID0gaEFhY0VuY29kZXItPm5EZWxheS9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwoKICAgIC8qIEdldCBlbmNvZGVyIGNvbmZpZ3VyYXRpb24gKi8KICAgIGlmICggYWFjRW5jR2V0Q29uZihoQWFjRW5jb2RlciwgJnBJbmZvLT5jb25mU2l6ZSwgJnBJbmZvLT5jb25mQnVmWzBdKSAhPSBBQUNfRU5DX09LKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOSVRfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQpiYWlsOgogICAgcmV0dXJuIGVycjsKfQoK