Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgU0JSIGRlY29kZXIgZnJvbnRlbmQKICBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIGZyb250ZW5kIHRvIHRoZSBTQlIgZGVjb2Rlci4gVGhlIGZ1bmN0aW9uIG9wZW5TQlIoKSBpcyBjYWxsZWQgZm9yCiAgaW5pdGlhbGl6YXRpb24uIFRoZSBmdW5jdGlvbiBzYnJEZWNvZGVyX0FwcGx5KCkgaXMgY2FsbGVkIGZvciBlYWNoIGZyYW1lLiBzYnJfQXBwbHkoKSB3aWxsIGNhbGwgdGhlCiAgcmVxdWlyZWQgZnVuY3Rpb25zIHRvIGRlY29kZSB0aGUgcmF3IFNCUiBkYXRhIChwcm92aWRlZCBieSBlbnZfZXh0ci5jcHApLCB0byBkZWNvZGUgdGhlIGVudmVsb3BlIGRhdGEgYW5kIG5vaXNlIGZsb29yIGxldmVscyBbZGVjb2RlU2JyRGF0YSgpXSwKICBhbmQgdG8gZmluYWxseSBhcHBseSBTQlIgdG8gdGhlIGN1cnJlbnQgZnJhbWUgW3Nicl9kZWMoKV0uCgogIFxzYSBzYnJEZWNvZGVyX0FwcGx5KCksIFxyZWYgZG9jdW1lbnRhdGlvbk92ZXJ2aWV3CiovCgovKiEKICBccGFnZSBkb2N1bWVudGF0aW9uT3ZlcnZpZXcgT3ZlcnZpZXcgb2YgaW1wb3J0YW50IGluZm9ybWF0aW9uIHJlc291cmNlcyBhbmQgc291cmNlIGNvZGUgZG9jdW1lbnRhdGlvbgoKICBUaGUgcHJpbWFyeSBzb3VyY2UgY29kZSBkb2N1bWVudGF0aW9uIGlzIGJhc2VkIG9uIGdlbmVyYXRlZCBhbmQgY3Jvc3MtcmVmZXJlbmNlZCBIVE1MIGZpbGVzIHVzaW5nCiAgPGEgSFJFRj0iaHR0cDovL3d3dy5kb3h5Z2VuLm9yZyI+ZG94eWdlbjwvYT4uIEFzIHBhcnQgb2YgdGhpcyBkb2N1bWVudGF0aW9uCiAgeW91IGNhbiBmaW5kIG1vcmUgZXh0ZW5zaXZlIGRlc2NyaXB0aW9ucyBhYm91dCBrZXkgY29uY2VwdHMgYW5kIGFsZ29yaXRobXMgYXQgdGhlIGZvbGxvd2luZyBsb2NhdGlvbnM6CgogIDxoMj5Qcm9ncmFtbWluZzwvaDI+CgogIFxsaSBCdWZmZXIgbWFuYWdlbWVudDogc2JyRGVjb2Rlcl9BcHBseSgpIGFuZCBzYnJfZGVjKCkKICBcbGkgSW50ZXJuYWwgc2NhbGUgZmFjdG9ycyB0byBtYXhpbWl6ZSBTTlIgb24gZml4ZWQgcG9pbnQgcHJvY2Vzc29yczogI1FNRl9TQ0FMRV9GQUNUT1IKICBcbGkgU3BlY2lhbCBtYW50aXNzYS1leHBvbmVudCBmb3JtYXQ6IENyZWF0ZWQgaW4gcmVxdWFudGl6ZUVudmVsb3BlRGF0YSgpIGFuZCB1c2VkIGluIGNhbGN1bGF0ZVNickVudmVsb3BlKCkKCiAgPGgyPkFsZ29yaXRobWljIGRldGFpbHM8L2gyPgogIFxsaSBBYm91dCB0aGUgU0JSIGRhdGEgZm9ybWF0OiBccmVmIFNCUl9IRUFERVJfRUxFTUVOVCBhbmQgXHJlZiBTQlJfU1RBTkRBUkRfRUxFTUVOVAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSBiaXRzdHJlYW0gZGVjb2RlcjogZW52X2V4dHIuY3BwCiAgXGxpIERldGFpbHMgYWJvdXQgdGhlIFFNRiBmaWx0ZXJiYW5rIGFuZCB0aGUgcHJvdmlkZWQgcG9seXBoYXNlIGltcGxlbWVudGF0aW9uOiBxbWZfZGVjLmNwcAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSB0cmFuc3Bvc2VyOiBscHBfdHJhbi5jcHAKICBcbGkgRGV0YWlscyBhYm91dCB0aGUgZW52ZWxvcGUgYWRqdXN0ZXI6IGVudl9jYWxjLmNwcAoKKi8KCiNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgojaW5jbHVkZSAiRkRLX2JpdHN0cmVhbS5oIgoKI2luY2x1ZGUgInNicmRlY19mcmVxX3NjYS5oIgojaW5jbHVkZSAiZW52X2V4dHIuaCIKI2luY2x1ZGUgInNicl9kZWMuaCIKI2luY2x1ZGUgImVudl9kZWMuaCIKI2luY2x1ZGUgInNicl9jcmMuaCIKI2luY2x1ZGUgInNicl9yYW0uaCIKI2luY2x1ZGUgInNicl9yb20uaCIKI2luY2x1ZGUgImxwcF90cmFuLmgiCiNpbmNsdWRlICJ0cmFuc2NlbmRlbnQuaCIKCgojaW5jbHVkZSAic2JyZGVjX2RyYy5oIgoKI2luY2x1ZGUgInBzYml0ZGVjLmgiCgoKLyogRGVjb2RlciBsaWJyYXJ5IGluZm8gKi8KI2RlZmluZSBTQlJERUNPREVSX0xJQl9WTDAgMgojZGVmaW5lIFNCUkRFQ09ERVJfTElCX1ZMMSAyCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfVkwyIDYKI2RlZmluZSBTQlJERUNPREVSX0xJQl9USVRMRSAiU0JSIERlY29kZXIiCiNpZmRlZiBfX0FORFJPSURfXwojZGVmaW5lIFNCUkRFQ09ERVJfTElCX0JVSUxEX0RBVEUgIiIKI2RlZmluZSBTQlJERUNPREVSX0xJQl9CVUlMRF9USU1FICIiCiNlbHNlCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfQlVJTERfREFURSBfX0RBVEVfXwojZGVmaW5lIFNCUkRFQ09ERVJfTElCX0JVSUxEX1RJTUUgX19USU1FX18KI2VuZGlmCgoKCgpzdGF0aWMgVUNIQVIgZ2V0SGVhZGVyU2xvdCggVUNIQVIgY3VycmVudFNsb3QsIFVDSEFSIGhkclNsb3RVc2FnZVsoMSkrMV0gKQp7CiAgVUlOVCAgb2NjdXBpZWQgPSAwOwogIGludCAgIHM7CiAgVUNIQVIgc2xvdCA9IGhkclNsb3RVc2FnZVtjdXJyZW50U2xvdF07CgogIEZES19BU1NFUlQoKDEpKzEgPCAzMik7CgogIGZvciAocyA9IDA7IHMgPCAoMSkrMTsgcysrKSB7CiAgICBpZiAoIChoZHJTbG90VXNhZ2Vbc10gPT0gc2xvdCkKICAgICAgJiYgKHMgIT0gc2xvdCkgKSB7CiAgICAgIG9jY3VwaWVkID0gMTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICBpZiAob2NjdXBpZWQpIHsKICAgIG9jY3VwaWVkID0gMDsKCiAgICBmb3IgKHMgPSAwOyBzIDwgKDEpKzE7IHMrKykgewogICAgICBvY2N1cGllZCB8PSAxIDw8IGhkclNsb3RVc2FnZVtzXTsKICAgIH0KICAgIGZvciAocyA9IDA7IHMgPCAoMSkrMTsgcysrKSB7CiAgICAgIGlmICggIShvY2N1cGllZCAmIDB4MSkgKSB7CiAgICAgICAgc2xvdCA9IHM7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgb2NjdXBpZWQgPj49IDE7CiAgICB9CiAgfQoKICByZXR1cm4gc2xvdDsKfQoKc3RhdGljIHZvaWQgY29weVNickhlYWRlciggSEFORExFX1NCUl9IRUFERVJfREFUQSBoRHN0LCBjb25zdCBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTcmMgKQp7CiAgLyogY29weSB0aGUgd2hvbGUgaGVhZGVyIG1lbW9yeSAoaW5jbHVkaW5nIHBvaW50ZXJzKSAqLwogIEZES21lbWNweSggaERzdCwgaFNyYywgc2l6ZW9mKFNCUl9IRUFERVJfREFUQSkgKTsKCiAgLyogdXBkYXRlIHBvaW50ZXJzICovCiAgaERzdC0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVbMF0gID0gaERzdC0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVMbzsKICBoRHN0LT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZVsxXSA9IGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlSGk7Cn0KCgovKiEKICBcYnJpZWYgUmVzZXQgU0JSIGRlY29kZXIuCgogIFJlc2V0IHNob3VsZCBvbmx5IGJlIGNhbGxlZCBpZiBTQlIgaGFzIGJlZW4gc3VjZXNzZnVsbHkgZGV0ZWN0ZWQgYnkKICBhbiBhcHByb3ByaWF0ZSBjaGVja0ZvclBheWxvYWQoKSBmdW5jdGlvbi4KCiAgXHJldHVybiBFcnJvciBjb2RlLgoqLwpzdGF0aWMKU0JSX0VSUk9SIHNickRlY29kZXJfUmVzZXRFbGVtZW50ICgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiAgICBzZWxmLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgIGludCAgICAgICAgICAgICAgICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICBjb25zdCBNUDRfRUxFTUVOVF9JRCBlbGVtZW50SUQsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgZWxlbWVudEluZGV4LAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIG92ZXJsYXAKICAgICAgICApCnsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CiAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyOwogIFVJTlQgcW1mRmxhZ3MgPSAwOwoKICBpbnQgaSwgc3luRG93bnNhbXBsZUZhYzsKCiAgLyogQ2hlY2sgaW4vb3V0IHNhbXBsZXJhdGVzICovCiAgaWYgKCBzYW1wbGVSYXRlSW4gPCA2NDAwCiAgICB8fCBzYW1wbGVSYXRlSW4gPiA0ODAwMAogICAgICkKICB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBpZiAoIHNhbXBsZVJhdGVPdXQgPiA5NjAwMCApCiAgewogICAgc2JyRXJyb3IgPSBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgZ290byBiYWlsOwogIH0KCiAgLyogU2V0IFFNRiBtb2RlIGZsYWdzICovCiAgaWYgKHNlbGYtPmZsYWdzICYgU0JSREVDX0xPV19QT1dFUikKICAgIHFtZkZsYWdzIHw9IFFNRl9GTEFHX0xQOwoKICBpZiAoc2VsZi0+Y29yZUNvZGVjID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICBpZiAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfTERfTVBTX1FNRikgewogICAgICBxbWZGbGFncyB8PSAgUU1GX0ZMQUdfTVBTTERGQjsKICAgIH0gZWxzZSB7CiAgICAgIHFtZkZsYWdzIHw9ICBRTUZfRkxBR19DTERGQjsKICAgIH0KICB9CgogIC8qIFNldCBkb3duc2FtcGxpbmcgZmFjdG9yIGZvciBzeW50aGVzaXMgZmlsdGVyIGJhbmsgKi8KICBpZiAoc2FtcGxlUmF0ZU91dCA9PSAwKQogIHsKICAgIC8qIG5vIHNpbmdsZSByYXRlIG1vZGUgKi8KICAgICAgc2FtcGxlUmF0ZU91dCA9IHNhbXBsZVJhdGVJbjw8MTsgLyogSW4gY2FzZSBvZiBpbXBsaWNpdCBzaWduYWxsaW5nLCBhc3N1bWUgZHVhbCByYXRlIFNCUiAqLwogIH0KCiAgaWYgKCBzYW1wbGVSYXRlSW4gPT0gc2FtcGxlUmF0ZU91dCApIHsKICAgIHN5bkRvd25zYW1wbGVGYWMgPSAyOwogICAgc2VsZi0+ZmxhZ3MgfD0gIFNCUkRFQ19ET1dOU0FNUExFOwogIH0gZWxzZSB7CiAgICBzeW5Eb3duc2FtcGxlRmFjID0gMTsKICAgIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfRE9XTlNBTVBMRTsKICB9CgogIHNlbGYtPnN5bkRvd25zYW1wbGVGYWMgPSBzeW5Eb3duc2FtcGxlRmFjOwogIHNlbGYtPnNhbXBsZVJhdGVPdXQgPSBzYW1wbGVSYXRlT3V0OwoKICB7CiAgICBpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgKDEpKzE7IGkrKykKICAgIHsKICAgICAgaFNickhlYWRlciA9ICYoc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baV0pOwoKICAgICAgLyogaW5pdCBhIGRlZmF1bHQgaGVhZGVyIHN1Y2ggdGhhdCB3ZSBjYW4gYXQgbGVhc3QgZG8gdXBzYW1wbGluZyBsYXRlciAqLwogICAgICBzYnJFcnJvciA9IGluaXRIZWFkZXJEYXRhKAogICAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICAgICAgKTsKICAgIH0KICB9CgogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qIEluaXQgU0JSIGNoYW5uZWxzIGdvaW5nIHRvIGJlIGFzc2lnbmVkIHRvIGEgU0JSIGVsZW1lbnQgKi8KICB7CiAgICBpbnQgY2g7CgogICAgZm9yIChjaD0wOyBjaDxzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5uQ2hhbm5lbHM7IGNoKyspCiAgICB7CiAgICAgIC8qIGFuZCBjcmVhdGUgc2JyRGVjICovCiAgICAgIHNickVycm9yID0gY3JlYXRlU2JyRGVjIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT50cmFuc3Bvc2VyU2V0dGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3luRG93bnNhbXBsZUZhYywKICAgICAgICAgICAgICAgICAgICAgICAgICBxbWZGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGFwLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoICk7CgogICAgICBpZiAoc2JyRXJyb3IgIT0gU0JSREVDX09LKSB7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9CiAgfQoKICAvL0ZES21lbWNsZWFyKHNicl9PdmVybGFwQnVmZmVyLCBzaXplb2Yoc2JyX092ZXJsYXBCdWZmZXIpKTsKCiAgaWYgKHNlbGYtPm51bVNickVsZW1lbnRzID09IDEpIHsKICAgIHN3aXRjaCAoIHNlbGYtPmNvcmVDb2RlYyApIHsKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX1NCUjoKICAgIGNhc2UgQU9UX1BTOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9EUk1fQUFDOgogICAgY2FzZSBBT1RfRFJNX1NVUlJPVU5EOgogICAgICBpZiAoQ3JlYXRlUHNEZWMgKCAmc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMsIHNhbXBsZXNQZXJGcmFtZSApKSB7CiAgICAgICAgc2JyRXJyb3IgPSBTQlJERUNfQ1JFQVRFX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgLyogSW5pdCBmcmFtZSBkZWxheSBzbG90IGhhbmRsaW5nICovCiAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlRnJhbWVTbG90ID0gMDsKICBmb3IgKGkgPSAwOyBpIDwgKCgxKSsxKTsgaSsrKSB7CiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VIZWFkZXJTbG90W2ldID0gaTsKICB9CgpiYWlsOgoKICByZXR1cm4gc2JyRXJyb3I7Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9PcGVuICggSEFORExFX1NCUkRFQ09ERVIgICogcFNlbGYgKQp7CiAgSEFORExFX1NCUkRFQ09ERVIgICAgc2VsZiA9IE5VTEw7CiAgU0JSX0VSUk9SIHNickVycm9yID0gU0JSREVDX09LOwoKICAvKiBHZXQgbWVtb3J5IGZvciB0aGlzIGluc3RhbmNlICovCiAgc2VsZiA9IEdldFJhbV9TYnJEZWNvZGVyKCk7CiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgc2JyRXJyb3IgPSBTQlJERUNfTUVNX0FMTE9DX0ZBSUxFRDsKICAgIGdvdG8gYmFpbDsKICB9CgogIHNlbGYtPndvcmtCdWZmZXIxID0gR2V0UmFtX1NickRlY1dvcmtCdWZmZXIxKCk7CiAgc2VsZi0+d29ya0J1ZmZlcjIgPSBHZXRSYW1fU2JyRGVjV29ya0J1ZmZlcjIoKTsKCiAgaWYgKCAgc2VsZi0+d29ya0J1ZmZlcjEgPT0gTlVMTAogICAgIHx8IHNlbGYtPndvcmtCdWZmZXIyID09IE5VTEwgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX01FTV9BTExPQ19GQUlMRUQ7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKgogIEFscmVhZHkgemVybyBiZWNhdXNlIG9mIGNhbGxvYwogIHNlbGYtPm51bVNickVsZW1lbnRzID0gMDsKICBzZWxmLT5udW1TYnJDaGFubmVscyA9IDA7CiAgc2VsZi0+Y29kZWNGcmFtZVNpemUgPSAwOwogICovCgogIHNlbGYtPm51bURlbGF5RnJhbWVzID0gKDEpOyAgLyogc2V0IHRvIHRoZSBtYXggdmFsdWUgYnkgZGVmYXVsdCAqLwoKICAqcFNlbGYgPSBzZWxmOwoKYmFpbDoKICByZXR1cm4gc2JyRXJyb3I7Cn0KCi8qKgogKiBcYnJpZWYgZGV0ZXJtaW5lIGlmIHRoZSBnaXZlbiBjb3JlIGNvZGVjIEFPVCBjYW4gYmUgcHJvY2Vzc2VkIG9yIG5vdC4KICogXHBhcmFtIGNvcmVDb2RlYyBjb3JlIGNvZGVjIGF1ZGlvIG9iamVjdCB0eXBlLgogKiBccmV0dXJuIDEgaWYgU0JSIGNhbiBiZSBwcm9jZXNzZWQsIDAgaWYgU0JSIGNhbm5vdCBiZSBwcm9jZXNzZWQvYXBwbGllZC4KICovCnN0YXRpYwppbnQgc2JyRGVjb2Rlcl9pc0NvcmVDb2RlY1ZhbGlkKEFVRElPX09CSkVDVF9UWVBFIGNvcmVDb2RlYykKewogIHN3aXRjaCAoY29yZUNvZGVjKSB7CiAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICBjYXNlIEFPVF9TQlI6CiAgICBjYXNlIEFPVF9QUzoKICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgcmV0dXJuIDE7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gMDsKICB9Cn0KCnN0YXRpYwp2b2lkIHNickRlY29kZXJfRGVzdHJveUVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgICAgIHNlbGYsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gIT0gTlVMTCkgewogICAgaW50IGNoOwoKICAgIGZvciAoY2g9MDsgY2g8U0JSREVDX01BWF9DSF9QRVJfRUxFTUVOVDsgY2grKykgewogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICE9IE5VTEwpIHsKICAgICAgICBkZWxldGVTYnJEZWMoIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgICAgIEZyZWVSYW1fU2JyRGVjQ2hhbm5lbCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgICAgIHNlbGYtPm51bVNickNoYW5uZWxzIC09IDE7CiAgICAgIH0KICAgIH0KICAgIEZyZWVSYW1fU2JyRGVjRWxlbWVudCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gKTsKICAgIHNlbGYtPm51bVNickVsZW1lbnRzIC09IDE7CiAgfQp9CgoKU0JSX0VSUk9SIHNickRlY29kZXJfSW5pdEVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgICAgIHNlbGYsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IEFVRElPX09CSkVDVF9UWVBFIGNvcmVDb2RlYywKICAgICAgICBjb25zdCBNUDRfRUxFTUVOVF9JRCAgICBlbGVtZW50SUQsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgZWxlbWVudEluZGV4CiAgICAgICAgKQp7CiAgU0JSX0VSUk9SIHNickVycm9yID0gU0JSREVDX09LOwogIGludCBjaENudD0wOwogIGludCBuU2JyRWxlbWVudHNTdGFydCA9IHNlbGYtPm51bVNickVsZW1lbnRzOwoKICAvKiBDaGVjayBjb3JlIGNvZGVjIEFPVCAqLwogIGlmICghIHNickRlY29kZXJfaXNDb3JlQ29kZWNWYWxpZChjb3JlQ29kZWMpIHx8IGVsZW1lbnRJbmRleCA+PSAoOCkpIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggZWxlbWVudElEICE9IElEX1NDRSAmJiBlbGVtZW50SUQgIT0gSURfQ1BFICYmIGVsZW1lbnRJRCAhPSBJRF9MRkUgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggIHNlbGYtPnNhbXBsZVJhdGVJbiA9PSBzYW1wbGVSYXRlSW4KICAgICAmJiBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9PSBzYW1wbGVzUGVyRnJhbWUKICAgICAmJiBzZWxmLT5jb3JlQ29kZWMgPT0gY29yZUNvZGVjCiAgICAgJiYgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMCiAgICAgJiYgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZWxlbWVudElEID09IGVsZW1lbnRJRAogICAgICYmICEoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfRk9SQ0VfUkVTRVQpCiAgICAgKQogIHsKICAgICAvKiBOb3RoaW5nIHRvIGRvICovCiAgICAgcmV0dXJuIFNCUkRFQ19PSzsKICB9CgogIHNlbGYtPnNhbXBsZVJhdGVJbiA9IHNhbXBsZVJhdGVJbjsKICBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9IHNhbXBsZXNQZXJGcmFtZTsKICBzZWxmLT5jb3JlQ29kZWMgPSBjb3JlQ29kZWM7CgogIHNlbGYtPmZsYWdzID0gMDsKICBzZWxmLT5mbGFncyB8PSAoY29yZUNvZGVjID09IEFPVF9FUl9BQUNfRUxEKSA/IFNCUkRFQ19FTERfR1JJRCA6IDA7CgogIC8qIEluaXQgU0JSIGVsZW1lbnRzICovCiAgewogICAgaW50IGVsQ2hhbm5lbHMsIGNoOwoKICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID09IE5VTEwpIHsKICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSA9IEdldFJhbV9TYnJEZWNFbGVtZW50KGVsZW1lbnRJbmRleCk7CiAgICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID09IE5VTEwpIHsKICAgICAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgICBzZWxmLT5udW1TYnJFbGVtZW50cyArKzsKICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPm51bVNickNoYW5uZWxzIC09IHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPm5DaGFubmVsczsKICAgIH0KCiAgICAvKiBTYXZlIGVsZW1lbnQgSUQgZm9yIHNhbml0eSBjaGVja3MgYW5kIHRvIGhhdmUgYSBmYWxsYmFjayBmb3IgY29uY2VhbG1lbnQuICovCiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5lbGVtZW50SUQgPSBlbGVtZW50SUQ7CgogICAgLyogRGV0ZXJtaW5lIGFtb3VudCBvZiBjaGFubmVscyBmb3IgdGhpcyBlbGVtZW50ICovCiAgICBzd2l0Y2ggKGVsZW1lbnRJRCkgewogICAgICBjYXNlIElEX05PTkU6CiAgICAgIGNhc2UgSURfQ1BFOiBlbENoYW5uZWxzPTI7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgSURfTEZFOgogICAgICBjYXNlIElEX1NDRTogZWxDaGFubmVscz0xOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OiBlbENoYW5uZWxzPTA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyogSGFuZGxlIGNhc2Ugb2YgUGFyYW1ldHJpYyBTdGVyZW8gKi8KICAgIGlmICggZWxlbWVudEluZGV4ID09IDAgJiYgZWxlbWVudElEID09IElEX1NDRSApIHsKICAgICAgc3dpdGNoIChjb3JlQ29kZWMpIHsKICAgICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgICAgY2FzZSBBT1RfU0JSOgogICAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgICAgIGNhc2UgQU9UX0RSTV9BQUM6CiAgICAgICAgY2FzZSBBT1RfRFJNX1NVUlJPVU5EOgogICAgICAgICAgZWxDaGFubmVscyA9IDI7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5uQ2hhbm5lbHMgPSBlbENoYW5uZWxzOwoKICAgIGZvciAoY2g9MDsgY2g8ZWxDaGFubmVsczsgY2grKykKICAgIHsKICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgc2VsZi0+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+bnVtU2JyQ2hhbm5lbHMgPT0gMCkgKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBGaW5kIHRoZSByaWdodCBTQlIgY2hhbm5lbCAqLwogIHBTYnJEcmNDaGFubmVsRGF0YSA9IHNickRlY29kZXJfZHJjR2V0Q2hhbm5lbCggc2VsZiwgY2ggKTsKCiAgaWYgKCBwU2JyRHJjQ2hhbm5lbERhdGEgIT0gTlVMTCApIHsKICAgIHNickRlY29kZXJfZHJjSW5pdENoYW5uZWwoIHBTYnJEcmNDaGFubmVsRGF0YSApOwogIH0KfQoKCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9QYXJzZSgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICBoQnMsCiAgICAgICAgaW50ICpjb3VudCwKICAgICAgICBpbnQgIGJzUGF5TGVuLAogICAgICAgIGludCAgY3JjRmxhZywKICAgICAgICBNUDRfRUxFTUVOVF9JRCBwcmV2RWxlbWVudCwKICAgICAgICBpbnQgZWxlbWVudEluZGV4LAogICAgICAgIGludCBmR2xvYmFsSW5kZXBlbmRlbmN5RmxhZwogICAgICAgICkKewogIFNCUl9ERUNPREVSX0VMRU1FTlQgICAqaFNickVsZW1lbnQ7CiAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyOwogIEhBTkRMRV9TQlJfQ0hBTk5FTCAgICAqcFNickNoYW5uZWw7CgogIFNCUl9GUkFNRV9EQVRBICpoRnJhbWVEYXRhTGVmdDsKICBTQlJfRlJBTUVfREFUQSAqaEZyYW1lRGF0YVJpZ2h0OwoKICBTQlJfRVJST1IgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CiAgU0JSX1NZTkNfU1RBVEUgaW5pdGlhbFN5bmNTdGF0ZTsKICBTQlJfSEVBREVSX1NUQVRVUyBoZWFkZXJTdGF0dXMgPSBIRUFERVJfTk9UX1BSRVNFTlQ7CgogIElOVCAgc3RhcnRQb3M7CiAgSU5UICBDUkNMZW4gPSAwOwoKICBpbnQgIHN0ZXJlbzsKICBpbnQgIGZEb0RlY29kZVNickRhdGEgPSAxOwoKICBpbnQgbGFzdFNsb3QsIGxhc3RIZHJTbG90ID0gMCwgdGhpc0hkclNsb3Q7CgogIC8qIFJlbWVtYmVyIHN0YXJ0IHBvc2l0aW9uIG9mICBTQlIgZWxlbWVudCAqLwogIHN0YXJ0UG9zID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogIC8qIFNCUiBzYW5pdHkgY2hlY2tzICovCiAgaWYgKCBzZWxmID09IE5VTEwgfHwgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSA9PSBOVUxMICkgewogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgZ290byBiYWlsOwogIH0gCgogIGhTYnJFbGVtZW50ID0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XTsKCiAgbGFzdFNsb3QgICAgPSAoaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCA+IDApID8gaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdC0xIDogc2VsZi0+bnVtRGVsYXlGcmFtZXM7CiAgbGFzdEhkclNsb3QgPSAgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbbGFzdFNsb3RdOwogIHRoaXNIZHJTbG90ID0gIGdldEhlYWRlclNsb3QoIGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QsIGhTYnJFbGVtZW50LT51c2VIZWFkZXJTbG90ICk7ICAvKiBHZXQgYSBmcmVlIGhlYWRlciBzbG90IG5vdCB1c2VkIGJ5IGZyYW1lcyBub3QgcHJvY2Vzc2VkIHlldC4gKi8KCiAgLyogQXNzaWduIHRoZSBmcmVlIHNsb3QgdG8gc3RvcmUgYSBuZXcgaGVhZGVyIGlmIHRoZXJlIGlzIG9uZS4gKi8KICBoU2JySGVhZGVyID0gJnNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW3RoaXNIZHJTbG90XTsKCiAgcFNickNoYW5uZWwgPSBoU2JyRWxlbWVudC0+cFNickNoYW5uZWw7CiAgc3RlcmVvID0gKGhTYnJFbGVtZW50LT5lbGVtZW50SUQgPT0gSURfQ1BFKSA/IDEgOiAwOwoKICBoRnJhbWVEYXRhTGVmdCAgPSAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbMF0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICBoRnJhbWVEYXRhUmlnaHQgPSAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbMV0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKCiAgaW5pdGlhbFN5bmNTdGF0ZSA9IGhTYnJIZWFkZXItPnN5bmNTdGF0ZTsKCiAgLyogcmVzZXQgUFMgZmxhZzsgd2lsbCBiZSBzZXQgYWZ0ZXIgUFMgd2FzIGZvdW5kICovCiAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19QU19ERUNPREVEOwoKICBpZiAoaFNickhlYWRlci0+c3RhdHVzICYgU0JSREVDX0hEUl9TVEFUX1VQREFURSkgewogICAgLyogR290IGEgbmV3IGhlYWRlciBmcm9tIGV4dGVybiAoZS5nLiBmcm9tIGFuIEFTQykgKi8KICAgIGhlYWRlclN0YXR1cyA9IEhFQURFUl9PSzsKICAgIGhTYnJIZWFkZXItPnN0YXR1cyAmPSB+U0JSREVDX0hEUl9TVEFUX1VQREFURTsKICB9CiAgZWxzZSBpZiAodGhpc0hkclNsb3QgIT0gbGFzdEhkclNsb3QpIHsKICAgIC8qIENvcHkgdGhlIGxhc3QgaGVhZGVyIGludG8gdGhpcyBzbG90IG90aGVyd2lzZSB0aGUKICAgICAgIGhlYWRlciBjb21wYXJlIHdpbGwgdHJpZ2dlciBtb3JlIEhFQURFUl9SRVNFVHMgdGhhbiBuZWVkZWQuICovCiAgICBjb3B5U2JySGVhZGVyKCBoU2JySGVhZGVyLCAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1bbGFzdEhkclNsb3RdICk7CiAgfQoKICAvKgogICAgIENoZWNrIGlmIGJpdCBzdHJlYW0gZGF0YSBpcyB2YWxpZCBhbmQgbWF0Y2hlcyB0aGUgZWxlbWVudCBjb250ZXh0CiAgKi8KICBpZiAoICgocHJldkVsZW1lbnQgIT0gSURfU0NFKSAmJiAocHJldkVsZW1lbnQgIT0gSURfQ1BFKSkgfHwgcHJldkVsZW1lbnQgIT0gaFNickVsZW1lbnQtPmVsZW1lbnRJRCkgewogICAgLyogSW4gY2FzZSBvZiBMRkUgd2UgYWxzbyBsYW5kIGhlcmUsIHNpbmNlIHRoZXJlIGlzIG5vIExGRSBTQlIgZWxlbWVudCAoZG8gdXBzYW1wbGluZyBvbmx5KSAqLwogICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgfQoKICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpZiAoKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKSA8PSAwKSB7CiAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgfQogIH0KCiAgLyoKICAgICBTQlIgQ1JDLWNoZWNrCiAgKi8KICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpZiAoY3JjRmxhZyA9PSAxKSB7CiAgICAgIHN3aXRjaCAoc2VsZi0+Y29yZUNvZGVjKSB7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgRkRLcHVzaEZvciAoaEJzLCAxMCk7CiAgICAgICAgLyogY2hlY2sgc2JyY3JjIGxhdGVyOiB3ZSBkb24ndCBrbm93IHRoZSBwYXlsb2FkIGxlbmd0aCBub3cgKi8KICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBDUkNMZW4gPSBic1BheUxlbiAtIDEwOyAgICAgICAgICAgICAgICAgICAgIC8qIGNoYW5nZTogMCA9PiBpICovCiAgICAgICAgaWYgKENSQ0xlbiA8IDApIHsKICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gU2JyQ3JjQ2hlY2sgKGhCcywgQ1JDTGVuKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9IC8qIGlmIChmRG9EZWNvZGVTYnJEYXRhKSAqLwoKICAvKgogICAgIFJlYWQgaW4gdGhlIGhlYWRlciBkYXRhIGFuZCBpc3N1ZSBhIHJlc2V0IGlmIGNoYW5nZSBvY2N1cmVkCiAgKi8KICBpZiAoZkRvRGVjb2RlU2JyRGF0YSkKICB7CiAgICBpbnQgc2JySGVhZGVyUHJlc2VudDsKCiAgICB7CiAgICAgIHNickhlYWRlclByZXNlbnQgPSBGREtyZWFkQml0KGhCcyk7CiAgICB9CgogICAgaWYgKCBzYnJIZWFkZXJQcmVzZW50ICkgewogICAgICBoZWFkZXJTdGF0dXMgPSBzYnJHZXRIZWFkZXJEYXRhIChoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKTsKICAgIH0KCiAgICBpZiAoaGVhZGVyU3RhdHVzID09IEhFQURFUl9SRVNFVCkKICAgIHsKICAgICAgZXJyb3JTdGF0dXMgPSBzYnJEZWNvZGVyX0hlYWRlclVwZGF0ZSgKICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgaGVhZGVyU3RhdHVzLAogICAgICAgICAgICBwU2JyQ2hhbm5lbCwKICAgICAgICAgICAgaFNickVsZW1lbnQtPm5DaGFubmVscyAKICAgICAgICAgICAgKTsKCiAgICAgIGlmIChlcnJvclN0YXR1cyA9PSBTQlJERUNfT0spIHsKICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfSEVBREVSOwogICAgICB9IGVsc2UgewogICAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9OT1RfSU5JVElBTElaRUQ7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoZXJyb3JTdGF0dXMgIT0gU0JSREVDX09LKSB7CiAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgfQogIH0gLyogaWYgKGZEb0RlY29kZVNickRhdGEpICovCgogIC8qCiAgICBQcmludCBkZWJ1Z2dpbmcgb3V0cHV0IG9ubHkgaWYgc3RhdGUgaGFzIGNoYW5nZWQKICAqLwoKICAvKiByZWFkIGZyYW1lIGRhdGEgKi8KICBpZiAoKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA+PSBTQlJfSEVBREVSKSAmJiBmRG9EZWNvZGVTYnJEYXRhKSB7CiAgICBpbnQgc2JyRnJhbWVPazsKICAgIC8qIHJlYWQgdGhlIFNCUiBlbGVtZW50IGRhdGEgKi8KICAgIGlmIChzdGVyZW8pIHsKICAgICAgc2JyRnJhbWVPayA9IHNickdldENoYW5uZWxQYWlyRWxlbWVudChoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhGcmFtZURhdGFMZWZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhGcmFtZURhdGFSaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dHJhbnNwb3NlclNldHRpbmdzLm92ZXJsYXApOwogICAgfQogICAgZWxzZSB7CiAgICAgIGlmIChzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYyAhPSBOVUxMKSB7CiAgICAgICAgLyogdXBkYXRlIHNsb3QgaW5kZXggZm9yIFBTIGJpdHN0cmVhbSBwYXJzaW5nICovCiAgICAgICAgc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMtPmJzTGFzdFNsb3QgPSBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYy0+YnNSZWFkU2xvdDsKICAgICAgICBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYy0+YnNSZWFkU2xvdCA9IGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3Q7CiAgICAgIH0KICAgICAgc2JyRnJhbWVPayA9IHNickdldFNpbmdsZUNoYW5uZWxFbGVtZW50KGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhTGVmdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT50cmFuc3Bvc2VyU2V0dGluZ3Mub3ZlcmxhcCk7CiAgICB9CiAgICBpZiAoIXNickZyYW1lT2spIHsKICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICB9CiAgICBlbHNlIHsKICAgICAgSU5UIHZhbEJpdHM7CgogICAgICBpZiAoYnNQYXlMZW4gPiAwKSB7CiAgICAgICAgdmFsQml0cyA9IGJzUGF5TGVuIC0gKChJTlQpc3RhcnRQb3MgLSAoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YWxCaXRzID0gKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKTsKICAgICAgfQoKICAgICAgaWYgKCBjcmNGbGFnID09IDEgKSB7CiAgICAgICAgc3dpdGNoIChzZWxmLT5jb3JlQ29kZWMpIHsKICAgICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgICAgewogICAgICAgICAgICAvKiBsYXRlIGNyYyBjaGVjayBmb3IgZWxkICovCiAgICAgICAgICAgIElOVCBwYXlsb2FkYml0cyA9IChJTlQpc3RhcnRQb3MgLSAoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpIC0gc3RhcnRQb3M7CiAgICAgICAgICAgIElOVCBjcmNMZW4gICAgICA9IHBheWxvYWRiaXRzIC0gMTA7CiAgICAgICAgICAgIEZES3B1c2hCYWNrKGhCcywgcGF5bG9hZGJpdHMpOwogICAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhICAgICAgPSBTYnJDcmNDaGVjayAoaEJzLCBjcmNMZW4pOwogICAgICAgICAgICBGREtwdXNoRm9yKGhCcywgY3JjTGVuKTsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIHNhbml0eSBjaGVjayBvZiByZW1haW5pbmcgYml0cyAqLwogICAgICBpZiAodmFsQml0cyA8IDApIHsKICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICBjYXNlIEFPVF9QUzoKICAgICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIFRoaXMgc2FuaXR5IGNoZWNrIGlzIG9ubHkgbWVhbmluZ2Z1bCB3aXRoIEdlbmVyYWwgQXVkaW8gYml0c3RyZWFtcyAqLwogICAgICAgICAgICBpbnQgYWxpZ25CaXRzID0gdmFsQml0cyAmIDB4NzsKCiAgICAgICAgICAgIGlmICh2YWxCaXRzID4gYWxpZ25CaXRzKSB7CiAgICAgICAgICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvKiBObyBzYW5pdHkgY2hlY2sgYXZhaWxhYmxlICovCiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgLyogVGhlIHJldHVybmVkIGJpdCBjb3VudCB3aWxsIG5vdCBiZSB0aGUgYWN0dWFsIHBheWxvYWQgc2l6ZSBzaW5jZSB3ZSBkaWQgbm90CiAgICAgICBwYXJzZSB0aGUgZnJhbWUgZGF0YS4gUmV0dXJuIGFuIGVycm9yIHNvIHRoYXQgdGhlIGNhbGxlciBjYW4gcmVhY3QgcmVzcGVjdGl2ZWx5LiAqLwogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfUEFSU0VfRVJST1I7CiAgfQoKICBpZiAoIWZEb0RlY29kZVNickRhdGEpIHsKICAgIC8qIFNldCBlcnJvciBmbGFnIGZvciB0aGlzIHNsb3QgdG8gdHJpZ2dlciBjb25jZWFsbWVudCAqLwogICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZnJhbWVFcnJvckZsYWdbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSAxOwogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfUEFSU0VfRVJST1I7CiAgfSBlbHNlIHsKICAgIC8qIEV2ZXJ5dGhpbmcgc2VlbXMgdG8gYmUgb2sgc28gY2xlYXIgdGhlIGVycm9yIGZsYWcgKi8KICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdID0gMDsKICB9CgogIGlmICghc3RlcmVvKSB7CiAgICAvKiBUdXJuIGNvdXBsaW5nIG9mZiBleHBsaWNpdGVseSB0byBhdm9pZCBhY2Nlc3MgdG8gYWJzZW50IHJpZ2h0IGZyYW1lIGRhdGEKICAgICAgIHRoYXQgbWlnaHQgb2NjdXIgd2l0aCBjb3JydXB0IGJpdHN0cmVhbXMuICovCiAgICBoRnJhbWVEYXRhTGVmdC0+Y291cGxpbmcgPSBDT1VQTElOR19PRkY7CiAgfQoKYmFpbDoKICBpZiAoZXJyb3JTdGF0dXMgPT0gU0JSREVDX09LKSB7CiAgICBpZiAoaGVhZGVyU3RhdHVzID09IEhFQURFUl9OT1RfUFJFU0VOVCkgewogICAgICAvKiBVc2UgdGhlIG9sZCBoZWFkZXIgZm9yIHRoaXMgZnJhbWUgKi8KICAgICAgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSBsYXN0SGRyU2xvdDsKICAgIH0gZWxzZSB7CiAgICAgIC8qIFVzZSB0aGUgbmV3IGhlYWRlciBmb3IgdGhpcyBmcmFtZSAqLwogICAgICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XSA9IHRoaXNIZHJTbG90OwogICAgfQoKICAgIC8qIE1vdmUgZnJhbWUgcG9pbnRlciB0byB0aGUgbmV4dCBzbG90IHdoaWNoIGlzIHVwIHRvIGJlIGRlY29kZWQvYXBwbGllZCBuZXh0ICovCiAgICBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID0gKGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QrMSkgJSAoc2VsZi0+bnVtRGVsYXlGcmFtZXMrMSk7CiAgfQoKICAqY291bnQgLT0gc3RhcnRQb3MgLSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgcmV0dXJuIGVycm9yU3RhdHVzOwp9CgoKLyoqCiAqIFxicmllZiBSZW5kZXIgb25lIFNCUiBlbGVtZW50IGludG8gdGltZSBkb21haW4gc2lnbmFsLgogKiBccGFyYW0gc2VsZiBTQlIgZGVjb2RlciBoYW5kbGUKICogXHBhcmFtIHRpbWVEYXRhIHBvaW50ZXIgdG8gb3V0cHV0IGJ1ZmZlcgogKiBccGFyYW0gaW50ZXJsZWF2ZWQgZmxhZyBpbmRpY2F0aW5nIGludGVybGVhdmVkIGNoYW5uZWwgb3V0cHV0CiAqIFxwYXJhbSBjaGFubmVsTWFwcGluZyBwb2ludGVyIHRvIFVDSEFSIGFycmF5IHdoZXJlIG5leHQgMiBjaGFubmVsIG9mZnNldHMgYXJlIHN0b3JlZC4gCiAqIFxwYXJhbSBlbGVtZW50SW5kZXggZW51bWVyYXRpbmcgaW5kZXggb2YgdGhlIFNCUiBlbGVtZW50IHRvIHJlbmRlci4KICogXHBhcmFtIG51bUluQ2hhbm5lbHMgbnVtYmVyIG9mIGNoYW5uZWxzIGZyb20gY29yZSBjb2RlciAocmVhZGluZyBzdHJpZGUpLgogKiBccGFyYW0gbnVtT3V0Q2hhbm5lbHMgcG9pbnRlciB0byBhIGxvY2F0aW9uIHRvIHJldHVybiBudW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzLgogKiBccGFyYW0gcHNQb3NzaWJsZSBmbGFnIGluZGljYXRpbmcgaWYgUFMgaXMgcG9zc2libGUgb3Igbm90LgogKiBccmV0dXJuIFNCUkRFQ19PSyBpZiBzdWNjZXNzZnVsbCwgZWxzZSBlcnJvciBjb2RlCiAqLwpzdGF0aWMgU0JSX0VSUk9SCnNickRlY29kZXJfRGVjb2RlRWxlbWVudCAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgc2VsZiwKICAgICAgICBJTlRfUENNICAgICAgICAgICAgICp0aW1lRGF0YSwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBpbnRlcmxlYXZlZCwKICAgICAgICBjb25zdCBVQ0hBUiAgICAgICAgICpjaGFubmVsTWFwcGluZywKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBlbGVtZW50SW5kZXgsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgbnVtSW5DaGFubmVscywKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICpudW1PdXRDaGFubmVscywKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBwc1Bvc3NpYmxlCiAgICAgICAgKQp7CiAgU0JSX0RFQ09ERVJfRUxFTUVOVCAqaFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwogIEhBTkRMRV9TQlJfQ0hBTk5FTCAgICAqcFNickNoYW5uZWwgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbDsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXIgPSAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3RbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF1dOwogIEhBTkRMRV9QU19ERUMgaF9wc19kID0gc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWM7CgogIC8qIGdldCBtZW1vcnkgZm9yIGZyYW1lIGRhdGEgZnJvbSBzY3JhdGNoICovCiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFMZWZ0ICA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMF0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICBTQlJfRlJBTUVfREFUQSAqaEZyYW1lRGF0YVJpZ2h0ID0gJmhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICBTQlJfRVJST1IgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CgoKICBJTlQgIHN0cmlkZUluLCBzdHJpZGVPdXQsIG9mZnNldDAsIG9mZnNldDE7CiAgSU5UICBjb2RlY0ZyYW1lU2l6ZSA9IHNlbGYtPmNvZGVjRnJhbWVTaXplOwoKICBpbnQgIHN0ZXJlbyA9IChoU2JyRWxlbWVudC0+ZWxlbWVudElEID09IElEX0NQRSkgPyAxIDogMDsKICBpbnQgIG51bUVsZW1lbnRDaGFubmVscyA9IGhTYnJFbGVtZW50LT5uQ2hhbm5lbHM7IC8qIE51bWJlciBvZiBjaGFubmVscyBvZiB0aGUgY3VycmVudCBTQlIgZWxlbWVudCAqLwoKICBpZiAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfRkxVU0gpIHsKICAgIC8qIE1vdmUgZnJhbWUgcG9pbnRlciB0byB0aGUgbmV4dCBzbG90IHdoaWNoIGlzIHVwIHRvIGJlIGRlY29kZWQvYXBwbGllZCBuZXh0ICovCiAgICBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID0gKGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QrMSkgJSAoc2VsZi0+bnVtRGVsYXlGcmFtZXMrMSk7CiAgICAvKiBVcGRhdGUgaGVhZGVyIGFuZCBmcmFtZSBkYXRhIHBvaW50ZXIgYmVjYXVzZSB0aGV5IGhhdmUgYWxyZWFkeSBiZWVuIHNldCAqLwogICAgaFNickhlYWRlciA9ICZzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XV07CiAgICBoRnJhbWVEYXRhTGVmdCAgPSAmaFNickVsZW1lbnQtPnBTYnJDaGFubmVsWzBdLT5mcmFtZURhdGFbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF07CiAgICBoRnJhbWVEYXRhUmlnaHQgPSAmaFNickVsZW1lbnQtPnBTYnJDaGFubmVsWzFdLT5mcmFtZURhdGFbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF07CiAgfQoKICAvKiBVcGRhdGUgdGhlIGhlYWRlciBlcnJvciBmbGFnICovCiAgaFNickhlYWRlci0+ZnJhbWVFcnJvckZsYWcgPSBoU2JyRWxlbWVudC0+ZnJhbWVFcnJvckZsYWdbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF07CgogIC8qCiAgICAgUHJlcGFyZSBmaWx0ZXJiYW5rIGZvciB1cHNhbXBsaW5nIGlmIG5vIHZhbGlkIGJpdCBzdHJlYW0gZGF0YSBpcyBhdmFpbGFibGUuCiAgICovCiAgaWYgKCBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX05PVF9JTklUSUFMSVpFRCApCiAgewogICAgZXJyb3JTdGF0dXMgPSBpbml0SGVhZGVyRGF0YSgKICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgc2VsZi0+c2FtcGxlUmF0ZUluLAogICAgICAgICAgICBzZWxmLT5zYW1wbGVSYXRlT3V0LAogICAgICAgICAgICBjb2RlY0ZyYW1lU2l6ZSwKICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICAgKTsKCiAgICBpZiAoZXJyb3JTdGF0dXMgIT0gU0JSREVDX09LKSB7CiAgICAgIHJldHVybiBlcnJvclN0YXR1czsKICAgIH0KCiAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBVUFNBTVBMSU5HOwoKICAgIGVycm9yU3RhdHVzID0gc2JyRGVjb2Rlcl9IZWFkZXJVcGRhdGUoCiAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgIEhFQURFUl9OT1RfUFJFU0VOVCwKICAgICAgICAgICAgcFNickNoYW5uZWwsCiAgICAgICAgICAgIGhTYnJFbGVtZW50LT5uQ2hhbm5lbHMKICAgICAgICAgICAgKTsKCiAgICBpZiAoZXJyb3JTdGF0dXMgIT0gU0JSREVDX09LKSB7CiAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9OT1RfSU5JVElBTElaRUQ7CiAgICAgIHJldHVybiBlcnJvclN0YXR1czsKICAgIH0KICB9CgogIC8qIHJlc2V0ICovCiAgaWYgKGhTYnJIZWFkZXItPnN0YXR1cyAmIFNCUkRFQ19IRFJfU1RBVF9SRVNFVCkgewogICAgaW50IGNoOwogICAgZm9yIChjaCA9IDAgOyBjaCA8IG51bUVsZW1lbnRDaGFubmVsczsgY2grKykgewogICAgICBTQlJfRVJST1IgZXJyb3JTdGF0dXNUbXAgPSBTQlJERUNfT0s7CgogICAgICBlcnJvclN0YXR1c1RtcCA9IHJlc2V0U2JyRGVjICgKICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFtjaF0tPlNickRlYywKICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgJnBTYnJDaGFubmVsW2NoXS0+cHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIsCiAgICAgICAgICAgICAgc2VsZi0+c3luRG93bnNhbXBsZUZhYwogICAgICAgICAgICAgICk7CgogICAgICBpZiAoZXJyb3JTdGF0dXNUbXAgIT0gU0JSREVDX09LKSB7CiAgICAgICAgZXJyb3JTdGF0dXMgPSBlcnJvclN0YXR1c1RtcDsKICAgICAgfQogICAgfQogICAgaFNickhlYWRlci0+c3RhdHVzICY9IH5TQlJERUNfSERSX1NUQVRfUkVTRVQ7CiAgfQoKICAvKiBkZWNvZGluZyAqLwogIGlmICggKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBTQlJfQUNUSVZFKQogICAgfHwgKChoU2JySGVhZGVyLT5zeW5jU3RhdGUgPT0gU0JSX0hFQURFUikgJiYgKGhTYnJIZWFkZXItPmZyYW1lRXJyb3JGbGFnID09IDApKSApCiAgewogICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CgogICAgZGVjb2RlU2JyRGF0YSAoaFNickhlYWRlciwKICAgICAgICAgICAgICAgICAgIGhGcmFtZURhdGFMZWZ0LAogICAgICAgICAgICAgICAgICAmcFNickNoYW5uZWxbMF0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgICAgICAgICAoc3RlcmVvKSA/IGhGcmFtZURhdGFSaWdodCA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAoc3RlcmVvKSA/ICZwU2JyQ2hhbm5lbFsxXS0+cHJldkZyYW1lRGF0YSA6IE5VTEwpOwoKCiAgICAvKiBOb3cgd2UgaGF2ZSBhIGZ1bGwgcGFyYW1ldGVyIHNldCBhbmQgY2FuIGRvIHBhcmFtZXRlcgogICAgICAgYmFzZWQgY29uY2VhbG1lbnQgaW5zdGVhZCBvZiBwbGFpbiB1cHNhbXBsaW5nLiAqLwogICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gU0JSX0FDVElWRTsKICB9CgogIC8qIGRlY29kZSBQUyBkYXRhIGlmIGF2YWlsYWJsZSAqLwogIGlmIChoX3BzX2QgIT0gTlVMTCAmJiBwc1Bvc3NpYmxlKSB7CiAgICBpbnQgYXBwbHlQcyA9IDE7CgogICAgLyogZGVmaW5lIHdoaWNoIGZyYW1lIGRlbGF5IGxpbmUgc2xvdCB0byBwcm9jZXNzICovCiAgICBoX3BzX2QtPnByb2Nlc3NTbG90ID0gaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdDsKCiAgICBhcHBseVBzID0gRGVjb2RlUHMoaF9wc19kLCBoU2JySGVhZGVyLT5mcmFtZUVycm9yRmxhZyk7CiAgICBzZWxmLT5mbGFncyB8PSAoYXBwbHlQcykgPyBTQlJERUNfUFNfREVDT0RFRCA6IDA7CiAgfQoKICAvKiBTZXQgc3RyaWRlcyBmb3IgcmVhZGluZyBhbmQgd3JpdGluZyAqLwogIGlmIChpbnRlcmxlYXZlZCkgewogICAgc3RyaWRlSW4gPSBudW1JbkNoYW5uZWxzOwogICAgaWYgKCBwc1Bvc3NpYmxlICkKICAgICAgc3RyaWRlT3V0ID0gKG51bUluQ2hhbm5lbHMgPCAyKSA/IDIgOiBudW1JbkNoYW5uZWxzOwogICAgZWxzZQogICAgICBzdHJpZGVPdXQgPSBudW1JbkNoYW5uZWxzOwogICAgb2Zmc2V0MCA9IGNoYW5uZWxNYXBwaW5nWzBdOwogICAgb2Zmc2V0MSA9IGNoYW5uZWxNYXBwaW5nWzFdOwogIH0gZWxzZSB7CiAgICBzdHJpZGVJbiAgPSAxOwogICAgc3RyaWRlT3V0ID0gMTsKICAgIG9mZnNldDAgPSBjaGFubmVsTWFwcGluZ1swXSoyKmNvZGVjRnJhbWVTaXplOwogICAgb2Zmc2V0MSA9IGNoYW5uZWxNYXBwaW5nWzFdKjIqY29kZWNGcmFtZVNpemU7CiAgfQoKICAvKiB1c2Ugc2FtZSBidWZmZXJzIGZvciBsZWZ0IGFuZCByaWdodCBjaGFubmVsIGFuZCBhcHBseSBQUyBwZXIgdGltZXNsb3QgKi8KICAvKiBQcm9jZXNzIGxlZnQgY2hhbm5lbCAqLwovL0ZES3ByaW50Zigic2VsZi0+Y29kZWNGcmFtZVNpemUgJWRcdCVkXG4iLHNlbGYtPmNvZGVjRnJhbWVTaXplLHNlbGYtPnNhbXBsZVJhdGVJbik7CiAgc2JyX2RlYyAoJnBTYnJDaGFubmVsWzBdLT5TYnJEZWMsCiAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MCwKICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQwLAogICAgICAgICAgICZwU2JyQ2hhbm5lbFsxXS0+U2JyRGVjLAogICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDEsCiAgICAgICAgICAgIHN0cmlkZUluLAogICAgICAgICAgICBzdHJpZGVPdXQsCiAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgIGhGcmFtZURhdGFMZWZ0LAogICAgICAgICAgICZwU2JyQ2hhbm5lbFswXS0+cHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBTQlJfQUNUSVZFKSwKICAgICAgICAgICAgaF9wc19kLAogICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgKTsKCiAgaWYgKHN0ZXJlbykgewogICAgLyogUHJvY2VzcyByaWdodCBjaGFubmVsICovCiAgICBzYnJfZGVjICgmcFNickNoYW5uZWxbMV0tPlNickRlYywKICAgICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDEsCiAgICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQxLAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBzdHJpZGVJbiwKICAgICAgICAgICAgICBzdHJpZGVPdXQsCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICBoRnJhbWVEYXRhUmlnaHQsCiAgICAgICAgICAgICAmcFNickNoYW5uZWxbMV0tPnByZXZGcmFtZURhdGEsCiAgICAgICAgICAgICAgKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBTQlJfQUNUSVZFKSwKICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICAgICk7CiAgfQoKICBpZiAoaF9wc19kICE9IE5VTEwpIHsKICAgIC8qIHNhdmUgUFMgc3RhdHVzIGZvciBuZXh0IHJ1biAqLwogICAgaF9wc19kLT5wc0RlY29kZWRQcnYgPSAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfUFNfREVDT0RFRCkgPyAxIDogMCA7CiAgfQoKICBpZiAoIHBzUG9zc2libGUgCiAgICApCiAgewogICAgRkRLX0FTU0VSVChzdHJpZGVPdXQgPiAxKTsKICAgIGlmICggIShzZWxmLT5mbGFncyAmIFNCUkRFQ19QU19ERUNPREVEKSApIHsKICAgICAgLyogQSBkZWNvZGVyIHdoaWNoIGlzIGFibGUgdG8gZGVjb2RlIFBTIGhhcyB0byBwcm9kdWNlIGEgc3RlcmVvIG91dHB1dCBldmVuIGlmIG5vIFBTIGRhdGEgaXMgYXZhaWxibGUuICovCiAgICAgIC8qIFNvIGNvcHkgbGVmdCBjaGFubmVsIHRvIHJpZ2h0IGNoYW5uZWwuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICBpZiAoaW50ZXJsZWF2ZWQpIHsKICAgICAgICBJTlRfUENNICpwdHI7CiAgICAgICAgSU5UIGk7CiAgICAgICAgRkRLX0FTU0VSVChzdHJpZGVPdXQgPT0gMik7CgogICAgICAgIHB0ciA9IHRpbWVEYXRhOwogICAgICAgIGZvciAoaSA9IGNvZGVjRnJhbWVTaXplOyBpLS07ICkgCiAgICAgICAgewogICAgICAgICAgSU5UX1BDTSB0bXA7IC8qIFRoaXMgdGVtcG9yYWwgdmFyaWFibGUgaXMgcmVxdWlyZWQgYmVjYXVzZSBzb21lIGNvbXBpbGVycyBjYW4ndCBkbyAqcHRyKysgPSAqcHRyKysgY29ycmVjdGx5LiAqLwogICAgICAgICAgdG1wID0gKnB0cisrOyAqcHRyKysgPSB0bXA7CiAgICAgICAgICB0bXAgPSAqcHRyKys7ICpwdHIrKyA9IHRtcDsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgRkRLbWVtY3B5KCB0aW1lRGF0YSsyKmNvZGVjRnJhbWVTaXplLCB0aW1lRGF0YSwgMipjb2RlY0ZyYW1lU2l6ZSpzaXplb2YoSU5UX1BDTSkgKTsKICAgICAgfQogICAgfQogICAgKm51bU91dENoYW5uZWxzID0gMjsgIC8qIE91dHB1dCBtaW5pbXVtIHR3byBjaGFubmVscyB3aGVuIFBTIGlzIGVuYWJsZWQuICovCiAgfQoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9BcHBseSAoIEhBTkRMRV9TQlJERUNPREVSICAgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfUENNICAgICAgICAgICAgKnRpbWVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICAqbnVtQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICpzYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICAgICAgICAgY2hhbm5lbE1hcHBpbmdbKDgpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgICAgICAgICAgIGludGVybGVhdmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCAgICAgICAgICAgY29yZURlY29kZWRPaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAgICAgICAgICAgICAgKnBzRGVjb2RlZCApCnsKICBTQlJfRVJST1IgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CgogIGludCAgIHBzUG9zc2libGUgPSAwOwogIGludCAgIHNickVsZW1lbnROdW07CiAgaW50ICAgbnVtQ29yZUNoYW5uZWxzID0gKm51bUNoYW5uZWxzOwogIGludCAgIG51bVNickNoYW5uZWxzICA9IDA7CgogIHBzUG9zc2libGUgPSAqcHNEZWNvZGVkOwoKICBpZiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgPCAxKSB7CiAgICAvKiBleGl0IGltbWVkaWF0ZWx5IHRvIGF2b2lkIGFjY2VzcyB2aW9sYXRpb25zICovCiAgICByZXR1cm4gU0JSREVDX0NSRUFURV9FUlJPUjsKICB9CgogIC8qIFNhbml0eSBjaGVjayBvZiBhbGxvY2F0ZWQgU0JSIGVsZW1lbnRzLiAqLwogIGZvciAoc2JyRWxlbWVudE51bT0wOyBzYnJFbGVtZW50TnVtPHNlbGYtPm51bVNickVsZW1lbnRzOyBzYnJFbGVtZW50TnVtKyspIHsKICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXSA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBTQlJERUNfQ1JFQVRFX0VSUk9SOwogICAgfQogIH0KCiAgaWYgKHNlbGYtPm51bVNickVsZW1lbnRzICE9IDEgfHwgc2VsZi0+cFNickVsZW1lbnRbMF0tPmVsZW1lbnRJRCAhPSBJRF9TQ0UpIHsKICAgIHBzUG9zc2libGUgPSAwOwogIH0KCgogIC8qIEluIGNhc2Ugb2Ygbm9uLWludGVybGVhdmVkIHRpbWUgZG9tYWluIGRhdGEgYW5kIHVwc2FtcGxpbmcsIG1ha2Ugcm9vbSBmb3IgYmlnZ2VyIFNCUiBvdXRwdXQuICovCiAgaWYgKHNlbGYtPnN5bkRvd25zYW1wbGVGYWMgPT0gMSAmJiBpbnRlcmxlYXZlZCA9PSAwKSB7CiAgICBpbnQgYywgb3V0cHV0RnJhbWVTaXplOwoKICAgIG91dHB1dEZyYW1lU2l6ZSA9CiAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50WzBdLT5wU2JyQ2hhbm5lbFswXS0+U2JyRGVjLlN5bnRoZXNpc1FNRi5ub19jaGFubmVscwogICAgICAgICAgICAqIHNlbGYtPnBTYnJFbGVtZW50WzBdLT5wU2JyQ2hhbm5lbFswXS0+U2JyRGVjLlN5bnRoZXNpc1FNRi5ub19jb2w7CgogICAgZm9yIChjPW51bUNvcmVDaGFubmVscy0xOyBjPjA7IGMtLSkgewogICAgICBGREttZW1tb3ZlKHRpbWVEYXRhICsgYypvdXRwdXRGcmFtZVNpemUsIHRpbWVEYXRhICsgYypzZWxmLT5jb2RlY0ZyYW1lU2l6ZSAsIHNlbGYtPmNvZGVjRnJhbWVTaXplKnNpemVvZihJTlRfUENNKSk7CiAgICB9CiAgfQoKCiAgLyogTWFrZSBzdXJlIHRoYXQgZXZlbiBpZiBubyBTQlIgZGF0YSB3YXMgZm91bmQvcGFyc2VkICpwc0RlY29kZWQgaXMgcmV0dXJuZWQgMSBpZiBwc1Bvc3NpYmxlIHdhcyAwLiAqLwogIGlmIChwc1Bvc3NpYmxlID09IDApIHsKICAgIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfUFNfREVDT0RFRDsKICB9CgogIC8qIExvb3Agb3ZlciBTQlIgZWxlbWVudHMgKi8KICBmb3IgKHNickVsZW1lbnROdW0gPSAwOyBzYnJFbGVtZW50TnVtPHNlbGYtPm51bVNickVsZW1lbnRzOyBzYnJFbGVtZW50TnVtKyspCiAgewogICAgaW50IG51bUVsZW1lbnRDaGFuOwoKICAgIGlmIChwc1Bvc3NpYmxlICYmIHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT5wU2JyQ2hhbm5lbFsxXSA9PSBOVUxMKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIG51bUVsZW1lbnRDaGFuID0gKHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT5lbGVtZW50SUQgPT0gSURfQ1BFKSA/IDIgOiAxOwoKICAgIC8qIElmIGNvcmUgc2lnbmFsIGlzIGJhZCB0aGVuIGZvcmNlIHVwc2FtcGxpbmcgKi8KICAgIGlmICggISBjb3JlRGVjb2RlZE9rICkgewogICAgICBzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXS0+ZnJhbWVFcnJvckZsYWdbc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0tPnVzZUZyYW1lU2xvdF0gPSAxOwogICAgfQoKICAgIGVycm9yU3RhdHVzID0gc2JyRGVjb2Rlcl9EZWNvZGVFbGVtZW50ICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybGVhdmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwcGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2JyRWxlbWVudE51bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ29yZUNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1FbGVtZW50Q2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNQb3NzaWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICBpZiAoZXJyb3JTdGF0dXMgIT0gU0JSREVDX09LKSB7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBudW1TYnJDaGFubmVscyArPSBudW1FbGVtZW50Q2hhbjsKICAgIGNoYW5uZWxNYXBwaW5nICs9IG51bUVsZW1lbnRDaGFuOwoKICAgIGlmIChudW1TYnJDaGFubmVscyA+PSBudW1Db3JlQ2hhbm5lbHMpIHsKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICAvKiBVcGRhdGUgbnVtQ2hhbm5lbHMgYW5kIHNhbXBsZXJhdGUgKi8KICAqbnVtQ2hhbm5lbHMgPSBudW1TYnJDaGFubmVsczsKICAqc2FtcGxlUmF0ZSA9IHNlbGYtPnNhbXBsZVJhdGVPdXQ7CiAgKnBzRGVjb2RlZCA9IChzZWxmLT5mbGFncyAmIFNCUkRFQ19QU19ERUNPREVEKSA/IDEgOiAwOwoKCgogIC8qIENsZWFyIHJlc2V0IGFuZCBmbHVzaCBmbGFnIGJlY2F1c2UgZXZlcnl0aGluZyBzZWVtcyB0byBiZSBkb25lIHN1Y2Nlc3NmdWxseS4gKi8KICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX0ZPUkNFX1JFU0VUOwogIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfRkxVU0g7CgpiYWlsOgoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9DbG9zZSAoIEhBTkRMRV9TQlJERUNPREVSICpwU2VsZiApCnsKICBIQU5ETEVfU0JSREVDT0RFUiBzZWxmID0gKnBTZWxmOwogIGludCBpOwoKICBpZiAoc2VsZiAhPSBOVUxMKQogIHsKICAgIGlmIChzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYyAhPSBOVUxMKSB7CiAgICAgIERlbGV0ZVBzRGVjICggJnNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjICk7CiAgICB9CgogICAgaWYgKHNlbGYtPndvcmtCdWZmZXIxICE9IE5VTEwpIHsKICAgICAgRnJlZVJhbV9TYnJEZWNXb3JrQnVmZmVyMSgmc2VsZi0+d29ya0J1ZmZlcjEpOwogICAgfQogICAgaWYgKHNlbGYtPndvcmtCdWZmZXIyICE9IE5VTEwpIHsKICAgICAgRnJlZVJhbV9TYnJEZWNXb3JrQnVmZmVyMigmc2VsZi0+d29ya0J1ZmZlcjIpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCAoOCk7IGkrKykgewogICAgICBzYnJEZWNvZGVyX0Rlc3Ryb3lFbGVtZW50KCBzZWxmLCBpICk7CiAgICB9CgogICAgRnJlZVJhbV9TYnJEZWNvZGVyKHBTZWxmKTsKICB9CgogIHJldHVybiBTQlJERUNfT0s7Cn0KCgpJTlQgc2JyRGVjb2Rlcl9HZXRMaWJJbmZvKCBMSUJfSU5GTyAqaW5mbyApCnsKICBpbnQgaTsKCiAgaWYgKGluZm8gPT0gTlVMTCkgewogICAgcmV0dXJuIC0xOwogIH0KCiAgLyogc2VhcmNoIGZvciBuZXh0IGZyZWUgdGFiICovCiAgZm9yIChpID0gMDsgaSA8IEZES19NT0RVTEVfTEFTVDsgaSsrKSB7CiAgICBpZiAoaW5mb1tpXS5tb2R1bGVfaWQgPT0gRkRLX05PTkUpCiAgICAgIGJyZWFrOwogIH0KICBpZiAoaSA9PSBGREtfTU9EVUxFX0xBU1QpCiAgICByZXR1cm4gLTE7CiAgaW5mbyArPSBpOwoKICBpbmZvLT5tb2R1bGVfaWQgPSBGREtfU0JSREVDOwogIGluZm8tPnZlcnNpb24gPSBMSUJfVkVSU0lPTihTQlJERUNPREVSX0xJQl9WTDAsIFNCUkRFQ09ERVJfTElCX1ZMMSwgU0JSREVDT0RFUl9MSUJfVkwyKTsKICBMSUJfVkVSU0lPTl9TVFJJTkcoaW5mbyk7CiAgaW5mby0+YnVpbGRfZGF0ZSA9IChjaGFyICopU0JSREVDT0RFUl9MSUJfQlVJTERfREFURTsKICBpbmZvLT5idWlsZF90aW1lID0gKGNoYXIgKilTQlJERUNPREVSX0xJQl9CVUlMRF9USU1FOwogIGluZm8tPnRpdGxlICAgICAgPSAoY2hhciAqKVNCUkRFQ09ERVJfTElCX1RJVExFOwoKICAvKiBTZXQgZmxhZ3MgKi8KICBpbmZvLT5mbGFncyA9IDAKICAgIHwgQ0FQRl9TQlJfSFEKICAgIHwgQ0FQRl9TQlJfTFAKICAgIHwgQ0FQRl9TQlJfUFNfTVBFRwogICAgfCBDQVBGX1NCUl9DT05DRUFMTUVOVAogICAgfCBDQVBGX1NCUl9EUkMKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gMDsKfQoKClVJTlQgc2JyRGVjb2Rlcl9HZXREZWxheSggY29uc3QgSEFORExFX1NCUkRFQ09ERVIgc2VsZiApCnsKICBVSU5UIG91dHB1dERlbGF5ID0gMDsKCiAgaWYgKCBzZWxmICE9IE5VTEwpIHsKICAgIFVJTlQgZmxhZ3MgPSBzZWxmLT5mbGFnczsKCiAgICAvKiBTZWUgY2hhcHRlciAxLjYuNy4yIG9mIElTTy9JRUMgMTQ0OTYtMyBmb3IgdGhlIEdBLVNCUiBmaWd1cmVzIGJlbG93LiAqLwoKICAgIC8qIEFyZSB3ZSBpbml0aWFsaXplZD8gKi8KICAgIGlmICggKHNlbGYtPm51bVNickNoYW5uZWxzID4gMCkKICAgICAgJiYgKHNlbGYtPm51bVNickVsZW1lbnRzID4gMCkgKQogICAgewogICAgICAvKiBBZGQgUU1GIHN5bnRoZXNpcyBkZWxheSAqLwogICAgICBpZiAoIChmbGFncyAmIFNCUkRFQ19FTERfR1JJRCkKICAgICAgICAmJiBJU19MT1dERUxBWShzZWxmLT5jb3JlQ29kZWMpICkgewogICAgICAgIC8qIExvdyBkZWxheSBTQlI6ICovCiAgICAgICAgewogICAgICAgICAgb3V0cHV0RGVsYXkgKz0gKGZsYWdzICYgU0JSREVDX0RPV05TQU1QTEUpID8gMzIgOiA2NDsgICAvKiBRTUYgc3ludGhlc2lzICovCiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UgaWYgKCFJU19VU0FDKHNlbGYtPmNvcmVDb2RlYykpIHsKICAgICAgICAvKiBCeSB0aGUgbWV0aG9kIG9mIGVsaW1pbmF0aW9uIHRoaXMgaXMgdGhlIEdBIChBQUMtTEMsIEhFLUFBQywgLi4uKSBicmFuY2g6ICovCiAgICAgICAgb3V0cHV0RGVsYXkgKz0gKGZsYWdzICYgU0JSREVDX0RPV05TQU1QTEUpID8gNDgxIDogOTYyOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gKG91dHB1dERlbGF5KTsKfQo=