Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGcmVlSW1hZ2VQbHVzIDMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmbmRlZiBGUkVFSU1BR0VQTFVTX0gKI2RlZmluZSBGUkVFSU1BR0VQTFVTX0gKCiNpZmRlZiBfV0lOMzIKI2luY2x1ZGUgPHdpbmRvd3MuaD4KI2VuZGlmIC8vIF9XSU4zMgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCgoKLy8gQ29tcGlsZXIgb3B0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNpZiBkZWZpbmVkKEZSRUVJTUFHRV9MSUIpCgkjZGVmaW5lIEZJUF9BUEkKCSNkZWZpbmUgRklQX0NBTExDT05WCiNlbHNlCgkjaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX19XSU4zMl9fKQoJCSNkZWZpbmUgV0lOMzJfTEVBTl9BTkRfTUVBTgoJCSNkZWZpbmUgRklQX0NBTExDT05WIF9fc3RkY2FsbAoJCS8vIFRoZSBmb2xsb3dpbmcgaWZkZWYgYmxvY2sgaXMgdGhlIHN0YW5kYXJkIHdheSBvZiBjcmVhdGluZyBtYWNyb3Mgd2hpY2ggbWFrZSBleHBvcnRpbmcgCgkJLy8gZnJvbSBhIERMTCBzaW1wbGVyLiBBbGwgZmlsZXMgd2l0aGluIHRoaXMgRExMIGFyZSBjb21waWxlZCB3aXRoIHRoZSBGSVBfRVhQT1JUUwoJCS8vIHN5bWJvbCBkZWZpbmVkIG9uIHRoZSBjb21tYW5kIGxpbmUuIHRoaXMgc3ltYm9sIHNob3VsZCBub3QgYmUgZGVmaW5lZCBvbiBhbnkgcHJvamVjdAoJCS8vIHRoYXQgdXNlcyB0aGlzIERMTC4gVGhpcyB3YXkgYW55IG90aGVyIHByb2plY3Qgd2hvc2Ugc291cmNlIGZpbGVzIGluY2x1ZGUgdGhpcyBmaWxlIHNlZSAKCQkvLyBGSVBfQVBJIGZ1bmN0aW9ucyBhcyBiZWluZyBpbXBvcnRlZCBmcm9tIGEgRExMLCB3aGVyYXMgdGhpcyBETEwgc2VlcyBzeW1ib2xzCgkJLy8gZGVmaW5lZCB3aXRoIHRoaXMgbWFjcm8gYXMgYmVpbmcgZXhwb3J0ZWQuCgkJI2lmZGVmIEZJUF9FWFBPUlRTCgkJCSNkZWZpbmUgRklQX0FQSSBfX2RlY2xzcGVjKGRsbGV4cG9ydCkKCQkjZWxzZQoJCQkjZGVmaW5lIEZJUF9BUEkgX19kZWNsc3BlYyhkbGxpbXBvcnQpCgkJI2VuZGlmIC8vIEZJUF9FWFBPUlRTCgkjZWxzZQoJCS8vIHRyeSB0aGUgZ2NjIHZpc2liaWxpdHkgc3VwcG9ydCAoc2VlIGh0dHA6Ly9nY2MuZ251Lm9yZy93aWtpL1Zpc2liaWxpdHkpCgkJI2lmIGRlZmluZWQoX19HTlVDX18pICYmICgoX19HTlVDX18gPj0gNCkgfHwgKF9fR05VQ19fID09IDMgJiYgX19HTlVDX01JTk9SX18gPj0gNCkpCgkJCSNpZm5kZWYgR0NDX0hBU0NMQVNTVklTSUJJTElUWQoJCQkJI2RlZmluZSBHQ0NfSEFTQ0xBU1NWSVNJQklMSVRZCgkJCSNlbmRpZgoJCSNlbmRpZgkKCQkjZGVmaW5lIEZJUF9DQUxMQ09OVgoJCSNpZiBkZWZpbmVkKEdDQ19IQVNDTEFTU1ZJU0lCSUxJVFkpCgkJCSNkZWZpbmUgRklQX0FQSSBfX2F0dHJpYnV0ZV9fICgodmlzaWJpbGl0eSgiZGVmYXVsdCIpKSkKCQkjZWxzZQoJCQkjZGVmaW5lIEZJUF9BUEkKCQkjZW5kaWYKCSNlbmRpZiAvLyBXSU4zMiAvICFXSU4zMgojZW5kaWYgLy8gRlJFRUlNQUdFX0xJQgoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGFsbCBvYmplY3RzIHVzZWQgYnkgdGhlIGxpYnJhcnkuCglAdmVyc2lvbiBGcmVlSW1hZ2UgMwoJQGF1dGhvciBIZXJ26SBEcm9sb24KKi8KCmNsYXNzIEZJUF9BUEkgZmlwT2JqZWN0CnsKcHVibGljOgoJLy8vIERlc3RydWN0b3IKCXZpcnR1YWwgfmZpcE9iamVjdCgpe307CgkKCS8qKkBuYW1lIEluZm9ybWF0aW9uIGZ1bmN0aW9ucyAqLwoJLy9AewoJLy8vIFJldHVybnMgVFJVRSBpZiB0aGUgb2JqZWN0IGlzIGFsbG9jYXRlZCwgRkFMU0Ugb3RoZXJ3aXNlCgl2aXJ0dWFsIEJPT0wgaXNWYWxpZCgpIGNvbnN0ID0gMDsKCS8vQH0KfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIGZpcE1lbW9yeUlPOwpjbGFzcyBmaXBNdWx0aVBhZ2U7CmNsYXNzIGZpcFRhZzsKCi8qKiBBIGNsYXNzIHVzZWQgdG8gbWFuYWdlIGFsbCBwaG90byByZWxhdGVkIGltYWdlcyBhbmQgYWxsIGltYWdlIHR5cGVzIHVzZWQgYnkgdGhlIGxpYnJhcnkuCgoJZmlwSW1hZ2UgZW5jYXBzdWxhdGVzIHRoZSBGSUJJVE1BUCBmb3JtYXQuIEl0IHJlbGllcyBvbiB0aGUgRnJlZUltYWdlIGxpYnJhcnksIGVzcGVjaWFsbHkgZm9yIAoJbG9hZGluZyAvIHNhdmluZyBpbWFnZXMgYW5kIGZvciBiaXQgZGVwdGggY29udmVyc2lvbi4KCUB2ZXJzaW9uIEZyZWVJbWFnZSAzCglAYXV0aG9yIEhlcnbpIERyb2xvbgoqLwoKY2xhc3MgRklQX0FQSSBmaXBJbWFnZSA6IHB1YmxpYyBmaXBPYmplY3QKewpwcm90ZWN0ZWQ6CgkvLy8gRElCIGRhdGEKCUZJQklUTUFQICpfZGliOwoJLy8vIE9yaWdpbmFsIChvciBsYXN0IHNhdmVkKSBmaWYgZm9ybWF0IGlmIGF2YWlsYWJsZSwgRklGX1VOS05PV04gb3RoZXJ3aXNlCglGUkVFX0lNQUdFX0ZPUk1BVCBfZmlmOwoJLy8vIFRSVUUgd2hlbmV2ZXIgdGhlIGRpc3BsYXkgbmVlZCB0byBiZSByZWZyZXNoZWQKCW11dGFibGUgQk9PTCBfYkhhc0NoYW5nZWQ7CgpwdWJsaWM6CglmcmllbmQgY2xhc3MgZmlwTXVsdGlQYWdlOwoKcHVibGljOgoKCS8qKkBuYW1lIENyZWF0aW9uICYgRGVzdHJ1Y3Rpb24gKi8KCS8vQHsJCgkvKioKCUNvbnN0cnVjdG9yCglAc2VlIEZyZWVJbWFnZV9BbGxvY2F0ZVQKCSovCglmaXBJbWFnZShGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZJVF9CSVRNQVAsIHVuc2lnbmVkIHdpZHRoID0gMCwgdW5zaWduZWQgaGVpZ2h0ID0gMCwgdW5zaWduZWQgYnBwID0gMCk7CgkvLy8gRGVzdHJ1Y3RvcgoJdmlydHVhbCB+ZmlwSW1hZ2UoKTsKCS8qKgoJSW1hZ2UgYWxsb2NhdG9yCglAc2VlIEZyZWVJbWFnZV9BbGxvY2F0ZVQKCSovCglCT09MIHNldFNpemUoRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUsIHVuc2lnbmVkIHdpZHRoLCB1bnNpZ25lZCBoZWlnaHQsIHVuc2lnbmVkIGJwcCwgdW5zaWduZWQgcmVkX21hc2sgPSAwLCB1bnNpZ25lZCBncmVlbl9tYXNrID0gMCwgdW5zaWduZWQgYmx1ZV9tYXNrID0gMCk7CgkvLy8gRGVzdHJveSBpbWFnZSBkYXRhCgl2aXJ0dWFsIHZvaWQgY2xlYXIoKTsKCS8vQH0KCgkvKipAbmFtZSBDb3B5aW5nICovCgkvL0B7CQoJLyoqCglDb3B5IGNvbnN0cnVjdG9yCglAc2VlIEZyZWVJbWFnZV9DbG9uZQoJKi8KCWZpcEltYWdlKGNvbnN0IGZpcEltYWdlJiBzcmMpOwoJLyoqCglDb3B5IGNvbnN0cnVjdG9yCglAc2VlIEZyZWVJbWFnZV9DbG9uZQoJKi8KCWZpcEltYWdlJiBvcGVyYXRvcj0oY29uc3QgZmlwSW1hZ2UmIHNyYyk7CgkvKioKCTxiPkFzc2lnbmVtZW50IG9wZXJhdG9yPC9iPjxicj4KCUNvcHkgdGhlIGlucHV0IHBvaW50ZXIgYW5kIG1hbmFnZSBpdHMgZGVzdHJ1Y3Rpb24KCUBzZWUgb3BlcmF0b3IgRklCSVRNQVAqKCkKCSovCglmaXBJbWFnZSYgb3BlcmF0b3I9KEZJQklUTUFQICpkaWIpOwoKCgkvKioKCUBicmllZiBDb3B5IGEgc3ViIHBhcnQgb2YgdGhlIGN1cnJlbnQgaW1hZ2UgYW5kIHJldHVybnMgaXQgYXMgYSBmaXBJbWFnZSBvYmplY3QuCgkKCVRoaXMgbWV0aG9kIHdvcmtzIHdpdGggYW55IGJpdG1hcCB0eXBlLgoJQHBhcmFtIGRzdCBPdXRwdXQgc3ViaW1hZ2UKCUBwYXJhbSBsZWZ0IFNwZWNpZmllcyB0aGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgY3JvcHBlZCByZWN0YW5nbGUuIAoJQHBhcmFtIHRvcCBTcGVjaWZpZXMgdGhlIHRvcCBwb3NpdGlvbiBvZiB0aGUgY3JvcHBlZCByZWN0YW5nbGUuIAoJQHBhcmFtIHJpZ2h0IFNwZWNpZmllcyB0aGUgcmlnaHQgcG9zaXRpb24gb2YgdGhlIGNyb3BwZWQgcmVjdGFuZ2xlLiAKCUBwYXJhbSBib3R0b20gU3BlY2lmaWVzIHRoZSBib3R0b20gcG9zaXRpb24gb2YgdGhlIGNyb3BwZWQgcmVjdGFuZ2xlLiAKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0NvcHkKCSovCglCT09MIGNvcHlTdWJJbWFnZShmaXBJbWFnZSYgZHN0LCBpbnQgbGVmdCwgaW50IHRvcCwgaW50IHJpZ2h0LCBpbnQgYm90dG9tKSBjb25zdDsKCgkvKioKCUBicmllZiBBbHBoYSBibGVuZCBvciBjb21iaW5lIGEgc3ViIHBhcnQgaW1hZ2Ugd2l0aCB0aGUgY3VycmVudCBpbWFnZS4KCiAgICBUaGUgYml0IGRlcHRoIG9mIGRzdCBiaXRtYXAgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGJpdCBkZXB0aCBvZiBzcmMuIAoJVXBwZXIgcHJvbW90aW9uIG9mIHNyYyBpcyBkb25lIGludGVybmFsbHkuIFN1cHBvcnRlZCBiaXQgZGVwdGggZXF1YWxzIHRvIDQsIDgsIDE2LCAyNCBvciAzMi4KCUBwYXJhbSBzcmMgU291cmNlIHN1YmltYWdlCglAcGFyYW0gbGVmdCBTcGVjaWZpZXMgdGhlIGxlZnQgcG9zaXRpb24gb2YgdGhlIHN1YiBpbWFnZS4gCglAcGFyYW0gdG9wIFNwZWNpZmllcyB0aGUgdG9wIHBvc2l0aW9uIG9mIHRoZSBzdWIgaW1hZ2UuIAoJQHBhcmFtIGFscGhhIEFscGhhIGJsZW5kIGZhY3Rvci4gVGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gaW1hZ2VzIGFyZSBhbHBoYSBibGVuZGVkIGlmIAoJYWxwaGEgPSAwLi4yNTUuIElmIGFscGhhID4gMjU1LCB0aGVuIHRoZSBzb3VyY2UgaW1hZ2UgaXMgY29tYmluZWQgdG8gdGhlIGRlc3RpbmF0aW9uIGltYWdlLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoJQHNlZSBGcmVlSW1hZ2VfUGFzdGUKCSovCglCT09MIHBhc3RlU3ViSW1hZ2UoZmlwSW1hZ2UmIHNyYywgaW50IGxlZnQsIGludCB0b3AsIGludCBhbHBoYSA9IDI1Nik7CgoJLyoqCglAYnJpZWYgQ3JvcCBhIHN1YiBwYXJ0IG9mIHRoZSBjdXJyZW50IGltYWdlIGFuZCB1cGRhdGUgaXQgYWNjb3JkaW5nbHkuCgkKCVRoaXMgbWV0aG9kIHdvcmtzIHdpdGggYW55IGJpdG1hcCB0eXBlLgoJQHBhcmFtIGxlZnQgU3BlY2lmaWVzIHRoZSBsZWZ0IHBvc2l0aW9uIG9mIHRoZSBjcm9wcGVkIHJlY3RhbmdsZS4gCglAcGFyYW0gdG9wIFNwZWNpZmllcyB0aGUgdG9wIHBvc2l0aW9uIG9mIHRoZSBjcm9wcGVkIHJlY3RhbmdsZS4gCglAcGFyYW0gcmlnaHQgU3BlY2lmaWVzIHRoZSByaWdodCBwb3NpdGlvbiBvZiB0aGUgY3JvcHBlZCByZWN0YW5nbGUuIAoJQHBhcmFtIGJvdHRvbSBTcGVjaWZpZXMgdGhlIGJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgY3JvcHBlZCByZWN0YW5nbGUuIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoJKi8KCUJPT0wgY3JvcChpbnQgbGVmdCwgaW50IHRvcCwgaW50IHJpZ2h0LCBpbnQgYm90dG9tKTsKCgkvL0B9CgoJLyoqIEBuYW1lIEZpbGUgdHlwZSBpZGVudGlmaWNhdGlvbgoJICovCgkvL0B7CQoJLyoqCglAYnJpZWYgSWRlbnRpZmllcyBhbiBpbWFnZSBmcm9tIGRpc2ssIGdpdmVuIGl0cyBmaWxlIG5hbWUKCUBwYXJhbSBscHN6UGF0aE5hbWUgUGF0aCBhbmQgZmlsZSBuYW1lIG9mIHRoZSBpbWFnZSB0byBpZGVudGlmeS4KCUByZXR1cm4gUmV0dXJucyB0aGUgZm91bmQgRnJlZUltYWdlIGZvcm1hdCBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZJRl9VTktOT1dOIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0dldEZpbGVUeXBlLCBGcmVlSW1hZ2VfR2V0RklGRnJvbUZpbGVuYW1lLCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCXN0YXRpYyBGUkVFX0lNQUdFX0ZPUk1BVCBpZGVudGlmeUZJRihjb25zdCBjaGFyKiBscHN6UGF0aE5hbWUpOwoKCS8qKgoJVU5JQ09ERSB2ZXJzaW9uIG9mIGlkZW50aWZ5RklGICh0aGlzIGZ1bmN0aW9uIG9ubHkgd29ya3MgdW5kZXIgV0lOMzIgYW5kIGRvZXMgbm90aGluZyBvbiBvdGhlciBPUykKCUBzZWUgRnJlZUltYWdlX0dldEZpbGVUeXBlVSwgRnJlZUltYWdlX0dldEZJRkZyb21GaWxlbmFtZVUsIEZyZWVJbWFnZSBkb2N1bWVudGF0aW9uCgkqLwoJc3RhdGljIEZSRUVfSU1BR0VfRk9STUFUIGlkZW50aWZ5RklGVShjb25zdCB3Y2hhcl90KiBscHN6UGF0aE5hbWUpOwoKCS8qKgoJQGJyaWVmIElkZW50aWZpZXMgYW4gaW1hZ2UgdXNpbmcgdGhlIHNwZWNpZmllZCBGcmVlSW1hZ2VJTyBzdHJ1Y3QgYW5kIGZpX2hhbmRsZS4KCUBwYXJhbSBpbyBGcmVlSW1hZ2VJTyBzdHJ1Y3R1cmUKCUBwYXJhbSBoYW5kbGUgRnJlZUltYWdlIGZpX2hhbmRsZQoJQHJldHVybiBSZXR1cm5zIHRoZSBmb3VuZCBGcmVlSW1hZ2UgZm9ybWF0IGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRklGX1VOS05PV04gb3RoZXJ3aXNlLgoJQHNlZSBGcmVlSW1hZ2VfR2V0RmlsZVR5cGVGcm9tSGFuZGxlLCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCXN0YXRpYyBGUkVFX0lNQUdFX0ZPUk1BVCBpZGVudGlmeUZJRkZyb21IYW5kbGUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKTsKCgkvKioKCUBicmllZiBJZGVudGlmaWVzIGFuIGltYWdlIHVzaW5nIHRoZSBzcGVjaWZpZWQgbWVtb3J5IHN0cmVhbS4KCUBwYXJhbSBobWVtIEZyZWVJbWFnZSBtZW1vcnkgc3RyZWFtCglAcmV0dXJuIFJldHVybnMgdGhlIGZvdW5kIEZyZWVJbWFnZSBmb3JtYXQgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGSUZfVU5LTk9XTiBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9HZXRGaWxlVHlwZUZyb21NZW1vcnksIEZyZWVJbWFnZSBkb2N1bWVudGF0aW9uCgkqLwoJc3RhdGljIEZSRUVfSU1BR0VfRk9STUFUIGlkZW50aWZ5RklGRnJvbU1lbW9yeShGSU1FTU9SWSAqaG1lbSk7CgoJLy9AfQoKCgkvKiogQG5hbWUgTG9hZGluZyAmIFNhdmluZwoJICogTG9hZGluZyBhbmQgc2F2aW5nIGlzIGhhbmRsZWQgYnkgdGhlIEZyZWVJbWFnZSBsaWJyYXJ5LgoJICovCgkvL0B7CQoJLyoqCglAYnJpZWYgTG9hZHMgYW4gaW1hZ2UgZnJvbSBkaXNrLCBnaXZlbiBpdHMgZmlsZSBuYW1lIGFuZCBhbiBvcHRpb25hbCBmbGFnLgoJQHBhcmFtIGxwc3pQYXRoTmFtZSBQYXRoIGFuZCBmaWxlIG5hbWUgb2YgdGhlIGltYWdlIHRvIGxvYWQuCglAcGFyYW0gZmxhZyBUaGUgc2lnbmlmaWNhdGlvbiBvZiB0aGlzIGZsYWcgZGVwZW5kcyBvbiB0aGUgaW1hZ2UgdG8gYmUgcmVhZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0xvYWQsIEZyZWVJbWFnZSBkb2N1bWVudGF0aW9uCgkqLwoJQk9PTCBsb2FkKGNvbnN0IGNoYXIqIGxwc3pQYXRoTmFtZSwgaW50IGZsYWcgPSAwKTsKCgkvKioKCVVOSUNPREUgdmVyc2lvbiBvZiBsb2FkICh0aGlzIGZ1bmN0aW9uIG9ubHkgd29ya3MgdW5kZXIgV0lOMzIgYW5kIGRvZXMgbm90aGluZyBvbiBvdGhlciBPUykKCUBzZWUgbG9hZAoJKi8KCUJPT0wgbG9hZFUoY29uc3Qgd2NoYXJfdCogbHBzelBhdGhOYW1lLCBpbnQgZmxhZyA9IDApOwoKCS8qKgoJQGJyaWVmIExvYWRzIGFuIGltYWdlIHVzaW5nIHRoZSBzcGVjaWZpZWQgRnJlZUltYWdlSU8gc3RydWN0IGFuZCBmaV9oYW5kbGUsIGFuZCBhbiBvcHRpb25hbCBmbGFnLgoJQHBhcmFtIGlvIEZyZWVJbWFnZUlPIHN0cnVjdHVyZQoJQHBhcmFtIGhhbmRsZSBGcmVlSW1hZ2UgZmlfaGFuZGxlCglAcGFyYW0gZmxhZyBUaGUgc2lnbmlmaWNhdGlvbiBvZiB0aGlzIGZsYWcgZGVwZW5kcyBvbiB0aGUgaW1hZ2UgdG8gYmUgcmVhZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0xvYWRGcm9tSGFuZGxlLCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCUJPT0wgbG9hZEZyb21IYW5kbGUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgZmxhZyA9IDApOwoKCS8qKgoJQGJyaWVmIExvYWRzIGFuIGltYWdlIHVzaW5nIHRoZSBzcGVjaWZpZWQgbWVtb3J5IHN0cmVhbSBhbmQgYW4gb3B0aW9uYWwgZmxhZy4KCUBwYXJhbSBtZW1JTyBGcmVlSW1hZ2UgbWVtb3J5IHN0cmVhbQoJQHBhcmFtIGZsYWcgVGhlIHNpZ25pZmljYXRpb24gb2YgdGhpcyBmbGFnIGRlcGVuZHMgb24gdGhlIGltYWdlIHRvIGJlIHJlYWQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9Mb2FkRnJvbU1lbW9yeSwgRnJlZUltYWdlIGRvY3VtZW50YXRpb24KCSovCglCT09MIGxvYWRGcm9tTWVtb3J5KGZpcE1lbW9yeUlPJiBtZW1JTywgaW50IGZsYWcgPSAwKTsKCgkvKioKCUBicmllZiBTYXZlcyBhbiBpbWFnZSB0byBkaXNrLCBnaXZlbiBpdHMgZmlsZSBuYW1lIGFuZCBhbiBvcHRpb25hbCBmbGFnLgoJQHBhcmFtIGxwc3pQYXRoTmFtZSBQYXRoIGFuZCBmaWxlIG5hbWUgb2YgdGhlIGltYWdlIHRvIHNhdmUuCglAcGFyYW0gZmxhZyBUaGUgc2lnbmlmaWNhdGlvbiBvZiB0aGlzIGZsYWcgZGVwZW5kcyBvbiB0aGUgaW1hZ2UgdG8gYmUgc2F2ZWQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9TYXZlLCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCUJPT0wgc2F2ZShjb25zdCBjaGFyKiBscHN6UGF0aE5hbWUsIGludCBmbGFnID0gMCkgY29uc3Q7CgoJLyoqCglVTklDT0RFIHZlcnNpb24gb2Ygc2F2ZSAodGhpcyBmdW5jdGlvbiBvbmx5IHdvcmtzIHVuZGVyIFdJTjMyIGFuZCBkb2VzIG5vdGhpbmcgb24gb3RoZXIgT1MpCglAc2VlIHNhdmUKCSovCglCT09MIHNhdmVVKGNvbnN0IHdjaGFyX3QqIGxwc3pQYXRoTmFtZSwgaW50IGZsYWcgPSAwKSBjb25zdDsKCgkvKioKCUBicmllZiBTYXZlcyBhbiBpbWFnZSB1c2luZyB0aGUgc3BlY2lmaWVkIEZyZWVJbWFnZUlPIHN0cnVjdCBhbmQgZmlfaGFuZGxlLCBhbmQgYW4gb3B0aW9uYWwgZmxhZy4KCUBwYXJhbSBmaWYgRm9ybWF0IGlkZW50aWZpZXIgKEZyZWVJbWFnZSBmb3JtYXQpCglAcGFyYW0gaW8gRnJlZUltYWdlSU8gc3RydWN0dXJlCglAcGFyYW0gaGFuZGxlIEZyZWVJbWFnZSBmaV9oYW5kbGUKCUBwYXJhbSBmbGFnIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBzYXZlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX1NhdmVUb0hhbmRsZSwgRnJlZUltYWdlIGRvY3VtZW50YXRpb24KCSovCglCT09MIHNhdmVUb0hhbmRsZShGUkVFX0lNQUdFX0ZPUk1BVCBmaWYsIEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IGZsYWcgPSAwKSBjb25zdDsKCgkvKioKCUBicmllZiBTYXZlcyBhbiBpbWFnZSB1c2luZyB0aGUgc3BlY2lmaWVkIG1lbW9yeSBzdHJlYW0gYW5kIGFuIG9wdGlvbmFsIGZsYWcuCglAcGFyYW0gZmlmIEZvcm1hdCBpZGVudGlmaWVyIChGcmVlSW1hZ2UgZm9ybWF0KQoJQHBhcmFtIG1lbUlPIEZyZWVJbWFnZSBtZW1vcnkgc3RyZWFtCglAcGFyYW0gZmxhZyBUaGUgc2lnbmlmaWNhdGlvbiBvZiB0aGlzIGZsYWcgZGVwZW5kcyBvbiB0aGUgaW1hZ2UgdG8gYmUgc2F2ZWQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9TYXZlVG9NZW1vcnksIEZyZWVJbWFnZSBkb2N1bWVudGF0aW9uCgkqLwoJQk9PTCBzYXZlVG9NZW1vcnkoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBmaXBNZW1vcnlJTyYgbWVtSU8sIGludCBmbGFnID0gMCkgY29uc3Q7CgoJLy9AfQoKCS8qKglAbmFtZSBJbmZvcm1hdGlvbiBmdW5jdGlvbnMKCSAqICBBY2Nlc3NvcnMgdG8gdGhlIERJQiBCSVRNQVBJTkZPIHN0cnVjdHVyZS4KCSAqLwoJLy9AewkKCgkvKioKCVJldHVybnMgdGhlIGRhdGEgdHlwZSBvZiB0aGUgaW1hZ2UKCUBzZWUgRnJlZUltYWdlX0dldEltYWdlVHlwZQoJKi8KCUZSRUVfSU1BR0VfVFlQRSBnZXRJbWFnZVR5cGUoKSBjb25zdDsKCgkvKioKCVJldHVybnMgdGhlIGltYWdlIHdpZHRoIGluIHBpeGVscwoJQHNlZSBGcmVlSW1hZ2VfR2V0V2lkdGgKCSovCgl1bnNpZ25lZCBnZXRXaWR0aCgpIGNvbnN0OwoJCgkvKioKCVJldHVybnMgdGhlIGltYWdlIGhlaWdodCBpbiBwaXhlbHMKCUBzZWUgRnJlZUltYWdlX0dldEhlaWdodAoJKi8KCXVuc2lnbmVkIGdldEhlaWdodCgpIGNvbnN0OwoJCgkvKioKCVJldHVybnMgdGhlIHdpZHRoIG9mIHRoZSBiaXRtYXAgaW4gYnl0ZXMgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBEV09SRC4KCUBzZWUgRnJlZUltYWdlX0dldFBpdGNoCgkqLwoJdW5zaWduZWQgZ2V0U2NhbldpZHRoKCkgY29uc3Q7CgoJLyoqCglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgRklCSVRNQVAgZGF0YS4gVXNlZCBmb3IgZGlyZWN0IGFjY2VzcyBmcm9tIEZSRUVJTUFHRSBmdW5jdGlvbnMgCglvciBmcm9tIHlvdXIgb3duIGxvdyBsZXZlbCBDIGZ1bmN0aW9ucy48YnI+Cgk8Yj5TYW1wbGUgdXNlPC9iPiA6IDxicj4KCTxwcmU+CglmaXBJbWFnZSBzcmMsIGRzdDsKCXNyYy5sb2FkKCJ0ZXN0LnBuZyIpOwoJZHN0ID0gRnJlZUltYWdlX0NvbnZlcnRUbzhCaXRzKHNyYyk7CglGcmVlSW1hZ2VfU2F2ZShGSUZfVElGRiwgZHN0LCAidGVzdC50aWYiLCAwKTsKCTwvcHJlPgoJQHNlZSBvcGVyYXRvcj0oRklCSVRNQVAgKmRpYikKCSovCglvcGVyYXRvciBGSUJJVE1BUCooKSB7IAoJCXJldHVybiBfZGliOyAKCX0KCgkvLy8gUmV0dXJucyBUUlVFIGlmIHRoZSBpbWFnZSBpcyBhbGxvY2F0ZWQsIEZBTFNFIG90aGVyd2lzZQoJQk9PTCBpc1ZhbGlkKCkgY29uc3Q7CgoJLyoqCglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgYml0bWFwJ3MgQklUTUFQSU5GTyBoZWFkZXIuIAoJQHNlZSBGcmVlSW1hZ2VfR2V0SW5mbwoJKi8KCUJJVE1BUElORk8qIGdldEluZm8oKSBjb25zdDsKCgkvKioKCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBiaXRtYXAncyBCSVRNQVBJTkZPSEVBREVSLiAKCUBzZWUgRnJlZUltYWdlX0dldEluZm9IZWFkZXIKCSovCiAgICBCSVRNQVBJTkZPSEVBREVSKiBnZXRJbmZvSGVhZGVyKCkgY29uc3Q7CgoJLyoqCglSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBiaXRtYXAgaW4gYnl0ZXMuIAoJVGhlIHNpemUgb2YgdGhlIGJpdG1hcCBpcyB0aGUgQklUTUFQSU5GT0hFQURFUiArIHRoZSBzaXplIG9mIHRoZSBwYWxldHRlICsgdGhlIHNpemUgb2YgdGhlIGJpdG1hcCBkYXRhLiAKCUBzZWUgRnJlZUltYWdlX0dldERJQlNpemUKCSovCgl1bnNpZ25lZCBnZXRJbWFnZVNpemUoKSBjb25zdDsKCgkvKioKCVJldHVybnMgdGhlIG1lbW9yeSBmb290cHJpbnQgb2YgYSBiaXRtYXAsIGluIGJ5dGVzLiAKCUBzZWUgRnJlZUltYWdlX0dldE1lbW9yeVNpemUKCSovCgl1bnNpZ25lZCBnZXRJbWFnZU1lbW9yeVNpemUoKSBjb25zdDsKCQoJLyoqCglSZXR1cm5zIHRoZSBiaXRkZXB0aCBvZiB0aGUgYml0bWFwLiA8YnI+CglXaGVuIHRoZSBpbWFnZSB0eXBlIGlzIEZJVF9CSVRNQVAsIHZhbGlkIGJpdGRlcHRoIGNhbiBiZSAxLCA0LCA4LCAxNiwgMjQgb3IgMzIuCglAc2VlIEZyZWVJbWFnZV9HZXRCUFAsIGdldEltYWdlVHlwZQoJKi8KCXVuc2lnbmVkIGdldEJpdHNQZXJQaXhlbCgpIGNvbnN0OwoKCS8qKgoJUmV0dXJucyB0aGUgd2lkdGggb2YgdGhlIGJpdG1hcCBpbiBieXRlcy48YnI+Cgk8Yj5UaGlzIGlzIG5vdCB0aGUgc2l6ZSBvZiB0aGUgc2NhbmxpbmU8L2I+LgoJQHNlZSBGcmVlSW1hZ2VfR2V0TGluZSwgZ2V0U2NhbldpZHRoCgkqLwoJdW5zaWduZWQgZ2V0TGluZSgpIGNvbnN0OwoKCS8qKgoJUmV0dXJucyB0aGUgYml0bWFwIHJlc29sdXRpb24gYWxvbmcgdGhlIFggYXhpcywgaW4gcGl4ZWxzIC8gY20KCUBzZWUgRnJlZUltYWdlX0dldERvdHNQZXJNZXRlclgKCSovCglkb3VibGUgZ2V0SG9yaXpvbnRhbFJlc29sdXRpb24oKSBjb25zdDsKCQoJLyoqCglSZXR1cm5zIHRoZSBiaXRtYXAgcmVzb2x1dGlvbiBhbG9uZyB0aGUgWSBheGlzLCBpbiBwaXhlbHMgLyBjbQoJQHNlZSBGcmVlSW1hZ2VfR2V0RG90c1Blck1ldGVyWQoJKi8KCWRvdWJsZSBnZXRWZXJ0aWNhbFJlc29sdXRpb24oKSBjb25zdDsKCgkvKioKCXNldCB0aGUgYml0bWFwIHJlc29sdXRpb24gYWxvbmcgdGhlIFggYXhpcywgaW4gcGl4ZWxzIC8gY20KCUBzZWUgRnJlZUltYWdlX0dldEluZm9IZWFkZXIKCSovCgl2b2lkIHNldEhvcml6b250YWxSZXNvbHV0aW9uKGRvdWJsZSB2YWx1ZSk7CgkKCS8qKgoJc2V0IHRoZSBiaXRtYXAgcmVzb2x1dGlvbiBhbG9uZyB0aGUgWSBheGlzLCBpbiBwaXhlbHMgLyBjbQoJQHNlZSBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcgoJKi8KCXZvaWQgc2V0VmVydGljYWxSZXNvbHV0aW9uKGRvdWJsZSB2YWx1ZSk7CgoJLy9AfQoKCS8qKkBuYW1lIFBhbGV0dGUgb3BlcmF0aW9ucyAqLwoJLy9AewoJLyoqCglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgYml0bWFwJ3MgcGFsZXR0ZS4gSWYgdGhlIGJpdG1hcCBkb2Vzbid0IGhhdmUgYSBwYWxldHRlLCBnZXRQYWxldHRlIHJldHVybnMgTlVMTC4gCglAc2VlIEZyZWVJbWFnZV9HZXRQYWxldHRlCgkqLwoJUkdCUVVBRCogZ2V0UGFsZXR0ZSgpIGNvbnN0OwoJCgkvKioKCVJldHVybnMgdGhlIHBhbGV0dGUgc2l6ZSBpbiA8Yj5ieXRlczwvYj4uCglAc2VlIEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkCgkqLwoJdW5zaWduZWQgZ2V0UGFsZXR0ZVNpemUoKSBjb25zdDsKCgkvKioKCVJldHJpZXZlcyB0aGUgbnVtYmVyIG9mIGNvbG91cnMgdXNlZCBpbiB0aGUgYml0bWFwLiBJZiB0aGUgYml0bWFwIGlzIG5vbi1wYWxsZXRpc2VkLCAwIGlzIHJldHVybmVkLiAKCUBzZWUgRnJlZUltYWdlX0dldENvbG9yc1VzZWQKCSovCgl1bnNpZ25lZCBnZXRDb2xvcnNVc2VkKCkgY29uc3Q7CgoJLyoqIAoJSW52ZXN0aWdhdGVzIHRoZSBjb2xvdXIgdHlwZSBvZiB0aGUgYml0bWFwLgoJQHNlZSBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlLCBGUkVFX0lNQUdFX0NPTE9SX1RZUEUKCSovCglGUkVFX0lNQUdFX0NPTE9SX1RZUEUgZ2V0Q29sb3JUeXBlKCkgY29uc3Q7CgoJLyoqCglSZXR1cm5zIFRSVUUgaWYgdGhlIGJpdG1hcCBpcyBhIDgtYml0IGJpdG1hcCB3aXRoIGEgZ3JleXNjYWxlIHBhbGV0dGUsIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfR2V0QlBQLCBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlCgkqLwoJQk9PTCBpc0dyYXlzY2FsZSgpIGNvbnN0OwoJLy9AfQoKCS8qKkBuYW1lIFRodW1ibmFpbCBhY2Nlc3MgKi8KCS8vQHsKCgkvKioKCVJldHJpZXZlcyBhIGNvcHkgdGhlIHRodW1ibmFpbCBwb3NzaWJseSBhdHRhY2hlZCB0byB0aGUgYml0bWFwCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiB0aGUgdGh1bWJuYWlsIGlzIHByZXNlbnQgaW4gdGhlIGJpdG1hcCBhbmQgc3VjY2Vzc2Z1bHkgcmV0cmlldmVkLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfR2V0VGh1bWJuYWlsCgkqLwoJQk9PTCBnZXRUaHVtYm5haWwoZmlwSW1hZ2UmIGltYWdlKSBjb25zdDsKCgkvKioKCUF0dGFjaCBhIHRodW1ibmFpbCB0byB0aGUgYml0bWFwCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiB0aGUgdGh1bWJuYWlsIHdhcyBzdWNjZXNzZnVseSBzZXQsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9TZXRUaHVtYm5haWwKCSovCglCT09MIHNldFRodW1ibmFpbChjb25zdCBmaXBJbWFnZSYgaW1hZ2UpOwoKCS8qKgoJQ2hlY2sgaWYgdGhlIGltYWdlIGhhcyBhbiBlbWJlZGRlZCB0aHVtYm5haWwKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIGEgdGh1bWJuYWlsIGlzIHByZXNlbnQgaW4gdGhlIGJpdG1hcCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0dldFRodW1ibmFpbAoJKi8KCUJPT0wgaGFzVGh1bWJuYWlsKCkgY29uc3Q7CgoJLyoqCglDbGVhciB0aGUgdGh1bWJuYWlsIHBvc3NpYmx5IGF0dGFjaGVkIHRvIHRoZSBiaXRtYXAKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU2Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9TZXRUaHVtYm5haWwKCSovCglCT09MIGNsZWFyVGh1bWJuYWlsKCk7CgoJLy9AfQoKCS8qKkBuYW1lIFBpeGVsIGFjY2VzcyAqLwoJLy9AewkKCgkvKiogQGJyaWVmIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBiaXRtYXAgYml0cy4KCglJdCBpcyB1cCB0byB5b3UgdG8gaW50ZXJwcmV0IHRoZXNlIGJ5dGVzIGNvcnJlY3RseSwgCglhY2NvcmRpbmcgdG8gdGhlIHJlc3VsdHMgb2YgRnJlZUltYWdlX0dldEJQUCBhbmQgCglHZXRSZWRNYXNrLCBGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrIGFuZCBGcmVlSW1hZ2VfR2V0Qmx1ZU1hc2suPGJyPgoJVXNlIHRoaXMgZnVuY3Rpb24gd2l0aCBnZXRTY2FuV2lkdGggdG8gaXRlcmF0ZXMgdGhyb3VnaCB0aGUgcGl4ZWxzLiAKCUBzZWUgRnJlZUltYWdlX0dldEJpdHMKCSovCglCWVRFKiBhY2Nlc3NQaXhlbHMoKSBjb25zdDsKCgkvKiogQGJyaWVmIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBzdGFydCBvZiB0aGUgZ2l2ZW4gc2NhbmxpbmUgaW4gdGhlIGJpdG1hcJJzIGRhdGEtYml0cy4KCQlUaGlzIHBvaW50ZXIgY2FuIGJlIGNhc3QgYWNjb3JkaW5nIHRvIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgZ2V0SW1hZ2VUeXBlLjxicj4KCQlVc2UgdGhpcyBmdW5jdGlvbiB3aXRoIGdldFNjYW5XaWR0aCB0byBpdGVyYXRlcyB0aHJvdWdoIHRoZSBwaXhlbHMuIAoJCUBzZWUgRnJlZUltYWdlX0dldFNjYW5MaW5lLCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCUJZVEUqIGdldFNjYW5MaW5lKHVuc2lnbmVkIHNjYW5saW5lKSBjb25zdDsKCgkvKiogCglHZXQgdGhlIHBpeGVsIGluZGV4IG9mIGEgMS0sIDQtIG9yIDgtYml0IHBhbGV0dGl6ZWQgaW1hZ2UgYXQgcG9zaXRpb24gKHgsIHkpLCBpbmNsdWRpbmcgcmFuZ2UgY2hlY2sgKHNsb3cgYWNjZXNzKS4gCglAcGFyYW0geCBQaXhlbCBwb3NpdGlvbiBpbiBob3Jpem9udGFsIGRpcmVjdGlvbgoJQHBhcmFtIHkgUGl4ZWwgcG9zaXRpb24gaW4gdmVydGljYWwgZGlyZWN0aW9uCglAcGFyYW0gdmFsdWUgUGl4ZWwgaW5kZXggKHJldHVybmVkIHZhbHVlKQoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0dldFBpeGVsSW5kZXgKCSovCglCT09MIGdldFBpeGVsSW5kZXgodW5zaWduZWQgeCwgdW5zaWduZWQgeSwgQllURSAqdmFsdWUpIGNvbnN0OwoKCS8qKiAKCUdldCB0aGUgcGl4ZWwgY29sb3Igb2YgYSAxNi0sIDI0LSBvciAzMi1iaXQgaW1hZ2UgYXQgcG9zaXRpb24gKHgsIHkpLCBpbmNsdWRpbmcgcmFuZ2UgY2hlY2sgKHNsb3cgYWNjZXNzKS4gCglAcGFyYW0geCBQaXhlbCBwb3NpdGlvbiBpbiBob3Jpem9udGFsIGRpcmVjdGlvbgoJQHBhcmFtIHkgUGl4ZWwgcG9zaXRpb24gaW4gdmVydGljYWwgZGlyZWN0aW9uCglAcGFyYW0gdmFsdWUgUGl4ZWwgY29sb3IgKHJldHVybmVkIHZhbHVlKQoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0dldFBpeGVsQ29sb3IKCSovCglCT09MIGdldFBpeGVsQ29sb3IodW5zaWduZWQgeCwgdW5zaWduZWQgeSwgUkdCUVVBRCAqdmFsdWUpIGNvbnN0OwoKCS8qKiAKCVNldCB0aGUgcGl4ZWwgaW5kZXggb2YgYSAxLSwgNC0gb3IgOC1iaXQgcGFsZXR0aXplZCBpbWFnZSBhdCBwb3NpdGlvbiAoeCwgeSksIGluY2x1ZGluZyByYW5nZSBjaGVjayAoc2xvdyBhY2Nlc3MpLiAKCUBwYXJhbSB4IFBpeGVsIHBvc2l0aW9uIGluIGhvcml6b250YWwgZGlyZWN0aW9uCglAcGFyYW0geSBQaXhlbCBwb3NpdGlvbiBpbiB2ZXJ0aWNhbCBkaXJlY3Rpb24KCUBwYXJhbSB2YWx1ZSBQaXhlbCBpbmRleAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX1NldFBpeGVsSW5kZXgKCSovCglCT09MIHNldFBpeGVsSW5kZXgodW5zaWduZWQgeCwgdW5zaWduZWQgeSwgQllURSAqdmFsdWUpOwoKCS8qKiAKCVNldCB0aGUgcGl4ZWwgY29sb3Igb2YgYSAxNi0sIDI0LSBvciAzMi1iaXQgaW1hZ2UgYXQgcG9zaXRpb24gKHgsIHkpLCBpbmNsdWRpbmcgcmFuZ2UgY2hlY2sgKHNsb3cgYWNjZXNzKS4gCglAcGFyYW0geCBQaXhlbCBwb3NpdGlvbiBpbiBob3Jpem9udGFsIGRpcmVjdGlvbgoJQHBhcmFtIHkgUGl4ZWwgcG9zaXRpb24gaW4gdmVydGljYWwgZGlyZWN0aW9uCglAcGFyYW0gdmFsdWUgUGl4ZWwgY29sb3IKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9TZXRQaXhlbENvbG9yCgkqLwoJQk9PTCBzZXRQaXhlbENvbG9yKHVuc2lnbmVkIHgsIHVuc2lnbmVkIHksIFJHQlFVQUQgKnZhbHVlKTsKCgkvL0B9CgoJLyoqCUBuYW1lIENvbnZlcnNpb24gcm91dGluZXMKCSAqICBCaXRtYXBzIGFyZSBhbHdheXMgbG9hZGVkIGluIHRoZWlyIGRlZmF1bHQgYml0IGRlcHRoLiBJZiB5b3Ugd2FudCB0aGUgYml0bWFwIHRvIGJlIHN0b3JlZCBpbiBhbm90aGVyIGJpdCBkZXB0aCwgdGhlIGNsYXNzIHByb3ZpZGVzIHNldmVyYWwgY29udmVyc2lvbiBmdW5jdGlvbnMuCgkgKi8KCS8vQHsJCgkvKiogCglDb252ZXJ0cyBhbiBpbWFnZSB0byBhIHR5cGUgc3VwcG9ydGVkIGJ5IEZyZWVJbWFnZS4KCUBwYXJhbSBpbWFnZV90eXBlIE5ldyBpbWFnZSB0eXBlCglAcGFyYW0gc2NhbGVfbGluZWFyIFRSVUUgaWYgaW1hZ2UgcGl4ZWxzIG11c3QgYmUgc2NhbGVkIGxpbmVhcmx5IHdoZW4gY29udmVydGluZyB0byBhIHN0YW5kYXJkIGJpdG1hcAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUb1R5cGUsIEZyZWVJbWFnZV9Db252ZXJ0VG9TdGFuZGFyZFR5cGUKCSovCglCT09MIGNvbnZlcnRUb1R5cGUoRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUsIEJPT0wgc2NhbGVfbGluZWFyID0gVFJVRSk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byAxIGJpdCB1c2luZyBhIHRocmVzaG9sZCBULgoJQHBhcmFtIFQgVGhyZXNob2xkIHZhbHVlIGluIFswLi4yNTVdCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfVGhyZXNob2xkCgkqLwoJQk9PTCB0aHJlc2hvbGQoQllURSBUKTsKCQoJLyoqIAoJQ29udmVydHMgYSA4LWJpdCBpbWFnZSB0byBhIG1vbm9jaHJvbWUgMS1iaXQgaW1hZ2UgdXNpbmcgYSBkaXRoZXJpbmcgYWxnb3JpdGhtLgoJQHBhcmFtIGFsZ29yaXRobSBEaXRoZXJpbmcgYWxnb3JpdGhtIHRvIHVzZS4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9EaXRoZXIsIEZSRUVfSU1BR0VfRElUSEVSCgkqLwoJQk9PTCBkaXRoZXIoRlJFRV9JTUFHRV9ESVRIRVIgYWxnb3JpdGhtKTsKCgkvKiogCglDb252ZXJ0cyB0aGUgYml0bWFwIHRvIDQgYml0cy4gVW5sZXNzIHRoZSBiaXRtYXAgaXMgYSAxLWJpdCBwYWxldHRpemVkIGJpdG1hcCwgY29sb3VyIHZhbHVlcyBhcmUgY29udmVydGVkIHRvIGdyZXlzY2FsZS4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9Db252ZXJ0VG80Qml0cwoJKi8KCUJPT0wgY29udmVydFRvNEJpdHMoKTsKCgkvKiogCglDb252ZXJ0cyB0aGUgYml0bWFwIHRvIDggYml0cy4gSWYgdGhlIGJpdG1hcCBpcyAyNCBvciAzMi1iaXQgUkdCLCB0aGUgY29sb3VyIHZhbHVlcyBhcmUgY29udmVydGVkIHRvIGdyZXlzY2FsZS4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9Db252ZXJ0VG84Qml0cwoJKi8KCUJPT0wgY29udmVydFRvOEJpdHMoKTsKCgkvKiogCglDb252ZXJ0cyB0aGUgYml0bWFwIHRvIDggYml0cy48YnI+IAoJRm9yIHBhbGxldGl6ZWQgYml0bWFwcywgdGhlIGNvbG9yIG1hcCBpcyBjb252ZXJ0ZWQgdG8gYSBncmV5c2NhbGUgcmFtcC4KCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUb0dyZXlzY2FsZQoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCSovCglCT09MIGNvbnZlcnRUb0dyYXlzY2FsZSgpOwoJCgkvKiogCglRdWFudGl6ZXMgYSBmdWxsIGNvbG91ciAyNC1iaXQgYml0bWFwIHRvIGEgcGFsbGV0aXNlZCA4LWJpdCBiaXRtYXAuPGJyPgoJVGhlIHF1YW50aXplIHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggY29sb3VyIHJlZHVjdGlvbiBhbGdvcml0aG0gc2hvdWxkIGJlIHVzZWQuCglAcGFyYW0gYWxnb3JpdGhtIENvbG9yIHF1YW50aXphdGlvbiBhbGdvcml0aG0gdG8gdXNlLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbG9yUXVhbnRpemUsIEZSRUVfSU1BR0VfUVVBTlRJWkUKCSovCglCT09MIGNvbG9yUXVhbnRpemUoRlJFRV9JTUFHRV9RVUFOVElaRSBhbGdvcml0aG0pOwoKCS8qKiAKCUNvbnZlcnRzIHRoZSBiaXRtYXAgdG8gMTYgYml0cy4gVGhlIHJlc3VsdGluZyBiaXRtYXAgaGFzIGEgbGF5b3V0IG9mIDUgYml0cyByZWQsIDUgYml0cyBncmVlbiwgNSBiaXRzIGJsdWUgYW5kIDEgdW51c2VkIGJpdC4gCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfQ29udmVydFRvMTZCaXRzNTU1CgkqLwoJQk9PTCBjb252ZXJ0VG8xNkJpdHM1NTUoKTsKCQoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byAxNiBiaXRzLiBUaGUgcmVzdWx0aW5nIGJpdG1hcCBoYXMgYSBsYXlvdXQgb2YgNSBiaXRzIHJlZCwgNiBiaXRzIGdyZWVuIGFuZCA1IGJpdHMgYmx1ZS4gCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfQ29udmVydFRvMTZCaXRzNTY1CgkqLwoJQk9PTCBjb252ZXJ0VG8xNkJpdHM1NjUoKTsKCQoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byAyNCBiaXRzLiAKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9Db252ZXJ0VG8yNEJpdHMKCSovCglCT09MIGNvbnZlcnRUbzI0Qml0cygpOwoJCgkvKiogCglDb252ZXJ0cyB0aGUgYml0bWFwIHRvIDMyIGJpdHMuIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUbzMyQml0cwoJKi8KCUJPT0wgY29udmVydFRvMzJCaXRzKCk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byBhIDMyLWJpdCBmbG9hdCBpbWFnZS4gCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfQ29udmVydFRvRmxvYXQKCSovCglCT09MIGNvbnZlcnRUb0Zsb2F0KCk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byBhIDk2LWJpdCBSR0JGIGltYWdlLiAKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9Db252ZXJ0VG9SR0JGCgkqLwoJQk9PTCBjb252ZXJ0VG9SR0JGKCk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byBhIDEyOC1iaXQgUkdCQUYgaW1hZ2UuIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUb1JHQkFGCgkqLwoJQk9PTCBjb252ZXJ0VG9SR0JBRigpOwoKCS8qKiAKCUNvbnZlcnRzIHRoZSBiaXRtYXAgdG8gYSAxNi1iaXQgdW5zaWduZWQgc2hvcnQgaW1hZ2UuIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUb1VJTlQxNgoJKi8KCUJPT0wgY29udmVydFRvVUlOVDE2KCk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byBhIDQ4LWJpdCBSR0IxNiBpbWFnZS4gCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfQ29udmVydFRvUkdCMTYKCSovCglCT09MIGNvbnZlcnRUb1JHQjE2KCk7CgoJLyoqIAoJQ29udmVydHMgdGhlIGJpdG1hcCB0byBhIDY0LWJpdCBSR0JBMTYgaW1hZ2UuIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLiAKCUBzZWUgRnJlZUltYWdlX0NvbnZlcnRUb1JHQkExNgoJKi8KCUJPT0wgY29udmVydFRvUkdCQTE2KCk7CgoJLyoqCglDb252ZXJ0cyBhIEhpZ2ggRHluYW1pYyBSYW5nZSBpbWFnZSAoNDgtYml0IFJHQiBvciA5Ni1iaXQgUkdCIEZsb2F0KSB0byBhIDI0LWJpdCBSR0IgaW1hZ2UuIAoJQHBhcmFtIHRtbyBUb25lIG1hcHBpbmcgb3BlcmF0b3IKCUBwYXJhbSBmaXJzdF9wYXJhbSBGaXJzdCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlciAoYWxnb3JpdGhtIGRlcGVuZGFudCkKCUBwYXJhbSBzZWNvbmRfcGFyYW0gU2Vjb25kIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyIChhbGdvcml0aG0gZGVwZW5kYW50KQoJQHBhcmFtIHRoaXJkX3BhcmFtIFRoaXJkIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyIChhbGdvcml0aG0gZGVwZW5kYW50KQoJQHBhcmFtIGZvdXJ0aF9wYXJhbSBGb3VydGggdG9uZSBtYXBwaW5nIGFsZ29yaXRobSBwYXJhbWV0ZXIgKGFsZ29yaXRobSBkZXBlbmRhbnQpCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuIAoJQHNlZSBGcmVlSW1hZ2VfVG9uZU1hcHBpbmcsIEZyZWVJbWFnZV9UbW9SZWluaGFyZDA1RXgKCSovCglCT09MIHRvbmVNYXBwaW5nKEZSRUVfSU1BR0VfVE1PIHRtbywgZG91YmxlIGZpcnN0X3BhcmFtID0gMCwgZG91YmxlIHNlY29uZF9wYXJhbSA9IDAsIGRvdWJsZSB0aGlyZF9wYXJhbSA9IDEsIGRvdWJsZSBmb3VydGhfcGFyYW0gPSAwKTsKCgkvL0B9CgoJLyoqCUBuYW1lIFRyYW5zcGFyZW5jeSBzdXBwb3J0OiBiYWNrZ3JvdW5kIGNvbG91ciBhbmQgYWxwaGEgY2hhbm5lbCAqLwoJLy9AewoKCS8qKgoJUmV0dXJucyBUUlVFIGlmIHRoZSBpbWFnZSBpcyB0cmFuc3BhcmVudCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQKCSovCglCT09MIGlzVHJhbnNwYXJlbnQoKSBjb25zdDsKCgkvKioKCTgtYml0IHRyYW5zcGFyZW5jeSA6IGdldCB0aGUgbnVtYmVyIG9mIHRyYW5zcGFyZW50IGNvbG9ycy4KCUByZXR1cm4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRyYW5zcGFyZW50IGNvbG9ycyBpbiBhIHBhbGxldGlzZWQgYml0bWFwLgoJQHNlZSBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5Q291bnQKCSovCgl1bnNpZ25lZCBnZXRUcmFuc3BhcmVuY3lDb3VudCgpIGNvbnN0OwoKCS8qKgoJOC1iaXQgdHJhbnNwYXJlbmN5IDogZ2V0IHRoZSBiaXRtYXCScyB0cmFuc3BhcmVuY3kgdGFibGUuCglAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBiaXRtYXCScyB0cmFuc3BhcmVuY3kgdGFibGUuCglAc2VlIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZQoJKi8KCUJZVEUqIGdldFRyYW5zcGFyZW5jeVRhYmxlKCkgY29uc3Q7CgoJLyoqIAoJOC1iaXQgdHJhbnNwYXJlbmN5IDogc2V0IHRoZSBiaXRtYXCScyB0cmFuc3BhcmVuY3kgdGFibGUuCglAc2VlIEZyZWVJbWFnZV9TZXRUcmFuc3BhcmVuY3lUYWJsZQoJKi8KCXZvaWQgc2V0VHJhbnNwYXJlbmN5VGFibGUoQllURSAqdGFibGUsIGludCBjb3VudCk7CgoJLyoqCglSZXR1cm5zIFRSVUUgd2hlbiB0aGUgaW1hZ2UgaGFzIGEgZmlsZSBiYWNrZ3JvdW5kIGNvbG9yLCBGQUxTRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IKCSovCglCT09MIGhhc0ZpbGVCa0NvbG9yKCkgY29uc3Q7CgoJLyoqCglAYnJpZWYgUmV0cmlldmVzIHRoZSBmaWxlIGJhY2tncm91bmQgY29sb3Igb2YgYW4gaW1hZ2UuIAoJCglGb3IgOC1iaXQgaW1hZ2VzLCB0aGUgY29sb3IgaW5kZXggCglpbiB0aGUgcGFsZXR0ZSBpcyByZXR1cm5lZCBpbiB0aGUgcmdiUmVzZXJ2ZWQgbWVtYmVyIG9mIHRoZSBia2NvbG9yIHBhcmFtZXRlci4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9HZXRCYWNrZ3JvdW5kQ29sb3IKCSovCglCT09MIGdldEZpbGVCa0NvbG9yKFJHQlFVQUQgKmJrY29sb3IpIGNvbnN0OwoKCS8qKgoJQGJyaWVmIFNldCB0aGUgZmlsZSBiYWNrZ3JvdW5kIGNvbG9yIG9mIGFuIGltYWdlLiAKCQoJV2hlbiBzYXZpbmcgYW4gaW1hZ2UgdG8gUE5HLCB0aGlzIGJhY2tncm91bmQgY29sb3IgaXMgdHJhbnNwYXJlbnRseSBzYXZlZCB0byB0aGUgUE5HIGZpbGUuIAoJV2hlbiB0aGUgYmtjb2xvciBwYXJhbWV0ZXIgaXMgTlVMTCwgdGhlIGJhY2tncm91bmQgY29sb3IgaXMgcmVtb3ZlZCBmcm9tIHRoZSBpbWFnZS4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCglAc2VlIEZyZWVJbWFnZV9TZXRCYWNrZ3JvdW5kQ29sb3IKCSovCglCT09MIHNldEZpbGVCa0NvbG9yKFJHQlFVQUQgKmJrY29sb3IpOwoJLy9AfQoKCS8qKkBuYW1lIENoYW5uZWwgcHJvY2Vzc2luZyBzdXBwb3J0ICovCgkvL0B7CQoJLyoqIEBicmllZiBSZXRyaWV2ZXMgdGhlIHJlZCwgZ3JlZW4sIGJsdWUgb3IgYWxwaGEgY2hhbm5lbCBvZiBhIDI0LSBvciAzMi1iaXQgQkdSW0FdIGltYWdlLiAKCUBwYXJhbSBpbWFnZSBPdXRwdXQgaW1hZ2UgdG8gYmUgZXh0cmFjdGVkCglAcGFyYW0gY2hhbm5lbCBDb2xvciBjaGFubmVsIHRvIGV4dHJhY3QKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0dldENoYW5uZWwsIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTAoJKi8KCUJPT0wgZ2V0Q2hhbm5lbChmaXBJbWFnZSYgaW1hZ2UsIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTCBjaGFubmVsKSBjb25zdDsKCgkvKioKCUBicmllZiBJbnNlcnQgYSA4LWJpdCBkaWIgaW50byBhIDI0LSBvciAzMi1iaXQgaW1hZ2UuIAoJQHBhcmFtIGltYWdlIElucHV0IDgtYml0IGltYWdlIHRvIGluc2VydAoJQHBhcmFtIGNoYW5uZWwgQ29sb3IgY2hhbm5lbCB0byByZXBsYWNlCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9TZXRDaGFubmVsLCBGUkVFX0lNQUdFX0NPTE9SX0NIQU5ORUwKCSovCglCT09MIHNldENoYW5uZWwoZmlwSW1hZ2UmIGltYWdlLCBGUkVFX0lNQUdFX0NPTE9SX0NIQU5ORUwgY2hhbm5lbCk7CgoJLyoqIEBicmllZiBTcGxpdCBhIDI0LWJpdCBSR0IgaW1hZ2UgaW50byAzIGdyZXlzY2FsZSBpbWFnZXMgY29ycmVzcG9uZGluZyB0byB0aGUgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVscy4KCUBwYXJhbSBSZWRDaGFubmVsIE91dHB1dCByZWQgY2hhbm5lbC4KCUBwYXJhbSBHcmVlbkNoYW5uZWwgT3V0cHV0IGdyZWVuIGNoYW5uZWwuCglAcGFyYW0gQmx1ZUNoYW5uZWwgT3V0cHV0IGJsdWUgY2hhbm5lbC4KCUByZXR1cm4gUmV0dXJucyBGQUxTRSBpZiB0aGUgZGliIGlzbid0IGEgdmFsaWQgaW1hZ2UsIGlmIGl0J3Mgbm90IGEgMjQtYml0IGltYWdlIG9yIGlmIAoJb25lIG9mIHRoZSBvdXRwdXQgY2hhbm5lbCBjYW4ndCBiZSBhbGxvY2F0ZWQuIFJldHVybnMgVFJVRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9HZXRDaGFubmVsCgkqLwoJQk9PTCBzcGxpdENoYW5uZWxzKGZpcEltYWdlJiBSZWRDaGFubmVsLCBmaXBJbWFnZSYgR3JlZW5DaGFubmVsLCBmaXBJbWFnZSYgQmx1ZUNoYW5uZWwpOwoKCS8qKiBAYnJpZWYgQnVpbGRzIGEgMjQtYml0IFJHQiBpbWFnZSBnaXZlbiBpdHMgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVsLgoJQHBhcmFtIHJlZCBJbnB1dCByZWQgY2hhbm5lbC4KCUBwYXJhbSBncmVlbiBJbnB1dCBncmVlbiBjaGFubmVsLgoJQHBhcmFtIGJsdWUgSW5wdXQgYmx1ZSBjaGFubmVsLgoJQHJldHVybiBSZXR1cm5zIEZBTFNFIGlmIHRoZSBkaWIgY2FuJ3QgYmUgYWxsb2NhdGVkLCBpZiB0aGUgaW5wdXQgY2hhbm5lbHMgYXJlIG5vdCA4LWJpdCBpbWFnZXMuIFJldHVybnMgVFJVRSBvdGhlcndpc2UuCglAc2VlIEZyZWVJbWFnZV9TZXRDaGFubmVsCgkqLwoJQk9PTCBjb21iaW5lQ2hhbm5lbHMoZmlwSW1hZ2UmIHJlZCwgZmlwSW1hZ2UmIGdyZWVuLCBmaXBJbWFnZSYgYmx1ZSk7CgkvL0B9CgoJLyoqQG5hbWUgUm90YXRpb24gYW5kIGZsaXBwaW5nICovCgkvL0B7CQoJLyoqIAoJSW1hZ2UgdHJhbnNsYXRpb24gYW5kIHJvdGF0aW9uIHVzaW5nIEItU3BsaW5lcy4KCUBwYXJhbSBhbmdsZSBJbWFnZSByb3RhdGlvbiBhbmdsZSwgaW4gZGVncmVlCglAcGFyYW0geF9zaGlmdCBJbWFnZSBob3Jpem9udGFsIHNoaWZ0CglAcGFyYW0geV9zaGlmdCBJbWFnZSB2ZXJ0aWNhbCBzaGlmdAoJQHBhcmFtIHhfb3JpZ2luIE9yaWdpbiBvZiB0aGUgeC1heGlzCglAcGFyYW0geV9vcmlnaW4gT3JpZ2luIG9mIHRoZSB5LWF4aXMKCUBwYXJhbSB1c2VfbWFzayBXaGV0aGVyIG9yIG5vdCB0byBtYXNrIHRoZSBpbWFnZS4gSW1hZ2UgbWlycm9yaW5nIGlzIGFwcGxpZWQgd2hlbiB1c2VfbWFzayBpcyBzZXQgdG8gRkFMU0UKCUByZXR1cm4gUmV0dXJucyB0aGUgdHJhbnNsYXRlZCAmIHJvdGF0ZWQgZGliIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1JvdGF0ZUV4CgkqLwoJQk9PTCByb3RhdGVFeChkb3VibGUgYW5nbGUsIGRvdWJsZSB4X3NoaWZ0LCBkb3VibGUgeV9zaGlmdCwgZG91YmxlIHhfb3JpZ2luLCBkb3VibGUgeV9vcmlnaW4sIEJPT0wgdXNlX21hc2spOwoKCS8qKiAKCUltYWdlIHJvdGF0aW9uIGJ5IG1lYW5zIG9mIHRocmVlIHNoZWFycy4KCUBwYXJhbSBhbmdsZSBJbWFnZSByb3RhdGlvbiBhbmdsZSwgaW4gZGVncmVlCglAcGFyYW0gYmtjb2xvciBCYWNrZ3JvdW5kIGNvbG9yIChpbWFnZSB0eXBlIGRlcGVuZGVudCksIGRlZmF1bHQgdG8gYmxhY2sgYmFja2dyb3VuZAoJQHJldHVybiBSZXR1cm5zIHJvdGF0ZWQgZGliIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1JvdGF0ZQoJKi8KCUJPT0wgcm90YXRlKGRvdWJsZSBhbmdsZSwgY29uc3Qgdm9pZCAqYmtjb2xvciA9IE5VTEwpOwoKCS8qKgoJRmxpcCB0aGUgaW1hZ2UgaG9yaXpvbnRhbGx5IGFsb25nIHRoZSB2ZXJ0aWNhbCBheGlzCglAc2VlIEZyZWVJbWFnZV9GbGlwSG9yaXpvbnRhbAoJKi8KCUJPT0wgZmxpcEhvcml6b250YWwoKTsKCgkvKioKCUZsaXAgdGhlIGltYWdlIHZlcnRpY2FsbHkgYWxvbmcgdGhlIGhvcml6b250YWwgYXhpcwoJQHNlZSBGcmVlSW1hZ2VfRmxpcFZlcnRpY2FsCgkqLwoJQk9PTCBmbGlwVmVydGljYWwoKTsKCS8vQH0KCgkvKipAbmFtZSBDb2xvciBtYW5pcHVsYXRpb24gcm91dGluZXMgKi8KCS8vQHsJCgkvKiogCglJbnZlcnRzIGVhY2ggcGl4ZWwgZGF0YS4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX0ludmVydAoJKi8KCUJPT0wgaW52ZXJ0KCk7CgkKCS8qKiBAYnJpZWYgUGVyZm9tcyBhbiBoaXN0b2dyYW0gdHJhbnNmb3JtYXRpb24gb24gYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UgCglhY2NvcmRpbmcgdG8gdGhlIHZhbHVlcyBvZiBhIGxvb2t1cCB0YWJsZSAoTFVUKS4KCglUaGUgdHJhbnNmb3JtYXRpb24gaXMgZG9uZSBhcyBmb2xsb3dzLjxicj4KCUltYWdlIDgtYml0IDogaWYgdGhlIGltYWdlIGhhcyBhIGNvbG9yIHBhbGV0dGUsIHRoZSBMVVQgaXMgYXBwbGllZCB0byB0aGlzIHBhbGV0dGUsIAoJb3RoZXJ3aXNlLCBpdCBpcyBhcHBsaWVkIHRvIHRoZSBncmV5IHZhbHVlcy48YnI+CglJbWFnZSAyNC1iaXQgJiAzMi1iaXQgOiBpZiBjaGFubmVsID09IElQTF9DQ19SR0IsIHRoZSBzYW1lIExVVCBpcyBhcHBsaWVkIHRvIGVhY2ggY29sb3IKCXBsYW5lIChSLEcsIGFuZCBCKS4gT3RoZXJ3aXNlLCB0aGUgTFVUIGlzIGFwcGxpZWQgdG8gdGhlIHNwZWNpZmllZCBjaGFubmVsIG9ubHkuCglAcGFyYW0gTFVUIExvb2t1cCB0YWJsZS4gPGI+VGhlIHNpemUgb2YgJ0xVVCcgaXMgYXNzdW1lZCB0byBiZSAyNTYuPC9iPgoJQHBhcmFtIGNoYW5uZWwgVGhlIGNvbG9yIGNoYW5uZWwgdG8gYmUgcHJvY2Vzc2VkIChvbmx5IHVzZWQgd2l0aCAyNCAmIDMyLWJpdCBESUIpLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZSwgRlJFRV9JTUFHRV9DT0xPUl9DSEFOTkVMCgkqLwoJQk9PTCBhZGp1c3RDdXJ2ZShCWVRFICpMVVQsIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTCBjaGFubmVsKTsKCgkvKiogQGJyaWVmIFBlcmZvcm1zIGdhbW1hIGNvcnJlY3Rpb24gb24gYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UuCglAcGFyYW0gZ2FtbWEgR2FtbWEgdmFsdWUgdG8gdXNlLiBBIHZhbHVlIG9mIDEuMCBsZWF2ZXMgdGhlIGltYWdlIGFsb25lLCAKCWxlc3MgdGhhbiBvbmUgZGFya2VucyBpdCwgYW5kIGdyZWF0ZXIgdGhhbiBvbmUgbGlnaHRlbnMgaXQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0FkanVzdEdhbW1hLCBhZGp1c3RDdXJ2ZQoJKi8KCUJPT0wgYWRqdXN0R2FtbWEoZG91YmxlIGdhbW1hKTsKCgkvKiogQGJyaWVmIEFkanVzdHMgdGhlIGJyaWdodG5lc3Mgb2YgYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UgYnkgYSBjZXJ0YWluIGFtb3VudC4KCUBwYXJhbSBwZXJjZW50YWdlIFdoZXJlIC0xMDAgPD0gcGVyY2VudGFnZSA8PSAxMDA8YnI+CglBIHZhbHVlIDAgbWVhbnMgbm8gY2hhbmdlLCBsZXNzIHRoYW4gMCB3aWxsIG1ha2UgdGhlIGltYWdlIGRhcmtlciAKCWFuZCBncmVhdGVyIHRoYW4gMCB3aWxsIG1ha2UgdGhlIGltYWdlIGJyaWdodGVyLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2VzZnVsLCBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0FkanVzdEJyaWdodG5lc3MsIGFkanVzdEN1cnZlCgkqLwoJQk9PTCBhZGp1c3RCcmlnaHRuZXNzKGRvdWJsZSBwZXJjZW50YWdlKTsKCgkvKiogQGJyaWVmIEFkanVzdHMgdGhlIGNvbnRyYXN0IG9mIGEgOCwgMjQgb3IgMzItYml0IGltYWdlIGJ5IGEgY2VydGFpbiBhbW91bnQuCglAcGFyYW0gcGVyY2VudGFnZSBXaGVyZSAtMTAwIDw9IHBlcmNlbnRhZ2UgPD0gMTAwPGJyPgoJQSB2YWx1ZSAwIG1lYW5zIG5vIGNoYW5nZSwgbGVzcyB0aGFuIDAgd2lsbCBkZWNyZWFzZSB0aGUgY29udHJhc3QgCglhbmQgZ3JlYXRlciB0aGFuIDAgd2lsbCBpbmNyZWFzZSB0aGUgY29udHJhc3Qgb2YgdGhlIGltYWdlLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2VzZnVsbCwgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9BZGp1c3RDb250cmFzdCwgYWRqdXN0Q3VydmUKCSovCglCT09MIGFkanVzdENvbnRyYXN0KGRvdWJsZSBwZXJjZW50YWdlKTsKCgkvKioKCUFkanVzdHMgYW4gaW1hZ2UncyBicmlnaHRuZXNzLCBjb250cmFzdCBhbmQgZ2FtbWEgd2l0aGluIGEgc2luZ2xlIG9wZXJhdGlvbi4gCglJZiBtb3JlIHRoYW4gb25lIG9mIHRoZXNlIGltYWdlIGRpc3BsYXkgcHJvcGVydGllcyBuZWVkIHRvIGJlIGFkanVzdGVkLCAKCXVzaW5nIHRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIHByZWZlcnJlZCBvdmVyIGNhbGxpbmcgZWFjaCBhZGp1c3RtZW50IGZ1bmN0aW9uIHNlcGFyYXRlbHkuIAoJVGhhdCdzIHBhcnRpY3VsYXJseSB0cnVlIGZvciBodWdlIGltYWdlcyBvciBpZiBwZXJmb3JtYW5jZSBpcyBhbiBpc3N1ZS4gCglAc2VlIGFkanVzdEJyaWdodG5lc3MKCUBzZWUgYWRqdXN0Q29udHJhc3QKCUBzZWUgYWRqdXN0R2FtbWEKCUBzZWUgRnJlZUltYWdlX0FkanVzdENvbG9ycwoJKi8KCUJPT0wgYWRqdXN0QnJpZ2h0bmVzc0NvbnRyYXN0R2FtbWEoZG91YmxlIGJyaWdodG5lc3MsIGRvdWJsZSBjb250cmFzdCwgZG91YmxlIGdhbW1hKTsKCgkvKiogQGJyaWVmIENvbXB1dGVzIGltYWdlIGhpc3RvZ3JhbQoJCglGb3IgMjQtYml0IGFuZCAzMi1iaXQgaW1hZ2VzLCBoaXN0b2dyYW0gY2FuIGJlIGNvbXB1dGVkIGZyb20gcmVkLCBncmVlbiwgYmx1ZSBhbmQgCglibGFjayBjaGFubmVscy4gRm9yIDgtYml0IGltYWdlcywgaGlzdG9ncmFtIGlzIGNvbXB1dGVkIGZyb20gdGhlIGJsYWNrIGNoYW5uZWwuIE90aGVyIAoJYml0IGRlcHRoIGlzIG5vdCBzdXBwb3J0ZWQuCglAcGFyYW0gaGlzdG8gcG9pbnRlciB0byBhbiBoaXN0b2dyYW0gYXJyYXkuIDxiPlNpemUgb2YgdGhpcyBhcnJheSBpcyBhc3N1bWVkIHRvIGJlIDI1NjwvYj4uCglAcGFyYW0gY2hhbm5lbCBDb2xvciBjaGFubmVsIHRvIHVzZQoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2VzZnVsbCwgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9HZXRIaXN0b2dyYW0KCSovCglCT09MIGdldEhpc3RvZ3JhbShEV09SRCAqaGlzdG8sIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTCBjaGFubmVsID0gRklDQ19CTEFDSykgY29uc3Q7CgkvL0B9CgoJLyoqQG5hbWUgVXBzYW1wbGluZyAvIGRvd25zYW1wbGluZyAqLwoJLy9AewkKCgkvKiogQGJyaWVmIFJlc2NhbGUgdGhlIGltYWdlIHRvIGEgbmV3IHdpZHRoIC8gaGVpZ2h0LgoKCUBwYXJhbSBuZXdfd2lkdGggTmV3IGltYWdlIHdpZHRoCglAcGFyYW0gbmV3X2hlaWdodCBOZXcgaW1hZ2UgaGVpZ2h0CglAcGFyYW0gZmlsdGVyIFRoZSBmaWx0ZXIgcGFyYW1ldGVyIHNwZWNpZmllcyB3aGljaCByZXNhbXBsaW5nIGZpbHRlciBzaG91bGQgYmUgdXNlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHRoZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfUmVzY2FsZSwgRlJFRV9JTUFHRV9GSUxURVIKCSovCglCT09MIHJlc2NhbGUodW5zaWduZWQgbmV3X3dpZHRoLCB1bnNpZ25lZCBuZXdfaGVpZ2h0LCBGUkVFX0lNQUdFX0ZJTFRFUiBmaWx0ZXIpOwoKCS8qKiBAYnJpZWYgQ3JlYXRlcyBhIHRodW1ibmFpbCBpbWFnZSBrZWVwaW5nIGFzcGVjdCByYXRpbwoKCUBwYXJhbSBtYXhfc2l6ZSBNYXhpbXVtIHdpZHRoIG9yIGhlaWdodCBpbiBwaXhlbCB1bml0cwoJQHBhcmFtIGNvbnZlcnQgV2hlbiBzZXQgdG8gVFJVRSwgY29udmVydHMgdGhlIGltYWdlIHRvIGEgc3RhbmRhcmQgdHlwZQoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9NYWtlVGh1bWJuYWlsCgkqLwoJQk9PTCBtYWtlVGh1bWJuYWlsKHVuc2lnbmVkIG1heF9zaXplLCBCT09MIGNvbnZlcnQgPSBUUlVFKTsKCS8vQH0KCgkvKipAbmFtZSBJbWFnZSBzdGF0dXMgKi8KCS8vQHsJCgkvKioKCVNldCB0aGUgaW1hZ2Ugc3RhdHVzIGFzICdtb2RpZmllZCcuPGJyPgoJV2hlbiB1c2luZyB0aGUgZmlwV2luSW1hZ2UgY2xhc3MsIHRoZSBpbWFnZSBzdGF0dXMgaXMgdXNlZCB0byByZWZyZXNoIHRoZSBkaXNwbGF5LiAKCUl0IGlzIGNoYW5nZWQgdG8gRkFMU0Ugd2hlbmV2ZXIgdGhlIGRpc3BsYXkgaGFzIGp1c3QgYmVlbiByZWZyZXNoZWQuIAoJQHBhcmFtIGJTdGF0dXMgVFJVRSBpZiB0aGUgaW1hZ2Ugc2hvdWxkIGJlIG1hcmtlZCBhcyBtb2RpZmllZCwgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIGlzTW9kaWZpZWQKCSovCgl2b2lkIHNldE1vZGlmaWVkKEJPT0wgYlN0YXR1cyA9IFRSVUUpIHsKCQlfYkhhc0NoYW5nZWQgPSBiU3RhdHVzOwoJfQoKCS8qKgoJR2V0IHRoZSBpbWFnZSBzdGF0dXMKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHRoZSBpbWFnZSBpcyBtYXJrZWQgYXMgbW9kaWZpZWQsIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBzZXRNb2RpZmllZAoJKi8KCUJPT0wgaXNNb2RpZmllZCgpIHsKCQlyZXR1cm4gX2JIYXNDaGFuZ2VkOwoJfQoJLy9AfQoKCS8qKkBuYW1lIE1ldGFkYXRhICovCgkvL0B7CQoJLyoqCglSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGFncyBjb250YWluZWQgaW4gdGhlIDxpPm1vZGVsPC9pPiBtZXRhZGF0YSBtb2RlbCAKCWF0dGFjaGVkIHRvIHRoZSBkaWIKCUBwYXJhbSBtb2RlbCBNZXRhZGF0YSBtb2RlbCB0byBsb29rIGZvcgoJKi8KCXVuc2lnbmVkIGdldE1ldGFkYXRhQ291bnQoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsKSBjb25zdDsKCS8qKgoJUmV0cmlldmUgYSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZGliCglAcGFyYW0gbW9kZWwgTWV0YWRhdGEgbW9kZWwgdG8gbG9vayBmb3IKCUBwYXJhbSBrZXkgTWV0YWRhdGEgZmllbGQgbmFtZSAKCUBwYXJhbSB0YWcgUmV0dXJuZWQgdGFnCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNmdWxsLCBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0dldE1ldGFkYXRhCgkqLwoJQk9PTCBnZXRNZXRhZGF0YShGUkVFX0lNQUdFX01ETU9ERUwgbW9kZWwsIGNvbnN0IGNoYXIgKmtleSwgZmlwVGFnJiB0YWcpIGNvbnN0OwoJLyoqCglBdHRhY2ggYSBuZXcgRnJlZUltYWdlIHRhZyB0byB0aGUgZGliLjxicj4KCTxiPlNhbXBsZSB1c2U8L2I+IDogPGJyPgoJPHByZT4KCWZpcEltYWdlIGltYWdlOwoJLy8gLi4uCglmaXBUYWcgdGFnOwoJdGFnLnNldEtleVZhbHVlKCJDYXB0aW9uL0Fic3RyYWN0IiwgIm15IGNhcHRpb24iKTsKCWltYWdlLnNldE1ldGFkYXRhKEZJTURfSVBUQywgdGFnLmdldEtleSgpLCB0YWcpOwoJdGFnLnNldEtleVZhbHVlKCJLZXl3b3JkcyIsICJGcmVlSW1hZ2U7TGlicmFyeTtJbWFnZXM7Q29tcHJlc3Npb24iKTsKCWltYWdlLnNldE1ldGFkYXRhKEZJTURfSVBUQywgdGFnLmdldEtleSgpLCB0YWcpOwoJPC9wcmU+CgoJQHBhcmFtIG1vZGVsIE1ldGFkYXRhIG1vZGVsIHVzZWQgdG8gc3RvcmUgdGhlIHRhZwoJQHBhcmFtIGtleSBUYWcgZmllbGQgbmFtZSAKCUBwYXJhbSB0YWcgVGFnIHRvIGJlIGF0dGFjaGVkCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNmdWxsLCBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1NldE1ldGFkYXRhCgkqLwoJQk9PTCBzZXRNZXRhZGF0YShGUkVFX0lNQUdFX01ETU9ERUwgbW9kZWwsIGNvbnN0IGNoYXIgKmtleSwgZmlwVGFnJiB0YWcpOwoJLy9AfQoKCiAgcHJvdGVjdGVkOgoJLyoqQG5hbWUgSW50ZXJuYWwgdXNlICovCgkvL0B7CgkgIEJPT0wgcmVwbGFjZShGSUJJVE1BUCAqbmV3X2RpYik7CgkvL0B9Cgp9OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqIEEgY2xhc3MgZGVzaWduZWQgZm9yIE1TIFdpbmRvd3MgKFRNKSBwbGF0Zm9ybXMuCgogICAgZmlwV2luSW1hZ2UgcHJvdmlkZXMgbWV0aG9kcyB1c2VkIHRvIDoKCTx1bD4KCTxsaT5EaXNwbGF5IGEgRElCIG9uIHRoZSBzY3JlZW4KCTxsaT5Db3B5IC8gUGFzdGUgYSBESUIgdG8vZnJvbSBXaW5kb3dzIGRldmljZXMgKEhBTkRMRSwgSEJJVE1BUCwgQ2xpcGJvYXJkKQoJPGxpPkNhcHR1cmUgYSB3aW5kb3cgKEhXTkQpIGFuZCBjb252ZXJ0IGl0IHRvIGFuIGltYWdlCgk8L3VsPgoJQHZlcnNpb24gRnJlZUltYWdlIDMKCUBhdXRob3IgSGVydukgRHJvbG9uCiovCiNpZmRlZiBfV0lOMzIKCmNsYXNzIEZJUF9BUEkgZmlwV2luSW1hZ2UgOiBwdWJsaWMgZmlwSW1hZ2UKewpwdWJsaWM6CgkvKipAbmFtZSBDcmVhdGlvbiAmIERlc3RydWN0aW9uICovCgkvL0B7CQoJLy8vIENvbnN0cnVjdG9yCglmaXBXaW5JbWFnZShGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZJVF9CSVRNQVAsIHVuc2lnbmVkIHdpZHRoID0gMCwgdW5zaWduZWQgaGVpZ2h0ID0gMCwgdW5zaWduZWQgYnBwID0gMCk7CgoJLy8vIERlc3RydWN0b3IKCXZpcnR1YWwgfmZpcFdpbkltYWdlKCk7CgoJLy8vIERlc3Ryb3kgaW1hZ2UgZGF0YQoJdmlydHVhbCB2b2lkIGNsZWFyKCk7CgoJLy8vIFJldHVybnMgVFJVRSBpZiB0aGUgaW1hZ2UgaXMgYWxsb2NhdGVkLCBGQUxTRSBvdGhlcndpc2UKCUJPT0wgaXNWYWxpZCgpIGNvbnN0OwoJLy9AfQoKCS8qKkBuYW1lIENvcHlpbmcgKi8KCS8vQHsJCgoJLyoqCglDb3B5IGNvbnN0cnVjdG9yLiAKCURlbGV0ZSBpbnRlcm5hbCBfZGlzcGxheV9kaWIgZGF0YSBhbmQgY29weSB0aGUgYmFzZSBjbGFzcyBpbWFnZSBkYXRhLiAKCVRvbmUgbWFwcGluZyBwYXJhbWV0ZXJzIGFyZSBsZWZ0IHVuY2hhbmdlZC4gCglAc2VlIEZyZWVJbWFnZV9DbG9uZQoJKi8KCWZpcFdpbkltYWdlJiBvcGVyYXRvcj0oY29uc3QgZmlwSW1hZ2UmIHNyYyk7CgoJLyoqCglDb3B5IGNvbnN0cnVjdG9yCglEZWxldGUgaW50ZXJuYWwgX2Rpc3BsYXlfZGliIGRhdGEgYW5kIGNvcHkgdG9uZSBtYXBwaW5nIHBhcmFtZXRlcnMuIAoJQ29weSBhbHNvIHRoZSBiYXNlIGNsYXNzIGltYWdlIGRhdGEuIAoJQHNlZSBGcmVlSW1hZ2VfQ2xvbmUKCSovCglmaXBXaW5JbWFnZSYgb3BlcmF0b3I9KGNvbnN0IGZpcFdpbkltYWdlJiBzcmMpOwoKCS8qKiBDbG9uZSBmdW5jdGlvbiB1c2VkIGZvciBjbGlwYm9hcmQgY29weS48YnI+CglDb252ZXJ0IHRoZSBGSUJJVE1BUCBpbWFnZSB0byBhIERJQiwgCglhbmQgdHJhbnNmZXIgdGhlIERJQiBpbiBhIGdsb2JhbCBiaXRtYXAgaGFuZGxlLjxicj4KCUZvciBub24gc3RhbmRhcmQgYml0bWFwcywgdGhlIEJJVE1BUElORk9IRUFERVItPmJpQ29tcHJlc3Npb24gZmllbGQgaXMgc2V0IHRvIDB4RkYgKyBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKF9kaWIpLCAKCWluIG9yZGVyIHRvIHJlY29nbml6ZSB0aGUgYml0bWFwIGFzIG5vbiBzdGFuZGFyZC4gCgkqLwoJSEFORExFIGNvcHlUb0hhbmRsZSgpIGNvbnN0OwoKCS8qKiBDb3B5IGNvbnN0cnVjdG9yIHVzZWQgZm9yIGNsaXBib2FyZCBwYXN0ZS48YnI+CglDb252ZXJ0cyBhIGdsb2JhbCBvYmplY3QgdG8gYSBGSUJJVE1BUC4gVGhlIGNsaXBib2FyZCBmb3JtYXQgbXVzdCBiZSBDRl9ESUIuPGJyPgoJV2hlbiB0aGUgQklUTUFQSU5GT0hFQURFUi0+YmlDb21wcmVzc2lvbiBmaWVsZCBpcyBzZXQgdG8gMHhGRiArIFtvbmUgb2YgdGhlIHByZWRlZmluZWQgRlJFRV9JTUFHRV9UWVBFXSwgCgl0aGUgYml0bWFwIGlzIHJlY29nbml6ZWQgYXMgbm9uIHN0YW5kYXJkIGFuZCBjb3JyZWN0bHkgY29waWVkLiAKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCgkqLwoJQk9PTCBjb3B5RnJvbUhhbmRsZShIQU5ETEUgaE1lbSk7CgoJLyoqIENvcHkgY29uc3RydWN0b3IuPGJyPgoJQ29udmVydHMgYSBIQklUTUFQIG9iamVjdCB0byBhIEZJQklUTUFQLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCSovCglCT09MIGNvcHlGcm9tQml0bWFwKEhCSVRNQVAgaGJtcCk7CgkvL0B9CgoJLyoqQG5hbWUgQ2xpcGJvYXJkIG9wZXJhdGlvbnMgKi8KCS8vQHsJCgkvKioKCUNsaXBib2FyZCBjb3B5LgoJQHBhcmFtIGhXbmROZXdPd25lciBIYW5kbGUgdG8gdGhlIHdpbmRvdyB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIG9wZW4gY2xpcGJvYXJkLiAKCUluIE1GQywgeW91IGNhbiB1c2UgQWZ4R2V0QXBwKCktPm1fcE1haW5XbmQtPkdldFNhZmVId25kKCkuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJKi8KCUJPT0wgY29weVRvQ2xpcGJvYXJkKEhXTkQgaFduZE5ld093bmVyKSBjb25zdDsKCgkvKioKCVJldHJpZXZlcyBkYXRhIGZyb20gdGhlIGNsaXBib2FyZC4gVGhlIGNsaXBib2FyZCBmb3JtYXQgbXVzdCBiZSBDRl9ESUIuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJKi8KCUJPT0wgcGFzdGVGcm9tQ2xpcGJvYXJkKCk7CgkvL0B9CgoJLyoqQG5hbWUgU2NyZWVuIGNhcHR1cmUgKi8KCS8vQHsJCgkvKiogQ2FwdHVyZSBhIHdpbmRvdyBhbmQgY29udmVydCBpdCB0byBhbiBpbWFnZQoJQHBhcmFtIGhXbmRBcHBsaWNhdGlvbldpbmRvdyBIYW5kbGUgdG8gdGhlIGFwcGxpY2F0aW9uIG1haW4gd2luZG93CglAcGFyYW0gaFduZFNlbGVjdGVkV2luZG93IEhhbmRsZSB0byB0aGUgd2luZG93IHRvIGJlIGNhcHR1cmVkCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJKi8KCUJPT0wgY2FwdHVyZVdpbmRvdyhIV05EIGhXbmRBcHBsaWNhdGlvbldpbmRvdywgSFdORCBoV25kU2VsZWN0ZWRXaW5kb3cpOwoJLy9AfQoKCgkvKipAbmFtZSBQYWludGluZyBvcGVyYXRpb25zICovCgkvL0B7CQoKCS8qKiBAYnJpZWYgRHJhdyAoc3RyZXRjaCkgdGhlIGltYWdlIG9uIGEgSERDLCB1c2luZyBTdHJldGNoRElCaXRzLgoKICAgIFdoZW4gdGhlIGltYWdlIGlzIHRyYW5zcGFyZW50IG9yIGhhcyBhIGZpbGUgYmFja2dyb3VuZCwgdGhpcyBmdW5jdGlvbiBjb21wb3NpdGUgCgl0aGUgZm9yZWdyb3VuZCBpbWFnZSBhZ2FpbnN0IGEgY2hlY2tlcmJvYXJkIGJhY2tncm91bmQgaW1hZ2UuCglAcGFyYW0gaERDIEhhbmRsZSB0byB0aGUgZGV2aWNlIGNvbnRleHQKCUBwYXJhbSByY0Rlc3QgRGVzdGluYXRpb24gcmVjdGFuZ2xlCglAc2VlIEZyZWVJbWFnZV9Db21wb3NpdGUKCSovCgl2b2lkIGRyYXcoSERDIGhEQywgUkVDVCYgcmNEZXN0KSBjb25zdCB7CgkJZHJhd0V4KGhEQywgcmNEZXN0LCBGQUxTRSwgTlVMTCwgTlVMTCk7Cgl9CgoJLyoqIEBicmllZiBEcmF3IChzdHJldGNoKSB0aGUgaW1hZ2Ugb24gYSBIREMsIHVzaW5nIFN0cmV0Y2hESUJpdHMuCgogICAgV2hlbiB0aGUgaW1hZ2UgaXMgdHJhbnNwYXJlbnQgb3IgaGFzIGEgZmlsZSBiYWNrZ3JvdW5kLCB0aGlzIGZ1bmN0aW9uIGNhbiBjb21wb3NpdGUgCgl0aGUgZm9yZWdyb3VuZCBpbWFnZSBhZ2FpbnN0IGEgY2hlY2tlcmJvYXJkIGJhY2tncm91bmQgaW1hZ2UsIGFnYWluc3QgYSBzaW5nbGUgYmFja2dyb3VuZCBjb2xvciBvciAKCWFnYWluc3QgYSB1c2VyIGJhY2tncm91bmQgaW1hZ2UuPGJyPgoJV2hlbiB0aGUgaW1hZ2UgaXMgYSBIaWdoIER5bmFtaWMgUmFuZ2UgaW1hZ2UgKDQ4LWJpdCBvciBSR0IgZmxvYXQpLCB0aGlzIGZ1bmN0aW9uIHdpbGwgYXBwbHkgYSAKCXRvbmUgbWFwcGluZyBvcGVyYXRvciBiZWZvcmUgZHJhd2luZyB0aGUgaW1hZ2UuPGJyPgoJVGhlIG9yaWdpbmFsIGltYWdlIChsb2NhdGVkIGluIHRoZSBmaXBJbWFnZSBjbGFzcykgd2lsbCBub3QgYmUgYWZmZWN0ZWQgYnkgYW55IG9mIHRoZSBvcGVyYXRpb25zIAoJdGhhdCBjb3VsZCBiZSBkb25lIGluIG9yZGVyIHRvIGRpc3BsYXkgaXQuIAoJQHBhcmFtIGhEQyBIYW5kbGUgdG8gdGhlIGRldmljZSBjb250ZXh0CglAcGFyYW0gcmNEZXN0IERlc3RpbmF0aW9uIHJlY3RhbmdsZQoJQHBhcmFtIHVzZUZpbGVCa2cgV2hlbiBzZXQgdG8gVFJVRSwgdGhlIGZ1bmN0aW9uIHVzZXMgdGhlIGZpbGUgY29sb3IgYmFja2dyb3VuZCBpZiB0aGVyZSBpcyBvbmUKCUBwYXJhbSBhcHBCa0NvbG9yIFdoZW4gYSBjb2xvciBpcyBnaXZlbiwgdGhlIGZ1bmN0aW9uIHVzZXMgaXQgYXMgdGhlIGJhY2tncm91bmQgY29sb3IKCUBwYXJhbSBiZyBXaGVuIGEgRklCSVRNQVAgaXMgZ2l2ZW4sIHRoZSBmdW5jdGlvbiB1c2VzIGl0IGFzIHRoZSBiYWNrZ3JvdW5kIGltYWdlCglAc2VlIEZyZWVJbWFnZV9Db21wb3NpdGUKCUBzZWUgc2V0VG9uZU1hcHBpbmdPcGVyYXRvcgoJKi8KCXZvaWQgZHJhd0V4KEhEQyBoREMsIFJFQ1QmIHJjRGVzdCwgQk9PTCB1c2VGaWxlQmtnID0gRkFMU0UsIFJHQlFVQUQgKmFwcEJrQ29sb3IgPSBOVUxMLCBGSUJJVE1BUCAqYmcgPSBOVUxMKSBjb25zdDsKCgkvKioKCVNlbGVjdCBhIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gdXNlZCBmb3IgZHJhd2luZyBhbmQgc2V0IHRoZSBpbWFnZSBhcyBtb2RpZmllZCAKCXNvIHRoYXQgdGhlIGRpc3BsYXkgd2lsbCBiZSByZWZyZXNoZWQuCglAcGFyYW0gdG1vIFRvbmUgbWFwcGluZyBvcGVyYXRvcgoJQHBhcmFtIGZpcnN0X3BhcmFtIEZpcnN0IHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglAcGFyYW0gc2Vjb25kX3BhcmFtIFNlY29uZCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcgoJQHBhcmFtIHRoaXJkX3BhcmFtIFRoaXJkIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglAcGFyYW0gZm91cnRoX3BhcmFtIEZvdXJ0aCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcgoJQHNlZSBGcmVlSW1hZ2VfVG9uZU1hcHBpbmcKCSovCgl2b2lkIHNldFRvbmVNYXBwaW5nT3BlcmF0b3IoRlJFRV9JTUFHRV9UTU8gdG1vLCBkb3VibGUgZmlyc3RfcGFyYW0gPSAwLCBkb3VibGUgc2Vjb25kX3BhcmFtID0gMCwgZG91YmxlIHRoaXJkX3BhcmFtID0gMSwgZG91YmxlIGZvdXJ0aF9wYXJhbSA9IDApOwoKCS8qKgoJR2V0IHRoZSB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHVzZWQgZm9yIGRyYXdpbmcsIHdpdGggaXRzIHBhcmFtZXRlcnMuCglAcGFyYW0gdG1vIFRvbmUgbWFwcGluZyBvcGVyYXRvcgoJQHBhcmFtIGZpcnN0X3BhcmFtIEZpcnN0IHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglAcGFyYW0gc2Vjb25kX3BhcmFtIFNlY29uZCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcgoJQHBhcmFtIHRoaXJkX3BhcmFtIFRoaXJkIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglAcGFyYW0gZm91cnRoX3BhcmFtIEZvdXJ0aCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcgoJQHNlZSBGcmVlSW1hZ2VfVG9uZU1hcHBpbmcKCSovCgl2b2lkIGdldFRvbmVNYXBwaW5nT3BlcmF0b3IoRlJFRV9JTUFHRV9UTU8gKnRtbywgZG91YmxlICpmaXJzdF9wYXJhbSwgZG91YmxlICpzZWNvbmRfcGFyYW0sIGRvdWJsZSAqdGhpcmRfcGFyYW0sIGRvdWJsZSAqZm91cnRoX3BhcmFtKSBjb25zdDsKCgkvL0B9Cgpwcm90ZWN0ZWQ6CgkvLy8gRElCIHVzZWQgZm9yIGRpc3BsYXkgKHRoaXMgYWxsb3cgdG8gZGlzcGxheSBub24tc3RhbmRhcmQgYml0bWFwcykKCW11dGFibGUgRklCSVRNQVAgKl9kaXNwbGF5X2RpYjsKCS8vLyByZW1lbWJlciB0byBkZWxldGUgX2Rpc3BsYXlfZGliCgltdXRhYmxlIEJPT0wgX2JEZWxldGVNZTsKCS8vLyB0b25lIG1hcHBpbmcgb3BlcmF0b3IKCUZSRUVfSU1BR0VfVE1PIF90bW87CgkvLy8gZmlyc3QgdG9uZSBtYXBwaW5nIGFsZ29yaXRobSBwYXJhbWV0ZXIKCWRvdWJsZSBfdG1vX3BhcmFtXzE7CgkvLy8gc2Vjb25kIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglkb3VibGUgX3Rtb19wYXJhbV8yOwoJLy8vIHRoaXJkIHRvbmUgbWFwcGluZyBhbGdvcml0aG0gcGFyYW1ldGVyCglkb3VibGUgX3Rtb19wYXJhbV8zOwoJLy8vIGZvdXJ0aCB0b25lIG1hcHBpbmcgYWxnb3JpdGhtIHBhcmFtZXRlcgoJZG91YmxlIF90bW9fcGFyYW1fNDsKfTsKCiNlbmRpZiAvLyBfV0lOMzIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKiBNZW1vcnkgaGFuZGxlCgkKCWZpcE1lbW9yeUlPIGlzIGEgY2xhc3MgdGhhdCBhbGxvd3MgeW91IHRvIGxvYWQgLyBzYXZlIGltYWdlcyBmcm9tIC8gdG8gYSBtZW1vcnkgc3RyZWFtLgoJQHZlcnNpb24gRnJlZUltYWdlIDMKCUBhdXRob3IgSGVydukgRHJvbG9uCiovCmNsYXNzIEZJUF9BUEkgZmlwTWVtb3J5SU8gOiBwdWJsaWMgZmlwT2JqZWN0CnsKcHJvdGVjdGVkOgoJLy8vIFBvaW50ZXIgdG8gYSBtZW1vcnkgc3RyZWFtCglGSU1FTU9SWSAqX2htZW07CgpwdWJsaWMgOgoJLyoqIENvbnN0cnVjdG9yLgoJV3JhcCBhIG1lbW9yeSBidWZmZXIgY29udGFpbmluZyBpbWFnZSBkYXRhLjxicj4KCVRoZSBtZW1vcnkgYnVmZmVyIGlzIHJlYWQgb25seSBhbmQgaGFzIHRvIGJlIGZyZWVkIGJ5IHRoZSB1c2VyIAoJd2hlbiBubyBsb25nZXIgaW4gdXNlLjxicj4KCVdoZW4gZGVmYXVsdCBhcmd1bWVudHMgYXJlIHVzZWQsIG9wZW4gYSBtZW1vcnkgZmlsZSBhcyByZWFkL3dyaXRlLiAKCUBwYXJhbSBkYXRhIFBvaW50ZXIgdG8gdGhlIG1lbW9yeSBidWZmZXIKCUBwYXJhbSBzaXplX2luX2J5dGVzIEJ1ZmZlciBzaXplIGluIGJ5dGVzCglAc2VlIEZyZWVJbWFnZV9PcGVuTWVtb3J5CgkqLwogICAgZmlwTWVtb3J5SU8oQllURSAqZGF0YSA9IE5VTEwsIERXT1JEIHNpemVfaW5fYnl0ZXMgPSAwKTsKCgkvKiogRGVzdHJ1Y3Rvci4KCUZyZWUgYW55IGFsbG9jYXRlZCBtZW1vcnkKCUBzZWUgRnJlZUltYWdlX0Nsb3NlTWVtb3J5CgkqLwoJdmlydHVhbCB+ZmlwTWVtb3J5SU8oKTsKCgkvKiogRGVzdHJ1Y3Rvci4KCUZyZWUgYW55IGFsbG9jYXRlZCBtZW1vcnkgYW5kIGludmFsaWRhdGUgdGhlIHN0cmVhbQoJQHNlZSBGcmVlSW1hZ2VfQ2xvc2VNZW1vcnkKCSovCgl2b2lkIGNsb3NlKCk7CgoJLyoqIFJldHVybnMgVFJVRSBpZiB0aGUgaW50ZXJuYWwgbWVtb3J5IGJ1ZmZlciBpcyBhIHZhbGlkIGJ1ZmZlciwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCSovCglCT09MIGlzVmFsaWQoKSBjb25zdDsKCgkvKiogUmV0dXJucyB0aGUgYnVmZmVyIGltYWdlIGZvcm1hdAoJQHNlZSBGcmVlSW1hZ2VfR2V0RmlsZVR5cGVGcm9tTWVtb3J5CgkqLwoJRlJFRV9JTUFHRV9GT1JNQVQgZ2V0RmlsZVR5cGUoKSBjb25zdDsKCgkvKioKCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBGSU1FTU9SWSBkYXRhLiBVc2VkIGZvciBkaXJlY3QgYWNjZXNzIGZyb20gRlJFRUlNQUdFIGZ1bmN0aW9ucyAKCW9yIGZyb20geW91ciBvd24gbG93IGxldmVsIEMgZnVuY3Rpb25zLgoJKi8KCW9wZXJhdG9yIEZJTUVNT1JZKigpIHsgCgkJcmV0dXJuIF9obWVtOyAKCX0KCgkvKipAbmFtZSBNZW1vcnkgSU8gcm91dGluZXMgKi8KCS8vQHsJCgkvKioKCUxvYWRzIGEgZGliIGZyb20gYSBtZW1vcnkgc3RyZWFtCglAcGFyYW0gZmlmIEZvcm1hdCBpZGVudGlmaWVyIChGcmVlSW1hZ2UgZm9ybWF0KQoJQHBhcmFtIGZsYWdzIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBsb2FkZWQuCglAcmV0dXJuIFJldHVybnMgdGhlIGxvYWRlZCBkaWIgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfTG9hZEZyb21NZW1vcnkKCSovCglGSUJJVE1BUCogbG9hZChGUkVFX0lNQUdFX0ZPUk1BVCBmaWYsIGludCBmbGFncyA9IDApIGNvbnN0OwoJLyoqCglMb2FkcyBhIG11bHRpLXBhZ2UgYml0bWFwIGZyb20gYSBtZW1vcnkgc3RyZWFtCglAcGFyYW0gZmlmIEZvcm1hdCBpZGVudGlmaWVyIChGcmVlSW1hZ2UgZm9ybWF0KQoJQHBhcmFtIGZsYWdzIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBtdWx0aS1wYWdlIHRvIGJlIGxvYWRlZC4KCUByZXR1cm4gUmV0dXJucyB0aGUgbG9hZGVkIG11bHRpLXBhZ2UgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfTG9hZE11bHRpQml0bWFwRnJvbU1lbW9yeQoJKi8KCUZJTVVMVElCSVRNQVAqIGxvYWRNdWx0aVBhZ2UoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBpbnQgZmxhZ3MgPSAwKSBjb25zdDsKCS8qKgoJU2F2ZXMgYSBkaWIgdG8gYSBtZW1vcnkgc3RyZWFtCglAcGFyYW0gZmlmIEZvcm1hdCBpZGVudGlmaWVyIChGcmVlSW1hZ2UgZm9ybWF0KQoJQHBhcmFtIGRpYiBJbWFnZSB0byBiZSBzYXZlZAoJQHBhcmFtIGZsYWdzIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBzYXZlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9TYXZlVG9NZW1vcnkKCSovCglCT09MIHNhdmUoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBGSUJJVE1BUCAqZGliLCBpbnQgZmxhZ3MgPSAwKTsKCS8qKgoJU2F2ZXMgYSBtdWx0aS1wYWdlIGJpdG1hcCB0byBhIG1lbW9yeSBzdHJlYW0KCUBwYXJhbSBmaWYgRm9ybWF0IGlkZW50aWZpZXIgKEZyZWVJbWFnZSBmb3JtYXQpCglAcGFyYW0gYml0bWFwIE11bHRpLXBhZ2UgaW1hZ2UgdG8gYmUgc2F2ZWQKCUBwYXJhbSBmbGFncyBUaGUgc2lnbmlmaWNhdGlvbiBvZiB0aGlzIGZsYWcgZGVwZW5kcyBvbiB0aGUgaW1hZ2UgdG8gYmUgc2F2ZWQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfU2F2ZU11bHRpQml0bWFwVG9NZW1vcnkKCSovCglCT09MIHNhdmVNdWx0aVBhZ2UoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBGSU1VTFRJQklUTUFQICpiaXRtYXAsIGludCBmbGFncyA9IDApOwoJLyoqCglSZWFkcyBkYXRhIGZyb20gYSBtZW1vcnkgc3RyZWFtCglAcGFyYW0gYnVmZmVyIFN0b3JhZ2UgbG9jYXRpb24gZm9yIGRhdGEKCUBwYXJhbSBzaXplIEl0ZW0gc2l6ZSBpbiBieXRlcwoJQHBhcmFtIGNvdW50IE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGJlIHJlYWQKCUByZXR1cm4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGZ1bGwgaXRlbXMgYWN0dWFsbHkgcmVhZCwgd2hpY2ggbWF5IGJlIGxlc3MgdGhhbiBjb3VudCBpZiBhbiBlcnJvciBvY2N1cnMKCUBzZWUgRnJlZUltYWdlX1JlYWRNZW1vcnkKCSovCgl1bnNpZ25lZCByZWFkKHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgc2l6ZSwgdW5zaWduZWQgY291bnQpIGNvbnN0OwoJLyoqCglXcml0ZXMgZGF0YSB0byBhIG1lbW9yeSBzdHJlYW0KCUBwYXJhbSBidWZmZXIgUG9pbnRlciB0byBkYXRhIHRvIGJlIHdyaXR0ZW4KCUBwYXJhbSBzaXplIEl0ZW0gc2l6ZSBpbiBieXRlcwoJQHBhcmFtIGNvdW50IE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGJlIHdyaXR0ZW4KCUByZXR1cm4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGZ1bGwgaXRlbXMgYWN0dWFsbHkgd3JpdHRlbiwgd2hpY2ggbWF5IGJlIGxlc3MgdGhhbiBjb3VudCBpZiBhbiBlcnJvciBvY2N1cnMKCUBzZWUgRnJlZUltYWdlX1dyaXRlTWVtb3J5CgkqLwoJdW5zaWduZWQgd3JpdGUoY29uc3Qgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBzaXplLCB1bnNpZ25lZCBjb3VudCk7CgkvKioKCUdldHMgdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgYSBtZW1vcnkgcG9pbnRlcgoJQHNlZSBGcmVlSW1hZ2VfVGVsbE1lbW9yeQoJKi8KCWxvbmcgdGVsbCgpIGNvbnN0OwoJLyoqCglNb3ZlcyB0aGUgbWVtb3J5IHBvaW50ZXIgdG8gYSBzcGVjaWZpZWQgbG9jYXRpb24KCUBzZWUgRnJlZUltYWdlX1NlZWtNZW1vcnkKCSovCglCT09MIHNlZWsobG9uZyBvZmZzZXQsIGludCBvcmlnaW4pOwoJLyoqCglQcm92aWRlcyBhIGRpcmVjdCBidWZmZXIgYWNjZXNzIHRvIGEgbWVtb3J5IHN0cmVhbQoJQHBhcmFtIGRhdGEgUG9pbnRlciB0byB0aGUgbWVtb3J5IGJ1ZmZlciAocmV0dXJuZWQgdmFsdWUpCglAcGFyYW0gc2l6ZV9pbl9ieXRlcyBCdWZmZXIgc2l6ZSBpbiBieXRlcyAocmV0dXJuZWQgdmFsdWUpCglAc2VlIEZyZWVJbWFnZV9BY3F1aXJlTWVtb3J5CgkqLwoJQk9PTCBhY3F1aXJlKEJZVEUgKipkYXRhLCBEV09SRCAqc2l6ZV9pbl9ieXRlcyk7CgkvL0B9Cgpwcml2YXRlOgoJLy8vIERpc2FibGUgY29weQoJZmlwTWVtb3J5SU8oY29uc3QgZmlwTWVtb3J5SU8mIHNyYyk7CgkvLy8gRGlzYWJsZSBjb3B5CglmaXBNZW1vcnlJTyYgb3BlcmF0b3I9KGNvbnN0IGZpcE1lbW9yeUlPJiBzcmMpOwoKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKiBNdWx0aS1wYWdlIGZpbGUgc3RyZWFtCgoJZmlwTXVsdGlQYWdlIGVuY2Fwc3VsYXRlcyB0aGUgbXVsdGktcGFnZSBBUEkuIEl0IHN1cHBvcnRzIHJlYWRpbmcvd3JpdGluZyAKCW11bHRpLXBhZ2UgVElGRiwgSUNPIGFuZCBHSUYgZmlsZXMuIAoqLwpjbGFzcyBGSVBfQVBJIGZpcE11bHRpUGFnZSA6IHB1YmxpYyBmaXBPYmplY3QgCnsKcHJvdGVjdGVkOgoJLy8vIFBvaW50ZXIgdG8gYSBtdWx0aS1wYWdlIGZpbGUgc3RyZWFtCglGSU1VTFRJQklUTUFQICpfbXBhZ2U7CgkvLy8gVFJVRSB3aGVuIHVzaW5nIGEgbWVtb3J5IGNhY2hlLCBGQUxTRSBvdGhlcndpc2UKCUJPT0wgX2JNZW1vcnlDYWNoZTsKCnB1YmxpYzoKCS8qKgoJQ29uc3RydWN0b3IKCUBwYXJhbSBrZWVwX2NhY2hlX2luX21lbW9yeSBXaGVuIGl0IGlzIFRSVUUsIGFsbCBnYXRoZXJlZCBiaXRtYXAgZGF0YSBpbiB0aGUgcGFnZSBtYW5pcHVsYXRpb24gcHJvY2VzcyBpcyBrZXB0IGluIG1lbW9yeSwgb3RoZXJ3aXNlIGl0IGlzIGxhemlseSBmbHVzaGVkIHRvIGEgdGVtcG9yYXJ5IGZpbGUgb24gdGhlIGhhcmQgZGlzayBpbiA2NCBLYiBibG9ja3MuCgkqLwoJZmlwTXVsdGlQYWdlKEJPT0wga2VlcF9jYWNoZV9pbl9tZW1vcnkgPSBGQUxTRSk7CgoJLyoqCglEZXN0cnVjdG9yCglDbG9zZSB0aGUgZmlsZSBzdHJlYW0gaWYgbm90IGFscmVhZHkgZG9uZS4gCgkqLwoJdmlydHVhbCB+ZmlwTXVsdGlQYWdlKCk7CgoJLy8vIFJldHVybnMgVFJVRSBpZiB0aGUgbXVsdGktcGFnZSBzdHJlYW0gaXMgb3BlbmVkCglCT09MIGlzVmFsaWQoKSBjb25zdDsKCgkvKioKCVJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBGSU1VTFRJQklUTUFQIGRhdGEuIFVzZWQgZm9yIGRpcmVjdCBhY2Nlc3MgZnJvbSBGUkVFSU1BR0UgZnVuY3Rpb25zIAoJb3IgZnJvbSB5b3VyIG93biBsb3cgbGV2ZWwgQyBmdW5jdGlvbnMuCgkqLwoJb3BlcmF0b3IgRklNVUxUSUJJVE1BUCooKSB7IAoJCXJldHVybiBfbXBhZ2U7IAoJfQoKCS8qKgoJT3BlbiBhIG11bHRpLXBhZ2UgZmlsZSBzdHJlYW0KCUBwYXJhbSBscHN6UGF0aE5hbWUgTmFtZSBvZiB0aGUgbXVsdGktcGFnZSBiaXRtYXAgZmlsZQoJQHBhcmFtIGNyZWF0ZV9uZXcgV2hlbiBUUlVFLCBpdCBtZWFucyB0aGF0IGEgbmV3IGJpdG1hcCB3aWxsIGJlIGNyZWF0ZWQgcmF0aGVyIHRoYW4gYW4gZXhpc3Rpbmcgb25lIGJlaW5nIG9wZW5lZAoJQHBhcmFtIHJlYWRfb25seSBXaGVuIFRSVUUgdGhlIGJpdG1hcCBpcyBvcGVuZWQgcmVhZC1vbmx5CglAcGFyYW0gZmxhZ3MgTG9hZCBmbGFncy4gVGhlIHNpZ25pZmljYXRpb24gb2YgdGhpcyBmbGFnIGRlcGVuZHMgb24gdGhlIGltYWdlIHRvIGJlIGxvYWRlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9PcGVuTXVsdGlCaXRtYXAKCSovCglCT09MIG9wZW4oY29uc3QgY2hhciogbHBzelBhdGhOYW1lLCBCT09MIGNyZWF0ZV9uZXcsIEJPT0wgcmVhZF9vbmx5LCBpbnQgZmxhZ3MgPSAwKTsKCgkvKioKCU9wZW4gYSBtdWx0aS1wYWdlIG1lbW9yeSBzdHJlYW0gYXMgcmVhZC93cml0ZS4gCglAcGFyYW0gbWVtSU8gTWVtb3J5IHN0cmVhbS4gVGhlIG1lbW9yeSBzdHJlYW0gTVVTVCBCRSBhIHdyYXBwZWQgdXNlciBidWZmZXIuIAoJQHBhcmFtIGZsYWdzIExvYWQgZmxhZ3MuIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBsb2FkZWQuCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfTG9hZE11bHRpQml0bWFwRnJvbU1lbW9yeQoJKi8KCUJPT0wgb3BlbihmaXBNZW1vcnlJTyYgbWVtSU8sIGludCBmbGFncyA9IDApOwoKCS8qKgoJT3BlbiBhIG11bHRpLXBhZ2UgaW1hZ2UgYXMgcmVhZC93cml0ZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBGcmVlSW1hZ2VJTyBzdHJ1Y3QgYW5kIGZpX2hhbmRsZSwgYW5kIGFuIG9wdGlvbmFsIGZsYWcuCglAcGFyYW0gaW8gRnJlZUltYWdlSU8gc3RydWN0dXJlCglAcGFyYW0gaGFuZGxlIEZyZWVJbWFnZSBmaV9oYW5kbGUKCUBwYXJhbSBmbGFnIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSByZWFkLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoJQHNlZSBGcmVlSW1hZ2VfT3Blbk11bHRpQml0bWFwRnJvbUhhbmRsZQoJKi8KCUJPT0wgb3BlbihGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBmbGFncyA9IDApOwoKCS8qKgoJQ2xvc2UgYSBmaWxlIHN0cmVhbQoJQHBhcmFtIGZsYWdzIFNhdmUgZmxhZ3MuIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBzYXZlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9DbG9zZU11bHRpQml0bWFwCgkqLwoJQk9PTCBjbG9zZShpbnQgZmxhZ3MgPSAwKTsKCgkvKioKCVNhdmVzIGEgbXVsdGktcGFnZSBpbWFnZSB1c2luZyB0aGUgc3BlY2lmaWVkIEZyZWVJbWFnZUlPIHN0cnVjdCBhbmQgZmlfaGFuZGxlLCBhbmQgYW4gb3B0aW9uYWwgZmxhZy4KCUBwYXJhbSBmaWYgRm9ybWF0IGlkZW50aWZpZXIgKEZyZWVJbWFnZSBmb3JtYXQpCglAcGFyYW0gaW8gRnJlZUltYWdlSU8gc3RydWN0dXJlCglAcGFyYW0gaGFuZGxlIEZyZWVJbWFnZSBmaV9oYW5kbGUKCUBwYXJhbSBmbGFnIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBtdWx0aS1wYWdlIGltYWdlIHRvIGJlIHNhdmVkLgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgoJQHNlZSBGcmVlSW1hZ2VfU2F2ZU11bHRpQml0bWFwVG9IYW5kbGUsIEZyZWVJbWFnZSBkb2N1bWVudGF0aW9uCgkqLwoJQk9PTCBzYXZlVG9IYW5kbGUoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBmbGFncyA9IDApIGNvbnN0OwoKCS8qKgoJU2F2ZXMgYSBtdWx0aS1wYWdlIGltYWdlIHVzaW5nIHRoZSBzcGVjaWZpZWQgbWVtb3J5IHN0cmVhbSBhbmQgYW4gb3B0aW9uYWwgZmxhZy4KCUBwYXJhbSBmaWYgRm9ybWF0IGlkZW50aWZpZXIgKEZyZWVJbWFnZSBmb3JtYXQpCglAcGFyYW0gbWVtSU8gRnJlZUltYWdlIG1lbW9yeSBzdHJlYW0KCUBwYXJhbSBmbGFnIFRoZSBzaWduaWZpY2F0aW9uIG9mIHRoaXMgZmxhZyBkZXBlbmRzIG9uIHRoZSBpbWFnZSB0byBiZSBzYXZlZC4KCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KCUBzZWUgRnJlZUltYWdlX1NhdmVNdWx0aUJpdG1hcFRvTWVtb3J5LCBGcmVlSW1hZ2UgZG9jdW1lbnRhdGlvbgoJKi8KCUJPT0wgc2F2ZVRvTWVtb3J5KEZSRUVfSU1BR0VfRk9STUFUIGZpZiwgZmlwTWVtb3J5SU8mIG1lbUlPLCBpbnQgZmxhZ3MgPSAwKSBjb25zdDsKCgkvKioKCVJldHVybnMgdGhlIG51bWJlciBvZiBwYWdlcyBjdXJyZW50bHkgYXZhaWxhYmxlIGluIHRoZSBtdWx0aS1wYWdlZCBiaXRtYXAKCUBzZWUgRnJlZUltYWdlX0dldFBhZ2VDb3VudAoJKi8KCWludCBnZXRQYWdlQ291bnQoKSBjb25zdDsKCgkvKioKCUFwcGVuZHMgYSBuZXcgcGFnZSB0byB0aGUgZW5kIG9mIHRoZSBiaXRtYXAKCUBwYXJhbSBpbWFnZSBJbWFnZSB0byBhcHBlbmQKCUBzZWUgRnJlZUltYWdlX0FwcGVuZFBhZ2UKCSovCgl2b2lkIGFwcGVuZFBhZ2UoZmlwSW1hZ2UmIGltYWdlKTsKCgkvKioKCUluc2VydHMgYSBuZXcgcGFnZSBiZWZvcmUgdGhlIGdpdmVuIHBvc2l0aW9uIGluIHRoZSBiaXRtYXAKCUBwYXJhbSBwYWdlIFBhZ2UgbnVtYmVyLiBQYWdlIGhhcyB0byBiZSBhIG51bWJlciBzbWFsbGVyIHRoYW4gdGhlIGN1cnJlbnQgbnVtYmVyIG9mIHBhZ2VzIGF2YWlsYWJsZSBpbiB0aGUgYml0bWFwLgoJQHBhcmFtIGltYWdlIEltYWdlIHRvIGluc2VydAoJQHNlZSBGcmVlSW1hZ2VfSW5zZXJ0UGFnZQoJKi8KCXZvaWQgaW5zZXJ0UGFnZShpbnQgcGFnZSwgZmlwSW1hZ2UmIGltYWdlKTsKCgkvKioKCURlbGV0ZXMgdGhlIHBhZ2Ugb24gdGhlIGdpdmVuIHBvc2l0aW9uCglAcGFyYW0gcGFnZSBQYWdlIG51bWJlcgoJQHNlZSBGcmVlSW1hZ2VfRGVsZXRlUGFnZQoJKi8KCXZvaWQgZGVsZXRlUGFnZShpbnQgcGFnZSk7CgoJLyoqCglNb3ZlcyB0aGUgc291cmNlIHBhZ2UgdG8gdGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgcGFnZS4gCglAcGFyYW0gdGFyZ2V0IFRhcmdldCBwYWdlIHBvc2l0aW9uCglAcGFyYW0gc291cmNlIFNvdXJjZSBwYWdlIHBvc2l0aW9uCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfTW92ZVBhZ2UKCSovCglCT09MIG1vdmVQYWdlKGludCB0YXJnZXQsIGludCBzb3VyY2UpOwoKCS8qKgoJTG9ja3MgYSBwYWdlIGluIG1lbW9yeSBmb3IgZWRpdGluZy4gWW91IG11c3QgY2FsbCB1bmxvY2tQYWdlIHRvIGZyZWUgdGhlIHBhZ2U8YnI+Cgk8Yj5Vc2FnZSA6IDwvYj48YnI+Cgk8cHJlPgoJZmlwTXVsdGlQYWdlIG1wYWdlOwoJLy8gLi4uCglmaXBJbWFnZSBpbWFnZTsJCS8vIFlvdSBtdXN0IGRlY2xhcmUgdGhpcyBiZWZvcmUKCWltYWdlID0gbXBhZ2UubG9ja1BhZ2UoMik7CglpZihpbWFnZS5pc1ZhbGlkKCkpIHsKCSAgLy8gLi4uCgkgIG1wYWdlLnVubG9ja1BhZ2UoaW1hZ2UsIFRSVUUpOwoJfQoJPC9wcmU+CglAcGFyYW0gcGFnZSBQYWdlIG51bWJlcgoJQHJldHVybiBSZXR1cm5zIHRoZSBwYWdlIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0xvY2tQYWdlCgkqLwoJRklCSVRNQVAqIGxvY2tQYWdlKGludCBwYWdlKTsKCgkvKioKCVVubG9ja3MgYSBwcmV2aW91c2x5IGxvY2tlZCBwYWdlIGFuZCBnaXZlcyBpdCBiYWNrIHRvIHRoZSBtdWx0aS1wYWdlIGVuZ2luZQoJQHBhcmFtIGltYWdlIFBhZ2UgdG8gdW5sb2NrCglAcGFyYW0gY2hhbmdlZCBXaGVuIFRSVUUsIHRoZSBwYWdlIGlzIG1hcmtlZCBjaGFuZ2VkIGFuZCB0aGUgbmV3IHBhZ2UgZGF0YSBpcyBhcHBsaWVkIGluIHRoZSBtdWx0aS1wYWdlIGJpdG1hcC4KCUBzZWUgRnJlZUltYWdlX1VubG9ja1BhZ2UKCSovCgl2b2lkIHVubG9ja1BhZ2UoZmlwSW1hZ2UmIGltYWdlLCBCT09MIGNoYW5nZWQpOwoKCS8qKgoJUmV0dXJucyBhbiBhcnJheSBvZiBwYWdlLW51bWJlcnMgdGhhdCBhcmUgY3VycmVudGx5IGxvY2tlZCBpbiBtZW1vcnkuIAoJV2hlbiB0aGUgcGFnZXMgcGFyYW1ldGVyIGlzIE5VTEwsIHRoZSBzaXplIG9mIHRoZSBhcnJheSBpcyByZXR1cm5lZCBpbiB0aGUgY291bnQgdmFyaWFibGUuIAoJWW91IGNhbiB0aGVuIGFsbG9jYXRlIHRoZSBhcnJheSBvZiB0aGUgZGVzaXJlZCBzaXplIGFuZCBjYWxsIAoJZ2V0TG9ja2VkUGFnZU51bWJlcnMgYWdhaW4gdG8gcG9wdWxhdGUgdGhlIGFycmF5LgoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0dldExvY2tlZFBhZ2VOdW1iZXJzCgkqLwoJQk9PTCBnZXRMb2NrZWRQYWdlTnVtYmVycyhpbnQgKnBhZ2VzLCBpbnQgKmNvdW50KSBjb25zdDsKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpGcmVlSW1hZ2UgVGFnCgpGcmVlSW1hZ2UgdXNlcyB0aGlzIHN0cnVjdHVyZSB0byBzdG9yZSBtZXRhZGF0YSBpbmZvcm1hdGlvbi4gCiovCmNsYXNzIEZJUF9BUEkgZmlwVGFnIDogcHVibGljIGZpcE9iamVjdAp7CnByb3RlY3RlZDoKCS8vLyBQb2ludGVyIHRvIGEgRnJlZUltYWdlIHRhZwoJRklUQUcgKl90YWc7CgpwdWJsaWM6CgkvKipAbmFtZSBDcmVhdGlvbiAmIERlc3RydWN0aW9uICovCgkvL0B7CQoJLyoqCglDb25zdHJ1Y3RvcgoJQHNlZSBGcmVlSW1hZ2VfQ3JlYXRlVGFnCgkqLwoJZmlwVGFnKCk7CgkvKiogCglEZXN0cnVjdG9yCglAc2VlIEZyZWVJbWFnZV9EZWxldGVUYWcKCSovCgl2aXJ0dWFsIH5maXBUYWcoKTsKCS8qKgoJQ29uc3RydWN0IGEgRklEVF9BU0NJSSB0YWcgKEFTQ0lJIHN0cmluZykuPGJyPgoJVGhpcyBtZXRob2QgaXMgdXNlZnVsIHRvIHN0b3JlIGNvbW1lbnRzIG9yIElQVEMgdGFncy4gCglAcGFyYW0gbmFtZSBGaWVsZCBuYW1lCglAcGFyYW0gdmFsdWUgRmllbGQgdmFsdWUKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9DcmVhdGVUYWcKCSovCglCT09MIHNldEtleVZhbHVlKGNvbnN0IGNoYXIgKmtleSwgY29uc3QgY2hhciAqdmFsdWUpOwoKCS8vQH0KCgkvKipAbmFtZSBDb3B5aW5nICovCgkvL0B7CQoJLyoqCglDb3B5IGNvbnN0cnVjdG9yCglAc2VlIEZyZWVJbWFnZV9DbG9uZVRhZwoJKi8KCWZpcFRhZyhjb25zdCBmaXBUYWcmIHRhZyk7CgkvKioKCUNvcHkgY29uc3RydWN0b3IKCUBzZWUgRnJlZUltYWdlX0Nsb25lVGFnCgkqLwoJZmlwVGFnJiBvcGVyYXRvcj0oY29uc3QgZmlwVGFnJiB0YWcpOwoJLyoqCgk8Yj5Bc3NpZ25lbWVudCBvcGVyYXRvcjwvYj48YnI+CglDb3B5IHRoZSBpbnB1dCBwb2ludGVyIGFuZCBtYW5hZ2UgaXRzIGRlc3RydWN0aW9uCglAc2VlIG9wZXJhdG9yIEZJVEFHKigpCgkqLwoJZmlwVGFnJiBvcGVyYXRvcj0oRklUQUcgKnRhZyk7CgkvL0B9CgoJLyoqCglSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgRklUQUcgZGF0YS4gVXNlZCBmb3IgZGlyZWN0IGFjY2VzcyBmcm9tIEZSRUVJTUFHRSBmdW5jdGlvbnMgCglvciBmcm9tIHlvdXIgb3duIGxvdyBsZXZlbCBDIGZ1bmN0aW9ucy4KCUBzZWUgb3BlcmF0b3I9KEZJVEFHICp0YWcpCgkqLwoJb3BlcmF0b3IgRklUQUcqKCkgeyAKCQlyZXR1cm4gX3RhZzsgCgl9CgoJLy8vIFJldHVybnMgVFJVRSBpZiB0aGUgdGFnIGlzIGFsbG9jYXRlZCwgRkFMU0Ugb3RoZXJ3aXNlCglCT09MIGlzVmFsaWQoKSBjb25zdDsKCgkvKipAbmFtZSBUYWcgYWNjZXNzb3JzICovCgkvL0B7CQoJLyoqCglSZXR1cm5zIHRoZSB0YWcgZmllbGQgbmFtZSAodW5pcXVlIGluc2lkZSBhIG1ldGFkYXRhIG1vZGVsKS4KCUBzZWUgRnJlZUltYWdlX0dldFRhZ0tleQoJKi8KCWNvbnN0IGNoYXIgKmdldEtleSgpIGNvbnN0OwoJLyoqCglSZXR1cm5zIHRoZSB0YWcgZGVzY3JpcHRpb24gaWYgYXZhaWxhYmxlLCByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlCglAc2VlIEZyZWVJbWFnZV9HZXRUYWdEZXNjcmlwdGlvbgoJKi8KCWNvbnN0IGNoYXIgKmdldERlc2NyaXB0aW9uKCkgY29uc3Q7CgkvKioKCVJldHVybnMgdGhlIHRhZyBJRCBpZiBhdmFpbGFibGUsIHJldHVybnMgMCBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX0dldFRhZ0lECgkqLwoJV09SRCBnZXRJRCgpIGNvbnN0OwoJLyoqCglSZXR1cm5zIHRoZSB0YWcgZGF0YSB0eXBlIAoJQHNlZSBGcmVlSW1hZ2VfR2V0VGFnVHlwZQoJKi8KCUZSRUVfSU1BR0VfTURUWVBFIGdldFR5cGUoKSBjb25zdDsKCS8qKgoJUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgaW4gdGhlIHRhZyAoaW4gdGFnIHR5cGUgdW5pdHMpCglAc2VlIEZyZWVJbWFnZV9HZXRUYWdDb3VudAoJKi8KCURXT1JEIGdldENvdW50KCkgY29uc3Q7CgkvKioKCVJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgdGFnIHZhbHVlIGluIGJ5dGVzCglAc2VlIEZyZWVJbWFnZV9HZXRUYWdMZW5ndGgKCSovCglEV09SRCBnZXRMZW5ndGgoKSBjb25zdDsKCS8qKgoJUmV0dXJucyB0aGUgdGFnIHZhbHVlCglAc2VlIEZyZWVJbWFnZV9HZXRUYWdWYWx1ZQoJKi8KCWNvbnN0IHZvaWQgKmdldFZhbHVlKCkgY29uc3Q7CgkvKioKCVNldCB0aGUgdGFnIGZpZWxkIG5hbWUgCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfU2V0VGFnS2V5CgkqLwoJQk9PTCBzZXRLZXkoY29uc3QgY2hhciAqa2V5KTsKCS8qKgoJU2V0IHRoZSAodXN1YWxseSBvcHRpb25hbCkgdGFnIGRlc2NyaXB0aW9uCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfU2V0VGFnRGVzY3JpcHRpb24KCSovCglCT09MIHNldERlc2NyaXB0aW9uKGNvbnN0IGNoYXIgKmRlc2NyaXB0aW9uKTsKCS8qKgoJU2V0IHRoZSAodXN1YWxseSBvcHRpb25hbCkgdGFkIElECglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfU2V0VGFnSUQKCSovCglCT09MIHNldElEKFdPUkQgaWQpOwoJLyoqCglTZXQgdGhlIHRhZyBkYXRhIHR5cGUgCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfU2V0VGFnVHlwZQoJKi8KCUJPT0wgc2V0VHlwZShGUkVFX0lNQUdFX01EVFlQRSB0eXBlKTsKCS8qKgoJU2V0IHRoZSBudW1iZXIgb2YgZGF0YSBpbiB0aGUgdGFnIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1NldFRhZ0NvdW50CgkqLwoJQk9PTCBzZXRDb3VudChEV09SRCBjb3VudCk7CgkvKioKCVNldCB0aGUgbGVuZ3RoIG9mIHRoZSB0YWcgdmFsdWUsIGluIGJ5dGVzIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1NldFRhZ0xlbmd0aAoJKi8KCUJPT0wgc2V0TGVuZ3RoKERXT1JEIGxlbmd0aCk7CgkvKioKCVNldCB0aGUgdGFnIHZhbHVlIAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKCUBzZWUgRnJlZUltYWdlX1NldFRhZ1ZhbHVlCgkqLwoJQk9PTCBzZXRWYWx1ZShjb25zdCB2b2lkICp2YWx1ZSk7CgoJLy9AfQoKCS8qKgoJQ29udmVydHMgYSBGcmVlSW1hZ2UgdGFnIHN0cnVjdHVyZSB0byBhIHN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGludGVycHJldGVkIHRhZyB2YWx1ZQoJQHBhcmFtIG1vZGVsIE1ldGFkYXRhIG1vZGVsIHNwZWNpZmljYXRpb24gKG1ldGFkYXRhIG1vZGVsIGZyb20gd2hpY2ggdGhlIHRhZyB3YXMgZXh0cmFjdGVkKQoJQHBhcmFtIE1ha2UgQ2FtZXJhIG1vZGVsIChub3QgdXNlZCB5ZXQpCgkqLwoJY29uc3QgY2hhciogdG9TdHJpbmcoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBjaGFyICpNYWtlID0gTlVMTCkgY29uc3Q7Cgp9OwoKLyoqCk1ldGFkYXRhIGl0ZXJhdG9yCgo8Yj5Vc2FnZSA6IDwvYj48YnI+CjxwcmU+CmZpcEltYWdlIGltYWdlOwovLyAuLi4KZmlwVGFnIHRhZzsKZmlwTWV0YWRhdGFGaW5kIGZpbmRlcjsKaWYoIGZpbmRlci5maW5kRmlyc3RNZXRhZGF0YShGSU1EX0VYSUZfTUFJTiwgaW1hZ2UsIHRhZykgKSB7CiAgZG8gewogICAgLy8gcHJvY2VzcyB0aGUgdGFnCgljb3V0IDw8IHRhZy5nZXRLZXkoKSA8PCAiXG4iOwoKICB9IHdoaWxlKCBmaW5kZXIuZmluZE5leHRNZXRhZGF0YSh0YWcpICk7Cn0KLy8gdGhlIGNsYXNzIGNhbiBiZSBjYWxsZWQgYWdhaW4gd2l0aCBhbm90aGVyIG1ldGFkYXRhIG1vZGVsCmlmKCBmaW5kZXIuZmluZEZpcnN0TWV0YWRhdGEoRklNRF9FWElGX0VYSUYsIGltYWdlLCB0YWcpICkgewogIGRvIHsKICAgIC8vIHByb2Nlc3MgdGhlIHRhZwoJY291dCA8PCB0YWcuZ2V0S2V5KCkgPDwgIlxuIjsKCiAgfSB3aGlsZSggZmluZGVyLmZpbmROZXh0TWV0YWRhdGEodGFnKSApOwp9CjwvcHJlPgoqLwpjbGFzcyBGSVBfQVBJIGZpcE1ldGFkYXRhRmluZCA6IHB1YmxpYyBmaXBPYmplY3QKewpwcm90ZWN0ZWQ6CgkvLy8gUG9pbnRlciB0byBhIHNlYXJjaCBoYW5kbGUKCUZJTUVUQURBVEEgKl9tZGhhbmRsZTsKCnB1YmxpYzoKCS8vLyBSZXR1cm5zIFRSVUUgaWYgdGhlIHNlYXJjaCBoYW5kbGUgaXMgYWxsb2NhdGVkLCBGQUxTRSBvdGhlcndpc2UKCUJPT0wgaXNWYWxpZCgpIGNvbnN0OwoKCS8vLyBDb25zdHJ1Y3RvcgoJZmlwTWV0YWRhdGFGaW5kKCk7CgkvKioKCURlc3RydWN0b3IKCUBzZWUgRnJlZUltYWdlX0ZpbmRDbG9zZU1ldGFkYXRhCgkqLwoJdmlydHVhbCB+ZmlwTWV0YWRhdGFGaW5kKCk7CgkvKioKCVByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmaXJzdCBpbnN0YW5jZSBvZiBhIHRhZyB0aGF0IG1hdGNoZXMgCgl0aGUgbWV0YWRhdGEgbW9kZWwgc3BlY2lmaWVkIGluIHRoZSA8aT5tb2RlbDwvaT4gYXJndW1lbnQuIAoJQHBhcmFtIG1vZGVsIE1ldGFkYXRhIG1vZGVsCglAcGFyYW0gaW1hZ2UgSW5wdXQgaW1hZ2UKCUBwYXJhbSB0YWcgUmV0dXJuZWQgdGFnCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoJQHNlZSBGcmVlSW1hZ2VfRmluZEZpcnN0TWV0YWRhdGEKCSovCglCT09MIGZpbmRGaXJzdE1ldGFkYXRhKEZSRUVfSU1BR0VfTURNT0RFTCBtb2RlbCwgZmlwSW1hZ2UmIGltYWdlLCBmaXBUYWcmIHRhZyk7CgkvKioKCUZpbmQgdGhlIG5leHQgdGFnLCBpZiBhbnksIHRoYXQgbWF0Y2hlcyB0aGUgbWV0YWRhdGEgbW9kZWwgYXJndW1lbnQgCglpbiBhIHByZXZpb3VzIGNhbGwgdG8gZmluZEZpcnN0TWV0YWRhdGEKCUBwYXJhbSB0YWcgUmV0dXJuZWQgdGFnCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZSwgaW5kaWNhdGluZyB0aGF0IG5vIG1vcmUgbWF0Y2hpbmcgdGFncyBjb3VsZCBiZSBmb3VuZAoJQHNlZSBGcmVlSW1hZ2VfRmluZE5leHRNZXRhZGF0YQoJKi8KCUJPT0wgZmluZE5leHRNZXRhZGF0YShmaXBUYWcmIHRhZyk7Cgp9OwoKI2VuZGlmCS8vIEZSRUVJTUFHRVBMVVNfSAo=