LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2xhbmcuYyx2IDEuNyAyMDAyLzA4LzI2IDIzOjM0OjMxIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAyIEtlaXRoIFBhY2thcmQsIG1lbWJlciBvZiBUaGUgWEZyZWU4NiBQcm9qZWN0LCBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSAiZmNpbnQuaCIKCnR5cGVkZWYgc3RydWN0IHsKICAgIEZjQ2hhcjgJKmxhbmc7CiAgICBGY0NoYXJTZXQJY2hhcnNldDsKfSBGY0xhbmdDaGFyU2V0OwoKI2luY2x1ZGUgIi4uL2ZjLWxhbmcvZmNsYW5nLmgiCgpzdHJ1Y3QgX0ZjTGFuZ1NldCB7CiAgICBGY0NoYXIzMgltYXBbTlVNX0xBTkdfU0VUX01BUF07CiAgICBGY1N0clNldAkqZXh0cmE7Cn07CgojZGVmaW5lIEZjTGFuZ1NldEJpdFNldChscywgaWQpCSgobHMpLT5tYXBbKGlkKT4+NV0gfD0gKChGY0NoYXIzMikgMSA8PCAoKGlkKSAmIDB4MWYpKSkKI2RlZmluZSBGY0xhbmdTZXRCaXRHZXQobHMsIGlkKSAoKChscyktPm1hcFsoaWQpPj41XSA+PiAoKGlkKSAmIDB4MWYpKSAmIDEpCgpGY0xhbmdTZXQgKgpGY0ZyZWVUeXBlTGFuZ1NldCAoY29uc3QgRmNDaGFyU2V0ICAqY2hhcnNldCwgCgkJICAgY29uc3QgRmNDaGFyOCAgICAqZXhjbHVzaXZlTGFuZykKewogICAgaW50CQkgICAgaTsKICAgIEZjQ2hhcjMyCSAgICBtaXNzaW5nOwogICAgY29uc3QgRmNDaGFyU2V0ICpleGNsdXNpdmVDaGFyc2V0ID0gMDsKICAgIEZjTGFuZ1NldAkgICAgKmxzOwogICAgCgogICAgaWYgKGV4Y2x1c2l2ZUxhbmcpCglleGNsdXNpdmVDaGFyc2V0ID0gRmNDaGFyU2V0Rm9yTGFuZyAoZXhjbHVzaXZlTGFuZyk7CiAgICBscyA9IEZjTGFuZ1NldENyZWF0ZSAoKTsKICAgIGlmICghbHMpCglyZXR1cm4gMDsKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19DSEFSX1NFVDsgaSsrKQogICAgewoJLyoKCSAqIENoZWNrIGZvciBIYW4gY2hhcnNldHMgdG8gbWFrZSBmb250cwoJICogd2hpY2ggYWR2ZXJ0aXNlIHN1cHBvcnQgZm9yIGEgc2luZ2xlIGxhbmd1YWdlCgkgKiBub3Qgc3VwcG9ydCBvdGhlciBIYW4gbGFuZ3VhZ2VzCgkgKi8KCWlmIChleGNsdXNpdmVDaGFyc2V0ICYmCgkgICAgRmNGcmVlVHlwZUlzRXhjbHVzaXZlTGFuZyAoZmNMYW5nQ2hhclNldHNbaV0ubGFuZykgJiYKCSAgICBmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0LmxlYXZlcyAhPSBleGNsdXNpdmVDaGFyc2V0LT5sZWF2ZXMpCgl7CgkgICAgY29udGludWU7Cgl9CgltaXNzaW5nID0gRmNDaGFyU2V0U3VidHJhY3RDb3VudCAoJmZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQsIGNoYXJzZXQpOwogICAgICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfU0NBTlYpCgl7CgkgICAgaWYgKG1pc3NpbmcgJiYgbWlzc2luZyA8IDEwKQoJICAgIHsKCQlGY0NoYXJTZXQgICAqbWlzc2VkID0gRmNDaGFyU2V0U3VidHJhY3QgKCZmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0LCAKCQkJCQkJCSBjaGFyc2V0KTsKCQlGY0NoYXIzMiAgICB1Y3M0OwoJCUZjQ2hhcjMyICAgIG1hcFtGQ19DSEFSU0VUX01BUF9TSVpFXTsKCQlGY0NoYXIzMiAgICBuZXh0OwoKCQlwcmludGYgKCJcbiVzKCVkKSAiLCBmY0xhbmdDaGFyU2V0c1tpXS5sYW5nLCBtaXNzaW5nKTsKCQlwcmludGYgKCJ7Iik7CgkJZm9yICh1Y3M0ID0gRmNDaGFyU2V0Rmlyc3RQYWdlIChtaXNzZWQsIG1hcCwgJm5leHQpOwoJCSAgICAgdWNzNCAhPSBGQ19DSEFSU0VUX0RPTkU7CgkJICAgICB1Y3M0ID0gRmNDaGFyU2V0TmV4dFBhZ2UgKG1pc3NlZCwgbWFwLCAmbmV4dCkpCgkJewoJCSAgICBpbnQJICAgIGksIGo7CgkJICAgIGZvciAoaSA9IDA7IGkgPCBGQ19DSEFSU0VUX01BUF9TSVpFOyBpKyspCgkJCWlmIChtYXBbaV0pCgkJCXsKCQkJICAgIGZvciAoaiA9IDA7IGogPCAzMjsgaisrKQoJCQkJaWYgKG1hcFtpXSAmICgxIDw8IGopKQoJCQkJICAgIHByaW50ZiAoIiAlMDR4IiwgdWNzNCArIGkgKiAzMiArIGopOwoJCQl9CgkJfQoJCXByaW50ZiAoIiB9XG5cdCIpOwoJCUZjQ2hhclNldERlc3Ryb3kgKG1pc3NlZCk7CgkgICAgfQoJICAgIGVsc2UKCQlwcmludGYgKCIlcyglZCkgIiwgZmNMYW5nQ2hhclNldHNbaV0ubGFuZywgbWlzc2luZyk7Cgl9CglpZiAoIW1pc3NpbmcpCgkgICAgRmNMYW5nU2V0Qml0U2V0IChscywgaSk7CiAgICB9CgogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19TQ0FOVikKCXByaW50ZiAoIlxuIik7CiAgICAKICAgIAogICAgcmV0dXJuIGxzOwp9CgojZGVmaW5lIEZjTGFuZ0VuZChjKQkoKGMpID09ICctJyB8fCAoYykgPT0gJ1wwJykKCkZjTGFuZ1Jlc3VsdApGY0xhbmdDb21wYXJlIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjgJICAgIGMxLCBjMjsKICAgIEZjTGFuZ1Jlc3VsdCAgICByZXN1bHQgPSBGY0xhbmdEaWZmZXJlbnRMYW5nOwoKICAgIGZvciAoOzspCiAgICB7CgljMSA9ICpzMSsrOwoJYzIgPSAqczIrKzsKCQoJYzEgPSBGY1RvTG93ZXIgKGMxKTsKCWMyID0gRmNUb0xvd2VyIChjMik7CglpZiAoYzEgIT0gYzIpCgl7CgkgICAgaWYgKEZjTGFuZ0VuZCAoYzEpICYmIEZjTGFuZ0VuZCAoYzIpKQoJCXJlc3VsdCA9IEZjTGFuZ0RpZmZlcmVudENvdW50cnk7CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCWVsc2UgaWYgKCFjMSkKCSAgICByZXR1cm4gRmNMYW5nRXF1YWw7CgllbHNlIGlmIChjMSA9PSAnLScpCgkgICAgcmVzdWx0ID0gRmNMYW5nRGlmZmVyZW50Q291bnRyeTsKICAgIH0KfQoKY29uc3QgRmNDaGFyU2V0ICoKRmNDaGFyU2V0Rm9yTGFuZyAoY29uc3QgRmNDaGFyOCAqbGFuZykKewogICAgaW50CQlpOwogICAgaW50CQljb3VudHJ5ID0gLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX0xBTkdfQ0hBUl9TRVQ7IGkrKykKICAgIHsKCXN3aXRjaCAoRmNMYW5nQ29tcGFyZSAobGFuZywgZmNMYW5nQ2hhclNldHNbaV0ubGFuZykpIHsKCWNhc2UgRmNMYW5nRXF1YWw6CgkgICAgcmV0dXJuICZmY0xhbmdDaGFyU2V0c1tpXS5jaGFyc2V0OwoJY2FzZSBGY0xhbmdEaWZmZXJlbnRDb3VudHJ5OgoJICAgIGlmIChjb3VudHJ5ID09IC0xKQoJCWNvdW50cnkgPSBpOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChjb3VudHJ5ID09IC0xKQoJcmV0dXJuIDA7CiAgICByZXR1cm4gJmZjTGFuZ0NoYXJTZXRzW2ldLmNoYXJzZXQ7Cn0KCkZjTGFuZ1NldCAqCkZjTGFuZ1NldENyZWF0ZSAodm9pZCkKewogICAgRmNMYW5nU2V0CSpsczsKCiAgICBscyA9IG1hbGxvYyAoc2l6ZW9mIChGY0xhbmdTZXQpKTsKICAgIGlmICghbHMpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9MQU5HU0VULCBzaXplb2YgKEZjTGFuZ1NldCkpOwogICAgbWVtc2V0IChscy0+bWFwLCAnXDAnLCBzaXplb2YgKGxzLT5tYXApKTsKICAgIGxzLT5leHRyYSA9IDA7CiAgICByZXR1cm4gbHM7Cn0KCnZvaWQKRmNMYW5nU2V0RGVzdHJveSAoRmNMYW5nU2V0ICpscykKewogICAgaWYgKGxzLT5leHRyYSkKCUZjU3RyU2V0RGVzdHJveSAobHMtPmV4dHJhKTsKICAgIEZjTWVtRnJlZSAoRkNfTUVNX0xBTkdTRVQsIHNpemVvZiAoRmNMYW5nU2V0KSk7CiAgICBmcmVlIChscyk7Cn0KCkZjTGFuZ1NldCAqCkZjTGFuZ1NldENvcHkgKGNvbnN0IEZjTGFuZ1NldCAqbHMpCnsKICAgIEZjTGFuZ1NldAkqbmV3OwoKICAgIG5ldyA9IEZjTGFuZ1NldENyZWF0ZSAoKTsKICAgIGlmICghbmV3KQoJZ290byBiYWlsMDsKICAgIG1lbWNweSAobmV3LT5tYXAsIGxzLT5tYXAsIHNpemVvZiAobmV3LT5tYXApKTsKICAgIGlmIChscy0+ZXh0cmEpCiAgICB7CglGY1N0ckxpc3QJKmxpc3Q7CglGY0NoYXI4CQkqZXh0cmE7CgkKCW5ldy0+ZXh0cmEgPSBGY1N0clNldENyZWF0ZSAoKTsKCWlmICghbmV3LT5leHRyYSkKCSAgICBnb3RvIGJhaWwxOwoKCWxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CQoJaWYgKCFsaXN0KQoJICAgIGdvdG8gYmFpbDE7CgkKCXdoaWxlICgoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgaWYgKCFGY1N0clNldEFkZCAobmV3LT5leHRyYSwgZXh0cmEpKQoJICAgIHsKCQlGY1N0ckxpc3REb25lIChsaXN0KTsKCQlnb3RvIGJhaWwxOwoJICAgIH0KCUZjU3RyTGlzdERvbmUgKGxpc3QpOwogICAgfQogICAgcmV0dXJuIG5ldzsKYmFpbDE6CiAgICBGY0xhbmdTZXREZXN0cm95IChuZXcpOwpiYWlsMDoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CkZjTGFuZ1NldEluZGV4IChjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBpbnQJICAgIGxvdywgaGlnaCwgbWlkOwogICAgaW50CSAgICBjbXA7CgogICAgbG93ID0gMDsKICAgIGhpZ2ggPSBOVU1fTEFOR19DSEFSX1NFVCAtIDE7CiAgICB3aGlsZSAobG93IDw9IGhpZ2gpCiAgICB7CgltaWQgPSAoaGlnaCArIGxvdykgPj4gMTsKCWNtcCA9IEZjU3RyQ21wSWdub3JlQ2FzZSAoZmNMYW5nQ2hhclNldHNbbWlkXS5sYW5nLCBsYW5nKTsKCWlmIChjbXAgPT0gMCkgCgkgICAgcmV0dXJuIG1pZDsKCWlmIChjbXAgPCAwKQoJICAgIGxvdyA9IG1pZCArIDE7CgllbHNlCgkgICAgaGlnaCA9IG1pZCAtIDE7CiAgICB9CiAgICBpZiAoY21wIDwgMCkKCW1pZCsrOwogICAgcmV0dXJuIC0obWlkICsgMSk7Cn0KCkZjQm9vbApGY0xhbmdTZXRBZGQgKEZjTGFuZ1NldCAqbHMsIGNvbnN0IEZjQ2hhcjggKmxhbmcpCnsKICAgIGludAkgICAgaWQ7CgogICAgaWQgPSBGY0xhbmdTZXRJbmRleCAobGFuZyk7CiAgICBpZiAoaWQgPj0gMCkKICAgIHsKCUZjTGFuZ1NldEJpdFNldCAobHMsIGlkKTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICBpZiAoIWxzLT5leHRyYSkKICAgIHsKCWxzLT5leHRyYSA9IEZjU3RyU2V0Q3JlYXRlICgpOwoJaWYgKCFscy0+ZXh0cmEpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNTdHJTZXRBZGQgKGxzLT5leHRyYSwgbGFuZyk7Cn0KCkZjTGFuZ1Jlc3VsdApGY0xhbmdTZXRIYXNMYW5nIChjb25zdCBGY0xhbmdTZXQgKmxzLCBjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBpbnQJCSAgICBpZDsKICAgIEZjTGFuZ1Jlc3VsdCAgICBiZXN0LCByOwogICAgaW50CQkgICAgaTsKCiAgICBpZCA9IEZjTGFuZ1NldEluZGV4IChsYW5nKTsKICAgIGlmIChpZCA8IDApCglpZCA9IC1pZCAtIDE7CiAgICBlbHNlIGlmIChGY0xhbmdTZXRCaXRHZXQgKGxzLCBpZCkpCglyZXR1cm4gRmNMYW5nRXF1YWw7CiAgICBiZXN0ID0gRmNMYW5nRGlmZmVyZW50TGFuZzsKICAgIGZvciAoaSA9IGlkIC0gMTsgaSA+PSAwOyBpLS0pCiAgICB7CglyID0gRmNMYW5nQ29tcGFyZSAobGFuZywgZmNMYW5nQ2hhclNldHNbaV0ubGFuZyk7CglpZiAociA9PSBGY0xhbmdEaWZmZXJlbnRMYW5nKQoJICAgIGJyZWFrOwoJaWYgKEZjTGFuZ1NldEJpdEdldCAobHMsIGkpICYmIHIgPCBiZXN0KQoJICAgIGJlc3QgPSByOwogICAgfQogICAgZm9yIChpID0gaWQ7IGkgPCBOVU1fTEFOR19DSEFSX1NFVDsgaSsrKQogICAgewoJciA9IEZjTGFuZ0NvbXBhcmUgKGxhbmcsIGZjTGFuZ0NoYXJTZXRzW2ldLmxhbmcpOwoJaWYgKHIgPT0gRmNMYW5nRGlmZmVyZW50TGFuZykKCSAgICBicmVhazsKCWlmIChGY0xhbmdTZXRCaXRHZXQgKGxzLCBpKSAmJiByIDwgYmVzdCkKCSAgICBiZXN0ID0gcjsKICAgIH0KICAgIGlmIChscy0+ZXh0cmEpCiAgICB7CglGY1N0ckxpc3QJKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CglGY0NoYXI4CQkqZXh0cmE7CglGY0xhbmdSZXN1bHQJcjsKCQoJaWYgKGxpc3QpCgl7CgkgICAgd2hpbGUgKGJlc3QgPiBGY0xhbmdFcXVhbCAmJiAoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgkgICAgewoJCXIgPSBGY0xhbmdDb21wYXJlIChsYW5nLCBleHRyYSk7CgkJaWYgKHIgPCBiZXN0KQoJCSAgICBiZXN0ID0gcjsKCSAgICB9CgkgICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7Cgl9CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQoKc3RhdGljIEZjTGFuZ1Jlc3VsdApGY0xhbmdTZXRDb21wYXJlU3RyU2V0IChjb25zdCBGY0xhbmdTZXQgKmxzLCBGY1N0clNldCAqc2V0KQp7CiAgICBGY1N0ckxpc3QJICAgICpsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChzZXQpOwogICAgRmNMYW5nUmVzdWx0ICAgIHIsIGJlc3QgPSBGY0xhbmdEaWZmZXJlbnRMYW5nOwogICAgRmNDaGFyOAkgICAgKmV4dHJhOwoKICAgIGlmIChsaXN0KQogICAgewoJd2hpbGUgKGJlc3QgPiBGY0xhbmdFcXVhbCAmJiAoZXh0cmEgPSBGY1N0ckxpc3ROZXh0IChsaXN0KSkpCgl7CgkgICAgciA9IEZjTGFuZ1NldEhhc0xhbmcgKGxzLCBleHRyYSk7CgkgICAgaWYgKHIgPCBiZXN0KQoJCWJlc3QgPSByOwoJfQoJRmNTdHJMaXN0RG9uZSAobGlzdCk7CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQoKRmNMYW5nUmVzdWx0CkZjTGFuZ1NldENvbXBhcmUgKGNvbnN0IEZjTGFuZ1NldCAqbHNhLCBjb25zdCBGY0xhbmdTZXQgKmxzYikKewogICAgaW50CQkgICAgaSwgajsKICAgIEZjTGFuZ1Jlc3VsdCAgICBiZXN0LCByOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCglpZiAobHNhLT5tYXBbaV0gJiBsc2ItPm1hcFtpXSkKCSAgICByZXR1cm4gRmNMYW5nRXF1YWw7CiAgICBiZXN0ID0gRmNMYW5nRGlmZmVyZW50TGFuZzsKICAgIGZvciAoaiA9IDA7IGogPCBOVU1fQ09VTlRSWV9TRVQ7IGorKykKCWZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCgkgICAgaWYgKChsc2EtPm1hcFtpXSAmIGZjTGFuZ0NvdW50cnlTZXRzW2pdW2ldKSAmJgoJCShsc2ItPm1hcFtpXSAmIGZjTGFuZ0NvdW50cnlTZXRzW2pdW2ldKSkKCSAgICB7CgkJYmVzdCA9IEZjTGFuZ0RpZmZlcmVudENvdW50cnk7CgkJYnJlYWs7CgkgICAgfQogICAgaWYgKGxzYS0+ZXh0cmEpCiAgICB7CglyID0gRmNMYW5nU2V0Q29tcGFyZVN0clNldCAobHNiLCBsc2EtPmV4dHJhKTsKCWlmIChyIDwgYmVzdCkKCSAgICBiZXN0ID0gcjsKICAgIH0KICAgIGlmIChiZXN0ID4gRmNMYW5nRXF1YWwgJiYgbHNiLT5leHRyYSkKICAgIHsKCXIgPSBGY0xhbmdTZXRDb21wYXJlU3RyU2V0IChsc2EsIGxzYi0+ZXh0cmEpOwoJaWYgKHIgPCBiZXN0KQoJICAgIGJlc3QgPSByOwogICAgfQogICAgcmV0dXJuIGJlc3Q7Cn0KCi8qCiAqIFVzZWQgaW4gY29tcHV0aW5nIHZhbHVlcyAtLSBtdXN0bid0IGFsbG9jYXRlIGFueSBzdG9yYWdlCiAqLwpGY0xhbmdTZXQgKgpGY0xhbmdTZXRQcm9tb3RlIChjb25zdCBGY0NoYXI4ICpsYW5nKQp7CiAgICBzdGF0aWMgRmNMYW5nU2V0CWxzOwogICAgc3RhdGljIEZjU3RyU2V0CXN0cnM7CiAgICBzdGF0aWMgRmNDaGFyOAkqc3RyOwogICAgaW50CQkJaWQ7CgogICAgbWVtc2V0IChscy5tYXAsICdcMCcsIHNpemVvZiAobHMubWFwKSk7CiAgICBscy5leHRyYSA9IDA7CiAgICBpZCA9IEZjTGFuZ1NldEluZGV4IChsYW5nKTsKICAgIGlmIChpZCA+IDApCiAgICB7CglGY0xhbmdTZXRCaXRTZXQgKCZscywgaWQpOwogICAgfQogICAgZWxzZQogICAgewoJbHMuZXh0cmEgPSAmc3RyczsKCXN0cnMubnVtID0gMTsKCXN0cnMuc2l6ZSA9IDE7CglzdHJzLnN0cnMgPSAmc3RyOwoJc3Rycy5yZWYgPSAxOwoJc3RyID0gKEZjQ2hhcjggKikgbGFuZzsKICAgIH0KICAgIHJldHVybiAmbHM7Cn0KCkZjQ2hhcjMyCkZjTGFuZ1NldEhhc2ggKGNvbnN0IEZjTGFuZ1NldCAqbHMpCnsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgaW50CQlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCgloIF49IGxzLT5tYXBbaV07CiAgICBpZiAobHMtPmV4dHJhKQoJaCBePSBscy0+ZXh0cmEtPm51bTsKICAgIHJldHVybiBoOwp9CgpGY0xhbmdTZXQgKgpGY05hbWVQYXJzZUxhbmdTZXQgKGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewogICAgRmNDaGFyOAkgICAgbGFuZ1szMl07CiAgICBjb25zdCBGY0NoYXI4ICAgKmVuZCwgKm5leHQ7CiAgICBGY0xhbmdTZXQJICAgICpsczsKCiAgICBscyA9IEZjTGFuZ1NldENyZWF0ZSAoKTsKICAgIGlmICghbHMpCglnb3RvIGJhaWwwOwoKICAgIHdoaWxlIChzdHJpbmcgJiYgKnN0cmluZykgCiAgICB7CgllbmQgPSAoRmNDaGFyOCAqKSBzdHJjaHIgKChjaGFyICopIHN0cmluZywgJ3wnKTsKCWlmICghZW5kKQoJewoJICAgIGVuZCA9IHN0cmluZyArIHN0cmxlbiAoKGNoYXIgKikgc3RyaW5nKTsKCSAgICBuZXh0ID0gZW5kOwoJfQoJZWxzZQoJICAgIG5leHQgPSBlbmQgKyAxOwoJaWYgKGVuZCAtIHN0cmluZyA8IHNpemVvZiAobGFuZykgLSAxKQoJewoJICAgIHN0cm5jcHkgKChjaGFyICopIGxhbmcsIChjaGFyICopIHN0cmluZywgZW5kIC0gc3RyaW5nKTsKCSAgICBsYW5nW2VuZC1zdHJpbmddID0gJ1wwJzsKCSAgICBpZiAoIUZjTGFuZ1NldEFkZCAobHMsIGxhbmcpKQoJCWdvdG8gYmFpbDE7Cgl9CglzdHJpbmcgPSBuZXh0OwogICAgfQogICAgcmV0dXJuIGxzOwpiYWlsMToKICAgIEZjTGFuZ1NldERlc3Ryb3kgKGxzKTsKYmFpbDA6CiAgICByZXR1cm4gMDsKfQoKRmNCb29sCkZjTmFtZVVucGFyc2VMYW5nU2V0IChGY1N0ckJ1ZiAqYnVmLCBjb25zdCBGY0xhbmdTZXQgKmxzKQp7CiAgICBpbnQJCWksIGJpdDsKICAgIEZjQ2hhcjMyCWJpdHM7CiAgICBGY0Jvb2wJZmlyc3QgPSBGY1RydWU7CgogICAgZm9yIChpID0gMDsgaSA8IE5VTV9MQU5HX1NFVF9NQVA7IGkrKykKICAgIHsKCWlmICgoYml0cyA9IGxzLT5tYXBbaV0pKQoJewoJICAgIGZvciAoYml0ID0gMDsgYml0IDw9IDMxOyBiaXQrKykKCQlpZiAoYml0cyAmICgxIDw8IGJpdCkpCgkJewoJCSAgICBpbnQgaWQgPSAoaSA8PCA1KSB8IGJpdDsKCQkgICAgaWYgKCFmaXJzdCkKCQkJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgJ3wnKSkKCQkJICAgIHJldHVybiBGY0ZhbHNlOwoJCSAgICBpZiAoIUZjU3RyQnVmU3RyaW5nIChidWYsIGZjTGFuZ0NoYXJTZXRzW2lkXS5sYW5nKSkKCQkJcmV0dXJuIEZjRmFsc2U7CgkJICAgIGZpcnN0ID0gRmNGYWxzZTsKCQl9Cgl9CiAgICB9CiAgICBpZiAobHMtPmV4dHJhKQogICAgewoJRmNTdHJMaXN0ICAgKmxpc3QgPSBGY1N0ckxpc3RDcmVhdGUgKGxzLT5leHRyYSk7CglGY0NoYXI4CSAgICAqZXh0cmE7CgoJaWYgKCFsaXN0KQoJICAgIHJldHVybiBGY0ZhbHNlOwoJd2hpbGUgKChleHRyYSA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKCXsKCSAgICBpZiAoIWZpcnN0KQoJCWlmICghRmNTdHJCdWZDaGFyIChidWYsICd8JykpCgkJICAgIHJldHVybiBGY0ZhbHNlOwoJICAgIGlmICghRmNTdHJCdWZTdHJpbmcgKGJ1ZiwgZXh0cmEpKTsKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICBmaXJzdCA9IEZjRmFsc2U7Cgl9CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNMYW5nU2V0RXF1YWwgKGNvbnN0IEZjTGFuZ1NldCAqbHNhLCBjb25zdCBGY0xhbmdTZXQgKmxzYikKewogICAgaW50CSAgICBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fTEFOR19TRVRfTUFQOyBpKyspCiAgICB7CglpZiAobHNhLT5tYXBbaV0gIT0gbHNiLT5tYXBbaV0pCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoIWxzYS0+ZXh0cmEgJiYgIWxzYi0+ZXh0cmEpCglyZXR1cm4gRmNUcnVlOwogICAgaWYgKGxzYS0+ZXh0cmEgJiYgbHNiLT5leHRyYSkKCXJldHVybiBGY1N0clNldEVxdWFsIChsc2EtPmV4dHJhLCBsc2ItPmV4dHJhKTsKICAgIHJldHVybiBGY0ZhbHNlOwp9Cg==