LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgPHN5cy92bTg2Lmg+CgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBTVEFSVF9PRkZTRVQgMAojZGVmaW5lIFBTUF9TSVpFIDB4MTAKCiNkZWZpbmUgU0VHMTYocHRyLHNlZykgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRCkoc2VnKTw8NCkpKQojZGVmaW5lIFNFR1BUUjE2KHB0cixzZWdwdHIpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpU0VMRUNUT1JPRihzZWdwdHIpPDw0KStPRkZTRVRPRihzZWdwdHIpKSkKCnN0YXRpYyB2b2lkIE1aX0luaXRQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBtZW1vcnkgc3R1ZmYgZnJvbSBXaW5lIChtc2Rvcy9kb3NtZW0uYykgKi8KIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIFBEQiBzdHVmZiBmcm9tIFdpbmUgKGxvYWRlci90YXNrLmMpICovCn0KCnN0YXRpYyBjaGFyIGVudGVyX3BtW109ewogMHg1MCwgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHg1MiwgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgIC8qIHB1c2h3ICVicCAqLwogMHg4OSwweEU1LCAgICAgIC8qIG1vdncgJXNwLCVicCAqLwovKiBnZXQgcmV0dXJuIENTICovCiAweDhCLDB4NTYsMHgwOCwgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgIC8qIGludCAweDMxICovCi8qIGZpeHVwIG91ciBzdGFjazsgcmV0dXJuIGFkZHJlc3Mgd2lsbCBiZSBsb3N0LCBidXQgd2Ugd29uJ3Qgd29ycnkgcXVpdGUgeWV0ICovCiAweDhFLDB4RDAsICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDg5LDB4RUMsICAgICAgLyogbW92dyAlYnAsJXNwICovCi8qIHNldCByZXR1cm4gQ1MgKi8KIDB4ODksMHg1NiwweDA4LCAvKiBtb3Z3ICVkeCw4KCVicCkgKi8KIDB4NUQsICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgIC8qIHBvcHcgJWR4ICovCiAweDU4LCAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0IgICAgICAgICAgICAvKiByZXRmICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl9wbSksJihscERvc1Rhc2stPmRwbWlfc2VnKSk7CiAKIGxwRG9zVGFzay0+ZHBtaV9zZWwgPSBTRUxFQ1RPUl9BbGxvY0Jsb2NrKCBzdGFydCwgc2l6ZW9mKGVudGVyX3BtKSwgU0VHTUVOVF9DT0RFLCBGQUxTRSwgVFJVRSApOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKaW50IE1aX0luaXRNZW1vcnkoIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIGludCB4OwoKIGlmIChscERvc1Rhc2stPmltZ19vZnMpIHJldHVybiAzMjsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIDA7CiB9CiBUUkFDRShtb2R1bGUsIkRPUyBWTTg2IGltYWdlIG1hcHBlZCBhdCAlMDhseFxuIiwoRFdPUkQpbHBEb3NUYXNrLT5pbWcpOwogcE1vZHVsZS0+ZG9zX2ltYWdlPWxwRG9zVGFzay0+aW1nOwoKIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KGxwRG9zVGFzay0+aE1vZHVsZSk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIDMyOwp9CgpzdGF0aWMgaW50IE1aX0xvYWRJbWFnZSggSEZJTEUxNiBoRmlsZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKIGludCB4LG9sZF9jb209MDsKIFNFR1BUUiByZWxvYzsKCiBpZiAoKF9ocmVhZDE2KGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlcikpICE9IHNpemVvZihtel9oZWFkZXIpKSB8fAogICAgIChtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSkgewojaWYgMAogICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KI2VuZGlmCiAgb2xkX2NvbT0xOyAvKiBhc3N1bWUgLkNPTSBmaWxlICovCiAgaW1hZ2Vfc3RhcnQ9MDsKICBpbWFnZV9zaXplPUdldEZpbGVTaXplKEhGSUxFMTZfVE9fSEZJTEUzMihoRmlsZSksTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayxwTW9kdWxlKTsKCiAvKiBGSVhNRTogYWxsb2NhdGUgbWVtb3J5IGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMgKi8KCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRShtb2R1bGUsIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZShscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKG1vZHVsZSwgImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKG1vZHVsZSwgImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPmxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9Jbml0UFNQKHBzcF9zdGFydCwgY21kbGluZSwgZW52KTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgJXMgaW1hZ2Ugc2l6ZSwgJTA4bHggYnl0ZXNcbiIsb2xkX2NvbT8iQ09NIjoiRVhFIixpbWFnZV9zaXplKTsKIF9sbHNlZWsxNihoRmlsZSxpbWFnZV9zdGFydCxGSUxFX0JFR0lOKTsKIGlmICgoX2hyZWFkMTYoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplKSkgIT0gaW1hZ2Vfc2l6ZSkKICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2xmYXJsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBfbGxzZWVrMTYoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoX2xyZWFkMTYoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpCiAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIC8qIGluaXRpYWxpemUgbW9kdWxlIHZhcmlhYmxlcyAqLwogcE1vZHVsZS0+Y3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIHBNb2R1bGUtPmlwPW16X2hlYWRlci5lX2lwOwogcE1vZHVsZS0+c3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIHBNb2R1bGUtPnNwPW16X2hlYWRlci5lX3NwOwogcE1vZHVsZS0+c2VsZl9sb2FkaW5nX3NlbD1scERvc1Rhc2stPnBzcF9zZWc7CgogVFJBQ0UobW9kdWxlLCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLHBNb2R1bGUtPmNzLHBNb2R1bGUtPmlwKTsKCiAvKiBpbml0aWFsaXplIHZtODYgc3RydWN0ICovCiAvKiBub3RlOiB0aGlzIG1heSBiZSBtb3ZlZCBzb29uLCB0byBiZSBhYmxlIHRvIHJlbW92ZSBWTTg2IGZyb20gbHBEb3NUYXNrCiAgICAoZ290IHRpcmVkIG9mIGFsbCB0aG9zZSBjb21waWxlciB3YXJuaW5ncywgYW5kIGRvbid0IGxpa2UgdGhlIHN5c3RlbSBkZXBlbmRlbmN5KSAqLwogbWVtc2V0KCZscERvc1Rhc2stPlZNODYsMCxzaXplb2YobHBEb3NUYXNrLT5WTTg2KSk7CiBscERvc1Rhc2stPlZNODYucmVncy5jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5WTTg2LnJlZ3MuZWlwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5WTTg2LnJlZ3Muc3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmVzcD1tel9oZWFkZXIuZV9zcDsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmRzPWxwRG9zVGFzay0+cHNwX3NlZzsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmVzPWxwRG9zVGFzay0+cHNwX3NlZzsKIC8qIGhtbSwgd2hhdCBlbHNlIGRvIHdlIG5lZWQ/ICovCgogcmV0dXJuIDMyOwp9CgppbnQgTVpfSW5pdFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBpbnQgcmVhZF9mZFsyXSx3cml0ZV9mZFsyXTsKIHBpZF90IGNoaWxkOwogY2hhciAqZm5hbWUsKmZhcmcsYXJnWzE2XSxmcHJvY1s2NF0scGF0aFsyNTZdLCpmcGF0aDsKCiAvKiBjcmVhdGUgcmVhZCBwaXBlICovCiBpZiAocGlwZShyZWFkX2ZkKTwwKSByZXR1cm4gMDsKIGlmIChwaXBlKHdyaXRlX2ZkKTwwKSB7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+cmVhZF9waXBlPXJlYWRfZmRbMF07CiBscERvc1Rhc2stPndyaXRlX3BpcGU9d3JpdGVfZmRbMV07CiBscERvc1Rhc2stPmZuPVZNODZfRU5URVI7CiBscERvc1Rhc2stPnN0YXRlPTE7CiAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KIGZuYW1lPWxwRG9zVGFzay0+bW1fbmFtZTsgZmFyZz1OVUxMOwogaWYgKCFmbmFtZVswXSkgewogIC8qIG90aGVyd2lzZSwgbWFwIG91ciBvd24gbWVtb3J5IGltYWdlICovCiAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgc3ByaW50ZihhcmcsIiVsZCIsKHVuc2lnbmVkIGxvbmcpbHBEb3NUYXNrLT5pbWcpOwogIGZuYW1lPWZwcm9jOyBmYXJnPWFyZzsKIH0KCiBUUkFDRShtb2R1bGUsIlByZXBhcmluZyB0byBsb2FkIERPUyBWTSBzdXBwb3J0IG1vZHVsZTogZm9ya2luZ1xuIik7CiBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogIGNsb3NlKHdyaXRlX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHJlYWRfZmRbMV0pOyBjbG9zZSh3cml0ZV9mZFswXSk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIGRvIHsKICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSkhPXNpemVvZihyZXQpKSB7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIobW9kdWxlLCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIDA7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogYWxsIHN5c3RlbXMgYXJlIG5vdyBnbyAqLwogfSBlbHNlIHsKICAvKiBjaGlsZCBwcm9jZXNzICovCiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHdyaXRlX2ZkWzFdKTsKICAvKiBwdXQgb3VyIHBpcGVzIHNvbWV3aGVyZSBkb3Ntb2QgY2FuIGZpbmQgdGhlbSAqLwogIGR1cDIod3JpdGVfZmRbMF0sMCk7ICAgICAgLyogc3RkaW4gKi8KICBkdXAyKHJlYWRfZmRbMV0sMSk7ICAgICAgIC8qIHN0ZG91dCAqLwogIC8qIG5vdyBsb2FkIGRvc21vZCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaG1tLCB0aGV5IGRpZG4ndCBpbnN0YWxsIHByb3Blcmx5ICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgcmVzb3J0LCB0cnkgdG8gZmluZCBpdCB0aHJvdWdoIGFyZ3ZbMF0gKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLE9wdGlvbnMuYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICB9CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiAzMjsKfQoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBOVUxMOyAvKiBrZWVwIGdjYyBmcm9tIGNvbXBsYWluaW5nICovCiBITU9EVUxFMTYgaE1vZHVsZTsKIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKIFREQiAqcFRhc2sgPSAoVERCKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IHBUYXNrID8gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApIDogTlVMTDsKIEhGSUxFMTYgaEZpbGU7CiBPRlNUUlVDVCBvZnM7CiBpbnQgZXJyLCBhbGxvYyA9ICEocE1vZHVsZSAmJiBwTW9kdWxlLT5kb3NfaW1hZ2UpOwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CgogaWYgKGFsbG9jICYmIChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICByZXR1cm4gMDsKCiBpZiAoKGhGaWxlID0gT3BlbkZpbGUxNiggbmFtZSwgJm9mcywgT0ZfUkVBRCApKSA9PSBIRklMRV9FUlJPUjE2KQogIHJldHVybiAyOyAvKiBGaWxlIG5vdCBmb3VuZCAqLwoKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7CiBpZiAobHBEb3NUYXNrLT5kcG1pX3NlbCkKICBVbk1hcExTKFBUUl9TRUdfT0ZGX1RPX1NFR1BUUihscERvc1Rhc2stPmRwbWlfc2VsLDApKTsKfQoKaW50IE1aX1J1bk1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKLyogdHJhbnNtaXQgdGhlIGN1cnJlbnQgY29udGV4dCBzdHJ1Y3R1cmUgdG8gdGhlIERPUyB0YXNrICovCiBpZiAobHBEb3NUYXNrLT5zdGF0ZT09MSkgewogIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJmxwRG9zVGFzay0+Zm4sc2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSE9c2l6ZW9mKGxwRG9zVGFzay0+Zm4pKQogICByZXR1cm4gLTE7CiAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmbHBEb3NUYXNrLT5WTTg2LHNpemVvZihscERvc1Rhc2stPlZNODYpKSE9c2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpCiAgIHJldHVybiAtMTsKICBscERvc1Rhc2stPnN0YXRlPTI7CiB9Ci8qIHdhaXQgZm9yIGFub3RoZXIgY29udGV4dCBzdHJ1Y3R1cmUgdG8gYXBwZWFyICh0aGlzIG1heSBibG9jaykgKi8KIGlmIChscERvc1Rhc2stPnN0YXRlPT0yKSB7CiAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJmxwRG9zVGFzay0+Zm4sc2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSE9c2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSB7CiAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSByZXR1cm4gMDsKICAgcmV0dXJuIC0xOwogIH0KICBscERvc1Rhc2stPnN0YXRlPTM7CiB9CiBpZiAobHBEb3NUYXNrLT5zdGF0ZT09MykgewogIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZscERvc1Rhc2stPlZNODYsc2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpIT1zaXplb2YobHBEb3NUYXNrLT5WTTg2KSkgewogICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgcmV0dXJuIDA7CiAgIHJldHVybiAtMTsKICB9Ci8qIGdvdCBvbmUgKi8KICBscERvc1Rhc2stPnN0YXRlPTE7CiAgcmV0dXJuIDE7CiB9CiByZXR1cm4gMDsKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiByZXR1cm4gKEhNT0RVTEUxNikxMTsgIC8qIGludmFsaWQgZXhlICovCn0KCiNlbmRpZgo=