Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvaG9va3MucHk6IHRlc3RzIGZvciB2YXJpb3VzIFNRTGl0ZS1zcGVjaWZpYyBob29rcwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMDcgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgb3MsIHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKY2xhc3MgQ29sbGF0aW9uVGVzdHModW5pdHRlc3QuVGVzdENhc2UpOgogICAgZGVmIHNldFVwKHNlbGYpOgogICAgICAgIHBhc3MKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiBDaGVja0NyZWF0ZUNvbGxhdGlvbk5vdENhbGxhYmxlKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigiWCIsIDQyKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFR5cGVFcnJvciIpCiAgICAgICAgZXhjZXB0IFR5cGVFcnJvciwgZToKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChlLmFyZ3NbMF0sICJwYXJhbWV0ZXIgbXVzdCBiZSBjYWxsYWJsZSIpCgogICAgZGVmIENoZWNrQ3JlYXRlQ29sbGF0aW9uTm90QXNjaWkoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJjb2xs5CIsIGNtcCkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYSBQcm9ncmFtbWluZ0Vycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLlByb2dyYW1taW5nRXJyb3IsIGU6CiAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb25Jc1VzZWQoc2VsZik6CiAgICAgICAgaWYgc3FsaXRlLnZlcnNpb25faW5mbyA8ICgzLCAyLCAxKTogICMgb2xkIFNRTGl0ZSB2ZXJzaW9ucyBjcmFzaCBvbiB0aGlzIHRlc3QKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgZGVmIG15Y29sbCh4LCB5KToKICAgICAgICAgICAgIyByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgIHJldHVybiAtY21wKHgsIHkpCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIG15Y29sbCkKICAgICAgICBzcWwgPSAiIiIKICAgICAgICAgICAgc2VsZWN0IHggZnJvbSAoCiAgICAgICAgICAgIHNlbGVjdCAnYScgYXMgeAogICAgICAgICAgICB1bmlvbgogICAgICAgICAgICBzZWxlY3QgJ2InIGFzIHgKICAgICAgICAgICAgdW5pb24KICAgICAgICAgICAgc2VsZWN0ICdjJyBhcyB4CiAgICAgICAgICAgICkgb3JkZXIgYnkgeCBjb2xsYXRlIG15Y29sbAogICAgICAgICAgICAiIiIKICAgICAgICByZXN1bHQgPSBjb24uZXhlY3V0ZShzcWwpLmZldGNoYWxsKCkKICAgICAgICBpZiByZXN1bHRbMF1bMF0gIT0gImMiIG9yIHJlc3VsdFsxXVswXSAhPSAiYiIgb3IgcmVzdWx0WzJdWzBdICE9ICJhIjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJ0aGUgZXhwZWN0ZWQgb3JkZXIgd2FzIG5vdCByZXR1cm5lZCIpCgogICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJteWNvbGwiLCBOb25lKQogICAgICAgIHRyeToKICAgICAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoc3FsKS5mZXRjaGFsbCgpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGFuIE9wZXJhdGlvbmFsRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvciwgZToKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChlLmFyZ3NbMF0ubG93ZXIoKSwgIm5vIHN1Y2ggY29sbGF0aW9uIHNlcXVlbmNlOiBteWNvbGwiKQoKICAgIGRlZiBDaGVja0NvbGxhdGlvblJldHVybnNMYXJnZUludGVnZXIoc2VsZik6CiAgICAgICAgZGVmIG15Y29sbCh4LCB5KToKICAgICAgICAgICAgIyByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgIHJldHVybiAtKCh4ID4geSkgLSAoeCA8IHkpKSAqIDIqKjMyCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgbXljb2xsKQogICAgICAgIHNxbCA9ICIiIgogICAgICAgICAgICBzZWxlY3QgeCBmcm9tICgKICAgICAgICAgICAgc2VsZWN0ICdhJyBhcyB4CiAgICAgICAgICAgIHVuaW9uCiAgICAgICAgICAgIHNlbGVjdCAnYicgYXMgeAogICAgICAgICAgICB1bmlvbgogICAgICAgICAgICBzZWxlY3QgJ2MnIGFzIHgKICAgICAgICAgICAgKSBvcmRlciBieSB4IGNvbGxhdGUgbXljb2xsCiAgICAgICAgICAgICIiIgogICAgICAgIHJlc3VsdCA9IGNvbi5leGVjdXRlKHNxbCkuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzdWx0LCBbKCdjJywpLCAoJ2InLCksICgnYScsKV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBtc2c9InRoZSBleHBlY3RlZCBvcmRlciB3YXMgbm90IHJldHVybmVkIikKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb25SZWdpc3RlclR3aWNlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIHR3byBkaWZmZXJlbnQgY29sbGF0aW9uIGZ1bmN0aW9ucyB1bmRlciB0aGUgc2FtZSBuYW1lLgogICAgICAgIFZlcmlmeSB0aGF0IHRoZSBsYXN0IG9uZSBpcyBhY3R1YWxseSB1c2VkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgbGFtYmRhIHgsIHk6IC1jbXAoeCwgeSkpCiAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIHNlbGVjdCB4IGZyb20gKHNlbGVjdCAnYScgYXMgeCB1bmlvbiBzZWxlY3QgJ2InIGFzIHgpIG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwKICAgICAgICAgICAgIiIiKS5mZXRjaGFsbCgpCiAgICAgICAgaWYgcmVzdWx0WzBdWzBdICE9ICdiJyBvciByZXN1bHRbMV1bMF0gIT0gJ2EnOgogICAgICAgICAgICBzZWxmLmZhaWwoIndyb25nIGNvbGxhdGlvbiBmdW5jdGlvbiBpcyB1c2VkIikKCiAgICBkZWYgQ2hlY2tEZXJlZ2lzdGVyQ29sbGF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIGEgY29sbGF0aW9uLCB0aGVuIGRlcmVnaXN0ZXIgaXQuIE1ha2Ugc3VyZSBhbiBlcnJvciBpcyByYWlzZWQgaWYgd2UgdHJ5CiAgICAgICAgdG8gdXNlIGl0LgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJzZWxlY3QgJ2EnIGFzIHggdW5pb24gc2VsZWN0ICdiJyBhcyB4IG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IsIGU6CiAgICAgICAgICAgIGlmIG5vdCBlLmFyZ3NbMF0uc3RhcnRzd2l0aCgibm8gc3VjaCBjb2xsYXRpb24gc2VxdWVuY2UiKToKICAgICAgICAgICAgICAgIHNlbGYuZmFpbCgid3JvbmcgT3BlcmF0aW9uYWxFcnJvciByYWlzZWQiKQoKY2xhc3MgUHJvZ3Jlc3NUZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgQ2hlY2tQcm9ncmVzc0hhbmRsZXJVc2VkKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRlc3QgdGhhdCB0aGUgcHJvZ3Jlc3MgaGFuZGxlciBpcyBpbnZva2VkIG9uY2UgaXQgaXMgc2V0LgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGRlZiBwcm9ncmVzcygpOgogICAgICAgICAgICBwcm9ncmVzc19jYWxscy5hcHBlbmQoTm9uZSkKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY29uLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIGNyZWF0ZSB0YWJsZSBmb28oYSwgYikKICAgICAgICAgICAgIiIiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShwcm9ncmVzc19jYWxscykKCgogICAgZGVmIENoZWNrT3Bjb2RlQ291bnQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGVzdCB0aGF0IHRoZSBvcGNvZGUgYXJndW1lbnQgaXMgcmVzcGVjdGVkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGRlZiBwcm9ncmVzcygpOgogICAgICAgICAgICBwcm9ncmVzc19jYWxscy5hcHBlbmQoTm9uZSkKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY3VycyA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1cnMuZXhlY3V0ZSgiIiIKICAgICAgICAgICAgY3JlYXRlIHRhYmxlIGZvbyAoYSwgYikKICAgICAgICAgICAgIiIiKQogICAgICAgIGZpcnN0X2NvdW50ID0gbGVuKHByb2dyZXNzX2NhbGxzKQogICAgICAgIHByb2dyZXNzX2NhbGxzID0gW10KICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDIpCiAgICAgICAgY3Vycy5leGVjdXRlKCIiIgogICAgICAgICAgICBjcmVhdGUgdGFibGUgYmFyIChhLCBiKQogICAgICAgICAgICAiIiIpCiAgICAgICAgc2Vjb25kX2NvdW50ID0gbGVuKHByb2dyZXNzX2NhbGxzKQogICAgICAgIHNlbGYuYXNzZXJ0R3JlYXRlckVxdWFsKGZpcnN0X2NvdW50LCBzZWNvbmRfY291bnQpCgogICAgZGVmIENoZWNrQ2FuY2VsT3BlcmF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRlc3QgdGhhdCByZXR1cm5pbmcgYSBub24temVybyB2YWx1ZSBzdG9wcyB0aGUgb3BlcmF0aW9uIGluIHByb2dyZXNzLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGRlZiBwcm9ncmVzcygpOgogICAgICAgICAgICBwcm9ncmVzc19jYWxscy5hcHBlbmQoTm9uZSkKICAgICAgICAgICAgcmV0dXJuIDEKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY3VycyA9IGNvbi5jdXJzb3IoKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKAogICAgICAgICAgICBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvciwKICAgICAgICAgICAgY3Vycy5leGVjdXRlLAogICAgICAgICAgICAiY3JlYXRlIHRhYmxlIGJhciAoYSwgYikiKQoKICAgIGRlZiBDaGVja0NsZWFySGFuZGxlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUZXN0IHRoYXQgc2V0dGluZyB0aGUgcHJvZ3Jlc3MgaGFuZGxlciB0byBOb25lIGNsZWFycyB0aGUgcHJldmlvdXNseSBzZXQgaGFuZGxlci4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGFjdGlvbiA9IFtdCiAgICAgICAgZGVmIHByb2dyZXNzKCk6CiAgICAgICAgICAgIGFjdGlvbi5hcHBlbmQoMSkKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY29uLnNldF9wcm9ncmVzc19oYW5kbGVyKE5vbmUsIDEpCiAgICAgICAgY29uLmV4ZWN1dGUoInNlbGVjdCAxIHVuaW9uIHNlbGVjdCAyIHVuaW9uIHNlbGVjdCAzIikuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKGFjdGlvbiksIDAsICJwcm9ncmVzcyBoYW5kbGVyIHdhcyBub3QgY2xlYXJlZCIpCgpkZWYgc3VpdGUoKToKICAgIGNvbGxhdGlvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShDb2xsYXRpb25UZXN0cywgIkNoZWNrIikKICAgIHByb2dyZXNzX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFByb2dyZXNzVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChjb2xsYXRpb25fc3VpdGUsIHByb2dyZXNzX3N1aXRlKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==