LyoKICogTU1JTyBmdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTggQW5kcmV3IFRheWxvcgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICogQ29weXJpZ2h0IDIwMDAsMjAwMiBFcmljIFBvdWVjaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKiBTdGlsbCB0byBiZSBkb25lOgogKiAJKyBjb3JyZWN0IGhhbmRsaW5nIG9mIGdsb2JhbC9sb2NhbCBJT1Byb2NzIChhbmQgdGVtcG9yYXJ5IElPUHJvY3MpCiAqCSsgbW9kZSBvZiBtbWlvIG9iamVjdHMgaXMgbm90IHVzZWQgKHJlYWQgdnMgd3JpdGUgdnMgcmVhZHdyaXRlKQogKgkrIHRocmVhZCBzYWZlbmVzcwogKiAgICAgICsgMzIgQSA8PT4gVyBtZXNzYWdlIG1hcHBpbmcKICovCgoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ3aW5lbW0uaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChtbWlvKTsKCkxSRVNVTFQgICAgICAgICAoKnBGbk1taW9DYWxsYmFjazE2KShEV09SRCxMUE1NSU9JTkZPLFVJTlQsTFBBUkFNLExQQVJBTSkgLyogPSBOVUxMICovOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgCW1taW9Eb3NJT1Byb2MgICAgICAgICAgIAkJW2ludGVybmFsXQogKi8Kc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sgbW1pb0Rvc0lPUHJvYyhMUE1NSU9JTkZPIGxwbW1pb2luZm8sIFVJTlQgdU1lc3NhZ2UsCgkJCQkgICAgICBMUEFSQU0gbFBhcmFtMSwgTFBBUkFNIGxQYXJhbTIpCnsKICAgIExSRVNVTFQJcmV0ID0gTU1TWVNFUlJfTk9FUlJPUjsKCiAgICBUUkFDRSgiKCVwLCAlWCwgMHglbHgsIDB4JWx4KTtcbiIsIGxwbW1pb2luZm8sIHVNZXNzYWdlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgICBzd2l0Y2ggKHVNZXNzYWdlKSB7CiAgICBjYXNlIE1NSU9NX09QRU46Cgl7CgkgICAgLyogUGFyYW1ldGVyczoKCSAgICAgKiBsUGFyYW0xID0gc3pGaWxlTmFtZSBwYXJhbWV0ZXIgZnJvbSBtbWlvT3BlbgoJICAgICAqIGxQYXJhbTIgPSByZXNlcnZlZAoJICAgICAqIFJldHVybnM6IHplcm8gb24gc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgoJICAgICAqIE5PVEU6IGxEaXNrT2Zmc2V0IGF1dG9tYXRpY2FsbHkgc2V0IHRvIHplcm8KCSAgICAgKi8KCSAgICBMUENTVFIgICAgICBzekZpbGVOYW1lID0gKExQQ1NUUilsUGFyYW0xOwoKCSAgICBpZiAobHBtbWlvaW5mby0+ZHdGbGFncyAmIE1NSU9fR0VUVEVNUCkgewoJCUZJWE1FKCJNTUlPX0dFVFRFTVAgbm90IGltcGxlbWVudGVkXG4iKTsKCQlyZXR1cm4gTU1JT0VSUl9DQU5OT1RPUEVOOwoJICAgIH0KCgkgICAgLyogaWYgZmlsZW5hbWUgTlVMTCwgYXNzdW1lIG9wZW4gZmlsZSBoYW5kbGUgaW4gYWR3SW5mb1swXSAqLwoJICAgIGlmIChzekZpbGVOYW1lKSB7CiAgICAgICAgICAgICAgICBPRlNUUlVDVCAgICBvZnM7CiAgICAgICAgICAgICAgICBscG1taW9pbmZvLT5hZHdJbmZvWzBdID0gKERXT1JEKU9wZW5GaWxlKHN6RmlsZU5hbWUsICZvZnMsIGxwbW1pb2luZm8tPmR3RmxhZ3MgJiAweEZGRkYpOwogICAgICAgICAgICB9CgkgICAgaWYgKGxwbW1pb2luZm8tPmFkd0luZm9bMF0gPT0gKERXT1JEKUhGSUxFX0VSUk9SKQoJCXJldCA9IE1NSU9FUlJfQ0FOTk9UT1BFTjsKCX0KCWJyZWFrOwoKICAgIGNhc2UgTU1JT01fQ0xPU0U6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IHdGbGFncyBwYXJhbWV0ZXIgZnJvbSBtbWlvQ2xvc2UKCSAqIGxQYXJhbTIgPSB1bnVzZWQKCSAqIFJldHVybnM6IHplcm8gb24gc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgoJICovCglpZiAoIShsUGFyYW0xICYgTU1JT19GSE9QRU4pKQoJICAgIF9sY2xvc2UoKEhGSUxFKWxwbW1pb2luZm8tPmFkd0luZm9bMF0pOwoJYnJlYWs7CgogICAgY2FzZSBNTUlPTV9SRUFEOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBodWdlIHBvaW50ZXIgdG8gcmVhZCBidWZmZXIKCSAqIGxQYXJhbTIgPSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZAoJICogUmV0dXJuczogbnVtYmVyIG9mIGJ5dGVzIHJlYWQsIDAgZm9yIEVPRiwgLTEgZm9yIGVycm9yIChlcnJvciBjb2RlCgkgKgkgICBpbiB3RXJyb3JSZXQpCgkgKi8KCXJldCA9IF9scmVhZCgoSEZJTEUpbHBtbWlvaW5mby0+YWR3SW5mb1swXSwgKEhQU1RSKWxQYXJhbTEsIChMT05HKWxQYXJhbTIpOwoJaWYgKHJldCAhPSAtMSkKCSAgICBscG1taW9pbmZvLT5sRGlza09mZnNldCArPSByZXQ7CgoJYnJlYWs7CgogICAgY2FzZSBNTUlPTV9XUklURToKICAgIGNhc2UgTU1JT01fV1JJVEVGTFVTSDoKCS8qIG5vIGludGVybmFsIGJ1ZmZlcmluZywgc28gV1JJVEVGTFVTSCBoYW5kbGVkIHNhbWUgYXMgV1JJVEUgKi8KCgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IGh1Z2UgcG9pbnRlciB0byB3cml0ZSBidWZmZXIKCSAqIGxQYXJhbTIgPSBudW1iZXIgb2YgYnl0ZXMgdG8gd3JpdGUKCSAqIFJldHVybnM6IG51bWJlciBvZiBieXRlcyB3cml0dGVuLCAtMSBmb3IgZXJyb3IgKGVycm9yIGNvZGUgaW4KCSAqCQl3RXJyb3JSZXQpCgkgKi8KCXJldCA9IF9od3JpdGUoKEhGSUxFKWxwbW1pb2luZm8tPmFkd0luZm9bMF0sIChIUFNUUilsUGFyYW0xLCAoTE9ORylsUGFyYW0yKTsKCWlmIChyZXQgIT0gLTEpCgkgICAgbHBtbWlvaW5mby0+bERpc2tPZmZzZXQgKz0gcmV0OwoJYnJlYWs7CgogICAgY2FzZSBNTUlPTV9TRUVLOgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBuZXcgcG9zaXRpb24KCSAqIGxQYXJhbTIgPSBmcm9tIHdoZW5jZSB0byBzZWVrIChTRUVLX1NFVCwgU0VFS19DVVIsIFNFRUtfRU5EKQoJICogUmV0dXJuczogbmV3IGZpbGUgcG9zdGlvbiwgLTEgb24gZXJyb3IKCSAqLwoJcmV0ID0gX2xsc2VlaygoSEZJTEUpbHBtbWlvaW5mby0+YWR3SW5mb1swXSwgKExPTkcpbFBhcmFtMSwgKExPTkcpbFBhcmFtMik7CglpZiAocmV0ICE9IC0xKQoJICAgIGxwbW1pb2luZm8tPmxEaXNrT2Zmc2V0ID0gcmV0OwoJcmV0dXJuIHJldDsKCiAgICBjYXNlIE1NSU9NX1JFTkFNRToKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gb2xkIG5hbWUKCSAqIGxQYXJhbTIgPSBuZXcgbmFtZQoJICogUmV0dXJuczogemVybyBvbiBzdWNjZXNzLCBub24temVybyBvbiBmYWlsdXJlCgkgKi8KIAkgaWYgKCFNb3ZlRmlsZUEoKGNvbnN0IGNoYXIqKWxQYXJhbTEsIChjb25zdCBjaGFyKilsUGFyYW0yKSkKCSAgICAgcmV0ID0gTU1JT0VSUl9GSUxFTk9URk9VTkQ7CgkgYnJlYWs7CgogICAgZGVmYXVsdDoKCUZJWE1FKCJ1bmV4cGVjdGVkIG1lc3NhZ2UgJXVcbiIsIHVNZXNzYWdlKTsKCXJldHVybiAwOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgIAltbWlvTWVtSU9Qcm9jICAgICAgICAgICAJCVtpbnRlcm5hbF0KICovCnN0YXRpYyBMUkVTVUxUIENBTExCQUNLIG1taW9NZW1JT1Byb2MoTFBNTUlPSU5GTyBscG1taW9pbmZvLCBVSU5UIHVNZXNzYWdlLAoJCQkJICAgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgICBUUkFDRSgiKCVwLDB4JTA0eCwweCUwOGx4LDB4JTA4bHgpXG4iLCBscG1taW9pbmZvLCB1TWVzc2FnZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogICAgc3dpdGNoICh1TWVzc2FnZSkgewoKICAgIGNhc2UgTU1JT01fT1BFTjoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gZmlsZW5hbWUgKG11c3QgYmUgTlVMTCkKCSAqIGxQYXJhbTIgPSByZXNlcnZlZAoJICogUmV0dXJuczogemVybyBvbiBzdWNjZXNzLCBlcnJvciBjb2RlIG9uIGVycm9yCgkgKiBOT1RFOiBsRGlza09mZnNldCBhdXRvbWF0aWNhbGx5IHNldCB0byB6ZXJvCgkgKi8KCS8qIEZJWE1FOiBpbyBwcm9jIHNob3VsZG4ndCBjaGFuZ2UgaXQgKi8KCWlmICghKGxwbW1pb2luZm8tPmR3RmxhZ3MgJiBNTUlPX0NSRUFURSkpCgkgICAgbHBtbWlvaW5mby0+cGNoRW5kUmVhZCA9IGxwbW1pb2luZm8tPnBjaEVuZFdyaXRlOwogICAgICAgIGxwbW1pb2luZm8tPmFkd0luZm9bMF0gPSBIRklMRV9FUlJPUjsKCXJldHVybiAwOwoKICAgIGNhc2UgTU1JT01fQ0xPU0U6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IHdGbGFncyBwYXJhbWV0ZXIgZnJvbSBtbWlvQ2xvc2UKCSAqIGxQYXJhbTIgPSB1bnVzZWQKCSAqIFJldHVybnM6IHplcm8gb24gc3VjY2VzcywgZXJyb3IgY29kZSBvbiBlcnJvcgoJICovCglyZXR1cm4gMDsKCiAgICBjYXNlIE1NSU9NX1JFQUQ6CgkvKiBQYXJhbWV0ZXJzOgoJICogbFBhcmFtMSA9IGh1Z2UgcG9pbnRlciB0byByZWFkIGJ1ZmZlcgoJICogbFBhcmFtMiA9IG51bWJlciBvZiBieXRlcyB0byByZWFkCgkgKiBSZXR1cm5zOiBudW1iZXIgb2YgYnl0ZXMgcmVhZCwgMCBmb3IgRU9GLCAtMSBmb3IgZXJyb3IgKGVycm9yIGNvZGUKCSAqCSAgIGluIHdFcnJvclJldCkKCSAqIE5PVEU6IGxEaXNrT2Zmc2V0IHNob3VsZCBiZSB1cGRhdGVkCgkgKi8KCUZJWE1FKCJNTUlPTV9SRUFEIG9uIG1lbW9yeSBmaWxlcyBzaG91bGQgbm90IG9jY3VyLCBidWZmZXIgbWF5IGJlIGxvc3QhXG4iKTsKCXJldHVybiAwOwoKICAgIGNhc2UgTU1JT01fV1JJVEU6CiAgICBjYXNlIE1NSU9NX1dSSVRFRkxVU0g6CgkvKiBubyBpbnRlcm5hbCBidWZmZXJpbmcsIHNvIFdSSVRFRkxVU0ggaGFuZGxlZCBzYW1lIGFzIFdSSVRFICovCgoJLyogUGFyYW1ldGVyczoKCSAqIGxQYXJhbTEgPSBodWdlIHBvaW50ZXIgdG8gd3JpdGUgYnVmZmVyCgkgKiBsUGFyYW0yID0gbnVtYmVyIG9mIGJ5dGVzIHRvIHdyaXRlCgkgKiBSZXR1cm5zOiBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiwgLTEgZm9yIGVycm9yIChlcnJvciBjb2RlIGluCgkgKgkJd0Vycm9yUmV0KQoJICogTk9URTogbERpc2tPZmZzZXQgc2hvdWxkIGJlIHVwZGF0ZWQKCSAqLwoJRklYTUUoIk1NSU9NX1dSSVRFIG9uIG1lbW9yeSBmaWxlcyBzaG91bGQgbm90IG9jY3VyLCBidWZmZXIgbWF5IGJlIGxvc3QhXG4iKTsKCXJldHVybiAwOwoKICAgIGNhc2UgTU1JT01fU0VFSzoKCS8qIFBhcmFtZXRlcnM6CgkgKiBsUGFyYW0xID0gbmV3IHBvc2l0aW9uCgkgKiBsUGFyYW0yID0gZnJvbSB3aGVuY2UgdG8gc2VlayAoU0VFS19TRVQsIFNFRUtfQ1VSLCBTRUVLX0VORCkKCSAqIFJldHVybnM6IG5ldyBmaWxlIHBvc3Rpb24sIC0xIG9uIGVycm9yCgkgKiBOT1RFOiBsRGlza09mZnNldCBzaG91bGQgYmUgdXBkYXRlZAoJICovCglGSVhNRSgiTU1JT01fU0VFSyBvbiBtZW1vcnkgZmlsZXMgc2hvdWxkIG5vdCBvY2N1ciwgYnVmZmVyIG1heSBiZSBsb3N0IVxuIik7CglyZXR1cm4gLTE7CgogICAgZGVmYXVsdDoKCUZJWE1FKCJ1bmV4cGVjdGVkIG1lc3NhZ2UgJXVcbiIsIHVNZXNzYWdlKTsKCXJldHVybiAwOwogICAgfQp9CgovKiBUaGlzIGFycmF5IHdpbGwgYmUgdGhlIGVudGlyZSBsaXN0IGZvciBtb3N0IGFwcHMgCiAqIE5vdGUgdGhhdCB0ZW1wb3JhcnkgaW9Qcm9jcyB3aWxsIGJlIHN0b3JlZCB3aXRoIGEgMCBmb3VyQ0MgY29kZQogKi8KCnN0YXRpYyBzdHJ1Y3QgSU9Qcm9jTGlzdCBkZWZhdWx0UHJvY3NbXSA9IHsKICAgIHsmZGVmYXVsdFByb2NzWzFdLCBGT1VSQ0NfRE9TLCAoTFBNTUlPUFJPQyltbWlvRG9zSU9Qcm9jLCBNTUlPX1BST0NfMzJBLCAwfSwKICAgIHtOVUxMLCAgICAgICAgICAgICBGT1VSQ0NfTUVNLCAoTFBNTUlPUFJPQyltbWlvTWVtSU9Qcm9jLCBNTUlPX1BST0NfMzJBLCAwfSwKfTsKCnN0YXRpYyBzdHJ1Y3QgSU9Qcm9jTGlzdCoJcElPUHJvY0xpc3RBbmNob3IgPSAmZGVmYXVsdFByb2NzWzBdOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgCU1NSU9fRmluZFByb2NOb2RlIAkJCVtJTlRFUk5BTF0KICoKICogRmluZHMgdGhlIFByb2NMaXN0IG5vZGUgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gRk9VUkNDIGNvZGUuCiAqLwpzdGF0aWMgc3RydWN0IElPUHJvY0xpc3QqCU1NSU9fRmluZFByb2NOb2RlKEZPVVJDQyBmY2NJT1Byb2MpCnsKICAgIHN0cnVjdCBJT1Byb2NMaXN0KglwTGlzdE5vZGU7CgogICAgZm9yIChwTGlzdE5vZGUgPSBwSU9Qcm9jTGlzdEFuY2hvcjsgcExpc3ROb2RlOyBwTGlzdE5vZGUgPSBwTGlzdE5vZGUtPnBOZXh0KSB7CglpZiAocExpc3ROb2RlLT5mb3VyQ0MgPT0gZmNjSU9Qcm9jKSB7CgkgICAgcmV0dXJuIHBMaXN0Tm9kZTsKCX0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJTU1JT19JbnN0YWxsSU9Qcm9jIAkJCVtJTlRFUk5BTF0KICovCkxQTU1JT1BST0MgTU1JT19JbnN0YWxsSU9Qcm9jKEZPVVJDQyBmY2NJT1Byb2MsIExQTU1JT1BST0MgcElPUHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdGbGFncywgZW51bSBtbWlvUHJvY1R5cGUgdHlwZSkKewogICAgTFBNTUlPUFJPQwkgICAgICAgIGxwUHJvYyA9IE5VTEw7CiAgICBzdHJ1Y3QgSU9Qcm9jTGlzdCogIHBMaXN0Tm9kZTsKICAgIHN0cnVjdCBJT1Byb2NMaXN0KiogcHBMaXN0Tm9kZTsKCiAgICBUUkFDRSgiKCUwOHgsICVwLCAlMDhYLCAlaSlcbiIsIGZjY0lPUHJvYywgcElPUHJvYywgZHdGbGFncywgdHlwZSk7CgogICAgaWYgKGR3RmxhZ3MgJiBNTUlPX0dMT0JBTFBST0MpCglGSVhNRSgiR2xvYmFsIHByb2NlZHVyZXMgbm90IGltcGxlbWVudGVkXG4iKTsKCiAgICAvKiBqdXN0IGhhbmRsZSB0aGUga25vd24gcHJvY2VkdXJlcyBmb3Igbm93ICovCiAgICBzd2l0Y2ggKGR3RmxhZ3MgJiAoTU1JT19JTlNUQUxMUFJPQ3xNTUlPX1JFTU9WRVBST0N8TU1JT19GSU5EUFJPQykpIHsKICAgIGNhc2UgTU1JT19JTlNUQUxMUFJPQzoKCS8qIENyZWF0ZSBuZXcgZW50cnkgZm9yIHRoZSBJT1Byb2MgbGlzdCAqLwoJcExpc3ROb2RlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcExpc3ROb2RlKSk7CglpZiAocExpc3ROb2RlKSB7CgkgICAgLyogRmlsbCBpbiB0aGlzIG5vZGUgKi8KCSAgICBwTGlzdE5vZGUtPmZvdXJDQyA9IGZjY0lPUHJvYzsKCSAgICBwTGlzdE5vZGUtPnBJT1Byb2MgPSBwSU9Qcm9jOwoJICAgIHBMaXN0Tm9kZS0+dHlwZSA9IHR5cGU7CgkgICAgcExpc3ROb2RlLT5jb3VudCA9IDA7CgoJICAgIC8qIFN0aWNrIGl0IG9uIHRoZSBlbmQgb2YgdGhlIGxpc3QgKi8KCSAgICBwTGlzdE5vZGUtPnBOZXh0ID0gcElPUHJvY0xpc3RBbmNob3I7CgkgICAgcElPUHJvY0xpc3RBbmNob3IgPSBwTGlzdE5vZGU7CgoJICAgIC8qIFJldHVybiB0aGlzIElPUHJvYyAtIHRoYXQncyBob3cgdGhlIGNhbGxlciBrbm93cyB3ZSBzdWNjZWVkZWQgKi8KCSAgICBscFByb2MgPSBwSU9Qcm9jOwoJfQoJYnJlYWs7CgogICAgY2FzZSBNTUlPX1JFTU9WRVBST0M6CgkvKgoJICogU2VhcmNoIGZvciB0aGUgbm9kZSB0aGF0IHdlJ3JlIHRyeWluZyB0byByZW1vdmUKICAgICAgICAgKiBXZSBzZWFyY2ggZm9yIGEgbWF0Y2hpbmcgZm91ckNDIGNvZGUgaWYgaXQncyBub24gbnVsbCwgb3IgdGhlIHByb2MKICAgICAgICAgKiBhZGRyZXNzIG90aGVyd2lzZQogICAgICAgICAqIG5vdGUgdGhhdCB0aGlzIG1ldGhvZCB3b24ndCBmaW5kIHRoZSBmaXJzdCBpdGVtIG9uIHRoZSBsaXN0LCBidXQKCSAqIHNpbmNlIHRoZSBmaXJzdCB0d28gaXRlbXMgb24gdGhpcyBsaXN0IGFyZSBvbmVzIHdlIHdvbid0CgkgKiBsZXQgdGhlIHVzZXIgZGVsZXRlIGFueXdheSwgdGhhdCdzIG9rYXkKCSAqLwoJcHBMaXN0Tm9kZSA9ICZwSU9Qcm9jTGlzdEFuY2hvcjsKCXdoaWxlICgoKnBwTGlzdE5vZGUpICYmIAogICAgICAgICAgICAgICAoKGZjY0lPUHJvYyAhPSAwKSA/IAogICAgICAgICAgICAgICAgKCpwcExpc3ROb2RlKS0+Zm91ckNDICE9IGZjY0lPUHJvYyA6IAogICAgICAgICAgICAgICAgKCpwcExpc3ROb2RlKS0+cElPUHJvYyAhPSBwSU9Qcm9jKSkKCSAgICBwcExpc3ROb2RlID0gJigoKnBwTGlzdE5vZGUpLT5wTmV4dCk7CgoJaWYgKCpwcExpc3ROb2RlKSB7IC8qIGZvdW5kIGl0ICovCgkgICAgLyogRklYTUU6IHdoYXQgc2hvdWxkIGJlIGRvbmUgaWYgYW4gb3BlbiBtbWlvIG9iamVjdCB1c2VzIHRoaXMgcHJvYyA/CgkgICAgICogc2hhbGwgd2UgcmV0dXJuIGFuIGVycm9yLCBudWtlIHRoZSBtbWlvIG9iamVjdCA/CgkgICAgICovCgkgICAgaWYgKCgqcHBMaXN0Tm9kZSktPmNvdW50KSB7CgkJRVJSKCJDYW5ub3QgcmVtb3ZlIGEgbW1JT1Byb2Mgd2hpbGUgaW4gdXNlXG4iKTsKCQlicmVhazsKCSAgICB9CgkgICAgLyogcmVtb3ZlIGl0LCBidXQgb25seSBpZiBpdCBpc24ndCBidWlsdGluICovCgkgICAgaWYgKCgqcHBMaXN0Tm9kZSkgPj0gZGVmYXVsdFByb2NzICYmCgkJKCpwcExpc3ROb2RlKSA8IGRlZmF1bHRQcm9jcyArIHNpemVvZihkZWZhdWx0UHJvY3MpKSB7CgkJV0FSTigiVHJpZWQgdG8gcmVtb3ZlIGJ1aWx0LWluIG1taW8gcHJvYy4gU2tpcHBpbmdcbiIpOwoJICAgIH0gZWxzZSB7CgkJLyogT2theSwgbnVrZSBpdCAqLwoJCXN0cnVjdCBJT1Byb2NMaXN0KiAgcHRtcE5vZGUgPSAqcHBMaXN0Tm9kZTsKCQlscFByb2MgPSAoKnBwTGlzdE5vZGUpLT5wSU9Qcm9jOwoJCSpwcExpc3ROb2RlID0gKCpwcExpc3ROb2RlKS0+cE5leHQ7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHRtcE5vZGUpOwoJICAgIH0KCX0KCWJyZWFrOwoKICAgIGNhc2UgTU1JT19GSU5EUFJPQzoKCWlmICgocExpc3ROb2RlID0gTU1JT19GaW5kUHJvY05vZGUoZmNjSU9Qcm9jKSkpIHsKCSAgICBscFByb2MgPSBwTGlzdE5vZGUtPnBJT1Byb2M7Cgl9CglicmVhazsKICAgIH0KCiAgICByZXR1cm4gbHBQcm9jOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJc2VuZF9tZXNzYWdlICAgIAkJCVtJTlRFUk5BTF0KICovCnN0YXRpYyBMUkVTVUxUCXNlbmRfbWVzc2FnZShzdHJ1Y3QgSU9Qcm9jTGlzdCogaW9Qcm9jLCBMUE1NSU9JTkZPIG1taW9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHdNc2csIExQQVJBTSBsUGFyYW0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0yLCBlbnVtIG1taW9Qcm9jVHlwZSB0eXBlKQp7CiAgICBMUkVTVUxUIAkJcmVzdWx0ID0gTU1TWVNFUlJfRVJST1I7CiAgICBMUEFSQU0JCWxwMSA9IGxQYXJhbTEsIGxwMiA9IGxQYXJhbTI7CgogICAgaWYgKCFpb1Byb2MpIHsKCUVSUigiYnJyclxuIik7CglyZXN1bHQgPSBNTVNZU0VSUl9JTlZBTFBBUkFNOwogICAgfQoKICAgIHN3aXRjaCAoaW9Qcm9jLT50eXBlKSB7CiAgICBjYXNlIE1NSU9fUFJPQ18xNjoKICAgICAgICBpZiAocEZuTW1pb0NhbGxiYWNrMTYpCiAgICAgICAgICAgIHJlc3VsdCA9IHBGbk1taW9DYWxsYmFjazE2KChEV09SRClpb1Byb2MtPnBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1taW9pbmZvLCB3TXNnLCBscDEsIGxwMik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIE1NSU9fUFJPQ18zMkE6CiAgICBjYXNlIE1NSU9fUFJPQ18zMlc6CglpZiAoaW9Qcm9jLT50eXBlICE9IHR5cGUpIHsKCSAgICAvKiBtYXAgKGxQYXJhbTEsIGxQYXJhbTIpIGludG8gKGxwMSwgbHAyKSAzMiBBPD0+VyAqLwoJICAgIEZJWE1FKCJOSVkgMzIgQTw9PlcgbWFwcGluZ1xuIik7Cgl9CglyZXN1bHQgPSAoaW9Qcm9jLT5wSU9Qcm9jKSgoTFBTVFIpbW1pb2luZm8sIHdNc2csIGxwMSwgbHAyKTsKCiNpZiAwCglpZiAoaW9Qcm9jLT50eXBlICE9IHR5cGUpIHsKCSAgICAvKiB1bm1hcCAobFBhcmFtMSwgbFBhcmFtMikgaW50byAobHAxLCBscDIpIDMyIEE8PT5XICovCgl9CiNlbmRpZgoJYnJlYWs7CiAgICBkZWZhdWx0OgoJRklYTUUoIkludGVybmFsIGVycm9yXG4iKTsKICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAJCQlNTUlPX1BhcnNlRXh0QSAJCSAgICAgICAgW2ludGVybmFsXQogKgogKiBQYXJzZXMgYSBmaWxlbmFtZSBmb3IgdGhlIGV4dGVuc2lvbi4KICoKICogUkVUVVJOUwogKiAgVGhlIEZPVVJDQyBjb2RlIGZvciB0aGUgZXh0ZW5zaW9uIGlmIGZvdW5kLCBlbHNlIDAuCiAqLwpzdGF0aWMgRk9VUkNDIE1NSU9fUGFyc2VFeHRBKExQQ1NUUiBzekZpbGVOYW1lKQp7CiAgICAvKiBGaWxlbmFtZXMgYXJlIG9mIHRoZSBmb3JtIGZpbGUuZXh0eytBQkN9CiAgICAgICBGb3Igbm93LCB3ZSB0YWtlIHRoZSBsYXN0ICcrJyBpZiBwcmVzZW50ICovCgogICAgRk9VUkNDIHJldCA9IDA7CgogICAgLyogTm90ZSB0aGF0IGV4dHtTdGFydCxFbmR9IHBvaW50IHRvIHRoZSAuIGFuZCArIHJlc3BlY3RpdmVseSAqLwogICAgTFBTVFIgZXh0RW5kOwogICAgTFBTVFIgZXh0U3RhcnQ7CgogICAgVFJBQ0UoIiglcylcbiIsIGRlYnVnc3RyX2Eoc3pGaWxlTmFtZSkpOwoKICAgIGlmICghc3pGaWxlTmFtZSkKCXJldHVybiByZXQ7CgogICAgLyogRmluZCB0aGUgbGFzdCAnLicgKi8KICAgIGV4dFN0YXJ0ID0gc3RycmNocihzekZpbGVOYW1lLCcuJyk7CgogICAgaWYgKCFleHRTdGFydCkgewogICAgICAgICBFUlIoIk5vIC4gaW4gc3pGaWxlTmFtZTogJXNcbiIsIGRlYnVnc3RyX2Eoc3pGaWxlTmFtZSkpOwogICAgfSBlbHNlIHsKICAgICAgICBDSEFSIGV4dFs1XTsKCiAgICAgICAgLyogRmluZCB0aGUgJysnIGFmdGVyd2FyZHMgKi8KICAgICAgICBleHRFbmQgPSBzdHJjaHIoZXh0U3RhcnQsJysnKTsKICAgICAgICBpZiAoZXh0RW5kKSB7CgogICAgICAgICAgICBpZiAoZXh0RW5kIC0gZXh0U3RhcnQgLSAxID4gNCkKICAgICAgICAgICAgICAgIFdBUk4oIkV4dGVuc2lvbiBsZW5ndGggPiA0XG4iKTsKICAgICAgICAgICAgbHN0cmNweW5BKGV4dCwgZXh0U3RhcnQgKyAxLCBtaW4oZXh0RW5kLWV4dFN0YXJ0LDUpKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogTm8gKyBzbyBqdXN0IGFuIGV4dGVuc2lvbiAqLwogICAgICAgICAgICBpZiAoc3RybGVuKGV4dFN0YXJ0KSA+IDQpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkV4dGVuc2lvbiBsZW5ndGggPiA0XG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsc3RyY3B5bkEoZXh0LCBleHRTdGFydCArIDEsIDUpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiR290IGV4dGVuc2lvbjogJXNcbiIsIGRlYnVnc3RyX2EoZXh0KSk7CgogICAgICAgIC8qIEZPVVJDQyBjb2RlcyBpZGVudGlmeWluZyBmaWxlLWV4dGVuc2lvbnMgbXVzdCBiZSB1cHBlcmNhc2UgKi8KICAgICAgICByZXQgPSBtbWlvU3RyaW5nVG9GT1VSQ0NBKGV4dCwgTU1JT19UT1VQUEVSKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQlNTUlPX0dldAkJCVtpbnRlcm5hbF0KICoKICogUmV0cmlldmVzIHRoZSBtbWlvIG9iamVjdCBmcm9tIGN1cnJlbnQgcHJvY2VzcwogKi8KTFBXSU5FX01NSU8JTU1JT19HZXQoSE1NSU8gaCkKewogICAgTFBXSU5FX01NSU8JCXdtID0gTlVMTDsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmV0lOTU1fSURhdGEuY3MpOwogICAgZm9yICh3bSA9IFdJTk1NX0lEYXRhLmxwTU1JTzsgd207IHdtID0gd20tPmxwTmV4dCkgewoJaWYgKHdtLT5pbmZvLmhtbWlvID09IGgpCgkgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmV0lOTU1fSURhdGEuY3MpOwogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJTU1JT19DcmVhdGUJCQlbaW50ZXJuYWxdCiAqCiAqIENyZWF0ZXMgYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gZm9yIGEgbW1pbyBpbnN0YW5jZQogKi8Kc3RhdGljCUxQV0lORV9NTUlPCQlNTUlPX0NyZWF0ZSh2b2lkKQp7CiAgICBzdGF0aWMJV09SRAlNTUlPX2NvdW50ZXIgPSAwOwogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIHdtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXSU5FX01NSU8pKTsKICAgIGlmICh3bSkgewoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJldJTk1NX0lEYXRhLmNzKTsKICAgICAgICAvKiBsb29rdXAgbmV4dCB1bmFsbG9jYXRlZCBXT1JEIGhhbmRsZSwgd2l0aCBhIG5vbiBOVUxMIHZhbHVlICovCgl3aGlsZSAoKytNTUlPX2NvdW50ZXIgPT0gMCB8fCBNTUlPX0dldCgoSE1NSU8pKFVMT05HX1BUUilNTUlPX2NvdW50ZXIpKTsKCXdtLT5pbmZvLmhtbWlvID0gKEhNTUlPKShVTE9OR19QVFIpTU1JT19jb3VudGVyOwoJd20tPmxwTmV4dCA9IFdJTk1NX0lEYXRhLmxwTU1JTzsKCVdJTk1NX0lEYXRhLmxwTU1JTyA9IHdtOwoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJldJTk1NX0lEYXRhLmNzKTsKICAgIH0KICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCU1NSU9fRGVzdHJveQkJCVtpbnRlcm5hbF0KICotCiAqIERlc3Ryb3lzIGFuIGludGVybmFsIHJlcHJlc2VudGF0aW9uIGZvciBhIG1taW8gaW5zdGFuY2UKICovCnN0YXRpYwlCT09MCQlNTUlPX0Rlc3Ryb3koTFBXSU5FX01NSU8gd20pCnsKICAgIExQV0lORV9NTUlPKgltOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZXSU5NTV9JRGF0YS5jcyk7CiAgICAvKiBzZWFyY2ggZm9yIHRoZSBtYXRjaGluZyBvbmUuLi4gKi8KICAgIG0gPSAmKFdJTk1NX0lEYXRhLmxwTU1JTyk7CiAgICB3aGlsZSAoKm0gJiYgKm0gIT0gd20pIG0gPSAmKCptKS0+bHBOZXh0OwogICAgLyogLi4uYW5kIGRlc3Ryb3kgKi8KICAgIGlmICgqbSkgewoJKm0gPSAoKm0pLT5scE5leHQ7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB3bSk7Cgl3bSA9IE5VTEw7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmV0lOTU1fSURhdGEuY3MpOwogICAgcmV0dXJuIHdtID8gRkFMU0UgOiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAJCU1NSU9fRmx1c2ggCQkJW0lOVEVSTkFMXQogKi8Kc3RhdGljCU1NUkVTVUxUIE1NSU9fRmx1c2goV0lORV9NTUlPKiB3bSwgVUlOVCB1RmxhZ3MpCnsKICAgIGlmICh3bS0+aW5mby5jY2hCdWZmZXIgJiYgKHdtLT5pbmZvLmZjY0lPUHJvYyAhPSBGT1VSQ0NfTUVNKSkgewoJLyogbm90IHF1aXRlIHN1cmUgd2hhdCB0byBkbyBoZXJlLCBidXQgSSdsbCBndWVzcyAqLwoJaWYgKHdtLT5pbmZvLmR3RmxhZ3MgJiBNTUlPX0RJUlRZKSB7CiAgICAgICAgICAgIC8qIEZJWE1FOiBlcnJvciBoYW5kbGluZyAqLwoJICAgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssIAogICAgICAgICAgICAgICAgICAgICAgICAgd20tPmluZm8ubEJ1Zk9mZnNldCwgU0VFS19TRVQsIE1NSU9fUFJPQ18zMkEpOwoJICAgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1dSSVRFLCAKICAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pd20tPmluZm8ucGNoQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgd20tPmluZm8ucGNoTmV4dCAtIHdtLT5pbmZvLnBjaEJ1ZmZlciwgTU1JT19QUk9DXzMyQSk7Cgl9CglpZiAodUZsYWdzICYgTU1JT19FTVBUWUJVRikKCSAgICB3bS0+aW5mby5wY2hOZXh0ID0gd20tPmluZm8ucGNoRW5kUmVhZCA9IHdtLT5pbmZvLnBjaEJ1ZmZlcjsKICAgIH0KICAgIHdtLT5pbmZvLmR3RmxhZ3MgJj0gfk1NSU9fRElSVFk7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgCQlNTUlPX0dyYWJOZXh0QnVmZmVyCQkJW0lOVEVSTkFMXQogKi8Kc3RhdGljIExPTkcJTU1JT19HcmFiTmV4dEJ1ZmZlcihMUFdJTkVfTU1JTyB3bSwgaW50IGZvcl9yZWFkKQp7CiAgICBMT05HCXNpemUgPSB3bS0+aW5mby5jY2hCdWZmZXI7CgogICAgVFJBQ0UoImJvPSV4IGRvPSV4IG9mPSVseFxuIiwKCSAgd20tPmluZm8ubEJ1Zk9mZnNldCwgd20tPmluZm8ubERpc2tPZmZzZXQsCgkgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssIDAsIFNFRUtfQ1VSLCBNTUlPX1BST0NfMzJBKSk7CgogICAgd20tPmluZm8ubEJ1Zk9mZnNldCA9IHdtLT5pbmZvLmxEaXNrT2Zmc2V0OwogICAgd20tPmluZm8ucGNoTmV4dCA9IHdtLT5pbmZvLnBjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLnBjaEVuZFJlYWQgPSB3bS0+aW5mby5wY2hCdWZmZXI7CiAgICB3bS0+aW5mby5wY2hFbmRXcml0ZSA9IHdtLT5pbmZvLnBjaEJ1ZmZlciArIHdtLT5pbmZvLmNjaEJ1ZmZlcjsKCiAgICB3bS0+YkJ1ZmZlckxvYWRlZCA9IFRSVUU7CiAgICBpZiAoZm9yX3JlYWQpIHsKCXNpemUgPSBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9SRUFELCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pd20tPmluZm8ucGNoQnVmZmVyLCBzaXplLCBNTUlPX1BST0NfMzJBKTsKCWlmIChzaXplID4gMCkKCSAgICB3bS0+aW5mby5wY2hFbmRSZWFkICs9IHNpemU7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+YkJ1ZmZlckxvYWRlZCA9IEZBTFNFOwogICAgfQoKICAgIHJldHVybiBzaXplOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgIAkJTU1JT19TZXRCdWZmZXIgCQkJCVtJTlRFUk5BTF0KICovCnN0YXRpYyBNTVJFU1VMVCBNTUlPX1NldEJ1ZmZlcihXSU5FX01NSU8qIHdtLCB2b2lkKiBwY2hCdWZmZXIsIExPTkcgY2NoQnVmZmVyLAoJCQkgICAgICAgVUlOVCB1RmxhZ3MpCnsKICAgIFRSQUNFKCIoJXAgJXAgJWQgJXUpXG4iLCB3bSwgcGNoQnVmZmVyLCBjY2hCdWZmZXIsIHVGbGFncyk7CgogICAgaWYgKHVGbGFncykJCQlyZXR1cm4gTU1TWVNFUlJfSU5WQUxQQVJBTTsKICAgIGlmIChjY2hCdWZmZXIgPiAweEZGRkYpCglXQVJOKCJVbnRlc3RlZCBoYW5kbGluZyBvZiBodWdlIG1taW8gYnVmZmVycyAoJWQgPj0gNjRrKVxuIiwgY2NoQnVmZmVyKTsKCiAgICBpZiAoTU1JT19GbHVzaCh3bSwgMCkgIT0gTU1TWVNFUlJfTk9FUlJPUikKCXJldHVybiBNTUlPRVJSX0NBTk5PVFdSSVRFOwoKICAgIC8qIGZyZWUgcHJldmlvdXMgYnVmZmVyIGlmIGFsbG9jYXRlZCAqLwogICAgaWYgKHdtLT5pbmZvLmR3RmxhZ3MgJiBNTUlPX0FMTE9DQlVGKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd20tPmluZm8ucGNoQnVmZmVyKTsKICAgICAgICB3bS0+aW5mby5wY2hCdWZmZXIgPSBOVUxMOwoJd20tPmluZm8uZHdGbGFncyAmPSB+TU1JT19BTExPQ0JVRjsKICAgIH0KCiAgICBpZiAocGNoQnVmZmVyKSB7CiAgICAgICAgd20tPmluZm8ucGNoQnVmZmVyID0gcGNoQnVmZmVyOwogICAgfSBlbHNlIGlmIChjY2hCdWZmZXIpIHsKCWlmICghKHdtLT5pbmZvLnBjaEJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjY2hCdWZmZXIpKSkKCSAgICByZXR1cm4gTU1JT0VSUl9PVVRPRk1FTU9SWTsKCXdtLT5pbmZvLmR3RmxhZ3MgfD0gTU1JT19BTExPQ0JVRjsKICAgIH0gZWxzZSB7Cgl3bS0+aW5mby5wY2hCdWZmZXIgPSBOVUxMOwogICAgfQoKICAgIHdtLT5pbmZvLmNjaEJ1ZmZlciA9IGNjaEJ1ZmZlcjsKICAgIHdtLT5pbmZvLnBjaE5leHQgPSB3bS0+aW5mby5wY2hCdWZmZXI7CiAgICB3bS0+aW5mby5wY2hFbmRSZWFkID0gd20tPmluZm8ucGNoQnVmZmVyOwogICAgd20tPmluZm8ucGNoRW5kV3JpdGUgPSB3bS0+aW5mby5wY2hCdWZmZXIgKyBjY2hCdWZmZXI7CiAgICB3bS0+aW5mby5sQnVmT2Zmc2V0ID0gMDsKICAgIHdtLT5iQnVmZmVyTG9hZGVkID0gRkFMU0U7CgogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQlNTUlPX09wZW4gICAgICAgCQkJW2ludGVybmFsXQogKi8KSE1NSU8gTU1JT19PcGVuKExQU1RSIHN6RmlsZU5hbWUsIE1NSU9JTkZPKiByZWZtbWluZm8sIERXT1JEIGR3T3BlbkZsYWdzLCAKICAgICAgICAgICAgICAgIGVudW0gbW1pb1Byb2NUeXBlIHR5cGUpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKICAgIE1NSU9JTkZPICAgIAltbWlvaW5mbzsKCiAgICBUUkFDRSgiKCclcycsICVwLCAlMDhYLCAlZCk7XG4iLCBzekZpbGVOYW1lLCByZWZtbWluZm8sIGR3T3BlbkZsYWdzLCB0eXBlKTsKCiAgICBpZiAoIXJlZm1taW5mbykgewogICAgICAgIHJlZm1taW5mbyA9ICZtbWlvaW5mbzsKCgltbWlvaW5mby5mY2NJT1Byb2MgPSAwOwoJbW1pb2luZm8ucElPUHJvYyA9IE5VTEw7CgltbWlvaW5mby5wY2hCdWZmZXIgPSBOVUxMOwoJbW1pb2luZm8uY2NoQnVmZmVyID0gMDsKICAgICAgICB0eXBlID0gTU1JT19QUk9DXzMyQTsKICAgIH0KCiAgICBpZiAoZHdPcGVuRmxhZ3MgJiAoTU1JT19QQVJTRXxNTUlPX0VYSVNUKSkgewoJY2hhcglidWZmZXJbTUFYX1BBVEhdOwoKCWlmIChHZXRGdWxsUGF0aE5hbWVBKHN6RmlsZU5hbWUsIHNpemVvZihidWZmZXIpLCBidWZmZXIsIE5VTEwpID49IHNpemVvZihidWZmZXIpKQoJICAgIHJldHVybiAoSE1NSU8pRkFMU0U7CglpZiAoKGR3T3BlbkZsYWdzICYgTU1JT19FWElTVCkgJiYgKEdldEZpbGVBdHRyaWJ1dGVzQShidWZmZXIpID09IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKSkKCSAgICByZXR1cm4gKEhNTUlPKUZBTFNFOwoJc3RyY3B5KHN6RmlsZU5hbWUsIGJ1ZmZlcik7CglyZXR1cm4gKEhNTUlPKVRSVUU7CiAgICB9CgogICAgaWYgKCh3bSA9IE1NSU9fQ3JlYXRlKCkpID09IE5VTEwpCglyZXR1cm4gMDsKCiAgICAvKiBJZiBib3RoIHBhcmFtcyBhcmUgTlVMTCwgdGhlbiBwYXJzZSB0aGUgZmlsZSBuYW1lIGlmIGF2YWlsYWJsZSAqLwogICAgaWYgKHJlZm1taW5mby0+ZmNjSU9Qcm9jID09IDAgJiYgcmVmbW1pbmZvLT5wSU9Qcm9jID09IE5VTEwpIHsKCXdtLT5pbmZvLmZjY0lPUHJvYyA9IE1NSU9fUGFyc2VFeHRBKHN6RmlsZU5hbWUpOwoJLyogSGFuZGxlIGFueSB1bmhhbmRsZWQvZXJyb3IgY2FzZS4gQXNzdW1lIERPUyBmaWxlICovCglpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IDApCgkgICAgd20tPmluZm8uZmNjSU9Qcm9jID0gRk9VUkNDX0RPUzsKCWlmICghKHdtLT5pb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZSh3bS0+aW5mby5mY2NJT1Byb2MpKSkgewoJICAgIC8qIElmIG5vdCBmb3VuZCwgcmV0cnkgd2l0aCBGT1VSQ0NfRE9TICovCgkgICAgd20tPmluZm8uZmNjSU9Qcm9jID0gRk9VUkNDX0RPUzsKCSAgICBpZiAoISh3bS0+aW9Qcm9jID0gTU1JT19GaW5kUHJvY05vZGUod20tPmluZm8uZmNjSU9Qcm9jKSkpCgkJZ290byBlcnJvcjI7Cgl9Cgl3bS0+YlRtcElPUHJvYyA9IEZBTFNFOwogICAgfQogICAgLyogaWYganVzdCB0aGUgZm91ciBjaGFyYWN0ZXIgY29kZSBpcyBwcmVzZW50LCBsb29rIHVwIElPIHByb2MgKi8KICAgIGVsc2UgaWYgKHJlZm1taW5mby0+cElPUHJvYyA9PSBOVUxMKSB7Cgl3bS0+aW5mby5mY2NJT1Byb2MgPSByZWZtbWluZm8tPmZjY0lPUHJvYzsKCWlmICghKHdtLT5pb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZSh3bS0+aW5mby5mY2NJT1Byb2MpKSkgZ290byBlcnJvcjI7Cgl3bS0+YlRtcElPUHJvYyA9IEZBTFNFOwogICAgfQogICAgLyogaWYgSU8gcHJvYyBzcGVjaWZpZWQsIHVzZSBpdCBhbmQgc3BlY2lmaWVkIGZvdXIgY2hhcmFjdGVyIGNvZGUgKi8KICAgIGVsc2UgewoJd20tPmluZm8uZmNjSU9Qcm9jID0gcmVmbW1pbmZvLT5mY2NJT1Byb2M7CglNTUlPX0luc3RhbGxJT1Byb2Mod20tPmluZm8uZmNjSU9Qcm9jLCByZWZtbWluZm8tPnBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9fSU5TVEFMTFBST0MsIHR5cGUpOwoJaWYgKCEod20tPmlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKHdtLT5pbmZvLmZjY0lPUHJvYykpKSBnb3RvIGVycm9yMjsKCWFzc2VydCh3bS0+aW9Qcm9jLT5wSU9Qcm9jID09IHJlZm1taW5mby0+cElPUHJvYyk7Cgl3bS0+YlRtcElPUHJvYyA9IFRSVUU7CiAgICB9CgogICAgd20tPmJCdWZmZXJMb2FkZWQgPSBGQUxTRTsKICAgIHdtLT5pb1Byb2MtPmNvdW50Kys7CgogICAgaWYgKGR3T3BlbkZsYWdzICYgTU1JT19BTExPQ0JVRikgewoJaWYgKChyZWZtbWluZm8tPndFcnJvclJldCA9IE1NSU9fU2V0QnVmZmVyKHdtLCBOVUxMLCBNTUlPX0RFRkFVTFRCVUZGRVIsIDApKSkKCSAgICBnb3RvIGVycm9yMTsKICAgIH0gZWxzZSBpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pIHsKICAgICAgICByZWZtbWluZm8tPndFcnJvclJldCA9IE1NSU9fU2V0QnVmZmVyKHdtLCByZWZtbWluZm8tPnBjaEJ1ZmZlciwgcmVmbW1pbmZvLT5jY2hCdWZmZXIsIDApOwoJaWYgKHJlZm1taW5mby0+d0Vycm9yUmV0ICE9IE1NU1lTRVJSX05PRVJST1IpCgkgICAgZ290byBlcnJvcjE7Cgl3bS0+YkJ1ZmZlckxvYWRlZCA9IFRSVUU7CiAgICB9IC8qIGVsc2UgPT4gdW5idWZmZXJlZCwgd20tPmluZm8ucGNoQnVmZmVyID09IE5VTEwgKi8KCiAgICAvKiBzZWUgbW1pb0Rvc0lPUHJvYyBmb3IgdGhhdCBvbmUgKi8KICAgIHdtLT5pbmZvLmFkd0luZm9bMF0gPSByZWZtbWluZm8tPmFkd0luZm9bMF07CiAgICB3bS0+aW5mby5kd0ZsYWdzID0gZHdPcGVuRmxhZ3M7CgogICAgLyogY2FsbCBJTyBwcm9jIHRvIGFjdHVhbGx5IG9wZW4gZmlsZSAqLwogICAgcmVmbW1pbmZvLT53RXJyb3JSZXQgPSBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9PUEVOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pc3pGaWxlTmFtZSwgMCwgTU1JT19QUk9DXzMyQSk7CgogICAgLyogZ3JhYiBmaWxlIHNpemUsIHdoZW4gcG9zc2libGUgKi8KICAgIHdtLT5kd0ZpbGVTaXplID0gR2V0RmlsZVNpemUoKEhBTkRMRSl3bS0+aW5mby5hZHdJbmZvWzBdLCBOVUxMKTsKCiAgICBpZiAocmVmbW1pbmZvLT53RXJyb3JSZXQgPT0gMCkKCXJldHVybiB3bS0+aW5mby5obW1pbzsKIGVycm9yMToKICAgIGlmICh3bS0+aW9Qcm9jKSB3bS0+aW9Qcm9jLT5jb3VudC0tOwogZXJyb3IyOgogICAgTU1JT19EZXN0cm95KHdtKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9PcGVuVyAgICAgICAJCVtXSU5NTS5AXQogKi8KSE1NSU8gV0lOQVBJIG1taW9PcGVuVyhMUFdTVFIgc3pGaWxlTmFtZSwgTU1JT0lORk8qIGxwbW1pb2luZm8sCgkJICAgICAgIERXT1JEIGR3T3BlbkZsYWdzKQp7CiAgICBITU1JTyAJcmV0OwogICAgTFBTVFIJc3pGbiA9IE5VTEw7CgogICAgaWYgKHN6RmlsZU5hbWUpCiAgICB7CiAgICAgICAgSU5UICAgICBsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKCBDUF9BQ1AsIDAsIHN6RmlsZU5hbWUsIC0xLCBOVUxMLCAwLCBOVUxMLCBOVUxMICk7CiAgICAgICAgc3pGbiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICk7CiAgICAgICAgaWYgKCFzekZuKSByZXR1cm4gTlVMTDsKICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKCBDUF9BQ1AsIDAsIHN6RmlsZU5hbWUsIC0xLCBzekZuLCBsZW4sIE5VTEwsIE5VTEwgKTsKICAgIH0KCiAgICByZXQgPSBNTUlPX09wZW4oc3pGbiwgbHBtbWlvaW5mbywgZHdPcGVuRmxhZ3MsIE1NSU9fUFJPQ18zMlcpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6Rm4pOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvT3BlbkEgICAgICAgCQlbV0lOTU0uQF0KICovCkhNTUlPIFdJTkFQSSBtbWlvT3BlbkEoTFBTVFIgc3pGaWxlTmFtZSwgTU1JT0lORk8qIGxwbW1pb2luZm8sCgkJICAgICAgIERXT1JEIGR3T3BlbkZsYWdzKQp7CiAgICByZXR1cm4gIE1NSU9fT3BlbihzekZpbGVOYW1lLCBscG1taW9pbmZvLCBkd09wZW5GbGFncywgTU1JT19QUk9DXzMyQSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0Nsb3NlICAgICAgCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvQ2xvc2UoSE1NSU8gaG1taW8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwl3bTsKICAgIE1NUkVTVUxUIAlyZXN1bHQ7CgogICAgVFJBQ0UoIiglcCwgJTA0WCk7XG4iLCBobW1pbywgdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIGlmICgocmVzdWx0ID0gTU1JT19GbHVzaCh3bSwgMCkpICE9IE1NU1lTRVJSX05PRVJST1IpCglyZXR1cm4gcmVzdWx0OwoKICAgIHJlc3VsdCA9IHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX0NMT1NFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB1RmxhZ3MsIDAsIE1NSU9fUFJPQ18zMkEpOwoKICAgIE1NSU9fU2V0QnVmZmVyKHdtLCBOVUxMLCAwLCAwKTsKCiAgICB3bS0+aW9Qcm9jLT5jb3VudC0tOwoKICAgIGlmICh3bS0+YlRtcElPUHJvYykKCU1NSU9fSW5zdGFsbElPUHJvYyh3bS0+aW5mby5mY2NJT1Byb2MsIHdtLT5pb1Byb2MtPnBJT1Byb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NSU9fUkVNT1ZFUFJPQywgd20tPmlvUHJvYy0+dHlwZSk7CgogICAgTU1JT19EZXN0cm95KHdtKTsKCiAgICByZXR1cm4gcmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9SZWFkCSAgICAgICAJW1dJTk1NLkBdCiAqLwpMT05HIFdJTkFQSSBtbWlvUmVhZChITU1JTyBobW1pbywgSFBTVFIgcGNoLCBMT05HIGNjaCkKewogICAgTFBXSU5FX01NSU8Jd207CiAgICBMT05HIAljb3VudDsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJWQpO1xuIiwgaG1taW8sIHBjaCwgY2NoKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIC0xOwoKICAgIC8qIHVuYnVmZmVyZWQgY2FzZSBmaXJzdCAqLwogICAgaWYgKCF3bS0+aW5mby5wY2hCdWZmZXIpCglyZXR1cm4gc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKXBjaCwgY2NoLCBNTUlPX1BST0NfMzJBKTsKCiAgICAvKiBmaXJzdCB0cnkgZnJvbSBjdXJyZW50IGJ1ZmZlciAqLwogICAgaWYgKHdtLT5pbmZvLnBjaE5leHQgIT0gd20tPmluZm8ucGNoRW5kUmVhZCkgewoJY291bnQgPSB3bS0+aW5mby5wY2hFbmRSZWFkIC0gd20tPmluZm8ucGNoTmV4dDsKCWlmIChjb3VudCA+IGNjaCB8fCBjb3VudCA8IDApIGNvdW50ID0gY2NoOwoJbWVtY3B5KHBjaCwgd20tPmluZm8ucGNoTmV4dCwgY291bnQpOwoJd20tPmluZm8ucGNoTmV4dCArPSBjb3VudDsKCXBjaCArPSBjb3VudDsKCWNjaCAtPSBjb3VudDsKICAgIH0gZWxzZQoJY291bnQgPSAwOwoKICAgIGlmIChjY2ggJiYgKHdtLT5pbmZvLmZjY0lPUHJvYyAhPSBGT1VSQ0NfTUVNKSkgewoJYXNzZXJ0KHdtLT5pbmZvLmNjaEJ1ZmZlcik7CgoJd2hpbGUgKGNjaCkgewoJICAgIExPTkcgc2l6ZTsKCgkgICAgc2l6ZSA9IE1NSU9fR3JhYk5leHRCdWZmZXIod20sIFRSVUUpOwoJICAgIGlmIChzaXplIDw9IDApIGJyZWFrOwoJICAgIGlmIChzaXplID4gY2NoKSBzaXplID0gY2NoOwoJICAgIG1lbWNweShwY2gsIHdtLT5pbmZvLnBjaEJ1ZmZlciwgc2l6ZSk7CgkgICAgd20tPmluZm8ucGNoTmV4dCArPSBzaXplOwoJICAgIHBjaCArPSBzaXplOwoJICAgIGNjaCAtPSBzaXplOwoJICAgIGNvdW50ICs9IHNpemU7Cgl9CiAgICB9CgogICAgVFJBQ0UoImNvdW50PSVkXG4iLCBjb3VudCk7CiAgICByZXR1cm4gY291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1dyaXRlICAgICAgCQlbV0lOTU0uQF0KICovCkxPTkcgV0lOQVBJIG1taW9Xcml0ZShITU1JTyBobW1pbywgSFBDU1RSIHBjaCwgTE9ORyBjY2gpCnsKICAgIExQV0lORV9NTUlPCXdtOwogICAgTE9ORwljb3VudDsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJWQpO1xuIiwgaG1taW8sIHBjaCwgY2NoKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIC0xOwoKICAgIGlmICh3bS0+aW5mby5jY2hCdWZmZXIpIHsKCUxPTkcJYnl0ZXNXID0gMDsKCiAgICAgICAgY291bnQgPSAwOwogICAgICAgIHdoaWxlIChjY2gpIHsKICAgICAgICAgICAgaWYgKHdtLT5pbmZvLnBjaE5leHQgIT0gd20tPmluZm8ucGNoRW5kV3JpdGUpIHsKICAgICAgICAgICAgICAgIGNvdW50ID0gd20tPmluZm8ucGNoRW5kV3JpdGUgLSB3bS0+aW5mby5wY2hOZXh0OwogICAgICAgICAgICAgICAgaWYgKGNvdW50ID4gY2NoIHx8IGNvdW50IDwgMCkgY291bnQgPSBjY2g7CiAgICAgICAgICAgICAgICBtZW1jcHkod20tPmluZm8ucGNoTmV4dCwgcGNoLCBjb3VudCk7CiAgICAgICAgICAgICAgICB3bS0+aW5mby5wY2hOZXh0ICs9IGNvdW50OwogICAgICAgICAgICAgICAgcGNoICs9IGNvdW50OwogICAgICAgICAgICAgICAgY2NoIC09IGNvdW50OwogICAgICAgICAgICAgICAgYnl0ZXNXICs9IGNvdW50OwogICAgICAgICAgICAgICAgd20tPmluZm8uZHdGbGFncyB8PSBNTUlPX0RJUlRZOwoJICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pIHsKICAgICAgICAgICAgICAgICAgICBpZiAod20tPmluZm8uYWR3SW5mb1swXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBmcm9tIHdoZXJlIHdvdWxkIHdlIGdldCB0aGUgbWVtb3J5IGhhbmRsZT8gKi8KICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIm1lbW9yeSBmaWxlIGV4cGFuc2lvbiBub3QgaW1wbGVtZW50ZWQhXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJICAgIH0gZWxzZSBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHdtLT5pbmZvLnBjaE5leHQgPT0gd20tPmluZm8ucGNoRW5kV3JpdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE1NSU9fRmx1c2god20sIE1NSU9fRU1QVFlCVUYpOwogICAgICAgICAgICAgICAgTU1JT19HcmFiTmV4dEJ1ZmZlcih3bSwgRkFMU0UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgYnJlYWs7CiAgICAgICAgfQoJY291bnQgPSBieXRlc1c7CiAgICB9IGVsc2UgewoJY291bnQgPSBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9XUklURSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSlwY2gsIGNjaCwgTU1JT19QUk9DXzMyQSk7Cgl3bS0+aW5mby5sQnVmT2Zmc2V0ID0gd20tPmluZm8ubERpc2tPZmZzZXQ7CiAgICB9CgogICAgVFJBQ0UoImJ5dGVzIHdyaXR0ZW49JWRcbiIsIGNvdW50KTsKICAgIHJldHVybiBjb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvU2VlawkJW1dJTk1NLkBdCiAqLwpMT05HIFdJTkFQSSBtbWlvU2VlayhITU1JTyBobW1pbywgTE9ORyBsT2Zmc2V0LCBJTlQgaU9yaWdpbikKewogICAgTFBXSU5FX01NSU8Jd207CiAgICBMT05HIAlvZmZzZXQ7CgogICAgVFJBQ0UoIiglcCwgJTA4WCwgJWQpO1xuIiwgaG1taW8sIGxPZmZzZXQsIGlPcmlnaW4pOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgLyogbm90IGJ1ZmZlcmVkLCBkaXJlY3Qgc2VlayBvbiBmaWxlICovCiAgICBpZiAoIXdtLT5pbmZvLnBjaEJ1ZmZlcikKCXJldHVybiBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9TRUVLLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxPZmZzZXQsIGlPcmlnaW4sIE1NSU9fUFJPQ18zMkEpOwoKICAgIHN3aXRjaCAoaU9yaWdpbikgewogICAgY2FzZSBTRUVLX1NFVDoKCW9mZnNldCA9IGxPZmZzZXQ7CglicmVhazsKICAgIGNhc2UgU0VFS19DVVI6CglvZmZzZXQgPSB3bS0+aW5mby5sQnVmT2Zmc2V0ICsgKHdtLT5pbmZvLnBjaE5leHQgLSB3bS0+aW5mby5wY2hCdWZmZXIpICsgbE9mZnNldDsKCWJyZWFrOwogICAgY2FzZSBTRUVLX0VORDoKCW9mZnNldCA9ICgod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pPyB3bS0+aW5mby5jY2hCdWZmZXIgOiB3bS0+ZHdGaWxlU2l6ZSkgLSBsT2Zmc2V0OwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJcmV0dXJuIC0xOwogICAgfQoKICAgIGlmIChvZmZzZXQgJiYgb2Zmc2V0ID49IHdtLT5kd0ZpbGVTaXplICYmIHdtLT5pbmZvLmZjY0lPUHJvYyAhPSBGT1VSQ0NfTUVNKSB7CiAgICAgICAgLyogc2hvdWxkIGNoZWNrIHRoYXQgd3JpdGUgbW9kZSBleGlzdHMgKi8KICAgICAgICBpZiAoTU1JT19GbHVzaCh3bSwgMCkgIT0gTU1TWVNFUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIHdtLT5pbmZvLmxCdWZPZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgd20tPmluZm8ucGNoRW5kUmVhZCA9IHdtLT5pbmZvLnBjaEJ1ZmZlcjsKICAgICAgICB3bS0+aW5mby5wY2hFbmRXcml0ZSA9IHdtLT5pbmZvLnBjaEJ1ZmZlciArIHdtLT5pbmZvLmNjaEJ1ZmZlcjsKICAgICAgICBpZiAoKHdtLT5pbmZvLmR3RmxhZ3MgJiBNTUlPX1JXTU9ERSkgPT0gTU1JT19SRUFEKSB7CiAgICAgICAgICAgIHdtLT5pbmZvLmxEaXNrT2Zmc2V0ID0gd20tPmR3RmlsZVNpemU7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICgod20tPmluZm8uY2NoQnVmZmVyID4gMCkgJiYKCSgob2Zmc2V0IDwgd20tPmluZm8ubEJ1Zk9mZnNldCkgfHwKCSAob2Zmc2V0ID49IHdtLT5pbmZvLmxCdWZPZmZzZXQgKyB3bS0+aW5mby5jY2hCdWZmZXIpIHx8CgkgIXdtLT5iQnVmZmVyTG9hZGVkKSkgewogICAgICAgIC8qIHN0YXkgaW4gc2FtZSBidWZmZXIgPyAqLwogICAgICAgIC8qIHNvbWUgbWVtb3J5IG1hcHBlZCBidWZmZXJzIGFyZSBkZWZpbmVkIHdpdGggLTEgYXMgYSBzaXplICovCgoJLyogY29uZGl0aW9uIHRvIGNoYW5nZSBidWZmZXIgKi8KCWlmICgod20tPmluZm8uZmNjSU9Qcm9jID09IEZPVVJDQ19NRU0pIHx8CgkgICAgTU1JT19GbHVzaCh3bSwgMCkgIT0gTU1TWVNFUlJfTk9FUlJPUiB8fAoJICAgIC8qIHRoaXMgYWxzbyBzZXRzIHRoZSB3bS0+aW5mby5sRGlza09mZnNldCBmaWVsZCAqLwoJICAgIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIE1NSU9NX1NFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAob2Zmc2V0IC8gd20tPmluZm8uY2NoQnVmZmVyKSAqIHdtLT5pbmZvLmNjaEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgIFNFRUtfU0VULCBNTUlPX1BST0NfMzJBKSA9PSAtMSkKCSAgICByZXR1cm4gLTE7CglNTUlPX0dyYWJOZXh0QnVmZmVyKHdtLCBUUlVFKTsKICAgIH0KCiAgICB3bS0+aW5mby5wY2hOZXh0ID0gd20tPmluZm8ucGNoQnVmZmVyICsgKG9mZnNldCAtIHdtLT5pbmZvLmxCdWZPZmZzZXQpOwoKICAgIFRSQUNFKCI9PiAlZFxuIiwgb2Zmc2V0KTsKICAgIHJldHVybiBvZmZzZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0dldEluZm8JICAgICAgIAlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvR2V0SW5mbyhITU1JTyBobW1pbywgTU1JT0lORk8qIGxwbW1pb2luZm8sIFVJTlQgdUZsYWdzKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwlcCwweCUwOHgpXG4iLGhtbWlvLGxwbW1pb2luZm8sdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIG1lbWNweShscG1taW9pbmZvLCAmd20tPmluZm8sIHNpemVvZihNTUlPSU5GTykpOwogICAgLyogZG9uJ3QgZXhwb3NlIDE2IGJpdCBpb3Byb2M6cyAqLwogICAgaWYgKHdtLT5pb1Byb2MtPnR5cGUgIT0gTU1JT19QUk9DXzE2KQogICAgICAgIGxwbW1pb2luZm8tPnBJT1Byb2MgPSB3bS0+aW9Qcm9jLT5wSU9Qcm9jOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TZXRJbmZvICAgIAkJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb1NldEluZm8oSE1NSU8gaG1taW8sIGNvbnN0IE1NSU9JTkZPKiBscG1taW9pbmZvLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCIoJXAsJXAsMHglMDh4KVxuIixobW1pbyxscG1taW9pbmZvLHVGbGFncyk7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICAvKiBjaGVjayBwb2ludGVycyBjb2hlcmVuY2UgKi8KICAgIGlmIChscG1taW9pbmZvLT5wY2hOZXh0IDwgd20tPmluZm8ucGNoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hOZXh0ID4gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRSZWFkIDwgd20tPmluZm8ucGNoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRSZWFkID4gd20tPmluZm8ucGNoQnVmZmVyICsgd20tPmluZm8uY2NoQnVmZmVyIHx8CglscG1taW9pbmZvLT5wY2hFbmRXcml0ZSA8IHdtLT5pbmZvLnBjaEJ1ZmZlciB8fAoJbHBtbWlvaW5mby0+cGNoRW5kV3JpdGUgPiB3bS0+aW5mby5wY2hCdWZmZXIgKyB3bS0+aW5mby5jY2hCdWZmZXIpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxQQVJBTTsKCiAgICB3bS0+aW5mby5wY2hOZXh0ID0gbHBtbWlvaW5mby0+cGNoTmV4dDsKICAgIHdtLT5pbmZvLnBjaEVuZFJlYWQgPSBscG1taW9pbmZvLT5wY2hFbmRSZWFkOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAJCQkJbW1pb1NldEJ1ZmZlcgkJW1dJTk1NLkBdCiovCk1NUkVTVUxUIFdJTkFQSSBtbWlvU2V0QnVmZmVyKEhNTUlPIGhtbWlvLCBMUFNUUiBwY2hCdWZmZXIsIExPTkcgY2NoQnVmZmVyLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCIoaG1taW89JXAsIHBjaEJ1Zj0lcCwgY2NoQnVmPSVkLCB1RmxhZ3M9JSMwOHgpXG4iLAoJICBobW1pbywgcGNoQnVmZmVyLCBjY2hCdWZmZXIsIHVGbGFncyk7CgogICAgaWYgKCh3bSA9IE1NSU9fR2V0KGhtbWlvKSkgPT0gTlVMTCkKCXJldHVybiBNTVNZU0VSUl9JTlZBTEhBTkRMRTsKCiAgICByZXR1cm4gTU1JT19TZXRCdWZmZXIod20sIHBjaEJ1ZmZlciwgY2NoQnVmZmVyLCB1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9GbHVzaCAgICAgIAkJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb0ZsdXNoKEhNTUlPIGhtbWlvLCBVSU5UIHVGbGFncykKewogICAgTFBXSU5FX01NSU8JCXdtOwoKICAgIFRSQUNFKCIoJXAsICUwNFgpXG4iLCBobW1pbywgdUZsYWdzKTsKCiAgICBpZiAoKHdtID0gTU1JT19HZXQoaG1taW8pKSA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMSEFORExFOwoKICAgIHJldHVybiBNTUlPX0ZsdXNoKHdtLCB1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9BZHZhbmNlICAgICAgCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9BZHZhbmNlKEhNTUlPIGhtbWlvLCBNTUlPSU5GTyogbHBtbWlvaW5mbywgVUlOVCB1RmxhZ3MpCnsKICAgIExQV0lORV9NTUlPCQl3bTsKCiAgICBUUkFDRSgiaG1taW89JXAsIGxwbW1pb2luZm89JXAsIHVGbGFncz0lMDRYXG4iLCBobW1pbywgbHBtbWlvaW5mbywgdUZsYWdzKTsKCiAgICAvKiBOT1RFOiBtbWlvQWR2YW5jZTE2IGhlYXZpbHkgcmVsaWVzIG9uIHBhcmFtZXRlcnMgZnJvbSBscG1taW9pbmZvIHdlJ3JlIHVzaW5nCiAgICAgKiBoZXJlLiBiZSBzdXJlIGlmIHlvdSBjaGFuZ2Ugc29tZXRoaW5nIGhlcmUgdG8gY2hlY2sgbW1pb0FkdmFuY2UxNiBhcyB3ZWxsCiAgICAgKi8KICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgaWYgKCF3bS0+aW5mby5jY2hCdWZmZXIpCglyZXR1cm4gTU1JT0VSUl9VTkJVRkZFUkVEOwoKICAgIGlmICh1RmxhZ3MgIT0gTU1JT19SRUFEICYmIHVGbGFncyAhPSBNTUlPX1dSSVRFKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMUEFSQU07CgogICAgaWYgKHVGbGFncyA9PSBNTUlPX1dSSVRFICYmIChscG1taW9pbmZvLT5kd0ZsYWdzICYgTU1JT19ESVJUWSkpCiAgICB7CiAgICAgICAgc2VuZF9tZXNzYWdlKHdtLT5pb1Byb2MsICZ3bS0+aW5mbywgTU1JT01fU0VFSywgCiAgICAgICAgICAgICAgICAgICAgIGxwbW1pb2luZm8tPmxCdWZPZmZzZXQsIFNFRUtfU0VULCBNTUlPX1BST0NfMzJBKTsKICAgICAgICBzZW5kX21lc3NhZ2Uod20tPmlvUHJvYywgJndtLT5pbmZvLCBNTUlPTV9XUklURSwgCiAgICAgICAgICAgICAgICAgICAgIChMUEFSQU0pbHBtbWlvaW5mby0+cGNoQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICBscG1taW9pbmZvLT5wY2hOZXh0IC0gbHBtbWlvaW5mby0+cGNoQnVmZmVyLCBNTUlPX1BST0NfMzJBKTsKICAgICAgICBscG1taW9pbmZvLT5kd0ZsYWdzICY9IH5NTUlPX0RJUlRZOwogICAgfQogICAgaWYgKE1NSU9fRmx1c2god20sIDApICE9IE1NU1lTRVJSX05PRVJST1IpCglyZXR1cm4gTU1JT0VSUl9DQU5OT1RXUklURTsKCiAgICBpZiAobHBtbWlvaW5mbykgewoJd20tPmR3RmlsZVNpemUgPSBtYXgod20tPmR3RmlsZVNpemUsIGxwbW1pb2luZm8tPmxCdWZPZmZzZXQgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobHBtbWlvaW5mby0+cGNoTmV4dCAtIGxwbW1pb2luZm8tPnBjaEJ1ZmZlcikpOwogICAgfQogICAgTU1JT19HcmFiTmV4dEJ1ZmZlcih3bSwgdUZsYWdzID09IE1NSU9fUkVBRCk7CgogICAgaWYgKGxwbW1pb2luZm8pIHsKCWxwbW1pb2luZm8tPnBjaE5leHQgPSBscG1taW9pbmZvLT5wY2hCdWZmZXI7CglscG1taW9pbmZvLT5wY2hFbmRSZWFkICA9IGxwbW1pb2luZm8tPnBjaEJ1ZmZlciArCgkgICAgKHdtLT5pbmZvLnBjaEVuZFJlYWQgLSB3bS0+aW5mby5wY2hCdWZmZXIpOwoJbHBtbWlvaW5mby0+cGNoRW5kV3JpdGUgPSBscG1taW9pbmZvLT5wY2hCdWZmZXIgKwoJICAgICh3bS0+aW5mby5wY2hFbmRXcml0ZSAtIHdtLT5pbmZvLnBjaEJ1ZmZlcik7CglscG1taW9pbmZvLT5sRGlza09mZnNldCA9IHdtLT5pbmZvLmxEaXNrT2Zmc2V0OwoJbHBtbWlvaW5mby0+bEJ1Zk9mZnNldCA9IHdtLT5pbmZvLmxCdWZPZmZzZXQ7CiAgICB9CiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvU3RyaW5nVG9GT1VSQ0NBCVtXSU5NTS5AXQogKi8KRk9VUkNDIFdJTkFQSSBtbWlvU3RyaW5nVG9GT1VSQ0NBKExQQ1NUUiBzeiwgVUlOVCB1RmxhZ3MpCnsKICAgIENIQVIgY2NbNF07CiAgICBpbnQgaSA9IDA7CgogICAgZm9yIChpID0gMDsgaSA8IDQgJiYgc3pbaV07IGkrKykgewoJaWYgKHVGbGFncyAmIE1NSU9fVE9VUFBFUikgewoJICAgIGNjW2ldID0gdG91cHBlcihzeltpXSk7Cgl9IGVsc2UgewoJICAgIGNjW2ldID0gc3pbaV07Cgl9CiAgICB9CgogICAgLyogUGFkIHdpdGggc3BhY2VzICovCiAgICB3aGlsZSAoaSA8IDQpIGNjW2krK10gPSAnICc7CgogICAgVFJBQ0UoIkdvdCAnJS40cydcbiIsY2MpOwogICAgcmV0dXJuIG1taW9GT1VSQ0MoY2NbMF0sY2NbMV0sY2NbMl0sY2NbM10pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9TdHJpbmdUb0ZPVVJDQ1cJW1dJTk1NLkBdCiAqLwpGT1VSQ0MgV0lOQVBJIG1taW9TdHJpbmdUb0ZPVVJDQ1coTFBDV1NUUiBzeiwgVUlOVCB1RmxhZ3MpCnsKICAgIGNoYXIJc3pBWzRdOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3osIDQsIHN6QSwgc2l6ZW9mKHN6QSksIE5VTEwsIE5VTEwgKTsKICAgIHJldHVybiBtbWlvU3RyaW5nVG9GT1VSQ0NBKHN6QSx1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9JbnN0YWxsSU9Qcm9jQQkgICBbV0lOTU0uQF0KICovCkxQTU1JT1BST0MgV0lOQVBJIG1taW9JbnN0YWxsSU9Qcm9jQShGT1VSQ0MgZmNjSU9Qcm9jLAoJCQkJICAgICBMUE1NSU9QUk9DIHBJT1Byb2MsIERXT1JEIGR3RmxhZ3MpCnsKICAgIHJldHVybiBNTUlPX0luc3RhbGxJT1Byb2MoZmNjSU9Qcm9jLCBwSU9Qcm9jLCBkd0ZsYWdzLCBNTUlPX1BST0NfMzJBKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvSW5zdGFsbElPUHJvY1cJICAgW1dJTk1NLkBdCiAqLwpMUE1NSU9QUk9DIFdJTkFQSSBtbWlvSW5zdGFsbElPUHJvY1coRk9VUkNDIGZjY0lPUHJvYywKCQkJCSAgICAgTFBNTUlPUFJPQyBwSU9Qcm9jLCBEV09SRCBkd0ZsYWdzKQp7CiAgICByZXR1cm4gTU1JT19JbnN0YWxsSU9Qcm9jKGZjY0lPUHJvYywgcElPUHJvYywgZHdGbGFncywgTU1JT19QUk9DXzMyVyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1NSU9fU2VuZE1lc3NhZ2UKICoKICoKICovCkxSRVNVTFQgICAgICAgICBNTUlPX1NlbmRNZXNzYWdlKEhNTUlPIGhtbWlvLCBVSU5UIHVNZXNzYWdlLCBMUEFSQU0gbFBhcmFtMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQVJBTSBsUGFyYW0yLCBlbnVtIG1taW9Qcm9jVHlwZSB0eXBlKQp7CiAgICBMUFdJTkVfTU1JTwkJd207CgogICAgVFJBQ0UoIiglcCwgJXUsICVsZCwgJWxkLCAlZClcbiIsIGhtbWlvLCB1TWVzc2FnZSwgbFBhcmFtMSwgbFBhcmFtMiwgdHlwZSk7CgogICAgaWYgKHVNZXNzYWdlIDwgTU1JT01fVVNFUikKCXJldHVybiBNTVNZU0VSUl9JTlZBTFBBUkFNOwoKICAgIGlmICgod20gPSBNTUlPX0dldChobW1pbykpID09IE5VTEwpCglyZXR1cm4gTU1TWVNFUlJfSU5WQUxIQU5ETEU7CgogICAgcmV0dXJuIHNlbmRfbWVzc2FnZSh3bS0+aW9Qcm9jLCAmd20tPmluZm8sIHVNZXNzYWdlLCBsUGFyYW0xLCBsUGFyYW0yLCB0eXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvU2VuZE1lc3NhZ2UJCVtXSU5NTS5AXQogKi8KTFJFU1VMVCBXSU5BUEkgbW1pb1NlbmRNZXNzYWdlKEhNTUlPIGhtbWlvLCBVSU5UIHVNZXNzYWdlLAoJCQkgICAgICAgTFBBUkFNIGxQYXJhbTEsIExQQVJBTSBsUGFyYW0yKQp7CiAgICByZXR1cm4gTU1JT19TZW5kTWVzc2FnZShobW1pbywgdU1lc3NhZ2UsIGxQYXJhbTEsIGxQYXJhbTIsIE1NSU9fUFJPQ18zMkEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCW1taW9EZXNjZW5kICAgICAgICAgCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9EZXNjZW5kKEhNTUlPIGhtbWlvLCBMUE1NQ0tJTkZPIGxwY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNTUNLSU5GTyogbHBja1BhcmVudCwgVUlOVCB1RmxhZ3MpCnsKICAgIERXT1JECQlkd09sZFBvczsKICAgIEZPVVJDQwkJc3JjaENrSWQ7CiAgICBGT1VSQ0MJCXNyY2hUeXBlOwoKICAgIFRSQUNFKCIoJXAsICVwLCAlcCwgJTA0WCk7XG4iLCBobW1pbywgbHBjaywgbHBja1BhcmVudCwgdUZsYWdzKTsKCiAgICBpZiAobHBjayA9PSBOVUxMKQoJcmV0dXJuIE1NU1lTRVJSX0lOVkFMUEFSQU07CgogICAgZHdPbGRQb3MgPSBtbWlvU2VlayhobW1pbywgMCwgU0VFS19DVVIpOwogICAgVFJBQ0UoImR3T2xkUG9zPSVkXG4iLCBkd09sZFBvcyk7CgogICAgaWYgKGxwY2tQYXJlbnQgIT0gTlVMTCkgewoJVFJBQ0UoInNlZWsgaW5zaWRlIHBhcmVudCBhdCAlZCAhXG4iLCBscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQpOwoJLyogRVBQOiB3YXMgZHdPbGRQb3MgPSBtbWlvU2VlayhobW1pbyxscGNrUGFyZW50LT5kd0RhdGFPZmZzZXQsU0VFS19TRVQpOyAqLwoJaWYgKGR3T2xkUG9zIDwgbHBja1BhcmVudC0+ZHdEYXRhT2Zmc2V0IHx8CgkgICAgZHdPbGRQb3MgPj0gbHBja1BhcmVudC0+ZHdEYXRhT2Zmc2V0ICsgbHBja1BhcmVudC0+Y2tzaXplKSB7CgkgICAgV0FSTigib3V0c2lkZSBwYXJlbnQgY2h1bmtcbiIpOwoJICAgIHJldHVybiBNTUlPRVJSX0NIVU5LTk9URk9VTkQ7Cgl9CiAgICB9CgogICAgLyogVGhlIFNESyBkb2N1IHNheXMgJ2NraWQnIGlzIHVzZWQgZm9yIGFsbCBjYXNlcy4gUmVhbCBXb3JsZAogICAgICogZXhhbXBsZXMgZGlzYWdyZWUgLU1hcmN1cyw5OTAyMTYuCiAgICAgKi8KCiAgICBzcmNoQ2tJZCA9IDA7CiAgICBzcmNoVHlwZSA9IDA7CgogICAgLyogZmluZF9jaHVuayBsb29rcyBmb3IgJ2NraWQnICovCiAgICBpZiAodUZsYWdzICYgTU1JT19GSU5EQ0hVTkspCglzcmNoQ2tJZCA9IGxwY2stPmNraWQ7CgogICAgLyogZmluZF9yaWZmIGFuZCBmaW5kX2xpc3QgbG9vayBmb3IgJ2ZjY1R5cGUnICovCiAgICBpZiAodUZsYWdzICYgTU1JT19GSU5ETElTVCkKICAgIHsKCXNyY2hDa0lkID0gRk9VUkNDX0xJU1Q7CiAgICAgICAgc3JjaFR5cGUgPSBscGNrLT5mY2NUeXBlOwogICAgfQoKICAgIGlmICh1RmxhZ3MgJiBNTUlPX0ZJTkRSSUZGKQogICAgewoJc3JjaENrSWQgPSBGT1VSQ0NfUklGRjsKICAgICAgICBzcmNoVHlwZSA9IGxwY2stPmZjY1R5cGU7CiAgICB9CgogICAgVFJBQ0UoInNlYXJjaGluZyBmb3IgJTQuNHMuJTQuNHNcbiIsCiAgICAgICAgICAoTFBDU1RSKSZzcmNoQ2tJZCwgc3JjaFR5cGUgPyAoTFBDU1RSKSZzcmNoVHlwZSA6ICJhbnkiKTsKCiAgICB3aGlsZSAoVFJVRSkKICAgIHsKICAgICAgICBMT05HIGl4OwoKICAgICAgICBpeCA9IG1taW9SZWFkKGhtbWlvLCAoTFBTVFIpbHBjaywgMyAqIHNpemVvZihEV09SRCkpOwogICAgICAgIGlmIChpeCA8IDIqc2l6ZW9mKERXT1JEKSkKICAgICAgICB7CiAgICAgICAgICAgIG1taW9TZWVrKGhtbWlvLCBkd09sZFBvcywgU0VFS19TRVQpOwogICAgICAgICAgICBXQVJOKCJyZXR1cm4gQ2h1bmtOb3RGb3VuZFxuIik7CiAgICAgICAgICAgIHJldHVybiBNTUlPRVJSX0NIVU5LTk9URk9VTkQ7CiAgICAgICAgfQoKICAgICAgICBscGNrLT5kd0RhdGFPZmZzZXQgPSBkd09sZFBvcyArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgICAgIFRSQUNFKCJja2lkPSU0LjRzIGZjYz0lNC40cyBja3NpemU9JTA4WCAhXG4iLAogICAgICAgICAgICAgIChMUENTVFIpJmxwY2stPmNraWQsCiAgICAgICAgICAgICAgc3JjaFR5cGUgPyAoTFBDU1RSKSZscGNrLT5mY2NUeXBlOiI8bmE+IiwKICAgICAgICAgICAgICBscGNrLT5ja3NpemUpOwogICAgICAgIGlmICggKCFzcmNoQ2tJZCB8fCAoc3JjaENrSWQgPT0gbHBjay0+Y2tpZCkpICYmCiAgICAgICAgICAgICAoIXNyY2hUeXBlIHx8IChzcmNoVHlwZSA9PSBscGNrLT5mY2NUeXBlKSkgKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZHdPbGRQb3MgPSBscGNrLT5kd0RhdGFPZmZzZXQgKyAoKGxwY2stPmNrc2l6ZSArIDEpICYgfjEpOwogICAgICAgIG1taW9TZWVrKGhtbWlvLCBkd09sZFBvcywgU0VFS19TRVQpOwogICAgfQoKICAgIGxwY2stPmR3RmxhZ3MgPSAwOwogICAgLyogSWYgd2Ugd2VyZSBsb29raW5nIGZvciBSSUZGL0xJU1QgY2h1bmtzLCB0aGUgZmluYWwgZmlsZSBwb3NpdGlvbgogICAgICogaXMgYWZ0ZXIgdGhlIGNodW5raWQuIElmIHdlIHdlcmUganVzdCBsb29raW5nIGZvciB0aGUgY2h1bmsKICAgICAqIGl0IGlzIGFmdGVyIHRoZSBja3NpemUuIFNvIGFkZCA0IGluIFJJRkYvTElTVCBjYXNlLgogICAgICovCiAgICBpZiAobHBjay0+Y2tpZCA9PSBGT1VSQ0NfUklGRiB8fCBscGNrLT5ja2lkID09IEZPVVJDQ19MSVNUKQoJbW1pb1NlZWsoaG1taW8sIGxwY2stPmR3RGF0YU9mZnNldCArIHNpemVvZihEV09SRCksIFNFRUtfU0VUKTsKICAgIGVsc2UKCW1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQsIFNFRUtfU0VUKTsKICAgIFRSQUNFKCJscGNrOiBja2lkPSUuNHMsIGNrc2l6ZT0lZCwgZHdEYXRhT2Zmc2V0PSVkIGZjY1R5cGU9JTA4WCAoJS40cykhXG4iLAoJICAoTFBTVFIpJmxwY2stPmNraWQsIGxwY2stPmNrc2l6ZSwgbHBjay0+ZHdEYXRhT2Zmc2V0LAoJICBscGNrLT5mY2NUeXBlLCBzcmNoVHlwZT8oTFBTVFIpJmxwY2stPmZjY1R5cGU6IiIpOwogICAgcmV0dXJuIE1NU1lTRVJSX05PRVJST1I7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb0FzY2VuZCAgICAgCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvQXNjZW5kKEhNTUlPIGhtbWlvLCBMUE1NQ0tJTkZPIGxwY2ssIFVJTlQgdUZsYWdzKQp7CiAgICBUUkFDRSgiKCVwLCAlcCwgJTA0WCk7XG4iLCBobW1pbywgbHBjaywgdUZsYWdzKTsKCiAgICBpZiAobHBjay0+ZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKCURXT1JECWR3T2xkUG9zLCBkd05ld1NpemU7CgoJVFJBQ0UoIkNodW5rIGlzIGRpcnR5LCBjaGVja2luZyBpZiBjaHVuaydzIHNpemUgaXMgY29ycmVjdFxuIik7Cglkd09sZFBvcyA9IG1taW9TZWVrKGhtbWlvLCAwLCBTRUVLX0NVUik7CglUUkFDRSgiZHdPbGRQb3M9JWQgbHBjay0+ZHdEYXRhT2Zmc2V0ID0gJWRcbiIsIGR3T2xkUG9zLCBscGNrLT5kd0RhdGFPZmZzZXQpOwoJZHdOZXdTaXplID0gZHdPbGRQb3MgLSBscGNrLT5kd0RhdGFPZmZzZXQ7CglpZiAoZHdOZXdTaXplICE9IGxwY2stPmNrc2l6ZSkgewoJICAgIFRSQUNFKCJOb3BlOiBscGNrLT5ja3NpemU9JWQgZHdOZXdTaXplPSVkXG4iLCBscGNrLT5ja3NpemUsIGR3TmV3U2l6ZSk7CgkgICAgbHBjay0+Y2tzaXplID0gZHdOZXdTaXplOwoKCSAgICAvKiBwYWQgb2RkIHNpemUgd2l0aCAwICovCgkgICAgaWYgKGR3TmV3U2l6ZSAmIDEpIHsKCQljaGFyIGNoID0gMDsKCQltbWlvV3JpdGUoaG1taW8sICZjaCwgMSk7CgkgICAgfQoJICAgIG1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQgLSBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCk7CgkgICAgbW1pb1dyaXRlKGhtbWlvLCAoTFBTVFIpJmR3TmV3U2l6ZSwgc2l6ZW9mKERXT1JEKSk7Cgl9CglscGNrLT5kd0ZsYWdzID0gMDsKICAgIH0KCiAgICBtbWlvU2VlayhobW1pbywgbHBjay0+ZHdEYXRhT2Zmc2V0ICsgKChscGNrLT5ja3NpemUgKyAxKSAmIH4xKSwgU0VFS19TRVQpOwoKICAgIHJldHVybiBNTVNZU0VSUl9OT0VSUk9SOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJbW1pb0NyZWF0ZUNodW5rCQkJCVtXSU5NTS5AXQogKi8KTU1SRVNVTFQgV0lOQVBJIG1taW9DcmVhdGVDaHVuayhITU1JTyBobW1pbywgTU1DS0lORk8qIGxwY2ssIFVJTlQgdUZsYWdzKQp7CiAgICBEV09SRAlkd09sZFBvczsKICAgIExPTkcgCXNpemU7CiAgICBMT05HIAlpeDsKCiAgICBUUkFDRSgiKCVwLCAlcCwgJTA0WCk7XG4iLCBobW1pbywgbHBjaywgdUZsYWdzKTsKCiAgICBkd09sZFBvcyA9IG1taW9TZWVrKGhtbWlvLCAwLCBTRUVLX0NVUik7CiAgICBUUkFDRSgiZHdPbGRQb3M9JWRcbiIsIGR3T2xkUG9zKTsKCiAgICBpZiAodUZsYWdzID09IE1NSU9fQ1JFQVRFTElTVCkKCWxwY2stPmNraWQgPSBGT1VSQ0NfTElTVDsKICAgIGVsc2UgaWYgKHVGbGFncyA9PSBNTUlPX0NSRUFURVJJRkYpCglscGNrLT5ja2lkID0gRk9VUkNDX1JJRkY7CgogICAgVFJBQ0UoImNraWQ9JS40c1xuIiwgKExQU1RSKSZscGNrLT5ja2lkKTsKCiAgICBzaXplID0gMiAqIHNpemVvZihEV09SRCk7CiAgICBscGNrLT5kd0RhdGFPZmZzZXQgPSBkd09sZFBvcyArIHNpemU7CgogICAgaWYgKGxwY2stPmNraWQgPT0gRk9VUkNDX1JJRkYgfHwgbHBjay0+Y2tpZCA9PSBGT1VSQ0NfTElTVCkKCXNpemUgKz0gc2l6ZW9mKERXT1JEKTsKICAgIGxwY2stPmR3RmxhZ3MgPSBNTUlPX0RJUlRZOwoKICAgIGl4ID0gbW1pb1dyaXRlKGhtbWlvLCAoTFBTVFIpbHBjaywgc2l6ZSk7CiAgICBUUkFDRSgiYWZ0ZXIgbW1pb1dyaXRlIGl4ID0gJWQgcmVxID0gJWQsIGVycm5vID0gJWRcbiIsIGl4LCBzaXplLCBlcnJubyk7CiAgICBpZiAoaXggPCBzaXplKSB7CgltbWlvU2VlayhobW1pbywgZHdPbGRQb3MsIFNFRUtfU0VUKTsKCVdBUk4oInJldHVybiBDYW5ub3RXcml0ZVxuIik7CglyZXR1cm4gTU1JT0VSUl9DQU5OT1RXUklURTsKICAgIH0KCiAgICByZXR1cm4gTU1TWVNFUlJfTk9FUlJPUjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQltbWlvUmVuYW1lQSAgICAJCQlbV0lOTU0uQF0KICovCk1NUkVTVUxUIFdJTkFQSSBtbWlvUmVuYW1lQShMUENTVFIgc3pGaWxlTmFtZSwgTFBDU1RSIHN6TmV3RmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNTUlPSU5GTyogbHBtbWlvaW5mbywgRFdPUkQgZHdGbGFncykKewogICAgc3RydWN0IElPUHJvY0xpc3QqICBpb1Byb2MgPSBOVUxMOwogICAgc3RydWN0IElPUHJvY0xpc3QgICB0bXA7CiAgICBGT1VSQ0MgICAgICAgICAgICAgIGZjYzsKCiAgICBUUkFDRSgiKCclcycsICclcycsICVwLCAlMDhYKTtcbiIsCgkgIGRlYnVnc3RyX2Eoc3pGaWxlTmFtZSksIGRlYnVnc3RyX2Eoc3pOZXdGaWxlTmFtZSksIGxwbW1pb2luZm8sIGR3RmxhZ3MpOwoKICAgIC8qIElmIGJvdGggcGFyYW1zIGFyZSBOVUxMLCB0aGVuIHBhcnNlIHRoZSBmaWxlIG5hbWUgKi8KICAgIGlmIChscG1taW9pbmZvICYmIGxwbW1pb2luZm8tPmZjY0lPUHJvYyA9PSAwICYmIGxwbW1pb2luZm8tPnBJT1Byb2MgPT0gTlVMTCkKICAgIHsKCWZjYyA9IE1NSU9fUGFyc2VFeHRBKHN6RmlsZU5hbWUpOwogICAgICAgIGlmIChmY2MpIGlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKGZjYyk7CiAgICB9CgogICAgLyogSGFuZGxlIGFueSB1bmhhbmRsZWQvZXJyb3IgY2FzZSBmcm9tIGFib3ZlLiBBc3N1bWUgRE9TIGZpbGUgKi8KICAgIGlmICghbHBtbWlvaW5mbyB8fCAobHBtbWlvaW5mby0+ZmNjSU9Qcm9jID09IDAgJiYgbHBtbWlvaW5mby0+cElPUHJvYyA9PSBOVUxMICYmIGlvUHJvYyA9PSBOVUxMKSkKCWlvUHJvYyA9IE1NSU9fRmluZFByb2NOb2RlKEZPVVJDQ19ET1MpOwogICAgLyogaWYganVzdCB0aGUgZm91ciBjaGFyYWN0ZXIgY29kZSBpcyBwcmVzZW50LCBsb29rIHVwIElPIHByb2MgKi8KICAgIGVsc2UgaWYgKGxwbW1pb2luZm8tPnBJT1Byb2MgPT0gTlVMTCkKICAgICAgICBpb1Byb2MgPSBNTUlPX0ZpbmRQcm9jTm9kZShscG1taW9pbmZvLT5mY2NJT1Byb2MpOwogICAgZWxzZSAvKiB1c2UgcmVsZXZhbnQgaW9Qcm9jICovCiAgICB7CiAgICAgICAgaW9Qcm9jID0gJnRtcDsKICAgICAgICB0bXAuZm91ckNDID0gbHBtbWlvaW5mby0+ZmNjSU9Qcm9jOwogICAgICAgIHRtcC5wSU9Qcm9jID0gbHBtbWlvaW5mby0+cElPUHJvYzsKICAgICAgICB0bXAudHlwZSA9IE1NSU9fUFJPQ18zMkE7CiAgICAgICAgdG1wLmNvdW50ID0gMTsKICAgIH0KCiAgICAvKiBGSVhNRTogc2hvdWxkIHdlIGFjdHVhbGx5IHBhc3MgbHBtbWlvaW5mbyBkb3duIHRoZSBkcmFpbiA/Pz8KICAgICAqIG9yIG1ha2UgYSBjb3B5IG9mIGl0IGJlY2F1c2UgaXQncyBjb25zdCA/Pz8KICAgICAqLwogICAgcmV0dXJuIHNlbmRfbWVzc2FnZShpb1Byb2MsIChNTUlPSU5GTyopbHBtbWlvaW5mbywgTU1JT01fUkVOQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKXN6RmlsZU5hbWUsIChMUEFSQU0pc3pOZXdGaWxlTmFtZSwgTU1JT19QUk9DXzMyQSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJbW1pb1JlbmFtZVcgICAgCQkJW1dJTk1NLkBdCiAqLwpNTVJFU1VMVCBXSU5BUEkgbW1pb1JlbmFtZVcoTFBDV1NUUiBzekZpbGVOYW1lLCBMUENXU1RSIHN6TmV3RmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNTUlPSU5GTyogbHBtbWlvaW5mbywgRFdPUkQgZHdGbGFncykKewogICAgTFBTVFIJc3pGbiA9IE5VTEw7CiAgICBMUFNUUglzem5GbiA9IE5VTEw7CiAgICBVSU5UCXJldCA9IE1NU1lTRVJSX05PTUVNOwogICAgSU5UICAgICAgICAgbGVuOwoKICAgIGlmIChzekZpbGVOYW1lKQogICAgewogICAgICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pGaWxlTmFtZSwgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwgKTsKICAgICAgICBzekZuID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKTsKICAgICAgICBpZiAoIXN6Rm4pIGdvdG8gZG9uZTsKICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKCBDUF9BQ1AsIDAsIHN6RmlsZU5hbWUsIC0xLCBzekZuLCBsZW4sIE5VTEwsIE5VTEwgKTsKICAgIH0KICAgIGlmIChzek5ld0ZpbGVOYW1lKQogICAgewogICAgICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pOZXdGaWxlTmFtZSwgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwgKTsKICAgICAgICBzem5GbiA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICk7CiAgICAgICAgaWYgKCFzem5GbikgZ290byBkb25lOwogICAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoIENQX0FDUCwgMCwgc3pOZXdGaWxlTmFtZSwgLTEsIHN6bkZuLCBsZW4sIE5VTEwsIE5VTEwgKTsKICAgIH0KCiAgICByZXQgPSBtbWlvUmVuYW1lQShzekZuLCBzem5GbiwgbHBtbWlvaW5mbywgZHdGbGFncyk7Cgpkb25lOgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLHN6Rm4pOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLHN6bkZuKTsKICAgIHJldHVybiByZXQ7Cn0K