UNPKG

antfarm

Version:

File automation framework for ants.

228 lines (226 loc) 28.2 kB
"use strict"; var webhookJob_1 = require("../job/webhookJob"); var express = require("express"); var cors = require("cors"), multer = require("multer"), path = require("path"), tmp = require("tmp"), async = require("async"); /** * Webhook and logging server. */ var Server = (function () { function Server(e) { this.hookRoutes = []; this.hookInterfaceRoutes = []; this.config = { hooks_prefix: "/hooks", hooks_ui_prefix: "/hooks-ui", log_prefix: "/log" }; /** * Handles request and response of the web hook interface. * @param im {InterfaceManager} * @param req {express.Request} * @param res {express.Response} * @param customHandler Custom request handler. */ this.handleHookInterfaceRequest = function (im, req, res, customHandler) { var s = this; // Job arrive var job = new webhookJob_1.WebhookJob(s.e, req, res); // Fill in default values var params = job.getQueryStringValues(); // If session not set, return a fresh ui somehow var sessionId = params["sessionId"] || job.getFormDataValue("sessionId"); var ui = im.getInterface(sessionId); if (ui.sessionId === sessionId) { // Fill in default values ui.fields.forEach(function (field) { if (field.id in params && params[field.id] !== "undefined") { field.value = params[field.id]; } }); // Do steps async.each(ui.steps, function (step, cb) { s.e.log(0, "Running UI step \"" + step.name + "\".", s); step.callback(job, ui, step, function () { cb(); }); }, function (err) { if (err) { s.e.log(3, "Error running UI steps. " + err, s); } else { s.e.log(0, "Done running all UI steps.", s); } if (customHandler) { customHandler(req, res, ui); } else { res.json(ui.getTransportInterface()); } }); } else { if (customHandler) { customHandler(req, res, ui); } else { res.json(ui.getTransportInterface()); } } }; var s = this; s.e = e; s.server = express(); s.createServer(); // let tmpDir = tmp.dirSync()._name; var tmpDir = "./example"; s.upload = multer({ destination: tmpDir, storage: multer.diskStorage({ filename: function (req, file, cb) { cb(null, file.fieldname + "-" + Date.now()); } }) }); } /** * Creates the server. */ Server.prototype.createServer = function () { var s = this; var port = s.e.options.port; s.server.use(cors()); // Add index routes s.server.get(s.config.hooks_prefix, function (req, res) { res.json(s.hookRoutes); }); s.server.get(s.config.hooks_ui_prefix, function (req, res) { res.json(s.hookInterfaceRoutes); }); // Prevent duplicate listening for tests // if (!module.parent) { // s.server.listen(port, () => s.e.log(1, `Server up and listening on port ${port}.`, s)); // } s.server.listen(port, function () { return s.e.log(1, "Server up and listening on port " + port + ".", s); }) .on("error", function (err) { s.e.log(3, "Server listen error: \"" + err.message + "\".", s); }); }; Server.prototype.createLogServer = function (logger) { var s = this; var options = { order: "desc", fields: ["message"] }; // Add index routes s.server.get(s.config.log_prefix, function (req, res) { logger.query(options, function (results) { res.json(results); }); }); }; /** * Log _name * @returns {string} */ Server.prototype.toString = function () { return "Server"; }; /** * Adds a webhook to the server. * @param nest {WebhookNest} */ Server.prototype.addWebhook = function (nest) { var s = this; var e = s.e; var httpMethod = nest.httpMethod; var hook_path = s.config.hooks_prefix + nest.path; var hook_ui_path; var im = nest.interfaceManager; var wi = im.getInterface(); hook_ui_path = s.config.hooks_ui_prefix + im.path; s.e.log(1, "Watching webhook " + httpMethod.toUpperCase() + " " + hook_path, s); s.hookRoutes.push({ id: nest.id, path: hook_path, nest: nest.name, tunnel: nest.tunnel.name, method: httpMethod, interface_path: hook_ui_path }); s.server[httpMethod](hook_path, s.upload.any(), function (req, res) { var customHandler = nest.customHandleRequest; s.handleHookRequest(nest, req, res, customHandler); }); }; /** * Handles request and response of the web hook, creates a new job, as well as calling the nest's arrive. * @param nest {WebhookNest} * @param req {express.Request} * @param res {express.Response} * @param customHandler Custom request handler. */ Server.prototype.handleHookRequest = function (nest, req, res, customHandler) { var s = this; // Job arrive var job = new webhookJob_1.WebhookJob(s.e, req, res); nest.arrive(job); s.sendHookResponse(nest.holdResponse, job, nest, req, res, customHandler); }; ; /** * Sends the actual hook response. * @param holdResponse Flag to bypass sending now for held responses. * @param job Webhook job * @param nest Webhook nest * @param req * @param res * @param customHandler * @param message */ Server.prototype.sendHookResponse = function (holdResponse, job, nest, req, res, customHandler, message) { if (holdResponse === true) { } else if (customHandler) { job.responseSent = true; customHandler(req, res, job, nest); } else { job.responseSent = true; var response = { message: message || "Job " + job.id + " was created!", job: { id: job.id, name: job.name }, nest: { name: nest.name } }; res.json(response); } }; /** * Adds a webhook interface to the webhook server. * @param im {InterfaceManager} */ Server.prototype.addWebhookInterface = function (im) { var s = this; var nest = im.nest; var hook_path = s.config.hooks_prefix + nest.path; var hook_ui_path = s.config.hooks_ui_prefix + im.path; s.e.log(1, "Watching webhook interface GET " + hook_ui_path, s); this.hookInterfaceRoutes.push({ id: nest.id, path: hook_ui_path, nest: nest.name, target: hook_path }); s.server.get(hook_ui_path, function (req, res) { var customHandler = im.customHandleRequest; s.handleHookInterfaceRequest(im, req, res, customHandler); }); }; return Server; }()); exports.Server = Server; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9lbnZpcm9ubWVudC9zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUVBLDJCQUF5QixtQkFBbUIsQ0FBQyxDQUFBO0FBQzdDLElBQVksT0FBTyxXQUFNLFNBQVMsQ0FBQyxDQUFBO0FBSW5DLElBQVEsSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFDdEIsTUFBTSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFDMUIsSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFDdEIsR0FBRyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFDcEIsS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUVqQzs7R0FFRztBQUNIO0lBY0ksZ0JBQVksQ0FBYztRQVZoQixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLHdCQUFtQixHQUFHLEVBQUUsQ0FBQztRQUd6QixXQUFNLEdBQUc7WUFDZixZQUFZLEVBQUUsUUFBUTtZQUN0QixlQUFlLEVBQUUsV0FBVztZQUM1QixVQUFVLEVBQUUsTUFBTTtTQUNyQixDQUFDO1FBK0xGOzs7Ozs7V0FNRztRQUNPLCtCQUEwQixHQUFHLFVBQVMsRUFBb0IsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLGFBQW1CO1lBQy9GLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQztZQUViLGFBQWE7WUFDYixJQUFJLEdBQUcsR0FBRyxJQUFJLHVCQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFeEMseUJBQXlCO1lBQ3pCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBRXhDLGdEQUFnRDtZQUNoRCxJQUFJLFNBQVMsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRXpFLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENB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RUFBRSxDQUFDLENBQUMsQ0FBQztRQUVoRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDO1lBQzFCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUNYLElBQUksRUFBRSxZQUFZO1lBQ2xCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLE1BQU0sRUFBRSxTQUFTO1NBRXBCLENBQUMsQ0FBQztRQUVILENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRyxVQUFVLEdBQUcsRUFBRSxHQUFHO1lBRTFDLElBQUksYUFBYSxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztZQUUzQyxDQUFDLENBQUMsMEJBQTBCLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBNERMLGFBQUM7QUFBRCxDQXJRQSxBQXFRQyxJQUFBO0FBclFZLGNBQU0sU0FxUWxCLENBQUEiLCJmaWxlIjoibGliL2Vudmlyb25tZW50L3NlcnZlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RW52aXJvbm1lbnR9IGZyb20gXCIuL2Vudmlyb25tZW50XCI7XG5pbXBvcnQge1dlYmhvb2tOZXN0fSBmcm9tIFwiLi4vbmVzdC93ZWJob29rTmVzdFwiO1xuaW1wb3J0IHtXZWJob29rSm9ifSBmcm9tIFwiLi4vam9iL3dlYmhvb2tKb2JcIjtcbmltcG9ydCAqIGFzIGV4cHJlc3MgZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7SW50ZXJmYWNlTWFuYWdlcn0gZnJvbSBcIi4uL3VpL2ludGVyZmFjZU1hbmFnZXJcIjtcbmltcG9ydCB7TG9nZ2VyLCBMb2dRdWVyeU9wdGlvbnN9IGZyb20gXCIuL2xvZ2dlclwiO1xuXG5jb25zdCAgIGNvcnMgPSByZXF1aXJlKFwiY29yc1wiKSxcbiAgICAgICAgbXVsdGVyID0gcmVxdWlyZShcIm11bHRlclwiKSxcbiAgICAgICAgcGF0aCA9IHJlcXVpcmUoXCJwYXRoXCIpLFxuICAgICAgICB0bXAgPSByZXF1aXJlKFwidG1wXCIpLFxuICAgICAgICBhc3luYyA9IHJlcXVpcmUoXCJhc3luY1wiKTtcblxuLyoqXG4gKiBXZWJob29rIGFuZCBsb2dnaW5nIHNlcnZlci5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlcnZlciB7XG5cbiAgICBwcm90ZWN0ZWQgc2VydmVyOiBleHByZXNzLkFwcGxpY2F0aW9uO1xuICAgIHByb3RlY3RlZCBlOiBFbnZpcm9ubWVudDtcbiAgICBwcm90ZWN0ZWQgaG9va1JvdXRlcyA9IFtdO1xuICAgIHByb3RlY3RlZCBob29rSW50ZXJmYWNlUm91dGVzID0gW107XG4gICAgcHJvdGVjdGVkIHVwbG9hZDtcblxuICAgIHByb3RlY3RlZCBjb25maWcgPSB7XG4gICAgICAgIGhvb2tzX3ByZWZpeDogXCIvaG9va3NcIixcbiAgICAgICAgaG9va3NfdWlfcHJlZml4OiBcIi9ob29rcy11aVwiLFxuICAgICAgICBsb2dfcHJlZml4OiBcIi9sb2dcIlxuICAgIH07XG5cbiAgICBjb25zdHJ1Y3RvcihlOiBFbnZpcm9ubWVudCkge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG4gICAgICAgIHMuZSA9IGU7XG4gICAgICAgIHMuc2VydmVyID0gZXhwcmVzcygpO1xuXG4gICAgICAgIHMuY3JlYXRlU2VydmVyKCk7XG5cbiAgICAgICAgLy8gbGV0IHRtcERpciA9IHRtcC5kaXJTeW5jKCkuX25hbWU7XG4gICAgICAgIGxldCB0bXBEaXIgPSBcIi4vZXhhbXBsZVwiO1xuXG4gICAgICAgIHMudXBsb2FkID0gbXVsdGVyKHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbjogdG1wRGlyLFxuICAgICAgICAgICAgICAgIHN0b3JhZ2U6IG11bHRlci5kaXNrU3RvcmFnZSh7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBmdW5jdGlvbiAocmVxLCBmaWxlLCBjYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2IobnVsbCwgZmlsZS5maWVsZG5hbWUgKyBcIi1cIiArIERhdGUubm93KCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIHNlcnZlci5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlU2VydmVyKCkge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG5cbiAgICAgICAgbGV0IHBvcnQgPSBzLmUub3B0aW9ucy5wb3J0O1xuXG4gICAgICAgIHMuc2VydmVyLnVzZShjb3JzKCkpO1xuXG4gICAgICAgIC8vIEFkZCBpbmRleCByb3V0ZXNcbiAgICAgICAgcy5zZXJ2ZXIuZ2V0KHMuY29uZmlnLmhvb2tzX3ByZWZpeCwgZnVuY3Rpb24ocmVxLCByZXMpe1xuICAgICAgICAgICAgcmVzLmpzb24ocy5ob29rUm91dGVzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHMuc2VydmVyLmdldChzLmNvbmZpZy5ob29rc191aV9wcmVmaXgsIGZ1bmN0aW9uKHJlcSwgcmVzKXtcbiAgICAgICAgICAgIHJlcy5qc29uKHMuaG9va0ludGVyZmFjZVJvdXRlcyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFByZXZlbnQgZHVwbGljYXRlIGxpc3RlbmluZyBmb3IgdGVzdHNcbiAgICAgICAgLy8gaWYgKCFtb2R1bGUucGFyZW50KSB7XG4gICAgICAgIC8vICAgICBzLnNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4gcy5lLmxvZygxLCBgU2VydmVyIHVwIGFuZCBsaXN0ZW5pbmcgb24gcG9ydCAke3BvcnR9LmAsIHMpKTtcbiAgICAgICAgLy8gfVxuICAgICAgICBzLnNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4gcy5lLmxvZygxLCBgU2VydmVyIHVwIGFuZCBsaXN0ZW5pbmcgb24gcG9ydCAke3BvcnR9LmAsIHMpKVxuICAgICAgICAgICAgLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIHMuZS5sb2coMywgYFNlcnZlciBsaXN0ZW4gZXJyb3I6IFwiJHtlcnIubWVzc2FnZX1cIi5gLCBzKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZUxvZ1NlcnZlcihsb2dnZXI6IExvZ2dlcikge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG5cbiAgICAgICAgbGV0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBvcmRlcjogXCJkZXNjXCIsXG4gICAgICAgICAgICBmaWVsZHM6IFtcIm1lc3NhZ2VcIl1cbiAgICAgICAgfSBhcyBMb2dRdWVyeU9wdGlvbnM7XG5cbiAgICAgICAgLy8gQWRkIGluZGV4IHJvdXRlc1xuICAgICAgICBzLnNlcnZlci5nZXQocy5jb25maWcubG9nX3ByZWZpeCwgKHJlcSwgcmVzKSA9PiB7XG5cbiAgICAgICAgICAgIGxvZ2dlci5xdWVyeShvcHRpb25zLCByZXN1bHRzID0+IHtcbiAgICAgICAgICAgICAgICByZXMuanNvbihyZXN1bHRzKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvZyBfbmFtZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gXCJTZXJ2ZXJcIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgd2ViaG9vayB0byB0aGUgc2VydmVyLlxuICAgICAqIEBwYXJhbSBuZXN0IHtXZWJob29rTmVzdH1cbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkV2ViaG9vayhuZXN0OiBXZWJob29rTmVzdCkge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG4gICAgICAgIGxldCBlID0gcy5lO1xuXG4gICAgICAgIGxldCBodHRwTWV0aG9kID0gbmVzdC5odHRwTWV0aG9kO1xuICAgICAgICBsZXQgaG9va19wYXRoID0gcy5jb25maWcuaG9va3NfcHJlZml4ICsgbmVzdC5wYXRoO1xuICAgICAgICBsZXQgaG9va191aV9wYXRoO1xuICAgICAgICBsZXQgaW0gPSBuZXN0LmludGVyZmFjZU1hbmFnZXI7XG5cbiAgICAgICAgbGV0IHdpID0gaW0uZ2V0SW50ZXJmYWNlKCk7XG4gICAgICAgIGhvb2tfdWlfcGF0aCA9IHMuY29uZmlnLmhvb2tzX3VpX3ByZWZpeCArIGltLnBhdGg7XG5cbiAgICAgICAgcy5lLmxvZygxLCBgV2F0Y2hpbmcgd2ViaG9vayAke2h0dHBNZXRob2QudG9VcHBlckNhc2UoKX0gJHtob29rX3BhdGh9YCwgcyk7XG5cbiAgICAgICAgcy5ob29rUm91dGVzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IG5lc3QuaWQsXG4gICAgICAgICAgICBwYXRoOiBob29rX3BhdGgsXG4gICAgICAgICAgICBuZXN0OiBuZXN0Lm5hbWUsXG4gICAgICAgICAgICB0dW5uZWw6IG5lc3QudHVubmVsLm5hbWUsXG4gICAgICAgICAgICBtZXRob2Q6IGh0dHBNZXRob2QsXG4gICAgICAgICAgICBpbnRlcmZhY2VfcGF0aDogaG9va191aV9wYXRoXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHMuc2VydmVyW2h0dHBNZXRob2RdKGhvb2tfcGF0aCwgcy51cGxvYWQuYW55KCksIGZ1bmN0aW9uIChyZXEsIHJlcykge1xuXG4gICAgICAgICAgICBsZXQgY3VzdG9tSGFuZGxlciA9IG5lc3QuY3VzdG9tSGFuZGxlUmVxdWVzdDtcblxuICAgICAgICAgICAgIHMuaGFuZGxlSG9va1JlcXVlc3QobmVzdCwgcmVxLCByZXMsIGN1c3RvbUhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHJlcXVlc3QgYW5kIHJlc3BvbnNlIG9mIHRoZSB3ZWIgaG9vaywgY3JlYXRlcyBhIG5ldyBqb2IsIGFzIHdlbGwgYXMgY2FsbGluZyB0aGUgbmVzdCdzIGFycml2ZS5cbiAgICAgKiBAcGFyYW0gbmVzdCB7V2ViaG9va05lc3R9XG4gICAgICogQHBhcmFtIHJlcSB7ZXhwcmVzcy5SZXF1ZXN0fVxuICAgICAqIEBwYXJhbSByZXMge2V4cHJlc3MuUmVzcG9uc2V9XG4gICAgICogQHBhcmFtIGN1c3RvbUhhbmRsZXIgICAgIEN1c3RvbSByZXF1ZXN0IGhhbmRsZXIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGhhbmRsZUhvb2tSZXF1ZXN0IChuZXN0OiBXZWJob29rTmVzdCwgcmVxLCByZXMsIGN1c3RvbUhhbmRsZXI/OiBhbnkpIHtcbiAgICAgICAgbGV0IHMgPSB0aGlzO1xuXG4gICAgICAgIC8vIEpvYiBhcnJpdmVcbiAgICAgICAgbGV0IGpvYiA9IG5ldyBXZWJob29rSm9iKHMuZSwgcmVxLCByZXMpO1xuICAgICAgICBuZXN0LmFycml2ZShqb2IpO1xuXG4gICAgICAgIHMuc2VuZEhvb2tSZXNwb25zZShuZXN0LmhvbGRSZXNwb25zZSwgam9iLCBuZXN0LCByZXEsIHJlcywgY3VzdG9tSGFuZGxlcik7XG5cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2VuZHMgdGhlIGFjdHVhbCBob29rIHJlc3BvbnNlLlxuICAgICAqIEBwYXJhbSBob2xkUmVzcG9uc2UgICAgICBGbGFnIHRvIGJ5cGFzcyBzZW5kaW5nIG5vdyBmb3IgaGVsZCByZXNwb25zZXMuXG4gICAgICogQHBhcmFtIGpvYiAgICAgICAgICAgICAgIFdlYmhvb2sgam9iXG4gICAgICogQHBhcmFtIG5lc3QgICAgICAgICAgICAgIFdlYmhvb2sgbmVzdFxuICAgICAqIEBwYXJhbSByZXFcbiAgICAgKiBAcGFyYW0gcmVzXG4gICAgICogQHBhcmFtIGN1c3RvbUhhbmRsZXJcbiAgICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgICAqL1xuICAgIHB1YmxpYyBzZW5kSG9va1Jlc3BvbnNlIChob2xkUmVzcG9uc2U6IGJvb2xlYW4sIGpvYjogV2ViaG9va0pvYiwgbmVzdDogV2ViaG9va05lc3QsIHJlcSwgcmVzLCBjdXN0b21IYW5kbGVyPzogYW55LCBtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgICAgIGlmIChob2xkUmVzcG9uc2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21IYW5kbGVyKSB7XG4gICAgICAgICAgICBqb2IucmVzcG9uc2VTZW50ID0gdHJ1ZTtcbiAgICAgICAgICAgIGN1c3RvbUhhbmRsZXIocmVxLCByZXMsIGpvYiwgbmVzdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBqb2IucmVzcG9uc2VTZW50ID0gdHJ1ZTtcbiAgICAgICAgICAgIGxldCByZXNwb25zZSA9IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlIHx8IGBKb2IgJHtqb2IuaWR9IHdhcyBjcmVhdGVkIWAsXG4gICAgICAgICAgICAgICAgam9iOiB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBqb2IuaWQsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGpvYi5uYW1lXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBuZXN0OiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IG5lc3QubmFtZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXMuanNvbihyZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgd2ViaG9vayBpbnRlcmZhY2UgdG8gdGhlIHdlYmhvb2sgc2VydmVyLlxuICAgICAqIEBwYXJhbSBpbSB7SW50ZXJmYWNlTWFuYWdlcn1cbiAgICAgKi9cbiAgICBwdWJsaWMgYWRkV2ViaG9va0ludGVyZmFjZShpbTogSW50ZXJmYWNlTWFuYWdlcikge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG4gICAgICAgIGxldCBuZXN0ID0gaW0ubmVzdDtcblxuICAgICAgICBsZXQgaG9va19wYXRoID0gcy5jb25maWcuaG9va3NfcHJlZml4ICsgbmVzdC5wYXRoO1xuICAgICAgICBsZXQgaG9va191aV9wYXRoID0gcy5jb25maWcuaG9va3NfdWlfcHJlZml4ICsgaW0ucGF0aDtcblxuICAgICAgICBzLmUubG9nKDEsIGBXYXRjaGluZyB3ZWJob29rIGludGVyZmFjZSBHRVQgJHtob29rX3VpX3BhdGh9YCwgcyk7XG5cbiAgICAgICAgdGhpcy5ob29rSW50ZXJmYWNlUm91dGVzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IG5lc3QuaWQsXG4gICAgICAgICAgICBwYXRoOiBob29rX3VpX3BhdGgsXG4gICAgICAgICAgICBuZXN0OiBuZXN0Lm5hbWUsXG4gICAgICAgICAgICB0YXJnZXQ6IGhvb2tfcGF0aFxuICAgICAgICAgICAgLy8gdHVubmVsOiBuZXN0LmdldFR1bm5lbCgpLm5hbWVcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcy5zZXJ2ZXIuZ2V0KGhvb2tfdWlfcGF0aCwgIGZ1bmN0aW9uIChyZXEsIHJlcykge1xuXG4gICAgICAgICAgICBsZXQgY3VzdG9tSGFuZGxlciA9IGltLmN1c3RvbUhhbmRsZVJlcXVlc3Q7XG5cbiAgICAgICAgICAgIHMuaGFuZGxlSG9va0ludGVyZmFjZVJlcXVlc3QoaW0sIHJlcSwgcmVzLCBjdXN0b21IYW5kbGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyByZXF1ZXN0IGFuZCByZXNwb25zZSBvZiB0aGUgd2ViIGhvb2sgaW50ZXJmYWNlLlxuICAgICAqIEBwYXJhbSBpbSB7SW50ZXJmYWNlTWFuYWdlcn1cbiAgICAgKiBAcGFyYW0gcmVxIHtleHByZXNzLlJlcXVlc3R9XG4gICAgICogQHBhcmFtIHJlcyB7ZXhwcmVzcy5SZXNwb25zZX1cbiAgICAgKiBAcGFyYW0gY3VzdG9tSGFuZGxlciAgICAgICAgICAgICBDdXN0b20gcmVxdWVzdCBoYW5kbGVyLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBoYW5kbGVIb29rSW50ZXJmYWNlUmVxdWVzdCA9IGZ1bmN0aW9uKGltOiBJbnRlcmZhY2VNYW5hZ2VyLCByZXEsIHJlcywgY3VzdG9tSGFuZGxlcj86IGFueSkge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG5cbiAgICAgICAgLy8gSm9iIGFycml2ZVxuICAgICAgICBsZXQgam9iID0gbmV3IFdlYmhvb2tKb2Iocy5lLCByZXEsIHJlcyk7XG5cbiAgICAgICAgLy8gRmlsbCBpbiBkZWZhdWx0IHZhbHVlc1xuICAgICAgICBsZXQgcGFyYW1zID0gam9iLmdldFF1ZXJ5U3RyaW5nVmFsdWVzKCk7XG5cbiAgICAgICAgLy8gSWYgc2Vzc2lvbiBub3Qgc2V0LCByZXR1cm4gYSBmcmVzaCB1aSBzb21laG93XG4gICAgICAgIGxldCBzZXNzaW9uSWQgPSBwYXJhbXNbXCJzZXNzaW9uSWRcIl0gfHwgam9iLmdldEZvcm1EYXRhVmFsdWUoXCJzZXNzaW9uSWRcIik7XG5cbiAgICAgICAgbGV0IHVpID0gaW0uZ2V0SW50ZXJmYWNlKHNlc3Npb25JZCk7XG5cbiAgICAgICAgaWYgKHVpLnNlc3Npb25JZCA9PT0gc2Vzc2lvbklkKSB7XG4gICAgICAgICAgICAvLyBGaWxsIGluIGRlZmF1bHQgdmFsdWVzXG4gICAgICAgICAgICB1aS5maWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkLmlkIGluIHBhcmFtcyAmJiBwYXJhbXNbZmllbGQuaWRdICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLnZhbHVlID0gcGFyYW1zW2ZpZWxkLmlkXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gRG8gc3RlcHNcbiAgICAgICAgICAgIGFzeW5jLmVhY2godWkuc3RlcHMsIChzdGVwLCBjYikgPT4ge1xuICAgICAgICAgICAgICAgIHMuZS5sb2coMCwgYFJ1bm5pbmcgVUkgc3RlcCBcIiR7c3RlcC5uYW1lfVwiLmAsIHMpO1xuICAgICAgICAgICAgICAgIHN0ZXAuY2FsbGJhY2soam9iLCB1aSwgc3RlcCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjYigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcy5lLmxvZygzLCBgRXJyb3IgcnVubmluZyBVSSBzdGVwcy4gJHtlcnJ9YCwgcyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcy5lLmxvZygwLCBgRG9uZSBydW5uaW5nIGFsbCBVSSBzdGVwcy5gLCBzKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoY3VzdG9tSGFuZGxlcikge1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21IYW5kbGVyKHJlcSwgcmVzLCB1aSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmpzb24odWkuZ2V0VHJhbnNwb3J0SW50ZXJmYWNlKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY3VzdG9tSGFuZGxlcikge1xuICAgICAgICAgICAgICAgIGN1c3RvbUhhbmRsZXIocmVxLCByZXMsIHVpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzLmpzb24odWkuZ2V0VHJhbnNwb3J0SW50ZXJmYWNlKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9O1xufSJdfQ==