Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgU0JSIGRlY29kZXIgZnJvbnRlbmQKICBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIGZyb250ZW5kIHRvIHRoZSBTQlIgZGVjb2Rlci4gVGhlIGZ1bmN0aW9uIG9wZW5TQlIoKSBpcyBjYWxsZWQgZm9yCiAgaW5pdGlhbGl6YXRpb24uIFRoZSBmdW5jdGlvbiBzYnJEZWNvZGVyX0FwcGx5KCkgaXMgY2FsbGVkIGZvciBlYWNoIGZyYW1lLiBzYnJfQXBwbHkoKSB3aWxsIGNhbGwgdGhlCiAgcmVxdWlyZWQgZnVuY3Rpb25zIHRvIGRlY29kZSB0aGUgcmF3IFNCUiBkYXRhIChwcm92aWRlZCBieSBlbnZfZXh0ci5jcHApLCB0byBkZWNvZGUgdGhlIGVudmVsb3BlIGRhdGEgYW5kIG5vaXNlIGZsb29yIGxldmVscyBbZGVjb2RlU2JyRGF0YSgpXSwKICBhbmQgdG8gZmluYWxseSBhcHBseSBTQlIgdG8gdGhlIGN1cnJlbnQgZnJhbWUgW3Nicl9kZWMoKV0uCgogIFxzYSBzYnJEZWNvZGVyX0FwcGx5KCksIFxyZWYgZG9jdW1lbnRhdGlvbk92ZXJ2aWV3CiovCgovKiEKICBccGFnZSBkb2N1bWVudGF0aW9uT3ZlcnZpZXcgT3ZlcnZpZXcgb2YgaW1wb3J0YW50IGluZm9ybWF0aW9uIHJlc291cmNlcyBhbmQgc291cmNlIGNvZGUgZG9jdW1lbnRhdGlvbgoKICBUaGUgcHJpbWFyeSBzb3VyY2UgY29kZSBkb2N1bWVudGF0aW9uIGlzIGJhc2VkIG9uIGdlbmVyYXRlZCBhbmQgY3Jvc3MtcmVmZXJlbmNlZCBIVE1MIGZpbGVzIHVzaW5nCiAgPGEgSFJFRj0iaHR0cDovL3d3dy5kb3h5Z2VuLm9yZyI+ZG94eWdlbjwvYT4uIEFzIHBhcnQgb2YgdGhpcyBkb2N1bWVudGF0aW9uCiAgeW91IGNhbiBmaW5kIG1vcmUgZXh0ZW5zaXZlIGRlc2NyaXB0aW9ucyBhYm91dCBrZXkgY29uY2VwdHMgYW5kIGFsZ29yaXRobXMgYXQgdGhlIGZvbGxvd2luZyBsb2NhdGlvbnM6CgogIDxoMj5Qcm9ncmFtbWluZzwvaDI+CgogIFxsaSBCdWZmZXIgbWFuYWdlbWVudDogc2JyRGVjb2Rlcl9BcHBseSgpIGFuZCBzYnJfZGVjKCkKICBcbGkgSW50ZXJuYWwgc2NhbGUgZmFjdG9ycyB0byBtYXhpbWl6ZSBTTlIgb24gZml4ZWQgcG9pbnQgcHJvY2Vzc29yczogI1FNRl9TQ0FMRV9GQUNUT1IKICBcbGkgU3BlY2lhbCBtYW50aXNzYS1leHBvbmVudCBmb3JtYXQ6IENyZWF0ZWQgaW4gcmVxdWFudGl6ZUVudmVsb3BlRGF0YSgpIGFuZCB1c2VkIGluIGNhbGN1bGF0ZVNickVudmVsb3BlKCkKCiAgPGgyPkFsZ29yaXRobWljIGRldGFpbHM8L2gyPgogIFxsaSBBYm91dCB0aGUgU0JSIGRhdGEgZm9ybWF0OiBccmVmIFNCUl9IRUFERVJfRUxFTUVOVCBhbmQgXHJlZiBTQlJfU1RBTkRBUkRfRUxFTUVOVAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSBiaXRzdHJlYW0gZGVjb2RlcjogZW52X2V4dHIuY3BwCiAgXGxpIERldGFpbHMgYWJvdXQgdGhlIFFNRiBmaWx0ZXJiYW5rIGFuZCB0aGUgcHJvdmlkZWQgcG9seXBoYXNlIGltcGxlbWVudGF0aW9uOiBxbWZfZGVjLmNwcAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSB0cmFuc3Bvc2VyOiBscHBfdHJhbi5jcHAKICBcbGkgRGV0YWlscyBhYm91dCB0aGUgZW52ZWxvcGUgYWRqdXN0ZXI6IGVudl9jYWxjLmNwcAoKKi8KCiNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgojaW5jbHVkZSAiRkRLX2JpdHN0cmVhbS5oIgoKI2luY2x1ZGUgInNicmRlY19mcmVxX3NjYS5oIgojaW5jbHVkZSAiZW52X2V4dHIuaCIKI2luY2x1ZGUgInNicl9kZWMuaCIKI2luY2x1ZGUgImVudl9kZWMuaCIKI2luY2x1ZGUgInNicl9jcmMuaCIKI2luY2x1ZGUgInNicl9yYW0uaCIKI2luY2x1ZGUgInNicl9yb20uaCIKI2luY2x1ZGUgImxwcF90cmFuLmgiCiNpbmNsdWRlICJ0cmFuc2NlbmRlbnQuaCIKCiNpbmNsdWRlICJGREtfY3JjLmgiCgojaW5jbHVkZSAic2JyZGVjX2RyYy5oIgoKI2luY2x1ZGUgInBzYml0ZGVjLmgiCgoKLyogRGVjb2RlciBsaWJyYXJ5IGluZm8gKi8KI2RlZmluZSBTQlJERUNPREVSX0xJQl9WTDAgMgojZGVmaW5lIFNCUkRFQ09ERVJfTElCX1ZMMSAyCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfVkwyIDEyCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfVElUTEUgIlNCUiBEZWNvZGVyIgojaWZkZWYgX19BTkRST0lEX18KI2RlZmluZSBTQlJERUNPREVSX0xJQl9CVUlMRF9EQVRFICIiCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfQlVJTERfVElNRSAiIgojZWxzZQojZGVmaW5lIFNCUkRFQ09ERVJfTElCX0JVSUxEX0RBVEUgX19EQVRFX18KI2RlZmluZSBTQlJERUNPREVSX0xJQl9CVUlMRF9USU1FIF9fVElNRV9fCiNlbmRpZgoKCgoKc3RhdGljIFVDSEFSIGdldEhlYWRlclNsb3QoIFVDSEFSIGN1cnJlbnRTbG90LCBVQ0hBUiBoZHJTbG90VXNhZ2VbKDEpKzFdICkKewogIFVJTlQgIG9jY3VwaWVkID0gMDsKICBpbnQgICBzOwogIFVDSEFSIHNsb3QgPSBoZHJTbG90VXNhZ2VbY3VycmVudFNsb3RdOwoKICBGREtfQVNTRVJUKCgxKSsxIDwgMzIpOwoKICBmb3IgKHMgPSAwOyBzIDwgKDEpKzE7IHMrKykgewogICAgaWYgKCAoaGRyU2xvdFVzYWdlW3NdID09IHNsb3QpCiAgICAgICYmIChzICE9IHNsb3QpICkgewogICAgICBvY2N1cGllZCA9IDE7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgaWYgKG9jY3VwaWVkKSB7CiAgICBvY2N1cGllZCA9IDA7CgogICAgZm9yIChzID0gMDsgcyA8ICgxKSsxOyBzKyspIHsKICAgICAgb2NjdXBpZWQgfD0gMSA8PCBoZHJTbG90VXNhZ2Vbc107CiAgICB9CiAgICBmb3IgKHMgPSAwOyBzIDwgKDEpKzE7IHMrKykgewogICAgICBpZiAoICEob2NjdXBpZWQgJiAweDEpICkgewogICAgICAgIHNsb3QgPSBzOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIG9jY3VwaWVkID4+PSAxOwogICAgfQogIH0KCiAgcmV0dXJuIHNsb3Q7Cn0KCnN0YXRpYyB2b2lkIGNvcHlTYnJIZWFkZXIoIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaERzdCwgY29uc3QgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU3JjICkKewogIC8qIGNvcHkgdGhlIHdob2xlIGhlYWRlciBtZW1vcnkgKGluY2x1ZGluZyBwb2ludGVycykgKi8KICBGREttZW1jcHkoIGhEc3QsIGhTcmMsIHNpemVvZihTQlJfSEVBREVSX0RBVEEpICk7CgogIC8qIHVwZGF0ZSBwb2ludGVycyAqLwogIGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlWzBdICA9IGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlTG87CiAgaERzdC0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVbMV0gPSBoRHN0LT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZUhpOwp9CgpzdGF0aWMgaW50IGNvbXBhcmVTYnJIZWFkZXIoIGNvbnN0IEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhkcjEsIGNvbnN0IEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhkcjIgKQp7CiAgaW50IHJlc3VsdCA9IDA7CgogIC8qIGNvbXBhcmUgYmFzaWMgZGF0YSAqLwogIHJlc3VsdCB8PSAoaEhkcjEtPnN5bmNTdGF0ZSAhPSBoSGRyMi0+c3luY1N0YXRlKSA/IDEgOiAwOwogIHJlc3VsdCB8PSAoaEhkcjEtPnN0YXR1cyAhPSBoSGRyMi0+c3RhdHVzKSA/IDEgOiAwOwogIHJlc3VsdCB8PSAoaEhkcjEtPmZyYW1lRXJyb3JGbGFnICE9IGhIZHIyLT5mcmFtZUVycm9yRmxhZykgPyAxIDogMDsKICByZXN1bHQgfD0gKGhIZHIxLT5udW1iZXJUaW1lU2xvdHMgIT0gaEhkcjItPm51bWJlclRpbWVTbG90cykgPyAxIDogMDsKICByZXN1bHQgfD0gKGhIZHIxLT5udW1iZXJPZkFuYWx5c2lzQmFuZHMgIT0gaEhkcjItPm51bWJlck9mQW5hbHlzaXNCYW5kcykgPyAxIDogMDsKICByZXN1bHQgfD0gKGhIZHIxLT50aW1lU3RlcCAhPSBoSGRyMi0+dGltZVN0ZXApID8gMSA6IDA7CiAgcmVzdWx0IHw9IChoSGRyMS0+c2JyUHJvY1NtcGxSYXRlICE9IGhIZHIyLT5zYnJQcm9jU21wbFJhdGUpID8gMSA6IDA7CgogIC8qIGNvbXBhcmUgYml0c3RyZWFtIGRhdGEgKi8KICByZXN1bHQgfD0gRkRLbWVtY21wKCAmaEhkcjEtPmJzX2RhdGEsICZoSGRyMi0+YnNfZGF0YSwgc2l6ZW9mKFNCUl9IRUFERVJfREFUQV9CUykgKTsKICByZXN1bHQgfD0gRkRLbWVtY21wKCAmaEhkcjEtPmJzX2luZm8sICZoSGRyMi0+YnNfaW5mbywgc2l6ZW9mKFNCUl9IRUFERVJfREFUQV9CU19JTkZPKSApOwoKICAvKiBjb21wYXJlIGZyZXF1ZW5jeSBiYW5kIGRhdGEgKi8KICByZXN1bHQgfD0gRkRLbWVtY21wKCAmaEhkcjEtPmZyZXFCYW5kRGF0YSwgJmhIZHIyLT5mcmVxQmFuZERhdGEsICg4K01BWF9OVU1fTElNSVRFUlMrMSkqc2l6ZW9mKFVDSEFSKSApOwogIHJlc3VsdCB8PSBGREttZW1jbXAoIGhIZHIxLT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZUxvLCBoSGRyMi0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVMbywgKE1BWF9GUkVRX0NPRUZGUy8yKzEpKnNpemVvZihVQ0hBUikgKTsKICByZXN1bHQgfD0gRkRLbWVtY21wKCBoSGRyMS0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVIaSwgaEhkcjItPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlSGksIChNQVhfRlJFUV9DT0VGRlMrMSkqc2l6ZW9mKFVDSEFSKSApOwogIHJlc3VsdCB8PSBGREttZW1jbXAoIGhIZHIxLT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZU5vaXNlLCBoSGRyMi0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVOb2lzZSwgKE1BWF9OT0lTRV9DT0VGRlMrMSkqc2l6ZW9mKFVDSEFSKSApOwogIHJlc3VsdCB8PSBGREttZW1jbXAoIGhIZHIxLT5mcmVxQmFuZERhdGEudl9rX21hc3RlciwgaEhkcjItPmZyZXFCYW5kRGF0YS52X2tfbWFzdGVyLCAoTUFYX0ZSRVFfQ09FRkZTKzEpKnNpemVvZihVQ0hBUikgKTsKCiAgcmV0dXJuIHJlc3VsdDsKfQoKCi8qIQogIFxicmllZiBSZXNldCBTQlIgZGVjb2Rlci4KCiAgUmVzZXQgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIFNCUiBoYXMgYmVlbiBzdWNlc3NmdWxseSBkZXRlY3RlZCBieQogIGFuIGFwcHJvcHJpYXRlIGNoZWNrRm9yUGF5bG9hZCgpIGZ1bmN0aW9uLgoKICBccmV0dXJuIEVycm9yIGNvZGUuCiovCnN0YXRpYwpTQlJfRVJST1Igc2JyRGVjb2Rlcl9SZXNldEVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgIHNlbGYsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBlbGVtZW50SW5kZXgsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgb3ZlcmxhcAogICAgICAgICkKewogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgVUlOVCBxbWZGbGFncyA9IDA7CgogIGludCBpLCBzeW5Eb3duc2FtcGxlRmFjOwoKICAvKiBDaGVjayBpbi9vdXQgc2FtcGxlcmF0ZXMgKi8KICBpZiAoIHNhbXBsZVJhdGVJbiA8IDY0MDAKICAgIHx8IHNhbXBsZVJhdGVJbiA+IDQ4MDAwCiAgICAgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggc2FtcGxlUmF0ZU91dCA+IDk2MDAwICkKICB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKiBTZXQgUU1GIG1vZGUgZmxhZ3MgKi8KICBpZiAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSKQogICAgcW1mRmxhZ3MgfD0gUU1GX0ZMQUdfTFA7CgogIGlmIChzZWxmLT5jb3JlQ29kZWMgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIGlmIChzZWxmLT5mbGFncyAmIFNCUkRFQ19MRF9NUFNfUU1GKSB7CiAgICAgIHFtZkZsYWdzIHw9ICBRTUZfRkxBR19NUFNMREZCOwogICAgfSBlbHNlIHsKICAgICAgcW1mRmxhZ3MgfD0gIFFNRl9GTEFHX0NMREZCOwogICAgfQogIH0KCiAgLyogU2V0IGRvd25zYW1wbGluZyBmYWN0b3IgZm9yIHN5bnRoZXNpcyBmaWx0ZXIgYmFuayAqLwogIGlmIChzYW1wbGVSYXRlT3V0ID09IDApCiAgewogICAgLyogbm8gc2luZ2xlIHJhdGUgbW9kZSAqLwogICAgICBzYW1wbGVSYXRlT3V0ID0gc2FtcGxlUmF0ZUluPDwxOyAvKiBJbiBjYXNlIG9mIGltcGxpY2l0IHNpZ25hbGxpbmcsIGFzc3VtZSBkdWFsIHJhdGUgU0JSICovCiAgfQoKICBpZiAoIHNhbXBsZVJhdGVJbiA9PSBzYW1wbGVSYXRlT3V0ICkgewogICAgc3luRG93bnNhbXBsZUZhYyA9IDI7CiAgICBzZWxmLT5mbGFncyB8PSAgU0JSREVDX0RPV05TQU1QTEU7CiAgfSBlbHNlIHsKICAgIHN5bkRvd25zYW1wbGVGYWMgPSAxOwogICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19ET1dOU0FNUExFOwogIH0KCiAgc2VsZi0+c3luRG93bnNhbXBsZUZhYyA9IHN5bkRvd25zYW1wbGVGYWM7CiAgc2VsZi0+c2FtcGxlUmF0ZU91dCA9IHNhbXBsZVJhdGVPdXQ7CgogIHsKICAgIGludCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAoMSkrMTsgaSsrKQogICAgewogICAgICBoU2JySGVhZGVyID0gJihzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtpXSk7CgogICAgICAvKiBpbml0IGEgZGVmYXVsdCBoZWFkZXIgc3VjaCB0aGF0IHdlIGNhbiBhdCBsZWFzdCBkbyB1cHNhbXBsaW5nIGxhdGVyICovCiAgICAgIHNickVycm9yID0gaW5pdEhlYWRlckRhdGEoCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgICAgICAgc2FtcGxlUmF0ZU91dCwKICAgICAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICAgICApOwogICAgfQogIH0KCiAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgZ290byBiYWlsOwogIH0KCiAgLyogSW5pdCBTQlIgY2hhbm5lbHMgZ29pbmcgdG8gYmUgYXNzaWduZWQgdG8gYSBTQlIgZWxlbWVudCAqLwogIHsKICAgIGludCBjaDsKCiAgICBmb3IgKGNoPTA7IGNoPHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPm5DaGFubmVsczsgY2grKykKICAgIHsKICAgICAgLyogYW5kIGNyZWF0ZSBzYnJEZWMgKi8KICAgICAgc2JyRXJyb3IgPSBjcmVhdGVTYnJEZWMgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnRyYW5zcG9zZXJTZXR0aW5ncywKICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5Eb3duc2FtcGxlRmFjLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFtZkZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJsYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggKTsKCiAgICAgIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgIH0KICB9CgogIC8vRkRLbWVtY2xlYXIoc2JyX092ZXJsYXBCdWZmZXIsIHNpemVvZihzYnJfT3ZlcmxhcEJ1ZmZlcikpOwoKICBpZiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgPT0gMSkgewogICAgc3dpdGNoICggc2VsZi0+Y29yZUNvZGVjICkgewogICAgY2FzZSBBT1RfQUFDX0xDOgogICAgY2FzZSBBT1RfU0JSOgogICAgY2FzZSBBT1RfUFM6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0RSTV9BQUM6CiAgICAgIGlmIChDcmVhdGVQc0RlYyAoICZzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYywgc2FtcGxlc1BlckZyYW1lICkpIHsKICAgICAgICBzYnJFcnJvciA9IFNCUkRFQ19DUkVBVEVfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICAvKiBJbml0IGZyYW1lIGRlbGF5IHNsb3QgaGFuZGxpbmcgKi8KICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QgPSAwOwogIGZvciAoaSA9IDA7IGkgPCAoKDEpKzEpOyBpKyspIHsKICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUhlYWRlclNsb3RbaV0gPSBpOwogIH0KCmJhaWw6CgogIHJldHVybiBzYnJFcnJvcjsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX09wZW4gKCBIQU5ETEVfU0JSREVDT0RFUiAgKiBwU2VsZiApCnsKICBIQU5ETEVfU0JSREVDT0RFUiAgICBzZWxmID0gTlVMTDsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CgogIC8qIEdldCBtZW1vcnkgZm9yIHRoaXMgaW5zdGFuY2UgKi8KICBzZWxmID0gR2V0UmFtX1NickRlY29kZXIoKTsKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgZ290byBiYWlsOwogIH0KCiAgc2VsZi0+d29ya0J1ZmZlcjEgPSBHZXRSYW1fU2JyRGVjV29ya0J1ZmZlcjEoKTsKICBzZWxmLT53b3JrQnVmZmVyMiA9IEdldFJhbV9TYnJEZWNXb3JrQnVmZmVyMigpOwoKICBpZiAoICBzZWxmLT53b3JrQnVmZmVyMSA9PSBOVUxMCiAgICAgfHwgc2VsZi0+d29ya0J1ZmZlcjIgPT0gTlVMTCApCiAgewogICAgc2JyRXJyb3IgPSBTQlJERUNfTUVNX0FMTE9DX0ZBSUxFRDsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qCiAgQWxyZWFkeSB6ZXJvIGJlY2F1c2Ugb2YgY2FsbG9jCiAgc2VsZi0+bnVtU2JyRWxlbWVudHMgPSAwOwogIHNlbGYtPm51bVNickNoYW5uZWxzID0gMDsKICBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9IDA7CiAgKi8KCiAgc2VsZi0+bnVtRGVsYXlGcmFtZXMgPSAoMSk7ICAvKiBzZXQgdG8gdGhlIG1heCB2YWx1ZSBieSBkZWZhdWx0ICovCgogICpwU2VsZiA9IHNlbGY7CgpiYWlsOgogIHJldHVybiBzYnJFcnJvcjsKfQoKLyoqCiAqIFxicmllZiBkZXRlcm1pbmUgaWYgdGhlIGdpdmVuIGNvcmUgY29kZWMgQU9UIGNhbiBiZSBwcm9jZXNzZWQgb3Igbm90LgogKiBccGFyYW0gY29yZUNvZGVjIGNvcmUgY29kZWMgYXVkaW8gb2JqZWN0IHR5cGUuCiAqIFxyZXR1cm4gMSBpZiBTQlIgY2FuIGJlIHByb2Nlc3NlZCwgMCBpZiBTQlIgY2Fubm90IGJlIHByb2Nlc3NlZC9hcHBsaWVkLgogKi8Kc3RhdGljCmludCBzYnJEZWNvZGVyX2lzQ29yZUNvZGVjVmFsaWQoQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjKQp7CiAgc3dpdGNoIChjb3JlQ29kZWMpIHsKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX1NCUjoKICAgIGNhc2UgQU9UX1BTOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgY2FzZSBBT1RfRFJNX0FBQzoKICAgICAgcmV0dXJuIDE7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gMDsKICB9Cn0KCnN0YXRpYwp2b2lkIHNickRlY29kZXJfRGVzdHJveUVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgICAgIHNlbGYsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gIT0gTlVMTCkgewogICAgaW50IGNoOwoKICAgIGZvciAoY2g9MDsgY2g8U0JSREVDX01BWF9DSF9QRVJfRUxFTUVOVDsgY2grKykgewogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICE9IE5VTEwpIHsKICAgICAgICBkZWxldGVTYnJEZWMoIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgICAgIEZyZWVSYW1fU2JyRGVjQ2hhbm5lbCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgICAgIHNlbGYtPm51bVNickNoYW5uZWxzIC09IDE7CiAgICAgIH0KICAgIH0KICAgIEZyZWVSYW1fU2JyRGVjRWxlbWVudCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gKTsKICAgIHNlbGYtPm51bVNickVsZW1lbnRzIC09IDE7CiAgfQp9CgoKU0JSX0VSUk9SIHNickRlY29kZXJfSW5pdEVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgICAgIHNlbGYsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IEFVRElPX09CSkVDVF9UWVBFIGNvcmVDb2RlYywKICAgICAgICBjb25zdCBNUDRfRUxFTUVOVF9JRCAgICBlbGVtZW50SUQsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgU0JSX0VSUk9SIHNickVycm9yID0gU0JSREVDX09LOwogIGludCBjaENudD0wOwogIGludCBuU2JyRWxlbWVudHNTdGFydCA9IHNlbGYtPm51bVNickVsZW1lbnRzOwoKICAvKiBDaGVjayBjb3JlIGNvZGVjIEFPVCAqLwogIGlmICghIHNickRlY29kZXJfaXNDb3JlQ29kZWNWYWxpZChjb3JlQ29kZWMpIHx8IGVsZW1lbnRJbmRleCA+PSAoOCkpIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggZWxlbWVudElEICE9IElEX1NDRSAmJiBlbGVtZW50SUQgIT0gSURfQ1BFICYmIGVsZW1lbnRJRCAhPSBJRF9MRkUgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggIHNlbGYtPnNhbXBsZVJhdGVJbiA9PSBzYW1wbGVSYXRlSW4KICAgICAmJiBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9PSBzYW1wbGVzUGVyRnJhbWUKICAgICAmJiBzZWxmLT5jb3JlQ29kZWMgPT0gY29yZUNvZGVjCiAgICAgJiYgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMCiAgICAgJiYgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZWxlbWVudElEID09IGVsZW1lbnRJRAogICAgICYmICEoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfRk9SQ0VfUkVTRVQpCiAgICAgKQogIHsKICAgICAvKiBOb3RoaW5nIHRvIGRvICovCiAgICAgcmV0dXJuIFNCUkRFQ19PSzsKICB9CgogIHNlbGYtPnNhbXBsZVJhdGVJbiA9IHNhbXBsZVJhdGVJbjsKICBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9IHNhbXBsZXNQZXJGcmFtZTsKICBzZWxmLT5jb3JlQ29kZWMgPSBjb3JlQ29kZWM7CgogIHNlbGYtPmZsYWdzID0gMDsKICBzZWxmLT5mbGFncyB8PSAoY29yZUNvZGVjID09IEFPVF9FUl9BQUNfRUxEKSA/IFNCUkRFQ19FTERfR1JJRCA6IDA7CiAgc2VsZi0+ZmxhZ3MgfD0gKGNvcmVDb2RlYyA9PSBBT1RfRVJfQUFDX1NDQUwpID8gU0JSREVDX1NZTlRBWF9TQ0FMIDogMDsKICBzZWxmLT5mbGFncyB8PSAoY29yZUNvZGVjID09IEFPVF9EUk1fQUFDKSAgICAgPyBTQlJERUNfU1lOVEFYX1NDQUx8U0JSREVDX1NZTlRBWF9EUk0gOiAwOwoKICAvKiBJbml0IFNCUiBlbGVtZW50cyAqLwogIHsKICAgIGludCBlbENoYW5uZWxzLCBjaDsKCiAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSA9PSBOVUxMKSB7CiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gPSBHZXRSYW1fU2JyRGVjRWxlbWVudChlbGVtZW50SW5kZXgpOwogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSA9PSBOVUxMKSB7CiAgICAgICAgc2JyRXJyb3IgPSBTQlJERUNfTUVNX0FMTE9DX0ZBSUxFRDsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgICAgc2VsZi0+bnVtU2JyRWxlbWVudHMgKys7CiAgICB9IGVsc2UgewogICAgICBzZWxmLT5udW1TYnJDaGFubmVscyAtPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5uQ2hhbm5lbHM7CiAgICB9CgogICAgLyogU2F2ZSBlbGVtZW50IElEIGZvciBzYW5pdHkgY2hlY2tzIGFuZCB0byBoYXZlIGEgZmFsbGJhY2sgZm9yIGNvbmNlYWxtZW50LiAqLwogICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZWxlbWVudElEID0gZWxlbWVudElEOwoKICAgIC8qIERldGVybWluZSBhbW91bnQgb2YgY2hhbm5lbHMgZm9yIHRoaXMgZWxlbWVudCAqLwogICAgc3dpdGNoIChlbGVtZW50SUQpIHsKICAgICAgY2FzZSBJRF9OT05FOgogICAgICBjYXNlIElEX0NQRTogZWxDaGFubmVscz0yOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIElEX0xGRToKICAgICAgY2FzZSBJRF9TQ0U6IGVsQ2hhbm5lbHM9MTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDogZWxDaGFubmVscz0wOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIEhhbmRsZSBjYXNlIG9mIFBhcmFtZXRyaWMgU3RlcmVvICovCiAgICBpZiAoIGVsZW1lbnRJbmRleCA9PSAwICYmIGVsZW1lbnRJRCA9PSBJRF9TQ0UgKSB7CiAgICAgIHN3aXRjaCAoY29yZUNvZGVjKSB7CiAgICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICBjYXNlIEFPVF9QUzoKICAgICAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgICAgICBjYXNlIEFPVF9EUk1fQUFDOgogICAgICAgICAgZWxDaGFubmVscyA9IDI7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5uQ2hhbm5lbHMgPSBlbENoYW5uZWxzOwoKICAgIGZvciAoY2g9MDsgY2g8ZWxDaGFubmVsczsgY2grKykKICAgIHsKICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdID0gR2V0UmFtX1NickRlY0NoYW5uZWwoY2hDbnQpOwogICAgICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gPT0gTlVMTCkgewogICAgICAgICAgc2JyRXJyb3IgPSBTQlJERUNfTUVNX0FMTE9DX0ZBSUxFRDsKICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgc2VsZi0+bnVtU2JyQ2hhbm5lbHMgKys7CgogICAgICBzYnJEZWNvZGVyX2RyY0luaXRDaGFubmVsKCAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdLT5TYnJEZWMuc2JyRHJjQ2hhbm5lbCApOwoKICAgICAgLyogQWRkIHJlZmVyZW5jZSBwb2ludGVyIHRvIHdvcmtidWZmZXJzLiAqLwogICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0tPlNickRlYy5Xb3JrQnVmZmVyMSA9IHNlbGYtPndvcmtCdWZmZXIxOwogICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0tPlNickRlYy5Xb3JrQnVmZmVyMiA9IHNlbGYtPndvcmtCdWZmZXIyOwogICAgICBjaENudCsrOwogICAgfQogICAgaWYgKGVsQ2hhbm5lbHMgPT0gMSAmJiBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gIT0gTlVMTCkgewogICAgICBkZWxldGVTYnJEZWMoIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgICBGcmVlUmFtX1NickRlY0NoYW5uZWwoICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gKTsKICAgIH0KICB9CgogIC8qIGNsZWFyIGVycm9yIGZsYWdzIGZvciBhbGwgZGVsYXkgc2xvdHMgKi8KICBGREttZW1jbGVhcihzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5mcmFtZUVycm9yRmxhZywgKCgxKSsxKSpzaXplb2YoVUNIQVIpKTsKCiAgLyogSW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlICovCiAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX1Jlc2V0RWxlbWVudCgKICAgICAgICAgIHNlbGYsCiAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgZWxlbWVudElELAogICAgICAgICAgZWxlbWVudEluZGV4LAogICAgICAgICAgKGNvcmVDb2RlYyA9PSBBT1RfRVJfQUFDX0VMRCkgPyAwIDogKDYpCiAgICAgICAgICApOwoKCgpiYWlsOgogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgIGlmIChuU2JyRWxlbWVudHNTdGFydCA8IHNlbGYtPm51bVNickVsZW1lbnRzKSB7CiAgICAgIC8qIEZyZWUgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIHRoaXMgZWxlbWVudCAqLwogICAgICBzYnJEZWNvZGVyX0Rlc3Ryb3lFbGVtZW50KCBzZWxmLCBlbGVtZW50SW5kZXggKTsKICAgIH0gZWxzZSBpZiAoIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICE9IE5VTEwpCiAgICAgICAgICAgICAmJiAoZWxlbWVudEluZGV4IDwgKDgpKSkKICAgIHsgLyogU2V0IGVycm9yIGZsYWcgdG8gdHJpZ2dlciBjb25jZWFsbWVudCAqLwogICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5mcmFtZUVycm9yRmxhZ1tzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3RdID0gMTsKICAgIH0KICB9CgogIHJldHVybiBzYnJFcnJvcjsKfQoKLyoqCiAqIFxicmllZiBBcHBseSBkZWNvZGVkIFNCUiBoZWFkZXIgZm9yIG9uZSBlbGVtZW50LgogKiBccGFyYW0gc2VsZiBTQlIgZGVjb2RlciBpbnN0YW5jZSBoYW5kbGUKICogXHBhcmFtIGhTYnJIZWFkZXIgU0JSIGhlYWRlciBoYW5kbGUgdG8gYmUgcHJvY2Vzc2VkLgogKiBccGFyYW0gaFNickNoYW5uZWwgcG9pbnRlciBhcnJheSB0byB0aGUgU0JSIGVsZW1lbnQgY2hhbm5lbHMgY29ycmVzcG9uZGluZyB0byB0aGUgU0JSIGhlYWRlci4KICogXHBhcmFtIGhlYWRlclN0YXR1cyBoZWFkZXIgc3RhdHVzIHZhbHVlIHJldHVybmVkIGZyb20gU0JSIGhlYWRlciBwYXJzZXIuCiAqIFxwYXJhbSBudW1FbGVtZW50Q2hhbm5lbHMgYW1vdW50IG9mIGNoYW5uZWxzIGZvciB0aGUgU0JSIGVsZW1lbnQgd2hvcyBoZWFkZXIgaXMgdG8gYmUgcHJvY2Vzc2VkLgogKi8Kc3RhdGljClNCUl9FUlJPUiBzYnJEZWNvZGVyX0hlYWRlclVwZGF0ZSgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiBzZWxmLAogICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNickhlYWRlciwKICAgICAgICBTQlJfSEVBREVSX1NUQVRVUyBoZWFkZXJTdGF0dXMsCiAgICAgICAgSEFORExFX1NCUl9DSEFOTkVMIGhTYnJDaGFubmVsW10sCiAgICAgICAgY29uc3QgaW50IG51bUVsZW1lbnRDaGFubmVscwogICAgICAgICkKewogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKCiAgLyoKICAgIGNoYW5nZSBvZiBjb250cm9sIGRhdGEsIHJlc2V0IGRlY29kZXIKICAqLwogIGVycm9yU3RhdHVzID0gcmVzZXRGcmVxQmFuZFRhYmxlcyhoU2JySGVhZGVyLCBzZWxmLT5mbGFncyk7CgogIGlmIChlcnJvclN0YXR1cyA9PSBTQlJERUNfT0spIHsKICAgIGlmIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gVVBTQU1QTElORyAmJiBoZWFkZXJTdGF0dXMgIT0gSEVBREVSX1JFU0VUKQogICAgewogICAgICAvKiBBcyB0aGUgZGVmYXVsdCBoZWFkZXIgd291bGQgbGltaXQgdGhlIGZyZXF1ZW5jeSByYW5nZSwKICAgICAgICAgbG93U3ViYmFuZCBhbmQgaGlnaFN1YmJhbmQgbXVzdCBiZSBwYXRjaGVkLiAqLwogICAgICBoU2JySGVhZGVyLT5mcmVxQmFuZERhdGEubG93U3ViYmFuZCA9IGhTYnJIZWFkZXItPm51bWJlck9mQW5hbHlzaXNCYW5kczsKICAgICAgaFNickhlYWRlci0+ZnJlcUJhbmREYXRhLmhpZ2hTdWJiYW5kID0gaFNickhlYWRlci0+bnVtYmVyT2ZBbmFseXNpc0JhbmRzOwogICAgfQoKICAgIC8qIFRyaWdnZXIgYSByZXNldCBiZWZvcmUgcHJvY2Vzc2luZyB0aGlzIHNsb3QgKi8KICAgIGhTYnJIZWFkZXItPnN0YXR1cyB8PSBTQlJERUNfSERSX1NUQVRfUkVTRVQ7CiAgfQoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCklOVCBzYnJEZWNvZGVyX0hlYWRlciAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgICAgc2VsZiwKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgICBoQnMsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZVJhdGVJbiwKICAgICAgICBjb25zdCBJTlQgc2FtcGxlUmF0ZU91dCwKICAgICAgICBjb25zdCBJTlQgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IEFVRElPX09CSkVDVF9UWVBFIGNvcmVDb2RlYywKICAgICAgICBjb25zdCBNUDRfRUxFTUVOVF9JRCAgICBlbGVtZW50SUQsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgU0JSX0hFQURFUl9TVEFUVVMgaGVhZGVyU3RhdHVzOwogIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNickhlYWRlcjsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CiAgaW50IGhlYWRlckluZGV4OwoKICBpZiAoIHNlbGYgPT0gTlVMTCB8fCBlbGVtZW50SW5kZXggPiAoOCkgKQogIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgaWYgKCEgc2JyRGVjb2Rlcl9pc0NvcmVDb2RlY1ZhbGlkKGNvcmVDb2RlYykpIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0luaXRFbGVtZW50KAogICAgICAgICAgc2VsZiwKICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICBjb3JlQ29kZWMsCiAgICAgICAgICBlbGVtZW50SUQsCiAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICAgICk7CgogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgIGdvdG8gYmFpbDsKICB9CgogIGhlYWRlckluZGV4ID0gZ2V0SGVhZGVyU2xvdChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUhlYWRlclNsb3QpOwogIGhTYnJIZWFkZXIgPSAmKHNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hlYWRlckluZGV4XSk7CgogIGhlYWRlclN0YXR1cyA9IHNickdldEhlYWRlckRhdGEgKCBoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCgogIHsKICAgIFNCUl9ERUNPREVSX0VMRU1FTlQgKnBTYnJFbGVtZW50OwoKICAgIHBTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKCiAgICAvKiBTYW5pdHkgY2hlY2sgKi8KICAgIGlmIChwU2JyRWxlbWVudCAhPSBOVUxMKSB7CiAgICAgIGlmICggKGVsZW1lbnRJRCA9PSBJRF9DUEUgJiYgcFNickVsZW1lbnQtPm5DaGFubmVscyAhPSAyKQogICAgICAgIHx8IChlbGVtZW50SUQgIT0gSURfQ1BFICYmIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMgIT0gMSkgKQogICAgICB7CiAgICAgICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICAgIH0KICAgICAgaWYgKCBoZWFkZXJTdGF0dXMgPT0gSEVBREVSX1JFU0VUICkgewoKICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICBoZWFkZXJTdGF0dXMsCiAgICAgICAgICAgICAgcFNickVsZW1lbnQtPnBTYnJDaGFubmVsLAogICAgICAgICAgICAgIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMKICAgICAgICAgICAgICApOwoKICAgICAgICBpZiAoc2JyRXJyb3IgPT0gU0JSREVDX09LKSB7CiAgICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfSEVBREVSOwogICAgICAgICAgaFNickhlYWRlci0+c3RhdHVzICAgfD0gU0JSREVDX0hEUl9TVEFUX1VQREFURTsKICAgICAgICB9CiAgICAgICAgLyogZWxzZSB7CiAgICAgICAgICBTaW5jZSB3ZSBhbHJlYWR5IGhhdmUgb3ZlcndyaXR0ZW4gdGhlIG9sZCBTQlIgaGVhZGVyIHRoZSBvbmx5IHdheSBvdXQgaXMgVVBTQU1QTElORyEKICAgICAgICAgIFRoaXMgd2lsbCBiZSBwcmVwYXJlZCBpbiB0aGUgbmV4dCBzdGVwLgogICAgICAgIH0gKi8KICAgICAgfQogICAgfQogIH0KYmFpbDoKICByZXR1cm4gc2JyRXJyb3I7Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9TZXRQYXJhbSAoSEFORExFX1NCUkRFQ09ERVIgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0JSREVDX1BBUkFNICBwYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgdmFsdWUgKQp7CiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICAvKiBjb25maWd1cmUgdGhlIHN1YnN5c3RlbXMgKi8KICBzd2l0Y2ggKHBhcmFtKQogIHsKICBjYXNlIFNCUl9TWVNURU1fQklUU1RSRUFNX0RFTEFZOgogICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+ICgxKSkgewogICAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPm51bURlbGF5RnJhbWVzID0gKFVDSEFSKXZhbHVlOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfUU1GX01PREU6CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh2YWx1ZSA9PSAxKSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gU0JSREVDX0xPV19QT1dFUjsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX0xPV19QT1dFUjsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfTERfUU1GX1RJTUVfQUxJR046CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh2YWx1ZSA9PSAxKSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gU0JSREVDX0xEX01QU19RTUY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19MRF9NUFNfUU1GOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIFNCUl9GTFVTSF9EQVRBOgogICAgaWYgKHZhbHVlICE9IDApIHsKICAgICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZWxmLT5mbGFncyB8PSBTQlJERUNfRkxVU0g7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgU0JSX0NMRUFSX0hJU1RPUlk6CiAgICBpZiAodmFsdWUgIT0gMCkgewogICAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgICB9IGVsc2UgewogICAgICAgIHNlbGYtPmZsYWdzIHw9IFNCUkRFQ19GT1JDRV9SRVNFVDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfQlNfSU5URVJSVVBUSU9OOgogICAgewogICAgICBpbnQgZWxlbWVudEluZGV4OwoKICAgICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX05PVF9JTklUSUFMSVpFRDsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLyogTG9vcCBvdmVyIFNCUiBlbGVtZW50cyAqLwogICAgICBmb3IgKGVsZW1lbnRJbmRleCA9IDA7IGVsZW1lbnRJbmRleCA8IHNlbGYtPm51bVNickVsZW1lbnRzOyBlbGVtZW50SW5kZXgrKykgewogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMKQogICAgICB7CiAgICAgICAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyOwogICAgICAgIGludCBoZWFkZXJJbmRleCA9IGdldEhlYWRlclNsb3Qoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlRnJhbWVTbG90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlSGVhZGVyU2xvdCk7CgogICAgICAgIGhTYnJIZWFkZXIgPSAmKHNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hlYWRlckluZGV4XSk7CgogICAgICAgIC8qIFNldCBzeW5jIHN0YXRlIFVQU0FNUExJTkcgZm9yIHRoZSBjb3JyZXNwb25kaW5nIHNsb3QuCiAgICAgICAgICAgVGhpcyBzd2l0Y2hlcyBvZmYgYml0c3RyZWFtIHBhcnNpbmcgdW50aWwgYSBuZXcgaGVhZGVyIGFycml2ZXMuICovCiAgICAgICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gVVBTQU1QTElORzsKICAgICAgICBoU2JySGVhZGVyLT5zdGF0dXMgICB8PSBTQlJERUNfSERSX1NUQVRfVVBEQVRFOwogICAgICB9IH0KICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19TRVRfUEFSQU1fRkFJTDsKICAgIGJyZWFrOwogIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCiAgcmV0dXJuIChlcnJvclN0YXR1cyk7Cn0KCnN0YXRpYwpTQlJERUNfRFJDX0NIQU5ORUwgKiBzYnJEZWNvZGVyX2RyY0dldENoYW5uZWwoIGNvbnN0IEhBTkRMRV9TQlJERUNPREVSIHNlbGYsIGNvbnN0IElOVCBjaGFubmVsICkKewogIFNCUkRFQ19EUkNfQ0hBTk5FTCAqcFNickRyY0NoYW5uZWxEYXRhID0gTlVMTDsKICBpbnQgZWxlbWVudEluZGV4LCBlbENoYW5JZHg9MCwgbnVtQ2g9MDsKCiAgZm9yIChlbGVtZW50SW5kZXggPSAwOyAoZWxlbWVudEluZGV4IDwgKDgpKSAmJiAobnVtQ2ggPD0gY2hhbm5lbCk7IGVsZW1lbnRJbmRleCsrKQogIHsKICAgIFNCUl9ERUNPREVSX0VMRU1FTlQgKnBTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKICAgIGludCBjLCBlbENoYW5uZWxzOwoKICAgIGVsQ2hhbklkeCA9IDA7CiAgICBpZiAocFNickVsZW1lbnQgPT0gTlVMTCkgYnJlYWs7CgogICAgLyogRGV0ZXJtaW5lIGFtb3VudCBvZiBjaGFubmVscyBmb3IgdGhpcyBlbGVtZW50ICovCiAgICBzd2l0Y2ggKHBTYnJFbGVtZW50LT5lbGVtZW50SUQpIHsKICAgICAgY2FzZSBJRF9DUEU6IGVsQ2hhbm5lbHMgPSAyOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIElEX0xGRToKICAgICAgY2FzZSBJRF9TQ0U6IGVsQ2hhbm5lbHMgPSAxOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIElEX05PTkU6CiAgICAgIGRlZmF1bHQ6IGVsQ2hhbm5lbHMgPSAwOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIExpbWl0IHdpdGggYWN0dWFsIGFsbG9jYXRlZCBlbGVtZW50IGNoYW5uZWxzICovCiAgICBlbENoYW5uZWxzID0gRkRLbWluKGVsQ2hhbm5lbHMsIHBTYnJFbGVtZW50LT5uQ2hhbm5lbHMpOwoKICAgIGZvciAoYyA9IDA7IChjIDwgZWxDaGFubmVscykgJiYgKG51bUNoIDw9IGNoYW5uZWwpOyBjKyspIHsKICAgICAgaWYgKHBTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFtlbENoYW5JZHhdICE9IE5VTEwpIHsKICAgICAgICBudW1DaCsrOwogICAgICAgIGVsQ2hhbklkeCsrOwogICAgICB9CiAgICB9CiAgfQogIGVsZW1lbnRJbmRleCAtPSAxOwogIGVsQ2hhbklkeCAtPSAxOwoKICBpZiAoZWxDaGFuSWR4IDwgMCB8fCBlbGVtZW50SW5kZXggPCAwKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIGlmICggc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMICkgewogICAgaWYgKCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtlbENoYW5JZHhdICE9IE5VTEwgKQogICAgewogICAgICBwU2JyRHJjQ2hhbm5lbERhdGEgPSAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbZWxDaGFuSWR4XS0+U2JyRGVjLnNickRyY0NoYW5uZWw7CiAgICB9CiAgfQoKICByZXR1cm4gKHBTYnJEcmNDaGFubmVsRGF0YSk7Cn0KClNCUl9FUlJPUiBzYnJEZWNvZGVyX2RyY0ZlZWRDaGFubmVsICggSEFORExFX1NCUkRFQ09ERVIgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICBudW1CYW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICAgICAgICAqcE5leHRGYWN0X21hZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgbmV4dEZhY3RfZXhwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICAgICAgICAgICAgICBkcmNJbnRlcnBvbGF0aW9uU2NoZW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICB3aW5TZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0hPUlQgICAgICAgICAgICAqcEJhbmRUb3AgKQp7CiAgU0JSREVDX0RSQ19DSEFOTkVMICpwU2JyRHJjQ2hhbm5lbERhdGEgPSBOVUxMOwogIGludCBiYW5kLCBpc1ZhbGlkRGF0YSA9IDA7CgogIGlmIChzZWxmID09IE5VTEwpIHsKICAgIHJldHVybiBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogIH0KICBpZiAoY2ggPiAoOCkgfHwgcE5leHRGYWN0X21hZyA9PSBOVUxMKSB7CiAgICByZXR1cm4gU0JSREVDX1NFVF9QQVJBTV9GQUlMOwogIH0KCiAgLyogU2VhcmNoIGZvciBnYWluIHZhbHVlcyBkaWZmZXJlbnQgdG8gMS4wZiAqLwogIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBudW1CYW5kczsgYmFuZCArPSAxKSB7CiAgICBpZiAoICEoKHBOZXh0RmFjdF9tYWdbYmFuZF0gPT0gRkwyRlhDT05TVF9EQkwoMC41KSkgICYmIChuZXh0RmFjdF9leHAgPT0gMSkpCiAgICAgICYmICEoKHBOZXh0RmFjdF9tYWdbYmFuZF0gPT0gKEZJWFBfREJMKU1BWFZBTF9EQkwpICYmIChuZXh0RmFjdF9leHAgPT0gMCkpICkgewogICAgICBpc1ZhbGlkRGF0YSA9IDE7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgLyogRmluZCB0aGUgcmlnaHQgU0JSIGNoYW5uZWwgKi8KICBwU2JyRHJjQ2hhbm5lbERhdGEgPSBzYnJEZWNvZGVyX2RyY0dldENoYW5uZWwoIHNlbGYsIGNoICk7CgogIGlmICggcFNickRyY0NoYW5uZWxEYXRhICE9IE5VTEwgKSB7CiAgICBpZiAoIHBTYnJEcmNDaGFubmVsRGF0YS0+ZW5hYmxlIHx8IGlzVmFsaWREYXRhICkKICB7IC8qIEFjdGl2YXRlIHByb2Nlc3Npbmcgb25seSB3aXRoIHJlYWwgYW5kIHZhbGlkIGRhdGEgKi8KICAgIGludCBpOwoKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+ZW5hYmxlICAgPSAxOwogICAgcFNickRyY0NoYW5uZWxEYXRhLT5udW1CYW5kc05leHQgPSBudW1CYW5kczsKCiAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPndpblNlcXVlbmNlTmV4dCAgICAgICAgICAgID0gd2luU2VxdWVuY2U7CiAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPmRyY0ludGVycG9sYXRpb25TY2hlbWVOZXh0ID0gZHJjSW50ZXJwb2xhdGlvblNjaGVtZTsKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+bmV4dEZhY3RfZXhwICAgICAgICAgICAgICAgPSBuZXh0RmFjdF9leHA7CgogICAgZm9yIChpID0gMDsgaSA8IChpbnQpbnVtQmFuZHM7IGkrKykgewogICAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPmJhbmRUb3BOZXh0W2ldICA9IHBCYW5kVG9wW2ldOwogICAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPm5leHRGYWN0X21hZ1tpXSA9IHBOZXh0RmFjdF9tYWdbaV07CiAgICB9CiAgfQogIH0KCiAgcmV0dXJuIFNCUkRFQ19PSzsKfQoKCnZvaWQgc2JyRGVjb2Rlcl9kcmNEaXNhYmxlICggSEFORExFX1NCUkRFQ09ERVIgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgIGNoICkKewogIFNCUkRFQ19EUkNfQ0hBTk5FTCAqcFNickRyY0NoYW5uZWxEYXRhID0gTlVMTDsKCiAgaWYgKCAoc2VsZiA9PSBOVUxMKQogICAgfHwgKGNoID4gKDgpKQogICAgfHwgKHNlbGYtPm51bVNickVsZW1lbnRzID09IDApCiAgICB8fCAoc2VsZi0+bnVtU2JyQ2hhbm5lbHMgPT0gMCkgKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBGaW5kIHRoZSByaWdodCBTQlIgY2hhbm5lbCAqLwogIHBTYnJEcmNDaGFubmVsRGF0YSA9IHNickRlY29kZXJfZHJjR2V0Q2hhbm5lbCggc2VsZiwgY2ggKTsKCiAgaWYgKCBwU2JyRHJjQ2hhbm5lbERhdGEgIT0gTlVMTCApIHsKICAgIHNickRlY29kZXJfZHJjSW5pdENoYW5uZWwoIHBTYnJEcmNDaGFubmVsRGF0YSApOwogIH0KfQoKCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9QYXJzZSgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICBoQnMsCiAgICAgICAgaW50ICpjb3VudCwKICAgICAgICBpbnQgIGJzUGF5TGVuLAogICAgICAgIGludCAgY3JjRmxhZywKICAgICAgICBNUDRfRUxFTUVOVF9JRCBwcmV2RWxlbWVudCwKICAgICAgICBpbnQgZWxlbWVudEluZGV4LAogICAgICAgIGludCBmR2xvYmFsSW5kZXBlbmRlbmN5RmxhZwogICAgICAgICkKewogIFNCUl9ERUNPREVSX0VMRU1FTlQgICAqaFNickVsZW1lbnQ7CiAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyID0gTlVMTDsKICBIQU5ETEVfU0JSX0NIQU5ORUwgICAgKnBTYnJDaGFubmVsOwoKICBTQlJfRlJBTUVfREFUQSAqaEZyYW1lRGF0YUxlZnQ7CiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFSaWdodDsKCiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwogIFNCUl9IRUFERVJfU1RBVFVTIGhlYWRlclN0YXR1cyA9IEhFQURFUl9OT1RfUFJFU0VOVDsKCiAgSU5UICBzdGFydFBvczsKICBJTlQgIENSQ0xlbiA9IDA7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzT3JpZ2luYWwgPSBoQnM7CiAgRkRLX0NSQ0lORk8gIGNyY0luZm87ICAgICAgICAgLyogc2hhbGwgYmUgdXNlZCBmb3IgYWxsIG90aGVyIENSQ3MgaW4gdGhlIGZ1dHVyZSAoVEJEKSAqLwogIElOVCAgICAgICAgICBjcmNSZWcgPSAwOwogIFVTSE9SVCAgICAgICBkcm1TYnJDcmMgPSAwOwoKICBpbnQgIHN0ZXJlbzsKICBpbnQgIGZEb0RlY29kZVNickRhdGEgPSAxOwoKICBpbnQgbGFzdFNsb3QsIGxhc3RIZHJTbG90ID0gMCwgdGhpc0hkclNsb3Q7CgogIC8qIFJldmVyc2UgYml0cyBvZiBEUk0gU0JSIHBheWxvYWQgKi8KICBpZiAoIChzZWxmLT5mbGFncyAmIFNCUkRFQ19TWU5UQVhfRFJNKSAmJiAqY291bnQgPiAwICkKICB7CiAgICBVQ0hBUiAqYnNCdWZmZXJEcm0gPSAoVUNIQVIqKXNlbGYtPndvcmtCdWZmZXIxOwogICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzQndkID0gKEhBTkRMRV9GREtfQklUU1RSRUFNKSAoYnNCdWZmZXJEcm0gKyAoNTEyKSk7CiAgICBpbnQgZGF0YUJ5dGVzLCBkYXRhQml0czsKCiAgICBkYXRhQml0cyA9ICpjb3VudDsKCiAgICBpZiAoZGF0YUJpdHMgPiAoKDUxMikqOCkpIHsKICAgICAgLyogZG8gbm90IGZsaXAgbW9yZSBkYXRhIHRoYW4gbmVlZGVkICovCiAgICAgIGRhdGFCaXRzID0gKDUxMikqODsKICAgIH0KCiAgICBkYXRhQnl0ZXMgPSAoZGF0YUJpdHMrNyk+PjM7CgogICAgaW50IGo7CgogICAgaWYgKChqID0gKGludClGREtnZXRWYWxpZEJpdHMoaEJzKSkgIT0gOCkgewogICAgICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsIChqLTgpKTsKICAgIH0KCiAgICBqID0gMDsKICAgIGZvciAoIDsgZGF0YUJ5dGVzID4gMDsgZGF0YUJ5dGVzLS0pCiAgICB7CiAgICAgIGludCBpOwogICAgICBVQ0hBUiB0bXBCeXRlOwogICAgICBVQ0hBUiBidWZmZXIgPSAweDAwOwoKICAgICAgdG1wQnl0ZSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewogICAgICAgIGludCBzaGlmdCA9IDIgKiBpICsgMTsKICAgICAgICBidWZmZXIgfD0gKHRtcEJ5dGUgJiAoMHgwOD4+aSkpIDw8IHNoaWZ0OwogICAgICAgIGJ1ZmZlciB8PSAodG1wQnl0ZSAmICgweDEwPDxpKSkgPj4gc2hpZnQ7CiAgICAgIH0KICAgICAgYnNCdWZmZXJEcm1baisrXSA9IGJ1ZmZlcjsKICAgICAgRkRLcHVzaEJhY2soaEJzLCAxNik7CiAgICB9CgogICAgRkRLaW5pdEJpdFN0cmVhbShoQnNCd2QsIGJzQnVmZmVyRHJtLCAoNTEyKSwgZGF0YUJpdHMsIEJTX1JFQURFUik7CgogICAgLyogVXNlIHJldmVyc2VkIGRhdGEgKi8KICAgIGhCcyA9IGhCc0J3ZDsKICAgIGJzUGF5TGVuID0gKmNvdW50OwogIH0KCiAgLyogUmVtZW1iZXIgc3RhcnQgcG9zaXRpb24gb2YgIFNCUiBlbGVtZW50ICovCiAgc3RhcnRQb3MgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgLyogU0JSIHNhbml0eSBjaGVja3MgKi8KICBpZiAoIHNlbGYgPT0gTlVMTCB8fCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID09IE5VTEwgKSB7CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19OT1RfSU5JVElBTElaRUQ7CiAgICBnb3RvIGJhaWw7CiAgfSAKCiAgaFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwoKICBsYXN0U2xvdCAgICA9IChoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID4gMCkgPyBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90LTEgOiBzZWxmLT5udW1EZWxheUZyYW1lczsKICBsYXN0SGRyU2xvdCA9ICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtsYXN0U2xvdF07CiAgdGhpc0hkclNsb3QgPSAgZ2V0SGVhZGVyU2xvdCggaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCwgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3QgKTsgIC8qIEdldCBhIGZyZWUgaGVhZGVyIHNsb3Qgbm90IHVzZWQgYnkgZnJhbWVzIG5vdCBwcm9jZXNzZWQgeWV0LiAqLwoKICAvKiBBc3NpZ24gdGhlIGZyZWUgc2xvdCB0byBzdG9yZSBhIG5ldyBoZWFkZXIgaWYgdGhlcmUgaXMgb25lLiAqLwogIGhTYnJIZWFkZXIgPSAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1bdGhpc0hkclNsb3RdOwoKICBwU2JyQ2hhbm5lbCA9IGhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbDsKICBzdGVyZW8gPSAoaFNickVsZW1lbnQtPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMSA6IDA7CgogIGhGcmFtZURhdGFMZWZ0ICA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFswXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwogIGhGcmFtZURhdGFSaWdodCA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKCiAgLyogcmVzZXQgUFMgZmxhZzsgd2lsbCBiZSBzZXQgYWZ0ZXIgUFMgd2FzIGZvdW5kICovCiAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19QU19ERUNPREVEOwoKICBpZiAoaFNickhlYWRlci0+c3RhdHVzICYgU0JSREVDX0hEUl9TVEFUX1VQREFURSkgewogICAgLyogR290IGEgbmV3IGhlYWRlciBmcm9tIGV4dGVybiAoZS5nLiBmcm9tIGFuIEFTQykgKi8KICAgIGhlYWRlclN0YXR1cyA9IEhFQURFUl9PSzsKICAgIGhTYnJIZWFkZXItPnN0YXR1cyAmPSB+U0JSREVDX0hEUl9TVEFUX1VQREFURTsKICB9CiAgZWxzZSBpZiAodGhpc0hkclNsb3QgIT0gbGFzdEhkclNsb3QpIHsKICAgIC8qIENvcHkgdGhlIGxhc3QgaGVhZGVyIGludG8gdGhpcyBzbG90IG90aGVyd2lzZSB0aGUKICAgICAgIGhlYWRlciBjb21wYXJlIHdpbGwgdHJpZ2dlciBtb3JlIEhFQURFUl9SRVNFVHMgdGhhbiBuZWVkZWQuICovCiAgICBjb3B5U2JySGVhZGVyKCBoU2JySGVhZGVyLCAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1bbGFzdEhkclNsb3RdICk7CiAgfQoKICAvKgogICAgIENoZWNrIGlmIGJpdCBzdHJlYW0gZGF0YSBpcyB2YWxpZCBhbmQgbWF0Y2hlcyB0aGUgZWxlbWVudCBjb250ZXh0CiAgKi8KICBpZiAoICgocHJldkVsZW1lbnQgIT0gSURfU0NFKSAmJiAocHJldkVsZW1lbnQgIT0gSURfQ1BFKSkgfHwgcHJldkVsZW1lbnQgIT0gaFNickVsZW1lbnQtPmVsZW1lbnRJRCkgewogICAgLyogSW4gY2FzZSBvZiBMRkUgd2UgYWxzbyBsYW5kIGhlcmUsIHNpbmNlIHRoZXJlIGlzIG5vIExGRSBTQlIgZWxlbWVudCAoZG8gdXBzYW1wbGluZyBvbmx5KSAqLwogICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgfQoKICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpZiAoKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKSA8PSAwKSB7CiAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgfQogIH0KCiAgLyoKICAgICBTQlIgQ1JDLWNoZWNrCiAgKi8KICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpZiAoY3JjRmxhZykgewogICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgIEZES3B1c2hGb3IgKGhCcywgMTApOwogICAgICAgIC8qIGNoZWNrIHNicmNyYyBsYXRlcjogd2UgZG9uJ3Qga25vdyB0aGUgcGF5bG9hZCBsZW5ndGggbm93ICovCiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgQU9UX0RSTV9BQUM6CiAgICAgICAgZHJtU2JyQ3JjID0gKFVTSE9SVClGREtyZWFkQml0cyhoQnMsIDgpOwogICAgICAgIC8qIFNldHVwIENSQyBkZWNvZGVyICovCiAgICAgICAgRkRLY3JjSW5pdCgmY3JjSW5mbywgMHgwMDFkLCAweEZGRkYsIDgpOwogICAgICAgIC8qIFN0YXJ0IENSQyByZWdpb24gKi8KICAgICAgICBjcmNSZWcgPSBGREtjcmNTdGFydFJlZygmY3JjSW5mbywgaEJzLCAwKTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBDUkNMZW4gPSBic1BheUxlbiAtIDEwOyAgICAgICAgICAgICAgICAgICAgIC8qIGNoYW5nZTogMCA9PiBpICovCiAgICAgICAgaWYgKENSQ0xlbiA8IDApIHsKICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gU2JyQ3JjQ2hlY2sgKGhCcywgQ1JDTGVuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9IC8qIGlmIChmRG9EZWNvZGVTYnJEYXRhKSAqLwoKICAvKgogICAgIFJlYWQgaW4gdGhlIGhlYWRlciBkYXRhIGFuZCBpc3N1ZSBhIHJlc2V0IGlmIGNoYW5nZSBvY2N1cmVkCiAgKi8KICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpbnQgc2JySGVhZGVyUHJlc2VudDsKCiAgICB7CiAgICAgIHNickhlYWRlclByZXNlbnQgPSBGREtyZWFkQml0KGhCcyk7CiAgICB9CgogICAgaWYgKCBzYnJIZWFkZXJQcmVzZW50ICkgewogICAgICBoZWFkZXJTdGF0dXMgPSBzYnJHZXRIZWFkZXJEYXRhIChoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKTsKICAgIH0KCiAgICBpZiAoaGVhZGVyU3RhdHVzID09IEhFQURFUl9SRVNFVCkKICAgIHsKICAgICAgZXJyb3JTdGF0dXMgPSBzYnJEZWNvZGVyX0hlYWRlclVwZGF0ZSgKICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgaGVhZGVyU3RhdHVzLAogICAgICAgICAgICBwU2JyQ2hhbm5lbCwKICAgICAgICAgICAgaFNickVsZW1lbnQtPm5DaGFubmVscyAKICAgICAgICAgICAgKTsKCiAgICAgIGlmIChlcnJvclN0YXR1cyA9PSBTQlJERUNfT0spIHsKICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfSEVBREVSOwogICAgICB9IGVsc2UgewogICAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9OT1RfSU5JVElBTElaRUQ7CiAgICAgICAgaGVhZGVyU3RhdHVzID0gSEVBREVSX0VSUk9SOwogICAgICB9CiAgICB9CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgIH0KICB9IC8qIGlmIChmRG9EZWNvZGVTYnJEYXRhKSAqLwoKICAvKgogICAgUHJpbnQgZGVidWdnaW5nIG91dHB1dCBvbmx5IGlmIHN0YXRlIGhhcyBjaGFuZ2VkCiAgKi8KCiAgLyogcmVhZCBmcmFtZSBkYXRhICovCiAgaWYgKChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPj0gU0JSX0hFQURFUikgJiYgZkRvRGVjb2RlU2JyRGF0YSkgewogICAgaW50IHNickZyYW1lT2s7CiAgICAvKiByZWFkIHRoZSBTQlIgZWxlbWVudCBkYXRhICovCiAgICBpZiAoc3RlcmVvKSB7CiAgICAgIHNickZyYW1lT2sgPSBzYnJHZXRDaGFubmVsUGFpckVsZW1lbnQoaFNickhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhUmlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnRyYW5zcG9zZXJTZXR0aW5ncy5vdmVybGFwKTsKICAgIH0KICAgIGVsc2UgewogICAgICBpZiAoc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMgIT0gTlVMTCkgewogICAgICAgIC8qIHVwZGF0ZSBzbG90IGluZGV4IGZvciBQUyBiaXRzdHJlYW0gcGFyc2luZyAqLwogICAgICAgIHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic0xhc3RTbG90ID0gc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMtPmJzUmVhZFNsb3Q7CiAgICAgICAgc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMtPmJzUmVhZFNsb3QgPSBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90OwogICAgICB9CiAgICAgIHNickZyYW1lT2sgPSBzYnJHZXRTaW5nbGVDaGFubmVsRWxlbWVudChoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dHJhbnNwb3NlclNldHRpbmdzLm92ZXJsYXApOwogICAgfQogICAgaWYgKCFzYnJGcmFtZU9rKSB7CiAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgfQogICAgZWxzZSB7CiAgICAgIElOVCB2YWxCaXRzOwoKICAgICAgaWYgKGJzUGF5TGVuID4gMCkgewogICAgICAgIHZhbEJpdHMgPSBic1BheUxlbiAtICgoSU5UKXN0YXJ0UG9zIC0gKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFsQml0cyA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CiAgICAgIH0KCiAgICAgIGlmICggY3JjRmxhZyApIHsKICAgICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIGxhdGUgY3JjIGNoZWNrIGZvciBlbGQgKi8KICAgICAgICAgICAgSU5UIHBheWxvYWRiaXRzID0gKElOVClzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBzdGFydFBvczsKICAgICAgICAgICAgSU5UIGNyY0xlbiAgICAgID0gcGF5bG9hZGJpdHMgLSAxMDsKICAgICAgICAgICAgRkRLcHVzaEJhY2soaEJzLCBwYXlsb2FkYml0cyk7CiAgICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgICAgICA9IFNickNyY0NoZWNrIChoQnMsIGNyY0xlbik7CiAgICAgICAgICAgIEZES3B1c2hGb3IoaEJzLCBjcmNMZW4pOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBT1RfRFJNX0FBQzoKICAgICAgICAgIC8qIEVuZCBDUkMgcmVnaW9uICovCiAgICAgICAgICBGREtjcmNFbmRSZWcoJmNyY0luZm8sIGhCcywgY3JjUmVnKTsKICAgICAgICAgIC8qIENoZWNrIENSQyAqLwogICAgICAgICAgaWYgKChGREtjcmNHZXRDUkMoJmNyY0luZm8pXjB4RkYpICE9IGRybVNickNyYykgewogICAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIHNhbml0eSBjaGVjayBvZiByZW1haW5pbmcgYml0cyAqLwogICAgICBpZiAodmFsQml0cyA8IDApIHsKICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICBjYXNlIEFPVF9QUzoKICAgICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIFRoaXMgc2FuaXR5IGNoZWNrIGlzIG9ubHkgbWVhbmluZ2Z1bCB3aXRoIEdlbmVyYWwgQXVkaW8gYml0c3RyZWFtcyAqLwogICAgICAgICAgICBpbnQgYWxpZ25CaXRzID0gdmFsQml0cyAmIDB4NzsKCiAgICAgICAgICAgIGlmICh2YWxCaXRzID4gYWxpZ25CaXRzKSB7CiAgICAgICAgICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvKiBObyBzYW5pdHkgY2hlY2sgYXZhaWxhYmxlICovCiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgLyogVGhlIHJldHVybmVkIGJpdCBjb3VudCB3aWxsIG5vdCBiZSB0aGUgYWN0dWFsIHBheWxvYWQgc2l6ZSBzaW5jZSB3ZSBkaWQgbm90CiAgICAgICBwYXJzZSB0aGUgZnJhbWUgZGF0YS4gUmV0dXJuIGFuIGVycm9yIHNvIHRoYXQgdGhlIGNhbGxlciBjYW4gcmVhY3QgcmVzcGVjdGl2ZWx5LiAqLwogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfUEFSU0VfRVJST1I7CiAgfQoKICBpZiAoIWZEb0RlY29kZVNickRhdGEpIHsKICAgIC8qIFNldCBlcnJvciBmbGFnIGZvciB0aGlzIHNsb3QgdG8gdHJpZ2dlciBjb25jZWFsbWVudCAqLwogICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZnJhbWVFcnJvckZsYWdbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSAxOwogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfUEFSU0VfRVJST1I7CiAgfSBlbHNlIHsKICAgIC8qIEV2ZXJ5dGhpbmcgc2VlbXMgdG8gYmUgb2sgc28gY2xlYXIgdGhlIGVycm9yIGZsYWcgKi8KICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdID0gMDsKICB9CgogIGlmICghc3RlcmVvKSB7CiAgICAvKiBUdXJuIGNvdXBsaW5nIG9mZiBleHBsaWNpdGVseSB0byBhdm9pZCBhY2Nlc3MgdG8gYWJzZW50IHJpZ2h0IGZyYW1lIGRhdGEKICAgICAgIHRoYXQgbWlnaHQgb2NjdXIgd2l0aCBjb3JydXB0IGJpdHN0cmVhbXMuICovCiAgICBoRnJhbWVEYXRhTGVmdC0+Y291cGxpbmcgPSBDT1VQTElOR19PRkY7CiAgfQoKYmFpbDoKCiAgaWYgKCBzZWxmLT5mbGFncyAmIFNCUkRFQ19TWU5UQVhfRFJNICkKICB7CiAgICBoQnMgPSBoQnNPcmlnaW5hbDsKICB9CgogIGlmICggKGVycm9yU3RhdHVzID09IFNCUkRFQ19PSykKICAgIHx8ICggKGVycm9yU3RhdHVzID09IFNCUkRFQ19QQVJTRV9FUlJPUikKICAgICAgJiYgKGhlYWRlclN0YXR1cyAhPSBIRUFERVJfRVJST1IpICkgKQogIHsKICAgIGludCB1c2VPbGRIZHIgPSAoIChoZWFkZXJTdGF0dXMgPT0gSEVBREVSX05PVF9QUkVTRU5UKQogICAgICAgICAgICAgICAgICAgfHwgKGhlYWRlclN0YXR1cyA9PSBIRUFERVJfRVJST1IpICkgPyAxIDogMDsKCiAgICBpZiAoIXVzZU9sZEhkciAmJiAodGhpc0hkclNsb3QgIT0gbGFzdEhkclNsb3QpKSB7CiAgICAgIHVzZU9sZEhkciB8PSAoIGNvbXBhcmVTYnJIZWFkZXIoIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2xhc3RIZHJTbG90XSApID09IDAgKSA/IDEgOiAwOwogICAgfQoKICAgIGlmICh1c2VPbGRIZHIgIT0gMCkgewogICAgICAvKiBVc2UgdGhlIG9sZCBoZWFkZXIgZm9yIHRoaXMgZnJhbWUgKi8KICAgICAgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSBsYXN0SGRyU2xvdDsKICAgIH0gZWxzZSB7CiAgICAgIC8qIFVzZSB0aGUgbmV3IGhlYWRlciBmb3IgdGhpcyBmcmFtZSAqLwogICAgICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XSA9IHRoaXNIZHJTbG90OwogICAgfQoKICAgIC8qIE1vdmUgZnJhbWUgcG9pbnRlciB0byB0aGUgbmV4dCBzbG90IHdoaWNoIGlzIHVwIHRvIGJlIGRlY29kZWQvYXBwbGllZCBuZXh0ICovCiAgICBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID0gKGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QrMSkgJSAoc2VsZi0+bnVtRGVsYXlGcmFtZXMrMSk7CiAgfQoKICAqY291bnQgLT0gc3RhcnRQb3MgLSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgcmV0dXJuIGVycm9yU3RhdHVzOwp9CgoKLyoqCiAqIFxicmllZiBSZW5kZXIgb25lIFNCUiBlbGVtZW50IGludG8gdGltZSBkb21haW4gc2lnbmFsLgogKiBccGFyYW0gc2VsZiBTQlIgZGVjb2RlciBoYW5kbGUKICogXHBhcmFtIHRpbWVEYXRhIHBvaW50ZXIgdG8gb3V0cHV0IGJ1ZmZlcgogKiBccGFyYW0gaW50ZXJsZWF2ZWQgZmxhZyBpbmRpY2F0aW5nIGludGVybGVhdmVkIGNoYW5uZWwgb3V0cHV0CiAqIFxwYXJhbSBjaGFubmVsTWFwcGluZyBwb2ludGVyIHRvIFVDSEFSIGFycmF5IHdoZXJlIG5leHQgMiBjaGFubmVsIG9mZnNldHMgYXJlIHN0b3JlZC4gCiAqIFxwYXJhbSBlbGVtZW50SW5kZXggZW51bWVyYXRpbmcgaW5kZXggb2YgdGhlIFNCUiBlbGVtZW50IHRvIHJlbmRlci4KICogXHBhcmFtIG51bUluQ2hhbm5lbHMgbnVtYmVyIG9mIGNoYW5uZWxzIGZyb20gY29yZSBjb2RlciAocmVhZGluZyBzdHJpZGUpLgogKiBccGFyYW0gbnVtT3V0Q2hhbm5lbHMgcG9pbnRlciB0byBhIGxvY2F0aW9uIHRvIHJldHVybiBudW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzLgogKiBccGFyYW0gcHNQb3NzaWJsZSBmbGFnIGluZGljYXRpbmcgaWYgUFMgaXMgcG9zc2libGUgb3Igbm90LgogKiBccmV0dXJuIFNCUkRFQ19PSyBpZiBzdWNjZXNzZnVsbCwgZWxzZSBlcnJvciBjb2RlCiAqLwpzdGF0aWMgU0JSX0VSUk9SCnNickRlY29kZXJfRGVjb2RlRWxlbWVudCAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgc2VsZiwKICAgICAgICBJTlRfUENNICAgICAgICAgICAgICp0aW1lRGF0YSwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBpbnRlcmxlYXZlZCwKICAgICAgICBjb25zdCBVQ0hBUiAgICAgICAgICpjaGFubmVsTWFwcGluZywKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBlbGVtZW50SW5kZXgsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgbnVtSW5DaGFubmVscywKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICpudW1PdXRDaGFubmVscywKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBwc1Bvc3NpYmxlCiAgICAgICAgKQp7CiAgU0JSX0RFQ09ERVJfRUxFTUVOVCAqaFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwogIEhBTkRMRV9TQlJfQ0hBTk5FTCAgICAqcFNickNoYW5uZWwgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbDsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXIgPSAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF1dOwogIEhBTkRMRV9QU19ERUMgaF9wc19kID0gc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWM7CgogIC8qIGdldCBtZW1vcnkgZm9yIGZyYW1lIGRhdGEgZnJvbSBzY3JhdGNoICovCiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFMZWZ0ICA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMF0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICBTQlJfRlJBTUVfREFUQSAqaEZyYW1lRGF0YVJpZ2h0ID0gJmhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICBTQlJfRVJST1IgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CgoKICBJTlQgIHN0cmlkZUluLCBzdHJpZGVPdXQsIG9mZnNldDAsIG9mZnNldDE7CiAgSU5UICBjb2RlY0ZyYW1lU2l6ZSA9IHNlbGYtPmNvZGVjRnJhbWVTaXplOwoKICBpbnQgIHN0ZXJlbyA9IChoU2JyRWxlbWVudC0+ZWxlbWVudElEID09IElEX0NQRSkgPyAxIDogMDsKICBpbnQgIG51bUVsZW1lbnRDaGFubmVscyA9IGhTYnJFbGVtZW50LT5uQ2hhbm5lbHM7IC8qIE51bWJlciBvZiBjaGFubmVscyBvZiB0aGUgY3VycmVudCBTQlIgZWxlbWVudCAqLwoKICBpZiAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfRkxVU0gpIHsKICAgIGlmICggc2VsZi0+bnVtRmx1c2hlZEZyYW1lcyA+IHNlbGYtPm51bURlbGF5RnJhbWVzICkgewogICAgICBpbnQgaGRySWR4OwogICAgICAvKiBObyB2YWxpZCBTQlIgcGF5bG9hZCBhdmFpbGFibGUsIGhlbmNlIHN3aXRjaCB0byB1cHNhbXBsaW5nIChpbiBhbGwgaGVhZGVycykgKi8KICAgICAgZm9yIChoZHJJZHggPSAwOyBoZHJJZHggPCAoKDEpKzEpOyBoZHJJZHggKz0gMSkgewogICAgICAgIHNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hkcklkeF0uc3luY1N0YXRlID0gVVBTQU1QTElORzsKICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIE1vdmUgZnJhbWUgcG9pbnRlciB0byB0aGUgbmV4dCBzbG90IHdoaWNoIGlzIHVwIHRvIGJlIGRlY29kZWQvYXBwbGllZCBuZXh0ICovCiAgICAgIGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QgPSAoaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCsxKSAlIChzZWxmLT5udW1EZWxheUZyYW1lcysxKTsKICAgICAgLyogVXBkYXRlIGhlYWRlciBhbmQgZnJhbWUgZGF0YSBwb2ludGVyIGJlY2F1c2UgdGhleSBoYXZlIGFscmVhZHkgYmVlbiBzZXQgKi8KICAgICAgaFNickhlYWRlciA9ICZzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XV07CiAgICAgIGhGcmFtZURhdGFMZWZ0ICA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMF0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICAgICAgaEZyYW1lRGF0YVJpZ2h0ID0gJmhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwogICAgfQogIH0KCiAgLyogVXBkYXRlIHRoZSBoZWFkZXIgZXJyb3IgZmxhZyAqLwogIGhTYnJIZWFkZXItPmZyYW1lRXJyb3JGbGFnID0gaFNickVsZW1lbnQtPmZyYW1lRXJyb3JGbGFnW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICAvKgogICAgIFByZXBhcmUgZmlsdGVyYmFuayBmb3IgdXBzYW1wbGluZyBpZiBubyB2YWxpZCBiaXQgc3RyZWFtIGRhdGEgaXMgYXZhaWxhYmxlLgogICAqLwogIGlmICggaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9OT1RfSU5JVElBTElaRUQgKQogIHsKICAgIGVycm9yU3RhdHVzID0gaW5pdEhlYWRlckRhdGEoCiAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgIHNlbGYtPnNhbXBsZVJhdGVJbiwKICAgICAgICAgICAgc2VsZi0+c2FtcGxlUmF0ZU91dCwKICAgICAgICAgICAgY29kZWNGcmFtZVNpemUsCiAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICAgICk7CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICByZXR1cm4gZXJyb3JTdGF0dXM7CiAgICB9CgogICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gVVBTQU1QTElORzsKCiAgICBlcnJvclN0YXR1cyA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBIRUFERVJfTk9UX1BSRVNFTlQsCiAgICAgICAgICAgIHBTYnJDaGFubmVsLAogICAgICAgICAgICBoU2JyRWxlbWVudC0+bkNoYW5uZWxzCiAgICAgICAgICAgICk7CgogICAgaWYgKGVycm9yU3RhdHVzICE9IFNCUkRFQ19PSykgewogICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfTk9UX0lOSVRJQUxJWkVEOwogICAgICByZXR1cm4gZXJyb3JTdGF0dXM7CiAgICB9CiAgfQoKICAvKiByZXNldCAqLwogIGlmIChoU2JySGVhZGVyLT5zdGF0dXMgJiBTQlJERUNfSERSX1NUQVRfUkVTRVQpIHsKICAgIGludCBjaDsKICAgIGZvciAoY2ggPSAwIDsgY2ggPCBudW1FbGVtZW50Q2hhbm5lbHM7IGNoKyspIHsKICAgICAgU0JSX0VSUk9SIGVycm9yU3RhdHVzVG1wID0gU0JSREVDX09LOwoKICAgICAgZXJyb3JTdGF0dXNUbXAgPSByZXNldFNickRlYyAoCiAgICAgICAgICAgICAmcFNickNoYW5uZWxbY2hdLT5TYnJEZWMsCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFtjaF0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSLAogICAgICAgICAgICAgIHNlbGYtPnN5bkRvd25zYW1wbGVGYWMKICAgICAgICAgICAgICApOwoKICAgICAgaWYgKGVycm9yU3RhdHVzVG1wICE9IFNCUkRFQ19PSykgewogICAgICAgIGVycm9yU3RhdHVzID0gZXJyb3JTdGF0dXNUbXA7CiAgICAgIH0KICAgIH0KICAgIGhTYnJIZWFkZXItPnN0YXR1cyAmPSB+U0JSREVDX0hEUl9TVEFUX1JFU0VUOwogIH0KCiAgLyogZGVjb2RpbmcgKi8KICBpZiAoIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0FDVElWRSkKICAgIHx8ICgoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9IRUFERVIpICYmIChoU2JySGVhZGVyLT5mcmFtZUVycm9yRmxhZyA9PSAwKSkgKQogIHsKICAgIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICAgIGRlY29kZVNickRhdGEgKGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAgICAgICAgJnBTYnJDaGFubmVsWzBdLT5wcmV2RnJhbWVEYXRhLAogICAgICAgICAgICAgICAgICAgKHN0ZXJlbykgPyBoRnJhbWVEYXRhUmlnaHQgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgKHN0ZXJlbykgPyAmcFNickNoYW5uZWxbMV0tPnByZXZGcmFtZURhdGEgOiBOVUxMKTsKCgogICAgLyogTm93IHdlIGhhdmUgYSBmdWxsIHBhcmFtZXRlciBzZXQgYW5kIGNhbiBkbyBwYXJhbWV0ZXIKICAgICAgIGJhc2VkIGNvbmNlYWxtZW50IGluc3RlYWQgb2YgcGxhaW4gdXBzYW1wbGluZy4gKi8KICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9BQ1RJVkU7CiAgfQoKICAvKiBkZWNvZGUgUFMgZGF0YSBpZiBhdmFpbGFibGUgKi8KICBpZiAoaF9wc19kICE9IE5VTEwgJiYgcHNQb3NzaWJsZSkgewogICAgaW50IGFwcGx5UHMgPSAxOwoKICAgIC8qIGRlZmluZSB3aGljaCBmcmFtZSBkZWxheSBsaW5lIHNsb3QgdG8gcHJvY2VzcyAqLwogICAgaF9wc19kLT5wcm9jZXNzU2xvdCA9IGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3Q7CgogICAgYXBwbHlQcyA9IERlY29kZVBzKGhfcHNfZCwgaFNickhlYWRlci0+ZnJhbWVFcnJvckZsYWcpOwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFwcGx5UHMpID8gU0JSREVDX1BTX0RFQ09ERUQgOiAwOwogIH0KCiAgLyogU2V0IHN0cmlkZXMgZm9yIHJlYWRpbmcgYW5kIHdyaXRpbmcgKi8KICBpZiAoaW50ZXJsZWF2ZWQpIHsKICAgIHN0cmlkZUluID0gbnVtSW5DaGFubmVsczsKICAgIGlmICggcHNQb3NzaWJsZSApCiAgICAgIHN0cmlkZU91dCA9IChudW1JbkNoYW5uZWxzIDwgMikgPyAyIDogbnVtSW5DaGFubmVsczsKICAgIGVsc2UKICAgICAgc3RyaWRlT3V0ID0gbnVtSW5DaGFubmVsczsKICAgIG9mZnNldDAgPSBjaGFubmVsTWFwcGluZ1swXTsKICAgIG9mZnNldDEgPSBjaGFubmVsTWFwcGluZ1sxXTsKICB9IGVsc2UgewogICAgc3RyaWRlSW4gID0gMTsKICAgIHN0cmlkZU91dCA9IDE7CiAgICBvZmZzZXQwID0gY2hhbm5lbE1hcHBpbmdbMF0qMipjb2RlY0ZyYW1lU2l6ZTsKICAgIG9mZnNldDEgPSBjaGFubmVsTWFwcGluZ1sxXSoyKmNvZGVjRnJhbWVTaXplOwogIH0KCiAgLyogdXNlIHNhbWUgYnVmZmVycyBmb3IgbGVmdCBhbmQgcmlnaHQgY2hhbm5lbCBhbmQgYXBwbHkgUFMgcGVyIHRpbWVzbG90ICovCiAgLyogUHJvY2VzcyBsZWZ0IGNoYW5uZWwgKi8KLy9GREtwcmludGYoInNlbGYtPmNvZGVjRnJhbWVTaXplICVkXHQlZFxuIixzZWxmLT5jb2RlY0ZyYW1lU2l6ZSxzZWxmLT5zYW1wbGVSYXRlSW4pOwogIHNicl9kZWMgKCZwU2JyQ2hhbm5lbFswXS0+U2JyRGVjLAogICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDAsCiAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MCwKICAgICAgICAgICAmcFNickNoYW5uZWxbMV0tPlNickRlYywKICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQxLAogICAgICAgICAgICBzdHJpZGVJbiwKICAgICAgICAgICAgc3RyaWRlT3V0LAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAmcFNickNoYW5uZWxbMF0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgIChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0FDVElWRSksCiAgICAgICAgICAgIGhfcHNfZCwKICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgIGNvZGVjRnJhbWVTaXplCiAgICAgICAgICApOwoKICBpZiAoc3RlcmVvKSB7CiAgICAvKiBQcm9jZXNzIHJpZ2h0IGNoYW5uZWwgKi8KICAgIHNicl9kZWMgKCZwU2JyQ2hhbm5lbFsxXS0+U2JyRGVjLAogICAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MSwKICAgICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDEsCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgIHN0cmlkZUluLAogICAgICAgICAgICAgIHN0cmlkZU91dCwKICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgIGhGcmFtZURhdGFSaWdodCwKICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFsxXS0+cHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgICAoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9BQ1RJVkUpLAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgY29kZWNGcmFtZVNpemUKICAgICAgICAgICAgKTsKICB9CgogIGlmIChoX3BzX2QgIT0gTlVMTCkgewogICAgLyogc2F2ZSBQUyBzdGF0dXMgZm9yIG5leHQgcnVuICovCiAgICBoX3BzX2QtPnBzRGVjb2RlZFBydiA9IChzZWxmLT5mbGFncyAmIFNCUkRFQ19QU19ERUNPREVEKSA/IDEgOiAwIDsKICB9CgogIGlmICggcHNQb3NzaWJsZSAKICAgICkKICB7CiAgICBGREtfQVNTRVJUKHN0cmlkZU91dCA+IDEpOwogICAgaWYgKCAhKHNlbGYtPmZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpICkgewogICAgICAvKiBBIGRlY29kZXIgd2hpY2ggaXMgYWJsZSB0byBkZWNvZGUgUFMgaGFzIHRvIHByb2R1Y2UgYSBzdGVyZW8gb3V0cHV0IGV2ZW4gaWYgbm8gUFMgZGF0YSBpcyBhdmFpbGJsZS4gKi8KICAgICAgLyogU28gY29weSBsZWZ0IGNoYW5uZWwgdG8gcmlnaHQgY2hhbm5lbC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgIGludCBjb3B5RnJhbWVTaXplID0gY29kZWNGcmFtZVNpemUgKiAyIC8gc2VsZi0+c3luRG93bnNhbXBsZUZhYzsKICAgICAgaWYgKGludGVybGVhdmVkKSB7CiAgICAgICAgSU5UX1BDTSAqcHRyOwogICAgICAgIElOVCBpOwogICAgICAgIEZES19BU1NFUlQoc3RyaWRlT3V0ID09IDIpOwoKICAgICAgICBwdHIgPSB0aW1lRGF0YTsKICAgICAgICBmb3IgKGkgPSBjb3B5RnJhbWVTaXplPj4xOyBpLS07ICkKICAgICAgICB7CiAgICAgICAgICBJTlRfUENNIHRtcDsgLyogVGhpcyB0ZW1wb3JhbCB2YXJpYWJsZSBpcyByZXF1aXJlZCBiZWNhdXNlIHNvbWUgY29tcGlsZXJzIGNhbid0IGRvICpwdHIrKyA9ICpwdHIrKyBjb3JyZWN0bHkuICovCiAgICAgICAgICB0bXAgPSAqcHRyKys7ICpwdHIrKyA9IHRtcDsKICAgICAgICAgIHRtcCA9ICpwdHIrKzsgKnB0cisrID0gdG1wOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBGREttZW1jcHkoIHRpbWVEYXRhK2NvcHlGcmFtZVNpemUsIHRpbWVEYXRhLCBjb3B5RnJhbWVTaXplKnNpemVvZihJTlRfUENNKSApOwogICAgICB9CiAgICB9CiAgICAqbnVtT3V0Q2hhbm5lbHMgPSAyOyAgLyogT3V0cHV0IG1pbmltdW0gdHdvIGNoYW5uZWxzIHdoZW4gUFMgaXMgZW5hYmxlZC4gKi8KICB9CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX0FwcGx5ICggSEFORExFX1NCUkRFQ09ERVIgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00gICAgICAgICAgICAqdGltZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICpudW1DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgKnNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNIQVIgICAgICAgICBjaGFubmVsTWFwcGluZ1soOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ICAgICAgICAgICBjb3JlRGVjb2RlZE9rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICAqcHNEZWNvZGVkICkKewogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKCiAgaW50ICAgcHNQb3NzaWJsZSA9IDA7CiAgaW50ICAgc2JyRWxlbWVudE51bTsKICBpbnQgICBudW1Db3JlQ2hhbm5lbHMgPSAqbnVtQ2hhbm5lbHM7CiAgaW50ICAgbnVtU2JyQ2hhbm5lbHMgID0gMDsKCiAgcHNQb3NzaWJsZSA9ICpwc0RlY29kZWQ7CgogIGlmIChzZWxmLT5udW1TYnJFbGVtZW50cyA8IDEpIHsKICAgIC8qIGV4aXQgaW1tZWRpYXRlbHkgdG8gYXZvaWQgYWNjZXNzIHZpb2xhdGlvbnMgKi8KICAgIHJldHVybiBTQlJERUNfQ1JFQVRFX0VSUk9SOwogIH0KCiAgLyogU2FuaXR5IGNoZWNrIG9mIGFsbG9jYXRlZCBTQlIgZWxlbWVudHMuICovCiAgZm9yIChzYnJFbGVtZW50TnVtPTA7IHNickVsZW1lbnROdW08c2VsZi0+bnVtU2JyRWxlbWVudHM7IHNickVsZW1lbnROdW0rKykgewogICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dID09IE5VTEwpIHsKICAgICAgcmV0dXJuIFNCUkRFQ19DUkVBVEVfRVJST1I7CiAgICB9CiAgfQoKICBpZiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgIT0gMSB8fCBzZWxmLT5wU2JyRWxlbWVudFswXS0+ZWxlbWVudElEICE9IElEX1NDRSkgewogICAgcHNQb3NzaWJsZSA9IDA7CiAgfQoKCiAgLyogSW4gY2FzZSBvZiBub24taW50ZXJsZWF2ZWQgdGltZSBkb21haW4gZGF0YSBhbmQgdXBzYW1wbGluZywgbWFrZSByb29tIGZvciBiaWdnZXIgU0JSIG91dHB1dC4gKi8KICBpZiAoc2VsZi0+c3luRG93bnNhbXBsZUZhYyA9PSAxICYmIGludGVybGVhdmVkID09IDApIHsKICAgIGludCBjLCBvdXRwdXRGcmFtZVNpemU7CgogICAgb3V0cHV0RnJhbWVTaXplID0KICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbMF0tPnBTYnJDaGFubmVsWzBdLT5TYnJEZWMuU3ludGhlc2lzUU1GLm5vX2NoYW5uZWxzCiAgICAgICAgICAgICogc2VsZi0+cFNickVsZW1lbnRbMF0tPnBTYnJDaGFubmVsWzBdLT5TYnJEZWMuU3ludGhlc2lzUU1GLm5vX2NvbDsKCiAgICBmb3IgKGM9bnVtQ29yZUNoYW5uZWxzLTE7IGM+MDsgYy0tKSB7CiAgICAgIEZES21lbW1vdmUodGltZURhdGEgKyBjKm91dHB1dEZyYW1lU2l6ZSwgdGltZURhdGEgKyBjKnNlbGYtPmNvZGVjRnJhbWVTaXplICwgc2VsZi0+Y29kZWNGcmFtZVNpemUqc2l6ZW9mKElOVF9QQ00pKTsKICAgIH0KICB9CgoKICAvKiBNYWtlIHN1cmUgdGhhdCBldmVuIGlmIG5vIFNCUiBkYXRhIHdhcyBmb3VuZC9wYXJzZWQgKnBzRGVjb2RlZCBpcyByZXR1cm5lZCAxIGlmIHBzUG9zc2libGUgd2FzIDAuICovCiAgaWYgKHBzUG9zc2libGUgPT0gMCkgewogICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19QU19ERUNPREVEOwogIH0KCiAgaWYgKCBzZWxmLT5mbGFncyAmIFNCUkRFQ19GTFVTSCApIHsKICAgIC8qIGZsdXNoaW5nIGlzIHNpZ25hbGl6ZWQsIGhlbmNlIGluY3JlbWVudCB0aGUgZmx1c2ggZnJhbWUgY291bnRlciAqLwogICAgc2VsZi0+bnVtRmx1c2hlZEZyYW1lcysrOwogIH0KICBlbHNlIHsKICAgIC8qIG5vIGZsdXNoaW5nIGlzIHNpZ25hbGl6ZWQsIGhlbmNlIHJlc2V0IHRoZSBmbHVzaCBmcmFtZSBjb3VudGVyICovCiAgICBzZWxmLT5udW1GbHVzaGVkRnJhbWVzID0gMDsKICB9CgogIC8qIExvb3Agb3ZlciBTQlIgZWxlbWVudHMgKi8KICBmb3IgKHNickVsZW1lbnROdW0gPSAwOyBzYnJFbGVtZW50TnVtPHNlbGYtPm51bVNickVsZW1lbnRzOyBzYnJFbGVtZW50TnVtKyspCiAgewogICAgaW50IG51bUVsZW1lbnRDaGFuOwoKICAgIGlmIChwc1Bvc3NpYmxlICYmIHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT5wU2JyQ2hhbm5lbFsxXSA9PSBOVUxMKSB7CiAgICAgIC8qIERpc2FibGUgUFMgYW5kIHRyeSBkZWNvZGluZyBTQlIgbW9uby4gKi8KICAgICAgcHNQb3NzaWJsZSA9IDA7CiAgICB9CgogICAgbnVtRWxlbWVudENoYW4gPSAoc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0tPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMiA6IDE7CgogICAgLyogSWYgY29yZSBzaWduYWwgaXMgYmFkIHRoZW4gZm9yY2UgdXBzYW1wbGluZyAqLwogICAgaWYgKCAhIGNvcmVEZWNvZGVkT2sgKSB7CiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT5mcmFtZUVycm9yRmxhZ1tzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXS0+dXNlRnJhbWVTbG90XSA9IDE7CiAgICB9CgogICAgZXJyb3JTdGF0dXMgPSBzYnJEZWNvZGVyX0RlY29kZUVsZW1lbnQgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnJFbGVtZW50TnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1Db3JlQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bUVsZW1lbnRDaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc1Bvc3NpYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIG51bVNickNoYW5uZWxzICs9IG51bUVsZW1lbnRDaGFuOwogICAgY2hhbm5lbE1hcHBpbmcgKz0gbnVtRWxlbWVudENoYW47CgogICAgaWYgKG51bVNickNoYW5uZWxzID49IG51bUNvcmVDaGFubmVscykgewogICAgICBicmVhazsKICAgIH0KICB9CgogIC8qIFVwZGF0ZSBudW1DaGFubmVscyBhbmQgc2FtcGxlcmF0ZSAqLwogICpudW1DaGFubmVscyA9IG51bVNickNoYW5uZWxzOwogICpzYW1wbGVSYXRlID0gc2VsZi0+c2FtcGxlUmF0ZU91dDsKICAqcHNEZWNvZGVkID0gKHNlbGYtPmZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpID8gMSA6IDA7CgoKCiAgLyogQ2xlYXIgcmVzZXQgYW5kIGZsdXNoIGZsYWcgYmVjYXVzZSBldmVyeXRoaW5nIHNlZW1zIHRvIGJlIGRvbmUgc3VjY2Vzc2Z1bGx5LiAqLwogIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfRk9SQ0VfUkVTRVQ7CiAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19GTFVTSDsKCmJhaWw6CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX0Nsb3NlICggSEFORExFX1NCUkRFQ09ERVIgKnBTZWxmICkKewogIEhBTkRMRV9TQlJERUNPREVSIHNlbGYgPSAqcFNlbGY7CiAgaW50IGk7CgogIGlmIChzZWxmICE9IE5VTEwpCiAgewogICAgaWYgKHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjICE9IE5VTEwpIHsKICAgICAgRGVsZXRlUHNEZWMgKCAmc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMgKTsKICAgIH0KCiAgICBpZiAoc2VsZi0+d29ya0J1ZmZlcjEgIT0gTlVMTCkgewogICAgICBGcmVlUmFtX1NickRlY1dvcmtCdWZmZXIxKCZzZWxmLT53b3JrQnVmZmVyMSk7CiAgICB9CiAgICBpZiAoc2VsZi0+d29ya0J1ZmZlcjIgIT0gTlVMTCkgewogICAgICBGcmVlUmFtX1NickRlY1dvcmtCdWZmZXIyKCZzZWxmLT53b3JrQnVmZmVyMik7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8ICg4KTsgaSsrKSB7CiAgICAgIHNickRlY29kZXJfRGVzdHJveUVsZW1lbnQoIHNlbGYsIGkgKTsKICAgIH0KCiAgICBGcmVlUmFtX1NickRlY29kZXIocFNlbGYpOwogIH0KCiAgcmV0dXJuIFNCUkRFQ19PSzsKfQoKCklOVCBzYnJEZWNvZGVyX0dldExpYkluZm8oIExJQl9JTkZPICppbmZvICkKewogIGludCBpOwoKICBpZiAoaW5mbyA9PSBOVUxMKSB7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBzZWFyY2ggZm9yIG5leHQgZnJlZSB0YWIgKi8KICBmb3IgKGkgPSAwOyBpIDwgRkRLX01PRFVMRV9MQVNUOyBpKyspIHsKICAgIGlmIChpbmZvW2ldLm1vZHVsZV9pZCA9PSBGREtfTk9ORSkKICAgICAgYnJlYWs7CiAgfQogIGlmIChpID09IEZES19NT0RVTEVfTEFTVCkKICAgIHJldHVybiAtMTsKICBpbmZvICs9IGk7CgogIGluZm8tPm1vZHVsZV9pZCA9IEZES19TQlJERUM7CiAgaW5mby0+dmVyc2lvbiA9IExJQl9WRVJTSU9OKFNCUkRFQ09ERVJfTElCX1ZMMCwgU0JSREVDT0RFUl9MSUJfVkwxLCBTQlJERUNPREVSX0xJQl9WTDIpOwogIExJQl9WRVJTSU9OX1NUUklORyhpbmZvKTsKICBpbmZvLT5idWlsZF9kYXRlID0gKGNoYXIgKilTQlJERUNPREVSX0xJQl9CVUlMRF9EQVRFOwogIGluZm8tPmJ1aWxkX3RpbWUgPSAoY2hhciAqKVNCUkRFQ09ERVJfTElCX0JVSUxEX1RJTUU7CiAgaW5mby0+dGl0bGUgICAgICA9IChjaGFyICopU0JSREVDT0RFUl9MSUJfVElUTEU7CgogIC8qIFNldCBmbGFncyAqLwogIGluZm8tPmZsYWdzID0gMAogICAgfCBDQVBGX1NCUl9IUQogICAgfCBDQVBGX1NCUl9MUAogICAgfCBDQVBGX1NCUl9QU19NUEVHCiAgICB8IENBUEZfU0JSX0RSTV9CUwogICAgfCBDQVBGX1NCUl9DT05DRUFMTUVOVAogICAgfCBDQVBGX1NCUl9EUkMKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gMDsKfQoKClVJTlQgc2JyRGVjb2Rlcl9HZXREZWxheSggY29uc3QgSEFORExFX1NCUkRFQ09ERVIgc2VsZiApCnsKICBVSU5UIG91dHB1dERlbGF5ID0gMDsKCiAgaWYgKCBzZWxmICE9IE5VTEwpIHsKICAgIFVJTlQgZmxhZ3MgPSBzZWxmLT5mbGFnczsKCiAgICAvKiBTZWUgY2hhcHRlciAxLjYuNy4yIG9mIElTTy9JRUMgMTQ0OTYtMyBmb3IgdGhlIEdBLVNCUiBmaWd1cmVzIGJlbG93LiAqLwoKICAgIC8qIEFyZSB3ZSBpbml0aWFsaXplZD8gKi8KICAgIGlmICggKHNlbGYtPm51bVNickNoYW5uZWxzID4gMCkKICAgICAgJiYgKHNlbGYtPm51bVNickVsZW1lbnRzID4gMCkgKQogICAgewogICAgICAvKiBBZGQgUU1GIHN5bnRoZXNpcyBkZWxheSAqLwogICAgICBpZiAoIChmbGFncyAmIFNCUkRFQ19FTERfR1JJRCkKICAgICAgICAmJiBJU19MT1dERUxBWShzZWxmLT5jb3JlQ29kZWMpICkgewogICAgICAgIC8qIExvdyBkZWxheSBTQlI6ICovCiAgICAgICAgewogICAgICAgICAgb3V0cHV0RGVsYXkgKz0gKGZsYWdzICYgU0JSREVDX0RPV05TQU1QTEUpID8gMzIgOiA2NDsgICAvKiBRTUYgc3ludGhlc2lzICovCiAgICAgICAgICBpZiAoZmxhZ3MgJiBTQlJERUNfTERfTVBTX1FNRikgewogICAgICAgICAgICBvdXRwdXREZWxheSArPSAzMjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSBpZiAoIUlTX1VTQUMoc2VsZi0+Y29yZUNvZGVjKSkgewogICAgICAgIC8qIEJ5IHRoZSBtZXRob2Qgb2YgZWxpbWluYXRpb24gdGhpcyBpcyB0aGUgR0EgKEFBQy1MQywgSEUtQUFDLCAuLi4pIGJyYW5jaDogKi8KICAgICAgICBvdXRwdXREZWxheSArPSAoZmxhZ3MgJiBTQlJERUNfRE9XTlNBTVBMRSkgPyA0ODEgOiA5NjI7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiAob3V0cHV0RGVsYXkpOwp9Cg==