Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKToKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAidHBlbmNfbGF0bS5oIgoKCiNpbmNsdWRlICJnZW5lcmljU3Rkcy5oIgoKc3RhdGljIGNvbnN0IHNob3J0IGNlbHBGcmFtZUxlbmd0aFRhYmxlWzY0XSA9IHsKIDE1NCwgMTcwLCAxODYsIDE0NywgMTU2LCAxNjUsIDExNCwgMTIwLAogMTg2LCAxMjYsIDEzMiwgMTM4LCAxNDIsIDE0NiwgMTU0LCAxNjYsCiAxNzQsIDE4MiwgMTkwLCAxOTgsIDIwNiwgMjEwLCAyMTQsIDExMCwKIDExNCwgMTE4LCAxMjAsIDEyMiwgMjE4LCAyMzAsIDI0MiwgMjU0LAogMjY2LCAyNzgsIDI4NiwgMjk0LCAzMTgsIDM0MiwgMzU4LCAzNzQsCiAzOTAsIDQwNiwgNDIyLCAxMzYsIDE0MiwgMTQ4LCAxNTQsIDE2MCwKIDE2NiwgMTcwLCAxNzQsIDE4NiwgMTk4LCAyMDYsIDIxNCwgMjIyLAogMjMwLCAyMzgsIDIxNiwgMTYwLCAyODAsIDMzOCwgMCwgICAwCn07CgovKioqKioqKgogd3JpdGUgdmFsdWUgdG8gdHJhbnNwb3J0IHN0cmVhbQogZmlyc3QgdHdvIGJpdHMgZGVmaW5lIHRoZSBzaXplIG9mIHRoZSB2YWx1ZSBpdHNlbGYKIHRoZW4gdGhlIHZhbHVlIGl0c2VsZiwgd2l0aCBhIHNpemUgb2YgMC0zIGJ5dGVzCioqKioqKiovCnN0YXRpYwpVSU5UIHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZShIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsIGludCB2YWx1ZSkKewogIFVDSEFSIHZhbHVlQnl0ZXMgPSA0OwogIHVuc2lnbmVkIGludCBiaXRzV3JpdHRlbiA9IDA7CiAgaW50IGk7CgogIGlmICggdmFsdWUgPCAoMTw8OCkgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMTsKICB9IGVsc2UgaWYgKCB2YWx1ZSA8ICgxPDwxNikgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMjsKICB9IGVsc2UgaWYgKCB2YWx1ZSA8ICgxPDwyNCkgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMzsKICB9IGVsc2UgewogICAgdmFsdWVCeXRlcyA9IDQ7CiAgfQoKICBGREt3cml0ZUJpdHMoaEJzLCB2YWx1ZUJ5dGVzLTEsIDIgKTsgLyogc2l6ZSBvZiB2YWx1ZSBpbiBCeXRlcyAqLwogIGZvciAoaT0wOyBpPHZhbHVlQnl0ZXM7IGkrKykgewogICAgLyogd3JpdGUgbW9zdCBzaWduaWZpY2FudCBCeXRlIGZpcnN0ICovCiAgICBGREt3cml0ZUJpdHMoaEJzLCAoVUNIQVIpKHZhbHVlPj4oKHZhbHVlQnl0ZXMtMS1pKTw8MykpLCA4KTsKICB9CgogIGJpdHNXcml0dGVuID0gKHZhbHVlQnl0ZXM8PDMpKzI7CgogIHJldHVybiBiaXRzV3JpdHRlbjsKfQoKc3RhdGljClVJTlQgdHJhbnNwb3J0RW5jX0xhdG1Db3VudEZpeEJpdERlbWFuZEhlYWRlciAoIEhBTkRMRV9MQVRNX1NUUkVBTSBoQXNzICkKewogIGludCBiaXREZW1hbmQgPSAwOwogIGludCBpbnNlcnRTZXR1cERhdGEgPSAwIDsKCiAgLyogb25seSBpZiBzdGFydCBvZiBuZXcgbGF0bSBmcmFtZSAqLwogIGlmIChoQXNzLT5zdWJGcmFtZUNudD09MCkKICB7CiAgICAvKiBBdWRpb1N5bmNTdHJlYW0gKi8KCiAgICBpZiAoaEFzcy0+dHQgPT0gVFRfTVA0X0xPQVMpIHsKICAgICAgYml0RGVtYW5kICs9IDExIDsgICAgICAgICAgICAgLyogc3luY3dvcmQgKi8KICAgICAgYml0RGVtYW5kICs9IDEzIDsgICAgICAgICAgICAgLyogYXVkaW9NdXhMZW5ndGhCeXRlcyAqLwogICAgfQoKICAgIC8qIEF1ZGlvTXV4RWxlbWVudCovCgogICAgLyogQXVkaW9NdXhFbGVtZW50OjpTdHJlYW0gTXV4IENvbmZpZyAqLwogICAgaWYgKGhBc3MtPm11eENvbmZpZ1BlcmlvZCA+IDApIHsKICAgICAgaW5zZXJ0U2V0dXBEYXRhID0gKGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPT0gMCk7CiAgICB9IGVsc2UgewogICAgICBpbnNlcnRTZXR1cERhdGEgPSAwOwogICAgfQoKICAgIGlmIChoQXNzLT50dCAhPSBUVF9NUDRfTEFUTV9NQ1AwKSB7CiAgICAgIC8qIEF1ZGlvTXV4RWxlbWVudDo6dXNlU2FtZVN0cmVhbU11eCBGbGFnICovCiAgICAgIGJpdERlbWFuZCs9MTsKCiAgICAgIGlmKCBpbnNlcnRTZXR1cERhdGEgKSB7CiAgICAgICAgYml0RGVtYW5kICs9IGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHM7CiAgICAgIH0KICAgIH0KCiAgICAvKiBBdWRpb011eEVsZW1lbnQ6Om90aGVyRGF0YUJpdHMgKi8KICAgIGJpdERlbWFuZCArPSA4KmhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzOwoKICAgIC8qIEF1ZGlvTXV4RWxlbWVudDo6Qnl0ZUFsaWduICovCiAgICBpZiAoIGJpdERlbWFuZCAlIDggKSB7CiAgICAgICBoQXNzLT5maWxsQml0cyA9IDggLSAoYml0RGVtYW5kICUgOCk7CiAgICAgICBiaXREZW1hbmQgKz0gaEFzcy0+ZmlsbEJpdHMgOwogICAgfSBlbHNlIHsKICAgICAgaEFzcy0+ZmlsbEJpdHMgPSAwOwogICAgfQogIH0KCiAgcmV0dXJuIGJpdERlbWFuZCA7Cn0KCnN0YXRpYwpVSU5UIHRyYW5zcG9ydEVuY19MYXRtQ291bnRWYXJCaXREZW1hbmRIZWFkZXIgKCBIQU5ETEVfTEFUTV9TVFJFQU0gaEFzcyAsIHVuc2lnbmVkIGludCBzdHJlYW1EYXRhTGVuZ3RoICkKewogIGludCBiaXREZW1hbmQgPSAwOwogIGludCAgcHJvZywgbGF5ZXI7CgogIC8qIFBheWxvYWQgTGVuZ3RoIEluZm8qLwogIGlmKCBoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nICkgewogICAgZm9yKCBwcm9nPTA7IHByb2c8aEFzcy0+bm9Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICAgIGZvciggbGF5ZXI9MDsgbGF5ZXI8TEFUTV9NQVhfTEFZRVJTOyBsYXllcisrICkgewogICAgICAgIExBVE1fTEFZRVJfSU5GTyAqcF9saW5mbyA9ICYoaEFzcy0+bV9saW5mb1twcm9nXVtsYXllcl0pOwoKICAgICAgICBpZiggcF9saW5mby0+c3RyZWFtSUQgPj0gMCApIHsKICAgICAgICAgIHN3aXRjaCggcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlICkgewogICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICBpZiAoIHN0cmVhbURhdGFMZW5ndGggPiAwICkgewogICAgICAgICAgICAgIHN0cmVhbURhdGFMZW5ndGggLT0gYml0RGVtYW5kIDsKICAgICAgICAgICAgICB3aGlsZSggc3RyZWFtRGF0YUxlbmd0aCA+PSAoMjU1PDwzKSApIHsKICAgICAgICAgICAgICAgIGJpdERlbWFuZCs9ODsKICAgICAgICAgICAgICAgIHN0cmVhbURhdGFMZW5ndGggLT0gKDI1NTw8Myk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJpdERlbWFuZCArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgYml0RGVtYW5kICs9IDI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiB0aGVyZSBhcmUgbWFueSBwb3NzaWJpbGl0aWVzIHRvIHVzZSB0aGlzIG1lY2hhbmlzbS4gICovCiAgICBzd2l0Y2goIGhBc3MtPnZhck1vZGUgKSB7CiAgICBjYXNlIExBVE1WQVJfU0lNUExFX1NFUVVFTkNFOiB7CiAgICAgIC8qIFVzZSB0aGUgc2VxdWVuY2UgZ2VuZXJhdGVkIGJ5IHRoZSBlbmNvZGVyICovCiAgICAgIC8vaW50IHN0cmVhbUNudFBvc2l0aW9uID0gdHJhbnNwb3J0RW5jX1NldFdyaXRlUG9pbnRlciggaEFzcy0+aEFzc2VtYmxlLCAwICk7CiAgICAgIC8vaW50IHN0cmVhbUNudFBvc2l0aW9uID0gRkRLZ2V0VmFsaWRCaXRzKCBoQXNzLT5oQXNzZW1ibGUgKTsKICAgICAgYml0RGVtYW5kKz00OwoKICAgICAgaEFzcy0+dmFyU3RyZWFtQ250ID0gMDsKICAgICAgZm9yKCBwcm9nPTA7IHByb2c8aEFzcy0+bm9Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICAgICAgZm9yKCBsYXllcj0wOyBsYXllcjxMQVRNX01BWF9MQVlFUlM7IGxheWVyKysgKSB7CiAgICAgICAgICBMQVRNX0xBWUVSX0lORk8gKnBfbGluZm8gPSAmKGhBc3MtPm1fbGluZm9bcHJvZ11bbGF5ZXJdKTsKCiAgICAgICAgICBpZiggcF9saW5mby0+c3RyZWFtSUQgPj0gMCApIHsKCiAgICAgICAgICAgIGJpdERlbWFuZCs9NDsgLyogc3RyZWFtSUQgKi8KICAgICAgICAgICAgc3dpdGNoKCBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUgKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBzdHJlYW1EYXRhTGVuZ3RoIC09IGJpdERlbWFuZCA7CiAgICAgICAgICAgICAgd2hpbGUoIHN0cmVhbURhdGFMZW5ndGggPj0gKDI1NTw8MykgKSB7CiAgICAgICAgICAgICAgICBiaXREZW1hbmQrPTg7CiAgICAgICAgICAgICAgICBzdHJlYW1EYXRhTGVuZ3RoIC09ICgyNTU8PDMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgYml0RGVtYW5kICs9IDg7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgLypiaXREZW1hbmQgKz0gMTsgZW5kRmxhZwogICAgICAgICAgICAgIGJyZWFrOyovCgogICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgY2FzZSA2OgoKICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgcmV0dXJuICAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhBc3MtPnZhclN0cmVhbUNudCsrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBiaXREZW1hbmQrPTQ7CiAgICAgIC8vdHJhbnNwb3J0RW5jX1VwZGF0ZUJpdHN0cmVhbUZpZWxkKCBoQXNzLT5oQXNzZW1ibGUsIHN0cmVhbUNudFBvc2l0aW9uLCBoQXNzLT52YXJTdHJlYW1DbnQtMSwgNCApOwogICAgICAvL1VJTlQgcG9zID0gc3RyZWFtQ250UG9zaXRpb24tRkRLZ2V0VmFsaWRCaXRzKGhBc3MtPmhBc3NlbWJsZSk7CiAgICAgIC8vRkRLcHVzaEJhY2soIGhBc3MtPmhBc3NlbWJsZSwgIHBvcyk7CiAgICAgIC8vRkRLd3JpdGVCaXRzKCBoQXNzLT5oQXNzZW1ibGUsIGhBc3MtPnZhclN0cmVhbUNudC0xLCA0KTsKICAgICAgLy9GREtwdXNoRm9yKCBoQXNzLT5oQXNzZW1ibGUsIHBvcy00KTsKICAgIH0KICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiAgMDsKICAgIH0KICB9CgogIHJldHVybiBiaXREZW1hbmQgOwp9CgpUUkFOU1BPUlRFTkNfRVJST1IKQ3JlYXRlU3RyZWFtTXV4Q29uZmlnKAogICAgICAgICAgICAgICAgICAgICAgSEFORExFX0xBVE1fU1RSRUFNIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgICAgICAgICAgICAgICBDU1RwQ2FsbEJhY2tzICpjYgogICAgICAgICAgICAgICAgICAgICApCnsKICBJTlQgc3RyZWFtSURjbnQsIHRtcDsKICBpbnQgbGF5ZXIsIHByb2c7CgogIFVTSE9SVCBjb3JlRnJhbWVPZmZzZXQ9MDsKCiAgaEFzcy0+dGFyYUJ1ZmZlckZ1bGxuZXNzICA9IDB4RkY7CiAgaEFzcy0+YXVkaW9NdXhWZXJzaW9uQSAgICA9IDA7IC8qIGZvciBmdXR1cmUgZXh0ZW5zaW9ucyAqLwogIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMgPSAwOwoKICBGREt3cml0ZUJpdHMoIGhCcywgaEFzcy0+YXVkaW9NdXhWZXJzaW9uLCAxICk7ICAgICAgICAgICAgICAgICAgIC8qIGF1ZGlvTXV4VmVyc2lvbiAqLwogIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMgKz0gMTsKCiAgaWYgKCBoQXNzLT5hdWRpb011eFZlcnNpb24gPT0gMSApIHsKICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5hdWRpb011eFZlcnNpb25BLCAxICk7ICAgICAgICAgICAgICAgIC8qIGF1ZGlvTXV4VmVyc2lvbkEgKi8KICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTE7CiAgfQoKICBpZiAoIGhBc3MtPmF1ZGlvTXV4VmVyc2lvbkEgPT0gMCApCiAgewogICAgaWYgKCBoQXNzLT5hdWRpb011eFZlcnNpb24gPT0gMSApIHsKICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9IHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZSggaEJzLCBoQXNzLT50YXJhQnVmZmVyRnVsbG5lc3MgKTsvKiB0YXJhQnVmZmVyRnVsbG5lc3MgKi8KICAgIH0KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nID8gMTowLCAxICk7IC8qIGFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5ub1N1YmZyYW1lcy0xLCA2ICk7ICAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBTdWJmcmFtZXMgKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5ub1Byb2dyYW0tMSwgNCApOyAgICAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBQcm9ncmFtcyAqLwoKICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTExOwoKICAgIHN0cmVhbUlEY250ID0gMDsKICAgIGZvciggcHJvZz0wOyBwcm9nPGhBc3MtPm5vUHJvZ3JhbTsgcHJvZysrICkgewogICAgICBpbnQgdHJhbnNMYXllciA9IDA7CgogICAgICBGREt3cml0ZUJpdHMoIGhCcywgaEFzcy0+bm9MYXllcltwcm9nXS0xLCAzICk7CiAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTM7CgogICAgICBmb3IoIGxheWVyPTA7IGxheWVyPExBVE1fTUFYX0xBWUVSUzsgbGF5ZXIrKyApIHsKICAgICAgICBMQVRNX0xBWUVSX0lORk8gICAqcF9saW5mbyA9ICYoaEFzcy0+bV9saW5mb1twcm9nXVtsYXllcl0pOwogICAgICAgIENPREVSX0NPTkZJRyAqcF9sY2kgICA9IGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl07CgogICAgICAgIHBfbGluZm8tPnN0cmVhbUlEID0gLTE7CgogICAgICAgIGlmKCBoQXNzLT5jb25maWdbcHJvZ11bbGF5ZXJdICE9IE5VTEwgKSB7CiAgICAgICAgICBpbnQgdXNlU2FtZUNvbmZpZyA9IDA7CgogICAgICAgICAgaWYoIHRyYW5zTGF5ZXIgPiAwICkgewogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgdXNlU2FtZUNvbmZpZyA/IDEgOiAwLCAxICk7CiAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTE7CiAgICAgICAgICB9CiAgICAgICAgICBpZiggKHVzZVNhbWVDb25maWcgPT0gMCkgfHwgKHRyYW5zTGF5ZXI9PTApICkgewogICAgICAgICAgICBjb25zdCBVSU5UIGFsaWduQW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogICAgICAgICAgICB0cmFuc3BvcnRFbmNfd3JpdGVBU0MoCiAgICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICAgIGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl0sCiAgICAgICAgICAgICAgICAgICAgY2IKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgaWYgKCBoQXNzLT5hdWRpb011eFZlcnNpb24gPT0gMSApIHsKICAgICAgICAgICAgICBVSU5UIGFzY0xlbiA9IHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZShoQnMsIDApOwogICAgICAgICAgICAgIEZES2J5dGVBbGlnbihoQnMsIGFsaWduQW5jaG9yKTsKICAgICAgICAgICAgICBhc2NMZW4gPSBGREtnZXRWYWxpZEJpdHMoaEJzKSAtIGFsaWduQW5jaG9yIC0gYXNjTGVuOwogICAgICAgICAgICAgIEZES3B1c2hCYWNrKGhCcywgRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBhbGlnbkFuY2hvcik7CgogICAgICAgICAgICAgIHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZShoQnMsIGFzY0xlbik7CgogICAgICAgICAgICAgIHRyYW5zcG9ydEVuY193cml0ZUFTQygKICAgICAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgIGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl0sCiAgICAgICAgICAgICAgICAgICAgICBjYgogICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgRkRLYnl0ZUFsaWduKGhCcywgYWxpZ25BbmNob3IpOyAvKiBhc2MgbGVuZ3RoIGZpbGxiaXRzICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMgKz0gRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBhbGlnbkFuY2hvcjsgLyogYWRkIGFzYyBsZW5ndGggdG8gc21jIHN1bW1hcnkgKi8KICAgICAgICAgIH0KICAgICAgICAgIHRyYW5zTGF5ZXIrKzsKCiAgICAgICAgICBpZiggIWhBc3MtPmFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgKSB7CiAgICAgICAgICAgIGlmKCBzdHJlYW1JRGNudCA+PSBMQVRNX01BWF9TVFJFQU1fSUQgKQogICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICB9CiAgICAgICAgICBwX2xpbmZvLT5zdHJlYW1JRCA9IHN0cmVhbUlEY250Kys7CgogICAgICAgICAgc3dpdGNoKCBwX2xjaS0+YW90ICkgewogICAgICAgICAgY2FzZSBBT1RfQUFDX01BSU4gICAgICA6CiAgICAgICAgICBjYXNlIEFPVF9BQUNfTEMgICAgICAgIDoKICAgICAgICAgIGNhc2UgQU9UX0FBQ19TU1IgICAgICAgOgogICAgICAgICAgY2FzZSBBT1RfQUFDX0xUUCAgICAgICA6CiAgICAgICAgICBjYXNlIEFPVF9BQUNfU0NBTCAgICAgIDoKICAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRCAgICAgOgogICAgICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRCAgICA6CiAgICAgICAgICBjYXNlIEFPVF9VU0FDOgogICAgICAgICAgICBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUgPSAwOwoKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIHBfbGluZm8tPmZyYW1lTGVuZ3RoVHlwZSwgMyApOyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZyYW1lTGVuZ3RoVHlwZSAqLwogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgYnVmZmVyRnVsbG5lc3MsIDggKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWZmZXJGdWxsbmVzcyAqLwogICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0xMTsKCiAgICAgICAgICAgIGlmICggIWhBc3MtPmFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgKSB7CiAgICAgICAgICAgICAgQ09ERVJfQ09ORklHICpwX2xjaV9wcmV2ID0gaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyLTFdOwogICAgICAgICAgICAgIGlmICggKChwX2xjaS0+YW90ID09IEFPVF9BQUNfU0NBTCkgfHwgKHBfbGNpLT5hb3QgPT0gQU9UX0VSX0FBQ19TQ0FMKSkgJiYKICAgICAgICAgICAgICAgICAgICgocF9sY2lfcHJldi0+YW90ID09IEFPVF9DRUxQKSB8fCAocF9sY2lfcHJldi0+YW90ID09IEFPVF9FUl9DRUxQKSkgKSB7CiAgICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgY29yZUZyYW1lT2Zmc2V0LCA2ICk7ICAgICAgICAgICAgICAgICAgICAgIC8qIGNvcmVGcmFtZU9mZnNldCAqLwogICAgICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9NjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBBT1RfVFdJTl9WUToKICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlID0gMTsKICAgICAgICAgICAgdG1wID0gKCAocF9sY2ktPmJpdHNGcmFtZSs3KSA+PiAzICkgLSAyMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHJhbnNtaXNzaW9uIGZyYW1lIGxlbmd0aCBpbiBieXRlcyAqLwogICAgICAgICAgICBpZiggKHRtcCA8IDApICkgewogICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9UUkFOU01JU1NJT05fRlJBTUVfTEVOR1RIOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUsIDMgKTsgICAgICAgICAgLyogZnJhbWVMZW5ndGhUeXBlICovCiAgICAgICAgICAgIEZES3dyaXRlQml0cyggaEJzLCB0bXAsIDkgKTsKICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MTI7CgogICAgICAgICAgICBwX2xpbmZvLT5mcmFtZUxlbmd0aEJpdHMgPSAodG1wKzIwKSA8PCAzOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIEFPVF9DRUxQOgogICAgICAgICAgICBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUgPSA0OwogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlLCAzICk7ICAgICAgICAgIC8qIGZyYW1lTGVuZ3RoVHlwZSAqLwogICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0zOwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgICAgZm9yKCBpPTA7IGk8NjI7IGkrKyApIHsKICAgICAgICAgICAgICAgIGlmKCBjZWxwRnJhbWVMZW5ndGhUYWJsZVtpXSA9PSBwX2xjaS0+Yml0c0ZyYW1lICkKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmKCBpPj02MiApIHsKICAgICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9DRUxQX0ZSQU1FX0xFTkdUSDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBpLCA2ICk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBDRUxQZnJhbWVMZW5ndGhUYWJlbEluZGV4ICovCiAgICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9NjsKICAgICAgICAgICAgfQogICAgICAgICAgICBwX2xpbmZvLT5mcmFtZUxlbmd0aEJpdHMgPSBwX2xjaS0+Yml0c0ZyYW1lOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIEFPVF9IVlhDOgogICAgICAgICAgICBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUgPSA2OwogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlLCAzICk7ICAgICAgICAgIC8qIGZyYW1lTGVuZ3RoVHlwZSAqLwogICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0zOwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgaW50IGk7CgogICAgICAgICAgICAgIGlmKCBwX2xjaS0+Yml0c0ZyYW1lID09IDQwICkgewogICAgICAgICAgICAgICAgaSA9IDA7CiAgICAgICAgICAgICAgfSBlbHNlIGlmKCBwX2xjaS0+Yml0c0ZyYW1lID09IDgwICkgewogICAgICAgICAgICAgICAgaSA9IDE7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9GUkFNRV9CSVRTOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgaSwgMSApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogSFZYQ2ZyYW1lTGVuZ3RoVGFibGVJbmRleCAqLwogICAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhCaXRzID0gcF9sY2ktPmJpdHNGcmFtZTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBBT1RfTlVMTF9PQkpFQ1Q6CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfQU9UOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIEZES3dyaXRlQml0cyggaEJzLCAoaEFzcy0+b3RoZXJEYXRhTGVuQnl0ZXM+MCkgPyAxOjAsIDEgKTsgICAgICAvKiBvdGhlckRhdGFQcmVzZW50ICovCiAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0xOwoKICAgIGlmKCBoQXNzLT5vdGhlckRhdGFMZW5CeXRlcyA+IDAgKSB7CgogICAgICBJTlQgb3RoZXJEYXRhTGVuVG1wID0gaEFzcy0+b3RoZXJEYXRhTGVuQnl0ZXM7CiAgICAgIElOVCBlc2NDbnQgPSAwOwogICAgICBJTlQgb3RoZXJEYXRhTGVuRXNjID0gMTsKCiAgICAgIHdoaWxlKG90aGVyRGF0YUxlblRtcCkgewogICAgICAgIG90aGVyRGF0YUxlblRtcCA+Pj0gODsKICAgICAgICBlc2NDbnQgKys7CiAgICAgIH0KCiAgICAgIGRvIHsKICAgICAgICBvdGhlckRhdGFMZW5UbXAgPSAoaEFzcy0+b3RoZXJEYXRhTGVuQnl0ZXM+Pihlc2NDbnQqOCkpICYgMHhGRjsKICAgICAgICBlc2NDbnQtLTsKICAgICAgICBvdGhlckRhdGFMZW5Fc2MgPSBlc2NDbnQ+MDsKCiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIG90aGVyRGF0YUxlbkVzYywgMSApOwogICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBvdGhlckRhdGFMZW5UbXAsIDggKTsKICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz05OwogICAgICB9IHdoaWxlKG90aGVyRGF0YUxlbkVzYyk7CiAgICB9CgogICAgewogICAgICBVU0hPUlQgY3JjQ2hlY2tQcmVzZW50PTA7CiAgICAgIFVTSE9SVCBjcmNDaGVja1N1bT0wOwoKICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIGNyY0NoZWNrUHJlc2VudCwgMSApOyAgICAgICAgICAgICAgIC8qIGNyY0NoZWNrUHJlc2VudCAqLwogICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0xOwogICAgICBpZiAoIGNyY0NoZWNrUHJlc2VudCApewogICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBjcmNDaGVja1N1bSwgOCApOyAgICAgICAgICAgICAgICAgLyogY3JjQ2hlY2tTdW0gKi8KICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz04OwogICAgICB9CiAgICB9CgogIH0gZWxzZSB7ICAvKiBpZiAoIGF1ZGlvTXV4VmVyc2lvbkEgPT0gMCApICovCgogICAgLyogZm9yIGZ1dHVyZSBleHRlbnNpb25zICovCgogIH0KCiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKCnN0YXRpYyBUUkFOU1BPUlRFTkNfRVJST1IKV3JpdGVBdVBheWxvYWRMZW5ndGhJbmZvKCBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQml0U3RyZWFtLCBpbnQgQXVMZW5ndGhCaXRzICkKewogIGludCByZXN0Qnl0ZXM7CgogIGlmKCBBdUxlbmd0aEJpdHMgJSA4ICkKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9BVV9MRU5HVEg7CgogIHdoaWxlKCBBdUxlbmd0aEJpdHMgPj0gMjU1KjggKSB7CiAgICBGREt3cml0ZUJpdHMoIGhCaXRTdHJlYW0sIDI1NSwgOCApOyAgLyogMjU1IHNob3dzIGluY29tcGxldGUgQVUgKi8KICAgIEF1TGVuZ3RoQml0cyAtPSAoMjU1KjgpOwogIH0KCiAgcmVzdEJ5dGVzID0gKEF1TGVuZ3RoQml0cykgPj4gMzsKICBGREt3cml0ZUJpdHMoIGhCaXRTdHJlYW0sIHJlc3RCeXRlcywgOCApOwoKICByZXR1cm4gVFJBTlNQT1JURU5DX09LOwp9CgpzdGF0aWMKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19MYXRtU2V0TnJPZlN1YmZyYW1lcyggSEFORExFX0xBVE1fU1RSRUFNIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub1N1YmZyYW1lc19uZXh0KSAgICAvKiBuciBvZiBhY2Nlc3MgdW5pdHMgLyBwYXlsb2FkcyB3aXRoaW4gYSBsYXRtIGZyYW1lICovCnsKICAvKiBzYW5pdHkgY2hrICovCiAgaWYgKG5vU3ViZnJhbWVzX25leHQgPCAxIHx8IG5vU3ViZnJhbWVzX25leHQgPiBNQVhfTlJfT0ZfU1VCRlJBTUVTKSB7CiAgICByZXR1cm4gVFJBTlNQT1JURU5DX0xBVE1fSU5WQUxJRF9OUl9PRl9TVUJGUkFNRVM7CiAgfQoKICBoQXNzLT5ub1N1YmZyYW1lc19uZXh0ID0gbm9TdWJmcmFtZXNfbmV4dDsKCiAgLyogaWYgYXQgc3RhcnQgdGhlbiB3ZSBjYW4gdGFrZSBvdmVyIHRoZSB2YWx1ZSBpbW1lZGlhdGVseSwgb3RoZXJ3aXNlIHdlIGhhdmUgdG8gd2FpdCBmb3IgdGhlIG5leHQgU01DICovCiAgaWYgKCAoaEFzcy0+c3ViRnJhbWVDbnQgPT0gMCkgJiYgKGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPT0gMCkgKSB7CiAgICBoQXNzLT5ub1N1YmZyYW1lcyA9IG5vU3ViZnJhbWVzX25leHQ7CiAgfQoKICByZXR1cm4gVFJBTlNQT1JURU5DX09LOwp9CgpzdGF0aWMKaW50IGFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcoIEhBTkRMRV9MQVRNX1NUUkVBTSBoQXNzLCBVQ0hBUiBub1Byb2dyYW0sIFVDSEFSIG5vTGF5ZXJbXSAvKiByZXR1cm4gKi8gKQp7CiAgaW50IHByb2csIGxheWVyOwoKICBzaWduZWQgaW50IGxhc3ROb1NhbXBsZXMgICA9IC0xOwogIHNpZ25lZCBpbnQgbWluRnJhbWVTYW1wbGVzID0gRkRLX0lOVF9NQVg7CiAgc2lnbmVkIGludCBtYXhGcmFtZVNhbXBsZXMgPSAwOwoKICBzaWduZWQgaW50IGhpZ2hlc3RTYW1wbGluZ1JhdGUgPSAtMTsKCiAgZm9yKCBwcm9nPTA7IHByb2c8bm9Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICBub0xheWVyW3Byb2ddID0gMDsKCiAgICBmb3IoIGxheWVyPTA7IGxheWVyPExBVE1fTUFYX0xBWUVSUzsgbGF5ZXIrKyApCiAgICB7CiAgICAgIGlmKCBoQXNzLT5jb25maWdbcHJvZ11bbGF5ZXJdICE9IE5VTEwgKQogICAgICB7CiAgICAgICAgSU5UIGhzZlNhbXBsZXNGcmFtZTsKCiAgICAgICAgbm9MYXllcltwcm9nXSsrOwoKICAgICAgICBpZiggaGlnaGVzdFNhbXBsaW5nUmF0ZSA8IDAgKQogICAgICAgICAgaGlnaGVzdFNhbXBsaW5nUmF0ZSA9IGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl0tPnNhbXBsaW5nUmF0ZTsKCiAgICAgICAgaHNmU2FtcGxlc0ZyYW1lID0gaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXS0+c2FtcGxlc1BlckZyYW1lICAqIGhpZ2hlc3RTYW1wbGluZ1JhdGUgLyBoQXNzLT5jb25maWdbcHJvZ11bbGF5ZXJdLT5zYW1wbGluZ1JhdGU7CgogICAgICAgIGlmKCBoc2ZTYW1wbGVzRnJhbWUgPD0gbWluRnJhbWVTYW1wbGVzICkgbWluRnJhbWVTYW1wbGVzID0gaHNmU2FtcGxlc0ZyYW1lOwogICAgICAgIGlmKCBoc2ZTYW1wbGVzRnJhbWUgPj0gbWF4RnJhbWVTYW1wbGVzICkgbWF4RnJhbWVTYW1wbGVzID0gaHNmU2FtcGxlc0ZyYW1lOwoKICAgICAgICBpZiggbGFzdE5vU2FtcGxlcyA9PSAtMSApIHsKICAgICAgICAgIGxhc3ROb1NhbXBsZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gaHNmU2FtcGxlc0ZyYW1lOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiggaHNmU2FtcGxlc0ZyYW1lICE9IGxhc3ROb1NhbXBsZXMgKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIDE7Cn0KCi8qKgogKiBJbml0aWFsaXplIExBVE0vTE9BUyBTdHJlYW0gYW5kIGFkZCBsYXllciAwIGF0IHByb2dyYW0gMC4KICovCnN0YXRpYwpUUkFOU1BPUlRFTkNfRVJST1IgdHJhbnNwb3J0RW5jX0luaXRMYXRtU3RyZWFtKCBIQU5ETEVfTEFUTV9TVFJFQU0gaEFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgIGZyYWN0RGVsYXlQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduZWQgaW50ICAgICAgICAgbXV4Q29uZmlnUGVyaW9kLCAvKiBpbnNlcnQgc2V0dXAgZGF0YSBldmVyeSBtdXhDb25maWdQZXJpb2QgZnJhbWVzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICBhdWRpb011eFZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQU5TUE9SVF9UWVBFICAgICB0dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgVFJBTlNQT1JURU5DX0VSUk9SIEVycm9yU3RhdHVzID0gVFJBTlNQT1JURU5DX09LOwoKICBpZiAoaEFzcyA9PSBOVUxMKQogICAgcmV0dXJuIFRSQU5TUE9SVEVOQ19JTlZBTElEX1BBUkFNRVRFUjsKCiAgaEFzcy0+dHQgPSB0dDsKCiAgaEFzcy0+bm9Qcm9ncmFtID0gMTsKCiAgaEFzcy0+YXVkaW9NdXhWZXJzaW9uID0gYXVkaW9NdXhWZXJzaW9uOwoKICAvKiBGaWxsIG5vTGF5ZXIgYXJyYXkgdXNpbmcgaEFzcy0+Y29uZmlnICovCiAgaEFzcy0+YWxsU3RyZWFtc1NhbWVUaW1lRnJhbWluZyA9IGFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcoIGhBc3MsIGhBc3MtPm5vUHJvZ3JhbSwgaEFzcy0+bm9MYXllciApOwogIC8qIE9ubHkgYWxsU3RyZWFtc1NhbWVUaW1lRnJhbWluZz09MSBpcyBzdXBwb3J0ZWQgKi8KICBGREtfQVNTRVJUKGhBc3MtPmFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcpOwoKICBoQXNzLT5mcmFjdERlbGF5UHJlc2VudCA9IGZyYWN0RGVsYXlQcmVzZW50OwogIGhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzID0gMDsKCiAgaEFzcy0+dmFyTW9kZSA9IExBVE1WQVJfU0lNUExFX1NFUVVFTkNFOwoKICAvKiBpbml0aWFsaXplIGNvdW50ZXJzICovCiAgaEFzcy0+c3ViRnJhbWVDbnQgICAgICAgICAgICAgICAgICA9IDA7CiAgaEFzcy0+bm9TdWJmcmFtZXMgICAgICAgICAgICAgICAgICA9IERFRkFVTFRfTEFUTV9OUl9PRl9TVUJGUkFNRVM7CiAgaEFzcy0+bm9TdWJmcmFtZXNfbmV4dCAgICAgICAgICAgICA9IERFRkFVTFRfTEFUTV9OUl9PRl9TVUJGUkFNRVM7CgogIC8qIHN5bmMgbGF5ZXIgcmVsYXRlZCAqLwogIGhBc3MtPmF1ZGlvTXV4TGVuZ3RoQnl0ZXMgICAgID0gMDsKCiAgaEFzcy0+bGF0bUZyYW1lQ291bnRlciAgICAgICAgPSAwOwogIGhBc3MtPm11eENvbmZpZ1BlcmlvZCA9IG11eENvbmZpZ1BlcmlvZDsKCiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9CgoKLyoqCiAqCiAqLwpVSU5UIHRyYW5zcG9ydEVuY19MYXRtQ291bnRUb3RhbEJpdERlbWFuZEhlYWRlciAoIEhBTkRMRV9MQVRNX1NUUkVBTSBoQXNzICwgdW5zaWduZWQgaW50IHN0cmVhbURhdGFMZW5ndGggKQp7CiAgVUlOVCBiaXREZW1hbmQgPSAwOwoKICBzd2l0Y2ggKGhBc3MtPnR0KSB7CiAgY2FzZSBUVF9NUDRfTE9BUzoKICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgaWYgKGhBc3MtPnN1YkZyYW1lQ250ID09IDApIHsKICAgICAgYml0RGVtYW5kICA9IHRyYW5zcG9ydEVuY19MYXRtQ291bnRGaXhCaXREZW1hbmRIZWFkZXIgKCBoQXNzICk7CiAgICB9CiAgICBiaXREZW1hbmQgKz0gdHJhbnNwb3J0RW5jX0xhdG1Db3VudFZhckJpdERlbWFuZEhlYWRlciAoIGhBc3MgLCBzdHJlYW1EYXRhTGVuZ3RoIC8qLSBiaXREZW1hbmQqLyk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgYnJlYWs7CiAgfQoKICByZXR1cm4gYml0RGVtYW5kOwp9CgpzdGF0aWMgVFJBTlNQT1JURU5DX0VSUk9SCkFkdmFuY2VBdWRpb011eEVsZW1lbnQgKAogICAgICAgIEhBTkRMRV9MQVRNX1NUUkVBTSAgIGhBc3MsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgIGF1Qml0cywKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBidWZmZXJGdWxsbmVzcywKICAgICAgICBDU1RwQ2FsbEJhY2tzICAgICpjYgogICAgICAgICkKewogIFRSQU5TUE9SVEVOQ19FUlJPUiBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVEVOQ19PSzsKICBpbnQgaW5zZXJ0TXV4U2V0dXA7CgogIC8qIEluc2VydCBzZXR1cCBkYXRhIHRvIGFzc2VtYmxlIEJ1ZmZlciAqLwogIGlmIChoQXNzLT5zdWJGcmFtZUNudCA9PSAwKQogIHsKICAgIGlmIChoQXNzLT5tdXhDb25maWdQZXJpb2QgPiAwKSB7CiAgICAgIGluc2VydE11eFNldHVwID0gKGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPT0gMCk7CiAgICB9IGVsc2UgIHsKICAgICAgaW5zZXJ0TXV4U2V0dXAgPSAwOwogICAgfQoKICAgIGlmIChoQXNzLT50dCAhPSBUVF9NUDRfTEFUTV9NQ1AwKSB7CiAgICAgIGlmKCBpbnNlcnRNdXhTZXR1cCApIHsKICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgMCwgMSApOyAgLyogdXNlU2FtZVN0cmVhbU11eCB1c2VOZXdTdHJlYW1NdXggKi8KICAgICAgICBDcmVhdGVTdHJlYW1NdXhDb25maWcoaEFzcywgaEJzLCBidWZmZXJGdWxsbmVzcywgY2IpOwogICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBUUkFOU1BPUlRFTkNfT0spCiAgICAgICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIDEsIDEgKTsgICAvKiB1c2VTYW1lU3RyZWFtTXV4ICovCiAgICAgIH0KICAgIH0KICB9CgogIC8qIFBheWxvYWRMZW5ndGhJbmZvICovCiAgewogICAgaW50IHByb2csIGxheWVyOwoKICAgIGZvciAocHJvZyA9IDA7IHByb2cgPCBoQXNzLT5ub1Byb2dyYW07IHByb2crKykgewogICAgICBmb3IgKGxheWVyID0gMDsgbGF5ZXIgPCBoQXNzLT5ub0xheWVyW3Byb2ddOyBsYXllcisrKSB7CiAgICAgICAgRXJyb3JTdGF0dXMgPSBXcml0ZUF1UGF5bG9hZExlbmd0aEluZm8oIGhCcywgYXVCaXRzICk7CiAgICAgICAgaWYgKEVycm9yU3RhdHVzICE9IFRSQU5TUE9SVEVOQ19PSykKICAgICAgICAgIHJldHVybiBFcnJvclN0YXR1czsKICAgICAgfQogICAgfQogIH0KICAvKiBBdCB0aGlzIHBvaW50IGNvbWVzIHRoZSBhY2Nlc3MgdW5pdC4gKi8KCiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKVFJBTlNQT1JURU5DX0VSUk9SCnRyYW5zcG9ydEVuY19MYXRtV3JpdGUgKAogICAgICAgIEhBTkRMRV9MQVRNX1NUUkVBTSAgICBoQXNzLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICBoQnMsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgIGF1Qml0cywKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAgICAgKmNiCiAgICAgICAgKQp7CiAgVFJBTlNQT1JURU5DX0VSUk9SIEVycm9yU3RhdHVzOwoKICBpZiAoaEFzcy0+c3ViRnJhbWVDbnQgPT0gMCkgewogICAgLyogU3RhcnQgbmV3IGZyYW1lICovCiAgICBGREtyZXNldEJpdGJ1ZmZlcihoQnMsIEJTX1dSSVRFUik7CiAgfQoKICBoQXNzLT5sYXRtU3ViZnJhbWVTdGFydCA9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICAvKiBJbnNlcnQgc3luY3dvcmQgYW5kIHN5bmN3b3JkIGRpc3RhbmNlCiAgICAgLSBvbmx5IGlmIGxvYXMKICAgICAtIHdlIG11c3QgdXBkYXRlIHRoZSBzeW5jd29yZCBkaXN0YW5jZSAoPWF1ZGlvbXV4bGVuZ3RoYnl0ZXMpIGxhdGVyCiAgICovCiAgaWYoIGhBc3MtPnR0ID09IFRUX01QNF9MT0FTICYmIGhBc3MtPnN1YkZyYW1lQ250ID09IDApCiAgewogICAgLyogU3RhcnQgbmV3IExPQVMgZnJhbWUgKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCAweDJCNywgMTEgKTsKICAgIGhBc3MtPmF1ZGlvTXV4TGVuZ3RoQnl0ZXMgPSAwOwogICAgaEFzcy0+YXVkaW9NdXhMZW5ndGhCeXRlc1BvcyA9IEZES2dldFZhbGlkQml0cyggaEJzICk7ICAvKiBzdG9yZSByZWFkIHBvaW50ZXIgcG9zaXRpb24gKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzLCAxMyApOwogIH0KCiAgRXJyb3JTdGF0dXMgPSBBZHZhbmNlQXVkaW9NdXhFbGVtZW50KAogICAgICAgICAgaEFzcywKICAgICAgICAgIGhCcywKICAgICAgICAgIGF1Qml0cywKICAgICAgICAgIGJ1ZmZlckZ1bGxuZXNzLAogICAgICAgICAgY2IKICAgICAgICAgICk7CgogIGlmIChFcnJvclN0YXR1cyAhPSBUUkFOU1BPUlRFTkNfT0spCiAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKdm9pZCB0cmFuc3BvcnRFbmNfTGF0bUFkanVzdFN1YmZyYW1lQml0cyhIQU5ETEVfTEFUTV9TVFJFQU0gICAgaEFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAqYml0cykKewogIC8qIFN1YnN0cmFjdCBiaXRzIGZyb20gcG9zc2libGUgcHJldmlvdXMgc3ViZnJhbWUgKi8KICAqYml0cyAtPSBoQXNzLT5sYXRtU3ViZnJhbWVTdGFydDsKICAvKiBBZGQgZmlsbCBiaXRzICovCiAgaWYgKGhBc3MtPnN1YkZyYW1lQ250ID09IDApCiAgICAqYml0cyArPSBoQXNzLT5maWxsQml0czsKfQoKCnZvaWQgdHJhbnNwb3J0RW5jX0xhdG1HZXRGcmFtZShIQU5ETEVfTEFUTV9TVFJFQU0gICAgaEFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgICAgICAqYnl0ZXMpCnsKCiAgaEFzcy0+c3ViRnJhbWVDbnQrKzsKICBpZiAoaEFzcy0+c3ViRnJhbWVDbnQgPj0gaEFzcy0+bm9TdWJmcmFtZXMpCiAgewoKICAgIC8qIEFkZCBMT0FTIGZyYW1lIGxlbmd0aCBpZiByZXF1aXJlZC4gKi8KICAgIGlmIChoQXNzLT50dCA9PSBUVF9NUDRfTE9BUykKICAgIHsKICAgICAgaW50IGxhdG1CeXRlczsKCiAgICAgIGxhdG1CeXRlcyA9IChGREtnZXRWYWxpZEJpdHMoaEJzKSs3KSA+PiAzOwoKICAgICAgLyogd3JpdGUgbGVuZ3RoIGluZm8gaW50byBhc3NlbWJsZXIgYnVmZmVyICovCiAgICAgIGhBc3MtPmF1ZGlvTXV4TGVuZ3RoQnl0ZXMgPSBsYXRtQnl0ZXMgLSAzOyAvKiAzPVN5bmN3b3JkICsgbGVuZ3RoICovCiAgICAgIHsKICAgICAgICBGREtfQklUU1RSRUFNIHRtcEJ1ZjsKCiAgICAgICAgRkRLaW5pdEJpdFN0cmVhbSggJnRtcEJ1ZiwgaEJzLT5oQml0QnVmLkJ1ZmZlciwgaEJzLT5oQml0QnVmLmJ1ZlNpemUsIDAsIEJTX1dSSVRFUiApIDsKICAgICAgICBGREtwdXNoRm9yKCAmdG1wQnVmLCBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzUG9zICk7CiAgICAgICAgRkRLd3JpdGVCaXRzKCAmdG1wQnVmLCBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzLCAxMyApOwogICAgICAgIEZES3N5bmNDYWNoZSggJnRtcEJ1ZiApOwogICAgICB9CiAgICB9CgogICAgLyogV3JpdGUgQXVkaW9NdXhFbGVtZW50IGJ5dGUgYWxpZ25tZW50IGZpbGwgYml0cyAqLwogICAgRkRLd3JpdGVCaXRzKGhCcywgMCwgaEFzcy0+ZmlsbEJpdHMpOwoKICAgIEZES19BU1NFUlQoIChGREtnZXRWYWxpZEJpdHMoaEJzKSAlIDgpID09IDApOwoKICAgIGhBc3MtPnN1YkZyYW1lQ250ID0gMDsKCiAgICBGREtzeW5jQ2FjaGUoaEJzKTsKICAgICpieXRlcyA9IChGREtnZXRWYWxpZEJpdHMoaEJzKSArIDcpPj4zOwogICAgLy9GREtmZXRjaEJ1ZmZlcihoQnMsIGJ1ZmZlciwgKFVJTlQqKWJ5dGVzKTsKCiAgICBpZiAoaEFzcy0+bXV4Q29uZmlnUGVyaW9kID4gMCkKICAgIHsKICAgICAgaEFzcy0+bGF0bUZyYW1lQ291bnRlcisrOwoKICAgICAgaWYgKGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPj0gaEFzcy0+bXV4Q29uZmlnUGVyaW9kKSB7CiAgICAgICAgaEFzcy0+bGF0bUZyYW1lQ291bnRlciA9IDA7CiAgICAgICAgaEFzcy0+bm9TdWJmcmFtZXMgPSBoQXNzLT5ub1N1YmZyYW1lc19uZXh0OwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIE5vIGRhdGEgdGhpcyB0aW1lICovCiAgICAqYnl0ZXMgPSAwOwogIH0KfQoKLyoqCiAqIEluaXQgTEFUTS9MT0FTCiAqLwpUUkFOU1BPUlRFTkNfRVJST1IgdHJhbnNwb3J0RW5jX0xhdG1fSW5pdCgKICAgICAgICBIQU5ETEVfTEFUTV9TVFJFQU0gIGhBc3MsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgIENPREVSX0NPTkZJRyAgKmxheWVyQ29uZmlnLAogICAgICAgIFVJTlQgYXVkaW9NdXhWZXJzaW9uLAogICAgICAgIFRSQU5TUE9SVF9UWVBFIHR0LAogICAgICAgIENTVHBDYWxsQmFja3MgKmNiCiAgICAgICAgKQp7CiAgVFJBTlNQT1JURU5DX0VSUk9SIEVycm9yU3RhdHVzOwogIGludCBmcmFjdERlbGF5UHJlc2VudCA9IDA7CiAgaW50IHByb2csIGxheWVyOwoKICBpbnQgc2V0dXBEYXRhRGlzdGFuY2VGcmFtZXMgPSBsYXllckNvbmZpZy0+aGVhZGVyUGVyaW9kOwoKICBGREtfQVNTRVJUKHNldHVwRGF0YURpc3RhbmNlRnJhbWVzPj0wKTsKCiAgZm9yIChwcm9nPTA7IHByb2c8TEFUTV9NQVhfUFJPR1JBTVM7IHByb2crKykgewogICAgZm9yIChsYXllcj0wOyBsYXllcjxMQVRNX01BWF9MQVlFUlM7IGxheWVyKyspIHsKICAgICAgaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXSA9IE5VTEw7CiAgICAgIGhBc3MtPm1fbGluZm9bcHJvZ11bbGF5ZXJdLnN0cmVhbUlEID0gLTE7CiAgICB9CiAgfQoKICBoQXNzLT5jb25maWdbMF1bMF0gPSBsYXllckNvbmZpZzsKICBoQXNzLT5tX2xpbmZvWzBdWzBdLnN0cmVhbUlEID0gMDsKCiAgRXJyb3JTdGF0dXMgPSB0cmFuc3BvcnRFbmNfSW5pdExhdG1TdHJlYW0oIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYWN0RGVsYXlQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cERhdGFEaXN0YW5jZUZyYW1lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGF1ZGlvTXV4VmVyc2lvbik/MTowLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogIGlmIChFcnJvclN0YXR1cyAhPSBUUkFOU1BPUlRFTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIEVycm9yU3RhdHVzID0gdHJhbnNwb3J0RW5jX0xhdG1TZXROck9mU3ViZnJhbWVzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllckNvbmZpZy0+blN1YkZyYW1lcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgaWYgKEVycm9yU3RhdHVzICE9IFRSQU5TUE9SVEVOQ19PSykKICAgIGdvdG8gYmFpbDsKCiAgLyogR2V0IHRoZSBzaXplIG9mIHRoZSBTdHJlYW1NdXhDb25maWcgc29tZWhvdyAqLwogIEFkdmFuY2VBdWRpb011eEVsZW1lbnQoaEFzcywgaEJzLCAwLCAwLCBjYik7CiAgLy9DcmVhdGVTdHJlYW1NdXhDb25maWcoaEFzcywgaEJzLCAwKTsKCmJhaWw6CiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9CgoKCgoKCg==