Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSAidG9uX2NvcnIuaCIKCiNpbmNsdWRlICJzYnJfcmFtLmgiCiNpbmNsdWRlICJzYnJfbWlzYy5oIgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKI2luY2x1ZGUgImF1dG9jb3JyMm5kLmgiCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgU2VuZCBhdXRvQ29yclNlY29uZE9yZGVyIHRvIG1sZmlsZQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmIENhbGN1bGF0ZXMgdGhlIHRvbmFsIHRvIG5vaXNlIHJhdGlvbiBmb3IgZGlmZmVyZW50IGZyZXF1ZW5jeSBiYW5kcwogICBhbmQgdGltZSBzZWdtZW50cy4KCiAgIFRoZSByYXRpbyBiZXR3ZWVuIHRoZSBwcmVkaWN0ZWQgZW5lcmd5ICh0b25hbCBlbmVyZ3kgQSkgYW5kIHRoZSB0b3RhbAogICBlbmVyZ3kgKEEgKyBCKSBpcyBjYWxjdWxhdGVkLiBUaGlzIGlzIGNvbnZlcnRlZCB0byB0aGUgcmF0aW8gYmV0d2VlbgogICB0aGUgcHJlZGljdGVkIGVuZXJneSAodG9uYWwgZW5lcmd5IEEpIGFuZCB0aGUgbm9uLXByZWRpY3RhYmxlIGVuZXJneQogICAobm9pc2UgZW5lcmd5IEIpLiBIZW5jZSB0aGUgcXVvdGEtbWF0cml4IGNvbnRhaW5zIEEvQiA9IHEvKDEtcSkuCgogICBUaGUgc2FtcGxlcyBpbiBucmdWZWN0b3IgYXJlIHNjYWxlZCBieSAxLjAvMTYuMAoJCVRoZSBzYW1wbGVzIGluIHBOcmdWZWN0b3JGcmVxCWFyZSBzY2FsZWQgYnkgMS4wLzIuMAogICBUaGUgc2FtcGxlcyBpbiBxdW90YU1hdHJpeCBhcmUgc2NhbGVkIGJ5IFJFTEFYQVRJT04KCiAgXHJldHVybiBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZApGREtzYnJFbmNfQ2FsY3VsYXRlVG9uYWxpdHlRdW90YXMoIEhBTkRMRV9TQlJfVE9OX0NPUlJfRVNUIGhUb25Db3JyLCAgICAgIC8qITwgSGFuZGxlIHRvIFNCUl9UT05fQ09SUiBzdHJ1Y3QuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKipSRVNUUklDVCBzb3VyY2VCdWZmZXJSZWFsLCAgLyohPCBUaGUgcmVhbCBwYXJ0IG9mIHRoZSBRTUYtbWF0cml4LiAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKlJFU1RSSUNUIHNvdXJjZUJ1ZmZlckltYWcsICAvKiE8IFRoZSBpbWFnaW5hcnkgcGFydCBvZiB0aGUgUU1GLW1hdHJpeC4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdXNiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IHVwcGVyIHNpZGUgYmFuZCwgaGlnaGVzdCArIDEgUU1GIGJhbmQgaW4gdGhlIFNCUiByYW5nZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcW1mU2NhbGUgICAgICAgICAgICAgICAgICAgICAgIC8qITwgc2NsZWZhY3RvciBvZiBRTUYgc3Vic2FtcGxlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBJTlQgICAgIGksIGssIHIsIHIyLCB0aW1lSW5kZXgsIGF1dG9Db3JyU2NhbGluZzsKCiAgSU5UICAgICBzdGFydEluZGV4TWF0cml4ICA9IGhUb25Db3JyLT5zdGFydEluZGV4TWF0cml4OwogIElOVCAgICAgdG90Tm9Fc3QgICAgICAgICAgPSBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXM7CiAgSU5UICAgICBub0VzdFBlckZyYW1lICAgICA9IGhUb25Db3JyLT5udW1iZXJPZkVzdGltYXRlc1BlckZyYW1lOwogIElOVCAgICAgbW92ZSAgICAgICAgICAgICAgPSBoVG9uQ29yci0+bW92ZTsKICBJTlQgICAgIG5vUW1mQ2hhbm5lbHMgICAgID0gaFRvbkNvcnItPm5vUW1mQ2hhbm5lbHM7ICAgICAvKiBOdW1lciBvZiBCYW5kcyAqLwogIElOVCAgICAgYnVmZkxlbiAgICAgICAgICAgPSBoVG9uQ29yci0+YnVmZmVyTGVuZ3RoOyAgICAgIC8qIE51bWVyIG9mIFNsb3RzICovCiAgSU5UICAgICBzdGVwU2l6ZSAgICAgICAgICA9IGhUb25Db3JyLT5zdGVwU2l6ZTsKICBJTlQgICAgKnBCbG9ja0xlbmd0aCAgICAgID0gaFRvbkNvcnItPmxwY0xlbmd0aDsKICBJTlQqKiAgIFJFU1RSSUNUIHNpZ25NYXRyaXggICAgICAgID0gaFRvbkNvcnItPnNpZ25NYXRyaXg7CiAgRklYUF9EQkwqIFJFU1RSSUNUICBucmdWZWN0b3IgICAgICA9IGhUb25Db3JyLT5ucmdWZWN0b3I7CiAgRklYUF9EQkwqKiBSRVNUUklDVCBxdW90YU1hdHJpeCAgICA9IGhUb25Db3JyLT5xdW90YU1hdHJpeDsKICBGSVhQX0RCTCogIFJFU1RSSUNUIHBOcmdWZWN0b3JGcmVxID0gaFRvbkNvcnItPm5yZ1ZlY3RvckZyZXE7CgojZGVmaW5lIEJBTkRfVl9TSVpFIFFNRl9NQVhfVElNRV9TTE9UUwojZGVmaW5lIE5VTV9WX0NPTUJJTkUgOCAvKiBNdXN0IGJlIGEgZGl2aXNvciBvZiA2NCBhbmQgZnVsZmlsbCB0aGUgQVNTRVJUcyBiZWxvdyAqLwoKICBGSVhQX0RCTCAqcmVhbEJ1ZjsKICBGSVhQX0RCTCAqaW1hZ0J1ZjsKCiAgRklYUF9EQkwgIGFscGhhclsyXSxhbHBoYWlbMl0sZmFjOwoKICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQoYWMsIEFDT1JSX0NPRUZTLCAxKTsKICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQocmVhbEJ1ZlJlZiwgRklYUF9EQkwsIDIqQkFORF9WX1NJWkUqTlVNX1ZfQ09NQklORSk7CgogIHJlYWxCdWYgPSByZWFsQnVmUmVmOwogIGltYWdCdWYgPSByZWFsQnVmICsgQkFORF9WX1NJWkUqTlVNX1ZfQ09NQklORTsKCgogIEZES19BU1NFUlQoYnVmZkxlbiA8PSBCQU5EX1ZfU0laRSk7CiAgRkRLX0FTU0VSVChzaXplb2YoRklYUF9EQkwpKk5VTV9WX0NPTUJJTkUqQkFORF9WX1NJWkUqMiA8ICgxMDI0KnNpemVvZihGSVhQX0RCTCktc2l6ZW9mKEFDT1JSX0NPRUZTKSkgKTsKCiAgLyoKICAgKiBCdWZmZXJpbmcgb2YgdGhlIHF1b3RhTWF0cml4IGFuZCB0aGUgcXVvdGFNYXRyaXhUcmFuc3AuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICBmb3IoaSA9ICAwIDsgaSA8IG1vdmU7IGkrKyl7CiAgICBGREttZW1jcHkocXVvdGFNYXRyaXhbaV0scXVvdGFNYXRyaXhbaSArIG5vRXN0UGVyRnJhbWVdLG5vUW1mQ2hhbm5lbHMgKiBzaXplb2YoRklYUF9EQkwpKTsKICAgIEZES21lbWNweShzaWduTWF0cml4W2ldLHNpZ25NYXRyaXhbaSArIG5vRXN0UGVyRnJhbWVdLG5vUW1mQ2hhbm5lbHMgKiBzaXplb2YoSU5UKSk7CiAgfQoKICBGREttZW1tb3ZlKG5yZ1ZlY3RvcixucmdWZWN0b3Irbm9Fc3RQZXJGcmFtZSxtb3ZlKnNpemVvZihGSVhQX0RCTCkpOwogIEZES21lbWNsZWFyKG5yZ1ZlY3RvcitzdGFydEluZGV4TWF0cml4LCh0b3ROb0VzdC1zdGFydEluZGV4TWF0cml4KSpzaXplb2YoRklYUF9EQkwpKTsKICBGREttZW1jbGVhcihwTnJnVmVjdG9yRnJlcSxub1FtZkNoYW5uZWxzICogc2l6ZW9mKEZJWFBfREJMKSk7CgogIC8qCiAgICogQ2FsY3VsYXRlIHRoZSBxdW90YXMgZm9yIHRoZSBjdXJyZW50IHRpbWUgc3RlcHMuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICBmb3IgKHIgPSAwOyByIDwgdXNiOyByKyspCiAgewogICAgaW50IGJsb2NrTGVuZ3RoOwoKICAgIGsgPSBoVG9uQ29yci0+bmV4dFNhbXBsZTsgLyogc3RhcnRTYW1wbGUgKi8KICAgIHRpbWVJbmRleCA9IHN0YXJ0SW5kZXhNYXRyaXg7CiAgICAvKiBDb3B5IGFzIG1hbnkgYXMgcG9zc2libGUgQmFuZCBhY2Nyb3NzIGFsbCBTbG90cyBhdCBvbmNlICovCiAgICBpZiAocmVhbEJ1ZiAhPSByZWFsQnVmUmVmKSB7CiAgICAgIHJlYWxCdWYgLT0gQkFORF9WX1NJWkU7CiAgICAgIGltYWdCdWYgLT0gQkFORF9WX1NJWkU7CiAgICB9IGVsc2UgewogICAgICByZWFsQnVmICs9IEJBTkRfVl9TSVpFKihOVU1fVl9DT01CSU5FLTEpOwogICAgICBpbWFnQnVmICs9IEJBTkRfVl9TSVpFKihOVU1fVl9DT01CSU5FLTEpOwogICAgICBmb3IgKGkgPSAwOyBpIDwgYnVmZkxlbjsgaSsrKSB7CiAgICAgICAgaW50IHY7CiAgICAgICAgRklYUF9EQkwgKnB0cjsKICAgICAgICBwdHIgPSByZWFsQnVmK2k7CiAgICAgICAgZm9yICh2PTA7IHY8TlVNX1ZfQ09NQklORTsgdisrKQogICAgICAgIHsKICAgICAgICAgIHB0clswXSA9IHNvdXJjZUJ1ZmZlclJlYWxbaV1bcit2XTsKICAgICAgICAgIHB0clswK0JBTkRfVl9TSVpFKk5VTV9WX0NPTUJJTkVdID0gc291cmNlQnVmZmVySW1hZ1tpXVtyK3ZdOwogICAgICAgICAgcHRyIC09IEJBTkRfVl9TSVpFOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGJsb2NrTGVuZ3RoID0gcEJsb2NrTGVuZ3RoWzBdOwoKICAgIHdoaWxlKGsgPD0gYnVmZkxlbiAtIGJsb2NrTGVuZ3RoKQogICAgewogICAgICBhdXRvQ29yclNjYWxpbmcgPSBmaXhNaW4oZ2V0U2NhbGVmYWN0b3IoJnJlYWxCdWZbay1MUENfT1JERVJdLCBMUENfT1JERVIrYmxvY2tMZW5ndGgpLCBnZXRTY2FsZWZhY3RvcigmaW1hZ0J1ZltrLUxQQ19PUkRFUl0sIExQQ19PUkRFUitibG9ja0xlbmd0aCkpOwogICAgICBhdXRvQ29yclNjYWxpbmcgPSBmaXhNYXgoMCwgYXV0b0NvcnJTY2FsaW5nLTEpOwoKICAgICAgc2NhbGVWYWx1ZXMoJnJlYWxCdWZbay1MUENfT1JERVJdLCBMUENfT1JERVIrYmxvY2tMZW5ndGgsIGF1dG9Db3JyU2NhbGluZyk7CiAgICAgIHNjYWxlVmFsdWVzKCZpbWFnQnVmW2stTFBDX09SREVSXSwgTFBDX09SREVSK2Jsb2NrTGVuZ3RoLCBhdXRvQ29yclNjYWxpbmcpOwoKICAgICAgYXV0b0NvcnJTY2FsaW5nIDw8PSAxOyAvKiBjb25zaWRlciBxbWYgYnVmZmVyIHNjYWxpbmcgdHdpY2UgKi8KICAgICAgYXV0b0NvcnJTY2FsaW5nICs9IGF1dG9Db3JyMm5kX2NwbHggKCBhYywgcmVhbEJ1ZitrLCBpbWFnQnVmK2ssIGJsb2NrTGVuZ3RoICk7CgoKICAgICAgaWYoYWMtPmRldCA9PSBGTDJGWENPTlNUX0RCTCgwLjBmKSl7CiAgICAgICAgYWxwaGFyWzFdID0gYWxwaGFpWzFdID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CgogICAgICAgIGFscGhhclswXSA9IChhYy0+cjAxcik+PjI7CiAgICAgICAgYWxwaGFpWzBdID0gKGFjLT5yMDFpKT4+MjsKCiAgICAgICAgZmFjID0gZk11bHREaXYyKGFjLT5yMDByLCBhYy0+cjExcik+PjE7CiAgICAgIH0KICAgICAgZWxzZXsKICAgICAgICBhbHBoYXJbMV0gPSAoZk11bHREaXYyKGFjLT5yMDFyLCBhYy0+cjEycik+PjEpIC0gKGZNdWx0RGl2MihhYy0+cjAxaSwgYWMtPnIxMmkpPj4xKSAtIChmTXVsdERpdjIoYWMtPnIwMnIsIGFjLT5yMTFyKT4+MSk7CiAgICAgICAgYWxwaGFpWzFdID0gKGZNdWx0RGl2MihhYy0+cjAxaSwgYWMtPnIxMnIpPj4xKSArIChmTXVsdERpdjIoYWMtPnIwMXIsIGFjLT5yMTJpKT4+MSkgLSAoZk11bHREaXYyKGFjLT5yMDJpLCBhYy0+cjExcik+PjEpOwoKICAgICAgICBhbHBoYXJbMF0gPSAoZk11bHREaXYyKGFjLT5yMDFyLCBhYy0+ZGV0KT4+KGFjLT5kZXRfc2NhbGUrMSkpICsgZk11bHQoYWxwaGFyWzFdLCBhYy0+cjEycikgKyBmTXVsdChhbHBoYWlbMV0sIGFjLT5yMTJpKTsKICAgICAgICBhbHBoYWlbMF0gPSAoZk11bHREaXYyKGFjLT5yMDFpLCBhYy0+ZGV0KT4+KGFjLT5kZXRfc2NhbGUrMSkpICsgZk11bHQoYWxwaGFpWzFdLCBhYy0+cjEycikgLSBmTXVsdChhbHBoYXJbMV0sIGFjLT5yMTJpKTsKCiAgICAgICAgZmFjID0gZk11bHREaXYyKGFjLT5yMDByLCBmTXVsdChhYy0+ZGV0LCBhYy0+cjExcikpPj4oYWMtPmRldF9zY2FsZSsxKTsKICAgICAgfQoKICAgICAgaWYoZmFjID09IEZMMkZYQ09OU1RfREJMKDAuMGYpKXsKICAgICAgICBxdW90YU1hdHJpeFt0aW1lSW5kZXhdW3JdID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgICAgc2lnbk1hdHJpeFt0aW1lSW5kZXhdW3JdID0gMDsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICAvKiBxdW90YU1hdHJpeCBpcyBzY2FsZWQgd2l0aCB0aGUgZmFjdG9yIFJFTEFYQVRJT04KICAgICAgICAgICBwYXJzZSBSRUxBWEFUSU9OIGluIGZyYWN0aW9uYWwgcGFydCBhbmQgc2hpZnQgZmFjdG9yOiAxLygxLzAuNTI0Mjg4ICogMl5SRUxBWEFUSU9OX1NISUZUKSAqLwogICAgICAgIEZJWFBfREJMIHRtcCxudW0sZGVub207CiAgICAgICAgSU5UIG51bVNoaWZ0LGRlbm9tU2hpZnQsY29tbW9uU2hpZnQ7CiAgICAgICAgSU5UIHNpZ247CgogICAgICAgIG51bSA9IGZNdWx0RGl2MihhbHBoYXJbMF0sIGFjLT5yMDFyKSArIGZNdWx0RGl2MihhbHBoYWlbMF0sIGFjLT5yMDFpKSAtIGZNdWx0RGl2MihhbHBoYXJbMV0sIGZNdWx0KGFjLT5yMDJyLCBhYy0+cjExcikpIC0gZk11bHREaXYyKGFscGhhaVsxXSwgZk11bHQoYWMtPnIwMmksIGFjLT5yMTFyKSk7CiAgICAgICAgbnVtID0gZml4cF9hYnMobnVtKTsKCiAgICAgICAgZGVub20gPSAoZmFjPj4xKSArIChmTXVsdERpdjIoZmFjLFJFTEFYQVRJT05fRlJBQ1QpPj5SRUxBWEFUSU9OX1NISUZUKSAtIG51bTsKICAgICAgICBkZW5vbSA9IGZpeHBfYWJzKGRlbm9tKTsKCiAgICAgICAgbnVtID0gZk11bHQobnVtLFJFTEFYQVRJT05fRlJBQ1QpOwoKICAgICAgICBudW1TaGlmdCA9IENvdW50TGVhZGluZ0JpdHMobnVtKSAtIDI7CiAgICAgICAgbnVtID0gc2NhbGVWYWx1ZShudW0sIG51bVNoaWZ0KTsKCiAgICAgICAgZGVub21TaGlmdCA9IENvdW50TGVhZGluZ0JpdHMoZGVub20pOwogICAgICAgIGRlbm9tID0gKEZJWFBfREJMKWRlbm9tIDw8IGRlbm9tU2hpZnQ7CgogICAgICAgIGlmICgobnVtID4gRkwyRlhDT05TVF9EQkwoMC4wZikpICYmIChkZW5vbSAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSkpIHsKICAgICAgICAgIGNvbW1vblNoaWZ0ID0gZml4TWluKG51bVNoaWZ0IC0gZGVub21TaGlmdCArIFJFTEFYQVRJT05fU0hJRlQsIERGUkFDVF9CSVRTLTEpOwogICAgICAgICAgaWYgKGNvbW1vblNoaWZ0IDwgMCkgewogICAgICAgICAgICBjb21tb25TaGlmdCA9IC1jb21tb25TaGlmdDsKICAgICAgICAgICAgdG1wID0gc2NodXJfZGl2KG51bSxkZW5vbSwxNik7CiAgICAgICAgICAgIGNvbW1vblNoaWZ0ID0gZml4TWluKGNvbW1vblNoaWZ0LENvdW50TGVhZGluZ0JpdHModG1wKSk7CiAgICAgICAgICAgIHF1b3RhTWF0cml4W3RpbWVJbmRleF1bcl0gPSB0bXAgPDwgY29tbW9uU2hpZnQ7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcXVvdGFNYXRyaXhbdGltZUluZGV4XVtyXSA9IHNjaHVyX2RpdihudW0sZGVub20sMTYpID4+IGNvbW1vblNoaWZ0OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIHF1b3RhTWF0cml4W3RpbWVJbmRleF1bcl0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgICB9CgogICAgICAgIGlmIChhYy0+cjExciAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSkgewogICAgICAgICAgaWYgKCAgKCAoYWMtPnIwMXIgPj0gRkwyRlhDT05TVF9EQkwoMC4wZikgKSAmJiAoIGFjLT5yMTFyID49IEZMMkZYQ09OU1RfREJMKDAuMGYpICkgKQogICAgICAgICAgICAgIHx8KCAoYWMtPnIwMXIgPCAgRkwyRlhDT05TVF9EQkwoMC4wZikgKSAmJiAoIGFjLT5yMTFyIDwgIEZMMkZYQ09OU1RfREJMKDAuMGYpICkgKSAgKSB7CiAgICAgICAgICAgIHNpZ24gPSAxOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHNpZ24gPSAtMTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICBzaWduID0gMTsKICAgICAgICB9CgogICAgICAgIGlmKHNpZ24gPCAwKSB7CiAgICAgICAgICByMiA9IHI7ICAgICAgIC8qIChJTlQpIHBvdygtMSwgYmFuZCk7ICovCiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgcjIgPSByICsgMTsgICAvKiAoSU5UKSBwb3coLTEsIGJhbmQrMSk7ICovCiAgICAgICAgfQogICAgICAgIHNpZ25NYXRyaXhbdGltZUluZGV4XVtyXSA9IDEgLSAyKihyMiAmIDB4MSk7CiAgICAgIH0KCiAgICAgIG5yZ1ZlY3Rvclt0aW1lSW5kZXhdICs9ICgoYWMtPnIwMHIpID4+IGZpeE1pbihERlJBQ1RfQklUUy0xLCgyKnFtZlNjYWxlK2F1dG9Db3JyU2NhbGluZyArIFNDQUxFX05SR1ZFQykpKTsKICAgICAgLyogcE5yZ1ZlY3RvckZyZXFbcl0gZmluYWxseSBoYXMgdG8gYmUgZGl2aWRlZCBieSBub0VzdFBlckZyYW1lLCByZXBsYWNlZCBkaXZpc2lvbiBieSBzaGlmdGluZyB3aXRoIG9uZSAqLwogICAgICBwTnJnVmVjdG9yRnJlcVtyXSA9IHBOcmdWZWN0b3JGcmVxW3JdICsgKChhYy0+cjAwcikgPj4gZml4TWluKERGUkFDVF9CSVRTLTEsKDIqcW1mU2NhbGUrYXV0b0NvcnJTY2FsaW5nICsgU0NBTEVfTlJHVkVDKSkpOwoKICAgICAgYmxvY2tMZW5ndGggPSBwQmxvY2tMZW5ndGhbMV07CiAgICAgIGsgKz0gc3RlcFNpemU7CiAgICAgIHRpbWVJbmRleCsrOwogICAgfQogIH0KCgogIENfQUxMT0NfU0NSQVRDSF9FTkQocmVhbEJ1ZiwgRklYUF9EQkwsIDIqQkFORF9WX1NJWkUqTlVNX1ZfQ09NQklORSk7CiAgQ19BTExPQ19TQ1JBVENIX0VORChhYywgQUNPUlJfQ09FRlMsIDEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiBFeHRyYWN0cyB0aGUgcGFyYW1ldGVycyByZXF1aXJlZCBpbiB0aGUgZGVjb2RlciB0byBvYnRhaW4gdGhlCiAgY29ycmVjdCB0b25hbCB0byBub2lzZSByYXRpbyBhZnRlciBTQlIuCgogIEVzdGltYXRlcyB0aGUgdG9uYWwgdG8gbm9pc2UgcmF0aW8gb2YgdGhlIG9yaWdpbmFsIHNpZ25hbCAodXNpbmcgTFBDKS4KICBQcmVkaWN0cyB0aGUgdG9uYWwgdG8gbm9pc2UgcmF0aW9uIG9mIHRoZSBTQlIgc2lnbmFsIChpbiB0aGUgZGVjb2RlcikgYnkKICBwYXRjaGluZyB0aGUgdG9uYWwgdG8gbm9pc2UgcmF0aW8gdmFsdWVzIHNpbWlsYXIgdG8gdGhlIHBhdGNoaW5nIG9mIHRoZQogIGxvd2JhbmQgaW4gdGhlIGRlY29kZXIuIEdpdmVuIHRoZSB0b25hbCB0byBub2lzZSByYXRpbyBvZiB0aGUgb3JpZ2luYWwKICBhbmQgdGhlIFNCUiBzaWduYWwsIGl0IGVzdGltYXRlcyB0aGUgcmVxdWlyZWQgYW1vdW50IG9mIGludmVyc2UgZmlsdGVyaW5nLAogIGFkZGl0aW9uYWwgbm9pc2UgYXMgd2VsbCBhcyBhbnkgYWRkaXRpb25hbCBzaW5lcy4KCiAgXHJldHVybiBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkCkZES3NickVuY19Ub25Db3JyUGFyYW1FeHRyKEhBTkRMRV9TQlJfVE9OX0NPUlJfRVNUIGhUb25Db3JyLC8qITwgSGFuZGxlIHRvIFNCUl9UT05fQ09SUiBzdHJ1Y3QuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVkZfTU9ERSogaW5mVmVjLCAgICAgICAgICAgICAgIC8qITwgVmVjdG9yIHdoZXJlIHRoZSBpbnZlcnNlIGZpbHRlcmluZyBsZXZlbHMgd2lsbCBiZSBzdG9yZWQuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICogbm9pc2VMZXZlbHMsICAgICAgICAgIC8qITwgVmVjdG9yIHdoZXJlIHRoZSBub2lzZSBsZXZlbHMgd2lsbCBiZSBzdG9yZWQuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCogbWlzc2luZ0hhcm1vbmljRmxhZywgICAgICAgIC8qITwgRmxhZyBzZXQgdG8gb25lIG9yIHplcm8sIGRlcGVuZGVudCBvbiBpZiBhbnkgc3Ryb25nIHNpbmVzIGFyZSBtaXNzaW5nLiovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICogbWlzc2luZ0hhcm1vbmljc0luZGV4LCAgIC8qITwgVmVjdG9yIGluZGljYXRpbmcgd2hlcmUgc2luZXMgYXJlIG1pc3NpbmcuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICogZW52ZWxvcGVDb21wZW5zYXRpb24sICAgIC8qITwgVmVjdG9yIHRvIHN0b3JlIGNvbXBlbnNhdGlvbiB2YWx1ZXMgZm9yIHRoZSBlbmVyZ2llcyBpbi4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0JSX0ZSQU1FX0lORk8gKmZyYW1lSW5mbywgLyohPCBGcmFtZSBpbmZvIHN0cnVjdCwgY29udGFpbnMgdGhlIHRpbWUgYW5kIGZyZXF1ZW5jeSBncmlkIG9mIHRoZSBjdXJyZW50IGZyYW1lLiovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSKiB0cmFuc2llbnRJbmZvLCAgICAgICAgICAgIC8qITwgVHJhbnNpZW50IGluZm8uKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIqIGZyZXFCYW5kVGFibGUsICAgICAgICAgICAgLyohPCBGcmVxdWVuY3kgYmFuZCB0YWJsZXMgZm9yIGhpZ2gtcmVzLiovCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLCAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgTnVtYmVyIG9mIHNjYWxlZmFjdG9yIGJhbmRzIGZvciBoaWdoLXJlcy4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBPU19NT0RFIHhwb3NUeXBlLCAgICAgICAgICAgICAgLyohPCBUeXBlIG9mIHRyYW5zcG9zZXIgdXNlZCBpbiB0aGUgZGVjb2Rlci4qLwogICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHNiclN5bnRheEZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIElOVCBiYW5kOwogIElOVCB0cmFuc2llbnRGbGFnID0gdHJhbnNpZW50SW5mb1sxXSA7ICAgIC8qITwgRmxhZyBpbmRpY2F0aW5nIGlmIGEgdHJhbnNpZW50IGlzIHByZXNlbnQgaW4gdGhlIGN1cnJlbnQgZnJhbWUuICovCiAgSU5UIHRyYW5zaWVudFBvcyAgPSB0cmFuc2llbnRJbmZvWzBdOyAgICAgLyohPCBQb3NpdGlvbiBvZiB0aGUgdHJhbnNpZW50LiovCiAgSU5UIHRyYW5zaWVudEZyYW1lLCB0cmFuc2llbnRGcmFtZUludmZFc3Q7CiAgSU5WRl9NT0RFKiBpbmZWZWNQdHI7CgoKICAvKiBEZXRlcm1pbmUgaWYgdGhpcyBpcyBhIGZyYW1lIHdoZXJlIGEgdHJhbnNpZW50IHN0YXJ0cy4uLgoKICBUaGUgZGV0ZWN0aW9uIG9mIG5vaXNlLWZsb29yLCBtaXNzaW5nIGhhcm1vbmljcyBhbmQgaW52Zl9lc3QsIGlzIG5vdCBpbiBzeW5jIGZvciB0aGUKICBub24tYnVmLW9wdCBkZWNvZGVyIHN1Y2ggYXMgQUFDLiBIZW5jZSB3ZSBuZWVkIHRvIGtlZXAgdHJhY2sgb24gdGhlIHRyYW5zaWVudCBpbiB0aGUKICBwcmVzZW50IGZyYW1lIGFzIHdlbGwgYXMgaW4gdGhlIG5leHQuCiAgKi8KICB0cmFuc2llbnRGcmFtZSA9IDA7CiAgaWYoaFRvbkNvcnItPnRyYW5zaWVudE5leHRGcmFtZSl7ICAgICAgIC8qIFRoZSB0cmFuc2llbnQgd2FzIGRldGVjdGVkIGluIHRoZSBwcmV2aW91cyBmcmFtZSwgYnV0IGlzIGFjdHVhbGx5ICovCiAgICB0cmFuc2llbnRGcmFtZSA9IDE7CiAgICBoVG9uQ29yci0+dHJhbnNpZW50TmV4dEZyYW1lID0gMDsKCiAgICBpZih0cmFuc2llbnRGbGFnKXsKICAgICAgaWYodHJhbnNpZW50UG9zICsgaFRvbkNvcnItPnRyYW5zaWVudFBvc09mZnNldCA+PSBmcmFtZUluZm8tPmJvcmRlcnNbZnJhbWVJbmZvLT5uRW52ZWxvcGVzXSl7CiAgICAgICAgaFRvbkNvcnItPnRyYW5zaWVudE5leHRGcmFtZSA9IDE7CiAgICAgIH0KICAgIH0KICB9CiAgZWxzZXsKICAgIGlmKHRyYW5zaWVudEZsYWcpewogICAgICBpZih0cmFuc2llbnRQb3MgKyBoVG9uQ29yci0+dHJhbnNpZW50UG9zT2Zmc2V0IDwgZnJhbWVJbmZvLT5ib3JkZXJzW2ZyYW1lSW5mby0+bkVudmVsb3Blc10pewogICAgICAgIHRyYW5zaWVudEZyYW1lID0gMTsKICAgICAgICBoVG9uQ29yci0+dHJhbnNpZW50TmV4dEZyYW1lID0gMDsKICAgICAgfQogICAgICBlbHNlewogICAgICAgIGhUb25Db3JyLT50cmFuc2llbnROZXh0RnJhbWUgPSAxOwogICAgICB9CiAgICB9CiAgfQogIHRyYW5zaWVudEZyYW1lSW52ZkVzdCA9IHRyYW5zaWVudEZyYW1lOwoKCiAgLyoKICAgIEVzdGltYXRlIHRoZSByZXF1aXJlZCBpbnZlc2UgZmlsdGVyZWluZyBsZXZlbC4KICAqLwogIGlmIChoVG9uQ29yci0+c3dpdGNoSW52ZXJzZUZpbHQpCiAgICBGREtzYnJFbmNfcW1mSW52ZXJzZUZpbHRlcmluZ0RldGVjdG9yKCZoVG9uQ29yci0+c2JySW52RmlsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPnF1b3RhTWF0cml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+bnJnVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+aW5kZXhWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUb25Db3JyLT5mcmFtZVN0YXJ0SW5kZXhJbnZmRXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXNQZXJGcmFtZSArIGhUb25Db3JyLT5mcmFtZVN0YXJ0SW5kZXhJbnZmRXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2llbnRGcmFtZUludmZFc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZlZlYyk7CgogIC8qCiAgICAgIERldGVjdCB3aGF0IHRvbmVzIHdpbGwgYmUgbWlzc2luZy4KICAgKi8KICBpZiAoeHBvc1R5cGUgPT0gWFBPU19MQyApewogICAgRkRLc2JyRW5jX1Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvclFtZigmaFRvbkNvcnItPnNick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPnF1b3RhTWF0cml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+c2lnbk1hdHJpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPmluZGV4VmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaWVudEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3NpbmdIYXJtb25pY0ZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3NpbmdIYXJtb25pY3NJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52ZWxvcGVDb21wZW5zYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUb25Db3JyLT5ucmdWZWN0b3JGcmVxKTsKICB9CiAgZWxzZXsKICAgICptaXNzaW5nSGFybW9uaWNGbGFnID0gMDsKICAgIEZES21lbWNsZWFyKG1pc3NpbmdIYXJtb25pY3NJbmRleCxuU2ZiKnNpemVvZihVQ0hBUikpOwogIH0KCgoKICAvKgogICAgTm9pc2UgZmxvb3IgZXN0aW1hdGlvbgogICovCgogIGluZlZlY1B0ciA9IGhUb25Db3JyLT5zYnJJbnZGaWx0LnByZXZJbnZmTW9kZTsKCiAgRkRLc2JyRW5jX3Nick5vaXNlRmxvb3JFc3RpbWF0ZVFtZigmaFRvbkNvcnItPnNick5vaXNlRmxvb3JFc3RpbWF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vaXNlTGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPnF1b3RhTWF0cml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPmluZGV4VmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm1pc3NpbmdIYXJtb25pY0ZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+ZnJhbWVTdGFydEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPm51bWJlck9mRXN0aW1hdGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2llbnRGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZlZlY1B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNiclN5bnRheEZsYWdzKTsKCgogIC8qIFN0b3JlIHRoZSBpbnZmVmVjIGRhdGEgZm9yIHRoZSBuZXh0IGZyYW1lLi4uKi8KICBmb3IoYmFuZCA9IDAgOyBiYW5kIDwgaFRvbkNvcnItPnNickludkZpbHQubm9EZXRlY3RvckJhbmRzOyBiYW5kKyspewogICAgaFRvbkNvcnItPnNickludkZpbHQucHJldkludmZNb2RlW2JhbmRdID0gaW5mVmVjW2JhbmRdOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIFNlYXJjaGVzIGZvciB0aGUgY2xvc2VzdCBtYXRjaCBpbiB0aGUgZnJlcXVlbmN5IG1hc3RlciB0YWJsZS4KCgoKICBccmV0dXJuICAgY2xvc2VzdCBlbnRyeS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVApmaW5kQ2xvc2VzdEVudHJ5KElOVCBnb2FsU2IsCiAgICAgICAgICAgICAgICAgVUNIQVIgKnZfa19tYXN0ZXIsCiAgICAgICAgICAgICAgICAgSU5UIG51bU1hc3RlciwKICAgICAgICAgICAgICAgICBJTlQgZGlyZWN0aW9uKQp7CiAgSU5UIGluZGV4OwoKICBpZiggZ29hbFNiIDw9IHZfa19tYXN0ZXJbMF0gKQogICAgcmV0dXJuIHZfa19tYXN0ZXJbMF07CgogIGlmKCBnb2FsU2IgPj0gdl9rX21hc3RlcltudW1NYXN0ZXJdICkKICAgIHJldHVybiB2X2tfbWFzdGVyW251bU1hc3Rlcl07CgogIGlmKGRpcmVjdGlvbikgewogICAgaW5kZXggPSAwOwogICAgd2hpbGUoIHZfa19tYXN0ZXJbaW5kZXhdIDwgZ29hbFNiICkgewogICAgICBpbmRleCsrOwogICAgfQogIH0gZWxzZSB7CiAgICBpbmRleCA9IG51bU1hc3RlcjsKICAgIHdoaWxlKCB2X2tfbWFzdGVyW2luZGV4XSA+IGdvYWxTYiApIHsKICAgICAgaW5kZXgtLTsKICAgIH0KICB9CgogIHJldHVybiB2X2tfbWFzdGVyW2luZGV4XTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICByZXNldHMgdGhlIHBhdGNoCgoKCiAgXHJldHVybiAgIGVycm9yQ29kZSwgbm9FcnJvciBpZiBzdWNjZXNzZnVsLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UCnJlc2V0UGF0Y2goSEFORExFX1NCUl9UT05fQ09SUl9FU1QgaFRvbkNvcnIsICAvKiE8IEhhbmRsZSB0byBTQlJfVE9OX0NPUlIgc3RydWN0LiAqLwogICAgICAgICAgIElOVCB4cG9zY3RybCwgICAgICAgICAgICAgICAgICAgICAgLyohPCBEaWZmZXJlbnQgcGF0Y2ggbW9kZXMuICovCiAgICAgICAgICAgSU5UIGhpZ2hCYW5kU3RhcnRTYiwgICAgICAgICAgICAgICAvKiE8IFN0YXJ0IGJhbmQgb2YgdGhlIFNCUiByYW5nZS4gKi8KICAgICAgICAgICBVQ0hBUiAqdl9rX21hc3RlciwgICAgICAgICAgICAgICAgICAgLyohPCBNYXN0ZXIgZnJlcXVlbmN5IHRhYmxlIGZyb20gd2hpY2ggYWxsIG90aGVyIHRhYmxlIGFyZSBkZXJpdmVkLiovCiAgICAgICAgICAgSU5UIG51bU1hc3RlciwgICAgICAgICAgICAgICAgICAgICAvKiE8IE51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbWFzdGVyIHRhYmxlLiAqLwogICAgICAgICAgIElOVCBmcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBTYW1wbGluZyBmcmVxdWVuY3kuICovCiAgICAgICAgICAgSU5UIG5vQ2hhbm5lbHMpICAgICAgICAgICAgICAgICAgICAvKiE8IE51bWJlciBvZiBRTUYtY2hhbm5lbHMuICovCnsKICBJTlQgcGF0Y2gsayxpOwogIElOVCB0YXJnZXRTdG9wQmFuZDsKCiAgUEFUQ0hfUEFSQU0gICpwYXRjaFBhcmFtID0gaFRvbkNvcnItPnBhdGNoUGFyYW07CgogIElOVCBzYkd1YXJkID0gaFRvbkNvcnItPmd1YXJkOwogIElOVCBzb3VyY2VTdGFydEJhbmQ7CiAgSU5UIHBhdGNoRGlzdGFuY2U7CiAgSU5UIG51bUJhbmRzSW5QYXRjaDsKCiAgSU5UIGxzYiA9IHZfa19tYXN0ZXJbMF07ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTG93ZXN0IHN1YmJhbmQgcmVsYXRlZCB0byB0aGUgc3ludGhlc2lzIGZpbHRlcmJhbmsgKi8KICBJTlQgdXNiID0gdl9rX21hc3RlcltudW1NYXN0ZXJdOyAgICAgICAgICAgICAgICAgICAvKiBTdG9wIHN1YmJhbmQgcmVsYXRlZCB0byB0aGUgc3ludGhlc2lzIGZpbHRlcmJhbmsgKi8KICBJTlQgeG92ZXJPZmZzZXQgPSBoaWdoQmFuZFN0YXJ0U2IgLSB2X2tfbWFzdGVyWzBdOyAvKiBDYWxjdWxhdGUgZGlzdGFuY2UgaW4gc3ViYmFuZHMgYmV0d2VlbiBrMCBhbmQga3ggKi8KCiAgSU5UIGdvYWxTYjsKCgogIC8qCiAgICogSW5pdGlhbGl6ZSB0aGUgcGF0Y2hpbmcgcGFyYW1ldGVyCiAgICovCgogIGlmICh4cG9zY3RybCA9PSAxKSB7CiAgICBsc2IgKz0geG92ZXJPZmZzZXQ7CiAgICB4b3Zlck9mZnNldCA9IDA7CiAgfQoKICBnb2FsU2IgPSAoSU5UKSggKDIgKiBub0NoYW5uZWxzICogMTYwMDAgKyAoZnM+PjEpKSAvIGZzICk7IC8qIDE2IGtIeiBiYW5kICovCiAgZ29hbFNiID0gZmluZENsb3Nlc3RFbnRyeShnb2FsU2IsIHZfa19tYXN0ZXIsIG51bU1hc3RlciwgMSk7IC8qIEFkYXB0IHJlZ2lvbiB0byBtYXN0ZXItdGFibGUgKi8KCiAgLyogRmlyc3QgcGF0Y2ggKi8KICBzb3VyY2VTdGFydEJhbmQgPSBoVG9uQ29yci0+c2hpZnRTdGFydFNiICsgeG92ZXJPZmZzZXQ7CiAgdGFyZ2V0U3RvcEJhbmQgPSBsc2IgKyB4b3Zlck9mZnNldDsKCiAgLyogZXZlbiAob2RkKSBudW1iZXJlZCBjaGFubmVsIG11c3QgYmUgcGF0Y2hlZCB0byBldmVuIChvZGQpIG51bWJlcmVkIGNoYW5uZWwgKi8KICBwYXRjaCA9IDA7CiAgd2hpbGUodGFyZ2V0U3RvcEJhbmQgPCB1c2IpIHsKCiAgICAvKiBUbyBtYW55IHBhdGNoZXMgKi8KICAgIGlmIChwYXRjaCA+PSBNQVhfTlVNX1BBVENIRVMpCiAgICAgIHJldHVybigxKTsgLypOdW1iZXIgb2YgcGF0Y2hlcyB0byBoaWdoICovCgogICAgcGF0Y2hQYXJhbVtwYXRjaF0uZ3VhcmRTdGFydEJhbmQgPSB0YXJnZXRTdG9wQmFuZDsKICAgIHRhcmdldFN0b3BCYW5kICs9IHNiR3VhcmQ7CiAgICBwYXRjaFBhcmFtW3BhdGNoXS50YXJnZXRTdGFydEJhbmQgPSB0YXJnZXRTdG9wQmFuZDsKCiAgICBudW1CYW5kc0luUGF0Y2ggPSBnb2FsU2IgLSB0YXJnZXRTdG9wQmFuZDsgICAgICAgICAgICAgICAgICAgLyogZ2V0IHRoZSBkZXNpcmVkIHJhbmdlIG9mIHRoZSBwYXRjaCAqLwoKICAgIGlmICggbnVtQmFuZHNJblBhdGNoID49IGxzYiAtIHNvdXJjZVN0YXJ0QmFuZCApIHsKICAgICAgLyogZGVzaXJlZCBudW1iZXIgYmFuZHMgYXJlIG5vdCBhdmFpbGFibGUgLT4gcGF0Y2ggd2hvbGUgc291cmNlIHJhbmdlICovCiAgICAgIHBhdGNoRGlzdGFuY2UgICA9IHRhcmdldFN0b3BCYW5kIC0gc291cmNlU3RhcnRCYW5kOyAgICAgICAgLyogZ2V0IHRoZSB0YXJnZXRPZmZzZXQgKi8KICAgICAgcGF0Y2hEaXN0YW5jZSAgID0gcGF0Y2hEaXN0YW5jZSAmIH4xOyAgICAgICAgICAgICAgICAgICAgICAvKiByb3VuZGluZyBvZmYgb2RkIG51bWJlcnMgYW5kIG1ha2UgYWxsIGV2ZW4gKi8KICAgICAgbnVtQmFuZHNJblBhdGNoID0gbHNiIC0gKHRhcmdldFN0b3BCYW5kIC0gcGF0Y2hEaXN0YW5jZSk7CiAgICAgIG51bUJhbmRzSW5QYXRjaCA9IGZpbmRDbG9zZXN0RW50cnkodGFyZ2V0U3RvcEJhbmQgKyBudW1CYW5kc0luUGF0Y2gsIHZfa19tYXN0ZXIsIG51bU1hc3RlciwgMCkgLQogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRTdG9wQmFuZDsgIC8qIEFkYXB0IHJlZ2lvbiB0byBtYXN0ZXItdGFibGUgKi8KICAgIH0KCiAgICAvKiBkZXNpcmVkIG51bWJlciBiYW5kcyBhcmUgYXZhaWxhYmxlIC0+IGdldCB0aGUgbWluaW1hbCBldmVuIHBhdGNoaW5nIGRpc3RhbmNlICovCiAgICBwYXRjaERpc3RhbmNlICAgPSBudW1CYW5kc0luUGF0Y2ggKyB0YXJnZXRTdG9wQmFuZCAtIGxzYjsgIC8qIGdldCBtaW5pbWFsIGRpc3RhbmNlICovCiAgICBwYXRjaERpc3RhbmNlICAgPSAocGF0Y2hEaXN0YW5jZSArIDEpICYgfjE7ICAgICAgICAgICAgICAgIC8qIHJvdW5kaW5nIHVwIG9kZCBudW1iZXJzIGFuZCBtYWtlIGFsbCBldmVuICovCgogICAgaWYgKG51bUJhbmRzSW5QYXRjaCA8PSAwKSB7CiAgICAgIHBhdGNoLS07CiAgICB9IGVsc2UgewogICAgICBwYXRjaFBhcmFtW3BhdGNoXS5zb3VyY2VTdGFydEJhbmQgPSB0YXJnZXRTdG9wQmFuZCAtIHBhdGNoRGlzdGFuY2U7CiAgICAgIHBhdGNoUGFyYW1bcGF0Y2hdLnRhcmdldEJhbmRPZmZzICA9IHBhdGNoRGlzdGFuY2U7CiAgICAgIHBhdGNoUGFyYW1bcGF0Y2hdLm51bUJhbmRzSW5QYXRjaCA9IG51bUJhbmRzSW5QYXRjaDsKICAgICAgcGF0Y2hQYXJhbVtwYXRjaF0uc291cmNlU3RvcEJhbmQgID0gcGF0Y2hQYXJhbVtwYXRjaF0uc291cmNlU3RhcnRCYW5kICsgbnVtQmFuZHNJblBhdGNoOwoKICAgICAgdGFyZ2V0U3RvcEJhbmQgKz0gcGF0Y2hQYXJhbVtwYXRjaF0ubnVtQmFuZHNJblBhdGNoOwogICAgfQoKICAgIC8qIEFsbCBwYXRjaGVzIGJ1dCBmaXJzdCAqLwogICAgc291cmNlU3RhcnRCYW5kID0gaFRvbkNvcnItPnNoaWZ0U3RhcnRTYjsKCiAgICAvKiBDaGVjayBpZiB3ZSBhcmUgY2xvc2UgdG8gZ29hbFNiICovCiAgICBpZiggZml4cF9hYnModGFyZ2V0U3RvcEJhbmQgLSBnb2FsU2IpIDwgMykgewogICAgICBnb2FsU2IgPSB1c2I7CiAgICB9CgogICAgcGF0Y2grKzsKCiAgfQoKICBwYXRjaC0tOwoKICAvKiBpZiBoaWdoZXN0IHBhdGNoIGNvbnRhaW5zIGxlc3MgdGhhbiB0aHJlZSBzdWJiYW5kOiBza2lwIGl0ICovCiAgaWYgKCBwYXRjaFBhcmFtW3BhdGNoXS5udW1CYW5kc0luUGF0Y2ggPCAzICYmIHBhdGNoID4gMCApIHsKICAgIHBhdGNoLS07CiAgICB0YXJnZXRTdG9wQmFuZCA9IHBhdGNoUGFyYW1bcGF0Y2hdLnRhcmdldFN0YXJ0QmFuZCArIHBhdGNoUGFyYW1bcGF0Y2hdLm51bUJhbmRzSW5QYXRjaDsKICB9CgogIGhUb25Db3JyLT5ub09mUGF0Y2hlcyA9IHBhdGNoICsgMTsKCgogIC8qIEFzc2lnbiB0aGUgaW5kZXgtdmVjdG9yLCBzbyB3ZSBrbm93IHdoZXJlIHRvIGxvb2sgZm9yIHRoZSBoaWdoLWJhbmQuCiAgICAgLTEgcmVwcmVzZW50cyBhIGd1YXJkLWJhbmQuICovCiAgZm9yKGsgPSAwOyBrIDwgaFRvbkNvcnItPnBhdGNoUGFyYW1bMF0uZ3VhcmRTdGFydEJhbmQ7IGsrKykKICAgIGhUb25Db3JyLT5pbmRleFZlY3RvcltrXSA9IGs7CgogIGZvcihpID0gMDsgaSA8IGhUb25Db3JyLT5ub09mUGF0Y2hlczsgaSsrKQogIHsKICAgIElOVCBzb3VyY2VTdGFydCAgICA9IGhUb25Db3JyLT5wYXRjaFBhcmFtW2ldLnNvdXJjZVN0YXJ0QmFuZDsKICAgIElOVCB0YXJnZXRTdGFydCAgICA9IGhUb25Db3JyLT5wYXRjaFBhcmFtW2ldLnRhcmdldFN0YXJ0QmFuZDsKICAgIElOVCBudW1iZXJPZkJhbmRzICA9IGhUb25Db3JyLT5wYXRjaFBhcmFtW2ldLm51bUJhbmRzSW5QYXRjaDsKICAgIElOVCBzdGFydEd1YXJkQmFuZCA9IGhUb25Db3JyLT5wYXRjaFBhcmFtW2ldLmd1YXJkU3RhcnRCYW5kOwoKICAgIGZvcihrID0gMDsgayA8ICh0YXJnZXRTdGFydC0gc3RhcnRHdWFyZEJhbmQpOyBrKyspCiAgICAgIGhUb25Db3JyLT5pbmRleFZlY3RvcltzdGFydEd1YXJkQmFuZCtrXSA9IC0xOwoKICAgIGZvcihrID0gMDsgayA8IG51bWJlck9mQmFuZHM7IGsrKykKICAgICAgaFRvbkNvcnItPmluZGV4VmVjdG9yW3RhcmdldFN0YXJ0K2tdID0gc291cmNlU3RhcnQrazsKICB9CgogIHJldHVybiAoMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIHRoZSB0b25hbGl0eSBjb3JyZWN0aW9uIHBhcmFtZXRlciBtb2R1bGUuCgogIFRoZSBtb2R1bGUgaW5jbHVkZXMgbW9kdWxlcyBmb3IgaW52ZXJzZSBmaWx0ZXJpbmcgbGV2ZWwgZXN0aW1hdGlvbiwKICBtaXNzaW5nIGhhcm1vbmljcyBkZXRlY3Rpb24gYW5kIG5vaXNlIGZsb29yIGxldmVsIGVzdGltYXRpb24uCgogIFxyZXR1cm4gICBlcnJvckNvZGUsIG5vRXJyb3IgaWYgc3VjY2Vzc2Z1bC4KKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQKRkRLc2JyRW5jX0NyZWF0ZVRvbkNvcnJQYXJhbUV4dHIoSEFORExFX1NCUl9UT05fQ09SUl9FU1QgaFRvbkNvcnIsIC8qITwgUG9pbnRlciB0byBoYW5kbGUgdG8gU0JSX1RPTl9DT1JSIHN0cnVjdC4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgICAgICAgY2hhbikgICAgIC8qITwgQ2hhbm5lbCBpbmRleCwgbmVlZGVkIGZvciBtZW0gYWxsb2NhdGlvbiAqLwp7CiAgSU5UIGk7CiAgRklYUF9EQkwqIHF1b3RhTWF0cml4ID0gR2V0UmFtX1Nicl9xdW90YU1hdHJpeChjaGFuKTsKICBJTlQqICAgICAgc2lnbk1hdHJpeCAgPSBHZXRSYW1fU2JyX3NpZ25NYXRyaXgoY2hhbik7CgogIEZES21lbWNsZWFyKGhUb25Db3JyLCBzaXplb2YoU0JSX1RPTl9DT1JSX0VTVCkpOwoKICBmb3IgKGk9MDsgaTxNQVhfTk9fT0ZfRVNUSU1BVEVTOyBpKyspIHsKICAgIGhUb25Db3JyLT5xdW90YU1hdHJpeFtpXSA9IHF1b3RhTWF0cml4ICsgKGkqUU1GX0NIQU5ORUxTKTsKICAgIGhUb25Db3JyLT5zaWduTWF0cml4W2ldICA9IHNpZ25NYXRyaXggICsgKGkqUU1GX0NIQU5ORUxTKTsKICB9CgogIEZES3NickVuY19DcmVhdGVTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IgKCZoVG9uQ29yci0+c2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLCBjaGFuKTsKCiAgcmV0dXJuIDA7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEluaXRpYWxpemUgYW4gaW5zdGFuY2Ugb2YgdGhlIHRvbmFsaXR5IGNvcnJlY3Rpb24gcGFyYW1ldGVyIG1vZHVsZS4KCiAgVGhlIG1vZHVsZSBpbmNsdWRlcyBtb2R1bGVzIGZvciBpbnZlcnNlIGZpbHRlcmluZyBsZXZlbCBlc3RpbWF0aW9uLAogIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdGlvbiBhbmQgbm9pc2UgZmxvb3IgbGV2ZWwgZXN0aW1hdGlvbi4KCiAgXHJldHVybiAgIGVycm9yQ29kZSwgbm9FcnJvciBpZiBzdWNjZXNzZnVsLgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCklOVApGREtzYnJFbmNfSW5pdFRvbkNvcnJQYXJhbUV4dHIgKElOVCBmcmFtZVNpemUsICAgICAgICAgICAgICAgICAgICAgLyohPCBDdXJyZW50IFNCUiBmcmFtZSBzaXplLiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfVE9OX0NPUlJfRVNUIGhUb25Db3JyLCAgLyohPCBQb2ludGVyIHRvIGhhbmRsZSB0byBTQlJfVE9OX0NPUlIgc3RydWN0LiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfQ09ORklHX0RBVEEgc2JyQ2ZnLCAgICAgLyohPCBQb2ludGVyIHRvIFNCUiBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHRpbWVTbG90cywgICAgICAgICAgICAgICAgICAgICAvKiE8IE51bWJlciBvZiB0aW1lLXNsb3RzIHBlciBmcmFtZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCB4cG9zQ3RybCwgICAgICAgICAgICAgICAgICAgICAgLyohPCBEaWZmZXJlbnQgcGF0Y2ggbW9kZXMuICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGFuYV9tYXhfbGV2ZWwsICAgICAgICAgICAgICAgICAvKiE8IE1heGltdW0gbGV2ZWwgb2YgdGhlIGFkYXB0aXZlIG5vaXNlLiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub2lzZUJhbmRzLCAgICAgICAgICAgICAgICAgICAgLyohPCBOdW1iZXIgb2Ygbm9pc2UgYmFuZHMgcGVyIG9jdGF2ZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9pc2VGbG9vck9mZnNldCwgICAgICAgICAgICAgIC8qITwgTm9pc2UgZmxvb3Igb2Zmc2V0LiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgdXNlU3BlZWNoQ29uZmlnKSAgICAgICAgICAgICAgLyohPCBTcGVlY2ggb3IgbXVzaWMgdHVuaW5nLiAqLwp7CiAgSU5UIG5Db2xzID0gc2JyQ2ZnLT5ub1FtZlNsb3RzOwogIElOVCBmcyAgICA9IHNickNmZy0+c2FtcGxlRnJlcTsKICBJTlQgbm9RbWZDaGFubmVscyA9IHNickNmZy0+bm9RbWZCYW5kczsKCiAgSU5UIGhpZ2hCYW5kU3RhcnRTYiA9IHNickNmZy0+ZnJlcUJhbmRUYWJsZVtMT1dfUkVTXVswXTsKICBVQ0hBUiAqdl9rX21hc3RlciAgID0gc2JyQ2ZnLT52X2tfbWFzdGVyOwogIElOVCBudW1NYXN0ZXIgICAgICAgPSBzYnJDZmctPm51bV9NYXN0ZXI7CgogIFVDSEFSICoqZnJlcUJhbmRUYWJsZSAgID0gc2JyQ2ZnLT5mcmVxQmFuZFRhYmxlOwogIElOVCAgICAqblNmYiAgICAgICAgICAgID0gc2JyQ2ZnLT5uU2ZiOwoKICBJTlQgaTsKCiAgLyoKICBSZXNldCB0aGUgcGF0Y2hpbmcgYW5kIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIHF1b3RhIG1hdHJpeC4KICBBc3NpbmcgcGFyYW1ldGVycyBmb3IgdGhlIExQQyBhbmFseXNpcy4KICAqLwogIGlmIChzYnJDZmctPnNiclN5bnRheEZsYWdzICYgU0JSX1NZTlRBWF9MT1dfREVMQVkpIHsKICAgIHN3aXRjaCAodGltZVNsb3RzKSB7CiAgICBjYXNlIE5VTUJFUl9USU1FX1NMT1RTXzE5MjA6CiAgICAgIGhUb25Db3JyLT5scGNMZW5ndGhbMF0gICAgICAgICAgICAgID0gOCAtIExQQ19PUkRFUjsKICAgICAgaFRvbkNvcnItPmxwY0xlbmd0aFsxXSAgICAgICAgICAgICAgPSA3IC0gTFBDX09SREVSOwogICAgICBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXMgICAgICAgICA9IE5PX09GX0VTVElNQVRFU19MRDsKICAgICAgaFRvbkNvcnItPm51bWJlck9mRXN0aW1hdGVzUGVyRnJhbWUgPSBzYnJDZmctPm5vUW1mU2xvdHMgLyA3OwogICAgICBoVG9uQ29yci0+ZnJhbWVTdGFydEluZGV4SW52ZkVzdCAgICA9IDA7CiAgICAgIGhUb25Db3JyLT50cmFuc2llbnRQb3NPZmZzZXQgICAgICAgID0gRlJBTUVfTUlERExFX1NMT1RfNTEyTEQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBOVU1CRVJfVElNRV9TTE9UU18yMDQ4OgogICAgICBoVG9uQ29yci0+bHBjTGVuZ3RoWzBdICAgICAgICAgICAgICA9IDggLSBMUENfT1JERVI7CiAgICAgIGhUb25Db3JyLT5scGNMZW5ndGhbMV0gICAgICAgICAgICAgID0gOCAtIExQQ19PUkRFUjsKICAgICAgaFRvbkNvcnItPm51bWJlck9mRXN0aW1hdGVzICAgICAgICAgPSBOT19PRl9FU1RJTUFURVNfTEQ7CiAgICAgIGhUb25Db3JyLT5udW1iZXJPZkVzdGltYXRlc1BlckZyYW1lID0gc2JyQ2ZnLT5ub1FtZlNsb3RzIC8gODsKICAgICAgaFRvbkNvcnItPmZyYW1lU3RhcnRJbmRleEludmZFc3QgICAgPSAwOwogICAgICBoVG9uQ29yci0+dHJhbnNpZW50UG9zT2Zmc2V0ICAgICAgICA9IEZSQU1FX01JRERMRV9TTE9UXzUxMkxEOwogICAgICBicmVhazsKICAgIH0KICB9IGVsc2UKICBzd2l0Y2ggKHRpbWVTbG90cykgewogIGNhc2UgTlVNQkVSX1RJTUVfU0xPVFNfMjA0ODoKICAgIGhUb25Db3JyLT5scGNMZW5ndGhbMF0gICAgICAgICAgICAgID0gMTYgLSBMUENfT1JERVI7IC8qIGJsb2NrTGVuZ3RoWzBdICovCiAgICBoVG9uQ29yci0+bHBjTGVuZ3RoWzFdICAgICAgICAgICAgICA9IDE2IC0gTFBDX09SREVSOyAvKiBibG9ja0xlbmd0aFswXSAqLwogICAgaFRvbkNvcnItPm51bWJlck9mRXN0aW1hdGVzICAgICAgICAgPSBOT19PRl9FU1RJTUFURVNfTEM7CiAgICBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXNQZXJGcmFtZSA9IHNickNmZy0+bm9RbWZTbG90cyAvIDE2OwogICAgaFRvbkNvcnItPmZyYW1lU3RhcnRJbmRleEludmZFc3QgICAgPSAwOwogICAgaFRvbkNvcnItPnRyYW5zaWVudFBvc09mZnNldCAgICAgICAgPSBGUkFNRV9NSURETEVfU0xPVF8yMDQ4OwogICAgYnJlYWs7CiAgY2FzZSBOVU1CRVJfVElNRV9TTE9UU18xOTIwOgogICAgaFRvbkNvcnItPmxwY0xlbmd0aFswXSAgICAgICAgICAgICAgPSAxNSAtIExQQ19PUkRFUjsgLyogYmxvY2tMZW5ndGhbMF0gKi8KICAgIGhUb25Db3JyLT5scGNMZW5ndGhbMV0gICAgICAgICAgICAgID0gMTUgLSBMUENfT1JERVI7IC8qIGJsb2NrTGVuZ3RoWzBdICovCiAgICBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXMgICAgICAgICA9IE5PX09GX0VTVElNQVRFU19MQzsKICAgIGhUb25Db3JyLT5udW1iZXJPZkVzdGltYXRlc1BlckZyYW1lID0gc2JyQ2ZnLT5ub1FtZlNsb3RzIC8gMTU7CiAgICBoVG9uQ29yci0+ZnJhbWVTdGFydEluZGV4SW52ZkVzdCAgICA9IDA7CiAgICBoVG9uQ29yci0+dHJhbnNpZW50UG9zT2Zmc2V0ICAgICAgICA9IEZSQU1FX01JRERMRV9TTE9UXzE5MjA7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcmV0dXJuIC0xOwogIH0KCiAgaFRvbkNvcnItPmJ1ZmZlckxlbmd0aCAgICAgICAgICAgICAgPSBuQ29sczsKICBoVG9uQ29yci0+c3RlcFNpemUgICAgICAgICAgICAgICAgICA9IGhUb25Db3JyLT5scGNMZW5ndGhbMF0gKyBMUENfT1JERVI7IC8qIHN0ZXBTaXplWzBdIGltcGxpY2l0bHkgMC4gKi8KCiAgaFRvbkNvcnItPm5leHRTYW1wbGUgICAgICAgICAgICAgICAgPSBMUENfT1JERVI7IC8qIGZpcnN0U2FtcGxlICovCiAgaFRvbkNvcnItPm1vdmUgICAgICAgICAgICAgICAgICAgICAgPSBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXMgLSBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXNQZXJGcmFtZTsgICAgLyogTnVtYmVyIG9mIGVzdGltYXRlcyB0byBtb3ZlIHdoZW4gYnVmZmVyaW5nLiovCiAgaFRvbkNvcnItPnN0YXJ0SW5kZXhNYXRyaXggICAgICAgICAgPSBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXMgLSBoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXNQZXJGcmFtZTsgICAgLyogV2hlcmUgdG8gc3RvcmUgdGhlIGxhdGVzdCBlc3RpbWF0aW9ucyBpbiB0aGUgdG9uYWxpdHkgTWF0cml4LiovCiAgaFRvbkNvcnItPmZyYW1lU3RhcnRJbmRleCAgICAgICAgICAgPSAwOyAgICAgICAgICAgICAgICAgICAgICAvKiBXaGVyZSBpbiB0aGUgdG9uYWxpdHkgbWF0cml4IHRoZSBjdXJyZW50IGZyYW1lICh0byBiZSBzZW50IHRvIHRoZSBkZWNvZGVyKSBzdGFydHMuICovCiAgaFRvbkNvcnItPnByZXZUcmFuc2llbnRGbGFnID0gMDsKICBoVG9uQ29yci0+dHJhbnNpZW50TmV4dEZyYW1lID0gMDsKCiAgaFRvbkNvcnItPm5vUW1mQ2hhbm5lbHMgPSBub1FtZkNoYW5uZWxzOwoKICBmb3IgKGk9MDsgaTxoVG9uQ29yci0+bnVtYmVyT2ZFc3RpbWF0ZXM7IGkrKykgewogICAgRkRLbWVtY2xlYXIgKGhUb25Db3JyLT5xdW90YU1hdHJpeFtpXSAsIHNpemVvZihGSVhQX0RCTCkqbm9RbWZDaGFubmVscyk7CiAgICBGREttZW1jbGVhciAoaFRvbkNvcnItPnNpZ25NYXRyaXhbaV0gLCBzaXplb2YoSU5UKSpub1FtZkNoYW5uZWxzKTsKICB9CgogICAvKiBSZXNldCB0aGUgcGF0Y2guKi8KICBoVG9uQ29yci0+Z3VhcmQgPSAwOwogIGhUb25Db3JyLT5zaGlmdFN0YXJ0U2IgPSAxOwoKICBpZihyZXNldFBhdGNoKGhUb25Db3JyLAogICAgICAgICAgICAgICAgeHBvc0N0cmwsCiAgICAgICAgICAgICAgICBoaWdoQmFuZFN0YXJ0U2IsCiAgICAgICAgICAgICAgICB2X2tfbWFzdGVyLAogICAgICAgICAgICAgICAgbnVtTWFzdGVyLAogICAgICAgICAgICAgICAgZnMsCiAgICAgICAgICAgICAgICBub1FtZkNoYW5uZWxzKSkKICAgIHJldHVybigxKTsKCiAgaWYoRkRLc2JyRW5jX0luaXRTYnJOb2lzZUZsb29yRXN0aW1hdGUgKCZoVG9uQ29yci0+c2JyTm9pc2VGbG9vckVzdGltYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuYV9tYXhfbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlcUJhbmRUYWJsZVtMT10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblNmYltMT10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9pc2VCYW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2lzZUZsb29yT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTbG90cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VTcGVlY2hDb25maWcpKQogICAgcmV0dXJuKDEpOwoKCiAgaWYoRkRLc2JyRW5jX2luaXRJbnZGaWx0RGV0ZWN0b3IoJmhUb25Db3JyLT5zYnJJbnZGaWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPnNick5vaXNlRmxvb3JFc3RpbWF0ZS5mcmVxQmFuZFRhYmxlUW1mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPnNick5vaXNlRmxvb3JFc3RpbWF0ZS5ub05vaXNlQmFuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VTcGVlY2hDb25maWcpKQogICAgcmV0dXJuKDEpOwoKCgogIGlmKEZES3NickVuY19Jbml0U2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhUb25Db3JyLT5zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmJbSEldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9RbWZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUb25Db3JyLT5udW1iZXJPZkVzdGltYXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUb25Db3JyLT5tb3ZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRvbkNvcnItPm51bWJlck9mRXN0aW1hdGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnJDZmctPnNiclN5bnRheEZsYWdzKSkKICAgIHJldHVybigxKTsKCgoKICByZXR1cm4gKDApOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICByZXNldHMgdG9uYWxpdHkgY29ycmVjdGlvbiBwYXJhbWV0ZXIgbW9kdWxlLgoKCgogIFxyZXR1cm4gICBlcnJvckNvZGUsIG5vRXJyb3IgaWYgc3VjY2Vzc2Z1bC4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU5UCkZES3NickVuY19SZXNldFRvbkNvcnJQYXJhbUV4dHIoSEFORExFX1NCUl9UT05fQ09SUl9FU1QgaFRvbkNvcnIsIC8qITwgSGFuZGxlIHRvIFNCUl9UT05fQ09SUiBzdHJ1Y3QuICovCiAgICAgICAgICAgICAgICAgICAgICBJTlQgeHBvc2N0cmwsICAgICAgICAgICAgICAgICAgICAgLyohPCBEaWZmZXJlbnQgcGF0Y2ggbW9kZXMuICovCiAgICAgICAgICAgICAgICAgICAgICBJTlQgaGlnaEJhbmRTdGFydFNiLCAgICAgICAgICAgICAgLyohPCBTdGFydCBiYW5kIG9mIHRoZSBTQlIgcmFuZ2UuICovCiAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqdl9rX21hc3RlciwgICAgICAgIC8qITwgTWFzdGVyIGZyZXF1ZW5jeSB0YWJsZSBmcm9tIHdoaWNoIGFsbCBvdGhlciB0YWJsZSBhcmUgZGVyaXZlZC4qLwogICAgICAgICAgICAgICAgICAgICAgSU5UIG51bU1hc3RlciwgICAgICAgICAgICAgICAgICAgIC8qITwgTnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBtYXN0ZXIgdGFibGUuICovCiAgICAgICAgICAgICAgICAgICAgICBJTlQgZnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBTYW1wbGluZyBmcmVxdWVuY3kgKG9mIHRoZSBTQlIgcGFydCkuICovCiAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqKiBmcmVxQmFuZFRhYmxlLCAgIC8qITwgRnJlcXVlbmN5IGJhbmQgdGFibGUgZm9yIGxvdy1yZXMgYW5kIGhpZ2gtcmVzLiAqLwogICAgICAgICAgICAgICAgICAgICAgSU5UKiBuU2ZiLCAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgTnVtYmVyIG9mIGZyZXF1ZW5jeSBiYW5kcyAoaGlnLXJlcyBhbmQgbG93LXJlcykuICovCiAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9RbWZDaGFubmVscyAgICAgICAgICAgICAgICAgLyohPCBOdW1iZXIgb2YgUU1GIGNoYW5uZWxzLiAqLwogICAgICAgICAgICAgICAgICAgICAgKQp7CgogIC8qIFJlc2V0IHRoZSBwYXRjaC4qLwogIGhUb25Db3JyLT5ndWFyZCA9IDA7CiAgaFRvbkNvcnItPnNoaWZ0U3RhcnRTYiA9IDE7CgogIGlmKHJlc2V0UGF0Y2goaFRvbkNvcnIsCiAgICAgICAgICAgICAgICB4cG9zY3RybCwKICAgICAgICAgICAgICAgIGhpZ2hCYW5kU3RhcnRTYiwKICAgICAgICAgICAgICAgIHZfa19tYXN0ZXIsCiAgICAgICAgICAgICAgICBudW1NYXN0ZXIsCiAgICAgICAgICAgICAgICBmcywKICAgICAgICAgICAgICAgIG5vUW1mQ2hhbm5lbHMpKQogICAgcmV0dXJuKDEpOwoKCgogIC8qIFJlc2V0IHRoZSBub2lzZSBmbG9vciBlc3RpbWF0ZS4qLwogIGlmKEZES3NickVuY19yZXNldFNick5vaXNlRmxvb3JFc3RpbWF0ZSAoJmhUb25Db3JyLT5zYnJOb2lzZUZsb29yRXN0aW1hdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZXFCYW5kVGFibGVbTE9dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuU2ZiW0xPXSkpCiAgICByZXR1cm4oMSk7CgogIC8qCiAgUmVzZXQgdGhlIGludmVlcnNlIGZpbHRlcmVpbmcgZGV0ZWN0b3IuCiAgKi8KICBpZihGREtzYnJFbmNfcmVzZXRJbnZGaWx0RGV0ZWN0b3IoJmhUb25Db3JyLT5zYnJJbnZGaWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBoVG9uQ29yci0+c2JyTm9pc2VGbG9vckVzdGltYXRlLmZyZXFCYW5kVGFibGVRbWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUb25Db3JyLT5zYnJOb2lzZUZsb29yRXN0aW1hdGUubm9Ob2lzZUJhbmRzKSkKICAgIHJldHVybigxKTsKLyogUmVzZXQgdGhlIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdG9yLiAqLwogIGlmKEZES3NickVuY19SZXNldFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvciAoJmhUb25Db3JyLT5zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmJbSEldKSkKICAgIHJldHVybigxKTsKCiAgcmV0dXJuICgwKTsKfQoKCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICBEZWxldGVzIHRoZSB0b25hbGl0eSBjb3JyZWN0aW9uIHBhcmFtdGVyZSBtb2R1bGUuCgoKCiAgXHJldHVybiAgIG5vbmUKCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZApGREtzYnJFbmNfRGVsZXRlVG9uQ29yclBhcmFtRXh0ciAoSEFORExFX1NCUl9UT05fQ09SUl9FU1QgaFRvbkNvcnIpIC8qITwgSGFuZGxlIHRvIFNCUl9UT05fQ09SUiBzdHJ1Y3QuICovCnsKCiAgaWYgKGhUb25Db3JyKSB7CgogICBGcmVlUmFtX1Nicl9xdW90YU1hdHJpeChoVG9uQ29yci0+cXVvdGFNYXRyaXgpOwoKICAgRnJlZVJhbV9TYnJfc2lnbk1hdHJpeChoVG9uQ29yci0+c2lnbk1hdHJpeCk7CgogICBGREtzYnJFbmNfRGVsZXRlU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yICgmaFRvbkNvcnItPnNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvcik7CiAgfQp9Cg==