Ly89PT0tLS0tLS0tLS0tLS0tLS0tIGdjY2h1bmsuaCAtIE12bSBhbGxvY2F0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdm0KLy8KLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCi8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KLy8KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCiNpZm5kZWYgX0dDX0NIVU5LX0hfCiNkZWZpbmUgX0dDX0NIVU5LX0hfCgojaW5jbHVkZSAibXZtL1ZpcnR1YWxNYWNoaW5lLmgiCgojaW5jbHVkZSAiZ2NtYXBwZXIuaCIKI2luY2x1ZGUgInR5cGVzLmgiCgpjbGFzcyBnY1Jvb3Q7ICAgICAgICAvKiBvYmplY3QgY29sbGVjdGFibGUgKi8KCi8qIGRlc2NyaXB0aW9uIGQndW4gYm91dCBkZSBt6W1vaXJlICovCmNsYXNzIEdDQ2h1bmtOb2RlIHsKIAlHQ0NodW5rTm9kZSAqX3ByZXY7ICAgICAvKiBiaXQgMC0xOiBsJ2FnZSwgbGVzIGF1dHJlczogbGUgcHJldmlvdXMgKi8KIAlHQ0NodW5rTm9kZQkqX25leHQ7CiAJdm9pZCAqICAgICAgIF9jaHVuazsKIAl1aW50cHRyX3QJCSBfbmJiX21hcms7CS8qIG5iYiA9IDAgPD0+IGNlIGNodW5rIGVzdCBsaWJyZSAqLwoJICAgICAgICAgICAgICAgICAgICAgICAgLyogYml0IDAtMjogbGEgbWFycXVlICovCgkgICAgICAgICAgICAgICAgICAgICAgICAvKiBiaXQgMzogZXN0LW9uIGNvbGxlY3RhYmxlICovCnB1YmxpYzoKI2lmZGVmIFNFUlZJQ0UKICBtdm06OlZpcnR1YWxNYWNoaW5lKiBtZXRhOyAvLyB3aG8gYWxsb2NhdGVkIG1lCiNlbmRpZgogCXN0YXRpYyBjb25zdCBzaWduZWQgaW50IG1hc2tDb2xsZWN0YWJsZSAgICA9IDg7CiAJc3RhdGljIGNvbnN0IHNpZ25lZCBpbnQgbWFza05vdENvbGxlY3RhYmxlID0gMDsKCiAJaW5saW5lIEdDQ2h1bmtOb2RlKCkge30KIAlpbmxpbmUgfkdDQ2h1bmtOb2RlKCkge30KCiAJaW5saW5lIGdjUm9vdAkgICAgICoJY2h1bmsoKSAgICAgICAgICAgICAgICB7IHJldHVybiAoZ2NSb290KilfY2h1bms7IH0KCiAJaW5saW5lIEdDQ2h1bmtOb2RlICoJbmV4dCgpICAgICAgICAgICAgICAgICB7IHJldHVybiBfbmV4dDsgfQogCWlubGluZSB2b2lkCQkJCQkJbmV4dChHQ0NodW5rTm9kZSAqbikgICB7IF9uZXh0ID0gbjsgfQoKIAlpbmxpbmUgR0NDaHVua05vZGUgKglwcmV2KCkgICAgICAgICAgICAgICAgIHsgcmV0dXJuIF9wcmV2OyB9CiAJaW5saW5lIEdDQ2h1bmtOb2RlICogIHByZXYoR0NDaHVua05vZGUgKnApICAgeyByZXR1cm4gX3ByZXYgPSBwOyB9CgogCWlubGluZSB2b2lkCQkJCQkJZnJlZSgpIHsgX25iYl9tYXJrID0gMDsgfQoKIAlpbmxpbmUgdm9pZAkJCQkJCW5iYih1aW50cHRyX3QgbiwgYm9vbCBpc0NvbCwgaW50IG0pIHsgX25iYl9tYXJrID0gKG4gPDwgNCkgfCAoKGlzQ29sICYgMHgxKSA8PCAzKSB8IG07IH0KIAlpbmxpbmUgdm9pZAkJCQkJCW5iYih1aW50cHRyX3QgbikJCQkJCSAgICAgICAgCSB7IF9uYmJfbWFyayA9IChuIDw8IDQpIHwgKF9uYmJfbWFyayAmIDB4Zik7IH0KIAlpbmxpbmUgdWludHB0cl90CQkJCQluYmIoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBfbmJiX21hcmsgPj4gNDsgfQoKCS8qIHBhcyBkZSB2ZXJpZmljYXRpb24gZGUgZGVib3JkZW1lbnQhISEhICovCiAJaW5saW5lIHZvaWQJCQkJCQlfbWFyayh1bnNpZ25lZCBpbnQgbSkgICAgICAgICAgICAgeyBfbmJiX21hcmsgPSBtIHwgKF9uYmJfbWFyayAmIC04KTsgfQogCWlubGluZSB1bnNpZ25lZCBpbnQJCW1hcmsoKSAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIF9uYmJfbWFyayAmIDc7IH0KCiAJaW5saW5lIHNpZ25lZCBpbnQgICAgICBpc0NvbGxlY3RhYmxlKCkgeyByZXR1cm4gX25iYl9tYXJrICYgODsgfQoKIAlpbmxpbmUgdm9pZCBpbml0aWFsaXNlKEdDQ2h1bmtOb2RlICpuLCB2b2lkICpjKSB7CiAJCV9jaHVuayA9IGM7CiAJCV9uZXh0ID0gbjsKIAkJX25iYl9tYXJrID0gMDsKIAl9CgoJLyogcG91ciBmYWlyZSB1bmUgYW1vcmNlIGRlIGxpc3RlICovCiAJaW5saW5lIHZvaWQgYWxvbmUoKSB7IF9wcmV2ID0gX25leHQgPSB0aGlzOyB9CgoJLyogYWpvdXRlIHRoaXMg4CBwICovCiAJaW5saW5lIHZvaWQgYXBwZW5kKEdDQ2h1bmtOb2RlICpwKSB7CiAJCV9wcmV2ID0gcDsKIAkJX25leHQgPSBwLT5fbmV4dDsKIAkJcC0+X25leHQgPSB0aGlzOwogCQlfbmV4dC0+X3ByZXYgPSB0aGlzOwogCX0KCQogIC8qIGFqb3V0ZSB0aGlzIOAgcCAqLwogCWlubGluZSB2b2lkIHByZXBlbmQoR0NDaHVua05vZGUgKnApIHsKIAkJX25leHQgPSBwOwogICAgX3ByZXYgPSBwLT5fcHJldjsKICAgIHAtPl9wcmV2ID0gdGhpczsKICAgIF9wcmV2LT5fbmV4dCA9IHRoaXM7CiAJfQoKCS8qIGVubGV2ZSB0aGlzIGRlIHNhIGxpc3RlICovCiAJaW5saW5lIHZvaWQgcmVtb3ZlKCkgewogCQlfbmV4dC0+X3ByZXYgPSBfcHJldjsKIAkJX3ByZXYtPl9uZXh0ID0gX25leHQ7CiAJfQoKCS8qIHBsYWNlIGxhIGxpc3RlIGRlIHAgZGFucyB0aGlzLiBFY3Jhc2UgY2VsbGUgZGUgcCAqLwoJaW5saW5lIHZvaWQgYXR0cmFwZShHQ0NodW5rTm9kZSAqbCkJewoJCWlmKGwgPT0gbC0+X25leHQpCgkJCWFsb25lKCk7CgkJZWxzZSB7CgkJCShfbmV4dCA9IGwtPl9uZXh0KS0+X3ByZXYgPSB0aGlzOwoJCQkoX3ByZXYgPSBsLT5fcHJldiktPl9uZXh0ID0gdGhpczsKCQkJbC0+YWxvbmUoKTsKCQl9Cgl9CgoJLyogYWpvdXRlIGxhIGxpc3RlIGRlIGwgZGFucyB0aGlzICovCiAJaW5saW5lIHZvaWQgZWF0KEdDQ2h1bmtOb2RlICpsKSB7CiAJCWlmKGwgIT0gbC0+X25leHQpIHsKIAkJCShfbmV4dC0+X3ByZXYgPSBsLT5fcHJldiktPl9uZXh0ID0gX25leHQ7CiAJCQkoX25leHQgPSBsLT5fbmV4dCktPl9wcmV2ID0gdGhpczsKIAkJCWwtPmFsb25lKCk7CiAJCX0KIAl9Cn07CgovKiBlbnRldGUgZGUgZGVzY3JpcHRpb24gZGUgem9uZSBt6W1vaXJlICovCi8qIHVuZSB6b25lIGVzdCB1biBlbnNlbWJsZSBkZSBib3V0cyBkZSBt6W1vaXJlIGRlIG3qbWUgdGFpbGxlLCBjb250aWd1ZXMsIGFsaWdu6SBzdXIgZGVzIHBhZ2VzICovCmNsYXNzIEdDUGFnZSA6IHB1YmxpYyBHQ01hcHBlZEFyZWEgewogCXN0YXRpYyBHQ0NodW5rTm9kZSBlbXB0eTsKCiAJR0NDaHVua05vZGUJKl9oZWFkZXJzOwogCXVpbnRwdHJfdAkJCSBfY2h1bmtfbmJiOwpwdWJsaWM6CiAJc3RhdGljIHZvaWQgaW5pdGlhbGlzZSgpOwoKIAlpbmxpbmUgR0NQYWdlKCkgewogCQlHQ01hcHBlZEFyZWE6OmluaXRpYWxpc2UoMCwgMCk7CiAJCV9oZWFkZXJzID0gJmVtcHR5OwogCQlfY2h1bmtfbmJiID0gKCh1bnNpZ25lZCBpbnQpLTEpID4+IDE7CQkvKiBvbiDpdml0ZSBsZSAvMCAqLwogCX0KCiAJaW5saW5lIEdDUGFnZShHQ01hcHBlZEFyZWEgKnAsIHVpbnRwdHJfdCBtYXBwZWRfbmJiLCB1aW50cHRyX3QgY25iYikKIAkJOiBHQ01hcHBlZEFyZWEocCwgbWFwcGVkX25iYikgewogCQlfY2h1bmtfbmJiID0gY25iYjsKIAl9CgogCWlubGluZSB+R0NQYWdlKCkge30gICAgIC8qIEZBSVJFIExFIFVOTUFQIEEgTEEgTUFJTiEhISEhICovCgogCWlubGluZSB1aW50cHRyX3QJCQkJCWNodW5rX25iYigpCQkgICAgICAgIHsgcmV0dXJuIF9jaHVua19uYmI7IH0KIAlpbmxpbmUgdm9pZCAJCQkJCWNodW5rX25iYih1aW50cHRyX3QgbikJCXsgX2NodW5rX25iYiA9IG47IH0KIAlpbmxpbmUgR0NDaHVua05vZGUgICAqaGVhZGVycygpCQkJICAgICAgICB7IHJldHVybiBfaGVhZGVyczsgfQogCWlubGluZSB2b2lkIGhlYWRlcnMoR0NDaHVua05vZGUgKmgpICAgICAgICAgeyBfaGVhZGVycyA9IGg7OyB9CgogCWlubGluZSBHQ0NodW5rTm9kZSAqbzJub2RlKHZvaWQgKnB0ciwgc2lnbmVkIGludCBtYXNrKSB7CiAJCXJlZ2lzdGVyIHVpbnRwdHJfdCBlbnRyeSA9ICgodWludHB0cl90KXB0ciAtICh1aW50cHRyX3QpYXJlYSgpKS9fY2h1bmtfbmJiOwogCQlyZWdpc3RlciBHQ0NodW5rTm9kZSAqcmVzID0gX2hlYWRlcnMgKyBlbnRyeTsKIAkJcmV0dXJuICgodWludHB0cl90KXB0ciAtICh1aW50cHRyX3QpcmVzLT5jaHVuaygpIDwgcmVzLT5uYmIoKSkKIAkJCSYmIChyZXMtPmlzQ29sbGVjdGFibGUoKSA9PSBtYXNrKQogCQkJPyByZXMgOiAwOwogCX0KCQogCWlubGluZSBnY1Jvb3QgKm8yaGVhZGVyKHZvaWQgKnB0ciwgc2lnbmVkIGludCBtYXNrKSB7CiAJCXJlZ2lzdGVyIHVpbnRwdHJfdCBlbnRyeSA9ICgodWludHB0cl90KXB0ciAtICh1aW50cHRyX3QpYXJlYSgpKS9fY2h1bmtfbmJiOwogCQlyZWdpc3RlciBHQ0NodW5rTm9kZSAqcmVzID0gX2hlYWRlcnMgKyBlbnRyeTsKIAkJcmV0dXJuICgodWludHB0cl90KXB0ciAtICh1aW50cHRyX3QpcmVzLT5jaHVuaygpIDwgcmVzLT5uYmIoKSkKIAkJCSYmIChyZXMtPmlzQ29sbGVjdGFibGUoKSA9PSBtYXNrKQogCQkJPyByZXMtPmNodW5rKCkgOiAwOwogCX0KfTsKCmNsYXNzIEdDRGVzY3JpcHRvck1hcHBlZENodW5rIDogcHVibGljIEdDUGFnZSB7CglHQ0NodW5rTm9kZQloZWFkZXI7CnB1YmxpYzoKCWlubGluZSBHQ0Rlc2NyaXB0b3JNYXBwZWRDaHVuayhHQ01hcHBlZEFyZWEgKnAsIHVpbnRwdHJfdCBtYXBwZWRfbmJiLCB1aW50cHRyX3QgY25iYikgCgkJOiBHQ1BhZ2UocCwgbWFwcGVkX25iYiwgY25iYikgewoJCWhlYWRlci5pbml0aWFsaXNlKDAsIGFyZWEoKSk7CgkJaGVhZGVycygmaGVhZGVyKTsKCX0KfTsKCmNsYXNzIEdDSGFzaENvbnN0IHsKcHVibGljOgogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQJCWRlc2NfYml0cyA9IFBBR0VfU0hJRlQ7CiAJc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludAkJc2V0X2JpdHMgPSAxMDsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQloYXNoX2JpdHMgPSAoMzIgLSBzZXRfYml0cyAtIGRlc2NfYml0cyk7CiAJc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludAkJbmJfZGVzY19wZXJfc2V0ID0gMSA8PCBzZXRfYml0czsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQluYl9zZXRfcGVyX2hhc2ggPSAxIDw8IGhhc2hfYml0czsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQlzZXRfbmJiID0gMSA8PCAoc2V0X2JpdHMgKyBkZXNjX2JpdHMpOwoKIAlzdGF0aWMgdWludHB0cl90CWRlc2NfZW50cnkodm9pZCAqIHB0cikgeyByZXR1cm4gKCh1aW50cHRyX3QpcHRyID4+IGRlc2NfYml0cykgJiAoKCAxIDw8IHNldF9iaXRzKSAtIDEpOyB9CiAJc3RhdGljIHVpbnRwdHJfdAlzZXRfZW50cnkodm9pZCAqcHRyKSB7IHJldHVybiAodWludHB0cl90KXB0ciA+PiAoc2V0X2JpdHMgKyBkZXNjX2JpdHMpOyB9CiAJc3RhdGljIHVpbnRwdHJfdAlzZXRfZW50cnlfMl9wdHIodWludHB0cl90IGVudHJ5KSB7IHJldHVybiBlbnRyeSA8PCAoc2V0X2JpdHMgKyBkZXNjX2JpdHMpOyB9Cn07CgpjbGFzcyBHQ0hhc2hTZXQgewogCXN0YXRpYyBHQ1BhZ2UgZW1wdHk7CgogCUdDUGFnZQkJKnBhZ2VzW0dDSGFzaENvbnN0OjpuYl9kZXNjX3Blcl9zZXRdOwpwdWJsaWM6CiAJdm9pZCAqb3BlcmF0b3IgbmV3KHVpbnRwdHJfdCk7CiAJdm9pZCBvcGVyYXRvciBkZWxldGUodm9pZCAqLCB1aW50cHRyX3QpOwoJCiAJR0NIYXNoU2V0KCk7CgogCXZvaWQgaGFzaChHQ1BhZ2UgKiwgdm9pZCAqLCB1aW50cHRyX3QsIHVpbnRwdHJfdCwgdW5zaWduZWQgaW50ICopOwoKIAlpbmxpbmUgR0NQYWdlICpnZXQodm9pZCAqcHRyKSB7IHJldHVybiBwYWdlc1tHQ0hhc2hDb25zdDo6ZGVzY19lbnRyeShwdHIpXTsgfQp9OwoKY2xhc3MgR0NIYXNoIHsKIAlzdGF0aWMgR0NIYXNoU2V0CQkJKnNldHNbR0NIYXNoQ29uc3Q6Om5iX3NldF9wZXJfaGFzaF07CiAJc3RhdGljIHVuc2lnbmVkIGludAkJdXNlZFtHQ0hhc2hDb25zdDo6bmJfc2V0X3Blcl9oYXNoXTsKIAlzdGF0aWMgR0NIYXNoU2V0CSAgICBlbXB0eTsKCXN0YXRpYyBib29sICAgICAgICAgICBpbml0ZWQ7CglzdGF0aWMgdWludHB0cl90ICAgICAgICAgbmJfbGluazsKCnB1YmxpYzoKCXN0YXRpYyB2b2lkIHVubGluaygpIHsgbmJfbGluay0tOyB9CiAJc3RhdGljIHZvaWQgaW5pdGlhbGlzZSgpOwogCXN0YXRpYyB2b2lkIGRlc3Ryb3koKTsKCiAJc3RhdGljIHZvaWQgaGFzaF91bnByb3RlY3RlZChHQ1BhZ2UgKnAsIHZvaWQgKmJhc2UsIHVuc2lnbmVkIGludCBuYmIsIHVuc2lnbmVkIGludCBuYmJfbWFwKTsKIAkvL3ZvaWQgaGFzaChHQ1BhZ2UgKnApIHsgaGFzaChwLCBwLT5hcmVhKCksIHAtPm5iYigpLCBwLT5uYmIoKSk7IH0KIAkvL3ZvaWQgdW5oYXNoKEdDUGFnZSAqcCkgeyBoYXNoKHAsIHAtPmFyZWEoKSwgcC0+bmJiKCksIDApOyB9CgogCXN0YXRpYyBpbmxpbmUgR0NQYWdlICpnZXQodm9pZCAqcHRyKSB7IHJldHVybiBzZXRzW0dDSGFzaENvbnN0OjpzZXRfZW50cnkocHRyKV0tPmdldChwdHIpOyB9Cn07CgojZW5kaWYK