Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IHRlbXBvcmFsIG5vaXNlIHNoYXBpbmcgdG9vbAoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2RlY190bnMuaCIKI2luY2x1ZGUgImFhY19yb20uaCIKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKI2luY2x1ZGUgImNoYW5uZWxpbmZvLmgiCgoKCi8qIQogIFxicmllZiBSZXNldCB0bnMgZGF0YQoKICBUaGUgZnVuY3Rpb24gcmVzZXRzIHRoZSB0bnMgZGF0YQoKICBccmV0dXJuICBub25lCiovCnZvaWQgQ1Ruc19SZXNldChDVG5zRGF0YSAqcFRuc0RhdGEpCnsKICAvKiBOb3RlOiB0aGUgZm9sbG93aW5nIEZES21lbWNsZWFyIHNob3VsZCBub3QgYmUgcmVxdWlyZWQuICovCiAgRkRLbWVtY2xlYXIocFRuc0RhdGEtPkZpbHRlciwgVE5TX01BWF9XSU5ET1dTKlROU19NQVhJTVVNX0ZJTFRFUlMqc2l6ZW9mKENGaWx0ZXIpKTsKICBGREttZW1jbGVhcihwVG5zRGF0YS0+TnVtYmVyT2ZGaWx0ZXJzLCBUTlNfTUFYX1dJTkRPV1Mqc2l6ZW9mKFVDSEFSKSk7CiAgcFRuc0RhdGEtPkRhdGFQcmVzZW50ID0gMDsKICBwVG5zRGF0YS0+QWN0aXZlID0gMDsKfQoKdm9pZCBDVG5zX1JlYWREYXRhUHJlc2VudEZsYWcoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsICAgIC8qITwgcG9pbnRlciB0byBiaXRzdHJlYW0gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1Ruc0RhdGEgKnBUbnNEYXRhKSAgICAgICAgIC8qITwgcG9pbnRlciB0byBhYWMgZGVjb2RlciBjaGFubmVsIGluZm8gKi8KewogIHBUbnNEYXRhLT5EYXRhUHJlc2VudCA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMSk7Cn0KCi8qIQogIFxicmllZiBSZWFkIHRucyBkYXRhIGZyb20gYml0c3RyZWFtCgogIFRoZSBmdW5jdGlvbiByZWFkcyB0aGUgZWxlbWVudHMgZm9yIHRucyBmcm9tCiAgdGhlIGJpdHN0cmVhbS4KCiAgXHJldHVybiAgbm9uZQoqLwpBQUNfREVDT0RFUl9FUlJPUiBDVG5zX1JlYWQoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDVG5zRGF0YSAqcFRuc0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDSWNzSW5mbyAqcEljc0luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UIGZsYWdzKQp7CiAgVUNIQVIgbl9maWx0LG9yZGVyOwogIFVDSEFSIGxlbmd0aCxjb2VmX3Jlcyxjb2VmX2NvbXByZXNzOwogIFVDSEFSIHdpbmRvdzsKICBVQ0hBUiB3aW5zX3Blcl9mcmFtZSA9IEdldFdpbmRvd3NQZXJGcmFtZShwSWNzSW5mbyk7CiAgVUNIQVIgaXNMb25nRmxhZyA9IElzTG9uZ0Jsb2NrKHBJY3NJbmZvKTsKICBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1cyA9IEFBQ19ERUNfT0s7CgogIGlmICghcFRuc0RhdGEtPkRhdGFQcmVzZW50KSB7CiAgICByZXR1cm4gRXJyb3JTdGF0dXM7CiAgfQoKICBmb3IgKHdpbmRvdyA9IDA7IHdpbmRvdyA8IHdpbnNfcGVyX2ZyYW1lOyB3aW5kb3crKykKICB7CiAgICBwVG5zRGF0YS0+TnVtYmVyT2ZGaWx0ZXJzW3dpbmRvd10gPSBuX2ZpbHQgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLCBpc0xvbmdGbGFnID8gMiA6IDEpOwoKICAgIGlmIChwVG5zRGF0YS0+TnVtYmVyT2ZGaWx0ZXJzW3dpbmRvd10gPiBUTlNfTUFYSU1VTV9GSUxURVJTKXsKICAgICAgICBwVG5zRGF0YS0+TnVtYmVyT2ZGaWx0ZXJzW3dpbmRvd10gPSBuX2ZpbHQgPSBUTlNfTUFYSU1VTV9GSUxURVJTOwogICAgfQoKICAgIGlmIChuX2ZpbHQpCiAgICB7CiAgICAgIGludCBpbmRleDsKICAgICAgVUNIQVIgbmV4dHN0b3BiYW5kOwoKICAgICAgY29lZl9yZXMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDEpOwoKICAgICAgbmV4dHN0b3BiYW5kID0gR2V0U2NhbGVGYWN0b3JCYW5kc1RvdGFsKHBJY3NJbmZvKTsKCiAgICAgIGZvciAoaW5kZXg9MDsgaW5kZXggPCBuX2ZpbHQ7IGluZGV4KyspCiAgICAgIHsKICAgICAgICBDRmlsdGVyICpmaWx0ZXIgPSAmcFRuc0RhdGEtPkZpbHRlclt3aW5kb3ddW2luZGV4XTsKCiAgICAgICAgbGVuZ3RoID0gKFVDSEFSKUZES3JlYWRCaXRzKGJzLCBpc0xvbmdGbGFnID8gNiA6IDQpOwoKICAgICAgICBpZiAobGVuZ3RoID4gbmV4dHN0b3BiYW5kKXsKICAgICAgICAgIGxlbmd0aCA9IG5leHRzdG9wYmFuZDsKICAgICAgICB9CgogICAgICAgIGZpbHRlci0+U3RhcnRCYW5kID0gbmV4dHN0b3BiYW5kIC0gbGVuZ3RoOwogICAgICAgIGZpbHRlci0+U3RvcEJhbmQgID0gbmV4dHN0b3BiYW5kOwogICAgICAgIG5leHRzdG9wYmFuZCA9IGZpbHRlci0+U3RhcnRCYW5kOwoKICAgICAgICB7CiAgICAgICAgICBmaWx0ZXItPk9yZGVyID0gb3JkZXIgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLCBpc0xvbmdGbGFnID8gNSA6IDMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbHRlci0+T3JkZXIgPiBUTlNfTUFYSU1VTV9PUkRFUil7CiAgICAgICAgICBmaWx0ZXItPk9yZGVyID0gb3JkZXIgPSBUTlNfTUFYSU1VTV9PUkRFUjsKICAgICAgICB9CgogICAgICAgIGlmIChvcmRlcikKICAgICAgICB7CiAgICAgICAgICBVQ0hBUiBjb2VmLHNfbWFzazsKICAgICAgICAgIFVDSEFSIGk7CiAgICAgICAgICBTQ0hBUiBuX21hc2s7CiAgICAgICAgICBzdGF0aWMgY29uc3QgVUNIQVIgc2duX21hc2tbXSA9IHsgIDB4MiwgIDB4NCwgIDB4OCB9OwogICAgICAgICAgc3RhdGljIGNvbnN0IFNDSEFSIG5lZ19tYXNrW10gPSB7IH4weDMsIH4weDcsIH4weEYgfTsKCiAgICAgICAgICBmaWx0ZXItPkRpcmVjdGlvbiA9IEZES3JlYWRCaXRzKGJzLDEpID8gLTEgOiAxOwoKICAgICAgICAgIGNvZWZfY29tcHJlc3MgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDEpOwoKICAgICAgICAgIGZpbHRlci0+UmVzb2x1dGlvbiA9IGNvZWZfcmVzICsgMzsKCiAgICAgICAgICBzX21hc2sgPSBzZ25fbWFza1tjb2VmX3JlcyArIDEgLSBjb2VmX2NvbXByZXNzXTsKICAgICAgICAgIG5fbWFzayA9IG5lZ19tYXNrW2NvZWZfcmVzICsgMSAtIGNvZWZfY29tcHJlc3NdOwoKICAgICAgICAgIGZvciAoaT0wOyBpIDwgb3JkZXI7IGkrKykKICAgICAgICAgIHsKICAgICAgICAgICAgY29lZiA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsZmlsdGVyLT5SZXNvbHV0aW9uIC0gY29lZl9jb21wcmVzcyk7CiAgICAgICAgICAgIGZpbHRlci0+Q29lZmZbaV0gPSAoY29lZiAmIHNfbWFzaykgPyAoY29lZiB8IG5fbWFzaykgOiBjb2VmOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcFRuc0RhdGEtPkFjdGl2ZSA9IDE7CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCnN0YXRpYyB2b2lkIENUbnNfRmlsdGVyIChGSVhQX0RCTCAqc3BlYywgaW50IHNpemUsIGludCBpbmMsIEZJWFBfVENDIGNvZWZmIFtdLCBpbnQgb3JkZXIpCnsKICAvLyAtIFNpbXBsZSBhbGwtcG9sZSBmaWx0ZXIgb2Ygb3JkZXIgIm9yZGVyIiBkZWZpbmVkIGJ5CiAgLy8gICB5KG4pID0gIHgobikgLSBhKDIpKnkobi0xKSAtIC4uLiAtIGEob3JkZXIrMSkqeShuLW9yZGVyKQogIC8vCiAgLy8gLSBUaGUgc3RhdGUgdmFyaWFibGVzIG9mIHRoZSBmaWx0ZXIgYXJlIGluaXRpYWxpemVkIHRvIHplcm8gZXZlcnkgdGltZQogIC8vCiAgLy8gLSBUaGUgb3V0cHV0IGRhdGEgaXMgd3JpdHRlbiBvdmVyIHRoZSBpbnB1dCBkYXRhICgiaW4tcGxhY2Ugb3BlcmF0aW9uIikKICAvLwogIC8vIC0gQW4gaW5wdXQgdmVjdG9yIG9mICJzaXplIiBzYW1wbGVzIGlzIHByb2Nlc3NlZCBhbmQgdGhlIGluZGV4IGluY3JlbWVudAogIC8vICAgdG8gdGhlIG5leHQgZGF0YSBzYW1wbGUgaXMgZ2l2ZW4gYnkgImluYyIKCiAgaW50IGksaixOOwogIEZJWFBfREJMICpwU3BlYzsKICBGSVhQX0RCTCBtYXhWYWw9RkwyRlhDT05TVF9EQkwoMC4wKTsKICBJTlQgczsKCiAgRkRLX0FTU0VSVChvcmRlciA8PSBUTlNfTUFYSU1VTV9PUkRFUik7CiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHN0YXRlLCBGSVhQX0RCTCwgVE5TX01BWElNVU1fT1JERVIpOwogIEZES21lbWNsZWFyKHN0YXRlLCBvcmRlcipzaXplb2YoRklYUF9EQkwpKTsKCiAgZm9yIChpPTA7IGk8c2l6ZTsgaSsrKSB7CiAgICBtYXhWYWwgPSBmaXhNYXgobWF4VmFsLGZpeHBfYWJzKHNwZWNbaV0pKTsKICB9CgogIGlmICggbWF4VmFsID4gRkwyRlhDT05TVF9EQkwoMC4wMzEyNSowLjcwNzEwNjc4MTE4KSApCiAgICBzID0gZml4TWF4KENudExlYWRpbmdaZXJvcyhtYXhWYWwpLTYsMCk7CiAgZWxzZQogICAgcyA9IGZpeE1heChDbnRMZWFkaW5nWmVyb3MobWF4VmFsKS01LDApOwoKICBzID0gZml4TWluKHMsMik7CiAgcyA9IHMtMTsKCiAgaWYgKGluYyA9PSAtMSkKICAgIHBTcGVjID0gJnNwZWNbc2l6ZSAtIDFdOwogIGVsc2UKICAgIHBTcGVjID0gJnNwZWNbMF07CgogIEZJWFBfVENDICpwQ29lZmY7CgojZGVmaW5lIEZJUlNUX1BBUlRfRkxUUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBGSVhQX0RCTCB4LCAqcFN0YXRlID0gc3RhdGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHBDb2VmZiA9IGNvZWZmOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBpZiAocyA8IDApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgeCA9IChwU3BlYyBbMF0+PjEpICsgZk11bHREaXYyICgqcENvZWZmKyssIHBTdGF0ZSBbMF0pIDsgICAgICAgXAogICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgIHggPSAocFNwZWMgWzBdPDxzKSArIGZNdWx0RGl2MiAoKnBDb2VmZisrLCBwU3RhdGUgWzBdKSA7CgojZGVmaW5lIElOTkVSX0ZMVFJfSU5MSU5FICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgIHggPSBmTXVsdEFkZERpdjIgKHgsICpwQ29lZmYsIHBTdGF0ZSBbMV0pOyAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgcFN0YXRlIFswXSA9IHBTdGF0ZSBbMV0gLSAoZk11bHREaXYyICgqcENvZWZmKyssIHgpIDw8MikgOyAgICAgXAogICAgICBwU3RhdGUrKzsKCiNkZWZpbmUgTEFTVF9QQVJUX0ZMVFIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgaWYgKHMgPCAwKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgICpwU3BlYyA9IHggPDwgMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAqcFNwZWMgPSB4ID4+IHM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAqcFN0YXRlID0oLXgpIDw8IDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgIHBTcGVjICAgKz0gaW5jIDsKCgogICBpZiAob3JkZXI+OCkKICAgewogICAgICBOID0gKG9yZGVyLTEpJjc7CgogICAgICBmb3IgKGkgPSBzaXplIDsgaSAhPSAwIDsgaS0tKQogICAgICB7CiAgICAgICAgRklSU1RfUEFSVF9GTFRSCgogICAgICAgIGZvciAoaiA9IE47IGogPiAwIDsgai0tKSB7IElOTkVSX0ZMVFJfSU5MSU5FIH0KCiAgICAgICAgSU5ORVJfRkxUUl9JTkxJTkUgSU5ORVJfRkxUUl9JTkxJTkUgSU5ORVJfRkxUUl9JTkxJTkUgSU5ORVJfRkxUUl9JTkxJTkUKICAgICAgICBJTk5FUl9GTFRSX0lOTElORSBJTk5FUl9GTFRSX0lOTElORSBJTk5FUl9GTFRSX0lOTElORSBJTk5FUl9GTFRSX0lOTElORQoKICAgICAgICBMQVNUX1BBUlRfRkxUUgogICAgICB9CgogICB9IGVsc2UgaWYgKG9yZGVyPjQpIHsKCiAgICAgIE4gPSAob3JkZXItMSkmMzsKCiAgICAgIGZvciAoaSA9IHNpemUgOyBpICE9IDAgOyBpLS0pCiAgICAgIHsKICAgICAgICBGSVJTVF9QQVJUX0ZMVFIKICAgICAgICBmb3IgKGogPSBOOyBqID4gMCA7IGotLSkgeyBJTk5FUl9GTFRSX0lOTElORSB9CgogICAgICAgIElOTkVSX0ZMVFJfSU5MSU5FIElOTkVSX0ZMVFJfSU5MSU5FIElOTkVSX0ZMVFJfSU5MSU5FIElOTkVSX0ZMVFJfSU5MSU5FCgogICAgICAgIExBU1RfUEFSVF9GTFRSCiAgICAgIH0KCiAgIH0gZWxzZSB7CgogICAgICBOID0gb3JkZXItMTsKCiAgICAgIGZvciAoaSA9IHNpemUgOyBpICE9IDAgOyBpLS0pCiAgICAgIHsKICAgICAgICBGSVJTVF9QQVJUX0ZMVFIKCiAgICAgICAgZm9yIChqID0gTjsgaiA+IDAgOyBqLS0pIHsgSU5ORVJfRkxUUl9JTkxJTkUgfQoKICAgICAgICBMQVNUX1BBUlRfRkxUUgogICAgICB9CiAgIH0KCiAgIENfQUxMT0NfU0NSQVRDSF9FTkQoc3RhdGUsIEZJWFBfREJMLCBUTlNfTUFYSU1VTV9PUkRFUik7Cn0KCi8qIQogIFxicmllZiBBcHBseSB0bnMgdG8gc3BlY3RyYWwgbGluZXMKCiAgVGhlIGZ1bmN0aW9uIGFwcGxpZXMgdGhlIHRucyB0byB0aGUgc3BlY3RydW0sCgogIFxyZXR1cm4gIG5vbmUKKi8Kdm9pZCBDVG5zX0FwcGx5ICgKICAgICAgICBDVG5zRGF0YSAqUkVTVFJJQ1QgcFRuc0RhdGEsIC8qITwgcG9pbnRlciB0byBhYWMgZGVjb2RlciBpbmZvICovCiAgICAgICAgY29uc3QgQ0ljc0luZm8gKnBJY3NJbmZvLAogICAgICAgIFNQRUNUUkFMX1BUUiBwU3BlY3RyYWxDb2VmZmljaWVudCwKICAgICAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICBjb25zdCBJTlQgZ3JhbnVsZUxlbmd0aAogICAgICAgICkKewogIGludCB3aW5kb3csaW5kZXgsc3RhcnQsc3RvcCxzaXplOwoKCiAgaWYgKHBUbnNEYXRhLT5BY3RpdmUpCiAgewogICAgICBDX0FBTExPQ19TQ1JBVENIX1NUQVJUKGNvZWZmLCBGSVhQX1RDQywgVE5TX01BWElNVU1fT1JERVIpOwoKICAgICAgZm9yICh3aW5kb3c9MDsgd2luZG93IDwgR2V0V2luZG93c1BlckZyYW1lKHBJY3NJbmZvKTsgd2luZG93KyspCiAgICAgIHsKICAgICAgICBGSVhQX0RCTCAqcFNwZWN0cnVtID0gU1BFQyhwU3BlY3RyYWxDb2VmZmljaWVudCwgd2luZG93LCBncmFudWxlTGVuZ3RoKTsKCiAgICAgICAgZm9yIChpbmRleD0wOyBpbmRleCA8IHBUbnNEYXRhLT5OdW1iZXJPZkZpbHRlcnNbd2luZG93XTsgaW5kZXgrKykKICAgICAgICB7CiAgICAgICAgICBDRmlsdGVyICpSRVNUUklDVCBmaWx0ZXIgPSAmcFRuc0RhdGEtPkZpbHRlclt3aW5kb3ddW2luZGV4XTsKCiAgICAgICAgICBpZiAoZmlsdGVyLT5PcmRlciA+IDApCiAgICAgICAgICB7CiAgICAgICAgICAgICBGSVhQX1RDQyAqcENvZWZmOwogICAgICAgICAgICAgaW50IHRuc19tYXhfYmFuZHM7CgogICAgICAgICAgICAgcENvZWZmID0gJmNvZWZmW2ZpbHRlci0+T3JkZXItMV07CiAgICAgICAgICAgICBpZiAoZmlsdGVyLT5SZXNvbHV0aW9uID09IDMpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICBmb3IgKGk9MDsgaSA8IGZpbHRlci0+T3JkZXI7IGkrKykKICAgICAgICAgICAgICAgICAqcENvZWZmLS0gPSBGREthYWNEZWNfdG5zQ29lZmYzW2ZpbHRlci0+Q29lZmZbaV0rNF07CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICBmb3IgKGk9MDsgaSA8IGZpbHRlci0+T3JkZXI7IGkrKykKICAgICAgICAgICAgICAgICAqcENvZWZmLS0gPSBGREthYWNEZWNfdG5zQ29lZmY0W2ZpbHRlci0+Q29lZmZbaV0rOF07CiAgICAgICAgICAgICB9CgogICAgICAgICAgICAgc3dpdGNoIChncmFudWxlTGVuZ3RoKSB7CiAgICAgICAgICAgICAgIGNhc2UgNDgwOgogICAgICAgICAgICAgICAgIHRuc19tYXhfYmFuZHMgPSB0bnNfbWF4X2JhbmRzX3RibF80ODBbcFNhbXBsaW5nUmF0ZUluZm8tPnNhbXBsaW5nUmF0ZUluZGV4XTsKICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSA1MTI6CiAgICAgICAgICAgICAgICAgdG5zX21heF9iYW5kcyA9IHRuc19tYXhfYmFuZHNfdGJsXzUxMltwU2FtcGxpbmdSYXRlSW5mby0+c2FtcGxpbmdSYXRlSW5kZXhdOwogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgIHRuc19tYXhfYmFuZHMgPSBHZXRNYXhpbXVtVG5zQmFuZHMocEljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvLT5zYW1wbGluZ1JhdGVJbmRleCk7CiAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICB9CgogICAgICAgICAgICAgc3RhcnQgPSBmaXhNaW4oIGZpeE1pbihmaWx0ZXItPlN0YXJ0QmFuZCwgdG5zX21heF9iYW5kcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U2NhbGVGYWN0b3JCYW5kc1RyYW5zbWl0dGVkKHBJY3NJbmZvKSApOwoKICAgICAgICAgICAgIHN0YXJ0ID0gR2V0U2NhbGVGYWN0b3JCYW5kT2Zmc2V0cyhwSWNzSW5mbywgcFNhbXBsaW5nUmF0ZUluZm8pW3N0YXJ0XTsKCiAgICAgICAgICAgICBzdG9wID0gZml4TWluKCBmaXhNaW4oZmlsdGVyLT5TdG9wQmFuZCwgdG5zX21heF9iYW5kcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQocEljc0luZm8pICk7CgogICAgICAgICAgICAgc3RvcCA9IEdldFNjYWxlRmFjdG9yQmFuZE9mZnNldHMocEljc0luZm8sIHBTYW1wbGluZ1JhdGVJbmZvKVtzdG9wXTsKCiAgICAgICAgICAgICBzaXplID0gc3RvcCAtIHN0YXJ0OwoKICAgICAgICAgICAgIGlmIChzaXplID4gMCkgewogICAgICAgICAgICAgICBDVG5zX0ZpbHRlcigmcFNwZWN0cnVtW3N0YXJ0XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXItPkRpcmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyLT5PcmRlciApOwogICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBDX0FBTExPQ19TQ1JBVENIX0VORChjb2VmZiwgRklYUF9UQ0MsIFROU19NQVhJTVVNX09SREVSKTsKICB9Cgp9Cg==