Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyB0aGluZy9jb21tYW5kcy5jIC0tIHRoaW5nIGRlc2NyaXB0aW9uCi8vCi8vICRJZDogY29tbWFuZHMuYyA5NTE0IDIwMTYtMDItMjMgMjA6MzM6MDlaIEdsb2luc29uICQKLy8KLy8gQXVzIFJlZ2VuYm9nZW4gTVVETGliCi8vIGF1cyBHdWVsZGVubGFuZC9XdW5kZXJsYW5kIE1VRGxpYiAoTW9yZ2VuZ3JhdWVuIE1VRGxpYikKLy8KLy8gUF9DT01NQU5EUyBkYXRhLXN0cnVjdHVyZToKLy8KLy8gQWRkQ21kKHZlcmIsZnVuMSwxKTsKLy8gQWRkQ21kKHZlcmIrc3luMWF8c3luMWImc3luMmF8c3luMmJ8c3luMmMsZnVuMiwKLy8JICAgZXJyb3IxX25vdGlmeXxlcnJvcjJfbm90aWZ5XmVycm9yMl93cml0ZSk7Ci8vIC0tPgovLyAoW3ZlcmI6KHtmdW4xLGZ1bjJ9KTsJCQkJCS8vIGZ1bnMKLy8JICAoezEsKHtlcnJvcjFfbm90aWZ5LCBlcnJvcjJfd3JpdGVeZXJyb3IyX3NheSwgMX0pfSk7ICAvLyBmbGFncwovLyAgICAgICAgKHswLCh7KHtzeW4xYSxzeW4xYn0pLCh7c3luMmEsc3luMmIsc3luMmN9KX0pfSk7CS8vIHJ1bGVzCi8vICAgICAgICAwXSkJCQkJCQkJLy8gSURzCi8vCi8vIFJ1bGVzOiAoezxSZWdlbHNhdHogZnVlciBmdW4xPiwgKHs8MS4gU3lub255bWdydXBwZT4sCi8vCQkJCSAgICAgPDIuIFN5bm9ueW1ncnVwcGUsIC4uLn0pLCAuLi59KQovLyBGbGFnczogKHs8RmxhZyBmdWVyIGZ1bjE+LCAoezxGZWhsZXJtZWxkdW5nIDEuIFN5bm9ueW1ncnVwcGU+LCAuLi4gLAovLwkJCQlbLCBJbmRleCBmdWVyIHdyaXRlIGFuc3RhdHQgbm90aWZ5X2ZhaWxdfSksCi8vCSAgICAuLi4gfSkKLy8gSURzOiAgIDAgb2RlciAoezxJRCBmdWVyIGZ1bjE+fSkgb2RlciAoezAsIDxJRCBmdWVyIGZ1bjI+fSkgLi4uCi8vCi8vIElERUE6IHNhdmUgbm8gMHMgaW4gcnVsZXMvZmxhZ3MgaWYgcG9zc2libGUgKGFzIGluIElEcykKLy8gICAgICAgKGFkcmVzc2luZyBlc3BlY2lhbGx5IG9sZC1zdHlsZS1BZGRDbWQtTVVEcykKI3ByYWdtYSBzdHJpY3RfdHlwZXMKI3ByYWdtYSBzYXZlX3R5cGVzCiNwcmFnbWEgcmFuZ2VfY2hlY2sKI3ByYWdtYSBub19jbG9uZQojcHJhZ21hIHBlZGFudGljCgojaW5jbHVkZSA8bW92aW5nLmg+CiNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgojaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KI2luY2x1ZGUgPGRlZmluZXMuaD4KI2luY2x1ZGUgPGxpdmluZy9jb21tLmg+CgojZGVmaW5lIE5FRURfUFJPVE9UWVBFUwojaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgojaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KI2luY2x1ZGUgPHRoaW5nL2NvbW1hbmRzLmg+CiN1bmRlZiBORUVEX1BST1RPVFlQRVMKCiNpZmRlZiBEQkcKI3VuZGVmIERCRwojZW5kaWYKI2RlZmluZSBEQkcoeCkgcHJpbnRmKCJPYmplY3QgJU8gdG1wc3RyPSVzXG4iLCBleHBsb2RlKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpLCIjIilbMV0sIHgpOwoKcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBhZGRlZF9jbWRzOwoKcHJvdGVjdGVkIGludCBfY21kX3N5bnRheGhlbHAoc3RyaW5nIHN0ciwgbWl4ZWQgKmFyZ3MpCnsKICBtYXBwaW5nfGNsb3N1cmUgcmVzdHI7CiAgbWl4ZWQgaGVscCA9IFF1ZXJ5UHJvcChQX1NZTlRBWF9IRUxQKTsKICBpZiAocG9pbnRlcnAoaGVscCkpCiAgewogICAgcmVzdHIgPSBoZWxwWzFdOwogICAgaGVscCA9IGhlbHBbMF07CiAgfQogIC8vIFJlc3RyaWt0aW9uZW4gdm9yIGRlbSBBbnplaWdlbiBwcnVlZmVuLgogIGlmIChtYXBwaW5ncChyZXN0cikpCiAgewogICAgc3RyaW5nIHJlcyA9ICIvc3RkL3Jlc3RyaWN0aW9uX2NoZWNrZXIiLT5jaGVja19yZXN0cmljdGlvbnMoUEwscmVzdHIpOwogICAgaWYgKHJlcykKICAgIHsKICAgICAgUEwtPlJlY2VpdmVNc2coIkZ1ZXIgIiArIG5hbWUoV0VOLDEpICsgIiBkYXJmc3QgRHUgIgogICAgICAgICAgICAgICAgICAgICAiZGllIFN5bnRheGhpbGZlIChub2NoKSBuaWNodCBsZXNlbjpcbiIKICAgICAgICAgICAgICAgICAgICAgKyByZXMsCiAgICAgICAgICAgICAgICAgICAgIE1UX05PVElGSUNBVElPTnxNU0dfQlNfTEVBVkVfTEZTLAogICAgICAgICAgICAgICAgICAgICAic3ludGF4aGlsZmUiLDAsdGhpc19vYmplY3QoKSk7CiAgICAgIHJldHVybiAxOwogICAgfQogIH0KICBlbHNlIGlmIChjbG9zdXJlcChyZXN0cikpCiAgewogICAgc3RyaW5nIHJlcyA9IGZ1bmNhbGwocmVzdHIsIE1FKTsKICAgIGlmIChyZXMpCiAgICB7CiAgICAgIGlmIChpbnRwKHJlcykpCiAgICAgICAgUEwtPlJlY2VpdmVNc2coIkZ1ZXIgIiArIG5hbWUoV0VOLDEpICsgIiBkYXJmc3QgRHUgIgogICAgICAgICAgICAgICAgICAgICAgICJkaWUgU3ludGF4aGlsZmUgKG5vY2gpIG5pY2h0IGxlc2VuLiIsCiAgICAgICAgICAgICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsCiAgICAgICAgICAgICAgICAgICAgICAgInN5bnRheGhpbGZlIiwwLHRoaXNfb2JqZWN0KCkpOwogICAgICBlbHNlIGlmIChzdHJpbmdwKHJlcykpCiAgICAgICAgUEwtPlJlY2VpdmVNc2cocmVzLAogICAgICAgICAgICAgICAgICAgICAgIE1UX05PVElGSUNBVElPTnxNU0dfQlNfTEVBVkVfTEZTLAogICAgICAgICAgICAgICAgICAgICAgICJzeW50YXhoaWxmZSIsMCx0aGlzX29iamVjdCgpKTsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgfQoKICBpZiAoc3RyaW5ncChoZWxwKSkKICB7CiAgICBoZWxwID0gIkZ1ZXIgIiArIG5hbWUoV0VOLDEpICsgIiBnaWJ0IGVzIGZvbGdlbmRlIFN5bnRheGhpbGZlOlxuIgogICAgICAgICAgICsgaGVscDsKICB9CiAgZWxzZSBpZiAoY2xvc3VyZXAoaGVscCkpCiAgewogICAgaGVscCA9IGZ1bmNhbGwoaGVscCwgdGhpc19vYmplY3QoKSk7CiAgfQogIGVsc2UKICB7CiAgICAvLyB3ZW5uIGRhcyBPYmpla3Qga2VpbmUgU3ludGF4aGlsZmUgaGF0LCBicmF1Y2h0IGVzIGRhcyBLb21tYW5kbyBhdWNoCiAgICAvLyBuaWNodC4KICAgIG5vdGlmeV9mYWlsKCJGdWVyICIgKyBuYW1lKFdFTiwxKQogICAgICAgICAgICAgICAgKyAiIGdpYnQgZXMga2VpbmUgU3ludGF4aGlsZmUuXG4iKTsKICAgIFJlbW92ZUNtZCgwLDAsICJfY21kX3N5bnRheGhlbHAiKTsKICAgIHJldHVybiAwOwogIH0KICBpZiAoc3RyaW5ncChoZWxwKSAmJiBzaXplb2YoaGVscCkpCiAgICBQTC0+UmVjZWl2ZU1zZyhoZWxwLCBNVF9OT1RJRklDQVRJT058TVNHX0JTX0xFQVZFX0xGUywKICAgICAgICAgICAgICAgICAgICJzeW50YXhoaWxmZSIsMCx0aGlzX29iamVjdCgpKTsKCiAgcmV0dXJuIDE7Cn0KCnByb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCnsKICBBZGRDbWQoInN5bnRheGhpbGZlJkBJRCIsICMnX2NtZF9zeW50YXhoZWxwLAogICAgICAgICAiRnVlciBXQVMgbW9lY2h0ZXN0IER1IGVpbmUgU3ludGF4aGlsZmU/XG4iLAogICAgICAgICAiX2NtZF9zeW50YXhoZWxwIik7Cn0KCnByb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKICBzZXRfbmV4dF9yZXNldCgtMSk7Cn0KCnZhcmFyZ3Mgdm9pZCBBZGRDbWQobWl4ZWQgY21kLCBtaXhlZCBmdW5jLCBtaXhlZCBmbGFnLCBtaXhlZCBjbWRpZCkgewogaW50IGksajsKIGNsb3N1cmUgY2w7CiBtaXhlZCAqcnVsZTsKCiAvLyBwb3RlbnRpZWxsZSBBZGRDbWQgbWl0IFJlZ2VsPwogaWYoc3RyaW5ncChjbWQpKSB7CiAgLy8gZWluZSBSZWdlbD8gLSBhdWZzcGxpdHRlbgogIGlmKChpPW1lbWJlcihjbWQsJyYnKSk+MCkgewogICAvLyAuLi4gaW4gQXJyYXkgbWl0IFZlcmtudWVwZnVuZ3NlbGVtZW50ZW4KICAgcnVsZT1leHBsb2RlKGNtZFsoaSsxKS4uXSwiJiIpOwogICBqPXNpemVvZihydWxlKTsKICAgLy8gLi4uIGluIEFycmF5IG1pdCBBcnJheXMgbWl0IEFsdGVybmF0aXZlbGVtZW50ZW46CiAgIC8vICJwfHEmcnxzIiAtPiAoeyAoeyJwIiwicSJ9KSwgKHsiciIsInMifX0gfSkKICAgd2hpbGUoai0tKQogICAgcnVsZVtqXT1leHBsb2RlKHJ1bGVbal0sInwiKTsKCiAgIC8vIFJlZ2VsbiB2b24gS29tbWFuZG92ZXJiZW4gYWJzY2huZWlkZW4KICAgY21kPWNtZFswLi4oaS0xKV07CiAgfQogIC8vIEtvbW1hbmRvdmVyYmVuIGV4dHJhaGllcmVuCiAgY21kPWV4cGxvZGUoY21kLCJ8Iik7CgogIC8vIFNhdHogdm9uIFJlZ2VsbiBleGlzdGllcnQ6IEF1ZnNwbGl0dGVuIHZvbiBGZWhsZXJtZWxkdW5nZW4KICBpZihydWxlKQogICBpZihzdHJpbmdwKGZsYWcpKSB7CiAgICBtaXhlZCAqZmFpbDsKICAgIC8vIGluIGVpbmZhY2hlcyBBcnJheSBtaXQgamV3ZWlsaWdlbiBGZWhsZXJtZWxkdW5nZW4KICAgIGZhaWw9ZXhwbG9kZShmbGFnLCJ8Iik7CiAgICBqPTA7CiAgICBpPXNpemVvZihmYWlsKTsKICAgIHdoaWxlKGo8aSkgewogICAgIC8vIHdyaXRlIC0gRmVobGVybWVsZHVuZyBlbnRkZWNrdCAtIFBvc2l0aW9uIGdnZi4gZWludHJhZ2VuCiAgICAgaWYobWVtYmVyKGZhaWxbal0sJ14nKT49MCAmJiAhaW50cChmYWlsWzwxXSkpCiAgICAgIGZhaWwrPSh7an0pOwogICAgIGlmKG1lbWJlcihmYWlsW2pdLCdAJyk+PTApIHsKICAgICAgaW50IHM7CiAgICAgIGZsYWc9cmVnZXhwbG9kZShmYWlsW2pdLCAiQFdFW0EtU1VdKlswLTldIik7CiAgICAgIHM9c2l6ZW9mKGZsYWcpOwogICAgICB3aGlsZSgocy09Mik+MCkgewogICAgICAgaW50IHRtcGludDsKICAgICAgIHRtcGludD1mbGFnW3NdWzwxXS0nMSc7CiAgICAgICBpZih0bXBpbnQ8MCB8fCB0bXBpbnQ+aikKICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICAgICAiQWRkQ21kOiBlcnJvci1tZXNzYWdlICVkIGNvbnRhaW5zIG91dC1vZi1ib3VuZHMgQFdFeHgtcnVsZS5cbiIsaisxKSk7CiAgICAgIH0KICAgICB9CiAgICAgaisrOwogICAgfQogICAgLy8gIldhcz98V2llIGRhcz8iIC0+ICh7Ildhcz8iLCJXaWUgZGFzPyJ9KQogICAgLy8gIldhcz98V2llIGRhcz9efFdvbWl0IGRhcz98V29yYXVmIGRhcz9eQFdFUjEgbWFjaHQgd2FzLiIgLT4KICAgIC8vICAoeyJXYXM/IiwKICAgIC8vICAgICJXaWUgZGFzP15Xb21pdCBkYXM/IiwKICAgIC8vCSAgIldvcmF1ZiBkYXM/XkBXRVIxIG1hY2h0IHdhcy4iLDF9KQogICAgZmxhZz1zaXplb2YoZmFpbCk7CiAgICBpZihmbGFnICYmIGZsYWc8c2l6ZW9mKHJ1bGUpKQogICAgIHJhaXNlX2Vycm9yKAogICAgICAiQWRkQ21kOiBudW1iZXIgb2YgZXJyb3ItbWVzc2FnZXMgZG9lcyBub3QgbWF0Y2ggbnVtYmVyIG9mIHJ1bGVzLlxuIik7CiAgICBmbGFnPWZhaWw7IC8vIHVlYmVyc2NocmVpYmVuIG1pdCBkZW4gcGFyc2VmcmV1bmRsaWNoZW4gRm9ybWF0CiAgfSBlbHNlIGlmKGZsYWcpCiAgIHJhaXNlX2Vycm9yKCJBZGRDbWQ6IHJ1bGVzIGV4aXN0IGJ1dCBmbGFncyBhcmUgbm90IGFuIGVycm9yLXN0cmluZy5cbiIpOwogfSAvLyBlbmQgaWYoc3RyaW5ncChjbWQpKSAuLi4ga2VpbiBSZWdlbHN0cmluZyB2b3JoYW5kZW4KCiAvLyBrZWluIEtvbW1hbmRvYXJyYXkgZ2V3ZXNlbiBub2NoIGVyemV1Z3Q/CiBpZighcG9pbnRlcnAoY21kKSkKICAgcmFpc2VfZXJyb3IoIkFkZENtZDogbWlzc2luZyBzdHJpbmcvcG9pbnRlci1wYXJhbWV0ZXIgZm9yIGNvbW1hbmQuXG4iKTsKCiAvLyBDbG9zdXJlIGF1cyBlaW5lbSBTdHJpbmcgZXJ6ZXVnZW4sIHdlbm4gbW9lZ2xpY2ggdW5kIHNpY2hlcgogLy8gKGZ1bmN0aW9uX2V4aXN0cygpIGZpbHRlcnQgdW5ub2V0aWdlcndlaXNlIGF1Y2ggcmVpbmUgInN0YXRpYyIgZnVucywKIC8vICBkaWUgZ2VuYXVlIFBydWVmdW5nIHVlYmVyIGZ1bmN0aW9ubGlzdCgpIGtvc3RldCBqZWRvY2ggenV2aWVsKQogaWYoc3RyaW5ncChmdW5jKSAmJgogICAgKCFleHRlcm5fY2FsbCgpIHx8IGZ1bmN0aW9uX2V4aXN0cyhmdW5jLHRoaXNfb2JqZWN0KCkpKSAmJgogICAgY2xvc3VyZXAoY2w9c3ltYm9sX2Z1bmN0aW9uKGZ1bmMsdGhpc19vYmplY3QoKSkpKQogIGZ1bmM9Y2w7CgogLy8gamVkZXMgZWluemVsbmUgVmVyYiBtaXQgc2VpbmVuIFJlZ2VsbiB1bmQgRnVua3Rpb25lbiBlaW50cmFnZW4KIGk9c2l6ZW9mKGNtZCk7CiBpZighYWRkZWRfY21kcykgYWRkZWRfY21kcz1tX2FsbG9jYXRlKGksNCk7CiB3aGlsZShpLS0pIHsKICBzdHJpbmcgc3RyOwogIHN0cj1jbWRbaV07CiAgaWYoIWZ1bmMpCiAgIGlmKGV4dGVybl9jYWxsKCkpIGZ1bmM9cHJldmlvdXNfb2JqZWN0KCk7CiAgIGVsc2UgZnVuYz10aGlzX29iamVjdCgpOwogIGlmKCFtZW1iZXIoYWRkZWRfY21kcyxzdHIpKQogICBhZGRlZF9jbWRzKz0oW3N0cjphbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTswXSk7CiAgLy8gZXhpc3RpZXJlbmRlcyBWZXJiIGVyZ2FlbnplbgogIGFkZGVkX2NtZHNbc3RyLDBdKz0oe2Z1bmN9KTsKICBhZGRlZF9jbWRzW3N0ciwxXSs9KHtmbGFnfSk7CiAgYWRkZWRfY21kc1tzdHIsMl0rPSh7cnVsZX0pOwogIC8vIGdnZi4gaWQgaW4gZGFzIElELU1hcHBpbmcgZWludHJhZ2VuCiAgaWYoY21kaWQpIHsKICAgbWl4ZWQgKnRtcDsKICAgaj1zaXplb2YoKHN0cmluZyopYWRkZWRfY21kc1tzdHIsMF0pOwogICB0bXA9YWRkZWRfY21kc1tzdHIsM118fGFsbG9jYXRlKGopOwogICBpZihzaXplb2YodG1wKTxqKSB0bXArPWFsbG9jYXRlKGotc2l6ZW9mKHRtcCkpOwogICB0bXBbPDFdPWNtZGlkOwogICBhZGRlZF9jbWRzW3N0ciwzXT10bXA7CiAgfQogfQp9CgovLyBBdXN3ZXJ0dW5nIGZ1ZXIgZWluIFZlcmIgbG9lc2NoZW4KdmFyYXJncyBpbnQgUmVtb3ZlQ21kKG1peGVkIGNtZCwgaW50IGRlbF9ub3J1bGUsIG1peGVkIG9ubHlpZCkgewogaW50IHJldDsKCiAvLyBGYWxscyBNYWdpZXIgZGFzIFJlbW92ZUNtZCBmYWxzY2ggbnV0emVuICh6LkIuIGFuYWxvZyB6dSBBZGRDbWQpCiAvLyB3aXJkIGRhcyBSZWdlbHN5c3RlbSB2ZXJ3aXJydC4gRGEgZGFzIGRlbF9ub3J1bGUgbnVyIGludCBzZWluIGRhcmYsCiAvLyBnaWJ0IGVzIGhpZXIgZWluZSBndXRlIENoYW5jZSBkZW4gRmVobGVyIGFid2FlcnRza29tcGF0aWJlbCB6dSBlbnQtCiAvLyBkZWNrZW4uIERhbWl0IFNwaWVsZXIgZGVuIEZlaGxlciBuaWNodCBtaXRiZWtvbW1lbiwgd2lyZCBoaWVyIGF1ZgogLy8gZWluIHJhaXNlX2Vycm9yIHZlcnppY2h0ZXQsIHVuZCBzdGF0dCBkZXNzZW4gaW4gZWluIExvZ2ZpbGUgZ2UtCiAvLyBzY2hyaWViZW4uCiBpZiAoIWludHAoZGVsX25vcnVsZSkpCiB7CiAgIGxvZ19maWxlKCJSRU1PVkVfQ01EIiwKICAgICBzcHJpbnRmKCJcbi0tICVzIC0tXG5JbGxlZ2FsIFJlbW92ZUNvbW1hbmQoKSBpbiBPYmplY3QgWyVPXTpcbiAlT1xuIiwKICAgICAgIGR0aW1lKHRpbWUoKSksIHRoaXNfb2JqZWN0KCksIGNtZCkpOwogICBkZWxfbm9ydWxlPTA7CiAgIG9ubHlpZD0wOwogfQogCiBpZighYWRkZWRfY21kcyB8fCAoIWNtZCAmJiAhZGVsX25vcnVsZSAmJiAhb25seWlkKSkKICBhZGRlZF9jbWRzPShtYXBwaW5nKTA7IAogZWxzZSB7CiAgaW50IGksIGo7CiAgbWl4ZWQgKnJ1bGUsICpmbGFnLCAqZnVuLCAqZGVscnVsZSwgKmlkczsKCiAgaWYoc3RyaW5ncChjbWQpKSB7CiAgIC8vIFJlZ2VsbiBlbnRkZWNrdCAtIFplcmxlZ2VuICh3aWUgQWRkQ21kKQogICBpZigoaT1tZW1iZXIoY21kLCcmJykpPjApIHsKICAgIGRlbHJ1bGU9ZXhwbG9kZShjbWRbKGkrMSkuLl0sIiYiKTsKICAgIGo9c2l6ZW9mKGRlbHJ1bGUpOwogICAgd2hpbGUoai0tKQogICAgIGRlbHJ1bGVbal09ZXhwbG9kZShkZWxydWxlW2pdLCJ8Iik7CiAgICBjbWQ9Y21kWzAuLihpLTEpXTsKICAgfQogICBjbWQ9ZXhwbG9kZShjbWQsInwiKTsKICB9IGVsc2UgaWYoZGVsX25vcnVsZSB8fCBvbmx5aWQpIGNtZD1tX2luZGljZXMoYWRkZWRfY21kcyk7CgogIGlmKCFwb2ludGVycChjbWQpKQogICByYWlzZV9lcnJvcigiUmVtb3ZlQ21kOiBtaXNzaW5nIHN0cmluZy9wb2ludGVyLXBhcmFtZXRlci5cbiIpOwogIGk9c2l6ZW9mKGNtZCk7CgogIHdoaWxlKGktLSkgewogICAvLyBrZWluZSBSZWdlbG4gZGEgdW5kIFJlZ2VsbiBsb2VzY2hlbiBlcmxhdWJ0OiBhbGxlcyBsb2VzY2hlbgogICBpZighZGVscnVsZSAmJiAhZGVsX25vcnVsZSAmJiAhb25seWlkKSBtX2RlbGV0ZShhZGRlZF9jbWRzLGNtZFtpXSk7CiAgIGVsc2UgaWYobV9jb250YWlucygmZnVuLCAmZmxhZywgJnJ1bGUsICZpZHMsIGFkZGVkX2NtZHMsIGNtZFtpXSkpIHsKICAgIGo9c2l6ZW9mKGZ1bik7CiAgICB3aGlsZShqLS0pIHsKICAgICBpbnQgazsKICAgICAvLyBEQkcocnVsZVtqXSk7CiAgICAJLy8gUmVnZWxuIG5pY2h0IGz2c2NoZW4gdW5kIFJlZ2VsPwogICAgIGlmKCEoZGVsX25vcnVsZSAmJiBwb2ludGVycChydWxlW2pdKSkgJiYKICAgICAgICAvLyBudXIgYmVzdGltbXRlIElEIGz2c2NoZW4gdW5kIElEIHBhc3N0IG5pY2h0PwogICAgICAgICEob25seWlkICYmICghcG9pbnRlcnAoaWRzKSB8fCBzaXplb2YoaWRzKTw9aiB8fCBpZHNbal0hPW9ubHlpZCkpICYmCiAgICAgICAgLy8gTPZzY2hyZWdlbCBleGlzdGllcnQgdW5kIHBhc3N0IG5pY2h0IGF1ZiBSZWdlbD8KICAgICAgICAhKGRlbHJ1bGUgJiYgKGs9c2l6ZW9mKHJ1bGVbal0pKSE9c2l6ZW9mKGRlbHJ1bGUpKSkgewogICAgICAvLyBwYXJ0aWVsbGVzIFRlc3RlbiBlaW5lciBM9nNjaHJlZ2VsIC4uLgogICAgICBpZihkZWxydWxlKSB7CiAgICAgICB3aGlsZShrLS0pCiAgICAgICAgaWYoIXNpemVvZihydWxlW2pdW2tdJmRlbHJ1bGVba10pKSBicmVhazsKICAgICAgIGlmKGs+PTApIGNvbnRpbnVlOwogICAgICB9CiAgICAgIC8vIGFsbGVzIGtvcnJla3Q6IEz2c2NoZW4hCiAgICAgIC8vIChBcnJheWJlcmVpY2ggZHVyY2ggbGVlcmVzIEFycmF5IGxvZXNjaGVuKQogICAgICBmbGFnW2ouLmpdICA9IGFsbG9jYXRlKDApOwogICAgICBmdW5bai4ual0gICA9IGFsbG9jYXRlKDApOwogICAgICBydWxlW2ouLmpdICA9IGFsbG9jYXRlKDApOwogICAgICBpZihpZHMpIHsKICAgICAgIGlkc1tqLi5qXSA9IGFsbG9jYXRlKDApOwogICAgICAgaWYoIXNpemVvZihpZHMtYWxsb2NhdGUoMSkpKSBpZHM9KG1peGVkKikwOwogICAgICB9CiAgICAgIHJldCsrOwogICAgIH0KICAgIH0gLy8gZW5kIHdoaWxlKGotLSkgewogICB9CiAgIC8vIEZ1bmt0aW9ucy9SZWdlbGxpc3RlIHVwZGF0ZSBvZGVyIGdnZi4gS29tbWFuZG8gdm9lbGxpZyBsb2VzY2hlbgogICBpZihzaXplb2YocnVsZSkpIHsKICAgIGFkZGVkX2NtZHNbY21kW2ldLDBdPWZ1bjsKICAgIGFkZGVkX2NtZHNbY21kW2ldLDFdPWZsYWc7CiAgICBhZGRlZF9jbWRzW2NtZFtpXSwyXT1ydWxlOwogICAgYWRkZWRfY21kc1tjbWRbaV0sM109aWRzOwogICB9IGVsc2UgbV9kZWxldGUoYWRkZWRfY21kcyxjbWRbaV0pOwogIH0KICBpZighc2l6ZW9mKGFkZGVkX2NtZHMpKSBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CiB9CiByZXR1cm4gcmV0Owp9CgovLyBBdXNmdWVocmVuIHNhbXQgZ2VwYXJzdGVtIElucHV0c3RyaW5nIHVuZCBnZXRyaWdnZXJ0ZW4gUGFyc2VyZXJnZWJuaXNzZW4Kc3RhdGljIGludCBfZXhlY3V0ZShtaXhlZCBmdW4sIHN0cmluZyBzdHIsIG1peGVkICpwYXJzZWQpIHsKIGlmKGNsb3N1cmVwKGZ1bikpCiAgcmV0dXJuICgoaW50KWZ1bmNhbGwoZnVuLHN0ciwmcGFyc2VkKSk7CiBpZihzdHJpbmdwKGZ1bikpCiAgcmV0dXJuICgoaW50KWNhbGxfb3RoZXIodGhpc19vYmplY3QoKSxmdW4sc3RyLCZwYXJzZWQpKTsKIHJldHVybiAwOwp9CgojZGVmaW5lIENIRUNLX1BSRVNFTlQgICAgIDEKI2RlZmluZSBDSEVDS19JRCAgICAgICAgICAyCiNkZWZpbmUgQ0hFQ0tfUFVUR0VUTk9ORSAgNAojZGVmaW5lIENIRUNLX1BVVEdFVERST1AgIDgKI2RlZmluZSBDSEVDS19QVVRHRVRUQUtFICAxNgojZGVmaW5lIENIRUNLX1BVVEdFVCAgICAgIChDSEVDS19QVVRHRVROT05FfENIRUNLX1BVVEdFVERST1B8Q0hFQ0tfUFVUR0VUVEFLRSkKCi8vIFdlcnQgZnVlciBGZWhsc2NobGFnLCBGYWxsYmFjay1XZXJ0IGRlciBiZW51dHp0ZW4gd2hpbGUtLSAtIFNjaGxlaWZlbgojZGVmaW5lIE5PTUFUQ0hGT1VORCAgICAgIC0xCgovLyBSZWdlbG4gZnVlciBlaW4gKG51biB1bndpY2h0aWdlcykgVmVyYiB0cmlnZ2VybgpzdGF0aWMgaW50IF9wcm9jZXNzX2NvbW1hbmQoc3RyaW5nIHN0ciwgc3RyaW5nICpub3BhcnNlc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgZnVuLCBtaXhlZCBmbGFnLCBtaXhlZCBydWxlLCBtaXhlZCBpZCkKewogbWl4ZWQgKnBhcnNlZCwgKm9iam1hdGNoZXM7CgogLy8gZWluZSBSZWdlbCAuLi4gYXVzd2VydGVuIC4uLgogaWYocG9pbnRlcnAocnVsZSkpIHsKICBpbnQgbnJ1bDsKICBwYXJzZWQ9b2JqbWF0Y2hlcz1hbGxvY2F0ZSgwKTsKICBpbnQgbGFzdG1hdGNocG9zPU5PTUFUQ0hGT1VORDsKCiAgLy8gQWJnbGVpY2hlbiBkZXIgZ2VzcGxpdHRldGVuIEVpbmdhYmUgbWl0IFJlZ2VsbjoKICAvLyB2b3J3YWVydHMgZHVyY2ggZGllIFN5bm9ueW1ncnVwcGVuCiAgaW50IHJzPXNpemVvZihydWxlKTsKICB3aGlsZShucnVsPHJzKSB7CiAgIGludCBtYXRjaHBvczsKICAgc3RyaW5nICpzeW5vbnltOwogICBtaXhlZCBtYXRjaHN0cjsKCiAgIG1hdGNocG9zPU5PTUFUQ0hGT1VORDsKICAgbWF0Y2hzdHI9MDsKCiAgIC8vIFN5bm9ueW1lIGV4dHJhaGllcmVuCiAgIGludCBucnN5bm9ueW1zPXNpemVvZihzeW5vbnltPXJ1bGVbbnJ1bF0pOwoKICAgLy8gZWdhbCB3aWUgZHVyY2ggU3lub255bWUgYmlzIE1hdGNoIC0gQWJnbGVpY2ggbWl0IEVpbmdhYmUKICAgd2hpbGUobnJzeW5vbnltcy0tKSB7CiAgICBpbnQgdG1wcG9zID0gbWVtYmVyKG5vcGFyc2VzdHIsc3lub255bVtucnN5bm9ueW1zXSk7CiAgICAvLyBpc3QgU3lub255bSBpbSBFaW5nYWJlc3RyaW5nIHVuZCBrb21tdCBzcGFldGVyIGFscyB2b3JoZXJpZ2VzIFN5bm9ueW0/CiAgICBpZih0bXBwb3M+PTAgJiYgdG1wcG9zPmxhc3RtYXRjaHBvcykgewogICAgIC8vIEVyZm9sZzogbWVya2VuIGRlciBQb3NpdGlvbiBpbSBFaW5nYWJlc3RyaW5nIHVuZCBkZW4gbWF0Y2hlbmRlbiBTdHJpbmcKICAgICBtYXRjaHBvcz10bXBwb3M7CiAgICAgbWF0Y2hzdHI9bm9wYXJzZXN0clt0bXBwb3NdOwogICAgIGJyZWFrOwogICAgfQogICB9CgogICAvLyBrZWluIE1hdGNoIGR1cmNoIFN5bm9ueW1lPyBQcnVlZmUgZGllIEAtU3BlemlhbHZhcmlhYmxlbi4KICAgaWYobWF0Y2hwb3MgPT0gTk9NQVRDSEZPVU5EKSB7CiAgICBpbnQgY2hlY2tfcHJlc2VudDsKICAgIC8vIGlzdCBBYnBydWVmZW4gdm9uIElEL1BSRVNFTlQgaW4gZGVyIFN5bm9ueW1ncnVwcGUgdmVybGFuZ3QKICAgIC8vIGJlaSBwcmVzZW50KCkvZmluZF9vYnMgZ2xlaWNoIFZvcmF1c3NldHp1bmcgZ3VlbHRpZ2VyIFRQIG1pdHBydWZlbgogICAgaWYobWVtYmVyKHN5bm9ueW0sIkBJRCIpPj0wKSBjaGVja19wcmVzZW50PUNIRUNLX0lEOwogICAgaWYodGhpc19wbGF5ZXIoKSkgewogICAgIGlmKG1lbWJlcihzeW5vbnltLCJAUFJFU0VOVCIpPj0wKSBjaGVja19wcmVzZW50fD1DSEVDS19QUkVTRU5UOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX05PTkUiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVROT05FOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX1RBS0UiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVREUk9QOwogICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX0RST1AiKT49MCkKCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVRUQUtFOwogICAgfQoKICAgIGlmKGNoZWNrX3ByZXNlbnQpIHsKICAgICAvLyB3aXIgZmFuZ2VuIGhpbnRlciBkZW0gbGV0enRlbiBNYXRjaCBhbgogICAgIGludCBxX3N0YXJ0PWxhc3RtYXRjaHBvcysxOwogICAgIGludCByX2VuZD1zaXplb2Yobm9wYXJzZXN0ciktMTsKCiAgICAgaW50IHJhbmdlOwogICAgIHdoaWxlKChyYW5nZT1yX2VuZC1xX3N0YXJ0KT49MCkgewogICAgICBtaXhlZCB0bXBvYmo7CgogICAgICAvLyB3aWUgd2VpdCB3b2xsZW4gd2lyIHp1cvxja2dlaGVuPwogICAgICBpZihyYW5nZSkKICAgICAgICBpZighKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFVUR0VUKSkKICAgICAgICAgIHJhbmdlPXJhbmdlPjI/MjpyYW5nZTsgLy8gMyBGcmFnbWVudGUgZnVlciBASUQvQFBSRVNFTlQgKEFkdmVyYi9OcikKICAgICAgICBlbHNlIGlmKHJhbmdlPjQpCiAgICAgICAgICByYW5nZT00OyAgICAgICAgICAgICAgIC8vIDUgRnJhZ21lbnRlIGZ1ZXIgQFBVVF9YWFggCgogICAgICAvLyB1bmQgamV0enQgZGllIFN1YnN0cmluZ3MgcHJ1ZWZlbgogICAgICB3aGlsZShyYW5nZT49MCAmJiAhbWF0Y2hzdHIpIHsKICAgICAgIHN0cmluZyB0bXBzdHI7CgogICAgICAgLy8genUgcHJ1ZWZlbmRlbiBTdHJpbmcgYXVzIGRlbiBUZWlsZW4genVzYW1tZW5zZXR6ZW4KICAgICAgIGlmKHJhbmdlKSB0bXBzdHI9aW1wbG9kZShub3BhcnNlc3RyW3Ffc3RhcnQuLihxX3N0YXJ0K3JhbmdlKV0sIiAiKTsKICAgICAgIGVsc2UgdG1wc3RyPW5vcGFyc2VzdHJbcV9zdGFydF07CgogICAgICAgLy9EQkcodG1wc3RyKTsKICAgICAgIGlmKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFJFU0VOVCAmJgkJCS8vIFBSRVNFTlQgPwogICAgICAgICAgKCh0bXBvYmo9cHJlc2VudCh0bXBzdHIsdGhpc19wbGF5ZXIoKSkpIHx8CiAgICAgICAgICAgKHRtcG9iaj1wcmVzZW50KHRtcHN0cixlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSkpKSkKICAgICAgICBtYXRjaHN0cj10bXBvYmo7CiAgICAgICBlbHNlIGlmKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfSUQgJiYgaWQodG1wc3RyKSkJLy8gSUQgPwogICAgICAgIG1hdGNoc3RyPXRoaXNfb2JqZWN0KCk7CiAgICAgICBlbHNlIGlmKChjaGVja19wcmVzZW50JkNIRUNLX1BVVEdFVCkgJiYJLy8gUFVUX0dFVF8/Pz8gPwogICAgICAgICAgICAgICAodG1wb2JqPShvYmplY3QqKQogICAgICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLT5maW5kX29icyh0bXBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAoW0NIRUNLX1BVVEdFVE5PTkU6UFVUX0dFVF9OT05FLAogICAgICAgICAgICAgICAgICAgICAgICBDSEVDS19QVVRHRVREUk9QOlBVVF9HRVRfVEFLRSwKICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfUFVUR0VUVEFLRTpQVVRfR0VUX0RST1BdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NIRUNLX1BVVEdFVCZjaGVja19wcmVzZW50XSkpICYmCiAgICAgICAgICAgICAgIHNpemVvZih0bXBvYmopKSB7CiAgICAgICAgaWYoc2l6ZW9mKHRtcG9iaik9PTEpIG1hdGNoc3RyPXRtcG9ialswXTsKICAgICAgICBlbHNlIHsJLy8gQXJyYXlzIHdlcmRlbiB6d2lzY2hlbmdlc3BlaWNoZXJ0IC4uLgogICAgICAgICBvYmptYXRjaGVzKz0oe3NpemVvZihwYXJzZWQpLHRtcG9ian0pOwogICAgICAgICBtYXRjaHN0cj10bXBzdHI7CiAgICAgICAgfQogICAgICAgfSBlbHNlIHsgLy8gZGllc2VyIFN1YnN0cmluZyBoYXQgbmljaHQgZ2VtYXRjaHQKICAgICAgICAvLyBhYiB3ZW5pZ2VyIGFscyAzIFRlaWxlbiBpc3QgZGFzIE5pY2h0bWF0Y2hpbmcgZWluZXMgU3Vic3RyaW5ncyBtaXQKICAgICAgICAvLyBiZWVuZGVuZGVtIE51bWVyYWwgS3JpdGVyaXVtIGZ1ZXIgQWJicnVjaCAoIm9iamVrdCAyIiBzb2xsIG1hdGNoZW4pCiAgICAgICAgc3RyaW5nIG51bWVyYWxjaGVjazsKICAgICAgICBpZihyYW5nZSAmJiByYW5nZTw9MiAmJgogICAgICAgICAgIHNpemVvZihudW1lcmFsY2hlY2s9bm9wYXJzZXN0cltxX3N0YXJ0K3JhbmdlXSkgJiYKICAgICAgICAgICB0b19zdHJpbmcodG9faW50KG51bWVyYWxjaGVjaykpPT1udW1lcmFsY2hlY2spCiAgICAgICAgICBicmVhazsKCiAgICAgICAgLy8gU3Vic3RyaW5nbGFlbmdlIHZlcmt1ZXJ6ZW4gdW5kIHdlaXRlcgogICAgICAgIHJhbmdlLS07CiAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIE1hdGNoIGdlZnVuZGVuIQogICAgICBpZihtYXRjaHN0cikgewogICAgICAgbWF0Y2hwb3M9cmFuZ2UrcV9zdGFydDsKICAgICAgIC8vIERCRyhtYXRjaHBvcyk7CiAgICAgICBicmVhazsKICAgICAgfQogICAgICBxX3N0YXJ0Kys7CiAgICAgfSAvLyBlbmQgd2hpbGUKICAgIH0KICAgfQoKICAgLy8gRmVobGVybWVsZHVuZyBmdWVyIGRpZXNlIGZlaGxnZXNjaGxhZ2VuZSBTeW5vbnltZ3J1cHBlIHNldHplbgogICBpZihtYXRjaHBvcyA9PSBOT01BVENIRk9VTkQpIHsKICAgIC8vIEZlaGxlcm1lbGR1bmdlbiB1bmQgZWluIEVpbnRyYWcgYW4gZGVyIEZlaGxlcnN0ZWxsZT8KICAgIGlmKHBvaW50ZXJwKGZsYWcpICYmIHNpemVvZihmbGFnKT5ucnVsKSB7CgogICAgIG1hdGNoc3RyPWZsYWdbbnJ1bF07CgogICAgIGlmKHN0cmluZ3AobWF0Y2hzdHIpICYmIHNpemVvZihtYXRjaHN0cikpIHsKICAgICAgaWYobWVtYmVyKG1hdGNoc3RyLCdAJyk+PTApIHsKICAgICAgIG1hdGNoc3RyPXJlcGxhY2VfcGVyc29uYWwoJm1hdGNoc3RyLCh7dGhpc19wbGF5ZXIoKX0pK3BhcnNlZCwxKTsKICAgICAgIHN0cmluZyBzdGFtbT0oKHF1ZXJ5X3ZlcmIoKVs8MV1eJ2UnKT9xdWVyeV92ZXJiKCk6cXVlcnlfdmVyYigpWzAuLjwyXSk7CiAgICAgICBtYXRjaHN0cj1yZWdyZXBsYWNlKG1hdGNoc3RyLCJAVkVSQiIsY2FwaXRhbGl6ZShzdGFtbSksMSk7CiAgICAgICBtYXRjaHN0cj1yZWdyZXBsYWNlKG1hdGNoc3RyLCJAdmVyYiIsc3RhbW0sMSk7CiAgICAgIH0KCiAgICAgIC8vIGlzdCBGZWhsZXJtZWxkdW5nIGVpbiBXUklURT8KICAgICAgLy8gZGFubiByZXR1cm4gMSAhCiAgICAgIGlmKGludHAoZmxhZ1s8MV0pICYmIGZsYWdbPDFdPD1ucnVsKSB7CiAgICAgICBpZihtZW1iZXIobWF0Y2hzdHIsJ14nKT49MCkgewogICAgICAgIG1hdGNoc3RyPWV4cGxvZGUobWF0Y2hzdHIsIl4iKTsKICAgICAgICB3cml0ZShjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0clswXSw3OCwwLDEpKSk7CiAgICAgICAgaWYoc2l6ZW9mKG1hdGNoc3RyWzFdKSkKICAgICAgICAgc2F5KGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyWzFdLDc4LDAsMSkpLCh7dGhpc19wbGF5ZXIoKX0pICk7CiAgICAgICB9IGVsc2Ugd3JpdGUoY2FwaXRhbGl6ZShicmVha19zdHJpbmcobWF0Y2hzdHIsNzgsMCwxKSkpOwogICAgICAgcmV0dXJuIDE7CiAgICAgIH0gZWxzZSBub3RpZnlfZmFpbChjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0ciw3OCwwLDEpKSk7CiAgICAgfQogICAgfQogICAgcmV0dXJuIDA7CiAgIH0KCiAgIC8vIFVwZGF0ZW4gZGVyIEhpbGZzdmFyaWFibGVuCiAgIHBhcnNlZCs9KHttYXRjaHN0cn0pOwogICBsYXN0bWF0Y2hwb3M9bWF0Y2hwb3M7CiAgIG5ydWwrKzsKICB9IC8vIGVuZCB3aGlsZShucnVsPHJzKSAuLi4gRXJmb2xnIC4uLiBhYiB6dW0gbmFlY2hzdGVuIFJlZ2VsdGVpbAogfQoKIC8vIEFycmF5cyBkZXIgQC1PYmplY3RtYXRjaGVzIGluIFBhcmFtZXRlciBmdWVyIE1ldGhvZGUgcmVzdWJzdGl0dWllcmVuCiBpbnQgb2Jqc2l6ZTsKIGlmKChvYmpzaXplPXNpemVvZihvYmptYXRjaGVzKSkpCiAgd2hpbGUoKG9ianNpemUtPTIpPj0wKQogICBwYXJzZWRbb2JqbWF0Y2hlc1tvYmpzaXplXV09b2JqbWF0Y2hlc1tvYmpzaXplKzFdOwoKIC8vIGVyZm9sZ3JlaWNoIE1ldGhvZGUgZ2VmdW5kZW4vZWluZSBSZWdlbCBiaXMgenVtIEVuZGUgZHVyY2hnZXBhcnN0OgogcmV0dXJuKF9leGVjdXRlKCZmdW4sJnN0ciwmcGFyc2VkKSk7Cn0KCi8vIEF1c3dlcnR1bmcgLSBhZGRfYWN0aW9uLUZ1biAKcHVibGljIGludCBfY2woc3RyaW5nIHN0cikgewogaW50IG5pbmRleDsKIHN0cmluZyAqa2V5czsKIG1peGVkICpmbGFnOwogLy8gVmVyYiBleGlzdGllcnQsIEtvbW1hbmRvcyBhdWNoLCBFaW50cmFnIGZ1ZXIgVmVyYiBnZWZ1bmRlbgogaWYobWFwcGluZ3AoYWRkZWRfY21kcykgJiYgcXVlcnlfdmVyYigpKSB7CiAgbWl4ZWQgKmZ1biwgKnJ1bGUsICppZHM7CgogIC8vIGlzdCBkYXMgVmVyYiBlaW4gS2V5IGltIEtvbW1hbmRvbWFwcGluZz8KICBpZihtX2NvbnRhaW5zKCZmdW4sICZmbGFnLCAmcnVsZSwgJmlkcywgYWRkZWRfY21kcywgcXVlcnlfdmVyYigpKSkgewogICBzdHJpbmcgKm5vcGFyc2VzdHI7CiAgIG5pbmRleD1zaXplb2YoZnVuKTsKICAgbm9wYXJzZXN0cj1leHBsb2RlKChzdHJ8fCIiKSwiICIpLSh7IiJ9KTsKICAgLy8gZGFubiBtYXRjaGUgdW5nZXBhcnN0ZW4gSW5wdXQgZ2VnZW4gZXR3YWlnZSBSZWdlbG4KICAgLy8gLS0gbmljaHQgYWVuZGVybjogbmV1ZSBLb21tYW5kb3Mgc29sbGVuIGFsdGUgInVlYmVyc2NocmVpYmVuIiBrb2VubmVuCiAgIHdoaWxlKG5pbmRleC0tKQogICB7CiAgICBtaXhlZCBjbWRfaWQgPSAocG9pbnRlcnAoaWRzKSAmJiBzaXplb2YoaWRzKT5uaW5kZXgpID8gaWRzW25pbmRleF0gOiAwOwogICAgaWYoX3Byb2Nlc3NfY29tbWFuZCgmc3RyLCBub3BhcnNlc3RyLCBmdW5bbmluZGV4XSwgZmxhZ1tuaW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICBydWxlW25pbmRleF0sIGNtZF9pZCkpCiAgICB7CiAgICAgIEdpdmVFUChFUF9DTUQsIHF1ZXJ5X3ZlcmIoKSk7CiAgICAgIHJldHVybiAxOwogICAgfQogICB9CiAgfQoKICAvLyBrZWluZSBSZWdlbCBwYXNzdGUsIHVuc2NoYXJmZSBBdXN3ZXJ0dW5nIGF1ZiBhbGxlCiAgLy8gQWRkQ21kdmVyYmVuIGF1c2RlaG5lbgogIGtleXM9bV9pbmRpY2VzKGFkZGVkX2NtZHMpOwogIG5pbmRleD1zaXplb2Yoa2V5cyk7CiAgd2hpbGUobmluZGV4LS0pCiAgIGlmKCFzdHJzdHIocXVlcnlfdmVyYigpLGtleXNbbmluZGV4XSkgJiYKICAgICAgbWVtYmVyKChmbGFnPWFkZGVkX2NtZHNba2V5c1tuaW5kZXhdLDFdKSwxKT49MCkgewogICAgaW50IGkscmV0OwogICAgaT1zaXplb2YoZmxhZyk7CiAgICAvLyBSZWloZW5mb2xnZSBuaWNodCBhZW5kZXJuICEKICAgIHdoaWxlKGktLSkKICAgICAgaWYoZmxhZ1tpXT09MSkgewogICAgICAgIG1peGVkICpleGVjID0gYWRkZWRfY21kc1trZXlzW25pbmRleF0sMF07CiAgICAgICAgaWYoIXBvaW50ZXJwKGV4ZWMpIHx8IHNpemVvZihleGVjKTw9aSkKICAgICAgICAgIGNhdGNoKHJhaXNlX2Vycm9yKAogICAgICAgICAgICAiQWRkQ21kLUF1c3dlcnR1bmc6IENhdGNoQWxsLUtvbW1hbmRvIFwiIitrZXlzW25pbmRleF0rIlwiIgogICAgICAgICAgICAiIHd1cmRlIHdhZWhyZW5kIGRlciBBdXNmdWVocnVuZyB2ZXJhZW5kZXJ0IG9kZXIgZ2Vsb2VzY2h0LiAiCiAgICAgICAgICAgICJLbGFydGV4dDogRGFzIGlzdCBzY2hsZWNodC4gU3VjaHQgZWluIFJlbW92ZUNtZD8gIik7CiAgICAgICAgICAgIHB1Ymxpc2gpOwogICAgICAgIGVsc2UgaWYoX2V4ZWN1dGUoZXhlY1tpXSxzdHIsMCkpIHsKICAgICAgICAgIEdpdmVFUChFUF9DTUQsIHF1ZXJ5X3ZlcmIoKSk7CiAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgIH0KICAgfQogfQogcmV0dXJuIDA7Cn0KCnZvaWQgaW5pdCgpIHsKIGFkZF9hY3Rpb24oIl9jbCIsIiIsMSk7Cn0KCgpzdGF0aWMgdm9pZCBfY2hlY2tfY29weV9jb21tYW5kcyhzdHJpbmcgaW5kLCBtaXhlZCAqZnVuLAoJCQkJICBtaXhlZCAqZmxhZywgbWl4ZWQgKnJ1bGUpIHsKIGlmKHBvaW50ZXJwKGZ1bikpIGFkZGVkX2NtZHNbaW5kLDBdPWZ1bithbGxvY2F0ZSgwKTsKIGVsc2UgYWRkZWRfY21kc1tpbmQsMF09KHtmdW59KTsKIGlmKHBvaW50ZXJwKGZsYWcpKSBhZGRlZF9jbWRzW2luZCwxXT1mbGFnK2FsbG9jYXRlKDApOwogZWxzZSBpZihmbGFnKSBhZGRlZF9jbWRzW2luZCwxXT0oe2ZsYWd9KTsKIGVsc2UgYWRkZWRfY21kc1tpbmQsMV09YWxsb2NhdGUoc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkpOwogaWYocG9pbnRlcnAocnVsZSkpIGFkZGVkX2NtZHNbaW5kLDJdPXJ1bGUrYWxsb2NhdGUoMCk7CiBlbHNlIGFkZGVkX2NtZHNbaW5kLDJdPWFsbG9jYXRlKHNpemVvZihhZGRlZF9jbWRzW2luZF0pKTsKCiBpZihzaXplb2YoYWRkZWRfY21kc1tpbmRdKSE9c2l6ZW9mKGFkZGVkX2NtZHNbaW5kLDFdKSB8fAogICAgc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkhPXNpemVvZihhZGRlZF9jbWRzW2luZCwyXSkpIHsKICBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CiAgcmFpc2VfZXJyb3IoIlNldFByb3AoUF9DT01NQU5EUyk6IGNvcnJ1cHQgY29tbWFuZHMtbWFwcGluZy5cbiIpOwogfQp9CgpzdGF0aWMgbWFwcGluZyBfc2V0X2NvbW1hbmRzKG1hcHBpbmcgY29tbWFuZHMpIHsKIGlmKCFjb21tYW5kcykgYWRkZWRfY21kcz0obWFwcGluZykwOwogZWxzZSBpZihtYXBwaW5ncChjb21tYW5kcykpIHsKICBhZGRlZF9jbWRzPW1fYWxsb2NhdGUoc2l6ZW9mKGNvbW1hbmRzKSw0KTsKICB3YWxrX21hcHBpbmcoY29tbWFuZHMsIydfY2hlY2tfY29weV9jb21tYW5kcyk7CiB9CiBpZiAobWFwcGluZ3AoYWRkZWRfY21kcykpCiAgIHJldHVybihkZWVwX2NvcHkoYWRkZWRfY21kcykpOwogZWxzZQogICByZXR1cm4gKG1hcHBpbmcpMDsKfQoKc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2NvbW1hbmRzKCkgewogaWYgKG1hcHBpbmdwKGFkZGVkX2NtZHMpKQogICByZXR1cm4oZGVlcF9jb3B5KGFkZGVkX2NtZHMpKTsKIGVsc2UKICAgcmV0dXJuIChtYXBwaW5nKTA7Cn0KCg==