Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoLmNjCi8vCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBNb2RpZmllZCB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IC0gaHR0cDovL3BvcHBsZXIuZnJlZWRlc2t0b3Aub3JnCi8vCi8vIEFsbCBjaGFuZ2VzIG1hZGUgdW5kZXIgdGhlIFBvcHBsZXIgcHJvamVjdCB0byB0aGlzIGZpbGUgYXJlIGxpY2Vuc2VkCi8vIHVuZGVyIEdQTCB2ZXJzaW9uIDIgb3IgbGF0ZXIKLy8KLy8gQ29weXJpZ2h0IChDKSAyMDA1LTIwMTIgQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vIENvcHlyaWdodCAoQykgMjAwNSBNYXJjbyBQZXNlbnRpIEdyaXR0aSA8bXBnQHJlZGhhdC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMC0yMDEyIFRob21hcyBGcmVpdGFnIDxUaG9tYXMuRnJlaXRhZ0BhbGZhLmRlPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgQ2hyaXN0aWFuIEZldWVyc+RuZ2VyIDxjZmV1ZXJzYWVuZ2VyQGdvb2dsZW1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTEsIDIwMTIgV2lsbGlhbSBCYWRlciA8d2lsbGlhbWJhZGVyQGhvdG1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgTWFya3VzIFRyaXBwZWxzZG9yZiA8bWFya3VzQHRyaXBwZWxzZG9yZi5kZT4KLy8KLy8gVG8gc2VlIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNoYW5nZXMgcGxlYXNlIHNlZSB0aGUgQ2hhbmdlbG9nIGZpbGUgdGhhdAovLyBjYW1lIHdpdGggeW91ciB0YXJiYWxsIG9yIHR5cGUgbWFrZSBDaGFuZ2VMb2cgaWYgeW91IGFyZSBidWlsZGluZyBmcm9tIGdpdAovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgPGNvbmZpZy5oPgoKI2lmZGVmIFVTRV9HQ0NfUFJBR01BUwojcHJhZ21hIGltcGxlbWVudGF0aW9uCiNlbmRpZgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8bWF0aC5oPgojaW5jbHVkZSAiZ29vL2dtZW0uaCIKI2luY2x1ZGUgImdvby9Hb29MaWtlbHkuaCIKI2luY2x1ZGUgImdvby9Hb29MaXN0LmgiCiNpbmNsdWRlICJwb3BwbGVyL0Vycm9yLmgiCiNpbmNsdWRlICJTcGxhc2hFcnJvckNvZGVzLmgiCiNpbmNsdWRlICJTcGxhc2hNYXRoLmgiCiNpbmNsdWRlICJTcGxhc2hCaXRtYXAuaCIKI2luY2x1ZGUgIlNwbGFzaFN0YXRlLmgiCiNpbmNsdWRlICJTcGxhc2hQYXRoLmgiCiNpbmNsdWRlICJTcGxhc2hYUGF0aC5oIgojaW5jbHVkZSAiU3BsYXNoWFBhdGhTY2FubmVyLmgiCiNpbmNsdWRlICJTcGxhc2hQYXR0ZXJuLmgiCiNpbmNsdWRlICJTcGxhc2hTY3JlZW4uaCIKI2luY2x1ZGUgIlNwbGFzaEZvbnQuaCIKI2luY2x1ZGUgIlNwbGFzaEdseXBoQml0bWFwLmgiCiNpbmNsdWRlICJTcGxhc2guaCIKI2luY2x1ZGUgPGFsZ29yaXRobT4KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojZGVmaW5lIHNwbGFzaEFBR2FtbWEgMS41CgovLyBkaXN0YW5jZSBvZiBCZXppZXIgY29udHJvbCBwb2ludCBmcm9tIGNlbnRlciBmb3IgY2lyY2xlIGFwcHJveGltYXRpb24KLy8gPSAoNCAqIChzcXJ0KDIpIC0gMSkgLyAzKSAqIHIKI2RlZmluZSBiZXppZXJDaXJjbGUgKChTcGxhc2hDb29yZCkwLjU1MjI4NDc1KQojZGVmaW5lIGJlemllckNpcmNsZTIgKChTcGxhc2hDb29yZCkoMC41ICogMC41NTIyODQ3NSkpCgovLyBEaXZpZGUgYSAxNi1iaXQgdmFsdWUgKGluIFswLCAyNTUqMjU1XSkgYnkgMjU1LCByZXR1cm5pbmcgYW4gOC1iaXQgcmVzdWx0LgpzdGF0aWMgaW5saW5lIEd1Y2hhciBkaXYyNTUoaW50IHgpIHsKICByZXR1cm4gKEd1Y2hhcikoKHggKyAoeCA+PiA4KSArIDB4ODApID4+IDgpOwp9CgovLyBDbGlwIHggdG8gbGllIGluIFswLCAyNTVdLgpzdGF0aWMgaW5saW5lIEd1Y2hhciBjbGlwMjU1KGludCB4KSB7CiAgcmV0dXJuIHggPCAwID8gMCA6IHggPiAyNTUgPyAyNTUgOiB4Owp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgppbmxpbmUgdm9pZCBHdXN3YXAoIFQmYSwgVCZiICkgeyBUIHRtcCA9IGE7IGE9YjsgYj10bXA7IH0KCi8vIFRoZSBQREYgc3BlYyBzYXlzIHRoYXQgYWxsIHBpeGVscyB3aG9zZSAqY2VudGVycyogbGllIHdpdGhpbiB0aGUKLy8gaW1hZ2UgdGFyZ2V0IHJlZ2lvbiBnZXQgcGFpbnRlZCwgc28gd2Ugd2FudCB0byByb3VuZCBuKzAuNSBkb3duIHRvCi8vIG4uICBCdXQgdGhpcyBjYXVzZXMgcHJvYmxlbXMsIGUuZy4sIHdpdGggUERGIGZpbGVzIHRoYXQgZmlsbCBhCi8vIHJlY3RhbmdsZSB3aXRoIGJsYWNrIGFuZCB0aGVuIGRyYXcgYW4gaW1hZ2UgdG8gdGhlIGV4YWN0IHNhbWUKLy8gcmVjdGFuZ2xlLCBzbyB3ZSBpbnN0ZWFkIHVzZSB0aGUgZmlsbCBzY2FuIGNvbnZlcnNpb24gcnVsZS4KLy8gSG93ZXZlciwgdGhlIGNvcnJlY3QgcnVsZSB3b3JrcyBiZXR0ZXIgZm9yIGdseXBocywgc28gd2UgYWxzbwovLyBwcm92aWRlIHRoYXQgb3B0aW9uIGluIGZpbGxJbWFnZU1hc2suCiNpZiAwCnN0YXRpYyBpbmxpbmUgaW50IGltZ0Nvb3JkTXVuZ2VMb3dlcihTcGxhc2hDb29yZCB4KSB7CiAgcmV0dXJuIHNwbGFzaENlaWwoeCArIDAuNSkgLSAxOwp9CnN0YXRpYyBpbmxpbmUgaW50IGltZ0Nvb3JkTXVuZ2VVcHBlcihTcGxhc2hDb29yZCB4KSB7CiAgcmV0dXJuIHNwbGFzaENlaWwoeCArIDAuNSkgLSAxOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgaW50IGltZ0Nvb3JkTXVuZ2VMb3dlcihTcGxhc2hDb29yZCB4KSB7CiAgcmV0dXJuIHNwbGFzaEZsb29yKHgpOwp9CnN0YXRpYyBpbmxpbmUgaW50IGltZ0Nvb3JkTXVuZ2VVcHBlcihTcGxhc2hDb29yZCB4KSB7CiAgcmV0dXJuIHNwbGFzaEZsb29yKHgpICsgMTsKfQpzdGF0aWMgaW5saW5lIGludCBpbWdDb29yZE11bmdlTG93ZXJDKFNwbGFzaENvb3JkIHgsIEdCb29sIGdseXBoTW9kZSkgewogIHJldHVybiBnbHlwaE1vZGUgPyAoc3BsYXNoQ2VpbCh4ICsgMC41KSAtIDEpIDogc3BsYXNoRmxvb3IoeCk7Cn0Kc3RhdGljIGlubGluZSBpbnQgaW1nQ29vcmRNdW5nZVVwcGVyQyhTcGxhc2hDb29yZCB4LCBHQm9vbCBnbHlwaE1vZGUpIHsKICByZXR1cm4gZ2x5cGhNb2RlID8gKHNwbGFzaENlaWwoeCArIDAuNSkgLSAxKSA6IChzcGxhc2hGbG9vcih4KSArIDEpOwp9CiNlbmRpZgoKLy8gVXNlZCBieSBkcmF3SW1hZ2UgYW5kIGZpbGxJbWFnZU1hc2sgdG8gZGl2aWRlIHRoZSB0YXJnZXQKLy8gcXVhZHJpbGF0ZXJhbCBpbnRvIHNlY3Rpb25zLgpzdHJ1Y3QgSW1hZ2VTZWN0aW9uIHsKICBpbnQgeTAsIHkxOwkJCQkvLyBhY3R1YWwgeSByYW5nZQogIGludCBpYTAsIGlhMTsJCQkJLy8gdmVydGV4IGluZGljZXMgZm9yIGVkZ2UgQQogIGludCBpYjAsIGliMTsJCQkJLy8gdmVydGV4IGluZGljZXMgZm9yIGVkZ2UgQQogIFNwbGFzaENvb3JkIHhhMCwgeWEwLCB4YTEsIHlhMTsJLy8gZWRnZSBBCiAgU3BsYXNoQ29vcmQgZHhkeWE7CQkJLy8gc2xvcGUgb2YgZWRnZSBBCiAgU3BsYXNoQ29vcmQgeGIwLCB5YjAsIHhiMSwgeWIxOwkvLyBlZGdlIEIKICBTcGxhc2hDb29yZCBkeGR5YjsJCQkvLyBzbG9wZSBvZiBlZGdlIEIKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFNwbGFzaFBpcGUKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgc3BsYXNoUGlwZU1heFN0YWdlcyA5CgpzdHJ1Y3QgU3BsYXNoUGlwZSB7CiAgLy8gcGl4ZWwgY29vcmRpbmF0ZXMKICBpbnQgeCwgeTsKCiAgLy8gc291cmNlIHBhdHRlcm4KICBTcGxhc2hQYXR0ZXJuICpwYXR0ZXJuOwoKICAvLyBzb3VyY2UgYWxwaGEgYW5kIGNvbG9yCiAgR3VjaGFyIGFJbnB1dDsKICBHQm9vbCB1c2VzU2hhcGU7CiAgU3BsYXNoQ29sb3JQdHIgY1NyYzsKICBTcGxhc2hDb2xvciBjU3JjVmFsOwoKICAvLyBub24taXNvbGF0ZWQgZ3JvdXAgYWxwaGEwCiAgR3VjaGFyICphbHBoYTBQdHI7CgogIC8vIGtub2Nrb3V0IGdyb3VwcwogIEdCb29sIGtub2Nrb3V0OwogIEd1Y2hhciBrbm9ja291dE9wYWNpdHk7CgogIC8vIHNvZnQgbWFzawogIFNwbGFzaENvbG9yUHRyIHNvZnRNYXNrUHRyOwoKICAvLyBkZXN0aW5hdGlvbiBhbHBoYSBhbmQgY29sb3IKICBTcGxhc2hDb2xvclB0ciBkZXN0Q29sb3JQdHI7CiAgaW50IGRlc3RDb2xvck1hc2s7CiAgR3VjaGFyICpkZXN0QWxwaGFQdHI7CgogIC8vIHNoYXBlCiAgR3VjaGFyIHNoYXBlOwoKICAvLyByZXN1bHQgYWxwaGEgYW5kIGNvbG9yCiAgR0Jvb2wgbm9UcmFuc3BhcmVuY3k7CiAgU3BsYXNoUGlwZVJlc3VsdENvbG9yQ3RybCByZXN1bHRDb2xvckN0cmw7CgogIC8vIG5vbi1pc29sYXRlZCBncm91cCBjb3JyZWN0aW9uCiAgR0Jvb2wgbm9uSXNvbGF0ZWRHcm91cDsKCiAgLy8gdGhlICJydW4iIGZ1bmN0aW9uCiAgdm9pZCAoU3BsYXNoOjoqcnVuKShTcGxhc2hQaXBlICpwaXBlKTsKfTsKClNwbGFzaFBpcGVSZXN1bHRDb2xvckN0cmwgU3BsYXNoOjpwaXBlUmVzdWx0Q29sb3JOb0FscGhhQmxlbmRbXSA9IHsKICBzcGxhc2hQaXBlUmVzdWx0Q29sb3JOb0FscGhhQmxlbmRNb25vLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZE1vbm8sCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yTm9BbHBoYUJsZW5kUkdCLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZFJHQiwKICBzcGxhc2hQaXBlUmVzdWx0Q29sb3JOb0FscGhhQmxlbmRSR0IKI2lmIFNQTEFTSF9DTVlLCiAgLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZENNWUssCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yTm9BbHBoYUJsZW5kRGV2aWNlTgojZW5kaWYKfTsKClNwbGFzaFBpcGVSZXN1bHRDb2xvckN0cmwgU3BsYXNoOjpwaXBlUmVzdWx0Q29sb3JBbHBoYU5vQmxlbmRbXSA9IHsKICBzcGxhc2hQaXBlUmVzdWx0Q29sb3JBbHBoYU5vQmxlbmRNb25vLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvckFscGhhTm9CbGVuZE1vbm8sCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFOb0JsZW5kUkdCLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZFJHQiwKICBzcGxhc2hQaXBlUmVzdWx0Q29sb3JBbHBoYU5vQmxlbmRSR0IKI2lmIFNQTEFTSF9DTVlLCiAgLAogIHNwbGFzaFBpcGVSZXN1bHRDb2xvckFscGhhTm9CbGVuZENNWUssCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFOb0JsZW5kRGV2aWNlTgojZW5kaWYKfTsKClNwbGFzaFBpcGVSZXN1bHRDb2xvckN0cmwgU3BsYXNoOjpwaXBlUmVzdWx0Q29sb3JBbHBoYUJsZW5kW10gPSB7CiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZE1vbm8sCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZE1vbm8sCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZFJHQiwKICBzcGxhc2hQaXBlUmVzdWx0Q29sb3JOb0FscGhhQmxlbmRSR0IsCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZFJHQgojaWYgU1BMQVNIX0NNWUsKICAsCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZENNWUssCiAgc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZERldmljZU4KI2VuZGlmCn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIHZvaWQgYmxlbmRYb3IoU3BsYXNoQ29sb3JQdHIgc3JjLCBTcGxhc2hDb2xvclB0ciBkZXN0LAoJCSAgICAgU3BsYXNoQ29sb3JQdHIgYmxlbmQsIFNwbGFzaENvbG9yTW9kZSBjbSkgewogIGludCBpOwoKICBmb3IgKGkgPSAwOyBpIDwgc3BsYXNoQ29sb3JNb2RlTkNvbXBzW2NtXTsgKytpKSB7CiAgICBibGVuZFtpXSA9IHNyY1tpXSBeIGRlc3RbaV07CiAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBtb2RpZmllZCByZWdpb24KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3BsYXNoOjpjbGVhck1vZFJlZ2lvbigpIHsKICBtb2RYTWluID0gYml0bWFwLT5nZXRXaWR0aCgpOwogIG1vZFlNaW4gPSBiaXRtYXAtPmdldEhlaWdodCgpOwogIG1vZFhNYXggPSAtMTsKICBtb2RZTWF4ID0gLTE7Cn0KCmlubGluZSB2b2lkIFNwbGFzaDo6dXBkYXRlTW9kWChpbnQgeCkgewogIGlmICh4IDwgbW9kWE1pbikgewogICAgbW9kWE1pbiA9IHg7CiAgfQogIGlmICh4ID4gbW9kWE1heCkgewogICAgbW9kWE1heCA9IHg7CiAgfQp9CgppbmxpbmUgdm9pZCBTcGxhc2g6OnVwZGF0ZU1vZFkoaW50IHkpIHsKICBpZiAoeSA8IG1vZFlNaW4pIHsKICAgIG1vZFlNaW4gPSB5OwogIH0KICBpZiAoeSA+IG1vZFlNYXgpIHsKICAgIG1vZFlNYXggPSB5OwogIH0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gcGlwZWxpbmUKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSB2b2lkIFNwbGFzaDo6cGlwZUluaXQoU3BsYXNoUGlwZSAqcGlwZSwgaW50IHgsIGludCB5LAoJCQkgICAgIFNwbGFzaFBhdHRlcm4gKnBhdHRlcm4sIFNwbGFzaENvbG9yUHRyIGNTcmMsCgkJCSAgICAgR3VjaGFyIGFJbnB1dCwgR0Jvb2wgdXNlc1NoYXBlLAoJCQkgICAgIEdCb29sIG5vbklzb2xhdGVkR3JvdXAsCgkJCSAgICAgR0Jvb2wga25vY2tvdXQsIEd1Y2hhciBrbm9ja291dE9wYWNpdHkpIHsKICBwaXBlU2V0WFkocGlwZSwgeCwgeSk7CiAgcGlwZS0+cGF0dGVybiA9IE5VTEw7CgogIC8vIHNvdXJjZSBjb2xvcgogIGlmIChwYXR0ZXJuKSB7CiAgICBpZiAocGF0dGVybi0+aXNTdGF0aWMoKSkgewogICAgICBwYXR0ZXJuLT5nZXRDb2xvcih4LCB5LCBwaXBlLT5jU3JjVmFsKTsKICAgIH0gZWxzZSB7CiAgICAgIHBpcGUtPnBhdHRlcm4gPSBwYXR0ZXJuOwogICAgfQogICAgcGlwZS0+Y1NyYyA9IHBpcGUtPmNTcmNWYWw7CiAgfSBlbHNlIHsKICAgIHBpcGUtPmNTcmMgPSBjU3JjOwogIH0KCiAgLy8gc291cmNlIGFscGhhCiAgcGlwZS0+YUlucHV0ID0gYUlucHV0OwogIHBpcGUtPnVzZXNTaGFwZSA9IHVzZXNTaGFwZTsKCiAgLy8ga25vY2tvdXQKICBwaXBlLT5rbm9ja291dCA9IGtub2Nrb3V0OwogIHBpcGUtPmtub2Nrb3V0T3BhY2l0eSA9IGtub2Nrb3V0T3BhY2l0eTsKCiAgLy8gcmVzdWx0IGFscGhhCiAgaWYgKGFJbnB1dCA9PSAyNTUgJiYgIXN0YXRlLT5zb2Z0TWFzayAmJiAhdXNlc1NoYXBlICYmCiAgICAgICFzdGF0ZS0+aW5Ob25Jc29sYXRlZEdyb3VwICYmICFub25Jc29sYXRlZEdyb3VwKSB7CiAgICBwaXBlLT5ub1RyYW5zcGFyZW5jeSA9IGdUcnVlOwogIH0gZWxzZSB7CiAgICBwaXBlLT5ub1RyYW5zcGFyZW5jeSA9IGdGYWxzZTsKICB9CgogIC8vIHJlc3VsdCBjb2xvcgogIGlmIChwaXBlLT5ub1RyYW5zcGFyZW5jeSkgewogICAgLy8gdGhlICFzdGF0ZS0+YmxlbmRGdW5jIGNhc2UgaXMgaGFuZGxlZCBzZXBhcmF0ZWx5IGluIHBpcGVSdW4KICAgIHBpcGUtPnJlc3VsdENvbG9yQ3RybCA9IHBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZFtiaXRtYXAtPm1vZGVdOwogIH0gZWxzZSBpZiAoIXN0YXRlLT5ibGVuZEZ1bmMpIHsKICAgIHBpcGUtPnJlc3VsdENvbG9yQ3RybCA9IHBpcGVSZXN1bHRDb2xvckFscGhhTm9CbGVuZFtiaXRtYXAtPm1vZGVdOwogIH0gZWxzZSB7CiAgICBwaXBlLT5yZXN1bHRDb2xvckN0cmwgPSBwaXBlUmVzdWx0Q29sb3JBbHBoYUJsZW5kW2JpdG1hcC0+bW9kZV07CiAgfQoKICAvLyBub24taXNvbGF0ZWQgZ3JvdXAgY29ycmVjdGlvbgogIHBpcGUtPm5vbklzb2xhdGVkR3JvdXAgPSBub25Jc29sYXRlZEdyb3VwOwoKICAvLyBzZWxlY3QgdGhlICdydW4nIGZ1bmN0aW9uCiAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1bjsKICBpZiAoIXBpcGUtPnBhdHRlcm4gJiYgcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5ibGVuZEZ1bmMpIHsKICAgIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm8xICYmICFwaXBlLT5kZXN0QWxwaGFQdHIpIHsKICAgICAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1blNpbXBsZU1vbm8xOwogICAgfSBlbHNlIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm84ICYmIHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgICBwaXBlLT5ydW4gPSAmU3BsYXNoOjpwaXBlUnVuU2ltcGxlTW9ubzg7CiAgICB9IGVsc2UgaWYgKGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlUkdCOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIpIHsKICAgICAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1blNpbXBsZVJHQjg7CiAgICB9IGVsc2UgaWYgKGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlWEJHUjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5TaW1wbGVYQkdSODsKICAgIH0gZWxzZSBpZiAoYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVCR1I4ICYmIHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgICBwaXBlLT5ydW4gPSAmU3BsYXNoOjpwaXBlUnVuU2ltcGxlQkdSODsKI2lmIFNQTEFTSF9DTVlLCiAgICB9IGVsc2UgaWYgKGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlQ01ZSzggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5TaW1wbGVDTVlLODsKICAgIH0gZWxzZSBpZiAoYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVEZXZpY2VOOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIpIHsKICAgICAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1blNpbXBsZURldmljZU44OwojZW5kaWYKICAgIH0KICB9IGVsc2UgaWYgKCFwaXBlLT5wYXR0ZXJuICYmICFwaXBlLT5ub1RyYW5zcGFyZW5jeSAmJiAhc3RhdGUtPnNvZnRNYXNrICYmCgkgICAgIHBpcGUtPnVzZXNTaGFwZSAmJgoJICAgICAhKHN0YXRlLT5pbk5vbklzb2xhdGVkR3JvdXAgJiYgYWxwaGEwQml0bWFwLT5hbHBoYSkgJiYKCSAgICAgIXN0YXRlLT5ibGVuZEZ1bmMgJiYgIXBpcGUtPm5vbklzb2xhdGVkR3JvdXApIHsKICAgIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm8xICYmICFwaXBlLT5kZXN0QWxwaGFQdHIpIHsKICAgICAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1bkFBTW9ubzE7CiAgICB9IGVsc2UgaWYgKGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlTW9ubzggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5BQU1vbm84OwogICAgfSBlbHNlIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZVJHQjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5BQVJHQjg7CiAgICB9IGVsc2UgaWYgKGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlWEJHUjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5BQVhCR1I4OwogICAgfSBlbHNlIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZUJHUjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgIHBpcGUtPnJ1biA9ICZTcGxhc2g6OnBpcGVSdW5BQUJHUjg7CiNpZiBTUExBU0hfQ01ZSwogICAgfSBlbHNlIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZUNNWUs4ICYmIHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgICBwaXBlLT5ydW4gPSAmU3BsYXNoOjpwaXBlUnVuQUFDTVlLODsKICAgIH0gZWxzZSBpZiAoYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVEZXZpY2VOOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIpIHsKICAgICAgcGlwZS0+cnVuID0gJlNwbGFzaDo6cGlwZVJ1bkFBRGV2aWNlTjg7CiNlbmRpZgogICAgfQogIH0KfQoKLy8gZ2VuZXJhbCBjYXNlCnZvaWQgU3BsYXNoOjpwaXBlUnVuKFNwbGFzaFBpcGUgKnBpcGUpIHsKICBHdWNoYXIgYVNyYywgYURlc3QsIGFscGhhSSwgYWxwaGFJbTEsIGFscGhhMCwgYVJlc3VsdDsKICBTcGxhc2hDb2xvciBjU3JjTm9uSXNvLCBjRGVzdCwgY0JsZW5kOwogIFNwbGFzaENvbG9yUHRyIGNTcmM7CiAgR3VjaGFyIGNSZXN1bHQwLCBjUmVzdWx0MSwgY1Jlc3VsdDIsIGNSZXN1bHQzOwogIGludCB0OwojaWYgU1BMQVNIX0NNWUsKICBpbnQgY3AsIG1hc2s7CiAgR3VjaGFyIGNSZXN1bHRbU1BPVF9OQ09NUFMrNF07CiNlbmRpZgoKICAvLy0tLS0tIHNvdXJjZSBjb2xvcgoKICAvLyBzdGF0aWMgcGF0dGVybjogaGFuZGxlZCBpbiBwaXBlSW5pdAogIC8vIGZpeGVkIGNvbG9yOiBoYW5kbGVkIGluIHBpcGVJbml0CgogIC8vIGR5bmFtaWMgcGF0dGVybgogIGlmIChwaXBlLT5wYXR0ZXJuKSB7CiAgICBpZiAoIXBpcGUtPnBhdHRlcm4tPmdldENvbG9yKHBpcGUtPngsIHBpcGUtPnksIHBpcGUtPmNTcmNWYWwpKSB7CgkJcGlwZUluY1gocGlwZSk7CgkJcmV0dXJuOwogICAgfQogIH0KCiAgaWYgKHBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+YmxlbmRGdW5jKSB7CgogICAgLy8tLS0tLSB3cml0ZSBkZXN0aW5hdGlvbiBwaXhlbAoKICAgIHN3aXRjaCAoYml0bWFwLT5tb2RlKSB7CiAgICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgICAgY1Jlc3VsdDAgPSBzdGF0ZS0+Z3JheVRyYW5zZmVyW3BpcGUtPmNTcmNbMF1dOwogICAgICBpZiAoc3RhdGUtPnNjcmVlbi0+dGVzdChwaXBlLT54LCBwaXBlLT55LCBjUmVzdWx0MCkpIHsKCSpwaXBlLT5kZXN0Q29sb3JQdHIgfD0gcGlwZS0+ZGVzdENvbG9yTWFzazsKICAgICAgfSBlbHNlIHsKCSpwaXBlLT5kZXN0Q29sb3JQdHIgJj0gfnBpcGUtPmRlc3RDb2xvck1hc2s7CiAgICAgIH0KICAgICAgaWYgKCEocGlwZS0+ZGVzdENvbG9yTWFzayA+Pj0gMSkpIHsKCXBpcGUtPmRlc3RDb2xvck1hc2sgPSAweDgwOwoJKytwaXBlLT5kZXN0Q29sb3JQdHI7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPmdyYXlUcmFuc2ZlcltwaXBlLT5jU3JjWzBdXTsKICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJSW3BpcGUtPmNTcmNbMF1dOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJHW3BpcGUtPmNTcmNbMV1dOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW3BpcGUtPmNTcmNbMl1dOwogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW3BpcGUtPmNTcmNbMl1dOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJHW3BpcGUtPmNTcmNbMV1dOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJSW3BpcGUtPmNTcmNbMF1dOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSAyNTU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyQltwaXBlLT5jU3JjWzJdXTsKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyR1twaXBlLT5jU3JjWzFdXTsKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyUltwaXBlLT5jU3JjWzBdXTsKICAgICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDEpIHsKCXBpcGUtPmRlc3RDb2xvclB0clswXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMF0gKyBzdGF0ZS0+Y215a1RyYW5zZmVyQ1twaXBlLT5jU3JjWzBdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2ZlckNbcGlwZS0+Y1NyY1swXV07CiAgICAgIH0KICAgICAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgMikgewoJcGlwZS0+ZGVzdENvbG9yUHRyWzFdID0gKHN0YXRlLT5vdmVycHJpbnRBZGRpdGl2ZSkgPyAKICAgICAgICAgICAgICBzdGQ6Om1pbjxpbnQ+KHBpcGUtPmRlc3RDb2xvclB0clsxXSArIHN0YXRlLT5jbXlrVHJhbnNmZXJNW3BpcGUtPmNTcmNbMV1dLCAyNTUpIDoKICAgICAgICAgICAgICBzdGF0ZS0+Y215a1RyYW5zZmVyTVtwaXBlLT5jU3JjWzFdXTsKICAgICAgfQogICAgICBpZiAoc3RhdGUtPm92ZXJwcmludE1hc2sgJiA0KSB7CglwaXBlLT5kZXN0Q29sb3JQdHJbMl0gPSAoc3RhdGUtPm92ZXJwcmludEFkZGl0aXZlKSA/IAogICAgICAgICAgICAgIHN0ZDo6bWluPGludD4ocGlwZS0+ZGVzdENvbG9yUHRyWzJdICsgc3RhdGUtPmNteWtUcmFuc2ZlcllbcGlwZS0+Y1NyY1syXV0sIDI1NSkgOgogICAgICAgICAgICAgIHN0YXRlLT5jbXlrVHJhbnNmZXJZW3BpcGUtPmNTcmNbMl1dOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDgpIHsKCXBpcGUtPmRlc3RDb2xvclB0clszXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbM10gKyBzdGF0ZS0+Y215a1RyYW5zZmVyS1twaXBlLT5jU3JjWzNdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2ZlcktbcGlwZS0+Y1NyY1szXV07CiAgICAgIH0KICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IDQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAgIG1hc2sgPSAxOwogICAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUyArIDQ7IGNwICsrKSB7CiAgICAgICAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgbWFzaykgewogICAgICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyW2NwXSA9IHN0YXRlLT5kZXZpY2VOVHJhbnNmZXJbY3BdW3BpcGUtPmNTcmNbY3BdXTsKICAgICAgICB9CiAgICAgICAgbWFzayA8PD0gMTsKICAgICAgfQogICAgICBwaXBlLT5kZXN0Q29sb3JQdHIgKz0gKFNQT1RfTkNPTVBTKzQpOwogICAgICBicmVhazsKI2VuZGlmCiAgICB9CiAgICBpZiAocGlwZS0+ZGVzdEFscGhhUHRyKSB7CiAgICAgICpwaXBlLT5kZXN0QWxwaGFQdHIrKyA9IDI1NTsKICAgIH0KCiAgfSBlbHNlIHsKCiAgICAvLy0tLS0tIHJlYWQgZGVzdGluYXRpb24gcGl4ZWwKCiAgICBzd2l0Y2ggKGJpdG1hcC0+bW9kZSkgewogICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICAgIGNEZXN0WzBdID0gKCpwaXBlLT5kZXN0Q29sb3JQdHIgJiBwaXBlLT5kZXN0Q29sb3JNYXNrKSA/IDB4ZmYgOiAweDAwOwogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgICBjRGVzdFswXSA9ICpwaXBlLT5kZXN0Q29sb3JQdHI7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgICAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMF07CiAgICAgIGNEZXN0WzFdID0gcGlwZS0+ZGVzdENvbG9yUHRyWzFdOwogICAgICBjRGVzdFsyXSA9IHBpcGUtPmRlc3RDb2xvclB0clsyXTsKICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVYQkdSODoKICAgICAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgICAgIGNEZXN0WzFdID0gcGlwZS0+ZGVzdENvbG9yUHRyWzFdOwogICAgICBjRGVzdFsyXSA9IHBpcGUtPmRlc3RDb2xvclB0clswXTsKICAgICAgY0Rlc3RbM10gPSAyNTU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgICAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgICAgIGNEZXN0WzFdID0gcGlwZS0+ZGVzdENvbG9yUHRyWzFdOwogICAgICBjRGVzdFsyXSA9IHBpcGUtPmRlc3RDb2xvclB0clswXTsKICAgICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICAgIGNEZXN0WzBdID0gcGlwZS0+ZGVzdENvbG9yUHRyWzBdOwogICAgICBjRGVzdFsxXSA9IHBpcGUtPmRlc3RDb2xvclB0clsxXTsKICAgICAgY0Rlc3RbMl0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgICAgIGNEZXN0WzNdID0gcGlwZS0+ZGVzdENvbG9yUHRyWzNdOwogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUyArIDQ7IGNwKyspCiAgICAgICAgY0Rlc3RbY3BdID0gcGlwZS0+ZGVzdENvbG9yUHRyW2NwXTsKICAgICAgYnJlYWs7CiNlbmRpZgogICAgfQogICAgaWYgKHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgICBhRGVzdCA9ICpwaXBlLT5kZXN0QWxwaGFQdHI7CiAgICB9IGVsc2UgewogICAgICBhRGVzdCA9IDB4ZmY7CiAgICB9CgogICAgLy8tLS0tLSBzb3VyY2UgYWxwaGEKCiAgICBpZiAoc3RhdGUtPnNvZnRNYXNrKSB7CiAgICAgIGlmIChwaXBlLT51c2VzU2hhcGUpIHsKCWFTcmMgPSBkaXYyNTUoZGl2MjU1KHBpcGUtPmFJbnB1dCAqICpwaXBlLT5zb2Z0TWFza1B0cisrKSAqCgkJICAgICAgcGlwZS0+c2hhcGUpOwogICAgICB9IGVsc2UgewoJYVNyYyA9IGRpdjI1NShwaXBlLT5hSW5wdXQgKiAqcGlwZS0+c29mdE1hc2tQdHIrKyk7CiAgICAgIH0KICAgIH0gZWxzZSBpZiAocGlwZS0+dXNlc1NoYXBlKSB7CiAgICAgIGFTcmMgPSBkaXYyNTUocGlwZS0+YUlucHV0ICogcGlwZS0+c2hhcGUpOwogICAgfSBlbHNlIHsKICAgICAgYVNyYyA9IHBpcGUtPmFJbnB1dDsKICAgIH0KCiAgICAvLy0tLS0tIG5vbi1pc29sYXRlZCBncm91cCBjb3JyZWN0aW9uCgogICAgaWYgKHBpcGUtPm5vbklzb2xhdGVkR3JvdXApIHsKICAgICAgLy8gVGhpcyBwYXRoIGlzIG9ubHkgdXNlZCB3aGVuIFNwbGFzaDo6Y29tcG9zaXRlKCkgaXMgY2FsbGVkIHRvCiAgICAgIC8vIGNvbXBvc2l0ZSBhIG5vbi1pc29sYXRlZCBncm91cCBvbnRvIHRoZSBiYWNrZHJvcC4gIEluIHRoaXMKICAgICAgLy8gY2FzZSwgcGlwZS0+c2hhcGUgaXMgdGhlIHNvdXJjZSAoZ3JvdXApIGFscGhhLgogICAgICBpZiAocGlwZS0+c2hhcGUgPT0gMCkgewoJLy8gdGhpcyB2YWx1ZSB3aWxsIGJlIG11bHRpcGxpZWQgYnkgemVybyBsYXRlciwgc28gaXQgZG9lc24ndAoJLy8gbWF0dGVyIHdoYXQgd2UgdXNlCgljU3JjID0gcGlwZS0+Y1NyYzsKICAgICAgfSBlbHNlIHsKCXQgPSAoYURlc3QgKiAyNTUpIC8gcGlwZS0+c2hhcGUgLSBhRGVzdDsKCXN3aXRjaCAoYml0bWFwLT5tb2RlKSB7CiNpZiBTUExBU0hfQ01ZSwoJY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CgkgIGZvciAoY3AgPSA0OyBjcCA8IFNQT1RfTkNPTVBTICsgNDsgY3ArKykKCSAgICBjU3JjTm9uSXNvW2NwXSA9IGNsaXAyNTUocGlwZS0+Y1NyY1tjcF0gKwoJCQkJICAoKHBpcGUtPmNTcmNbY3BdIC0gY0Rlc3RbY3BdKSAqIHQpIC8gMjU1KTsKCWNhc2Ugc3BsYXNoTW9kZUNNWUs4OgoJICBjU3JjTm9uSXNvWzNdID0gY2xpcDI1NShwaXBlLT5jU3JjWzNdICsKCQkJCSAgKChwaXBlLT5jU3JjWzNdIC0gY0Rlc3RbM10pICogdCkgLyAyNTUpOwojZW5kaWYKCWNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CgljYXNlIHNwbGFzaE1vZGVCR1I4OgoJICBjU3JjTm9uSXNvWzJdID0gY2xpcDI1NShwaXBlLT5jU3JjWzJdICsKCQkJCSAgKChwaXBlLT5jU3JjWzJdIC0gY0Rlc3RbMl0pICogdCkgLyAyNTUpOwoJICBjU3JjTm9uSXNvWzFdID0gY2xpcDI1NShwaXBlLT5jU3JjWzFdICsKCQkJCSAgKChwaXBlLT5jU3JjWzFdIC0gY0Rlc3RbMV0pICogdCkgLyAyNTUpOwoJY2FzZSBzcGxhc2hNb2RlTW9ubzE6CgljYXNlIHNwbGFzaE1vZGVNb25vODoKCSAgY1NyY05vbklzb1swXSA9IGNsaXAyNTUocGlwZS0+Y1NyY1swXSArCgkJCQkgICgocGlwZS0+Y1NyY1swXSAtIGNEZXN0WzBdKSAqIHQpIC8gMjU1KTsKCSAgYnJlYWs7Cgl9CgljU3JjID0gY1NyY05vbklzbzsKICAgICAgICAvLyBrbm9ja291dDogcmVtb3ZlIGJhY2tkcm9wIGNvbG9yCiAgICAgICAgaWYgKHBpcGUtPmtub2Nrb3V0ICYmIHBpcGUtPnNoYXBlID49IHBpcGUtPmtub2Nrb3V0T3BhY2l0eSkgewogICAgICAgICAgYURlc3QgPSAwOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgY1NyYyA9IHBpcGUtPmNTcmM7CiAgICB9CgogICAgLy8tLS0tLSBibGVuZCBmdW5jdGlvbgoKICAgIGlmIChzdGF0ZS0+YmxlbmRGdW5jKSB7CiAgICAgICgqc3RhdGUtPmJsZW5kRnVuYykoY1NyYywgY0Rlc3QsIGNCbGVuZCwgYml0bWFwLT5tb2RlKTsKICAgIH0KCiAgICAvLy0tLS0tIHJlc3VsdCBhbHBoYSBhbmQgbm9uLWlzb2xhdGVkIGdyb3VwIGVsZW1lbnQgY29ycmVjdGlvbgoKICAgIGlmIChwaXBlLT5ub1RyYW5zcGFyZW5jeSkgewogICAgICBhbHBoYUkgPSBhbHBoYUltMSA9IGFSZXN1bHQgPSAyNTU7CiAgICB9IGVsc2UgewogICAgICBhUmVzdWx0ID0gYVNyYyArIGFEZXN0IC0gZGl2MjU1KGFTcmMgKiBhRGVzdCk7CgogICAgICAvLyBhbHBoYUkgPSBhbHBoYV9pCiAgICAgIC8vIGFscGhhSW0xID0gYWxwaGFfKGktMSkKICAgICAgaWYgKHBpcGUtPmFscGhhMFB0cikgewoJYWxwaGEwID0gKnBpcGUtPmFscGhhMFB0cisrOwoJYWxwaGFJID0gYVJlc3VsdCArIGFscGhhMCAtIGRpdjI1NShhUmVzdWx0ICogYWxwaGEwKTsKCWFscGhhSW0xID0gYWxwaGEwICsgYURlc3QgLSBkaXYyNTUoYWxwaGEwICogYURlc3QpOwogICAgICB9IGVsc2UgewoJYWxwaGFJID0gYVJlc3VsdDsKCWFscGhhSW0xID0gYURlc3Q7CiAgICAgIH0KICAgIH0KCiAgICAvLy0tLS0tIHJlc3VsdCBjb2xvcgoKICAgIGNSZXN1bHQwID0gY1Jlc3VsdDEgPSBjUmVzdWx0MiA9IGNSZXN1bHQzID0gMDsgLy8gbWFrZSBnY2MgaGFwcHkKCiAgICBzd2l0Y2ggKHBpcGUtPnJlc3VsdENvbG9yQ3RybCkgewoKICAgIGNhc2Ugc3BsYXNoUGlwZVJlc3VsdENvbG9yTm9BbHBoYUJsZW5kTW9ubzoKICAgICAgY1Jlc3VsdDAgPSBzdGF0ZS0+Z3JheVRyYW5zZmVyW2RpdjI1NSgoMjU1IC0gYURlc3QpICogY1NyY1swXSArCgkJCQkJICAgIGFEZXN0ICogY0JsZW5kWzBdKV07CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hQaXBlUmVzdWx0Q29sb3JOb0FscGhhQmxlbmRSR0I6CiAgICAgIGNSZXN1bHQwID0gc3RhdGUtPnJnYlRyYW5zZmVyUltkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbMF0gKwoJCQkJCSAgICBhRGVzdCAqIGNCbGVuZFswXSldOwogICAgICBjUmVzdWx0MSA9IHN0YXRlLT5yZ2JUcmFuc2ZlckdbZGl2MjU1KCgyNTUgLSBhRGVzdCkgKiBjU3JjWzFdICsKCQkJCQkgICAgYURlc3QgKiBjQmxlbmRbMV0pXTsKICAgICAgY1Jlc3VsdDIgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW2RpdjI1NSgoMjU1IC0gYURlc3QpICogY1NyY1syXSArCgkJCQkJICAgIGFEZXN0ICogY0JsZW5kWzJdKV07CiAgICAgIGJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoUGlwZVJlc3VsdENvbG9yTm9BbHBoYUJsZW5kQ01ZSzoKICAgICAgY1Jlc3VsdDAgPSBzdGF0ZS0+Y215a1RyYW5zZmVyQ1tkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbMF0gKwoJCQkJCSAgICAgYURlc3QgKiBjQmxlbmRbMF0pXTsKICAgICAgY1Jlc3VsdDEgPSBzdGF0ZS0+Y215a1RyYW5zZmVyTVtkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbMV0gKwoJCQkJCSAgICAgYURlc3QgKiBjQmxlbmRbMV0pXTsKICAgICAgY1Jlc3VsdDIgPSBzdGF0ZS0+Y215a1RyYW5zZmVyWVtkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbMl0gKwoJCQkJCSAgICAgYURlc3QgKiBjQmxlbmRbMl0pXTsKICAgICAgY1Jlc3VsdDMgPSBzdGF0ZS0+Y215a1RyYW5zZmVyS1tkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbM10gKwoJCQkJCSAgICAgYURlc3QgKiBjQmxlbmRbM10pXTsKICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaFBpcGVSZXN1bHRDb2xvck5vQWxwaGFCbGVuZERldmljZU46CiAgICAgIGZvciAoY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgICAgY1Jlc3VsdFtjcF0gPSBzdGF0ZS0+ZGV2aWNlTlRyYW5zZmVyW2NwXVtkaXYyNTUoKDI1NSAtIGFEZXN0KSAqIGNTcmNbY3BdICsKCQkJCQkgICAgIGFEZXN0ICogY0JsZW5kW2NwXSldOwogICAgICBicmVhazsKI2VuZGlmCgogICAgY2FzZSBzcGxhc2hQaXBlUmVzdWx0Q29sb3JBbHBoYU5vQmxlbmRNb25vOgogICAgICBpZiAoYWxwaGFJID09IDApIHsKCWNSZXN1bHQwID0gMDsKICAgICAgfSBlbHNlIHsKCWNSZXN1bHQwID0gc3RhdGUtPmdyYXlUcmFuc2ZlclsoKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbMF0gKwoJCQkJCWFTcmMgKiBjU3JjWzBdKSAvIGFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaFBpcGVSZXN1bHRDb2xvckFscGhhTm9CbGVuZFJHQjoKICAgICAgaWYgKGFscGhhSSA9PSAwKSB7CgljUmVzdWx0MCA9IDA7CgljUmVzdWx0MSA9IDA7CgljUmVzdWx0MiA9IDA7CiAgICAgIH0gZWxzZSB7CgljUmVzdWx0MCA9IHN0YXRlLT5yZ2JUcmFuc2ZlclJbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzBdICsKCQkJCQlhU3JjICogY1NyY1swXSkgLyBhbHBoYUldOwoJY1Jlc3VsdDEgPSBzdGF0ZS0+cmdiVHJhbnNmZXJHWygoYWxwaGFJIC0gYVNyYykgKiBjRGVzdFsxXSArCgkJCQkJYVNyYyAqIGNTcmNbMV0pIC8gYWxwaGFJXTsKCWNSZXN1bHQyID0gc3RhdGUtPnJnYlRyYW5zZmVyQlsoKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbMl0gKwoJCQkJCWFTcmMgKiBjU3JjWzJdKSAvIGFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hQaXBlUmVzdWx0Q29sb3JBbHBoYU5vQmxlbmRDTVlLOgogICAgICBpZiAoYWxwaGFJID09IDApIHsKCWNSZXN1bHQwID0gMDsKCWNSZXN1bHQxID0gMDsKCWNSZXN1bHQyID0gMDsKCWNSZXN1bHQzID0gMDsKICAgICAgfSBlbHNlIHsKCWNSZXN1bHQwID0gc3RhdGUtPmNteWtUcmFuc2ZlckNbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzBdICsKCQkJCQkgYVNyYyAqIGNTcmNbMF0pIC8gYWxwaGFJXTsKCWNSZXN1bHQxID0gc3RhdGUtPmNteWtUcmFuc2Zlck1bKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzFdICsKCQkJCQkgYVNyYyAqIGNTcmNbMV0pIC8gYWxwaGFJXTsKCWNSZXN1bHQyID0gc3RhdGUtPmNteWtUcmFuc2ZlcllbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzJdICsKCQkJCQkgYVNyYyAqIGNTcmNbMl0pIC8gYWxwaGFJXTsKCWNSZXN1bHQzID0gc3RhdGUtPmNteWtUcmFuc2ZlcktbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzNdICsKCQkJCQkgYVNyYyAqIGNTcmNbM10pIC8gYWxwaGFJXTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFOb0JsZW5kRGV2aWNlTjoKICAgICAgaWYgKGFscGhhSSA9PSAwKSB7CiAgICAgICAgZm9yIChjcCA9IDA7IGNwIDwgU1BPVF9OQ09NUFMrNDsgY3ArKykKICAgICAgICAgIGNSZXN1bHRbY3BdID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgICAgICAgY1Jlc3VsdFtjcF0gPSBzdGF0ZS0+ZGV2aWNlTlRyYW5zZmVyW2NwXVsoKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbY3BdICsKCQkJCQkgYVNyYyAqIGNTcmNbY3BdKSAvIGFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiNlbmRpZgoKICAgIGNhc2Ugc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZE1vbm86CiAgICAgIGlmIChhbHBoYUkgPT0gMCkgewoJY1Jlc3VsdDAgPSAwOwogICAgICB9IGVsc2UgewoJY1Jlc3VsdDAgPSBzdGF0ZS0+Z3JheVRyYW5zZmVyWygoYWxwaGFJIC0gYVNyYykgKiBjRGVzdFswXSArCgkJCQkJYVNyYyAqICgoMjU1IC0gYWxwaGFJbTEpICogY1NyY1swXSArCgkJCQkJCWFscGhhSW0xICogY0JsZW5kWzBdKSAvIDI1NSkgLwoJCQkJICAgICAgIGFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaFBpcGVSZXN1bHRDb2xvckFscGhhQmxlbmRSR0I6CiAgICAgIGlmIChhbHBoYUkgPT0gMCkgewoJY1Jlc3VsdDAgPSAwOwoJY1Jlc3VsdDEgPSAwOwoJY1Jlc3VsdDIgPSAwOwogICAgICB9IGVsc2UgewoJY1Jlc3VsdDAgPSBzdGF0ZS0+cmdiVHJhbnNmZXJSWygoYWxwaGFJIC0gYVNyYykgKiBjRGVzdFswXSArCgkJCQkJYVNyYyAqICgoMjU1IC0gYWxwaGFJbTEpICogY1NyY1swXSArCgkJCQkJCWFscGhhSW0xICogY0JsZW5kWzBdKSAvIDI1NSkgLwoJCQkJICAgICAgIGFscGhhSV07CgljUmVzdWx0MSA9IHN0YXRlLT5yZ2JUcmFuc2ZlckdbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzFdICsKCQkJCQlhU3JjICogKCgyNTUgLSBhbHBoYUltMSkgKiBjU3JjWzFdICsKCQkJCQkJYWxwaGFJbTEgKiBjQmxlbmRbMV0pIC8gMjU1KSAvCgkJCQkgICAgICAgYWxwaGFJXTsKCWNSZXN1bHQyID0gc3RhdGUtPnJnYlRyYW5zZmVyQlsoKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbMl0gKwoJCQkJCWFTcmMgKiAoKDI1NSAtIGFscGhhSW0xKSAqIGNTcmNbMl0gKwoJCQkJCQlhbHBoYUltMSAqIGNCbGVuZFsyXSkgLyAyNTUpIC8KCQkJCSAgICAgICBhbHBoYUldOwogICAgICB9CiAgICAgIGJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICAgIGNhc2Ugc3BsYXNoUGlwZVJlc3VsdENvbG9yQWxwaGFCbGVuZENNWUs6CiAgICAgIGlmIChhbHBoYUkgPT0gMCkgewoJY1Jlc3VsdDAgPSAwOwoJY1Jlc3VsdDEgPSAwOwoJY1Jlc3VsdDIgPSAwOwoJY1Jlc3VsdDMgPSAwOwogICAgICB9IGVsc2UgewoJY1Jlc3VsdDAgPSBzdGF0ZS0+Y215a1RyYW5zZmVyQ1soKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbMF0gKwoJCQkJCSBhU3JjICogKCgyNTUgLSBhbHBoYUltMSkgKiBjU3JjWzBdICsKCQkJCQkJIGFscGhhSW0xICogY0JsZW5kWzBdKSAvIDI1NSkgLwoJCQkJCWFscGhhSV07CgljUmVzdWx0MSA9IHN0YXRlLT5jbXlrVHJhbnNmZXJNWygoYWxwaGFJIC0gYVNyYykgKiBjRGVzdFsxXSArCgkJCQkJIGFTcmMgKiAoKDI1NSAtIGFscGhhSW0xKSAqIGNTcmNbMV0gKwoJCQkJCQkgYWxwaGFJbTEgKiBjQmxlbmRbMV0pIC8gMjU1KSAvCgkJCQkJYWxwaGFJXTsKCWNSZXN1bHQyID0gc3RhdGUtPmNteWtUcmFuc2ZlcllbKChhbHBoYUkgLSBhU3JjKSAqIGNEZXN0WzJdICsKCQkJCQkgYVNyYyAqICgoMjU1IC0gYWxwaGFJbTEpICogY1NyY1syXSArCgkJCQkJCSBhbHBoYUltMSAqIGNCbGVuZFsyXSkgLyAyNTUpIC8KCQkJCQlhbHBoYUldOwoJY1Jlc3VsdDMgPSBzdGF0ZS0+Y215a1RyYW5zZmVyS1soKGFscGhhSSAtIGFTcmMpICogY0Rlc3RbM10gKwoJCQkJCSBhU3JjICogKCgyNTUgLSBhbHBoYUltMSkgKiBjU3JjWzNdICsKCQkJCQkJIGFscGhhSW0xICogY0JsZW5kWzNdKSAvIDI1NSkgLwoJCQkJCWFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaFBpcGVSZXN1bHRDb2xvckFscGhhQmxlbmREZXZpY2VOOgogICAgICBpZiAoYWxwaGFJID09IDApIHsKICAgICAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgICAgICAgY1Jlc3VsdFtjcF0gPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIGZvciAoY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgICAgICBjUmVzdWx0W2NwXSA9IHN0YXRlLT5kZXZpY2VOVHJhbnNmZXJbY3BdWygoYWxwaGFJIC0gYVNyYykgKiBjRGVzdFtjcF0gKwogICAgICAgICAgICBhU3JjICogKCgyNTUgLSBhbHBoYUltMSkgKiBjU3JjW2NwXSArCgkJCQkJCWFscGhhSW0xICogY0JsZW5kW2NwXSkgLyAyNTUpIC8KCQkJCQkgIGFscGhhSV07CiAgICAgIH0KICAgICAgYnJlYWs7CiNlbmRpZgogICAgfQoKICAgIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKCiAgICBzd2l0Y2ggKGJpdG1hcC0+bW9kZSkgewogICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICAgIGlmIChzdGF0ZS0+c2NyZWVuLT50ZXN0KHBpcGUtPngsIHBpcGUtPnksIGNSZXN1bHQwKSkgewoJKnBpcGUtPmRlc3RDb2xvclB0ciB8PSBwaXBlLT5kZXN0Q29sb3JNYXNrOwogICAgICB9IGVsc2UgewoJKnBpcGUtPmRlc3RDb2xvclB0ciAmPSB+cGlwZS0+ZGVzdENvbG9yTWFzazsKICAgICAgfQogICAgICBpZiAoIShwaXBlLT5kZXN0Q29sb3JNYXNrID4+PSAxKSkgewoJcGlwZS0+ZGVzdENvbG9yTWFzayA9IDB4ODA7CgkrK3BpcGUtPmRlc3RDb2xvclB0cjsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MDsKICAgICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MDsKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDE7CiAgICAgICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IGNSZXN1bHQyOwogICAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MjsKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDE7CiAgICAgICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IGNSZXN1bHQwOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSAyNTU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgICAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDI7CiAgICAgICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IGNSZXN1bHQxOwogICAgICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MDsKICAgICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDEpIHsKCXBpcGUtPmRlc3RDb2xvclB0clswXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMF0gKyBjUmVzdWx0MCwgMjU1KSA6CiAgICAgICAgICAgICAgY1Jlc3VsdDA7CiAgICAgIH0KICAgICAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgMikgewoJcGlwZS0+ZGVzdENvbG9yUHRyWzFdID0gKHN0YXRlLT5vdmVycHJpbnRBZGRpdGl2ZSkgPyAKICAgICAgICAgICAgICBzdGQ6Om1pbjxpbnQ+KHBpcGUtPmRlc3RDb2xvclB0clsxXSArIGNSZXN1bHQxLCAyNTUpIDoKICAgICAgICAgICAgICBjUmVzdWx0MTsKICAgICAgfQogICAgICBpZiAoc3RhdGUtPm92ZXJwcmludE1hc2sgJiA0KSB7CglwaXBlLT5kZXN0Q29sb3JQdHJbMl0gPSAoc3RhdGUtPm92ZXJwcmludEFkZGl0aXZlKSA/IAogICAgICAgICAgICAgIHN0ZDo6bWluPGludD4ocGlwZS0+ZGVzdENvbG9yUHRyWzJdICsgY1Jlc3VsdDIsIDI1NSkgOgogICAgICAgICAgICAgIGNSZXN1bHQyOwogICAgICB9CiAgICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDgpIHsKCXBpcGUtPmRlc3RDb2xvclB0clszXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbM10gKyBjUmVzdWx0MywgMjU1KSA6CiAgICAgICAgICAgICAgY1Jlc3VsdDM7CiAgICAgIH0KICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IDQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICAgIG1hc2sgPSAxOwogICAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKSB7CiAgICAgICAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgbWFzaykgewogICAgICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyW2NwXSA9IGNSZXN1bHRbY3BdOwogICAgICAgIH0KICAgICAgICBtYXNrIDw8PTE7CiAgICAgIH0KICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IChTUE9UX05DT01QUys0KTsKICAgICAgYnJlYWs7CiNlbmRpZgogICAgfQogICAgaWYgKHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSBhUmVzdWx0OwogICAgfQoKICB9CgogICsrcGlwZS0+eDsKfQoKLy8gc3BlY2lhbCBjYXNlOgovLyAhcGlwZS0+cGF0dGVybiAmJiBwaXBlLT5ub1RyYW5zcGFyZW5jeSAmJiAhc3RhdGUtPmJsZW5kRnVuYyAmJgovLyBiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm8xICYmICFwaXBlLT5kZXN0QWxwaGFQdHIpIHsKdm9pZCBTcGxhc2g6OnBpcGVSdW5TaW1wbGVNb25vMShTcGxhc2hQaXBlICpwaXBlKSB7CiAgR3VjaGFyIGNSZXN1bHQwOwoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgY1Jlc3VsdDAgPSBzdGF0ZS0+Z3JheVRyYW5zZmVyW3BpcGUtPmNTcmNbMF1dOwogIGlmIChzdGF0ZS0+c2NyZWVuLT50ZXN0KHBpcGUtPngsIHBpcGUtPnksIGNSZXN1bHQwKSkgewogICAgKnBpcGUtPmRlc3RDb2xvclB0ciB8PSBwaXBlLT5kZXN0Q29sb3JNYXNrOwogIH0gZWxzZSB7CiAgICAqcGlwZS0+ZGVzdENvbG9yUHRyICY9IH5waXBlLT5kZXN0Q29sb3JNYXNrOwogIH0KICBpZiAoIShwaXBlLT5kZXN0Q29sb3JNYXNrID4+PSAxKSkgewogICAgcGlwZS0+ZGVzdENvbG9yTWFzayA9IDB4ODA7CiAgICArK3BpcGUtPmRlc3RDb2xvclB0cjsKICB9CgogICsrcGlwZS0+eDsKfQoKLy8gc3BlY2lhbCBjYXNlOgovLyAhcGlwZS0+cGF0dGVybiAmJiBwaXBlLT5ub1RyYW5zcGFyZW5jeSAmJiAhc3RhdGUtPmJsZW5kRnVuYyAmJgovLyBiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm84ICYmIHBpcGUtPmRlc3RBbHBoYVB0cikgewp2b2lkIFNwbGFzaDo6cGlwZVJ1blNpbXBsZU1vbm84KFNwbGFzaFBpcGUgKnBpcGUpIHsKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPmdyYXlUcmFuc2ZlcltwaXBlLT5jU3JjWzBdXTsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSAyNTU7CgogICsrcGlwZS0+eDsKfQoKLy8gc3BlY2lhbCBjYXNlOgovLyAhcGlwZS0+cGF0dGVybiAmJiBwaXBlLT5ub1RyYW5zcGFyZW5jeSAmJiAhc3RhdGUtPmJsZW5kRnVuYyAmJgovLyBiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZVJHQjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CnZvaWQgU3BsYXNoOjpwaXBlUnVuU2ltcGxlUkdCOChTcGxhc2hQaXBlICpwaXBlKSB7CiAgLy8tLS0tLSB3cml0ZSBkZXN0aW5hdGlvbiBwaXhlbAogICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IHN0YXRlLT5yZ2JUcmFuc2ZlclJbcGlwZS0+Y1NyY1swXV07CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyR1twaXBlLT5jU3JjWzFdXTsKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW3BpcGUtPmNTcmNbMl1dOwogICpwaXBlLT5kZXN0QWxwaGFQdHIrKyA9IDI1NTsKCiAgKytwaXBlLT54Owp9CgovLyBzcGVjaWFsIGNhc2U6Ci8vICFwaXBlLT5wYXR0ZXJuICYmIHBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+YmxlbmRGdW5jICYmCi8vIGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlWEJHUjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CnZvaWQgU3BsYXNoOjpwaXBlUnVuU2ltcGxlWEJHUjgoU3BsYXNoUGlwZSAqcGlwZSkgewogIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW3BpcGUtPmNTcmNbMl1dOwogICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IHN0YXRlLT5yZ2JUcmFuc2ZlckdbcGlwZS0+Y1NyY1sxXV07CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyUltwaXBlLT5jU3JjWzBdXTsKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSAyNTU7CiAgKnBpcGUtPmRlc3RBbHBoYVB0cisrID0gMjU1OwoKICArK3BpcGUtPng7Cn0KCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVCR1I4ICYmIHBpcGUtPmRlc3RBbHBoYVB0cikgewp2b2lkIFNwbGFzaDo6cGlwZVJ1blNpbXBsZUJHUjgoU3BsYXNoUGlwZSAqcGlwZSkgewogIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCW3BpcGUtPmNTcmNbMl1dOwogICpwaXBlLT5kZXN0Q29sb3JQdHIrKyA9IHN0YXRlLT5yZ2JUcmFuc2ZlckdbcGlwZS0+Y1NyY1sxXV07CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gc3RhdGUtPnJnYlRyYW5zZmVyUltwaXBlLT5jU3JjWzBdXTsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSAyNTU7CgogICsrcGlwZS0+eDsKfQoKI2lmIFNQTEFTSF9DTVlLCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVDTVlLOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIpIHsKdm9pZCBTcGxhc2g6OnBpcGVSdW5TaW1wbGVDTVlLOChTcGxhc2hQaXBlICpwaXBlKSB7CiAgLy8tLS0tLSB3cml0ZSBkZXN0aW5hdGlvbiBwaXhlbAogIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDEpIHsKICAgIHBpcGUtPmRlc3RDb2xvclB0clswXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMF0gKyBzdGF0ZS0+Y215a1RyYW5zZmVyQ1twaXBlLT5jU3JjWzBdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2ZlckNbcGlwZS0+Y1NyY1swXV07CiAgfQogIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDIpIHsKICAgIHBpcGUtPmRlc3RDb2xvclB0clsxXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMV0gKyBzdGF0ZS0+Y215a1RyYW5zZmVyTVtwaXBlLT5jU3JjWzFdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2Zlck1bcGlwZS0+Y1NyY1sxXV07CiAgfQogIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDQpIHsKICAgIHBpcGUtPmRlc3RDb2xvclB0clsyXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMl0gKyBzdGF0ZS0+Y215a1RyYW5zZmVyWVtwaXBlLT5jU3JjWzJdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2ZlcllbcGlwZS0+Y1NyY1syXV07CiAgfQogIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDgpIHsKICAgIHBpcGUtPmRlc3RDb2xvclB0clszXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUpID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbM10gKyBzdGF0ZS0+Y215a1RyYW5zZmVyS1twaXBlLT5jU3JjWzNdXSwgMjU1KSA6CiAgICAgICAgICAgICAgc3RhdGUtPmNteWtUcmFuc2ZlcktbcGlwZS0+Y1NyY1szXV07CiAgfQogIHBpcGUtPmRlc3RDb2xvclB0ciArPSA0OwogICpwaXBlLT5kZXN0QWxwaGFQdHIrKyA9IDI1NTsKCiAgKytwaXBlLT54Owp9CgovLyBzcGVjaWFsIGNhc2U6Ci8vICFwaXBlLT5wYXR0ZXJuICYmIHBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+YmxlbmRGdW5jICYmCi8vIGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlRGV2aWNlTjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyKSB7CnZvaWQgU3BsYXNoOjpwaXBlUnVuU2ltcGxlRGV2aWNlTjgoU3BsYXNoUGlwZSAqcGlwZSkgewogIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKICBpbnQgbWFzayA9IDE7CiAgZm9yIChpbnQgY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspIHsKICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIG1hc2spIHsKICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyW2NwXSA9IHN0YXRlLT5kZXZpY2VOVHJhbnNmZXJbY3BdW3BpcGUtPmNTcmNbY3BdXTsKICAgIH0KICAgIG1hc2sgPDw9MTsKICB9CiAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IChTUE9UX05DT01QUys0KTsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSAyNTU7CgogICsrcGlwZS0+eDsKfQojZW5kaWYKCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgIXBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+c29mdE1hc2sgJiYKLy8gcGlwZS0+dXNlc1NoYXBlICYmICFwaXBlLT5hbHBoYTBQdHIgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gIXBpcGUtPm5vbklzb2xhdGVkR3JvdXAgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVNb25vMSAmJiAhcGlwZS0+ZGVzdEFscGhhUHRyCnZvaWQgU3BsYXNoOjpwaXBlUnVuQUFNb25vMShTcGxhc2hQaXBlICpwaXBlKSB7CiAgR3VjaGFyIGFTcmM7CiAgU3BsYXNoQ29sb3IgY0Rlc3Q7CiAgR3VjaGFyIGNSZXN1bHQwOwoKICAvLy0tLS0tIHJlYWQgZGVzdGluYXRpb24gcGl4ZWwKICBjRGVzdFswXSA9ICgqcGlwZS0+ZGVzdENvbG9yUHRyICYgcGlwZS0+ZGVzdENvbG9yTWFzaykgPyAweGZmIDogMHgwMDsKCiAgLy8tLS0tLSBzb3VyY2UgYWxwaGEKICBhU3JjID0gZGl2MjU1KHBpcGUtPmFJbnB1dCAqIHBpcGUtPnNoYXBlKTsKCiAgLy8tLS0tLSByZXN1bHQgY29sb3IKICAvLyBub3RlOiBhRGVzdCA9IGFscGhhMiA9IGFSZXN1bHQgPSAweGZmCiAgY1Jlc3VsdDAgPSBzdGF0ZS0+Z3JheVRyYW5zZmVyWyhHdWNoYXIpZGl2MjU1KCgweGZmIC0gYVNyYykgKiBjRGVzdFswXSArCgkJCQkJCWFTcmMgKiBwaXBlLT5jU3JjWzBdKV07CgogIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKICBpZiAoc3RhdGUtPnNjcmVlbi0+dGVzdChwaXBlLT54LCBwaXBlLT55LCBjUmVzdWx0MCkpIHsKICAgICpwaXBlLT5kZXN0Q29sb3JQdHIgfD0gcGlwZS0+ZGVzdENvbG9yTWFzazsKICB9IGVsc2UgewogICAgKnBpcGUtPmRlc3RDb2xvclB0ciAmPSB+cGlwZS0+ZGVzdENvbG9yTWFzazsKICB9CiAgaWYgKCEocGlwZS0+ZGVzdENvbG9yTWFzayA+Pj0gMSkpIHsKICAgIHBpcGUtPmRlc3RDb2xvck1hc2sgPSAweDgwOwogICAgKytwaXBlLT5kZXN0Q29sb3JQdHI7CiAgfQoKICArK3BpcGUtPng7Cn0KCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgIXBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+c29mdE1hc2sgJiYKLy8gcGlwZS0+dXNlc1NoYXBlICYmICFwaXBlLT5hbHBoYTBQdHIgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gIXBpcGUtPm5vbklzb2xhdGVkR3JvdXAgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVNb25vOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIKdm9pZCBTcGxhc2g6OnBpcGVSdW5BQU1vbm84KFNwbGFzaFBpcGUgKnBpcGUpIHsKICBHdWNoYXIgYVNyYywgYURlc3QsIGFscGhhMiwgYVJlc3VsdDsKICBTcGxhc2hDb2xvciBjRGVzdDsKICBHdWNoYXIgY1Jlc3VsdDA7CgogIC8vLS0tLS0gcmVhZCBkZXN0aW5hdGlvbiBwaXhlbAogIGNEZXN0WzBdID0gKnBpcGUtPmRlc3RDb2xvclB0cjsKICBhRGVzdCA9ICpwaXBlLT5kZXN0QWxwaGFQdHI7CgogIC8vLS0tLS0gc291cmNlIGFscGhhCiAgYVNyYyA9IGRpdjI1NShwaXBlLT5hSW5wdXQgKiBwaXBlLT5zaGFwZSk7CgogIC8vLS0tLS0gcmVzdWx0IGFscGhhIGFuZCBub24taXNvbGF0ZWQgZ3JvdXAgZWxlbWVudCBjb3JyZWN0aW9uCiAgYVJlc3VsdCA9IGFTcmMgKyBhRGVzdCAtIGRpdjI1NShhU3JjICogYURlc3QpOwogIGFscGhhMiA9IGFSZXN1bHQ7CgogIC8vLS0tLS0gcmVzdWx0IGNvbG9yCiAgaWYgKGFscGhhMiA9PSAwKSB7CiAgICBjUmVzdWx0MCA9IDA7CiAgfSBlbHNlIHsKICAgIGNSZXN1bHQwID0gc3RhdGUtPmdyYXlUcmFuc2ZlclsoR3VjaGFyKSgoKGFscGhhMiAtIGFTcmMpICogY0Rlc3RbMF0gKwoJCQkJCSAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMF0pIC8gYWxwaGEyKV07CiAgfQoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDA7CiAgKnBpcGUtPmRlc3RBbHBoYVB0cisrID0gYVJlc3VsdDsKCiAgKytwaXBlLT54Owp9CgovLyBzcGVjaWFsIGNhc2U6Ci8vICFwaXBlLT5wYXR0ZXJuICYmICFwaXBlLT5ub1RyYW5zcGFyZW5jeSAmJiAhc3RhdGUtPnNvZnRNYXNrICYmCi8vIHBpcGUtPnVzZXNTaGFwZSAmJiAhcGlwZS0+YWxwaGEwUHRyICYmICFzdGF0ZS0+YmxlbmRGdW5jICYmCi8vICFwaXBlLT5ub25Jc29sYXRlZEdyb3VwICYmCi8vIGJpdG1hcC0+bW9kZSA9PSBzcGxhc2hNb2RlUkdCOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIKdm9pZCBTcGxhc2g6OnBpcGVSdW5BQVJHQjgoU3BsYXNoUGlwZSAqcGlwZSkgewogIEd1Y2hhciBhU3JjLCBhRGVzdCwgYWxwaGEyLCBhUmVzdWx0OwogIFNwbGFzaENvbG9yIGNEZXN0OwogIEd1Y2hhciBjUmVzdWx0MCwgY1Jlc3VsdDEsIGNSZXN1bHQyOwoKICAvLy0tLS0tIHJlYWQgZGVzdGluYXRpb24gcGl4ZWwKICBjRGVzdFswXSA9IHBpcGUtPmRlc3RDb2xvclB0clswXTsKICBjRGVzdFsxXSA9IHBpcGUtPmRlc3RDb2xvclB0clsxXTsKICBjRGVzdFsyXSA9IHBpcGUtPmRlc3RDb2xvclB0clsyXTsKICBhRGVzdCA9ICpwaXBlLT5kZXN0QWxwaGFQdHI7CgogIC8vLS0tLS0gc291cmNlIGFscGhhCiAgYVNyYyA9IGRpdjI1NShwaXBlLT5hSW5wdXQgKiBwaXBlLT5zaGFwZSk7CgogIC8vLS0tLS0gcmVzdWx0IGFscGhhIGFuZCBub24taXNvbGF0ZWQgZ3JvdXAgZWxlbWVudCBjb3JyZWN0aW9uCiAgYVJlc3VsdCA9IGFTcmMgKyBhRGVzdCAtIGRpdjI1NShhU3JjICogYURlc3QpOwogIGFscGhhMiA9IGFSZXN1bHQ7CgogIC8vLS0tLS0gcmVzdWx0IGNvbG9yCiAgaWYgKGFscGhhMiA9PSAwKSB7CiAgICBjUmVzdWx0MCA9IDA7CiAgICBjUmVzdWx0MSA9IDA7CiAgICBjUmVzdWx0MiA9IDA7CiAgfSBlbHNlIHsKICAgIGNSZXN1bHQwID0gc3RhdGUtPnJnYlRyYW5zZmVyUlsoR3VjaGFyKSgoKGFscGhhMiAtIGFTcmMpICogY0Rlc3RbMF0gKwoJCQkJCSAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMF0pIC8gYWxwaGEyKV07CiAgICBjUmVzdWx0MSA9IHN0YXRlLT5yZ2JUcmFuc2ZlckdbKEd1Y2hhcikoKChhbHBoYTIgLSBhU3JjKSAqIGNEZXN0WzFdICsKCQkJCQkgICAgIGFTcmMgKiBwaXBlLT5jU3JjWzFdKSAvIGFscGhhMildOwogICAgY1Jlc3VsdDIgPSBzdGF0ZS0+cmdiVHJhbnNmZXJCWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFsyXSArCgkJCQkJICAgICBhU3JjICogcGlwZS0+Y1NyY1syXSkgLyBhbHBoYTIpXTsKICB9CgogIC8vLS0tLS0gd3JpdGUgZGVzdGluYXRpb24gcGl4ZWwKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MDsKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MTsKICAqcGlwZS0+ZGVzdENvbG9yUHRyKysgPSBjUmVzdWx0MjsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSBhUmVzdWx0OwoKICArK3BpcGUtPng7Cn0KCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgIXBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+c29mdE1hc2sgJiYKLy8gcGlwZS0+dXNlc1NoYXBlICYmICFwaXBlLT5hbHBoYTBQdHIgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gIXBpcGUtPm5vbklzb2xhdGVkR3JvdXAgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVYQkdSOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIKdm9pZCBTcGxhc2g6OnBpcGVSdW5BQVhCR1I4KFNwbGFzaFBpcGUgKnBpcGUpIHsKICBHdWNoYXIgYVNyYywgYURlc3QsIGFscGhhMiwgYVJlc3VsdDsKICBTcGxhc2hDb2xvciBjRGVzdDsKICBHdWNoYXIgY1Jlc3VsdDAsIGNSZXN1bHQxLCBjUmVzdWx0MjsKCiAgLy8tLS0tLSByZWFkIGRlc3RpbmF0aW9uIHBpeGVsCiAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgY0Rlc3RbMV0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMV07CiAgY0Rlc3RbMl0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMF07CiAgYURlc3QgPSAqcGlwZS0+ZGVzdEFscGhhUHRyOwoKICAvLy0tLS0tIHNvdXJjZSBhbHBoYQogIGFTcmMgPSBkaXYyNTUocGlwZS0+YUlucHV0ICogcGlwZS0+c2hhcGUpOwoKICAvLy0tLS0tIHJlc3VsdCBhbHBoYSBhbmQgbm9uLWlzb2xhdGVkIGdyb3VwIGVsZW1lbnQgY29ycmVjdGlvbgogIGFSZXN1bHQgPSBhU3JjICsgYURlc3QgLSBkaXYyNTUoYVNyYyAqIGFEZXN0KTsKICBhbHBoYTIgPSBhUmVzdWx0OwoKICAvLy0tLS0tIHJlc3VsdCBjb2xvcgogIGlmIChhbHBoYTIgPT0gMCkgewogICAgY1Jlc3VsdDAgPSAwOwogICAgY1Jlc3VsdDEgPSAwOwogICAgY1Jlc3VsdDIgPSAwOwogIH0gZWxzZSB7CiAgICBjUmVzdWx0MCA9IHN0YXRlLT5yZ2JUcmFuc2ZlclJbKEd1Y2hhcikoKChhbHBoYTIgLSBhU3JjKSAqIGNEZXN0WzBdICsKCQkJCQkgICAgIGFTcmMgKiBwaXBlLT5jU3JjWzBdKSAvIGFscGhhMildOwogICAgY1Jlc3VsdDEgPSBzdGF0ZS0+cmdiVHJhbnNmZXJHWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFsxXSArCgkJCQkJICAgICBhU3JjICogcGlwZS0+Y1NyY1sxXSkgLyBhbHBoYTIpXTsKICAgIGNSZXN1bHQyID0gc3RhdGUtPnJnYlRyYW5zZmVyQlsoR3VjaGFyKSgoKGFscGhhMiAtIGFTcmMpICogY0Rlc3RbMl0gKwoJCQkJCSAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMl0pIC8gYWxwaGEyKV07CiAgfQoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDI7CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDE7CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDA7CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gMjU1OwogICpwaXBlLT5kZXN0QWxwaGFQdHIrKyA9IGFSZXN1bHQ7CgogICsrcGlwZS0+eDsKfQoKLy8gc3BlY2lhbCBjYXNlOgovLyAhcGlwZS0+cGF0dGVybiAmJiAhcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5zb2Z0TWFzayAmJgovLyBwaXBlLT51c2VzU2hhcGUgJiYgIXBpcGUtPmFscGhhMFB0ciAmJiAhc3RhdGUtPmJsZW5kRnVuYyAmJgovLyAhcGlwZS0+bm9uSXNvbGF0ZWRHcm91cCAmJgovLyBiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZUJHUjggJiYgcGlwZS0+ZGVzdEFscGhhUHRyCnZvaWQgU3BsYXNoOjpwaXBlUnVuQUFCR1I4KFNwbGFzaFBpcGUgKnBpcGUpIHsKICBHdWNoYXIgYVNyYywgYURlc3QsIGFscGhhMiwgYVJlc3VsdDsKICBTcGxhc2hDb2xvciBjRGVzdDsKICBHdWNoYXIgY1Jlc3VsdDAsIGNSZXN1bHQxLCBjUmVzdWx0MjsKCiAgLy8tLS0tLSByZWFkIGRlc3RpbmF0aW9uIHBpeGVsCiAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgY0Rlc3RbMV0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMV07CiAgY0Rlc3RbMl0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMF07CiAgYURlc3QgPSAqcGlwZS0+ZGVzdEFscGhhUHRyOwoKICAvLy0tLS0tIHNvdXJjZSBhbHBoYQogIGFTcmMgPSBkaXYyNTUocGlwZS0+YUlucHV0ICogcGlwZS0+c2hhcGUpOwoKICAvLy0tLS0tIHJlc3VsdCBhbHBoYSBhbmQgbm9uLWlzb2xhdGVkIGdyb3VwIGVsZW1lbnQgY29ycmVjdGlvbgogIGFSZXN1bHQgPSBhU3JjICsgYURlc3QgLSBkaXYyNTUoYVNyYyAqIGFEZXN0KTsKICBhbHBoYTIgPSBhUmVzdWx0OwoKICAvLy0tLS0tIHJlc3VsdCBjb2xvcgogIGlmIChhbHBoYTIgPT0gMCkgewogICAgY1Jlc3VsdDAgPSAwOwogICAgY1Jlc3VsdDEgPSAwOwogICAgY1Jlc3VsdDIgPSAwOwogIH0gZWxzZSB7CiAgICBjUmVzdWx0MCA9IHN0YXRlLT5yZ2JUcmFuc2ZlclJbKEd1Y2hhcikoKChhbHBoYTIgLSBhU3JjKSAqIGNEZXN0WzBdICsKCQkJCQkgICAgIGFTcmMgKiBwaXBlLT5jU3JjWzBdKSAvIGFscGhhMildOwogICAgY1Jlc3VsdDEgPSBzdGF0ZS0+cmdiVHJhbnNmZXJHWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFsxXSArCgkJCQkJICAgICBhU3JjICogcGlwZS0+Y1NyY1sxXSkgLyBhbHBoYTIpXTsKICAgIGNSZXN1bHQyID0gc3RhdGUtPnJnYlRyYW5zZmVyQlsoR3VjaGFyKSgoKGFscGhhMiAtIGFTcmMpICogY0Rlc3RbMl0gKwoJCQkJCSAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMl0pIC8gYWxwaGEyKV07CiAgfQoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDI7CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDE7CiAgKnBpcGUtPmRlc3RDb2xvclB0cisrID0gY1Jlc3VsdDA7CiAgKnBpcGUtPmRlc3RBbHBoYVB0cisrID0gYVJlc3VsdDsKCiAgKytwaXBlLT54Owp9CgojaWYgU1BMQVNIX0NNWUsKLy8gc3BlY2lhbCBjYXNlOgovLyAhcGlwZS0+cGF0dGVybiAmJiAhcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5zb2Z0TWFzayAmJgovLyBwaXBlLT51c2VzU2hhcGUgJiYgIXBpcGUtPmFscGhhMFB0ciAmJiAhc3RhdGUtPmJsZW5kRnVuYyAmJgovLyAhcGlwZS0+bm9uSXNvbGF0ZWRHcm91cCAmJgovLyBiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZUNNWUs4ICYmIHBpcGUtPmRlc3RBbHBoYVB0cgp2b2lkIFNwbGFzaDo6cGlwZVJ1bkFBQ01ZSzgoU3BsYXNoUGlwZSAqcGlwZSkgewogIEd1Y2hhciBhU3JjLCBhRGVzdCwgYWxwaGEyLCBhUmVzdWx0OwogIFNwbGFzaENvbG9yIGNEZXN0OwogIEd1Y2hhciBjUmVzdWx0MCwgY1Jlc3VsdDEsIGNSZXN1bHQyLCBjUmVzdWx0MzsKCiAgLy8tLS0tLSByZWFkIGRlc3RpbmF0aW9uIHBpeGVsCiAgY0Rlc3RbMF0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMF07CiAgY0Rlc3RbMV0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMV07CiAgY0Rlc3RbMl0gPSBwaXBlLT5kZXN0Q29sb3JQdHJbMl07CiAgY0Rlc3RbM10gPSBwaXBlLT5kZXN0Q29sb3JQdHJbM107CiAgYURlc3QgPSAqcGlwZS0+ZGVzdEFscGhhUHRyOwoKICAvLy0tLS0tIHNvdXJjZSBhbHBoYQogIGFTcmMgPSBkaXYyNTUocGlwZS0+YUlucHV0ICogcGlwZS0+c2hhcGUpOwoKICAvLy0tLS0tIHJlc3VsdCBhbHBoYSBhbmQgbm9uLWlzb2xhdGVkIGdyb3VwIGVsZW1lbnQgY29ycmVjdGlvbgogIGFSZXN1bHQgPSBhU3JjICsgYURlc3QgLSBkaXYyNTUoYVNyYyAqIGFEZXN0KTsKICBhbHBoYTIgPSBhUmVzdWx0OwoKICAvLy0tLS0tIHJlc3VsdCBjb2xvcgogIGlmIChhbHBoYTIgPT0gMCkgewogICAgY1Jlc3VsdDAgPSAwOwogICAgY1Jlc3VsdDEgPSAwOwogICAgY1Jlc3VsdDIgPSAwOwogICAgY1Jlc3VsdDMgPSAwOwogIH0gZWxzZSB7CiAgICBjUmVzdWx0MCA9IHN0YXRlLT5jbXlrVHJhbnNmZXJDWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFswXSArCgkJCQkJICAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMF0pIC8gYWxwaGEyKV07CiAgICBjUmVzdWx0MSA9IHN0YXRlLT5jbXlrVHJhbnNmZXJNWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFsxXSArCgkJCQkJICAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMV0pIC8gYWxwaGEyKV07CiAgICBjUmVzdWx0MiA9IHN0YXRlLT5jbXlrVHJhbnNmZXJZWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFsyXSArCgkJCQkJICAgICAgYVNyYyAqIHBpcGUtPmNTcmNbMl0pIC8gYWxwaGEyKV07CiAgICBjUmVzdWx0MyA9IHN0YXRlLT5jbXlrVHJhbnNmZXJLWyhHdWNoYXIpKCgoYWxwaGEyIC0gYVNyYykgKiBjRGVzdFszXSArCgkJCQkJICAgICAgYVNyYyAqIHBpcGUtPmNTcmNbM10pIC8gYWxwaGEyKV07CiAgfQoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgMSkgewogICAgcGlwZS0+ZGVzdENvbG9yUHRyWzBdID0gKHN0YXRlLT5vdmVycHJpbnRBZGRpdGl2ZSAmJiBwaXBlLT5zaGFwZSAhPSAwKSA/IAogICAgICAgICAgICAgIHN0ZDo6bWluPGludD4ocGlwZS0+ZGVzdENvbG9yUHRyWzBdICsgY1Jlc3VsdDAsIDI1NSkgOgogICAgICAgICAgICAgIGNSZXN1bHQwOwogIH0KICBpZiAoc3RhdGUtPm92ZXJwcmludE1hc2sgJiAyKSB7CiAgICBwaXBlLT5kZXN0Q29sb3JQdHJbMV0gPSAoc3RhdGUtPm92ZXJwcmludEFkZGl0aXZlICYmIHBpcGUtPnNoYXBlICE9IDApID8gCiAgICAgICAgICAgICAgc3RkOjptaW48aW50PihwaXBlLT5kZXN0Q29sb3JQdHJbMV0gKyBjUmVzdWx0MSwgMjU1KSA6CiAgICAgICAgICAgICAgY1Jlc3VsdDE7CiAgfQogIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIDQpIHsKICAgIHBpcGUtPmRlc3RDb2xvclB0clsyXSA9IChzdGF0ZS0+b3ZlcnByaW50QWRkaXRpdmUgJiYgcGlwZS0+c2hhcGUgIT0gMCkgPyAKICAgICAgICAgICAgICBzdGQ6Om1pbjxpbnQ+KHBpcGUtPmRlc3RDb2xvclB0clsyXSArIGNSZXN1bHQyLCAyNTUpIDoKICAgICAgICAgICAgICBjUmVzdWx0MjsKICB9CiAgaWYgKHN0YXRlLT5vdmVycHJpbnRNYXNrICYgOCkgewogICAgcGlwZS0+ZGVzdENvbG9yUHRyWzNdID0gKHN0YXRlLT5vdmVycHJpbnRBZGRpdGl2ZSAmJiBwaXBlLT5zaGFwZSAhPSAwKSA/IAogICAgICAgICAgICAgIHN0ZDo6bWluPGludD4ocGlwZS0+ZGVzdENvbG9yUHRyWzNdICsgY1Jlc3VsdDMsIDI1NSkgOgogICAgICAgICAgICAgIGNSZXN1bHQzOwogIH0KICBwaXBlLT5kZXN0Q29sb3JQdHIgKz0gNDsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSBhUmVzdWx0OwoKICArK3BpcGUtPng7Cn0KCi8vIHNwZWNpYWwgY2FzZToKLy8gIXBpcGUtPnBhdHRlcm4gJiYgIXBpcGUtPm5vVHJhbnNwYXJlbmN5ICYmICFzdGF0ZS0+c29mdE1hc2sgJiYKLy8gcGlwZS0+dXNlc1NoYXBlICYmICFwaXBlLT5hbHBoYTBQdHIgJiYgIXN0YXRlLT5ibGVuZEZ1bmMgJiYKLy8gIXBpcGUtPm5vbklzb2xhdGVkR3JvdXAgJiYKLy8gYml0bWFwLT5tb2RlID09IHNwbGFzaE1vZGVEZXZpY2VOOCAmJiBwaXBlLT5kZXN0QWxwaGFQdHIKdm9pZCBTcGxhc2g6OnBpcGVSdW5BQURldmljZU44KFNwbGFzaFBpcGUgKnBpcGUpIHsKICBHdWNoYXIgYVNyYywgYURlc3QsIGFscGhhMiwgYVJlc3VsdDsKICBTcGxhc2hDb2xvciBjRGVzdDsKICBHdWNoYXIgY1Jlc3VsdFtTUE9UX05DT01QUys0XTsKICBpbnQgY3AsIG1hc2s7CgogIC8vLS0tLS0gcmVhZCBkZXN0aW5hdGlvbiBwaXhlbAogIGZvciAoY3A9MDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgY0Rlc3RbY3BdID0gcGlwZS0+ZGVzdENvbG9yUHRyW2NwXTsKICBhRGVzdCA9ICpwaXBlLT5kZXN0QWxwaGFQdHI7CgogIC8vLS0tLS0gc291cmNlIGFscGhhCiAgYVNyYyA9IGRpdjI1NShwaXBlLT5hSW5wdXQgKiBwaXBlLT5zaGFwZSk7CgogIC8vLS0tLS0gcmVzdWx0IGFscGhhIGFuZCBub24taXNvbGF0ZWQgZ3JvdXAgZWxlbWVudCBjb3JyZWN0aW9uCiAgYVJlc3VsdCA9IGFTcmMgKyBhRGVzdCAtIGRpdjI1NShhU3JjICogYURlc3QpOwogIGFscGhhMiA9IGFSZXN1bHQ7CgogIC8vLS0tLS0gcmVzdWx0IGNvbG9yCiAgaWYgKGFscGhhMiA9PSAwKSB7CiAgICBmb3IgKGNwPTA7IGNwIDwgU1BPVF9OQ09NUFMrNDsgY3ArKykKICAgICAgY1Jlc3VsdFtjcF0gPSAwOwogIH0gZWxzZSB7CiAgICBmb3IgKGNwPTA7IGNwIDwgU1BPVF9OQ09NUFMrNDsgY3ArKykKICAgICAgY1Jlc3VsdFtjcF0gPSBzdGF0ZS0+ZGV2aWNlTlRyYW5zZmVyW2NwXVsoR3VjaGFyKSgoKGFscGhhMiAtIGFTcmMpICogY0Rlc3RbY3BdICsKCQkJCQkgICAgICBhU3JjICogcGlwZS0+Y1NyY1tjcF0pIC8gYWxwaGEyKV07CiAgfQoKICAvLy0tLS0tIHdyaXRlIGRlc3RpbmF0aW9uIHBpeGVsCiAgbWFzayA9IDE7CiAgZm9yIChjcD0wOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspIHsKICAgIGlmIChzdGF0ZS0+b3ZlcnByaW50TWFzayAmIG1hc2spIHsKICAgICAgcGlwZS0+ZGVzdENvbG9yUHRyW2NwXSA9IGNSZXN1bHRbY3BdOwogICAgfQogICAgbWFzayA8PD0gMTsKICB9CiAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IChTUE9UX05DT01QUys0KTsKICAqcGlwZS0+ZGVzdEFscGhhUHRyKysgPSBhUmVzdWx0OwoKICArK3BpcGUtPng7Cn0KI2VuZGlmCgppbmxpbmUgdm9pZCBTcGxhc2g6OnBpcGVTZXRYWShTcGxhc2hQaXBlICpwaXBlLCBpbnQgeCwgaW50IHkpIHsKICBwaXBlLT54ID0geDsKICBwaXBlLT55ID0geTsKICBpZiAoc3RhdGUtPnNvZnRNYXNrKSB7CiAgICBwaXBlLT5zb2Z0TWFza1B0ciA9CiAgICAgICAgJnN0YXRlLT5zb2Z0TWFzay0+ZGF0YVt5ICogc3RhdGUtPnNvZnRNYXNrLT5yb3dTaXplICsgeF07CiAgfQogIHN3aXRjaCAoYml0bWFwLT5tb2RlKSB7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBwaXBlLT5kZXN0Q29sb3JQdHIgPSAmYml0bWFwLT5kYXRhW3kgKiBiaXRtYXAtPnJvd1NpemUgKyAoeCA+PiAzKV07CiAgICBwaXBlLT5kZXN0Q29sb3JNYXNrID0gMHg4MCA+PiAoeCAmIDcpOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzg6CiAgICBwaXBlLT5kZXN0Q29sb3JQdHIgPSAmYml0bWFwLT5kYXRhW3kgKiBiaXRtYXAtPnJvd1NpemUgKyB4XTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIHBpcGUtPmRlc3RDb2xvclB0ciA9ICZiaXRtYXAtPmRhdGFbeSAqIGJpdG1hcC0+cm93U2l6ZSArIDMgKiB4XTsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgcGlwZS0+ZGVzdENvbG9yUHRyID0gJmJpdG1hcC0+ZGF0YVt5ICogYml0bWFwLT5yb3dTaXplICsgNCAqIHhdOwogICAgYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgogICAgcGlwZS0+ZGVzdENvbG9yUHRyID0gJmJpdG1hcC0+ZGF0YVt5ICogYml0bWFwLT5yb3dTaXplICsgNCAqIHhdOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICBwaXBlLT5kZXN0Q29sb3JQdHIgPSAmYml0bWFwLT5kYXRhW3kgKiBiaXRtYXAtPnJvd1NpemUgKyAoU1BPVF9OQ09NUFMgKyA0KSAqIHhdOwogICAgYnJlYWs7CiNlbmRpZgogIH0KICBpZiAoYml0bWFwLT5hbHBoYSkgewogICAgcGlwZS0+ZGVzdEFscGhhUHRyID0gJmJpdG1hcC0+YWxwaGFbeSAqIGJpdG1hcC0+d2lkdGggKyB4XTsKICB9IGVsc2UgewogICAgcGlwZS0+ZGVzdEFscGhhUHRyID0gTlVMTDsKICB9CiAgaWYgKHN0YXRlLT5pbk5vbklzb2xhdGVkR3JvdXAgJiYgYWxwaGEwQml0bWFwLT5hbHBoYSkgewogICAgcGlwZS0+YWxwaGEwUHRyID0KICAgICAgICAmYWxwaGEwQml0bWFwLT5hbHBoYVsoYWxwaGEwWSArIHkpICogYWxwaGEwQml0bWFwLT53aWR0aCArCgkJCSAgICAgKGFscGhhMFggKyB4KV07CiAgfSBlbHNlIHsKICAgIHBpcGUtPmFscGhhMFB0ciA9IE5VTEw7CiAgfQp9CgppbmxpbmUgdm9pZCBTcGxhc2g6OnBpcGVJbmNYKFNwbGFzaFBpcGUgKnBpcGUpIHsKICArK3BpcGUtPng7CiAgaWYgKHN0YXRlLT5zb2Z0TWFzaykgewogICAgKytwaXBlLT5zb2Z0TWFza1B0cjsKICB9CiAgc3dpdGNoIChiaXRtYXAtPm1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGlmICghKHBpcGUtPmRlc3RDb2xvck1hc2sgPj49IDEpKSB7CiAgICAgIHBpcGUtPmRlc3RDb2xvck1hc2sgPSAweDgwOwogICAgICArK3BpcGUtPmRlc3RDb2xvclB0cjsKICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgKytwaXBlLT5kZXN0Q29sb3JQdHI7CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogIGNhc2Ugc3BsYXNoTW9kZUJHUjg6CiAgICBwaXBlLT5kZXN0Q29sb3JQdHIgKz0gMzsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IDQ7CiAgICBicmVhazsKI2lmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICBwaXBlLT5kZXN0Q29sb3JQdHIgKz0gNDsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgcGlwZS0+ZGVzdENvbG9yUHRyICs9IChTUE9UX05DT01QUys0KTsKICAgIGJyZWFrOwojZW5kaWYKICB9CiAgaWYgKHBpcGUtPmRlc3RBbHBoYVB0cikgewogICAgKytwaXBlLT5kZXN0QWxwaGFQdHI7CiAgfQogIGlmIChwaXBlLT5hbHBoYTBQdHIpIHsKICAgICsrcGlwZS0+YWxwaGEwUHRyOwogIH0KfQoKaW5saW5lIHZvaWQgU3BsYXNoOjpkcmF3UGl4ZWwoU3BsYXNoUGlwZSAqcGlwZSwgaW50IHgsIGludCB5LCBHQm9vbCBub0NsaXApIHsKICBpZiAodW5saWtlbHkoeSA8IDApKQogICAgcmV0dXJuOwoKICBpZiAobm9DbGlwIHx8IHN0YXRlLT5jbGlwLT50ZXN0KHgsIHkpKSB7CiAgICBwaXBlU2V0WFkocGlwZSwgeCwgeSk7CiAgICAodGhpcy0+KnBpcGUtPnJ1bikocGlwZSk7CiAgICB1cGRhdGVNb2RYKHgpOwogICAgdXBkYXRlTW9kWSh5KTsKICB9Cn0KCmlubGluZSB2b2lkIFNwbGFzaDo6ZHJhd0FBUGl4ZWxJbml0KCkgewogIGFhQnVmWSA9IC0xOwp9CgppbmxpbmUgdm9pZCBTcGxhc2g6OmRyYXdBQVBpeGVsKFNwbGFzaFBpcGUgKnBpcGUsIGludCB4LCBpbnQgeSkgewojaWYgc3BsYXNoQUFTaXplID09IDQKICBzdGF0aWMgaW50IGJpdENvdW50NFsxNl0gPSB7IDAsIDEsIDEsIDIsIDEsIDIsIDIsIDMsCgkJCSAgICAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0IH07CiAgaW50IHc7CiNlbHNlCiAgaW50IHh4LCB5eTsKI2VuZGlmCiAgU3BsYXNoQ29sb3JQdHIgcDsKICBpbnQgeDAsIHgxLCB0OwoKICBpZiAoeCA8IDAgfHwgeCA+PSBiaXRtYXAtPndpZHRoIHx8CiAgICAgIHkgPCBzdGF0ZS0+Y2xpcC0+Z2V0WU1pbkkoKSB8fCB5ID4gc3RhdGUtPmNsaXAtPmdldFlNYXhJKCkpIHsKICAgIHJldHVybjsKICB9CgogIC8vIHVwZGF0ZSBhYUJ1ZgogIGlmICh5ICE9IGFhQnVmWSkgewogICAgbWVtc2V0KGFhQnVmLT5nZXREYXRhUHRyKCksIDB4ZmYsCgkgICBhYUJ1Zi0+Z2V0Um93U2l6ZSgpICogYWFCdWYtPmdldEhlaWdodCgpKTsKICAgIHgwID0gMDsKICAgIHgxID0gYml0bWFwLT53aWR0aCAtIDE7CiAgICBzdGF0ZS0+Y2xpcC0+Y2xpcEFBTGluZShhYUJ1ZiwgJngwLCAmeDEsIHkpOwogICAgYWFCdWZZID0geTsKICB9CgogIC8vIGNvbXB1dGUgdGhlIHNoYXBlIHZhbHVlCiNpZiBzcGxhc2hBQVNpemUgPT0gNAogIHAgPSBhYUJ1Zi0+Z2V0RGF0YVB0cigpICsgKHggPj4gMSk7CiAgdyA9IGFhQnVmLT5nZXRSb3dTaXplKCk7CiAgaWYgKHggJiAxKSB7CiAgICB0ID0gYml0Q291bnQ0WypwICYgMHgwZl0gKyBiaXRDb3VudDRbcFt3XSAmIDB4MGZdICsKICAgICAgICBiaXRDb3VudDRbcFsyKnddICYgMHgwZl0gKyBiaXRDb3VudDRbcFszKnddICYgMHgwZl07CiAgfSBlbHNlIHsKICAgIHQgPSBiaXRDb3VudDRbKnAgPj4gNF0gKyBiaXRDb3VudDRbcFt3XSA+PiA0XSArCiAgICAgICAgYml0Q291bnQ0W3BbMip3XSA+PiA0XSArIGJpdENvdW50NFtwWzMqd10gPj4gNF07CiAgfQojZWxzZQogIHQgPSAwOwogIGZvciAoeXkgPSAwOyB5eSA8IHNwbGFzaEFBU2l6ZTsgKyt5eSkgewogICAgZm9yICh4eCA9IDA7IHh4IDwgc3BsYXNoQUFTaXplOyArK3h4KSB7CiAgICAgIHAgPSBhYUJ1Zi0+Z2V0RGF0YVB0cigpICsgeXkgKiBhYUJ1Zi0+Z2V0Um93U2l6ZSgpICsKCSAgKCh4ICogc3BsYXNoQUFTaXplICsgeHgpID4+IDMpOwogICAgICB0ICs9ICgqcCA+PiAoNyAtICgoeCAqIHNwbGFzaEFBU2l6ZSArIHh4KSAmIDcpKSkgJiAxOwogICAgfQogIH0KI2VuZGlmCgogIC8vIGRyYXcgdGhlIHBpeGVsCiAgaWYgKHQgIT0gMCkgewogICAgcGlwZVNldFhZKHBpcGUsIHgsIHkpOwogICAgcGlwZS0+c2hhcGUgPSBkaXYyNTUoYWFHYW1tYVt0XSAqIHBpcGUtPnNoYXBlKTsKICAgICh0aGlzLT4qcGlwZS0+cnVuKShwaXBlKTsKICAgIHVwZGF0ZU1vZFgoeCk7CiAgICB1cGRhdGVNb2RZKHkpOwogIH0KfQoKaW5saW5lIHZvaWQgU3BsYXNoOjpkcmF3U3BhbihTcGxhc2hQaXBlICpwaXBlLCBpbnQgeDAsIGludCB4MSwgaW50IHksCgkJCSAgICAgR0Jvb2wgbm9DbGlwKSB7CiAgaW50IHg7CgogIGlmIChub0NsaXApIHsKICAgIHBpcGVTZXRYWShwaXBlLCB4MCwgeSk7CiAgICBmb3IgKHggPSB4MDsgeCA8PSB4MTsgKyt4KSB7CiAgICAgICh0aGlzLT4qcGlwZS0+cnVuKShwaXBlKTsKICAgIH0KICAgIHVwZGF0ZU1vZFgoeDApOwogICAgdXBkYXRlTW9kWCh4MSk7CiAgICB1cGRhdGVNb2RZKHkpOwogIH0gZWxzZSB7CiAgICBpZiAoeDAgPCBzdGF0ZS0+Y2xpcC0+Z2V0WE1pbkkoKSkgewogICAgICB4MCA9IHN0YXRlLT5jbGlwLT5nZXRYTWluSSgpOwogICAgfQogICAgaWYgKHgxID4gc3RhdGUtPmNsaXAtPmdldFhNYXhJKCkpIHsKICAgICAgeDEgPSBzdGF0ZS0+Y2xpcC0+Z2V0WE1heEkoKTsKICAgIH0KICAgIHBpcGVTZXRYWShwaXBlLCB4MCwgeSk7CiAgICBmb3IgKHggPSB4MDsgeCA8PSB4MTsgKyt4KSB7CiAgICAgIGlmIChzdGF0ZS0+Y2xpcC0+dGVzdCh4LCB5KSkgewoJKHRoaXMtPipwaXBlLT5ydW4pKHBpcGUpOwoJdXBkYXRlTW9kWCh4KTsKCXVwZGF0ZU1vZFkoeSk7CiAgICAgIH0gZWxzZSB7CglwaXBlSW5jWChwaXBlKTsKICAgICAgfQogICAgfQogIH0KfQoKaW5saW5lIHZvaWQgU3BsYXNoOjpkcmF3QUFMaW5lKFNwbGFzaFBpcGUgKnBpcGUsIGludCB4MCwgaW50IHgxLCBpbnQgeSkgewojaWYgc3BsYXNoQUFTaXplID09IDQKICBzdGF0aWMgaW50IGJpdENvdW50NFsxNl0gPSB7IDAsIDEsIDEsIDIsIDEsIDIsIDIsIDMsCgkJCSAgICAgICAxLCAyLCAyLCAzLCAyLCAzLCAzLCA0IH07CiAgU3BsYXNoQ29sb3JQdHIgcDAsIHAxLCBwMiwgcDM7CiAgaW50IHQ7CiNlbHNlCiAgU3BsYXNoQ29sb3JQdHIgcDsKICBpbnQgeHgsIHl5LCB0OwojZW5kaWYKICBpbnQgeDsKCiNpZiBzcGxhc2hBQVNpemUgPT0gNAogIHAwID0gYWFCdWYtPmdldERhdGFQdHIoKSArICh4MCA+PiAxKTsKICBwMSA9IHAwICsgYWFCdWYtPmdldFJvd1NpemUoKTsKICBwMiA9IHAxICsgYWFCdWYtPmdldFJvd1NpemUoKTsKICBwMyA9IHAyICsgYWFCdWYtPmdldFJvd1NpemUoKTsKI2VuZGlmCiAgcGlwZVNldFhZKHBpcGUsIHgwLCB5KTsKICBmb3IgKHggPSB4MDsgeCA8PSB4MTsgKyt4KSB7CgogICAgLy8gY29tcHV0ZSB0aGUgc2hhcGUgdmFsdWUKI2lmIHNwbGFzaEFBU2l6ZSA9PSA0CiAgICBpZiAoeCAmIDEpIHsKICAgICAgdCA9IGJpdENvdW50NFsqcDAgJiAweDBmXSArIGJpdENvdW50NFsqcDEgJiAweDBmXSArCgkgIGJpdENvdW50NFsqcDIgJiAweDBmXSArIGJpdENvdW50NFsqcDMgJiAweDBmXTsKICAgICAgKytwMDsgKytwMTsgKytwMjsgKytwMzsKICAgIH0gZWxzZSB7CiAgICAgIHQgPSBiaXRDb3VudDRbKnAwID4+IDRdICsgYml0Q291bnQ0WypwMSA+PiA0XSArCgkgIGJpdENvdW50NFsqcDIgPj4gNF0gKyBiaXRDb3VudDRbKnAzID4+IDRdOwogICAgfQojZWxzZQogICAgdCA9IDA7CiAgICBmb3IgKHl5ID0gMDsgeXkgPCBzcGxhc2hBQVNpemU7ICsreXkpIHsKICAgICAgZm9yICh4eCA9IDA7IHh4IDwgc3BsYXNoQUFTaXplOyArK3h4KSB7CglwID0gYWFCdWYtPmdldERhdGFQdHIoKSArIHl5ICogYWFCdWYtPmdldFJvd1NpemUoKSArCgkgICAgKCh4ICogc3BsYXNoQUFTaXplICsgeHgpID4+IDMpOwoJdCArPSAoKnAgPj4gKDcgLSAoKHggKiBzcGxhc2hBQVNpemUgKyB4eCkgJiA3KSkpICYgMTsKICAgICAgfQogICAgfQojZW5kaWYKCiAgICBpZiAodCAhPSAwKSB7CiAgICAgIHBpcGUtPnNoYXBlID0gYWFHYW1tYVt0XTsKICAgICAgKHRoaXMtPipwaXBlLT5ydW4pKHBpcGUpOwogICAgICB1cGRhdGVNb2RYKHgpOwogICAgICB1cGRhdGVNb2RZKHkpOwogICAgfSBlbHNlIHsKICAgICAgcGlwZUluY1gocGlwZSk7CiAgICB9CiAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLy8gVHJhbnNmb3JtIGEgcG9pbnQgZnJvbSB1c2VyIHNwYWNlIHRvIGRldmljZSBzcGFjZS4KaW5saW5lIHZvaWQgU3BsYXNoOjp0cmFuc2Zvcm0oU3BsYXNoQ29vcmQgKm1hdHJpeCwKCQkJICAgICAgU3BsYXNoQ29vcmQgeGksIFNwbGFzaENvb3JkIHlpLAoJCQkgICAgICBTcGxhc2hDb29yZCAqeG8sIFNwbGFzaENvb3JkICp5bykgewogIC8vICAgICAgICAgICAgICAgICAgICAgICAgICBbIG1bMF0gbVsxXSAwIF0KICAvLyBbeG8geW8gMV0gPSBbeGkgeWkgMV0gKiAgWyBtWzJdIG1bM10gMCBdCiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFsgbVs0XSBtWzVdIDEgXQogICp4byA9IHhpICogbWF0cml4WzBdICsgeWkgKiBtYXRyaXhbMl0gKyBtYXRyaXhbNF07CiAgKnlvID0geGkgKiBtYXRyaXhbMV0gKyB5aSAqIG1hdHJpeFszXSArIG1hdHJpeFs1XTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTcGxhc2g6OlNwbGFzaChTcGxhc2hCaXRtYXAgKmJpdG1hcEEsIEdCb29sIHZlY3RvckFudGlhbGlhc0EsCgkgICAgICAgU3BsYXNoU2NyZWVuUGFyYW1zICpzY3JlZW5QYXJhbXMpIHsKICBpbnQgaTsKCiAgYml0bWFwID0gYml0bWFwQTsKICB2ZWN0b3JBbnRpYWxpYXMgPSB2ZWN0b3JBbnRpYWxpYXNBOwogIGluU2hhZGluZyA9IGdGYWxzZTsKICBzdGF0ZSA9IG5ldyBTcGxhc2hTdGF0ZShiaXRtYXAtPndpZHRoLCBiaXRtYXAtPmhlaWdodCwgdmVjdG9yQW50aWFsaWFzLAoJCQkgIHNjcmVlblBhcmFtcyk7CiAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgYWFCdWYgPSBuZXcgU3BsYXNoQml0bWFwKHNwbGFzaEFBU2l6ZSAqIGJpdG1hcC0+d2lkdGgsIHNwbGFzaEFBU2l6ZSwKCQkJICAgICAxLCBzcGxhc2hNb2RlTW9ubzEsIGdGYWxzZSk7CiAgICBmb3IgKGkgPSAwOyBpIDw9IHNwbGFzaEFBU2l6ZSAqIHNwbGFzaEFBU2l6ZTsgKytpKSB7CiAgICAgIGFhR2FtbWFbaV0gPSAoR3VjaGFyKXNwbGFzaFJvdW5kKAoJCSAgICAgICBzcGxhc2hQb3coKFNwbGFzaENvb3JkKWkgLwoJCQkJIChTcGxhc2hDb29yZCkoc3BsYXNoQUFTaXplICogc3BsYXNoQUFTaXplKSwKCQkJCSBzcGxhc2hBQUdhbW1hKSAqIDI1NSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGFhQnVmID0gTlVMTDsKICB9CiAgbWluTGluZVdpZHRoID0gMDsKICBjbGVhck1vZFJlZ2lvbigpOwogIGRlYnVnTW9kZSA9IGdGYWxzZTsKfQoKU3BsYXNoOjpTcGxhc2goU3BsYXNoQml0bWFwICpiaXRtYXBBLCBHQm9vbCB2ZWN0b3JBbnRpYWxpYXNBLAoJICAgICAgIFNwbGFzaFNjcmVlbiAqc2NyZWVuQSkgewogIGludCBpOwoKICBiaXRtYXAgPSBiaXRtYXBBOwogIGluU2hhZGluZyA9IGdGYWxzZTsKICB2ZWN0b3JBbnRpYWxpYXMgPSB2ZWN0b3JBbnRpYWxpYXNBOwogIHN0YXRlID0gbmV3IFNwbGFzaFN0YXRlKGJpdG1hcC0+d2lkdGgsIGJpdG1hcC0+aGVpZ2h0LCB2ZWN0b3JBbnRpYWxpYXMsCgkJCSAgc2NyZWVuQSk7CiAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgYWFCdWYgPSBuZXcgU3BsYXNoQml0bWFwKHNwbGFzaEFBU2l6ZSAqIGJpdG1hcC0+d2lkdGgsIHNwbGFzaEFBU2l6ZSwKCQkJICAgICAxLCBzcGxhc2hNb2RlTW9ubzEsIGdGYWxzZSk7CiAgICBmb3IgKGkgPSAwOyBpIDw9IHNwbGFzaEFBU2l6ZSAqIHNwbGFzaEFBU2l6ZTsgKytpKSB7CiAgICAgIGFhR2FtbWFbaV0gPSAoR3VjaGFyKXNwbGFzaFJvdW5kKAoJCSAgICAgICBzcGxhc2hQb3coKFNwbGFzaENvb3JkKWkgLwoJCQkJIChTcGxhc2hDb29yZCkoc3BsYXNoQUFTaXplICogc3BsYXNoQUFTaXplKSwKCQkJCSBzcGxhc2hBQUdhbW1hKSAqIDI1NSk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGFhQnVmID0gTlVMTDsKICB9CiAgbWluTGluZVdpZHRoID0gMDsKICBjbGVhck1vZFJlZ2lvbigpOwogIGRlYnVnTW9kZSA9IGdGYWxzZTsKfQoKU3BsYXNoOjp+U3BsYXNoKCkgewogIHdoaWxlIChzdGF0ZS0+bmV4dCkgewogICAgcmVzdG9yZVN0YXRlKCk7CiAgfQogIGRlbGV0ZSBzdGF0ZTsKICBpZiAodmVjdG9yQW50aWFsaWFzKSB7CiAgICBkZWxldGUgYWFCdWY7CiAgfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBzdGF0ZSByZWFkCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTcGxhc2hDb29yZCAqU3BsYXNoOjpnZXRNYXRyaXgoKSB7CiAgcmV0dXJuIHN0YXRlLT5tYXRyaXg7Cn0KClNwbGFzaFBhdHRlcm4gKlNwbGFzaDo6Z2V0U3Ryb2tlUGF0dGVybigpIHsKICByZXR1cm4gc3RhdGUtPnN0cm9rZVBhdHRlcm47Cn0KClNwbGFzaFBhdHRlcm4gKlNwbGFzaDo6Z2V0RmlsbFBhdHRlcm4oKSB7CiAgcmV0dXJuIHN0YXRlLT5maWxsUGF0dGVybjsKfQoKU3BsYXNoU2NyZWVuICpTcGxhc2g6OmdldFNjcmVlbigpIHsKICByZXR1cm4gc3RhdGUtPnNjcmVlbjsKfQoKU3BsYXNoQmxlbmRGdW5jIFNwbGFzaDo6Z2V0QmxlbmRGdW5jKCkgewogIHJldHVybiBzdGF0ZS0+YmxlbmRGdW5jOwp9CgpTcGxhc2hDb29yZCBTcGxhc2g6OmdldFN0cm9rZUFscGhhKCkgewogIHJldHVybiBzdGF0ZS0+c3Ryb2tlQWxwaGE7Cn0KClNwbGFzaENvb3JkIFNwbGFzaDo6Z2V0RmlsbEFscGhhKCkgewogIHJldHVybiBzdGF0ZS0+ZmlsbEFscGhhOwp9CgpTcGxhc2hDb29yZCBTcGxhc2g6OmdldExpbmVXaWR0aCgpIHsKICByZXR1cm4gc3RhdGUtPmxpbmVXaWR0aDsKfQoKaW50IFNwbGFzaDo6Z2V0TGluZUNhcCgpIHsKICByZXR1cm4gc3RhdGUtPmxpbmVDYXA7Cn0KCmludCBTcGxhc2g6OmdldExpbmVKb2luKCkgewogIHJldHVybiBzdGF0ZS0+bGluZUpvaW47Cn0KClNwbGFzaENvb3JkIFNwbGFzaDo6Z2V0TWl0ZXJMaW1pdCgpIHsKICByZXR1cm4gc3RhdGUtPm1pdGVyTGltaXQ7Cn0KClNwbGFzaENvb3JkIFNwbGFzaDo6Z2V0RmxhdG5lc3MoKSB7CiAgcmV0dXJuIHN0YXRlLT5mbGF0bmVzczsKfQoKU3BsYXNoQ29vcmQgKlNwbGFzaDo6Z2V0TGluZURhc2goKSB7CiAgcmV0dXJuIHN0YXRlLT5saW5lRGFzaDsKfQoKaW50IFNwbGFzaDo6Z2V0TGluZURhc2hMZW5ndGgoKSB7CiAgcmV0dXJuIHN0YXRlLT5saW5lRGFzaExlbmd0aDsKfQoKU3BsYXNoQ29vcmQgU3BsYXNoOjpnZXRMaW5lRGFzaFBoYXNlKCkgewogIHJldHVybiBzdGF0ZS0+bGluZURhc2hQaGFzZTsKfQoKR0Jvb2wgU3BsYXNoOjpnZXRTdHJva2VBZGp1c3QoKSB7CiAgcmV0dXJuIHN0YXRlLT5zdHJva2VBZGp1c3Q7Cn0KClNwbGFzaENsaXAgKlNwbGFzaDo6Z2V0Q2xpcCgpIHsKICByZXR1cm4gc3RhdGUtPmNsaXA7Cn0KClNwbGFzaEJpdG1hcCAqU3BsYXNoOjpnZXRTb2Z0TWFzaygpIHsKICByZXR1cm4gc3RhdGUtPnNvZnRNYXNrOwp9CgpHQm9vbCBTcGxhc2g6OmdldEluTm9uSXNvbGF0ZWRHcm91cCgpIHsKICByZXR1cm4gc3RhdGUtPmluTm9uSXNvbGF0ZWRHcm91cDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gc3RhdGUgd3JpdGUKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3BsYXNoOjpzZXRNYXRyaXgoU3BsYXNoQ29vcmQgKm1hdHJpeCkgewogIG1lbWNweShzdGF0ZS0+bWF0cml4LCBtYXRyaXgsIDYgKiBzaXplb2YoU3BsYXNoQ29vcmQpKTsKfQoKdm9pZCBTcGxhc2g6OnNldFN0cm9rZVBhdHRlcm4oU3BsYXNoUGF0dGVybiAqc3Ryb2tlUGF0dGVybikgewogIHN0YXRlLT5zZXRTdHJva2VQYXR0ZXJuKHN0cm9rZVBhdHRlcm4pOwp9Cgp2b2lkIFNwbGFzaDo6c2V0RmlsbFBhdHRlcm4oU3BsYXNoUGF0dGVybiAqZmlsbFBhdHRlcm4pIHsKICBzdGF0ZS0+c2V0RmlsbFBhdHRlcm4oZmlsbFBhdHRlcm4pOwp9Cgp2b2lkIFNwbGFzaDo6c2V0U2NyZWVuKFNwbGFzaFNjcmVlbiAqc2NyZWVuKSB7CiAgc3RhdGUtPnNldFNjcmVlbihzY3JlZW4pOwp9Cgp2b2lkIFNwbGFzaDo6c2V0QmxlbmRGdW5jKFNwbGFzaEJsZW5kRnVuYyBmdW5jKSB7CiAgc3RhdGUtPmJsZW5kRnVuYyA9IGZ1bmM7Cn0KCnZvaWQgU3BsYXNoOjpzZXRTdHJva2VBbHBoYShTcGxhc2hDb29yZCBhbHBoYSkgewogIHN0YXRlLT5zdHJva2VBbHBoYSA9IGFscGhhOwp9Cgp2b2lkIFNwbGFzaDo6c2V0RmlsbEFscGhhKFNwbGFzaENvb3JkIGFscGhhKSB7CiAgc3RhdGUtPmZpbGxBbHBoYSA9IGFscGhhOwp9Cgp2b2lkIFNwbGFzaDo6c2V0RmlsbE92ZXJwcmludChHQm9vbCBmb3ApIHsKICBzdGF0ZS0+ZmlsbE92ZXJwcmludCA9IGZvcDsKfQoKdm9pZCBTcGxhc2g6OnNldFN0cm9rZU92ZXJwcmludChHQm9vbCBnb3ApIHsKICBzdGF0ZS0+c3Ryb2tlT3ZlcnByaW50ID0gZ29wOwp9Cgp2b2lkIFNwbGFzaDo6c2V0T3ZlcnByaW50TW9kZShpbnQgb3BtKSB7CiAgc3RhdGUtPm92ZXJwcmludE1vZGUgPSBvcG07Cn0KCnZvaWQgU3BsYXNoOjpzZXRMaW5lV2lkdGgoU3BsYXNoQ29vcmQgbGluZVdpZHRoKSB7CiAgc3RhdGUtPmxpbmVXaWR0aCA9IGxpbmVXaWR0aDsKfQoKdm9pZCBTcGxhc2g6OnNldExpbmVDYXAoaW50IGxpbmVDYXApIHsKICBzdGF0ZS0+bGluZUNhcCA9IGxpbmVDYXA7Cn0KCnZvaWQgU3BsYXNoOjpzZXRMaW5lSm9pbihpbnQgbGluZUpvaW4pIHsKICBzdGF0ZS0+bGluZUpvaW4gPSBsaW5lSm9pbjsKfQoKdm9pZCBTcGxhc2g6OnNldE1pdGVyTGltaXQoU3BsYXNoQ29vcmQgbWl0ZXJMaW1pdCkgewogIHN0YXRlLT5taXRlckxpbWl0ID0gbWl0ZXJMaW1pdDsKfQoKdm9pZCBTcGxhc2g6OnNldEZsYXRuZXNzKFNwbGFzaENvb3JkIGZsYXRuZXNzKSB7CiAgaWYgKGZsYXRuZXNzIDwgMSkgewogICAgc3RhdGUtPmZsYXRuZXNzID0gMTsKICB9IGVsc2UgewogICAgc3RhdGUtPmZsYXRuZXNzID0gZmxhdG5lc3M7CiAgfQp9Cgp2b2lkIFNwbGFzaDo6c2V0TGluZURhc2goU3BsYXNoQ29vcmQgKmxpbmVEYXNoLCBpbnQgbGluZURhc2hMZW5ndGgsCgkJCSBTcGxhc2hDb29yZCBsaW5lRGFzaFBoYXNlKSB7CiAgc3RhdGUtPnNldExpbmVEYXNoKGxpbmVEYXNoLCBsaW5lRGFzaExlbmd0aCwgbGluZURhc2hQaGFzZSk7Cn0KCnZvaWQgU3BsYXNoOjpzZXRTdHJva2VBZGp1c3QoR0Jvb2wgc3Ryb2tlQWRqdXN0KSB7CiAgc3RhdGUtPnN0cm9rZUFkanVzdCA9IHN0cm9rZUFkanVzdDsKfQoKdm9pZCBTcGxhc2g6OmNsaXBSZXNldFRvUmVjdChTcGxhc2hDb29yZCB4MCwgU3BsYXNoQ29vcmQgeTAsCgkJCSAgICAgU3BsYXNoQ29vcmQgeDEsIFNwbGFzaENvb3JkIHkxKSB7CiAgc3RhdGUtPmNsaXAtPnJlc2V0VG9SZWN0KHgwLCB5MCwgeDEsIHkxKTsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpjbGlwVG9SZWN0KFNwbGFzaENvb3JkIHgwLCBTcGxhc2hDb29yZCB5MCwKCQkJICAgICAgIFNwbGFzaENvb3JkIHgxLCBTcGxhc2hDb29yZCB5MSkgewogIHJldHVybiBzdGF0ZS0+Y2xpcC0+Y2xpcFRvUmVjdCh4MCwgeTAsIHgxLCB5MSk7Cn0KClNwbGFzaEVycm9yIFNwbGFzaDo6Y2xpcFRvUGF0aChTcGxhc2hQYXRoICpwYXRoLCBHQm9vbCBlbykgewogIHJldHVybiBzdGF0ZS0+Y2xpcC0+Y2xpcFRvUGF0aChwYXRoLCBzdGF0ZS0+bWF0cml4LCBzdGF0ZS0+ZmxhdG5lc3MsIGVvKTsKfQoKdm9pZCBTcGxhc2g6OnNldFNvZnRNYXNrKFNwbGFzaEJpdG1hcCAqc29mdE1hc2spIHsKICBzdGF0ZS0+c2V0U29mdE1hc2soc29mdE1hc2spOwp9Cgp2b2lkIFNwbGFzaDo6c2V0SW5Ob25Jc29sYXRlZEdyb3VwKFNwbGFzaEJpdG1hcCAqYWxwaGEwQml0bWFwQSwKCQkJCSAgIGludCBhbHBoYTBYQSwgaW50IGFscGhhMFlBKSB7CiAgYWxwaGEwQml0bWFwID0gYWxwaGEwQml0bWFwQTsKICBhbHBoYTBYID0gYWxwaGEwWEE7CiAgYWxwaGEwWSA9IGFscGhhMFlBOwogIHN0YXRlLT5pbk5vbklzb2xhdGVkR3JvdXAgPSBnVHJ1ZTsKfQoKdm9pZCBTcGxhc2g6OnNldFRyYW5zZmVyKEd1Y2hhciAqcmVkLCBHdWNoYXIgKmdyZWVuLCBHdWNoYXIgKmJsdWUsCgkJCSBHdWNoYXIgKmdyYXkpIHsKICBzdGF0ZS0+c2V0VHJhbnNmZXIocmVkLCBncmVlbiwgYmx1ZSwgZ3JheSk7Cn0KCnZvaWQgU3BsYXNoOjpzZXRPdmVycHJpbnRNYXNrKEd1aW50IG92ZXJwcmludE1hc2ssIEdCb29sIGFkZGl0aXZlKSB7CiAgc3RhdGUtPm92ZXJwcmludE1hc2sgPSBvdmVycHJpbnRNYXNrOwogIHN0YXRlLT5vdmVycHJpbnRBZGRpdGl2ZSA9IGFkZGl0aXZlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBzdGF0ZSBzYXZlL3Jlc3RvcmUKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3BsYXNoOjpzYXZlU3RhdGUoKSB7CiAgU3BsYXNoU3RhdGUgKm5ld1N0YXRlOwoKICBuZXdTdGF0ZSA9IHN0YXRlLT5jb3B5KCk7CiAgbmV3U3RhdGUtPm5leHQgPSBzdGF0ZTsKICBzdGF0ZSA9IG5ld1N0YXRlOwp9CgpTcGxhc2hFcnJvciBTcGxhc2g6OnJlc3RvcmVTdGF0ZSgpIHsKICBTcGxhc2hTdGF0ZSAqb2xkU3RhdGU7CgogIGlmICghc3RhdGUtPm5leHQpIHsKICAgIHJldHVybiBzcGxhc2hFcnJOb1NhdmU7CiAgfQogIG9sZFN0YXRlID0gc3RhdGU7CiAgc3RhdGUgPSBzdGF0ZS0+bmV4dDsKICBkZWxldGUgb2xkU3RhdGU7CiAgcmV0dXJuIHNwbGFzaE9rOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBkcmF3aW5nIG9wZXJhdGlvbnMKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU3BsYXNoOjpjbGVhcihTcGxhc2hDb2xvclB0ciBjb2xvciwgR3VjaGFyIGFscGhhKSB7CiAgU3BsYXNoQ29sb3JQdHIgcm93LCBwOwogIEd1Y2hhciBtb25vOwogIGludCB4LCB5OwoKICBzd2l0Y2ggKGJpdG1hcC0+bW9kZSkgewogIGNhc2Ugc3BsYXNoTW9kZU1vbm8xOgogICAgbW9ubyA9IChjb2xvclswXSAmIDB4ODApID8gMHhmZiA6IDB4MDA7CiAgICBpZiAoYml0bWFwLT5yb3dTaXplIDwgMCkgewogICAgICBtZW1zZXQoYml0bWFwLT5kYXRhICsgYml0bWFwLT5yb3dTaXplICogKGJpdG1hcC0+aGVpZ2h0IC0gMSksCgkgICAgIG1vbm8sIC1iaXRtYXAtPnJvd1NpemUgKiBiaXRtYXAtPmhlaWdodCk7CiAgICB9IGVsc2UgewogICAgICBtZW1zZXQoYml0bWFwLT5kYXRhLCBtb25vLCBiaXRtYXAtPnJvd1NpemUgKiBiaXRtYXAtPmhlaWdodCk7CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIGlmIChiaXRtYXAtPnJvd1NpemUgPCAwKSB7CiAgICAgIG1lbXNldChiaXRtYXAtPmRhdGEgKyBiaXRtYXAtPnJvd1NpemUgKiAoYml0bWFwLT5oZWlnaHQgLSAxKSwKCSAgICAgY29sb3JbMF0sIC1iaXRtYXAtPnJvd1NpemUgKiBiaXRtYXAtPmhlaWdodCk7CiAgICB9IGVsc2UgewogICAgICBtZW1zZXQoYml0bWFwLT5kYXRhLCBjb2xvclswXSwgYml0bWFwLT5yb3dTaXplICogYml0bWFwLT5oZWlnaHQpOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgIGlmIChjb2xvclswXSA9PSBjb2xvclsxXSAmJiBjb2xvclsxXSA9PSBjb2xvclsyXSkgewogICAgICBpZiAoYml0bWFwLT5yb3dTaXplIDwgMCkgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSArIGJpdG1hcC0+cm93U2l6ZSAqIChiaXRtYXAtPmhlaWdodCAtIDEpLAoJICAgICAgIGNvbG9yWzBdLCAtYml0bWFwLT5yb3dTaXplICogYml0bWFwLT5oZWlnaHQpOwogICAgICB9IGVsc2UgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSwgY29sb3JbMF0sIGJpdG1hcC0+cm93U2l6ZSAqIGJpdG1hcC0+aGVpZ2h0KTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcm93ID0gYml0bWFwLT5kYXRhOwogICAgICBmb3IgKHkgPSAwOyB5IDwgYml0bWFwLT5oZWlnaHQ7ICsreSkgewoJcCA9IHJvdzsKCWZvciAoeCA9IDA7IHggPCBiaXRtYXAtPndpZHRoOyArK3gpIHsKCSAgKnArKyA9IGNvbG9yWzJdOwoJICAqcCsrID0gY29sb3JbMV07CgkgICpwKysgPSBjb2xvclswXTsKCX0KCXJvdyArPSBiaXRtYXAtPnJvd1NpemU7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgaWYgKGNvbG9yWzBdID09IGNvbG9yWzFdICYmIGNvbG9yWzFdID09IGNvbG9yWzJdKSB7CiAgICAgIGlmIChiaXRtYXAtPnJvd1NpemUgPCAwKSB7CgltZW1zZXQoYml0bWFwLT5kYXRhICsgYml0bWFwLT5yb3dTaXplICogKGJpdG1hcC0+aGVpZ2h0IC0gMSksCgkgICAgICAgY29sb3JbMF0sIC1iaXRtYXAtPnJvd1NpemUgKiBiaXRtYXAtPmhlaWdodCk7CiAgICAgIH0gZWxzZSB7CgltZW1zZXQoYml0bWFwLT5kYXRhLCBjb2xvclswXSwgYml0bWFwLT5yb3dTaXplICogYml0bWFwLT5oZWlnaHQpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICByb3cgPSBiaXRtYXAtPmRhdGE7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBiaXRtYXAtPmhlaWdodDsgKyt5KSB7CglwID0gcm93OwoJZm9yICh4ID0gMDsgeCA8IGJpdG1hcC0+d2lkdGg7ICsreCkgewoJICAqcCsrID0gY29sb3JbMF07CgkgICpwKysgPSBjb2xvclsxXTsKCSAgKnArKyA9IGNvbG9yWzJdOwoJICAqcCsrID0gMjU1OwoJfQoJcm93ICs9IGJpdG1hcC0+cm93U2l6ZTsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIGlmIChjb2xvclswXSA9PSBjb2xvclsxXSAmJiBjb2xvclsxXSA9PSBjb2xvclsyXSkgewogICAgICBpZiAoYml0bWFwLT5yb3dTaXplIDwgMCkgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSArIGJpdG1hcC0+cm93U2l6ZSAqIChiaXRtYXAtPmhlaWdodCAtIDEpLAoJICAgICAgIGNvbG9yWzBdLCAtYml0bWFwLT5yb3dTaXplICogYml0bWFwLT5oZWlnaHQpOwogICAgICB9IGVsc2UgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSwgY29sb3JbMF0sIGJpdG1hcC0+cm93U2l6ZSAqIGJpdG1hcC0+aGVpZ2h0KTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcm93ID0gYml0bWFwLT5kYXRhOwogICAgICBmb3IgKHkgPSAwOyB5IDwgYml0bWFwLT5oZWlnaHQ7ICsreSkgewoJcCA9IHJvdzsKCWZvciAoeCA9IDA7IHggPCBiaXRtYXAtPndpZHRoOyArK3gpIHsKCSAgKnArKyA9IGNvbG9yWzBdOwoJICAqcCsrID0gY29sb3JbMV07CgkgICpwKysgPSBjb2xvclsyXTsKCX0KCXJvdyArPSBiaXRtYXAtPnJvd1NpemU7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgIGlmIChjb2xvclswXSA9PSBjb2xvclsxXSAmJiBjb2xvclsxXSA9PSBjb2xvclsyXSAmJiBjb2xvclsyXSA9PSBjb2xvclszXSkgewogICAgICBpZiAoYml0bWFwLT5yb3dTaXplIDwgMCkgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSArIGJpdG1hcC0+cm93U2l6ZSAqIChiaXRtYXAtPmhlaWdodCAtIDEpLAoJICAgICAgIGNvbG9yWzBdLCAtYml0bWFwLT5yb3dTaXplICogYml0bWFwLT5oZWlnaHQpOwogICAgICB9IGVsc2UgewoJbWVtc2V0KGJpdG1hcC0+ZGF0YSwgY29sb3JbMF0sIGJpdG1hcC0+cm93U2l6ZSAqIGJpdG1hcC0+aGVpZ2h0KTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcm93ID0gYml0bWFwLT5kYXRhOwogICAgICBmb3IgKHkgPSAwOyB5IDwgYml0bWFwLT5oZWlnaHQ7ICsreSkgewoJcCA9IHJvdzsKCWZvciAoeCA9IDA7IHggPCBiaXRtYXAtPndpZHRoOyArK3gpIHsKCSAgKnArKyA9IGNvbG9yWzBdOwoJICAqcCsrID0gY29sb3JbMV07CgkgICpwKysgPSBjb2xvclsyXTsKCSAgKnArKyA9IGNvbG9yWzNdOwoJfQoJcm93ICs9IGJpdG1hcC0+cm93U2l6ZTsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICByb3cgPSBiaXRtYXAtPmRhdGE7CiAgICBmb3IgKHkgPSAwOyB5IDwgYml0bWFwLT5oZWlnaHQ7ICsreSkgewogICAgICBwID0gcm93OwogICAgICBmb3IgKHggPSAwOyB4IDwgYml0bWFwLT53aWR0aDsgKyt4KSB7CiAgICAgICAgZm9yIChpbnQgY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgICAgICAqcCsrID0gY29sb3JbY3BdOwogICAgICB9CiAgICAgIHJvdyArPSBiaXRtYXAtPnJvd1NpemU7CiAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgfQoKICBpZiAoYml0bWFwLT5hbHBoYSkgewogICAgbWVtc2V0KGJpdG1hcC0+YWxwaGEsIGFscGhhLCBiaXRtYXAtPndpZHRoICogYml0bWFwLT5oZWlnaHQpOwogIH0KCiAgdXBkYXRlTW9kWCgwKTsKICB1cGRhdGVNb2RZKDApOwogIHVwZGF0ZU1vZFgoYml0bWFwLT53aWR0aCAtIDEpOwogIHVwZGF0ZU1vZFkoYml0bWFwLT5oZWlnaHQgLSAxKTsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpzdHJva2UoU3BsYXNoUGF0aCAqcGF0aCkgewogIFNwbGFzaFBhdGggKnBhdGgyLCAqZFBhdGg7CiAgU3BsYXNoQ29vcmQgZDEsIGQyLCB0MSwgdDIsIHc7CgogIGlmIChkZWJ1Z01vZGUpIHsKICAgIHByaW50Zigic3Ryb2tlIFtkYXNoOiVkXSBbd2lkdGg6JS4yZl06XG4iLAoJICAgc3RhdGUtPmxpbmVEYXNoTGVuZ3RoLCAoZG91YmxlKXN0YXRlLT5saW5lV2lkdGgpOwogICAgZHVtcFBhdGgocGF0aCk7CiAgfQogIG9wQ2xpcFJlcyA9IHNwbGFzaENsaXBBbGxPdXRzaWRlOwogIGlmIChwYXRoLT5sZW5ndGggPT0gMCkgewogICAgcmV0dXJuIHNwbGFzaEVyckVtcHR5UGF0aDsKICB9CiAgcGF0aDIgPSBmbGF0dGVuUGF0aChwYXRoLCBzdGF0ZS0+bWF0cml4LCBzdGF0ZS0+ZmxhdG5lc3MpOwogIGlmIChzdGF0ZS0+bGluZURhc2hMZW5ndGggPiAwKSB7CiAgICBkUGF0aCA9IG1ha2VEYXNoZWRQYXRoKHBhdGgyKTsKICAgIGRlbGV0ZSBwYXRoMjsKICAgIHBhdGgyID0gZFBhdGg7CiAgICBpZiAocGF0aDItPmxlbmd0aCA9PSAwKSB7CiAgICAgIGRlbGV0ZSBwYXRoMjsKICAgICAgcmV0dXJuIHNwbGFzaEVyckVtcHR5UGF0aDsKICAgIH0KICB9CgogIC8vIHRyYW5zZm9ybSBhIHVuaXQgc3F1YXJlLCBhbmQgdGFrZSB0aGUgaGFsZiB0aGUgbWF4IG9mIHRoZSB0d28KICAvLyBkaWFnb25hbHM7IHRoZSBwcm9kdWN0IG9mIHRoaXMgbnVtYmVyIGFuZCB0aGUgbGluZSB3aWR0aCBpcyB0aGUKICAvLyAoYXBwcm94aW1hdGUpIHRyYW5zZm9ybWVkIGxpbmUgd2lkdGgKICB0MSA9IHN0YXRlLT5tYXRyaXhbMF0gKyBzdGF0ZS0+bWF0cml4WzJdOwogIHQyID0gc3RhdGUtPm1hdHJpeFsxXSArIHN0YXRlLT5tYXRyaXhbM107CiAgZDEgPSB0MSAqIHQxICsgdDIgKiB0MjsKICB0MSA9IHN0YXRlLT5tYXRyaXhbMF0gLSBzdGF0ZS0+bWF0cml4WzJdOwogIHQyID0gc3RhdGUtPm1hdHJpeFsxXSAtIHN0YXRlLT5tYXRyaXhbM107CiAgZDIgPSB0MSAqIHQxICsgdDIgKiB0MjsKICBpZiAoZDIgPiBkMSkgewogICAgZDEgPSBkMjsKICB9CiAgZDEgKj0gMC41OwogIGlmIChkMSA+IDAgJiYKICAgICAgZDEgKiBzdGF0ZS0+bGluZVdpZHRoICogc3RhdGUtPmxpbmVXaWR0aCA8IG1pbkxpbmVXaWR0aCAqIG1pbkxpbmVXaWR0aCkgewogICAgdyA9IG1pbkxpbmVXaWR0aCAvIHNwbGFzaFNxcnQoZDEpOwogICAgc3Ryb2tlV2lkZShwYXRoMiwgdyk7CiAgfSBlbHNlIGlmIChiaXRtYXAtPm1vZGUgPT0gc3BsYXNoTW9kZU1vbm8xKSB7CiAgICAvLyB0aGlzIGdldHMgY2xvc2UgdG8gQWRvYmUncyBiZWhhdmlvciBpbiBtb25vIG1vZGUKICAgIGlmIChkMSA8PSAyKSB7CiAgICAgIHN0cm9rZU5hcnJvdyhwYXRoMik7CiAgICB9IGVsc2UgewogICAgICBzdHJva2VXaWRlKHBhdGgyLCBzdGF0ZS0+bGluZVdpZHRoKTsKICAgIH0KICB9IGVsc2UgewogICAgaWYgKHN0YXRlLT5saW5lV2lkdGggPT0gMCkgewogICAgICBzdHJva2VOYXJyb3cocGF0aDIpOwogICAgfSBlbHNlIHsKICAgICAgc3Ryb2tlV2lkZShwYXRoMiwgc3RhdGUtPmxpbmVXaWR0aCk7CiAgICB9CiAgfQoKICBkZWxldGUgcGF0aDI7CiAgcmV0dXJuIHNwbGFzaE9rOwp9Cgp2b2lkIFNwbGFzaDo6c3Ryb2tlTmFycm93KFNwbGFzaFBhdGggKnBhdGgpIHsKICBTcGxhc2hQaXBlIHBpcGU7CiAgU3BsYXNoWFBhdGggKnhQYXRoOwogIFNwbGFzaFhQYXRoU2VnICpzZWc7CiAgaW50IHgwLCB4MSwgeTAsIHkxLCB4YSwgeGIsIHk7CiAgU3BsYXNoQ29vcmQgZHhkeTsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXM7CiAgaW50IG5DbGlwUmVzWzNdOwogIGludCBpOwoKICBuQ2xpcFJlc1swXSA9IG5DbGlwUmVzWzFdID0gbkNsaXBSZXNbMl0gPSAwOwoKICB4UGF0aCA9IG5ldyBTcGxhc2hYUGF0aChwYXRoLCBzdGF0ZS0+bWF0cml4LCBzdGF0ZS0+ZmxhdG5lc3MsIGdGYWxzZSk7CgogIHBpcGVJbml0KCZwaXBlLCAwLCAwLCBzdGF0ZS0+c3Ryb2tlUGF0dGVybiwgTlVMTCwKCSAgIChHdWNoYXIpc3BsYXNoUm91bmQoc3RhdGUtPnN0cm9rZUFscGhhICogMjU1KSwKCSAgIGdGYWxzZSwgZ0ZhbHNlKTsKCiAgZm9yIChpID0gMCwgc2VnID0geFBhdGgtPnNlZ3M7IGkgPCB4UGF0aC0+bGVuZ3RoOyArK2ksICsrc2VnKSB7CiAgICBpZiAoc2VnLT55MCA8PSBzZWctPnkxKSB7CiAgICAgIHkwID0gc3BsYXNoRmxvb3Ioc2VnLT55MCk7CiAgICAgIHkxID0gc3BsYXNoRmxvb3Ioc2VnLT55MSk7CiAgICAgIHgwID0gc3BsYXNoRmxvb3Ioc2VnLT54MCk7CiAgICAgIHgxID0gc3BsYXNoRmxvb3Ioc2VnLT54MSk7CiAgICB9IGVsc2UgewogICAgICB5MCA9IHNwbGFzaEZsb29yKHNlZy0+eTEpOwogICAgICB5MSA9IHNwbGFzaEZsb29yKHNlZy0+eTApOwogICAgICB4MCA9IHNwbGFzaEZsb29yKHNlZy0+eDEpOwogICAgICB4MSA9IHNwbGFzaEZsb29yKHNlZy0+eDApOwogICAgfQogICAgaWYgKChjbGlwUmVzID0gc3RhdGUtPmNsaXAtPnRlc3RSZWN0KHgwIDw9IHgxID8geDAgOiB4MSwgeTAsCgkJCQkJIHgwIDw9IHgxID8geDEgOiB4MCwgeTEpKQoJIT0gc3BsYXNoQ2xpcEFsbE91dHNpZGUpIHsKICAgICAgaWYgKHkwID09IHkxKSB7CglpZiAoeDAgPD0geDEpIHsKCSAgZHJhd1NwYW4oJnBpcGUsIHgwLCB4MSwgeTAsIGNsaXBSZXMgPT0gc3BsYXNoQ2xpcEFsbEluc2lkZSk7Cgl9IGVsc2UgewoJICBkcmF3U3BhbigmcGlwZSwgeDEsIHgwLCB5MCwgY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKTsKCX0KICAgICAgfSBlbHNlIHsKCWR4ZHkgPSBzZWctPmR4ZHk7CglpZiAoeTAgPCBzdGF0ZS0+Y2xpcC0+Z2V0WU1pbkkoKSkgewoJICB5MCA9IHN0YXRlLT5jbGlwLT5nZXRZTWluSSgpOwoJICB4MCA9IHNwbGFzaEZsb29yKHNlZy0+eDAgKyAoKFNwbGFzaENvb3JkKXkwIC0gc2VnLT55MCkgKiBkeGR5KTsKCX0KCWlmICh5MSA+IHN0YXRlLT5jbGlwLT5nZXRZTWF4SSgpKSB7CgkgIHkxID0gc3RhdGUtPmNsaXAtPmdldFlNYXhJKCk7CgkgIHgxID0gc3BsYXNoRmxvb3Ioc2VnLT54MCArICgoU3BsYXNoQ29vcmQpeTEgLSBzZWctPnkwKSAqIGR4ZHkpOwoJfQoJaWYgKHgwIDw9IHgxKSB7CgkgIHhhID0geDA7CgkgIGZvciAoeSA9IHkwOyB5IDw9IHkxOyArK3kpIHsKCSAgICBpZiAoeSA8IHkxKSB7CgkgICAgICB4YiA9IHNwbGFzaEZsb29yKHNlZy0+eDAgKwoJCQkgICAgICAgKChTcGxhc2hDb29yZCl5ICsgMSAtIHNlZy0+eTApICogZHhkeSk7CgkgICAgfSBlbHNlIHsKCSAgICAgIHhiID0geDEgKyAxOwoJICAgIH0KCSAgICBpZiAoeGEgPT0geGIpIHsKCSAgICAgIGRyYXdQaXhlbCgmcGlwZSwgeGEsIHksIGNsaXBSZXMgPT0gc3BsYXNoQ2xpcEFsbEluc2lkZSk7CgkgICAgfSBlbHNlIHsKCSAgICAgIGRyYXdTcGFuKCZwaXBlLCB4YSwgeGIgLSAxLCB5LCBjbGlwUmVzID09IHNwbGFzaENsaXBBbGxJbnNpZGUpOwoJICAgIH0KCSAgICB4YSA9IHhiOwoJICB9Cgl9IGVsc2UgewoJICB4YSA9IHgwOwoJICBmb3IgKHkgPSB5MDsgeSA8PSB5MTsgKyt5KSB7CgkgICAgaWYgKHkgPCB5MSkgewoJICAgICAgeGIgPSBzcGxhc2hGbG9vcihzZWctPngwICsKCQkJICAgICAgICgoU3BsYXNoQ29vcmQpeSArIDEgLSBzZWctPnkwKSAqIGR4ZHkpOwoJICAgIH0gZWxzZSB7CgkgICAgICB4YiA9IHgxIC0gMTsKCSAgICB9CgkgICAgaWYgKHhhID09IHhiKSB7CgkgICAgICBkcmF3UGl4ZWwoJnBpcGUsIHhhLCB5LCBjbGlwUmVzID09IHNwbGFzaENsaXBBbGxJbnNpZGUpOwoJICAgIH0gZWxzZSB7CgkgICAgICBkcmF3U3BhbigmcGlwZSwgeGIgKyAxLCB4YSwgeSwgY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKTsKCSAgICB9CgkgICAgeGEgPSB4YjsKCSAgfQoJfQogICAgICB9CiAgICB9CiAgICArK25DbGlwUmVzW2NsaXBSZXNdOwogIH0KICBpZiAobkNsaXBSZXNbc3BsYXNoQ2xpcFBhcnRpYWxdIHx8CiAgICAgIChuQ2xpcFJlc1tzcGxhc2hDbGlwQWxsSW5zaWRlXSAmJiBuQ2xpcFJlc1tzcGxhc2hDbGlwQWxsT3V0c2lkZV0pKSB7CiAgICBvcENsaXBSZXMgPSBzcGxhc2hDbGlwUGFydGlhbDsKICB9IGVsc2UgaWYgKG5DbGlwUmVzW3NwbGFzaENsaXBBbGxJbnNpZGVdKSB7CiAgICBvcENsaXBSZXMgPSBzcGxhc2hDbGlwQWxsSW5zaWRlOwogIH0gZWxzZSB7CiAgICBvcENsaXBSZXMgPSBzcGxhc2hDbGlwQWxsT3V0c2lkZTsKICB9CgogIGRlbGV0ZSB4UGF0aDsKfQoKdm9pZCBTcGxhc2g6OnN0cm9rZVdpZGUoU3BsYXNoUGF0aCAqcGF0aCwgU3BsYXNoQ29vcmQgdykgewogIFNwbGFzaFBhdGggKnBhdGgyOwoKICBwYXRoMiA9IG1ha2VTdHJva2VQYXRoKHBhdGgsIHcsIGdGYWxzZSk7CiAgZmlsbFdpdGhQYXR0ZXJuKHBhdGgyLCBnRmFsc2UsIHN0YXRlLT5zdHJva2VQYXR0ZXJuLCBzdGF0ZS0+c3Ryb2tlQWxwaGEpOwogIGRlbGV0ZSBwYXRoMjsKfQoKU3BsYXNoUGF0aCAqU3BsYXNoOjpmbGF0dGVuUGF0aChTcGxhc2hQYXRoICpwYXRoLCBTcGxhc2hDb29yZCAqbWF0cml4LAoJCQkJU3BsYXNoQ29vcmQgZmxhdG5lc3MpIHsKICBTcGxhc2hQYXRoICpmUGF0aDsKICBTcGxhc2hDb29yZCBmbGF0bmVzczI7CiAgR3VjaGFyIGZsYWc7CiAgaW50IGk7CgogIGZQYXRoID0gbmV3IFNwbGFzaFBhdGgoKTsKI2lmIFVTRV9GSVhFRFBPSU5UCiAgZmxhdG5lc3MyID0gZmxhdG5lc3M7CiNlbHNlCiAgZmxhdG5lc3MyID0gZmxhdG5lc3MgKiBmbGF0bmVzczsKI2VuZGlmCiAgaSA9IDA7CiAgd2hpbGUgKGkgPCBwYXRoLT5sZW5ndGgpIHsKICAgIGZsYWcgPSBwYXRoLT5mbGFnc1tpXTsKICAgIGlmIChmbGFnICYgc3BsYXNoUGF0aEZpcnN0KSB7CiAgICAgIGZQYXRoLT5tb3ZlVG8ocGF0aC0+cHRzW2ldLngsIHBhdGgtPnB0c1tpXS55KTsKICAgICAgKytpOwogICAgfSBlbHNlIHsKICAgICAgaWYgKGZsYWcgJiBzcGxhc2hQYXRoQ3VydmUpIHsKCWZsYXR0ZW5DdXJ2ZShwYXRoLT5wdHNbaS0xXS54LCBwYXRoLT5wdHNbaS0xXS55LAoJCSAgICAgcGF0aC0+cHRzW2kgIF0ueCwgcGF0aC0+cHRzW2kgIF0ueSwKCQkgICAgIHBhdGgtPnB0c1tpKzFdLngsIHBhdGgtPnB0c1tpKzFdLnksCgkJICAgICBwYXRoLT5wdHNbaSsyXS54LCBwYXRoLT5wdHNbaSsyXS55LAoJCSAgICAgbWF0cml4LCBmbGF0bmVzczIsIGZQYXRoKTsKCWkgKz0gMzsKICAgICAgfSBlbHNlIHsKCWZQYXRoLT5saW5lVG8ocGF0aC0+cHRzW2ldLngsIHBhdGgtPnB0c1tpXS55KTsKCSsraTsKICAgICAgfQogICAgICBpZiAocGF0aC0+ZmxhZ3NbaS0xXSAmIHNwbGFzaFBhdGhDbG9zZWQpIHsKCWZQYXRoLT5jbG9zZSgpOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBmUGF0aDsKfQoKdm9pZCBTcGxhc2g6OmZsYXR0ZW5DdXJ2ZShTcGxhc2hDb29yZCB4MCwgU3BsYXNoQ29vcmQgeTAsCgkJCSAgU3BsYXNoQ29vcmQgeDEsIFNwbGFzaENvb3JkIHkxLAoJCQkgIFNwbGFzaENvb3JkIHgyLCBTcGxhc2hDb29yZCB5MiwKCQkJICBTcGxhc2hDb29yZCB4MywgU3BsYXNoQ29vcmQgeTMsCgkJCSAgU3BsYXNoQ29vcmQgKm1hdHJpeCwgU3BsYXNoQ29vcmQgZmxhdG5lc3MyLAoJCQkgIFNwbGFzaFBhdGggKmZQYXRoKSB7CiAgU3BsYXNoQ29vcmQgY3hbc3BsYXNoTWF4Q3VydmVTcGxpdHMgKyAxXVszXTsKICBTcGxhc2hDb29yZCBjeVtzcGxhc2hNYXhDdXJ2ZVNwbGl0cyArIDFdWzNdOwogIGludCBjTmV4dFtzcGxhc2hNYXhDdXJ2ZVNwbGl0cyArIDFdOwogIFNwbGFzaENvb3JkIHhsMCwgeGwxLCB4bDIsIHhyMCwgeHIxLCB4cjIsIHhyMywgeHgxLCB4eDIsIHhoOwogIFNwbGFzaENvb3JkIHlsMCwgeWwxLCB5bDIsIHlyMCwgeXIxLCB5cjIsIHlyMywgeXkxLCB5eTIsIHloOwogIFNwbGFzaENvb3JkIGR4LCBkeSwgbXgsIG15LCB0eCwgdHksIGQxLCBkMjsKICBpbnQgcDEsIHAyLCBwMzsKCiAgLy8gaW5pdGlhbCBzZWdtZW50CiAgcDEgPSAwOwogIHAyID0gc3BsYXNoTWF4Q3VydmVTcGxpdHM7CiAgY3hbcDFdWzBdID0geDA7ICBjeVtwMV1bMF0gPSB5MDsKICBjeFtwMV1bMV0gPSB4MTsgIGN5W3AxXVsxXSA9IHkxOwogIGN4W3AxXVsyXSA9IHgyOyAgY3lbcDFdWzJdID0geTI7CiAgY3hbcDJdWzBdID0geDM7ICBjeVtwMl1bMF0gPSB5MzsKICBjTmV4dFtwMV0gPSBwMjsKCiAgd2hpbGUgKHAxIDwgc3BsYXNoTWF4Q3VydmVTcGxpdHMpIHsKCiAgICAvLyBnZXQgdGhlIG5leHQgc2VnbWVudAogICAgeGwwID0gY3hbcDFdWzBdOyAgeWwwID0gY3lbcDFdWzBdOwogICAgeHgxID0gY3hbcDFdWzFdOyAgeXkxID0gY3lbcDFdWzFdOwogICAgeHgyID0gY3hbcDFdWzJdOyAgeXkyID0gY3lbcDFdWzJdOwogICAgcDIgPSBjTmV4dFtwMV07CiAgICB4cjMgPSBjeFtwMl1bMF07ICB5cjMgPSBjeVtwMl1bMF07CgogICAgLy8gY29tcHV0ZSB0aGUgZGlzdGFuY2VzIChpbiBkZXZpY2Ugc3BhY2UpIGZyb20gdGhlIGNvbnRyb2wgcG9pbnRzCiAgICAvLyB0byB0aGUgbWlkcG9pbnQgb2YgdGhlIHN0cmFpZ2h0IGxpbmUgKHRoaXMgaXMgYSBiaXQgb2YgYSBoYWNrLAogICAgLy8gYnV0IGl0J3MgbXVjaCBmYXN0ZXIgdGhhbiBjb21wdXRpbmcgdGhlIGFjdHVhbCBkaXN0YW5jZXMgdG8gdGhlCiAgICAvLyBsaW5lKQogICAgdHJhbnNmb3JtKG1hdHJpeCwgKHhsMCArIHhyMykgKiAwLjUsICh5bDAgKyB5cjMpICogMC41LCAmbXgsICZteSk7CiAgICB0cmFuc2Zvcm0obWF0cml4LCB4eDEsIHl5MSwgJnR4LCAmdHkpOwojaWYgVVNFX0ZJWEVEUE9JTlQKICAgIGQxID0gc3BsYXNoRGlzdCh0eCwgdHksIG14LCBteSk7CiNlbHNlCiAgICBkeCA9IHR4IC0gbXg7CiAgICBkeSA9IHR5IC0gbXk7CiAgICBkMSA9IGR4KmR4ICsgZHkqZHk7CiNlbmRpZgogICAgdHJhbnNmb3JtKG1hdHJpeCwgeHgyLCB5eTIsICZ0eCwgJnR5KTsKI2lmIFVTRV9GSVhFRFBPSU5UCiAgICBkMiA9IHNwbGFzaERpc3QodHgsIHR5LCBteCwgbXkpOwojZWxzZQogICAgZHggPSB0eCAtIG14OwogICAgZHkgPSB0eSAtIG15OwogICAgZDIgPSBkeCpkeCArIGR5KmR5OwojZW5kaWYKCiAgICAvLyBpZiB0aGUgY3VydmUgaXMgZmxhdCBlbm91Z2gsIG9yIG5vIG1vcmUgc3ViZGl2aXNpb25zIGFyZQogICAgLy8gYWxsb3dlZCwgYWRkIHRoZSBzdHJhaWdodCBsaW5lIHNlZ21lbnQKICAgIGlmIChwMiAtIHAxID09IDEgfHwgKGQxIDw9IGZsYXRuZXNzMiAmJiBkMiA8PSBmbGF0bmVzczIpKSB7CiAgICAgIGZQYXRoLT5saW5lVG8oeHIzLCB5cjMpOwogICAgICBwMSA9IHAyOwoKICAgIC8vIG90aGVyd2lzZSwgc3ViZGl2aWRlIHRoZSBjdXJ2ZQogICAgfSBlbHNlIHsKICAgICAgeGwxID0gc3BsYXNoQXZnKHhsMCwgeHgxKTsKICAgICAgeWwxID0gc3BsYXNoQXZnKHlsMCwgeXkxKTsKICAgICAgeGggPSBzcGxhc2hBdmcoeHgxLCB4eDIpOwogICAgICB5aCA9IHNwbGFzaEF2Zyh5eTEsIHl5Mik7CiAgICAgIHhsMiA9IHNwbGFzaEF2Zyh4bDEsIHhoKTsKICAgICAgeWwyID0gc3BsYXNoQXZnKHlsMSwgeWgpOwogICAgICB4cjIgPSBzcGxhc2hBdmcoeHgyLCB4cjMpOwogICAgICB5cjIgPSBzcGxhc2hBdmcoeXkyLCB5cjMpOwogICAgICB4cjEgPSBzcGxhc2hBdmcoeGgsIHhyMik7CiAgICAgIHlyMSA9IHNwbGFzaEF2Zyh5aCwgeXIyKTsKICAgICAgeHIwID0gc3BsYXNoQXZnKHhsMiwgeHIxKTsKICAgICAgeXIwID0gc3BsYXNoQXZnKHlsMiwgeXIxKTsKICAgICAgLy8gYWRkIHRoZSBuZXcgc3ViZGl2aXNpb24gcG9pbnRzCiAgICAgIHAzID0gKHAxICsgcDIpIC8gMjsKICAgICAgY3hbcDFdWzFdID0geGwxOyAgY3lbcDFdWzFdID0geWwxOwogICAgICBjeFtwMV1bMl0gPSB4bDI7ICBjeVtwMV1bMl0gPSB5bDI7CiAgICAgIGNOZXh0W3AxXSA9IHAzOwogICAgICBjeFtwM11bMF0gPSB4cjA7ICBjeVtwM11bMF0gPSB5cjA7CiAgICAgIGN4W3AzXVsxXSA9IHhyMTsgIGN5W3AzXVsxXSA9IHlyMTsKICAgICAgY3hbcDNdWzJdID0geHIyOyAgY3lbcDNdWzJdID0geXIyOwogICAgICBjTmV4dFtwM10gPSBwMjsKICAgIH0KICB9Cn0KClNwbGFzaFBhdGggKlNwbGFzaDo6bWFrZURhc2hlZFBhdGgoU3BsYXNoUGF0aCAqcGF0aCkgewogIFNwbGFzaFBhdGggKmRQYXRoOwogIFNwbGFzaENvb3JkIGxpbmVEYXNoVG90YWw7CiAgU3BsYXNoQ29vcmQgbGluZURhc2hTdGFydFBoYXNlLCBsaW5lRGFzaERpc3QsIHNlZ0xlbjsKICBTcGxhc2hDb29yZCB4MCwgeTAsIHgxLCB5MSwgeGEsIHlhOwogIEdCb29sIGxpbmVEYXNoU3RhcnRPbiwgbGluZURhc2hPbiwgbmV3UGF0aDsKICBpbnQgbGluZURhc2hTdGFydElkeCwgbGluZURhc2hJZHg7CiAgaW50IGksIGosIGs7CgogIGxpbmVEYXNoVG90YWwgPSAwOwogIGZvciAoaSA9IDA7IGkgPCBzdGF0ZS0+bGluZURhc2hMZW5ndGg7ICsraSkgewogICAgbGluZURhc2hUb3RhbCArPSBzdGF0ZS0+bGluZURhc2hbaV07CiAgfQogIC8vIEFjcm9iYXQgc2ltcGx5IGRyYXdzIG5vdGhpbmcgaWYgdGhlIGRhc2ggYXJyYXkgaXMgWzBdCiAgaWYgKGxpbmVEYXNoVG90YWwgPT0gMCkgewogICAgcmV0dXJuIG5ldyBTcGxhc2hQYXRoKCk7CiAgfQogIGxpbmVEYXNoU3RhcnRQaGFzZSA9IHN0YXRlLT5saW5lRGFzaFBoYXNlOwogIGkgPSBzcGxhc2hGbG9vcihsaW5lRGFzaFN0YXJ0UGhhc2UgLyBsaW5lRGFzaFRvdGFsKTsKICBsaW5lRGFzaFN0YXJ0UGhhc2UgLT0gKFNwbGFzaENvb3JkKWkgKiBsaW5lRGFzaFRvdGFsOwogIGxpbmVEYXNoU3RhcnRPbiA9IGdUcnVlOwogIGxpbmVEYXNoU3RhcnRJZHggPSAwOwogIGlmIChsaW5lRGFzaFN0YXJ0UGhhc2UgPiAwKSB7CiAgICB3aGlsZSAobGluZURhc2hTdGFydFBoYXNlID49IHN0YXRlLT5saW5lRGFzaFtsaW5lRGFzaFN0YXJ0SWR4XSkgewogICAgICBsaW5lRGFzaFN0YXJ0T24gPSAhbGluZURhc2hTdGFydE9uOwogICAgICBsaW5lRGFzaFN0YXJ0UGhhc2UgLT0gc3RhdGUtPmxpbmVEYXNoW2xpbmVEYXNoU3RhcnRJZHhdOwogICAgICArK2xpbmVEYXNoU3RhcnRJZHg7CiAgICB9CiAgfQoKICBkUGF0aCA9IG5ldyBTcGxhc2hQYXRoKCk7CgogIC8vIHByb2Nlc3MgZWFjaCBzdWJwYXRoCiAgaSA9IDA7CiAgd2hpbGUgKGkgPCBwYXRoLT5sZW5ndGgpIHsKCiAgICAvLyBmaW5kIHRoZSBlbmQgb2YgdGhlIHN1YnBhdGgKICAgIGZvciAoaiA9IGk7CgkgaiA8IHBhdGgtPmxlbmd0aCAtIDEgJiYgIShwYXRoLT5mbGFnc1tqXSAmIHNwbGFzaFBhdGhMYXN0KTsKCSArK2opIDsKCiAgICAvLyBpbml0aWFsaXplIHRoZSBkYXNoIHBhcmFtZXRlcnMKICAgIGxpbmVEYXNoT24gPSBsaW5lRGFzaFN0YXJ0T247CiAgICBsaW5lRGFzaElkeCA9IGxpbmVEYXNoU3RhcnRJZHg7CiAgICBsaW5lRGFzaERpc3QgPSBzdGF0ZS0+bGluZURhc2hbbGluZURhc2hJZHhdIC0gbGluZURhc2hTdGFydFBoYXNlOwoKICAgIC8vIHByb2Nlc3MgZWFjaCBzZWdtZW50IG9mIHRoZSBzdWJwYXRoCiAgICBuZXdQYXRoID0gZ1RydWU7CiAgICBmb3IgKGsgPSBpOyBrIDwgajsgKytrKSB7CgogICAgICAvLyBncmFiIHRoZSBzZWdtZW50CiAgICAgIHgwID0gcGF0aC0+cHRzW2tdLng7CiAgICAgIHkwID0gcGF0aC0+cHRzW2tdLnk7CiAgICAgIHgxID0gcGF0aC0+cHRzW2srMV0ueDsKICAgICAgeTEgPSBwYXRoLT5wdHNbaysxXS55OwogICAgICBzZWdMZW4gPSBzcGxhc2hEaXN0KHgwLCB5MCwgeDEsIHkxKTsKCiAgICAgIC8vIHByb2Nlc3MgdGhlIHNlZ21lbnQKICAgICAgd2hpbGUgKHNlZ0xlbiA+IDApIHsKCglpZiAobGluZURhc2hEaXN0ID49IHNlZ0xlbikgewoJICBpZiAobGluZURhc2hPbikgewoJICAgIGlmIChuZXdQYXRoKSB7CgkgICAgICBkUGF0aC0+bW92ZVRvKHgwLCB5MCk7CgkgICAgICBuZXdQYXRoID0gZ0ZhbHNlOwoJICAgIH0KCSAgICBkUGF0aC0+bGluZVRvKHgxLCB5MSk7CgkgIH0KCSAgbGluZURhc2hEaXN0IC09IHNlZ0xlbjsKCSAgc2VnTGVuID0gMDsKCgl9IGVsc2UgewoJICB4YSA9IHgwICsgKGxpbmVEYXNoRGlzdCAvIHNlZ0xlbikgKiAoeDEgLSB4MCk7CgkgIHlhID0geTAgKyAobGluZURhc2hEaXN0IC8gc2VnTGVuKSAqICh5MSAtIHkwKTsKCSAgaWYgKGxpbmVEYXNoT24pIHsKCSAgICBpZiAobmV3UGF0aCkgewoJICAgICAgZFBhdGgtPm1vdmVUbyh4MCwgeTApOwoJICAgICAgbmV3UGF0aCA9IGdGYWxzZTsKCSAgICB9CgkgICAgZFBhdGgtPmxpbmVUbyh4YSwgeWEpOwoJICB9CgkgIHgwID0geGE7CgkgIHkwID0geWE7CgkgIHNlZ0xlbiAtPSBsaW5lRGFzaERpc3Q7CgkgIGxpbmVEYXNoRGlzdCA9IDA7Cgl9CgoJLy8gZ2V0IHRoZSBuZXh0IGVudHJ5IGluIHRoZSBkYXNoIGFycmF5CglpZiAobGluZURhc2hEaXN0IDw9IDApIHsKCSAgbGluZURhc2hPbiA9ICFsaW5lRGFzaE9uOwoJICBpZiAoKytsaW5lRGFzaElkeCA9PSBzdGF0ZS0+bGluZURhc2hMZW5ndGgpIHsKCSAgICBsaW5lRGFzaElkeCA9IDA7CgkgIH0KCSAgbGluZURhc2hEaXN0ID0gc3RhdGUtPmxpbmVEYXNoW2xpbmVEYXNoSWR4XTsKCSAgbmV3UGF0aCA9IGdUcnVlOwoJfQogICAgICB9CiAgICB9CiAgICBpID0gaiArIDE7CiAgfQogIAogIGlmIChkUGF0aC0+bGVuZ3RoID09IDApIHsKICAgIEdCb29sIGFsbFNhbWUgPSBnVHJ1ZTsKICAgIGZvciAoaW50IGkgPSAwOyBhbGxTYW1lICYmIGkgPCBwYXRoLT5sZW5ndGggLSAxOyArK2kpIHsKICAgICAgYWxsU2FtZSA9IHBhdGgtPnB0c1tpXS54ID09IHBhdGgtPnB0c1tpICsgMV0ueCAmJiBwYXRoLT5wdHNbaV0ueSA9PSBwYXRoLT5wdHNbaSArIDFdLnk7CiAgICB9CiAgICBpZiAoYWxsU2FtZSkgewogICAgICB4MCA9IHBhdGgtPnB0c1swXS54OwogICAgICB5MCA9IHBhdGgtPnB0c1swXS55OwogICAgICBkUGF0aC0+bW92ZVRvKHgwLCB5MCk7CiAgICAgIGRQYXRoLT5saW5lVG8oeDAsIHkwKTsKICAgIH0KICB9CgogIHJldHVybiBkUGF0aDsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpmaWxsKFNwbGFzaFBhdGggKnBhdGgsIEdCb29sIGVvKSB7CiAgaWYgKGRlYnVnTW9kZSkgewogICAgcHJpbnRmKCJmaWxsIFtlbzolZF06XG4iLCBlbyk7CiAgICBkdW1wUGF0aChwYXRoKTsKICB9CiAgcmV0dXJuIGZpbGxXaXRoUGF0dGVybihwYXRoLCBlbywgc3RhdGUtPmZpbGxQYXR0ZXJuLCBzdGF0ZS0+ZmlsbEFscGhhKTsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpmaWxsV2l0aFBhdHRlcm4oU3BsYXNoUGF0aCAqcGF0aCwgR0Jvb2wgZW8sCgkJCQkgICAgU3BsYXNoUGF0dGVybiAqcGF0dGVybiwKCQkJCSAgICBTcGxhc2hDb29yZCBhbHBoYSkgewogIFNwbGFzaFBpcGUgcGlwZTsKICBTcGxhc2hYUGF0aCAqeFBhdGg7CiAgU3BsYXNoWFBhdGhTY2FubmVyICpzY2FubmVyOwogIGludCB4TWluSSwgeU1pbkksIHhNYXhJLCB5TWF4SSwgeDAsIHgxLCB5OwogIFNwbGFzaENsaXBSZXN1bHQgY2xpcFJlcywgY2xpcFJlczI7CgogIGlmIChwYXRoLT5sZW5ndGggPT0gMCkgewogICAgcmV0dXJuIHNwbGFzaEVyckVtcHR5UGF0aDsKICB9CiAgaWYgKHBhdGhBbGxPdXRzaWRlKHBhdGgpKSB7CiAgICBvcENsaXBSZXMgPSBzcGxhc2hDbGlwQWxsT3V0c2lkZTsKICAgIHJldHVybiBzcGxhc2hPazsKICB9CgogIC8vIGFkZCBzdHJva2UgYWRqdXN0bWVudCBoaW50cyBmb3IgZmlsbGVkIHJlY3RhbmdsZXMgLS0gdGhpcyBvbmx5CiAgLy8gYXBwbGllcyB0byBwYXRocyB0aGF0IGNvbnNpc3Qgb2YgYSBzaW5nbGUgc3VicGF0aAogIC8vICh0aGlzIGFwcGVhcnMgdG8gbWF0Y2ggQWNyb2JhdCdzIGJlaGF2aW9yKQogIGlmIChzdGF0ZS0+c3Ryb2tlQWRqdXN0ICYmICFwYXRoLT5oaW50cykgewogICAgaW50IG47CiAgICBuID0gcGF0aC0+Z2V0TGVuZ3RoKCk7CiAgICBpZiAobiA9PSA0ICYmCgkhKHBhdGgtPmZsYWdzWzBdICYgc3BsYXNoUGF0aENsb3NlZCkgJiYKCSEocGF0aC0+ZmxhZ3NbMV0gJiBzcGxhc2hQYXRoTGFzdCkgJiYKCSEocGF0aC0+ZmxhZ3NbMl0gJiBzcGxhc2hQYXRoTGFzdCkpIHsKICAgICAgcGF0aC0+Y2xvc2UoZ1RydWUpOwogICAgICBwYXRoLT5hZGRTdHJva2VBZGp1c3RIaW50KDAsIDIsIDAsIDQpOwogICAgICBwYXRoLT5hZGRTdHJva2VBZGp1c3RIaW50KDEsIDMsIDAsIDQpOwogICAgfSBlbHNlIGlmIChuID09IDUgJiYKCSAgICAgICAocGF0aC0+ZmxhZ3NbMF0gJiBzcGxhc2hQYXRoQ2xvc2VkKSAmJgoJICAgICAgICEocGF0aC0+ZmxhZ3NbMV0gJiBzcGxhc2hQYXRoTGFzdCkgJiYKCSAgICAgICAhKHBhdGgtPmZsYWdzWzJdICYgc3BsYXNoUGF0aExhc3QpICYmCgkgICAgICAgIShwYXRoLT5mbGFnc1szXSAmIHNwbGFzaFBhdGhMYXN0KSkgewogICAgICBwYXRoLT5hZGRTdHJva2VBZGp1c3RIaW50KDAsIDIsIDAsIDQpOwogICAgICBwYXRoLT5hZGRTdHJva2VBZGp1c3RIaW50KDEsIDMsIDAsIDQpOwogICAgfQogIH0KCiAgeFBhdGggPSBuZXcgU3BsYXNoWFBhdGgocGF0aCwgc3RhdGUtPm1hdHJpeCwgc3RhdGUtPmZsYXRuZXNzLCBnVHJ1ZSk7CiAgaWYgKHZlY3RvckFudGlhbGlhcyAmJiAhaW5TaGFkaW5nKSB7CiAgICB4UGF0aC0+YWFTY2FsZSgpOwogIH0KICB4UGF0aC0+c29ydCgpOwogIHlNaW5JID0gc3RhdGUtPmNsaXAtPmdldFlNaW5JKCk7CiAgeU1heEkgPSBzdGF0ZS0+Y2xpcC0+Z2V0WU1heEkoKTsKICBpZiAodmVjdG9yQW50aWFsaWFzICYmICFpblNoYWRpbmcpIHsKICAgIHlNaW5JID0geU1pbkkgKiBzcGxhc2hBQVNpemU7CiAgICB5TWF4SSA9ICh5TWF4SSArIDEpICogc3BsYXNoQUFTaXplIC0gMTsKICB9CiAgc2Nhbm5lciA9IG5ldyBTcGxhc2hYUGF0aFNjYW5uZXIoeFBhdGgsIGVvLCB5TWluSSwgeU1heEkpOwoKICAvLyBnZXQgdGhlIG1pbiBhbmQgbWF4IHggYW5kIHkgdmFsdWVzCiAgaWYgKHZlY3RvckFudGlhbGlhcyAmJiAhaW5TaGFkaW5nKSB7CiAgICBzY2FubmVyLT5nZXRCQm94QUEoJnhNaW5JLCAmeU1pbkksICZ4TWF4SSwgJnlNYXhJKTsKICB9IGVsc2UgewogICAgc2Nhbm5lci0+Z2V0QkJveCgmeE1pbkksICZ5TWluSSwgJnhNYXhJLCAmeU1heEkpOwogIH0KCiAgLy8gY2hlY2sgY2xpcHBpbmcKICBpZiAoKGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeE1pbkksIHlNaW5JLCB4TWF4SSwgeU1heEkpKQogICAgICAhPSBzcGxhc2hDbGlwQWxsT3V0c2lkZSkgewogICAgaWYgKHNjYW5uZXItPmhhc1BhcnRpYWxDbGlwKCkpIHsKICAgICAgY2xpcFJlcyA9IHNwbGFzaENsaXBQYXJ0aWFsOwogICAgfQoKICAgIHBpcGVJbml0KCZwaXBlLCAwLCB5TWluSSwgcGF0dGVybiwgTlVMTCwgKEd1Y2hhcilzcGxhc2hSb3VuZChhbHBoYSAqIDI1NSksCgkgICAgIHZlY3RvckFudGlhbGlhcyAmJiAhaW5TaGFkaW5nLCBnRmFsc2UpOwoKICAgIC8vIGRyYXcgdGhlIHNwYW5zCiAgICBpZiAodmVjdG9yQW50aWFsaWFzICYmICFpblNoYWRpbmcpIHsKICAgICAgZm9yICh5ID0geU1pbkk7IHkgPD0geU1heEk7ICsreSkgewoJc2Nhbm5lci0+cmVuZGVyQUFMaW5lKGFhQnVmLCAmeDAsICZ4MSwgeSk7CglpZiAoY2xpcFJlcyAhPSBzcGxhc2hDbGlwQWxsSW5zaWRlKSB7CgkgIHN0YXRlLT5jbGlwLT5jbGlwQUFMaW5lKGFhQnVmLCAmeDAsICZ4MSwgeSk7Cgl9CglkcmF3QUFMaW5lKCZwaXBlLCB4MCwgeDEsIHkpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBmb3IgKHkgPSB5TWluSTsgeSA8PSB5TWF4STsgKyt5KSB7Cgl3aGlsZSAoc2Nhbm5lci0+Z2V0TmV4dFNwYW4oeSwgJngwLCAmeDEpKSB7CgkgIGlmIChjbGlwUmVzID09IHNwbGFzaENsaXBBbGxJbnNpZGUpIHsKCSAgICBkcmF3U3BhbigmcGlwZSwgeDAsIHgxLCB5LCBnVHJ1ZSk7CgkgIH0gZWxzZSB7CgkgICAgLy8gbGltaXQgdGhlIHggcmFuZ2UKCSAgICBpZiAoeDAgPCBzdGF0ZS0+Y2xpcC0+Z2V0WE1pbkkoKSkgewoJICAgICAgeDAgPSBzdGF0ZS0+Y2xpcC0+Z2V0WE1pbkkoKTsKCSAgICB9CgkgICAgaWYgKHgxID4gc3RhdGUtPmNsaXAtPmdldFhNYXhJKCkpIHsKCSAgICAgIHgxID0gc3RhdGUtPmNsaXAtPmdldFhNYXhJKCk7CgkgICAgfQoJICAgIGNsaXBSZXMyID0gc3RhdGUtPmNsaXAtPnRlc3RTcGFuKHgwLCB4MSwgeSk7CgkgICAgZHJhd1NwYW4oJnBpcGUsIHgwLCB4MSwgeSwgY2xpcFJlczIgPT0gc3BsYXNoQ2xpcEFsbEluc2lkZSk7CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KICBvcENsaXBSZXMgPSBjbGlwUmVzOwoKICBkZWxldGUgc2Nhbm5lcjsKICBkZWxldGUgeFBhdGg7CiAgcmV0dXJuIHNwbGFzaE9rOwp9CgpHQm9vbCBTcGxhc2g6OnBhdGhBbGxPdXRzaWRlKFNwbGFzaFBhdGggKnBhdGgpIHsKICBTcGxhc2hDb29yZCB4TWluMSwgeU1pbjEsIHhNYXgxLCB5TWF4MTsKICBTcGxhc2hDb29yZCB4TWluMiwgeU1pbjIsIHhNYXgyLCB5TWF4MjsKICBTcGxhc2hDb29yZCB4LCB5OwogIGludCB4TWluSSwgeU1pbkksIHhNYXhJLCB5TWF4STsKICBpbnQgaTsKCiAgeE1pbjEgPSB4TWF4MSA9IHBhdGgtPnB0c1swXS54OwogIHlNaW4xID0geU1heDEgPSBwYXRoLT5wdHNbMF0ueTsKICBmb3IgKGkgPSAxOyBpIDwgcGF0aC0+bGVuZ3RoOyArK2kpIHsKICAgIGlmIChwYXRoLT5wdHNbaV0ueCA8IHhNaW4xKSB7CiAgICAgIHhNaW4xID0gcGF0aC0+cHRzW2ldLng7CiAgICB9IGVsc2UgaWYgKHBhdGgtPnB0c1tpXS54ID4geE1heDEpIHsKICAgICAgeE1heDEgPSBwYXRoLT5wdHNbaV0ueDsKICAgIH0KICAgIGlmIChwYXRoLT5wdHNbaV0ueSA8IHlNaW4xKSB7CiAgICAgIHlNaW4xID0gcGF0aC0+cHRzW2ldLnk7CiAgICB9IGVsc2UgaWYgKHBhdGgtPnB0c1tpXS55ID4geU1heDEpIHsKICAgICAgeU1heDEgPSBwYXRoLT5wdHNbaV0ueTsKICAgIH0KICB9CgogIHRyYW5zZm9ybShzdGF0ZS0+bWF0cml4LCB4TWluMSwgeU1pbjEsICZ4LCAmeSk7CiAgeE1pbjIgPSB4TWF4MiA9IHg7CiAgeU1pbjIgPSB5TWF4MiA9IHk7CiAgdHJhbnNmb3JtKHN0YXRlLT5tYXRyaXgsIHhNaW4xLCB5TWF4MSwgJngsICZ5KTsKICBpZiAoeCA8IHhNaW4yKSB7CiAgICB4TWluMiA9IHg7CiAgfSBlbHNlIGlmICh4ID4geE1heDIpIHsKICAgIHhNYXgyID0geDsKICB9CiAgaWYgKHkgPCB5TWluMikgewogICAgeU1pbjIgPSB5OwogIH0gZWxzZSBpZiAoeSA+IHlNYXgyKSB7CiAgICB5TWF4MiA9IHk7CiAgfQogIHRyYW5zZm9ybShzdGF0ZS0+bWF0cml4LCB4TWF4MSwgeU1pbjEsICZ4LCAmeSk7CiAgaWYgKHggPCB4TWluMikgewogICAgeE1pbjIgPSB4OwogIH0gZWxzZSBpZiAoeCA+IHhNYXgyKSB7CiAgICB4TWF4MiA9IHg7CiAgfQogIGlmICh5IDwgeU1pbjIpIHsKICAgIHlNaW4yID0geTsKICB9IGVsc2UgaWYgKHkgPiB5TWF4MikgewogICAgeU1heDIgPSB5OwogIH0KICB0cmFuc2Zvcm0oc3RhdGUtPm1hdHJpeCwgeE1heDEsIHlNYXgxLCAmeCwgJnkpOwogIGlmICh4IDwgeE1pbjIpIHsKICAgIHhNaW4yID0geDsKICB9IGVsc2UgaWYgKHggPiB4TWF4MikgewogICAgeE1heDIgPSB4OwogIH0KICBpZiAoeSA8IHlNaW4yKSB7CiAgICB5TWluMiA9IHk7CiAgfSBlbHNlIGlmICh5ID4geU1heDIpIHsKICAgIHlNYXgyID0geTsKICB9CiAgeE1pbkkgPSBzcGxhc2hGbG9vcih4TWluMik7CiAgeU1pbkkgPSBzcGxhc2hGbG9vcih5TWluMik7CiAgeE1heEkgPSBzcGxhc2hGbG9vcih4TWF4Mik7CiAgeU1heEkgPSBzcGxhc2hGbG9vcih5TWF4Mik7CgogIHJldHVybiBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeE1pbkksIHlNaW5JLCB4TWF4SSwgeU1heEkpID09CiAgICAgICAgIHNwbGFzaENsaXBBbGxPdXRzaWRlOwp9CgpTcGxhc2hFcnJvciBTcGxhc2g6OnhvckZpbGwoU3BsYXNoUGF0aCAqcGF0aCwgR0Jvb2wgZW8pIHsKICBTcGxhc2hQaXBlIHBpcGU7CiAgU3BsYXNoWFBhdGggKnhQYXRoOwogIFNwbGFzaFhQYXRoU2Nhbm5lciAqc2Nhbm5lcjsKICBpbnQgeE1pbkksIHlNaW5JLCB4TWF4SSwgeU1heEksIHgwLCB4MSwgeTsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXMsIGNsaXBSZXMyOwogIFNwbGFzaEJsZW5kRnVuYyBvcmlnQmxlbmRGdW5jOwoKICBpZiAocGF0aC0+bGVuZ3RoID09IDApIHsKICAgIHJldHVybiBzcGxhc2hFcnJFbXB0eVBhdGg7CiAgfQogIHhQYXRoID0gbmV3IFNwbGFzaFhQYXRoKHBhdGgsIHN0YXRlLT5tYXRyaXgsIHN0YXRlLT5mbGF0bmVzcywgZ1RydWUpOwogIHhQYXRoLT5zb3J0KCk7CiAgc2Nhbm5lciA9IG5ldyBTcGxhc2hYUGF0aFNjYW5uZXIoeFBhdGgsIGVvLCBzdGF0ZS0+Y2xpcC0+Z2V0WU1pbkkoKSwKCQkJCSAgIHN0YXRlLT5jbGlwLT5nZXRZTWF4SSgpKTsKCiAgLy8gZ2V0IHRoZSBtaW4gYW5kIG1heCB4IGFuZCB5IHZhbHVlcwogIHNjYW5uZXItPmdldEJCb3goJnhNaW5JLCAmeU1pbkksICZ4TWF4SSwgJnlNYXhJKTsKCiAgLy8gY2hlY2sgY2xpcHBpbmcKICBpZiAoKGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeE1pbkksIHlNaW5JLCB4TWF4SSwgeU1heEkpKQogICAgICAhPSBzcGxhc2hDbGlwQWxsT3V0c2lkZSkgewogICAgaWYgKHNjYW5uZXItPmhhc1BhcnRpYWxDbGlwKCkpIHsKICAgICAgY2xpcFJlcyA9IHNwbGFzaENsaXBQYXJ0aWFsOwogICAgfQoKICAgIG9yaWdCbGVuZEZ1bmMgPSBzdGF0ZS0+YmxlbmRGdW5jOwogICAgc3RhdGUtPmJsZW5kRnVuYyA9ICZibGVuZFhvcjsKICAgIHBpcGVJbml0KCZwaXBlLCAwLCB5TWluSSwgc3RhdGUtPmZpbGxQYXR0ZXJuLCBOVUxMLCAyNTUsIGdGYWxzZSwgZ0ZhbHNlKTsKCiAgICAvLyBkcmF3IHRoZSBzcGFucwogICAgZm9yICh5ID0geU1pbkk7IHkgPD0geU1heEk7ICsreSkgewogICAgICB3aGlsZSAoc2Nhbm5lci0+Z2V0TmV4dFNwYW4oeSwgJngwLCAmeDEpKSB7CglpZiAoY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKSB7CgkgIGRyYXdTcGFuKCZwaXBlLCB4MCwgeDEsIHksIGdUcnVlKTsKCX0gZWxzZSB7CgkgIC8vIGxpbWl0IHRoZSB4IHJhbmdlCgkgIGlmICh4MCA8IHN0YXRlLT5jbGlwLT5nZXRYTWluSSgpKSB7CgkgICAgeDAgPSBzdGF0ZS0+Y2xpcC0+Z2V0WE1pbkkoKTsKCSAgfQoJICBpZiAoeDEgPiBzdGF0ZS0+Y2xpcC0+Z2V0WE1heEkoKSkgewoJICAgIHgxID0gc3RhdGUtPmNsaXAtPmdldFhNYXhJKCk7CgkgIH0KCSAgY2xpcFJlczIgPSBzdGF0ZS0+Y2xpcC0+dGVzdFNwYW4oeDAsIHgxLCB5KTsKCSAgZHJhd1NwYW4oJnBpcGUsIHgwLCB4MSwgeSwgY2xpcFJlczIgPT0gc3BsYXNoQ2xpcEFsbEluc2lkZSk7Cgl9CiAgICAgIH0KICAgIH0KICAgIHN0YXRlLT5ibGVuZEZ1bmMgPSBvcmlnQmxlbmRGdW5jOwogIH0KICBvcENsaXBSZXMgPSBjbGlwUmVzOwoKICBkZWxldGUgc2Nhbm5lcjsKICBkZWxldGUgeFBhdGg7CiAgcmV0dXJuIHNwbGFzaE9rOwp9CgpTcGxhc2hFcnJvciBTcGxhc2g6OmZpbGxDaGFyKFNwbGFzaENvb3JkIHgsIFNwbGFzaENvb3JkIHksCgkJCSAgICAgaW50IGMsIFNwbGFzaEZvbnQgKmZvbnQpIHsKICBTcGxhc2hHbHlwaEJpdG1hcCBnbHlwaDsKICBTcGxhc2hDb29yZCB4dCwgeXQ7CiAgaW50IHgwLCB5MCwgeEZyYWMsIHlGcmFjOwogIFNwbGFzaENsaXBSZXN1bHQgY2xpcFJlczsKCiAgaWYgKGRlYnVnTW9kZSkgewogICAgcHJpbnRmKCJmaWxsQ2hhcjogeD0lLjJmIHk9JS4yZiBjPSUzZD0weCUwMng9JyVjJ1xuIiwKCSAgIChkb3VibGUpeCwgKGRvdWJsZSl5LCBjLCBjLCBjKTsKICB9CiAgdHJhbnNmb3JtKHN0YXRlLT5tYXRyaXgsIHgsIHksICZ4dCwgJnl0KTsKICB4MCA9IHNwbGFzaEZsb29yKHh0KTsKICB4RnJhYyA9IHNwbGFzaEZsb29yKCh4dCAtIHgwKSAqIHNwbGFzaEZvbnRGcmFjdGlvbik7CiAgeTAgPSBzcGxhc2hGbG9vcih5dCk7CiAgeUZyYWMgPSBzcGxhc2hGbG9vcigoeXQgLSB5MCkgKiBzcGxhc2hGb250RnJhY3Rpb24pOwogIGlmICghZm9udC0+Z2V0R2x5cGgoYywgeEZyYWMsIHlGcmFjLCAmZ2x5cGgsIHgwLCB5MCwgc3RhdGUtPmNsaXAsICZjbGlwUmVzKSkgewogICAgcmV0dXJuIHNwbGFzaEVyck5vR2x5cGg7CiAgfQogIGlmIChjbGlwUmVzICE9IHNwbGFzaENsaXBBbGxPdXRzaWRlKSB7CiAgICBmaWxsR2x5cGgyKHgwLCB5MCwgJmdseXBoLCBjbGlwUmVzID09IHNwbGFzaENsaXBBbGxJbnNpZGUpOwogIH0KICBvcENsaXBSZXMgPSBjbGlwUmVzOwogIGlmIChnbHlwaC5mcmVlRGF0YSkgewogICAgZ2ZyZWUoZ2x5cGguZGF0YSk7CiAgfQogIHJldHVybiBzcGxhc2hPazsKfQoKdm9pZCBTcGxhc2g6OmZpbGxHbHlwaChTcGxhc2hDb29yZCB4LCBTcGxhc2hDb29yZCB5LAoJCQkgICAgICBTcGxhc2hHbHlwaEJpdG1hcCAqZ2x5cGgpIHsKICBTcGxhc2hDb29yZCB4dCwgeXQ7CiAgaW50IHgwLCB5MDsKCiAgdHJhbnNmb3JtKHN0YXRlLT5tYXRyaXgsIHgsIHksICZ4dCwgJnl0KTsKICB4MCA9IHNwbGFzaEZsb29yKHh0KTsKICB5MCA9IHNwbGFzaEZsb29yKHl0KTsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeDAgLSBnbHlwaC0+eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MCAtIGdseXBoLT55LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgwIC0gZ2x5cGgtPnggKyBnbHlwaC0+dyAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTAgLSBnbHlwaC0+eSArIGdseXBoLT5oIC0gMSk7CiAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbE91dHNpZGUpIHsKICAgIGZpbGxHbHlwaDIoeDAsIHkwLCBnbHlwaCwgY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKTsKICB9CiAgb3BDbGlwUmVzID0gY2xpcFJlczsKfQoKdm9pZCBTcGxhc2g6OmZpbGxHbHlwaDIoaW50IHgwLCBpbnQgeTAsIFNwbGFzaEdseXBoQml0bWFwICpnbHlwaCwgR0Jvb2wgbm9DbGlwKSB7CiAgU3BsYXNoUGlwZSBwaXBlOwogIGludCBhbHBoYTA7CiAgR3VjaGFyIGFscGhhOwogIEd1Y2hhciAqcDsKICBpbnQgeDEsIHkxLCB4eCwgeHgxLCB5eTsKCiAgcCA9IGdseXBoLT5kYXRhOwogIGludCB4U3RhcnQgPSB4MCAtIGdseXBoLT54OwogIGludCB5U3RhcnQgPSB5MCAtIGdseXBoLT55OwogIGludCB4eExpbWl0ID0gZ2x5cGgtPnc7CiAgaW50IHl5TGltaXQgPSBnbHlwaC0+aDsKICBpbnQgeFNoaWZ0ID0gMDsKCiAgaWYgKHlTdGFydCA8IDApCiAgewogICAgcCArPSAoZ2x5cGgtPmFhID8gZ2x5cGgtPncgOiBzcGxhc2hDZWlsKGdseXBoLT53IC8gOC4wKSkgKiAteVN0YXJ0OyAvLyBtb3ZlIHAgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgcGFpbnRlZCByb3cKICAgIHl5TGltaXQgKz0geVN0YXJ0OwogICAgeVN0YXJ0ID0gMDsKICB9CgogIGlmICh4U3RhcnQgPCAwKQogIHsKICAgIGlmIChnbHlwaC0+YWEpIHsKICAgICAgcCArPSAteFN0YXJ0OwogICAgfSBlbHNlIHsKICAgICAgcCArPSAoLXhTdGFydCkgLyA4OwogICAgICB4U2hpZnQgPSAoLXhTdGFydCkgJSA4OwogICAgfQogICAgeHhMaW1pdCArPSB4U3RhcnQ7CiAgICB4U3RhcnQgPSAwOwogIH0KCiAgaWYgKHh4TGltaXQgKyB4U3RhcnQgPj0gYml0bWFwLT53aWR0aCkgeHhMaW1pdCA9IGJpdG1hcC0+d2lkdGggLSB4U3RhcnQ7CiAgaWYgKHl5TGltaXQgKyB5U3RhcnQgPj0gYml0bWFwLT5oZWlnaHQpIHl5TGltaXQgPSBiaXRtYXAtPmhlaWdodCAtIHlTdGFydDsKCiAgaWYgKG5vQ2xpcCkgewogICAgaWYgKGdseXBoLT5hYSkgewogICAgICBwaXBlSW5pdCgmcGlwZSwgeFN0YXJ0LCB5U3RhcnQsCiAgICAgICAgICAgICAgIHN0YXRlLT5maWxsUGF0dGVybiwgTlVMTCwgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ1RydWUsIGdGYWxzZSk7CiAgICAgIGZvciAoeXkgPSAwLCB5MSA9IHlTdGFydDsgeXkgPCB5eUxpbWl0OyArK3l5LCArK3kxKSB7CiAgICAgICAgcGlwZVNldFhZKCZwaXBlLCB4U3RhcnQsIHkxKTsKICAgICAgICBmb3IgKHh4ID0gMCwgeDEgPSB4U3RhcnQ7IHh4IDwgeHhMaW1pdDsgKyt4eCwgKyt4MSkgewogICAgICAgICAgYWxwaGEgPSBwW3h4XTsKICAgICAgICAgIGlmIChhbHBoYSAhPSAwKSB7CiAgICAgICAgICAgIHBpcGUuc2hhcGUgPSBhbHBoYTsKICAgICAgICAgICAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwogICAgICAgICAgICB1cGRhdGVNb2RYKHgxKTsKICAgICAgICAgICAgdXBkYXRlTW9kWSh5MSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwaXBlSW5jWCgmcGlwZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHAgKz0gZ2x5cGgtPnc7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IGludCB3aWR0aEVpZ2h0ID0gc3BsYXNoQ2VpbChnbHlwaC0+dyAvIDguMCk7CgogICAgICBwaXBlSW5pdCgmcGlwZSwgeFN0YXJ0LCB5U3RhcnQsCiAgICAgICAgICAgICAgIHN0YXRlLT5maWxsUGF0dGVybiwgTlVMTCwgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ0ZhbHNlLCBnRmFsc2UpOwogICAgICBmb3IgKHl5ID0gMCwgeTEgPSB5U3RhcnQ7IHl5IDwgeXlMaW1pdDsgKyt5eSwgKyt5MSkgewogICAgICAgIHBpcGVTZXRYWSgmcGlwZSwgeFN0YXJ0LCB5MSk7CiAgICAgICAgZm9yICh4eCA9IDAsIHgxID0geFN0YXJ0OyB4eCA8IHh4TGltaXQ7IHh4ICs9IDgpIHsKICAgICAgICAgIGFscGhhMCA9ICh4U2hpZnQgPiAwID8gKHBbeHggLyA4XSA8PCB4U2hpZnQpIHwgKHBbeHggLyA4ICsgMV0gPj4gKDggLSB4U2hpZnQpKSA6IHBbeHggLyA4XSk7CiAgICAgICAgICBmb3IgKHh4MSA9IDA7IHh4MSA8IDggJiYgeHggKyB4eDEgPCB4eExpbWl0OyArK3h4MSwgKyt4MSkgewogICAgICAgICAgICBpZiAoYWxwaGEwICYgMHg4MCkgewogICAgICAgICAgICAgICh0aGlzLT4qcGlwZS5ydW4pKCZwaXBlKTsKICAgICAgICAgICAgICB1cGRhdGVNb2RYKHgxKTsKICAgICAgICAgICAgICB1cGRhdGVNb2RZKHkxKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBwaXBlSW5jWCgmcGlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWxwaGEwIDw8PSAxOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwICs9IHdpZHRoRWlnaHQ7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgaWYgKGdseXBoLT5hYSkgewogICAgICBwaXBlSW5pdCgmcGlwZSwgeFN0YXJ0LCB5U3RhcnQsCiAgICAgICAgICAgICAgIHN0YXRlLT5maWxsUGF0dGVybiwgTlVMTCwgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ1RydWUsIGdGYWxzZSk7CiAgICAgIGZvciAoeXkgPSAwLCB5MSA9IHlTdGFydDsgeXkgPCB5eUxpbWl0OyArK3l5LCArK3kxKSB7CiAgICAgICAgcGlwZVNldFhZKCZwaXBlLCB4U3RhcnQsIHkxKTsKICAgICAgICBmb3IgKHh4ID0gMCwgeDEgPSB4U3RhcnQ7IHh4IDwgeHhMaW1pdDsgKyt4eCwgKyt4MSkgewogICAgICAgICAgaWYgKHN0YXRlLT5jbGlwLT50ZXN0KHgxLCB5MSkpIHsKICAgICAgICAgICAgYWxwaGEgPSBwW3h4XTsKICAgICAgICAgICAgaWYgKGFscGhhICE9IDApIHsKICAgICAgICAgICAgICBwaXBlLnNoYXBlID0gYWxwaGE7CiAgICAgICAgICAgICAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwogICAgICAgICAgICAgIHVwZGF0ZU1vZFgoeDEpOwogICAgICAgICAgICAgIHVwZGF0ZU1vZFkoeTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHBpcGVJbmNYKCZwaXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGlwZUluY1goJnBpcGUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwICs9IGdseXBoLT53OwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjb25zdCBpbnQgd2lkdGhFaWdodCA9IHNwbGFzaENlaWwoZ2x5cGgtPncgLyA4LjApOwoKICAgICAgcGlwZUluaXQoJnBpcGUsIHhTdGFydCwgeVN0YXJ0LAogICAgICAgICAgICAgICBzdGF0ZS0+ZmlsbFBhdHRlcm4sIE5VTEwsIChHdWNoYXIpc3BsYXNoUm91bmQoc3RhdGUtPmZpbGxBbHBoYSAqIDI1NSksIGdGYWxzZSwgZ0ZhbHNlKTsKICAgICAgZm9yICh5eSA9IDAsIHkxID0geVN0YXJ0OyB5eSA8IHl5TGltaXQ7ICsreXksICsreTEpIHsKICAgICAgICBwaXBlU2V0WFkoJnBpcGUsIHhTdGFydCwgeTEpOwogICAgICAgIGZvciAoeHggPSAwLCB4MSA9IHhTdGFydDsgeHggPCB4eExpbWl0OyB4eCArPSA4KSB7CiAgICAgICAgICBhbHBoYTAgPSAoeFNoaWZ0ID4gMCA/IChwW3h4IC8gOF0gPDwgeFNoaWZ0KSB8IChwW3h4IC8gOCArIDFdID4+ICg4IC0geFNoaWZ0KSkgOiBwW3h4IC8gOF0pOwogICAgICAgICAgZm9yICh4eDEgPSAwOyB4eDEgPCA4ICYmIHh4ICsgeHgxIDwgeHhMaW1pdDsgKyt4eDEsICsreDEpIHsKICAgICAgICAgICAgaWYgKHN0YXRlLT5jbGlwLT50ZXN0KHgxLCB5MSkpIHsKICAgICAgICAgICAgICBpZiAoYWxwaGEwICYgMHg4MCkgewogICAgICAgICAgICAgICAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwogICAgICAgICAgICAgICAgdXBkYXRlTW9kWCh4MSk7CiAgICAgICAgICAgICAgICB1cGRhdGVNb2RZKHkxKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGlwZUluY1goJnBpcGUpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBwaXBlSW5jWCgmcGlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWxwaGEwIDw8PSAxOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwICs9IHdpZHRoRWlnaHQ7CiAgICAgIH0KICAgIH0KICB9Cn0KClNwbGFzaEVycm9yIFNwbGFzaDo6ZmlsbEltYWdlTWFzayhTcGxhc2hJbWFnZU1hc2tTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkJICBpbnQgdywgaW50IGgsIFNwbGFzaENvb3JkICptYXQsCgkJCQkgIEdCb29sIGdseXBoTW9kZSkgewogIFNwbGFzaEJpdG1hcCAqc2NhbGVkTWFzazsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXM7CiAgR0Jvb2wgbWlub3JBeGlzWmVybzsKICBpbnQgeDAsIHkwLCB4MSwgeTEsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQ7CiAgaW50IHlwOwoKICBpZiAoZGVidWdNb2RlKSB7CiAgICBwcmludGYoImZpbGxJbWFnZU1hc2s6IHc9JWQgaD0lZCBtYXQ9WyUuMmYgJS4yZiAlLjJmICUuMmYgJS4yZiAlLjJmXVxuIiwKCSAgIHcsIGgsIChkb3VibGUpbWF0WzBdLCAoZG91YmxlKW1hdFsxXSwgKGRvdWJsZSltYXRbMl0sCgkgICAoZG91YmxlKW1hdFszXSwgKGRvdWJsZSltYXRbNF0sIChkb3VibGUpbWF0WzVdKTsKICB9CgogIGlmICh3ID09IDAgJiYgaCA9PSAwKSByZXR1cm4gc3BsYXNoRXJyWmVyb0ltYWdlOwoKICAvLyBjaGVjayBmb3Igc2luZ3VsYXIgbWF0cml4CiAgaWYgKCFzcGxhc2hDaGVja0RldChtYXRbMF0sIG1hdFsxXSwgbWF0WzJdLCBtYXRbM10sIDAuMDAwMDAxKSkgewogICAgcmV0dXJuIHNwbGFzaEVyclNpbmd1bGFyTWF0cml4OwogIH0KCiAgbWlub3JBeGlzWmVybyA9IG1hdFsxXSA9PSAwICYmIG1hdFsyXSA9PSAwOwoKICAvLyBzY2FsaW5nIG9ubHkKICBpZiAobWF0WzBdID4gMCAmJiBtaW5vckF4aXNaZXJvICYmIG1hdFszXSA+IDApIHsKICAgIHgwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbNF0sIGdseXBoTW9kZSk7CiAgICB5MCA9IGltZ0Nvb3JkTXVuZ2VMb3dlckMobWF0WzVdLCBnbHlwaE1vZGUpOwogICAgeDEgPSBpbWdDb29yZE11bmdlVXBwZXJDKG1hdFswXSArIG1hdFs0XSwgZ2x5cGhNb2RlKTsKICAgIHkxID0gaW1nQ29vcmRNdW5nZVVwcGVyQyhtYXRbM10gKyBtYXRbNV0sIGdseXBoTW9kZSk7CiAgICAvLyBtYWtlIHN1cmUgbmFycm93IGltYWdlcyBjb3ZlciBhdCBsZWFzdCBvbmUgcGl4ZWwKICAgIGlmICh4MCA9PSB4MSkgewogICAgICArK3gxOwogICAgfQogICAgaWYgKHkwID09IHkxKSB7CiAgICAgICsreTE7CiAgICB9CiAgICBjbGlwUmVzID0gc3RhdGUtPmNsaXAtPnRlc3RSZWN0KHgwLCB5MCwgeDEgLSAxLCB5MSAtIDEpOwogICAgb3BDbGlwUmVzID0gY2xpcFJlczsKICAgIGlmIChjbGlwUmVzICE9IHNwbGFzaENsaXBBbGxPdXRzaWRlKSB7CiAgICAgIHNjYWxlZFdpZHRoID0geDEgLSB4MDsKICAgICAgc2NhbGVkSGVpZ2h0ID0geTEgLSB5MDsKICAgICAgeXAgPSBoIC8gc2NhbGVkSGVpZ2h0OwogICAgICBpZiAoeXAgPCAwIHx8IHlwID4gSU5UX01BWCAtIDEpIHsKICAgICAgICByZXR1cm4gc3BsYXNoRXJyQmFkQXJnOwogICAgICB9CiAgICAgIHNjYWxlZE1hc2sgPSBzY2FsZU1hc2soc3JjLCBzcmNEYXRhLCB3LCBoLCBzY2FsZWRXaWR0aCwgc2NhbGVkSGVpZ2h0KTsKICAgICAgYmxpdE1hc2soc2NhbGVkTWFzaywgeDAsIHkwLCBjbGlwUmVzKTsKICAgICAgZGVsZXRlIHNjYWxlZE1hc2s7CiAgICB9CgogIC8vIHNjYWxpbmcgcGx1cyB2ZXJ0aWNhbCBmbGlwCiAgfSBlbHNlIGlmIChtYXRbMF0gPiAwICYmIG1pbm9yQXhpc1plcm8gJiYgbWF0WzNdIDwgMCkgewogICAgeDAgPSBpbWdDb29yZE11bmdlTG93ZXJDKG1hdFs0XSwgZ2x5cGhNb2RlKTsKICAgIHkwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbM10gKyBtYXRbNV0sIGdseXBoTW9kZSk7CiAgICB4MSA9IGltZ0Nvb3JkTXVuZ2VVcHBlckMobWF0WzBdICsgbWF0WzRdLCBnbHlwaE1vZGUpOwogICAgeTEgPSBpbWdDb29yZE11bmdlVXBwZXJDKG1hdFs1XSwgZ2x5cGhNb2RlKTsKICAgIC8vIG1ha2Ugc3VyZSBuYXJyb3cgaW1hZ2VzIGNvdmVyIGF0IGxlYXN0IG9uZSBwaXhlbAogICAgaWYgKHgwID09IHgxKSB7CiAgICAgICsreDE7CiAgICB9CiAgICBpZiAoeTAgPT0geTEpIHsKICAgICAgKyt5MTsKICAgIH0KICAgIGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeDAsIHkwLCB4MSAtIDEsIHkxIC0gMSk7CiAgICBvcENsaXBSZXMgPSBjbGlwUmVzOwogICAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbE91dHNpZGUpIHsKICAgICAgc2NhbGVkV2lkdGggPSB4MSAtIHgwOwogICAgICBzY2FsZWRIZWlnaHQgPSB5MSAtIHkwOwogICAgICB5cCA9IGggLyBzY2FsZWRIZWlnaHQ7CiAgICAgIGlmICh5cCA8IDAgfHwgeXAgPiBJTlRfTUFYIC0gMSkgewogICAgICAgIHJldHVybiBzcGxhc2hFcnJCYWRBcmc7CiAgICAgIH0KICAgICAgc2NhbGVkTWFzayA9IHNjYWxlTWFzayhzcmMsIHNyY0RhdGEsIHcsIGgsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQpOwogICAgICB2ZXJ0RmxpcEltYWdlKHNjYWxlZE1hc2ssIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIDEpOwogICAgICBibGl0TWFzayhzY2FsZWRNYXNrLCB4MCwgeTAsIGNsaXBSZXMpOwogICAgICBkZWxldGUgc2NhbGVkTWFzazsKICAgIH0KCiAgLy8gYWxsIG90aGVyIGNhc2VzCiAgfSBlbHNlIHsKICAgIGFyYml0cmFyeVRyYW5zZm9ybU1hc2soc3JjLCBzcmNEYXRhLCB3LCBoLCBtYXQsIGdseXBoTW9kZSk7CiAgfQoKICByZXR1cm4gc3BsYXNoT2s7Cn0KCnZvaWQgU3BsYXNoOjphcmJpdHJhcnlUcmFuc2Zvcm1NYXNrKFNwbGFzaEltYWdlTWFza1NvdXJjZSBzcmMsIHZvaWQgKnNyY0RhdGEsCgkJCQkgICAgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkJICAgIFNwbGFzaENvb3JkICptYXQsIEdCb29sIGdseXBoTW9kZSkgewogIFNwbGFzaEJpdG1hcCAqc2NhbGVkTWFzazsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXMsIGNsaXBSZXMyOwogIFNwbGFzaFBpcGUgcGlwZTsKICBpbnQgc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCwgdDAsIHQxOwogIFNwbGFzaENvb3JkIHIwMCwgcjAxLCByMTAsIHIxMSwgZGV0LCBpcjAwLCBpcjAxLCBpcjEwLCBpcjExOwogIFNwbGFzaENvb3JkIHZ4WzRdLCB2eVs0XTsKICBpbnQgeE1pbiwgeU1pbiwgeE1heCwgeU1heDsKICBJbWFnZVNlY3Rpb24gc2VjdGlvblszXTsKICBpbnQgblNlY3Rpb25zOwogIGludCB5LCB4YSwgeGIsIHgsIGksIHh4LCB5eTsKCiAgLy8gY29tcHV0ZSB0aGUgZm91ciB2ZXJ0aWNlcyBvZiB0aGUgdGFyZ2V0IHF1YWRyaWxhdGVyYWwKICB2eFswXSA9IG1hdFs0XTsgICAgICAgICAgICAgICAgICAgIHZ5WzBdID0gbWF0WzVdOwogIHZ4WzFdID0gbWF0WzJdICsgbWF0WzRdOyAgICAgICAgICAgdnlbMV0gPSBtYXRbM10gKyBtYXRbNV07CiAgdnhbMl0gPSBtYXRbMF0gKyBtYXRbMl0gKyBtYXRbNF07ICB2eVsyXSA9IG1hdFsxXSArIG1hdFszXSArIG1hdFs1XTsKICB2eFszXSA9IG1hdFswXSArIG1hdFs0XTsgICAgICAgICAgIHZ5WzNdID0gbWF0WzFdICsgbWF0WzVdOwoKICAvLyBjbGlwcGluZwogIHhNaW4gPSBpbWdDb29yZE11bmdlTG93ZXJDKHZ4WzBdLCBnbHlwaE1vZGUpOwogIHhNYXggPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ4WzBdLCBnbHlwaE1vZGUpOwogIHlNaW4gPSBpbWdDb29yZE11bmdlTG93ZXJDKHZ5WzBdLCBnbHlwaE1vZGUpOwogIHlNYXggPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ5WzBdLCBnbHlwaE1vZGUpOwogIGZvciAoaSA9IDE7IGkgPCA0OyArK2kpIHsKICAgIHQwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyh2eFtpXSwgZ2x5cGhNb2RlKTsKICAgIGlmICh0MCA8IHhNaW4pIHsKICAgICAgeE1pbiA9IHQwOwogICAgfQogICAgdDAgPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ4W2ldLCBnbHlwaE1vZGUpOwogICAgaWYgKHQwID4geE1heCkgewogICAgICB4TWF4ID0gdDA7CiAgICB9CiAgICB0MSA9IGltZ0Nvb3JkTXVuZ2VMb3dlckModnlbaV0sIGdseXBoTW9kZSk7CiAgICBpZiAodDEgPCB5TWluKSB7CiAgICAgIHlNaW4gPSB0MTsKICAgIH0KICAgIHQxID0gaW1nQ29vcmRNdW5nZVVwcGVyQyh2eVtpXSwgZ2x5cGhNb2RlKTsKICAgIGlmICh0MSA+IHlNYXgpIHsKICAgICAgeU1heCA9IHQxOwogICAgfQogIH0KICBjbGlwUmVzID0gc3RhdGUtPmNsaXAtPnRlc3RSZWN0KHhNaW4sIHlNaW4sIHhNYXggLSAxLCB5TWF4IC0gMSk7CiAgb3BDbGlwUmVzID0gY2xpcFJlczsKICBpZiAoY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsT3V0c2lkZSkgewogICAgcmV0dXJuOwogIH0KCiAgLy8gY29tcHV0ZSB0aGUgc2NhbGUgZmFjdG9ycwogIGlmIChtYXRbMF0gPj0gMCkgewogICAgdDAgPSBpbWdDb29yZE11bmdlVXBwZXJDKG1hdFswXSArIG1hdFs0XSwgZ2x5cGhNb2RlKSAtCiAgICAgICAgIGltZ0Nvb3JkTXVuZ2VMb3dlckMobWF0WzRdLCBnbHlwaE1vZGUpOwogIH0gZWxzZSB7CiAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlckMobWF0WzRdLCBnbHlwaE1vZGUpIC0KICAgICAgICAgaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbMF0gKyBtYXRbNF0sIGdseXBoTW9kZSk7CiAgfQogIGlmIChtYXRbMV0gPj0gMCkgewogICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXJDKG1hdFsxXSArIG1hdFs1XSwgZ2x5cGhNb2RlKSAtCiAgICAgICAgIGltZ0Nvb3JkTXVuZ2VMb3dlckMobWF0WzVdLCBnbHlwaE1vZGUpOwogIH0gZWxzZSB7CiAgICB0MSA9IGltZ0Nvb3JkTXVuZ2VVcHBlckMobWF0WzVdLCBnbHlwaE1vZGUpIC0KICAgICAgICAgaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbMV0gKyBtYXRbNV0sIGdseXBoTW9kZSk7CiAgfQogIHNjYWxlZFdpZHRoID0gdDAgPiB0MSA/IHQwIDogdDE7CiAgaWYgKG1hdFsyXSA+PSAwKSB7CiAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlckMobWF0WzJdICsgbWF0WzRdLCBnbHlwaE1vZGUpIC0KICAgICAgICAgaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbNF0sIGdseXBoTW9kZSk7CiAgfSBlbHNlIHsKICAgIHQwID0gaW1nQ29vcmRNdW5nZVVwcGVyQyhtYXRbNF0sIGdseXBoTW9kZSkgLQogICAgICAgICBpbWdDb29yZE11bmdlTG93ZXJDKG1hdFsyXSArIG1hdFs0XSwgZ2x5cGhNb2RlKTsKICB9CiAgaWYgKG1hdFszXSA+PSAwKSB7CiAgICB0MSA9IGltZ0Nvb3JkTXVuZ2VVcHBlckMobWF0WzNdICsgbWF0WzVdLCBnbHlwaE1vZGUpIC0KICAgICAgICAgaW1nQ29vcmRNdW5nZUxvd2VyQyhtYXRbNV0sIGdseXBoTW9kZSk7CiAgfSBlbHNlIHsKICAgIHQxID0gaW1nQ29vcmRNdW5nZVVwcGVyQyhtYXRbNV0sIGdseXBoTW9kZSkgLQogICAgICAgICBpbWdDb29yZE11bmdlTG93ZXJDKG1hdFszXSArIG1hdFs1XSwgZ2x5cGhNb2RlKTsKICB9CiAgc2NhbGVkSGVpZ2h0ID0gdDAgPiB0MSA/IHQwIDogdDE7CiAgaWYgKHNjYWxlZFdpZHRoID09IDApIHsKICAgIHNjYWxlZFdpZHRoID0gMTsKICB9CiAgaWYgKHNjYWxlZEhlaWdodCA9PSAwKSB7CiAgICBzY2FsZWRIZWlnaHQgPSAxOwogIH0KCiAgLy8gY29tcHV0ZSB0aGUgaW52ZXJzZSB0cmFuc2Zvcm0gKGFmdGVyIHNjYWxpbmcpIG1hdHJpeAogIHIwMCA9IG1hdFswXSAvIHNjYWxlZFdpZHRoOwogIHIwMSA9IG1hdFsxXSAvIHNjYWxlZFdpZHRoOwogIHIxMCA9IG1hdFsyXSAvIHNjYWxlZEhlaWdodDsKICByMTEgPSBtYXRbM10gLyBzY2FsZWRIZWlnaHQ7CiAgZGV0ID0gcjAwICogcjExIC0gcjAxICogcjEwOwogIGlmIChzcGxhc2hBYnMoZGV0KSA8IDFlLTYpIHsKICAgIC8vIHRoaXMgc2hvdWxkIGJlIGNhdWdodCBieSB0aGUgc2luZ3VsYXIgbWF0cml4IGNoZWNrIGluIGZpbGxJbWFnZU1hc2sKICAgIHJldHVybjsKICB9CiAgaXIwMCA9IHIxMSAvIGRldDsKICBpcjAxID0gLXIwMSAvIGRldDsKICBpcjEwID0gLXIxMCAvIGRldDsKICBpcjExID0gcjAwIC8gZGV0OwoKICAvLyBzY2FsZSB0aGUgaW5wdXQgaW1hZ2UKICBzY2FsZWRNYXNrID0gc2NhbGVNYXNrKHNyYywgc3JjRGF0YSwgc3JjV2lkdGgsIHNyY0hlaWdodCwKCQkJIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQpOwoKICAvLyBjb25zdHJ1Y3QgdGhlIHRocmVlIHNlY3Rpb25zCiAgaSA9ICh2eVsyXSA8PSB2eVszXSkgPyAyIDogMzsKICBpZiAodnlbMV0gPD0gdnlbaV0pIHsKICAgIGkgPSAxOwogIH0KICBpZiAodnlbMF0gPCB2eVtpXSB8fCAoaSAhPSAzICYmIHZ5WzBdID09IHZ5W2ldKSkgewogICAgaSA9IDA7CiAgfQogIGlmICh2eVtpXSA9PSB2eVsoaSsxKSAmIDNdKSB7CiAgICBzZWN0aW9uWzBdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyh2eVtpXSwgZ2x5cGhNb2RlKTsKICAgIHNlY3Rpb25bMF0ueTEgPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ5WyhpKzIpICYgM10sIGdseXBoTW9kZSkgLSAxOwogICAgaWYgKHZ4W2ldIDwgdnhbKGkrMSkgJiAzXSkgewogICAgICBzZWN0aW9uWzBdLmlhMCA9IGk7CiAgICAgIHNlY3Rpb25bMF0uaWExID0gKGkrMykgJiAzOwogICAgICBzZWN0aW9uWzBdLmliMCA9IChpKzEpICYgMzsKICAgICAgc2VjdGlvblswXS5pYjEgPSAoaSsyKSAmIDM7CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzBdLmlhMCA9IChpKzEpICYgMzsKICAgICAgc2VjdGlvblswXS5pYTEgPSAoaSsyKSAmIDM7CiAgICAgIHNlY3Rpb25bMF0uaWIwID0gaTsKICAgICAgc2VjdGlvblswXS5pYjEgPSAoaSszKSAmIDM7CiAgICB9CiAgICBuU2VjdGlvbnMgPSAxOwogIH0gZWxzZSB7CiAgICBzZWN0aW9uWzBdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyh2eVtpXSwgZ2x5cGhNb2RlKTsKICAgIHNlY3Rpb25bMl0ueTEgPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ5WyhpKzIpICYgM10sIGdseXBoTW9kZSkgLSAxOwogICAgc2VjdGlvblswXS5pYTAgPSBzZWN0aW9uWzBdLmliMCA9IGk7CiAgICBzZWN0aW9uWzJdLmlhMSA9IHNlY3Rpb25bMl0uaWIxID0gKGkrMikgJiAzOwogICAgaWYgKHZ4WyhpKzEpICYgM10gPCB2eFsoaSszKSAmIDNdKSB7CiAgICAgIHNlY3Rpb25bMF0uaWExID0gc2VjdGlvblsyXS5pYTAgPSAoaSsxKSAmIDM7CiAgICAgIHNlY3Rpb25bMF0uaWIxID0gc2VjdGlvblsyXS5pYjAgPSAoaSszKSAmIDM7CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzBdLmlhMSA9IHNlY3Rpb25bMl0uaWEwID0gKGkrMykgJiAzOwogICAgICBzZWN0aW9uWzBdLmliMSA9IHNlY3Rpb25bMl0uaWIwID0gKGkrMSkgJiAzOwogICAgfQogICAgaWYgKHZ5WyhpKzEpICYgM10gPCB2eVsoaSszKSAmIDNdKSB7CiAgICAgIHNlY3Rpb25bMV0ueTAgPSBpbWdDb29yZE11bmdlTG93ZXJDKHZ5WyhpKzEpICYgM10sIGdseXBoTW9kZSk7CiAgICAgIHNlY3Rpb25bMl0ueTAgPSBpbWdDb29yZE11bmdlVXBwZXJDKHZ5WyhpKzMpICYgM10sIGdseXBoTW9kZSk7CiAgICAgIGlmICh2eFsoaSsxKSAmIDNdIDwgdnhbKGkrMykgJiAzXSkgewoJc2VjdGlvblsxXS5pYTAgPSAoaSsxKSAmIDM7CglzZWN0aW9uWzFdLmlhMSA9IChpKzIpICYgMzsKCXNlY3Rpb25bMV0uaWIwID0gaTsKCXNlY3Rpb25bMV0uaWIxID0gKGkrMykgJiAzOwogICAgICB9IGVsc2UgewoJc2VjdGlvblsxXS5pYTAgPSBpOwoJc2VjdGlvblsxXS5pYTEgPSAoaSszKSAmIDM7CglzZWN0aW9uWzFdLmliMCA9IChpKzEpICYgMzsKCXNlY3Rpb25bMV0uaWIxID0gKGkrMikgJiAzOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzFdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyQyh2eVsoaSszKSAmIDNdLCBnbHlwaE1vZGUpOwogICAgICBzZWN0aW9uWzJdLnkwID0gaW1nQ29vcmRNdW5nZVVwcGVyQyh2eVsoaSsxKSAmIDNdLCBnbHlwaE1vZGUpOwogICAgICBpZiAodnhbKGkrMSkgJiAzXSA8IHZ4WyhpKzMpICYgM10pIHsKCXNlY3Rpb25bMV0uaWEwID0gaTsKCXNlY3Rpb25bMV0uaWExID0gKGkrMSkgJiAzOwoJc2VjdGlvblsxXS5pYjAgPSAoaSszKSAmIDM7CglzZWN0aW9uWzFdLmliMSA9IChpKzIpICYgMzsKICAgICAgfSBlbHNlIHsKCXNlY3Rpb25bMV0uaWEwID0gKGkrMykgJiAzOwoJc2VjdGlvblsxXS5pYTEgPSAoaSsyKSAmIDM7CglzZWN0aW9uWzFdLmliMCA9IGk7CglzZWN0aW9uWzFdLmliMSA9IChpKzEpICYgMzsKICAgICAgfQogICAgfQogICAgc2VjdGlvblswXS55MSA9IHNlY3Rpb25bMV0ueTAgLSAxOwogICAgc2VjdGlvblsxXS55MSA9IHNlY3Rpb25bMl0ueTAgLSAxOwogICAgblNlY3Rpb25zID0gMzsKICB9CiAgZm9yIChpID0gMDsgaSA8IG5TZWN0aW9uczsgKytpKSB7CiAgICBzZWN0aW9uW2ldLnhhMCA9IHZ4W3NlY3Rpb25baV0uaWEwXTsKICAgIHNlY3Rpb25baV0ueWEwID0gdnlbc2VjdGlvbltpXS5pYTBdOwogICAgc2VjdGlvbltpXS54YTEgPSB2eFtzZWN0aW9uW2ldLmlhMV07CiAgICBzZWN0aW9uW2ldLnlhMSA9IHZ5W3NlY3Rpb25baV0uaWExXTsKICAgIHNlY3Rpb25baV0ueGIwID0gdnhbc2VjdGlvbltpXS5pYjBdOwogICAgc2VjdGlvbltpXS55YjAgPSB2eVtzZWN0aW9uW2ldLmliMF07CiAgICBzZWN0aW9uW2ldLnhiMSA9IHZ4W3NlY3Rpb25baV0uaWIxXTsKICAgIHNlY3Rpb25baV0ueWIxID0gdnlbc2VjdGlvbltpXS5pYjFdOwogICAgc2VjdGlvbltpXS5keGR5YSA9IChzZWN0aW9uW2ldLnhhMSAtIHNlY3Rpb25baV0ueGEwKSAvCiAgICAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb25baV0ueWExIC0gc2VjdGlvbltpXS55YTApOwogICAgc2VjdGlvbltpXS5keGR5YiA9IChzZWN0aW9uW2ldLnhiMSAtIHNlY3Rpb25baV0ueGIwKSAvCiAgICAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb25baV0ueWIxIC0gc2VjdGlvbltpXS55YjApOwogIH0KCiAgLy8gaW5pdGlhbGl6ZSB0aGUgcGl4ZWwgcGlwZQogIHBpcGVJbml0KCZwaXBlLCAwLCAwLCBzdGF0ZS0+ZmlsbFBhdHRlcm4sIE5VTEwsCgkgICAoR3VjaGFyKXNwbGFzaFJvdW5kKHN0YXRlLT5maWxsQWxwaGEgKiAyNTUpLCBnVHJ1ZSwgZ0ZhbHNlKTsKICBpZiAodmVjdG9yQW50aWFsaWFzKSB7CiAgICBkcmF3QUFQaXhlbEluaXQoKTsKICB9CgogIC8vIG1ha2Ugc3VyZSBuYXJyb3cgaW1hZ2VzIGNvdmVyIGF0IGxlYXN0IG9uZSBwaXhlbAogIGlmIChuU2VjdGlvbnMgPT0gMSkgewogICAgaWYgKHNlY3Rpb25bMF0ueTAgPT0gc2VjdGlvblswXS55MSkgewogICAgICArK3NlY3Rpb25bMF0ueTE7CiAgICAgIGNsaXBSZXMgPSBvcENsaXBSZXMgPSBzcGxhc2hDbGlwUGFydGlhbDsKICAgIH0KICB9IGVsc2UgewogICAgaWYgKHNlY3Rpb25bMF0ueTAgPT0gc2VjdGlvblsyXS55MSkgewogICAgICArK3NlY3Rpb25bMV0ueTE7CiAgICAgIGNsaXBSZXMgPSBvcENsaXBSZXMgPSBzcGxhc2hDbGlwUGFydGlhbDsKICAgIH0KICB9CgogIC8vIHNjYW4gYWxsIHBpeGVscyBpbnNpZGUgdGhlIHRhcmdldCByZWdpb24KICBmb3IgKGkgPSAwOyBpIDwgblNlY3Rpb25zOyArK2kpIHsKICAgIGZvciAoeSA9IHNlY3Rpb25baV0ueTA7IHkgPD0gc2VjdGlvbltpXS55MTsgKyt5KSB7CiAgICAgIHhhID0gaW1nQ29vcmRNdW5nZUxvd2VyQyhzZWN0aW9uW2ldLnhhMCArCgkJCSAgICAgICAgICgoU3BsYXNoQ29vcmQpeSArIDAuNSAtIHNlY3Rpb25baV0ueWEwKSAqCgkJCSAgICAgICAgICAgc2VjdGlvbltpXS5keGR5YSwKCQkJICAgICAgIGdseXBoTW9kZSk7CiAgICAgIHhiID0gaW1nQ29vcmRNdW5nZVVwcGVyQyhzZWN0aW9uW2ldLnhiMCArCgkJCSAgICAgICAgICgoU3BsYXNoQ29vcmQpeSArIDAuNSAtIHNlY3Rpb25baV0ueWIwKSAqCgkJCSAgICAgICAgICAgc2VjdGlvbltpXS5keGR5YiwKCQkJICAgICAgIGdseXBoTW9kZSk7CiAgICAgIC8vIG1ha2Ugc3VyZSBuYXJyb3cgaW1hZ2VzIGNvdmVyIGF0IGxlYXN0IG9uZSBwaXhlbAogICAgICBpZiAoeGEgPT0geGIpIHsKCSsreGI7CiAgICAgIH0KICAgICAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbEluc2lkZSkgewoJY2xpcFJlczIgPSBzdGF0ZS0+Y2xpcC0+dGVzdFNwYW4oeGEsIHhiIC0gMSwgeSk7CiAgICAgIH0gZWxzZSB7CgljbGlwUmVzMiA9IGNsaXBSZXM7CiAgICAgIH0KICAgICAgZm9yICh4ID0geGE7IHggPCB4YjsgKyt4KSB7CgkvLyBtYXAgKHgrMC41LCB5KzAuNSkgYmFjayB0byB0aGUgc2NhbGVkIGltYWdlCgl4eCA9IHNwbGFzaEZsb29yKCgoU3BsYXNoQ29vcmQpeCArIDAuNSAtIG1hdFs0XSkgKiBpcjAwICsKCQkJICgoU3BsYXNoQ29vcmQpeSArIDAuNSAtIG1hdFs1XSkgKiBpcjEwKTsKCXl5ID0gc3BsYXNoRmxvb3IoKChTcGxhc2hDb29yZCl4ICsgMC41IC0gbWF0WzRdKSAqIGlyMDEgKwoJCQkgKChTcGxhc2hDb29yZCl5ICsgMC41IC0gbWF0WzVdKSAqIGlyMTEpOwoJLy8geHggc2hvdWxkIGFsd2F5cyBiZSB3aXRoaW4gYm91bmRzLCBidXQgZmxvYXRpbmcgcG9pbnQKCS8vIGluYWNjdXJhY3kgY2FuIGNhdXNlIHByb2JsZW1zCglpZiAoeHggPCAwKSB7CgkgIHh4ID0gMDsKCX0gZWxzZSBpZiAoeHggPj0gc2NhbGVkV2lkdGgpIHsKCSAgeHggPSBzY2FsZWRXaWR0aCAtIDE7Cgl9CglpZiAoeXkgPCAwKSB7CgkgIHl5ID0gMDsKCX0gZWxzZSBpZiAoeXkgPj0gc2NhbGVkSGVpZ2h0KSB7CgkgIHl5ID0gc2NhbGVkSGVpZ2h0IC0gMTsKCX0KCXBpcGUuc2hhcGUgPSBzY2FsZWRNYXNrLT5kYXRhW3l5ICogc2NhbGVkV2lkdGggKyB4eF07CglpZiAodmVjdG9yQW50aWFsaWFzICYmIGNsaXBSZXMyICE9IHNwbGFzaENsaXBBbGxJbnNpZGUpIHsKCSAgZHJhd0FBUGl4ZWwoJnBpcGUsIHgsIHkpOwoJfSBlbHNlIHsKCSAgZHJhd1BpeGVsKCZwaXBlLCB4LCB5LCBjbGlwUmVzMiA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKTsKCX0KICAgICAgfQogICAgfQogIH0KCiAgZGVsZXRlIHNjYWxlZE1hc2s7Cn0KCi8vIFNjYWxlIGFuIGltYWdlIG1hc2sgaW50byBhIFNwbGFzaEJpdG1hcC4KU3BsYXNoQml0bWFwICpTcGxhc2g6OnNjYWxlTWFzayhTcGxhc2hJbWFnZU1hc2tTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkJaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkJaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0KSB7CiAgU3BsYXNoQml0bWFwICpkZXN0OwoKICBkZXN0ID0gbmV3IFNwbGFzaEJpdG1hcChzY2FsZWRXaWR0aCwgc2NhbGVkSGVpZ2h0LCAxLCBzcGxhc2hNb2RlTW9ubzgsCgkJCSAgZ0ZhbHNlKTsKICBpZiAoc2NhbGVkSGVpZ2h0IDwgc3JjSGVpZ2h0KSB7CiAgICBpZiAoc2NhbGVkV2lkdGggPCBzcmNXaWR0aCkgewogICAgICBzY2FsZU1hc2tZZFhkKHNyYywgc3JjRGF0YSwgc3JjV2lkdGgsIHNyY0hlaWdodCwKCQkgICAgc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCwgZGVzdCk7CiAgICB9IGVsc2UgewogICAgICBzY2FsZU1hc2tZZFh1KHNyYywgc3JjRGF0YSwgc3JjV2lkdGgsIHNyY0hlaWdodCwKCQkgICAgc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCwgZGVzdCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGlmIChzY2FsZWRXaWR0aCA8IHNyY1dpZHRoKSB7CiAgICAgIHNjYWxlTWFza1l1WGQoc3JjLCBzcmNEYXRhLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LAoJCSAgICBzY2FsZWRXaWR0aCwgc2NhbGVkSGVpZ2h0LCBkZXN0KTsKICAgIH0gZWxzZSB7CiAgICAgIHNjYWxlTWFza1l1WHUoc3JjLCBzcmNEYXRhLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LAoJCSAgICBzY2FsZWRXaWR0aCwgc2NhbGVkSGVpZ2h0LCBkZXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGRlc3Q7Cn0KCnZvaWQgU3BsYXNoOjpzY2FsZU1hc2tZZFhkKFNwbGFzaEltYWdlTWFza1NvdXJjZSBzcmMsIHZvaWQgKnNyY0RhdGEsCgkJCSAgIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwKCQkJICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICBTcGxhc2hCaXRtYXAgKmRlc3QpIHsKICBHdWNoYXIgKmxpbmVCdWY7CiAgR3VpbnQgKnBpeEJ1ZjsKICBHdWludCBwaXg7CiAgR3VjaGFyICpkZXN0UHRyOwogIGludCB5cCwgeXEsIHhwLCB4cSwgeXQsIHksIHlTdGVwLCB4dCwgeCwgeFN0ZXAsIHh4LCBkLCBkMCwgZDE7CiAgaW50IGksIGo7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB5IHNjYWxlCiAgeXAgPSBzcmNIZWlnaHQgLyBzY2FsZWRIZWlnaHQ7CiAgeXEgPSBzcmNIZWlnaHQgJSBzY2FsZWRIZWlnaHQ7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB4IHNjYWxlCiAgeHAgPSBzcmNXaWR0aCAvIHNjYWxlZFdpZHRoOwogIHhxID0gc3JjV2lkdGggJSBzY2FsZWRXaWR0aDsKCiAgLy8gYWxsb2NhdGUgYnVmZmVycwogIGxpbmVCdWYgPSAoR3VjaGFyICopZ21hbGxvYyhzcmNXaWR0aCk7CiAgcGl4QnVmID0gKEd1aW50ICopZ21hbGxvY24oc3JjV2lkdGgsIHNpemVvZihpbnQpKTsKCiAgLy8gaW5pdCB5IHNjYWxlIEJyZXNlbmhhbQogIHl0ID0gMDsKCiAgZGVzdFB0ciA9IGRlc3QtPmRhdGE7CiAgZm9yICh5ID0gMDsgeSA8IHNjYWxlZEhlaWdodDsgKyt5KSB7CgogICAgLy8geSBzY2FsZSBCcmVzZW5oYW0KICAgIGlmICgoeXQgKz0geXEpID49IHNjYWxlZEhlaWdodCkgewogICAgICB5dCAtPSBzY2FsZWRIZWlnaHQ7CiAgICAgIHlTdGVwID0geXAgKyAxOwogICAgfSBlbHNlIHsKICAgICAgeVN0ZXAgPSB5cDsKICAgIH0KCiAgICAvLyByZWFkIHJvd3MgZnJvbSBpbWFnZQogICAgbWVtc2V0KHBpeEJ1ZiwgMCwgc3JjV2lkdGggKiBzaXplb2YoaW50KSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewogICAgICAoKnNyYykoc3JjRGF0YSwgbGluZUJ1Zik7CiAgICAgIGZvciAoaiA9IDA7IGogPCBzcmNXaWR0aDsgKytqKSB7CglwaXhCdWZbal0gKz0gbGluZUJ1ZltqXTsKICAgICAgfQogICAgfQoKICAgIC8vIGluaXQgeCBzY2FsZSBCcmVzZW5oYW0KICAgIHh0ID0gMDsKICAgIGQwID0gKDI1NSA8PCAyMykgLyAoeVN0ZXAgKiB4cCk7CiAgICBkMSA9ICgyNTUgPDwgMjMpIC8gKHlTdGVwICogKHhwICsgMSkpOwoKICAgIHh4ID0gMDsKICAgIGZvciAoeCA9IDA7IHggPCBzY2FsZWRXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzY2FsZWRXaWR0aCkgewoJeHQgLT0gc2NhbGVkV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKCWQgPSBkMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CglkID0gZDA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIHBpeCA9IDA7CiAgICAgIGZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CglwaXggKz0gcGl4QnVmW3h4KytdOwogICAgICB9CiAgICAgIC8vICgyNTUgKiBwaXgpIC8geFN0ZXAgKiB5U3RlcAogICAgICBwaXggPSAocGl4ICogZCkgPj4gMjM7CgogICAgICAvLyBzdG9yZSB0aGUgcGl4ZWwKICAgICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4OwogICAgfQogIH0KCiAgZ2ZyZWUocGl4QnVmKTsKICBnZnJlZShsaW5lQnVmKTsKfQoKdm9pZCBTcGxhc2g6OnNjYWxlTWFza1lkWHUoU3BsYXNoSW1hZ2VNYXNrU291cmNlIHNyYywgdm9pZCAqc3JjRGF0YSwKCQkJICAgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkgICBpbnQgc2NhbGVkV2lkdGgsIGludCBzY2FsZWRIZWlnaHQsCgkJCSAgIFNwbGFzaEJpdG1hcCAqZGVzdCkgewogIEd1Y2hhciAqbGluZUJ1ZjsKICBHdWludCAqcGl4QnVmOwogIEd1aW50IHBpeDsKICBHdWNoYXIgKmRlc3RQdHI7CiAgaW50IHlwLCB5cSwgeHAsIHhxLCB5dCwgeSwgeVN0ZXAsIHh0LCB4LCB4U3RlcCwgZDsKICBpbnQgaSwgajsKCiAgLy8gQnJlc2VuaGFtIHBhcmFtZXRlcnMgZm9yIHkgc2NhbGUKICB5cCA9IHNyY0hlaWdodCAvIHNjYWxlZEhlaWdodDsKICB5cSA9IHNyY0hlaWdodCAlIHNjYWxlZEhlaWdodDsKCiAgLy8gQnJlc2VuaGFtIHBhcmFtZXRlcnMgZm9yIHggc2NhbGUKICB4cCA9IHNjYWxlZFdpZHRoIC8gc3JjV2lkdGg7CiAgeHEgPSBzY2FsZWRXaWR0aCAlIHNyY1dpZHRoOwoKICAvLyBhbGxvY2F0ZSBidWZmZXJzCiAgbGluZUJ1ZiA9IChHdWNoYXIgKilnbWFsbG9jKHNyY1dpZHRoKTsKICBwaXhCdWYgPSAoR3VpbnQgKilnbWFsbG9jbihzcmNXaWR0aCwgc2l6ZW9mKGludCkpOwoKICAvLyBpbml0IHkgc2NhbGUgQnJlc2VuaGFtCiAgeXQgPSAwOwoKICBkZXN0UHRyID0gZGVzdC0+ZGF0YTsKICBmb3IgKHkgPSAwOyB5IDwgc2NhbGVkSGVpZ2h0OyArK3kpIHsKCiAgICAvLyB5IHNjYWxlIEJyZXNlbmhhbQogICAgaWYgKCh5dCArPSB5cSkgPj0gc2NhbGVkSGVpZ2h0KSB7CiAgICAgIHl0IC09IHNjYWxlZEhlaWdodDsKICAgICAgeVN0ZXAgPSB5cCArIDE7CiAgICB9IGVsc2UgewogICAgICB5U3RlcCA9IHlwOwogICAgfQoKICAgIC8vIHJlYWQgcm93cyBmcm9tIGltYWdlCiAgICBtZW1zZXQocGl4QnVmLCAwLCBzcmNXaWR0aCAqIHNpemVvZihpbnQpKTsKICAgIGZvciAoaSA9IDA7IGkgPCB5U3RlcDsgKytpKSB7CiAgICAgICgqc3JjKShzcmNEYXRhLCBsaW5lQnVmKTsKICAgICAgZm9yIChqID0gMDsgaiA8IHNyY1dpZHRoOyArK2opIHsKCXBpeEJ1ZltqXSArPSBsaW5lQnVmW2pdOwogICAgICB9CiAgICB9CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwogICAgZCA9ICgyNTUgPDwgMjMpIC8geVN0ZXA7CgogICAgZm9yICh4ID0gMDsgeCA8IHNyY1dpZHRoOyArK3gpIHsKCiAgICAgIC8vIHggc2NhbGUgQnJlc2VuaGFtCiAgICAgIGlmICgoeHQgKz0geHEpID49IHNyY1dpZHRoKSB7Cgl4dCAtPSBzcmNXaWR0aDsKCXhTdGVwID0geHAgKyAxOwogICAgICB9IGVsc2UgewoJeFN0ZXAgPSB4cDsKICAgICAgfQoKICAgICAgLy8gY29tcHV0ZSB0aGUgZmluYWwgcGl4ZWwKICAgICAgcGl4ID0gcGl4QnVmW3hdOwogICAgICAvLyAoMjU1ICogcGl4KSAvIHlTdGVwCiAgICAgIHBpeCA9IChwaXggKiBkKSA+PiAyMzsKCiAgICAgIC8vIHN0b3JlIHRoZSBwaXhlbAogICAgICBmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4OwogICAgICB9CiAgICB9CiAgfQoKICBnZnJlZShwaXhCdWYpOwogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6c2NhbGVNYXNrWXVYZChTcGxhc2hJbWFnZU1hc2tTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkgICBpbnQgc3JjV2lkdGgsIGludCBzcmNIZWlnaHQsCgkJCSAgIGludCBzY2FsZWRXaWR0aCwgaW50IHNjYWxlZEhlaWdodCwKCQkJICAgU3BsYXNoQml0bWFwICpkZXN0KSB7CiAgR3VjaGFyICpsaW5lQnVmOwogIEd1aW50IHBpeDsKICBHdWNoYXIgKmRlc3RQdHIwLCAqZGVzdFB0cjsKICBpbnQgeXAsIHlxLCB4cCwgeHEsIHl0LCB5LCB5U3RlcCwgeHQsIHgsIHhTdGVwLCB4eCwgZCwgZDAsIGQxOwogIGludCBpOwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeSBzY2FsZQogIHlwID0gc2NhbGVkSGVpZ2h0IC8gc3JjSGVpZ2h0OwogIHlxID0gc2NhbGVkSGVpZ2h0ICUgc3JjSGVpZ2h0OwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeCBzY2FsZQogIHhwID0gc3JjV2lkdGggLyBzY2FsZWRXaWR0aDsKICB4cSA9IHNyY1dpZHRoICUgc2NhbGVkV2lkdGg7CgogIC8vIGFsbG9jYXRlIGJ1ZmZlcnMKICBsaW5lQnVmID0gKEd1Y2hhciAqKWdtYWxsb2Moc3JjV2lkdGgpOwoKICAvLyBpbml0IHkgc2NhbGUgQnJlc2VuaGFtCiAgeXQgPSAwOwoKICBkZXN0UHRyMCA9IGRlc3QtPmRhdGE7CiAgZm9yICh5ID0gMDsgeSA8IHNyY0hlaWdodDsgKyt5KSB7CgogICAgLy8geSBzY2FsZSBCcmVzZW5oYW0KICAgIGlmICgoeXQgKz0geXEpID49IHNyY0hlaWdodCkgewogICAgICB5dCAtPSBzcmNIZWlnaHQ7CiAgICAgIHlTdGVwID0geXAgKyAxOwogICAgfSBlbHNlIHsKICAgICAgeVN0ZXAgPSB5cDsKICAgIH0KCiAgICAvLyByZWFkIHJvdyBmcm9tIGltYWdlCiAgICAoKnNyYykoc3JjRGF0YSwgbGluZUJ1Zik7CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwogICAgZDAgPSAoMjU1IDw8IDIzKSAvIHhwOwogICAgZDEgPSAoMjU1IDw8IDIzKSAvICh4cCArIDEpOwoKICAgIHh4ID0gMDsKICAgIGZvciAoeCA9IDA7IHggPCBzY2FsZWRXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzY2FsZWRXaWR0aCkgewoJeHQgLT0gc2NhbGVkV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKCWQgPSBkMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CglkID0gZDA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIHBpeCA9IDA7CiAgICAgIGZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CglwaXggKz0gbGluZUJ1Zlt4eCsrXTsKICAgICAgfQogICAgICAvLyAoMjU1ICogcGl4KSAvIHhTdGVwCiAgICAgIHBpeCA9IChwaXggKiBkKSA+PiAyMzsKCiAgICAgIC8vIHN0b3JlIHRoZSBwaXhlbAogICAgICBmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJZGVzdFB0ciA9IGRlc3RQdHIwICsgaSAqIHNjYWxlZFdpZHRoICsgeDsKCSpkZXN0UHRyID0gKEd1Y2hhcilwaXg7CiAgICAgIH0KICAgIH0KCiAgICBkZXN0UHRyMCArPSB5U3RlcCAqIHNjYWxlZFdpZHRoOwogIH0KCiAgZ2ZyZWUobGluZUJ1Zik7Cn0KCnZvaWQgU3BsYXNoOjpzY2FsZU1hc2tZdVh1KFNwbGFzaEltYWdlTWFza1NvdXJjZSBzcmMsIHZvaWQgKnNyY0RhdGEsCgkJCSAgIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwKCQkJICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICBTcGxhc2hCaXRtYXAgKmRlc3QpIHsKICBHdWNoYXIgKmxpbmVCdWY7CiAgR3VpbnQgcGl4OwogIEd1Y2hhciAqZGVzdFB0cjAsICpkZXN0UHRyOwogIGludCB5cCwgeXEsIHhwLCB4cSwgeXQsIHksIHlTdGVwLCB4dCwgeCwgeFN0ZXAsIHh4OwogIGludCBpLCBqOwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeSBzY2FsZQogIHlwID0gc2NhbGVkSGVpZ2h0IC8gc3JjSGVpZ2h0OwogIHlxID0gc2NhbGVkSGVpZ2h0ICUgc3JjSGVpZ2h0OwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeCBzY2FsZQogIHhwID0gc2NhbGVkV2lkdGggLyBzcmNXaWR0aDsKICB4cSA9IHNjYWxlZFdpZHRoICUgc3JjV2lkdGg7CgogIC8vIGFsbG9jYXRlIGJ1ZmZlcnMKICBsaW5lQnVmID0gKEd1Y2hhciAqKWdtYWxsb2Moc3JjV2lkdGgpOwoKICAvLyBpbml0IHkgc2NhbGUgQnJlc2VuaGFtCiAgeXQgPSAwOwoKICBkZXN0UHRyMCA9IGRlc3QtPmRhdGE7CiAgZm9yICh5ID0gMDsgeSA8IHNyY0hlaWdodDsgKyt5KSB7CgogICAgLy8geSBzY2FsZSBCcmVzZW5oYW0KICAgIGlmICgoeXQgKz0geXEpID49IHNyY0hlaWdodCkgewogICAgICB5dCAtPSBzcmNIZWlnaHQ7CiAgICAgIHlTdGVwID0geXAgKyAxOwogICAgfSBlbHNlIHsKICAgICAgeVN0ZXAgPSB5cDsKICAgIH0KCiAgICAvLyByZWFkIHJvdyBmcm9tIGltYWdlCiAgICAoKnNyYykoc3JjRGF0YSwgbGluZUJ1Zik7CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwoKICAgIHh4ID0gMDsKICAgIGZvciAoeCA9IDA7IHggPCBzcmNXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzcmNXaWR0aCkgewoJeHQgLT0gc3JjV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIHBpeCA9IGxpbmVCdWZbeF0gPyAyNTUgOiAwOwoKICAgICAgLy8gc3RvcmUgdGhlIHBpeGVsCiAgICAgIGZvciAoaSA9IDA7IGkgPCB5U3RlcDsgKytpKSB7Cglmb3IgKGogPSAwOyBqIDwgeFN0ZXA7ICsraikgewoJICBkZXN0UHRyID0gZGVzdFB0cjAgKyBpICogc2NhbGVkV2lkdGggKyB4eCArIGo7CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeDsKCX0KICAgICAgfQoKICAgICAgeHggKz0geFN0ZXA7CiAgICB9CgogICAgZGVzdFB0cjAgKz0geVN0ZXAgKiBzY2FsZWRXaWR0aDsKICB9CgogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6YmxpdE1hc2soU3BsYXNoQml0bWFwICpzcmMsIGludCB4RGVzdCwgaW50IHlEZXN0LAoJCSAgICAgIFNwbGFzaENsaXBSZXN1bHQgY2xpcFJlcykgewogIFNwbGFzaFBpcGUgcGlwZTsKICBHdWNoYXIgKnA7CiAgaW50IHcsIGgsIHgsIHk7CgogIHcgPSBzcmMtPmdldFdpZHRoKCk7CiAgaCA9IHNyYy0+Z2V0SGVpZ2h0KCk7CiAgaWYgKHZlY3RvckFudGlhbGlhcyAmJiBjbGlwUmVzICE9IHNwbGFzaENsaXBBbGxJbnNpZGUpIHsKICAgIHBpcGVJbml0KCZwaXBlLCB4RGVzdCwgeURlc3QsIHN0YXRlLT5maWxsUGF0dGVybiwgTlVMTCwKCSAgICAgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ1RydWUsIGdGYWxzZSk7CiAgICBkcmF3QUFQaXhlbEluaXQoKTsKICAgIHAgPSBzcmMtPmdldERhdGFQdHIoKTsKICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKICAgICAgZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJcGlwZS5zaGFwZSA9ICpwKys7CglkcmF3QUFQaXhlbCgmcGlwZSwgeERlc3QgKyB4LCB5RGVzdCArIHkpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIHBpcGVJbml0KCZwaXBlLCB4RGVzdCwgeURlc3QsIHN0YXRlLT5maWxsUGF0dGVybiwgTlVMTCwKCSAgICAgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ1RydWUsIGdGYWxzZSk7CiAgICBwID0gc3JjLT5nZXREYXRhUHRyKCk7CiAgICBpZiAoY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKSB7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKCXBpcGVTZXRYWSgmcGlwZSwgeERlc3QsIHlEZXN0ICsgeSk7Cglmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CgkgIGlmICgqcCkgewoJICAgIHBpcGUuc2hhcGUgPSAqcDsKCSAgICAodGhpcy0+KnBpcGUucnVuKSgmcGlwZSk7CgkgIH0gZWxzZSB7CgkgICAgcGlwZUluY1goJnBpcGUpOwoJICB9CgkgICsrcDsKCX0KICAgICAgfQogICAgICB1cGRhdGVNb2RYKHhEZXN0KTsKICAgICAgdXBkYXRlTW9kWCh4RGVzdCArIHcgLSAxKTsKICAgICAgdXBkYXRlTW9kWSh5RGVzdCk7CiAgICAgIHVwZGF0ZU1vZFkoeURlc3QgKyBoIC0gMSk7CiAgICB9IGVsc2UgewogICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CglwaXBlU2V0WFkoJnBpcGUsIHhEZXN0LCB5RGVzdCArIHkpOwoJZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJICBpZiAoKnAgJiYgc3RhdGUtPmNsaXAtPnRlc3QoeERlc3QgKyB4LCB5RGVzdCArIHkpKSB7CgkgICAgcGlwZS5zaGFwZSA9ICpwOwoJICAgICh0aGlzLT4qcGlwZS5ydW4pKCZwaXBlKTsKCSAgICB1cGRhdGVNb2RYKHhEZXN0ICsgeCk7CgkgICAgdXBkYXRlTW9kWSh5RGVzdCArIHkpOwoJICB9IGVsc2UgewoJICAgIHBpcGVJbmNYKCZwaXBlKTsKCSAgfQoJICArK3A7Cgl9CiAgICAgIH0KICAgIH0KICB9Cn0KClNwbGFzaEVycm9yIFNwbGFzaDo6ZHJhd0ltYWdlKFNwbGFzaEltYWdlU291cmNlIHNyYywgdm9pZCAqc3JjRGF0YSwKCQkJICAgICAgU3BsYXNoQ29sb3JNb2RlIHNyY01vZGUsIEdCb29sIHNyY0FscGhhLAoJCQkgICAgICBpbnQgdywgaW50IGgsIFNwbGFzaENvb3JkICptYXQsCiAgICAgICAgICAgIEdCb29sIHRpbGluZ1BhdHRlcm4pIHsKICBHQm9vbCBvazsKICBTcGxhc2hCaXRtYXAgKnNjYWxlZEltZzsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXM7CiAgR0Jvb2wgbWlub3JBeGlzWmVybzsKICBpbnQgeDAsIHkwLCB4MSwgeTEsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQ7CiAgaW50IG5Db21wczsKICBpbnQgeXA7CgogIGlmIChkZWJ1Z01vZGUpIHsKICAgIHByaW50ZigiZHJhd0ltYWdlOiBzcmNNb2RlPSVkIHNyY0FscGhhPSVkIHc9JWQgaD0lZCBtYXQ9WyUuMmYgJS4yZiAlLjJmICUuMmYgJS4yZiAlLjJmXVxuIiwKCSAgIHNyY01vZGUsIHNyY0FscGhhLCB3LCBoLCAoZG91YmxlKW1hdFswXSwgKGRvdWJsZSltYXRbMV0sIChkb3VibGUpbWF0WzJdLAoJICAgKGRvdWJsZSltYXRbM10sIChkb3VibGUpbWF0WzRdLCAoZG91YmxlKW1hdFs1XSk7CiAgfQoKICAvLyBjaGVjayBjb2xvciBtb2RlcwogIG9rID0gZ0ZhbHNlOyAvLyBtYWtlIGdjYyBoYXBweQogIG5Db21wcyA9IDA7IC8vIG1ha2UgZ2NjIGhhcHB5CiAgc3dpdGNoIChiaXRtYXAtPm1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICBjYXNlIHNwbGFzaE1vZGVNb25vODoKICAgIG9rID0gc3JjTW9kZSA9PSBzcGxhc2hNb2RlTW9ubzg7CiAgICBuQ29tcHMgPSAxOwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgIG9rID0gc3JjTW9kZSA9PSBzcGxhc2hNb2RlUkdCODsKICAgIG5Db21wcyA9IDM7CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVYQkdSODoKICAgIG9rID0gc3JjTW9kZSA9PSBzcGxhc2hNb2RlWEJHUjg7CiAgICBuQ29tcHMgPSA0OwogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIG9rID0gc3JjTW9kZSA9PSBzcGxhc2hNb2RlQkdSODsKICAgIG5Db21wcyA9IDM7CiAgICBicmVhazsKI2lmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICBvayA9IHNyY01vZGUgPT0gc3BsYXNoTW9kZUNNWUs4OwogICAgbkNvbXBzID0gNDsKICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgogICAgb2sgPSBzcmNNb2RlID09IHNwbGFzaE1vZGVEZXZpY2VOODsKICAgIG5Db21wcyA9IFNQT1RfTkNPTVBTKzQ7CiAgICBicmVhazsKI2VuZGlmCiAgZGVmYXVsdDoKICAgIG9rID0gZ0ZhbHNlOwogICAgYnJlYWs7CiAgfQogIGlmICghb2spIHsKICAgIHJldHVybiBzcGxhc2hFcnJNb2RlTWlzbWF0Y2g7CiAgfQoKICAvLyBjaGVjayBmb3Igc2luZ3VsYXIgbWF0cml4CiAgaWYgKCFzcGxhc2hDaGVja0RldChtYXRbMF0sIG1hdFsxXSwgbWF0WzJdLCBtYXRbM10sIDAuMDAwMDAxKSkgewogICAgcmV0dXJuIHNwbGFzaEVyclNpbmd1bGFyTWF0cml4OwogIH0KCiAgbWlub3JBeGlzWmVybyA9IG1hdFsxXSA9PSAwICYmIG1hdFsyXSA9PSAwOwoKICAvLyBzY2FsaW5nIG9ubHkKICBpZiAobWF0WzBdID4gMCAmJiBtaW5vckF4aXNaZXJvICYmIG1hdFszXSA+IDApIHsKICAgIHgwID0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFs0XSk7CiAgICB5MCA9IGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbNV0pOwogICAgeDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzBdICsgbWF0WzRdKTsKICAgIHkxID0gaW1nQ29vcmRNdW5nZVVwcGVyKG1hdFszXSArIG1hdFs1XSk7CiAgICAvLyBtYWtlIHN1cmUgbmFycm93IGltYWdlcyBjb3ZlciBhdCBsZWFzdCBvbmUgcGl4ZWwKICAgIGlmICh4MCA9PSB4MSkgewogICAgICArK3gxOwogICAgfQogICAgaWYgKHkwID09IHkxKSB7CiAgICAgICsreTE7CiAgICB9CiAgICBjbGlwUmVzID0gc3RhdGUtPmNsaXAtPnRlc3RSZWN0KHgwLCB5MCwgeDEgLSAxLCB5MSAtIDEpOwogICAgb3BDbGlwUmVzID0gY2xpcFJlczsKICAgIGlmIChjbGlwUmVzICE9IHNwbGFzaENsaXBBbGxPdXRzaWRlKSB7CiAgICAgIHNjYWxlZFdpZHRoID0geDEgLSB4MDsKICAgICAgc2NhbGVkSGVpZ2h0ID0geTEgLSB5MDsKICAgICAgeXAgPSBoIC8gc2NhbGVkSGVpZ2h0OwogICAgICBpZiAoeXAgPCAwIHx8IHlwID4gSU5UX01BWCAtIDEpIHsKICAgICAgICByZXR1cm4gc3BsYXNoRXJyQmFkQXJnOwogICAgICB9CiAgICAgIHNjYWxlZEltZyA9IHNjYWxlSW1hZ2Uoc3JjLCBzcmNEYXRhLCBzcmNNb2RlLCBuQ29tcHMsIHNyY0FscGhhLCB3LCBoLAoJCQkgICAgIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQpOwogICAgICBpZiAoc2NhbGVkSW1nID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gc3BsYXNoRXJyQmFkQXJnOwogICAgICB9CiAgICAgIGJsaXRJbWFnZShzY2FsZWRJbWcsIHNyY0FscGhhLCB4MCwgeTAsIGNsaXBSZXMpOwogICAgICBkZWxldGUgc2NhbGVkSW1nOwogICAgfQoKICAvLyBzY2FsaW5nIHBsdXMgdmVydGljYWwgZmxpcAogIH0gZWxzZSBpZiAobWF0WzBdID4gMCAmJiBtaW5vckF4aXNaZXJvICYmIG1hdFszXSA8IDApIHsKICAgIHgwID0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFs0XSk7CiAgICB5MCA9IGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbM10gKyBtYXRbNV0pOwogICAgeDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzBdICsgbWF0WzRdKTsKICAgIHkxID0gaW1nQ29vcmRNdW5nZVVwcGVyKG1hdFs1XSk7CiAgICBpZiAoeDAgPT0geDEpIHsKICAgICAgaWYgKG1hdFs0XSArIG1hdFswXSAqIDAuNSA8IHgwKSB7CgktLXgwOwogICAgICB9IGVsc2UgewoJKyt4MTsKICAgICAgfQogICAgfQogICAgaWYgKHkwID09IHkxKSB7CiAgICAgIGlmIChtYXRbNV0gKyBtYXRbMV0gKiAwLjUgPCB5MCkgewoJLS15MDsKICAgICAgfSBlbHNlIHsKCSsreTE7CiAgICAgIH0KICAgIH0KICAgIGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeDAsIHkwLCB4MSAtIDEsIHkxIC0gMSk7CiAgICBvcENsaXBSZXMgPSBjbGlwUmVzOwogICAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbE91dHNpZGUpIHsKICAgICAgc2NhbGVkV2lkdGggPSB4MSAtIHgwOwogICAgICBzY2FsZWRIZWlnaHQgPSB5MSAtIHkwOwogICAgICB5cCA9IGggLyBzY2FsZWRIZWlnaHQ7CiAgICAgIGlmICh5cCA8IDAgfHwgeXAgPiBJTlRfTUFYIC0gMSkgewogICAgICAgIHJldHVybiBzcGxhc2hFcnJCYWRBcmc7CiAgICAgIH0KICAgICAgc2NhbGVkSW1nID0gc2NhbGVJbWFnZShzcmMsIHNyY0RhdGEsIHNyY01vZGUsIG5Db21wcywgc3JjQWxwaGEsIHcsIGgsCgkJCSAgICAgc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCk7CiAgICAgIGlmIChzY2FsZWRJbWcgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBzcGxhc2hFcnJCYWRBcmc7CiAgICAgIH0KICAgICAgdmVydEZsaXBJbWFnZShzY2FsZWRJbWcsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIG5Db21wcyk7CiAgICAgIGJsaXRJbWFnZShzY2FsZWRJbWcsIHNyY0FscGhhLCB4MCwgeTAsIGNsaXBSZXMpOwogICAgICBkZWxldGUgc2NhbGVkSW1nOwogICAgfQoKICAvLyBhbGwgb3RoZXIgY2FzZXMKICB9IGVsc2UgewogICAgcmV0dXJuIGFyYml0cmFyeVRyYW5zZm9ybUltYWdlKHNyYywgc3JjRGF0YSwgc3JjTW9kZSwgbkNvbXBzLCBzcmNBbHBoYSwKCQkJICAgIHcsIGgsIG1hdCwgdGlsaW5nUGF0dGVybik7CiAgfQoKICByZXR1cm4gc3BsYXNoT2s7Cn0KClNwbGFzaEVycm9yIFNwbGFzaDo6YXJiaXRyYXJ5VHJhbnNmb3JtSW1hZ2UoU3BsYXNoSW1hZ2VTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkJICAgICBTcGxhc2hDb2xvck1vZGUgc3JjTW9kZSwgaW50IG5Db21wcywKCQkJCSAgICAgR0Jvb2wgc3JjQWxwaGEsCgkJCQkgICAgIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwKCQkJCSAgICAgU3BsYXNoQ29vcmQgKm1hdCwKICAgICAgICAgICAgIEdCb29sIHRpbGluZ1BhdHRlcm4pIHsKICBTcGxhc2hCaXRtYXAgKnNjYWxlZEltZzsKICBTcGxhc2hDbGlwUmVzdWx0IGNsaXBSZXMsIGNsaXBSZXMyOwogIFNwbGFzaFBpcGUgcGlwZTsKICBTcGxhc2hDb2xvciBwaXhlbDsKICBpbnQgc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCwgdDAsIHQxLCB0aDsKICBTcGxhc2hDb29yZCByMDAsIHIwMSwgcjEwLCByMTEsIGRldCwgaXIwMCwgaXIwMSwgaXIxMCwgaXIxMTsKICBTcGxhc2hDb29yZCB2eFs0XSwgdnlbNF07CiAgaW50IHhNaW4sIHlNaW4sIHhNYXgsIHlNYXg7CiAgSW1hZ2VTZWN0aW9uIHNlY3Rpb25bM107CiAgaW50IG5TZWN0aW9uczsKICBpbnQgeSwgeGEsIHhiLCB4LCBpLCB4eCwgeXksIHlwOwoKICAvLyBjb21wdXRlIHRoZSBmb3VyIHZlcnRpY2VzIG9mIHRoZSB0YXJnZXQgcXVhZHJpbGF0ZXJhbAogIHZ4WzBdID0gbWF0WzRdOyAgICAgICAgICAgICAgICAgICAgdnlbMF0gPSBtYXRbNV07CiAgdnhbMV0gPSBtYXRbMl0gKyBtYXRbNF07ICAgICAgICAgICB2eVsxXSA9IG1hdFszXSArIG1hdFs1XTsKICB2eFsyXSA9IG1hdFswXSArIG1hdFsyXSArIG1hdFs0XTsgIHZ5WzJdID0gbWF0WzFdICsgbWF0WzNdICsgbWF0WzVdOwogIHZ4WzNdID0gbWF0WzBdICsgbWF0WzRdOyAgICAgICAgICAgdnlbM10gPSBtYXRbMV0gKyBtYXRbNV07CgogIC8vIGNsaXBwaW5nCiAgeE1pbiA9IGltZ0Nvb3JkTXVuZ2VMb3dlcih2eFswXSk7CiAgeE1heCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcih2eFswXSk7CiAgeU1pbiA9IGltZ0Nvb3JkTXVuZ2VMb3dlcih2eVswXSk7CiAgeU1heCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcih2eVswXSk7CiAgZm9yIChpID0gMTsgaSA8IDQ7ICsraSkgewogICAgdDAgPSBpbWdDb29yZE11bmdlTG93ZXIodnhbaV0pOwogICAgaWYgKHQwIDwgeE1pbikgewogICAgICB4TWluID0gdDA7CiAgICB9CiAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcih2eFtpXSk7CiAgICBpZiAodDAgPiB4TWF4KSB7CiAgICAgIHhNYXggPSB0MDsKICAgIH0KICAgIHQxID0gaW1nQ29vcmRNdW5nZUxvd2VyKHZ5W2ldKTsKICAgIGlmICh0MSA8IHlNaW4pIHsKICAgICAgeU1pbiA9IHQxOwogICAgfQogICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXIodnlbaV0pOwogICAgaWYgKHQxID4geU1heCkgewogICAgICB5TWF4ID0gdDE7CiAgICB9CiAgfQogIGNsaXBSZXMgPSBzdGF0ZS0+Y2xpcC0+dGVzdFJlY3QoeE1pbiwgeU1pbiwgeE1heCAtIDEsIHlNYXggLSAxKTsKICBvcENsaXBSZXMgPSBjbGlwUmVzOwogIGlmIChjbGlwUmVzID09IHNwbGFzaENsaXBBbGxPdXRzaWRlKSB7CiAgICByZXR1cm4gc3BsYXNoT2s7CiAgfQoKICAvLyBjb21wdXRlIHRoZSBzY2FsZSBmYWN0b3JzCiAgaWYgKHNwbGFzaEFicyhtYXRbMF0pID49IHNwbGFzaEFicyhtYXRbMV0pKSB7CiAgICBzY2FsZWRXaWR0aCA9IHhNYXggLSB4TWluOwogICAgc2NhbGVkSGVpZ2h0ID0geU1heCAtIHlNaW47CiAgfSBlbHNlIHsKICAgIHNjYWxlZFdpZHRoID0geU1heCAtIHlNaW47CiAgICBzY2FsZWRIZWlnaHQgPSB4TWF4IC0geE1pbjsKICB9CiAgaWYgKHNjYWxlZEhlaWdodCA8PSAxIHx8IHNjYWxlZEhlaWdodCA8PSAxIHx8IHRpbGluZ1BhdHRlcm4pIHsKICAgIGlmIChtYXRbMF0gPj0gMCkgewogICAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcihtYXRbMF0gKyBtYXRbNF0pIC0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFs0XSk7CiAgICB9IGVsc2UgewogICAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcihtYXRbNF0pIC0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFswXSArIG1hdFs0XSk7CiAgICB9CiAgICBpZiAobWF0WzFdID49IDApIHsKICAgICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzFdICsgbWF0WzVdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbNV0pOwogICAgfSBlbHNlIHsKICAgICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzVdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbMV0gKyBtYXRbNV0pOwogICAgfQogICAgc2NhbGVkV2lkdGggPSB0MCA+IHQxID8gdDAgOiB0MTsKICAgIGlmIChtYXRbMl0gPj0gMCkgewogICAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcihtYXRbMl0gKyBtYXRbNF0pIC0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFs0XSk7CiAgICAgIGlmIChzcGxhc2hBYnMobWF0WzFdKSA+PSAxKSB7CiAgICAgICAgdGggPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzJdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbMF0gKiBtYXRbM10gLyBtYXRbMV0pOwoJICAgIGlmICh0aCA+IHQwKSB0MCA9IHRoOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB0MCA9IGltZ0Nvb3JkTXVuZ2VVcHBlcihtYXRbNF0pIC0gaW1nQ29vcmRNdW5nZUxvd2VyKG1hdFsyXSArIG1hdFs0XSk7CiAgICAgIGlmIChzcGxhc2hBYnMobWF0WzFdKSA+PSAxKSB7CiAgICAgICAgdGggPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzBdICogbWF0WzNdIC8gbWF0WzFdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbMl0pOwogICAgICAgIGlmICh0aCA+IHQwKSB0MCA9IHRoOwogICAgICB9CiAgICB9CiAgICBpZiAobWF0WzNdID49IDApIHsKICAgICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzNdICsgbWF0WzVdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbNV0pOwogICAgICBpZiAoc3BsYXNoQWJzKG1hdFswXSkgPj0gMSkgewogICAgICAgIHRoID0gaW1nQ29vcmRNdW5nZVVwcGVyKG1hdFszXSkgLSBpbWdDb29yZE11bmdlTG93ZXIobWF0WzFdICogbWF0WzJdIC8gbWF0WzBdKTsKCSAgICBpZiAodGggPiB0MSkgdDEgPSB0aDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdDEgPSBpbWdDb29yZE11bmdlVXBwZXIobWF0WzVdKSAtIGltZ0Nvb3JkTXVuZ2VMb3dlcihtYXRbM10gKyBtYXRbNV0pOwogICAgICBpZiAoc3BsYXNoQWJzKG1hdFswXSkgPj0gMSkgewogICAgICAgIHRoID0gaW1nQ29vcmRNdW5nZVVwcGVyKG1hdFsxXSAqIG1hdFsyXSAvIG1hdFswXSkgLSBpbWdDb29yZE11bmdlTG93ZXIobWF0WzNdKTsKCSAgICBpZiAodGggPiB0MSkgdDEgPSB0aDsKICAgICAgfQogICAgfQogICAgc2NhbGVkSGVpZ2h0ID0gdDAgPiB0MSA/IHQwIDogdDE7CiAgfQogIGlmIChzY2FsZWRXaWR0aCA9PSAwKSB7CiAgICBzY2FsZWRXaWR0aCA9IDE7CiAgfQogIGlmIChzY2FsZWRIZWlnaHQgPT0gMCkgewogICAgc2NhbGVkSGVpZ2h0ID0gMTsKICB9CgogIC8vIGNvbXB1dGUgdGhlIGludmVyc2UgdHJhbnNmb3JtIChhZnRlciBzY2FsaW5nKSBtYXRyaXgKICByMDAgPSBtYXRbMF0gLyBzY2FsZWRXaWR0aDsKICByMDEgPSBtYXRbMV0gLyBzY2FsZWRXaWR0aDsKICByMTAgPSBtYXRbMl0gLyBzY2FsZWRIZWlnaHQ7CiAgcjExID0gbWF0WzNdIC8gc2NhbGVkSGVpZ2h0OwogIGRldCA9IHIwMCAqIHIxMSAtIHIwMSAqIHIxMDsKICBpZiAoc3BsYXNoQWJzKGRldCkgPCAxZS02KSB7CiAgICAvLyB0aGlzIHNob3VsZCBiZSBjYXVnaHQgYnkgdGhlIHNpbmd1bGFyIG1hdHJpeCBjaGVjayBpbiBkcmF3SW1hZ2UKICAgIHJldHVybiBzcGxhc2hFcnJCYWRBcmc7CiAgfQogIGlyMDAgPSByMTEgLyBkZXQ7CiAgaXIwMSA9IC1yMDEgLyBkZXQ7CiAgaXIxMCA9IC1yMTAgLyBkZXQ7CiAgaXIxMSA9IHIwMCAvIGRldDsKCiAgLy8gc2NhbGUgdGhlIGlucHV0IGltYWdlCiAgeXAgPSBzcmNIZWlnaHQgLyBzY2FsZWRIZWlnaHQ7CiAgaWYgKHlwIDwgMCB8fCB5cCA+IElOVF9NQVggLSAxKSB7CiAgICByZXR1cm4gc3BsYXNoRXJyQmFkQXJnOwogIH0KICBzY2FsZWRJbWcgPSBzY2FsZUltYWdlKHNyYywgc3JjRGF0YSwgc3JjTW9kZSwgbkNvbXBzLCBzcmNBbHBoYSwKCQkJIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQpOwoKICBpZiAoc2NhbGVkSW1nID09IE5VTEwpIHsKICAgIHJldHVybiBzcGxhc2hFcnJCYWRBcmc7CiAgfQoKICAvLyBjb25zdHJ1Y3QgdGhlIHRocmVlIHNlY3Rpb25zCiAgaSA9IDA7CiAgaWYgKHZ5WzFdIDwgdnlbaV0pIHsKICAgIGkgPSAxOwogIH0KICBpZiAodnlbMl0gPCB2eVtpXSkgewogICAgaSA9IDI7CiAgfQogIGlmICh2eVszXSA8IHZ5W2ldKSB7CiAgICBpID0gMzsKICB9CiAgLy8gTkI6IGlmIHVzaW5nIGZpeGVkIHBvaW50LCAwLjAwMDAwMSB3aWxsIGJlIHRydW5jYXRlZCB0byB6ZXJvLAogIC8vIHNvIHRoZXNlIHR3byBjb21wYXJpc29ucyBtdXN0IGJlIDw9LCBub3QgPAogIGlmIChzcGxhc2hBYnModnlbaV0gLSB2eVsoaS0xKSAmIDNdKSA8PSAwLjAwMDAwMSAmJgogICAgICB2eVsoaS0xKSAmIDNdIDwgdnlbKGkrMSkgJiAzXSkgewogICAgaSA9IChpLTEpICYgMzsKICB9CiAgaWYgKHNwbGFzaEFicyh2eVtpXSAtIHZ5WyhpKzEpICYgM10pIDw9IDAuMDAwMDAxKSB7CiAgICBzZWN0aW9uWzBdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyKHZ5W2ldKTsKICAgIHNlY3Rpb25bMF0ueTEgPSBpbWdDb29yZE11bmdlVXBwZXIodnlbKGkrMikgJiAzXSkgLSAxOwogICAgaWYgKHZ4W2ldIDwgdnhbKGkrMSkgJiAzXSkgewogICAgICBzZWN0aW9uWzBdLmlhMCA9IGk7CiAgICAgIHNlY3Rpb25bMF0uaWExID0gKGkrMykgJiAzOwogICAgICBzZWN0aW9uWzBdLmliMCA9IChpKzEpICYgMzsKICAgICAgc2VjdGlvblswXS5pYjEgPSAoaSsyKSAmIDM7CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzBdLmlhMCA9IChpKzEpICYgMzsKICAgICAgc2VjdGlvblswXS5pYTEgPSAoaSsyKSAmIDM7CiAgICAgIHNlY3Rpb25bMF0uaWIwID0gaTsKICAgICAgc2VjdGlvblswXS5pYjEgPSAoaSszKSAmIDM7CiAgICB9CiAgICBuU2VjdGlvbnMgPSAxOwogIH0gZWxzZSB7CiAgICBzZWN0aW9uWzBdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyKHZ5W2ldKTsKICAgIHNlY3Rpb25bMl0ueTEgPSBpbWdDb29yZE11bmdlVXBwZXIodnlbKGkrMikgJiAzXSkgLSAxOwogICAgc2VjdGlvblswXS5pYTAgPSBzZWN0aW9uWzBdLmliMCA9IGk7CiAgICBzZWN0aW9uWzJdLmlhMSA9IHNlY3Rpb25bMl0uaWIxID0gKGkrMikgJiAzOwogICAgaWYgKHZ4WyhpKzEpICYgM10gPCB2eFsoaSszKSAmIDNdKSB7CiAgICAgIHNlY3Rpb25bMF0uaWExID0gc2VjdGlvblsyXS5pYTAgPSAoaSsxKSAmIDM7CiAgICAgIHNlY3Rpb25bMF0uaWIxID0gc2VjdGlvblsyXS5pYjAgPSAoaSszKSAmIDM7CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzBdLmlhMSA9IHNlY3Rpb25bMl0uaWEwID0gKGkrMykgJiAzOwogICAgICBzZWN0aW9uWzBdLmliMSA9IHNlY3Rpb25bMl0uaWIwID0gKGkrMSkgJiAzOwogICAgfQogICAgaWYgKHZ5WyhpKzEpICYgM10gPCB2eVsoaSszKSAmIDNdKSB7CiAgICAgIHNlY3Rpb25bMV0ueTAgPSBpbWdDb29yZE11bmdlTG93ZXIodnlbKGkrMSkgJiAzXSk7CiAgICAgIHNlY3Rpb25bMl0ueTAgPSBpbWdDb29yZE11bmdlVXBwZXIodnlbKGkrMykgJiAzXSk7CiAgICAgIGlmICh2eFsoaSsxKSAmIDNdIDwgdnhbKGkrMykgJiAzXSkgewoJc2VjdGlvblsxXS5pYTAgPSAoaSsxKSAmIDM7CglzZWN0aW9uWzFdLmlhMSA9IChpKzIpICYgMzsKCXNlY3Rpb25bMV0uaWIwID0gaTsKCXNlY3Rpb25bMV0uaWIxID0gKGkrMykgJiAzOwogICAgICB9IGVsc2UgewoJc2VjdGlvblsxXS5pYTAgPSBpOwoJc2VjdGlvblsxXS5pYTEgPSAoaSszKSAmIDM7CglzZWN0aW9uWzFdLmliMCA9IChpKzEpICYgMzsKCXNlY3Rpb25bMV0uaWIxID0gKGkrMikgJiAzOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBzZWN0aW9uWzFdLnkwID0gaW1nQ29vcmRNdW5nZUxvd2VyKHZ5WyhpKzMpICYgM10pOwogICAgICBzZWN0aW9uWzJdLnkwID0gaW1nQ29vcmRNdW5nZVVwcGVyKHZ5WyhpKzEpICYgM10pOwogICAgICBpZiAodnhbKGkrMSkgJiAzXSA8IHZ4WyhpKzMpICYgM10pIHsKCXNlY3Rpb25bMV0uaWEwID0gaTsKCXNlY3Rpb25bMV0uaWExID0gKGkrMSkgJiAzOwoJc2VjdGlvblsxXS5pYjAgPSAoaSszKSAmIDM7CglzZWN0aW9uWzFdLmliMSA9IChpKzIpICYgMzsKICAgICAgfSBlbHNlIHsKCXNlY3Rpb25bMV0uaWEwID0gKGkrMykgJiAzOwoJc2VjdGlvblsxXS5pYTEgPSAoaSsyKSAmIDM7CglzZWN0aW9uWzFdLmliMCA9IGk7CglzZWN0aW9uWzFdLmliMSA9IChpKzEpICYgMzsKICAgICAgfQogICAgfQogICAgc2VjdGlvblswXS55MSA9IHNlY3Rpb25bMV0ueTAgLSAxOwogICAgc2VjdGlvblsxXS55MSA9IHNlY3Rpb25bMl0ueTAgLSAxOwogICAgblNlY3Rpb25zID0gMzsKICB9CiAgZm9yIChpID0gMDsgaSA8IG5TZWN0aW9uczsgKytpKSB7CiAgICBzZWN0aW9uW2ldLnhhMCA9IHZ4W3NlY3Rpb25baV0uaWEwXTsKICAgIHNlY3Rpb25baV0ueWEwID0gdnlbc2VjdGlvbltpXS5pYTBdOwogICAgc2VjdGlvbltpXS54YTEgPSB2eFtzZWN0aW9uW2ldLmlhMV07CiAgICBzZWN0aW9uW2ldLnlhMSA9IHZ5W3NlY3Rpb25baV0uaWExXTsKICAgIHNlY3Rpb25baV0ueGIwID0gdnhbc2VjdGlvbltpXS5pYjBdOwogICAgc2VjdGlvbltpXS55YjAgPSB2eVtzZWN0aW9uW2ldLmliMF07CiAgICBzZWN0aW9uW2ldLnhiMSA9IHZ4W3NlY3Rpb25baV0uaWIxXTsKICAgIHNlY3Rpb25baV0ueWIxID0gdnlbc2VjdGlvbltpXS5pYjFdOwogICAgc2VjdGlvbltpXS5keGR5YSA9IChzZWN0aW9uW2ldLnhhMSAtIHNlY3Rpb25baV0ueGEwKSAvCiAgICAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb25baV0ueWExIC0gc2VjdGlvbltpXS55YTApOwogICAgc2VjdGlvbltpXS5keGR5YiA9IChzZWN0aW9uW2ldLnhiMSAtIHNlY3Rpb25baV0ueGIwKSAvCiAgICAgICAgICAgICAgICAgICAgICAgKHNlY3Rpb25baV0ueWIxIC0gc2VjdGlvbltpXS55YjApOwogIH0KCiAgLy8gaW5pdGlhbGl6ZSB0aGUgcGl4ZWwgcGlwZQogIHBpcGVJbml0KCZwaXBlLCAwLCAwLCBOVUxMLCBwaXhlbCwKCSAgIChHdWNoYXIpc3BsYXNoUm91bmQoc3RhdGUtPmZpbGxBbHBoYSAqIDI1NSksCgkgICBzcmNBbHBoYSB8fCAodmVjdG9yQW50aWFsaWFzICYmIGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbEluc2lkZSksCgkgICBnRmFsc2UpOwogIGlmICh2ZWN0b3JBbnRpYWxpYXMpIHsKICAgIGRyYXdBQVBpeGVsSW5pdCgpOwogIH0KCiAgLy8gbWFrZSBzdXJlIG5hcnJvdyBpbWFnZXMgY292ZXIgYXQgbGVhc3Qgb25lIHBpeGVsCiAgaWYgKG5TZWN0aW9ucyA9PSAxKSB7CiAgICBpZiAoc2VjdGlvblswXS55MCA9PSBzZWN0aW9uWzBdLnkxKSB7CiAgICAgICsrc2VjdGlvblswXS55MTsKICAgICAgY2xpcFJlcyA9IG9wQ2xpcFJlcyA9IHNwbGFzaENsaXBQYXJ0aWFsOwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAoc2VjdGlvblswXS55MCA9PSBzZWN0aW9uWzJdLnkxKSB7CiAgICAgICsrc2VjdGlvblsxXS55MTsKICAgICAgY2xpcFJlcyA9IG9wQ2xpcFJlcyA9IHNwbGFzaENsaXBQYXJ0aWFsOwogICAgfQogIH0KCiAgLy8gc2NhbiBhbGwgcGl4ZWxzIGluc2lkZSB0aGUgdGFyZ2V0IHJlZ2lvbgogIGZvciAoaSA9IDA7IGkgPCBuU2VjdGlvbnM7ICsraSkgewogICAgZm9yICh5ID0gc2VjdGlvbltpXS55MDsgeSA8PSBzZWN0aW9uW2ldLnkxOyArK3kpIHsKICAgICAgeGEgPSBpbWdDb29yZE11bmdlTG93ZXIoc2VjdGlvbltpXS54YTAgKwoJCQkgICAgICAoKFNwbGFzaENvb3JkKXkgKyAwLjUgLSBzZWN0aW9uW2ldLnlhMCkgKgoJCQkgICAgICAgIHNlY3Rpb25baV0uZHhkeWEpOwogICAgICB4YiA9IGltZ0Nvb3JkTXVuZ2VVcHBlcihzZWN0aW9uW2ldLnhiMCArCgkJCSAgICAgICgoU3BsYXNoQ29vcmQpeSArIDAuNSAtIHNlY3Rpb25baV0ueWIwKSAqCgkJCSAgICAgICAgc2VjdGlvbltpXS5keGR5Yik7CiAgICAgIC8vIG1ha2Ugc3VyZSBuYXJyb3cgaW1hZ2VzIGNvdmVyIGF0IGxlYXN0IG9uZSBwaXhlbAogICAgICBpZiAoeGEgPT0geGIpIHsKCSsreGI7CiAgICAgIH0KICAgICAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbEluc2lkZSkgewoJY2xpcFJlczIgPSBzdGF0ZS0+Y2xpcC0+dGVzdFNwYW4oeGEsIHhiIC0gMSwgeSk7CiAgICAgIH0gZWxzZSB7CgljbGlwUmVzMiA9IGNsaXBSZXM7CiAgICAgIH0KICAgICAgZm9yICh4ID0geGE7IHggPCB4YjsgKyt4KSB7CgkvLyBtYXAgKHgrMC41LCB5KzAuNSkgYmFjayB0byB0aGUgc2NhbGVkIGltYWdlCgl4eCA9IHNwbGFzaEZsb29yKCgoU3BsYXNoQ29vcmQpeCArIDAuNSAtIG1hdFs0XSkgKiBpcjAwICsKCQkJICgoU3BsYXNoQ29vcmQpeSArIDAuNSAtIG1hdFs1XSkgKiBpcjEwKTsKCXl5ID0gc3BsYXNoRmxvb3IoKChTcGxhc2hDb29yZCl4ICsgMC41IC0gbWF0WzRdKSAqIGlyMDEgKwoJCQkgKChTcGxhc2hDb29yZCl5ICsgMC41IC0gbWF0WzVdKSAqIGlyMTEpOwoJLy8geHggc2hvdWxkIGFsd2F5cyBiZSB3aXRoaW4gYm91bmRzLCBidXQgZmxvYXRpbmcgcG9pbnQKCS8vIGluYWNjdXJhY3kgY2FuIGNhdXNlIHByb2JsZW1zCglpZiAoeHggPCAwKSB7CgkgIHh4ID0gMDsKCX0gZWxzZSBpZiAoeHggPj0gc2NhbGVkV2lkdGgpIHsKCSAgeHggPSBzY2FsZWRXaWR0aCAtIDE7Cgl9CglpZiAoeXkgPCAwKSB7CgkgIHl5ID0gMDsKCX0gZWxzZSBpZiAoeXkgPj0gc2NhbGVkSGVpZ2h0KSB7CgkgIHl5ID0gc2NhbGVkSGVpZ2h0IC0gMTsKCX0KCXNjYWxlZEltZy0+Z2V0UGl4ZWwoeHgsIHl5LCBwaXhlbCk7CglpZiAoc3JjQWxwaGEpIHsKCSAgcGlwZS5zaGFwZSA9IHNjYWxlZEltZy0+YWxwaGFbeXkgKiBzY2FsZWRXaWR0aCArIHh4XTsKCX0gZWxzZSB7CgkgIHBpcGUuc2hhcGUgPSAyNTU7Cgl9CglpZiAodmVjdG9yQW50aWFsaWFzICYmIGNsaXBSZXMyICE9IHNwbGFzaENsaXBBbGxJbnNpZGUpIHsKCSAgZHJhd0FBUGl4ZWwoJnBpcGUsIHgsIHkpOwoJfSBlbHNlIHsKCSAgZHJhd1BpeGVsKCZwaXBlLCB4LCB5LCBjbGlwUmVzMiA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKTsKCX0KICAgICAgfQogICAgfQogIH0KCiAgZGVsZXRlIHNjYWxlZEltZzsKICByZXR1cm4gc3BsYXNoT2s7Cn0KCi8vIFNjYWxlIGFuIGltYWdlIGludG8gYSBTcGxhc2hCaXRtYXAuClNwbGFzaEJpdG1hcCAqU3BsYXNoOjpzY2FsZUltYWdlKFNwbGFzaEltYWdlU291cmNlIHNyYywgdm9pZCAqc3JjRGF0YSwKCQkJCSBTcGxhc2hDb2xvck1vZGUgc3JjTW9kZSwgaW50IG5Db21wcywKCQkJCSBHQm9vbCBzcmNBbHBoYSwgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkJIGludCBzY2FsZWRXaWR0aCwgaW50IHNjYWxlZEhlaWdodCkgewogIFNwbGFzaEJpdG1hcCAqZGVzdDsKCiAgZGVzdCA9IG5ldyBTcGxhc2hCaXRtYXAoc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCwgMSwgc3JjTW9kZSwgc3JjQWxwaGEsIGdUcnVlLCBiaXRtYXAtPmdldFNlcGFyYXRpb25MaXN0KCkpOwogIGlmIChkZXN0LT5nZXREYXRhUHRyKCkgIT0gTlVMTCkgewogICAgaWYgKHNjYWxlZEhlaWdodCA8IHNyY0hlaWdodCkgewogICAgICBpZiAoc2NhbGVkV2lkdGggPCBzcmNXaWR0aCkgewoJc2NhbGVJbWFnZVlkWGQoc3JjLCBzcmNEYXRhLCBzcmNNb2RlLCBuQ29tcHMsIHNyY0FscGhhLAoJCSAgICAgIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIGRlc3QpOwogICAgICB9IGVsc2UgewoJc2NhbGVJbWFnZVlkWHUoc3JjLCBzcmNEYXRhLCBzcmNNb2RlLCBuQ29tcHMsIHNyY0FscGhhLAoJCSAgICAgIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIGRlc3QpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBpZiAoc2NhbGVkV2lkdGggPCBzcmNXaWR0aCkgewoJc2NhbGVJbWFnZVl1WGQoc3JjLCBzcmNEYXRhLCBzcmNNb2RlLCBuQ29tcHMsIHNyY0FscGhhLAoJCSAgICAgIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIGRlc3QpOwogICAgICB9IGVsc2UgewoJc2NhbGVJbWFnZVl1WHUoc3JjLCBzcmNEYXRhLCBzcmNNb2RlLCBuQ29tcHMsIHNyY0FscGhhLAoJCSAgICAgIHNyY1dpZHRoLCBzcmNIZWlnaHQsIHNjYWxlZFdpZHRoLCBzY2FsZWRIZWlnaHQsIGRlc3QpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIGRlbGV0ZSBkZXN0OwogICAgZGVzdCA9IE5VTEw7CiAgfQogIHJldHVybiBkZXN0Owp9Cgp2b2lkIFNwbGFzaDo6c2NhbGVJbWFnZVlkWGQoU3BsYXNoSW1hZ2VTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkgICAgU3BsYXNoQ29sb3JNb2RlIHNyY01vZGUsIGludCBuQ29tcHMsCgkJCSAgICBHQm9vbCBzcmNBbHBoYSwgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkgICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICAgU3BsYXNoQml0bWFwICpkZXN0KSB7CiAgR3VjaGFyICpsaW5lQnVmLCAqYWxwaGFMaW5lQnVmOwogIEd1aW50ICpwaXhCdWYsICphbHBoYVBpeEJ1ZjsKICBHdWludCBwaXgwLCBwaXgxLCBwaXgyOwojaWYgU1BMQVNIX0NNWUsKICBHdWludCBwaXgzOwogIEd1aW50IHBpeFtTUE9UX05DT01QUys0XSwgY3A7CiNlbmRpZgogIEd1aW50IGFscGhhOwogIEd1Y2hhciAqZGVzdFB0ciwgKmRlc3RBbHBoYVB0cjsKICBpbnQgeXAsIHlxLCB4cCwgeHEsIHl0LCB5LCB5U3RlcCwgeHQsIHgsIHhTdGVwLCB4eCwgeHhhLCBkLCBkMCwgZDE7CiAgaW50IGksIGo7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB5IHNjYWxlCiAgeXAgPSBzcmNIZWlnaHQgLyBzY2FsZWRIZWlnaHQ7CiAgeXEgPSBzcmNIZWlnaHQgJSBzY2FsZWRIZWlnaHQ7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB4IHNjYWxlCiAgeHAgPSBzcmNXaWR0aCAvIHNjYWxlZFdpZHRoOwogIHhxID0gc3JjV2lkdGggJSBzY2FsZWRXaWR0aDsKCiAgLy8gYWxsb2NhdGUgYnVmZmVycwogIGxpbmVCdWYgPSAoR3VjaGFyICopZ21hbGxvY24oc3JjV2lkdGgsIG5Db21wcyk7CiAgcGl4QnVmID0gKEd1aW50ICopZ21hbGxvY24oc3JjV2lkdGgsIG5Db21wcyAqIHNpemVvZihpbnQpKTsKICBpZiAoc3JjQWxwaGEpIHsKICAgIGFscGhhTGluZUJ1ZiA9IChHdWNoYXIgKilnbWFsbG9jKHNyY1dpZHRoKTsKICAgIGFscGhhUGl4QnVmID0gKEd1aW50ICopZ21hbGxvY24oc3JjV2lkdGgsIHNpemVvZihpbnQpKTsKICB9IGVsc2UgewogICAgYWxwaGFMaW5lQnVmID0gTlVMTDsKICAgIGFscGhhUGl4QnVmID0gTlVMTDsKICB9CgogIC8vIGluaXQgeSBzY2FsZSBCcmVzZW5oYW0KICB5dCA9IDA7CgogIGRlc3RQdHIgPSBkZXN0LT5kYXRhOwogIGRlc3RBbHBoYVB0ciA9IGRlc3QtPmFscGhhOwogIGZvciAoeSA9IDA7IHkgPCBzY2FsZWRIZWlnaHQ7ICsreSkgewoKICAgIC8vIHkgc2NhbGUgQnJlc2VuaGFtCiAgICBpZiAoKHl0ICs9IHlxKSA+PSBzY2FsZWRIZWlnaHQpIHsKICAgICAgeXQgLT0gc2NhbGVkSGVpZ2h0OwogICAgICB5U3RlcCA9IHlwICsgMTsKICAgIH0gZWxzZSB7CiAgICAgIHlTdGVwID0geXA7CiAgICB9CgogICAgLy8gcmVhZCByb3dzIGZyb20gaW1hZ2UKICAgIG1lbXNldChwaXhCdWYsIDAsIHNyY1dpZHRoICogbkNvbXBzICogc2l6ZW9mKGludCkpOwogICAgaWYgKHNyY0FscGhhKSB7CiAgICAgIG1lbXNldChhbHBoYVBpeEJ1ZiwgMCwgc3JjV2lkdGggKiBzaXplb2YoaW50KSk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewogICAgICAoKnNyYykoc3JjRGF0YSwgbGluZUJ1ZiwgYWxwaGFMaW5lQnVmKTsKICAgICAgZm9yIChqID0gMDsgaiA8IHNyY1dpZHRoICogbkNvbXBzOyArK2opIHsKCXBpeEJ1ZltqXSArPSBsaW5lQnVmW2pdOwogICAgICB9CiAgICAgIGlmIChzcmNBbHBoYSkgewoJZm9yIChqID0gMDsgaiA8IHNyY1dpZHRoOyArK2opIHsKCSAgYWxwaGFQaXhCdWZbal0gKz0gYWxwaGFMaW5lQnVmW2pdOwoJfQogICAgICB9CiAgICB9CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwogICAgZDAgPSAoMSA8PCAyMykgLyAoeVN0ZXAgKiB4cCk7CiAgICBkMSA9ICgxIDw8IDIzKSAvICh5U3RlcCAqICh4cCArIDEpKTsKCiAgICB4eCA9IHh4YSA9IDA7CiAgICBmb3IgKHggPSAwOyB4IDwgc2NhbGVkV2lkdGg7ICsreCkgewoKICAgICAgLy8geCBzY2FsZSBCcmVzZW5oYW0KICAgICAgaWYgKCh4dCArPSB4cSkgPj0gc2NhbGVkV2lkdGgpIHsKCXh0IC09IHNjYWxlZFdpZHRoOwoJeFN0ZXAgPSB4cCArIDE7CglkID0gZDE7CiAgICAgIH0gZWxzZSB7Cgl4U3RlcCA9IHhwOwoJZCA9IGQwOwogICAgICB9CgogICAgICBzd2l0Y2ggKHNyY01vZGUpIHsKCiAgICAgIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgoKCS8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCglwaXgwID0gMDsKCWZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CgkgIHBpeDAgKz0gcGl4QnVmW3h4KytdOwoJfQoJLy8gcGl4IC8geFN0ZXAgKiB5U3RlcAoJcGl4MCA9IChwaXgwICogZCkgPj4gMjM7CgoJLy8gc3RvcmUgdGhlIHBpeGVsCgkqZGVzdFB0cisrID0gKEd1Y2hhcilwaXgwOwoJYnJlYWs7CgogICAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgoKCS8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCglwaXgwID0gcGl4MSA9IHBpeDIgPSAwOwoJZm9yIChpID0gMDsgaSA8IHhTdGVwOyArK2kpIHsKCSAgcGl4MCArPSBwaXhCdWZbeHhdOwoJICBwaXgxICs9IHBpeEJ1Zlt4eCsxXTsKCSAgcGl4MiArPSBwaXhCdWZbeHgrMl07CgkgIHh4ICs9IDM7Cgl9CgkvLyBwaXggLyB4U3RlcCAqIHlTdGVwCglwaXgwID0gKHBpeDAgKiBkKSA+PiAyMzsKCXBpeDEgPSAocGl4MSAqIGQpID4+IDIzOwoJcGl4MiA9IChwaXgyICogZCkgPj4gMjM7CgoJLy8gc3RvcmUgdGhlIHBpeGVsCgkqZGVzdFB0cisrID0gKEd1Y2hhcilwaXgwOwoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4MTsKCSpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeDI7CglicmVhazsKCiAgICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgoKCS8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCglwaXgwID0gcGl4MSA9IHBpeDIgPSAwOwoJZm9yIChpID0gMDsgaSA8IHhTdGVwOyArK2kpIHsKCSAgcGl4MCArPSBwaXhCdWZbeHhdOwoJICBwaXgxICs9IHBpeEJ1Zlt4eCsxXTsKCSAgcGl4MiArPSBwaXhCdWZbeHgrMl07CgkgIHh4ICs9IDQ7Cgl9CgkvLyBwaXggLyB4U3RlcCAqIHlTdGVwCglwaXgwID0gKHBpeDAgKiBkKSA+PiAyMzsKCXBpeDEgPSAocGl4MSAqIGQpID4+IDIzOwoJcGl4MiA9IChwaXgyICogZCkgPj4gMjM7CgoJLy8gc3RvcmUgdGhlIHBpeGVsCgkqZGVzdFB0cisrID0gKEd1Y2hhcilwaXgyOwoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4MTsKCSpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeDA7CgkqZGVzdFB0cisrID0gKEd1Y2hhcikyNTU7CglicmVhazsKCiAgICAgIGNhc2Ugc3BsYXNoTW9kZUJHUjg6CgoJLy8gY29tcHV0ZSB0aGUgZmluYWwgcGl4ZWwKCXBpeDAgPSBwaXgxID0gcGl4MiA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewoJICBwaXgwICs9IHBpeEJ1Zlt4eF07CgkgIHBpeDEgKz0gcGl4QnVmW3h4KzFdOwoJICBwaXgyICs9IHBpeEJ1Zlt4eCsyXTsKCSAgeHggKz0gMzsKCX0KCS8vIHBpeCAvIHhTdGVwICogeVN0ZXAKCXBpeDAgPSAocGl4MCAqIGQpID4+IDIzOwoJcGl4MSA9IChwaXgxICogZCkgPj4gMjM7CglwaXgyID0gKHBpeDIgKiBkKSA+PiAyMzsKCgkvLyBzdG9yZSB0aGUgcGl4ZWwKCSpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeDI7CgkqZGVzdFB0cisrID0gKEd1Y2hhcilwaXgxOwoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4MDsKCWJyZWFrOwoKI2lmIFNQTEFTSF9DTVlLCiAgICAgIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgoKCS8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCglwaXgwID0gcGl4MSA9IHBpeDIgPSBwaXgzID0gMDsKCWZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CgkgIHBpeDAgKz0gcGl4QnVmW3h4XTsKCSAgcGl4MSArPSBwaXhCdWZbeHgrMV07CgkgIHBpeDIgKz0gcGl4QnVmW3h4KzJdOwoJICBwaXgzICs9IHBpeEJ1Zlt4eCszXTsKCSAgeHggKz0gNDsKCX0KCS8vIHBpeCAvIHhTdGVwICogeVN0ZXAKCXBpeDAgPSAocGl4MCAqIGQpID4+IDIzOwoJcGl4MSA9IChwaXgxICogZCkgPj4gMjM7CglwaXgyID0gKHBpeDIgKiBkKSA+PiAyMzsKCXBpeDMgPSAocGl4MyAqIGQpID4+IDIzOwoKCS8vIHN0b3JlIHRoZSBwaXhlbAoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4MDsKCSpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeDE7CgkqZGVzdFB0cisrID0gKEd1Y2hhcilwaXgyOwoJKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4MzsKCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKCgkvLyBjb21wdXRlIHRoZSBmaW5hbCBwaXhlbAogIGZvciAoY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICBwaXhbY3BdID0gMDsKCWZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CiAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKSB7CiAgICAgIHBpeFtjcF0gKz0gcGl4QnVmW3h4ICsgY3BdOwogICAgfQogICAgeHggKz0gKFNQT1RfTkNPTVBTKzQpOwoJfQoJLy8gcGl4IC8geFN0ZXAgKiB5U3RlcAogIGZvciAoY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICBwaXhbY3BdID0gKHBpeFtjcF0gKiBkKSA+PiAyMzsKCgkvLyBzdG9yZSB0aGUgcGl4ZWwKICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4W2NwXTsKCWJyZWFrOwojZW5kaWYKCgogICAgICBjYXNlIHNwbGFzaE1vZGVNb25vMTogLy8gbW9ubzEgaXMgbm90IGFsbG93ZWQKICAgICAgZGVmYXVsdDoKCWJyZWFrOwogICAgICB9CgogICAgICAvLyBwcm9jZXNzIGFscGhhCiAgICAgIGlmIChzcmNBbHBoYSkgewoJYWxwaGEgPSAwOwoJZm9yIChpID0gMDsgaSA8IHhTdGVwOyArK2ksICsreHhhKSB7CgkgIGFscGhhICs9IGFscGhhUGl4QnVmW3h4YV07Cgl9CgkvLyBhbHBoYSAvIHhTdGVwICogeVN0ZXAKCWFscGhhID0gKGFscGhhICogZCkgPj4gMjM7CgkqZGVzdEFscGhhUHRyKysgPSAoR3VjaGFyKWFscGhhOwogICAgICB9CiAgICB9CiAgfQoKICBnZnJlZShhbHBoYVBpeEJ1Zik7CiAgZ2ZyZWUoYWxwaGFMaW5lQnVmKTsKICBnZnJlZShwaXhCdWYpOwogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6c2NhbGVJbWFnZVlkWHUoU3BsYXNoSW1hZ2VTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkgICAgU3BsYXNoQ29sb3JNb2RlIHNyY01vZGUsIGludCBuQ29tcHMsCgkJCSAgICBHQm9vbCBzcmNBbHBoYSwgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkgICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICAgU3BsYXNoQml0bWFwICpkZXN0KSB7CiAgR3VjaGFyICpsaW5lQnVmLCAqYWxwaGFMaW5lQnVmOwogIEd1aW50ICpwaXhCdWYsICphbHBoYVBpeEJ1ZjsKICBHdWludCBwaXhbc3BsYXNoTWF4Q29sb3JDb21wc107CiAgR3VpbnQgYWxwaGE7CiAgR3VjaGFyICpkZXN0UHRyLCAqZGVzdEFscGhhUHRyOwogIGludCB5cCwgeXEsIHhwLCB4cSwgeXQsIHksIHlTdGVwLCB4dCwgeCwgeFN0ZXAsIGQ7CiAgaW50IGksIGo7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB5IHNjYWxlCiAgeXAgPSBzcmNIZWlnaHQgLyBzY2FsZWRIZWlnaHQ7CiAgeXEgPSBzcmNIZWlnaHQgJSBzY2FsZWRIZWlnaHQ7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB4IHNjYWxlCiAgeHAgPSBzY2FsZWRXaWR0aCAvIHNyY1dpZHRoOwogIHhxID0gc2NhbGVkV2lkdGggJSBzcmNXaWR0aDsKCiAgLy8gYWxsb2NhdGUgYnVmZmVycwogIGxpbmVCdWYgPSAoR3VjaGFyICopZ21hbGxvY24oc3JjV2lkdGgsIG5Db21wcyk7CiAgcGl4QnVmID0gKEd1aW50ICopZ21hbGxvY24oc3JjV2lkdGgsIG5Db21wcyAqIHNpemVvZihpbnQpKTsKICBpZiAoc3JjQWxwaGEpIHsKICAgIGFscGhhTGluZUJ1ZiA9IChHdWNoYXIgKilnbWFsbG9jKHNyY1dpZHRoKTsKICAgIGFscGhhUGl4QnVmID0gKEd1aW50ICopZ21hbGxvY24oc3JjV2lkdGgsIHNpemVvZihpbnQpKTsKICB9IGVsc2UgewogICAgYWxwaGFMaW5lQnVmID0gTlVMTDsKICAgIGFscGhhUGl4QnVmID0gTlVMTDsKICB9CgogIC8vIGluaXQgeSBzY2FsZSBCcmVzZW5oYW0KICB5dCA9IDA7CgogIGRlc3RQdHIgPSBkZXN0LT5kYXRhOwogIGRlc3RBbHBoYVB0ciA9IGRlc3QtPmFscGhhOwogIGZvciAoeSA9IDA7IHkgPCBzY2FsZWRIZWlnaHQ7ICsreSkgewoKICAgIC8vIHkgc2NhbGUgQnJlc2VuaGFtCiAgICBpZiAoKHl0ICs9IHlxKSA+PSBzY2FsZWRIZWlnaHQpIHsKICAgICAgeXQgLT0gc2NhbGVkSGVpZ2h0OwogICAgICB5U3RlcCA9IHlwICsgMTsKICAgIH0gZWxzZSB7CiAgICAgIHlTdGVwID0geXA7CiAgICB9CgogICAgLy8gcmVhZCByb3dzIGZyb20gaW1hZ2UKICAgIG1lbXNldChwaXhCdWYsIDAsIHNyY1dpZHRoICogbkNvbXBzICogc2l6ZW9mKGludCkpOwogICAgaWYgKHNyY0FscGhhKSB7CiAgICAgIG1lbXNldChhbHBoYVBpeEJ1ZiwgMCwgc3JjV2lkdGggKiBzaXplb2YoaW50KSk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewogICAgICAoKnNyYykoc3JjRGF0YSwgbGluZUJ1ZiwgYWxwaGFMaW5lQnVmKTsKICAgICAgZm9yIChqID0gMDsgaiA8IHNyY1dpZHRoICogbkNvbXBzOyArK2opIHsKCXBpeEJ1ZltqXSArPSBsaW5lQnVmW2pdOwogICAgICB9CiAgICAgIGlmIChzcmNBbHBoYSkgewoJZm9yIChqID0gMDsgaiA8IHNyY1dpZHRoOyArK2opIHsKCSAgYWxwaGFQaXhCdWZbal0gKz0gYWxwaGFMaW5lQnVmW2pdOwoJfQogICAgICB9CiAgICB9CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwogICAgZCA9ICgxIDw8IDIzKSAvIHlTdGVwOwoKICAgIGZvciAoeCA9IDA7IHggPCBzcmNXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzcmNXaWR0aCkgewoJeHQgLT0gc3JjV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIGZvciAoaSA9IDA7IGkgPCBuQ29tcHM7ICsraSkgewoJLy8gcGl4QnVmW10gLyB5U3RlcAoJcGl4W2ldID0gKHBpeEJ1Zlt4ICogbkNvbXBzICsgaV0gKiBkKSA+PiAyMzsKICAgICAgfQoKICAgICAgLy8gc3RvcmUgdGhlIHBpeGVsCiAgICAgIHN3aXRjaCAoc3JjTW9kZSkgewogICAgICBjYXNlIHNwbGFzaE1vZGVNb25vMTogLy8gbW9ubzEgaXMgbm90IGFsbG93ZWQKCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVNb25vODoKCWZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFswXTsKCX0KCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVSR0I4OgoJZm9yIChpID0gMDsgaSA8IHhTdGVwOyArK2kpIHsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCX0KCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVYQkdSODoKCWZvciAoaSA9IDA7IGkgPCB4U3RlcDsgKytpKSB7CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzFdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMF07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKTI1NTsKCX0KCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgoJZm9yIChpID0gMDsgaSA8IHhTdGVwOyArK2kpIHsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzJdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFswXTsKCX0KCWJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICAgICAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6Cglmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMF07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsxXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzJdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbM107Cgl9CglicmVhazsKICAgICAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6Cglmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewogICAgZm9yIChpbnQgY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFtjcF07Cgl9CglicmVhazsKI2VuZGlmCiAgICAgIH0KCiAgICAgIC8vIHByb2Nlc3MgYWxwaGEKICAgICAgaWYgKHNyY0FscGhhKSB7CgkvLyBhbHBoYVBpeEJ1ZltdIC8geVN0ZXAKCWFscGhhID0gKGFscGhhUGl4QnVmW3hdICogZCkgPj4gMjM7Cglmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewoJICAqZGVzdEFscGhhUHRyKysgPSAoR3VjaGFyKWFscGhhOwoJfQogICAgICB9CiAgICB9CiAgfQoKICBnZnJlZShhbHBoYVBpeEJ1Zik7CiAgZ2ZyZWUoYWxwaGFMaW5lQnVmKTsKICBnZnJlZShwaXhCdWYpOwogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6c2NhbGVJbWFnZVl1WGQoU3BsYXNoSW1hZ2VTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkgICAgU3BsYXNoQ29sb3JNb2RlIHNyY01vZGUsIGludCBuQ29tcHMsCgkJCSAgICBHQm9vbCBzcmNBbHBoYSwgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkgICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICAgU3BsYXNoQml0bWFwICpkZXN0KSB7CiAgR3VjaGFyICpsaW5lQnVmLCAqYWxwaGFMaW5lQnVmOwogIEd1aW50IHBpeFtzcGxhc2hNYXhDb2xvckNvbXBzXTsKICBHdWludCBhbHBoYTsKICBHdWNoYXIgKmRlc3RQdHIwLCAqZGVzdFB0ciwgKmRlc3RBbHBoYVB0cjAsICpkZXN0QWxwaGFQdHI7CiAgaW50IHlwLCB5cSwgeHAsIHhxLCB5dCwgeSwgeVN0ZXAsIHh0LCB4LCB4U3RlcCwgeHgsIHh4YSwgZCwgZDAsIGQxOwogIGludCBpLCBqOwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeSBzY2FsZQogIHlwID0gc2NhbGVkSGVpZ2h0IC8gc3JjSGVpZ2h0OwogIHlxID0gc2NhbGVkSGVpZ2h0ICUgc3JjSGVpZ2h0OwoKICAvLyBCcmVzZW5oYW0gcGFyYW1ldGVycyBmb3IgeCBzY2FsZQogIHhwID0gc3JjV2lkdGggLyBzY2FsZWRXaWR0aDsKICB4cSA9IHNyY1dpZHRoICUgc2NhbGVkV2lkdGg7CgogIC8vIGFsbG9jYXRlIGJ1ZmZlcnMKICBsaW5lQnVmID0gKEd1Y2hhciAqKWdtYWxsb2NuKHNyY1dpZHRoLCBuQ29tcHMpOwogIGlmIChzcmNBbHBoYSkgewogICAgYWxwaGFMaW5lQnVmID0gKEd1Y2hhciAqKWdtYWxsb2Moc3JjV2lkdGgpOwogIH0gZWxzZSB7CiAgICBhbHBoYUxpbmVCdWYgPSBOVUxMOwogIH0KCiAgLy8gaW5pdCB5IHNjYWxlIEJyZXNlbmhhbQogIHl0ID0gMDsKCiAgZGVzdFB0cjAgPSBkZXN0LT5kYXRhOwogIGRlc3RBbHBoYVB0cjAgPSBkZXN0LT5hbHBoYTsKICBmb3IgKHkgPSAwOyB5IDwgc3JjSGVpZ2h0OyArK3kpIHsKCiAgICAvLyB5IHNjYWxlIEJyZXNlbmhhbQogICAgaWYgKCh5dCArPSB5cSkgPj0gc3JjSGVpZ2h0KSB7CiAgICAgIHl0IC09IHNyY0hlaWdodDsKICAgICAgeVN0ZXAgPSB5cCArIDE7CiAgICB9IGVsc2UgewogICAgICB5U3RlcCA9IHlwOwogICAgfQoKICAgIC8vIHJlYWQgcm93IGZyb20gaW1hZ2UKICAgICgqc3JjKShzcmNEYXRhLCBsaW5lQnVmLCBhbHBoYUxpbmVCdWYpOwoKICAgIC8vIGluaXQgeCBzY2FsZSBCcmVzZW5oYW0KICAgIHh0ID0gMDsKICAgIGQwID0gKDEgPDwgMjMpIC8geHA7CiAgICBkMSA9ICgxIDw8IDIzKSAvICh4cCArIDEpOwoKICAgIHh4ID0geHhhID0gMDsKICAgIGZvciAoeCA9IDA7IHggPCBzY2FsZWRXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzY2FsZWRXaWR0aCkgewoJeHQgLT0gc2NhbGVkV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKCWQgPSBkMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CglkID0gZDA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIGZvciAoaSA9IDA7IGkgPCBuQ29tcHM7ICsraSkgewoJcGl4W2ldID0gMDsKICAgICAgfQogICAgICBmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSkgewoJZm9yIChqID0gMDsgaiA8IG5Db21wczsgKytqLCArK3h4KSB7CgkgIHBpeFtqXSArPSBsaW5lQnVmW3h4XTsKCX0KICAgICAgfQogICAgICBmb3IgKGkgPSAwOyBpIDwgbkNvbXBzOyArK2kpIHsKCS8vIHBpeFtdIC8geFN0ZXAKCXBpeFtpXSA9IChwaXhbaV0gKiBkKSA+PiAyMzsKICAgICAgfQoKICAgICAgLy8gc3RvcmUgdGhlIHBpeGVsCiAgICAgIHN3aXRjaCAoc3JjTW9kZSkgewogICAgICBjYXNlIHNwbGFzaE1vZGVNb25vMTogLy8gbW9ubzEgaXMgbm90IGFsbG93ZWQKCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVNb25vODoKCWZvciAoaSA9IDA7IGkgPCB5U3RlcDsgKytpKSB7CgkgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4KSAqIG5Db21wczsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJfQoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZVJHQjg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBkZXN0UHRyID0gZGVzdFB0cjAgKyAoaSAqIHNjYWxlZFdpZHRoICsgeCkgKiBuQ29tcHM7CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFswXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzFdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMl07Cgl9CglicmVhazsKICAgICAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBkZXN0UHRyID0gZGVzdFB0cjAgKyAoaSAqIHNjYWxlZFdpZHRoICsgeCkgKiBuQ29tcHM7CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzFdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMF07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKTI1NTsKCX0KCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgoJZm9yIChpID0gMDsgaSA8IHlTdGVwOyArK2kpIHsKCSAgZGVzdFB0ciA9IGRlc3RQdHIwICsgKGkgKiBzY2FsZWRXaWR0aCArIHgpICogbkNvbXBzOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMl07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsxXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJfQoJYnJlYWs7CiNpZiBTUExBU0hfQ01ZSwogICAgICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKCWZvciAoaSA9IDA7IGkgPCB5U3RlcDsgKytpKSB7CgkgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4KSAqIG5Db21wczsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzNdOwoJfQoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZURldmljZU44OgoJZm9yIChpID0gMDsgaSA8IHlTdGVwOyArK2kpIHsKCSAgZGVzdFB0ciA9IGRlc3RQdHIwICsgKGkgKiBzY2FsZWRXaWR0aCArIHgpICogbkNvbXBzOwogICAgZm9yIChpbnQgY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFtjcF07Cgl9CglicmVhazsKI2VuZGlmCiAgICAgIH0KCiAgICAgIC8vIHByb2Nlc3MgYWxwaGEKICAgICAgaWYgKHNyY0FscGhhKSB7CglhbHBoYSA9IDA7Cglmb3IgKGkgPSAwOyBpIDwgeFN0ZXA7ICsraSwgKyt4eGEpIHsKCSAgYWxwaGEgKz0gYWxwaGFMaW5lQnVmW3h4YV07Cgl9CgkvLyBhbHBoYSAvIHhTdGVwCglhbHBoYSA9IChhbHBoYSAqIGQpID4+IDIzOwoJZm9yIChpID0gMDsgaSA8IHlTdGVwOyArK2kpIHsKCSAgZGVzdEFscGhhUHRyID0gZGVzdEFscGhhUHRyMCArIGkgKiBzY2FsZWRXaWR0aCArIHg7CgkgICpkZXN0QWxwaGFQdHIgPSAoR3VjaGFyKWFscGhhOwoJfQogICAgICB9CiAgICB9CgogICAgZGVzdFB0cjAgKz0geVN0ZXAgKiBzY2FsZWRXaWR0aCAqIG5Db21wczsKICAgIGlmIChzcmNBbHBoYSkgewogICAgICBkZXN0QWxwaGFQdHIwICs9IHlTdGVwICogc2NhbGVkV2lkdGg7CiAgICB9CiAgfQoKICBnZnJlZShhbHBoYUxpbmVCdWYpOwogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6c2NhbGVJbWFnZVl1WHUoU3BsYXNoSW1hZ2VTb3VyY2Ugc3JjLCB2b2lkICpzcmNEYXRhLAoJCQkgICAgU3BsYXNoQ29sb3JNb2RlIHNyY01vZGUsIGludCBuQ29tcHMsCgkJCSAgICBHQm9vbCBzcmNBbHBoYSwgaW50IHNyY1dpZHRoLCBpbnQgc3JjSGVpZ2h0LAoJCQkgICAgaW50IHNjYWxlZFdpZHRoLCBpbnQgc2NhbGVkSGVpZ2h0LAoJCQkgICAgU3BsYXNoQml0bWFwICpkZXN0KSB7CiAgR3VjaGFyICpsaW5lQnVmLCAqYWxwaGFMaW5lQnVmOwogIEd1aW50IHBpeFtzcGxhc2hNYXhDb2xvckNvbXBzXTsKICBHdWludCBhbHBoYTsKICBHdWNoYXIgKmRlc3RQdHIwLCAqZGVzdFB0ciwgKmRlc3RBbHBoYVB0cjAsICpkZXN0QWxwaGFQdHI7CiAgaW50IHlwLCB5cSwgeHAsIHhxLCB5dCwgeSwgeVN0ZXAsIHh0LCB4LCB4U3RlcCwgeHg7CiAgaW50IGksIGo7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB5IHNjYWxlCiAgeXAgPSBzY2FsZWRIZWlnaHQgLyBzcmNIZWlnaHQ7CiAgeXEgPSBzY2FsZWRIZWlnaHQgJSBzcmNIZWlnaHQ7CgogIC8vIEJyZXNlbmhhbSBwYXJhbWV0ZXJzIGZvciB4IHNjYWxlCiAgeHAgPSBzY2FsZWRXaWR0aCAvIHNyY1dpZHRoOwogIHhxID0gc2NhbGVkV2lkdGggJSBzcmNXaWR0aDsKCiAgLy8gYWxsb2NhdGUgYnVmZmVycwogIGxpbmVCdWYgPSAoR3VjaGFyICopZ21hbGxvY24oc3JjV2lkdGgsIG5Db21wcyk7CiAgaWYgKHNyY0FscGhhKSB7CiAgICBhbHBoYUxpbmVCdWYgPSAoR3VjaGFyICopZ21hbGxvYyhzcmNXaWR0aCk7CiAgfSBlbHNlIHsKICAgIGFscGhhTGluZUJ1ZiA9IE5VTEw7CiAgfQoKICAvLyBpbml0IHkgc2NhbGUgQnJlc2VuaGFtCiAgeXQgPSAwOwoKICBkZXN0UHRyMCA9IGRlc3QtPmRhdGE7CiAgZGVzdEFscGhhUHRyMCA9IGRlc3QtPmFscGhhOwogIGZvciAoeSA9IDA7IHkgPCBzcmNIZWlnaHQ7ICsreSkgewoKICAgIC8vIHkgc2NhbGUgQnJlc2VuaGFtCiAgICBpZiAoKHl0ICs9IHlxKSA+PSBzcmNIZWlnaHQpIHsKICAgICAgeXQgLT0gc3JjSGVpZ2h0OwogICAgICB5U3RlcCA9IHlwICsgMTsKICAgIH0gZWxzZSB7CiAgICAgIHlTdGVwID0geXA7CiAgICB9CgogICAgLy8gcmVhZCByb3cgZnJvbSBpbWFnZQogICAgKCpzcmMpKHNyY0RhdGEsIGxpbmVCdWYsIGFscGhhTGluZUJ1Zik7CgogICAgLy8gaW5pdCB4IHNjYWxlIEJyZXNlbmhhbQogICAgeHQgPSAwOwoKICAgIHh4ID0gMDsKICAgIGZvciAoeCA9IDA7IHggPCBzcmNXaWR0aDsgKyt4KSB7CgogICAgICAvLyB4IHNjYWxlIEJyZXNlbmhhbQogICAgICBpZiAoKHh0ICs9IHhxKSA+PSBzcmNXaWR0aCkgewoJeHQgLT0gc3JjV2lkdGg7Cgl4U3RlcCA9IHhwICsgMTsKICAgICAgfSBlbHNlIHsKCXhTdGVwID0geHA7CiAgICAgIH0KCiAgICAgIC8vIGNvbXB1dGUgdGhlIGZpbmFsIHBpeGVsCiAgICAgIGZvciAoaSA9IDA7IGkgPCBuQ29tcHM7ICsraSkgewoJcGl4W2ldID0gbGluZUJ1Zlt4ICogbkNvbXBzICsgaV07CiAgICAgIH0KCiAgICAgIC8vIHN0b3JlIHRoZSBwaXhlbAogICAgICBzd2l0Y2ggKHNyY01vZGUpIHsKICAgICAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6IC8vIG1vbm8xIGlzIG5vdCBhbGxvd2VkCglicmVhazsKICAgICAgY2FzZSBzcGxhc2hNb2RlTW9ubzg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBmb3IgKGogPSAwOyBqIDwgeFN0ZXA7ICsraikgewoJICAgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4eCArIGopICogbkNvbXBzOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFswXTsKCSAgfQoJfQoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZVJHQjg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBmb3IgKGogPSAwOyBqIDwgeFN0ZXA7ICsraikgewoJICAgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4eCArIGopICogbkNvbXBzOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFswXTsKCSAgICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzJdOwoJICB9Cgl9CglicmVhazsKICAgICAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBmb3IgKGogPSAwOyBqIDwgeFN0ZXA7ICsraikgewoJICAgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4eCArIGopICogbkNvbXBzOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKTI1NTsKCSAgfQoJfQoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTW9kZUJHUjg6Cglmb3IgKGkgPSAwOyBpIDwgeVN0ZXA7ICsraSkgewoJICBmb3IgKGogPSAwOyBqIDwgeFN0ZXA7ICsraikgewoJICAgIGRlc3RQdHIgPSBkZXN0UHRyMCArIChpICogc2NhbGVkV2lkdGggKyB4eCArIGopICogbkNvbXBzOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMV07CgkgICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzBdOwoJICB9Cgl9CglicmVhazsKI2lmIFNQTEFTSF9DTVlLCiAgICAgIGNhc2Ugc3BsYXNoTW9kZUNNWUs4OgoJZm9yIChpID0gMDsgaSA8IHlTdGVwOyArK2kpIHsKCSAgZm9yIChqID0gMDsgaiA8IHhTdGVwOyArK2opIHsKCSAgICBkZXN0UHRyID0gZGVzdFB0cjAgKyAoaSAqIHNjYWxlZFdpZHRoICsgeHggKyBqKSAqIG5Db21wczsKCSAgICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbMF07CgkgICAgKmRlc3RQdHIrKyA9IChHdWNoYXIpcGl4WzFdOwoJICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFsyXTsKCSAgICAqZGVzdFB0cisrID0gKEd1Y2hhcilwaXhbM107CgkgIH0KCX0KCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKCWZvciAoaSA9IDA7IGkgPCB5U3RlcDsgKytpKSB7CgkgIGZvciAoaiA9IDA7IGogPCB4U3RlcDsgKytqKSB7CgkgICAgZGVzdFB0ciA9IGRlc3RQdHIwICsgKGkgKiBzY2FsZWRXaWR0aCArIHh4ICsgaikgKiBuQ29tcHM7CiAgICAgIGZvciAoaW50IGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgICAgICpkZXN0UHRyKysgPSAoR3VjaGFyKXBpeFtjcF07CgkgIH0KCX0KCWJyZWFrOwojZW5kaWYKICAgICAgfQoKICAgICAgLy8gcHJvY2VzcyBhbHBoYQogICAgICBpZiAoc3JjQWxwaGEpIHsKCWFscGhhID0gYWxwaGFMaW5lQnVmW3hdOwoJZm9yIChpID0gMDsgaSA8IHlTdGVwOyArK2kpIHsKCSAgZm9yIChqID0gMDsgaiA8IHhTdGVwOyArK2opIHsKCSAgICBkZXN0QWxwaGFQdHIgPSBkZXN0QWxwaGFQdHIwICsgaSAqIHNjYWxlZFdpZHRoICsgeHggKyBqOwoJICAgICpkZXN0QWxwaGFQdHIgPSAoR3VjaGFyKWFscGhhOwoJICB9Cgl9CiAgICAgIH0KCiAgICAgIHh4ICs9IHhTdGVwOwogICAgfQoKICAgIGRlc3RQdHIwICs9IHlTdGVwICogc2NhbGVkV2lkdGggKiBuQ29tcHM7CiAgICBpZiAoc3JjQWxwaGEpIHsKICAgICAgZGVzdEFscGhhUHRyMCArPSB5U3RlcCAqIHNjYWxlZFdpZHRoOwogICAgfQogIH0KCiAgZ2ZyZWUoYWxwaGFMaW5lQnVmKTsKICBnZnJlZShsaW5lQnVmKTsKfQoKdm9pZCBTcGxhc2g6OnZlcnRGbGlwSW1hZ2UoU3BsYXNoQml0bWFwICppbWcsIGludCB3aWR0aCwgaW50IGhlaWdodCwKCQkJICAgaW50IG5Db21wcykgewogIEd1Y2hhciAqbGluZUJ1ZjsKICBHdWNoYXIgKnAwLCAqcDE7CiAgaW50IHc7CgogIHcgPSB3aWR0aCAqIG5Db21wczsKICBsaW5lQnVmID0gKEd1Y2hhciAqKWdtYWxsb2Modyk7CiAgZm9yIChwMCA9IGltZy0+ZGF0YSwgcDEgPSBpbWctPmRhdGEgKyAoaGVpZ2h0IC0gMSkgKiB3OwogICAgICAgcDAgPCBwMTsKICAgICAgIHAwICs9IHcsIHAxIC09IHcpIHsKICAgIG1lbWNweShsaW5lQnVmLCBwMCwgdyk7CiAgICBtZW1jcHkocDAsIHAxLCB3KTsKICAgIG1lbWNweShwMSwgbGluZUJ1Ziwgdyk7CiAgfQogIGlmIChpbWctPmFscGhhKSB7CiAgICBmb3IgKHAwID0gaW1nLT5hbHBoYSwgcDEgPSBpbWctPmFscGhhICsgKGhlaWdodCAtIDEpICogd2lkdGg7CgkgcDAgPCBwMTsKCSBwMCArPSB3aWR0aCwgcDEgLT0gd2lkdGgpIHsKICAgICAgbWVtY3B5KGxpbmVCdWYsIHAwLCB3aWR0aCk7CiAgICAgIG1lbWNweShwMCwgcDEsIHdpZHRoKTsKICAgICAgbWVtY3B5KHAxLCBsaW5lQnVmLCB3aWR0aCk7CiAgICB9CiAgfQogIGdmcmVlKGxpbmVCdWYpOwp9Cgp2b2lkIFNwbGFzaDo6YmxpdEltYWdlKFNwbGFzaEJpdG1hcCAqc3JjLCBHQm9vbCBzcmNBbHBoYSwgaW50IHhEZXN0LCBpbnQgeURlc3QsCgkJICAgICAgIFNwbGFzaENsaXBSZXN1bHQgY2xpcFJlcykgewogIFNwbGFzaFBpcGUgcGlwZTsKICBTcGxhc2hDb2xvciBwaXhlbDsKICBHdWNoYXIgKmFwOwogIGludCB3LCBoLCB4MCwgeTAsIHgxLCB5MSwgeCwgeTsKCiAgLy8gc3BsaXQgdGhlIGltYWdlIGludG8gY2xpcHBlZCBhbmQgdW5jbGlwcGVkIHJlZ2lvbnMKICB3ID0gc3JjLT5nZXRXaWR0aCgpOwogIGggPSBzcmMtPmdldEhlaWdodCgpOwogIGlmIChjbGlwUmVzID09IHNwbGFzaENsaXBBbGxJbnNpZGUpIHsKICAgIHgwID0gMDsKICAgIHkwID0gMDsKICAgIHgxID0gdzsKICAgIHkxID0gaDsKICB9IGVsc2UgewogICAgaWYgKHN0YXRlLT5jbGlwLT5nZXROdW1QYXRocygpKSB7CiAgICAgIHgwID0geDEgPSB3OwogICAgICB5MCA9IHkxID0gaDsKICAgIH0gZWxzZSB7CiAgICAgIGlmICgoeDAgPSBzcGxhc2hDZWlsKHN0YXRlLT5jbGlwLT5nZXRYTWluKCkpIC0geERlc3QpIDwgMCkgewoJeDAgPSAwOwogICAgICB9CiAgICAgIGlmICgoeTAgPSBzcGxhc2hDZWlsKHN0YXRlLT5jbGlwLT5nZXRZTWluKCkpIC0geURlc3QpIDwgMCkgewoJeTAgPSAwOwogICAgICB9CiAgICAgIGlmICgoeDEgPSBzcGxhc2hGbG9vcihzdGF0ZS0+Y2xpcC0+Z2V0WE1heCgpKSAtIHhEZXN0KSA+IHcpIHsKCXgxID0gdzsKICAgICAgfQogICAgICBpZiAoeDEgPCB4MCkgewoJeDEgPSB4MDsKICAgICAgfQogICAgICBpZiAoKHkxID0gc3BsYXNoRmxvb3Ioc3RhdGUtPmNsaXAtPmdldFlNYXgoKSkgLSB5RGVzdCkgPiBoKSB7Cgl5MSA9IGg7CiAgICAgIH0KICAgICAgaWYgKHkxIDwgeTApIHsKCXkxID0geTA7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIGRyYXcgdGhlIHVuY2xpcHBlZCByZWdpb24KICBpZiAoeDAgPCB3ICYmIHkwIDwgaCAmJiB4MCA8IHgxICYmIHkwIDwgeTEpIHsKICAgIHBpcGVJbml0KCZwaXBlLCB4RGVzdCArIHgwLCB5RGVzdCArIHkwLCBOVUxMLCBwaXhlbCwKCSAgICAgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgc3JjQWxwaGEsIGdGYWxzZSk7CiAgICBpZiAoc3JjQWxwaGEpIHsKICAgICAgZm9yICh5ID0geTA7IHkgPCB5MTsgKyt5KSB7CglwaXBlU2V0WFkoJnBpcGUsIHhEZXN0ICsgeDAsIHlEZXN0ICsgeSk7CglhcCA9IHNyYy0+Z2V0QWxwaGFQdHIoKSArIHkgKiB3ICsgeDA7Cglmb3IgKHggPSB4MDsgeCA8IHgxOyArK3gpIHsKCSAgc3JjLT5nZXRQaXhlbCh4LCB5LCBwaXhlbCk7CgkgIHBpcGUuc2hhcGUgPSAqYXArKzsKCSAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwoJfQogICAgICB9CiAgICB9IGVsc2UgewogICAgICBmb3IgKHkgPSB5MDsgeSA8IHkxOyArK3kpIHsKCXBpcGVTZXRYWSgmcGlwZSwgeERlc3QgKyB4MCwgeURlc3QgKyB5KTsKCWZvciAoeCA9IHgwOyB4IDwgeDE7ICsreCkgewoJICBzcmMtPmdldFBpeGVsKHgsIHksIHBpeGVsKTsKCSAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwoJfQogICAgICB9CiAgICB9CiAgICB1cGRhdGVNb2RYKHhEZXN0ICsgeDApOwogICAgdXBkYXRlTW9kWCh4RGVzdCArIHgxIC0gMSk7CiAgICB1cGRhdGVNb2RZKHlEZXN0ICsgeTApOwogICAgdXBkYXRlTW9kWSh5RGVzdCArIHkxIC0gMSk7CiAgfQoKICAvLyBkcmF3IHRoZSBjbGlwcGVkIHJlZ2lvbnMKICBpZiAoeTAgPiAwKSB7CiAgICBibGl0SW1hZ2VDbGlwcGVkKHNyYywgc3JjQWxwaGEsIDAsIDAsIHhEZXN0LCB5RGVzdCwgdywgeTApOwogIH0KICBpZiAoeTEgPCBoKSB7CiAgICBibGl0SW1hZ2VDbGlwcGVkKHNyYywgc3JjQWxwaGEsIDAsIHkxLCB4RGVzdCwgeURlc3QgKyB5MSwgdywgaCAtIHkxKTsKICB9CiAgaWYgKHgwID4gMCAmJiB5MCA8IHkxKSB7CiAgICBibGl0SW1hZ2VDbGlwcGVkKHNyYywgc3JjQWxwaGEsIDAsIHkwLCB4RGVzdCwgeURlc3QgKyB5MCwgeDAsIHkxIC0geTApOwogIH0KICBpZiAoeDEgPCB3ICYmIHkwIDwgeTEpIHsKICAgIGJsaXRJbWFnZUNsaXBwZWQoc3JjLCBzcmNBbHBoYSwgeDEsIHkwLCB4RGVzdCArIHgxLCB5RGVzdCArIHkwLAoJCSAgICAgdyAtIHgxLCB5MSAtIHkwKTsKICB9Cn0KCnZvaWQgU3BsYXNoOjpibGl0SW1hZ2VDbGlwcGVkKFNwbGFzaEJpdG1hcCAqc3JjLCBHQm9vbCBzcmNBbHBoYSwKCQkJICAgICAgaW50IHhTcmMsIGludCB5U3JjLCBpbnQgeERlc3QsIGludCB5RGVzdCwKCQkJICAgICAgaW50IHcsIGludCBoKSB7CiAgU3BsYXNoUGlwZSBwaXBlOwogIFNwbGFzaENvbG9yIHBpeGVsOwogIEd1Y2hhciAqYXA7CiAgaW50IHgsIHk7CgogIGlmICh2ZWN0b3JBbnRpYWxpYXMpIHsKICAgIHBpcGVJbml0KCZwaXBlLCB4RGVzdCwgeURlc3QsIE5VTEwsIHBpeGVsLAoJICAgICAoR3VjaGFyKXNwbGFzaFJvdW5kKHN0YXRlLT5maWxsQWxwaGEgKiAyNTUpLCBnVHJ1ZSwgZ0ZhbHNlKTsKICAgIGRyYXdBQVBpeGVsSW5pdCgpOwogICAgaWYgKHNyY0FscGhhKSB7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKCWFwID0gc3JjLT5nZXRBbHBoYVB0cigpICsgKHlTcmMgKyB5KSAqIHNyYy0+Z2V0V2lkdGgoKSArIHhTcmM7Cglmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CgkgIHNyYy0+Z2V0UGl4ZWwoeFNyYyArIHgsIHlTcmMgKyB5LCBwaXhlbCk7CgkgIHBpcGUuc2hhcGUgPSAqYXArKzsKCSAgZHJhd0FBUGl4ZWwoJnBpcGUsIHhEZXN0ICsgeCwgeURlc3QgKyB5KTsKCX0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgZm9yICh5ID0gMDsgeSA8IGg7ICsreSkgewoJZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJICBzcmMtPmdldFBpeGVsKHhTcmMgKyB4LCB5U3JjICsgeSwgcGl4ZWwpOwoJICBwaXBlLnNoYXBlID0gMjU1OwoJICBkcmF3QUFQaXhlbCgmcGlwZSwgeERlc3QgKyB4LCB5RGVzdCArIHkpOwoJfQogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIHBpcGVJbml0KCZwaXBlLCB4RGVzdCwgeURlc3QsIE5VTEwsIHBpeGVsLAoJICAgICAoR3VjaGFyKXNwbGFzaFJvdW5kKHN0YXRlLT5maWxsQWxwaGEgKiAyNTUpLCBzcmNBbHBoYSwgZ0ZhbHNlKTsKICAgIGlmIChzcmNBbHBoYSkgewogICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CglhcCA9IHNyYy0+Z2V0QWxwaGFQdHIoKSArICh5U3JjICsgeSkgKiBzcmMtPmdldFdpZHRoKCkgKyB4U3JjOwoJcGlwZVNldFhZKCZwaXBlLCB4RGVzdCwgeURlc3QgKyB5KTsKCWZvciAoeCA9IDA7IHggPCB3OyArK3gpIHsKCSAgaWYgKHN0YXRlLT5jbGlwLT50ZXN0KHhEZXN0ICsgeCwgeURlc3QgKyB5KSkgewoJICAgIHNyYy0+Z2V0UGl4ZWwoeFNyYyArIHgsIHlTcmMgKyB5LCBwaXhlbCk7CgkgICAgcGlwZS5zaGFwZSA9ICphcCsrOwoJICAgICh0aGlzLT4qcGlwZS5ydW4pKCZwaXBlKTsKCSAgICB1cGRhdGVNb2RYKHhEZXN0ICsgeCk7CgkgICAgdXBkYXRlTW9kWSh5RGVzdCArIHkpOwoJICB9IGVsc2UgewoJICAgIHBpcGVJbmNYKCZwaXBlKTsKCSAgICArK2FwOwoJICB9Cgl9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKCXBpcGVTZXRYWSgmcGlwZSwgeERlc3QsIHlEZXN0ICsgeSk7Cglmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CgkgIGlmIChzdGF0ZS0+Y2xpcC0+dGVzdCh4RGVzdCArIHgsIHlEZXN0ICsgeSkpIHsKCSAgICBzcmMtPmdldFBpeGVsKHhTcmMgKyB4LCB5U3JjICsgeSwgcGl4ZWwpOwoJICAgICh0aGlzLT4qcGlwZS5ydW4pKCZwaXBlKTsKCSAgICB1cGRhdGVNb2RYKHhEZXN0ICsgeCk7CgkgICAgdXBkYXRlTW9kWSh5RGVzdCArIHkpOwoJICB9IGVsc2UgewoJICAgIHBpcGVJbmNYKCZwaXBlKTsKCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQp9CgpTcGxhc2hFcnJvciBTcGxhc2g6OmNvbXBvc2l0ZShTcGxhc2hCaXRtYXAgKnNyYywgaW50IHhTcmMsIGludCB5U3JjLAoJCQkgICAgICBpbnQgeERlc3QsIGludCB5RGVzdCwgaW50IHcsIGludCBoLAoJCQkgICAgICBHQm9vbCBub0NsaXAsIEdCb29sIG5vbklzb2xhdGVkLAoJCQkgICAgICBHQm9vbCBrbm9ja291dCwgU3BsYXNoQ29vcmQga25vY2tvdXRPcGFjaXR5KSB7CiAgU3BsYXNoUGlwZSBwaXBlOwogIFNwbGFzaENvbG9yIHBpeGVsOwogIEd1Y2hhciBhbHBoYTsKICBHdWNoYXIgKmFwOwogIGludCB4LCB5OwoKICBpZiAoc3JjLT5tb2RlICE9IGJpdG1hcC0+bW9kZSkgewogICAgcmV0dXJuIHNwbGFzaEVyck1vZGVNaXNtYXRjaDsKICB9CgogIGlmKHNyYy0+Z2V0U2VwYXJhdGlvbkxpc3QoKS0+Z2V0TGVuZ3RoKCkgPiBiaXRtYXAtPmdldFNlcGFyYXRpb25MaXN0KCktPmdldExlbmd0aCgpKSB7CiAgICBmb3IgKHggPSBiaXRtYXAtPmdldFNlcGFyYXRpb25MaXN0KCktPmdldExlbmd0aCgpOyB4IDwgc3JjLT5nZXRTZXBhcmF0aW9uTGlzdCgpLT5nZXRMZW5ndGgoKTsgeCsrKQogICAgICBiaXRtYXAtPmdldFNlcGFyYXRpb25MaXN0KCktPmFwcGVuZCgoKEdmeFNlcGFyYXRpb25Db2xvclNwYWNlICopc3JjLT5nZXRTZXBhcmF0aW9uTGlzdCgpLT5nZXQoeCkpLT5jb3B5KCkpOwogIH0KICBpZiAoc3JjLT5hbHBoYSkgewogICAgcGlwZUluaXQoJnBpcGUsIHhEZXN0LCB5RGVzdCwgTlVMTCwgcGl4ZWwsCgkgICAgIChHdWNoYXIpc3BsYXNoUm91bmQoc3RhdGUtPmZpbGxBbHBoYSAqIDI1NSksIGdUcnVlLCBub25Jc29sYXRlZCwKCSAgICAga25vY2tvdXQsIChHdWNoYXIpc3BsYXNoUm91bmQoa25vY2tvdXRPcGFjaXR5ICogMjU1KSk7CiAgICBpZiAobm9DbGlwKSB7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKCXBpcGVTZXRYWSgmcGlwZSwgeERlc3QsIHlEZXN0ICsgeSk7CglhcCA9IHNyYy0+Z2V0QWxwaGFQdHIoKSArICh5U3JjICsgeSkgKiBzcmMtPmdldFdpZHRoKCkgKyB4U3JjOwoJZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJICBzcmMtPmdldFBpeGVsKHhTcmMgKyB4LCB5U3JjICsgeSwgcGl4ZWwpOwoJICBhbHBoYSA9ICphcCsrOwoJICAvLyB0aGlzIHVzZXMgc2hhcGUgaW5zdGVhZCBvZiBhbHBoYSwgd2hpY2ggaXNuJ3QgdGVjaG5pY2FsbHkKCSAgLy8gY29ycmVjdCwgYnV0IHdvcmtzIG91dCB0aGUgc2FtZQogICAgcGlwZS5zaGFwZSA9IGFscGhhOwoJICAodGhpcy0+KnBpcGUucnVuKSgmcGlwZSk7Cgl9CiAgICAgIH0KICAgICAgdXBkYXRlTW9kWCh4RGVzdCk7CiAgICAgIHVwZGF0ZU1vZFgoeERlc3QgKyB3IC0gMSk7CiAgICAgIHVwZGF0ZU1vZFkoeURlc3QpOwogICAgICB1cGRhdGVNb2RZKHlEZXN0ICsgaCAtIDEpOwogICAgfSBlbHNlIHsKICAgICAgZm9yICh5ID0gMDsgeSA8IGg7ICsreSkgewoJcGlwZVNldFhZKCZwaXBlLCB4RGVzdCwgeURlc3QgKyB5KTsKCWFwID0gc3JjLT5nZXRBbHBoYVB0cigpICsgKHlTcmMgKyB5KSAqIHNyYy0+Z2V0V2lkdGgoKSArIHhTcmM7Cglmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CgkgIHNyYy0+Z2V0UGl4ZWwoeFNyYyArIHgsIHlTcmMgKyB5LCBwaXhlbCk7CgkgIGFscGhhID0gKmFwKys7CgkgIGlmIChzdGF0ZS0+Y2xpcC0+dGVzdCh4RGVzdCArIHgsIHlEZXN0ICsgeSkpIHsKCSAgICAvLyB0aGlzIHVzZXMgc2hhcGUgaW5zdGVhZCBvZiBhbHBoYSwgd2hpY2ggaXNuJ3QgdGVjaG5pY2FsbHkKCSAgICAvLyBjb3JyZWN0LCBidXQgd29ya3Mgb3V0IHRoZSBzYW1lCiAgICAgIHBpcGUuc2hhcGUgPSBhbHBoYTsKCSAgICAodGhpcy0+KnBpcGUucnVuKSgmcGlwZSk7CgkgICAgdXBkYXRlTW9kWCh4RGVzdCArIHgpOwoJICAgIHVwZGF0ZU1vZFkoeURlc3QgKyB5KTsKCSAgfSBlbHNlIHsKCSAgICBwaXBlSW5jWCgmcGlwZSk7CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICBwaXBlSW5pdCgmcGlwZSwgeERlc3QsIHlEZXN0LCBOVUxMLCBwaXhlbCwKCSAgICAgKEd1Y2hhcilzcGxhc2hSb3VuZChzdGF0ZS0+ZmlsbEFscGhhICogMjU1KSwgZ0ZhbHNlLCBub25Jc29sYXRlZCk7CiAgICBpZiAobm9DbGlwKSB7CiAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyArK3kpIHsKCXBpcGVTZXRYWSgmcGlwZSwgeERlc3QsIHlEZXN0ICsgeSk7Cglmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CgkgIHNyYy0+Z2V0UGl4ZWwoeFNyYyArIHgsIHlTcmMgKyB5LCBwaXhlbCk7CgkgICh0aGlzLT4qcGlwZS5ydW4pKCZwaXBlKTsKCX0KICAgICAgfQogICAgICB1cGRhdGVNb2RYKHhEZXN0KTsKICAgICAgdXBkYXRlTW9kWCh4RGVzdCArIHcgLSAxKTsKICAgICAgdXBkYXRlTW9kWSh5RGVzdCk7CiAgICAgIHVwZGF0ZU1vZFkoeURlc3QgKyBoIC0gMSk7CiAgICB9IGVsc2UgewogICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CglwaXBlU2V0WFkoJnBpcGUsIHhEZXN0LCB5RGVzdCArIHkpOwoJZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJICBzcmMtPmdldFBpeGVsKHhTcmMgKyB4LCB5U3JjICsgeSwgcGl4ZWwpOwoJICBpZiAoc3RhdGUtPmNsaXAtPnRlc3QoeERlc3QgKyB4LCB5RGVzdCArIHkpKSB7CgkgICAgKHRoaXMtPipwaXBlLnJ1bikoJnBpcGUpOwoJICAgIHVwZGF0ZU1vZFgoeERlc3QgKyB4KTsKCSAgICB1cGRhdGVNb2RZKHlEZXN0ICsgeSk7CgkgIH0gZWxzZSB7CgkgICAgcGlwZUluY1goJnBpcGUpOwoJICB9Cgl9CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBzcGxhc2hPazsKfQoKdm9pZCBTcGxhc2g6OmNvbXBvc2l0ZUJhY2tncm91bmQoU3BsYXNoQ29sb3JQdHIgY29sb3IpIHsKICBTcGxhc2hDb2xvclB0ciBwOwogIEd1Y2hhciAqcTsKICBHdWNoYXIgYWxwaGEsIGFscGhhMSwgYywgY29sb3IwLCBjb2xvcjEsIGNvbG9yMjsKI2lmIFNQTEFTSF9DTVlLCiAgR3VjaGFyIGNvbG9yMzsKICBHdWNoYXIgY29sb3JzcFtTUE9UX05DT01QUys0XSwgY3A7CiNlbmRpZgogIGludCB4LCB5LCBtYXNrOwoKICBpZiAodW5saWtlbHkoYml0bWFwLT5hbHBoYSA9PSBOVUxMKSkgewogICAgZXJyb3IoZXJySW50ZXJuYWwsIC0xLCAiYml0bWFwLT5hbHBoYSBpcyBOVUxMIGluIFNwbGFzaDo6Y29tcG9zaXRlQmFja2dyb3VuZCIpOwogICAgcmV0dXJuOwogIH0KCiAgc3dpdGNoIChiaXRtYXAtPm1vZGUpIHsKICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGNvbG9yMCA9IGNvbG9yWzBdOwogICAgZm9yICh5ID0gMDsgeSA8IGJpdG1hcC0+aGVpZ2h0OyArK3kpIHsKICAgICAgcCA9ICZiaXRtYXAtPmRhdGFbeSAqIGJpdG1hcC0+cm93U2l6ZV07CiAgICAgIHEgPSAmYml0bWFwLT5hbHBoYVt5ICogYml0bWFwLT53aWR0aF07CiAgICAgIG1hc2sgPSAweDgwOwogICAgICBmb3IgKHggPSAwOyB4IDwgYml0bWFwLT53aWR0aDsgKyt4KSB7CglhbHBoYSA9ICpxKys7CglhbHBoYTEgPSAyNTUgLSBhbHBoYTsKCWMgPSAoKnAgJiBtYXNrKSA/IDB4ZmYgOiAweDAwOwoJYyA9IGRpdjI1NShhbHBoYTEgKiBjb2xvcjAgKyBhbHBoYSAqIGMpOwoJaWYgKGMgJiAweDgwKSB7CgkgICpwIHw9IG1hc2s7Cgl9IGVsc2UgewoJICAqcCAmPSB+bWFzazsKCX0KCWlmICghKG1hc2sgPj49IDEpKSB7CgkgIG1hc2sgPSAweDgwOwoJICArK3A7Cgl9CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgY29sb3IwID0gY29sb3JbMF07CiAgICBmb3IgKHkgPSAwOyB5IDwgYml0bWFwLT5oZWlnaHQ7ICsreSkgewogICAgICBwID0gJmJpdG1hcC0+ZGF0YVt5ICogYml0bWFwLT5yb3dTaXplXTsKICAgICAgcSA9ICZiaXRtYXAtPmFscGhhW3kgKiBiaXRtYXAtPndpZHRoXTsKICAgICAgZm9yICh4ID0gMDsgeCA8IGJpdG1hcC0+d2lkdGg7ICsreCkgewoJYWxwaGEgPSAqcSsrOwoJYWxwaGExID0gMjU1IC0gYWxwaGE7CglwWzBdID0gZGl2MjU1KGFscGhhMSAqIGNvbG9yMCArIGFscGhhICogcFswXSk7CgkrK3A7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVJHQjg6CiAgY2FzZSBzcGxhc2hNb2RlQkdSODoKICAgIGNvbG9yMCA9IGNvbG9yWzBdOwogICAgY29sb3IxID0gY29sb3JbMV07CiAgICBjb2xvcjIgPSBjb2xvclsyXTsKICAgIGZvciAoeSA9IDA7IHkgPCBiaXRtYXAtPmhlaWdodDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhW3kgKiBiaXRtYXAtPnJvd1NpemVdOwogICAgICBxID0gJmJpdG1hcC0+YWxwaGFbeSAqIGJpdG1hcC0+d2lkdGhdOwogICAgICBmb3IgKHggPSAwOyB4IDwgYml0bWFwLT53aWR0aDsgKyt4KSB7CglhbHBoYSA9ICpxKys7CglpZiAoYWxwaGEgPT0gMCkKCXsKCSAgcFswXSA9IGNvbG9yMDsKCSAgcFsxXSA9IGNvbG9yMTsKCSAgcFsyXSA9IGNvbG9yMjsKCX0KCWVsc2UgaWYgKGFscGhhICE9IDI1NSkKCXsKCSAgYWxwaGExID0gMjU1IC0gYWxwaGE7CgkgIHBbMF0gPSBkaXYyNTUoYWxwaGExICogY29sb3IwICsgYWxwaGEgKiBwWzBdKTsKCSAgcFsxXSA9IGRpdjI1NShhbHBoYTEgKiBjb2xvcjEgKyBhbHBoYSAqIHBbMV0pOwoJICBwWzJdID0gZGl2MjU1KGFscGhhMSAqIGNvbG9yMiArIGFscGhhICogcFsyXSk7Cgl9CglwICs9IDM7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgY29sb3IwID0gY29sb3JbMF07CiAgICBjb2xvcjEgPSBjb2xvclsxXTsKICAgIGNvbG9yMiA9IGNvbG9yWzJdOwogICAgZm9yICh5ID0gMDsgeSA8IGJpdG1hcC0+aGVpZ2h0OyArK3kpIHsKICAgICAgcCA9ICZiaXRtYXAtPmRhdGFbeSAqIGJpdG1hcC0+cm93U2l6ZV07CiAgICAgIHEgPSAmYml0bWFwLT5hbHBoYVt5ICogYml0bWFwLT53aWR0aF07CiAgICAgIGZvciAoeCA9IDA7IHggPCBiaXRtYXAtPndpZHRoOyArK3gpIHsKCWFscGhhID0gKnErKzsKCWlmIChhbHBoYSA9PSAwKQoJewoJICBwWzBdID0gY29sb3IwOwoJICBwWzFdID0gY29sb3IxOwoJICBwWzJdID0gY29sb3IyOwoJfQoJZWxzZSBpZiAoYWxwaGEgIT0gMjU1KQoJewoJICBhbHBoYTEgPSAyNTUgLSBhbHBoYTsKCSAgcFswXSA9IGRpdjI1NShhbHBoYTEgKiBjb2xvcjAgKyBhbHBoYSAqIHBbMF0pOwoJICBwWzFdID0gZGl2MjU1KGFscGhhMSAqIGNvbG9yMSArIGFscGhhICogcFsxXSk7CgkgIHBbMl0gPSBkaXYyNTUoYWxwaGExICogY29sb3IyICsgYWxwaGEgKiBwWzJdKTsKCX0KCXBbM10gPSAyNTU7CglwICs9IDQ7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwojaWYgU1BMQVNIX0NNWUsKICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgIGNvbG9yMCA9IGNvbG9yWzBdOwogICAgY29sb3IxID0gY29sb3JbMV07CiAgICBjb2xvcjIgPSBjb2xvclsyXTsKICAgIGNvbG9yMyA9IGNvbG9yWzNdOwogICAgZm9yICh5ID0gMDsgeSA8IGJpdG1hcC0+aGVpZ2h0OyArK3kpIHsKICAgICAgcCA9ICZiaXRtYXAtPmRhdGFbeSAqIGJpdG1hcC0+cm93U2l6ZV07CiAgICAgIHEgPSAmYml0bWFwLT5hbHBoYVt5ICogYml0bWFwLT53aWR0aF07CiAgICAgIGZvciAoeCA9IDA7IHggPCBiaXRtYXAtPndpZHRoOyArK3gpIHsKCWFscGhhID0gKnErKzsKCWlmIChhbHBoYSA9PSAwKQoJewoJICBwWzBdID0gY29sb3IwOwoJICBwWzFdID0gY29sb3IxOwoJICBwWzJdID0gY29sb3IyOwoJICBwWzNdID0gY29sb3IzOwoJfQoJZWxzZSBpZiAoYWxwaGEgIT0gMjU1KQoJewoJICBhbHBoYTEgPSAyNTUgLSBhbHBoYTsKCSAgcFswXSA9IGRpdjI1NShhbHBoYTEgKiBjb2xvcjAgKyBhbHBoYSAqIHBbMF0pOwoJICBwWzFdID0gZGl2MjU1KGFscGhhMSAqIGNvbG9yMSArIGFscGhhICogcFsxXSk7CgkgIHBbMl0gPSBkaXYyNTUoYWxwaGExICogY29sb3IyICsgYWxwaGEgKiBwWzJdKTsKICAgIHBbM10gPSBkaXYyNTUoYWxwaGExICogY29sb3IzICsgYWxwaGEgKiBwWzNdKTsKCX0KCXAgKz0gNDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICBmb3IgKGNwID0gMDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgICBjb2xvcnNwW2NwXSA9IGNvbG9yW2NwXTsKICAgIGZvciAoeSA9IDA7IHkgPCBiaXRtYXAtPmhlaWdodDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhW3kgKiBiaXRtYXAtPnJvd1NpemVdOwogICAgICBxID0gJmJpdG1hcC0+YWxwaGFbeSAqIGJpdG1hcC0+d2lkdGhdOwogICAgICBmb3IgKHggPSAwOyB4IDwgYml0bWFwLT53aWR0aDsgKyt4KSB7CglhbHBoYSA9ICpxKys7CglpZiAoYWxwaGEgPT0gMCkKCXsKICAgIGZvciAoY3AgPSAwOyBjcCA8IFNQT1RfTkNPTVBTKzQ7IGNwKyspCiAgICAgIHBbY3BdID0gY29sb3JzcFtjcF07Cgl9CgllbHNlIGlmIChhbHBoYSAhPSAyNTUpCgl7CgkgIGFscGhhMSA9IDI1NSAtIGFscGhhOwogICAgZm9yIChjcCA9IDA7IGNwIDwgU1BPVF9OQ09NUFMrNDsgY3ArKykKICAgICAgcFtjcF0gPSBkaXYyNTUoYWxwaGExICogY29sb3JzcFtjcF0gKyBhbHBoYSAqIHBbY3BdKTsKCX0KCXAgKz0gKFNQT1RfTkNPTVBTKzQpOwogICAgICB9CiAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgfQogIG1lbXNldChiaXRtYXAtPmFscGhhLCAyNTUsIGJpdG1hcC0+d2lkdGggKiBiaXRtYXAtPmhlaWdodCk7Cn0KCkdCb29sIFNwbGFzaDo6Z291cmF1ZFRyaWFuZ2xlU2hhZGVkRmlsbChTcGxhc2hHb3VyYXVkQ29sb3IgKnNoYWRpbmcpCnsKICBkb3VibGUgeGRibFszXSA9IHswLiwgMC4sIDAufTsKICBkb3VibGUgeWRibFszXSA9IHswLiwgMC4sIDAufTsKICBpbnQgICAgeFszXSA9IHswLCAwLCAwfTsKICBpbnQgICAgeVszXSA9IHswLCAwLCAwfTsKICBkb3VibGUgeHQ9MC4sIHhhPTAuLCB5dD0wLjsKICBkb3VibGUgY2E9MC4sIGN0PTAuOwoKICAvLyB0cmlhbmdsZSBpbnRlcnBvbGF0aW9uOgogIC8vCiAgZG91YmxlIHNjYW5MaW1pdE1hcExbMl0gPSB7MC4sIDAufTsKICBkb3VibGUgc2NhbkxpbWl0TWFwUlsyXSA9IHswLiwgMC59OwogIGRvdWJsZSBzY2FuQ29sb3JNYXBMWzJdID0gezAuLCAwLn07CiAgZG91YmxlIHNjYW5Db2xvck1hcFJbMl0gPSB7MC4sIDAufTsKICBkb3VibGUgc2NhbkNvbG9yTWFwWzJdID0gezAuLCAwLn07CiAgaW50IHNjYW5FZGdlTFsyXSA9IHsgMCwgMCB9OwogIGludCBzY2FuRWRnZVJbMl0gPSB7IDAsIDAgfTsKICBHQm9vbCBoYXNGdXJ0aGVyU2VnbWVudCA9IGdGYWxzZTsKCiAgaW50IHNjYW5MaW5lT2ZmID0gMDsKICBpbnQgYml0bWFwT2ZmID0gMDsKICBpbnQgc2NhbkxpbWl0UiA9IDAsIHNjYW5MaW1pdEwgPSAwOwoKICBpbnQgYml0bWFwV2lkdGggPSBiaXRtYXAtPmdldFdpZHRoKCk7CiAgU3BsYXNoQ2xpcCogY2xpcCA9IGdldENsaXAoKTsKICBTcGxhc2hCaXRtYXAgKmJsaXRUYXJnZXQgPSBiaXRtYXA7CiAgU3BsYXNoQ29sb3JQdHIgYml0bWFwRGF0YSA9IGJpdG1hcC0+Z2V0RGF0YVB0cigpOwogIFNwbGFzaENvbG9yUHRyIGJpdG1hcEFscGhhID0gYml0bWFwLT5nZXRBbHBoYVB0cigpOwogIFNwbGFzaENvbG9yUHRyIGN1ciA9IE5VTEw7CiAgU3BsYXNoQ29vcmQqIHVzZXJUb0NhbnZhc01hdHJpeCA9IGdldE1hdHJpeCgpOwogIFNwbGFzaENvbG9yTW9kZSBiaXRtYXBNb2RlID0gYml0bWFwLT5nZXRNb2RlKCk7CiAgR0Jvb2wgaGFzQWxwaGEgPSAoYml0bWFwQWxwaGEgIT0gTlVMTCk7CiAgaW50IHJvd1NpemUgPSBiaXRtYXAtPmdldFJvd1NpemUoKTsKICBpbnQgY29sb3JDb21wcyA9IDA7CiAgc3dpdGNoIChiaXRtYXBNb2RlKSB7CiAgICBjYXNlIHNwbGFzaE1vZGVNb25vMToKICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlTW9ubzg6CiAgICAgIGNvbG9yQ29tcHM9MTsKICAgIGJyZWFrOwogICAgY2FzZSBzcGxhc2hNb2RlUkdCODoKICAgICAgY29sb3JDb21wcz0zOwogICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVCR1I4OgogICAgICBjb2xvckNvbXBzPTM7CiAgICBicmVhazsKICAgIGNhc2Ugc3BsYXNoTW9kZVhCR1I4OgogICAgICBjb2xvckNvbXBzPTQ7CiAgICBicmVhazsKI2lmIFNQTEFTSF9DTVlLCiAgICBjYXNlIHNwbGFzaE1vZGVDTVlLODoKICAgICAgY29sb3JDb21wcz00OwogICAgYnJlYWs7CiAgICBjYXNlIHNwbGFzaE1vZGVEZXZpY2VOODoKICAgICAgY29sb3JDb21wcz1TUE9UX05DT01QUys0OwogICAgYnJlYWs7CiNlbmRpZgogIH0KCiAgU3BsYXNoUGlwZSBwaXBlOwogIFNwbGFzaENvbG9yIGNTcmNWYWw7CgogIHBpcGVJbml0KCZwaXBlLCAwLCAwLCBOVUxMLCBjU3JjVmFsLCAoR3VjaGFyKXNwbGFzaFJvdW5kKHN0YXRlLT5zdHJva2VBbHBoYSAqIDI1NSksIGdGYWxzZSwgZ0ZhbHNlKTsKCiAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgaWYgKGFhQnVmID09IE5VTEwpCiAgICAgIHJldHVybiBnRmFsc2U7IC8vIGZhbGwgYmFjayB0byBvbGQgYmVoYXZpb3VyCiAgICBkcmF3QUFQaXhlbEluaXQoKTsKICB9CgogIC8vIGlkZWE6CiAgLy8gMS4gSWYgcGlwZS0+bm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5ibGVuZEZ1bmMKICAvLyAgLT4gYmxpdCBkaXJlY3RseSBpbnRvIHRoZSBkcmF3aW5nIHN1cmZhY2UhCiAgLy8gIC0+IGRpc2FibGUgYWxwaGEgbWFudWFsbHkuCiAgLy8gMi4gT3RoZXJ3aXNlOgogIC8vIC0gYmxpdCBhbHNvIGRpcmVjdGx5LCBidXQgaW50byBhbiBpbnRlcm1lZGlhdGUgc3VyZmFjZS4KICAvLyBBZnRlcndhcmRzLCBibGl0IHRoZSBpbnRlcm1lZGlhdGUgc3VyZmFjZSB1c2luZyB0aGUgZHJhd2luZyBwaXBlbGluZS4KICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRyaWFuZ2xlIGVsZW1lbnRzIGNhbiBiZSBvbiB0b3Agb2YgZWFjaAogIC8vIG90aGVyLCBzbyB0aGUgY29tcGxldGUgc2hhZGluZyBuZWVkcyB0byBiZSBkcmF3biBiZWZvcmUgb3BhY2l0eSBpcwogIC8vIGFwcGxpZWQuCiAgLy8gLSB0aGUgZmluYWwgc3RlcCwgaXMgcGVyZm9ybWVkIHVzaW5nIGEgU3BsYXNoUGlwZToKICAvLyAtIGFzc2lnbiB0aGUgYWN0dWFsIGNvbG9yIGludG8gY1NyY1ZhbDogcGlwZSB1c2VzIGNTcmNWYWwgYnkgcmVmZXJlbmNlCiAgLy8gLSBpbnZva2UgZHJhd1BpeGVsKCZwaXBlLFgsWSxiTm9DbGlwKTsKICBHQm9vbCBiRGlyZWN0QmxpdCA9IHZlY3RvckFudGlhbGlhcyA/IGdGYWxzZSA6IHBpcGUubm9UcmFuc3BhcmVuY3kgJiYgIXN0YXRlLT5ibGVuZEZ1bmM7CiAgaWYgKCFiRGlyZWN0QmxpdCkgewogICAgYmxpdFRhcmdldCA9IG5ldyBTcGxhc2hCaXRtYXAoYml0bWFwLT5nZXRXaWR0aCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYml0bWFwLT5nZXRIZWlnaHQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdG1hcC0+Z2V0Um93UGFkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRtYXAtPmdldE1vZGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdUcnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYml0bWFwLT5nZXRSb3dTaXplKCkgPj0gMCk7CiAgICBiaXRtYXBEYXRhID0gYmxpdFRhcmdldC0+Z2V0RGF0YVB0cigpOwogICAgYml0bWFwQWxwaGEgPSBibGl0VGFyZ2V0LT5nZXRBbHBoYVB0cigpOwoKICAgIC8vIGluaXRpYWxpc2F0aW9uIHNlZW1zIHRvIGJlIG5lY2Vzc2FyeToKICAgIGludCBTID0gYml0bWFwLT5nZXRXaWR0aCgpICogYml0bWFwLT5nZXRIZWlnaHQoKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgUzsgKytpKQogICAgICBiaXRtYXBBbHBoYVtpXSA9IDA7CiAgICBoYXNBbHBoYSA9IGdUcnVlOwogIH0KCiAgaWYgKHNoYWRpbmctPmlzUGFyYW1ldGVyaXplZCgpKSB7CiAgICBkb3VibGUgY29sb3JbM107CiAgICBkb3VibGUgY29sb3JpbnRlcnA7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaGFkaW5nLT5nZXROVHJpYW5nbGVzKCk7ICsraSkgewogICAgICBzaGFkaW5nLT5nZXRUcmlhbmdsZShpLAogICAgICAgICAgICAgICAgICAgICAgICAgICB4ZGJsICsgMCwgeWRibCArIDAsIGNvbG9yICsgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeGRibCArIDEsIHlkYmwgKyAxLCBjb2xvciArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhkYmwgKyAyLCB5ZGJsICsgMiwgY29sb3IgKyAyKTsKICAgICAgZm9yIChpbnQgbSA9IDA7IG0gPCAzOyArK20pIHsKICAgICAgICB4dCA9IHhkYmxbbV0gKiAoZG91YmxlKXVzZXJUb0NhbnZhc01hdHJpeFswXSArIHlkYmxbbV0gKiAoZG91YmxlKXVzZXJUb0NhbnZhc01hdHJpeFsyXSArIChkb3VibGUpdXNlclRvQ2FudmFzTWF0cml4WzRdOwogICAgICAgIHl0ID0geGRibFttXSAqIChkb3VibGUpdXNlclRvQ2FudmFzTWF0cml4WzFdICsgeWRibFttXSAqIChkb3VibGUpdXNlclRvQ2FudmFzTWF0cml4WzNdICsgKGRvdWJsZSl1c2VyVG9DYW52YXNNYXRyaXhbNV07CiAgICAgICAgeGRibFttXSA9IHh0OwogICAgICAgIHlkYmxbbV0gPSB5dDsKICAgICAgICAvLyB3ZSBvcGVyYXRlIG9uIHNjYW5saW5lcyB3aGljaCBhcmUgaW50ZWdlciBvZmZzZXRzIGludG8gdGhlCiAgICAgICAgLy8gcmFzdGVyIGltYWdlLiBUaGUgZG91YmxlIG9mZnNldHMgYXJlIG9mIG5vIHVzZSBoZXJlLgogICAgICAgIHhbbV0gPSBzcGxhc2hSb3VuZCh4dCk7CiAgICAgICAgeVttXSA9IHNwbGFzaFJvdW5kKHl0KTsKICAgICAgfQogICAgICAvLyBzb3J0IGFjY29yZGluZyB0byB5IGNvb3JkaW5hdGUgdG8gc2ltcGxpZnkgc3dlZXAgdGhyb3VnaCBzY2FubGluZXM6CiAgICAgIC8vIElOU0VSVElPTiBTT1JULgogICAgICBpZiAoeVswXSA+IHlbMV0pIHsKICAgICAgICBHdXN3YXAoeFswXSwgeFsxXSk7CiAgICAgICAgR3Vzd2FwKHlbMF0sIHlbMV0pOwogICAgICAgIEd1c3dhcChjb2xvclswXSwgY29sb3JbMV0pOwogICAgICB9CiAgICAgIC8vIGZpcnN0IHR3byBhcmUgc29ydGVkLgogICAgICBhc3NlcnQoeVswXSA8PSB5WzFdKTsKICAgICAgaWYgKHlbMV0gPiB5WzJdKSB7CiAgICAgICAgaW50IHRtcFggPSB4WzJdOwogICAgICAgIGludCB0bXBZID0geVsyXTsKICAgICAgICBkb3VibGUgdG1wQyA9IGNvbG9yWzJdOwogICAgICAgIHhbMl0gPSB4WzFdOyB5WzJdID0geVsxXTsgY29sb3JbMl0gPSBjb2xvclsxXTsKCiAgICAgICAgaWYgKHlbMF0gPiB0bXBZKSB7CiAgICAgICAgICB4WzFdID0geFswXTsgeVsxXSA9IHlbMF07IGNvbG9yWzFdID0gY29sb3JbMF07CiAgICAgICAgICB4WzBdID0gdG1wWDsgeVswXSA9IHRtcFk7IGNvbG9yWzBdID0gdG1wQzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgeFsxXSA9IHRtcFg7IHlbMV0gPSB0bXBZOyBjb2xvclsxXSA9IHRtcEM7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGZpcnN0IHRocmVlIGFyZSBzb3J0ZWQKICAgICAgYXNzZXJ0KHlbMF0gPD0geVsxXSk7CiAgICAgIGFzc2VydCh5WzFdIDw9IHlbMl0pOwogICAgICAvLy8vLwoKICAgICAgLy8gdGhpcyBoZXJlIGlzIGRldCggVCApID09IDAKICAgICAgLy8gd2hlcmUgVCBpcyB0aGUgbWF0cml4IHRvIG1hcCB0byBiYXJ5Y2VudHJpYyBjb29yZGluYXRlcy4KICAgICAgaWYgKCh4WzBdIC0geFsyXSkgKiAoeVsxXSAtIHlbMl0pIC0gKHhbMV0gLSB4WzJdKSAqICh5WzBdIC0geVsyXSkgPT0gMCkKICAgICAgICBjb250aW51ZTsgLy8gZGVnZW5lcmF0ZSB0cmlhbmdsZS4KCiAgICAgIC8vIHRoaXMgaGVyZSBpbml0aWFsaXNlcyB0aGUgc2NhbmxpbmUgZ2VuZXJhdGlvbi4KICAgICAgLy8gV2Ugc3RhcnQgd2l0aCBsb3cgWSBjb29yZGluYXRlcyBhbmQgc3dlZXAgdXAgdG8gdGhlIGxhcmdlIFkKICAgICAgLy8gY29vcmRpbmF0ZXMuCiAgICAgIC8vCiAgICAgIC8vIHNjYW5FZGdlTFttXSBpbiB7MCwxLDJ9IG09MCwxCiAgICAgIC8vIHNjYW5FZGdlUlttXSBpbiB7MCwxLDJ9IG09MCwxCiAgICAgIC8vCiAgICAgIC8vIGFyZSB0aGUgdHdvIGVkZ2VzIGJldHdlZW4gd2hpY2ggc2NhbmxpbmVzIGFyZSAoY3VycmVudGx5KQogICAgICAvLyBzd2VlcGVkLiBUaGUgdmFsdWVzIHswLDEsMn0gYXJlIGluZGljZXMgaW50byAneCcgYW5kICd5Jy4KICAgICAgLy8gc2NhbkVkZ2VMWzBdID0gMCBtZWFuczogdGhlIGxlZnQgc2NhbiBlZGdlIGhhcyAoeFswXSx5WzBdKSBhcyB2ZXJ0ZXguCiAgICAgIC8vCiAgICAgIHNjYW5FZGdlTFswXSA9IDA7CiAgICAgIHNjYW5FZGdlUlswXSA9IDA7CiAgICAgIGlmICh5WzBdID09IHlbMV0pIHsKICAgICAgICBzY2FuRWRnZUxbMF0gPSAxOwogICAgICAgIHNjYW5FZGdlTFsxXSA9IHNjYW5FZGdlUlsxXSA9IDI7CgogICAgICB9IGVsc2UgewogICAgICAgIHNjYW5FZGdlTFsxXSA9IDE7IHNjYW5FZGdlUlsxXSA9IDI7CiAgICAgIH0KICAgICAgYXNzZXJ0KHlbc2NhbkVkZ2VMWzBdXSA8IHlbc2NhbkVkZ2VMWzFdXSk7CiAgICAgIGFzc2VydCh5W3NjYW5FZGdlUlswXV0gPCB5W3NjYW5FZGdlUlsxXV0pOwoKICAgICAgLy8gT2suIE5vdyBwcmVwYXJlIHRoZSBsaW5lYXIgbWFwcyB3aGljaCBtYXAgdGhlIHkgY29vcmRpbmF0ZSBvZgogICAgICAvLyB0aGUgY3VycmVudCBzY2FubGluZSB0byB0aGUgY29ycmVzcG9uZGluZyBMRUZUIGFuZCBSSUdIVCB4CiAgICAgIC8vIGNvb3JkaW5hdGUgKHdoaWNoIGRlZmluZSB0aGUgc2NhbmxpbmUpLgogICAgICBzY2FuTGltaXRNYXBMWzBdID0gZG91YmxlKHhbc2NhbkVkZ2VMWzFdXSAtIHhbc2NhbkVkZ2VMWzBdXSkgLyAoeVtzY2FuRWRnZUxbMV1dIC0geVtzY2FuRWRnZUxbMF1dKTsKICAgICAgc2NhbkxpbWl0TWFwTFsxXSA9IHhbc2NhbkVkZ2VMWzBdXSAtIHlbc2NhbkVkZ2VMWzBdXSAqIHNjYW5MaW1pdE1hcExbMF07CiAgICAgIHNjYW5MaW1pdE1hcFJbMF0gPSBkb3VibGUoeFtzY2FuRWRnZVJbMV1dIC0geFtzY2FuRWRnZVJbMF1dKSAvICh5W3NjYW5FZGdlUlsxXV0gLSB5W3NjYW5FZGdlUlswXV0pOwogICAgICBzY2FuTGltaXRNYXBSWzFdID0geFtzY2FuRWRnZVJbMF1dIC0geVtzY2FuRWRnZVJbMF1dICogc2NhbkxpbWl0TWFwUlswXTsKCiAgICAgIHhhID0geVsxXSAqIHNjYW5MaW1pdE1hcExbMF0gKyBzY2FuTGltaXRNYXBMWzFdOwogICAgICB4dCA9IHlbMV0gKiBzY2FuTGltaXRNYXBSWzBdICsgc2NhbkxpbWl0TWFwUlsxXTsKICAgICAgaWYgKHhhID4geHQpIHsKICAgICAgICAvLyBJIGhhdmUgImxlZnQiIGlzIHRvIHRoZSByaWdodCBvZiAicmlnaHQiLgogICAgICAgIC8vIEV4Y2hhbmdlIHNpZGVzIQogICAgICAgIEd1c3dhcChzY2FuRWRnZUxbMF0sIHNjYW5FZGdlUlswXSk7CiAgICAgICAgR3Vzd2FwKHNjYW5FZGdlTFsxXSwgc2NhbkVkZ2VSWzFdKTsKICAgICAgICBHdXN3YXAoc2NhbkxpbWl0TWFwTFswXSwgc2NhbkxpbWl0TWFwUlswXSk7CiAgICAgICAgR3Vzd2FwKHNjYW5MaW1pdE1hcExbMV0sIHNjYW5MaW1pdE1hcFJbMV0pOwogICAgICAgIC8vIEZJWE1FIEknbSBzdXJlIHRoZXJlIGlzIGEgbW9yZSBlZmZpY2llbnQgd2F5IHRvIGNoZWNrIHRoaXMuCiAgICAgIH0KCiAgICAgIC8vIFNhbWUgZ2FtZTogd2UgY2FuIGxpbmVhcmx5IGludGVycG9sYXRlIHRoZSBjb2xvciBiYXNlZCBvbiB0aGUKICAgICAgLy8gY3VycmVudCB5IGNvb3JkaW5hdGUgKHRoYXQncyBjb3JyZWN0IGZvciB0cmlhbmdsZQogICAgICAvLyBpbnRlcnBvbGF0aW9uIGR1ZSB0byBsaW5lYXJpdHkuIFdlIGNvdWxkIGFsc28gaGF2ZSBkb25lIGl0IGluCiAgICAgIC8vIGJhcnljZW50cmljIGNvb3JkaW5hdGVzLCBidXQgdGhhdCdzIHNsaWdodGx5IG1vcmUgaW52b2x2ZWQpCiAgICAgIHNjYW5Db2xvck1hcExbMF0gPSAoY29sb3Jbc2NhbkVkZ2VMWzFdXSAtIGNvbG9yW3NjYW5FZGdlTFswXV0pIC8gKHlbc2NhbkVkZ2VMWzFdXSAtIHlbc2NhbkVkZ2VMWzBdXSk7CiAgICAgIHNjYW5Db2xvck1hcExbMV0gPSBjb2xvcltzY2FuRWRnZUxbMF1dIC0geVtzY2FuRWRnZUxbMF1dICogc2NhbkNvbG9yTWFwTFswXTsKICAgICAgc2NhbkNvbG9yTWFwUlswXSA9IChjb2xvcltzY2FuRWRnZVJbMV1dIC0gY29sb3Jbc2NhbkVkZ2VSWzBdXSkgLyAoeVtzY2FuRWRnZVJbMV1dIC0geVtzY2FuRWRnZVJbMF1dKTsKICAgICAgc2NhbkNvbG9yTWFwUlsxXSA9IGNvbG9yW3NjYW5FZGdlUlswXV0gLSB5W3NjYW5FZGdlUlswXV0gKiBzY2FuQ29sb3JNYXBSWzBdOwoKICAgICAgaGFzRnVydGhlclNlZ21lbnQgPSAoeVsxXSA8IHlbMl0pOwogICAgICBzY2FuTGluZU9mZiA9IHlbMF0gKiByb3dTaXplOwoKICAgICAgZm9yIChpbnQgWSA9IHlbMF07IFkgPD0geVsyXTsgKytZLCBzY2FuTGluZU9mZiArPSByb3dTaXplKSB7CiAgICAgICAgaWYgKGhhc0Z1cnRoZXJTZWdtZW50ICYmIFkgPT0geVsxXSkgewogICAgICAgICAgLy8gU1dFRVAgRVZFTlQ6IHdlIGVuY291bnRlcmVkIHRoZSBuZXh0IHNlZ21lbnQuCiAgICAgICAgICAvLwogICAgICAgICAgLy8gc3dpdGNoIHRvIG5leHQgc2VnbWVudCwgZWl0aGVyIGF0IGxlZnQgZW5kIG9yIGF0IHJpZ2h0CiAgICAgICAgICAvLyBlbmQ6CiAgICAgICAgICBpZiAoc2NhbkVkZ2VMWzFdID09IDEpIHsKICAgICAgICAgICAgc2NhbkVkZ2VMWzBdID0gMTsKICAgICAgICAgICAgc2NhbkVkZ2VMWzFdID0gMjsKICAgICAgICAgICAgc2NhbkxpbWl0TWFwTFswXSA9IGRvdWJsZSh4W3NjYW5FZGdlTFsxXV0gLSB4W3NjYW5FZGdlTFswXV0pIC8gKHlbc2NhbkVkZ2VMWzFdXSAtIHlbc2NhbkVkZ2VMWzBdXSk7CiAgICAgICAgICAgIHNjYW5MaW1pdE1hcExbMV0gPSB4W3NjYW5FZGdlTFswXV0gLSB5W3NjYW5FZGdlTFswXV0gKiBzY2FuTGltaXRNYXBMWzBdOwoKICAgICAgICAgICAgc2NhbkNvbG9yTWFwTFswXSA9IChjb2xvcltzY2FuRWRnZUxbMV1dIC0gY29sb3Jbc2NhbkVkZ2VMWzBdXSkgLyAoeVtzY2FuRWRnZUxbMV1dIC0geVtzY2FuRWRnZUxbMF1dKTsKICAgICAgICAgICAgc2NhbkNvbG9yTWFwTFsxXSA9IGNvbG9yW3NjYW5FZGdlTFswXV0gLSB5W3NjYW5FZGdlTFswXV0gKiBzY2FuQ29sb3JNYXBMWzBdOwogICAgICAgICAgfSBlbHNlIGlmIChzY2FuRWRnZVJbMV0gPT0gMSkgewogICAgICAgICAgICBzY2FuRWRnZVJbMF0gPSAxOwogICAgICAgICAgICBzY2FuRWRnZVJbMV0gPSAyOwogICAgICAgICAgICBzY2FuTGltaXRNYXBSWzBdID0gZG91YmxlKHhbc2NhbkVkZ2VSWzFdXSAtIHhbc2NhbkVkZ2VSWzBdXSkgLyAoeVtzY2FuRWRnZVJbMV1dIC0geVtzY2FuRWRnZVJbMF1dKTsKICAgICAgICAgICAgc2NhbkxpbWl0TWFwUlsxXSA9IHhbc2NhbkVkZ2VSWzBdXSAtIHlbc2NhbkVkZ2VSWzBdXSAqIHNjYW5MaW1pdE1hcFJbMF07CgogICAgICAgICAgICBzY2FuQ29sb3JNYXBSWzBdID0gKGNvbG9yW3NjYW5FZGdlUlsxXV0gLSBjb2xvcltzY2FuRWRnZVJbMF1dKSAvICh5W3NjYW5FZGdlUlsxXV0gLSB5W3NjYW5FZGdlUlswXV0pOwogICAgICAgICAgICBzY2FuQ29sb3JNYXBSWzFdID0gY29sb3Jbc2NhbkVkZ2VSWzBdXSAtIHlbc2NhbkVkZ2VSWzBdXSAqIHNjYW5Db2xvck1hcFJbMF07CiAgICAgICAgICB9CiAgICAgICAgICBhc3NlcnQoIHlbc2NhbkVkZ2VMWzBdXSAgPCAgeVtzY2FuRWRnZUxbMV1dICk7CiAgICAgICAgICBhc3NlcnQoIHlbc2NhbkVkZ2VSWzBdXSA8ICB5W3NjYW5FZGdlUlsxXV0gKTsKICAgICAgICAgIGhhc0Z1cnRoZXJTZWdtZW50ID0gZ0ZhbHNlOwogICAgICAgIH0KCiAgICAgICAgeXQgPSBZOwoKICAgICAgICB4YSA9IHl0ICogc2NhbkxpbWl0TWFwTFswXSArIHNjYW5MaW1pdE1hcExbMV07CiAgICAgICAgeHQgPSB5dCAqIHNjYW5MaW1pdE1hcFJbMF0gKyBzY2FuTGltaXRNYXBSWzFdOwoKICAgICAgICBjYSA9IHl0ICogc2NhbkNvbG9yTWFwTFswXSArIHNjYW5Db2xvck1hcExbMV07CiAgICAgICAgY3QgPSB5dCAqIHNjYW5Db2xvck1hcFJbMF0gKyBzY2FuQ29sb3JNYXBSWzFdOwoKICAgICAgICBzY2FuTGltaXRMID0gc3BsYXNoUm91bmQoeGEpOwogICAgICAgIHNjYW5MaW1pdFIgPSBzcGxhc2hSb3VuZCh4dCk7CgogICAgICAgIC8vIE9rLiBOb3c6IGluaXQgdGhlIGNvbG9yIGludGVycG9sYXRpb24gZGVwZW5kaW5nIG9uIHRoZSBYCiAgICAgICAgLy8gY29vcmRpbmF0ZSBpbnNpZGUgb2YgdGhlIGN1cnJlbnQgc2NhbmxpbmU6CiAgICAgICAgc2NhbkNvbG9yTWFwWzBdID0gKHNjYW5MaW1pdFIgPT0gc2NhbkxpbWl0TCkgPyAwLiA6ICgoY3QgLSBjYSkgLyAoc2NhbkxpbWl0UiAtIHNjYW5MaW1pdEwpKTsKICAgICAgICBzY2FuQ29sb3JNYXBbMV0gPSBjYSAtIHNjYW5MaW1pdEwgKiBzY2FuQ29sb3JNYXBbMF07CgogICAgICAgIC8vIGhhbmRsZWQgYnkgY2xpcHBpbmc6CiAgICAgICAgLy8gYXNzZXJ0KCBzY2FuTGltaXRMID49IDAgJiYgc2NhbkxpbWl0UiA8IGJpdG1hcC0+Z2V0V2lkdGgoKSApOwogICAgICAgIGFzc2VydChzY2FuTGltaXRMIDw9IHNjYW5MaW1pdFIgfHwgYWJzKHNjYW5MaW1pdEwgLSBzY2FuTGltaXRSKSA8PSAyKTsgLy8gYWxsb3cgcm91bmRpbmcgaW5hY2N1cmFjaWVzCiAgICAgICAgYXNzZXJ0KHNjYW5MaW5lT2ZmID09IFkgKiByb3dTaXplKTsKCiAgICAgICAgY29sb3JpbnRlcnAgPSBzY2FuQ29sb3JNYXBbMF0gKiBzY2FuTGltaXRMICsgc2NhbkNvbG9yTWFwWzFdOwoKICAgICAgICBiaXRtYXBPZmYgPSBzY2FuTGluZU9mZiArIHNjYW5MaW1pdEwgKiBjb2xvckNvbXBzOwogICAgICAgIGZvciAoaW50IFggPSBzY2FuTGltaXRMOyBYIDw9IHNjYW5MaW1pdFI7ICsrWCwgY29sb3JpbnRlcnAgKz0gc2NhbkNvbG9yTWFwWzBdLCBiaXRtYXBPZmYgKz0gY29sb3JDb21wcykgewogICAgICAgICAgLy8gRklYTUUgOiBzdGFuZGFyZCByZWN0YW5ndWxhciBjbGlwcGluZyBjYW4gYmUgZG9uZSBmb3IgYQogICAgICAgICAgLy8gY29tcGxldGUgc2NhbmxpbmUgd2hpY2ggaXMgZmFzdGVyCiAgICAgICAgICAvLyAtLT4gc2VlIFNwbGFzaENsaXAgYW5kIGl0cyBtZXRob2RzCiAgICAgICAgICBpZiAoIWNsaXAtPnRlc3QoWCwgWSkpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgIGFzc2VydChmYWJzKGNvbG9yaW50ZXJwIC0gKHNjYW5Db2xvck1hcFswXSAqIFggKyBzY2FuQ29sb3JNYXBbMV0pKSA8IDFlLTEwKTsKICAgICAgICAgIGFzc2VydChiaXRtYXBPZmYgPT0gWSAqIHJvd1NpemUgKyBjb2xvckNvbXBzICogWCAmJiBzY2FuTGluZU9mZiA9PSBZICogcm93U2l6ZSk7CgogICAgICAgICAgc2hhZGluZy0+Z2V0UGFyYW1ldGVyaXplZENvbG9yKGNvbG9yaW50ZXJwLCBiaXRtYXBNb2RlLCAmYml0bWFwRGF0YVtiaXRtYXBPZmZdKTsKCiAgICAgICAgICAvLyBtYWtlIHRoZSBzaGFkaW5nIHZpc2libGUuCiAgICAgICAgICAvLyBOb3RlIHRoYXQgb3BhY2l0eSBpcyBoYW5kbGVkIGJ5IHRoZSBiRGlyZWN0QmxpdCBzdHVmZiwgc2VlCiAgICAgICAgICAvLyBhYm92ZSBmb3IgY29tbWVudHMgYW5kIGJlbG93IGZvciBpbXBsZW1lbnRhdGlvbi4KICAgICAgICAgIGlmIChoYXNBbHBoYSkKICAgICAgICAgICAgYml0bWFwQWxwaGFbWSAqIGJpdG1hcFdpZHRoICsgWF0gPSAyNTU7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIHJldHVybiBnRmFsc2U7CiAgfQoKICBpZiAoIWJEaXJlY3RCbGl0KSB7CiAgICAvLyBvay4gRmluYWxpemUgdGhlIHN0dWZmIGJ5IGJsaXR0aW5nIHRoZSBzaGFkaW5nIGludG8gdGhlIGZpbmFsCiAgICAvLyBnZW9tZXRyeSwgdGhpcyB0aW1lIHJlc3BlY3RpbmcgdGhlIHJlbmRlcmluZyBwaXBlLgogICAgaW50IFcgPSBibGl0VGFyZ2V0LT5nZXRXaWR0aCgpOwogICAgaW50IEggPSBibGl0VGFyZ2V0LT5nZXRIZWlnaHQoKTsKICAgIGN1ciA9IGNTcmNWYWw7CgogICAgZm9yIChpbnQgWCA9IDA7IFggPCBXOyArK1gpIHsKICAgICAgZm9yIChpbnQgWSA9IDA7IFkgPCBIOyArK1kpIHsKICAgICAgICBpZiAoIWJpdG1hcEFscGhhW1kgKiBiaXRtYXBXaWR0aCArIFhdKQogICAgICAgICAgY29udGludWU7IC8vIGRyYXcgb25seSBwYXJ0cyBvZiB0aGUgc2hhZGluZyEKICAgICAgICBiaXRtYXBPZmYgPSBZICogcm93U2l6ZSArIGNvbG9yQ29tcHMgKiBYOwoKICAgICAgICBmb3IgKGludCBtID0gMDsgbSA8IGNvbG9yQ29tcHM7ICsrbSkKICAgICAgICAgIGN1clttXSA9IGJpdG1hcERhdGFbYml0bWFwT2ZmICsgbV07CiAgICAgICAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgICAgICAgZHJhd0FBUGl4ZWwoJnBpcGUsIFgsIFkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkcmF3UGl4ZWwoJnBpcGUsIFgsIFksIGdUcnVlKTsgLy8gbm8gY2xpcHBpbmcgLSBoYXMgYWxyZWFkeSBiZWVuIGRvbmUuCiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGVsZXRlIGJsaXRUYXJnZXQ7CiAgICBibGl0VGFyZ2V0ID0gTlVMTDsKICB9CgogIHJldHVybiBnVHJ1ZTsKfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpibGl0VHJhbnNwYXJlbnQoU3BsYXNoQml0bWFwICpzcmMsIGludCB4U3JjLCBpbnQgeVNyYywKCQkJCSAgICBpbnQgeERlc3QsIGludCB5RGVzdCwgaW50IHcsIGludCBoKSB7CiAgU3BsYXNoQ29sb3JQdHIgcCwgc3A7CiAgR3VjaGFyICpxOwogIGludCB4LCB5LCBtYXNrLCBzcmNNYXNrOwoKICBpZiAoc3JjLT5tb2RlICE9IGJpdG1hcC0+bW9kZSkgewogICAgcmV0dXJuIHNwbGFzaEVyck1vZGVNaXNtYXRjaDsKICB9CgogIHN3aXRjaCAoYml0bWFwLT5tb2RlKSB7CiAgY2FzZSBzcGxhc2hNb2RlTW9ubzE6CiAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhWyh5RGVzdCArIHkpICogYml0bWFwLT5yb3dTaXplICsgKHhEZXN0ID4+IDMpXTsKICAgICAgbWFzayA9IDB4ODAgPj4gKHhEZXN0ICYgNyk7CiAgICAgIHNwID0gJnNyYy0+ZGF0YVsoeVNyYyArIHkpICogc3JjLT5yb3dTaXplICsgKHhTcmMgPj4gMyldOwogICAgICBzcmNNYXNrID0gMHg4MCA+PiAoeFNyYyAmIDcpOwogICAgICBmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CglpZiAoKnNwICYgc3JjTWFzaykgewoJICAqcCB8PSBtYXNrOwoJfSBlbHNlIHsKCSAgKnAgJj0gfm1hc2s7Cgl9CglpZiAoIShtYXNrID4+PSAxKSkgewoJICBtYXNrID0gMHg4MDsKCSAgKytwOwoJfQoJaWYgKCEoc3JjTWFzayA+Pj0gMSkpIHsKCSAgc3JjTWFzayA9IDB4ODA7CgkgICsrc3A7Cgl9CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2Ugc3BsYXNoTW9kZU1vbm84OgogICAgZm9yICh5ID0gMDsgeSA8IGg7ICsreSkgewogICAgICBwID0gJmJpdG1hcC0+ZGF0YVsoeURlc3QgKyB5KSAqIGJpdG1hcC0+cm93U2l6ZSArIHhEZXN0XTsKICAgICAgc3AgPSAmc3JjLT5kYXRhWyh5U3JjICsgeSkgKiBiaXRtYXAtPnJvd1NpemUgKyB4U3JjXTsKICAgICAgZm9yICh4ID0gMDsgeCA8IHc7ICsreCkgewoJKnArKyA9ICpzcCsrOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIHNwbGFzaE1vZGVSR0I4OgogIGNhc2Ugc3BsYXNoTW9kZUJHUjg6CiAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhWyh5RGVzdCArIHkpICogYml0bWFwLT5yb3dTaXplICsgMyAqIHhEZXN0XTsKICAgICAgc3AgPSAmc3JjLT5kYXRhWyh5U3JjICsgeSkgKiBzcmMtPnJvd1NpemUgKyAzICogeFNyY107CiAgICAgIGZvciAoeCA9IDA7IHggPCB3OyArK3gpIHsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlWEJHUjg6CiAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhWyh5RGVzdCArIHkpICogYml0bWFwLT5yb3dTaXplICsgNCAqIHhEZXN0XTsKICAgICAgc3AgPSAmc3JjLT5kYXRhWyh5U3JjICsgeSkgKiBzcmMtPnJvd1NpemUgKyA0ICogeFNyY107CiAgICAgIGZvciAoeCA9IDA7IHggPCB3OyArK3gpIHsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAyNTU7CglzcCsrOwogICAgICB9CiAgICB9CiAgICBicmVhazsKI2lmIFNQTEFTSF9DTVlLCiAgY2FzZSBzcGxhc2hNb2RlQ01ZSzg6CiAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhWyh5RGVzdCArIHkpICogYml0bWFwLT5yb3dTaXplICsgNCAqIHhEZXN0XTsKICAgICAgc3AgPSAmc3JjLT5kYXRhWyh5U3JjICsgeSkgKiBzcmMtPnJvd1NpemUgKyA0ICogeFNyY107CiAgICAgIGZvciAoeCA9IDA7IHggPCB3OyArK3gpIHsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKCSpwKysgPSAqc3ArKzsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBzcGxhc2hNb2RlRGV2aWNlTjg6CiAgICBmb3IgKHkgPSAwOyB5IDwgaDsgKyt5KSB7CiAgICAgIHAgPSAmYml0bWFwLT5kYXRhWyh5RGVzdCArIHkpICogYml0bWFwLT5yb3dTaXplICsgKFNQT1RfTkNPTVBTKzQpICogeERlc3RdOwogICAgICBzcCA9ICZzcmMtPmRhdGFbKHlTcmMgKyB5KSAqIHNyYy0+cm93U2l6ZSArIChTUE9UX05DT01QUys0KSAqIHhTcmNdOwogICAgICBmb3IgKHggPSAwOyB4IDwgdzsgKyt4KSB7CiAgICAgICAgZm9yIChpbnQgY3A9MDsgY3AgPCBTUE9UX05DT01QUys0OyBjcCsrKQogICAgICAgICAgKnArKyA9ICpzcCsrOwogICAgICB9CiAgICB9CiAgICBicmVhazsKI2VuZGlmCiAgfQoKICBpZiAoYml0bWFwLT5hbHBoYSkgewogICAgZm9yICh5ID0gMDsgeSA8IGg7ICsreSkgewogICAgICBxID0gJmJpdG1hcC0+YWxwaGFbKHlEZXN0ICsgeSkgKiBiaXRtYXAtPndpZHRoICsgeERlc3RdOwogICAgICBtZW1zZXQocSwgMHgwMCwgdyk7CiAgICB9CiAgfQoKICByZXR1cm4gc3BsYXNoT2s7Cn0KClNwbGFzaFBhdGggKlNwbGFzaDo6bWFrZVN0cm9rZVBhdGgoU3BsYXNoUGF0aCAqcGF0aCwgU3BsYXNoQ29vcmQgdywKCQkJCSAgICBHQm9vbCBmbGF0dGVuKSB7ClNwbGFzaFBhdGggKnBhdGhJbiwgKmRhc2hQYXRoLCAqcGF0aE91dDsKICBTcGxhc2hDb29yZCBkLCBkeCwgZHksIHdkeCwgd2R5LCBkeE5leHQsIGR5TmV4dCwgd2R4TmV4dCwgd2R5TmV4dDsKICBTcGxhc2hDb29yZCBjcm9zc3Byb2QsIGRvdHByb2QsIG1pdGVyLCBtOwogIEdCb29sIGZpcnN0LCBsYXN0LCBjbG9zZWQ7CiAgaW50IHN1YnBhdGhTdGFydDAsIHN1YnBhdGhTdGFydDEsIHNlZywgaTAsIGkxLCBqMCwgajEsIGswLCBrMTsKICBpbnQgbGVmdDAsIGxlZnQxLCBsZWZ0MiwgcmlnaHQwLCByaWdodDEsIHJpZ2h0Miwgam9pbjAsIGpvaW4xLCBqb2luMjsKICBpbnQgbGVmdEZpcnN0LCByaWdodEZpcnN0LCBmaXJzdFB0OwoKICBwYXRoT3V0ID0gbmV3IFNwbGFzaFBhdGgoKTsKCiAgaWYgKHBhdGgtPmxlbmd0aCA9PSAwKSB7CiAgICByZXR1cm4gcGF0aE91dDsKICB9CgogIGlmIChmbGF0dGVuKSB7CiAgICBwYXRoSW4gPSBmbGF0dGVuUGF0aChwYXRoLCBzdGF0ZS0+bWF0cml4LCBzdGF0ZS0+ZmxhdG5lc3MpOwogICAgaWYgKHN0YXRlLT5saW5lRGFzaExlbmd0aCA+IDApIHsKICAgICAgZGFzaFBhdGggPSBtYWtlRGFzaGVkUGF0aChwYXRoSW4pOwogICAgICBkZWxldGUgcGF0aEluOwogICAgICBwYXRoSW4gPSBkYXNoUGF0aDsKICAgICAgaWYgKHBhdGhJbi0+bGVuZ3RoID09IDApIHsKCWRlbGV0ZSBwYXRoSW47CglyZXR1cm4gcGF0aE91dDsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICBwYXRoSW4gPSBwYXRoOwogIH0KCiAgc3VicGF0aFN0YXJ0MCA9IHN1YnBhdGhTdGFydDEgPSAwOyAvLyBtYWtlIGdjYyBoYXBweQogIHNlZyA9IDA7IC8vIG1ha2UgZ2NjIGhhcHB5CiAgY2xvc2VkID0gZ0ZhbHNlOyAvLyBtYWtlIGdjYyBoYXBweQogIGxlZnQwID0gbGVmdDEgPSByaWdodDAgPSByaWdodDEgPSBqb2luMCA9IGpvaW4xID0gMDsgLy8gbWFrZSBnY2MgaGFwcHkKICBsZWZ0Rmlyc3QgPSByaWdodEZpcnN0ID0gZmlyc3RQdCA9IDA7IC8vIG1ha2UgZ2NjIGhhcHB5CgogIGkwID0gMDsKICBmb3IgKGkxID0gaTA7CiAgICAgICAhKHBhdGhJbi0+ZmxhZ3NbaTFdICYgc3BsYXNoUGF0aExhc3QpICYmCgkgaTEgKyAxIDwgcGF0aEluLT5sZW5ndGggJiYKCSBwYXRoSW4tPnB0c1tpMSsxXS54ID09IHBhdGhJbi0+cHRzW2kxXS54ICYmCgkgcGF0aEluLT5wdHNbaTErMV0ueSA9PSBwYXRoSW4tPnB0c1tpMV0ueTsKICAgICAgICsraTEpIDsKCiAgd2hpbGUgKGkxIDwgcGF0aEluLT5sZW5ndGgpIHsKICAgIGlmICgoZmlyc3QgPSBwYXRoSW4tPmZsYWdzW2kwXSAmIHNwbGFzaFBhdGhGaXJzdCkpIHsKICAgICAgc3VicGF0aFN0YXJ0MCA9IGkwOwogICAgICBzdWJwYXRoU3RhcnQxID0gaTE7CiAgICAgIHNlZyA9IDA7CiAgICAgIGNsb3NlZCA9IHBhdGhJbi0+ZmxhZ3NbaTBdICYgc3BsYXNoUGF0aENsb3NlZDsKICAgIH0KICAgIGowID0gaTEgKyAxOwogICAgaWYgKGowIDwgcGF0aEluLT5sZW5ndGgpIHsKICAgICAgZm9yIChqMSA9IGowOwoJICAgIShwYXRoSW4tPmZsYWdzW2oxXSAmIHNwbGFzaFBhdGhMYXN0KSAmJgoJICAgICBqMSArIDEgPCBwYXRoSW4tPmxlbmd0aCAmJgoJICAgICBwYXRoSW4tPnB0c1tqMSsxXS54ID09IHBhdGhJbi0+cHRzW2oxXS54ICYmCgkgICAgIHBhdGhJbi0+cHRzW2oxKzFdLnkgPT0gcGF0aEluLT5wdHNbajFdLnk7CgkgICArK2oxKSA7CiAgICB9IGVsc2UgewogICAgICBqMSA9IGowOwogICAgfQogICAgaWYgKHBhdGhJbi0+ZmxhZ3NbaTFdICYgc3BsYXNoUGF0aExhc3QpIHsKICAgICAgaWYgKGZpcnN0ICYmIHN0YXRlLT5saW5lQ2FwID09IHNwbGFzaExpbmVDYXBSb3VuZCkgewoJLy8gc3BlY2lhbCBjYXNlOiB6ZXJvLWxlbmd0aCBzdWJwYXRoIHdpdGggcm91bmQgbGluZSBjYXBzIC0tPgoJLy8gZHJhdyBhIGNpcmNsZQoJcGF0aE91dC0+bW92ZVRvKHBhdGhJbi0+cHRzW2kwXS54ICsgKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCXBhdGhJbi0+cHRzW2kwXS55KTsKCXBhdGhPdXQtPmN1cnZlVG8ocGF0aEluLT5wdHNbaTBdLnggKyAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS55ICsgYmV6aWVyQ2lyY2xlMiAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueCArIGJlemllckNpcmNsZTIgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgKyAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS54LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgKyAoU3BsYXNoQ29vcmQpMC41ICogdyk7CglwYXRoT3V0LT5jdXJ2ZVRvKHBhdGhJbi0+cHRzW2kwXS54IC0gYmV6aWVyQ2lyY2xlMiAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSArIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLnggLSAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS55ICsgYmV6aWVyQ2lyY2xlMiAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueCAtIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkpOwoJcGF0aE91dC0+Y3VydmVUbyhwYXRoSW4tPnB0c1tpMF0ueCAtIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgLSBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS54IC0gYmV6aWVyQ2lyY2xlMiAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSAtIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLngsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSAtIChTcGxhc2hDb29yZCkwLjUgKiB3KTsKCXBhdGhPdXQtPmN1cnZlVG8ocGF0aEluLT5wdHNbaTBdLnggKyBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS55IC0gKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueCArIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgLSBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2kwXS54ICsgKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSk7CglwYXRoT3V0LT5jbG9zZSgpOwogICAgICB9CiAgICAgIGkwID0gajA7CiAgICAgIGkxID0gajE7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgbGFzdCA9IHBhdGhJbi0+ZmxhZ3NbajFdICYgc3BsYXNoUGF0aExhc3Q7CiAgICBpZiAobGFzdCkgewogICAgICBrMCA9IHN1YnBhdGhTdGFydDEgKyAxOwogICAgfSBlbHNlIHsKICAgICAgazAgPSBqMSArIDE7CiAgICB9CiAgICBmb3IgKGsxID0gazA7CgkgIShwYXRoSW4tPmZsYWdzW2sxXSAmIHNwbGFzaFBhdGhMYXN0KSAmJgoJICAgazEgKyAxIDwgcGF0aEluLT5sZW5ndGggJiYKCSAgIHBhdGhJbi0+cHRzW2sxKzFdLnggPT0gcGF0aEluLT5wdHNbazFdLnggJiYKCSAgIHBhdGhJbi0+cHRzW2sxKzFdLnkgPT0gcGF0aEluLT5wdHNbazFdLnk7CgkgKytrMSkgOwoKICAgIC8vIGNvbXB1dGUgdGhlIGRlbHRhcyBmb3Igc2VnbWVudCAoaTEsIGowKQojaWYgVVNFX0ZJWEVEUE9JTlQKICAgIC8vIHRoZSAxL2QgdmFsdWUgY2FuIGJlIHNtYWxsLCB3aGljaCBpbnRyb2R1Y2VzIHNpZ25pZmljYW50CiAgICAvLyBpbmFjY3VyYWNpZXMgaW4gZml4ZWQgcG9pbnQgbW9kZQogICAgZCA9IHNwbGFzaERpc3QocGF0aEluLT5wdHNbaTFdLngsIHBhdGhJbi0+cHRzW2kxXS55LAoJCSAgIHBhdGhJbi0+cHRzW2owXS54LCBwYXRoSW4tPnB0c1tqMF0ueSk7CiAgICBkeCA9IChwYXRoSW4tPnB0c1tqMF0ueCAtIHBhdGhJbi0+cHRzW2kxXS54KSAvIGQ7CiAgICBkeSA9IChwYXRoSW4tPnB0c1tqMF0ueSAtIHBhdGhJbi0+cHRzW2kxXS55KSAvIGQ7CiNlbHNlCiAgICBkID0gKFNwbGFzaENvb3JkKTEgLyBzcGxhc2hEaXN0KHBhdGhJbi0+cHRzW2kxXS54LCBwYXRoSW4tPnB0c1tpMV0ueSwKCQkJCSAgICBwYXRoSW4tPnB0c1tqMF0ueCwgcGF0aEluLT5wdHNbajBdLnkpOwogICAgZHggPSBkICogKHBhdGhJbi0+cHRzW2owXS54IC0gcGF0aEluLT5wdHNbaTFdLngpOwogICAgZHkgPSBkICogKHBhdGhJbi0+cHRzW2owXS55IC0gcGF0aEluLT5wdHNbaTFdLnkpOwojZW5kaWYKICAgIHdkeCA9IChTcGxhc2hDb29yZCkwLjUgKiB3ICogZHg7CiAgICB3ZHkgPSAoU3BsYXNoQ29vcmQpMC41ICogdyAqIGR5OwoKICAgIC8vIGRyYXcgdGhlIHN0YXJ0IGNhcAogICAgcGF0aE91dC0+bW92ZVRvKHBhdGhJbi0+cHRzW2kwXS54IC0gd2R5LCBwYXRoSW4tPnB0c1tpMF0ueSArIHdkeCk7CiAgICBpZiAoaTAgPT0gc3VicGF0aFN0YXJ0MCkgewogICAgICBmaXJzdFB0ID0gcGF0aE91dC0+bGVuZ3RoIC0gMTsKICAgIH0KICAgIGlmIChmaXJzdCAmJiAhY2xvc2VkKSB7CiAgICAgIHN3aXRjaCAoc3RhdGUtPmxpbmVDYXApIHsKICAgICAgY2FzZSBzcGxhc2hMaW5lQ2FwQnV0dDoKCXBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tpMF0ueCArIHdkeSwgcGF0aEluLT5wdHNbaTBdLnkgLSB3ZHgpOwoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTGluZUNhcFJvdW5kOgoJcGF0aE91dC0+Y3VydmVUbyhwYXRoSW4tPnB0c1tpMF0ueCAtIHdkeSAtIGJlemllckNpcmNsZSAqIHdkeCwKCQkJIHBhdGhJbi0+cHRzW2kwXS55ICsgd2R4IC0gYmV6aWVyQ2lyY2xlICogd2R5LAoJCQkgcGF0aEluLT5wdHNbaTBdLnggLSB3ZHggLSBiZXppZXJDaXJjbGUgKiB3ZHksCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSAtIHdkeSArIGJlemllckNpcmNsZSAqIHdkeCwKCQkJIHBhdGhJbi0+cHRzW2kwXS54IC0gd2R4LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgLSB3ZHkpOwoJcGF0aE91dC0+Y3VydmVUbyhwYXRoSW4tPnB0c1tpMF0ueCAtIHdkeCArIGJlemllckNpcmNsZSAqIHdkeSwKCQkJIHBhdGhJbi0+cHRzW2kwXS55IC0gd2R5IC0gYmV6aWVyQ2lyY2xlICogd2R4LAoJCQkgcGF0aEluLT5wdHNbaTBdLnggKyB3ZHkgLSBiZXppZXJDaXJjbGUgKiB3ZHgsCgkJCSBwYXRoSW4tPnB0c1tpMF0ueSAtIHdkeCAtIGJlemllckNpcmNsZSAqIHdkeSwKCQkJIHBhdGhJbi0+cHRzW2kwXS54ICsgd2R5LAoJCQkgcGF0aEluLT5wdHNbaTBdLnkgLSB3ZHgpOwoJYnJlYWs7CiAgICAgIGNhc2Ugc3BsYXNoTGluZUNhcFByb2plY3Rpbmc6CglwYXRoT3V0LT5saW5lVG8ocGF0aEluLT5wdHNbaTBdLnggLSB3ZHggLSB3ZHksCgkJCXBhdGhJbi0+cHRzW2kwXS55ICsgd2R4IC0gd2R5KTsKCXBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tpMF0ueCAtIHdkeCArIHdkeSwKCQkJcGF0aEluLT5wdHNbaTBdLnkgLSB3ZHggLSB3ZHkpOwoJcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2kwXS54ICsgd2R5LAoJCQlwYXRoSW4tPnB0c1tpMF0ueSAtIHdkeCk7CglicmVhazsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2kwXS54ICsgd2R5LCBwYXRoSW4tPnB0c1tpMF0ueSAtIHdkeCk7CiAgICB9CgogICAgLy8gZHJhdyB0aGUgbGVmdCBzaWRlIG9mIHRoZSBzZWdtZW50IHJlY3RhbmdsZQogICAgbGVmdDIgPSBwYXRoT3V0LT5sZW5ndGggLSAxOwogICAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54ICsgd2R5LCBwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeCk7CgogICAgLy8gZHJhdyB0aGUgZW5kIGNhcAogICAgaWYgKGxhc3QgJiYgIWNsb3NlZCkgewogICAgICBzd2l0Y2ggKHN0YXRlLT5saW5lQ2FwKSB7CiAgICAgIGNhc2Ugc3BsYXNoTGluZUNhcEJ1dHQ6CglwYXRoT3V0LT5saW5lVG8ocGF0aEluLT5wdHNbajBdLnggLSB3ZHksIHBhdGhJbi0+cHRzW2owXS55ICsgd2R4KTsKCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaExpbmVDYXBSb3VuZDoKCXBhdGhPdXQtPmN1cnZlVG8ocGF0aEluLT5wdHNbajBdLnggKyB3ZHkgKyBiZXppZXJDaXJjbGUgKiB3ZHgsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeCArIGJlemllckNpcmNsZSAqIHdkeSwKCQkJIHBhdGhJbi0+cHRzW2owXS54ICsgd2R4ICsgYmV6aWVyQ2lyY2xlICogd2R5LAoJCQkgcGF0aEluLT5wdHNbajBdLnkgKyB3ZHkgLSBiZXppZXJDaXJjbGUgKiB3ZHgsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueCArIHdkeCwKCQkJIHBhdGhJbi0+cHRzW2owXS55ICsgd2R5KTsKCXBhdGhPdXQtPmN1cnZlVG8ocGF0aEluLT5wdHNbajBdLnggKyB3ZHggLSBiZXppZXJDaXJjbGUgKiB3ZHksCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSArIHdkeSArIGJlemllckNpcmNsZSAqIHdkeCwKCQkJIHBhdGhJbi0+cHRzW2owXS54IC0gd2R5ICsgYmV6aWVyQ2lyY2xlICogd2R4LAoJCQkgcGF0aEluLT5wdHNbajBdLnkgKyB3ZHggKyBiZXppZXJDaXJjbGUgKiB3ZHksCgkJCSBwYXRoSW4tPnB0c1tqMF0ueCAtIHdkeSwKCQkJIHBhdGhJbi0+cHRzW2owXS55ICsgd2R4KTsKCWJyZWFrOwogICAgICBjYXNlIHNwbGFzaExpbmVDYXBQcm9qZWN0aW5nOgoJcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54ICsgd2R5ICsgd2R4LAoJCQlwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeCArIHdkeSk7CglwYXRoT3V0LT5saW5lVG8ocGF0aEluLT5wdHNbajBdLnggLSB3ZHkgKyB3ZHgsCgkJCXBhdGhJbi0+cHRzW2owXS55ICsgd2R4ICsgd2R5KTsKCXBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCAtIHdkeSwKCQkJcGF0aEluLT5wdHNbajBdLnkgKyB3ZHgpOwoJYnJlYWs7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCAtIHdkeSwgcGF0aEluLT5wdHNbajBdLnkgKyB3ZHgpOwogICAgfQoKICAgIC8vIGRyYXcgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHNlZ21lbnQgcmVjdGFuZ2xlCiAgICAvLyAoTkI6IGlmIHN0cm9rZSBhZGp1c3RtZW50IGlzIGVuYWJsZWQsIHRoZSBjbG9zZXBhdGggb3BlcmF0aW9uIE1VU1QKICAgIC8vIGFkZCBhIHNlZ21lbnQgYmVjYXVzZSB0aGlzIHNlZ21lbnQgaXMgdXNlZCBmb3IgYSBoaW50KQogICAgcmlnaHQyID0gcGF0aE91dC0+bGVuZ3RoIC0gMTsKICAgIHBhdGhPdXQtPmNsb3NlKHN0YXRlLT5zdHJva2VBZGp1c3QpOwoKICAgIC8vIGRyYXcgdGhlIGpvaW4KICAgIGpvaW4yID0gcGF0aE91dC0+bGVuZ3RoOwogICAgaWYgKCFsYXN0IHx8IGNsb3NlZCkgewoKICAgICAgLy8gY29tcHV0ZSB0aGUgZGVsdGFzIGZvciBzZWdtZW50IChqMSwgazApCiNpZiBVU0VfRklYRURQT0lOVAogICAgICAvLyB0aGUgMS9kIHZhbHVlIGNhbiBiZSBzbWFsbCwgd2hpY2ggaW50cm9kdWNlcyBzaWduaWZpY2FudAogICAgICAvLyBpbmFjY3VyYWNpZXMgaW4gZml4ZWQgcG9pbnQgbW9kZQogICAgICBkID0gc3BsYXNoRGlzdChwYXRoSW4tPnB0c1tqMV0ueCwgcGF0aEluLT5wdHNbajFdLnksCgkJICAgICBwYXRoSW4tPnB0c1trMF0ueCwgcGF0aEluLT5wdHNbazBdLnkpOwogICAgICBkeE5leHQgPSAocGF0aEluLT5wdHNbazBdLnggLSBwYXRoSW4tPnB0c1tqMV0ueCkgLyBkOwogICAgICBkeU5leHQgPSAocGF0aEluLT5wdHNbazBdLnkgLSBwYXRoSW4tPnB0c1tqMV0ueSkgLyBkOwojZWxzZQogICAgICBkID0gKFNwbGFzaENvb3JkKTEgLyBzcGxhc2hEaXN0KHBhdGhJbi0+cHRzW2oxXS54LCBwYXRoSW4tPnB0c1tqMV0ueSwKCQkJCSAgICAgIHBhdGhJbi0+cHRzW2swXS54LCBwYXRoSW4tPnB0c1trMF0ueSk7CiAgICAgIGR4TmV4dCA9IGQgKiAocGF0aEluLT5wdHNbazBdLnggLSBwYXRoSW4tPnB0c1tqMV0ueCk7CiAgICAgIGR5TmV4dCA9IGQgKiAocGF0aEluLT5wdHNbazBdLnkgLSBwYXRoSW4tPnB0c1tqMV0ueSk7CiNlbmRpZgogICAgICB3ZHhOZXh0ID0gKFNwbGFzaENvb3JkKTAuNSAqIHcgKiBkeE5leHQ7CiAgICAgIHdkeU5leHQgPSAoU3BsYXNoQ29vcmQpMC41ICogdyAqIGR5TmV4dDsKCiAgICAgIC8vIGNvbXB1dGUgdGhlIGpvaW4gcGFyYW1ldGVycwogICAgICBjcm9zc3Byb2QgPSBkeCAqIGR5TmV4dCAtIGR5ICogZHhOZXh0OwogICAgICBkb3Rwcm9kID0gLShkeCAqIGR4TmV4dCArIGR5ICogZHlOZXh0KTsKICAgICAgaWYgKGRvdHByb2QgPiAwLjk5OTkpIHsKCS8vIGF2b2lkIGEgZGl2aWRlLWJ5LXplcm8gLS0gc2V0IG1pdGVyIHRvIHNvbWV0aGluZyBhcmJpdHJhcnkKCS8vIHN1Y2ggdGhhdCBzcXJ0KG1pdGVyKSB3aWxsIGV4Y2VlZCBtaXRlckxpbWl0IChhbmQgbSBpcyBuZXZlcgoJLy8gdXNlZCBpbiB0aGF0IHNpdHVhdGlvbikKCS8vIChub3RlOiB0aGUgY29tcGFyaXNvbiB2YWx1ZSAoMC45OTk5KSBoYXMgdG8gYmUgbGVzcyB0aGFuCgkvLyAxLWVwc2lsb24sIHdoZXJlIGVwc2lsb24gaXMgdGhlIHNtYWxsZXN0IHZhbHVlCgkvLyByZXByZXNlbnRhYmxlIGluIHRoZSBmaXhlZCBwb2ludCBmb3JtYXQpCgltaXRlciA9IChzdGF0ZS0+bWl0ZXJMaW1pdCArIDEpICogKHN0YXRlLT5taXRlckxpbWl0ICsgMSk7CgltID0gMDsKICAgICAgfSBlbHNlIHsKCW1pdGVyID0gKFNwbGFzaENvb3JkKTIgLyAoKFNwbGFzaENvb3JkKTEgLSBkb3Rwcm9kKTsKCWlmIChtaXRlciA8IDEpIHsKCSAgLy8gdGhpcyBjYW4gaGFwcGVuIGJlY2F1c2Ugb2YgZmxvYXRpbmcgcG9pbnQgaW5hY2N1cmFjaWVzCgkgIG1pdGVyID0gMTsKCX0KCW0gPSBzcGxhc2hTcXJ0KG1pdGVyIC0gMSk7CiAgICAgIH0KCiAgICAgIC8vIHJvdW5kIGpvaW4KICAgICAgaWYgKHN0YXRlLT5saW5lSm9pbiA9PSBzcGxhc2hMaW5lSm9pblJvdW5kKSB7CglwYXRoT3V0LT5tb3ZlVG8ocGF0aEluLT5wdHNbajBdLnggKyAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJcGF0aEluLT5wdHNbajBdLnkpOwoJcGF0aE91dC0+Y3VydmVUbyhwYXRoSW4tPnB0c1tqMF0ueCArIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLnkgKyBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS54ICsgYmV6aWVyQ2lyY2xlMiAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSArIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLngsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSArIChTcGxhc2hDb29yZCkwLjUgKiB3KTsKCXBhdGhPdXQtPmN1cnZlVG8ocGF0aEluLT5wdHNbajBdLnggLSBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS55ICsgKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueCAtIChTcGxhc2hDb29yZCkwLjUgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLnkgKyBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS54IC0gKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSk7CglwYXRoT3V0LT5jdXJ2ZVRvKHBhdGhJbi0+cHRzW2owXS54IC0gKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSAtIGJlemllckNpcmNsZTIgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLnggLSBiZXppZXJDaXJjbGUyICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS55IC0gKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueCwKCQkJIHBhdGhJbi0+cHRzW2owXS55IC0gKFNwbGFzaENvb3JkKTAuNSAqIHcpOwoJcGF0aE91dC0+Y3VydmVUbyhwYXRoSW4tPnB0c1tqMF0ueCArIGJlemllckNpcmNsZTIgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLnkgLSAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS54ICsgKFNwbGFzaENvb3JkKTAuNSAqIHcsCgkJCSBwYXRoSW4tPnB0c1tqMF0ueSAtIGJlemllckNpcmNsZTIgKiB3LAoJCQkgcGF0aEluLT5wdHNbajBdLnggKyAoU3BsYXNoQ29vcmQpMC41ICogdywKCQkJIHBhdGhJbi0+cHRzW2owXS55KTsKCiAgICAgIH0gZWxzZSB7CglwYXRoT3V0LT5tb3ZlVG8ocGF0aEluLT5wdHNbajBdLngsIHBhdGhJbi0+cHRzW2owXS55KTsKCgkvLyBhbmdsZSA8IDE4MAoJaWYgKGNyb3NzcHJvZCA8IDApIHsKCSAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54IC0gd2R5TmV4dCwKCQkJICBwYXRoSW4tPnB0c1tqMF0ueSArIHdkeE5leHQpOwoJICAvLyBtaXRlciBqb2luIGluc2lkZSBsaW1pdAoJICBpZiAoc3RhdGUtPmxpbmVKb2luID09IHNwbGFzaExpbmVKb2luTWl0ZXIgJiYKCSAgICAgIHNwbGFzaFNxcnQobWl0ZXIpIDw9IHN0YXRlLT5taXRlckxpbWl0KSB7CgkgICAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54IC0gd2R5ICsgd2R4ICogbSwKCQkJICAgIHBhdGhJbi0+cHRzW2owXS55ICsgd2R4ICsgd2R5ICogbSk7CgkgICAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54IC0gd2R5LAoJCQkgICAgcGF0aEluLT5wdHNbajBdLnkgKyB3ZHgpOwoJICAvLyBiZXZlbCBqb2luIG9yIG1pdGVyIGpvaW4gb3V0c2lkZSBsaW1pdAoJICB9IGVsc2UgewoJICAgIHBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCAtIHdkeSwKCQkJICAgIHBhdGhJbi0+cHRzW2owXS55ICsgd2R4KTsKCSAgfQoKCS8vIGFuZ2xlID49IDE4MAoJfSBlbHNlIHsKCSAgcGF0aE91dC0+bGluZVRvKHBhdGhJbi0+cHRzW2owXS54ICsgd2R5LAoJCQkgIHBhdGhJbi0+cHRzW2owXS55IC0gd2R4KTsKCSAgLy8gbWl0ZXIgam9pbiBpbnNpZGUgbGltaXQKCSAgaWYgKHN0YXRlLT5saW5lSm9pbiA9PSBzcGxhc2hMaW5lSm9pbk1pdGVyICYmCgkgICAgICBzcGxhc2hTcXJ0KG1pdGVyKSA8PSBzdGF0ZS0+bWl0ZXJMaW1pdCkgewoJICAgIHBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCArIHdkeSArIHdkeCAqIG0sCgkJCSAgICBwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeCArIHdkeSAqIG0pOwoJICAgIHBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCArIHdkeU5leHQsCgkJCSAgICBwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeE5leHQpOwoJICAvLyBiZXZlbCBqb2luIG9yIG1pdGVyIGpvaW4gb3V0c2lkZSBsaW1pdAoJICB9IGVsc2UgewoJICAgIHBhdGhPdXQtPmxpbmVUbyhwYXRoSW4tPnB0c1tqMF0ueCArIHdkeU5leHQsCgkJCSAgICBwYXRoSW4tPnB0c1tqMF0ueSAtIHdkeE5leHQpOwoJICB9Cgl9CiAgICAgIH0KCiAgICAgIHBhdGhPdXQtPmNsb3NlKCk7CiAgICB9CgogICAgLy8gYWRkIHN0cm9rZSBhZGp1c3RtZW50IGhpbnRzCiAgICBpZiAoc3RhdGUtPnN0cm9rZUFkanVzdCkgewogICAgICBpZiAoc2VnID09IDAgJiYgIWNsb3NlZCkgewoJaWYgKHN0YXRlLT5saW5lQ2FwID09IHNwbGFzaExpbmVDYXBCdXR0KSB7CgkgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQoZmlyc3RQdCwgbGVmdDIgKyAxLAoJCQkJICAgICAgIGZpcnN0UHQsIGZpcnN0UHQgKyAxKTsKCSAgaWYgKGxhc3QpIHsKCSAgICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGZpcnN0UHQsIGxlZnQyICsgMSwKCQkJCQkgbGVmdDIgKyAxLCBsZWZ0MiArIDIpOwoJICB9Cgl9IGVsc2UgaWYgKHN0YXRlLT5saW5lQ2FwID09IHNwbGFzaExpbmVDYXBQcm9qZWN0aW5nKSB7CgkgIGlmIChsYXN0KSB7CgkgICAgcGF0aE91dC0+YWRkU3Ryb2tlQWRqdXN0SGludChmaXJzdFB0ICsgMSwgbGVmdDIgKyAyLAoJCQkJCSBmaXJzdFB0ICsgMSwgZmlyc3RQdCArIDIpOwoJICAgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQoZmlyc3RQdCArIDEsIGxlZnQyICsgMiwKCQkJCQkgbGVmdDIgKyAyLCBsZWZ0MiArIDMpOwoJICB9IGVsc2UgewoJICAgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQoZmlyc3RQdCArIDEsIGxlZnQyICsgMSwKCQkJCQkgZmlyc3RQdCArIDEsIGZpcnN0UHQgKyAyKTsKCSAgfQoJfQogICAgICB9CiAgICAgIGlmIChzZWcgPj0gMSkgewoJaWYgKHNlZyA+PSAyKSB7CgkgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQobGVmdDEsIHJpZ2h0MSwgbGVmdDAgKyAxLCByaWdodDApOwoJICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGxlZnQxLCByaWdodDEsIGpvaW4wLCBsZWZ0Mik7Cgl9IGVsc2UgewoJICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGxlZnQxLCByaWdodDEsIGZpcnN0UHQsIGxlZnQyKTsKCX0KCXBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQobGVmdDEsIHJpZ2h0MSwgcmlnaHQyICsgMSwgcmlnaHQyICsgMSk7CiAgICAgIH0KICAgICAgbGVmdDAgPSBsZWZ0MTsKICAgICAgbGVmdDEgPSBsZWZ0MjsKICAgICAgcmlnaHQwID0gcmlnaHQxOwogICAgICByaWdodDEgPSByaWdodDI7CiAgICAgIGpvaW4wID0gam9pbjE7CiAgICAgIGpvaW4xID0gam9pbjI7CiAgICAgIGlmIChzZWcgPT0gMCkgewoJbGVmdEZpcnN0ID0gbGVmdDI7CglyaWdodEZpcnN0ID0gcmlnaHQyOwogICAgICB9CiAgICAgIGlmIChsYXN0KSB7CglpZiAoc2VnID49IDIpIHsKCSAgcGF0aE91dC0+YWRkU3Ryb2tlQWRqdXN0SGludChsZWZ0MSwgcmlnaHQxLCBsZWZ0MCArIDEsIHJpZ2h0MCk7CgkgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQobGVmdDEsIHJpZ2h0MSwKCQkJCSAgICAgICBqb2luMCwgcGF0aE91dC0+bGVuZ3RoIC0gMSk7Cgl9IGVsc2UgewoJICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGxlZnQxLCByaWdodDEsCgkJCQkgICAgICAgZmlyc3RQdCwgcGF0aE91dC0+bGVuZ3RoIC0gMSk7Cgl9CglpZiAoY2xvc2VkKSB7CgkgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQobGVmdDEsIHJpZ2h0MSwgZmlyc3RQdCwgbGVmdEZpcnN0KTsKCSAgcGF0aE91dC0+YWRkU3Ryb2tlQWRqdXN0SGludChsZWZ0MSwgcmlnaHQxLAoJCQkJICAgICAgIHJpZ2h0Rmlyc3QgKyAxLCByaWdodEZpcnN0ICsgMSk7CgkgIHBhdGhPdXQtPmFkZFN0cm9rZUFkanVzdEhpbnQobGVmdEZpcnN0LCByaWdodEZpcnN0LAoJCQkJICAgICAgIGxlZnQxICsgMSwgcmlnaHQxKTsKCSAgcGF0aE91dC0+YWRkU3Ryb2tlQWRqdXN0SGludChsZWZ0Rmlyc3QsIHJpZ2h0Rmlyc3QsCgkJCQkgICAgICAgam9pbjEsIHBhdGhPdXQtPmxlbmd0aCAtIDEpOwoJfQoJaWYgKCFjbG9zZWQgJiYgc2VnID4gMCkgewoJICBpZiAoc3RhdGUtPmxpbmVDYXAgPT0gc3BsYXNoTGluZUNhcEJ1dHQpIHsKCSAgICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGxlZnQxIC0gMSwgbGVmdDEgKyAxLAoJCQkJCSBsZWZ0MSArIDEsIGxlZnQxICsgMik7CgkgIH0gZWxzZSBpZiAoc3RhdGUtPmxpbmVDYXAgPT0gc3BsYXNoTGluZUNhcFByb2plY3RpbmcpIHsKCSAgICBwYXRoT3V0LT5hZGRTdHJva2VBZGp1c3RIaW50KGxlZnQxIC0gMSwgbGVmdDEgKyAyLAoJCQkJCSBsZWZ0MSArIDIsIGxlZnQxICsgMyk7CgkgIH0KCX0KICAgICAgfQogICAgfQoKICAgIGkwID0gajA7CiAgICBpMSA9IGoxOwogICAgKytzZWc7CiAgfQoKICBpZiAocGF0aEluICE9IHBhdGgpIHsKICAgIGRlbGV0ZSBwYXRoSW47CiAgfQoKICByZXR1cm4gcGF0aE91dDsKfQoKdm9pZCBTcGxhc2g6OmR1bXBQYXRoKFNwbGFzaFBhdGggKnBhdGgpIHsKICBpbnQgaTsKCiAgZm9yIChpID0gMDsgaSA8IHBhdGgtPmxlbmd0aDsgKytpKSB7CiAgICBwcmludGYoIiAgJTNkOiB4PSU4LjJmIHk9JTguMmYlcyVzJXMlc1xuIiwKCSAgIGksIChkb3VibGUpcGF0aC0+cHRzW2ldLngsIChkb3VibGUpcGF0aC0+cHRzW2ldLnksCgkgICAocGF0aC0+ZmxhZ3NbaV0gJiBzcGxhc2hQYXRoRmlyc3QpID8gIiBmaXJzdCIgOiAiIiwKCSAgIChwYXRoLT5mbGFnc1tpXSAmIHNwbGFzaFBhdGhMYXN0KSA/ICIgbGFzdCIgOiAiIiwKCSAgIChwYXRoLT5mbGFnc1tpXSAmIHNwbGFzaFBhdGhDbG9zZWQpID8gIiBjbG9zZWQiIDogIiIsCgkgICAocGF0aC0+ZmxhZ3NbaV0gJiBzcGxhc2hQYXRoQ3VydmUpID8gIiBjdXJ2ZSIgOiAiIik7CiAgfQp9Cgp2b2lkIFNwbGFzaDo6ZHVtcFhQYXRoKFNwbGFzaFhQYXRoICpwYXRoKSB7CiAgaW50IGk7CgogIGZvciAoaSA9IDA7IGkgPCBwYXRoLT5sZW5ndGg7ICsraSkgewogICAgcHJpbnRmKCIgICU0ZDogeDA9JTguMmYgeTA9JTguMmYgeDE9JTguMmYgeTE9JTguMmYgJXMlcyVzXG4iLAoJICAgaSwgKGRvdWJsZSlwYXRoLT5zZWdzW2ldLngwLCAoZG91YmxlKXBhdGgtPnNlZ3NbaV0ueTAsCgkgICAoZG91YmxlKXBhdGgtPnNlZ3NbaV0ueDEsIChkb3VibGUpcGF0aC0+c2Vnc1tpXS55MSwKCSAgIChwYXRoLT5zZWdzW2ldLmZsYWdzCSYgc3BsYXNoWFBhdGhIb3JpeikgPyAiSCIgOiAiICIsCgkgICAocGF0aC0+c2Vnc1tpXS5mbGFncwkmIHNwbGFzaFhQYXRoVmVydCkgPyAiViIgOiAiICIsCgkgICAocGF0aC0+c2Vnc1tpXS5mbGFncwkmIHNwbGFzaFhQYXRoRmxpcCkgPyAiUCIgOiAiICIpOwogIH0KfQoKU3BsYXNoRXJyb3IgU3BsYXNoOjpzaGFkZWRGaWxsKFNwbGFzaFBhdGggKnBhdGgsIEdCb29sIGhhc0JCb3gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTcGxhc2hQYXR0ZXJuICpwYXR0ZXJuKSB7CiAgU3BsYXNoUGlwZSBwaXBlOwogIFNwbGFzaFhQYXRoICp4UGF0aDsKICBTcGxhc2hYUGF0aFNjYW5uZXIgKnNjYW5uZXI7CiAgaW50IHhNaW5JLCB5TWluSSwgeE1heEksIHlNYXhJLCB4MCwgeDEsIHk7CiAgU3BsYXNoQ2xpcFJlc3VsdCBjbGlwUmVzOwoKICBpZiAodmVjdG9yQW50aWFsaWFzICYmIGFhQnVmID09IE5VTEwpIHsgLy8gc2hvdWxkIG5vdCBoYXBwZW4sIGJ1dCB0byBiZSBzZWN1cmUKICAgIHJldHVybiBzcGxhc2hFcnJHZW5lcmljOwogIH0KICBpZiAocGF0aC0+bGVuZ3RoID09IDApIHsKICAgIHJldHVybiBzcGxhc2hFcnJFbXB0eVBhdGg7CiAgfQogIHhQYXRoID0gbmV3IFNwbGFzaFhQYXRoKHBhdGgsIHN0YXRlLT5tYXRyaXgsIHN0YXRlLT5mbGF0bmVzcywgZ1RydWUpOwogIGlmICh2ZWN0b3JBbnRpYWxpYXMpIHsKICAgIHhQYXRoLT5hYVNjYWxlKCk7CiAgfQogIHhQYXRoLT5zb3J0KCk7CiAgeU1pbkkgPSBzdGF0ZS0+Y2xpcC0+Z2V0WU1pbkkoKTsKICB5TWF4SSA9IHN0YXRlLT5jbGlwLT5nZXRZTWF4SSgpOwogIGlmICh2ZWN0b3JBbnRpYWxpYXMgJiYgIWluU2hhZGluZykgewogICAgeU1pbkkgPSB5TWluSSAqIHNwbGFzaEFBU2l6ZTsKICAgIHlNYXhJID0gKHlNYXhJICsgMSkgKiBzcGxhc2hBQVNpemUgLSAxOwogIH0KICBzY2FubmVyID0gbmV3IFNwbGFzaFhQYXRoU2Nhbm5lcih4UGF0aCwgZ0ZhbHNlLCB5TWluSSwgeU1heEkpOwoKICAvLyBnZXQgdGhlIG1pbiBhbmQgbWF4IHggYW5kIHkgdmFsdWVzCiAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgc2Nhbm5lci0+Z2V0QkJveEFBKCZ4TWluSSwgJnlNaW5JLCAmeE1heEksICZ5TWF4SSk7CiAgfSBlbHNlIHsKICAgIHNjYW5uZXItPmdldEJCb3goJnhNaW5JLCAmeU1pbkksICZ4TWF4SSwgJnlNYXhJKTsKICB9CgogIC8vIGNoZWNrIGNsaXBwaW5nCiAgaWYgKChjbGlwUmVzID0gc3RhdGUtPmNsaXAtPnRlc3RSZWN0KHhNaW5JLCB5TWluSSwgeE1heEksIHlNYXhJKSkgIT0gc3BsYXNoQ2xpcEFsbE91dHNpZGUpIHsKICAgIC8vIGxpbWl0IHRoZSB5IHJhbmdlCiAgICBpZiAoeU1pbkkgPCBzdGF0ZS0+Y2xpcC0+Z2V0WU1pbkkoKSkgewogICAgICB5TWluSSA9IHN0YXRlLT5jbGlwLT5nZXRZTWluSSgpOwogICAgfQogICAgaWYgKHlNYXhJID4gc3RhdGUtPmNsaXAtPmdldFlNYXhJKCkpIHsKICAgICAgeU1heEkgPSBzdGF0ZS0+Y2xpcC0+Z2V0WU1heEkoKTsKICAgIH0KCiAgICBwaXBlSW5pdCgmcGlwZSwgMCwgeU1pbkksIHBhdHRlcm4sIE5VTEwsIChHdWNoYXIpc3BsYXNoUm91bmQoc3RhdGUtPmZpbGxBbHBoYSAqIDI1NSksIHZlY3RvckFudGlhbGlhcyAmJiAhaGFzQkJveCwgZ0ZhbHNlKTsKCiAgICAvLyBkcmF3IHRoZSBzcGFucwogICAgaWYgKHZlY3RvckFudGlhbGlhcykgewogICAgICBmb3IgKHkgPSB5TWluSTsgeSA8PSB5TWF4STsgKyt5KSB7CiAgICAgICAgc2Nhbm5lci0+cmVuZGVyQUFMaW5lKGFhQnVmLCAmeDAsICZ4MSwgeSk7CiAgICAgICAgaWYgKGNsaXBSZXMgIT0gc3BsYXNoQ2xpcEFsbEluc2lkZSkgewogICAgICAgICAgc3RhdGUtPmNsaXAtPmNsaXBBQUxpbmUoYWFCdWYsICZ4MCwgJngxLCB5KTsKICAgICAgICB9CiNpZiBzcGxhc2hBQVNpemUgPT0gNAogICAgICAgIGlmICghaGFzQkJveCAmJiB5ID4geU1pbkkgJiYgeSA8IHlNYXhJKSB7CiAgICAgICAgICAvLyBjb3JyZWN0IHNoYXBlIG9uIGxlZnQgc2lkZSBpZiBjbGlwIGlzCiAgICAgICAgICAvLyB2ZXJ0aWNhbCB0aHJvdWdoIHRoZSBtaWRkbGUgb2Ygc2hhZGluZzoKICAgICAgICAgIEd1Y2hhciAqcDAsICpwMSwgKnAyLCAqcDM7CiAgICAgICAgICBHdWNoYXIgYzEsIGMyLCBjMywgYzQ7CiAgICAgICAgICBwMCA9IGFhQnVmLT5nZXREYXRhUHRyKCkgKyAoeDAgPj4gMSk7CiAgICAgICAgICBwMSA9IHAwICsgYWFCdWYtPmdldFJvd1NpemUoKTsKICAgICAgICAgIHAyID0gcDEgKyBhYUJ1Zi0+Z2V0Um93U2l6ZSgpOwogICAgICAgICAgcDMgPSBwMiArIGFhQnVmLT5nZXRSb3dTaXplKCk7CiAgICAgICAgICBpZiAoeDAgJiAxKSB7CiAgICAgICAgICAgYzEgPSAoKnAwICYgMHgwZik7IGMyID0oKnAxICYgMHgwZik7IGMzID0gKCpwMiAmIDB4MGYpIDsgYzQgPSAoKnAzICYgMHgwZik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjMSA9ICgqcDAgPj4gNCk7IGMyID0gKCpwMSA+PiA0KTsgYzMgPSAoKnAyID4+IDQpOyBjNCA9ICgqcDMgPj4gNCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIChjMSAmIDB4MDMpID09IDB4MDMgJiYgKGMyICYgMHgwMykgPT0gMHgwMyAmJiAoYzMgJiAweDAzKSA9PSAweDAzICYmIChjNCAmIDB4MDMpID09IDB4MDMKICAgICAgICAgICAgJiYgYzEgPT0gYzIgJiYgYzIgPT0gYzMgJiYgYzMgPT0gYzQgJiYKICAgICAgICAgICAgcGF0dGVybi0+dGVzdFBvc2l0aW9uKHgwIC0gMSwgeSkgKQogICAgICAgICAgewogICAgICAgICAgICBHdWNoYXIgc2hhcGVDb3JyZWN0aW9uID0gKHgwICYgMSkgPyAweDBmIDogMHhmMDsKICAgICAgICAgICAgKnAwIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAxIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAyIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAzIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgIH0KICAgICAgICAgIC8vIGNvcnJlY3Qgc2hhcGUgb24gcmlnaHQgc2lkZSBpZiBjbGlwIGlzCiAgICAgICAgICAvLyB0aHJvdWdoIHRoZSBtaWRkbGUgb2Ygc2hhZGluZzoKICAgICAgICAgIHAwID0gYWFCdWYtPmdldERhdGFQdHIoKSArICh4MSA+PiAxKTsKICAgICAgICAgIHAxID0gcDAgKyBhYUJ1Zi0+Z2V0Um93U2l6ZSgpOwogICAgICAgICAgcDIgPSBwMSArIGFhQnVmLT5nZXRSb3dTaXplKCk7CiAgICAgICAgICBwMyA9IHAyICsgYWFCdWYtPmdldFJvd1NpemUoKTsKICAgICAgICAgIGlmICh4MSAmIDEpIHsKICAgICAgICAgICAgYzEgPSAoKnAwICYgMHgwZik7IGMyID0oKnAxICYgMHgwZik7IGMzID0gKCpwMiAmIDB4MGYpIDsgYzQgPSAoKnAzICYgMHgwZik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjMSA9ICgqcDAgPj4gNCk7IGMyID0gKCpwMSA+PiA0KTsgYzMgPSAoKnAyID4+IDQpOyBjNCA9ICgqcDMgPj4gNCk7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKCAoYzEgJiAweGMpID09IDB4MGMgJiYgKGMyICYgMHgwYykgPT0gMHgwYyAmJiAoYzMgJiAweDBjKSA9PSAweDBjICYmIChjNCAmIDB4MGMpID09IDB4MGMKICAgICAgICAgICAgJiYgYzEgPT0gYzIgJiYgYzIgPT0gYzMgJiYgYzMgPT0gYzQgJiYKICAgICAgICAgICAgcGF0dGVybi0+dGVzdFBvc2l0aW9uKHgxICsgMSwgeSkgKQogICAgICAgICAgewogICAgICAgICAgICBHdWNoYXIgc2hhcGVDb3JyZWN0aW9uID0gKHgxICYgMSkgPyAweDBmIDogMHhmMDsKICAgICAgICAgICAgKnAwIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAxIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAyIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgICAgKnAzIHw9IHNoYXBlQ29ycmVjdGlvbjsKICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgogICAgICAgIGRyYXdBQUxpbmUoJnBpcGUsIHgwLCB4MSwgeSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIFNwbGFzaENsaXBSZXN1bHQgY2xpcFJlczI7CiAgICAgIGZvciAoeSA9IHlNaW5JOyB5IDw9IHlNYXhJOyArK3kpIHsKICAgICAgICB3aGlsZSAoc2Nhbm5lci0+Z2V0TmV4dFNwYW4oeSwgJngwLCAmeDEpKSB7CiAgICAgICAgICBpZiAoY2xpcFJlcyA9PSBzcGxhc2hDbGlwQWxsSW5zaWRlKSB7CiAgICAgICAgICAgIGRyYXdTcGFuKCZwaXBlLCB4MCwgeDEsIHksIGdUcnVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIGxpbWl0IHRoZSB4IHJhbmdlCiAgICAgICAgICAgIGlmICh4MCA8IHN0YXRlLT5jbGlwLT5nZXRYTWluSSgpKSB7CiAgICAgICAgICAgICAgeDAgPSBzdGF0ZS0+Y2xpcC0+Z2V0WE1pbkkoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoeDEgPiBzdGF0ZS0+Y2xpcC0+Z2V0WE1heEkoKSkgewogICAgICAgICAgICAgIHgxID0gc3RhdGUtPmNsaXAtPmdldFhNYXhJKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xpcFJlczIgPSBzdGF0ZS0+Y2xpcC0+dGVzdFNwYW4oeDAsIHgxLCB5KTsKICAgICAgICAgICAgZHJhd1NwYW4oJnBpcGUsIHgwLCB4MSwgeSwgY2xpcFJlczIgPT0gc3BsYXNoQ2xpcEFsbEluc2lkZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIG9wQ2xpcFJlcyA9IGNsaXBSZXM7CgogIGRlbGV0ZSBzY2FubmVyOwogIGRlbGV0ZSB4UGF0aDsKICByZXR1cm4gc3BsYXNoT2s7Cn0K