Ly89PT0tLS0tLS0tLS0tLS0tLS0tIGdjY2h1bmsuaCAtIE12bSBhbGxvY2F0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdm0KLy8KLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCi8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KLy8KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCiNpZm5kZWYgX0dDX0NIVU5LX0hfCiNkZWZpbmUgX0dDX0NIVU5LX0hfCgojaW5jbHVkZSAiZ2NtYXBwZXIuaCIKI2luY2x1ZGUgInR5cGVzLmgiCgpjbGFzcyBnYzsgICAgICAgIC8qIG9iamVjdCBjb2xsZWN0YWJsZSAqLwpjbGFzcyBnY19oZWFkZXI7IC8qIGVudGV0ZSBsb2NhbGUgKi8KCi8qIGRlc2NyaXB0aW9uIGQndW4gYm91dCBkZSBt6W1vaXJlICovCmNsYXNzIEdDQ2h1bmtOb2RlIHsKIAlHQ0NodW5rTm9kZSAqX3ByZXY7ICAgICAvKiBiaXQgMC0xOiBsJ2FnZSwgbGVzIGF1dHJlczogbGUgcHJldmlvdXMgKi8KIAlHQ0NodW5rTm9kZQkqX25leHQ7CiAJdm9pZCAqICAgICAgIF9jaHVuazsKIAl1aW50cHRyX3QJCQkgX25iYl9tYXJrOwkvKiBuYmIgPSAwIDw9PiBjZSBjaHVuayBlc3QgbGlicmUgKi8KCSAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJpdCAwLTI6IGxhIG1hcnF1ZSAqLwoJICAgICAgICAgICAgICAgICAgICAgICAgLyogYml0IDM6IGVzdC1vbiBjb2xsZWN0YWJsZSAqLwpwdWJsaWM6CiNpZmRlZiBTRVJWSUNFX0dDCiAgdm9pZCogbWV0YTsgLy8gd2hvIGFsbG9jYXRlZCBtZQojZW5kaWYKIAlzdGF0aWMgY29uc3Qgc2lnbmVkIGludCBtYXNrQ29sbGVjdGFibGUgICAgPSA4OwogCXN0YXRpYyBjb25zdCBzaWduZWQgaW50IG1hc2tOb3RDb2xsZWN0YWJsZSA9IDA7CgogCWlubGluZSBHQ0NodW5rTm9kZSgpIHt9CiAJaW5saW5lIH5HQ0NodW5rTm9kZSgpIHt9CgogCWlubGluZSBnY19oZWFkZXIJICoJY2h1bmsoKSAgICAgICAgICAgICAgICB7IHJldHVybiAoZ2NfaGVhZGVyICopX2NodW5rOyB9CgogCWlubGluZSBHQ0NodW5rTm9kZSAqCW5leHQoKSAgICAgICAgICAgICAgICAgeyByZXR1cm4gX25leHQ7IH0KIAlpbmxpbmUgdm9pZAkJCQkJCW5leHQoR0NDaHVua05vZGUgKm4pICAgeyBfbmV4dCA9IG47IH0KCiAJaW5saW5lIEdDQ2h1bmtOb2RlICoJcHJldigpICAgICAgICAgICAgICAgICB7IHJldHVybiBfcHJldjsgfQogCWlubGluZSBHQ0NodW5rTm9kZSAqICBwcmV2KEdDQ2h1bmtOb2RlICpwKSAgIHsgcmV0dXJuIF9wcmV2ID0gcDsgfQoKIAlpbmxpbmUgdm9pZAkJCQkJCWZyZWUoKSB7IF9uYmJfbWFyayA9IDA7IH0KCiAJaW5saW5lIHZvaWQJCQkJCQluYmIodWludHB0cl90IG4sIGJvb2wgaXNDb2wsIGludCBtKSB7IF9uYmJfbWFyayA9IChuIDw8IDQpIHwgKChpc0NvbCAmIDB4MSkgPDwgMykgfCBtOyB9CiAJaW5saW5lIHZvaWQJCQkJCQluYmIodWludHB0cl90IG4pCQkJCQkgICAgICAgIAkgeyBfbmJiX21hcmsgPSAobiA8PCA0KSB8IChfbmJiX21hcmsgJiAweGYpOyB9CiAJaW5saW5lIHVpbnRwdHJfdAkJCQkJbmJiKCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gX25iYl9tYXJrID4+IDQ7IH0KCgkvKiBwYXMgZGUgdmVyaWZpY2F0aW9uIGRlIGRlYm9yZGVtZW50ISEhISAqLwogCWlubGluZSB2b2lkCQkJCQkJX21hcmsodW5zaWduZWQgaW50IG0pICAgICAgICAgICAgIHsgX25iYl9tYXJrID0gbSB8IChfbmJiX21hcmsgJiAtOCk7IH0KIAlpbmxpbmUgdW5zaWduZWQgaW50CQltYXJrKCkgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBfbmJiX21hcmsgJiA3OyB9CgogCWlubGluZSBzaWduZWQgaW50ICAgICAgaXNDb2xsZWN0YWJsZSgpIHsgcmV0dXJuIF9uYmJfbWFyayAmIDg7IH0KCiAJaW5saW5lIHZvaWQgaW5pdGlhbGlzZShHQ0NodW5rTm9kZSAqbiwgdm9pZCAqYykgewogCQlfY2h1bmsgPSBjOwogCQlfbmV4dCA9IG47CiAJCV9uYmJfbWFyayA9IDA7CiAJfQoKCS8qIHBvdXIgZmFpcmUgdW5lIGFtb3JjZSBkZSBsaXN0ZSAqLwogCWlubGluZSB2b2lkIGFsb25lKCkgeyBfcHJldiA9IF9uZXh0ID0gdGhpczsgfQoKCS8qIGFqb3V0ZSB0aGlzIOAgcCAqLwogCWlubGluZSB2b2lkIGFwcGVuZChHQ0NodW5rTm9kZSAqcCkgewogCQlfcHJldiA9IHA7CiAJCV9uZXh0ID0gcC0+X25leHQ7CiAJCXAtPl9uZXh0ID0gdGhpczsKIAkJX25leHQtPl9wcmV2ID0gdGhpczsKIAl9CgoJLyogZW5sZXZlIHRoaXMgZGUgc2EgbGlzdGUgKi8KIAlpbmxpbmUgdm9pZCByZW1vdmUoKSB7CiAJCV9uZXh0LT5fcHJldiA9IF9wcmV2OwogCQlfcHJldi0+X25leHQgPSBfbmV4dDsKIAl9CgoJLyogcGxhY2UgbGEgbGlzdGUgZGUgcCBkYW5zIHRoaXMuIEVjcmFzZSBjZWxsZSBkZSBwICovCglpbmxpbmUgdm9pZCBhdHRyYXBlKEdDQ2h1bmtOb2RlICpsKQl7CgkJaWYobCA9PSBsLT5fbmV4dCkKCQkJYWxvbmUoKTsKCQllbHNlIHsKCQkJKF9uZXh0ID0gbC0+X25leHQpLT5fcHJldiA9IHRoaXM7CgkJCShfcHJldiA9IGwtPl9wcmV2KS0+X25leHQgPSB0aGlzOwoJCQlsLT5hbG9uZSgpOwoJCX0KCX0KCgkvKiBham91dGUgbGEgbGlzdGUgZGUgbCBkYW5zIHRoaXMgKi8KIAlpbmxpbmUgdm9pZCBlYXQoR0NDaHVua05vZGUgKmwpIHsKIAkJaWYobCAhPSBsLT5fbmV4dCkgewogCQkJKF9uZXh0LT5fcHJldiA9IGwtPl9wcmV2KS0+X25leHQgPSBfbmV4dDsKIAkJCShfbmV4dCA9IGwtPl9uZXh0KS0+X3ByZXYgPSB0aGlzOwogCQkJbC0+YWxvbmUoKTsKIAkJfQogCX0KfTsKCi8qIGVudGV0ZSBkZSBkZXNjcmlwdGlvbiBkZSB6b25lIG3pbW9pcmUgKi8KLyogdW5lIHpvbmUgZXN0IHVuIGVuc2VtYmxlIGRlIGJvdXRzIGRlIG3pbW9pcmUgZGUgbeptZSB0YWlsbGUsIGNvbnRpZ3VlcywgYWxpZ27pIHN1ciBkZXMgcGFnZXMgKi8KY2xhc3MgR0NQYWdlIDogcHVibGljIEdDTWFwcGVkQXJlYSB7CiAJc3RhdGljIEdDQ2h1bmtOb2RlIGVtcHR5OwoKIAlHQ0NodW5rTm9kZQkqX2hlYWRlcnM7CiAJdWludHB0cl90CQkJIF9jaHVua19uYmI7CnB1YmxpYzoKIAlzdGF0aWMgdm9pZCBpbml0aWFsaXNlKCk7CgogCWlubGluZSBHQ1BhZ2UoKSB7CiAJCUdDTWFwcGVkQXJlYTo6aW5pdGlhbGlzZSgwLCAwKTsKIAkJX2hlYWRlcnMgPSAmZW1wdHk7CiAJCV9jaHVua19uYmIgPSAoKHVuc2lnbmVkIGludCktMSkgPj4gMTsJCS8qIG9uIOl2aXRlIGxlIC8wICovCiAJfQoKIAlpbmxpbmUgR0NQYWdlKEdDTWFwcGVkQXJlYSAqcCwgdWludHB0cl90IG1hcHBlZF9uYmIsIHVpbnRwdHJfdCBjbmJiKQogCQk6IEdDTWFwcGVkQXJlYShwLCBtYXBwZWRfbmJiKSB7CiAJCV9jaHVua19uYmIgPSBjbmJiOwogCX0KCiAJaW5saW5lIH5HQ1BhZ2UoKSB7fSAgICAgLyogRkFJUkUgTEUgVU5NQVAgQSBMQSBNQUlOISEhISEgKi8KCiAJaW5saW5lIHVpbnRwdHJfdAkJCQkJY2h1bmtfbmJiKCkJCSAgICAgICAgeyByZXR1cm4gX2NodW5rX25iYjsgfQogCWlubGluZSB2b2lkIAkJCQkJY2h1bmtfbmJiKHVpbnRwdHJfdCBuKQkJeyBfY2h1bmtfbmJiID0gbjsgfQogCWlubGluZSBHQ0NodW5rTm9kZSAgICpoZWFkZXJzKCkJCQkgICAgICAgIHsgcmV0dXJuIF9oZWFkZXJzOyB9CiAJaW5saW5lIHZvaWQgaGVhZGVycyhHQ0NodW5rTm9kZSAqaCkgICAgICAgICB7IF9oZWFkZXJzID0gaDs7IH0KCiAJaW5saW5lIEdDQ2h1bmtOb2RlICpvMm5vZGUodm9pZCAqcHRyLCBzaWduZWQgaW50IG1hc2spIHsKIAkJcmVnaXN0ZXIgdWludHB0cl90IGVudHJ5ID0gKCh1aW50cHRyX3QpcHRyIC0gKHVpbnRwdHJfdClhcmVhKCkpL19jaHVua19uYmI7CiAJCXJlZ2lzdGVyIEdDQ2h1bmtOb2RlICpyZXMgPSBfaGVhZGVycyArIGVudHJ5OwogCQlyZXR1cm4gKCh1aW50cHRyX3QpcHRyIC0gKHVpbnRwdHJfdClyZXMtPmNodW5rKCkgPCByZXMtPm5iYigpKQogCQkJJiYgKHJlcy0+aXNDb2xsZWN0YWJsZSgpID09IG1hc2spCiAJCQk/IHJlcyA6IDA7CiAJfQoJCiAJaW5saW5lIGdjX2hlYWRlciAqbzJoZWFkZXIodm9pZCAqcHRyLCBzaWduZWQgaW50IG1hc2spIHsKIAkJcmVnaXN0ZXIgdWludHB0cl90IGVudHJ5ID0gKCh1aW50cHRyX3QpcHRyIC0gKHVpbnRwdHJfdClhcmVhKCkpL19jaHVua19uYmI7CiAJCXJlZ2lzdGVyIEdDQ2h1bmtOb2RlICpyZXMgPSBfaGVhZGVycyArIGVudHJ5OwogCQlyZXR1cm4gKCh1aW50cHRyX3QpcHRyIC0gKHVpbnRwdHJfdClyZXMtPmNodW5rKCkgPCByZXMtPm5iYigpKQogCQkJJiYgKHJlcy0+aXNDb2xsZWN0YWJsZSgpID09IG1hc2spCiAJCQk/IHJlcy0+Y2h1bmsoKSA6IDA7CiAJfQp9OwoKY2xhc3MgR0NEZXNjcmlwdG9yTWFwcGVkQ2h1bmsgOiBwdWJsaWMgR0NQYWdlIHsKCUdDQ2h1bmtOb2RlCWhlYWRlcjsKcHVibGljOgoJaW5saW5lIEdDRGVzY3JpcHRvck1hcHBlZENodW5rKEdDTWFwcGVkQXJlYSAqcCwgdWludHB0cl90IG1hcHBlZF9uYmIsIHVpbnRwdHJfdCBjbmJiKSAKCQk6IEdDUGFnZShwLCBtYXBwZWRfbmJiLCBjbmJiKSB7CgkJaGVhZGVyLmluaXRpYWxpc2UoMCwgYXJlYSgpKTsKCQloZWFkZXJzKCZoZWFkZXIpOwoJfQp9OwoKY2xhc3MgR0NIYXNoQ29uc3QgewpwdWJsaWM6CiAJc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludAkJZGVzY19iaXRzID0gUEFHRV9TSElGVDsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQlzZXRfYml0cyA9IDEwOwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQJCWhhc2hfYml0cyA9ICgzMiAtIHNldF9iaXRzIC0gZGVzY19iaXRzKTsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQluYl9kZXNjX3Blcl9zZXQgPSAxIDw8IHNldF9iaXRzOwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQJCW5iX3NldF9wZXJfaGFzaCA9IDEgPDwgaGFzaF9iaXRzOwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQJCXNldF9uYmIgPSAxIDw8IChzZXRfYml0cyArIGRlc2NfYml0cyk7CgogCXN0YXRpYyB1aW50cHRyX3QJZGVzY19lbnRyeSh2b2lkICogcHRyKSB7IHJldHVybiAoKHVpbnRwdHJfdClwdHIgPj4gZGVzY19iaXRzKSAmICgoIDEgPDwgc2V0X2JpdHMpIC0gMSk7IH0KIAlzdGF0aWMgdWludHB0cl90CXNldF9lbnRyeSh2b2lkICpwdHIpIHsgcmV0dXJuICh1aW50cHRyX3QpcHRyID4+IChzZXRfYml0cyArIGRlc2NfYml0cyk7IH0KIAlzdGF0aWMgdWludHB0cl90CXNldF9lbnRyeV8yX3B0cih1aW50cHRyX3QgZW50cnkpIHsgcmV0dXJuIGVudHJ5IDw8IChzZXRfYml0cyArIGRlc2NfYml0cyk7IH0KfTsKCmNsYXNzIEdDSGFzaFNldCB7CiAJc3RhdGljIEdDUGFnZSBlbXB0eTsKCiAJR0NQYWdlCQkqcGFnZXNbR0NIYXNoQ29uc3Q6Om5iX2Rlc2NfcGVyX3NldF07CnB1YmxpYzoKIAl2b2lkICpvcGVyYXRvciBuZXcodWludHB0cl90KTsKIAl2b2lkIG9wZXJhdG9yIGRlbGV0ZSh2b2lkICosIHVpbnRwdHJfdCk7CgkKIAlHQ0hhc2hTZXQoKTsKCiAJdm9pZCBoYXNoKEdDUGFnZSAqLCB2b2lkICosIHVpbnRwdHJfdCwgdWludHB0cl90LCB1bnNpZ25lZCBpbnQgKik7CgogCWlubGluZSBHQ1BhZ2UgKmdldCh2b2lkICpwdHIpIHsgcmV0dXJuIHBhZ2VzW0dDSGFzaENvbnN0OjpkZXNjX2VudHJ5KHB0cildOyB9Cn07CgpjbGFzcyBHQ0hhc2ggewogCXN0YXRpYyBHQ0hhc2hTZXQJCQkqc2V0c1tHQ0hhc2hDb25zdDo6bmJfc2V0X3Blcl9oYXNoXTsKIAlzdGF0aWMgdW5zaWduZWQgaW50CQl1c2VkW0dDSGFzaENvbnN0OjpuYl9zZXRfcGVyX2hhc2hdOwogCXN0YXRpYyBHQ0hhc2hTZXQJICAgIGVtcHR5OwoJc3RhdGljIGJvb2wgICAgICAgICAgIGluaXRlZDsKCXN0YXRpYyB1aW50cHRyX3QgICAgICAgICBuYl9saW5rOwoKcHVibGljOgoJc3RhdGljIHZvaWQgdW5saW5rKCkgeyBuYl9saW5rLS07IH0KIAlzdGF0aWMgdm9pZCBpbml0aWFsaXNlKCk7CiAJc3RhdGljIHZvaWQgZGVzdHJveSgpOwoKIAlzdGF0aWMgdm9pZCBoYXNoX3VucHJvdGVjdGVkKEdDUGFnZSAqcCwgdm9pZCAqYmFzZSwgdW5zaWduZWQgaW50IG5iYiwgdW5zaWduZWQgaW50IG5iYl9tYXApOwogCS8vdm9pZCBoYXNoKEdDUGFnZSAqcCkgeyBoYXNoKHAsIHAtPmFyZWEoKSwgcC0+bmJiKCksIHAtPm5iYigpKTsgfQogCS8vdm9pZCB1bmhhc2goR0NQYWdlICpwKSB7IGhhc2gocCwgcC0+YXJlYSgpLCBwLT5uYmIoKSwgMCk7IH0KCiAJc3RhdGljIGlubGluZSBHQ1BhZ2UgKmdldCh2b2lkICpwdHIpIHsgcmV0dXJuIHNldHNbR0NIYXNoQ29uc3Q6OnNldF9lbnRyeShwdHIpXS0+Z2V0KHB0cik7IH0KfTsKCiNlbmRpZgo=