LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NhY2hlLmMsdiAxLjIgMjAwMi8wMi8xNSAwNjowMToyNyBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgImZjaW50LmgiCgpzdGF0aWMgdW5zaWduZWQgaW50CkZjRmlsZUNhY2hlSGFzaCAoY29uc3QgRmNDaGFyOAkqc3RyaW5nKQp7CiAgICB1bnNpZ25lZCBpbnQgICAgaCA9IDA7CiAgICBGY0NoYXI4CSAgICBjOwoKICAgIHdoaWxlICgoYyA9ICpzdHJpbmcrKykpCgloID0gKGggPDwgMSkgXiBjOwogICAgcmV0dXJuIGg7Cn0KCkZjQ2hhcjggKgpGY0ZpbGVDYWNoZUZpbmQgKEZjRmlsZUNhY2hlCSpjYWNoZSwKCQkgY29uc3QgRmNDaGFyOAkqZmlsZSwKCQkgaW50CQlpZCwKCQkgaW50CQkqY291bnQpCnsKICAgIHVuc2lnbmVkIGludCAgICBoYXNoOwogICAgY29uc3QgRmNDaGFyOCAgICptYXRjaDsKICAgIEZjRmlsZUNhY2hlRW50ICAqYywgKm5hbWU7CiAgICBpbnQJCSAgICBtYXhpZDsKICAgIHN0cnVjdCBzdGF0CSAgICBzdGF0YjsKICAgIAogICAgbWF0Y2ggPSBmaWxlOwogICAgCiAgICBoYXNoID0gRmNGaWxlQ2FjaGVIYXNoIChtYXRjaCk7CiAgICBuYW1lID0gMDsKICAgIG1heGlkID0gLTE7CiAgICBmb3IgKGMgPSBjYWNoZS0+ZW50c1toYXNoICUgRkNfRklMRV9DQUNIRV9IQVNIX1NJWkVdOyBjOyBjID0gYy0+bmV4dCkKICAgIHsKCWlmIChjLT5oYXNoID09IGhhc2ggJiYgIXN0cmNtcCAobWF0Y2gsIGMtPmZpbGUpKQoJewoJICAgIGlmIChjLT5pZCA+IG1heGlkKQoJCW1heGlkID0gYy0+aWQ7CgkgICAgaWYgKGMtPmlkID09IGlkKQoJICAgIHsKCQlpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCgkJewoJCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCQkJcHJpbnRmICgiIGZpbGUgbWlzc2luZ1xuIik7CgkJICAgIHJldHVybiAwOwoJCX0KCQlpZiAoc3RhdGIuc3RfbXRpbWUgIT0gYy0+dGltZSkKCQl7CgkJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJCQlwcmludGYgKCIgdGltZXN0YW1wIG1pc21hdGNoICh3YXMgJWQgaXMgJWQpXG4iLAoJCQkJKGludCkgYy0+dGltZSwgKGludCkgc3RhdGIuc3RfbXRpbWUpOwoJCSAgICByZXR1cm4gMDsKCQl9CgkJaWYgKCFjLT5yZWZlcmVuY2VkKQoJCXsKCQkgICAgY2FjaGUtPnJlZmVyZW5jZWQrKzsKCQkgICAgYy0+cmVmZXJlbmNlZCA9IEZjVHJ1ZTsKCQl9CgkJbmFtZSA9IGM7CgkgICAgfQoJfQogICAgfQogICAgaWYgKCFuYW1lKQoJcmV0dXJuIDA7CiAgICAqY291bnQgPSBtYXhpZCArIDE7CiAgICByZXR1cm4gbmFtZS0+bmFtZTsKfQoKLyoKICogQ2FjaGUgZmlsZSBzeW50YXggaXMgcXVpdGUgc2ltcGxlOgogKgogKiAiZmlsZV9uYW1lIiBpZCB0aW1lICJmb250X25hbWUiIFxuCiAqLwogCnN0YXRpYyBGY0NoYXI4ICoKRmNGaWxlQ2FjaGVSZWFkU3RyaW5nIChGSUxFICpmLCBGY0NoYXI4ICpkZXN0LCBpbnQgbGVuKQp7CiAgICBpbnQJCWM7CiAgICBGY0Jvb2wJZXNjYXBlOwogICAgRmNDaGFyOAkqZDsKICAgIGludAkJc2l6ZTsKICAgIGludAkJaTsKCiAgICB3aGlsZSAoKGMgPSBnZXRjIChmKSkgIT0gRU9GKQoJaWYgKGMgPT0gJyInKQoJICAgIGJyZWFrOwogICAgaWYgKGMgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAobGVuID09IDApCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgc2l6ZSA9IGxlbjsKICAgIGkgPSAwOwogICAgZCA9IGRlc3Q7CiAgICBlc2NhcGUgPSBGY0ZhbHNlOwogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpICE9IEVPRikKICAgIHsKCWlmICghZXNjYXBlKQoJewoJICAgIHN3aXRjaCAoYykgewoJICAgIGNhc2UgJyInOgoJCWMgPSAnXDAnOwoJCWJyZWFrOwoJICAgIGNhc2UgJ1xcJzoKCQllc2NhcGUgPSBGY1RydWU7CgkJY29udGludWU7CgkgICAgfQoJfQoJaWYgKGkgPT0gc2l6ZSkKCXsKCSAgICBGY0NoYXI4ICpuZXcgPSBtYWxsb2MgKHNpemUgKiAyKTsKCSAgICBpZiAoIW5ldykKCQlicmVhazsKCSAgICBtZW1jcHkgKG5ldywgZCwgc2l6ZSk7CgkgICAgc2l6ZSAqPSAyOwoJICAgIGlmIChkICE9IGRlc3QpCgkJZnJlZSAoZCk7CgkgICAgZCA9IG5ldzsKCX0KCWRbaSsrXSA9IGM7CglpZiAoYyA9PSAnXDAnKQoJICAgIHJldHVybiBkOwoJZXNjYXBlID0gRmNGYWxzZTsKICAgIH0KICAgIGlmIChkICE9IGRlc3QpCglmcmVlIChkKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgRmNCb29sCkZjRmlsZUNhY2hlUmVhZFVsb25nIChGSUxFICpmLCB1bnNpZ25lZCBsb25nICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIGludAkJICAgIGM7CgogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpICE9IEVPRikKICAgIHsKCWlmICghaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoYyA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIHQgPSAwOwogICAgZm9yICg7OykKICAgIHsKCWlmIChjID09IEVPRiB8fCBpc3NwYWNlIChjKSkKCSAgICBicmVhazsKCWlmICghaXNkaWdpdCAoYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ID0gdCAqIDEwICsgKGMgLSAnMCcpOwoJYyA9IGdldGMgKGYpOwogICAgfQogICAgKmRlc3QgPSB0OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0ZpbGVDYWNoZVJlYWRJbnQgKEZJTEUgKmYsIGludCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0ZpbGVDYWNoZVJlYWRVbG9uZyAoZiwgJnQpOwogICAgaWYgKHJldCkKCSpkZXN0ID0gKGludCkgdDsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNGaWxlQ2FjaGVSZWFkVGltZSAoRklMRSAqZiwgdGltZV90ICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIEZjQm9vbAkgICAgcmV0OwoKICAgIHJldCA9IEZjRmlsZUNhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAodGltZV90KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0ZpbGVDYWNoZUFkZCAoRmNGaWxlQ2FjaGUJKmNhY2hlLAoJCSBjb25zdCBGY0NoYXI4CSpmaWxlLAoJCSBpbnQJCWlkLAoJCSB0aW1lX3QJCXRpbWUsCgkJIGNvbnN0IEZjQ2hhcjgJKm5hbWUsCgkJIEZjQm9vbAkJcmVwbGFjZSkKewogICAgRmNGaWxlQ2FjaGVFbnQgICAgKmM7CiAgICBGY0ZpbGVDYWNoZUVudCAgICAqKnByZXYsICpvbGQ7CiAgICB1bnNpZ25lZCBpbnQgICAgaGFzaDsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKICAgIHsKCXByaW50ZiAoIiVzIGZhY2UgJXMvJWQgYXMgJXNcbiIsIHJlcGxhY2UgPyAiUmVwbGFjZSIgOiAiQWRkIiwKCQlmaWxlLCBpZCwgbmFtZSk7CiAgICB9CiAgICBoYXNoID0gRmNGaWxlQ2FjaGVIYXNoIChmaWxlKTsKICAgIGZvciAocHJldiA9ICZjYWNoZS0+ZW50c1toYXNoICUgRkNfRklMRV9DQUNIRV9IQVNIX1NJWkVdOyAKCSAob2xkID0gKnByZXYpOwoJIHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmIChvbGQtPmhhc2ggPT0gaGFzaCAmJiBvbGQtPmlkID09IGlkICYmICFzdHJjbXAgKG9sZC0+ZmlsZSwgZmlsZSkpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoKnByZXYpCiAgICB7CglpZiAoIXJlcGxhY2UpCgkgICAgcmV0dXJuIEZjRmFsc2U7CgoJb2xkID0gKnByZXY7CglpZiAob2xkLT5yZWZlcmVuY2VkKQoJICAgIGNhY2hlLT5yZWZlcmVuY2VkLS07CgkqcHJldiA9IG9sZC0+bmV4dDsKCWZyZWUgKG9sZCk7CgljYWNoZS0+ZW50cmllcy0tOwogICAgfQoJCiAgICBjID0gbWFsbG9jIChzaXplb2YgKEZjRmlsZUNhY2hlRW50KSArCgkJc3RybGVuICgoY2hhciAqKSBmaWxlKSArIDEgKwoJCXN0cmxlbiAoKGNoYXIgKikgbmFtZSkgKyAxKTsKICAgIGlmICghYykKCXJldHVybiBGY0ZhbHNlOwogICAgYy0+bmV4dCA9ICpwcmV2OwogICAgKnByZXYgPSBjOwogICAgYy0+aGFzaCA9IGhhc2g7CiAgICBjLT5maWxlID0gKEZjQ2hhcjggKikgKGMgKyAxKTsKICAgIGMtPmlkID0gaWQ7CiAgICBjLT5uYW1lID0gYy0+ZmlsZSArIHN0cmxlbiAoKGNoYXIgKikgZmlsZSkgKyAxOwogICAgc3RyY3B5IChjLT5maWxlLCBmaWxlKTsKICAgIGMtPnRpbWUgPSB0aW1lOwogICAgYy0+cmVmZXJlbmNlZCA9IHJlcGxhY2U7CiAgICBzdHJjcHkgKGMtPm5hbWUsIG5hbWUpOwogICAgY2FjaGUtPmVudHJpZXMrKzsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjRmlsZUNhY2hlICoKRmNGaWxlQ2FjaGVDcmVhdGUgKHZvaWQpCnsKICAgIEZjRmlsZUNhY2hlCSpjYWNoZTsKICAgIGludAkJaDsKCiAgICBjYWNoZSA9IG1hbGxvYyAoc2l6ZW9mIChGY0ZpbGVDYWNoZSkpOwogICAgaWYgKCFjYWNoZSkKCXJldHVybiAwOwogICAgZm9yIChoID0gMDsgaCA8IEZDX0ZJTEVfQ0FDSEVfSEFTSF9TSVpFOyBoKyspCgljYWNoZS0+ZW50c1toXSA9IDA7CiAgICBjYWNoZS0+ZW50cmllcyA9IDA7CiAgICBjYWNoZS0+cmVmZXJlbmNlZCA9IDA7CiAgICBjYWNoZS0+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICByZXR1cm4gY2FjaGU7Cn0KCnZvaWQKRmNGaWxlQ2FjaGVEZXN0cm95IChGY0ZpbGVDYWNoZSAqY2FjaGUpCnsKICAgIEZjRmlsZUNhY2hlRW50ICpjLCAqbmV4dDsKICAgIGludAkJICAgIGg7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0ZJTEVfQ0FDSEVfSEFTSF9TSVpFOyBoKyspCiAgICB7Cglmb3IgKGMgPSBjYWNoZS0+ZW50c1toXTsgYzsgYyA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGMtPm5leHQ7CgkgICAgZnJlZSAoYyk7Cgl9CiAgICB9CiAgICBmcmVlIChjYWNoZSk7Cn0KCnZvaWQKRmNGaWxlQ2FjaGVMb2FkIChGY0ZpbGVDYWNoZQkqY2FjaGUsCgkJIGNvbnN0IEZjQ2hhcjgJKmNhY2hlX2ZpbGUpCnsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgZmlsZV9idWZbODE5Ml0sICpmaWxlOwogICAgaW50CQkgICAgaWQ7CiAgICB0aW1lX3QJICAgIHRpbWU7CiAgICBGY0NoYXI4CSAgICBuYW1lX2J1Zls4MTkyXSwgKm5hbWU7CgogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQoJcmV0dXJuOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0ZpbGVDYWNoZVJlYWRTdHJpbmcgKGYsIGZpbGVfYnVmLCBzaXplb2YgKGZpbGVfYnVmKSkpICYmCgkgICBGY0ZpbGVDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIEZjRmlsZUNhY2hlUmVhZFRpbWUgKGYsICZ0aW1lKSAmJgoJICAgKG5hbWUgPSBGY0ZpbGVDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJKHZvaWQpIEZjRmlsZUNhY2hlQWRkIChjYWNoZSwgZmlsZSwgaWQsIHRpbWUsIG5hbWUsIEZjRmFsc2UpOwoJaWYgKGZpbGUgIT0gZmlsZV9idWYpCgkgICAgZnJlZSAoZmlsZSk7CglpZiAobmFtZSAhPSBuYW1lX2J1ZikKCSAgICBmcmVlIChuYW1lKTsKCWZpbGUgPSAwOwoJbmFtZSA9IDA7CiAgICB9CiAgICBpZiAoZmlsZSAmJiBmaWxlICE9IGZpbGVfYnVmKQoJZnJlZSAoZmlsZSk7CiAgICBpZiAobmFtZSAmJiBuYW1lICE9IG5hbWVfYnVmKQoJZnJlZSAobmFtZSk7CiAgICBmY2xvc2UgKGYpOwp9CgpGY0Jvb2wKRmNGaWxlQ2FjaGVVcGRhdGUgKEZjRmlsZUNhY2hlCSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqZmlsZSwKCQkgICBpbnQJCSAgICBpZCwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpuYW1lKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKm1hdGNoOwogICAgc3RydWN0IHN0YXQJICAgIHN0YXRiOwogICAgRmNCb29sCSAgICByZXQ7CgogICAgbWF0Y2ggPSBmaWxlOwoKICAgIGlmIChzdGF0ICgoY2hhciAqKSBmaWxlLCAmc3RhdGIpIDwgMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0ID0gRmNGaWxlQ2FjaGVBZGQgKGNhY2hlLCBtYXRjaCwgaWQsIAoJCQkgICAgc3RhdGIuc3RfbXRpbWUsIG5hbWUsIEZjVHJ1ZSk7CiAgICBpZiAocmV0KQoJY2FjaGUtPnVwZGF0ZWQgPSBGY1RydWU7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNCb29sCkZjRmlsZUNhY2hlV3JpdGVTdHJpbmcgKEZJTEUgKmYsIGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewogICAgY2hhciAgICBjOwoKICAgIGlmIChwdXRjICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgd2hpbGUgKChjID0gKnN0cmluZysrKSkKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnIic6CgljYXNlICdcXCc6CgkgICAgaWYgKHB1dGMgKCdcXCcsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICAvKiBmYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkgICAgaWYgKHB1dGMgKGMsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIGlmIChwdXRjICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0ZpbGVDYWNoZVdyaXRlVWxvbmcgKEZJTEUgKmYsIHVuc2lnbmVkIGxvbmcgdCkKewogICAgaW50CSAgICBwb3c7CiAgICB1bnNpZ25lZCBsb25nICAgdGVtcCwgZGlnaXQ7CgogICAgdGVtcCA9IHQ7CiAgICBwb3cgPSAxOwogICAgd2hpbGUgKHRlbXAgPj0gMTApCiAgICB7Cgl0ZW1wIC89IDEwOwoJcG93ICo9IDEwOwogICAgfQogICAgdGVtcCA9IHQ7CiAgICB3aGlsZSAocG93KQogICAgewoJZGlnaXQgPSB0ZW1wIC8gcG93OwoJaWYgKHB1dGMgKChjaGFyKSBkaWdpdCArICcwJywgZikgPT0gRU9GKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJdGVtcCA9IHRlbXAgLSBwb3cgKiBkaWdpdDsKCXBvdyA9IHBvdyAvIDEwOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0ZpbGVDYWNoZVdyaXRlSW50IChGSUxFICpmLCBpbnQgaSkKewogICAgcmV0dXJuIEZjRmlsZUNhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjRmlsZUNhY2hlV3JpdGVUaW1lIChGSUxFICpmLCB0aW1lX3QgdCkKewogICAgcmV0dXJuIEZjRmlsZUNhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIHQpOwp9CgpGY0Jvb2wKRmNGaWxlQ2FjaGVTYXZlIChGY0ZpbGVDYWNoZQkqY2FjaGUsCgkJIGNvbnN0IEZjQ2hhcjgJKmNhY2hlX2ZpbGUpCnsKICAgIEZjQ2hhcjgJICAgICpsY2s7CiAgICBGY0NoYXI4CSAgICAqdG1wOwogICAgRklMRQkgICAgKmY7CiAgICBpbnQJCSAgICBoOwogICAgRmNGaWxlQ2FjaGVFbnQgKmM7CgogICAgaWYgKCFjYWNoZS0+dXBkYXRlZCAmJiBjYWNoZS0+cmVmZXJlbmNlZCA9PSBjYWNoZS0+ZW50cmllcykKCXJldHVybiBGY1RydWU7CiAgICAKICAgIGxjayA9IG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBjYWNoZV9maWxlKSoyICsgNCk7CiAgICBpZiAoIWxjaykKCWdvdG8gYmFpbDA7CiAgICB0bXAgPSBsY2sgKyBzdHJsZW4gKChjaGFyICopIGNhY2hlX2ZpbGUpICsgMjsKICAgIHN0cmNweSAoKGNoYXIgKikgbGNrLCAoY2hhciAqKSBjYWNoZV9maWxlKTsKICAgIHN0cmNhdCAoKGNoYXIgKikgbGNrLCAiTCIpOwogICAgc3RyY3B5ICgoY2hhciAqKSB0bXAsIChjaGFyICopIGNhY2hlX2ZpbGUpOwogICAgc3RyY2F0ICgoY2hhciAqKSB0bXAsICJUIik7CiAgICBpZiAobGluayAoKGNoYXIgKikgbGNrLCAoY2hhciAqKSBjYWNoZV9maWxlKSA8IDAgJiYgZXJybm8gIT0gRU5PRU5UKQoJZ290byBiYWlsMTsKICAgIGlmIChhY2Nlc3MgKChjaGFyICopIHRtcCwgRl9PSykgPT0gMCkKCWdvdG8gYmFpbDI7CiAgICBmID0gZm9wZW4gKChjaGFyICopIHRtcCwgInciKTsKICAgIGlmICghZikKCWdvdG8gYmFpbDI7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0ZJTEVfQ0FDSEVfSEFTSF9TSVpFOyBoKyspCiAgICB7Cglmb3IgKGMgPSBjYWNoZS0+ZW50c1toXTsgYzsgYyA9IGMtPm5leHQpCgl7CgkgICAgaWYgKCFjLT5yZWZlcmVuY2VkKQoJCWNvbnRpbnVlOwoJICAgIGlmICghRmNGaWxlQ2FjaGVXcml0ZVN0cmluZyAoZiwgYy0+ZmlsZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjRmlsZUNhY2hlV3JpdGVJbnQgKGYsIGMtPmlkKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCQlnb3RvIGJhaWw0OwoJICAgIGlmICghRmNGaWxlQ2FjaGVXcml0ZVRpbWUgKGYsIGMtPnRpbWUpKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0ZpbGVDYWNoZVdyaXRlU3RyaW5nIChmLCBjLT5uYW1lKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChwdXRjICgnXG4nLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCX0KICAgIH0KCiAgICBpZiAoZmNsb3NlIChmKSA9PSBFT0YpCglnb3RvIGJhaWwzOwogICAgCiAgICBpZiAocmVuYW1lICgoY2hhciAqKSB0bXAsIChjaGFyICopIGNhY2hlX2ZpbGUpIDwgMCkKCWdvdG8gYmFpbDM7CiAgICAKICAgIHVubGluayAoKGNoYXIgKikgbGNrKTsKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7CgpiYWlsNDoKICAgIGZjbG9zZSAoZik7CmJhaWwzOgogICAgdW5saW5rICgoY2hhciAqKSB0bXApOwpiYWlsMjoKICAgIHVubGluayAoKGNoYXIgKikgbGNrKTsKYmFpbDE6CiAgICBmcmVlIChsY2spOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNGaWxlQ2FjaGVSZWFkRGlyIChGY0ZvbnRTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqY2FjaGVfZmlsZSkKewogICAgRmNQYXR0ZXJuCSAgICAqZm9udDsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgKnBhdGg7CiAgICBGY0NoYXI4CSAgICAqYmFzZTsKICAgIEZjQ2hhcjgJICAgIGZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIGludAkJICAgIGlkOwogICAgRmNDaGFyOAkgICAgbmFtZV9idWZbODE5Ml0sICpuYW1lOwogICAgRmNCb29sCSAgICByZXQgPSBGY0ZhbHNlOwoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQogICAgewoJcHJpbnRmICgiRmNGaWxlQ2FjaGVSZWFkRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIH0KICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgl7CgkgICAgcHJpbnRmICgiIG5vIGNhY2hlIGZpbGVcbiIpOwoJfQoJZ290byBiYWlsMDsKICAgIH0KCiAgICBiYXNlID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJy8nKTsKICAgIGlmICghYmFzZSkKCWdvdG8gYmFpbDE7CiAgICBiYXNlKys7CiAgICBwYXRoID0gbWFsbG9jIChiYXNlIC0gY2FjaGVfZmlsZSArIDgxOTIgKyAxKTsKICAgIGlmICghcGF0aCkKCWdvdG8gYmFpbDE7CiAgICBtZW1jcHkgKHBhdGgsIGNhY2hlX2ZpbGUsIGJhc2UgLSBjYWNoZV9maWxlKTsKICAgIGJhc2UgPSBwYXRoICsgKGJhc2UgLSBjYWNoZV9maWxlKTsKICAgIAogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjRmlsZUNhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjRmlsZUNhY2hlUmVhZEludCAoZiwgJmlkKSAmJgoJICAgKG5hbWUgPSBGY0ZpbGVDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJZm9udCA9IEZjTmFtZVBhcnNlIChuYW1lKTsKCWlmIChmb250KQoJewoJICAgIHN0cmNweSAoYmFzZSwgZmlsZSk7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHsKCQlwcmludGYgKCIgZGlyIGNhY2hlIGZpbGUgXCIlc1wiXG4iLCBmaWxlKTsKCSAgICB9CgkgICAgRmNQYXR0ZXJuQWRkU3RyaW5nIChmb250LCBGQ19GSUxFLCBwYXRoKTsKCSAgICBpZiAoIUZjRm9udFNldEFkZCAoc2V0LCBmb250KSkKCQlnb3RvIGJhaWwyOwoJfQoJaWYgKGZpbGUgIT0gZmlsZV9idWYpCgkgICAgZnJlZSAoZmlsZSk7CglpZiAobmFtZSAhPSBuYW1lX2J1ZikKCSAgICBmcmVlIChuYW1lKTsKCWZpbGUgPSBuYW1lID0gMDsKICAgIH0KICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQogICAgewoJcHJpbnRmICgiIGNhY2hlIGxvYWRlZFxuIik7CiAgICB9CiAgICAKICAgIHJldCA9IEZjVHJ1ZTsKYmFpbDI6CiAgICBmcmVlIChwYXRoKTsKICAgIGlmIChmaWxlICYmIGZpbGUgIT0gZmlsZV9idWYpCglmcmVlIChmaWxlKTsKICAgIGlmIChuYW1lICYmIG5hbWUgIT0gbmFtZV9idWYpCglmcmVlIChuYW1lKTsKYmFpbDE6CiAgICBmY2xvc2UgKGYpOwpiYWlsMDoKICAgIHJldHVybiByZXQ7Cn0KCkZjQm9vbApGY0ZpbGVDYWNoZVdyaXRlRGlyIChGY0ZvbnRTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqY2FjaGVfZmlsZSkKewogICAgRmNQYXR0ZXJuCSAgICAqZm9udDsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgKm5hbWU7CiAgICBjb25zdCBGY0NoYXI4ICAgKmZpbGUsICpiYXNlOwogICAgaW50CQkgICAgbjsKICAgIGludAkJICAgIGlkOwogICAgRmNCb29sCSAgICByZXQ7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0ZpbGVDYWNoZVdyaXRlRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAidyIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGNhbid0IGNyZWF0ZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwoJZ290byBiYWlsMDsKICAgIH0KICAgIGZvciAobiA9IDA7IG4gPCBzZXQtPm5mb250OyBuKyspCiAgICB7Cglmb250ID0gc2V0LT5mb250c1tuXTsKCWlmIChGY1BhdHRlcm5HZXRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIDAsIChGY0NoYXI4ICoqKSAmZmlsZSkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwxOwoJYmFzZSA9IChGY0NoYXI4ICopIHN0cnJjaHIgKChjaGFyICopIGZpbGUsICcvJyk7CglpZiAoYmFzZSkKCSAgICBiYXNlID0gYmFzZSArIDE7CgllbHNlCgkgICAgYmFzZSA9IGZpbGU7CglpZiAoRmNQYXR0ZXJuR2V0SW50ZWdlciAoZm9udCwgRkNfSU5ERVgsIDAsICZpZCkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwxOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiB3cml0ZSBmaWxlIFwiJXNcIlxuIiwgYmFzZSk7CglpZiAoIUZjRmlsZUNhY2hlV3JpdGVTdHJpbmcgKGYsIGJhc2UpKQoJICAgIGdvdG8gYmFpbDE7CglpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMTsKCWlmICghRmNGaWxlQ2FjaGVXcml0ZUludCAoZiwgaWQpKQoJICAgIGdvdG8gYmFpbDE7CiAgICAgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDE7CgluYW1lID0gRmNOYW1lVW5wYXJzZSAoZm9udCk7CglpZiAoIW5hbWUpCgkgICAgZ290byBiYWlsMTsKCXJldCA9IEZjRmlsZUNhY2hlV3JpdGVTdHJpbmcgKGYsIG5hbWUpOwoJZnJlZSAobmFtZSk7CglpZiAoIXJldCkKCSAgICBnb3RvIGJhaWwxOwoJaWYgKHB1dGMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwxOwogICAgfQogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQoJZ290byBiYWlsMDsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCIgY2FjaGUgd3JpdHRlblxuIik7CiAgICByZXR1cm4gRmNUcnVlOwogICAgCmJhaWwxOgogICAgZmNsb3NlIChmKTsKYmFpbDA6CiAgICB1bmxpbmsgKChjaGFyICopIGNhY2hlX2ZpbGUpOwogICAgcmV0dXJuIEZjRmFsc2U7Cn0K