Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUcgQXVkaW8gRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIEF1dGhvcnM6ICAgICAgTS4gTXVsdHJ1cwogICBDb250ZW50cy9EZXNjcmlwdGlvbjogUFMgV3JhcHBlciwgRG93bm1peAoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInBzX21haW4uaCIKCgovKiBJbmNsdWRlcyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAicHNfY29uc3QuaCIKI2luY2x1ZGUgInBzX2JpdGVuYy5oIgoKI2luY2x1ZGUgInNicl9yYW0uaCIKCi8qLS0tLS0tLS0tLS0tLS0tIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyB2b2lkIHBzRmluZEJlc3RTY2FsaW5nKAogICAgICAgIEhBTkRMRV9QQVJBTUVUUklDX1NURVJFTyAgaFBhcmFtZXRyaWNTdGVyZW8sCiAgICAgICAgRklYUF9EQkwgICAgICAgICAgICAgICAgICpoeWJyaWREYXRhW0hZQlJJRF9GUkFNRVNJWkVdW01BWF9QU19DSEFOTkVMU11bMl0sCiAgICAgICAgVUNIQVIgICAgICAgICAgICAgICAgICAgICpkeW5CYW5kU2NhbGUsCiAgICAgICAgRklYUF9RTUYgICAgICAgICAgICAgICAgICptYXhCYW5kVmFsdWUsCiAgICAgICAgU0NIQVIgICAgICAgICAgICAgICAgICAgICpkbXhTY2FsZQogICAgICAgICk7CgovKi0tLS0tLS0tLS0tLS0gZnVuY3Rpb24gZGVmaW5pdGlvbnMgLS0tLS0tLS0tLS0tLS0tLSovCkZES19QU0VOQ19FUlJPUiBQU0VuY19DcmVhdGUoCiAgICAgICAgSEFORExFX1BBUkFNRVRSSUNfU1RFUkVPICpwaFBhcmFtZXRyaWNTdGVyZW8KICAgICAgICApCnsKICBGREtfUFNFTkNfRVJST1IgZXJyb3IgPSBQU0VOQ19PSzsKCiAgaWYgKHBoUGFyYW1ldHJpY1N0ZXJlbz09TlVMTCkgewogICAgZXJyb3IgPSBQU0VOQ19JTlZBTElEX0hBTkRMRTsKICB9CiAgZWxzZSB7CiAgICBpbnQgaTsKICAgIEhBTkRMRV9QQVJBTUVUUklDX1NURVJFTyBoUGFyYW1ldHJpY1N0ZXJlbyA9IE5VTEw7CgogICAgaWYgKE5VTEw9PShoUGFyYW1ldHJpY1N0ZXJlbyA9IEdldFJhbV9QYXJhbVN0ZXJlbygpKSkgewogICAgICBlcnJvciA9IFBTRU5DX01FTU9SWV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQogICAgRkRLbWVtY2xlYXIoaFBhcmFtZXRyaWNTdGVyZW8sIHNpemVvZihQQVJBTUVUUklDX1NURVJFTykpOwoKICAgIGlmIChQU0VOQ19PSyAhPSAoZXJyb3IgPSBGREtzYnJFbmNfQ3JlYXRlUFNFbmNvZGUoJmhQYXJhbWV0cmljU3RlcmVvLT5oUHNFbmNvZGUpKSkgewogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgZm9yIChpPTA7IGk8TUFYX1BTX0NIQU5ORUxTOyBpKyspIHsKICAgICAgaWYgKEZES2h5YnJpZEFuYWx5c2lzT3BlbigKICAgICAgICAgICAgJmhQYXJhbWV0cmljU3RlcmVvLT5mZGtIeWJBbmFGaWx0ZXJbaV0sCiAgICAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+X19zdGF0aWNIeWJBbmFTdGF0ZXNMRltpXSwKICAgICAgICAgICAgIHNpemVvZihoUGFyYW1ldHJpY1N0ZXJlby0+X19zdGF0aWNIeWJBbmFTdGF0ZXNMRltpXSksCiAgICAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+X19zdGF0aWNIeWJBbmFTdGF0ZXNIRltpXSwKICAgICAgICAgICAgIHNpemVvZihoUGFyYW1ldHJpY1N0ZXJlby0+X19zdGF0aWNIeWJBbmFTdGF0ZXNIRltpXSkKICAgICAgICAgICAgICkgIT0wICkKICAgICAgewogICAgICAgIGVycm9yID0gUFNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgfQoKICAgICpwaFBhcmFtZXRyaWNTdGVyZW8gPSBoUGFyYW1ldHJpY1N0ZXJlbzsgLyogcmV0dXJuIGFsbG9jYXRlZCBoYW5kbGUgKi8KICB9CmJhaWw6CiAgcmV0dXJuIGVycm9yOwp9CgpGREtfUFNFTkNfRVJST1IgUFNFbmNfSW5pdCgKICAgICAgICBIQU5ETEVfUEFSQU1FVFJJQ19TVEVSRU8gIGhQYXJhbWV0cmljU3RlcmVvLAogICAgICAgIGNvbnN0IEhBTkRMRV9QU0VOQ19DT05GSUcgaFBzRW5jQ29uZmlnLAogICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbm9RbWZTbG90cywKICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5vUW1mQmFuZHMKICAgICAgICxVQ0hBUiAgICAgICAgICAgICAgICAgICAgKmR5bmFtaWNfUkFNCiAgICAgICAgKQp7CiAgRkRLX1BTRU5DX0VSUk9SIGVycm9yID0gUFNFTkNfT0s7CgogIGlmICggKE5VTEw9PWhQYXJhbWV0cmljU3RlcmVvKSB8fCAoTlVMTD09aFBzRW5jQ29uZmlnKSApIHsKICAgIGVycm9yID0gUFNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgfQogIGVsc2UgewogICAgaW50IGNoLCBpOwoKICAgIGhQYXJhbWV0cmljU3RlcmVvLT5pbml0UFMgPSAxOwogICAgaFBhcmFtZXRyaWNTdGVyZW8tPm5vUW1mU2xvdHMgPSBub1FtZlNsb3RzOwogICAgaFBhcmFtZXRyaWNTdGVyZW8tPm5vUW1mQmFuZHMgPSBub1FtZkJhbmRzOwoKICAgIC8qIGNsZWFyIGRlbGF5IGxpbmVzICovCiAgICBGREttZW1jbGVhcihoUGFyYW1ldHJpY1N0ZXJlby0+cW1mRGVsYXlMaW5lcywgc2l6ZW9mKGhQYXJhbWV0cmljU3RlcmVvLT5xbWZEZWxheUxpbmVzKSk7CgogICAgaFBhcmFtZXRyaWNTdGVyZW8tPnFtZkRlbGF5U2NhbGUgPSBGUkFDVF9CSVRTLTE7CgogICAgLyogY3JlYXRlIGNvbmZpZ3VyYXRpb24gZm9yIGh5YnJpZCBmaWx0ZXIgYmFuayAqLwogICAgZm9yIChjaD0wOyBjaDxNQVhfUFNfQ0hBTk5FTFM7IGNoKyspIHsKICAgICAgRkRLaHlicmlkQW5hbHlzaXNJbml0KAogICAgICAgICAgICAmaFBhcmFtZXRyaWNTdGVyZW8tPmZka0h5YkFuYUZpbHRlcltjaF0sCiAgICAgICAgICAgICBUSFJFRV9UT19URU4sCiAgICAgICAgICAgICBRTUZfQ0hBTk5FTFMsCiAgICAgICAgICAgICBRTUZfQ0hBTk5FTFMsCiAgICAgICAgICAgICAxCiAgICAgICAgICAgICApOwogICAgfSAvKiBjaCAqLwoKICAgIEZES2h5YnJpZFN5bnRoZXNpc0luaXQoCiAgICAgICAgICAmaFBhcmFtZXRyaWNTdGVyZW8tPmZka0h5YlN5bkZpbHRlciwKICAgICAgICAgICBUSFJFRV9UT19URU4sCiAgICAgICAgICAgUU1GX0NIQU5ORUxTLAogICAgICAgICAgIFFNRl9DSEFOTkVMUwogICAgICAgICAgICk7CgogICAgLyogZGV0ZXJtaW5lIGF2ZXJhZ2UgZGVsYXkgKi8KICAgIGhQYXJhbWV0cmljU3RlcmVvLT5wc0RlbGF5ID0gKEhZQlJJRF9GSUxURVJfREVMQVkqaFBhcmFtZXRyaWNTdGVyZW8tPm5vUW1mQmFuZHMpOwoKICAgIGlmICggKGhQc0VuY0NvbmZpZy0+bWF4RW52ZWxvcGVzIDwgUFNFTkNfTkVOVl8xKSB8fCAoaFBzRW5jQ29uZmlnLT5tYXhFbnZlbG9wZXMgPiBQU0VOQ19ORU5WX01BWCkgKSB7CiAgICAgIGhQc0VuY0NvbmZpZy0+bWF4RW52ZWxvcGVzID0gUFNFTkNfTkVOVl9ERUZBVUxUOwogICAgfQogICAgaFBhcmFtZXRyaWNTdGVyZW8tPm1heEVudmVsb3BlcyA9IGhQc0VuY0NvbmZpZy0+bWF4RW52ZWxvcGVzOwoKICAgIGlmIChQU0VOQ19PSyAhPSAoZXJyb3IgPSBGREtzYnJFbmNfSW5pdFBTRW5jb2RlKGhQYXJhbWV0cmljU3RlcmVvLT5oUHNFbmNvZGUsIChQU19CQU5EUykgaFBzRW5jQ29uZmlnLT5uU3RlcmVvQmFuZHMsIGhQc0VuY0NvbmZpZy0+aWlkUXVhbnRFcnJvclRocmVzaG9sZCkpKXsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGZvciAoY2ggPSAwOyBjaDxNQVhfUFNfQ0hBTk5FTFM7IGNoICsrKSB7CiAgICAgIEZJWFBfREJMICpwRHluUmVhbCA9IEdldFJhbV9TYnJfZW52UkJ1ZmZlciAoY2gsIGR5bmFtaWNfUkFNKTsKICAgICAgRklYUF9EQkwgKnBEeW5JbWFnID0gR2V0UmFtX1Nicl9lbnZJQnVmZmVyIChjaCwgZHluYW1pY19SQU0pOwoKICAgICAgZm9yIChpPTA7IGk8SFlCUklEX0ZSQU1FU0laRTsgaSsrKSB7CiAgICAgICAgaFBhcmFtZXRyaWNTdGVyZW8tPnBIeWJyaWREYXRhW2krSFlCUklEX1JFQURfT0ZGU0VUXVtjaF1bMF0gPSAmcER5blJlYWxbaSpNQVhfSFlCUklEX0JBTkRTXTsKICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbaStIWUJSSURfUkVBRF9PRkZTRVRdW2NoXVsxXSA9ICZwRHluSW1hZ1tpKk1BWF9IWUJSSURfQkFORFNdOzsKICAgICAgfQoKICAgICAgZm9yIChpPTA7IGk8SFlCUklEX1JFQURfT0ZGU0VUOyBpKyspIHsKICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbaV1bY2hdWzBdID0gaFBhcmFtZXRyaWNTdGVyZW8tPl9fc3RhdGljSHlicmlkRGF0YVtpXVtjaF1bMF07CiAgICAgICAgaFBhcmFtZXRyaWNTdGVyZW8tPnBIeWJyaWREYXRhW2ldW2NoXVsxXSA9IGhQYXJhbWV0cmljU3RlcmVvLT5fX3N0YXRpY0h5YnJpZERhdGFbaV1bY2hdWzFdOwogICAgICB9CiAgICB9IC8qIGNoICovCgogICAgLyogY2xlYXIgc3RhdGljIGh5YnJpZCBidWZmZXIgKi8KICAgIEZES21lbWNsZWFyKGhQYXJhbWV0cmljU3RlcmVvLT5fX3N0YXRpY0h5YnJpZERhdGEsIHNpemVvZihoUGFyYW1ldHJpY1N0ZXJlby0+X19zdGF0aWNIeWJyaWREYXRhKSk7CgogICAgLyogY2xlYXIgYnMgYnVmZmVyICovCiAgICBGREttZW1jbGVhcihoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXQsIHNpemVvZihoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXQpKTsKCiAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXRbMF0uZW5hYmxlUFNIZWFkZXIgPSAxOyAvKiB3cml0ZSBwcyBoZWFkZXIgaW4gZmlyc3QgZnJhbWUgKi8KCiAgICAvKiBjbGVhciBzY2FsaW5nIGJ1ZmZlciAqLwogICAgRkRLbWVtY2xlYXIoaFBhcmFtZXRyaWNTdGVyZW8tPmR5bkJhbmRTY2FsZSwgc2l6ZW9mKFVDSEFSKSpQU19NQVhfQkFORFMpOwogICAgRkRLbWVtY2xlYXIoaFBhcmFtZXRyaWNTdGVyZW8tPm1heEJhbmRWYWx1ZSwgc2l6ZW9mKEZJWFBfUU1GKSpQU19NQVhfQkFORFMpOwoKICB9IC8qIHZhbGlkIGhhbmRsZSAqLwpiYWlsOgogIHJldHVybiBlcnJvcjsKfQoKCkZES19QU0VOQ19FUlJPUiBQU0VuY19EZXN0cm95KAogICAgICAgIEhBTkRMRV9QQVJBTUVUUklDX1NURVJFTyAqcGhQYXJhbWV0cmljU3RlcmVvCiAgICAgICAgKQp7CiAgRkRLX1BTRU5DX0VSUk9SIGVycm9yID0gUFNFTkNfT0s7CgogIGlmIChOVUxMIT1waFBhcmFtZXRyaWNTdGVyZW8pIHsKICAgIEhBTkRMRV9QQVJBTUVUUklDX1NURVJFTyBoUGFyYW1ldHJpY1N0ZXJlbyA9ICpwaFBhcmFtZXRyaWNTdGVyZW87CiAgICBpZihoUGFyYW1ldHJpY1N0ZXJlbyAhPSBOVUxMKXsKICAgICAgRkRLc2JyRW5jX0Rlc3Ryb3lQU0VuY29kZSgmaFBhcmFtZXRyaWNTdGVyZW8tPmhQc0VuY29kZSk7CiAgICAgIEZyZWVSYW1fUGFyYW1TdGVyZW8ocGhQYXJhbWV0cmljU3RlcmVvKTsKICAgIH0KICB9CgogIHJldHVybiBlcnJvcjsKfQoKc3RhdGljIEZES19QU0VOQ19FUlJPUiBFeHRyYWN0UFNQYXJhbWV0ZXJzKAogICAgICAgIEhBTkRMRV9QQVJBTUVUUklDX1NURVJFTyAgaFBhcmFtZXRyaWNTdGVyZW8sCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICAgICBzZW5kSGVhZGVyLAogICAgICAgIEZJWFBfREJMICAgICAgICAgICAgICAgICAqaHlicmlkRGF0YVtIWUJSSURfRlJBTUVTSVpFXVtNQVhfUFNfQ0hBTk5FTFNdWzJdCiAgICAgICAgKQp7CiAgRkRLX1BTRU5DX0VSUk9SIGVycm9yID0gUFNFTkNfT0s7CgogIGlmIChoUGFyYW1ldHJpY1N0ZXJlbyA9PSBOVUxMKSB7CiAgICBlcnJvciA9IFBTRU5DX0lOVkFMSURfSEFORExFOwogIH0KICBlbHNlIHsKICAgIC8qIGNhbGwgcHMgZW5jb2RlIGZ1bmN0aW9uICovCiAgICBpZiAoaFBhcmFtZXRyaWNTdGVyZW8tPmluaXRQUyl7CiAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5wc091dFsxXSA9IGhQYXJhbWV0cmljU3RlcmVvLT5wc091dFswXTsKICAgIH0KICAgIGhQYXJhbWV0cmljU3RlcmVvLT5wc091dFswXSA9IGhQYXJhbWV0cmljU3RlcmVvLT5wc091dFsxXTsKCiAgICBpZiAoUFNFTkNfT0sgIT0gKGVycm9yID0gRkRLc2JyRW5jX1BTRW5jb2RlKAogICAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+aFBzRW5jb2RlLAogICAgICAgICAgICZoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXRbMV0sCiAgICAgICAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5keW5CYW5kU2NhbGUsCiAgICAgICAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5tYXhFbnZlbG9wZXMsCiAgICAgICAgICAgIGh5YnJpZERhdGEsCiAgICAgICAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5ub1FtZlNsb3RzLAogICAgICAgICAgICBzZW5kSGVhZGVyKSkpCiAgICB7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBpZiAoaFBhcmFtZXRyaWNTdGVyZW8tPmluaXRQUykgewogICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXRbMF0gPSBoUGFyYW1ldHJpY1N0ZXJlby0+cHNPdXRbMV07CiAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5pbml0UFMgPSAwOwogICAgfQogIH0KYmFpbDoKICByZXR1cm4gZXJyb3I7Cn0KCgpzdGF0aWMgRkRLX1BTRU5DX0VSUk9SIERvd25taXhQU1FtZkRhdGEoCiAgICAgICBIQU5ETEVfUEFSQU1FVFJJQ19TVEVSRU8gIGhQYXJhbWV0cmljU3RlcmVvLAogICAgICAgSEFORExFX1FNRl9GSUxURVJfQkFOSyAgICBzYnJTeW50aFFtZiwKICAgICAgIEZJWFBfUU1GICAgICAgICoqUkVTVFJJQ1QgbWl4UmVhbFFtZkRhdGEsCiAgICAgICBGSVhQX1FNRiAgICAgICAqKlJFU1RSSUNUIG1peEltYWdRbWZEYXRhLAogICAgICAgSU5UX1BDTSAgICAgICAgICAgICAgICAgICpkb3duc2FtcGxlZE91dFNpZ25hbCwKICAgICAgIEZJWFBfREJMICAgICAgICAgICAgICAgICAqaHlicmlkRGF0YVtIWUJSSURfRlJBTUVTSVpFXVtNQVhfUFNfQ0hBTk5FTFNdWzJdLAogICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBub1FtZlNsb3RzLAogICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBwc1FtZlNjYWxlW01BWF9QU19DSEFOTkVMU10sCiAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgKnFtZlNjYWxlCiAgICAgICApCnsKICBGREtfUFNFTkNfRVJST1IgZXJyb3IgPSBQU0VOQ19PSzsKCiAgaWYoaFBhcmFtZXRyaWNTdGVyZW8gPT0gTlVMTCl7CiAgICBlcnJvciA9IFBTRU5DX0lOVkFMSURfSEFORExFOwogIH0KICBlbHNlIHsKICAgIGludCBuLCBrOwogICAgQ19BQUxMT0NfU0NSQVRDSF9TVEFSVChwV29ya0J1ZmZlciwgRklYUF9RTUYsIDIqUU1GX0NIQU5ORUxTKQoKICAgIC8qIGRlZmluZSBzY2FsaW5ncyAqLwogICAgaW50IGR5blFtZlNjYWxlID0gZml4TWF4KDAsIGhQYXJhbWV0cmljU3RlcmVvLT5kbXhTY2FsZS0xKTsgLyogc2NhbGUgb25lIGJpdCBtb3JlIGZvciBhZGRpdGlvbiBvZiBsZWZ0IGFuZCByaWdodCAqLwogICAgaW50IGRvd25taXhTY2FsZSA9IHBzUW1mU2NhbGVbMF0gLSBkeW5RbWZTY2FsZTsKICAgIGNvbnN0IEZJWFBfREJMIG1heFN0ZXJlb1NjYWxlRmFjdG9yID0gTUFYVkFMX0RCTDsgLyogMi5mLzIuZiAqLwoKICAgIGZvciAobiA9IDA7IG48bm9RbWZTbG90czsgbisrKSB7CgogICAgICBGSVhQX0RCTCB0bXBIeWJyaWRbMl1bTUFYX0hZQlJJRF9CQU5EU107CgogICAgICBmb3IoayA9IDA7IGs8NzE7IGsrKyl7CiAgICAgICAgICBpbnQgZHluU2NhbGUsIHNjOyAvKiBzY2FsaW5nICovCiAgICAgICAgICBGSVhQX1FNRiB0bXBMZWZ0UmVhbCwgdG1wUmlnaHRSZWFsLCB0bXBMZWZ0SW1hZywgdG1wUmlnaHRJbWFnOwogICAgICAgICAgRklYUF9EQkwgdG1wU2NhbGVGYWN0b3IsIHN0ZXJlb1NjYWxlRmFjdG9yOwoKICAgICAgICAgIHRtcExlZnRSZWFsICA9IGh5YnJpZERhdGFbbl1bMF1bMF1ba107CiAgICAgICAgICB0bXBMZWZ0SW1hZyAgPSBoeWJyaWREYXRhW25dWzBdWzFdW2tdOwogICAgICAgICAgdG1wUmlnaHRSZWFsID0gaHlicmlkRGF0YVtuXVsxXVswXVtrXTsKICAgICAgICAgIHRtcFJpZ2h0SW1hZyA9IGh5YnJpZERhdGFbbl1bMV1bMV1ba107CgogICAgICAgICAgc2MgPSBmaXhNYXgoMCxDbnRMZWFkaW5nWmVyb3MoIGZpeE1heChmaXhNYXgoZml4cF9hYnModG1wTGVmdFJlYWwpLGZpeHBfYWJzKHRtcExlZnRJbWFnKSksZml4TWF4KGZpeHBfYWJzKHRtcFJpZ2h0UmVhbCksZml4cF9hYnModG1wUmlnaHRJbWFnKSkpICktMik7CgogICAgICAgICAgdG1wTGVmdFJlYWwgIDw8PSBzYzsgdG1wTGVmdEltYWcgIDw8PSBzYzsKICAgICAgICAgIHRtcFJpZ2h0UmVhbCA8PD0gc2M7IHRtcFJpZ2h0SW1hZyA8PD0gc2M7CiAgICAgICAgICBkeW5TY2FsZSA9IGZpeE1pbihzYy1keW5RbWZTY2FsZSxERlJBQ1RfQklUUy0xKTsKCiAgICAgICAgICAvKiBjYWxjIHN0ZXJlbyBzY2FsZSBmYWN0b3IgdG8gYXZvaWQgbG9zcyBvZiBlbmVyZ3kgaW4gYmFuZHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgIC8qIHN0ZXJlbyBzY2FsZSBmYWN0b3IgPSBtaW4oMi4wZiwgc3FydCggKGFicyhsKGssIG4pXjIgKyBhYnMocihrLCBuKV4yICkpKS8oMC41ZiphYnMobChrLCBuKSArIHIoaywgbikpKSApKSAqLwogICAgICAgICAgc3RlcmVvU2NhbGVGYWN0b3IgPSBmUG93MkRpdjIodG1wTGVmdFJlYWwpICArIGZQb3cyRGl2Mih0bXBMZWZ0SW1hZykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZlBvdzJEaXYyKHRtcFJpZ2h0UmVhbCkgKyBmUG93MkRpdjIodG1wUmlnaHRJbWFnKSA7CgogICAgICAgICAgLyogbWlnaHQgYmUgdGhhdCB0bXBTY2FsZUZhY3RvciBiZWNvbWVzIG5lZ2F0aXZlLCBzbyBmYWJzKC4pICovCiAgICAgICAgICB0bXBTY2FsZUZhY3RvciAgICA9IGZpeHBfYWJzKHN0ZXJlb1NjYWxlRmFjdG9yICsgZk11bHQodG1wTGVmdFJlYWwsdG1wUmlnaHRSZWFsKSArIGZNdWx0KHRtcExlZnRJbWFnLHRtcFJpZ2h0SW1hZykpOwoKICAgICAgICAgIC8qIG1pbigyLjBmLCBzcXJ0KHN0ZXJlb1NjYWxlRmFjdG9yLygwLjVmKnRtcFNjYWxlRmFjdG9yKSkpICAqLwogICAgICAgICAgaWYgKCAoc3RlcmVvU2NhbGVGYWN0b3I+PjEpIDwgZk11bHQobWF4U3RlcmVvU2NhbGVGYWN0b3IsdG1wU2NhbGVGYWN0b3IpICkgewoKICAgICAgICAgICAgICBpbnQgc2NfbnVtICAgPSBDb3VudExlYWRpbmdCaXRzKHN0ZXJlb1NjYWxlRmFjdG9yKSA7CiAgICAgICAgICAgICAgaW50IHNjX2RlbnVtID0gQ291bnRMZWFkaW5nQml0cyh0bXBTY2FsZUZhY3RvcikgOwogICAgICAgICAgICAgIHNjICAgICAgID0gLShzY19udW0tc2NfZGVudW0pOwoKICAgICAgICAgICAgICB0bXBTY2FsZUZhY3RvciA9IHNjaHVyX2Rpdigoc3RlcmVvU2NhbGVGYWN0b3I8PChzY19udW0pKT4+MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wU2NhbGVGYWN0b3I8PHNjX2RlbnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxNikgOwoKICAgICAgICAgICAgICAvKiBwcmV2ZW50IG9kZCBzY2FsaW5nIGZvciBuZXh0IHNxcnQgY2FsY3VsYXRpb24gKi8KICAgICAgICAgICAgICBpZiAoc2MmMHgxKSB7CiAgICAgICAgICAgICAgICBzYysrOwogICAgICAgICAgICAgICAgdG1wU2NhbGVGYWN0b3I+Pj0xOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBzdGVyZW9TY2FsZUZhY3RvciA9IHNxcnRGaXhwKHRtcFNjYWxlRmFjdG9yKTsKICAgICAgICAgICAgICBzdGVyZW9TY2FsZUZhY3RvciA8PD0gKHNjPj4xKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIHN0ZXJlb1NjYWxlRmFjdG9yID0gbWF4U3RlcmVvU2NhbGVGYWN0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgLyogd3JpdGUgZGF0YSB0byBoeWJyaWQgb3V0cHV0ICovCiAgICAgICAgICB0bXBIeWJyaWRbMF1ba10gPSBmTXVsdERpdjIoc3RlcmVvU2NhbGVGYWN0b3IsIChGSVhQX1FNRikodG1wTGVmdFJlYWwgKyB0bXBSaWdodFJlYWwpKT4+ZHluU2NhbGU7CiAgICAgICAgICB0bXBIeWJyaWRbMV1ba10gPSBmTXVsdERpdjIoc3RlcmVvU2NhbGVGYWN0b3IsIChGSVhQX1FNRikodG1wTGVmdEltYWcgKyB0bXBSaWdodEltYWcpKT4+ZHluU2NhbGU7CgogICAgICB9IC8qIGh5YnJpZCBiYW5kcyAtIGsgKi8KCiAgICAgIEZES2h5YnJpZFN5bnRoZXNpc0FwcGx5KAogICAgICAgICAgICAmaFBhcmFtZXRyaWNTdGVyZW8tPmZka0h5YlN5bkZpbHRlciwKICAgICAgICAgICAgIHRtcEh5YnJpZFswXSwKICAgICAgICAgICAgIHRtcEh5YnJpZFsxXSwKICAgICAgICAgICAgIG1peFJlYWxRbWZEYXRhW25dLAogICAgICAgICAgICAgbWl4SW1hZ1FtZkRhdGFbbl0pOwoKICAgICAgcW1mU3ludGhlc2lzRmlsdGVyaW5nU2xvdCgKICAgICAgICAgICAgc2JyU3ludGhRbWYsCiAgICAgICAgICAgIG1peFJlYWxRbWZEYXRhW25dLAogICAgICAgICAgICBtaXhJbWFnUW1mRGF0YVtuXSwKICAgICAgICAgICAgZG93bm1peFNjYWxlLTcsCiAgICAgICAgICAgIGRvd25taXhTY2FsZS03LAogICAgICAgICAgICBkb3duc2FtcGxlZE91dFNpZ25hbCsobipzYnJTeW50aFFtZi0+bm9fY2hhbm5lbHMpLAogICAgICAgICAgICAxLAogICAgICAgICAgICBwV29ya0J1ZmZlcik7CgogICAgfSAvKiBzbG90cyAqLwoKICAgICpxbWZTY2FsZSA9IC1kb3dubWl4U2NhbGUgKyA3OwoKICAgIENfQUFMTE9DX1NDUkFUQ0hfRU5EKHBXb3JrQnVmZmVyLCBGSVhQX1FNRiwgMipRTUZfQ0hBTk5FTFMpCgogIHsKICAgIGNvbnN0IElOVCBub1FtZlNsb3RzMiA9IGhQYXJhbWV0cmljU3RlcmVvLT5ub1FtZlNsb3RzPj4xOwogICAgY29uc3QgaW50IG5vUW1mQmFuZHMgID0gaFBhcmFtZXRyaWNTdGVyZW8tPm5vUW1mQmFuZHM7CgogICAgSU5UIHNjYWxlLCBpLCBqLCBzbG90T2Zmc2V0OwoKICAgIEZJWFBfUU1GIHRtcFsyXVtRTUZfQ0hBTk5FTFNdOwoKICAgIGZvciAoaT0wOyBpPG5vUW1mU2xvdHMyOyBpKyspIHsKICAgICAgRkRLbWVtY3B5KHRtcFswXSwgaFBhcmFtZXRyaWNTdGVyZW8tPnFtZkRlbGF5TGluZXNbMF1baV0sIG5vUW1mQmFuZHMqc2l6ZW9mKEZJWFBfUU1GKSk7CiAgICAgIEZES21lbWNweSh0bXBbMV0sIGhQYXJhbWV0cmljU3RlcmVvLT5xbWZEZWxheUxpbmVzWzFdW2ldLCBub1FtZkJhbmRzKnNpemVvZihGSVhQX1FNRikpOwoKICAgICAgRkRLbWVtY3B5KGhQYXJhbWV0cmljU3RlcmVvLT5xbWZEZWxheUxpbmVzWzBdW2ldLCBtaXhSZWFsUW1mRGF0YVtpK25vUW1mU2xvdHMyXSwgbm9RbWZCYW5kcypzaXplb2YoRklYUF9RTUYpKTsKICAgICAgRkRLbWVtY3B5KGhQYXJhbWV0cmljU3RlcmVvLT5xbWZEZWxheUxpbmVzWzFdW2ldLCBtaXhJbWFnUW1mRGF0YVtpK25vUW1mU2xvdHMyXSwgbm9RbWZCYW5kcypzaXplb2YoRklYUF9RTUYpKTsKCiAgICAgIEZES21lbWNweShtaXhSZWFsUW1mRGF0YVtpK25vUW1mU2xvdHMyXSwgbWl4UmVhbFFtZkRhdGFbaV0sIG5vUW1mQmFuZHMqc2l6ZW9mKEZJWFBfUU1GKSk7CiAgICAgIEZES21lbWNweShtaXhJbWFnUW1mRGF0YVtpK25vUW1mU2xvdHMyXSwgbWl4SW1hZ1FtZkRhdGFbaV0sIG5vUW1mQmFuZHMqc2l6ZW9mKEZJWFBfUU1GKSk7CgogICAgICBGREttZW1jcHkobWl4UmVhbFFtZkRhdGFbaV0sIHRtcFswXSwgbm9RbWZCYW5kcypzaXplb2YoRklYUF9RTUYpKTsKICAgICAgRkRLbWVtY3B5KG1peEltYWdRbWZEYXRhW2ldLCB0bXBbMV0sIG5vUW1mQmFuZHMqc2l6ZW9mKEZJWFBfUU1GKSk7CiAgICB9CgogICAgaWYgKGhQYXJhbWV0cmljU3RlcmVvLT5xbWZEZWxheVNjYWxlID4gKnFtZlNjYWxlKSB7CiAgICAgIHNjYWxlID0gaFBhcmFtZXRyaWNTdGVyZW8tPnFtZkRlbGF5U2NhbGUgLSAqcW1mU2NhbGU7CiAgICAgIHNsb3RPZmZzZXQgPSAwOwogICAgfQogICAgZWxzZSB7CiAgICAgIHNjYWxlID0gKnFtZlNjYWxlIC0gaFBhcmFtZXRyaWNTdGVyZW8tPnFtZkRlbGF5U2NhbGU7CiAgICAgIHNsb3RPZmZzZXQgPSBub1FtZlNsb3RzMjsKICAgIH0KCiAgICBmb3IgKGk9MDsgaTxub1FtZlNsb3RzMjsgaSsrKSB7CiAgICAgIGZvciAoaj0wOyBqPG5vUW1mQmFuZHM7IGorKykgewogICAgICAgIG1peFJlYWxRbWZEYXRhW2krc2xvdE9mZnNldF1bal0gPj49IHNjYWxlOwogICAgICAgIG1peEltYWdRbWZEYXRhW2krc2xvdE9mZnNldF1bal0gPj49IHNjYWxlOwogICAgICB9CiAgICB9CgogICAgc2NhbGUgPSAqcW1mU2NhbGU7CiAgICAqcW1mU2NhbGUgPSBGREttaW4oKnFtZlNjYWxlLCBoUGFyYW1ldHJpY1N0ZXJlby0+cW1mRGVsYXlTY2FsZSk7CiAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cW1mRGVsYXlTY2FsZSA9IHNjYWxlOwogIH0KCiAgfSAvKiB2YWxpZCBoYW5kbGUgKi8KCiAgcmV0dXJuIGVycm9yOwp9CgoKSU5UIEZES3NickVuY19QU0VuY19Xcml0ZVBTRGF0YSgKICAgICAgICBIQU5ETEVfUEFSQU1FVFJJQ19TVEVSRU8gIGhQYXJhbWV0cmljU3RlcmVvLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgICAgaEJpdHN0cmVhbQogICAgICAgICkKewogIHJldHVybiAoIChoUGFyYW1ldHJpY1N0ZXJlbyE9TlVMTCkgPyBGREtzYnJFbmNfV3JpdGVQU0JpdHN0cmVhbSgmaFBhcmFtZXRyaWNTdGVyZW8tPnBzT3V0WzBdLCBoQml0c3RyZWFtKSA6IDAgKTsKfQoKCkZES19QU0VOQ19FUlJPUiBGREtzYnJFbmNfUFNFbmNfUGFyYW1ldHJpY1N0ZXJlb1Byb2Nlc3NpbmcoCiAgICAgICAgSEFORExFX1BBUkFNRVRSSUNfU1RFUkVPICBoUGFyYW1ldHJpY1N0ZXJlbywKICAgICAgICBJTlRfUENNICAgICAgICAgICAgICAgICAgKnNhbXBsZXNbMl0sCiAgICAgICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICB0aW1lSW5TdHJpZGUsCiAgICAgICAgUU1GX0ZJTFRFUl9CQU5LICAgICAgICAgKipoUW1mQW5hbHlzaXMsCiAgICAgICAgRklYUF9RTUYgKipSRVNUUklDVCAgICAgICBkb3dubWl4ZWRSZWFsUW1mRGF0YSwKICAgICAgICBGSVhQX1FNRiAqKlJFU1RSSUNUICAgICAgIGRvd25taXhlZEltYWdRbWZEYXRhLAogICAgICAgIElOVF9QQ00gICAgICAgICAgICAgICAgICAqZG93bnNhbXBsZWRPdXRTaWduYWwsCiAgICAgICAgSEFORExFX1FNRl9GSUxURVJfQkFOSyAgICBzYnJTeW50aFFtZiwKICAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgKnFtZlNjYWxlLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgICAgc2VuZEhlYWRlcgogICAgICAgICkKewogIEZES19QU0VOQ19FUlJPUiBlcnJvciA9IFBTRU5DX09LOwogIElOVCBwc1FtZlNjYWxlW01BWF9QU19DSEFOTkVMU10gPSB7MH07CiAgaW50IHBzQ2gsIGk7CiAgQ19BQUxMT0NfU0NSQVRDSF9TVEFSVChwV29ya0J1ZmZlciwgRklYUF9RTUYsIDQqUU1GX0NIQU5ORUxTKQoKICBmb3IgKHBzQ2ggPSAwOyBwc0NoPE1BWF9QU19DSEFOTkVMUzsgcHNDaCArKykgewoKICAgIGZvciAoaSA9IDA7IGkgPCBoUW1mQW5hbHlzaXNbcHNDaF0tPm5vX2NvbDsgaSsrKSB7CgogICAgICBxbWZBbmFseXNpc0ZpbHRlcmluZ1Nsb3QoCiAgICAgICAgICBoUW1mQW5hbHlzaXNbcHNDaF0sCiAgICAgICAgICZwV29ya0J1ZmZlclsyKlFNRl9DSEFOTkVMU10sIC8qIHFtZlJlYWxbUU1GX0NIQU5ORUxTXSAqLwogICAgICAgICAmcFdvcmtCdWZmZXJbMypRTUZfQ0hBTk5FTFNdLCAvKiBxbWZJbWFnW1FNRl9DSEFOTkVMU10gKi8KICAgICAgICAgIHNhbXBsZXNbcHNDaF0raSooaFFtZkFuYWx5c2lzW3BzQ2hdLT5ub19jaGFubmVscyp0aW1lSW5TdHJpZGUpLAogICAgICAgICAgdGltZUluU3RyaWRlLAogICAgICAgICAmcFdvcmtCdWZmZXJbMCpRTUZfQ0hBTk5FTFNdICAvKiBxbWYgd29ya2J1ZmZlciAyKlFNRl9DSEFOTkVMUyAqLwogICAgICAgICAgKTsKCiAgICAgIEZES2h5YnJpZEFuYWx5c2lzQXBwbHkoCiAgICAgICAgICZoUGFyYW1ldHJpY1N0ZXJlby0+ZmRrSHliQW5hRmlsdGVyW3BzQ2hdLAogICAgICAgICAmcFdvcmtCdWZmZXJbMipRTUZfQ0hBTk5FTFNdLCAgLyogcW1mUmVhbFtRTUZfQ0hBTk5FTFNdICovCiAgICAgICAgICZwV29ya0J1ZmZlclszKlFNRl9DSEFOTkVMU10sICAvKiBxbWZJbWFnW1FNRl9DSEFOTkVMU10gKi8KICAgICAgICAgIGhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtpK0hZQlJJRF9SRUFEX09GRlNFVF1bcHNDaF1bMF0sCiAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbaStIWUJSSURfUkVBRF9PRkZTRVRdW3BzQ2hdWzFdCiAgICAgICAgICApOwoKICAgIH0gLyogbm9fY29sIGxvb3AgIGkgICovCgogICAgcHNRbWZTY2FsZVtwc0NoXSA9IGhRbWZBbmFseXNpc1twc0NoXS0+b3V0U2NhbGVmYWN0b3I7CgogIH0gLyogZm9yIHBzQ2ggKi8KCiAgQ19BQUxMT0NfU0NSQVRDSF9FTkQocFdvcmtCdWZmZXIsIEZJWFBfUU1GLCA0KlFNRl9DSEFOTkVMUykKCiAgLyogZmluZCBiZXN0IHNjYWxpbmcgaW4gbmV3IFFNRiBhbmQgSHlicmlkIGRhdGEgKi8KICBwc0ZpbmRCZXN0U2NhbGluZyggaFBhcmFtZXRyaWNTdGVyZW8sCiAgICAgICAgICAgICAgICAgICAgJmhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtIWUJSSURfUkVBRF9PRkZTRVRdLAogICAgICAgICAgICAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+ZHluQmFuZFNjYWxlLAogICAgICAgICAgICAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlby0+bWF4QmFuZFZhbHVlLAogICAgICAgICAgICAgICAgICAgICZoUGFyYW1ldHJpY1N0ZXJlby0+ZG14U2NhbGUgKSA7CgoKICAvKiBleHRyYWN0IHRoZSBwcyBwYXJhbWV0ZXJzICovCiAgaWYoUFNFTkNfT0sgIT0gKGVycm9yID0gRXh0cmFjdFBTUGFyYW1ldGVycyhoUGFyYW1ldHJpY1N0ZXJlbywgc2VuZEhlYWRlciwgJmhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVswXSkpKXsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qIHNhdmUgaHlicmlkIGRhdGUgZm9yIG5leHQgZnJhbWUgKi8KICBmb3IgKGk9MDsgaTxIWUJSSURfUkVBRF9PRkZTRVQ7IGkrKykgewogICAgRkRLbWVtY3B5KGhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtpXVswXVswXSwgaFBhcmFtZXRyaWNTdGVyZW8tPnBIeWJyaWREYXRhW0hZQlJJRF9GUkFNRVNJWkUraV1bMF1bMF0sIE1BWF9IWUJSSURfQkFORFMqc2l6ZW9mKEZJWFBfREJMKSk7IC8qIGxlZnQsIHJlYWwgKi8KICAgIEZES21lbWNweShoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbaV1bMF1bMV0sIGhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtIWUJSSURfRlJBTUVTSVpFK2ldWzBdWzFdLCBNQVhfSFlCUklEX0JBTkRTKnNpemVvZihGSVhQX0RCTCkpOyAvKiBsZWZ0LCBpbWFnICovCiAgICBGREttZW1jcHkoaFBhcmFtZXRyaWNTdGVyZW8tPnBIeWJyaWREYXRhW2ldWzFdWzBdLCBoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbSFlCUklEX0ZSQU1FU0laRStpXVsxXVswXSwgTUFYX0hZQlJJRF9CQU5EUypzaXplb2YoRklYUF9EQkwpKTsgLyogcmlnaHQsIHJlYWwgKi8KICAgIEZES21lbWNweShoUGFyYW1ldHJpY1N0ZXJlby0+cEh5YnJpZERhdGFbaV1bMV1bMV0sIGhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtIWUJSSURfRlJBTUVTSVpFK2ldWzFdWzFdLCBNQVhfSFlCUklEX0JBTkRTKnNpemVvZihGSVhQX0RCTCkpOyAvKiByaWdodCwgaW1hZyAqLwogIH0KCiAgLyogZG93bm1peCBhbmQgaHlicmlkIHN5bnRoZXNpcyAqLwogIGlmIChQU0VOQ19PSyAhPSAoZXJyb3IgPSBEb3dubWl4UFNRbWZEYXRhKGhQYXJhbWV0cmljU3RlcmVvLCBzYnJTeW50aFFtZiwgZG93bm1peGVkUmVhbFFtZkRhdGEsIGRvd25taXhlZEltYWdRbWZEYXRhLCBkb3duc2FtcGxlZE91dFNpZ25hbCwgJmhQYXJhbWV0cmljU3RlcmVvLT5wSHlicmlkRGF0YVtIWUJSSURfUkVBRF9PRkZTRVRdLCBoUGFyYW1ldHJpY1N0ZXJlby0+bm9RbWZTbG90cywgcHNRbWZTY2FsZSwgcW1mU2NhbGUpKSkgewogICAgZ290byBiYWlsOwogIH0KCmJhaWw6CgogIHJldHVybiBlcnJvcjsKfQoKc3RhdGljIHZvaWQgcHNGaW5kQmVzdFNjYWxpbmcoCiAgICAgICAgSEFORExFX1BBUkFNRVRSSUNfU1RFUkVPICBoUGFyYW1ldHJpY1N0ZXJlbywKICAgICAgICBGSVhQX0RCTCAgICAgICAgICAgICAgICAgKmh5YnJpZERhdGFbSFlCUklEX0ZSQU1FU0laRV1bTUFYX1BTX0NIQU5ORUxTXVsyXSwKICAgICAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgKmR5bkJhbmRTY2FsZSwKICAgICAgICBGSVhQX1FNRiAgICAgICAgICAgICAgICAgKm1heEJhbmRWYWx1ZSwKICAgICAgICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgKmRteFNjYWxlCiAgICAgICAgKQp7CiAgSEFORExFX1BTX0VOQ09ERSBoUHNFbmNvZGUgICAgICA9ICBoUGFyYW1ldHJpY1N0ZXJlby0+aFBzRW5jb2RlOwoKICBJTlQgZ3JvdXAsIGJpbiwgY29sLCBiYW5kOwogIGNvbnN0IElOVCBmcmFtZVNpemUgID0gaFBhcmFtZXRyaWNTdGVyZW8tPm5vUW1mU2xvdHM7CiAgY29uc3QgSU5UIHBzQmFuZHMgICAgPSAoSU5UKSBoUHNFbmNvZGUtPnBzRW5jTW9kZTsKICBjb25zdCBJTlQgbklpZEdyb3VwcyA9IGhQc0VuY29kZS0+blFtZklpZEdyb3VwcyArIGhQc0VuY29kZS0+blN1YlFtZklpZEdyb3VwczsKCiAgLyogZ3JvdXAgd2lzZSBzY2FsaW5nICovCiAgRklYUF9RTUYgbWF4VmFsIFsyXVtQU19NQVhfQkFORFNdOwogIEZJWFBfUU1GIG1heFZhbHVlID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKCiAgRkRLbWVtY2xlYXIobWF4VmFsLCBzaXplb2YobWF4VmFsKSk7CgogIC8qIHN0YXJ0IHdpdGggaHlicmlkIGRhdGEgKi8KICBmb3IgKGdyb3VwPTA7IGdyb3VwIDwgbklpZEdyb3VwczsgZ3JvdXArKykgewogICAgLyogVHJhbnNsYXRlIGdyb3VwIHRvIGJpbiAqLwogICAgYmluID0gaFBzRW5jb2RlLT5zdWJiYW5kMnBhcmFtZXRlckluZGV4W2dyb3VwXTsKCiAgICAvKiBUcmFuc2xhdGUgZnJvbSAyMCBiaW5zIHRvIDEwIGJpbnMgKi8KICAgIGlmIChoUHNFbmNvZGUtPnBzRW5jTW9kZSA9PSBQU19CQU5EU19DT0FSU0UpIHsKICAgICAgYmluID4+PSAxOwogICAgfQoKICAgIC8qIFFNRiBkb3dubWl4IHNjYWxpbmcgKi8KICAgIHsKICAgICAgRklYUF9RTUYgdG1wID0gbWF4VmFsWzBdW2Jpbl07CiAgICAgIGludCBpOwogICAgICBmb3IgKGNvbD0wOyBjb2w8ZnJhbWVTaXplLUhZQlJJRF9SRUFEX09GRlNFVDsgY29sKyspIHsKICAgICAgICBmb3IgKGkgPSBoUHNFbmNvZGUtPmlpZEdyb3VwQm9yZGVyc1tncm91cF07IGkgPCBoUHNFbmNvZGUtPmlpZEdyb3VwQm9yZGVyc1tncm91cCsxXTsgaSsrKSB7CiAgICAgICAgICB0bXAgPSBmaXhNYXgodG1wLCAoRklYUF9RTUYpZml4cF9hYnMoaHlicmlkRGF0YVtjb2xdWzBdWzBdW2ldKSk7CiAgICAgICAgICB0bXAgPSBmaXhNYXgodG1wLCAoRklYUF9RTUYpZml4cF9hYnMoaHlicmlkRGF0YVtjb2xdWzBdWzFdW2ldKSk7CiAgICAgICAgICB0bXAgPSBmaXhNYXgodG1wLCAoRklYUF9RTUYpZml4cF9hYnMoaHlicmlkRGF0YVtjb2xdWzFdWzBdW2ldKSk7CiAgICAgICAgICB0bXAgPSBmaXhNYXgodG1wLCAoRklYUF9RTUYpZml4cF9hYnMoaHlicmlkRGF0YVtjb2xdWzFdWzFdW2ldKSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1heFZhbFswXVtiaW5dID0gdG1wOwoKICAgICAgdG1wID0gbWF4VmFsWzFdW2Jpbl07CiAgICAgIGZvciAoY29sPWZyYW1lU2l6ZS1IWUJSSURfUkVBRF9PRkZTRVQ7IGNvbDxmcmFtZVNpemU7IGNvbCsrKSB7CiAgICAgICAgZm9yIChpID0gaFBzRW5jb2RlLT5paWRHcm91cEJvcmRlcnNbZ3JvdXBdOyBpIDwgaFBzRW5jb2RlLT5paWRHcm91cEJvcmRlcnNbZ3JvdXArMV07IGkrKykgewogICAgICAgICAgdG1wID0gZml4TWF4KHRtcCwgKEZJWFBfUU1GKWZpeHBfYWJzKGh5YnJpZERhdGFbY29sXVswXVswXVtpXSkpOwogICAgICAgICAgdG1wID0gZml4TWF4KHRtcCwgKEZJWFBfUU1GKWZpeHBfYWJzKGh5YnJpZERhdGFbY29sXVswXVsxXVtpXSkpOwogICAgICAgICAgdG1wID0gZml4TWF4KHRtcCwgKEZJWFBfUU1GKWZpeHBfYWJzKGh5YnJpZERhdGFbY29sXVsxXVswXVtpXSkpOwogICAgICAgICAgdG1wID0gZml4TWF4KHRtcCwgKEZJWFBfUU1GKWZpeHBfYWJzKGh5YnJpZERhdGFbY29sXVsxXVsxXVtpXSkpOwogICAgICAgIH0KICAgICAgfQogICAgICBtYXhWYWxbMV1bYmluXSA9IHRtcDsKICAgIH0KICB9IC8qIG5JaWRHcm91cHMgKi8KCiAgLyogY29udmVydCBtYXhTcGVjIHRvIG1heFNjYWxpbmcsIGZpbmQgc2NhbGluZyBzcGFjZSAqLwogIGZvciAoYmFuZD0wOyBiYW5kPHBzQmFuZHM7IGJhbmQrKykgewojaWZuZGVmIE1VTFRfMTZ4MTYKICAgIGR5bkJhbmRTY2FsZVtiYW5kXSA9IENvdW50TGVhZGluZ0JpdHMoZml4TWF4KG1heFZhbFswXVtiYW5kXSxtYXhCYW5kVmFsdWVbYmFuZF0pKTsKI2Vsc2UKICAgIGR5bkJhbmRTY2FsZVtiYW5kXSA9IGZpeE1heCgwLENvdW50TGVhZGluZ0JpdHMoZml4TWF4KG1heFZhbFswXVtiYW5kXSxtYXhCYW5kVmFsdWVbYmFuZF0pKS1GUkFDVF9CSVRTKTsKI2VuZGlmCiAgICBtYXhWYWx1ZSA9IGZpeE1heChtYXhWYWx1ZSxmaXhNYXgobWF4VmFsWzBdW2JhbmRdLG1heFZhbFsxXVtiYW5kXSkpOwogICAgbWF4QmFuZFZhbHVlW2JhbmRdID0gZml4TWF4KG1heFZhbFswXVtiYW5kXSwgbWF4VmFsWzFdW2JhbmRdKTsKICB9CgogIC8qIGNhbGN1bGF0ZSBtYXhpbWFsIHNjYWxpbmcgZm9yIFFNRiBkb3dubWl4ICovCiNpZm5kZWYgTVVMVF8xNngxNgogICpkbXhTY2FsZSA9IGZpeE1pbihERlJBQ1RfQklUUywgQ291bnRMZWFkaW5nQml0cyhtYXhWYWx1ZSkpOwojZWxzZQogICpkbXhTY2FsZSA9IGZpeE1heCgwLGZpeE1pbihGUkFDVF9CSVRTLCBDb3VudExlYWRpbmdCaXRzKEZYX1FNRjJGWF9EQkwobWF4VmFsdWUpKSkpOwojZW5kaWYKCn0KCg==