LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNsaXN0LmMsdiAxLjExdHNpIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZAogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjT2JqZWN0U2V0ICoKRmNPYmplY3RTZXRDcmVhdGUgKHZvaWQpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICBvcyA9IChGY09iamVjdFNldCAqKSBtYWxsb2MgKHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIGlmICghb3MpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RTRVQsIHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIG9zLT5ub2JqZWN0ID0gMDsKICAgIG9zLT5zb2JqZWN0ID0gMDsKICAgIG9zLT5vYmplY3RzID0gMDsKICAgIHJldHVybiBvczsKfQoKRmNCb29sCkZjT2JqZWN0U2V0QWRkIChGY09iamVjdFNldCAqb3MsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQlzOwogICAgY29uc3QgY2hhcgkqKm9iamVjdHM7CiAgICBpbnQJCWhpZ2gsIGxvdywgbWlkLCBjOwogICAgCiAgICBpZiAob3MtPm5vYmplY3QgPT0gb3MtPnNvYmplY3QpCiAgICB7CglzID0gb3MtPnNvYmplY3QgKyA0OwoJaWYgKG9zLT5vYmplY3RzKQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgcmVhbGxvYyAoKHZvaWQgKikgb3MtPm9iamVjdHMsCgkJCQkJICAgICAgIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJZWxzZQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgbWFsbG9jIChzICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWlmICghb2JqZWN0cykKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmIChvcy0+c29iamVjdCkKCSAgICBGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCUZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RQVFIsIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJb3MtPm9iamVjdHMgPSBvYmplY3RzOwoJb3MtPnNvYmplY3QgPSBzOwogICAgfQogICAgaGlnaCA9IG9zLT5ub2JqZWN0IC0gMTsKICAgIGxvdyA9IDA7CiAgICBtaWQgPSAwOwogICAgYyA9IDE7CiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAobG93ICsgaGlnaCkgPj4gMTsKCWMgPSBzdHJjbXAgKG9zLT5vYmplY3RzW21pZF0sIG9iamVjdCk7CglpZiAoYyA9PSAwKQoJICAgIHJldHVybiBGY1RydWU7CglpZiAoYyA8IDApCgkgICAgbG93ID0gbWlkICsgMTsKCWVsc2UKCSAgICBoaWdoID0gbWlkIC0gMTsKICAgIH0KICAgIGlmIChjIDwgMCkKCW1pZCsrOwogICAgbWVtbW92ZSAob3MtPm9iamVjdHMgKyBtaWQgKyAxLCBvcy0+b2JqZWN0cyArIG1pZCwgCgkgICAgIChvcy0+bm9iamVjdCAtIG1pZCkgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwogICAgb3MtPm9iamVjdHNbbWlkXSA9IG9iamVjdDsKICAgIG9zLT5ub2JqZWN0Kys7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjT2JqZWN0U2V0RGVzdHJveSAoRmNPYmplY3RTZXQgKm9zKQp7CiAgICBpZiAob3MtPm9iamVjdHMpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWZyZWUgKCh2b2lkICopIG9zLT5vYmplY3RzKTsKICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX09CSkVDVFNFVCwgc2l6ZW9mIChGY09iamVjdFNldCkpOwogICAgZnJlZSAob3MpOwp9CgpGY09iamVjdFNldCAqCkZjT2JqZWN0U2V0VmFCdWlsZCAoY29uc3QgY2hhciAqZmlyc3QsIHZhX2xpc3QgdmEpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpyZXQ7CgogICAgRmNPYmplY3RTZXRWYXBCdWlsZCAocmV0LCBmaXJzdCwgdmEpOwogICAgcmV0dXJuIHJldDsKfQoKRmNPYmplY3RTZXQgKgpGY09iamVjdFNldEJ1aWxkIChjb25zdCBjaGFyICpmaXJzdCwgLi4uKQp7CiAgICB2YV9saXN0CSAgICB2YTsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICB2YV9zdGFydCAodmEsIGZpcnN0KTsKICAgIEZjT2JqZWN0U2V0VmFwQnVpbGQgKG9zLCBmaXJzdCwgdmEpOwogICAgdmFfZW5kICh2YSk7CiAgICByZXR1cm4gb3M7Cn0KCi8qCiAqIEZvbnQgbXVzdCBoYXZlIGEgY29udGFpbmluZyB2YWx1ZSBmb3IgZXZlcnkgdmFsdWUgaW4gdGhlIHBhdHRlcm4KICovCnN0YXRpYyBGY0Jvb2wKRmNMaXN0VmFsdWVMaXN0TWF0Y2hBbnkgKEZjVmFsdWVMaXN0ICpwYXRPcmlnLAkgICAgLyogcGF0dGVybiAqLwoJCQkgRmNWYWx1ZUxpc3QgKmZudE9yaWcpCSAgICAvKiBmb250ICovCnsKICAgIEZjVmFsdWVMaXN0CSAgICAqcGF0LCAqZm50OwoKICAgIGZvciAocGF0ID0gcGF0T3JpZzsgcGF0OyBwYXQgPSBwYXQtPm5leHQpCiAgICB7Cglmb3IgKGZudCA9IGZudE9yaWc7IGZudDsgZm50ID0gZm50LT5uZXh0KQoJewoJICAgIC8qCgkgICAgICogbWFrZSBzdXJlIHRoZSBmb250ICdjb250YWlucycgdGhlIHBhdHRlcm4uCgkgICAgICogKE9wTGlzdGluZyBpcyBPcENvbnRhaW5zIGV4Y2VwdCBmb3Igc3RyaW5ncwoJICAgICAqICB3aGVyZSBpdCByZXF1aXJlcyBhbiBleGFjdCBtYXRjaCkKCSAgICAgKi8KCSAgICBpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKGZudC0+dmFsdWUsCgkJCQkgICAgICBGY09wTGlzdGluZywgCgkJCQkgICAgICBwYXQtPnZhbHVlKSkgCgkJYnJlYWs7Cgl9CglpZiAoIWZudCkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNMaXN0VmFsdWVMaXN0RXF1YWwgKEZjVmFsdWVMaXN0ICAgKnYxb3JpZywKCQkgICAgICBGY1ZhbHVlTGlzdCAgICp2Mm9yaWcpCnsKICAgIEZjVmFsdWVMaXN0CSAgICAqdjEsICp2MjsKCiAgICBmb3IgKHYxID0gdjFvcmlnOyB2MTsgdjEgPSB2MS0+bmV4dCkKICAgIHsKCWZvciAodjIgPSB2Mm9yaWc7IHYyOyB2MiA9IHYyLT5uZXh0KQoJICAgIGlmIChGY1ZhbHVlRXF1YWwgKHYxLT52YWx1ZSwgdjItPnZhbHVlKSkKCQlicmVhazsKCWlmICghdjIpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBmb3IgKHYyID0gdjJvcmlnOyB2MjsgdjIgPSB2Mi0+bmV4dCkKICAgIHsKCWZvciAodjEgPSB2MW9yaWc7IHYxOyB2MSA9IHYxLT5uZXh0KQoJICAgIGlmIChGY1ZhbHVlRXF1YWwgKHYxLT52YWx1ZSwgdjItPnZhbHVlKSkKCQlicmVhazsKCWlmICghdjEpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjTGlzdFBhdHRlcm5FcXVhbCAoRmNQYXR0ZXJuCSpwMSwKCQkgICAgRmNQYXR0ZXJuCSpwMiwKCQkgICAgRmNPYmplY3RTZXQJKm9zKQp7CiAgICBpbnQJCSAgICBpOwogICAgRmNQYXR0ZXJuRWx0ICAgICplMSwgKmUyOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvcy0+bm9iamVjdDsgaSsrKQogICAgewoJZTEgPSBGY1BhdHRlcm5GaW5kRWx0IChwMSwgb3MtPm9iamVjdHNbaV0pOwoJZTIgPSBGY1BhdHRlcm5GaW5kRWx0IChwMiwgb3MtPm9iamVjdHNbaV0pOwoJaWYgKCFlMSAmJiAhZTIpCgkgICAgY29udGludWU7CglpZiAoIWUxIHx8ICFlMikKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmICghRmNMaXN0VmFsdWVMaXN0RXF1YWwgKGUxLT52YWx1ZXMsIGUyLT52YWx1ZXMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKLyoKICogRmNUcnVlIGlmZiBhbGwgb2JqZWN0cyBpbiAicCIgbWF0Y2ggImZvbnQiCiAqLwoKRmNCb29sCkZjTGlzdFBhdHRlcm5NYXRjaEFueSAoY29uc3QgRmNQYXR0ZXJuICpwLAoJCSAgICAgICBjb25zdCBGY1BhdHRlcm4gKmZvbnQpCnsKICAgIGludAkJICAgIGk7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCiAgICB7CgllID0gRmNQYXR0ZXJuRmluZEVsdCAoZm9udCwgcC0+ZWx0c1tpXS5vYmplY3QpOwoJaWYgKCFlKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY0xpc3RWYWx1ZUxpc3RNYXRjaEFueSAocC0+ZWx0c1tpXS52YWx1ZXMsICAgIC8qIHBhdCBlbHRzICovCgkJCQkgICAgICBlLT52YWx1ZXMpKQkgICAgLyogZm9udCBlbHRzICovCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0U3RyaW5nSGFzaCAoY29uc3QgRmNDaGFyOAkqcykKewogICAgRmNDaGFyMzIJaCA9IDA7CiAgICBGY0NoYXI4CWM7CgogICAgd2hpbGUgKChjID0gKnMrKykpCiAgICB7CgljID0gRmNUb0xvd2VyIChjKTsKCWggPSAoKGggPDwgMykgXiAoaCA+PiAzKSkgXiBjOwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RNYXRyaXhIYXNoIChjb25zdCBGY01hdHJpeCAqbSkKewogICAgaW50CSAgICB4eCA9IChpbnQpIChtLT54eCAqIDEwMCksIAoJICAgIHh5ID0gKGludCkgKG0tPnh5ICogMTAwKSwgCgkgICAgeXggPSAoaW50KSAobS0+eXggKiAxMDApLAoJICAgIHl5ID0gKGludCkgKG0tPnl5ICogMTAwKTsKCiAgICByZXR1cm4gKChGY0NoYXIzMikgeHgpIF4gKChGY0NoYXIzMikgeHkpIF4gKChGY0NoYXIzMikgeXgpIF4gKChGY0NoYXIzMikgeXkpOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0VmFsdWVIYXNoIChGY1ZhbHVlICAgIHYpCnsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVZvaWQ6CglyZXR1cm4gMDsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5pOwogICAgY2FzZSBGY1R5cGVEb3VibGU6CglyZXR1cm4gKEZjQ2hhcjMyKSAoaW50KSB2LnUuZDsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjTGlzdFN0cmluZ0hhc2ggKHYudS5zKTsKICAgIGNhc2UgRmNUeXBlQm9vbDoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5iOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglyZXR1cm4gRmNMaXN0TWF0cml4SGFzaCAodi51Lm0pOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJcmV0dXJuIEZjQ2hhclNldENvdW50ICh2LnUuYyk7CiAgICBjYXNlIEZjVHlwZUZURmFjZToKCXJldHVybiAobG9uZykgdi51LmY7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6CglyZXR1cm4gRmNMYW5nU2V0SGFzaCAodi51LmwpOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RWYWx1ZUxpc3RIYXNoIChGY1ZhbHVlTGlzdCAgICAqbGlzdCkKewogICAgRmNDaGFyMzIJaCA9IDA7CiAgICAKICAgIHdoaWxlIChsaXN0KQogICAgewoJaCA9IGggXiBGY0xpc3RWYWx1ZUhhc2ggKGxpc3QtPnZhbHVlKTsKCWxpc3QgPSBsaXN0LT5uZXh0OwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RQYXR0ZXJuSGFzaCAoRmNQYXR0ZXJuCSpmb250LAoJCSAgIEZjT2JqZWN0U2V0CSpvcykKewogICAgaW50CQkgICAgbjsKICAgIEZjUGF0dGVybkVsdCAgICAqZTsKICAgIEZjQ2hhcjMyCSAgICBoID0gMDsKCiAgICBmb3IgKG4gPSAwOyBuIDwgb3MtPm5vYmplY3Q7IG4rKykKICAgIHsKCWUgPSBGY1BhdHRlcm5GaW5kRWx0IChmb250LCBvcy0+b2JqZWN0c1tuXSk7CglpZiAoZSkKCSAgICBoID0gaCBeIEZjTGlzdFZhbHVlTGlzdEhhc2ggKGUtPnZhbHVlcyk7CiAgICB9CiAgICByZXR1cm4gaDsKfQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjTGlzdEJ1Y2tldCB7CiAgICBzdHJ1Y3QgX0ZjTGlzdEJ1Y2tldCAgICAqbmV4dDsKICAgIEZjQ2hhcjMyCQkgICAgaGFzaDsKICAgIEZjUGF0dGVybgkJICAgICpwYXR0ZXJuOwp9IEZjTGlzdEJ1Y2tldDsKCiNkZWZpbmUgRkNfTElTVF9IQVNIX1NJWkUgICA0MDk5Cgp0eXBlZGVmIHN0cnVjdCBfRmNMaXN0SGFzaFRhYmxlIHsKICAgIGludAkJICAgIGVudHJpZXM7CiAgICBGY0xpc3RCdWNrZXQgICAgKmJ1Y2tldHNbRkNfTElTVF9IQVNIX1NJWkVdOwp9IEZjTGlzdEhhc2hUYWJsZTsKICAgIApzdGF0aWMgdm9pZApGY0xpc3RIYXNoVGFibGVJbml0IChGY0xpc3RIYXNoVGFibGUgKnRhYmxlKQp7CiAgICB0YWJsZS0+ZW50cmllcyA9IDA7CiAgICBtZW1zZXQgKHRhYmxlLT5idWNrZXRzLCAnXDAnLCBzaXplb2YgKHRhYmxlLT5idWNrZXRzKSk7Cn0KCnN0YXRpYyB2b2lkCkZjTGlzdEhhc2hUYWJsZUNsZWFudXAgKEZjTGlzdEhhc2hUYWJsZSAqdGFibGUpCnsKICAgIGludAlpOwogICAgRmNMaXN0QnVja2V0ICAgICpidWNrZXQsICpuZXh0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBGQ19MSVNUX0hBU0hfU0laRTsgaSsrKQogICAgewoJZm9yIChidWNrZXQgPSB0YWJsZS0+YnVja2V0c1tpXTsgYnVja2V0OyBidWNrZXQgPSBuZXh0KQoJewoJICAgIG5leHQgPSBidWNrZXQtPm5leHQ7CgkgICAgRmNQYXR0ZXJuRGVzdHJveSAoYnVja2V0LT5wYXR0ZXJuKTsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9MSVNUQlVDSywgc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKCSAgICBmcmVlIChidWNrZXQpOwoJfQoJdGFibGUtPmJ1Y2tldHNbaV0gPSAwOwogICAgfQogICAgdGFibGUtPmVudHJpZXMgPSAwOwp9CgpzdGF0aWMgRmNCb29sCkZjTGlzdEFwcGVuZCAoRmNMaXN0SGFzaFRhYmxlCSp0YWJsZSwKCSAgICAgIEZjUGF0dGVybgkJKmZvbnQsCgkgICAgICBGY09iamVjdFNldAkqb3MpCnsKICAgIGludAkJICAgIG87CiAgICBGY1BhdHRlcm5FbHQgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnY7CiAgICBGY0NoYXIzMgkgICAgaGFzaDsKICAgIEZjTGlzdEJ1Y2tldCAgICAqKnByZXYsICpidWNrZXQ7CgogICAgaGFzaCA9IEZjTGlzdFBhdHRlcm5IYXNoIChmb250LCBvcyk7CiAgICBmb3IgKHByZXYgPSAmdGFibGUtPmJ1Y2tldHNbaGFzaCAlIEZDX0xJU1RfSEFTSF9TSVpFXTsKCSAoYnVja2V0ID0gKnByZXYpOyBwcmV2ID0gJihidWNrZXQtPm5leHQpKQogICAgewoJaWYgKGJ1Y2tldC0+aGFzaCA9PSBoYXNoICYmIAoJICAgIEZjTGlzdFBhdHRlcm5FcXVhbCAoYnVja2V0LT5wYXR0ZXJuLCBmb250LCBvcykpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGJ1Y2tldCA9IChGY0xpc3RCdWNrZXQgKikgbWFsbG9jIChzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgaWYgKCFidWNrZXQpCglnb3RvIGJhaWwwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0xJU1RCVUNLLCBzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgYnVja2V0LT5uZXh0ID0gMDsKICAgIGJ1Y2tldC0+aGFzaCA9IGhhc2g7CiAgICBidWNrZXQtPnBhdHRlcm4gPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIWJ1Y2tldC0+cGF0dGVybikKCWdvdG8gYmFpbDE7CiAgICAKICAgIGZvciAobyA9IDA7IG8gPCBvcy0+bm9iamVjdDsgbysrKQogICAgewoJZSA9IEZjUGF0dGVybkZpbmRFbHQgKGZvbnQsIG9zLT5vYmplY3RzW29dKTsKCWlmIChlKQoJewoJICAgIGZvciAodiA9IGUtPnZhbHVlczsgdjsgdiA9IHYtPm5leHQpCgkgICAgewoJCWlmICghRmNQYXR0ZXJuQWRkIChidWNrZXQtPnBhdHRlcm4sIAoJCQkJICAgb3MtPm9iamVjdHNbb10sIAoJCQkJICAgdi0+dmFsdWUsIEZjVHJ1ZSkpCgkJICAgIGdvdG8gYmFpbDI7CgkgICAgfQoJfQogICAgfQogICAgKnByZXYgPSBidWNrZXQ7CiAgICArK3RhYmxlLT5lbnRyaWVzOwoKICAgIHJldHVybiBGY1RydWU7CiAgICAKYmFpbDI6CiAgICBGY1BhdHRlcm5EZXN0cm95IChidWNrZXQtPnBhdHRlcm4pOwpiYWlsMToKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0xJU1RCVUNLLCBzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgZnJlZSAoYnVja2V0KTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNGb250U2V0ICoKRmNGb250U2V0TGlzdCAoRmNDb25maWcJICAgICpjb25maWcsCgkgICAgICAgRmNGb250U2V0ICAgICoqc2V0cywKCSAgICAgICBpbnQJICAgIG5zZXRzLAoJICAgICAgIEZjUGF0dGVybiAgICAqcCwKCSAgICAgICBGY09iamVjdFNldCAgKm9zKQp7CiAgICBGY0ZvbnRTZXQJICAgICpyZXQ7CiAgICBGY0ZvbnRTZXQJICAgICpzOwogICAgaW50CQkgICAgZjsKICAgIGludAkJICAgIHNldDsKICAgIEZjTGlzdEhhc2hUYWJsZSB0YWJsZTsKICAgIGludAkJICAgIGk7CiAgICBGY0xpc3RCdWNrZXQgICAgKmJ1Y2tldDsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWlmICghRmNJbml0QnJpbmdVcHRvRGF0ZSAoKSkKCSAgICBnb3RvIGJhaWwwOwoKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBGY0xpc3RIYXNoVGFibGVJbml0ICgmdGFibGUpOwogICAgLyoKICAgICAqIFdhbGsgYWxsIGF2YWlsYWJsZSBmb250cyBhZGRpbmcgdGhvc2UgdGhhdAogICAgICogbWF0Y2ggdG8gdGhlIGhhc2ggdGFibGUKICAgICAqLwogICAgZm9yIChzZXQgPSAwOyBzZXQgPCBuc2V0czsgc2V0KyspCiAgICB7CglzID0gc2V0c1tzZXRdOwoJaWYgKCFzKQoJICAgIGNvbnRpbnVlOwoJZm9yIChmID0gMDsgZiA8IHMtPm5mb250OyBmKyspCgkgICAgaWYgKEZjTGlzdFBhdHRlcm5NYXRjaEFueSAocCwJCS8qIHBhdHRlcm4gKi8KCQkJCSAgICAgICBzLT5mb250c1tmXSkpCS8qIGZvbnQgKi8KCQlpZiAoIUZjTGlzdEFwcGVuZCAoJnRhYmxlLCBzLT5mb250c1tmXSwgb3MpKQoJCSAgICBnb3RvIGJhaWwxOwogICAgfQojaWYgMAogICAgewoJaW50CW1heCA9IDA7CglpbnQJZnVsbCA9IDA7CglpbnQJZW50cyA9IDA7CglpbnQJbGVuOwoJZm9yIChpID0gMDsgaSA8IEZDX0xJU1RfSEFTSF9TSVpFOyBpKyspCgl7CgkgICAgaWYgKChidWNrZXQgPSB0YWJsZS5idWNrZXRzW2ldKSkKCSAgICB7CgkJbGVuID0gMDsKCQlmb3IgKDsgYnVja2V0OyBidWNrZXQgPSBidWNrZXQtPm5leHQpCgkJewoJCSAgICBlbnRzKys7CgkJICAgIGxlbisrOwoJCX0KCQlpZiAobGVuID4gbWF4KQoJCSAgICBtYXggPSBsZW47CgkJZnVsbCsrOwoJICAgIH0KCX0KCXByaW50ZiAoInVzZWQ6ICVkIG1heDogJWQgYXZnOiAlZ1xuIiwgZnVsbCwgbWF4LCAKCQkoZG91YmxlKSBlbnRzIC8gRkNfTElTVF9IQVNIX1NJWkUpOwogICAgfQojZW5kaWYKICAgIC8qCiAgICAgKiBXYWxrIHRoZSBoYXNoIHRhYmxlIGFuZCBidWlsZAogICAgICogYSBmb250IHNldAogICAgICovCiAgICByZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CiAgICBpZiAoIXJldCkKCWdvdG8gYmFpbDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgRkNfTElTVF9IQVNIX1NJWkU7IGkrKykKCXdoaWxlICgoYnVja2V0ID0gdGFibGUuYnVja2V0c1tpXSkpCgl7CgkgICAgaWYgKCFGY0ZvbnRTZXRBZGQgKHJldCwgYnVja2V0LT5wYXR0ZXJuKSkKCQlnb3RvIGJhaWwyOwoJICAgIHRhYmxlLmJ1Y2tldHNbaV0gPSBidWNrZXQtPm5leHQ7CgkgICAgRmNNZW1GcmVlIChGQ19NRU1fTElTVEJVQ0ssIHNpemVvZiAoRmNMaXN0QnVja2V0KSk7CgkgICAgZnJlZSAoYnVja2V0KTsKCX0KICAgIAogICAgcmV0dXJuIHJldDsKCmJhaWwyOgogICAgRmNGb250U2V0RGVzdHJveSAocmV0KTsKYmFpbDE6CiAgICBGY0xpc3RIYXNoVGFibGVDbGVhbnVwICgmdGFibGUpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpGY0ZvbnRTZXQgKgpGY0ZvbnRMaXN0IChGY0NvbmZpZwkqY29uZmlnLAoJICAgIEZjUGF0dGVybgkqcCwKCSAgICBGY09iamVjdFNldCAqb3MpCnsKICAgIEZjRm9udFNldAkqc2V0c1syXTsKICAgIGludAkJbnNldHM7CgogICAgaWYgKCFjb25maWcpCiAgICB7Cgljb25maWcgPSBGY0NvbmZpZ0dldEN1cnJlbnQgKCk7CglpZiAoIWNvbmZpZykKCSAgICByZXR1cm4gMDsKICAgIH0KICAgIG5zZXRzID0gMDsKICAgIGlmIChjb25maWctPmZvbnRzW0ZjU2V0U3lzdGVtXSkKCXNldHNbbnNldHMrK10gPSBjb25maWctPmZvbnRzW0ZjU2V0U3lzdGVtXTsKICAgIGlmIChjb25maWctPmZvbnRzW0ZjU2V0QXBwbGljYXRpb25dKQoJc2V0c1tuc2V0cysrXSA9IGNvbmZpZy0+Zm9udHNbRmNTZXRBcHBsaWNhdGlvbl07CiAgICByZXR1cm4gRmNGb250U2V0TGlzdCAoY29uZmlnLCBzZXRzLCBuc2V0cywgcCwgb3MpOwp9Cg==