Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgRnJlcXVlbmN5IHNjYWxlIGNhbGN1bGF0aW9uICAKKi8KCiNpbmNsdWRlICJzYnJkZWNfZnJlcV9zY2EuaCIKCiNpbmNsdWRlICJ0cmFuc2NlbmRlbnQuaCIKI2luY2x1ZGUgInNicl9yb20uaCIKI2luY2x1ZGUgImVudl9leHRyLmgiCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIgICAgICAvKiBuZWVkIGxvZygpIGZvciBkZWJ1Zy1jb2RlIG9ubHkgKi8KCiNkZWZpbmUgTUFYX09DVEFWRSAgICAgICAgIDI5CiNkZWZpbmUgTUFYX1NFQ09ORF9SRUdJT04gIDUwCgoKc3RhdGljIGludCAgbnVtYmVyT2ZCYW5kcyhGSVhQX1NHTCBicG9fZGl2MTYsIGludCBzdGFydCwgaW50IHN0b3AsIGludCB3YXJwRmxhZyk7CnN0YXRpYyB2b2lkIENhbGNCYW5kcyhVQ0hBUiAqIGRpZmYsIFVDSEFSIHN0YXJ0LCBVQ0hBUiBzdG9wLCBVQ0hBUiBudW1fYmFuZHMpOwpzdGF0aWMgU0JSX0VSUk9SIG1vZGlmeUJhbmRzKFVDSEFSIG1heF9iYW5kLCBVQ0hBUiAqIGRpZmYsIFVDSEFSIGxlbmd0aCk7CnN0YXRpYyB2b2lkIGN1bVN1bShVQ0hBUiBzdGFydF92YWx1ZSwgVUNIQVIqIGRpZmYsIFVDSEFSIGxlbmd0aCwgVUNIQVIgKnN0YXJ0X2FkcmVzcyk7CgoKCi8qIQogIFxicmllZiAgICAgUmV0cmlldmUgUU1GLWJhbmQgd2hlcmUgdGhlIFNCUiByYW5nZSBzdGFydHMKCiAgQ29udmVydCBzdGFydEZyZXEgd2hpY2ggd2FzIHJlYWQgZnJvbSB0aGUgYml0c3RyZWFtIGludG8gYQogIFFNRi1jaGFubmVsIG51bWJlci4KCiAgXHJldHVybiAgTnVtYmVyIG9mIHN0YXJ0IGJhbmQKKi8Kc3RhdGljIFVDSEFSCmdldFN0YXJ0QmFuZChVSU5UICAgZnMsICAgICAgICAgICAgICAgLyohPCBPdXRwdXQgc2FtcGxpbmcgZnJlcXVlbmN5ICovCiAgICAgICAgICAgICBVQ0hBUiAgc3RhcnRGcmVxLCAgICAgICAgLyohPCBJbmRleCB0byB0YWJsZSBvZiBwb3NzaWJsZSBzdGFydCBiYW5kcyAqLwogICAgICAgICAgICAgVUlOVCAgIGhlYWRlckRhdGFGbGFncykgIC8qITwgSW5mbyB0byBTQlIgbW9kZSAqLwp7CiAgSU5UICBiYW5kOwogIFVJTlQgZnNNYXBwZWQ7CgogICAgZnNNYXBwZWQgPSBmczsKCiAgc3dpdGNoIChmc01hcHBlZCkgewogICAgY2FzZSA0ODAwMDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzQ4W3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgY2FzZSA0NDEwMDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzQ0W3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgY2FzZSAzMjAwMDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzMyW3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgY2FzZSAyNDAwMDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzI0W3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgY2FzZSAyMjA1MDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzIyW3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgY2FzZSAxNjAwMDoKICAgICAgYmFuZCA9IEZES19zYnJEZWNvZGVyX3Nicl9zdGFydF9mcmVxXzE2W3N0YXJ0RnJlcV07CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYmFuZCA9IDI1NTsKICB9CgogIHJldHVybiBiYW5kOwp9CgoKLyohCiAgXGJyaWVmICAgICBSZXRyaWV2ZSBRTUYtYmFuZCB3aGVyZSB0aGUgU0JSIHJhbmdlIHN0YXJ0cwoKICBDb252ZXJ0IHN0YXJ0RnJlcSB3aGljaCB3YXMgcmVhZCBmcm9tIHRoZSBiaXRzdHJlYW0gaW50byBhCiAgUU1GLWNoYW5uZWwgbnVtYmVyLgoKICBccmV0dXJuICBOdW1iZXIgb2Ygc3RhcnQgYmFuZAoqLwpzdGF0aWMgVUNIQVIKZ2V0U3RvcEJhbmQoVUlOVCAgIGZzLCAgICAgICAgICAgICAgIC8qITwgT3V0cHV0IHNhbXBsaW5nIGZyZXF1ZW5jeSAqLwogICAgICAgICAgICBVQ0hBUiAgc3RvcEZyZXEsICAgICAgICAgLyohPCBJbmRleCB0byB0YWJsZSBvZiBwb3NzaWJsZSBzdGFydCBiYW5kcyAqLwogICAgICAgICAgICBVSU5UICAgaGVhZGVyRGF0YUZsYWdzLCAgLyohPCBJbmZvIHRvIFNCUiBtb2RlICovCiAgICAgICAgICAgIFVDSEFSICBrMCkgICAgICAgICAgICAgICAvKiE8IFN0YXJ0IGZyZXEgaW5kZXggKi8KewogIFVDSEFSIGsyOwoKICBpZiAoc3RvcEZyZXEgPCAxNCkgewogICAgSU5UICAgIHN0b3BNaW47CiAgICBVQ0hBUiAgZGlmZl90b3RbTUFYX09DVEFWRSArIE1BWF9TRUNPTkRfUkVHSU9OXTsKICAgIFVDSEFSICpkaWZmMCA9IGRpZmZfdG90OwogICAgVUNIQVIgKmRpZmYxID0gZGlmZl90b3QrTUFYX09DVEFWRTsKCiAgICBpZiAoZnMgPCAzMjAwMCkgewogICAgICBzdG9wTWluID0gKCgoMio2MDAwKjIqKDY0KSkgLyBmcykgKyAxKSA+PiAxOwogICAgfQogICAgZWxzZSB7CiAgICAgIGlmIChmcyA8IDY0MDAwKSB7CiAgICAgICAgc3RvcE1pbiA9ICgoKDIqODAwMCoyKig2NCkpIC8gZnMpICsgMSkgPj4gMTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBzdG9wTWluID0gKCgoMioxMDAwMCoyKig2NCkpIC8gZnMpICsgMSkgPj4gMTsKICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgIENob29zZSBhIHN0b3AgYmFuZCBiZXR3ZWVuIGsxIGFuZCA2NCBkZXBlbmRpbmcgb24gc3RvcEZyZXEgKDAuLjEzKSwKICAgICAgYmFzZWQgb24gYSBsb2dhcml0aG1pYyBzY2FsZS4KICAgICAgVGhlIHZlY3RvcnMgZGlmZjAgYW5kIGRpZmYxIGFyZSB1c2VkIHRlbXBvcmFyaWx5IGhlcmUuCiAgICAqLwogICAgQ2FsY0JhbmRzKCBkaWZmMCwgc3RvcE1pbiwgNjQsIDEzKTsKICAgIHNoZWxsc29ydCggZGlmZjAsIDEzKTsKICAgIGN1bVN1bShzdG9wTWluLCBkaWZmMCwgMTMsIGRpZmYxKTsKICAgIGsyID0gZGlmZjFbc3RvcEZyZXFdOwogIH0KICBlbHNlIGlmIChzdG9wRnJlcT09MTQpCiAgICBrMiA9IDIqazA7CiAgZWxzZQogICAgazIgPSAzKmswOwoKICAvKiBMaW1pdCB0byBOeXF1aXN0ICovCiAgaWYgKGsyID4gKDY0KSkKICAgIGsyID0gKDY0KTsKCgogIC8qIFJhbmdlIGNoZWNrcyAqLwogIC8qIDEgPD0gZGlmZmVyZW5jZSA8PSA0ODsgMSA8PSBmcyA8PSA5NjAwMCAqLwogIGlmICggKChrMiAtIGswKSA+IE1BWF9GUkVRX0NPRUZGUykgfHwgKGsyIDw9IGswKSApIHsKICAgIHJldHVybiAyNTU7CiAgfQoKICBpZiAoaGVhZGVyRGF0YUZsYWdzICYgKFNCUkRFQ19TWU5UQVhfVVNBQ3xTQlJERUNfU1lOVEFYX1JTVkQ1MCkpIHsKICAgIC8qIDEgPD0gZGlmZmVyZW5jZSA8PSAzNTsgNDIwMDAgPD0gZnMgPD0gOTYwMDAgKi8KICAgIGlmICggKGZzID49IDQyMDAwKSAmJiAoIChrMiAtIGswKSA+IE1BWF9GUkVRX0NPRUZGU19GUzQ0MTAwICkgKSB7CiAgICAgIHJldHVybiAyNTU7CiAgICB9CiAgICAvKiAxIDw9IGRpZmZlcmVuY2UgPD0gMzI7IDQ2MDA5IDw9IGZzIDw9IDk2MDAwICovCiAgICBpZiAoIChmcyA+PSA0NjAwOSkgJiYgKCAoazIgLSBrMCkgPiBNQVhfRlJFUV9DT0VGRlNfRlM0ODAwMCApICkgewogICAgICByZXR1cm4gMjU1OwogICAgfQogIH0KICBlbHNlIHsKICAgIC8qIDEgPD0gZGlmZmVyZW5jZSA8PSAzNTsgZnMgPT0gNDQxMDAgKi8KICAgIGlmICggKGZzID09IDQ0MTAwKSAmJiAoIChrMiAtIGswKSA+IE1BWF9GUkVRX0NPRUZGU19GUzQ0MTAwICkgKSB7CiAgICAgIHJldHVybiAyNTU7CiAgICB9CiAgICAvKiAxIDw9IGRpZmZlcmVuY2UgPD0gMzI7IDQ4MDAwIDw9IGZzIDw9IDk2MDAwICovCiAgICBpZiAoIChmcyA+PSA0ODAwMCkgJiYgKCAoazIgLSBrMCkgPiBNQVhfRlJFUV9DT0VGRlNfRlM0ODAwMCApICkgewogICAgICByZXR1cm4gMjU1OwogICAgfQogIH0KCiAgcmV0dXJuIGsyOwp9CgoKLyohCiAgXGJyaWVmICAgICBHZW5lcmF0ZXMgbWFzdGVyIGZyZXF1ZW5jeSB0YWJsZXMKCiAgRnJlcXVlbmN5IHRhYmxlcyBhcmUgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG8gdGhlIHNlbGVjdGVkIGRvbWFpbgogIChsaW5lYXIvbG9nYXJpdGhtaWMpIGFuZCBncmFudWxhcml0eS4KICBJRUMgMTQ0OTYtMyA0LjYuMTguMy4yLjEKCiAgXHJldHVybiAgZXJyb3JDb2RlLCAwIGlmIHN1Y2Nlc3NmdWwKKi8KU0JSX0VSUk9SCnNicmRlY1VwZGF0ZUZyZXFTY2FsZShVQ0hBUiAqIHZfa19tYXN0ZXIsICAgIC8qITwgTWFzdGVyIHRhYmxlIHRvIGJlIGNyZWF0ZWQgKi8KICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICpudW1NYXN0ZXIsICAgICAgLyohPCBOdW1iZXIgb2YgZW50cmllcyBpbiBtYXN0ZXIgdGFibGUgKi8KICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICBmcywgICAgICAgICAgICAgLyohPCBTQlIgd29ya2luZyBzYW1wbGluZyByYXRlICovCiAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAvKiE8IENvbnRyb2wgZGF0YSBmcm9tIGJpdHN0cmVhbSAqLwogICAgICAgICAgICAgICAgICAgICAgVUlOVCBmbGFncykKewogIEZJWFBfU0dMIGJwb19kaXYxNjsgICAgICAgIC8qIGJhbmRzX3Blcl9vY3RhdmUgZGl2aWRlZCBieSAxNiAqLwogIElOVCAgICAgIGRrPTA7CgogIC8qIEludGVybmFsIHZhcmlhYmxlcyAqLwogIFVDSEFSICBrMCwgazIsIGk7CiAgVUNIQVIgIG51bV9iYW5kczAgPSAwOwogIFVDSEFSICBudW1fYmFuZHMxID0gMDsKICBVQ0hBUiAgZGlmZl90b3RbTUFYX09DVEFWRSArIE1BWF9TRUNPTkRfUkVHSU9OXTsKICBVQ0hBUiAqZGlmZjAgPSBkaWZmX3RvdDsKICBVQ0hBUiAqZGlmZjEgPSBkaWZmX3RvdCtNQVhfT0NUQVZFOwogIElOVCAgICBrMl9hY2hpdmVkOwogIElOVCAgICBrMl9kaWZmOwogIElOVCAgICBpbmNyPTA7CgogIC8qCiAgICBEZXRlcm1pbmUgc3RhcnQgYmFuZAogICovCiAgazAgPSBnZXRTdGFydEJhbmQoZnMsIGhIZWFkZXJEYXRhLT5ic19kYXRhLnN0YXJ0RnJlcSwgZmxhZ3MpOwogIGlmIChrMCA9PSAyNTUpIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgLyoKICAgIERldGVybWluZSBzdG9wIGJhbmQKICAqLwogIGsyID0gZ2V0U3RvcEJhbmQoZnMsIGhIZWFkZXJEYXRhLT5ic19kYXRhLnN0b3BGcmVxLCBmbGFncywgazApOwogIGlmIChrMiA9PSAyNTUpIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgaWYoaEhlYWRlckRhdGEtPmJzX2RhdGEuZnJlcVNjYWxlPjApIHsgLyogQmFyayAqLwogICAgSU5UIGsxOwoKICAgIGlmKGhIZWFkZXJEYXRhLT5ic19kYXRhLmZyZXFTY2FsZT09MSkgewogICAgICBicG9fZGl2MTYgPSBGTDJGWENPTlNUX1NHTCgxMi4wZi8xNi4wZik7CiAgICB9CiAgICBlbHNlIGlmKGhIZWFkZXJEYXRhLT5ic19kYXRhLmZyZXFTY2FsZT09MikgewogICAgICBicG9fZGl2MTYgPSBGTDJGWENPTlNUX1NHTCgxMC4wZi8xNi4wZik7CiAgICB9CiAgICBlbHNlIHsKICAgICAgYnBvX2RpdjE2ID0gIEZMMkZYQ09OU1RfU0dMKDguMGYvMTYuMGYpOwogICAgfQoKCiAgICBpZiggMTAwMCAqIGsyID4gMjI0NSAqIGswICkgeyAvKiBUd28gb3IgbW9yZSByZWdpb25zICovCiAgICAgIGsxID0gMiprMDsKCiAgICAgIG51bV9iYW5kczAgPSBudW1iZXJPZkJhbmRzKGJwb19kaXYxNiwgazAsIGsxLCAwKTsKICAgICAgbnVtX2JhbmRzMSA9IG51bWJlck9mQmFuZHMoYnBvX2RpdjE2LCBrMSwgazIsIGhIZWFkZXJEYXRhLT5ic19kYXRhLmFsdGVyU2NhbGUgKTsKICAgICAgaWYgKCBudW1fYmFuZHMwIDwgMSkgewogICAgICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgICB9CiAgICAgIGlmICggbnVtX2JhbmRzMSA8IDEgKSB7CiAgICAgICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICAgIH0KCiAgICAgIENhbGNCYW5kcyhkaWZmMCwgazAsIGsxLCBudW1fYmFuZHMwKTsKICAgICAgc2hlbGxzb3J0KCBkaWZmMCwgbnVtX2JhbmRzMCk7CiAgICAgIGlmIChkaWZmMFswXSA9PSAwKSB7CiNpZmRlZiBERUJVR19UT09MUwojZW5kaWYKICAgICAgICByZXR1cm4gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgICAgfQoKICAgICAgY3VtU3VtKGswLCBkaWZmMCwgbnVtX2JhbmRzMCwgdl9rX21hc3Rlcik7CgogICAgICBDYWxjQmFuZHMoZGlmZjEsIGsxLCBrMiwgbnVtX2JhbmRzMSk7CiAgICAgIHNoZWxsc29ydCggZGlmZjEsIG51bV9iYW5kczEpOwogICAgICBpZihkaWZmMFtudW1fYmFuZHMwLTFdID4gZGlmZjFbMF0pIHsKICAgICAgICBTQlJfRVJST1IgZXJyOwoKICAgICAgICBlcnIgPSBtb2RpZnlCYW5kcyhkaWZmMFtudW1fYmFuZHMwLTFdLGRpZmYxLCBudW1fYmFuZHMxKTsKICAgICAgICBpZiAoZXJyKQogICAgICAgICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICAgIH0KCiAgICAgIC8qIEFkZCAybmQgcmVnaW9uICovCiAgICAgIGN1bVN1bShrMSwgZGlmZjEsIG51bV9iYW5kczEsICZ2X2tfbWFzdGVyW251bV9iYW5kczBdKTsKICAgICAgKm51bU1hc3RlciA9IG51bV9iYW5kczAgKyBudW1fYmFuZHMxOyAgICAgLyogT3V0cHV0IG5yIG9mIGJhbmRzICovCgogICAgfQogICAgZWxzZSB7IC8qIE9ubHkgb25lIHJlZ2lvbiAqLwogICAgICBrMT1rMjsKCiAgICAgIG51bV9iYW5kczAgPSBudW1iZXJPZkJhbmRzKGJwb19kaXYxNiwgazAsIGsxLCAwKTsKICAgICAgaWYgKCBudW1fYmFuZHMwIDwgMSkgewogICAgICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgICB9CiAgICAgIENhbGNCYW5kcyhkaWZmMCwgazAsIGsxLCBudW1fYmFuZHMwKTsKICAgICAgc2hlbGxzb3J0KGRpZmYwLCBudW1fYmFuZHMwKTsKICAgICAgaWYgKGRpZmYwWzBdID09IDApIHsKI2lmZGVmIERFQlVHX1RPT0xTCiNlbmRpZgogICAgICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogICAgICB9CgogICAgICBjdW1TdW0oazAsIGRpZmYwLCBudW1fYmFuZHMwLCB2X2tfbWFzdGVyKTsKICAgICAgKm51bU1hc3RlciA9IG51bV9iYW5kczA7ICAgICAgICAvKiBPdXRwdXQgbnIgb2YgYmFuZHMgKi8KCiAgICB9CiAgfQogIGVsc2UgeyAvKiBMaW5lYXIgbW9kZSAqLwogICAgIGlmIChoSGVhZGVyRGF0YS0+YnNfZGF0YS5hbHRlclNjYWxlPT0wKSB7CiAgICAgICAgZGsgPSAxOwogICAgICAgIC8qIEZMT09SIHRvIGdldCB0byBmZXcgbnVtYmVyIG9mIGJhbmRzIChuZXh0IGxvd2VyIGV2ZW4gbnVtYmVyKSAqLwogICAgICAgIG51bV9iYW5kczAgPSAoazIgLSBrMCkgJiAyNTQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGsgPSAyOwogICAgICAgIG51bV9iYW5kczAgPSAoICgoazIgLSBrMCkgPj4gMSkgKyAxICkgJiAyNTQ7IC8qIFJPVU5EIHRvIHRoZSBjbG9zZXN0IGZpdCAqLwogICAgICB9CgogICAgICBpZiAobnVtX2JhbmRzMCA8IDEpIHsKICAgICAgICByZXR1cm4gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgICAgICAvKiBXZSBtdXN0IHJldHVybiBhbHJlYWR5IGhlcmUgYmVjYXVzZSAnaScgY2FuIGJlY29tZSBuZWdhdGl2ZSBiZWxvdy4gKi8KICAgICAgfQoKICAgICAgazJfYWNoaXZlZCA9IGswICsgbnVtX2JhbmRzMCpkazsKICAgICAgazJfZGlmZiA9IGsyIC0gazJfYWNoaXZlZDsKCiAgICAgIGZvcihpPTA7aTxudW1fYmFuZHMwO2krKykKICAgICAgICBkaWZmX3RvdFtpXSA9IGRrOwoKICAgICAgLyogSWYgbGluZWFyIHNjYWxlIHdhc24ndCBhY2hpZXZlZCAqLwogICAgICAvKiBhbmQgd2UgZ290IHRvbyB3aWRlIFNCUiBhcmVhICovCiAgICAgIGlmIChrMl9kaWZmIDwgMCkgewogICAgICAgICAgaW5jciA9IDE7CiAgICAgICAgICBpID0gMDsKICAgICAgfQoKICAgICAgLyogSWYgbGluZWFyIHNjYWxlIHdhc24ndCBhY2hpZXZlZCAqLwogICAgICAvKiBhbmQgd2UgZ290IHRvbyBzbWFsbCBTQlIgYXJlYSAqLwogICAgICBpZiAoazJfZGlmZiA+IDApIHsKICAgICAgICAgIGluY3IgPSAtMTsKICAgICAgICAgIGkgPSBudW1fYmFuZHMwLTE7CiAgICAgIH0KCiAgICAgIC8qIEFkanVzdCBkaWZmIHZlY3RvciB0byBnZXQgc2VwYy4gU0JSIHJhbmdlICovCiAgICAgIHdoaWxlIChrMl9kaWZmICE9IDApIHsKICAgICAgICBkaWZmX3RvdFtpXSA9IGRpZmZfdG90W2ldIC0gaW5jcjsKICAgICAgICBpID0gaSArIGluY3I7CiAgICAgICAgazJfZGlmZiA9IGsyX2RpZmYgKyBpbmNyOwogICAgICB9CgogICAgICBjdW1TdW0oazAsIGRpZmZfdG90LCBudW1fYmFuZHMwLCB2X2tfbWFzdGVyKTsvKiBjdW1zdW0gKi8KICAgICpudW1NYXN0ZXIgPSBudW1fYmFuZHMwOyAgLyogT3V0cHV0IG5yIG9mIGJhbmRzICovCiAgfQoKICBpZiAoKm51bU1hc3RlciA8IDEpIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCgogIC8qCiAgICBQcmludCBvdXQgdGhlIGNhbGN1bGF0ZWQgdGFibGUKICAqLwoKICByZXR1cm4gU0JSREVDX09LOwp9CgoKLyohCiAgXGJyaWVmICAgICBDYWxjdWxhdGUgZnJlcXVlbmN5IHJhdGlvIG9mIG9uZSBTQlIgYmFuZAoKICBBbGwgU0JSIGJhbmRzIHNob3VsZCBzcGFuIGEgY29uc3RhbnQgZnJlcXVlbmN5IHJhbmdlIGluIHRoZSBsb2dhcml0aG1pYwogIGRvbWFpbi4gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIHRoZSByYXRpbyBvZiBhbnkgU0JSIGJhbmQncyB1cHBlciBhbmQgbG93ZXIKICBmcmVxdWVuY3kuCgogXHJldHVybiAgICBudW1fYmFuZC10aCByb290IG9mIGtfc3RhcnQva19zdG9wCiovCnN0YXRpYyBGSVhQX1NHTCBjYWxjRmFjdG9yUGVyQmFuZChpbnQga19zdGFydCwgaW50IGtfc3RvcCwgaW50IG51bV9iYW5kcykKewovKiBTY2FsZWQgYmFuZGZhY3RvciBhbmQgc3RlcCAxIGJpdCByaWdodCB0byBhdm9pZCBvdmVyZmxvdwogKiB1c2UgZG91YmxlIGRhdGEgdHlwZSAqLwogIEZJWFBfREJMIGJhbmRmYWN0b3IgPSBGTDJGWENPTlNUX0RCTCgwLjI1Zik7IC8qIFN0YXJ0IHZhbHVlICovCiAgRklYUF9EQkwgc3RlcCA9IEZMMkZYQ09OU1RfREJMKDAuMTI1Zik7ICAgICAgLyogSW5pdGlhbCBpbmNyZW1lbnQgZm9yIGZhY3RvciAqLwoKICBpbnQgICAgZGlyZWN0aW9uID0gMTsKCi8qIEJlY2F1c2Ugc2F0dXJhdGlvbiBjYW4ndCBiZSBkb25lIGluIElOVCBJSVMsCiAqIGNoYW5nZWQgc3RhcnQgYW5kIHN0b3AgZGF0YSB0eXBlIGZyb20gRklYUF9TR0wgdG8gRklYUF9EQkwgKi8KICBGSVhQX0RCTCBzdGFydCA9IGtfc3RhcnQgPDwgKERGUkFDVF9CSVRTLTgpOwogIEZJWFBfREJMIHN0b3AgPSBrX3N0b3AgPDwgKERGUkFDVF9CSVRTLTgpOwoKICBGSVhQX0RCTCB0ZW1wOwoKICBpbnQgICBqLCBpPTA7CgogIHdoaWxlICggc3RlcCA+IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CiAgICBpKys7CiAgICB0ZW1wID0gc3RvcDsKCiAgICAvKiBDYWxjdWxhdGUgdGVtcF5udW1fYmFuZHM6ICovCiAgICBmb3IgKGo9MDsgajxudW1fYmFuZHM7IGorKykKICAgICAgLy90ZW1wID0gZk11bHQodGVtcCxiYW5kZmFjdG9yKTsKICAgICAgdGVtcCA9IGZNdWx0RGl2Mih0ZW1wLGJhbmRmYWN0b3IpPDwyOwoKICAgIGlmICh0ZW1wPHN0YXJ0KSB7IC8qIEZhY3RvciB0b28gc3Ryb25nLCBtYWtlIGl0IHdlYWtlciAqLwogICAgICBpZiAoZGlyZWN0aW9uID09IDApCiAgICAgICAgLyogSGFsZmVuIHN0ZXAuIFJpZ2h0IHNoaWZ0IGlzIG5vdCBkb25lIGFzIGZyYWN0IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZQogICAgICAgICAgIGxvd2VzdCBiaXQgY2Fubm90IGJlIGNsZWFyZWQgZHVlIHRvIHJvdW5kaW5nICovCiAgICAgICAgc3RlcCA9IChGSVhQX0RCTCkoKExPTkcpc3RlcCA+PiAxKTsKICAgICAgZGlyZWN0aW9uID0gMTsKICAgICAgYmFuZGZhY3RvciA9IGJhbmRmYWN0b3IgKyBzdGVwOwogICAgfQogICAgZWxzZSB7ICAvKiBGYWN0b3IgaXMgdG9vIHdlYWs6IG1ha2UgaXQgc3Ryb25nZXIgKi8KICAgICAgaWYgKGRpcmVjdGlvbiA9PSAxKQogICAgICAgIHN0ZXAgPSAoRklYUF9EQkwpKChMT05HKXN0ZXAgPj4gMSk7CiAgICAgIGRpcmVjdGlvbiA9IDA7CiAgICAgIGJhbmRmYWN0b3IgPSBiYW5kZmFjdG9yIC0gc3RlcDsKICAgIH0KCiAgICBpZiAoaT4xMDApIHsKICAgICAgc3RlcCA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgfQogIH0KICByZXR1cm4gRlhfREJMMkZYX1NHTChiYW5kZmFjdG9yPDwxKTsKfQoKCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlIG51bWJlciBvZiBTQlIgYmFuZHMgYmV0d2VlbiBzdGFydCBhbmQgc3RvcCBiYW5kCgogIEdpdmVuIHRoZSBudW1iZXIgb2YgYmFuZHMgcGVyIG9jdGF2ZSwgdGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIGhvdyBtYW55CiAgYmFuZHMgZml0IGluIHRoZSBnaXZlbiBmcmVxdWVuY3kgcmFuZ2UuCiAgV2hlbiB0aGUgd2FycEZsYWcgaXMgc2V0LCB0aGUgJ2JhbmQgZGVuc2l0eScgaXMgZGVjcmVhc2VkIGJ5IGEgZmFjdG9yCiAgb2YgMS8xLjMKCiAgXHJldHVybiAgICBudW1iZXIgb2YgYmFuZHMKKi8Kc3RhdGljIGludApudW1iZXJPZkJhbmRzKEZJWFBfU0dMIGJwb19kaXYxNiwgLyohPCBJbnB1dDogbnVtYmVyIG9mIGJhbmRzIHBlciBvY3RhdmUgZGl2aWRlZCBieSAxNiAqLwogICAgICAgICAgICAgIGludCAgICBzdGFydCwgICAgIC8qITwgRmlyc3QgUU1GIGJhbmQgb2YgU0JSIGZyZXF1ZW5jeSByYW5nZSAqLwogICAgICAgICAgICAgIGludCAgICBzdG9wLCAgICAgIC8qITwgTGFzdCBRTUYgYmFuZCBvZiBTQlIgZnJlcXVlbmN5IHJhbmdlICsgMSAqLwogICAgICAgICAgICAgIGludCAgICB3YXJwRmxhZykgIC8qITwgU3RyZXRjaGluZyBmbGFnICovCnsKICBGSVhQX1NHTCBudW1fYmFuZHNfZGl2MTI4OwogIGludCAgICBudW1fYmFuZHM7CgogIG51bV9iYW5kc19kaXYxMjggPSBGWF9EQkwyRlhfU0dMKGZNdWx0KEZES19nZXROdW1PY3RhdmVzRGl2OChzdGFydCxzdG9wKSxicG9fZGl2MTYpKTsKCiAgaWYgKHdhcnBGbGFnKSB7CiAgICAvKiBBcHBseSB0aGUgd2FycCBmYWN0b3Igb2YgMS4zIHRvIGdldCB3aWRlciBiYW5kcy4gIFdlIHVzZSBhIHZhbHVlCiAgICAgICBvZiAzMjc2OC8yNTIwMCBpbnN0ZWFkIG9mIHRoZSBleGFjdCB2YWx1ZSB0byBhdm9pZCBjcml0aWNhbCBjYXNlcwogICAgICAgb2Ygcm91bmRpbmcuCiAgICAqLwogICAgbnVtX2JhbmRzX2RpdjEyOCA9IEZYX0RCTDJGWF9TR0woZk11bHQobnVtX2JhbmRzX2RpdjEyOCwgRkwyRlhDT05TVF9TR0woMjUyMDAuMC8zMjc2OC4wKSkpOwogIH0KCiAgLyogYWRkIHNjYWxlZCAxIGZvciByb3VuZGluZyB0byBldmVuIG51bWJlcnM6ICovCiAgbnVtX2JhbmRzX2RpdjEyOCA9IG51bV9iYW5kc19kaXYxMjggKyBGTDJGWENPTlNUX1NHTCggMS4wZi8xMjguMGYgKTsKICAvKiBzY2FsZSBiYWNrIHRvIHJpZ2h0IGFsaWduZWQgaW50ZWdlciBhbmQgZG91YmxlIHRoZSB2YWx1ZTogKi8KICBudW1fYmFuZHMgPSAyICogKChMT05HKW51bV9iYW5kc19kaXYxMjggPj4gKEZSQUNUX0JJVFMgLSA3KSk7CgogIHJldHVybihudW1fYmFuZHMpOwp9CgoKLyohCiAgXGJyaWVmICAgICBDYWxjdWxhdGUgd2lkdGggb2YgU0JSIGJhbmRzCgogIEdpdmVuIHRoZSBkZXNpcmVkIG51bWJlciBvZiBiYW5kcyB3aXRoaW4gdGhlIFNCUiBmcmVxdWVuY3kgcmFuZ2UsCiAgdGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIHRoZSB3aWR0aCBvZiBlYWNoIFNCUiBiYW5kIGluIFFNRiBjaGFubmVscy4KICBUaGUgYmFuZHMgZ2V0IHdpZGVyIGZyb20gc3RhcnQgdG8gc3RvcCAoYmFyayBzY2FsZSkuCiovCnN0YXRpYyB2b2lkCkNhbGNCYW5kcyhVQ0hBUiAqIGRpZmYsICAgIC8qITwgVmVjdG9yIG9mIHdpZHRocyB0byBiZSBjYWxjdWxhdGVkICovCiAgICAgICAgICBVQ0hBUiBzdGFydCwgICAgIC8qITwgTG93ZXIgZW5kIG9mIHN1YmJhbmQgcmFuZ2UgKi8KICAgICAgICAgIFVDSEFSIHN0b3AsICAgICAgLyohPCBVcHBlciBlbmQgb2Ygc3ViYmFuZCByYW5nZSAqLwogICAgICAgICAgVUNIQVIgbnVtX2JhbmRzKSAvKiE8IERlc2lyZWQgbnVtYmVyIG9mIGJhbmRzICovCnsKICBpbnQgaTsKICBpbnQgcHJldmlvdXM7CiAgaW50IGN1cnJlbnQ7CiAgRklYUF9TR0wgZXhhY3QsIHRlbXA7CiAgRklYUF9TR0wgYmFuZGZhY3RvciA9IGNhbGNGYWN0b3JQZXJCYW5kKHN0YXJ0LCBzdG9wLCBudW1fYmFuZHMpOwoKICBwcmV2aW91cyA9IHN0b3A7IC8qIFN0YXJ0IHdpdGggaGlnaGVzdCBRTUYgY2hhbm5lbCAqLwogIGV4YWN0ID0gKEZJWFBfU0dMKShzdG9wIDw8IChGUkFDVF9CSVRTLTgpKTsgLyogU2hpZnQgbGVmdCB0byBnYWluIHNvbWUgYWNjdXJhY3kgKi8KCiAgZm9yKGk9bnVtX2JhbmRzLTE7IGk+PTA7IGktLSkgewogICAgLyogQ2FsY3VsYXRlIGJvcmRlciBvZiBuZXh0IGxvd2VyIHNiciBiYW5kICovCiAgICBleGFjdCA9IEZYX0RCTDJGWF9TR0woZk11bHQoZXhhY3QsYmFuZGZhY3RvcikpOwoKICAgIC8qIEFkZCBzY2FsZWQgMC41IGZvciByb3VuZGluZzoKICAgICAgIFdlIHVzZSBhIHZhbHVlIDEyOC8yNTYgaW5zdGVhZCBvZiAwLjUgdG8gYXZvaWQgc29tZSBjcml0aWNhbCBjYXNlcyBvZiByb3VuZGluZy4gKi8KICAgIHRlbXAgPSBleGFjdCArICBGTDJGWENPTlNUX1NHTCgxMjguMC8zMjc2OC4wKTsKCiAgICAvKiBzY2FsZSBiYWNrIHRvIHJpZ2h0IGFsaW5nZWQgaW50ZWdlcjogKi8KICAgIGN1cnJlbnQgPSAoTE9ORyl0ZW1wID4+IChGUkFDVF9CSVRTLTgpOwoKICAgIC8qIFNhdmUgd2lkdGggb2YgYmFuZCBpICovCiAgICBkaWZmW2ldID0gcHJldmlvdXMgLSBjdXJyZW50OwogICAgcHJldmlvdXMgPSBjdXJyZW50OwogIH0KfQoKCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlIGN1bXVsYXRlZCBzdW0gdmVjdG9yIGZyb20gZGVsdGEgdmVjdG9yCiovCnN0YXRpYyB2b2lkCmN1bVN1bShVQ0hBUiBzdGFydF92YWx1ZSwgVUNIQVIqIGRpZmYsIFVDSEFSIGxlbmd0aCwgVUNIQVIgKnN0YXJ0X2FkcmVzcykKewogIGludCBpOwogIHN0YXJ0X2FkcmVzc1swXT1zdGFydF92YWx1ZTsKICBmb3IoaT0xOyBpPD1sZW5ndGg7IGkrKykKICAgIHN0YXJ0X2FkcmVzc1tpXSA9IHN0YXJ0X2FkcmVzc1tpLTFdICsgZGlmZltpLTFdOwp9CgoKLyohCiAgXGJyaWVmICAgICBBZGFwdCB3aWR0aCBvZiBmcmVxdWVuY3kgYmFuZHMgaW4gdGhlIHNlY29uZCByZWdpb24KCiAgSWYgU0JSIHNwYW5zIG1vcmUgdGhhbiAyIG9jdGF2ZXMsIHRoZSB1cHBlciBwYXJ0IG9mIGEgYmFyay1mcmVxdWVuY3ktc2NhbGUKICBpcyBjYWxjdWxhdGVkIHNlcGFyYXRlbHkuIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gYXZvaWQgdGhhdCB0aGUgc2Vjb25kIHJlZ2lvbgogIHN0YXJ0cyB3aXRoIGEgYmFuZCBzbWFsbGVyIHRoYW4gdGhlIGhpZ2hlc3QgYmFuZCBvZiB0aGUgZmlyc3QgcmVnaW9uLgoqLwpzdGF0aWMgU0JSX0VSUk9SCm1vZGlmeUJhbmRzKFVDSEFSIG1heF9iYW5kX3ByZXZpb3VzLCBVQ0hBUiAqIGRpZmYsIFVDSEFSIGxlbmd0aCkKewogIGludCBjaGFuZ2UgPSBtYXhfYmFuZF9wcmV2aW91cyAtIGRpZmZbMF07CgogIC8qIExpbWl0IHRoZSBjaGFuZ2Ugc28gdGhhdCB0aGUgbGFzdCBiYW5kIGNhbm5vdCBnZXQgbmFycm93ZXIgdGhhbiB0aGUgZmlyc3Qgb25lICovCiAgaWYgKCBjaGFuZ2UgPiAoZGlmZltsZW5ndGgtMV0tZGlmZlswXSk+PjEgKQogICAgY2hhbmdlID0gKGRpZmZbbGVuZ3RoLTFdLWRpZmZbMF0pPj4xOwoKICBkaWZmWzBdICs9IGNoYW5nZTsKICBkaWZmW2xlbmd0aC0xXSAtPSBjaGFuZ2U7CiAgc2hlbGxzb3J0KGRpZmYsIGxlbmd0aCk7CgogIHJldHVybiBTQlJERUNfT0s7Cn0KCgovKiEKICBcYnJpZWYgICBVcGRhdGUgaGlnaCByZXNvbHV0aW9uIGZyZXF1ZW5jeSBiYW5kIHRhYmxlCiovCnN0YXRpYyB2b2lkCnNicmRlY1VwZGF0ZUhpUmVzKFVDSEFSICogaF9oaXJlcywKICAgICAgICAgICAgICAgICAgVUNIQVIgKiBudW1faGlyZXMsCiAgICAgICAgICAgICAgICAgIFVDSEFSICogdl9rX21hc3RlciwKICAgICAgICAgICAgICAgICAgVUNIQVIgbnVtX2JhbmRzLAogICAgICAgICAgICAgICAgICBVQ0hBUiB4b3Zlcl9iYW5kKQp7CiAgVUNIQVIgaTsKCiAgKm51bV9oaXJlcyA9IG51bV9iYW5kcy14b3Zlcl9iYW5kOwoKICBmb3IoaT14b3Zlcl9iYW5kOyBpPD1udW1fYmFuZHM7IGkrKykgewogICAgaF9oaXJlc1tpLXhvdmVyX2JhbmRdID0gdl9rX21hc3RlcltpXTsKICB9Cn0KCgovKiEKICBcYnJpZWYgIEJ1aWxkIGxvdyByZXNvbHV0aW9uIHRhYmxlIG91dCBvZiBoaWdoIHJlc29sdXRpb24gdGFibGUKKi8Kc3RhdGljIHZvaWQKc2JyZGVjVXBkYXRlTG9SZXMoVUNIQVIgKiBoX2xvcmVzLAogICAgICAgICAgICAgICAgICBVQ0hBUiAqIG51bV9sb3JlcywKICAgICAgICAgICAgICAgICAgVUNIQVIgKiBoX2hpcmVzLAogICAgICAgICAgICAgICAgICBVQ0hBUiBudW1faGlyZXMpCnsKICBVQ0hBUiBpOwoKICBpZiggKG51bV9oaXJlcyAmIDEpID09IDApIHsKICAgIC8qIElmIGV2ZW4gbnVtYmVyIG9mIGhpcmVzIGJhbmRzICovCiAgICAqbnVtX2xvcmVzID0gbnVtX2hpcmVzID4+IDE7CiAgICAvKiBVc2UgZXZlcnkgc2Vjb25kIGxvcmVzPWhpcmVzWzAsMiw0Li4uXSAqLwogICAgZm9yKGk9MDsgaTw9Km51bV9sb3JlczsgaSsrKQogICAgICBoX2xvcmVzW2ldID0gaF9oaXJlc1tpKjJdOwogIH0KICBlbHNlIHsKICAgIC8qIE9kZCBudW1iZXIgb2YgaGlyZXMsIHdoaWNoIG1lYW5zIHhvdmVyIGlzIG9kZCAqLwogICAgKm51bV9sb3JlcyA9IChudW1faGlyZXMrMSkgPj4gMTsKICAgIC8qIFVzZSBsb3Jlcz1oaXJlc1swLDEsMyw1IC4uLl0gKi8KICAgIGhfbG9yZXNbMF0gPSBoX2hpcmVzWzBdOwogICAgZm9yKGk9MTsgaTw9Km51bV9sb3JlczsgaSsrKSB7CiAgICAgIGhfbG9yZXNbaV0gPSBoX2hpcmVzW2kqMi0xXTsKICAgIH0KICB9Cn0KCgovKiEKICBcYnJpZWYgICBEZXJpdmUgYSBsb3ctcmVzb2x1dGlvbiBmcmVxdWVuY3ktdGFibGUgZnJvbSB0aGUgbWFzdGVyIGZyZXF1ZW5jeSB0YWJsZQoqLwp2b2lkCnNicmRlY0Rvd25TYW1wbGVMb1JlcyhVQ0hBUiAqdl9yZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiBudW1fcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKmZyZXFCYW5kVGFibGVSZWYsCiAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiBudW1fUmVmKQp7CiAgaW50IHN0ZXA7CiAgaW50IGksajsKICBpbnQgb3JnX2xlbmd0aCxyZXN1bHRfbGVuZ3RoOwogIGludCB2X2luZGV4W01BWF9GUkVRX0NPRUZGUz4+MV07CgogIC8qIGluaXQgKi8KICBvcmdfbGVuZ3RoID0gbnVtX1JlZjsKICByZXN1bHRfbGVuZ3RoID0gbnVtX3Jlc3VsdDsKCiAgdl9pbmRleFswXSA9IDA7ICAgLyogQWx3YXlzIHVzZSBsZWZ0IGJvcmRlciAqLwogIGk9MDsKICB3aGlsZShvcmdfbGVuZ3RoID4gMCkgewogICAgLyogQ3JlYXRlIGRvd25zYW1wbGUgdmVjdG9yICovCiAgICBpKys7CiAgICBzdGVwID0gb3JnX2xlbmd0aCAvIHJlc3VsdF9sZW5ndGg7CiAgICBvcmdfbGVuZ3RoID0gb3JnX2xlbmd0aCAtIHN0ZXA7CiAgICByZXN1bHRfbGVuZ3RoLS07CiAgICB2X2luZGV4W2ldID0gdl9pbmRleFtpLTFdICsgc3RlcDsKICB9CgogIGZvcihqPTA7ajw9aTtqKyspIHsKICAgIC8qIFVzZSBkb3duc2FtcGxlIHZlY3RvciB0byBpbmRleCBMb1Jlc29sdXRpb24gdmVjdG9yICovCiAgICB2X3Jlc3VsdFtqXT1mcmVxQmFuZFRhYmxlUmVmW3ZfaW5kZXhbal1dOwogIH0KCn0KCgovKiEKICBcYnJpZWYgICBTb3J0aW5nIHJvdXRpbmUKKi8Kdm9pZCBzaGVsbHNvcnQoVUNIQVIgKmluLCBVQ0hBUiBuKQp7CgogIGludCBpLCBqLCB2LCB3OwogIGludCBpbmMgPSAxOwoKICBkbwogICAgaW5jID0gMyAqIGluYyArIDE7CiAgd2hpbGUgKGluYyA8PSBuKTsKCiAgZG8gewogICAgaW5jID0gaW5jIC8gMzsKICAgIGZvciAoaSA9IGluYzsgaSA8IG47IGkrKykgewogICAgICB2ID0gaW5baV07CiAgICAgIGogPSBpOwogICAgICB3aGlsZSAoKHc9aW5bai1pbmNdKSA+IHYpIHsKICAgICAgICBpbltqXSA9IHc7CiAgICAgICAgaiAtPSBpbmM7CiAgICAgICAgaWYgKGogPCBpbmMpCiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgICBpbltqXSA9IHY7CiAgICB9CiAgfSB3aGlsZSAoaW5jID4gMSk7Cgp9CgoKCi8qIQogIFxicmllZiAgIFJlc2V0IGZyZXF1ZW5jeSBiYW5kIHRhYmxlcwogIFxyZXR1cm4gIGVycm9yQ29kZSwgMCBpZiBzdWNjZXNzZnVsCiovClNCUl9FUlJPUgpyZXNldEZyZXFCYW5kVGFibGVzKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsIGNvbnN0IFVJTlQgZmxhZ3MpCnsKICBTQlJfRVJST1IgZXJyID0gU0JSREVDX09LOwogIGludCBrMixreCwgbHNiLCB1c2I7CiAgaW50ICAgICBpbnRUZW1wOwogIFVDSEFSICAgIG5CYW5kc0xvLCBuQmFuZHNIaTsKICBIQU5ETEVfRlJFUV9CQU5EX0RBVEEgaEZyZXEgPSAmaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YTsKCiAgLyogQ2FsY3VsYXRlIG1hc3RlciBmcmVxdWVuY3kgZnVuY3Rpb24gKi8KICBlcnIgPSBzYnJkZWNVcGRhdGVGcmVxU2NhbGUoaEZyZXEtPnZfa19tYXN0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoRnJlcS0+bnVtTWFzdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+c2JyUHJvY1NtcGxSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MpOwoKICBpZiAoIGVyciB8fCAoaEhlYWRlckRhdGEtPmJzX2luZm8ueG92ZXJfYmFuZCA+IGhGcmVxLT5udW1NYXN0ZXIpICkgewogICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgfQoKICAvKiBEZXJpdmUgSGlyZXNvbHV0aW9uIGZyb20gbWFzdGVyIGZyZXF1ZW5jeSBmdW5jdGlvbiAqLwogIHNicmRlY1VwZGF0ZUhpUmVzKGhGcmVxLT5mcmVxQmFuZFRhYmxlWzFdLCAmbkJhbmRzSGksIGhGcmVxLT52X2tfbWFzdGVyLCBoRnJlcS0+bnVtTWFzdGVyLCBoSGVhZGVyRGF0YS0+YnNfaW5mby54b3Zlcl9iYW5kICk7CiAgLyogRGVyaXZlIExvcmVzb2x1dGlvbiBmcm9tIEhpcmVzb2x1dGlvbiAqLwogIHNicmRlY1VwZGF0ZUxvUmVzKGhGcmVxLT5mcmVxQmFuZFRhYmxlWzBdLCAmbkJhbmRzTG8sIGhGcmVxLT5mcmVxQmFuZFRhYmxlWzFdLCBuQmFuZHNIaSk7CgoKICBoRnJlcS0+blNmYlswXSA9IG5CYW5kc0xvOwogIGhGcmVxLT5uU2ZiWzFdID0gbkJhbmRzSGk7CgogIC8qIENoZWNrIGluZGV4IHRvIGZyZXFCYW5kVGFibGVbMF0gKi8KICBpZiAoICEobkJhbmRzTG8gPiAwKSB8fCAobkJhbmRzTG8gPiAoTUFYX0ZSRVFfQ09FRkZTPj4xKSkgKSB7CiAgICByZXR1cm4gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICB9CgogIGxzYiA9IGhGcmVxLT5mcmVxQmFuZFRhYmxlWzBdWzBdOwogIHVzYiA9IGhGcmVxLT5mcmVxQmFuZFRhYmxlWzBdW25CYW5kc0xvXTsKCiAgLyogQWRkaXRpb25hbCBjaGVjayBmb3IgbHNiICovCiAgaWYgKCAobHNiID4gKDMyKSkgfHwgKGxzYiA+PSB1c2IpICkgewogICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgfQoKCiAgLyogQ2FsY3VsYXRlIG51bWJlciBvZiBub2lzZSBiYW5kcyAqLwoKICBrMiA9IGhGcmVxLT5mcmVxQmFuZFRhYmxlWzFdW25CYW5kc0hpXTsKICBreCA9IGhGcmVxLT5mcmVxQmFuZFRhYmxlWzFdWzBdOwoKICBpZiAoaEhlYWRlckRhdGEtPmJzX2RhdGEubm9pc2VfYmFuZHMgPT0gMCkKICB7CiAgICBoRnJlcS0+bk5mYiA9IDE7CiAgfQogIGVsc2UgLyogQ2FsY3VsYXRlIG5vIG9mIG5vaXNlIGJhbmRzIDEsMiBvciAzIGJhbmRzL29jdGF2ZSAqLwogIHsKICAgIC8qIEZldGNoIG51bWJlciBvZiBvY3RhdmVzIGRpdmlkZWQgYnkgMzIgKi8KICAgIGludFRlbXAgPSAoTE9ORylGREtfZ2V0TnVtT2N0YXZlc0Rpdjgoa3gsazIpID4+IDI7CgogICAgLyogSW50ZWdlci1NdWx0aXBsaWNhdGlvbiB3aXRoIG51bWJlciBvZiBiYW5kczogKi8KICAgIGludFRlbXAgPSBpbnRUZW1wICogaEhlYWRlckRhdGEtPmJzX2RhdGEubm9pc2VfYmFuZHM7CgogICAgLyogQWRkIHNjYWxlZCAwLjUgZm9yIHJvdW5kaW5nOiAqLwogICAgaW50VGVtcCA9IGludFRlbXAgKyAoTE9ORylGTDJGWENPTlNUX1NHTCgwLjVmLzMyLjBmKTsKCiAgICAvKiBDb252ZXJ0IHRvIHJpZ2h0LWFsaWduZWQgaW50ZWdlcjogKi8KICAgIGludFRlbXAgPSBpbnRUZW1wID4+IChGUkFDVF9CSVRTIC0gMSAvKnNpZ24qLyAtIDUgLyogcmVzY2FsZSAqLyk7CgogICAgLyogQ29tcGFyZSB3aXRoIGZsb2F0IGNhbGN1bGF0aW9uICovCiAgICBGREtfQVNTRVJUKCBpbnRUZW1wID09ICAoaW50KSgoaEhlYWRlckRhdGEtPmJzX2RhdGEubm9pc2VfYmFuZHMgKiBGREtsb2coIChmbG9hdClrMi9reCkgLyAoZmxvYXQpKEZES2xvZygyLjApKSkrMC41KSApOwoKICAgIGlmKCBpbnRUZW1wPT0wKQogICAgICBpbnRUZW1wPTE7CgogICAgaEZyZXEtPm5OZmIgPSBpbnRUZW1wOwogIH0KCiAgaEZyZXEtPm5JbnZmQmFuZHMgPSBoRnJlcS0+bk5mYjsKCiAgaWYoIGhGcmVxLT5uTmZiID4gTUFYX05PSVNFX0NPRUZGUyApIHsKICAgIHJldHVybiBTQlJERUNfVU5TVVBQT1JURURfQ09ORklHOwogIH0KCiAgLyogR2V0IG5vaXNlIGJhbmRzICovCiAgc2JyZGVjRG93blNhbXBsZUxvUmVzKGhGcmVxLT5mcmVxQmFuZFRhYmxlTm9pc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGhGcmVxLT5uTmZiLAogICAgICAgICAgICAgICAgICAgICAgICBoRnJlcS0+ZnJlcUJhbmRUYWJsZVswXSwKICAgICAgICAgICAgICAgICAgICAgICAgbkJhbmRzTG8pOwoKCgoKICBoRnJlcS0+bG93U3ViYmFuZCAgPSBsc2I7CiAgaEZyZXEtPmhpZ2hTdWJiYW5kID0gdXNiOwoKICByZXR1cm4gU0JSREVDX09LOwp9Cg==