Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gV2VybmVyCiAgIGNvbnRlbnRzL2Rlc2NyaXB0aW9uOiBTY2FsZSBmYWN0b3IgZXN0aW1hdGlvbgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInNmX2VzdGltLmgiCiNpbmNsdWRlICJhYWNFbmNfcm9tLmgiCiNpbmNsdWRlICJxdWFudGl6ZS5oIgojaW5jbHVkZSAiYml0X2NudC5oIgoKCgoKI2RlZmluZSBBU19QRV9GQUNfU0hJRlQgNwojZGVmaW5lIERJU1RfRkFDX1NISUZUICAzCiNkZWZpbmUgQVNfUEVfRkFDX0ZMT0FUIChmbG9hdCkoMSA8PCBBU19QRV9GQUNfU0hJRlQpCnN0YXRpYyBjb25zdCBJTlQgTUFYX1NDRl9ERUxUQSA9IDYwOwoKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMSA9IEZMMkZYQ09OU1RfREJMKDMuMGYvQVNfUEVfRkFDX0ZMT0FUKTsgICAgICAgICAgLyogKGxvZyg4LjApL2xvZygyKSkgPj4gQVNfUEVfRkFDX1NISUZUICovCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMiA9IEZMMkZYQ09OU1RfREJMKDEuMzIxOTI4MWYvQVNfUEVfRkFDX0ZMT0FUKTsgICAgLyogKGxvZygyLjUpL2xvZygyKSkgPj4gQVNfUEVfRkFDX1NISUZUICovCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMyA9IEZMMkZYQ09OU1RfREJMKDAuNTU5MzU3M2YpOyAgICAgICAgICAgICAgICAgICAgLyogMS1DMi9DMSAqLwoKCi8qCiAgRnVuY3Rpb247IEZES2FhY0VuY19GREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3JDaGFubmVsCgogIERlc2NyaXB0aW9uOiBDYWxjdWxhdGVzIHRoZSBmb3JtZmFjdG9yCgogIHNmOiBzY2FsZSBmYWN0b3Igb2YgdGhlIG1kY3Qgc3BlY3RydW0KICBzZmJGb3JtRmFjdG9yTGREYXRhIGlzIHNjYWxlZCB3aXRoIHRoZSBmYWN0b3IgMS8oKCgyXnNmKV4wLjUpICogKDJeRk9STV9GQUNfU0hJRlQpKQoqLwpzdGF0aWMgdm9pZApGREthYWNFbmNfRkRLYWFjRW5jX0NhbGNGb3JtRmFjdG9yQ2hhbm5lbChGSVhQX0RCTCAqUkVTVFJJQ1Qgc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAqUkVTVFJJQ1QgcHN5T3V0Q2hhbikKewogIElOVCBqLCBzZmIsIHNmYkdycDsKICBGSVhQX0RCTCBmb3JtRmFjdG9yOwoKICBpbnQgdG1wMCA9IHBzeU91dENoYW4tPnNmYkNudDsKICBpbnQgdG1wMSA9IHBzeU91dENoYW4tPm1heFNmYlBlckdyb3VwOwogIGludCBzdGVwID0gcHN5T3V0Q2hhbi0+c2ZiUGVyR3JvdXA7CiAgZm9yKHNmYkdycCA9IDA7IHNmYkdycCA8IHRtcDA7IHNmYkdycCArPSBzdGVwKSB7CiAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IHRtcDE7IHNmYisrKSB7CiAgICAgIGZvcm1GYWN0b3IgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgLyogY2FsYyBzdW0gb2Ygc3FydChzcGVjKSAqLwogICAgICBmb3Ioaj1wc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYkdycCtzZmJdOyBqPHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiR3JwK3NmYisxXTsgaisrICkgewogICAgICAgICBmb3JtRmFjdG9yICs9IHNxcnRGaXhwKGZpeHBfYWJzKHBzeU91dENoYW4tPm1kY3RTcGVjdHJ1bVtqXSkpPj5GT1JNX0ZBQ19TSElGVDsKICAgICAgfQogICAgICBzZmJGb3JtRmFjdG9yTGREYXRhW3NmYkdycCtzZmJdID0gQ2FsY0xkRGF0YShmb3JtRmFjdG9yKTsKICAgIH0KICAgIC8qIHNldCBzZmJGb3JtRmFjdG9yIGZvciBzZmJzIHdpdGggemVybyBzcGVjIHRvIHplcm8uIEp1c3QgZm9yIGRlYnVnZ2luZy4gKi8KICAgIGZvciAoIDsgc2ZiIDwgcHN5T3V0Q2hhbi0+c2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgIHNmYkZvcm1GYWN0b3JMZERhdGFbc2ZiR3JwK3NmYl0gPSBGTDJGWENPTlNUX0RCTCgtMS4wZik7CiAgICB9CiAgfQp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3IKCiAgRGVzY3JpcHRpb246IENhbGxzIEZES2FhY0VuY19GREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3JDaGFubmVsKCkgZm9yIGVhY2ggY2hhbm5lbAoqLwoKdm9pZApGREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3IoUUNfT1VUX0NIQU5ORUwgICAqcWNPdXRDaGFubmVsWygyKV0sCiAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAgKnBzeU91dENoYW5uZWxbKDIpXSwKICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICBuQ2hhbm5lbHMpCnsKICBJTlQgajsKICBmb3IgKGo9MDsgajxuQ2hhbm5lbHM7IGorKykgewogICAgRkRLYWFjRW5jX0ZES2FhY0VuY19DYWxjRm9ybUZhY3RvckNoYW5uZWwocWNPdXRDaGFubmVsW2pdLT5zZmJGb3JtRmFjdG9yTGREYXRhLCBwc3lPdXRDaGFubmVsW2pdKTsKICB9Cn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19jYWxjU2ZiUmVsZXZhbnRMaW5lcwoKICBEZXNjcmlwdGlvbjogQ2FsY3VsYXRlcyBzZmJOUmVsZXZhbnRMaW5lcwoKICBzZmJOUmVsZXZhbnRMaW5lcyBpcyBzY2FsZWQgd2l0aCB0aGUgZmFjdG9yIDEvKCgyXkZPUk1fRkFDX1NISUZUKSAqIDIuMCkKKi8Kc3RhdGljIHZvaWQKRkRLYWFjRW5jX2NhbGNTZmJSZWxldmFudExpbmVzKCBjb25zdCBGSVhQX0RCTCAqY29uc3Qgc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZJWFBfREJMICpjb25zdCBzZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGSVhQX0RCTCAqY29uc3Qgc2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICpjb25zdCBzZmJPZmZzZXRzLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UIHNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBzZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBtYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcykKewogIElOVCBzZmJPZmZzLCBzZmI7CiAgRklYUF9EQkwgc2ZiV2lkdGhMZERhdGE7CiAgRklYUF9EQkwgYXNQZUZhY0xkRGF0YSA9IEZMMkZYQ09OU1RfREJMKDAuMTA5Mzc1KTsgICAvKiBBU19QRV9GQUNfU0hJRlQqbGQ2NCgyKSAqLwogIEZJWFBfREJMIGFjY3U7CgogIC8qIHNmYk5SZWxldmFudExpbmVzW2ldID0gMl4oIChzZmJGb3JtRmFjdG9yTGREYXRhW2ldIC0gMC4yNSAqIChzZmJFbmVyZ3lMZERhdGFbaV0gLSBsZDY0KHNmYldpZHRoW2ldLygyXjcpKSAtIEFTX1BFX0ZBQ19TSElGVCpsZDY0KDIpKSAqIDY0KTsgKi8KCiAgRkRLbWVtY2xlYXIoc2ZiTlJlbGV2YW50TGluZXMsIHNmYkNudCAqIHNpemVvZihGSVhQX0RCTCkpOwoKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2ZmczxzZmJDbnQ7IHNmYk9mZnMrPXNmYlBlckdyb3VwKSB7CiAgICBmb3Ioc2ZiPTA7IHNmYjxtYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgLyogY2FsYyBzdW0gb2Ygc3FydChzcGVjKSAqLwogICAgICBpZigoRklYUF9EQkwpc2ZiRW5lcmd5TGREYXRhW3NmYk9mZnMrc2ZiXSA+IChGSVhQX0RCTClzZmJUaHJlc2hvbGRMZERhdGFbc2ZiT2ZmcytzZmJdKSB7CiAgICAgICAgSU5UIHNmYldpZHRoID0gc2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYisxXSAtIHNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdOwoKICAgICAgICAvKiBhdmdGb3JtRmFjdG9yTGREYXRhID0gc3FydEZpeHAoc3FydEZpeHAoc2ZiRW5lcmd5TGREYXRhW3NmYk9mZnMrc2ZiXS9zZmJXaWR0aCkpOyAqLwogICAgICAgIC8qIHNmYk5SZWxldmFudExpbmVzW3NmYk9mZnMrc2ZiXSA9IHNmYkZvcm1GYWN0b3Jbc2ZiT2ZmcytzZmJdIC8gYXZnRm9ybUZhY3RvckxkRGF0YTsgKi8KICAgICAgICBzZmJXaWR0aExkRGF0YSA9IChGSVhQX0RCTCkoc2ZiV2lkdGggPDwgKERGUkFDVF9CSVRTLTEtQVNfUEVfRkFDX1NISUZUKSk7CiAgICAgICAgc2ZiV2lkdGhMZERhdGEgPSBDYWxjTGREYXRhKHNmYldpZHRoTGREYXRhKTsKCiAgICAgICAgYWNjdSA9IHNmYkVuZXJneUxkRGF0YVtzZmJPZmZzK3NmYl0gLSBzZmJXaWR0aExkRGF0YSAtIGFzUGVGYWNMZERhdGE7CiAgICAgICAgYWNjdSA9IHNmYkZvcm1GYWN0b3JMZERhdGFbc2ZiT2ZmcytzZmJdIC0gKGFjY3UgPj4gMik7CgogICAgICAgIHNmYk5SZWxldmFudExpbmVzW3NmYk9mZnMrc2ZiXSA9IENhbGNJbnZMZERhdGEoYWNjdSkgPj4gMTsKICAgICAgfQogICAgfQogIH0KfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX2NvdW50U2luZ2xlU2NmQml0cwoKICBEZXNjcmlwdGlvbjoKCiAgc2NmQml0c0ZyYWN0IGlzIHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpCiovCnN0YXRpYyBGSVhQX0RCTCBGREthYWNFbmNfY291bnRTaW5nbGVTY2ZCaXRzKElOVCBzY2YsIElOVCBzY2ZMZWZ0LCBJTlQgc2NmUmlnaHQpCnsKICBGSVhQX0RCTCBzY2ZCaXRzRnJhY3Q7CgogIHNjZkJpdHNGcmFjdCA9IChGSVhQX0RCTCkgKCAgRkRLYWFjRW5jX2JpdENvdW50U2NhbGVmYWN0b3JEZWx0YShzY2ZMZWZ0LXNjZikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmLXNjZlJpZ2h0KSApOwoKICBzY2ZCaXRzRnJhY3QgPSBzY2ZCaXRzRnJhY3QgPDwgKERGUkFDVF9CSVRTLTEtKDIqQVNfUEVfRkFDX1NISUZUKSk7CgogIHJldHVybiBzY2ZCaXRzRnJhY3Q7IC8qIG91dHB1dCBzY2FsZWQgYnkgMS8oMl4oMipBU19QRV9GQUMpKSAqLwp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfY2FsY1NpbmdsZVNwZWNQZQoKICBzcGVjUGUgaXMgc2NhbGVkIGJ5IDEvKDJeKDIqQVNfUEVfRkFDX1NISUZUKSkKKi8Kc3RhdGljIEZJWFBfREJMIEZES2FhY0VuY19jYWxjU2luZ2xlU3BlY1BlKElOVCBzY2YsIEZJWFBfREJMIHNmYkNvbnN0UGVQYXJ0LCBGSVhQX0RCTCBuTGluZXMpCnsKICBGSVhQX0RCTCBzcGVjUGUgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBGSVhQX0RCTCBsZFJhdGlvOwogIEZJWFBfREJMIHNjZkZyYWN0OwoKICBzY2ZGcmFjdCA9IChGSVhQX0RCTCkoc2NmIDw8IChERlJBQ1RfQklUUy0xLUFTX1BFX0ZBQ19TSElGVCkpOwoKICBsZFJhdGlvID0gc2ZiQ29uc3RQZVBhcnQgLSBmTXVsdChGTDJGWENPTlNUX0RCTCgwLjM3NWYpLHNjZkZyYWN0KTsKCiAgaWYgKGxkUmF0aW8gPj0gUEVfQzEpIHsKICAgIHNwZWNQZSA9IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuN2YpLGZNdWx0KG5MaW5lcyxsZFJhdGlvKSk7CiAgfQogIGVsc2UgewogICAgc3BlY1BlID0gZk11bHQoRkwyRlhDT05TVF9EQkwoMC43ZiksZk11bHQobkxpbmVzLChQRV9DMiArIGZNdWx0KFBFX0MzLGxkUmF0aW8pKSkpOwogIH0KCiAgcmV0dXJuIHNwZWNQZTsgLyogb3V0cHV0IHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQykpICovCn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmCgogIHNjZkJpdHNEaWZmIGlzIHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpCiovCnN0YXRpYyBGSVhQX0RCTCBGREthYWNFbmNfY291bnRTY2ZCaXRzRGlmZihJTlQgKnNjZk9sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydFNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHN0b3BTZmIpCnsKICBGSVhQX0RCTCBzY2ZCaXRzRnJhY3Q7CiAgSU5UIHNjZkJpdHNEaWZmID0gMDsKICBJTlQgc2ZiID0gMCwgc2ZiTGFzdDsKICBJTlQgc2ZiUHJldiwgc2ZiTmV4dDsKCiAgLyogc2VhcmNoIGZvciBmaXJzdCByZWxldmFudCBzZmIgKi8KICBzZmJMYXN0ID0gc3RhcnRTZmI7CiAgd2hpbGUgKChzZmJMYXN0PHN0b3BTZmIpICYmIChzY2ZPbGRbc2ZiTGFzdF09PUZES19JTlRfTUlOKSkKICAgIHNmYkxhc3QrKzsKICAvKiBzZWFyY2ggZm9yIHByZXZpb3VzIHJlbGV2YW50IHNmYiBhbmQgY291bnQgZGlmZiAqLwogIHNmYlByZXYgPSBzdGFydFNmYiAtIDE7CiAgd2hpbGUgKChzZmJQcmV2Pj0wKSAmJiAoc2NmT2xkW3NmYlByZXZdPT1GREtfSU5UX01JTikpCiAgICBzZmJQcmV2LS07CiAgaWYgKHNmYlByZXY+PTApCiAgICBzY2ZCaXRzRGlmZiArPSBGREthYWNFbmNfYml0Q291bnRTY2FsZWZhY3RvckRlbHRhKHNjZk5ld1tzZmJQcmV2XS1zY2ZOZXdbc2ZiTGFzdF0pIC0KICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYlByZXZdLXNjZk9sZFtzZmJMYXN0XSk7CiAgLyogbm93IGxvb3AgdGhyb3VnaCBhbGwgc2ZicyBhbmQgY291bnQgZGlmZnMgb2YgcmVsZXZhbnQgc2ZicyAqLwogIGZvciAoc2ZiPXNmYkxhc3QrMTsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICBpZiAoc2NmT2xkW3NmYl0hPUZES19JTlRfTUlOKSB7CiAgICAgIHNjZkJpdHNEaWZmICs9IEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmTmV3W3NmYkxhc3RdLXNjZk5ld1tzZmJdKSAtCiAgICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYkxhc3RdLXNjZk9sZFtzZmJdKTsKICAgICAgc2ZiTGFzdCA9IHNmYjsKICAgIH0KICB9CiAgLyogc2VhcmNoIGZvciBuZXh0IHJlbGV2YW50IHNmYiBhbmQgY291bnQgZGlmZiAqLwogIHNmYk5leHQgPSBzdG9wU2ZiOwogIHdoaWxlICgoc2ZiTmV4dDxzZmJDbnQpICYmIChzY2ZPbGRbc2ZiTmV4dF09PUZES19JTlRfTUlOKSkKICAgIHNmYk5leHQrKzsKICBpZiAoc2ZiTmV4dDxzZmJDbnQpCiAgICBzY2ZCaXRzRGlmZiArPSBGREthYWNFbmNfYml0Q291bnRTY2FsZWZhY3RvckRlbHRhKHNjZk5ld1tzZmJMYXN0XS1zY2ZOZXdbc2ZiTmV4dF0pIC0KICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYkxhc3RdLXNjZk9sZFtzZmJOZXh0XSk7CgogIHNjZkJpdHNGcmFjdCA9IChGSVhQX0RCTCkgKHNjZkJpdHNEaWZmIDw8IChERlJBQ1RfQklUUy0xLSgyKkFTX1BFX0ZBQ19TSElGVCkpKTsKCiAgcmV0dXJuIHNjZkJpdHNGcmFjdDsKfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmCgogIHNwZWNQZURpZmYgaXMgc2NhbGVkIGJ5IDEvKDJeKDIqQVNfUEVfRkFDX1NISUZUKSkKKi8Kc3RhdGljIEZJWFBfREJMIEZES2FhY0VuY19jYWxjU3BlY1BlRGlmZihQU1lfT1VUX0NIQU5ORUwgKnBzeU91dENoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfQ0hBTk5FTCAgKnFjT3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqc2NmT2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydFNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdG9wU2ZiKQp7CiAgRklYUF9EQkwgc3BlY1BlRGlmZiA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIEZJWFBfREJMIHNjZkZyYWN0ID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgSU5UIHNmYjsKCiAgLyogbG9vcCB0aHJvdWdoIGFsbCBzZmJzIGFuZCBjb3VudCBwZSBkaWZmZXJlbmNlICovCiAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgaWYgKHNjZk9sZFtzZmJdIT1GREtfSU5UX01JTikgewogICAgICBGSVhQX0RCTCBsZFJhdGlvT2xkLCBsZFJhdGlvTmV3LCBwT2xkLCBwTmV3OwoKICAgICAgLyogc2ZiQ29uc3RQZVBhcnRbc2ZiXSA9IChmbG9hdClsb2cocHN5T3V0Q2hhbi0+c2ZiRW5lcmd5W3NmYl0gKiA2Ljc1ZiAvIHNmYkZvcm1GYWN0b3Jbc2ZiXSkgKiBMT0cyXzE7ICovCiAgICAgIC8qIDAuMDIxNTIyNTU4NjFmID0gbG9nKDYuNzUpL2xvZygyKS9BU19QRV9GQUNfRkxPQVQ7IExPRzJfMSBpcyAxLjAgZm9yIGxvZzIgKi8KICAgICAgLyogMC4wOTM3NWYgPSBsb2coNjQuMCkvbG9nKDIuMCkvNjQuMCA9IHNjYWxlIG9mIHNmYkZvcm1GYWN0b3JMZERhdGEgKi8KICAgICAgaWYgKHNmYkNvbnN0UGVQYXJ0W3NmYl0gPT0gKEZJWFBfREJMKUZES19JTlRfTUlOKQogICAgICAgIHNmYkNvbnN0UGVQYXJ0W3NmYl0gPSAoKHBzeU91dENoYW4tPnNmYkVuZXJneUxkRGF0YVtzZmJdIC0gc2ZiRm9ybUZhY3RvckxkRGF0YVtzZmJdIC0gRkwyRlhDT05TVF9EQkwoMC4wOTM3NWYpKSA+PiAxKSArIEZMMkZYQ09OU1RfREJMKDAuMDIxNTIyNTU4NjFmKTsKCiAgICAgIHNjZkZyYWN0ID0gKEZJWFBfREJMKSAoc2NmT2xkW3NmYl0gPDwgKERGUkFDVF9CSVRTLTEtQVNfUEVfRkFDX1NISUZUKSk7CiAgICAgIGxkUmF0aW9PbGQgPSBzZmJDb25zdFBlUGFydFtzZmJdIC0gZk11bHQoRkwyRlhDT05TVF9EQkwoMC4zNzVmKSxzY2ZGcmFjdCk7CgogICAgICBzY2ZGcmFjdCA9IChGSVhQX0RCTCkgKHNjZk5ld1tzZmJdIDw8IChERlJBQ1RfQklUUy0xLUFTX1BFX0ZBQ19TSElGVCkpOwogICAgICBsZFJhdGlvTmV3ID0gc2ZiQ29uc3RQZVBhcnRbc2ZiXSAtIGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuMzc1Ziksc2NmRnJhY3QpOwoKICAgICAgaWYgKGxkUmF0aW9PbGQgPj0gUEVfQzEpCiAgICAgICAgcE9sZCA9IGxkUmF0aW9PbGQ7CiAgICAgIGVsc2UKICAgICAgICBwT2xkID0gUEVfQzIgKyBmTXVsdChQRV9DMyxsZFJhdGlvT2xkKTsKCiAgICAgIGlmIChsZFJhdGlvTmV3ID49IFBFX0MxKQogICAgICAgIHBOZXcgPSBsZFJhdGlvTmV3OwogICAgICBlbHNlCiAgICAgICAgcE5ldyA9IFBFX0MyICsgZk11bHQoUEVfQzMsbGRSYXRpb05ldyk7CgogICAgICBzcGVjUGVEaWZmICs9IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuN2YpLGZNdWx0KHNmYk5SZWxldmFudExpbmVzW3NmYl0sKHBOZXcgLSBwT2xkKSkpOwogICAgfQogIH0KCiAgcmV0dXJuIHNwZWNQZURpZmY7Cn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19pbXByb3ZlU2NmCgogIERlc2NyaXB0aW9uOiBDYWxjdWxhdGUgdGhlIGRpc3RvcnRpb24gYnkgcXVhbnRpemF0aW9uIGFuZCBpbnZlcnNlIHF1YW50aXphdGlvbiBvZiB0aGUgc3BlY3RydW0gd2l0aAogICAgICAgICAgICAgICB2YXJpb3VzIHNjYWxlZmFjdG9ycy4gVGhlIHNjYWxlZmFjdG9yIHdoaWNoIHByb3ZpZGVzIHRoZSBiZXN0IHJlc3VsdHMgd2lsbCBiZSB1c2VkLgoqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19pbXByb3ZlU2NmKEZJWFBfREJMICpzcGVjLAogICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgdGhyZXNoTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgSU5UIHNjZiwKICAgICAgICAgICAgICAgICAgICAgIElOVCBtaW5TY2YsCiAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgKmRpc3RMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZkNhbGN1bGF0ZWQKICAgICAgICAgICAgICAgICAgICAgICkKewogICBGSVhQX0RCTCBzZmJEaXN0TGREYXRhOwogICBJTlQgc2NmQmVzdCA9IHNjZjsKICAgSU5UIGs7CiAgIEZJWFBfREJMIGRpc3RGYWN0b3JMZERhdGEgPSBGTDJGWENPTlNUX0RCTCgtMC4wMDUwMzAxMjY1KTsgICAvKiBsZDY0KDEvMS4yNSkgKi8KCiAgIC8qIGNhbGMgcmVhbCBkaXN0b3J0aW9uICovCiAgIHNmYkRpc3RMZERhdGEgPSBGREthYWNFbmNfY2FsY1NmYkRpc3Qoc3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NmKTsKICAgKm1pblNjZkNhbGN1bGF0ZWQgPSBzY2Y7CiAgIC8qIG5tciA+IDEuMjUgLT4gdHJ5IHRvIGltcHJvdmUgbm1yICovCiAgIGlmIChzZmJEaXN0TGREYXRhID4gKHRocmVzaExkRGF0YS1kaXN0RmFjdG9yTGREYXRhKSkgewogICAgICBJTlQgc2NmRXN0aW1hdGVkID0gc2NmOwogICAgICBGSVhQX0RCTCBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgIElOVCBjbnQ7CiAgICAgIC8qIGltcHJvdmUgYnkgYmlnZ2VyIHNjZiA/ICovCiAgICAgIGNudCA9IDA7CgogICAgICB3aGlsZSAoKHNmYkRpc3RMZERhdGEgPiAodGhyZXNoTGREYXRhLWRpc3RGYWN0b3JMZERhdGEpKSAmJiAoY250KysgPCAzKSkgewogICAgICAgICBzY2YrKzsKICAgICAgICAgc2ZiRGlzdExkRGF0YSA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2YpOwoKICAgICAgICAgaWYgKHNmYkRpc3RMZERhdGEgPCBzZmJEaXN0QmVzdExkRGF0YSkgewogICAgICAgICAgICBzY2ZCZXN0ID0gc2NmOwogICAgICAgICAgICBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYldpZHRoOyBrKyspCgkgICAgICAgICAgICAgcXVhbnRTcGVjW2tdID0gcXVhbnRTcGVjVG1wW2tdOwogICAgICAgICB9CiAgICAgIH0KICAgICAgLyogaW1wcm92ZSBieSBzbWFsbGVyIHNjZiA/ICovCiAgICAgIGNudCA9IDA7CiAgICAgIHNjZiA9IHNjZkVzdGltYXRlZDsKICAgICAgc2ZiRGlzdExkRGF0YSA9IHNmYkRpc3RCZXN0TGREYXRhOwogICAgICB3aGlsZSAoKHNmYkRpc3RMZERhdGEgPiAodGhyZXNoTGREYXRhLWRpc3RGYWN0b3JMZERhdGEpKSAmJiAoY250KysgPCAxKSAmJiAoc2NmID4gbWluU2NmKSkgewogICAgICAgICBzY2YtLTsKICAgICAgICAgc2ZiRGlzdExkRGF0YSA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2YpOwoKICAgICAgICAgaWYgKHNmYkRpc3RMZERhdGEgPCBzZmJEaXN0QmVzdExkRGF0YSkgewogICAgICAgICAgICBzY2ZCZXN0ID0gc2NmOwogICAgICAgICAgICBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYldpZHRoOyBrKyspCgkgICAgICAgICAgICAgcXVhbnRTcGVjW2tdID0gcXVhbnRTcGVjVG1wW2tdOwogICAgICAgICB9CiAgICAgICAgICptaW5TY2ZDYWxjdWxhdGVkID0gc2NmOwogICAgICB9CiAgICAgICpkaXN0TGREYXRhID0gc2ZiRGlzdEJlc3RMZERhdGE7CiAgIH0KICAgZWxzZSB7IC8qIG5tciA8PSAxLjI1IC0+IHRyeSB0byBmaW5kIGJpZ2dlciBzY2YgdG8gdXNlIGxlc3MgYml0cyAqLwogICAgICBGSVhQX0RCTCBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgIEZJWFBfREJMIHNmYkRpc3RBbGxvd2VkTGREYXRhID0gZml4TWluKHNmYkRpc3RMZERhdGEtZGlzdEZhY3RvckxkRGF0YSx0aHJlc2hMZERhdGEpOwogICAgICBpbnQgY250OwogICAgICBmb3IgKGNudD0wOyBjbnQ8MzsgY250KyspIHsKICAgICAgICAgc2NmKys7CiAgICAgICAgIHNmYkRpc3RMZERhdGEgPSBGREthYWNFbmNfY2FsY1NmYkRpc3Qoc3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NmKTsKCiAgICAgICAgIGlmIChzZmJEaXN0TGREYXRhIDwgc2ZiRGlzdEFsbG93ZWRMZERhdGEpIHsKICAgICAgICAgICAqbWluU2NmQ2FsY3VsYXRlZCA9IHNjZkJlc3QrMTsKICAgICAgICAgICBzY2ZCZXN0ID0gc2NmOwogICAgICAgICAgIHNmYkRpc3RCZXN0TGREYXRhID0gc2ZiRGlzdExkRGF0YTsKICAgICAgICAgICBmb3IgKGs9MDsgazxzZmJXaWR0aDsgaysrKQogICAgICAgICAgICAgcXVhbnRTcGVjW2tdID0gcXVhbnRTcGVjVG1wW2tdOwogICAgICAgICB9CiAgICAgIH0KICAgICAgKmRpc3RMZERhdGEgPSBzZmJEaXN0QmVzdExkRGF0YTsKICAgfQoKICAgLyogcmV0dXJuIGJlc3Qgc2NhbGVmYWN0b3IgKi8KICAgcmV0dXJuIHNjZkJlc3Q7Cn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19hc3NpbWlsYXRlU2luZ2xlU2NmCgoqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfYXNzaW1pbGF0ZVNpbmdsZVNjZihQU1lfT1VUX0NIQU5ORUwgKnBzeU91dENoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0NIQU5ORUwgICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkZvcm1GYWN0b3JMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYk5SZWxldmFudExpbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqbWluU2NmQ2FsY3VsYXRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcmVzdGFydE9uU3VjY2VzcykKewogIElOVCBzZmJMYXN0LCBzZmJBY3QsIHNmYk5leHQ7CiAgSU5UIHNjZkFjdCwgKnNjZkxhc3QsICpzY2ZOZXh0LCBzY2ZNaW4sIHNjZk1heDsKICBJTlQgc2ZiV2lkdGgsIHNmYk9mZnM7CiAgRklYUF9EQkwgZW5MZERhdGE7CiAgRklYUF9EQkwgc2ZiUGVPbGQsIHNmYlBlTmV3OwogIEZJWFBfREJMIHNmYkRpc3ROZXc7CiAgSU5UIGksIGs7CiAgSU5UIHN1Y2Nlc3MgPSAwOwogIEZJWFBfREJMIGRlbHRhUGUgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBGSVhQX0RCTCBkZWx0YVBlTmV3LCBkZWx0YVBlVG1wOwogIElOVCBwcmV2U2NmTGFzdFtNQVhfR1JPVVBFRF9TRkJdLCBwcmV2U2NmTmV4dFtNQVhfR1JPVVBFRF9TRkJdOwogIEZJWFBfREJMIGRlbHRhUGVMYXN0W01BWF9HUk9VUEVEX1NGQl07CiAgSU5UIHVwZGF0ZU1pblNjZkNhbGN1bGF0ZWQ7CgogIGZvciAoaT0wOyBpPHBzeU91dENoYW4tPnNmYkNudDsgaSsrKSB7CiAgICBwcmV2U2NmTGFzdFtpXSA9IEZES19JTlRfTUFYOwogICAgcHJldlNjZk5leHRbaV0gPSBGREtfSU5UX01BWDsKICAgIGRlbHRhUGVMYXN0W2ldID0gKEZJWFBfREJMKUZES19JTlRfTUFYOwogIH0KCiAgc2ZiTGFzdCA9IC0xOwogIHNmYkFjdCAgPSAtMTsKICBzZmJOZXh0ID0gLTE7CiAgc2NmTGFzdCA9IDA7CiAgc2NmTmV4dCA9IDA7CiAgc2NmTWluICA9IEZES19JTlRfTUFYOwogIHNjZk1heCAgPSBGREtfSU5UX01BWDsKICBkbyB7CiAgICAvKiBzZWFyY2ggZm9yIG5ldyByZWxldmFudCBzZmIgKi8KICAgIHNmYk5leHQrKzsKICAgIHdoaWxlICgoc2ZiTmV4dCA8IHBzeU91dENoYW4tPnNmYkNudCkgJiYgKHNjZltzZmJOZXh0XSA9PSBGREtfSU5UX01JTikpCiAgICAgIHNmYk5leHQrKzsKICAgIGlmICgoc2ZiTGFzdD49MCkgJiYgKHNmYkFjdD49MCkgJiYgKHNmYk5leHQ8cHN5T3V0Q2hhbi0+c2ZiQ250KSkgewogICAgICAvKiByZWxldmFudCBzY2ZzIHRvIHRoZSBsZWZ0IGFuZCB0byB0aGUgcmlnaHQgKi8KICAgICAgc2NmQWN0ICA9IHNjZltzZmJBY3RdOwogICAgICBzY2ZMYXN0ID0gc2NmICsgc2ZiTGFzdDsKICAgICAgc2NmTmV4dCA9IHNjZiArIHNmYk5leHQ7CiAgICAgIHNjZk1pbiAgPSBmaXhNaW4oKnNjZkxhc3QsICpzY2ZOZXh0KTsKICAgICAgc2NmTWF4ICA9IGZpeE1heCgqc2NmTGFzdCwgKnNjZk5leHQpOwogICAgfQogICAgZWxzZSBpZiAoKHNmYkxhc3Q9PS0xKSAmJiAoc2ZiQWN0Pj0wKSAmJiAoc2ZiTmV4dDxwc3lPdXRDaGFuLT5zZmJDbnQpKSB7CiAgICAgIC8qIGZpcnN0IHJlbGV2YW50IHNjZiAqLwogICAgICBzY2ZBY3QgID0gc2NmW3NmYkFjdF07CiAgICAgIHNjZkxhc3QgPSAmc2NmQWN0OwogICAgICBzY2ZOZXh0ID0gc2NmICsgc2ZiTmV4dDsKICAgICAgc2NmTWluICA9ICpzY2ZOZXh0OwogICAgICBzY2ZNYXggID0gKnNjZk5leHQ7CiAgICB9CiAgICBlbHNlIGlmICgoc2ZiTGFzdD49MCkgJiYgKHNmYkFjdD49MCkgJiYgKHNmYk5leHQ9PXBzeU91dENoYW4tPnNmYkNudCkpIHsKICAgICAgLyogbGFzdCByZWxldmFudCBzY2YgKi8KICAgICAgc2NmQWN0ICA9IHNjZltzZmJBY3RdOwogICAgICBzY2ZMYXN0ID0gc2NmICsgc2ZiTGFzdDsKICAgICAgc2NmTmV4dCA9ICZzY2ZBY3Q7CiAgICAgIHNjZk1pbiAgPSAqc2NmTGFzdDsKICAgICAgc2NmTWF4ICA9ICpzY2ZMYXN0OwogICAgfQogICAgaWYgKHNmYkFjdD49MCkKICAgICAgc2NmTWluID0gZml4TWF4KHNjZk1pbiwgbWluU2NmW3NmYkFjdF0pOwoKICAgIGlmICgoc2ZiQWN0ID49IDApICYmCiAgICAgICAgKHNmYkxhc3Q+PTAgfHwgc2ZiTmV4dDxwc3lPdXRDaGFuLT5zZmJDbnQpICYmCiAgICAgICAgKHNjZkFjdCA+IHNjZk1pbikgJiYKICAgICAgICAoc2NmQWN0IDw9IHNjZk1pbitNQVhfU0NGX0RFTFRBKSAmJgogICAgICAgIChzY2ZBY3QgPj0gc2NmTWF4LU1BWF9TQ0ZfREVMVEEpICYmCiAgICAgICAgKCpzY2ZMYXN0ICE9IHByZXZTY2ZMYXN0W3NmYkFjdF0gfHwKICAgICAgICAgKnNjZk5leHQgIT0gcHJldlNjZk5leHRbc2ZiQWN0XSB8fAogICAgICAgICBkZWx0YVBlIDwgZGVsdGFQZUxhc3Rbc2ZiQWN0XSkpIHsKICAgICAgLyogYmlnZ2VyIHRoYW4gbmVpZ2hib3VyaW5nIHNjZiBmb3VuZCwgdHJ5IHRvIHVzZSBzbWFsbGVyIHNjZiAqLwogICAgICBzdWNjZXNzID0gMDsKCiAgICAgIHNmYldpZHRoID0gcHN5T3V0Q2hhbi0+c2ZiT2Zmc2V0c1tzZmJBY3QrMV0gLSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYkFjdF07CiAgICAgIHNmYk9mZnMgPSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYkFjdF07CgogICAgICAvKiBlc3RpbWF0ZSByZXF1aXJlZCBiaXRzIGZvciBhY3R1YWwgc2NmICovCiAgICAgIGVuTGREYXRhID0gcWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiQWN0XTsKCiAgICAgIC8qIHNmYkNvbnN0UGVQYXJ0W3NmYkFjdF0gPSAoZmxvYXQpbG9nKDYuNzVmKmVuL3NmYkZvcm1GYWN0b3Jbc2ZiQWN0XSkgKiBMT0cyXzE7ICovCiAgICAgIC8qIDAuMDIxNTIyNTU4NjFmID0gbG9nKDYuNzUpL2xvZygyKS9BU19QRV9GQUNfRkxPQVQ7IExPRzJfMSBpcyAxLjAgZm9yIGxvZzIgKi8KICAgICAgLyogMC4wOTM3NWYgPSBsb2coNjQuMCkvbG9nKDIuMCkvNjQuMCA9IHNjYWxlIG9mIHNmYkZvcm1GYWN0b3JMZERhdGEgKi8KICAgICAgaWYgKHNmYkNvbnN0UGVQYXJ0W3NmYkFjdF0gPT0gKEZJWFBfREJMKUZES19JTlRfTUlOKSB7CiAgICAgICAgc2ZiQ29uc3RQZVBhcnRbc2ZiQWN0XSA9ICgoZW5MZERhdGEgLSBzZmJGb3JtRmFjdG9yTGREYXRhW3NmYkFjdF0gLSBGTDJGWENPTlNUX0RCTCgwLjA5Mzc1ZikpID4+IDEpICsgRkwyRlhDT05TVF9EQkwoMC4wMjE1MjI1NTg2MWYpOwogICAgICB9CgogICAgICBzZmJQZU9sZCA9IEZES2FhY0VuY19jYWxjU2luZ2xlU3BlY1BlKHNjZkFjdCxzZmJDb25zdFBlUGFydFtzZmJBY3RdLHNmYk5SZWxldmFudExpbmVzW3NmYkFjdF0pCiAgICAgICAgICAgICAgICArRkRLYWFjRW5jX2NvdW50U2luZ2xlU2NmQml0cyhzY2ZBY3QsICpzY2ZMYXN0LCAqc2NmTmV4dCk7CgogICAgICBkZWx0YVBlTmV3ID0gZGVsdGFQZTsKICAgICAgdXBkYXRlTWluU2NmQ2FsY3VsYXRlZCA9IDE7CgogICAgICBkbyB7CiAgICAgICAgLyogZXN0aW1hdGUgcmVxdWlyZWQgYml0cyBmb3Igc21hbGxlciBzY2YgKi8KICAgICAgICBzY2ZBY3QtLTsKICAgICAgICAvKiBjaGVjayBvbmx5IGlmIHRoZSBzYW1lIGNoZWNrIHdhcyBub3QgZG9uZSBiZWZvcmUgKi8KICAgICAgICBpZiAoc2NmQWN0IDwgbWluU2NmQ2FsY3VsYXRlZFtzZmJBY3RdICYmIHNjZkFjdD49c2NmTWF4LU1BWF9TQ0ZfREVMVEEpewogICAgICAgICAgLyogZXN0aW1hdGUgcmVxdWlyZWQgYml0cyBmb3IgbmV3IHNjZiAqLwogICAgICAgICAgc2ZiUGVOZXcgPSAgRkRLYWFjRW5jX2NhbGNTaW5nbGVTcGVjUGUoc2NmQWN0LHNmYkNvbnN0UGVQYXJ0W3NmYkFjdF0sc2ZiTlJlbGV2YW50TGluZXNbc2ZiQWN0XSkKICAgICAgICAgICAgICAgICAgICAgK0ZES2FhY0VuY19jb3VudFNpbmdsZVNjZkJpdHMoc2NmQWN0LCpzY2ZMYXN0LCAqc2NmTmV4dCk7CgogICAgICAgICAgLyogdXNlIG5ldyBzY2YgaWYgbm8gaW5jcmVhc2UgaW4gcGUgYW5kCiAgICAgICAgICAgICBxdWFudGl6YXRpb24gZXJyb3IgaXMgc21hbGxlciAqLwogICAgICAgICAgZGVsdGFQZVRtcCA9IGRlbHRhUGUgKyBzZmJQZU5ldyAtIHNmYlBlT2xkOwogICAgICAgICAgLyogMC4wMDA2MTAzNTE1NjI1ZiA9IDEwLjBmLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpICovCiAgICAgICAgICBpZiAoZGVsdGFQZVRtcCA8IEZMMkZYQ09OU1RfREJMKDAuMDAwNjEwMzUxNTYyNWYpKSB7CiAgICAgICAgICAgIC8qIGRpc3RvcnRpb24gb2YgbmV3IHNjZiAqLwogICAgICAgICAgICBzZmJEaXN0TmV3ID0gRkRLYWFjRW5jX2NhbGNTZmJEaXN0KHFjT3V0Q2hhbm5lbC0+bWRjdFNwZWN0cnVtK3NmYk9mZnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjVG1wK3NmYk9mZnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NmQWN0KTsKCiAgICAgICAgICAgIGlmIChzZmJEaXN0TmV3IDwgc2ZiRGlzdFtzZmJBY3RdKSB7CiAgICAgICAgICAgICAgLyogc3VjY2VzcywgcmVwbGFjZSBzY2YgYnkgbmV3IG9uZSAqLwogICAgICAgICAgICAgIHNjZltzZmJBY3RdID0gc2NmQWN0OwogICAgICAgICAgICAgIHNmYkRpc3Rbc2ZiQWN0XSA9IHNmYkRpc3ROZXc7CgogICAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYldpZHRoOyBrKyspCiAgICAgICAgICAgICAgICBxdWFudFNwZWNbc2ZiT2ZmcytrXSA9IHF1YW50U3BlY1RtcFtzZmJPZmZzK2tdOwoKICAgICAgICAgICAgICBkZWx0YVBlTmV3ID0gZGVsdGFQZVRtcDsKICAgICAgICAgICAgICBzdWNjZXNzID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBtYXJrIGFzIGFscmVhZHkgY2hlY2tlZCAqLwogICAgICAgICAgICBpZiAodXBkYXRlTWluU2NmQ2FsY3VsYXRlZCkKICAgICAgICAgICAgICBtaW5TY2ZDYWxjdWxhdGVkW3NmYkFjdF0gPSBzY2ZBY3Q7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyogZnJvbSB0aGlzIHNjZiB2YWx1ZSBvbiBub3QgYWxsIG5ldyB2YWx1ZXMgaGF2ZSBiZWVuIGNoZWNrZWQgKi8KICAgICAgICAgICAgdXBkYXRlTWluU2NmQ2FsY3VsYXRlZCA9IDA7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9IHdoaWxlIChzY2ZBY3QgPiBzY2ZNaW4pOwoKICAgICAgZGVsdGFQZSA9IGRlbHRhUGVOZXc7CgogICAgICAvKiBzYXZlIHBhcmFtZXRlcnMgdG8gYXZvaWQgbXVsdGlwbGUgY29tcHV0YXRpb25zIG9mIHRoZSBzYW1lIHNmYiAqLwogICAgICBwcmV2U2NmTGFzdFtzZmJBY3RdID0gKnNjZkxhc3Q7CiAgICAgIHByZXZTY2ZOZXh0W3NmYkFjdF0gPSAqc2NmTmV4dDsKICAgICAgZGVsdGFQZUxhc3Rbc2ZiQWN0XSA9IGRlbHRhUGU7CiAgICB9CgogICAgaWYgKHN1Y2Nlc3MgJiYgcmVzdGFydE9uU3VjY2VzcykgewogICAgICAvKiBzdGFydCBhZ2FpbiBhdCBmaXJzdCBzZmIgKi8KICAgICAgc2ZiTGFzdCA9IC0xOwogICAgICBzZmJBY3QgID0gLTE7CiAgICAgIHNmYk5leHQgPSAtMTsKICAgICAgc2NmTGFzdCA9IDA7CiAgICAgIHNjZk5leHQgPSAwOwogICAgICBzY2ZNaW4gID0gRkRLX0lOVF9NQVg7CiAgICAgIHNjZk1heCAgPSBGREtfSU5UX01BWDsKICAgICAgc3VjY2VzcyA9IDA7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogc2hpZnQgc2ZicyBmb3IgbmV4dCBiYW5kICovCiAgICAgIHNmYkxhc3QgPSBzZmJBY3Q7CiAgICAgIHNmYkFjdCAgPSBzZmJOZXh0OwogICAgfQogIH0gd2hpbGUgKHNmYk5leHQgPCBwc3lPdXRDaGFuLT5zZmJDbnQpOwp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmCgoqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmKFBTWV9PVVRfQ0hBTk5FTCAqcHN5T3V0Q2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqbWluU2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkRpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcykKewogIElOVCBzZmIsIHN0YXJ0U2ZiLCBzdG9wU2ZiOwogIElOVCBzY2ZUbXBbTUFYX0dST1VQRURfU0ZCXSwgc2NmTWluLCBzY2ZNYXgsIHNjZkFjdDsKICBJTlQgcG9zc2libGVSZWdpb25Gb3VuZDsKICBJTlQgc2ZiV2lkdGgsIHNmYk9mZnMsIGksIGs7CiAgRklYUF9EQkwgc2ZiRGlzdE5ld1tNQVhfR1JPVVBFRF9TRkJdLCBkaXN0T2xkU3VtLCBkaXN0TmV3U3VtOwogIElOVCBkZWx0YVNjZkJpdHM7CiAgRklYUF9EQkwgZGVsdGFTcGVjUGU7CiAgRklYUF9EQkwgZGVsdGFQZSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIEZJWFBfREJMIGRlbHRhUGVOZXc7CiAgSU5UIHNmYkNudCA9IHBzeU91dENoYW4tPnNmYkNudDsKCiAgLyogY2FsYyBtaW4gYW5kIG1heCBzY2FsZmFjdG9ycyAqLwogIHNjZk1pbiA9IEZES19JTlRfTUFYOwogIHNjZk1heCA9IEZES19JTlRfTUlOOwogIGZvciAoc2ZiPTA7IHNmYjxzZmJDbnQ7IHNmYisrKSB7CiAgICBpZiAoc2NmW3NmYl0hPUZES19JTlRfTUlOKSB7CiAgICAgIHNjZk1pbiA9IGZpeE1pbihzY2ZNaW4sIHNjZltzZmJdKTsKICAgICAgc2NmTWF4ID0gZml4TWF4KHNjZk1heCwgc2NmW3NmYl0pOwogICAgfQogIH0KCiAgaWYgKHNjZk1heCAhPSBGREtfSU5UX01JTiAmJiBzY2ZNYXggPD0gc2NmTWluK01BWF9TQ0ZfREVMVEEpIHsKCiAgICBzY2ZBY3QgPSBzY2ZNYXg7CgogICAgZG8gewogICAgICAvKiB0cnkgc21hbGxlciBzY2YgKi8KICAgICAgc2NmQWN0LS07CiAgICAgIGZvciAoaT0wOyBpPE1BWF9HUk9VUEVEX1NGQjsgaSsrKQogICAgICAgIHNjZlRtcFtpXSA9IHNjZltpXTsKICAgICAgc3RvcFNmYiA9IDA7CiAgICAgIGRvIHsKICAgICAgICAvKiBzZWFyY2ggZm9yIHJlZ2lvbiB3aGVyZSBhbGwgc2NmcyBhcmUgYmlnZ2VyIHRoYW4gc2NmQWN0ICovCiAgICAgICAgc2ZiID0gc3RvcFNmYjsKICAgICAgICB3aGlsZSAoc2ZiPHNmYkNudCAmJiAoc2NmW3NmYl09PUZES19JTlRfTUlOIHx8IHNjZltzZmJdIDw9IHNjZkFjdCkpCiAgICAgICAgICBzZmIrKzsKICAgICAgICBzdGFydFNmYiA9IHNmYjsKICAgICAgICBzZmIrKzsKICAgICAgICB3aGlsZSAoc2ZiPHNmYkNudCAmJiAoc2NmW3NmYl09PUZES19JTlRfTUlOIHx8IHNjZltzZmJdID4gc2NmQWN0KSkKICAgICAgICAgIHNmYisrOwogICAgICAgIHN0b3BTZmIgPSBzZmI7CgogICAgICAgIC8qIGNoZWNrIGlmIGluIGFsbCBzZmIgb2YgYSB2YWxpZCByZWdpb24gc2NmQWN0ID49IG1pblNjZltzZmJdICovCiAgICAgICAgcG9zc2libGVSZWdpb25Gb3VuZCA9IDA7CiAgICAgICAgaWYgKHN0YXJ0U2ZiIDwgc2ZiQ250KSB7CiAgICAgICAgICBwb3NzaWJsZVJlZ2lvbkZvdW5kID0gMTsKICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKQogICAgICAgICAgICAgIGlmIChzY2ZBY3QgPCBtaW5TY2Zbc2ZiXSkgewogICAgICAgICAgICAgICAgcG9zc2libGVSZWdpb25Gb3VuZCA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocG9zc2libGVSZWdpb25Gb3VuZCkgeyAvKiByZWdpb24gZm91bmQgKi8KCiAgICAgICAgICAvKiByZXBsYWNlIHNjZnMgaW4gcmVnaW9uIGJ5IHNjZkFjdCAqLwogICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICBpZiAoc2NmVG1wW3NmYl0gIT0gRkRLX0lOVF9NSU4pCiAgICAgICAgICAgICAgc2NmVG1wW3NmYl0gPSBzY2ZBY3Q7CiAgICAgICAgICB9CgogICAgICAgICAgLyogZXN0aW1hdGUgY2hhbmdlIGluIGJpdCBkZW1hbmQgZm9yIG5ldyBzY2ZzICovCiAgICAgICAgICBkZWx0YVNjZkJpdHMgPSBGREthYWNFbmNfY291bnRTY2ZCaXRzRGlmZihzY2Ysc2NmVG1wLHNmYkNudCxzdGFydFNmYixzdG9wU2ZiKTsKCiAgICAgICAgICBkZWx0YVNwZWNQZSA9IEZES2FhY0VuY19jYWxjU3BlY1BlRGlmZihwc3lPdXRDaGFuLCBxY091dENoYW5uZWwsIHNjZiwgc2NmVG1wLCBzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRm9ybUZhY3RvckxkRGF0YSwgc2ZiTlJlbGV2YW50TGluZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0U2ZiLCBzdG9wU2ZiKTsKCiAgICAgICAgICBkZWx0YVBlTmV3ID0gZGVsdGFQZSArIChGSVhQX0RCTClkZWx0YVNjZkJpdHMgKyBkZWx0YVNwZWNQZTsKCiAgICAgICAgICAvKiBuZXcgYml0IGRlbWFuZCBzbWFsbCBlbm91Z2ggPyAqLwogICAgICAgICAgLyogMC4wMDA2MTAzNTE1NjI1ZiA9IDEwLjBmLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpICovCiAgICAgICAgICBpZiAoZGVsdGFQZU5ldyA8IEZMMkZYQ09OU1RfREJMKDAuMDAwNjEwMzUxNTYyNWYpKSB7CgogICAgICAgICAgICAvKiBxdWFudGl6ZSBhbmQgY2FsYyBzdW0gb2YgbmV3IGRpc3RvcnRpb24gKi8KICAgICAgICAgICAgZGlzdE9sZFN1bSA9IGRpc3ROZXdTdW0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgICAgZGlzdE9sZFN1bSArPSBDYWxjSW52TGREYXRhKHNmYkRpc3Rbc2ZiXSkgPj4gRElTVF9GQUNfU0hJRlQ7CgogICAgICAgICAgICAgICAgc2ZiV2lkdGggPSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYisxXSAtIHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiXTsKICAgICAgICAgICAgICAgIHNmYk9mZnMgPSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYl07CgogICAgICAgICAgICAgICAgc2ZiRGlzdE5ld1tzZmJdID0gRkRLYWFjRW5jX2NhbGNTZmJEaXN0KHFjT3V0Q2hhbm5lbC0+bWRjdFNwZWN0cnVtK3NmYk9mZnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXArc2ZiT2ZmcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NmQWN0KTsKCiAgICAgICAgICAgICAgICBpZiAoc2ZiRGlzdE5ld1tzZmJdID5xY091dENoYW5uZWwtPnNmYlRocmVzaG9sZExkRGF0YVtzZmJdKSB7CiAgICAgICAgICAgICAgICAgIC8qIG5vIGltcHJvdmVtZW50LCBza2lwIGZ1cnRoZXIgZGlzdC4gY2FsY3VsYXRpb25zICovCiAgICAgICAgICAgICAgICAgIGRpc3ROZXdTdW0gPSBkaXN0T2xkU3VtIDw8IDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlzdE5ld1N1bSArPSBDYWxjSW52TGREYXRhKHNmYkRpc3ROZXdbc2ZiXSkgPj4gRElTVF9GQUNfU0hJRlQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGRpc3RvcnRpb24gc21hbGxlciA/IC0+IHVzZSBuZXcgc2NhbGVmYWN0b3JzICovCiAgICAgICAgICAgIGlmIChkaXN0TmV3U3VtIDwgZGlzdE9sZFN1bSkgewogICAgICAgICAgICAgIGRlbHRhUGUgPSBkZWx0YVBlTmV3OwogICAgICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgICAgIGlmIChzY2Zbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgICAgICBzZmJXaWR0aCA9IHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiKzFdIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYl07CiAgICAgICAgICAgICAgICAgIHNmYk9mZnMgPSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYl07CiAgICAgICAgICAgICAgICAgIHNjZltzZmJdID0gc2NmQWN0OwogICAgICAgICAgICAgICAgICBzZmJEaXN0W3NmYl0gPSBzZmJEaXN0TmV3W3NmYl07CgogICAgICAgICAgICAgICAgICBmb3IgKGs9MDsgazxzZmJXaWR0aDsgaysrKQogICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1tzZmJPZmZzK2tdID0gcXVhbnRTcGVjVG1wW3NmYk9mZnMra107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgIH0gd2hpbGUgKHN0b3BTZmIgPD0gc2ZiQ250KTsKCiAgICB9IHdoaWxlIChzY2ZBY3QgPiBzY2ZNaW4pOwogIH0KfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX0ZES2FhY0VuY19hc3NpbWlsYXRlTXVsdGlwbGVTY2YyCgoqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfRkRLYWFjRW5jX2Fzc2ltaWxhdGVNdWx0aXBsZVNjZjIoUFNZX09VVF9DSEFOTkVMICpwc3lPdXRDaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkZvcm1GYWN0b3JMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYk5SZWxldmFudExpbmVzKQp7CiAgSU5UIHNmYiwgc3RhcnRTZmIsIHN0b3BTZmI7CiAgSU5UIHNjZlRtcFtNQVhfR1JPVVBFRF9TRkJdLCBzY2ZBY3QsIHNjZk5ldzsKICBJTlQgc2NmUHJldiwgc2NmTmV4dCwgc2NmUHJldk5leHRNaW4sIHNjZlByZXZOZXh0TWF4LCBzY2ZMbywgc2NmSGk7CiAgSU5UIHNjZk1pbiwgc2NmTWF4OwogIElOVCAqc2ZiT2ZmcyA9IHBzeU91dENoYW4tPnNmYk9mZnNldHM7CiAgRklYUF9EQkwgc2ZiRGlzdE5ld1tNQVhfR1JPVVBFRF9TRkJdLCBzZmJEaXN0TWF4W01BWF9HUk9VUEVEX1NGQl07CiAgRklYUF9EQkwgZGlzdE9sZFN1bSwgZGlzdE5ld1N1bTsKICBJTlQgZGVsdGFTY2ZCaXRzOwogIEZJWFBfREJMIGRlbHRhU3BlY1BlOwogIEZJWFBfREJMIGRlbHRhUGUgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBGSVhQX0RCTCBkZWx0YVBlTmV3ID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgSU5UIHNmYkNudCA9IHBzeU91dENoYW4tPnNmYkNudDsKICBJTlQgYlN1Y2Nlc3MsIGJDaGVja1NjZjsKICBJTlQgaSxrOwoKICAvKiBjYWxjIG1pbiBhbmQgbWF4IHNjYWxmYWN0b3JzICovCiAgc2NmTWluID0gRkRLX0lOVF9NQVg7CiAgc2NmTWF4ID0gRkRLX0lOVF9NSU47CiAgZm9yIChzZmI9MDsgc2ZiPHNmYkNudDsgc2ZiKyspIHsKICAgIGlmIChzY2Zbc2ZiXSE9RkRLX0lOVF9NSU4pIHsKICAgICAgc2NmTWluID0gZml4TWluKHNjZk1pbiwgc2NmW3NmYl0pOwogICAgICBzY2ZNYXggPSBmaXhNYXgoc2NmTWF4LCBzY2Zbc2ZiXSk7CiAgICB9CiAgfQoKICBzdG9wU2ZiID0gMDsKICBzY2ZBY3QgPSBGREtfSU5UX01JTjsKICBkbyB7CiAgICAvKiBzZWFyY2ggZm9yIHJlZ2lvbiB3aXRoIHNhbWUgc2NmIHZhbHVlcyBzY2ZBY3QgKi8KICAgIHNjZlByZXYgPSBzY2ZBY3Q7CgogICAgc2ZiID0gc3RvcFNmYjsKICAgIHdoaWxlIChzZmI8c2ZiQ250ICYmIChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4pKQogICAgICBzZmIrKzsKICAgIHN0YXJ0U2ZiID0gc2ZiOwogICAgc2NmQWN0ID0gc2NmW3N0YXJ0U2ZiXTsKICAgIHNmYisrOwogICAgd2hpbGUgKHNmYjxzZmJDbnQgJiYgKChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4pIHx8IChzY2Zbc2ZiXT09c2NmW3N0YXJ0U2ZiXSkpKQogICAgICBzZmIrKzsKICAgIHN0b3BTZmIgPSBzZmI7CgogICAgaWYgKHN0b3BTZmIgPCBzZmJDbnQpCiAgICAgIHNjZk5leHQgPSBzY2Zbc3RvcFNmYl07CiAgICBlbHNlCiAgICAgIHNjZk5leHQgPSBzY2ZBY3Q7CgogICAgaWYgKHNjZlByZXYgPT0gRkRLX0lOVF9NSU4pCiAgICAgIHNjZlByZXYgPSBzY2ZBY3Q7CgogICAgc2NmUHJldk5leHRNYXggPSBmaXhNYXgoc2NmUHJldiwgc2NmTmV4dCk7CiAgICBzY2ZQcmV2TmV4dE1pbiA9IGZpeE1pbihzY2ZQcmV2LCBzY2ZOZXh0KTsKCiAgICAvKiB0cnkgdG8gcmVkdWNlIGJpdHMgYnkgY2hlY2tpbmcgc2NmIHZhbHVlcyBpbiB0aGUgcmFuZ2UKICAgICAgIHNjZltzdGFydFNmYl0uLi5zY2ZIaSAqLwogICAgc2NmSGkgPSBmaXhNYXgoc2NmUHJldk5leHRNYXgsIHNjZkFjdCk7CiAgICAvKiB0cnkgdG8gZmluZCBhIGJldHRlciBzb2x1dGlvbiBieSByZWR1Y2luZyB0aGUgc2NmIGRpZmZlcmVuY2UgdG8KICAgICAgIHRoZSBuZWFyZXN0IHBvc3NpYmxlIGxvd2VyIHNjZiAqLwogICAgaWYgKHNjZlByZXZOZXh0TWF4ID49IHNjZkFjdCkKICAgICAgc2NmTG8gPSBmaXhNaW4oc2NmQWN0LCBzY2ZQcmV2TmV4dE1pbik7CiAgICBlbHNlCiAgICAgIHNjZkxvID0gc2NmUHJldk5leHRNYXg7CgogICAgaWYgKHN0YXJ0U2ZiIDwgc2ZiQ250ICYmIHNjZkhpLXNjZkxvIDw9IE1BWF9TQ0ZfREVMVEEpIHsgLyogcmVnaW9uIGZvdW5kICovCiAgICAgIC8qIDEuIHRyeSB0byBzYXZlIGJpdHMgYnkgY29hcnNlciBxdWFudGl6YXRpb24gKi8KICAgICAgaWYgKHNjZkhpID4gc2NmW3N0YXJ0U2ZiXSkgewogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgYWxsb3dlZCBkaXN0b3J0aW9uICovCiAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgIC8qIHNmYkRpc3RNYXhbc2ZiXSA9IChmbG9hdClwb3cocWNPdXRDaGFubmVsLT5zZmJUaHJlc2hvbGRbc2ZiXSpzZmJEaXN0W3NmYl0qc2ZiRGlzdFtzZmJdLDEuMGYvMy4wZik7ICovCiAgICAgICAgICAgIC8qIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1heChzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lbc2ZiXSpGTDJGWENPTlNUX0RCTCgxLmUtM2YpKTsgKi8KICAgICAgICAgICAgLyogLTAuMTU1NzE1Mzc5NDQgPSBsZDY0KDEuZS0zZikqLwogICAgICAgICAgICBzZmJEaXN0TWF4W3NmYl0gPSBmTXVsdChGTDJGWENPTlNUX0RCTCgxLjBmLzMuMGYpLHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhW3NmYl0pK2ZNdWx0KEZMMkZYQ09OU1RfREJMKDEuMGYvMy4wZiksc2ZiRGlzdFtzZmJdKStmTXVsdChGTDJGWENPTlNUX0RCTCgxLjBmLzMuMGYpLHNmYkRpc3Rbc2ZiXSk7CiAgICAgICAgICAgIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1heChzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiXS1GTDJGWENPTlNUX0RCTCgwLjE1NTcxNTM3OTQ0KSk7CiAgICAgICAgICAgIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1pbihzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJUaHJlc2hvbGRMZERhdGFbc2ZiXSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIG92ZXIgYWxsIHBvc3NpYmxlIHNjZiB2YWx1ZXMgZm9yIHRoaXMgcmVnaW9uICovCiAgICAgICAgYkNoZWNrU2NmID0gMTsKICAgICAgICBmb3IgKHNjZk5ldz1zY2Zbc3RhcnRTZmJdKzE7IHNjZk5ldzw9c2NmSGk7IHNjZk5ldysrKSB7CgkgICAgICAgICBmb3IgKGs9MDsgazxNQVhfR1JPVVBFRF9TRkI7IGsrKykKICAgICAgICAgICAgc2NmVG1wW2tdID0gc2NmW2tdOwoKICAgICAgICAgIC8qIHJlcGxhY2Ugc2NmcyBpbiByZWdpb24gYnkgc2NmTmV3ICovCiAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikKICAgICAgICAgICAgICBzY2ZUbXBbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBlc3RpbWF0ZSBjaGFuZ2UgaW4gYml0IGRlbWFuZCBmb3IgbmV3IHNjZnMgKi8KICAgICAgICAgIGRlbHRhU2NmQml0cyA9IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmKHNjZixzY2ZUbXAsc2ZiQ250LHN0YXJ0U2ZiLHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhU3BlY1BlID0gRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmKHBzeU91dENoYW4sIHFjT3V0Q2hhbm5lbCwgc2NmLCBzY2ZUbXAsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTZmIsIHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhUGVOZXcgPSBkZWx0YVBlICsgKEZJWFBfREJMKWRlbHRhU2NmQml0cyArIGRlbHRhU3BlY1BlOwoKICAgICAgICAgIC8qIG5ldyBiaXQgZGVtYW5kIHNtYWxsIGVub3VnaCA/ICovCiAgICAgICAgICBpZiAoZGVsdGFQZU5ldyA8IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CiAgICAgICAgICAgIGJTdWNjZXNzID0gMTsKCiAgICAgICAgICAgIC8qIHF1YW50aXplIGFuZCBjYWxjIHN1bSBvZiBuZXcgZGlzdG9ydGlvbiAqLwogICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICBzZmJEaXN0TmV3W3NmYl0gPSBGREthYWNFbmNfY2FsY1NmYkRpc3QocWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW0rc2ZiT2Zmc1tzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjVG1wK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYk9mZnNbc2ZiKzFdLXNmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZk5ldyk7CgogICAgICAgICAgICAgICAgaWYgKHNmYkRpc3ROZXdbc2ZiXSA+IHNmYkRpc3RNYXhbc2ZiXSkgewogICAgICAgICAgICAgICAgICAvKiBubyBpbXByb3ZlbWVudCwgc2tpcCBmdXJ0aGVyIGRpc3QuIGNhbGN1bGF0aW9ucyAqLwogICAgICAgICAgICAgICAgICBiU3VjY2VzcyA9IDA7CiAgICAgICAgICAgICAgICAgIGlmIChzZmJEaXN0TmV3W3NmYl0gPT0gcWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiXSkgewogICAgICAgICAgICAgICAgICAgIC8qIGlmIHdob2xlIHNmYiBpcyBhbHJlYWR5IHF1YW50aXplZCB0byAwLCBmdXJ0aGVyCiAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tzIHdpdGggZXZlbiBjb2Fyc2VyIHF1YW50LiBhcmUgdXNlbGVzcyovCiAgICAgICAgICAgICAgICAgICAgYkNoZWNrU2NmID0gMDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGJDaGVja1NjZj09MCkgLyogZnVydGhlciBjYWxjdWxhdGlvbnMgdXNlbGVzcyA/ICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgLyogZGlzdG9ydGlvbiBzbWFsbCBlbm91Z2ggPyAtPiB1c2UgbmV3IHNjYWxlZmFjdG9ycyAqLwogICAgICAgICAgICBpZiAoYlN1Y2Nlc3MpIHsKICAgICAgICAgICAgICBkZWx0YVBlID0gZGVsdGFQZU5ldzsKICAgICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgICBpZiAoc2NmW3NmYl0gIT0gRkRLX0lOVF9NSU4pIHsKICAgICAgICAgICAgICAgICAgc2NmW3NmYl0gPSBzY2ZOZXc7CiAgICAgICAgICAgICAgICAgIHNmYkRpc3Rbc2ZiXSA9IHNmYkRpc3ROZXdbc2ZiXTsKCiAgICAgICAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYk9mZnNbc2ZiKzFdLXNmYk9mZnNbc2ZiXTsgaysrKQogICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1tzZmJPZmZzW3NmYl0ra10gPSBxdWFudFNwZWNUbXBbc2ZiT2Zmc1tzZmJdK2tdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogMi4gb25seSBpZiBjb2Fyc2VyIHF1YW50aXphdGlvbiB3YXMgbm90IHN1Y2Nlc3NmdWwsIHRyeSB0byBmaW5kCiAgICAgICAgIGEgYmV0dGVyIHNvbHV0aW9uIGJ5IGZpbmVyIHF1YW50aXphdGlvbiBhbmQgcmVkdWNpbmcgYml0cyBmb3IKICAgICAgICAgc2NhbGVmYWN0b3IgY29kaW5nICovCiAgICAgIGlmIChzY2ZBY3Q9PXNjZltzdGFydFNmYl0gJiYKICAgICAgICAgIHNjZkxvIDwgc2NmQWN0ICYmCiAgICAgICAgICBzY2ZNYXgtc2NmTWluIDw9IE1BWF9TQ0ZfREVMVEEpIHsKCiAgICAgICAgaW50IGJtaW5TY2ZWaW9sYXRpb24gPSAwOwoKICAgICAgICBmb3IgKGs9MDsgazxNQVhfR1JPVVBFRF9TRkI7IGsrKykKICAgICAgICAgIHNjZlRtcFtrXSA9IHNjZltrXTsKCiAgICAgICAgc2NmTmV3ID0gc2NmTG87CgogICAgICAgIC8qIHJlcGxhY2Ugc2NmcyBpbiByZWdpb24gYnkgc2NmTmV3IGFuZAogICAgICAgICAgIGNoZWNrIGlmIGluIGFsbCBzZmIgc2NmTmV3ID49IG1pblNjZltzZmJdICovCiAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgIHNjZlRtcFtzZmJdID0gc2NmTmV3OwogICAgICAgICAgICBpZiAoc2NmTmV3IDwgbWluU2NmW3NmYl0pCiAgICAgICAgICAgICAgYm1pblNjZlZpb2xhdGlvbiA9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJtaW5TY2ZWaW9sYXRpb24pIHsKICAgICAgICAgIC8qIGVzdGltYXRlIGNoYW5nZSBpbiBiaXQgZGVtYW5kIGZvciBuZXcgc2NmcyAqLwogICAgICAgICAgZGVsdGFTY2ZCaXRzID0gRkRLYWFjRW5jX2NvdW50U2NmQml0c0RpZmYoc2NmLHNjZlRtcCxzZmJDbnQsc3RhcnRTZmIsc3RvcFNmYik7CgogICAgICAgICAgZGVsdGFTcGVjUGUgPSBGREthYWNFbmNfY2FsY1NwZWNQZURpZmYocHN5T3V0Q2hhbiwgcWNPdXRDaGFubmVsLCBzY2YsIHNjZlRtcCwgc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYkZvcm1GYWN0b3JMZERhdGEsIHNmYk5SZWxldmFudExpbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFNmYiwgc3RvcFNmYik7CgogICAgICAgICAgZGVsdGFQZU5ldyA9IGRlbHRhUGUgKyAoRklYUF9EQkwpZGVsdGFTY2ZCaXRzICsgZGVsdGFTcGVjUGU7CiAgICAgICAgfQoKICAgICAgICAvKiBuZXcgYml0IGRlbWFuZCBzbWFsbCBlbm91Z2ggPyAqLwogICAgICAgIGlmICghYm1pblNjZlZpb2xhdGlvbiAmJiBkZWx0YVBlTmV3IDwgRkwyRlhDT05TVF9EQkwoMC4wZikpIHsKCiAgICAgICAgICAvKiBxdWFudGl6ZSBhbmQgY2FsYyBzdW0gb2YgbmV3IGRpc3RvcnRpb24gKi8KICAgICAgICAgIGRpc3RPbGRTdW0gPSBkaXN0TmV3U3VtID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgIGRpc3RPbGRTdW0gKz0gQ2FsY0ludkxkRGF0YShzZmJEaXN0W3NmYl0pID4+IERJU1RfRkFDX1NISUZUOwoKICAgICAgICAgICAgICBzZmJEaXN0TmV3W3NmYl0gPSBGREthYWNFbmNfY2FsY1NmYkRpc3QocWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW0rc2ZiT2Zmc1tzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXArc2ZiT2Zmc1tzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJPZmZzW3NmYisxXS1zZmJPZmZzW3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZk5ldyk7CgogICAgICAgICAgICAgIGlmIChzZmJEaXN0TmV3W3NmYl0gPiBxY091dENoYW5uZWwtPnNmYlRocmVzaG9sZExkRGF0YVtzZmJdKSB7CiAgICAgICAgICAgICAgICAvKiBubyBpbXByb3ZlbWVudCwgc2tpcCBmdXJ0aGVyIGRpc3QuIGNhbGN1bGF0aW9ucyAqLwogICAgICAgICAgICAgICAgZGlzdE5ld1N1bSA9IGRpc3RPbGRTdW0gPDwgMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkaXN0TmV3U3VtICs9IENhbGNJbnZMZERhdGEoc2ZiRGlzdE5ld1tzZmJdKSA+PiBESVNUX0ZBQ19TSElGVDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLyogZGlzdG9ydGlvbiBzbWFsbGVyID8gLT4gdXNlIG5ldyBzY2FsZWZhY3RvcnMgKi8KICAgICAgICAgIGlmIChkaXN0TmV3U3VtIDwgZk11bHQoRkwyRlhDT05TVF9EQkwoMC44ZiksZGlzdE9sZFN1bSkpIHsKICAgICAgICAgICAgZGVsdGFQZSA9IGRlbHRhUGVOZXc7CiAgICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgICBpZiAoc2NmW3NmYl0gIT0gRkRLX0lOVF9NSU4pIHsKICAgICAgICAgICAgICAgIHNjZltzZmJdID0gc2NmTmV3OwogICAgICAgICAgICAgICAgc2ZiRGlzdFtzZmJdID0gc2ZiRGlzdE5ld1tzZmJdOwoKICAgICAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYk9mZnNbc2ZiKzFdLXNmYk9mZnNbc2ZiXTsgaysrKQogICAgICAgICAgICAgICAgICBxdWFudFNwZWNbc2ZiT2Zmc1tzZmJdK2tdID0gcXVhbnRTcGVjVG1wW3NmYk9mZnNbc2ZiXStrXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIDMuIHRyeSB0byBmaW5kIGEgYmV0dGVyIHNvbHV0aW9uIChzYXZlIGJpdHMpIGJ5IG9ubHkgcmVkdWNpbmcgdGhlCiAgICAgICAgIHNjYWxlZmFjdG9yIHdpdGhvdXQgbmV3IHF1YW50aXphdGlvbiAqLwogICAgICBpZiAoc2NmTWF4LXNjZk1pbiA8PSBNQVhfU0NGX0RFTFRBLTMpIHsgLyogMyBiZWMuIHNjZiBpcyByZWR1Y2VkIDMgdGltZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWUgZm9yIGxvb3AgYmVsb3cgKi8KCiAgICAgICAgZm9yIChrPTA7IGs8c2ZiQ250OyBrKyspCiAgICAgICAgICBzY2ZUbXBba10gPSBzY2Zba107CgogICAgICAgIGZvciAoaT0wOyBpPDM7IGkrKykgewogICAgICAgICAgc2NmTmV3ID0gc2NmVG1wW3N0YXJ0U2ZiXS0xOwogICAgICAgICAgLyogcmVwbGFjZSBzY2ZzIGluIHJlZ2lvbiBieSBzY2ZOZXcgKi8KICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKQogICAgICAgICAgICAgIHNjZlRtcFtzZmJdID0gc2NmTmV3OwogICAgICAgICAgfQogICAgICAgICAgLyogZXN0aW1hdGUgY2hhbmdlIGluIGJpdCBkZW1hbmQgZm9yIG5ldyBzY2ZzICovCiAgICAgICAgICBkZWx0YVNjZkJpdHMgPSBGREthYWNFbmNfY291bnRTY2ZCaXRzRGlmZihzY2Ysc2NmVG1wLHNmYkNudCxzdGFydFNmYixzdG9wU2ZiKTsKICAgICAgICAgIGRlbHRhUGVOZXcgPSBkZWx0YVBlICsgKEZJWFBfREJMKWRlbHRhU2NmQml0czsKICAgICAgICAgIC8qIG5ldyBiaXQgZGVtYW5kIHNtYWxsIGVub3VnaCA/ICovCiAgICAgICAgICBpZiAoZGVsdGFQZU5ldyA8PSBGTDJGWENPTlNUX0RCTCgwLjBmKSkgewoKICAgICAgICAgICAgYlN1Y2Nlc3MgPSAxOwogICAgICAgICAgICBkaXN0T2xkU3VtID0gZGlzdE5ld1N1bSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICBGSVhQX0RCTCBzZmJFblE7CiAgICAgICAgICAgICAgICAvKiBjYWxjIHRoZSBlbmVyZ3kgYW5kIGRpc3RvcnRpb24gb2YgdGhlIHF1YW50aXplZCBzcGVjdHJ1bSBmb3IKICAgICAgICAgICAgICAgICAgIGEgc21hbGxlciBzY2YgKi8KICAgICAgICAgICAgICAgIEZES2FhY0VuY19jYWxjU2ZiUXVhbnRFbmVyZ3lBbmREaXN0KHFjT3V0Q2hhbm5lbC0+bWRjdFNwZWN0cnVtK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiT2Zmc1tzZmIrMV0tc2ZiT2Zmc1tzZmJdLCBzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZmJFblEsICZzZmJEaXN0TmV3W3NmYl0pOwoKICAgICAgICAgICAgICAgIGRpc3RPbGRTdW0gKz0gQ2FsY0ludkxkRGF0YShzZmJEaXN0W3NmYl0pID4+IERJU1RfRkFDX1NISUZUOwogICAgICAgICAgICAgICAgZGlzdE5ld1N1bSArPSBDYWxjSW52TGREYXRhKHNmYkRpc3ROZXdbc2ZiXSkgPj4gRElTVF9GQUNfU0hJRlQ7CgogICAgICAgICAgICAgICAgLyogIDAuMDAyNTk0ODg1NTYxNjcgPSBsZDY0KDEuMTIyZikgKi8KICAgICAgICAgICAgICAgIC8qIC0wLjAwNzc4NzIyNjg2NjUyID0gbGQ2NCgwLjcwNzlmKSAqLwogICAgICAgICAgICAgICAgaWYgKChzZmJEaXN0TmV3W3NmYl0gPiAoc2ZiRGlzdFtzZmJdK0ZMMkZYQ09OU1RfREJMKDAuMDAyNTk0ODg1NTYxNjdmKSkpIHx8IChzZmJFblEgPCAocWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiXSAtIEZMMkZYQ09OU1RfREJMKDAuMDA3Nzg3MjI2ODY2NTJmKSkpKXsKICAgICAgICAgICAgICAgICAgYlN1Y2Nlc3MgPSAwOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogZGlzdG9ydGlvbiBzbWFsbGVyID8gLT4gdXNlIG5ldyBzY2FsZWZhY3RvcnMgKi8KICAgICAgICAgICAgaWYgKGRpc3ROZXdTdW0gPCBkaXN0T2xkU3VtICYmIGJTdWNjZXNzKSB7CiAgICAgICAgICAgICAgZGVsdGFQZSA9IGRlbHRhUGVOZXc7CiAgICAgICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICAgIHNjZltzZmJdID0gc2NmTmV3OwogICAgICAgICAgICAgICAgICBzZmJEaXN0W3NmYl0gPSBzZmJEaXN0TmV3W3NmYl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSB3aGlsZSAoc3RvcFNmYiA8PSBzZmJDbnQpOwoKfQoKc3RhdGljIHZvaWQKRkRLYWFjRW5jX0ZES2FhY0VuY19Fc3RpbWF0ZVNjYWxlRmFjdG9yc0NoYW5uZWwoUUNfT1VUX0NIQU5ORUwgICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZX09VVF9DSEFOTkVMICAqcHN5T3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqUkVTVFJJQ1Qgc2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpSRVNUUklDVCBnbG9iYWxHYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHNmYkZvcm1GYWN0b3JMZERhdGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICxjb25zdCBJTlQgaW52UXVhbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSE9SVCAqUkVTVFJJQ1QgcXVhbnRTcGVjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBJTlQgaSwgaiwgc2ZiLCBzZmJPZmZzOwogIElOVCBzY2ZJbnQ7CiAgSU5UIG1heFNmOwogIElOVCBtaW5TZjsKICBGSVhQX0RCTCB0aHJlc2hMZERhdGE7CiAgRklYUF9EQkwgZW5lcmd5TGREYXRhOwogIEZJWFBfREJMIGVuZXJneVBhcnRMZERhdGE7CiAgRklYUF9EQkwgdGhyZXNob2xkUGFydExkRGF0YTsKICBGSVhQX0RCTCBzY2ZGcmFjdDsKICBGSVhQX0RCTCBtYXhTcGVjOwogIEZJWFBfREJMIGFic1NwZWM7CiAgSU5UIG1pblNjZkNhbGN1bGF0ZWRbTUFYX0dST1VQRURfU0ZCXTsKICBGSVhQX0RCTCBzZmJEaXN0TGREYXRhW01BWF9HUk9VUEVEX1NGQl07CiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHF1YW50U3BlY1RtcCwgU0hPUlQsICgxMDI0KSk7CiAgSU5UIG1pblNmTWF4UXVhbnRbTUFYX0dST1VQRURfU0ZCXTsKCiAgRklYUF9EQkwgdGhyZXNoQ29uc3RMZERhdGE9RkwyRlhDT05TVF9EQkwoMC4wNDMwNDUxMTcyMmYpOyAvKiBsb2cxMCg2Ljc1KS9sb2cxMCgyLjApLzY0LjAgKi8KICBGSVhQX0RCTCBjb252Q29uc3Q9RkwyRlhDT05TVF9EQkwoMC4zMDEwMjk5OTU2NmYpOyAvKiBsb2cxMCgyLjApICovCiAgRklYUF9EQkwgYzFDb25zdD1GTDJGWENPTlNUX0RCTCgtMC4yNzA4MzE4MzU5NGYpOyAvKiBDMSA9IC02OS4zMzI5NSA9PiBDMS8yXjggKi8KCgoKICBpZiAoaW52UXVhbnQ+MCkgewogICAgRkRLbWVtY2xlYXIocXVhbnRTcGVjLCAoMTAyNCkqc2l6ZW9mKFNIT1JUKSk7CiAgfQoKICAvKiBzY2ZzIHdpdGhvdXQgZW5lcmd5IG9yIHdpdGggdGhyZXNoPmVuZXJneSBhcmUgbWFya2VkIHdpdGggRkRLX0lOVF9NSU4gKi8KICBmb3IoaT0wOyBpPHBzeU91dENoYW5uZWwtPnNmYkNudDsgaSsrKSB7CiAgICBzY2ZbaV0gPSBGREtfSU5UX01JTjsKICB9CgogIGZvciAoaT0wOyBpPE1BWF9HUk9VUEVEX1NGQjsgaSsrKSB7CiAgICBtaW5TZk1heFF1YW50W2ldID0gRkRLX0lOVF9NSU47CiAgfQoKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICBmb3Ioc2ZiPTA7IHNmYjxwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKCiAgICAgIHRocmVzaExkRGF0YSA9IHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhW3NmYk9mZnMrc2ZiXTsKICAgICAgZW5lcmd5TGREYXRhID0gcWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiT2ZmcytzZmJdOwoKICAgICAgc2ZiRGlzdExkRGF0YVtzZmJPZmZzK3NmYl0gPSBlbmVyZ3lMZERhdGE7CgoKICAgICAgaWYgKGVuZXJneUxkRGF0YSA+IHRocmVzaExkRGF0YSkgewogICAgICAgIEZJWFBfREJMIHRtcDsKCiAgICAgICAgLyogZW5lcmd5UGFydCA9IChmbG9hdClsb2cxMChzZmJGb3JtRmFjdG9yW3NmYk9mZnMrc2ZiXSk7ICovCiAgICAgICAgLyogMC4wOTM3NWYgPSBsb2coNjQuMCkvbG9nKDIuMCkvNjQuMCA9IHNjYWxlIG9mIHNmYkZvcm1GYWN0b3JMZERhdGEgKi8KICAgICAgICBlbmVyZ3lQYXJ0TGREYXRhID0gc2ZiRm9ybUZhY3RvckxkRGF0YVtzZmJPZmZzK3NmYl0gKyBGTDJGWENPTlNUX0RCTCgwLjA5Mzc1Zik7CgogICAgICAgIC8qIGluZmx1ZW5jZSBvZiBhbGxvd2VkIGRpc3RvcnRpb24gKi8KICAgICAgICAvKiB0aHJlc2hvbGRQYXJ0ID0gKGZsb2F0KWxvZzEwKDYuNzUqdGhyZXNoK0ZMVF9NSU4pOyAqLwogICAgICAgIHRocmVzaG9sZFBhcnRMZERhdGEgPSB0aHJlc2hDb25zdExkRGF0YSArIHRocmVzaExkRGF0YTsKCiAgICAgICAgLyogc2NmIGNhbGMgKi8KICAgICAgICAvKiBzY2ZGbG9hdCA9IDguODU4NWYgKiAodGhyZXNob2xkUGFydCAtIGVuZXJneVBhcnQpOyAqLwogICAgICAgIHNjZkZyYWN0ID0gdGhyZXNob2xkUGFydExkRGF0YSAtIGVuZXJneVBhcnRMZERhdGE7CiAgICAgICAgLyogY29udmVyc2lvbiBmcm9tIGxvZzIgdG8gbG9nMTAgKi8KICAgICAgICBzY2ZGcmFjdCA9IGZNdWx0KGNvbnZDb25zdCxzY2ZGcmFjdCk7CiAgICAgICAgLyogKDguODU4NWYgKiBzY2ZGcmFjdCkvOCA9IDgvOCAqIHNjZkZyYWN0ICsgMC44NTg1ICogc2NmRnJhY3QvOCAqLwogICAgICAgIHNjZkZyYWN0ID0gc2NmRnJhY3QgKyBmTXVsdChGTDJGWENPTlNUX0RCTCgwLjg1ODVmKSxzY2ZGcmFjdCA+PiAzKTsKCiAgICAgICAgLyogaW50ZWdlciBzY2FsZWZhY3RvciAqLwogICAgICAgIC8qIHNjZkludCA9IChpbnQpZmxvb3Ioc2NmRmxvYXQpOyAqLwogICAgICAgIHNjZkludCA9IChJTlQpKHNjZkZyYWN0Pj4oKERGUkFDVF9CSVRTLTEpLTMtTERfREFUQV9TSElGVCkpOyAvKiAzIGJpdHMgPT4gc2NmRnJhY3QvOC4wOyA2IGJpdHMgPT4gbGQ2NCAqLwoKICAgICAgICAvKiBtYXhpbXVtIG9mIHNwZWN0cnVtICovCiAgICAgICAgbWF4U3BlYyA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwoKICAgICAgICBmb3Ioaj1wc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXTsgajxwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiKzFdOyBqKysgKXsKICAgICAgICAgIGFic1NwZWMgPSBmaXhwX2FicyhxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bVtqXSk7CiAgICAgICAgICBtYXhTcGVjID0gKGFic1NwZWMgPiBtYXhTcGVjKSA/IGFic1NwZWMgOiBtYXhTcGVjOwogICAgICAgIH0KCiAgICAgICAgLyogbG93ZXIgc2NmIGxpbWl0IHRvIGF2b2lkIHF1YW50aXplZCB2YWx1ZXMgYmlnZ2VyIHRoYW4gTUFYX1FVQU5UICovCiAgICAgICAgLyogQzEgPSAtNjkuMzMyOTVmLCBDMiA9IDUuNzcwNzhmID0gNC9sb2coMikgKi8KICAgICAgICAvKiBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9IChpbnQpY2VpbChDMSArIEMyKmxvZyhtYXhTcGVjKSk7ICovCiAgICAgICAgLyogQzEvMl44ICsgNC9sb2coMi4wKSpsb2cobWF4U3BlYykvMl44ICA9PiBDMS8yXjggKyBsb2cobWF4U3BlYykvbG9nKDIuMCkqNC8yXjggPT4gQzEvMl44ICsgbG9nKG1heFNwZWMpL2xvZygyLjApLzY0LjAgKi8KCiAgICAgICAgLy9taW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9ICgoSU5UKSAoKGMxQ29uc3QgKyBDYWxjTGREYXRhKG1heFNwZWMpKSA+PiAoKERGUkFDVF9CSVRTLTEpLTgpKSkgKyAxOwogICAgICAgIHRtcCA9IENhbGNMZERhdGEobWF4U3BlYyk7CiAgICAgICAgaWYgKGMxQ29uc3Q+RkwyRlhDT05TVF9EQkwoLTEuZiktdG1wKSB7CiAgICAgICAgICBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9ICgoSU5UKSAoKGMxQ29uc3QgKyB0bXApID4+ICgoREZSQUNUX0JJVFMtMSktOCkpKSArIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgbWluU2ZNYXhRdWFudFtzZmJPZmZzK3NmYl0gPSAoKElOVCkgKEZMMkZYQ09OU1RfREJMKC0xLmYpID4+ICgoREZSQUNUX0JJVFMtMSktOCkpKSArIDE7CiAgICAgICAgfQoKICAgICAgICBzY2ZJbnQgPSBmaXhNYXgoc2NmSW50LCBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSk7CgoKICAgICAgICAvKiBmaW5kIGJldHRlciBzY2FsZWZhY3RvciB3aXRoIGFuYWx5c2lzIGJ5IHN5bnRoZXNpcyAqLwogICAgICAgIGlmIChpbnZRdWFudD4wKSB7CiAgICAgICAgICBzY2ZJbnQgPSBGREthYWNFbmNfaW1wcm92ZVNjZihxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bStwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjK3BzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXArcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmIrMV0tcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVzaExkRGF0YSwgc2NmSW50LCBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNmYkRpc3RMZERhdGFbc2ZiT2ZmcytzZmJdLCAmbWluU2NmQ2FsY3VsYXRlZFtzZmJPZmZzK3NmYl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgc2NmW3NmYk9mZnMrc2ZiXSA9IHNjZkludDsKICAgICAgfQogICAgfQogIH0KCgogIGlmIChpbnZRdWFudD4xKSB7CiAgICAvKiB0cnkgdG8gZGVjcmVhc2Ugc2NmIGRpZmZlcmVuY2VzICovCiAgICBGSVhQX0RCTCBzZmJDb25zdFBlUGFydFtNQVhfR1JPVVBFRF9TRkJdOwogICAgRklYUF9EQkwgc2ZiTlJlbGV2YW50TGluZXNbTUFYX0dST1VQRURfU0ZCXTsKCiAgICBmb3IgKGk9MDsgaTxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IGkrKykKICAgICAgc2ZiQ29uc3RQZVBhcnRbaV0gPSAoRklYUF9EQkwpRkRLX0lOVF9NSU47CgogICAgRkRLYWFjRW5jX2NhbGNTZmJSZWxldmFudExpbmVzKCBzZmJGb3JtRmFjdG9yTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbC0+c2ZiRW5lcmd5TGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbC0+c2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPm1heFNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNmYk5SZWxldmFudExpbmVzKTsKCgogICAgRkRLYWFjRW5jX2Fzc2ltaWxhdGVTaW5nbGVTY2YocHN5T3V0Q2hhbm5lbCwgcWNPdXRDaGFubmVsLCBxdWFudFNwZWMsIHF1YW50U3BlY1RtcCwgc2NmLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5TZk1heFF1YW50LCBzZmJEaXN0TGREYXRhLCBzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRm9ybUZhY3RvckxkRGF0YSwgc2ZiTlJlbGV2YW50TGluZXMsIG1pblNjZkNhbGN1bGF0ZWQsIDEpOwoKCiAgICBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmKHBzeU91dENoYW5uZWwsIHFjT3V0Q2hhbm5lbCwgcXVhbnRTcGVjLCBxdWFudFNwZWNUbXAsIHNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5TZk1heFF1YW50LCBzZmJEaXN0TGREYXRhLCBzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcyk7CgoKICAgIEZES2FhY0VuY19GREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmMihwc3lPdXRDaGFubmVsLCBxY091dENoYW5uZWwsIHF1YW50U3BlYywgcXVhbnRTcGVjVG1wLCBzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pblNmTWF4UXVhbnQsIHNmYkRpc3RMZERhdGEsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcyk7CgogIH0KCgogIC8qIGdldCBtaW4gc2NhbGVmYWMgKi8KICBtaW5TZiA9IEZES19JTlRfTUFYOwogIGZvciAoc2ZiT2Zmcz0wOyBzZmJPZmZzPHBzeU91dENoYW5uZWwtPnNmYkNudDsgc2ZiT2Zmcys9cHN5T3V0Q2hhbm5lbC0+c2ZiUGVyR3JvdXApIHsKICAgIGZvciAoc2ZiID0gMDsgc2ZiIDwgcHN5T3V0Q2hhbm5lbC0+bWF4U2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgIGlmIChzY2Zbc2ZiT2ZmcytzZmJdIT1GREtfSU5UX01JTikKICAgICAgICBtaW5TZiA9IGZpeE1pbihtaW5TZixzY2Zbc2ZiT2ZmcytzZmJdKTsKICAgIH0KICB9CgogIC8qIGxpbWl0IHNjZiBkZWx0YSAqLwogIGZvciAoc2ZiT2Zmcz0wOyBzZmJPZmZzPHBzeU91dENoYW5uZWwtPnNmYkNudDsgc2ZiT2Zmcys9cHN5T3V0Q2hhbm5lbC0+c2ZiUGVyR3JvdXApIHsKICAgIGZvciAoc2ZiID0gMDsgc2ZiIDwgcHN5T3V0Q2hhbm5lbC0+bWF4U2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgIGlmICgoc2NmW3NmYk9mZnMrc2ZiXSAhPSBGREtfSU5UX01JTikgJiYgKG1pblNmK01BWF9TQ0ZfREVMVEEpIDwgc2NmW3NmYk9mZnMrc2ZiXSkgewogICAgICAgIHNjZltzZmJPZmZzK3NmYl0gPSBtaW5TZiArIE1BWF9TQ0ZfREVMVEE7CiAgICAgICAgaWYgKGludlF1YW50ID4gMCkgeyAvKiBjaGFuZ2VkIGJhbmRzIG5lZWQgdG8gYmUgcXVhbnRpemVkIGFnYWluICovCiAgICAgICAgICBzZmJEaXN0TGREYXRhW3NmYk9mZnMrc2ZiXSA9CiAgICAgICAgICAgICAgIEZES2FhY0VuY19jYWxjU2ZiRGlzdChxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bStwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlYytwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmIrMV0tcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCgogIC8qIGdldCBtYXggc2NhbGVmYWMgZm9yIGdsb2JhbCBnYWluICovCiAgbWF4U2YgPSBGREtfSU5UX01JTjsKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IHBzeU91dENoYW5uZWwtPm1heFNmYlBlckdyb3VwOyBzZmIrKykgewogICAgICBtYXhTZiA9IGZpeE1heChtYXhTZixzY2Zbc2ZiT2ZmcytzZmJdKTsKICAgIH0KICB9CgogIC8qIGNhbGMgbG9vcCBzY2FsZWZhY3RvcnMsIGlmIHNwZWMgaXMgbm90IGFsbCB6ZXJvIChpLmUuIG1heFNmID09IC05OSkgKi8KICBpZiggbWF4U2YgPiBGREtfSU5UX01JTiApIHsKICAgICpnbG9iYWxHYWluID0gbWF4U2Y7CiAgICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICAgIGZvciAoc2ZiID0gMDsgc2ZiIDwgcHN5T3V0Q2hhbm5lbC0+bWF4U2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgICAgaWYoIHNjZltzZmJPZmZzK3NmYl0gPT0gRkRLX0lOVF9NSU4gKSB7CiAgICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gMDsKICAgICAgICAgIC8qIHNldCBiYW5kIGV4cGxpY2l0ZWx5IHRvIHplcm8gKi8KICAgICAgICAgIGZvcihqPXBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdOyBqPHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmIrMV07IGorKyApIHsKICAgICAgICAgICAgcWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW1bal0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gbWF4U2YgLSBzY2Zbc2ZiT2ZmcytzZmJdOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICBlbHNlewogICAgKmdsb2JhbEdhaW4gPSAwOwogICAgLyogc2V0IHNwZWN0cnVtIGV4cGxpY2l0ZWx5IHRvIHplcm8gKi8KICAgIGZvciAoc2ZiT2Zmcz0wOyBzZmJPZmZzPHBzeU91dENoYW5uZWwtPnNmYkNudDsgc2ZiT2Zmcys9cHN5T3V0Q2hhbm5lbC0+c2ZiUGVyR3JvdXApIHsKICAgICAgZm9yIChzZmIgPSAwOyBzZmIgPCBwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gMDsKICAgICAgICAvKiBzZXQgYmFuZCBleHBsaWNpdGVseSB0byB6ZXJvICovCiAgICAgICAgZm9yKGo9cHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl07IGo8cHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYisxXTsgaisrICkgewogICAgICAgICAgcWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW1bal0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIGZyZWUgcXVhbnRTcGVjVG1wIGZyb20gc2NyYXRjaCAqLwogIENfQUxMT0NfU0NSQVRDSF9FTkQocXVhbnRTcGVjVG1wLCBTSE9SVCwgKDEwMjQpKTsKCgp9Cgp2b2lkCkZES2FhY0VuY19Fc3RpbWF0ZVNjYWxlRmFjdG9ycyhQU1lfT1VUX0NIQU5ORUwgKnBzeU91dENoYW5uZWxbXSwKICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0NIQU5ORUwqIHFjT3V0Q2hhbm5lbFtdLAogICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgaW52UXVhbnQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBuQ2hhbm5lbHMpCnsKICBpbnQgY2g7CgogIGZvciAoY2ggPSAwOyBjaCA8IG5DaGFubmVsczsgY2grKykKICB7CiAgICAgIEZES2FhY0VuY19GREthYWNFbmNfRXN0aW1hdGVTY2FsZUZhY3RvcnNDaGFubmVsKHFjT3V0Q2hhbm5lbFtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbFtjaF0tPnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZxY091dENoYW5uZWxbY2hdLT5nbG9iYWxHYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRDaGFubmVsW2NoXS0+c2ZiRm9ybUZhY3RvckxkRGF0YQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLGludlF1YW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcWNPdXRDaGFubmVsW2NoXS0+cXVhbnRTcGVjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogIH0KCn0KCg==