Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBEYW5pZWwgSG9tbQogICBEZXNjcmlwdGlvbjoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJ0cGRlY19saWIuaCIKI2luY2x1ZGUgInRwX2RhdGEuaCIKI2lmZGVmIFRQX1BDRV9FTkFCTEUKI2luY2x1ZGUgIkZES19jcmMuaCIKI2VuZGlmCgoKdm9pZCBDUHJvZ3JhbUNvbmZpZ19SZXNldChDUHJvZ3JhbUNvbmZpZyAqcFBjZSkKewogIHBQY2UtPmVsQ291bnRlciA9IDA7Cn0KCnZvaWQgQ1Byb2dyYW1Db25maWdfSW5pdChDUHJvZ3JhbUNvbmZpZyAqcFBjZSkKewogIEZES21lbWNsZWFyKHBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwojaWZkZWYgVFBfUENFX0VOQUJMRQogIHBQY2UtPlNhbXBsaW5nRnJlcXVlbmN5SW5kZXggPSAweGY7CiNlbmRpZgp9CgppbnQgIENQcm9ncmFtQ29uZmlnX0lzVmFsaWQgKCBjb25zdCBDUHJvZ3JhbUNvbmZpZyAqcFBjZSApCnsKICByZXR1cm4gKCAocFBjZS0+aXNWYWxpZCkgPyAxIDogMCk7Cn0KCiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiNkZWZpbmUgUENFX0hFSUdIVF9FWFRfU1lOQyAgKCAweEFDICkKCi8qCiAqIFJlYWQgdGhlIGV4dGVuc2lvbiBmb3IgaGVpZ2h0IGluZm8uCiAqIHJldHVybiAwIGlmIHN1Y2Nlc3NmdWxsIG9yIC0xIGlmIHRoZSBDUkMgZmFpbGVkLgogKi8Kc3RhdGljCmludCBDUHJvZ3JhbUNvbmZpZ19SZWFkSGVpZ2h0RXh0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqIGNvbnN0IGJ5dGVzQXZhaWxhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCBhbGlnbm1lbnRBbmNob3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgZXJyID0gMDsKICBGREtfQ1JDSU5GTyBjcmNJbmZvOyAgICAvKiBDUkMgc3RhdGUgaW5mbyAqLwogIElOVCBjcmNSZWc7CiAgRkRLY3JjSW5pdCgmY3JjSW5mbywgMHgwNywgMHhGRiwgOCk7CiAgY3JjUmVnID0gRkRLY3JjU3RhcnRSZWcoJmNyY0luZm8sIGJzLCAwKTsKICBVSU5UIHN0YXJ0QW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgRkRLX0FTU0VSVChwUGNlICE9IE5VTEwpOwogIEZES19BU1NFUlQoYnMgIT0gTlVMTCk7CiAgRkRLX0FTU0VSVChieXRlc0F2YWlsYWJsZSAhPSBOVUxMKTsKCiAgaWYgKCAoc3RhcnRBbmNob3IgPj0gMjQpICYmICgqYnl0ZXNBdmFpbGFibGUgPj0gMykKICAgICYmIChGREtyZWFkQml0cyhicyw4KSA9PSBQQ0VfSEVJR0hUX0VYVF9TWU5DKSApCiAgewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSsrKQogICAgewogICAgICBwUGNlLT5Gcm9udEVsZW1lbnRIZWlnaHRJbmZvW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywyKTsKICAgIH0KICAgIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgaSsrKQogICAgewogICAgICBwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9baV0gPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDIpOwogICAgfQogICAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgICB7CiAgICAgIHBQY2UtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgICB9CiAgICBGREtieXRlQWxpZ24oYnMsIGFsaWdubWVudEFuY2hvcik7CgogICAgRkRLY3JjRW5kUmVnKCZjcmNJbmZvLCBicywgY3JjUmVnKTsKICAgIGlmICgoVVNIT1JUKUZES3JlYWRCaXRzKGJzLDgpICE9IEZES2NyY0dldENSQygmY3JjSW5mbykpIHsKICAgICAgLyogQ1JDIGZhaWxlZCAqLwogICAgICBlcnIgPSAtMTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICAvKiBObyB2YWxpZCBleHRlbnNpb24gZGF0YSBmb3VuZCAtPiByZXN0b3JlIHRoZSBpbml0aWFsIGJpdGJ1ZmZlciBzdGF0ZSAqLwogICAgRkRLcHVzaEJhY2soYnMsIHN0YXJ0QW5jaG9yIC0gRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CiAgfQoKICAvKiBBbHdheXMgcmVwb3J0IHRoZSBieXRlcyByZWFkLiAqLwogICpieXRlc0F2YWlsYWJsZSAtPSAoc3RhcnRBbmNob3IgLSBGREtnZXRWYWxpZEJpdHMoYnMpKSA+PiAzOwoKICByZXR1cm4gKGVycik7Cn0KCnZvaWQgQ1Byb2dyYW1Db25maWdfUmVhZCgKICAgICAgICAgICAgICAgICAgICAgICAgICBDUHJvZ3JhbUNvbmZpZyAqcFBjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGFsaWdubWVudEFuY2hvcgogICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgaSwgZXJyID0gMDsKICBpbnQgY29tbWVudEJ5dGVzOwoKICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyA9IDA7CiAgcFBjZS0+TnVtQ2hhbm5lbHMgPSAwOwogIHBQY2UtPkVsZW1lbnRJbnN0YW5jZVRhZyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgcFBjZS0+UHJvZmlsZSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgcFBjZS0+U2FtcGxpbmdGcmVxdWVuY3lJbmRleCA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgcFBjZS0+TnVtQXNzb2NEYXRhRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDMpOwogIHBQY2UtPk51bVZhbGlkQ2NFbGVtZW50cyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CgogIGlmICgocFBjZS0+TW9ub01peGRvd25QcmVzZW50ID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKSkgIT0gMCkKICB7CiAgICBwUGNlLT5Nb25vTWl4ZG93bkVsZW1lbnROdW1iZXIgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgaWYgKChwUGNlLT5TdGVyZW9NaXhkb3duUHJlc2VudCA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMSkpICE9IDApCiAgewogICAgcFBjZS0+U3RlcmVvTWl4ZG93bkVsZW1lbnROdW1iZXIgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgaWYgKChwUGNlLT5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50ID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKSkgIT0gMCkKICB7CiAgICBwUGNlLT5NYXRyaXhNaXhkb3duSW5kZXggPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDIpOwogICAgcFBjZS0+UHNldWRvU3Vycm91bmRFbmFibGUgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDEpOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSsrKQogIHsKICAgIHBQY2UtPkZyb250RWxlbWVudElzQ3BlW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPkZyb250RWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSA/IDIgOiAxOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgewogICAgcFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMSk7CiAgICBwUGNlLT5TaWRlRWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSBwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldID8gMiA6IDE7CiAgfQoKICBmb3IgKGk9MDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBwUGNlLT5CYWNrRWxlbWVudElzQ3BlW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPkJhY2tFbGVtZW50VGFnU2VsZWN0W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw0KTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICs9IHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0gPyAyIDogMTsKICB9CgogIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzID0gcFBjZS0+TnVtQ2hhbm5lbHM7CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtTGZlQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgewogICAgcFBjZS0+TGZlRWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSAxOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Bc3NvY0RhdGFFbGVtZW50czsgaSsrKQogIHsKICAgIHBQY2UtPkFzc29jRGF0YUVsZW1lbnRUYWdTZWxlY3RbaV0gPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1WYWxpZENjRWxlbWVudHM7IGkrKykKICB7CiAgICBwUGNlLT5DY0VsZW1lbnRJc0luZFN3W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPlZhbGlkQ2NFbGVtZW50VGFnU2VsZWN0W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw0KTsKICB9CgogIEZES2J5dGVBbGlnbihicywgYWxpZ25tZW50QW5jaG9yKTsKCiAgcFBjZS0+Q29tbWVudEZpZWxkQnl0ZXMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDgpOwogIGNvbW1lbnRCeXRlcyA9IHBQY2UtPkNvbW1lbnRGaWVsZEJ5dGVzOwoKICAvKiBTZWFyY2ggZm9yIGhlaWdodCBpbmZvIGV4dGVuc2lvbiBhbmQgcmVhZCBpdCBpZiBhdmFpbGFibGUgKi8KICBlcnIgPSBDUHJvZ3JhbUNvbmZpZ19SZWFkSGVpZ2h0RXh0KCBwUGNlLCBicywgJmNvbW1lbnRCeXRlcywgYWxpZ25tZW50QW5jaG9yICk7CgogIGZvciAoaT0wOyBpIDwgY29tbWVudEJ5dGVzOyBpKyspCiAgewogICAgVUNIQVIgdGV4dDsKCiAgICB0ZXh0ID0gKFVDSEFSKUZES3JlYWRCaXRzKGJzLDgpOwoKICAgIGlmIChpIDwgUENfQ09NTUVOVExFTkdUSCkKICAgIHsKICAgICAgcFBjZS0+Q29tbWVudFtpXSA9IHRleHQ7CiAgICB9CiAgfQoKICBwUGNlLT5pc1ZhbGlkID0gKGVycikgPyAwIDogMTsKfQoKLyoKICogQ29tcGFyZSB0d28gcHJvZ3JhbSBjb25maWd1cmF0aW9ucy4KICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBjb21wYXJpc29uOgogKiAgLTEgLSBjb21wbGV0ZWx5IGRpZmZlcmVudAogKiAgIDAgLSBjb21wbGV0ZWx5IGVxdWFsCiAqICAgMSAtIGRpZmZlcmVudCBidXQgc2FtZSBjaGFubmVsIGNvbmZpZ3VyYXRpb24KICogICAyIC0gZGlmZmVyZW50IGNoYW5uZWwgY29uZmlndXJhdGlvbiBidXQgc2FtZSBudW1iZXIgb2YgY2hhbm5lbHMKICovCmludCBDUHJvZ3JhbUNvbmZpZ19Db21wYXJlICggY29uc3QgQ1Byb2dyYW1Db25maWcgKiBjb25zdCBwUGNlMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDUHJvZ3JhbUNvbmZpZyAqIGNvbnN0IHBQY2UyICkKewogIGludCByZXN1bHQgPSAwOyAgLyogSW5ub2NlbnQgdW50aWwgcHJvdmVuIGZhbHNlLiAqLwoKICBpZiAoRkRLbWVtY21wKHBQY2UxLCBwUGNlMiwgc2l6ZW9mKENQcm9ncmFtQ29uZmlnKSkgIT0gMCkKICB7IC8qIENvbmZpZ3VyYXRpb25zIGFyZSBub3QgY29tcGxldGVseSBkaWZmZXJlbnQuCiAgICAgICBTbyBsb29rIGludG8gZGV0YWlscyBhbmQgYW5hbHlzZSB0aGUgY2hhbm5lbCBjb25maWd1cmF0aW9uczogKi8KICAgIHJlc3VsdCA9IC0xOwoKICAgIGlmIChwUGNlMS0+TnVtQ2hhbm5lbHMgPT0gcFBjZTItPk51bUNoYW5uZWxzKQogICAgeyAvKiBOb3cgdGhlIGxvZ2ljIGNoYW5nZXMuIFdlIGZpcnN0IGFzc3VtZSB0byBoYXZlIHRoZSBzYW1lIGNoYW5uZWwgY29uZmlndXJhdGlvbgogICAgICAgICBhbmQgdGhlbiBwcm92ZSBpZiB0aGlzIGFzc3VtcHRpb24gaXMgdHJ1ZS4gKi8KICAgICAgcmVzdWx0ID0gMTsKCiAgICAgIC8qIEZyb250IGNoYW5uZWxzICovCiAgICAgIGlmIChwUGNlMS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzKSB7CiAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgZnJvbnQgY2hhbm5lbCBlbGVtZW50cyAqLwogICAgICB9IGVsc2UgewogICAgICAgIGludCBlbCwgbnVtQ2gxID0gMCwgbnVtQ2gyID0gMDsKICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlMS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgICAgIGlmIChwUGNlMS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gIT0gcFBjZTItPkZyb250RWxlbWVudEhlaWdodEluZm9bZWxdKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IDI7IC8qIGRpZmZlcmVudCBoZWlnaHQgaW5mbyAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIG51bUNoMSArPSBwUGNlMS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgICBudW1DaDIgKz0gcFBjZTItPkZyb250RWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICBpZiAobnVtQ2gxICE9IG51bUNoMikgewogICAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgZnJvbnQgY2hhbm5lbHMgKi8KICAgICAgICB9CiAgICAgIH0KICAgICAgLyogU2lkZSBjaGFubmVscyAqLwogICAgICBpZiAocFBjZTEtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bVNpZGVDaGFubmVsRWxlbWVudHMpIHsKICAgICAgICByZXN1bHQgPSAyOyAgLyogZGlmZmVyZW50IG51bWJlciBvZiBzaWRlIGNoYW5uZWwgZWxlbWVudHMgKi8KICAgICAgfSBlbHNlIHsKICAgICAgICBpbnQgZWwsIG51bUNoMSA9IDAsIG51bUNoMiA9IDA7CiAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZTEtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgICAgIGlmIChwUGNlMS0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2VsXSAhPSBwUGNlMi0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2VsXSkgewogICAgICAgICAgICByZXN1bHQgPSAyOyAvKiBkaWZmZXJlbnQgaGVpZ2h0IGluZm8gKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBudW1DaDEgKz0gcFBjZTEtPlNpZGVFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgICBudW1DaDIgKz0gcFBjZTItPlNpZGVFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgfQogICAgICAgIGlmIChudW1DaDEgIT0gbnVtQ2gyKSB7CiAgICAgICAgICByZXN1bHQgPSAyOyAgLyogZGlmZmVyZW50IG51bWJlciBvZiBzaWRlIGNoYW5uZWxzICovCiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIEJhY2sgY2hhbm5lbHMgKi8KICAgICAgaWYgKHBQY2UxLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzICE9IHBQY2UyLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzKSB7CiAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgYmFjayBjaGFubmVsIGVsZW1lbnRzICovCiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50IGVsLCBudW1DaDEgPSAwLCBudW1DaDIgPSAwOwogICAgICAgIGZvciAoZWwgPSAwOyBlbCA8IHBQY2UxLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgICAgICBpZiAocFBjZTEtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0gIT0gcFBjZTItPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0pIHsKICAgICAgICAgICAgcmVzdWx0ID0gMjsgLyogZGlmZmVyZW50IGhlaWdodCBpbmZvICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgbnVtQ2gxICs9IHBQY2UxLT5CYWNrRWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgICAgbnVtQ2gyICs9IHBQY2UyLT5CYWNrRWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICBpZiAobnVtQ2gxICE9IG51bUNoMikgewogICAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgYmFjayBjaGFubmVscyAqLwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBMRkUgY2hhbm5lbHMgKi8KICAgICAgaWYgKHBQY2UxLT5OdW1MZmVDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bUxmZUNoYW5uZWxFbGVtZW50cykgewogICAgICAgIHJlc3VsdCA9IDI7ICAvKiBkaWZmZXJlbnQgbnVtYmVyIG9mIGxmZSBjaGFubmVscyAqLwogICAgICB9CiAgICAgIC8qIExGRXMgYXJlIGFsd2F5cyBTQ0VzIHNvIHdlIGRvbid0IG5lZWQgdG8gY291bnQgdGhlIGNoYW5uZWxzLiAqLwogICAgfQogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKdm9pZCBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KCBDUHJvZ3JhbUNvbmZpZyAqcFBjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UIGNoYW5uZWxDb25maWcgKQp7CiAgRkRLX0FTU0VSVChwUGNlICE9IE5VTEwpOwoKICAvKiBJbml0IFBDRSAqLwogIENQcm9ncmFtQ29uZmlnX0luaXQocFBjZSk7CiAgcFBjZS0+UHJvZmlsZSA9IDE7ICAvKiBTZXQgQUFDIExDIGJlY2F1c2UgaXQgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIG9iamVjdCB0eXBlLiAqLwoKICBzd2l0Y2ggKGNoYW5uZWxDb25maWcpIHsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAzMjogLyogNy4xIHNpZGUgY2hhbm5lbCBjb25maWd1cmF0aW9uIGFzIGRlZmluZWQgaW4gRkRLX2F1ZGlvLmggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICA9IDI7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVswXSAgICAgPSAwOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMV0gICAgID0gMTsKICAgIHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgICA9IDE7CiAgICBwUGNlLT5TaWRlRWxlbWVudElzQ3BlWzBdICAgICAgPSAxOwogICAgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50cyAgID0gMTsKICAgIHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbMF0gICAgICA9IDE7CiAgICBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHMgICAgPSAxOwogICAgcFBjZS0+TnVtQ2hhbm5lbHMgICAgICAgICAgICAgID0gODsKICAgIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzICAgICA9IDc7CiAgICBwUGNlLT5pc1ZhbGlkICAgICAgICAgICAgICAgICAgPSAxOwogICAgYnJlYWs7CiAgLyogLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAqLwogIGNhc2UgMTI6ICAvKiAzLzAvNC4xY2ggc3Vycm91bmQgYmFjayAqLwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVsxXSAgICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDE7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAxOwogIGNhc2UgMTE6ICAvKiAzLzAvMy4xY2ggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICs9IDI7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVswXSAgICAgPSAwOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMV0gICAgID0gMTsKICAgIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgICs9IDI7CiAgICBwUGNlLT5CYWNrRWxlbWVudElzQ3BlWzBdICAgICAgPSAxOwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVsxXSAgICAgKz0gMDsKICAgIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyAgICs9IDE7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSA3OwogICAgcFBjZS0+TnVtRWZmZWN0aXZlQ2hhbm5lbHMgICAgKz0gNjsKICAgIHBQY2UtPmlzVmFsaWQgICAgICAgICAgICAgICAgICA9IDE7CiAgICBicmVhazsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAxNDogIC8qIDIvMC8wLTMvMC8yLTAuMWNoIGZyb250IGhlaWdodCAqLwogICAgcFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1syXSA9IDE7ICAgICAgLyogVG9wIHNwZWFrZXIgKi8KICBjYXNlIDc6ICAgLyogNS8wLzIuMWNoIGZyb250ICovCiAgICBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50cyArPSAxOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMl0gICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDI7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAyOwogIGNhc2UgNjogICAvKiAzLzAvMi4xY2ggKi8KICAgIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyAgICs9IDE7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSAxOwogIGNhc2UgNTogICAvKiAzLzAvMi4wY2ggKi8KICBjYXNlIDQ6ICAgLyogMy8wLzEuMGNoICovCiAgICBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzICArPSAxOwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVswXSAgICAgID0gKGNoYW5uZWxDb25maWc+NCkgPyAxIDogMDsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IChjaGFubmVsQ29uZmlnPjQpID8gMiA6IDE7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAoY2hhbm5lbENvbmZpZz40KSA/IDIgOiAxOwogIGNhc2UgMzogICAvKiAzLzAvMC4wY2ggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICs9IDE7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVsxXSAgICAgPSAxOwogICAgcFBjZS0+TnVtQ2hhbm5lbHMgICAgICAgICAgICAgKz0gMjsKICAgIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzICAgICs9IDI7CiAgY2FzZSAxOiAgIC8qIDEvMC8wLjBjaCAqLwogICAgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgKz0gMTsKICAgIHBQY2UtPkZyb250RWxlbWVudElzQ3BlWzBdICAgICA9IDA7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSAxOwogICAgcFBjZS0+TnVtRWZmZWN0aXZlQ2hhbm5lbHMgICAgKz0gMTsKICAgIHBQY2UtPmlzVmFsaWQgICAgICAgICAgICAgICAgICA9IDE7CiAgICBicmVhazsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAyOiAgIC8qIDIvMC8wLmNoICovCiAgICBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50cyAgPSAxOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMF0gICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDI7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAyOwogICAgcFBjZS0+aXNWYWxpZCAgICAgICAgICAgICAgICAgID0gMTsKICAgIGJyZWFrOwogIC8qIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gKi8KICBkZWZhdWx0OgogICAgcFBjZS0+aXNWYWxpZCAgICAgICAgICAgICAgICAgID0gMDsgICAvKiBUbyBiZSBleHBsaWNpdCEgKi8KICAgIGJyZWFrOwogIH0KCiAgaWYgKHBQY2UtPmlzVmFsaWQpIHsKICAgIC8qIENyZWF0ZSB2YWxpZCBlbGVtZW50IGluc3RhbmNlIHRhZ3MgKi8KICAgIGludCBlbCwgZWxUYWdTY2UgPSAwLCBlbFRhZ0NwZSA9IDA7CgogICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgcFBjZS0+RnJvbnRFbGVtZW50VGFnU2VsZWN0W2VsXSA9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtlbF0pID8gZWxUYWdDcGUrKyA6IGVsVGFnU2NlKys7CiAgICB9CiAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgIHBQY2UtPlNpZGVFbGVtZW50VGFnU2VsZWN0W2VsXSA9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2VsXSkgPyBlbFRhZ0NwZSsrIDogZWxUYWdTY2UrKzsKICAgIH0KICAgIGZvciAoZWwgPSAwOyBlbCA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgcFBjZS0+QmFja0VsZW1lbnRUYWdTZWxlY3RbZWxdID0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IGVsVGFnQ3BlKysgOiBlbFRhZ1NjZSsrOwogICAgfQogICAgZWxUYWdTY2UgPSAwOwogICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtTGZlQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgIHBQY2UtPkxmZUVsZW1lbnRUYWdTZWxlY3RbZWxdID0gZWxUYWdTY2UrKzsKICAgIH0KICB9Cn0KI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCi8qKgogKiBcYnJpZWYgZ2V0IGltcGxpY2l0IGF1ZGlvIGNoYW5uZWwgdHlwZSBmb3IgZ2l2ZW4gY2hhbm5lbENvbmZpZyBhbmQgTVBFRyBvcmRlcmVkIGNoYW5uZWwgaW5kZXgKICogXHBhcmFtIGNoYW5uZWxDb25maWcgTVBFRyBjaGFubmVsQ29uZmlndXJhdGlvbiBmcm9tIDEgdXB0byAxNAogKiBccGFyYW0gaW5kZXggTVBFRyBjaGFubmVsIG9yZGVyIGluZGV4CiAqIFxyZXR1cm4gYXVkaW8gY2hhbm5lbCB0eXBlLgogKi8Kc3RhdGljCnZvaWQgZ2V0SW1wbGljaXRBdWRpb0NoYW5uZWxUeXBlQW5kSW5kZXgoCiAgICAgICAgQVVESU9fQ0hBTk5FTF9UWVBFICpjaFR5cGUsCiAgICAgICAgVUNIQVIgKmNoSW5kZXgsCiAgICAgICAgVUlOVCBjaGFubmVsQ29uZmlnLAogICAgICAgIFVJTlQgaW5kZXgKICAgICAgICApCnsKICBpZiAoaW5kZXggPCAzKSB7CiAgICAqY2hUeXBlID0gQUNUX0ZST05UOwogICAgKmNoSW5kZXggPSBpbmRleDsKICB9IGVsc2UgewogICAgc3dpdGNoIChjaGFubmVsQ29uZmlnKSB7CiAgICAgIGNhc2UgNDogIC8qIFNDRSwgQ1BFLCBTQ0UgKi8KICAgICAgY2FzZSA1OiAgLyogU0NFLCBDUEUsIENQRSAqLwogICAgICBjYXNlIDY6ICAvKiBTQ0UsIENQRSwgQ1BFLCBMRkUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNzogIC8qIFNDRSxDUEUsQ1BFLENQRSxMRkUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfRlJPTlQ7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXg7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0JBQ0s7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSA1OwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgKmNoVHlwZSA9IEFDVF9MRkU7CiAgICAgICAgICAgICpjaEluZGV4ID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDExOiAgLyogU0NFLENQRSxDUEUsU0NFLExGRSAqLwogICAgICAgIGlmIChpbmRleCA8IDYpIHsKICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSAzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICpjaEluZGV4ID0gMDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTI6ICAvKiBTQ0UsQ1BFLENQRSxDUEUsTEZFICovCiAgICAgICAgaWYgKGluZGV4IDwgNykgewogICAgICAgICAgKmNoVHlwZSA9IEFDVF9CQUNLOwogICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICpjaFR5cGUgPSBBQ1RfTEZFOwogICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSAxNDogIC8qIFNDRSxDUEUsQ1BFLExGRSxDUEUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgKmNoVHlwZSA9IEFDVF9GUk9OVF9UT1A7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSA2OyAgLyogaGFuZGxlIHRoZSB0b3AgbGF5ZXIgaW5kZXBlbmRlbnRseSAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgKmNoVHlwZSA9IEFDVF9OT05FOwogICAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKaW50IENQcm9ncmFtQ29uZmlnX0xvb2t1cEVsZW1lbnQoCiAgICAgICAgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgVUlOVCAgICAgICAgICAgIGNoYW5uZWxDb25maWcsCiAgICAgICAgY29uc3QgVUlOVCAgICAgIHRhZywKICAgICAgICBjb25zdCBVSU5UICAgICAgY2hhbm5lbElkeCwKICAgICAgICBVQ0hBUiAgICAgICAgICAgY2hNYXBwaW5nW10sCiAgICAgICAgQVVESU9fQ0hBTk5FTF9UWVBFIGNoVHlwZVtdLAogICAgICAgIFVDSEFSICAgICAgICAgICBjaEluZGV4W10sCiAgICAgICAgVUNIQVIgICAgICAgICAgKmVsTWFwcGluZywKICAgICAgICBNUDRfRUxFTUVOVF9JRCAgZWxMaXN0W10sCiAgICAgICAgTVA0X0VMRU1FTlRfSUQgIGVsVHlwZQogICAgICAgKQp7CiAgaWYgKGNoYW5uZWxDb25maWcgPiAwKQogIHsKICAgIC8qIENvbnN0YW50IGNoYW5uZWwgbWFwcGluZyBtdXN0IGhhdmUKICAgICAgIGJlZW4gc2V0IGR1cmluZyBpbml0aWFsaXphdGlvbi4gKi8KICAgIGlmICggZWxUeXBlID09IElEX1NDRQogICAgICB8fCBlbFR5cGUgPT0gSURfQ1BFCiAgICAgIHx8IGVsVHlwZSA9PSBJRF9MRkUgKQogICAgewogICAgICAqZWxNYXBwaW5nID0gcFBjZS0+ZWxDb3VudGVyOwogICAgICBpZiAoZWxMaXN0W3BQY2UtPmVsQ291bnRlcl0gIT0gZWxUeXBlKSB7CiAgICAgICAgLyogTm90IGluIHRoZSBsaXN0ICovCiAgICAgICAgaWYgKCAoY2hhbm5lbENvbmZpZyA9PSAyKSAmJiAoZWxUeXBlID09IElEX1NDRSkgKQogICAgICAgIHsgLyogVGhpcyBzY2VuYXJpbyBvY2N1cnMgd2l0aCBIRS1BQUMgdjIgc3RyZWFtcyBvZiBidWdneSBlbmNvZGVycy4KICAgICAgICAgICAgIER1ZSB0byBvdGhlciBkZWNvZGVyIGltcGxlbWVudGF0aW9ucyBkZWNvZGluZyBvZiB0aGVzZSBraW5kIG9mIHN0cmVhbXMgaXMgZGVzaXJlZC4gKi8KICAgICAgICAgIGNoYW5uZWxDb25maWcgPSAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyogQXNzdW1lIGFsbCBmcm9udCBjaGFubmVscyAqLwogICAgICBnZXRJbXBsaWNpdEF1ZGlvQ2hhbm5lbFR5cGVBbmRJbmRleCgmY2hUeXBlW2NoYW5uZWxJZHhdLCAmY2hJbmRleFtjaGFubmVsSWR4XSwgY2hhbm5lbENvbmZpZywgY2hhbm5lbElkeCk7CiAgICAgIGlmIChlbFR5cGUgPT0gSURfQ1BFKSB7CiAgICAgICAgY2hUeXBlW2NoYW5uZWxJZHgrMV0gPSBjaFR5cGVbY2hhbm5lbElkeF07CiAgICAgICAgY2hJbmRleFtjaGFubmVsSWR4KzFdID0gY2hJbmRleFtjaGFubmVsSWR4XSsxOwogICAgICB9CiAgICAgIHBQY2UtPmVsQ291bnRlcisrOwogICAgfQogICAgLyogQWNjZXB0IGFsbCBub24tY2hhbm5lbCBlbGVtZW50cywgdG9vLiAqLwogICAgcmV0dXJuIDE7CiAgfQogIGVsc2UKICB7CiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgICBpZiAoIXBQY2UtPmlzVmFsaWQpCiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICB7CiAgICAgIC8qIEltcGxpY2l0IGNoYW5uZWwgbWFwcGluZy4gKi8KICAgICAgaWYgKCBlbFR5cGUgPT0gSURfU0NFCiAgICAgICAgfHwgZWxUeXBlID09IElEX0NQRQogICAgICAgIHx8IGVsVHlwZSA9PSBJRF9MRkUgKQogICAgICB7CiAgICAgICAgLyogU3RvcmUgYWxsIGNoYW5uZWwgZWxlbWVudCBJRHMgKi8KICAgICAgICBlbExpc3RbcFBjZS0+ZWxDb3VudGVyXSA9IGVsVHlwZTsKICAgICAgICAqZWxNYXBwaW5nID0gcFBjZS0+ZWxDb3VudGVyKys7CiAgICAgIH0KICAgIH0KI2lmZGVmICBUUF9QQ0VfRU5BQkxFCiAgICBlbHNlIHsKICAgICAgLyogQWNjZXB0IHRoZSBhZGRpdGlvbmFsIGNoYW5uZWwocyksIG9ubHkgaWYgdGhlIHRhZyBpcyBpbiB0aGUgbGlzdHMgKi8KICAgICAgaW50IGlzQ3BlID0gMCwgaTsKICAgICAgLyogRWxlbWVudCBjb3VudGVyICovCiAgICAgIGludCBlY1tQQ19OVU1fSEVJR0hUX0xBWUVSXSA9IHswfTsKICAgICAgLyogQ2hhbm5lbCBjb3VudGVycyAqLwogICAgICBpbnQgY2NbUENfTlVNX0hFSUdIVF9MQVlFUl0gPSB7MH07CiAgICAgIGludCBmY1tQQ19OVU1fSEVJR0hUX0xBWUVSXSA9IHswfTsKICAgICAgaW50IHNjW1BDX05VTV9IRUlHSFRfTEFZRVJdID0gezB9OwogICAgICBpbnQgYmNbUENfTlVNX0hFSUdIVF9MQVlFUl0gPSB7MH07CiAgICAgIGludCBsYyA9IDA7OwoKICAgICAgLyogR2VuZXJhbCBNUEVHIChQQ0UpIGNvbXBvc2l0aW9uIHJ1bGVzOgogICAgICAgICAtIE92ZXIgYWxsOgogICAgICAgICAgICAgPG5vcm1hbCBoZWlnaHQgY2hhbm5lbHM+PHRvcCBoZWlnaHQgY2hhbm5lbHM+PGJvdHRvbSBoZWlnaHQgY2hhbm5lbHM+CiAgICAgICAgIC0gV2l0aGluIGVhY2ggaGVpZ2h0IGxheWVyOgogICAgICAgICAgICAgPGZyb250IGNoYW5uZWxzPjxzaWRlIGNoYW5uZWxzPjxiYWNrIGNoYW5uZWxzPgogICAgICAgICAtIEV4Y2VwdGlvbjoKICAgICAgICAgICAgIFRoZSBMRkUgY2hhbm5lbHMgaGF2ZSBubyBoZWlnaHQgaW5mbyBhbmQgdGh1cyB0aGV5IGFyZSBhcnJhbmdlZCBhdCB0aGUgdmVyeQogICAgICAgICAgICAgZW5kIG9mIHRoZSBub3JtYWwgaGVpZ2h0IGxheWVyIGNoYW5uZWxzLgogICAgICAgKi8KCiAgICAgIHN3aXRjaCAoZWxUeXBlKQogICAgICB7CiAgICAgIGNhc2UgSURfQ1BFOgogICAgICAgIGlzQ3BlID0gMTsKICAgICAgY2FzZSBJRF9TQ0U6CiAgICAgICAgLyogc2VhcmNoIGluIGZyb250IGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzOyBpKyspIHsKICAgICAgICAgIGludCBoZWlnaHRMYXllciA9IHBQY2UtPkZyb250RWxlbWVudEhlaWdodEluZm9baV07CiAgICAgICAgICBpZiAoaXNDcGUgPT0gcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+RnJvbnRFbGVtZW50VGFnU2VsZWN0W2ldID09IHRhZykgewogICAgICAgICAgICBpbnQgaCwgZWxJZHggPSBlY1toZWlnaHRMYXllcl0sIGNoSWR4ID0gY2NbaGVpZ2h0TGF5ZXJdOwogICAgICAgICAgICBBVURJT19DSEFOTkVMX1RZUEUgYUNoVHlwZSA9IChBVURJT19DSEFOTkVMX1RZUEUpKChoZWlnaHRMYXllcjw8NCkgfCBBQ1RfRlJPTlQpOwogICAgICAgICAgICBmb3IgKGggPSBoZWlnaHRMYXllci0xOyBoID49IDA7IGgtPTEpIHsKICAgICAgICAgICAgICBpbnQgZWw7CiAgICAgICAgICAgICAgLyogQ291bnQgZnJvbnQgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5Gcm9udEVsZW1lbnRIZWlnaHRJbmZvW2VsXSA9PSBoKSB7CiAgICAgICAgICAgICAgICAgIGVsSWR4ICs9IDE7CiAgICAgICAgICAgICAgICAgIGNoSWR4ICs9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8qIENvdW50IHNpZGUgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBlbCs9MSkgewogICAgICAgICAgICAgICAgaWYgKHBQY2UtPlNpZGVFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8qIENvdW50IGJhY2sgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBlbCs9MSkgewogICAgICAgICAgICAgICAgaWYgKHBQY2UtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChoID09IDApIHsgIC8qIG5vcm1hbCBoZWlnaHQgKi8KICAgICAgICAgICAgICAgIGVsSWR4ICs9IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsKICAgICAgICAgICAgICAgIGNoSWR4ICs9IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4XSA9IGNoYW5uZWxJZHg7CiAgICAgICAgICAgIGNoVHlwZVtjaElkeF0gPSBhQ2hUeXBlOwogICAgICAgICAgICBjaEluZGV4W2NoSWR4XSA9IGZjW2hlaWdodExheWVyXTsKICAgICAgICAgICAgaWYgKGlzQ3BlKSB7CiAgICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4KzFdID0gY2hhbm5lbElkeCsxOwogICAgICAgICAgICAgIGNoVHlwZVtjaElkeCsxXSA9IGFDaFR5cGU7CiAgICAgICAgICAgICAgY2hJbmRleFtjaElkeCsxXSA9IGZjW2hlaWdodExheWVyXSsxOwogICAgICAgICAgICB9CiAgICAgICAgICAgICplbE1hcHBpbmcgPSBlbElkeDsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICB9CiAgICAgICAgICBlY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgIGlmIChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgZmNbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgZmNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIHNlYXJjaCBpbiBzaWRlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGkrKykgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgaWYgKGlzQ3BlID09IHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+U2lkZUVsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIGludCBoLCBlbElkeCA9IGVjW2hlaWdodExheWVyXSwgY2hJZHggPSBjY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIEFVRElPX0NIQU5ORUxfVFlQRSBhQ2hUeXBlID0gKEFVRElPX0NIQU5ORUxfVFlQRSkoKGhlaWdodExheWVyPDw0KSB8IEFDVF9TSURFKTsKICAgICAgICAgICAgZm9yIChoID0gaGVpZ2h0TGF5ZXItMTsgaCA+PSAwOyBoLT0xKSB7CiAgICAgICAgICAgICAgaW50IGVsOwogICAgICAgICAgICAgIC8qIENvdW50IGZyb250IGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsKz0xKSB7CiAgICAgICAgICAgICAgICBpZiAocFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBzaWRlIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5CYWNrRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoaCA9PSAwKSB7ICAvKiBMRkUgY2hhbm5lbHMgYmVsb25nIHRvIHRoZSBub3JtYWwgaGVpZ2h0IGxheWVyICovCiAgICAgICAgICAgICAgICBlbElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgICBjaElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeF0gPSBjaGFubmVsSWR4OwogICAgICAgICAgICBjaFR5cGVbY2hJZHhdID0gYUNoVHlwZTsKICAgICAgICAgICAgY2hJbmRleFtjaElkeF0gPSBzY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIGlmIChpc0NwZSkgewogICAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeCsxXSA9IGNoYW5uZWxJZHgrMTsKICAgICAgICAgICAgICBjaFR5cGVbY2hJZHgrMV0gPSBhQ2hUeXBlOwogICAgICAgICAgICAgIGNoSW5kZXhbY2hJZHgrMV0gPSBzY1toZWlnaHRMYXllcl0rMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqZWxNYXBwaW5nID0gZWxJZHg7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBpZiAocFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgc2NbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgc2NbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIHNlYXJjaCBpbiBiYWNrIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+QmFja0VsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgaWYgKGlzQ3BlID09IHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+QmFja0VsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIGludCBoLCBlbElkeCA9IGVjW2hlaWdodExheWVyXSwgY2hJZHggPSBjY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIEFVRElPX0NIQU5ORUxfVFlQRSBhQ2hUeXBlID0gKEFVRElPX0NIQU5ORUxfVFlQRSkoKGhlaWdodExheWVyPDw0KSB8IEFDVF9CQUNLKTsKICAgICAgICAgICAgZm9yIChoID0gaGVpZ2h0TGF5ZXItMTsgaCA+PSAwOyBoLT0xKSB7CiAgICAgICAgICAgICAgaW50IGVsOwogICAgICAgICAgICAgIC8qIENvdW50IGZyb250IGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsKz0xKSB7CiAgICAgICAgICAgICAgICBpZiAocFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBzaWRlIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5CYWNrRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoaCA9PSAwKSB7ICAvKiBub3JtYWwgaGVpZ2h0ICovCiAgICAgICAgICAgICAgICBlbElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgICBjaElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeF0gPSBjaGFubmVsSWR4OwogICAgICAgICAgICBjaFR5cGVbY2hJZHhdID0gYUNoVHlwZTsKICAgICAgICAgICAgY2hJbmRleFtjaElkeF0gPSBiY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIGlmIChpc0NwZSkgewogICAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeCsxXSA9IGNoYW5uZWxJZHgrMTsKICAgICAgICAgICAgICBjaFR5cGVbY2hJZHgrMV0gPSBhQ2hUeXBlOwogICAgICAgICAgICAgIGNoSW5kZXhbY2hJZHgrMV0gPSBiY1toZWlnaHRMYXllcl0rMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqZWxNYXBwaW5nID0gZWxJZHg7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBpZiAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgYmNbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgYmNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgIHsgLyogVW5mb3J0dW5hdGVseSB3ZSBoYXZlIHRvIGdvIHRocm91Z2ggYWxsIG5vcm1hbCBoZWlnaHQKICAgICAgICAgICBsYXllciBlbGVtZW50cyB0byBnZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBMRkUgY2hhbm5lbHMuCiAgICAgICAgICAgU3RhcnQgd2l0aCBjb3VudGluZyB0aGUgZnJvbnQgY2hhbm5lbHMvZWxlbWVudHMgYXQgbm9ybWFsIGhlaWdodCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSs9MSkgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tpXTsKICAgICAgICAgIGVjW2hlaWdodExheWVyXSArPSAxOwogICAgICAgICAgY2NbaGVpZ2h0TGF5ZXJdICs9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSkgPyAyIDogMTsKICAgICAgICB9CiAgICAgICAgLyogQ291bnQgc2lkZSBjaGFubmVscy9lbGVtZW50cyBhdCBub3JtYWwgaGVpZ2h0ICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGkrPTEpIHsKICAgICAgICAgIGludCBoZWlnaHRMYXllciA9IHBQY2UtPlNpZGVFbGVtZW50SGVpZ2h0SW5mb1tpXTsKICAgICAgICAgIGVjW2hlaWdodExheWVyXSArPSAxOwogICAgICAgICAgY2NbaGVpZ2h0TGF5ZXJdICs9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldKSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzIGF0IG5vcm1hbCBoZWlnaHQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgaSs9MSkgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+QmFja0VsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0pID8gMiA6IDE7CiAgICAgICAgfQoKICAgICAgICAvKiBzZWFyY2ggaW4gbGZlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpbnQgZWxJZHggPSBlY1swXTsgIC8qIExGRSBjaGFubmVscyBiZWxvbmcgdG8gdGhlIG5vcm1hbCBoZWlnaHQgbGF5ZXIgKi8KICAgICAgICAgIGludCBjaElkeCA9IGNjWzBdOwogICAgICAgICAgaWYgKCBwUGNlLT5MZmVFbGVtZW50VGFnU2VsZWN0W2ldID09IHRhZyApIHsKICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4XSA9IGNoYW5uZWxJZHg7CiAgICAgICAgICAgICplbE1hcHBpbmcgPSBlbElkeDsKICAgICAgICAgICAgY2hUeXBlW2NoSWR4XSA9IEFDVF9MRkU7CiAgICAgICAgICAgIGNoSW5kZXhbY2hJZHhdID0gbGM7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbMF0gKz0gMTsKICAgICAgICAgIGNjWzBdICs9IDE7CiAgICAgICAgICBsYyArPSAxOwogICAgICAgIH0KICAgICAgfSBicmVhazsKCiAgICAgIC8qIE5vbiBhdWRpbyBlbGVtZW50cyAqLwogICAgICBjYXNlIElEX0NDRToKICAgICAgICAvKiBzZWFyY2ggaW4gY2NlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVZhbGlkQ2NFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpZiAocFBjZS0+VmFsaWRDY0VsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBJRF9EU0U6CiAgICAgICAgLyogc2VhcmNoIGFzc29jaWF0ZWQgZGF0YSBlbGVtZW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUGNlLT5OdW1Bc3NvY0RhdGFFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpZiAocFBjZS0+QXNzb2NEYXRhRWxlbWVudFRhZ1NlbGVjdFtpXSA9PSB0YWcpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIHJldHVybiAwOyAgLyogbm90IGZvdW5kIGluIGFueSBsaXN0ICovCiAgICB9CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCiAgfQoKICByZXR1cm4gMTsKfQoKI2lmZGVmICBUUF9QQ0VfRU5BQkxFCmludCBDUHJvZ3JhbUNvbmZpZ19HZXRFbGVtZW50VGFibGUoCiAgICAgICAgY29uc3QgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgTVA0X0VMRU1FTlRfSUQgIGVsTGlzdFtdLAogICAgICAgIGNvbnN0IElOVCBlbExpc3RTaXplLAogICAgICAgIFVDSEFSICpwQ2hNYXBJZHgKICAgICAgICkKewogIGludCBpLCBlbCA9IDA7CgogIEZES19BU1NFUlQoZWxMaXN0ICE9IE5VTEwpOwogIEZES19BU1NFUlQocENoTWFwSWR4ICE9IE5VTEwpOwoKICAqcENoTWFwSWR4ID0gMDsKCiAgaWYgKCBlbExpc3RTaXplCiAgICA8IHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICsgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50cyArIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgKyBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHMKICAgICkKICB7CiAgICByZXR1cm4gMDsKICB9CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbaV0pID8gIElEX0NQRSA6IElEX1NDRTsKICB9CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgaSsrKQogIHsKICAgIGVsTGlzdFtlbCsrXSA9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldKSA/ICBJRF9DUEUgOiBJRF9TQ0U7CiAgfQoKICBmb3IgKGk9MDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtpXSkgPyAgSURfQ1BFIDogSURfU0NFOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSBJRF9MRkU7CiAgfQoKCiAgLyogRmluZCBhbiBjb3JyZXNwb25kaW5nIGNoYW5uZWwgY29uZmlndXJhdGlvbiBpZiBwb3NzaWJsZSAqLwogIHN3aXRjaCAocFBjZS0+TnVtQ2hhbm5lbHMpIHsKICBjYXNlIDE6IGNhc2UgMjogY2FzZSAzOiBjYXNlIDQ6IGNhc2UgNTogY2FzZSA2OgogICAgLyogT25lIGFuZCB0d28gY2hhbm5lbHMgaGF2ZSBubyBhbHRlcm5hdGl2ZXMuIFRoZSBvdGhlciBvbmVzIGFyZSBtYXBwZWQgZGlyZWN0bHkgdG8gdGhlCiAgICAgICBjb3JyZXNwb25kaW5nIGNoYW5uZWwgY29uZmlnLiBCZWNhdXNlIG9mIGxlZ2FjeSByZWFzb25zIG9yIGZvciBsYWNrIG9mIGFsdGVybmF0aXZlIG1hcHBpbmdzLiAqLwogICAgKnBDaE1hcElkeCA9IHBQY2UtPk51bUNoYW5uZWxzOwogICAgYnJlYWs7CiAgY2FzZSA3OgogICAgewogICAgICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQodG1wUGNlLCBDUHJvZ3JhbUNvbmZpZywgMSk7CiAgICAgIC8qIENyZWF0ZSBhIFBDRSBmb3IgdGhlIGNvbmZpZyB0byB0ZXN0IC4uLiAqLwogICAgICBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KHRtcFBjZSwgMTEpOwogICAgICAvKiAuLi4gYW5kIGNvbXBhcmUgaXQgd2l0aCB0aGUgZ2l2ZW4gb25lLiAqLwogICAgICAqcENoTWFwSWR4ID0gKCEoQ1Byb2dyYW1Db25maWdfQ29tcGFyZShwUGNlLCB0bXBQY2UpJjB4RSkpID8gMTEgOiAwOwogICAgICAvKiBJZiBjb21wYXJlIHJlc3VsdCBpcyAwIG9yIDEgd2UgY2FuIGJlIHN1cmUgdGhhdCBpdCBpcyBjaGFubmVsIGNvbmZpZyAxMS4gKi8KICAgICAgQ19BTExPQ19TQ1JBVENIX0VORCh0bXBQY2UsIENQcm9ncmFtQ29uZmlnLCAxKTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgODoKICAgIHsgLyogVHJ5IHRoZSBmb3VyIHBvc3NpYmxlIDcuMWNoIGNvbmZpZ3VyYXRpb25zLiBPbmUgYWZ0ZXIgdGhlIG90aGVyLiAqLwogICAgICBVQ0hBUiB0ZXN0Q2ZnWzRdID0geyAzMiwgMTQsIDEyLCA3fTsKICAgICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwogICAgICBmb3IgKGk9MDsgaTw0OyBpKz0xKSB7CiAgICAgICAgLyogQ3JlYXRlIGEgUENFIGZvciB0aGUgY29uZmlnIHRvIHRlc3QgLi4uICovCiAgICAgICAgQ1Byb2dyYW1Db25maWdfR2V0RGVmYXVsdCh0bXBQY2UsIHRlc3RDZmdbaV0pOwogICAgICAgIC8qIC4uLiBhbmQgY29tcGFyZSBpdCB3aXRoIHRoZSBnaXZlbiBvbmUuICovCiAgICAgICAgaWYgKCEoQ1Byb2dyYW1Db25maWdfQ29tcGFyZShwUGNlLCB0bXBQY2UpJjB4RSkpIHsKICAgICAgICAgIC8qIElmIHRoZSBjb21wYXJlIHJlc3VsdCBpcyAwIG9yIDEgdGhhbiB0aGUgdHdvIGNoYW5uZWwgY29uZmlndXJhdGlvbnMgbWF0Y2guICovCiAgICAgICAgICAvKiBFeHBsaWNpdCBtYXBwaW5nIG9mIDcuMSBzaWRlIGNoYW5uZWwgY29uZmlndXJhdGlvbiB0byA3LjEgcmVhciBjaGFubmVsIG1hcHBpbmcuICovCiAgICAgICAgICAqcENoTWFwSWR4ID0gKHRlc3RDZmdbaV09PTMyKSA/IDEyIDogdGVzdENmZ1tpXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQ19BTExPQ19TQ1JBVENIX0VORCh0bXBQY2UsIENQcm9ncmFtQ29uZmlnLCAxKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICAvKiBUaGUgUENFIGRvZXMgbm90IG1hdGNoIGFueSBwcmVkZWZpbmVkIGNoYW5uZWwgY29uZmlndXJhdGlvbi4gKi8KICAgICpwQ2hNYXBJZHggPSAwOwogICAgYnJlYWs7CiAgfQoKICByZXR1cm4gZWw7Cn0KI2VuZGlmCgpzdGF0aWMgQVVESU9fT0JKRUNUX1RZUEUgZ2V0QU9UKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzKQp7CiAgaW50IHRtcCA9IDA7CgogIHRtcCA9IEZES3JlYWRCaXRzKGJzLDUpOwogIGlmICh0bXAgPT0gQU9UX0VTQ0FQRSkgewogICAgaW50IHRtcDIgPSBGREtyZWFkQml0cyhicyw2KTsKICAgIHRtcCA9IDMyICsgdG1wMjsKICB9CgogIHJldHVybiAoQVVESU9fT0JKRUNUX1RZUEUpdG1wOwp9CgpzdGF0aWMgSU5UIGdldFNhbXBsZVJhdGUoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsIFVDSEFSICppbmRleCwgaW50IG5CaXRzKQp7CiAgSU5UIHNhbXBsZVJhdGU7CiAgaW50IGlkeDsKCiAgaWR4ID0gRkRLcmVhZEJpdHMoYnMsIG5CaXRzKTsKICBpZiggaWR4ID09ICgxPDxuQml0cyktMSApIHsKICAgIGlmKEZES2dldFZhbGlkQml0cyhicykgPCAyNCkgewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHNhbXBsZVJhdGUgPSBGREtyZWFkQml0cyhicywyNCk7CiAgfSBlbHNlIHsKICAgIHNhbXBsZVJhdGUgPSBTYW1wbGluZ1JhdGVUYWJsZVtpZHhdOwogIH0KCiAgKmluZGV4ID0gaWR4OwoKICByZXR1cm4gc2FtcGxlUmF0ZTsKfQoKI2lmZGVmIFRQX0dBX0VOQUJMRQpzdGF0aWMKVFJBTlNQT1JUREVDX0VSUk9SIEdhU3BlY2lmaWNDb25maWdfUGFyc2UoIENTR2FTcGVjaWZpY0NvbmZpZyAgICAqc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICAgICAgYXNjU3RhcnRBbmNob3IgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX09LOwoKICBzZWxmLT5tX2ZyYW1lTGVuZ3RoRmxhZyA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICBzZWxmLT5tX2RlcGVuZHNPbkNvcmVDb2RlciA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICBpZiggc2VsZi0+bV9kZXBlbmRzT25Db3JlQ29kZXIgKQogICAgc2VsZi0+bV9jb3JlQ29kZXJEZWxheSA9IEZES3JlYWRCaXRzKGJzLDE0KTsKCiAgc2VsZi0+bV9leHRlbnNpb25GbGFnID0gRkRLcmVhZEJpdHMoYnMsMSk7CgogIGlmKCBhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPT0gMCApIHsKICAgIENQcm9ncmFtQ29uZmlnX1JlYWQoJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIGJzLCBhc2NTdGFydEFuY2hvcik7CiAgfQoKICBpZiAoKGFzYy0+bV9hb3QgPT0gQU9UX0FBQ19TQ0FMKSB8fCAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX1NDQUwpKSB7CiAgICBzZWxmLT5tX2xheWVyID0gRkRLcmVhZEJpdHMoYnMsMyk7CiAgfQoKICBpZiAoc2VsZi0+bV9leHRlbnNpb25GbGFnKSB7CiAgICBpZiAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQlNBQykgewogICAgICBzZWxmLT5tX251bU9mU3ViRnJhbWUgPSBGREtyZWFkQml0cyhicyw1KTsKICAgICAgc2VsZi0+bV9sYXllckxlbmd0aCAgID0gRkRLcmVhZEJpdHMoYnMsMTEpOwogICAgfQoKICAgIGlmICgoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX0xDKSAgIHx8IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfTFRQKSAgfHwKICAgICAgICAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX1NDQUwpIHx8IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfTEQpKQogICAgewogICAgICBhc2MtPm1fdmNiMTFGbGFnID0gRkRLcmVhZEJpdHMoYnMsMSk7IC8qIGFhY1NlY3Rpb25EYXRhUmVzaWxpZW5jZUZsYWcgKi8KICAgICAgYXNjLT5tX3J2bGNGbGFnICA9IEZES3JlYWRCaXRzKGJzLDEpOyAvKiBhYWNTY2FsZWZhY3RvckRhdGFSZXNpbGllbmNlRmxhZyAqLwogICAgICBhc2MtPm1faGNyRmxhZyAgID0gRkRLcmVhZEJpdHMoYnMsMSk7IC8qIGFhY1NwZWN0cmFsRGF0YVJlc2lsaWVuY2VGbGFnICovCiAgICB9CgogICAgc2VsZi0+bV9leHRlbnNpb25GbGFnMyA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICB9CiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KI2VuZGlmIC8qIFRQX0dBX0VOQUJMRSAqLwoKCgoKCiNpZmRlZiBUUF9FTERfRU5BQkxFCgpzdGF0aWMgSU5UIGxkX3Nicl9oZWFkZXIoIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENTVHBDYWxsQmFja3MgKmNiICkKewogIGNvbnN0IGludCBjaGFubmVsQ29uZmlndXJhdGlvbiA9IGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbjsKICBpbnQgaSA9IDA7CiAgSU5UIGVycm9yID0gMDsKCiAgaWYgKGNoYW5uZWxDb25maWd1cmF0aW9uID09IDIpIHsKICAgIGVycm9yID0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgfSBlbHNlIHsKICAgIGVycm9yID0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9TQ0UsIGkrKyk7CiAgfQoKICBzd2l0Y2ggKCBjaGFubmVsQ29uZmlndXJhdGlvbiApIHsKICAgIGNhc2UgMTQ6CiAgICBjYXNlIDEyOgogICAgY2FzZSA3OgogICAgICBlcnJvciB8PSBjYi0+Y2JTYnIoY2ItPmNiU2JyRGF0YSwgaEJzLCBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSwgQU9UX0VSX0FBQ19FTEQsIElEX0NQRSwgaSsrKTsKICAgIGNhc2UgNjoKICAgIGNhc2UgNToKICAgICAgZXJyb3IgfD0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgICBjYXNlIDM6CiAgICAgIGVycm9yIHw9IGNiLT5jYlNicihjYi0+Y2JTYnJEYXRhLCBoQnMsIGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fc2FtcGxlc1BlckZyYW1lLCBBT1RfRVJfQUFDX0VMRCwgSURfQ1BFLCBpKyspOwogICAgICBicmVhazsKCiAgICBjYXNlIDExOgogICAgICBlcnJvciB8PSBjYi0+Y2JTYnIoY2ItPmNiU2JyRGF0YSwgaEJzLCBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSwgQU9UX0VSX0FBQ19FTEQsIElEX0NQRSwgaSsrKTsKICAgIGNhc2UgNDoKICAgICAgZXJyb3IgfD0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgICAgIGVycm9yIHw9IGNiLT5jYlNicihjYi0+Y2JTYnJEYXRhLCBoQnMsIGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fc2FtcGxlc1BlckZyYW1lLCBBT1RfRVJfQUFDX0VMRCwgSURfU0NFLCBpKyspOwogICAgICBicmVhazsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKc3RhdGljClRSQU5TUE9SVERFQ19FUlJPUiBFbGRTcGVjaWZpY0NvbmZpZ19QYXJzZSgKICAgICAgICBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKmFzYywKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAqY2IKICAgICAgICApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRERUNfT0s7CiAgQ1NFbGRTcGVjaWZpY0NvbmZpZyAqZXNjID0gJmFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnOwogIEFTQ19FTERfRVhUX1RZUEUgZWxkRXh0VHlwZTsKICBpbnQgZWxkRXh0TGVuLCBsZW4sIGNudDsKCiAgRkRLbWVtY2xlYXIoZXNjLCBzaXplb2YoQ1NFbGRTcGVjaWZpY0NvbmZpZykpOwoKICBlc2MtPm1fZnJhbWVMZW5ndGhGbGFnID0gRkRLcmVhZEJpdHMoaEJzLCAxICk7CiAgaWYgKGVzYy0+bV9mcmFtZUxlbmd0aEZsYWcpIHsKICAgIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUgPSA0ODA7CiAgfSBlbHNlIHsKICAgIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUgPSA1MTI7CiAgfQoKICBhc2MtPm1fdmNiMTFGbGFnID0gRkRLcmVhZEJpdHMoaEJzLCAxICk7CiAgYXNjLT5tX3J2bGNGbGFnICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwogIGFzYy0+bV9oY3JGbGFnICAgPSBGREtyZWFkQml0cyhoQnMsIDEgKTsKCiAgZXNjLT5tX3NiclByZXNlbnRGbGFnICAgICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwoKICBpZiAoZXNjLT5tX3NiclByZXNlbnRGbGFnID09IDEpIHsKICAgIGVzYy0+bV9zYnJTYW1wbGluZ1JhdGUgICAgPSBGREtyZWFkQml0cyhoQnMsIDEgKTsgLyogMDogc2luZ2xlIHJhdGUsIDE6IGR1YWwgcmF0ZSAqLwogICAgZXNjLT5tX3NickNyY0ZsYWcgICAgICAgICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwoKICAgIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSA9IGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSA8PCBlc2MtPm1fc2JyU2FtcGxpbmdSYXRlOwoKICAgIGlmIChjYi0+Y2JTYnIgIT0gTlVMTCl7CiAgICAgIGlmICggMCAhPSBsZF9zYnJfaGVhZGVyKGFzYywgaEJzLCBjYikgKSB7CiAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9CiAgfQogIGVzYy0+bV91c2VMZFFtZlRpbWVBbGlnbiA9IDA7CgogIC8qIG5ldyBFTEQgc3ludGF4ICovCiAgLyogcGFyc2UgRXh0VHlwZUNvbmZpZ0RhdGEgKi8KICB3aGlsZSAoKGVsZEV4dFR5cGUgPSAoQVNDX0VMRF9FWFRfVFlQRSlGREtyZWFkQml0cyhoQnMsIDQgKSkgIT0gRUxERVhUX1RFUk0pIHsKICAgIGVsZEV4dExlbiA9IGxlbiA9IEZES3JlYWRCaXRzKGhCcywgNCApOwogICAgaWYgKCBsZW4gPT0gMHhmICkgewogICAgICBsZW4gPSBGREtyZWFkQml0cyhoQnMsIDggKTsKICAgICAgZWxkRXh0TGVuICs9IGxlbjsKCiAgICAgIGlmICggbGVuID09IDB4ZmYgKSB7CiAgICAgICAgbGVuID0gRkRLcmVhZEJpdHMoaEJzLCAxNiApOwogICAgICAgIGVsZEV4dExlbiArPSBsZW47CiAgICAgIH0KICAgIH0KCiAgICBzd2l0Y2ggKGVsZEV4dFR5cGUpIHsKICAgICAgZGVmYXVsdDoKICAgICAgICBmb3IoY250PTA7IGNudDxlbGRFeHRMZW47IGNudCsrKSB7CiAgICAgICAgICBGREtyZWFkQml0cyhoQnMsIDggKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIC8qIGFkZCBmdXR1cmUgZWxkIGV4dGVuc2lvbiBjb25maWdzIGhlcmUgKi8KICAgIH0KICB9CmJhaWw6CiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KI2VuZGlmIC8qIFRQX0VMRF9FTkFCTEUgKi8KCgpzdGF0aWMKVFJBTlNQT1JUREVDX0VSUk9SIEF1ZGlvU3BlY2lmaWNDb25maWdfRXh0ZW5zaW9uUGFyc2UoQ1NBdWRpb1NwZWNpZmljQ29uZmlnICpzZWxmLCBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywgQ1NUcENhbGxCYWNrcyAqY2IpCnsKICBUUF9BU0NfRVhURU5TSU9OX0lEICBsYXN0QXNjRXh0LCBhc2NFeHRJZCA9IEFTQ0VYVF9VTktPV047CiAgSU5UICBiaXRzQXZhaWxhYmxlID0gKElOVClGREtnZXRWYWxpZEJpdHMoYnMpOwoKICB3aGlsZSAoYml0c0F2YWlsYWJsZSA+PSAxMSkKICB7CiAgICBsYXN0QXNjRXh0ID0gYXNjRXh0SWQ7CiAgICBhc2NFeHRJZCAgID0gKFRQX0FTQ19FWFRFTlNJT05fSUQpRkRLcmVhZEJpdHMoYnMsIDExKTsKICAgIGJpdHNBdmFpbGFibGUgLT0gMTE7CgogICAgc3dpdGNoIChhc2NFeHRJZCkgewogICAgY2FzZSBBU0NFWFRfU0JSOiAgICAvKiAweDJiNyAqLwogICAgICBpZiAoIChzZWxmLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZSAhPSBBT1RfU0JSKSAmJiAoYml0c0F2YWlsYWJsZSA+PSA1KSApIHsKICAgICAgICBzZWxmLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZSA9IGdldEFPVChicyk7CgogICAgICAgIGlmICggKHNlbGYtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlID09IEFPVF9TQlIpCiAgICAgICAgICB8fCAoc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0JTQUMpICkKICAgICAgICB7IC8qIEdldCBTQlIgZXh0ZW5zaW9uIGNvbmZpZ3VyYXRpb24gKi8KICAgICAgICAgIHNlbGYtPm1fc2JyUHJlc2VudEZsYWcgPSBGREtyZWFkQml0cyhicywgMSk7CiAgICAgICAgICBiaXRzQXZhaWxhYmxlIC09IDE7CgogICAgICAgICAgaWYgKCBzZWxmLT5tX3NiclByZXNlbnRGbGFnID09IDEgKSB7CiAgICAgICAgICAgIHNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3kgPSBnZXRTYW1wbGVSYXRlKGJzLCAmc2VsZi0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeUluZGV4LCA0KTsKCiAgICAgICAgICAgIGlmICgoSU5UKXNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3kgPD0gMCkgewogICAgICAgICAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmICggc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0JTQUMgKSB7CiAgICAgICAgICAgIHNlbGYtPm1fZXh0ZW5zaW9uQ2hhbm5lbENvbmZpZ3VyYXRpb24gPSBGREtyZWFkQml0cyhicywgNCk7CiAgICAgICAgICAgIGJpdHNBdmFpbGFibGUgLT0gNDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyogVXBkYXRlIGNvdW50ZXIgYmVjYXVzZSBvZiB2YXJpYWJsZSBsZW5ndGggZmllbGRzIChBT1QgYW5kIHNhbXBsaW5nIHJhdGUpICovCiAgICAgICAgYml0c0F2YWlsYWJsZSA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgQVNDRVhUX1BTOiAgICAgLyogMHg1NDggKi8KICAgICAgaWYgKCAobGFzdEFzY0V4dCA9PSBBU0NFWFRfU0JSKQogICAgICAgICYmIChzZWxmLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfU0JSKQogICAgICAgICYmIChiaXRzQXZhaWxhYmxlID4gMCkgKQogICAgICB7IC8qIEdldCBQUyBleHRlbnNpb24gY29uZmlndXJhdGlvbiAqLwogICAgICAgIHNlbGYtPm1fcHNQcmVzZW50RmxhZyA9IEZES3JlYWRCaXRzKGJzLCAxKTsKICAgICAgICBiaXRzQXZhaWxhYmxlIC09IDE7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAvKiBKdXN0IGlnbm9yZSBhbnl0aGluZy4gKi8KICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19PSzsKICAgIH0KICB9CgogIHJldHVybiBUUkFOU1BPUlRERUNfT0s7Cn0KCi8qCiAqIEFQSSBGdW5jdGlvbnMKICovCgp2b2lkIEF1ZGlvU3BlY2lmaWNDb25maWdfSW5pdChDU0F1ZGlvU3BlY2lmaWNDb25maWcgKmFzYykKewogIEZES21lbWNsZWFyKGFzYywgc2l6ZW9mKENTQXVkaW9TcGVjaWZpY0NvbmZpZykpOwoKICAvKiBJbml0IGFsbCB2YWx1ZXMgdGhhdCBzaG91bGQgbm90IGJlIHplcm8uICovCiAgYXNjLT5tX2FvdCAgICAgICAgICAgICAgICAgICAgPSBBT1RfTk9ORTsKICBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3lJbmRleCA9IDB4ZjsKICBhc2MtPm1fZXBDb25maWcgICAgICAgICAgICAgICA9IC0xOwogIGFzYy0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgICAgICAgID0gQU9UX05VTExfT0JKRUNUOwojaWZkZWYgVFBfUENFX0VOQUJMRQogIENQcm9ncmFtQ29uZmlnX0luaXQoJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQpOwojZW5kaWYKfQoKVFJBTlNQT1JUREVDX0VSUk9SIEF1ZGlvU3BlY2lmaWNDb25maWdfUGFyc2UoCiAgICAgICAgQ1NBdWRpb1NwZWNpZmljQ29uZmlnICpzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgYnMsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgICBmRXhwbGljaXRCYWNrd2FyZENvbXBhdGlibGUsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAgICAgICpjYgogICAgICAgICkKewogIFRSQU5TUE9SVERFQ19FUlJPUiBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVERFQ19PSzsKICBVSU5UIGFzY1N0YXJ0QW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKICBpbnQgZnJhbWVMZW5ndGhGbGFnID0gLTE7CgogIEF1ZGlvU3BlY2lmaWNDb25maWdfSW5pdChzZWxmKTsKCiAgc2VsZi0+bV9hb3QgPSBnZXRBT1QoYnMpOwogIHNlbGYtPm1fc2FtcGxpbmdGcmVxdWVuY3kgPSBnZXRTYW1wbGVSYXRlKGJzLCAmc2VsZi0+bV9zYW1wbGluZ0ZyZXF1ZW5jeUluZGV4LCA0KTsKICBpZiAoc2VsZi0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSA8PSAwKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOwogIH0KCiAgc2VsZi0+bV9jaGFubmVsQ29uZmlndXJhdGlvbiA9IEZES3JlYWRCaXRzKGJzLDQpOwoKICAvKiBTQlIgZXh0ZW5zaW9uICggZXhwbGljaXQgbm9uLWJhY2t3YXJkcyBjb21wYXRpYmxlIG1vZGUgKSAqLwogIHNlbGYtPm1fc2JyUHJlc2VudEZsYWcgPSAwOwogIHNlbGYtPm1fcHNQcmVzZW50RmxhZyAgPSAwOwoKICBpZiAoIHNlbGYtPm1fYW90ID09IEFPVF9TQlIgfHwgc2VsZi0+bV9hb3QgPT0gQU9UX1BTICkgewogICAgc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPSBBT1RfU0JSOwoKICAgIHNlbGYtPm1fc2JyUHJlc2VudEZsYWcgPSAxOwogICAgaWYgKCBzZWxmLT5tX2FvdCA9PSBBT1RfUFMgKSB7CiAgICAgIHNlbGYtPm1fcHNQcmVzZW50RmxhZyA9IDE7CiAgICB9CgogICAgc2VsZi0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSA9IGdldFNhbXBsZVJhdGUoYnMsICZzZWxmLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5SW5kZXgsIDQpOwogICAgc2VsZi0+bV9hb3QgPSBnZXRBT1QoYnMpOwoKICB9IGVsc2UgewogICAgc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPSBBT1RfTlVMTF9PQkpFQ1Q7CiAgfQoKICAvKiBQYXJzZSB3aGF0ZXZlciBzcGVjaWZpYyBjb25maWdzICovCiAgc3dpdGNoIChzZWxmLT5tX2FvdCkKICB7CiNpZmRlZiBUUF9HQV9FTkFCTEUKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgY2FzZSBBT1RfRVJfQlNBQzoKICAgICAgaWYgKChFcnJvclN0YXR1cyA9IEdhU3BlY2lmaWNDb25maWdfUGFyc2UoJnNlbGYtPm1fc2MubV9nYVNwZWNpZmljQ29uZmlnLCBzZWxmLCBicywgYXNjU3RhcnRBbmNob3IpKSAhPSBUUkFOU1BPUlRERUNfT0sgKSB7CiAgICAgICAgcmV0dXJuIChFcnJvclN0YXR1cyk7CiAgICAgIH0KICAgICAgZnJhbWVMZW5ndGhGbGFnID0gc2VsZi0+bV9zYy5tX2dhU3BlY2lmaWNDb25maWcubV9mcmFtZUxlbmd0aEZsYWc7CiAgICAgIGJyZWFrOwojZW5kaWYgLyogVFBfR0FfRU5BQkxFICovCiAgICBjYXNlIEFPVF9NUEVHUzoKICAgICAgaWYgKGNiLT5jYlNzYyAhPSBOVUxMKSB7CiAgICAgICAgY2ItPmNiU3NjKAogICAgICAgICAgICAgICAgY2ItPmNiU3NjRGF0YSwKICAgICAgICAgICAgICAgIGJzLAogICAgICAgICAgICAgICAgc2VsZi0+bV9hb3QsCiAgICAgICAgICAgICAgICBzZWxmLT5tX3NhbXBsaW5nRnJlcXVlbmN5LAogICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgIDAgIC8qIGRvbid0IGtub3cgdGhlIGxlbmd0aCAqLwogICAgICAgICAgICAgICAgKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgfQogICAgICBicmVhazsKI2lmZGVmIFRQX0VMRF9FTkFCTEUKICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgIGlmICgoRXJyb3JTdGF0dXMgPSBFbGRTcGVjaWZpY0NvbmZpZ19QYXJzZShzZWxmLCBicywgY2IpKSAhPSBUUkFOU1BPUlRERUNfT0sgKSB7CiAgICAgICAgcmV0dXJuIChFcnJvclN0YXR1cyk7CiAgICAgIH0KICAgICAgZnJhbWVMZW5ndGhGbGFnID0gc2VsZi0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fZnJhbWVMZW5ndGhGbGFnOwogICAgICBzZWxmLT5tX3NiclByZXNlbnRGbGFnID0gc2VsZi0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fc2JyUHJlc2VudEZsYWc7CiAgICAgIHNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3kgPSAoc2VsZi0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fc2JyU2FtcGxpbmdSYXRlKzEpICogc2VsZi0+bV9zYW1wbGluZ0ZyZXF1ZW5jeTsKICAgICAgYnJlYWs7CiNlbmRpZiAvKiBUUF9FTERfRU5BQkxFICovCgogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICAgIGJyZWFrOwogIH0KCiAgLyogRnJhbWUgbGVuZ3RoICovCiAgc3dpdGNoIChzZWxmLT5tX2FvdCkKICB7CiNpZiBkZWZpbmVkKFRQX0dBX0VOQUJMRSkgfHwgZGVmaW5lZChUUF9VU0FDX0VOQUJMRSkKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgY2FzZSBBT1RfRVJfQlNBQzoKICAgIC8qY2FzZSBBT1RfVVNBQzoqLwogICAgICBpZiAoIWZyYW1lTGVuZ3RoRmxhZykKICAgICAgICBzZWxmLT5tX3NhbXBsZXNQZXJGcmFtZSA9IDEwMjQ7CiAgICAgIGVsc2UKICAgICAgICBzZWxmLT5tX3NhbXBsZXNQZXJGcmFtZSA9IDk2MDsKICAgICAgYnJlYWs7CiNlbmRpZiAvKiBUUF9HQV9FTkFCTEUgKi8KI2lmIGRlZmluZWQoVFBfR0FfRU5BQkxFKQogICAgY2FzZSBBT1RfRVJfQUFDX0xEOgogICAgICBpZiAoIWZyYW1lTGVuZ3RoRmxhZykKICAgICAgICBzZWxmLT5tX3NhbXBsZXNQZXJGcmFtZSA9IDUxMjsKICAgICAgZWxzZQogICAgICAgIHNlbGYtPm1fc2FtcGxlc1BlckZyYW1lID0gNDgwOwogICAgICBicmVhazsKI2VuZGlmIC8qIGRlZmluZWQoVFBfR0FfRU5BQkxFKSAqLwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICBzd2l0Y2ggKHNlbGYtPm1fYW90KQogIHsKICAgIGNhc2UgQU9UX0VSX0FBQ19MQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0VSX0NFTFA6CiAgICBjYXNlIEFPVF9FUl9IVlhDOgogICAgY2FzZSBBT1RfRVJfQlNBQzoKICAgICAgc2VsZi0+bV9lcENvbmZpZyA9IEZES3JlYWRCaXRzKGJzLDIpOwoKICAgICAgaWYgKHNlbGYtPm1fZXBDb25maWcgPiAxKSB7CiAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7IC8vIEVQQ09ORklHOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICBpZiAoZkV4cGxpY2l0QmFja3dhcmRDb21wYXRpYmxlKSB7CiAgICBFcnJvclN0YXR1cyA9IEF1ZGlvU3BlY2lmaWNDb25maWdfRXh0ZW5zaW9uUGFyc2Uoc2VsZiwgYnMsIGNiKTsKICB9CgogIHJldHVybiAoRXJyb3JTdGF0dXMpOwp9CgpUUkFOU1BPUlRERUNfRVJST1IgRHJtUmF3U2RjQXVkaW9Db25maWdfUGFyc2UoCiAgICAgICAgQ1NBdWRpb1NwZWNpZmljQ29uZmlnICpzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgYnMKICAgICAgICApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRERUNfT0s7CgogIEF1ZGlvU3BlY2lmaWNDb25maWdfSW5pdChzZWxmKTsKCiAgaWYgKChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKSA8IDIwKSB7CiAgICBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgIGdvdG8gYmFpbDsKICB9CiAgZWxzZSB7CiAgICAvKiBEUk0gLSBBdWRpbyBpbmZvcm1hdGlvbiBkYXRhIGVudGl0eSAtIHR5cGUgOQogICAgICAgLSBTaG9ydCBJZCAgICAgICAgICAgIDIgYml0cwogICAgICAgLSBTdHJlYW0gSWQgICAgICAgICAgIDIgYml0cwogICAgICAgLSBhdWRpbyBjb2RpbmcgICAgICAgIDIgYml0cwogICAgICAgLSBTQlIgZmxhZyAgICAgICAgICAgIDEgYml0CiAgICAgICAtIGF1ZGlvIG1vZGUgICAgICAgICAgMiBiaXRzCiAgICAgICAtIGF1ZGlvIHNhbXBsaW5nIHJhdGUgMyBiaXRzCiAgICAgICAtIHRleHQgZmxhZyAgICAgICAgICAgMSBiaXQKICAgICAgIC0gZW5oYW5jZW1lbnQgZmxhZyAgICAxIGJpdAogICAgICAgLSBjb2RlciBmaWVsZCAgICAgICAgIDUgYml0cwogICAgICAgLSByZmEgICAgICAgICAgICAgICAgIDEgYml0ICAqLwoKICAgIGludCBhdWRpb0NvZGluZywgYXVkaW9Nb2RlLCBjU2FtcGxpbmdGcmVxLCBjb2RlckZpZWxkLCBzZklkeCwgc2JyRmxhZzsKCiAgICAvKiBSZWFkIHRoZSBTREMgZmllbGQgKi8KICAgIEZES3JlYWRCaXRzKGJzLDQpOyAgIC8qIFNob3J0IGFuZCBTdHJlYW0gSWQgKi8KCiAgICBhdWRpb0NvZGluZyAgID0gRkRLcmVhZEJpdHMoYnMsIDIpOwogICAgc2JyRmxhZyAgICAgICA9IEZES3JlYWRCaXRzKGJzLCAxKTsKICAgIGF1ZGlvTW9kZSAgICAgPSBGREtyZWFkQml0cyhicywgMik7CiAgICBjU2FtcGxpbmdGcmVxID0gRkRLcmVhZEJpdHMoYnMsIDMpOyAgICAvKiBhdWRpbyBzYW1wbGluZyByYXRlICovCgogICAgRkRLcmVhZEJpdHMoYnMsIDIpOyAgLyogVGV4dCBhbmQgZW5oYW5jZW1lbnQgZmxhZyAqLwogICAgY29kZXJGaWVsZCAgID0gRkRLcmVhZEJpdHMoYnMsIDUpOwogICAgRkRLcmVhZEJpdHMoYnMsIDEpOyAgLyogcmZhICovCgogICAgLyogRXZhbHVhdGUgY29uZmlndXJhdGlvbiBhbmQgZmlsbCB0aGUgQVNDICovCiAgICBzd2l0Y2ggKGNTYW1wbGluZ0ZyZXEpIHsKICAgIGNhc2UgMDogLyogIDgga0h6ICovCiAgICAgIHNmSWR4ID0gMTE7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxOiAvKiAxMiBrSHogKi8KICAgICAgc2ZJZHggPSA5OwogICAgICBicmVhazsKICAgIGNhc2UgMjogLyogMTYga0h6ICovCiAgICAgIHNmSWR4ID0gODsKICAgICAgYnJlYWs7CiAgICBjYXNlIDM6IC8qIDI0IGtIeiAqLwogICAgICBzZklkeCA9IDY7CiAgICAgIGJyZWFrOwogICAgY2FzZSA1OiAvKiA0OCBrSHogKi8KICAgICAgc2ZJZHggPSAzOwogICAgICBicmVhazsKICAgIGNhc2UgNDogLyogcmVzZXJ2ZWQgKi8KICAgIGNhc2UgNjogLyogcmVzZXJ2ZWQgKi8KICAgIGNhc2UgNzogLyogcmVzZXJ2ZWQgKi8KICAgIGRlZmF1bHQ6CiAgICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgc2VsZi0+bV9zYW1wbGluZ0ZyZXF1ZW5jeUluZGV4ID0gc2ZJZHg7CiAgICBzZWxmLT5tX3NhbXBsaW5nRnJlcXVlbmN5ID0gU2FtcGxpbmdSYXRlVGFibGVbc2ZJZHhdOwoKICAgIGlmICggc2JyRmxhZyApIHsKICAgICAgVUlOVCBpOwogICAgICBpbnQgdG1wID0gLTE7CiAgICAgIHNlbGYtPm1fc2JyUHJlc2VudEZsYWcgPSAxOwogICAgICBzZWxmLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZSA9IEFPVF9TQlI7CiAgICAgIHNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3kgPSBzZWxmLT5tX3NhbXBsaW5nRnJlcXVlbmN5IDw8IDE7CiAgICAgIGZvciAoaT0wOyBpPChzaXplb2YoU2FtcGxpbmdSYXRlVGFibGUpL3NpemVvZihTYW1wbGluZ1JhdGVUYWJsZVswXSkpOyBpKyspewogICAgICAgIGlmIChTYW1wbGluZ1JhdGVUYWJsZVtpXSA9PSBzZWxmLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5KXsKICAgICAgICAgIHRtcCA9IGk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgc2VsZi0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeUluZGV4ID0gdG1wOwogICAgfQoKICAgIHN3aXRjaCAoYXVkaW9Db2RpbmcpIHsKICAgICAgY2FzZSAwOiAvKiBBQUMgKi8KICAgICAgICAgIHNlbGYtPm1fYW90ID0gQU9UX0RSTV9BQUMgICAgIDsgIC8qIFNldCBwc2V1ZG8gQU9UIGZvciBEcm0gQUFDICovCgogICAgICAgIHN3aXRjaCAoYXVkaW9Nb2RlKSB7CiAgICAgICAgY2FzZSAxOiAvKiBwYXJhbWV0cmljIHN0ZXJlbyAqLwogICAgICAgICAgc2VsZi0+bV9wc1ByZXNlbnRGbGFnID0gMTsKICAgICAgICBjYXNlIDA6IC8qIG1vbm8gKi8KICAgICAgICAgIHNlbGYtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPSAxOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOiAvKiBzdGVyZW8gKi8KICAgICAgICAgIHNlbGYtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPSAyOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgICBzZWxmLT5tX3ZjYjExRmxhZyA9IDE7CiAgICAgICAgc2VsZi0+bV9oY3JGbGFnID0gMTsKICAgICAgICBzZWxmLT5tX3NhbXBsZXNQZXJGcmFtZSA9IDk2MDsKICAgICAgICBzZWxmLT5tX2VwQ29uZmlnID0gMTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxOiAvKiBDRUxQICovCiAgICAgICAgc2VsZi0+bV9hb3QgPSBBT1RfRVJfQ0VMUDsKICAgICAgICBzZWxmLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uID0gMTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAyOiAvKiBIVlhDICovCiAgICAgICAgc2VsZi0+bV9hb3QgPSBBT1RfRVJfSFZYQzsKICAgICAgICBzZWxmLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uID0gMTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAzOiAvKiByZXNlcnZlZCAqLwogICAgICBkZWZhdWx0OgogICAgICAgIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOwogICAgICAgIHNlbGYtPm1fYW90ID0gQU9UX05PTkU7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHNlbGYtPm1fcHNQcmVzZW50RmxhZyAmJiAhc2VsZi0+bV9zYnJQcmVzZW50RmxhZykgewogICAgICBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQogIH0KCmJhaWw6CiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KCg==