LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY3N0ci5jLHYgMS4xMCAyMDAyLzA4LzMxIDIyOjE3OjMyIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKRmNDaGFyOCAqCkZjU3RyQ29weSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOAkqcjsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIHIgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgcykgKyAxKTsKICAgIGlmICghcikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc3RybGVuICgoY2hhciAqKSBzKSArIDEpOwogICAgc3RyY3B5ICgoY2hhciAqKSByLCAoY2hhciAqKSBzKTsKICAgIHJldHVybiByOwp9CgpGY0NoYXI4ICoKRmNTdHJQbHVzIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIGludAkgICAgbCA9IHN0cmxlbiAoKGNoYXIgKilzMSkgKyBzdHJsZW4gKChjaGFyICopIHMyKSArIDE7CiAgICBGY0NoYXI4ICpzID0gbWFsbG9jIChsKTsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIGwpOwogICAgc3RyY3B5ICgoY2hhciAqKSBzLCAoY2hhciAqKSBzMSk7CiAgICBzdHJjYXQgKChjaGFyICopIHMsIChjaGFyICopIHMyKTsKICAgIHJldHVybiBzOwp9Cgp2b2lkCkZjU3RyRnJlZSAoRmNDaGFyOCAqcykKewogICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSSU5HLCBzdHJsZW4gKChjaGFyICopIHMpICsgMSk7CiAgICBmcmVlIChzKTsKfQoKaW50CkZjU3RyQ21wSWdub3JlQ2FzZSAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4IGMxLCBjMjsKICAgIAogICAgZm9yICg7OykgCiAgICB7CgljMSA9ICpzMSsrOwoJYzIgPSAqczIrKzsKCWlmICghYzEpCgkgICAgYnJlYWs7CglpZiAoYzEgIT0gYzIpCgl7CgkgICAgYzEgPSBGY1RvTG93ZXIgKGMxKTsKCSAgICBjMiA9IEZjVG9Mb3dlciAoYzIpOwoJICAgIGlmIChjMSAhPSBjMikKCQlicmVhazsKCX0KICAgIH0KICAgIHJldHVybiAoaW50KSBjMSAtIChpbnQpIGMyOwp9CgppbnQKRmNTdHJDbXBJZ25vcmVCbGFua3NBbmRDYXNlIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgCiAgICBmb3IgKDs7KSAKICAgIHsKCWRvCgkgICAgYzEgPSAqczErKzsKCXdoaWxlIChjMSA9PSAnICcpOwoJZG8KCSAgICBjMiA9ICpzMisrOwoJd2hpbGUgKGMyID09ICcgJyk7CglpZiAoIWMxIHx8ICFjMikKCSAgICBicmVhazsKCWMxID0gRmNUb0xvd2VyIChjMSk7CgljMiA9IEZjVG9Mb3dlciAoYzIpOwoJaWYgKGMxICE9IGMyKQoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChpbnQpIGMxIC0gKGludCkgYzI7Cn0KCmludApGY1N0ckNtcCAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4IGMxLCBjMjsKICAgIAogICAgaWYgKHMxID09IHMyKQoJcmV0dXJuIDA7CiAgICBmb3IgKDs7KSAKICAgIHsKCWMxID0gKnMxKys7CgljMiA9ICpzMisrOwoJaWYgKCFjMSB8fCAhYzIpCgkgICAgYnJlYWs7CglpZiAoYzEgIT0gYzIpCgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKGludCkgYzEgLSAoaW50KSBjMjsKfQoKaW50CkZjVXRmOFRvVWNzNCAoY29uc3QgRmNDaGFyOCAqc3JjX29yaWcsCgkgICAgICBGY0NoYXIzMgkgICAgKmRzdCwKCSAgICAgIGludAkgICAgbGVuKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKnNyYyA9IHNyY19vcmlnOwogICAgRmNDaGFyOAkgICAgczsKICAgIGludAkJICAgIGV4dHJhOwogICAgRmNDaGFyMzIJICAgIHJlc3VsdDsKCiAgICBpZiAobGVuID09IDApCglyZXR1cm4gMDsKICAgIAogICAgcyA9ICpzcmMrKzsKICAgIGxlbi0tOwogICAgCiAgICBpZiAoIShzICYgMHg4MCkpCiAgICB7CglyZXN1bHQgPSBzOwoJZXh0cmEgPSAwOwogICAgfSAKICAgIGVsc2UgaWYgKCEocyAmIDB4NDApKQogICAgewoJcmV0dXJuIC0xOwogICAgfQogICAgZWxzZSBpZiAoIShzICYgMHgyMCkpCiAgICB7CglyZXN1bHQgPSBzICYgMHgxZjsKCWV4dHJhID0gMTsKICAgIH0KICAgIGVsc2UgaWYgKCEocyAmIDB4MTApKQogICAgewoJcmVzdWx0ID0gcyAmIDB4ZjsKCWV4dHJhID0gMjsKICAgIH0KICAgIGVsc2UgaWYgKCEocyAmIDB4MDgpKQogICAgewoJcmVzdWx0ID0gcyAmIDB4MDc7CglleHRyYSA9IDM7CiAgICB9CiAgICBlbHNlIGlmICghKHMgJiAweDA0KSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweDAzOwoJZXh0cmEgPSA0OwogICAgfQogICAgZWxzZSBpZiAoICEgKHMgJiAweDAyKSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweDAxOwoJZXh0cmEgPSA1OwogICAgfQogICAgZWxzZQogICAgewoJcmV0dXJuIC0xOwogICAgfQogICAgaWYgKGV4dHJhID4gbGVuKQoJcmV0dXJuIC0xOwogICAgCiAgICB3aGlsZSAoZXh0cmEtLSkKICAgIHsKCXJlc3VsdCA8PD0gNjsKCXMgPSAqc3JjKys7CgkKCWlmICgocyAmIDB4YzApICE9IDB4ODApCgkgICAgcmV0dXJuIC0xOwoJCglyZXN1bHQgfD0gcyAmIDB4M2Y7CiAgICB9CiAgICAqZHN0ID0gcmVzdWx0OwogICAgcmV0dXJuIHNyYyAtIHNyY19vcmlnOwp9CgpGY0Jvb2wKRmNVdGY4TGVuIChjb25zdCBGY0NoYXI4ICAgICpzdHJpbmcsCgkgICBpbnQJCSAgICBsZW4sCgkgICBpbnQJCSAgICAqbmNoYXIsCgkgICBpbnQJCSAgICAqd2NoYXIpCnsKICAgIGludAkJbjsKICAgIGludAkJY2xlbjsKICAgIEZjQ2hhcjMyCWM7CiAgICBGY0NoYXIzMgltYXg7CiAgICAKICAgIG4gPSAwOwogICAgbWF4ID0gMDsKICAgIHdoaWxlIChsZW4pCiAgICB7CgljbGVuID0gRmNVdGY4VG9VY3M0IChzdHJpbmcsICZjLCBsZW4pOwoJaWYgKGNsZW4gPD0gMCkJLyogbWFsZm9ybWVkIFVURjggc3RyaW5nICovCgkgICAgcmV0dXJuIEZjRmFsc2U7CglpZiAoYyA+IG1heCkKCSAgICBtYXggPSBjOwoJc3RyaW5nICs9IGNsZW47CglsZW4gLT0gY2xlbjsKCW4rKzsKICAgIH0KICAgICpuY2hhciA9IG47CiAgICBpZiAobWF4ID49IDB4MTAwMDApCgkqd2NoYXIgPSA0OwogICAgZWxzZSBpZiAobWF4ID4gMHgxMDApCgkqd2NoYXIgPSAyOwogICAgZWxzZQoJKndjaGFyID0gMTsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY1VjczRUb1V0ZjggKEZjQ2hhcjMyCXVjczQsCgkgICAgICBGY0NoYXI4CWRlc3RbRkNfVVRGOF9NQVhfTEVOXSkKewogICAgaW50CWJpdHM7CiAgICBGY0NoYXI4ICpkID0gZGVzdDsKICAgIAogICAgaWYgICAgICAodWNzNCA8ICAgICAgIDB4ODApIHsgICpkKys9ICB1Y3M0OyAgICAgICAgICAgICAgICAgICAgICAgICBiaXRzPSAtNjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgICAgMHg4MDApIHsgICpkKys9ICgodWNzNCA+PiAgNikgJiAweDFGKSB8IDB4QzA7ICBiaXRzPSAgMDsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgIDB4MTAwMDApIHsgICpkKys9ICgodWNzNCA+PiAxMikgJiAweDBGKSB8IDB4RTA7ICBiaXRzPSAgNjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgMHgyMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAxOCkgJiAweDA3KSB8IDB4RjA7ICBiaXRzPSAxMjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAweDQwMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAyNCkgJiAweDAzKSB8IDB4Rjg7ICBiaXRzPSAxODsgfQogICAgZWxzZSBpZiAodWNzNCA8IDB4ODAwMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAzMCkgJiAweDAxKSB8IDB4RkM7ICBiaXRzPSAyNDsgfQogICAgZWxzZSByZXR1cm4gMDsKCiAgICBmb3IgKCA7IGJpdHMgPj0gMDsgYml0cy09IDYpIHsKCSpkKys9ICgodWNzNCA+PiBiaXRzKSAmIDB4M0YpIHwgMHg4MDsKICAgIH0KICAgIHJldHVybiBkIC0gZGVzdDsKfQoKI2RlZmluZSBHZXRVdGYxNihzcmMsZW5kaWFuKSBcCiAgICAoKEZjQ2hhcjE2KSAoKHNyYylbZW5kaWFuID09IEZjRW5kaWFuQmlnID8gMCA6IDFdIDw8IDgpIHwgXAogICAgIChGY0NoYXIxNikgKChzcmMpW2VuZGlhbiA9PSBGY0VuZGlhbkJpZyA/IDEgOiAwXSkpCgppbnQKRmNVdGYxNlRvVWNzNCAoY29uc3QgRmNDaGFyOAkqc3JjX29yaWcsCgkgICAgICAgRmNFbmRpYW4JCWVuZGlhbiwKCSAgICAgICBGY0NoYXIzMgkJKmRzdCwKCSAgICAgICBpbnQJCWxlbikJLyogaW4gYnl0ZXMgKi8KewogICAgY29uc3QgRmNDaGFyOCAgICpzcmMgPSBzcmNfb3JpZzsKICAgIEZjQ2hhcjE2CSAgICBhLCBiOwogICAgRmNDaGFyMzIJICAgIHJlc3VsdDsKCiAgICBpZiAobGVuIDwgMikKCXJldHVybiAwOwogICAgCiAgICBhID0gR2V0VXRmMTYgKHNyYywgZW5kaWFuKTsgc3JjICs9IDI7IGxlbiAtPSAyOwogICAgCiAgICAvKiAKICAgICAqIENoZWNrIGZvciBzdXJyb2dhdGUgCiAgICAgKi8KICAgIGlmICgoYSAmIDB4ZmMwMCkgPT0gMHhkODAwKQogICAgewoJaWYgKGxlbiA8IDIpCgkgICAgcmV0dXJuIDA7CgliID0gR2V0VXRmMTYgKHNyYywgZW5kaWFuKTsgc3JjICs9IDI7IGxlbiAtPSAyOwoJLyoKCSAqIENoZWNrIGZvciBpbnZhbGlkIHN1cnJvZ2F0ZSBzZXF1ZW5jZQoJICovCglpZiAoKGIgJiAweGZjMDApICE9IDB4ZGMwMCkKCSAgICByZXR1cm4gMDsKCXJlc3VsdCA9ICgoKChGY0NoYXIzMikgYSAmIDB4M2ZmKSA8PCAxMCkgfAoJCSAgKChGY0NoYXIzMikgYiAmIDB4M2ZmKSkgKyAweDEwMDAwOwogICAgfQogICAgZWxzZQoJcmVzdWx0ID0gYTsKICAgICpkc3QgPSByZXN1bHQ7CiAgICByZXR1cm4gc3JjIC0gc3JjX29yaWc7Cn0KCkZjQm9vbApGY1V0ZjE2TGVuIChjb25zdCBGY0NoYXI4ICAgKnN0cmluZywKCSAgICBGY0VuZGlhbgkgICAgZW5kaWFuLAoJICAgIGludAkJICAgIGxlbiwJLyogaW4gYnl0ZXMgKi8KCSAgICBpbnQJCSAgICAqbmNoYXIsCgkgICAgaW50CQkgICAgKndjaGFyKQp7CiAgICBpbnQJCW47CiAgICBpbnQJCWNsZW47CiAgICBGY0NoYXIzMgljOwogICAgRmNDaGFyMzIJbWF4OwogICAgCiAgICBuID0gMDsKICAgIG1heCA9IDA7CiAgICB3aGlsZSAobGVuKQogICAgewoJY2xlbiA9IEZjVXRmMTZUb1VjczQgKHN0cmluZywgZW5kaWFuLCAmYywgbGVuKTsKCWlmIChjbGVuIDw9IDApCS8qIG1hbGZvcm1lZCBVVEY4IHN0cmluZyAqLwoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKGMgPiBtYXgpCgkgICAgbWF4ID0gYzsKCXN0cmluZyArPSBjbGVuOwoJbGVuIC09IGNsZW47CgluKys7CiAgICB9CiAgICAqbmNoYXIgPSBuOwogICAgaWYgKG1heCA+PSAweDEwMDAwKQoJKndjaGFyID0gNDsKICAgIGVsc2UgaWYgKG1heCA+IDB4MTAwKQoJKndjaGFyID0gMjsKICAgIGVsc2UKCSp3Y2hhciA9IDE7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjU3RyQnVmSW5pdCAoRmNTdHJCdWYgKmJ1ZiwgRmNDaGFyOCAqaW5pdCwgaW50IHNpemUpCnsKICAgIGJ1Zi0+YnVmID0gaW5pdDsKICAgIGJ1Zi0+YWxsb2NhdGVkID0gRmNGYWxzZTsKICAgIGJ1Zi0+ZmFpbGVkID0gRmNGYWxzZTsKICAgIGJ1Zi0+bGVuID0gMDsKICAgIGJ1Zi0+c2l6ZSA9IHNpemU7Cn0KCnZvaWQKRmNTdHJCdWZEZXN0cm95IChGY1N0ckJ1ZiAqYnVmKQp7CiAgICBpZiAoYnVmLT5hbGxvY2F0ZWQpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9TVFJCVUYsIGJ1Zi0+c2l6ZSk7CglmcmVlIChidWYtPmJ1Zik7CglGY1N0ckJ1ZkluaXQgKGJ1ZiwgMCwgMCk7CiAgICB9Cn0KCkZjQ2hhcjggKgpGY1N0ckJ1ZkRvbmUgKEZjU3RyQnVmICpidWYpCnsKICAgIEZjQ2hhcjggKnJldDsKCiAgICByZXQgPSBtYWxsb2MgKGJ1Zi0+bGVuICsgMSk7CiAgICBpZiAocmV0KQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgYnVmLT5sZW4gKyAxKTsKCW1lbWNweSAocmV0LCBidWYtPmJ1ZiwgYnVmLT5sZW4pOwoJcmV0W2J1Zi0+bGVuXSA9ICdcMCc7CiAgICB9CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKGJ1Zik7CiAgICByZXR1cm4gcmV0Owp9CgpGY0Jvb2wKRmNTdHJCdWZDaGFyIChGY1N0ckJ1ZiAqYnVmLCBGY0NoYXI4IGMpCnsKICAgIGlmIChidWYtPmxlbiA9PSBidWYtPnNpemUpCiAgICB7CglGY0NoYXI4CSAgICAqbmV3OwoJaW50CSAgICBzaXplOwoKCWlmIChidWYtPmFsbG9jYXRlZCkKCXsKCSAgICBzaXplID0gYnVmLT5zaXplICogMjsKCSAgICBuZXcgPSByZWFsbG9jIChidWYtPmJ1Ziwgc2l6ZSk7Cgl9CgllbHNlCgl7CgkgICAgc2l6ZSA9IGJ1Zi0+c2l6ZSArIDEwMjQ7CgkgICAgbmV3ID0gbWFsbG9jIChzaXplKTsKCSAgICBpZiAobmV3KQoJICAgIHsKCQlidWYtPmFsbG9jYXRlZCA9IEZjVHJ1ZTsKCQltZW1jcHkgKG5ldywgYnVmLT5idWYsIGJ1Zi0+bGVuKTsKCSAgICB9Cgl9CglpZiAoIW5ldykKCXsKCSAgICBidWYtPmZhaWxlZCA9IEZjVHJ1ZTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KCWlmIChidWYtPnNpemUpCgkgICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSQlVGLCBidWYtPnNpemUpOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUkJVRiwgc2l6ZSk7CglidWYtPnNpemUgPSBzaXplOwoJYnVmLT5idWYgPSBuZXc7CiAgICB9CiAgICBidWYtPmJ1ZltidWYtPmxlbisrXSA9IGM7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJCdWZTdHJpbmcgKEZjU3RyQnVmICpidWYsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjggYzsKICAgIHdoaWxlICgoYyA9ICpzKyspKQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJCdWZEYXRhIChGY1N0ckJ1ZiAqYnVmLCBjb25zdCBGY0NoYXI4ICpzLCBpbnQgbGVuKQp7CiAgICB3aGlsZSAobGVuLS0gPiAwKQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgKnMrKykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJVc2VzSG9tZSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgcmV0dXJuICpzID09ICd+JzsKfQoKRmNDaGFyOCAqCkZjU3RyQ29weUZpbGVuYW1lIChjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY0NoYXI4ICpuZXc7CiAgICAKICAgIGlmICgqcyA9PSAnficpCiAgICB7CglGY0NoYXI4CSpob21lID0gRmNDb25maWdIb21lICgpOwoJaW50CXNpemU7CglpZiAoIWhvbWUpCgkgICAgcmV0dXJuIDA7CglzaXplID0gc3RybGVuICgoY2hhciAqKSBob21lKSArIHN0cmxlbiAoKGNoYXIgKikgcyk7CgluZXcgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHNpemUpOwoJaWYgKCFuZXcpCgkgICAgcmV0dXJuIDA7CglGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCBzaXplKTsKCXN0cmNweSAoKGNoYXIgKikgbmV3LCAoY2hhciAqKSBob21lKTsKCXN0cmNhdCAoKGNoYXIgKikgbmV3LCAoY2hhciAqKSBzICsgMSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglpbnQJc2l6ZSA9IHN0cmxlbiAoKGNoYXIgKikgcykgKyAxOwoJbmV3ID0gKEZjQ2hhcjggKikgbWFsbG9jIChzaXplKTsKCWlmICghbmV3KQoJICAgIHJldHVybiAwOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc2l6ZSk7CglzdHJjcHkgKChjaGFyICopIG5ldywgKGNvbnN0IGNoYXIgKikgcyk7CiAgICB9CiAgICByZXR1cm4gbmV3Owp9CgpGY0NoYXI4ICoKRmNTdHJEaXJuYW1lIChjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBGY0NoYXI4ICpzbGFzaDsKICAgIEZjQ2hhcjggKmRpcjsKCiAgICBzbGFzaCA9IChGY0NoYXI4ICopIHN0cnJjaHIgKChjaGFyICopIGZpbGUsICcvJyk7CiAgICBpZiAoIXNsYXNoKQoJcmV0dXJuIEZjU3RyQ29weSAoKEZjQ2hhcjggKikgIi4iKTsKICAgIGRpciA9IG1hbGxvYyAoKHNsYXNoIC0gZmlsZSkgKyAxKTsKICAgIGlmICghZGlyKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCAoc2xhc2ggLSBmaWxlKSArIDEpOwogICAgc3RybmNweSAoKGNoYXIgKikgZGlyLCAoY29uc3QgY2hhciAqKSBmaWxlLCBzbGFzaCAtIGZpbGUpOwogICAgZGlyW3NsYXNoIC0gZmlsZV0gPSAnXDAnOwogICAgcmV0dXJuIGRpcjsKfQoKRmNDaGFyOCAqCkZjU3RyQmFzZW5hbWUgKGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIEZjQ2hhcjggKnNsYXNoOwoKICAgIHNsYXNoID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgZmlsZSwgJy8nKTsKICAgIGlmICghc2xhc2gpCglyZXR1cm4gRmNTdHJDb3B5IChmaWxlKTsKICAgIHJldHVybiBGY1N0ckNvcHkgKHNsYXNoICsgMSk7Cn0KCkZjU3RyU2V0ICoKRmNTdHJTZXRDcmVhdGUgKHZvaWQpCnsKICAgIEZjU3RyU2V0CSpzZXQgPSBtYWxsb2MgKHNpemVvZiAoRmNTdHJTZXQpKTsKICAgIGlmICghc2V0KQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSU0VULCBzaXplb2YgKEZjU3RyU2V0KSk7CiAgICBzZXQtPnJlZiA9IDE7CiAgICBzZXQtPm51bSA9IDA7CiAgICBzZXQtPnNpemUgPSAwOwogICAgc2V0LT5zdHJzID0gMDsKICAgIHJldHVybiBzZXQ7Cn0KCnN0YXRpYyBGY0Jvb2wKX0ZjU3RyU2V0QXBwZW5kIChGY1N0clNldCAqc2V0LCBGY0NoYXI4ICpzKQp7CiAgICBpZiAoRmNTdHJTZXRNZW1iZXIgKHNldCwgcykpCiAgICB7CglGY1N0ckZyZWUgKHMpOwoJcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGlmIChzZXQtPm51bSA9PSBzZXQtPnNpemUpCiAgICB7CglGY0NoYXI4CSoqc3RycyA9IG1hbGxvYyAoKHNldC0+c2l6ZSArIDIpICogc2l6ZW9mIChGY0NoYXI4ICopKTsKCglpZiAoIXN0cnMpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglGY01lbUFsbG9jIChGQ19NRU1fU1RSU0VULCAoc2V0LT5zaXplICsgMikgKiBzaXplb2YgKEZjQ2hhcjggKikpOwoJc2V0LT5zaXplID0gc2V0LT5zaXplICsgMTsKCWlmIChzZXQtPm51bSkKCSAgICBtZW1jcHkgKHN0cnMsIHNldC0+c3Rycywgc2V0LT5udW0gKiBzaXplb2YgKEZjQ2hhcjggKikpOwoJaWYgKHNldC0+c3RycykKCSAgICBmcmVlIChzZXQtPnN0cnMpOwoJc2V0LT5zdHJzID0gc3RyczsKICAgIH0KICAgIHNldC0+c3Ryc1tzZXQtPm51bSsrXSA9IHM7CiAgICBzZXQtPnN0cnNbc2V0LT5udW1dID0gMDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1N0clNldE1lbWJlciAoRmNTdHJTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgaW50CWk7CgogICAgZm9yIChpID0gMDsgaSA8IHNldC0+bnVtOyBpKyspCglpZiAoIUZjU3RyQ21wIChzZXQtPnN0cnNbaV0sIHMpKQoJICAgIHJldHVybiBGY1RydWU7CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjU3RyU2V0RXF1YWwgKEZjU3RyU2V0ICpzYSwgRmNTdHJTZXQgKnNiKQp7CiAgICBpbnQJaTsKICAgIGlmIChzYS0+bnVtICE9IHNiLT5udW0pCglyZXR1cm4gRmNGYWxzZTsKICAgIGZvciAoaSA9IDA7IGkgPCBzYS0+bnVtOyBpKyspCglpZiAoIUZjU3RyU2V0TWVtYmVyIChzYiwgc2EtPnN0cnNbaV0pKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyU2V0QWRkIChGY1N0clNldCAqc2V0LCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY0NoYXI4ICpuZXcgPSBGY1N0ckNvcHkgKHMpOwogICAgaWYgKCFuZXcpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICghX0ZjU3RyU2V0QXBwZW5kIChzZXQsIG5ldykpCiAgICB7CglGY1N0ckZyZWUgKG5ldyk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1N0clNldEFkZEZpbGVuYW1lIChGY1N0clNldCAqc2V0LCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY0NoYXI4ICpuZXcgPSBGY1N0ckNvcHlGaWxlbmFtZSAocyk7CiAgICBpZiAoIW5ldykKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFfRmNTdHJTZXRBcHBlbmQgKHNldCwgbmV3KSkKICAgIHsKCUZjU3RyRnJlZSAobmV3KTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyU2V0RGVsIChGY1N0clNldCAqc2V0LCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBpbnQJaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5udW07IGkrKykKCWlmICghRmNTdHJDbXAgKHNldC0+c3Ryc1tpXSwgcykpCgl7CgkgICAgRmNTdHJGcmVlIChzZXQtPnN0cnNbaV0pOwoJICAgIC8qCgkgICAgICogY29weSByZW1haW5pbmcgc3RyaW5nIHBvaW50ZXJzIGFuZCB0cmFpbGluZwoJICAgICAqIE5VTEwKCSAgICAgKi8KCSAgICBtZW1tb3ZlICgmc2V0LT5zdHJzW2ldLCAmc2V0LT5zdHJzW2krMV0sIAoJCSAgICAgKHNldC0+bnVtIC0gaSkgKiBzaXplb2YgKEZjQ2hhcjggKikpOwoJICAgIHNldC0+bnVtLS07CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KICAgIHJldHVybiBGY0ZhbHNlOwp9Cgp2b2lkCkZjU3RyU2V0RGVzdHJveSAoRmNTdHJTZXQgKnNldCkKewogICAgaWYgKC0tc2V0LT5yZWYgPT0gMCkKICAgIHsKCWludAlpOwogICAgCglmb3IgKGkgPSAwOyBpIDwgc2V0LT5udW07IGkrKykKCSAgICBGY1N0ckZyZWUgKHNldC0+c3Ryc1tpXSk7CglGY01lbUZyZWUgKEZDX01FTV9TVFJTRVQsIChzZXQtPnNpemUpICogc2l6ZW9mIChGY0NoYXI4ICopKTsKCWlmIChzZXQtPnN0cnMpCgkgICAgZnJlZSAoc2V0LT5zdHJzKTsKCUZjTWVtRnJlZSAoRkNfTUVNX1NUUlNFVCwgc2l6ZW9mIChGY1N0clNldCkpOwoJZnJlZSAoc2V0KTsKICAgIH0KfQoKRmNTdHJMaXN0ICoKRmNTdHJMaXN0Q3JlYXRlIChGY1N0clNldCAqc2V0KQp7CiAgICBGY1N0ckxpc3QJKmxpc3Q7CgogICAgbGlzdCA9IG1hbGxvYyAoc2l6ZW9mIChGY1N0ckxpc3QpKTsKICAgIGlmICghbGlzdCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NUUkxJU1QsIHNpemVvZiAoRmNTdHJMaXN0KSk7CiAgICBsaXN0LT5zZXQgPSBzZXQ7CiAgICBzZXQtPnJlZisrOwogICAgbGlzdC0+biA9IDA7CiAgICByZXR1cm4gbGlzdDsKfQoKRmNDaGFyOCAqCkZjU3RyTGlzdE5leHQgKEZjU3RyTGlzdCAqbGlzdCkKewogICAgaWYgKGxpc3QtPm4gPj0gbGlzdC0+c2V0LT5udW0pCglyZXR1cm4gMDsKICAgIHJldHVybiBsaXN0LT5zZXQtPnN0cnNbbGlzdC0+bisrXTsKfQoKdm9pZApGY1N0ckxpc3REb25lIChGY1N0ckxpc3QgKmxpc3QpCnsKICAgIEZjU3RyU2V0RGVzdHJveSAobGlzdC0+c2V0KTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1NUUkxJU1QsIHNpemVvZiAoRmNTdHJMaXN0KSk7CiAgICBmcmVlIChsaXN0KTsKfQo=