Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gV2VybmVyCiAgIGNvbnRlbnRzL2Rlc2NyaXB0aW9uOiBTY2FsZSBmYWN0b3IgZXN0aW1hdGlvbgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInNmX2VzdGltLmgiCiNpbmNsdWRlICJhYWNFbmNfcm9tLmgiCiNpbmNsdWRlICJxdWFudGl6ZS5oIgojaW5jbHVkZSAiYml0X2NudC5oIgoKCgoKI2RlZmluZSBBU19QRV9GQUNfU0hJRlQgNwojZGVmaW5lIERJU1RfRkFDX1NISUZUICAzCiNkZWZpbmUgQVNfUEVfRkFDX0ZMT0FUIChmbG9hdCkoMSA8PCBBU19QRV9GQUNfU0hJRlQpCnN0YXRpYyBjb25zdCBJTlQgTUFYX1NDRl9ERUxUQSA9IDYwOwoKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMSA9IEZMMkZYQ09OU1RfREJMKDMuMGYvQVNfUEVfRkFDX0ZMT0FUKTsgICAgICAgICAgLyogKGxvZyg4LjApL2xvZygyKSkgPj4gQVNfUEVfRkFDX1NISUZUICovCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMiA9IEZMMkZYQ09OU1RfREJMKDEuMzIxOTI4MWYvQVNfUEVfRkFDX0ZMT0FUKTsgICAgLyogKGxvZygyLjUpL2xvZygyKSkgPj4gQVNfUEVfRkFDX1NISUZUICovCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBQRV9DMyA9IEZMMkZYQ09OU1RfREJMKDAuNTU5MzU3M2YpOyAgICAgICAgICAgICAgICAgICAgLyogMS1DMi9DMSAqLwoKCi8qCiAgRnVuY3Rpb247IEZES2FhY0VuY19GREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3JDaGFubmVsCgogIERlc2NyaXB0aW9uOiBDYWxjdWxhdGVzIHRoZSBmb3JtZmFjdG9yCgogIHNmOiBzY2FsZSBmYWN0b3Igb2YgdGhlIG1kY3Qgc3BlY3RydW0KICBzZmJGb3JtRmFjdG9yTGREYXRhIGlzIHNjYWxlZCB3aXRoIHRoZSBmYWN0b3IgMS8oKCgyXnNmKV4wLjUpICogKDJeRk9STV9GQUNfU0hJRlQpKQoqLwpzdGF0aWMgdm9pZApGREthYWNFbmNfRkRLYWFjRW5jX0NhbGNGb3JtRmFjdG9yQ2hhbm5lbChGSVhQX0RCTCAqUkVTVFJJQ1Qgc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAqUkVTVFJJQ1QgcHN5T3V0Q2hhbikKewogIElOVCBqLCBzZmIsIHNmYkdycDsKICBGSVhQX0RCTCBmb3JtRmFjdG9yOwoKICBpbnQgdG1wMCA9IHBzeU91dENoYW4tPnNmYkNudDsKICBpbnQgdG1wMSA9IHBzeU91dENoYW4tPm1heFNmYlBlckdyb3VwOwogIGludCBzdGVwID0gcHN5T3V0Q2hhbi0+c2ZiUGVyR3JvdXA7CiAgZm9yKHNmYkdycCA9IDA7IHNmYkdycCA8IHRtcDA7IHNmYkdycCArPSBzdGVwKSB7CiAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IHRtcDE7IHNmYisrKSB7CiAgICAgIGZvcm1GYWN0b3IgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgLyogY2FsYyBzdW0gb2Ygc3FydChzcGVjKSAqLwogICAgICBmb3Ioaj1wc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYkdycCtzZmJdOyBqPHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiR3JwK3NmYisxXTsgaisrICkgewogICAgICAgICBmb3JtRmFjdG9yICs9IHNxcnRGaXhwKGZpeHBfYWJzKHBzeU91dENoYW4tPm1kY3RTcGVjdHJ1bVtqXSkpPj5GT1JNX0ZBQ19TSElGVDsKICAgICAgfQogICAgICBzZmJGb3JtRmFjdG9yTGREYXRhW3NmYkdycCtzZmJdID0gQ2FsY0xkRGF0YShmb3JtRmFjdG9yKTsKICAgIH0KICAgIC8qIHNldCBzZmJGb3JtRmFjdG9yIGZvciBzZmJzIHdpdGggemVybyBzcGVjIHRvIHplcm8uIEp1c3QgZm9yIGRlYnVnZ2luZy4gKi8KICAgIGZvciAoIDsgc2ZiIDwgcHN5T3V0Q2hhbi0+c2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgIHNmYkZvcm1GYWN0b3JMZERhdGFbc2ZiR3JwK3NmYl0gPSBGTDJGWENPTlNUX0RCTCgtMS4wZik7CiAgICB9CiAgfQp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3IKCiAgRGVzY3JpcHRpb246IENhbGxzIEZES2FhY0VuY19GREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3JDaGFubmVsKCkgZm9yIGVhY2ggY2hhbm5lbAoqLwoKdm9pZApGREthYWNFbmNfQ2FsY0Zvcm1GYWN0b3IoUUNfT1VUX0NIQU5ORUwgICAqcWNPdXRDaGFubmVsWygyKV0sCiAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAgKnBzeU91dENoYW5uZWxbKDIpXSwKICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICBuQ2hhbm5lbHMpCnsKICBJTlQgajsKICBmb3IgKGo9MDsgajxuQ2hhbm5lbHM7IGorKykgewogICAgRkRLYWFjRW5jX0ZES2FhY0VuY19DYWxjRm9ybUZhY3RvckNoYW5uZWwocWNPdXRDaGFubmVsW2pdLT5zZmJGb3JtRmFjdG9yTGREYXRhLCBwc3lPdXRDaGFubmVsW2pdKTsKICB9Cn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19jYWxjU2ZiUmVsZXZhbnRMaW5lcwoKICBEZXNjcmlwdGlvbjogQ2FsY3VsYXRlcyBzZmJOUmVsZXZhbnRMaW5lcwoKICBzZmJOUmVsZXZhbnRMaW5lcyBpcyBzY2FsZWQgd2l0aCB0aGUgZmFjdG9yIDEvKCgyXkZPUk1fRkFDX1NISUZUKSAqIDIuMCkKKi8Kc3RhdGljIHZvaWQKRkRLYWFjRW5jX2NhbGNTZmJSZWxldmFudExpbmVzKCBjb25zdCBGSVhQX0RCTCAqY29uc3Qgc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZJWFBfREJMICpjb25zdCBzZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGSVhQX0RCTCAqY29uc3Qgc2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICpjb25zdCBzZmJPZmZzZXRzLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UIHNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBzZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBtYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcykKewogIElOVCBzZmJPZmZzLCBzZmI7CiAgRklYUF9EQkwgc2ZiV2lkdGhMZERhdGE7CiAgRklYUF9EQkwgYXNQZUZhY0xkRGF0YSA9IEZMMkZYQ09OU1RfREJMKDAuMTA5Mzc1KTsgICAvKiBBU19QRV9GQUNfU0hJRlQqbGQ2NCgyKSAqLwogIEZJWFBfREJMIGFjY3U7CgogIC8qIHNmYk5SZWxldmFudExpbmVzW2ldID0gMl4oIChzZmJGb3JtRmFjdG9yTGREYXRhW2ldIC0gMC4yNSAqIChzZmJFbmVyZ3lMZERhdGFbaV0gLSBsZDY0KHNmYldpZHRoW2ldLygyXjcpKSAtIEFTX1BFX0ZBQ19TSElGVCpsZDY0KDIpKSAqIDY0KTsgKi8KCiAgRkRLbWVtY2xlYXIoc2ZiTlJlbGV2YW50TGluZXMsIHNmYkNudCAqIHNpemVvZihGSVhQX0RCTCkpOwoKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2ZmczxzZmJDbnQ7IHNmYk9mZnMrPXNmYlBlckdyb3VwKSB7CiAgICBmb3Ioc2ZiPTA7IHNmYjxtYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgLyogY2FsYyBzdW0gb2Ygc3FydChzcGVjKSAqLwogICAgICBpZigoRklYUF9EQkwpc2ZiRW5lcmd5TGREYXRhW3NmYk9mZnMrc2ZiXSA+IChGSVhQX0RCTClzZmJUaHJlc2hvbGRMZERhdGFbc2ZiT2ZmcytzZmJdKSB7CiAgICAgICAgSU5UIHNmYldpZHRoID0gc2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYisxXSAtIHNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdOwoKICAgICAgICAvKiBhdmdGb3JtRmFjdG9yTGREYXRhID0gc3FydEZpeHAoc3FydEZpeHAoc2ZiRW5lcmd5TGREYXRhW3NmYk9mZnMrc2ZiXS9zZmJXaWR0aCkpOyAqLwogICAgICAgIC8qIHNmYk5SZWxldmFudExpbmVzW3NmYk9mZnMrc2ZiXSA9IHNmYkZvcm1GYWN0b3Jbc2ZiT2ZmcytzZmJdIC8gYXZnRm9ybUZhY3RvckxkRGF0YTsgKi8KICAgICAgICBzZmJXaWR0aExkRGF0YSA9IChGSVhQX0RCTCkoc2ZiV2lkdGggPDwgKERGUkFDVF9CSVRTLTEtQVNfUEVfRkFDX1NISUZUKSk7CiAgICAgICAgc2ZiV2lkdGhMZERhdGEgPSBDYWxjTGREYXRhKHNmYldpZHRoTGREYXRhKTsKCiAgICAgICAgYWNjdSA9IHNmYkVuZXJneUxkRGF0YVtzZmJPZmZzK3NmYl0gLSBzZmJXaWR0aExkRGF0YSAtIGFzUGVGYWNMZERhdGE7CiAgICAgICAgYWNjdSA9IHNmYkZvcm1GYWN0b3JMZERhdGFbc2ZiT2ZmcytzZmJdIC0gKGFjY3UgPj4gMik7CgogICAgICAgIHNmYk5SZWxldmFudExpbmVzW3NmYk9mZnMrc2ZiXSA9IENhbGNJbnZMZERhdGEoYWNjdSkgPj4gMTsKICAgICAgfQogICAgfQogIH0KfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX2NvdW50U2luZ2xlU2NmQml0cwoKICBEZXNjcmlwdGlvbjoKCiAgc2NmQml0c0ZyYWN0IGlzIHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpCiovCnN0YXRpYyBGSVhQX0RCTCBGREthYWNFbmNfY291bnRTaW5nbGVTY2ZCaXRzKElOVCBzY2YsIElOVCBzY2ZMZWZ0LCBJTlQgc2NmUmlnaHQpCnsKICBGSVhQX0RCTCBzY2ZCaXRzRnJhY3Q7CgogIHNjZkJpdHNGcmFjdCA9IChGSVhQX0RCTCkgKCAgRkRLYWFjRW5jX2JpdENvdW50U2NhbGVmYWN0b3JEZWx0YShzY2ZMZWZ0LXNjZikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmLXNjZlJpZ2h0KSApOwoKICBzY2ZCaXRzRnJhY3QgPSBzY2ZCaXRzRnJhY3QgPDwgKERGUkFDVF9CSVRTLTEtKDIqQVNfUEVfRkFDX1NISUZUKSk7CgogIHJldHVybiBzY2ZCaXRzRnJhY3Q7IC8qIG91dHB1dCBzY2FsZWQgYnkgMS8oMl4oMipBU19QRV9GQUMpKSAqLwp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfY2FsY1NpbmdsZVNwZWNQZQoKICBzcGVjUGUgaXMgc2NhbGVkIGJ5IDEvKDJeKDIqQVNfUEVfRkFDX1NISUZUKSkKKi8Kc3RhdGljIEZJWFBfREJMIEZES2FhY0VuY19jYWxjU2luZ2xlU3BlY1BlKElOVCBzY2YsIEZJWFBfREJMIHNmYkNvbnN0UGVQYXJ0LCBGSVhQX0RCTCBuTGluZXMpCnsKICBGSVhQX0RCTCBzcGVjUGUgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBGSVhQX0RCTCBsZFJhdGlvOwogIEZJWFBfREJMIHNjZkZyYWN0OwoKICBzY2ZGcmFjdCA9IChGSVhQX0RCTCkoc2NmIDw8IChERlJBQ1RfQklUUy0xLUFTX1BFX0ZBQ19TSElGVCkpOwoKICBsZFJhdGlvID0gc2ZiQ29uc3RQZVBhcnQgLSBmTXVsdChGTDJGWENPTlNUX0RCTCgwLjM3NWYpLHNjZkZyYWN0KTsKCiAgaWYgKGxkUmF0aW8gPj0gUEVfQzEpIHsKICAgIHNwZWNQZSA9IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuN2YpLGZNdWx0KG5MaW5lcyxsZFJhdGlvKSk7CiAgfQogIGVsc2UgewogICAgc3BlY1BlID0gZk11bHQoRkwyRlhDT05TVF9EQkwoMC43ZiksZk11bHQobkxpbmVzLChQRV9DMiArIGZNdWx0KFBFX0MzLGxkUmF0aW8pKSkpOwogIH0KCiAgcmV0dXJuIHNwZWNQZTsgLyogb3V0cHV0IHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQykpICovCn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmCgogIHNjZkJpdHNEaWZmIGlzIHNjYWxlZCBieSAxLygyXigyKkFTX1BFX0ZBQ19TSElGVCkpCiovCnN0YXRpYyBGSVhQX0RCTCBGREthYWNFbmNfY291bnRTY2ZCaXRzRGlmZihJTlQgKnNjZk9sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydFNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHN0b3BTZmIpCnsKICBGSVhQX0RCTCBzY2ZCaXRzRnJhY3Q7CiAgSU5UIHNjZkJpdHNEaWZmID0gMDsKICBJTlQgc2ZiID0gMCwgc2ZiTGFzdDsKICBJTlQgc2ZiUHJldiwgc2ZiTmV4dDsKCiAgLyogc2VhcmNoIGZvciBmaXJzdCByZWxldmFudCBzZmIgKi8KICBzZmJMYXN0ID0gc3RhcnRTZmI7CiAgd2hpbGUgKChzZmJMYXN0PHN0b3BTZmIpICYmIChzY2ZPbGRbc2ZiTGFzdF09PUZES19JTlRfTUlOKSkKICAgIHNmYkxhc3QrKzsKICAvKiBzZWFyY2ggZm9yIHByZXZpb3VzIHJlbGV2YW50IHNmYiBhbmQgY291bnQgZGlmZiAqLwogIHNmYlByZXYgPSBzdGFydFNmYiAtIDE7CiAgd2hpbGUgKChzZmJQcmV2Pj0wKSAmJiAoc2NmT2xkW3NmYlByZXZdPT1GREtfSU5UX01JTikpCiAgICBzZmJQcmV2LS07CiAgaWYgKHNmYlByZXY+PTApCiAgICBzY2ZCaXRzRGlmZiArPSBGREthYWNFbmNfYml0Q291bnRTY2FsZWZhY3RvckRlbHRhKHNjZk5ld1tzZmJQcmV2XS1zY2ZOZXdbc2ZiTGFzdF0pIC0KICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYlByZXZdLXNjZk9sZFtzZmJMYXN0XSk7CiAgLyogbm93IGxvb3AgdGhyb3VnaCBhbGwgc2ZicyBhbmQgY291bnQgZGlmZnMgb2YgcmVsZXZhbnQgc2ZicyAqLwogIGZvciAoc2ZiPXNmYkxhc3QrMTsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICBpZiAoc2NmT2xkW3NmYl0hPUZES19JTlRfTUlOKSB7CiAgICAgIHNjZkJpdHNEaWZmICs9IEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmTmV3W3NmYkxhc3RdLXNjZk5ld1tzZmJdKSAtCiAgICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYkxhc3RdLXNjZk9sZFtzZmJdKTsKICAgICAgc2ZiTGFzdCA9IHNmYjsKICAgIH0KICB9CiAgLyogc2VhcmNoIGZvciBuZXh0IHJlbGV2YW50IHNmYiBhbmQgY291bnQgZGlmZiAqLwogIHNmYk5leHQgPSBzdG9wU2ZiOwogIHdoaWxlICgoc2ZiTmV4dDxzZmJDbnQpICYmIChzY2ZPbGRbc2ZiTmV4dF09PUZES19JTlRfTUlOKSkKICAgIHNmYk5leHQrKzsKICBpZiAoc2ZiTmV4dDxzZmJDbnQpCiAgICBzY2ZCaXRzRGlmZiArPSBGREthYWNFbmNfYml0Q291bnRTY2FsZWZhY3RvckRlbHRhKHNjZk5ld1tzZmJMYXN0XS1zY2ZOZXdbc2ZiTmV4dF0pIC0KICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19iaXRDb3VudFNjYWxlZmFjdG9yRGVsdGEoc2NmT2xkW3NmYkxhc3RdLXNjZk9sZFtzZmJOZXh0XSk7CgogIHNjZkJpdHNGcmFjdCA9IChGSVhQX0RCTCkgKHNjZkJpdHNEaWZmIDw8IChERlJBQ1RfQklUUy0xLSgyKkFTX1BFX0ZBQ19TSElGVCkpKTsKCiAgcmV0dXJuIHNjZkJpdHNGcmFjdDsKfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmCgogIHNwZWNQZURpZmYgaXMgc2NhbGVkIGJ5IDEvKDJeKDIqQVNfUEVfRkFDX1NISUZUKSkKKi8Kc3RhdGljIEZJWFBfREJMIEZES2FhY0VuY19jYWxjU3BlY1BlRGlmZihQU1lfT1VUX0NIQU5ORUwgKnBzeU91dENoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfQ0hBTk5FTCAgKnFjT3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqc2NmT2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRm9ybUZhY3RvckxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydFNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdG9wU2ZiKQp7CiAgRklYUF9EQkwgc3BlY1BlRGlmZiA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIEZJWFBfREJMIHNjZkZyYWN0ID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgSU5UIHNmYjsKCiAgLyogbG9vcCB0aHJvdWdoIGFsbCBzZmJzIGFuZCBjb3VudCBwZSBkaWZmZXJlbmNlICovCiAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgaWYgKHNjZk9sZFtzZmJdIT1GREtfSU5UX01JTikgewogICAgICBGSVhQX0RCTCBsZFJhdGlvT2xkLCBsZFJhdGlvTmV3LCBwT2xkLCBwTmV3OwoKICAgICAgLyogc2ZiQ29uc3RQZVBhcnRbc2ZiXSA9IChmbG9hdClsb2cocHN5T3V0Q2hhbi0+c2ZiRW5lcmd5W3NmYl0gKiA2Ljc1ZiAvIHNmYkZvcm1GYWN0b3Jbc2ZiXSkgKiBMT0cyXzE7ICovCiAgICAgIC8qIDAuMDIxNTIyNTU4NjFmID0gbG9nKDYuNzUpL2xvZygyKS9BU19QRV9GQUNfRkxPQVQ7IExPRzJfMSBpcyAxLjAgZm9yIGxvZzIgKi8KICAgICAgLyogMC4wOTM3NWYgPSBsb2coNjQuMCkvbG9nKDIuMCkvNjQuMCA9IHNjYWxlIG9mIHNmYkZvcm1GYWN0b3JMZERhdGEgKi8KICAgICAgaWYgKHNmYkNvbnN0UGVQYXJ0W3NmYl0gPT0gKEZJWFBfREJMKUZES19JTlRfTUlOKQogICAgICAgIHNmYkNvbnN0UGVQYXJ0W3NmYl0gPSAoKHBzeU91dENoYW4tPnNmYkVuZXJneUxkRGF0YVtzZmJdIC0gc2ZiRm9ybUZhY3RvckxkRGF0YVtzZmJdIC0gRkwyRlhDT05TVF9EQkwoMC4wOTM3NWYpKSA+PiAxKSArIEZMMkZYQ09OU1RfREJMKDAuMDIxNTIyNTU4NjFmKTsKCiAgICAgIHNjZkZyYWN0ID0gKEZJWFBfREJMKSAoc2NmT2xkW3NmYl0gPDwgKERGUkFDVF9CSVRTLTEtQVNfUEVfRkFDX1NISUZUKSk7CiAgICAgIGxkUmF0aW9PbGQgPSBzZmJDb25zdFBlUGFydFtzZmJdIC0gZk11bHQoRkwyRlhDT05TVF9EQkwoMC4zNzVmKSxzY2ZGcmFjdCk7CgogICAgICBzY2ZGcmFjdCA9IChGSVhQX0RCTCkgKHNjZk5ld1tzZmJdIDw8IChERlJBQ1RfQklUUy0xLUFTX1BFX0ZBQ19TSElGVCkpOwogICAgICBsZFJhdGlvTmV3ID0gc2ZiQ29uc3RQZVBhcnRbc2ZiXSAtIGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuMzc1Ziksc2NmRnJhY3QpOwoKICAgICAgaWYgKGxkUmF0aW9PbGQgPj0gUEVfQzEpCiAgICAgICAgcE9sZCA9IGxkUmF0aW9PbGQ7CiAgICAgIGVsc2UKICAgICAgICBwT2xkID0gUEVfQzIgKyBmTXVsdChQRV9DMyxsZFJhdGlvT2xkKTsKCiAgICAgIGlmIChsZFJhdGlvTmV3ID49IFBFX0MxKQogICAgICAgIHBOZXcgPSBsZFJhdGlvTmV3OwogICAgICBlbHNlCiAgICAgICAgcE5ldyA9IFBFX0MyICsgZk11bHQoUEVfQzMsbGRSYXRpb05ldyk7CgogICAgICBzcGVjUGVEaWZmICs9IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuN2YpLGZNdWx0KHNmYk5SZWxldmFudExpbmVzW3NmYl0sKHBOZXcgLSBwT2xkKSkpOwogICAgfQogIH0KCiAgcmV0dXJuIHNwZWNQZURpZmY7Cn0KCi8qCiAgRnVuY3Rpb246IEZES2FhY0VuY19pbXByb3ZlU2NmCgogIERlc2NyaXB0aW9uOiBDYWxjdWxhdGUgdGhlIGRpc3RvcnRpb24gYnkgcXVhbnRpemF0aW9uIGFuZCBpbnZlcnNlIHF1YW50aXphdGlvbiBvZiB0aGUgc3BlY3RydW0gd2l0aAogICAgICAgICAgICAgICB2YXJpb3VzIHNjYWxlZmFjdG9ycy4gVGhlIHNjYWxlZmFjdG9yIHdoaWNoIHByb3ZpZGVzIHRoZSBiZXN0IHJlc3VsdHMgd2lsbCBiZSB1c2VkLgoqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19pbXByb3ZlU2NmKEZJWFBfREJMICpzcGVjLAogICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgdGhyZXNoTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgSU5UIHNjZiwKICAgICAgICAgICAgICAgICAgICAgIElOVCBtaW5TY2YsCiAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgKmRpc3RMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZkNhbGN1bGF0ZWQsCiAgICAgICAgICAgICAgICAgICAgICBJTlQgZFpvbmVRdWFudEVuYWJsZQogICAgICAgICAgICAgICAgICAgICAgKQp7CiAgIEZJWFBfREJMIHNmYkRpc3RMZERhdGE7CiAgIElOVCBzY2ZCZXN0ID0gc2NmOwogICBJTlQgazsKICAgRklYUF9EQkwgZGlzdEZhY3RvckxkRGF0YSA9IEZMMkZYQ09OU1RfREJMKC0wLjAwNTAzMDEyNjUpOyAgIC8qIGxkNjQoMS8xLjI1KSAqLwoKICAgLyogY2FsYyByZWFsIGRpc3RvcnRpb24gKi8KICAgc2ZiRGlzdExkRGF0YSA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFpvbmVRdWFudEVuYWJsZSk7CiAgICptaW5TY2ZDYWxjdWxhdGVkID0gc2NmOwogICAvKiBubXIgPiAxLjI1IC0+IHRyeSB0byBpbXByb3ZlIG5tciAqLwogICBpZiAoc2ZiRGlzdExkRGF0YSA+ICh0aHJlc2hMZERhdGEtZGlzdEZhY3RvckxkRGF0YSkpIHsKICAgICAgSU5UIHNjZkVzdGltYXRlZCA9IHNjZjsKICAgICAgRklYUF9EQkwgc2ZiRGlzdEJlc3RMZERhdGEgPSBzZmJEaXN0TGREYXRhOwogICAgICBJTlQgY250OwogICAgICAvKiBpbXByb3ZlIGJ5IGJpZ2dlciBzY2YgPyAqLwogICAgICBjbnQgPSAwOwoKICAgICAgd2hpbGUgKChzZmJEaXN0TGREYXRhID4gKHRocmVzaExkRGF0YS1kaXN0RmFjdG9yTGREYXRhKSkgJiYgKGNudCsrIDwgMykpIHsKICAgICAgICAgc2NmKys7CiAgICAgICAgIHNmYkRpc3RMZERhdGEgPSBGREthYWNFbmNfY2FsY1NmYkRpc3Qoc3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUpOwoKICAgICAgICAgaWYgKHNmYkRpc3RMZERhdGEgPCBzZmJEaXN0QmVzdExkRGF0YSkgewogICAgICAgICAgICBzY2ZCZXN0ID0gc2NmOwogICAgICAgICAgICBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYldpZHRoOyBrKyspCgkgICAgICAgICAgICAgcXVhbnRTcGVjW2tdID0gcXVhbnRTcGVjVG1wW2tdOwogICAgICAgICB9CiAgICAgIH0KICAgICAgLyogaW1wcm92ZSBieSBzbWFsbGVyIHNjZiA/ICovCiAgICAgIGNudCA9IDA7CiAgICAgIHNjZiA9IHNjZkVzdGltYXRlZDsKICAgICAgc2ZiRGlzdExkRGF0YSA9IHNmYkRpc3RCZXN0TGREYXRhOwogICAgICB3aGlsZSAoKHNmYkRpc3RMZERhdGEgPiAodGhyZXNoTGREYXRhLWRpc3RGYWN0b3JMZERhdGEpKSAmJiAoY250KysgPCAxKSAmJiAoc2NmID4gbWluU2NmKSkgewogICAgICAgICBzY2YtLTsKICAgICAgICAgc2ZiRGlzdExkRGF0YSA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFpvbmVRdWFudEVuYWJsZSk7CgogICAgICAgICBpZiAoc2ZiRGlzdExkRGF0YSA8IHNmYkRpc3RCZXN0TGREYXRhKSB7CiAgICAgICAgICAgIHNjZkJlc3QgPSBzY2Y7CiAgICAgICAgICAgIHNmYkRpc3RCZXN0TGREYXRhID0gc2ZiRGlzdExkRGF0YTsKICAgICAgICAgICAgZm9yIChrPTA7IGs8c2ZiV2lkdGg7IGsrKykKCSAgICAgICAgICAgICBxdWFudFNwZWNba10gPSBxdWFudFNwZWNUbXBba107CiAgICAgICAgIH0KICAgICAgICAgKm1pblNjZkNhbGN1bGF0ZWQgPSBzY2Y7CiAgICAgIH0KICAgICAgKmRpc3RMZERhdGEgPSBzZmJEaXN0QmVzdExkRGF0YTsKICAgfQogICBlbHNlIHsgLyogbm1yIDw9IDEuMjUgLT4gdHJ5IHRvIGZpbmQgYmlnZ2VyIHNjZiB0byB1c2UgbGVzcyBiaXRzICovCiAgICAgIEZJWFBfREJMIHNmYkRpc3RCZXN0TGREYXRhID0gc2ZiRGlzdExkRGF0YTsKICAgICAgRklYUF9EQkwgc2ZiRGlzdEFsbG93ZWRMZERhdGEgPSBmaXhNaW4oc2ZiRGlzdExkRGF0YS1kaXN0RmFjdG9yTGREYXRhLHRocmVzaExkRGF0YSk7CiAgICAgIGludCBjbnQ7CiAgICAgIGZvciAoY250PTA7IGNudDwzOyBjbnQrKykgewogICAgICAgICBzY2YrKzsKICAgICAgICAgc2ZiRGlzdExkRGF0YSA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFpvbmVRdWFudEVuYWJsZSk7CgogICAgICAgICBpZiAoc2ZiRGlzdExkRGF0YSA8IHNmYkRpc3RBbGxvd2VkTGREYXRhKSB7CiAgICAgICAgICAgKm1pblNjZkNhbGN1bGF0ZWQgPSBzY2ZCZXN0KzE7CiAgICAgICAgICAgc2NmQmVzdCA9IHNjZjsKICAgICAgICAgICBzZmJEaXN0QmVzdExkRGF0YSA9IHNmYkRpc3RMZERhdGE7CiAgICAgICAgICAgZm9yIChrPTA7IGs8c2ZiV2lkdGg7IGsrKykKICAgICAgICAgICAgIHF1YW50U3BlY1trXSA9IHF1YW50U3BlY1RtcFtrXTsKICAgICAgICAgfQogICAgICB9CiAgICAgICpkaXN0TGREYXRhID0gc2ZiRGlzdEJlc3RMZERhdGE7CiAgIH0KCiAgIC8qIHJldHVybiBiZXN0IHNjYWxlZmFjdG9yICovCiAgIHJldHVybiBzY2ZCZXN0Owp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfYXNzaW1pbGF0ZVNpbmdsZVNjZgoKKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX2Fzc2ltaWxhdGVTaW5nbGVTY2YoUFNZX09VVF9DSEFOTkVMICpwc3lPdXRDaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMICAgKnFjT3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSE9SVCAqcXVhbnRTcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGRab25lUXVhbnRFbmFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICptaW5TY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkRpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJGb3JtRmFjdG9yTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZkNhbGN1bGF0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHJlc3RhcnRPblN1Y2Nlc3MpCnsKICBJTlQgc2ZiTGFzdCwgc2ZiQWN0LCBzZmJOZXh0OwogIElOVCBzY2ZBY3QsICpzY2ZMYXN0LCAqc2NmTmV4dCwgc2NmTWluLCBzY2ZNYXg7CiAgSU5UIHNmYldpZHRoLCBzZmJPZmZzOwogIEZJWFBfREJMIGVuTGREYXRhOwogIEZJWFBfREJMIHNmYlBlT2xkLCBzZmJQZU5ldzsKICBGSVhQX0RCTCBzZmJEaXN0TmV3OwogIElOVCBpLCBrOwogIElOVCBzdWNjZXNzID0gMDsKICBGSVhQX0RCTCBkZWx0YVBlID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgRklYUF9EQkwgZGVsdGFQZU5ldywgZGVsdGFQZVRtcDsKICBJTlQgcHJldlNjZkxhc3RbTUFYX0dST1VQRURfU0ZCXSwgcHJldlNjZk5leHRbTUFYX0dST1VQRURfU0ZCXTsKICBGSVhQX0RCTCBkZWx0YVBlTGFzdFtNQVhfR1JPVVBFRF9TRkJdOwogIElOVCB1cGRhdGVNaW5TY2ZDYWxjdWxhdGVkOwoKICBmb3IgKGk9MDsgaTxwc3lPdXRDaGFuLT5zZmJDbnQ7IGkrKykgewogICAgcHJldlNjZkxhc3RbaV0gPSBGREtfSU5UX01BWDsKICAgIHByZXZTY2ZOZXh0W2ldID0gRkRLX0lOVF9NQVg7CiAgICBkZWx0YVBlTGFzdFtpXSA9IChGSVhQX0RCTClGREtfSU5UX01BWDsKICB9CgogIHNmYkxhc3QgPSAtMTsKICBzZmJBY3QgID0gLTE7CiAgc2ZiTmV4dCA9IC0xOwogIHNjZkxhc3QgPSAwOwogIHNjZk5leHQgPSAwOwogIHNjZk1pbiAgPSBGREtfSU5UX01BWDsKICBzY2ZNYXggID0gRkRLX0lOVF9NQVg7CiAgZG8gewogICAgLyogc2VhcmNoIGZvciBuZXcgcmVsZXZhbnQgc2ZiICovCiAgICBzZmJOZXh0Kys7CiAgICB3aGlsZSAoKHNmYk5leHQgPCBwc3lPdXRDaGFuLT5zZmJDbnQpICYmIChzY2Zbc2ZiTmV4dF0gPT0gRkRLX0lOVF9NSU4pKQogICAgICBzZmJOZXh0Kys7CiAgICBpZiAoKHNmYkxhc3Q+PTApICYmIChzZmJBY3Q+PTApICYmIChzZmJOZXh0PHBzeU91dENoYW4tPnNmYkNudCkpIHsKICAgICAgLyogcmVsZXZhbnQgc2NmcyB0byB0aGUgbGVmdCBhbmQgdG8gdGhlIHJpZ2h0ICovCiAgICAgIHNjZkFjdCAgPSBzY2Zbc2ZiQWN0XTsKICAgICAgc2NmTGFzdCA9IHNjZiArIHNmYkxhc3Q7CiAgICAgIHNjZk5leHQgPSBzY2YgKyBzZmJOZXh0OwogICAgICBzY2ZNaW4gID0gZml4TWluKCpzY2ZMYXN0LCAqc2NmTmV4dCk7CiAgICAgIHNjZk1heCAgPSBmaXhNYXgoKnNjZkxhc3QsICpzY2ZOZXh0KTsKICAgIH0KICAgIGVsc2UgaWYgKChzZmJMYXN0PT0tMSkgJiYgKHNmYkFjdD49MCkgJiYgKHNmYk5leHQ8cHN5T3V0Q2hhbi0+c2ZiQ250KSkgewogICAgICAvKiBmaXJzdCByZWxldmFudCBzY2YgKi8KICAgICAgc2NmQWN0ICA9IHNjZltzZmJBY3RdOwogICAgICBzY2ZMYXN0ID0gJnNjZkFjdDsKICAgICAgc2NmTmV4dCA9IHNjZiArIHNmYk5leHQ7CiAgICAgIHNjZk1pbiAgPSAqc2NmTmV4dDsKICAgICAgc2NmTWF4ICA9ICpzY2ZOZXh0OwogICAgfQogICAgZWxzZSBpZiAoKHNmYkxhc3Q+PTApICYmIChzZmJBY3Q+PTApICYmIChzZmJOZXh0PT1wc3lPdXRDaGFuLT5zZmJDbnQpKSB7CiAgICAgIC8qIGxhc3QgcmVsZXZhbnQgc2NmICovCiAgICAgIHNjZkFjdCAgPSBzY2Zbc2ZiQWN0XTsKICAgICAgc2NmTGFzdCA9IHNjZiArIHNmYkxhc3Q7CiAgICAgIHNjZk5leHQgPSAmc2NmQWN0OwogICAgICBzY2ZNaW4gID0gKnNjZkxhc3Q7CiAgICAgIHNjZk1heCAgPSAqc2NmTGFzdDsKICAgIH0KICAgIGlmIChzZmJBY3Q+PTApCiAgICAgIHNjZk1pbiA9IGZpeE1heChzY2ZNaW4sIG1pblNjZltzZmJBY3RdKTsKCiAgICBpZiAoKHNmYkFjdCA+PSAwKSAmJgogICAgICAgIChzZmJMYXN0Pj0wIHx8IHNmYk5leHQ8cHN5T3V0Q2hhbi0+c2ZiQ250KSAmJgogICAgICAgIChzY2ZBY3QgPiBzY2ZNaW4pICYmCiAgICAgICAgKHNjZkFjdCA8PSBzY2ZNaW4rTUFYX1NDRl9ERUxUQSkgJiYKICAgICAgICAoc2NmQWN0ID49IHNjZk1heC1NQVhfU0NGX0RFTFRBKSAmJgogICAgICAgICgqc2NmTGFzdCAhPSBwcmV2U2NmTGFzdFtzZmJBY3RdIHx8CiAgICAgICAgICpzY2ZOZXh0ICE9IHByZXZTY2ZOZXh0W3NmYkFjdF0gfHwKICAgICAgICAgZGVsdGFQZSA8IGRlbHRhUGVMYXN0W3NmYkFjdF0pKSB7CiAgICAgIC8qIGJpZ2dlciB0aGFuIG5laWdoYm91cmluZyBzY2YgZm91bmQsIHRyeSB0byB1c2Ugc21hbGxlciBzY2YgKi8KICAgICAgc3VjY2VzcyA9IDA7CgogICAgICBzZmJXaWR0aCA9IHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiQWN0KzFdIC0gcHN5T3V0Q2hhbi0+c2ZiT2Zmc2V0c1tzZmJBY3RdOwogICAgICBzZmJPZmZzID0gcHN5T3V0Q2hhbi0+c2ZiT2Zmc2V0c1tzZmJBY3RdOwoKICAgICAgLyogZXN0aW1hdGUgcmVxdWlyZWQgYml0cyBmb3IgYWN0dWFsIHNjZiAqLwogICAgICBlbkxkRGF0YSA9IHFjT3V0Q2hhbm5lbC0+c2ZiRW5lcmd5TGREYXRhW3NmYkFjdF07CgogICAgICAvKiBzZmJDb25zdFBlUGFydFtzZmJBY3RdID0gKGZsb2F0KWxvZyg2Ljc1Ziplbi9zZmJGb3JtRmFjdG9yW3NmYkFjdF0pICogTE9HMl8xOyAqLwogICAgICAvKiAwLjAyMTUyMjU1ODYxZiA9IGxvZyg2Ljc1KS9sb2coMikvQVNfUEVfRkFDX0ZMT0FUOyBMT0cyXzEgaXMgMS4wIGZvciBsb2cyICovCiAgICAgIC8qIDAuMDkzNzVmID0gbG9nKDY0LjApL2xvZygyLjApLzY0LjAgPSBzY2FsZSBvZiBzZmJGb3JtRmFjdG9yTGREYXRhICovCiAgICAgIGlmIChzZmJDb25zdFBlUGFydFtzZmJBY3RdID09IChGSVhQX0RCTClGREtfSU5UX01JTikgewogICAgICAgIHNmYkNvbnN0UGVQYXJ0W3NmYkFjdF0gPSAoKGVuTGREYXRhIC0gc2ZiRm9ybUZhY3RvckxkRGF0YVtzZmJBY3RdIC0gRkwyRlhDT05TVF9EQkwoMC4wOTM3NWYpKSA+PiAxKSArIEZMMkZYQ09OU1RfREJMKDAuMDIxNTIyNTU4NjFmKTsKICAgICAgfQoKICAgICAgc2ZiUGVPbGQgPSBGREthYWNFbmNfY2FsY1NpbmdsZVNwZWNQZShzY2ZBY3Qsc2ZiQ29uc3RQZVBhcnRbc2ZiQWN0XSxzZmJOUmVsZXZhbnRMaW5lc1tzZmJBY3RdKQogICAgICAgICAgICAgICAgK0ZES2FhY0VuY19jb3VudFNpbmdsZVNjZkJpdHMoc2NmQWN0LCAqc2NmTGFzdCwgKnNjZk5leHQpOwoKICAgICAgZGVsdGFQZU5ldyA9IGRlbHRhUGU7CiAgICAgIHVwZGF0ZU1pblNjZkNhbGN1bGF0ZWQgPSAxOwoKICAgICAgZG8gewogICAgICAgIC8qIGVzdGltYXRlIHJlcXVpcmVkIGJpdHMgZm9yIHNtYWxsZXIgc2NmICovCiAgICAgICAgc2NmQWN0LS07CiAgICAgICAgLyogY2hlY2sgb25seSBpZiB0aGUgc2FtZSBjaGVjayB3YXMgbm90IGRvbmUgYmVmb3JlICovCiAgICAgICAgaWYgKHNjZkFjdCA8IG1pblNjZkNhbGN1bGF0ZWRbc2ZiQWN0XSAmJiBzY2ZBY3Q+PXNjZk1heC1NQVhfU0NGX0RFTFRBKXsKICAgICAgICAgIC8qIGVzdGltYXRlIHJlcXVpcmVkIGJpdHMgZm9yIG5ldyBzY2YgKi8KICAgICAgICAgIHNmYlBlTmV3ID0gIEZES2FhY0VuY19jYWxjU2luZ2xlU3BlY1BlKHNjZkFjdCxzZmJDb25zdFBlUGFydFtzZmJBY3RdLHNmYk5SZWxldmFudExpbmVzW3NmYkFjdF0pCiAgICAgICAgICAgICAgICAgICAgICtGREthYWNFbmNfY291bnRTaW5nbGVTY2ZCaXRzKHNjZkFjdCwqc2NmTGFzdCwgKnNjZk5leHQpOwoKICAgICAgICAgIC8qIHVzZSBuZXcgc2NmIGlmIG5vIGluY3JlYXNlIGluIHBlIGFuZAogICAgICAgICAgICAgcXVhbnRpemF0aW9uIGVycm9yIGlzIHNtYWxsZXIgKi8KICAgICAgICAgIGRlbHRhUGVUbXAgPSBkZWx0YVBlICsgc2ZiUGVOZXcgLSBzZmJQZU9sZDsKICAgICAgICAgIC8qIDAuMDAwNjEwMzUxNTYyNWYgPSAxMC4wZi8oMl4oMipBU19QRV9GQUNfU0hJRlQpKSAqLwogICAgICAgICAgaWYgKGRlbHRhUGVUbXAgPCBGTDJGWENPTlNUX0RCTCgwLjAwMDYxMDM1MTU2MjVmKSkgewogICAgICAgICAgICAvKiBkaXN0b3J0aW9uIG9mIG5ldyBzY2YgKi8KICAgICAgICAgICAgc2ZiRGlzdE5ldyA9IEZES2FhY0VuY19jYWxjU2ZiRGlzdChxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bStzZmJPZmZzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCtzZmJPZmZzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZkFjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWm9uZVF1YW50RW5hYmxlKTsKCiAgICAgICAgICAgIGlmIChzZmJEaXN0TmV3IDwgc2ZiRGlzdFtzZmJBY3RdKSB7CiAgICAgICAgICAgICAgLyogc3VjY2VzcywgcmVwbGFjZSBzY2YgYnkgbmV3IG9uZSAqLwogICAgICAgICAgICAgIHNjZltzZmJBY3RdID0gc2NmQWN0OwogICAgICAgICAgICAgIHNmYkRpc3Rbc2ZiQWN0XSA9IHNmYkRpc3ROZXc7CgogICAgICAgICAgICAgIGZvciAoaz0wOyBrPHNmYldpZHRoOyBrKyspCiAgICAgICAgICAgICAgICBxdWFudFNwZWNbc2ZiT2ZmcytrXSA9IHF1YW50U3BlY1RtcFtzZmJPZmZzK2tdOwoKICAgICAgICAgICAgICBkZWx0YVBlTmV3ID0gZGVsdGFQZVRtcDsKICAgICAgICAgICAgICBzdWNjZXNzID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBtYXJrIGFzIGFscmVhZHkgY2hlY2tlZCAqLwogICAgICAgICAgICBpZiAodXBkYXRlTWluU2NmQ2FsY3VsYXRlZCkKICAgICAgICAgICAgICBtaW5TY2ZDYWxjdWxhdGVkW3NmYkFjdF0gPSBzY2ZBY3Q7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyogZnJvbSB0aGlzIHNjZiB2YWx1ZSBvbiBub3QgYWxsIG5ldyB2YWx1ZXMgaGF2ZSBiZWVuIGNoZWNrZWQgKi8KICAgICAgICAgICAgdXBkYXRlTWluU2NmQ2FsY3VsYXRlZCA9IDA7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9IHdoaWxlIChzY2ZBY3QgPiBzY2ZNaW4pOwoKICAgICAgZGVsdGFQZSA9IGRlbHRhUGVOZXc7CgogICAgICAvKiBzYXZlIHBhcmFtZXRlcnMgdG8gYXZvaWQgbXVsdGlwbGUgY29tcHV0YXRpb25zIG9mIHRoZSBzYW1lIHNmYiAqLwogICAgICBwcmV2U2NmTGFzdFtzZmJBY3RdID0gKnNjZkxhc3Q7CiAgICAgIHByZXZTY2ZOZXh0W3NmYkFjdF0gPSAqc2NmTmV4dDsKICAgICAgZGVsdGFQZUxhc3Rbc2ZiQWN0XSA9IGRlbHRhUGU7CiAgICB9CgogICAgaWYgKHN1Y2Nlc3MgJiYgcmVzdGFydE9uU3VjY2VzcykgewogICAgICAvKiBzdGFydCBhZ2FpbiBhdCBmaXJzdCBzZmIgKi8KICAgICAgc2ZiTGFzdCA9IC0xOwogICAgICBzZmJBY3QgID0gLTE7CiAgICAgIHNmYk5leHQgPSAtMTsKICAgICAgc2NmTGFzdCA9IDA7CiAgICAgIHNjZk5leHQgPSAwOwogICAgICBzY2ZNaW4gID0gRkRLX0lOVF9NQVg7CiAgICAgIHNjZk1heCAgPSBGREtfSU5UX01BWDsKICAgICAgc3VjY2VzcyA9IDA7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogc2hpZnQgc2ZicyBmb3IgbmV4dCBiYW5kICovCiAgICAgIHNmYkxhc3QgPSBzZmJBY3Q7CiAgICAgIHNmYkFjdCAgPSBzZmJOZXh0OwogICAgfQogIH0gd2hpbGUgKHNmYk5leHQgPCBwc3lPdXRDaGFuLT5zZmJDbnQpOwp9CgovKgogIEZ1bmN0aW9uOiBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmCgoqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmKFBTWV9PVVRfQ0hBTk5FTCAqcHN5T3V0Q2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZFpvbmVRdWFudEVuYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqc2NmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICptaW5TY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzZmJGb3JtRmFjdG9yTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYk5SZWxldmFudExpbmVzKQp7CiAgSU5UIHNmYiwgc3RhcnRTZmIsIHN0b3BTZmI7CiAgSU5UIHNjZlRtcFtNQVhfR1JPVVBFRF9TRkJdLCBzY2ZNaW4sIHNjZk1heCwgc2NmQWN0OwogIElOVCBwb3NzaWJsZVJlZ2lvbkZvdW5kOwogIElOVCBzZmJXaWR0aCwgc2ZiT2ZmcywgaSwgazsKICBGSVhQX0RCTCBzZmJEaXN0TmV3W01BWF9HUk9VUEVEX1NGQl0sIGRpc3RPbGRTdW0sIGRpc3ROZXdTdW07CiAgSU5UIGRlbHRhU2NmQml0czsKICBGSVhQX0RCTCBkZWx0YVNwZWNQZTsKICBGSVhQX0RCTCBkZWx0YVBlID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgRklYUF9EQkwgZGVsdGFQZU5ldzsKICBJTlQgc2ZiQ250ID0gcHN5T3V0Q2hhbi0+c2ZiQ250OwoKICAvKiBjYWxjIG1pbiBhbmQgbWF4IHNjYWxmYWN0b3JzICovCiAgc2NmTWluID0gRkRLX0lOVF9NQVg7CiAgc2NmTWF4ID0gRkRLX0lOVF9NSU47CiAgZm9yIChzZmI9MDsgc2ZiPHNmYkNudDsgc2ZiKyspIHsKICAgIGlmIChzY2Zbc2ZiXSE9RkRLX0lOVF9NSU4pIHsKICAgICAgc2NmTWluID0gZml4TWluKHNjZk1pbiwgc2NmW3NmYl0pOwogICAgICBzY2ZNYXggPSBmaXhNYXgoc2NmTWF4LCBzY2Zbc2ZiXSk7CiAgICB9CiAgfQoKICBpZiAoc2NmTWF4ICE9IEZES19JTlRfTUlOICYmIHNjZk1heCA8PSBzY2ZNaW4rTUFYX1NDRl9ERUxUQSkgewoKICAgIHNjZkFjdCA9IHNjZk1heDsKCiAgICBkbyB7CiAgICAgIC8qIHRyeSBzbWFsbGVyIHNjZiAqLwogICAgICBzY2ZBY3QtLTsKICAgICAgZm9yIChpPTA7IGk8TUFYX0dST1VQRURfU0ZCOyBpKyspCiAgICAgICAgc2NmVG1wW2ldID0gc2NmW2ldOwogICAgICBzdG9wU2ZiID0gMDsKICAgICAgZG8gewogICAgICAgIC8qIHNlYXJjaCBmb3IgcmVnaW9uIHdoZXJlIGFsbCBzY2ZzIGFyZSBiaWdnZXIgdGhhbiBzY2ZBY3QgKi8KICAgICAgICBzZmIgPSBzdG9wU2ZiOwogICAgICAgIHdoaWxlIChzZmI8c2ZiQ250ICYmIChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4gfHwgc2NmW3NmYl0gPD0gc2NmQWN0KSkKICAgICAgICAgIHNmYisrOwogICAgICAgIHN0YXJ0U2ZiID0gc2ZiOwogICAgICAgIHNmYisrOwogICAgICAgIHdoaWxlIChzZmI8c2ZiQ250ICYmIChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4gfHwgc2NmW3NmYl0gPiBzY2ZBY3QpKQogICAgICAgICAgc2ZiKys7CiAgICAgICAgc3RvcFNmYiA9IHNmYjsKCiAgICAgICAgLyogY2hlY2sgaWYgaW4gYWxsIHNmYiBvZiBhIHZhbGlkIHJlZ2lvbiBzY2ZBY3QgPj0gbWluU2NmW3NmYl0gKi8KICAgICAgICBwb3NzaWJsZVJlZ2lvbkZvdW5kID0gMDsKICAgICAgICBpZiAoc3RhcnRTZmIgPCBzZmJDbnQpIHsKICAgICAgICAgIHBvc3NpYmxlUmVnaW9uRm91bmQgPSAxOwogICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICBpZiAoc2NmW3NmYl0gIT0gRkRLX0lOVF9NSU4pCiAgICAgICAgICAgICAgaWYgKHNjZkFjdCA8IG1pblNjZltzZmJdKSB7CiAgICAgICAgICAgICAgICBwb3NzaWJsZVJlZ2lvbkZvdW5kID0gMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChwb3NzaWJsZVJlZ2lvbkZvdW5kKSB7IC8qIHJlZ2lvbiBmb3VuZCAqLwoKICAgICAgICAgIC8qIHJlcGxhY2Ugc2NmcyBpbiByZWdpb24gYnkgc2NmQWN0ICovCiAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikKICAgICAgICAgICAgICBzY2ZUbXBbc2ZiXSA9IHNjZkFjdDsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBlc3RpbWF0ZSBjaGFuZ2UgaW4gYml0IGRlbWFuZCBmb3IgbmV3IHNjZnMgKi8KICAgICAgICAgIGRlbHRhU2NmQml0cyA9IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmKHNjZixzY2ZUbXAsc2ZiQ250LHN0YXJ0U2ZiLHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhU3BlY1BlID0gRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmKHBzeU91dENoYW4sIHFjT3V0Q2hhbm5lbCwgc2NmLCBzY2ZUbXAsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTZmIsIHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhUGVOZXcgPSBkZWx0YVBlICsgKEZJWFBfREJMKWRlbHRhU2NmQml0cyArIGRlbHRhU3BlY1BlOwoKICAgICAgICAgIC8qIG5ldyBiaXQgZGVtYW5kIHNtYWxsIGVub3VnaCA/ICovCiAgICAgICAgICAvKiAwLjAwMDYxMDM1MTU2MjVmID0gMTAuMGYvKDJeKDIqQVNfUEVfRkFDX1NISUZUKSkgKi8KICAgICAgICAgIGlmIChkZWx0YVBlTmV3IDwgRkwyRlhDT05TVF9EQkwoMC4wMDA2MTAzNTE1NjI1ZikpIHsKCiAgICAgICAgICAgIC8qIHF1YW50aXplIGFuZCBjYWxjIHN1bSBvZiBuZXcgZGlzdG9ydGlvbiAqLwogICAgICAgICAgICBkaXN0T2xkU3VtID0gZGlzdE5ld1N1bSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICBkaXN0T2xkU3VtICs9IENhbGNJbnZMZERhdGEoc2ZiRGlzdFtzZmJdKSA+PiBESVNUX0ZBQ19TSElGVDsKCiAgICAgICAgICAgICAgICBzZmJXaWR0aCA9IHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiKzFdIC0gcHN5T3V0Q2hhbi0+c2ZiT2Zmc2V0c1tzZmJdOwogICAgICAgICAgICAgICAgc2ZiT2ZmcyA9IHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiXTsKCiAgICAgICAgICAgICAgICBzZmJEaXN0TmV3W3NmYl0gPSBGREthYWNFbmNfY2FsY1NmYkRpc3QocWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW0rc2ZiT2ZmcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1RtcCtzZmJPZmZzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2ZBY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWm9uZVF1YW50RW5hYmxlKTsKCiAgICAgICAgICAgICAgICBpZiAoc2ZiRGlzdE5ld1tzZmJdID5xY091dENoYW5uZWwtPnNmYlRocmVzaG9sZExkRGF0YVtzZmJdKSB7CiAgICAgICAgICAgICAgICAgIC8qIG5vIGltcHJvdmVtZW50LCBza2lwIGZ1cnRoZXIgZGlzdC4gY2FsY3VsYXRpb25zICovCiAgICAgICAgICAgICAgICAgIGRpc3ROZXdTdW0gPSBkaXN0T2xkU3VtIDw8IDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlzdE5ld1N1bSArPSBDYWxjSW52TGREYXRhKHNmYkRpc3ROZXdbc2ZiXSkgPj4gRElTVF9GQUNfU0hJRlQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGRpc3RvcnRpb24gc21hbGxlciA/IC0+IHVzZSBuZXcgc2NhbGVmYWN0b3JzICovCiAgICAgICAgICAgIGlmIChkaXN0TmV3U3VtIDwgZGlzdE9sZFN1bSkgewogICAgICAgICAgICAgIGRlbHRhUGUgPSBkZWx0YVBlTmV3OwogICAgICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgICAgIGlmIChzY2Zbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgICAgICBzZmJXaWR0aCA9IHBzeU91dENoYW4tPnNmYk9mZnNldHNbc2ZiKzFdIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYl07CiAgICAgICAgICAgICAgICAgIHNmYk9mZnMgPSBwc3lPdXRDaGFuLT5zZmJPZmZzZXRzW3NmYl07CiAgICAgICAgICAgICAgICAgIHNjZltzZmJdID0gc2NmQWN0OwogICAgICAgICAgICAgICAgICBzZmJEaXN0W3NmYl0gPSBzZmJEaXN0TmV3W3NmYl07CgogICAgICAgICAgICAgICAgICBmb3IgKGs9MDsgazxzZmJXaWR0aDsgaysrKQogICAgICAgICAgICAgICAgICAgIHF1YW50U3BlY1tzZmJPZmZzK2tdID0gcXVhbnRTcGVjVG1wW3NmYk9mZnMra107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgIH0gd2hpbGUgKHN0b3BTZmIgPD0gc2ZiQ250KTsKCiAgICB9IHdoaWxlIChzY2ZBY3QgPiBzY2ZNaW4pOwogIH0KfQoKLyoKICBGdW5jdGlvbjogRkRLYWFjRW5jX0ZES2FhY0VuY19hc3NpbWlsYXRlTXVsdGlwbGVTY2YyCgoqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfRkRLYWFjRW5jX2Fzc2ltaWxhdGVNdWx0aXBsZVNjZjIoUFNZX09VVF9DSEFOTkVMICpwc3lPdXRDaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9DSEFOTkVMICAqcWNPdXRDaGFubmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICpxdWFudFNwZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKnF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZFpvbmVRdWFudEVuYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKnNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKm1pblNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiRGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYkZvcm1GYWN0b3JMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmYk5SZWxldmFudExpbmVzKQp7CiAgSU5UIHNmYiwgc3RhcnRTZmIsIHN0b3BTZmI7CiAgSU5UIHNjZlRtcFtNQVhfR1JPVVBFRF9TRkJdLCBzY2ZBY3QsIHNjZk5ldzsKICBJTlQgc2NmUHJldiwgc2NmTmV4dCwgc2NmUHJldk5leHRNaW4sIHNjZlByZXZOZXh0TWF4LCBzY2ZMbywgc2NmSGk7CiAgSU5UIHNjZk1pbiwgc2NmTWF4OwogIElOVCAqc2ZiT2ZmcyA9IHBzeU91dENoYW4tPnNmYk9mZnNldHM7CiAgRklYUF9EQkwgc2ZiRGlzdE5ld1tNQVhfR1JPVVBFRF9TRkJdLCBzZmJEaXN0TWF4W01BWF9HUk9VUEVEX1NGQl07CiAgRklYUF9EQkwgZGlzdE9sZFN1bSwgZGlzdE5ld1N1bTsKICBJTlQgZGVsdGFTY2ZCaXRzOwogIEZJWFBfREJMIGRlbHRhU3BlY1BlOwogIEZJWFBfREJMIGRlbHRhUGUgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBGSVhQX0RCTCBkZWx0YVBlTmV3ID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgSU5UIHNmYkNudCA9IHBzeU91dENoYW4tPnNmYkNudDsKICBJTlQgYlN1Y2Nlc3MsIGJDaGVja1NjZjsKICBJTlQgaSxrOwoKICAvKiBjYWxjIG1pbiBhbmQgbWF4IHNjYWxmYWN0b3JzICovCiAgc2NmTWluID0gRkRLX0lOVF9NQVg7CiAgc2NmTWF4ID0gRkRLX0lOVF9NSU47CiAgZm9yIChzZmI9MDsgc2ZiPHNmYkNudDsgc2ZiKyspIHsKICAgIGlmIChzY2Zbc2ZiXSE9RkRLX0lOVF9NSU4pIHsKICAgICAgc2NmTWluID0gZml4TWluKHNjZk1pbiwgc2NmW3NmYl0pOwogICAgICBzY2ZNYXggPSBmaXhNYXgoc2NmTWF4LCBzY2Zbc2ZiXSk7CiAgICB9CiAgfQoKICBzdG9wU2ZiID0gMDsKICBzY2ZBY3QgPSBGREtfSU5UX01JTjsKICBkbyB7CiAgICAvKiBzZWFyY2ggZm9yIHJlZ2lvbiB3aXRoIHNhbWUgc2NmIHZhbHVlcyBzY2ZBY3QgKi8KICAgIHNjZlByZXYgPSBzY2ZBY3Q7CgogICAgc2ZiID0gc3RvcFNmYjsKICAgIHdoaWxlIChzZmI8c2ZiQ250ICYmIChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4pKQogICAgICBzZmIrKzsKICAgIHN0YXJ0U2ZiID0gc2ZiOwogICAgc2NmQWN0ID0gc2NmW3N0YXJ0U2ZiXTsKICAgIHNmYisrOwogICAgd2hpbGUgKHNmYjxzZmJDbnQgJiYgKChzY2Zbc2ZiXT09RkRLX0lOVF9NSU4pIHx8IChzY2Zbc2ZiXT09c2NmW3N0YXJ0U2ZiXSkpKQogICAgICBzZmIrKzsKICAgIHN0b3BTZmIgPSBzZmI7CgogICAgaWYgKHN0b3BTZmIgPCBzZmJDbnQpCiAgICAgIHNjZk5leHQgPSBzY2Zbc3RvcFNmYl07CiAgICBlbHNlCiAgICAgIHNjZk5leHQgPSBzY2ZBY3Q7CgogICAgaWYgKHNjZlByZXYgPT0gRkRLX0lOVF9NSU4pCiAgICAgIHNjZlByZXYgPSBzY2ZBY3Q7CgogICAgc2NmUHJldk5leHRNYXggPSBmaXhNYXgoc2NmUHJldiwgc2NmTmV4dCk7CiAgICBzY2ZQcmV2TmV4dE1pbiA9IGZpeE1pbihzY2ZQcmV2LCBzY2ZOZXh0KTsKCiAgICAvKiB0cnkgdG8gcmVkdWNlIGJpdHMgYnkgY2hlY2tpbmcgc2NmIHZhbHVlcyBpbiB0aGUgcmFuZ2UKICAgICAgIHNjZltzdGFydFNmYl0uLi5zY2ZIaSAqLwogICAgc2NmSGkgPSBmaXhNYXgoc2NmUHJldk5leHRNYXgsIHNjZkFjdCk7CiAgICAvKiB0cnkgdG8gZmluZCBhIGJldHRlciBzb2x1dGlvbiBieSByZWR1Y2luZyB0aGUgc2NmIGRpZmZlcmVuY2UgdG8KICAgICAgIHRoZSBuZWFyZXN0IHBvc3NpYmxlIGxvd2VyIHNjZiAqLwogICAgaWYgKHNjZlByZXZOZXh0TWF4ID49IHNjZkFjdCkKICAgICAgc2NmTG8gPSBmaXhNaW4oc2NmQWN0LCBzY2ZQcmV2TmV4dE1pbik7CiAgICBlbHNlCiAgICAgIHNjZkxvID0gc2NmUHJldk5leHRNYXg7CgogICAgaWYgKHN0YXJ0U2ZiIDwgc2ZiQ250ICYmIHNjZkhpLXNjZkxvIDw9IE1BWF9TQ0ZfREVMVEEpIHsgLyogcmVnaW9uIGZvdW5kICovCiAgICAgIC8qIDEuIHRyeSB0byBzYXZlIGJpdHMgYnkgY29hcnNlciBxdWFudGl6YXRpb24gKi8KICAgICAgaWYgKHNjZkhpID4gc2NmW3N0YXJ0U2ZiXSkgewogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgYWxsb3dlZCBkaXN0b3J0aW9uICovCiAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgIC8qIHNmYkRpc3RNYXhbc2ZiXSA9IChmbG9hdClwb3cocWNPdXRDaGFubmVsLT5zZmJUaHJlc2hvbGRbc2ZiXSpzZmJEaXN0W3NmYl0qc2ZiRGlzdFtzZmJdLDEuMGYvMy4wZik7ICovCiAgICAgICAgICAgIC8qIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1heChzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lbc2ZiXSpGTDJGWENPTlNUX0RCTCgxLmUtM2YpKTsgKi8KICAgICAgICAgICAgLyogLTAuMTU1NzE1Mzc5NDQgPSBsZDY0KDEuZS0zZikqLwogICAgICAgICAgICBzZmJEaXN0TWF4W3NmYl0gPSBmTXVsdChGTDJGWENPTlNUX0RCTCgxLjBmLzMuMGYpLHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhW3NmYl0pK2ZNdWx0KEZMMkZYQ09OU1RfREJMKDEuMGYvMy4wZiksc2ZiRGlzdFtzZmJdKStmTXVsdChGTDJGWENPTlNUX0RCTCgxLjBmLzMuMGYpLHNmYkRpc3Rbc2ZiXSk7CiAgICAgICAgICAgIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1heChzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiXS1GTDJGWENPTlNUX0RCTCgwLjE1NTcxNTM3OTQ0KSk7CiAgICAgICAgICAgIHNmYkRpc3RNYXhbc2ZiXSA9IGZpeE1pbihzZmJEaXN0TWF4W3NmYl0scWNPdXRDaGFubmVsLT5zZmJUaHJlc2hvbGRMZERhdGFbc2ZiXSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBsb29wIG92ZXIgYWxsIHBvc3NpYmxlIHNjZiB2YWx1ZXMgZm9yIHRoaXMgcmVnaW9uICovCiAgICAgICAgYkNoZWNrU2NmID0gMTsKICAgICAgICBmb3IgKHNjZk5ldz1zY2Zbc3RhcnRTZmJdKzE7IHNjZk5ldzw9c2NmSGk7IHNjZk5ldysrKSB7CgkgICAgICAgICBmb3IgKGs9MDsgazxNQVhfR1JPVVBFRF9TRkI7IGsrKykKICAgICAgICAgICAgc2NmVG1wW2tdID0gc2NmW2tdOwoKICAgICAgICAgIC8qIHJlcGxhY2Ugc2NmcyBpbiByZWdpb24gYnkgc2NmTmV3ICovCiAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikKICAgICAgICAgICAgICBzY2ZUbXBbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBlc3RpbWF0ZSBjaGFuZ2UgaW4gYml0IGRlbWFuZCBmb3IgbmV3IHNjZnMgKi8KICAgICAgICAgIGRlbHRhU2NmQml0cyA9IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmKHNjZixzY2ZUbXAsc2ZiQ250LHN0YXJ0U2ZiLHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhU3BlY1BlID0gRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmKHBzeU91dENoYW4sIHFjT3V0Q2hhbm5lbCwgc2NmLCBzY2ZUbXAsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTZmIsIHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhUGVOZXcgPSBkZWx0YVBlICsgKEZJWFBfREJMKWRlbHRhU2NmQml0cyArIGRlbHRhU3BlY1BlOwoKICAgICAgICAgIC8qIG5ldyBiaXQgZGVtYW5kIHNtYWxsIGVub3VnaCA/ICovCiAgICAgICAgICBpZiAoZGVsdGFQZU5ldyA8IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CiAgICAgICAgICAgIGJTdWNjZXNzID0gMTsKCiAgICAgICAgICAgIC8qIHF1YW50aXplIGFuZCBjYWxjIHN1bSBvZiBuZXcgZGlzdG9ydGlvbiAqLwogICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgaWYgKHNjZlRtcFtzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICBzZmJEaXN0TmV3W3NmYl0gPSBGREthYWNFbmNfY2FsY1NmYkRpc3QocWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW0rc2ZiT2Zmc1tzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjVG1wK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYk9mZnNbc2ZiKzFdLXNmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZk5ldywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUpOwoKICAgICAgICAgICAgICAgIGlmIChzZmJEaXN0TmV3W3NmYl0gPiBzZmJEaXN0TWF4W3NmYl0pIHsKICAgICAgICAgICAgICAgICAgLyogbm8gaW1wcm92ZW1lbnQsIHNraXAgZnVydGhlciBkaXN0LiBjYWxjdWxhdGlvbnMgKi8KICAgICAgICAgICAgICAgICAgYlN1Y2Nlc3MgPSAwOwogICAgICAgICAgICAgICAgICBpZiAoc2ZiRGlzdE5ld1tzZmJdID09IHFjT3V0Q2hhbm5lbC0+c2ZiRW5lcmd5TGREYXRhW3NmYl0pIHsKICAgICAgICAgICAgICAgICAgICAvKiBpZiB3aG9sZSBzZmIgaXMgYWxyZWFkeSBxdWFudGl6ZWQgdG8gMCwgZnVydGhlcgogICAgICAgICAgICAgICAgICAgICAgIGNoZWNrcyB3aXRoIGV2ZW4gY29hcnNlciBxdWFudC4gYXJlIHVzZWxlc3MqLwogICAgICAgICAgICAgICAgICAgIGJDaGVja1NjZiA9IDA7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChiQ2hlY2tTY2Y9PTApIC8qIGZ1cnRoZXIgY2FsY3VsYXRpb25zIHVzZWxlc3MgPyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIC8qIGRpc3RvcnRpb24gc21hbGwgZW5vdWdoID8gLT4gdXNlIG5ldyBzY2FsZWZhY3RvcnMgKi8KICAgICAgICAgICAgaWYgKGJTdWNjZXNzKSB7CiAgICAgICAgICAgICAgZGVsdGFQZSA9IGRlbHRhUGVOZXc7CiAgICAgICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICAgIHNjZltzZmJdID0gc2NmTmV3OwogICAgICAgICAgICAgICAgICBzZmJEaXN0W3NmYl0gPSBzZmJEaXN0TmV3W3NmYl07CgogICAgICAgICAgICAgICAgICBmb3IgKGs9MDsgazxzZmJPZmZzW3NmYisxXS1zZmJPZmZzW3NmYl07IGsrKykKICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNbc2ZiT2Zmc1tzZmJdK2tdID0gcXVhbnRTcGVjVG1wW3NmYk9mZnNbc2ZiXStrXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIDIuIG9ubHkgaWYgY29hcnNlciBxdWFudGl6YXRpb24gd2FzIG5vdCBzdWNjZXNzZnVsLCB0cnkgdG8gZmluZAogICAgICAgICBhIGJldHRlciBzb2x1dGlvbiBieSBmaW5lciBxdWFudGl6YXRpb24gYW5kIHJlZHVjaW5nIGJpdHMgZm9yCiAgICAgICAgIHNjYWxlZmFjdG9yIGNvZGluZyAqLwogICAgICBpZiAoc2NmQWN0PT1zY2Zbc3RhcnRTZmJdICYmCiAgICAgICAgICBzY2ZMbyA8IHNjZkFjdCAmJgogICAgICAgICAgc2NmTWF4LXNjZk1pbiA8PSBNQVhfU0NGX0RFTFRBKSB7CgogICAgICAgIGludCBibWluU2NmVmlvbGF0aW9uID0gMDsKCiAgICAgICAgZm9yIChrPTA7IGs8TUFYX0dST1VQRURfU0ZCOyBrKyspCiAgICAgICAgICBzY2ZUbXBba10gPSBzY2Zba107CgogICAgICAgIHNjZk5ldyA9IHNjZkxvOwoKICAgICAgICAvKiByZXBsYWNlIHNjZnMgaW4gcmVnaW9uIGJ5IHNjZk5ldyBhbmQKICAgICAgICAgICBjaGVjayBpZiBpbiBhbGwgc2ZiIHNjZk5ldyA+PSBtaW5TY2Zbc2ZiXSAqLwogICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICBzY2ZUbXBbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgICAgaWYgKHNjZk5ldyA8IG1pblNjZltzZmJdKQogICAgICAgICAgICAgIGJtaW5TY2ZWaW9sYXRpb24gPSAxOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFibWluU2NmVmlvbGF0aW9uKSB7CiAgICAgICAgICAvKiBlc3RpbWF0ZSBjaGFuZ2UgaW4gYml0IGRlbWFuZCBmb3IgbmV3IHNjZnMgKi8KICAgICAgICAgIGRlbHRhU2NmQml0cyA9IEZES2FhY0VuY19jb3VudFNjZkJpdHNEaWZmKHNjZixzY2ZUbXAsc2ZiQ250LHN0YXJ0U2ZiLHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhU3BlY1BlID0gRkRLYWFjRW5jX2NhbGNTcGVjUGVEaWZmKHBzeU91dENoYW4sIHFjT3V0Q2hhbm5lbCwgc2NmLCBzY2ZUbXAsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTZmIsIHN0b3BTZmIpOwoKICAgICAgICAgIGRlbHRhUGVOZXcgPSBkZWx0YVBlICsgKEZJWFBfREJMKWRlbHRhU2NmQml0cyArIGRlbHRhU3BlY1BlOwogICAgICAgIH0KCiAgICAgICAgLyogbmV3IGJpdCBkZW1hbmQgc21hbGwgZW5vdWdoID8gKi8KICAgICAgICBpZiAoIWJtaW5TY2ZWaW9sYXRpb24gJiYgZGVsdGFQZU5ldyA8IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CgogICAgICAgICAgLyogcXVhbnRpemUgYW5kIGNhbGMgc3VtIG9mIG5ldyBkaXN0b3J0aW9uICovCiAgICAgICAgICBkaXN0T2xkU3VtID0gZGlzdE5ld1N1bSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICBpZiAoc2NmVG1wW3NmYl0gIT0gRkRLX0lOVF9NSU4pIHsKICAgICAgICAgICAgICBkaXN0T2xkU3VtICs9IENhbGNJbnZMZERhdGEoc2ZiRGlzdFtzZmJdKSA+PiBESVNUX0ZBQ19TSElGVDsKCiAgICAgICAgICAgICAgc2ZiRGlzdE5ld1tzZmJdID0gRkRLYWFjRW5jX2NhbGNTZmJEaXN0KHFjT3V0Q2hhbm5lbC0+bWRjdFNwZWN0cnVtK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjVG1wK3NmYk9mZnNbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiT2Zmc1tzZmIrMV0tc2ZiT2Zmc1tzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2ZOZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUpOwoKICAgICAgICAgICAgICBpZiAoc2ZiRGlzdE5ld1tzZmJdID4gcWNPdXRDaGFubmVsLT5zZmJUaHJlc2hvbGRMZERhdGFbc2ZiXSkgewogICAgICAgICAgICAgICAgLyogbm8gaW1wcm92ZW1lbnQsIHNraXAgZnVydGhlciBkaXN0LiBjYWxjdWxhdGlvbnMgKi8KICAgICAgICAgICAgICAgIGRpc3ROZXdTdW0gPSBkaXN0T2xkU3VtIDw8IDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZGlzdE5ld1N1bSArPSBDYWxjSW52TGREYXRhKHNmYkRpc3ROZXdbc2ZiXSkgPj4gRElTVF9GQUNfU0hJRlQ7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8qIGRpc3RvcnRpb24gc21hbGxlciA/IC0+IHVzZSBuZXcgc2NhbGVmYWN0b3JzICovCiAgICAgICAgICBpZiAoZGlzdE5ld1N1bSA8IGZNdWx0KEZMMkZYQ09OU1RfREJMKDAuOGYpLGRpc3RPbGRTdW0pKSB7CiAgICAgICAgICAgIGRlbHRhUGUgPSBkZWx0YVBlTmV3OwogICAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgICAgaWYgKHNjZltzZmJdICE9IEZES19JTlRfTUlOKSB7CiAgICAgICAgICAgICAgICBzY2Zbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgICAgICAgIHNmYkRpc3Rbc2ZiXSA9IHNmYkRpc3ROZXdbc2ZiXTsKCiAgICAgICAgICAgICAgICBmb3IgKGs9MDsgazxzZmJPZmZzW3NmYisxXS1zZmJPZmZzW3NmYl07IGsrKykKICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjW3NmYk9mZnNbc2ZiXStrXSA9IHF1YW50U3BlY1RtcFtzZmJPZmZzW3NmYl0ra107CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICAvKiAzLiB0cnkgdG8gZmluZCBhIGJldHRlciBzb2x1dGlvbiAoc2F2ZSBiaXRzKSBieSBvbmx5IHJlZHVjaW5nIHRoZQogICAgICAgICBzY2FsZWZhY3RvciB3aXRob3V0IG5ldyBxdWFudGl6YXRpb24gKi8KICAgICAgaWYgKHNjZk1heC1zY2ZNaW4gPD0gTUFYX1NDRl9ERUxUQS0zKSB7IC8qIDMgYmVjLiBzY2YgaXMgcmVkdWNlZCAzIHRpbWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlIGZvciBsb29wIGJlbG93ICovCgogICAgICAgIGZvciAoaz0wOyBrPHNmYkNudDsgaysrKQogICAgICAgICAgc2NmVG1wW2tdID0gc2NmW2tdOwoKICAgICAgICBmb3IgKGk9MDsgaTwzOyBpKyspIHsKICAgICAgICAgIHNjZk5ldyA9IHNjZlRtcFtzdGFydFNmYl0tMTsKICAgICAgICAgIC8qIHJlcGxhY2Ugc2NmcyBpbiByZWdpb24gYnkgc2NmTmV3ICovCiAgICAgICAgICBmb3IgKHNmYj1zdGFydFNmYjsgc2ZiPHN0b3BTZmI7IHNmYisrKSB7CiAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikKICAgICAgICAgICAgICBzY2ZUbXBbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgIH0KICAgICAgICAgIC8qIGVzdGltYXRlIGNoYW5nZSBpbiBiaXQgZGVtYW5kIGZvciBuZXcgc2NmcyAqLwogICAgICAgICAgZGVsdGFTY2ZCaXRzID0gRkRLYWFjRW5jX2NvdW50U2NmQml0c0RpZmYoc2NmLHNjZlRtcCxzZmJDbnQsc3RhcnRTZmIsc3RvcFNmYik7CiAgICAgICAgICBkZWx0YVBlTmV3ID0gZGVsdGFQZSArIChGSVhQX0RCTClkZWx0YVNjZkJpdHM7CiAgICAgICAgICAvKiBuZXcgYml0IGRlbWFuZCBzbWFsbCBlbm91Z2ggPyAqLwogICAgICAgICAgaWYgKGRlbHRhUGVOZXcgPD0gRkwyRlhDT05TVF9EQkwoMC4wZikpIHsKCiAgICAgICAgICAgIGJTdWNjZXNzID0gMTsKICAgICAgICAgICAgZGlzdE9sZFN1bSA9IGRpc3ROZXdTdW0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICAgICAgZm9yIChzZmI9c3RhcnRTZmI7IHNmYjxzdG9wU2ZiOyBzZmIrKykgewogICAgICAgICAgICAgIGlmIChzY2ZUbXBbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgICAgRklYUF9EQkwgc2ZiRW5ROwogICAgICAgICAgICAgICAgLyogY2FsYyB0aGUgZW5lcmd5IGFuZCBkaXN0b3J0aW9uIG9mIHRoZSBxdWFudGl6ZWQgc3BlY3RydW0gZm9yCiAgICAgICAgICAgICAgICAgICBhIHNtYWxsZXIgc2NmICovCiAgICAgICAgICAgICAgICBGREthYWNFbmNfY2FsY1NmYlF1YW50RW5lcmd5QW5kRGlzdChxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bStzZmJPZmZzW3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1YW50U3BlYytzZmJPZmZzW3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYk9mZnNbc2ZiKzFdLXNmYk9mZnNbc2ZiXSwgc2NmTmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2ZiRW5RLCAmc2ZiRGlzdE5ld1tzZmJdKTsKCiAgICAgICAgICAgICAgICBkaXN0T2xkU3VtICs9IENhbGNJbnZMZERhdGEoc2ZiRGlzdFtzZmJdKSA+PiBESVNUX0ZBQ19TSElGVDsKICAgICAgICAgICAgICAgIGRpc3ROZXdTdW0gKz0gQ2FsY0ludkxkRGF0YShzZmJEaXN0TmV3W3NmYl0pID4+IERJU1RfRkFDX1NISUZUOwoKICAgICAgICAgICAgICAgIC8qICAwLjAwMjU5NDg4NTU2MTY3ID0gbGQ2NCgxLjEyMmYpICovCiAgICAgICAgICAgICAgICAvKiAtMC4wMDc3ODcyMjY4NjY1MiA9IGxkNjQoMC43MDc5ZikgKi8KICAgICAgICAgICAgICAgIGlmICgoc2ZiRGlzdE5ld1tzZmJdID4gKHNmYkRpc3Rbc2ZiXStGTDJGWENPTlNUX0RCTCgwLjAwMjU5NDg4NTU2MTY3ZikpKSB8fCAoc2ZiRW5RIDwgKHFjT3V0Q2hhbm5lbC0+c2ZiRW5lcmd5TGREYXRhW3NmYl0gLSBGTDJGWENPTlNUX0RCTCgwLjAwNzc4NzIyNjg2NjUyZikpKSl7CiAgICAgICAgICAgICAgICAgIGJTdWNjZXNzID0gMDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGRpc3RvcnRpb24gc21hbGxlciA/IC0+IHVzZSBuZXcgc2NhbGVmYWN0b3JzICovCiAgICAgICAgICAgIGlmIChkaXN0TmV3U3VtIDwgZGlzdE9sZFN1bSAmJiBiU3VjY2VzcykgewogICAgICAgICAgICAgIGRlbHRhUGUgPSBkZWx0YVBlTmV3OwogICAgICAgICAgICAgIGZvciAoc2ZiPXN0YXJ0U2ZiOyBzZmI8c3RvcFNmYjsgc2ZiKyspIHsKICAgICAgICAgICAgICAgIGlmIChzY2Zbc2ZiXSAhPSBGREtfSU5UX01JTikgewogICAgICAgICAgICAgICAgICBzY2Zbc2ZiXSA9IHNjZk5ldzsKICAgICAgICAgICAgICAgICAgc2ZiRGlzdFtzZmJdID0gc2ZiRGlzdE5ld1tzZmJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gd2hpbGUgKHN0b3BTZmIgPD0gc2ZiQ250KTsKCn0KCnN0YXRpYyB2b2lkCkZES2FhY0VuY19GREthYWNFbmNfRXN0aW1hdGVTY2FsZUZhY3RvcnNDaGFubmVsKFFDX09VVF9DSEFOTkVMICAgKnFjT3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfQ0hBTk5FTCAgKnBzeU91dENoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKlJFU1RSSUNUIHNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAqUkVTVFJJQ1QgZ2xvYmFsR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBzZmJGb3JtRmFjdG9yTGREYXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsY29uc3QgSU5UIGludlF1YW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hPUlQgKlJFU1RSSUNUIHF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBkWm9uZVF1YW50RW5hYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBJTlQgaSwgaiwgc2ZiLCBzZmJPZmZzOwogIElOVCBzY2ZJbnQ7CiAgSU5UIG1heFNmOwogIElOVCBtaW5TZjsKICBGSVhQX0RCTCB0aHJlc2hMZERhdGE7CiAgRklYUF9EQkwgZW5lcmd5TGREYXRhOwogIEZJWFBfREJMIGVuZXJneVBhcnRMZERhdGE7CiAgRklYUF9EQkwgdGhyZXNob2xkUGFydExkRGF0YTsKICBGSVhQX0RCTCBzY2ZGcmFjdDsKICBGSVhQX0RCTCBtYXhTcGVjOwogIEZJWFBfREJMIGFic1NwZWM7CiAgSU5UIG1pblNjZkNhbGN1bGF0ZWRbTUFYX0dST1VQRURfU0ZCXTsKICBGSVhQX0RCTCBzZmJEaXN0TGREYXRhW01BWF9HUk9VUEVEX1NGQl07CiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHF1YW50U3BlY1RtcCwgU0hPUlQsICgxMDI0KSk7CiAgSU5UIG1pblNmTWF4UXVhbnRbTUFYX0dST1VQRURfU0ZCXTsKCiAgRklYUF9EQkwgdGhyZXNoQ29uc3RMZERhdGE9RkwyRlhDT05TVF9EQkwoMC4wNDMwNDUxMTcyMmYpOyAvKiBsb2cxMCg2Ljc1KS9sb2cxMCgyLjApLzY0LjAgKi8KICBGSVhQX0RCTCBjb252Q29uc3Q9RkwyRlhDT05TVF9EQkwoMC4zMDEwMjk5OTU2NmYpOyAvKiBsb2cxMCgyLjApICovCiAgRklYUF9EQkwgYzFDb25zdD1GTDJGWENPTlNUX0RCTCgtMC4yNzA4MzE4MzU5NGYpOyAvKiBDMSA9IC02OS4zMzI5NSA9PiBDMS8yXjggKi8KCgoKICBpZiAoaW52UXVhbnQ+MCkgewogICAgRkRLbWVtY2xlYXIocXVhbnRTcGVjLCAoMTAyNCkqc2l6ZW9mKFNIT1JUKSk7CiAgfQoKICAvKiBzY2ZzIHdpdGhvdXQgZW5lcmd5IG9yIHdpdGggdGhyZXNoPmVuZXJneSBhcmUgbWFya2VkIHdpdGggRkRLX0lOVF9NSU4gKi8KICBmb3IoaT0wOyBpPHBzeU91dENoYW5uZWwtPnNmYkNudDsgaSsrKSB7CiAgICBzY2ZbaV0gPSBGREtfSU5UX01JTjsKICB9CgogIGZvciAoaT0wOyBpPE1BWF9HUk9VUEVEX1NGQjsgaSsrKSB7CiAgICBtaW5TZk1heFF1YW50W2ldID0gRkRLX0lOVF9NSU47CiAgfQoKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICBmb3Ioc2ZiPTA7IHNmYjxwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKCiAgICAgIHRocmVzaExkRGF0YSA9IHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhW3NmYk9mZnMrc2ZiXTsKICAgICAgZW5lcmd5TGREYXRhID0gcWNPdXRDaGFubmVsLT5zZmJFbmVyZ3lMZERhdGFbc2ZiT2ZmcytzZmJdOwoKICAgICAgc2ZiRGlzdExkRGF0YVtzZmJPZmZzK3NmYl0gPSBlbmVyZ3lMZERhdGE7CgoKICAgICAgaWYgKGVuZXJneUxkRGF0YSA+IHRocmVzaExkRGF0YSkgewogICAgICAgIEZJWFBfREJMIHRtcDsKCiAgICAgICAgLyogZW5lcmd5UGFydCA9IChmbG9hdClsb2cxMChzZmJGb3JtRmFjdG9yW3NmYk9mZnMrc2ZiXSk7ICovCiAgICAgICAgLyogMC4wOTM3NWYgPSBsb2coNjQuMCkvbG9nKDIuMCkvNjQuMCA9IHNjYWxlIG9mIHNmYkZvcm1GYWN0b3JMZERhdGEgKi8KICAgICAgICBlbmVyZ3lQYXJ0TGREYXRhID0gc2ZiRm9ybUZhY3RvckxkRGF0YVtzZmJPZmZzK3NmYl0gKyBGTDJGWENPTlNUX0RCTCgwLjA5Mzc1Zik7CgogICAgICAgIC8qIGluZmx1ZW5jZSBvZiBhbGxvd2VkIGRpc3RvcnRpb24gKi8KICAgICAgICAvKiB0aHJlc2hvbGRQYXJ0ID0gKGZsb2F0KWxvZzEwKDYuNzUqdGhyZXNoK0ZMVF9NSU4pOyAqLwogICAgICAgIHRocmVzaG9sZFBhcnRMZERhdGEgPSB0aHJlc2hDb25zdExkRGF0YSArIHRocmVzaExkRGF0YTsKCiAgICAgICAgLyogc2NmIGNhbGMgKi8KICAgICAgICAvKiBzY2ZGbG9hdCA9IDguODU4NWYgKiAodGhyZXNob2xkUGFydCAtIGVuZXJneVBhcnQpOyAqLwogICAgICAgIHNjZkZyYWN0ID0gdGhyZXNob2xkUGFydExkRGF0YSAtIGVuZXJneVBhcnRMZERhdGE7CiAgICAgICAgLyogY29udmVyc2lvbiBmcm9tIGxvZzIgdG8gbG9nMTAgKi8KICAgICAgICBzY2ZGcmFjdCA9IGZNdWx0KGNvbnZDb25zdCxzY2ZGcmFjdCk7CiAgICAgICAgLyogKDguODU4NWYgKiBzY2ZGcmFjdCkvOCA9IDgvOCAqIHNjZkZyYWN0ICsgMC44NTg1ICogc2NmRnJhY3QvOCAqLwogICAgICAgIHNjZkZyYWN0ID0gc2NmRnJhY3QgKyBmTXVsdChGTDJGWENPTlNUX0RCTCgwLjg1ODVmKSxzY2ZGcmFjdCA+PiAzKTsKCiAgICAgICAgLyogaW50ZWdlciBzY2FsZWZhY3RvciAqLwogICAgICAgIC8qIHNjZkludCA9IChpbnQpZmxvb3Ioc2NmRmxvYXQpOyAqLwogICAgICAgIHNjZkludCA9IChJTlQpKHNjZkZyYWN0Pj4oKERGUkFDVF9CSVRTLTEpLTMtTERfREFUQV9TSElGVCkpOyAvKiAzIGJpdHMgPT4gc2NmRnJhY3QvOC4wOyA2IGJpdHMgPT4gbGQ2NCAqLwoKICAgICAgICAvKiBtYXhpbXVtIG9mIHNwZWN0cnVtICovCiAgICAgICAgbWF4U3BlYyA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwoKICAgICAgICBmb3Ioaj1wc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXTsgajxwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiKzFdOyBqKysgKXsKICAgICAgICAgIGFic1NwZWMgPSBmaXhwX2FicyhxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bVtqXSk7CiAgICAgICAgICBtYXhTcGVjID0gKGFic1NwZWMgPiBtYXhTcGVjKSA/IGFic1NwZWMgOiBtYXhTcGVjOwogICAgICAgIH0KCiAgICAgICAgLyogbG93ZXIgc2NmIGxpbWl0IHRvIGF2b2lkIHF1YW50aXplZCB2YWx1ZXMgYmlnZ2VyIHRoYW4gTUFYX1FVQU5UICovCiAgICAgICAgLyogQzEgPSAtNjkuMzMyOTVmLCBDMiA9IDUuNzcwNzhmID0gNC9sb2coMikgKi8KICAgICAgICAvKiBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9IChpbnQpY2VpbChDMSArIEMyKmxvZyhtYXhTcGVjKSk7ICovCiAgICAgICAgLyogQzEvMl44ICsgNC9sb2coMi4wKSpsb2cobWF4U3BlYykvMl44ICA9PiBDMS8yXjggKyBsb2cobWF4U3BlYykvbG9nKDIuMCkqNC8yXjggPT4gQzEvMl44ICsgbG9nKG1heFNwZWMpL2xvZygyLjApLzY0LjAgKi8KCiAgICAgICAgLy9taW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9ICgoSU5UKSAoKGMxQ29uc3QgKyBDYWxjTGREYXRhKG1heFNwZWMpKSA+PiAoKERGUkFDVF9CSVRTLTEpLTgpKSkgKyAxOwogICAgICAgIHRtcCA9IENhbGNMZERhdGEobWF4U3BlYyk7CiAgICAgICAgaWYgKGMxQ29uc3Q+RkwyRlhDT05TVF9EQkwoLTEuZiktdG1wKSB7CiAgICAgICAgICBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSA9ICgoSU5UKSAoKGMxQ29uc3QgKyB0bXApID4+ICgoREZSQUNUX0JJVFMtMSktOCkpKSArIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgbWluU2ZNYXhRdWFudFtzZmJPZmZzK3NmYl0gPSAoKElOVCkgKEZMMkZYQ09OU1RfREJMKC0xLmYpID4+ICgoREZSQUNUX0JJVFMtMSktOCkpKSArIDE7CiAgICAgICAgfQoKICAgICAgICBzY2ZJbnQgPSBmaXhNYXgoc2NmSW50LCBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSk7CgoKICAgICAgICAvKiBmaW5kIGJldHRlciBzY2FsZWZhY3RvciB3aXRoIGFuYWx5c2lzIGJ5IHN5bnRoZXNpcyAqLwogICAgICAgIGlmIChpbnZRdWFudD4wKSB7CiAgICAgICAgICBzY2ZJbnQgPSBGREthYWNFbmNfaW1wcm92ZVNjZihxY091dENoYW5uZWwtPm1kY3RTcGVjdHJ1bStwc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjK3BzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWFudFNwZWNUbXArcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmIrMV0tcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVzaExkRGF0YSwgc2NmSW50LCBtaW5TZk1heFF1YW50W3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNmYkRpc3RMZERhdGFbc2ZiT2ZmcytzZmJdLCAmbWluU2NmQ2FsY3VsYXRlZFtzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgc2NmW3NmYk9mZnMrc2ZiXSA9IHNjZkludDsKICAgICAgfQogICAgfQogIH0KCgogIGlmIChpbnZRdWFudD4xKSB7CiAgICAvKiB0cnkgdG8gZGVjcmVhc2Ugc2NmIGRpZmZlcmVuY2VzICovCiAgICBGSVhQX0RCTCBzZmJDb25zdFBlUGFydFtNQVhfR1JPVVBFRF9TRkJdOwogICAgRklYUF9EQkwgc2ZiTlJlbGV2YW50TGluZXNbTUFYX0dST1VQRURfU0ZCXTsKCiAgICBmb3IgKGk9MDsgaTxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IGkrKykKICAgICAgc2ZiQ29uc3RQZVBhcnRbaV0gPSAoRklYUF9EQkwpRkRLX0lOVF9NSU47CgogICAgRkRLYWFjRW5jX2NhbGNTZmJSZWxldmFudExpbmVzKCBzZmJGb3JtRmFjdG9yTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbC0+c2ZiRW5lcmd5TGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbC0+c2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbC0+c2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwtPm1heFNmYlBlckdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNmYk5SZWxldmFudExpbmVzKTsKCgogICAgRkRLYWFjRW5jX2Fzc2ltaWxhdGVTaW5nbGVTY2YocHN5T3V0Q2hhbm5lbCwgcWNPdXRDaGFubmVsLCBxdWFudFNwZWMsIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgZFpvbmVRdWFudEVuYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgc2NmLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5TZk1heFF1YW50LCBzZmJEaXN0TGREYXRhLCBzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRm9ybUZhY3RvckxkRGF0YSwgc2ZiTlJlbGV2YW50TGluZXMsIG1pblNjZkNhbGN1bGF0ZWQsIDEpOwoKICAgIGlmKGludlF1YW50ID4gMSkgewogICAgICBGREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmKHBzeU91dENoYW5uZWwsIHFjT3V0Q2hhbm5lbCwgcXVhbnRTcGVjLCBxdWFudFNwZWNUbXAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHNjZiwKICAgICAgICAgICAgICAgICAgICAgICAgbWluU2ZNYXhRdWFudCwgc2ZiRGlzdExkRGF0YSwgc2ZiQ29uc3RQZVBhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNmYkZvcm1GYWN0b3JMZERhdGEsIHNmYk5SZWxldmFudExpbmVzKTsKCiAgICAgIEZES2FhY0VuY19hc3NpbWlsYXRlTXVsdGlwbGVTY2YocHN5T3V0Q2hhbm5lbCwgcWNPdXRDaGFubmVsLCBxdWFudFNwZWMsIHF1YW50U3BlY1RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgZFpvbmVRdWFudEVuYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgc2NmLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5TZk1heFF1YW50LCBzZmJEaXN0TGREYXRhLCBzZmJDb25zdFBlUGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRm9ybUZhY3RvckxkRGF0YSwgc2ZiTlJlbGV2YW50TGluZXMpOwoKCiAgICAgIEZES2FhY0VuY19GREthYWNFbmNfYXNzaW1pbGF0ZU11bHRpcGxlU2NmMihwc3lPdXRDaGFubmVsLCBxY091dENoYW5uZWwsIHF1YW50U3BlYywgcXVhbnRTcGVjVG1wLAogICAgICAgICAgICAgICAgICAgICAgICBkWm9uZVF1YW50RW5hYmxlLAogICAgICAgICAgICAgICAgICAgICAgICBzY2YsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblNmTWF4UXVhbnQsIHNmYkRpc3RMZERhdGEsIHNmYkNvbnN0UGVQYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICBzZmJGb3JtRmFjdG9yTGREYXRhLCBzZmJOUmVsZXZhbnRMaW5lcyk7CiAgICB9CiAgfQoKCiAgLyogZ2V0IG1pbiBzY2FsZWZhYyAqLwogIG1pblNmID0gRkRLX0lOVF9NQVg7CiAgZm9yIChzZmJPZmZzPTA7IHNmYk9mZnM8cHN5T3V0Q2hhbm5lbC0+c2ZiQ250OyBzZmJPZmZzKz1wc3lPdXRDaGFubmVsLT5zZmJQZXJHcm91cCkgewogICAgZm9yIChzZmIgPSAwOyBzZmIgPCBwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgaWYgKHNjZltzZmJPZmZzK3NmYl0hPUZES19JTlRfTUlOKQogICAgICAgIG1pblNmID0gZml4TWluKG1pblNmLHNjZltzZmJPZmZzK3NmYl0pOwogICAgfQogIH0KCiAgLyogbGltaXQgc2NmIGRlbHRhICovCiAgZm9yIChzZmJPZmZzPTA7IHNmYk9mZnM8cHN5T3V0Q2hhbm5lbC0+c2ZiQ250OyBzZmJPZmZzKz1wc3lPdXRDaGFubmVsLT5zZmJQZXJHcm91cCkgewogICAgZm9yIChzZmIgPSAwOyBzZmIgPCBwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgaWYgKChzY2Zbc2ZiT2ZmcytzZmJdICE9IEZES19JTlRfTUlOKSAmJiAobWluU2YrTUFYX1NDRl9ERUxUQSkgPCBzY2Zbc2ZiT2ZmcytzZmJdKSB7CiAgICAgICAgc2NmW3NmYk9mZnMrc2ZiXSA9IG1pblNmICsgTUFYX1NDRl9ERUxUQTsKICAgICAgICBpZiAoaW52UXVhbnQgPiAwKSB7IC8qIGNoYW5nZWQgYmFuZHMgbmVlZCB0byBiZSBxdWFudGl6ZWQgYWdhaW4gKi8KICAgICAgICAgIHNmYkRpc3RMZERhdGFbc2ZiT2ZmcytzZmJdID0KICAgICAgICAgICAgICAgRkRLYWFjRW5jX2NhbGNTZmJEaXN0KHFjT3V0Q2hhbm5lbC0+bWRjdFNwZWN0cnVtK3BzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRTcGVjK3BzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYisxXS1wc3lPdXRDaGFubmVsLT5zZmJPZmZzZXRzW3NmYk9mZnMrc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjZltzZmJPZmZzK3NmYl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWm9uZVF1YW50RW5hYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCgogIC8qIGdldCBtYXggc2NhbGVmYWMgZm9yIGdsb2JhbCBnYWluICovCiAgbWF4U2YgPSBGREtfSU5UX01JTjsKICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IHBzeU91dENoYW5uZWwtPm1heFNmYlBlckdyb3VwOyBzZmIrKykgewogICAgICBtYXhTZiA9IGZpeE1heChtYXhTZixzY2Zbc2ZiT2ZmcytzZmJdKTsKICAgIH0KICB9CgogIC8qIGNhbGMgbG9vcCBzY2FsZWZhY3RvcnMsIGlmIHNwZWMgaXMgbm90IGFsbCB6ZXJvIChpLmUuIG1heFNmID09IC05OSkgKi8KICBpZiggbWF4U2YgPiBGREtfSU5UX01JTiApIHsKICAgICpnbG9iYWxHYWluID0gbWF4U2Y7CiAgICBmb3IgKHNmYk9mZnM9MDsgc2ZiT2Zmczxwc3lPdXRDaGFubmVsLT5zZmJDbnQ7IHNmYk9mZnMrPXBzeU91dENoYW5uZWwtPnNmYlBlckdyb3VwKSB7CiAgICAgIGZvciAoc2ZiID0gMDsgc2ZiIDwgcHN5T3V0Q2hhbm5lbC0+bWF4U2ZiUGVyR3JvdXA7IHNmYisrKSB7CiAgICAgICAgaWYoIHNjZltzZmJPZmZzK3NmYl0gPT0gRkRLX0lOVF9NSU4gKSB7CiAgICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gMDsKICAgICAgICAgIC8qIHNldCBiYW5kIGV4cGxpY2l0ZWx5IHRvIHplcm8gKi8KICAgICAgICAgIGZvcihqPXBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmJdOyBqPHBzeU91dENoYW5uZWwtPnNmYk9mZnNldHNbc2ZiT2ZmcytzZmIrMV07IGorKyApIHsKICAgICAgICAgICAgcWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW1bal0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gbWF4U2YgLSBzY2Zbc2ZiT2ZmcytzZmJdOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICBlbHNlewogICAgKmdsb2JhbEdhaW4gPSAwOwogICAgLyogc2V0IHNwZWN0cnVtIGV4cGxpY2l0ZWx5IHRvIHplcm8gKi8KICAgIGZvciAoc2ZiT2Zmcz0wOyBzZmJPZmZzPHBzeU91dENoYW5uZWwtPnNmYkNudDsgc2ZiT2Zmcys9cHN5T3V0Q2hhbm5lbC0+c2ZiUGVyR3JvdXApIHsKICAgICAgZm9yIChzZmIgPSAwOyBzZmIgPCBwc3lPdXRDaGFubmVsLT5tYXhTZmJQZXJHcm91cDsgc2ZiKyspIHsKICAgICAgICBzY2Zbc2ZiT2ZmcytzZmJdID0gMDsKICAgICAgICAvKiBzZXQgYmFuZCBleHBsaWNpdGVseSB0byB6ZXJvICovCiAgICAgICAgZm9yKGo9cHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYl07IGo8cHN5T3V0Q2hhbm5lbC0+c2ZiT2Zmc2V0c1tzZmJPZmZzK3NmYisxXTsgaisrICkgewogICAgICAgICAgcWNPdXRDaGFubmVsLT5tZGN0U3BlY3RydW1bal0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIGZyZWUgcXVhbnRTcGVjVG1wIGZyb20gc2NyYXRjaCAqLwogIENfQUxMT0NfU0NSQVRDSF9FTkQocXVhbnRTcGVjVG1wLCBTSE9SVCwgKDEwMjQpKTsKCgp9Cgp2b2lkCkZES2FhY0VuY19Fc3RpbWF0ZVNjYWxlRmFjdG9ycyhQU1lfT1VUX0NIQU5ORUwgKnBzeU91dENoYW5uZWxbXSwKICAgICAgICAgICAgICAgICAgICAgUUNfT1VUX0NIQU5ORUwqIHFjT3V0Q2hhbm5lbFtdLAogICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgaW52UXVhbnQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCBkWm9uZVF1YW50RW5hYmxlLAogICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgbkNoYW5uZWxzKQp7CiAgaW50IGNoOwoKICBmb3IgKGNoID0gMDsgY2ggPCBuQ2hhbm5lbHM7IGNoKyspCiAgewogICAgICBGREthYWNFbmNfRkRLYWFjRW5jX0VzdGltYXRlU2NhbGVGYWN0b3JzQ2hhbm5lbChxY091dENoYW5uZWxbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxY091dENoYW5uZWxbY2hdLT5zY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXRDaGFubmVsW2NoXS0+Z2xvYmFsR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbFtjaF0tPnNmYkZvcm1GYWN0b3JMZERhdGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxpbnZRdWFudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbFtjaF0tPnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRab25lUXVhbnRFbmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgfQoKfQoK