UNPKG

kre-form

Version:

本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装

642 lines 53.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input, Output, EventEmitter, } from "@angular/core"; import { Graph, Shape, Addon } from "@antv/x6"; import { NzMessageService } from "ng-zorro-antd/message"; var DataFlowComponent = /** @class */ (function () { function DataFlowComponent(message) { this.message = message; this.drawerEvent = new EventEmitter(); this.modalEvent = new EventEmitter(); this.data = { // 节点 nodes: [ { id: "node1", // String,可选,节点的唯一标识 x: 40, // Number,必选,节点位置的 x 值 y: 40, // Number,必选,节点位置的 y 值 width: 80, // Number,可选,节点大小的 width 值 height: 40, // Number,可选,节点大小的 height 值 label: "hello", }, { id: "node2", // String,节点的唯一标识 x: 160, // Number,必选,节点位置的 x 值 y: 180, // Number,必选,节点位置的 y 值 width: 80, // Number,可选,节点大小的 width 值 height: 40, // Number,可选,节点大小的 height 值 label: "world", }, ], // 边 edges: [ { source: "node1", // String,必须,起始节点 id target: "node2", }, ], }; this.title = "my-app"; } /** * @return {?} */ DataFlowComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.graphShape(); this.grahpInit(); this.getHistoryGrahp(); this.graphEvent(); // console.log("节点", this.graph.getNodes()); // console.log("cell-----"); // console.log("节点和边", this.graph.getCells()); // console.log("根节点,即没有输入边的节点", this.graph.getRootNodes()); // console.log("叶子节点,即没有输出边的节点", this.graph.getLeafNodes()); // console.log("数量", this.graph.getCellCount()); // console.log(this.graph); // console.log(this.stencil.graphs.group1.getNodes()); /** @type {?} */ var nodes = this.graph.getLeafNodes(); for (var i = 0; i < nodes.length; i++) { /** @type {?} */ var node = nodes[i]; if (node["label"] !== "输出") { this.message.error("界面必须包含输出"); break; } } }; /** * @return {?} */ DataFlowComponent.prototype.grahpInit = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var that = this; // #region 初始化画布 this.graph = new Graph({ container: (/** @type {?} */ (document.getElementById("graph-container"))), grid: true, history: true, minimap: { enabled: true, container: (/** @type {?} */ (document.getElementById("minimap"))), width: 198, height: 198, padding: 10, }, mousewheel: { enabled: true, zoomAtMousePosition: true, modifiers: "ctrl", minScale: 0.5, maxScale: 3, }, connecting: { router: "manhattan", connector: { name: "rounded", args: { radius: 8, }, }, anchor: "center", connectionPoint: "anchor", allowBlank: false, snap: { radius: 20, }, createEdge: /** * @return {?} */ function () { return new Shape.Edge({ attrs: { line: { stroke: "#A2B1C3", strokeWidth: 2, targetMarker: { name: "block", width: 12, height: 8, }, }, }, zIndex: 0, }); }, // 在移动边的时候判断连接是否有效 validateConnection: // 在移动边的时候判断连接是否有效 /** * @param {?} __0 * @return {?} */ function (_a) { var sourceView = _a.sourceView, targetView = _a.targetView, sourceMagnet = _a.sourceMagnet, targetMagnet = _a.targetMagnet, sourceCell = _a.sourceCell, targetCell = _a.targetCell; if (targetMagnet && targetCell) { /** @type {?} */ var incomingEdges = (/** @type {?} */ (that.graph)).getIncomingEdges(targetCell) || []; if (incomingEdges.length >= (/** @type {?} */ (targetView)).cell.getData().out) { that.message.error("超出out数量"); return false; } } // 不允许连接到自己 if (sourceView === targetView) { // that.message.error("不允许连接到自己"); return false; } // 只能从输出链接桩创建连接 if (!sourceMagnet || sourceMagnet.getAttribute("port-group") === "left") { // that.message.error("只能从输出链接桩创建连接"); return false; } // 只能连接到输入链接桩 if (!targetMagnet || targetMagnet.getAttribute("port-group") === "right") { // that.message.error("只能连接到输入链接桩"); return false; } return !!targetMagnet; }, }, highlighting: { magnetAdsorbed: { name: "stroke", args: { attrs: { fill: "#5F95FF", stroke: "#5F95FF", }, }, }, }, resizing: true, rotating: true, selecting: { enabled: true, rubberband: true, showNodeSelectionBox: true, }, snapline: true, keyboard: true, clipboard: true, }); this.stencil = new Addon.Stencil({ target: this.graph, stencilGraphWidth: 200, stencilGraphHeight: 180, collapsable: true, groups: [ { title: "数据处理", name: "group1", }, { title: "输入输出", name: "group2", }, ], layoutOptions: { columns: 2, columnWidth: 80, rowHeight: 55, }, validateNode: /** * @param {?} currentnode * @return {?} */ function (currentnode) { /** @type {?} */ var nodes = that.graph.getNodes(); if (nodes.length > 0) { for (var i = 0; i < nodes.length; i++) { /** @type {?} */ var node = nodes[i]; if (currentnode["label"] === "输出" && node["label"] === "输出") { return false; } } } return true; }, getDropNode: /** * @param {?} node * @return {?} */ function (node) { /** @type {?} */ var size = node.size(); if (node["label"] === "输入") { that.getModal(node["label"]); } if (node["label"] === "输出") { r2.attr("body/fill", "#ccc"); } return node.clone().size(size.width * 1.1, size.height * 1.1); }, }); (/** @type {?} */ (document.getElementById("stencil"))).appendChild(this.stencil.container); // #region 初始化图形 // 常规左右两个桩 /** @type {?} */ var ports = { groups: { right: { position: "right", attrs: { circle: { r: 4, magnet: true, stroke: "#5F95FF", strokeWidth: 1, fill: "#fff", style: { visibility: "hidden", }, }, }, }, left: { position: "left", attrs: { circle: { r: 4, magnet: true, stroke: "#5F95FF", strokeWidth: 1, fill: "#fff", style: { visibility: "hidden", }, }, }, }, }, items: [ { id: "port1", group: "left", }, { id: "port2", group: "right", }, ], }; // 输入只有左侧一个桩 /** @type {?} */ var ports2 = { groups: { left: { position: "left", attrs: { circle: { r: 4, magnet: true, stroke: "#5F95FF", strokeWidth: 1, fill: "#fff", style: { visibility: "hidden", }, }, }, }, }, items: [ { id: "port1", group: "left", }, ], }; // 输出只有右侧一个桩 /** @type {?} */ var ports3 = { groups: { right: { position: "right", attrs: { circle: { r: 4, magnet: true, stroke: "#5F95FF", strokeWidth: 1, fill: "#fff", style: { visibility: "hidden", }, }, }, }, }, items: [ { id: "port2", group: "right", }, ], }; /** @type {?} */ var r1 = this.graph.createNode({ shape: "custom-rect", id: "in", label: "输入", ports: tslib_1.__assign({}, ports3), data: { in: 0, out: 3, }, }); /** @type {?} */ var r2 = this.graph.createNode({ shape: "custom-rect", id: "out", label: "输出", ports: tslib_1.__assign({}, ports2), data: { in: 2, out: 2, }, }); /** @type {?} */ var nodeArr = []; this.menuList.forEach((/** * @param {?} element * @param {?} i * @return {?} */ function (element, i) { nodeArr.push(_this.graph.createNode({ shape: "custom-rect", label: element.title, ports: tslib_1.__assign({}, ports), data: element.data, })); })); this.stencil.load([r1, r2], "group1"); this.stencil.load(tslib_1.__spread(nodeArr), "group2"); }; /** * @return {?} */ DataFlowComponent.prototype.graphEvent = /** * @return {?} */ function () { var _this = this; // delete this.graph.bindKey("backspace", (/** * @return {?} */ function () { /** @type {?} */ var cells = _this.graph.getSelectedCells(); if (cells.length) { _this.graph.removeCells(cells); } })); // 控制连接桩显示/隐藏 /** @type {?} */ var showPorts = (/** * @param {?} ports * @param {?} show * @return {?} */ function (ports, show) { for (var i = 0, len = ports.length; i < len; i = i + 1) { ports[i].style.visibility = show ? "visible" : "hidden"; } }); this.graph.on("node:mouseenter", (/** * @return {?} */ function () { /** @type {?} */ var container = (/** @type {?} */ (document.getElementById("graph-container"))); /** @type {?} */ var ports = (/** @type {?} */ (container.querySelectorAll(".x6-port-body"))); showPorts(ports, true); })); this.graph.on("node:mouseleave", (/** * @return {?} */ function () { /** @type {?} */ var container = (/** @type {?} */ (document.getElementById("graph-container"))); /** @type {?} */ var ports = (/** @type {?} */ (container.querySelectorAll(".x6-port-body"))); showPorts(ports, false); })); // this.graph.on( // "edge:connected", // ({ isNew, currentMagnet, currentCell }) => {} // ); // this.graph.on("edge:added", ({ cell, index, options }) => {}); // this.graph.on( // "edge:change:*", // (args: { // key: string; // 通过 key 来确定改变项 // current: any; // 当前值,类型根据 key 指代的类型确定 // previous: any; // 改变之前的值,类型根据 key 指代的类型确定 // options: any; // 透传的 options // }) => { // console.log("key:", args.key); // } // ); // this.graph.on("edge:changed", ({ edge, options }) => {}); this.graph.on("node:click", (/** * @param {?} __0 * @return {?} */ function (_a) { var cell = _a.cell, view = _a.view; /** @type {?} */ var node = view.cell; console.log(node.label); if (node.label === "输入") { _this.getModal(node.label); } else { _this.getDrawer(node.label); } })); }; /** * @return {?} */ DataFlowComponent.prototype.getHistoryGrahp = /** * @return {?} */ function () { /** @type {?} */ var json = localStorage.getItem("graphJSON"); if (json) { this.graph.fromJSON(JSON.parse(json)); } }; /** * @param {?} label * @return {?} */ DataFlowComponent.prototype.getModal = /** * @param {?} label * @return {?} */ function (label) { this.modalEvent.emit(label); }; /** * @param {?} label * @return {?} */ DataFlowComponent.prototype.getDrawer = /** * @param {?} label * @return {?} */ function (label) { this.drawerEvent.emit(label); }; /** * @return {?} */ DataFlowComponent.prototype.graphShape = /** * @return {?} */ function () { Graph.registerNode("custom-rect", { inherit: "rect", width: 66, height: 30, attrs: { body: { strokeWidth: 1, stroke: "#eee", fill: "#fff", }, text: { fontSize: 12, color: "#262626", }, }, }, true); }; /** * @return {?} */ DataFlowComponent.prototype.handleZoomIn = /** * @return {?} */ function () { this.graph.zoom(0.1); console.log(this.graph.zoom()); }; /** * @return {?} */ DataFlowComponent.prototype.handleZoomOut = /** * @return {?} */ function () { this.graph.zoom(-0.1); }; /** * @return {?} */ DataFlowComponent.prototype.handleUndo = /** * @return {?} */ function () { this.graph.history.undo(); }; /** * @return {?} */ DataFlowComponent.prototype.handleRedo = /** * @return {?} */ function () { this.graph.history.redo(); }; /** * @return {?} */ DataFlowComponent.prototype.handleReal = /** * @return {?} */ function () { this.graph.scale(1); this.graph.centerContent(); }; /** * @return {?} */ DataFlowComponent.prototype.handleFit = /** * @return {?} */ function () { this.graph.zoomToFit({ padding: 12 }); }; DataFlowComponent.decorators = [ { type: Component, args: [{ selector: "data-flow", template: "<div class=\"wrap\">\n <div class=\"main\">\n <div class=\"edit-container\">\n <div id=\"container\">\n <div id=\"stencil\"></div>\n <div class=\"graph-wrap\">\n <div class=\"toolbar-wrap\">\n <span (click)=\"handleZoomIn()\" class=\"toolbar-btn\">+</span>\n <span class=\"number\">{{ graph.zoom() | percent }}</span>\n <span (click)=\"handleZoomOut()\" class=\"toolbar-btn\">-</span>\n <span class=\"line\">|</span>\n <span\n (click)=\"handleUndo()\"\n [ngClass]=\"{ on: graph.history.canUndo() }\"\n class=\"toolbar-btn-off\"\n >&lt;</span\n >\n <span\n (click)=\"handleRedo()\"\n [ngClass]=\"{ on: graph.history.canRedo() }\"\n class=\"toolbar-btn-off\"\n >&gt;</span\n >\n\n <span (click)=\"handleReal()\">\u5B9E\u9645\u5C3A\u5BF8</span>\n <span (click)=\"handleFit()\">\u9002\u5E94\u753B\u5E03</span>\n </div>\n <div id=\"graph-container\"></div>\n <div id=\"minimap\"></div>\n </div>\n </div>\n </div>\n <div class=\"board\"></div>\n </div>\n</div>\n", styles: [":host #stencil{width:180px;height:100%;position:relative}:host .graph-wrap{width:calc(100% - 180px)}:host .graph-wrap .toolbar-wrap{height:42px;line-height:42px}:host .graph-wrap .toolbar-wrap span{color:#111;margin:0 10px}:host .graph-wrap .toolbar-wrap .number{display:inline-block;width:42px}:host .graph-wrap .toolbar-wrap .line{color:#eee}:host .graph-wrap .toolbar-wrap .toolbar-btn{cursor:pointer;font-weight:700;padding:0 10px}:host .graph-wrap .toolbar-wrap .toolbar-btn-off{font-weight:700;padding:0 10px;cursor:default;color:#eee}:host .graph-wrap .toolbar-wrap .on{cursor:pointer;color:#111}:host .graph-wrap #graph-container{width:100%;height:100%}:host .graph-wrap #minimap{position:absolute;right:1rem;top:1rem;background-color:#bc8f8f}:host #container{display:flex;height:500px}:host ::ng-deep .x6-widget-stencil-title{display:none}:host ::ng-deep .x6-widget-stencil.collapsable>.x6-widget-stencil-content{top:0}"] }] } ]; /** @nocollapse */ DataFlowComponent.ctorParameters = function () { return [ { type: NzMessageService } ]; }; DataFlowComponent.propDecorators = { menuList: [{ type: Input }], drawerEvent: [{ type: Output }], modalEvent: [{ type: Output }] }; return DataFlowComponent; }()); export { DataFlowComponent }; if (false) { /** @type {?} */ DataFlowComponent.prototype.menuList; /** @type {?} */ DataFlowComponent.prototype.drawerEvent; /** @type {?} */ DataFlowComponent.prototype.modalEvent; /** @type {?} */ DataFlowComponent.prototype.data; /** @type {?} */ DataFlowComponent.prototype.title; /** @type {?} */ DataFlowComponent.prototype.graph; /** @type {?} */ DataFlowComponent.prototype.stencil; /** * @type {?} * @private */ DataFlowComponent.prototype.message; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrcmUtZm9ybS9hYmMvIiwic291cmNlcyI6WyJsaWIvZGF0YS1mbG93L2RhdGEtZmxvdy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUlULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBUSxNQUFNLFVBQVUsQ0FBQztBQUVyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUV6RDtJQXdDRSwyQkFBb0IsT0FBeUI7UUFBekIsWUFBTyxHQUFQLE9BQU8sQ0FBa0I7UUFqQ25DLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN0QyxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUMvQyxTQUFJLEdBQUc7O1lBRUwsS0FBSyxFQUFFO2dCQUNMO29CQUNFLEVBQUUsRUFBRSxPQUFPOztvQkFDWCxDQUFDLEVBQUUsRUFBRTs7b0JBQ0wsQ0FBQyxFQUFFLEVBQUU7O29CQUNMLEtBQUssRUFBRSxFQUFFOztvQkFDVCxNQUFNLEVBQUUsRUFBRTs7b0JBQ1YsS0FBSyxFQUFFLE9BQU87aUJBQ2Y7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLE9BQU87O29CQUNYLENBQUMsRUFBRSxHQUFHOztvQkFDTixDQUFDLEVBQUUsR0FBRzs7b0JBQ04sS0FBSyxFQUFFLEVBQUU7O29CQUNULE1BQU0sRUFBRSxFQUFFOztvQkFDVixLQUFLLEVBQUUsT0FBTztpQkFDZjthQUNGOztZQUVELEtBQUssRUFBRTtnQkFDTDtvQkFDRSxNQUFNLEVBQUUsT0FBTzs7b0JBQ2YsTUFBTSxFQUFFLE9BQU87aUJBQ2hCO2FBQ0Y7U0FDRixDQUFDO1FBQ0YsVUFBSyxHQUFHLFFBQVEsQ0FBQztJQUcr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QUF5Qzs7aUJBRTFDOzs7O2dCQU5RLGdCQUFnQjs7OzJCQVF0QixLQUFLOzhCQUNMLE1BQU07NkJBQ04sTUFBTTs7SUFnZVQsd0JBQUM7Q0FBQSxBQXhlRCxJQXdlQztTQW5lWSxpQkFBaUI7OztJQUM1QixxQ0FBc0I7O0lBQ3RCLHdDQUFnRDs7SUFDaEQsdUNBQStDOztJQUMvQyxpQ0EyQkU7O0lBQ0Ysa0NBQWlCOztJQUNqQixrQ0FBYTs7SUFDYixvQ0FBdUI7Ozs7O0lBQ1gsb0NBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIFZpZXdDaGlsZCxcbiAgVGVtcGxhdGVSZWYsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEdyYXBoLCBTaGFwZSwgQWRkb24sIE5vZGUgfSBmcm9tIFwiQGFudHYveDZcIjtcbmltcG9ydCB7IG5vZGVDZW50ZXIgfSBmcm9tIFwiQGFudHYveDYvbGliL3JlZ2lzdHJ5L25vZGUtYW5jaG9yL25vZGUtY2VudGVyXCI7XG5pbXBvcnQgeyBOek1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSBcIm5nLXpvcnJvLWFudGQvbWVzc2FnZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiZGF0YS1mbG93XCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vZGF0YS1mbG93LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9kYXRhLWZsb3cuY29tcG9uZW50Lmxlc3NcIl0sXG59KVxuZXhwb3J0IGNsYXNzIERhdGFGbG93Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgbWVudUxpc3Q6IFtdO1xuICBAT3V0cHV0KCkgZHJhd2VyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIG1vZGFsRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgZGF0YSA9IHtcbiAgICAvLyDoioLngrlcbiAgICBub2RlczogW1xuICAgICAge1xuICAgICAgICBpZDogXCJub2RlMVwiLCAvLyBTdHJpbmfvvIzlj6/pgInvvIzoioLngrnnmoTllK/kuIDmoIfor4ZcbiAgICAgICAgeDogNDAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB4IOWAvFxuICAgICAgICB5OiA0MCwgLy8gTnVtYmVy77yM5b+F6YCJ77yM6IqC54K55L2N572u55qEIHkg5YC8XG4gICAgICAgIHdpZHRoOiA4MCwgLy8gTnVtYmVy77yM5Y+v6YCJ77yM6IqC54K55aSn5bCP55qEIHdpZHRoIOWAvFxuICAgICAgICBoZWlnaHQ6IDQwLCAvLyBOdW1iZXLvvIzlj6/pgInvvIzoioLngrnlpKflsI/nmoQgaGVpZ2h0IOWAvFxuICAgICAgICBsYWJlbDogXCJoZWxsb1wiLCAvLyBTdHJpbmfvvIzoioLngrnmoIfnrb5cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiBcIm5vZGUyXCIsIC8vIFN0cmluZ++8jOiKgueCueeahOWUr+S4gOagh+ivhlxuICAgICAgICB4OiAxNjAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB4IOWAvFxuICAgICAgICB5OiAxODAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB5IOWAvFxuICAgICAgICB3aWR0aDogODAsIC8vIE51bWJlcu+8jOWPr+mAie+8jOiKgueCueWkp+Wwj+eahCB3aWR0aCDlgLxcbiAgICAgICAgaGVpZ2h0OiA0MCwgLy8gTnVtYmVy77yM5Y+v6YCJ77yM6IqC54K55aSn5bCP55qEIGhlaWdodCDlgLxcbiAgICAgICAgbGFiZWw6IFwid29ybGRcIiwgLy8gU3RyaW5n77yM6IqC54K55qCH562+XG4gICAgICB9LFxuICAgIF0sXG4gICAgLy8g6L65XG4gICAgZWRnZXM6IFtcbiAgICAgIHtcbiAgICAgICAgc291cmNlOiBcIm5vZGUxXCIsIC8vIFN0cmluZ++8jOW/hemhu++8jOi1t+Wni+iKgueCuSBpZFxuICAgICAgICB0YXJnZXQ6IFwibm9kZTJcIiwgLy8gU3RyaW5n77yM5b+F6aG777yM55uu5qCH6IqC54K5IGlkXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIHRpdGxlID0gXCJteS1hcHBcIjtcbiAgZ3JhcGg6IEdyYXBoO1xuICBzdGVuY2lsOiBBZGRvbi5TdGVuY2lsO1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lc3NhZ2U6IE56TWVzc2FnZVNlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5ncmFwaFNoYXBlKCk7XG4gICAgdGhpcy5ncmFocEluaXQoKTtcbiAgICB0aGlzLmdldEhpc3RvcnlHcmFocCgpO1xuICAgIHRoaXMuZ3JhcGhFdmVudCgpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwi6IqC54K5XCIsIHRoaXMuZ3JhcGguZ2V0Tm9kZXMoKSk7XG4gICAgLy8gY29uc29sZS5sb2coXCJjZWxsLS0tLS1cIik7XG4gICAgLy8gY29uc29sZS5sb2coXCLoioLngrnlkozovrlcIiwgdGhpcy5ncmFwaC5nZXRDZWxscygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuagueiKgueCue+8jOWNs+ayoeaciei+k+WFpei+ueeahOiKgueCuVwiLCB0aGlzLmdyYXBoLmdldFJvb3ROb2RlcygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuWPtuWtkOiKgueCue+8jOWNs+ayoeaciei+k+WHuui+ueeahOiKgueCuVwiLCB0aGlzLmdyYXBoLmdldExlYWZOb2RlcygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuaVsOmHj1wiLCB0aGlzLmdyYXBoLmdldENlbGxDb3VudCgpKTtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLmdyYXBoKTtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLnN0ZW5jaWwuZ3JhcGhzLmdyb3VwMS5nZXROb2RlcygpKTtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLmdyYXBoLmdldExlYWZOb2RlcygpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBub2RlOiBhbnkgPSBub2Rlc1tpXTtcbiAgICAgIGlmIChub2RlW1wibGFiZWxcIl0gIT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKFwi55WM6Z2i5b+F6aG75YyF5ZCr6L6T5Ye6XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBncmFocEluaXQoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgLy8gI3JlZ2lvbiDliJ3lp4vljJbnlLvluINcbiAgICB0aGlzLmdyYXBoID0gbmV3IEdyYXBoKHtcbiAgICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJncmFwaC1jb250YWluZXJcIikhLFxuICAgICAgZ3JpZDogdHJ1ZSxcbiAgICAgIGhpc3Rvcnk6IHRydWUsXG4gICAgICBtaW5pbWFwOiB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtaW5pbWFwXCIpISxcbiAgICAgICAgd2lkdGg6IDE5OCxcbiAgICAgICAgaGVpZ2h0OiAxOTgsXG4gICAgICAgIHBhZGRpbmc6IDEwLFxuICAgICAgfSxcbiAgICAgIG1vdXNld2hlZWw6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgem9vbUF0TW91c2VQb3NpdGlvbjogdHJ1ZSxcbiAgICAgICAgbW9kaWZpZXJzOiBcImN0cmxcIixcbiAgICAgICAgbWluU2NhbGU6IDAuNSxcbiAgICAgICAgbWF4U2NhbGU6IDMsXG4gICAgICB9LFxuICAgICAgY29ubmVjdGluZzoge1xuICAgICAgICByb3V0ZXI6IFwibWFuaGF0dGFuXCIsXG4gICAgICAgIGNvbm5lY3Rvcjoge1xuICAgICAgICAgIG5hbWU6IFwicm91bmRlZFwiLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIHJhZGl1czogOCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBhbmNob3I6IFwiY2VudGVyXCIsXG4gICAgICAgIGNvbm5lY3Rpb25Qb2ludDogXCJhbmNob3JcIixcbiAgICAgICAgYWxsb3dCbGFuazogZmFsc2UsXG4gICAgICAgIHNuYXA6IHtcbiAgICAgICAgICByYWRpdXM6IDIwLFxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVFZGdlKCkge1xuICAgICAgICAgIHJldHVybiBuZXcgU2hhcGUuRWRnZSh7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBcIiNBMkIxQzNcIixcbiAgICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMixcbiAgICAgICAgICAgICAgICB0YXJnZXRNYXJrZXI6IHtcbiAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYmxvY2tcIixcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMixcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHpJbmRleDogMCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8g5Zyo56e75Yqo6L6555qE5pe25YCZ5Yik5pat6L+e5o6l5piv5ZCm5pyJ5pWIXG4gICAgICAgIHZhbGlkYXRlQ29ubmVjdGlvbih7XG4gICAgICAgICAgc291cmNlVmlldyxcbiAgICAgICAgICB0YXJnZXRWaWV3LFxuICAgICAgICAgIHNvdXJjZU1hZ25ldCxcbiAgICAgICAgICB0YXJnZXRNYWduZXQsXG4gICAgICAgICAgc291cmNlQ2VsbCxcbiAgICAgICAgICB0YXJnZXRDZWxsLFxuICAgICAgICB9KSB7XG4gICAgICAgICAgaWYgKHRhcmdldE1hZ25ldCAmJiB0YXJnZXRDZWxsKSB7XG4gICAgICAgICAgICBjb25zdCBpbmNvbWluZ0VkZ2VzID1cbiAgICAgICAgICAgICAgdGhhdC5ncmFwaCEuZ2V0SW5jb21pbmdFZGdlcyh0YXJnZXRDZWxsKSB8fCBbXTtcbiAgICAgICAgICAgIGlmIChpbmNvbWluZ0VkZ2VzLmxlbmd0aCA+PSB0YXJnZXRWaWV3IS5jZWxsLmdldERhdGEoKS5vdXQpIHtcbiAgICAgICAgICAgICAgdGhhdC5tZXNzYWdlLmVycm9yKFwi6LaF5Ye6b3V05pWw6YePXCIpO1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8g5LiN5YWB6K646L+e5o6l5Yiw6Ieq5bexXG4gICAgICAgICAgaWYgKHNvdXJjZVZpZXcgPT09IHRhcmdldFZpZXcpIHtcbiAgICAgICAgICAgIC8vIHRoYXQubWVzc2FnZS5lcnJvcihcIuS4jeWFgeiuuOi/nuaOpeWIsOiHquW3sVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDlj6rog73ku47ovpPlh7rpk77mjqXmoanliJvlu7rov57mjqVcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhc291cmNlTWFnbmV0IHx8XG4gICAgICAgICAgICBzb3VyY2VNYWduZXQuZ2V0QXR0cmlidXRlKFwicG9ydC1ncm91cFwiKSA9PT0gXCJsZWZ0XCJcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIHRoYXQubWVzc2FnZS5lcnJvcihcIuWPquiDveS7jui+k+WHuumTvuaOpeahqeWIm+W7uui/nuaOpVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDlj6rog73ov57mjqXliLDovpPlhaXpk77mjqXmoalcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGFyZ2V0TWFnbmV0IHx8XG4gICAgICAgICAgICB0YXJnZXRNYWduZXQuZ2V0QXR0cmlidXRlKFwicG9ydC1ncm91cFwiKSA9PT0gXCJyaWdodFwiXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyB0aGF0Lm1lc3NhZ2UuZXJyb3IoXCLlj6rog73ov57mjqXliLDovpPlhaXpk77mjqXmoalcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiAhIXRhcmdldE1hZ25ldDtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBoaWdobGlnaHRpbmc6IHtcbiAgICAgICAgbWFnbmV0QWRzb3JiZWQ6IHtcbiAgICAgICAgICBuYW1lOiBcInN0cm9rZVwiLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgIGZpbGw6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlc2l6aW5nOiB0cnVlLFxuICAgICAgcm90YXRpbmc6IHRydWUsXG4gICAgICBzZWxlY3Rpbmc6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcnViYmVyYmFuZDogdHJ1ZSxcbiAgICAgICAgc2hvd05vZGVTZWxlY3Rpb25Cb3g6IHRydWUsXG4gICAgICB9LFxuICAgICAgc25hcGxpbmU6IHRydWUsXG4gICAgICBrZXlib2FyZDogdHJ1ZSxcbiAgICAgIGNsaXBib2FyZDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc3RlbmNpbCA9IG5ldyBBZGRvbi5TdGVuY2lsKHtcbiAgICAgIHRhcmdldDogdGhpcy5ncmFwaCxcbiAgICAgIHN0ZW5jaWxHcmFwaFdpZHRoOiAyMDAsXG4gICAgICBzdGVuY2lsR3JhcGhIZWlnaHQ6IDE4MCxcbiAgICAgIGNvbGxhcHNhYmxlOiB0cnVlLFxuICAgICAgZ3JvdXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogXCLmlbDmja7lpITnkIZcIixcbiAgICAgICAgICBuYW1lOiBcImdyb3VwMVwiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGl0bGU6IFwi6L6T5YWl6L6T5Ye6XCIsXG4gICAgICAgICAgbmFtZTogXCJncm91cDJcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBsYXlvdXRPcHRpb25zOiB7XG4gICAgICAgIGNvbHVtbnM6IDIsXG4gICAgICAgIGNvbHVtbldpZHRoOiA4MCxcbiAgICAgICAgcm93SGVpZ2h0OiA1NSxcbiAgICAgIH0sXG4gICAgICB2YWxpZGF0ZU5vZGUoY3VycmVudG5vZGU6IGFueSkge1xuICAgICAgICBjb25zdCBub2RlcyA9IHRoYXQuZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICAgICAgaWYgKG5vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZTogYW55ID0gbm9kZXNbaV07XG4gICAgICAgICAgICBpZiAoY3VycmVudG5vZGVbXCJsYWJlbFwiXSA9PT0gXCLovpPlh7pcIiAmJiBub2RlW1wibGFiZWxcIl0gPT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICBnZXREcm9wTm9kZShub2RlOiBhbnkpIHtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IG5vZGUuc2l6ZSgpO1xuICAgICAgICBpZiAobm9kZVtcImxhYmVsXCJdID09PSBcIui+k+WFpVwiKSB7XG4gICAgICAgICAgdGhhdC5nZXRNb2RhbChub2RlW1wibGFiZWxcIl0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlW1wibGFiZWxcIl0gPT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgICByMi5hdHRyKFwiYm9keS9maWxsXCIsIFwiI2NjY1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub2RlLmNsb25lKCkuc2l6ZShzaXplLndpZHRoICogMS4xLCBzaXplLmhlaWdodCAqIDEuMSk7XG4gICAgICB9LFxuICAgIH0pO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3RlbmNpbFwiKSEuYXBwZW5kQ2hpbGQodGhpcy5zdGVuY2lsLmNvbnRhaW5lcik7XG5cbiAgICAvLyAjcmVnaW9uIOWIneWni+WMluWbvuW9olxuICAgIC8vIOW4uOinhOW3puWPs+S4pOS4quahqVxuICAgIGNvbnN0IHBvcnRzID0ge1xuICAgICAgZ3JvdXBzOiB7XG4gICAgICAgIHJpZ2h0OiB7XG4gICAgICAgICAgcG9zaXRpb246IFwicmlnaHRcIixcbiAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgY2lyY2xlOiB7XG4gICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgIG1hZ25ldDogdHJ1ZSxcbiAgICAgICAgICAgICAgc3Ryb2tlOiBcIiM1Rjk1RkZcIixcbiAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgICAgIGZpbGw6IFwiI2ZmZlwiLFxuICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGxlZnQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJsZWZ0XCIsXG4gICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIGNpcmNsZToge1xuICAgICAgICAgICAgICByOiA0LFxuICAgICAgICAgICAgICBtYWduZXQ6IHRydWUsXG4gICAgICAgICAgICAgIHN0cm9rZTogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgICBmaWxsOiBcIiNmZmZcIixcbiAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBcImhpZGRlblwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogXCJwb3J0MVwiLFxuICAgICAgICAgIGdyb3VwOiBcImxlZnRcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiBcInBvcnQyXCIsXG4gICAgICAgICAgZ3JvdXA6IFwicmlnaHRcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIC8vIOi+k+WFpeWPquacieW3puS+p+S4gOS4quahqVxuICAgIGNvbnN0IHBvcnRzMiA9IHtcbiAgICAgIGdyb3Vwczoge1xuICAgICAgICBsZWZ0OiB7XG4gICAgICAgICAgcG9zaXRpb246IFwibGVmdFwiLFxuICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICBjaXJjbGU6IHtcbiAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgbWFnbmV0OiB0cnVlLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICAgICAgZmlsbDogXCIjZmZmXCIsXG4gICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFwicG9ydDFcIixcbiAgICAgICAgICBncm91cDogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICAvLyDovpPlh7rlj6rmnInlj7PkvqfkuIDkuKrmoalcbiAgICBjb25zdCBwb3J0czMgPSB7XG4gICAgICBncm91cHM6IHtcbiAgICAgICAgcmlnaHQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJyaWdodFwiLFxuICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICBjaXJjbGU6IHtcbiAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgbWFnbmV0OiB0cnVlLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICAgICAgZmlsbDogXCIjZmZmXCIsXG4gICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFwicG9ydDJcIixcbiAgICAgICAgICBncm91cDogXCJyaWdodFwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuXG4gICAgY29uc3QgcjEgPSB0aGlzLmdyYXBoLmNyZWF0ZU5vZGUoe1xuICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgIGlkOiBcImluXCIsXG4gICAgICBsYWJlbDogXCLovpPlhaVcIixcbiAgICAgIHBvcnRzOiB7IC4uLnBvcnRzMyB9LFxuICAgICAgZGF0YToge1xuICAgICAgICBpbjogMCxcbiAgICAgICAgb3V0OiAzLCAvL+WPquiDveWHuuWOuzPmnaHnur9cbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgcjIgPSB0aGlzLmdyYXBoLmNyZWF0ZU5vZGUoe1xuICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgIGlkOiBcIm91dFwiLFxuICAgICAgbGFiZWw6IFwi6L6T5Ye6XCIsXG4gICAgICBwb3J0czogeyAuLi5wb3J0czIgfSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgaW46IDIsXG4gICAgICAgIG91dDogMixcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBub2RlQXJyOiBhbnlbXSA9IFtdO1xuICAgIHRoaXMubWVudUxpc3QuZm9yRWFjaCgoZWxlbWVudDogYW55LCBpKSA9PiB7XG4gICAgICBub2RlQXJyLnB1c2goXG4gICAgICAgIHRoaXMuZ3JhcGguY3JlYXRlTm9kZSh7XG4gICAgICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgICAgICBsYWJlbDogZWxlbWVudC50aXRsZSxcbiAgICAgICAgICBwb3J0czogeyAuLi5wb3J0cyB9LFxuICAgICAgICAgIGRhdGE6IGVsZW1lbnQuZGF0YSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0ZW5jaWwubG9hZChbcjEsIHIyXSwgXCJncm91cDFcIik7XG4gICAgdGhpcy5zdGVuY2lsLmxvYWQoWy4uLm5vZGVBcnJdLCBcImdyb3VwMlwiKTtcbiAgfVxuXG4gIGdyYXBoRXZlbnQoKSB7XG4gICAgLy8gZGVsZXRlXG4gICAgdGhpcy5ncmFwaC5iaW5kS2V5KFwiYmFja3NwYWNlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNlbGxzID0gdGhpcy5ncmFwaC5nZXRTZWxlY3RlZENlbGxzKCk7XG4gICAgICBpZiAoY2VsbHMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuZ3JhcGgucmVtb3ZlQ2VsbHMoY2VsbHMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8g5o6n5Yi26L+e5o6l5qGp5pi+56S6L+makOiXj1xuICAgIGNvbnN0IHNob3dQb3J0cyA9IChwb3J0czogTm9kZUxpc3RPZjxTVkdFbGVtZW50Piwgc2hvdzogYm9vbGVhbikgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBvcnRzLmxlbmd0aDsgaSA8IGxlbjsgaSA9IGkgKyAxKSB7XG4gICAgICAgIHBvcnRzW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBzaG93ID8gXCJ2aXNpYmxlXCIgOiBcImhpZGRlblwiO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5ncmFwaC5vbihcIm5vZGU6bW91c2VlbnRlclwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImdyYXBoLWNvbnRhaW5lclwiKSE7XG4gICAgICBjb25zdCBwb3J0cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBcIi54Ni1wb3J0LWJvZHlcIlxuICAgICAgKSBhcyBOb2RlTGlzdE9mPFNWR0VsZW1lbnQ+O1xuICAgICAgc2hvd1BvcnRzKHBvcnRzLCB0cnVlKTtcbiAgICB9KTtcbiAgICB0aGlzLmdyYXBoLm9uKFwibm9kZTptb3VzZWxlYXZlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZ3JhcGgtY29udGFpbmVyXCIpITtcbiAgICAgIGNvbnN0IHBvcnRzID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIF