Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBmaXBUYWcgY2xhc3MgaW1wbGVtZW50YXRpb24KLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAiRnJlZUltYWdlUGx1cy5oIgoKZmlwVGFnOjpmaXBUYWcoKSB7CglfdGFnID0gRnJlZUltYWdlX0NyZWF0ZVRhZygpOwp9CgpmaXBUYWc6On5maXBUYWcoKSB7CglGcmVlSW1hZ2VfRGVsZXRlVGFnKF90YWcpOwp9CgpCT09MIGZpcFRhZzo6c2V0S2V5VmFsdWUoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkgewoJaWYoX3RhZykgewoJCUZyZWVJbWFnZV9EZWxldGVUYWcoX3RhZyk7CgkJX3RhZyA9IE5VTEw7Cgl9CgkvLyBjcmVhdGUgYSB0YWcKCV90YWcgPSBGcmVlSW1hZ2VfQ3JlYXRlVGFnKCk7CglpZihfdGFnKSB7CgkJQk9PTCBiU3VjY2VzcyA9IFRSVUU7CgkJLy8gZmlsbCB0aGUgdGFnCgkJRFdPUkQgdGFnX2xlbmd0aCA9IChEV09SRCkoc3RybGVuKHZhbHVlKSArIDEpOwoJCWJTdWNjZXNzICY9IEZyZWVJbWFnZV9TZXRUYWdLZXkoX3RhZywga2V5KTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnTGVuZ3RoKF90YWcsIHRhZ19sZW5ndGgpOwoJCWJTdWNjZXNzICY9IEZyZWVJbWFnZV9TZXRUYWdDb3VudChfdGFnLCB0YWdfbGVuZ3RoKTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnVHlwZShfdGFnLCBGSURUX0FTQ0lJKTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnVmFsdWUoX3RhZywgdmFsdWUpOwoJCXJldHVybiBiU3VjY2VzczsKCX0KCXJldHVybiBGQUxTRTsKfQoKZmlwVGFnOjpmaXBUYWcoY29uc3QgZmlwVGFnJiB0YWcpIHsKCV90YWcgPSBGcmVlSW1hZ2VfQ2xvbmVUYWcodGFnLl90YWcpOwp9CgpmaXBUYWcmIGZpcFRhZzo6b3BlcmF0b3I9KGNvbnN0IGZpcFRhZyYgdGFnKSB7CglpZih0aGlzICE9ICZ0YWcpIHsKCQlpZihfdGFnKSBGcmVlSW1hZ2VfRGVsZXRlVGFnKF90YWcpOwoJCV90YWcgPSBGcmVlSW1hZ2VfQ2xvbmVUYWcodGFnLl90YWcpOwoJfQoJcmV0dXJuICp0aGlzOwp9CgpmaXBUYWcmIGZpcFRhZzo6b3BlcmF0b3I9KEZJVEFHICp0YWcpIHsKCWlmKF90YWcpIEZyZWVJbWFnZV9EZWxldGVUYWcoX3RhZyk7CglfdGFnID0gdGFnOwoJcmV0dXJuICp0aGlzOwp9CgpCT09MIGZpcFRhZzo6aXNWYWxpZCgpIGNvbnN0IHsKCXJldHVybiAoX3RhZyAhPSBOVUxMKSA/IFRSVUUgOiBGQUxTRTsKfQoKY29uc3QgY2hhciogZmlwVGFnOjpnZXRLZXkoKSBjb25zdCB7CglyZXR1cm4gRnJlZUltYWdlX0dldFRhZ0tleShfdGFnKTsKfQoKY29uc3QgY2hhciogZmlwVGFnOjpnZXREZXNjcmlwdGlvbigpIGNvbnN0IHsKCXJldHVybiBGcmVlSW1hZ2VfR2V0VGFnRGVzY3JpcHRpb24oX3RhZyk7Cn0KCldPUkQgZmlwVGFnOjpnZXRJRCgpIGNvbnN0IHsKCXJldHVybiBGcmVlSW1hZ2VfR2V0VGFnSUQoX3RhZyk7Cn0KCkZSRUVfSU1BR0VfTURUWVBFIGZpcFRhZzo6Z2V0VHlwZSgpIGNvbnN0IHsKCXJldHVybiBGcmVlSW1hZ2VfR2V0VGFnVHlwZShfdGFnKTsKfQoKRFdPUkQgZmlwVGFnOjpnZXRDb3VudCgpIGNvbnN0IHsKCXJldHVybiBGcmVlSW1hZ2VfR2V0VGFnQ291bnQoX3RhZyk7Cn0KCkRXT1JEIGZpcFRhZzo6Z2V0TGVuZ3RoKCkgY29uc3QgewoJcmV0dXJuIEZyZWVJbWFnZV9HZXRUYWdMZW5ndGgoX3RhZyk7Cn0KCmNvbnN0IHZvaWQqIGZpcFRhZzo6Z2V0VmFsdWUoKSBjb25zdCB7CglyZXR1cm4gRnJlZUltYWdlX0dldFRhZ1ZhbHVlKF90YWcpOwp9CgpCT09MIGZpcFRhZzo6c2V0S2V5KGNvbnN0IGNoYXIgKmtleSkgewoJcmV0dXJuIEZyZWVJbWFnZV9TZXRUYWdLZXkoX3RhZywga2V5KTsKfQoKQk9PTCBmaXBUYWc6OnNldERlc2NyaXB0aW9uKGNvbnN0IGNoYXIgKmRlc2NyaXB0aW9uKSB7CglyZXR1cm4gRnJlZUltYWdlX1NldFRhZ0Rlc2NyaXB0aW9uKF90YWcsIGRlc2NyaXB0aW9uKTsKfQoKQk9PTCBmaXBUYWc6OnNldElEKFdPUkQgaWQpIHsKCXJldHVybiBGcmVlSW1hZ2VfU2V0VGFnSUQoX3RhZywgaWQpOwp9CgpCT09MIGZpcFRhZzo6c2V0VHlwZShGUkVFX0lNQUdFX01EVFlQRSB0eXBlKSB7CglyZXR1cm4gRnJlZUltYWdlX1NldFRhZ1R5cGUoX3RhZywgdHlwZSk7Cn0KCkJPT0wgZmlwVGFnOjpzZXRDb3VudChEV09SRCBjb3VudCkgewoJcmV0dXJuIEZyZWVJbWFnZV9TZXRUYWdDb3VudChfdGFnLCBjb3VudCk7Cn0KCkJPT0wgZmlwVGFnOjpzZXRMZW5ndGgoRFdPUkQgbGVuZ3RoKSB7CglyZXR1cm4gRnJlZUltYWdlX1NldFRhZ0xlbmd0aChfdGFnLCBsZW5ndGgpOwp9CgpCT09MIGZpcFRhZzo6c2V0VmFsdWUoY29uc3Qgdm9pZCAqdmFsdWUpIHsKCXJldHVybiBGcmVlSW1hZ2VfU2V0VGFnVmFsdWUoX3RhZywgdmFsdWUpOwp9Cgpjb25zdCBjaGFyKiBmaXBUYWc6OnRvU3RyaW5nKEZSRUVfSU1BR0VfTURNT0RFTCBtb2RlbCwgY2hhciAqTWFrZSkgY29uc3QgewoJcmV0dXJuIEZyZWVJbWFnZV9UYWdUb1N0cmluZyhtb2RlbCwgX3RhZywgTWFrZSk7Cn0K