Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgRkRLIEZpeGVkIFBvaW50IEFyaXRobWV0aWMgTGlicmFyeSBJbnRlcmZhY2UgIAoqLwoKI2lmbmRlZiBfX1RSQU5TQ0VOREVOVF9ICiNkZWZpbmUgX19UUkFOU0NFTkRFTlRfSAoKI2luY2x1ZGUgInNicmRlY29kZXIuaCIKI2luY2x1ZGUgInNicl9yb20uaCIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgIEdldCBudW1iZXIgb2Ygb2N0YXZlcyBiZXR3ZWVuIGZyZXF1ZW5jaWVzIGEgYW5kIGIKCiAgVGhlIFJlc3VsdCBpcyBzY2FsZWQgd2l0aCAxLzguCiAgVGhlIHZhbGlkIHJhbmdlIGZvciBhIGFuZCBiIGlzIDEgdG8gTE9HX0RVQUxJU19UQUJMRV9TSVpFLgoKICBccmV0dXJuICAgbGQoYS9iKSAvIDgKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSBGSVhQX1NHTCBGREtfZ2V0TnVtT2N0YXZlc0RpdjgoSU5UIGEsIC8qITwgbG93ZXIgYmFuZCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgYikgLyohPCB1cHBlciBiYW5kICovCnsKICByZXR1cm4gKCAoU0hPUlQpKChMT05HKShDYWxjTGRJbnQoYikgLSBDYWxjTGRJbnQoYSkpPj4oRlJBQ1RfQklUUy0zKSkgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgIEFkZCB0d28gdmFsdWVzIGdpdmVuIGJ5IG1hbnRpc3NhIGFuZCBleHBvbmVudC4KCiAgTWFudGlzc2FzIGFyZSBpbiBmcmFjdCBmb3JtYXQgd2l0aCB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxLiA8YnI+CiAgVGhlIGJhc2UgZm9yIGV4cG9uZW50cyBpcyAyLiAgRXhhbXBsZTogIFxmJCAgYSA9IGFcX20gKiAyXnthXF9lfSAgXGYkPGJyPgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwppbmxpbmUgdm9pZCBGREtfYWRkX01hbnRFeHAoRklYUF9TR0wgYV9tLCAvKiE8IE1hbnRpc3NhIG9mIDFzdCBvcGVyYW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgIGFfZSwgICAgICAgLyohPCBFeHBvbmVudCBvZiAxc3Qgb3BlcmFuZCBhICovCiAgICAgICAgICAgICAgICAgICAgIEZJWFBfU0dMICBiX20sICAgICAgIC8qITwgTWFudGlzc2Egb2YgMm5kIG9wZXJhbmQgYiAqLwogICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgYl9lLCAgICAgICAvKiE8IEV4cG9uZW50IG9mIDJuZCBvcGVyYW5kIGIgKi8KICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wgKnB0clN1bV9tLCAgLyohPCBNYW50aXNzYSBvZiByZXN1bHQgKi8KICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgKnB0clN1bV9lKSAgLyohPCBFeHBvbmVudCBvZiByZXN1bHQgKi8KewogIEZJWFBfREJMIGFjY3U7CiAgaW50ICAgc2hpZnQ7CiAgaW50ICAgc2hpZnRBYnM7CgogIEZJWFBfREJMIHNoaWZ0ZWRNYW50aXNzYTsKICBGSVhQX0RCTCBvdGhlck1hbnRpc3NhOwoKICAvKiBFcXVhbGl6ZSBleHBvbmVudHMgb2YgdGhlIHN1bW1hbmRzLgogICAgIEZvciB0aGUgc21hbGxlciBzdW1tYW5kLCB0aGUgZXhwb25lbnQgaXMgYWRhcHRlZCBhbmQKICAgICBmb3IgY29tcGVuc2F0aW9uLCB0aGUgbWFudGlzc2EgaXMgc2hpZnRlZCByaWdodC4gKi8KCiAgc2hpZnQgPSAoaW50KShhX2UgLSBiX2UpOwoKICBzaGlmdEFicyA9IChzaGlmdD4wKT8gc2hpZnQgOiAtc2hpZnQ7CiAgc2hpZnRBYnMgPSAoc2hpZnRBYnMgPCBERlJBQ1RfQklUUy0xKT8gc2hpZnRBYnMgOiBERlJBQ1RfQklUUy0xOwogIHNoaWZ0ZWRNYW50aXNzYSA9IChzaGlmdD4wKT8gKEZYX1NHTDJGWF9EQkwoYl9tKSA+PiBzaGlmdEFicykgOiAoRlhfU0dMMkZYX0RCTChhX20pID4+IHNoaWZ0QWJzKTsKICBvdGhlck1hbnRpc3NhID0gKHNoaWZ0PjApPyBGWF9TR0wyRlhfREJMKGFfbSkgOiBGWF9TR0wyRlhfREJMKGJfbSk7CiAgKnB0clN1bV9lID0gKHNoaWZ0PjApPyBhX2UgOiBiX2U7CgogIGFjY3UgPSAoc2hpZnRlZE1hbnRpc3NhID4+IDEpICsgKG90aGVyTWFudGlzc2EgPj4gMSk7CiAgLyogc2hpZnQgYnkgMSBiaXQgdG8gYXZvaWQgb3ZlcmZsb3cgKi8KCiAgaWYgKCAoYWNjdSA+PSAoRkwyRlhDT05TVF9EQkwoMC41ZikgLSAoRklYUF9EQkwpMSkpIHx8IChhY2N1IDw9IEZMMkZYQ09OU1RfREJMKC0wLjVmKSkgKQogICAgKnB0clN1bV9lICs9IDE7CiAgZWxzZQogICAgYWNjdSA9IChzaGlmdGVkTWFudGlzc2EgKyBvdGhlck1hbnRpc3NhKTsKCiAgKnB0clN1bV9tID0gRlhfREJMMkZYX1NHTChhY2N1KTsKCn0KCmlubGluZSB2b2lkIEZES19hZGRfTWFudEV4cChGSVhQX0RCTCBhLCAgIC8qITwgTWFudGlzc2Egb2YgMXN0IG9wZXJhbmQgYSAqLwogICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgYV9lLCAgICAgICAvKiE8IEV4cG9uZW50IG9mIDFzdCBvcGVyYW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgIGIsICAgICAgICAgLyohPCBNYW50aXNzYSBvZiAybmQgb3BlcmFuZCBiICovCiAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICBiX2UsICAgICAgIC8qITwgRXhwb25lbnQgb2YgMm5kIG9wZXJhbmQgYiAqLwogICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqcHRyU3VtLCAgICAvKiE8IE1hbnRpc3NhIG9mIHJlc3VsdCAqLwogICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAqcHRyU3VtX2UpICAvKiE8IEV4cG9uZW50IG9mIHJlc3VsdCAqLwp7CiAgRklYUF9EQkwgYWNjdTsKICBpbnQgICBzaGlmdDsKICBpbnQgICBzaGlmdEFiczsKCiAgRklYUF9EQkwgc2hpZnRlZE1hbnRpc3NhOwogIEZJWFBfREJMIG90aGVyTWFudGlzc2E7CgogIC8qIEVxdWFsaXplIGV4cG9uZW50cyBvZiB0aGUgc3VtbWFuZHMuCiAgICAgRm9yIHRoZSBzbWFsbGVyIHN1bW1hbmQsIHRoZSBleHBvbmVudCBpcyBhZGFwdGVkIGFuZAogICAgIGZvciBjb21wZW5zYXRpb24sIHRoZSBtYW50aXNzYSBpcyBzaGlmdGVkIHJpZ2h0LiAqLwoKICBzaGlmdCA9IChpbnQpKGFfZSAtIGJfZSk7CgogIHNoaWZ0QWJzID0gKHNoaWZ0PjApPyBzaGlmdCA6IC1zaGlmdDsKICBzaGlmdEFicyA9IChzaGlmdEFicyA8IERGUkFDVF9CSVRTLTEpPyBzaGlmdEFicyA6IERGUkFDVF9CSVRTLTE7CiAgc2hpZnRlZE1hbnRpc3NhID0gKHNoaWZ0PjApPyAoYiA+PiBzaGlmdEFicykgOiAoYSA+PiBzaGlmdEFicyk7CiAgb3RoZXJNYW50aXNzYSA9IChzaGlmdD4wKT8gYSA6IGI7CiAgKnB0clN1bV9lID0gKHNoaWZ0PjApPyBhX2UgOiBiX2U7CgogIGFjY3UgPSAoc2hpZnRlZE1hbnRpc3NhID4+IDEpICsgKG90aGVyTWFudGlzc2EgPj4gMSk7CiAgLyogc2hpZnQgYnkgMSBiaXQgdG8gYXZvaWQgb3ZlcmZsb3cgKi8KCiAgaWYgKCAoYWNjdSA+PSAoRkwyRlhDT05TVF9EQkwoMC41ZikgLSAoRklYUF9EQkwpMSkpIHx8IChhY2N1IDw9IEZMMkZYQ09OU1RfREJMKC0wLjVmKSkgKQogICAgKnB0clN1bV9lICs9IDE7CiAgZWxzZQogICAgYWNjdSA9IChzaGlmdGVkTWFudGlzc2EgKyBvdGhlck1hbnRpc3NhKTsKCiAgKnB0clN1bSA9IGFjY3U7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICBEaXZpZGUgdHdvIHZhbHVlcyBnaXZlbiBieSBtYW50aXNzYSBhbmQgZXhwb25lbnQuCgogIE1hbnRpc3NhcyBhcmUgaW4gZnJhY3QgZm9ybWF0IHdpdGggdmFsdWVzIGJldHdlZW4gMCBhbmQgMS4gPGJyPgogIFRoZSBiYXNlIGZvciBleHBvbmVudHMgaXMgMi4gIEV4YW1wbGU6ICBcZiQgIGEgPSBhXF9tICogMl57YVxfZX0gIFxmJDxicj4KCiAgRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMsIHRoZSBkaXZpc2lvbiBpcyBiYXNlZCBvbiBhIHRhYmxlIGxvb2t1cAogIHdoaWNoIGxpbWl0cyBhY2N1cmFjeS4KKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSB2b2lkIEZES19kaXZpZGVfTWFudEV4cChGSVhQX1NHTCBhX20sICAgICAgICAgICAvKiE8IE1hbnRpc3NhIG9mIGRpdmlkZW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgYV9lLCAgICAgICAgICAvKiE8IEV4cG9uZW50IG9mIGRpdmlkZW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX1NHTCAgYl9tLCAgICAgICAgICAvKiE8IE1hbnRpc3NhIG9mIGRpdmlzb3IgYiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICBiX2UsICAgICAgICAgIC8qITwgRXhwb25lbnQgb2YgZGl2aXNvciBiICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wgKnB0clJlc3VsdF9tLCAgLyohPCBNYW50aXNzYSBvZiBxdW90aWVudCBhL2IgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAqcHRyUmVzdWx0X2UpICAvKiE8IEV4cG9uZW50IG9mIHF1b3RpZW50IGEvYiAqLwoKewogIGludCBwcmVTaGlmdCwgcG9zdFNoaWZ0LCBpbmRleCwgc2hpZnQ7CiAgRklYUF9EQkwgcmF0aW9fbTsKICBGSVhQX1NHTCAgYkludl9tID0gRkwyRlhDT05TVF9TR0woMC4wZik7CgogIHByZVNoaWZ0ID0gQ250TGVhZGluZ1plcm9zKEZYX1NHTDJGWF9EQkwoYl9tKSk7CgogIC8qCiAgICBTaGlmdCBiIGludG8gdGhlIHJhbmdlIGZyb20gMC4uSU5WX1RBQkxFX1NJWkUtMSwKCiAgICBFLmcuIDEwIGJpdHMgbXVzdCBiZSBza2lwcGVkIGZvciBJTlZfVEFCTEVfQklUUyA4OgogICAgLSBsZWF2ZSA4IGJpdHMgYXMgaW5kZXggZm9yIHRhYmxlCiAgICAtIHNraXAgc2lnbiBiaXQsCiAgICAtIHNraXAgZmlyc3QgYml0IG9mIG1hbnRpc3NhLCBiZWNhdXNlIHRoaXMgaXMgYWx3YXlzIHRoZSBzYW1lICg+MC41KQoKICAgIFdlIGFyZSBkZWFsaW5nIHdpdGggZW5lcmdpZXMsIHNvIHdlIG5lZWQgbm90IGNhcmUKICAgIGFib3V0IG5lZ2F0aXZlIG51bWJlcnMKICAqLwoKICAvKgogICAgVGhlIGZpcnN0IGludGVydmFsIGhhcyBoYWxmIHdpZHRoIHNvIHRoZSBsb3dlc3QgYml0IG9mIHRoZSBpbmRleCBpcwogICAgbmVlZGVkIGZvciBhIGRvdWJsZWQgcmVzb2x1dGlvbi4KICAqLwogIHNoaWZ0ID0gKEZSQUNUX0JJVFMgLSAyIC0gSU5WX1RBQkxFX0JJVFMgLSBwcmVTaGlmdCk7CgogIGluZGV4ID0gKHNoaWZ0PDApPyAoTE9ORyliX20gPDwgKC1zaGlmdCkgOiAoTE9ORyliX20gPj4gc2hpZnQ7CgoKICAvKiBUaGUgaW5kZXggaGFzIElOVl9UQUJMRV9CSVRTICsxIHZhbGlkIGJpdHMgaGVyZS4gQ2xlYXIgdGhlIG90aGVyIGJpdHMuICovCiAgaW5kZXggJj0gKDEgPDwgKElOVl9UQUJMRV9CSVRTKzEpKSAtIDE7CgogICAgLyogUmVtb3ZlIG9mZnNldCBvZiBoYWxmIGFuIGludGVydmFsICovCiAgaW5kZXgtLTsKCiAgICAvKiBOb3cgdGhlIGxvd2VzdCBiaXQgaXMgc2hpZnRlZCBvdXQgKi8KICBpbmRleCA9IGluZGV4ID4+IDE7CgogICAgLyogRmV0Y2ggaW52ZXJzZWQgbWFudGlzc2EgZnJvbSB0YWJsZTogKi8KICBiSW52X20gPSAoaW5kZXg8MCk/IGJJbnZfbSA6IEZES19zYnJEZWNvZGVyX2ludlRhYmxlW2luZGV4XTsKCiAgICAvKiBNdWx0aXBseSBhIHdpdGggdGhlIGludmVyc2Ugb2YgYjogKi8KICByYXRpb19tID0gKGluZGV4PDApPyBGWF9TR0wyRlhfREJMKGFfbSA+PiAxKSA6IGZNdWx0RGl2MihiSW52X20sYV9tKTsKCiAgcG9zdFNoaWZ0ID0gQ250TGVhZGluZ1plcm9zKHJhdGlvX20pLTE7CgogICpwdHJSZXN1bHRfbSA9IEZYX0RCTDJGWF9TR0wocmF0aW9fbSA8PCBwb3N0U2hpZnQpOwogICpwdHJSZXN1bHRfZSA9IGFfZSAtIGJfZSArIDEgKyBwcmVTaGlmdCAtIHBvc3RTaGlmdDsKfQoKc3RhdGljIGlubGluZSB2b2lkIEZES19kaXZpZGVfTWFudEV4cChGSVhQX0RCTCBhX20sICAgICAgICAgICAvKiE8IE1hbnRpc3NhIG9mIGRpdmlkZW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAgYV9lLCAgICAgICAgICAvKiE8IEV4cG9uZW50IG9mIGRpdmlkZW5kIGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgYl9tLCAgICAgICAgICAvKiE8IE1hbnRpc3NhIG9mIGRpdmlzb3IgYiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNDSEFSICAgICBiX2UsICAgICAgICAgIC8qITwgRXhwb25lbnQgb2YgZGl2aXNvciBiICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnB0clJlc3VsdF9tLCAgLyohPCBNYW50aXNzYSBvZiBxdW90aWVudCBhL2IgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAqcHRyUmVzdWx0X2UpICAvKiE8IEV4cG9uZW50IG9mIHF1b3RpZW50IGEvYiAqLwoKewogIGludCBwcmVTaGlmdCwgcG9zdFNoaWZ0LCBpbmRleCwgc2hpZnQ7CiAgRklYUF9EQkwgcmF0aW9fbTsKICBGSVhQX1NHTCAgYkludl9tID0gRkwyRlhDT05TVF9TR0woMC4wZik7CgogIHByZVNoaWZ0ID0gQ250TGVhZGluZ1plcm9zKGJfbSk7CgogIC8qCiAgICBTaGlmdCBiIGludG8gdGhlIHJhbmdlIGZyb20gMC4uSU5WX1RBQkxFX1NJWkUtMSwKCiAgICBFLmcuIDEwIGJpdHMgbXVzdCBiZSBza2lwcGVkIGZvciBJTlZfVEFCTEVfQklUUyA4OgogICAgLSBsZWF2ZSA4IGJpdHMgYXMgaW5kZXggZm9yIHRhYmxlCiAgICAtIHNraXAgc2lnbiBiaXQsCiAgICAtIHNraXAgZmlyc3QgYml0IG9mIG1hbnRpc3NhLCBiZWNhdXNlIHRoaXMgaXMgYWx3YXlzIHRoZSBzYW1lICg+MC41KQoKICAgIFdlIGFyZSBkZWFsaW5nIHdpdGggZW5lcmdpZXMsIHNvIHdlIG5lZWQgbm90IGNhcmUKICAgIGFib3V0IG5lZ2F0aXZlIG51bWJlcnMKICAqLwoKICAvKgogICAgVGhlIGZpcnN0IGludGVydmFsIGhhcyBoYWxmIHdpZHRoIHNvIHRoZSBsb3dlc3QgYml0IG9mIHRoZSBpbmRleCBpcwogICAgbmVlZGVkIGZvciBhIGRvdWJsZWQgcmVzb2x1dGlvbi4KICAqLwogIHNoaWZ0ID0gKERGUkFDVF9CSVRTIC0gMiAtIElOVl9UQUJMRV9CSVRTIC0gcHJlU2hpZnQpOwoKICBpbmRleCA9IChzaGlmdDwwKT8gKExPTkcpYl9tIDw8ICgtc2hpZnQpIDogKExPTkcpYl9tID4+IHNoaWZ0OwoKCiAgLyogVGhlIGluZGV4IGhhcyBJTlZfVEFCTEVfQklUUyArMSB2YWxpZCBiaXRzIGhlcmUuIENsZWFyIHRoZSBvdGhlciBiaXRzLiAqLwogIGluZGV4ICY9ICgxIDw8IChJTlZfVEFCTEVfQklUUysxKSkgLSAxOwoKICAgIC8qIFJlbW92ZSBvZmZzZXQgb2YgaGFsZiBhbiBpbnRlcnZhbCAqLwogIGluZGV4LS07CgogICAgLyogTm93IHRoZSBsb3dlc3QgYml0IGlzIHNoaWZ0ZWQgb3V0ICovCiAgaW5kZXggPSBpbmRleCA+PiAxOwoKICAgIC8qIEZldGNoIGludmVyc2VkIG1hbnRpc3NhIGZyb20gdGFibGU6ICovCiAgYkludl9tID0gKGluZGV4PDApPyBiSW52X20gOiBGREtfc2JyRGVjb2Rlcl9pbnZUYWJsZVtpbmRleF07CgogICAgLyogTXVsdGlwbHkgYSB3aXRoIHRoZSBpbnZlcnNlIG9mIGI6ICovCiAgcmF0aW9fbSA9IChpbmRleDwwKT8gKGFfbSA+PiAxKSA6IGZNdWx0RGl2MihiSW52X20sYV9tKTsKCiAgcG9zdFNoaWZ0ID0gQ250TGVhZGluZ1plcm9zKHJhdGlvX20pLTE7CgogICpwdHJSZXN1bHRfbSA9IHJhdGlvX20gPDwgcG9zdFNoaWZ0OwogICpwdHJSZXN1bHRfZSA9IGFfZSAtIGJfZSArIDEgKyBwcmVTaGlmdCAtIHBvc3RTaGlmdDsKfQoKLyohCiAgXGJyaWVmICAgQ2FsY3VsYXRlIHRoZSBzcXVhcmVyb290IG9mIGEgbnVtYmVyIGdpdmVuIGJ5IG1hbnRpc3NhIGFuZCBleHBvbmVudAoKICBNYW50aXNzYSBpcyBpbiBmcmFjdCBmb3JtYXQgd2l0aCB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxLiA8YnI+CiAgVGhlIGJhc2UgZm9yIHRoZSBleHBvbmVudCBpcyAyLiAgRXhhbXBsZTogIFxmJCAgYSA9IGFcX20gKiAyXnthXF9lfSAgXGYkPGJyPgogIFRoZSBvcGVyYW5kIGlzIGFkZHJlc3NlZCB2aWEgcG9pbnRlcnMgYW5kIHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGUgcmVzdWx0LgoKICBGb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgdGhlIHNxdWFyZSByb290IGlzIGJhc2VkIG9uIGEgdGFibGUgbG9va3VwCiAgd2hpY2ggbGltaXRzIGFjY3VyYWN5LgoqLwpzdGF0aWMgaW5saW5lIHZvaWQgRkRLX3NxcnRfTWFudEV4cChGSVhQX0RCTCAqbWFudGlzc2EsICAgIC8qITwgUG9pbnRlciB0byBtYW50aXNzYSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiAgICAqZXhwb25lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNDSEFSICpkZXN0U2NhbGUpCnsKICBGSVhQX0RCTCBpbnB1dF9tID0gKm1hbnRpc3NhOwogIGludCAgIGlucHV0X2UgPSAoaW50KSAqZXhwb25lbnQ7CiAgRklYUF9EQkwgcmVzdWx0ID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgaW50ICAgIHJlc3VsdF9lID0gLUZSQUNUX0JJVFM7CgogIC8qIENhbGwgbG9va3VwIHNxdWFyZSByb290LCB3aGljaCBkb2VzIGludGVybmFsbHkgbm9ybWFsaXphdGlvbi4gKi8KICByZXN1bHQgICA9IHNxcnRGaXhwX2xvb2t1cChpbnB1dF9tLCAmaW5wdXRfZSk7CiAgcmVzdWx0X2UgPSBpbnB1dF9lOwoKICAvKiBXcml0ZSByZXN1bHQgKi8KICBpZiAoZXhwb25lbnQ9PWRlc3RTY2FsZSkgewogICAgKm1hbnRpc3NhID0gcmVzdWx0OwogICAgKmV4cG9uZW50ID0gcmVzdWx0X2U7CiAgfSBlbHNlIHsKICAgIGludCBzaGlmdCA9IHJlc3VsdF9lIC0gKmRlc3RTY2FsZTsKICAgICptYW50aXNzYSA9IChzaGlmdD49MCkgPyByZXN1bHQgPDwgKElOVClmaXhNaW4oREZSQUNUX0JJVFMtMSxzaGlmdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgOiByZXN1bHQgPj4gKElOVClmaXhNaW4oREZSQUNUX0JJVFMtMSwtc2hpZnQpOwogICAgKmV4cG9uZW50ID0gKmRlc3RTY2FsZTsKICB9Cn0KCgojZW5kaWYK