LyogLSotIHRhYi13aWR0aDogODsgYy1iYXNpYy1vZmZzZXQ6IDQgLSotICovCi8qCiAqIE1NSU8gZnVuY3Rpb25zCiAqCiAqIENvcHlyaWdodCAxOTk4IEFuZHJldyBUYXlsb3IKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuCiAqIENvcHlyaWdodCAyMDAwLDIwMDIgRXJpYyBQb3VlY2gKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKLyogU3RpbGwgdG8gYmUgZG9uZToKICogCSsgY29ycmVjdCBoYW5kbGluZyBvZiBnbG9iYWwvbG9jYWwgSU9Qcm9jcyAoYW5kIHRlbXBvcmFyeSBJT1Byb2NzKQogKgkrIG1vZGUgb2YgbW1pbyBvYmplY3RzIGlzIG5vdCB1c2VkIChyZWFkIHZzIHdyaXRlIHZzIHJlYWR3cml0ZSkKICoJKyB0aHJlYWQgc2FmZW5lc3MKICogICAgICArIDMyIEEgPD0+IFcgbWVzc2FnZSBtYXBwaW5nCiAqLwoKCiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJ3aW5lbW0uaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtbWlvKTsKCkxSRVNVTFQgICAgICAgICAoKnBGbk1taW9DYWxsYmFjazE2KShTRUdQVFIsTFBNTUlPSU5GTyxVSU5ULExQQVJBTSxMUEFSQU0pIC8qID0gTlVMTCAqLzsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgIAltbWlvRG9zSU9Qcm9jICAgICAgICAgICAJCVtpbnRlcm5hbF0KICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIG1taW9Eb3NJT1Byb2MoTFBNTUlPSU5GTyBscG1taW9pbmZvLCBVSU5UIHVNZXNzYWdlLAoJCQkJICAgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgICBMUkVTVUxUCXJldCA9IE1NU1lTRVJSX05PRVJST1I7CgogICAgVFJBQ0UoIiglcCwgJVgsIDB4JWx4LCAweCVseCk7XG4iLCBscG1taW9pbmZvLCB1TWVzc2FnZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogICAgc3dpdGNoICh1TWVzc2FnZSkgewogICAgY2FzZSBNTUlPTV9PUEVOOgoJewoJICAgIC8qIFBhcmFtZXRlcnM6CgkgICAgICogbFBhcmFtMSA9IHN6RmlsZU5hbWUgcGFyYW1ldGVyIGZyb20gbW1pb09wZW4KCSAgICAgKiBsUGFyYW0yID0gcmVzZXJ2ZWQKCSAgICAgKiBSZXR1cm5zOiB6ZXJvIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKCSAgICAgKiBOT1RFOiBsRGlza09mZnNldCBhdXRvbWF0aWNhbGx5IHNldCB0byB6ZXJvCgkgICAgICovCgkgICAgTFBDU1RSICAgICAgc3pGaWxlTmFtZSA9IChMUENTVFIpbFBhcmFtMTsKCgkgICAgaWYgKGxwbW1pb2luZm8tPmR3RmxhZ3MgJiBNTUlPX0dFVFRFTVApIHsKCQlGSVhNRSgiTU1JT19HRVRURU1QIG5vdCBpbXBsZW1lbnRlZFxuIik7CgkJcmV0dXJuIE1NSU9FUlJfQ0FOTk9UT1BFTjsKCSAgICB9CgoJICAgIC8qIGlmIGZpbGVuYW1lIE5VTEwsIGFzc3VtZSBvcGVuIGZpbGUgaGFuZGxlIGluIGFkd0luZm9bMF0gKi8KCSAgICBpZiAoc3pGaWxlTmFtZSkgewogICAgICAgICAgICAgICAgT0ZTVFJVQ1QgICAgb2ZzOwogICAgICAgICAgICAgICAgbHBtbWlvaW5mby0+YWR3SW5mb1swXSA9IChEV09SRClPcGVuRmlsZShzekZpbGVOYW1lLCAmb2ZzLCBscG1taW9pbmZvLT5kd0ZsYWdzICYgMHhGRkZGKTsKICAgICAgICAgICAgfQoJICAgIGlmIChscG1taW9pbmZvLT5hZHdJbmZvWzBdID09IChEV09SRClIRklMRV9FUlJPUikKCQlyZXQgPSBNTUlPRVJSX0NBTk5PVE9QRU47Cgl9CglicmVhazsKCiAgICBjYXNlIE1NSU9NX0NMT1NFOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSB3RmxhZ3MgcGFyYW1ldGVyIGZyb20gbW1pb0Nsb3NlCgkgKiBsUGFyYW0yID0gdW51c2VkCgkgKiBSZXR1cm5zOiB6ZXJvIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKCSAqLwoJaWYgKCEobFBhcmFtMSAmIE1NSU9fRkhPUEVOKSkKCSAgICBfbGNsb3NlKChIRklMRSlscG1taW9pbmZvLT5hZHdJbmZvWzBdKTsKCWJyZWFrOwoKICAgIGNhc2UgTU1JT01fUkVBRDoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gaHVnZSBwb2ludGVyIHRvIHJlYWQgYnVmZmVyCgkgKiBsUGFyYW0yID0gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQKCSAqIFJldHVybnM6IG51bWJlciBvZiBieXRlcyByZWFkLCAwIGZvciBFT0YsIC0xIGZvciBlcnJvciAoZXJyb3IgY29kZQoJICoJICAgaW4gd0Vycm9yUmV0KQoJICovCglyZXQgPSBfbHJlYWQoKEhGSUxFKWxwbW1pb2luZm8tPmFkd0luZm9bMF0sIChIUFNUUilsUGFyYW0xLCAoTE9ORylsUGFyYW0yKTsKCWlmIChyZXQgIT0gLTEpCgkgICAgbHBtbWlvaW5mby0+bERpc2tPZmZzZXQgKz0gcmV0OwoKCWJyZWFrOwoKICAgIGNhc2UgTU1JT01fV1JJVEU6CiAgICBjYXNlIE1NSU9NX1dSSVRFRkxVU0g6CgkvKiBubyBpbnRlcm5hbCBidWZmZXJpbmcsIHNvIFdSSVRFRkxVU0ggaGFuZGxlZCBzYW1lIGFzIFdSSVRFICovCgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBodWdlIHBvaW50ZXIgdG8gd3JpdGUgYnVmZmVyCgkgKiBsUGFyYW0yID0gbnVtYmVyIG9mIGJ5dGVzIHRvIHdyaXRlCgkgKiBSZXR1cm5zOiBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiwgLTEgZm9yIGVycm9yIChlcnJvciBjb2RlIGluCgkgKgkJd0Vycm9yUmV0KQoJICovCglyZXQgPSBfaHdyaXRlKChIRklMRSlscG1taW9pbmZvLT5hZHdJbmZvWzBdLCAoSFBTVFIpbFBhcmFtMSwgKExPTkcpbFBhcmFtMik7CglpZiAocmV0ICE9IC0xKQoJICAgIGxwbW1pb2luZm8tPmxEaXNrT2Zmc2V0ICs9IHJldDsKCWJyZWFrOwoKICAgIGNhc2UgTU1JT01fU0VFSzoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gbmV3IHBvc2l0aW9uCgkgKiBsUGFyYW0yID0gZnJvbSB3aGVuY2UgdG8gc2VlayAoU0VFS19TRVQsIFNFRUtfQ1VSLCBTRUVLX0VORCkKCSAqIFJldHVybnM6IG5ldyBmaWxlIHBvc3Rpb24sIC0xIG9uIGVycm9yCgkgKi8KCXJldCA9IF9sbHNlZWsoKEhGSUxFKWxwbW1pb2luZm8tPmFkd0luZm9bMF0sIChMT05HKWxQYXJhbTEsIChMT05HKWxQYXJhbTIpOwoJaWYgKHJldCAhPSAtMSkKCSAgICBscG1taW9pbmZvLT5sRGlza09mZnNldCA9IHJldDsKCXJldHVybiByZXQ7CgogICAgY2FzZSBNTUlPTV9SRU5BTUU6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IG9sZCBuYW1lCgkgKiBsUGFyYW0yID0gbmV3IG5hbWUKCSAqIFJldHVybnM6IHplcm8gb24gc3VjY2Vzcywgbm9uLXplcm8gb24gZmFpbHVyZQoJICovCiAJIGlmICghTW92ZUZpbGVBKChjb25zdCBjaGFyKilsUGFyYW0xLCAoY29uc3QgY2hhciopbFBhcmFtMikpCgkgICAgIHJldCA9IE1NSU9FUlJfRklMRU5PVEZPVU5EOwoJIGJyZWFrOwoKICAgIGRlZmF1bHQ6CglGSVhNRSgidW5leHBlY3RlZCBtZXNzYWdlICV1XG4iLCB1TWVzc2FnZSk7CglyZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAJbW1pb01lbUlPUHJvYyAgICAgICAgICAgCQlbaW50ZXJuYWxdCiAqLwpzdGF0aWMgTFJFU1VMVCBDQUxMQkFDSyBtbWlvTWVtSU9Qcm9jKExQTU1JT0lORk8gbHBtbWlvaW5mbywgVUlOVCB1TWVzc2FnZSwKCQkJCSAgICAgIExQQVJBTSBsUGFyYW0xLCBMUEFSQU0gbFBhcmFtMikKewogICAgVFJBQ0UoIiglcCwweCUwNHgsMHglMDhseCwweCUwOGx4KVxuIiwgbHBtbWlvaW5mbywgdU1lc3NhZ2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAgIHN3aXRjaCAodU1lc3NhZ2UpIHsKCiAgICBjYXNlIE1NSU9NX09QRU46CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IGZpbGVuYW1lIChtdXN0IGJlIE5VTEwpCgkgKiBsUGFyYW0yID0gcmVzZXJ2ZWQKCSAqIFJldHVybnM6IHplcm8gb24gc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgoJICogTk9URTogbERpc2tPZmZzZXQgYXV0b21hdGljYWxseSBzZXQgdG8gemVybwoJICovCgkvKiBGSVhNRTogaW8gcHJvYyBzaG91bGRuJ3QgY2hhbmdlIGl0ICovCglpZiAoIShscG1taW9pbmZvLT5kd0ZsYWdzICYgTU1JT19DUkVBVEUpKQoJICAgIGxwbW1pb2luZm8tPnBjaEVuZFJlYWQgPSBscG1taW9pbmZvLT5wY2hFbmRXcml0ZTsKICAgICAgICBscG1taW9pbmZvLT5hZHdJbmZvWzBdID0gSEZJTEVfRVJST1I7CglyZXR1cm4gMDsKCiAgICBjYXNlIE1NSU9NX0NMT1NFOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSB3RmxhZ3MgcGFyYW1ldGVyIGZyb20gbW1pb0Nsb3NlCgkgKiBsUGFyYW0yID0gdW51c2VkCgkgKiBSZXR1cm5zOiB6ZXJvIG9uIHN1Y2Nlc3MsIGVycm9yIGNvZGUgb24gZXJyb3IKCSAqLwoJcmV0dXJuIDA7CgogICAgY2FzZSBNTUlPTV9SRUFEOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBodWdlIHBvaW50ZXIgdG8gcmVhZCBidWZmZXIKCSAqIGxQYXJhbTIgPSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZAoJICogUmV0dXJuczogbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIDAgZm9yIEVPRiwgLTEgZm9yIGVycm9yIChlcnJvciBjb2RlCgkgKgkgICBpbiB3RXJyb3JSZXQpCgkgKiBOT1RFOiBsRGlza09mZnNldCBzaG91bGQgYmUgdXBkYXRlZAoJICovCglGSVhNRSgiTU1JT01fUkVBRCBvbiBtZW1vcnkgZmlsZXMgc2hvdWxkIG5vdCBvY2N1ciwgYnVmZmVyIG1heSBiZSBsb3N0IVxuIik7CglyZXR1cm4gMDsKCiAgICBjYXNlIE1NSU9NX1dSSVRFOgogICAgY2FzZSBNTUlPTV9XUklURUZMVVNIOgoJLyogbm8gaW50ZXJuYWwgYnVmZmVyaW5nLCBzbyBXUklURUZMVVNIIGhhbmRsZWQgc2FtZSBhcyBXUklURSAqLwoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gaHVnZSBwb2ludGVyIHRvIHdyaXRlIGJ1ZmZlcgoJICogbFBhcmFtMiA9IG51bWJlciBvZiBieXRlcyB0byB3cml0ZQoJICogUmV0dXJuczogbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4sIC0xIGZvciBlcnJvciAoZXJyb3IgY29kZSBpbgoJICoJCXdFcnJvclJldCkKCSAqIE5PVEU6IGxEaXNrT2Zmc2V0IHNob3VsZCBiZSB1cGRhdGVkCgkgKi8KCUZJWE1FKCJNTUlPTV9XUklURSBvbiBtZW1vcnkgZmlsZXMgc2hvdWxkIG5vdCBvY2N1ciwgYnVmZmVyIG1heSBiZSBsb3N0IVxuIik7CglyZXR1cm4gMDsKCiAgICBjYXNlIE1NSU9NX1NFRUs6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IG5ldyBwb3NpdGlvbgoJICogbFBhcmFtMiA9IGZyb20gd2hlbmNlIHRvIHNlZWsgKFNFRUtfU0VULCBTRUVLX0NVUiwgU0VFS19FTkQpCgkgKiBSZXR1cm5zOiBuZXcgZmlsZSBwb3N0aW9uLCAtMSBvbiBlcnJvcgoJICogTk9URTogbERpc2tPZmZzZXQgc2hvdWxkIGJlIHVwZGF0ZWQKCSAqLwoJRklYTUUoIk1NSU9NX1NFRUsgb24gbWVtb3J5IGZpbGVzIHNob3VsZCBub3Qgb2NjdXIsIGJ1ZmZlciBtYXkgYmUgbG9zdCFcbiIpOwoJcmV0dXJuIC0xOwoKICAgIGRlZmF1bHQ6CglGSVhNRSgidW5leHBlY3RlZCBtZXNzYWdlICV1XG4iLCB1TWVzc2FnZSk7CglyZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLyogVGhpcyBhcnJheSB3aWxsIGJlIHRoZSBlbnRpcmUgbGlzdCBmb3IgbW9zdCBhcHBzIAogKiBOb3RlIHRoYXQgdGVtcG9yYXJ5IGlvUHJvY3Mgd2lsbCBiZSBzdG9yZWQgd2l0aCBhIDAgZm91ckNDIGNvZGUKICovCgpzdGF0aWMgc3RydWN0IElPUHJvY0xpc3QgZGVmYXVsdFByb2NzW10gPSB7CiAgICB7JmRlZmF1bHRQcm9jc1sxXSwgRk9VUkNDX0RPUywgKExQTU1JT1BST0MpbW1pb0Rvc0lPUHJvYywgTU1JT19QUk9DXzMyQSwgMH0sCiAgICB7TlVMTCwgICAgICAgICAgICAgRk9VUkNDX01FTSwgKExQTU1JT1BST0MpbW1pb01lbUlPUHJvYywgTU1JT19QUk9DXzMyQSwgMH0sCn07CgpzdGF0aWMgc3RydWN0IElPUHJvY0xpc3QqCXBJT1Byb2NMaXN0QW5jaG9yID0gJmRlZmF1bHRQcm9jc1swXTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAlNTUlPX0ZpbmRQcm9jTm9kZSAJCQlbSU5URVJOQUxdCiAqCiAqIEZpbmRzIHRoZSBQcm9jTGlzdCBub2RlIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIEZPVVJDQyBjb2RlLgogKi8Kc3RhdGljIHN0cnVjdCBJT1Byb2NMaXN0KglNTUlPX0ZpbmRQcm9jTm9kZShGT1VSQ0MgZmNjSU9Qcm9jKQp7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCoJcExpc3ROb2RlOwoKICAgIGZvciAocExpc3ROb2RlID0gcElPUHJvY0xpc3RBbmNob3I7IHBMaXN0Tm9kZTsgcExpc3ROb2RlID0gcExpc3ROb2RlLT5wTmV4dCkgewoJaWYgKHBMaXN0Tm9kZS0+Zm91ckNDID09IGZjY0lPUHJvYykgewoJICAgIHJldHVybiBwTGlzdE5vZGU7Cgl9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgCU1NSU9fSW5zdGFsbElPUHJvYyAJCQlbSU5URVJOQUxdCiAqLwpMUE1NSU9QUk9DIE1NSU9fSW5zdGFsbElPUHJvYyhGT1VSQ0MgZmNjSU9Qcm9jLCBMUE1NSU9QUk9DIHBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3RmxhZ3MsIGVudW0gbW1pb1Byb2NUeXBlIHR5cGUpCnsKICAgIExQTU1JT1BST0MJICAgICAgICBscFByb2MgPSBOVUxMOwogICAgc3RydWN0IElPUHJvY0xpc3QqICBwTGlzdE5vZGU7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCoqIHBwTGlzdE5vZGU7CgogICAgVFJBQ0UoIiglMDhseCwgJXAsICUwOGxYLCAlaSlcbiIsIGZjY0lPUHJvYywgcElPUHJvYywgZHdGbGFncywgdHlwZSk7CgogICAgaWYgKGR3RmxhZ3MgJiBNTUlPX0dMT0JBTFBST0MpCglGSVhNRSgiR2xvYmFsIHByb2NlZHVyZXMgbm90IGltcGxlbWVudGVkXG4iKTsKCiAgICAvKiBqdXN0IGhhbmRsZSB0aGUga25vd24gcHJvY2VkdXJlcyBmb3Igbm93ICovCiAgICBzd2l0Y2ggKGR3RmxhZ3MgJiAoTU1JT19JTlNUQUxMUFJPQ3xNTUlPX1JFTU9WRVBST0N8TU1JT19GSU5EUFJPQykpIHsKICAgIGNhc2UgTU1JT19JTlNUQUxMUFJPQzoKCS8qIENyZWF0ZSBuZXcgZW50cnkgZm9yIHRoZSBJT1Byb2MgbGlzdCAqLwoJcExpc3ROb2RlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcExpc3ROb2RlKSk7CglpZiAocExpc3ROb2RlKSB7CgkgICAgLyogRmlsbCBpbiB0aGlzIG5vZGUgKi8KCSAgICBwTGlzdE5vZGUtPmZvdXJDQyA9IGZjY0lPUHJvYzsKCSAgICBwTGlzdE5vZGUtPnBJT1Byb2MgPSBwSU9Qcm9jOwoJICAgIHBMaXN0Tm9kZS0+dHlwZSA9IHR5cGU7CgkgICAgcExpc3ROb2RlLT5jb3VudCA9IDA7CgoJICAgIC8qIFN0aWNrIGl0IG9uIHRoZSBlbmQgb2YgdGhlIGxpc3QgKi8KCSAgICBwTGlzdE5vZGUtPnBOZXh0ID0gcElPUHJvY0xpc3RBbmNob3I7CgkgICAgcElPUHJvY0xpc3RBbmNob3IgPSBwTGlzdE5vZGU7CgoJICAgIC8qIFJldHVybiB0aGlzIElPUHJvYyAtIHRoYXQncyBob3cgdGhlIGNhbGxlciBrbm93cyB3ZSBzdWNjZWVkZWQgKi8KCSAgICBscFByb2MgPSBwSU9Qcm9jOwoJfQoJYnJlYWs7CgogICAgY2FzZSBNTUlPX1JFTU9WRVBST0M6CgkvKgoJICogU2VhcmNoIGZvciB0aGUgbm9kZSB0aGF0IHdlJ3JlIHRyeWluZyB0byByZW1vdmUKICAgICAgICAgKiBXZSBzZWFyY2ggZm9yIGEgbWF0Y2hpbmcgZm91ckNDIGNvZGUgaWYgaXQncyBub24gbnVsbCwgb3IgdGhlIHByb2MKICAgICAgICAgKiBhZGRyZXNzIG90aGVyd2lzZQogICAgICAgICAqIG5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3b24ndCBmaW5kIHRoZSBmaXJzdCBpdGVtIG9uIHRoZSBsaXN0LCBidXQKCSAqIHNpbmNlIHRoZSBmaXJzdCB0d28gaXRlbXMgb24gdGhpcyBsaXN0IGFyZSBvbmVzIHdlIHdvbid0CgkgKiBsZXQgdGhlIHVzZXIgZGVsZXRlIGFueXdheSwgdGhhdCdzIG9rYXkKCSAqLwoJcHBMaXN0Tm9kZSA9ICZwSU9Qcm9jTGlzdEFuY2hvcjsKCXdoaWxlICgoKnBwTGlzdE5vZGUpICYmIAogICAgICAgICAgICAgICAoKGZjY0lPUHJvYyAhPSAwKSA/IAogICAgICAgICAgICAgICAgKCpwcExpc3ROb2RlKS0+Zm91ckNDICE9IGZjY0lPUHJvYyA6IAogICAgICAgICAgICAgICAgKCpwcExpc3ROb2RlKS0+cElPUHJvYyAhPSBwSU9Qcm9jKSkKCSAgICBwcExpc3ROb2RlID0gJigoKnBwTGlzdE5vZGUpLT5wTmV4dCk7CgoJaWYgKCpwcExpc3ROb2RlKSB7IC8qIGZvdW5kIGl0ICovCgkgICAgLyogRklYTUU6IHdoYXQgc2hvdWxkIGJlIGRvbmUgaWYgYW4gb3BlbiBtbWlvIG9iamVjdCB1c2VzIHRoaXMgcHJvYyA/CgkgICAgICogc2hhbGwgd2UgcmV0dXJuIGFuIGVycm9yLCBudWtlIHRoZSBtbWlvIG9iamVjdCA/CgkgICAgICovCgkgICAgaWYgKCgqcHBMaXN0Tm9kZSktPmNvdW50KSB7CgkJRVJSKCJDYW5ub3QgcmVtb3ZlIGEgbW1JT1Byb2Mgd2hpbGUgaW4gdXNlXG4iKTsKCQlicmVhazsKCSAgICB9CgkgICAgLyogcmVtb3ZlIGl0LCBidXQgb25seSBpZiBpdCBpc24ndCBidWlsdGluICovCgkgICAgaWYgKCgqcHBMaXN0Tm9kZSkgPj0gZGVmYXVsdFByb2NzICYmCgkJKCpwcExpc3ROb2RlKSA8IGRlZmF1bHRQcm9jcyArIHNpemVvZihkZWZhdWx0UHJvY3MpKSB7CgkJV0FSTigiVHJpZWQgdG8gcmVtb3ZlIGJ1aWx0LWluIG1taW8gcHJvYy4gU2tpcHBpbmdcbiIpOwoJICAgIH0gZWxzZSB7CgkJLyogT2theSwgbnVrZSBpdCAqLwoJCXN0cnVjdCBJT1Byb2NMaXN0KiAgcHRtcE5vZGUgPSAqcHBMaXN0Tm9kZTsKCQlscFByb2MgPSAoKnBwTGlzdE5vZGUpLT5wSU9Qcm9jOwoJCSpwcExpc3ROb2RlID0gKCpwcExpc3ROb2RlKS0+cE5leHQ7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHRtcE5vZGUpOwoJICAgIH0KCX0KCWJyZWFrOwoKICAgIGNhc2UgTU1JT19GSU5EUFJPQzoKCWlmICgocExpc3ROb2RlID0gTU1JT19GaW5kUHJvY05vZGUoZmNjSU9Qcm9jKSkpIHsKCSAgICBscFByb2MgPSBwTGlzdE5vZGUtPnBJT1Byb2M7Cgl9CglicmVhazsKICAgIH0KCiAgICByZXR1cm4gbHBQcm9jOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJc2VuZF9tZXNzYWdlICAgIAkJCVtJTlRFUk5BTF0KICovCnN0YXRpYyBMUkVTVUxUCXNlbmRfbWVzc2FnZShzdHJ1Y3QgSU9Qcm9jTGlzdCogaW9Qcm9jLCBMUE1NSU9JTkZPIG1taW9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHdNc2csIExQQVJBTSBsUGFyYW0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0yLCBlbnVtIG1taW9Qcm9jVHlwZSB0eXBlKQp7CiAgICBMUkVTVUxUIAkJcmVzdWx0ID0gTU1TWVNFUlJfRVJST1I7CiAgICBMUEFSQU0JCWxwMSA9IGxQYXJhbTEsIGxwMiA9IGxQYXJhbTI7CgogICAgaWYgKCFpb1Byb2MpIHsKCUVSUigiYnJyclxuIik7CglyZXN1bHQgPSBNTVNZU0VSUl9JTlZBTFBBUkFNOwogICAgfQoKICAgIHN3aXRjaCAoaW9Qcm9jLT50eXBlKSB7CiAgICBjYXNlIE1NSU9fUFJPQ18xNjoKICAgICAgICBpZiAocEZuTW1pb0NhbGxiYWNrMTYpCiAgICAgICAgICAgIHJlc3VsdCA9IHBGbk1taW9DYWxsYmFjazE2KChTRUdQVFIpaW9Qcm9jLT5wSU9Qcm9jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbWlvaW5mbywgd01zZywgbHAxLCBscDIpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBNTUlPX1BST0NfMzJBOgogICAgY2FzZSBNTUlPX1BST0NfMzJXOgoJaWYgKGlvUHJvYy0+dHlwZSAhPSB0eXBlKSB7CgkgICAgLyogbWFwIChsUGFyYW0xLCBsUGFyYW0yKSBpbnRvIChscDEsIGxwMikgMzIgQTw9PlcgKi8KCSAgICBGSVhNRSgiTklZIDMyIEE8PT5XIG1hcHBpbmdcbiIpOwoJfQoJcmVzdWx0ID0gKGlvUHJvYy0+cElPUHJvYykoKExQU1RSKW1taW9pbmZvLCB3TXNnLCBscDEsIGxwMik7CgojaWYgMAoJaWYgKGlvUHJvYy0+dHlwZSAhPSB0eXBlKSB7CgkgICAgLyogdW5tYXAgKGxQYXJhbTEsIGxQYXJhbTIpIGludG8gKGxwMSwgbHAyKSAzMiBBPD0+VyAqLwoJfQojZW5kaWYKCWJyZWFrOwogICAgZGVmYXVsdDoKCUZJWE1FKCJJbnRlcm5hbCBlcnJvclxuIik7CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgCQkJTU1JT19QYXJzZUV4dEEgCQkgICAgICAgIFtpbnRlcm5hbF0KICoKICogUGFyc2VzIGEgZmlsZW5hbWUgZm9yIHRoZSBleHRlbnNpb24uCiAqCiAqIFJFVFVSTlMKICogIFRoZSBGT1VSQ0MgY29kZSBmb3IgdGhlIGV4dGVuc2lvbiBpZiBmb3VuZCwgZWxzZSAwLgogKi8Kc3RhdGljIEZPVVJDQyBNTUlPX1BhcnNlRXh0QShMUENTVFIgc3pGaWxlTmFtZSkKewogICAgLyogRmlsZW5hbWVzIGFyZSBvZiB0aGUgZm9ybSBmaWxlLmV4dCtBQkMKICAgICAgIEZJWE1FOiBXaGF0IGlmIGEgJysnIGlzIHBhcnQgb2YgdGhlIGZpbGUgbmFtZT8KICAgICAgIEZvciBub3csIHdlIHRha2UgdGhlIGxhc3QgJysnIHByZXNlbnQgKi8KCiAgICBGT1VSQ0MgcmV0ID0gMDsKCiAgICAvKiBOb3RlIHRoYXQgZXh0e1N0YXJ0LEVuZH0gcG9pbnQgdG8gdGhlIC4gYW5kICsgcmVzcGVjdGl2ZWx5ICovCiAgICBMUFNUUiBleHRFbmQ7CgogICAgVFJBQ0UoIiglcylcbiIsIGRlYnVnc3RyX2Eoc3pGaWxlTmFtZSkpOwoKICAgIGlmICghc3pGaWxlTmFtZSkKCXJldHVybiByZXQ7CiAgICBleHRFbmQgPSBzdHJyY2hyKHN6RmlsZU5hbWUsJysnKTsKICAgIGlmIChleHRFbmQpIHsKCS8qIE5lZWQgdG8gcGFyc2UgdG8gZmluZCB0aGUgZXh0ZW5zaW9uICovCglMUFNUUiBleHRTdGFydDsKCglleHRTdGFydCA9IGV4dEVuZDsKCXdoaWxlIChleHRTdGFydCA+PSBzekZpbGVOYW1lICYmIGV4dFN0YXJ0WzBdICE9ICcuJykgewoJICAgIGV4dFN0YXJ0LS07Cgl9CgoJaWYgKGV4dFN0YXJ0IDwgc3pGaWxlTmFtZSkgewoJICAgIEVSUigiKyBidXQgbm8gLiBpbiBzekZpbGVOYW1lOiAlc1xuIiwgZGVidWdzdHJfYShzekZpbGVOYW1lKSk7Cgl9IGVsc2UgewoJICAgIENIQVIgZXh0WzVdOwoKCSAgICBpZiAoZXh0RW5kIC0gZXh0U3RhcnQgLSAxID4gNCkKCQlXQVJOKCJFeHRlbnNpb24gbGVuZ3RoID4gNFxuIik7CgkgICAgbHN0cmNweW5BKGV4dCwgZXh0U3RhcnQgKyAxLCBtaW4oZXh0RW5kLWV4dFN0YXJ0LDUpKTsKCSAgICBUUkFDRSgiR290IGV4dGVuc2lvbjogJXNcbiIsIGRlYnVnc3RyX2EoZXh0KSk7CgkgICAgLyogRk9VUkNDIGNvZGVzIGlkZW50aWZ5aW5nIGZpbGUtZXh0ZW5zaW9ucyBtdXN0IGJlIHVwcGVyY2FzZSAqLwoJICAgIHJldCA9IG1taW9TdHJpbmdUb0ZPVVJDQ0EoZXh0LCBNTUlPX1RPVVBQRVIpOwoJfQogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCU1NSU9fR2V0CQkJW2ludGVybmFsXQogKgogKiBSZXRyaWV2ZXMgdGhlIG1taW8gb2JqZWN0IGZyb20gY3VycmVudCBwcm9jZXNzCiAqLwpMUFdJTkVfTU1JTwlNTUlPX0dldChITU1JTyBoKQp7CiAgICBMUFdJTkVfTU1JTwkJd20gPSBOVUxMOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9JRGF0YS0+Y3MpOwogICAgZm9yICh3bSA9IFdJTk1NX0lEYXRhLT5scE1NSU87IHdtOyB3bSA9IHdtLT5scE5leHQpIHsKCWlmICh3bS0+aW5mby5obW1pbyA9PSBoKQoJICAgIGJyZWFrOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJldJTk1NX0lEYXRhLT5jcyk7CiAgICByZXR1cm4gd207Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQlNTUlPX0NyZWF0ZQkJCVtpbnRlcm5hbF0KICoKICogQ3JlYXRlcyBhbiBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBmb3IgYSBtbWlvIGluc3RhbmNlCiAqLwpzdGF0aWMJTFBXSU5FX01NSU8JCU1NSU9fQ3JlYXRlKHZvaWQpCnsKICAgIHN0YXRpYwlXT1JECU1NSU9fY291bnRlciA9IDA7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgd20gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFdJTkVfTU1JTykpOwogICAgaWYgKHdtKSB7CglFbnRlckNyaXRpY2FsU2VjdGlvbigmV0lOTU1fSURhdGEtPmNzKTsKICAgICAgICAvKiBsb29rdXAgbmV4dCB1bmFsbG9jYXRlZCBXT1JEIGhhbmRsZSwgd2l0aCBhIG5vbiBOVUxMIHZhbHVlICovCgl3aGlsZSAoKytNTUlPX2NvdW50ZXIgPT0gMCB8fCBNTUlPX0dldChITU1JT18zMihNTUlPX2NvdW50ZXIpKSk7Cgl3bS0+aW5mby5obW1pbyA9IEhNTUlPXzMyKE1NSU9fY291bnRlcik7Cgl3bS0+bHBOZXh0ID0gV0lOTU1fSURhdGEtPmxwTU1JTzsKCVdJTk1NX0lEYXRhLT5scE1NSU8gPSB3bTsKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9JRGF0YS0+Y3MpOwogICAgfQogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJTU1JT19EZXN0cm95CQkJW2ludGVybmFsXQogKi0KICogRGVzdHJveXMgYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gZm9yIGEgbW1pbyBpbnN0YW5jZQogKi8Kc3RhdGljCUJPT0wJCU1NSU9fRGVzdHJveShMUFdJTkVfTU1JTyB3bSkKewogICAgTFBXSU5FX01NSU8qCW07CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJldJTk1NX0lEYXRhLT5jcyk7CiAgICAvKiBzZWFyY2ggZm9yIHRoZSBtYXRjaGluZyBvbmUuLi4gKi8KICAgIG0gPSAmKFdJTk1NX0lEYXRhLT5scE1NSU8pOwogICAgd2hpbGUgKCptICYmICptICE9IHdtKSBtID0gJigqbSktPmxwTmV4dDsKICAgIC8qIC4uLmFuZCBkZXN0cm95ICovCiAgICBpZiAoKm0pIHsKCSptID0gKCptKS0+bHBOZXh0OwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd20pOwoJd20gPSBOVUxMOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJldJTk1NX0lEYXRhLT5jcyk7CiAgICByZXR1cm4gd20gPyBGQUxTRSA6IFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAkJTU1JT19GbHVzaCAJCQlbSU5URVJOQUxdCiAqLwpzdGF0aWMJTU1SRVNVTFQgTU1JT19GbHVzaChXSU5FX01NSU8qIHdtLCBVSU5UIHVGbGFncykKewogICAgaWYgKHdtLT5pbmZvLmNjaEJ1ZmZlciAmJiAod20tPmluZm8uZmNjSU9Qcm9jICE9IEZPVVJDQ19NRU0pKSB7CgkvKiBub3QgcXVpdGUgc3VyZSB3aGF0IHRvIGRvIGhlcmUsIGJ1dCBJJ2xsIGd1ZXNzICovCglpZiAod20tPmluZm8uZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgICAgICAgICAgLyogRklYTUU6IGVycm9yIGhhbmRsaW5nICovCgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywgCiAgICAgICAgICAgICAgICAgICAgICAgICB3bS0+aW5mby5sQnVmT2Zmc2V0LCBTRUVLX1NFVCwgTU1JT19QUk9DXzMyQSk7CgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fV1JJVEUsIAogICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSl3bS0+aW5mby5wY2hCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICB3bS0+aW5mby5wY2hOZXh0IC0gd20tPmluZm8ucGNoQnVmZmVyLCBNTUlPX1BST0NfMzJBKTsKCX0KCWlmICh1RmxhZ3MgJiBNTUlPX0VNUFRZQlVGKQoJICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgfQogICAgd20tPmluZm8uZHdGbGFncyAmPSB+TU1JT19ESVJUWTsKCiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJCU1NSU9fR3JhYk5leHRCdWZmZXIJCQlbSU5URVJOQUxdCiAqLwpzdGF0aWMgTE9ORwlNTUlPX0dyYWJOZXh0QnVmZmVyKExQV0lORV9NTUlPIHdtLCBpbnQgZm9yX3JlYWQpCnsKICAgIExPTkcJc2l6ZSA9IHdtLT5pbmZvLmNjaEJ1ZmZlcjsKCiAgICBUUkFDRSgiYm89JWx4IGRvPSVseCBvZj0lbHhcbiIsCgkgIHdtLT5pbmZvLmxCdWZPZmZzZXQsIHdtLT5pbmZvLmxEaXNrT2Zmc2V0LAoJICBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9TRUVLLCAwLCBTRUVLX0NVUiwgTU1JT19QUk9DXzMyQSkpOwoKICAgIHdtLT5pbmZvLmxCdWZPZmZzZXQgPSB3bS0+aW5mby5sRGlza09mZnNldDsKICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hCdWZmZXI7CiAgICB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgd20tPmluZm8ucGNoRW5kV3JpdGUgPSB3bS0+aW5mby5wY2hCdWZmZXIgKyB3bS0+aW5mby5jY2hCdWZmZXI7CgogICAgd20tPmJCdWZmZXJMb2FkZWQgPSBUUlVFOwogICAgaWYgKGZvcl9yZWFkKSB7CglzaXplID0gc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKXdtLT5pbmZvLnBjaEJ1ZmZlciwgc2l6ZSwgTU1JT19QUk9DXzMyQSk7CglpZiAoc2l6ZSA+IDApCgkgICAgd20tPmluZm8ucGNoRW5kUmVhZCArPSBzaXplOwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPmJCdWZmZXJMb2FkZWQgPSBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gc2l6ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJCU1NSU9fU2V0QnVmZmVyIAkJCQlbSU5URVJOQUxdCiAqLwpzdGF0aWMgTU1SRVNVTFQgTU1JT19TZXRCdWZmZXIoV0lORV9NTUlPKiB3bSwgdm9pZCogcGNoQnVmZmVyLCBMT05HIGNjaEJ1ZmZlciwKCQkJICAgICAgIFVJTlQgdUZsYWdzKQp7CiAgICBUUkFDRSgiKCVwICVwICVsZCAldSlcbiIsIHdtLCBwY2hCdWZmZXIsIGNjaEJ1ZmZlciwgdUZsYWdzKTsKCiAgICBpZiAodUZsYWdzKQkJCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwogICAgaWYgKGNjaEJ1ZmZlciA+IDB4RkZGRikKCVdBUk4oIlVudGVzdGVkIGhhbmRsaW5nIG9mIGh1Z2UgbW1pbyBidWZmZXJzICglbGQgPj0gNjRrKVxuIiwgY2NoQnVmZmVyKTsKCiAgICBpZiAoTU1JT19GbHVzaCh3bSwgMCkgIT0gTU1TWVNFUlJfTk9FUlJPUikKCXJldHVybiBNTUlPRVJSX0NBTk5PVFdSSVRFOwoKICAgIC8qIGZyZWUgcHJldmlvdXMgYnVmZmVyIGlmIGFsbG9jYXRlZCAqLwogICAgaWYgKHdtLT5pbmZvLmR3RmxhZ3MgJiBNTUlPX0FMTE9DQlVGKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd20tPmluZm8ucGNoQnVmZmVyKTsKICAgICAgICB3bS0+aW5mby5wY2hCdWZmZXIgPSBOVUxMOwoJd20tPmluZm8uZHdGbGFncyAmPSB+TU1JT19BTExPQ0JVRjsKICAgIH0KCiAgICBpZiAocGNoQnVmZmVyKSB7CiAgICAgICAgd20tPmluZm8ucGNoQnVmZmVyID0gcGNoQnVmZmVyOwogICAgfSBlbHNlIGlmIChjY2hCdWZmZXIpIHsKCWlmICghKHdtLT5pbmZvLnBjaEJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjY2hCdWZmZXIpKSkKCSAgICByZXR1cm4gTU1JT0VSUl9PVVRPRk1FTU9SWTsKCXdtLT5pbmZvLmR3RmxhZ3MgfD0gTU1JT19BTExPQ0JVRjsKICAgIH0gZWxzZSB7Cgl3bS0+aW5mby5wY2hCdWZmZXIgPSBOVUxMOwogICAgfQoKICAgIHdtLT5pbmZvLmNjaEJ1ZmZlciA9IGNjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hCdWZmZXI7CiAgICB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgd20tPmluZm8ucGNoRW5kV3JpdGUgPSB3bS0+aW5mby5wY2hCdWZmZXIgKyBjY2hCdWZmZXI7CiAgICB3bS0+aW5mby5sQnVmT2Zmc2V0ID0gMDsKICAgIHdtLT5iQnVmZmVyTG9hZGVkID0gRkFMU0U7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQlNTUlPX09wZW4gICAgICAgCQkJW2ludGVybmFsXQogKi8KSE1NSU8gTU1JT19PcGVuKExQU1RSIHN6RmlsZU5hbWUsIE1NSU9JTkZPKiByZWZtbWluZm8sIERXT1JEIGR3T3BlbkZsYWdzLCAKICAgICAgICAgICAgICAgIGVudW0gbW1pb1Byb2NUeXBlIHR5cGUpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKICAgIE1NSU9JTkZPICAgIAltbWlvaW5mbzsKCiAgICBUUkFDRSgiKCclcycsICVwLCAlMDhsWCwgJWQpO1xuIiwgc3pGaWxlTmFtZSwgcmVmbW1pbmZvLCBkd09wZW5GbGFncywgdHlwZSk7CgogICAgaWYgKCFyZWZtbWluZm8pIHsKICAgICAgICByZWZtbWluZm8gPSAmbW1pb2luZm87CgoJbW1pb2luZm8uZmNjSU9Qcm9jID0gMDsKCW1taW9pbmZvLnBJT1Byb2MgPSBOVUxMOwoJbW1pb2luZm8ucGNoQnVmZmVyID0gTlVMTDsKCW1taW9pbmZvLmNjaEJ1ZmZlciA9IDA7CiAgICAgICAgdHlwZSA9IE1NSU9fUFJPQ18zMkE7CiAgICB9CgogICAgaWYgKGR3T3BlbkZsYWdzICYgKE1NSU9fUEFSU0V8TU1JT19FWElTVCkpIHsKCWNoYXIJYnVmZmVyW01BWF9QQVRIXTsKCglpZiAoR2V0RnVsbFBhdGhOYW1lQShzekZpbGVOYW1lLCBzaXplb2YoYnVmZmVyKSwgYnVmZmVyLCBOVUxMKSA+PSBzaXplb2YoYnVmZmVyKSkKCSAgICByZXR1cm4gKEhNTUlPMTYpRkFMU0U7CglpZiAoKGR3T3BlbkZsYWdzICYgTU1JT19FWElTVCkgJiYgKEdldEZpbGVBdHRyaWJ1dGVzQShidWZmZXIpID09IC0xKSkKCSAgICByZXR1cm4gKEhNTUlPKUZBTFNFOwoJc3RyY3B5KHN6RmlsZU5hbWUsIGJ1ZmZlcik7CglyZXR1cm4gKEhNTUlPKVRSVUU7CiAgICB9CgogICAgaWYgKCh3bSA9IE1NSU9fQ3JlYXRlKCkpID09IE5VTEwpCglyZXR1cm4gMDsKCiAgICAvKiBJZiBib3RoIHBhcmFtcyBhcmUgTlVMTCwgdGhlbiBwYXJzZSB0aGUgZmlsZSBuYW1lIGlmIGF2YWlsYWJsZSAqLwogICAgaWYgKHJlZm1taW5mby0+ZmNjSU9Qcm9jID09IDAgJiYgcmVmbW1pbmZvLT5wSU9Qcm9jID09IE5VTEwpIHsKCXdtLT5pbmZvLmZjY0lPUHJvYyA9IE1NSU9fUGFyc2VFeHRBKHN6RmlsZU5hbWUpOwoJLyogSGFuZGxlIGFueSB1bmhhbmRsZWQvZXJyb3IgY2FzZS4gQXNzdW1lIERPUyBmaWxlICovCglpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IDApCgkgICAgd20tPmluZm8uZmNjSU9Qcm9jID0gRk9VUkNDX0RPUzsKCWlmICghKHdtLT5pb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZSh3bS0+aW5mby5mY2NJT1Byb2MpKSkgZ290byBlcnJvcjI7Cgl3bS0+YlRtcElPUHJvYyA9IEZBTFNFOwogICAgfQogICAgLyogaWYganVzdCB0aGUgZm91ciBjaGFyYWN0ZXIgY29kZSBpcyBwcmVzZW50LCBsb29rIHVwIElPIHByb2MgKi8KICAgIGVsc2UgaWYgKHJlZm1taW5mby0+cElPUHJvYyA9PSBOVUxMKSB7Cgl3bS0+aW5mby5mY2NJT1Byb2MgPSByZWZtbWluZm8tPmZjY0lPUHJvYzsKCWlmICghKHdtLT5pb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZSh3bS0+aW5mby5mY2NJT1Byb2MpKSkgZ290byBlcnJvcjI7Cgl3bS0+YlRtcElPUHJvYyA9IEZBTFNFOwogICAgfQogICAgLyogaWYgSU8gcHJvYyBzcGVjaWZpZWQsIHVzZSBpdCBhbmQgc3BlY2lmaWVkIGZvdXIgY2hhcmFjdGVyIGNvZGUgKi8KICAgIGVsc2UgewoJd20tPmluZm8uZmNjSU9Qcm9jID0gcmVmbW1pbmZvLT5mY2NJT1Byb2M7CglNTUlPX0luc3RhbGxJT1Byb2Mod20tPmluZm8uZmNjSU9Qcm9jLCByZWZtbWluZm8tPnBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9fSU5TVEFMTFBST0MsIHR5cGUpOwoJaWYgKCEod20tPmlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKHdtLT5pbmZvLmZjY0lPUHJvYykpKSBnb3RvIGVycm9yMjsKCWFzc2VydCh3bS0+aW9Qcm9jLT5wSU9Qcm9jID09IHJlZm1taW5mby0+cElPUHJvYyk7Cgl3bS0+YlRtcElPUHJvYyA9IFRSVUU7CiAgICB9CgogICAgd20tPmJCdWZmZXJMb2FkZWQgPSBGQUxTRTsKICAgIHdtLT5pb1Byb2MtPmNvdW50Kys7CgogICAgaWYgKGR3T3BlbkZsYWdzICYgTU1JT19BTExPQ0JVRikgewoJaWYgKChyZWZtbWluZm8tPndFcnJvclJldCA9IE1NSU9fU2V0QnVmZmVyKHdtLCBOVUxMLCBNTUlPX0RFRkFVTFRCVUZGRVIsIDApKSkKCSAgICBnb3RvIGVycm9yMTsKICAgIH0gZWxzZSBpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pIHsKICAgICAgICByZWZtbWluZm8tPndFcnJvclJldCA9IE1NSU9fU2V0QnVmZmVyKHdtLCByZWZtbWluZm8tPnBjaEJ1ZmZlciwgcmVmbW1pbmZvLT5jY2hCdWZmZXIsIDApOwoJaWYgKHJlZm1taW5mby0+d0Vycm9yUmV0ICE9IE1NU1lTRVJSX05PRVJST1IpCgkgICAgZ290byBlcnJvcjE7Cgl3bS0+YkJ1ZmZlckxvYWRlZCA9IFRSVUU7CiAgICB9IC8qIGVsc2UgPT4gdW5idWZmZXJlZCwgd20tPmluZm8ucGNoQnVmZmVyID09IE5VTEwgKi8KCiAgICAvKiBzZWUgbW1pb0Rvc0lPUHJvYyBmb3IgdGhhdCBvbmUgKi8KICAgIHdtLT5pbmZvLmFkd0luZm9bMF0gPSByZWZtbWluZm8tPmFkd0luZm9bMF07CiAgICB3bS0+aW5mby5kd0ZsYWdzID0gZHdPcGVuRmxhZ3M7CgogICAgLyogY2FsbCBJTyBwcm9jIHRvIGFjdHVhbGx5IG9wZW4gZmlsZSAqLwogICAgcmVmbW1pbmZvLT53RXJyb3JSZXQgPSBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9PUEVOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pc3pGaWxlTmFtZSwgMCwgTU1JT19QUk9DXzMyQSk7CgogICAgLyogZ3JhYiBmaWxlIHNpemUsIHdoZW4gcG9zc2libGUgKi8KICAgIHdtLT5kd0ZpbGVTaXplID0gR2V0RmlsZVNpemUoKEhBTkRMRSl3bS0+aW5mby5hZHdJbmZvWzBdLCBOVUxMKTsKCiAgICBpZiAocmVmbW1pbmZvLT53RXJyb3JSZXQgPT0gMCkKCXJldHVybiB3bS0+aW5mby5obW1pbzsKIGVycm9yMToKICAgIGlmICh3bS0+aW9Qcm9jKSB3bS0+aW9Qcm9jLT5jb3VudC0tOwogZXJyb3IyOgogICAgTU1JT19EZXN0cm95KHdtKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9PcGVuVyAgICAgICAJCVtXSU5NTS5AXQogKi8KSE1NSU8gV0lOQVBJIG1taW9PcGVuVyhMUFdTVFIgc3pGaWxlTmFtZSwgTU1JT0lORk8qIGxwbW1pb2luZm8sCgkJICAgICAgIERXT1JEIGR3T3BlbkZsYWdzKQp7CiAgICBITU1JTyAJcmV0OwogICAgTFBTVFIJc3pGbiA9IEhFQVBfc3RyZHVwV3RvQShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzekZpbGVOYW1lKTsKCiAgICByZXQgPSBNTUlPX09wZW4oc3pGbiwgbHBtbWlvaW5mbywgZHdPcGVuRmxhZ3MsIE1NSU9fUFJPQ18zMlcpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6Rm4pOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvT3BlbkEgICAgICAgCQlbV0lOTU0uQF0KICovCkhNTUlPIFdJTkFQSSBtbWlvT3BlbkEoTFBTVFIgc3pGaWxlTmFtZSwgTU1JT0lORk8qIGxwbW1pb2luZm8sCgkJICAgICAgIERXT1JEIGR3T3BlbkZsYWdzKQp7CiAgICByZXR1cm4gIE1NSU9fT3BlbihzekZpbGVOYW1lLCBscG1taW9pbmZvLCBkd09wZW5GbGFncywgTU1JT19QUk9DXzMyQSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0Nsb3NlICAgICAgCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvQ2xvc2UoSE1NSU8gaG1taW8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwl3bTsKICAgIE1NUkVTVUxUIAlyZXN1bHQ7CgogICAgVFJBQ0UoIiglcCwgJTA0WCk7XG4iLCBobW1pbywgdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIGlmICgocmVzdWx0ID0gTU1JT19GbHVzaCh3bSwgMCkpICE9IE1NU1lTRVJSX05PRVJST1IpCglyZXR1cm4gcmVzdWx0OwoKICAgIHJlc3VsdCA9IHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX0NMT1NFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB1RmxhZ3MsIDAsIE1NSU9fUFJPQ18zMkEpOwoKICAgIE1NSU9fU2V0QnVmZmVyKHdtLCBOVUxMLCAwLCAwKTsKCiAgICB3bS0+aW9Qcm9jLT5jb3VudC0tOwoKICAgIGlmICh3bS0+YlRtcElPUHJvYykKCU1NSU9fSW5zdGFsbElPUHJvYyh3bS0+aW5mby5mY2NJT1Byb2MsIHdtLT5pb1Byb2MtPnBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9fUkVNT1ZFUFJPQywgd20tPmlvUHJvYy0+dHlwZSk7CgogICAgTU1JT19EZXN0cm95KHdtKTsKCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9SZWFkCSAgICAgICAJW1dJTk1NLkBdCiAqLwpMT05HIFdJTkFQSSBtbWlvUmVhZChITU1JTyBobW1pbywgSFBTVFIgcGNoLCBMT05HIGNjaCkKewogICAgTFBXSU5FX01NSU8Jd207CiAgICBMT05HIAljb3VudDsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJWxkKTtcbiIsIGhtbWlvLCBwY2gsIGNjaCk7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiAtMTsKCiAgICAvKiB1bmJ1ZmZlcmVkIGNhc2UgZmlyc3QgKi8KICAgIGlmICghd20tPmluZm8ucGNoQnVmZmVyKQoJcmV0dXJuIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1JFQUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSlwY2gsIGNjaCwgTU1JT19QUk9DXzMyQSk7CgogICAgLyogZmlyc3QgdHJ5IGZyb20gY3VycmVudCBidWZmZXIgKi8KICAgIGlmICh3bS0+aW5mby5wY2hOZXh0ICE9IHdtLT5pbmZvLnBjaEVuZFJlYWQpIHsKCWNvdW50ID0gd20tPmluZm8ucGNoRW5kUmVhZCAtIHdtLT5pbmZvLnBjaE5leHQ7CglpZiAoY291bnQgPiBjY2ggfHwgY291bnQgPCAwKSBjb3VudCA9IGNjaDsKCW1lbWNweShwY2gsIHdtLT5pbmZvLnBjaE5leHQsIGNvdW50KTsKCXdtLT5pbmZvLnBjaE5leHQgKz0gY291bnQ7CglwY2ggKz0gY291bnQ7CgljY2ggLT0gY291bnQ7CiAgICB9IGVsc2UKCWNvdW50ID0gMDsKCiAgICBpZiAoY2NoICYmICh3bS0+aW5mby5mY2NJT1Byb2MgIT0gRk9VUkNDX01FTSkpIHsKCWFzc2VydCh3bS0+aW5mby5jY2hCdWZmZXIpOwoKCXdoaWxlIChjY2gpIHsKCSAgICBMT05HIHNpemU7CgoJICAgIHNpemUgPSBNTUlPX0dyYWJOZXh0QnVmZmVyKHdtLCBUUlVFKTsKCSAgICBpZiAoc2l6ZSA8PSAwKSBicmVhazsKCSAgICBpZiAoc2l6ZSA+IGNjaCkgc2l6ZSA9IGNjaDsKCSAgICBtZW1jcHkocGNoLCB3bS0+aW5mby5wY2hCdWZmZXIsIHNpemUpOwoJICAgIHdtLT5pbmZvLnBjaE5leHQgKz0gc2l6ZTsKCSAgICBwY2ggKz0gc2l6ZTsKCSAgICBjY2ggLT0gc2l6ZTsKCSAgICBjb3VudCArPSBzaXplOwoJfQogICAgfQoKICAgIFRSQUNFKCJjb3VudD0lbGRcbiIsIGNvdW50KTsKICAgIHJldHVybiBjb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvV3JpdGUgICAgICAJCVtXSU5NTS5AXQogKi8KTE9ORyBXSU5BUEkgbW1pb1dyaXRlKEhNTUlPIGhtbWlvLCBIUENTVFIgcGNoLCBMT05HIGNjaCkKewogICAgTFBXSU5FX01NSU8Jd207CiAgICBMT05HCWNvdW50OwoKICAgIFRSQUNFKCIoJXAsICVwLCAlbGQpO1xuIiwgaG1taW8sIHBjaCwgY2NoKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIC0xOwoKICAgIGlmICh3bS0+aW5mby5jY2hCdWZmZXIpIHsKCUxPTkcJYnl0ZXNXID0gMDsKCiAgICAgICAgY291bnQgPSAwOwogICAgICAgIHdoaWxlIChjY2gpIHsKICAgICAgICAgICAgaWYgKHdtLT5pbmZvLnBjaE5leHQgIT0gd20tPmluZm8ucGNoRW5kV3JpdGUpIHsKICAgICAgICAgICAgICAgIGNvdW50ID0gd20tPmluZm8ucGNoRW5kV3JpdGUgLSB3bS0+aW5mby5wY2hOZXh0OwogICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gY2NoIHx8IGNvdW50IDwgMCkgY291bnQgPSBjY2g7CiAgICAgICAgICAgICAgICBtZW1jcHkod20tPmluZm8ucGNoTmV4dCwgcGNoLCBjb3VudCk7CiAgICAgICAgICAgICAgICB3bS0+aW5mby5wY2hOZXh0ICs9IGNvdW50OwogICAgICAgICAgICAgICAgcGNoICs9IGNvdW50OwogICAgICAgICAgICAgICAgY2NoIC09IGNvdW50OwogICAgICAgICAgICAgICAgYnl0ZXNXICs9IGNvdW50OwogICAgICAgICAgICAgICAgd20tPmluZm8uZHdGbGFncyB8PSBNTUlPX0RJUlRZOwoJICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pIHsKICAgICAgICAgICAgICAgICAgICBpZiAod20tPmluZm8uYWR3SW5mb1swXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBmcm9tIHdoZXJlIHdvdWxkIHdlIGdldCB0aGUgbWVtb3J5IGhhbmRsZT8gKi8KICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIm1lbW9yeSBmaWxlIGV4cGFuc2lvbiBub3QgaW1wbGVtZW50ZWQhXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJICAgIH0gZWxzZSBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHdtLT5pbmZvLnBjaE5leHQgPT0gd20tPmluZm8ucGNoRW5kV3JpdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE1NSU9fRmx1c2god20sIE1NSU9fRU1QVFlCVUYpOwogICAgICAgICAgICAgICAgTU1JT19HcmFiTmV4dEJ1ZmZlcih3bSwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgYnJlYWs7CiAgICAgICAgfQoJY291bnQgPSBieXRlc1c7CiAgICB9IGVsc2UgewoJY291bnQgPSBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9XUklURSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSlwY2gsIGNjaCwgTU1JT19QUk9DXzMyQSk7Cgl3bS0+aW5mby5sQnVmT2Zmc2V0ID0gd20tPmluZm8ubERpc2tPZmZzZXQ7CiAgICB9CgogICAgVFJBQ0UoImJ5dGVzIHdyaXR0ZW49JWxkXG4iLCBjb3VudCk7CiAgICByZXR1cm4gY291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1NlZWsJCVtXSU5NTS5AXQogKi8KTE9ORyBXSU5BUEkgbW1pb1NlZWsoSE1NSU8gaG1taW8sIExPTkcgbE9mZnNldCwgSU5UIGlPcmlnaW4pCnsKICAgIExQV0lORV9NTUlPCXdtOwogICAgTE9ORyAJb2Zmc2V0OwoKICAgIFRSQUNFKCIoJXAsICUwOGxYLCAlZCk7XG4iLCBobW1pbywgbE9mZnNldCwgaU9yaWdpbik7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICAvKiBub3QgYnVmZmVyZWQsIGRpcmVjdCBzZWVrIG9uIGZpbGUgKi8KICAgIGlmICghd20tPmluZm8ucGNoQnVmZmVyKQoJcmV0dXJuIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbE9mZnNldCwgaU9yaWdpbiwgTU1JT19QUk9DXzMyQSk7CgogICAgc3dpdGNoIChpT3JpZ2luKSB7CiAgICBjYXNlIFNFRUtfU0VUOgoJb2Zmc2V0ID0gbE9mZnNldDsKCWJyZWFrOwogICAgY2FzZSBTRUVLX0NVUjoKCW9mZnNldCA9IHdtLT5pbmZvLmxCdWZPZmZzZXQgKyAod20tPmluZm8ucGNoTmV4dCAtIHdtLT5pbmZvLnBjaEJ1ZmZlcikgKyBsT2Zmc2V0OwoJYnJlYWs7CiAgICBjYXNlIFNFRUtfRU5EOgoJb2Zmc2V0ID0gKCh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSk/IHdtLT5pbmZvLmNjaEJ1ZmZlciA6IHdtLT5kd0ZpbGVTaXplKSAtIGxPZmZzZXQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglyZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKG9mZnNldCAmJiBvZmZzZXQgPj0gd20tPmR3RmlsZVNpemUgJiYgd20tPmluZm8uZmNjSU9Qcm9jICE9IEZPVVJDQ19NRU0pIHsKICAgICAgICAvKiBzaG91bGQgY2hlY2sgdGhhdCB3cml0ZSBtb2RlIGV4aXN0cyAqLwogICAgICAgIGlmIChNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgd20tPmluZm8ubEJ1Zk9mZnNldCA9IG9mZnNldDsKICAgICAgICB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgICAgIHdtLT5pbmZvLnBjaEVuZFdyaXRlID0gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyOwogICAgICAgIGlmICgod20tPmluZm8uZHdGbGFncyAmIE1NSU9fUldNT0RFKSA9PSBNTUlPX1JFQUQpIHsKICAgICAgICAgICAgd20tPmluZm8ubERpc2tPZmZzZXQgPSB3bS0+ZHdGaWxlU2l6ZTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKCh3bS0+aW5mby5jY2hCdWZmZXIgPiAwKSAmJgoJKChvZmZzZXQgPCB3bS0+aW5mby5sQnVmT2Zmc2V0KSB8fAoJIChvZmZzZXQgPj0gd20tPmluZm8ubEJ1Zk9mZnNldCArIHdtLT5pbmZvLmNjaEJ1ZmZlcikgfHwKCSAhd20tPmJCdWZmZXJMb2FkZWQpKSB7CiAgICAgICAgLyogc3RheSBpbiBzYW1lIGJ1ZmZlciA/ICovCiAgICAgICAgLyogc29tZSBtZW1vcnkgbWFwcGVkIGJ1ZmZlcnMgYXJlIGRlZmluZWQgd2l0aCAtMSBhcyBhIHNpemUgKi8KCgkvKiBjb25kaXRpb24gdG8gY2hhbmdlIGJ1ZmZlciAqLwoJaWYgKCh3bS0+aW5mby5mY2NJT1Byb2MgPT0gRk9VUkNDX01FTSkgfHwKCSAgICBNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SIHx8CgkgICAgLyogdGhpcyBhbHNvIHNldHMgdGhlIHdtLT5pbmZvLmxEaXNrT2Zmc2V0IGZpZWxkICovCgkgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgIChvZmZzZXQgLyB3bS0+aW5mby5jY2hCdWZmZXIpICogd20tPmluZm8uY2NoQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgU0VFS19TRVQsIE1NSU9fUFJPQ18zMkEpID09IC0xKQoJICAgIHJldHVybiAtMTsKCU1NSU9fR3JhYk5leHRCdWZmZXIod20sIFRSVUUpOwogICAgfQoKICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hCdWZmZXIgKyAob2Zmc2V0IC0gd20tPmluZm8ubEJ1Zk9mZnNldCk7CgogICAgVFJBQ0UoIj0+ICVsZFxuIiwgb2Zmc2V0KTsKICAgIHJldHVybiBvZmZzZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0dldEluZm8JICAgICAgIAlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvR2V0SW5mbyhITU1JTyBobW1pbywgTU1JT0lORk8qIGxwbW1pb2luZm8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwlcCwweCUwOHgpXG4iLGhtbWlvLGxwbW1pb2luZm8sdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIG1lbWNweShscG1taW9pbmZvLCAmd20tPmluZm8sIHNpemVvZihNTUlPSU5GTykpOwogICAgLyogZG9uJ3QgZXhwb3NlIDE2IGJpdCBpb3Byb2M6cyAqLwogICAgaWYgKHdtLT5pb1Byb2MtPnR5cGUgIT0gTU1JT19QUk9DXzE2KQogICAgICAgIGxwbW1pb2luZm8tPnBJT1Byb2MgPSB3bS0+aW9Qcm9jLT5wSU9Qcm9jOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TZXRJbmZvICAgIAkJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb1NldEluZm8oSE1NSU8gaG1taW8sIGNvbnN0IE1NSU9JTkZPKiBscG1taW9pbmZvLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCIoJXAsJXAsMHglMDh4KVxuIixobW1pbyxscG1taW9pbmZvLHVGbGFncyk7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICAvKiBjaGVjayBwb2ludGVycyBjb2hlcmVuY2UgKi8KICAgIGlmIChscG1taW9pbmZvLT5wY2hOZXh0IDwgd20tPmluZm8ucGNoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hOZXh0ID4gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRSZWFkIDwgd20tPmluZm8ucGNoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRSZWFkID4gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRXcml0ZSA8IHdtLT5pbmZvLnBjaEJ1ZmZlciB8fAoJbHBtbWlvaW5mby0+cGNoRW5kV3JpdGUgPiB3bS0+aW5mby5wY2hCdWZmZXIgKyB3bS0+aW5mby5jY2hCdWZmZXIpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxQQVJBTTsKCiAgICB3bS0+aW5mby5wY2hOZXh0ID0gbHBtbWlvaW5mby0+cGNoTmV4dDsKICAgIHdtLT5pbmZvLnBjaEVuZFJlYWQgPSBscG1taW9pbmZvLT5wY2hFbmRSZWFkOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAJCQkJbW1pb1NldEJ1ZmZlcgkJW1dJTk1NLkBdCiovCk1NUkVTVUxUIFdJTkFQSSBtbWlvU2V0QnVmZmVyKEhNTUlPIGhtbWlvLCBMUFNUUiBwY2hCdWZmZXIsIExPTkcgY2NoQnVmZmVyLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCIoaG1taW89JXAsIHBjaEJ1Zj0lcCwgY2NoQnVmPSVsZCwgdUZsYWdzPSUjMDh4KVxuIiwKCSAgaG1taW8sIHBjaEJ1ZmZlciwgY2NoQnVmZmVyLCB1RmxhZ3MpOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgcmV0dXJuIE1NSU9fU2V0QnVmZmVyKHdtLCBwY2hCdWZmZXIsIGNjaEJ1ZmZlciwgdUZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvRmx1c2ggICAgICAJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9GbHVzaChITU1JTyBobW1pbywgVUlOVCB1RmxhZ3MpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKCiAgICBUUkFDRSgiKCVwLCAlMDRYKVxuIiwgaG1taW8sIHVGbGFncyk7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICByZXR1cm4gTU1JT19GbHVzaCh3bSwgdUZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvQWR2YW5jZSAgICAgIAlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvQWR2YW5jZShITU1JTyBobW1pbywgTU1JT0lORk8qIGxwbW1pb2luZm8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoImhtbWlvPSVwLCBscG1taW9pbmZvPSVwLCB1RmxhZ3M9JTA0WFxuIiwgaG1taW8sIGxwbW1pb2luZm8sIHVGbGFncyk7CgogICAgLyogTk9URTogbW1pb0FkdmFuY2UxNiBoZWF2aWx5IHJlbGllcyBvbiBwYXJhbWV0ZXJzIGZyb20gbHBtbWlvaW5mbyB3ZSdyZSB1c2luZwogICAgICogaGVyZS4gYmUgc3VyZSBpZiB5b3UgY2hhbmdlIHNvbWV0aGluZyBoZXJlIHRvIGNoZWNrIG1taW9BZHZhbmNlMTYgYXMgd2VsbAogICAgICovCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIGlmICghd20tPmluZm8uY2NoQnVmZmVyKQoJcmV0dXJuIE1NSU9FUlJfVU5CVUZGRVJFRDsKCiAgICBpZiAodUZsYWdzICE9IE1NSU9fUkVBRCAmJiB1RmxhZ3MgIT0gTU1JT19XUklURSkKCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIGlmICh1RmxhZ3MgPT0gTU1JT19XUklURSAmJiAobHBtbWlvaW5mby0+ZHdGbGFncyAmIE1NSU9fRElSVFkpKQogICAgewogICAgICAgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssIAogICAgICAgICAgICAgICAgICAgICBscG1taW9pbmZvLT5sQnVmT2Zmc2V0LCBTRUVLX1NFVCwgTU1JT19QUk9DXzMyQSk7CiAgICAgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fV1JJVEUsIAogICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKWxwbW1pb2luZm8tPnBjaEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgbHBtbWlvaW5mby0+cGNoTmV4dCAtIGxwbW1pb2luZm8tPnBjaEJ1ZmZlciwgTU1JT19QUk9DXzMyQSk7CiAgICAgICAgbHBtbWlvaW5mby0+ZHdGbGFncyAmPSB+TU1JT19ESVJUWTsKICAgIH0KICAgIGlmIChNTUlPX0ZsdXNoKHdtLCAwKSAhPSBNTVNZU0VSUl9OT0VSUk9SKQoJcmV0dXJuIE1NSU9FUlJfQ0FOTk9UV1JJVEU7CgogICAgaWYgKGxwbW1pb2luZm8pIHsKCXdtLT5kd0ZpbGVTaXplID0gbWF4KHdtLT5kd0ZpbGVTaXplLCBscG1taW9pbmZvLT5sQnVmT2Zmc2V0ICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxwbW1pb2luZm8tPnBjaE5leHQgLSBscG1taW9pbmZvLT5wY2hCdWZmZXIpKTsKICAgIH0KICAgIE1NSU9fR3JhYk5leHRCdWZmZXIod20sIHVGbGFncyA9PSBNTUlPX1JFQUQpOwoKICAgIGlmIChscG1taW9pbmZvKSB7CglscG1taW9pbmZvLT5wY2hOZXh0ID0gbHBtbWlvaW5mby0+cGNoQnVmZmVyOwoJbHBtbWlvaW5mby0+cGNoRW5kUmVhZCAgPSBscG1taW9pbmZvLT5wY2hCdWZmZXIgKwoJICAgICh3bS0+aW5mby5wY2hFbmRSZWFkIC0gd20tPmluZm8ucGNoQnVmZmVyKTsKCWxwbW1pb2luZm8tPnBjaEVuZFdyaXRlID0gbHBtbWlvaW5mby0+cGNoQnVmZmVyICsKCSAgICAod20tPmluZm8ucGNoRW5kV3JpdGUgLSB3bS0+aW5mby5wY2hCdWZmZXIpOwoJbHBtbWlvaW5mby0+bERpc2tPZmZzZXQgPSB3bS0+aW5mby5sRGlza09mZnNldDsKCWxwbW1pb2luZm8tPmxCdWZPZmZzZXQgPSB3bS0+aW5mby5sQnVmT2Zmc2V0OwogICAgfQogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1N0cmluZ1RvRk9VUkNDQQlbV0lOTU0uQF0KICovCkZPVVJDQyBXSU5BUEkgbW1pb1N0cmluZ1RvRk9VUkNDQShMUENTVFIgc3osIFVJTlQgdUZsYWdzKQp7CiAgICBDSEFSIGNjWzRdOwogICAgaW50IGkgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCA0ICYmIHN6W2ldOyBpKyspIHsKCWlmICh1RmxhZ3MgJiBNTUlPX1RPVVBQRVIpIHsKCSAgICBjY1tpXSA9IHRvdXBwZXIoc3pbaV0pOwoJfSBlbHNlIHsKCSAgICBjY1tpXSA9IHN6W2ldOwoJfQogICAgfQoKICAgIC8qIFBhZCB3aXRoIHNwYWNlcyAqLwogICAgd2hpbGUgKGkgPCA0KSBjY1tpKytdID0gJyAnOwoKICAgIFRSQUNFKCJHb3QgJyUuNHMnXG4iLGNjKTsKICAgIHJldHVybiBtbWlvRk9VUkNDKGNjWzBdLGNjWzFdLGNjWzJdLGNjWzNdKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvU3RyaW5nVG9GT1VSQ0NXCVtXSU5NTS5AXQogKi8KRk9VUkNDIFdJTkFQSSBtbWlvU3RyaW5nVG9GT1VSQ0NXKExQQ1dTVFIgc3osIFVJTlQgdUZsYWdzKQp7CiAgICBMUFNUUglzekEgPSBIRUFQX3N0cmR1cFd0b0EoR2V0UHJvY2Vzc0hlYXAoKSwwLHN6KTsKICAgIEZPVVJDQwlyZXQgPSBtbWlvU3RyaW5nVG9GT1VSQ0NBKHN6QSx1RmxhZ3MpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6QSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9JbnN0YWxsSU9Qcm9jQQkgICBbV0lOTU0uQF0KICovCkxQTU1JT1BST0MgV0lOQVBJIG1taW9JbnN0YWxsSU9Qcm9jQShGT1VSQ0MgZmNjSU9Qcm9jLAoJCQkJICAgICBMUE1NSU9QUk9DIHBJT1Byb2MsIERXT1JEIGR3RmxhZ3MpCnsKICAgIHJldHVybiBNTUlPX0luc3RhbGxJT1Byb2MoZmNjSU9Qcm9jLCBwSU9Qcm9jLCBkd0ZsYWdzLCBNTUlPX1BST0NfMzJBKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvSW5zdGFsbElPUHJvY1cJICAgW1dJTk1NLkBdCiAqLwpMUE1NSU9QUk9DIFdJTkFQSSBtbWlvSW5zdGFsbElPUHJvY1coRk9VUkNDIGZjY0lPUHJvYywKCQkJCSAgICAgTFBNTUlPUFJPQyBwSU9Qcm9jLCBEV09SRCBkd0ZsYWdzKQp7CiAgICByZXR1cm4gTU1JT19JbnN0YWxsSU9Qcm9jKGZjY0lPUHJvYywgcElPUHJvYywgZHdGbGFncywgTU1JT19QUk9DXzMyVyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1NSU9fU2VuZE1lc3NhZ2UKICoKICoKICovCkxSRVNVTFQgICAgICAgICBNTUlPX1NlbmRNZXNzYWdlKEhNTUlPIGhtbWlvLCBVSU5UIHVNZXNzYWdlLCBMUEFSQU0gbFBhcmFtMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0yLCBlbnVtIG1taW9Qcm9jVHlwZSB0eXBlKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwgJXUsICVsZCwgJWxkLCAlZClcbiIsIGhtbWlvLCB1TWVzc2FnZSwgbFBhcmFtMSwgbFBhcmFtMiwgdHlwZSk7CgogICAgaWYgKHVNZXNzYWdlIDwgTU1JT01fVVNFUikKCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgcmV0dXJuIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIHVNZXNzYWdlLCBsUGFyYW0xLCBsUGFyYW0yLCB0eXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvU2VuZE1lc3NhZ2UJCVtXSU5NTS5AXQogKi8KTFJFU1VMVCBXSU5BUEkgbW1pb1NlbmRNZXNzYWdlKEhNTUlPIGhtbWlvLCBVSU5UIHVNZXNzYWdlLAoJCQkgICAgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgICByZXR1cm4gTU1JT19TZW5kTWVzc2FnZShobW1pbywgdU1lc3NhZ2UsIGxQYXJhbTEsIGxQYXJhbTIsIE1NSU9fUFJPQ18zMkEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9EZXNjZW5kICAgICAgICAgCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9EZXNjZW5kKEhNTUlPIGhtbWlvLCBMUE1NQ0tJTkZPIGxwY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNTUNLSU5GTyogbHBja1BhcmVudCwgVUlOVCB1RmxhZ3MpCnsKICAgIERXT1JECQlkd09sZFBvczsKICAgIEZPVVJDQwkJc3JjaENrSWQ7CiAgICBGT1VSQ0MJCXNyY2hUeXBlOwoKCiAgICBUUkFDRSgiKCVwLCAlcCwgJXAsICUwNFgpO1xuIiwgaG1taW8sIGxwY2ssIGxwY2tQYXJlbnQsIHVGbGFncyk7CgogICAgaWYgKGxwY2sgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIGR3T2xkUG9zID0gbW1pb1NlZWsoaG1taW8sIDAsIFNFRUtfQ1VSKTsKICAgIFRSQUNFKCJkd09sZFBvcz0lbGRcbiIsIGR3T2xkUG9zKTsKCiAgICBpZiAobHBja1BhcmVudCAhPSBOVUxMKSB7CglUUkFDRSgic2VlayBpbnNpZGUgcGFyZW50IGF0ICVsZCAhXG4iLCBscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQpOwoJLyogRVBQOiB3YXMgZHdPbGRQb3MgPSBtbWlvU2VlayhobW1pbyxscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQsU0VFS19TRVQpOyAqLwoJaWYgKGR3T2xkUG9zIDwgbHBja1BhcmVudC0+ZHdEYXRhT2Zmc2V0IHx8CgkgICAgZHdPbGRQb3MgPj0gbHBja1BhcmVudC0+ZHdEYXRhT2Zmc2V0ICsgbHBja1BhcmVudC0+Y2tzaXplKSB7CgkgICAgV0FSTigib3V0c2lkZSBwYXJlbnQgY2h1bmtcbiIpOwoJICAgIHJldHVybiBNTUlPRVJSX0NIVU5LTk9URk9VTkQ7Cgl9CiAgICB9CgogICAgLyogVGhlIFNESyBkb2N1IHNheXMgJ2NraWQnIGlzIHVzZWQgZm9yIGFsbCBjYXNlcy4gUmVhbCBXb3JsZAogICAgICogZXhhbXBsZXMgZGlzYWdyZWUgLU1hcmN1cyw5OTAyMTYuCiAgICAgKi8KCiAgICBzcmNoVHlwZSA9IDA7CiAgICAvKiBmaW5kX2NodW5rIGxvb2tzIGZvciAnY2tpZCcgKi8KICAgIGlmICh1RmxhZ3MgJiBNTUlPX0ZJTkRDSFVOSykKCXNyY2hDa0lkID0gbHBjay0+Y2tpZDsKICAgIC8qIGZpbmRfcmlmZiBhbmQgZmluZF9saXN0IGxvb2sgZm9yICdmY2NUeXBlJyAqLwogICAgaWYgKHVGbGFncyAmIE1NSU9fRklORExJU1QpIHsKCXNyY2hDa0lkID0gRk9VUkNDX0xJU1Q7CglzcmNoVHlwZSA9IGxwY2stPmZjY1R5cGU7CiAgICB9CiAgICBpZiAodUZsYWdzICYgTU1JT19GSU5EUklGRikgewoJc3JjaENrSWQgPSBGT1VSQ0NfUklGRjsKCXNyY2hUeXBlID0gbHBjay0+ZmNjVHlwZTsKICAgIH0KCiAgICBpZiAodUZsYWdzICYgKE1NSU9fRklORENIVU5LfE1NSU9fRklORExJU1R8TU1JT19GSU5EUklGRikpIHsKCVRSQUNFKCJzZWFyY2hpbmcgZm9yICUuNHMuJS40c1xuIiwKCSAgICAgIChMUFNUUikmc3JjaENrSWQsCgkgICAgICBzcmNoVHlwZT8oTFBTVFIpJnNyY2hUeXBlOiJhbnkgIik7CgoJd2hpbGUgKFRSVUUpIHsKCSAgICBMT05HIGl4OwoKCSAgICBpeCA9IG1taW9SZWFkKGhtbWlvLCAoTFBTVFIpbHBjaywgMyAqIHNpemVvZihEV09SRCkpOwoJICAgIGlmIChpeCA8IDIqc2l6ZW9mKERXT1JEKSkgewoJCW1taW9TZWVrKGhtbWlvLCBkd09sZFBvcywgU0VFS19TRVQpOwoJCVdBUk4oInJldHVybiBDaHVua05vdEZvdW5kXG4iKTsKCQlyZXR1cm4gTU1JT0VSUl9DSFVOS05PVEZPVU5EOwoJICAgIH0KCSAgICBscGNrLT5kd0RhdGFPZmZzZXQgPSBkd09sZFBvcyArIDIgKiBzaXplb2YoRFdPUkQpOwoJICAgIGlmIChpeCA8IGxwY2stPmR3RGF0YU9mZnNldCAtIGR3T2xkUG9zKSB7CgkJbW1pb1NlZWsoaG1taW8sIGR3T2xkUG9zLCBTRUVLX1NFVCk7CgkJV0FSTigicmV0dXJuIENodW5rTm90Rm91bmRcbiIpOwoJCXJldHVybiBNTUlPRVJSX0NIVU5LTk9URk9VTkQ7CgkgICAgfQoJICAgIFRSQUNFKCJja2lkPSUuNHMgZmNjPSUuNHMgY2tzaXplPSUwOGxYICFcbiIsCgkJICAoTFBTVFIpJmxwY2stPmNraWQsCgkJICBzcmNoVHlwZT8oTFBTVFIpJmxwY2stPmZjY1R5cGU6IjxuYT4iLAoJCSAgbHBjay0+Y2tzaXplKTsKCSAgICBpZiAoKHNyY2hDa0lkID09IGxwY2stPmNraWQpICYmCgkJKCFzcmNoVHlwZSB8fCAoc3JjaFR5cGUgPT0gbHBjay0+ZmNjVHlwZSkpCgkJKQoJCWJyZWFrOwoKCSAgICBkd09sZFBvcyA9IGxwY2stPmR3RGF0YU9mZnNldCArICgobHBjay0+Y2tzaXplICsgMSkgJiB+MSk7CgkgICAgbW1pb1NlZWsoaG1taW8sIGR3T2xkUG9zLCBTRUVLX1NFVCk7Cgl9CiAgICB9IGVsc2UgewoJLyogRklYTUU6IHVudmVyaWZpZWQsIGRvZXMgaXQgZG8gdGhpcz8gKi8KCS8qIE5COiBUaGlzIHBhcnQgaXMgdXNlZCBieSBXQVZFX21jaU9wZW4sIGFtb25nIG90aGVycyAqLwoJaWYgKG1taW9SZWFkKGhtbWlvLCAoTFBTVFIpbHBjaywgMyAqIHNpemVvZihEV09SRCkpIDwgMyAqIHNpemVvZihEV09SRCkpIHsKCSAgICBtbWlvU2VlayhobW1pbywgZHdPbGRQb3MsIFNFRUtfU0VUKTsKCSAgICBXQVJOKCJyZXR1cm4gQ2h1bmtOb3RGb3VuZCAybmRcbiIpOwoJICAgIHJldHVybiBNTUlPRVJSX0NIVU5LTk9URk9VTkQ7Cgl9CglscGNrLT5kd0RhdGFPZmZzZXQgPSBkd09sZFBvcyArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgfQogICAgbHBjay0+ZHdGbGFncyA9IDA7CiAgICAvKiBJZiB3ZSB3ZXJlIGxvb2tpbmcgZm9yIFJJRkYvTElTVCBjaHVua3MsIHRoZSBmaW5hbCBmaWxlIHBvc2l0aW9uCiAgICAgKiBpcyBhZnRlciB0aGUgY2h1bmtpZC4gSWYgd2Ugd2VyZSBqdXN0IGxvb2tpbmcgZm9yIHRoZSBjaHVuawogICAgICogaXQgaXMgYWZ0ZXIgdGhlIGNrc2l6ZS4gU28gYWRkIDQgaW4gUklGRi9MSVNUIGNhc2UuCiAgICAgKi8KICAgIGlmIChscGNrLT5ja2lkID09IEZPVVJDQ19SSUZGIHx8IGxwY2stPmNraWQgPT0gRk9VUkNDX0xJU1QpCgltbWlvU2VlayhobW1pbywgbHBjay0+ZHdEYXRhT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpOwogICAgZWxzZQoJbW1pb1NlZWsoaG1taW8sIGxwY2stPmR3RGF0YU9mZnNldCwgU0VFS19TRVQpOwogICAgVFJBQ0UoImxwY2s6IGNraWQ9JS40cywgY2tzaXplPSVsZCwgZHdEYXRhT2Zmc2V0PSVsZCBmY2NUeXBlPSUwOGxYICglLjRzKSFcbiIsCgkgIChMUFNUUikmbHBjay0+Y2tpZCwgbHBjay0+Y2tzaXplLCBscGNrLT5kd0RhdGFPZmZzZXQsCgkgIGxwY2stPmZjY1R5cGUsIHNyY2hUeXBlPyhMUFNUUikmbHBjay0+ZmNjVHlwZToiIik7CiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvQXNjZW5kICAgICAJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9Bc2NlbmQoSE1NSU8gaG1taW8sIExQTU1DS0lORk8gbHBjaywgVUlOVCB1RmxhZ3MpCnsKICAgIFRSQUNFKCIoJXAsICVwLCAlMDRYKTtcbiIsIGhtbWlvLCBscGNrLCB1RmxhZ3MpOwoKICAgIGlmIChscGNrLT5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewoJRFdPUkQJZHdPbGRQb3MsIGR3TmV3U2l6ZTsKCglUUkFDRSgiQ2h1bmsgaXMgZGlydHksIGNoZWNraW5nIGlmIGNodW5rJ3Mgc2l6ZSBpcyBjb3JyZWN0XG4iKTsKCWR3T2xkUG9zID0gbW1pb1NlZWsoaG1taW8sIDAsIFNFRUtfQ1VSKTsKCVRSQUNFKCJkd09sZFBvcz0lbGQgbHBjay0+ZHdEYXRhT2Zmc2V0ID0gJWxkXG4iLCBkd09sZFBvcywgbHBjay0+ZHdEYXRhT2Zmc2V0KTsKCWR3TmV3U2l6ZSA9IGR3T2xkUG9zIC0gbHBjay0+ZHdEYXRhT2Zmc2V0OwoJaWYgKGR3TmV3U2l6ZSAhPSBscGNrLT5ja3NpemUpIHsKCSAgICBUUkFDRSgiTm9wZTogbHBjay0+Y2tzaXplPSVsZCBkd05ld1NpemU9JWxkXG4iLCBscGNrLT5ja3NpemUsIGR3TmV3U2l6ZSk7CgkgICAgbHBjay0+Y2tzaXplID0gZHdOZXdTaXplOwoKCSAgICAvKiBwYWQgb2RkIHNpemUgd2l0aCAwICovCgkgICAgaWYgKGR3TmV3U2l6ZSAmIDEpIHsKCQljaGFyIGNoID0gMDsKCQltbWlvV3JpdGUoaG1taW8sICZjaCwgMSk7CgkgICAgfQoJICAgIG1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQgLSBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCk7CgkgICAgbW1pb1dyaXRlKGhtbWlvLCAoTFBTVFIpJmR3TmV3U2l6ZSwgc2l6ZW9mKERXT1JEKSk7Cgl9CglscGNrLT5kd0ZsYWdzID0gMDsKICAgIH0KCiAgICBtbWlvU2VlayhobW1pbywgbHBjay0+ZHdEYXRhT2Zmc2V0ICsgKChscGNrLT5ja3NpemUgKyAxKSAmIH4xKSwgU0VFS19TRVQpOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJbW1pb0NyZWF0ZUNodW5rCQkJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9DcmVhdGVDaHVuayhITU1JTyBobW1pbywgTU1DS0lORk8qIGxwY2ssIFVJTlQgdUZsYWdzKQp7CiAgICBEV09SRAlkd09sZFBvczsKICAgIExPTkcgCXNpemU7CiAgICBMT05HIAlpeDsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJTA0WCk7XG4iLCBobW1pbywgbHBjaywgdUZsYWdzKTsKCiAgICBkd09sZFBvcyA9IG1taW9TZWVrKGhtbWlvLCAwLCBTRUVLX0NVUik7CiAgICBUUkFDRSgiZHdPbGRQb3M9JWxkXG4iLCBkd09sZFBvcyk7CgogICAgaWYgKHVGbGFncyA9PSBNTUlPX0NSRUFURUxJU1QpCglscGNrLT5ja2lkID0gRk9VUkNDX0xJU1Q7CiAgICBlbHNlIGlmICh1RmxhZ3MgPT0gTU1JT19DUkVBVEVSSUZGKQoJbHBjay0+Y2tpZCA9IEZPVVJDQ19SSUZGOwoKICAgIFRSQUNFKCJja2lkPSUuNHNcbiIsIChMUFNUUikmbHBjay0+Y2tpZCk7CgogICAgc2l6ZSA9IDIgKiBzaXplb2YoRFdPUkQpOwogICAgbHBjay0+ZHdEYXRhT2Zmc2V0ID0gZHdPbGRQb3MgKyBzaXplOwoKICAgIGlmIChscGNrLT5ja2lkID09IEZPVVJDQ19SSUZGIHx8IGxwY2stPmNraWQgPT0gRk9VUkNDX0xJU1QpCglzaXplICs9IHNpemVvZihEV09SRCk7CiAgICBscGNrLT5kd0ZsYWdzID0gTU1JT19ESVJUWTsKCiAgICBpeCA9IG1taW9Xcml0ZShobW1pbywgKExQU1RSKWxwY2ssIHNpemUpOwogICAgVFJBQ0UoImFmdGVyIG1taW9Xcml0ZSBpeCA9ICVsZCByZXEgPSAlbGQsIGVycm5vID0gJWRcbiIsaXgsIHNpemUsIGVycm5vKTsKICAgIGlmIChpeCA8IHNpemUpIHsKCW1taW9TZWVrKGhtbWlvLCBkd09sZFBvcywgU0VFS19TRVQpOwoJV0FSTigicmV0dXJuIENhbm5vdFdyaXRlXG4iKTsKCXJldHVybiBNTUlPRVJSX0NBTk5PVFdSSVRFOwogICAgfQoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9SZW5hbWVBICAgIAkJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9SZW5hbWVBKExQQ1NUUiBzekZpbGVOYW1lLCBMUENTVFIgc3pOZXdGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9JTkZPKiBscG1taW9pbmZvLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCogIGlvUHJvYyA9IE5VTEw7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCAgIHRtcDsKCiAgICBUUkFDRSgiKCclcycsICclcycsICVwLCAlMDhsWCk7XG4iLAoJICBkZWJ1Z3N0cl9hKHN6RmlsZU5hbWUpLCBkZWJ1Z3N0cl9hKHN6TmV3RmlsZU5hbWUpLCBscG1taW9pbmZvLCBkd0ZsYWdzKTsKCiAgICAvKiBJZiBib3RoIHBhcmFtcyBhcmUgTlVMTCwgdGhlbiBwYXJzZSB0aGUgZmlsZSBuYW1lICovCiAgICBpZiAobHBtbWlvaW5mbyAmJiBscG1taW9pbmZvLT5mY2NJT1Byb2MgPT0gMCAmJiBscG1taW9pbmZvLT5wSU9Qcm9jID09IE5VTEwpCglscG1taW9pbmZvLT5mY2NJT1Byb2MgPSBNTUlPX1BhcnNlRXh0QShzekZpbGVOYW1lKTsKCiAgICAvKiBIYW5kbGUgYW55IHVuaGFuZGxlZC9lcnJvciBjYXNlIGZyb20gYWJvdmUuIEFzc3VtZSBET1MgZmlsZSAqLwogICAgaWYgKCFscG1taW9pbmZvIHx8IChscG1taW9pbmZvLT5mY2NJT1Byb2MgPT0gMCAmJiBscG1taW9pbmZvLT5wSU9Qcm9jID09IE5VTEwpKQoJaW9Qcm9jID0gTU1JT19GaW5kUHJvY05vZGUoRk9VUkNDX0RPUyk7CiAgICAvKiBpZiBqdXN0IHRoZSBmb3VyIGNoYXJhY3RlciBjb2RlIGlzIHByZXNlbnQsIGxvb2sgdXAgSU8gcHJvYyAqLwogICAgZWxzZSBpZiAobHBtbWlvaW5mby0+cElPUHJvYyA9PSBOVUxMKQogICAgICAgIGlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKGxwbW1pb2luZm8tPmZjY0lPUHJvYyk7CiAgICBlbHNlIC8qIHVzZSByZWxldmFudCBpb1Byb2MgKi8KICAgIHsKICAgICAgICBpb1Byb2MgPSAmdG1wOwogICAgICAgIHRtcC5mb3VyQ0MgPSBscG1taW9pbmZvLT5mY2NJT1Byb2M7CiAgICAgICAgdG1wLnBJT1Byb2MgPSBscG1taW9pbmZvLT5wSU9Qcm9jOwogICAgICAgIHRtcC50eXBlID0gTU1JT19QUk9DXzMyQTsKICAgICAgICB0bXAuY291bnQgPSAxOwogICAgfQoKICAgIHJldHVybiBzZW5kX21lc3NhZ2UoaW9Qcm9jLCBscG1taW9pbmZvLCBNTUlPTV9SRU5BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pc3pGaWxlTmFtZSwgKExQQVJBTSlzek5ld0ZpbGVOYW1lLCBNTUlPX1BST0NfMzJBKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvUmVuYW1lVyAgICAJCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvUmVuYW1lVyhMUENXU1RSIHN6RmlsZU5hbWUsIExQQ1dTVFIgc3pOZXdGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9JTkZPKiBscG1taW9pbmZvLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBMUFNUUglzekZuID0gSEVBUF9zdHJkdXBXdG9BKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6RmlsZU5hbWUpOwogICAgTFBTVFIJc3puRm4gPSBIRUFQX3N0cmR1cFd0b0EoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3pOZXdGaWxlTmFtZSk7CiAgICBVSU5UCXJldCA9IG1taW9SZW5hbWVBKHN6Rm4sIHN6bkZuLCBscG1taW9pbmZvLCBkd0ZsYWdzKTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsc3pGbik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsc3puRm4pOwogICAgcmV0dXJuIHJldDsKfQo=