LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgKGludGVybmFsKSBkcml2ZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucywKICogZHJpdmVyIGVudW1lcmF0aW9uIEFQSXMgYW5kIERpcmVjdERyYXcgY3JlYXRpb24gZnVuY3Rpb25zLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgojaW5jbHVkZSAiZXhjcHQuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgp0eXBlZGVmIElXaW5lRDNEKiAoV0lOQVBJICpmbldpbmVEaXJlY3QzRENyZWF0ZSkoVUlOVCwgVUlOVCwgSVVua25vd24gKik7CgpzdGF0aWMgSE1PRFVMRSBoV2luZUQzRCA9IChITU9EVUxFKSAtMTsKc3RhdGljIGZuV2luZURpcmVjdDNEQ3JlYXRlIHBXaW5lRGlyZWN0M0RDcmVhdGU7CgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgovKiBUaGUgY29uZmlndXJlZCBkZWZhdWx0IHN1cmZhY2UgKi8KV0lORUQzRFNVUkZUWVBFIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfVU5LTk9XTjsKCi8qIEREcmF3IGxpc3QgYW5kIGNyaXRpY2FsIHNlY3Rpb24gKi8Kc3RhdGljIHN0cnVjdCBsaXN0IGdsb2JhbF9kZHJhd19saXN0ID0gTElTVF9JTklUKGdsb2JhbF9kZHJhd19saXN0KTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGRkcmF3X2xpc3RfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmZGRyYXdfbGlzdF9jcywKICAgIHsgJmRkcmF3X2xpc3RfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgCiAgICAmZGRyYXdfbGlzdF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRkcmF3X2xpc3RfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3MgPSB7ICZkZHJhd19saXN0X2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEhlbHBlciBmdW5jdGlvbiBmb3IgRGlyZWN0RHJhd0NyZWF0ZSBhbmQgZnJpZW5kcwogKiBDcmVhdGVzIGEgbmV3IEREcmF3IGludGVyZmFjZSB3aXRoIHRoZSBnaXZlbiBSRUZJSUQKICoKICogSW50ZXJmYWNlcyB0aGF0IGNhbiBiZSBjcmVhdGVkOgogKiAgSURpcmVjdERyYXcsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXc0LCBJRGlyZWN0RHJhdzcKICogIElEaXJlY3QzRCwgSURpcmVjdDNEMiwgSURpcmVjdDNEMywgSURpcmVjdDNENy4gKERvZXMgV2luZG93cyByZXR1cm4KICogIElEaXJlY3QzRCBpbnRlcmZhY2VzPykKICoKICogQXJndW1lbnRzOgogKiAgZ3VpZDogSUQgb2YgdGhlIHJlcXVlc3RlZCBkcml2ZXIsIE5VTEwgZm9yIHRoZSBkZWZhdWx0IGRyaXZlci4KICogICAgICAgIFRoZSBHVUlEIGNhbiBiZSBxdWVyaWVkIHdpdGggRGlyZWN0RHJhd0VudW1lcmF0ZShFeClBL1cKICogIEREOiBVc2VkIHRvIHJldHVybiB0aGUgcG9pbnRlciB0byB0aGUgY3JlYXRlZCBvYmplY3QKICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24sIHdoaWNoIGlzIHVuc3VwcG9ydGVkLiBNdXN0IGJlIE5VTEwKICogIGlpZDogcmVxdWVzdGVkIHZlcnNpb24gSUQuCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgSW50ZXJmYWNlIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyIGlzIG5vdCBOVUxMCiAqICBFX09VVE9GTUVNT1JZIGlmIHNvbWUgYWxsb2NhdGlvbiBmYWlsZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApERFJBV19DcmVhdGUoR1VJRCAqZ3VpZCwKICAgICAgICAgICAgIHZvaWQgKipERCwKICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlciwKICAgICAgICAgICAgIFJFRklJRCBpaWQpCnsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0QgKndpbmVEM0QgPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2UgKndpbmVEM0REZXZpY2UgPSBOVUxMOwogICAgSERDIGhEQzsKICAgIFdJTkVEM0RERVZUWVBFIGRldmljZXR5cGU7CgogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIERELCBVbmtPdXRlcik7CgogICAgKkREID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBjYXJlIGFib3V0IHRoaXMgZ3VpZHMuIFdlbGwsIHRoZXJlJ3Mgbm8gc3BlY2lhbCBndWlkIGFueXdheQogICAgICogT0ssIHdlIGNvdWxkCiAgICAgKi8KICAgIGlmIChndWlkID09IChHVUlEICopIEREQ1JFQVRFX0VNVUxBVElPTk9OTFkpCiAgICB7CiAgICAgICAgLyogVXNlIHRoZSByZWZlcmVuY2UgZGV2aWNlIGlkLiBUaGlzIGRvZXNuJ3QgYWN0dWFsbHkgY2hhbmdlIGFueXRoaW5nLAogICAgICAgICAqIFdpbmVEM0QgYWx3YXlzIHVzZXMgT3BlbkdMIGZvciBEM0QgcmVuZGVyaW5nLiBPbmUgY291bGQgbWFrZSBpdCByZXF1ZXN0CiAgICAgICAgICogaW5kaXJlY3QgcmVuZGVyaW5nCiAgICAgICAgICovCiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX1JFRjsKICAgIH0KICAgIGVsc2UgaWYoZ3VpZCA9PSAoR1VJRCAqKSBERENSRUFURV9IQVJEV0FSRU9OTFkpCiAgICB7CiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX0hBTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBkZXZpY2V0eXBlID0gMDsKICAgIH0KCiAgICAvKiBERHJhdyBkb2Vzbid0IHN1cHBvcnQgYWdncmVnYXRpb24sIGFjY29yZGluZyB0byBtc2RuICovCiAgICBpZiAoVW5rT3V0ZXIgIT0gTlVMTCkKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwoKICAgIC8qIERpcmVjdERyYXcgY3JlYXRpb24gY29tZXMgaGVyZSAqLwogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdERyYXdJbXBsKSk7CiAgICBpZighVGhpcykKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBjcmVhdGluZyBEaXJlY3REcmF3XG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICAvKiBUaGUgaW50ZXJmYWNlczoKICAgICAqIElEaXJlY3REcmF3IGFuZCBJRGlyZWN0M0QgYXJlIHRoZSBzYW1lIG9iamVjdCwKICAgICAqIFF1ZXJ5SW50ZXJmYWNlIGlzIHVzZWQgdG8gZ2V0IG90aGVyIGludGVyZmFjZXMuCiAgICAgKi8KICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcsICBJRGlyZWN0RHJhdzFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXcyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQsIElEaXJlY3REcmF3NF9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3LCBJRGlyZWN0RHJhdzdfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRCwgIElEaXJlY3QzRDFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDIsIElEaXJlY3QzRDJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDMsIElEaXJlY3QzRDNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDcsIElEaXJlY3QzRDdfVnRibCk7CgogICAgLyogU2VlIGNvbW1lbnRzIGluIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlIGZvciBhIGRlc2NyaXB0aW9uCiAgICAgKiBvZiB0aGlzIG1lbWJlci4KICAgICAqIFJlYWQgZnJvbSBhIHJlZ2lzdHJ5IGtleSwgc2hvdWxkIGFkZCBhIHdpbmVjZmcgb3B0aW9uIGxhdGVyCiAgICAgKi8KICAgIFRoaXMtPkltcGxUeXBlID0gRGVmYXVsdFN1cmZhY2VUeXBlOwoKICAgIC8qIEdldCB0aGUgY3VycmVudCBzY3JlZW4gc2V0dGluZ3MgKi8KICAgIGhEQyA9IENyZWF0ZURDQSgiRElTUExBWSIsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgVGhpcy0+b3JpZ19icHAgPSBHZXREZXZpY2VDYXBzKGhEQywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaERDLCBQTEFORVMpOwogICAgRGVsZXRlREMoaERDKTsKICAgIFRoaXMtPm9yaWdfd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKTsKICAgIFRoaXMtPm9yaWdfaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTik7CgogICAgaWYgKGhXaW5lRDNEID09IChITU9EVUxFKSAtMSkKICAgIHsKICAgICAgICBoV2luZUQzRCA9IExvYWRMaWJyYXJ5QSgid2luZWQzZCIpOwogICAgICAgIGlmIChoV2luZUQzRCkKICAgICAgICAgICAgcFdpbmVEaXJlY3QzRENyZWF0ZSA9IChmbldpbmVEaXJlY3QzRENyZWF0ZSkgR2V0UHJvY0FkZHJlc3MoaFdpbmVEM0QsICJXaW5lRGlyZWN0M0RDcmVhdGUiKTsKICAgIH0KCiAgICBpZiAoIWhXaW5lRDNEKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgbG9hZCBXaW5lRDNEIC0gT3BlbkdMIGxpYnMgbm90IHByZXNlbnQ/XG4iKTsKICAgICAgICBociA9IERERVJSX05PRElSRUNURFJBV1NVUFBPUlQ7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgV2luZUQzRAogICAgICoKICAgICAqIEFsbCBSZW5kZXJpbmcgKDJEIGFuZCAzRCkgaXMgcmVsYXllZCB0byBXaW5lRDNELAogICAgICogYnV0IERpcmVjdERyYXcgc3BlY2lmaWMgbWFuYWdlbWVudCwgbGlrZSBERFNVUkZBQ0VERVNDIGFuZCBERFBJWEVMRk9STUFUCiAgICAgKiBzdHJ1Y3R1cmUgaGFuZGxpbmcgaXMgaGFuZGxlZCBpbiB0aGlzIGxpYi4KICAgICAqLwogICAgd2luZUQzRCA9IHBXaW5lRGlyZWN0M0RDcmVhdGUoMCAvKiBTREtWZXJzaW9uICovLCA3IC8qIERYVmVyc2lvbiAqLywgKElVbmtub3duICopIFRoaXMgLyogUGFyZW50ICovKTsKICAgIGlmKCF3aW5lRDNEKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGluaXRpYWxpc2UgV2luZUQzRFxuIik7CiAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRoaXMtPndpbmVEM0QgPSB3aW5lRDNEOwogICAgVFJBQ0UoIldpbmVEM0QgY3JlYXRlZCBhdCAlcFxuIiwgd2luZUQzRCk7CgogICAgLyogSW5pdGlhbGl6ZWQgbWVtYmVyLi4uCiAgICAgKgogICAgICogSXQgaXMgc2V0IHRvIGZhbHNlIGF0IGNyZWF0aW9uIHRpbWUsIGFuZCBzZXQgdG8gdHJ1ZSBpbgogICAgICogSURpcmVjdERyYXc3OjpJbml0aWFsaXplLiBJdHMgc29sZSBwdXJwb3NlIGlzIHRvIHJldHVybiBERF9PSyBvbgogICAgICogaW5pdGlhbGl6ZSBvbmx5IG9uY2UKICAgICAqLwogICAgVGhpcy0+aW5pdGlhbGl6ZWQgPSBGQUxTRTsKCiAgICAvKiBJbml0aWFsaXplIFdpbmVEM0REZXZpY2UKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIGZvciBzY3JlZW4gc2V0dXAsIHN1cmZhY2UgYW5kIHBhbGV0dGUgY3JlYXRpb24KICAgICAqIFdoZW4gYSBEaXJlY3QzRERldmljZTcgaXMgY3JlYXRlZCwgdGhlIEQzRCBjYXBhYmlsaXRpZXMgb2YgV2luZUQzRCBhcmUKICAgICAqIGluaXRpYWxpemVkCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RfQ3JlYXRlRGV2aWNlKHdpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qRDNEX0FEQVBURVJfREVGQVVMVCovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNldHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIC8qIEZvY3VzV2luZG93LCBkb24ndCBrbm93IHlldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogQmVoYXZpb3JGbGFncyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIHdpbmVEM0REZXZpY2UsIHJlc3VsdCA9ICV4XG4iLCBocik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQogICAgVGhpcy0+d2luZUQzRERldmljZSA9IHdpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgid2luZUQzRERldmljZSBjcmVhdGVkIGF0ICVwXG4iLCBUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBSZWdpc3RlciB0aGUgd2luZG93IGNsYXNzCiAgICAgKgogICAgICogSXQgaXMgdXNlZCB0byBjcmVhdGUgYSBoaWRkZW4gd2luZG93IGZvciBEM0QKICAgICAqIHJlbmRlcmluZywgaWYgdGhlIGFwcGxpY2F0aW9uIGRpZG4ndCBwYXNzIG9uZS4KICAgICAqIEl0IGNhbiBhbHNvIGJlIHVzZWQgZm9yIENyZWF0aW5nIGEgZGV2aWNlIHdpbmRvdwogICAgICogZnJvbSBTZXRDb29wZXJhdGl2ZUxldmVsCiAgICAgKgogICAgICogVGhlIG5hbWU6IEREUkFXXzxhZGRyZXNzPi4gVGhlIGNsYXNzbmFtZSBpcwogICAgICogMzIgYml0IGxvbmcsIHNvIGEgNjQgYml0IGFkZHJlc3Mgd2lsbCBmaXQgbmljZWx5CiAgICAgKiAoV2lsbCB0aGlzIGJlIGNvbXBpbGVkIGZvciA2NCBiaXQgYW55d2F5PykKICAgICAqCiAgICAgKi8KICAgIHNwcmludGYoVGhpcy0+Y2xhc3NuYW1lLCAiRERSQVdfJXAiLCBUaGlzKTsKCiAgICBtZW1zZXQoJlRoaXMtPnduZF9jbGFzcywgMCwgc2l6ZW9mKFRoaXMtPnduZF9jbGFzcykpOwogICAgVGhpcy0+d25kX2NsYXNzLnN0eWxlID0gQ1NfSFJFRFJBVyB8IENTX1ZSRURSQVc7CiAgICBUaGlzLT53bmRfY2xhc3MubHBmblduZFByb2MgPSBEZWZXaW5kb3dQcm9jQTsKICAgIFRoaXMtPnduZF9jbGFzcy5jYkNsc0V4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5jYlduZEV4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oSW5zdGFuY2UgPSBHZXRNb2R1bGVIYW5kbGVBKDApOwogICAgVGhpcy0+d25kX2NsYXNzLmhJY29uID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oQ3Vyc29yID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkgR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgVGhpcy0+d25kX2NsYXNzLmxwc3pNZW51TmFtZSA9IE5VTEw7CiAgICBUaGlzLT53bmRfY2xhc3MubHBzekNsYXNzTmFtZSA9IFRoaXMtPmNsYXNzbmFtZTsKICAgIGlmKCFSZWdpc3RlckNsYXNzQSgmVGhpcy0+d25kX2NsYXNzKSkKICAgIHsKICAgICAgICBFUlIoIlJlZ2lzdGVyQ2xhc3NBIGZhaWxlZCFcbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIGFtb3VudCBvZiB2aWRlbyBtZW1vcnkgKi8KICAgIFRoaXMtPnRvdGFsX3ZpZG1lbSA9IElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgY2FwcyAqLwogICAgVGhpcy0+Y2Fwcy5kd1NpemUgPSBzaXplb2YoVGhpcy0+Y2Fwcyk7Ci8qIGRvIG5vdCByZXBvcnQgRERDQVBTX09WRVJMQVkgYW5kIGZyaWVuZHMgc2luY2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cyAqLwojZGVmaW5lIEJMSVRfQ0FQUyAoRERDQVBTX0JMVCB8IEREQ0FQU19CTFRDT0xPUkZJTEwgfCBERENBUFNfQkxUREVQVEhGSUxMIFwKICAgICAgICAgIHwgRERDQVBTX0JMVFNUUkVUQ0ggfCBERENBUFNfQ0FOQkxUU1lTTUVNIHwgRERDQVBTX0NBTkNMSVAJICBcCiAgICAgICAgICB8IEREQ0FQU19DQU5DTElQU1RSRVRDSEVEIHwgRERDQVBTX0NPTE9SS0VZCQkJICBcCiAgICAgICAgICB8IEREQ0FQU19DT0xPUktFWUhXQVNTSVNUIHwgRERDQVBTX0FMSUdOQk9VTkRBUllTUkMgKQojZGVmaW5lIENLRVlfQ0FQUyAoRERDS0VZQ0FQU19ERVNUQkxUIHwgRERDS0VZQ0FQU19TUkNCTFQpCiNkZWZpbmUgRlhfQ0FQUyAoRERGWENBUFNfQkxUQUxQSEEgfCBEREZYQ0FQU19CTFRNSVJST1JMRUZUUklHSFQJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRNSVJST1JVUERPV04gfCBEREZYQ0FQU19CTFRST1RBVElPTjkwCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU0hSSU5LWCB8IERERlhDQVBTX0JMVFNIUklOS1hOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNIUklOS1kgfCBEREZYQ0FQU19CTFRTSFJJTktYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWCB8IERERlhDQVBTX0JMVFNUUkVUQ0hYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWSB8IERERlhDQVBTX0JMVFNUUkVUQ0hZTikKICAgIFRoaXMtPmNhcHMuZHdDYXBzIHw9IEREQ0FQU19HREkgfCBERENBUFNfUEFMRVRURSB8IEJMSVRfQ0FQUzsKCiAgICBUaGlzLT5jYXBzLmR3Q2FwczIgfD0gRERDQVBTMl9DRVJUSUZJRUQgfCBERENBUFMyX05PUEFHRUxPQ0tSRVFVSVJFRCB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9QUklNQVJZR0FNTUEgfCBERENBUFMyX1dJREVTVVJGQUNFUyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9DQU5SRU5ERVJXSU5ET1dFRDsKICAgIFRoaXMtPmNhcHMuZHdDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3RlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3UGFsQ2FwcyB8PSBERFBDQVBTXzhCSVQgfCBERFBDQVBTX1BSSU1BUllTVVJGQUNFOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbVRvdGFsID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbUZyZWUgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NWQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdWU0JGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1NCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfQUxQSEEgfCBERFNDQVBTX0JBQ0tCVUZGRVIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0ZMSVAgfCBERFNDQVBTX0ZST05UQlVGRkVSIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19PRkZTQ1JFRU5QTEFJTiB8IEREU0NBUFNfUEFMRVRURSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTX1NZU1RFTU1FTU9SWSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVklERU9NRU1PUlkgfCBERFNDQVBTX1ZJU0lCTEU7CiAgICAvKiBIYWNrcyBmb3IgRDNEIGNvZGUgKi8KICAgIC8qIFRPRE86IENoZWNrIGlmIFdpbmVEM0QgaGFzIDNEIGVuYWJsZWQKICAgICAgIE5lZWQgb3BlbmdsIHN1cmZhY2VzIG9yIGF1dG8gZm9yIDNECiAgICAgKi8KICAgIGlmKFRoaXMtPkltcGxUeXBlID09IDAgfHwgVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9PUEVOR0wpCiAgICB7CiAgICAgICAgVGhpcy0+Y2Fwcy5kd0NhcHMgfD0gRERDQVBTXzNEOwogICAgICAgIFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU18zRERFVklDRSB8IEREU0NBUFNfTUlQTUFQIHwgRERTQ0FQU19URVhUVVJFIHwgRERTQ0FQU19aQlVGRkVSOwogICAgfQogICAgVGhpcy0+Y2Fwcy5kZHNPbGRDYXBzLmR3Q2FwcyA9IFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHM7CgojdW5kZWYgQkxJVF9DQVBTCiN1bmRlZiBDS0VZX0NBUFMKI3VuZGVmIEZYX0NBUFMKCiAgICBsaXN0X2luaXQoJlRoaXMtPnN1cmZhY2VfbGlzdCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2xpc3RfY3MpOwogICAgbGlzdF9hZGRfaGVhZCgmZ2xvYmFsX2RkcmF3X2xpc3QsICZUaGlzLT5kZHJhd19saXN0X2VudHJ5KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19saXN0X2NzKTsKCiAgICAvKiBDYWxsIFF1ZXJ5SW50ZXJmYWNlIHRvIGdldCB0aGUgcG9pbnRlciB0byB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4gVGhpcyBhbHNvIGluaXRpYWxpemVzCiAgICAgKiBUaGUgcmVxdWlyZWQgcmVmY291bnQKICAgICAqLwogICAgaHIgPSBJRGlyZWN0RHJhdzdfUXVlcnlJbnRlcmZhY2UoIElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NyksIGlpZCwgREQpOwogICAgaWYoU1VDQ0VFREVEKGhyKSkgcmV0dXJuIEREX09LOwoKZXJyX291dDoKICAgIC8qIExldCdzIGhvcGUgd2UgbmV2ZXIgbmVlZCB0aGlzIDspICovCiAgICBpZih3aW5lRDNERGV2aWNlKSBJV2luZUQzRERldmljZV9SZWxlYXNlKHdpbmVEM0REZXZpY2UpOwogICAgaWYod2luZUQzRCkgSVdpbmVEM0RfUmVsZWFzZSh3aW5lRDNEKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZSAoRERSQVcuQCkKICoKICogQ3JlYXRlcyBsZWdhY3kgRGlyZWN0RHJhdyBJbnRlcmZhY2VzLiBDYW4ndCBjcmVhdGUgSURpcmVjdERyYXc3CiAqIGludGVyZmFjZXMgaW4gdGhlb3J5CiAqCiAqIEFyZ3VtZW50cywgcmV0dXJuIHZhbHVlczogU2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGUoR1VJRCAqR1VJRCwKICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdyAqKkRELAogICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBVbmtPdXRlcik7CgogICAgcmV0dXJuIEREUkFXX0NyZWF0ZShHVUlELCAodm9pZCAqKikgREQsIFVua091dGVyLCAmSUlEX0lEaXJlY3REcmF3KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGVFeCAoRERSQVcuQCkKICoKICogT25seSBjcmVhdGVzIG5ldyBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlcywgc3VwcG9zZWQgdG8gZmFpbCBpZiBsZWdhY3kKICogaW50ZXJmYWNlcyBhcmUgcmVxdWVzdGVkLgogKgogKiBBcmd1bWVudHMsIHJldHVybiB2YWx1ZXM6IFNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3Q3JlYXRlRXgoR1VJRCAqR1VJRCwKICAgICAgICAgICAgICAgICAgIHZvaWQgKipERCwKICAgICAgICAgICAgICAgICAgIFJFRklJRCBpaWQsCiAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIFRSQUNFKCIoJXMsJXAsJXMsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKEdVSUQpLCBERCwgZGVidWdzdHJfZ3VpZChpaWQpLCBVbmtPdXRlcik7CgogICAgaWYgKCFJc0VxdWFsR1VJRChpaWQsICZJSURfSURpcmVjdERyYXc3KSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICByZXR1cm4gRERSQVdfQ3JlYXRlKEdVSUQsIERELCBVbmtPdXRlciwgaWlkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVBIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIGxlZ2FjeSBkZHJhdyBkcml2ZXJzLCBhc2NpaSB2ZXJzaW9uLiBXZSBvbmx5IGhhdmUgb25lCiAqIGRyaXZlciwgd2hpY2ggcmVsYXlzIHRvIFdpbmVEM0QuIElmIHdlIHdlcmUgc3VmZmljaWVudGx5IGNvb2wsCiAqIHdlIGNvdWxkIG9mZmVyIHZhcmlvdXMgaW50ZXJmYWNlcywgd2hpY2ggdXNlIGEgZGlmZmVyZW50IGRlZmF1bHQgc3VyZmFjZQogKiBpbXBsZW1lbnRhdGlvbiwgYnV0IEkgdGhpbmsgaXQncyBiZXR0ZXIgdG8gb2ZmZXIgdGhpcyBjaG9pY2UgaW4KICogd2luZWNmZywgYmVjYXVzZSBzb21lIGFwcHMgdXNlIHRoZSBkZWZhdWx0IGRyaXZlciwgc28gd2Ugd291bGQgbmVlZAogKiBhIHdpbmVjZmcgb3B0aW9uIGFueXdheSwgYW5kIHRoZXJlIHNob3VsZG4ndCBiZSAyIHdheXMgdG8gc2V0IG9uZSBzZXR0aW5nCiAqCiAqIEFyZ3VtZW50czoKICogIENhbGxiYWNrOiBDYWxsYmFjayBmdW5jdGlvbiBmcm9tIHRoZSBhcHAKICogIENvbnRleHQ6IEFyZ3VtZW50IHRvIHRoZSBjYWxsIGJhY2suCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBFX0lOVkFMSURBUkcgaWYgdGhlIENhbGxiYWNrIGNhdXNlZCBhIHBhZ2UgZmF1bHQKICoKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3RW51bWVyYXRlQShMUERERU5VTUNBTExCQUNLQSBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCkKewogICAgQk9PTCBzdG9wID0gRkFMU0U7CgogICAgVFJBQ0UoIiBFbnVtZXJhdGluZyBkZWZhdWx0IERpcmVjdERyYXcgSEFMIGludGVyZmFjZVxuIik7CiAgICAvKiBXZSBvbmx5IGhhdmUgb25lIGRyaXZlciAqLwogICAgX19UUlkKICAgIHsKICAgICAgICBzdGF0aWMgQ0hBUiBkcml2ZXJfZGVzY1tdID0gIkRpcmVjdERyYXcgSEFMIiwKICAgICAgICBkcml2ZXJfbmFtZVtdID0gImRpc3BsYXkiOwoKICAgICAgICBzdG9wID0gIUNhbGxiYWNrKE5VTEwsIGRyaXZlcl9kZXNjLCBkcml2ZXJfbmFtZSwgQ29udGV4dCk7CiAgICB9CiAgICBfX0VYQ0VQVF9QQUdFX0ZBVUxUCiAgICB7CiAgICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKICAgIH0KICAgIF9fRU5EVFJZCgogICAgVFJBQ0UoIiBFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUV4QSAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBEaXJlY3REcmF3NyBkcml2ZXJzLCBhc2NpaSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3RW51bWVyYXRlRXhBKExQRERFTlVNQ0FMTEJBQ0tFWEEgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgQk9PTCBzdG9wID0gRkFMU0U7CiAgICBUUkFDRSgiRW51bWVyYXRpbmcgZGVmYXVsdCBEaXJlY3REcmF3IEhBTCBpbnRlcmZhY2VcbiIpOwoKICAgIC8qIFdlIG9ubHkgaGF2ZSBvbmUgZHJpdmVyIGJ5IG5vdyAqLwogICAgX19UUlkKICAgIHsKICAgICAgICBzdGF0aWMgQ0hBUiBkcml2ZXJfZGVzY1tdID0gIkRpcmVjdERyYXcgSEFMIiwKICAgICAgICBkcml2ZXJfbmFtZVtdID0gImRpc3BsYXkiOwoKICAgICAgICAvKiBRdWlja1RpbWUgZXhwZWN0cyB0aGUgZGVzY3JpcHRpb24gIkRpcmVjdERyYXcgSEFMIiAqLwogICAgICAgIHN0b3AgPSAhQ2FsbGJhY2soTlVMTCwgZHJpdmVyX2Rlc2MsIGRyaXZlcl9uYW1lLCBDb250ZXh0LCAwKTsKICAgIH0KICAgIF9fRVhDRVBUX1BBR0VfRkFVTFQKICAgIHsKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwogICAgfQogICAgX19FTkRUUlk7CgogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlVyAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBsZWdhY3kgZHJpdmVycywgdW5pY29kZSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVFeFcgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgRGlyZWN0RHJhdzcgZHJpdmVycywgdW5pY29kZSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENsYXNzZmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENGX0NyZWF0ZURpcmVjdERyYXcKICoKICogRERyYXcgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBhcmFtczoKICogIFVua091dGVyOiBTZXQgdG8gTlVMTAogKiAgaWlkOiBJRCBvZiB0aGUgd2FudGVkIGludGVyZmFjZQogKiAgb2JqOiBBZGRyZXNzIHRvIHBhc3MgdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sKICoKICogUmV0dXJucwogKiAgRERfT0sgLyBEREVSUiosIHNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDRl9DcmVhdGVEaXJlY3REcmF3KElVbmtub3duKiBVbmtPdXRlciwgUkVGSUlEIGlpZCwKICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBVbmtPdXRlciwgZGVidWdzdHJfZ3VpZChpaWQpLCBvYmopOwoKICAgIGhyID0gRERSQVdfQ3JlYXRlKE5VTEwsIG9iaiwgVW5rT3V0ZXIsIGlpZCk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDRl9DcmVhdGVEaXJlY3REcmF3CiAqCiAqIENsaXBwZXIgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBhcmFtczoKICogIFVua091dGVyOiBTZXQgdG8gTlVMTAogKiAgaWlkOiBJRCBvZiB0aGUgd2FudGVkIGludGVyZmFjZQogKiAgb2JqOiBBZGRyZXNzIHRvIHBhc3MgdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sKICoKICogUmV0dXJucwogKiAgRERfT0sgLyBEREVSUiosIHNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDRl9DcmVhdGVEaXJlY3REcmF3Q2xpcHBlcihJVW5rbm93biogVW5rT3V0ZXIsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdDbGlwcGVyICpDbGlwOwoKICAgIGhyID0gRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoMCwgJkNsaXAsIFVua091dGVyKTsKICAgIGlmIChociAhPSBERF9PSykgcmV0dXJuIGhyOwoKICAgIGhyID0gSURpcmVjdERyYXdDbGlwcGVyX1F1ZXJ5SW50ZXJmYWNlKENsaXAsIHJpaWQsIG9iaik7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXJfUmVsZWFzZShDbGlwKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBvYmplY3RfY3JlYXRpb25faW5mbyBvYmplY3RfY3JlYXRpb25bXSA9CnsKICAgIHsgJkNMU0lEX0RpcmVjdERyYXcsICAgICAgICBDRl9DcmVhdGVEaXJlY3REcmF3IH0sCiAgICB7ICZDTFNJRF9EaXJlY3REcmF3NywgICAgICAgQ0ZfQ3JlYXRlRGlyZWN0RHJhdyB9LAogICAgeyAmQ0xTSURfRGlyZWN0RHJhd0NsaXBwZXIsIENGX0NyZWF0ZURpcmVjdERyYXdDbGlwcGVyIH0KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpRdWVyeUludGVyZmFjZQogKgogKiBRdWVyeUludGVyZmFjZSBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUEFSQU1TCiAqICAgIHJpaWQgICBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBxdWVyaWVkIGludGVyZmFjZQogKiAgICBwcHYgICAgQWRkcmVzcyB0byByZXR1cm4gdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBFX05PSU5URVJGQUNFCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1F1ZXJ5SW50ZXJmYWNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIG9iaik7CgogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSkKICAgIHsKICAgICAgICBJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CiAgICAgICAgKm9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgV0FSTigiKCVwKS0+KCVzLCVwKSxub3QgZm91bmRcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkFkZFJlZgogKgogKiBBZGRSZWYgZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0FkZFJlZihJQ2xhc3NGYWN0b3J5ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApLT4oKSBpbmNyZW1lbnRpbmcgZnJvbSAlZC5cbiIsIFRoaXMsIHJlZiAtIDEpOwoKICAgIHJldHVybiByZWY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpSZWxlYXNlCiAqCiAqIFJlbGVhc2UgZm9yIHRoZSBjbGFzcyBmYWN0b3J5LiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlIG9iamVjdAogKiBpcyBkZXN0cm95ZWQKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUmVsZWFzZShJQ2xhc3NGYWN0b3J5ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBmcm9tICVkLlxuIiwgVGhpcywgcmVmKzEpOwoKICAgIGlmIChyZWYgPT0gMCkKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gcmVmOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkNyZWF0ZUluc3RhbmNlCiAqCiAqIFdoYXQgaXMgdGhpcz8gU2VlbXMgdG8gY3JlYXRlIERpcmVjdERyYXcgb2JqZWN0cy4uLgogKgogKiBQYXJhbXMKICogIFRoZSB1c3VzYWwgdGhpbmdzPz8/CiAqCiAqIFJFVFVSTlMKICogID8/PwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9DcmVhdGVJbnN0YW5jZShJQ2xhc3NGYWN0b3J5ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVzLCVwKVxuIixUaGlzLFVua091dGVyLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKCiAgICByZXR1cm4gVGhpcy0+cGZuQ3JlYXRlSW5zdGFuY2UoVW5rT3V0ZXIsIHJpaWQsIG9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpMb2NrU2VydmVyCiAqCiAqIFdoYXQgaXMgdGhpcz8KICoKICogUGFyYW1zCiAqICA/Pz8KICoKICogUkVUVVJOUwogKiAgU19PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9Mb2NrU2VydmVyKElDbGFzc0ZhY3RvcnkgKmlmYWNlLEJPT0wgZG9sb2NrKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglZCksc3R1YiFcbiIsVGhpcyxkb2xvY2spOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBjbGFzcyBmYWN0b3J5IFZUYWJsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsIElDbGFzc0ZhY3RvcnlfVnRibCA9CnsKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUmVsZWFzZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9DcmVhdGVJbnN0YW5jZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9Mb2NrU2VydmVyCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxHZXRDbGFzc09iamVjdCBbRERSQVcuQF0KICogUmV0cmlldmVzIGNsYXNzIG9iamVjdCBmcm9tIGEgRExMIG9iamVjdAogKgogKiBOT1RFUwogKiAgICBEb2NzIHNheSByZXR1cm5zIFNUREFQSQogKgogKiBQQVJBTVMKICogICAgcmNsc2lkIFtJXSBDTFNJRCBmb3IgdGhlIGNsYXNzIG9iamVjdAogKiAgICByaWlkICAgW0ldIFJlZmVyZW5jZSB0byBpZGVudGlmaWVyIG9mIGludGVyZmFjZSBmb3IgY2xhc3Mgb2JqZWN0CiAqICAgIHBwdiAgICBbT10gQWRkcmVzcyBvZiB2YXJpYWJsZSB0byByZWNlaXZlIGludGVyZmFjZSBwb2ludGVyIGZvciByaWlkCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFLCBFX09VVE9GTUVNT1JZLCBFX0lOVkFMSURBUkcsCiAqICAgICAgICAgICAgIEVfVU5FWFBFQ1RFRAogKi8KSFJFU1VMVCBXSU5BUEkgRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHVuc2lnbmVkIGludCBpOwogICAgSUNsYXNzRmFjdG9yeUltcGwgKmZhY3Rvcnk7CgogICAgVFJBQ0UoIiglcywlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKCiAgICBpZiAoICFJc0VxdWFsR1VJRCggJklJRF9JQ2xhc3NGYWN0b3J5LCByaWlkICkKCSAmJiAhIElzRXF1YWxHVUlEKCAmSUlEX0lVbmtub3duLCByaWlkKSApCglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgICBmb3IgKGk9MDsgaSA8IHNpemVvZihvYmplY3RfY3JlYXRpb24pL3NpemVvZihvYmplY3RfY3JlYXRpb25bMF0pOyBpKyspCiAgICB7CglpZiAoSXNFcXVhbEdVSUQob2JqZWN0X2NyZWF0aW9uW2ldLmNsc2lkLCByY2xzaWQpKQoJICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChpID09IHNpemVvZihvYmplY3RfY3JlYXRpb24pL3NpemVvZihvYmplY3RfY3JlYXRpb25bMF0pKQogICAgewoJRklYTUUoIiVzOiBubyBjbGFzcyBmb3VuZC5cbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CglyZXR1cm4gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKICAgIH0KCiAgICBmYWN0b3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqZmFjdG9yeSkpOwogICAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShmYWN0b3J5LCBJQ2xhc3NGYWN0b3J5LCBJQ2xhc3NGYWN0b3J5X1Z0YmwpOwogICAgZmFjdG9yeS0+cmVmID0gMTsKCiAgICBmYWN0b3J5LT5wZm5DcmVhdGVJbnN0YW5jZSA9IG9iamVjdF9jcmVhdGlvbltpXS5wZm5DcmVhdGVJbnN0YW5jZTsKCiAgICAqcHB2ID0gSUNPTV9JTlRFUkZBQ0UoZmFjdG9yeSwgSUNsYXNzRmFjdG9yeSk7CiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbENhblVubG9hZE5vdyBbRERSQVcuQF0gIERldGVybWluZXMgd2hldGhlciB0aGUgRExMIGlzIGluIHVzZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IFNfRkFMU0UKICovCkhSRVNVTFQgV0lOQVBJIERsbENhblVubG9hZE5vdyh2b2lkKQp7CiAgICBGSVhNRSgiKHZvaWQpOiBzdHViXG4iKTsKICAgIHJldHVybiBTX0ZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZXN0cm95Q2FsbGJhY2sKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBFbnVtU3VyZmFjZXMgY2FsbCBpbiBEbGxNYWluLgogKiBEdW1wcyBzb21lIHN1cmZhY2UgaW5mbyBhbmQgcmVsZWFzZXMgdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgc3VyZjogVGhlIGVudW1lcmF0ZWQgc3VyZmFjZQogKiAgZGVzYzogaXQncyBkZXNjcmlwdGlvbgogKiAgY29udGV4dDogUG9pbnRlciB0byB0aGUgZGRyYXcgaW1wbAogKgogKiBSZXR1cm5zOgogKiAgRERFTlVNUkVUX09LOwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkRlc3Ryb3lDYWxsYmFjayhJRGlyZWN0RHJhd1N1cmZhY2U3ICpzdXJmLAogICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0KQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgc3VyZik7CiAgICBJRGlyZWN0RHJhd0ltcGwgKmRkcmF3ID0gKElEaXJlY3REcmF3SW1wbCAqKSBjb250ZXh0OwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsgIC8qIEZvciB0aGUgRW51bVN1cmZhY2VzICovCiAgICBXQVJOKCJTdXJmYWNlICVwIGhhcyBhbiByZWZlcmVuY2UgY291bnQgb2YgJWRcbiIsIEltcGwsIHJlZik7CgogICAgLyogU2tpcCBzdXJmYWNlcyB3aGljaCBhcmUgYXR0YWNoZWQgc29tZXdoZXJlIG9yIHdoaWNoIGFyZQogICAgICogcGFydCBvZiBhIGNvbXBsZXggY29tcG91bmQuIFRoZXkgd2lsbCBnZXQgcmVsZWFzZWQgd2hlbiBkZXN0cm95aW5nCiAgICAgKiB0aGUgcm9vdAogICAgICovCiAgICBpZiggKEltcGwtPmZpcnN0X2NvbXBsZXggIT0gSW1wbCkgfHwgKEltcGwtPmZpcnN0X2F0dGFjaGVkICE9IEltcGwpICkKICAgICAgICByZXR1cm4gRERFTlVNUkVUX09LOwogICAgLyogU2tpcCBvdXIgZGVwdGggc3RlbmNpbCBzdXJmYWNlLCBpdCB3aWxsIGJlIHJlbGVhc2VkIHdpdGggdGhlIHJlbmRlciB0YXJnZXQgKi8KICAgIGlmKCBJbXBsID09IGRkcmF3LT5EZXB0aFN0ZW5jaWxCdWZmZXIpCiAgICAgICAgcmV0dXJuIERERU5VTVJFVF9PSzsKCiAgICAvKiBEZXN0cm95IHRoZSBzdXJmYWNlICovCiAgICB3aGlsZShyZWYpIHJlZiA9IElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsKCiAgICByZXR1cm4gRERFTlVNUkVUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2NvbmZpZ19rZXkKICoKICogUmVhZHMgYSBjb25maWcga2V5IGZyb20gdGhlIHJlZ2lzdHJ5LiBUYWtlbiBmcm9tIFdpbmVEM0QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwppbmxpbmUgc3RhdGljIERXT1JEIGdldF9jb25maWdfa2V5KEhLRVkgZGVma2V5LCBIS0VZIGFwcGtleSwgY29uc3QgY2hhciogbmFtZSwgY2hhciogYnVmZmVyLCBEV09SRCBzaXplKQp7CiAgICBpZiAoMCAhPSBhcHBrZXkgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoIGFwcGtleSwgbmFtZSwgMCwgTlVMTCwgKExQQllURSkgYnVmZmVyLCAmc2l6ZSApKSByZXR1cm4gMDsKICAgIGlmICgwICE9IGRlZmtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggZGVma2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsTWFpbiAoRERSQVcuMCkKICoKICogQ291bGQgYmUgdXNlZCB0byByZWdpc3RlciBEaXJlY3REcmF3IGRyaXZlcnMsIGlmIHdlIGhhdmUgbW9yZSB0aGFuCiAqIG9uZS4gQWxzbyB1c2VkIHRvIGRlc3Ryb3kgYW55IG9iamVjdHMgbGVmdCBhdCB1bmxvYWQgaWYgdGhlCiAqIGFwcCBkaWRuJ3QgcmVsZWFzZSB0aGVtIHByb3Blcmx5KEdvdGhpYyAyLCBEaWFibG8gMiwgTW90byByYWNlciwgLi4uKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkJPT0wgV0lOQVBJCkRsbE1haW4oSElOU1RBTkNFIGhJbnN0RExMLAogICAgICAgIERXT1JEIFJlYXNvbiwKICAgICAgICB2b2lkICpscHYpCnsKICAgIFRSQUNFKCIoJXAsJXgsJXApXG4iLCBoSW5zdERMTCwgUmVhc29uLCBscHYpOwogICAgaWYgKFJlYXNvbiA9PSBETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgY2hhciBidWZmZXJbTUFYX1BBVEgrMTBdOwogICAgICAgIERXT1JEIHNpemUgPSBzaXplb2YoYnVmZmVyKTsKICAgICAgICBIS0VZIGhrZXkgPSAwOwogICAgICAgIEhLRVkgYXBwa2V5ID0gMDsKICAgICAgICBEV09SRCBsZW47CgogICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxEaXJlY3QzRCAqLwogICAgICAgaWYgKCBSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcRGlyZWN0M0QiLCAmaGtleSApICkgaGtleSA9IDA7CgogICAgICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKCAwLCBidWZmZXIsIE1BWF9QQVRIICk7CiAgICAgICBpZiAobGVuICYmIGxlbiA8IE1BWF9QQVRIKQogICAgICAgewogICAgICAgICAgICBIS0VZIHRtcGtleTsKICAgICAgICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxBcHBEZWZhdWx0c1xhcHAuZXhlXERpcmVjdDNEICovCiAgICAgICAgICAgIGlmICghUmVnT3BlbktleUEoIEhLRVlfQ1VSUkVOVF9VU0VSLCAiU29mdHdhcmVcXFdpbmVcXEFwcERlZmF1bHRzIiwgJnRtcGtleSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyICpwLCAqYXBwbmFtZSA9IGJ1ZmZlcjsKICAgICAgICAgICAgICAgIGlmICgocCA9IHN0cnJjaHIoIGFwcG5hbWUsICcvJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJ1xcJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgc3RyY2F0KCBhcHBuYW1lLCAiXFxEaXJlY3QzRCIgKTsKICAgICAgICAgICAgICAgIFRSQUNFKCJhcHBuYW1lID0gWyVzXVxuIiwgYXBwbmFtZSk7CiAgICAgICAgICAgICAgICBpZiAoUmVnT3BlbktleUEoIHRtcGtleSwgYXBwbmFtZSwgJmFwcGtleSApKSBhcHBrZXkgPSAwOwogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoIHRtcGtleSApOwogICAgICAgICAgICB9CiAgICAgICB9CgogICAgICAgaWYgKCAwICE9IGhrZXkgfHwgMCAhPSBhcHBrZXkgKQogICAgICAgewogICAgICAgICAgICBpZiAoICFnZXRfY29uZmlnX2tleSggaGtleSwgYXBwa2V5LCAiRGlyZWN0RHJhd1JlbmRlcmVyIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiZ2RpIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkRlZmF1bHRpbmcgdG8gR0RJIHN1cmZhY2VzXG4iKTsKICAgICAgICAgICAgICAgICAgICBEZWZhdWx0U3VyZmFjZVR5cGUgPSBTVVJGQUNFX0dESTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJvcGVuZ2wiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBvcGVuZ2wgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigiVW5rbm93biBkZWZhdWx0IHN1cmZhY2UgdHlwZS4gU3VwcG9ydGVkIGFyZTpcbiBnZGksIG9wZW5nbFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaEluc3RETEwpOwogICAgfQogICAgZWxzZSBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0RFVEFDSCkKICAgIHsKICAgICAgICBpZighbGlzdF9lbXB0eSgmZ2xvYmFsX2RkcmF3X2xpc3QpKQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmVudHJ5LCAqZW50cnkyOwogICAgICAgICAgICBXQVJOKCJUaGVyZSBhcmUgc3RpbGwgZXhpc3RpbmcgRGlyZWN0RHJhdyBpbnRlcmZhY2VzLiBXaW5lIGJ1ZyBvciBidWdneSBhcHBsaWNhdGlvbj9cbiIpOwoKICAgICAgICAgICAgLyogV2UgcmVtb3ZlIGVsZW1ldHMgZnJvbSB0aGlzIGxvb3AgKi8KICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9TQUZFKGVudHJ5LCBlbnRyeTIsICZnbG9iYWxfZGRyYXdfbGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICAgICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXcgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd0ltcGwsIGRkcmF3X2xpc3RfZW50cnkpOwoKICAgICAgICAgICAgICAgIFdBUk4oIkREcmF3ICVwIGhhcyBhIHJlZmNvdW50IG9mICVkXG4iLCBkZHJhdywgZGRyYXctPnJlZjcgKyBkZHJhdy0+cmVmNCArIGRkcmF3LT5yZWYyICsgZGRyYXctPnJlZjEpOwoKICAgICAgICAgICAgICAgIC8qIEFkZCByZWZlcmVuY2VzIHRvIGVhY2ggaW50ZXJmYWNlIHRvIGF2b2lkIGZyZWVpbmcgdGhlbSB1bmV4cGVjdGFkZWx5ICovCiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3KSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzJfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzIpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3NF9BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NCkpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXc3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSk7CgogICAgICAgICAgICAgICAgLyogRG9lcyBhIEQzRCBkZXZpY2UgZXhpc3Q/IERlc3Ryb3kgaXQKICAgICAgICAgICAgICAgICAgICAqIFRPRE86IERlc3Ryb3kgYWxsIFZlcnRleCBidWZmZXJzLCBMaWdodHMsIE1hdGVyaWFscwogICAgICAgICAgICAgICAgICAgICogYW5kIGV4ZWN0dXJlIGJ1ZmZlcnMgdG9vCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmKGRkcmF3LT5kM2RkZXZpY2UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgV0FSTigiRERyYXcgJXAgaGFzIGQzZGRldmljZSAlcCBhdHRhY2hlZFxuIiwgZGRyYXcsIGRkcmF3LT5kM2RkZXZpY2UpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3QzRERldmljZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdy0+ZDNkZGV2aWNlLCBJRGlyZWN0M0REZXZpY2U3KSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFRyeSB0byByZWxlYXNlIHRoZSBvYmplY3RzCiAgICAgICAgICAgICAgICAgICAgKiBEbyBhbiBFbnVtU3VyZmFjZXMgdG8gZmluZCBhbnkgaGFuZ2luZyBzdXJmYWNlcwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICAgICAgICAgICAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8PSAxOyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaHIgPSBJRGlyZWN0RHJhdzdfRW51bVN1cmZhY2VzKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERFTlVNU1VSRkFDRVNfQUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBkZHJhdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3Ryb3lDYWxsYmFjayk7CiAgICAgICAgICAgICAgICAgICAgaWYoaHIgIT0gRDNEX09LKQogICAgICAgICAgICAgICAgICAgICAgICBFUlIoIiglcCkgRW51bVN1cmZhY2VzIGZhaWxlZCwgcHJlcGFyZSBmb3IgdHJvdWJsZVxuIiwgZGRyYXcpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIENoZWNrIHRoZSBzdXJmYWNlIGNvdW50ICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+c3VyZmFjZXMgPiAwKQogICAgICAgICAgICAgICAgICAgIEVSUigiRERyYXcgJXAgc3RpbGwgaGFzICVkIHN1cmZhY2VzIGF0dGFjaGVkXG4iLCBkZHJhdywgZGRyYXctPnN1cmZhY2VzKTsKCiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIGFsbCBoYW5naW5nIHJlZmVyZW5jZXMgdG8gZGVzdHJveSB0aGUgb2JqZWN0cy4gVGhpcwogICAgICAgICAgICAgICAgICAgICogcmVzdG9yZXMgdGhlIHNjcmVlbiBtb2RlIHRvbwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhd19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdykpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3Ml9SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzIpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzRfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc0KSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXc3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NykpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKdm9pZApyZW1vdmVfZGRyYXdfb2JqZWN0KElEaXJlY3REcmF3SW1wbCAqZGRyYXcpCnsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19saXN0X2NzKTsKICAgIGxpc3RfcmVtb3ZlKCZkZHJhdy0+ZGRyYXdfbGlzdF9lbnRyeSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfbGlzdF9jcyk7Cn0K