Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMDcgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHhyYW5nZSg1KV0KICAgICAgICBjdXJzb3JzWzBdLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KHgpIikKICAgICAgICBmb3IgaSBpbiByYW5nZSgxMCk6CiAgICAgICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIHRlc3QoeCkgdmFsdWVzICg/KSIsIFsoeCwpIGZvciB4IGluIHhyYW5nZSgxMCldKQoKICAgICAgICBmb3IgaSBpbiByYW5nZSg1KToKICAgICAgICAgICAgY3Vyc29yc1tpXS5leGVjdXRlKCIgIiAqIGkgKyAic2VsZWN0IHggZnJvbSB0ZXN0IikKCiAgICAgICAgY29uLnJvbGxiYWNrKCkKCiAgICBkZWYgQ2hlY2tDb2x1bW5OYW1lV2l0aFNwYWNlcyhzZWxmKToKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCdzZWxlY3QgMSBhcyAiZm9vIGJhciBbZGF0ZXRpbWVdIicpCiAgICAgICAgc2VsZi5mYWlsVW5sZXNzRXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciIpCgogICAgICAgIGN1ci5leGVjdXRlKCdzZWxlY3QgMSBhcyAiZm9vIGJheiInKQogICAgICAgIHNlbGYuZmFpbFVubGVzc0VxdWFsKGN1ci5kZXNjcmlwdGlvblswXVswXSwgImZvbyBiYXoiKQoKICAgIGRlZiBDaGVja1N0YXRlbWVudEF2YWlsYWJsZShzZWxmKToKICAgICAgICAjIHB5c3FsaXRlIHVwIHRvIDIuMy4yIGNyYXNoZWQgb24gdGhpcywgYmVjYXVzZSB0aGUgYWN0aXZlIHN0YXRlbWVudCBoYW5kbGUgd2FzIG5vdCBjaGVja2VkCiAgICAgICAgIyBiZWZvcmUgdHJ5aW5nIHRvIGZldGNoIGRhdGEgZnJvbSBpdC4gY2xvc2UoKSBkZXN0cm95cyB0aGUgYWN0aXZlIHN0YXRlbWVudCAuLi4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDQgdW5pb24gc2VsZWN0IDUiKQogICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgY3VyLmZldGNob25lKCkKICAgICAgICBjdXIuZmV0Y2hvbmUoKQoKICAgIGRlZiBDaGVja1N0YXRlbWVudEZpbmFsaXphdGlvbk9uQ2xvc2VEYihzZWxmKToKICAgICAgICAjIHB5c3FsaXRlIHZlcnNpb25zIDw9IDIuMy4zIG9ubHkgZmluYWxpemVkIHN0YXRlbWVudHMgaW4gdGhlIHN0YXRlbWVudAogICAgICAgICMgY2FjaGUgd2hlbiBjbG9zaW5nIHRoZSBkYXRhYmFzZS4gc3RhdGVtZW50cyB0aGF0IHdlcmUgc3RpbGwKICAgICAgICAjIHJlZmVyZW5jZWQgaW4gY3Vyc29ycyB3ZXJlbid0IGNsb3NlZCBhbiBjb3VsZCBwcm92b2tlICIKICAgICAgICAjICJPcGVyYXRpb25hbEVycm9yOiBVbmFibGUgdG8gY2xvc2UgZHVlIHRvIHVuZmluYWxpc2VkIHN0YXRlbWVudHMiLgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3Vyc29ycyA9IFtdCiAgICAgICAgIyBkZWZhdWx0IHN0YXRlbWVudCBjYWNoZSBzaXplIGlzIDEwMAogICAgICAgIGZvciBpIGluIHJhbmdlKDEwNSk6CiAgICAgICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgICAgICBjdXJzb3JzLmFwcGVuZChjdXIpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgMSB4IHVuaW9uIHNlbGVjdCAiICsgc3RyKGkpKQogICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrT25Db25mbGljdFJvbGxiYWNrKHNlbGYpOgogICAgICAgIGlmIHNxbGl0ZS5zcWxpdGVfdmVyc2lvbl9pbmZvIDwgKDMsIDIsIDIpOgogICAgICAgICAgICByZXR1cm4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgsIHVuaXF1ZSh4KSBvbiBjb25mbGljdCByb2xsYmFjaykiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMSkiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuRGF0YWJhc2VFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgyKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uY29tbWl0KCkKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHNlbGYuZmFpbCgicHlzcWxpdGUga25ldyBub3RoaW5nIGFib3V0IHRoZSBpbXBsaWNpdCBST0xMQkFDSyIpCgogICAgZGVmIENoZWNrV29ya2Fyb3VuZEZvckJ1Z2d5U3FsaXRlVHJhbnNmZXJCaW5kaW5ncyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB3b3VsZCBjcmFzaCB3aXRoIG9sZGVyIFNRTGl0ZSB2ZXJzaW9ucyB1bmxlc3MKICAgICAgICBhIHdvcmthcm91bmQgaXMgaW1wbGVtZW50ZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKCiAgICBkZWYgQ2hlY2tFbXB0eVN0YXRlbWVudChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1c2VkIHRvIHNlZ2ZhdWx0IHdpdGggU1FMaXRlIHZlcnNpb25zIDMuNS54LiBUaGVzZSByZXR1cm4gTlVMTAogICAgICAgIGZvciAibm8tb3BlcmF0aW9uIiBzdGF0ZW1lbnRzCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiIikKCiAgICBkZWYgQ2hlY2tVbmljb2RlQ29ubmVjdChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBXaXRoIHB5c3FsaXRlIDIuNC4wIHlvdSBuZWVkZWQgdG8gdXNlIGEgc3RyaW5nIG9yIGEgQVBTVyBjb25uZWN0aW9uCiAgICAgICAgb2JqZWN0IGZvciBvcGVuaW5nIGRhdGFiYXNlIGNvbm5lY3Rpb25zLgoKICAgICAgICBGb3JtZXJseSwgYm90aCBieXRlc3RyaW5ncyBhbmQgdW5pY29kZSBzdHJpbmdzIHVzZWQgdG8gd29yay4KCiAgICAgICAgTGV0J3MgbWFrZSBzdXJlIHVuaWNvZGUgc3RyaW5ncyB3b3JrIGluIHRoZSBmdXR1cmUuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QodSI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tUeXBlTWFwVXNhZ2Uoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgdW50aWwgMi40LjEgZGlkIG5vdCByZWJ1aWxkIHRoZSByb3dfY2FzdF9tYXAgd2hlbiByZWNvbXBpbGluZwogICAgICAgIGEgc3RhdGVtZW50LiBUaGlzIHRlc3QgZXhoaWJpdHMgdGhlIHByb2JsZW0uCiAgICAgICAgIiIiCiAgICAgICAgU0VMRUNUID0gInNlbGVjdCAqIGZyb20gZm9vIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9ERUNMVFlQRVMpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIHRpbWVzdGFtcCkiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKD8pIiwgKGRhdGV0aW1lLmRhdGV0aW1lLm5vdygpLCkpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQogICAgICAgIGNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIGludGVnZXIpIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQoKICAgIGRlZiBDaGVja1JlZ2lzdGVyQWRhcHRlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNxbGl0ZS5yZWdpc3Rlcl9hZGFwdGVyLCB7fSwgTm9uZSkKCiAgICBkZWYgQ2hlY2tTZXRJc29sYXRpb25MZXZlbChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFVuaWNvZGVFbmNvZGVFcnJvciwgc2V0YXR0ciwgY29uLAogICAgICAgICAgICAgICAgICAgICAgICAgICJpc29sYXRpb25fbGV2ZWwiLCB1Ilx4ZTkiKQoKCmRlZiBzdWl0ZSgpOgogICAgcmVncmVzc2lvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShSZWdyZXNzaW9uVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChyZWdyZXNzaW9uX3N1aXRlLCkpCgpkZWYgdGVzdCgpOgogICAgcnVubmVyID0gdW5pdHRlc3QuVGV4dFRlc3RSdW5uZXIoKQogICAgcnVubmVyLnJ1bihzdWl0ZSgpKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHRlc3QoKQo=