Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgogLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIE1QRUcgQXVkaW8gRW5jb2RlciAqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgSW5pdGlhbCBhdXRob3I6ICAgICAgIE0uIFdlcm5lcgogICBjb250ZW50cy9kZXNjcmlwdGlvbjogQml0c3RyZWFtIGVuY29kZXIKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJiaXRlbmMuaCIKI2luY2x1ZGUgImJpdF9jbnQuaCIKI2luY2x1ZGUgImR5bl9iaXRzLmgiCiNpbmNsdWRlICJxY19kYXRhLmgiCiNpbmNsdWRlICJpbnRlcmZhY2UuaCIKI2luY2x1ZGUgImFhY0VuY19yYW0uaCIKCgojaW5jbHVkZSAidHBlbmNfbGliLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIiAgLyogbmVlZGVkIGZvciB0aGUgYml0c3RyZWFtIHN5bnRheCB0YWJsZXMgKi8KCnN0YXRpYyBjb25zdCBpbnQgZ2xvYmFsR2Fpbk9mZnNldCA9IDEwMDsKc3RhdGljIGNvbnN0IGludCBpY3NSZXNlcnZlZEJpdCAgID0gMDsKc3RhdGljIGNvbnN0IGludCBub2lzZU9mZnNldCAgICAgID0gOTA7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19lbmNvZGVTcGVjdHJhbERhdGEKICAgIGRlc2NyaXB0aW9uOiAgZW5jb2RlIHNwZWN0cmFsIGRhdGEKICAgIHJldHVybnM6ICAgICAgdGhlIG51bWJlciBvZiB3cml0dGVuIGJpdHMKICAgIGlucHV0OgogICAgb3V0cHV0OgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBJTlQgRkRLYWFjRW5jX2VuY29kZVNwZWN0cmFsRGF0YShJTlQgICAgICAgICAgICAgICAgICAgICpzZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRUNUSU9OX0RBVEEgICAgICAgICAgICpzZWN0aW9uRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNIT1JUICAgICAgICAgICAgICAgICAgKnF1YW50U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgICBoQml0U3RyZWFtKQp7CiAgSU5UIGksc2ZiOwogIElOVCBkYmdWYWwgPSBGREtnZXRWYWxpZEJpdHMoaEJpdFN0cmVhbSk7CgogIGZvcihpPTA7aTxzZWN0aW9uRGF0YS0+bm9PZlNlY3Rpb25zO2krKykKICB7CiAgICBpZihzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgIT0gQ09ERV9CT09LX1BOU19OTykKICAgIHsKICAgICAgLyogaHVmZmVuY29kZSBzcGVjdHJhbCBkYXRhIGZvciB0aGlzIGh1ZmZzZWN0aW9uICovCiAgICAgIElOVCB0bXAgPSBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiU3RhcnQrc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYkNudDsKICAgICAgZm9yKHNmYj1zZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiU3RhcnQ7IHNmYjx0bXA7IHNmYisrKQogICAgICB7CiAgICAgICAgRkRLYWFjRW5jX2NvZGVWYWx1ZXMocXVhbnRTcGVjdHJ1bStzZmJPZmZzZXRbc2ZiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJPZmZzZXRbc2ZiKzFdLXNmYk9mZnNldFtzZmJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5jb2RlQm9vaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQml0U3RyZWFtKTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4oRkRLZ2V0VmFsaWRCaXRzKGhCaXRTdHJlYW0pLWRiZ1ZhbCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfZW5jb2RlR2xvYmFsR2FpbgogICAgZGVzY3JpcHRpb246IGVuY29kZXMgR2xvYmFsIEdhaW4gKGNvbW1vbiBzY2FsZSBmYWN0b3IpCiAgICByZXR1cm5zOiAgICAgdGhlIG51bWJlciBvZiBzdGF0aWMgYml0cwogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlR2xvYmFsR2FpbihJTlQgZ2xvYmFsR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2NhbGVmYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJpdFN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbWRjdFNjYWxlKQp7CiAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sZ2xvYmFsR2FpbiAtIHNjYWxlZmFjICsgZ2xvYmFsR2Fpbk9mZnNldC00KihMT0dfTk9STV9QQ00tbWRjdFNjYWxlKSw4KTsKICB9CiAgcmV0dXJuICg4KTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfZW5jb2RlSWNzSW5mbwogICAgZGVzY3JpcHRpb246IGVuY29kZXMgSWNzIEluZm8KICAgIHJldHVybnM6ICAgICB0aGUgbnVtYmVyIG9mIHN0YXRpYyBiaXRzCiAgICBpbnB1dDoKICAgIG91dHB1dDoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlSWNzSW5mbyhJTlQgYmxvY2tUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCB3aW5kb3dTaGFwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZ3JvdXBpbmdNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBtYXhTZmJQZXJHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgaEJpdFN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHN5bnRheEZsYWdzKQp7CiAgSU5UIHN0YXRCaXRzOwoKICBpZiAoYmxvY2tUeXBlID09IFNIT1JUX1dJTkRPVykgewogICAgc3RhdEJpdHMgPSA4ICsgVFJBTlNfRkFDIC0gMTsKICB9IGVsc2UgewogICAgaWYgKHN5bnRheEZsYWdzICYgQUNfRUxEKSB7CiAgICAgIHN0YXRCaXRzID0gNjsKICAgIH0gZWxzZQogICAgewogICAgICBzdGF0Qml0cyA9ICghKHN5bnRheEZsYWdzICYgQUNfU0NBTEFCTEUpKSA/IDExIDogMTA7CiAgICB9CiAgfQoKICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKSB7CgogICAgaWYgKCEoc3ludGF4RmxhZ3MgJiBBQ19FTEQpKXsKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0saWNzUmVzZXJ2ZWRCaXQsMSk7CiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLGJsb2NrVHlwZSwyKTsKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sICh3aW5kb3dTaGFwZSA9PSBMT0xfV0lORE9XKSA/IEtCRF9XSU5ET1cgOiB3aW5kb3dTaGFwZSwxKTsKICAgIH0KCiAgICBzd2l0Y2goYmxvY2tUeXBlKXsKICAgIGNhc2UgTE9OR19XSU5ET1c6CiAgICBjYXNlIFNUQVJUX1dJTkRPVzoKICAgIGNhc2UgU1RPUF9XSU5ET1c6CiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLG1heFNmYlBlckdyb3VwLDYpOwoKICAgICAgaWYgKCEoc3ludGF4RmxhZ3MgJiAoQUNfU0NBTEFCTEV8QUNfRUxEKSkgKSB7IC8qIElmIG5vdCBzY2FsYWJsZSBzeW50YXggdGhlbiAuLi4gKi8KICAgICAgICAvKiBObyBwcmVkaWN0b3IgZGF0YSBwcmVzZW50ICovCiAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIDAsIDEpOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgU0hPUlRfV0lORE9XOgogICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSxtYXhTZmJQZXJHcm91cCw0KTsKCiAgICAgIC8qIFdyaXRlIGdyb3VwaW5nIGJpdHMgKi8KICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sZ3JvdXBpbmdNYXNrLFRSQU5TX0ZBQy0xKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQoKICByZXR1cm4gKHN0YXRCaXRzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfZW5jb2RlU2VjdGlvbkRhdGEKICAgIGRlc2NyaXB0aW9uOiAgZW5jb2RlIHNlY3Rpb24gZGF0YSAoY29tbW9uIEh1ZmZtYW4gY29kZWJvb2tzIGZvciBhZGphY2VudAogICAgICAgICAgICAgICAgICBTRkIncykKICAgIHJldHVybnM6ICAgICAgbm9uZQogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlU2VjdGlvbkRhdGEoU0VDVElPTl9EQVRBICpzZWN0aW9uRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJpdFN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCB1c2VWQ0IxMSkKewogIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgIElOVCBzZWN0RXNjYXBlVmFsPTAsc2VjdExlbkJpdHM9MDsKICAgIElOVCBzZWN0TGVuOwogICAgSU5UIGk7CiAgICBJTlQgZGJnVmFsPUZES2dldFZhbGlkQml0cyhoQml0U3RyZWFtKTsKICAgIElOVCBzZWN0Q2JCaXRzID0gNDsKCiAgICBzd2l0Y2goc2VjdGlvbkRhdGEtPmJsb2NrVHlwZSkKICAgIHsKICAgIGNhc2UgTE9OR19XSU5ET1c6CiAgICBjYXNlIFNUQVJUX1dJTkRPVzoKICAgIGNhc2UgU1RPUF9XSU5ET1c6CiAgICAgIHNlY3RFc2NhcGVWYWwgPSBTRUNUX0VTQ19WQUxfTE9ORzsKICAgICAgc2VjdExlbkJpdHMgICA9IFNFQ1RfQklUU19MT05HOwogICAgICBicmVhazsKCiAgICBjYXNlIFNIT1JUX1dJTkRPVzoKICAgICAgc2VjdEVzY2FwZVZhbCA9IFNFQ1RfRVNDX1ZBTF9TSE9SVDsKICAgICAgc2VjdExlbkJpdHMgICA9IFNFQ1RfQklUU19TSE9SVDsKICAgICAgYnJlYWs7CiAgICB9CgogICAgZm9yKGk9MDtpPHNlY3Rpb25EYXRhLT5ub09mU2VjdGlvbnM7aSsrKQogICAgewogICAgICBJTlQgY29kZUJvb2sgPSBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2s7CgogICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSxjb2RlQm9vayxzZWN0Q2JCaXRzKTsKCiAgICAgIHsKICAgICAgICBzZWN0TGVuID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYkNudDsKCiAgICAgICAgd2hpbGUoc2VjdExlbiA+PSBzZWN0RXNjYXBlVmFsKQogICAgICAgIHsKICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLHNlY3RFc2NhcGVWYWwsc2VjdExlbkJpdHMpOwogICAgICAgICAgc2VjdExlbi09c2VjdEVzY2FwZVZhbDsKICAgICAgICB9CiAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sc2VjdExlbixzZWN0TGVuQml0cyk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybihGREtnZXRWYWxpZEJpdHMoaEJpdFN0cmVhbSktZGJnVmFsKTsKICB9CiAgcmV0dXJuICgwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfZW5jb2RlU2NhbGVGYWN0b3JEYXRhCiAgICBkZXNjcmlwdGlvbjogIGVuY29kZSBEUENNIGNvZGVkIHNjYWxlIGZhY3RvcnMKICAgIHJldHVybnM6ICAgICAgbm9uZQogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlU2NhbGVGYWN0b3JEYXRhKFVJTlQgICAgICAgICAgICAgICAgICAqbWF4VmFsdWVJblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQ1RJT05fREFUQSAgICAgICAgICAqc2VjdGlvbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgKnNjYWxlZmFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICBoQml0U3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgICAgICpSRVNUUklDVCBub2lzZU5yZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAqaXNTY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgZ2xvYmFsR2FpbikKewogIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgIElOVCBpLGosbGFzdFZhbFNjZixkZWx0YVNjZjsKICAgIElOVCBkZWx0YVBuczsKICAgIElOVCBsYXN0VmFsUG5zID0gMDsKICAgIElOVCBub2lzZVBDTUZsYWcgPSBUUlVFOwogICAgSU5UIGxhc3RWYWxJczsKCiAgICBJTlQgZGJnVmFsID0gRkRLZ2V0VmFsaWRCaXRzKGhCaXRTdHJlYW0pOwoKICAgIGxhc3RWYWxTY2Y9c2NhbGVmYWNbc2VjdGlvbkRhdGEtPmZpcnN0U2NmXTsKICAgIGxhc3RWYWxQbnMgPSBnbG9iYWxHYWluLXNjYWxlZmFjW3NlY3Rpb25EYXRhLT5maXJzdFNjZl0rZ2xvYmFsR2Fpbk9mZnNldC00KkxPR19OT1JNX1BDTS1ub2lzZU9mZnNldDsKICAgIGxhc3RWYWxJcyAgPSAwOwoKICAgIGZvcihpPTA7IGk8c2VjdGlvbkRhdGEtPm5vT2ZTZWN0aW9uczsgaSsrKXsKICAgICAgaWYgKHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5jb2RlQm9vayAhPSBDT0RFX0JPT0tfWkVST19OTykgewoKICAgICAgICBpZiAoKHNlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5jb2RlQm9vayA9PSBDT0RFX0JPT0tfSVNfT1VUX09GX1BIQVNFX05PKSB8fAogICAgICAgICAgICAoc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLmNvZGVCb29rID09IENPREVfQk9PS19JU19JTl9QSEFTRV9OTykpCiAgICAgICAgewogICAgICAgICAgSU5UIHNmYlN0YXJ0ID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYlN0YXJ0OwogICAgICAgICAgSU5UIHRtcCA9IHNmYlN0YXJ0ICsgc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYkNudDsKICAgICAgICAgIGZvcihqPXNmYlN0YXJ0OyBqPHRtcDsgaisrKSB7CiAgICAgICAgICAgIElOVCBkZWx0YUlzICAgPSBpc1NjYWxlW2pdLWxhc3RWYWxJczsKICAgICAgICAgICAgbGFzdFZhbElzID0gaXNTY2FsZVtqXTsKICAgICAgICAgICAgaWYoRkRLYWFjRW5jX2NvZGVTY2FsZWZhY3RvckRlbHRhKGRlbHRhSXMsaEJpdFN0cmVhbSkpIHsKICAgICAgICAgICAgICAgIHJldHVybigxKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSAvKiBzZmIgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZihzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgPT0gQ09ERV9CT09LX1BOU19OTykgewogICAgICAgICAgSU5UIHNmYlN0YXJ0ID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYlN0YXJ0OwogICAgICAgICAgSU5UIHRtcCA9IHNmYlN0YXJ0ICsgc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYkNudDsKICAgICAgICAgIGZvcihqPXNmYlN0YXJ0OyBqPHRtcDsgaisrKSB7CiAgICAgICAgICAgIGRlbHRhUG5zICAgPSBub2lzZU5yZ1tqXS1sYXN0VmFsUG5zOwogICAgICAgICAgICBsYXN0VmFsUG5zID0gbm9pc2VOcmdbal07CgogICAgICAgICAgICBpZihub2lzZVBDTUZsYWcpewogICAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLGRlbHRhUG5zKygxPDwoUE5TX1BDTV9CSVRTLTEpKSxQTlNfUENNX0JJVFMpOwogICAgICAgICAgICAgIG5vaXNlUENNRmxhZyA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIGlmKEZES2FhY0VuY19jb2RlU2NhbGVmYWN0b3JEZWx0YShkZWx0YVBucyxoQml0U3RyZWFtKSkgewogICAgICAgICAgICAgICAgcmV0dXJuKDEpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSAvKiBzZmIgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBJTlQgdG1wID0gc2VjdGlvbkRhdGEtPmh1ZmZzZWN0aW9uW2ldLnNmYlN0YXJ0K3NlY3Rpb25EYXRhLT5odWZmc2VjdGlvbltpXS5zZmJDbnQ7CiAgICAgICAgICBmb3Ioaj1zZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uc2ZiU3RhcnQ7IGo8dG1wOyBqKyspewogICAgICAgICAgICAvKgogICAgICAgICAgICAgIGNoZWNrIGlmIHdlIGNhbiByZXBlYXQgdGhlIGxhc3QgdmFsdWUgdG8gc2F2ZSBiaXRzCiAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKG1heFZhbHVlSW5TZmJbal0gPT0gMCkKICAgICAgICAgICAgICBkZWx0YVNjZiA9IDA7CiAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgZGVsdGFTY2YgPSAtKHNjYWxlZmFjW2pdLWxhc3RWYWxTY2YpOwogICAgICAgICAgICAgIGxhc3RWYWxTY2YgPSBzY2FsZWZhY1tqXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihGREthYWNFbmNfY29kZVNjYWxlZmFjdG9yRGVsdGEoZGVsdGFTY2YsaEJpdFN0cmVhbSkpewogICAgICAgICAgICAgIHJldHVybigxKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSAvKiBzZmIgKi8KICAgICAgICB9IC8qIGNvZGUgc2NhbGVmYWN0b3IgKi8KICAgICAgfSAvKiBzZWN0aW9uRGF0YS0+aHVmZnNlY3Rpb25baV0uY29kZUJvb2sgIT0gQ09ERV9CT09LX1pFUk9fTk8gKi8KICAgIH0gLyogc2VjdGlvbiBsb29wICovCgogICAgcmV0dXJuKEZES2dldFZhbGlkQml0cyhoQml0U3RyZWFtKS1kYmdWYWwpOwogIH0gLyogaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgKi8KCiAgcmV0dXJuICgwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOmVuY29kZU1zSW5mbwogICAgZGVzY3JpcHRpb246IGVuY29kZXMgTVMtU3RlcmVvIEluZm8KICAgIHJldHVybnM6ICAgICB0aGUgbnVtYmVyIG9mIHN0YXRpYyBiaXRzCiAgICBpbnB1dDoKICAgIG91dHB1dDoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19lbmNvZGVNU0luZm8oSU5UICAgICAgICAgICAgc2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgZ3JwU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgbWF4U2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgbXNEaWdlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICpqc0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJpdFN0cmVhbSkKewogIElOVCBzZmIsIHNmYk9mZiwgbXNCaXRzID0gMDsKCiAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkKICB7CiAgICBzd2l0Y2gobXNEaWdlc3QpCiAgICB7CiAgICBjYXNlIE1TX05PTkU6CiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLFNJX01TX01BU0tfTk9ORSwyKTsKICAgICAgbXNCaXRzICs9IDI7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTVNfQUxMOgogICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSxTSV9NU19NQVNLX0FMTCwyKTsKICAgICAgbXNCaXRzICs9IDI7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgTVNfU09NRToKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sU0lfTVNfTUFTS19TT01FLDIpOwogICAgICBtc0JpdHMgKz0gMjsKICAgICAgZm9yKHNmYk9mZiA9IDA7IHNmYk9mZiA8IHNmYkNudDsgc2ZiT2ZmKz1ncnBTZmIpCiAgICAgIHsKICAgICAgICBmb3Ioc2ZiPTA7IHNmYjxtYXhTZmI7IHNmYisrKQogICAgICAgIHsKICAgICAgICAgIGlmKGpzRmxhZ3Nbc2ZiT2ZmK3NmYl0gJiBNU19PTil7CiAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLDEsMSk7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlewogICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwwLDEpOwogICAgICAgICAgfQogICAgICAgICAgbXNCaXRzICs9IDE7CiAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBlbHNlIHsKICAgIG1zQml0cyArPSAyOwogICAgaWYgKG1zRGlnZXN0ID09IE1TX1NPTUUpIHsKICAgICAgZm9yKHNmYk9mZiA9IDA7IHNmYk9mZiA8IHNmYkNudDsgc2ZiT2ZmKz1ncnBTZmIpIHsKICAgICAgICBmb3Ioc2ZiPTA7IHNmYjxtYXhTZmI7IHNmYisrKSB7CiAgICAgICAgICBtc0JpdHMgKz0gMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIChtc0JpdHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19lbmNvZGVUbnNEYXRhUHJlc2VudAogICAgZGVzY3JpcHRpb246ICBlbmNvZGUgVE5TIGRhdGEgKGZpbHRlciBvcmRlciwgY29lZmZzLCAuLikKICAgIHJldHVybnM6ICAgICAgdGhlIG51bWJlciBvZiBzdGF0aWMgYml0cwogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlVG5zRGF0YVByZXNlbnQoVE5TX0lORk8gKnRuc0luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBibG9ja1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0pCnsKICBpZiAoIChoQml0U3RyZWFtIT1OVUxMKSAmJiAodG5zSW5mbyE9TlVMTCkgKQogIHsKICAgIElOVCBpLCB0bnNQcmVzZW50ID0gMDsKICAgIElOVCBudW1PZldpbmRvd3MgPSAoYmxvY2tUeXBlPT1TSE9SVF9XSU5ET1c/VFJBTlNfRkFDOjEpOwoKICAgIGZvciAoaT0wOyBpPG51bU9mV2luZG93czsgaSsrKSB7CiAgICAgIGlmICh0bnNJbmZvLT5udW1PZkZpbHRlcnNbaV0hPTApIHsKICAgICAgICB0bnNQcmVzZW50PTE7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBpZiAodG5zUHJlc2VudD09MCkgewogICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwwLDEpOwogICAgfSBlbHNlIHsKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sMSwxKTsKICAgIH0KICB9CiAgcmV0dXJuICgxKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfZW5jb2RlVG5zRGF0YQogICAgZGVzY3JpcHRpb246ICBlbmNvZGUgVE5TIGRhdGEgKGZpbHRlciBvcmRlciwgY29lZmZzLCAuLikKICAgIHJldHVybnM6ICAgICAgdGhlIG51bWJlciBvZiBzdGF0aWMgYml0cwogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlVG5zRGF0YShUTlNfSU5GTyAqdG5zSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgYmxvY2tUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0pCnsKICBJTlQgdG5zQml0cyA9IDA7CgogIGlmICh0bnNJbmZvIT1OVUxMKSB7CgogICAgSU5UIGksaixrOwogICAgSU5UIHRuc1ByZXNlbnQgPSAwOwogICAgSU5UIGNvZWZCaXRzOwogICAgSU5UIG51bU9mV2luZG93cz0oYmxvY2tUeXBlPT1TSE9SVF9XSU5ET1c/VFJBTlNfRkFDOjEpOwoKICAgIGZvciAoaT0wOyBpPG51bU9mV2luZG93czsgaSsrKSB7CiAgICAgIGlmICh0bnNJbmZvLT5udW1PZkZpbHRlcnNbaV0hPTApIHsKICAgICAgICB0bnNQcmVzZW50PTE7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKQogICAgewogICAgICBpZiAodG5zUHJlc2VudD09MSkgeyAvKiB0aGVyZSBpcyBkYXRhIHRvIGJlIHdyaXR0ZW4qLwogICAgICAgIGZvciAoaT0wOyBpPG51bU9mV2luZG93czsgaSsrKSB7CiAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSx0bnNJbmZvLT5udW1PZkZpbHRlcnNbaV0sKGJsb2NrVHlwZT09U0hPUlRfV0lORE9XPzE6MikpOwogICAgICAgICAgdG5zQml0cyArPSAoYmxvY2tUeXBlPT1TSE9SVF9XSU5ET1c/MToyKTsKICAgICAgICAgIGlmICh0bnNJbmZvLT5udW1PZkZpbHRlcnNbaV0pIHsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sKHRuc0luZm8tPmNvZWZSZXNbaV09PTQ/MTowKSwxKTsKICAgICAgICAgICAgdG5zQml0cyArPSAxOwogICAgICAgICAgfQogICAgICAgICAgZm9yIChqPTA7IGo8dG5zSW5mby0+bnVtT2ZGaWx0ZXJzW2ldOyBqKyspIHsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sdG5zSW5mby0+bGVuZ3RoW2ldW2pdLChibG9ja1R5cGU9PVNIT1JUX1dJTkRPVz80OjYpKTsKICAgICAgICAgICAgdG5zQml0cyArPSAoYmxvY2tUeXBlPT1TSE9SVF9XSU5ET1c/NDo2KTsKICAgICAgICAgICAgRkRLX0FTU0VSVCh0bnNJbmZvLT5vcmRlcltpXVtqXSA8PSAxMik7CiAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLHRuc0luZm8tPm9yZGVyW2ldW2pdLChibG9ja1R5cGU9PVNIT1JUX1dJTkRPVz8zOjUpKTsKICAgICAgICAgICAgdG5zQml0cyArPSAoYmxvY2tUeXBlPT1TSE9SVF9XSU5ET1c/Mzo1KTsKICAgICAgICAgICAgaWYgKHRuc0luZm8tPm9yZGVyW2ldW2pdKXsKICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSx0bnNJbmZvLT5kaXJlY3Rpb25baV1bal0sMSk7CiAgICAgICAgICAgICAgdG5zQml0cyArPTE7IC8qZGlyZWN0aW9uKi8KICAgICAgICAgICAgICBpZih0bnNJbmZvLT5jb2VmUmVzW2ldID09IDQpIHsKICAgICAgICAgICAgICAgIGNvZWZCaXRzID0gMzsKICAgICAgICAgICAgICAgIGZvcihrPTA7IGs8dG5zSW5mby0+b3JkZXJbaV1bal07IGsrKykgewogICAgICAgICAgICAgICAgICBpZiAodG5zSW5mby0+Y29lZltpXVtqXVtrXT4gMyB8fAogICAgICAgICAgICAgICAgICAgIHRuc0luZm8tPmNvZWZbaV1bal1ba108IC00KSB7CiAgICAgICAgICAgICAgICAgICAgY29lZkJpdHMgPSA0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvZWZCaXRzID0gMjsKICAgICAgICAgICAgICAgIGZvcihrPTA7IGs8dG5zSW5mby0+b3JkZXJbaV1bal07IGsrKykgewogICAgICAgICAgICAgICAgICBpZiAoIHRuc0luZm8tPmNvZWZbaV1bal1ba10+IDEKICAgICAgICAgICAgICAgICAgICB8fCB0bnNJbmZvLT5jb2VmW2ldW2pdW2tdPCAtMikgewogICAgICAgICAgICAgICAgICAgIGNvZWZCaXRzID0gMzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwtKGNvZWZCaXRzIC0gdG5zSW5mby0+Y29lZlJlc1tpXSksMSk7IC8qY29lZl9jb21wcmVzKi8KICAgICAgICAgICAgICB0bnNCaXRzICs9MTsgLypjb2VmX2NvbXByZXNzaW9uICovCiAgICAgICAgICAgICAgZm9yIChrPTA7IGs8dG5zSW5mby0+b3JkZXJbaV1bal07IGsrKyApIHsKICAgICAgICAgICAgICAgIHN0YXRpYyBjb25zdCBJTlQgcm1hc2tbXSA9IHswLDEsMyw3LDE1fTsKICAgICAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLHRuc0luZm8tPmNvZWZbaV1bal1ba10gJiBybWFza1tjb2VmQml0c10sY29lZkJpdHMpOwogICAgICAgICAgICAgICAgdG5zQml0cyArPSBjb2VmQml0czsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICBpZiAodG5zUHJlc2VudCAhPSAwKSB7CiAgICAgICAgZm9yIChpPTA7IGk8bnVtT2ZXaW5kb3dzOyBpKyspIHsKICAgICAgICAgIHRuc0JpdHMgKz0gKGJsb2NrVHlwZT09U0hPUlRfV0lORE9XPzE6Mik7CiAgICAgICAgICBpZiAodG5zSW5mby0+bnVtT2ZGaWx0ZXJzW2ldKSB7CiAgICAgICAgICAgIHRuc0JpdHMgKz0gMTsKICAgICAgICAgICAgZm9yIChqPTA7IGo8dG5zSW5mby0+bnVtT2ZGaWx0ZXJzW2ldOyBqKyspIHsKICAgICAgICAgICAgICB0bnNCaXRzICs9IChibG9ja1R5cGU9PVNIT1JUX1dJTkRPVz80OjYpOwogICAgICAgICAgICAgIHRuc0JpdHMgKz0gKGJsb2NrVHlwZT09U0hPUlRfV0lORE9XPzM6NSk7CiAgICAgICAgICAgICAgaWYgKHRuc0luZm8tPm9yZGVyW2ldW2pdKSB7CiAgICAgICAgICAgICAgICB0bnNCaXRzICs9MTsgLypkaXJlY3Rpb24qLwogICAgICAgICAgICAgICAgdG5zQml0cyArPTE7IC8qY29lZl9jb21wcmVzc2lvbiAqLwogICAgICAgICAgICAgICAgaWYgKHRuc0luZm8tPmNvZWZSZXNbaV0gPT0gNCkgewogICAgICAgICAgICAgICAgICBjb2VmQml0cz0zOwogICAgICAgICAgICAgICAgICBmb3IgKGs9MDsgazx0bnNJbmZvLT5vcmRlcltpXVtqXTsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRuc0luZm8tPmNvZWZbaV1bal1ba10+IDMgfHwgdG5zSW5mby0+Y29lZltpXVtqXVtrXTwgLTQpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvZWZCaXRzID0gNDsKICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgIGNvZWZCaXRzID0gMjsKICAgICAgICAgICAgICAgICAgZm9yIChrPTA7IGs8dG5zSW5mby0+b3JkZXJbaV1bal07IGsrKykgewogICAgICAgICAgICAgICAgICAgIGlmICh0bnNJbmZvLT5jb2VmW2ldW2pdW2tdPiAxIHx8IHRuc0luZm8tPmNvZWZbaV1bal1ba108IC0yKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb2VmQml0cyA9IDM7CiAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoaz0wOyBrPHRuc0luZm8tPm9yZGVyW2ldW2pdOyBrKyspIHsKICAgICAgICAgICAgICAgICAgdG5zQml0cyArPSBjb2VmQml0czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IC8qICh0bnNJbmZvIT1OVUxMKSAqLwoKICByZXR1cm4gKHRuc0JpdHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19lbmNvZGVHYWluQ29udHJvbERhdGEKICAgIGRlc2NyaXB0aW9uOiAgdW5zdXBwb3J0ZWQKICAgIHJldHVybnM6ICAgICAgbm9uZQogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfZW5jb2RlR2FpbkNvbnRyb2xEYXRhKEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0pCnsKICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKSB7CiAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwwLDEpOwogIH0KICByZXR1cm4gKDEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19lbmNvZGVQdWxzZURhdGEKICAgIGRlc2NyaXB0aW9uOiAgbm90IHN1cHBvcnRlZCB5ZXQgKGR1bW15KQogICAgcmV0dXJuczogICAgICBub25lCiAgICBpbnB1dDoKICAgIG91dHB1dDoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19lbmNvZGVQdWxzZURhdGEoSEFORExFX0ZES19CSVRTVFJFQU0gaEJpdFN0cmVhbSkKewogIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLDAsMSk7CiAgfQogIHJldHVybiAoMSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY193cml0ZUV4dGVuc2lvblBheWxvYWQKICAgIGRlc2NyaXB0aW9uOiAgd3JpdGUgZXh0ZW5zaW9uIHBheWxvYWQgdG8gYml0c3RyZWFtCiAgICByZXR1cm5zOiAgICAgIG51bWJlciBvZiB3cml0dGVuIGJpdHMKICAgIGlucHV0OgogICAgb3V0cHV0OgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBJTlQgRkRLYWFjRW5jX3dyaXRlRXh0ZW5zaW9uUGF5bG9hZCggSEFORExFX0ZES19CSVRTVFJFQU0gIGhCaXRTdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVhUX1BBWUxPQURfVFlQRSAgICAgIGV4dFBheWxvYWRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICAgICAgICAgICpleHRQYXlsb2FkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgZXh0UGF5bG9hZEJpdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgI2RlZmluZSBFWFRfVFlQRV9CSVRTICAgICAgICAgKCA0ICkKICAjZGVmaW5lIERBVEFfRUxfVkVSU0lPTl9CSVRTICAoIDQgKQogICNkZWZpbmUgRklMTF9OSUJCTEVfQklUUyAgICAgICggNCApCgogIElOVCAgZXh0Qml0c1VzZWQgPSAwOwoKICBpZiAoZXh0UGF5bG9hZEJpdHMgPj0gRVhUX1RZUEVfQklUUykKICB7CiAgICBVQ0hBUiAgZmlsbEJ5dGUgPSAweDAwOyAgLyogZm9yIEVYVF9GSUwgYW5kIEVYVF9GSUxMX0RBVEEgKi8KCiAgICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBleHRQYXlsb2FkVHlwZSwgRVhUX1RZUEVfQklUUyk7CiAgICB9CiAgICBleHRCaXRzVXNlZCArPSBFWFRfVFlQRV9CSVRTOwoKICAgIHN3aXRjaCAoZXh0UGF5bG9hZFR5cGUpIHsKICAgICAgY2FzZSBFWFRfRFlOQU1JQ19SQU5HRToKICAgICAgLyogY2FzZSBFWFRfU0FDX0RBVEE6ICovCiAgICAgIGNhc2UgRVhUX1NCUl9EQVRBOgogICAgICBjYXNlIEVYVF9TQlJfREFUQV9DUkM6CiAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgaW50IGksIHdyaXRlQml0cyA9IGV4dFBheWxvYWRCaXRzOwogICAgICAgICAgZm9yIChpPTA7IHdyaXRlQml0cyA+PSA4OyBpKyspIHsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGV4dFBheWxvYWREYXRhW2ldLCA4KTsKICAgICAgICAgICAgd3JpdGVCaXRzIC09IDg7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAod3JpdGVCaXRzID4gMCkgewogICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgZXh0UGF5bG9hZERhdGFbaV0+Pig4LXdyaXRlQml0cyksIHdyaXRlQml0cyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGV4dEJpdHNVc2VkICs9IGV4dFBheWxvYWRCaXRzOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBFWFRfREFUQV9FTEVNRU5UOgogICAgICAgIHsKICAgICAgICAgIElOVCBkYXRhRWxlbWVudExlbmd0aCA9IChleHRQYXlsb2FkQml0cys3KT4+MzsKICAgICAgICAgIElOVCBjbnQgPSBkYXRhRWxlbWVudExlbmd0aDsKICAgICAgICAgIGludCBsb29wQ291bnRlciA9IDE7CgogICAgICAgICAgd2hpbGUgKGRhdGFFbGVtZW50TGVuZ3RoID49IDI1NSkgewogICAgICAgICAgICBsb29wQ291bnRlcisrOwogICAgICAgICAgICBkYXRhRWxlbWVudExlbmd0aCAtPSAyNTU7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIDB4MDAsIERBVEFfRUxfVkVSU0lPTl9CSVRTKTsgIC8qIGRhdGFfZWxlbWVudF92ZXJzaW9uID0gQU5DX0RBVEEgKi8KCiAgICAgICAgICAgIGZvciAoaT0xOyBpPGxvb3BDb3VudGVyOyBpKyspIHsKICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgMjU1LCA4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgZGF0YUVsZW1lbnRMZW5ndGgsIDgpOwoKICAgICAgICAgICAgZm9yIChpPTA7IGk8Y250OyBpKyspIHsKICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgZXh0UGF5bG9hZERhdGFbaV0sIDgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBleHRCaXRzVXNlZCArPSBEQVRBX0VMX1ZFUlNJT05fQklUUyArIChsb29wQ291bnRlcio4KSArIChjbnQqOCk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBFWFRfRklMTF9EQVRBOgogICAgICAgIGZpbGxCeXRlID0gMHhBNTsKICAgICAgY2FzZSBFWFRfRklMOgogICAgICBkZWZhdWx0OgogICAgICAgIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgICAgICAgIGludCB3cml0ZUJpdHMgPSBleHRQYXlsb2FkQml0czsKICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCAweDAwLCBGSUxMX05JQkJMRV9CSVRTKTsKICAgICAgICAgIHdyaXRlQml0cyAtPSA4OyAgLyogYWNvdW50IGZvciB0aGUgZXh0ZW5zaW9uIHR5cGUgYW5kIHRoZSBmaWxsIG5pYmJsZSAqLwogICAgICAgICAgd2hpbGUgKHdyaXRlQml0cyA+PSA4KSB7CiAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBmaWxsQnl0ZSwgOCk7CiAgICAgICAgICAgIHdyaXRlQml0cyAtPSA4OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBleHRCaXRzVXNlZCArPSBGSUxMX05JQkJMRV9CSVRTICsgKGV4dFBheWxvYWRCaXRzICYgfjB4NykgLSA4OwogICAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgcmV0dXJuIChleHRCaXRzVXNlZCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY193cml0ZURhdGFTdHJlYW1FbGVtZW50CiAgICBkZXNjcmlwdGlvbjogIHdyaXRlIGRhdGEgc3RyZWFtIGVsZW1lbnRzIGxpa2UgYW5jaWxsYXJ5IGRhdGEgLi4uCiAgICByZXR1cm5zOiAgICAgIHRoZSBhbW91bnQgb2YgdXNlZCBiaXRzCiAgICBpbnB1dDoKICAgIG91dHB1dDoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfd3JpdGVEYXRhU3RyZWFtRWxlbWVudCggSEFORExFX1RSQU5TUE9SVEVOQyAgaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgZWxlbWVudEluc3RhbmNlVGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgZGF0YVBheWxvYWRCeXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKmRhdGFCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICBhbGlnbkFuY2hvciApCnsKICAjZGVmaW5lIERBVEFfQllURV9BTElHTl9GTEFHICAgICAgKCAwICkKCiAgI2RlZmluZSBFTF9JTlNUQU5DRV9UQUdfQklUUyAgICAgICggNCApCiAgI2RlZmluZSBEQVRBX0JZVEVfQUxJR05fRkxBR19CSVRTICggMSApCiAgI2RlZmluZSBEQVRBX0xFTl9DT1VOVF9CSVRTICAgICAgICggOCApCiAgI2RlZmluZSBEQVRBX0xFTl9FU0NfQ09VTlRfQklUUyAgICggOCApCgogICNkZWZpbmUgTUFYX0RBVEFfQUxJR05fQklUUyAgICAgICAoIDcgKQogICNkZWZpbmUgTUFYX0RTRV9EQVRBX0JZVEVTICAgICAgICAoIDUxMCApCgogIElOVCAgZHNlQml0c1VzZWQgPSAwOwoKICB3aGlsZSAoZGF0YVBheWxvYWRCeXRlcyA+IDApCiAgewogICAgaW50IGVzY19jb3VudCA9IC0xOwogICAgaW50IGNudCA9IDA7CiAgICBJTlQgY3JjUmVnID0gLTE7CgogICAgZHNlQml0c1VzZWQgKz0gRUxfSURfQklUUyArIEVMX0lOU1RBTkNFX1RBR19CSVRTCiAgICAgICAgICAgICAgICArICBEQVRBX0JZVEVfQUxJR05fRkxBR19CSVRTICsgREFUQV9MRU5fQ09VTlRfQklUUzsKCiAgICBpZiAoREFUQV9CWVRFX0FMSUdOX0ZMQUcpIHsKICAgICAgZHNlQml0c1VzZWQgKz0gTUFYX0RBVEFfQUxJR05fQklUUzsKICAgIH0KCiAgICBjbnQgPSBmaXhNaW4oTUFYX0RTRV9EQVRBX0JZVEVTLCBkYXRhUGF5bG9hZEJ5dGVzKTsKICAgIGlmICggY250ID49IDI1NSApIHsKICAgICAgZXNjX2NvdW50ID0gY250IC0gMjU1OwogICAgICBkc2VCaXRzVXNlZCArPSBEQVRBX0xFTl9FU0NfQ09VTlRfQklUUzsKICAgIH0KCiAgICBkYXRhUGF5bG9hZEJ5dGVzIC09IGNudDsKICAgIGRzZUJpdHNVc2VkICs9IGNudCAqIDg7CgogICAgaWYgKGhUcEVuYyAhPSBOVUxMKSB7CiAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0gPSB0cmFuc3BvcnRFbmNfR2V0Qml0c3RyZWFtKGhUcEVuYyk7CiAgICAgIGludCBpOwoKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIElEX0RTRSwgRUxfSURfQklUUyk7CgogICAgICBjcmNSZWcgPSB0cmFuc3BvcnRFbmNfQ3JjU3RhcnRSZWcoaFRwRW5jLCAwKTsKCiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBlbGVtZW50SW5zdGFuY2VUYWcsIEVMX0lOU1RBTkNFX1RBR19CSVRTKTsKICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIERBVEFfQllURV9BTElHTl9GTEFHLCBEQVRBX0JZVEVfQUxJR05fRkxBR19CSVRTKTsKCiAgICAgIC8qIHdyaXRlIGxlbmd0aCBmaWVsZChzKSAqLwogICAgICBpZiAoIGVzY19jb3VudCA+PSAwICkgewogICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCAyNTUsIERBVEFfTEVOX0NPVU5UX0JJVFMpOwogICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBlc2NfY291bnQsIERBVEFfTEVOX0VTQ19DT1VOVF9CSVRTKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgY250LCBEQVRBX0xFTl9DT1VOVF9CSVRTKTsKICAgICAgfQoKICAgICAgaWYgKERBVEFfQllURV9BTElHTl9GTEFHKSB7CiAgICAgICAgSU5UIHRtcCA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCaXRTdHJlYW0pOwogICAgICAgIEZES2J5dGVBbGlnbihoQml0U3RyZWFtLCBhbGlnbkFuY2hvcik7CiAgICAgICAgLyogY291bnQgYWN0dWFsIGJpdHMgKi8KICAgICAgICBkc2VCaXRzVXNlZCArPSAoSU5UKUZES2dldFZhbGlkQml0cyhoQml0U3RyZWFtKSAtIHRtcCAtIE1BWF9EQVRBX0FMSUdOX0JJVFM7CiAgICAgIH0KCiAgICAgIC8qIHdyaXRlIHBheWxvYWQgKi8KICAgICAgZm9yIChpPTA7IGk8Y250OyBpKyspIHsKICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgZGF0YUJ1ZmZlcltpXSwgOCk7CiAgICAgIH0KICAgICAgdHJhbnNwb3J0RW5jX0NyY0VuZFJlZyhoVHBFbmMsIGNyY1JlZyk7CiAgICB9CiAgfQoKICByZXR1cm4gKGRzZUJpdHNVc2VkKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX3dyaXRlRXh0ZW5zaW9uRGF0YQogICAgZGVzY3JpcHRpb246ICB3cml0ZSBleHRlbnNpb24gcGF5bG9hZCB0byBiaXRzdHJlYW0KICAgIHJldHVybnM6ICAgICAgbnVtYmVyIG9mIHdyaXR0ZW4gYml0cwogICAgaW5wdXQ6CiAgICBvdXRwdXQ6CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU5UIEZES2FhY0VuY193cml0ZUV4dGVuc2lvbkRhdGEoIEhBTkRMRV9UUkFOU1BPUlRFTkMgIGhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVF9FWFRFTlNJT04gICAgKnBFeHRlbnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICAgICAgICBlbEluc3RhbmNlVGFnLCAvKiBmb3IgRFNFIG9ubHkgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICAgIGFsaWduQW5jaG9yLCAgIC8qIGZvciBEU0Ugb25seSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSAgICBhb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICBlcENvbmZpZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogICNkZWZpbmUgRklMTF9FTF9DT1VOVF9CSVRTICAgICAgKCA0ICkKICAjZGVmaW5lIEZJTExfRUxfRVNDX0NPVU5UX0JJVFMgICggOCApCiAgI2RlZmluZSBNQVhfRklMTF9EQVRBX0JZVEVTICAgICAoIDI2OSApCgogIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0gPSBOVUxMOwogIElOVCBwYXlsb2FkQml0cyA9IHBFeHRlbnNpb24tPm5QYXlsb2FkQml0czsKICBJTlQgZXh0Qml0c1VzZWQgPSAwOwoKICBpZiAoaFRwRW5jICE9IE5VTEwpIHsKICAgIGhCaXRTdHJlYW0gPSB0cmFuc3BvcnRFbmNfR2V0Qml0c3RyZWFtKGhUcEVuYyk7CiAgfQoKICBpZiAoc3ludGF4RmxhZ3MgJiAoQUNfU0NBTEFCTEV8QUNfRVIpKQogIHsKICAgIGlmICggc3ludGF4RmxhZ3MgJiBBQ19EUk0gKQogICAgeyAvKiBDQVVUSU9OOiBUaGUgY2FsbGVyIGhhcyB0byBhc3N1cmUgdGhhdCBmaWxsCiAgICAgICAgICAgICAgICAgIGRhdGEgaXMgd3JpdHRlbiBiZWZvcmUgdGhlIFNCUiBwYXlsb2FkLiAqLwogICAgICBVQ0hBUiAqZXh0UGF5bG9hZERhdGEgPSBwRXh0ZW5zaW9uLT5wUGF5bG9hZDsKCiAgICAgIHN3aXRjaCAocEV4dGVuc2lvbi0+dHlwZSkKICAgICAgewogICAgICAgIGNhc2UgRVhUX1NCUl9EQVRBOgogICAgICAgIGNhc2UgRVhUX1NCUl9EQVRBX0NSQzoKICAgICAgICAgIC8qIFNCUiBwYXlsb2FkIGlzIHdyaXR0ZW4gaW4gcmV2ZXJzZSAqLwogICAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgICBpbnQgICBpLCB3cml0ZUJpdHMgPSBwYXlsb2FkQml0czsKCiAgICAgICAgICAgIEZES3B1c2hGb3IoaEJpdFN0cmVhbSwgcGF5bG9hZEJpdHMtMSk7ICAvKiBEb2VzIGEgY2FjaGUgc3luYyBpbnRlcm5hbGx5ICovCgogICAgICAgICAgICBmb3IgKGk9MDsgd3JpdGVCaXRzID49IDg7IGkrKykgewogICAgICAgICAgICAgIEZES3dyaXRlQml0c0J3ZChoQml0U3RyZWFtLCBleHRQYXlsb2FkRGF0YVtpXSwgOCk7CiAgICAgICAgICAgICAgd3JpdGVCaXRzIC09IDg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHdyaXRlQml0cyA+IDApIHsKICAgICAgICAgICAgICBGREt3cml0ZUJpdHNCd2QoaEJpdFN0cmVhbSwgZXh0UGF5bG9hZERhdGFbaV0+Pig4LXdyaXRlQml0cyksIHdyaXRlQml0cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZES3N5bmNDYWNoZUJ3ZCAoaEJpdFN0cmVhbSk7CiAgICAgICAgICAgIEZES3B1c2hGb3IgKGhCaXRTdHJlYW0sIHBheWxvYWRCaXRzKzEpOwogICAgICAgICAgfQogICAgICAgICAgZXh0Qml0c1VzZWQgKz0gcGF5bG9hZEJpdHM7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBFWFRfRklMTF9EQVRBOgogICAgICAgIGNhc2UgRVhUX0ZJTDoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgICBpbnQgd3JpdGVCaXRzID0gcGF5bG9hZEJpdHM7CiAgICAgICAgICAgIHdoaWxlICh3cml0ZUJpdHMgPj0gOCkgewogICAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCAweDAwLCA4KTsKICAgICAgICAgICAgICB3cml0ZUJpdHMgLT0gODsKICAgICAgICAgICAgfQogICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgMHgwMCwgd3JpdGVCaXRzKTsKICAgICAgICAgIH0KICAgICAgICAgIGV4dEJpdHNVc2VkICs9IHBheWxvYWRCaXRzOwogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICBpZiAoIChzeW50YXhGbGFncyAmIEFDX0VMRCkgJiYgKChwRXh0ZW5zaW9uLT50eXBlPT1FWFRfU0JSX0RBVEEpIHx8IChwRXh0ZW5zaW9uLT50eXBlPT1FWFRfU0JSX0RBVEFfQ1JDKSkgKSB7CgogICAgICAgIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgICAgICAgIGludCBpLCB3cml0ZUJpdHMgPSBwYXlsb2FkQml0czsKICAgICAgICAgIFVDSEFSICpleHRQYXlsb2FkRGF0YSA9IHBFeHRlbnNpb24tPnBQYXlsb2FkOwoKICAgICAgICAgIGZvciAoaT0wOyB3cml0ZUJpdHMgPj0gODsgaSsrKSB7CiAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBleHRQYXlsb2FkRGF0YVtpXSwgOCk7CiAgICAgICAgICAgIHdyaXRlQml0cyAtPSA4OwogICAgICAgICAgfQogICAgICAgICAgaWYgKHdyaXRlQml0cyA+IDApIHsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGV4dFBheWxvYWREYXRhW2ldPj4oOC13cml0ZUJpdHMpLCB3cml0ZUJpdHMpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBleHRCaXRzVXNlZCArPSBwYXlsb2FkQml0czsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAvKiBFUiBvciBzY2FsYWJsZSBzeW50YXggLT4gd3JpdGUgZXh0ZW5zaW9uIGVuIGJsb2MgKi8KICAgICAgICBleHRCaXRzVXNlZCArPSBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25QYXlsb2FkKCBoQml0U3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBFeHRlbnNpb24tPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEV4dGVuc2lvbi0+cFBheWxvYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZEJpdHMgKTsKICAgICAgfQogICAgfQogIH0KICBlbHNlIHsKICAgIC8qIFdlIGhhdmUgbm9ybWFsIEdBIGJpdHN0cmVhbSBwYXlsb2FkIChBT1QgMiw1LDI5KSBzbyBwYWNrCiAgICAgICB0aGUgZGF0YSBpbnRvIGEgZmlsbCBlbGVtZW50cyBvciBEU0VzICovCgogICAgaWYgKCBwRXh0ZW5zaW9uLT50eXBlID09IEVYVF9EQVRBX0VMRU1FTlQgKQogICAgewogICAgICBleHRCaXRzVXNlZCArPSBGREthYWNFbmNfd3JpdGVEYXRhU3RyZWFtRWxlbWVudCggaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBFeHRlbnNpb24tPm5QYXlsb2FkQml0cz4+MywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBFeHRlbnNpb24tPnBQYXlsb2FkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25BbmNob3IgKTsKICAgIH0KICAgIGVsc2UgewogICAgICB3aGlsZSAocGF5bG9hZEJpdHMgPj0gKEVMX0lEX0JJVFMgKyBGSUxMX0VMX0NPVU5UX0JJVFMpKSB7CiAgICAgICAgSU5UIGNudCwgZXNjX2NvdW50PS0xLCBhbGlnbkJpdHM9NzsKCiAgICAgICAgaWYgKCAocEV4dGVuc2lvbi0+dHlwZSA9PSBFWFRfRklMTF9EQVRBKSB8fCAocEV4dGVuc2lvbi0+dHlwZSA9PSBFWFRfRklMKSApCiAgICAgICAgewogICAgICAgICAgcGF5bG9hZEJpdHMgLT0gRUxfSURfQklUUyArIEZJTExfRUxfQ09VTlRfQklUUzsKICAgICAgICAgIGlmIChwYXlsb2FkQml0cyA+PSAxNSo4KSB7CiAgICAgICAgICAgIHBheWxvYWRCaXRzIC09IEZJTExfRUxfRVNDX0NPVU5UX0JJVFM7CiAgICAgICAgICAgIGVzY19jb3VudCA9IDA7ICAvKiB3cml0ZSBlc2NfY291bnQgZXZlbiBpZiBjbnQgYmVjb21lcyBzbWFsbGVyIDE1ICovCiAgICAgICAgICB9CiAgICAgICAgICBhbGlnbkJpdHMgPSAwOwogICAgICAgIH0KCiAgICAgICAgY250ID0gZml4TWluKE1BWF9GSUxMX0RBVEFfQllURVMsIChwYXlsb2FkQml0cythbGlnbkJpdHMpPj4zKTsKCiAgICAgICAgaWYgKGNudCA+PSAxNSkgewogICAgICAgICAgZXNjX2NvdW50ID0gY250IC0gMTUgKyAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgLyogd3JpdGUgYml0c3RyZWFtICovCiAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgSURfRklMLCBFTF9JRF9CSVRTKTsKICAgICAgICAgIGlmIChlc2NfY291bnQgPj0gMCkgewogICAgICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgMTUsIEZJTExfRUxfQ09VTlRfQklUUyk7CiAgICAgICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBlc2NfY291bnQsIEZJTExfRUxfRVNDX0NPVU5UX0JJVFMpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGNudCwgRklMTF9FTF9DT1VOVF9CSVRTKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGV4dEJpdHNVc2VkICs9IEVMX0lEX0JJVFMgKyBGSUxMX0VMX0NPVU5UX0JJVFMgKyAoKGVzY19jb3VudD49MCkgPyBGSUxMX0VMX0VTQ19DT1VOVF9CSVRTIDogMCk7CgogICAgICAgIGNudCA9IGZpeE1pbihjbnQqOCwgcGF5bG9hZEJpdHMpOyAgLyogY29udmVydCBiYWNrIHRvIGJpdHMgKi8KICAgICAgICBleHRCaXRzVXNlZCArPSBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25QYXlsb2FkKCBoQml0U3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBFeHRlbnNpb24tPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEV4dGVuc2lvbi0+cFBheWxvYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY250ICk7CiAgICAgICAgcGF5bG9hZEJpdHMgLT0gY250OwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gKGV4dEJpdHNVc2VkKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX0J5dGVBbGlnbm1lbnQKICAgIGRlc2NyaXB0aW9uOgogICAgcmV0dXJuczoKICAgIGlucHV0OgogICAgb3V0cHV0OgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIEZES2FhY0VuY19CeXRlQWxpZ25tZW50KEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0sIGludCBhbGlnbkJpdHMpCnsKICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgMCwgYWxpZ25CaXRzKTsKfQoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX0NoYW5uZWxFbGVtZW50V3JpdGUoIEhBTkRMRV9UUkFOU1BPUlRFTkMgIGhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVMRU1FTlRfSU5GTyAgICAgICAgKnBFbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19PVVRfQ0hBTk5FTCAgICAgICpxY091dENoYW5uZWxbKDIpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9PVVRfRUxFTUVOVCAgICAgKnBzeU91dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUX0NIQU5ORUwgICAgICpwc3lPdXRDaGFubmVsWygyKV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFVRElPX09CSkVDVF9UWVBFICAgIGFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICAgICAgICAgICAgIGVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgICAqcEJpdERlbWFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICAgIG1pbkNudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIEFBQ19FTkNPREVSX0VSUk9SIGVycm9yID0gQUFDX0VOQ19PSzsKICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQml0U3RyZWFtID0gTlVMTDsKICBJTlQgICAgYml0RGVtYW5kID0gMDsKICBjb25zdCAgZWxlbWVudF9saXN0X3QgKmxpc3Q7CiAgaW50ICAgIGksIGNoLCBkZWNpc2lvbl9iaXQ7CiAgSU5UICAgIGNyY1JlZzEgPSAtMSwgY3JjUmVnMiA9IC0xOwogIFVDSEFSICBudW1iZXJPZkNoYW5uZWxzOwoKICBpZiAoaFRwRW5jICE9IE5VTEwpIHsKICAgIC8qIEdldCBiaXRzdHJlYW0gaGFuZGxlICovCiAgICBoQml0U3RyZWFtID0gdHJhbnNwb3J0RW5jX0dldEJpdHN0cmVhbShoVHBFbmMpOwogIH0KCiAgaWYgKCAocEVsSW5mby0+ZWxUeXBlPT1JRF9TQ0UpIHx8IChwRWxJbmZvLT5lbFR5cGU9PUlEX0xGRSkgKSB7CiAgICBudW1iZXJPZkNoYW5uZWxzID0gMTsKICB9IGVsc2UgewogICAgbnVtYmVyT2ZDaGFubmVscyA9IDI7CiAgfQoKICAvKiBHZXQgY2hhbm5lbCBlbGVtZW50IHNlcXVlbmNlIHRhYmxlICovCiAgbGlzdCA9IGdldEJpdHN0cmVhbUVsZW1lbnRMaXN0KGFvdCwgZXBDb25maWcsIG51bWJlck9mQ2hhbm5lbHMsIDApOwogIGlmIChsaXN0ID09IE5VTEwpIHsKICAgIGVycm9yID0gQUFDX0VOQ19VTlNVUFBPUlRFRF9BT1Q7CiAgICBnb3RvIGJhaWw7CiAgfQoKICBpZiAoIShzeW50YXhGbGFncyAmIChBQ19TQ0FMQUJMRXxBQ19FUikpKSB7CiAgICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBwRWxJbmZvLT5lbFR5cGUsIEVMX0lEX0JJVFMpOwogICAgfQogICAgYml0RGVtYW5kICs9IEVMX0lEX0JJVFM7CiAgfQoKICAvKiBJdGVyYXRlIHRocm91Z2ggc2VxdWVuY2UgdGFibGUgKi8KICBpID0gMDsKICBjaCA9IDA7CiAgZGVjaXNpb25fYml0ID0gMDsKICBkbyB7CiAgICAvKiBzb21lIHRtcCB2YWx1ZXMgKi8KICAgIFNFQ1RJT05fREFUQSAqcENoU2VjdGlvbkRhdGEgPSBOVUxMOwogICAgSU5UICAqcENoU2NmICAgICAgICAgICA9IE5VTEw7CiAgICBVSU5UICpwQ2hNYXhWYWx1ZUluU2ZiID0gTlVMTDsKICAgIFROU19JTkZPICpwVG5zSW5mbyAgICAgPSBOVUxMOwogICAgSU5UICAgY2hHbG9iYWxHYWluICAgICA9IDA7CiAgICBJTlQgICBjaEJsb2NrVHlwZSAgICAgID0gMDsKICAgIElOVCAgIGNoTWF4U2ZiUGVyR3JwICAgPSAwOwogICAgSU5UICAgY2hTZmJQZXJHcnAgICAgICA9IDA7CiAgICBJTlQgICBjaFNmYkNudCAgICAgICAgID0gMDsKICAgIElOVCAgIGNoRmlyc3RTY2YgICAgICAgPSAwOwoKICAgIGlmIChtaW5DbnQ9PTApIHsKICAgICAgaWYgKCBxY091dENoYW5uZWwhPU5VTEwgKSB7CiAgICAgICAgcENoU2VjdGlvbkRhdGEgICA9ICYocWNPdXRDaGFubmVsW2NoXS0+c2VjdGlvbkRhdGEpOwogICAgICAgIHBDaFNjZiAgICAgICAgICAgPSAgcWNPdXRDaGFubmVsW2NoXS0+c2NmOwogICAgICAgIGNoR2xvYmFsR2FpbiAgICAgPSAgcWNPdXRDaGFubmVsW2NoXS0+Z2xvYmFsR2FpbjsKICAgICAgICBwQ2hNYXhWYWx1ZUluU2ZiID0gIHFjT3V0Q2hhbm5lbFtjaF0tPm1heFZhbHVlSW5TZmI7CiAgICAgICAgY2hCbG9ja1R5cGUgICAgICA9ICBwQ2hTZWN0aW9uRGF0YS0+YmxvY2tUeXBlOwogICAgICAgIGNoTWF4U2ZiUGVyR3JwICAgPSAgcENoU2VjdGlvbkRhdGEtPm1heFNmYlBlckdyb3VwOwogICAgICAgIGNoU2ZiUGVyR3JwICAgICAgPSAgcENoU2VjdGlvbkRhdGEtPnNmYlBlckdyb3VwOwogICAgICAgIGNoU2ZiQ250ICAgICAgICAgPSAgcENoU2VjdGlvbkRhdGEtPnNmYkNudDsKICAgICAgICBjaEZpcnN0U2NmICAgICAgID0gIHBDaFNjZltwQ2hTZWN0aW9uRGF0YS0+Zmlyc3RTY2ZdOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8qIGdldCB2YWx1ZXMgZnJvbSBQU1kgKi8KICAgICAgICBjaFNmYkNudCAgICAgICA9IHBzeU91dENoYW5uZWxbY2hdLT5zZmJDbnQ7CiAgICAgICAgY2hTZmJQZXJHcnAgICAgPSBwc3lPdXRDaGFubmVsW2NoXS0+c2ZiUGVyR3JvdXA7CiAgICAgICAgY2hNYXhTZmJQZXJHcnAgPSBwc3lPdXRDaGFubmVsW2NoXS0+bWF4U2ZiUGVyR3JvdXA7CiAgICAgIH0KICAgICAgcFRuc0luZm8gPSAmcHN5T3V0Q2hhbm5lbFtjaF0tPnRuc0luZm87CiAgICB9IC8qIG1pbkNudD09MCAqLwoKICAgIGlmICggcWNPdXRDaGFubmVsPT1OVUxMICkgewogICAgICBjaEJsb2NrVHlwZSAgICA9IHBzeU91dENoYW5uZWxbY2hdLT5sYXN0V2luZG93U2VxdWVuY2U7CiAgICB9CgogICAgc3dpdGNoIChsaXN0LT5pZFtpXSkKICAgIHsKICAgIGNhc2UgZWxlbWVudF9pbnN0YW5jZV90YWc6CiAgICAgIC8qIFdyaXRlIGVsZW1lbnQgaW5zdGFuY2UgdGFnICovCiAgICAgIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgcEVsSW5mby0+aW5zdGFuY2VUYWcsIDQpOwogICAgICB9CiAgICAgIGJpdERlbWFuZCArPSA0OwogICAgICBicmVhazsKCiAgICBjYXNlIGNvbW1vbl93aW5kb3c6CiAgICAgIC8qIFdyaXRlIGNvbW1vbiB3aW5kb3cgZmxhZyAqLwogICAgICBkZWNpc2lvbl9iaXQgPSBwc3lPdXRFbGVtZW50LT5jb21tb25XaW5kb3c7CiAgICAgIGlmIChoQml0U3RyZWFtICE9IE5VTEwpIHsKICAgICAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgcHN5T3V0RWxlbWVudC0+Y29tbW9uV2luZG93LCAxKTsKICAgICAgfQogICAgICBiaXREZW1hbmQgKz0gMTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBpY3NfaW5mbzoKICAgICAgLyogV3JpdGUgaW5kaXZpZHVhbCBjaGFubmVsIGluZm8gKi8KICAgICAgYml0RGVtYW5kICs9IEZES2FhY0VuY19lbmNvZGVJY3NJbmZvKCBjaEJsb2NrVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+d2luZG93U2hhcGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPmdyb3VwaW5nTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaE1heFNmYlBlckdycCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQml0U3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBsdHBfZGF0YV9wcmVzZW50OgogICAgICAvKiBXcml0ZSBMVFAgZGF0YSBwcmVzZW50IGZsYWcgKi8KICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCAwLCAxKTsKICAgICAgfQogICAgICBiaXREZW1hbmQgKz0gMTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBsdHBfZGF0YToKICAgICAgLyogUHJlZGljdG9yIGRhdGEgbm90IHN1cHBvcnRlZC4KICAgICAgICAgTm90aGluZyB0byBkbyBoZXJlLiAqLwogICAgICBicmVhazsKCiAgICBjYXNlIG1zOgogICAgICAvKiBXcml0ZSBNUyBpbmZvICovCiAgICAgIGJpdERlbWFuZCArPSBGREthYWNFbmNfZW5jb2RlTVNJbmZvKCBjaFNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoU2ZiUGVyR3JwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hNYXhTZmJQZXJHcnAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWluQ250PT0wKSA/IHBzeU91dEVsZW1lbnQtPnRvb2xzSW5mby5tc0RpZ2VzdCA6IE1TX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRFbGVtZW50LT50b29sc0luZm8ubXNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJpdFN0cmVhbSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgZ2xvYmFsX2dhaW46CiAgICAgIGJpdERlbWFuZCArPSBGREthYWNFbmNfZW5jb2RlR2xvYmFsR2FpbiggY2hHbG9iYWxHYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoRmlyc3RTY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJpdFN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bWRjdFNjYWxlICk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2Ugc2VjdGlvbl9kYXRhOgogICAgICB7CiAgICAgICAgSU5UIHNpQml0cyA9IEZES2FhY0VuY19lbmNvZGVTZWN0aW9uRGF0YShwQ2hTZWN0aW9uRGF0YSwgaEJpdFN0cmVhbSwgKHN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpPzE6MCk7CiAgICAgICAgaWYgKGhCaXRTdHJlYW0gIT0gTlVMTCkgewogICAgICAgICAgaWYgKHNpQml0cyAhPSBxY091dENoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5zaWRlSW5mb0JpdHMpIHsKICAgICAgICAgICAgZXJyb3IgPSBBQUNfRU5DX1dSSVRFX1NFQ19FUlJPUjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYml0RGVtYW5kICs9IHNpQml0czsKICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIHNjYWxlX2ZhY3Rvcl9kYXRhOgogICAgICB7CiAgICAgICAgSU5UIHNmRGF0YUJpdHMgPSBGREthYWNFbmNfZW5jb2RlU2NhbGVGYWN0b3JEYXRhKCBwQ2hNYXhWYWx1ZUluU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcENoU2VjdGlvbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ2hTY2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQml0U3RyZWFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPm5vaXNlTnJnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPmlzU2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaEdsb2JhbEdhaW4gKTsKICAgICAgICBpZiAoIChoQml0U3RyZWFtICE9IE5VTEwpCiAgICAgICAgICAmJiAoc2ZEYXRhQml0cyAhPSAocWNPdXRDaGFubmVsW2NoXS0+c2VjdGlvbkRhdGEuc2NhbGVmYWNCaXRzICsgcWNPdXRDaGFubmVsW2NoXS0+c2VjdGlvbkRhdGEubm9pc2VOcmdCaXRzKSkgKSB7CiAgICAgICAgICAgZXJyb3IgPSBBQUNfRU5DX1dSSVRFX1NDQUxfRVJST1I7CiAgICAgICAgfQogICAgICAgIGJpdERlbWFuZCArPSBzZkRhdGFCaXRzOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgZXNjMl9ydmxjOgogICAgICBpZiAoc3ludGF4RmxhZ3MgJiBBQ19FUl9SVkxDKSB7CiAgICAgICAgLyogd3JpdGUgUlZMQyBkYXRhIGludG8gYml0c3RyZWFtIChlcnJvciBzZW5zLiBjYXQuIDIpICovCiAgICAgICAgZXJyb3IgPSBBQUNfRU5DX1VOU1VQUE9SVEVEX0FPVDsKICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIHB1bHNlOgogICAgICAvKiBXcml0ZSBwdWxzZSBkYXRhICovCiAgICAgIGJpdERlbWFuZCArPSBGREthYWNFbmNfZW5jb2RlUHVsc2VEYXRhKGhCaXRTdHJlYW0pOwogICAgICBicmVhazsKCiAgICBjYXNlIHRuc19kYXRhX3ByZXNlbnQ6CiAgICAgIC8qIFdyaXRlIFROUyBkYXRhIHByZXNlbnQgZmxhZyAqLwogICAgICBiaXREZW1hbmQgKz0gRkRLYWFjRW5jX2VuY29kZVRuc0RhdGFQcmVzZW50KHBUbnNJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoQmxvY2tUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCaXRTdHJlYW0pOwogICAgICBicmVhazsKICAgIGNhc2UgdG5zX2RhdGE6CiAgICAgIC8qIFdyaXRlIFROUyBkYXRhICovCiAgICAgIGJpdERlbWFuZCArPSBGREthYWNFbmNfZW5jb2RlVG5zRGF0YShwVG5zSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoQmxvY2tUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJpdFN0cmVhbSk7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgZ2Fpbl9jb250cm9sX2RhdGE6CiAgICAgIC8qIE5vdGhpbmcgdG8gZG8gaGVyZSAqLwogICAgICBicmVhazsKCiAgICBjYXNlIGdhaW5fY29udHJvbF9kYXRhX3ByZXNlbnQ6CiAgICAgIGJpdERlbWFuZCArPSBGREthYWNFbmNfZW5jb2RlR2FpbkNvbnRyb2xEYXRhKGhCaXRTdHJlYW0pOwogICAgICBicmVhazsKCgogICAgY2FzZSBlc2MxX2hjcjoKICAgICAgaWYgKHN5bnRheEZsYWdzICYgQUNfRVJfSENSKQogICAgICB7CiAgICAgICAgZXJyb3IgPSBBQUNfRU5DX1VOS05PV047CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgY2FzZSBzcGVjdHJhbF9kYXRhOgogICAgICBpZiAoaEJpdFN0cmVhbSAhPSBOVUxMKQogICAgICB7CiAgICAgICAgSU5UIHNwZWN0cmFsQml0cyA9IDA7CgogICAgICAgICAgc3BlY3RyYWxCaXRzID0gRkRLYWFjRW5jX2VuY29kZVNwZWN0cmFsRGF0YSggcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYk9mZnNldHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ2hTZWN0aW9uRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0Q2hhbm5lbFtjaF0tPnF1YW50U3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhCaXRTdHJlYW0gKTsKCiAgICAgICAgaWYgKHNwZWN0cmFsQml0cyAhPSBxY091dENoYW5uZWxbY2hdLT5zZWN0aW9uRGF0YS5odWZmbWFuQml0cykgewogICAgICAgICAgcmV0dXJuIEFBQ19FTkNfV1JJVEVfU1BFQ19FUlJPUjsKICAgICAgICB9CiAgICAgICAgYml0RGVtYW5kICs9IHNwZWN0cmFsQml0czsKICAgICAgfQogICAgICBicmVhazsKCiAgICAgIC8qIE5vbiBkYXRhIGNhc2VzICovCiAgICBjYXNlIGFkdHNjcmNfc3RhcnRfcmVnMToKICAgICAgaWYgKGhUcEVuYyAhPSBOVUxMKSB7CiAgICAgICAgY3JjUmVnMSA9IHRyYW5zcG9ydEVuY19DcmNTdGFydFJlZyhoVHBFbmMsIDE5Mik7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIGFkdHNjcmNfc3RhcnRfcmVnMjoKICAgICAgaWYgKGhUcEVuYyAhPSBOVUxMKSB7CiAgICAgICAgY3JjUmVnMiA9IHRyYW5zcG9ydEVuY19DcmNTdGFydFJlZyhoVHBFbmMsIDEyOCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIGFkdHNjcmNfZW5kX3JlZzE6CiAgICBjYXNlIGRybWNyY19lbmRfcmVnOgogICAgICBpZiAoaFRwRW5jICE9IE5VTEwpIHsKICAgICAgICB0cmFuc3BvcnRFbmNfQ3JjRW5kUmVnKGhUcEVuYywgY3JjUmVnMSk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIGFkdHNjcmNfZW5kX3JlZzI6CiAgICAgIGlmIChoVHBFbmMgIT0gTlVMTCkgewogICAgICAgIHRyYW5zcG9ydEVuY19DcmNFbmRSZWcoaFRwRW5jLCBjcmNSZWcyKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgZHJtY3JjX3N0YXJ0X3JlZzoKICAgICAgaWYgKGhUcEVuYyAhPSBOVUxMKSB7CiAgICAgICAgY3JjUmVnMSA9IHRyYW5zcG9ydEVuY19DcmNTdGFydFJlZyhoVHBFbmMsIDApOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBuZXh0X2NoYW5uZWw6CiAgICAgIGNoID0gKGNoICsgMSkgJSBudW1iZXJPZkNoYW5uZWxzOwogICAgICBicmVhazsKICAgIGNhc2UgbGlua19zZXF1ZW5jZToKICAgICAgbGlzdCA9IGxpc3QtPm5leHRbZGVjaXNpb25fYml0XTsKICAgICAgaT0tMTsKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgZXJyb3IgPSBBQUNfRU5DX1VOS05PV047CiAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChlcnJvciAhPSBBQUNfRU5DX09LKSB7CiAgICAgIHJldHVybiBlcnJvcjsKICAgIH0KCiAgICBpKys7CgogIH0gd2hpbGUgKGxpc3QtPmlkW2ldICE9IGVuZF9vZl9zZXF1ZW5jZSk7CgpiYWlsOgogIGlmIChwQml0RGVtYW5kICE9IE5VTEwpIHsKICAgICpwQml0RGVtYW5kID0gYml0RGVtYW5kOwogIH0KCiAgcmV0dXJuIGVycm9yOwp9CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX1dyaXRlQml0c3RyZWFtKEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBTk5FTF9NQVBQSU5HICpjaGFubmVsTWFwcGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDX09VVCAqcWNPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUKiBwc3lPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRQ19TVEFURSAqcWNLZXJuZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgZXBDb25maWcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzID0gdHJhbnNwb3J0RW5jX0dldEJpdHN0cmVhbShoVHBFbmMpOwogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzID0gQUFDX0VOQ19PSzsKICBpbnQgICBpLCBuLCBkb0J5dGVBbGlnbiA9IDE7CiAgSU5UICAgYml0TWFya1VwOwogIElOVCAgIGZyYW1lQml0czsKICAvKiBHZXQgZmlyc3QgYml0IG9mIHJhdyBkYXRhIGJsb2NrLgogICAgIEluIGNhc2Ugb2YgQURUUytQQ0UsIEFVIHdvdWxkIHN0YXJ0IGF0IFBDRS4KICAgICBUaGlzIGlzIG9rYXkgYmVjYXVzZSBQQ0UgYXNzdXJlcyBhbGlnbm1lbnQuICovCiAgVUlOVCBhbGlnbkFuY2hvciA9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICBmcmFtZUJpdHMgPSBiaXRNYXJrVXAgPSBhbGlnbkFuY2hvcjsKCgogIC8qIENoYW5uZWwgZWxlbWVudCBsb29wICovCiAgZm9yIChpPTA7IGk8Y2hhbm5lbE1hcHBpbmctPm5FbGVtZW50czsgaSsrKSB7CgogICAgRUxFTUVOVF9JTkZPIGVsSW5mbyA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9baV07CiAgICBJTlQgZWxlbWVudFVzZWRCaXRzID0gMDsKCiAgICBzd2l0Y2ggKGVsSW5mby5lbFR5cGUpCiAgICB7CiAgICAgICAgY2FzZSBJRF9TQ0U6ICAgICAgLyogc2luZ2xlIGNoYW5uZWwgKi8KICAgICAgICBjYXNlIElEX0NQRTogICAgICAvKiBjaGFubmVsIHBhaXIgKi8KICAgICAgICBjYXNlIElEX0xGRTogICAgICAvKiBsb3cgZnJlcSBlZmZlY3RzIGNoYW5uZWwgKi8KICAgICAgICB7CiAgICAgICAgICBpZiAoIEFBQ19FTkNfT0sgIT0gKEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0NoYW5uZWxFbGVtZW50V3JpdGUoIGhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFjT3V0LT5xY0VsZW1lbnRbaV0tPnFjT3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dC0+cHN5T3V0RWxlbWVudFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dC0+cHN5T3V0RWxlbWVudFtpXS0+cHN5T3V0Q2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzLCAgIC8qIHN5bnRheEZsYWdzIChFUiB0b29scyAuLi4pICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhb3QsICAgICAgICAgICAvKiBhb3Q6IEFPVF9BQUNfTEMsIEFPVF9TQlIsIEFPVF9QUyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBDb25maWcsICAgICAgLyogZXBDb25maWcgLTEsIDAsIDEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwICkpICkKICAgICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEVycm9yU3RhdHVzOwogICAgICAgICAgfQoKICAgICAgICAgIGlmICggIShzeW50YXhGbGFncyAmIEFDX0VSKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIFdyaXRlIGFzc29jaWF0ZWQgZXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgICAgICAgICAgZm9yIChuID0gMDsgbiA8IHFjT3V0LT5xY0VsZW1lbnRbaV0tPm5FeHRlbnNpb25zOyBuKyspIHsKICAgICAgICAgICAgICBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25EYXRhKCBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXQtPnFjRWxlbWVudFtpXS0+ZXh0ZW5zaW9uW25dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25BbmNob3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGF4RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwQ29uZmlnICk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qIEluIEZESywgRFNFIHNpZ25hbGxpbmcgZXhwbGljaXQgZG9uZSBpbiBlbERTRS4gU2VlIGNoYW5uZWxfbWFwLmNwcCAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gQUFDX0VOQ19JTlZBTElEX0VMRU1FTlRJTkZPX1RZUEU7CgogICAgfSAgIC8qIHN3aXRjaCAqLwoKICAgIGlmKGVsSW5mby5lbFR5cGUgIT0gSURfRFNFKSB7CiAgICAgIGVsZW1lbnRVc2VkQml0cyAtPSBiaXRNYXJrVXA7CiAgICAgIGJpdE1hcmtVcCAgICAgICAgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKICAgICAgZWxlbWVudFVzZWRCaXRzICs9IGJpdE1hcmtVcDsKICAgICAgZnJhbWVCaXRzICAgICAgICs9IGVsZW1lbnRVc2VkQml0czsKICAgIH0KCiAgfSAvKiBmb3IgKGk9MDsgaTxjaGFubmVsTWFwcGluZy5uRWxlbWVudHM7IGkrKykgKi8KCiAgaWYgKCAoc3ludGF4RmxhZ3MgJiBBQ19FUikgJiYgIShzeW50YXhGbGFncyAmIEFDX0RSTSkgKQogIHsKICAgIFVDSEFSIGNoYW5uZWxFbGVtZW50RXh0ZW5zaW9uV3JpdHRlblsoNildWygxKV07IC8qIDA6IGV4dGVuc2lvbiBub3QgdG91Y2hlZCwgMTogZXh0ZW5zaW9uIGFscmVhZHkgd3JpdHRlbiAqLwoKICAgIEZES21lbWNsZWFyKGNoYW5uZWxFbGVtZW50RXh0ZW5zaW9uV3JpdHRlbiwgc2l6ZW9mKGNoYW5uZWxFbGVtZW50RXh0ZW5zaW9uV3JpdHRlbikpOwoKICAgIGlmICggc3ludGF4RmxhZ3MgJiBBQ19FTEQgKSB7CgogICAgICBmb3IgKGk9MDsgaTxjaGFubmVsTWFwcGluZy0+bkVsZW1lbnRzOyBpKyspIHsKICAgICAgICBmb3IgKG4gPSAwOyBuIDwgcWNPdXQtPnFjRWxlbWVudFtpXS0+bkV4dGVuc2lvbnM7IG4rKykgewoKICAgICAgICAgIGlmICggKHFjT3V0LT5xY0VsZW1lbnRbaV0tPmV4dGVuc2lvbltuXS50eXBlPT1FWFRfU0JSX0RBVEEpCiAgICAgICAgICAgIHx8IChxY091dC0+cWNFbGVtZW50W2ldLT5leHRlbnNpb25bbl0udHlwZT09RVhUX1NCUl9EQVRBX0NSQykgKQogICAgICAgICAgewogICAgICAgICAgICAvKiBXcml0ZSBzYnIgZXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgICAgICAgICAgRkRLYWFjRW5jX3dyaXRlRXh0ZW5zaW9uRGF0YSggaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZxY091dC0+cWNFbGVtZW50W2ldLT5leHRlbnNpb25bbl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduQW5jaG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcENvbmZpZyApOwoKICAgICAgICAgICAgY2hhbm5lbEVsZW1lbnRFeHRlbnNpb25Xcml0dGVuW2ldW25dID0gMTsKICAgICAgICAgIH0gLyogU0JSICovCiAgICAgICAgfSAvKiBuICovCiAgICAgIH0gLyogaSAqLwogICAgfSAvKiBBQ19FTEQgKi8KCiAgICBmb3IgKGk9MDsgaTxjaGFubmVsTWFwcGluZy0+bkVsZW1lbnRzOyBpKyspIHsKICAgICAgZm9yIChuID0gMDsgbiA8IHFjT3V0LT5xY0VsZW1lbnRbaV0tPm5FeHRlbnNpb25zOyBuKyspIHsKCiAgICAgICAgaWYgKGNoYW5uZWxFbGVtZW50RXh0ZW5zaW9uV3JpdHRlbltpXVtuXT09MCkKICAgICAgICB7CiAgICAgICAgICAvKiBXcml0ZSBhbGwgcmFtYWluaW5nIGV4dGVuc2lvbiBwYXlsb2FkcyBpbiBlbGVtZW50ICovCiAgICAgICAgICBGREthYWNFbmNfd3JpdGVFeHRlbnNpb25EYXRhKCBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZxY091dC0+cWNFbGVtZW50W2ldLT5leHRlbnNpb25bbl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ25BbmNob3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwQ29uZmlnICk7CiAgICAgICAgfQogICAgICB9IC8qIG4gKi8KICAgIH0gLyogaSAqLwogIH0gLyogaWYgQUNfRVIgKi8KCiAgLyogRXh0ZW5kIGdsb2JhbCBleHRlbnNpb24gcGF5bG9hZCB0YWJsZSB3aXRoIGZpbGwgYml0cyAqLwogIGlmICggc3ludGF4RmxhZ3MgJiBBQ19EUk0gKQogIHsKICAgIC8qIEV4Y2VwdGlvbiBmb3IgRHJtICovCiAgICBmb3IgKG4gPSAwOyBuIDwgcWNPdXQtPm5FeHRlbnNpb25zOyBuKyspIHsKICAgICAgaWYgKCAocWNPdXQtPmV4dGVuc2lvbltuXS50eXBlID09IEVYVF9TQlJfREFUQSkKICAgICAgICB8fCAocWNPdXQtPmV4dGVuc2lvbltuXS50eXBlID09IEVYVF9TQlJfREFUQV9DUkMpICkgewogICAgICAgIC8qIFNCUiBkYXRhIG11c3QgYmUgdGhlIGxhc3QgZXh0ZW5zaW9uISAqLwogICAgICAgIEZES21lbWNweSgmcWNPdXQtPmV4dGVuc2lvbltxY091dC0+bkV4dGVuc2lvbnNdLCAmcWNPdXQtPmV4dGVuc2lvbltuXSwgc2l6ZW9mKFFDX09VVF9FWFRFTlNJT04pKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgLyogRG8gYnl0ZSBhbGlnbm1lbnQgYWZ0ZXIgQUFDICgrIE1QUykgcGF5bG9hZC4KICAgICAgIEFzc3VyZSB0aGF0IE1QUyBoYXMgYmVlbiB3cml0dGVuIGFzIGNoYW5uZWwgYXNzaWduZWQgZXh0ZW5zaW9uIHBheWxvYWQhICovCiAgICBpZiAoKChGREtnZXRWYWxpZEJpdHMoaEJzKS1hbGlnbkFuY2hvcisoVUlOVClxY091dC0+dG90RmlsbEJpdHMpJjB4NykhPShVSU5UKXFjT3V0LT5hbGlnbkJpdHMpIHsKICAgICAgcmV0dXJuIEFBQ19FTkNfV1JJVFRFTl9CSVRTX0VSUk9SOwogICAgfQogICAgRkRLYWFjRW5jX0J5dGVBbGlnbm1lbnQoaEJzLCBxY091dC0+YWxpZ25CaXRzKTsKICAgIGRvQnl0ZUFsaWduID0gMDsKCiAgfSAvKiBBQ19EUk0gKi8KCiAgLyogQWRkIGZpbGwgZGF0YSAvIHN0dWZmaW5nIGJpdHMgKi8KICBuID0gcWNPdXQtPm5FeHRlbnNpb25zOwogIHFjT3V0LT5leHRlbnNpb25bbl0udHlwZSA9IEVYVF9GSUxMX0RBVEE7CiAgcWNPdXQtPmV4dGVuc2lvbltuXS5uUGF5bG9hZEJpdHMgPSBxY091dC0+dG90RmlsbEJpdHM7CiAgcWNPdXQtPm5FeHRlbnNpb25zKys7CgogIC8qIFdyaXRlIGdsb2JhbCBleHRlbnNpb24gcGF5bG9hZCBhbmQgZmlsbCBkYXRhICovCiAgZm9yIChuID0gMDsgKG4gPCBxY091dC0+bkV4dGVuc2lvbnMpICYmIChuIDwgKDIrMikpOyBuKyspCiAgewogICAgRkRLYWFjRW5jX3dyaXRlRXh0ZW5zaW9uRGF0YSggaFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcWNPdXQtPmV4dGVuc2lvbltuXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlnbkFuY2hvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRheEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBDb25maWcgKTsKCiAgICAvKiBGb3IgRVhUX0ZJTCBvciBFWFRfRklMTF9EQVRBIHdlIGNvdWxkIGRvIGFuIGFkZGl0aW9uYWwgc2FuaXR5IGNoZWNrIGhlcmUgKi8KICB9CgogIGlmICghKHN5bnRheEZsYWdzICYgKEFDX1NDQUxBQkxFfEFDX0VSKSkpIHsKICAgIEZES3dyaXRlQml0cyhoQnMsIElEX0VORCwgRUxfSURfQklUUyk7CiAgfQoKICBpZiAoZG9CeXRlQWxpZ24pIHsKICAgIC8qIEFzc3VyZSBieXRlIGFsaWdubWVudCovCiAgICBpZiAoKChhbGlnbkFuY2hvci1GREtnZXRWYWxpZEJpdHMoaEJzKSkmMHg3KSE9KFVJTlQpcWNPdXQtPmFsaWduQml0cykgewogICAgICByZXR1cm4gQUFDX0VOQ19XUklUVEVOX0JJVFNfRVJST1I7CiAgICB9CgogICAgRkRLYWFjRW5jX0J5dGVBbGlnbm1lbnQoaEJzLCBxY091dC0+YWxpZ25CaXRzKTsKICB9CgogIGZyYW1lQml0cyAtPSBiaXRNYXJrVXA7CiAgZnJhbWVCaXRzICs9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICB0cmFuc3BvcnRFbmNfRW5kQWNjZXNzVW5pdChoVHBFbmMsICZmcmFtZUJpdHMpOwoKICBpZiAoZnJhbWVCaXRzICE9IHFjT3V0LT50b3RhbEJpdHMgKyBxY0tlcm5lbC0+Z2xvYkhkckJpdHMpewogICAgcmV0dXJuIEFBQ19FTkNfV1JJVFRFTl9CSVRTX0VSUk9SOwogIH0KCiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9Cgo=