Iy0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHJhbmdlKDUpXQogICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoeCkiKQogICAgICAgIGZvciBpIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgY3Vyc29yc1swXS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTApXSkKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICAgICAgICAgIGN1cnNvcnNbaV0uZXhlY3V0ZSgiICIgKiBpICsgInNlbGVjdCB4IGZyb20gdGVzdCIpCgogICAgICAgIGNvbi5yb2xsYmFjaygpCgogICAgZGVmIENoZWNrQ29sdW1uTmFtZVdpdGhTcGFjZXMoc2VsZik6CiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXIgW2RhdGV0aW1lXSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciIpCgogICAgICAgIGN1ci5leGVjdXRlKCdzZWxlY3QgMSBhcyAiZm9vIGJheiInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJheiIpCgogICAgZGVmIENoZWNrU3RhdGVtZW50RmluYWxpemF0aW9uT25DbG9zZURiKHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgdmVyc2lvbnMgPD0gMi4zLjMgb25seSBmaW5hbGl6ZWQgc3RhdGVtZW50cyBpbiB0aGUgc3RhdGVtZW50CiAgICAgICAgIyBjYWNoZSB3aGVuIGNsb3NpbmcgdGhlIGRhdGFiYXNlLiBzdGF0ZW1lbnRzIHRoYXQgd2VyZSBzdGlsbAogICAgICAgICMgcmVmZXJlbmNlZCBpbiBjdXJzb3JzIHdlcmVuJ3QgY2xvc2VkIGFuZCBjb3VsZCBwcm92b2tlICIKICAgICAgICAjICJPcGVyYXRpb25hbEVycm9yOiBVbmFibGUgdG8gY2xvc2UgZHVlIHRvIHVuZmluYWxpc2VkIHN0YXRlbWVudHMiLgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3Vyc29ycyA9IFtdCiAgICAgICAgIyBkZWZhdWx0IHN0YXRlbWVudCBjYWNoZSBzaXplIGlzIDEwMAogICAgICAgIGZvciBpIGluIHJhbmdlKDEwNSk6CiAgICAgICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgICAgICBjdXJzb3JzLmFwcGVuZChjdXIpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgMSB4IHVuaW9uIHNlbGVjdCAiICsgc3RyKGkpKQogICAgICAgIGNvbi5jbG9zZSgpCgogICAgQHVuaXR0ZXN0LnNraXBJZihzcWxpdGUuc3FsaXRlX3ZlcnNpb25faW5mbyA8ICgzLCAyLCAyKSwgJ25lZWRzIHNxbGl0ZSAzLjIuMiBvciBuZXdlcicpCiAgICBkZWYgQ2hlY2tPbkNvbmZsaWN0Um9sbGJhY2soc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyh4LCB1bmlxdWUoeCkgb24gY29uZmxpY3Qgcm9sbGJhY2spIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMSkiKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDEpIikKICAgICAgICBleGNlcHQgc3FsaXRlLkRhdGFiYXNlRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMikiKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoInB5c3FsaXRlIGtuZXcgbm90aGluZyBhYm91dCB0aGUgaW1wbGljaXQgUk9MTEJBQ0siKQoKICAgIGRlZiBDaGVja1dvcmthcm91bmRGb3JCdWdneVNxbGl0ZVRyYW5zZmVyQmluZGluZ3Moc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgd291bGQgY3Jhc2ggd2l0aCBvbGRlciBTUUxpdGUgdmVyc2lvbnMgdW5sZXNzCiAgICAgICAgYSB3b3JrYXJvdW5kIGlzIGltcGxlbWVudGVkLgogICAgICAgICIiIgogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiZHJvcCB0YWJsZSBmb28iKQogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCgogICAgZGVmIENoZWNrRW1wdHlTdGF0ZW1lbnQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgdXNlZCB0byBzZWdmYXVsdCB3aXRoIFNRTGl0ZSB2ZXJzaW9ucyAzLjUueC4gVGhlc2UgcmV0dXJuIE5VTEwKICAgICAgICBmb3IgIm5vLW9wZXJhdGlvbiIgc3RhdGVtZW50cwogICAgICAgICIiIgogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoIiIpCgogICAgZGVmIENoZWNrVHlwZU1hcFVzYWdlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHVudGlsIDIuNC4xIGRpZCBub3QgcmVidWlsZCB0aGUgcm93X2Nhc3RfbWFwIHdoZW4gcmVjb21waWxpbmcKICAgICAgICBhIHN0YXRlbWVudC4gVGhpcyB0ZXN0IGV4aGliaXRzIHRoZSBwcm9ibGVtLgogICAgICAgICIiIgogICAgICAgIFNFTEVDVCA9ICJzZWxlY3QgKiBmcm9tIGZvbyIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfREVDTFRZUEVTKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhciB0aW1lc3RhbXApIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg/KSIsIChkYXRldGltZS5kYXRldGltZS5ub3coKSwpKQogICAgICAgIGNvbi5leGVjdXRlKFNFTEVDVCkKICAgICAgICBjb24uZXhlY3V0ZSgiZHJvcCB0YWJsZSBmb28iKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhciBpbnRlZ2VyKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoNSkiKQogICAgICAgIGNvbi5leGVjdXRlKFNFTEVDVCkKCiAgICBkZWYgQ2hlY2tFcnJvck1zZ0RlY29kZUVycm9yKHNlbGYpOgogICAgICAgICMgV2hlbiBwb3J0aW5nIHRoZSBtb2R1bGUgdG8gUHl0aG9uIDMuMCwgdGhlIGVycm9yIG1lc3NhZ2UgYWJvdXQKICAgICAgICAjIGRlY29kaW5nIGVycm9ycyBkaXNhcHBlYXJlZC4gVGhpcyB2ZXJpZmllcyB0aGV5J3JlIGJhY2sgYWdhaW4uCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcikgYXMgY206CiAgICAgICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCAneHh4JyB8fCA/IHx8ICd5eXknIGNvbG5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChieXRlcyhieXRlYXJyYXkoWzI1MF0pKSwpKS5mZXRjaG9uZSgpCiAgICAgICAgbXNnID0gIkNvdWxkIG5vdCBkZWNvZGUgdG8gVVRGLTggY29sdW1uICdjb2xuYW1lJyB3aXRoIHRleHQgJ3h4eCIKICAgICAgICBzZWxmLmFzc2VydEluKG1zZywgc3RyKGNtLmV4Y2VwdGlvbikpCgogICAgZGVmIENoZWNrUmVnaXN0ZXJBZGFwdGVyKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFNlZSBpc3N1ZSAzMzEyLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc3FsaXRlLnJlZ2lzdGVyX2FkYXB0ZXIsIHt9LCBOb25lKQoKICAgIGRlZiBDaGVja1NldElzb2xhdGlvbkxldmVsKHNlbGYpOgogICAgICAgICMgU2VlIGlzc3VlIDI3ODgxLgogICAgICAgIGNsYXNzIEN1c3RvbVN0cihzdHIpOgogICAgICAgICAgICBkZWYgdXBwZXIoc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICBkZWYgX19kZWxfXyhzZWxmKToKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSAiIgoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBOb25lCiAgICAgICAgZm9yIGxldmVsIGluICIiLCAiREVGRVJSRUQiLCAiSU1NRURJQVRFIiwgIkVYQ0xVU0lWRSI6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGxldmVsPWxldmVsKToKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbAogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IGxldmVsLmxvd2VyKCkKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbC5jYXBpdGFsaXplKCkKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBDdXN0b21TdHIobGV2ZWwpCgogICAgICAgICMgc2V0dGluZyBpc29sYXRpb25fbGV2ZWwgZmFpbHVyZSBzaG91bGQgbm90IGFsdGVyIHByZXZpb3VzIHN0YXRlCiAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IE5vbmUKICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gIkRFRkVSUkVEIgogICAgICAgIHBhaXJzID0gWwogICAgICAgICAgICAoMSwgVHlwZUVycm9yKSwgKGInJywgVHlwZUVycm9yKSwgKCJhYmMiLCBWYWx1ZUVycm9yKSwKICAgICAgICAgICAgKCJJTU1FRElBVEVcMEVYQ0xVU0lWRSIsIFZhbHVlRXJyb3IpLCAoIlx4ZTkiLCBWYWx1ZUVycm9yKSwKICAgICAgICBdCiAgICAgICAgZm9yIHZhbHVlLCBleGMgaW4gcGFpcnM6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGxldmVsPXZhbHVlKToKICAgICAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoZXhjKToKICAgICAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gdmFsdWUKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29uLmlzb2xhdGlvbl9sZXZlbCwgIkRFRkVSUkVEIikKCiAgICBkZWYgQ2hlY2tDdXJzb3JDb25zdHJ1Y3RvckNhbGxDaGVjayhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGN1cnNvciBtZXRob2RzIGNoZWNrIHdoZXRoZXIgYmFzZSBjbGFzcyBfX2luaXRfXyB3YXMKICAgICAgICBjYWxsZWQuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ3Vyc29yKHNxbGl0ZS5DdXJzb3IpOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgY29uKToKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBDdXJzb3IoY29uKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDQrNSIpLmZldGNoYWxsKCkKCiAgICBkZWYgQ2hlY2tTdHJTdWJjbGFzcyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUaGUgUHl0aG9uIDMuMCBwb3J0IG9mIHRoZSBtb2R1bGUgZGlkbid0IGNvcGUgd2l0aCB2YWx1ZXMgb2Ygc3ViY2xhc3NlcyBvZiBzdHIuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgTXlTdHIoc3RyKTogcGFzcwogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCA/IiwgKE15U3RyKCJhYmMiKSwpKQoKICAgIGRlZiBDaGVja0Nvbm5lY3Rpb25Db25zdHJ1Y3RvckNhbGxDaGVjayhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGNvbm5lY3Rpb24gbWV0aG9kcyBjaGVjayB3aGV0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzCiAgICAgICAgY2FsbGVkLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIENvbm5lY3Rpb24oc3FsaXRlLkNvbm5lY3Rpb24pOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSk6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGNvbiA9IENvbm5lY3Rpb24oIjptZW1vcnk6IikKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yKToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCgogICAgZGVmIENoZWNrQ3Vyc29yUmVnaXN0cmF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgc3ViY2xhc3NlZCBjdXJzb3IgY2xhc3NlcyBhcmUgY29ycmVjdGx5IHJlZ2lzdGVyZWQgd2l0aAogICAgICAgIHRoZSBjb25uZWN0aW9uIG9iamVjdCwgdG9vLiAgKGZldGNoLWFjcm9zcy1yb2xsYmFjayBwcm9ibGVtKQogICAgICAgICIiIgogICAgICAgIGNsYXNzIENvbm5lY3Rpb24oc3FsaXRlLkNvbm5lY3Rpb24pOgogICAgICAgICAgICBkZWYgY3Vyc29yKHNlbGYpOgogICAgICAgICAgICAgICAgcmV0dXJuIEN1cnNvcihzZWxmKQoKICAgICAgICBjbGFzcyBDdXJzb3Ioc3FsaXRlLkN1cnNvcik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBjb24pOgogICAgICAgICAgICAgICAgc3FsaXRlLkN1cnNvci5fX2luaXRfXyhzZWxmLCBjb24pCgogICAgICAgIGNvbiA9IENvbm5lY3Rpb24oIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyh4KSIpCiAgICAgICAgY3VyLmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICg/KSIsIFsoMywpLCAoNCwpLCAoNSwpXSkKICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IHggZnJvbSBmb28iKQogICAgICAgIGNvbi5yb2xsYmFjaygpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuSW50ZXJmYWNlRXJyb3IpOgogICAgICAgICAgICBjdXIuZmV0Y2hhbGwoKQoKICAgIGRlZiBDaGVja0F1dG9Db21taXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjcmVhdGluZyBhIGNvbm5lY3Rpb24gaW4gYXV0b2NvbW1pdCBtb2RlIHdvcmtzLgogICAgICAgIDIuNS4zIGludHJvZHVjZWQgYSByZWdyZXNzaW9uIHNvIHRoYXQgdGhlc2UgY291bGQgbm8gbG9uZ2VyCiAgICAgICAgYmUgY3JlYXRlZC4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBpc29sYXRpb25fbGV2ZWw9Tm9uZSkKCiAgICBkZWYgQ2hlY2tQcmFnbWFBdXRvY29tbWl0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgcnVubmluZyBhIFBSQUdNQSBzdGF0ZW1lbnQgdGhhdCBkb2VzIGFuIGF1dG9jb21taXQgZG9lcwogICAgICAgIHdvcmsuIFRoaXMgZGlkIG5vdCB3b3JrIGluIDIuNS4zLzIuNS40LgogICAgICAgICIiIgogICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCiAgICAgICAgY3VyLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoNSkiKQoKICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHBhZ2Vfc2l6ZSIpCiAgICAgICAgcm93ID0gY3VyLmZldGNob25lKCkKCiAgICBkZWYgQ2hlY2tTZXREaWN0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFNlZSBodHRwOi8vYnVncy5weXRob24ub3JnL2lzc3VlNzQ3OAoKICAgICAgICBJdCB3YXMgcG9zc2libGUgdG8gc3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyIGNhbGxiYWNrcyB0aGF0IGNvdWxkIG5vdCBiZQogICAgICAgIGhhc2hlZC4gUmV0dXJuIGNvZGVzIG9mIFB5RGljdF9TZXRJdGVtIHdlcmUgbm90IGNoZWNrZWQgcHJvcGVybHkuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgTm90SGFzaGFibGU6CiAgICAgICAgICAgIGRlZiBfX2NhbGxfXyhzZWxmLCAqYXJncywgKiprdyk6CiAgICAgICAgICAgICAgICBwYXNzCiAgICAgICAgICAgIGRlZiBfX2hhc2hfXyhzZWxmKToKICAgICAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcigpCiAgICAgICAgdmFyID0gTm90SGFzaGFibGUoKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc2VsZi5jb24uY3JlYXRlX2Z1bmN0aW9uLCB2YXIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5jcmVhdGVfYWdncmVnYXRlLCB2YXIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5zZXRfYXV0aG9yaXplciwgdmFyKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc2VsZi5jb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIsIHZhcikKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uQ2FsbChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBDYWxsIGEgY29ubmVjdGlvbiB3aXRoIGEgbm9uLXN0cmluZyBTUUwgcmVxdWVzdDogY2hlY2sgZXJyb3IgaGFuZGxpbmcKICAgICAgICBvZiB0aGUgc3RhdGVtZW50IGNvbnN0cnVjdG9yLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5XYXJuaW5nLCBzZWxmLmNvbiwgMSkKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb24oc2VsZik6CiAgICAgICAgZGVmIGNvbGxhdGlvbl9jYihhLCBiKToKICAgICAgICAgICAgcmV0dXJuIDEKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvciwgc2VsZi5jb24uY3JlYXRlX2NvbGxhdGlvbiwKICAgICAgICAgICAgIyBMb25lIHN1cnJvZ2F0ZSBjYW5ub3QgYmUgZW5jb2RlZCB0byB0aGUgZGVmYXVsdCBlbmNvZGluZyAodXRmOCkKICAgICAgICAgICAgIlx1REM4MCIsIGNvbGxhdGlvbl9jYikKCiAgICBkZWYgQ2hlY2tSZWN1cnNpdmVDdXJzb3JVc2Uoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgaHR0cDovL2J1Z3MucHl0aG9uLm9yZy9pc3N1ZTEwODExCgogICAgICAgIFJlY3Vyc2l2ZWx5IHVzaW5nIGEgY3Vyc29yLCBzdWNoIGFzIHdoZW4gcmV1c2luZyBpdCBmcm9tIGEgZ2VuZXJhdG9yIGxlZCB0byBzZWdmYXVsdHMuCiAgICAgICAgTm93IHdlIGNhdGNoIHJlY3Vyc2l2ZSBjdXJzb3IgdXNhZ2UgYW5kIHJhaXNlIGEgUHJvZ3JhbW1pbmdFcnJvci4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQoKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGEgKGJhcikiKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgYiAoYmF6KSIpCgogICAgICAgIGRlZiBmb28oKToKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoImluc2VydCBpbnRvIGEgKGJhcikgdmFsdWVzICg/KSIsICgxLCkpCiAgICAgICAgICAgIHlpZWxkIDEKCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcik6CiAgICAgICAgICAgIGN1ci5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gYiAoYmF6KSB2YWx1ZXMgKD8pIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaSwpIGZvciBpIGluIGZvbygpKSkKCiAgICBkZWYgQ2hlY2tDb252ZXJ0VGltZXN0YW1wTWljcm9zZWNvbmRQYWRkaW5nKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWUxNDcyMAoKICAgICAgICBUaGUgbWljcm9zZWNvbmQgcGFyc2luZyBvZiBjb252ZXJ0X3RpbWVzdGFtcCgpIHNob3VsZCBwYWQgd2l0aCB6ZXJvcywKICAgICAgICBzaW5jZSB0aGUgbWljcm9zZWNvbmQgc3RyaW5nICI0NTYiIGFjdHVhbGx5IHJlcHJlc2VudHMgIjQ1NjAwMCIuCiAgICAgICAgIiIiCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfREVDTFRZUEVTKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJDUkVBVEUgVEFCTEUgdCAoeCBUSU1FU1RBTVApIikKCiAgICAgICAgIyBNaWNyb3NlY29uZHMgc2hvdWxkIGJlIDQ1NjAwMAogICAgICAgIGN1ci5leGVjdXRlKCJJTlNFUlQgSU5UTyB0ICh4KSBWQUxVRVMgKCcyMDEyLTA0LTA0IDE1OjA2OjAwLjQ1NicpIikKCiAgICAgICAgIyBNaWNyb3NlY29uZHMgc2hvdWxkIGJlIHRydW5jYXRlZCB0byAxMjM0NTYKICAgICAgICBjdXIuZXhlY3V0ZSgiSU5TRVJUIElOVE8gdCAoeCkgVkFMVUVTICgnMjAxMi0wNC0wNCAxNTowNjowMC4xMjM0NTY3ODknKSIpCgogICAgICAgIGN1ci5leGVjdXRlKCJTRUxFQ1QgKiBGUk9NIHQiKQogICAgICAgIHZhbHVlcyA9IFt4WzBdIGZvciB4IGluIGN1ci5mZXRjaGFsbCgpXQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHZhbHVlcywgWwogICAgICAgICAgICBkYXRldGltZS5kYXRldGltZSgyMDEyLCA0LCA0LCAxNSwgNiwgMCwgNDU2MDAwKSwKICAgICAgICAgICAgZGF0ZXRpbWUuZGF0ZXRpbWUoMjAxMiwgNCwgNCwgMTUsIDYsIDAsIDEyMzQ1NiksCiAgICAgICAgXSkKCiAgICBkZWYgQ2hlY2tJbnZhbGlkSXNvbGF0aW9uTGV2ZWxUeXBlKHNlbGYpOgogICAgICAgICMgaXNvbGF0aW9uIGxldmVsIGlzIGEgc3RyaW5nLCBub3QgYW4gaW50ZWdlcgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICBzcWxpdGUuY29ubmVjdCwgIjptZW1vcnk6IiwgaXNvbGF0aW9uX2xldmVsPTEyMykKCgogICAgZGVmIENoZWNrTnVsbENoYXJhY3RlcihzZWxmKToKICAgICAgICAjIElzc3VlICMyMTE0NwogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY29uLCAiXDBzZWxlY3QgMSIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY29uLCAic2VsZWN0IDFcMCIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY3VyLmV4ZWN1dGUsICIgXDBzZWxlY3QgMiIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY3VyLmV4ZWN1dGUsICJzZWxlY3QgMlwwIikKCiAgICBkZWYgQ2hlY2tDb21taXRDdXJzb3JSZXNldChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBDb25uZWN0aW9uLmNvbW1pdCgpIGRpZCByZXNldCBjdXJzb3JzLCB3aGljaCBtYWRlIHNxbGl0ZTMKICAgICAgICB0byByZXR1cm4gcm93cyBtdWx0aXBsZSB0aW1lcyB3aGVuIGZldGNoZWQgZnJvbSBjdXJzb3JzCiAgICAgICAgYWZ0ZXIgY29tbWl0LiBTZWUgaXNzdWVzIDEwNTEzIGFuZCAyMzEyOSBmb3IgZGV0YWlscy4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5leGVjdXRlc2NyaXB0KCIiIgogICAgICAgIGNyZWF0ZSB0YWJsZSB0KGMpOwogICAgICAgIGNyZWF0ZSB0YWJsZSB0MihjKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygwKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygxKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygyKTsKICAgICAgICAiIiIpCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29uLmlzb2xhdGlvbl9sZXZlbCwgIiIpCgogICAgICAgIGNvdW50ZXIgPSAwCiAgICAgICAgZm9yIGksIHJvdyBpbiBlbnVtZXJhdGUoY29uLmV4ZWN1dGUoInNlbGVjdCBjIGZyb20gdCIpKToKICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QoaT1pLCByb3c9cm93KToKICAgICAgICAgICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byB0MihjKSB2YWx1ZXMgKD8pIiwgKGksKSkKICAgICAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgICAgICAgICAgaWYgY291bnRlciA9PSAwOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocm93WzBdLCAwKQogICAgICAgICAgICAgICAgZWxpZiBjb3VudGVyID09IDE6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sIDEpCiAgICAgICAgICAgICAgICBlbGlmIGNvdW50ZXIgPT0gMjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgMikKICAgICAgICAgICAgICAgIGNvdW50ZXIgKz0gMQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY291bnRlciwgMywgInNob3VsZCBoYXZlIHJldHVybmVkIGV4YWN0bHkgdGhyZWUgcm93cyIpCgoKZGVmIHN1aXRlKCk6CiAgICByZWdyZXNzaW9uX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFJlZ3Jlc3Npb25UZXN0cywgIkNoZWNrIikKICAgIHJldHVybiB1bml0dGVzdC5UZXN0U3VpdGUoKHJlZ3Jlc3Npb25fc3VpdGUsKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==