aW1wb3J0IHRlc3Rfc3VwcG9ydAppbXBvcnQgdW5pdHRlc3QKCmZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwpmcm9tIHF1b3ByaSBpbXBvcnQgKgoKCgpFTkNTQU1QTEUgPSAiIiJcCkhlcmUncyBhIGJ1bmNoIG9mIHNwZWNpYWw9MjAKCj1BMT1BMj1BMz1BND1BNT1BNj1BNz1BOD1BOQo9QUE9QUI9QUM9QUQ9QUU9QUY9QjA9QjE9QjI9QjMKPUI0PUI1PUI2PUI3PUI4PUI5PUJBPUJCPUJDPUJEPUJFCj1CRj1DMD1DMT1DMj1DMz1DND1DNT1DNgo9Qzc9Qzg9Qzk9Q0E9Q0I9Q0M9Q0Q9Q0U9Q0YKPUQwPUQxPUQyPUQzPUQ0PUQ1PUQ2PUQ3Cj1EOD1EOT1EQT1EQj1EQz1ERD1ERT1ERgo9RTA9RTE9RTI9RTM9RTQ9RTU9RTY9RTcKPUU4PUU5PUVBPUVCPUVDPUVEPUVFPUVGCj1GMD1GMT1GMj1GMz1GND1GNT1GNj1GNwo9Rjg9Rjk9RkE9RkI9RkM9RkQ9RkU9RkYKCmNoYXJhY3RlcnMuLi4gaGF2ZSBmdW4hCiIiIgoKIyBGaXJzdCBsaW5lIGVuZHMgd2l0aCBhIHNwYWNlCkRFQ1NBTVBMRSA9ICJIZXJlJ3MgYSBidW5jaCBvZiBzcGVjaWFsIFxuIiArIFwKIiIiXAoKoaKjpKWmp6ipCqqrrK2ur7CxsrMKtLW2t7i5uru8vb4Kv8DBwsPExcYKx8jJysvMzc7PCtDR0tPU1dbXCtjZ2tvc3d7fCuDh4uPk5ebnCujp6uvs7e7vCvDx8vP09fb3Cvj5+vv8/f7/CgpjaGFyYWN0ZXJzLi4uIGhhdmUgZnVuIQoiIiIKCgoKY2xhc3MgUXVvcHJpVGVzdENhc2UodW5pdHRlc3QuVGVzdENhc2UpOgogICAgIyBFYWNoIGVudHJ5IGlzIGEgdHVwbGUgb2YgKHBsYWludGV4dCwgZW5jb2RlZCBzdHJpbmcpLiAgVGhlc2Ugc3RyaW5ncyBhcmUKICAgICMgdXNlZCBpbiB0aGUgInF1b3RldGFicz0wIiB0ZXN0cy4KICAgIFNUUklOR1MgPSAoCiAgICAgICAgIyBTb21lIG5vcm1hbCBzdHJpbmdzCiAgICAgICAgKCdoZWxsbycsICdoZWxsbycpLAogICAgICAgICgnJydoZWxsbwogICAgICAgIHRoZXJlCiAgICAgICAgd29ybGQnJycsICcnJ2hlbGxvCiAgICAgICAgdGhlcmUKICAgICAgICB3b3JsZCcnJyksCiAgICAgICAgKCcnJ2hlbGxvCiAgICAgICAgdGhlcmUKICAgICAgICB3b3JsZAonJycsICcnJ2hlbGxvCiAgICAgICAgdGhlcmUKICAgICAgICB3b3JsZAonJycpLAogICAgICAgICgnXDIwMVwyMDJcMjAzJywgJz04MT04Mj04MycpLAogICAgICAgICMgQWRkIHNvbWUgdHJhaWxpbmcgTVVTVCBRVU9URSBzdHJpbmdzCiAgICAgICAgKCdoZWxsbyAnLCAnaGVsbG89MjAnKSwKICAgICAgICAoJ2hlbGxvXHQnLCAnaGVsbG89MDknKSwKICAgICAgICAjIFNvbWUgbG9uZyBsaW5lcy4gIEZpcnN0LCBhIHNpbmdsZSBsaW5lIG9mIDEwOCBjaGFyYWN0ZXJzCiAgICAgICAgKCd4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eNjZ2tvc3d7feHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHgnLAogICAgICAgICAnJyd4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eD1EOD1EOT1EQT1EQj1EQz1ERD1ERT1ERng9Cnh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHgnJycpLAogICAgICAgICMgQSBsaW5lIG9mIGV4YWN0bHkgNzYgY2hhcmFjdGVycywgbm8gc29mdCBsaW5lIGJyZWFrIHNob3VsZCBiZSBuZWVkZWQKICAgICAgICAoJ3l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXknLAogICAgICAgICd5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5JyksCiAgICAgICAgIyBBIGxpbmUgb2YgNzcgY2hhcmFjdGVycywgZm9yY2luZyBhIHNvZnQgbGluZSBicmVhayBhdCBwb3NpdGlvbiA3NSwKICAgICAgICAjIGFuZCBhIHNlY29uZCBsaW5lIG9mIGV4YWN0bHkgMiBjaGFyYWN0ZXJzIChiZWNhdXNlIHRoZSBzb2Z0IGxpbmUKICAgICAgICAjIGJyZWFrIGA9JyBzaWduIGNvdW50cyBhZ2FpbnN0IHRoZSBsaW5lIGxlbmd0aCBsaW1pdCkuCiAgICAgICAgKCd6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6eicsCiAgICAgICAgICcnJ3p6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6ej0KenonJycpLAogICAgICAgICMgQSBsaW5lIG9mIDE1MSBjaGFyYWN0ZXJzLCBmb3JjaW5nIGEgc29mdCBsaW5lIGJyZWFrIGF0IHBvc2l0aW9uIDc1LAogICAgICAgICMgd2l0aCBhIHNlY29uZCBsaW5lIG9mIGV4YWN0bHkgNzYgY2hhcmFjdGVycyBhbmQgbm8gdHJhaWxpbmcgPQogICAgICAgICgnenp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6eicsCiAgICAgICAgICcnJ3p6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6ej0Kenp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6eicnJyksCiAgICAgICAgIyBBIHN0cmluZyBjb250YWluaW5nIGEgaGFyZCBsaW5lIGJyZWFrLCBidXQgd2hpY2ggdGhlIGZpcnN0IGxpbmUgaXMKICAgICAgICAjIDE1MSBjaGFyYWN0ZXJzIGFuZCB0aGUgc2Vjb25kIGxpbmUgaXMgZXhhY3RseSA3NiBjaGFyYWN0ZXJzLiAgVGhpcwogICAgICAgICMgc2hvdWxkIGxlYXZlIHVzIHdpdGggdGhyZWUgbGluZXMsIHRoZSBmaXJzdCB3aGljaCBoYXMgYSBzb2Z0IGxpbmUKICAgICAgICAjIGJyZWFrLCBhbmQgd2hpY2ggdGhlIHNlY29uZCBhbmQgdGhpcmQgZG8gbm90LgogICAgICAgICgnJyd5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5Cnp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enonJycsCiAgICAgICAgICcnJ3l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eT0KeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eQp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6JycnKSwKICAgICAgICAjIE5vdyBzb21lIHJlYWxseSBjb21wbGV4IHN0dWZmIDspCiAgICAgICAgKERFQ1NBTVBMRSwgRU5DU0FNUExFKSwKICAgICAgICApCgogICAgIyBUaGVzZSBhcmUgdXNlZCBpbiB0aGUgInF1b3RldGFicz0xIiB0ZXN0cy4KICAgIEVTVFJJTkdTID0gKAogICAgICAgICgnaGVsbG8gd29ybGQnLCAnaGVsbG89MjB3b3JsZCcpLAogICAgICAgICgnaGVsbG9cdHdvcmxkJywgJ2hlbGxvPTA5d29ybGQnKSwKICAgICAgICApCgogICAgZGVmIHRlc3RfZW5jb2Rlc3RyaW5nKHNlbGYpOgogICAgICAgIGZvciBwLCBlIGluIHNlbGYuU1RSSU5HUzoKICAgICAgICAgICAgc2VsZi5hc3NlcnRfKGVuY29kZXN0cmluZyhwKSA9PSBlKQoKICAgIGRlZiB0ZXN0X2RlY29kZXN0cmluZyhzZWxmKToKICAgICAgICBmb3IgcCwgZSBpbiBzZWxmLlNUUklOR1M6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhkZWNvZGVzdHJpbmcoZSkgPT0gcCkKCiAgICBkZWYgdGVzdF9pZGVtcG90ZW50X3N0cmluZyhzZWxmKToKICAgICAgICBmb3IgcCwgZSBpbiBzZWxmLlNUUklOR1M6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0XyhkZWNvZGVzdHJpbmcoZW5jb2Rlc3RyaW5nKGUpKSA9PSBlKQoKICAgIGRlZiB0ZXN0X2VuY29kZShzZWxmKToKICAgICAgICBmb3IgcCwgZSBpbiBzZWxmLlNUUklOR1M6CiAgICAgICAgICAgIGluZnAgPSBTdHJpbmdJTyhwKQogICAgICAgICAgICBvdXRmcCA9IFN0cmluZ0lPKCkKICAgICAgICAgICAgZW5jb2RlKGluZnAsIG91dGZwLCBxdW90ZXRhYnM9MCkKICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG91dGZwLmdldHZhbHVlKCkgPT0gZSkKCiAgICBkZWYgdGVzdF9kZWNvZGUoc2VsZik6CiAgICAgICAgZm9yIHAsIGUgaW4gc2VsZi5TVFJJTkdTOgogICAgICAgICAgICBpbmZwID0gU3RyaW5nSU8oZSkKICAgICAgICAgICAgb3V0ZnAgPSBTdHJpbmdJTygpCiAgICAgICAgICAgIGRlY29kZShpbmZwLCBvdXRmcCkKICAgICAgICAgICAgc2VsZi5hc3NlcnRfKG91dGZwLmdldHZhbHVlKCkgPT0gcCkKCiAgICBkZWYgdGVzdF9lbWJlZGRlZF93cyhzZWxmKToKICAgICAgICBmb3IgcCwgZSBpbiBzZWxmLkVTVFJJTkdTOgogICAgICAgICAgICBzZWxmLmFzc2VydF8oZW5jb2Rlc3RyaW5nKHAsIHF1b3RldGFicz0xKSA9PSBlKQogICAgICAgICAgICBzZWxmLmFzc2VydF8oZGVjb2Rlc3RyaW5nKGUpID09IHApCgoKdGVzdF9zdXBwb3J0LnJ1bl91bml0dGVzdChRdW9wcmlUZXN0Q2FzZSkK