LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNsaXN0LmMsdiAxLjExdHNpIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZAogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjT2JqZWN0U2V0ICoKRmNPYmplY3RTZXRDcmVhdGUgKHZvaWQpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICBvcyA9IChGY09iamVjdFNldCAqKSBtYWxsb2MgKHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIGlmICghb3MpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RTRVQsIHNpemVvZiAoRmNPYmplY3RTZXQpKTsKICAgIG9zLT5ub2JqZWN0ID0gMDsKICAgIG9zLT5zb2JqZWN0ID0gMDsKICAgIG9zLT5vYmplY3RzID0gMDsKICAgIHJldHVybiBvczsKfQoKRmNCb29sCkZjT2JqZWN0U2V0QWRkIChGY09iamVjdFNldCAqb3MsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQlzOwogICAgY29uc3QgY2hhcgkqKm9iamVjdHM7CiAgICBpbnQJCWhpZ2gsIGxvdywgbWlkLCBjOwogICAgCiAgICBpZiAob3MtPm5vYmplY3QgPT0gb3MtPnNvYmplY3QpCiAgICB7CglzID0gb3MtPnNvYmplY3QgKyA0OwoJaWYgKG9zLT5vYmplY3RzKQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgcmVhbGxvYyAoKHZvaWQgKikgb3MtPm9iamVjdHMsCgkJCQkJICAgICAgIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJZWxzZQoJICAgIG9iamVjdHMgPSAoY29uc3QgY2hhciAqKikgbWFsbG9jIChzICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWlmICghb2JqZWN0cykKCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmIChvcy0+c29iamVjdCkKCSAgICBGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCUZjTWVtQWxsb2MgKEZDX01FTV9PQkpFQ1RQVFIsIHMgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwoJb3MtPm9iamVjdHMgPSBvYmplY3RzOwoJb3MtPnNvYmplY3QgPSBzOwogICAgfQogICAgaGlnaCA9IG9zLT5ub2JqZWN0IC0gMTsKICAgIGxvdyA9IDA7CiAgICBtaWQgPSAwOwogICAgYyA9IDE7CiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAobG93ICsgaGlnaCkgPj4gMTsKCWMgPSBzdHJjbXAgKG9zLT5vYmplY3RzW21pZF0sIG9iamVjdCk7CglpZiAoYyA9PSAwKQoJICAgIHJldHVybiBGY1RydWU7CglpZiAoYyA8IDApCgkgICAgbG93ID0gbWlkICsgMTsKCWVsc2UKCSAgICBoaWdoID0gbWlkIC0gMTsKICAgIH0KICAgIGlmIChjIDwgMCkKCW1pZCsrOwogICAgbWVtbW92ZSAob3MtPm9iamVjdHMgKyBtaWQgKyAxLCBvcy0+b2JqZWN0cyArIG1pZCwgCgkgICAgIChvcy0+bm9iamVjdCAtIG1pZCkgKiBzaXplb2YgKGNvbnN0IGNoYXIgKikpOwogICAgb3MtPm9iamVjdHNbbWlkXSA9IG9iamVjdDsKICAgIG9zLT5ub2JqZWN0Kys7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjT2JqZWN0U2V0RGVzdHJveSAoRmNPYmplY3RTZXQgKm9zKQp7CiAgICBpZiAob3MtPm9iamVjdHMpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9PQkpFQ1RQVFIsIG9zLT5zb2JqZWN0ICogc2l6ZW9mIChjb25zdCBjaGFyICopKTsKCWZyZWUgKCh2b2lkICopIG9zLT5vYmplY3RzKTsKICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX09CSkVDVFNFVCwgc2l6ZW9mIChGY09iamVjdFNldCkpOwogICAgZnJlZSAob3MpOwp9CgpGY09iamVjdFNldCAqCkZjT2JqZWN0U2V0VmFCdWlsZCAoY29uc3QgY2hhciAqZmlyc3QsIHZhX2xpc3QgdmEpCnsKICAgIEZjT2JqZWN0U2V0ICAgICpyZXQ7CgogICAgRmNPYmplY3RTZXRWYXBCdWlsZCAocmV0LCBmaXJzdCwgdmEpOwogICAgcmV0dXJuIHJldDsKfQoKRmNPYmplY3RTZXQgKgpGY09iamVjdFNldEJ1aWxkIChjb25zdCBjaGFyICpmaXJzdCwgLi4uKQp7CiAgICB2YV9saXN0CSAgICB2YTsKICAgIEZjT2JqZWN0U2V0ICAgICpvczsKCiAgICB2YV9zdGFydCAodmEsIGZpcnN0KTsKICAgIEZjT2JqZWN0U2V0VmFwQnVpbGQgKG9zLCBmaXJzdCwgdmEpOwogICAgdmFfZW5kICh2YSk7CiAgICByZXR1cm4gb3M7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNMaXN0VmFsdWVMaXN0TWF0Y2hBbnkgKEZjVmFsdWVMaXN0ICp2MW9yaWcsCgkJCSBGY1ZhbHVlTGlzdCAqdjJvcmlnKQp7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnYxLCAqdjI7CgogICAgZm9yICh2MSA9IHYxb3JpZzsgdjE7IHYxID0gdjEtPm5leHQpCglmb3IgKHYyID0gdjJvcmlnOyB2MjsgdjIgPSB2Mi0+bmV4dCkKCSAgICBpZiAoRmNDb25maWdDb21wYXJlVmFsdWUgKHYxLT52YWx1ZSwgRmNPcENvbnRhaW5zLCB2Mi0+dmFsdWUpKQoJCXJldHVybiBGY1RydWU7CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKc3RhdGljIEZjQm9vbApGY0xpc3RWYWx1ZUxpc3RFcXVhbCAoRmNWYWx1ZUxpc3QgICAqdjFvcmlnLAoJCSAgICAgIEZjVmFsdWVMaXN0ICAgKnYyb3JpZykKewogICAgRmNWYWx1ZUxpc3QJICAgICp2MSwgKnYyOwoKICAgIGZvciAodjEgPSB2MW9yaWc7IHYxOyB2MSA9IHYxLT5uZXh0KQogICAgewoJZm9yICh2MiA9IHYyb3JpZzsgdjI7IHYyID0gdjItPm5leHQpCgkgICAgaWYgKEZjVmFsdWVFcXVhbCAodjEtPnZhbHVlLCB2Mi0+dmFsdWUpKQoJCWJyZWFrOwoJaWYgKCF2MikKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGZvciAodjIgPSB2Mm9yaWc7IHYyOyB2MiA9IHYyLT5uZXh0KQogICAgewoJZm9yICh2MSA9IHYxb3JpZzsgdjE7IHYxID0gdjEtPm5leHQpCgkgICAgaWYgKEZjVmFsdWVFcXVhbCAodjEtPnZhbHVlLCB2Mi0+dmFsdWUpKQoJCWJyZWFrOwoJaWYgKCF2MSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNMaXN0UGF0dGVybkVxdWFsIChGY1BhdHRlcm4JKnAxLAoJCSAgICBGY1BhdHRlcm4JKnAyLAoJCSAgICBGY09iamVjdFNldAkqb3MpCnsKICAgIGludAkJICAgIGk7CiAgICBGY1BhdHRlcm5FbHQgICAgKmUxLCAqZTI7CgogICAgZm9yIChpID0gMDsgaSA8IG9zLT5ub2JqZWN0OyBpKyspCiAgICB7CgllMSA9IEZjUGF0dGVybkZpbmRFbHQgKHAxLCBvcy0+b2JqZWN0c1tpXSk7CgllMiA9IEZjUGF0dGVybkZpbmRFbHQgKHAyLCBvcy0+b2JqZWN0c1tpXSk7CglpZiAoIWUxICYmICFlMikKCSAgICBjb250aW51ZTsKCWlmICghZTEgfHwgIWUyKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY0xpc3RWYWx1ZUxpc3RFcXVhbCAoZTEtPnZhbHVlcywgZTItPnZhbHVlcykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgovKgogKiBGY1RydWUgaWZmIGFsbCBvYmplY3RzIGluICJwIiBtYXRjaCAiZm9udCIKICovCgpzdGF0aWMgRmNCb29sCkZjTGlzdFBhdHRlcm5NYXRjaEFueSAoRmNQYXR0ZXJuICpwLAoJCSAgICAgICBGY1BhdHRlcm4gKmZvbnQpCnsKICAgIGludAkJICAgIGk7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCiAgICB7CgllID0gRmNQYXR0ZXJuRmluZEVsdCAoZm9udCwgcC0+ZWx0c1tpXS5vYmplY3QpOwoJaWYgKCFlKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY0xpc3RWYWx1ZUxpc3RNYXRjaEFueSAocC0+ZWx0c1tpXS52YWx1ZXMsIGUtPnZhbHVlcykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0U3RyaW5nSGFzaCAoY29uc3QgRmNDaGFyOAkqcykKewogICAgRmNDaGFyMzIJaCA9IDA7CiAgICBGY0NoYXI4CWM7CgogICAgd2hpbGUgKChjID0gKnMrKykpCiAgICB7CgljID0gRmNUb0xvd2VyIChjKTsKCWggPSAoKGggPDwgMykgXiAoaCA+PiAzKSkgXiBjOwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RNYXRyaXhIYXNoIChjb25zdCBGY01hdHJpeCAqbSkKewogICAgaW50CSAgICB4eCA9IChpbnQpIChtLT54eCAqIDEwMCksIAoJICAgIHh5ID0gKGludCkgKG0tPnh5ICogMTAwKSwgCgkgICAgeXggPSAoaW50KSAobS0+eXggKiAxMDApLAoJICAgIHl5ID0gKGludCkgKG0tPnl5ICogMTAwKTsKCiAgICByZXR1cm4gKChGY0NoYXIzMikgeHgpIF4gKChGY0NoYXIzMikgeHkpIF4gKChGY0NoYXIzMikgeXgpIF4gKChGY0NoYXIzMikgeXkpOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNMaXN0VmFsdWVIYXNoIChGY1ZhbHVlICAgIHYpCnsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVZvaWQ6CglyZXR1cm4gMDsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5pOwogICAgY2FzZSBGY1R5cGVEb3VibGU6CglyZXR1cm4gKEZjQ2hhcjMyKSAoaW50KSB2LnUuZDsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjTGlzdFN0cmluZ0hhc2ggKHYudS5zKTsKICAgIGNhc2UgRmNUeXBlQm9vbDoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5iOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglyZXR1cm4gRmNMaXN0TWF0cml4SGFzaCAodi51Lm0pOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJcmV0dXJuIEZjQ2hhclNldENvdW50ICh2LnUuYyk7CiAgICBjYXNlIEZjVHlwZUZURmFjZToKCXJldHVybiAobG9uZykgdi51LmY7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6CglyZXR1cm4gRmNMYW5nU2V0SGFzaCAodi51LmwpOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RWYWx1ZUxpc3RIYXNoIChGY1ZhbHVlTGlzdCAgICAqbGlzdCkKewogICAgRmNDaGFyMzIJaCA9IDA7CiAgICAKICAgIHdoaWxlIChsaXN0KQogICAgewoJaCA9IGggXiBGY0xpc3RWYWx1ZUhhc2ggKGxpc3QtPnZhbHVlKTsKCWxpc3QgPSBsaXN0LT5uZXh0OwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0xpc3RQYXR0ZXJuSGFzaCAoRmNQYXR0ZXJuCSpmb250LAoJCSAgIEZjT2JqZWN0U2V0CSpvcykKewogICAgaW50CQkgICAgbjsKICAgIEZjUGF0dGVybkVsdCAgICAqZTsKICAgIEZjQ2hhcjMyCSAgICBoID0gMDsKCiAgICBmb3IgKG4gPSAwOyBuIDwgb3MtPm5vYmplY3Q7IG4rKykKICAgIHsKCWUgPSBGY1BhdHRlcm5GaW5kRWx0IChmb250LCBvcy0+b2JqZWN0c1tuXSk7CglpZiAoZSkKCSAgICBoID0gaCBeIEZjTGlzdFZhbHVlTGlzdEhhc2ggKGUtPnZhbHVlcyk7CiAgICB9CiAgICByZXR1cm4gaDsKfQoKdHlwZWRlZiBzdHJ1Y3QgX0ZjTGlzdEJ1Y2tldCB7CiAgICBzdHJ1Y3QgX0ZjTGlzdEJ1Y2tldCAgICAqbmV4dDsKICAgIEZjQ2hhcjMyCQkgICAgaGFzaDsKICAgIEZjUGF0dGVybgkJICAgICpwYXR0ZXJuOwp9IEZjTGlzdEJ1Y2tldDsKCiNkZWZpbmUgRkNfTElTVF9IQVNIX1NJWkUgICA0MDk5Cgp0eXBlZGVmIHN0cnVjdCBfRmNMaXN0SGFzaFRhYmxlIHsKICAgIGludAkJICAgIGVudHJpZXM7CiAgICBGY0xpc3RCdWNrZXQgICAgKmJ1Y2tldHNbRkNfTElTVF9IQVNIX1NJWkVdOwp9IEZjTGlzdEhhc2hUYWJsZTsKICAgIApzdGF0aWMgdm9pZApGY0xpc3RIYXNoVGFibGVJbml0IChGY0xpc3RIYXNoVGFibGUgKnRhYmxlKQp7CiAgICB0YWJsZS0+ZW50cmllcyA9IDA7CiAgICBtZW1zZXQgKHRhYmxlLT5idWNrZXRzLCAnXDAnLCBzaXplb2YgKHRhYmxlLT5idWNrZXRzKSk7Cn0KCnN0YXRpYyB2b2lkCkZjTGlzdEhhc2hUYWJsZUNsZWFudXAgKEZjTGlzdEhhc2hUYWJsZSAqdGFibGUpCnsKICAgIGludAlpOwogICAgRmNMaXN0QnVja2V0ICAgICpidWNrZXQsICpuZXh0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBGQ19MSVNUX0hBU0hfU0laRTsgaSsrKQogICAgewoJZm9yIChidWNrZXQgPSB0YWJsZS0+YnVja2V0c1tpXTsgYnVja2V0OyBidWNrZXQgPSBuZXh0KQoJewoJICAgIG5leHQgPSBidWNrZXQtPm5leHQ7CgkgICAgRmNQYXR0ZXJuRGVzdHJveSAoYnVja2V0LT5wYXR0ZXJuKTsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9MSVNUQlVDSywgc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKCSAgICBmcmVlIChidWNrZXQpOwoJfQoJdGFibGUtPmJ1Y2tldHNbaV0gPSAwOwogICAgfQogICAgdGFibGUtPmVudHJpZXMgPSAwOwp9CgpzdGF0aWMgRmNCb29sCkZjTGlzdEFwcGVuZCAoRmNMaXN0SGFzaFRhYmxlCSp0YWJsZSwKCSAgICAgIEZjUGF0dGVybgkJKmZvbnQsCgkgICAgICBGY09iamVjdFNldAkqb3MpCnsKICAgIGludAkJICAgIG87CiAgICBGY1BhdHRlcm5FbHQgICAgKmU7CiAgICBGY1ZhbHVlTGlzdAkgICAgKnY7CiAgICBGY0NoYXIzMgkgICAgaGFzaDsKICAgIEZjTGlzdEJ1Y2tldCAgICAqKnByZXYsICpidWNrZXQ7CgogICAgaGFzaCA9IEZjTGlzdFBhdHRlcm5IYXNoIChmb250LCBvcyk7CiAgICBmb3IgKHByZXYgPSAmdGFibGUtPmJ1Y2tldHNbaGFzaCAlIEZDX0xJU1RfSEFTSF9TSVpFXTsKCSAoYnVja2V0ID0gKnByZXYpOyBwcmV2ID0gJihidWNrZXQtPm5leHQpKQogICAgewoJaWYgKGJ1Y2tldC0+aGFzaCA9PSBoYXNoICYmIAoJICAgIEZjTGlzdFBhdHRlcm5FcXVhbCAoYnVja2V0LT5wYXR0ZXJuLCBmb250LCBvcykpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIGJ1Y2tldCA9IChGY0xpc3RCdWNrZXQgKikgbWFsbG9jIChzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgaWYgKCFidWNrZXQpCglnb3RvIGJhaWwwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0xJU1RCVUNLLCBzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgYnVja2V0LT5uZXh0ID0gMDsKICAgIGJ1Y2tldC0+aGFzaCA9IGhhc2g7CiAgICBidWNrZXQtPnBhdHRlcm4gPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIWJ1Y2tldC0+cGF0dGVybikKCWdvdG8gYmFpbDE7CiAgICAKICAgIGZvciAobyA9IDA7IG8gPCBvcy0+bm9iamVjdDsgbysrKQogICAgewoJZSA9IEZjUGF0dGVybkZpbmRFbHQgKGZvbnQsIG9zLT5vYmplY3RzW29dKTsKCWlmIChlKQoJewoJICAgIGZvciAodiA9IGUtPnZhbHVlczsgdjsgdiA9IHYtPm5leHQpCgkgICAgewoJCWlmICghRmNQYXR0ZXJuQWRkIChidWNrZXQtPnBhdHRlcm4sIAoJCQkJICAgb3MtPm9iamVjdHNbb10sIAoJCQkJICAgdi0+dmFsdWUsIEZjVHJ1ZSkpCgkJICAgIGdvdG8gYmFpbDI7CgkgICAgfQoJfQogICAgfQogICAgKnByZXYgPSBidWNrZXQ7CiAgICArK3RhYmxlLT5lbnRyaWVzOwoKICAgIHJldHVybiBGY1RydWU7CiAgICAKYmFpbDI6CiAgICBGY1BhdHRlcm5EZXN0cm95IChidWNrZXQtPnBhdHRlcm4pOwpiYWlsMToKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0xJU1RCVUNLLCBzaXplb2YgKEZjTGlzdEJ1Y2tldCkpOwogICAgZnJlZSAoYnVja2V0KTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNGb250U2V0ICoKRmNGb250U2V0TGlzdCAoRmNDb25maWcJICAgICpjb25maWcsCgkgICAgICAgRmNGb250U2V0ICAgICoqc2V0cywKCSAgICAgICBpbnQJICAgIG5zZXRzLAoJICAgICAgIEZjUGF0dGVybiAgICAqcCwKCSAgICAgICBGY09iamVjdFNldCAgKm9zKQp7CiAgICBGY0ZvbnRTZXQJICAgICpyZXQ7CiAgICBGY0ZvbnRTZXQJICAgICpzOwogICAgaW50CQkgICAgZjsKICAgIGludAkJICAgIHNldDsKICAgIEZjTGlzdEhhc2hUYWJsZSB0YWJsZTsKICAgIGludAkJICAgIGk7CiAgICBGY0xpc3RCdWNrZXQgICAgKmJ1Y2tldDsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWlmICghRmNJbml0QnJpbmdVcHRvRGF0ZSAoKSkKCSAgICBnb3RvIGJhaWwwOwoKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIGdvdG8gYmFpbDA7CiAgICB9CiAgICBGY0xpc3RIYXNoVGFibGVJbml0ICgmdGFibGUpOwogICAgLyoKICAgICAqIFdhbGsgYWxsIGF2YWlsYWJsZSBmb250cyBhZGRpbmcgdGhvc2UgdGhhdAogICAgICogbWF0Y2ggdG8gdGhlIGhhc2ggdGFibGUKICAgICAqLwogICAgZm9yIChzZXQgPSAwOyBzZXQgPCBuc2V0czsgc2V0KyspCiAgICB7CglzID0gc2V0c1tzZXRdOwoJaWYgKCFzKQoJICAgIGNvbnRpbnVlOwoJZm9yIChmID0gMDsgZiA8IHMtPm5mb250OyBmKyspCgkgICAgaWYgKEZjTGlzdFBhdHRlcm5NYXRjaEFueSAocCwgcy0+Zm9udHNbZl0pKQoJCWlmICghRmNMaXN0QXBwZW5kICgmdGFibGUsIHMtPmZvbnRzW2ZdLCBvcykpCgkJICAgIGdvdG8gYmFpbDE7CiAgICB9CiNpZiAwCiAgICB7CglpbnQJbWF4ID0gMDsKCWludAlmdWxsID0gMDsKCWludAllbnRzID0gMDsKCWludAlsZW47Cglmb3IgKGkgPSAwOyBpIDwgRkNfTElTVF9IQVNIX1NJWkU7IGkrKykKCXsKCSAgICBpZiAoKGJ1Y2tldCA9IHRhYmxlLmJ1Y2tldHNbaV0pKQoJICAgIHsKCQlsZW4gPSAwOwoJCWZvciAoOyBidWNrZXQ7IGJ1Y2tldCA9IGJ1Y2tldC0+bmV4dCkKCQl7CgkJICAgIGVudHMrKzsKCQkgICAgbGVuKys7CgkJfQoJCWlmIChsZW4gPiBtYXgpCgkJICAgIG1heCA9IGxlbjsKCQlmdWxsKys7CgkgICAgfQoJfQoJcHJpbnRmICgidXNlZDogJWQgbWF4OiAlZCBhdmc6ICVnXG4iLCBmdWxsLCBtYXgsIAoJCShkb3VibGUpIGVudHMgLyBGQ19MSVNUX0hBU0hfU0laRSk7CiAgICB9CiNlbmRpZgogICAgLyoKICAgICAqIFdhbGsgdGhlIGhhc2ggdGFibGUgYW5kIGJ1aWxkCiAgICAgKiBhIGZvbnQgc2V0CiAgICAgKi8KICAgIHJldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKICAgIGlmICghcmV0KQoJZ290byBiYWlsMDsKICAgIGZvciAoaSA9IDA7IGkgPCBGQ19MSVNUX0hBU0hfU0laRTsgaSsrKQoJd2hpbGUgKChidWNrZXQgPSB0YWJsZS5idWNrZXRzW2ldKSkKCXsKCSAgICBpZiAoIUZjRm9udFNldEFkZCAocmV0LCBidWNrZXQtPnBhdHRlcm4pKQoJCWdvdG8gYmFpbDI7CgkgICAgdGFibGUuYnVja2V0c1tpXSA9IGJ1Y2tldC0+bmV4dDsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9MSVNUQlVDSywgc2l6ZW9mIChGY0xpc3RCdWNrZXQpKTsKCSAgICBmcmVlIChidWNrZXQpOwoJfQogICAgCiAgICByZXR1cm4gcmV0OwoKYmFpbDI6CiAgICBGY0ZvbnRTZXREZXN0cm95IChyZXQpOwpiYWlsMToKICAgIEZjTGlzdEhhc2hUYWJsZUNsZWFudXAgKCZ0YWJsZSk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCkZjRm9udFNldCAqCkZjRm9udExpc3QgKEZjQ29uZmlnCSpjb25maWcsCgkgICAgRmNQYXR0ZXJuCSpwLAoJICAgIEZjT2JqZWN0U2V0ICpvcykKewogICAgRmNGb250U2V0CSpzZXRzWzJdOwogICAgaW50CQluc2V0czsKCiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWNvbmZpZyA9IEZjQ29uZmlnR2V0Q3VycmVudCAoKTsKCWlmICghY29uZmlnKQoJICAgIHJldHVybiAwOwogICAgfQogICAgbnNldHMgPSAwOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dKQoJc2V0c1tuc2V0cysrXSA9IGNvbmZpZy0+Zm9udHNbRmNTZXRTeXN0ZW1dOwogICAgaWYgKGNvbmZpZy0+Zm9udHNbRmNTZXRBcHBsaWNhdGlvbl0pCglzZXRzW25zZXRzKytdID0gY29uZmlnLT5mb250c1tGY1NldEFwcGxpY2F0aW9uXTsKICAgIHJldHVybiBGY0ZvbnRTZXRMaXN0IChjb25maWcsIHNldHMsIG5zZXRzLCBwLCBvcyk7Cn0K