Iy0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQppbXBvcnQgd2Vha3JlZgppbXBvcnQgZnVuY3Rvb2xzCmZyb20gdGVzdCBpbXBvcnQgc3VwcG9ydAoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHJhbmdlKDUpXQogICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoeCkiKQogICAgICAgIGZvciBpIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgY3Vyc29yc1swXS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTApXSkKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICAgICAgICAgIGN1cnNvcnNbaV0uZXhlY3V0ZSgiICIgKiBpICsgInNlbGVjdCB4IGZyb20gdGVzdCIpCgogICAgICAgIGNvbi5yb2xsYmFjaygpCgogICAgZGVmIENoZWNrQ29sdW1uTmFtZVdpdGhTcGFjZXMoc2VsZik6CiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXIgW2RhdGV0aW1lXSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciBbZGF0ZXRpbWVdIikKCiAgICAgICAgY3VyLmV4ZWN1dGUoJ3NlbGVjdCAxIGFzICJmb28gYmF6IicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjdXIuZGVzY3JpcHRpb25bMF1bMF0sICJmb28gYmF6IikKCiAgICBkZWYgQ2hlY2tTdGF0ZW1lbnRGaW5hbGl6YXRpb25PbkNsb3NlRGIoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSB2ZXJzaW9ucyA8PSAyLjMuMyBvbmx5IGZpbmFsaXplZCBzdGF0ZW1lbnRzIGluIHRoZSBzdGF0ZW1lbnQKICAgICAgICAjIGNhY2hlIHdoZW4gY2xvc2luZyB0aGUgZGF0YWJhc2UuIHN0YXRlbWVudHMgdGhhdCB3ZXJlIHN0aWxsCiAgICAgICAgIyByZWZlcmVuY2VkIGluIGN1cnNvcnMgd2VyZW4ndCBjbG9zZWQgYW5kIGNvdWxkIHByb3Zva2UgIgogICAgICAgICMgIk9wZXJhdGlvbmFsRXJyb3I6IFVuYWJsZSB0byBjbG9zZSBkdWUgdG8gdW5maW5hbGlzZWQgc3RhdGVtZW50cyIuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXJzb3JzID0gW10KICAgICAgICAjIGRlZmF1bHQgc3RhdGVtZW50IGNhY2hlIHNpemUgaXMgMTAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTA1KToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1cnNvcnMuYXBwZW5kKGN1cikKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCAxIHggdW5pb24gc2VsZWN0ICIgKyBzdHIoaSkpCiAgICAgICAgY29uLmNsb3NlKCkKCiAgICBAdW5pdHRlc3Quc2tpcElmKHNxbGl0ZS5zcWxpdGVfdmVyc2lvbl9pbmZvIDwgKDMsIDIsIDIpLCAnbmVlZHMgc3FsaXRlIDMuMi4yIG9yIG5ld2VyJykKICAgIGRlZiBDaGVja09uQ29uZmxpY3RSb2xsYmFjayhzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgsIHVuaXF1ZSh4KSBvbiBjb25mbGljdCByb2xsYmFjaykiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMSkiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuRGF0YWJhc2VFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgyKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uY29tbWl0KCkKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHNlbGYuZmFpbCgicHlzcWxpdGUga25ldyBub3RoaW5nIGFib3V0IHRoZSBpbXBsaWNpdCBST0xMQkFDSyIpCgogICAgZGVmIENoZWNrV29ya2Fyb3VuZEZvckJ1Z2d5U3FsaXRlVHJhbnNmZXJCaW5kaW5ncyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB3b3VsZCBjcmFzaCB3aXRoIG9sZGVyIFNRTGl0ZSB2ZXJzaW9ucyB1bmxlc3MKICAgICAgICBhIHdvcmthcm91bmQgaXMgaW1wbGVtZW50ZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKCiAgICBkZWYgQ2hlY2tFbXB0eVN0YXRlbWVudChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1c2VkIHRvIHNlZ2ZhdWx0IHdpdGggU1FMaXRlIHZlcnNpb25zIDMuNS54LiBUaGVzZSByZXR1cm4gTlVMTAogICAgICAgIGZvciAibm8tb3BlcmF0aW9uIiBzdGF0ZW1lbnRzCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiIikKCiAgICBkZWYgQ2hlY2tUeXBlTWFwVXNhZ2Uoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgdW50aWwgMi40LjEgZGlkIG5vdCByZWJ1aWxkIHRoZSByb3dfY2FzdF9tYXAgd2hlbiByZWNvbXBpbGluZwogICAgICAgIGEgc3RhdGVtZW50LiBUaGlzIHRlc3QgZXhoaWJpdHMgdGhlIHByb2JsZW0uCiAgICAgICAgIiIiCiAgICAgICAgU0VMRUNUID0gInNlbGVjdCAqIGZyb20gZm9vIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9ERUNMVFlQRVMpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIHRpbWVzdGFtcCkiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKD8pIiwgKGRhdGV0aW1lLmRhdGV0aW1lLm5vdygpLCkpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQogICAgICAgIGNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIGludGVnZXIpIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQoKICAgIGRlZiBDaGVja0JpbmRNdXRhdGluZ0xpc3Qoc2VsZik6CiAgICAgICAgIyBJc3N1ZTQxNjYyOiBDcmFzaCB3aGVuIG11dGF0ZSBhIGxpc3Qgb2YgcGFyYW1ldGVycyBkdXJpbmcgaXRlcmF0aW9uLgogICAgICAgIGNsYXNzIFg6CiAgICAgICAgICAgIGRlZiBfX2NvbmZvcm1fXyhzZWxmLCBwcm90b2NvbCk6CiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLmNsZWFyKCkKICAgICAgICAgICAgICAgIHJldHVybiAiLi4uIgogICAgICAgIHBhcmFtZXRlcnMgPSBbWCgpLCAwXQogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9ERUNMVFlQRVMpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIFgsIGJheiBpbnRlZ2VyKSIpCiAgICAgICAgIyBTaG91bGQgbm90IGNyYXNoCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhJbmRleEVycm9yKToKICAgICAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIsIGJheikgdmFsdWVzICg/LCA/KSIsIHBhcmFtZXRlcnMpCgogICAgZGVmIENoZWNrRXJyb3JNc2dEZWNvZGVFcnJvcihzZWxmKToKICAgICAgICAjIFdoZW4gcG9ydGluZyB0aGUgbW9kdWxlIHRvIFB5dGhvbiAzLjAsIHRoZSBlcnJvciBtZXNzYWdlIGFib3V0CiAgICAgICAgIyBkZWNvZGluZyBlcnJvcnMgZGlzYXBwZWFyZWQuIFRoaXMgdmVyaWZpZXMgdGhleSdyZSBiYWNrIGFnYWluLgogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IpIGFzIGNtOgogICAgICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgJ3h4eCcgfHwgPyB8fCAneXl5JyBjb2xuYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZXMoYnl0ZWFycmF5KFsyNTBdKSksKSkuZmV0Y2hvbmUoKQogICAgICAgIG1zZyA9ICJDb3VsZCBub3QgZGVjb2RlIHRvIFVURi04IGNvbHVtbiAnY29sbmFtZScgd2l0aCB0ZXh0ICd4eHgiCiAgICAgICAgc2VsZi5hc3NlcnRJbihtc2csIHN0cihjbS5leGNlcHRpb24pKQoKICAgIGRlZiBDaGVja1JlZ2lzdGVyQWRhcHRlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNxbGl0ZS5yZWdpc3Rlcl9hZGFwdGVyLCB7fSwgTm9uZSkKCiAgICBkZWYgQ2hlY2tTZXRJc29sYXRpb25MZXZlbChzZWxmKToKICAgICAgICAjIFNlZSBpc3N1ZSAyNzg4MS4KICAgICAgICBjbGFzcyBDdXN0b21TdHIoc3RyKToKICAgICAgICAgICAgZGVmIHVwcGVyKHNlbGYpOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gIiIKCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gTm9uZQogICAgICAgIGZvciBsZXZlbCBpbiAiIiwgIkRFRkVSUkVEIiwgIklNTUVESUFURSIsICJFWENMVVNJVkUiOgogICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChsZXZlbD1sZXZlbCk6CiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gbGV2ZWwKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbC5sb3dlcigpCiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gbGV2ZWwuY2FwaXRhbGl6ZSgpCiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gQ3VzdG9tU3RyKGxldmVsKQoKICAgICAgICAjIHNldHRpbmcgaXNvbGF0aW9uX2xldmVsIGZhaWx1cmUgc2hvdWxkIG5vdCBhbHRlciBwcmV2aW91cyBzdGF0ZQogICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBOb25lCiAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9ICJERUZFUlJFRCIKICAgICAgICBwYWlycyA9IFsKICAgICAgICAgICAgKDEsIFR5cGVFcnJvciksIChiJycsIFR5cGVFcnJvciksICgiYWJjIiwgVmFsdWVFcnJvciksCiAgICAgICAgICAgICgiSU1NRURJQVRFXDBFWENMVVNJVkUiLCBWYWx1ZUVycm9yKSwgKCJceGU5IiwgVmFsdWVFcnJvciksCiAgICAgICAgXQogICAgICAgIGZvciB2YWx1ZSwgZXhjIGluIHBhaXJzOgogICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChsZXZlbD12YWx1ZSk6CiAgICAgICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKGV4Yyk6CiAgICAgICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IHZhbHVlCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvbi5pc29sYXRpb25fbGV2ZWwsICJERUZFUlJFRCIpCgogICAgZGVmIENoZWNrQ3Vyc29yQ29uc3RydWN0b3JDYWxsQ2hlY2soc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjdXJzb3IgbWV0aG9kcyBjaGVjayB3aGV0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzCiAgICAgICAgY2FsbGVkLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIEN1cnNvcihzcWxpdGUuQ3Vyc29yKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbik6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gQ3Vyc29yKGNvbikKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yKToKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCA0KzUiKS5mZXRjaGFsbCgpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4KHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ15CYXNlIEN1cnNvclwuX19pbml0X18gbm90IGNhbGxlZFwuJCcpOgogICAgICAgICAgICBjdXIuY2xvc2UoKQoKICAgIGRlZiBDaGVja1N0clN1YmNsYXNzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRoZSBQeXRob24gMy4wIHBvcnQgb2YgdGhlIG1vZHVsZSBkaWRuJ3QgY29wZSB3aXRoIHZhbHVlcyBvZiBzdWJjbGFzc2VzIG9mIHN0ci4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBNeVN0cihzdHIpOiBwYXNzCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgic2VsZWN0ID8iLCAoTXlTdHIoImFiYyIpLCkpCgogICAgZGVmIENoZWNrQ29ubmVjdGlvbkNvbnN0cnVjdG9yQ2FsbENoZWNrKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgY29ubmVjdGlvbiBtZXRob2RzIGNoZWNrIHdoZXRoZXIgYmFzZSBjbGFzcyBfX2luaXRfXyB3YXMKICAgICAgICBjYWxsZWQuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ29ubmVjdGlvbihzcWxpdGUuQ29ubmVjdGlvbik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lKToKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgY29uID0gQ29ubmVjdGlvbigiOm1lbW9yeToiKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKCiAgICBkZWYgQ2hlY2tDdXJzb3JSZWdpc3RyYXRpb24oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBzdWJjbGFzc2VkIGN1cnNvciBjbGFzc2VzIGFyZSBjb3JyZWN0bHkgcmVnaXN0ZXJlZCB3aXRoCiAgICAgICAgdGhlIGNvbm5lY3Rpb24gb2JqZWN0LCB0b28uICAoZmV0Y2gtYWNyb3NzLXJvbGxiYWNrIHByb2JsZW0pCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ29ubmVjdGlvbihzcWxpdGUuQ29ubmVjdGlvbik6CiAgICAgICAgICAgIGRlZiBjdXJzb3Ioc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gQ3Vyc29yKHNlbGYpCgogICAgICAgIGNsYXNzIEN1cnNvcihzcWxpdGUuQ3Vyc29yKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbik6CiAgICAgICAgICAgICAgICBzcWxpdGUuQ3Vyc29yLl9faW5pdF9fKHNlbGYsIGNvbikKCiAgICAgICAgY29uID0gQ29ubmVjdGlvbigiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgpIikKICAgICAgICBjdXIuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKD8pIiwgWygzLCksICg0LCksICg1LCldKQogICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgeCBmcm9tIGZvbyIpCiAgICAgICAgY29uLnJvbGxiYWNrKCkKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5JbnRlcmZhY2VFcnJvcik6CiAgICAgICAgICAgIGN1ci5mZXRjaGFsbCgpCgogICAgZGVmIENoZWNrQXV0b0NvbW1pdChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGNyZWF0aW5nIGEgY29ubmVjdGlvbiBpbiBhdXRvY29tbWl0IG1vZGUgd29ya3MuCiAgICAgICAgMi41LjMgaW50cm9kdWNlZCBhIHJlZ3Jlc3Npb24gc28gdGhhdCB0aGVzZSBjb3VsZCBubyBsb25nZXIKICAgICAgICBiZSBjcmVhdGVkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGlzb2xhdGlvbl9sZXZlbD1Ob25lKQoKICAgIGRlZiBDaGVja1ByYWdtYUF1dG9jb21taXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBydW5uaW5nIGEgUFJBR01BIHN0YXRlbWVudCB0aGF0IGRvZXMgYW4gYXV0b2NvbW1pdCBkb2VzCiAgICAgICAgd29yay4gVGhpcyBkaWQgbm90IHdvcmsgaW4gMi41LjMvMi41LjQuCiAgICAgICAgIiIiCiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCgogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgcGFnZV9zaXplIikKICAgICAgICByb3cgPSBjdXIuZmV0Y2hvbmUoKQoKICAgIGRlZiBDaGVja0Nvbm5lY3Rpb25DYWxsKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENhbGwgYSBjb25uZWN0aW9uIHdpdGggYSBub24tc3RyaW5nIFNRTCByZXF1ZXN0OiBjaGVjayBlcnJvciBoYW5kbGluZwogICAgICAgIG9mIHRoZSBzdGF0ZW1lbnQgY29uc3RydWN0b3IuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbiwgMSkKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb24oc2VsZik6CiAgICAgICAgZGVmIGNvbGxhdGlvbl9jYihhLCBiKToKICAgICAgICAgICAgcmV0dXJuIDEKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvciwgc2VsZi5jb24uY3JlYXRlX2NvbGxhdGlvbiwKICAgICAgICAgICAgIyBMb25lIHN1cnJvZ2F0ZSBjYW5ub3QgYmUgZW5jb2RlZCB0byB0aGUgZGVmYXVsdCBlbmNvZGluZyAodXRmOCkKICAgICAgICAgICAgIlx1REM4MCIsIGNvbGxhdGlvbl9jYikKCiAgICBkZWYgQ2hlY2tSZWN1cnNpdmVDdXJzb3JVc2Uoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgaHR0cDovL2J1Z3MucHl0aG9uLm9yZy9pc3N1ZTEwODExCgogICAgICAgIFJlY3Vyc2l2ZWx5IHVzaW5nIGEgY3Vyc29yLCBzdWNoIGFzIHdoZW4gcmV1c2luZyBpdCBmcm9tIGEgZ2VuZXJhdG9yIGxlZCB0byBzZWdmYXVsdHMuCiAgICAgICAgTm93IHdlIGNhdGNoIHJlY3Vyc2l2ZSBjdXJzb3IgdXNhZ2UgYW5kIHJhaXNlIGEgUHJvZ3JhbW1pbmdFcnJvci4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQoKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGEgKGJhcikiKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgYiAoYmF6KSIpCgogICAgICAgIGRlZiBmb28oKToKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoImluc2VydCBpbnRvIGEgKGJhcikgdmFsdWVzICg/KSIsICgxLCkpCiAgICAgICAgICAgIHlpZWxkIDEKCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcik6CiAgICAgICAgICAgIGN1ci5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gYiAoYmF6KSB2YWx1ZXMgKD8pIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoaSwpIGZvciBpIGluIGZvbygpKSkKCiAgICBkZWYgQ2hlY2tDb252ZXJ0VGltZXN0YW1wTWljcm9zZWNvbmRQYWRkaW5nKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWUxNDcyMAoKICAgICAgICBUaGUgbWljcm9zZWNvbmQgcGFyc2luZyBvZiBjb252ZXJ0X3RpbWVzdGFtcCgpIHNob3VsZCBwYWQgd2l0aCB6ZXJvcywKICAgICAgICBzaW5jZSB0aGUgbWljcm9zZWNvbmQgc3RyaW5nICI0NTYiIGFjdHVhbGx5IHJlcHJlc2VudHMgIjQ1NjAwMCIuCiAgICAgICAgIiIiCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfREVDTFRZUEVTKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJDUkVBVEUgVEFCTEUgdCAoeCBUSU1FU1RBTVApIikKCiAgICAgICAgIyBNaWNyb3NlY29uZHMgc2hvdWxkIGJlIDQ1NjAwMAogICAgICAgIGN1ci5leGVjdXRlKCJJTlNFUlQgSU5UTyB0ICh4KSBWQUxVRVMgKCcyMDEyLTA0LTA0IDE1OjA2OjAwLjQ1NicpIikKCiAgICAgICAgIyBNaWNyb3NlY29uZHMgc2hvdWxkIGJlIHRydW5jYXRlZCB0byAxMjM0NTYKICAgICAgICBjdXIuZXhlY3V0ZSgiSU5TRVJUIElOVE8gdCAoeCkgVkFMVUVTICgnMjAxMi0wNC0wNCAxNTowNjowMC4xMjM0NTY3ODknKSIpCgogICAgICAgIGN1ci5leGVjdXRlKCJTRUxFQ1QgKiBGUk9NIHQiKQogICAgICAgIHZhbHVlcyA9IFt4WzBdIGZvciB4IGluIGN1ci5mZXRjaGFsbCgpXQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHZhbHVlcywgWwogICAgICAgICAgICBkYXRldGltZS5kYXRldGltZSgyMDEyLCA0LCA0LCAxNSwgNiwgMCwgNDU2MDAwKSwKICAgICAgICAgICAgZGF0ZXRpbWUuZGF0ZXRpbWUoMjAxMiwgNCwgNCwgMTUsIDYsIDAsIDEyMzQ1NiksCiAgICAgICAgXSkKCiAgICBkZWYgQ2hlY2tJbnZhbGlkSXNvbGF0aW9uTGV2ZWxUeXBlKHNlbGYpOgogICAgICAgICMgaXNvbGF0aW9uIGxldmVsIGlzIGEgc3RyaW5nLCBub3QgYW4gaW50ZWdlcgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICBzcWxpdGUuY29ubmVjdCwgIjptZW1vcnk6IiwgaXNvbGF0aW9uX2xldmVsPTEyMykKCgogICAgZGVmIENoZWNrTnVsbENoYXJhY3RlcihzZWxmKToKICAgICAgICAjIElzc3VlICMyMTE0NwogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY29uLCAiXDBzZWxlY3QgMSIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY29uLCAic2VsZWN0IDFcMCIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY3VyLmV4ZWN1dGUsICIgXDBzZWxlY3QgMiIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgY3VyLmV4ZWN1dGUsICJzZWxlY3QgMlwwIikKCiAgICBkZWYgQ2hlY2tDb21taXRDdXJzb3JSZXNldChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBDb25uZWN0aW9uLmNvbW1pdCgpIGRpZCByZXNldCBjdXJzb3JzLCB3aGljaCBtYWRlIHNxbGl0ZTMKICAgICAgICB0byByZXR1cm4gcm93cyBtdWx0aXBsZSB0aW1lcyB3aGVuIGZldGNoZWQgZnJvbSBjdXJzb3JzCiAgICAgICAgYWZ0ZXIgY29tbWl0LiBTZWUgaXNzdWVzIDEwNTEzIGFuZCAyMzEyOSBmb3IgZGV0YWlscy4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5leGVjdXRlc2NyaXB0KCIiIgogICAgICAgIGNyZWF0ZSB0YWJsZSB0KGMpOwogICAgICAgIGNyZWF0ZSB0YWJsZSB0MihjKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygwKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygxKTsKICAgICAgICBpbnNlcnQgaW50byB0IHZhbHVlcygyKTsKICAgICAgICAiIiIpCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY29uLmlzb2xhdGlvbl9sZXZlbCwgIiIpCgogICAgICAgIGNvdW50ZXIgPSAwCiAgICAgICAgZm9yIGksIHJvdyBpbiBlbnVtZXJhdGUoY29uLmV4ZWN1dGUoInNlbGVjdCBjIGZyb20gdCIpKToKICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QoaT1pLCByb3c9cm93KToKICAgICAgICAgICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byB0MihjKSB2YWx1ZXMgKD8pIiwgKGksKSkKICAgICAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgICAgICAgICAgaWYgY291bnRlciA9PSAwOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocm93WzBdLCAwKQogICAgICAgICAgICAgICAgZWxpZiBjb3VudGVyID09IDE6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sIDEpCiAgICAgICAgICAgICAgICBlbGlmIGNvdW50ZXIgPT0gMjoKICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgMikKICAgICAgICAgICAgICAgIGNvdW50ZXIgKz0gMQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY291bnRlciwgMywgInNob3VsZCBoYXZlIHJldHVybmVkIGV4YWN0bHkgdGhyZWUgcm93cyIpCgogICAgZGVmIENoZWNrQnBvMzE3NzAoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGhlIGludGVycHJldGVyIHNob3VsZG4ndCBjcmFzaCBpbiBjYXNlIEN1cnNvci5fX2luaXRfXygpIGlzIGNhbGxlZAogICAgICAgIG1vcmUgdGhhbiBvbmNlLgogICAgICAgICIiIgogICAgICAgIGRlZiBjYWxsYmFjaygqYXJncyk6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IHNxbGl0ZS5DdXJzb3IoY29uKQogICAgICAgIHJlZiA9IHdlYWtyZWYucmVmKGN1ciwgY2FsbGJhY2spCiAgICAgICAgY3VyLl9faW5pdF9fKGNvbikKICAgICAgICBkZWwgY3VyCiAgICAgICAgIyBUaGUgaW50ZXJwcmV0ZXIgc2hvdWxkbid0IGNyYXNoIHdoZW4gcmVmIGlzIGNvbGxlY3RlZC4KICAgICAgICBkZWwgcmVmCiAgICAgICAgc3VwcG9ydC5nY19jb2xsZWN0KCkKCiAgICBkZWYgQ2hlY2tEZWxJc29sYXRpb25fbGV2ZWxTZWdmYXVsdChzZWxmKToKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKEF0dHJpYnV0ZUVycm9yKToKICAgICAgICAgICAgZGVsIHNlbGYuY29uLmlzb2xhdGlvbl9sZXZlbAoKICAgIGRlZiBDaGVja0JwbzM3MzQ3KHNlbGYpOgogICAgICAgIGNsYXNzIFByaW50ZXI6CiAgICAgICAgICAgIGRlZiBsb2coc2VsZiwgKmFyZ3MpOgogICAgICAgICAgICAgICAgcmV0dXJuIHNxbGl0ZS5TUUxJVEVfT0sKCiAgICAgICAgZm9yIG1ldGhvZCBpbiBbc2VsZi5jb24uc2V0X3RyYWNlX2NhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0b29scy5wYXJ0aWFsKHNlbGYuY29uLnNldF9wcm9ncmVzc19oYW5kbGVyLCBuPTEpLAogICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY29uLnNldF9hdXRob3JpemVyXToKICAgICAgICAgICAgcHJpbnRlcl9pbnN0YW5jZSA9IFByaW50ZXIoKQogICAgICAgICAgICBtZXRob2QocHJpbnRlcl9pbnN0YW5jZS5sb2cpCiAgICAgICAgICAgIG1ldGhvZChwcmludGVyX2luc3RhbmNlLmxvZykKICAgICAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgic2VsZWN0IDEiKSAgIyB0cmlnZ2VyIHNlZyBmYXVsdAogICAgICAgICAgICBtZXRob2QoTm9uZSkKCgoKZGVmIHN1aXRlKCk6CiAgICByZWdyZXNzaW9uX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFJlZ3Jlc3Npb25UZXN0cywgIkNoZWNrIikKICAgIHJldHVybiB1bml0dGVzdC5UZXN0U3VpdGUoKAogICAgICAgIHJlZ3Jlc3Npb25fc3VpdGUsCiAgICApKQoKZGVmIHRlc3QoKToKICAgIHJ1bm5lciA9IHVuaXR0ZXN0LlRleHRUZXN0UnVubmVyKCkKICAgIHJ1bm5lci5ydW4oc3VpdGUoKSkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0KCkK