LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY3BhdC5jLHYgMS4xOCAyMDAyLzA5LzE4IDE3OjExOjQ2IHRzaSBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSAiZmNpbnQuaCIKCkZjUGF0dGVybiAqCkZjUGF0dGVybkNyZWF0ZSAodm9pZCkKewogICAgRmNQYXR0ZXJuCSpwOwoKICAgIHAgPSAoRmNQYXR0ZXJuICopIG1hbGxvYyAoc2l6ZW9mIChGY1BhdHRlcm4pKTsKICAgIGlmICghcCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1BBVFRFUk4sIHNpemVvZiAoRmNQYXR0ZXJuKSk7CiAgICBwLT5udW0gPSAwOwogICAgcC0+c2l6ZSA9IDA7CiAgICBwLT5lbHRzID0gMDsKICAgIHAtPnJlZiA9IDE7CiAgICByZXR1cm4gcDsKfQoKdm9pZApGY1ZhbHVlRGVzdHJveSAoRmNWYWx1ZSB2KQp7CiAgICBzd2l0Y2ggKHYudHlwZSkgewogICAgY2FzZSBGY1R5cGVTdHJpbmc6CglGY1N0ckZyZWUgKChGY0NoYXI4ICopIHYudS5zKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglGY01hdHJpeEZyZWUgKChGY01hdHJpeCAqKSB2LnUubSk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCUZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgdi51LmMpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUxhbmdTZXQ6CglGY0xhbmdTZXREZXN0cm95ICgoRmNMYW5nU2V0ICopIHYudS5sKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQp9CgpGY1ZhbHVlCkZjVmFsdWVTYXZlIChGY1ZhbHVlIHYpCnsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCXYudS5zID0gRmNTdHJDb3B5ICh2LnUucyk7CglpZiAoIXYudS5zKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJdi51Lm0gPSBGY01hdHJpeENvcHkgKHYudS5tKTsKCWlmICghdi51Lm0pCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVDaGFyU2V0OgoJdi51LmMgPSBGY0NoYXJTZXRDb3B5ICgoRmNDaGFyU2V0ICopIHYudS5jKTsKCWlmICghdi51LmMpCgkgICAgdi50eXBlID0gRmNUeXBlVm9pZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJdi51LmwgPSBGY0xhbmdTZXRDb3B5ICh2LnUubCk7CglpZiAoIXYudS5sKQoJICAgIHYudHlwZSA9IEZjVHlwZVZvaWQ7CglicmVhazsKICAgIGRlZmF1bHQ6CglicmVhazsKICAgIH0KICAgIHJldHVybiB2Owp9Cgp2b2lkCkZjVmFsdWVMaXN0RGVzdHJveSAoRmNWYWx1ZUxpc3QgKmwpCnsKICAgIEZjVmFsdWVMaXN0ICAgICpuZXh0OwogICAgZm9yICg7IGw7IGwgPSBuZXh0KQogICAgewoJc3dpdGNoIChsLT52YWx1ZS50eXBlKSB7CgljYXNlIEZjVHlwZVN0cmluZzoKCSAgICBGY1N0ckZyZWUgKChGY0NoYXI4ICopIGwtPnZhbHVlLnUucyk7CgkgICAgYnJlYWs7CgljYXNlIEZjVHlwZU1hdHJpeDoKCSAgICBGY01hdHJpeEZyZWUgKChGY01hdHJpeCAqKSBsLT52YWx1ZS51Lm0pOwoJICAgIGJyZWFrOwoJY2FzZSBGY1R5cGVDaGFyU2V0OgoJICAgIEZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgbC0+dmFsdWUudS5jKTsKCSAgICBicmVhazsKCWNhc2UgRmNUeXBlTGFuZ1NldDoKCSAgICBGY0xhbmdTZXREZXN0cm95ICgoRmNMYW5nU2V0ICopIGwtPnZhbHVlLnUubCk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIGJyZWFrOwoJfQoJbmV4dCA9IGwtPm5leHQ7CglGY01lbUZyZWUgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CglmcmVlIChsKTsKICAgIH0KfQoKRmNCb29sCkZjVmFsdWVFcXVhbCAoRmNWYWx1ZSB2YSwgRmNWYWx1ZSB2YikKewogICAgaWYgKHZhLnR5cGUgIT0gdmIudHlwZSkKICAgIHsKCWlmICh2YS50eXBlID09IEZjVHlwZUludGVnZXIpCgl7CgkgICAgdmEudHlwZSA9IEZjVHlwZURvdWJsZTsKCSAgICB2YS51LmQgPSB2YS51Lmk7Cgl9CglpZiAodmIudHlwZSA9PSBGY1R5cGVJbnRlZ2VyKQoJewoJICAgIHZiLnR5cGUgPSBGY1R5cGVEb3VibGU7CgkgICAgdmIudS5kID0gdmIudS5pOwoJfQoJaWYgKHZhLnR5cGUgIT0gdmIudHlwZSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN3aXRjaCAodmEudHlwZSkgewogICAgY2FzZSBGY1R5cGVWb2lkOgoJcmV0dXJuIEZjVHJ1ZTsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCXJldHVybiB2YS51LmkgPT0gdmIudS5pOwogICAgY2FzZSBGY1R5cGVEb3VibGU6CglyZXR1cm4gdmEudS5kID09IHZiLnUuZDsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjU3RyQ21wSWdub3JlQ2FzZSAodmEudS5zLCB2Yi51LnMpID09IDA7CiAgICBjYXNlIEZjVHlwZUJvb2w6CglyZXR1cm4gdmEudS5iID09IHZiLnUuYjsKICAgIGNhc2UgRmNUeXBlTWF0cml4OgoJcmV0dXJuIEZjTWF0cml4RXF1YWwgKHZhLnUubSwgdmIudS5tKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiBGY0NoYXJTZXRFcXVhbCAodmEudS5jLCB2Yi51LmMpOwogICAgY2FzZSBGY1R5cGVGVEZhY2U6CglyZXR1cm4gdmEudS5mID09IHZiLnUuZjsKICAgIGNhc2UgRmNUeXBlTGFuZ1NldDoKCXJldHVybiBGY0xhbmdTZXRFcXVhbCAodmEudS5sLCB2Yi51LmwpOwogICAgfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0RvdWJsZUhhc2ggKGRvdWJsZSBkKQp7CiAgICBpZiAoZCA8IDApCglkID0gLWQ7CiAgICBpZiAoZCA+IDB4ZmZmZmZmZmYpCglkID0gMHhmZmZmZmZmZjsKICAgIHJldHVybiAoRmNDaGFyMzIpIGQ7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY1N0cmluZ0hhc2ggKGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjgJYzsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgCiAgICBpZiAocykKCXdoaWxlICgoYyA9ICpzKyspKQoJICAgIGggPSAoKGggPDwgMSkgfCAoaCA+PiAzMSkpIF4gYzsKICAgIHJldHVybiBoOwp9CgpzdGF0aWMgRmNDaGFyMzIKRmNWYWx1ZUhhc2ggKEZjVmFsdWUgdikKewogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlVm9pZDoKCXJldHVybiAwOwogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJcmV0dXJuIChGY0NoYXIzMikgdi51Lmk7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCXJldHVybiBGY0RvdWJsZUhhc2ggKHYudS5kKTsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJcmV0dXJuIEZjU3RyaW5nSGFzaCAodi51LnMpOwogICAgY2FzZSBGY1R5cGVCb29sOgoJcmV0dXJuIChGY0NoYXIzMikgdi51LmI7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCXJldHVybiAoRmNEb3VibGVIYXNoICh2LnUubS0+eHgpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eHkpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eXgpIF4gCgkJRmNEb3VibGVIYXNoICh2LnUubS0+eXkpKTsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCXJldHVybiAoRmNDaGFyMzIpIHYudS5jLT5udW07CiAgICBjYXNlIEZjVHlwZUZURmFjZToKCXJldHVybiBGY1N0cmluZ0hhc2ggKChjb25zdCBGY0NoYXI4ICopICgoRlRfRmFjZSkgdi51LmYpLT5mYW1pbHlfbmFtZSkgXgoJICAgICAgIEZjU3RyaW5nSGFzaCAoKGNvbnN0IEZjQ2hhcjggKikgKChGVF9GYWNlKSB2LnUuZiktPnN0eWxlX25hbWUpOwogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJcmV0dXJuIEZjTGFuZ1NldEhhc2ggKHYudS5sKTsKICAgIH0KICAgIHJldHVybiBGY0ZhbHNlOwp9CgpzdGF0aWMgRmNCb29sCkZjVmFsdWVMaXN0RXF1YWwgKEZjVmFsdWVMaXN0ICpsYSwgRmNWYWx1ZUxpc3QgKmxiKQp7CiAgICBpZiAobGEgPT0gbGIpCglyZXR1cm4gRmNUcnVlOwoKICAgIHdoaWxlIChsYSAmJiBsYikKICAgIHsKCWlmICghRmNWYWx1ZUVxdWFsIChsYS0+dmFsdWUsIGxiLT52YWx1ZSkpCgkgICAgcmV0dXJuIEZjRmFsc2U7CglsYSA9IGxhLT5uZXh0OwoJbGIgPSBsYi0+bmV4dDsKICAgIH0KICAgIGlmIChsYSB8fCBsYikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjVmFsdWVMaXN0SGFzaCAoRmNWYWx1ZUxpc3QgKmwpCnsKICAgIEZjQ2hhcjMyCWhhc2ggPSAwOwogICAgCiAgICB3aGlsZSAobCkKICAgIHsKCWhhc2ggPSAoKGhhc2ggPDwgMSkgfCAoaGFzaCA+PiAzMSkpIF4gRmNWYWx1ZUhhc2ggKGwtPnZhbHVlKTsKCWwgPSBsLT5uZXh0OwogICAgfQogICAgcmV0dXJuIGhhc2g7Cn0KCnZvaWQKRmNQYXR0ZXJuRGVzdHJveSAoRmNQYXR0ZXJuICpwKQp7CiAgICBpbnQJCSAgICBpOwogICAgCiAgICBpZiAocC0+cmVmID09IEZDX1JFRl9DT05TVEFOVCB8fCAtLXAtPnJlZiA+IDApCglyZXR1cm47CgogICAgZm9yIChpID0gMDsgaSA8IHAtPm51bTsgaSsrKQoJRmNWYWx1ZUxpc3REZXN0cm95IChwLT5lbHRzW2ldLnZhbHVlcyk7CgogICAgcC0+bnVtID0gMDsKICAgIGlmIChwLT5lbHRzKQogICAgewoJRmNNZW1GcmVlIChGQ19NRU1fUEFURUxULCBwLT5zaXplICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCWZyZWUgKHAtPmVsdHMpOwoJcC0+ZWx0cyA9IDA7CiAgICB9CiAgICBwLT5zaXplID0gMDsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1BBVFRFUk4sIHNpemVvZiAoRmNQYXR0ZXJuKSk7CiAgICBmcmVlIChwKTsKfQoKI2RlZmluZSBGQ19WQUxVRV9MSVNUX0hBU0hfU0laRQkgICAgMjU3CiNkZWZpbmUgRkNfUEFUVEVSTl9IQVNIX1NJWkUJICAgIDY3Cgp0eXBlZGVmIHN0cnVjdCBfRmNWYWx1ZUxpc3RFbnQgRmNWYWx1ZUxpc3RFbnQ7CgpzdHJ1Y3QgX0ZjVmFsdWVMaXN0RW50IHsKICAgIEZjVmFsdWVMaXN0RW50ICAqbmV4dDsKICAgIEZjVmFsdWVMaXN0CSAgICAqbGlzdDsKICAgIEZjQ2hhcjMyCSAgICBoYXNoLCBwYWQ7Cn07Cgp0eXBlZGVmIHVuaW9uIF9GY1ZhbHVlTGlzdEFsaWduIHsKICAgIEZjVmFsdWVMaXN0RW50ICBlbnQ7CiAgICBGY1ZhbHVlTGlzdAkgICAgbGlzdDsKfSBGY1ZhbHVlTGlzdEFsaWduOwoKc3RhdGljIGludAkgICAgRmNWYWx1ZUxpc3RGcm96ZW5Db3VudFtGY1R5cGVMYW5nU2V0ICsgMV07CnN0YXRpYyBpbnQJICAgIEZjVmFsdWVMaXN0RnJvemVuQnl0ZXNbRmNUeXBlTGFuZ1NldCArIDFdOwpzdGF0aWMgY2hhcgkgICAgKkZjVmFsdWVMaXN0RnJvemVuTmFtZVtdID0gewogICAgIlZvaWQiLCAKICAgICJJbnRlZ2VyIiwgCiAgICAiRG91YmxlIiwgCiAgICAiU3RyaW5nIiwgCiAgICAiQm9vbCIsCiAgICAiTWF0cml4IiwKICAgICJDaGFyU2V0IiwKICAgICJGVEZhY2UiLAogICAgIkxhbmdTZXQiCn07Cgp2b2lkCkZjVmFsdWVMaXN0UmVwb3J0ICh2b2lkKTsKICAgIAp2b2lkCkZjVmFsdWVMaXN0UmVwb3J0ICh2b2lkKQp7CiAgICBGY1R5cGUgIHQ7CgogICAgcHJpbnRmICgiRmMgRnJvemVuIFZhbHVlczpcbiIpOwogICAgcHJpbnRmICgiXHQlOHMgJTlzICU5c1xuIiwgIlR5cGUiLCAiQ291bnQiLCAiQnl0ZXMiKTsKICAgIGZvciAodCA9IEZjVHlwZVZvaWQ7IHQgPD0gRmNUeXBlTGFuZ1NldDsgdCsrKQoJcHJpbnRmICgiXHQlOHMgJTlkICU5ZFxuIiwgRmNWYWx1ZUxpc3RGcm96ZW5OYW1lW3RdLAoJCUZjVmFsdWVMaXN0RnJvemVuQ291bnRbdF0sIEZjVmFsdWVMaXN0RnJvemVuQnl0ZXNbdF0pOwp9CgpzdGF0aWMgRmNWYWx1ZUxpc3RFbnQgKgpGY1ZhbHVlTGlzdEVudENyZWF0ZSAoRmNWYWx1ZUxpc3QgKmgpCnsKICAgIEZjVmFsdWVMaXN0QWxpZ24JKmVhOwogICAgRmNWYWx1ZUxpc3RFbnQgICplOwogICAgRmNWYWx1ZUxpc3QJICAgICpsLCAqbmV3OwogICAgaW50CQkgICAgbjsKICAgIGludAkJICAgIHN0cmluZ19zaXplID0gMDsKICAgIEZjQ2hhcjgJICAgICpzdHJzOwogICAgaW50CQkgICAgc2l6ZTsKCiAgICBuID0gMDsKICAgIGZvciAobCA9IGg7IGw7IGwgPSBsLT5uZXh0KQogICAgewoJaWYgKGwtPnZhbHVlLnR5cGUgPT0gRmNUeXBlU3RyaW5nKQoJICAgIHN0cmluZ19zaXplICs9IHN0cmxlbiAoKGNoYXIgKikgbC0+dmFsdWUudS5zKSArIDE7CgluKys7CiAgICB9CiAgICBzaXplID0gc2l6ZW9mIChGY1ZhbHVlTGlzdEFsaWduKSArIG4gKiBzaXplb2YgKEZjVmFsdWVMaXN0KSArIHN0cmluZ19zaXplOwogICAgRmNWYWx1ZUxpc3RGcm96ZW5Db3VudFtoLT52YWx1ZS50eXBlXSsrOwogICAgRmNWYWx1ZUxpc3RGcm96ZW5CeXRlc1toLT52YWx1ZS50eXBlXSArPSBzaXplOwogICAgZWEgPSBtYWxsb2MgKHNpemUpOwogICAgaWYgKCFlYSkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemUpOwogICAgZSA9ICZlYS0+ZW50OwogICAgZS0+bGlzdCA9IChGY1ZhbHVlTGlzdCAqKSAoZWEgKyAxKTsKICAgIHN0cnMgPSAoRmNDaGFyOCAqKSAoZS0+bGlzdCArIG4pOwogICAgbmV3ID0gZS0+bGlzdDsKICAgIGZvciAobCA9IGg7IGw7IGwgPSBsLT5uZXh0LCBuZXcrKykKICAgIHsKCWlmIChsLT52YWx1ZS50eXBlID09IEZjVHlwZVN0cmluZykKCXsKCSAgICBuZXctPnZhbHVlLnR5cGUgPSBGY1R5cGVTdHJpbmc7CgkgICAgbmV3LT52YWx1ZS51LnMgPSBzdHJzOwoJICAgIHN0cmNweSAoKGNoYXIgKikgc3RycywgKGNoYXIgKikgbC0+dmFsdWUudS5zKTsKCSAgICBzdHJzICs9IHN0cmxlbiAoKGNoYXIgKikgc3RycykgKyAxOwoJfQoJZWxzZQoJewoJICAgIG5ldy0+dmFsdWUgPSBsLT52YWx1ZTsKCSAgICBuZXctPnZhbHVlID0gRmNWYWx1ZVNhdmUgKG5ldy0+dmFsdWUpOwoJfQoJbmV3LT5iaW5kaW5nID0gbC0+YmluZGluZzsKCWlmIChsLT5uZXh0KQoJICAgIG5ldy0+bmV4dCA9IG5ldyArIDE7CgllbHNlCgkgICAgbmV3LT5uZXh0ID0gMDsKICAgIH0KICAgIHJldHVybiBlOwp9CgpzdGF0aWMgaW50CUZjVmFsdWVMaXN0VG90YWw7CnN0YXRpYyBpbnQJRmNWYWx1ZUxpc3RVc2VkOwoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNWYWx1ZUxpc3RGcmVlemUgKEZjVmFsdWVMaXN0ICpsKQp7CiAgICBzdGF0aWMgRmNWYWx1ZUxpc3RFbnQgICAqaGFzaFRhYmxlW0ZDX1ZBTFVFX0xJU1RfSEFTSF9TSVpFXTsKICAgIEZjQ2hhcjMyCQkgICAgaGFzaCA9IEZjVmFsdWVMaXN0SGFzaCAobCk7CiAgICBGY1ZhbHVlTGlzdEVudAkgICAgKipidWNrZXQgPSAmaGFzaFRhYmxlW2hhc2ggJSBGQ19WQUxVRV9MSVNUX0hBU0hfU0laRV07CiAgICBGY1ZhbHVlTGlzdEVudAkgICAgKmVudDsKCiAgICBGY1ZhbHVlTGlzdFRvdGFsKys7CiAgICBmb3IgKGVudCA9ICpidWNrZXQ7IGVudDsgZW50ID0gZW50LT5uZXh0KQogICAgewoJaWYgKGVudC0+aGFzaCA9PSBoYXNoICYmIEZjVmFsdWVMaXN0RXF1YWwgKGVudC0+bGlzdCwgbCkpCgkgICAgcmV0dXJuIGVudC0+bGlzdDsKICAgIH0KCiAgICBlbnQgPSBGY1ZhbHVlTGlzdEVudENyZWF0ZSAobCk7CiAgICBpZiAoIWVudCkKCXJldHVybiAwOwoKICAgIEZjVmFsdWVMaXN0VXNlZCsrOwogICAgZW50LT5oYXNoID0gaGFzaDsKICAgIGVudC0+bmV4dCA9ICpidWNrZXQ7CiAgICAqYnVja2V0ID0gZW50OwogICAgcmV0dXJuIGVudC0+bGlzdDsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjUGF0dGVybkJhc2VIYXNoIChGY1BhdHRlcm4gKmIpCnsKICAgIEZjQ2hhcjMyCWhhc2ggPSBiLT5udW07CiAgICBpbnQJCWk7CgogICAgZm9yIChpID0gMDsgaSA8IGItPm51bTsgaSsrKQoJaGFzaCA9ICgoaGFzaCA8PCAxKSB8IChoYXNoID4+IDMxKSkgXiAoKGxvbmcpIGItPmVsdHNbaV0udmFsdWVzKTsKICAgIHJldHVybiBoYXNoOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNQYXR0ZXJuRW50IEZjUGF0dGVybkVudDsKCnN0cnVjdCBfRmNQYXR0ZXJuRW50IHsKICAgIEZjUGF0dGVybkVudCAgICAqbmV4dDsKICAgIEZjQ2hhcjMyCSAgICBoYXNoOwogICAgRmNQYXR0ZXJuCSAgICBwYXR0ZXJuOwp9OwoKc3RhdGljIGludAlGY1BhdHRlcm5Ub3RhbDsKc3RhdGljIGludAlGY1BhdHRlcm5Vc2VkOwoKc3RhdGljIEZjUGF0dGVybiAqCkZjUGF0dGVybkJhc2VGcmVlemUgKEZjUGF0dGVybiAqYikKewogICAgc3RhdGljIEZjUGF0dGVybkVudAkqaGFzaFRhYmxlW0ZDX1ZBTFVFX0xJU1RfSEFTSF9TSVpFXTsKICAgIEZjQ2hhcjMyCQloYXNoID0gRmNQYXR0ZXJuQmFzZUhhc2ggKGIpOwogICAgRmNQYXR0ZXJuRW50CSoqYnVja2V0ID0gJmhhc2hUYWJsZVtoYXNoICUgRkNfVkFMVUVfTElTVF9IQVNIX1NJWkVdOwogICAgRmNQYXR0ZXJuRW50CSplbnQ7CiAgICBpbnQJCQlpOwogICAgY2hhcgkJKm9iamVjdHM7CiAgICBpbnQJCQlzaXplX29iamVjdHM7CiAgICBpbnQJCQlzaXplOwoKICAgIEZjUGF0dGVyblRvdGFsKys7CiAgICBmb3IgKGVudCA9ICpidWNrZXQ7IGVudDsgZW50ID0gZW50LT5uZXh0KQogICAgewoJaWYgKGVudC0+aGFzaCA9PSBoYXNoICYmIGItPm51bSA9PSBlbnQtPnBhdHRlcm4ubnVtKQoJewoJICAgIGZvciAoaSA9IDA7IGkgPCBiLT5udW07IGkrKykKCSAgICB7CgkJaWYgKHN0cmNtcCAoYi0+ZWx0c1tpXS5vYmplY3QsIGVudC0+cGF0dGVybi5lbHRzW2ldLm9iamVjdCkpCgkJICAgIGJyZWFrOwoJCWlmIChiLT5lbHRzW2ldLnZhbHVlcyAhPSBlbnQtPnBhdHRlcm4uZWx0c1tpXS52YWx1ZXMpCgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBpZiAoaSA9PSBiLT5udW0pCgkJcmV0dXJuICZlbnQtPnBhdHRlcm47Cgl9CiAgICB9CgogICAgLyoKICAgICAqIENvbXB1dGUgc2l6ZSBvZiBwYXR0ZXJuICsgZWx0cyArIG9iamVjdCBuYW1lcwogICAgICovCiAgICBzaXplX29iamVjdHMgPSAwOwogICAgZm9yIChpID0gMDsgaSA8IGItPm51bTsgaSsrKQoJc2l6ZV9vYmplY3RzICs9IHN0cmxlbiAoYi0+ZWx0c1tpXS5vYmplY3QpICsgMTsKCiAgICBzaXplID0gc2l6ZW9mIChGY1BhdHRlcm5FbnQpICsgYi0+bnVtKnNpemVvZiAoRmNQYXR0ZXJuRWx0KSArIHNpemVfb2JqZWN0czsKICAgIGVudCA9IG1hbGxvYyAoc2l6ZSk7CiAgICBpZiAoIWVudCkKCXJldHVybiAwOwoKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRURVJOLCBzaXplKTsKICAgIEZjUGF0dGVyblVzZWQrKzsKCiAgICBlbnQtPnBhdHRlcm4uZWx0cyA9IChGY1BhdHRlcm5FbHQgKikgKGVudCArIDEpOwogICAgZW50LT5wYXR0ZXJuLm51bSA9IGItPm51bTsKICAgIGVudC0+cGF0dGVybi5zaXplID0gYi0+bnVtOwogICAgZW50LT5wYXR0ZXJuLnJlZiA9IEZDX1JFRl9DT05TVEFOVDsKCiAgICBvYmplY3RzID0gKGNoYXIgKikgKGVudC0+cGF0dGVybi5lbHRzICsgYi0+bnVtKTsKICAgIGZvciAoaSA9IDA7IGkgPCBiLT5udW07IGkrKykKICAgIHsKCWVudC0+cGF0dGVybi5lbHRzW2ldLnZhbHVlcyA9IGItPmVsdHNbaV0udmFsdWVzOwoJc3RyY3B5IChvYmplY3RzLCBiLT5lbHRzW2ldLm9iamVjdCk7CgllbnQtPnBhdHRlcm4uZWx0c1tpXS5vYmplY3QgPSBvYmplY3RzOwoJb2JqZWN0cyArPSBzdHJsZW4gKG9iamVjdHMpICsgMTsKICAgIH0KCiAgICBlbnQtPmhhc2ggPSBoYXNoOwogICAgZW50LT5uZXh0ID0gKmJ1Y2tldDsKICAgICpidWNrZXQgPSBlbnQ7CiAgICByZXR1cm4gJmVudC0+cGF0dGVybjsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuRnJlZXplIChGY1BhdHRlcm4gKnApCnsKICAgIEZjUGF0dGVybgkqYiwgKm4gPSAwOwogICAgaW50CQlzaXplOwogICAgaW50CQlpOwogICAgCiAgICBzaXplID0gc2l6ZW9mIChGY1BhdHRlcm4pICsgcC0+bnVtICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpOwogICAgYiA9IChGY1BhdHRlcm4gKikgbWFsbG9jIChzaXplKTsKICAgIGlmICghYikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1BBVFRFUk4sIHNpemUpOwogICAgYi0+bnVtID0gcC0+bnVtOwogICAgYi0+c2l6ZSA9IGItPm51bTsKICAgIGItPnJlZiA9IDE7CiAgICBiLT5lbHRzID0gKEZjUGF0dGVybkVsdCAqKSAoYiArIDEpOwogICAgLyoKICAgICAqIEZyZWV6ZSBvYmplY3QgbGlzdHMKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHAtPm51bTsgaSsrKQogICAgewoJYi0+ZWx0c1tpXS5vYmplY3QgPSBwLT5lbHRzW2ldLm9iamVjdDsKCWItPmVsdHNbaV0udmFsdWVzID0gRmNWYWx1ZUxpc3RGcmVlemUgKHAtPmVsdHNbaV0udmFsdWVzKTsKCWlmICghYi0+ZWx0c1tpXS52YWx1ZXMpCgkgICAgZ290byBiYWlsOwogICAgfQogICAgLyoKICAgICAqIEZyZWV6ZSBiYXNlCiAgICAgKi8KICAgIG4gPSBGY1BhdHRlcm5CYXNlRnJlZXplIChiKTsKI2lmZGVmIENIQVRUWQogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19NRU1PUlkpCiAgICB7CglwcmludGYgKCJWYWx1ZUxpc3RzOiB0b3RhbCAlOWQgdXNlZCAlOWRcbiIsIEZjVmFsdWVMaXN0VG90YWwsIEZjVmFsdWVMaXN0VXNlZCk7CglwcmludGYgKCJQYXR0ZXJuczogICB0b3RhbCAlOWQgdXNlZCAlOWRcbiIsIEZjUGF0dGVyblRvdGFsLCBGY1BhdHRlcm5Vc2VkKTsKICAgIH0KI2VuZGlmCmJhaWw6CiAgICBmcmVlIChiKTsKI2lmZGVmIERFQlVHCiAgICBhc3NlcnQgKEZjUGF0dGVybkVxdWFsIChuLCBwKSk7CiNlbmRpZgogICAgcmV0dXJuIG47Cn0KCnN0YXRpYyBpbnQKRmNQYXR0ZXJuUG9zaXRpb24gKGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0KQp7CiAgICBpbnQJICAgIGxvdywgaGlnaCwgbWlkLCBjOwoKICAgIGxvdyA9IDA7CiAgICBoaWdoID0gcC0+bnVtIC0gMTsKICAgIGMgPSAxOwogICAgbWlkID0gMDsKICAgIHdoaWxlIChsb3cgPD0gaGlnaCkKICAgIHsKCW1pZCA9IChsb3cgKyBoaWdoKSA+PiAxOwoJYyA9IHN0cmNtcCAocC0+ZWx0c1ttaWRdLm9iamVjdCwgb2JqZWN0KTsKCWlmIChjID09IDApCgkgICAgcmV0dXJuIG1pZDsKCWlmIChjIDwgMCkKCSAgICBsb3cgPSBtaWQgKyAxOwoJZWxzZQoJICAgIGhpZ2ggPSBtaWQgLSAxOwogICAgfQogICAgaWYgKGMgPCAwKQoJbWlkKys7CiAgICByZXR1cm4gLShtaWQgKyAxKTsKfQoKRmNQYXR0ZXJuRWx0ICoKRmNQYXR0ZXJuRmluZEVsdCAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIGludAkgICAgaSA9IEZjUGF0dGVyblBvc2l0aW9uIChwLCBvYmplY3QpOwogICAgaWYgKGkgPCAwKQoJcmV0dXJuIDA7CiAgICByZXR1cm4gJnAtPmVsdHNbaV07Cn0KCkZjUGF0dGVybkVsdCAqCkZjUGF0dGVybkluc2VydEVsdCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIGludAkJICAgIGk7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIAogICAgaSA9IEZjUGF0dGVyblBvc2l0aW9uIChwLCBvYmplY3QpOwogICAgaWYgKGkgPCAwKQogICAgewoJaSA9IC1pIC0gMTsKICAgIAoJLyogZ3JvdyBhcnJheSAqLwoJaWYgKHAtPm51bSArIDEgPj0gcC0+c2l6ZSkKCXsKCSAgICBpbnQgcyA9IHAtPnNpemUgKyAxNjsKCSAgICBpZiAocC0+ZWx0cykKCQllID0gKEZjUGF0dGVybkVsdCAqKSByZWFsbG9jIChwLT5lbHRzLCBzICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCSAgICBlbHNlCgkJZSA9IChGY1BhdHRlcm5FbHQgKikgbWFsbG9jIChzICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCSAgICBpZiAoIWUpCgkJcmV0dXJuIEZjRmFsc2U7CgkgICAgcC0+ZWx0cyA9IGU7CgkgICAgaWYgKHAtPnNpemUpCgkJRmNNZW1GcmVlIChGQ19NRU1fUEFURUxULCBwLT5zaXplICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCSAgICBGY01lbUFsbG9jIChGQ19NRU1fUEFURUxULCBzICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKCSAgICB3aGlsZSAocC0+c2l6ZSA8IHMpCgkgICAgewoJCXAtPmVsdHNbcC0+c2l6ZV0ub2JqZWN0ID0gMDsKCQlwLT5lbHRzW3AtPnNpemVdLnZhbHVlcyA9IDA7CgkJcC0+c2l6ZSsrOwoJICAgIH0KCX0KCQoJLyogbW92ZSBlbHRzIHVwICovCgltZW1tb3ZlIChwLT5lbHRzICsgaSArIDEsCgkJIHAtPmVsdHMgKyBpLAoJCSBzaXplb2YgKEZjUGF0dGVybkVsdCkgKgoJCSAocC0+bnVtIC0gaSkpOwoJCSAKCS8qIGJ1bXAgY291bnQgKi8KCXAtPm51bSsrOwoJCglwLT5lbHRzW2ldLm9iamVjdCA9IG9iamVjdDsKCXAtPmVsdHNbaV0udmFsdWVzID0gMDsKICAgIH0KICAgIAogICAgcmV0dXJuICZwLT5lbHRzW2ldOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuRXF1YWwgKGNvbnN0IEZjUGF0dGVybiAqcGEsIGNvbnN0IEZjUGF0dGVybiAqcGIpCnsKICAgIGludAlpOwoKICAgIGlmIChwYSA9PSBwYikKCXJldHVybiBGY1RydWU7CgogICAgaWYgKHBhLT5udW0gIT0gcGItPm51bSkKCXJldHVybiBGY0ZhbHNlOwogICAgZm9yIChpID0gMDsgaSA8IHBhLT5udW07IGkrKykKICAgIHsKCWlmIChzdHJjbXAgKHBhLT5lbHRzW2ldLm9iamVjdCwgcGItPmVsdHNbaV0ub2JqZWN0KSAhPSAwKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKCFGY1ZhbHVlTGlzdEVxdWFsIChwYS0+ZWx0c1tpXS52YWx1ZXMsIHBiLT5lbHRzW2ldLnZhbHVlcykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0NoYXIzMgpGY1BhdHRlcm5IYXNoIChjb25zdCBGY1BhdHRlcm4gKnApCnsKICAgIGludAkJaTsKICAgIEZjQ2hhcjMyCWggPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBwLT5udW07IGkrKykKICAgIHsKCWggPSAoKChoIDw8IDEpIHwgKGggPj4gMzEpKSBeIAoJICAgICBGY1N0cmluZ0hhc2ggKChjb25zdCBGY0NoYXI4ICopIHAtPmVsdHNbaV0ub2JqZWN0KSBeCgkgICAgIEZjVmFsdWVMaXN0SGFzaCAocC0+ZWx0c1tpXS52YWx1ZXMpKTsKICAgIH0KICAgIHJldHVybiBoOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuRXF1YWxTdWJzZXQgKGNvbnN0IEZjUGF0dGVybiAqcGEsIGNvbnN0IEZjUGF0dGVybiAqcGIsIGNvbnN0IEZjT2JqZWN0U2V0ICpvcykKewogICAgRmNQYXR0ZXJuRWx0ICAgICplYSwgKmViOwogICAgaW50CQkgICAgaTsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IG9zLT5ub2JqZWN0OyBpKyspCiAgICB7CgllYSA9IEZjUGF0dGVybkZpbmRFbHQgKHBhLCBvcy0+b2JqZWN0c1tpXSk7CgllYiA9IEZjUGF0dGVybkZpbmRFbHQgKHBiLCBvcy0+b2JqZWN0c1tpXSk7CglpZiAoZWEpCgl7CgkgICAgaWYgKCFlYikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBpZiAoIUZjVmFsdWVMaXN0RXF1YWwgKGVhLT52YWx1ZXMsIGViLT52YWx1ZXMpKQoJCXJldHVybiBGY0ZhbHNlOwoJfQoJZWxzZQoJewoJICAgIGlmIChlYikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRXaXRoQmluZGluZyAgKEZjUGF0dGVybgkgICAgKnAsCgkJCSAgY29uc3QgY2hhcgkgICAgKm9iamVjdCwKCQkJICBGY1ZhbHVlCSAgICB2YWx1ZSwKCQkJICBGY1ZhbHVlQmluZGluZyAgICBiaW5kaW5nLAoJCQkgIEZjQm9vbAkgICAgYXBwZW5kKQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpuZXcsICoqcHJldjsKCiAgICBpZiAocC0+cmVmID09IEZDX1JFRl9DT05TVEFOVCkKCWdvdG8gYmFpbDA7CgogICAgbmV3ID0gKEZjVmFsdWVMaXN0ICopIG1hbGxvYyAoc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgaWYgKCFuZXcpCglnb3RvIGJhaWwwOwoKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9WQUxMSVNULCBzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICAvKiBkdXAgc3RyaW5nICovCiAgICB2YWx1ZSA9IEZjVmFsdWVTYXZlICh2YWx1ZSk7CiAgICBpZiAodmFsdWUudHlwZSA9PSBGY1R5cGVWb2lkKQoJZ290byBiYWlsMTsKCiAgICBuZXctPnZhbHVlID0gdmFsdWU7CiAgICBuZXctPmJpbmRpbmcgPSBiaW5kaW5nOwogICAgbmV3LT5uZXh0ID0gMDsKICAgIAogICAgZSA9IEZjUGF0dGVybkluc2VydEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCWdvdG8gYmFpbDI7CiAgICAKICAgIGlmIChhcHBlbmQpCiAgICB7Cglmb3IgKHByZXYgPSAmZS0+dmFsdWVzOyAqcHJldjsgcHJldiA9ICYoKnByZXYpLT5uZXh0KTsKCSpwcmV2ID0gbmV3OwogICAgfQogICAgZWxzZQogICAgewoJbmV3LT5uZXh0ID0gZS0+dmFsdWVzOwoJZS0+dmFsdWVzID0gbmV3OwogICAgfQogICAgCiAgICByZXR1cm4gRmNUcnVlOwoKYmFpbDI6ICAgIAogICAgc3dpdGNoICh2YWx1ZS50eXBlKSB7CiAgICBjYXNlIEZjVHlwZVN0cmluZzoKCUZjU3RyRnJlZSAoKEZjQ2hhcjggKikgdmFsdWUudS5zKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVNYXRyaXg6CglGY01hdHJpeEZyZWUgKChGY01hdHJpeCAqKSB2YWx1ZS51Lm0pOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZUNoYXJTZXQ6CglGY0NoYXJTZXREZXN0cm95ICgoRmNDaGFyU2V0ICopIHZhbHVlLnUuYyk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlTGFuZ1NldDoKCUZjTGFuZ1NldERlc3Ryb3kgKChGY0xhbmdTZXQgKikgdmFsdWUudS5sKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCWJyZWFrOwogICAgfQpiYWlsMToKICAgIEZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIGZyZWUgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nU3Ryb25nLCBhcHBlbmQpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkV2VhayAgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY1ZhbHVlIHZhbHVlLCBGY0Jvb2wgYXBwZW5kKQp7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkV2l0aEJpbmRpbmcgKHAsIG9iamVjdCwgdmFsdWUsIEZjVmFsdWVCaW5kaW5nV2VhaywgYXBwZW5kKTsKfQoKRmNCb29sCkZjUGF0dGVybkRlbCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgaW50CQkgICAgaTsKCiAgICBlID0gRmNQYXR0ZXJuRmluZEVsdCAocCwgb2JqZWN0KTsKICAgIGlmICghZSkKCXJldHVybiBGY0ZhbHNlOwoKICAgIGkgPSBlIC0gcC0+ZWx0czsKICAgIAogICAgLyogZGVzdHJveSB2YWx1ZSAqLwogICAgRmNWYWx1ZUxpc3REZXN0cm95IChlLT52YWx1ZXMpOwogICAgCiAgICAvKiBzaHVmZmxlIGV4aXN0aW5nIG9uZXMgZG93biAqLwogICAgbWVtbW92ZSAoZSwgZSsxLCAocC0+ZWx0cyArIHAtPm51bSAtIChlICsgMSkpICogc2l6ZW9mIChGY1BhdHRlcm5FbHQpKTsKICAgIHAtPm51bS0tOwogICAgcC0+ZWx0c1twLT5udW1dLm9iamVjdCA9IDA7CiAgICBwLT5lbHRzW3AtPm51bV0udmFsdWVzID0gMDsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRJbnRlZ2VyIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGkpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVJbnRlZ2VyOwogICAgdi51LmkgPSBpOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkRG91YmxlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgZG91YmxlIGQpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVEb3VibGU7CiAgICB2LnUuZCA9IGQ7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCgpGY0Jvb2wKRmNQYXR0ZXJuQWRkU3RyaW5nIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZVN0cmluZzsKICAgIHYudS5zID0gczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZE1hdHJpeCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjTWF0cml4ICpzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlTWF0cml4OwogICAgdi51Lm0gPSAoRmNNYXRyaXggKikgczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKCkZjQm9vbApGY1BhdHRlcm5BZGRCb29sIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgRmNCb29sIGIpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVCb29sOwogICAgdi51LmIgPSBiOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkQ2hhclNldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjQ2hhclNldCAqYykKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUNoYXJTZXQ7CiAgICB2LnUuYyA9IChGY0NoYXJTZXQgKikgYzsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZEZURmFjZSAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZUX0ZhY2UgZikKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUZURmFjZTsKICAgIHYudS5mID0gKHZvaWQgKikgZjsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZExhbmdTZXQgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBjb25zdCBGY0xhbmdTZXQgKmxzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlTGFuZ1NldDsKICAgIHYudS5sID0gKEZjTGFuZ1NldCAqKSBsczsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0IChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY1ZhbHVlICp2KQp7CiAgICBGY1BhdHRlcm5FbHQgICAqZTsKICAgIEZjVmFsdWVMaXN0ICAgICpsOwoKICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJcmV0dXJuIEZjUmVzdWx0Tm9NYXRjaDsKICAgIGZvciAobCA9IGUtPnZhbHVlczsgbDsgbCA9IGwtPm5leHQpCiAgICB7CglpZiAoIWlkKQoJewoJICAgICp2ID0gbC0+dmFsdWU7CgkgICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cgl9CglpZC0tOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0Tm9JZDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0SW50ZWdlciAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgaW50ICppKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSppID0gKGludCkgdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSppID0gdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldERvdWJsZSAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgZG91YmxlICpkKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIHN3aXRjaCAodi50eXBlKSB7CiAgICBjYXNlIEZjVHlwZURvdWJsZToKCSpkID0gdi51LmQ7CglicmVhazsKICAgIGNhc2UgRmNUeXBlSW50ZWdlcjoKCSpkID0gKGRvdWJsZSkgdi51Lmk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgfQogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldFN0cmluZyAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNDaGFyOCAqKiBzKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlU3RyaW5nKQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpzID0gKEZjQ2hhcjggKikgdi51LnM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0TWF0cml4KGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjTWF0cml4ICoqbSkKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZU1hdHJpeCkKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqbSA9IChGY01hdHJpeCAqKSB2LnUubTsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0Qm9vbChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0Jvb2wgKmIpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVCb29sKQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpiID0gdi51LmI7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0Q2hhclNldChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0NoYXJTZXQgKipjKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlQ2hhclNldCkKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqYyA9IChGY0NoYXJTZXQgKikgdi51LmM7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0RlRGYWNlKGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZUX0ZhY2UgKmYpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVGVEZhY2UpCglyZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqZiA9IChGVF9GYWNlKSB2LnUuZjsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRMYW5nU2V0KGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjTGFuZ1NldCAqKmxzKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlTGFuZ1NldCkKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICAqbHMgPSAoRmNMYW5nU2V0ICopIHYudS5sOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVybkR1cGxpY2F0ZSAoY29uc3QgRmNQYXR0ZXJuICpvcmlnKQp7CiAgICBGY1BhdHRlcm4JICAgICpuZXc7CiAgICBpbnQJCSAgICBpOwogICAgRmNWYWx1ZUxpc3QgICAgKmw7CgogICAgbmV3ID0gRmNQYXR0ZXJuQ3JlYXRlICgpOwogICAgaWYgKCFuZXcpCglnb3RvIGJhaWwwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvcmlnLT5udW07IGkrKykKICAgIHsKCWZvciAobCA9IG9yaWctPmVsdHNbaV0udmFsdWVzOyBsOyBsID0gbC0+bmV4dCkKCSAgICBpZiAoIUZjUGF0dGVybkFkZCAobmV3LCBvcmlnLT5lbHRzW2ldLm9iamVjdCwgbC0+dmFsdWUsIEZjVHJ1ZSkpCgkJZ290byBiYWlsMTsKICAgIH0KCiAgICByZXR1cm4gbmV3OwoKYmFpbDE6CiAgICBGY1BhdHRlcm5EZXN0cm95IChuZXcpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9Cgp2b2lkCkZjUGF0dGVyblJlZmVyZW5jZSAoRmNQYXR0ZXJuICpwKQp7CiAgICBpZiAocC0+cmVmICE9IEZDX1JFRl9DT05TVEFOVCkKCXAtPnJlZisrOwp9CgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5WYUJ1aWxkIChGY1BhdHRlcm4gKm9yaWcsIHZhX2xpc3QgdmEpCnsKICAgIEZjUGF0dGVybgkqcmV0OwogICAgCiAgICBGY1BhdHRlcm5WYXBCdWlsZCAocmV0LCBvcmlnLCB2YSk7CiAgICByZXR1cm4gcmV0Owp9CgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5CdWlsZCAoRmNQYXR0ZXJuICpvcmlnLCAuLi4pCnsKICAgIHZhX2xpc3QJdmE7CiAgICAKICAgIHZhX3N0YXJ0ICh2YSwgb3JpZyk7CiAgICBGY1BhdHRlcm5WYXBCdWlsZCAob3JpZywgb3JpZywgdmEpOwogICAgdmFfZW5kICh2YSk7CiAgICByZXR1cm4gb3JpZzsKfQo=