LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL2ZjLWNhY2hlL2ZjLWNhY2hlLmMsdiAxLjh0c2kgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMiBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgPGZvbnRjb25maWcvZm9udGNvbmZpZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaWZkZWYgSEFWRV9DT05GSUdfSAojaW5jbHVkZSA8Y29uZmlnLmg+CiNlbHNlCiNpZmRlZiBsaW51eAojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMQojZW5kaWYKI2RlZmluZSBIQVZFX0dFVE9QVCAxCiNlbmRpZgoKI2lmbmRlZiBIQVZFX0dFVE9QVAojZGVmaW5lIEhBVkVfR0VUT1BUIDAKI2VuZGlmCiNpZm5kZWYgSEFWRV9HRVRPUFRfTE9ORwojZGVmaW5lIEhBVkVfR0VUT1BUX0xPTkcgMAojZW5kaWYKCiNpZiBIQVZFX0dFVE9QVF9MT05HCiN1bmRlZiAgX0dOVV9TT1VSQ0UKI2RlZmluZSBfR05VX1NPVVJDRQojaW5jbHVkZSA8Z2V0b3B0Lmg+CmNvbnN0IHN0cnVjdCBvcHRpb24gbG9uZ29wdHNbXSA9IHsKICAgIHsiZm9yY2UiLCAwLCAwLCAnZid9LAogICAgeyJ2ZXJzaW9uIiwgMCwgMCwgJ1YnfSwKICAgIHsidmVyYm9zZSIsIDAsIDAsICd2J30sCiAgICB7ImhlbHAiLCAwLCAwLCAnPyd9LAogICAge05VTEwsMCwwLDB9LAp9OwojZWxzZQojaWYgSEFWRV9HRVRPUFQKZXh0ZXJuIGNoYXIgKm9wdGFyZzsKZXh0ZXJuIGludCBvcHRpbmQsIG9wdGVyciwgb3B0b3B0OwojZW5kaWYKI2VuZGlmCgpzdGF0aWMgdm9pZAp1c2FnZSAoY2hhciAqcHJvZ3JhbSkKewogICAgZnByaW50ZiAoc3RkZXJyLCAidXNhZ2U6ICVzIFstZnZWP10gWy0tZm9yY2VdIFstLXZlcmJvc2VdIFstLXZlcnNpb25dIFstLWhlbHBdIFtkaXJzXVxuIiwKCSAgICAgcHJvZ3JhbSk7CiAgICBmcHJpbnRmIChzdGRlcnIsICJCdWlsZCBmb250IGluZm9ybWF0aW9uIGNhY2hlcyBpbiBbZGlyc11cbiIKCSAgICAgIihhbGwgZGlyZWN0b3JpZXMgaW4gZm9udCBjb25maWd1cmF0aW9uIGJ5IGRlZmF1bHQpLlxuIik7CiAgICBmcHJpbnRmIChzdGRlcnIsICJcbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiICAtZiwgLS1mb3JjZSAgICAgICAgICBzY2FuIGRpcmVjdG9yaWVzIHdpdGggYXBwYXJlbnRseSB2YWxpZCBjYWNoZXNcbiIpOwogICAgZnByaW50ZiAoc3RkZXJyLCAiICAtdiwgLS12ZXJib3NlICAgICAgICBkaXNwbGF5IHN0YXR1cyBpbmZvcm1hdGlvbiB3aGlsZSBidXN5XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLVYsIC0tdmVyc2lvbiAgICAgICAgZGlzcGxheSBmb250IGNvbmZpZyB2ZXJzaW9uIGFuZCBleGl0XG4iKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIiAgLT8sIC0taGVscCAgICAgICAgICAgZGlzcGxheSB0aGlzIGhlbHAgYW5kIGV4aXRcbiIpOwogICAgZXhpdCAoMSk7Cn0KCnN0YXRpYyBpbnQKbnN1YmRpcnMgKEZjU3RyU2V0ICpzZXQpCnsKICAgIEZjU3RyTGlzdAkqbGlzdDsKICAgIGludAkJbiA9IDA7CgogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoc2V0KTsKICAgIGlmICghbGlzdCkKCXJldHVybiAwOwogICAgd2hpbGUgKEZjU3RyTGlzdE5leHQgKGxpc3QpKQoJbisrOwogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICByZXR1cm4gbjsKfQoKc3RhdGljIGludApzY2FuRGlycyAoRmNTdHJMaXN0ICpsaXN0LCBGY0NvbmZpZyAqY29uZmlnLCBjaGFyICpwcm9ncmFtLCBGY0Jvb2wgZm9yY2UsIEZjQm9vbCB2ZXJib3NlKQp7CiAgICBpbnQJCXJldCA9IDA7CiAgICBGY0NoYXI4CSpkaXI7CiAgICBGY0ZvbnRTZXQJKnNldDsKICAgIEZjU3RyU2V0CSpzdWJkaXJzOwogICAgRmNTdHJMaXN0CSpzdWJsaXN0OwogICAgc3RydWN0IHN0YXQJc3RhdGI7CiAgICAKICAgIC8qCiAgICAgKiBOb3cgc2NhbiBhbGwgb2YgdGhlIGRpcmVjdG9yaWVzIGludG8gc2VwYXJhdGUgZGF0YWJhc2VzCiAgICAgKiBhbmQgd3JpdGUgb3V0IHRoZSByZXN1bHRzCiAgICAgKi8KICAgIHdoaWxlICgoZGlyID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQogICAgewoJaWYgKHZlcmJvc2UpCgl7CgkgICAgcHJpbnRmICgiJXM6IFwiJXNcIjogIiwgcHJvZ3JhbSwgZGlyKTsKCSAgICBmZmx1c2ggKHN0ZG91dCk7Cgl9CglzZXQgPSBGY0ZvbnRTZXRDcmVhdGUgKCk7CglpZiAoIXNldCkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBjcmVhdGUgZm9udCBzZXRcbiIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJc3ViZGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwoJaWYgKCFzdWJkaXJzKQoJewoJICAgIGZwcmludGYgKHN0ZGVyciwgIkNhbid0IGNyZWF0ZSBkaXJlY3Rvcnkgc2V0XG4iKTsKCSAgICByZXQrKzsKCSAgICBjb250aW51ZTsKCX0KCQoJaWYgKHN0YXQgKChjaGFyICopIGRpciwgJnN0YXRiKSA9PSAtMSkKCXsKCSAgICBpZiAoZXJybm8gPT0gRU5PRU5UIHx8IGVycm5vID09IEVOT1RESVIpCgkgICAgewoJCWlmICh2ZXJib3NlKQoJCSAgICBwcmludGYgKCJubyBzdWNoIGRpcmVjdG9yeSwgc2tpcHBpbmdcbiIpOwoJICAgIH0KCSAgICBlbHNlCgkgICAgewoJCWZwcmludGYgKHN0ZGVyciwgIlwiJXNcIjogIiwgZGlyKTsKCQlwZXJyb3IgKCIiKTsKCQlyZXQrKzsKCSAgICB9CgkgICAgY29udGludWU7Cgl9CglpZiAoIVNfSVNESVIgKHN0YXRiLnN0X21vZGUpKQoJewoJICAgIGZwcmludGYgKHN0ZGVyciwgIlwiJXNcIjogbm90IGEgZGlyZWN0b3J5LCBza2lwcGluZ1xuIiwgZGlyKTsKCSAgICBjb250aW51ZTsKCX0KCWlmICghRmNEaXJTY2FuIChzZXQsIHN1YmRpcnMsIDAsIEZjQ29uZmlnR2V0QmxhbmtzIChjb25maWcpLCBkaXIsIGZvcmNlKSkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJcIiVzXCI6IGVycm9yIHNjYW5uaW5nXG4iLCBkaXIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKCFmb3JjZSAmJiBGY0RpckNhY2hlVmFsaWQgKGRpcikpCgl7CgkgICAgaWYgKHZlcmJvc2UpCgkJcHJpbnRmICgic2tpcHBpbmcsICVkIGZvbnRzLCAlZCBkaXJzXG4iLAoJCQlzZXQtPm5mb250LCBuc3ViZGlycyhzdWJkaXJzKSk7Cgl9CgllbHNlCgl7CgkgICAgaWYgKHZlcmJvc2UpCgkJcHJpbnRmICgiY2FjaGluZywgJWQgZm9udHMsICVkIGRpcnNcbiIsIAoJCQlzZXQtPm5mb250LCBuc3ViZGlycyAoc3ViZGlycykpOwoJICAgIGlmICghRmNEaXJTYXZlIChzZXQsIHN1YmRpcnMsIGRpcikpCgkgICAgewoJCWZwcmludGYgKHN0ZGVyciwgIkNhbid0IHNhdmUgY2FjaGUgaW4gXCIlc1wiXG4iLCBkaXIpOwoJCXJldCsrOwoJICAgIH0KCX0KCUZjRm9udFNldERlc3Ryb3kgKHNldCk7CglzdWJsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzdWJkaXJzKTsKCWlmICghc3VibGlzdCkKCXsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJDYW4ndCBjcmVhdGUgc3ViZGlyIGxpc3QgaW4gXCIlc1wiXG4iLCBkaXIpOwoJICAgIHJldCsrOwoJICAgIGNvbnRpbnVlOwoJfQoJcmV0ICs9IHNjYW5EaXJzIChzdWJsaXN0LCBjb25maWcsIHByb2dyYW0sIGZvcmNlLCB2ZXJib3NlKTsKCUZjU3RyU2V0RGVzdHJveSAoc3ViZGlycyk7CiAgICB9CiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKICAgIHJldHVybiByZXQ7Cn0KCmludAptYWluIChpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKICAgIEZjU3RyU2V0CSpkaXJzOwogICAgRmNTdHJMaXN0CSpsaXN0OwogICAgRmNCb29sICAgIAl2ZXJib3NlID0gRmNGYWxzZTsKICAgIEZjQm9vbAlmb3JjZSA9IEZjRmFsc2U7CiAgICBGY0NvbmZpZwkqY29uZmlnOwogICAgaW50CQlpOwogICAgaW50CQlyZXQ7CiNpZiBIQVZFX0dFVE9QVF9MT05HIHx8IEhBVkVfR0VUT1BUCiAgICBpbnQJCWM7CgojaWYgSEFWRV9HRVRPUFRfTE9ORwogICAgd2hpbGUgKChjID0gZ2V0b3B0X2xvbmcgKGFyZ2MsIGFyZ3YsICJmVnY/IiwgbG9uZ29wdHMsIE5VTEwpKSAhPSAtMSkKI2Vsc2UKICAgIHdoaWxlICgoYyA9IGdldG9wdCAoYXJnYywgYXJndiwgImZWdj8iKSkgIT0gLTEpCiNlbmRpZgogICAgewoJc3dpdGNoIChjKSB7CgljYXNlICdmJzoKCSAgICBmb3JjZSA9IEZjVHJ1ZTsKCSAgICBicmVhazsKCWNhc2UgJ1YnOgoJICAgIGZwcmludGYgKHN0ZGVyciwgImZvbnRjb25maWcgdmVyc2lvbiAlZC4lZC4lZFxuIiwgCgkJICAgICBGQ19NQUpPUiwgRkNfTUlOT1IsIEZDX1JFVklTSU9OKTsKCSAgICBleGl0ICgwKTsKCWNhc2UgJ3YnOgoJICAgIHZlcmJvc2UgPSBGY1RydWU7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHVzYWdlIChhcmd2WzBdKTsKCX0KICAgIH0KICAgIGkgPSBvcHRpbmQ7CiNlbHNlCiAgICBpID0gMTsKI2VuZGlmCgogICAgY29uZmlnID0gRmNJbml0TG9hZENvbmZpZyAoKTsKICAgIGlmICghY29uZmlnKQogICAgewoJZnByaW50ZiAoc3RkZXJyLCAiJXM6IENhbid0IGluaXQgZm9udCBjb25maWcgbGlicmFyeVxuIiwgYXJndlswXSk7CglyZXR1cm4gMTsKICAgIH0KICAgIGlmIChhcmd2W2ldKQogICAgewoJZGlycyA9IEZjU3RyU2V0Q3JlYXRlICgpOwoJaWYgKCFkaXJzKQoJewoJICAgIGZwcmludGYgKHN0ZGVyciwgIiVzOiBDYW4ndCBjcmVhdGUgbGlzdCBvZiBkaXJlY3Rvcmllc1xuIiwKCQkgICAgIGFyZ3ZbMF0pOwoJICAgIHJldHVybiAxOwoJfQoJd2hpbGUgKGFyZ3ZbaV0pCgl7CgkgICAgaWYgKCFGY1N0clNldEFkZCAoZGlycywgKEZjQ2hhcjggKikgYXJndltpXSkpCgkgICAgewoJCWZwcmludGYgKHN0ZGVyciwgIiVzOiBDYW4ndCBhZGQgZGlyZWN0b3J5XG4iLCBhcmd2WzBdKTsKCQlyZXR1cm4gMTsKCSAgICB9CgkgICAgaSsrOwoJfQoJbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZGlycyk7CglGY1N0clNldERlc3Ryb3kgKGRpcnMpOwogICAgfQogICAgZWxzZQoJbGlzdCA9IEZjQ29uZmlnR2V0Q29uZmlnRGlycyAoY29uZmlnKTsKICAgIHJldCA9IHNjYW5EaXJzIChsaXN0LCBjb25maWcsIGFyZ3ZbMF0sIGZvcmNlLCB2ZXJib3NlKTsKICAgIGlmICh2ZXJib3NlKQoJcHJpbnRmICgiJXM6ICVzXG4iLCBhcmd2WzBdLCByZXQgPyAiZmFpbGVkIiA6ICJzdWNjZWVkZWQiKTsKICAgIHJldHVybiByZXQ7Cn0K