kre-form
Version:
本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装
642 lines • 53.7 kB
JavaScript
/**
* @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 ><</span\n >\n <span\n (click)=\"handleRedo()\"\n [ngClass]=\"{ on: graph.history.canRedo() }\"\n class=\"toolbar-btn-off\"\n >></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