Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS5XZXJuZXIKICAgY29udGVudHMvZGVzY3JpcHRpb246IE5vaXNlbGVzcyBjb2RlciBtb2R1bGUKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJkeW5fYml0cy5oIgojaW5jbHVkZSAiYml0X2NudC5oIgojaW5jbHVkZSAicHN5X2NvbnN0LmgiCiNpbmNsdWRlICJhYWNlbmNfcG5zLmgiCiNpbmNsdWRlICJhYWNFbmNfcmFtLmgiCiNpbmNsdWRlICJhYWNFbmNfcm9tLmgiCgp0eXBlZGVmIElOVCAoKmxvb2tVcFRhYmxlKVtDT0RFX0JPT0tfRVNDX05EWCArIDFdOwoKc3RhdGljIElOVCBGREthYWNFbmNfZ2V0U2lkZUluZm9CaXRzKAogICAgICAgIGNvbnN0IFNFQ1RJT05fSU5GTyogY29uc3QgaHVmZnNlY3Rpb24sCiAgICAgICAgY29uc3QgU0hPUlQqIGNvbnN0ICAgICAgICBzaWRlSW5mb1RhYiwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHVzZUhDUgogICAgICAgICkKewogIElOVCBzaWRlSW5mb0JpdHM7CgogIGlmICggdXNlSENSICYmICgoaHVmZnNlY3Rpb24tPmNvZGVCb29rID09IDExKSB8fCAoaHVmZnNlY3Rpb24tPmNvZGVCb29rID49IDE2KSkgKSB7CiAgICBzaWRlSW5mb0JpdHMgPSA1OwogIH0KICBlbHNlIHsKICAgIHNpZGVJbmZvQml0cyA9IHNpZGVJbmZvVGFiW2h1ZmZzZWN0aW9uLT5zZmJDbnRdOwogIH0KCiAgcmV0dXJuIChzaWRlSW5mb0JpdHMpOwp9CgovKiBjb3VudCBiaXRzIHVzaW5nIGFsbCBwb3NzaWJsZSB0YWJsZXMgKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX2J1aWxkQml0TG9va1VwKAogICAgICAgIGNvbnN0IFNIT1JUKiBjb25zdCAgICAgICAgcXVhbnRTcGVjdHJ1bSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIG1heFNmYiwKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgIHNmYk9mZnNldCwKICAgICAgICBjb25zdCBVSU5UKiBjb25zdCAgICAgICAgIHNmYk1heCwKICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgIGJpdExvb2tVcFtNQVhfU0ZCX0xPTkddW0NPREVfQk9PS19FU0NfTkRYICsgMV0sCiAgICAgICAgU0VDVElPTl9JTkZPKiBjb25zdCAgICAgICBodWZmc2VjdGlvbgogICAgICAgICkKewogIElOVCBpLCBzZmJXaWR0aDsKCiAgZm9yIChpID0gMDsgaSA8IG1heFNmYjsgaSsrKQogIHsKICAgIGh1ZmZzZWN0aW9uW2ldLnNmYkNudCA9IDE7CiAgICBodWZmc2VjdGlvbltpXS5zZmJTdGFydCA9IGk7CiAgICBodWZmc2VjdGlvbltpXS5zZWN0aW9uQml0cyA9IElOVkFMSURfQklUQ09VTlQ7CiAgICBodWZmc2VjdGlvbltpXS5jb2RlQm9vayA9IC0xOwogICAgc2ZiV2lkdGggPSBzZmJPZmZzZXRbaSArIDFdIC0gc2ZiT2Zmc2V0W2ldOwogICAgRkRLYWFjRW5jX2JpdENvdW50KHF1YW50U3BlY3RydW0gKyBzZmJPZmZzZXRbaV0sIHNmYldpZHRoLCBzZmJNYXhbaV0sIGJpdExvb2tVcFtpXSk7CiAgfQp9CgovKiBlc3NlbnRpYWwgaGVscGVyIGZ1bmN0aW9ucyAqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19maW5kQmVzdEJvb2soCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICBiYywKICAgICAgICBJTlQqIGNvbnN0ICAgICAgICAgICAgICAgIGJvb2ssCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICB1c2VWQ0IxMQogICAgICAgICkKewogIElOVCBtaW5CaXRzID0gSU5WQUxJRF9CSVRDT1VOVCwgajsKCiAgaW50IGVuZCA9IENPREVfQk9PS19FU0NfTkRYOwoKCiAgZm9yIChqID0gMDsgaiA8PSBlbmQ7IGorKykKICB7CiAgICBpZiAoYmNbal0gPCBtaW5CaXRzKQogICAgewogICAgICBtaW5CaXRzID0gYmNbal07CiAgICAgICpib29rID0gajsKICAgIH0KICB9CiAgcmV0dXJuIChtaW5CaXRzKTsKfQoKc3RhdGljIElOVCBGREthYWNFbmNfZmluZE1pbk1lcmdlQml0cygKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgIGJjMSwKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgIGJjMiwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHVzZVZDQjExCiAgICAgICAgKQp7CiAgSU5UIG1pbkJpdHMgPSBJTlZBTElEX0JJVENPVU5ULCBqOwoKICBpbnQgZW5kID0gQ09ERV9CT09LX0VTQ19ORFg7CgoKICBmb3IgKGogPSAwOyBqIDw9IGVuZDsgaisrKQogIHsKICAgIGlmIChiYzFbal0gKyBiYzJbal0gPCBtaW5CaXRzKQogICAgewogICAgICBtaW5CaXRzID0gYmMxW2pdICsgYmMyW2pdOwogICAgfQogIH0KICByZXR1cm4gKG1pbkJpdHMpOwp9CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfbWVyZ2VCaXRMb29rVXAoCiAgICAgICAgSU5UKiBjb25zdCAgICAgICAgICAgICAgICBiYzEsCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICBiYzIKICAgICAgICApCnsKICBpbnQgajsKCiAgZm9yIChqID0gMDsgaiA8PSBDT0RFX0JPT0tfRVNDX05EWDsgaisrKQogIHsKICAgIGJjMVtqXSA9IGZpeE1pbihiYzFbal0gKyBiYzJbal0sIElOVkFMSURfQklUQ09VTlQpOwogIH0KfQoKc3RhdGljIElOVCBGREthYWNFbmNfZmluZE1heE1lcmdlKAogICAgICAgIGNvbnN0IElOVCogY29uc3QgICAgICAgICAgbWVyZ2VHYWluTG9va1VwLAogICAgICAgIGNvbnN0IFNFQ1RJT05fSU5GTyogY29uc3QgIGh1ZmZzZWN0aW9uLAogICAgICAgIGNvbnN0IElOVCBtYXhTZmIsCiAgICAgICAgSU5UKiBjb25zdCAgICAgICAgICAgICAgICBtYXhOZHgKICAgICAgICApCnsKICBJTlQgaSwgbWF4TWVyZ2VHYWluID0gMDsKCiAgZm9yIChpID0gMDsgaSArIGh1ZmZzZWN0aW9uW2ldLnNmYkNudCA8IG1heFNmYjsgaSArPSBodWZmc2VjdGlvbltpXS5zZmJDbnQpCiAgewogICAgaWYgKG1lcmdlR2Fpbkxvb2tVcFtpXSA+IG1heE1lcmdlR2FpbikKICAgIHsKICAgICAgbWF4TWVyZ2VHYWluID0gbWVyZ2VHYWluTG9va1VwW2ldOwogICAgICAqbWF4TmR4ID0gaTsKICAgIH0KICB9CiAgcmV0dXJuIChtYXhNZXJnZUdhaW4pOwp9CgpzdGF0aWMgSU5UIEZES2FhY0VuY19DYWxjTWVyZ2VHYWluKAogICAgICAgIGNvbnN0IFNFQ1RJT05fSU5GTyogY29uc3QgaHVmZnNlY3Rpb24sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBiaXRMb29rVXBbTUFYX1NGQl9MT05HXVtDT0RFX0JPT0tfRVNDX05EWCArIDFdLAogICAgICAgIGNvbnN0IFNIT1JUKiBjb25zdCAgICAgICAgc2lkZUluZm9UYWIsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBuZHgxLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgbmR4MiwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHVzZVZDQjExCiAgICAgICAgKQp7CiAgSU5UIE1lcmdlR2FpbiwgTWVyZ2VCaXRzLCBTcGxpdEJpdHM7CgogIE1lcmdlQml0cyA9IHNpZGVJbmZvVGFiW2h1ZmZzZWN0aW9uW25keDFdLnNmYkNudCArIGh1ZmZzZWN0aW9uW25keDJdLnNmYkNudF0gKyBGREthYWNFbmNfZmluZE1pbk1lcmdlQml0cyhiaXRMb29rVXBbbmR4MV0sIGJpdExvb2tVcFtuZHgyXSwgdXNlVkNCMTEpOwogIFNwbGl0Qml0cyA9IGh1ZmZzZWN0aW9uW25keDFdLnNlY3Rpb25CaXRzICsgaHVmZnNlY3Rpb25bbmR4Ml0uc2VjdGlvbkJpdHM7IC8qIEJpdCBhbW91bnQgZm9yIHNwbGl0dGVkIGh1ZmZzZWN0aW9ucyAqLwogIE1lcmdlR2FpbiA9IFNwbGl0Qml0cyAtIE1lcmdlQml0czsKCiAgaWYgKCAoaHVmZnNlY3Rpb25bbmR4MV0uY29kZUJvb2s9PUNPREVfQk9PS19QTlNfTk8pfHwoaHVmZnNlY3Rpb25bbmR4Ml0uY29kZUJvb2s9PUNPREVfQk9PS19QTlNfTk8pCiAgICB8fCAoaHVmZnNlY3Rpb25bbmR4MV0uY29kZUJvb2s9PUNPREVfQk9PS19JU19PVVRfT0ZfUEhBU0VfTk8pfHwoaHVmZnNlY3Rpb25bbmR4Ml0uY29kZUJvb2s9PUNPREVfQk9PS19JU19PVVRfT0ZfUEhBU0VfTk8pCiAgICB8fCAoaHVmZnNlY3Rpb25bbmR4MV0uY29kZUJvb2s9PUNPREVfQk9PS19JU19JTl9QSEFTRV9OTyl8fChodWZmc2VjdGlvbltuZHgyXS5jb2RlQm9vaz09Q09ERV9CT09LX0lTX0lOX1BIQVNFX05PKQogICAgKQogIHsKICAgIE1lcmdlR2FpbiA9IC0xOwogIH0KCiAgcmV0dXJuIChNZXJnZUdhaW4pOwp9CgoKLyogc2VjdGlvbmluZyBTdGFnZSAwOmZpbmQgbWluaW11bSBjb2Rib29rcyAqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfZ21TdGFnZTAoCiAgICAgICAgU0VDVElPTl9JTkZPKiBjb25zdCBSRVNUUklDVCBodWZmc2VjdGlvbiwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgIGJpdExvb2tVcFtNQVhfU0ZCX0xPTkddW0NPREVfQk9PS19FU0NfTkRYICsgMV0sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICBtYXhTZmIsCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBub2lzZU5yZywKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgICAgIGlzQm9vawogICAgICAgICkKewogIElOVCBpOwoKICBmb3IgKGkgPSAwOyBpIDwgbWF4U2ZiOyBpKyspCiAgewogICAgLyogU2lkZS1JbmZvIGJpdHMgd2lsbCBiZSBjYWxjdWxhdGVkIGluIFN0YWdlIDEhICovCiAgICBpZiAoaHVmZnNlY3Rpb25baV0uc2VjdGlvbkJpdHMgPT0gSU5WQUxJRF9CSVRDT1VOVCkKICAgIHsKICAgICAgLyogaW50ZW5zaXR5IGFuZCBwbnMgY29kZWJvb2tzIGFyZSBhbHJlYWR5IGFsbG9jYXRlZCBpbiBiaXRjb3VudC5jICovCiAgICAgIGlmKG5vaXNlTnJnW2ldICE9IE5PX05PSVNFX1BOUyl7CiAgICAgICAgaHVmZnNlY3Rpb25baV0uY29kZUJvb2s9Q09ERV9CT09LX1BOU19OTzsKICAgICAgICBodWZmc2VjdGlvbltpXS5zZWN0aW9uQml0cyA9IDA7CiAgICAgIH0KICAgICAgZWxzZSBpZiggaXNCb29rW2ldICkgewogICAgICAgIGh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rPWlzQm9va1tpXTsKICAgICAgICBodWZmc2VjdGlvbltpXS5zZWN0aW9uQml0cyA9IDA7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgaHVmZnNlY3Rpb25baV0uc2VjdGlvbkJpdHMgPSBGREthYWNFbmNfZmluZEJlc3RCb29rKGJpdExvb2tVcFtpXSwgJihodWZmc2VjdGlvbltpXS5jb2RlQm9vayksIDApOyAvKiB1c2VWQ0IxMSBtdXN0IGJlIDAhISEgKi8KICAgICAgfQogICAgfQogIH0KfQoKLyoKICAgc2VjdGlvbmluZyBTdGFnZSAxOm1lcmdlIGFsbCBjb25uZWN0ZWQgcmVnaW9ucyB3aXRoIHRoZSBzYW1lIGNvZGUgYm9vayBhbmQKICAgY2FsY3VsYXRlIHNpZGUgaW5mbwogKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX2dtU3RhZ2UxKAogICAgICAgIFNFQ1RJT05fSU5GTyogY29uc3QgUkVTVFJJQ1QgaHVmZnNlY3Rpb24sCiAgICAgICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRMb29rVXBbTUFYX1NGQl9MT05HXVtDT0RFX0JPT0tfRVNDX05EWCArIDFdLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgbWF4U2ZiLAogICAgICAgIGNvbnN0IFNIT1JUKiBjb25zdCAgICAgICAgICAgc2lkZUluZm9UYWIsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICB1c2VWQ0IxMQogICAgICAgICkKewogIElOVCBtZXJnZVN0YXJ0ID0gMCwgbWVyZ2VFbmQ7CgogIGRvCiAgewogICAgZm9yIChtZXJnZUVuZCA9IG1lcmdlU3RhcnQgKyAxOyBtZXJnZUVuZCA8IG1heFNmYjsgbWVyZ2VFbmQrKykKICAgIHsKICAgICAgaWYgKGh1ZmZzZWN0aW9uW21lcmdlU3RhcnRdLmNvZGVCb29rICE9IGh1ZmZzZWN0aW9uW21lcmdlRW5kXS5jb2RlQm9vaykKICAgICAgICBicmVhazsKCgogICAgICAvKiB3ZSBjYW4gbWVyZ2UuIHVwZGF0ZSB0YWJsZXMsIHNpZGUgaW5mbyBiaXRzIHdpbGwgYmUgdXBkYXRlZCBvdXRzaWRlIG9mIHRoaXMgbG9vcCAqLwogICAgICBodWZmc2VjdGlvblttZXJnZVN0YXJ0XS5zZmJDbnQrKzsKICAgICAgaHVmZnNlY3Rpb25bbWVyZ2VTdGFydF0uc2VjdGlvbkJpdHMgKz0gaHVmZnNlY3Rpb25bbWVyZ2VFbmRdLnNlY3Rpb25CaXRzOwoKICAgICAgLyogdXBkYXRlIGJpdCBsb29rIHVwIGZvciBhbGwgY29kZSBib29rcyAqLwogICAgICBGREthYWNFbmNfbWVyZ2VCaXRMb29rVXAoYml0TG9va1VwW21lcmdlU3RhcnRdLCBiaXRMb29rVXBbbWVyZ2VFbmRdKTsKICAgIH0KCiAgICAvKiBhZGQgc2lkZSBpbmZvIGluZm8gYml0cyAqLwogICAgaHVmZnNlY3Rpb25bbWVyZ2VTdGFydF0uc2VjdGlvbkJpdHMgKz0gRkRLYWFjRW5jX2dldFNpZGVJbmZvQml0cygmaHVmZnNlY3Rpb25bbWVyZ2VTdGFydF0sIHNpZGVJbmZvVGFiLCB1c2VWQ0IxMSk7CiAgICBodWZmc2VjdGlvblttZXJnZUVuZCAtIDFdLnNmYlN0YXJ0ID0gaHVmZnNlY3Rpb25bbWVyZ2VTdGFydF0uc2ZiU3RhcnQ7ICAgICAgLyogc3BlZWQgdXAgcHJldiBzZWFyY2ggKi8KCiAgICBtZXJnZVN0YXJ0ID0gbWVyZ2VFbmQ7CgogIH0gd2hpbGUgKG1lcmdlU3RhcnQgPCBtYXhTZmIpOwp9CgovKgogICBzZWN0aW9uaW5nIFN0YWdlIDI6Z3JlZWR5IG1lcmdlIGFsZ29yaXRobSwgbWVyZ2UgY29ubmVjdGVkIHNlY3Rpb25zIHdpdGgKICAgbWF4aW11bSBiaXQgZ2FpbiB1bnRpbCBubyBtb3JlIGdhaW4gaXMgcG9zc2libGUKICovCnN0YXRpYyB2b2lkCkZES2FhY0VuY19nbVN0YWdlMigKICAgICAgICBTRUNUSU9OX0lORk8qIGNvbnN0IFJFU1RSSUNUIGh1ZmZzZWN0aW9uLAogICAgICAgIElOVCogY29uc3QgUkVTVFJJQ1QgICAgICAgICAgbWVyZ2VHYWluTG9va1VwLAogICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgYml0TG9va1VwW01BWF9TRkJfTE9OR11bQ09ERV9CT09LX0VTQ19ORFggKyAxXSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgIG1heFNmYiwKICAgICAgICBjb25zdCBTSE9SVCogY29uc3QgICAgICAgICAgIHNpZGVJbmZvVGFiLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgdXNlVkNCMTEKICAgICAgICApCnsKICBJTlQgaTsKCiAgZm9yIChpID0gMDsgaSArIGh1ZmZzZWN0aW9uW2ldLnNmYkNudCA8IG1heFNmYjsgaSArPSBodWZmc2VjdGlvbltpXS5zZmJDbnQpCiAgewogICAgbWVyZ2VHYWluTG9va1VwW2ldID0gRkRLYWFjRW5jX0NhbGNNZXJnZUdhaW4oaHVmZnNlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdExvb2tVcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkZUluZm9UYWIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKyBodWZmc2VjdGlvbltpXS5zZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZVZDQjExKTsKICB9CgogIHdoaWxlIChUUlVFKQogIHsKICAgIElOVCBtYXhNZXJnZUdhaW4sIG1heE5keCA9IDAsIG1heE5keE5leHQsIG1heE5keExhc3Q7CgogICAgbWF4TWVyZ2VHYWluID0gRkRLYWFjRW5jX2ZpbmRNYXhNZXJnZShtZXJnZUdhaW5Mb29rVXAsIGh1ZmZzZWN0aW9uLCBtYXhTZmIsICZtYXhOZHgpOwoKICAgIC8qIGV4aXQgd2hpbGUgbG9vcCBpZiBubyBtb3JlIGdhaW4gaXMgcG9zc2libGUgKi8KICAgIGlmIChtYXhNZXJnZUdhaW4gPD0gMCkKICAgICAgYnJlYWs7CgogICAgbWF4TmR4TmV4dCA9IG1heE5keCArIGh1ZmZzZWN0aW9uW21heE5keF0uc2ZiQ250OwoKICAgIC8qIG1lcmdlIHNlY3Rpb25zIHdpdGggbWF4aW11bSBiaXQgZ2FpbiAqLwogICAgaHVmZnNlY3Rpb25bbWF4TmR4XS5zZmJDbnQgKz0gaHVmZnNlY3Rpb25bbWF4TmR4TmV4dF0uc2ZiQ250OwogICAgaHVmZnNlY3Rpb25bbWF4TmR4XS5zZWN0aW9uQml0cyArPSBodWZmc2VjdGlvblttYXhOZHhOZXh0XS5zZWN0aW9uQml0cyAtIG1heE1lcmdlR2FpbjsKCiAgICAvKiB1cGRhdGUgYml0IGxvb2sgdXAgdGFibGUgZm9yIG1lcmdlZCBodWZmc2VjdGlvbiAgKi8KICAgIEZES2FhY0VuY19tZXJnZUJpdExvb2tVcChiaXRMb29rVXBbbWF4TmR4XSwgYml0TG9va1VwW21heE5keE5leHRdKTsKCiAgICAvKiB1cGRhdGUgbWVyZ2VMb29rVXBUYWJsZSAqLwogICAgaWYgKG1heE5keCAhPSAwKQogICAgewogICAgICBtYXhOZHhMYXN0ID0gaHVmZnNlY3Rpb25bbWF4TmR4IC0gMV0uc2ZiU3RhcnQ7CiAgICAgIG1lcmdlR2Fpbkxvb2tVcFttYXhOZHhMYXN0XSA9IEZES2FhY0VuY19DYWxjTWVyZ2VHYWluKGh1ZmZzZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdExvb2tVcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWRlSW5mb1RhYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhOZHhMYXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heE5keCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VWQ0IxMSk7CgogICAgfQogICAgbWF4TmR4TmV4dCA9IG1heE5keCArIGh1ZmZzZWN0aW9uW21heE5keF0uc2ZiQ250OwoKICAgIGh1ZmZzZWN0aW9uW21heE5keE5leHQgLSAxXS5zZmJTdGFydCA9IGh1ZmZzZWN0aW9uW21heE5keF0uc2ZiU3RhcnQ7CgogICAgaWYgKG1heE5keE5leHQgPCBtYXhTZmIpCiAgICAgIG1lcmdlR2Fpbkxvb2tVcFttYXhOZHhdID0gRkRLYWFjRW5jX0NhbGNNZXJnZUdhaW4oaHVmZnNlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRMb29rVXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWRlSW5mb1RhYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heE5keCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heE5keE5leHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VWQ0IxMSk7CgogIH0KfQoKLyogY291bnQgYml0cyB1c2VkIGJ5IHRoZSBub2lzZWxlc3MgY29kZXIgKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX25vaXNlbGVzc0NvdW50ZXIoCiAgICAgICAgU0VDVElPTl9EQVRBKiBjb25zdCBSRVNUUklDVCBzZWN0aW9uRGF0YSwKICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlR2Fpbkxvb2tVcFtNQVhfU0ZCX0xPTkddLAogICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgYml0TG9va1VwW01BWF9TRkJfTE9OR11bQ09ERV9CT09LX0VTQ19ORFggKyAxXSwKICAgICAgICBjb25zdCBTSE9SVCogY29uc3QgICAgICAgICAgIHF1YW50U3BlY3RydW0sCiAgICAgICAgY29uc3QgVUlOVCogY29uc3QgICAgICAgICAgICBtYXhWYWx1ZUluU2ZiLAogICAgICAgIGNvbnN0IElOVCogY29uc3QgICAgICAgICAgICAgc2ZiT2Zmc2V0LAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgYmxvY2tUeXBlLAogICAgICAgIGNvbnN0IElOVCogY29uc3QgICAgICAgICAgICAgbm9pc2VOcmcsCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBpc0Jvb2ssCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICB1c2VWQ0IxMQogICAgICAgICkKewogIElOVCBncnBOZHgsIGk7CiAgY29uc3QgU0hPUlQgKnNpZGVJbmZvVGFiID0gTlVMTDsKICBTRUNUSU9OX0lORk8gKmh1ZmZzZWN0aW9uOwoKICAvKiB1c2UgYXBwcm9wcmlhdGUgc2lkZSBpbmZvIHRhYmxlICovCiAgc3dpdGNoIChibG9ja1R5cGUpCiAgewogIGNhc2UgTE9OR19XSU5ET1c6CiAgY2FzZSBTVEFSVF9XSU5ET1c6CiAgY2FzZSBTVE9QX1dJTkRPVzoKICAgIHNpZGVJbmZvVGFiID0gRkRLYWFjRW5jX3NpZGVJbmZvVGFiTG9uZzsKICAgIGJyZWFrOwogIGNhc2UgU0hPUlRfV0lORE9XOgogICAgc2lkZUluZm9UYWIgPSBGREthYWNFbmNfc2lkZUluZm9UYWJTaG9ydDsKICAgIGJyZWFrOwogIH0KCiAgc2VjdGlvbkRhdGEtPm5vT2ZTZWN0aW9ucyA9IDA7CiAgc2VjdGlvbkRhdGEtPmh1ZmZtYW5CaXRzID0gMDsKICBzZWN0aW9uRGF0YS0+c2lkZUluZm9CaXRzID0gMDsKCgogIGlmIChzZWN0aW9uRGF0YS0+bWF4U2ZiUGVyR3JvdXAgPT0gMCkKICAgIHJldHVybjsKCiAgLyogbG9vcCB0cm91Z2ggZ3JvdXBzICovCiAgZm9yIChncnBOZHggPSAwOyBncnBOZHggPCBzZWN0aW9uRGF0YS0+c2ZiQ250OyBncnBOZHggKz0gc2VjdGlvbkRhdGEtPnNmYlBlckdyb3VwKQogIHsKICAgIGh1ZmZzZWN0aW9uID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uICsgc2VjdGlvbkRhdGEtPm5vT2ZTZWN0aW9uczsKCiAgICAvKiBjb3VudCBiaXRzIGluIHRoaXMgZ3JvdXAgKi8KICAgIEZES2FhY0VuY19idWlsZEJpdExvb2tVcChxdWFudFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgc2VjdGlvbkRhdGEtPm1heFNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgc2ZiT2Zmc2V0ICsgZ3JwTmR4LAogICAgICAgICAgICAgICAgICAgbWF4VmFsdWVJblNmYiArIGdycE5keCwKICAgICAgICAgICAgICAgICAgIGJpdExvb2tVcCwKICAgICAgICAgICAgICAgICAgIGh1ZmZzZWN0aW9uKTsKCiAgICAvKiAwLlN0YWdlIDpGaW5kIG1pbmltdW0gQ29kZWJvb2tzICovCiAgICBGREthYWNFbmNfZ21TdGFnZTAoaHVmZnNlY3Rpb24sIGJpdExvb2tVcCwgc2VjdGlvbkRhdGEtPm1heFNmYlBlckdyb3VwLCBub2lzZU5yZytncnBOZHgsIGlzQm9vaytncnBOZHgpOwoKICAgIC8qIDEuU3RhZ2UgOk1lcmdlIGFsbCBjb25uZWN0ZWQgcmVnaW9ucyB3aXRoIHRoZSBzYW1lIGNvZGUgYm9vayAqLwogICAgRkRLYWFjRW5jX2dtU3RhZ2UxKGh1ZmZzZWN0aW9uLCBiaXRMb29rVXAsIHNlY3Rpb25EYXRhLT5tYXhTZmJQZXJHcm91cCwgc2lkZUluZm9UYWIsIHVzZVZDQjExKTsKCgogICAgLyoKICAgICAgIDIuU3RhZ2UKICAgICAgIGdyZWVkeSBtZXJnZSBhbGdvcml0aG0sIG1lcmdlIGNvbm5lY3RlZCBodWZmc2VjdGlvbnMgd2l0aCBtYXhpbXVtIGJpdAogICAgICAgZ2FpbiB1bnRpbCBubyBtb3JlIGdhaW4gaXMgcG9zc2libGUKICAgICAqLwoKICAgIEZES2FhY0VuY19nbVN0YWdlMihodWZmc2VjdGlvbiwKICAgICAgICAgICAgIG1lcmdlR2Fpbkxvb2tVcCwKICAgICAgICAgICAgIGJpdExvb2tVcCwKICAgICAgICAgICAgIHNlY3Rpb25EYXRhLT5tYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgIHNpZGVJbmZvVGFiLAogICAgICAgICAgICAgdXNlVkNCMTEpOwoKCgogICAgLyoKICAgICAgIGNvbXByZXNzIG91dHB1dCwgY2FsY3VsYXRlIHRvdGFsIGh1ZmYgYW5kIHNpZGUgYml0cwogICAgICAgc2luY2Ugd2UgZGlkIG5vdCB1cGRhdGUgdGhlIGFjdHVhbCBjb2RlYm9vayBpbiBzdGFnZSAyCiAgICAgICB0byBzYXZlIHRpbWUsIHdlIG11c3Qgc2V0IGl0IGhlcmUgZm9yIGxhdGVyIHVzZSBpbiBiaXRlbmMKICAgICAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCBzZWN0aW9uRGF0YS0+bWF4U2ZiUGVyR3JvdXA7IGkgKz0gaHVmZnNlY3Rpb25baV0uc2ZiQ250KQogICAgewogICAgICBpZiAoKGh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rPT1DT0RFX0JPT0tfUE5TX05PKSB8fAogICAgICAgICAgKGh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rPT1DT0RFX0JPT0tfSVNfT1VUX09GX1BIQVNFX05PKSB8fAogICAgICAgICAgKGh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rPT1DT0RFX0JPT0tfSVNfSU5fUEhBU0VfTk8pKQogICAgICB7CiAgICAgICAgaHVmZnNlY3Rpb25baV0uc2VjdGlvbkJpdHM9MDsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiB0aGUgc2VjdGlvbnMgaW4gdGhlIHNlY3Rpb25EYXRhIGFyZSBub3cgbWFya2VkIHdpdGggdGhlIG9wdGltYWwgY29kZSBib29rICovCgogICAgICAgICAgRkRLYWFjRW5jX2ZpbmRCZXN0Qm9vayhiaXRMb29rVXBbaV0sICYoaHVmZnNlY3Rpb25baV0uY29kZUJvb2spLCB1c2VWQ0IxMSk7CgogICAgICAgIHNlY3Rpb25EYXRhLT5odWZmbWFuQml0cyArPSBodWZmc2VjdGlvbltpXS5zZWN0aW9uQml0cyAtIEZES2FhY0VuY19nZXRTaWRlSW5mb0JpdHMoJmh1ZmZzZWN0aW9uW2ldLCBzaWRlSW5mb1RhYiwgdXNlVkNCMTEpOwogICAgICB9CgogICAgICBodWZmc2VjdGlvbltpXS5zZmJTdGFydCArPSBncnBOZHg7CgogICAgICAvKiBzdW0gdXAgc2lkZSBpbmZvIGJpdHMgKHNlY3Rpb24gZGF0YSBiaXRzKSAqLwogICAgICBzZWN0aW9uRGF0YS0+c2lkZUluZm9CaXRzICs9IEZES2FhY0VuY19nZXRTaWRlSW5mb0JpdHMoJmh1ZmZzZWN0aW9uW2ldLCBzaWRlSW5mb1RhYiwgdXNlVkNCMTEpOwogICAgICBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25bc2VjdGlvbkRhdGEtPm5vT2ZTZWN0aW9ucysrXSA9IGh1ZmZzZWN0aW9uW2ldOwogICAgfQogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX3NjZkNvdW50CiAgICAgcmV0dXJucyAgICAgOiAtLS0KICAgICBkZXNjcmlwdGlvbiA6IGNvdW50IGJpdHMgdXNlZCBieSBzY2FsZWZhY3RvcnMuCgogICAgICAgICAgICAgICAgICAgbm90IGluIGFsbCBjYXNlcyBpZiBtYXhWYWx1ZUluU2ZiW10gPT0gMCB3ZSBzZXQgZGVsdGFTY2YKICAgICAgICAgICAgICAgICAgIHRvIHplcm8uIG9ubHkgaWYgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIGxhc3QgYW5kIGZ1dHVyZQogICAgICAgICAgICAgICAgICAgc2NhbGVmYWNHYWluIGlzIG5vdCBncmVhdGVyIHRoZW4gQ09ERV9CT09LX1NDRl9MQVYgKDYwKS4KCiAgICAgZXhhbXBsZToKICAgICAgICAgICAgICAgICAgXgogICAgIHNjYWxlZmFjR2FpbiB8CiAgICAgICAgICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICBsYXN0IDc1CiAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfAogICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgIGN1cnJlbnQgNTAKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICBmdXR1cmUgNQogICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgIC0tLSAuLi4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAuLi4gLS0tLS0tLS0tPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiCgoKICAgICAgICAgICAgICAgICAgaWYgbWF4VmFsdWVJblNmYltdIG9mIGN1cnJlbnQgaXMgemVybyBiZWNhdXNlIG9mIGEKICAgICAgICAgICAgICAgICAgbm90ZmFsbHN0cmF0ZWdpZSwgd2UgZG8gbm90IHNhdmUgYml0cyBhbmQgdHJhbnNtaXQgYQogICAgICAgICAgICAgICAgICBkZWx0YVNjZiBvZiAyNS4gb3RoZXJ3aXNlIHRoZSBkZWx0YVNjZiBiZXR3ZWVuIHRoZSBsYXN0CiAgICAgICAgICAgICAgICAgIHNjYWxmYWNHYWluICg3NSkgYW5kIHRoZSBmdXR1cmUgc2NhbGVmYWNHYWluICg1KSBpcyA3MC4KCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfc2NmQ291bnQoCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBzY2FsZWZhY0dhaW4sCiAgICAgICAgY29uc3QgVUlOVCogY29uc3QgICAgICAgICAgICBtYXhWYWx1ZUluU2ZiLAogICAgICAgIFNFQ1RJT05fREFUQSogY29uc3QgUkVTVFJJQ1Qgc2VjdGlvbkRhdGEsCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBpc1NjYWxlCiAgICAgICAgKQp7CiAgSU5UIGksIGosIGssIG0sIG47CgogIElOVCBsYXN0VmFsU2NmICAgICA9IDA7CiAgSU5UIGRlbHRhU2NmICAgICAgID0gMDsKICBJTlQgZm91bmQgICAgICAgICAgPSAwOwogIElOVCBzY2ZTa2lwQ291bnRlciA9IDA7CiAgSU5UIGxhc3RWYWxJcyAgICAgID0gMDsKCiAgc2VjdGlvbkRhdGEtPnNjYWxlZmFjQml0cyA9IDA7CgogIGlmIChzY2FsZWZhY0dhaW4gPT0gTlVMTCkKICAgIHJldHVybjsKCiAgc2VjdGlvbkRhdGEtPmZpcnN0U2NmID0gMDsKCiAgZm9yIChpPTA7IGk8c2VjdGlvbkRhdGEtPm5vT2ZTZWN0aW9uczsgaSsrKQogIHsKICAgIGlmIChzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgIT0gQ09ERV9CT09LX1pFUk9fTk8pCiAgICB7CiAgICAgIHNlY3Rpb25EYXRhLT5maXJzdFNjZiA9IHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJTdGFydDsKICAgICAgbGFzdFZhbFNjZiA9IHNjYWxlZmFjR2FpbltzZWN0aW9uRGF0YS0+Zmlyc3RTY2ZdOwogICAgICBicmVhazsKICAgIH0KICB9CgogIGZvciAoaT0wOyBpPHNlY3Rpb25EYXRhLT5ub09mU2VjdGlvbnM7IGkrKykKICB7CiAgICBpZiAoKHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5jb2RlQm9vayA9PSBDT0RFX0JPT0tfSVNfT1VUX09GX1BIQVNFX05PKSB8fAogICAgICAgIChzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgPT0gQ09ERV9CT09LX0lTX0lOX1BIQVNFX05PKSkKICAgIHsKICAgICAgZm9yIChqID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYlN0YXJ0OwogICAgICAgICAgIGogPCBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiU3RhcnQgKyBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiQ250OwogICAgICAgICAgIGorKykKICAgICAgewogICAgICAgIElOVCBkZWx0YUlzID0gaXNTY2FsZVtqXS1sYXN0VmFsSXM7CiAgICAgICAgbGFzdFZhbElzICAgPSBpc1NjYWxlW2pdOwogICAgICAgIHNlY3Rpb25EYXRhLT5zY2FsZWZhY0JpdHMrPUZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoZGVsdGFJcyk7CiAgICAgIH0KICAgIH0gLyogSW50ZW5zaXR5ICovCiAgICBlbHNlIGlmICgoc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rICE9IENPREVfQk9PS19aRVJPX05PKSAmJgogICAgICAgICAgICAgKHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5jb2RlQm9vayAhPSBDT0RFX0JPT0tfUE5TX05PKSkKICAgIHsKICAgICAgSU5UIHRtcCA9IHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJTdGFydCArIHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJDbnQ7CiAgICAgIGZvciAoaiA9IHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJTdGFydDsgajx0bXA7IGorKykKICAgICAgewogICAgICAgIC8qIGNoZWNrIGlmIHdlIGNhbiByZXBlYXQgdGhlIGxhc3QgdmFsdWUgdG8gc2F2ZSBiaXRzICovCiAgICAgICAgaWYgKG1heFZhbHVlSW5TZmJbal0gPT0gMCkKICAgICAgICB7CiAgICAgICAgICBmb3VuZCA9IDA7CiAgICAgICAgICAvKiBhcmUgc2NhbGVmYWN0b3JzIHNraXBwZWQ/ICovCiAgICAgICAgICBpZiAoc2NmU2tpcENvdW50ZXIgPT0gMCkKICAgICAgICAgIHsKICAgICAgICAgICAgLyogZW5kIG9mIHNlY3Rpb24gKi8KICAgICAgICAgICAgaWYgKGogPT0gKHRtcCAtIDEpICkKICAgICAgICAgICAgICBmb3VuZCA9IDA7ICAvKiBzZWFyY2ggaW4gb3RoZXIgc2VjdGlvbnMgZm9yIG1heFZhbHVlSW5TZmIgIT0gMCAqLwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAvKiBzZWFyY2ggaW4gdGhpcyBzZWN0aW9uIGZvciB0aGUgbmV4dCBtYXhWYWx1ZUluU2ZiW10gIT0gMCAqLwogICAgICAgICAgICAgIGZvciAoayA9IChqKzEpOyBrIDwgdG1wOyBrKyspCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG1heFZhbHVlSW5TZmJba10gIT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgZm91bmQgPSAxOwogICAgICAgICAgICAgICAgICBpZiAoIChmaXhwX2FicyhzY2FsZWZhY0dhaW5ba10gLSBsYXN0VmFsU2NmKSkgPD0gQ09ERV9CT09LX1NDRl9MQVYpCiAgICAgICAgICAgICAgICAgICAgIGRlbHRhU2NmID0gMDsgLyogc2F2ZSBiaXRzICovCiAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGRvIG5vdCBzYXZlIGJpdHMgKi8KICAgICAgICAgICAgICAgICAgICBkZWx0YVNjZiA9IGxhc3RWYWxTY2YgLSBzY2FsZWZhY0dhaW5bal07CiAgICAgICAgICAgICAgICAgICAgbGFzdFZhbFNjZiA9IHNjYWxlZmFjR2FpbltqXTsKICAgICAgICAgICAgICAgICAgICBzY2ZTa2lwQ291bnRlciA9IDA7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBjb3VudCBzY2FsZWZhY3RvciBza2lwICovCiAgICAgICAgICAgICAgICBzY2ZTa2lwQ291bnRlcisrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogc2VhcmNoIGZvciB0aGUgbmV4dCBtYXhWYWx1ZUluU2ZiW10gIT0gMCBpbiBhbGwgb3RoZXIgc2VjdGlvbnMgKi8KICAgICAgICAgICAgZm9yIChtPShpKzEpOyAobSA8IHNlY3Rpb25EYXRhLT5ub09mU2VjdGlvbnMpICYmIChmb3VuZCA9PSAwKTsgbSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKChzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25bbV0uY29kZUJvb2sgIT0gQ09ERV9CT09LX1pFUk9fTk8pICYmIChzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25bbV0uY29kZUJvb2sgIT0gQ09ERV9CT09LX1BOU19OTykpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSU5UIGVuZCA9IHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvblttXS5zZmJTdGFydCArIHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvblttXS5zZmJDbnQ7CiAgICAgICAgICAgICAgICBmb3IgKG4gPSBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25bbV0uc2ZiU3RhcnQ7IG48ZW5kOyBuKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIGlmIChtYXhWYWx1ZUluU2ZiW25dICE9IDApCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IDE7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZpeHBfYWJzKHNjYWxlZmFjR2FpbltuXSAtIGxhc3RWYWxTY2YpIDw9IENPREVfQk9PS19TQ0ZfTEFWKQogICAgICAgICAgICAgICAgICAgICAgZGVsdGFTY2YgPSAwOyAgLyogc2F2ZSBiaXRzICovCiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIC8qIGRvIG5vdCBzYXZlIGJpdHMgKi8KICAgICAgICAgICAgICAgICAgICAgIGRlbHRhU2NmID0gbGFzdFZhbFNjZiAtIHNjYWxlZmFjR2FpbltqXTsKICAgICAgICAgICAgICAgICAgICAgIGxhc3RWYWxTY2YgPSBzY2FsZWZhY0dhaW5bal07CiAgICAgICAgICAgICAgICAgICAgICBzY2ZTa2lwQ291bnRlciA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8qIGNvdW50IHNjYWxlZmFjdG9yIHNraXAgKi8KICAgICAgICAgICAgICAgICAgc2NmU2tpcENvdW50ZXIrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogbm8gbWF4VmFsdWVJblNmYltdICE9IDAgZm91bmQgKi8KICAgICAgICAgICAgaWYgKGZvdW5kID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBkZWx0YVNjZiA9IDA7CiAgICAgICAgICAgICAgc2NmU2tpcENvdW50ZXIgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyogY29uc2lkZXIgc2tpcHBlZCBzY2FsZWZhY3RvcnMgKi8KICAgICAgICAgICAgZGVsdGFTY2YgPSAwOwogICAgICAgICAgICBzY2ZTa2lwQ291bnRlci0tOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIGRlbHRhU2NmID0gbGFzdFZhbFNjZiAtIHNjYWxlZmFjR2FpbltqXTsKICAgICAgICAgIGxhc3RWYWxTY2YgPSBzY2FsZWZhY0dhaW5bal07CiAgICAgICAgfQogICAgICAgIHNlY3Rpb25EYXRhLT5zY2FsZWZhY0JpdHMgKz0gRkRLYWFjRW5jX2JpdENvdW50U2NhbGVmYWN0b3JEZWx0YShkZWx0YVNjZik7CiAgICAgIH0KICAgIH0KICB9IC8qIGZvciAoaT0wOyBpPHNlY3Rpb25EYXRhLT5ub09mU2VjdGlvbnM7IGkrKykgKi8KfQoKI2lmZGVmIFBOU19QUkVDT1VOVF9FTkFCTEUKLyoKICBwcmVDb3VudCBiaXRzIHVzZWQgcG5zCiovCi8qIGVzdGltYXRlIGJpdHMgdXNlZCBieSBwbnMgZm9yIGNvcnJlY3Rpb24gb2Ygc3RhdGljIGJpdHMgKi8KLyogbm8gY29kZWJvb2sgc3dpdGNoIGVzdGltYXRpb24sIHNlZSBBQUMgTEQgRkFTVEVOQyAqLwpJTlQgbm9pc2VQcmVDb3VudChjb25zdCBJTlQgKm5vaXNlTnJnLCBJTlQgbWF4U2ZiKQp7CiAgSU5UICAgbm9pc2VQQ01GbGFnID0gVFJVRTsKICBJTlQgICBsYXN0VmFsUG5zID0gMCwgZGVsdGFQbnM7CiAgaW50ICAgaSwgYml0cz0wOwoKIGZvciAoaSA9IDA7IGkgPCBtYXhTZmI7IGkrKykgewogICBpZiAobm9pc2VOcmdbaV0gIT0gTk9fTk9JU0VfUE5TKSB7CgogICAgIGlmIChub2lzZVBDTUZsYWcpIHsKICAgICAgIGJpdHMrPVBOU19QQ01fQklUUzsKICAgICAgIGxhc3RWYWxQbnMgICA9IG5vaXNlTnJnW2ldOwogICAgICAgbm9pc2VQQ01GbGFnID0gRkFMU0U7CiAgICAgfWVsc2UgewogICAgICAgZGVsdGFQbnMgICAgID0gbm9pc2VOcmdbaV0tbGFzdFZhbFBuczsKICAgICAgIGxhc3RWYWxQbnMgICA9IG5vaXNlTnJnW2ldOwogICAgICAgYml0cys9RkRLYWFjRW5jX2JpdENvdW50U2NhbGVmYWN0b3JEZWx0YShkZWx0YVBucyk7CiAgICAgfQogICB9CiB9CiByZXR1cm4gKCBiaXRzICk7Cn0KI2VuZGlmIC8qIFBOU19QUkVDT1VOVF9FTkFCTEUgKi8KCi8qIGNvdW50IGJpdHMgdXNlZCBieSBwbnMgKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX25vaXNlQ291bnQoCiAgICAgICAgU0VDVElPTl9EQVRBKiBjb25zdCBSRVNUUklDVCBzZWN0aW9uRGF0YSwKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgICAgIG5vaXNlTnJnCiAgICAgICAgKQp7CiAgSU5UIG5vaXNlUENNRmxhZyA9IFRSVUU7CiAgSU5UIGxhc3RWYWxQbnMgPSAwLCBkZWx0YVBuczsKICBpbnQgaSwgajsKCiAgc2VjdGlvbkRhdGEtPm5vaXNlTnJnQml0cyA9IDA7CgogIGZvciAoaSA9IDA7IGkgPCBzZWN0aW9uRGF0YS0+bm9PZlNlY3Rpb25zOyBpKyspIHsKICAgIGlmIChzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgPT0gQ09ERV9CT09LX1BOU19OTykgewogICAgICBpbnQgc2ZiU3RhcnQgPSBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiU3RhcnQ7CiAgICAgIGludCBzZmJFbmQgPSBzZmJTdGFydCArIHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJDbnQ7CiAgICAgIGZvciAoaj1zZmJTdGFydDsgajxzZmJFbmQ7IGorKykgewoKICAgICAgICBpZiAobm9pc2VQQ01GbGFnKSB7CiAgICAgICAgICBzZWN0aW9uRGF0YS0+bm9pc2VOcmdCaXRzKz1QTlNfUENNX0JJVFM7CiAgICAgICAgICBsYXN0VmFsUG5zICAgPSBub2lzZU5yZ1tqXTsKICAgICAgICAgIG5vaXNlUENNRmxhZyA9IEZBTFNFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkZWx0YVBucyAgICAgPSBub2lzZU5yZ1tqXS1sYXN0VmFsUG5zOwogICAgICAgICAgbGFzdFZhbFBucyAgID0gbm9pc2VOcmdbal07CiAgICAgICAgICBzZWN0aW9uRGF0YS0+bm9pc2VOcmdCaXRzKz1GREthYWNFbmNfYml0Q291bnRTY2FsZWZhY3RvckRlbHRhKGRlbHRhUG5zKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn0KCklOVCBGREthYWNFbmNfZHluQml0Q291bnQoCiAgICAgICAgQklUQ05UUl9TVEFURSogY29uc3QgICAgICAgICBoQkMsCiAgICAgICAgY29uc3QgU0hPUlQqIGNvbnN0ICAgICAgICAgICBxdWFudFNwZWN0cnVtLAogICAgICAgIGNvbnN0IFVJTlQqIGNvbnN0ICAgICAgICAgICAgbWF4VmFsdWVJblNmYiwKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgICAgIHNjYWxlZmFjLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgYmxvY2tUeXBlLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgc2ZiQ250LAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgbWF4U2ZiUGVyR3JvdXAsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICBzZmJQZXJHcm91cCwKICAgICAgICBjb25zdCBJTlQqIGNvbnN0ICAgICAgICAgICAgIHNmYk9mZnNldCwKICAgICAgICBTRUNUSU9OX0RBVEEqIGNvbnN0IFJFU1RSSUNUIHNlY3Rpb25EYXRhLAogICAgICAgIGNvbnN0IElOVCogY29uc3QgICAgICAgICAgICAgbm9pc2VOcmcsCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBpc0Jvb2ssCiAgICAgICAgY29uc3QgSU5UKiBjb25zdCAgICAgICAgICAgICBpc1NjYWxlLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MKICAgICAgICApCnsKICBzZWN0aW9uRGF0YS0+YmxvY2tUeXBlICAgICAgPSBibG9ja1R5cGU7CiAgc2VjdGlvbkRhdGEtPnNmYkNudCAgICAgICAgID0gc2ZiQ250OwogIHNlY3Rpb25EYXRhLT5zZmJQZXJHcm91cCAgICA9IHNmYlBlckdyb3VwOwogIHNlY3Rpb25EYXRhLT5ub09mR3JvdXBzICAgICA9IHNmYkNudCAvIHNmYlBlckdyb3VwOwogIHNlY3Rpb25EYXRhLT5tYXhTZmJQZXJHcm91cCA9IG1heFNmYlBlckdyb3VwOwoKICBGREthYWNFbmNfbm9pc2VsZXNzQ291bnRlcigKICAgICAgICAgICAgICAgICAgIHNlY3Rpb25EYXRhLAogICAgICAgICAgICAgICAgICAgaEJDLT5tZXJnZUdhaW5Mb29rVXAsCiAgICAgICAgICAgICAgICAgICAobG9va1VwVGFibGUpaEJDLT5iaXRMb29rVXAsCiAgICAgICAgICAgICAgICAgICBxdWFudFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgbWF4VmFsdWVJblNmYiwKICAgICAgICAgICAgICAgICAgIHNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgIGJsb2NrVHlwZSwKICAgICAgICAgICAgICAgICAgIG5vaXNlTnJnLAogICAgICAgICAgICAgICAgICAgaXNCb29rLAogICAgICAgICAgICAgICAgICAgKHN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpPzE6MCk7CgogIEZES2FhY0VuY19zY2ZDb3VudCgKICAgICAgICAgICBzY2FsZWZhYywKICAgICAgICAgICBtYXhWYWx1ZUluU2ZiLAogICAgICAgICAgIHNlY3Rpb25EYXRhLAogICAgICAgICAgIGlzU2NhbGUpOwoKICBGREthYWNFbmNfbm9pc2VDb3VudChzZWN0aW9uRGF0YSwKICAgICAgICAgICAgIG5vaXNlTnJnKTsKCiAgcmV0dXJuIChzZWN0aW9uRGF0YS0+aHVmZm1hbkJpdHMgKwogICAgICAgICAgc2VjdGlvbkRhdGEtPnNpZGVJbmZvQml0cyArCiAgICAgICAgICBzZWN0aW9uRGF0YS0+c2NhbGVmYWNCaXRzICsKICAgICAgICAgIHNlY3Rpb25EYXRhLT5ub2lzZU5yZ0JpdHMpOwp9CgpJTlQgRkRLYWFjRW5jX0JDTmV3KEJJVENOVFJfU1RBVEUgKipwaEJDCiAgICAgICAgICxVQ0hBUiogZHluYW1pY19SQU0KICAgICAgICAgKQp7CiAgQklUQ05UUl9TVEFURSAqaEJDID0gIEdldFJhbV9hYWNFbmNfQml0Q250clN0YXRlKCk7CgogIGlmIChoQkMpCiAgewogICAgKnBoQkMgPSBoQkM7CiAgICBoQkMtPmJpdExvb2tVcCAgICAgICA9IEdldFJhbV9hYWNFbmNfQml0TG9va1VwKDAsZHluYW1pY19SQU0pOwogICAgaEJDLT5tZXJnZUdhaW5Mb29rVXAgPSBHZXRSYW1fYWFjRW5jX01lcmdlR2Fpbkxvb2tVcCgwLGR5bmFtaWNfUkFNKTsKICAgIGlmIChoQkMtPmJpdExvb2tVcCAgICAgICA9PSAwIHx8CiAgICAgICAgaEJDLT5tZXJnZUdhaW5Mb29rVXAgPT0gMCkKICAgIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgfQogIHJldHVybiAoaEJDID09IDApID8gMSA6IDA7Cn0KCnZvaWQgRkRLYWFjRW5jX0JDQ2xvc2UoQklUQ05UUl9TVEFURSAqKnBoQkMpCnsKICBpZiAoKnBoQkMhPU5VTEwpIHsKCiAgICBGcmVlUmFtX2FhY0VuY19CaXRDbnRyU3RhdGUocGhCQyk7CiAgfQp9CgoKCg==