LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl94bXMpLCYobHBEb3NUYXNrLT54bXNfc2VnKSk7CiBtZW1jcHkoc3RhcnQsZW50ZXJfeG1zLHNpemVvZihlbnRlcl94bXMpKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfcG1bXT17CiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4NTIsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWJwICovCiAweDg5LDB4RTUsICAgICAgICAgICAvKiBtb3Z3ICVzcCwlYnAgKi8KLyogZ2V0IHJldHVybiBDUyAqLwogMHg4QiwweDU2LDB4MDgsICAgICAgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgY2hhciB3cmFwX3JtW109ewogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIHVuc2lnbmVkIHNpemU9c2l6ZW9mKGVudGVyX3BtKStzaXplb2Yod3JhcF9ybSk7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplLCYobHBEb3NUYXNrLT5kcG1pX3NlZykpOwogCiBscERvc1Rhc2stPmRwbWlfc2VsID0gU0VMRUNUT1JfQWxsb2NCbG9jayggc3RhcnQsIHNpemUsIFNFR01FTlRfQ09ERSwgRkFMU0UsIEZBTFNFICk7CiBscERvc1Rhc2stPndyYXBfb2ZzID0gc2l6ZS1zaXplb2Yod3JhcF9ybSk7CiBscERvc1Rhc2stPmNhbGxfb2ZzID0gc2l6ZS0xOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKaW50IE1aX0luaXRNZW1vcnkoIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIGludCB4OwoKIGlmIChscERvc1Rhc2stPmltZ19vZnMpIHJldHVybiAzMjsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIDA7CiB9CiBUUkFDRShtb2R1bGUsIkRPUyBWTTg2IGltYWdlIG1hcHBlZCBhdCAlMDhseFxuIiwoRFdPUkQpbHBEb3NUYXNrLT5pbWcpOwogcE1vZHVsZS0+ZG9zX2ltYWdlPWxwRG9zVGFzay0+aW1nOwoKIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KGxwRG9zVGFzay0+aE1vZHVsZSk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIDMyOwp9CgpzdGF0aWMgaW50IE1aX0xvYWRJbWFnZSggSEZJTEUxNiBoRmlsZSwgTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGVudiwgTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQ7CiBpbnQgeCxvbGRfY29tPTA7CiBTRUdQVFIgcmVsb2M7CiBXT1JEIGVudl9zZWc7CgogaWYgKChfaHJlYWQxNihoRmlsZSwmbXpfaGVhZGVyLHNpemVvZihtel9oZWFkZXIpKSAhPSBzaXplb2YobXpfaGVhZGVyKSkgfHwKICAgICAobXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkpIHsKI2lmIDAKICAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiNlbmRpZgogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShIRklMRTE2X1RPX0hGSUxFMzIoaEZpbGUpLE5VTEwpOwogIG1pbl9zaXplPTB4MTAwMDA7IG1heF9zaXplPTB4MTAwMDAwOwogIG16X2hlYWRlci5lX2NybGM9MDsKICBtel9oZWFkZXIuZV9zcz0wOyBtel9oZWFkZXIuZV9zcD0weEZGRkU7CiAgbXpfaGVhZGVyLmVfY3M9MDsgbXpfaGVhZGVyLmVfaXA9MHgxMDA7CiB9IGVsc2UgewogIC8qIGNhbGN1bGF0ZSBsb2FkIHNpemUgKi8KICBpbWFnZV9zdGFydD1tel9oZWFkZXIuZV9jcGFyaGRyPDw0OwogIGltYWdlX3NpemU9bXpfaGVhZGVyLmVfY3A8PDk7IC8qIHBhZ2VzIGFyZSA1MTIgYnl0ZXMgKi8KICBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogIG1pbl9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9taW5hbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKICBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiB9CgogTVpfSW5pdE1lbW9yeShscERvc1Rhc2sscE1vZHVsZSk7CgogLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KGxwRG9zVGFzayxlbnYsbmFtZSk7CgogLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogVFJBQ0UobW9kdWxlLCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKIGF2YWlsPURPU01FTV9BdmFpbGFibGUobHBEb3NUYXNrLT5oTW9kdWxlKTsKIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogIEVSUihtb2R1bGUsICJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgcmV0dXJuIDA7CiB9CiBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsYXZhaWwsJmxwRG9zVGFzay0+cHNwX3NlZyk7CiBpZiAoIXBzcF9zdGFydCkgewogIEVSUihtb2R1bGUsICJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogbHBEb3NUYXNrLT5sb2FkX3NlZz1scERvc1Rhc2stPnBzcF9zZWcrKG9sZF9jb20/MDpQU1BfU0laRSk7CiBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogTVpfSW5pdFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUsIGVudl9zZWcpOwoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyAlcyBpbWFnZSwgJTA4bHggYnl0ZXNcbiIsb2xkX2NvbT8iQ09NIjoiRVhFIixpbWFnZV9zaXplKTsKIF9sbHNlZWsxNihoRmlsZSxpbWFnZV9zdGFydCxGSUxFX0JFR0lOKTsKIGlmICgoX2hyZWFkMTYoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplKSkgIT0gaW1hZ2Vfc2l6ZSkKICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2xmYXJsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBfbGxzZWVrMTYoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoX2xyZWFkMTYoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpCiAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIGxwRG9zVGFzay0+aW5pdF9jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5pbml0X2lwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5pbml0X3NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPmluaXRfc3A9bXpfaGVhZGVyLmVfc3A7CgogVFJBQ0UobW9kdWxlLCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGxwRG9zVGFzay0+aW5pdF9jcyxscERvc1Rhc2stPmluaXRfaXApOwoKIHJldHVybiAzMjsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIEhNT0RVTEUxNiBoTW9kdWxlICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpOwogTkVfTU9EVUxFICpwTW9kdWxlOwoKIGlmIChscERvc1Rhc2spIHsKICBscERvc1Rhc2stPmhNb2R1bGUgPSBoTW9kdWxlOwoKICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKICBwTW9kdWxlLT5scERvc1Rhc2sgPSBscERvc1Rhc2s7CiAKICBscERvc1Rhc2stPmltZz1OVUxMOyBscERvc1Rhc2stPm1tX25hbWVbMF09MDsgbHBEb3NUYXNrLT5tbV9mZD0tMTsKCiAgTVpfSW5pdE1lbW9yeShscERvc1Rhc2ssIHBNb2R1bGUpOwoKICBHbG9iYWxVbmxvY2sxNihoTW9kdWxlKTsKIH0KIHJldHVybiBscERvc1Rhc2s7Cn0KCmludCBNWl9Jbml0VGFzayggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGludCByZWFkX2ZkWzJdLHdyaXRlX2ZkWzJdOwogcGlkX3QgY2hpbGQ7CiBjaGFyICpmbmFtZSwqZmFyZyxhcmdbMTZdLGZwcm9jWzY0XSxwYXRoWzI1Nl0sKmZwYXRoOwoKIGlmICghbHBEb3NUYXNrKSByZXR1cm4gMDsKIC8qIGNyZWF0ZSByZWFkIHBpcGUgKi8KIGlmIChwaXBlKHJlYWRfZmQpPDApIHJldHVybiAwOwogaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2UocmVhZF9mZFsxXSk7IHJldHVybiAwOwogfQogbHBEb3NUYXNrLT5yZWFkX3BpcGU9cmVhZF9mZFswXTsKIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKIC8qIGlmIHdlIGhhdmUgYSBtYXBwaW5nIGZpbGUsIHVzZSBpdCAqLwogZm5hbWU9bHBEb3NUYXNrLT5tbV9uYW1lOyBmYXJnPU5VTEw7CiBpZiAoIWZuYW1lWzBdKSB7CiAgLyogb3RoZXJ3aXNlLCBtYXAgb3VyIG93biBtZW1vcnkgaW1hZ2UgKi8KICBzcHJpbnRmKGZwcm9jLCIvcHJvYy8lZC9tZW0iLGdldHBpZCgpKTsKICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgZm5hbWU9ZnByb2M7IGZhcmc9YXJnOwogfQoKIFRSQUNFKG1vZHVsZSwiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGUgKGhtb2R1bGU9JTA0eClcbiIsbHBEb3NUYXNrLT5oTW9kdWxlKTsKIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgY2xvc2Uod3JpdGVfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2UocmVhZF9mZFsxXSk7IGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBscERvc1Rhc2stPnRhc2s9Y2hpbGQ7CiAgLyogd2FpdCBmb3IgY2hpbGQgcHJvY2VzcyB0byBzaWduYWwgcmVhZGluZXNzICovCiAgZG8gewogICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKSE9c2l6ZW9mKHJldCkpIHsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIC8qIGZhaWx1cmUgKi8KICAgIEVSUihtb2R1bGUsImRvc21vZCBoYXMgZmFpbGVkIHRvIGluaXRpYWxpemVcbiIpOwogICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgICByZXR1cm4gMDsKICAgfQogIH0gd2hpbGUgKDApOwogIC8qIHRoZSBjaGlsZCBoYXMgbm93IG1tYXBlZCB0aGUgdGVtcCBmaWxlLCBpdCdzIG5vdyBzYWZlIHRvIHVubGluay4KICAgKiBkbyBpdCBoZXJlIHRvIGF2b2lkIGxlYXZpbmcgYSBtZXNzIGluIC90bXAgaWYvd2hlbiBXaW5lIGNyYXNoZXMuLi4gKi8KICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgICAgICAvKiBzdGRpbiAqLwogIGR1cDIocmVhZF9mZFsxXSwxKTsgICAgICAgLyogc3Rkb3V0ICovCiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgZXhlY2xwKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgZXhlY2woImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBobW0sIHRoZXkgZGlkbid0IGluc3RhbGwgcHJvcGVybHkgKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogbGFzdCByZXNvcnQsIHRyeSB0byBmaW5kIGl0IHRocm91Z2ggYXJndlswXSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsT3B0aW9ucy5hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxmbmFtZSxmYXJnLE5VTEwpOwogIH0KICAvKiBpZiBmYWlsdXJlLCBleGl0ICovCiAgRVJSKG1vZHVsZSwiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIDMyOwp9CgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogSElOU1RBTkNFMTYgaEluc3RhbmNlOwogUERCMzIgKnBkYiA9IFBST0NFU1NfQ3VycmVudCgpOwogVERCICpwVGFzayA9IChUREIqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwogSEZJTEUxNiBoRmlsZTsKIE9GU1RSVUNUIG9mczsKIGludCBlcnIsIGFsbG9jID0gIShwTW9kdWxlICYmIHBNb2R1bGUtPmRvc19pbWFnZSk7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKCiBpZiAoYWxsb2MgJiYgKGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpKSA9PSBOVUxMKQogIHJldHVybiAwOwoKIGlmICgoaEZpbGUgPSBPcGVuRmlsZTE2KCBuYW1lLCAmb2ZzLCBPRl9SRUFEICkpID09IEhGSUxFX0VSUk9SMTYpCiAgcmV0dXJuIDI7IC8qIEZpbGUgbm90IGZvdW5kICovCgogaWYgKCghZW52KSYmcGRiKSBlbnYgPSBwZGItPmVudl9kYi0+ZW52aXJvbjsKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7CiNpZiAwCiAvKiBGSVhNRTogdGhpcyBzZWVtcyB0byBjcmFzaCAqLwogaWYgKGxwRG9zVGFzay0+ZHBtaV9zZWwpCiAgVW5NYXBMUyhQVFJfU0VHX09GRl9UT19TRUdQVFIobHBEb3NUYXNrLT5kcG1pX3NlbCwwKSk7CiNlbmRpZgp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogV0FSTihtb2R1bGUsIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIHJldHVybiAoSE1PRFVMRTE2KTExOyAgLyogaW52YWxpZCBleGUgKi8KfQoKI2VuZGlmCg==