Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IGxvbmcvc2hvcnQtYmxvY2sgZGVjb2RpbmcKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJibG9jay5oIgoKI2luY2x1ZGUgImFhY19yb20uaCIKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKI2luY2x1ZGUgIkZES190b29sc19yb20uaCIKCgoKCiNpbmNsdWRlICJhYWNkZWNfaGNyLmgiCiNpbmNsdWRlICJydmxjLmgiCgoKI2lmIGRlZmluZWQoX19hcm1fXykKI2luY2x1ZGUgImFybS9ibG9ja19hcm0uY3BwIgojZW5kaWYKCi8qIQogIFxicmllZiBSZWFkIGVzY2FwZSBzZXF1ZW5jZSBvZiBjb2Rld29yZAoKICBUaGUgZnVuY3Rpb24gcmVhZHMgdGhlIGVzY2FwZSBzZXF1ZW5jZSBmcm9tIHRoZSBiaXRzdHJlYW0sCiAgaWYgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBxdWFudGl6ZWQgY29lZmZpY2llbnQgaGFzIHRoZQogIHZhbHVlIDE2LgoKICBccmV0dXJuICBxdWFudGl6ZWQgY29lZmZpY2llbnQKKi8KTE9ORyBDQmxvY2tfR2V0RXNjYXBlKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCAvKiE8IHBvaW50ZXIgdG8gYml0c3RyZWFtICovCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExPTkcgcSkgICAgICAgIC8qITwgcXVhbnRpemVkIGNvZWZmaWNpZW50ICovCnsKICBMT05HIGksIG9mZiwgbmVnIDsKCiAgaWYgKHEgPCAwKQogIHsKICAgIGlmIChxICE9IC0xNikgcmV0dXJuIHE7CiAgICBuZWcgPSAxOwogIH0KICBlbHNlCiAgewogICAgaWYgKHEgIT0gKzE2KSByZXR1cm4gcTsKICAgIG5lZyA9IDA7CiAgfQoKICBmb3IgKGk9NDsgOyBpKyspCiAgewogICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpID09IDApCiAgICAgIGJyZWFrOwogIH0KCiAgaWYgKGkgPiAxNikKICB7CiAgICBpZiAoaSAtIDE2ID4gQ0FDSEVfQklUUykgeyAvKiBjYW5ub3QgcmVhZCBtb3JlIHRoYW4gIkNBQ0hFX0JJVFMiIGJpdHMgYXQgb25jZSBpbiB0aGUgZnVuY3Rpb24gRkRLcmVhZEJpdHMoKSAqLwogICAgICByZXR1cm4gKE1BWF9RVUFOVElaRURfVkFMVUUgKyAxKTsgLyogcmV0dXJuaW5nIGludmFsaWQgdmFsdWUgdGhhdCB3aWxsIGJlIGNhcHR1cmVkIGxhdGVyICovCiAgICB9CgogICAgb2ZmID0gRkRLcmVhZEJpdHMoYnMsaS0xNikgPDwgMTY7CiAgICBvZmYgfD0gRkRLcmVhZEJpdHMoYnMsMTYpOwogIH0KICBlbHNlCiAgewogICAgb2ZmID0gRkRLcmVhZEJpdHMoYnMsaSk7CiAgfQoKICBpID0gb2ZmICsgKDEgPDwgaSk7CgogIGlmIChuZWcpIGkgPSAtaTsKCiAgcmV0dXJuIGk7Cn0KCkFBQ19ERUNPREVSX0VSUk9SIENCbG9ja19SZWFkU2NhbGVGYWN0b3JEYXRhKAogICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgVUlOVCBmbGFncwogICAgICAgICkKewogIGludCB0ZW1wOwogIGludCBiYW5kOwogIGludCBncm91cDsKICBpbnQgcG9zaXRpb24gPSAwOyAvKiBhY2N1IGZvciBpbnRlbnNpdHkgZGVsdGEgY29kaW5nICovCiAgaW50IGZhY3RvciA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5HbG9iYWxHYWluOyAvKiBhY2N1IGZvciBzY2FsZSBmYWN0b3IgZGVsdGEgY29kaW5nICovCiAgVUNIQVIgKnBDb2RlQm9vayA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hQ29kZUJvb2s7CiAgU0hPUlQgKnBTY2FsZUZhY3RvciA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3I7CiAgY29uc3QgQ29kZUJvb2tEZXNjcmlwdGlvbiAqaGNiID0mQUFDY29kZUJvb2tEZXNjcmlwdGlvblRhYmxlW0JPT0tTQ0xdOwoKICBpbnQgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBmb3IgKGdyb3VwPTA7IGdyb3VwIDwgR2V0V2luZG93R3JvdXBzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsgZ3JvdXArKykKICB7CiAgICBmb3IgKGJhbmQ9MDsgYmFuZCA8IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZDsgYmFuZCsrKQogICAgewogICAgICBzd2l0Y2ggKHBDb2RlQm9va1tncm91cCoxNitiYW5kXSkgewoKICAgICAgY2FzZSBaRVJPX0hDQjogLyogemVybyBib29rICovCiAgICAgICAgcFNjYWxlRmFjdG9yW2dyb3VwKjE2K2JhbmRdID0gMDsKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6IC8qIGRlY29kZSBzY2FsZSBmYWN0b3IgKi8KICAgICAgICB7CiAgICAgICAgICB0ZW1wID0gQ0Jsb2NrX0RlY29kZUh1ZmZtYW5Xb3JkKGJzLGhjYik7CiAgICAgICAgICBmYWN0b3IgKz0gdGVtcCAtIDYwOyAvKiBNSURGQUMgMS41IGRCICovCiAgICAgICAgfQogICAgICAgIHBTY2FsZUZhY3Rvcltncm91cCoxNitiYW5kXSA9IGZhY3RvciAtIDEwMDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSU5URU5TSVRZX0hDQjogLyogaW50ZW5zaXR5IHN0ZWVyaW5nICovCiAgICAgIGNhc2UgSU5URU5TSVRZX0hDQjI6CiAgICAgICAgdGVtcCA9IENCbG9ja19EZWNvZGVIdWZmbWFuV29yZChicyxoY2IpOwogICAgICAgIHBvc2l0aW9uICs9IHRlbXAgLSA2MDsKICAgICAgICBwU2NhbGVGYWN0b3JbZ3JvdXAqMTYrYmFuZF0gPSBwb3NpdGlvbiAtIDEwMDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgTk9JU0VfSENCOiAvKiBQTlMgKi8KICAgICAgICBpZiAoZmxhZ3MgJiAoQUNfTVBTX1JFU3xBQ19VU0FDfEFDX1JTVkQ1MCkpIHsKICAgICAgICAgIHJldHVybiBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIH0KICAgICAgICBDUG5zX1JlYWQoICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5kYXRhLmFhYy5QbnNEYXRhLCBicywgaGNiLCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YVNjYWxlRmFjdG9yLCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uR2xvYmFsR2FpbiwgYmFuZCwgZ3JvdXApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKdm9pZCBDQmxvY2tfU2NhbGVTcGVjdHJhbERhdGEoQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8pCnsKICBpbnQgYmFuZDsKICBpbnQgd2luZG93OwogIGNvbnN0IFNIT1JUICogUkVTVFJJQ1QgcFNmYlNjYWxlICA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2ZiU2NhbGU7CiAgU0hPUlQgKiBSRVNUUklDVCBwU3BlY1NjYWxlID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlOwogIGludCBncm91cHdpbixncm91cDsKICBjb25zdCBTSE9SVCAqIFJFU1RSSUNUIEJhbmRPZmZzZXRzID0gR2V0U2NhbGVGYWN0b3JCYW5kT2Zmc2V0cygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8pOwogIFNQRUNUUkFMX1BUUiBSRVNUUklDVCBwU3BlY3RyYWxDb2VmZmljaWVudCA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50OwoKCiAgRkRLbWVtY2xlYXIocFNwZWNTY2FsZSwgOCpzaXplb2YoU0hPUlQpKTsKCiAgaW50IG1heF9iYW5kID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBmb3IgKHdpbmRvdz0wLCBncm91cD0wOyBncm91cCA8IEdldFdpbmRvd0dyb3VwcygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7IGdyb3VwKyspCiAgewogICAgZm9yIChncm91cHdpbj0wOyBncm91cHdpbiA8IEdldFdpbmRvd0dyb3VwTGVuZ3RoKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLGdyb3VwKTsgZ3JvdXB3aW4rKywgd2luZG93KyspCiAgICB7CiAgICAgIGludCBTcGVjU2NhbGVfd2luZG93ID0gcFNwZWNTY2FsZVt3aW5kb3ddOwogICAgICBGSVhQX0RCTCAqcFNwZWN0cnVtID0gU1BFQyhwU3BlY3RyYWxDb2VmZmljaWVudCwgd2luZG93LCAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+Z3JhbnVsZUxlbmd0aCk7CgogICAgICAvKiBmaW5kIHNjYWxpbmcgZm9yIGN1cnJlbnQgd2luZG93ICovCiAgICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgbWF4X2JhbmQ7IGJhbmQrKykKICAgICAgewogICAgICAgIFNwZWNTY2FsZV93aW5kb3cgPSBmTWF4KFNwZWNTY2FsZV93aW5kb3csIChpbnQpcFNmYlNjYWxlW3dpbmRvdyoxNitiYW5kXSk7CiAgICAgIH0KCiAgICAgIGlmIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+VG5zRGF0YS5BY3RpdmUpIHsKICAgICAgICBTcGVjU2NhbGVfd2luZG93ICs9IFROU19TQ0FMRTsKICAgICAgfQoKICAgICAgLyogc3RvcmUgc2NhbGluZyBvZiBjdXJyZW50IHdpbmRvdyAqLwogICAgICBwU3BlY1NjYWxlW3dpbmRvd10gPSBTcGVjU2NhbGVfd2luZG93OwoKI2lmZGVmIEZVTkNUSU9OX0NCbG9ja19TY2FsZVNwZWN0cmFsRGF0YV9mdW5jMQoKICAgICAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhX2Z1bmMxKHBTcGVjdHJ1bSwgbWF4X2JhbmQsIEJhbmRPZmZzZXRzLCBTcGVjU2NhbGVfd2luZG93LCBwU2ZiU2NhbGUsIHdpbmRvdyk7CgojZWxzZSAvKiBGVU5DVElPTl9DQmxvY2tfU2NhbGVTcGVjdHJhbERhdGFfZnVuYzEgKi8KICAgICAgZm9yIChiYW5kPTA7IGJhbmQgPCBtYXhfYmFuZDsgYmFuZCsrKQogICAgICB7CiAgICAgICAgaW50IHNjYWxlID0gU3BlY1NjYWxlX3dpbmRvdyAtIHBTZmJTY2FsZVt3aW5kb3cqMTYrYmFuZF07CiAgICAgICAgaWYgKHNjYWxlKQogICAgICAgIHsKICAgICAgICAgIC8qIGZvbGxvd2luZyByZWxhdGlvbiBjYW4gYmUgdXNlZCBmb3Igb3B0aW1pemF0aW9uczogKEJhbmRPZmZzZXRzW2ldJTQpID09IDAgZm9yIGFsbCBpICovCiAgICAgICAgICBpbnQgbWF4X2luZGV4ID0gQmFuZE9mZnNldHNbYmFuZCsxXTsKICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gQmFuZE9mZnNldHNbYmFuZF07IGluZGV4IDwgbWF4X2luZGV4OyBpbmRleCsrKQogICAgICAgICAgewogICAgICAgICAgICBwU3BlY3RydW1baW5kZXhdID4+PSBzY2FsZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KI2VuZGlmICAvKiBGVU5DVElPTl9DQmxvY2tfU2NhbGVTcGVjdHJhbERhdGFfZnVuYzEgKi8KICAgIH0KICB9Cgp9CgpBQUNfREVDT0RFUl9FUlJPUiBDQmxvY2tfUmVhZFNlY3Rpb25EYXRhKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCAgZmxhZ3MpCnsKICBpbnQgdG9wLCBiYW5kOwogIGludCBzZWN0X2xlbiwgc2VjdF9sZW5faW5jcjsKICBpbnQgZ3JvdXA7CiAgVUNIQVIgc2VjdF9jYjsKICBVQ0hBUiAqcENvZGVCb29rID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9vazsKICAvKiBIQ1IgaW5wdXQgKGxvbmcpICovCiAgU0hPUlQgKnBOdW1MaW5lc0luU2VjICAgID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLmFOdW1MaW5lSW5TZWM0SGNyOwogIGludCAgICBudW1MaW5lc0luU2VjSWR4ICA9IDA7CiAgVUNIQVIgKnBIY3JDb2RlQm9vayAgICAgID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLmFDb2RlQm9va3M0SGNyOwogIGNvbnN0IFNIT1JUICpCYW5kT2Zmc2V0cyA9IEdldFNjYWxlRmFjdG9yQmFuZE9mZnNldHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvKTsKICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMubnVtYmVyU2VjdGlvbiA9IDA7CiAgQUFDX0RFQ09ERVJfRVJST1IgRXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwoKICBGREttZW1jbGVhcihwQ29kZUJvb2ssIHNpemVvZihVQ0hBUikqKDgqMTYpKTsKCiAgY29uc3QgaW50IG5iaXRzID0gKElzTG9uZ0Jsb2NrKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSA9PSAxKSA/IDUgOiAzOwoKICBpbnQgc2VjdF9lc2NfdmFsID0gKDEgPDwgbmJpdHMpIC0gMSA7CgogIFVDSEFSIFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCA9IEdldFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7CiAgZm9yIChncm91cD0wOyBncm91cDxHZXRXaW5kb3dHcm91cHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOyBncm91cCsrKQogIHsKICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkOyApCiAgICB7CiAgICAgIHNlY3RfbGVuID0gMDsKICAgICAgaWYgKCBmbGFncyAmIEFDX0VSX1ZDQjExICkgIHsKICAgICAgICBzZWN0X2NiID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw1KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgICAgc2VjdF9jYiA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CgogICAgICBpZiAoICgoZmxhZ3MgJiBBQ19FUl9WQ0IxMSkgPT0gMCkgfHwgKCBzZWN0X2NiIDwgMTEgKSB8fCAoKHNlY3RfY2IgPiAxMSkgJiYgKHNlY3RfY2IgPCAxNikpICkgewogICAgICAgIHNlY3RfbGVuX2luY3IgPSBGREtyZWFkQml0cyhicywgbmJpdHMpOwogICAgICAgIHdoaWxlIChzZWN0X2xlbl9pbmNyID09IHNlY3RfZXNjX3ZhbCkKICAgICAgICB7CiAgICAgICAgICBzZWN0X2xlbiArPSBzZWN0X2VzY192YWw7CiAgICAgICAgICBzZWN0X2xlbl9pbmNyID0gRkRLcmVhZEJpdHMoYnMsIG5iaXRzKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgc2VjdF9sZW5faW5jciA9IDE7CiAgICAgIH0KCiAgICAgIHNlY3RfbGVuICs9IHNlY3RfbGVuX2luY3I7CgoKICAgICAgdG9wID0gYmFuZCArIHNlY3RfbGVuOwoKICAgICAgaWYgKGZsYWdzICYgQUNfRVJfSENSKSB7CiAgICAgICAgLyogSENSIGlucHV0IChsb25nKSAtLSBjb2xsZWN0aW5nIHNpZGVpbmZvIChmb3IgSENSLV9sb25nXyBvbmx5KSAqLwogICAgICAgIGlmIChudW1MaW5lc0luU2VjSWR4ID49IE1BWF9TRkJfSENSKSB7CiAgICAgICAgICByZXR1cm4gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICB9CiAgICAgICAgcE51bUxpbmVzSW5TZWNbbnVtTGluZXNJblNlY0lkeF0gPSBCYW5kT2Zmc2V0c1t0b3BdIC0gQmFuZE9mZnNldHNbYmFuZF07CiAgICAgICAgbnVtTGluZXNJblNlY0lkeCsrOwogICAgICAgIGlmICgKICAgICAgICAgICAgIChzZWN0X2NiID09IEJPT0tTQ0wpICkKICAgICAgICB7CiAgICAgICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0NPREVfQk9PSzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgKnBIY3JDb2RlQm9vaysrID0gc2VjdF9jYjsKICAgICAgICB9CiAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLm51bWJlclNlY3Rpb24rKzsKICAgICAgfQoKICAgICAgLyogQ2hlY2sgc3BlY3RyYWwgbGluZSBsaW1pdHMgKi8KICAgICAgaWYgKElzTG9uZ0Jsb2NrKCAmKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pICkpCiAgICAgIHsKICAgICAgICBpZiAodG9wID4gNjQpIHsKICAgICAgICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7IC8qIHNob3J0IGJsb2NrICovCiAgICAgICAgaWYgKHRvcCArIGdyb3VwKjE2ID4gKDggKiAxNikpIHsKICAgICAgICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qIENoZWNrIGlmIGRlY29kZWQgY29kZWJvb2sgaW5kZXggaXMgZmVhc2libGUgKi8KICAgICAgaWYgKCAoc2VjdF9jYiA9PSBCT09LU0NMKQogICAgICAgfHwgKCAoc2VjdF9jYiA9PSBJTlRFTlNJVFlfSENCIHx8IHNlY3RfY2IgPT0gSU5URU5TSVRZX0hDQjIpICYmIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5Db21tb25XaW5kb3cgPT0gMCkKICAgICAgICAgKQogICAgICB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9DT0RFX0JPT0s7CiAgICAgIH0KCiAgICAgIC8qIFN0b3JlIGNvZGVib29rIGluZGV4ICovCiAgICAgIGZvciAoOyBiYW5kIDwgdG9wOyBiYW5kKyspCiAgICAgIHsKICAgICAgICBwQ29kZUJvb2tbZ3JvdXAqMTYrYmFuZF0gPSBzZWN0X2NiOwogICAgICB9CiAgICB9CiAgfQoKCiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9CgovKiBtc286IHByb3ZpZGVzIGEgZmFzdGVyIHdheSB0byBpLXF1YW50aXplIGEgd2hvbGUgYmFuZCBpbiBvbmUgZ28gKi8KCi8qKgogKiBcYnJpZWYgaW52ZXJzZSBxdWFudGl6ZSBvbmUgc2ZiLiBFYWNoIHZhbHVlIG9mIHRoZSBzZmIgaXMgcHJvY2Vzc2VkIGFjY29yZGluZyB0byB0aGUKICogICAgICAgIGZvcm11bGE6IHNwZWN0cnVtW2ldID0gU2lnbihzcGVjdHJ1bVtpXSkgKiBNYXRpc3NhKHNwZWN0cnVtW2ldKV4oNC8zKSAqIDJeKGxzYi80KS4KICogXHBhcmFtIHNwZWN0cnVtIHBvaW50ZXIgdG8gZmlyc3QgbGluZSBvZiB0aGUgc2ZiIHRvIGJlIGludmVyc2UgcXVhbnRpemVkLgogKiBccGFyYW0gbm9MaW5lcyBudW1iZXIgb2YgbGluZXMgYmVsb25naW5nIHRvIHRoZSBzZmIuCiAqIFxwYXJhbSBsc2IgbGFzdCAyIGJpdHMgb2YgdGhlIHNjYWxlIGZhY3RvciBvZiB0aGUgc2ZiLgogKiBccGFyYW0gc2NhbGUgbWF4IGFsbG93ZWQgc2hpZnQgc2NhbGUgZm9yIHRoZSBzZmIuCiAqLwpzdGF0aWMKdm9pZCBJbnZlcnNlUXVhbnRpemVCYW5kKCBGSVhQX0RCTCAqIFJFU1RSSUNUIHNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9MaW5lcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGxzYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHNjYWxlICkKewogICAgY29uc3QgRklYUF9EQkwgKiBSRVNUUklDVCBJbnZlcnNlUXVhbnRUYWJsZXI9KEZJWFBfREJMICopSW52ZXJzZVF1YW50VGFibGU7CiAgICBjb25zdCBGSVhQX0RCTCAqIFJFU1RSSUNUIE1hbnRpc3NhVGFibGVyPShGSVhQX0RCTCAqKU1hbnRpc3NhVGFibGVbbHNiXTsKICAgIGNvbnN0IFNDSEFSKiBSRVNUUklDVCBFeHBvbmVudFRhYmxlcj0oU0NIQVIqKUV4cG9uZW50VGFibGVbbHNiXTsKCiAgICBGSVhQX0RCTCAqcHRyID0gc3BlY3RydW07CiAgICBGSVhQX0RCTCBzaWduZWRWYWx1ZTsKCiAgICBGREtfQVNTRVJUKG5vTGluZXM+Mik7CiAgICBmb3IgKElOVCBpPW5vTGluZXM7IGktLTsgKQogICAgewogICAgICAgIGlmICgoc2lnbmVkVmFsdWUgPSAqcHRyKyspICE9IEZMMkZYQ09OU1RfREJMKDApKQogICAgICAgIHsKICAgICAgICAgIEZJWFBfREJMIHZhbHVlID0gZkFicyhzaWduZWRWYWx1ZSk7CiAgICAgICAgICBVSU5UIGZyZWVCaXRzID0gQ250TGVhZGluZ1plcm9zKHZhbHVlKTsKICAgICAgICAgIFVJTlQgZXhwb25lbnQgPSAzMiAtIGZyZWVCaXRzOwoKICAgICAgICAgIFVJTlQgeCA9IChVSU5UKSAoTE9ORyl2YWx1ZSA8PCAoSU5UKSBmcmVlQml0czsKICAgICAgICAgIHggPDw9IDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNoaWZ0IG91dCBzaWduIGJpdCB0byBhdm9pZCBtYXNraW5nIGxhdGVyIG9uICovCiAgICAgICAgICBVSU5UIHRhYmxlSW5kZXggPSB4ID4+IDI0OwogICAgICAgICAgeCA9ICh4ID4+IDIwKSAmICAweDBGOwoKICAgICAgICAgIFVJTlQgcjA9KFVJTlQpKExPTkcpSW52ZXJzZVF1YW50VGFibGVyW3RhYmxlSW5kZXgrMF07CiAgICAgICAgICBVSU5UIHIxPShVSU5UKShMT05HKUludmVyc2VRdWFudFRhYmxlclt0YWJsZUluZGV4KzFdOwogICAgICAgICAgVUlOVCB0ZW1wPSAocjEgLSByMCkqeCArIChyMCA8PCA0KTsKCiAgICAgICAgICB2YWx1ZSA9IGZNdWx0RGl2MigoRklYUF9EQkwpdGVtcCwgTWFudGlzc2FUYWJsZXJbZXhwb25lbnRdKTsKCiAgICAgICAgICAvKiArIDEgY29tcGVuc2F0ZXMgZk11bHREaXYyKCkgKi8KICAgICAgICAgIHNjYWxlVmFsdWVJblBsYWNlKCZ2YWx1ZSwgc2NhbGUgKyBFeHBvbmVudFRhYmxlcltleHBvbmVudF0gKyAxKTsKCiAgICAgICAgICBzaWduZWRWYWx1ZSA9IChzaWduZWRWYWx1ZSA8IChGSVhQX0RCTCkwKSA/IC12YWx1ZSA6IHZhbHVlOwogICAgICAgICAgcHRyWy0xXSA9IHNpZ25lZFZhbHVlOwogICAgICAgIH0KICAgIH0KfQoKQUFDX0RFQ09ERVJfRVJST1IgQ0Jsb2NrX0ludmVyc2VRdWFudGl6ZVNwZWN0cmFsRGF0YShDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbykKewogIGludCB3aW5kb3csIGdyb3VwLCBncm91cHdpbiwgYmFuZDsKICBpbnQgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBVQ0hBUiAqUkVTVFJJQ1QgcENvZGVCb29rID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9vazsKICBTSE9SVCAqUkVTVFJJQ1QgcFNmYlNjYWxlID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTZmJTY2FsZTsKICBTSE9SVCAqUkVTVFJJQ1QgcFNjYWxlRmFjdG9yID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTY2FsZUZhY3RvcjsKICBjb25zdCBTSE9SVCAqUkVTVFJJQ1QgQmFuZE9mZnNldHMgPSBHZXRTY2FsZUZhY3RvckJhbmRPZmZzZXRzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLCBwU2FtcGxpbmdSYXRlSW5mbyk7CgogIEZES21lbWNsZWFyKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2ZiU2NhbGUsICg4KjE2KSpzaXplb2YoU0hPUlQpKTsKCiAgZm9yICh3aW5kb3c9MCwgZ3JvdXA9MDsgZ3JvdXAgPCBHZXRXaW5kb3dHcm91cHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOyBncm91cCsrKQogIHsKICAgIGZvciAoZ3JvdXB3aW49MDsgZ3JvdXB3aW4gPCBHZXRXaW5kb3dHcm91cExlbmd0aCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyxncm91cCk7IGdyb3Vwd2luKyssIHdpbmRvdysrKQogICAgewogICAgICAvKiBpbnZlcnNlIHF1YW50aXphdGlvbiAqLwogICAgICBmb3IgKGJhbmQ9MDsgYmFuZCA8IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZDsgYmFuZCsrKQogICAgICB7CiAgICAgICAgRklYUF9EQkwgKnBTcGVjdHJhbENvZWZmaWNpZW50ID0gU1BFQyhwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCwgd2luZG93LCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5ncmFudWxlTGVuZ3RoKSArIEJhbmRPZmZzZXRzW2JhbmRdOwoKICAgICAgICBpbnQgbm9MaW5lcyA9IEJhbmRPZmZzZXRzW2JhbmQrMV0gLSBCYW5kT2Zmc2V0c1tiYW5kXTsKICAgICAgICBpbnQgYm5kcyA9IGdyb3VwKjE2K2JhbmQ7CiAgICAgICAgaW50IGk7CgogICAgICAgIGlmICgocENvZGVCb29rW2JuZHNdID09IFpFUk9fSENCKQogICAgICAgICB8fCAocENvZGVCb29rW2JuZHNdID09IElOVEVOU0lUWV9IQ0IpCiAgICAgICAgIHx8IChwQ29kZUJvb2tbYm5kc10gPT0gSU5URU5TSVRZX0hDQjIpCiAgICAgICAgICAgKQogICAgICAgICAgY29udGludWU7CgogICAgICAgIGlmIChwQ29kZUJvb2tbYm5kc10gPT0gTk9JU0VfSENCKQogICAgICAgIHsKICAgICAgICAgIC8qIExlYXZlIGhlYWRyb29tIGZvciBQTlMgdmFsdWVzLiArIDEgYmVjYXVzZSBjZWlsKGxvZzIoMl4oMC4yNSozKSkpID0gMSwKICAgICAgICAgICAgIHdvcnN0IGNhc2Ugb2YgYWRkaXRpb25hbCBoZWFkcm9vbSByZXF1aXJlZCBiZWNhdXNlIG9mIHRoZSBzY2FsZWZhY3Rvci4gKi8KICAgICAgICAgIHBTZmJTY2FsZVt3aW5kb3cqMTYrYmFuZF0gPSAocFNjYWxlRmFjdG9yIFtibmRzXSA+PiAyKSArIDEgOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICAvKiBGaW5kIG1heCBzcGVjdHJhbCBsaW5lIHZhbHVlIG9mIHRoZSBjdXJyZW50IHNmYiAqLwogICAgICAgIEZJWFBfREJMIGxvY01heCA9IChGSVhQX0RCTCkwOwoKICAgICAgICBmb3IgKGkgPSBub0xpbmVzOyBpLS0gOyApIHsKICAgICAgICAgIC8qIEV4cGVuc2l2ZSBtZW1vcnkgYWNjZXNzICovCiAgICAgICAgICBsb2NNYXggPSBmTWF4KGZpeHBfYWJzKHBTcGVjdHJhbENvZWZmaWNpZW50W2ldKSwgbG9jTWF4KTsKICAgICAgICB9CgogICAgICAgIC8qIENoZWFwIHJvYnVzdG5lc3MgaW1wcm92ZW1lbnQgLSBEbyBub3QgcmVtb3ZlISEhICovCiAgICAgICAgaWYgKGZpeHBfYWJzKGxvY01heCkgPiAoRklYUF9EQkwpTUFYX1FVQU5USVpFRF9WQUxVRSkgewogICAgICAgICAgcmV0dXJuIEFBQ19ERUNfREVDT0RFX0ZSQU1FX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgICBUaGUgaW52ZXJzZSBxdWFudGl6ZWQgc3BlY3RyYWwgbGluZXMgYXJlIGRlZmluZWQgYnk6CiAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnRbaV0gPSBTaWduKHBTcGVjdHJhbENvZWZmaWNpZW50W2ldKSAqIDJeKDAuMjUqcFNjYWxlRmFjdG9yW2JuZHNdKSAqIHBTcGVjdHJhbENvZWZmaWNpZW50W2ldXig0LzMpCiAgICAgICAgICAgVGhpcyBpcyBlcXVpdmFsZW50IHRvOgogICAgICAgIHBTcGVjdHJhbENvZWZmaWNpZW50W2ldICAgID0gU2lnbihwU3BlY3RyYWxDb2VmZmljaWVudFtpXSkgKiAoMl4ocFNjYWxlRmFjdG9yW2JuZHNdICUgNCkgKiBwU3BlY3RyYWxDb2VmZmljaWVudFtpXV4oNC8zKSkKICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudF9lW2ldICs9IHBTY2FsZUZhY3RvcltibmRzXS80CiAgICAgICAgKi8KICAgICAgICB7CiAgICAgICAgICBpbnQgbXNiID0gcFNjYWxlRmFjdG9yIFtibmRzXSA+PiAyIDsKICAgICAgICAgIGludCBsc2IgPSBwU2NhbGVGYWN0b3IgW2JuZHNdICYgMHgwMyA7CgogICAgICAgICAgaW50IHNjYWxlID0gR2V0U2NhbGVGcm9tVmFsdWUobG9jTWF4LCBsc2IpOwoKICAgICAgICAgIHBTZmJTY2FsZVt3aW5kb3cqMTYrYmFuZF0gPSBtc2IgLSBzY2FsZTsKICAgICAgICAgIEludmVyc2VRdWFudGl6ZUJhbmQocFNwZWN0cmFsQ29lZmZpY2llbnQsIG5vTGluZXMsIGxzYiwgc2NhbGUpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCgogIHJldHVybiBBQUNfREVDX09LOwp9CgoKQUFDX0RFQ09ERVJfRVJST1IgIENCbG9ja19SZWFkU3BlY3RyYWxEYXRhKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNhbXBsaW5nUmF0ZUluZm8gKnBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCAgZmxhZ3MpCnsKICBpbnQgaSxpbmRleDsKICBpbnQgd2luZG93LGdyb3VwLGdyb3Vwd2luLGdyb3Vwb2Zmc2V0LGJhbmQ7CiAgVUNIQVIgKlJFU1RSSUNUIHBDb2RlQm9vayA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hQ29kZUJvb2s7CiAgY29uc3QgU0hPUlQgKlJFU1RSSUNUIEJhbmRPZmZzZXRzID0gR2V0U2NhbGVGYWN0b3JCYW5kT2Zmc2V0cygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8pOwoKICBTUEVDVFJBTF9QVFIgcFNwZWN0cmFsQ29lZmZpY2llbnQgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudDsKICBGSVhQX0RCTCBsb2NNYXg7CgogIGludCBTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQgPSBHZXRTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOwoKICBGREtfQVNTRVJUKEJhbmRPZmZzZXRzICE9IE5VTEwpOwoKICBGREttZW1jbGVhcihwU3BlY3RyYWxDb2VmZmljaWVudCwgc2l6ZW9mKFNQRUNUUlVNKSk7CgogIGlmICggKGZsYWdzICYgQUNfRVJfSENSKSA9PSAwICkKICB7CiAgICBncm91cG9mZnNldCA9IDA7CgogICAgLyogcGxhaW4gaHVmZm1hbiBkZWNvZGVyICBzaG9ydCAqLwogICAgZm9yIChncm91cD0wOyBncm91cCA8IEdldFdpbmRvd0dyb3VwcygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7IGdyb3VwKyspCiAgICB7CiAgICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkOyBiYW5kKyspCiAgICAgIHsKICAgICAgICBpbnQgYm5kcyA9IGdyb3VwKjE2K2JhbmQ7CiAgICAgICAgVUNIQVIgY3VycmVudENCID0gcENvZGVCb29rW2JuZHNdOwoKICAgICAgICAvKiBwYXRjaCB0byBydW4gcGxhaW4taHVmZm1hbi1kZWNvZGVyIHdpdGggdmNiMTEgaW5wdXQgY29kZWJvb2tzIChMQVYtY2hlY2tpbmcgbWlnaHQgYmUgcG9zc2libGUgYmVsb3cgdXNpbmcgdGhlIHZpcnR1YWwgY2IgYW5kIGEgTEFWLXRhYmxlKSAqLwogICAgICAgIGlmICgoY3VycmVudENCID49IDE2KSAmJiAoY3VycmVudENCIDw9IDMxKSkgewogICAgICAgICAgcENvZGVCb29rW2JuZHNdID0gY3VycmVudENCID0gMTE7CiAgICAgICAgfQogICAgICAgIGlmICggISgoY3VycmVudENCID09IFpFUk9fSENCKQogICAgICAgICAgICB8fCAoY3VycmVudENCID09IE5PSVNFX0hDQikKICAgICAgICAgICAgfHwgKGN1cnJlbnRDQiA9PSBJTlRFTlNJVFlfSENCKQogICAgICAgICAgICB8fCAoY3VycmVudENCID09IElOVEVOU0lUWV9IQ0IyKSkgKQogICAgICAgIHsKICAgICAgICAgIGNvbnN0IENvZGVCb29rRGVzY3JpcHRpb24gKmhjYiA9ICZBQUNjb2RlQm9va0Rlc2NyaXB0aW9uVGFibGVbY3VycmVudENCXTsKICAgICAgICAgIGludCBzdGVwID0gaGNiLT5EaW1lbnNpb247CiAgICAgICAgICBpbnQgb2Zmc2V0ID0gaGNiLT5PZmZzZXQ7CiAgICAgICAgICBpbnQgYml0cyA9IGhjYi0+bnVtQml0czsKICAgICAgICAgIGludCBtYXNrID0gKDE8PGJpdHMpLTE7CgogICAgICAgICAgZm9yIChncm91cHdpbj0wOyBncm91cHdpbiA8IEdldFdpbmRvd0dyb3VwTGVuZ3RoKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLGdyb3VwKTsgZ3JvdXB3aW4rKykKICAgICAgICAgIHsKICAgICAgICAgICAgd2luZG93ID0gZ3JvdXBvZmZzZXQgKyBncm91cHdpbjsKCiAgICAgICAgICAgIEZJWFBfREJMICptZGN0U3BlY3RydW0gPSBTUEVDKHBTcGVjdHJhbENvZWZmaWNpZW50LCB3aW5kb3csIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmdyYW51bGVMZW5ndGgpOwoKICAgICAgICAgICAgbG9jTWF4ID0gKEZJWFBfREJMKTAgOwoKICAgICAgICAgICAgZm9yIChpbmRleD1CYW5kT2Zmc2V0c1tiYW5kXTsgaW5kZXggPCBCYW5kT2Zmc2V0c1tiYW5kKzFdOyBpbmRleCs9c3RlcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgIGludCBpZHggPSBDQmxvY2tfRGVjb2RlSHVmZm1hbldvcmQoYnMsaGNiKTsKCiAgICAgICAgICAgICAgZm9yIChpPTA7IGk8c3RlcDsgaSsrKSB7CiAgICAgICAgICAgICAgICBGSVhQX0RCTCB0bXA7CgogICAgICAgICAgICAgICAgdG1wID0gKEZJWFBfREJMKSgoaWR4ICYgbWFzayktb2Zmc2V0KTsKICAgICAgICAgICAgICAgIGlkeCA+Pj0gYml0czsKCiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ID09IDApIHsKICAgICAgICAgICAgICAgICAgaWYgKHRtcCAhPSBGSVhQX0RCTCgwKSkKICAgICAgICAgICAgICAgICAgICB0bXAgPSAoRkRLcmVhZEJpdHMoYnMsMSkpPyAtdG1wIDogdG1wOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWRjdFNwZWN0cnVtW2luZGV4K2ldID0gdG1wOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDQiA9PSBFU0NCT09LKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG1kY3RTcGVjdHJ1bVtpbmRleCswXSA9IChGSVhQX0RCTClDQmxvY2tfR2V0RXNjYXBlKGJzLCAoTE9ORyltZGN0U3BlY3RydW1baW5kZXgrMF0pOwogICAgICAgICAgICAgICAgbWRjdFNwZWN0cnVtW2luZGV4KzFdID0gKEZJWFBfREJMKUNCbG9ja19HZXRFc2NhcGUoYnMsIChMT05HKW1kY3RTcGVjdHJ1bVtpbmRleCsxXSk7CgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBncm91cG9mZnNldCArPSBHZXRXaW5kb3dHcm91cExlbmd0aCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyxncm91cCk7CiAgICB9CiAgICAvKiBwbGFpbiBodWZmbWFuIGRlY29kaW5nIChzaG9ydCkgZmluaXNoZWQgKi8KICB9CiAgLyogSENSIC0gSHVmZm1hbiBDb2Rld29yZCBSZW9yZGVyaW5nICBzaG9ydCAqLwogIGVsc2UgIC8qIGlmICggZmxhZ3MgJiBBQ19FUl9IQ1IgKSAqLwogIHsKICAgIEhfSENSX0lORk8gaEhjciA9ICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+b3ZlcmxheS5hYWMuZXJIY3JJbmZvOwogICAgaW50IGhjclN0YXR1cyA9IDA7CgogICAgLyogYWR2YW5jZWQgSHVmZm1hbiBkZWNvZGluZyBzdGFydHMgaGVyZSAoSENSIGRlY29kaW5nIDopICovCiAgICBpZiAoIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5sZW5PZlJlb3JkZXJlZFNwZWN0cmFsRGF0YSAhPSAwICkgewoKICAgICAgLyogSENSIGluaXRpYWxpemF0aW9uIHNob3J0ICovCiAgICAgIGhjclN0YXR1cyA9IEhjckluaXQoaEhjciwgcEFhY0RlY29kZXJDaGFubmVsSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8sIGJzKTsKCiAgICAgIGlmIChoY3JTdGF0dXMgIT0gMCkgewogICAgICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgfQoKICAgICAgLyogSENSIGRlY29kaW5nIHNob3J0ICovCiAgICAgIGhjclN0YXR1cyA9IEhjckRlY29kZXIoaEhjciwgcEFhY0RlY29kZXJDaGFubmVsSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8sIGJzKTsKCiAgICAgIGlmIChoY3JTdGF0dXMgIT0gMCkgewojaWYgSENSX0VSUk9SX0NPTkNFQUxNRU5UCiAgICAgICAgSGNyTXV0ZUVycm9uZW91c0xpbmVzKGhIY3IpOwojZWxzZQogICAgICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKI2VuZGlmIC8qIEhDUl9FUlJPUl9DT05DRUFMTUVOVCAqLwogICAgICB9CgogICAgICBGREtwdXNoRm9yIChicywgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLmxlbk9mUmVvcmRlcmVkU3BlY3RyYWxEYXRhKTsKICAgIH0KICB9CiAgLyogSENSIC0gSHVmZm1hbiBDb2Rld29yZCBSZW9yZGVyaW5nIHNob3J0IGZpbmlzaGVkICovCgoKCiAgaWYgKCBJc0xvbmdCbG9jaygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbykgJiYgIShmbGFncyAmIChBQ19FTER8QUNfU0NBTEFCTEUpKSApCiAgewogICAgLyogYXBwbHkgcHVsc2UgZGF0YSAqLwogICAgQ1B1bHNlRGF0YV9BcHBseSgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLlB1bHNlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgIEdldFNjYWxlRmFjdG9yQmFuZE9mZnNldHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvKSwKICAgICAgICAgICAgICAgICAgICAgIFNQRUNfTE9ORyhwU3BlY3RyYWxDb2VmZmljaWVudCkpOwogIH0KCgogIHJldHVybiBBQUNfREVDX09LOwp9CgoKCnZvaWQgQXBwbHlUb29scyAoIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bXSwKICAgICAgICAgICAgICAgICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBjaGFubmVsICkKewoKICBpZiAoICEoZmxhZ3MgJiAoQUNfVVNBQ3xBQ19SU1ZENTB8QUNfTVBTX1JFUykpICkgewogICAgQ1Buc19BcHBseSgKICAgICAgICAgICAmcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+ZGF0YS5hYWMuUG5zRGF0YSwKICAgICAgICAgICAmcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+aWNzSW5mbywKICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+cFNwZWN0cmFsQ29lZmZpY2llbnQsCiAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPnNwZWNTY2FsZSwKICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+cER5bkRhdGEtPmFTY2FsZUZhY3RvciwKICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPmdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgIGNoYW5uZWwKICAgICAgICAgICAgKTsKICB9CgogIENUbnNfQXBwbHkgKAogICAgICAgICAmcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+cER5bkRhdGEtPlRuc0RhdGEsCiAgICAgICAgICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoYW5uZWxdLT5pY3NJbmZvLAogICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+cFNwZWN0cmFsQ29lZmZpY2llbnQsCiAgICAgICAgICBwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPmdyYW51bGVMZW5ndGgKICAgICAgICAgICk7Cn0KCnN0YXRpYwppbnQgZ2V0V2luZG93Mk5yKGludCBsZW5ndGgsIGludCBzaGFwZSkKewogIGludCBuciA9IDA7CgogIGlmIChzaGFwZSA9PSAyKSB7CiAgICAvKiBMb3cgT3ZlcmxhcCwgMy80IHplcm9lZCAqLwogICAgbnIgPSAobGVuZ3RoICogMyk+PjI7CiAgfQoKICByZXR1cm4gbnI7Cn0KCnZvaWQgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZShDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00gb3V0U2FtcGxlc1tdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0hPUlQgZnJhbWVMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgc3RyaWRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGZyYW1lT2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqcFdvcmtCdWZmZXIxICkKewogIGludCBmciwgZmwsIHRsLCBuU2FtcGxlcywgblNwZWM7CgogIC8qIERldGVybWluZSBsZWZ0IHNsb3BlIGxlbmd0aCAoZmwpLCByaWdodCBzbG9wZSBsZW5ndGggKGZyKSBhbmQgdHJhbnNmb3JtIGxlbmd0aCAodGwpLgogICAgIFVTQUM6IFRoZSBzbG9wZSBsZW5ndGggbWF5IG1pc21hdGNoIHdpdGggdGhlIHByZXZpb3VzIGZyYW1lIGluIGNhc2Ugb2YgTFBEIC8gRkQKICAgICAgICAgICB0cmFuc2l0aW9ucy4gVGhlIGFkanVzdG1lbnQgaXMgaGFuZGxlZCBieSB0aGUgaW1kY3QgaW1wbGVtZW50YXRpb24uCiAgKi8KICB0bCA9IGZyYW1lTGVuOwogIG5TcGVjID0gMTsKCiAgc3dpdGNoKCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLldpbmRvd1NlcXVlbmNlICkgewogICAgZGVmYXVsdDoKICAgIGNhc2UgT25seUxvbmdTZXF1ZW5jZToKICAgICAgZmwgPSBmcmFtZUxlbjsKICAgICAgZnIgPSBmcmFtZUxlbiAtIGdldFdpbmRvdzJOcihmcmFtZUxlbiwgR2V0V2luZG93U2hhcGUoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIExvbmdTdG9wU2VxdWVuY2U6CiAgICAgIGZsID0gZnJhbWVMZW4gPj4gMzsKICAgICAgZnIgPSBmcmFtZUxlbjsKICAgICAgYnJlYWs7CiAgICBjYXNlIExvbmdTdGFydFNlcXVlbmNlOiAvKiBvciBTdG9wU3RhcnRTZXF1ZW5jZSAqLwogICAgICBmbCA9IGZyYW1lTGVuOwogICAgICBmciA9IGZyYW1lTGVuID4+IDM7CiAgICAgIGJyZWFrOwogICAgY2FzZSBFaWdodFNob3J0U2VxdWVuY2U6CiAgICAgIGZsID0gZnIgPSBmcmFtZUxlbiA+PiAzOwogICAgICB0bCA+Pj0gMzsKICAgICAgblNwZWMgPSA4OwogICAgICBicmVhazsKICB9CgogIHsKICAgIGludCBpOwoKICAgIHsKICAgICAgRklYUF9EQkwgKnRtcCA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBDb21EYXRhLT53b3JrQnVmZmVyQ29yZTEtPm1kY3RPdXRUZW1wOwoKICAgICAgblNhbXBsZXMgPSBpbWRjdF9ibG9jaygKICAgICAgICAgICAgICZwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLT5JTWRjdCwKICAgICAgICAgICAgICB0bXAsCiAgICAgICAgICAgICAgU1BFQ19MT05HKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50KSwKICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5zcGVjU2NhbGUsCiAgICAgICAgICAgICAgblNwZWMsCiAgICAgICAgICAgICAgZnJhbWVMZW4sCiAgICAgICAgICAgICAgdGwsCiAgICAgICAgICAgICAgRkRLZ2V0V2luZG93U2xvcGUoZmwsIEdldFdpbmRvd1NoYXBlKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSksCiAgICAgICAgICAgICAgZmwsCiAgICAgICAgICAgICAgRkRLZ2V0V2luZG93U2xvcGUoZnIsIEdldFdpbmRvd1NoYXBlKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSksCiAgICAgICAgICAgICAgZnIsCiAgICAgICAgICAgICAgKEZJWFBfREJMKTAgKTsKCiAgICAgIGZvciAoaT0wOyBpPGZyYW1lTGVuOyBpKyspIHsKICAgICAgICBvdXRTYW1wbGVzW2kqc3RyaWRlXSA9IElNRENUX1NDQUxFKHRtcFtpXSk7CiAgICAgIH0KICAgIH0KICB9CgogIEZES19BU1NFUlQoblNhbXBsZXMgPT0gZnJhbWVMZW4pOwoKfQoKI2luY2x1ZGUgImxkZmlsdGJhbmsuaCIKdm9pZCBDQmxvY2tfRnJlcXVlbmN5VG9UaW1lTG93RGVsYXkoIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UX1BDTSBvdXRTYW1wbGVzW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaG9ydCBmcmFtZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgc3RyaWRlICkKewogIEludk1kY3RUcmFuc2Zvcm1Mb3dEZWxheV9mZGsgKAogICAgICAgICAgU1BFQ19MT05HKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50KSwKICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnNwZWNTY2FsZVswXSwKICAgICAgICAgIG91dFNhbXBsZXMsCiAgICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLT5wT3ZlcmxhcEJ1ZmZlciwKICAgICAgICAgIHN0cmlkZSwKICAgICAgICAgIGZyYW1lTGVuCiAgICAgICAgICApOwp9Cg==