LyoKICogJFhGcmVlODY6ICQKICoKICogQ29weXJpZ2h0IKkgMjAwMSBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgImZjaW50LmgiCiNpbmNsdWRlIDxsb2NhbGUuaD4KCnN0YXRpYyBzdHJ1Y3QgewogICAgY2hhcgkqZmllbGQ7CiAgICBGY0Jvb2wJdmFsdWU7Cn0gRmNCb29sRGVmYXVsdHNbXSA9IHsKICAgIHsgRkNfSElOVElORywJICAgIEZjVHJ1ZQl9LCAgLyogIUZUX0xPQURfTk9fSElOVElORyAqLwogICAgeyBGQ19WRVJUSUNBTF9MQVlPVVQsICAgRmNGYWxzZQl9LCAgLyogRkNfTE9BRF9WRVJUSUNBTF9MQVlPVVQgKi8KICAgIHsgRkNfQVVUT0hJTlQsCSAgICBGY0ZhbHNlCX0sICAvKiBGQ19MT0FEX0ZPUkNFX0FVVE9ISU5UICovCiAgICB7IEZDX0dMT0JBTF9BRFZBTkNFLCAgICBGY1RydWUJfSwgIC8qICFGQ19MT0FEX0lHTk9SRV9HTE9CQUxfQURWQU5DRV9XSURUSCAqLwp9OwoKI2RlZmluZSBOVU1fRkNfQk9PTF9ERUZBVUxUUwkoc2l6ZW9mIEZjQm9vbERlZmF1bHRzIC8gc2l6ZW9mIEZjQm9vbERlZmF1bHRzWzBdKQoKdm9pZApGY0RlZmF1bHRTdWJzdGl0dXRlIChGY1BhdHRlcm4gKnBhdHRlcm4pCnsKICAgIEZjVmFsdWUgdjsKICAgIGludAkgICAgaTsKCiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19TVFlMRSwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKICAgIHsKCWlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX1dFSUdIVCwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCApCgl7CgkgICAgRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0dGVybiwgRkNfV0VJR0hULCBGQ19XRUlHSFRfTUVESVVNKTsKCX0KCWlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX1NMQU5ULCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQoJewoJICAgIEZjUGF0dGVybkFkZEludGVnZXIgKHBhdHRlcm4sIEZDX1NMQU5ULCBGQ19TTEFOVF9ST01BTik7Cgl9CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IE5VTV9GQ19CT09MX0RFRkFVTFRTOyBpKyspCglpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGY0Jvb2xEZWZhdWx0c1tpXS5maWVsZCwgMCwgJnYpID09IEZjUmVzdWx0Tm9NYXRjaCkKCSAgICBGY1BhdHRlcm5BZGRCb29sIChwYXR0ZXJuLCBGY0Jvb2xEZWZhdWx0c1tpXS5maWVsZCwgRmNCb29sRGVmYXVsdHNbaV0udmFsdWUpOwogICAgCiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19QSVhFTF9TSVpFLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQogICAgewoJZG91YmxlCWRwaSwgc2l6ZSwgc2NhbGU7CgoJaWYgKEZjUGF0dGVybkdldERvdWJsZSAocGF0dGVybiwgRkNfU0laRSwgMCwgJnNpemUpICE9IEZjUmVzdWx0TWF0Y2gpCgl7CgkgICAgc2l6ZSA9IDEyLjA7CgkgICAgKHZvaWQpIEZjUGF0dGVybkRlbCAocGF0dGVybiwgRkNfU0laRSk7CgkgICAgRmNQYXR0ZXJuQWRkRG91YmxlIChwYXR0ZXJuLCBGQ19TSVpFLCBzaXplKTsKCX0KCWlmIChGY1BhdHRlcm5HZXREb3VibGUgKHBhdHRlcm4sIEZDX1NDQUxFLCAwLCAmc2NhbGUpICE9IEZjUmVzdWx0TWF0Y2gpCgl7CgkgICAgc2NhbGUgPSAxLjA7CgkgICAgKHZvaWQpIEZjUGF0dGVybkRlbCAocGF0dGVybiwgRkNfU0NBTEUpOwoJICAgIEZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfU0NBTEUsIHNjYWxlKTsKCX0KCXNpemUgKj0gc2NhbGU7CglpZiAoRmNQYXR0ZXJuR2V0RG91YmxlIChwYXR0ZXJuLCBGQ19EUEksIDAsICZkcGkpICE9IEZjUmVzdWx0TWF0Y2gpCgl7CgkgICAgZHBpID0gNzUuMDsKCSAgICAodm9pZCkgRmNQYXR0ZXJuRGVsIChwYXR0ZXJuLCBGQ19EUEkpOwoJICAgIEZjUGF0dGVybkFkZERvdWJsZSAocGF0dGVybiwgRkNfRFBJLCBkcGkpOwoJfQoJc2l6ZSAqPSBkcGkgLyA3Mi4wOwoJRmNQYXR0ZXJuQWRkRG91YmxlIChwYXR0ZXJuLCBGQ19QSVhFTF9TSVpFLCBzaXplKTsKICAgIH0KCiAgICBpZiAoRmNQYXR0ZXJuR2V0IChwYXR0ZXJuLCBGQ19MQU5HLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQogICAgewoJY2hhcgkqbGFuZzsKCWNoYXIJKnRlcnJpdG9yeTsKCWNoYXIJKmFmdGVyOwoJaW50CWxhbmdfbGVuLCB0ZXJyaXRvcnlfbGVuOwoJY2hhcglsYW5nX2xvY2FsWzEyOF07CgljaGFyCSpjdHlwZSA9IHNldGxvY2FsZSAoTENfQ1RZUEUsIE5VTEwpOwoKCS8qCgkgKiBDaGVjayBpZiBzZXRsb2NhbGUgKExDX0FMTCwgIiIpIGhhcyBiZWVuIGNhbGxlZAoJICovCglpZiAoIWN0eXBlIHx8ICFzdHJjbXAgKGN0eXBlLCAiQyIpKQoJewoJICAgIGN0eXBlID0gZ2V0ZW52ICgiTENfQUxMIik7CgkgICAgaWYgKCFjdHlwZSkKCSAgICB7CgkJY3R5cGUgPSBnZXRlbnYgKCJMQ19DVFlQRSIpOwoJCWlmICghY3R5cGUpCgkJICAgIGN0eXBlID0gZ2V0ZW52ICgiTEFORyIpOwoJICAgIH0KCX0KCWlmIChjdHlwZSkKCXsKCSAgICBsYW5nID0gY3R5cGU7CgkgICAgdGVycml0b3J5ID0gc3RyY2hyIChjdHlwZSwgJ18nKTsKCSAgICBpZiAodGVycml0b3J5KQoJICAgIHsKCQlsYW5nX2xlbiA9IHRlcnJpdG9yeSAtIGxhbmc7CgkJdGVycml0b3J5ID0gdGVycml0b3J5ICsgMTsKCQlhZnRlciA9IHN0cmNociAodGVycml0b3J5LCAnLicpOwoJCWlmICghYWZ0ZXIpCgkJewoJCSAgICBhZnRlciA9IHN0cmNociAodGVycml0b3J5LCAnQCcpOwoJCSAgICBpZiAoIWFmdGVyKQoJCQlhZnRlciA9IHRlcnJpdG9yeSArIHN0cmxlbiAodGVycml0b3J5KTsKCQl9CgkJdGVycml0b3J5X2xlbiA9IGFmdGVyIC0gdGVycml0b3J5OwoJCWlmIChsYW5nX2xlbiArIDEgKyB0ZXJyaXRvcnlfbGVuICsgMSA8PSBzaXplb2YgKGxhbmdfbG9jYWwpKQoJCXsKCQkgICAgc3RybmNweSAobGFuZ19sb2NhbCwgbGFuZywgbGFuZ19sZW4pOwoJCSAgICBsYW5nX2xvY2FsW2xhbmdfbGVuXSA9ICctJzsKCQkgICAgc3RybmNweSAobGFuZ19sb2NhbCArIGxhbmdfbGVuICsgMSwgdGVycml0b3J5LCB0ZXJyaXRvcnlfbGVuKTsKCQkgICAgbGFuZ19sb2NhbFtsYW5nX2xlbiArIDEgKyB0ZXJyaXRvcnlfbGVuXSA9ICdcMCc7CgkJICAgIEZjUGF0dGVybkFkZFN0cmluZyAocGF0dGVybiwgRkNfTEFORywgKEZjQ2hhcjggKikgbGFuZ19sb2NhbCk7CgkJfQoJICAgIH0KCSAgICBlbHNlCgkJRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXR0ZXJuLCBGQ19MQU5HLCAoRmNDaGFyOCAqKSBsYW5nKTsKCX0KICAgIH0KfQo=