Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUcgQXVkaW8gRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIEF1dGhvcnM6ICAgICAgTS4gTmV1ZW5kb3JmLCBOLiBSZXR0ZWxiYWNoLCBNLiBNdWx0cnVzCiAgIENvbnRlbnRzL0Rlc2NyaXB0aW9uOiBQUyBwYXJhbWV0ZXIgZXh0cmFjdGlvbiwgZW5jb2RpbmcKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGZpbGUKICBcYnJpZWYgIFBTIHBhcmFtZXRlciBleHRyYWN0aW9uLCBlbmNvZGluZyBmdW5jdGlvbnMgIAoqLwoKI2luY2x1ZGUgInBzX21haW4uaCIKCgojaW5jbHVkZSAic2JyX3JhbS5oIgojaW5jbHVkZSAicHNfZW5jb2RlLmgiCgojaW5jbHVkZSAicW1mLmgiCgojaW5jbHVkZSAicHNfY29uc3QuaCIKI2luY2x1ZGUgInNicl9taXNjLmgiCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCmlubGluZSB2b2lkIEZES3NickVuY19hZGRGSVhQX0RCTChjb25zdCBGSVhQX0RCTCAqWCwgY29uc3QgRklYUF9EQkwgKlksIEZJWFBfREJMICpaLCBJTlQgbikKewogIGZvciAoSU5UIGk9MDsgaTxuOyBpKyspCiAgICBaW2ldID0gKFhbaV0+PjEpICsgKFlbaV0+PjEpOwp9CgojZGVmaW5lIExPRzEwXzJfMTAgICAgICAgICAgICAgMy4wMTAyOTk5NTY2NGYgLyogMTAuMGYqbG9nMTAoMi5mKSAqLwoKc3RhdGljIGNvbnN0IElOVCBpaWRHcm91cEJvcmRlcnNMb1Jlc1tRTUZfR1JPVVBTX0xPX1JFUyArIFNVQlFNRl9HUk9VUFNfTE9fUkVTICsgMV0gPQp7CiAgMCwgMSwgMiwgMywgNCwgNSwgICAgLyogNiBzdWJxbWYgc3ViYmFuZHMgLSAwdGggcW1mIHN1YmJhbmQgKi8KICA2LCA3LCAgICAgICAgICAgICAgICAvKiAyIHN1YnFtZiBzdWJiYW5kcyAtIDFzdCBxbWYgc3ViYmFuZCAqLwogIDgsIDksICAgICAgICAgICAgICAgIC8qIDIgc3VicW1mIHN1YmJhbmRzIC0gMm5kIHFtZiBzdWJiYW5kICovCiAgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTYsIDE4LCAyMSwgMjUsIDMwLCA0MiwgNzEKfTsKCnN0YXRpYyBjb25zdCBVQ0hBUiBpaWRHcm91cFdpZHRoTGRMb1Jlc1tRTUZfR1JPVVBTX0xPX1JFUyArIFNVQlFNRl9HUk9VUFNfTE9fUkVTXSA9CnsKICAwLCAwLCAwLCAwLCAwLCAwLAogIDAsIDAsCiAgMCwgMCwKICAwLCAwLCAwLCAwLCAwLCAwLCAxLCAyLCAyLCAzLCA0LCA1Cn07CgoKc3RhdGljIGNvbnN0IElOVCBzdWJiYW5kMnBhcmFtZXRlcjIwW1FNRl9HUk9VUFNfTE9fUkVTICsgU1VCUU1GX0dST1VQU19MT19SRVNdID0KewogIDEsIDAsIDAsIDEsIDIsIDMsICAgLyogNiBzdWJxbWYgc3ViYmFuZHMgLSAwdGggcW1mIHN1YmJhbmQgKi8KICA0LCA1LCAgICAgICAgICAgICAgIC8qIDIgc3VicW1mIHN1YmJhbmRzIC0gMXN0IHFtZiBzdWJiYW5kICovCiAgNiwgNywgICAgICAgICAgICAgICAvKiAyIHN1YnFtZiBzdWJiYW5kcyAtIDJuZCBxbWYgc3ViYmFuZCAqLwogIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywgMTgsIDE5Cn07CgoKdHlwZWRlZiBlbnVtIHsKICBNQVhfVElNRV9ESUZGX0ZSQU1FUyA9IDIwLAogIE1BWF9QU19OT0hFQURFUl9DTlQgID0gMTAsCiAgTUFYX05PRU5WX0NOVCAgICAgICAgPSAxMCwKICBET19OT1RfVVNFX1RISVNfTU9ERSA9IDB4N0ZGRkZGCn0gX19QU19DT05TVEFOVFM7CgoKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBpaWRRdWFudF9meFsxNV0gPSB7CiAgMHhjZTAwMDAwMCwgMHhkYzAwMDAwMCwgMHhlNDAwMDAwMCwgMHhlYzAwMDAwMCwgMHhmMjAwMDAwMCwgMHhmODAwMDAwMCwgMHhmYzAwMDAwMCwgMHgwMDAwMDAwMCwKICAweDA0MDAwMDAwLCAweDA4MDAwMDAwLCAweDBlMDAwMDAwLCAweDE0MDAwMDAwLCAweDFjMDAwMDAwLCAweDI0MDAwMDAwLCAweDMyMDAwMDAwCn07CgpzdGF0aWMgY29uc3QgRklYUF9EQkwgaWlkUXVhbnRGaW5lX2Z4WzMxXSA9IHsKICAweDljMDAwMDAxLCAweGE2MDAwMDAxLCAweGIwMDAwMDAxLCAweGJhMDAwMDAxLCAweGM0MDAwMDAwLCAweGNlMDAwMDAwLCAweGQ0MDAwMDAwLCAweGRhMDAwMDAwLAogIDB4ZTAwMDAwMDAsIDB4ZTYwMDAwMDAsIDB4ZWMwMDAwMDAsIDB4ZjAwMDAwMDAsIDB4ZjQwMDAwMDAsIDB4ZjgwMDAwMDAsIDB4ZmMwMDAwMDAsIDB4MDAwMDAwMDAsCiAgMHgwNDAwMDAwMCwgMHgwODAwMDAwMCwgMHgwYzAwMDAwMCwgMHgxMDAwMDAwMCwgMHgxNDAwMDAwMCwgMHgxYTAwMDAwMCwgMHgyMDAwMDAwMCwgMHgyNjAwMDAwMCwKICAweDJjMDAwMDAwLCAweDMyMDAwMDAwLCAweDNjMDAwMDAwLCAweDQ1ZmZmZmZmLCAweDRmZmZmZmZmLCAweDU5ZmZmZmZmLCAweDYzZmZmZmZmCn07CgoKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBpY2NRdWFudFs4XSA9IHsKICAweDdmZmZmZmZmLCAweDc3ZWY5ZDdmLCAweDZiYWJjOTdmLCAweDRjZWFmMjdmLCAweDJmMGVkM2MwLCAweDAwMDAwMDAwLCAweGI0OWJhNjAxLCAweDgwMDAwMDAwCn07CgpzdGF0aWMgRkRLX1BTRU5DX0VSUk9SIEluaXRQU0RhdGEoCiAgICAgICAgSEFORExFX1BTX0RBVEEgICAgICAgICAgICBoUHNEYXRhCiAgICAgICAgKQp7CiAgRkRLX1BTRU5DX0VSUk9SIGVycm9yID0gUFNFTkNfT0s7CgogIGlmKGhQc0RhdGEgPT0gTlVMTCkgewogICAgZXJyb3IgPSBQU0VOQ19JTlZBTElEX0hBTkRMRTsKICB9CiAgZWxzZSB7CiAgICBpbnQgaSwgZW52OwogICAgRkRLbWVtY2xlYXIoaFBzRGF0YSxzaXplb2YoUFNfREFUQSkpOwoKICAgIGZvciAoaT0wOyBpPFBTX01BWF9CQU5EUzsgaSsrKSB7CiAgICAgIGhQc0RhdGEtPmlpZElkeExhc3RbaV0gPSAwOwogICAgICBoUHNEYXRhLT5pY2NJZHhMYXN0W2ldID0gMDsKICAgIH0KCiAgICBoUHNEYXRhLT5paWRFbmFibGUgICAgPSBoUHNEYXRhLT5paWRFbmFibGVMYXN0ID0gMDsKICAgIGhQc0RhdGEtPmljY0VuYWJsZSAgICA9IGhQc0RhdGEtPmljY0VuYWJsZUxhc3QgPSAwOwogICAgaFBzRGF0YS0+aWlkUXVhbnRNb2RlID0gaFBzRGF0YS0+aWlkUXVhbnRNb2RlTGFzdCA9IFBTX0lJRF9SRVNfQ09BUlNFOwogICAgaFBzRGF0YS0+aWNjUXVhbnRNb2RlID0gaFBzRGF0YS0+aWNjUXVhbnRNb2RlTGFzdCA9IFBTX0lDQ19ST1RfQTsKCiAgICBmb3IoZW52PTA7IGVudjxQU19NQVhfRU5WRUxPUEVTOyBlbnYrKykgewogICAgICBoUHNEYXRhLT5pY2NEaWZmTW9kZVtlbnZdID0gUFNfREVMVEFfRlJFUTsKICAgICAgaFBzRGF0YS0+aWNjRGlmZk1vZGVbZW52XSA9IFBTX0RFTFRBX0ZSRVE7CgogICAgICBmb3IgKGk9MDsgaTxQU19NQVhfQkFORFM7IGkrKykgewogICAgICAgIGhQc0RhdGEtPmlpZElkeFtlbnZdW2ldID0gMDsKICAgICAgICBoUHNEYXRhLT5pY2NJZHhbZW52XVtpXSA9IDA7CiAgICAgIH0KICAgIH0KCiAgICBoUHNEYXRhLT5uRW52ZWxvcGVzTGFzdCA9IDA7CgogICAgaFBzRGF0YS0+aGVhZGVyQ250ICA9IE1BWF9QU19OT0hFQURFUl9DTlQ7CiAgICBoUHNEYXRhLT5paWRUaW1lQ250ID0gTUFYX1RJTUVfRElGRl9GUkFNRVM7CiAgICBoUHNEYXRhLT5pY2NUaW1lQ250ID0gTUFYX1RJTUVfRElGRl9GUkFNRVM7CiAgICBoUHNEYXRhLT5ub0VudkNudCAgID0gTUFYX05PRU5WX0NOVDsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKc3RhdGljIEZJWFBfREJMIHF1YW50aXplQ29lZiggY29uc3QgRklYUF9EQkwgKlJFU1RSSUNUIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgbkJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGSVhQX0RCTCAqUkVTVFJJQ1QgcXVhbnRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgIGlkeE9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgIG5RdWFudFN0ZXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAqUkVTVFJJQ1QgcXVhbnRPdXQpCnsKICBJTlQgaWR4LCBiYW5kOwogIEZJWFBfREJMIHF1YW50RXJyID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKCiAgZm9yIChiYW5kPTA7IGJhbmQ8bkJhbmRzO2JhbmQrKykgewogICAgZm9yKGlkeD0wOyBpZHg8blF1YW50U3RlcHMtMTsgaWR4KyspewogICAgICBpZiggZml4cF9hYnMoKGlucHV0W2JhbmRdPj4xKS0ocXVhbnRUYWJsZVtpZHgrMV0+PjEpKSA+CiAgICAgICAgICBmaXhwX2FicygoaW5wdXRbYmFuZF0+PjEpLShxdWFudFRhYmxlW2lkeF0+PjEpKSApCiAgICAgIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcXVhbnRFcnIgICAgICArPSAoZml4cF9hYnMoaW5wdXRbYmFuZF0tcXVhbnRUYWJsZVtpZHhdKT4+UFNfUVVBTlRfU0NBTEUpOyAgIC8qIGRvbid0IHNjYWxlIGJlZm9yZSBzdWJ0cmFjdGlvbjsgZGlmZiBzbWFsbGVyICg2NC0yNSkvNjQgKi8KICAgIHF1YW50T3V0W2JhbmRdID0gaWR4IC0gaWR4T2Zmc2V0OwogIH0KCiAgcmV0dXJuIHF1YW50RXJyOwp9CgpzdGF0aWMgSU5UIGdldElDQ01vZGUoY29uc3QgSU5UIG5CYW5kcywKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCByb3RUeXBlKQp7CiAgSU5UIG1vZGUgPSAwOwoKICBzd2l0Y2gobkJhbmRzKSB7CiAgY2FzZSBQU19CQU5EU19DT0FSU0U6CiAgICBtb2RlID0gUFNfUkVTX0NPQVJTRTsKICAgIGJyZWFrOwogIGNhc2UgUFNfQkFORFNfTUlEOgogICAgbW9kZSA9IFBTX1JFU19NSUQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgbW9kZSA9IDA7CiAgfQogIGlmKHJvdFR5cGU9PVBTX0lDQ19ST1RfQil7CiAgICBtb2RlICs9IDM7CiAgfQoKICByZXR1cm4gbW9kZTsKfQoKCnN0YXRpYyBJTlQgZ2V0SUlETW9kZShjb25zdCBJTlQgbkJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UIGlpZFJlcykKewogIElOVCBtb2RlID0gMDsKCiAgc3dpdGNoKG5CYW5kcykgewogIGNhc2UgUFNfQkFORFNfQ09BUlNFOgogICAgbW9kZSA9IFBTX1JFU19DT0FSU0U7CiAgICBicmVhazsKICBjYXNlIFBTX0JBTkRTX01JRDoKICAgIG1vZGUgPSBQU19SRVNfTUlEOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIG1vZGUgPSAwOwogICAgYnJlYWs7CiAgfQoKICBpZihpaWRSZXMgPT0gUFNfSUlEX1JFU19GSU5FKXsKICAgIG1vZGUgKz0gMzsKICB9CgogIHJldHVybiBtb2RlOwp9CgoKc3RhdGljIElOVCBlbnZlbG9wZVJlZHVjaWJsZShGSVhQX0RCTCBpaWRbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCBpY2NbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcHNCYW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbkVudmVsb3BlcykKewogICNkZWZpbmUgVEhSRVNIX1NDQUxFICAgICA3CgogIElOVCByZWR1Y2libGUgPSAxOyAvKiB0cnVlICovCiAgSU5UIGUgPSAwLCBiID0gMDsKICBGSVhQX0RCTCBkSWlkID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKICBGSVhQX0RCTCBkSWNjID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKCiAgRklYUF9EQkwgaWlkRXJyVGhyZXNob2xkLCBpY2NFcnJUaHJlc2hvbGQ7CiAgRklYUF9EQkwgaWlkTWVhbkVycm9yLCBpY2NNZWFuRXJyb3I7CgogIC8qIHNxdWFyZSB2YWx1ZXMgdG8gcHJldmVudCBzcXJ0LAogICAgIG11bHRpcGx5IGJhbmRzIHRvIHByZXZlbnQgZGl2aXNpb247IGJhbmRzIHNoaWZ0ZWQgREZSQUNUX0JJVFMgaW5zdGVhZCAoREZSQUNUX0JJVFMtMSkgYmVjYXVzZSBmTXVsdERpdjIgdXNlZCovCiAgaWlkRXJyVGhyZXNob2xkID0gZk11bHREaXYyICggRkwyRlhDT05TVF9EQkwoNi41Zio2LjVmLyhJSURfU0NBTEVfRlQqSUlEX1NDQUxFX0ZUKSksIChGSVhQX0RCTCkocHNCYW5kczw8KChERlJBQ1RfQklUUyktVEhSRVNIX1NDQUxFKSkgKTsKICBpY2NFcnJUaHJlc2hvbGQgPSBmTXVsdERpdjIgKCBGTDJGWENPTlNUX0RCTCgwLjc1ZiowLjc1ZiksICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZJWFBfREJMKShwc0JhbmRzPDwoKERGUkFDVF9CSVRTKS1USFJFU0hfU0NBTEUpKSApOwoKICBpZiAobkVudmVsb3BlcyA8PSAxKSB7CiAgICByZWR1Y2libGUgPSAwOwogIH0gZWxzZSB7CgogICAgLyogbWVhbiBlcnJvciBjcml0ZXJpb24gKi8KICAgIGZvciAoZT0wOyAoZSA8IG5FbnZlbG9wZXMvMikgJiYgKHJlZHVjaWJsZSE9MCApIDsgZSsrKSB7CiAgICAgIGlpZE1lYW5FcnJvciA9IGljY01lYW5FcnJvciA9IEZMMkZYQ09OU1RfREJMKDAuZik7CiAgICAgIGZvcihiPTA7IGI8cHNCYW5kczsgYisrKSB7CiAgICAgICAgZElpZCA9IChpaWRbMiplXVtiXT4+MSkgLSAoaWlkWzIqZSsxXVtiXT4+MSk7ICAgLyogc2NhbGUgMSBiaXQ7IHNxdWFyZWQgLT4gMiBiaXQgKi8KICAgICAgICBkSWNjID0gKGljY1syKmVdW2JdPj4xKSAtIChpY2NbMiplKzFdW2JdPj4xKTsKICAgICAgICBpaWRNZWFuRXJyb3IgKz0gZlBvdzJEaXYyKGRJaWQpPj4oNS0xKTsgICAgLyogKyAoYmFuZHM9MjApIHNjYWxlID0gNSAqLwogICAgICAgIGljY01lYW5FcnJvciArPSBmUG93MkRpdjIoZEljYyk+Pig1LTEpOwogICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIC0tPiBzY2FsaW5nID0gNyBiaXQgPSBUSFJFU0hfU0NBTEUgISEgKi8KCiAgICAgIC8qIGluc3RlYWQgc3FydCB2YWx1ZXMgYXJlIHNxdWFyZWQhCiAgICAgICAgIGluc3RlYWQgb2YgZGl2aXNpb24sIG11bHRpcGx5IHRocmVzaG9sZCB3aXRoIHBzQmFuZHMKICAgICAgICAgc2NhbGluZyBuZWNlc3NhcnkhISAqLwoKICAgICAgLyogcXVpdCBhcyBzb29uIGFzIHRocmVzaG9sZCBpcyByZWFjaGVkICovCiAgICAgIGlmICggKGlpZE1lYW5FcnJvciA+IChpaWRFcnJUaHJlc2hvbGQpKSB8fAogICAgICAgICAgIChpY2NNZWFuRXJyb3IgPiAoaWNjRXJyVGhyZXNob2xkKSkgKSB7CiAgICAgICAgcmVkdWNpYmxlID0gMDsKICAgICAgfQogICAgfQogIH0gLyogbkVudmVsb3BlcyAhPSAxICovCgogIHJldHVybiByZWR1Y2libGU7Cn0KCgpzdGF0aWMgdm9pZCBwcm9jZXNzSWlkRGF0YShQU19EQVRBICAgICAgICpwc0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICAgIGlpZFtQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICBwc0JhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICBuRW52ZWxvcGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGSVhQX0RCTCBxdWFudEVycm9yVGhyZXNob2xkKQp7CiAgSU5UIGlpZElkeEZpbmUgIFtQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdOwogIElOVCBpaWRJZHhDb2Fyc2VbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXTsKCiAgRklYUF9EQkwgZXJySUlEID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKICBGSVhQX0RCTCBlcnJJSURGaW5lID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKICBJTlQgICBiaXRzSWlkRnJlcSA9IDA7CiAgSU5UICAgYml0c0lpZFRpbWUgPSAwOwogIElOVCAgIGJpdHNGaW5lVG90ID0gMDsKICBJTlQgICBiaXRzQ29hcnNlVG90ID0gMDsKICBJTlQgICBlcnJvciA9IDA7CiAgSU5UICAgZW52LCBiYW5kOwogIElOVCAgIGRpZmZNb2RlW1BTX01BWF9FTlZFTE9QRVNdLCBkaWZmTW9kZUZpbmVbUFNfTUFYX0VOVkVMT1BFU107CiAgSU5UIGxvdWRuRGlmZiA9IDA7CiAgSU5UIGlpZFRyYW5zbWl0ID0gMDsKCiAgYml0c0lpZEZyZXEgPSBiaXRzSWlkVGltZSA9IDA7CgogIC8qIFF1YW50aXplIElJRCBjb2VmZmljaWVudHMgKi8KICBmb3IoZW52PTA7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICBlcnJJSUQgICAgICs9IHF1YW50aXplQ29lZihpaWRbZW52XSwgcHNCYW5kcywgaWlkUXVhbnRfZngsICAgICAgNywgMTUsIGlpZElkeENvYXJzZVtlbnZdKTsKICAgIGVycklJREZpbmUgKz0gcXVhbnRpemVDb2VmKGlpZFtlbnZdLCBwc0JhbmRzLCBpaWRRdWFudEZpbmVfZngsIDE1LCAzMSwgaWlkSWR4RmluZVtlbnZdKTsKICB9CgogIC8qIG5vcm1hbGl6ZSBlcnJvciB0byBudW1iZXIgb2YgZW52ZWxvcGVzLCBwcyBiYW5kcwogICAgIGVycklJRCAvPSBwc0JhbmRzKm5FbnZlbG9wZXM7CiAgICAgZXJySUlERmluZSAvPSBwc0JhbmRzKm5FbnZlbG9wZXM7ICovCgoKICAvKiBDaGVjayBpZiBJSUQgY29lZmZpY2llbnRzIHNob3VsZCBiZSB1c2VkIGluIHRoaXMgZnJhbWUgKi8KICBwc0RhdGEtPmlpZEVuYWJsZSA9IDA7CiAgZm9yKGVudj0wO2VudjxuRW52ZWxvcGVzOyBlbnYrKykgewogICAgZm9yKGJhbmQ9MDtiYW5kPHBzQmFuZHM7YmFuZCsrKSB7CiAgICAgIGxvdWRuRGlmZiAgICs9IGZpeHBfYWJzKGlpZElkeENvYXJzZVtlbnZdW2JhbmRdKTsKICAgICAgaWlkVHJhbnNtaXQgKys7CiAgICB9CiAgfQoKICBpZihsb3VkbkRpZmYgPiBmTXVsdEkoRkwyRlhDT05TVF9EQkwoMC43ZiksaWlkVHJhbnNtaXQpKXsgICAgLyogMC43ZiBlbXBpcmljIHZhbHVlICovCiAgICBwc0RhdGEtPmlpZEVuYWJsZSA9IDE7CiAgfQoKICAvKiBpZiBpaWQgbm90IGFjdGl2ZSAtPiBSRVNFVCBkYXRhICovCiAgaWYocHNEYXRhLT5paWRFbmFibGU9PTApIHsKICAgIHBzRGF0YS0+aWlkVGltZUNudCA9IE1BWF9USU1FX0RJRkZfRlJBTUVTOwogICAgZm9yKGVudj0wO2VudjxuRW52ZWxvcGVzOyBlbnYrKykgewogICAgICBwc0RhdGEtPmlpZERpZmZNb2RlW2Vudl0gPSBQU19ERUxUQV9GUkVROwogICAgICBGREttZW1jbGVhcihwc0RhdGEtPmlpZElkeFtlbnZdLCBzaXplb2YoSU5UKSpwc0JhbmRzKTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8qIGNvdW50IENPQVJTRSBxdWFudGl6YXRpb24gYml0cyBmb3IgZmlyc3QgZW52ZWxvcGUqLwogIGJpdHNJaWRGcmVxID0gRkRLc2JyRW5jX0VuY29kZUlpZChOVUxMLCBpaWRJZHhDb2Fyc2VbMF0sIE5VTEwsIHBzQmFuZHMsIFBTX0lJRF9SRVNfQ09BUlNFLCBQU19ERUxUQV9GUkVRLCAmZXJyb3IpOwoKICBpZiggKHBzRGF0YS0+aWlkVGltZUNudD49TUFYX1RJTUVfRElGRl9GUkFNRVMpIHx8IChwc0RhdGEtPmlpZFF1YW50TW9kZUxhc3Q9PVBTX0lJRF9SRVNfRklORSkgKSB7CiAgICBiaXRzSWlkVGltZSAgICAgPSBET19OT1RfVVNFX1RISVNfTU9ERTsKICB9CiAgZWxzZSB7CiAgICBiaXRzSWlkVGltZSAgICAgPSBGREtzYnJFbmNfRW5jb2RlSWlkKE5VTEwsIGlpZElkeENvYXJzZVswXSwgcHNEYXRhLT5paWRJZHhMYXN0LCBwc0JhbmRzLCBQU19JSURfUkVTX0NPQVJTRSwgUFNfREVMVEFfVElNRSwgJmVycm9yKTsKICB9CgogIC8qIGRlY2lzaW9uIERFTFRBX0ZSRVEgdnMgREVMVEFfVElNRSAqLwogIGlmKGJpdHNJaWRUaW1lPmJpdHNJaWRGcmVxKSB7CiAgICBkaWZmTW9kZVswXSAgID0gUFNfREVMVEFfRlJFUTsKICAgIGJpdHNDb2Fyc2VUb3QgPSBiaXRzSWlkRnJlcTsKICB9CiAgZWxzZSB7CiAgICBkaWZmTW9kZVswXSAgID0gUFNfREVMVEFfVElNRTsKICAgIGJpdHNDb2Fyc2VUb3QgPSBiaXRzSWlkVGltZTsKICB9CgogIC8qIGNvdW50IENPQVJTRSBxdWFudGl6YXRpb24gYml0cyBmb3IgZm9sbG93aW5nIGVudmVsb3BlcyovCiAgZm9yKGVudj0xO2VudjxuRW52ZWxvcGVzOyBlbnYrKykgewogICAgYml0c0lpZEZyZXEgID0gRkRLc2JyRW5jX0VuY29kZUlpZChOVUxMLCBpaWRJZHhDb2Fyc2VbZW52XSwgTlVMTCwgICAgICAgICAgICAgICAgcHNCYW5kcywgUFNfSUlEX1JFU19DT0FSU0UsIFBTX0RFTFRBX0ZSRVEsICZlcnJvcik7CiAgICBiaXRzSWlkVGltZSAgPSBGREtzYnJFbmNfRW5jb2RlSWlkKE5VTEwsIGlpZElkeENvYXJzZVtlbnZdLCBpaWRJZHhDb2Fyc2VbZW52LTFdLCBwc0JhbmRzLCBQU19JSURfUkVTX0NPQVJTRSwgUFNfREVMVEFfVElNRSwgJmVycm9yKTsKCiAgICAvKiBkZWNpc2lvbiBERUxUQV9GUkVRIHZzIERFTFRBX1RJTUUgKi8KICAgIGlmKGJpdHNJaWRUaW1lPmJpdHNJaWRGcmVxKSB7CiAgICAgIGRpZmZNb2RlW2Vudl0gID0gUFNfREVMVEFfRlJFUTsKICAgICAgYml0c0NvYXJzZVRvdCArPSBiaXRzSWlkRnJlcTsKICAgIH0KICAgIGVsc2UgewogICAgICBkaWZmTW9kZVtlbnZdICA9IFBTX0RFTFRBX1RJTUU7CiAgICAgIGJpdHNDb2Fyc2VUb3QgKz0gYml0c0lpZFRpbWU7CiAgICB9CiAgfQoKCiAgLyogY291bnQgRklORSBxdWFudGl6YXRpb24gYml0cyBmb3IgZmlyc3QgZW52ZWxvcGUqLwogIGJpdHNJaWRGcmVxID0gRkRLc2JyRW5jX0VuY29kZUlpZChOVUxMLCBpaWRJZHhGaW5lWzBdLCAgIE5VTEwsIHBzQmFuZHMsIFBTX0lJRF9SRVNfRklORSwgICBQU19ERUxUQV9GUkVRLCAmZXJyb3IpOwoKICBpZiggKHBzRGF0YS0+aWlkVGltZUNudD49TUFYX1RJTUVfRElGRl9GUkFNRVMpIHx8IChwc0RhdGEtPmlpZFF1YW50TW9kZUxhc3Q9PVBTX0lJRF9SRVNfQ09BUlNFKSApIHsKICAgIGJpdHNJaWRUaW1lID0gRE9fTk9UX1VTRV9USElTX01PREU7CiAgfQogIGVsc2UgewogICAgYml0c0lpZFRpbWUgPSBGREtzYnJFbmNfRW5jb2RlSWlkKE5VTEwsIGlpZElkeEZpbmVbMF0sICBwc0RhdGEtPmlpZElkeExhc3QsIHBzQmFuZHMsIFBTX0lJRF9SRVNfRklORSwgUFNfREVMVEFfVElNRSwgJmVycm9yKTsKICB9CgogIC8qIGRlY2lzaW9uIERFTFRBX0ZSRVEgdnMgREVMVEFfVElNRSAqLwogIGlmKGJpdHNJaWRUaW1lPmJpdHNJaWRGcmVxKSB7CiAgICBkaWZmTW9kZUZpbmVbMF0gICA9IFBTX0RFTFRBX0ZSRVE7CiAgICBiaXRzRmluZVRvdCAgICAgICA9IGJpdHNJaWRGcmVxOwogIH0KICBlbHNlIHsKICAgIGRpZmZNb2RlRmluZVswXSAgID0gUFNfREVMVEFfVElNRTsKICAgIGJpdHNGaW5lVG90ICAgICAgID0gYml0c0lpZFRpbWU7CiAgfQoKICAvKiBjb3VudCBGSU5FIHF1YW50aXphdGlvbiBiaXRzIGZvciBmb2xsb3dpbmcgZW52ZWxvcGVzKi8KICBmb3IoZW52PTE7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICBiaXRzSWlkRnJlcSA9IEZES3NickVuY19FbmNvZGVJaWQoTlVMTCwgaWlkSWR4RmluZVtlbnZdLCAgIE5VTEwsICAgICAgICAgICAgICBwc0JhbmRzLCBQU19JSURfUkVTX0ZJTkUsIFBTX0RFTFRBX0ZSRVEsICZlcnJvcik7CiAgICBiaXRzSWlkVGltZSA9IEZES3NickVuY19FbmNvZGVJaWQoTlVMTCwgaWlkSWR4RmluZVtlbnZdLCAgIGlpZElkeEZpbmVbZW52LTFdLCBwc0JhbmRzLCBQU19JSURfUkVTX0ZJTkUsIFBTX0RFTFRBX1RJTUUsICZlcnJvcik7CgogICAgLyogZGVjaXNpb24gREVMVEFfRlJFUSB2cyBERUxUQV9USU1FICovCiAgICBpZihiaXRzSWlkVGltZT5iaXRzSWlkRnJlcSkgewogICAgICBkaWZmTW9kZUZpbmVbZW52XSAgPSBQU19ERUxUQV9GUkVROwogICAgICBiaXRzRmluZVRvdCArPSBiaXRzSWlkRnJlcTsKICAgIH0KICAgIGVsc2UgewogICAgICBkaWZmTW9kZUZpbmVbZW52XSAgPSBQU19ERUxUQV9USU1FOwogICAgICBiaXRzRmluZVRvdCAgICAgICArPSBiaXRzSWlkVGltZTsKICAgIH0KICB9CgogIGlmKGJpdHNGaW5lVG90ID09IGJpdHNDb2Fyc2VUb3QpewogICAgLyogaWYgc2FtZSBudW1iZXIgb2YgYml0cyBpcyBuZWVkZWQsIHVzZSB0aGUgcXVhbnRpemF0aW9uIHdpdGggbG93ZXIgZXJyb3IgKi8KICAgIGlmKGVycklJREZpbmUgPCBlcnJJSUQpewogICAgICBiaXRzQ29hcnNlVG90ID0gRE9fTk9UX1VTRV9USElTX01PREU7CiAgICB9IGVsc2UgewogICAgICBiaXRzRmluZVRvdCA9IERPX05PVF9VU0VfVEhJU19NT0RFOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiBjb25zdCBGSVhQX0RCTCBtaW5UaHJlc2hvbGQgPSBGTDJGWENPTlNUX0RCTCgwLjJmLyhJSURfU0NBTEVfRlQqUFNfUVVBTlRfU0NBTEVfRlQpKihwc0JhbmRzKm5FbnZlbG9wZXMpKTsgKi8KICAgIGNvbnN0IEZJWFBfREJMIG1pblRocmVzaG9sZCA9IChGSVhQX0RCTCkoKExPTkcpMHgwMDAxOTk5OSAqIChwc0JhbmRzKm5FbnZlbG9wZXMpKTsKCiAgICAvKiBkZWNpc2lvbiBSRVNfRklORSB2cyBSRVNfQ09BUlNFICAgICAgICAgICAgICAgICAqLwogICAgLyogdGVzdCBpZiBlcnJJSURGaW5lKnF1YW50RXJyb3JUaHJlc2hvbGQgPCBlcnJJSUQgKi8KICAgIC8qIHNoaWZ0VmFsIDIgY29tZXMgZnJvbSBzY2FsaW5nIG9mIHF1YW50RXJyb3JUaHJlc2hvbGQgKi8KICAgIGlmKGZpeE1heCgoKGVycklJREZpbmU+PjEpKyhtaW5UaHJlc2hvbGQ+PjEpKT4+MSwgZk11bHQocXVhbnRFcnJvclRocmVzaG9sZCxlcnJJSURGaW5lKSkgPCAoZXJySUlEPj4yKSApIHsKICAgICAgYml0c0NvYXJzZVRvdCA9IERPX05PVF9VU0VfVEhJU19NT0RFOwogICAgfQogICAgZWxzZSBpZihmaXhNYXgoKChlcnJJSUQ+PjEpKyhtaW5UaHJlc2hvbGQ+PjEpKT4+MSwgZk11bHQocXVhbnRFcnJvclRocmVzaG9sZCxlcnJJSUQpKSA8IChlcnJJSURGaW5lPj4yKSApIHsKICAgICAgYml0c0ZpbmVUb3QgPSBET19OT1RfVVNFX1RISVNfTU9ERTsKICAgIH0KICB9CgogIC8qIGRlY2lzaW9uIFJFU19GSU5FIHZzIFJFU19DT0FSU0UgKi8KICBpZihiaXRzRmluZVRvdDxiaXRzQ29hcnNlVG90KSB7CiAgICBwc0RhdGEtPmlpZFF1YW50TW9kZSA9IFBTX0lJRF9SRVNfRklORTsKICAgIGZvcihlbnY9MDtlbnY8bkVudmVsb3BlczsgZW52KyspIHsKICAgICAgcHNEYXRhLT5paWREaWZmTW9kZVtlbnZdID0gZGlmZk1vZGVGaW5lW2Vudl07CiAgICAgIEZES21lbWNweShwc0RhdGEtPmlpZElkeFtlbnZdLCBpaWRJZHhGaW5lW2Vudl0sIHBzQmFuZHMqc2l6ZW9mKElOVCkpOwogICAgfQogIH0KICBlbHNlIHsKICAgIHBzRGF0YS0+aWlkUXVhbnRNb2RlID0gUFNfSUlEX1JFU19DT0FSU0U7CiAgICBmb3IoZW52PTA7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICAgIHBzRGF0YS0+aWlkRGlmZk1vZGVbZW52XSA9IGRpZmZNb2RlW2Vudl07CiAgICAgIEZES21lbWNweShwc0RhdGEtPmlpZElkeFtlbnZdLCBpaWRJZHhDb2Fyc2VbZW52XSwgcHNCYW5kcypzaXplb2YoSU5UKSk7CiAgICB9CiAgfQoKICAvKiBDb3VudCBERUxUQV9USU1FIGVuY29kaW5nIHN0cmVha3MgKi8KICBmb3IoZW52PTA7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICBpZihwc0RhdGEtPmlpZERpZmZNb2RlW2Vudl09PVBTX0RFTFRBX1RJTUUpCiAgICAgIHBzRGF0YS0+aWlkVGltZUNudCsrOwogICAgZWxzZQogICAgICBwc0RhdGEtPmlpZFRpbWVDbnQ9MDsKICB9Cn0KCgpzdGF0aWMgSU5UIHNpbWlsYXJJaWQoUFNfREFUQSAgICpwc0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgIHBzQmFuZHMsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgIG5FbnZlbG9wZXMpCnsKICBjb25zdCBJTlQgZGlmZlRociA9IChwc0RhdGEtPmlpZFF1YW50TW9kZSA9PSBQU19JSURfUkVTX0NPQVJTRSkgPyAyIDogMzsKICBjb25zdCBJTlQgc3VtRGlmZlRociA9IGRpZmZUaHIgKiBwc0JhbmRzLzQ7CiAgSU5UIHNpbWlsYXIgPSAwOwogIElOVCBkaWZmICAgID0gMDsKICBJTlQgc3VtRGlmZiA9IDA7CiAgSU5UIGVudiA9IDA7CiAgSU5UIGIgICA9IDA7CiAgaWYgKChuRW52ZWxvcGVzID09IHBzRGF0YS0+bkVudmVsb3Blc0xhc3QpICYmIChuRW52ZWxvcGVzPT0xKSkgewogICAgc2ltaWxhciA9IDE7CiAgICBmb3IgKGVudj0wOyBlbnY8bkVudmVsb3BlczsgZW52KyspIHsKICAgICAgc3VtRGlmZiA9IDA7CiAgICAgIGIgPSAwOwogICAgICBkbyB7CiAgICAgICAgZGlmZiA9IGZpeHBfYWJzKHBzRGF0YS0+aWlkSWR4W2Vudl1bYl0gLSBwc0RhdGEtPmlpZElkeExhc3RbYl0pOwogICAgICAgIHN1bURpZmYgKz0gZGlmZjsKICAgICAgICBpZiAoIChkaWZmID4gZGlmZlRocikgLyogbW9yZSB0aGFuIHggcXVhbnRpemF0aW9uIHN0ZXBzIGluIGFueSBiYW5kICovCiAgICAgICAgICAgICB8fCAoc3VtRGlmZiA+IHN1bURpZmZUaHIpICkgeyAgLyogbW9yZSB0aGFuIHggcXVhbnRpc2F0aW9ucyBzdGVwcyBvdmVyYWxsIGRpZmZlcmVuY2UgKi8KICAgICAgICAgIHNpbWlsYXIgPSAwOwogICAgICAgIH0KICAgICAgICBiKys7CiAgICAgIH0gd2hpbGUgKChiPHBzQmFuZHMpICYmIChzaW1pbGFyPjApKTsKICAgIH0KICB9IC8qIG5FbnZlbG9wZXM9PTEgICovCgogIHJldHVybiBzaW1pbGFyOwp9CgoKc3RhdGljIElOVCBzaW1pbGFySWNjKFBTX0RBVEEgKnBzRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICBwc0JhbmRzLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgIG5FbnZlbG9wZXMpCnsKICBjb25zdCBJTlQgZGlmZlRociA9IDI7CiAgY29uc3QgSU5UIHN1bURpZmZUaHIgPSBkaWZmVGhyICogcHNCYW5kcy80OwogIElOVCBzaW1pbGFyID0gMDsKICBJTlQgZGlmZiAgICA9IDA7CiAgSU5UIHN1bURpZmYgPSAwOwogIElOVCBlbnYgPSAwOwogIElOVCBiICAgPSAwOwogIGlmICgobkVudmVsb3BlcyA9PSBwc0RhdGEtPm5FbnZlbG9wZXNMYXN0KSAmJiAobkVudmVsb3Blcz09MSkpIHsKICAgIHNpbWlsYXIgPSAxOwogICAgZm9yIChlbnY9MDsgZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICAgIHN1bURpZmYgPSAwOwogICAgICBiID0gMDsKICAgICAgZG8gewogICAgICAgIGRpZmYgPSBmaXhwX2Ficyhwc0RhdGEtPmljY0lkeFtlbnZdW2JdIC0gcHNEYXRhLT5pY2NJZHhMYXN0W2JdKTsKICAgICAgICBzdW1EaWZmICs9IGRpZmY7CiAgICAgICAgaWYgKCAoZGlmZiA+IGRpZmZUaHIpIC8qIG1vcmUgdGhhbiB4IHF1YW50aXNhdGlvbiBzdGVwIGluIGFueSBiYW5kICovCiAgICAgICAgICAgICB8fCAoc3VtRGlmZiA+IHN1bURpZmZUaHIpICkgeyAgLyogbW9yZSB0aGFuIHggcXVhbnRpc2F0aW9ucyBzdGVwcyBvdmVyYWxsIGRpZmZlcmVuY2UgKi8KICAgICAgICAgIHNpbWlsYXIgPSAwOwogICAgICAgIH0KICAgICAgICBiKys7CiAgICAgIH0gd2hpbGUgKChiPHBzQmFuZHMpICYmIChzaW1pbGFyPjApKTsKICAgIH0KICB9IC8qIG5FbnZlbG9wZXM9PTEgICovCgogIHJldHVybiBzaW1pbGFyOwp9CgpzdGF0aWMgdm9pZCBwcm9jZXNzSWNjRGF0YShQU19EQVRBICAgKnBzRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgICBpY2NbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwgLyogY29uc3QgaW5wdXQgdmFsdWVzOiB1bmFibGUgdG8gZGVjbGFyZSBhcyBjb25zdCwgc2luY2UgaXQgZG9lcyBub3QgcG9JTlQgdG8gY29uc3QgbWVtb3J5ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgcHNCYW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICBuRW52ZWxvcGVzKQp7CiAgRklYUF9EQkwgZXJySUNDID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKICBJTlQgICBlbnYsIGJhbmQ7CiAgSU5UICAgYml0c0ljY0ZyZXEsIGJpdHNJY2NUaW1lOwogIElOVCAgIGVycm9yID0gMDsKICBJTlQgICBpbkNvaGVyZW5jZT0wLCBpY2NUcmFuc21pdD0wOwogIElOVCAgKmljY0lkeExhc3Q7CgogIGljY0lkeExhc3QgPSBwc0RhdGEtPmljY0lkeExhc3Q7CgogIC8qIFF1YW50aXplIElDQyBjb2VmZmljaWVudHMgKi8KICBmb3IoZW52PTA7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICBlcnJJQ0MgKz0gcXVhbnRpemVDb2VmKGljY1tlbnZdLCBwc0JhbmRzLCBpY2NRdWFudCwgMCwgOCwgcHNEYXRhLT5pY2NJZHhbZW52XSk7CiAgfQoKICAvKiBDaGVjayBpZiBJQ0MgY29lZmZpY2llbnRzIHNob3VsZCBiZSB1c2VkICovCiAgcHNEYXRhLT5pY2NFbmFibGUgPSAwOwogIGZvcihlbnY9MDtlbnY8bkVudmVsb3BlczsgZW52KyspIHsKICAgIGZvcihiYW5kPTA7YmFuZDxwc0JhbmRzO2JhbmQrKykgewogICAgICBpbkNvaGVyZW5jZSArPSBwc0RhdGEtPmljY0lkeFtlbnZdW2JhbmRdOwogICAgICBpY2NUcmFuc21pdCArKzsKICAgIH0KICB9CiAgaWYoaW5Db2hlcmVuY2UgPiBmTXVsdEkoRkwyRlhDT05TVF9EQkwoMC41ZiksaWNjVHJhbnNtaXQpKXsgICAvKiAwLjVmIGVtcGlyaWMgdmFsdWUgKi8KICAgIHBzRGF0YS0+aWNjRW5hYmxlID0gMTsKICB9CgogIGlmKHBzRGF0YS0+aWNjRW5hYmxlPT0wKSB7CiAgICBwc0RhdGEtPmljY1RpbWVDbnQgPSBNQVhfVElNRV9ESUZGX0ZSQU1FUzsKICAgIGZvcihlbnY9MDtlbnY8bkVudmVsb3BlczsgZW52KyspIHsKICAgICAgcHNEYXRhLT5pY2NEaWZmTW9kZVtlbnZdID0gUFNfREVMVEFfRlJFUTsKICAgICAgRkRLbWVtY2xlYXIocHNEYXRhLT5pY2NJZHhbZW52XSwgc2l6ZW9mKElOVCkqcHNCYW5kcyk7CiAgICB9CiAgICByZXR1cm47CiAgfQoKICBmb3IoZW52PTA7ZW52PG5FbnZlbG9wZXM7IGVudisrKSB7CiAgICBiaXRzSWNjRnJlcSAgPSBGREtzYnJFbmNfRW5jb2RlSWNjKE5VTEwsIHBzRGF0YS0+aWNjSWR4W2Vudl0sICAgTlVMTCwgICAgICAgcHNCYW5kcywgUFNfREVMVEFfRlJFUSwgJmVycm9yKTsKCiAgICBpZihwc0RhdGEtPmljY1RpbWVDbnQ8TUFYX1RJTUVfRElGRl9GUkFNRVMpIHsKICAgICAgYml0c0ljY1RpbWUgID0gRkRLc2JyRW5jX0VuY29kZUljYyhOVUxMLCBwc0RhdGEtPmljY0lkeFtlbnZdLCBpY2NJZHhMYXN0LCBwc0JhbmRzLCBQU19ERUxUQV9USU1FLCAmZXJyb3IpOwogICAgfQogICAgZWxzZSB7CiAgICAgIGJpdHNJY2NUaW1lICA9IERPX05PVF9VU0VfVEhJU19NT0RFOwogICAgfQoKICAgIGlmKGJpdHNJY2NGcmVxPmJpdHNJY2NUaW1lKSB7CiAgICAgIHBzRGF0YS0+aWNjRGlmZk1vZGVbZW52XSA9IFBTX0RFTFRBX1RJTUU7CiAgICAgIHBzRGF0YS0+aWNjVGltZUNudCsrOwogICAgfQogICAgZWxzZSB7CiAgICAgIHBzRGF0YS0+aWNjRGlmZk1vZGVbZW52XSA9IFBTX0RFTFRBX0ZSRVE7CiAgICAgIHBzRGF0YS0+aWNjVGltZUNudD0wOwogICAgfQogICAgaWNjSWR4TGFzdCA9IHBzRGF0YS0+aWNjSWR4W2Vudl07CiAgfQp9CgpzdGF0aWMgdm9pZCBjYWxjdWxhdGVJSUQoRklYUF9EQkwgbGRQd3JMW1BTX01BWF9FTlZFTE9QRVNdW1BTX01BWF9CQU5EU10sCiAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCBsZFB3clJbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMIGlpZFtQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdLAogICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgbkVudmVsb3BlcywKICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgIHBzQmFuZHMpCnsKICBJTlQgaT0wOwogIElOVCBlbnY9MDsKICBmb3IoZW52PTA7IGVudjxuRW52ZWxvcGVzO2VudisrKSB7CiAgICBmb3IgKGk9MDsgaTxwc0JhbmRzOyBpKyspIHsKCiAgICAgIC8qIGlpZFtlbnZdW2ldID0gMTAuMGYqKGZsb2F0KWxvZzEwKHB3ckxbZW52XVtpXS9wd3JSW2Vudl1baV0pOwogICAgICAqLwogICAgICBGSVhQX0RCTCBJSUQgPSBmTXVsdERpdjIoIEZMMkZYQ09OU1RfREJMKExPRzEwXzJfMTAvSUlEX1NDQUxFX0ZUKSwgKGxkUHdyTFtlbnZdW2ldLWxkUHdyUltlbnZdW2ldKSApOwoKICAgICAgSUlEID0gZml4TWluKCBJSUQsIChGSVhQX0RCTCkoTUFYVkFMX0RCTD4+KExEX0RBVEFfU0hJRlQrMSkpICk7CiAgICAgIElJRCA9IGZpeE1heCggSUlELCAoRklYUF9EQkwpKE1JTlZBTF9EQkw+PihMRF9EQVRBX1NISUZUKzEpKSApOwogICAgICBpaWRbZW52XVtpXSA9IElJRCA8PCAoTERfREFUQV9TSElGVCsxKTsKICAgIH0KICB9Cn0KCnN0YXRpYyB2b2lkIGNhbGN1bGF0ZUlDQyhGSVhQX0RCTCBsZFB3ckxbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMIGxkUHdyUltQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdLAogICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgcHdyQ3JbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMIHB3ckNpW1BTX01BWF9FTlZFTE9QRVNdW1BTX01BWF9CQU5EU10sCiAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCBpY2NbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXSwKICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgIG5FbnZlbG9wZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICBwc0JhbmRzKQp7CiAgSU5UIGkgPSAwOwogIElOVCBlbnYgPSAwOwogIElOVCBib3JkZXIgPSBwc0JhbmRzOwoKICBzd2l0Y2ggKHBzQmFuZHMpIHsKICBjYXNlIFBTX0JBTkRTX0NPQVJTRToKICAgIGJvcmRlciA9IDU7CiAgICBicmVhazsKICBjYXNlIFBTX0JBTkRTX01JRDoKICAgIGJvcmRlciA9IDExOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGJyZWFrOwogIH0KCiAgZm9yKGVudj0wOyBlbnY8bkVudmVsb3BlcztlbnYrKykgewogICAgZm9yIChpPTA7IGk8Ym9yZGVyOyBpKyspIHsKCiAgICAgIC8qIGljY1tlbnZdW2ldID0gbWluKCBwd3JDcltlbnZdW2ldIC8gKGZsb2F0KSBzcXJ0KHB3ckxbZW52XVtpXSAqIHB3clJbZW52XVtpXSkgLCAxLmYpOwogICAgICAqLwogICAgICBGSVhQX0RCTCBJQ0MsIGludk5yZyA9IENhbGNJbnZMZERhdGEgKCAtKChsZFB3ckxbZW52XVtpXT4+MSkgKyAobGRQd3JSW2Vudl1baV0+PjEpICsgKEZJWFBfREJMKTEpICk7CiAgICAgIElOVCAgICAgIHNjYWxlLCBpbnZTY2FsZSA9IENvdW50TGVhZGluZ0JpdHMoaW52TnJnKTsKCiAgICAgIHNjYWxlID0gKERGUkFDVF9CSVRTLTEpIC0gaW52U2NhbGU7CiAgICAgIElDQyA9IGZNdWx0KHB3ckNyW2Vudl1baV0sIGludk5yZzw8aW52U2NhbGUpIDsKICAgICAgaWNjW2Vudl1baV0gPSBTQVRVUkFURV9MRUZUX1NISUZUKElDQywgc2NhbGUsIERGUkFDVF9CSVRTKTsKICAgIH0KCiAgICBmb3IgKDsgaTxwc0JhbmRzOyBpKyspIHsKICAgICAgSU5UIHNjMSwgc2MyOwogICAgICBGSVhQX0RCTCBjTnJnUiwgY05yZ0ksIElDQzsKCiAgICAgIHNjMSA9IENvdW50TGVhZGluZ0JpdHMoIGZpeE1heChmaXhwX2Ficyhwd3JDcltlbnZdW2ldKSxmaXhwX2Ficyhwd3JDaVtlbnZdW2ldKSkgKSA7CiAgICAgIGNOcmdSID0gZlBvdzJEaXYyKChwd3JDcltlbnZdW2ldPDxzYzEpKTsgICAgICAgLyogc3F1YXJlZCBucmcncyBleHBlY3QgZXhwbGljaXQgc2NhbGluZyAqLwogICAgICBjTnJnSSA9IGZQb3cyRGl2MigocHdyQ2lbZW52XVtpXTw8c2MxKSk7CgogICAgICBJQ0MgPSBDYWxjSW52TGREYXRhKCAoQ2FsY0xkRGF0YSgoY05yZ1IgKyBjTnJnSSk+PjEpPj4xKSAtIChGSVhQX0RCTCkoKHNjMS0xKTw8KERGUkFDVF9CSVRTLTEtTERfREFUQV9TSElGVCkpICk7CgogICAgICBGSVhQX0RCTCBpbnZOcmcgPSBDYWxjSW52TGREYXRhICggLSgobGRQd3JMW2Vudl1baV0+PjEpICsgKGxkUHdyUltlbnZdW2ldPj4xKSArIChGSVhQX0RCTCkxKSApOwogICAgICBzYzEgPSBDb3VudExlYWRpbmdCaXRzKGludk5yZyk7CiAgICAgIGludk5yZyA8PD0gc2MxOwoKICAgICAgc2MyID0gQ291bnRMZWFkaW5nQml0cyhJQ0MpOwogICAgICBJQ0MgPSBmTXVsdChJQ0M8PHNjMixpbnZOcmcpOwoKICAgICAgc2MxID0gKCAoREZSQUNUX0JJVFMtMSkgLSBzYzEgLSBzYzIgKTsKICAgICAgaWYgKHNjMSA8IDApIHsKICAgICAgICAgIElDQyA+Pj0gLXNjMTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAgIGlmIChJQ0MgPj0gKChGSVhQX0RCTClNQVhWQUxfREJMPj5zYzEpICkKICAgICAgICAgICAgICBJQ0MgPSAoRklYUF9EQkwpTUFYVkFMX0RCTDsKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICBJQ0MgPDw9IHNjMTsKICAgICAgfQoKICAgICAgaWNjW2Vudl1baV0gPSBJQ0M7CiAgICB9CiAgfQp9Cgp2b2lkIEZES3NickVuY19pbml0UHNCYW5kTnJnU2NhbGUoSEFORExFX1BTX0VOQ09ERSBoUHNFbmNvZGUpCnsKICBJTlQgZ3JvdXAsIGJpbjsKICBJTlQgbklpZEdyb3VwcyAgID0gaFBzRW5jb2RlLT5uUW1mSWlkR3JvdXBzICsgaFBzRW5jb2RlLT5uU3ViUW1mSWlkR3JvdXBzOwoKICBGREttZW1jbGVhcihoUHNFbmNvZGUtPnBzQmFuZE5yZ1NjYWxlLCBQU19NQVhfQkFORFMqc2l6ZW9mKFNDSEFSKSk7CgogIGZvciAoZ3JvdXA9MDsgZ3JvdXAgPCBuSWlkR3JvdXBzOyBncm91cCsrKSB7CiAgICAvKiBUcmFuc2xhdGUgZ3JvdXAgdG8gYmluICovCiAgICBiaW4gPSBoUHNFbmNvZGUtPnN1YmJhbmQycGFyYW1ldGVySW5kZXhbZ3JvdXBdOwoKICAgIC8qIFRyYW5zbGF0ZSBmcm9tIDIwIGJpbnMgdG8gMTAgYmlucyAqLwogICAgaWYgKGhQc0VuY29kZS0+cHNFbmNNb2RlID09IFBTX0JBTkRTX0NPQVJTRSkgewogICAgICBiaW4gPSBiaW4+PjE7CiAgICB9CgogICAgaFBzRW5jb2RlLT5wc0JhbmROcmdTY2FsZVtiaW5dID0gKGhQc0VuY29kZS0+cHNCYW5kTnJnU2NhbGVbYmluXT09MCkKICAgICAgICAgICAgICAgICAgICAgICAgICA/IChoUHNFbmNvZGUtPmlpZEdyb3VwV2lkdGhMZFtncm91cF0gKyA1KQogICAgICAgICAgICAgICAgICAgICAgICAgIDogKGZpeE1heChoUHNFbmNvZGUtPmlpZEdyb3VwV2lkdGhMZFtncm91cF0saFBzRW5jb2RlLT5wc0JhbmROcmdTY2FsZVtiaW5dKSArIDEpIDsKCiAgfQp9CgpGREtfUFNFTkNfRVJST1IgRkRLc2JyRW5jX0NyZWF0ZVBTRW5jb2RlKAogICAgICAgIEhBTkRMRV9QU19FTkNPREUgICAgICAgICAqcGhQc0VuY29kZQogICAgICAgICkKewogIEZES19QU0VOQ19FUlJPUiBlcnJvciA9IFBTRU5DX09LOwoKICBpZiAocGhQc0VuY29kZT09TlVMTCkgewogICAgZXJyb3IgPSBQU0VOQ19JTlZBTElEX0hBTkRMRTsKICB9CiAgZWxzZSB7CiAgICBIQU5ETEVfUFNfRU5DT0RFIGhQc0VuY29kZSA9IE5VTEw7CiAgICBpZiAoTlVMTD09KGhQc0VuY29kZSA9IEdldFJhbV9Qc0VuY29kZSgpKSkgewogICAgICBlcnJvciA9IFBTRU5DX01FTU9SWV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQogICAgRkRLbWVtY2xlYXIoaFBzRW5jb2RlLHNpemVvZihQU19FTkNPREUpKTsKICAgICpwaFBzRW5jb2RlID0gaFBzRW5jb2RlOyAvKiByZXR1cm4gYWxsb2NhdGVkIGhhbmRsZSAqLwogIH0KYmFpbDoKICByZXR1cm4gZXJyb3I7Cn0KCkZES19QU0VOQ19FUlJPUiBGREtzYnJFbmNfSW5pdFBTRW5jb2RlKAogICAgICAgIEhBTkRMRV9QU19FTkNPREUgICAgICAgICAgaFBzRW5jb2RlLAogICAgICAgIGNvbnN0IFBTX0JBTkRTICAgICAgICAgICAgcHNFbmNNb2RlLAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAgaWlkUXVhbnRFcnJvclRocmVzaG9sZAogICAgICAgICkKewogIEZES19QU0VOQ19FUlJPUiBlcnJvciA9IFBTRU5DX09LOwoKICBpZiAoTlVMTD09aFBzRW5jb2RlKSB7CiAgICBlcnJvciA9IFBTRU5DX0lOVkFMSURfSEFORExFOwogIH0KICBlbHNlIHsKICAgIGlmIChQU0VOQ19PSyAhPSAoSW5pdFBTRGF0YSgmaFBzRW5jb2RlLT5wc0RhdGEpKSkgewogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgc3dpdGNoKHBzRW5jTW9kZSl7CiAgICAgIGNhc2UgUFNfQkFORFNfQ09BUlNFOgogICAgICBjYXNlIFBTX0JBTkRTX01JRDoKICAgICAgICBoUHNFbmNvZGUtPm5RbWZJaWRHcm91cHMgICAgPSBRTUZfR1JPVVBTX0xPX1JFUzsKICAgICAgICBoUHNFbmNvZGUtPm5TdWJRbWZJaWRHcm91cHMgPSBTVUJRTUZfR1JPVVBTX0xPX1JFUzsKICAgICAgICBGREttZW1jcHkoaFBzRW5jb2RlLT5paWRHcm91cEJvcmRlcnMsICAgICAgICBpaWRHcm91cEJvcmRlcnNMb1JlcywgKGhQc0VuY29kZS0+blFtZklpZEdyb3VwcyArIGhQc0VuY29kZS0+blN1YlFtZklpZEdyb3VwcyArIDEpKnNpemVvZihJTlQpKTsKICAgICAgICBGREttZW1jcHkoaFBzRW5jb2RlLT5zdWJiYW5kMnBhcmFtZXRlckluZGV4LCBzdWJiYW5kMnBhcmFtZXRlcjIwLCAgKGhQc0VuY29kZS0+blFtZklpZEdyb3VwcyArIGhQc0VuY29kZS0+blN1YlFtZklpZEdyb3VwcykgICAgKnNpemVvZihJTlQpKTsKICAgICAgICBGREttZW1jcHkoaFBzRW5jb2RlLT5paWRHcm91cFdpZHRoTGQsICAgICAgICBpaWRHcm91cFdpZHRoTGRMb1JlcywgKGhQc0VuY29kZS0+blFtZklpZEdyb3VwcyArIGhQc0VuY29kZS0+blN1YlFtZklpZEdyb3VwcykgICAgKnNpemVvZihVQ0hBUikpOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGVycm9yID0gUFNFTkNfSU5JVF9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgaFBzRW5jb2RlLT5wc0VuY01vZGUgPSBwc0VuY01vZGU7CiAgICBoUHNFbmNvZGUtPmlpZFF1YW50RXJyb3JUaHJlc2hvbGQgPSBpaWRRdWFudEVycm9yVGhyZXNob2xkOwogICAgRkRLc2JyRW5jX2luaXRQc0JhbmROcmdTY2FsZShoUHNFbmNvZGUpOwogIH0KYmFpbDoKICByZXR1cm4gZXJyb3I7Cn0KCgpGREtfUFNFTkNfRVJST1IgRkRLc2JyRW5jX0Rlc3Ryb3lQU0VuY29kZSgKICAgICAgICBIQU5ETEVfUFNfRU5DT0RFICAgICAgICAgKnBoUHNFbmNvZGUKICAgICAgICApCnsKICBGREtfUFNFTkNfRVJST1IgZXJyb3IgPSBQU0VOQ19PSzsKCiAgaWYgKE5VTEwgIT1waFBzRW5jb2RlKSB7CiAgICBGcmVlUmFtX1BzRW5jb2RlKHBoUHNFbmNvZGUpOwogIH0KCiAgcmV0dXJuIGVycm9yOwp9Cgp0eXBlZGVmIHN0cnVjdCB7CiAgRklYUF9EQkwgcHdyTFtQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdOwogIEZJWFBfREJMIHB3clJbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXTsKICBGSVhQX0RCTCBsZFB3ckxbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXTsKICBGSVhQX0RCTCBsZFB3clJbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXTsKICBGSVhQX0RCTCBwd3JDcltQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdOwogIEZJWFBfREJMIHB3ckNpW1BTX01BWF9FTlZFTE9QRVNdW1BTX01BWF9CQU5EU107Cgp9IFBTX1BXUl9EQVRBOwoKCkZES19QU0VOQ19FUlJPUiBGREtzYnJFbmNfUFNFbmNvZGUoCiAgICAgICAgSEFORExFX1BTX0VOQ09ERSAgICAgICAgICBoUHNFbmNvZGUsCiAgICAgICAgSEFORExFX1BTX09VVCAgICAgICAgICAgICBoUHNPdXQsCiAgICAgICAgVUNIQVIgICAgICAgICAgICAgICAgICAgICpkeW5CYW5kU2NhbGUsCiAgICAgICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICBtYXhFbnZlbG9wZXMsCiAgICAgICAgRklYUF9EQkwgICAgICAgICAgICAgICAgICpoeWJyaWREYXRhW0hZQlJJRF9GUkFNRVNJWkVdW01BWF9QU19DSEFOTkVMU11bMl0sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBmcmFtZVNpemUsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzZW5kSGVhZGVyCiAgICAgICAgKQp7CiAgRkRLX1BTRU5DX0VSUk9SIGVycm9yID0gUFNFTkNfT0s7CgogIEhBTkRMRV9QU19EQVRBIGhQc0RhdGEgPSAmaFBzRW5jb2RlLT5wc0RhdGE7CiAgRklYUF9EQkwgaWlkIFtQU19NQVhfRU5WRUxPUEVTXVtQU19NQVhfQkFORFNdOwogIEZJWFBfREJMIGljYyBbUFNfTUFYX0VOVkVMT1BFU11bUFNfTUFYX0JBTkRTXTsKICBpbnQgZW52Qm9yZGVyW1BTX01BWF9FTlZFTE9QRVMrMV07CgogIGludCBncm91cCwgYmluLCBjb2wsIHN1YmJhbmQsIGJhbmQ7CiAgaW50IGkgPSAwOwoKICBpbnQgZW52ID0gMDsKICBpbnQgcHNCYW5kcyAgICAgID0gKGludCkgaFBzRW5jb2RlLT5wc0VuY01vZGU7CiAgaW50IG5JaWRHcm91cHMgICA9IGhQc0VuY29kZS0+blFtZklpZEdyb3VwcyArIGhQc0VuY29kZS0+blN1YlFtZklpZEdyb3VwczsKICBpbnQgbkVudmVsb3BlcyAgID0gZml4TWluKG1heEVudmVsb3BlcywgKFVJTlQpUFNfTUFYX0VOVkVMT1BFUyk7CgogIENfQUxMT0NfU0NSQVRDSF9TVEFSVChwd3JEYXRhLCBQU19QV1JfREFUQSwgMSk7CgogIGZvcihlbnY9MDsgZW52PG5FbnZlbG9wZXMrMTtlbnYrKykgewogICAgZW52Qm9yZGVyW2Vudl0gPSBmTXVsdEkoR2V0SW52SW50KG5FbnZlbG9wZXMpLGZyYW1lU2l6ZSplbnYpOwogIH0KCiAgZm9yKGVudj0wOyBlbnY8bkVudmVsb3BlcztlbnYrKykgewoKICAgIC8qIGNsZWFyIGVuZXJneSBhcnJheSAqLwogICAgZm9yIChiYW5kPTA7IGJhbmQ8cHNCYW5kczsgYmFuZCsrKSB7CiAgICAgIHB3ckRhdGEtPnB3ckxbZW52XVtiYW5kXSA9IHB3ckRhdGEtPnB3clJbZW52XVtiYW5kXSA9IHB3ckRhdGEtPnB3ckNyW2Vudl1bYmFuZF0gPSBwd3JEYXRhLT5wd3JDaVtlbnZdW2JhbmRdID0gRklYUF9EQkwoMSk7CiAgICB9CgogICAgLyoqKiogY2FsY3VsYXRlIGVuZXJnaWVzIGFuZCBjb3JyZWxhdGlvbiAqKioqLwoKICAgIC8qIHN0YXJ0IHdpdGggaHlicmlkIGRhdGEgKi8KICAgIGZvciAoZ3JvdXA9MDsgZ3JvdXAgPCBuSWlkR3JvdXBzOyBncm91cCsrKSB7CiAgICAgIC8qIFRyYW5zbGF0ZSBncm91cCB0byBiaW4gKi8KICAgICAgYmluID0gaFBzRW5jb2RlLT5zdWJiYW5kMnBhcmFtZXRlckluZGV4W2dyb3VwXTsKCiAgICAgIC8qIFRyYW5zbGF0ZSBmcm9tIDIwIGJpbnMgdG8gMTAgYmlucyAqLwogICAgICBpZiAoaFBzRW5jb2RlLT5wc0VuY01vZGUgPT0gUFNfQkFORFNfQ09BUlNFKSB7CiAgICAgICAgYmluID4+PSAxOwogICAgICB9CgogICAgICAvKiBkZXRlcm1pbmUgZ3JvdXAgYm9yZGVyICovCiAgICAgIGludCBiU2NhbGUgPSBoUHNFbmNvZGUtPnBzQmFuZE5yZ1NjYWxlW2Jpbl07CgogICAgICBGSVhQX0RCTCBwd3JMX2Vudl9iaW4gPSBwd3JEYXRhLT5wd3JMW2Vudl1bYmluXTsKICAgICAgRklYUF9EQkwgcHdyUl9lbnZfYmluID0gcHdyRGF0YS0+cHdyUltlbnZdW2Jpbl07CiAgICAgIEZJWFBfREJMIHB3ckNyX2Vudl9iaW4gPSBwd3JEYXRhLT5wd3JDcltlbnZdW2Jpbl07CiAgICAgIEZJWFBfREJMIHB3ckNpX2Vudl9iaW4gPSBwd3JEYXRhLT5wd3JDaVtlbnZdW2Jpbl07CgogICAgICBpbnQgc2NhbGUgPSAoaW50KWR5bkJhbmRTY2FsZVtiaW5dOwogICAgICBmb3IgKGNvbD1lbnZCb3JkZXJbZW52XTsgY29sPGVudkJvcmRlcltlbnYrMV07IGNvbCsrKSB7CiAgICAgICAgZm9yIChzdWJiYW5kID0gaFBzRW5jb2RlLT5paWRHcm91cEJvcmRlcnNbZ3JvdXBdOyBzdWJiYW5kIDwgaFBzRW5jb2RlLT5paWRHcm91cEJvcmRlcnNbZ3JvdXArMV07IHN1YmJhbmQrKykgewogICAgICAgICAgRklYUF9RTUYgbF9yZWFsID0gKGh5YnJpZERhdGFbY29sXVswXVswXVtzdWJiYW5kXSkgPDwgc2NhbGU7CiAgICAgICAgICBGSVhQX1FNRiBsX2ltYWcgPSAoaHlicmlkRGF0YVtjb2xdWzBdWzFdW3N1YmJhbmRdKSA8PCBzY2FsZTsKICAgICAgICAgIEZJWFBfUU1GIHJfcmVhbCA9IChoeWJyaWREYXRhW2NvbF1bMV1bMF1bc3ViYmFuZF0pIDw8IHNjYWxlOwogICAgICAgICAgRklYUF9RTUYgcl9pbWFnID0gKGh5YnJpZERhdGFbY29sXVsxXVsxXVtzdWJiYW5kXSkgPDwgc2NhbGU7CgogICAgICAgICAgcHdyTF9lbnZfYmluICArPSAoZlBvdzJEaXYyKGxfcmVhbCkgKyBmUG93MkRpdjIobF9pbWFnKSkgPj4gYlNjYWxlOwogICAgICAgICAgcHdyUl9lbnZfYmluICArPSAoZlBvdzJEaXYyKHJfcmVhbCkgKyBmUG93MkRpdjIocl9pbWFnKSkgPj4gYlNjYWxlOwogICAgICAgICAgcHdyQ3JfZW52X2JpbiArPSAoZk11bHREaXYyKGxfcmVhbCwgcl9yZWFsKSArIGZNdWx0RGl2MihsX2ltYWcsIHJfaW1hZykpID4+IGJTY2FsZTsKICAgICAgICAgIHB3ckNpX2Vudl9iaW4gKz0gKGZNdWx0RGl2MihyX3JlYWwsIGxfaW1hZykgLSBmTXVsdERpdjIobF9yZWFsLCByX2ltYWcpKSA+PiBiU2NhbGU7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIGFzc3VyZSwgbnJnJ3Mgb2YgbGVmdCBhbmQgcmlnaHQgY2hhbm5lbCBhcmUgbm90IG5lZ2F0aXZlOyBuZWNlc3Nhcnkgb24gMTYgYml0IG11bHRpcGx5IHVuaXRzICovCiAgICAgIHB3ckRhdGEtPnB3ckxbZW52XVtiaW5dID0gZml4TWF4KChGSVhQX0RCTCkwLHB3ckxfZW52X2Jpbik7CiAgICAgIHB3ckRhdGEtPnB3clJbZW52XVtiaW5dID0gZml4TWF4KChGSVhQX0RCTCkwLHB3clJfZW52X2Jpbik7CgogICAgICBwd3JEYXRhLT5wd3JDcltlbnZdW2Jpbl0gPSBwd3JDcl9lbnZfYmluOwogICAgICBwd3JEYXRhLT5wd3JDaVtlbnZdW2Jpbl0gPSBwd3JDaV9lbnZfYmluOwoKICAgIH0gLyogbklpZEdyb3VwcyAqLwoKICAgIC8qIGNhbGMgbG9nYXJpdGhtaWMgZW5lcmd5ICovCiAgICBMZERhdGFWZWN0b3IocHdyRGF0YS0+cHdyTFtlbnZdLCBwd3JEYXRhLT5sZFB3ckxbZW52XSwgcHNCYW5kcyk7CiAgICBMZERhdGFWZWN0b3IocHdyRGF0YS0+cHdyUltlbnZdLCBwd3JEYXRhLT5sZFB3clJbZW52XSwgcHNCYW5kcyk7CgogIH0gLyogbkVudmVsb3BlcyAqLwoKICAvKiBjYWxjdWxhdGUgaWlkIGFuZCBpY2MgKi8KICBjYWxjdWxhdGVJSUQocHdyRGF0YS0+bGRQd3JMLCBwd3JEYXRhLT5sZFB3clIsIGlpZCwgbkVudmVsb3BlcywgcHNCYW5kcyk7CiAgY2FsY3VsYXRlSUNDKHB3ckRhdGEtPmxkUHdyTCwgcHdyRGF0YS0+bGRQd3JSLCBwd3JEYXRhLT5wd3JDciwgcHdyRGF0YS0+cHdyQ2ksIGljYywgbkVudmVsb3BlcywgcHNCYW5kcyk7CgogIC8qKiogRW52ZWxvcGUgUmVkdWN0aW9uICoqKi8KICB3aGlsZSAoZW52ZWxvcGVSZWR1Y2libGUoaWlkLGljYyxwc0JhbmRzLG5FbnZlbG9wZXMpKSB7CiAgICBpbnQgZT0wOwogICAgLyogc3VtIGVuZXJnaWVzIG9mIHR3byBuZWlnaGJvcmluZyBlbnZlbG9wZXMgKi8KICAgIG5FbnZlbG9wZXMgPj49IDE7CiAgICBmb3IgKGU9MDsgZTxuRW52ZWxvcGVzOyBlKyspIHsKICAgICAgRkRLc2JyRW5jX2FkZEZJWFBfREJMKHB3ckRhdGEtPnB3ckxbMiplXSwgcHdyRGF0YS0+cHdyTFsyKmUrMV0sIHB3ckRhdGEtPnB3ckxbZV0sIHBzQmFuZHMpOwogICAgICBGREtzYnJFbmNfYWRkRklYUF9EQkwocHdyRGF0YS0+cHdyUlsyKmVdLCBwd3JEYXRhLT5wd3JSWzIqZSsxXSwgcHdyRGF0YS0+cHdyUltlXSwgcHNCYW5kcyk7CiAgICAgIEZES3NickVuY19hZGRGSVhQX0RCTChwd3JEYXRhLT5wd3JDclsyKmVdLHB3ckRhdGEtPnB3ckNyWzIqZSsxXSxwd3JEYXRhLT5wd3JDcltlXSxwc0JhbmRzKTsKICAgICAgRkRLc2JyRW5jX2FkZEZJWFBfREJMKHB3ckRhdGEtPnB3ckNpWzIqZV0scHdyRGF0YS0+cHdyQ2lbMiplKzFdLHB3ckRhdGEtPnB3ckNpW2VdLHBzQmFuZHMpOwoKICAgICAgLyogY2FsYyBsb2dhcml0aG1pYyBlbmVyZ3kgKi8KICAgICAgTGREYXRhVmVjdG9yKHB3ckRhdGEtPnB3ckxbZV0sIHB3ckRhdGEtPmxkUHdyTFtlXSwgcHNCYW5kcyk7CiAgICAgIExkRGF0YVZlY3Rvcihwd3JEYXRhLT5wd3JSW2VdLCBwd3JEYXRhLT5sZFB3clJbZV0sIHBzQmFuZHMpOwoKICAgICAgLyogcmVkdWNlIG51bWJlciBvZiBlbnZlbG9wZXMgYW5kIGFkanVzdCBib3JkZXJzICovCiAgICAgIGVudkJvcmRlcltlXSA9IGVudkJvcmRlclsyKmVdOwogICAgfQogICAgZW52Qm9yZGVyW25FbnZlbG9wZXNdID0gZW52Qm9yZGVyWzIqbkVudmVsb3Blc107CgogICAgLyogcmUtY2FsY3VsYXRlIGlpZCBhbmQgaWNjICovCiAgICBjYWxjdWxhdGVJSUQocHdyRGF0YS0+bGRQd3JMLCBwd3JEYXRhLT5sZFB3clIsIGlpZCwgbkVudmVsb3BlcywgcHNCYW5kcyk7CiAgICBjYWxjdWxhdGVJQ0MocHdyRGF0YS0+bGRQd3JMLCBwd3JEYXRhLT5sZFB3clIsIHB3ckRhdGEtPnB3ckNyLCBwd3JEYXRhLT5wd3JDaSwgaWNjLCBuRW52ZWxvcGVzLCBwc0JhbmRzKTsKICB9CgoKICAvKiAgKi8KICBpZihzZW5kSGVhZGVyKSB7CiAgICBoUHNEYXRhLT5oZWFkZXJDbnQgID0gTUFYX1BTX05PSEVBREVSX0NOVDsKICAgIGhQc0RhdGEtPmlpZFRpbWVDbnQgPSBNQVhfVElNRV9ESUZGX0ZSQU1FUzsKICAgIGhQc0RhdGEtPmljY1RpbWVDbnQgPSBNQVhfVElNRV9ESUZGX0ZSQU1FUzsKICAgIGhQc0RhdGEtPm5vRW52Q250ICAgPSBNQVhfTk9FTlZfQ05UOwogIH0KCiAgLyoqKiBQYXJhbWV0ZXIgcHJvY2Vzc2luZywgcXVhbnRpc2F0aW9uIGV0YyAqKiovCiAgcHJvY2Vzc0lpZERhdGEoaFBzRGF0YSwgaWlkLCBwc0JhbmRzLCBuRW52ZWxvcGVzLCBoUHNFbmNvZGUtPmlpZFF1YW50RXJyb3JUaHJlc2hvbGQpOwogIHByb2Nlc3NJY2NEYXRhKGhQc0RhdGEsIGljYywgcHNCYW5kcywgbkVudmVsb3Blcyk7CgoKICAvKioqIEluaXRpYWxpemUgb3V0cHV0IHN0cnVjdCAqKiovCgogIC8qIFBTIEhlYWRlciBvbi9vZmYgPyAqLwogIGlmKCAoaFBzRGF0YS0+aGVhZGVyQ250PE1BWF9QU19OT0hFQURFUl9DTlQpCiAgICAgICAmJiAoIChoUHNEYXRhLT5paWRRdWFudE1vZGUgPT0gaFBzRGF0YS0+aWlkUXVhbnRNb2RlTGFzdCkgJiYgKGhQc0RhdGEtPmljY1F1YW50TW9kZSA9PSBoUHNEYXRhLT5pY2NRdWFudE1vZGVMYXN0KSApCiAgICAgICAmJiAoIChoUHNEYXRhLT5paWRFbmFibGUgICAgPT0gaFBzRGF0YS0+aWlkRW5hYmxlTGFzdCkgICAgJiYgKGhQc0RhdGEtPmljY0VuYWJsZSAgICA9PSBoUHNEYXRhLT5pY2NFbmFibGVMYXN0KSAgKSApIHsKICAgIGhQc091dC0+ZW5hYmxlUFNIZWFkZXIgPSAwOwogIH0KICBlbHNlIHsKICAgIGhQc091dC0+ZW5hYmxlUFNIZWFkZXIgPSAxOwogICAgaFBzRGF0YS0+aGVhZGVyQ250ID0gMDsKICB9CgogIC8qIG5FbnZlbG9wZXMgPSAwID8gKi8KICBpZiAoIChoUHNEYXRhLT5ub0VudkNudCA8IE1BWF9OT0VOVl9DTlQpCiAgICAgICAmJiAoc2ltaWxhcklpZChoUHNEYXRhLCBwc0JhbmRzLCBuRW52ZWxvcGVzKSkKICAgICAgICYmIChzaW1pbGFySWNjKGhQc0RhdGEsIHBzQmFuZHMsIG5FbnZlbG9wZXMpKSApIHsKICAgIGhQc091dC0+bkVudmVsb3BlcyA9IG5FbnZlbG9wZXMgPSAwOwogICAgaFBzRGF0YS0+bm9FbnZDbnQrKzsKICB9IGVsc2UgewogICAgaFBzRGF0YS0+bm9FbnZDbnQgPSAwOwogIH0KCgogIGlmIChuRW52ZWxvcGVzPjApIHsKCiAgICBoUHNPdXQtPmVuYWJsZUlJRCAgICAgID0gaFBzRGF0YS0+aWlkRW5hYmxlOwogICAgaFBzT3V0LT5paWRNb2RlICAgICAgICA9IGdldElJRE1vZGUocHNCYW5kcywgaFBzRGF0YS0+aWlkUXVhbnRNb2RlKTsKCiAgICBoUHNPdXQtPmVuYWJsZUlDQyAgICAgID0gaFBzRGF0YS0+aWNjRW5hYmxlOwogICAgaFBzT3V0LT5pY2NNb2RlICAgICAgICA9IGdldElDQ01vZGUocHNCYW5kcywgaFBzRGF0YS0+aWNjUXVhbnRNb2RlKTsKCiAgICBoUHNPdXQtPmVuYWJsZUlwZE9wZCAgPSAwOwogICAgaFBzT3V0LT5mcmFtZUNsYXNzICAgID0gMDsKICAgIGhQc091dC0+bkVudmVsb3BlcyAgICA9IG5FbnZlbG9wZXM7CgogICAgZm9yKGVudj0wOyBlbnY8bkVudmVsb3BlczsgZW52KyspIHsKICAgICAgaFBzT3V0LT5mcmFtZUJvcmRlcltlbnZdID0gZW52Qm9yZGVyW2VudisxXTsKICAgIH0KCiAgICBmb3IoZW52PTA7IGVudjxoUHNPdXQtPm5FbnZlbG9wZXM7IGVudisrKSB7CiAgICAgIGhQc091dC0+ZGVsdGFJSURbZW52XSA9IChQU19ERUxUQSloUHNEYXRhLT5paWREaWZmTW9kZVtlbnZdOwoKICAgICAgZm9yKGJhbmQ9MDsgYmFuZDxwc0JhbmRzOyBiYW5kKyspIHsKICAgICAgICBoUHNPdXQtPmlpZFtlbnZdW2JhbmRdID0gaFBzRGF0YS0+aWlkSWR4W2Vudl1bYmFuZF07CiAgICAgIH0KICAgIH0KCiAgICBmb3IoZW52PTA7IGVudjxoUHNPdXQtPm5FbnZlbG9wZXM7IGVudisrKSB7CiAgICAgIGhQc091dC0+ZGVsdGFJQ0NbZW52XSA9IChQU19ERUxUQSloUHNEYXRhLT5pY2NEaWZmTW9kZVtlbnZdOwogICAgICBmb3IoYmFuZD0wOyBiYW5kPHBzQmFuZHM7IGJhbmQrKykgewogICAgICAgIGhQc091dC0+aWNjW2Vudl1bYmFuZF0gPSBoUHNEYXRhLT5pY2NJZHhbZW52XVtiYW5kXTsKICAgICAgfQogICAgfQoKICAgIC8qIElQRCBPUEQgbm90IHN1cHBvcnRlZCByaWdodCBub3cgKi8KICAgIEZES21lbWNsZWFyKGhQc091dC0+aXBkLCBQU19NQVhfRU5WRUxPUEVTKlBTX01BWF9CQU5EUypzaXplb2YoUFNfREVMVEEpKTsKICAgIGZvcihlbnY9MDsgZW52PFBTX01BWF9FTlZFTE9QRVM7IGVudisrKSB7CiAgICAgIGhQc091dC0+ZGVsdGFJUERbZW52XSA9IFBTX0RFTFRBX0ZSRVE7CiAgICAgIGhQc091dC0+ZGVsdGFPUERbZW52XSA9IFBTX0RFTFRBX0ZSRVE7CiAgICB9CgogICAgRkRLbWVtY2xlYXIoaFBzT3V0LT5pcGRMYXN0LCBQU19NQVhfQkFORFMqc2l6ZW9mKElOVCkpOwogICAgRkRLbWVtY2xlYXIoaFBzT3V0LT5vcGRMYXN0LCBQU19NQVhfQkFORFMqc2l6ZW9mKElOVCkpOwoKICAgIGZvcihiYW5kPTA7IGJhbmQ8UFNfTUFYX0JBTkRTOyBiYW5kKyspIHsKICAgICAgaFBzT3V0LT5paWRMYXN0W2JhbmRdID0gaFBzRGF0YS0+aWlkSWR4TGFzdFtiYW5kXTsKICAgICAgaFBzT3V0LT5pY2NMYXN0W2JhbmRdID0gaFBzRGF0YS0+aWNjSWR4TGFzdFtiYW5kXTsKICAgIH0KCiAgICAvKiBzYXZlIGlpZHMgYW5kIGljY3MgZm9yIGRpZmZlcmVudGlhbCB0aW1lIGNvZGluZyBpbiB0aGUgbmV4dCBmcmFtZSAqLwogICAgaFBzRGF0YS0+bkVudmVsb3Blc0xhc3QgICA9IG5FbnZlbG9wZXM7CiAgICBoUHNEYXRhLT5paWRFbmFibGVMYXN0ICAgID0gaFBzRGF0YS0+aWlkRW5hYmxlOwogICAgaFBzRGF0YS0+aWNjRW5hYmxlTGFzdCAgICA9IGhQc0RhdGEtPmljY0VuYWJsZTsKICAgIGhQc0RhdGEtPmlpZFF1YW50TW9kZUxhc3QgPSBoUHNEYXRhLT5paWRRdWFudE1vZGU7CiAgICBoUHNEYXRhLT5pY2NRdWFudE1vZGVMYXN0ID0gaFBzRGF0YS0+aWNjUXVhbnRNb2RlOwogICAgZm9yIChpPTA7IGk8cHNCYW5kczsgaSsrKSB7CiAgICAgIGhQc0RhdGEtPmlpZElkeExhc3RbaV0gPSBoUHNEYXRhLT5paWRJZHhbbkVudmVsb3Blcy0xXVtpXTsKICAgICAgaFBzRGF0YS0+aWNjSWR4TGFzdFtpXSA9IGhQc0RhdGEtPmljY0lkeFtuRW52ZWxvcGVzLTFdW2ldOwogICAgfQogIH0gLyogRW52ZWxvcGUgPiAwICovCgogIENfQUxMT0NfU0NSQVRDSF9FTkQocHdyRGF0YSwgUFNfUFdSX0RBVEEsIDEpCgogIHJldHVybiBlcnJvcjsKfQoK