Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IGxvbmcvc2hvcnQtYmxvY2sgZGVjb2RpbmcKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJibG9jay5oIgoKI2luY2x1ZGUgImFhY19yb20uaCIKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKI2luY2x1ZGUgIkZES190b29sc19yb20uaCIKCgoKCiNpbmNsdWRlICJhYWNkZWNfaGNyLmgiCiNpbmNsdWRlICJydmxjLmgiCgoKI2lmIGRlZmluZWQoX19hcm1fXykKI2luY2x1ZGUgImFybS9ibG9ja19hcm0uY3BwIgojZW5kaWYKCi8qIQogIFxicmllZiBSZWFkIGVzY2FwZSBzZXF1ZW5jZSBvZiBjb2Rld29yZAoKICBUaGUgZnVuY3Rpb24gcmVhZHMgdGhlIGVzY2FwZSBzZXF1ZW5jZSBmcm9tIHRoZSBiaXRzdHJlYW0sCiAgaWYgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBxdWFudGl6ZWQgY29lZmZpY2llbnQgaGFzIHRoZQogIHZhbHVlIDE2LgoKICBccmV0dXJuICBxdWFudGl6ZWQgY29lZmZpY2llbnQKKi8KTE9ORyBDQmxvY2tfR2V0RXNjYXBlKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLCAvKiE8IHBvaW50ZXIgdG8gYml0c3RyZWFtICovCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExPTkcgcSkgICAgICAgIC8qITwgcXVhbnRpemVkIGNvZWZmaWNpZW50ICovCnsKICBMT05HIGksIG9mZiwgbmVnIDsKCiAgaWYgKHEgPCAwKQogIHsKICAgIGlmIChxICE9IC0xNikgcmV0dXJuIHE7CiAgICBuZWcgPSAxOwogIH0KICBlbHNlCiAgewogICAgaWYgKHEgIT0gKzE2KSByZXR1cm4gcTsKICAgIG5lZyA9IDA7CiAgfQoKICBmb3IgKGk9NDsgOyBpKyspCiAgewogICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpID09IDApCiAgICAgIGJyZWFrOwogIH0KCiAgaWYgKGkgPiAxNikKICB7CiAgICBpZiAoaSAtIDE2ID4gQ0FDSEVfQklUUykgeyAvKiBjYW5ub3QgcmVhZCBtb3JlIHRoYW4gIkNBQ0hFX0JJVFMiIGJpdHMgYXQgb25jZSBpbiB0aGUgZnVuY3Rpb24gRkRLcmVhZEJpdHMoKSAqLwogICAgICByZXR1cm4gKE1BWF9RVUFOVElaRURfVkFMVUUgKyAxKTsgLyogcmV0dXJuaW5nIGludmFsaWQgdmFsdWUgdGhhdCB3aWxsIGJlIGNhcHR1cmVkIGxhdGVyICovCiAgICB9CgogICAgb2ZmID0gRkRLcmVhZEJpdHMoYnMsaS0xNikgPDwgMTY7CiAgICBvZmYgfD0gRkRLcmVhZEJpdHMoYnMsMTYpOwogIH0KICBlbHNlCiAgewogICAgb2ZmID0gRkRLcmVhZEJpdHMoYnMsaSk7CiAgfQoKICBpID0gb2ZmICsgKDEgPDwgaSk7CgogIGlmIChuZWcpIGkgPSAtaTsKCiAgcmV0dXJuIGk7Cn0KCkFBQ19ERUNPREVSX0VSUk9SIENCbG9ja19SZWFkU2NhbGVGYWN0b3JEYXRhKAogICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgVUlOVCBmbGFncwogICAgICAgICkKewogIGludCB0ZW1wOwogIGludCBiYW5kOwogIGludCBncm91cDsKICBpbnQgcG9zaXRpb24gPSAwOyAvKiBhY2N1IGZvciBpbnRlbnNpdHkgZGVsdGEgY29kaW5nICovCiAgaW50IGZhY3RvciA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5SYXdEYXRhSW5mby5HbG9iYWxHYWluOyAvKiBhY2N1IGZvciBzY2FsZSBmYWN0b3IgZGVsdGEgY29kaW5nICovCiAgVUNIQVIgKnBDb2RlQm9vayA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hQ29kZUJvb2s7CiAgU0hPUlQgKnBTY2FsZUZhY3RvciA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3I7CiAgY29uc3QgQ29kZUJvb2tEZXNjcmlwdGlvbiAqaGNiID0mQUFDY29kZUJvb2tEZXNjcmlwdGlvblRhYmxlW0JPT0tTQ0xdOwoKICBpbnQgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBmb3IgKGdyb3VwPTA7IGdyb3VwIDwgR2V0V2luZG93R3JvdXBzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsgZ3JvdXArKykKICB7CiAgICBmb3IgKGJhbmQ9MDsgYmFuZCA8IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZDsgYmFuZCsrKQogICAgewogICAgICBzd2l0Y2ggKHBDb2RlQm9va1tncm91cCoxNitiYW5kXSkgewoKICAgICAgY2FzZSBaRVJPX0hDQjogLyogemVybyBib29rICovCiAgICAgICAgcFNjYWxlRmFjdG9yW2dyb3VwKjE2K2JhbmRdID0gMDsKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6IC8qIGRlY29kZSBzY2FsZSBmYWN0b3IgKi8KICAgICAgICB7CiAgICAgICAgICB0ZW1wID0gQ0Jsb2NrX0RlY29kZUh1ZmZtYW5Xb3JkKGJzLGhjYik7CiAgICAgICAgICBmYWN0b3IgKz0gdGVtcCAtIDYwOyAvKiBNSURGQUMgMS41IGRCICovCiAgICAgICAgfQogICAgICAgIHBTY2FsZUZhY3Rvcltncm91cCoxNitiYW5kXSA9IGZhY3RvciAtIDEwMDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSU5URU5TSVRZX0hDQjogLyogaW50ZW5zaXR5IHN0ZWVyaW5nICovCiAgICAgIGNhc2UgSU5URU5TSVRZX0hDQjI6CiAgICAgICAgdGVtcCA9IENCbG9ja19EZWNvZGVIdWZmbWFuV29yZChicyxoY2IpOwogICAgICAgIHBvc2l0aW9uICs9IHRlbXAgLSA2MDsKICAgICAgICBwU2NhbGVGYWN0b3JbZ3JvdXAqMTYrYmFuZF0gPSBwb3NpdGlvbiAtIDEwMDsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgTk9JU0VfSENCOiAvKiBQTlMgKi8KICAgICAgICBpZiAoZmxhZ3MgJiAoQUNfTVBTX1JFU3xBQ19VU0FDfEFDX1JTVkQ1MCkpIHsKICAgICAgICAgIHJldHVybiBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIH0KICAgICAgICBDUG5zX1JlYWQoICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5kYXRhLmFhYy5QbnNEYXRhLCBicywgaGNiLCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YVNjYWxlRmFjdG9yLCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uR2xvYmFsR2FpbiwgYmFuZCwgZ3JvdXApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKdm9pZCBDQmxvY2tfU2NhbGVTcGVjdHJhbERhdGEoQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8pCnsKICBpbnQgYmFuZDsKICBpbnQgd2luZG93OwogIGNvbnN0IFNIT1JUICogUkVTVFJJQ1QgcFNmYlNjYWxlICA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2ZiU2NhbGU7CiAgU0hPUlQgKiBSRVNUUklDVCBwU3BlY1NjYWxlID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlOwogIGludCBncm91cHdpbixncm91cDsKICBjb25zdCBTSE9SVCAqIFJFU1RSSUNUIEJhbmRPZmZzZXRzID0gR2V0U2NhbGVGYWN0b3JCYW5kT2Zmc2V0cygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8pOwogIFNQRUNUUkFMX1BUUiBSRVNUUklDVCBwU3BlY3RyYWxDb2VmZmljaWVudCA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50OwoKCiAgRkRLbWVtY2xlYXIocFNwZWNTY2FsZSwgOCpzaXplb2YoU0hPUlQpKTsKCiAgaW50IG1heF9iYW5kID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKICBmb3IgKHdpbmRvdz0wLCBncm91cD0wOyBncm91cCA8IEdldFdpbmRvd0dyb3VwcygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7IGdyb3VwKyspCiAgewogICAgZm9yIChncm91cHdpbj0wOyBncm91cHdpbiA8IEdldFdpbmRvd0dyb3VwTGVuZ3RoKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLGdyb3VwKTsgZ3JvdXB3aW4rKywgd2luZG93KyspCiAgICB7CiAgICAgIGludCBTcGVjU2NhbGVfd2luZG93ID0gcFNwZWNTY2FsZVt3aW5kb3ddOwogICAgICBGSVhQX0RCTCAqcFNwZWN0cnVtID0gU1BFQyhwU3BlY3RyYWxDb2VmZmljaWVudCwgd2luZG93LCAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+Z3JhbnVsZUxlbmd0aCk7CgogICAgICAvKiBmaW5kIHNjYWxpbmcgZm9yIGN1cnJlbnQgd2luZG93ICovCiAgICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgbWF4X2JhbmQ7IGJhbmQrKykKICAgICAgewogICAgICAgIFNwZWNTY2FsZV93aW5kb3cgPSBmTWF4KFNwZWNTY2FsZV93aW5kb3csIChpbnQpcFNmYlNjYWxlW3dpbmRvdyoxNitiYW5kXSk7CiAgICAgIH0KCiAgICAgIGlmIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+VG5zRGF0YS5BY3RpdmUpIHsKICAgICAgICBTcGVjU2NhbGVfd2luZG93ICs9IFROU19TQ0FMRTsKICAgICAgfQoKICAgICAgLyogc3RvcmUgc2NhbGluZyBvZiBjdXJyZW50IHdpbmRvdyAqLwogICAgICBwU3BlY1NjYWxlW3dpbmRvd10gPSBTcGVjU2NhbGVfd2luZG93OwoKI2lmZGVmIEZVTkNUSU9OX0NCbG9ja19TY2FsZVNwZWN0cmFsRGF0YV9mdW5jMQoKICAgICAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhX2Z1bmMxKHBTcGVjdHJ1bSwgbWF4X2JhbmQsIEJhbmRPZmZzZXRzLCBTcGVjU2NhbGVfd2luZG93LCBwU2ZiU2NhbGUsIHdpbmRvdyk7CgojZWxzZSAvKiBGVU5DVElPTl9DQmxvY2tfU2NhbGVTcGVjdHJhbERhdGFfZnVuYzEgKi8KICAgICAgZm9yIChiYW5kPTA7IGJhbmQgPCBtYXhfYmFuZDsgYmFuZCsrKQogICAgICB7CiAgICAgICAgaW50IHNjYWxlID0gU3BlY1NjYWxlX3dpbmRvdyAtIHBTZmJTY2FsZVt3aW5kb3cqMTYrYmFuZF07CiAgICAgICAgaWYgKHNjYWxlKQogICAgICAgIHsKICAgICAgICAgIC8qIGZvbGxvd2luZyByZWxhdGlvbiBjYW4gYmUgdXNlZCBmb3Igb3B0aW1pemF0aW9uczogKEJhbmRPZmZzZXRzW2ldJTQpID09IDAgZm9yIGFsbCBpICovCiAgICAgICAgICBpbnQgbWF4X2luZGV4ID0gQmFuZE9mZnNldHNbYmFuZCsxXTsKICAgICAgICAgIGZvciAoaW50IGluZGV4ID0gQmFuZE9mZnNldHNbYmFuZF07IGluZGV4IDwgbWF4X2luZGV4OyBpbmRleCsrKQogICAgICAgICAgewogICAgICAgICAgICBwU3BlY3RydW1baW5kZXhdID4+PSBzY2FsZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KI2VuZGlmICAvKiBGVU5DVElPTl9DQmxvY2tfU2NhbGVTcGVjdHJhbERhdGFfZnVuYzEgKi8KICAgIH0KICB9Cgp9CgpBQUNfREVDT0RFUl9FUlJPUiBDQmxvY2tfUmVhZFNlY3Rpb25EYXRhKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCAgZmxhZ3MpCnsKICBpbnQgdG9wLCBiYW5kOwogIGludCBzZWN0X2xlbiwgc2VjdF9sZW5faW5jcjsKICBpbnQgZ3JvdXA7CiAgVUNIQVIgc2VjdF9jYjsKICBVQ0hBUiAqcENvZGVCb29rID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFDb2RlQm9vazsKICAvKiBIQ1IgaW5wdXQgKGxvbmcpICovCiAgU0hPUlQgKnBOdW1MaW5lc0luU2VjICAgID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLmFOdW1MaW5lSW5TZWM0SGNyOwogIGludCAgICBudW1MaW5lc0luU2VjSWR4ICA9IDA7CiAgVUNIQVIgKnBIY3JDb2RlQm9vayAgICAgID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPnNwZWNpZmljVG8uYWFjLmFDb2RlQm9va3M0SGNyOwogIGNvbnN0IFNIT1JUICpCYW5kT2Zmc2V0cyA9IEdldFNjYWxlRmFjdG9yQmFuZE9mZnNldHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvKTsKICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMubnVtYmVyU2VjdGlvbiA9IDA7CiAgQUFDX0RFQ09ERVJfRVJST1IgRXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwoKICBGREttZW1jbGVhcihwQ29kZUJvb2ssIHNpemVvZihVQ0hBUikqKDgqMTYpKTsKCiAgY29uc3QgaW50IG5iaXRzID0gKElzTG9uZ0Jsb2NrKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSA9PSAxKSA/IDUgOiAzOwoKICBpbnQgc2VjdF9lc2NfdmFsID0gKDEgPDwgbmJpdHMpIC0gMSA7CgogIFVDSEFSIFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCA9IEdldFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7CiAgZm9yIChncm91cD0wOyBncm91cDxHZXRXaW5kb3dHcm91cHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOyBncm91cCsrKQogIHsKICAgIGZvciAoYmFuZD0wOyBiYW5kIDwgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkOyApCiAgICB7CiAgICAgIHNlY3RfbGVuID0gMDsKICAgICAgaWYgKCBmbGFncyAmIEFDX0VSX1ZDQjExICkgIHsKICAgICAgICBzZWN0X2NiID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw1KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgICAgc2VjdF9jYiA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CgogICAgICBpZiAoICgoZmxhZ3MgJiBBQ19FUl9WQ0IxMSkgPT0gMCkgfHwgKCBzZWN0X2NiIDwgMTEgKSB8fCAoKHNlY3RfY2IgPiAxMSkgJiYgKHNlY3RfY2IgPCAxNikpICkgewogICAgICAgIHNlY3RfbGVuX2luY3IgPSBGREtyZWFkQml0cyhicywgbmJpdHMpOwogICAgICAgIHdoaWxlIChzZWN0X2xlbl9pbmNyID09IHNlY3RfZXNjX3ZhbCkKICAgICAgICB7CiAgICAgICAgICBzZWN0X2xlbiArPSBzZWN0X2VzY192YWw7CiAgICAgICAgICBzZWN0X2xlbl9pbmNyID0gRkRLcmVhZEJpdHMoYnMsIG5iaXRzKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgc2VjdF9sZW5faW5jciA9IDE7CiAgICAgIH0KCiAgICAgIHNlY3RfbGVuICs9IHNlY3RfbGVuX2luY3I7CgoKICAgICAgdG9wID0gYmFuZCArIHNlY3RfbGVuOwoKICAgICAgaWYgKGZsYWdzICYgQUNfRVJfSENSKSB7CiAgICAgICAgLyogSENSIGlucHV0IChsb25nKSAtLSBjb2xsZWN0aW5nIHNpZGVpbmZvIChmb3IgSENSLV9sb25nXyBvbmx5KSAqLwogICAgICAgIHBOdW1MaW5lc0luU2VjW251bUxpbmVzSW5TZWNJZHhdID0gQmFuZE9mZnNldHNbdG9wXSAtIEJhbmRPZmZzZXRzW2JhbmRdOwogICAgICAgIG51bUxpbmVzSW5TZWNJZHgrKzsKICAgICAgICBpZiAobnVtTGluZXNJblNlY0lkeCA+PSBNQVhfU0ZCX0hDUikgewogICAgICAgICAgcmV0dXJuIEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgfQogICAgICAgIGlmIChzZWN0X2NiID09IEJPT0tTQ0wpCiAgICAgICAgewogICAgICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9DT0RFX0JPT0s7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICpwSGNyQ29kZUJvb2srKyA9IHNlY3RfY2I7CiAgICAgICAgfQogICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5udW1iZXJTZWN0aW9uKys7CiAgICAgIH0KCiAgICAgIC8qIENoZWNrIHNwZWN0cmFsIGxpbmUgbGltaXRzICovCiAgICAgIGlmIChJc0xvbmdCbG9jayggJihwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSApKQogICAgICB7CiAgICAgICAgaWYgKHRvcCA+IDY0KSB7CiAgICAgICAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgfQogICAgICB9IGVsc2UgeyAvKiBzaG9ydCBibG9jayAqLwogICAgICAgIGlmICh0b3AgKyBncm91cCoxNiA+ICg4ICogMTYpKSB7CiAgICAgICAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgfQogICAgICB9CgogICAgICAvKiBDaGVjayBpZiBkZWNvZGVkIGNvZGVib29rIGluZGV4IGlzIGZlYXNpYmxlICovCiAgICAgIGlmICggKHNlY3RfY2IgPT0gQk9PS1NDTCkKICAgICAgIHx8ICggKHNlY3RfY2IgPT0gSU5URU5TSVRZX0hDQiB8fCBzZWN0X2NiID09IElOVEVOU0lUWV9IQ0IyKSAmJiBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+UmF3RGF0YUluZm8uQ29tbW9uV2luZG93ID09IDApCiAgICAgICAgICkKICAgICAgewogICAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfQ09ERV9CT09LOwogICAgICB9CgogICAgICAvKiBTdG9yZSBjb2RlYm9vayBpbmRleCAqLwogICAgICBmb3IgKDsgYmFuZCA8IHRvcDsgYmFuZCsrKQogICAgICB7CiAgICAgICAgcENvZGVCb29rW2dyb3VwKjE2K2JhbmRdID0gc2VjdF9jYjsKICAgICAgfQogICAgfQogIH0KCgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKLyogbXNvOiBwcm92aWRlcyBhIGZhc3RlciB3YXkgdG8gaS1xdWFudGl6ZSBhIHdob2xlIGJhbmQgaW4gb25lIGdvICovCgovKioKICogXGJyaWVmIGludmVyc2UgcXVhbnRpemUgb25lIHNmYi4gRWFjaCB2YWx1ZSBvZiB0aGUgc2ZiIGlzIHByb2Nlc3NlZCBhY2NvcmRpbmcgdG8gdGhlCiAqICAgICAgICBmb3JtdWxhOiBzcGVjdHJ1bVtpXSA9IFNpZ24oc3BlY3RydW1baV0pICogTWF0aXNzYShzcGVjdHJ1bVtpXSleKDQvMykgKiAyXihsc2IvNCkuCiAqIFxwYXJhbSBzcGVjdHJ1bSBwb2ludGVyIHRvIGZpcnN0IGxpbmUgb2YgdGhlIHNmYiB0byBiZSBpbnZlcnNlIHF1YW50aXplZC4KICogXHBhcmFtIG5vTGluZXMgbnVtYmVyIG9mIGxpbmVzIGJlbG9uZ2luZyB0byB0aGUgc2ZiLgogKiBccGFyYW0gbHNiIGxhc3QgMiBiaXRzIG9mIHRoZSBzY2FsZSBmYWN0b3Igb2YgdGhlIHNmYi4KICogXHBhcmFtIHNjYWxlIG1heCBhbGxvd2VkIHNoaWZ0IHNjYWxlIGZvciB0aGUgc2ZiLgogKi8Kc3RhdGljCnZvaWQgSW52ZXJzZVF1YW50aXplQmFuZCggRklYUF9EQkwgKiBSRVNUUklDVCBzcGVjdHJ1bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG5vTGluZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBsc2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzY2FsZSApCnsKICAgIGNvbnN0IEZJWFBfREJMICogUkVTVFJJQ1QgSW52ZXJzZVF1YW50VGFibGVyPShGSVhQX0RCTCAqKUludmVyc2VRdWFudFRhYmxlOwogICAgY29uc3QgRklYUF9EQkwgKiBSRVNUUklDVCBNYW50aXNzYVRhYmxlcj0oRklYUF9EQkwgKilNYW50aXNzYVRhYmxlW2xzYl07CiAgICBjb25zdCBTQ0hBUiogUkVTVFJJQ1QgRXhwb25lbnRUYWJsZXI9KFNDSEFSKilFeHBvbmVudFRhYmxlW2xzYl07CgogICAgRklYUF9EQkwgKnB0ciA9IHNwZWN0cnVtOwogICAgRklYUF9EQkwgc2lnbmVkVmFsdWU7CgogICAgRkRLX0FTU0VSVChub0xpbmVzPjIpOwogICAgZm9yIChJTlQgaT1ub0xpbmVzOyBpLS07ICkKICAgIHsKICAgICAgICBpZiAoKHNpZ25lZFZhbHVlID0gKnB0cisrKSAhPSBGTDJGWENPTlNUX0RCTCgwKSkKICAgICAgICB7CiAgICAgICAgICBGSVhQX0RCTCB2YWx1ZSA9IGZBYnMoc2lnbmVkVmFsdWUpOwogICAgICAgICAgVUlOVCBmcmVlQml0cyA9IENudExlYWRpbmdaZXJvcyh2YWx1ZSk7CiAgICAgICAgICBVSU5UIGV4cG9uZW50ID0gMzIgLSBmcmVlQml0czsKCiAgICAgICAgICBVSU5UIHggPSAoVUlOVCkgKExPTkcpdmFsdWUgPDwgKElOVCkgZnJlZUJpdHM7CiAgICAgICAgICB4IDw8PSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzaGlmdCBvdXQgc2lnbiBiaXQgdG8gYXZvaWQgbWFza2luZyBsYXRlciBvbiAqLwogICAgICAgICAgVUlOVCB0YWJsZUluZGV4ID0geCA+PiAyNDsKICAgICAgICAgIHggPSAoeCA+PiAyMCkgJiAgMHgwRjsKCiAgICAgICAgICBVSU5UIHIwPShVSU5UKShMT05HKUludmVyc2VRdWFudFRhYmxlclt0YWJsZUluZGV4KzBdOwogICAgICAgICAgVUlOVCByMT0oVUlOVCkoTE9ORylJbnZlcnNlUXVhbnRUYWJsZXJbdGFibGVJbmRleCsxXTsKICAgICAgICAgIFVJTlQgdGVtcD0gKHIxIC0gcjApKnggKyAocjAgPDwgNCk7CgogICAgICAgICAgdmFsdWUgPSBmTXVsdERpdjIoKEZJWFBfREJMKXRlbXAsIE1hbnRpc3NhVGFibGVyW2V4cG9uZW50XSk7CgogICAgICAgICAgLyogKyAxIGNvbXBlbnNhdGVzIGZNdWx0RGl2MigpICovCiAgICAgICAgICBzY2FsZVZhbHVlSW5QbGFjZSgmdmFsdWUsIHNjYWxlICsgRXhwb25lbnRUYWJsZXJbZXhwb25lbnRdICsgMSk7CgogICAgICAgICAgc2lnbmVkVmFsdWUgPSAoc2lnbmVkVmFsdWUgPCAoRklYUF9EQkwpMCkgPyAtdmFsdWUgOiB2YWx1ZTsKICAgICAgICAgIHB0clstMV0gPSBzaWduZWRWYWx1ZTsKICAgICAgICB9CiAgICB9Cn0KCkFBQ19ERUNPREVSX0VSUk9SIENCbG9ja19JbnZlcnNlUXVhbnRpemVTcGVjdHJhbERhdGEoQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8pCnsKICBpbnQgd2luZG93LCBncm91cCwgZ3JvdXB3aW4sIGJhbmQ7CiAgaW50IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCA9IEdldFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyk7CiAgVUNIQVIgKlJFU1RSSUNUIHBDb2RlQm9vayA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hQ29kZUJvb2s7CiAgU0hPUlQgKlJFU1RSSUNUIHBTZmJTY2FsZSA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2ZiU2NhbGU7CiAgU0hPUlQgKlJFU1RSSUNUIHBTY2FsZUZhY3RvciA9IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3I7CiAgY29uc3QgU0hPUlQgKlJFU1RSSUNUIEJhbmRPZmZzZXRzID0gR2V0U2NhbGVGYWN0b3JCYW5kT2Zmc2V0cygmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8pOwoKICBGREttZW1jbGVhcihwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YVNmYlNjYWxlLCAoOCoxNikqc2l6ZW9mKFNIT1JUKSk7CgogIGZvciAod2luZG93PTAsIGdyb3VwPTA7IGdyb3VwIDwgR2V0V2luZG93R3JvdXBzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsgZ3JvdXArKykKICB7CiAgICBmb3IgKGdyb3Vwd2luPTA7IGdyb3Vwd2luIDwgR2V0V2luZG93R3JvdXBMZW5ndGgoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sZ3JvdXApOyBncm91cHdpbisrLCB3aW5kb3crKykKICAgIHsKICAgICAgLyogaW52ZXJzZSBxdWFudGl6YXRpb24gKi8KICAgICAgZm9yIChiYW5kPTA7IGJhbmQgPCBTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQ7IGJhbmQrKykKICAgICAgewogICAgICAgIEZJWFBfREJMICpwU3BlY3RyYWxDb2VmZmljaWVudCA9IFNQRUMocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQsIHdpbmRvdywgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+Z3JhbnVsZUxlbmd0aCkgKyBCYW5kT2Zmc2V0c1tiYW5kXTsKCiAgICAgICAgaW50IG5vTGluZXMgPSBCYW5kT2Zmc2V0c1tiYW5kKzFdIC0gQmFuZE9mZnNldHNbYmFuZF07CiAgICAgICAgaW50IGJuZHMgPSBncm91cCoxNitiYW5kOwogICAgICAgIGludCBpOwoKICAgICAgICBpZiAoKHBDb2RlQm9va1tibmRzXSA9PSBaRVJPX0hDQikKICAgICAgICAgfHwgKHBDb2RlQm9va1tibmRzXSA9PSBJTlRFTlNJVFlfSENCKQogICAgICAgICB8fCAocENvZGVCb29rW2JuZHNdID09IElOVEVOU0lUWV9IQ0IyKQogICAgICAgICAgICkKICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBpZiAocENvZGVCb29rW2JuZHNdID09IE5PSVNFX0hDQikKICAgICAgICB7CiAgICAgICAgICAvKiBMZWF2ZSBoZWFkcm9vbSBmb3IgUE5TIHZhbHVlcy4gKyAxIGJlY2F1c2UgY2VpbChsb2cyKDJeKDAuMjUqMykpKSA9IDEsCiAgICAgICAgICAgICB3b3JzdCBjYXNlIG9mIGFkZGl0aW9uYWwgaGVhZHJvb20gcmVxdWlyZWQgYmVjYXVzZSBvZiB0aGUgc2NhbGVmYWN0b3IuICovCiAgICAgICAgICBwU2ZiU2NhbGVbd2luZG93KjE2K2JhbmRdID0gKHBTY2FsZUZhY3RvciBbYm5kc10gPj4gMikgKyAxIDsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLyogRmluZCBtYXggc3BlY3RyYWwgbGluZSB2YWx1ZSBvZiB0aGUgY3VycmVudCBzZmIgKi8KICAgICAgICBGSVhQX0RCTCBsb2NNYXggPSAoRklYUF9EQkwpMDsKCiAgICAgICAgZm9yIChpID0gbm9MaW5lczsgaS0tIDsgKSB7CiAgICAgICAgICAvKiBFeHBlbnNpdmUgbWVtb3J5IGFjY2VzcyAqLwogICAgICAgICAgbG9jTWF4ID0gZk1heChmaXhwX2FicyhwU3BlY3RyYWxDb2VmZmljaWVudFtpXSksIGxvY01heCk7CiAgICAgICAgfQoKICAgICAgICAvKiBDaGVhcCByb2J1c3RuZXNzIGltcHJvdmVtZW50IC0gRG8gbm90IHJlbW92ZSEhISAqLwogICAgICAgIGlmIChmaXhwX2Ficyhsb2NNYXgpID4gKEZJWFBfREJMKU1BWF9RVUFOVElaRURfVkFMVUUpIHsKICAgICAgICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICAgVGhlIGludmVyc2UgcXVhbnRpemVkIHNwZWN0cmFsIGxpbmVzIGFyZSBkZWZpbmVkIGJ5OgogICAgICAgIHBTcGVjdHJhbENvZWZmaWNpZW50W2ldID0gU2lnbihwU3BlY3RyYWxDb2VmZmljaWVudFtpXSkgKiAyXigwLjI1KnBTY2FsZUZhY3RvcltibmRzXSkgKiBwU3BlY3RyYWxDb2VmZmljaWVudFtpXV4oNC8zKQogICAgICAgICAgIFRoaXMgaXMgZXF1aXZhbGVudCB0bzoKICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudFtpXSAgICA9IFNpZ24ocFNwZWN0cmFsQ29lZmZpY2llbnRbaV0pICogKDJeKHBTY2FsZUZhY3RvcltibmRzXSAlIDQpICogcFNwZWN0cmFsQ29lZmZpY2llbnRbaV1eKDQvMykpCiAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnRfZVtpXSArPSBwU2NhbGVGYWN0b3JbYm5kc10vNAogICAgICAgICovCiAgICAgICAgewogICAgICAgICAgaW50IG1zYiA9IHBTY2FsZUZhY3RvciBbYm5kc10gPj4gMiA7CiAgICAgICAgICBpbnQgbHNiID0gcFNjYWxlRmFjdG9yIFtibmRzXSAmIDB4MDMgOwoKICAgICAgICAgIGludCBzY2FsZSA9IEdldFNjYWxlRnJvbVZhbHVlKGxvY01heCwgbHNiKTsKCiAgICAgICAgICBwU2ZiU2NhbGVbd2luZG93KjE2K2JhbmRdID0gbXNiIC0gc2NhbGU7CiAgICAgICAgICBJbnZlcnNlUXVhbnRpemVCYW5kKHBTcGVjdHJhbENvZWZmaWNpZW50LCBub0xpbmVzLCBsc2IsIHNjYWxlKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKCkFBQ19ERUNPREVSX0VSUk9SICBDQmxvY2tfUmVhZFNwZWN0cmFsRGF0YShIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgIGZsYWdzKQp7CiAgaW50IGksaW5kZXg7CiAgaW50IHdpbmRvdyxncm91cCxncm91cHdpbixncm91cG9mZnNldCxiYW5kOwogIFVDSEFSICpSRVNUUklDVCBwQ29kZUJvb2sgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YUNvZGVCb29rOwogIGNvbnN0IFNIT1JUICpSRVNUUklDVCBCYW5kT2Zmc2V0cyA9IEdldFNjYWxlRmFjdG9yQmFuZE9mZnNldHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvKTsKCiAgU1BFQ1RSQUxfUFRSIHBTcGVjdHJhbENvZWZmaWNpZW50ID0gcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQ7CiAgRklYUF9EQkwgbG9jTWF4OwoKICBpbnQgU2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKTsKCiAgRkRLX0FTU0VSVChCYW5kT2Zmc2V0cyAhPSBOVUxMKTsKCiAgRkRLbWVtY2xlYXIocFNwZWN0cmFsQ29lZmZpY2llbnQsIHNpemVvZihTUEVDVFJVTSkpOwoKICBpZiAoIChmbGFncyAmIEFDX0VSX0hDUikgPT0gMCApCiAgewogICAgZ3JvdXBvZmZzZXQgPSAwOwoKICAgIC8qIHBsYWluIGh1ZmZtYW4gZGVjb2RlciAgc2hvcnQgKi8KICAgIGZvciAoZ3JvdXA9MDsgZ3JvdXAgPCBHZXRXaW5kb3dHcm91cHMoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pOyBncm91cCsrKQogICAgewogICAgICBmb3IgKGJhbmQ9MDsgYmFuZCA8IFNjYWxlRmFjdG9yQmFuZHNUcmFuc21pdHRlZDsgYmFuZCsrKQogICAgICB7CiAgICAgICAgaW50IGJuZHMgPSBncm91cCoxNitiYW5kOwogICAgICAgIFVDSEFSIGN1cnJlbnRDQiA9IHBDb2RlQm9va1tibmRzXTsKCiAgICAgICAgLyogcGF0Y2ggdG8gcnVuIHBsYWluLWh1ZmZtYW4tZGVjb2RlciB3aXRoIHZjYjExIGlucHV0IGNvZGVib29rcyAoTEFWLWNoZWNraW5nIG1pZ2h0IGJlIHBvc3NpYmxlIGJlbG93IHVzaW5nIHRoZSB2aXJ0dWFsIGNiIGFuZCBhIExBVi10YWJsZSkgKi8KICAgICAgICBpZiAoKGN1cnJlbnRDQiA+PSAxNikgJiYgKGN1cnJlbnRDQiA8PSAzMSkpIHsKICAgICAgICAgIHBDb2RlQm9va1tibmRzXSA9IGN1cnJlbnRDQiA9IDExOwogICAgICAgIH0KICAgICAgICBpZiAoICEoKGN1cnJlbnRDQiA9PSBaRVJPX0hDQikKICAgICAgICAgICAgfHwgKGN1cnJlbnRDQiA9PSBOT0lTRV9IQ0IpCiAgICAgICAgICAgIHx8IChjdXJyZW50Q0IgPT0gSU5URU5TSVRZX0hDQikKICAgICAgICAgICAgfHwgKGN1cnJlbnRDQiA9PSBJTlRFTlNJVFlfSENCMikpICkKICAgICAgICB7CiAgICAgICAgICBjb25zdCBDb2RlQm9va0Rlc2NyaXB0aW9uICpoY2IgPSAmQUFDY29kZUJvb2tEZXNjcmlwdGlvblRhYmxlW2N1cnJlbnRDQl07CiAgICAgICAgICBpbnQgc3RlcCA9IGhjYi0+RGltZW5zaW9uOwogICAgICAgICAgaW50IG9mZnNldCA9IGhjYi0+T2Zmc2V0OwogICAgICAgICAgaW50IGJpdHMgPSBoY2ItPm51bUJpdHM7CiAgICAgICAgICBpbnQgbWFzayA9ICgxPDxiaXRzKS0xOwoKICAgICAgICAgIGZvciAoZ3JvdXB3aW49MDsgZ3JvdXB3aW4gPCBHZXRXaW5kb3dHcm91cExlbmd0aCgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbyxncm91cCk7IGdyb3Vwd2luKyspCiAgICAgICAgICB7CiAgICAgICAgICAgIHdpbmRvdyA9IGdyb3Vwb2Zmc2V0ICsgZ3JvdXB3aW47CgogICAgICAgICAgICBGSVhQX0RCTCAqbWRjdFNwZWN0cnVtID0gU1BFQyhwU3BlY3RyYWxDb2VmZmljaWVudCwgd2luZG93LCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5ncmFudWxlTGVuZ3RoKTsKCiAgICAgICAgICAgIGxvY01heCA9IChGSVhQX0RCTCkwIDsKCiAgICAgICAgICAgIGZvciAoaW5kZXg9QmFuZE9mZnNldHNbYmFuZF07IGluZGV4IDwgQmFuZE9mZnNldHNbYmFuZCsxXTsgaW5kZXgrPXN0ZXApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBpbnQgaWR4ID0gQ0Jsb2NrX0RlY29kZUh1ZmZtYW5Xb3JkKGJzLGhjYik7CgogICAgICAgICAgICAgIGZvciAoaT0wOyBpPHN0ZXA7IGkrKykgewogICAgICAgICAgICAgICAgRklYUF9EQkwgdG1wOwoKICAgICAgICAgICAgICAgIHRtcCA9IChGSVhQX0RCTCkoKGlkeCAmIG1hc2spLW9mZnNldCk7CiAgICAgICAgICAgICAgICBpZHggPj49IGJpdHM7CgogICAgICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgIGlmICh0bXAgIT0gRklYUF9EQkwoMCkpCiAgICAgICAgICAgICAgICAgICAgdG1wID0gKEZES3JlYWRCaXRzKGJzLDEpKT8gLXRtcCA6IHRtcDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG1kY3RTcGVjdHJ1bVtpbmRleCtpXSA9IHRtcDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGlmIChjdXJyZW50Q0IgPT0gRVNDQk9PSykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtZGN0U3BlY3RydW1baW5kZXgrMF0gPSAoRklYUF9EQkwpQ0Jsb2NrX0dldEVzY2FwZShicywgKExPTkcpbWRjdFNwZWN0cnVtW2luZGV4KzBdKTsKICAgICAgICAgICAgICAgIG1kY3RTcGVjdHJ1bVtpbmRleCsxXSA9IChGSVhQX0RCTClDQmxvY2tfR2V0RXNjYXBlKGJzLCAoTE9ORyltZGN0U3BlY3RydW1baW5kZXgrMV0pOwoKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgZ3JvdXBvZmZzZXQgKz0gR2V0V2luZG93R3JvdXBMZW5ndGgoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8sZ3JvdXApOwogICAgfQogICAgLyogcGxhaW4gaHVmZm1hbiBkZWNvZGluZyAoc2hvcnQpIGZpbmlzaGVkICovCiAgfQogIC8qIEhDUiAtIEh1ZmZtYW4gQ29kZXdvcmQgUmVvcmRlcmluZyAgc2hvcnQgKi8KICBlbHNlICAvKiBpZiAoIGZsYWdzICYgQUNfRVJfSENSICkgKi8KICB7CiAgICBIX0hDUl9JTkZPIGhIY3IgPSAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cENvbURhdGEtPm92ZXJsYXkuYWFjLmVySGNySW5mbzsKICAgIGludCBoY3JTdGF0dXMgPSAwOwoKICAgIC8qIGFkdmFuY2VkIEh1ZmZtYW4gZGVjb2Rpbmcgc3RhcnRzIGhlcmUgKEhDUiBkZWNvZGluZyA6KSAqLwogICAgaWYgKCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+c3BlY2lmaWNUby5hYWMubGVuT2ZSZW9yZGVyZWRTcGVjdHJhbERhdGEgIT0gMCApIHsKCiAgICAgIC8qIEhDUiBpbml0aWFsaXphdGlvbiBzaG9ydCAqLwogICAgICBoY3JTdGF0dXMgPSBIY3JJbml0KGhIY3IsIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sIHBTYW1wbGluZ1JhdGVJbmZvLCBicyk7CgogICAgICBpZiAoaGNyU3RhdHVzICE9IDApIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgIH0KCiAgICAgIC8qIEhDUiBkZWNvZGluZyBzaG9ydCAqLwogICAgICBoY3JTdGF0dXMgPSBIY3JEZWNvZGVyKGhIY3IsIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sIHBTYW1wbGluZ1JhdGVJbmZvLCBicyk7CgogICAgICBpZiAoaGNyU3RhdHVzICE9IDApIHsKI2lmIEhDUl9FUlJPUl9DT05DRUFMTUVOVAogICAgICAgIEhjck11dGVFcnJvbmVvdXNMaW5lcyhoSGNyKTsKI2Vsc2UKICAgICAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiNlbmRpZiAvKiBIQ1JfRVJST1JfQ09OQ0VBTE1FTlQgKi8KICAgICAgfQoKICAgICAgRkRLcHVzaEZvciAoYnMsIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5sZW5PZlJlb3JkZXJlZFNwZWN0cmFsRGF0YSk7CiAgICB9CiAgfQogIC8qIEhDUiAtIEh1ZmZtYW4gQ29kZXdvcmQgUmVvcmRlcmluZyBzaG9ydCBmaW5pc2hlZCAqLwoKCgogIGlmICggSXNMb25nQmxvY2soJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm8pICYmICEoZmxhZ3MgJiAoQUNfRUxEfEFDX1NDQUxBQkxFKSkgKQogIHsKICAgIC8qIGFwcGx5IHB1bHNlIGRhdGEgKi8KICAgIENQdWxzZURhdGFfQXBwbHkoJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5zcGVjaWZpY1RvLmFhYy5QdWxzZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICBHZXRTY2FsZUZhY3RvckJhbmRPZmZzZXRzKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLCBwU2FtcGxpbmdSYXRlSW5mbyksCiAgICAgICAgICAgICAgICAgICAgICBTUEVDX0xPTkcocFNwZWN0cmFsQ29lZmZpY2llbnQpKTsKICB9CgoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKCgp2b2lkIEFwcGx5VG9vbHMgKCBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvW10sCiAgICAgICAgICAgICAgICAgIGNvbnN0IFNhbXBsaW5nUmF0ZUluZm8gKnBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICBjb25zdCBVSU5UIGZsYWdzLAogICAgICAgICAgICAgICAgICBjb25zdCBpbnQgY2hhbm5lbCApCnsKCiAgaWYgKCAhKGZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX01QU19SRVMpKSApIHsKICAgIENQbnNfQXBwbHkoCiAgICAgICAgICAgJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPmRhdGEuYWFjLlBuc0RhdGEsCiAgICAgICAgICAgJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPmljc0luZm8sCiAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPnBTcGVjdHJhbENvZWZmaWNpZW50LAogICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoYW5uZWxdLT5zcGVjU2NhbGUsCiAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3IsCiAgICAgICAgICAgIHBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoYW5uZWxdLT5ncmFudWxlTGVuZ3RoLAogICAgICAgICAgICBjaGFubmVsCiAgICAgICAgICAgICk7CiAgfQoKICBDVG5zX0FwcGx5ICgKICAgICAgICAgJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPnBEeW5EYXRhLT5UbnNEYXRhLAogICAgICAgICAmcEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaGFubmVsXS0+aWNzSW5mbywKICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hhbm5lbF0tPnBTcGVjdHJhbENvZWZmaWNpZW50LAogICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoYW5uZWxdLT5ncmFudWxlTGVuZ3RoCiAgICAgICAgICApOwp9CgpzdGF0aWMKaW50IGdldFdpbmRvdzJOcihpbnQgbGVuZ3RoLCBpbnQgc2hhcGUpCnsKICBpbnQgbnIgPSAwOwoKICBpZiAoc2hhcGUgPT0gMikgewogICAgLyogTG93IE92ZXJsYXAsIDMvNCB6ZXJvZWQgKi8KICAgIG5yID0gKGxlbmd0aCAqIDMpPj4yOwogIH0KCiAgcmV0dXJuIG5yOwp9Cgp2b2lkIENCbG9ja19GcmVxdWVuY3lUb1RpbWUoQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfUENNIG91dFNhbXBsZXNbXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNIT1JUIGZyYW1lTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IHN0cmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBmcmFtZU9rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBXb3JrQnVmZmVyMSApCnsKICBpbnQgZnIsIGZsLCB0bCwgblNhbXBsZXMsIG5TcGVjOwoKICAvKiBEZXRlcm1pbmUgbGVmdCBzbG9wZSBsZW5ndGggKGZsKSwgcmlnaHQgc2xvcGUgbGVuZ3RoIChmcikgYW5kIHRyYW5zZm9ybSBsZW5ndGggKHRsKS4KICAgICBVU0FDOiBUaGUgc2xvcGUgbGVuZ3RoIG1heSBtaXNtYXRjaCB3aXRoIHRoZSBwcmV2aW91cyBmcmFtZSBpbiBjYXNlIG9mIExQRCAvIEZECiAgICAgICAgICAgdHJhbnNpdGlvbnMuIFRoZSBhZGp1c3RtZW50IGlzIGhhbmRsZWQgYnkgdGhlIGltZGN0IGltcGxlbWVudGF0aW9uLgogICovCiAgdGwgPSBmcmFtZUxlbjsKICBuU3BlYyA9IDE7CgogIHN3aXRjaCggcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mby5XaW5kb3dTZXF1ZW5jZSApIHsKICAgIGRlZmF1bHQ6CiAgICBjYXNlIE9ubHlMb25nU2VxdWVuY2U6CiAgICAgIGZsID0gZnJhbWVMZW47CiAgICAgIGZyID0gZnJhbWVMZW4gLSBnZXRXaW5kb3cyTnIoZnJhbWVMZW4sIEdldFdpbmRvd1NoYXBlKCZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvKSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBMb25nU3RvcFNlcXVlbmNlOgogICAgICBmbCA9IGZyYW1lTGVuID4+IDM7CiAgICAgIGZyID0gZnJhbWVMZW47CiAgICAgIGJyZWFrOwogICAgY2FzZSBMb25nU3RhcnRTZXF1ZW5jZTogLyogb3IgU3RvcFN0YXJ0U2VxdWVuY2UgKi8KICAgICAgZmwgPSBmcmFtZUxlbjsKICAgICAgZnIgPSBmcmFtZUxlbiA+PiAzOwogICAgICBicmVhazsKICAgIGNhc2UgRWlnaHRTaG9ydFNlcXVlbmNlOgogICAgICBmbCA9IGZyID0gZnJhbWVMZW4gPj4gMzsKICAgICAgdGwgPj49IDM7CiAgICAgIG5TcGVjID0gODsKICAgICAgYnJlYWs7CiAgfQoKICB7CiAgICBpbnQgaTsKCiAgICB7CiAgICAgIEZJWFBfREJMICp0bXAgPSBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wQ29tRGF0YS0+d29ya0J1ZmZlckNvcmUxLT5tZGN0T3V0VGVtcDsKCiAgICAgIG5TYW1wbGVzID0gaW1kY3RfYmxvY2soCiAgICAgICAgICAgICAmcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mby0+SU1kY3QsCiAgICAgICAgICAgICAgdG1wLAogICAgICAgICAgICAgIFNQRUNfTE9ORyhwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCksCiAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlLAogICAgICAgICAgICAgIG5TcGVjLAogICAgICAgICAgICAgIGZyYW1lTGVuLAogICAgICAgICAgICAgIHRsLAogICAgICAgICAgICAgIEZES2dldFdpbmRvd1Nsb3BlKGZsLCBHZXRXaW5kb3dTaGFwZSgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbykpLAogICAgICAgICAgICAgIGZsLAogICAgICAgICAgICAgIEZES2dldFdpbmRvd1Nsb3BlKGZyLCBHZXRXaW5kb3dTaGFwZSgmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbykpLAogICAgICAgICAgICAgIGZyLAogICAgICAgICAgICAgIChGSVhQX0RCTCkwICk7CgogICAgICBmb3IgKGk9MDsgaTxmcmFtZUxlbjsgaSsrKSB7CiAgICAgICAgb3V0U2FtcGxlc1tpKnN0cmlkZV0gPSBJTURDVF9TQ0FMRSh0bXBbaV0pOwogICAgICB9CiAgICB9CiAgfQoKICBGREtfQVNTRVJUKG5TYW1wbGVzID09IGZyYW1lTGVuKTsKCn0KCiNpbmNsdWRlICJsZGZpbHRiYW5rLmgiCnZvaWQgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZUxvd0RlbGF5KCBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00gb3V0U2FtcGxlc1tdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2hvcnQgZnJhbWVMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyIHN0cmlkZSApCnsKICBJbnZNZGN0VHJhbnNmb3JtTG93RGVsYXlfZmRrICgKICAgICAgICAgIFNQRUNfTE9ORyhwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCksCiAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5zcGVjU2NhbGVbMF0sCiAgICAgICAgICBvdXRTYW1wbGVzLAogICAgICAgICAgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mby0+cE92ZXJsYXBCdWZmZXIsCiAgICAgICAgICBzdHJpZGUsCiAgICAgICAgICBmcmFtZUxlbgogICAgICAgICAgKTsKfQo=