I2luY2x1ZGUJPHN0cmluZy5oPgojaW5jbHVkZQk8c3RkbGliLmg+CgojaWZkZWYgVUVNRgoJI2luY2x1ZGUJInVlbWYuaCIKI2Vsc2UKCSNpbmNsdWRlCTxzb2NrZXQuaD4KCSNpbmNsdWRlCTx0eXBlcy5oPgoJI2luY2x1ZGUJPHVuaXN0ZC5oPgoJI2luY2x1ZGUJImVtZkludGVybmFsLmgiCiNlbmRpZgoKc3RhdGljIGludAlzb2NrZXREb091dHB1dChzb2NrZXRfdCAqc3AsIGNoYXIgKmJ1ZiwgaW50IHRvV3JpdGUsIGludCAqZXJyQ29kZSk7CnN0YXRpYyBpbnQJdHJ5QWx0ZXJuYXRlU2VuZFRvKGludCBzb2NrLCBjaGFyICpidWYsIGludCB0b1dyaXRlLCBpbnQgaSwKCQkJc3RydWN0IHNvY2thZGRyICpzZXJ2ZXIpOwoKaW50IAkJc29ja2V0SGlnaGVzdEZkID0gLTE7CQoKc29ja2V0X3QJKipzb2NrZXRMaXN0OwkJCQppbnQJCQlzb2NrZXRNYXg7CQkJCQoKCmludAlzb2NrZXRXcml0ZVN0cmluZyhpbnQgc2lkLCBjaGFyX3QgKmJ1ZikKewogI2lmZGVmIFVOSUNPREUKIAljaGFyCSpieXRlQnVmOwogCWludAkJciwgYnVmX2xlbjsKIAogCWJ1Zl9sZW4gPSBnc3RybGVuKGJ1Zik7CiAJYnl0ZUJ1ZiA9IGJhbGxvY1VuaVRvQXNjKGJ1ZiwgYnVmX2xlbik7CiAJciA9IHNvY2tldFdyaXRlKHNpZCwgYnl0ZUJ1ZiwgYnVmX2xlbik7CiAJYmZyZWVTYWZlKEJfTCwgYnl0ZUJ1Zik7CiAJcmV0dXJuIHI7CiAjZWxzZQogCXJldHVybiBzb2NrZXRXcml0ZShzaWQsIGJ1Ziwgc3RybGVuKGJ1ZikpOwogI2VuZGlmIC8qIFVOSUNPREUgKi8KfQoKCmludAlzb2NrZXRXcml0ZShpbnQgc2lkLCBjaGFyICpidWYsIGludCBidWZzaXplKQp7Cglzb2NrZXRfdAkqc3A7CglyaW5ncV90CQkqcnE7CglpbnQJCQlidWZfbGVuLCBieXRlc1dyaXR0ZW4sIHJvb207CgoJYV9hc3NlcnQoYnVmKTsKCWFfYXNzZXJ0KGJ1ZnNpemUgPj0gMCk7CgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJcmV0dXJuIC0xOwoJfQoKCXJxID0gJnNwLT5vdXRCdWY7Cglmb3IgKGJ5dGVzV3JpdHRlbiA9IDA7IGJ1ZnNpemUgPiAwOyApIHsKCQlpZiAoKHJvb20gPSByaW5ncVB1dEJsa01heChycSkpID09IDApIHsKCQkJaWYgKHNvY2tldEZsdXNoKHNpZCkgPCAwKSB7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJaWYgKChyb29tID0gcmluZ3FQdXRCbGtNYXgocnEpKSA9PSAwKSB7CgkJCQlpZiAoc3AtPmZsYWdzICYgU09DS0VUX0JMT0NLKSB7CiNpZiAoZGVmaW5lZCAoV0lOKSB8fCBkZWZpbmVkIChDRSkpCgkJCQkJaW50CQllcnJDb2RlOwoJCQkJCWlmICghIHNvY2tldFdhaXRGb3JFdmVudChzcCwgIEZEX1dSSVRFIHwgU09DS0VUX1dSSVRBQkxFLCAmZXJyQ29kZSkpIHsKCQkJCQkJcmV0dXJuIC0xOwoJCQkJCX0KI2VuZGlmCgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCQljb250aW51ZTsKCQl9CgkJYnVmX2xlbiA9IG1pbihyb29tLCBidWZzaXplKTsKCQlyaW5ncVB1dEJsayhycSwgKHVuc2lnbmVkIGNoYXIgKikgYnVmLCBidWZfbGVuKTsKCQlieXRlc1dyaXR0ZW4gKz0gYnVmX2xlbjsKCQlidWZzaXplIC09IGJ1Zl9sZW47CgkJYnVmICs9IGJ1Zl9sZW47Cgl9CglyZXR1cm4gYnl0ZXNXcml0dGVuOwp9CgoKaW50CXNvY2tldFJlYWQoaW50IHNpZCwgY2hhciAqYnVmLCBpbnQgYnVmc2l6ZSkKewoJc29ja2V0X3QJKnNwOwoJcmluZ3FfdAkJKnJxOwoJaW50CQkJYnVmX2xlbiwgcm9vbSwgZXJyQ29kZSwgYnl0ZXNSZWFkOwoKCWFfYXNzZXJ0KGJ1Zik7CglhX2Fzc2VydChidWZzaXplID4gMCk7CgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJcmV0dXJuIC0xOwoJfQoKCWlmIChzcC0+ZmxhZ3MgJiBTT0NLRVRfRU9GKSB7CgkJcmV0dXJuIDA7Cgl9CgoJcnEgPSAmc3AtPmluQnVmOwoJZm9yIChieXRlc1JlYWQgPSAwOyBidWZzaXplID4gMDsgKSB7CgkJYnVmX2xlbiA9IG1pbihyaW5ncUxlbihycSksIGJ1ZnNpemUpOwoJCWlmIChidWZfbGVuIDw9IDApIHsKCgkJCWlmICgoc3AtPmZsYWdzICYgU09DS0VUX0JMT0NLKSAmJgoJCQkJKGJ5dGVzUmVhZCA+IDApKSB7CgkJCQlicmVhazsKCQkJfQoKCQkJcmluZ3FGbHVzaChycSk7CgkJCXJvb20gPSByaW5ncVB1dEJsa01heChycSk7CgkJCWJ1Zl9sZW4gPSBzb2NrZXRHZXRJbnB1dChzaWQsIChjaGFyICopIHJxLT5lbmRwLCByb29tLCAmZXJyQ29kZSk7CgkJCWlmIChidWZfbGVuIDwgMCkgewoJCQkJaWYgKGVyckNvZGUgPT0gRVdPVUxEQkxPQ0spIHsKCQkJCQlpZiAoKHNwLT5mbGFncyAmIFNPQ0tFVF9CTE9DSykgJiYKCQkJCQkJKGJ5dGVzUmVhZCA9PSAgMCkpIHsKCQkJCQkJY29udGludWU7CgkJCQkJfQovLwkJCQkJaWYgKGJ5dGVzUmVhZCA+PSAwKSB7ICAvLyBrdyAzIDsgIGJ5dGVzUmVhZD49MCBhbHdheXMgYmUgdHJ1ZQoJCQkJCQlyZXR1cm4gYnl0ZXNSZWFkOwovLwkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIC0xOwoKCQkJfSBlbHNlIGlmIChidWZfbGVuID09IDApIHsKCgkJCQlpZiAoYnl0ZXNSZWFkID09IDApIHsKCQkJCQlzcC0+ZmxhZ3MgfD0gU09DS0VUX0VPRjsKCQkJCX0KCQkJCXJldHVybiBieXRlc1JlYWQ7CgkJCX0KCQkJcmluZ3FQdXRCbGtBZGoocnEsIGJ1Zl9sZW4pOwoJCQlidWZfbGVuID0gbWluKGJ1Zl9sZW4sIGJ1ZnNpemUpOwoJCX0KCQltZW1jcHkoJmJ1ZltieXRlc1JlYWRdLCBycS0+c2VydnAsIGJ1Zl9sZW4pOwoJCXJpbmdxR2V0QmxrQWRqKHJxLCBidWZfbGVuKTsKCQlidWZzaXplIC09IGJ1Zl9sZW47CgkJYnl0ZXNSZWFkICs9IGJ1Zl9sZW47Cgl9CglyZXR1cm4gYnl0ZXNSZWFkOwp9CgppbnQgc29ja2V0Rmx1c2goaW50IHNpZCkKewoJc29ja2V0X3QJKnNwOwoJcmluZ3FfdAkJKnJxOwoJaW50CQkJcnFfbGVuLCBieXRlc1dyaXR0ZW4sIGVyckNvZGU7CglpbnQgICAgICAgICBlcnJFSU5UUk51bSA9IDA7IC8qIG15cDog08PT2rnmsdxzb2NrZXS07c7zICovCgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJcmV0dXJuIC0xOwoJfQoJcnEgPSAmc3AtPm91dEJ1ZjsKCglpZiAoISAoc3AtPmZsYWdzICYgU09DS0VUX0JMT0NLKSkgewoJCXNwLT5mbGFncyB8PSBTT0NLRVRfRkxVU0hJTkc7Cgl9CgoJd2hpbGUgKHJpbmdxTGVuKHJxKSA+IDApIHsKCQlycV9sZW4gPSByaW5ncUdldEJsa01heCgmc3AtPm91dEJ1Zik7CgkJYnl0ZXNXcml0dGVuID0gc29ja2V0RG9PdXRwdXQoc3AsIChjaGFyKikgcnEtPnNlcnZwLCBycV9sZW4sICZlcnJDb2RlKTsKCQlpZiAoYnl0ZXNXcml0dGVuIDwgMCkgewoJCQlpZiAoZXJyQ29kZSA9PSBFSU5UUiAmJiBlcnJFSU5UUk51bSsrIDwgMTAwMCkgewoJCQkJY29udGludWU7Ci8vCQkJfSBlbHNlIGlmIChlcnJDb2RlID09IEVXT1VMREJMT0NLIHx8IGVyckNvZGUgPT0gRUFHQUlOKSB7IGt3IDMgICAvLyAjZGVmaW5lCUVXT1VMREJMT0NLCUVBR0FJTgogICAgICAgICAgICB9IGVsc2UgaWYgKGVyckNvZGUgPT0gRUFHQUlOKSB7CgkJCQlpZiAoc3AtPnNhdmVNYXNrIDwgMCApIHsKCQkJCQlzcC0+c2F2ZU1hc2sgPSBzcC0+aGFuZGxlck1hc2s7CgkJCQkJc29ja2V0UmVnaXN0ZXJJbnRlcmVzdChzcCwgCgkJCQkJc3AtPmhhbmRsZXJNYXNrIHwgU09DS0VUX1dSSVRBQkxFKTsKCQkJCX0KCQkJCXJldHVybiAwOwoJCQl9CgkJCXJldHVybiAtMTsKCQl9CgkJcmluZ3FHZXRCbGtBZGoocnEsIGJ5dGVzV3JpdHRlbik7Cgl9CgoJaWYgKHJpbmdxTGVuKHJxKSA9PSAwKSB7CgkJcmluZ3FGbHVzaChycSk7Cgl9CgoJaWYgKHNwLT5zYXZlTWFzayA+PSAwKSB7CgkJc29ja2V0UmVnaXN0ZXJJbnRlcmVzdChzcCwgc3AtPnNhdmVNYXNrKTsKCQlzcC0+c2F2ZU1hc2sgPSAtMTsKCX0KCXNwLT5mbGFncyAmPSB+U09DS0VUX0ZMVVNISU5HOwoJcmV0dXJuIDA7Cn0KCmludAlzb2NrZXRHZXRzKGludCBzaWQsIGNoYXJfdCAqKmJ1ZikKewoJc29ja2V0X3QJKnNwOwoJcmluZ3FfdAkJKmxxOwoJY2hhcgkJYyA9ICdcMCc7IC8vY292CglpbnQJCQlyYywgcnFfbGVuOwoKCWFfYXNzZXJ0KGJ1Zik7CgkqYnVmID0gTlVMTDsKCglpZiAoKHNwID0gc29ja2V0UHRyKHNpZCkpID09IE5VTEwpIHsKCQlyZXR1cm4gLTE7Cgl9CglscSA9ICZzcC0+bGluZUJ1ZjsKCgl3aGlsZSAocmluZ3FMZW4obHEpIDwgMTUzNikgewoKCQlpZiAoKHJjID0gc29ja2V0UmVhZChzaWQsICZjLCAxKSkgPCAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJCgkJaWYgKHJjID09IDApIHsKCQkJaWYgKHJpbmdxTGVuKGxxKSA+IDAgJiYgKHNwLT5mbGFncyAmIFNPQ0tFVF9FT0YpKSB7CgkJCQljID0gJ1xuJzsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiAtMTsKCQkJfQoJCX0KCgkJaWYgKGMgPT0gJ1xuJykgewoJCQlycV9sZW4gPSByaW5ncUxlbihscSk7CgkJCWlmIChycV9sZW4gPiAwKSB7CgkJCQkqYnVmID0gYmFsbG9jQXNjVG9VbmkoKGNoYXIgKilscS0+c2VydnAsIHJxX2xlbik7CgkJCX0gZWxzZSB7CgkJCQkqYnVmID0gTlVMTDsKCQkJfQoJCQlyaW5ncUZsdXNoKGxxKTsKCQkJcmV0dXJuIHJxX2xlbjsKCgkJfSBlbHNlIGlmIChjID09ICdccicpIHsKCQkJY29udGludWU7CgkJfQoJCXJpbmdxUHV0Y0EobHEsIGMpOwoJfQoJcmluZ3FGbHVzaChscSk7CglyZXR1cm4gLTE7Cn0KCgppbnQgc29ja2V0SW5wdXRCdWZmZXJlZChpbnQgc2lkKQp7Cglzb2NrZXRfdAkqc3A7CgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKHNvY2tldEVvZihzaWQpKSB7CgkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIHJpbmdxTGVuKCZzcC0+bGluZUJ1ZikgKyByaW5ncUxlbigmc3AtPmluQnVmKTsKfQoKaW50IHNvY2tldEVvZihpbnQgc2lkKQp7Cglzb2NrZXRfdAkqc3A7CgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIHNwLT5mbGFncyAmIFNPQ0tFVF9FT0Y7Cn0KCnZvaWQgc29ja2V0Q3JlYXRlSGFuZGxlcihpbnQgc2lkLCBpbnQgaGFuZGxlck1hc2ssIHNvY2tldEhhbmRsZXJfdCBoYW5kbGVyLCAKCQlpbnQgZGF0YSkKewoJc29ja2V0X3QJKnNwOwoKCWlmICgoc3AgPSBzb2NrZXRQdHIoc2lkKSkgPT0gTlVMTCkgewoJCXJldHVybjsKCX0KCXNwLT5oYW5kbGVyID0gaGFuZGxlcjsKCXNwLT5oYW5kbGVyX2RhdGEgPSBkYXRhOwoJc29ja2V0UmVnaXN0ZXJJbnRlcmVzdChzcCwgaGFuZGxlck1hc2spOwp9CgpzdGF0aWMgaW50IHNvY2tldERvT3V0cHV0KHNvY2tldF90ICpzcCwgY2hhciAqYnVmLCBpbnQgdG9Xcml0ZSwgaW50ICplcnJDb2RlKQp7CglzdHJ1Y3Qgc29ja2FkZHJfaW4Jc2VydmVyOwoJaW50CQkJCQlieXRlczsKCglhX2Fzc2VydChzcCk7CglhX2Fzc2VydChidWYpOwoJYV9hc3NlcnQodG9Xcml0ZSA+IDApOwoJYV9hc3NlcnQoZXJyQ29kZSk7CgoJKmVyckNvZGUgPSAwOwoKCWlmIChzcC0+ZmxhZ3MgJiBTT0NLRVRfQlJPQURDQVNUKSB7CgkJc2VydmVyLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwoJCXNlcnZlci5zaW5fYWRkci5zX2FkZHIgPSBJTkFERFJfQlJPQURDQVNUOwoJCXNlcnZlci5zaW5fcG9ydCA9IGh0b25zKChzaG9ydCkoc3AtPnBvcnQgJiAweEZGRkYpKTsKCQlieXRlcyA9IHNlbmR0byhzcC0+c29jaywgYnVmLCB0b1dyaXRlLCAwLChzdHJ1Y3Qgc29ja2FkZHIgKikgJnNlcnZlciwgc2l6ZW9mKHNlcnZlcikpOwoJfSBlbHNlIGlmIChzcC0+ZmxhZ3MgJiBTT0NLRVRfREFUQUdSQU0pIHsKCQlzZXJ2ZXIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CgkJc2VydmVyLnNpbl9hZGRyLnNfYWRkciA9IGluZXRfYWRkcihzcC0+aG9zdCk7CgkJc2VydmVyLnNpbl9wb3J0ID0gaHRvbnMoKHNob3J0KShzcC0+cG9ydCAmIDB4RkZGRikpOwoJCWJ5dGVzID0gc2VuZHRvKHNwLT5zb2NrLCBidWYsIHRvV3JpdGUsIDAsKHN0cnVjdCBzb2NrYWRkciAqKSAmc2VydmVyLCBzaXplb2Yoc2VydmVyKSk7CgoJfSBlbHNlIHsKCQlieXRlcyA9IHNlbmQoc3AtPnNvY2ssIGJ1ZiwgdG9Xcml0ZSwgMCk7Cgl9CgoJaWYgKGJ5dGVzIDwgMCkgewoJCSplcnJDb2RlID0gc29ja2V0R2V0RXJyb3IoKTsKICAgICAgICAvL3ByaW50ZigiXG4gc29ja2V0RG9PdXRwdXQgRVJST1I6IGJ5dGVzID0gJWQsICplcnJDb2RlID0gJWQhICIsIGJ5dGVzLCAqZXJyQ29kZSk7CgkJcmV0dXJuIC0xOwoKCX0gZWxzZSBpZiAoYnl0ZXMgPT0gMCAmJiBieXRlcyAhPSB0b1dyaXRlKSB7CgkJKmVyckNvZGUgPSBFV09VTERCTE9DSzsKICAgICAgICAvL3ByaW50ZigiXG4gc29ja2V0RG9PdXRwdXQgRVJST1I6IGJ5dGVzID0gJWQsICplcnJDb2RlID0gJWQhICIsIGJ5dGVzLCAqZXJyQ29kZSk7CgkJcmV0dXJuIC0xOwoJfQoKCXJldHVybiBieXRlczsKfQoKdm9pZCBzb2NrZXREZWxldGVIYW5kbGVyKGludCBzaWQpCnsKCXNvY2tldF90CSpzcDsKCglpZiAoKHNwID0gc29ja2V0UHRyKHNpZCkpID09IE5VTEwpIHsKCQlyZXR1cm47Cgl9CglzcC0+aGFuZGxlciA9IE5VTEw7Cglzb2NrZXRSZWdpc3RlckludGVyZXN0KHNwLCAwKTsKfQoKaW50IHNvY2tldEFsbG9jKGNoYXIgKmhvc3QsIGludCBwb3J0LCBzb2NrZXRBY2NlcHRfdCBhY2NlcHQsIGludCBmbGFncykKewoJc29ja2V0X3QJKnNwOwoJaW50CQkJc2lkOwoKCWlmICgoc2lkID0gaEFsbG9jRW50cnkoKHZvaWQqKiopICZzb2NrZXRMaXN0LCAmc29ja2V0TWF4LAoJCQlzaXplb2Yoc29ja2V0X3QpKSkgPCAwKSB7CgkJcmV0dXJuIC0xOwoJfQoJc3AgPSBzb2NrZXRMaXN0W3NpZF07CgoJc3AtPnNpZCA9IHNpZDsKCXNwLT5hY2NlcHQgPSBhY2NlcHQ7CglzcC0+cG9ydCA9IHBvcnQ7CglzcC0+ZmlsZUhhbmRsZSA9IC0xOwoJc3AtPnNhdmVNYXNrID0gLTE7CgoJaWYgKGhvc3QpIHsKCQlzdHJuY3B5KHNwLT5ob3N0LCBob3N0LCBzaXplb2Yoc3AtPmhvc3QpLTEpOwoJfQoKCWFfYXNzZXJ0KChmbGFncyAmIH4oU09DS0VUX0JST0FEQ0FTVHxTT0NLRVRfREFUQUdSQU18U09DS0VUX0JMT0NLfAoJCQkJCQlTT0NLRVRfTElTVEVOSU5HKSkgPT0gMCk7CglzcC0+ZmxhZ3MgPSBmbGFncyAmIChTT0NLRVRfQlJPQURDQVNUIHwgU09DS0VUX0RBVEFHUkFNIHwgU09DS0VUX0JMT0NLfAoJCQkJCQlTT0NLRVRfTElTVEVOSU5HKTsKCgoJcmluZ3FPcGVuKCZzcC0+aW5CdWYsIFNPQ0tFVF9CVUZTSVosIFNPQ0tFVF9CVUZTSVopOwoJcmluZ3FPcGVuKCZzcC0+b3V0QnVmLCBTT0NLRVRfQlVGU0laICsgMSwgU09DS0VUX0JVRlNJWiArIDEpOwoJcmluZ3FPcGVuKCZzcC0+bGluZUJ1ZiwgU09DS0VUX0JVRlNJWiwgLTEpOwoKCXJldHVybiBzaWQ7Cn0KCnZvaWQgc29ja2V0RnJlZShpbnQgc2lkKQp7Cglzb2NrZXRfdAkqc3A7CgljaGFyX3QJCWJ1ZlsyNTZdOwoJaW50CQkJaTsKCWludCByZWN2X2xlbiA9IC0xOwoKCWlmICgoc3AgPSBzb2NrZXRQdHIoc2lkKSkgPT0gTlVMTCkgewoJCXJldHVybjsKCX0KCglzb2NrZXRSZWdpc3RlckludGVyZXN0KHNwLCAwKTsKCWlmIChzcC0+c29jayA+PSAwKSB7CgkJc29ja2V0U2V0QmxvY2soc2lkLCAwKTsKCQlpZiAoc2h1dGRvd24oc3AtPnNvY2ssIDEpID49IDApIHsKCQkJcmVjdl9sZW4gPSByZWN2KHNwLT5zb2NrLCBidWYsIHNpemVvZihidWYpLCAwKTsKCQkJaWYocmVjdl9sZW4gPCAwKXsKCQkJCTsKCQkJfWVsc2UgaWYocmVjdl9sZW4gPT0gMCl7CgkJCQkvLyDV4sDvse3KvrbUtsu1xHNvY2tldNLR1f2zo7nYsdU/CgkJCQk7CgkJCX1lbHNlIGlmKHJlY3ZfbGVuID09IHNpemVvZihidWYpKXsKCQkJCTsKCQkJfWVsc2V7CgkJCQk7Ly8g0OjSqtTZtM62wcihCgkJCX0KCQl9CiNpZiAoZGVmaW5lZCAoV0lOKSB8fCBkZWZpbmVkIChDRSkpCgkJY2xvc2Vzb2NrZXQoc3AtPnNvY2spOwojZWxzZQoJCWNsb3NlKHNwLT5zb2NrKTsKI2VuZGlmCgl9CgoJcmluZ3FDbG9zZSgmc3AtPmluQnVmKTsKCXJpbmdxQ2xvc2UoJnNwLT5vdXRCdWYpOwoJcmluZ3FDbG9zZSgmc3AtPmxpbmVCdWYpOwoKCWJmcmVlKEJfTCwgc3ApOwoJc29ja2V0TWF4ID0gaEZyZWUoKHZvaWQqKiopICZzb2NrZXRMaXN0LCBzaWQpOwoKCXNvY2tldEhpZ2hlc3RGZCA9IC0xOwoJZm9yIChpID0gMDsgaSA8IHNvY2tldE1heDsgaSsrKSB7CgkJaWYgKChzcCA9IHNvY2tldExpc3RbaV0pID09IE5VTEwpIHsKCQkJY29udGludWU7CgkJfSAKCQlzb2NrZXRIaWdoZXN0RmQgPSBtYXgoc29ja2V0SGlnaGVzdEZkLCBzcC0+c29jayk7Cgl9Cn0KCgppbnQgc29ja2V0R2V0RXJyb3IoKQp7CiNpZiAoZGVmaW5lZCAoV0lOKSB8fCBkZWZpbmVkIChDRSkpCglzd2l0Y2ggKFdTQUdldExhc3RFcnJvcigpKSB7CgljYXNlIFdTQUVXT1VMREJMT0NLOgoJCXJldHVybiBFV09VTERCTE9DSzsKCWNhc2UgV1NBRUNPTk5SRVNFVDoKCQlyZXR1cm4gRUNPTk5SRVNFVDsKCWNhc2UgV1NBRU5FVERPV046CgkJcmV0dXJuIEVORVRET1dOOwoJY2FzZSBXU0FFUFJPQ0xJTToKCQlyZXR1cm4gRUFHQUlOOwoJY2FzZSBXU0FFSU5UUjoKCQlyZXR1cm4gRUlOVFI7CglkZWZhdWx0OgoJCXJldHVybiBFSU5WQUw7Cgl9CiNlbHNlCglyZXR1cm4gZXJybm87CiNlbmRpZgp9Cgpzb2NrZXRfdCAqc29ja2V0UHRyKGludCBzaWQpCnsKCWlmIChzaWQgPCAwIHx8IHNpZCA+PSBzb2NrZXRNYXggfHwgc29ja2V0TGlzdFtzaWRdID09IE5VTEwpIHsKCQlhX2Fzc2VydChOVUxMKTsKCQllcnJubyA9IEVCQURGOwoJCXJldHVybiBOVUxMOwoJfQoKCWFfYXNzZXJ0KHNvY2tldExpc3Rbc2lkXSk7CglyZXR1cm4gc29ja2V0TGlzdFtzaWRdOwp9CgppbnQgc29ja2V0R2V0SGFuZGxlKGludCBzaWQpCnsKCXNvY2tldF90CSpzcDsKCglpZiAoKHNwID0gc29ja2V0UHRyKHNpZCkpID09IE5VTEwpIHsKCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gc3AtPnNvY2s7Cn0KCmludCBzb2NrZXRHZXRCbG9jayhpbnQgc2lkKQp7Cglzb2NrZXRfdAkqc3A7CgoJaWYgKChzcCA9IHNvY2tldFB0cihzaWQpKSA9PSBOVUxMKSB7CgkJYV9hc3NlcnQoMCk7CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gKHNwLT5mbGFncyAmIFNPQ0tFVF9CTE9DSyk7Cn0KCmludCBzb2NrZXRHZXRNb2RlKGludCBzaWQpCnsKCXNvY2tldF90CSpzcDsKCglpZiAoKHNwID0gc29ja2V0UHRyKHNpZCkpID09IE5VTEwpIHsKCQlhX2Fzc2VydCgwKTsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBzcC0+ZmxhZ3M7Cn0KCnZvaWQgc29ja2V0U2V0TW9kZShpbnQgc2lkLCBpbnQgbW9kZSkKewoJc29ja2V0X3QJKnNwOwoKCWlmICgoc3AgPSBzb2NrZXRQdHIoc2lkKSkgPT0gTlVMTCkgewoJCWFfYXNzZXJ0KDApOwoJCXJldHVybjsKCX0KCXNwLT5mbGFncyA9IG1vZGU7Cn0KCmludCBzb2NrZXRHZXRQb3J0KGludCBzaWQpCnsKCXNvY2tldF90CSpzcDsKCglpZiAoKHNwID0gc29ja2V0UHRyKHNpZCkpID09IE5VTEwpIHsKCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gc3AtPnBvcnQ7Cn0KCg==