Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBUcmFuc3BvcnQgRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqCgogICBBdXRob3Iocyk6IE1hbnVlbCBKYW5kZXIKICAgRGVzY3JpcHRpb246IE1QRUcgVHJhbnNwb3J0IGVuY29kZQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInRwZW5jX2xpYi5oIgoKLyogbGlicmFyeSBpbmZvICovCiNpbmNsdWRlICJ2ZXJzaW9uIgoKI2RlZmluZSBNT0RVTEVfTkFNRSAidHJhbnNwb3J0RW5jIgoKI2luY2x1ZGUgInRwZW5jX2FzYy5oIgojaW5jbHVkZSAiY29udl9zdHJpbmcuaCIKCiNpbmNsdWRlICJ0cGVuY19hZHRzLmgiCgojaW5jbHVkZSAidHBlbmNfYWRpZi5oIgoKI2luY2x1ZGUgInRwZW5jX2xhdG0uaCIKCgoKdHlwZWRlZiBzdHJ1Y3QgewogIGludCBjdXJTdWJGcmFtZTsKICBpbnQgblN1YkZyYW1lczsKICBpbnQgcHJldkJpdHM7Cn0gUkFXUEFDS0VUU19JTkZPOwoKc3RydWN0IFRSQU5TUE9SVEVOQwp7CiAgQ09ERVJfQ09ORklHIGNvbmZpZzsKICBUUkFOU1BPUlRfVFlQRSB0cmFuc3BvcnRGbXQ7ICAgICAgICAgIC8qITwgTVBFRzQgdHJhbnNwb3J0IHR5cGUuICovCgogIEZES19CSVRTVFJFQU0gYml0U3RyZWFtOwogIFVDSEFSICpic0J1ZmZlcjsKICBJTlQgYnNCdWZmZXJTaXplOwoKICBJTlQgcGNlRnJhbWVDb3VudGVyOyAgICAgICAgICAgICAgICAgIC8qITwgSW5kaWNhdGVzIGZyYW1lIHBlcmlvZCB3aGVuIFBDRSBtdXN0IGJlIHdyaXR0ZW4gaW4gcmF3X2RhdGFfYmxvY2suCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xIG1lYW5zIG5vdCB0byB3cml0ZSBhIFBDRSBpbiByYXdfZGF0X2Jsb2NrLiAqLwogIHVuaW9uIHsKICAgIFNUUlVDVF9BRFRTIGFkdHM7CgogICAgQURJRl9JTkZPIGFkaWY7CgogICAgTEFUTV9TVFJFQU0gbGF0bTsKCiAgICBSQVdQQUNLRVRTX0lORk8gcmF3OwoKCgogIH0gd3JpdGVyOwoKICBDU1RwQ2FsbEJhY2tzIGNhbGxiYWNrczsKfTsKCnR5cGVkZWYgc3RydWN0IF9UUkFOU1BPUlRFTkNfU1RSVUNUIFRSQU5TUE9SVEVOQ19TVFJVQ1Q7CgoKLyoKICogTUVNT1JZIERlY2xhcmF0aW9uCiAqLwoKQ19BTExPQ19NRU0oUmFtX1RyYW5zcG9ydEVuY29kZXIsIFRSQU5TUE9SVEVOQywgMSkKClRSQU5TUE9SVEVOQ19FUlJPUiB0cmFuc3BvcnRFbmNfT3BlbiggSEFORExFX1RSQU5TUE9SVEVOQyAqcGhUcEVuYyApCnsKICBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYzsKCiAgaWYgKCBwaFRwRW5jID09IE5VTEwgKXsKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9QQVJBTUVURVI7CiAgfQoKICBoVHBFbmMgPSBHZXRSYW1fVHJhbnNwb3J0RW5jb2RlcigwKTsKCiAgaWYgKCBoVHBFbmMgPT0gTlVMTCApIHsKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfTk9fTUVNOwogIH0KCiAgKnBoVHBFbmMgPSBoVHBFbmM7CiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKLyoqCiAqIFxicmllZiAgR2V0IGZyYW1lIHBlcmlvZCBvZiBQQ0UgaW4gcmF3X2RhdGFfYmxvY2suCiAqCiAqICAtIFdyaXRlIFBDRSBvbmx5IGlmIG5lY2Vzc2FyeS4gUENFIGNhbiBiZSBwYXJ0IG9mIHRoZSBBU0MgaWYgY2hDb25maWc9PTAgd2hlcmVyZm9yZQogKiAgICBubyBhZGRpdG9uYWwgUENFIHdpbGwgYmUgd3JpdHRlbiBpbiByYXdfZGF0YV9ibG9jay4KICogLSBBIG1hdHJpeE1peGRvd24gY29lZmZpY2llbnQgY2FuIG9ubHkgYmUgd3JpdHRlbiBpZiBjaENvbmZpZyBpcyA1LjAgb3IgNS4xLgogKiAtIFRoZSBQQ0UgcmVwZXRpdGlvbiByYXRlIGluIHJhd19kYXRhX2Jsb2NrIGNhbiBiZSBjb250cm9sbGVkIHZpYSBoZWFkZXJQZXJpb2QgcGFyYW1ldGVyLgogKgogKiBccGFyYW0gY2hhbm5lbENvbmZpZyAgICAgICAgIENoYW5uZWwgQ29uZmlndXJhdGlvbiBkZXJpdmVkIGZyb20gQ2hhbm5lbCBNb2RlCiAqIFxwYXJhbSB0cmFuc3BvcnRGbXQgICAgICAgICAgRm9ybWF0IG9mIHRoZSB0cmFuc3BvcnQgdG8gYmUgd3JpdHRlbi4KICogXHBhcmFtIGhlYWRlclBlcmlvZCAgICAgICAgICBDaG9zZW4gUENFIGZyYW1lIHJlcGV0aXRpb24gcmF0ZS4KICogXHBhcmFtIG1hdHJpeE1peGRvd25BICAgICAgICBJbmRpY2F0ZXMgaWYgYSB2YWxpZCBNYXRyaXggTWl4ZG93biBjb2VmZmljaWVudCBpcyBhdmFpbGFibGUuCiAqCiAqIFxyZXR1cm4gIFBDRSBmcmFtZSByZXBldGl0aW9uIHJhdGUuIC0xIG1lYW5zIG5vIFBDRSBwcmVzZW50IGluIHJhd19kYXRhX2Jsb2NrLgogKi8Kc3RhdGljIElOVCBnZXRQY2VSZXBldGl0aW9uUmF0ZSgKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBjaGFubmVsQ29uZmlnLAogICAgICAgIGNvbnN0IFRSQU5TUE9SVF9UWVBFIHRyYW5zcG9ydEZtdCwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICBoZWFkZXJQZXJpb2QsCiAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgbWF0cml4TWl4ZG93bkEKICAgICAgICApCnsKICBJTlQgcGNlRnJhbWVDb3VudGVyID0gLTE7IC8qIHZhcmlhYmxlIHRvIGJlIHJldHVybmVkICovCgogIGlmIChoZWFkZXJQZXJpb2Q+MCkgewogICAgc3dpdGNoICggY2hhbm5lbENvbmZpZyApIHsKICAgICAgY2FzZSAwOgogICAgICAgIHN3aXRjaCAodHJhbnNwb3J0Rm10KSB7CiAgICAgICAgICBjYXNlIFRUX01QNF9BRFRTOgogICAgICAgICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogICAgICAgICAgY2FzZSBUVF9NUDRfUkFXOgogICAgICAgICAgICBwY2VGcmFtZUNvdW50ZXIgPSBoZWFkZXJQZXJpb2Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSBUVF9NUDRfQURJRjogICAgICAgICAgICAgICAgICAvKiBBRElGIGhlYWRlciBjb21wcmlzZXMgUENFICovCiAgICAgICAgICBjYXNlIFRUX01QNF9MT0FTOiAgICAgICAgICAgICAgICAgIC8qIFBDRSBpbiBBU0MgaWYgY2hDaG9uZmlnPT0wICovCiAgICAgICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6ICAgICAgICAgICAgIC8qIFBDRSBpbiBBU0MgaWYgY2hDaG9uZmlnPT0wICovCiAgICAgICAgICBjYXNlIFRUX0RSTTogICAgICAgICAgICAgICAgICAgICAgIC8qIFBDRSBub3QgYWxsb3dlZCBpbiBEUk0gKi8KICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHBjZUZyYW1lQ291bnRlciA9IC0xOyAgICAgICAgICAgIC8qIG5vIFBDRSBpbiByYXdfZGF0YV9ibG9jayAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSA1OiAvKiBNT0RFXzFfMl8yICovCiAgICAgIGNhc2UgNjogLyogTU9ERV8xXzJfMl8xICovCiAgICAgICAgLyogbWF0cml4TWl4ZG93bkNvZWZmaWNpZW50IGNhbiBvbmx5IGJlIHdyaXR0ZW4gaWYgNS4wIGFuZCA1LjEgY29uZmlnIHByZXNlbnQuICovCiAgICAgICAgaWYgKG1hdHJpeE1peGRvd25BIT0wKSB7CiAgICAgICAgICBzd2l0Y2ggKHRyYW5zcG9ydEZtdCkgewogICAgICAgICAgICBjYXNlIFRUX01QNF9BRElGOiAgICAgICAgICAgICAgICAvKiBBRElGIGhlYWRlciBjb21wcmlzZXMgUENFICovCiAgICAgICAgICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgICAgICAgIGNhc2UgVFRfTVA0X0xPQVM6ICAgICAgICAgICAgICAgIC8qIG5vIFBDRSBpbiBBU0MgYmVjYXVzZSBjaENvbmZpZyE9MCAqLwogICAgICAgICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6ICAgICAgICAgICAvKiBubyBQQ0UgaW4gQVNDIGJlY2F1c2UgY2hDb25maWchPTAgKi8KICAgICAgICAgICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogICAgICAgICAgICBjYXNlIFRUX01QNF9SQVc6CiAgICAgICAgICAgICAgcGNlRnJhbWVDb3VudGVyID0gaGVhZGVyUGVyaW9kOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRUX0RSTTogICAgICAgICAgICAgICAgICAgICAvKiBQQ0Ugbm90IGFsbG93ZWQgaW4gRFJNICovCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgcGNlRnJhbWVDb3VudGVyID0gLTE7ICAgICAgICAgIC8qIG5vIFBDRSBpbiByYXdfZGF0YV9ibG9jayAqLwogICAgICAgICAgfSAvKiBzd2l0Y2ggdHJhbnNwb3J0Rm10ICovCiAgICAgICAgfSAvKiBpZiBtYXRyaXhNaXhkb3duQSE9MCAqLwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHBjZUZyYW1lQ291bnRlciA9IC0xOyAgICAgICAgICAgICAgICAvKiBubyBQQ0UgaW4gcmF3X2RhdGFfYmxvY2sgKi8KICAgIH0gLyogc3dpdGNoIGdldENoYW5uZWxDb25maWcoKSAqLwogIH0gLyogaWYgaGVhZGVyUGVyaW9kPjAgICovCiAgZWxzZSB7CiAgICBwY2VGcmFtZUNvdW50ZXIgPSAtMTsgICAgICAgICAgICAgICAgICAgIC8qIG5vIFBDRSBpbiByYXdfZGF0YV9ibG9jayAqLwogIH0KCiAgcmV0dXJuIHBjZUZyYW1lQ291bnRlcjsKfQoKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19Jbml0KAogICAgICAgIEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwRW5jLAogICAgICAgIFVDSEFSICAgICAgICAgICAgICpic0J1ZmZlciwKICAgICAgICBJTlQgICAgICAgICAgICAgICAgYnNCdWZmZXJTaXplLAogICAgICAgIFRSQU5TUE9SVF9UWVBFICAgICB0cmFuc3BvcnRGbXQsCiAgICAgICAgQ09ERVJfQ09ORklHICAgICAgKmNjb25maWcsCiAgICAgICAgVUlOVCAgICAgICAgICAgICAgIGZsYWdzCiAgICAgICAgKQp7CiAgLyogQ29weSBjb25maWd1cmF0aW9uIHN0cnVjdHVyZSAqLwogIEZES21lbWNweSgmaFRwRW5jLT5jb25maWcsIGNjb25maWcsIHNpemVvZihDT0RFUl9DT05GSUcpKTsKCiAgLyogSW5pdCB0cmFuc3BvcnRFbmMgc3RydWN0LiAqLwogIGhUcEVuYy0+dHJhbnNwb3J0Rm10ID0gdHJhbnNwb3J0Rm10OwoKICBoVHBFbmMtPmJzQnVmZmVyID0gYnNCdWZmZXI7CiAgaFRwRW5jLT5ic0J1ZmZlclNpemUgPSBic0J1ZmZlclNpemU7CgogIEZES2luaXRCaXRTdHJlYW0oJmhUcEVuYy0+Yml0U3RyZWFtLCBoVHBFbmMtPmJzQnVmZmVyLCBoVHBFbmMtPmJzQnVmZmVyU2l6ZSwgMCwgQlNfV1JJVEVSKTsKCiAgc3dpdGNoICh0cmFuc3BvcnRGbXQpIHsKCiAgY2FzZSBUVF9NUDRfQURJRjoKICAgIC8qIFNhbml0eSBjaGVja3MgKi8KICAgIGlmICggKGhUcEVuYy0+Y29uZmlnLmFvdCAhPSBBT1RfQUFDX0xDKQogICAgICAgfHwoaFRwRW5jLT5jb25maWcuc2FtcGxlc1BlckZyYW1lICE9IDEwMjQpKQogICAgewogICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfUEFSQU1FVEVSOwogICAgfQogICAgaFRwRW5jLT53cml0ZXIuYWRpZi5oZWFkZXJXcml0dGVuID0gMDsKICAgIGhUcEVuYy0+d3JpdGVyLmFkaWYuc2FtcGxpbmdSYXRlID0gaFRwRW5jLT5jb25maWcuc2FtcGxpbmdSYXRlOwogICAgaFRwRW5jLT53cml0ZXIuYWRpZi5iaXRSYXRlID0gaFRwRW5jLT5jb25maWcuYml0UmF0ZTsKICAgIGhUcEVuYy0+d3JpdGVyLmFkaWYucHJvZmlsZSA9ICgoaW50KWhUcEVuYy0+Y29uZmlnLmFvdCkgLSAxOwogICAgaFRwRW5jLT53cml0ZXIuYWRpZi5jbSA9IGhUcEVuYy0+Y29uZmlnLmNoYW5uZWxNb2RlOwogICAgaFRwRW5jLT53cml0ZXIuYWRpZi5iVmFyaWFibGVSYXRlID0gMDsKICAgIGhUcEVuYy0+d3JpdGVyLmFkaWYuaW5zdGFuY2VUYWcgPSAwOwogICAgYnJlYWs7CgogIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAvKiBTYW5pdHkgY2hlY2tzICovCiAgICBpZiAoICggaFRwRW5jLT5jb25maWcuYW90ICE9IEFPVF9BQUNfTEMpCiAgICAgICB8fChoVHBFbmMtPmNvbmZpZy5zYW1wbGVzUGVyRnJhbWUgIT0gMTAyNCkgKQogICAgewogICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfUEFSQU1FVEVSOwogICAgfQogICAgaWYgKCBhZHRzV3JpdGVfSW5pdCgmaFRwRW5jLT53cml0ZXIuYWR0cywgJmhUcEVuYy0+Y29uZmlnKSAhPSAwKSB7CiAgICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9QQVJBTUVURVI7CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBUVF9NUDRfTE9BUzoKICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgewogICAgICBUUkFOU1BPUlRFTkNfRVJST1IgZXJyb3I7CgogICAgICBlcnJvciA9IHRyYW5zcG9ydEVuY19MYXRtX0luaXQoCiAgICAgICAgICAgICAgICAmaFRwRW5jLT53cml0ZXIubGF0bSwKICAgICAgICAgICAgICAgICZoVHBFbmMtPmJpdFN0cmVhbSwKICAgICAgICAgICAgICAgICZoVHBFbmMtPmNvbmZpZywKICAgICAgICAgICAgICAgICBmbGFncyAmIFRQX0ZMQUdfTEFUTV9BTVYsCiAgICAgICAgICAgICAgICAgdHJhbnNwb3J0Rm10LAogICAgICAgICAgICAgICAgJmhUcEVuYy0+Y2FsbGJhY2tzCiAgICAgICAgICAgICAgICAgKTsKICAgICAgaWYgKGVycm9yICE9IFRSQU5TUE9SVEVOQ19PSykgewogICAgICAgIHJldHVybiBlcnJvcjsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgogIGNhc2UgVFRfTVA0X1JBVzoKICAgIGhUcEVuYy0+d3JpdGVyLnJhdy5jdXJTdWJGcmFtZSA9IDA7CiAgICBoVHBFbmMtPndyaXRlci5yYXcublN1YkZyYW1lcyA9IGhUcEVuYy0+Y29uZmlnLm5TdWJGcmFtZXM7CiAgICBicmVhazsKCgoKICBkZWZhdWx0OgogICAgcmV0dXJuIFRSQU5TUE9SVEVOQ19JTlZBTElEX1BBUkFNRVRFUjsKICB9CgogIC8qIHBjZUZyYW1lQ291bnRlciBpbmRpY2F0ZXMgaWYgUENFIG11c3QgYmUgd3JpdHRlbiBpbiByYXdfZGF0YV9ibG9jay4gKi8KICBoVHBFbmMtPnBjZUZyYW1lQ291bnRlciA9IGdldFBjZVJlcGV0aXRpb25SYXRlKAogICAgICAgICAgICAgICAgICAgIGdldENoYW5uZWxDb25maWcoaFRwRW5jLT5jb25maWcuY2hhbm5lbE1vZGUpLAogICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydEZtdCwKICAgICAgICAgICAgICAgICAgICBoVHBFbmMtPmNvbmZpZy5oZWFkZXJQZXJpb2QsCiAgICAgICAgICAgICAgICAgICAgaFRwRW5jLT5jb25maWcubWF0cml4TWl4ZG93bkEpOwoKICByZXR1cm4gVFJBTlNQT1JURU5DX09LOwp9CgpIQU5ETEVfRkRLX0JJVFNUUkVBTSB0cmFuc3BvcnRFbmNfR2V0Qml0c3RyZWFtKCBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcCApCnsKICByZXR1cm4gJmhUcC0+Yml0U3RyZWFtOwp9CgppbnQgdHJhbnNwb3J0RW5jX1JlZ2lzdGVyU2JyQ2FsbGJhY2soIEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwRW5jLCBjb25zdCBjYlNicl90IGNiU2JyLCB2b2lkKiB1c2VyX2RhdGEpCnsKICBpZiAoaFRwRW5jID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CiAgaFRwRW5jLT5jYWxsYmFja3MuY2JTYnIgPSBjYlNicjsKICBoVHBFbmMtPmNhbGxiYWNrcy5jYlNickRhdGEgPSB1c2VyX2RhdGE7CiAgcmV0dXJuIDA7Cn0KCgpUUkFOU1BPUlRFTkNfRVJST1IgdHJhbnNwb3J0RW5jX1dyaXRlQWNjZXNzVW5pdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZnJhbWVVc2VkQml0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5jYwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgVFJBTlNQT1JURU5DX0VSUk9SIGVyciA9IFRSQU5TUE9SVEVOQ19PSzsKCiAgaWYgKCFoVHApIHsKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9QQVJBTUVURVI7CiAgfQogIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcyA9ICZoVHAtPmJpdFN0cmVhbTsKCiAgLyogSW4gY2FzZSBvZiB3cml0aW5nIFBDRSBpbiByYXdfZGF0YV9ibG9jayBmcmFtZVVzZWRCaXRzIG11c3QgYmUgYWRhcHRlZC4gKi8KICBpZiAoaFRwLT5wY2VGcmFtZUNvdW50ZXI+PWhUcC0+Y29uZmlnLmhlYWRlclBlcmlvZCkgewogICAgZnJhbWVVc2VkQml0cyArPSB0cmFuc3BvcnRFbmNfR2V0UENFQml0cyhoVHAtPmNvbmZpZy5jaGFubmVsTW9kZSwgaFRwLT5jb25maWcubWF0cml4TWl4ZG93bkEsIDMpOyAvKiBDb25zaWRlciAzIGJpdHMgSUQgc2lnbmFsbGluZyBpbiBhbGlnbm1lbnQgKi8KICB9CgogIHN3aXRjaCAoaFRwLT50cmFuc3BvcnRGbXQpIHsKICAgIGNhc2UgVFRfTVA0X0FESUY6CiAgICAgIEZES2luaXRCaXRTdHJlYW0oJmhUcC0+Yml0U3RyZWFtLCBoVHAtPmJzQnVmZmVyLCBoVHAtPmJzQnVmZmVyU2l6ZSwgMCwgQlNfV1JJVEVSKTsKICAgICAgYWRpZldyaXRlX0VuY29kZUhlYWRlcigKICAgICAgICAgICAgICZoVHAtPndyaXRlci5hZGlmLAogICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICBidWZmZXJGdWxsbmVzcwogICAgICAgICAgICAgICk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBUVF9NUDRfQURUUzoKICAgICAgYnVmZmVyRnVsbG5lc3MgLz0gbmNjOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTnVtYmVyIG9mIENvbnNpZGVyZWQgQ2hhbm5lbHMgKi8KICAgICAgYnVmZmVyRnVsbG5lc3MgLz0gMzI7CiAgICAgIGJ1ZmZlckZ1bGxuZXNzID0gRkRLbWluKDB4N0ZGLCBidWZmZXJGdWxsbmVzcyk7IC8qIFNpZ25hbCB2YXJpYWJsZSByYXRlICovCiAgICAgIGFkdHNXcml0ZV9FbmNvZGVIZWFkZXIoCiAgICAgICAgICAgICAmaFRwLT53cml0ZXIuYWR0cywKICAgICAgICAgICAgICZoVHAtPmJpdFN0cmVhbSwKICAgICAgICAgICAgICBidWZmZXJGdWxsbmVzcywKICAgICAgICAgICAgICBmcmFtZVVzZWRCaXRzCiAgICAgICAgICAgICAgKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgICBidWZmZXJGdWxsbmVzcyAvPSBuY2M7ICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBDb25zaWRlcmVkIENoYW5uZWxzICovCiAgICAgIGJ1ZmZlckZ1bGxuZXNzIC89IDMyOwogICAgICBidWZmZXJGdWxsbmVzcyA9IEZES21pbigweEZGLCBidWZmZXJGdWxsbmVzcyk7IC8qIFNpZ25hbCB2YXJpYWJsZSByYXRlICovCiAgICAgIHRyYW5zcG9ydEVuY19MYXRtV3JpdGUoCiAgICAgICAgICAgICAmaFRwLT53cml0ZXIubGF0bSwKICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgZnJhbWVVc2VkQml0cywKICAgICAgICAgICAgICBidWZmZXJGdWxsbmVzcywKICAgICAgICAgICAgICZoVHAtPmNhbGxiYWNrcwogICAgICAgICAgICAgICk7CiAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X1JBVzoKICAgICAgaWYgKGhUcC0+d3JpdGVyLnJhdy5jdXJTdWJGcmFtZSA+PSBoVHAtPndyaXRlci5yYXcublN1YkZyYW1lcykgewogICAgICAgIGhUcC0+d3JpdGVyLnJhdy5jdXJTdWJGcmFtZSA9IDA7CiAgICAgICAgRkRLaW5pdEJpdFN0cmVhbSgmaFRwLT5iaXRTdHJlYW0sIGhUcC0+YnNCdWZmZXIsIGhUcC0+YnNCdWZmZXJTaXplLCAwLCBCU19XUklURVIpOwogICAgICB9CiAgICAgIGhUcC0+d3JpdGVyLnJhdy5wcmV2Qml0cyA9IEZES2dldFZhbGlkQml0cyhoQnMpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGVyciA9IFRSQU5TUE9SVEVOQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICAgIGJyZWFrOwogIH0KCiAgLyogV3JpdGUgUENFIGluIHJhd19kYXRhX2Jsb2NrIGlmIHJlcXVpcmVkICovCiAgaWYgKGhUcC0+cGNlRnJhbWVDb3VudGVyPj1oVHAtPmNvbmZpZy5oZWFkZXJQZXJpb2QpIHsKICAgIElOVCBjcmNJbmRleCA9IDA7CiAgICAvKiBBbGlnbiBpbnNpZGUgUENFIHdpdGggcmVwc2VjdCB0byB0aGUgZmlyc3QgYml0IG9mIHRoZSByYXdfZGF0YV9ibG9jaygpICovCiAgICBVSU5UIGFsaWduQW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKCZoVHAtPmJpdFN0cmVhbSk7CgogICAgLyogV3JpdGUgUENFIGVsZW1lbnQgSUQgYml0cyAqLwogICAgRkRLd3JpdGVCaXRzKCZoVHAtPmJpdFN0cmVhbSwgSURfUENFLCAzKTsKCiAgICBpZiAoIChoVHAtPnRyYW5zcG9ydEZtdD09VFRfTVA0X0FEVFMpICYmICFoVHAtPndyaXRlci5hZHRzLnByb3RlY3Rpb25fYWJzZW50KSB7CiAgICAgIGNyY0luZGV4ID0gYWR0c1dyaXRlX0NyY1N0YXJ0UmVnKCZoVHAtPndyaXRlci5hZHRzLCAmaFRwLT5iaXRTdHJlYW0sIDApOwogICAgfQoKICAgIC8qIFdyaXRlIFBDRSBhcyBmaXJzdCByYXdfZGF0YV9ibG9jayBlbGVtZW50ICovCiAgICB0cmFuc3BvcnRFbmNfd3JpdGVQQ0UoJmhUcC0+Yml0U3RyZWFtLCBoVHAtPmNvbmZpZy5jaGFubmVsTW9kZSwgaFRwLT5jb25maWcuc2FtcGxpbmdSYXRlLCAwLCAxLCBoVHAtPmNvbmZpZy5tYXRyaXhNaXhkb3duQSwgKGhUcC0+Y29uZmlnLmZsYWdzJkNDX1BTRVVET19TVVJST1VORCk/MTowLCBhbGlnbkFuY2hvcik7CgogICAgaWYgKCAoaFRwLT50cmFuc3BvcnRGbXQ9PVRUX01QNF9BRFRTKSAmJiAhaFRwLT53cml0ZXIuYWR0cy5wcm90ZWN0aW9uX2Fic2VudCkgewogICAgICBhZHRzV3JpdGVfQ3JjRW5kUmVnKCZoVHAtPndyaXRlci5hZHRzLCAmaFRwLT5iaXRTdHJlYW0sIGNyY0luZGV4KTsKICAgIH0KICAgIGhUcC0+cGNlRnJhbWVDb3VudGVyID0gMDsgLyogcmVzZXQgcGNlIGZyYW1lIGNvdW50ZXIgKi8KICB9CgogIGlmIChoVHAtPnBjZUZyYW1lQ291bnRlciE9LTEpIHsKICAgIGhUcC0+cGNlRnJhbWVDb3VudGVyKys7IC8qIFVwZGF0ZSBwY2VGcmFtZUNvdW50ZXIgb25seSBpZiBQQ0Ugd3JpdGluZyBpcyBhY3RpdmUuICovCiAgfQoKICByZXR1cm4gZXJyOwp9CgoKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19FbmRBY2Nlc3NVbml0KEhBTkRMRV9UUkFOU1BPUlRFTkMgaFRwLCBpbnQgKmJpdHMpCnsKICBzd2l0Y2ggKGhUcC0+dHJhbnNwb3J0Rm10KSB7CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICB0cmFuc3BvcnRFbmNfTGF0bUFkanVzdFN1YmZyYW1lQml0cygmaFRwLT53cml0ZXIubGF0bSwgYml0cyk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBUVF9NUDRfQURUUzoKICAgICAgYWR0c1dyaXRlX0VuZFJhd0RhdGFCbG9jaygmaFRwLT53cml0ZXIuYWR0cywgJmhUcC0+Yml0U3RyZWFtLCBiaXRzKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFRUX01QNF9BRElGOgogICAgICAvKiBTdWJzdHJhY3QgQURJRiBoZWFkZXIgZnJvbSBBVSBiaXRzLCBub3QgdG8gYmUgY29uc2lkZXJlZC4gKi8KICAgICAgKmJpdHMgLT0gYWRpZldyaXRlX0dldEhlYWRlckJpdHMoJmhUcC0+d3JpdGVyLmFkaWYpOwogICAgICBoVHAtPndyaXRlci5hZGlmLmhlYWRlcldyaXR0ZW4gPSAxOwogICAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X1JBVzoKICAgICAgKmJpdHMgLT0gaFRwLT53cml0ZXIucmF3LnByZXZCaXRzOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19HZXRGcmFtZShIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywgaW50ICpuYnl0ZXMpCnsKICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMgPSAmaFRwRW5jLT5iaXRTdHJlYW07CgogIHN3aXRjaCAoaFRwRW5jLT50cmFuc3BvcnRGbXQpIHsKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMDoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICAgICpuYnl0ZXMgPSBoVHBFbmMtPmJzQnVmZmVyU2l6ZTsKICAgICAgdHJhbnNwb3J0RW5jX0xhdG1HZXRGcmFtZSgmaFRwRW5jLT53cml0ZXIubGF0bSwgaEJzLCBuYnl0ZXMpOwogICAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgIGlmIChoVHBFbmMtPndyaXRlci5hZHRzLmN1cnJlbnRCbG9jayA+PSBoVHBFbmMtPndyaXRlci5hZHRzLm51bV9yYXdfYmxvY2tzKzEpIHsKICAgICAgICAqbmJ5dGVzID0gKEZES2dldFZhbGlkQml0cyhoQnMpICsgNyk+PjM7CiAgICAgICAgaFRwRW5jLT53cml0ZXIuYWR0cy5jdXJyZW50QmxvY2sgPSAwOwogICAgICB9IGVsc2UgewogICAgICAgICpuYnl0ZXMgPSAwOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBUVF9NUDRfQURJRjoKICAgICAgRkRLX0FTU0VSVCgoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpID49IDApOwogICAgICAqbmJ5dGVzID0gKEZES2dldFZhbGlkQml0cyhoQnMpICsgNyk+PjM7CiAgICAgIGJyZWFrOwogICAgY2FzZSBUVF9NUDRfUkFXOgogICAgICBGREtzeW5jQ2FjaGUoaEJzKTsKICAgICAgaFRwRW5jLT53cml0ZXIucmF3LmN1clN1YkZyYW1lKys7CiAgICAgICpuYnl0ZXMgPSAoKEZES2dldFZhbGlkQml0cyhoQnMpLWhUcEVuYy0+d3JpdGVyLnJhdy5wcmV2Qml0cykgKyA3KT4+MzsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIHJldHVybiBUUkFOU1BPUlRFTkNfT0s7Cn0KCklOVCB0cmFuc3BvcnRFbmNfR2V0U3RhdGljQml0cyggSEFORExFX1RSQU5TUE9SVEVOQyBoVHAsIGludCBhdUJpdHMgKQp7CiAgSU5UIG5iaXRzID0gMCwgblBjZUJpdHMgPSAwOwoKICAvKiBXcml0ZSBQQ0Ugd2l0aGluIHJhd19kYXRhX2Jsb2NrIGluIHRyYW5zcG9ydCBsaWIuICovCiAgaWYgKGhUcC0+cGNlRnJhbWVDb3VudGVyPj1oVHAtPmNvbmZpZy5oZWFkZXJQZXJpb2QpIHsKICAgIG5QY2VCaXRzID0gdHJhbnNwb3J0RW5jX0dldFBDRUJpdHMoaFRwLT5jb25maWcuY2hhbm5lbE1vZGUsIGhUcC0+Y29uZmlnLm1hdHJpeE1peGRvd25BLCAzKTsgLyogQ29uc2lkZXIgMyBiaXRzIElEIHNpZ25hbGxpbmcgaW4gYWxpZ25tZW50ICovCiAgICBhdUJpdHMgKz0gblBjZUJpdHM7IC8qIEFkYXB0IHJlcXVpcmVkIHJhd19kYXRhX2Jsb2NrIGJpdCBjb25zdW10cGlvbiBmb3IgQVUgbGVuZ3RoIGluZm9ybWF0aW9uIGUuZy4gaW4gTEFUTS9MT0FTIGNvbmZpZ3VyYXRpb24uICovCiAgfQoKICBzd2l0Y2ggKGhUcC0+dHJhbnNwb3J0Rm10KSB7CiAgICBjYXNlIFRUX01QNF9BRElGOgogICAgY2FzZSBUVF9NUDRfUkFXOgogICAgICBuYml0cyA9IDA7IC8qIERvIG5vdCBjb25zaWRlciB0aGUgQURJRiBoZWFkZXIgaW50byB0aGUgdG90YWwgYml0cmF0ZSAqLwogICAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgIG5iaXRzID0gYWR0c1dyaXRlX0dldEhlYWRlckJpdHMoJmhUcC0+d3JpdGVyLmFkdHMpOwogICAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICAgIG5iaXRzID0gdHJhbnNwb3J0RW5jX0xhdG1Db3VudFRvdGFsQml0RGVtYW5kSGVhZGVyKCAmaFRwLT53cml0ZXIubGF0bSwgYXVCaXRzICk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgbmJpdHMgPSAwOwogICAgICBicmVhazsKICB9CgogIC8qIFBDRSBpcyB3cml0dGVuIGluIHRoZSB0cmFuc3BvcnQgbGlicmFyeSB0aGVyZWZvcmUgdGhlIGJpdCBjb25zdW1wdGlvbiBpcyBwYXJ0IG9mIHRoZSB0cmFuc3BvcnQgc3RhdGljIGJpdHMuICovCiAgbmJpdHMgKz0gblBjZUJpdHM7CgogIHJldHVybiBuYml0czsKfQoKdm9pZCB0cmFuc3BvcnRFbmNfQ2xvc2UoSEFORExFX1RSQU5TUE9SVEVOQyAqcGhUcCkKewogIGlmIChwaFRwICE9IE5VTEwpCiAgewogICAgaWYgKCpwaFRwICE9IE5VTEwpIHsKICAgICAgRnJlZVJhbV9UcmFuc3BvcnRFbmNvZGVyKHBoVHApOwogICAgfQogIH0KfQoKaW50IHRyYW5zcG9ydEVuY19DcmNTdGFydFJlZyhIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywgaW50IG1CaXRzKQp7CiAgaW50IGNyY1JlZyA9IDA7CgogIHN3aXRjaCAoaFRwRW5jLT50cmFuc3BvcnRGbXQpIHsKICBjYXNlIFRUX01QNF9BRFRTOgogICAgY3JjUmVnID0gYWR0c1dyaXRlX0NyY1N0YXJ0UmVnKCZoVHBFbmMtPndyaXRlci5hZHRzLCAmaFRwRW5jLT5iaXRTdHJlYW0sIG1CaXRzKTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBicmVhazsKICB9CgogIHJldHVybiBjcmNSZWc7Cn0KCnZvaWQgdHJhbnNwb3J0RW5jX0NyY0VuZFJlZyhIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywgaW50IHJlZykKewogIHN3aXRjaCAoaFRwRW5jLT50cmFuc3BvcnRGbXQpIHsKICBjYXNlIFRUX01QNF9BRFRTOgogICAgYWR0c1dyaXRlX0NyY0VuZFJlZygmaFRwRW5jLT53cml0ZXIuYWR0cywgJmhUcEVuYy0+Yml0U3RyZWFtLCByZWcpOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGJyZWFrOwogIH0KfQoKClRSQU5TUE9SVEVOQ19FUlJPUiB0cmFuc3BvcnRFbmNfR2V0Q29uZihIQU5ETEVfVFJBTlNQT1JURU5DICBoVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT0RFUl9DT05GSUcgICAgICAgICpjYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZES19CSVRTVFJFQU0gICAgICAgKmRhdGFCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgICAgICpjb25mVHlwZSkKewogIFRSQU5TUE9SVEVOQ19FUlJPUiB0cEVyciA9IFRSQU5TUE9SVEVOQ19PSzsKICBIQU5ETEVfTEFUTV9TVFJFQU0gaExhdG1Db25maWcgPSAmaFRwRW5jLT53cml0ZXIubGF0bTsKCiAgKmNvbmZUeXBlID0gMDsgLyogc2V0IGNvbmZUeXBlIHZhcmlhYmxlIHRvIGRlZmF1bHQgKi8KCiAgLyogd3JpdGUgU3RyZWFtTXV4Q29uZmlnIG9yIEF1ZGlvU3BlY2lmaWNDb25maWcgZGVwZW5kaW5nIG9uIGZvcm1hdCB1c2VkICovCiAgc3dpdGNoIChoVHBFbmMtPnRyYW5zcG9ydEZtdCkKICB7CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICB0cEVyciA9IENyZWF0ZVN0cmVhbU11eENvbmZpZyhoTGF0bUNvbmZpZywgZGF0YUJ1ZmZlciwgMCwgJmhUcEVuYy0+Y2FsbGJhY2tzKTsKICAgICAgKmNvbmZUeXBlID0gMTsgLyogY29uZmlnIGlzIFNNQyAqLwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGlmICh0cmFuc3BvcnRFbmNfd3JpdGVBU0MoZGF0YUJ1ZmZlciwgY2MsICZoVHBFbmMtPmNhbGxiYWNrcykgIT0gMCkgewogICAgICAgIHRwRXJyID0gVFJBTlNQT1JURU5DX1VOS09XTl9FUlJPUjsKICAgICAgfQogIH0KCiAgcmV0dXJuIHRwRXJyOwoKfQoKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19HZXRMaWJJbmZvKCBMSUJfSU5GTyAqaW5mbyApCnsKICBpbnQgaTsKCiAgaWYgKGluZm8gPT0gTlVMTCkgewogICAgcmV0dXJuIFRSQU5TUE9SVEVOQ19JTlZBTElEX1BBUkFNRVRFUjsKICB9CiAgLyogc2VhcmNoIGZvciBuZXh0IGZyZWUgdGFiICovCiAgZm9yIChpID0gMDsgaSA8IEZES19NT0RVTEVfTEFTVDsgaSsrKSB7CiAgICBpZiAoaW5mb1tpXS5tb2R1bGVfaWQgPT0gRkRLX05PTkUpIGJyZWFrOwogIH0KICBpZiAoaSA9PSBGREtfTU9EVUxFX0xBU1QpIHsKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfVU5LT1dOX0VSUk9SOwogIH0KICBpbmZvICs9IGk7CgogIGluZm8tPm1vZHVsZV9pZCA9IEZES19UUEVOQzsKICBpbmZvLT52ZXJzaW9uID0gTElCX1ZFUlNJT04oVFBfTElCX1ZMMCwgVFBfTElCX1ZMMSwgVFBfTElCX1ZMMik7CiAgTElCX1ZFUlNJT05fU1RSSU5HKGluZm8pOwojaWZkZWYgX19BTkRST0lEX18KICBpbmZvLT5idWlsZF9kYXRlID0gIiI7CiAgaW5mby0+YnVpbGRfdGltZSA9ICIiOwojZWxzZQogIGluZm8tPmJ1aWxkX2RhdGUgPSBfX0RBVEVfXzsKICBpbmZvLT5idWlsZF90aW1lID0gX19USU1FX187CiNlbmRpZgogIGluZm8tPnRpdGxlID0gVFBfTElCX1RJVExFOwoKICAvKiBTZXQgZmxhZ3MgKi8KICBpbmZvLT5mbGFncyA9IDAKICAgIHwgQ0FQRl9BRElGCiAgICB8IENBUEZfQURUUwogICAgfCBDQVBGX0xBVE0KICAgIHwgQ0FQRl9MT0FTCiAgICB8IENBUEZfUkFXUEFDS0VUUwogICAgOwoKICByZXR1cm4gVFJBTlNQT1JURU5DX09LOwp9Cgo=