Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvaG9va3MucHk6IHRlc3RzIGZvciB2YXJpb3VzIFNRTGl0ZS1zcGVjaWZpYyBob29rcwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMDcgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgb3MsIHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKY2xhc3MgQ29sbGF0aW9uVGVzdHModW5pdHRlc3QuVGVzdENhc2UpOgogICAgZGVmIHNldFVwKHNlbGYpOgogICAgICAgIHBhc3MKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBDaGVja0NyZWF0ZUNvbGxhdGlvbk5vdENhbGxhYmxlKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigiWCIsIDQyKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFR5cGVFcnJvciIpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvciwgZToKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChlLmFyZ3NbMF0sICJwYXJhbWV0ZXIgbXVzdCBiZSBjYWxsYWJsZSIpCgogICAgZGVmIENoZWNrQ3JlYXRlQ29sbGF0aW9uTm90QXNjaWkoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJjb2xs5CIsIGNtcCkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3IsIGU6CiAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb25Jc1VzZWQoc2VsZik6CiAgICAgICAgaWYgc3FsaXRlLnZlcnNpb25faW5mbyA8ICgzLCAyLCAxKTogICMgb2xkIFNRTGl0ZSB2ZXJzaW9ucyBjcmFzaCBvbiB0aGlzIHRlc3QKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZGVmIG15Y29sbCh4LCB5KToKICAgICAgICAgICAgIyByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgIHJldHVybiAtY21wKHgsIHkpCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIG15Y29sbCkKICAgICAgICBzcWwgPSAiIiIKICAgICAgICAgICAgc2VsZWN0IHggZnJvbSAoCiAgICAgICAgICAgIHNlbGVjdCAnYScgYXMgeAogICAgICAgICAgICB1bmlvbgogICAgICAgICAgICBzZWxlY3QgJ2InIGFzIHgKICAgICAgICAgICAgdW5pb24KICAgICAgICAgICAgc2VsZWN0ICdjJyBhcyB4CiAgICAgICAgICAgICkgb3JkZXIgYnkgeCBjb2xsYXRlIG15Y29sbAogICAgICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBjb24uZXhlY3V0ZShzcWwpLmZldGNoYWxsKCkKICAgICAgICBpZiByZXN1bHRbMF1bMF0gIT0gImMiIG9yIHJlc3VsdFsxXVswXSAhPSAiYiIgb3IgcmVzdWx0WzJdWzBdICE9ICJhIjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJ0aGUgZXhwZWN0ZWQgb3JkZXIgd2FzIG5vdCByZXR1cm5lZCIpCgogICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJteWNvbGwiLCBOb25lKQogICAgICAgIHRyeToKICAgICAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoc3FsKS5mZXRjaGFsbCgpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGFuIE9wZXJhdGlvbmFsRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvciwgZToKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChlLmFyZ3NbMF0ubG93ZXIoKSwgIm5vIHN1Y2ggY29sbGF0aW9uIHNlcXVlbmNlOiBteWNvbGwiKQoKICAgIGRlZiBDaGVja0NvbGxhdGlvblJldHVybnNMYXJnZUludGVnZXIoc2VsZik6CiAgICAgICAgZGVmIG15Y29sbCh4LCB5KToKICAgICAgICAgICAgIyByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgIHJldHVybiAtKCh4ID4geSkgLSAoeCA8IHkpKSAqIDIqKjMyCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgbXljb2xsKQogICAgICAgIHNxbCA9ICIiIgogICAgICAgICAgICBzZWxlY3QgeCBmcm9tICgKICAgICAgICAgICAgc2VsZWN0ICdhJyBhcyB4CiAgICAgICAgICAgIHVuaW9uCiAgICAgICAgICAgIHNlbGVjdCAnYicgYXMgeAogICAgICAgICAgICB1bmlvbgogICAgICAgICAgICBzZWxlY3QgJ2MnIGFzIHgKICAgICAgICAgICAgKSBvcmRlciBieSB4IGNvbGxhdGUgbXljb2xsCiAgICAgICAgICAgICIiIgogICAgICAgIHJlc3VsdCA9IGNvbi5leGVjdXRlKHNxbCkuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LCBbKCdjJywpLCAoJ2InLCksICgnYScsKV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBtc2c9InRoZSBleHBlY3RlZCBvcmRlciB3YXMgbm90IHJldHVybmVkIikKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb25SZWdpc3RlclR3aWNlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIHR3byBkaWZmZXJlbnQgY29sbGF0aW9uIGZ1bmN0aW9ucyB1bmRlciB0aGUgc2FtZSBuYW1lLgogICAgICAgIFZlcmlmeSB0aGF0IHRoZSBsYXN0IG9uZSBpcyBhY3R1YWxseSB1c2VkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgbGFtYmRhIHgsIHk6IC1jbXAoeCwgeSkpCiAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIHNlbGVjdCB4IGZyb20gKHNlbGVjdCAnYScgYXMgeCB1bmlvbiBzZWxlY3QgJ2InIGFzIHgpIG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwKICAgICAgICAgICAgIiIiKS5mZXRjaGFsbCgpCiAgICAgICAgaWYgcmVzdWx0WzBdWzBdICE9ICdiJyBvciByZXN1bHRbMV1bMF0gIT0gJ2EnOgogICAgICAgICAgICBzZWxmLmZhaWwoIndyb25nIGNvbGxhdGlvbiBmdW5jdGlvbiBpcyB1c2VkIikKCiAgICBkZWYgQ2hlY2tEZXJlZ2lzdGVyQ29sbGF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIGEgY29sbGF0aW9uLCB0aGVuIGRlcmVnaXN0ZXIgaXQuIE1ha2Ugc3VyZSBhbiBlcnJvciBpcyByYWlzZWQgaWYgd2UgdHJ5CiAgICAgICAgdG8gdXNlIGl0LgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJzZWxlY3QgJ2EnIGFzIHggdW5pb24gc2VsZWN0ICdiJyBhcyB4IG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IsIGU6CiAgICAgICAgICAgIGlmIG5vdCBlLmFyZ3NbMF0uc3RhcnRzd2l0aCgibm8gc3VjaCBjb2xsYXRpb24gc2VxdWVuY2UiKToKICAgICAgICAgICAgICAgIHNlbGYuZmFpbCgid3JvbmcgT3BlcmF0aW9uYWxFcnJvciByYWlzZWQiKQoKY2xhc3MgUHJvZ3Jlc3NUZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgQ2hlY2tQcm9ncmVzc0hhbmRsZXJVc2VkKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRlc3QgdGhhdCB0aGUgcHJvZ3Jlc3MgaGFuZGxlciBpcyBpbnZva2VkIG9uY2UgaXQgaXMgc2V0LgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGRlZiBwcm9ncmVzcygpOgogICAgICAgICAgICBwcm9ncmVzc19jYWxscy5hcHBlbmQoTm9uZSkKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY29uLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIGNyZWF0ZSB0YWJsZSBmb28oYSwgYikKICAgICAgICAgICAgIiIiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm9ncmVzc19jYWxscykKCgogICAgZGVmIENoZWNrT3Bjb2RlQ291bnQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGVzdCB0aGF0IHRoZSBvcGNvZGUgYXJndW1lbnQgaXMgcmVzcGVjdGVkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGRlZiBwcm9ncmVzcygpOgogICAgICAgICAgICBwcm9ncmVzc19jYWxscy5hcHBlbmQoTm9uZSkKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY3VycyA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1cnMuZXhlY3V0ZSgiIiIKICAgICAgICAgICAgY3JlYXRlIHRhYmxlIGZvbyAoYSwgYikKICAgICAgICAgICAgIiIiKQogICAgICAgIGZpcnN0X2NvdW50ID0gbGVuKHByb2dyZXNzX2NhbGxzKQogICAgICAgIHByb2dyZXNzX2NhbGxzID0gW10KICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDIpCiAgICAgICAgY3Vycy5leGVjdXRlKCIiIgogICAgICAgICAgICBjcmVhdGUgdGFibGUgYmFyIChhLCBiKQogICAgICAgICAgICAiIiIpCiAgICAgICAgc2Vjb25kX2NvdW50ID0gbGVuKHByb2dyZXNzX2NhbGxzKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShmaXJzdF9jb3VudCA+IHNlY29uZF9jb3VudCkKCiAgICBkZWYgQ2hlY2tDYW5jZWxPcGVyYXRpb24oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGVzdCB0aGF0IHJldHVybmluZyBhIG5vbi16ZXJvIHZhbHVlIHN0b3BzIHRoZSBvcGVyYXRpb24gaW4gcHJvZ3Jlc3MuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBwcm9ncmVzc19jYWxscyA9IFtdCiAgICAgICAgZGVmIHByb2dyZXNzKCk6CiAgICAgICAgICAgIHByb2dyZXNzX2NhbGxzLmFwcGVuZChOb25lKQogICAgICAgICAgICByZXR1cm4gMQogICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMSkKICAgICAgICBjdXJzID0gY29uLmN1cnNvcigpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoCiAgICAgICAgICAgIHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yLAogICAgICAgICAgICBjdXJzLmV4ZWN1dGUsCiAgICAgICAgICAgICJjcmVhdGUgdGFibGUgYmFyIChhLCBiKSIpCgogICAgZGVmIENoZWNrQ2xlYXJIYW5kbGVyKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRlc3QgdGhhdCBzZXR0aW5nIHRoZSBwcm9ncmVzcyBoYW5kbGVyIHRvIE5vbmUgY2xlYXJzIHRoZSBwcmV2aW91c2x5IHNldCBoYW5kbGVyLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgYWN0aW9uID0gW10KICAgICAgICBkZWYgcHJvZ3Jlc3MoKToKICAgICAgICAgICAgYWN0aW9uLmFwcGVuZCgxKQogICAgICAgICAgICByZXR1cm4gMAogICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMSkKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIoTm9uZSwgMSkKICAgICAgICBjb24uZXhlY3V0ZSgic2VsZWN0IDEgdW5pb24gc2VsZWN0IDIgdW5pb24gc2VsZWN0IDMiKS5mZXRjaGFsbCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oYWN0aW9uKSwgMCwgInByb2dyZXNzIGhhbmRsZXIgd2FzIG5vdCBjbGVhcmVkIikKCmRlZiBzdWl0ZSgpOgogICAgY29sbGF0aW9uX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKENvbGxhdGlvblRlc3RzLCAiQ2hlY2siKQogICAgcHJvZ3Jlc3Nfc3VpdGUgPSB1bml0dGVzdC5tYWtlU3VpdGUoUHJvZ3Jlc3NUZXN0cywgIkNoZWNrIikKICAgIHJldHVybiB1bml0dGVzdC5UZXN0U3VpdGUoKGNvbGxhdGlvbl9zdWl0ZSwgcHJvZ3Jlc3Nfc3VpdGUpKQoKZGVmIHRlc3QoKToKICAgIHJ1bm5lciA9IHVuaXR0ZXN0LlRleHRUZXN0UnVubmVyKCkKICAgIHJ1bm5lci5ydW4oc3VpdGUoKSkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0KCkK