Iy0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQppbXBvcnQgd2Vha3JlZgppbXBvcnQgZnVuY3Rvb2xzCmZyb20gdGVzdCBpbXBvcnQgc3VwcG9ydAoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHJhbmdlKDUpXQogICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoeCkiKQogICAgICAgIGZvciBpIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgY3Vyc29yc1swXS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTApXSkKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICAgICAgICAgIGN1cnNvcnNbaV0uZXhlY3V0ZSgiICIgKiBpICsgInNlbGVjdCB4IGZyb20gdGVzdCIpCgogICAgICAgIGNvbi5yb2xsYmFjaygpCgogICAgZGVmIENoZWNrQ29sdW1uTmFtZVdpdGhTcGFjZXMoc2VsZik6CiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXIgW2RhdGV0aW1lXSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciIpCgogICAgICAgIGN1ci5leGVjdXRlKCdzZWxlY3QgMSBhcyAiZm9vIGJheiInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJheiIpCgogICAgZGVmIENoZWNrU3RhdGVtZW50RmluYWxpemF0aW9uT25DbG9zZURiKHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgdmVyc2lvbnMgPD0gMi4zLjMgb25seSBmaW5hbGl6ZWQgc3RhdGVtZW50cyBpbiB0aGUgc3RhdGVtZW50CiAgICAgICAgIyBjYWNoZSB3aGVuIGNsb3NpbmcgdGhlIGRhdGFiYXNlLiBzdGF0ZW1lbnRzIHRoYXQgd2VyZSBzdGlsbAogICAgICAgICMgcmVmZXJlbmNlZCBpbiBjdXJzb3JzIHdlcmVuJ3QgY2xvc2VkIGFuZCBjb3VsZCBwcm92b2tlICIKICAgICAgICAjICJPcGVyYXRpb25hbEVycm9yOiBVbmFibGUgdG8gY2xvc2UgZHVlIHRvIHVuZmluYWxpc2VkIHN0YXRlbWVudHMiLgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3Vyc29ycyA9IFtdCiAgICAgICAgIyBkZWZhdWx0IHN0YXRlbWVudCBjYWNoZSBzaXplIGlzIDEwMAogICAgICAgIGZvciBpIGluIHJhbmdlKDEwNSk6CiAgICAgICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgICAgICBjdXJzb3JzLmFwcGVuZChjdXIpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgMSB4IHVuaW9uIHNlbGVjdCAiICsgc3RyKGkpKQogICAgICAgIGNvbi5jbG9zZSgpCgogICAgQHVuaXR0ZXN0LnNraXBJZihzcWxpdGUuc3FsaXRlX3ZlcnNpb25faW5mbyA8ICgzLCAyLCAyKSwgJ25lZWRzIHNxbGl0ZSAzLjIuMiBvciBuZXdlcicpCiAgICBkZWYgQ2hlY2tPbkNvbmZsaWN0Um9sbGJhY2soc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyh4LCB1bmlxdWUoeCkgb24gY29uZmxpY3Qgcm9sbGJhY2spIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMSkiKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDEpIikKICAgICAgICBleGNlcHQgc3FsaXRlLkRhdGFiYXNlRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMikiKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoInB5c3FsaXRlIGtuZXcgbm90aGluZyBhYm91dCB0aGUgaW1wbGljaXQgUk9MTEJBQ0siKQoKICAgIGRlZiBDaGVja1dvcmthcm91bmRGb3JCdWdneVNxbGl0ZVRyYW5zZmVyQmluZGluZ3Moc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgd291bGQgY3Jhc2ggd2l0aCBvbGRlciBTUUxpdGUgdmVyc2lvbnMgdW5sZXNzCiAgICAgICAgYSB3b3JrYXJvdW5kIGlzIGltcGxlbWVudGVkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiZHJvcCB0YWJsZSBmb28iKQogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCgogICAgZGVmIENoZWNrRW1wdHlTdGF0ZW1lbnQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgdXNlZCB0byBzZWdmYXVsdCB3aXRoIFNRTGl0ZSB2ZXJzaW9ucyAzLjUueC4gVGhlc2UgcmV0dXJuIE5VTEwKICAgICAgICBmb3IgIm5vLW9wZXJhdGlvbiIgc3RhdGVtZW50cwogICAgICAgICIiIgogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoIiIpCgogICAgZGVmIENoZWNrVHlwZU1hcFVzYWdlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHVudGlsIDIuNC4xIGRpZCBub3QgcmVidWlsZCB0aGUgcm93X2Nhc3RfbWFwIHdoZW4gcmVjb21waWxpbmcKICAgICAgICBhIHN0YXRlbWVudC4gVGhpcyB0ZXN0IGV4aGliaXRzIHRoZSBwcm9ibGVtLgogICAgICAgICIiIgogICAgICAgIFNFTEVDVCA9ICJzZWxlY3QgKiBmcm9tIGZvbyIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfREVDTFRZUEVTKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhciB0aW1lc3RhbXApIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg/KSIsIChkYXRldGltZS5kYXRldGltZS5ub3coKSwpKQogICAgICAgIGNvbi5leGVjdXRlKFNFTEVDVCkKICAgICAgICBjb24uZXhlY3V0ZSgiZHJvcCB0YWJsZSBmb28iKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhciBpbnRlZ2VyKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoNSkiKQogICAgICAgIGNvbi5leGVjdXRlKFNFTEVDVCkKCiAgICBkZWYgQ2hlY2tFcnJvck1zZ0RlY29kZUVycm9yKHNlbGYpOgogICAgICAgICMgV2hlbiBwb3J0aW5nIHRoZSBtb2R1bGUgdG8gUHl0aG9uIDMuMCwgdGhlIGVycm9yIG1lc3NhZ2UgYWJvdXQKICAgICAgICAjIGRlY29kaW5nIGVycm9ycyBkaXNhcHBlYXJlZC4gVGhpcyB2ZXJpZmllcyB0aGV5J3JlIGJhY2sgYWdhaW4uCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcikgYXMgY206CiAgICAgICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCAneHh4JyB8fCA/IHx8ICd5eXknIGNvbG5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlcyhieXRlYXJyYXkoWzI1MF0pKSwpKS5mZXRjaG9uZSgpCiAgICAgICAgbXNnID0gIkNvdWxkIG5vdCBkZWNvZGUgdG8gVVRGLTggY29sdW1uICdjb2xuYW1lJyB3aXRoIHRleHQgJ3h4eCIKICAgICAgICBzZWxmLmFzc2VydEluKG1zZywgc3RyKGNtLmV4Y2VwdGlvbikpCgogICAgZGVmIENoZWNrUmVnaXN0ZXJBZGFwdGVyKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFNlZSBpc3N1ZSAzMzEyLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc3FsaXRlLnJlZ2lzdGVyX2FkYXB0ZXIsIHt9LCBOb25lKQoKICAgIGRlZiBDaGVja1NldElzb2xhdGlvbkxldmVsKHNlbGYpOgogICAgICAgICMgU2VlIGlzc3VlIDI3ODgxLgogICAgICAgIGNsYXNzIEN1c3RvbVN0cihzdHIpOgogICAgICAgICAgICBkZWYgdXBwZXIoc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICBkZWYgX19kZWxfXyhzZWxmKToKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSAiIgoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBOb25lCiAgICAgICAgZm9yIGxldmVsIGluICIiLCAiREVGRVJSRUQiLCAiSU1NRURJQVRFIiwgIkVYQ0xVU0lWRSI6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGxldmVsPWxldmVsKToKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbAogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IGxldmVsLmxvd2VyKCkKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbC5jYXBpdGFsaXplKCkKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBDdXN0b21TdHIobGV2ZWwpCgogICAgICAgICMgc2V0dGluZyBpc29sYXRpb25fbGV2ZWwgZmFpbHVyZSBzaG91bGQgbm90IGFsdGVyIHByZXZpb3VzIHN0YXRlCiAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IE5vbmUKICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gIkRFRkVSUkVEIgogICAgICAgIHBhaXJzID0gWwogICAgICAgICAgICAoMSwgVHlwZUVycm9yKSwgKGInJywgVHlwZUVycm9yKSwgKCJhYmMiLCBWYWx1ZUVycm9yKSwKICAgICAgICAgICAgKCJJTU1FRElBVEVcMEVYQ0xVU0lWRSIsIFZhbHVlRXJyb3IpLCAoIlx4ZTkiLCBWYWx1ZUVycm9yKSwKICAgICAgICBdCiAgICAgICAgZm9yIHZhbHVlLCBleGMgaW4gcGFpcnM6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGxldmVsPXZhbHVlKToKICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoZXhjKToKICAgICAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gdmFsdWUKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29uLmlzb2xhdGlvbl9sZXZlbCwgIkRFRkVSUkVEIikKCiAgICBkZWYgQ2hlY2tDdXJzb3JDb25zdHJ1Y3RvckNhbGxDaGVjayhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGN1cnNvciBtZXRob2RzIGNoZWNrIHdoZXRoZXIgYmFzZSBjbGFzcyBfX2luaXRfXyB3YXMKICAgICAgICBjYWxsZWQuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ3Vyc29yKHNxbGl0ZS5DdXJzb3IpOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgY29uKToKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBDdXJzb3IoY29uKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDQrNSIpLmZldGNoYWxsKCkKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzUmVnZXgoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInXkJhc2UgQ3Vyc29yXC5fX2luaXRfXyBub3QgY2FsbGVkXC4kJyk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RyU3ViY2xhc3Moc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGhlIFB5dGhvbiAzLjAgcG9ydCBvZiB0aGUgbW9kdWxlIGRpZG4ndCBjb3BlIHdpdGggdmFsdWVzIG9mIHN1YmNsYXNzZXMgb2Ygc3RyLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIE15U3RyKHN0cik6IHBhc3MKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgPyIsIChNeVN0cigiYWJjIiksKSkKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uQ29uc3RydWN0b3JDYWxsQ2hlY2soc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjb25uZWN0aW9uIG1ldGhvZHMgY2hlY2sgd2hldGhlciBiYXNlIGNsYXNzIF9faW5pdF9fIHdhcwogICAgICAgIGNhbGxlZC4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBDb25uZWN0aW9uKHNxbGl0ZS5Db25uZWN0aW9uKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUpOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBjb24gPSBDb25uZWN0aW9uKCI6bWVtb3J5OiIpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcik6CiAgICAgICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQoKICAgIGRlZiBDaGVja0N1cnNvclJlZ2lzdHJhdGlvbihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IHN1YmNsYXNzZWQgY3Vyc29yIGNsYXNzZXMgYXJlIGNvcnJlY3RseSByZWdpc3RlcmVkIHdpdGgKICAgICAgICB0aGUgY29ubmVjdGlvbiBvYmplY3QsIHRvby4gIChmZXRjaC1hY3Jvc3Mtcm9sbGJhY2sgcHJvYmxlbSkKICAgICAgICAiIiIKICAgICAgICBjbGFzcyBDb25uZWN0aW9uKHNxbGl0ZS5Db25uZWN0aW9uKToKICAgICAgICAgICAgZGVmIGN1cnNvcihzZWxmKToKICAgICAgICAgICAgICAgIHJldHVybiBDdXJzb3Ioc2VsZikKCiAgICAgICAgY2xhc3MgQ3Vyc29yKHNxbGl0ZS5DdXJzb3IpOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgY29uKToKICAgICAgICAgICAgICAgIHNxbGl0ZS5DdXJzb3IuX19pbml0X18oc2VsZiwgY29uKQoKICAgICAgICBjb24gPSBDb25uZWN0aW9uKCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oeCkiKQogICAgICAgIGN1ci5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoPykiLCBbKDMsKSwgKDQsKSwgKDUsKV0pCiAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCB4IGZyb20gZm9vIikKICAgICAgICBjb24ucm9sbGJhY2soKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLkludGVyZmFjZUVycm9yKToKICAgICAgICAgICAgY3VyLmZldGNoYWxsKCkKCiAgICBkZWYgQ2hlY2tBdXRvQ29tbWl0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgY3JlYXRpbmcgYSBjb25uZWN0aW9uIGluIGF1dG9jb21taXQgbW9kZSB3b3Jrcy4KICAgICAgICAyLjUuMyBpbnRyb2R1Y2VkIGEgcmVncmVzc2lvbiBzbyB0aGF0IHRoZXNlIGNvdWxkIG5vIGxvbmdlcgogICAgICAgIGJlIGNyZWF0ZWQuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgaXNvbGF0aW9uX2xldmVsPU5vbmUpCgogICAgZGVmIENoZWNrUHJhZ21hQXV0b2NvbW1pdChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IHJ1bm5pbmcgYSBQUkFHTUEgc3RhdGVtZW50IHRoYXQgZG9lcyBhbiBhdXRvY29tbWl0IGRvZXMKICAgICAgICB3b3JrLiBUaGlzIGRpZCBub3Qgd29yayBpbiAyLjUuMy8yLjUuNC4KICAgICAgICAiIiIKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQogICAgICAgIGN1ci5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKDUpIikKCiAgICAgICAgY3VyLmV4ZWN1dGUoInByYWdtYSBwYWdlX3NpemUiKQogICAgICAgIHJvdyA9IGN1ci5mZXRjaG9uZSgpCgogICAgZGVmIENoZWNrQ29ubmVjdGlvbkNhbGwoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ2FsbCBhIGNvbm5lY3Rpb24gd2l0aCBhIG5vbi1zdHJpbmcgU1FMIHJlcXVlc3Q6IGNoZWNrIGVycm9yIGhhbmRsaW5nCiAgICAgICAgb2YgdGhlIHN0YXRlbWVudCBjb25zdHJ1Y3Rvci4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuV2FybmluZywgc2VsZi5jb24sIDEpCgogICAgZGVmIENoZWNrQ29sbGF0aW9uKHNlbGYpOgogICAgICAgIGRlZiBjb2xsYXRpb25fY2IoYSwgYik6CiAgICAgICAgICAgIHJldHVybiAxCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IsIHNlbGYuY29uLmNyZWF0ZV9jb2xsYXRpb24sCiAgICAgICAgICAgICMgTG9uZSBzdXJyb2dhdGUgY2Fubm90IGJlIGVuY29kZWQgdG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcgKHV0ZjgpCiAgICAgICAgICAgICJcdURDODAiLCBjb2xsYXRpb25fY2IpCgogICAgZGVmIENoZWNrUmVjdXJzaXZlQ3Vyc29yVXNlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWUxMDgxMQoKICAgICAgICBSZWN1cnNpdmVseSB1c2luZyBhIGN1cnNvciwgc3VjaCBhcyB3aGVuIHJldXNpbmcgaXQgZnJvbSBhIGdlbmVyYXRvciBsZWQgdG8gc2VnZmF1bHRzLgogICAgICAgIE5vdyB3ZSBjYXRjaCByZWN1cnNpdmUgY3Vyc29yIHVzYWdlIGFuZCByYWlzZSBhIFByb2dyYW1taW5nRXJyb3IuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBhIChiYXIpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGIgKGJheikiKQoKICAgICAgICBkZWYgZm9vKCk6CiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJpbnNlcnQgaW50byBhIChiYXIpIHZhbHVlcyAoPykiLCAoMSwpKQogICAgICAgICAgICB5aWVsZCAxCgogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIGIgKGJheikgdmFsdWVzICg/KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGksKSBmb3IgaSBpbiBmb28oKSkpCgogICAgZGVmIENoZWNrQ29udmVydFRpbWVzdGFtcE1pY3Jvc2Vjb25kUGFkZGluZyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBodHRwOi8vYnVncy5weXRob24ub3JnL2lzc3VlMTQ3MjAKCiAgICAgICAgVGhlIG1pY3Jvc2Vjb25kIHBhcnNpbmcgb2YgY29udmVydF90aW1lc3RhbXAoKSBzaG91bGQgcGFkIHdpdGggemVyb3MsCiAgICAgICAgc2luY2UgdGhlIG1pY3Jvc2Vjb25kIHN0cmluZyAiNDU2IiBhY3R1YWxseSByZXByZXNlbnRzICI0NTYwMDAiLgogICAgICAgICIiIgoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiQ1JFQVRFIFRBQkxFIHQgKHggVElNRVNUQU1QKSIpCgogICAgICAgICMgTWljcm9zZWNvbmRzIHNob3VsZCBiZSA0NTYwMDAKICAgICAgICBjdXIuZXhlY3V0ZSgiSU5TRVJUIElOVE8gdCAoeCkgVkFMVUVTICgnMjAxMi0wNC0wNCAxNTowNjowMC40NTYnKSIpCgogICAgICAgICMgTWljcm9zZWNvbmRzIHNob3VsZCBiZSB0cnVuY2F0ZWQgdG8gMTIzNDU2CiAgICAgICAgY3VyLmV4ZWN1dGUoIklOU0VSVCBJTlRPIHQgKHgpIFZBTFVFUyAoJzIwMTItMDQtMDQgMTU6MDY6MDAuMTIzNDU2Nzg5JykiKQoKICAgICAgICBjdXIuZXhlY3V0ZSgiU0VMRUNUICogRlJPTSB0IikKICAgICAgICB2YWx1ZXMgPSBbeFswXSBmb3IgeCBpbiBjdXIuZmV0Y2hhbGwoKV0KCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh2YWx1ZXMsIFsKICAgICAgICAgICAgZGF0ZXRpbWUuZGF0ZXRpbWUoMjAxMiwgNCwgNCwgMTUsIDYsIDAsIDQ1NjAwMCksCiAgICAgICAgICAgIGRhdGV0aW1lLmRhdGV0aW1lKDIwMTIsIDQsIDQsIDE1LCA2LCAwLCAxMjM0NTYpLAogICAgICAgIF0pCgogICAgZGVmIENoZWNrSW52YWxpZElzb2xhdGlvbkxldmVsVHlwZShzZWxmKToKICAgICAgICAjIGlzb2xhdGlvbiBsZXZlbCBpcyBhIHN0cmluZywgbm90IGFuIGludGVnZXIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3FsaXRlLmNvbm5lY3QsICI6bWVtb3J5OiIsIGlzb2xhdGlvbl9sZXZlbD0xMjMpCgoKICAgIGRlZiBDaGVja051bGxDaGFyYWN0ZXIoc2VsZik6CiAgICAgICAgIyBJc3N1ZSAjMjExNDcKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGNvbiwgIlwwc2VsZWN0IDEiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGNvbiwgInNlbGVjdCAxXDAiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGN1ci5leGVjdXRlLCAiIFwwc2VsZWN0IDIiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGN1ci5leGVjdXRlLCAic2VsZWN0IDJcMCIpCgogICAgZGVmIENoZWNrQ29tbWl0Q3Vyc29yUmVzZXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ29ubmVjdGlvbi5jb21taXQoKSBkaWQgcmVzZXQgY3Vyc29ycywgd2hpY2ggbWFkZSBzcWxpdGUzCiAgICAgICAgdG8gcmV0dXJuIHJvd3MgbXVsdGlwbGUgdGltZXMgd2hlbiBmZXRjaGVkIGZyb20gY3Vyc29ycwogICAgICAgIGFmdGVyIGNvbW1pdC4gU2VlIGlzc3VlcyAxMDUxMyBhbmQgMjMxMjkgZm9yIGRldGFpbHMuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZXNjcmlwdCgiIiIKICAgICAgICBjcmVhdGUgdGFibGUgdChjKTsKICAgICAgICBjcmVhdGUgdGFibGUgdDIoYyk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMCk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMSk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMik7CiAgICAgICAgIiIiKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvbi5pc29sYXRpb25fbGV2ZWwsICIiKQoKICAgICAgICBjb3VudGVyID0gMAogICAgICAgIGZvciBpLCByb3cgaW4gZW51bWVyYXRlKGNvbi5leGVjdXRlKCJzZWxlY3QgYyBmcm9tIHQiKSk6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGk9aSwgcm93PXJvdyk6CiAgICAgICAgICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gdDIoYykgdmFsdWVzICg/KSIsIChpLCkpCiAgICAgICAgICAgICAgICBjb24uY29tbWl0KCkKICAgICAgICAgICAgICAgIGlmIGNvdW50ZXIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgMCkKICAgICAgICAgICAgICAgIGVsaWYgY291bnRlciA9PSAxOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocm93WzBdLCAxKQogICAgICAgICAgICAgICAgZWxpZiBjb3VudGVyID09IDI6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sIDIpCiAgICAgICAgICAgICAgICBjb3VudGVyICs9IDEKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvdW50ZXIsIDMsICJzaG91bGQgaGF2ZSByZXR1cm5lZCBleGFjdGx5IHRocmVlIHJvd3MiKQoKICAgIGRlZiBDaGVja0JwbzMxNzcwKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRoZSBpbnRlcnByZXRlciBzaG91bGRuJ3QgY3Jhc2ggaW4gY2FzZSBDdXJzb3IuX19pbml0X18oKSBpcyBjYWxsZWQKICAgICAgICBtb3JlIHRoYW4gb25jZS4KICAgICAgICAiIiIKICAgICAgICBkZWYgY2FsbGJhY2soKmFyZ3MpOgogICAgICAgICAgICBwYXNzCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBzcWxpdGUuQ3Vyc29yKGNvbikKICAgICAgICByZWYgPSB3ZWFrcmVmLnJlZihjdXIsIGNhbGxiYWNrKQogICAgICAgIGN1ci5fX2luaXRfXyhjb24pCiAgICAgICAgZGVsIGN1cgogICAgICAgICMgVGhlIGludGVycHJldGVyIHNob3VsZG4ndCBjcmFzaCB3aGVuIHJlZiBpcyBjb2xsZWN0ZWQuCiAgICAgICAgZGVsIHJlZgogICAgICAgIHN1cHBvcnQuZ2NfY29sbGVjdCgpCgogICAgZGVmIENoZWNrRGVsSXNvbGF0aW9uX2xldmVsU2VnZmF1bHQoc2VsZik6CiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIGRlbCBzZWxmLmNvbi5pc29sYXRpb25fbGV2ZWwKCiAgICBkZWYgQ2hlY2tCcG8zNzM0NyhzZWxmKToKICAgICAgICBjbGFzcyBQcmludGVyOgogICAgICAgICAgICBkZWYgbG9nKHNlbGYsICphcmdzKToKICAgICAgICAgICAgICAgIHJldHVybiBzcWxpdGUuU1FMSVRFX09LCgogICAgICAgIGZvciBtZXRob2QgaW4gW3NlbGYuY29uLnNldF90cmFjZV9jYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBmdW5jdG9vbHMucGFydGlhbChzZWxmLmNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlciwgbj0xKSwKICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbi5zZXRfYXV0aG9yaXplcl06CiAgICAgICAgICAgIHByaW50ZXJfaW5zdGFuY2UgPSBQcmludGVyKCkKICAgICAgICAgICAgbWV0aG9kKHByaW50ZXJfaW5zdGFuY2UubG9nKQogICAgICAgICAgICBtZXRob2QocHJpbnRlcl9pbnN0YW5jZS5sb2cpCiAgICAgICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCAxIikgICMgdHJpZ2dlciBzZWcgZmF1bHQKICAgICAgICAgICAgbWV0aG9kKE5vbmUpCgoKCmRlZiBzdWl0ZSgpOgogICAgcmVncmVzc2lvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShSZWdyZXNzaW9uVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKCgKICAgICAgICByZWdyZXNzaW9uX3N1aXRlLAogICAgKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==