LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNwYXQuYyx2IDEuMTggMjAwMi8wOS8xOCAxNzoxMTo0NiB0c2kgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+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+bmV4dCA9IG5ldyArIDE7CgllbHNlCgkgICAgbmV3LT5uZXh0ID0gMDsKICAgIH0KICAgIHJldHVybiBlOwp9CgpzdGF0aWMgdm9pZApGY1ZhbHVlTGlzdEVudERlc3Ryb3kgKEZjVmFsdWVMaXN0RW50ICplKQp7CiAgICBGY1ZhbHVlTGlzdAkqbDsKCiAgICBGY1ZhbHVlTGlzdEZyb3plbkNvdW50W2UtPmxpc3QtPnZhbHVlLnR5cGVdLS07CgogICAgLyogWFhYOiBXZSBzaG91bGQgcGVyZm9ybSB0aGVzZSB0d28gb3BlcmF0aW9ucyB3aXRoICJzaXplIiBhcwogICAgICAgY29tcHV0ZWQgaW4gRmNWYWx1ZUxpc3RFbnRDcmVhdGUsIGJ1dCB3ZSBkb24ndCBoYXZlIGFjY2VzcyB0bwogICAgICAgdGhhdCB2YWx1ZSBoZXJlLiBXaXRob3V0IHRoaXMsIHRoZSBGY1ZhbHVlTGlzdEZyb3plbkJ5dGVzCiAgICAgICB2YWx1ZXMgd2lsbCBiZSB3cm9uZyBhcyB3aWxsIHRoZSBGY01lbUZyZWUgY291bnRzLgoKICAgICAgIEZjVmFsdWVMaXN0RnJvemVuQnl0ZXNbZS0+bGlzdC0+dmFsdWUudHlwZV0gLT0gc2l6ZTsKICAgICAgIEZjTWVtRnJlZSAoRkNfTUVNX1ZBTExJU1QsIHNpemUpOwogICAgKi8KCiAgICBmb3IgKGwgPSBlLT5saXN0OyBsOyBsID0gbC0+bmV4dCkKICAgIHsKCWlmIChsLT52YWx1ZS50eXBlICE9IEZjVHlwZVN0cmluZykKCSAgICBGY1ZhbHVlRGVzdHJveSAobC0+dmFsdWUpOwogICAgfQogICAgLyogWFhYOiBBcmUgd2UgYmVpbmcgdG9vIGNodW1teSB3aXRoIHRoZSBpbXBsZW1lbnRhdGlvbiBoZXJlIHRvCiAgICAgICBmcmVlKGUpIHdoZW4gaXQgd2FzIGFjdHVhbGx5IHRoZSBlbmNsb3NpbmcgRmNWYWx1ZUxpc3RBbGlnbgogICAgICAgdGhhdCB3YXMgYWxsb2NhdGVkPyAqLwogICAgZnJlZSAoZSk7Cn0KCnN0YXRpYyBpbnQJRmNWYWx1ZUxpc3RUb3RhbDsKc3RhdGljIGludAlGY1ZhbHVlTGlzdFVzZWQ7CgpzdGF0aWMgRmNWYWx1ZUxpc3RFbnQgICAqRmNWYWx1ZUxpc3RIYXNoVGFibGVbRkNfVkFMVUVfTElTVF9IQVNIX1NJWkVdOwoKc3RhdGljIEZjVmFsdWVMaXN0ICoKRmNWYWx1ZUxpc3RGcmVlemUgKEZjVmFsdWVMaXN0ICpsKQp7CiAgICBGY0NoYXIzMgkJICAgIGhhc2ggPSBGY1ZhbHVlTGlzdEhhc2ggKGwpOwogICAgRmNWYWx1ZUxpc3RFbnQJICAgICoqYnVja2V0ID0gJkZjVmFsdWVMaXN0SGFzaFRhYmxlW2hhc2ggJSBGQ19WQUxVRV9MSVNUX0hBU0hfU0laRV07CiAgICBGY1ZhbHVlTGlzdEVudAkgICAgKmVudDsKCiAgICBGY1ZhbHVlTGlzdFRvdGFsKys7CiAgICBmb3IgKGVudCA9ICpidWNrZXQ7IGVudDsgZW50ID0gZW50LT5uZXh0KQogICAgewoJaWYgKGVudC0+aGFzaCA9PSBoYXNoICYmIEZjVmFsdWVMaXN0RXF1YWwgKGVudC0+bGlzdCwgbCkpCgkgICAgcmV0dXJuIGVudC0+bGlzdDsKICAgIH0KCiAgICBlbnQgPSBGY1ZhbHVlTGlzdEVudENyZWF0ZSAobCk7CiAgICBpZiAoIWVudCkKCXJldHVybiAwOwoKICAgIEZjVmFsdWVMaXN0VXNlZCsrOwogICAgZW50LT5oYXNoID0gaGFzaDsKICAgIGVudC0+bmV4dCA9ICpidWNrZXQ7CiAgICAqYnVja2V0ID0gZW50OwogICAgcmV0dXJuIGVudC0+bGlzdDsKfQoKc3RhdGljIHZvaWQKRmNWYWx1ZUxpc3RUaGF3QWxsICh2b2lkKQp7CiAgICBpbnQgaTsKICAgIEZjVmFsdWVMaXN0RW50CSplbnQsICpuZXh0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBGQ19WQUxVRV9MSVNUX0hBU0hfU0laRTsgaSsrKQogICAgewoJZm9yIChlbnQgPSBGY1ZhbHVlTGlzdEhhc2hUYWJsZVtpXTsgZW50OyBlbnQgPSBuZXh0KQoJewoJICAgIG5leHQgPSBlbnQtPm5leHQ7CgkgICAgRmNWYWx1ZUxpc3RFbnREZXN0cm95IChlbnQpOwoJfQoJRmNWYWx1ZUxpc3RIYXNoVGFibGVbaV0gPSAwOwogICAgfQoKICAgIEZjVmFsdWVMaXN0VG90YWwgPSAwOwogICAgRmNWYWx1ZUxpc3RVc2VkID0gMDsKfQoKc3RhdGljIEZjQ2hhcjMyCkZjUGF0dGVybkJhc2VIYXNoIChGY1BhdHRlcm4gKmIpCnsKICAgIEZjQ2hhcjMyCWhhc2ggPSBiLT5udW07CiAgICBpbnQJCWk7CgogICAgZm9yIChpID0gMDsgaSA8IGItPm51bTsgaSsrKQoJaGFzaCA9ICgoaGFzaCA8PCAxKSB8IChoYXNoID4+IDMxKSkgXiAoKGxvbmcpIGItPmVsdHNbaV0udmFsdWVzKTsKICAgIHJldHVybiBoYXNoOwp9Cgp0eXBlZGVmIHN0cnVjdCBfRmNQYXR0ZXJuRW50IEZjUGF0dGVybkVudDsKCnN0cnVjdCBfRmNQYXR0ZXJuRW50IHsKICAgIEZjUGF0dGVybkVudCAgICAqbmV4dDsKICAgIEZjQ2hhcjMyCSAgICBoYXNoOwogICAgRmNQYXR0ZXJuCSAgICBwYXR0ZXJuOwp9OwoKc3RhdGljIGludAlGY1BhdHRlcm5Ub3RhbDsKc3RhdGljIGludAlGY1BhdHRlcm5Vc2VkOwoKc3RhdGljIEZjUGF0dGVybkVudAkqRmNQYXR0ZXJuSGFzaFRhYmxlW0ZDX1ZBTFVFX0xJU1RfSEFTSF9TSVpFXTsKCnN0YXRpYyBGY1BhdHRlcm4gKgpGY1BhdHRlcm5CYXNlRnJlZXplIChGY1BhdHRlcm4gKmIpCnsKICAgIEZjQ2hhcjMyCQloYXNoID0gRmNQYXR0ZXJuQmFzZUhhc2ggKGIpOwogICAgRmNQYXR0ZXJuRW50CSoqYnVja2V0ID0gJkZjUGF0dGVybkhhc2hUYWJsZVtoYXNoICUgRkNfVkFMVUVfTElTVF9IQVNIX1NJWkVdOwogICAgRmNQYXR0ZXJuRW50CSplbnQ7CiAgICBpbnQJCQlpOwogICAgY2hhcgkJKm9iamVjdHM7CiAgICBpbnQJCQlzaXplX29iamVjdHM7CiAgICBpbnQJCQlzaXplOwoKICAgIEZjUGF0dGVyblRvdGFsKys7CiAgICBmb3IgKGVudCA9ICpidWNrZXQ7IGVudDsgZW50ID0gZW50LT5uZXh0KQogICAgewoJaWYgKGVudC0+aGFzaCA9PSBoYXNoICYmIGItPm51bSA9PSBlbnQtPnBhdHRlcm4ubnVtKQoJewoJICAgIGZvciAoaSA9IDA7IGkgPCBiLT5udW07IGkrKykKCSAgICB7CgkJaWYgKHN0cmNtcCAoYi0+ZWx0c1tpXS5vYmplY3QsIGVudC0+cGF0dGVybi5lbHRzW2ldLm9iamVjdCkpCgkJICAgIGJyZWFrOwoJCWlmIChiLT5lbHRzW2ldLnZhbHVlcyAhPSBlbnQtPnBhdHRlcm4uZWx0c1tpXS52YWx1ZXMpCgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBpZiAoaSA9PSBiLT5udW0pCgkJcmV0dXJuICZlbnQtPnBhdHRlcm47Cgl9CiAgICB9CgogICAgLyoKICAgICAqIENvbXB1dGUgc2l6ZSBvZiBwYXR0ZXJuICsgZWx0cyArIG9iamVjdCBuYW1lcwogICAgICovCiAgICBzaXplX29iamVjdHMgPSAwOwogICAgZm9yIChpID0gMDsgaSA8IGItPm51bTsgaSsrKQoJc2l6ZV9vYmplY3RzICs9IHN0cmxlbiAoYi0+ZWx0c1tpXS5vYmplY3QpICsgMTsKCiAgICBzaXplID0gc2l6ZW9mIChGY1BhdHRlcm5FbnQpICsgYi0+bnVtKnNpemVvZiAoRmNQYXR0ZXJuRWx0KSArIHNpemVfb2JqZWN0czsKICAgIGVudCA9IG1hbGxvYyAoc2l6ZSk7CiAgICBpZiAoIWVudCkKCXJldHVybiAwOwoKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRURVJOLCBzaXplKTsKICAgIEZjUGF0dGVyblVzZWQrKzsKCiAgICBlbnQtPnBhdHRlcm4uZWx0cyA9IChGY1BhdHRlcm5FbHQgKikgKGVudCArIDEpOwogICAgZW50LT5wYXR0ZXJuLm51bSA9IGItPm51bTsKICAgIGVudC0+cGF0dGVybi5zaXplID0gYi0+bnVtOwogICAgZW50LT5wYXR0ZXJuLnJlZiA9IEZDX1JFRl9DT05TVEFOVDsKCiAgICBvYmplY3RzID0gKGNoYXIgKikgKGVudC0+cGF0dGVybi5lbHRzICsgYi0+bnVtKTsKICAgIGZvciAoaSA9IDA7IGkgPCBiLT5udW07IGkrKykKICAgIHsKCWVudC0+cGF0dGVybi5lbHRzW2ldLnZhbHVlcyA9IGItPmVsdHNbaV0udmFsdWVzOwoJc3RyY3B5IChvYmplY3RzLCBiLT5lbHRzW2ldLm9iamVjdCk7CgllbnQtPnBhdHRlcm4uZWx0c1tpXS5vYmplY3QgPSBvYmplY3RzOwoJb2JqZWN0cyArPSBzdHJsZW4gKG9iamVjdHMpICsgMTsKICAgIH0KCiAgICBlbnQtPmhhc2ggPSBoYXNoOwogICAgZW50LT5uZXh0ID0gKmJ1Y2tldDsKICAgICpidWNrZXQgPSBlbnQ7CiAgICByZXR1cm4gJmVudC0+cGF0dGVybjsKfQoKc3RhdGljIHZvaWQKRmNQYXR0ZXJuQmFzZVRoYXdBbGwgKHZvaWQpCnsKICAgIGludCBpOwogICAgRmNQYXR0ZXJuRW50CSplbnQsICpuZXh0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBGQ19WQUxVRV9MSVNUX0hBU0hfU0laRTsgaSsrKQogICAgewoJZm9yIChlbnQgPSBGY1BhdHRlcm5IYXNoVGFibGVbaV07IGVudDsgZW50ID0gbmV4dCkKCXsKCSAgICBuZXh0ID0gZW50LT5uZXh0OwoJICAgIGZyZWUgKGVudCk7Cgl9CglGY1BhdHRlcm5IYXNoVGFibGVbaV0gPSAwOwogICAgfQoKICAgIEZjUGF0dGVyblRvdGFsID0gMDsKICAgIEZjUGF0dGVyblVzZWQgPSAwOwp9CgpGY1BhdHRlcm4gKgpGY1BhdHRlcm5GcmVlemUgKEZjUGF0dGVybiAqcCkKewogICAgRmNQYXR0ZXJuCSpiLCAqbiA9IDA7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CiAgICAKICAgIHNpemUgPSBzaXplb2YgKEZjUGF0dGVybikgKyBwLT5udW0gKiBzaXplb2YgKEZjUGF0dGVybkVsdCk7CiAgICBiID0gKEZjUGF0dGVybiAqKSBtYWxsb2MgKHNpemUpOwogICAgaWYgKCFiKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fUEFUVEVSTiwgc2l6ZSk7CiAgICBiLT5udW0gPSBwLT5udW07CiAgICBiLT5zaXplID0gYi0+bnVtOwogICAgYi0+cmVmID0gMTsKICAgIGItPmVsdHMgPSAoRmNQYXR0ZXJuRWx0ICopIChiICsgMSk7CiAgICAvKgogICAgICogRnJlZXplIG9iamVjdCBsaXN0cwogICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgcC0+bnVtOyBpKyspCiAgICB7CgliLT5lbHRzW2ldLm9iamVjdCA9IHAtPmVsdHNbaV0ub2JqZWN0OwoJYi0+ZWx0c1tpXS52YWx1ZXMgPSBGY1ZhbHVlTGlzdEZyZWV6ZSAocC0+ZWx0c1tpXS52YWx1ZXMpOwoJaWYgKCFiLT5lbHRzW2ldLnZhbHVlcykKCSAgICBnb3RvIGJhaWw7CiAgICB9CiAgICAvKgogICAgICogRnJlZXplIGJhc2UKICAgICAqLwogICAgbiA9IEZjUGF0dGVybkJhc2VGcmVlemUgKGIpOwojaWZkZWYgQ0hBVFRZCiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX01FTU9SWSkKICAgIHsKCXByaW50ZiAoIlZhbHVlTGlzdHM6IHRvdGFsICU5ZCB1c2VkICU5ZFxuIiwgRmNWYWx1ZUxpc3RUb3RhbCwgRmNWYWx1ZUxpc3RVc2VkKTsKCXByaW50ZiAoIlBhdHRlcm5zOiAgIHRvdGFsICU5ZCB1c2VkICU5ZFxuIiwgRmNQYXR0ZXJuVG90YWwsIEZjUGF0dGVyblVzZWQpOwogICAgfQojZW5kaWYKYmFpbDoKICAgIGZyZWUgKGIpOwojaWZkZWYgREVCVUcKICAgIGFzc2VydCAoRmNQYXR0ZXJuRXF1YWwgKG4sIHApKTsKI2VuZGlmCiAgICByZXR1cm4gbjsKfQoKdm9pZApGY1BhdHRlcm5UaGF3QWxsICh2b2lkKQp7CiAgICBGY1BhdHRlcm5CYXNlVGhhd0FsbCAoKTsKICAgIEZjVmFsdWVMaXN0VGhhd0FsbCAoKTsKfQoKc3RhdGljIGludApGY1BhdHRlcm5Qb3NpdGlvbiAoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QpCnsKICAgIGludAkgICAgbG93LCBoaWdoLCBtaWQsIGM7CgogICAgbG93ID0gMDsKICAgIGhpZ2ggPSBwLT5udW0gLSAxOwogICAgYyA9IDE7CiAgICBtaWQgPSAwOwogICAgd2hpbGUgKGxvdyA8PSBoaWdoKQogICAgewoJbWlkID0gKGxvdyArIGhpZ2gpID4+IDE7CgljID0gc3RyY21wIChwLT5lbHRzW21pZF0ub2JqZWN0LCBvYmplY3QpOwoJaWYgKGMgPT0gMCkKCSAgICByZXR1cm4gbWlkOwoJaWYgKGMgPCAwKQoJICAgIGxvdyA9IG1pZCArIDE7CgllbHNlCgkgICAgaGlnaCA9IG1pZCAtIDE7CiAgICB9CiAgICBpZiAoYyA8IDApCgltaWQrKzsKICAgIHJldHVybiAtKG1pZCArIDEpOwp9CgpGY1BhdHRlcm5FbHQgKgpGY1BhdHRlcm5GaW5kRWx0IChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CSAgICBpID0gRmNQYXR0ZXJuUG9zaXRpb24gKHAsIG9iamVjdCk7CiAgICBpZiAoaSA8IDApCglyZXR1cm4gMDsKICAgIHJldHVybiAmcC0+ZWx0c1tpXTsKfQoKRmNQYXR0ZXJuRWx0ICoKRmNQYXR0ZXJuSW5zZXJ0RWx0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgaW50CQkgICAgaTsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgCiAgICBpID0gRmNQYXR0ZXJuUG9zaXRpb24gKHAsIG9iamVjdCk7CiAgICBpZiAoaSA8IDApCiAgICB7CglpID0gLWkgLSAxOwogICAgCgkvKiBncm93IGFycmF5ICovCglpZiAocC0+bnVtICsgMSA+PSBwLT5zaXplKQoJewoJICAgIGludCBzID0gcC0+c2l6ZSArIDE2OwoJICAgIGlmIChwLT5lbHRzKQoJCWUgPSAoRmNQYXR0ZXJuRWx0ICopIHJlYWxsb2MgKHAtPmVsdHMsIHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIGVsc2UKCQllID0gKEZjUGF0dGVybkVsdCAqKSBtYWxsb2MgKHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIGlmICghZSkKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBwLT5lbHRzID0gZTsKCSAgICBpZiAocC0+c2l6ZSkKCQlGY01lbUZyZWUgKEZDX01FTV9QQVRFTFQsIHAtPnNpemUgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIEZjTWVtQWxsb2MgKEZDX01FTV9QQVRFTFQsIHMgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwoJICAgIHdoaWxlIChwLT5zaXplIDwgcykKCSAgICB7CgkJcC0+ZWx0c1twLT5zaXplXS5vYmplY3QgPSAwOwoJCXAtPmVsdHNbcC0+c2l6ZV0udmFsdWVzID0gMDsKCQlwLT5zaXplKys7CgkgICAgfQoJfQoJCgkvKiBtb3ZlIGVsdHMgdXAgKi8KCW1lbW1vdmUgKHAtPmVsdHMgKyBpICsgMSwKCQkgcC0+ZWx0cyArIGksCgkJIHNpemVvZiAoRmNQYXR0ZXJuRWx0KSAqCgkJIChwLT5udW0gLSBpKSk7CgkJIAoJLyogYnVtcCBjb3VudCAqLwoJcC0+bnVtKys7CgkKCXAtPmVsdHNbaV0ub2JqZWN0ID0gb2JqZWN0OwoJcC0+ZWx0c1tpXS52YWx1ZXMgPSAwOwogICAgfQogICAgCiAgICByZXR1cm4gJnAtPmVsdHNbaV07Cn0KCkZjQm9vbApGY1BhdHRlcm5FcXVhbCAoY29uc3QgRmNQYXR0ZXJuICpwYSwgY29uc3QgRmNQYXR0ZXJuICpwYikKewogICAgaW50CWk7CgogICAgaWYgKHBhID09IHBiKQoJcmV0dXJuIEZjVHJ1ZTsKCiAgICBpZiAocGEtPm51bSAhPSBwYi0+bnVtKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBmb3IgKGkgPSAwOyBpIDwgcGEtPm51bTsgaSsrKQogICAgewoJaWYgKHN0cmNtcCAocGEtPmVsdHNbaV0ub2JqZWN0LCBwYi0+ZWx0c1tpXS5vYmplY3QpICE9IDApCgkgICAgcmV0dXJuIEZjRmFsc2U7CglpZiAoIUZjVmFsdWVMaXN0RXF1YWwgKHBhLT5lbHRzW2ldLnZhbHVlcywgcGItPmVsdHNbaV0udmFsdWVzKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQ2hhcjMyCkZjUGF0dGVybkhhc2ggKGNvbnN0IEZjUGF0dGVybiAqcCkKewogICAgaW50CQlpOwogICAgRmNDaGFyMzIJaCA9IDA7CgogICAgZm9yIChpID0gMDsgaSA8IHAtPm51bTsgaSsrKQogICAgewoJaCA9ICgoKGggPDwgMSkgfCAoaCA+PiAzMSkpIF4gCgkgICAgIEZjU3RyaW5nSGFzaCAoKGNvbnN0IEZjQ2hhcjggKikgcC0+ZWx0c1tpXS5vYmplY3QpIF4KCSAgICAgRmNWYWx1ZUxpc3RIYXNoIChwLT5lbHRzW2ldLnZhbHVlcykpOwogICAgfQogICAgcmV0dXJuIGg7Cn0KCkZjQm9vbApGY1BhdHRlcm5FcXVhbFN1YnNldCAoY29uc3QgRmNQYXR0ZXJuICpwYSwgY29uc3QgRmNQYXR0ZXJuICpwYiwgY29uc3QgRmNPYmplY3RTZXQgKm9zKQp7CiAgICBGY1BhdHRlcm5FbHQgICAgKmVhLCAqZWI7CiAgICBpbnQJCSAgICBpOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgb3MtPm5vYmplY3Q7IGkrKykKICAgIHsKCWVhID0gRmNQYXR0ZXJuRmluZEVsdCAocGEsIG9zLT5vYmplY3RzW2ldKTsKCWViID0gRmNQYXR0ZXJuRmluZEVsdCAocGIsIG9zLT5vYmplY3RzW2ldKTsKCWlmIChlYSkKCXsKCSAgICBpZiAoIWViKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIGlmICghRmNWYWx1ZUxpc3RFcXVhbCAoZWEtPnZhbHVlcywgZWItPnZhbHVlcykpCgkJcmV0dXJuIEZjRmFsc2U7Cgl9CgllbHNlCgl7CgkgICAgaWYgKGViKQoJCXJldHVybiBGY0ZhbHNlOwoJfQogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZFdpdGhCaW5kaW5nICAoRmNQYXR0ZXJuCSAgICAqcCwKCQkJICBjb25zdCBjaGFyCSAgICAqb2JqZWN0LAoJCQkgIEZjVmFsdWUJICAgIHZhbHVlLAoJCQkgIEZjVmFsdWVCaW5kaW5nICAgIGJpbmRpbmcsCgkJCSAgRmNCb29sCSAgICBhcHBlbmQpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgRmNWYWx1ZUxpc3QgICAgKm5ldywgKipwcmV2OwoKICAgIGlmIChwLT5yZWYgPT0gRkNfUkVGX0NPTlNUQU5UKQoJZ290byBiYWlsMDsKCiAgICBuZXcgPSAoRmNWYWx1ZUxpc3QgKikgbWFsbG9jIChzaXplb2YgKEZjVmFsdWVMaXN0KSk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1ZBTExJU1QsIHNpemVvZiAoRmNWYWx1ZUxpc3QpKTsKICAgIC8qIGR1cCBzdHJpbmcgKi8KICAgIHZhbHVlID0gRmNWYWx1ZVNhdmUgKHZhbHVlKTsKICAgIGlmICh2YWx1ZS50eXBlID09IEZjVHlwZVZvaWQpCglnb3RvIGJhaWwxOwoKICAgIG5ldy0+dmFsdWUgPSB2YWx1ZTsKICAgIG5ldy0+YmluZGluZyA9IGJpbmRpbmc7CiAgICBuZXctPm5leHQgPSAwOwogICAgCiAgICBlID0gRmNQYXR0ZXJuSW5zZXJ0RWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJZ290byBiYWlsMjsKICAgIAogICAgaWYgKGFwcGVuZCkKICAgIHsKCWZvciAocHJldiA9ICZlLT52YWx1ZXM7ICpwcmV2OyBwcmV2ID0gJigqcHJldiktPm5leHQpOwoJKnByZXYgPSBuZXc7CiAgICB9CiAgICBlbHNlCiAgICB7CgluZXctPm5leHQgPSBlLT52YWx1ZXM7CgllLT52YWx1ZXMgPSBuZXc7CiAgICB9CiAgICAKICAgIHJldHVybiBGY1RydWU7CgpiYWlsMjogICAgCiAgICBzd2l0Y2ggKHZhbHVlLnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlU3RyaW5nOgoJRmNTdHJGcmVlICgoRmNDaGFyOCAqKSB2YWx1ZS51LnMpOwoJYnJlYWs7CiAgICBjYXNlIEZjVHlwZU1hdHJpeDoKCUZjTWF0cml4RnJlZSAoKEZjTWF0cml4ICopIHZhbHVlLnUubSk7CglicmVhazsKICAgIGNhc2UgRmNUeXBlQ2hhclNldDoKCUZjQ2hhclNldERlc3Ryb3kgKChGY0NoYXJTZXQgKikgdmFsdWUudS5jKTsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVMYW5nU2V0OgoJRmNMYW5nU2V0RGVzdHJveSAoKEZjTGFuZ1NldCAqKSB2YWx1ZS51LmwpOwoJYnJlYWs7CiAgICBkZWZhdWx0OgoJYnJlYWs7CiAgICB9CmJhaWwxOgogICAgRmNNZW1GcmVlIChGQ19NRU1fVkFMTElTVCwgc2l6ZW9mIChGY1ZhbHVlTGlzdCkpOwogICAgZnJlZSAobmV3KTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUsIEZjQm9vbCBhcHBlbmQpCnsKICAgIHJldHVybiBGY1BhdHRlcm5BZGRXaXRoQmluZGluZyAocCwgb2JqZWN0LCB2YWx1ZSwgRmNWYWx1ZUJpbmRpbmdTdHJvbmcsIGFwcGVuZCk7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRXZWFrICAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIEZjVmFsdWUgdmFsdWUsIEZjQm9vbCBhcHBlbmQpCnsKICAgIHJldHVybiBGY1BhdHRlcm5BZGRXaXRoQmluZGluZyAocCwgb2JqZWN0LCB2YWx1ZSwgRmNWYWx1ZUJpbmRpbmdXZWFrLCBhcHBlbmQpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuRGVsIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCkKewogICAgRmNQYXR0ZXJuRWx0ICAgKmU7CiAgICBpbnQJCSAgICBpOwoKICAgIGUgPSBGY1BhdHRlcm5GaW5kRWx0IChwLCBvYmplY3QpOwogICAgaWYgKCFlKQoJcmV0dXJuIEZjRmFsc2U7CgogICAgaSA9IGUgLSBwLT5lbHRzOwogICAgCiAgICAvKiBkZXN0cm95IHZhbHVlICovCiAgICBGY1ZhbHVlTGlzdERlc3Ryb3kgKGUtPnZhbHVlcyk7CiAgICAKICAgIC8qIHNodWZmbGUgZXhpc3Rpbmcgb25lcyBkb3duICovCiAgICBtZW1tb3ZlIChlLCBlKzEsIChwLT5lbHRzICsgcC0+bnVtIC0gKGUgKyAxKSkgKiBzaXplb2YgKEZjUGF0dGVybkVsdCkpOwogICAgcC0+bnVtLS07CiAgICBwLT5lbHRzW3AtPm51bV0ub2JqZWN0ID0gMDsKICAgIHAtPmVsdHNbcC0+bnVtXS52YWx1ZXMgPSAwOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjUGF0dGVybkFkZEludGVnZXIgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaSkKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUludGVnZXI7CiAgICB2LnUuaSA9IGk7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGREb3VibGUgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBkb3VibGUgZCkKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZURvdWJsZTsKICAgIHYudS5kID0gZDsKICAgIHJldHVybiBGY1BhdHRlcm5BZGQgKHAsIG9iamVjdCwgdiwgRmNUcnVlKTsKfQoKCkZjQm9vbApGY1BhdHRlcm5BZGRTdHJpbmcgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlU3RyaW5nOwogICAgdi51LnMgPSBzOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkTWF0cml4IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRmNNYXRyaXggKnMpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVNYXRyaXg7CiAgICB2LnUubSA9IChGY01hdHJpeCAqKSBzOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgoKRmNCb29sCkZjUGF0dGVybkFkZEJvb2wgKEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBGY0Jvb2wgYikKewogICAgRmNWYWx1ZQl2OwoKICAgIHYudHlwZSA9IEZjVHlwZUJvb2w7CiAgICB2LnUuYiA9IGI7CiAgICByZXR1cm4gRmNQYXR0ZXJuQWRkIChwLCBvYmplY3QsIHYsIEZjVHJ1ZSk7Cn0KCkZjQm9vbApGY1BhdHRlcm5BZGRDaGFyU2V0IChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRmNDaGFyU2V0ICpjKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlQ2hhclNldDsKICAgIHYudS5jID0gKEZjQ2hhclNldCAqKSBjOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkRlRGYWNlIChGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgY29uc3QgRlRfRmFjZSBmKQp7CiAgICBGY1ZhbHVlCXY7CgogICAgdi50eXBlID0gRmNUeXBlRlRGYWNlOwogICAgdi51LmYgPSAodm9pZCAqKSBmOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY0Jvb2wKRmNQYXR0ZXJuQWRkTGFuZ1NldCAoRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGNvbnN0IEZjTGFuZ1NldCAqbHMpCnsKICAgIEZjVmFsdWUJdjsKCiAgICB2LnR5cGUgPSBGY1R5cGVMYW5nU2V0OwogICAgdi51LmwgPSAoRmNMYW5nU2V0ICopIGxzOwogICAgcmV0dXJuIEZjUGF0dGVybkFkZCAocCwgb2JqZWN0LCB2LCBGY1RydWUpOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXQgKGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjVmFsdWUgKnYpCnsKICAgIEZjUGF0dGVybkVsdCAgICplOwogICAgRmNWYWx1ZUxpc3QgICAgKmw7CgogICAgZSA9IEZjUGF0dGVybkZpbmRFbHQgKHAsIG9iamVjdCk7CiAgICBpZiAoIWUpCglyZXR1cm4gRmNSZXN1bHROb01hdGNoOwogICAgZm9yIChsID0gZS0+dmFsdWVzOyBsOyBsID0gbC0+bmV4dCkKICAgIHsKCWlmICghaWQpCgl7CgkgICAgKnYgPSBsLT52YWx1ZTsKCSAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKCX0KCWlkLS07CiAgICB9CiAgICByZXR1cm4gRmNSZXN1bHROb0lkOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRJbnRlZ2VyIChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBpbnQgKmkpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJKmkgPSAoaW50KSB2LnUuZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJKmkgPSB2LnUuaTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICB9CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0RG91YmxlIChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBkb3VibGUgKmQpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgc3dpdGNoICh2LnR5cGUpIHsKICAgIGNhc2UgRmNUeXBlRG91YmxlOgoJKmQgPSB2LnUuZDsKCWJyZWFrOwogICAgY2FzZSBGY1R5cGVJbnRlZ2VyOgoJKmQgPSAoZG91YmxlKSB2LnUuaTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRmNSZXN1bHRUeXBlTWlzbWF0Y2g7CiAgICB9CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNSZXN1bHQKRmNQYXR0ZXJuR2V0U3RyaW5nIChjb25zdCBGY1BhdHRlcm4gKnAsIGNvbnN0IGNoYXIgKm9iamVjdCwgaW50IGlkLCBGY0NoYXI4ICoqIHMpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVTdHJpbmcpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKnMgPSAoRmNDaGFyOCAqKSB2LnUuczsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRNYXRyaXgoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNNYXRyaXggKiptKQp7CiAgICBGY1ZhbHVlCXY7CiAgICBGY1Jlc3VsdAlyOwoKICAgIHIgPSBGY1BhdHRlcm5HZXQgKHAsIG9iamVjdCwgaWQsICZ2KTsKICAgIGlmIChyICE9IEZjUmVzdWx0TWF0Y2gpCglyZXR1cm4gcjsKICAgIGlmICh2LnR5cGUgIT0gRmNUeXBlTWF0cml4KQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICptID0gKEZjTWF0cml4ICopIHYudS5tOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRCb29sKGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjQm9vbCAqYikKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUJvb2wpCiAgICAgICAgcmV0dXJuIEZjUmVzdWx0VHlwZU1pc21hdGNoOwogICAgKmIgPSB2LnUuYjsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRDaGFyU2V0KGNvbnN0IEZjUGF0dGVybiAqcCwgY29uc3QgY2hhciAqb2JqZWN0LCBpbnQgaWQsIEZjQ2hhclNldCAqKmMpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVDaGFyU2V0KQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpjID0gKEZjQ2hhclNldCAqKSB2LnUuYzsKICAgIHJldHVybiBGY1Jlc3VsdE1hdGNoOwp9CgpGY1Jlc3VsdApGY1BhdHRlcm5HZXRGVEZhY2UoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRlRfRmFjZSAqZikKewogICAgRmNWYWx1ZQl2OwogICAgRmNSZXN1bHQJcjsKCiAgICByID0gRmNQYXR0ZXJuR2V0IChwLCBvYmplY3QsIGlkLCAmdik7CiAgICBpZiAociAhPSBGY1Jlc3VsdE1hdGNoKQoJcmV0dXJuIHI7CiAgICBpZiAodi50eXBlICE9IEZjVHlwZUZURmFjZSkKCXJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpmID0gKEZUX0ZhY2UpIHYudS5mOwogICAgcmV0dXJuIEZjUmVzdWx0TWF0Y2g7Cn0KCkZjUmVzdWx0CkZjUGF0dGVybkdldExhbmdTZXQoY29uc3QgRmNQYXR0ZXJuICpwLCBjb25zdCBjaGFyICpvYmplY3QsIGludCBpZCwgRmNMYW5nU2V0ICoqbHMpCnsKICAgIEZjVmFsdWUJdjsKICAgIEZjUmVzdWx0CXI7CgogICAgciA9IEZjUGF0dGVybkdldCAocCwgb2JqZWN0LCBpZCwgJnYpOwogICAgaWYgKHIgIT0gRmNSZXN1bHRNYXRjaCkKCXJldHVybiByOwogICAgaWYgKHYudHlwZSAhPSBGY1R5cGVMYW5nU2V0KQogICAgICAgIHJldHVybiBGY1Jlc3VsdFR5cGVNaXNtYXRjaDsKICAgICpscyA9IChGY0xhbmdTZXQgKikgdi51Lmw7CiAgICByZXR1cm4gRmNSZXN1bHRNYXRjaDsKfQoKRmNQYXR0ZXJuICoKRmNQYXR0ZXJuRHVwbGljYXRlIChjb25zdCBGY1BhdHRlcm4gKm9yaWcpCnsKICAgIEZjUGF0dGVybgkgICAgKm5ldzsKICAgIGludAkJICAgIGk7CiAgICBGY1ZhbHVlTGlzdCAgICAqbDsKCiAgICBuZXcgPSBGY1BhdHRlcm5DcmVhdGUgKCk7CiAgICBpZiAoIW5ldykKCWdvdG8gYmFpbDA7CgogICAgZm9yIChpID0gMDsgaSA8IG9yaWctPm51bTsgaSsrKQogICAgewoJZm9yIChsID0gb3JpZy0+ZWx0c1tpXS52YWx1ZXM7IGw7IGwgPSBsLT5uZXh0KQoJICAgIGlmICghRmNQYXR0ZXJuQWRkIChuZXcsIG9yaWctPmVsdHNbaV0ub2JqZWN0LCBsLT52YWx1ZSwgRmNUcnVlKSkKCQlnb3RvIGJhaWwxOwogICAgfQoKICAgIHJldHVybiBuZXc7CgpiYWlsMToKICAgIEZjUGF0dGVybkRlc3Ryb3kgKG5ldyk7CmJhaWwwOgogICAgcmV0dXJuIDA7Cn0KCnZvaWQKRmNQYXR0ZXJuUmVmZXJlbmNlIChGY1BhdHRlcm4gKnApCnsKICAgIGlmIChwLT5yZWYgIT0gRkNfUkVGX0NPTlNUQU5UKQoJcC0+cmVmKys7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVyblZhQnVpbGQgKEZjUGF0dGVybiAqb3JpZywgdmFfbGlzdCB2YSkKewogICAgRmNQYXR0ZXJuCSpyZXQ7CiAgICAKICAgIEZjUGF0dGVyblZhcEJ1aWxkIChyZXQsIG9yaWcsIHZhKTsKICAgIHJldHVybiByZXQ7Cn0KCkZjUGF0dGVybiAqCkZjUGF0dGVybkJ1aWxkIChGY1BhdHRlcm4gKm9yaWcsIC4uLikKewogICAgdmFfbGlzdAl2YTsKICAgIAogICAgdmFfc3RhcnQgKHZhLCBvcmlnKTsKICAgIEZjUGF0dGVyblZhcEJ1aWxkIChvcmlnLCBvcmlnLCB2YSk7CiAgICB2YV9lbmQgKHZhKTsKICAgIHJldHVybiBvcmlnOwp9Cg==