Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBSQVcgY2FtZXJhIGltYWdlIGxvYWRlcgovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5IAovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCiNpbmNsdWRlICIuLi9NZXRhZGF0YS9GcmVlSW1hZ2VUYWcuaCIKCiNpbmNsdWRlICIuLi9MaWJSYXdMaXRlL2xpYnJhdy9saWJyYXcuaCIKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUGx1Z2luIEludGVyZmFjZQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgaW50IHNfZm9ybWF0X2lkOwoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBJbnRlcm5hbCBmdW5jdGlvbnMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIEZyZWVJbWFnZSBkYXRhc3RyZWFtIHdyYXBwZXIKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgTGliUmF3X2ZyZWVpbWFnZV9kYXRhc3RyZWFtIDogcHVibGljIExpYlJhd19hYnN0cmFjdF9kYXRhc3RyZWFtIHsKcHJpdmF0ZTogCglGcmVlSW1hZ2VJTyAqX2lvOwoJZmlfaGFuZGxlIF9oYW5kbGU7Cglsb25nIF9lb2Y7CgpwdWJsaWM6CglMaWJSYXdfZnJlZWltYWdlX2RhdGFzdHJlYW0oRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSA6IF9pbyhpbyksIF9oYW5kbGUoaGFuZGxlKSB7CgkJbG9uZyBzdGFydF9wb3MgPSBpby0+dGVsbF9wcm9jKGhhbmRsZSk7CgkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIDAsIFNFRUtfRU5EKTsKCQlfZW9mID0gaW8tPnRlbGxfcHJvYyhoYW5kbGUpOwoJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBzdGFydF9wb3MsIFNFRUtfU0VUKTsKCX0KCX5MaWJSYXdfZnJlZWltYWdlX2RhdGFzdHJlYW0oKSB7Cgl9CiAgICB2aXJ0dWFsIGludCB2YWxpZCgpIHsgCgkJcmV0dXJuIChfaW8gJiYgX2hhbmRsZSk7Cgl9CiAgICB2aXJ0dWFsIGludCByZWFkKHZvaWQgKmJ1ZmZlciwgc2l6ZV90IHNpemUsIHNpemVfdCBjb3VudCkgeyAKCQlpZihzdWJzdHJlYW0pIHJldHVybiBzdWJzdHJlYW0tPnJlYWQoYnVmZmVyLCBzaXplLCBjb3VudCk7CgkJcmV0dXJuIF9pby0+cmVhZF9wcm9jKGJ1ZmZlciwgKHVuc2lnbmVkKXNpemUsICh1bnNpZ25lZCljb3VudCwgX2hhbmRsZSk7Cgl9CQogICAgdmlydHVhbCBpbnQgZW9mKCkgeyAKICAgICAgICBpZihzdWJzdHJlYW0pIHJldHVybiBzdWJzdHJlYW0tPmVvZigpOwogICAgICAgIHJldHVybiAoX2lvLT50ZWxsX3Byb2MoX2hhbmRsZSkgPj0gX2VvZik7CiAgICB9CiAgICB2aXJ0dWFsIGludCBzZWVrKG9mZl90IG9mZnNldCwgaW50IG9yaWdpbikgeyAKICAgICAgICBpZihzdWJzdHJlYW0pIHJldHVybiBzdWJzdHJlYW0tPnNlZWsob2Zmc2V0LCBvcmlnaW4pOwoJCXJldHVybiBfaW8tPnNlZWtfcHJvYyhfaGFuZGxlLCBvZmZzZXQsIG9yaWdpbik7Cgl9IAogICAgdmlydHVhbCBpbnQgdGVsbCgpIHsgCgkJaWYoc3Vic3RyZWFtKSByZXR1cm4gc3Vic3RyZWFtLT50ZWxsKCk7CiAgICAgICAgcmV0dXJuIF9pby0+dGVsbF9wcm9jKF9oYW5kbGUpOwogICAgfQogICAgdmlydHVhbCBpbnQgZ2V0X2NoYXIoKSB7IAoJCWludCBjID0gMDsKCQlpZihzdWJzdHJlYW0pIHJldHVybiBzdWJzdHJlYW0tPmdldF9jaGFyKCk7CgkJaWYoIV9pby0+cmVhZF9wcm9jKCZjLCAxLCAxLCBfaGFuZGxlKSkgcmV0dXJuIC0xOwoJCXJldHVybiBjOwogICB9Cgl2aXJ0dWFsIGNoYXIqIGdldHMoY2hhciAqYnVmZmVyLCBpbnQgbGVuZ3RoKSB7IAoJCWlmIChzdWJzdHJlYW0pIHJldHVybiBzdWJzdHJlYW0tPmdldHMoYnVmZmVyLCBsZW5ndGgpOwoJCW1lbXNldChidWZmZXIsIDAsIGxlbmd0aCk7CgkJZm9yKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CgkJCWlmKCFfaW8tPnJlYWRfcHJvYygmYnVmZmVyW2ldLCAxLCAxLCBfaGFuZGxlKSkKCQkJCXJldHVybiBOVUxMOwoJCQlpZihidWZmZXJbaV0gPT0gMHgwQSkKCQkJCWJyZWFrOwoJCX0KCQlyZXR1cm4gYnVmZmVyOwoJfQoJdmlydHVhbCBpbnQgc2NhbmZfb25lKGNvbnN0IGNoYXIgKmZtdCwgdm9pZCogdmFsKSB7CgkJc3RkOjpzdHJpbmcgYnVmZmVyOwoJCWNoYXIgZWxlbWVudCA9IDA7CgkJYm9vbCBiRG9uZSA9IGZhbHNlOwoJCWlmKHN1YnN0cmVhbSkgcmV0dXJuIHN1YnN0cmVhbS0+c2NhbmZfb25lKGZtdCx2YWwpOwkJCQkKCQlkbyB7CgkJCWlmKF9pby0+cmVhZF9wcm9jKCZlbGVtZW50LCAxLCAxLCBfaGFuZGxlKSA9PSAxKSB7CgkJCQlzd2l0Y2goZWxlbWVudCkgewoJCQkJCWNhc2UgJzAnOgoJCQkJCWNhc2UgJ1xuJzoKCQkJCQljYXNlICcgJzoKCQkJCQljYXNlICdcdCc6CgkJCQkJCWJEb25lID0gdHJ1ZTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCQlidWZmZXIuYXBwZW5kKCZlbGVtZW50LCAxKTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiAwOwoJCQl9CgkJfSB3aGlsZSghYkRvbmUpOwoKCQlyZXR1cm4gc3NjYW5mKGJ1ZmZlci5jX3N0cigpLCBmbXQsIHZhbCk7Cgl9Cn07CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKQ29udmVydCBhIHByb2Nlc3NlZCByYXcgZGF0YSBhcnJheSB0byBhIEZJQklUTUFQCkBwYXJhbSBpbWFnZSBQcm9jZXNzZWQgcmF3IGltYWdlCkByZXR1cm4gUmV0dXJucyB0aGUgY29udmVydGVkIGRpYiBpZiBzdWNjZXNzZnVsbCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoqLwpzdGF0aWMgRklCSVRNQVAgKiAKbGlicmF3X0NvbnZlcnRUb0RpYihsaWJyYXdfcHJvY2Vzc2VkX2ltYWdlX3QgKmltYWdlKSB7CglGSUJJVE1BUCAqZGliID0gTlVMTDsKCXRyeSB7CgkJdW5zaWduZWQgd2lkdGggPSBpbWFnZS0+d2lkdGg7CgkJdW5zaWduZWQgaGVpZ2h0ID0gaW1hZ2UtPmhlaWdodDsKCQl1bnNpZ25lZCBicHAgPSBpbWFnZS0+Yml0czsKCQlpZihicHAgPT0gMTYpIHsKCQkJLy8gYWxsb2NhdGUgb3V0cHV0IGRpYgoJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKEZJVF9SR0IxNiwgd2lkdGgsIGhlaWdodCk7CgkJCWlmKCFkaWIpIHsKCQkJCXRocm93IEZJX01TR19FUlJPUl9ESUJfTUVNT1JZOwoJCQl9CgkJCS8vIHdyaXRlIGRhdGEKCQkJdW5zaWduZWQgc2hvcnQgKnJhd19kYXRhID0gKHVuc2lnbmVkIHNob3J0KilpbWFnZS0+ZGF0YTsKCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCUZJUkdCMTYgKm91dHB1dCA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJb3V0cHV0W3hdLnJlZCAgID0gcmF3X2RhdGFbMF07CgkJCQkJb3V0cHV0W3hdLmdyZWVuID0gcmF3X2RhdGFbMV07CgkJCQkJb3V0cHV0W3hdLmJsdWUgID0gcmF3X2RhdGFbMl07CgkJCQkJcmF3X2RhdGEgKz0gMzsKCQkJCX0KCQkJfQoJCX0gZWxzZSBpZihicHAgPT0gOCkgewoJCQkvLyBhbGxvY2F0ZSBvdXRwdXQgZGliCgkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX0JJVE1BUCwgd2lkdGgsIGhlaWdodCwgMjQpOwoJCQlpZighZGliKSB7CgkJCQl0aHJvdyBGSV9NU0dfRVJST1JfRElCX01FTU9SWTsKCQkJfQoJCQkvLyB3cml0ZSBkYXRhCgkJCUJZVEUgKnJhd19kYXRhID0gKEJZVEUqKWltYWdlLT5kYXRhOwoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJUkdCVFJJUExFICpvdXRwdXQgPSAoUkdCVFJJUExFKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoZWlnaHQgLSAxIC0geSk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJb3V0cHV0W3hdLnJnYnRSZWQgICA9IHJhd19kYXRhWzBdOwoJCQkJCW91dHB1dFt4XS5yZ2J0R3JlZW4gPSByYXdfZGF0YVsxXTsKCQkJCQlvdXRwdXRbeF0ucmdidEJsdWUgID0gcmF3X2RhdGFbMl07CgkJCQkJcmF3X2RhdGEgKz0gMzsKCQkJCX0KCQkJfQoJCX0KCgl9IGNhdGNoKGNvbnN0IGNoYXIgKnRleHQpIHsKCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsIHRleHQpOwoJfQoKCXJldHVybiBkaWI7Cn0KCi8qKiAKR2V0IHRoZSBlbWJlZGRlZCBKUEVHIHByZXZpZXcgaW1hZ2UgZnJvbSBSQVcgcGljdHVyZSB3aXRoIGluY2x1ZGVkIEV4aWYgRGF0YS4gCkBwYXJhbSBSYXdQcm9jZXNzb3IgTGlicmF3IGhhbmRsZQpAcmV0dXJuIFJldHVybnMgdGhlIGxvYWRlZCBkaWIgaWYgc3VjY2Vzc2Z1bGwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKKi8Kc3RhdGljIEZJQklUTUFQICogCmxpYnJhd19Mb2FkRW1iZWRkZWRQcmV2aWV3KExpYlJhdyYgUmF3UHJvY2Vzc29yKSB7CglGSUJJVE1BUCAqZGliID0gTlVMTDsKCWxpYnJhd19wcm9jZXNzZWRfaW1hZ2VfdCAqdGh1bWJfaW1hZ2UgPSBOVUxMOwoJCgl0cnkgewoJCS8vIHVucGFjayBkYXRhCgkJaWYoUmF3UHJvY2Vzc29yLnVucGFja190aHVtYigpICE9IExJQlJBV19TVUNDRVNTKSB7CgkJCXRocm93IChjaGFyKilOVUxMOwkvLyBydW4gc2lsZW50bHkgIkxpYlJhdyA6IGZhaWxlZCB0byBydW4gdW5wYWNrX3RodW1iIgoJCX0KCgkJLy8gcmV0cmlldmUgdGh1bWIgaW1hZ2UKCQlpbnQgZXJyb3JfY29kZSA9IDA7CgkJdGh1bWJfaW1hZ2UgPSBSYXdQcm9jZXNzb3IuZGNyYXdfbWFrZV9tZW1fdGh1bWIoJmVycm9yX2NvZGUpOwoJCWlmKHRodW1iX2ltYWdlKSB7CgkJCWlmKHRodW1iX2ltYWdlLT50eXBlICE9IExJQlJBV19JTUFHRV9CSVRNQVApIHsKCQkJCWludCBmbGFncyA9IDA7CgkJCQkvLyBhdHRhY2ggdGhlIGJpbmFyeSBkYXRhIHRvIGEgbWVtb3J5IHN0cmVhbQoJCQkJRklNRU1PUlkgKmhtZW0gPSBGcmVlSW1hZ2VfT3Blbk1lbW9yeSgoQllURSopdGh1bWJfaW1hZ2UtPmRhdGEsIChEV09SRCl0aHVtYl9pbWFnZS0+ZGF0YV9zaXplKTsKCQkJCS8vIGdldCB0aGUgZmlsZSB0eXBlCgkJCQlGUkVFX0lNQUdFX0ZPUk1BVCBmaWYgPSBGcmVlSW1hZ2VfR2V0RmlsZVR5cGVGcm9tTWVtb3J5KGhtZW0sIDApOwoJCQkJaWYoZmlmID09IEZJRl9KUEVHKSB7CgkJCQkJLy8gcm90YXRlIGFjY29yZGluZyB0byBFeGlmIG9yaWVudGF0aW9uCgkJCQkJZmxhZ3MgfD0gSlBFR19FWElGUk9UQVRFOwoJCQkJfQoJCQkJLy8gbG9hZCBhbiBpbWFnZSBmcm9tIHRoZSBtZW1vcnkgc3RyZWFtCgkJCQlkaWIgPSBGcmVlSW1hZ2VfTG9hZEZyb21NZW1vcnkoZmlmLCBobWVtLCBmbGFncyk7CgkJCQkvLyBjbG9zZSB0aGUgc3RyZWFtCgkJCQlGcmVlSW1hZ2VfQ2xvc2VNZW1vcnkoaG1lbSk7CgkJCX0gZWxzZSB7CgkJCQkvLyBjb252ZXJ0IHByb2Nlc3NlZCBkYXRhIHRvIG91dHB1dCBkaWIKCQkJCWRpYiA9IGxpYnJhd19Db252ZXJ0VG9EaWIodGh1bWJfaW1hZ2UpOwoJCQl9CgkJfSBlbHNlIHsKCQkJdGhyb3cgIkxpYlJhdyA6IGZhaWxlZCB0byBydW4gZGNyYXdfbWFrZV9tZW1fdGh1bWIiOwoJCX0KCgkJLy8gY2xlYW4tdXAgYW5kIHJldHVybgoJCWZyZWUodGh1bWJfaW1hZ2UpOwoKCQlyZXR1cm4gZGliOwoKCX0gY2F0Y2goY29uc3QgY2hhciAqdGV4dCkgewoJCS8vIGNsZWFuLXVwIGFuZCByZXR1cm4KCQlpZih0aHVtYl9pbWFnZSkgewoJCQlmcmVlKHRodW1iX2ltYWdlKTsKCQl9CgkJaWYodGV4dCAhPSBOVUxMKSB7CgkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgdGV4dCk7CgkJfQoJfQoKCXJldHVybiBOVUxMOwp9Ci8qKgpMb2FkIHJhdyBkYXRhIGFuZCBjb252ZXJ0IHRvIEZJQklUTUFQCkBwYXJhbSBSYXdQcm9jZXNzb3IgTGlicmF3IGhhbmRsZQpAcGFyYW0gYml0c3BlcnNhbXBsZSBPdXRwdXQgYml0ZGVwdGggKDgtIG9yIDE2LWJpdCkKQHJldHVybiBSZXR1cm5zIHRoZSBsb2FkZWQgZGliIGlmIHN1Y2Nlc3NmdWxsLCByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlCiovCnN0YXRpYyBGSUJJVE1BUCAqIApsaWJyYXdfTG9hZFJhd0RhdGEoTGliUmF3JiBSYXdQcm9jZXNzb3IsIGludCBiaXRzcGVyc2FtcGxlKSB7CglGSUJJVE1BUCAqZGliID0gTlVMTDsKCWxpYnJhd19wcm9jZXNzZWRfaW1hZ2VfdCAqcHJvY2Vzc2VkX2ltYWdlID0gTlVMTDsKCgl0cnkgewoJCS8vIHNldCBkZWNvZGluZyBwYXJhbWV0ZXJzCgkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQkKCQkvLyAoLTQpIExpbmVhciAxNi1iaXQgb3IgOC1iaXQKCQlSYXdQcm9jZXNzb3IuaW1nZGF0YS5wYXJhbXMub3V0cHV0X2JwcyA9IGJpdHNwZXJzYW1wbGU7CgkJLy8gKC13KSBVc2UgY2FtZXJhIHdoaXRlIGJhbGFuY2UsIGlmIHBvc3NpYmxlCgkJUmF3UHJvY2Vzc29yLmltZ2RhdGEucGFyYW1zLnVzZV9jYW1lcmFfd2IgPSAxOwoJCS8vICgtYSkgQXZlcmFnZSB0aGUgd2hvbGUgaW1hZ2UgZm9yIHdoaXRlIGJhbGFuY2UKCQlSYXdQcm9jZXNzb3IuaW1nZGF0YS5wYXJhbXMudXNlX2F1dG9fd2IgPSAxOwoJCS8vICgtcSAzKSBBZGFwdGl2ZSBob21vZ2VuZWl0eS1kaXJlY3RlZCBkZW1vc2FpY2luZyBhbGdvcml0aG0gKEFIRCkKCQlSYXdQcm9jZXNzb3IuaW1nZGF0YS5wYXJhbXMudXNlcl9xdWFsID0gMzsKCgkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJLy8gdW5wYWNrIGRhdGEKCQlpZihSYXdQcm9jZXNzb3IudW5wYWNrKCkgIT0gTElCUkFXX1NVQ0NFU1MpIHsKCQkJdGhyb3cgIkxpYlJhdyA6IGZhaWxlZCB0byB1bnBhY2sgZGF0YSI7CgkJfQoKCQkvLyBwcm9jZXNzIGRhdGEgKC4uLiBtb3N0IGNvbnN1bWluZyB0YXNrIC4uLikKCQlpZihSYXdQcm9jZXNzb3IuZGNyYXdfcHJvY2VzcygpICE9IExJQlJBV19TVUNDRVNTKSB7CgkJCXRocm93ICJMaWJSYXcgOiBmYWlsZWQgdG8gcHJvY2VzcyBkYXRhIjsKCQl9CgoJCS8vIHJldHJpZXZlIHByb2Nlc3NlZCBpbWFnZQoJCWludCBlcnJvcl9jb2RlID0gMDsKCQlwcm9jZXNzZWRfaW1hZ2UgPSBSYXdQcm9jZXNzb3IuZGNyYXdfbWFrZV9tZW1faW1hZ2UoJmVycm9yX2NvZGUpOwoJCWlmKHByb2Nlc3NlZF9pbWFnZSkgewoJCQkvLyB0eXBlIFNIT1VMRCBiZSBMSUJSQVdfSU1BR0VfQklUTUFQLCBidXQgd2UnbGwgY2hlY2sKCQkJaWYocHJvY2Vzc2VkX2ltYWdlLT50eXBlICE9IExJQlJBV19JTUFHRV9CSVRNQVApIHsKCQkJCXRocm93ICJpbnZhbGlkIGltYWdlIHR5cGUiOwoJCQl9CgkJCS8vIG9ubHkgMy1jb2xvciBpbWFnZXMgc3VwcG9ydGVkLi4uCgkJCWlmKHByb2Nlc3NlZF9pbWFnZS0+Y29sb3JzICE9IDMpIHsKCQkJCXRocm93ICJvbmx5IDMtY29sb3IgaW1hZ2VzIHN1cHBvcnRlZCI7CgkJCX0KCQl9IGVsc2UgewoJCQl0aHJvdyAiTGliUmF3IDogZmFpbGVkIHRvIHJ1biBkY3Jhd19tYWtlX21lbV9pbWFnZSI7CgkJfQoKCQkvLyBjb252ZXJ0IHByb2Nlc3NlZCBkYXRhIHRvIG91dHB1dCBkaWIKCQlkaWIgPSBsaWJyYXdfQ29udmVydFRvRGliKHByb2Nlc3NlZF9pbWFnZSk7CgkKCQkvLyBjbGVhbi11cCBhbmQgcmV0dXJuCgkJZnJlZShwcm9jZXNzZWRfaW1hZ2UpOwoKCQlyZXR1cm4gZGliOwoKCX0gY2F0Y2goY29uc3QgY2hhciAqdGV4dCkgewoJCS8vIGNsZWFuLXVwIGFuZCByZXR1cm4KCQlpZihwcm9jZXNzZWRfaW1hZ2UpIHsKCQkJZnJlZShwcm9jZXNzZWRfaW1hZ2UpOwoJCX0KCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsIHRleHQpOwoJfQoKCXJldHVybiBOVUxMOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbXBsZW1lbnRhdGlvbgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpGb3JtYXQoKSB7CglyZXR1cm4gIlJBVyI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkRlc2NyaXB0aW9uKCkgewoJcmV0dXJuICJSQVcgY2FtZXJhIGltYWdlIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRXh0ZW5zaW9uKCkgewoJc3RhdGljIGNvbnN0IGNoYXIgKnJhd19leHRlbnNpb25zID0gCgkJImJheSwiICAgLy8gQ2FzaW8gRGlnaXRhbCBDYW1lcmEgUmF3IEZpbGUgRm9ybWF0LgoJCSJibXEsIiAgIC8vIE51Q29yZSBSYXcgSW1hZ2UgRmlsZS4KCQkiY3IyLCIgICAvLyBDYW5vbiBEaWdpdGFsIENhbWVyYSBSQVcgSW1hZ2UgRm9ybWF0IHZlcnNpb24gMi4wLiBUaGVzZSBpbWFnZXMgYXJlIGJhc2VkIG9uIHRoZSBUSUZGIGltYWdlIHN0YW5kYXJkLgoJCSJjcncsIiAgIC8vIENhbm9uIERpZ2l0YWwgQ2FtZXJhIFJBVyBJbWFnZSBGb3JtYXQgdmVyc2lvbiAxLjAuIAoJCSJjczEsIiAgIC8vIENhcHR1cmUgU2hvcCBSYXcgSW1hZ2UgRmlsZS4KCQkiZGMyLCIgICAvLyBLb2RhayBEQzI1IERpZ2l0YWwgQ2FtZXJhIEZpbGUuCgkJImRjciwiICAgLy8gS29kYWsgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdCBmb3IgdGhlc2UgbW9kZWxzOiBLb2RhayBEU0MgUHJvIFNMUi9jLCBLb2RhayBEU0MgUHJvIFNMUi9uLCBLb2RhayBEU0MgUHJvIDE0TiwgS29kYWsgRFNDIFBSTyAxNG54LgoJCSJkbmcsIiAgIC8vIEFkb2JlIERpZ2l0YWwgTmVnYXRpdmU6IERORyBpcyBwdWJsaWNseSBhdmFpbGFibGUgYXJjaGl2YWwgZm9ybWF0IGZvciB0aGUgcmF3IGZpbGVzIGdlbmVyYXRlZCBieSBkaWdpdGFsIGNhbWVyYXMuIEJ5IGFkZHJlc3NpbmcgdGhlIGxhY2sgb2YgYW4gb3BlbiBzdGFuZGFyZCBmb3IgdGhlIHJhdyBmaWxlcyBjcmVhdGVkIGJ5IGluZGl2aWR1YWwgY2FtZXJhIG1vZGVscywgRE5HIGhlbHBzIGVuc3VyZSB0aGF0IHBob3RvZ3JhcGhlcnMgd2lsbCBiZSBhYmxlIHRvIGFjY2VzcyB0aGVpciBmaWxlcyBpbiB0aGUgZnV0dXJlLiAKCQkiZXJmLCIgICAvLyBFcHNvbiBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJmZmYsIiAgIC8vIEltYWNvbiBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJoZHIsIiAgIC8vIExlYWYgUmF3IEltYWdlIEZpbGUuCgkJImsyNSwiICAgLy8gS29kYWsgREMyNSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJrZGMsIiAgIC8vIEtvZGFrIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJIm1kYywiICAgLy8gTWlub2x0YSBSRDE3NSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJtb3MsIiAgIC8vIE1hbWl5YSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJtcncsIiAgIC8vIE1pbm9sdGEgRGltYWdlIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJIm5lZiwiICAgLy8gTmlrb24gRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkib3JmLCIgICAvLyBPbHltcHVzIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJInBlZiwiICAgLy8gUGVudGF4IERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJInB4biwiICAgLy8gTG9naXRlY2ggRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkicmFmLCIgICAvLyBGdWppIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJInJhdywiICAgLy8gUGFuYXNvbmljIERpZ2l0YWwgQ2FtZXJhIEltYWdlIEZvcm1hdC4KCQkicmRjLCIgICAvLyBEaWdpdGFsIEZvdG8gTWFrZXIgUmF3IEltYWdlIEZpbGUuCgkJInNyMiwiICAgLy8gU29ueSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJzcmYsIiAgIC8vIFNvbnkgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdCBmb3IgRFNDLUY4MjggOCBtZWdhcGl4ZWwgZGlnaXRhbCBjYW1lcmEgb3IgU29ueSBEU0MtUjEKLy8JCSJ4M2YsIiAgIC8vIFNpZ21hIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQgZm9yIGRldmljZXMgYmFzZWQgb24gRm92ZW9uIFgzIGRpcmVjdCBpbWFnZSBzZW5zb3IuCgkJImFydywiICAgLy8gU29ueSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0IGZvciBBbHBoYSBkZXZpY2VzLgoJCSIzZnIsIiAgIC8vIEhhc3NlbGJsYWQgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkiY2luZSwiICAvLyBQaGFudG9tIFNvZnR3YXJlIFJhdyBJbWFnZSBGaWxlLgoJCSJpYSwiICAgIC8vIFNpbmFyIFJhdyBJbWFnZSBGaWxlLgoJCSJrYzIsIiAgIC8vIEtvZGFrIERDUzIwMCBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJtZWYsIiAgIC8vIE1hbWl5YSBEaWdpdGFsIENhbWVyYSBSYXcgSW1hZ2UgRm9ybWF0LgoJCSJucncsIiAgIC8vIE5pa29uIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJInF0aywiICAgLy8gQXBwbGUgUXVpY2t0YWtlIDEwMC8xNTAgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkicncyLCIgICAvLyBQYW5hc29uaWMgTFgzIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJInN0aSwiICAgLy8gU2luYXIgQ2FwdHVyZSBTaG9wIFJhdyBJbWFnZSBGaWxlLgoJCSJkcmYsIiAgIC8vIEtvZGFrIERpZ2l0YWwgQ2FtZXJhIFJhdyBJbWFnZSBGb3JtYXQuCgkJImRzYywiICAgLy8gS29kYWsgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkicHR4LCIgICAvLyBQZW50YXggRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkiY2FwLCIgICAvLyBQaGFzZSBPbmUgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkiaWlxLCIgICAvLyBQaGFzZSBPbmUgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCQkicnd6IjsgICAvLyBSYXd6b3IgRGlnaXRhbCBDYW1lcmEgUmF3IEltYWdlIEZvcm1hdC4KCXJldHVybiByYXdfZXh0ZW5zaW9uczsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKUmVnRXhwcigpIHsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2UveC1yYXciOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKVmFsaWRhdGUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSB7CglMaWJSYXcgUmF3UHJvY2Vzc29yOwoJCgl0cnkgewoJCS8vIHdyYXAgdGhlIGlucHV0IGRhdGFzdHJlYW0KCQlMaWJSYXdfZnJlZWltYWdlX2RhdGFzdHJlYW0gZGF0YXN0cmVhbShpbywgaGFuZGxlKTsKCgkJLy8gb3BlbiB0aGUgZGF0YXN0cmVhbQoJCWlmKFJhd1Byb2Nlc3Nvci5vcGVuX2RhdGFzdHJlYW0oJmRhdGFzdHJlYW0pICE9IExJQlJBV19TVUNDRVNTKSB7CgkJCXRocm93KDEpOwkvLyBMaWJSYXcgOiBmYWlsZWQgdG8gb3BlbiBpbnB1dCBzdHJlYW0gKHVua25vd24gZm9ybWF0KQoJCX0KCgkJLy8gY2xlYW4tdXAgaW50ZXJuYWwgbWVtb3J5IGFsbG9jYXRpb25zCgkJUmF3UHJvY2Vzc29yLnJlY3ljbGUoKTsKCgkJcmV0dXJuIFRSVUU7CgoJfSBjYXRjaChpbnQpIHsKCQkvLyBjbGVhbi11cCBhbmQgcmV0dXJuCgkJUmF3UHJvY2Vzc29yLnJlY3ljbGUoKTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTdXBwb3J0c0V4cG9ydERlcHRoKGludCBkZXB0aCkgewoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYgClN1cHBvcnRzRXhwb3J0VHlwZShGUkVFX0lNQUdFX1RZUEUgdHlwZSkgewoJcmV0dXJuIEZBTFNFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgRklCSVRNQVAgKiBETExfQ0FMTENPTlYKTG9hZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCUZJQklUTUFQICpkaWIgPSBOVUxMOwoJTGliUmF3IFJhd1Byb2Nlc3NvcjsKCgl0cnkgewoJCS8vIHdyYXAgdGhlIGlucHV0IGRhdGFzdHJlYW0KCQlMaWJSYXdfZnJlZWltYWdlX2RhdGFzdHJlYW0gZGF0YXN0cmVhbShpbywgaGFuZGxlKTsKCgkJLy8gb3BlbiB0aGUgZGF0YXN0cmVhbQoJCWlmKFJhd1Byb2Nlc3Nvci5vcGVuX2RhdGFzdHJlYW0oJmRhdGFzdHJlYW0pICE9IExJQlJBV19TVUNDRVNTKSB7CgkJCXRocm93ICJMaWJSYXcgOiBmYWlsZWQgdG8gb3BlbiBpbnB1dCBzdHJlYW0gKHVua25vd24gZm9ybWF0KSI7CgkJfQoKCQlpZigoZmxhZ3MgJiBSQVdfUFJFVklFVykgPT0gUkFXX1BSRVZJRVcpIHsKCQkJLy8gdHJ5IHRvIGdldCB0aGUgZW1iZWRkZWQgSlBFRwoJCQlkaWIgPSBsaWJyYXdfTG9hZEVtYmVkZGVkUHJldmlldyhSYXdQcm9jZXNzb3IpOwoJCQlpZighZGliKSB7CgkJCQkvLyBubyBKUEVHIHByZXZpZXc6IHRyeSB0byBsb2FkIGFzIDgtYml0CgkJCQlkaWIgPSBsaWJyYXdfTG9hZFJhd0RhdGEoUmF3UHJvY2Vzc29yLCA4KTsKCQkJfQoJCX0gZWxzZSBpZigoZmxhZ3MgJiBSQVdfRElTUExBWSkgPT0gUkFXX0RJU1BMQVkpIHsKCQkJLy8gbG9hZCByYXcgZGF0YSBhcyBSR0IgMjQtYml0CgkJCWRpYiA9IGxpYnJhd19Mb2FkUmF3RGF0YShSYXdQcm9jZXNzb3IsIDgpOwoJCX0gZWxzZSB7CgkJCS8vIGRlZmF1bHQ6IGxvYWQgcmF3IGRhdGEgYXMgbGluZWFyIDE2LWJpdAoJCQlkaWIgPSBsaWJyYXdfTG9hZFJhd0RhdGEoUmF3UHJvY2Vzc29yLCAxNik7CgkJfQoKCQkvLyBzYXZlIElDQyBwcm9maWxlIGlmIHByZXNlbnQKCQlpZihOVUxMICE9IFJhd1Byb2Nlc3Nvci5pbWdkYXRhLmNvbG9yLnByb2ZpbGUpIHsKCQkJRnJlZUltYWdlX0NyZWF0ZUlDQ1Byb2ZpbGUoZGliLCBSYXdQcm9jZXNzb3IuaW1nZGF0YS5jb2xvci5wcm9maWxlLCBSYXdQcm9jZXNzb3IuaW1nZGF0YS5jb2xvci5wcm9maWxlX2xlbmd0aCk7CgkJfQoKCQkvLyBjbGVhbi11cCBpbnRlcm5hbCBtZW1vcnkgYWxsb2NhdGlvbnMKCQlSYXdQcm9jZXNzb3IucmVjeWNsZSgpOwoKCQlyZXR1cm4gZGliOwoKCX0gY2F0Y2goY29uc3QgY2hhciAqdGV4dCkgewoJCWlmKGRpYikgewoJCQlGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJfQoJCVJhd1Byb2Nlc3Nvci5yZWN5Y2xlKCk7CgkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCB0ZXh0KTsKCX0KCglyZXR1cm4gTlVMTDsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgIEluaXQKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKdm9pZCBETExfQ0FMTENPTlYKSW5pdFJBVyhQbHVnaW4gKnBsdWdpbiwgaW50IGZvcm1hdF9pZCkgewoJc19mb3JtYXRfaWQgPSBmb3JtYXRfaWQ7CgoJcGx1Z2luLT5mb3JtYXRfcHJvYyA9IEZvcm1hdDsKCXBsdWdpbi0+ZGVzY3JpcHRpb25fcHJvYyA9IERlc2NyaXB0aW9uOwoJcGx1Z2luLT5leHRlbnNpb25fcHJvYyA9IEV4dGVuc2lvbjsKCXBsdWdpbi0+cmVnZXhwcl9wcm9jID0gUmVnRXhwcjsKCXBsdWdpbi0+b3Blbl9wcm9jID0gTlVMTDsKCXBsdWdpbi0+Y2xvc2VfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnBhZ2Vjb3VudF9wcm9jID0gTlVMTDsKCXBsdWdpbi0+cGFnZWNhcGFiaWxpdHlfcHJvYyA9IE5VTEw7CglwbHVnaW4tPmxvYWRfcHJvYyA9IExvYWQ7CglwbHVnaW4tPnNhdmVfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnZhbGlkYXRlX3Byb2MgPSBWYWxpZGF0ZTsKCXBsdWdpbi0+bWltZV9wcm9jID0gTWltZVR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF9icHBfcHJvYyA9IFN1cHBvcnRzRXhwb3J0RGVwdGg7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF90eXBlX3Byb2MgPSBTdXBwb3J0c0V4cG9ydFR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2ljY19wcm9maWxlc19wcm9jID0gTlVMTDsKfQo=