Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKToKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAidHBfZGF0YS5oIgoKI2luY2x1ZGUgInRwZW5jX2xpYi5oIgojaW5jbHVkZSAidHBlbmNfYXNjLmgiCiNpbmNsdWRlICJGREtfYml0c3RyZWFtLmgiCiNpbmNsdWRlICJnZW5lcmljU3Rkcy5oIgoKI2RlZmluZSBQQ0VfTUFYX0VMRU1FTlRTIDgKCi8qKgogKiAgRGVzY3JpYmUgYSBQQ0UgYmFzZWQgb24gcGxhY2VkIGNoYW5uZWwgZWxlbWVudHMgYW5kIGVsZW1lbnQgdHlwZSBzZXF1ZW5jZS4KICovCnR5cGVkZWYgc3RydWN0IHsKCiAgICBVQ0hBUiAgICBudW1fZnJvbnRfY2hhbm5lbF9lbGVtZW50czsgICAgIC8qITwgTnVtYmVyIG9mIGZyb250IGNoYW5uZWwgZWxlbWVudHMuICovCiAgICBVQ0hBUiAgICBudW1fc2lkZV9jaGFubmVsX2VsZW1lbnRzOyAgICAgIC8qITwgTnVtYmVyIG9mIHNpZGUgY2hhbm5lbCBlbGVtZW50cy4gKi8KICAgIFVDSEFSICAgIG51bV9iYWNrX2NoYW5uZWxfZWxlbWVudHM7ICAgICAgLyohPCBOdW1iZXIgb2YgYmFjayBjaGFubmVsIGVsZW1lbnRzLiAqLwogICAgVUNIQVIgICAgbnVtX2xmZV9jaGFubmVsX2VsZW1lbnRzOyAgICAgICAvKiE8IE51bWJlciBvZiBsZmUgY2hhbm5lbCBlbGVtZW50cy4gKi8KICAgIE1QNF9FTEVNRU5UX0lEIGVsX2xpc3RbUENFX01BWF9FTEVNRU5UU107LyohPCBMaXN0IGNvbnRhaW5zIHNlcXVlbmNlIGRlc2NyaWJpbmcgdGhlIGVsZW1lbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gcHJlc2VudCBjaGFubmVsIG1vZGUuIChNUEVHIG9yZGVyKSAqLwp9IFBDRV9DT05GSUdVUkFUSU9OOwoKCi8qKgogKiAgTWFwIGFuIGluY29taW5nIGNoYW5uZWwgbW9kZSB0byBhIGV4aXN0aW5nIFBDRSBjb25maWd1cmF0aW9uIGVudHJ5LgogKi8KdHlwZWRlZiBzdHJ1Y3QgewoKICAgIENIQU5ORUxfTU9ERSAgICAgICAgY2hhbm5lbF9tb2RlOyAgICAgICAgLyohPCBQcmVzZW50IGNoYW5uZWwgbW9kZS4gKi8KICAgIFBDRV9DT05GSUdVUkFUSU9OICAgcGNlX2NvbmZpZ3VyYXRpb247ICAgLyohPCBQcm9ncmFtIGNvbmZpZyBlbGVtZW50IGRlc2NyaXB0aW9uLiAqLwoKfSBDSEFOTkVMX0NPTkZJR1VSQVRJT047CgoKLyoqCiAqIFxicmllZiBUYWJsZSBjb250YWlucyBhbGwgc3VwcG9ydGVkIGNoYW5uZWwgbW9kZXMgYW5kIGFjY29yZGluZyBQQ0UgY29uZmlndXJhdGlvbiBkZXNjcmlwdGlvbi4KICoKICogVGhlIG51bWJlciBvZiBjaGFubmVsIGVsZW1lbnQgcGFyYW1ldGVyIGRlc2NyaWJlcyB0aGUga2luZCBvZiBjb25zZWN1dGl2ZWx5IGVsZW1lbnRzLgogKiBFLmcuIE1PREVfMV8yXzJfMl8xIG1lYW5zOgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBGaXJzdCAzIGVsZW1lbnRzIChTQ0UsQ1BFLENQRSkgYXJlIGZyb250IGNoYW5uZWwgZWxlbWVudHMuCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAtIE5leHQgZWxlbWVudCAoQ1BFKSBpcyBhIGJhY2sgY2hhbm5lbCBlbGVtZW50LgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBMYXN0IGVsZW1lbnQgKExGRSkgaXMgYSBsZmUgY2hhbm5lbCBlbGVtZW50LgogKi8Kc3RhdGljIGNvbnN0IENIQU5ORUxfQ09ORklHVVJBVElPTiBwY2VDb25maWdUYWJbXSA9CnsKICB7IE1PREVfMSwgICAgICAgICAgICAgICAgICAgICAgICB7ICAxLCAwLCAwLCAwLCB7IElEX1NDRSwgIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUgfSB9IH0sCiAgeyBNT0RFXzIsICAgICAgICAgICAgICAgICAgICAgICAgeyAgMSwgMCwgMCwgMCwgeyBJRF9DUEUsICBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAogIHsgTU9ERV8xXzIsICAgICAgICAgICAgICAgICAgICAgIHsgIDIsIDAsIDAsIDAsIHsgSURfU0NFLCAgSURfQ1BFLCAgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSB9IH0gfSwKICB7IE1PREVfMV8yXzEsICAgICAgICAgICAgICAgICAgICB7ICAyLCAwLCAxLCAwLCB7IElEX1NDRSwgIElEX0NQRSwgIElEX1NDRSwgIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUgfSB9IH0sCiAgeyBNT0RFXzFfMl8yLCAgICAgICAgICAgICAgICAgICAgeyAgMiwgMCwgMSwgMCwgeyBJRF9TQ0UsICBJRF9DUEUsICBJRF9DUEUsICBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAogIHsgTU9ERV8xXzJfMl8xLCAgICAgICAgICAgICAgICAgIHsgIDIsIDAsIDEsIDEsIHsgSURfU0NFLCAgSURfQ1BFLCAgSURfQ1BFLCAgSURfTEZFLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAogIHsgTU9ERV8xXzJfMl8yXzEsICAgICAgICAgICAgICAgIHsgIDMsIDAsIDEsIDEsIHsgSURfU0NFLCAgSURfQ1BFLCAgSURfQ1BFLCAgSURfQ1BFLCAgSURfTEZFLCAgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSB9IH0gfSwKCgogIHsgTU9ERV8xXzEsICAgICAgICAgICAgICAgICAgICAgIHsgIDIsIDAsIDAsIDAsIHsgSURfU0NFLCAgSURfU0NFLCAgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSB9IH0gfSwKICB7IE1PREVfMV8xXzFfMSwgICAgICAgICAgICAgICAgICB7ICAyLCAyLCAwLCAwLCB7IElEX1NDRSwgIElEX1NDRSwgIElEX1NDRSwgIElEX1NDRSwgIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUgfSB9IH0sCiAgeyBNT0RFXzFfMV8xXzFfMV8xLCAgICAgICAgICAgICAgeyAgMiwgMiwgMiwgMCwgeyBJRF9TQ0UsICBJRF9TQ0UsICBJRF9TQ0UsICBJRF9TQ0UsICBJRF9TQ0UsICBJRF9TQ0UsICBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAogIHsgTU9ERV8xXzFfMV8xXzFfMV8xXzEsICAgICAgICAgIHsgIDMsIDIsIDMsIDAsIHsgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFLCAgSURfU0NFIH0gfSB9LAoKICB7IE1PREVfMl8yLCAgICAgICAgICAgICAgICAgICAgICB7ICAxLCAwLCAxLCAwLCB7IElEX0NQRSwgIElEX0NQRSwgIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUsIElEX05PTkUgfSB9IH0sCiAgeyBNT0RFXzJfMl8yLCAgICAgICAgICAgICAgICAgICAgeyAgMSwgMSwgMSwgMCwgeyBJRF9DUEUsICBJRF9DUEUsICBJRF9DUEUsICBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAogIHsgTU9ERV8yXzJfMl8yLCAgICAgICAgICAgICAgICAgIHsgIDQsIDAsIDAsIDAsIHsgSURfQ1BFLCAgSURfQ1BFLCAgSURfQ1BFLCAgSURfQ1BFLCAgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSwgSURfTk9ORSB9IH0gfSwKCiAgeyBNT0RFXzJfMSwgICAgICAgICAgICAgICAgICAgICAgeyAgMSwgMCwgMSwgMCwgeyBJRF9DUEUsICBJRF9TQ0UsICBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAoKICB7IE1PREVfN18xX1JFQVJfU1VSUk9VTkQsICAgICAgICB7ICAyLCAwLCAyLCAxLCB7IElEX1NDRSwgIElEX0NQRSwgIElEX0NQRSwgIElEX0NQRSwgIElEX0xGRSwgIElEX05PTkUsIElEX05PTkUsIElEX05PTkUgfSB9IH0sCiAgeyBNT0RFXzdfMV9GUk9OVF9DRU5URVIsICAgICAgICAgeyAgMywgMCwgMSwgMSwgeyBJRF9TQ0UsICBJRF9DUEUsICBJRF9DUEUsICBJRF9DUEUsICBJRF9MRkUsICBJRF9OT05FLCBJRF9OT05FLCBJRF9OT05FIH0gfSB9LAoKfTsKCgovKioKICogXGJyaWVmICBHZXQgcHJvZ3JhbSBjb25maWcgZWxlbWVudCBkZXNjcmlwdGlvbiBmb3IgZXhpc3RpbmcgY2hhbm5lbCBtb2RlLgogKgogKiBccGFyYW0gY2hhbm5lbF9tb2RlICAgICAgICAgIEN1cnJlbnQgY2hhbm5lbCBtb2RlLgogKgogKiBccmV0dXJuCiAqICAgICAgICAgIC0gUG9pbnRlciB0byBQQ0VfQ09ORklHVVJBVElPTiBlbnRyeSwgb24gc3VjY2Vzcy4KICogICAgICAgICAgLSBOVUxMLCBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGNvbnN0IFBDRV9DT05GSUdVUkFUSU9OKiBnZXRQY2VFbnRyeSgKICAgICAgICBjb25zdCBDSEFOTkVMX01PREUgY2hhbm5lbF9tb2RlCiAgICAgICAgKQp7CiAgVUlOVCBpOwogIGNvbnN0IFBDRV9DT05GSUdVUkFUSU9OICpwY2VfY29uZmlnID0gTlVMTDsKCiAgZm9yIChpPTA7IGkgPCAoc2l6ZW9mKHBjZUNvbmZpZ1RhYikvc2l6ZW9mKENIQU5ORUxfQ09ORklHVVJBVElPTikpOyBpKyspIHsKICAgIGlmIChwY2VDb25maWdUYWJbaV0uY2hhbm5lbF9tb2RlID09IGNoYW5uZWxfbW9kZSkgewogICAgICBwY2VfY29uZmlnID0gJnBjZUNvbmZpZ1RhYltpXS5wY2VfY29uZmlndXJhdGlvbjsKICAgIH0KICB9CgogIHJldHVybiBwY2VfY29uZmlnOwp9CgppbnQgZ2V0Q2hhbm5lbENvbmZpZyggQ0hBTk5FTF9NT0RFIGNoYW5uZWxfbW9kZSApCnsKICBJTlQgY2hhbl9jb25maWcgPSAwOwoKICBzd2l0Y2goY2hhbm5lbF9tb2RlKSB7CiAgICBjYXNlIE1PREVfMTogICAgICAgICBjaGFuX2NvbmZpZyA9IDE7IGJyZWFrOwogICAgY2FzZSBNT0RFXzI6ICAgICAgICAgY2hhbl9jb25maWcgPSAyOyBicmVhazsKICAgIGNhc2UgTU9ERV8xXzI6ICAgICAgIGNoYW5fY29uZmlnID0gMzsgYnJlYWs7CiAgICBjYXNlIE1PREVfMV8yXzE6ICAgICBjaGFuX2NvbmZpZyA9IDQ7IGJyZWFrOwogICAgY2FzZSBNT0RFXzFfMl8yOiAgICAgY2hhbl9jb25maWcgPSA1OyBicmVhazsKICAgIGNhc2UgTU9ERV8xXzJfMl8xOiAgIGNoYW5fY29uZmlnID0gNjsgYnJlYWs7CiAgICBjYXNlIE1PREVfMV8yXzJfMl8xOiBjaGFuX2NvbmZpZyA9IDc7IGJyZWFrOwoKICAgIGRlZmF1bHQ6ICAgICAgICAgICAgIGNoYW5fY29uZmlnID0gMDsKICB9CgogIHJldHVybiBjaGFuX2NvbmZpZzsKfQoKQ0hBTk5FTF9NT0RFIHRyYW5zcG9ydEVuY19HZXRDaGFubmVsTW9kZSggaW50IG5vQ2hhbm5lbHMgKQp7CiAgQ0hBTk5FTF9NT0RFIGNoTW9kZTsKCiAgaWYgKG5vQ2hhbm5lbHMgPD0gOCAmJiBub0NoYW5uZWxzID4gMCkKICAgIGNoTW9kZSA9IChDSEFOTkVMX01PREUpKChub0NoYW5uZWxzID09IDgpID8gNyA6IG5vQ2hhbm5lbHMpOyAvKiBzZWUgOiBpc28vbXBlZzQgdjEgYXVkaW8gc3VicGFydDEqLwogIGVsc2UKICAgIGNoTW9kZSA9IE1PREVfVU5LTk9XTjsKCiAgcmV0dXJuIGNoTW9kZTsKfQoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKaW50IHRyYW5zcG9ydEVuY193cml0ZVBDRShIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgQ0hBTk5FTF9NT0RFIGNoYW5uZWxNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbnN0YW5jZVRhZ1BDRSwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF0cml4TWl4ZG93bkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBzZXVkb1N1cnJvdW5kRW5hYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgYWxpZ25BbmNob3IpCnsKICBpbnQgc2FtcGxlUmF0ZUluZGV4LCBpOwogIGNvbnN0IFBDRV9DT05GSUdVUkFUSU9OKiBjb25maWcgPSBOVUxMOwogIGNvbnN0IE1QNF9FTEVNRU5UX0lEKiBwRWxfbGlzdCA9IE5VTEw7CiAgVUNIQVIgY3BlQ250PTAsIHNjZUNudD0wLCBsZmVDbnQ9MDsKCiAgc2FtcGxlUmF0ZUluZGV4ID0gZ2V0U2FtcGxpbmdSYXRlSW5kZXgoc2FtcGxlUmF0ZSk7CiAgaWYgKHNhbXBsZVJhdGVJbmRleCA9PSAxNSkgewogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYgKChjb25maWc9Z2V0UGNlRW50cnkoY2hhbm5lbE1vZGUpKT09TlVMTCkgewogICAgcmV0dXJuIC0xOwogIH0KCiAgLyogUG9pbnRlciB0byBmaXJzdCBlbGVtZW50IGluIGVsZW1lbnQgbGlzdC4gKi8KICBwRWxfbGlzdCA9ICZjb25maWctPmVsX2xpc3RbMF07CgogIEZES3dyaXRlQml0cyhoQnMsIGluc3RhbmNlVGFnUENFLCAgNCk7ICAgICAgICAgICAgICAgICAgICAgICAgLyogRWxlbWVudCBpbnN0YW5jZSB0YWcgKi8KICBGREt3cml0ZUJpdHMoaEJzLCBwcm9maWxlLCAgICAgICAgIDIpOyAgICAgICAgICAgICAgICAgICAgICAgIC8qIE9iamVjdCB0eXBlICovCiAgRkRLd3JpdGVCaXRzKGhCcywgc2FtcGxlUmF0ZUluZGV4LCA0KTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBTYW1wbGUgcmF0ZSBpbmRleCovCgogIEZES3dyaXRlQml0cyhoQnMsIGNvbmZpZy0+bnVtX2Zyb250X2NoYW5uZWxfZWxlbWVudHMsIDQpOyAgICAgLyogRnJvbnQgY2hhbm5lbCBFbGVtZW50cyAqLwogIEZES3dyaXRlQml0cyhoQnMsIGNvbmZpZy0+bnVtX3NpZGVfY2hhbm5lbF9lbGVtZW50cyAsIDQpOyAgICAgLyogTm8gU2lkZSBDaGFubmVsIEVsZW1lbnRzICovCiAgRkRLd3JpdGVCaXRzKGhCcywgY29uZmlnLT5udW1fYmFja19jaGFubmVsX2VsZW1lbnRzICwgNCk7ICAgICAvKiBObyBCYWNrIGNoYW5uZWwgRWxlbWVudHMgKi8KICBGREt3cml0ZUJpdHMoaEJzLCBjb25maWctPm51bV9sZmVfY2hhbm5lbF9lbGVtZW50cyAgLCAyKTsgICAgIC8qIE5vIExmZSBjaGFubmVsIGVsZW1lbnRzICovCgogIEZES3dyaXRlQml0cyhoQnMsIDAsIDMpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm8gYXNzb2MgZGF0YSBlbGVtZW50cyAqLwogIEZES3dyaXRlQml0cyhoQnMsIDAsIDQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm8gdmFsaWQgY2MgZWxlbWVudHMgKi8KICBGREt3cml0ZUJpdHMoaEJzLCAwLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE1vbm8gbWl4ZG93biBwcmVzZW50ICovCiAgRkRLd3JpdGVCaXRzKGhCcywgMCwgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTdGVyZW8gbWl4ZG93biBwcmVzZW50ICovCgogIGlmICggbWF0cml4TWl4ZG93bkEhPTAgJiYgKChjaGFubmVsTW9kZT09TU9ERV8xXzJfMil8fChjaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKSB7CiAgICAgIEZES3dyaXRlQml0cyhoQnMsIDEsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBNYXRyaXggbWl4ZG93biBwcmVzZW50ICovCiAgICAgIEZES3dyaXRlQml0cyhoQnMsIChtYXRyaXhNaXhkb3duQS0xKSYweDMsIDIpOyAgICAgICAgICAgICAvKiBtYXRyaXhfbWl4ZG93bl9pZHggKi8KICAgICAgRkRLd3JpdGVCaXRzKGhCcywgKHBzZXVkb1N1cnJvdW5kRW5hYmxlKT8xOjAsIDEpOyAgICAgICAgIC8qIHBzZXVkb19zdXJyb3VuZF9lbmFibGUgKi8KICB9CiAgZWxzZSB7CiAgICAgIEZES3dyaXRlQml0cyhoQnMsIDAsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBNYXRyaXggbWl4ZG93biBub3QgcHJlc2VudCAqLwogIH0KCiAgZm9yKGk9MDsgaTxjb25maWctPm51bV9mcm9udF9jaGFubmVsX2VsZW1lbnRzOyBpKyspIHsKICAgICAgVUNIQVIgaXNDcGUgPSAoKnBFbF9saXN0Kys9PUlEX0NQRSkgPyAxIDogMDsKICAgICAgVUNIQVIgdGFnICAgPSAoaXNDcGUpID8gY3BlQ250KysgOiBzY2VDbnQrKzsKICAgICAgRkRLd3JpdGVCaXRzKGhCcywgaXNDcGUsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZyb250IGNoYW5uZWwgRWxlbWVudHMgaXMgQ1BFPyAqLwogICAgICBGREt3cml0ZUJpdHMoaEJzLCB0YWcsIDQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRnJvbnQgY2hhbm5lbCBJbnN0YW5jZSBUYWcuKi8KICB9CiAgZm9yKGk9MDsgaTxjb25maWctPm51bV9zaWRlX2NoYW5uZWxfZWxlbWVudHM7IGkrKykgewogICAgICBVQ0hBUiBpc0NwZSA9ICgqcEVsX2xpc3QrKz09SURfQ1BFKSA/IDEgOiAwOwogICAgICBVQ0hBUiB0YWcgICA9IChpc0NwZSkgPyBjcGVDbnQrKyA6IHNjZUNudCsrOwogICAgICBGREt3cml0ZUJpdHMoaEJzLCBpc0NwZSwgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRnJvbnQgY2hhbm5lbCBFbGVtZW50cyBpcyBDUEU/ICovCiAgICAgIEZES3dyaXRlQml0cyhoQnMsIHRhZywgNCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGcm9udCBjaGFubmVsIEluc3RhbmNlIFRhZy4qLwogIH0KICBmb3IoaT0wOyBpPGNvbmZpZy0+bnVtX2JhY2tfY2hhbm5lbF9lbGVtZW50czsgaSsrKSB7CiAgICAgIFVDSEFSIGlzQ3BlID0gKCpwRWxfbGlzdCsrPT1JRF9DUEUpID8gMSA6IDA7CiAgICAgIFVDSEFSIHRhZyAgID0gKGlzQ3BlKSA/IGNwZUNudCsrIDogc2NlQ250Kys7CiAgICAgIEZES3dyaXRlQml0cyhoQnMsIGlzQ3BlLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGcm9udCBjaGFubmVsIEVsZW1lbnRzIGlzIENQRT8gKi8KICAgICAgRkRLd3JpdGVCaXRzKGhCcywgdGFnLCA0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZyb250IGNoYW5uZWwgSW5zdGFuY2UgVGFnLiovCiAgfQogIGZvcihpPTA7IGk8Y29uZmlnLT5udW1fbGZlX2NoYW5uZWxfZWxlbWVudHM7IGkrKykgewogICAgICBGREt3cml0ZUJpdHMoaEJzLCBsZmVDbnQrKywgNCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTEZFIGNoYW5uZWwgSW5zdGFuY2UgVGFnLiAqLwogIH0KCiAgLyogLSBudW1fdmFsaWRfY2NfZWxlbWVudHMgYWx3YXlzIDAuCiAgICAgLSBudW1fYXNzb2NfZGF0YV9lbGVtZW50cyBhbHdheXMgMC4gKi8KCiAgLyogQnl0ZSBhbGlnbm1lbnQ6IHJlbGF0aXZlIHRvIGFsaWduQW5jaG9yCiAgICAgICBBRFRTOiBhbGlnbiB3aXRoIHJlc3BlY3QgdG8gdGhlIGZpcnN0IGJpdCBvZiB0aGUgcmF3X2RhdGFfYmxvY2soKQogICAgICAgQURJRjogYWxpZ24gd2l0aCByZXNwZWN0IHRvIHRoZSBmaXJzdCBiaXQgb2YgdGhlIGhlYWRlcgogICAgICAgTEFUTTogYWxpZ24gd2l0aCByZXNwZWN0IHRvIHRoZSBmaXJzdCBiaXQgb2YgdGhlIEFTQyAqLwogIEZES2J5dGVBbGlnbihoQnMsIGFsaWduQW5jaG9yKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQWxpZ25tZW50ICovCgogIEZES3dyaXRlQml0cyhoQnMsIDAgLDgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRG8gbm8gd3JpdGUgYW55IGNvbW1lbnQuICovCgogIC8qIC0gY29tbWVudF9maWVsZF9ieXRlcyBhbHdheXMgMC4gKi8KCiAgcmV0dXJuIDA7Cn0KCmludCB0cmFuc3BvcnRFbmNfR2V0UENFQml0cyhDSEFOTkVMX01PREUgY2hhbm5lbE1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWF0cml4TWl4ZG93bkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYml0cykKewogIGNvbnN0IFBDRV9DT05GSUdVUkFUSU9OKiBjb25maWcgPSBOVUxMOwoKICBpZiAoKGNvbmZpZz1nZXRQY2VFbnRyeShjaGFubmVsTW9kZSkpPT1OVUxMKSB7CiAgICByZXR1cm4gLTE7ICAvKiB1bnN1cHBvcnRlZCBjaGFubmVsbWFwcGluZyAqLwogIH0KCiAgYml0cyArPSA0ICsgMiArIDQ7ICAgICAgICAvKiBFbGVtZW50IGluc3RhbmNlIHRhZyAgKyBPYmplY3QgdHlwZSArIFNhbXBsZSByYXRlIGluZGV4ICovCiAgYml0cyArPSA0ICsgNCArIDQgKyAyOyAgICAvKiBObyAoZnJvbnQgKyBzaWRlICsgYmFjayArIGxmZSBjaGFubmVsKSBlbGVtZW50cyAqLwogIGJpdHMgKz0gMyArIDQ7ICAgICAgICAgICAgLyogTm8gKGFzc29jIGRhdGEgKyB2YWxpZCBjYykgZWxlbWVudHMgKi8KICBiaXRzICs9IDEgKyAxICsgMSA7ICAgICAgIC8qIE1vbm8gKyBTdGVyZW8gKyBNYXRyaXggbWl4ZG93biBwcmVzZW50ICovCgogIGlmICggbWF0cml4TWl4ZG93bkEhPTAgJiYgKChjaGFubmVsTW9kZT09TU9ERV8xXzJfMil8fChjaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKSB7CiAgICBiaXRzICs9MzsgICAgICAgICAgICAgICAvKiBtYXRyaXhfbWl4ZG93bl9pZHggKyBwc2V1ZG9fc3Vycm91bmRfZW5hYmxlICovCiAgfQoKICBiaXRzICs9ICgxKzQpICogKElOVCljb25maWctPm51bV9mcm9udF9jaGFubmVsX2VsZW1lbnRzOwogIGJpdHMgKz0gKDErNCkgKiAoSU5UKWNvbmZpZy0+bnVtX3NpZGVfY2hhbm5lbF9lbGVtZW50czsKICBiaXRzICs9ICgxKzQpICogKElOVCljb25maWctPm51bV9iYWNrX2NoYW5uZWxfZWxlbWVudHM7CiAgYml0cyArPSAgICg0KSAqIChJTlQpY29uZmlnLT5udW1fbGZlX2NoYW5uZWxfZWxlbWVudHM7CgogIC8qIC0gbnVtX3ZhbGlkX2NjX2VsZW1lbnRzIGFsd2F5cyAwLgogICAgIC0gbnVtX2Fzc29jX2RhdGFfZWxlbWVudHMgYWx3YXlzIDAuICovCgogIGlmICgoYml0cyU4KSAhPSAwKSB7CiAgICBiaXRzICs9ICg4IC0gKGJpdHMlOCkpOyAvKiBBbGlnbm1lbnQgKi8KICB9CgogIGJpdHMgKz0gODsgICAgICAgICAgICAgICAgLyogQ29tbWVudCBmaWVsZCAgYnl0ZXMgKi8KCiAgLyogLSBjb21tZW50X2ZpZWxkX2J5dGVzIGFsd3lzIDAuICovCgogIHJldHVybiBiaXRzOwp9CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCgpzdGF0aWMgdm9pZCB3cml0ZUFvdChIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQml0c3RyZWFtQnVmZmVyLCBBVURJT19PQkpFQ1RfVFlQRSBhb3QpCnsKICAgIGludCB0bXAgPSAoaW50KSBhb3Q7CgogICAgaWYgKHRtcCA+IDMxKSB7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQml0c3RyZWFtQnVmZmVyLCBBT1RfRVNDQVBFLCA1ICk7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQml0c3RyZWFtQnVmZmVyLCB0bXAtMzIsIDYgKTsgICAvKiBBdWRpb09iamVjdFR5cGUgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQml0c3RyZWFtQnVmZmVyLCB0bXAsIDUgKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgd3JpdGVTYW1wbGVSYXRlKEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRzdHJlYW1CdWZmZXIsIGludCBzYW1wbGVSYXRlKQp7CiAgaW50IHNhbXBsZVJhdGVJbmRleCA9IGdldFNhbXBsaW5nUmF0ZUluZGV4KHNhbXBsZVJhdGUpOwoKICBGREt3cml0ZUJpdHMoIGhCaXRzdHJlYW1CdWZmZXIsIHNhbXBsZVJhdGVJbmRleCwgNCApOwogIGlmKCBzYW1wbGVSYXRlSW5kZXggPT0gMTUgKSB7CiAgICBGREt3cml0ZUJpdHMoIGhCaXRzdHJlYW1CdWZmZXIsIHNhbXBsZVJhdGUsIDI0ICk7CiAgfQp9CgojaWZkZWYgVFBfR0FfRU5BQkxFCnN0YXRpYwppbnQgdHJhbnNwb3J0RW5jX3dyaXRlR0FTcGVjaWZpY0NvbmZpZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGFzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPREVSX0NPTkZJRyAqY29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgIGV4dEZsZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICBhbGlnbkFuY2hvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgYW90ID0gY29uZmlnLT5hb3Q7CiAgaW50IHNhbXBsZXNQZXJGcmFtZSA9IGNvbmZpZy0+c2FtcGxlc1BlckZyYW1lOwoKICAvKiBzdGFydCBvZiBHQVNwZWNpZmljQ29uZmlnIGFjY29yZGluZyB0byBJU08vSUVDIDE0NDk2LTMgU3VicGFydCA0LCA0LjQuMSAqLwogIEZES3dyaXRlQml0cyggYXNjLCAoKHNhbXBsZXNQZXJGcmFtZT09OTYwIHx8IHNhbXBsZXNQZXJGcmFtZT09NDgwKT8xOjApLCAxKTsgIC8qIGZyYW1lTGVuZ3RoRmxhZzogMSBmb3IgYSA5NjAvNDgwIChJKU1EQ1QsIDAgZm9yIGEgMTAyNC81MTIgKEkpTURDVCovCiAgRkRLd3JpdGVCaXRzKCBhc2MsIDAsIDEpOyAgLyogZGVwZW5kc09uQ29yZUNvZGVyOiBTYW1wbGluZyBSYXRlIENvZGVyIFNwZWNpZmljLCBzZWUgaW4gSVNPL0lFQyAxNDQ5Ni0zIFN1YnBhcnQgNCwgNC40LjEgKi8KICBGREt3cml0ZUJpdHMoIGFzYywgZXh0RmxnLCAxICk7IC8qIEV4dGVuc2lvbiBGbGFnOiBTaGFsbCBiZSAxIGZvciBhb3QgPSAxNywxOSwyMCwyMSwyMiwyMyAqLwoKICAvKiBXcml0ZSBQQ0UgaWYgY2hhbm5lbCBjb25maWcgaXMgbm90IDEtNyAqLwogIGlmIChnZXRDaGFubmVsQ29uZmlnKGNvbmZpZy0+Y2hhbm5lbE1vZGUpID09IDApIHsKICAgICAgdHJhbnNwb3J0RW5jX3dyaXRlUENFKGFzYywgY29uZmlnLT5jaGFubmVsTW9kZSwgY29uZmlnLT5zYW1wbGluZ1JhdGUsIDAsIDEsIGNvbmZpZy0+bWF0cml4TWl4ZG93bkEsIChjb25maWctPmZsYWdzJkNDX1BTRVVET19TVVJST1VORCk/MTowLCBhbGlnbkFuY2hvcik7CiAgfQogIGlmIChleHRGbGcpIHsKICAgIGlmIChhb3QgPT0gQU9UX0VSX0JTQUMpIHsKICAgICAgRkRLd3JpdGVCaXRzKCBhc2MsIGNvbmZpZy0+QlNBQ251bU9mU3ViRnJhbWUsIDUgKTsgLyogbnVtT2ZTdWJGcmFtZSAqLwogICAgICBGREt3cml0ZUJpdHMoIGFzYywgY29uZmlnLT5CU0FDbGF5ZXJMZW5ndGgsIDExICk7ICAvKiBsYXllcl9sZW5ndGggKi8KICAgIH0KICAgIGlmICgoYW90ID09IEFPVF9FUl9BQUNfTEMpICAgfHwgKGFvdCA9PSBBT1RfRVJfQUFDX0xUUCkgIHx8CiAgICAgICAgKGFvdCA9PSBBT1RfRVJfQUFDX1NDQUwpIHx8IChhb3QgPT0gQU9UX0VSX0FBQ19MRCkpCiAgICB7CiAgICAgIEZES3dyaXRlQml0cyggYXNjLCAoY29uZmlnLT5mbGFncyAmIENDX1ZDQjExKSA/IDEgOiAwLCAxICk7IC8qIGFhY1NlY3Rpb25EYXRhUmVzaWxsaWVuY2VGbGFnICovCiAgICAgIEZES3dyaXRlQml0cyggYXNjLCAoY29uZmlnLT5mbGFncyAmIENDX1JWTEMpID8gMSA6IDAsICAxICk7IC8qIGFhY1NjYWxlRmFjdG9yRGF0YVJlc2lsbGllbmNlRmxhZyAqLwogICAgICBGREt3cml0ZUJpdHMoIGFzYywgKGNvbmZpZy0+ZmxhZ3MgJiBDQ19IQ1IpID8gMSA6IDAsICAgMSApOyAvKiBhYWNTcGVjdHJhbERhdGFSZXNpbGxpZW5jZUZsYWcgKi8KICAgIH0KICAgIEZES3dyaXRlQml0cyggYXNjLCAwLCAxICk7IC8qIGV4dGVuc2lvbkZsYWczOiByZXNlcnZlZC4gU2hhbGwgYmUgJzAnICovCiAgfQogIHJldHVybiAwOwp9CiNlbmRpZiAvKiBUUF9HQV9FTkFCTEUgKi8KCiNpZmRlZiBUUF9FTERfRU5BQkxFCgpzdGF0aWMKaW50IHRyYW5zcG9ydEVuY193cml0ZUVMRFNwZWNpZmljQ29uZmlnKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFUl9DT05GSUcgKmNvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgIGVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTVHBDYWxsQmFja3MgKmNiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICAvKiBFTEQgc3BlY2lmaWMgY29uZmlnICovCiAgaWYgKGNvbmZpZy0+Y2hhbm5lbE1vZGUgPT0gTU9ERV8xXzEpIHsKICAgIHJldHVybiAtMTsKICB9CiAgRkRLd3JpdGVCaXRzKGhCcywgKGNvbmZpZy0+c2FtcGxlc1BlckZyYW1lID09IDQ4MCkgPyAxIDogMCwgMSk7CgogIEZES3dyaXRlQml0cyhoQnMsIChjb25maWctPmZsYWdzICYgQ0NfVkNCMTEgKSA/IDE6MCwgMSk7CiAgRkRLd3JpdGVCaXRzKGhCcywgKGNvbmZpZy0+ZmxhZ3MgJiBDQ19SVkxDICkgPyAxOjAsIDEpOwogIEZES3dyaXRlQml0cyhoQnMsIChjb25maWctPmZsYWdzICYgQ0NfSENSICApID8gMTowLCAxKTsKCiAgRkRLd3JpdGVCaXRzKGhCcywgKGNvbmZpZy0+ZmxhZ3MgJiBDQ19TQlIpID8gMTowLCAxKTsgLyogU0JSIGhlYWRlciBmbGFnICovCiAgaWYgKCAoY29uZmlnLT5mbGFncyAmIENDX1NCUikgKSB7CiAgICBGREt3cml0ZUJpdHMoaEJzLCAoY29uZmlnLT5zYW1wbGluZ1JhdGUgPT0gY29uZmlnLT5leHRTYW1wbGluZ1JhdGUpID8gMDoxLCAxKTsgLyogU2FtcGxlcmF0ZSBGbGFnICovCiAgICBGREt3cml0ZUJpdHMoaEJzLCAoY29uZmlnLT5mbGFncyAmIENDX1NCUkNSQykgPyAxOjAsIDEpOyAvKiBTQlIgQ1JDIGZsYWcqLwoKICAgIGlmIChjYi0+Y2JTYnIgIT0gTlVMTCkgewogICAgICBjb25zdCBQQ0VfQ09ORklHVVJBVElPTiAqcFBjZTsKICAgICAgaW50IGU7CgogICAgICBwUGNlID0gZ2V0UGNlRW50cnkoY29uZmlnLT5jaGFubmVsTW9kZSk7CgogICAgICBmb3IgKGU9MDsgZTxQQ0VfTUFYX0VMRU1FTlRTICYmIHBQY2UtPmVsX2xpc3RbZV0gIT0gSURfTk9ORTsgZSsrICApIHsKICAgICAgICBpZiAoIChwUGNlLT5lbF9saXN0W2VdID09IElEX1NDRSkgfHwgKHBQY2UtPmVsX2xpc3RbZV0gPT0gSURfQ1BFKSApIHsKICAgICAgICAgIGNiLT5jYlNicihjYi0+Y2JTYnJEYXRhLCBoQnMsIDAsIDAsIDAsIGNvbmZpZy0+YW90LCBwUGNlLT5lbF9saXN0W2VdLCBlKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIEZES3dyaXRlQml0cyhoQnMsIDAsIDQpOyAvKiBFTERFWFRfVEVSTSAqLwoKICByZXR1cm4gMDsKfQojZW5kaWYgLyogVFBfRUxEX0VOQUJMRSAqLwoKCmludCB0cmFuc3BvcnRFbmNfd3JpdGVBU0MgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ERVJfQ09ORklHICpjb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDU1RwQ2FsbEJhY2tzICpjYgogICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBVSU5UIGV4dEZsYWcgPSAwOwogIGludCBlcnI7CiAgaW50IGVwQ29uZmlnID0gMDsKCiAgLyogUmVxdWlyZWQgZm9yIHRoZSBQQ0UuICovCiAgVUlOVCBhbGlnbkFuY2hvciA9IEZES2dldFZhbGlkQml0cyhhc2MpOwoKICAvKiBFeHRlbnNpb24gRmxhZzogU2hhbGwgYmUgMSBmb3IgYW90ID0gMTcsMTksMjAsMjEsMjIsMjMsMzkgKi8KICBzd2l0Y2ggKGNvbmZpZy0+YW90KSB7CiAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTFRQOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9FUl9UV0lOX1ZROgogICAgY2FzZSBBT1RfRVJfQlNBQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICBjYXNlIEFPVF9VU0FDOgogICAgICAgIGV4dEZsYWcgPSAxOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICB9CgogIGlmIChjb25maWctPnNiclNpZ25hbGluZz09U0lHX0VYUExJQ0lUX0hJRVJBUkNISUNBTCAmJiBjb25maWctPnNiclByZXNlbnQpCiAgICB3cml0ZUFvdChhc2MsIGNvbmZpZy0+ZXh0QU9UKTsKICBlbHNlCiAgICB3cml0ZUFvdChhc2MsIGNvbmZpZy0+YW90KTsKCiAgewogICAgd3JpdGVTYW1wbGVSYXRlKGFzYywgY29uZmlnLT5zYW1wbGluZ1JhdGUpOwogIH0KCiAgLyogVHJ5IHRvIGd1ZXNzIGEgcmVhc29uYWJsZSBjaGFubmVsIG1vZGUgaWYgbm90IGdpdmVuICovCiAgaWYgKGNvbmZpZy0+Y2hhbm5lbE1vZGUgPT0gTU9ERV9JTlZBTElEKSB7CiAgICBjb25maWctPmNoYW5uZWxNb2RlID0gdHJhbnNwb3J0RW5jX0dldENoYW5uZWxNb2RlKGNvbmZpZy0+bm9DaGFubmVscyk7CiAgICBpZiAoY29uZmlnLT5jaGFubmVsTW9kZSA9PSBNT0RFX0lOVkFMSUQpCiAgICAgIHJldHVybiAtMTsKICB9CgogIEZES3dyaXRlQml0cyggYXNjLCBnZXRDaGFubmVsQ29uZmlnKGNvbmZpZy0+Y2hhbm5lbE1vZGUpLCA0ICk7CgogIGlmIChjb25maWctPnNiclNpZ25hbGluZz09U0lHX0VYUExJQ0lUX0hJRVJBUkNISUNBTCAmJiBjb25maWctPnNiclByZXNlbnQpIHsKICAgIHdyaXRlU2FtcGxlUmF0ZShhc2MsIGNvbmZpZy0+ZXh0U2FtcGxpbmdSYXRlKTsKICAgIHdyaXRlQW90KGFzYywgY29uZmlnLT5hb3QpOwogIH0KCiAgc3dpdGNoIChjb25maWctPmFvdCkgewojaWZkZWYgVFBfR0FfRU5BQkxFCiAgICBjYXNlIEFPVF9BQUNfTUFJTjoKICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgIGNhc2UgQU9UX0FBQ19TU1I6CiAgICBjYXNlIEFPVF9BQUNfTFRQOgogICAgY2FzZSBBT1RfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9UV0lOX1ZROgogICAgY2FzZSBBT1RfRVJfQUFDX0xDOgogICAgY2FzZSBBT1RfRVJfQUFDX0xUUDoKICAgIGNhc2UgQU9UX0VSX0FBQ19TQ0FMOgogICAgY2FzZSBBT1RfRVJfVFdJTl9WUToKICAgIGNhc2UgQU9UX0VSX0JTQUM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICAgIGVyciA9IHRyYW5zcG9ydEVuY193cml0ZUdBU3BlY2lmaWNDb25maWcoYXNjLCBjb25maWcsIGV4dEZsYWcsIGFsaWduQW5jaG9yKTsKICAgICAgaWYgKGVycikKICAgICAgICByZXR1cm4gZXJyOwogICAgICBicmVhazsKI2VuZGlmIC8qIFRQX0dBX0VOQUJMRSAqLwojaWZkZWYgVFBfRUxEX0VOQUJMRQogICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgZXJyID0gdHJhbnNwb3J0RW5jX3dyaXRlRUxEU3BlY2lmaWNDb25maWcoYXNjLCBjb25maWcsIGVwQ29uZmlnLCBjYik7CiAgICAgIGlmIChlcnIpCiAgICAgICAgcmV0dXJuIGVycjsKICAgICAgYnJlYWs7CiNlbmRpZiAvKiBUUF9FTERfRU5BQkxFICovCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gLTE7CiAgfQoKICBzd2l0Y2ggKGNvbmZpZy0+YW90KSB7CiAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTFRQOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9FUl9UV0lOX1ZROgogICAgY2FzZSBBT1RfRVJfQlNBQzoKICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgIGNhc2UgQU9UX0VSX0NFTFA6CiAgICBjYXNlIEFPVF9FUl9IVlhDOgogICAgY2FzZSBBT1RfRVJfSElMTjoKICAgIGNhc2UgQU9UX0VSX1BBUkE6CiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICBGREt3cml0ZUJpdHMoIGFzYywgMCwgMiApOyAvKiBlcGNvbmZpZyAwICovCiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICAvKiBiYWNrd2FyZCBjb21wYXRpYmxlIGV4cGxpY2l0IHNpZ25hbGluZyBvZiBleHRlbnNpb24gQU9UICovCiAgaWYgKGNvbmZpZy0+c2JyU2lnbmFsaW5nPT1TSUdfRVhQTElDSVRfQldfQ09NUEFUSUJMRSkKICB7CiAgICBUUF9BU0NfRVhURU5TSU9OX0lEIGFzY0V4dElkID0gQVNDRVhUX1VOS09XTjsKCiAgICBpZiAoY29uZmlnLT5zYnJQcmVzZW50KSB7CiAgICAgIGFzY0V4dElkPUFTQ0VYVF9TQlI7CiAgICAgIEZES3dyaXRlQml0cyggYXNjLCBhc2NFeHRJZCwgMTEgKTsKICAgICAgd3JpdGVBb3QoYXNjLCBjb25maWctPmV4dEFPVCk7CiAgICAgIEZES3dyaXRlQml0cyggYXNjLCAxLCAxICk7IC8qIHNiclByZXNlbnRGbGFnPTEgKi8KICAgICAgd3JpdGVTYW1wbGVSYXRlKGFzYywgY29uZmlnLT5leHRTYW1wbGluZ1JhdGUpOwogICAgICBpZiAoY29uZmlnLT5wc1ByZXNlbnQpIHsKICAgICAgICBhc2NFeHRJZD1BU0NFWFRfUFM7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBhc2MsIGFzY0V4dElkLCAxMSApOwogICAgICAgIEZES3dyaXRlQml0cyggYXNjLCAxLCAxICk7IC8qIHBzUHJlc2VudEZsYWc9MSAqLwogICAgICB9CiAgICB9CgogIH0KCiAgLyogTWFrZSBzdXJlIGFsbCBiaXRzIGFyZSBzeW5jJ2VkICovCiAgRkRLc3luY0NhY2hlKCBhc2MgKTsKCiAgcmV0dXJuIDA7Cn0K