LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2RlZmF1bHQuYyx2IDEuMiAyMDAyLzA3LzA5IDIyOjA4OjE0IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAxIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKI2luY2x1ZGUgPGxvY2FsZS5oPgoKc3RhdGljIHN0cnVjdCB7CiAgICBjaGFyCSpmaWVsZDsKICAgIEZjQm9vbAl2YWx1ZTsKfSBGY0Jvb2xEZWZhdWx0c1tdID0gewogICAgeyBGQ19ISU5USU5HLAkgICAgRmNUcnVlCX0sICAvKiAhRlRfTE9BRF9OT19ISU5USU5HICovCiAgICB7IEZDX1ZFUlRJQ0FMX0xBWU9VVCwgICBGY0ZhbHNlCX0sICAvKiBGQ19MT0FEX1ZFUlRJQ0FMX0xBWU9VVCAqLwogICAgeyBGQ19BVVRPSElOVCwJICAgIEZjRmFsc2UJfSwgIC8qIEZDX0xPQURfRk9SQ0VfQVVUT0hJTlQgKi8KICAgIHsgRkNfR0xPQkFMX0FEVkFOQ0UsICAgIEZjVHJ1ZQl9LCAgLyogIUZDX0xPQURfSUdOT1JFX0dMT0JBTF9BRFZBTkNFX1dJRFRIICovCn07CgojZGVmaW5lIE5VTV9GQ19CT09MX0RFRkFVTFRTCShzaXplb2YgRmNCb29sRGVmYXVsdHMgLyBzaXplb2YgRmNCb29sRGVmYXVsdHNbMF0pCgp2b2lkCkZjRGVmYXVsdFN1YnN0aXR1dGUgKEZjUGF0dGVybiAqcGF0dGVybikKewogICAgRmNWYWx1ZSB2OwogICAgaW50CSAgICBpOwoKICAgIGlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX1NUWUxFLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQogICAgewoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfV0VJR0hULCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoICkKCXsKCSAgICBGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXR0ZXJuLCBGQ19XRUlHSFQsIEZDX1dFSUdIVF9NRURJVU0pOwoJfQoJaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfU0xBTlQsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCgl7CgkgICAgRmNQYXR0ZXJuQWRkSW50ZWdlciAocGF0dGVybiwgRkNfU0xBTlQsIEZDX1NMQU5UX1JPTUFOKTsKCX0KICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0ZDX0JPT0xfREVGQVVMVFM7IGkrKykKCWlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZjQm9vbERlZmF1bHRzW2ldLmZpZWxkLCAwLCAmdikgPT0gRmNSZXN1bHROb01hdGNoKQoJICAgIEZjUGF0dGVybkFkZEJvb2wgKHBhdHRlcm4sIEZjQm9vbERlZmF1bHRzW2ldLmZpZWxkLCBGY0Jvb2xEZWZhdWx0c1tpXS52YWx1ZSk7CiAgICAKICAgIGlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX1BJWEVMX1NJWkUsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCiAgICB7Cglkb3VibGUJZHBpLCBzaXplLCBzY2FsZTsKCglpZiAoRmNQYXR0ZXJuR2V0RG91YmxlIChwYXR0ZXJuLCBGQ19TSVpFLCAwLCAmc2l6ZSkgIT0gRmNSZXN1bHRNYXRjaCkKCXsKCSAgICBzaXplID0gMTIuMDsKCSAgICAodm9pZCkgRmNQYXR0ZXJuRGVsIChwYXR0ZXJuLCBGQ19TSVpFKTsKCSAgICBGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX1NJWkUsIHNpemUpOwoJfQoJaWYgKEZjUGF0dGVybkdldERvdWJsZSAocGF0dGVybiwgRkNfU0NBTEUsIDAsICZzY2FsZSkgIT0gRmNSZXN1bHRNYXRjaCkKCXsKCSAgICBzY2FsZSA9IDEuMDsKCSAgICAodm9pZCkgRmNQYXR0ZXJuRGVsIChwYXR0ZXJuLCBGQ19TQ0FMRSk7CgkgICAgRmNQYXR0ZXJuQWRkRG91YmxlIChwYXR0ZXJuLCBGQ19TQ0FMRSwgc2NhbGUpOwoJfQoJc2l6ZSAqPSBzY2FsZTsKCWlmIChGY1BhdHRlcm5HZXREb3VibGUgKHBhdHRlcm4sIEZDX0RQSSwgMCwgJmRwaSkgIT0gRmNSZXN1bHRNYXRjaCkKCXsKCSAgICBkcGkgPSA3NS4wOwoJICAgICh2b2lkKSBGY1BhdHRlcm5EZWwgKHBhdHRlcm4sIEZDX0RQSSk7CgkgICAgRmNQYXR0ZXJuQWRkRG91YmxlIChwYXR0ZXJuLCBGQ19EUEksIGRwaSk7Cgl9CglzaXplICo9IGRwaSAvIDcyLjA7CglGY1BhdHRlcm5BZGREb3VibGUgKHBhdHRlcm4sIEZDX1BJWEVMX1NJWkUsIHNpemUpOwogICAgfQoKICAgIGlmIChGY1BhdHRlcm5HZXQgKHBhdHRlcm4sIEZDX0xBTkcsIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCiAgICB7CgljaGFyCSpsYW5nOwoJY2hhcgkqdGVycml0b3J5OwoJY2hhcgkqYWZ0ZXI7CglpbnQJbGFuZ19sZW4sIHRlcnJpdG9yeV9sZW47CgljaGFyCWxhbmdfbG9jYWxbMTI4XTsKCWNoYXIJKmN0eXBlID0gc2V0bG9jYWxlIChMQ19DVFlQRSwgTlVMTCk7CgoJLyoKCSAqIENoZWNrIGlmIHNldGxvY2FsZSAoTENfQUxMLCAiIikgaGFzIGJlZW4gY2FsbGVkCgkgKi8KCWlmICghY3R5cGUgfHwgIXN0cmNtcCAoY3R5cGUsICJDIikpCgl7CgkgICAgY3R5cGUgPSBnZXRlbnYgKCJMQ19BTEwiKTsKCSAgICBpZiAoIWN0eXBlKQoJICAgIHsKCQljdHlwZSA9IGdldGVudiAoIkxDX0NUWVBFIik7CgkJaWYgKCFjdHlwZSkKCQkgICAgY3R5cGUgPSBnZXRlbnYgKCJMQU5HIik7CgkgICAgfQoJfQoJaWYgKGN0eXBlKQoJewoJICAgIGxhbmcgPSBjdHlwZTsKCSAgICB0ZXJyaXRvcnkgPSBzdHJjaHIgKGN0eXBlLCAnXycpOwoJICAgIGlmICh0ZXJyaXRvcnkpCgkgICAgewoJCWxhbmdfbGVuID0gdGVycml0b3J5IC0gbGFuZzsKCQl0ZXJyaXRvcnkgPSB0ZXJyaXRvcnkgKyAxOwoJCWFmdGVyID0gc3RyY2hyICh0ZXJyaXRvcnksICcuJyk7CgkJaWYgKCFhZnRlcikKCQl7CgkJICAgIGFmdGVyID0gc3RyY2hyICh0ZXJyaXRvcnksICdAJyk7CgkJICAgIGlmICghYWZ0ZXIpCgkJCWFmdGVyID0gdGVycml0b3J5ICsgc3RybGVuICh0ZXJyaXRvcnkpOwoJCX0KCQl0ZXJyaXRvcnlfbGVuID0gYWZ0ZXIgLSB0ZXJyaXRvcnk7CgkJaWYgKGxhbmdfbGVuICsgMSArIHRlcnJpdG9yeV9sZW4gKyAxIDw9IHNpemVvZiAobGFuZ19sb2NhbCkpCgkJewoJCSAgICBzdHJuY3B5IChsYW5nX2xvY2FsLCBsYW5nLCBsYW5nX2xlbik7CgkJICAgIGxhbmdfbG9jYWxbbGFuZ19sZW5dID0gJy0nOwoJCSAgICBzdHJuY3B5IChsYW5nX2xvY2FsICsgbGFuZ19sZW4gKyAxLCB0ZXJyaXRvcnksIHRlcnJpdG9yeV9sZW4pOwoJCSAgICBsYW5nX2xvY2FsW2xhbmdfbGVuICsgMSArIHRlcnJpdG9yeV9sZW5dID0gJ1wwJzsKCQkgICAgRmNQYXR0ZXJuQWRkU3RyaW5nIChwYXR0ZXJuLCBGQ19MQU5HLCAoRmNDaGFyOCAqKSBsYW5nX2xvY2FsKTsKCQl9CgkgICAgfQoJICAgIGVsc2UKCQlGY1BhdHRlcm5BZGRTdHJpbmcgKHBhdHRlcm4sIEZDX0xBTkcsIChGY0NoYXI4ICopIGxhbmcpOwoJfQogICAgfQogICAgaWYgKEZjUGF0dGVybkdldCAocGF0dGVybiwgRkNfRk9OVFZFUlNJT04sIDAsICZ2KSA9PSBGY1Jlc3VsdE5vTWF0Y2gpCiAgICB7CglGY1BhdHRlcm5BZGRJbnRlZ2VyIChwYXR0ZXJuLCBGQ19GT05UVkVSU0lPTiwgMHg3ZmZmZmZmZik7CiAgICB9Cn0K