LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9mYy1jYWNoZS9mYy1jYWNoZS5jLHYgMS44dHNpIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDIgS2VpdGggUGFja2FyZAogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGZvbnRjb25maWcvZm9udGNvbmZpZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaWZkZWYgSEFWRV9DT05GSUdfSAojaW5jbHVkZSA8Y29uZmlnLmg+CiNlbHNlCiNpZmRlZiBsaW51eAojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMQojZW5kaWYKI2RlZmluZSBIQVZFX0dFVE9QVCAxCiNlbmRpZgoKI2lmbmRlZiBIQVZFX0dFVE9QVAojZGVmaW5lIEhBVkVfR0VUT1BUIDAKI2VuZGlmCiNpZm5kZWYgSEFWRV9HRVRPUFRfTE9ORwojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMAojZW5kaWYKCiNpZiBIQVZFX0dFVE9QVF9MT05HCiN1bmRlZiAgX0dOVV9TT1VSQ0UKI2RlZmluZSBfR05VX1NPVVJDRQojaW5jbHVkZSA8Z2V0b3B0Lmg+CmNvbnN0IHN0cnVjdCBvcHRpb24gbG9uZ29wdHNbXSA9IHsKICAgIHsiZm9yY2UiLCAwLCAwLCAnZid9LAogICAgeyJzeXN0ZW0tb25seSIsIDAsIDAsICdzJ30sCiAgICB7InZlcnNpb24iLCAwLCAwLCAnVid9LAogICAgeyJ2ZXJib3NlIiwgMCwgMCwgJ3YnfSwKICAgIHsiaGVscCIsIDAsIDAsICc/J30sCiAgICB7TlVMTCwwLDAsMH0sCn07CiNlbHNlCiNpZiBIQVZFX0dFVE9QVApleHRlcm4gY2hhciAqb3B0YXJnOwpleHRlcm4gaW50IG9wdGluZCwgb3B0ZXJyLCBvcHRvcHQ7CiNlbmRpZgojZW5kaWYKCnN0YXRpYyB2b2lkCnVzYWdlIChjaGFyICpwcm9ncmFtKQp7CiNpZiBIQVZFX0dFVE9QVF9MT05HCiAgICBmcHJpbnRmIChzdGRlcnIsICJ1c2FnZTogJXMgWy1mc3ZWP10gWy0tZm9yY2VdIFstLXN5c3RlbS1vbmx5XSBbLS12ZXJib3NlXSBbLS12ZXJzaW9uXSBbLS1oZWxwXSBbZGlyc11cbiIsCgkgICAgIHByb2dyYW0pOwojZWxzZQogICAgZnByaW50ZiAoc3RkZXJyLCAidXNhZ2U6ICVzIFstZnN2Vj9dIFtkaXJzXVxuIiwKCSAgICAgcHJvZ3JhbSk7CiNlbmRpZgogICAgZnByaW50ZiAoc3RkZXJyLCAiQnVpbGQgZm9udCBpbmZvcm1hdGlvbiBjYWNoZXMgaW4gW2RpcnNdXG4iCgkgICAgICIoYWxsIGRpcmVjdG9yaWVzIGluIGZvbnQgY29uZmlndXJhdGlvbiBieSBkZWZhdWx0KS5cbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiXG4iKTsKI2lmIEhBVkVfR0VUT1BUX0xPTkcKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLWYsIC0tZm9yY2UgICAgICAgICAgc2NhbiBkaXJlY3RvcmllcyB3aXRoIGFwcGFyZW50bHkgdmFsaWQgY2FjaGVzXG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXMsIC0tc3lzdGVtLW9ubHkgICAgc2NhbiBzeXN0ZW0td2lkZSBkaXJlY3RvcmllcyBvbmx5XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXYsIC0tdmVyYm9zZSAgICAgICAgZGlzcGxheSBzdGF0dXMgaW5mb3JtYXRpb24gd2hpbGUgYnVzeVxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC1WLCAtLXZlcnNpb24gICAgICAgIGRpc3BsYXkgZm9udCBjb25maWcgdmVyc2lvbiBhbmQgZXhpdFxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC0/LCAtLWhlbHAgICAgICAgICAgIGRpc3BsYXkgdGhpcyBoZWxwIGFuZCBleGl0XG4iKTsKI2Vsc2UKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLWYgICAgICAgICAoZm9yY2UpICAgc2NhbiBkaXJlY3RvcmllcyB3aXRoIGFwcGFyZW50bHkgdmFsaWQgY2FjaGVzXG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXMgICAgICAgICAoc3lzdGVtKSAgc2NhbiBzeXN0ZW0td2lkZSBkaXJlY3RvcmllcyBvbmx5XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLXYgICAgICAgICAodmVyYm9zZSkgZGlzcGxheSBzdGF0dXMgaW5mb3JtYXRpb24gd2hpbGUgYnVzeVxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC1WICAgICAgICAgKHZlcnNpb24pIGRpc3BsYXkgZm9udCBjb25maWcgdmVyc2lvbiBhbmQgZXhpdFxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICIgIC0/ICAgICAgICAgKGhlbHApICAgIGRpc3BsYXkgdGhpcyBoZWxwIGFuZCBleGl0XG4iKTsKI2VuZGlmCiAgICBleGl0ICgxKTsKfQoKc3RhdGljIGludApuc3ViZGlycyAoRmNTdHJTZXQgKnNldCkKewogICAgRmNTdHJMaXN0CSpsaXN0OwogICAgaW50CQluID0gMDsKCiAgICBsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzZXQpOwogICAgaWYgKCFsaXN0KQoJcmV0dXJuIDA7CiAgICB3aGlsZSAoRmNTdHJMaXN0TmV4dCAobGlzdCkpCgluKys7CiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIHJldHVybiBuOwp9CgpzdGF0aWMgaW50CnNjYW5EaXJzIChGY1N0ckxpc3QgKmxpc3QsIEZjQ29uZmlnICpjb25maWcsIGNoYXIgKnByb2dyYW0sIEZjQm9vbCBmb3JjZSwgRmNCb29sIHZlcmJvc2UpCnsKICAgIGludAkJcmV0ID0gMDsKICAgIEZjQ2hhcjgJKmRpcjsKICAgIEZjRm9udFNldAkqc2V0OwogICAgRmNTdHJTZXQJKnN1YmRpcnM7CiAgICBGY1N0ckxpc3QJKnN1Ymxpc3Q7CiAgICBzdHJ1Y3Qgc3RhdAlzdGF0YjsKICAgIAogICAgLyoKICAgICAqIE5vdyBzY2FuIGFsbCBvZiB0aGUgZGlyZWN0b3JpZXMgaW50byBzZXBhcmF0ZSBkYXRhYmFzZXMKICAgICAqIGFuZCB3cml0ZSBvdXQgdGhlIHJlc3VsdHMKICAgICAqLwogICAgd2hpbGUgKChkaXIgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCiAgICB7CglpZiAodmVyYm9zZSkKCXsKCSAgICBwcmludGYgKCIlczogXCIlc1wiOiAiLCBwcm9ncmFtLCBkaXIpOwoJICAgIGZmbHVzaCAoc3Rkb3V0KTsKCX0KCXNldCA9IEZjRm9udFNldENyZWF0ZSAoKTsKCWlmICghc2V0KQoJewoJICAgIGZwcmludGYgKHN0ZGVyciwgIkNhbid0IGNyZWF0ZSBmb250IHNldFxuIik7CgkgICAgcmV0Kys7CgkgICAgY29udGludWU7Cgl9CglzdWJkaXJzID0gRmNTdHJTZXRDcmVhdGUgKCk7CglpZiAoIXN1YmRpcnMpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiQ2FuJ3QgY3JlYXRlIGRpcmVjdG9yeSBzZXRcbiIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJCglpZiAoYWNjZXNzICgoY2hhciAqKSBkaXIsIFdfT0spIDwgMCkKCXsKCSAgICBzd2l0Y2ggKGVycm5vKSB7CgkgICAgY2FzZSBFTk9FTlQ6CgkgICAgY2FzZSBFTk9URElSOgoJCWlmICh2ZXJib3NlKQoJCSAgICBwcmludGYgKCJza2lwcGluZywgbm8gc3VjaCBkaXJlY3RvcnlcbiIpOwoJCWJyZWFrOwoJICAgIGNhc2UgRUFDQ0VTOgoJICAgIGNhc2UgRVJPRlM6CgkJaWYgKHZlcmJvc2UpCgkJICAgIHByaW50ZiAoInNraXBwaW5nLCBubyB3cml0ZSBhY2Nlc3NcbiIpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJZnByaW50ZiAoc3RkZXJyLCAiXCIlc1wiOiAiLCBkaXIpOwoJCXBlcnJvciAoIiIpOwoJCXJldCsrOwoJICAgIH0KCSAgICBjb250aW51ZTsKCX0KCWlmIChzdGF0ICgoY2hhciAqKSBkaXIsICZzdGF0YikgPT0gLTEpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiXCIlc1wiOiAiLCBkaXIpOwoJICAgIHBlcnJvciAoIiIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKCFTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJcIiVzXCI6IG5vdCBhIGRpcmVjdG9yeSwgc2tpcHBpbmdcbiIsIGRpcik7CgkgICAgY29udGludWU7Cgl9CglpZiAoIUZjRGlyU2NhbiAoc2V0LCBzdWJkaXJzLCAwLCBGY0NvbmZpZ0dldEJsYW5rcyAoY29uZmlnKSwgZGlyLCBmb3JjZSkpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiXCIlc1wiOiBlcnJvciBzY2FubmluZ1xuIiwgZGlyKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCWlmICghZm9yY2UgJiYgRmNEaXJDYWNoZVZhbGlkIChkaXIpKQoJewoJICAgIGlmICh2ZXJib3NlKQoJCXByaW50ZiAoInNraXBwaW5nLCAlZCBmb250cywgJWQgZGlyc1xuIiwKCQkJc2V0LT5uZm9udCwgbnN1YmRpcnMoc3ViZGlycykpOwoJfQoJZWxzZQoJewoJICAgIGlmICh2ZXJib3NlKQoJCXByaW50ZiAoImNhY2hpbmcsICVkIGZvbnRzLCAlZCBkaXJzXG4iLCAKCQkJc2V0LT5uZm9udCwgbnN1YmRpcnMgKHN1YmRpcnMpKTsKCSAgICBpZiAoIUZjRGlyU2F2ZSAoc2V0LCBzdWJkaXJzLCBkaXIpKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBzYXZlIGNhY2hlIGluIFwiJXNcIlxuIiwgZGlyKTsKCQlyZXQrKzsKCSAgICB9Cgl9CglGY0ZvbnRTZXREZXN0cm95IChzZXQpOwoJc3VibGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc3ViZGlycyk7CglpZiAoIXN1Ymxpc3QpCgl7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiQ2FuJ3QgY3JlYXRlIHN1YmRpciBsaXN0IGluIFwiJXNcIlxuIiwgZGlyKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCXJldCArPSBzY2FuRGlycyAoc3VibGlzdCwgY29uZmlnLCBwcm9ncmFtLCBmb3JjZSwgdmVyYm9zZSk7CglGY1N0clNldERlc3Ryb3kgKHN1YmRpcnMpOwogICAgfQogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICByZXR1cm4gcmV0Owp9CgppbnQKbWFpbiAoaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CiAgICBGY1N0clNldAkqZGlyczsKICAgIEZjU3RyTGlzdAkqbGlzdDsKICAgIEZjQm9vbCAgICAJdmVyYm9zZSA9IEZjRmFsc2U7CiAgICBGY0Jvb2wJZm9yY2UgPSBGY0ZhbHNlOwogICAgRmNCb29sCXN5c3RlbU9ubHkgPSBGY0ZhbHNlOwogICAgRmNDb25maWcJKmNvbmZpZzsKICAgIGludAkJaTsKICAgIGludAkJcmV0OwojaWYgSEFWRV9HRVRPUFRfTE9ORyB8fCBIQVZFX0dFVE9QVAogICAgaW50CQljOwoKI2lmIEhBVkVfR0VUT1BUX0xPTkcKICAgIHdoaWxlICgoYyA9IGdldG9wdF9sb25nIChhcmdjLCBhcmd2LCAiZnNWdj8iLCBsb25nb3B0cywgTlVMTCkpICE9IC0xKQojZWxzZQogICAgd2hpbGUgKChjID0gZ2V0b3B0IChhcmdjLCBhcmd2LCAiZnNWdj8iKSkgIT0gLTEpCiNlbmRpZgogICAgewoJc3dpdGNoIChjKSB7CgljYXNlICdmJzoKCSAgICBmb3JjZSA9IEZjVHJ1ZTsKCSAgICBicmVhazsKCWNhc2UgJ3MnOgoJICAgIHN5c3RlbU9ubHkgPSBGY1RydWU7CgkgICAgYnJlYWs7CgljYXNlICdWJzoKCSAgICBmcHJpbnRmIChzdGRlcnIsICJmb250Y29uZmlnIHZlcnNpb24gJWQuJWQuJWRcbiIsIAoJCSAgICAgRkNfTUFKT1IsIEZDX01JTk9SLCBGQ19SRVZJU0lPTik7CgkgICAgZXhpdCAoMCk7CgljYXNlICd2JzoKCSAgICB2ZXJib3NlID0gRmNUcnVlOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICB1c2FnZSAoYXJndlswXSk7Cgl9CiAgICB9CiAgICBpID0gb3B0aW5kOwojZWxzZQogICAgaSA9IDE7CiNlbmRpZgoKICAgIGlmIChzeXN0ZW1Pbmx5KQoJRmNDb25maWdFbmFibGVIb21lIChGY0ZhbHNlKTsKICAgIGNvbmZpZyA9IEZjSW5pdExvYWRDb25maWcgKCk7CiAgICBpZiAoIWNvbmZpZykKICAgIHsKCWZwcmludGYgKHN0ZGVyciwgIiVzOiBDYW4ndCBpbml0IGZvbnQgY29uZmlnIGxpYnJhcnlcbiIsIGFyZ3ZbMF0pOwoJcmV0dXJuIDE7CiAgICB9CiAgICBpZiAoYXJndltpXSkKICAgIHsKCWRpcnMgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghZGlycykKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgY3JlYXRlIGxpc3Qgb2YgZGlyZWN0b3JpZXNcbiIsCgkJICAgICBhcmd2WzBdKTsKCSAgICByZXR1cm4gMTsKCX0KCXdoaWxlIChhcmd2W2ldKQoJewoJICAgIGlmICghRmNTdHJTZXRBZGQgKGRpcnMsIChGY0NoYXI4ICopIGFyZ3ZbaV0pKQoJICAgIHsKCQlmcHJpbnRmIChzdGRlcnIsICIlczogQ2FuJ3QgYWRkIGRpcmVjdG9yeVxuIiwgYXJndlswXSk7CgkJcmV0dXJuIDE7CgkgICAgfQoJICAgIGkrKzsKCX0KCWxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGRpcnMpOwoJRmNTdHJTZXREZXN0cm95IChkaXJzKTsKICAgIH0KICAgIGVsc2UKCWxpc3QgPSBGY0NvbmZpZ0dldENvbmZpZ0RpcnMgKGNvbmZpZyk7CiAgICByZXQgPSBzY2FuRGlycyAobGlzdCwgY29uZmlnLCBhcmd2WzBdLCBmb3JjZSwgdmVyYm9zZSk7CiAgICBpZiAodmVyYm9zZSkKCXByaW50ZiAoIiVzOiAlc1xuIiwgYXJndlswXSwgcmV0ID8gImZhaWxlZCIgOiAic3VjY2VlZGVkIik7CiAgICByZXR1cm4gcmV0Owp9Cg==