Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgU0JSIGRlY29kZXIgZnJvbnRlbmQKICBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIGZyb250ZW5kIHRvIHRoZSBTQlIgZGVjb2Rlci4gVGhlIGZ1bmN0aW9uIG9wZW5TQlIoKSBpcyBjYWxsZWQgZm9yCiAgaW5pdGlhbGl6YXRpb24uIFRoZSBmdW5jdGlvbiBzYnJEZWNvZGVyX0FwcGx5KCkgaXMgY2FsbGVkIGZvciBlYWNoIGZyYW1lLiBzYnJfQXBwbHkoKSB3aWxsIGNhbGwgdGhlCiAgcmVxdWlyZWQgZnVuY3Rpb25zIHRvIGRlY29kZSB0aGUgcmF3IFNCUiBkYXRhIChwcm92aWRlZCBieSBlbnZfZXh0ci5jcHApLCB0byBkZWNvZGUgdGhlIGVudmVsb3BlIGRhdGEgYW5kIG5vaXNlIGZsb29yIGxldmVscyBbZGVjb2RlU2JyRGF0YSgpXSwKICBhbmQgdG8gZmluYWxseSBhcHBseSBTQlIgdG8gdGhlIGN1cnJlbnQgZnJhbWUgW3Nicl9kZWMoKV0uCgogIFxzYSBzYnJEZWNvZGVyX0FwcGx5KCksIFxyZWYgZG9jdW1lbnRhdGlvbk92ZXJ2aWV3CiovCgovKiEKICBccGFnZSBkb2N1bWVudGF0aW9uT3ZlcnZpZXcgT3ZlcnZpZXcgb2YgaW1wb3J0YW50IGluZm9ybWF0aW9uIHJlc291cmNlcyBhbmQgc291cmNlIGNvZGUgZG9jdW1lbnRhdGlvbgoKICBUaGUgcHJpbWFyeSBzb3VyY2UgY29kZSBkb2N1bWVudGF0aW9uIGlzIGJhc2VkIG9uIGdlbmVyYXRlZCBhbmQgY3Jvc3MtcmVmZXJlbmNlZCBIVE1MIGZpbGVzIHVzaW5nCiAgPGEgSFJFRj0iaHR0cDovL3d3dy5kb3h5Z2VuLm9yZyI+ZG94eWdlbjwvYT4uIEFzIHBhcnQgb2YgdGhpcyBkb2N1bWVudGF0aW9uCiAgeW91IGNhbiBmaW5kIG1vcmUgZXh0ZW5zaXZlIGRlc2NyaXB0aW9ucyBhYm91dCBrZXkgY29uY2VwdHMgYW5kIGFsZ29yaXRobXMgYXQgdGhlIGZvbGxvd2luZyBsb2NhdGlvbnM6CgogIDxoMj5Qcm9ncmFtbWluZzwvaDI+CgogIFxsaSBCdWZmZXIgbWFuYWdlbWVudDogc2JyRGVjb2Rlcl9BcHBseSgpIGFuZCBzYnJfZGVjKCkKICBcbGkgSW50ZXJuYWwgc2NhbGUgZmFjdG9ycyB0byBtYXhpbWl6ZSBTTlIgb24gZml4ZWQgcG9pbnQgcHJvY2Vzc29yczogI1FNRl9TQ0FMRV9GQUNUT1IKICBcbGkgU3BlY2lhbCBtYW50aXNzYS1leHBvbmVudCBmb3JtYXQ6IENyZWF0ZWQgaW4gcmVxdWFudGl6ZUVudmVsb3BlRGF0YSgpIGFuZCB1c2VkIGluIGNhbGN1bGF0ZVNickVudmVsb3BlKCkKCiAgPGgyPkFsZ29yaXRobWljIGRldGFpbHM8L2gyPgogIFxsaSBBYm91dCB0aGUgU0JSIGRhdGEgZm9ybWF0OiBccmVmIFNCUl9IRUFERVJfRUxFTUVOVCBhbmQgXHJlZiBTQlJfU1RBTkRBUkRfRUxFTUVOVAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSBiaXRzdHJlYW0gZGVjb2RlcjogZW52X2V4dHIuY3BwCiAgXGxpIERldGFpbHMgYWJvdXQgdGhlIFFNRiBmaWx0ZXJiYW5rIGFuZCB0aGUgcHJvdmlkZWQgcG9seXBoYXNlIGltcGxlbWVudGF0aW9uOiBxbWZfZGVjLmNwcAogIFxsaSBEZXRhaWxzIGFib3V0IHRoZSB0cmFuc3Bvc2VyOiBscHBfdHJhbi5jcHAKICBcbGkgRGV0YWlscyBhYm91dCB0aGUgZW52ZWxvcGUgYWRqdXN0ZXI6IGVudl9jYWxjLmNwcAoKKi8KCiNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgojaW5jbHVkZSAiRkRLX2JpdHN0cmVhbS5oIgoKI2luY2x1ZGUgInNicmRlY19mcmVxX3NjYS5oIgojaW5jbHVkZSAiZW52X2V4dHIuaCIKI2luY2x1ZGUgInNicl9kZWMuaCIKI2luY2x1ZGUgImVudl9kZWMuaCIKI2luY2x1ZGUgInNicl9jcmMuaCIKI2luY2x1ZGUgInNicl9yYW0uaCIKI2luY2x1ZGUgInNicl9yb20uaCIKI2luY2x1ZGUgImxwcF90cmFuLmgiCiNpbmNsdWRlICJ0cmFuc2NlbmRlbnQuaCIKCgojaW5jbHVkZSAic2JyZGVjX2RyYy5oIgoKI2luY2x1ZGUgInBzYml0ZGVjLmgiCgoKLyogRGVjb2RlciBsaWJyYXJ5IGluZm8gKi8KI2RlZmluZSBTQlJERUNPREVSX0xJQl9WTDAgMgojZGVmaW5lIFNCUkRFQ09ERVJfTElCX1ZMMSAyCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfVkwyIDYKI2RlZmluZSBTQlJERUNPREVSX0xJQl9USVRMRSAiU0JSIERlY29kZXIiCiNkZWZpbmUgU0JSREVDT0RFUl9MSUJfQlVJTERfREFURSBfX0RBVEVfXwojZGVmaW5lIFNCUkRFQ09ERVJfTElCX0JVSUxEX1RJTUUgX19USU1FX18KCgoKCnN0YXRpYyBVQ0hBUiBnZXRIZWFkZXJTbG90KCBVQ0hBUiBjdXJyZW50U2xvdCwgVUNIQVIgaGRyU2xvdFVzYWdlWygxKSsxXSApCnsKICBVSU5UICBvY2N1cGllZCA9IDA7CiAgaW50ICAgczsKICBVQ0hBUiBzbG90ID0gaGRyU2xvdFVzYWdlW2N1cnJlbnRTbG90XTsKCiAgRkRLX0FTU0VSVCgoMSkrMSA8IDMyKTsKCiAgZm9yIChzID0gMDsgcyA8ICgxKSsxOyBzKyspIHsKICAgIGlmICggKGhkclNsb3RVc2FnZVtzXSA9PSBzbG90KQogICAgICAmJiAocyAhPSBzbG90KSApIHsKICAgICAgb2NjdXBpZWQgPSAxOwogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmIChvY2N1cGllZCkgewogICAgb2NjdXBpZWQgPSAwOwoKICAgIGZvciAocyA9IDA7IHMgPCAoMSkrMTsgcysrKSB7CiAgICAgIG9jY3VwaWVkIHw9IDEgPDwgaGRyU2xvdFVzYWdlW3NdOwogICAgfQogICAgZm9yIChzID0gMDsgcyA8ICgxKSsxOyBzKyspIHsKICAgICAgaWYgKCAhKG9jY3VwaWVkICYgMHgxKSApIHsKICAgICAgICBzbG90ID0gczsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBvY2N1cGllZCA+Pj0gMTsKICAgIH0KICB9CgogIHJldHVybiBzbG90Owp9CgpzdGF0aWMgdm9pZCBjb3B5U2JySGVhZGVyKCBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhEc3QsIGNvbnN0IEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNyYyApCnsKICAvKiBjb3B5IHRoZSB3aG9sZSBoZWFkZXIgbWVtb3J5IChpbmNsdWRpbmcgcG9pbnRlcnMpICovCiAgRkRLbWVtY3B5KCBoRHN0LCBoU3JjLCBzaXplb2YoU0JSX0hFQURFUl9EQVRBKSApOwoKICAvKiB1cGRhdGUgcG9pbnRlcnMgKi8KICBoRHN0LT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZVswXSAgPSBoRHN0LT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZUxvOwogIGhEc3QtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlWzFdID0gaERzdC0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVIaTsKfQoKCi8qIQogIFxicmllZiBSZXNldCBTQlIgZGVjb2Rlci4KCiAgUmVzZXQgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIFNCUiBoYXMgYmVlbiBzdWNlc3NmdWxseSBkZXRlY3RlZCBieQogIGFuIGFwcHJvcHJpYXRlIGNoZWNrRm9yUGF5bG9hZCgpIGZ1bmN0aW9uLgoKICBccmV0dXJuIEVycm9yIGNvZGUuCiovCnN0YXRpYwpTQlJfRVJST1Igc2JyRGVjb2Rlcl9SZXNldEVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSICAgIHNlbGYsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBlbGVtZW50SW5kZXgsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgb3ZlcmxhcAogICAgICAgICkKewogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgVUlOVCBxbWZGbGFncyA9IDA7CgogIGludCBpLCBzeW5Eb3duc2FtcGxlRmFjOwoKICAvKiBDaGVjayBpbi9vdXQgc2FtcGxlcmF0ZXMgKi8KICBpZiAoIHNhbXBsZVJhdGVJbiA8IDY0MDAKICAgIHx8IHNhbXBsZVJhdGVJbiA+IDQ4MDAwCiAgICAgKQogIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIGdvdG8gYmFpbDsKICB9CgogIGlmICggc2FtcGxlUmF0ZU91dCA+IDk2MDAwICkKICB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKiBTZXQgUU1GIG1vZGUgZmxhZ3MgKi8KICBpZiAoc2VsZi0+ZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSKQogICAgcW1mRmxhZ3MgfD0gUU1GX0ZMQUdfTFA7CgogIGlmIChzZWxmLT5jb3JlQ29kZWMgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIGlmIChzZWxmLT5mbGFncyAmIFNCUkRFQ19MRF9NUFNfUU1GKSB7CiAgICAgIHFtZkZsYWdzIHw9ICBRTUZfRkxBR19NUFNMREZCOwogICAgfSBlbHNlIHsKICAgICAgcW1mRmxhZ3MgfD0gIFFNRl9GTEFHX0NMREZCOwogICAgfQogIH0KCiAgLyogU2V0IGRvd25zYW1wbGluZyBmYWN0b3IgZm9yIHN5bnRoZXNpcyBmaWx0ZXIgYmFuayAqLwogIGlmIChzYW1wbGVSYXRlT3V0ID09IDApCiAgewogICAgLyogbm8gc2luZ2xlIHJhdGUgbW9kZSAqLwogICAgICBzYW1wbGVSYXRlT3V0ID0gc2FtcGxlUmF0ZUluPDwxOyAvKiBJbiBjYXNlIG9mIGltcGxpY2l0IHNpZ25hbGxpbmcsIGFzc3VtZSBkdWFsIHJhdGUgU0JSICovCiAgfQoKICBpZiAoIHNhbXBsZVJhdGVJbiA9PSBzYW1wbGVSYXRlT3V0ICkgewogICAgc3luRG93bnNhbXBsZUZhYyA9IDI7CiAgICBzZWxmLT5mbGFncyB8PSAgU0JSREVDX0RPV05TQU1QTEU7CiAgfSBlbHNlIHsKICAgIHN5bkRvd25zYW1wbGVGYWMgPSAxOwogICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19ET1dOU0FNUExFOwogIH0KCiAgc2VsZi0+c3luRG93bnNhbXBsZUZhYyA9IHN5bkRvd25zYW1wbGVGYWM7CiAgc2VsZi0+c2FtcGxlUmF0ZU91dCA9IHNhbXBsZVJhdGVPdXQ7CgogIHsKICAgIGludCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAoMSkrMTsgaSsrKQogICAgewogICAgICBoU2JySGVhZGVyID0gJihzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtpXSk7CgogICAgICAvKiBpbml0IGEgZGVmYXVsdCBoZWFkZXIgc3VjaCB0aGF0IHdlIGNhbiBhdCBsZWFzdCBkbyB1cHNhbXBsaW5nIGxhdGVyICovCiAgICAgIHNickVycm9yID0gaW5pdEhlYWRlckRhdGEoCiAgICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgICAgICAgc2FtcGxlUmF0ZU91dCwKICAgICAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICAgICApOwogICAgfQogIH0KCiAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgZ290byBiYWlsOwogIH0KCiAgLyogSW5pdCBTQlIgY2hhbm5lbHMgZ29pbmcgdG8gYmUgYXNzaWduZWQgdG8gYSBTQlIgZWxlbWVudCAqLwogIHsKICAgIGludCBjaDsKCiAgICBmb3IgKGNoPTA7IGNoPHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPm5DaGFubmVsczsgY2grKykKICAgIHsKICAgICAgLyogYW5kIGNyZWF0ZSBzYnJEZWMgKi8KICAgICAgc2JyRXJyb3IgPSBjcmVhdGVTYnJEZWMgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnRyYW5zcG9zZXJTZXR0aW5ncywKICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5Eb3duc2FtcGxlRmFjLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFtZkZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJsYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggKTsKCiAgICAgIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgIH0KICB9CgogIC8vRkRLbWVtY2xlYXIoc2JyX092ZXJsYXBCdWZmZXIsIHNpemVvZihzYnJfT3ZlcmxhcEJ1ZmZlcikpOwoKICBpZiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgPT0gMSkgewogICAgc3dpdGNoICggc2VsZi0+Y29yZUNvZGVjICkgewogICAgY2FzZSBBT1RfQUFDX0xDOgogICAgY2FzZSBBT1RfU0JSOgogICAgY2FzZSBBT1RfUFM6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0RSTV9BQUM6CiAgICBjYXNlIEFPVF9EUk1fU1VSUk9VTkQ6CiAgICAgIGlmIChDcmVhdGVQc0RlYyAoICZzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYywgc2FtcGxlc1BlckZyYW1lICkpIHsKICAgICAgICBzYnJFcnJvciA9IFNCUkRFQ19DUkVBVEVfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICAvKiBJbml0IGZyYW1lIGRlbGF5IHNsb3QgaGFuZGxpbmcgKi8KICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QgPSAwOwogIGZvciAoaSA9IDA7IGkgPCAoKDEpKzEpOyBpKyspIHsKICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUhlYWRlclNsb3RbaV0gPSBpOwogIH0KCmJhaWw6CgogIHJldHVybiBzYnJFcnJvcjsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX09wZW4gKCBIQU5ETEVfU0JSREVDT0RFUiAgKiBwU2VsZiApCnsKICBIQU5ETEVfU0JSREVDT0RFUiAgICBzZWxmID0gTlVMTDsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CgogIC8qIEdldCBtZW1vcnkgZm9yIHRoaXMgaW5zdGFuY2UgKi8KICBzZWxmID0gR2V0UmFtX1NickRlY29kZXIoKTsKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgZ290byBiYWlsOwogIH0KCiAgc2VsZi0+d29ya0J1ZmZlcjEgPSBHZXRSYW1fU2JyRGVjV29ya0J1ZmZlcjEoKTsKICBzZWxmLT53b3JrQnVmZmVyMiA9IEdldFJhbV9TYnJEZWNXb3JrQnVmZmVyMigpOwoKICBpZiAoICBzZWxmLT53b3JrQnVmZmVyMSA9PSBOVUxMCiAgICAgfHwgc2VsZi0+d29ya0J1ZmZlcjIgPT0gTlVMTCApCiAgewogICAgc2JyRXJyb3IgPSBTQlJERUNfTUVNX0FMTE9DX0ZBSUxFRDsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qCiAgQWxyZWFkeSB6ZXJvIGJlY2F1c2Ugb2YgY2FsbG9jCiAgc2VsZi0+bnVtU2JyRWxlbWVudHMgPSAwOwogIHNlbGYtPm51bVNickNoYW5uZWxzID0gMDsKICBzZWxmLT5jb2RlY0ZyYW1lU2l6ZSA9IDA7CiAgKi8KCiAgc2VsZi0+bnVtRGVsYXlGcmFtZXMgPSAoMSk7ICAvKiBzZXQgdG8gdGhlIG1heCB2YWx1ZSBieSBkZWZhdWx0ICovCgogICpwU2VsZiA9IHNlbGY7CgpiYWlsOgogIHJldHVybiBzYnJFcnJvcjsKfQoKLyoqCiAqIFxicmllZiBkZXRlcm1pbmUgaWYgdGhlIGdpdmVuIGNvcmUgY29kZWMgQU9UIGNhbiBiZSBwcm9jZXNzZWQgb3Igbm90LgogKiBccGFyYW0gY29yZUNvZGVjIGNvcmUgY29kZWMgYXVkaW8gb2JqZWN0IHR5cGUuCiAqIFxyZXR1cm4gMSBpZiBTQlIgY2FuIGJlIHByb2Nlc3NlZCwgMCBpZiBTQlIgY2Fubm90IGJlIHByb2Nlc3NlZC9hcHBsaWVkLgogKi8Kc3RhdGljCmludCBzYnJEZWNvZGVyX2lzQ29yZUNvZGVjVmFsaWQoQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjKQp7CiAgc3dpdGNoIChjb3JlQ29kZWMpIHsKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX1NCUjoKICAgIGNhc2UgQU9UX1BTOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICByZXR1cm4gMTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiAwOwogIH0KfQoKc3RhdGljCnZvaWQgc2JyRGVjb2Rlcl9EZXN0cm95RWxlbWVudCAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgICAgc2VsZiwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICApCnsKICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSAhPSBOVUxMKSB7CiAgICBpbnQgY2g7CgogICAgZm9yIChjaD0wOyBjaDxTQlJERUNfTUFYX0NIX1BFUl9FTEVNRU5UOyBjaCsrKSB7CiAgICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZVNickRlYyggc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICk7CiAgICAgICAgRnJlZVJhbV9TYnJEZWNDaGFubmVsKCAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICk7CiAgICAgICAgc2VsZi0+bnVtU2JyQ2hhbm5lbHMgLT0gMTsKICAgICAgfQogICAgfQogICAgRnJlZVJhbV9TYnJEZWNFbGVtZW50KCAmc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XSApOwogICAgc2VsZi0+bnVtU2JyRWxlbWVudHMgLT0gMTsKICB9Cn0KCgpTQlJfRVJST1Igc2JyRGVjb2Rlcl9Jbml0RWxlbWVudCAoCiAgICAgICAgSEFORExFX1NCUkRFQ09ERVIgICAgICAgc2VsZiwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBzYW1wbGVSYXRlSW4sCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgc2FtcGxlUmF0ZU91dCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEICAgIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICApCnsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CiAgaW50IGNoQ250PTA7CiAgaW50IG5TYnJFbGVtZW50c1N0YXJ0ID0gc2VsZi0+bnVtU2JyRWxlbWVudHM7CgogIC8qIENoZWNrIGNvcmUgY29kZWMgQU9UICovCiAgaWYgKCEgc2JyRGVjb2Rlcl9pc0NvcmVDb2RlY1ZhbGlkKGNvcmVDb2RlYykgfHwgZWxlbWVudEluZGV4ID49ICg4KSkgewogICAgc2JyRXJyb3IgPSBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgZ290byBiYWlsOwogIH0KCiAgaWYgKCBlbGVtZW50SUQgIT0gSURfU0NFICYmIGVsZW1lbnRJRCAhPSBJRF9DUEUgJiYgZWxlbWVudElEICE9IElEX0xGRSApCiAgewogICAgc2JyRXJyb3IgPSBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgZ290byBiYWlsOwogIH0KCiAgaWYgKCAgc2VsZi0+c2FtcGxlUmF0ZUluID09IHNhbXBsZVJhdGVJbgogICAgICYmIHNlbGYtPmNvZGVjRnJhbWVTaXplID09IHNhbXBsZXNQZXJGcmFtZQogICAgICYmIHNlbGYtPmNvcmVDb2RlYyA9PSBjb3JlQ29kZWMKICAgICAmJiBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICE9IE5VTEwKICAgICAmJiBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5lbGVtZW50SUQgPT0gZWxlbWVudElECiAgICAgJiYgIShzZWxmLT5mbGFncyAmIFNCUkRFQ19GT1JDRV9SRVNFVCkKICAgICApCiAgewogICAgIC8qIE5vdGhpbmcgdG8gZG8gKi8KICAgICByZXR1cm4gU0JSREVDX09LOwogIH0KCiAgc2VsZi0+c2FtcGxlUmF0ZUluID0gc2FtcGxlUmF0ZUluOwogIHNlbGYtPmNvZGVjRnJhbWVTaXplID0gc2FtcGxlc1BlckZyYW1lOwogIHNlbGYtPmNvcmVDb2RlYyA9IGNvcmVDb2RlYzsKCiAgc2VsZi0+ZmxhZ3MgPSAwOwogIHNlbGYtPmZsYWdzIHw9IChjb3JlQ29kZWMgPT0gQU9UX0VSX0FBQ19FTEQpID8gU0JSREVDX0VMRF9HUklEIDogMDsKCiAgLyogSW5pdCBTQlIgZWxlbWVudHMgKi8KICB7CiAgICBpbnQgZWxDaGFubmVscywgY2g7CgogICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gPT0gTlVMTCkgewogICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID0gR2V0UmFtX1NickRlY0VsZW1lbnQoZWxlbWVudEluZGV4KTsKICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gPT0gTlVMTCkgewogICAgICAgIHNickVycm9yID0gU0JSREVDX01FTV9BTExPQ19GQUlMRUQ7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICAgIHNlbGYtPm51bVNickVsZW1lbnRzICsrOwogICAgfSBlbHNlIHsKICAgICAgc2VsZi0+bnVtU2JyQ2hhbm5lbHMgLT0gc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+bkNoYW5uZWxzOwogICAgfQoKICAgIC8qIFNhdmUgZWxlbWVudCBJRCBmb3Igc2FuaXR5IGNoZWNrcyBhbmQgdG8gaGF2ZSBhIGZhbGxiYWNrIGZvciBjb25jZWFsbWVudC4gKi8KICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmVsZW1lbnRJRCA9IGVsZW1lbnRJRDsKCiAgICAvKiBEZXRlcm1pbmUgYW1vdW50IG9mIGNoYW5uZWxzIGZvciB0aGlzIGVsZW1lbnQgKi8KICAgIHN3aXRjaCAoZWxlbWVudElEKSB7CiAgICAgIGNhc2UgSURfTk9ORToKICAgICAgY2FzZSBJRF9DUEU6IGVsQ2hhbm5lbHM9MjsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgIGNhc2UgSURfU0NFOiBlbENoYW5uZWxzPTE7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6IGVsQ2hhbm5lbHM9MDsKICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBIYW5kbGUgY2FzZSBvZiBQYXJhbWV0cmljIFN0ZXJlbyAqLwogICAgaWYgKCBlbGVtZW50SW5kZXggPT0gMCAmJiBlbGVtZW50SUQgPT0gSURfU0NFICkgewogICAgICBzd2l0Y2ggKGNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgICBjYXNlIEFPVF9TQlI6CiAgICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICAgICAgY2FzZSBBT1RfRFJNX0FBQzoKICAgICAgICBjYXNlIEFPVF9EUk1fU1VSUk9VTkQ6CiAgICAgICAgICBlbENoYW5uZWxzID0gMjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfQoKICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPm5DaGFubmVscyA9IGVsQ2hhbm5lbHM7CgogICAgZm9yIChjaD0wOyBjaDxlbENoYW5uZWxzOyBjaCsrKQogICAgewogICAgICBpZiAoc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdID09IE5VTEwpIHsKICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0gPSBHZXRSYW1fU2JyRGVjQ2hhbm5lbChjaENudCk7CiAgICAgICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgICBzYnJFcnJvciA9IFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgfQogICAgICBzZWxmLT5udW1TYnJDaGFubmVscyArKzsKCiAgICAgIHNickRlY29kZXJfZHJjSW5pdENoYW5uZWwoICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtjaF0tPlNickRlYy5zYnJEcmNDaGFubmVsICk7CgogICAgICAvKiBBZGQgcmVmZXJlbmNlIHBvaW50ZXIgdG8gd29ya2J1ZmZlcnMuICovCiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXS0+U2JyRGVjLldvcmtCdWZmZXIxID0gc2VsZi0+d29ya0J1ZmZlcjE7CiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXS0+U2JyRGVjLldvcmtCdWZmZXIyID0gc2VsZi0+d29ya0J1ZmZlcjI7CiAgICAgIGNoQ250Kys7CiAgICB9CiAgICBpZiAoZWxDaGFubmVscyA9PSAxICYmIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSAhPSBOVUxMKSB7CiAgICAgIGRlbGV0ZVNickRlYyggc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+cFNickNoYW5uZWxbY2hdICk7CiAgICAgIEZyZWVSYW1fU2JyRGVjQ2hhbm5lbCggJnNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2NoXSApOwogICAgfQogIH0KCiAgLyogY2xlYXIgZXJyb3IgZmxhZ3MgZm9yIGFsbCBkZWxheSBzbG90cyAqLwogIEZES21lbWNsZWFyKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnLCAoKDEpKzEpKnNpemVvZihVQ0hBUikpOwoKICAvKiBJbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgKi8KICBzYnJFcnJvciA9IHNickRlY29kZXJfUmVzZXRFbGVtZW50KAogICAgICAgICAgc2VsZiwKICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICAgIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICBlbGVtZW50SUQsCiAgICAgICAgICBlbGVtZW50SW5kZXgsCiAgICAgICAgICAoY29yZUNvZGVjID09IEFPVF9FUl9BQUNfRUxEKSA/IDAgOiAoNikKICAgICAgICAgICk7CgoKCmJhaWw6CiAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgaWYgKG5TYnJFbGVtZW50c1N0YXJ0IDwgc2VsZi0+bnVtU2JyRWxlbWVudHMpIHsKICAgICAgLyogRnJlZSB0aGUgbWVtb3J5IGFsbG9jYXRlZCBmb3IgdGhpcyBlbGVtZW50ICovCiAgICAgIHNickRlY29kZXJfRGVzdHJveUVsZW1lbnQoIHNlbGYsIGVsZW1lbnRJbmRleCApOwogICAgfSBlbHNlIGlmICggKHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0gIT0gTlVMTCkKICAgICAgICAgICAgICYmIChlbGVtZW50SW5kZXggPCAoOCkpKQogICAgeyAvKiBTZXQgZXJyb3IgZmxhZyB0byB0cmlnZ2VyIGNvbmNlYWxtZW50ICovCiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPmZyYW1lRXJyb3JGbGFnW3NlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUZyYW1lU2xvdF0gPSAxOwogICAgfQogIH0KCiAgcmV0dXJuIHNickVycm9yOwp9CgovKioKICogXGJyaWVmIEFwcGx5IGRlY29kZWQgU0JSIGhlYWRlciBmb3Igb25lIGVsZW1lbnQuCiAqIFxwYXJhbSBzZWxmIFNCUiBkZWNvZGVyIGluc3RhbmNlIGhhbmRsZQogKiBccGFyYW0gaFNickhlYWRlciBTQlIgaGVhZGVyIGhhbmRsZSB0byBiZSBwcm9jZXNzZWQuCiAqIFxwYXJhbSBoU2JyQ2hhbm5lbCBwb2ludGVyIGFycmF5IHRvIHRoZSBTQlIgZWxlbWVudCBjaGFubmVscyBjb3JyZXNwb25kaW5nIHRvIHRoZSBTQlIgaGVhZGVyLgogKiBccGFyYW0gaGVhZGVyU3RhdHVzIGhlYWRlciBzdGF0dXMgdmFsdWUgcmV0dXJuZWQgZnJvbSBTQlIgaGVhZGVyIHBhcnNlci4KICogXHBhcmFtIG51bUVsZW1lbnRDaGFubmVscyBhbW91bnQgb2YgY2hhbm5lbHMgZm9yIHRoZSBTQlIgZWxlbWVudCB3aG9zIGhlYWRlciBpcyB0byBiZSBwcm9jZXNzZWQuCiAqLwpzdGF0aWMKU0JSX0VSUk9SIHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSIHNlbGYsCiAgICAgICAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyLAogICAgICAgIFNCUl9IRUFERVJfU1RBVFVTIGhlYWRlclN0YXR1cywKICAgICAgICBIQU5ETEVfU0JSX0NIQU5ORUwgaFNickNoYW5uZWxbXSwKICAgICAgICBjb25zdCBpbnQgbnVtRWxlbWVudENoYW5uZWxzCiAgICAgICAgKQp7CiAgU0JSX0VSUk9SIGVycm9yU3RhdHVzID0gU0JSREVDX09LOwoKICAvKgogICAgY2hhbmdlIG9mIGNvbnRyb2wgZGF0YSwgcmVzZXQgZGVjb2RlcgogICovCiAgZXJyb3JTdGF0dXMgPSByZXNldEZyZXFCYW5kVGFibGVzKGhTYnJIZWFkZXIsIHNlbGYtPmZsYWdzKTsKCiAgaWYgKGVycm9yU3RhdHVzID09IFNCUkRFQ19PSykgewogICAgaWYgKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBVUFNBTVBMSU5HICYmIGhlYWRlclN0YXR1cyAhPSBIRUFERVJfUkVTRVQpCiAgICB7CiAgICAgIC8qIEFzIHRoZSBkZWZhdWx0IGhlYWRlciB3b3VsZCBsaW1pdCB0aGUgZnJlcXVlbmN5IHJhbmdlLAogICAgICAgICBsb3dTdWJiYW5kIGFuZCBoaWdoU3ViYmFuZCBtdXN0IGJlIHBhdGNoZWQuICovCiAgICAgIGhTYnJIZWFkZXItPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kID0gaFNickhlYWRlci0+bnVtYmVyT2ZBbmFseXNpc0JhbmRzOwogICAgICBoU2JySGVhZGVyLT5mcmVxQmFuZERhdGEuaGlnaFN1YmJhbmQgPSBoU2JySGVhZGVyLT5udW1iZXJPZkFuYWx5c2lzQmFuZHM7CiAgICB9CgogICAgLyogVHJpZ2dlciBhIHJlc2V0IGJlZm9yZSBwcm9jZXNzaW5nIHRoaXMgc2xvdCAqLwogICAgaFNickhlYWRlci0+c3RhdHVzIHw9IFNCUkRFQ19IRFJfU1RBVF9SRVNFVDsKICB9CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKSU5UIHNickRlY29kZXJfSGVhZGVyICgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiAgICAgICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgIGhCcywKICAgICAgICBjb25zdCBJTlQgc2FtcGxlUmF0ZUluLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlT3V0LAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEICAgIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICApCnsKICBTQlJfSEVBREVSX1NUQVRVUyBoZWFkZXJTdGF0dXM7CiAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoU2JySGVhZGVyOwogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICBpbnQgaGVhZGVySW5kZXg7CgogIGlmICggc2VsZiA9PSBOVUxMIHx8IGVsZW1lbnRJbmRleCA+ICg4KSApCiAgewogICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgfQoKICBpZiAoISBzYnJEZWNvZGVyX2lzQ29yZUNvZGVjVmFsaWQoY29yZUNvZGVjKSkgewogICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgfQoKICBzYnJFcnJvciA9IHNickRlY29kZXJfSW5pdEVsZW1lbnQoCiAgICAgICAgICBzZWxmLAogICAgICAgICAgc2FtcGxlUmF0ZUluLAogICAgICAgICAgc2FtcGxlUmF0ZU91dCwKICAgICAgICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgIGNvcmVDb2RlYywKICAgICAgICAgIGVsZW1lbnRJRCwKICAgICAgICAgIGVsZW1lbnRJbmRleAogICAgICAgICAgKTsKCiAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgZ290byBiYWlsOwogIH0KCiAgaGVhZGVySW5kZXggPSBnZXRIZWFkZXJTbG90KHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnVzZUZyYW1lU2xvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+dXNlSGVhZGVyU2xvdCk7CiAgaFNickhlYWRlciA9ICYoc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baGVhZGVySW5kZXhdKTsKCiAgaGVhZGVyU3RhdHVzID0gc2JyR2V0SGVhZGVyRGF0YSAoIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwoKCiAgewogICAgU0JSX0RFQ09ERVJfRUxFTUVOVCAqcFNickVsZW1lbnQ7CgogICAgcFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYgKHBTYnJFbGVtZW50ICE9IE5VTEwpIHsKICAgICAgaWYgKCAoZWxlbWVudElEID09IElEX0NQRSAmJiBwU2JyRWxlbWVudC0+bkNoYW5uZWxzICE9IDIpCiAgICAgICAgfHwgKGVsZW1lbnRJRCAhPSBJRF9DUEUgJiYgcFNickVsZW1lbnQtPm5DaGFubmVscyAhPSAxKSApCiAgICAgIHsKICAgICAgICByZXR1cm4gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgICAgfQogICAgICBpZiAoIGhlYWRlclN0YXR1cyA9PSBIRUFERVJfUkVTRVQgKSB7CgogICAgICAgIHNickVycm9yID0gc2JyRGVjb2Rlcl9IZWFkZXJVcGRhdGUoCiAgICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgIGhlYWRlclN0YXR1cywKICAgICAgICAgICAgICBwU2JyRWxlbWVudC0+cFNickNoYW5uZWwsCiAgICAgICAgICAgICAgcFNickVsZW1lbnQtPm5DaGFubmVscwogICAgICAgICAgICAgICk7CgogICAgICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKICAgICAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9IRUFERVI7CiAgICAgICAgICBoU2JySGVhZGVyLT5zdGF0dXMgICB8PSBTQlJERUNfSERSX1NUQVRfVVBEQVRFOwogICAgICAgIH0KICAgICAgICAvKiBlbHNlIHsKICAgICAgICAgIFNpbmNlIHdlIGFscmVhZHkgaGF2ZSBvdmVyd3JpdHRlbiB0aGUgb2xkIFNCUiBoZWFkZXIgdGhlIG9ubHkgd2F5IG91dCBpcyBVUFNBTVBMSU5HIQogICAgICAgICAgVGhpcyB3aWxsIGJlIHByZXBhcmVkIGluIHRoZSBuZXh0IHN0ZXAuCiAgICAgICAgfSAqLwogICAgICB9CiAgICB9CiAgfQpiYWlsOgogIHJldHVybiBzYnJFcnJvcjsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX1NldFBhcmFtIChIQU5ETEVfU0JSREVDT0RFUiAgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTQlJERUNfUEFSQU0gIHBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICAgICB2YWx1ZSApCnsKICBTQlJfRVJST1IgZXJyb3JTdGF0dXMgPSBTQlJERUNfT0s7CgogIC8qIGNvbmZpZ3VyZSB0aGUgc3Vic3lzdGVtcyAqLwogIHN3aXRjaCAocGFyYW0pCiAgewogIGNhc2UgU0JSX1NZU1RFTV9CSVRTVFJFQU1fREVMQVk6CiAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gKDEpKSB7CiAgICAgIGVycm9yU3RhdHVzID0gU0JSREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICBicmVhazsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgfSBlbHNlIHsKICAgICAgc2VsZi0+bnVtRGVsYXlGcmFtZXMgPSAoVUNIQVIpdmFsdWU7CiAgICB9CiAgICBicmVhazsKICBjYXNlIFNCUl9RTUZfTU9ERToKICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgfSBlbHNlIHsKICAgICAgaWYgKHZhbHVlID09IDEpIHsKICAgICAgICBzZWxmLT5mbGFncyB8PSBTQlJERUNfTE9XX1BPV0VSOwogICAgICB9IGVsc2UgewogICAgICAgIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfTE9XX1BPV0VSOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIFNCUl9MRF9RTUZfVElNRV9BTElHTjoKICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgfSBlbHNlIHsKICAgICAgaWYgKHZhbHVlID09IDEpIHsKICAgICAgICBzZWxmLT5mbGFncyB8PSBTQlJERUNfTERfTVBTX1FNRjsKICAgICAgfSBlbHNlIHsKICAgICAgICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX0xEX01QU19RTUY7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgU0JSX0ZMVVNIX0RBVEE6CiAgICBpZiAodmFsdWUgIT0gMCkgewogICAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgICB9IGVsc2UgewogICAgICAgIHNlbGYtPmZsYWdzIHw9IFNCUkRFQ19GTFVTSDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBTQlJfQ0xFQVJfSElTVE9SWToKICAgIGlmICh2YWx1ZSAhPSAwKSB7CiAgICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19OT1RfSU5JVElBTElaRUQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gU0JSREVDX0ZPUkNFX1JFU0VUOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIFNCUl9CU19JTlRFUlJVUFRJT046CiAgICB7CiAgICAgIGludCBlbGVtZW50SW5kZXg7CgogICAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfTk9UX0lOSVRJQUxJWkVEOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICAvKiBMb29wIG92ZXIgU0JSIGVsZW1lbnRzICovCiAgICAgIGZvciAoZWxlbWVudEluZGV4ID0gMDsgZWxlbWVudEluZGV4IDwgc2VsZi0+bnVtU2JyRWxlbWVudHM7IGVsZW1lbnRJbmRleCsrKSB7CiAgICAgIGlmIChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICE9IE5VTEwpCiAgICAgIHsKICAgICAgICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgICAgICAgaW50IGhlYWRlckluZGV4ID0gZ2V0SGVhZGVyU2xvdChzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VGcmFtZVNsb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT51c2VIZWFkZXJTbG90KTsKCiAgICAgICAgaFNickhlYWRlciA9ICYoc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1baGVhZGVySW5kZXhdKTsKCiAgICAgICAgLyogU2V0IHN5bmMgc3RhdGUgVVBTQU1QTElORyBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgc2xvdC4KICAgICAgICAgICBUaGlzIHN3aXRjaGVzIG9mZiBiaXRzdHJlYW0gcGFyc2luZyB1bnRpbCBhIG5ldyBoZWFkZXIgYXJyaXZlcy4gKi8KICAgICAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBVUFNBTVBMSU5HOwogICAgICAgIGhTYnJIZWFkZXItPnN0YXR1cyAgIHw9IFNCUkRFQ19IRFJfU1RBVF9VUERBVEU7CiAgICAgIH0gfQogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGVycm9yU3RhdHVzID0gU0JSREVDX1NFVF9QQVJBTV9GQUlMOwogICAgYnJlYWs7CiAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKICByZXR1cm4gKGVycm9yU3RhdHVzKTsKfQoKc3RhdGljClNCUkRFQ19EUkNfQ0hBTk5FTCAqIHNickRlY29kZXJfZHJjR2V0Q2hhbm5lbCggY29uc3QgSEFORExFX1NCUkRFQ09ERVIgc2VsZiwgY29uc3QgSU5UIGNoYW5uZWwgKQp7CiAgU0JSREVDX0RSQ19DSEFOTkVMICpwU2JyRHJjQ2hhbm5lbERhdGEgPSBOVUxMOwogIGludCBlbGVtZW50SW5kZXgsIGVsQ2hhbklkeD0wLCBudW1DaD0wOwoKICBmb3IgKGVsZW1lbnRJbmRleCA9IDA7IChlbGVtZW50SW5kZXggPCAoOCkpICYmIChudW1DaCA8PSBjaGFubmVsKTsgZWxlbWVudEluZGV4KyspCiAgewogICAgU0JSX0RFQ09ERVJfRUxFTUVOVCAqcFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwogICAgaW50IGMsIGVsQ2hhbm5lbHM7CgogICAgZWxDaGFuSWR4ID0gMDsKICAgIGlmIChwU2JyRWxlbWVudCA9PSBOVUxMKSBicmVhazsKCiAgICAvKiBEZXRlcm1pbmUgYW1vdW50IG9mIGNoYW5uZWxzIGZvciB0aGlzIGVsZW1lbnQgKi8KICAgIHN3aXRjaCAocFNickVsZW1lbnQtPmVsZW1lbnRJRCkgewogICAgICBjYXNlIElEX0NQRTogZWxDaGFubmVscyA9IDI7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgSURfTEZFOgogICAgICBjYXNlIElEX1NDRTogZWxDaGFubmVscyA9IDE7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgSURfTk9ORToKICAgICAgZGVmYXVsdDogZWxDaGFubmVscyA9IDA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyogTGltaXQgd2l0aCBhY3R1YWwgYWxsb2NhdGVkIGVsZW1lbnQgY2hhbm5lbHMgKi8KICAgIGVsQ2hhbm5lbHMgPSBGREttaW4oZWxDaGFubmVscywgcFNickVsZW1lbnQtPm5DaGFubmVscyk7CgogICAgZm9yIChjID0gMDsgKGMgPCBlbENoYW5uZWxzKSAmJiAobnVtQ2ggPD0gY2hhbm5lbCk7IGMrKykgewogICAgICBpZiAocFNickVsZW1lbnQtPnBTYnJDaGFubmVsW2VsQ2hhbklkeF0gIT0gTlVMTCkgewogICAgICAgIG51bUNoKys7CiAgICAgICAgZWxDaGFuSWR4Kys7CiAgICAgIH0KICAgIH0KICB9CiAgZWxlbWVudEluZGV4IC09IDE7CiAgZWxDaGFuSWR4IC09IDE7CgogIGlmIChlbENoYW5JZHggPCAwIHx8IGVsZW1lbnRJbmRleCA8IDApIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgaWYgKCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdICE9IE5VTEwgKSB7CiAgICBpZiAoIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsW2VsQ2hhbklkeF0gIT0gTlVMTCApCiAgICB7CiAgICAgIHBTYnJEcmNDaGFubmVsRGF0YSA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFtlbENoYW5JZHhdLT5TYnJEZWMuc2JyRHJjQ2hhbm5lbDsKICAgIH0KICB9CgogIHJldHVybiAocFNickRyY0NoYW5uZWxEYXRhKTsKfQoKU0JSX0VSUk9SIHNickRlY29kZXJfZHJjRmVlZENoYW5uZWwgKCBIQU5ETEVfU0JSREVDT0RFUiAgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICAgICAgICAgICAgIG51bUJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICAgICAgICpwTmV4dEZhY3RfbWFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICBuZXh0RmFjdF9leHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgICAgICAgICAgICAgIGRyY0ludGVycG9sYXRpb25TY2hlbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgICAgICAgICAgICAgIHdpblNlcXVlbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTSE9SVCAgICAgICAgICAgICpwQmFuZFRvcCApCnsKICBTQlJERUNfRFJDX0NIQU5ORUwgKnBTYnJEcmNDaGFubmVsRGF0YSA9IE5VTEw7CiAgaW50IGJhbmQsIGlzVmFsaWREYXRhID0gMDsKCiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgcmV0dXJuIFNCUkRFQ19OT1RfSU5JVElBTElaRUQ7CiAgfQogIGlmIChjaCA+ICg4KSB8fCBwTmV4dEZhY3RfbWFnID09IE5VTEwpIHsKICAgIHJldHVybiBTQlJERUNfU0VUX1BBUkFNX0ZBSUw7CiAgfQoKICAvKiBTZWFyY2ggZm9yIGdhaW4gdmFsdWVzIGRpZmZlcmVudCB0byAxLjBmICovCiAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kICs9IDEpIHsKICAgIGlmICggISgocE5leHRGYWN0X21hZ1tiYW5kXSA9PSBGTDJGWENPTlNUX0RCTCgwLjUpKSAgJiYgKG5leHRGYWN0X2V4cCA9PSAxKSkKICAgICAgJiYgISgocE5leHRGYWN0X21hZ1tiYW5kXSA9PSAoRklYUF9EQkwpTUFYVkFMX0RCTCkgJiYgKG5leHRGYWN0X2V4cCA9PSAwKSkgKSB7CiAgICAgIGlzVmFsaWREYXRhID0gMTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICAvKiBGaW5kIHRoZSByaWdodCBTQlIgY2hhbm5lbCAqLwogIHBTYnJEcmNDaGFubmVsRGF0YSA9IHNickRlY29kZXJfZHJjR2V0Q2hhbm5lbCggc2VsZiwgY2ggKTsKCiAgaWYgKCBwU2JyRHJjQ2hhbm5lbERhdGEgIT0gTlVMTCApIHsKICAgIGlmICggcFNickRyY0NoYW5uZWxEYXRhLT5lbmFibGUgfHwgaXNWYWxpZERhdGEgKQogIHsgLyogQWN0aXZhdGUgcHJvY2Vzc2luZyBvbmx5IHdpdGggcmVhbCBhbmQgdmFsaWQgZGF0YSAqLwogICAgaW50IGk7CgogICAgcFNickRyY0NoYW5uZWxEYXRhLT5lbmFibGUgICA9IDE7CiAgICBwU2JyRHJjQ2hhbm5lbERhdGEtPm51bUJhbmRzTmV4dCA9IG51bUJhbmRzOwoKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+d2luU2VxdWVuY2VOZXh0ICAgICAgICAgICAgPSB3aW5TZXF1ZW5jZTsKICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+ZHJjSW50ZXJwb2xhdGlvblNjaGVtZU5leHQgPSBkcmNJbnRlcnBvbGF0aW9uU2NoZW1lOwogICAgcFNickRyY0NoYW5uZWxEYXRhLT5uZXh0RmFjdF9leHAgICAgICAgICAgICAgICA9IG5leHRGYWN0X2V4cDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgKGludCludW1CYW5kczsgaSsrKSB7CiAgICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+YmFuZFRvcE5leHRbaV0gID0gcEJhbmRUb3BbaV07CiAgICAgIHBTYnJEcmNDaGFubmVsRGF0YS0+bmV4dEZhY3RfbWFnW2ldID0gcE5leHRGYWN0X21hZ1tpXTsKICAgIH0KICB9CiAgfQoKICByZXR1cm4gU0JSREVDX09LOwp9CgoKdm9pZCBzYnJEZWNvZGVyX2RyY0Rpc2FibGUgKCBIQU5ETEVfU0JSREVDT0RFUiAgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgY2ggKQp7CiAgU0JSREVDX0RSQ19DSEFOTkVMICpwU2JyRHJjQ2hhbm5lbERhdGEgPSBOVUxMOwoKICBpZiAoIChzZWxmID09IE5VTEwpCiAgICB8fCAoY2ggPiAoOCkpCiAgICB8fCAoc2VsZi0+bnVtU2JyRWxlbWVudHMgPT0gMCkKICAgIHx8IChzZWxmLT5udW1TYnJDaGFubmVscyA9PSAwKSApIHsKICAgIHJldHVybjsKICB9CgogIC8qIEZpbmQgdGhlIHJpZ2h0IFNCUiBjaGFubmVsICovCiAgcFNickRyY0NoYW5uZWxEYXRhID0gc2JyRGVjb2Rlcl9kcmNHZXRDaGFubmVsKCBzZWxmLCBjaCApOwoKICBpZiAoIHBTYnJEcmNDaGFubmVsRGF0YSAhPSBOVUxMICkgewogICAgc2JyRGVjb2Rlcl9kcmNJbml0Q2hhbm5lbCggcFNickRyY0NoYW5uZWxEYXRhICk7CiAgfQp9CgoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX1BhcnNlKAogICAgICAgIEhBTkRMRV9TQlJERUNPREVSIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gIGhCcywKICAgICAgICBpbnQgKmNvdW50LAogICAgICAgIGludCAgYnNQYXlMZW4sCiAgICAgICAgaW50ICBjcmNGbGFnLAogICAgICAgIE1QNF9FTEVNRU5UX0lEIHByZXZFbGVtZW50LAogICAgICAgIGludCBlbGVtZW50SW5kZXgsCiAgICAgICAgaW50IGZHbG9iYWxJbmRlcGVuZGVuY3lGbGFnCiAgICAgICAgKQp7CiAgU0JSX0RFQ09ERVJfRUxFTUVOVCAgICpoU2JyRWxlbWVudDsKICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhTYnJIZWFkZXI7CiAgSEFORExFX1NCUl9DSEFOTkVMICAgICpwU2JyQ2hhbm5lbDsKCiAgU0JSX0ZSQU1FX0RBVEEgKmhGcmFtZURhdGFMZWZ0OwogIFNCUl9GUkFNRV9EQVRBICpoRnJhbWVEYXRhUmlnaHQ7CgogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKICBTQlJfU1lOQ19TVEFURSBpbml0aWFsU3luY1N0YXRlOwogIFNCUl9IRUFERVJfU1RBVFVTIGhlYWRlclN0YXR1cyA9IEhFQURFUl9OT1RfUFJFU0VOVDsKCiAgSU5UICBzdGFydFBvczsKICBJTlQgIENSQ0xlbiA9IDA7CgogIGludCAgc3RlcmVvOwogIGludCAgZkRvRGVjb2RlU2JyRGF0YSA9IDE7CgogIGludCBsYXN0U2xvdCwgbGFzdEhkclNsb3QgPSAwLCB0aGlzSGRyU2xvdDsKCiAgLyogUmVtZW1iZXIgc3RhcnQgcG9zaXRpb24gb2YgIFNCUiBlbGVtZW50ICovCiAgc3RhcnRQb3MgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgLyogU0JSIHNhbml0eSBjaGVja3MgKi8KICBpZiAoIHNlbGYgPT0gTlVMTCB8fCBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdID09IE5VTEwgKSB7CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19OT1RfSU5JVElBTElaRUQ7CiAgICBnb3RvIGJhaWw7CiAgfSAKCiAgaFNickVsZW1lbnQgPSBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdOwoKICBsYXN0U2xvdCAgICA9IChoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90ID4gMCkgPyBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90LTEgOiBzZWxmLT5udW1EZWxheUZyYW1lczsKICBsYXN0SGRyU2xvdCA9ICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtsYXN0U2xvdF07CiAgdGhpc0hkclNsb3QgPSAgZ2V0SGVhZGVyU2xvdCggaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCwgaFNickVsZW1lbnQtPnVzZUhlYWRlclNsb3QgKTsgIC8qIEdldCBhIGZyZWUgaGVhZGVyIHNsb3Qgbm90IHVzZWQgYnkgZnJhbWVzIG5vdCBwcm9jZXNzZWQgeWV0LiAqLwoKICAvKiBBc3NpZ24gdGhlIGZyZWUgc2xvdCB0byBzdG9yZSBhIG5ldyBoZWFkZXIgaWYgdGhlcmUgaXMgb25lLiAqLwogIGhTYnJIZWFkZXIgPSAmc2VsZi0+c2JySGVhZGVyW2VsZW1lbnRJbmRleF1bdGhpc0hkclNsb3RdOwoKICBwU2JyQ2hhbm5lbCA9IGhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbDsKICBzdGVyZW8gPSAoaFNickVsZW1lbnQtPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMSA6IDA7CgogIGhGcmFtZURhdGFMZWZ0ICA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFswXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwogIGhGcmFtZURhdGFSaWdodCA9ICZzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5wU2JyQ2hhbm5lbFsxXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwoKICBpbml0aWFsU3luY1N0YXRlID0gaFNickhlYWRlci0+c3luY1N0YXRlOwoKICAvKiByZXNldCBQUyBmbGFnOyB3aWxsIGJlIHNldCBhZnRlciBQUyB3YXMgZm91bmQgKi8KICBzZWxmLT5mbGFncyAmPSB+U0JSREVDX1BTX0RFQ09ERUQ7CgogIGlmIChoU2JySGVhZGVyLT5zdGF0dXMgJiBTQlJERUNfSERSX1NUQVRfVVBEQVRFKSB7CiAgICAvKiBHb3QgYSBuZXcgaGVhZGVyIGZyb20gZXh0ZXJuIChlLmcuIGZyb20gYW4gQVNDKSAqLwogICAgaGVhZGVyU3RhdHVzID0gSEVBREVSX09LOwogICAgaFNickhlYWRlci0+c3RhdHVzICY9IH5TQlJERUNfSERSX1NUQVRfVVBEQVRFOwogIH0KICBlbHNlIGlmICh0aGlzSGRyU2xvdCAhPSBsYXN0SGRyU2xvdCkgewogICAgLyogQ29weSB0aGUgbGFzdCBoZWFkZXIgaW50byB0aGlzIHNsb3Qgb3RoZXJ3aXNlIHRoZQogICAgICAgaGVhZGVyIGNvbXBhcmUgd2lsbCB0cmlnZ2VyIG1vcmUgSEVBREVSX1JFU0VUcyB0aGFuIG5lZWRlZC4gKi8KICAgIGNvcHlTYnJIZWFkZXIoIGhTYnJIZWFkZXIsICZzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtsYXN0SGRyU2xvdF0gKTsKICB9CgogIC8qCiAgICAgQ2hlY2sgaWYgYml0IHN0cmVhbSBkYXRhIGlzIHZhbGlkIGFuZCBtYXRjaGVzIHRoZSBlbGVtZW50IGNvbnRleHQKICAqLwogIGlmICggKChwcmV2RWxlbWVudCAhPSBJRF9TQ0UpICYmIChwcmV2RWxlbWVudCAhPSBJRF9DUEUpKSB8fCBwcmV2RWxlbWVudCAhPSBoU2JyRWxlbWVudC0+ZWxlbWVudElEKSB7CiAgICAvKiBJbiBjYXNlIG9mIExGRSB3ZSBhbHNvIGxhbmQgaGVyZSwgc2luY2UgdGhlcmUgaXMgbm8gTEZFIFNCUiBlbGVtZW50IChkbyB1cHNhbXBsaW5nIG9ubHkpICovCiAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICB9CgogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpIDw9IDApIHsKICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICB9CiAgfQoKICAvKgogICAgIFNCUiBDUkMtY2hlY2sKICAqLwogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGlmIChjcmNGbGFnID09IDEpIHsKICAgICAgc3dpdGNoIChzZWxmLT5jb3JlQ29kZWMpIHsKICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICBGREtwdXNoRm9yIChoQnMsIDEwKTsKICAgICAgICAvKiBjaGVjayBzYnJjcmMgbGF0ZXI6IHdlIGRvbid0IGtub3cgdGhlIHBheWxvYWQgbGVuZ3RoIG5vdyAqLwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIENSQ0xlbiA9IGJzUGF5TGVuIC0gMTA7ICAgICAgICAgICAgICAgICAgICAgLyogY2hhbmdlOiAwID0+IGkgKi8KICAgICAgICBpZiAoQ1JDTGVuIDwgMCkgewogICAgICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgPSBTYnJDcmNDaGVjayAoaEJzLCBDUkNMZW4pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0gLyogaWYgKGZEb0RlY29kZVNickRhdGEpICovCgogIC8qCiAgICAgUmVhZCBpbiB0aGUgaGVhZGVyIGRhdGEgYW5kIGlzc3VlIGEgcmVzZXQgaWYgY2hhbmdlIG9jY3VyZWQKICAqLwogIGlmIChmRG9EZWNvZGVTYnJEYXRhKQogIHsKICAgIGludCBzYnJIZWFkZXJQcmVzZW50OwoKICAgIHsKICAgICAgc2JySGVhZGVyUHJlc2VudCA9IEZES3JlYWRCaXQoaEJzKTsKICAgIH0KCiAgICBpZiAoIHNickhlYWRlclByZXNlbnQgKSB7CiAgICAgIGhlYWRlclN0YXR1cyA9IHNickdldEhlYWRlckRhdGEgKGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpOwogICAgfQoKICAgIGlmIChoZWFkZXJTdGF0dXMgPT0gSEVBREVSX1JFU0VUKQogICAgewogICAgICBlcnJvclN0YXR1cyA9IHNickRlY29kZXJfSGVhZGVyVXBkYXRlKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBoZWFkZXJTdGF0dXMsCiAgICAgICAgICAgIHBTYnJDaGFubmVsLAogICAgICAgICAgICBoU2JyRWxlbWVudC0+bkNoYW5uZWxzIAogICAgICAgICAgICApOwoKICAgICAgaWYgKGVycm9yU3RhdHVzID09IFNCUkRFQ19PSykgewogICAgICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFNCUl9IRUFERVI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gU0JSX05PVF9JTklUSUFMSVpFRDsKICAgICAgfQogICAgfQoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgZkRvRGVjb2RlU2JyRGF0YSA9IDA7CiAgICB9CiAgfSAvKiBpZiAoZkRvRGVjb2RlU2JyRGF0YSkgKi8KCiAgLyoKICAgIFByaW50IGRlYnVnZ2luZyBvdXRwdXQgb25seSBpZiBzdGF0ZSBoYXMgY2hhbmdlZAogICovCgogIC8qIHJlYWQgZnJhbWUgZGF0YSAqLwogIGlmICgoaFNickhlYWRlci0+c3luY1N0YXRlID49IFNCUl9IRUFERVIpICYmIGZEb0RlY29kZVNickRhdGEpIHsKICAgIGludCBzYnJGcmFtZU9rOwogICAgLyogcmVhZCB0aGUgU0JSIGVsZW1lbnQgZGF0YSAqLwogICAgaWYgKHN0ZXJlbykgewogICAgICBzYnJGcmFtZU9rID0gc2JyR2V0Q2hhbm5lbFBhaXJFbGVtZW50KGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YVJpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT50cmFuc3Bvc2VyU2V0dGluZ3Mub3ZlcmxhcCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgaWYgKHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjICE9IE5VTEwpIHsKICAgICAgICAvKiB1cGRhdGUgc2xvdCBpbmRleCBmb3IgUFMgYml0c3RyZWFtIHBhcnNpbmcgKi8KICAgICAgICBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYy0+YnNMYXN0U2xvdCA9IHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic1JlYWRTbG90OwogICAgICAgIHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic1JlYWRTbG90ID0gaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdDsKICAgICAgfQogICAgICBzYnJGcmFtZU9rID0gc2JyR2V0U2luZ2xlQ2hhbm5lbEVsZW1lbnQoaFNickhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhGcmFtZURhdGFMZWZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnRyYW5zcG9zZXJTZXR0aW5ncy5vdmVybGFwKTsKICAgIH0KICAgIGlmICghc2JyRnJhbWVPaykgewogICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgIH0KICAgIGVsc2UgewogICAgICBJTlQgdmFsQml0czsKCiAgICAgIGlmIChic1BheUxlbiA+IDApIHsKICAgICAgICB2YWxCaXRzID0gYnNQYXlMZW4gLSAoKElOVClzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhbEJpdHMgPSAoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpOwogICAgICB9CgogICAgICBpZiAoIGNyY0ZsYWcgPT0gMSApIHsKICAgICAgICBzd2l0Y2ggKHNlbGYtPmNvcmVDb2RlYykgewogICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIGxhdGUgY3JjIGNoZWNrIGZvciBlbGQgKi8KICAgICAgICAgICAgSU5UIHBheWxvYWRiaXRzID0gKElOVClzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBzdGFydFBvczsKICAgICAgICAgICAgSU5UIGNyY0xlbiAgICAgID0gcGF5bG9hZGJpdHMgLSAxMDsKICAgICAgICAgICAgRkRLcHVzaEJhY2soaEJzLCBwYXlsb2FkYml0cyk7CiAgICAgICAgICAgIGZEb0RlY29kZVNickRhdGEgICAgICA9IFNickNyY0NoZWNrIChoQnMsIGNyY0xlbik7CiAgICAgICAgICAgIEZES3B1c2hGb3IoaEJzLCBjcmNMZW4pOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogc2FuaXR5IGNoZWNrIG9mIHJlbWFpbmluZyBiaXRzICovCiAgICAgIGlmICh2YWxCaXRzIDwgMCkgewogICAgICAgIGZEb0RlY29kZVNickRhdGEgPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIHN3aXRjaCAoc2VsZi0+Y29yZUNvZGVjKSB7CiAgICAgICAgY2FzZSBBT1RfU0JSOgogICAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgICAgIHsKICAgICAgICAgICAgLyogVGhpcyBzYW5pdHkgY2hlY2sgaXMgb25seSBtZWFuaW5nZnVsIHdpdGggR2VuZXJhbCBBdWRpbyBiaXRzdHJlYW1zICovCiAgICAgICAgICAgIGludCBhbGlnbkJpdHMgPSB2YWxCaXRzICYgMHg3OwoKICAgICAgICAgICAgaWYgKHZhbEJpdHMgPiBhbGlnbkJpdHMpIHsKICAgICAgICAgICAgICBmRG9EZWNvZGVTYnJEYXRhID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIC8qIE5vIHNhbml0eSBjaGVjayBhdmFpbGFibGUgKi8KICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBUaGUgcmV0dXJuZWQgYml0IGNvdW50IHdpbGwgbm90IGJlIHRoZSBhY3R1YWwgcGF5bG9hZCBzaXplIHNpbmNlIHdlIGRpZCBub3QKICAgICAgIHBhcnNlIHRoZSBmcmFtZSBkYXRhLiBSZXR1cm4gYW4gZXJyb3Igc28gdGhhdCB0aGUgY2FsbGVyIGNhbiByZWFjdCByZXNwZWN0aXZlbHkuICovCiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19QQVJTRV9FUlJPUjsKICB9CgogIGlmICghZkRvRGVjb2RlU2JyRGF0YSkgewogICAgLyogU2V0IGVycm9yIGZsYWcgZm9yIHRoaXMgc2xvdCB0byB0cmlnZ2VyIGNvbmNlYWxtZW50ICovCiAgICBzZWxmLT5wU2JyRWxlbWVudFtlbGVtZW50SW5kZXhdLT5mcmFtZUVycm9yRmxhZ1toU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XSA9IDE7CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19QQVJTRV9FUlJPUjsKICB9IGVsc2UgewogICAgLyogRXZlcnl0aGluZyBzZWVtcyB0byBiZSBvayBzbyBjbGVhciB0aGUgZXJyb3IgZmxhZyAqLwogICAgc2VsZi0+cFNickVsZW1lbnRbZWxlbWVudEluZGV4XS0+ZnJhbWVFcnJvckZsYWdbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF0gPSAwOwogIH0KCiAgaWYgKCFzdGVyZW8pIHsKICAgIC8qIFR1cm4gY291cGxpbmcgb2ZmIGV4cGxpY2l0ZWx5IHRvIGF2b2lkIGFjY2VzcyB0byBhYnNlbnQgcmlnaHQgZnJhbWUgZGF0YQogICAgICAgdGhhdCBtaWdodCBvY2N1ciB3aXRoIGNvcnJ1cHQgYml0c3RyZWFtcy4gKi8KICAgIGhGcmFtZURhdGFMZWZ0LT5jb3VwbGluZyA9IENPVVBMSU5HX09GRjsKICB9CgpiYWlsOgogIGlmIChlcnJvclN0YXR1cyA9PSBTQlJERUNfT0spIHsKICAgIGlmIChoZWFkZXJTdGF0dXMgPT0gSEVBREVSX05PVF9QUkVTRU5UKSB7CiAgICAgIC8qIFVzZSB0aGUgb2xkIGhlYWRlciBmb3IgdGhpcyBmcmFtZSAqLwogICAgICBoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XSA9IGxhc3RIZHJTbG90OwogICAgfSBlbHNlIHsKICAgICAgLyogVXNlIHRoZSBuZXcgaGVhZGVyIGZvciB0aGlzIGZyYW1lICovCiAgICAgIGhTYnJFbGVtZW50LT51c2VIZWFkZXJTbG90W2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdID0gdGhpc0hkclNsb3Q7CiAgICB9CgogICAgLyogTW92ZSBmcmFtZSBwb2ludGVyIHRvIHRoZSBuZXh0IHNsb3Qgd2hpY2ggaXMgdXAgdG8gYmUgZGVjb2RlZC9hcHBsaWVkIG5leHQgKi8KICAgIGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QgPSAoaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCsxKSAlIChzZWxmLT5udW1EZWxheUZyYW1lcysxKTsKICB9CgogICpjb3VudCAtPSBzdGFydFBvcyAtIEZES2dldFZhbGlkQml0cyhoQnMpOwoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCgovKioKICogXGJyaWVmIFJlbmRlciBvbmUgU0JSIGVsZW1lbnQgaW50byB0aW1lIGRvbWFpbiBzaWduYWwuCiAqIFxwYXJhbSBzZWxmIFNCUiBkZWNvZGVyIGhhbmRsZQogKiBccGFyYW0gdGltZURhdGEgcG9pbnRlciB0byBvdXRwdXQgYnVmZmVyCiAqIFxwYXJhbSBpbnRlcmxlYXZlZCBmbGFnIGluZGljYXRpbmcgaW50ZXJsZWF2ZWQgY2hhbm5lbCBvdXRwdXQKICogXHBhcmFtIGNoYW5uZWxNYXBwaW5nIHBvaW50ZXIgdG8gVUNIQVIgYXJyYXkgd2hlcmUgbmV4dCAyIGNoYW5uZWwgb2Zmc2V0cyBhcmUgc3RvcmVkLiAKICogXHBhcmFtIGVsZW1lbnRJbmRleCBlbnVtZXJhdGluZyBpbmRleCBvZiB0aGUgU0JSIGVsZW1lbnQgdG8gcmVuZGVyLgogKiBccGFyYW0gbnVtSW5DaGFubmVscyBudW1iZXIgb2YgY2hhbm5lbHMgZnJvbSBjb3JlIGNvZGVyIChyZWFkaW5nIHN0cmlkZSkuCiAqIFxwYXJhbSBudW1PdXRDaGFubmVscyBwb2ludGVyIHRvIGEgbG9jYXRpb24gdG8gcmV0dXJuIG51bWJlciBvZiBvdXRwdXQgY2hhbm5lbHMuCiAqIFxwYXJhbSBwc1Bvc3NpYmxlIGZsYWcgaW5kaWNhdGluZyBpZiBQUyBpcyBwb3NzaWJsZSBvciBub3QuCiAqIFxyZXR1cm4gU0JSREVDX09LIGlmIHN1Y2Nlc3NmdWxsLCBlbHNlIGVycm9yIGNvZGUKICovCnN0YXRpYyBTQlJfRVJST1IKc2JyRGVjb2Rlcl9EZWNvZGVFbGVtZW50ICgKICAgICAgICBIQU5ETEVfU0JSREVDT0RFUiAgICBzZWxmLAogICAgICAgIElOVF9QQ00gICAgICAgICAgICAgKnRpbWVEYXRhLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIGludGVybGVhdmVkLAogICAgICAgIGNvbnN0IFVDSEFSICAgICAgICAgKmNoYW5uZWxNYXBwaW5nLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIGVsZW1lbnRJbmRleCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBudW1JbkNoYW5uZWxzLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgKm51bU91dENoYW5uZWxzLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgIHBzUG9zc2libGUKICAgICAgICApCnsKICBTQlJfREVDT0RFUl9FTEVNRU5UICpoU2JyRWxlbWVudCA9IHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF07CiAgSEFORExFX1NCUl9DSEFOTkVMICAgICpwU2JyQ2hhbm5lbCA9IHNlbGYtPnBTYnJFbGVtZW50W2VsZW1lbnRJbmRleF0tPnBTYnJDaGFubmVsOwogIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaFNickhlYWRlciA9ICZzZWxmLT5zYnJIZWFkZXJbZWxlbWVudEluZGV4XVtoU2JyRWxlbWVudC0+dXNlSGVhZGVyU2xvdFtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XV07CiAgSEFORExFX1BTX0RFQyBoX3BzX2QgPSBzZWxmLT5oUGFyYW1ldHJpY1N0ZXJlb0RlYzsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZnJhbWUgZGF0YSBmcm9tIHNjcmF0Y2ggKi8KICBTQlJfRlJBTUVfREFUQSAqaEZyYW1lRGF0YUxlZnQgID0gJmhTYnJFbGVtZW50LT5wU2JyQ2hhbm5lbFswXS0+ZnJhbWVEYXRhW2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdOwogIFNCUl9GUkFNRV9EQVRBICpoRnJhbWVEYXRhUmlnaHQgPSAmaFNickVsZW1lbnQtPnBTYnJDaGFubmVsWzFdLT5mcmFtZURhdGFbaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdF07CgogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKCgogIElOVCAgc3RyaWRlSW4sIHN0cmlkZU91dCwgb2Zmc2V0MCwgb2Zmc2V0MTsKICBJTlQgIGNvZGVjRnJhbWVTaXplID0gc2VsZi0+Y29kZWNGcmFtZVNpemU7CgogIGludCAgc3RlcmVvID0gKGhTYnJFbGVtZW50LT5lbGVtZW50SUQgPT0gSURfQ1BFKSA/IDEgOiAwOwogIGludCAgbnVtRWxlbWVudENoYW5uZWxzID0gaFNickVsZW1lbnQtPm5DaGFubmVsczsgLyogTnVtYmVyIG9mIGNoYW5uZWxzIG9mIHRoZSBjdXJyZW50IFNCUiBlbGVtZW50ICovCgogIGlmIChzZWxmLT5mbGFncyAmIFNCUkRFQ19GTFVTSCkgewogICAgLyogTW92ZSBmcmFtZSBwb2ludGVyIHRvIHRoZSBuZXh0IHNsb3Qgd2hpY2ggaXMgdXAgdG8gYmUgZGVjb2RlZC9hcHBsaWVkIG5leHQgKi8KICAgIGhTYnJFbGVtZW50LT51c2VGcmFtZVNsb3QgPSAoaFNickVsZW1lbnQtPnVzZUZyYW1lU2xvdCsxKSAlIChzZWxmLT5udW1EZWxheUZyYW1lcysxKTsKICAgIC8qIFVwZGF0ZSBoZWFkZXIgYW5kIGZyYW1lIGRhdGEgcG9pbnRlciBiZWNhdXNlIHRoZXkgaGF2ZSBhbHJlYWR5IGJlZW4gc2V0ICovCiAgICBoU2JySGVhZGVyID0gJnNlbGYtPnNickhlYWRlcltlbGVtZW50SW5kZXhdW2hTYnJFbGVtZW50LT51c2VIZWFkZXJTbG90W2hTYnJFbGVtZW50LT51c2VGcmFtZVNsb3RdXTsKICAgIGhGcmFtZURhdGFMZWZ0ICA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMF0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICAgIGhGcmFtZURhdGFSaWdodCA9ICZoU2JyRWxlbWVudC0+cFNickNoYW5uZWxbMV0tPmZyYW1lRGF0YVtoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKICB9CgogIC8qIFVwZGF0ZSB0aGUgaGVhZGVyIGVycm9yIGZsYWcgKi8KICBoU2JySGVhZGVyLT5mcmFtZUVycm9yRmxhZyA9IGhTYnJFbGVtZW50LT5mcmFtZUVycm9yRmxhZ1toU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90XTsKCiAgLyoKICAgICBQcmVwYXJlIGZpbHRlcmJhbmsgZm9yIHVwc2FtcGxpbmcgaWYgbm8gdmFsaWQgYml0IHN0cmVhbSBkYXRhIGlzIGF2YWlsYWJsZS4KICAgKi8KICBpZiAoIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBTQlJfTk9UX0lOSVRJQUxJWkVEICkKICB7CiAgICBlcnJvclN0YXR1cyA9IGluaXRIZWFkZXJEYXRhKAogICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICBzZWxmLT5zYW1wbGVSYXRlSW4sCiAgICAgICAgICAgIHNlbGYtPnNhbXBsZVJhdGVPdXQsCiAgICAgICAgICAgIGNvZGVjRnJhbWVTaXplLAogICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgICApOwoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgcmV0dXJuIGVycm9yU3RhdHVzOwogICAgfQoKICAgIGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9IFVQU0FNUExJTkc7CgogICAgZXJyb3JTdGF0dXMgPSBzYnJEZWNvZGVyX0hlYWRlclVwZGF0ZSgKICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgSEVBREVSX05PVF9QUkVTRU5ULAogICAgICAgICAgICBwU2JyQ2hhbm5lbCwKICAgICAgICAgICAgaFNickVsZW1lbnQtPm5DaGFubmVscwogICAgICAgICAgICApOwoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgaFNickhlYWRlci0+c3luY1N0YXRlID0gU0JSX05PVF9JTklUSUFMSVpFRDsKICAgICAgcmV0dXJuIGVycm9yU3RhdHVzOwogICAgfQogIH0KCiAgLyogcmVzZXQgKi8KICBpZiAoaFNickhlYWRlci0+c3RhdHVzICYgU0JSREVDX0hEUl9TVEFUX1JFU0VUKSB7CiAgICBpbnQgY2g7CiAgICBmb3IgKGNoID0gMCA7IGNoIDwgbnVtRWxlbWVudENoYW5uZWxzOyBjaCsrKSB7CiAgICAgIFNCUl9FUlJPUiBlcnJvclN0YXR1c1RtcCA9IFNCUkRFQ19PSzsKCiAgICAgIGVycm9yU3RhdHVzVG1wID0gcmVzZXRTYnJEZWMgKAogICAgICAgICAgICAgJnBTYnJDaGFubmVsW2NoXS0+U2JyRGVjLAogICAgICAgICAgICAgIGhTYnJIZWFkZXIsCiAgICAgICAgICAgICAmcFNickNoYW5uZWxbY2hdLT5wcmV2RnJhbWVEYXRhLAogICAgICAgICAgICAgIHNlbGYtPmZsYWdzICYgU0JSREVDX0xPV19QT1dFUiwKICAgICAgICAgICAgICBzZWxmLT5zeW5Eb3duc2FtcGxlRmFjCiAgICAgICAgICAgICAgKTsKCiAgICAgIGlmIChlcnJvclN0YXR1c1RtcCAhPSBTQlJERUNfT0spIHsKICAgICAgICBlcnJvclN0YXR1cyA9IGVycm9yU3RhdHVzVG1wOwogICAgICB9CiAgICB9CiAgICBoU2JySGVhZGVyLT5zdGF0dXMgJj0gflNCUkRFQ19IRFJfU1RBVF9SRVNFVDsKICB9CgogIC8qIGRlY29kaW5nICovCiAgaWYgKCAoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9BQ1RJVkUpCiAgICB8fCAoKGhTYnJIZWFkZXItPnN5bmNTdGF0ZSA9PSBTQlJfSEVBREVSKSAmJiAoaFNickhlYWRlci0+ZnJhbWVFcnJvckZsYWcgPT0gMCkpICkKICB7CiAgICBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKCiAgICBkZWNvZGVTYnJEYXRhIChoU2JySGVhZGVyLAogICAgICAgICAgICAgICAgICAgaEZyYW1lRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFswXS0+cHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgICAgICAgIChzdGVyZW8pID8gaEZyYW1lRGF0YVJpZ2h0IDogTlVMTCwKICAgICAgICAgICAgICAgICAgIChzdGVyZW8pID8gJnBTYnJDaGFubmVsWzFdLT5wcmV2RnJhbWVEYXRhIDogTlVMTCk7CgoKICAgIC8qIE5vdyB3ZSBoYXZlIGEgZnVsbCBwYXJhbWV0ZXIgc2V0IGFuZCBjYW4gZG8gcGFyYW1ldGVyCiAgICAgICBiYXNlZCBjb25jZWFsbWVudCBpbnN0ZWFkIG9mIHBsYWluIHVwc2FtcGxpbmcuICovCiAgICBoU2JySGVhZGVyLT5zeW5jU3RhdGUgPSBTQlJfQUNUSVZFOwogIH0KCiAgLyogZGVjb2RlIFBTIGRhdGEgaWYgYXZhaWxhYmxlICovCiAgaWYgKGhfcHNfZCAhPSBOVUxMICYmIHBzUG9zc2libGUpIHsKICAgIGludCBhcHBseVBzID0gMTsKCiAgICAvKiBkZWZpbmUgd2hpY2ggZnJhbWUgZGVsYXkgbGluZSBzbG90IHRvIHByb2Nlc3MgKi8KICAgIGhfcHNfZC0+cHJvY2Vzc1Nsb3QgPSBoU2JyRWxlbWVudC0+dXNlRnJhbWVTbG90OwoKICAgIGFwcGx5UHMgPSBEZWNvZGVQcyhoX3BzX2QsIGhTYnJIZWFkZXItPmZyYW1lRXJyb3JGbGFnKTsKICAgIHNlbGYtPmZsYWdzIHw9IChhcHBseVBzKSA/IFNCUkRFQ19QU19ERUNPREVEIDogMDsKICB9CgogIC8qIFNldCBzdHJpZGVzIGZvciByZWFkaW5nIGFuZCB3cml0aW5nICovCiAgaWYgKGludGVybGVhdmVkKSB7CiAgICBzdHJpZGVJbiA9IG51bUluQ2hhbm5lbHM7CiAgICBpZiAoIHBzUG9zc2libGUgKQogICAgICBzdHJpZGVPdXQgPSAobnVtSW5DaGFubmVscyA8IDIpID8gMiA6IG51bUluQ2hhbm5lbHM7CiAgICBlbHNlCiAgICAgIHN0cmlkZU91dCA9IG51bUluQ2hhbm5lbHM7CiAgICBvZmZzZXQwID0gY2hhbm5lbE1hcHBpbmdbMF07CiAgICBvZmZzZXQxID0gY2hhbm5lbE1hcHBpbmdbMV07CiAgfSBlbHNlIHsKICAgIHN0cmlkZUluICA9IDE7CiAgICBzdHJpZGVPdXQgPSAxOwogICAgb2Zmc2V0MCA9IGNoYW5uZWxNYXBwaW5nWzBdKjIqY29kZWNGcmFtZVNpemU7CiAgICBvZmZzZXQxID0gY2hhbm5lbE1hcHBpbmdbMV0qMipjb2RlY0ZyYW1lU2l6ZTsKICB9CgogIC8qIHVzZSBzYW1lIGJ1ZmZlcnMgZm9yIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWwgYW5kIGFwcGx5IFBTIHBlciB0aW1lc2xvdCAqLwogIC8qIFByb2Nlc3MgbGVmdCBjaGFubmVsICovCi8vRkRLcHJpbnRmKCJzZWxmLT5jb2RlY0ZyYW1lU2l6ZSAlZFx0JWRcbiIsc2VsZi0+Y29kZWNGcmFtZVNpemUsc2VsZi0+c2FtcGxlUmF0ZUluKTsKICBzYnJfZGVjICgmcFNickNoYW5uZWxbMF0tPlNickRlYywKICAgICAgICAgICAgdGltZURhdGEgKyBvZmZzZXQwLAogICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDAsCiAgICAgICAgICAgJnBTYnJDaGFubmVsWzFdLT5TYnJEZWMsCiAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MSwKICAgICAgICAgICAgc3RyaWRlSW4sCiAgICAgICAgICAgIHN0cmlkZU91dCwKICAgICAgICAgICAgaFNickhlYWRlciwKICAgICAgICAgICAgaEZyYW1lRGF0YUxlZnQsCiAgICAgICAgICAgJnBTYnJDaGFubmVsWzBdLT5wcmV2RnJhbWVEYXRhLAogICAgICAgICAgICAoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9BQ1RJVkUpLAogICAgICAgICAgICBoX3BzX2QsCiAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICApOwoKICBpZiAoc3RlcmVvKSB7CiAgICAvKiBQcm9jZXNzIHJpZ2h0IGNoYW5uZWwgKi8KICAgIHNicl9kZWMgKCZwU2JyQ2hhbm5lbFsxXS0+U2JyRGVjLAogICAgICAgICAgICAgIHRpbWVEYXRhICsgb2Zmc2V0MSwKICAgICAgICAgICAgICB0aW1lRGF0YSArIG9mZnNldDEsCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgIHN0cmlkZUluLAogICAgICAgICAgICAgIHN0cmlkZU91dCwKICAgICAgICAgICAgICBoU2JySGVhZGVyLAogICAgICAgICAgICAgIGhGcmFtZURhdGFSaWdodCwKICAgICAgICAgICAgICZwU2JyQ2hhbm5lbFsxXS0+cHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgICAoaFNickhlYWRlci0+c3luY1N0YXRlID09IFNCUl9BQ1RJVkUpLAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICAgKTsKICB9CgogIGlmIChoX3BzX2QgIT0gTlVMTCkgewogICAgLyogc2F2ZSBQUyBzdGF0dXMgZm9yIG5leHQgcnVuICovCiAgICBoX3BzX2QtPnBzRGVjb2RlZFBydiA9IChzZWxmLT5mbGFncyAmIFNCUkRFQ19QU19ERUNPREVEKSA/IDEgOiAwIDsKICB9CgogIGlmICggcHNQb3NzaWJsZSAKICAgICkKICB7CiAgICBGREtfQVNTRVJUKHN0cmlkZU91dCA+IDEpOwogICAgaWYgKCAhKHNlbGYtPmZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpICkgewogICAgICAvKiBBIGRlY29kZXIgd2hpY2ggaXMgYWJsZSB0byBkZWNvZGUgUFMgaGFzIHRvIHByb2R1Y2UgYSBzdGVyZW8gb3V0cHV0IGV2ZW4gaWYgbm8gUFMgZGF0YSBpcyBhdmFpbGJsZS4gKi8KICAgICAgLyogU28gY29weSBsZWZ0IGNoYW5uZWwgdG8gcmlnaHQgY2hhbm5lbC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgIGlmIChpbnRlcmxlYXZlZCkgewogICAgICAgIElOVF9QQ00gKnB0cjsKICAgICAgICBJTlQgaTsKICAgICAgICBGREtfQVNTRVJUKHN0cmlkZU91dCA9PSAyKTsKCiAgICAgICAgcHRyID0gdGltZURhdGE7CiAgICAgICAgZm9yIChpID0gY29kZWNGcmFtZVNpemU7IGktLTsgKSAKICAgICAgICB7CiAgICAgICAgICBJTlRfUENNIHRtcDsgLyogVGhpcyB0ZW1wb3JhbCB2YXJpYWJsZSBpcyByZXF1aXJlZCBiZWNhdXNlIHNvbWUgY29tcGlsZXJzIGNhbid0IGRvICpwdHIrKyA9ICpwdHIrKyBjb3JyZWN0bHkuICovCiAgICAgICAgICB0bXAgPSAqcHRyKys7ICpwdHIrKyA9IHRtcDsKICAgICAgICAgIHRtcCA9ICpwdHIrKzsgKnB0cisrID0gdG1wOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBGREttZW1jcHkoIHRpbWVEYXRhKzIqY29kZWNGcmFtZVNpemUsIHRpbWVEYXRhLCAyKmNvZGVjRnJhbWVTaXplKnNpemVvZihJTlRfUENNKSApOwogICAgICB9CiAgICB9CiAgICAqbnVtT3V0Q2hhbm5lbHMgPSAyOyAgLyogT3V0cHV0IG1pbmltdW0gdHdvIGNoYW5uZWxzIHdoZW4gUFMgaXMgZW5hYmxlZC4gKi8KICB9CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX0FwcGx5ICggSEFORExFX1NCUkRFQ09ERVIgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00gICAgICAgICAgICAqdGltZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICpudW1DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgKnNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNIQVIgICAgICAgICBjaGFubmVsTWFwcGluZ1soOCldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ICAgICAgICAgICBjb3JlRGVjb2RlZE9rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICAqcHNEZWNvZGVkICkKewogIFNCUl9FUlJPUiBlcnJvclN0YXR1cyA9IFNCUkRFQ19PSzsKCiAgaW50ICAgcHNQb3NzaWJsZSA9IDA7CiAgaW50ICAgc2JyRWxlbWVudE51bTsKICBpbnQgICBudW1Db3JlQ2hhbm5lbHMgPSAqbnVtQ2hhbm5lbHM7CiAgaW50ICAgbnVtU2JyQ2hhbm5lbHMgID0gMDsKCiAgcHNQb3NzaWJsZSA9ICpwc0RlY29kZWQ7CgogIGlmIChzZWxmLT5udW1TYnJFbGVtZW50cyA8IDEpIHsKICAgIC8qIGV4aXQgaW1tZWRpYXRlbHkgdG8gYXZvaWQgYWNjZXNzIHZpb2xhdGlvbnMgKi8KICAgIHJldHVybiBTQlJERUNfQ1JFQVRFX0VSUk9SOwogIH0KCiAgLyogU2FuaXR5IGNoZWNrIG9mIGFsbG9jYXRlZCBTQlIgZWxlbWVudHMuICovCiAgZm9yIChzYnJFbGVtZW50TnVtPTA7IHNickVsZW1lbnROdW08c2VsZi0+bnVtU2JyRWxlbWVudHM7IHNickVsZW1lbnROdW0rKykgewogICAgaWYgKHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dID09IE5VTEwpIHsKICAgICAgcmV0dXJuIFNCUkRFQ19DUkVBVEVfRVJST1I7CiAgICB9CiAgfQoKICBpZiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgIT0gMSB8fCBzZWxmLT5wU2JyRWxlbWVudFswXS0+ZWxlbWVudElEICE9IElEX1NDRSkgewogICAgcHNQb3NzaWJsZSA9IDA7CiAgfQoKCiAgLyogSW4gY2FzZSBvZiBub24taW50ZXJsZWF2ZWQgdGltZSBkb21haW4gZGF0YSBhbmQgdXBzYW1wbGluZywgbWFrZSByb29tIGZvciBiaWdnZXIgU0JSIG91dHB1dC4gKi8KICBpZiAoc2VsZi0+c3luRG93bnNhbXBsZUZhYyA9PSAxICYmIGludGVybGVhdmVkID09IDApIHsKICAgIGludCBjLCBvdXRwdXRGcmFtZVNpemU7CgogICAgb3V0cHV0RnJhbWVTaXplID0KICAgICAgICAgICAgc2VsZi0+cFNickVsZW1lbnRbMF0tPnBTYnJDaGFubmVsWzBdLT5TYnJEZWMuU3ludGhlc2lzUU1GLm5vX2NoYW5uZWxzCiAgICAgICAgICAgICogc2VsZi0+cFNickVsZW1lbnRbMF0tPnBTYnJDaGFubmVsWzBdLT5TYnJEZWMuU3ludGhlc2lzUU1GLm5vX2NvbDsKCiAgICBmb3IgKGM9bnVtQ29yZUNoYW5uZWxzLTE7IGM+MDsgYy0tKSB7CiAgICAgIEZES21lbW1vdmUodGltZURhdGEgKyBjKm91dHB1dEZyYW1lU2l6ZSwgdGltZURhdGEgKyBjKnNlbGYtPmNvZGVjRnJhbWVTaXplICwgc2VsZi0+Y29kZWNGcmFtZVNpemUqc2l6ZW9mKElOVF9QQ00pKTsKICAgIH0KICB9CgoKICAvKiBNYWtlIHN1cmUgdGhhdCBldmVuIGlmIG5vIFNCUiBkYXRhIHdhcyBmb3VuZC9wYXJzZWQgKnBzRGVjb2RlZCBpcyByZXR1cm5lZCAxIGlmIHBzUG9zc2libGUgd2FzIDAuICovCiAgaWYgKHBzUG9zc2libGUgPT0gMCkgewogICAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19QU19ERUNPREVEOwogIH0KCiAgLyogTG9vcCBvdmVyIFNCUiBlbGVtZW50cyAqLwogIGZvciAoc2JyRWxlbWVudE51bSA9IDA7IHNickVsZW1lbnROdW08c2VsZi0+bnVtU2JyRWxlbWVudHM7IHNickVsZW1lbnROdW0rKykKICB7CiAgICBpbnQgbnVtRWxlbWVudENoYW47CgogICAgaWYgKHBzUG9zc2libGUgJiYgc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0tPnBTYnJDaGFubmVsWzFdID09IE5VTEwpIHsKICAgICAgZXJyb3JTdGF0dXMgPSBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgbnVtRWxlbWVudENoYW4gPSAoc2VsZi0+cFNickVsZW1lbnRbc2JyRWxlbWVudE51bV0tPmVsZW1lbnRJRCA9PSBJRF9DUEUpID8gMiA6IDE7CgogICAgLyogSWYgY29yZSBzaWduYWwgaXMgYmFkIHRoZW4gZm9yY2UgdXBzYW1wbGluZyAqLwogICAgaWYgKCAhIGNvcmVEZWNvZGVkT2sgKSB7CiAgICAgIHNlbGYtPnBTYnJFbGVtZW50W3NickVsZW1lbnROdW1dLT5mcmFtZUVycm9yRmxhZ1tzZWxmLT5wU2JyRWxlbWVudFtzYnJFbGVtZW50TnVtXS0+dXNlRnJhbWVTbG90XSA9IDE7CiAgICB9CgogICAgZXJyb3JTdGF0dXMgPSBzYnJEZWNvZGVyX0RlY29kZUVsZW1lbnQgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnJFbGVtZW50TnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1Db3JlQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bUVsZW1lbnRDaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc1Bvc3NpYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgIGlmIChlcnJvclN0YXR1cyAhPSBTQlJERUNfT0spIHsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIG51bVNickNoYW5uZWxzICs9IG51bUVsZW1lbnRDaGFuOwogICAgY2hhbm5lbE1hcHBpbmcgKz0gbnVtRWxlbWVudENoYW47CgogICAgaWYgKG51bVNickNoYW5uZWxzID49IG51bUNvcmVDaGFubmVscykgewogICAgICBicmVhazsKICAgIH0KICB9CgogIC8qIFVwZGF0ZSBudW1DaGFubmVscyBhbmQgc2FtcGxlcmF0ZSAqLwogICpudW1DaGFubmVscyA9IG51bVNickNoYW5uZWxzOwogICpzYW1wbGVSYXRlID0gc2VsZi0+c2FtcGxlUmF0ZU91dDsKICAqcHNEZWNvZGVkID0gKHNlbGYtPmZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpID8gMSA6IDA7CgoKCiAgLyogQ2xlYXIgcmVzZXQgYW5kIGZsdXNoIGZsYWcgYmVjYXVzZSBldmVyeXRoaW5nIHNlZW1zIHRvIGJlIGRvbmUgc3VjY2Vzc2Z1bGx5LiAqLwogIHNlbGYtPmZsYWdzICY9IH5TQlJERUNfRk9SQ0VfUkVTRVQ7CiAgc2VsZi0+ZmxhZ3MgJj0gflNCUkRFQ19GTFVTSDsKCmJhaWw6CgogIHJldHVybiBlcnJvclN0YXR1czsKfQoKClNCUl9FUlJPUiBzYnJEZWNvZGVyX0Nsb3NlICggSEFORExFX1NCUkRFQ09ERVIgKnBTZWxmICkKewogIEhBTkRMRV9TQlJERUNPREVSIHNlbGYgPSAqcFNlbGY7CiAgaW50IGk7CgogIGlmIChzZWxmICE9IE5VTEwpCiAgewogICAgaWYgKHNlbGYtPmhQYXJhbWV0cmljU3RlcmVvRGVjICE9IE5VTEwpIHsKICAgICAgRGVsZXRlUHNEZWMgKCAmc2VsZi0+aFBhcmFtZXRyaWNTdGVyZW9EZWMgKTsKICAgIH0KCiAgICBpZiAoc2VsZi0+d29ya0J1ZmZlcjEgIT0gTlVMTCkgewogICAgICBGcmVlUmFtX1NickRlY1dvcmtCdWZmZXIxKCZzZWxmLT53b3JrQnVmZmVyMSk7CiAgICB9CiAgICBpZiAoc2VsZi0+d29ya0J1ZmZlcjIgIT0gTlVMTCkgewogICAgICBGcmVlUmFtX1NickRlY1dvcmtCdWZmZXIyKCZzZWxmLT53b3JrQnVmZmVyMik7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8ICg4KTsgaSsrKSB7CiAgICAgIHNickRlY29kZXJfRGVzdHJveUVsZW1lbnQoIHNlbGYsIGkgKTsKICAgIH0KCiAgICBGcmVlUmFtX1NickRlY29kZXIocFNlbGYpOwogIH0KCiAgcmV0dXJuIFNCUkRFQ19PSzsKfQoKCklOVCBzYnJEZWNvZGVyX0dldExpYkluZm8oIExJQl9JTkZPICppbmZvICkKewogIGludCBpOwoKICBpZiAoaW5mbyA9PSBOVUxMKSB7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBzZWFyY2ggZm9yIG5leHQgZnJlZSB0YWIgKi8KICBmb3IgKGkgPSAwOyBpIDwgRkRLX01PRFVMRV9MQVNUOyBpKyspIHsKICAgIGlmIChpbmZvW2ldLm1vZHVsZV9pZCA9PSBGREtfTk9ORSkKICAgICAgYnJlYWs7CiAgfQogIGlmIChpID09IEZES19NT0RVTEVfTEFTVCkKICAgIHJldHVybiAtMTsKICBpbmZvICs9IGk7CgogIGluZm8tPm1vZHVsZV9pZCA9IEZES19TQlJERUM7CiAgaW5mby0+dmVyc2lvbiA9IExJQl9WRVJTSU9OKFNCUkRFQ09ERVJfTElCX1ZMMCwgU0JSREVDT0RFUl9MSUJfVkwxLCBTQlJERUNPREVSX0xJQl9WTDIpOwogIExJQl9WRVJTSU9OX1NUUklORyhpbmZvKTsKICBpbmZvLT5idWlsZF9kYXRlID0gKGNoYXIgKilTQlJERUNPREVSX0xJQl9CVUlMRF9EQVRFOwogIGluZm8tPmJ1aWxkX3RpbWUgPSAoY2hhciAqKVNCUkRFQ09ERVJfTElCX0JVSUxEX1RJTUU7CiAgaW5mby0+dGl0bGUgICAgICA9IChjaGFyICopU0JSREVDT0RFUl9MSUJfVElUTEU7CgogIC8qIFNldCBmbGFncyAqLwogIGluZm8tPmZsYWdzID0gMAogICAgfCBDQVBGX1NCUl9IUQogICAgfCBDQVBGX1NCUl9MUAogICAgfCBDQVBGX1NCUl9QU19NUEVHCiAgICB8IENBUEZfU0JSX0NPTkNFQUxNRU5UCiAgICB8IENBUEZfU0JSX0RSQwogICAgICA7CiAgLyogRW5kIG9mIGZsYWdzICovCgogIHJldHVybiAwOwp9CgoKVUlOVCBzYnJEZWNvZGVyX0dldERlbGF5KCBjb25zdCBIQU5ETEVfU0JSREVDT0RFUiBzZWxmICkKewogIFVJTlQgb3V0cHV0RGVsYXkgPSAwOwoKICBpZiAoIHNlbGYgIT0gTlVMTCkgewogICAgVUlOVCBmbGFncyA9IHNlbGYtPmZsYWdzOwoKICAgIC8qIFNlZSBjaGFwdGVyIDEuNi43LjIgb2YgSVNPL0lFQyAxNDQ5Ni0zIGZvciB0aGUgR0EtU0JSIGZpZ3VyZXMgYmVsb3cuICovCgogICAgLyogQXJlIHdlIGluaXRpYWxpemVkPyAqLwogICAgaWYgKCAoc2VsZi0+bnVtU2JyQ2hhbm5lbHMgPiAwKQogICAgICAmJiAoc2VsZi0+bnVtU2JyRWxlbWVudHMgPiAwKSApCiAgICB7CiAgICAgIC8qIEFkZCBRTUYgc3ludGhlc2lzIGRlbGF5ICovCiAgICAgIGlmICggKGZsYWdzICYgU0JSREVDX0VMRF9HUklEKQogICAgICAgICYmIElTX0xPV0RFTEFZKHNlbGYtPmNvcmVDb2RlYykgKSB7CiAgICAgICAgLyogTG93IGRlbGF5IFNCUjogKi8KICAgICAgICB7CiAgICAgICAgICBvdXRwdXREZWxheSArPSAoZmxhZ3MgJiBTQlJERUNfRE9XTlNBTVBMRSkgPyAzMiA6IDY0OyAgIC8qIFFNRiBzeW50aGVzaXMgKi8KICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSBpZiAoIUlTX1VTQUMoc2VsZi0+Y29yZUNvZGVjKSkgewogICAgICAgIC8qIEJ5IHRoZSBtZXRob2Qgb2YgZWxpbWluYXRpb24gdGhpcyBpcyB0aGUgR0EgKEFBQy1MQywgSEUtQUFDLCAuLi4pIGJyYW5jaDogKi8KICAgICAgICBvdXRwdXREZWxheSArPSAoZmxhZ3MgJiBTQlJERUNfRE9XTlNBTVBMRSkgPyA0ODEgOiA5NjI7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiAob3V0cHV0RGVsYXkpOwp9Cg==