LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKZXh0ZXJuIFdPUkQgV0lOQVBJIFNZU1RFTV9LaWxsU3lzdGVtVGltZXIoIFdPUkQgdGltZXIgKTsKCnN0YXRpYyB2b2lkIE1aX0luaXRQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUsIFdPUkQgZW52ICkKewogUERCKnBzcD1scFBTUDsKIGNvbnN0IGNoYXIqY21kPWNtZGxpbmU/c3RyY2hyKGNtZGxpbmUsJyAnKTpOVUxMOwoKIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KIHBzcC0+bmV4dFBhcmFncmFwaD0weDlGRkY7CiBwc3AtPmVudmlyb25tZW50PWVudjsKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBtZW1vcnkgc3R1ZmYgZnJvbSBXaW5lIChtc2Rvcy9kb3NtZW0uYykgKi8KIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIFBEQiBzdHVmZiBmcm9tIFdpbmUgKGxvYWRlci90YXNrLmMpICovCn0KCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7CiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl94bXMpLCYobHBEb3NUYXNrLT54bXNfc2VnKSk7CiBtZW1jcHkoc3RhcnQsZW50ZXJfeG1zLHNpemVvZihlbnRlcl94bXMpKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfcG1bXT17CiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4NTIsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWJwICovCiAweDg5LDB4RTUsICAgICAgICAgICAvKiBtb3Z3ICVzcCwlYnAgKi8KLyogZ2V0IHJldHVybiBDUyAqLwogMHg4QiwweDU2LDB4MDgsICAgICAgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgY2hhciB3cmFwX3JtW109ewogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIHVuc2lnbmVkIHNpemU9c2l6ZW9mKGVudGVyX3BtKStzaXplb2Yod3JhcF9ybSk7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplLCYobHBEb3NUYXNrLT5kcG1pX3NlZykpOwogCiBscERvc1Rhc2stPmRwbWlfc2VsID0gU0VMRUNUT1JfQWxsb2NCbG9jayggc3RhcnQsIHNpemUsIFNFR01FTlRfQ09ERSwgRkFMU0UsIEZBTFNFICk7CiBscERvc1Rhc2stPndyYXBfb2ZzID0gc2l6ZS1zaXplb2Yod3JhcF9ybSk7CiBscERvc1Rhc2stPmNhbGxfb2ZzID0gc2l6ZS0xOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKIG1lbWNweShzdGFydCtzaXplb2YoZW50ZXJfcG0pLHdyYXBfcm0sc2l6ZW9mKHdyYXBfcm0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKaW50IE1aX0luaXRNZW1vcnkoIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIGludCB4OwoKIGlmIChscERvc1Rhc2stPmltZ19vZnMpIHJldHVybiAzMjsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIDA7CiB9CiBUUkFDRShtb2R1bGUsIkRPUyBWTTg2IGltYWdlIG1hcHBlZCBhdCAlMDhseFxuIiwoRFdPUkQpbHBEb3NUYXNrLT5pbWcpOwogcE1vZHVsZS0+ZG9zX2ltYWdlPWxwRG9zVGFzay0+aW1nOwoKIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KGxwRG9zVGFzay0+aE1vZHVsZSk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKc3RhdGljIGludCBNWl9Mb2FkSW1hZ2UoIEhGSUxFMTYgaEZpbGUsIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogaW50IHgsb2xkX2NvbT0wOwogU0VHUFRSIHJlbG9jOwogV09SRCBlbnZfc2VnOwoKIGlmICgoX2hyZWFkMTYoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSkgIT0gc2l6ZW9mKG16X2hlYWRlcikpIHx8CiAgICAgKG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpKSB7CiNpZiAwCiAgICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwojZW5kaWYKICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoSEZJTEUxNl9UT19IRklMRTMyKGhGaWxlKSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLHBNb2R1bGUpOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssZW52LG5hbWUpOwoKIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KIFRSQUNFKG1vZHVsZSwiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIobW9kdWxlLCAiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIobW9kdWxlLCAiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+bG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKIE1aX0luaXRQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBlbnZfc2VnKTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBfbGxzZWVrMTYoaEZpbGUsaW1hZ2Vfc3RhcnQsRklMRV9CRUdJTik7CiBpZiAoKF9ocmVhZDE2KGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSkpICE9IGltYWdlX3NpemUpCiAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9sZmFybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgX2xsc2VlazE2KGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKF9scmVhZDE2KGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpKSAhPSBzaXplb2YocmVsb2MpKQogICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1scERvc1Rhc2stPmxvYWRfc2VnOwogIH0KIH0KCiBscERvc1Rhc2stPmluaXRfY3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+aW5pdF9pcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+aW5pdF9zcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogbHBEb3NUYXNrLT5pbml0X3NwPW16X2hlYWRlci5lX3NwOwoKIFRSQUNFKG1vZHVsZSwiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixscERvc1Rhc2stPmluaXRfY3MsbHBEb3NUYXNrLT5pbml0X2lwKTsKCiByZXR1cm4gbHBEb3NUYXNrLT5oTW9kdWxlOwp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSk7CiBORV9NT0RVTEUgKnBNb2R1bGU7CgogaWYgKGxwRG9zVGFzaykgewogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwoKICBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzaywgcE1vZHVsZSk7CgogIEdsb2JhbFVubG9jazE2KGhNb2R1bGUpOwogfQogcmV0dXJuIGxwRG9zVGFzazsKfQoKaW50IE1aX0luaXRUYXNrKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogaW50IHJlYWRfZmRbMl0sd3JpdGVfZmRbMl07CiBwaWRfdCBjaGlsZDsKIGNoYXIgKmZuYW1lLCpmYXJnLGFyZ1sxNl0sZnByb2NbNjRdLHBhdGhbMjU2XSwqZnBhdGg7CgogaWYgKCFscERvc1Rhc2spIHJldHVybiAwOwogLyogY3JlYXRlIHJlYWQgcGlwZSAqLwogaWYgKHBpcGUocmVhZF9mZCk8MCkgcmV0dXJuIDA7CiBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPnJlYWRfcGlwZT1yZWFkX2ZkWzBdOwogbHBEb3NUYXNrLT53cml0ZV9waXBlPXdyaXRlX2ZkWzFdOwogLyogaWYgd2UgaGF2ZSBhIG1hcHBpbmcgZmlsZSwgdXNlIGl0ICovCiBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKIGlmICghZm5hbWVbMF0pIHsKICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogIHNwcmludGYoZnByb2MsIi9wcm9jLyVkL21lbSIsZ2V0cGlkKCkpOwogIHNwcmludGYoYXJnLCIlbGQiLCh1bnNpZ25lZCBsb25nKWxwRG9zVGFzay0+aW1nKTsKICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiB9CgogVFJBQ0UobW9kdWxlLCJMb2FkaW5nIERPUyBWTSBzdXBwb3J0IG1vZHVsZSAoaG1vZHVsZT0lMDR4KVxuIixscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKChjaGlsZD1mb3JrKCkpPDApIHsKICBjbG9zZSh3cml0ZV9mZFswXSk7IGNsb3NlKHdyaXRlX2ZkWzFdKTsKICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2UocmVhZF9mZFsxXSk7IHJldHVybiAwOwogfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZShyZWFkX2ZkWzFdKTsgY2xvc2Uod3JpdGVfZmRbMF0pOwogIGxwRG9zVGFzay0+dGFzaz1jaGlsZDsKICAvKiB3YWl0IGZvciBjaGlsZCBwcm9jZXNzIHRvIHNpZ25hbCByZWFkaW5lc3MgKi8KICBkbyB7CiAgIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpIT1zaXplb2YocmV0KSkgewogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKG1vZHVsZSwiZG9zbW9kIGhhcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZVxuIik7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgIHJldHVybiAwOwogICB9CiAgfSB3aGlsZSAoMCk7CiAgLyogdGhlIGNoaWxkIGhhcyBub3cgbW1hcGVkIHRoZSB0ZW1wIGZpbGUsIGl0J3Mgbm93IHNhZmUgdG8gdW5saW5rLgogICAqIGRvIGl0IGhlcmUgdG8gYXZvaWQgbGVhdmluZyBhIG1lc3MgaW4gL3RtcCBpZi93aGVuIFdpbmUgY3Jhc2hlcy4uLiAqLwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgLyogcHV0IG91ciBwaXBlcyBzb21ld2hlcmUgZG9zbW9kIGNhbiBmaW5kIHRoZW0gKi8KICBkdXAyKHdyaXRlX2ZkWzBdLDApOyAgICAgIC8qIHN0ZGluICovCiAgZHVwMihyZWFkX2ZkWzFdLDEpOyAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICBleGVjbHAoImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICBleGVjbCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGhtbSwgdGhleSBkaWRuJ3QgaW5zdGFsbCBwcm9wZXJseSAqLwogIGV4ZWNsKCJsb2FkZXIvZG9zL2Rvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBsYXN0IHJlc29ydCwgdHJ5IHRvIGZpbmQgaXQgdGhyb3VnaCBhcmd2WzBdICovCiAgZnBhdGg9c3RycmNocihzdHJjcHkocGF0aCxPcHRpb25zLmFyZ3YwKSwnLycpOwogIGlmIChmcGF0aCkgewogICBzdHJjcHkoZnBhdGgsIi9sb2FkZXIvZG9zL2Rvc21vZCIpOwogICBleGVjbChwYXRoLGZuYW1lLGZhcmcsTlVMTCk7CiAgfQogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIobW9kdWxlLCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIDU1SHogdGltZXIgKi8KIGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyID0gQ3JlYXRlU3lzdGVtVGltZXIoIDU1LCBNWl9UaWNrICk7CiBUUkFDRShtb2R1bGUsImNyZWF0ZWQgNTVIeiB0aW1lciB0aWNrLCBoYW5kbGU9JWRcbiIsbHBEb3NUYXNrLT5zeXN0ZW1fdGltZXIpOwogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBOVUxMOyAvKiBrZWVwIGdjYyBmcm9tIGNvbXBsYWluaW5nICovCiBITU9EVUxFMTYgaE1vZHVsZTsKIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKIFBEQjMyICpwZGIgPSBQUk9DRVNTX0N1cnJlbnQoKTsKIFREQiAqcFRhc2sgPSAoVERCKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IHBUYXNrID8gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApIDogTlVMTDsKIEhGSUxFMTYgaEZpbGU7CiBPRlNUUlVDVCBvZnM7CiBpbnQgZXJyLCBhbGxvYyA9ICEocE1vZHVsZSAmJiBwTW9kdWxlLT5kb3NfaW1hZ2UpOwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CgogaWYgKGFsbG9jICYmIChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICByZXR1cm4gMDsKCiBpZiAoKGhGaWxlID0gT3BlbkZpbGUxNiggbmFtZSwgJm9mcywgT0ZfUkVBRCApKSA9PSBIRklMRV9FUlJPUjE2KQogIHJldHVybiAyOyAvKiBGaWxlIG5vdCBmb3VuZCAqLwoKIGlmICgoIWVudikmJnBkYikgZW52ID0gcGRiLT5lbnZfZGItPmVudmlyb247CiBpZiAoYWxsb2MpIHsKICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoJm9mcykpIDwgMzIpCiAgIHJldHVybiBoTW9kdWxlOwoKICBscERvc1Rhc2stPmhNb2R1bGUgPSBoTW9kdWxlOwoKICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKICBwTW9kdWxlLT5scERvc1Rhc2sgPSBscERvc1Rhc2s7CiAKICBscERvc1Rhc2stPmltZz1OVUxMOyBscERvc1Rhc2stPm1tX25hbWVbMF09MDsgbHBEb3NUYXNrLT5tbV9mZD0tMTsKIH0gZWxzZSBscERvc1Rhc2s9cE1vZHVsZS0+bHBEb3NUYXNrOwogZXJyID0gTVpfTG9hZEltYWdlKCBoRmlsZSwgbmFtZSwgY21kbGluZSwgZW52LCBscERvc1Rhc2ssIHBNb2R1bGUgKTsKIF9sY2xvc2UxNihoRmlsZSk7CiBpZiAoYWxsb2MpIHsKICBwTW9kdWxlLT5kb3NfaW1hZ2UgPSBscERvc1Rhc2stPmltZzsKICBpZiAoZXJyPDMyKSB7CiAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9mZD49MCkgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiAgICB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgfSBlbHNlCiAgICBpZiAobHBEb3NUYXNrLT5pbWchPU5VTEwpIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICAgcmV0dXJuIGVycjsKICB9CiAgZXJyID0gTVpfSW5pdFRhc2soIGxwRG9zVGFzayApOwogIGlmIChlcnI8MzIpIHsKICAgTVpfS2lsbE1vZHVsZSggbHBEb3NUYXNrICk7CiAgIC8qIEZJWE1FOiBjbGVhbnVwIGhNb2R1bGUgKi8KICAgcmV0dXJuIGVycjsKICB9CgogIGhJbnN0YW5jZSA9IE5FX0NyZWF0ZUluc3RhbmNlKHBNb2R1bGUsIE5VTEwsIChjbWRsaW5lID09IE5VTEwpKTsKICBQUk9DRVNTX0NyZWF0ZSggcE1vZHVsZSwgY21kbGluZSwgZW52LCBoSW5zdGFuY2UsIDAsIHN0YXJ0dXAsIGluZm8gKTsKICByZXR1cm4gaEluc3RhbmNlOwogfSBlbHNlIHsKICByZXR1cm4gKGVycjwzMikgPyBlcnIgOiBwVGFzay0+aEluc3RhbmNlOwogfQp9Cgp2b2lkIE1aX0tpbGxNb2R1bGUoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBUUkFDRShtb2R1bGUsImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogU1lTVEVNX0tpbGxTeXN0ZW1UaW1lcihscERvc1Rhc2stPnN5c3RlbV90aW1lcik7CiBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiB9IGVsc2UgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogY2xvc2UobHBEb3NUYXNrLT5yZWFkX3BpcGUpOwogY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwojaWYgMAogLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KIGlmIChscERvc1Rhc2stPmRwbWlfc2VsKQogIFVuTWFwTFMoUFRSX1NFR19PRkZfVE9fU0VHUFRSKGxwRG9zVGFzay0+ZHBtaV9zZWwsMCkpOwojZW5kaWYKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiByZXR1cm4gKEhNT0RVTEUxNikxMTsgIC8qIGludmFsaWQgZXhlICovCn0KCiNlbmRpZgo=