@tricoteuses/arbre-de-la-loi
Version:
Generate ASTs from the French bills & laws; manipulate & export them to Markdown, etc.
379 lines (285 loc) • 28.3 kB
JavaScript
;
require("core-js/modules/es.array.slice.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.from.js");
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.symbol.description.js");
require("core-js/modules/es.symbol.iterator.js");
require("core-js/modules/es.array.is-array.js");
require("core-js/modules/es.promise.js");
require("regenerator-runtime/runtime.js");
require("core-js/modules/es.array.join.js");
require("core-js/modules/es.array.sort.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.object.values.js");
require("core-js/modules/web.url.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.array.concat.js");
require("core-js/modules/es.regexp.to-string.js");
require("core-js/modules/es.date.to-string.js");
var _loaders = require("@tricoteuses/assemblee/lib/loaders");
var _assert = _interopRequireDefault(require("assert"));
var _child_process = require("child_process");
var _commandLineArgs = _interopRequireDefault(require("command-line-args"));
var _fsExtra = _interopRequireDefault(require("fs-extra"));
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
var _path = _interopRequireDefault(require("path"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var optionsDefinitions = [{
alias: "c",
help: "commit documents",
name: "commit",
type: Boolean
}, {
alias: "f",
help: "retrieve all documents, even already retrieved ones",
name: "full",
type: Boolean
}, {
alias: "l",
defaultValue: "15",
name: "legislature",
type: String
}, {
alias: "r",
help: "push commit to given remote",
multiple: true,
name: "remote",
type: String
}, {
alias: "s",
help: "don't log anything",
name: "silent",
type: Boolean
}, {
alias: "u",
help: "UID of first Assemblée's document to retrieve",
name: "uid",
type: String
}, {
alias: "v",
help: "verbose logs",
name: "verbose",
type: Boolean
}, {
defaultOption: true,
help: "directory containing Assemblée open data files",
name: "dataDir",
type: String
}];
var options = (0, _commandLineArgs["default"])(optionsDefinitions);
function commitAndPush(repositoryDir, commit, remotes) {
var error = false;
if (commit) {
(0, _child_process.execSync)("git add .", {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8",
stdio: ["ignore", "ignore", "pipe"]
});
try {
(0, _child_process.execSync)('git commit -m "Nouvelle moisson"', {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8"
});
} catch (childProcess) {
if (childProcess.stderr === null || !/nothing to commit/.test(childProcess.stdout)) {
console.error(childProcess.output);
throw childProcess;
}
}
var _iterator = _createForOfIteratorHelper(remotes || []),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var remote = _step.value;
try {
(0, _child_process.execSync)("git push ".concat(remote, " master"), {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8",
stdio: ["ignore", "ignore", "pipe"]
});
} catch (childProcess) {
// Don't stop when push fails.
console.error(childProcess.output);
error = true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return error;
}
function retrieveDocuments() {
return _retrieveDocuments.apply(this, arguments);
}
function _retrieveDocuments() {
_retrieveDocuments = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var dataDir, _loadAssembleeData, documentByUid, documentsDir, _iterator2, _step2, filename, documents, firstUid, skip, _iterator3, _step3, document, basename, fileNotFoundPath, filePath, url, response, page;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
(0, _assert["default"])(!options.commit || options.uid, 'Options "commit" & "uid" are incompatible');
dataDir = options.dataDir;
_loadAssembleeData = (0, _loaders.loadAssembleeData)(dataDir, _loaders.EnabledDatasets.DossiersLegislatifs, options.legislature), documentByUid = _loadAssembleeData.documentByUid;
documentsDir = _path["default"].join(dataDir, "documents_html");
_fsExtra["default"].ensureDirSync(documentsDir);
if (!(options.full && !options.uid)) {
_context.next = 24;
break;
}
_iterator2 = _createForOfIteratorHelper(_fsExtra["default"].readdirSync(documentsDir));
_context.prev = 7;
_iterator2.s();
case 9:
if ((_step2 = _iterator2.n()).done) {
_context.next = 16;
break;
}
filename = _step2.value;
if (!(filename[0] === ".")) {
_context.next = 13;
break;
}
return _context.abrupt("continue", 14);
case 13:
_fsExtra["default"].removeSync(_path["default"].join(documentsDir, filename));
case 14:
_context.next = 9;
break;
case 16:
_context.next = 21;
break;
case 18:
_context.prev = 18;
_context.t0 = _context["catch"](7);
_iterator2.e(_context.t0);
case 21:
_context.prev = 21;
_iterator2.f();
return _context.finish(21);
case 24:
documents = Object.values(documentByUid) // Ignore documents from Sénat.
.filter(function (document) {
return document.uid.substring(4, 6) !== "SN";
}).sort(function (a, b) {
return a.uid.localeCompare(b.uid);
});
firstUid = options.uid;
skip = !!firstUid;
_iterator3 = _createForOfIteratorHelper(documents);
_context.prev = 28;
_iterator3.s();
case 30:
if ((_step3 = _iterator3.n()).done) {
_context.next = 54;
break;
}
document = _step3.value;
if (!skip) {
_context.next = 38;
break;
}
if (!(document.uid === firstUid)) {
_context.next = 37;
break;
}
skip = false;
_context.next = 38;
break;
case 37:
return _context.abrupt("continue", 52);
case 38:
basename = (0, _loaders.pathFromDocumentUid)(documentsDir, document.uid);
fileNotFoundPath = "".concat(basename, ".404");
filePath = "".concat(basename, ".html");
if (!(!options.full && (_fsExtra["default"].existsSync(filePath) || _fsExtra["default"].existsSync(fileNotFoundPath)))) {
_context.next = 43;
break;
}
return _context.abrupt("continue", 52);
case 43:
// Note: Both URLs should work.
// const url = new URL(`https://www.assemblee-nationale.fr/dyn/docs/${document.uid}.raw`)
url = new URL("https://www.assemblee-nationale.fr/dyn/opendata/".concat(document.uid, ".html"));
if (!options.silent) {
console.log("Retrieving document ".concat(document.uid, " at ").concat(url.toString(), "\u2026"));
}
_context.next = 47;
return (0, _nodeFetch["default"])(url);
case 47:
response = _context.sent;
_context.next = 50;
return response.text();
case 50:
page = _context.sent;
if (response.ok) {
_fsExtra["default"].writeFileSync(filePath, page, {
encoding: "utf8"
});
_fsExtra["default"].removeSync(fileNotFoundPath);
} else {
if (response.status === 404) {
if (!options.silent) {
console.warn("Page \"".concat(url, "\" not found."));
_fsExtra["default"].writeFileSync(fileNotFoundPath, "Page \"".concat(url, "\" not found."), {
encoding: "utf8"
});
_fsExtra["default"].removeSync(filePath);
}
} else {
console.error("Error while getting page \"".concat(url, "\":\n\nError:\n").concat(JSON.stringify({
code: response.status,
message: response.statusText
}, null, 2)));
_fsExtra["default"].removeSync(fileNotFoundPath);
_fsExtra["default"].removeSync(filePath);
}
}
case 52:
_context.next = 30;
break;
case 54:
_context.next = 59;
break;
case 56:
_context.prev = 56;
_context.t1 = _context["catch"](28);
_iterator3.e(_context.t1);
case 59:
_context.prev = 59;
_iterator3.f();
return _context.finish(59);
case 62:
if (commitAndPush(documentsDir, options.commit, options.remote)) {
process.exit(1);
}
return _context.abrupt("return", documents);
case 64:
case "end":
return _context.stop();
}
}
}, _callee, null, [[7, 18, 21, 24], [28, 56, 59, 62]]);
}));
return _retrieveDocuments.apply(this, arguments);
}
retrieveDocuments()["catch"](function (error) {
console.log(error);
process.exit(1);
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JpcHRzL3JldHJpZXZlX2Fzc2VtYmxlZV9kb2N1bWVudHMudHMiXSwibmFtZXMiOlsib3B0aW9uc0RlZmluaXRpb25zIiwiYWxpYXMiLCJoZWxwIiwibmFtZSIsInR5cGUiLCJCb29sZWFuIiwiZGVmYXVsdFZhbHVlIiwiU3RyaW5nIiwibXVsdGlwbGUiLCJkZWZhdWx0T3B0aW9uIiwib3B0aW9ucyIsImNvbW1pdEFuZFB1c2giLCJyZXBvc2l0b3J5RGlyIiwiY29tbWl0IiwicmVtb3RlcyIsImVycm9yIiwiY3dkIiwiZW52IiwicHJvY2VzcyIsImVuY29kaW5nIiwic3RkaW8iLCJjaGlsZFByb2Nlc3MiLCJzdGRlcnIiLCJ0ZXN0Iiwic3Rkb3V0IiwiY29uc29sZSIsIm91dHB1dCIsInJlbW90ZSIsInJldHJpZXZlRG9jdW1lbnRzIiwidWlkIiwiZGF0YURpciIsIkVuYWJsZWREYXRhc2V0cyIsIkRvc3NpZXJzTGVnaXNsYXRpZnMiLCJsZWdpc2xhdHVyZSIsImRvY3VtZW50QnlVaWQiLCJkb2N1bWVudHNEaXIiLCJwYXRoIiwiam9pbiIsImZzIiwiZW5zdXJlRGlyU3luYyIsImZ1bGwiLCJyZWFkZGlyU3luYyIsImZpbGVuYW1lIiwicmVtb3ZlU3luYyIsImRvY3VtZW50cyIsIk9iamVjdCIsInZhbHVlcyIsImZpbHRlciIsImRvY3VtZW50Iiwic3Vic3RyaW5nIiwic29ydCIsImEiLCJiIiwibG9jYWxlQ29tcGFyZSIsImZpcnN0VWlkIiwic2tpcCIsImJhc2VuYW1lIiwiZmlsZU5vdEZvdW5kUGF0aCIsImZpbGVQYXRoIiwiZXhpc3RzU3luYyIsInVybCIsIlVSTCIsInNpbGVudCIsImxvZyIsInRvU3RyaW5nIiwicmVzcG9uc2UiLCJ0ZXh0IiwicGFnZSIsIm9rIiwid3JpdGVGaWxlU3luYyIsInN0YXR1cyIsIndhcm4iLCJKU09OIiwic3RyaW5naWZ5IiwiY29kZSIsIm1lc3NhZ2UiLCJzdGF0dXNUZXh0IiwiZXhpdCJdLCJt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QUFBQSxPQUFPLENBQUMyRCxJQUFSLENBQWEsQ0FBYjtBQUNELENBSEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEb2N1bWVudCB9IGZyb20gXCJAdHJpY290ZXVzZXMvYXNzZW1ibGVlXCJcbmltcG9ydCB7XG4gIEVuYWJsZWREYXRhc2V0cyxcbiAgbG9hZEFzc2VtYmxlZURhdGEsXG4gIHBhdGhGcm9tRG9jdW1lbnRVaWQsXG59IGZyb20gXCJAdHJpY290ZXVzZXMvYXNzZW1ibGVlL2xpYi9sb2FkZXJzXCJcbmltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCJcbmltcG9ydCBjb21tYW5kTGluZUFyZ3MgZnJvbSBcImNvbW1hbmQtbGluZS1hcmdzXCJcbmltcG9ydCBmcyBmcm9tIFwiZnMtZXh0cmFcIlxuaW1wb3J0IGZldGNoIGZyb20gXCJub2RlLWZldGNoXCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcblxuY29uc3Qgb3B0aW9uc0RlZmluaXRpb25zID0gW1xuICB7XG4gICAgYWxpYXM6IFwiY1wiLFxuICAgIGhlbHA6IFwiY29tbWl0IGRvY3VtZW50c1wiLFxuICAgIG5hbWU6IFwiY29tbWl0XCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcImZcIixcbiAgICBoZWxwOiBcInJldHJpZXZlIGFsbCBkb2N1bWVudHMsIGV2ZW4gYWxyZWFkeSByZXRyaWV2ZWQgb25lc1wiLFxuICAgIG5hbWU6IFwiZnVsbFwiLFxuICAgIHR5cGU6IEJvb2xlYW4sXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJsXCIsXG4gICAgZGVmYXVsdFZhbHVlOiBcIjE1XCIsXG4gICAgbmFtZTogXCJsZWdpc2xhdHVyZVwiLFxuICAgIHR5cGU6IFN0cmluZyxcbiAgfSxcbiAge1xuICAgIGFsaWFzOiBcInJcIixcbiAgICBoZWxwOiBcInB1c2ggY29tbWl0IHRvIGdpdmVuIHJlbW90ZVwiLFxuICAgIG11bHRpcGxlOiB0cnVlLFxuICAgIG5hbWU6IFwicmVtb3RlXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwic1wiLFxuICAgIGhlbHA6IFwiZG9uJ3QgbG9nIGFueXRoaW5nXCIsXG4gICAgbmFtZTogXCJzaWxlbnRcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwidVwiLFxuICAgIGhlbHA6IFwiVUlEIG9mIGZpcnN0IEFzc2VtYmzDqWUncyBkb2N1bWVudCB0byByZXRyaWV2ZVwiLFxuICAgIG5hbWU6IFwidWlkXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwidlwiLFxuICAgIGhlbHA6IFwidmVyYm9zZSBsb2dzXCIsXG4gICAgbmFtZTogXCJ2ZXJib3NlXCIsXG4gICAgdHlwZTogQm9vbGVhbixcbiAgfSxcbiAge1xuICAgIGRlZmF1bHRPcHRpb246IHRydWUsXG4gICAgaGVscDogXCJkaXJlY3RvcnkgY29udGFpbmluZyBBc3NlbWJsw6llIG9wZW4gZGF0YSBmaWxlc1wiLFxuICAgIG5hbWU6IFwiZGF0YURpclwiLFxuICAgIHR5cGU6IFN0cmluZyxcbiAgfSxcbl1cbmNvbnN0IG9wdGlvbnMgPSBjb21tYW5kTGluZUFyZ3Mob3B0aW9uc0RlZmluaXRpb25zKVxuXG5mdW5jdGlvbiBjb21taXRBbmRQdXNoKFxuICByZXBvc2l0b3J5RGlyOiBzdHJpbmcsXG4gIGNvbW1pdDogYm9vbGVhbixcbiAgcmVtb3Rlcz86IHN0cmluZ1tdLFxuKTogYm9vbGVhbiB7XG4gIGxldCBlcnJvciA9IGZhbHNlXG4gIGlmIChjb21taXQpIHtcbiAgICBleGVjU3luYyhcImdpdCBhZGQgLlwiLCB7XG4gICAgICBjd2Q6IHJlcG9zaXRvcnlEaXIsXG4gICAgICBlbnY6IHByb2Nlc3MuZW52LFxuICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgIHN0ZGlvOiBbXCJpZ25vcmVcIiwgXCJpZ25vcmVcIiwgXCJwaXBlXCJdLFxuICAgIH0pXG4gICAgdHJ5IHtcbiAgICAgIGV4ZWNTeW5jKCdnaXQgY29tbWl0IC1tIFwiTm91dmVsbGUgbW9pc3NvblwiJywge1xuICAgICAgICBjd2Q6IHJlcG9zaXRvcnlEaXIsXG4gICAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICAgIGVuY29kaW5nOiBcInV0Zi04XCIsXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGNoaWxkUHJvY2Vzcykge1xuICAgICAgaWYgKFxuICAgICAgICBjaGlsZFByb2Nlc3Muc3RkZXJyID09PSBudWxsIHx8XG4gICAgICAgICEvbm90aGluZyB0byBjb21taXQvLnRlc3QoY2hpbGRQcm9jZXNzLnN0ZG91dClcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGNoaWxkUHJvY2Vzcy5vdXRwdXQpXG4gICAgICAgIHRocm93IGNoaWxkUHJvY2Vzc1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHJlbW90ZSBvZiByZW1vdGVzIHx8IFtdKSB7XG4gICAgICB0cnkge1xuICAgICAgICBleGVjU3luYyhgZ2l0IHB1c2ggJHtyZW1vdGV9IG1hc3RlcmAsIHtcbiAgICAgICAgICBjd2Q6IHJlcG9zaXRvcnlEaXIsXG4gICAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgICAgIHN0ZGlvOiBbXCJpZ25vcmVcIiwgXCJpZ25vcmVcIiwgXCJwaXBlXCJdLFxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoY2hpbGRQcm9jZXNzKSB7XG4gICAgICAgIC8vIERvbid0IHN0b3Agd2hlbiBwdXNoIGZhaWxzLlxuICAgICAgICBjb25zb2xlLmVycm9yKGNoaWxkUHJvY2Vzcy5vdXRwdXQpXG4gICAgICAgIGVycm9yID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZXJyb3Jcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmV0cmlldmVEb2N1bWVudHMoKTogUHJvbWlzZTxEb2N1bWVudFtdPiB7XG4gIGFzc2VydChcbiAgICAhb3B0aW9ucy5jb21taXQgfHwgb3B0aW9ucy51aWQsXG4gICAgJ09wdGlvbnMgXCJjb21taXRcIiAmIFwidWlkXCIgYXJlIGluY29tcGF0aWJsZScsXG4gIClcblxuICBjb25zdCBkYXRhRGlyID0gb3B0aW9ucy5kYXRhRGlyXG4gIGNvbnN0IHsgZG9jdW1lbnRCeVVpZCB9ID0gbG9hZEFzc2VtYmxlZURhdGEoXG4gICAgZGF0YURpcixcbiAgICBFbmFibGVkRGF0YXNldHMuRG9zc2llcnNMZWdpc2xhdGlmcyxcbiAgICBvcHRpb25zLmxlZ2lzbGF0dXJlLFxuICApXG5cbiAgY29uc3QgZG9jdW1lbnRzRGlyID0gcGF0aC5qb2luKGRhdGFEaXIsIFwiZG9jdW1lbnRzX2h0bWxcIilcbiAgZnMuZW5zdXJlRGlyU3luYyhkb2N1bWVudHNEaXIpXG4gIGlmIChvcHRpb25zLmZ1bGwgJiYgIW9wdGlvbnMudWlkKSB7XG4gICAgZm9yIChjb25zdCBmaWxlbmFtZSBvZiBmcy5yZWFkZGlyU3luYyhkb2N1bWVudHNEaXIpKSB7XG4gICAgICBpZiAoZmlsZW5hbWVbMF0gPT09IFwiLlwiKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBmcy5yZW1vdmVTeW5jKHBhdGguam9pbihkb2N1bWVudHNEaXIsIGZpbGVuYW1lKSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBkb2N1bWVudHMgPSBPYmplY3QudmFsdWVzKGRvY3VtZW50QnlVaWQpXG4gICAgLy8gSWdub3JlIGRvY3VtZW50cyBmcm9tIFPDqW5hdC5cbiAgICAuZmlsdGVyKChkb2N1bWVudCkgPT4gZG9jdW1lbnQudWlkLnN1YnN0cmluZyg0LCA2KSAhPT0gXCJTTlwiKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLnVpZC5sb2NhbGVDb21wYXJlKGIudWlkKSlcblxuICBjb25zdCBmaXJzdFVpZCA9IG9wdGlvbnMudWlkXG4gIGxldCBza2lwID0gISFmaXJzdFVpZFxuICBmb3IgKGNvbnN0IGRvY3VtZW50IG9mIGRvY3VtZW50cykge1xuICAgIGlmIChza2lwKSB7XG4gICAgICBpZiAoZG9jdW1lbnQudWlkID09PSBmaXJzdFVpZCkge1xuICAgICAgICBza2lwID0gZmFsc2VcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZW5hbWUgPSBwYXRoRnJvbURvY3VtZW50VWlkKGRvY3VtZW50c0RpciwgZG9jdW1lbnQudWlkKVxuICAgIGNvbnN0IGZpbGVOb3RGb3VuZFBhdGggPSBgJHtiYXNlbmFtZX0uNDA0YFxuICAgIGNvbnN0IGZpbGVQYXRoID0gYCR7YmFzZW5hbWV9Lmh0bWxgXG4gICAgaWYgKFxuICAgICAgIW9wdGlvbnMuZnVsbCAmJlxuICAgICAgKGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpIHx8IGZzLmV4aXN0c1N5bmMoZmlsZU5vdEZvdW5kUGF0aCkpXG4gICAgKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIC8vIE5vdGU6IEJvdGggVVJMcyBzaG91bGQgd29yay5cbiAgICAvLyBjb25zdCB1cmwgPSBuZXcgVVJMKGBodHRwczovL3d3dy5hc3NlbWJsZWUtbmF0aW9uYWxlLmZyL2R5bi9kb2NzLyR7ZG9jdW1lbnQudWlkfS5yYXdgKVxuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoXG4gICAgICBgaHR0cHM6Ly93d3cuYXNzZW1ibGVlLW5hdGlvbmFsZS5mci9keW4vb3BlbmRhdGEvJHtkb2N1bWVudC51aWR9Lmh0bWxgLFxuICAgIClcbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG4gICAgICBjb25zb2xlLmxvZyhgUmV0cmlldmluZyBkb2N1bWVudCAke2RvY3VtZW50LnVpZH0gYXQgJHt1cmwudG9TdHJpbmcoKX3igKZgKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKVxuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCByZXNwb25zZS50ZXh0KClcbiAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIHBhZ2UsIHtcbiAgICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgfSlcbiAgICAgIGZzLnJlbW92ZVN5bmMoZmlsZU5vdEZvdW5kUGF0aClcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgIGlmICghb3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFBhZ2UgXCIke3VybH1cIiBub3QgZm91bmQuYClcbiAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGVOb3RGb3VuZFBhdGgsIGBQYWdlIFwiJHt1cmx9XCIgbm90IGZvdW5kLmAsIHtcbiAgICAgICAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgICAgICB9KVxuICAgICAgICAgIGZzLnJlbW92ZVN5bmMoZmlsZVBhdGgpXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgYEVycm9yIHdoaWxlIGdldHRpbmcgcGFnZSBcIiR7dXJsfVwiOlxcblxcbkVycm9yOlxcbiR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICB7IGNvZGU6IHJlc3BvbnNlLnN0YXR1cywgbWVzc2FnZTogcmVzcG9uc2Uuc3RhdHVzVGV4dCB9LFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIDIsXG4gICAgICAgICAgKX1gLFxuICAgICAgICApXG4gICAgICAgIGZzLnJlbW92ZVN5bmMoZmlsZU5vdEZvdW5kUGF0aClcbiAgICAgICAgZnMucmVtb3ZlU3luYyhmaWxlUGF0aClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoY29tbWl0QW5kUHVzaChkb2N1bWVudHNEaXIsIG9wdGlvbnMuY29tbWl0LCBvcHRpb25zLnJlbW90ZSkpIHtcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxuICByZXR1cm4gZG9jdW1lbnRzXG59XG5cbnJldHJpZXZlRG9jdW1lbnRzKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gIGNvbnNvbGUubG9nKGVycm9yKVxuICBwcm9jZXNzLmV4aXQoMSlcbn0pXG4iXX0=