Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvZGJhcGkucHk6IHRlc3RzIGZvciBEQi1BUEkgY29tcGxpYW5jZQojCiMgQ29weXJpZ2h0IChDKSAyMDA0LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgdW5pdHRlc3QKaW1wb3J0IHN5cwppbXBvcnQgc3FsaXRlMyBhcyBzcWxpdGUKdHJ5OgogICAgaW1wb3J0IHRocmVhZGluZwpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICB0aHJlYWRpbmcgPSBOb25lCgpjbGFzcyBNb2R1bGVUZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgQ2hlY2tBUElMZXZlbChzZWxmKToKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNxbGl0ZS5hcGlsZXZlbCwgIjIuMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiYXBpbGV2ZWwgaXMgJXMsIHNob3VsZCBiZSAyLjAiICUgc3FsaXRlLmFwaWxldmVsKQoKICAgIGRlZiBDaGVja1RocmVhZFNhZmV0eShzZWxmKToKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNxbGl0ZS50aHJlYWRzYWZldHksIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAidGhyZWFkc2FmZXR5IGlzICVkLCBzaG91bGQgYmUgMSIgJSBzcWxpdGUudGhyZWFkc2FmZXR5KQoKICAgIGRlZiBDaGVja1BhcmFtU3R5bGUoc2VsZik6CiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzcWxpdGUucGFyYW1zdHlsZSwgInFtYXJrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICJwYXJhbXN0eWxlIGlzICclcycsIHNob3VsZCBiZSAncW1hcmsnIiAlCiAgICAgICAgICAgICAgICAgICAgICAgICBzcWxpdGUucGFyYW1zdHlsZSkKCiAgICBkZWYgQ2hlY2tXYXJuaW5nKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0Xyhpc3N1YmNsYXNzKHNxbGl0ZS5XYXJuaW5nLCBTdGFuZGFyZEVycm9yKSwKICAgICAgICAgICAgICAgICAgICAgIldhcm5pbmcgaXMgbm90IGEgc3ViY2xhc3Mgb2YgU3RhbmRhcmRFcnJvciIpCgogICAgZGVmIENoZWNrRXJyb3Ioc2VsZik6CiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGlzc3ViY2xhc3Moc3FsaXRlLkVycm9yLCBTdGFuZGFyZEVycm9yKSwKICAgICAgICAgICAgICAgICAgICAgICAgIkVycm9yIGlzIG5vdCBhIHN1YmNsYXNzIG9mIFN0YW5kYXJkRXJyb3IiKQoKICAgIGRlZiBDaGVja0ludGVyZmFjZUVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5JbnRlcmZhY2VFcnJvciwgc3FsaXRlLkVycm9yKSwKICAgICAgICAgICAgICAgICAgICAgICAgIkludGVyZmFjZUVycm9yIGlzIG5vdCBhIHN1YmNsYXNzIG9mIEVycm9yIikKCiAgICBkZWYgQ2hlY2tEYXRhYmFzZUVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5EYXRhYmFzZUVycm9yLCBzcWxpdGUuRXJyb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAiRGF0YWJhc2VFcnJvciBpcyBub3QgYSBzdWJjbGFzcyBvZiBFcnJvciIpCgogICAgZGVmIENoZWNrRGF0YUVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5EYXRhRXJyb3IsIHNxbGl0ZS5EYXRhYmFzZUVycm9yKSwKICAgICAgICAgICAgICAgICAgICAgICAgIkRhdGFFcnJvciBpcyBub3QgYSBzdWJjbGFzcyBvZiBEYXRhYmFzZUVycm9yIikKCiAgICBkZWYgQ2hlY2tPcGVyYXRpb25hbEVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yLCBzcWxpdGUuRGF0YWJhc2VFcnJvciksCiAgICAgICAgICAgICAgICAgICAgICAgICJPcGVyYXRpb25hbEVycm9yIGlzIG5vdCBhIHN1YmNsYXNzIG9mIERhdGFiYXNlRXJyb3IiKQoKICAgIGRlZiBDaGVja0ludGVncml0eUVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5JbnRlZ3JpdHlFcnJvciwgc3FsaXRlLkRhdGFiYXNlRXJyb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAiSW50ZWdyaXR5RXJyb3IgaXMgbm90IGEgc3ViY2xhc3Mgb2YgRGF0YWJhc2VFcnJvciIpCgogICAgZGVmIENoZWNrSW50ZXJuYWxFcnJvcihzZWxmKToKICAgICAgICBzZWxmLmFzc2VydFRydWUoaXNzdWJjbGFzcyhzcWxpdGUuSW50ZXJuYWxFcnJvciwgc3FsaXRlLkRhdGFiYXNlRXJyb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAiSW50ZXJuYWxFcnJvciBpcyBub3QgYSBzdWJjbGFzcyBvZiBEYXRhYmFzZUVycm9yIikKCiAgICBkZWYgQ2hlY2tQcm9ncmFtbWluZ0Vycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yLCBzcWxpdGUuRGF0YWJhc2VFcnJvciksCiAgICAgICAgICAgICAgICAgICAgICAgICJQcm9ncmFtbWluZ0Vycm9yIGlzIG5vdCBhIHN1YmNsYXNzIG9mIERhdGFiYXNlRXJyb3IiKQoKICAgIGRlZiBDaGVja05vdFN1cHBvcnRlZEVycm9yKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpc3N1YmNsYXNzKHNxbGl0ZS5Ob3RTdXBwb3J0ZWRFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcWxpdGUuRGF0YWJhc2VFcnJvciksCiAgICAgICAgICAgICAgICAgICAgICAgICJOb3RTdXBwb3J0ZWRFcnJvciBpcyBub3QgYSBzdWJjbGFzcyBvZiBEYXRhYmFzZUVycm9yIikKCmNsYXNzIENvbm5lY3Rpb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgc2VsZi5jeCA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3UgPSBzZWxmLmN4LmN1cnNvcigpCiAgICAgICAgY3UuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaWQgaW50ZWdlciBwcmltYXJ5IGtleSwgbmFtZSB0ZXh0KSIpCiAgICAgICAgY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKD8pIiwgKCJmb28iLCkpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY3guY2xvc2UoKQoKICAgIGRlZiBDaGVja0NvbW1pdChzZWxmKToKICAgICAgICBzZWxmLmN4LmNvbW1pdCgpCgogICAgZGVmIENoZWNrQ29tbWl0QWZ0ZXJOb0NoYW5nZXMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQSBjb21taXQgc2hvdWxkIGFsc28gd29yayB3aGVuIG5vIGNoYW5nZXMgd2VyZSBtYWRlIHRvIHRoZSBkYXRhYmFzZS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmN4LmNvbW1pdCgpCiAgICAgICAgc2VsZi5jeC5jb21taXQoKQoKICAgIGRlZiBDaGVja1JvbGxiYWNrKHNlbGYpOgogICAgICAgIHNlbGYuY3gucm9sbGJhY2soKQoKICAgIGRlZiBDaGVja1JvbGxiYWNrQWZ0ZXJOb0NoYW5nZXMoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQSByb2xsYmFjayBzaG91bGQgYWxzbyB3b3JrIHdoZW4gbm8gY2hhbmdlcyB3ZXJlIG1hZGUgdG8gdGhlIGRhdGFiYXNlLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY3gucm9sbGJhY2soKQogICAgICAgIHNlbGYuY3gucm9sbGJhY2soKQoKICAgIGRlZiBDaGVja0N1cnNvcihzZWxmKToKICAgICAgICBjdSA9IHNlbGYuY3guY3Vyc29yKCkKCiAgICBkZWYgQ2hlY2tGYWlsZWRPcGVuKHNlbGYpOgogICAgICAgIFlPVV9DQU5OT1RfT1BFTl9USElTID0gIi9mb28vYmFyL2JsYS8yMzUzNC9teWRiLmRiIgogICAgICAgIHRyeToKICAgICAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoWU9VX0NBTk5PVF9PUEVOX1RISVMpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKCiAgICBkZWYgQ2hlY2tDbG9zZShzZWxmKToKICAgICAgICBzZWxmLmN4LmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tFeGNlcHRpb25zKHNlbGYpOgogICAgICAgICMgT3B0aW9uYWwgREItQVBJIGV4dGVuc2lvbi4KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuY3guV2FybmluZywgc3FsaXRlLldhcm5pbmcpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN4LkVycm9yLCBzcWxpdGUuRXJyb3IpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN4LkludGVyZmFjZUVycm9yLCBzcWxpdGUuSW50ZXJmYWNlRXJyb3IpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN4LkRhdGFiYXNlRXJyb3IsIHNxbGl0ZS5EYXRhYmFzZUVycm9yKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jeC5EYXRhRXJyb3IsIHNxbGl0ZS5EYXRhRXJyb3IpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN4Lk9wZXJhdGlvbmFsRXJyb3IsIHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jeC5JbnRlZ3JpdHlFcnJvciwgc3FsaXRlLkludGVncml0eUVycm9yKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jeC5JbnRlcm5hbEVycm9yLCBzcWxpdGUuSW50ZXJuYWxFcnJvcikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuY3guUHJvZ3JhbW1pbmdFcnJvciwgc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN4Lk5vdFN1cHBvcnRlZEVycm9yLCBzcWxpdGUuTm90U3VwcG9ydGVkRXJyb3IpCgpjbGFzcyBDdXJzb3JUZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgc2VsZi5jeCA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgc2VsZi5jdSA9IHNlbGYuY3guY3Vyc29yKCkKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGlkIGludGVnZXIgcHJpbWFyeSBrZXksIG5hbWUgdGV4dCwgaW5jb21lIG51bWJlcikiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKD8pIiwgKCJmb28iLCkpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY3UuY2xvc2UoKQogICAgICAgIHNlbGYuY3guY2xvc2UoKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVOb0FyZ3Moc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJkZWxldGUgZnJvbSB0ZXN0IikKCiAgICBkZWYgQ2hlY2tFeGVjdXRlSWxsZWdhbFNxbChzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IGFzZGYiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJyYWlzZWQgd3JvbmcgZXhjZXB0aW9uIikKCiAgICBkZWYgQ2hlY2tFeGVjdXRlVG9vTXVjaFNxbChzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IDUrNDsgc2VsZWN0IDQrNSIpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGEgV2FybmluZyIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5XYXJuaW5nOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgicmFpc2VkIHdyb25nIGV4Y2VwdGlvbiIpCgogICAgZGVmIENoZWNrRXhlY3V0ZVRvb011Y2hTcWwyKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IDUrNDsgLS0gZm9vIGJhciIpCgogICAgZGVmIENoZWNrRXhlY3V0ZVRvb011Y2hTcWwzKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiIiIKICAgICAgICAgICAgc2VsZWN0IDUrNDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgIGZvbwogICAgICAgICAgICAqLwogICAgICAgICAgICAiIiIpCgogICAgZGVmIENoZWNrRXhlY3V0ZVdyb25nU3FsQXJnKHNlbGYpOgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdS5leGVjdXRlKDQyKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFZhbHVlRXJyb3IiKQogICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgicmFpc2VkIHdyb25nIGV4Y2VwdGlvbi4iKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVBcmdJbnQoc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGlkKSB2YWx1ZXMgKD8pIiwgKDQyLCkpCgogICAgZGVmIENoZWNrRXhlY3V0ZUFyZ0Zsb2F0KHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpbmNvbWUpIHZhbHVlcyAoPykiLCAoMjUwMC4zMiwpKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVBcmdTdHJpbmcoc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KG5hbWUpIHZhbHVlcyAoPykiLCAoIkh1Z28iLCkpCgogICAgZGVmIENoZWNrRXhlY3V0ZVdyb25nTm9PZkFyZ3MxKHNlbGYpOgogICAgICAgICMgdG9vIG1hbnkgcGFyYW1ldGVycwogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGlkKSB2YWx1ZXMgKD8pIiwgKDE3LCAiRWdvbiIpKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgQ2hlY2tFeGVjdXRlV3JvbmdOb09mQXJnczIoc2VsZik6CiAgICAgICAgIyB0b28gbGl0dGxlIHBhcmFtZXRlcnMKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpZCkgdmFsdWVzICg/KSIpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgcGFzcwoKICAgIGRlZiBDaGVja0V4ZWN1dGVXcm9uZ05vT2ZBcmdzMyhzZWxmKToKICAgICAgICAjIG5vIHBhcmFtZXRlcnMsIHBhcmFtZXRlcnMgYXJlIG5lZWRlZAogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGlkKSB2YWx1ZXMgKD8pIikKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrRXhlY3V0ZVBhcmFtTGlzdChzZWxmKToKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IHdoZXJlIG5hbWU9PyIsIFsiZm9vIl0pCiAgICAgICAgcm93ID0gc2VsZi5jdS5mZXRjaG9uZSgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sICJmb28iKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVQYXJhbVNlcXVlbmNlKHNlbGYpOgogICAgICAgIGNsYXNzIEwob2JqZWN0KToKICAgICAgICAgICAgZGVmIF9fbGVuX18oc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gMQogICAgICAgICAgICBkZWYgX19nZXRpdGVtX18oc2VsZiwgeCk6CiAgICAgICAgICAgICAgICBhc3NlcnQgeCA9PSAwCiAgICAgICAgICAgICAgICByZXR1cm4gImZvbyIKCiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KG5hbWUpIHZhbHVlcyAoJ2ZvbycpIikKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoInNlbGVjdCBuYW1lIGZyb20gdGVzdCB3aGVyZSBuYW1lPT8iLCBMKCkpCiAgICAgICAgcm93ID0gc2VsZi5jdS5mZXRjaG9uZSgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sICJmb28iKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVEaWN0TWFwcGluZyhzZWxmKToKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IHdoZXJlIG5hbWU9Om5hbWUiLCB7Im5hbWUiOiAiZm9vIn0pCiAgICAgICAgcm93ID0gc2VsZi5jdS5mZXRjaG9uZSgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sICJmb28iKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVEaWN0TWFwcGluZ19NYXBwaW5nKHNlbGYpOgogICAgICAgICMgVGVzdCBvbmx5IHdvcmtzIHdpdGggUHl0aG9uIDIuNSBvciBsYXRlcgogICAgICAgIGlmIHN5cy52ZXJzaW9uX2luZm8gPCAoMiwgNSwgMCk6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBjbGFzcyBEKGRpY3QpOgogICAgICAgICAgICBkZWYgX19taXNzaW5nX18oc2VsZiwga2V5KToKICAgICAgICAgICAgICAgIHJldHVybiAiZm9vIgoKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IHdoZXJlIG5hbWU9Om5hbWUiLCBEKCkpCiAgICAgICAgcm93ID0gc2VsZi5jdS5mZXRjaG9uZSgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sICJmb28iKQoKICAgIGRlZiBDaGVja0V4ZWN1dGVEaWN0TWFwcGluZ1Rvb0xpdHRsZUFyZ3Moc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KG5hbWUpIHZhbHVlcyAoJ2ZvbycpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IHdoZXJlIG5hbWU9Om5hbWUgYW5kIGlkPTppZCIsIHsibmFtZSI6ICJmb28ifSkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrRXhlY3V0ZURpY3RNYXBwaW5nTm9BcmdzKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdmb28nKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoInNlbGVjdCBuYW1lIGZyb20gdGVzdCB3aGVyZSBuYW1lPTpuYW1lIikKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrRXhlY3V0ZURpY3RNYXBwaW5nVW5uYW1lZChzZWxmKToKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJzZWxlY3QgbmFtZSBmcm9tIHRlc3Qgd2hlcmUgbmFtZT0/IiwgeyJuYW1lIjogImZvbyJ9KQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgQ2hlY2tDbG9zZShzZWxmKToKICAgICAgICBzZWxmLmN1LmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tSb3djb3VudEV4ZWN1dGUoc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJkZWxldGUgZnJvbSB0ZXN0IikKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdmb28nKSIpCiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJ1cGRhdGUgdGVzdCBzZXQgbmFtZT0nYmFyJyIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN1LnJvd2NvdW50LCAyKQoKICAgIGRlZiBDaGVja1Jvd2NvdW50U2VsZWN0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIGRvZXMgbm90IGtub3cgdGhlIHJvd2NvdW50IG9mIFNFTEVDVCBzdGF0ZW1lbnRzLCBiZWNhdXNlIHdlCiAgICAgICAgZG9uJ3QgZmV0Y2ggYWxsIHJvd3MgYWZ0ZXIgZXhlY3V0aW5nIHRoZSBzZWxlY3Qgc3RhdGVtZW50LiBUaGUgcm93Y291bnQKICAgICAgICBoYXMgdGh1cyB0byBiZSAtMS4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoInNlbGVjdCA1IHVuaW9uIHNlbGVjdCA2IikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHNlbGYuY3Uucm93Y291bnQsIC0xKQoKICAgIGRlZiBDaGVja1Jvd2NvdW50RXhlY3V0ZW1hbnkoc2VsZik6CiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJkZWxldGUgZnJvbSB0ZXN0IikKICAgICAgICBzZWxmLmN1LmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byB0ZXN0KG5hbWUpIHZhbHVlcyAoPykiLCBbKDEsKSwgKDIsKSwgKDMsKV0pCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmN1LnJvd2NvdW50LCAzKQoKICAgIGRlZiBDaGVja1RvdGFsQ2hhbmdlcyhzZWxmKToKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QobmFtZSkgdmFsdWVzICgnZm9vJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdmb28nKSIpCiAgICAgICAgaWYgc2VsZi5jeC50b3RhbF9jaGFuZ2VzIDwgMjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJ0b3RhbCBjaGFuZ2VzIHJlcG9ydGVkIHdyb25nIHZhbHVlIikKCiAgICAjIENoZWNrcyBmb3IgZXhlY3V0ZW1hbnk6CiAgICAjIFNlcXVlbmNlcyBhcmUgcmVxdWlyZWQgYnkgdGhlIERCLUFQSSwgaXRlcmF0b3JzCiAgICAjIGVuaGFuY2VtZW50cyBpbiBweXNxbGl0ZS4KCiAgICBkZWYgQ2hlY2tFeGVjdXRlTWFueVNlcXVlbmNlKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIHRlc3QoaW5jb21lKSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTAwLCAxMTApXSkKCiAgICBkZWYgQ2hlY2tFeGVjdXRlTWFueUl0ZXJhdG9yKHNlbGYpOgogICAgICAgIGNsYXNzIE15SXRlcjoKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgICAgICAgICAgc2VsZi52YWx1ZSA9IDUKCiAgICAgICAgICAgIGRlZiBuZXh0KHNlbGYpOgogICAgICAgICAgICAgICAgaWYgc2VsZi52YWx1ZSA9PSAxMDoKICAgICAgICAgICAgICAgICAgICByYWlzZSBTdG9wSXRlcmF0aW9uCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYudmFsdWUgKz0gMQogICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2VsZi52YWx1ZSwpCgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIHRlc3QoaW5jb21lKSB2YWx1ZXMgKD8pIiwgTXlJdGVyKCkpCgogICAgZGVmIENoZWNrRXhlY3V0ZU1hbnlHZW5lcmF0b3Ioc2VsZik6CiAgICAgICAgZGVmIG15Z2VuKCk6CiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKDUpOgogICAgICAgICAgICAgICAgeWllbGQgKGksKQoKICAgICAgICBzZWxmLmN1LmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byB0ZXN0KGluY29tZSkgdmFsdWVzICg/KSIsIG15Z2VuKCkpCgogICAgZGVmIENoZWNrRXhlY3V0ZU1hbnlXcm9uZ1NxbEFyZyhzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZW1hbnkoNDIsIFsoMywpXSkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYSBWYWx1ZUVycm9yIikKICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInJhaXNlZCB3cm9uZyBleGNlcHRpb24uIikKCiAgICBkZWYgQ2hlY2tFeGVjdXRlTWFueVNlbGVjdChzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3UuZXhlY3V0ZW1hbnkoInNlbGVjdCA/IiwgWygzLCldKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInJhaXNlZCB3cm9uZyBleGNlcHRpb24uIikKCiAgICBkZWYgQ2hlY2tFeGVjdXRlTWFueU5vdEl0ZXJhYmxlKHNlbGYpOgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdChpbmNvbWUpIHZhbHVlcyAoPykiLCA0MikKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYSBUeXBlRXJyb3IiKQogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24sIGU6CiAgICAgICAgICAgIHByaW50ICJyYWlzZWQiLCBlLl9fY2xhc3NfXwogICAgICAgICAgICBzZWxmLmZhaWwoInJhaXNlZCB3cm9uZyBleGNlcHRpb24uIikKCiAgICBkZWYgQ2hlY2tGZXRjaEl0ZXIoc2VsZik6CiAgICAgICAgIyBPcHRpb25hbCBEQi1BUEkgZXh0ZW5zaW9uLgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiZGVsZXRlIGZyb20gdGVzdCIpCiAgICAgICAgc2VsZi5jdS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGlkKSB2YWx1ZXMgKD8pIiwgKDUsKSkKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaWQpIHZhbHVlcyAoPykiLCAoNiwpKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IGlkIGZyb20gdGVzdCBvcmRlciBieSBpZCIpCiAgICAgICAgbHN0ID0gW10KICAgICAgICBmb3Igcm93IGluIHNlbGYuY3U6CiAgICAgICAgICAgIGxzdC5hcHBlbmQocm93WzBdKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobHN0WzBdLCA1KQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobHN0WzFdLCA2KQoKICAgIGRlZiBDaGVja0ZldGNob25lKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IikKICAgICAgICByb3cgPSBzZWxmLmN1LmZldGNob25lKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgImZvbyIpCiAgICAgICAgcm93ID0gc2VsZi5jdS5mZXRjaG9uZSgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3csIE5vbmUpCgogICAgZGVmIENoZWNrRmV0Y2hvbmVOb1N0YXRlbWVudChzZWxmKToKICAgICAgICBjdXIgPSBzZWxmLmN4LmN1cnNvcigpCiAgICAgICAgcm93ID0gY3VyLmZldGNob25lKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvdywgTm9uZSkKCiAgICBkZWYgQ2hlY2tBcnJheVNpemUoc2VsZik6CiAgICAgICAgIyBtdXN0IGRlZmF1bHQgb3QgMQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jdS5hcnJheXNpemUsIDEpCgogICAgICAgICMgbm93IHNldCB0byAyCiAgICAgICAgc2VsZi5jdS5hcnJheXNpemUgPSAyCgogICAgICAgICMgbm93IG1ha2UgdGhlIHF1ZXJ5IHJldHVybiAzIHJvd3MKICAgICAgICBzZWxmLmN1LmV4ZWN1dGUoImRlbGV0ZSBmcm9tIHRlc3QiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdBJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdCJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdDJykiKQogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1LmZldGNobWFueSgpCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDIpCgogICAgZGVmIENoZWNrRmV0Y2htYW55KHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1LmZldGNobWFueSgxMDApCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVzKSwgMSkKICAgICAgICByZXMgPSBzZWxmLmN1LmZldGNobWFueSgxMDApCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXMsIFtdKQoKICAgIGRlZiBDaGVja0ZldGNobWFueUt3QXJnKHNlbGYpOgogICAgICAgICIiIkNoZWNrcyBpZiBmZXRjaG1hbnkgd29ya3Mgd2l0aCBrZXl3b3JkIGFyZ3VtZW50cyIiIgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1LmZldGNobWFueShzaXplPTEwMCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihyZXMpLCAxKQoKICAgIGRlZiBDaGVja0ZldGNoYWxsKHNlbGYpOgogICAgICAgIHNlbGYuY3UuZXhlY3V0ZSgic2VsZWN0IG5hbWUgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1LmZldGNoYWxsKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihyZXMpLCAxKQogICAgICAgIHJlcyA9IHNlbGYuY3UuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzLCBbXSkKCiAgICBkZWYgQ2hlY2tTZXRpbnB1dHNpemVzKHNlbGYpOgogICAgICAgIHNlbGYuY3Uuc2V0aW5wdXRzaXplcyhbMywgNCwgNV0pCgogICAgZGVmIENoZWNrU2V0b3V0cHV0c2l6ZShzZWxmKToKICAgICAgICBzZWxmLmN1LnNldG91dHB1dHNpemUoNSwgMCkKCiAgICBkZWYgQ2hlY2tTZXRvdXRwdXRzaXplTm9Db2x1bW4oc2VsZik6CiAgICAgICAgc2VsZi5jdS5zZXRvdXRwdXRzaXplKDQyKQoKICAgIGRlZiBDaGVja0N1cnNvckNvbm5lY3Rpb24oc2VsZik6CiAgICAgICAgIyBPcHRpb25hbCBEQi1BUEkgZXh0ZW5zaW9uLgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jdS5jb25uZWN0aW9uLCBzZWxmLmN4KQoKICAgIGRlZiBDaGVja1dyb25nQ3Vyc29yQ2FsbGFibGUoc2VsZik6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkZWYgZigpOiBwYXNzCiAgICAgICAgICAgIGN1ciA9IHNlbGYuY3guY3Vyc29yKGYpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGEgVHlwZUVycm9yIikKICAgICAgICBleGNlcHQgVHlwZUVycm9yOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFZhbHVlRXJyb3IiKQoKICAgIGRlZiBDaGVja0N1cnNvcldyb25nQ2xhc3Moc2VsZik6CiAgICAgICAgY2xhc3MgRm9vOiBwYXNzCiAgICAgICAgZm9vID0gRm9vKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNxbGl0ZS5DdXJzb3IoZm9vKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFZhbHVlRXJyb3IiKQogICAgICAgIGV4Y2VwdCBUeXBlRXJyb3I6CiAgICAgICAgICAgIHBhc3MKCkB1bml0dGVzdC5za2lwVW5sZXNzKHRocmVhZGluZywgJ1RoaXMgdGVzdCByZXF1aXJlcyB0aHJlYWRpbmcuJykKY2xhc3MgVGhyZWFkVGVzdHModW5pdHRlc3QuVGVzdENhc2UpOgogICAgZGVmIHNldFVwKHNlbGYpOgogICAgICAgIHNlbGYuY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBzZWxmLmN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaWQgaW50ZWdlciBwcmltYXJ5IGtleSwgbmFtZSB0ZXh0LCBiaW4gYmluYXJ5LCByYXRpbyBudW1iZXIsIHRzIHRpbWVzdGFtcCkiKQoKICAgIGRlZiB0ZWFyRG93bihzZWxmKToKICAgICAgICBzZWxmLmN1ci5jbG9zZSgpCiAgICAgICAgc2VsZi5jb24uY2xvc2UoKQoKICAgIGRlZiBDaGVja0NvbkN1cnNvcihzZWxmKToKICAgICAgICBkZWYgcnVuKGNvbiwgZXJyb3JzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJkaWQgbm90IHJhaXNlIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJyYWlzZWQgd3JvbmcgZXhjZXB0aW9uIikKCiAgICAgICAgZXJyb3JzID0gW10KICAgICAgICB0ID0gdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9cnVuLCBrd2FyZ3M9eyJjb24iOiBzZWxmLmNvbiwgImVycm9ycyI6IGVycm9yc30pCiAgICAgICAgdC5zdGFydCgpCiAgICAgICAgdC5qb2luKCkKICAgICAgICBpZiBsZW4oZXJyb3JzKSA+IDA6CiAgICAgICAgICAgIHNlbGYuZmFpbCgiXG4iLmpvaW4oZXJyb3JzKSkKCiAgICBkZWYgQ2hlY2tDb25Db21taXQoc2VsZik6CiAgICAgICAgZGVmIHJ1bihjb24sIGVycm9ycyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgiZGlkIG5vdCByYWlzZSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgicmFpc2VkIHdyb25nIGV4Y2VwdGlvbiIpCgogICAgICAgIGVycm9ycyA9IFtdCiAgICAgICAgdCA9IHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXJ1biwga3dhcmdzPXsiY29uIjogc2VsZi5jb24sICJlcnJvcnMiOiBlcnJvcnN9KQogICAgICAgIHQuc3RhcnQoKQogICAgICAgIHQuam9pbigpCiAgICAgICAgaWYgbGVuKGVycm9ycykgPiAwOgogICAgICAgICAgICBzZWxmLmZhaWwoIlxuIi5qb2luKGVycm9ycykpCgogICAgZGVmIENoZWNrQ29uUm9sbGJhY2soc2VsZik6CiAgICAgICAgZGVmIHJ1bihjb24sIGVycm9ycyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNvbi5yb2xsYmFjaygpCiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJkaWQgbm90IHJhaXNlIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJyYWlzZWQgd3JvbmcgZXhjZXB0aW9uIikKCiAgICAgICAgZXJyb3JzID0gW10KICAgICAgICB0ID0gdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9cnVuLCBrd2FyZ3M9eyJjb24iOiBzZWxmLmNvbiwgImVycm9ycyI6IGVycm9yc30pCiAgICAgICAgdC5zdGFydCgpCiAgICAgICAgdC5qb2luKCkKICAgICAgICBpZiBsZW4oZXJyb3JzKSA+IDA6CiAgICAgICAgICAgIHNlbGYuZmFpbCgiXG4iLmpvaW4oZXJyb3JzKSkKCiAgICBkZWYgQ2hlY2tDb25DbG9zZShzZWxmKToKICAgICAgICBkZWYgcnVuKGNvbiwgZXJyb3JzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgY29uLmNsb3NlKCkKICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoImRpZCBub3QgcmFpc2UgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoInJhaXNlZCB3cm9uZyBleGNlcHRpb24iKQoKICAgICAgICBlcnJvcnMgPSBbXQogICAgICAgIHQgPSB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1ydW4sIGt3YXJncz17ImNvbiI6IHNlbGYuY29uLCAiZXJyb3JzIjogZXJyb3JzfSkKICAgICAgICB0LnN0YXJ0KCkKICAgICAgICB0LmpvaW4oKQogICAgICAgIGlmIGxlbihlcnJvcnMpID4gMDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJcbiIuam9pbihlcnJvcnMpKQoKICAgIGRlZiBDaGVja0N1ckltcGxpY2l0QmVnaW4oc2VsZik6CiAgICAgICAgZGVmIHJ1bihjdXIsIGVycm9ycyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGN1ci5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KG5hbWUpIHZhbHVlcyAoJ2EnKSIpCiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJkaWQgbm90IHJhaXNlIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBlcnJvcnMuYXBwZW5kKCJyYWlzZWQgd3JvbmcgZXhjZXB0aW9uIikKCiAgICAgICAgZXJyb3JzID0gW10KICAgICAgICB0ID0gdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9cnVuLCBrd2FyZ3M9eyJjdXIiOiBzZWxmLmN1ciwgImVycm9ycyI6IGVycm9yc30pCiAgICAgICAgdC5zdGFydCgpCiAgICAgICAgdC5qb2luKCkKICAgICAgICBpZiBsZW4oZXJyb3JzKSA+IDA6CiAgICAgICAgICAgIHNlbGYuZmFpbCgiXG4iLmpvaW4oZXJyb3JzKSkKCiAgICBkZWYgQ2hlY2tDdXJDbG9zZShzZWxmKToKICAgICAgICBkZWYgcnVuKGN1ciwgZXJyb3JzKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgY3VyLmNsb3NlKCkKICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoImRpZCBub3QgcmFpc2UgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIGVycm9ycy5hcHBlbmQoInJhaXNlZCB3cm9uZyBleGNlcHRpb24iKQoKICAgICAgICBlcnJvcnMgPSBbXQogICAgICAgIHQgPSB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1ydW4sIGt3YXJncz17ImN1ciI6IHNlbGYuY3VyLCAiZXJyb3JzIjogZXJyb3JzfSkKICAgICAgICB0LnN0YXJ0KCkKICAgICAgICB0LmpvaW4oKQogICAgICAgIGlmIGxlbihlcnJvcnMpID4gMDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJcbiIuam9pbihlcnJvcnMpKQoKICAgIGRlZiBDaGVja0N1ckV4ZWN1dGUoc2VsZik6CiAgICAgICAgZGVmIHJ1bihjdXIsIGVycm9ycyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgbmFtZSBmcm9tIHRlc3QiKQogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgiZGlkIG5vdCByYWlzZSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgicmFpc2VkIHdyb25nIGV4Y2VwdGlvbiIpCgogICAgICAgIGVycm9ycyA9IFtdCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdhJykiKQogICAgICAgIHQgPSB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1ydW4sIGt3YXJncz17ImN1ciI6IHNlbGYuY3VyLCAiZXJyb3JzIjogZXJyb3JzfSkKICAgICAgICB0LnN0YXJ0KCkKICAgICAgICB0LmpvaW4oKQogICAgICAgIGlmIGxlbihlcnJvcnMpID4gMDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJcbiIuam9pbihlcnJvcnMpKQoKICAgIGRlZiBDaGVja0N1ckl0ZXJOZXh0KHNlbGYpOgogICAgICAgIGRlZiBydW4oY3VyLCBlcnJvcnMpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICByb3cgPSBjdXIuZmV0Y2hvbmUoKQogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgiZGlkIG5vdCByYWlzZSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjZXB0OgogICAgICAgICAgICAgICAgZXJyb3JzLmFwcGVuZCgicmFpc2VkIHdyb25nIGV4Y2VwdGlvbiIpCgogICAgICAgIGVycm9ycyA9IFtdCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChuYW1lKSB2YWx1ZXMgKCdhJykiKQogICAgICAgIHNlbGYuY3VyLmV4ZWN1dGUoInNlbGVjdCBuYW1lIGZyb20gdGVzdCIpCiAgICAgICAgdCA9IHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXJ1biwga3dhcmdzPXsiY3VyIjogc2VsZi5jdXIsICJlcnJvcnMiOiBlcnJvcnN9KQogICAgICAgIHQuc3RhcnQoKQogICAgICAgIHQuam9pbigpCiAgICAgICAgaWYgbGVuKGVycm9ycykgPiAwOgogICAgICAgICAgICBzZWxmLmZhaWwoIlxuIi5qb2luKGVycm9ycykpCgpjbGFzcyBDb25zdHJ1Y3RvclRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBDaGVja0RhdGUoc2VsZik6CiAgICAgICAgZCA9IHNxbGl0ZS5EYXRlKDIwMDQsIDEwLCAyOCkKCiAgICBkZWYgQ2hlY2tUaW1lKHNlbGYpOgogICAgICAgIHQgPSBzcWxpdGUuVGltZSgxMiwgMzksIDM1KQoKICAgIGRlZiBDaGVja1RpbWVzdGFtcChzZWxmKToKICAgICAgICB0cyA9IHNxbGl0ZS5UaW1lc3RhbXAoMjAwNCwgMTAsIDI4LCAxMiwgMzksIDM1KQoKICAgIGRlZiBDaGVja0RhdGVGcm9tVGlja3Moc2VsZik6CiAgICAgICAgZCA9IHNxbGl0ZS5EYXRlRnJvbVRpY2tzKDQyKQoKICAgIGRlZiBDaGVja1RpbWVGcm9tVGlja3Moc2VsZik6CiAgICAgICAgdCA9IHNxbGl0ZS5UaW1lRnJvbVRpY2tzKDQyKQoKICAgIGRlZiBDaGVja1RpbWVzdGFtcEZyb21UaWNrcyhzZWxmKToKICAgICAgICB0cyA9IHNxbGl0ZS5UaW1lc3RhbXBGcm9tVGlja3MoNDIpCgogICAgZGVmIENoZWNrQmluYXJ5KHNlbGYpOgogICAgICAgIGIgPSBzcWxpdGUuQmluYXJ5KGNocigwKSArICInIikKCmNsYXNzIEV4dGVuc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBDaGVja1NjcmlwdFN0cmluZ1NxbChzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlc2NyaXB0KCIiIgogICAgICAgICAgICAtLSBibGEgYmxhCiAgICAgICAgICAgIC8qIGEgc3R1cGlkIGNvbW1lbnQgKi8KICAgICAgICAgICAgY3JlYXRlIHRhYmxlIGEoaSk7CiAgICAgICAgICAgIGluc2VydCBpbnRvIGEoaSkgdmFsdWVzICg1KTsKICAgICAgICAgICAgIiIiKQogICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgaSBmcm9tIGEiKQogICAgICAgIHJlcyA9IGN1ci5mZXRjaG9uZSgpWzBdCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXMsIDUpCgogICAgZGVmIENoZWNrU2NyaXB0U3RyaW5nVW5pY29kZShzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlc2NyaXB0KHUiIiIKICAgICAgICAgICAgY3JlYXRlIHRhYmxlIGEoaSk7CiAgICAgICAgICAgIGluc2VydCBpbnRvIGEoaSkgdmFsdWVzICg1KTsKICAgICAgICAgICAgc2VsZWN0IGkgZnJvbSBhOwogICAgICAgICAgICBkZWxldGUgZnJvbSBhOwogICAgICAgICAgICBpbnNlcnQgaW50byBhKGkpIHZhbHVlcyAoNik7CiAgICAgICAgICAgICIiIikKICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSBhIikKICAgICAgICByZXMgPSBjdXIuZmV0Y2hvbmUoKVswXQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzLCA2KQoKICAgIGRlZiBDaGVja1NjcmlwdFN5bnRheEVycm9yKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgcmFpc2VkID0gRmFsc2UKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ci5leGVjdXRlc2NyaXB0KCJjcmVhdGUgdGFibGUgdGVzdCh4KTsgYXNkZjsgY3JlYXRlIHRhYmxlIHRlc3QyKHgpIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHJhaXNlZCA9IFRydWUKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJhaXNlZCwgVHJ1ZSwgInNob3VsZCBoYXZlIHJhaXNlZCBhbiBleGNlcHRpb24iKQoKICAgIGRlZiBDaGVja1NjcmlwdEVycm9yTm9ybWFsKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgcmFpc2VkID0gRmFsc2UKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ci5leGVjdXRlc2NyaXB0KCJjcmVhdGUgdGFibGUgdGVzdChzYWRmc2FkZmRzYSk7IHNlbGVjdCBmb28gZnJvbSBodXJ6OyIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yOgogICAgICAgICAgICByYWlzZWQgPSBUcnVlCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyYWlzZWQsIFRydWUsICJzaG91bGQgaGF2ZSByYWlzZWQgYW4gZXhjZXB0aW9uIikKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uRXhlY3V0ZShzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHJlc3VsdCA9IGNvbi5leGVjdXRlKCJzZWxlY3QgNSIpLmZldGNob25lKClbMF0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdCwgNSwgIkJhc2ljIHRlc3Qgb2YgQ29ubmVjdGlvbi5leGVjdXRlIikKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uRXhlY3V0ZW1hbnkoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoZm9vKSIpCiAgICAgICAgY29uLmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byB0ZXN0KGZvbykgdmFsdWVzICg/KSIsIFsoMywpLCAoNCwpXSkKICAgICAgICByZXN1bHQgPSBjb24uZXhlY3V0ZSgic2VsZWN0IGZvbyBmcm9tIHRlc3Qgb3JkZXIgYnkgZm9vIikuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0WzBdWzBdLCAzLCAiQmFzaWMgdGVzdCBvZiBDb25uZWN0aW9uLmV4ZWN1dGVtYW55IikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlc3VsdFsxXVswXSwgNCwgIkJhc2ljIHRlc3Qgb2YgQ29ubmVjdGlvbi5leGVjdXRlbWFueSIpCgogICAgZGVmIENoZWNrQ29ubmVjdGlvbkV4ZWN1dGVzY3JpcHQoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZXNjcmlwdCgiY3JlYXRlIHRhYmxlIHRlc3QoZm9vKTsgaW5zZXJ0IGludG8gdGVzdChmb28pIHZhbHVlcyAoNSk7IikKICAgICAgICByZXN1bHQgPSBjb24uZXhlY3V0ZSgic2VsZWN0IGZvbyBmcm9tIHRlc3QiKS5mZXRjaG9uZSgpWzBdCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyZXN1bHQsIDUsICJCYXNpYyB0ZXN0IG9mIENvbm5lY3Rpb24uZXhlY3V0ZXNjcmlwdCIpCgpjbGFzcyBDbG9zZWRDb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiB0ZWFyRG93bihzZWxmKToKICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrQ2xvc2VkQ29uQ3Vyc29yKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNsb3NlKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJTaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKCiAgICBkZWYgQ2hlY2tDbG9zZWRDb25Db21taXQoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uY2xvc2UoKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQoKICAgIGRlZiBDaGVja0Nsb3NlZENvblJvbGxiYWNrKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNsb3NlKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5yb2xsYmFjaygpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQoKICAgIGRlZiBDaGVja0Nsb3NlZEN1ckV4ZWN1dGUoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjb24uY2xvc2UoKQogICAgICAgIHRyeToKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCA0IikKICAgICAgICAgICAgc2VsZi5mYWlsKCJTaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCgogICAgZGVmIENoZWNrQ2xvc2VkQ3JlYXRlRnVuY3Rpb24oc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uY2xvc2UoKQogICAgICAgIGRlZiBmKHgpOiByZXR1cm4gMTcKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jcmVhdGVfZnVuY3Rpb24oImZvbyIsIDEsIGYpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQoKICAgIGRlZiBDaGVja0Nsb3NlZENyZWF0ZUFnZ3JlZ2F0ZShzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5jbG9zZSgpCiAgICAgICAgY2xhc3MgQWdnOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIGRlZiBzdGVwKHNlbGYsIHgpOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICBkZWYgZmluYWxpemUoc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gMTcKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jcmVhdGVfYWdncmVnYXRlKCJmb28iLCAxLCBBZ2cpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQoKICAgIGRlZiBDaGVja0Nsb3NlZFNldEF1dGhvcml6ZXIoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uY2xvc2UoKQogICAgICAgIGRlZiBhdXRob3JpemVyKCphcmdzKToKICAgICAgICAgICAgcmV0dXJuIHNxbGl0ZS5ERU5ZCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uc2V0X2F1dGhvcml6ZXIoYXV0aG9yaXplcikKICAgICAgICAgICAgc2VsZi5mYWlsKCJTaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCgogICAgZGVmIENoZWNrQ2xvc2VkU2V0UHJvZ3Jlc3NDYWxsYmFjayhzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5jbG9zZSgpCiAgICAgICAgZGVmIHByb2dyZXNzKCk6IHBhc3MKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMTAwKQogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJTaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKCiAgICBkZWYgQ2hlY2tDbG9zZWRDYWxsKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNsb3NlKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbigpCiAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQoKY2xhc3MgQ2xvc2VkQ3VyVGVzdHModW5pdHRlc3QuVGVzdENhc2UpOgogICAgZGVmIHNldFVwKHNlbGYpOgogICAgICAgIHBhc3MKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBDaGVja0Nsb3NlZChzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5jbG9zZSgpCgogICAgICAgIGZvciBtZXRob2RfbmFtZSBpbiAoImV4ZWN1dGUiLCAiZXhlY3V0ZW1hbnkiLCAiZXhlY3V0ZXNjcmlwdCIsICJmZXRjaGFsbCIsICJmZXRjaG1hbnkiLCAiZmV0Y2hvbmUiKToKICAgICAgICAgICAgaWYgbWV0aG9kX25hbWUgaW4gKCJleGVjdXRlIiwgImV4ZWN1dGVzY3JpcHQiKToKICAgICAgICAgICAgICAgIHBhcmFtcyA9ICgic2VsZWN0IDQgdW5pb24gc2VsZWN0IDUiLCkKICAgICAgICAgICAgZWxpZiBtZXRob2RfbmFtZSA9PSAiZXhlY3V0ZW1hbnkiOgogICAgICAgICAgICAgICAgcGFyYW1zID0gKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKD8pIiwgWygzLCksICg0LCldKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcGFyYW1zID0gW10KCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG1ldGhvZCA9IGdldGF0dHIoY3VyLCBtZXRob2RfbmFtZSkKCiAgICAgICAgICAgICAgICBtZXRob2QoKnBhcmFtcykKICAgICAgICAgICAgICAgIHNlbGYuZmFpbCgiU2hvdWxkIGhhdmUgcmFpc2VkIGEgUHJvZ3JhbW1pbmdFcnJvcjogbWV0aG9kICIgKyBtZXRob2RfbmFtZSkKICAgICAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBzZWxmLmZhaWwoIlNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3I6ICIgKyBtZXRob2RfbmFtZSkKCmRlZiBzdWl0ZSgpOgogICAgbW9kdWxlX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKE1vZHVsZVRlc3RzLCAiQ2hlY2siKQogICAgY29ubmVjdGlvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShDb25uZWN0aW9uVGVzdHMsICJDaGVjayIpCiAgICBjdXJzb3Jfc3VpdGUgPSB1bml0dGVzdC5tYWtlU3VpdGUoQ3Vyc29yVGVzdHMsICJDaGVjayIpCiAgICB0aHJlYWRfc3VpdGUgPSB1bml0dGVzdC5tYWtlU3VpdGUoVGhyZWFkVGVzdHMsICJDaGVjayIpCiAgICBjb25zdHJ1Y3Rvcl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShDb25zdHJ1Y3RvclRlc3RzLCAiQ2hlY2siKQogICAgZXh0X3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKEV4dGVuc2lvblRlc3RzLCAiQ2hlY2siKQogICAgY2xvc2VkX2Nvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShDbG9zZWRDb25UZXN0cywgIkNoZWNrIikKICAgIGNsb3NlZF9jdXJfc3VpdGUgPSB1bml0dGVzdC5tYWtlU3VpdGUoQ2xvc2VkQ3VyVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChtb2R1bGVfc3VpdGUsIGNvbm5lY3Rpb25fc3VpdGUsIGN1cnNvcl9zdWl0ZSwgdGhyZWFkX3N1aXRlLCBjb25zdHJ1Y3Rvcl9zdWl0ZSwgZXh0X3N1aXRlLCBjbG9zZWRfY29uX3N1aXRlLCBjbG9zZWRfY3VyX3N1aXRlKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==