LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL2ZjLWNhY2hlL2ZjLWNhY2hlLmMsdiAxLjUgMjAwMi8wNi8xOSAyMDo1NToxOSBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGZvbnRjb25maWcvZm9udGNvbmZpZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2lmZGVmIEhBVkVfQ09ORklHX0gKI2luY2x1ZGUgPGNvbmZpZy5oPgojZWxzZQojaWZkZWYgbGludXgKI2RlZmluZSBIQVZFX0dFVE9QVF9MT05HIDEKI2VuZGlmCiNkZWZpbmUgSEFWRV9HRVRPUFQgMQojZW5kaWYKCiNpZm5kZWYgSEFWRV9HRVRPUFQKI2RlZmluZSBIQVZFX0dFVE9QVCAwCiNlbmRpZgojaWZuZGVmIEhBVkVfR0VUT1BUX0xPTkcKI2RlZmluZSBIQVZFX0dFVE9QVF9MT05HIDAKI2VuZGlmCgojaWYgSEFWRV9HRVRPUFRfTE9ORwojdW5kZWYgIF9HTlVfU09VUkNFCiNkZWZpbmUgX0dOVV9TT1VSQ0UKI2luY2x1ZGUgPGdldG9wdC5oPgpjb25zdCBzdHJ1Y3Qgb3B0aW9uIGxvbmdvcHRzW10gPSB7CiAgICB7ImZvcmNlIiwgMCwgMCwgJ2YnfSwKICAgIHsidmVyc2lvbiIsIDAsIDAsICdWJ30sCiAgICB7InZlcmJvc2UiLCAwLCAwLCAndid9LAogICAgeyJoZWxwIiwgMCwgMCwgJz8nfSwKICAgIHtOVUxMLDAsMCwwfSwKfTsKI2Vsc2UKI2lmIEhBVkVfR0VUT1BUCmV4dGVybiBjaGFyICpvcHRhcmc7CmV4dGVybiBpbnQgb3B0aW5kLCBvcHRlcnIsIG9wdG9wdDsKI2VuZGlmCiNlbmRpZgoKc3RhdGljIHZvaWQKdXNhZ2UgKGNoYXIgKnByb2dyYW0pCnsKICAgIGZwcmludGYgKHN0ZGVyciwgInVzYWdlOiAlcyBbLWZ2Vj9dIFstLWZvcmNlXSBbLS12ZXJib3NlXSBbLS12ZXJzaW9uXSBbLS1oZWxwXSBbZGlyc11cbiIsCgkgICAgIHByb2dyYW0pOwogICAgZnByaW50ZiAoc3RkZXJyLCAiQnVpbGQgZm9udCBpbmZvcm1hdGlvbiBjYWNoZXMgaW4gW2RpcnNdXG4iCgkgICAgICIoYWxsIGRpcmVjdG9yaWVzIGluIGZvbnQgY29uZmlndXJhdGlvbiBieSBkZWZhdWx0KS5cbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiXG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXYsIC0tZm9yY2UgICAgICAgICAgc2NhbiBkaXJlY3RvcmllcyB3aXRoIGFwcGFyZW50bHkgdmFsaWQgY2FjaGVzXG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXYsIC0tdmVyYm9zZSAgICAgICAgZGlzcGxheSBzdGF0dXMgaW5mb3JtYXRpb24gd2hpbGUgYnVzeVxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC1WLCAtLXZlcnNpb24gICAgICAgIGRpc3BsYXkgZm9udCBjb25maWcgdmVyc2lvbiBhbmQgZXhpdFxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC0/LCAtLWhlbHAgICAgICAgICAgIGRpc3BsYXkgdGhpcyBoZWxwIGFuZCBleGl0XG4iKTsKICAgIGV4aXQgKDEpOwp9CgpzdGF0aWMgaW50Cm5zdWJkaXJzIChGY1N0clNldCAqc2V0KQp7CiAgICBGY1N0ckxpc3QJKmxpc3Q7CiAgICBpbnQJCW4gPSAwOwoKICAgIGxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKHNldCk7CiAgICBpZiAoIWxpc3QpCglyZXR1cm4gMDsKICAgIHdoaWxlIChGY1N0ckxpc3ROZXh0IChsaXN0KSkKCW4rKzsKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwogICAgcmV0dXJuIG47Cn0KCnN0YXRpYyBpbnQKc2NhbkRpcnMgKEZjU3RyTGlzdCAqbGlzdCwgRmNDb25maWcgKmNvbmZpZywgY2hhciAqcHJvZ3JhbSwgRmNCb29sIGZvcmNlLCBGY0Jvb2wgdmVyYm9zZSkKewogICAgaW50CQlyZXQgPSAwOwogICAgRmNDaGFyOAkqZGlyOwogICAgRmNGb250U2V0CSpzZXQ7CiAgICBGY1N0clNldAkqc3ViZGlyczsKICAgIEZjU3RyTGlzdAkqc3VibGlzdDsKICAgIHN0cnVjdCBzdGF0CXN0YXRiOwogICAgCiAgICAvKgogICAgICogTm93IHNjYW4gYWxsIG9mIHRoZSBkaXJlY3RvcmllcyBpbnRvIHNlcGFyYXRlIGRhdGFiYXNlcwogICAgICogYW5kIHdyaXRlIG91dCB0aGUgcmVzdWx0cwogICAgICovCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWlmICh2ZXJib3NlKQoJewoJICAgIHByaW50ZiAoIiVzOiBcIiVzXCI6ICIsIHByb2dyYW0sIGRpcik7CgkgICAgZmZsdXNoIChzdGRvdXQpOwoJfQoJc2V0ID0gRmNGb250U2V0Q3JlYXRlICgpOwoJaWYgKCFzZXQpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiQ2FuJ3QgY3JlYXRlIGZvbnQgc2V0XG4iKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCXN1YmRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghc3ViZGlycykKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBjcmVhdGUgZGlyZWN0b3J5IHNldFxuIik7CgkgICAgcmV0Kys7CgkgICAgY29udGludWU7Cgl9CgkKCWlmIChzdGF0ICgoY2hhciAqKSBkaXIsICZzdGF0YikgPT0gLTEpCgl7CgkgICAgaWYgKGVycm5vID09IEVOT0VOVCB8fCBlcnJubyA9PSBFTk9URElSKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICJcIiVzXCI6IG5vIHN1Y2ggZGlyZWN0b3J5LCBza2lwcGluZ1xuIiwgZGlyKTsKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICJcIiVzXCI6ICIsIGRpcik7CgkJcGVycm9yICgiIik7CgkJcmV0Kys7CgkgICAgfQoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKCFTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJcIiVzXCI6IG5vdCBhIGRpcmVjdG9yeSwgc2tpcHBpbmdcbiIsIGRpcik7CgkgICAgY29udGludWU7Cgl9CglpZiAoIUZjRGlyU2NhbiAoc2V0LCBzdWJkaXJzLCAwLCBGY0NvbmZpZ0dldEJsYW5rcyAoY29uZmlnKSwgZGlyLCBmb3JjZSkpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiXCIlc1wiOiBlcnJvciBzY2FubmluZ1xuIiwgZGlyKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCWlmICghZm9yY2UgJiYgRmNEaXJDYWNoZVZhbGlkIChkaXIpKQoJewoJICAgIGlmICh2ZXJib3NlKQoJCXByaW50ZiAoInNraXBwaW5nLCAlZCBmb250cywgJWQgZGlyc1xuIiwKCQkJc2V0LT5uZm9udCwgbnN1YmRpcnMoc3ViZGlycykpOwoJfQoJZWxzZQoJewoJICAgIGlmICh2ZXJib3NlKQoJCXByaW50ZiAoImNhY2hpbmcsICVkIGZvbnRzLCAlZCBkaXJzXG4iLCAKCQkJc2V0LT5uZm9udCwgbnN1YmRpcnMgKHN1YmRpcnMpKTsKCSAgICBpZiAoIUZjRGlyU2F2ZSAoc2V0LCBzdWJkaXJzLCBkaXIpKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBzYXZlIGNhY2hlIGluIFwiJXNcIlxuIiwgZGlyKTsKCQlyZXQrKzsKCSAgICB9Cgl9CglGY0ZvbnRTZXREZXN0cm95IChzZXQpOwoJc3VibGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc3ViZGlycyk7CglpZiAoIXN1Ymxpc3QpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiQ2FuJ3QgY3JlYXRlIHN1YmRpciBsaXN0IGluIFwiJXNcIlxuIiwgZGlyKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCXJldCArPSBzY2FuRGlycyAoc3VibGlzdCwgY29uZmlnLCBwcm9ncmFtLCBmb3JjZSwgdmVyYm9zZSk7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwogICAgfQogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICByZXR1cm4gcmV0Owp9CgppbnQKbWFpbiAoaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CiAgICBGY1N0clNldAkqZGlyczsKICAgIEZjU3RyTGlzdAkqbGlzdDsKICAgIEZjQm9vbCAgICAJdmVyYm9zZSA9IEZjRmFsc2U7CiAgICBGY0Jvb2wJZm9yY2UgPSBGY0ZhbHNlOwogICAgRmNDb25maWcJKmNvbmZpZzsKICAgIGludAkJaTsKICAgIGludAkJcmV0OwojaWYgSEFWRV9HRVRPUFRfTE9ORyB8fCBIQVZFX0dFVE9QVAogICAgaW50CQljOwoKI2lmIEhBVkVfR0VUT1BUX0xPTkcKICAgIHdoaWxlICgoYyA9IGdldG9wdF9sb25nIChhcmdjLCBhcmd2LCAiZlZ2PyIsIGxvbmdvcHRzLCBOVUxMKSkgIT0gLTEpCiNlbHNlCiAgICB3aGlsZSAoKGMgPSBnZXRvcHQgKGFyZ2MsIGFyZ3YsICJmVnY/IikpICE9IC0xKQojZW5kaWYKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnZic6CgkgICAgZm9yY2UgPSBGY1RydWU7CgkgICAgYnJlYWs7CgljYXNlICdWJzoKCSAgICBmcHJpbnRmIChzdGRlcnIsICJmb250Y29uZmlnIHZlcnNpb24gJWQuJWQuJWRcbiIsIAoJCSAgICAgRkNfTUFKT1IsIEZDX01JTk9SLCBGQ19SRVZJU0lPTik7CgkgICAgZXhpdCAoMCk7CgljYXNlICd2JzoKCSAgICB2ZXJib3NlID0gRmNUcnVlOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB1c2FnZSAoYXJndlswXSk7Cgl9CiAgICB9CiAgICBpID0gb3B0aW5kOwojZWxzZQogICAgaSA9IDE7CiNlbmRpZgoKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWcgKCk7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWZwcmludGYgKHN0ZGVyciwgIiVzOiBDYW4ndCBpbml0IGZvbnQgY29uZmlnIGxpYnJhcnlcbiIsIGFyZ3ZbMF0pOwoJcmV0dXJuIDE7CiAgICB9CiAgICBpZiAoYXJndltpXSkKICAgIHsKCWRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghZGlycykKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgY3JlYXRlIGxpc3Qgb2YgZGlyZWN0b3JpZXNcbiIsCgkJICAgICBhcmd2WzBdKTsKCSAgICByZXR1cm4gMTsKCX0KCXdoaWxlIChhcmd2W2ldKQoJewoJICAgIGlmICghRmNTdHJTZXRBZGQgKGRpcnMsIChGY0NoYXI4ICopIGFyZ3ZbaV0pKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgYWRkIGRpcmVjdG9yeVxuIiwgYXJndlswXSk7CgkJcmV0dXJuIDE7CgkgICAgfQoJICAgIGkrKzsKCX0KCWxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGRpcnMpOwoJRmNTdHJTZXREZXN0cm95IChkaXJzKTsKICAgIH0KICAgIGVsc2UKCWxpc3QgPSBGY0NvbmZpZ0dldENvbmZpZ0RpcnMgKGNvbmZpZyk7CiAgICByZXQgPSBzY2FuRGlycyAobGlzdCwgY29uZmlnLCBhcmd2WzBdLCBmb3JjZSwgdmVyYm9zZSk7CiAgICBpZiAodmVyYm9zZSkKCXByaW50ZiAoIiVzOiAlc1xuIiwgYXJndlswXSwgcmV0ID8gImZhaWxlZCIgOiAic3VjY2VlZGVkIik7CiAgICByZXR1cm4gcmV0Owp9Cg==