verben-workflow-ui 0.5.61 → 0.5.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,6 +58,13 @@ export class DesignerCanvasComponent {
58
58
  pendingDecisionConnection = null;
59
59
  pendingConnectionSourcePoint = null;
60
60
  pendingConnectionSourceSwimlaneIndex = null;
61
+ // ─── Node-drag state ───────────────────────────────────────────────────────
62
+ isDraggingNode = false;
63
+ draggingNode = null;
64
+ draggingNodeSwimlaneIndex = -1;
65
+ /** Mouse offset relative to node top-left at drag start (absolute canvas coords). */
66
+ dragOffsetX = 0;
67
+ dragOffsetY = 0;
61
68
  showDecisionConditionDialog = false;
62
69
  showConditionsDialog = false;
63
70
  activeDecisionNodeId = '';
@@ -298,6 +305,126 @@ export class DesignerCanvasComponent {
298
305
  this.potentialTargetPointId = null;
299
306
  }
300
307
  }
308
+ // ─────────────────────────────────────────────────────────────────────────
309
+ // Node drag logic
310
+ // ─────────────────────────────────────────────────────────────────────────
311
+ /**
312
+ * Called from the template when the user presses the mouse button on a node.
313
+ * Starts the drag interaction and registers document-level listeners so the
314
+ * drag continues even when the cursor leaves the SVG canvas.
315
+ */
316
+ onNodeMouseDown(event, node, swimlaneIndex) {
317
+ // Do not interfere with connection dragging or open popups
318
+ if (this.state.isConnectionDragging() ||
319
+ this.popupVisible ||
320
+ this.showStartNodeFormPopup ||
321
+ this.showSubflowPopup)
322
+ return;
323
+ event.stopPropagation(); // Prevent onCanvasClick from firing
324
+ event.preventDefault();
325
+ const position = this.getMousePosition(event);
326
+ // Template formula: absoluteSVGY = node.y + swimlane.order * 263
327
+ const absoluteNodeY = node.y + swimlaneIndex * this.swimlaneHeight;
328
+ this.isDraggingNode = true;
329
+ this.draggingNode = node;
330
+ this.draggingNodeSwimlaneIndex = swimlaneIndex;
331
+ // Store the offset from the node's top-left so the node doesn't jump
332
+ this.dragOffsetX = position.x - node.x;
333
+ this.dragOffsetY = position.y - absoluteNodeY;
334
+ document.addEventListener('mousemove', this.onNodeDragMove);
335
+ document.addEventListener('mouseup', this.onNodeDragEnd);
336
+ }
337
+ /**
338
+ * Arrow function (preserves `this`) — runs on every mousemove while dragging
339
+ * a node. Updates node.x / node.y in-place so Angular's change detection
340
+ * picks it up and redraws the node and all connected paths automatically.
341
+ */
342
+ onNodeDragMove = (event) => {
343
+ if (!this.isDraggingNode || !this.draggingNode)
344
+ return;
345
+ const position = this.getMousePosition(event);
346
+ // Raw desired absolute position of the node top-left
347
+ const rawAbsoluteX = position.x - this.dragOffsetX;
348
+ const rawAbsoluteY = position.y - this.dragOffsetY;
349
+ // Determine which swimlane the node is being dragged into (by cursor Y)
350
+ let targetSwimlaneIndex = Math.floor(position.y / this.swimlaneHeight);
351
+ targetSwimlaneIndex = Math.max(0, Math.min(targetSwimlaneIndex, this.state.swimlanes.length - 1));
352
+ const swimlaneTopY = targetSwimlaneIndex * this.swimlaneHeight;
353
+ const swimlaneBottomY = swimlaneTopY + this.swimlaneHeight;
354
+ const padding = 5;
355
+ // X: keep node fully on canvas (no left/right boundary needed for swimlanes)
356
+ const newAbsoluteX = Math.max(padding, rawAbsoluteX);
357
+ // Y: clamp so the node stays inside the targeted swimlane
358
+ let newAbsoluteY = rawAbsoluteY;
359
+ const node = this.draggingNode;
360
+ if (newAbsoluteY < swimlaneTopY + padding) {
361
+ newAbsoluteY = swimlaneTopY + padding;
362
+ }
363
+ else if (newAbsoluteY + node.height > swimlaneBottomY - padding) {
364
+ newAbsoluteY = swimlaneBottomY - node.height - padding;
365
+ }
366
+ // Convert absolute Y to swimlane-relative Y for storage
367
+ const newRelativeY = newAbsoluteY - targetSwimlaneIndex * this.swimlaneHeight;
368
+ // Live preview: update position directly.
369
+ // Template formula: absoluteSVGY = node.y + swimlane.order * 263
370
+ // => node.y = absoluteY - swimlane.order * 263 (swimlane-relative)
371
+ // The node is STILL in the source swimlane's array during preview,
372
+ // so swimlane.order = draggingNodeSwimlaneIndex.
373
+ node.x = newAbsoluteX;
374
+ node.y = newAbsoluteY - this.draggingNodeSwimlaneIndex * this.swimlaneHeight;
375
+ // Store computed values for onNodeDragEnd
376
+ this._pendingTargetSwimlaneIndex = targetSwimlaneIndex;
377
+ this._pendingAbsoluteY = newAbsoluteY;
378
+ };
379
+ /** Scratch fields used to pass computed values from move → end handlers. */
380
+ _pendingTargetSwimlaneIndex = -1;
381
+ _pendingAbsoluteY = 0;
382
+ /**
383
+ * Arrow function (preserves `this`) — fires on mouseup after a node drag.
384
+ * Finalises the node position and performs swimlane migration if necessary.
385
+ */
386
+ onNodeDragEnd = (_event) => {
387
+ document.removeEventListener('mousemove', this.onNodeDragMove);
388
+ document.removeEventListener('mouseup', this.onNodeDragEnd);
389
+ if (!this.isDraggingNode || !this.draggingNode) {
390
+ this.isDraggingNode = false;
391
+ this.draggingNode = null;
392
+ return;
393
+ }
394
+ const node = this.draggingNode;
395
+ const fromIndex = this.draggingNodeSwimlaneIndex;
396
+ const toIndex = this._pendingTargetSwimlaneIndex !== -1
397
+ ? this._pendingTargetSwimlaneIndex
398
+ : fromIndex;
399
+ const absoluteY = this._pendingAbsoluteY;
400
+ if (fromIndex !== toIndex) {
401
+ // Cross-swimlane drop: state helper moves node between arrays,
402
+ // updates connections, and syncs tags. It also sets node.y correctly.
403
+ this.state.moveNodeToSwimlane(node.id, fromIndex, toIndex, node.x, absoluteY);
404
+ }
405
+ else {
406
+ // Same swimlane: node.y = absoluteY - swimlane.order * 263 (swimlane-relative)
407
+ node.y = absoluteY - fromIndex * this.swimlaneHeight;
408
+ }
409
+ // Reset drag state
410
+ this.isDraggingNode = false;
411
+ this.draggingNode = null;
412
+ this.draggingNodeSwimlaneIndex = -1;
413
+ this.dragOffsetX = 0;
414
+ this.dragOffsetY = 0;
415
+ this._pendingTargetSwimlaneIndex = -1;
416
+ this._pendingAbsoluteY = 0;
417
+ };
418
+ /**
419
+ * Returns a CSS cursor value for the node rendering.
420
+ * Shows 'grabbing' while the node is being dragged, 'grab' otherwise.
421
+ */
422
+ getCursorForNode(nodeId) {
423
+ return this.isDraggingNode && this.draggingNode?.id === nodeId ? 'grabbing' : 'grab';
424
+ }
425
+ // ─────────────────────────────────────────────────────────────────────────
426
+ // Connection drag logic (existing)
427
+ // ─────────────────────────────────────────────────────────────────────────
301
428
  // Use arrow functions to preserve 'this' context
302
429
  onMouseMove = (event) => {
303
430
  const position = this.getMousePosition(event);
@@ -1052,11 +1179,11 @@ export class DesignerCanvasComponent {
1052
1179
  });
1053
1180
  }
1054
1181
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DesignerCanvasComponent, deps: [{ token: i1.WorkflowDesignerState }, { token: i2.WorkflowDataService }], target: i0.ɵɵFactoryTarget.Component });
1055
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DesignerCanvasComponent, selector: "lib-designer-canvas", inputs: { selectedTool: "selectedTool" }, outputs: { clickedPosition: "clickedPosition", subflowSelected: "subflowSelected", stagePropertiesUpdated: "stagePropertiesUpdated", actionPropertiesUpdated: "actionPropertiesUpdated" }, host: { listeners: { "window:mouseup": "onWindowMouseUp($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"canvas-container\">\n <svg #canvas [attr.width]=\"canvasWidth\" [attr.height]=\"canvasHeight\" class=\"designer-canvas\"\n (click)=\"onCanvasClick($event)\">\n <defs>\n <!-- Grid pattern definition -->\n\n <pattern id=\"grid\" [attr.width]=\"gridSize\" [attr.height]=\"gridSize\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 20 0 L 0 0 0 20\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"0.5\" />\n </pattern>\n\n <!-- Arrow head marker definition -->\n <marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#D36CFF\" />\n </marker>\n\n <!-- Connection point styles -->\n <circle id=\"connection-point-template\" r=\"5\" fill=\"#D36CFF\" stroke=\"#FFFFFF\" stroke-width=\"1\" />\n\n <!-- Dashed line style for connection preview -->\n <pattern id=\"dashed-line\" width=\"10\" height=\"10\" patternUnits=\"userSpaceOnUse\">\n <line x1=\"0\" y1=\"5\" x2=\"10\" y2=\"5\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" />\n </pattern>\n\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <clipPath [attr.id]=\"'swimlane-clip-' + swimlane.order\">\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" height=\"263\" />\n </clipPath>\n }\n </defs>\n\n <!-- Background grid -->\n <rect width=\"100%\" height=\"100%\" fill=\"url(#grid)\" />\n\n <!-- Display a message when no swimlanes exist -->\n @if (state.swimlanes.length === 0) {\n <text x=\"50%\" y=\"50%\" font-family=\"sans-serif\" font-size=\"16\" fill=\"#94a3b8\" text-anchor=\"middle\">\n Select the Swimlane tool and click on the canvas to add a swimlane\n </text>\n }\n\n <!-- This is where workflow elements will be added later -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- <g\n [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\"\n [attr.clip-path]=\"'url(#swimlane-clip-' + swimlane.order + ')'\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n [attr.height]=\"263\"\n fill=\"#ffffff\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n height=\"40\"\n fill=\"#f8fafc\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <text\n x=\"20\"\n y=\"25\"\n font-family=\"sans-serif\"\n font-size=\"14\"\n fill=\"#333333\"\n font-weight=\"bold\"\n >\n {{ swimlane.label }}\n </text>\n\n <g\n class=\"edit-swimlane-button\"\n [attr.transform]=\"'translate(100, 20)'\"\n (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \"\n >\n <rect\n x=\"-5\"\n y=\"-15\"\n width=\"40\"\n height=\"20\"\n fill=\"#f3e8ff\"\n rx=\"3\"\n ry=\"3\"\n stroke=\"#d8b4fe\"\n stroke-width=\"1\"\n ></rect>\n <text\n x=\"15\"\n y=\"0\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#7e22ce\"\n text-anchor=\"middle\"\n >\n Edit\n </text>\n </g>\n\n <g [attr.transform]=\"'translate(200, 20)'\">\n @for (tag of swimlane.tags.slice(0, 3); track tag.Name; let i = $index)\n {\n <text\n [attr.x]=\"i * 100\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n {{ tag.Name }}\n </text>\n } @if (swimlane.tags.length > 3) {\n <text\n [attr.x]=\"3 * 100 + 10\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n +{{ swimlane.tags.length - 3 }} more\n </text>\n }\n </g>\n </g> -->\n\n <g [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\">\n <!-- Swimlane container - remove stroke to make it purely background -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" [attr.height]=\"263\"\n [attr.fill]=\"swimlane.order % 2 === 0 ? '#FCF3FF' : '#ECFFF5'\" stroke=\"none\"></rect>\n\n <!-- Vertical swimlane label on the left -->\n <g class=\"swimlane-label\">\n <!-- Purple background for the label -->\n <rect x=\"0.5\" y=\"0.5\" width=\"43\" height=\"215\" rx=\"10.5\" fill=\"white\" stroke=\"#D36CFF\"></rect>\n\n <!-- Plus button at the top -->\n <g (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \">\n <rect x=\"12.5\" y=\"10\" width=\"18\" height=\"18\" fill=\"transparent\" style=\"cursor: pointer\"></rect>\n\n <path d=\"M22.52 12.174V17.08H27.47V18.51H22.52V23.394H21.2V18.51H16.25V17.08H21.2V12.174H22.52Z\"\n fill=\"#0000FF\" class=\"plus-icon\" style=\"cursor: pointer\"></path>\n </g>\n\n <!-- Swimlane label -->\n <text x=\"22\" y=\"106\" font-family=\"sans-serif\" font-size=\"14\" fill=\"#333333\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 100)\">\n {{\n swimlane.label.length > 12\n ? swimlane.label.substring(0, 10) + \"...\"\n : swimlane.label\n }}\n </text>\n\n <!-- Tag count indicator at the bottom -->\n <rect x=\"11.5\" y=\"187\" width=\"21\" height=\"19\" rx=\"9.5\" fill=\"#9E9E9E\"></rect>\n <text x=\"24\" y=\"206\" font-family=\"sans-serif\" font-size=\"12\" fill=\"black\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 200)\">\n {{ swimlane.tags.length }}\n </text>\n </g>\n </g>\n\n }\n\n <!-- Nodes -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- Render nodes in this swimlane -->\n @for (node of swimlane.nodes; track node.id) {\n <g class=\"node-element\" [attr.transform]=\"\n 'translate(' + node.x + ',' + (node.y - swimlane.order * 263) + ')'\n \" (mouseenter)=\"showConnectionPoints(node.id, swimlane.order)\" (mouseleave)=\"hideConnectionPoints(node.id)\">\n <!-- Start node indicator (circle and arrow) for the first node -->\n @if (node.isStartNode) {\n <!-- Circle -->\n <circle cx=\"-50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></circle>\n <!-- Form icon for start node -->\n <svg:g (click)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order)\n \" class=\"stage-icon\" transform=\"translate(-45, 42)\" style=\"cursor: pointer; pointer-events: all\">\n <!-- Transparent rectangle to capture clicks -->\n <svg:rect x=\"-2\" y=\"-2\" width=\"24\" height=\"24\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path\n d=\"M16.5 20.475V17.475H13.5V16.475H16.5V13.475H17.5V16.475H20.5V17.475H17.5V20.475H16.5ZM3.5 17.5V16.5H4.5V17.5H3.5ZM6.5 17.5V16.5H11.517C11.5057 16.6767 11.5043 16.845 11.513 17.005C11.521 17.165 11.531 17.33 11.543 17.5H6.5ZM3.5 13.5V12.5H4.5V13.5H3.5ZM6.5 13.5V12.5H13.804C13.6127 12.6387 13.4333 12.7913 13.266 12.958C13.0993 13.1247 12.9377 13.3053 12.781 13.5H6.5ZM3.5 9.5V8.5H4.5V9.5H3.5ZM6.5 9.5V8.5H18.5V9.5H6.5ZM3.5 5.5V4.5H4.5V5.5H3.5ZM6.5 5.5V4.5H18.5V5.5H6.5Z\"\n [attr.fill]=\"state.workflowFormId ? '#D36CFF' : 'black'\" transform=\"scale(0.7)\" />\n </svg:g>\n <!-- Arrow from circle to node -->\n <path d=\"M -20 50 L 0 50\" stroke=\"#D36CFF\" stroke-width=\"1\" marker-end=\"url(#arrowhead)\"></path>\n }\n\n <!-- Exit point indicator (circle and arrow) -->\n @if (node.stageData?.IsExitPoint) {\n <!-- Arrow from node to circle -->\n <path [attr.d]=\"'M ' + node.width + ' 50 L ' + (node.width + 20) + ' 50'\" stroke=\"#D36CFF\" stroke-width=\"1\"\n marker-end=\"url(#arrowhead)\"></path>\n <!-- Circle -->\n <circle [attr.cx]=\"node.width + 50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"2\"></circle>\n }\n\n <!-- Stage node -->\n @if (node.type === 'stage') {\n <!-- <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"node.width\"\n [attr.height]=\"node.height\"\n fill=\"none\"\n stroke=\"#D36CFF\"\n stroke-width=\"1\"\n ></rect> -->\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Decision node -->\n @if (node.type === 'decision') {\n <path [attr.d]=\"\n 'M 0 ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' 0' +\n ' L ' +\n node.width +\n ' ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' ' +\n node.height +\n ' Z'\n \" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></path>\n\n <!-- Decision node condition indicator icon -->\n <svg:g (click)=\"showDecisionConditionsPopup($event, node, swimlane.order)\" class=\"decision-condition-icon\"\n [attr.transform]=\"\n 'translate(' +\n (node.width / 2 - 10) +\n ',' +\n (node.height / 2 - 10) +\n ')'\n \">\n <svg:rect x=\"-5\" y=\"-5\" width=\"30\" height=\"30\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path d=\"M10 0H20V2H10V0ZM10 8H20V10H10V8ZM10 4H20V6H10V4ZM0 0H8V2H0V0ZM0 8H8V10H0V8ZM0 4H8V6H0V4Z\"\n fill=\"#D36CFF\" />\n </svg:g>\n }\n\n <!-- Form node -->\n @if (node.type === 'form') {\n <path\n d=\"M95.0625 50.5591V95.0625C95.0625 97.9716 93.9069 100.762 91.8498 102.819C89.7928 104.876 87.0028 106.031 84.0938 106.031H32.9062C29.9972 106.031 27.2072 104.876 25.1502 102.819C23.0931 100.762 21.9375 97.9716 21.9375 95.0625V21.9375C21.9375 19.0284 23.0931 16.2385 25.1502 14.1814C27.2072 12.1244 29.9972 10.9688 32.9062 10.9688H55.4722C57.4109 10.969 59.2701 11.7392 60.6412 13.1099L92.9213 45.3901C94.292 46.7611 95.0622 48.6204 95.0625 50.5591Z\"\n transform=\"scale(0.7)\" fill=\"none\" stroke=\"#D36CFF\" stroke-linejoin=\"round\" />\n <path\n d=\"M58.5 12.7969V40.2188C58.5 42.1581 59.2704 44.0181 60.6418 45.3895C62.0131 46.7608 63.8731 47.5312 65.8125 47.5312H93.2344\"\n transform=\"scale(0.7)\" stroke=\"#D36CFF\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"sans-serif\" font-size=\"14\"\n fill=\"#D36CFF\">\n Form\n </text>\n }\n\n <!-- Subflow node -->\n @if (node.type === 'subflow') {\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\" [isSubflow]=\"true\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Connection points for this node -->\n @for (point of node.connectionPoints || []; track point.id) { @if\n (isConnectionPointVisible(node.id)) {\n <use [attr.href]=\"'#connection-point-template'\" [attr.x]=\"point.x\" [attr.y]=\"point.y\" [attr.id]=\"point.id\"\n (mousedown)=\"startConnectionDrag($event, point, swimlane.order)\" />\n } }\n </g>\n <!-- A transparent hover area for improved hover detection -->\n <rect [attr.x]=\"node.x - 10\" [attr.y]=\"node.y - 10\" [attr.width]=\"node.width + 20\" [attr.height]=\"node.height + 20\"\n fill=\"transparent\" (mouseover)=\"showConnectionPoints(node.id, swimlane.order)\"\n (mouseout)=\"hideConnectionPoints(node.id)\" style=\"pointer-events: none\" />\n } }\n\n <!-- Connections -->\n @for (connection of state.connections; track connection.id) {\n <g class=\"connection-element\">\n <path [attr.d]=\"getConnectionPathForSavedConnection(connection)\" stroke=\"#D36CFF\" stroke-width=\"2\" fill=\"none\"\n marker-end=\"url(#arrowhead)\"></path>\n\n <!-- Connection Label -->\n @if (connection.sourceNodeId && connection.targetNodeId) {\n <foreignObject [attr.x]=\"getLabelPosition(connection).x\" [attr.y]=\"getLabelPosition(connection).y\" width=\"150\"\n height=\"40\" style=\"overflow: visible; pointer-events: all;\" [attr.transform]=\"'translate(-75, -10)'\">\n <wf-label-editor [label]=\"connection.label || 'New Action'\" [x]=\"0\" [y]=\"0\" [isConnection]=\"true\"\n (labelChange)=\"saveConnectionLabel(connection, $event)\" (openDialog)=\"onShowActionDialog(connection)\" />\n </foreignObject>\n }\n </g>\n }\n\n <!-- Connection preview line -->\n @if (state.isConnectionDragging()) {\n <g>\n <path [attr.d]=\"getConnectionPath()\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" fill=\"none\"></path>\n </g>\n }\n </svg>\n\n <div *ngIf=\"popupVisible\" [style.position]=\"'absolute'\" [style.left.px]=\"popupX\" [style.top.px]=\"popupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '99' }\" [enableMouseLeave]=\"false\"\n (dropdownOpenChange)=\"$event ? null : hideConnectionPopup()\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md\" dropdown-content>\n <h4 class=\"mb-2 font-medium\">Create Connection</h4>\n <div class=\"flex flex-col gap-2\">\n <ng-container *ngFor=\"let type of allowedNodeTypes\">\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"createNodeConnection(type)\">\n Create {{ type | titlecase }}\n </button>\n </ng-container>\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"hideConnectionPopup()\">\n Cancel\n </button>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showStartNodeFormPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"startNodeFormPopupX\"\n [style.top.px]=\"startNodeFormPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow Form</h4>\n <div *ngIf=\"isLoadingStartNodeForms\" class=\"text-center py-2\">\n Loading forms...\n </div>\n <div *ngIf=\"!isLoadingStartNodeForms\" class=\"max-h-48 overflow-y-auto\">\n <div class=\"mb-3\">\n <button\n class=\"w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectStartNodeForm(null)\">\n Clear form selection\n </button>\n </div>\n <div *ngFor=\"let form of startNodeFormsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n [ngClass]=\"{ 'bg-blue-50 !border-blue-500 !border-2 font-semibold': form?.Code === activeNodeForFormSelection?.stageData?.formId}\"\n (click)=\"selectStartNodeForm(form)\">\n {{ form.Name }}\n </button>\n </div>\n <div *ngIf=\"startNodeFormsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No forms available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showSubflowPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"subflowPopupX\"\n [style.top.px]=\"subflowPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow</h4>\n <div *ngIf=\"isLoadingWorkflows\" class=\"text-center py-2\">\n Loading workflows...\n </div>\n <div *ngIf=\"!isLoadingWorkflows\" class=\"max-h-48 overflow-y-auto\">\n <div *ngFor=\"let workflow of workflowsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectSubflowWorkflow(workflow)\">\n {{ workflow.Name }}\n </button>\n </div>\n <div *ngIf=\"workflowsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No workflows available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <lib-conditions-popup [visible]=\"showDecisionConditionDialog\" [decisionNodeId]=\"activeDecisionNodeId\"\n [newConnectionId]=\"activeConnectionId\" [popupX]=\"decisionConditionPopupX\" [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\" (saved)=\"onDecisionConditionSaved($event)\"></lib-conditions-popup>\n\n <!-- <lib-decision-popup\n [visible]=\"showConditionsDialog\"\n [decisionNodeId]=\"activeDecisionNodeId\"\n [popupX]=\"decisionConditionPopupX\"\n [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\"\n ></lib-decision-popup> -->\n\n <lib-stage-dialog [visible]=\"showStageDialogLocal\" [stageData]=\"activeStageData || {}\"\n (closed)=\"onStageDialogClosed()\" (saved)=\"onStageDialogSaved($event)\"></lib-stage-dialog>\n\n <lib-action-dialog [visible]=\"showActionDialogLocal\" [actionData]=\"activeActionData\" (closed)=\"onActionDialogClosed()\"\n (saved)=\"onActionDialogSaved($event)\"></lib-action-dialog>\n\n <lib-escalation-dialog [visible]=\"showEscalationDialogLocal\" [type]=\"activeEscalationType()!\"\n [stageCode]=\"activeStageCode() || ''\" [workflowCode]=\"state.workflow?.Code || ''\"\n (closed)=\"onEscalationDialogClosed()\"></lib-escalation-dialog>\n</div>\n", styles: [".canvas-container{flex:1;overflow:auto;background-color:#fff}.designer-canvas{min-width:100%;min-height:100%;cursor:default}.designer-canvas:focus{outline:none}.edit-swimlane-button{cursor:pointer}.edit-swimlane-button:hover rect{fill:#ddd6fe}.decision-condition-icon{cursor:pointer}.decision-condition-icon:hover path{fill:#c084fc}.swimlane-label{z-index:10;cursor:default}.plus-icon:hover{fill:#d36cff}.swimlane-container{pointer-events:none}.swimlane-container>*{pointer-events:auto}.node-element{z-index:10}.connection-element{z-index:5}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.VerbenPopUpComponent, selector: "verben-pop-Up", inputs: ["dropdownOpen", "dropdownWidth", "color", "customStyles", "popUpClass", "border", "borderRadius", "enableMouseLeave", "cdkPosition"], outputs: ["dropdownOpenChange", "close"] }, { kind: "component", type: i5.LabelEditorComponent, selector: "wf-label-editor", inputs: ["label", "x", "y", "isConnection", "isSwimlane"], outputs: ["labelChange", "openDialog"] }, { kind: "component", type: i6.StageNodeComponent, selector: "svg:g[lib-stage-node]", inputs: ["node", "isStartNode", "isSubflow", "stageData"], outputs: ["stagePropertiesUpdated", "parallelExecutionToggled", "showShieldDialog", "showEscalationDialog", "showFormDialog"] }, { kind: "component", type: i7.StageDialogComponent, selector: "lib-stage-dialog", inputs: ["visible", "stageData"], outputs: ["closed", "saved"] }, { kind: "component", type: i8.ConditionsPopupComponent, selector: "lib-conditions-popup", inputs: ["visible", "decisionNodeId", "newConnectionId", "popupX", "popupY"], outputs: ["closed", "saved"] }, { kind: "component", type: i9.EscalationDialogComponent, selector: "lib-escalation-dialog", inputs: ["visible", "workflowCode", "stageCode", "type"], outputs: ["closed", "created"] }, { kind: "component", type: i10.ActionDialogComponent, selector: "lib-action-dialog", inputs: ["visible", "actionData"], outputs: ["closed", "saved"] }, { kind: "pipe", type: i3.TitleCasePipe, name: "titlecase" }] });
1182
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DesignerCanvasComponent, selector: "lib-designer-canvas", inputs: { selectedTool: "selectedTool" }, outputs: { clickedPosition: "clickedPosition", subflowSelected: "subflowSelected", stagePropertiesUpdated: "stagePropertiesUpdated", actionPropertiesUpdated: "actionPropertiesUpdated" }, host: { listeners: { "window:mouseup": "onWindowMouseUp($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"canvas-container\">\n <svg #canvas [attr.width]=\"canvasWidth\" [attr.height]=\"canvasHeight\" class=\"designer-canvas\"\n (click)=\"onCanvasClick($event)\">\n <defs>\n <!-- Grid pattern definition -->\n\n <pattern id=\"grid\" [attr.width]=\"gridSize\" [attr.height]=\"gridSize\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 20 0 L 0 0 0 20\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"0.5\" />\n </pattern>\n\n <!-- Arrow head marker definition -->\n <marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#D36CFF\" />\n </marker>\n\n <!-- Connection point styles -->\n <circle id=\"connection-point-template\" r=\"5\" fill=\"#D36CFF\" stroke=\"#FFFFFF\" stroke-width=\"1\" />\n\n <!-- Dashed line style for connection preview -->\n <pattern id=\"dashed-line\" width=\"10\" height=\"10\" patternUnits=\"userSpaceOnUse\">\n <line x1=\"0\" y1=\"5\" x2=\"10\" y2=\"5\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" />\n </pattern>\n\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <clipPath [attr.id]=\"'swimlane-clip-' + swimlane.order\">\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" height=\"263\" />\n </clipPath>\n }\n </defs>\n\n <!-- Background grid -->\n <rect width=\"100%\" height=\"100%\" fill=\"url(#grid)\" />\n\n <!-- Display a message when no swimlanes exist -->\n @if (state.swimlanes.length === 0) {\n <text x=\"50%\" y=\"50%\" font-family=\"sans-serif\" font-size=\"16\" fill=\"#94a3b8\" text-anchor=\"middle\">\n Select the Swimlane tool and click on the canvas to add a swimlane\n </text>\n }\n\n <!-- This is where workflow elements will be added later -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- <g\n [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\"\n [attr.clip-path]=\"'url(#swimlane-clip-' + swimlane.order + ')'\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n [attr.height]=\"263\"\n fill=\"#ffffff\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n height=\"40\"\n fill=\"#f8fafc\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <text\n x=\"20\"\n y=\"25\"\n font-family=\"sans-serif\"\n font-size=\"14\"\n fill=\"#333333\"\n font-weight=\"bold\"\n >\n {{ swimlane.label }}\n </text>\n\n <g\n class=\"edit-swimlane-button\"\n [attr.transform]=\"'translate(100, 20)'\"\n (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \"\n >\n <rect\n x=\"-5\"\n y=\"-15\"\n width=\"40\"\n height=\"20\"\n fill=\"#f3e8ff\"\n rx=\"3\"\n ry=\"3\"\n stroke=\"#d8b4fe\"\n stroke-width=\"1\"\n ></rect>\n <text\n x=\"15\"\n y=\"0\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#7e22ce\"\n text-anchor=\"middle\"\n >\n Edit\n </text>\n </g>\n\n <g [attr.transform]=\"'translate(200, 20)'\">\n @for (tag of swimlane.tags.slice(0, 3); track tag.Name; let i = $index)\n {\n <text\n [attr.x]=\"i * 100\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n {{ tag.Name }}\n </text>\n } @if (swimlane.tags.length > 3) {\n <text\n [attr.x]=\"3 * 100 + 10\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n +{{ swimlane.tags.length - 3 }} more\n </text>\n }\n </g>\n </g> -->\n\n <g [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\">\n <!-- Swimlane container - remove stroke to make it purely background -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" [attr.height]=\"263\"\n [attr.fill]=\"swimlane.order % 2 === 0 ? '#FCF3FF' : '#ECFFF5'\" stroke=\"none\"></rect>\n\n <!-- Vertical swimlane label on the left -->\n <g class=\"swimlane-label\">\n <!-- Purple background for the label -->\n <rect x=\"0.5\" y=\"0.5\" width=\"43\" height=\"215\" rx=\"10.5\" fill=\"white\" stroke=\"#D36CFF\"></rect>\n\n <!-- Plus button at the top -->\n <g (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \">\n <rect x=\"12.5\" y=\"10\" width=\"18\" height=\"18\" fill=\"transparent\" style=\"cursor: pointer\"></rect>\n\n <path d=\"M22.52 12.174V17.08H27.47V18.51H22.52V23.394H21.2V18.51H16.25V17.08H21.2V12.174H22.52Z\"\n fill=\"#0000FF\" class=\"plus-icon\" style=\"cursor: pointer\"></path>\n </g>\n\n <!-- Swimlane label -->\n <text x=\"22\" y=\"106\" font-family=\"sans-serif\" font-size=\"14\" fill=\"#333333\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 100)\">\n {{\n swimlane.label.length > 12\n ? swimlane.label.substring(0, 10) + \"...\"\n : swimlane.label\n }}\n </text>\n\n <!-- Tag count indicator at the bottom -->\n <rect x=\"11.5\" y=\"187\" width=\"21\" height=\"19\" rx=\"9.5\" fill=\"#9E9E9E\"></rect>\n <text x=\"24\" y=\"206\" font-family=\"sans-serif\" font-size=\"12\" fill=\"black\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 200)\">\n {{ swimlane.tags.length }}\n </text>\n </g>\n </g>\n\n }\n\n <!-- Nodes -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- Render nodes in this swimlane -->\n @for (node of swimlane.nodes; track node.id) {\n <g class=\"node-element\" [attr.transform]=\"\n 'translate(' + node.x + ',' + (node.y + swimlane.order * 263) + ')'\" [style.cursor]=\"getCursorForNode(node.id)\"\n (mousedown)=\"onNodeMouseDown($event, node, swimlane.order)\"\n (mouseenter)=\"showConnectionPoints(node.id, swimlane.order)\" (mouseleave)=\"hideConnectionPoints(node.id)\">\n <!-- Start node indicator (circle and arrow) for the first node -->\n @if (node.isStartNode) {\n <!-- Circle -->\n <circle cx=\"-50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></circle>\n <!-- Form icon for start node -->\n <svg:g (click)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order)\n \" class=\"stage-icon\" transform=\"translate(-45, 42)\" style=\"cursor: pointer; pointer-events: all\">\n <!-- Transparent rectangle to capture clicks -->\n <svg:rect x=\"-2\" y=\"-2\" width=\"24\" height=\"24\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path\n d=\"M16.5 20.475V17.475H13.5V16.475H16.5V13.475H17.5V16.475H20.5V17.475H17.5V20.475H16.5ZM3.5 17.5V16.5H4.5V17.5H3.5ZM6.5 17.5V16.5H11.517C11.5057 16.6767 11.5043 16.845 11.513 17.005C11.521 17.165 11.531 17.33 11.543 17.5H6.5ZM3.5 13.5V12.5H4.5V13.5H3.5ZM6.5 13.5V12.5H13.804C13.6127 12.6387 13.4333 12.7913 13.266 12.958C13.0993 13.1247 12.9377 13.3053 12.781 13.5H6.5ZM3.5 9.5V8.5H4.5V9.5H3.5ZM6.5 9.5V8.5H18.5V9.5H6.5ZM3.5 5.5V4.5H4.5V5.5H3.5ZM6.5 5.5V4.5H18.5V5.5H6.5Z\"\n [attr.fill]=\"state.workflowFormId ? '#D36CFF' : 'black'\" transform=\"scale(0.7)\" />\n </svg:g>\n <!-- Arrow from circle to node -->\n <path d=\"M -20 50 L 0 50\" stroke=\"#D36CFF\" stroke-width=\"1\" marker-end=\"url(#arrowhead)\"></path>\n }\n\n <!-- Exit point indicator (circle and arrow) -->\n @if (node.stageData?.IsExitPoint) {\n <!-- Arrow from node to circle -->\n <path [attr.d]=\"'M ' + node.width + ' 50 L ' + (node.width + 20) + ' 50'\" stroke=\"#D36CFF\" stroke-width=\"1\"\n marker-end=\"url(#arrowhead)\"></path>\n <!-- Circle -->\n <circle [attr.cx]=\"node.width + 50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"2\"></circle>\n }\n\n <!-- Stage node -->\n @if (node.type === 'stage') {\n <!-- <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"node.width\"\n [attr.height]=\"node.height\"\n fill=\"none\"\n stroke=\"#D36CFF\"\n stroke-width=\"1\"\n ></rect> -->\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Decision node -->\n @if (node.type === 'decision') {\n <path [attr.d]=\"\n 'M 0 ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' 0' +\n ' L ' +\n node.width +\n ' ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' ' +\n node.height +\n ' Z'\n \" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></path>\n\n <!-- Decision node condition indicator icon -->\n <svg:g (click)=\"showDecisionConditionsPopup($event, node, swimlane.order)\" class=\"decision-condition-icon\"\n [attr.transform]=\"\n 'translate(' +\n (node.width / 2 - 10) +\n ',' +\n (node.height / 2 - 10) +\n ')'\n \">\n <svg:rect x=\"-5\" y=\"-5\" width=\"30\" height=\"30\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path d=\"M10 0H20V2H10V0ZM10 8H20V10H10V8ZM10 4H20V6H10V4ZM0 0H8V2H0V0ZM0 8H8V10H0V8ZM0 4H8V6H0V4Z\"\n fill=\"#D36CFF\" />\n </svg:g>\n }\n\n <!-- Form node -->\n @if (node.type === 'form') {\n <path\n d=\"M95.0625 50.5591V95.0625C95.0625 97.9716 93.9069 100.762 91.8498 102.819C89.7928 104.876 87.0028 106.031 84.0938 106.031H32.9062C29.9972 106.031 27.2072 104.876 25.1502 102.819C23.0931 100.762 21.9375 97.9716 21.9375 95.0625V21.9375C21.9375 19.0284 23.0931 16.2385 25.1502 14.1814C27.2072 12.1244 29.9972 10.9688 32.9062 10.9688H55.4722C57.4109 10.969 59.2701 11.7392 60.6412 13.1099L92.9213 45.3901C94.292 46.7611 95.0622 48.6204 95.0625 50.5591Z\"\n transform=\"scale(0.7)\" fill=\"none\" stroke=\"#D36CFF\" stroke-linejoin=\"round\" />\n <path\n d=\"M58.5 12.7969V40.2188C58.5 42.1581 59.2704 44.0181 60.6418 45.3895C62.0131 46.7608 63.8731 47.5312 65.8125 47.5312H93.2344\"\n transform=\"scale(0.7)\" stroke=\"#D36CFF\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"sans-serif\" font-size=\"14\"\n fill=\"#D36CFF\">\n Form\n </text>\n }\n\n <!-- Subflow node -->\n @if (node.type === 'subflow') {\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\" [isSubflow]=\"true\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Connection points for this node -->\n @for (point of node.connectionPoints || []; track point.id) { @if\n (isConnectionPointVisible(node.id)) {\n <use [attr.href]=\"'#connection-point-template'\" [attr.x]=\"point.x\" [attr.y]=\"point.y\" [attr.id]=\"point.id\"\n (mousedown)=\"startConnectionDrag($event, point, swimlane.order)\" />\n } }\n </g>\n <!-- A transparent hover area for improved hover detection -->\n <rect [attr.x]=\"node.x - 10\" [attr.y]=\"node.y - 10\" [attr.width]=\"node.width + 20\" [attr.height]=\"node.height + 20\"\n fill=\"transparent\" (mouseover)=\"showConnectionPoints(node.id, swimlane.order)\"\n (mouseout)=\"hideConnectionPoints(node.id)\" style=\"pointer-events: none\" />\n } }\n\n <!-- Connections -->\n @for (connection of state.connections; track connection.id) {\n <g class=\"connection-element\">\n <path [attr.d]=\"getConnectionPathForSavedConnection(connection)\" stroke=\"#D36CFF\" stroke-width=\"2\" fill=\"none\"\n marker-end=\"url(#arrowhead)\"></path>\n\n <!-- Connection Label -->\n @if (connection.sourceNodeId && connection.targetNodeId) {\n <foreignObject [attr.x]=\"getLabelPosition(connection).x\" [attr.y]=\"getLabelPosition(connection).y\" width=\"150\"\n height=\"40\" style=\"overflow: visible; pointer-events: all;\" [attr.transform]=\"'translate(-75, -10)'\">\n <wf-label-editor [label]=\"connection.label || 'New Action'\" [x]=\"0\" [y]=\"0\" [isConnection]=\"true\"\n (labelChange)=\"saveConnectionLabel(connection, $event)\" (openDialog)=\"onShowActionDialog(connection)\" />\n </foreignObject>\n }\n </g>\n }\n\n <!-- Connection preview line -->\n @if (state.isConnectionDragging()) {\n <g>\n <path [attr.d]=\"getConnectionPath()\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" fill=\"none\"></path>\n </g>\n }\n </svg>\n\n <div *ngIf=\"popupVisible\" [style.position]=\"'absolute'\" [style.left.px]=\"popupX\" [style.top.px]=\"popupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '99' }\" [enableMouseLeave]=\"false\"\n (dropdownOpenChange)=\"$event ? null : hideConnectionPopup()\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md\" dropdown-content>\n <h4 class=\"mb-2 font-medium\">Create Connection</h4>\n <div class=\"flex flex-col gap-2\">\n <ng-container *ngFor=\"let type of allowedNodeTypes\">\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"createNodeConnection(type)\">\n Create {{ type | titlecase }}\n </button>\n </ng-container>\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"hideConnectionPopup()\">\n Cancel\n </button>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showStartNodeFormPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"startNodeFormPopupX\"\n [style.top.px]=\"startNodeFormPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow Form</h4>\n <div *ngIf=\"isLoadingStartNodeForms\" class=\"text-center py-2\">\n Loading forms...\n </div>\n <div *ngIf=\"!isLoadingStartNodeForms\" class=\"max-h-48 overflow-y-auto\">\n <div class=\"mb-3\">\n <button\n class=\"w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectStartNodeForm(null)\">\n Clear form selection\n </button>\n </div>\n <div *ngFor=\"let form of startNodeFormsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n [ngClass]=\"{ 'bg-blue-50 !border-blue-500 !border-2 font-semibold': form?.Code === activeNodeForFormSelection?.stageData?.formId}\"\n (click)=\"selectStartNodeForm(form)\">\n {{ form.Name }}\n </button>\n </div>\n <div *ngIf=\"startNodeFormsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No forms available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showSubflowPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"subflowPopupX\"\n [style.top.px]=\"subflowPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow</h4>\n <div *ngIf=\"isLoadingWorkflows\" class=\"text-center py-2\">\n Loading workflows...\n </div>\n <div *ngIf=\"!isLoadingWorkflows\" class=\"max-h-48 overflow-y-auto\">\n <div *ngFor=\"let workflow of workflowsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectSubflowWorkflow(workflow)\">\n {{ workflow.Name }}\n </button>\n </div>\n <div *ngIf=\"workflowsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No workflows available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <lib-conditions-popup [visible]=\"showDecisionConditionDialog\" [decisionNodeId]=\"activeDecisionNodeId\"\n [newConnectionId]=\"activeConnectionId\" [popupX]=\"decisionConditionPopupX\" [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\" (saved)=\"onDecisionConditionSaved($event)\"></lib-conditions-popup>\n\n <!-- <lib-decision-popup\n [visible]=\"showConditionsDialog\"\n [decisionNodeId]=\"activeDecisionNodeId\"\n [popupX]=\"decisionConditionPopupX\"\n [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\"\n ></lib-decision-popup> -->\n\n <lib-stage-dialog [visible]=\"showStageDialogLocal\" [stageData]=\"activeStageData || {}\"\n (closed)=\"onStageDialogClosed()\" (saved)=\"onStageDialogSaved($event)\"></lib-stage-dialog>\n\n <lib-action-dialog [visible]=\"showActionDialogLocal\" [actionData]=\"activeActionData\" (closed)=\"onActionDialogClosed()\"\n (saved)=\"onActionDialogSaved($event)\"></lib-action-dialog>\n\n <lib-escalation-dialog [visible]=\"showEscalationDialogLocal\" [type]=\"activeEscalationType()!\"\n [stageCode]=\"activeStageCode() || ''\" [workflowCode]=\"state.workflow?.Code || ''\"\n (closed)=\"onEscalationDialogClosed()\"></lib-escalation-dialog>\n</div>\n", styles: [".canvas-container{flex:1;overflow:auto;background-color:#fff}.designer-canvas{min-width:100%;min-height:100%;cursor:default}.designer-canvas:focus{outline:none}.edit-swimlane-button{cursor:pointer}.edit-swimlane-button:hover rect{fill:#ddd6fe}.decision-condition-icon{cursor:pointer}.decision-condition-icon:hover path{fill:#c084fc}.swimlane-label{z-index:10;cursor:default}.plus-icon:hover{fill:#d36cff}.swimlane-container{pointer-events:none}.swimlane-container>*{pointer-events:auto}.node-element{z-index:10}.connection-element{z-index:5}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.VerbenPopUpComponent, selector: "verben-pop-Up", inputs: ["dropdownOpen", "dropdownWidth", "color", "customStyles", "popUpClass", "border", "borderRadius", "enableMouseLeave", "cdkPosition"], outputs: ["dropdownOpenChange", "close"] }, { kind: "component", type: i5.LabelEditorComponent, selector: "wf-label-editor", inputs: ["label", "x", "y", "isConnection", "isSwimlane"], outputs: ["labelChange", "openDialog"] }, { kind: "component", type: i6.StageNodeComponent, selector: "svg:g[lib-stage-node]", inputs: ["node", "isStartNode", "isSubflow", "stageData"], outputs: ["stagePropertiesUpdated", "parallelExecutionToggled", "showShieldDialog", "showEscalationDialog", "showFormDialog"] }, { kind: "component", type: i7.StageDialogComponent, selector: "lib-stage-dialog", inputs: ["visible", "stageData"], outputs: ["closed", "saved"] }, { kind: "component", type: i8.ConditionsPopupComponent, selector: "lib-conditions-popup", inputs: ["visible", "decisionNodeId", "newConnectionId", "popupX", "popupY"], outputs: ["closed", "saved"] }, { kind: "component", type: i9.EscalationDialogComponent, selector: "lib-escalation-dialog", inputs: ["visible", "workflowCode", "stageCode", "type"], outputs: ["closed", "created"] }, { kind: "component", type: i10.ActionDialogComponent, selector: "lib-action-dialog", inputs: ["visible", "actionData"], outputs: ["closed", "saved"] }, { kind: "pipe", type: i3.TitleCasePipe, name: "titlecase" }] });
1056
1183
  }
1057
1184
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DesignerCanvasComponent, decorators: [{
1058
1185
  type: Component,
1059
- args: [{ selector: 'lib-designer-canvas', template: "<div class=\"canvas-container\">\n <svg #canvas [attr.width]=\"canvasWidth\" [attr.height]=\"canvasHeight\" class=\"designer-canvas\"\n (click)=\"onCanvasClick($event)\">\n <defs>\n <!-- Grid pattern definition -->\n\n <pattern id=\"grid\" [attr.width]=\"gridSize\" [attr.height]=\"gridSize\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 20 0 L 0 0 0 20\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"0.5\" />\n </pattern>\n\n <!-- Arrow head marker definition -->\n <marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#D36CFF\" />\n </marker>\n\n <!-- Connection point styles -->\n <circle id=\"connection-point-template\" r=\"5\" fill=\"#D36CFF\" stroke=\"#FFFFFF\" stroke-width=\"1\" />\n\n <!-- Dashed line style for connection preview -->\n <pattern id=\"dashed-line\" width=\"10\" height=\"10\" patternUnits=\"userSpaceOnUse\">\n <line x1=\"0\" y1=\"5\" x2=\"10\" y2=\"5\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" />\n </pattern>\n\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <clipPath [attr.id]=\"'swimlane-clip-' + swimlane.order\">\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" height=\"263\" />\n </clipPath>\n }\n </defs>\n\n <!-- Background grid -->\n <rect width=\"100%\" height=\"100%\" fill=\"url(#grid)\" />\n\n <!-- Display a message when no swimlanes exist -->\n @if (state.swimlanes.length === 0) {\n <text x=\"50%\" y=\"50%\" font-family=\"sans-serif\" font-size=\"16\" fill=\"#94a3b8\" text-anchor=\"middle\">\n Select the Swimlane tool and click on the canvas to add a swimlane\n </text>\n }\n\n <!-- This is where workflow elements will be added later -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- <g\n [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\"\n [attr.clip-path]=\"'url(#swimlane-clip-' + swimlane.order + ')'\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n [attr.height]=\"263\"\n fill=\"#ffffff\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n height=\"40\"\n fill=\"#f8fafc\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <text\n x=\"20\"\n y=\"25\"\n font-family=\"sans-serif\"\n font-size=\"14\"\n fill=\"#333333\"\n font-weight=\"bold\"\n >\n {{ swimlane.label }}\n </text>\n\n <g\n class=\"edit-swimlane-button\"\n [attr.transform]=\"'translate(100, 20)'\"\n (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \"\n >\n <rect\n x=\"-5\"\n y=\"-15\"\n width=\"40\"\n height=\"20\"\n fill=\"#f3e8ff\"\n rx=\"3\"\n ry=\"3\"\n stroke=\"#d8b4fe\"\n stroke-width=\"1\"\n ></rect>\n <text\n x=\"15\"\n y=\"0\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#7e22ce\"\n text-anchor=\"middle\"\n >\n Edit\n </text>\n </g>\n\n <g [attr.transform]=\"'translate(200, 20)'\">\n @for (tag of swimlane.tags.slice(0, 3); track tag.Name; let i = $index)\n {\n <text\n [attr.x]=\"i * 100\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n {{ tag.Name }}\n </text>\n } @if (swimlane.tags.length > 3) {\n <text\n [attr.x]=\"3 * 100 + 10\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n +{{ swimlane.tags.length - 3 }} more\n </text>\n }\n </g>\n </g> -->\n\n <g [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\">\n <!-- Swimlane container - remove stroke to make it purely background -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" [attr.height]=\"263\"\n [attr.fill]=\"swimlane.order % 2 === 0 ? '#FCF3FF' : '#ECFFF5'\" stroke=\"none\"></rect>\n\n <!-- Vertical swimlane label on the left -->\n <g class=\"swimlane-label\">\n <!-- Purple background for the label -->\n <rect x=\"0.5\" y=\"0.5\" width=\"43\" height=\"215\" rx=\"10.5\" fill=\"white\" stroke=\"#D36CFF\"></rect>\n\n <!-- Plus button at the top -->\n <g (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \">\n <rect x=\"12.5\" y=\"10\" width=\"18\" height=\"18\" fill=\"transparent\" style=\"cursor: pointer\"></rect>\n\n <path d=\"M22.52 12.174V17.08H27.47V18.51H22.52V23.394H21.2V18.51H16.25V17.08H21.2V12.174H22.52Z\"\n fill=\"#0000FF\" class=\"plus-icon\" style=\"cursor: pointer\"></path>\n </g>\n\n <!-- Swimlane label -->\n <text x=\"22\" y=\"106\" font-family=\"sans-serif\" font-size=\"14\" fill=\"#333333\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 100)\">\n {{\n swimlane.label.length > 12\n ? swimlane.label.substring(0, 10) + \"...\"\n : swimlane.label\n }}\n </text>\n\n <!-- Tag count indicator at the bottom -->\n <rect x=\"11.5\" y=\"187\" width=\"21\" height=\"19\" rx=\"9.5\" fill=\"#9E9E9E\"></rect>\n <text x=\"24\" y=\"206\" font-family=\"sans-serif\" font-size=\"12\" fill=\"black\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 200)\">\n {{ swimlane.tags.length }}\n </text>\n </g>\n </g>\n\n }\n\n <!-- Nodes -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- Render nodes in this swimlane -->\n @for (node of swimlane.nodes; track node.id) {\n <g class=\"node-element\" [attr.transform]=\"\n 'translate(' + node.x + ',' + (node.y - swimlane.order * 263) + ')'\n \" (mouseenter)=\"showConnectionPoints(node.id, swimlane.order)\" (mouseleave)=\"hideConnectionPoints(node.id)\">\n <!-- Start node indicator (circle and arrow) for the first node -->\n @if (node.isStartNode) {\n <!-- Circle -->\n <circle cx=\"-50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></circle>\n <!-- Form icon for start node -->\n <svg:g (click)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order)\n \" class=\"stage-icon\" transform=\"translate(-45, 42)\" style=\"cursor: pointer; pointer-events: all\">\n <!-- Transparent rectangle to capture clicks -->\n <svg:rect x=\"-2\" y=\"-2\" width=\"24\" height=\"24\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path\n d=\"M16.5 20.475V17.475H13.5V16.475H16.5V13.475H17.5V16.475H20.5V17.475H17.5V20.475H16.5ZM3.5 17.5V16.5H4.5V17.5H3.5ZM6.5 17.5V16.5H11.517C11.5057 16.6767 11.5043 16.845 11.513 17.005C11.521 17.165 11.531 17.33 11.543 17.5H6.5ZM3.5 13.5V12.5H4.5V13.5H3.5ZM6.5 13.5V12.5H13.804C13.6127 12.6387 13.4333 12.7913 13.266 12.958C13.0993 13.1247 12.9377 13.3053 12.781 13.5H6.5ZM3.5 9.5V8.5H4.5V9.5H3.5ZM6.5 9.5V8.5H18.5V9.5H6.5ZM3.5 5.5V4.5H4.5V5.5H3.5ZM6.5 5.5V4.5H18.5V5.5H6.5Z\"\n [attr.fill]=\"state.workflowFormId ? '#D36CFF' : 'black'\" transform=\"scale(0.7)\" />\n </svg:g>\n <!-- Arrow from circle to node -->\n <path d=\"M -20 50 L 0 50\" stroke=\"#D36CFF\" stroke-width=\"1\" marker-end=\"url(#arrowhead)\"></path>\n }\n\n <!-- Exit point indicator (circle and arrow) -->\n @if (node.stageData?.IsExitPoint) {\n <!-- Arrow from node to circle -->\n <path [attr.d]=\"'M ' + node.width + ' 50 L ' + (node.width + 20) + ' 50'\" stroke=\"#D36CFF\" stroke-width=\"1\"\n marker-end=\"url(#arrowhead)\"></path>\n <!-- Circle -->\n <circle [attr.cx]=\"node.width + 50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"2\"></circle>\n }\n\n <!-- Stage node -->\n @if (node.type === 'stage') {\n <!-- <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"node.width\"\n [attr.height]=\"node.height\"\n fill=\"none\"\n stroke=\"#D36CFF\"\n stroke-width=\"1\"\n ></rect> -->\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Decision node -->\n @if (node.type === 'decision') {\n <path [attr.d]=\"\n 'M 0 ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' 0' +\n ' L ' +\n node.width +\n ' ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' ' +\n node.height +\n ' Z'\n \" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></path>\n\n <!-- Decision node condition indicator icon -->\n <svg:g (click)=\"showDecisionConditionsPopup($event, node, swimlane.order)\" class=\"decision-condition-icon\"\n [attr.transform]=\"\n 'translate(' +\n (node.width / 2 - 10) +\n ',' +\n (node.height / 2 - 10) +\n ')'\n \">\n <svg:rect x=\"-5\" y=\"-5\" width=\"30\" height=\"30\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path d=\"M10 0H20V2H10V0ZM10 8H20V10H10V8ZM10 4H20V6H10V4ZM0 0H8V2H0V0ZM0 8H8V10H0V8ZM0 4H8V6H0V4Z\"\n fill=\"#D36CFF\" />\n </svg:g>\n }\n\n <!-- Form node -->\n @if (node.type === 'form') {\n <path\n d=\"M95.0625 50.5591V95.0625C95.0625 97.9716 93.9069 100.762 91.8498 102.819C89.7928 104.876 87.0028 106.031 84.0938 106.031H32.9062C29.9972 106.031 27.2072 104.876 25.1502 102.819C23.0931 100.762 21.9375 97.9716 21.9375 95.0625V21.9375C21.9375 19.0284 23.0931 16.2385 25.1502 14.1814C27.2072 12.1244 29.9972 10.9688 32.9062 10.9688H55.4722C57.4109 10.969 59.2701 11.7392 60.6412 13.1099L92.9213 45.3901C94.292 46.7611 95.0622 48.6204 95.0625 50.5591Z\"\n transform=\"scale(0.7)\" fill=\"none\" stroke=\"#D36CFF\" stroke-linejoin=\"round\" />\n <path\n d=\"M58.5 12.7969V40.2188C58.5 42.1581 59.2704 44.0181 60.6418 45.3895C62.0131 46.7608 63.8731 47.5312 65.8125 47.5312H93.2344\"\n transform=\"scale(0.7)\" stroke=\"#D36CFF\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"sans-serif\" font-size=\"14\"\n fill=\"#D36CFF\">\n Form\n </text>\n }\n\n <!-- Subflow node -->\n @if (node.type === 'subflow') {\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\" [isSubflow]=\"true\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Connection points for this node -->\n @for (point of node.connectionPoints || []; track point.id) { @if\n (isConnectionPointVisible(node.id)) {\n <use [attr.href]=\"'#connection-point-template'\" [attr.x]=\"point.x\" [attr.y]=\"point.y\" [attr.id]=\"point.id\"\n (mousedown)=\"startConnectionDrag($event, point, swimlane.order)\" />\n } }\n </g>\n <!-- A transparent hover area for improved hover detection -->\n <rect [attr.x]=\"node.x - 10\" [attr.y]=\"node.y - 10\" [attr.width]=\"node.width + 20\" [attr.height]=\"node.height + 20\"\n fill=\"transparent\" (mouseover)=\"showConnectionPoints(node.id, swimlane.order)\"\n (mouseout)=\"hideConnectionPoints(node.id)\" style=\"pointer-events: none\" />\n } }\n\n <!-- Connections -->\n @for (connection of state.connections; track connection.id) {\n <g class=\"connection-element\">\n <path [attr.d]=\"getConnectionPathForSavedConnection(connection)\" stroke=\"#D36CFF\" stroke-width=\"2\" fill=\"none\"\n marker-end=\"url(#arrowhead)\"></path>\n\n <!-- Connection Label -->\n @if (connection.sourceNodeId && connection.targetNodeId) {\n <foreignObject [attr.x]=\"getLabelPosition(connection).x\" [attr.y]=\"getLabelPosition(connection).y\" width=\"150\"\n height=\"40\" style=\"overflow: visible; pointer-events: all;\" [attr.transform]=\"'translate(-75, -10)'\">\n <wf-label-editor [label]=\"connection.label || 'New Action'\" [x]=\"0\" [y]=\"0\" [isConnection]=\"true\"\n (labelChange)=\"saveConnectionLabel(connection, $event)\" (openDialog)=\"onShowActionDialog(connection)\" />\n </foreignObject>\n }\n </g>\n }\n\n <!-- Connection preview line -->\n @if (state.isConnectionDragging()) {\n <g>\n <path [attr.d]=\"getConnectionPath()\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" fill=\"none\"></path>\n </g>\n }\n </svg>\n\n <div *ngIf=\"popupVisible\" [style.position]=\"'absolute'\" [style.left.px]=\"popupX\" [style.top.px]=\"popupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '99' }\" [enableMouseLeave]=\"false\"\n (dropdownOpenChange)=\"$event ? null : hideConnectionPopup()\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md\" dropdown-content>\n <h4 class=\"mb-2 font-medium\">Create Connection</h4>\n <div class=\"flex flex-col gap-2\">\n <ng-container *ngFor=\"let type of allowedNodeTypes\">\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"createNodeConnection(type)\">\n Create {{ type | titlecase }}\n </button>\n </ng-container>\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"hideConnectionPopup()\">\n Cancel\n </button>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showStartNodeFormPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"startNodeFormPopupX\"\n [style.top.px]=\"startNodeFormPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow Form</h4>\n <div *ngIf=\"isLoadingStartNodeForms\" class=\"text-center py-2\">\n Loading forms...\n </div>\n <div *ngIf=\"!isLoadingStartNodeForms\" class=\"max-h-48 overflow-y-auto\">\n <div class=\"mb-3\">\n <button\n class=\"w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectStartNodeForm(null)\">\n Clear form selection\n </button>\n </div>\n <div *ngFor=\"let form of startNodeFormsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n [ngClass]=\"{ 'bg-blue-50 !border-blue-500 !border-2 font-semibold': form?.Code === activeNodeForFormSelection?.stageData?.formId}\"\n (click)=\"selectStartNodeForm(form)\">\n {{ form.Name }}\n </button>\n </div>\n <div *ngIf=\"startNodeFormsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No forms available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showSubflowPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"subflowPopupX\"\n [style.top.px]=\"subflowPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow</h4>\n <div *ngIf=\"isLoadingWorkflows\" class=\"text-center py-2\">\n Loading workflows...\n </div>\n <div *ngIf=\"!isLoadingWorkflows\" class=\"max-h-48 overflow-y-auto\">\n <div *ngFor=\"let workflow of workflowsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectSubflowWorkflow(workflow)\">\n {{ workflow.Name }}\n </button>\n </div>\n <div *ngIf=\"workflowsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No workflows available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <lib-conditions-popup [visible]=\"showDecisionConditionDialog\" [decisionNodeId]=\"activeDecisionNodeId\"\n [newConnectionId]=\"activeConnectionId\" [popupX]=\"decisionConditionPopupX\" [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\" (saved)=\"onDecisionConditionSaved($event)\"></lib-conditions-popup>\n\n <!-- <lib-decision-popup\n [visible]=\"showConditionsDialog\"\n [decisionNodeId]=\"activeDecisionNodeId\"\n [popupX]=\"decisionConditionPopupX\"\n [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\"\n ></lib-decision-popup> -->\n\n <lib-stage-dialog [visible]=\"showStageDialogLocal\" [stageData]=\"activeStageData || {}\"\n (closed)=\"onStageDialogClosed()\" (saved)=\"onStageDialogSaved($event)\"></lib-stage-dialog>\n\n <lib-action-dialog [visible]=\"showActionDialogLocal\" [actionData]=\"activeActionData\" (closed)=\"onActionDialogClosed()\"\n (saved)=\"onActionDialogSaved($event)\"></lib-action-dialog>\n\n <lib-escalation-dialog [visible]=\"showEscalationDialogLocal\" [type]=\"activeEscalationType()!\"\n [stageCode]=\"activeStageCode() || ''\" [workflowCode]=\"state.workflow?.Code || ''\"\n (closed)=\"onEscalationDialogClosed()\"></lib-escalation-dialog>\n</div>\n", styles: [".canvas-container{flex:1;overflow:auto;background-color:#fff}.designer-canvas{min-width:100%;min-height:100%;cursor:default}.designer-canvas:focus{outline:none}.edit-swimlane-button{cursor:pointer}.edit-swimlane-button:hover rect{fill:#ddd6fe}.decision-condition-icon{cursor:pointer}.decision-condition-icon:hover path{fill:#c084fc}.swimlane-label{z-index:10;cursor:default}.plus-icon:hover{fill:#d36cff}.swimlane-container{pointer-events:none}.swimlane-container>*{pointer-events:auto}.node-element{z-index:10}.connection-element{z-index:5}\n"] }]
1186
+ args: [{ selector: 'lib-designer-canvas', template: "<div class=\"canvas-container\">\n <svg #canvas [attr.width]=\"canvasWidth\" [attr.height]=\"canvasHeight\" class=\"designer-canvas\"\n (click)=\"onCanvasClick($event)\">\n <defs>\n <!-- Grid pattern definition -->\n\n <pattern id=\"grid\" [attr.width]=\"gridSize\" [attr.height]=\"gridSize\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 20 0 L 0 0 0 20\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"0.5\" />\n </pattern>\n\n <!-- Arrow head marker definition -->\n <marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#D36CFF\" />\n </marker>\n\n <!-- Connection point styles -->\n <circle id=\"connection-point-template\" r=\"5\" fill=\"#D36CFF\" stroke=\"#FFFFFF\" stroke-width=\"1\" />\n\n <!-- Dashed line style for connection preview -->\n <pattern id=\"dashed-line\" width=\"10\" height=\"10\" patternUnits=\"userSpaceOnUse\">\n <line x1=\"0\" y1=\"5\" x2=\"10\" y2=\"5\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" />\n </pattern>\n\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <clipPath [attr.id]=\"'swimlane-clip-' + swimlane.order\">\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" height=\"263\" />\n </clipPath>\n }\n </defs>\n\n <!-- Background grid -->\n <rect width=\"100%\" height=\"100%\" fill=\"url(#grid)\" />\n\n <!-- Display a message when no swimlanes exist -->\n @if (state.swimlanes.length === 0) {\n <text x=\"50%\" y=\"50%\" font-family=\"sans-serif\" font-size=\"16\" fill=\"#94a3b8\" text-anchor=\"middle\">\n Select the Swimlane tool and click on the canvas to add a swimlane\n </text>\n }\n\n <!-- This is where workflow elements will be added later -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- <g\n [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\"\n [attr.clip-path]=\"'url(#swimlane-clip-' + swimlane.order + ')'\"\n >\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n [attr.height]=\"263\"\n fill=\"#ffffff\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"canvasWidth\"\n height=\"40\"\n fill=\"#f8fafc\"\n stroke=\"#e2e8f0\"\n stroke-width=\"1\"\n ></rect>\n\n <text\n x=\"20\"\n y=\"25\"\n font-family=\"sans-serif\"\n font-size=\"14\"\n fill=\"#333333\"\n font-weight=\"bold\"\n >\n {{ swimlane.label }}\n </text>\n\n <g\n class=\"edit-swimlane-button\"\n [attr.transform]=\"'translate(100, 20)'\"\n (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \"\n >\n <rect\n x=\"-5\"\n y=\"-15\"\n width=\"40\"\n height=\"20\"\n fill=\"#f3e8ff\"\n rx=\"3\"\n ry=\"3\"\n stroke=\"#d8b4fe\"\n stroke-width=\"1\"\n ></rect>\n <text\n x=\"15\"\n y=\"0\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#7e22ce\"\n text-anchor=\"middle\"\n >\n Edit\n </text>\n </g>\n\n <g [attr.transform]=\"'translate(200, 20)'\">\n @for (tag of swimlane.tags.slice(0, 3); track tag.Name; let i = $index)\n {\n <text\n [attr.x]=\"i * 100\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n {{ tag.Name }}\n </text>\n } @if (swimlane.tags.length > 3) {\n <text\n [attr.x]=\"3 * 100 + 10\"\n y=\"5\"\n font-family=\"sans-serif\"\n font-size=\"12\"\n fill=\"#666666\"\n >\n +{{ swimlane.tags.length - 3 }} more\n </text>\n }\n </g>\n </g> -->\n\n <g [attr.transform]=\"'translate(0,' + swimlane.order * 263 + ')'\">\n <!-- Swimlane container - remove stroke to make it purely background -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"canvasWidth\" [attr.height]=\"263\"\n [attr.fill]=\"swimlane.order % 2 === 0 ? '#FCF3FF' : '#ECFFF5'\" stroke=\"none\"></rect>\n\n <!-- Vertical swimlane label on the left -->\n <g class=\"swimlane-label\">\n <!-- Purple background for the label -->\n <rect x=\"0.5\" y=\"0.5\" width=\"43\" height=\"215\" rx=\"10.5\" fill=\"white\" stroke=\"#D36CFF\"></rect>\n\n <!-- Plus button at the top -->\n <g (click)=\"\n onEditSwimlane($event, swimlane, swimlane.order);\n $event.stopPropagation()\n \">\n <rect x=\"12.5\" y=\"10\" width=\"18\" height=\"18\" fill=\"transparent\" style=\"cursor: pointer\"></rect>\n\n <path d=\"M22.52 12.174V17.08H27.47V18.51H22.52V23.394H21.2V18.51H16.25V17.08H21.2V12.174H22.52Z\"\n fill=\"#0000FF\" class=\"plus-icon\" style=\"cursor: pointer\"></path>\n </g>\n\n <!-- Swimlane label -->\n <text x=\"22\" y=\"106\" font-family=\"sans-serif\" font-size=\"14\" fill=\"#333333\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 100)\">\n {{\n swimlane.label.length > 12\n ? swimlane.label.substring(0, 10) + \"...\"\n : swimlane.label\n }}\n </text>\n\n <!-- Tag count indicator at the bottom -->\n <rect x=\"11.5\" y=\"187\" width=\"21\" height=\"19\" rx=\"9.5\" fill=\"#9E9E9E\"></rect>\n <text x=\"24\" y=\"206\" font-family=\"sans-serif\" font-size=\"12\" fill=\"black\" text-anchor=\"middle\"\n transform=\"rotate(-90, 22, 200)\">\n {{ swimlane.tags.length }}\n </text>\n </g>\n </g>\n\n }\n\n <!-- Nodes -->\n @for (swimlane of state.swimlanes; track swimlane.order) {\n <!-- Render nodes in this swimlane -->\n @for (node of swimlane.nodes; track node.id) {\n <g class=\"node-element\" [attr.transform]=\"\n 'translate(' + node.x + ',' + (node.y + swimlane.order * 263) + ')'\" [style.cursor]=\"getCursorForNode(node.id)\"\n (mousedown)=\"onNodeMouseDown($event, node, swimlane.order)\"\n (mouseenter)=\"showConnectionPoints(node.id, swimlane.order)\" (mouseleave)=\"hideConnectionPoints(node.id)\">\n <!-- Start node indicator (circle and arrow) for the first node -->\n @if (node.isStartNode) {\n <!-- Circle -->\n <circle cx=\"-50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></circle>\n <!-- Form icon for start node -->\n <svg:g (click)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order)\n \" class=\"stage-icon\" transform=\"translate(-45, 42)\" style=\"cursor: pointer; pointer-events: all\">\n <!-- Transparent rectangle to capture clicks -->\n <svg:rect x=\"-2\" y=\"-2\" width=\"24\" height=\"24\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path\n d=\"M16.5 20.475V17.475H13.5V16.475H16.5V13.475H17.5V16.475H20.5V17.475H17.5V20.475H16.5ZM3.5 17.5V16.5H4.5V17.5H3.5ZM6.5 17.5V16.5H11.517C11.5057 16.6767 11.5043 16.845 11.513 17.005C11.521 17.165 11.531 17.33 11.543 17.5H6.5ZM3.5 13.5V12.5H4.5V13.5H3.5ZM6.5 13.5V12.5H13.804C13.6127 12.6387 13.4333 12.7913 13.266 12.958C13.0993 13.1247 12.9377 13.3053 12.781 13.5H6.5ZM3.5 9.5V8.5H4.5V9.5H3.5ZM6.5 9.5V8.5H18.5V9.5H6.5ZM3.5 5.5V4.5H4.5V5.5H3.5ZM6.5 5.5V4.5H18.5V5.5H6.5Z\"\n [attr.fill]=\"state.workflowFormId ? '#D36CFF' : 'black'\" transform=\"scale(0.7)\" />\n </svg:g>\n <!-- Arrow from circle to node -->\n <path d=\"M -20 50 L 0 50\" stroke=\"#D36CFF\" stroke-width=\"1\" marker-end=\"url(#arrowhead)\"></path>\n }\n\n <!-- Exit point indicator (circle and arrow) -->\n @if (node.stageData?.IsExitPoint) {\n <!-- Arrow from node to circle -->\n <path [attr.d]=\"'M ' + node.width + ' 50 L ' + (node.width + 20) + ' 50'\" stroke=\"#D36CFF\" stroke-width=\"1\"\n marker-end=\"url(#arrowhead)\"></path>\n <!-- Circle -->\n <circle [attr.cx]=\"node.width + 50\" cy=\"50\" r=\"30\" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"2\"></circle>\n }\n\n <!-- Stage node -->\n @if (node.type === 'stage') {\n <!-- <rect\n x=\"0\"\n y=\"0\"\n [attr.width]=\"node.width\"\n [attr.height]=\"node.height\"\n fill=\"none\"\n stroke=\"#D36CFF\"\n stroke-width=\"1\"\n ></rect> -->\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Decision node -->\n @if (node.type === 'decision') {\n <path [attr.d]=\"\n 'M 0 ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' 0' +\n ' L ' +\n node.width +\n ' ' +\n node.height / 2 +\n ' L ' +\n node.width / 2 +\n ' ' +\n node.height +\n ' Z'\n \" fill=\"none\" stroke=\"#D36CFF\" stroke-width=\"1\"></path>\n\n <!-- Decision node condition indicator icon -->\n <svg:g (click)=\"showDecisionConditionsPopup($event, node, swimlane.order)\" class=\"decision-condition-icon\"\n [attr.transform]=\"\n 'translate(' +\n (node.width / 2 - 10) +\n ',' +\n (node.height / 2 - 10) +\n ')'\n \">\n <svg:rect x=\"-5\" y=\"-5\" width=\"30\" height=\"30\" fill=\"transparent\" style=\"cursor: pointer\" />\n <svg:path d=\"M10 0H20V2H10V0ZM10 8H20V10H10V8ZM10 4H20V6H10V4ZM0 0H8V2H0V0ZM0 8H8V10H0V8ZM0 4H8V6H0V4Z\"\n fill=\"#D36CFF\" />\n </svg:g>\n }\n\n <!-- Form node -->\n @if (node.type === 'form') {\n <path\n d=\"M95.0625 50.5591V95.0625C95.0625 97.9716 93.9069 100.762 91.8498 102.819C89.7928 104.876 87.0028 106.031 84.0938 106.031H32.9062C29.9972 106.031 27.2072 104.876 25.1502 102.819C23.0931 100.762 21.9375 97.9716 21.9375 95.0625V21.9375C21.9375 19.0284 23.0931 16.2385 25.1502 14.1814C27.2072 12.1244 29.9972 10.9688 32.9062 10.9688H55.4722C57.4109 10.969 59.2701 11.7392 60.6412 13.1099L92.9213 45.3901C94.292 46.7611 95.0622 48.6204 95.0625 50.5591Z\"\n transform=\"scale(0.7)\" fill=\"none\" stroke=\"#D36CFF\" stroke-linejoin=\"round\" />\n <path\n d=\"M58.5 12.7969V40.2188C58.5 42.1581 59.2704 44.0181 60.6418 45.3895C62.0131 46.7608 63.8731 47.5312 65.8125 47.5312H93.2344\"\n transform=\"scale(0.7)\" stroke=\"#D36CFF\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dominant-baseline=\"middle\" font-family=\"sans-serif\" font-size=\"14\"\n fill=\"#D36CFF\">\n Form\n </text>\n }\n\n <!-- Subflow node -->\n @if (node.type === 'subflow') {\n <svg:g lib-stage-node [node]=\"node\" [isStartNode]=\"node.isStartNode\" [isSubflow]=\"true\"\n (stagePropertiesUpdated)=\"onStagePropertiesUpdated($event)\" (showShieldDialog)=\"onShowShieldDialog($event)\"\n (showEscalationDialog)=\"onShowEscalationDialog($event)\" (showFormDialog)=\"\n toggleStartNodeFormPopup($event, node.x, node.y, swimlane.order, node)\n \"></svg:g>\n }\n\n <!-- Connection points for this node -->\n @for (point of node.connectionPoints || []; track point.id) { @if\n (isConnectionPointVisible(node.id)) {\n <use [attr.href]=\"'#connection-point-template'\" [attr.x]=\"point.x\" [attr.y]=\"point.y\" [attr.id]=\"point.id\"\n (mousedown)=\"startConnectionDrag($event, point, swimlane.order)\" />\n } }\n </g>\n <!-- A transparent hover area for improved hover detection -->\n <rect [attr.x]=\"node.x - 10\" [attr.y]=\"node.y - 10\" [attr.width]=\"node.width + 20\" [attr.height]=\"node.height + 20\"\n fill=\"transparent\" (mouseover)=\"showConnectionPoints(node.id, swimlane.order)\"\n (mouseout)=\"hideConnectionPoints(node.id)\" style=\"pointer-events: none\" />\n } }\n\n <!-- Connections -->\n @for (connection of state.connections; track connection.id) {\n <g class=\"connection-element\">\n <path [attr.d]=\"getConnectionPathForSavedConnection(connection)\" stroke=\"#D36CFF\" stroke-width=\"2\" fill=\"none\"\n marker-end=\"url(#arrowhead)\"></path>\n\n <!-- Connection Label -->\n @if (connection.sourceNodeId && connection.targetNodeId) {\n <foreignObject [attr.x]=\"getLabelPosition(connection).x\" [attr.y]=\"getLabelPosition(connection).y\" width=\"150\"\n height=\"40\" style=\"overflow: visible; pointer-events: all;\" [attr.transform]=\"'translate(-75, -10)'\">\n <wf-label-editor [label]=\"connection.label || 'New Action'\" [x]=\"0\" [y]=\"0\" [isConnection]=\"true\"\n (labelChange)=\"saveConnectionLabel(connection, $event)\" (openDialog)=\"onShowActionDialog(connection)\" />\n </foreignObject>\n }\n </g>\n }\n\n <!-- Connection preview line -->\n @if (state.isConnectionDragging()) {\n <g>\n <path [attr.d]=\"getConnectionPath()\" stroke=\"#D36CFF\" stroke-width=\"2\" stroke-dasharray=\"5,5\" fill=\"none\"></path>\n </g>\n }\n </svg>\n\n <div *ngIf=\"popupVisible\" [style.position]=\"'absolute'\" [style.left.px]=\"popupX\" [style.top.px]=\"popupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '99' }\" [enableMouseLeave]=\"false\"\n (dropdownOpenChange)=\"$event ? null : hideConnectionPopup()\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md\" dropdown-content>\n <h4 class=\"mb-2 font-medium\">Create Connection</h4>\n <div class=\"flex flex-col gap-2\">\n <ng-container *ngFor=\"let type of allowedNodeTypes\">\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"createNodeConnection(type)\">\n Create {{ type | titlecase }}\n </button>\n </ng-container>\n <button class=\"px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50\"\n (click)=\"hideConnectionPopup()\">\n Cancel\n </button>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showStartNodeFormPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"startNodeFormPopupX\"\n [style.top.px]=\"startNodeFormPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow Form</h4>\n <div *ngIf=\"isLoadingStartNodeForms\" class=\"text-center py-2\">\n Loading forms...\n </div>\n <div *ngIf=\"!isLoadingStartNodeForms\" class=\"max-h-48 overflow-y-auto\">\n <div class=\"mb-3\">\n <button\n class=\"w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectStartNodeForm(null)\">\n Clear form selection\n </button>\n </div>\n <div *ngFor=\"let form of startNodeFormsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n [ngClass]=\"{ 'bg-blue-50 !border-blue-500 !border-2 font-semibold': form?.Code === activeNodeForFormSelection?.stageData?.formId}\"\n (click)=\"selectStartNodeForm(form)\">\n {{ form.Name }}\n </button>\n </div>\n <div *ngIf=\"startNodeFormsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No forms available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <div *ngIf=\"showSubflowPopup\" [style.position]=\"'absolute'\" [style.left.px]=\"subflowPopupX\"\n [style.top.px]=\"subflowPopupY\">\n <verben-pop-Up [dropdownOpen]=\"true\" [customStyles]=\"{ 'z-index': '100' }\">\n <div dropdown-trigger style=\"display: none\">\n <!-- Hidden trigger element -->\n </div>\n <div class=\"p-3 bg-white border border-gray-200 rounded shadow-md w-64\" dropdown-content\n style=\"background-color: white; z-index: 1000\">\n <h4 class=\"mb-2 font-medium\">Select Workflow</h4>\n <div *ngIf=\"isLoadingWorkflows\" class=\"text-center py-2\">\n Loading workflows...\n </div>\n <div *ngIf=\"!isLoadingWorkflows\" class=\"max-h-48 overflow-y-auto\">\n <div *ngFor=\"let workflow of workflowsList\" class=\"mb-1\">\n <button class=\"w-full px-3 py-2 bg-white border border-gray-200 rounded text-sm hover:bg-gray-50 text-left\"\n (click)=\"selectSubflowWorkflow(workflow)\">\n {{ workflow.Name }}\n </button>\n </div>\n <div *ngIf=\"workflowsList.length === 0\" class=\"text-center py-2 text-gray-500\">\n No workflows available\n </div>\n </div>\n </div>\n </verben-pop-Up>\n </div>\n\n <lib-conditions-popup [visible]=\"showDecisionConditionDialog\" [decisionNodeId]=\"activeDecisionNodeId\"\n [newConnectionId]=\"activeConnectionId\" [popupX]=\"decisionConditionPopupX\" [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\" (saved)=\"onDecisionConditionSaved($event)\"></lib-conditions-popup>\n\n <!-- <lib-decision-popup\n [visible]=\"showConditionsDialog\"\n [decisionNodeId]=\"activeDecisionNodeId\"\n [popupX]=\"decisionConditionPopupX\"\n [popupY]=\"decisionConditionPopupY\"\n (closed)=\"onDecisionConditionCancelled()\"\n ></lib-decision-popup> -->\n\n <lib-stage-dialog [visible]=\"showStageDialogLocal\" [stageData]=\"activeStageData || {}\"\n (closed)=\"onStageDialogClosed()\" (saved)=\"onStageDialogSaved($event)\"></lib-stage-dialog>\n\n <lib-action-dialog [visible]=\"showActionDialogLocal\" [actionData]=\"activeActionData\" (closed)=\"onActionDialogClosed()\"\n (saved)=\"onActionDialogSaved($event)\"></lib-action-dialog>\n\n <lib-escalation-dialog [visible]=\"showEscalationDialogLocal\" [type]=\"activeEscalationType()!\"\n [stageCode]=\"activeStageCode() || ''\" [workflowCode]=\"state.workflow?.Code || ''\"\n (closed)=\"onEscalationDialogClosed()\"></lib-escalation-dialog>\n</div>\n", styles: [".canvas-container{flex:1;overflow:auto;background-color:#fff}.designer-canvas{min-width:100%;min-height:100%;cursor:default}.designer-canvas:focus{outline:none}.edit-swimlane-button{cursor:pointer}.edit-swimlane-button:hover rect{fill:#ddd6fe}.decision-condition-icon{cursor:pointer}.decision-condition-icon:hover path{fill:#c084fc}.swimlane-label{z-index:10;cursor:default}.plus-icon:hover{fill:#d36cff}.swimlane-container{pointer-events:none}.swimlane-container>*{pointer-events:auto}.node-element{z-index:10}.connection-element{z-index:5}\n"] }]
1060
1187
  }], ctorParameters: () => [{ type: i1.WorkflowDesignerState }, { type: i2.WorkflowDataService }], propDecorators: { selectedTool: [{
1061
1188
  type: Input
1062
1189
  }], clickedPosition: [{
@@ -1074,4 +1201,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1074
1201
  type: HostListener,
1075
1202
  args: ['window:mouseup', ['$event']]
1076
1203
  }] } });
1077
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduZXItY2FudmFzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3ZlcmJlbi13b3JrZmxvdy11aS9zcmMvbGliL2NvbXBvbmVudHMvd29ya2Zsb3ctZGVzaWduZXIvZGVzaWduZXItY2FudmFzL2Rlc2lnbmVyLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92ZXJiZW4td29ya2Zsb3ctdWkvc3JjL2xpYi9jb21wb25lbnRzL3dvcmtmbG93LWRlc2lnbmVyL2Rlc2lnbmVyLWNhbnZhcy9kZXNpZ25lci1jYW52YXMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsR0FFVixNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7Ozs7O0FBa0J2QixNQUFNLE9BQU8sdUJBQXVCO0lBcUd6QjtJQUNDO0lBckdELFlBQVksR0FBYSxJQUFJLENBQUM7SUFDN0IsZUFBZSxHQUFHLElBQUksWUFBWSxFQUE0QixDQUFDO0lBQy9ELGVBQWUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQy9DLG9CQUFvQixHQUNsQixJQUFJLENBQUM7SUFDRyxzQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFHL0MsQ0FBQztJQUNLLHVCQUF1QixHQUFHLElBQUksWUFBWSxFQUdoRCxDQUFDO0lBRUwsK0JBQStCO0lBQ1EsU0FBUyxDQUEwQjtJQUcxRSxlQUFlLENBQUMsS0FBaUI7UUFDL0Isc0VBQXNFO1FBQ3RFLElBQ0UsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCO1lBQ3RCLENBQUMsSUFBSSxDQUFDLHNCQUFzQjtZQUM1QixDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksdUNBQXVDO1lBQzdELElBQUks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QUNmLE9BQU8sQ0FBQyxLQUFLLENBQ1gsa0RBQWtELEVBQ2xELFVBQVUsRUFDVixLQUFLLENBQ04sQ0FBQztZQUNGLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELG1CQUFtQixDQUFDLFVBQXNCLEVBQUUsS0FBYTtRQUN2RCwyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDM0QsSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDOUIsT0FBTztvQkFDTCxHQUFHLElBQUk7b0JBQ1AsS0FBSyxFQUFFLEtBQUs7aUJBQ2IsQ0FBQztZQUNKLENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0FsNENVLHVCQUF1Qjs0RkFBdkIsdUJBQXVCLHlkQzdCcEMsODRsQkErYUE7OzRGRGxaYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0UscUJBQXFCOzRIQUt0QixZQUFZO3NCQUFwQixLQUFLO2dCQUNJLGVBQWU7c0JBQXhCLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFHRyxzQkFBc0I7c0JBQS9CLE1BQU07Z0JBSUcsdUJBQXVCO3NCQUFoQyxNQUFNO2dCQU1nQyxTQUFTO3NCQUEvQyxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBR3JDLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgc2lnbmFsLFxuICBWaWV3Q2hpbGQsXG4gIFdyaXRhYmxlU2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEVzY2FsYXRpb25UeXBlLCBGb3JtLCBXb3JrZmxvdywgV29ya2Zsb3dBY3Rpb24sIFdvcmtmbG93U3RhZ2UgfSBmcm9tICd2ZXJiZW4td29ya2Zsb3ctdWkvc3JjL2xpYi9tb2RlbHMnO1xuaW1wb3J0IHsgV29ya2Zsb3dEYXRhU2VydmljZSB9IGZyb20gJy4uL3dvcmtmbG93LWRhdGEuc2VydmljZSc7XG5pbXBvcnQgeyBXb3JrZmxvd0Rlc2lnbmVyU3RhdGUgfSBmcm9tICcuLi93b3JrZmxvdy1kZXNpZ25lci5zdGF0ZSc7XG5pbXBvcnQge1xuICBDb25uZWN0aW9uLFxuICBDb25uZWN0aW9uUG9pbnQsXG4gIE5vZGUsXG4gIFN3aW1sYW5lSXRlbSxcbiAgVG9vbFR5cGUsXG4gIE5vZGUgYXMgV0ZOb2RlLFxufSBmcm9tICcuLi93b3JrZmxvdy1kZXNpZ25lci50eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1kZXNpZ25lci1jYW52YXMnLFxuICB0ZW1wbGF0ZVVybDogJy4vZGVzaWduZXItY2FudmFzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2Rlc2lnbmVyLWNhbnZhcy5jb21wb25lbnQuY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgRGVzaWduZXJDYW52YXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBzZWxlY3RlZFRvb2w6IFRvb2xUeXBlID0gbnVsbDtcbiAgQE91dHB1dCgpIGNsaWNrZWRQb3NpdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8eyB4OiBudW1iZXI7IHk6IG51bWJlciB9PigpO1xuICBAT3V0cHV0KCkgc3ViZmxvd1NlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBwZW5kaW5nU3RhZ2VQb3NpdGlvbjogeyBzd2ltbGFuZUluZGV4OiBudW1iZXI7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsID1cbiAgICBudWxsO1xuICBAT3V0cHV0KCkgc3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIG5vZGVJZDogc3RyaW5nO1xuICAgIHN0YWdlRGF0YTogUGFydGlhbDxXb3JrZmxvd1N0YWdlPjtcbiAgfT4oKTtcbiAgQE91dHB1dCgpIGFjdGlvblByb3BlcnRpZXNVcGRhdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7XG4gICAgY29ubmVjdGlvbklkOiBzdHJpbmc7XG4gICAgYWN0aW9uRGF0YTogUGFydGlhbDxXb3JrZmxvd0FjdGlvbj47XG4gIH0+KCk7XG5cbiAgLy8gUmVmZXJlbmNlIHRvIHRoZSBTVkcgZWxlbWVudFxuICBAVmlld0NoaWxkKCdjYW52YXMnLCB7IHN0YXRpYzogdHJ1ZSB9KSBjYW52YXNSZWYhOiBFbGVtZW50UmVmPFNWR0VsZW1lbnQ+O1xuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzptb3VzZXVwJywgWyckZXZlbnQnXSlcbiAgb25XaW5kb3dNb3VzZVVwKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhIHBvcHVwIG9wZW4gYnV0IHRoZSBtb3VzZSBpcyByZWxlYXNlZCBvdXRzaWRlLCBjbGVhbiB1cFxuICAgIGlmIChcbiAgICAgICF0aGlzLnNob3dTdWJmbG93UG9wdXAgJiZcbiAgICAgICF0aGlzLnNob3dTdGFydE5vZGVGb3JtUG9wdXAgJiZcbiAgICAgICF0aGlzLnBvcHVwVmlzaWJsZSAmJiAvLyBPbmx5IGVuZCBkcmFnIGlmIG5vIHBvcHVwIGlzIHZpc2libGVcbiAgICAgIHRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKVxuICAgICkge1xuICAgICAgY29uc29sZS5sb2coJ0V4dGVybmFsIG1vdXNldXAgZGV0ZWN0ZWQgLSBjbGVhbmluZyB1cCBjb25uZWN0aW9uIGRyYWcnKTtcbiAgICAgIHRoaXMuc3RhdGUuZW5kQ29ubmVjdGlvbkRyYWcoKTtcbiAgICB9XG4gIH1cblxuICAvLyBDYW52YXMgZGltZW5zaW9uc1xuICBjYW52YXNXaWR0aCA9IDMwMDA7XG4gIGNhbnZhc0hlaWdodCA9IDIwMDA7XG5cbiAgLy8gR3JpZCBzaXplXG4gIGdyaWRTaXplID0gMjA7XG5cbiAgc3dpbWxhbmVIZWlnaHQgPSAyNjM7XG4gIHZpc2libGVDb25uZWN0aW9uUG9pbnRzTm9kZUlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcG9wdXBWaXNpYmxlID0gZmFsc2U7XG4gIHBvcHVwWCA9IDA7XG4gIHBvcHVwWSA9IDA7XG4gIGFsbG93ZWROb2RlVHlwZXM6IHN0cmluZ1tdID0gW107XG5cbiAgc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cDogYm9vbGVhbiA9IGZhbHNlO1xuICBzdGFydE5vZGVGb3Jtc0xpc3Q6IEZvcm1bXSA9IFtdO1xuICBpc0xvYWRpbmdTdGFydE5vZGVGb3JtczogYm9vbGVhbiA9IGZhbHNlO1xuICBzdGFydE5vZGVGb3JtUG9wdXBYOiBudW1iZXIgPSAwO1xuICBzdGFydE5vZGVGb3JtUG9wdXBZOiBudW1iZXIgPSAwO1xuICBhY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbjogTm9kZSB8IG51bGwgPSBudWxsO1xuICBub2RlRm9ybXM6IFdyaXRhYmxlU2lnbmFsPFxuICAgIFJlY29yZDxzdHJpbmcsIHsgZm9ybUlkOiBzdHJpbmc7IGZvcm1OYW1lOiBzdHJpbmcgfT5cbiAgPiA9IHNpZ25hbCh7fSk7XG5cbiAgc2hvd1N1YmZsb3dQb3B1cDogYm9vbGVhbiA9IGZhbHNlO1xuICB3b3JrZmxvd3NMaXN0OiBXb3JrZmxvd1tdID0gW107XG4gIGlzTG9hZGluZ1dvcmtmbG93czogYm9vbGVhbiA9IGZhbHNlO1xuICBzdWJmbG93UG9wdXBYOiBudW1iZXIgPSAwO1xuICBzdWJmbG93UG9wdXBZOiBudW1iZXIgPSAwO1xuICBwZW5kaW5nU3ViZmxvd1Bvc2l0aW9uOiB7XG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyO1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBwZW5kaW5nRGVjaXNpb25Db25uZWN0aW9uOiB7XG4gICAgZGVjaXNpb25Ob2RlSWQ6IHN0cmluZztcbiAgICBzd2ltbGFuZUluZGV4OiBudW1iZXI7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIHBlbmRpbmdDb25uZWN0aW9uU291cmNlUG9pbnQ6IENvbm5lY3Rpb25Qb2ludCB8IG51bGwgPSBudWxsO1xuICBwZW5kaW5nQ29ubmVjdGlvblNvdXJjZVN3aW1sYW5lSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIHNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZzogYm9vbGVhbiA9IGZhbHNlO1xuICBzaG93Q29uZGl0aW9uc0RpYWxvZzogYm9vbGVhbiA9IGZhbHNlO1xuICBhY3RpdmVEZWNpc2lvbk5vZGVJZDogc3RyaW5nID0gJyc7XG4gIGFjdGl2ZUNvbm5lY3Rpb25JZDogc3RyaW5nID0gJyc7XG4gIGRlY2lzaW9uQ29uZGl0aW9uUG9wdXBYOiBudW1iZXIgPSAwO1xuICBkZWNpc2lvbkNvbmRpdGlvblBvcHVwWTogbnVtYmVyID0gMDtcblxuICBpc0NyZWF0aW5nU3RhZ2VGcm9tRGVjaXNpb246IGJvb2xlYW4gPSBmYWxzZTtcbiAgcGVuZGluZ0RlY2lzaW9uQ29uZGl0aW9uOiBzdHJpbmcgPSAnJztcbiAgYWN0aXZlU3RhZ2VJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGFjdGl2ZUFjdGlvbklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBzaG93U3RhZ2VEaWFsb2dMb2NhbDogYm9vbGVhbiA9IGZhbHNlO1xuICBzaG93RXNjYWxhdGlvbkRpYWxvZ0xvY2FsOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGl2ZUVzY2FsYXRpb25UeXBlOiBXcml0YWJsZVNpZ25hbDxFc2NhbGF0aW9uVHlwZSB8IG51bGw+ID0gc2lnbmFsKG51bGwpO1xuICBhY3RpdmVTdGFnZUNvZGU6IFdyaXRhYmxlU2lnbmFsPHN0cmluZyB8IG51bGw+ID0gc2lnbmFsKG51bGwpO1xuICBhY3RpdmVTdGFnZURhdGE6IFBhcnRpYWw8V29ya2Zsb3dTdGFnZT4gPSB7fTtcbiAgYWN0aXZlQWN0aW9uRGF0YTogQ29ubmVjdGlvbiB8IG51bGwgPSBudWxsO1xuXG4gIHNob3dBY3Rpb25EaWFsb2dMb2NhbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHBvdGVudGlhbFRhcmdldFBvaW50SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBzdGF0ZTogV29ya2Zsb3dEZXNpZ25lclN0YXRlLFxuICAgIHByaXZhdGUgZGF0YVNlcnZpY2U6IFdvcmtmbG93RGF0YVNlcnZpY2VcbiAgKSB7IH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUNhbnZhc1NpemUoKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBtb3VzZSBjbGljayBvbiBjYW52YXNcbiAgb25DYW52YXNDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIC8vIE9ubHkgcHJvY2VzcyBjYW52YXMgY2xpY2tzIGlmIGEgdG9vbCBpcyBzZWxlY3RlZFxuICAgIGlmICghdGhpcy5zZWxlY3RlZFRvb2wpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSBjbGljayBvY2N1cnJlZFxuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICdDYW52YXMgY2xpY2tlZCBhdDonLFxuICAgICAgcG9zaXRpb24sXG4gICAgICAnd2l0aCB0b29sOicsXG4gICAgICB0aGlzLnNlbGVjdGVkVG9vbFxuICAgICk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIHN3aW1sYW5lIGluZGV4IGJhc2VkIG9uIHBvc2l0aW9uXG4gICAgLy8gY29uc3Qgc3dpbWxhbmVJbmRleCA9IE1hdGguZmxvb3IocG9zaXRpb24ueSAvIHRoaXMuc3dpbWxhbmVIZWlnaHQpO1xuXG4gICAgLy8gT25seSBlbWl0IHRoZSBwb3NpdGlvbiBpZiB3ZSBoYXZlIGEgdG9vbCBzZWxlY3RlZCBhbmQgaXQncyBhIHZhbGlkIGNsaWNrIGFyZWFcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRvb2wpIHtcbiAgICAgIHRoaXMuY2xpY2tlZFBvc2l0aW9uLmVtaXQoe1xuICAgICAgICB4OiBwb3NpdGlvbi54LFxuICAgICAgICB5OiBwb3NpdGlvbi55LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgb25TaG93U2hpZWxkRGlhbG9nKHN0YWdlSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIG5vZGVcbiAgICBjb25zdCBub2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKHN0YWdlSWQpO1xuICAgIGlmIChub2RlSW5mbykge1xuICAgICAgdGhpcy5hY3RpdmVTdGFnZUlkID0gc3RhZ2VJZDtcbiAgICAgIHRoaXMuYWN0aXZlU3RhZ2VEYXRhID0geyAuLi5ub2RlSW5mby5ub2RlLnN0YWdlRGF0YSwgaWQ6IHN0YWdlSWQgfTtcbiAgICAgIGNvbnNvbGUubG9nKHRoaXMuYWN0aXZlU3RhZ2VEYXRhLCBcIkFDVElWRSBTVEFHRSBEQVRBXCIpO1xuICAgICAgdGhpcy5zaG93U3RhZ2VEaWFsb2dMb2NhbCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgb25TaG93QWN0aW9uRGlhbG9nKGNvbm5lY3Rpb25JbmZvOiBDb25uZWN0aW9uKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coXCJDT05FQ1RJT05cIiwgY29ubmVjdGlvbkluZm8pO1xuICAgIC8vIEZpbmQgdGhlIG5vZGVcbiAgICAvLyBjb25zdCBjb25uZWN0aW9uSW5mbyA9IHRoaXMuc3RhdGUuZmluZEFjdGlvbkJ5SWQoYWN0aW9uSWQpO1xuICAgIGlmIChjb25uZWN0aW9uSW5mbykge1xuICAgICAgdGhpcy5hY3RpdmVBY3Rpb25JZCA9IGNvbm5lY3Rpb25JbmZvLmlkO1xuICAgICAgdGhpcy5hY3RpdmVBY3Rpb25EYXRhID0gY29ubmVjdGlvbkluZm87XG4gICAgICBjb25zb2xlLmxvZyh0aGlzLmFjdGl2ZUFjdGlvbkRhdGEpO1xuICAgICAgdGhpcy5zaG93QWN0aW9uRGlhbG9nTG9jYWwgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIG9uU2hvd0VzY2FsYXRpb25EaWFsb2coZXZlbnQ6IHtcbiAgICBzdGFnZUlkOiBzdHJpbmc7XG4gICAgdHlwZTogRXNjYWxhdGlvblR5cGU7XG4gIH0pOiB2b2lkIHtcbiAgICAvLyBGaW5kIHRoZSBub2RlXG4gICAgY29uc3Qgbm9kZUluZm8gPSB0aGlzLnN0YXRlLmZpbmROb2RlQnlJZChldmVudC5zdGFnZUlkKTtcbiAgICBpZiAobm9kZUluZm8pIHtcbiAgICAgIHRoaXMuYWN0aXZlU3RhZ2VJZCA9IGV2ZW50LnN0YWdlSWQ7XG4gICAgICB0aGlzLmFjdGl2ZVN0YWdlRGF0YSA9IG5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhIHx8IHtcbiAgICAgICAgaWQ6IHRoaXMuYWN0aXZlU3RhZ2VJZCxcbiAgICAgIH07XG4gICAgICB0aGlzLmFjdGl2ZUVzY2FsYXRpb25UeXBlLnNldChldmVudC50eXBlKTtcbiAgICAgIHRoaXMuYWN0aXZlU3RhZ2VDb2RlLnNldCh0aGlzLmFjdGl2ZVN0YWdlRGF0YT8uQ29kZSB8fCAnJyk7XG4gICAgICBjb25zb2xlLmxvZygnQWN0aXZlIFN0YWdlIERhdGE6JywgdGhpcy5hY3RpdmVTdGFnZURhdGEpO1xuICAgICAgY29uc29sZS5sb2coJ0VzY2FsYXRpb24gVHlwZTonLCB0aGlzLmFjdGl2ZUVzY2FsYXRpb25UeXBlKCkpO1xuICAgICAgdGhpcy5zaG93RXNjYWxhdGlvbkRpYWxvZ0xvY2FsID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGQgdGhpcyBtZXRob2QgdG8gaGFuZGxlIGRpYWxvZyBjbG9zdXJlXG4gIG9uU3RhZ2VEaWFsb2dDbG9zZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93U3RhZ2VEaWFsb2dMb2NhbCA9IGZhbHNlO1xuICAgIHRoaXMuYWN0aXZlU3RhZ2VJZCA9IG51bGw7XG4gICAgdGhpcy5hY3RpdmVTdGFnZURhdGEgPSB7fTtcbiAgfVxuXG4gIG9uQWN0aW9uRGlhbG9nQ2xvc2VkKCk6IHZvaWQge1xuICAgIHRoaXMuc2hvd0FjdGlvbkRpYWxvZ0xvY2FsID0gZmFsc2U7XG4gICAgdGhpcy5hY3RpdmVBY3Rpb25JZCA9IG51bGw7XG4gICAgdGhpcy5hY3RpdmVBY3Rpb25EYXRhID0gbnVsbDtcbiAgfVxuXG4gIC8vIEFkZCB0aGlzIG1ldGhvZCB0byBoYW5kbGUgZGlhbG9nIGNsb3N1cmVcbiAgb25Fc2NhbGF0aW9uRGlhbG9nQ2xvc2VkKCk6IHZvaWQge1xuICAgIHRoaXMuc2hvd0VzY2FsYXRpb25EaWFsb2dMb2NhbCA9IGZhbHNlO1xuICAgIHRoaXMuYWN0aXZlU3RhZ2VJZCA9IG51bGw7XG4gICAgdGhpcy5hY3RpdmVFc2NhbGF0aW9uVHlwZS5zZXQobnVsbCk7XG4gICAgdGhpcy5hY3RpdmVTdGFnZUNvZGUuc2V0KG51bGwpO1xuICAgIHRoaXMuYWN0aXZlU3RhZ2VEYXRhID0ge307XG4gIH1cblxuICAvLyBBZGQgdGhpcyBtZXRob2QgdG8gaGFuZGxlIHNhdmluZyBzdGFnZSBkYXRhXG4gIG9uU3RhZ2VEaWFsb2dTYXZlZChzdGFnZURhdGE6IFBhcnRpYWw8V29ya2Zsb3dTdGFnZT4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hY3RpdmVTdGFnZUlkKSB7XG4gICAgICAvLyBFZGl0aW5nIGFuIGV4aXN0aW5nIHN0YWdlXG4gICAgICBjb25zdCBub2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKHRoaXMuYWN0aXZlU3RhZ2VJZCk7XG4gICAgICBpZiAobm9kZUluZm8pIHtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBzdGFnZSBkYXRhXG4gICAgICAgIG5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhID0ge1xuICAgICAgICAgIC4uLm5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhLFxuICAgICAgICAgIC4uLnN0YWdlRGF0YSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc29sZS5sb2coJ1VwZGF0ZWQgc3RhZ2UgZGF0YTonLCBub2RlSW5mby5ub2RlLnN0YWdlRGF0YSk7XG5cbiAgICAgICAgLy8gRW1pdCBldmVudCBmb3IgcGFyZW50IGNvbXBvbmVudCB0byBrbm93IGFib3V0IHRoZSB1cGRhdGVcbiAgICAgICAgdGhpcy5zdGFnZVByb3BlcnRpZXNVcGRhdGVkLmVtaXQoe1xuICAgICAgICAgIG5vZGVJZDogdGhpcy5hY3RpdmVTdGFnZUlkLFxuICAgICAgICAgIHN0YWdlRGF0YTogbm9kZUluZm8ubm9kZS5zdGFnZURhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENsb3NlIHRoZSBkaWFsb2dcbiAgICB0aGlzLm9uU3RhZ2VEaWFsb2dDbG9zZWQoKTtcbiAgfVxuXG4gIG9uQWN0aW9uRGlhbG9nU2F2ZWQoYWN0aW9uRGF0YTogQ29ubmVjdGlvbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2ZUFjdGlvbklkKSB7XG4gICAgICAvLyBFZGl0aW5nIGFuIGV4aXN0aW5nIHN0YWdlXG4gICAgICAvLyBsZXQgY29ubmVjdGlvbkluZm8gPSB0aGlzLnN0YXRlLmZpbmRBY3Rpb25CeUlkKHRoaXMuYWN0aXZlQWN0aW9uSWQpO1xuICAgICAgdGhpcy5zdGF0ZS5jb25uZWN0aW9ucyA9IHRoaXMuc3RhdGUuY29ubmVjdGlvbnMubWFwKChjb25uZWN0aW9uLCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoY29ubmVjdGlvbi5pZCA9PT0gdGhpcy5hY3RpdmVBY3Rpb25JZCkge1xuICAgICAgICAgIGNvbm5lY3Rpb24ubGFiZWwgPSBhY3Rpb25EYXRhLmxhYmVsO1xuICAgICAgICAgIGNvbm5lY3Rpb24uYWN0aW9uID0gYWN0aW9uRGF0YS5hY3Rpb247XG4gICAgICAgICAgY29ubmVjdGlvbi50YXJnZXRTdGF0dXMgPSBhY3Rpb25EYXRhLnRhcmdldFN0YXR1cztcbiAgICAgICAgICBjb25zb2xlLmxvZygnVXBkYXRlZCBhY3Rpb24gZGF0YTonLCBjb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29ubmVjdGlvbjtcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gQ2xvc2UgdGhlIGRpYWxvZ1xuICAgIHRoaXMub25BY3Rpb25EaWFsb2dDbG9zZWQoKTtcbiAgfVxuXG4gIHVwZGF0ZUNhbnZhc1NpemUoKTogdm9pZCB7XG4gICAgY29uc3QgcmVxdWlyZWRIZWlnaHQgPVxuICAgICAgKHRoaXMuc3RhdGUuc3dpbWxhbmVzLmxlbmd0aCArIDEpICogdGhpcy5zd2ltbGFuZUhlaWdodDtcbiAgICB0aGlzLmNhbnZhc0hlaWdodCA9IE1hdGgubWF4KDIwMDAsIHJlcXVpcmVkSGVpZ2h0KTsgLy8gRW5zdXJlIHdlIGhhdmUgYXQgbGVhc3Qgb3VyIGRlZmF1bHQgaGVpZ2h0XG5cbiAgICAvLyBVcGRhdGUgYWxsIHRoZSBzd2ltbGFuZSBjbGlwIHBhdGhzIHdoZW4gc2l6ZSBjaGFuZ2VzXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlLnN3aW1sYW5lcy5mb3JFYWNoKChzd2ltbGFuZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgY2xpcFBhdGhJZCA9IGBzd2ltbGFuZS1jbGlwLSR7aW5kZXh9YDtcbiAgICAgICAgY29uc3QgY2xpcFBhdGhFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoY2xpcFBhdGhJZCk7XG4gICAgICAgIGlmIChjbGlwUGF0aEVsZW1lbnQpIHtcbiAgICAgICAgICBjb25zdCByZWN0RWxlbWVudCA9IGNsaXBQYXRoRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdyZWN0Jyk7XG4gICAgICAgICAgaWYgKHJlY3RFbGVtZW50KSB7XG4gICAgICAgICAgICByZWN0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy5jYW52YXNXaWR0aC50b1N0cmluZygpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sIDApO1xuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZCB0byBnZXQgdGhlIG1vdXNlIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBTVkcgY2FudmFzXG4gIHByaXZhdGUgZ2V0TW91c2VQb3NpdGlvbihldmVudDogTW91c2VFdmVudCk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB7XG4gICAgLy8gVXNlIGNsaWVudFgvWSBhbmQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgZm9yIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJpbGl0eVxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB4OiBldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0LFxuICAgICAgeTogZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wLFxuICAgIH07XG4gIH1cblxuICAvLyBIZWxwZXIgbWV0aG9kIHRvIGdldCB0aGUgbW91c2UgcG9zaXRpb24gZm9yIHZpZXdwb3J0LWJhc2VkIHBvcHVwc1xuICAvLyBUaGlzIGFjY291bnRzIGZvciBjYW52YXMgc2Nyb2xsIHBvc2l0aW9uXG4gIHByaXZhdGUgZ2V0Vmlld3BvcnRQb3NpdGlvbihjYW52YXNYOiBudW1iZXIsIGNhbnZhc1k6IG51bWJlcik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB7XG4gICAgY29uc3QgcGFyZW50RWxlbWVudCA9IHRoaXMuY2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gcGFyZW50RWxlbWVudD8uc2Nyb2xsTGVmdCB8fCAwO1xuICAgIGNvbnN0IHNjcm9sbFRvcCA9IHBhcmVudEVsZW1lbnQ/LnNjcm9sbFRvcCB8fCAwO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGNhbnZhc1ggLSBzY3JvbGxMZWZ0LFxuICAgICAgeTogY2FudmFzWSAtIHNjcm9sbFRvcCxcbiAgICB9O1xuICB9XG5cbiAgc2hvd0Nvbm5lY3Rpb25Qb2ludHMobm9kZUlkOiBzdHJpbmcsIHN3aW1sYW5lSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmlzaWJsZUNvbm5lY3Rpb25Qb2ludHNOb2RlSWQgPSBub2RlSWQ7XG4gIH1cblxuICBpc01vdXNlT3Zlck5vZGUoXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gICAgbm9kZTogV0ZOb2RlLFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlclxuICApOiBib29sZWFuIHtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuZ2V0TW91c2VQb3NpdGlvbihldmVudCk7XG4gICAgY29uc3Qgbm9kZUJvdW5kcyA9IHRoaXMuZ2V0Tm9kZUJvdW5kc1dpdGhQYWRkaW5nKG5vZGUsIHN3aW1sYW5lSW5kZXgpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIHBvc2l0aW9uLnggPj0gbm9kZUJvdW5kcy54ICYmXG4gICAgICBwb3NpdGlvbi54IDw9IG5vZGVCb3VuZHMueCArIG5vZGVCb3VuZHMud2lkdGggJiZcbiAgICAgIHBvc2l0aW9uLnkgPj0gbm9kZUJvdW5kcy55ICYmXG4gICAgICBwb3NpdGlvbi55IDw9IG5vZGVCb3VuZHMueSArIG5vZGVCb3VuZHMuaGVpZ2h0XG4gICAgKTtcbiAgfVxuXG4gIC8vIGhlbHBlciBtZXRob2QgdG8gY2FsY3VsYXRlIG5vZGUgYm91bmRzIHdpdGggcGFkZGluZ1xuICBnZXROb2RlQm91bmRzV2l0aFBhZGRpbmcoXG4gICAgbm9kZTogV0ZOb2RlLFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlclxuICApOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9IHtcbiAgICBjb25zdCBwYWRkaW5nID0gMTA7IC8vIEFkZCAxMHB4IHBhZGRpbmcgYXJvdW5kIG5vZGVzIGZvciBlYXNpZXIgaG92ZXIgZGV0ZWN0aW9uXG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGFic29sdXRlIFkgcG9zaXRpb24gaW5jbHVkaW5nIHN3aW1sYW5lIG9mZnNldFxuICAgIGNvbnN0IGFic29sdXRlWSA9IG5vZGUueSArIHN3aW1sYW5lSW5kZXggKiAyNjM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogbm9kZS54IC0gcGFkZGluZyxcbiAgICAgIHk6IGFic29sdXRlWSAtIHBhZGRpbmcsXG4gICAgICB3aWR0aDogbm9kZS53aWR0aCArIHBhZGRpbmcgKiAyLFxuICAgICAgaGVpZ2h0OiBub2RlLmhlaWdodCArIHBhZGRpbmcgKiAyLFxuICAgIH07XG4gIH1cblxuICBoaWRlQ29ubmVjdGlvblBvaW50cyhub2RlSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMudmlzaWJsZUNvbm5lY3Rpb25Qb2ludHNOb2RlSWQgPT09IG5vZGVJZCAmJlxuICAgICAgIXRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKVxuICAgICkge1xuICAgICAgdGhpcy52aXNpYmxlQ29ubmVjdGlvblBvaW50c05vZGVJZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgaXNDb25uZWN0aW9uUG9pbnRWaXNpYmxlKG5vZGVJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmlzaWJsZUNvbm5lY3Rpb25Qb2ludHNOb2RlSWQgPT09IG5vZGVJZDtcbiAgfVxuXG4gIHN0YXJ0Q29ubmVjdGlvbkRyYWcoXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gICAgcG9pbnQ6IENvbm5lY3Rpb25Qb2ludCxcbiAgICBzd2ltbGFuZUluZGV4OiBudW1iZXJcbiAgKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYW4gZXhpdCBwb2ludCBub2RlXG4gICAgY29uc3Qgbm9kZUluZm8gPSB0aGlzLnN0YXRlLmZpbmROb2RlQnlJZChwb2ludC5ub2RlSWQpO1xuICAgIGlmIChcbiAgICAgIG5vZGVJbmZvICYmXG4gICAgICBub2RlSW5mby5ub2RlLnR5cGUgPT09ICdzdGFnZScgJiZcbiAgICAgIG5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhPy5Jc0V4aXRQb2ludFxuICAgICkge1xuICAgICAgLy8gRG9uJ3QgYWxsb3cgY29ubmVjdGlvbnMgZnJvbSBleGl0IHBvaW50c1xuICAgICAgY29uc29sZS5sb2coJ0Nhbm5vdCBjcmVhdGUgY29ubmVjdGlvbnMgZnJvbSBleGl0IHBvaW50cycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICB0aGlzLnN0YXRlLnN0YXJ0Q29ubmVjdGlvbkRyYWcoXG4gICAgICBwb2ludCxcbiAgICAgIHN3aW1sYW5lSW5kZXgsXG4gICAgICBwb3NpdGlvbi54LFxuICAgICAgcG9zaXRpb24ueVxuICAgICk7XG5cbiAgICAvLyBBZGQgbW91c2UgbW92ZSBhbmQgbW91c2UgdXAgZXZlbnQgbGlzdGVuZXJzIHRvIHRoZSBkb2N1bWVudFxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25Nb3VzZU1vdmUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcCk7XG4gIH1cblxuICBoaWdobGlnaHRQb3RlbnRpYWxUYXJnZXRzKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpIHJldHVybjtcblxuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICBjb25zdCB0YXJnZXRQb2ludEluZm8gPSB0aGlzLmZpbmRDb25uZWN0aW9uUG9pbnRBdFBvc2l0aW9uKFxuICAgICAgcG9zaXRpb24ueCxcbiAgICAgIHBvc2l0aW9uLnlcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgdGFyZ2V0UG9pbnRJbmZvICYmXG4gICAgICB0YXJnZXRQb2ludEluZm8ucG9pbnQuaWQgIT09IHRoaXMucG90ZW50aWFsVGFyZ2V0UG9pbnRJZFxuICAgICkge1xuICAgICAgLy8gV2UgaGF2ZSBhIG5ldyB0YXJnZXQgcG9pbnRcbiAgICAgIHRoaXMucG90ZW50aWFsVGFyZ2V0UG9pbnRJZCA9IHRhcmdldFBvaW50SW5mby5wb2ludC5pZDtcbiAgICB9IGVsc2UgaWYgKCF0YXJnZXRQb2ludEluZm8gJiYgdGhpcy5wb3RlbnRpYWxUYXJnZXRQb2ludElkKSB7XG4gICAgICAvLyBXZSdyZSBubyBsb25nZXIgb3ZlciBhIHRhcmdldCBwb2ludFxuICAgICAgdGhpcy5wb3RlbnRpYWxUYXJnZXRQb2ludElkID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvLyBVc2UgYXJyb3cgZnVuY3Rpb25zIHRvIHByZXNlcnZlICd0aGlzJyBjb250ZXh0XG4gIG9uTW91c2VNb3ZlID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuICAgIHRoaXMudXBkYXRlQ29ubmVjdGlvbkRyYWcocG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG4gICAgdGhpcy5oaWdobGlnaHRQb3RlbnRpYWxUYXJnZXRzKGV2ZW50KTtcbiAgfTtcblxuICB1cGRhdGVDb25uZWN0aW9uRHJhZyhjdXJyZW50WDogbnVtYmVyLCBjdXJyZW50WTogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUuZHJhZ2dpbmdDb25uZWN0aW9uRGF0YS5zb3VyY2VQb2ludCkge1xuICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLmN1cnJlbnRYID0gY3VycmVudFg7XG4gICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuY3VycmVudFkgPSBjdXJyZW50WTtcblxuICAgICAgLy8gQ2FsY3VsYXRlIHdoaWNoIHN3aW1sYW5lIHRoZSBjdXJzb3IgaXMgb3ZlclxuICAgICAgY29uc3Qgc3dpbWxhbmVJbmRleCA9IE1hdGguZmxvb3IoY3VycmVudFkgLyB0aGlzLnN3aW1sYW5lSGVpZ2h0KTtcbiAgICAgIGlmIChzd2ltbGFuZUluZGV4ID49IDAgJiYgc3dpbWxhbmVJbmRleCA8IHRoaXMuc3RhdGUuc3dpbWxhbmVzLmxlbmd0aCkge1xuICAgICAgICAvLyBFbnN1cmUgdGhlIHRhcmdldCBzd2ltbGFuZSBpcyBmdWxseSB2aXNpYmxlXG4gICAgICAgIHRoaXMuZW5zdXJlU3dpbWxhbmVJblZpZXcoc3dpbWxhbmVJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25Nb3VzZVVwID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZVVwKTtcblxuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICBjb25zb2xlLmxvZygnTW91c2UgdXAgYXQgcG9zaXRpb246JywgcG9zaXRpb24pO1xuICAgIGNvbnNvbGUubG9nKCdJcyBjb25uZWN0aW9uIGRyYWdnaW5nOicsIHRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSk7XG5cbiAgICAvLyBPbmx5IHByb2NlZWQgaWYgd2UgYXJlIGRyYWdnaW5nIGEgY29ubmVjdGlvblxuICAgIGlmICghdGhpcy5zdGF0ZS5pc0Nvbm5lY3Rpb25EcmFnZ2luZygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgZHJvcHBpbmcgb250byBhIGNvbm5lY3Rpb24gcG9pbnRcbiAgICBjb25zdCB0YXJnZXRQb2ludEluZm8gPSB0aGlzLmZpbmRDb25uZWN0aW9uUG9pbnRBdFBvc2l0aW9uKFxuICAgICAgcG9zaXRpb24ueCxcbiAgICAgIHBvc2l0aW9uLnlcbiAgICApO1xuXG4gICAgaWYgKHRhcmdldFBvaW50SW5mbykge1xuICAgICAgLy8gV2UgZm91bmQgYSB0YXJnZXQgY29ubmVjdGlvbiBwb2ludFxuICAgICAgY29uc29sZS5sb2coJ0ZvdW5kIHRhcmdldCBjb25uZWN0aW9uIHBvaW50OicsIHRhcmdldFBvaW50SW5mbyk7XG5cbiAgICAgIC8vIEdldCB0aGUgc291cmNlIHBvaW50IGFuZCBzd2ltbGFuZSBpbmRleFxuICAgICAgY29uc3Qgc291cmNlUG9pbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuc291cmNlUG9pbnQ7XG4gICAgICBjb25zdCBzb3VyY2VTd2ltbGFuZUluZGV4ID1cbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLnNvdXJjZVN3aW1sYW5lSW5kZXg7XG5cbiAgICAgIGlmIChzb3VyY2VQb2ludCAmJiBzb3VyY2VTd2ltbGFuZUluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gUHJldmVudCBjb25uZWN0aW5nIGEgbm9kZSB0byBpdHNlbGZcbiAgICAgICAgaWYgKHNvdXJjZVBvaW50Lm5vZGVJZCAhPT0gdGFyZ2V0UG9pbnRJbmZvLm5vZGVJZCkge1xuICAgICAgICAgIC8vIEdldCBzb3VyY2UgYW5kIHRhcmdldCBub2RlIHR5cGVzIHRvIGNoZWNrIGlmIGNvbm5lY3Rpb24gaXMgYWxsb3dlZFxuICAgICAgICAgIGNvbnN0IHNvdXJjZU5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoc291cmNlUG9pbnQubm9kZUlkKTtcbiAgICAgICAgICBjb25zdCB0YXJnZXROb2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKFxuICAgICAgICAgICAgdGFyZ2V0UG9pbnRJbmZvLm5vZGVJZFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzb3VyY2VOb2RlSW5mbyAmJlxuICAgICAgICAgICAgdGFyZ2V0Tm9kZUluZm8gJiZcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuY2FuQ29ubmVjdChcbiAgICAgICAgICAgICAgc291cmNlTm9kZUluZm8ubm9kZS50eXBlLFxuICAgICAgICAgICAgICB0YXJnZXROb2RlSW5mby5ub2RlLnR5cGVcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgY29ubmVjdGlvblxuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHtcbiAgICAgICAgICAgICAgaWQ6IGBjb25uLSR7RGF0ZS5ub3coKX0tJHtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwKX1gLFxuICAgICAgICAgICAgICBzb3VyY2VOb2RlSWQ6IHNvdXJjZVBvaW50Lm5vZGVJZCxcbiAgICAgICAgICAgICAgdGFyZ2V0Tm9kZUlkOiB0YXJnZXRQb2ludEluZm8ubm9kZUlkLFxuICAgICAgICAgICAgICBzb3VyY2VQb2ludElkOiBzb3VyY2VQb2ludC5pZCxcbiAgICAgICAgICAgICAgdGFyZ2V0UG9pbnRJZDogdGFyZ2V0UG9pbnRJbmZvLnBvaW50LmlkLFxuICAgICAgICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4OiBzb3VyY2VTd2ltbGFuZUluZGV4LFxuICAgICAgICAgICAgICB0YXJnZXRTd2ltbGFuZUluZGV4OiB0YXJnZXRQb2ludEluZm8uc3dpbWxhbmVJbmRleCxcbiAgICAgICAgICAgICAgbGFiZWw6ICcnLFxuICAgICAgICAgICAgICBhY3Rpb246IG51bGwsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBBZGQgdG8gY29ubmVjdGlvbnMgYXJyYXlcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuY29ubmVjdGlvbnMucHVzaChjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDcmVhdGVkIGRpcmVjdCBjb25uZWN0aW9uIGJldHdlZW4gbm9kZXM6JywgY29ubmVjdGlvbik7XG5cbiAgICAgICAgICAgIC8vIE5vdGlmeSBhYm91dCBjb25uZWN0aW9uIGNyZWF0aW9uXG4gICAgICAgICAgICB0aGlzLm9uQ29ubmVjdGlvbkNyZWF0ZWQoY29ubmVjdGlvbik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAnQ2Fubm90IGNvbm5lY3QgdGhlc2Ugbm9kZSB0eXBlczonLFxuICAgICAgICAgICAgICBzb3VyY2VOb2RlSW5mbz8ubm9kZS50eXBlLFxuICAgICAgICAgICAgICAnLT4nLFxuICAgICAgICAgICAgICB0YXJnZXROb2RlSW5mbz8ubm9kZS50eXBlXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnQ2Fubm90IGNvbm5lY3QgYSBub2RlIHRvIGl0c2VsZicpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEVuZCB0aGUgY29ubmVjdGlvbiBkcmFnXG4gICAgICB0aGlzLnN0YXRlLmVuZENvbm5lY3Rpb25EcmFnKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHBvc2l0aW9uIGlzIHdpdGhpbiBhbnkgc3dpbWxhbmVcbiAgICBjb25zdCBpc0luc2lkZVN3aW1sYW5lID0gdGhpcy5pc1Bvc2l0aW9uSW5zaWRlU3dpbWxhbmUocG9zaXRpb24ueSk7XG4gICAgY29uc29sZS5sb2coJ0lzIGluc2lkZSBzd2ltbGFuZTonLCBpc0luc2lkZVN3aW1sYW5lKTtcblxuICAgIC8vIE9ubHkgc2hvdyBwb3B1cCBpZiB3aXRoaW4gYSBzd2ltbGFuZVxuICAgIGlmIChpc0luc2lkZVN3aW1sYW5lICYmIHRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSkge1xuICAgICAgY29uc29sZS5sb2coJ1Nob3dpbmcgY29ubmVjdGlvbiBwb3B1cCcpO1xuICAgICAgdGhpcy5zaG93Q29ubmVjdGlvblBvcHVwKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBFbmQgdGhlIGNvbm5lY3Rpb24gZHJhZyBpZiBvdXRzaWRlIGEgc3dpbWxhbmVcbiAgICAgIGNvbnNvbGUubG9nKCdFbmRpbmcgY29ubmVjdGlvbiBkcmFnIHdpdGhvdXQgc2hvd2luZyBwb3B1cCcpO1xuICAgICAgdGhpcy5zdGF0ZS5lbmRDb25uZWN0aW9uRHJhZygpO1xuICAgIH1cbiAgfTtcblxuICBmaW5kQ29ubmVjdGlvblBvaW50QXRQb3NpdGlvbihcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIHRvbGVyYW5jZTogbnVtYmVyID0gMTBcbiAgKToge1xuICAgIHBvaW50OiBDb25uZWN0aW9uUG9pbnQ7XG4gICAgbm9kZUlkOiBzdHJpbmc7XG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyO1xuICB9IHwgbnVsbCB7XG4gICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBzd2ltbGFuZXMgYW5kIG5vZGVzIHRvIGZpbmQgY29ubmVjdGlvbiBwb2ludHNcbiAgICBmb3IgKFxuICAgICAgbGV0IHN3aW1sYW5lSW5kZXggPSAwO1xuICAgICAgc3dpbWxhbmVJbmRleCA8IHRoaXMuc3RhdGUuc3dpbWxhbmVzLmxlbmd0aDtcbiAgICAgIHN3aW1sYW5lSW5kZXgrK1xuICAgICkge1xuICAgICAgY29uc3Qgc3dpbWxhbmUgPSB0aGlzLnN0YXRlLnN3aW1sYW5lc1tzd2ltbGFuZUluZGV4XTtcblxuICAgICAgaWYgKCFzd2ltbGFuZS5ub2RlcykgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBzd2ltbGFuZS5ub2Rlcykge1xuICAgICAgICBpZiAoIW5vZGUuY29ubmVjdGlvblBvaW50cykgY29udGludWU7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBhYnNvbHV0ZSBwb3NpdGlvbiBvZiB0aGUgbm9kZSAoaW5jbHVkaW5nIHN3aW1sYW5lIG9mZnNldClcbiAgICAgICAgY29uc3QgYWJzb2x1dGVOb2RlWCA9IG5vZGUueDtcbiAgICAgICAgY29uc3QgYWJzb2x1dGVOb2RlWSA9IG5vZGUueSArIHN3aW1sYW5lSW5kZXggKiB0aGlzLnN3aW1sYW5lSGVpZ2h0O1xuXG4gICAgICAgIGZvciAoY29uc3QgcG9pbnQgb2Ygbm9kZS5jb25uZWN0aW9uUG9pbnRzKSB7XG4gICAgICAgICAgLy8gQ2FsY3VsYXRlIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSBjb25uZWN0aW9uIHBvaW50XG4gICAgICAgICAgY29uc3QgcG9pbnRYID0gYWJzb2x1dGVOb2RlWCArIHBvaW50Lng7XG4gICAgICAgICAgY29uc3QgcG9pbnRZID0gYWJzb2x1dGVOb2RlWSArIHBvaW50Lnk7XG5cbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgZ2l2ZW4gcG9zaXRpb24gaXMgd2l0aGluIHRvbGVyYW5jZSBvZiB0aGlzIHBvaW50XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgTWF0aC5hYnMoeCAtIHBvaW50WCkgPD0gdG9sZXJhbmNlICYmXG4gICAgICAgICAgICBNYXRoLmFicyh5IC0gcG9pbnRZKSA8PSB0b2xlcmFuY2VcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgICAgICAgICAgbm9kZUlkOiBub2RlLmlkLFxuICAgICAgICAgICAgICBzd2ltbGFuZUluZGV4OiBzd2ltbGFuZUluZGV4LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlzUG9zaXRpb25JbnNpZGVTd2ltbGFuZSh5OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAvLyBDaGVjayBpZiB5IHBvc2l0aW9uIGlzIHdpdGhpbiBhbnkgc3dpbWxhbmVcbiAgICBjb25zdCBzd2ltbGFuZUNvdW50ID0gdGhpcy5zdGF0ZS5zd2ltbGFuZXMubGVuZ3RoO1xuICAgIGlmIChzd2ltbGFuZUNvdW50ID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBFYWNoIHN3aW1sYW5lIGhhcyBhIGhlaWdodCBvZiAyNjNweFxuICAgIGNvbnN0IHRvdGFsU3dpbWxhbmVIZWlnaHQgPSBzd2ltbGFuZUNvdW50ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcblxuICAgIC8vIENoZWNrIGlmIHkgaXMgd2l0aGluIHRoZSB0b3RhbCBoZWlnaHQgb2YgYWxsIHN3aW1sYW5lc1xuICAgIHJldHVybiB5ID49IDAgJiYgeSA8IHRvdGFsU3dpbWxhbmVIZWlnaHQ7XG4gIH1cblxuICBzaG93Q29ubmVjdGlvblBvcHVwKHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ1Nob3dpbmcgY29ubmVjdGlvbiBwb3B1cCBhdDonLCB4LCB5KTtcblxuICAgIC8vIENvbnZlcnQgY2FudmFzIGNvb3JkaW5hdGVzIHRvIHZpZXdwb3J0IGNvb3JkaW5hdGVzIGZvciBwb3B1cCBwb3NpdGlvbmluZ1xuICAgIGNvbnN0IHZpZXdwb3J0UG9zID0gdGhpcy5nZXRWaWV3cG9ydFBvc2l0aW9uKHgsIHkpO1xuICAgIHRoaXMucG9wdXBYID0gdmlld3BvcnRQb3MueDtcbiAgICB0aGlzLnBvcHVwWSA9IHZpZXdwb3J0UG9zLnk7XG5cbiAgICAvLyBHZXQgYWxsb3dlZCBub2RlIHR5cGVzIGJhc2VkIG9uIHRoZSBzb3VyY2Ugbm9kZSB0eXBlXG4gICAgdGhpcy5hbGxvd2VkTm9kZVR5cGVzID0gdGhpcy5zdGF0ZS5nZXRBbGxvd2VkVGFyZ2V0Tm9kZVR5cGVzKCk7XG4gICAgY29uc29sZS5sb2coJ0FsbG93ZWQgbm9kZSB0eXBlczonLCB0aGlzLmFsbG93ZWROb2RlVHlwZXMpO1xuXG4gICAgLy8gT25seSBzaG93IHRoZSBwb3B1cCBpZiB3ZSBoYXZlIGFsbG93ZWQgbm9kZSB0eXBlc1xuICAgIGlmICh0aGlzLmFsbG93ZWROb2RlVHlwZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5wb3B1cFZpc2libGUgPSB0cnVlO1xuICAgICAgY29uc29sZS5sb2coJ1BvcHVwIHZpc2liaWxpdHkgc2V0IHRvIHRydWUnKTtcblxuICAgICAgLy8gRm9yY2UgdGhlIHBvcHVwIHRvIGJlIHZpc2libGUgaW4gdGhlIG5leHQgdGlja1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdJcyBwb3B1cCB2aXNpYmxlIGluIG5leHQgdGljazonLCB0aGlzLnBvcHVwVmlzaWJsZSk7XG4gICAgICB9LCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gYWxsb3dlZCBub2RlIHR5cGVzLCBqdXN0IGVuZCB0aGUgZHJhZ1xuICAgICAgY29uc29sZS5sb2coJ05vIGFsbG93ZWQgbm9kZSB0eXBlcywgZW5kaW5nIGRyYWcnKTtcbiAgICAgIHRoaXMuc3RhdGUuZW5kQ29ubmVjdGlvbkRyYWcoKTtcbiAgICB9XG4gIH1cblxuICBoaWRlQ29ubmVjdGlvblBvcHVwKCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdDYWxsIHRvIGhpZGUnKTtcbiAgICB0aGlzLnBvcHVwVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuc3RhdGUuZW5kQ29ubmVjdGlvbkRyYWcoKTtcbiAgfVxuXG4gIC8vIEFkZCB0aGlzIGhhbmRsZXIgdG8gY2xvc2UgdGhlIHBvcHVwIHdoZW4gY2xpY2tpbmcgb3V0c2lkZVxuICAvLyBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIC8vIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAvLyAgIGlmICh0aGlzLnBvcHVwVmlzaWJsZSkge1xuICAvLyAgICAgY29uc3QgcG9wdXBFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndmVyYmVuLXBvcC1VcCcpO1xuICAvLyAgICAgaWYgKHBvcHVwRWxlbWVudCAmJiAhcG9wdXBFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCBhcyBOb2RlKSkge1xuICAvLyAgICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgLy8gICAgIH1cbiAgLy8gICB9XG4gIC8vIH1cblxuICBjcmVhdGVOb2RlQ29ubmVjdGlvbihub2RlVHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcGF0aERhdGEgPSB0aGlzLnN0YXRlLmdldENvbm5lY3Rpb25QYXRoRGF0YSgpO1xuICAgIGlmICghcGF0aERhdGEpIHtcbiAgICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRoaXMgbm9kZSB0eXBlIGlzIGFsbG93ZWQgdG8gYmUgY3JlYXRlZFxuICAgIGNvbnN0IGFsbG93ZWRUeXBlcyA9IHRoaXMuc3RhdGUuZ2V0QWxsb3dlZFRhcmdldE5vZGVUeXBlcygpO1xuICAgIGlmICghYWxsb3dlZFR5cGVzLmluY2x1ZGVzKG5vZGVUeXBlKSkge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYENhbm5vdCBjcmVhdGUgY29ubmVjdGlvbiB0byAke25vZGVUeXBlfSBmcm9tIGN1cnJlbnQgbm9kZSB0eXBlYFxuICAgICAgKTtcbiAgICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZW5kWCwgZW5kWSwgc291cmNlU3dpbWxhbmVJbmRleCB9ID0gcGF0aERhdGE7XG5cbiAgICAvLyBHZXQgc291cmNlIG5vZGUgaW5mb1xuICAgIGNvbnN0IHNvdXJjZVBvaW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLnNvdXJjZVBvaW50O1xuICAgIGlmICghc291cmNlUG9pbnQpIHtcbiAgICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZU5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoc291cmNlUG9pbnQubm9kZUlkKTtcbiAgICBpZiAoIXNvdXJjZU5vZGVJbmZvKSB7XG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiBjb25uZWN0aW5nIGZyb20gYSBkZWNpc2lvbiB0byBhIHN0YWdlLCBzaG93IGNvbmRpdGlvbiBwb3B1cCBmaXJzdFxuICAgIGlmIChzb3VyY2VOb2RlSW5mby5ub2RlLnR5cGUgPT09ICdkZWNpc2lvbicgJiYgbm9kZVR5cGUgPT09ICdzdGFnZScpIHtcbiAgICAgIC8vIFN0b3JlIGluZm9ybWF0aW9uIGZvciBsYXRlciBzdGFnZSBjcmVhdGlvblxuICAgICAgdGhpcy5wZW5kaW5nRGVjaXNpb25Db25uZWN0aW9uID0ge1xuICAgICAgICBkZWNpc2lvbk5vZGVJZDogc291cmNlTm9kZUluZm8ubm9kZS5pZCxcbiAgICAgICAgc3dpbWxhbmVJbmRleDogc291cmNlU3dpbWxhbmVJbmRleCxcbiAgICAgICAgeDogZW5kWCxcbiAgICAgICAgeTogZW5kWSxcbiAgICAgIH07XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBwb3B1cCBwb3NpdGlvbiAtIHBvc2l0aW9uIGl0IG5lYXIgdGhlIGRlY2lzaW9uIG5vZGVcbiAgICAgIGNvbnN0IHN3aW1sYW5lT2Zmc2V0WSA9IHNvdXJjZVN3aW1sYW5lSW5kZXggKiAyNjM7XG5cbiAgICAgIC8vIENlbnRlciB0aGUgcG9wdXAgb3ZlciB0aGUgY29ubmVjdGlvbiBlbmRwb2ludFxuICAgICAgdGhpcy5kZWNpc2lvbkNvbmRpdGlvblBvcHVwWCA9IGVuZFg7XG4gICAgICB0aGlzLmRlY2lzaW9uQ29uZGl0aW9uUG9wdXBZID0gZW5kWSAtIDE1MDsgLy8gUG9zaXRpb24gYWJvdmUgdGhlIGVuZHBvaW50XG5cbiAgICAgIC8vIFNldCBkZWNpc2lvbiBub2RlIElEXG4gICAgICB0aGlzLmFjdGl2ZURlY2lzaW9uTm9kZUlkID0gc291cmNlTm9kZUluZm8ubm9kZS5pZDtcbiAgICAgIHRoaXMuc2hvd0RlY2lzaW9uQ29uZGl0aW9uRGlhbG9nID0gdHJ1ZTtcblxuICAgICAgLy8gRW5kIHRoZSBjb25uZWN0aW9uIGRyYWdcbiAgICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN3aW1sYW5lSW5kZXggPSBNYXRoLmZsb29yKGVuZFkgLyB0aGlzLnN3aW1sYW5lSGVpZ2h0KTtcbiAgICBjb25zdCBzd2ltbGFuZVRvcCA9IHN3aW1sYW5lSW5kZXggKiB0aGlzLnN3aW1sYW5lSGVpZ2h0O1xuICAgIC8vIENhbGN1bGF0ZSBzd2ltbGFuZS1yZWxhdGl2ZSBwb3NpdGlvblxuICAgIGNvbnN0IHN3aW1sYW5lT2Zmc2V0WSA9IHNvdXJjZVN3aW1sYW5lSW5kZXggKiAyNjM7XG4gICAgbGV0IHJlbGF0aXZlWSA9IGVuZFkgLSBzd2ltbGFuZU9mZnNldFkgLSA1MDsgLy8gQWRkIGhhbGYgbm9kZSBoZWlnaHQgZm9yIGJldHRlciBhbGlnbm1lbnRcbiAgICBjb25zdCBzd2ltbGFuZUJvdHRvbSA9IHN3aW1sYW5lVG9wICsgMjYzO1xuXG4gICAgLy8gQ2xhbXAgbm9kZVkgc28gbm9kZSBzdGF5cyB3aXRoaW4gc3dpbWxhbmVcblxuICAgIGNvbnNvbGUubG9nKGVuZFksIHN3aW1sYW5lSW5kZXgsIHN3aW1sYW5lT2Zmc2V0WSwgc3dpbWxhbmVCb3R0b20pO1xuXG4gICAgaWYgKGVuZFkgLSA1MCA8IHN3aW1sYW5lVG9wKSB7XG4gICAgICBjb25zb2xlLmxvZygnTGVzcycpO1xuICAgICAgcmVsYXRpdmVZID0gc3dpbWxhbmVUb3A7IC8vIE5vZGUgd291bGQgb3ZlcmZsb3cgYWJvdmUsIHNvIGFsaWduIHRvIHRvcFxuICAgIH0gZWxzZSBpZiAoZW5kWSArIDUwID4gc3dpbWxhbmVCb3R0b20pIHtcbiAgICAgIGNvbnNvbGUubG9nKCdNb3JlJyk7XG4gICAgICByZWxhdGl2ZVkgPSBzd2ltbGFuZUJvdHRvbSAtIDEwMDsgLy8gTm9kZSB3b3VsZCBvdmVyZmxvdyBiZWxvdywgc28gYWxpZ24gdG8gYm90dG9tXG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHByZWNvbmRpdGlvbnMgYmFzZWQgb24gbm9kZSB0eXBlXG4gICAgaWYgKG5vZGVUeXBlID09PSAnc3RhZ2UnKSB7XG4gICAgICAvLyBDcmVhdGUgdGhlIHN0YWdlIGRpcmVjdGx5IHdpdGggZGVmYXVsdCBwcm9wZXJ0aWVzXG4gICAgICBjb25zdCBuZXdOb2RlID0gdGhpcy5zdGF0ZS5hZGROb2RlKFxuICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4LFxuICAgICAgICAnc3RhZ2UnLFxuICAgICAgICBlbmRYLFxuICAgICAgICByZWxhdGl2ZVksXG4gICAgICAgIHsgTmFtZTogJ05ldyBTdGFnZScgfSAvLyBBZGQgZGVmYXVsdCBwcm9wZXJ0aWVzXG4gICAgICApO1xuXG4gICAgICBpZiAoXG4gICAgICAgIG5ld05vZGUgJiZcbiAgICAgICAgbmV3Tm9kZS5jb25uZWN0aW9uUG9pbnRzICYmXG4gICAgICAgIG5ld05vZGUuY29ubmVjdGlvblBvaW50cy5sZW5ndGggPiAwICYmXG4gICAgICAgIHNvdXJjZVBvaW50XG4gICAgICApIHtcbiAgICAgICAgLy8gSGFuZGxlIGNvbm5lY3Rpb24gY3JlYXRpb25cbiAgICAgICAgY29uc3Qgb3Bwb3NpbmdUeXBlID0ge1xuICAgICAgICAgIHJpZ2h0OiAnbGVmdCcsXG4gICAgICAgICAgbGVmdDogJ3JpZ2h0JyxcbiAgICAgICAgICB0b3A6ICdib3R0b20nLFxuICAgICAgICAgIGJvdHRvbTogJ3RvcCcsXG4gICAgICAgIH1bc291cmNlUG9pbnQudHlwZV0gYXMgJ3RvcCcgfCAncmlnaHQnIHwgJ2JvdHRvbScgfCAnbGVmdCc7XG5cbiAgICAgICAgY29uc3QgdGFyZ2V0UG9pbnQgPSBuZXdOb2RlLmNvbm5lY3Rpb25Qb2ludHMuZmluZChcbiAgICAgICAgICAocCkgPT4gcC50eXBlID09PSBvcHBvc2luZ1R5cGVcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGFyZ2V0UG9pbnQpIHtcbiAgICAgICAgICAvLyBDcmVhdGUgdGhlIGNvbm5lY3Rpb25cbiAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5zdGF0ZS5jcmVhdGVDb25uZWN0aW9uKFxuICAgICAgICAgICAgbmV3Tm9kZS5pZCxcbiAgICAgICAgICAgIHRhcmdldFBvaW50LmlkLFxuICAgICAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoY29ubmVjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5vbkNvbm5lY3Rpb25DcmVhdGVkKGNvbm5lY3Rpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKG5vZGVUeXBlID09PSAnc3ViZmxvdycpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAnQ3JlYXRpbmcgc3ViZmxvdyBmcm9tIGNvbm5lY3Rpb24gYXQ6JyxcbiAgICAgICAgZW5kWCxcbiAgICAgICAgZW5kWSxcbiAgICAgICAgJ3N3aW1sYW5lOicsXG4gICAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXhcbiAgICAgICk7XG4gICAgICAvLyBTaG93IHdvcmtmbG93IHNlbGVjdGlvbiBwb3B1cCBhbmQgc3RvcmUgY29ubmVjdGlvbiBkYXRhIGZvciBsYXRlciB1c2VcbiAgICAgIHRoaXMuc2hvd1N1YmZsb3dTZWxlY3Rpb25Qb3B1cChlbmRYLCBlbmRZLCBzb3VyY2VTd2ltbGFuZUluZGV4KTtcbiAgICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEZvciBvdGhlciBub2RlcyBDcmVhdGUgdGhlIG5ldyBub2RlIGF0IHRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIGNvbm5lY3Rpb25cbiAgICBjb25zdCBuZXdOb2RlID0gdGhpcy5zdGF0ZS5hZGROb2RlKFxuICAgICAgc291cmNlU3dpbWxhbmVJbmRleCxcbiAgICAgIG5vZGVUeXBlIGFzIFRvb2xUeXBlLFxuICAgICAgZW5kWCxcbiAgICAgIHJlbGF0aXZlWVxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICBuZXdOb2RlICYmXG4gICAgICBuZXdOb2RlLmNvbm5lY3Rpb25Qb2ludHMgJiZcbiAgICAgIG5ld05vZGUuY29ubmVjdGlvblBvaW50cy5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICAvLyBGaW5kIHRoZSBtb3N0IGFwcHJvcHJpYXRlIGNvbm5lY3Rpb24gcG9pbnQgKGNsb3Nlc3QgdG8gdGhlIHNvdXJjZSlcbiAgICAgIGlmIChzb3VyY2VQb2ludCkge1xuICAgICAgICAvLyBGb3Igc2ltcGxpY2l0eSwgdXNlIHRoZSBmaXJzdCBjb25uZWN0aW9uIHBvaW50IG9mIG9wcG9zaW5nIHR5cGVcbiAgICAgICAgLy8gSW4gYSByZWFsIGltcGxlbWVudGF0aW9uLCB5b3UnZCBmaW5kIHRoZSBjbG9zZXN0IG9yIG1vc3QgYXBwcm9wcmlhdGUgcG9pbnRcbiAgICAgICAgbGV0IHRhcmdldFBvaW50O1xuXG4gICAgICAgIC8vIElmIHNvdXJjZSBpcyBvbiByaWdodCwgdGFyZ2V0IHNob3VsZCBiZSBvbiBsZWZ0LCBldGMuXG4gICAgICAgIGNvbnN0IG9wcG9zaW5nVHlwZSA9IHtcbiAgICAgICAgICByaWdodDogJ2xlZnQnLFxuICAgICAgICAgIGxlZnQ6ICdyaWdodCcsXG4gICAgICAgICAgdG9wOiAnYm90dG9tJyxcbiAgICAgICAgICBib3R0b206ICd0b3AnLFxuICAgICAgICB9W3NvdXJjZVBvaW50LnR5cGVdIGFzICd0b3AnIHwgJ3JpZ2h0JyB8ICdib3R0b20nIHwgJ2xlZnQnO1xuXG4gICAgICAgIHRhcmdldFBvaW50ID0gbmV3Tm9kZS5jb25uZWN0aW9uUG9pbnRzLmZpbmQoXG4gICAgICAgICAgKHApID0+IHAudHlwZSA9PT0gb3Bwb3NpbmdUeXBlXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRhcmdldFBvaW50KSB7XG4gICAgICAgICAgLy8gQ3JlYXRlIHRoZSBjb25uZWN0aW9uXG4gICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuc3RhdGUuY3JlYXRlQ29ubmVjdGlvbihcbiAgICAgICAgICAgIG5ld05vZGUuaWQsXG4gICAgICAgICAgICB0YXJnZXRQb2ludC5pZCxcbiAgICAgICAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXhcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMub25Db25uZWN0aW9uQ3JlYXRlZChjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc291cmNlTm9kZUluZm8pIHtcbiAgICAgIHRoaXMudXBkYXRlTm9kZUNvbm5lY3Rpb25zKHNvdXJjZU5vZGVJbmZvLm5vZGUpO1xuICAgIH1cblxuICAgIC8vIEVuZCB0aGUgY29ubmVjdGlvbiBkcmFnXG4gICAgdGhpcy5oaWRlQ29ubmVjdGlvblBvcHVwKCk7XG4gIH1cblxuICAvLyBNZXRob2QgdG8gaGFuZGxlIHNhdmluZyB0aGUgY29uZGl0aW9uXG4gIG9uRGVjaXNpb25Db25kaXRpb25TYXZlZChldmVudDoge1xuICAgIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuICAgIGNvbmRpdGlvbjogc3RyaW5nO1xuICB9KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBlbmRpbmdEZWNpc2lvbkNvbm5lY3Rpb24pIHtcbiAgICAgIHRoaXMuc2hvd0RlY2lzaW9uQ29uZGl0aW9uRGlhbG9nID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBkZWNpc2lvbk5vZGVJZCwgc3dpbWxhbmVJbmRleCwgeCwgeSB9ID1cbiAgICAgIHRoaXMucGVuZGluZ0RlY2lzaW9uQ29ubmVjdGlvbjtcblxuICAgIC8vIENyZWF0ZSB0aGUgc3RhZ2UgZGlyZWN0bHkgd2l0aCBkZWZhdWx0IHByb3BlcnRpZXNcbiAgICBjb25zdCBub2RlID0gdGhpcy5zdGF0ZS5hZGROb2RlKFxuICAgICAgc3dpbWxhbmVJbmRleCxcbiAgICAgICdzdGFnZScsXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHsgTmFtZTogJ05ldyBTdGFnZScgfSAvLyBBZGQgZGVmYXVsdCBwcm9wZXJ0aWVzXG4gICAgKTtcblxuICAgIGlmIChub2RlKSB7XG4gICAgICBjb25zdCBkZWNpc2lvbk5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoZGVjaXNpb25Ob2RlSWQpO1xuXG4gICAgICBpZiAoXG4gICAgICAgIGRlY2lzaW9uTm9kZUluZm8gJiZcbiAgICAgICAgbm9kZS5jb25uZWN0aW9uUG9pbnRzICYmXG4gICAgICAgIG5vZGUuY29ubmVjdGlvblBvaW50cy5sZW5ndGggPiAwXG4gICAgICApIHtcbiAgICAgICAgLy8gRmluZCBhIHN1aXRhYmxlIGNvbm5lY3Rpb24gcG9pbnQgZnJvbSB0aGUgZGVjaXNpb24gbm9kZVxuICAgICAgICBjb25zdCBkZWNpc2lvbk5vZGUgPSBkZWNpc2lvbk5vZGVJbmZvLm5vZGU7XG4gICAgICAgIGNvbnN0IGRlY2lzaW9uTm9kZVBvaW50cyA9IGRlY2lzaW9uTm9kZS5jb25uZWN0aW9uUG9pbnRzIHx8IFtdO1xuICAgICAgICBjb25zdCBzb3VyY2VQb2ludCA9IGRlY2lzaW9uTm9kZVBvaW50cy5maW5kKFxuICAgICAgICAgIChwKSA9PiBwLnR5cGUgPT09ICdyaWdodCcgfHwgcC50eXBlID09PSAnYm90dG9tJ1xuICAgICAgICApO1xuXG4gICAgICAgIGlmIChzb3VyY2VQb2ludCkge1xuICAgICAgICAgIC8vIEZpbmQgb3Bwb3NpbmcgdHlwZSBjb25uZWN0aW9uIHBvaW50IG9uIHRoZSBuZXcgc3RhZ2VcbiAgICAgICAgICBjb25zdCBvcHBvc2luZ1R5cGUgPSB7XG4gICAgICAgICAgICByaWdodDogJ2xlZnQnLFxuICAgICAgICAgICAgYm90dG9tOiAndG9wJyxcbiAgICAgICAgICAgIGxlZnQ6ICdyaWdodCcsXG4gICAgICAgICAgICB0b3A6ICdib3R0b20nLFxuICAgICAgICAgIH1bc291cmNlUG9pbnQudHlwZV0gYXMgJ3RvcCcgfCAncmlnaHQnIHwgJ2JvdHRvbScgfCAnbGVmdCc7XG5cbiAgICAgICAgICBjb25zdCB0YXJnZXRQb2ludCA9IG5vZGUuY29ubmVjdGlvblBvaW50cy5maW5kKFxuICAgICAgICAgICAgKHApID0+IHAudHlwZSA9PT0gb3Bwb3NpbmdUeXBlXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmICh0YXJnZXRQb2ludCkge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGNvbm5lY3Rpb24gd2l0aCBjb25kaXRpb25cbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB7XG4gICAgICAgICAgICAgIGlkOiBgY29ubi0ke0RhdGUubm93KCl9LSR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9YCxcbiAgICAgICAgICAgICAgc291cmNlTm9kZUlkOiBkZWNpc2lvbk5vZGUuaWQsXG4gICAgICAgICAgICAgIHRhcmdldE5vZGVJZDogbm9kZS5pZCxcbiAgICAgICAgICAgICAgc291cmNlUG9pbnRJZDogc291cmNlUG9pbnQuaWQsXG4gICAgICAgICAgICAgIHRhcmdldFBvaW50SWQ6IHRhcmdldFBvaW50LmlkLFxuICAgICAgICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4OiBkZWNpc2lvbk5vZGVJbmZvLnN3aW1sYW5lSW5kZXgsXG4gICAgICAgICAgICAgIHRhcmdldFN3aW1sYW5lSW5kZXg6IHN3aW1sYW5lSW5kZXgsXG4gICAgICAgICAgICAgIGNvbmRpdGlvbjogZXZlbnQuY29uZGl0aW9uLFxuICAgICAgICAgICAgICBsYWJlbDogJycsXG4gICAgICAgICAgICAgIGFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIEFkZCBjb25uZWN0aW9uIHRvIHRoZSBzdGF0ZVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICdDcmVhdGVkIGRlY2lzaW9uIGNvbm5lY3Rpb24gd2l0aCBjb25kaXRpb246JyxcbiAgICAgICAgICAgICAgY29ubmVjdGlvblxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDbGVhciBwZW5kaW5nIGRhdGFcbiAgICB0aGlzLnBlbmRpbmdEZWNpc2lvbkNvbm5lY3Rpb24gPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ0RlY2lzaW9uQ29uZGl0aW9uID0gJyc7XG5cbiAgICAvLyBIaWRlIHRoZSBjb25kaXRpb24gcG9wdXBcbiAgICB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyA9IGZhbHNlO1xuICB9XG5cbiAgb25EZWNpc2lvbkNvbmRpdGlvbkNhbmNlbGxlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyA9IGZhbHNlO1xuICAgIC8vIERvbid0IGNyZWF0ZSB0aGUgc3RhZ2Ugb3IgY29ubmVjdGlvblxuICB9XG5cbiAgZ2V0Q29ubmVjdGlvblBhdGgoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXRoRGF0YSA9IHRoaXMuc3RhdGUuZ2V0Q29ubmVjdGlvblBhdGhEYXRhKCk7XG4gICAgaWYgKCFwYXRoRGF0YSkgcmV0dXJuICcnO1xuXG4gICAgY29uc3QgeyBzdGFydFgsIHN0YXJ0WSwgZW5kWCwgZW5kWSB9ID0gcGF0aERhdGE7XG4gICAgY29uc3Qgc291cmNlUG9pbnQgPSB0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuc291cmNlUG9pbnQ7XG5cbiAgICBpZiAoIXNvdXJjZVBvaW50KSByZXR1cm4gJyc7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRPcnRob2dvbmFsUGF0aChzdGFydFgsIHN0YXJ0WSwgZW5kWCwgZW5kWSwgc291cmNlUG9pbnQudHlwZSk7XG4gIH1cblxuICBnZXRDb25uZWN0aW9uUGF0aEZvclNhdmVkQ29ubmVjdGlvbihjb25uZWN0aW9uOiBDb25uZWN0aW9uKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGF0aERhdGEgPSB0aGlzLnN0YXRlLmdldENvbm5lY3Rpb25EYXRhKGNvbm5lY3Rpb24pO1xuICAgICAgaWYgKCFwYXRoRGF0YSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdObyBwYXRoIGRhdGEgZm9yIGNvbm5lY3Rpb246JywgY29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBzdGFydFgsIHN0YXJ0WSwgZW5kWCwgZW5kWSB9ID0gcGF0aERhdGE7XG5cbiAgICAgIGNvbnN0IHNvdXJjZU5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoY29ubmVjdGlvbi5zb3VyY2VOb2RlSWQpO1xuICAgICAgaWYgKCFzb3VyY2VOb2RlSW5mbykge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdTb3VyY2Ugbm9kZSBub3QgZm91bmQgZm9yIGNvbm5lY3Rpb246JywgY29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlTm9kZSA9IHNvdXJjZU5vZGVJbmZvLm5vZGU7XG4gICAgICBjb25zdCBzb3VyY2VQb2ludCA9IHNvdXJjZU5vZGUuY29ubmVjdGlvblBvaW50cz8uZmluZChcbiAgICAgICAgKHApID0+IHAuaWQgPT09IGNvbm5lY3Rpb24uc291cmNlUG9pbnRJZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFzb3VyY2VQb2ludCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdTb3VyY2UgcG9pbnQgbm90IGZvdW5kIGZvciBjb25uZWN0aW9uOicsIGNvbm5lY3Rpb24pO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmdldE9ydGhvZ29uYWxQYXRoKFxuICAgICAgICBzdGFydFgsXG4gICAgICAgIHN0YXJ0WSxcbiAgICAgICAgZW5kWCxcbiAgICAgICAgZW5kWSxcbiAgICAgICAgc291cmNlUG9pbnQudHlwZVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2VuZXJhdGluZyBwYXRoIGZvciBjb25uZWN0aW9uOicsIGNvbm5lY3Rpb24sIGVycm9yKTtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cblxuICBnZXRPcnRob2dvbmFsUGF0aChcbiAgICBzdGFydFg6IG51bWJlcixcbiAgICBzdGFydFk6IG51bWJlcixcbiAgICBlbmRYOiBudW1iZXIsXG4gICAgZW5kWTogbnVtYmVyLFxuICAgIHBvaW50VHlwZTogJ3RvcCcgfCAncmlnaHQnIHwgJ2JvdHRvbScgfCAnbGVmdCdcbiAgKTogc3RyaW5nIHtcbiAgICAvLyBEZXRlcm1pbmUgaW5pdGlhbCBkaXJlY3Rpb24gYmFzZWQgb24gY29ubmVjdGlvbiBwb2ludCB0eXBlXG4gICAgbGV0IHBhdGggPSAnJztcblxuICAgIC8vIEZvciBzaWRlIHBvaW50cyAobGVmdC9yaWdodCksIHN0YXJ0IHdpdGggaG9yaXpvbnRhbCBsaW5lXG4gICAgaWYgKHBvaW50VHlwZSA9PT0gJ2xlZnQnIHx8IHBvaW50VHlwZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgLy8gQ2FsY3VsYXRlIGhvcml6b250YWwgZGlzdGFuY2VcbiAgICAgIGNvbnN0IGhvcml6b250YWxEaXN0ID0gZW5kWCAtIHN0YXJ0WDtcblxuICAgICAgLy8gSWYgdGhlIGVuZCBwb2ludCBpcyB2ZXJ5IGNsb3NlIGhvcml6b250YWxseSwgdXNlIGEgc2ltcGxlIDMtc2VnbWVudCBwYXRoXG4gICAgICBpZiAoTWF0aC5hYnMoaG9yaXpvbnRhbERpc3QpIDwgMzApIHtcbiAgICAgICAgY29uc3QgbWlkWSA9IChzdGFydFkgKyBlbmRZKSAvIDI7XG4gICAgICAgIHBhdGggPSBgTSAke3N0YXJ0WH0gJHtzdGFydFl9IEggJHtlbmRYfSBWICR7bWlkWX0gViAke2VuZFl9YDtcbiAgICAgIH1cbiAgICAgIC8vIE90aGVyd2lzZSwgY3JlYXRlIGEgcGF0aCB3aXRoIGhvcml6b250YWwgc2VnbWVudCBmaXJzdCwgdGhlbiB2ZXJ0aWNhbCwgdGhlbiBob3Jpem9udGFsXG4gICAgICBlbHNlIHtcbiAgICAgICAgcGF0aCA9IGBNICR7c3RhcnRYfSAke3N0YXJ0WX0gSCAke3N0YXJ0WCArIGhvcml6b250YWxEaXN0IC8gMlxuICAgICAgICAgIH0gViAke2VuZFl9IEggJHtlbmRYfWA7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEZvciB0b3AvYm90dG9tIHBvaW50cywgc3RhcnQgd2l0aCB2ZXJ0aWNhbCBsaW5lXG4gICAgZWxzZSBpZiAocG9pbnRUeXBlID09PSAndG9wJyB8fCBwb2ludFR5cGUgPT09ICdib3R0b20nKSB7XG4gICAgICAvLyBDYWxjdWxhdGUgdmVydGljYWwgZGlzdGFuY2VcbiAgICAgIGNvbnN0IHZlcnRpY2FsRGlzdCA9IGVuZFkgLSBzdGFydFk7XG5cbiAgICAgIC8vIElmIHRoZSBlbmQgcG9pbnQgaXMgdmVyeSBjbG9zZSB2ZXJ0aWNhbGx5LCB1c2UgYSBzaW1wbGUgMy1zZWdtZW50IHBhdGhcbiAgICAgIGlmIChNYXRoLmFicyh2ZXJ0aWNhbERpc3QpIDwgMzApIHtcbiAgICAgICAgY29uc3QgbWlkWCA9IChzdGFydFggKyBlbmRYKSAvIDI7XG4gICAgICAgIHBhdGggPSBgTSAke3N0YXJ0WH0gJHtzdGFydFl9IFYgJHtlbmRZfSBIICR7bWlkWH0gSCAke2VuZFh9YDtcbiAgICAgIH1cbiAgICAgIC8vIE90aGVyd2lzZSwgY3JlYXRlIGEgcGF0aCB3aXRoIHZlcnRpY2FsIHNlZ21lbnQgZmlyc3QsIHRoZW4gaG9yaXpvbnRhbCwgdGhlbiB2ZXJ0aWNhbFxuICAgICAgZWxzZSB7XG4gICAgICAgIHBhdGggPSBgTSAke3N0YXJ0WH0gJHtzdGFydFl9IFYgJHtzdGFydFkgKyB2ZXJ0aWNhbERpc3QgLyAyXG4gICAgICAgICAgfSBIICR7ZW5kWH0gViAke2VuZFl9YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIHNlbGVjdEZvcm1Gb3JTdGFnZShmb3JtOiBGb3JtIHwgbnVsbCwgbm9kZTogTm9kZSkge1xuICAgIC8vIElmIGZvcm0gaXMgbnVsbCwgd2UncmUgY2xlYXJpbmcgdGhlIHNlbGVjdGlvblxuICAgIGlmIChub2RlKSB7XG4gICAgICBpZiAoIW5vZGUuc3RhZ2VEYXRhKSB7XG4gICAgICAgIG5vZGUuc3RhZ2VEYXRhID0ge307XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3JtKSB7XG4gICAgICAgIG5vZGUuc3RhZ2VEYXRhLmZvcm1JZCA9IGZvcm0uQ29kZTtcbiAgICAgICAgbm9kZS5zdGFnZURhdGEuZm9ybU5hbWUgPSBmb3JtLk5hbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciBmb3JtIHNlbGVjdGlvblxuICAgICAgICBkZWxldGUgbm9kZS5zdGFnZURhdGEuZm9ybUlkO1xuICAgICAgICBkZWxldGUgbm9kZS5zdGFnZURhdGEuZm9ybU5hbWU7XG4gICAgICB9XG5cbiAgICAgIC8vIEVtaXQgYW4gZXZlbnQgdG8gdXBkYXRlIHRoZSBzdGFnZSBkYXRhXG4gICAgICB0aGlzLm9uU3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCh7XG4gICAgICAgIG5vZGVJZDogbm9kZS5pZCxcbiAgICAgICAgc3RhZ2VEYXRhOiBub2RlLnN0YWdlRGF0YSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9uU3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZChldmVudDoge1xuICAgIG5vZGVJZDogc3RyaW5nO1xuICAgIHN0YWdlRGF0YTogUGFydGlhbDxXb3JrZmxvd1N0YWdlPjtcbiAgfSk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIG5vZGUgaW4gdGhlIHN3aW1sYW5lc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zdGF0ZS5zd2ltbGFuZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHN3aW1sYW5lID0gdGhpcy5zdGF0ZS5zd2ltbGFuZXNbaV07XG4gICAgICBjb25zdCBub2RlSW5kZXggPSBzd2ltbGFuZS5ub2Rlcz8uZmluZEluZGV4KChuKSA9PiBuLmlkID09PSBldmVudC5ub2RlSWQpO1xuXG4gICAgICBpZiAobm9kZUluZGV4ICE9PSB1bmRlZmluZWQgJiYgbm9kZUluZGV4ID49IDApIHtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBzdGFnZSBkYXRhXG4gICAgICAgIGlmIChzd2ltbGFuZS5ub2Rlcykge1xuICAgICAgICAgIHN3aW1sYW5lLm5vZGVzW25vZGVJbmRleF0uc3RhZ2VEYXRhID0ge1xuICAgICAgICAgICAgLi4uc3dpbWxhbmUubm9kZXNbbm9kZUluZGV4XS5zdGFnZURhdGEsXG4gICAgICAgICAgICAuLi5ldmVudC5zdGFnZURhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICdVcGRhdGVkIHN0YWdlIGRhdGEgaW4gc3dpbWxhbmU6JyxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICAnbm9kZTonLFxuICAgICAgICAgICAgbm9kZUluZGV4LFxuICAgICAgICAgICAgJ2RhdGE6JyxcbiAgICAgICAgICAgIHN3aW1sYW5lLm5vZGVzW25vZGVJbmRleF0uc3RhZ2VEYXRhXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkNvbm5lY3Rpb25DcmVhdGVkKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAvLyBBZnRlciBhIGNvbm5lY3Rpb24gaXMgY3JlYXRlZCwgcmVmcmVzaCB0aGUgc291cmNlIG5vZGUgdG8gdXBkYXRlIGl0cyBzdGF0ZVxuICAgIGNvbnN0IHNvdXJjZU5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoY29ubmVjdGlvbi5zb3VyY2VOb2RlSWQpO1xuICAgIGlmIChzb3VyY2VOb2RlSW5mbyAmJiBzb3VyY2VOb2RlSW5mby5ub2RlLnR5cGUgPT09ICdzdGFnZScpIHtcbiAgICAgIC8vIFJlZnJlc2ggbm9kZSBzdGF0ZVxuICAgICAgdGhpcy51cGRhdGVOb2RlQ29ubmVjdGlvbnMoc291cmNlTm9kZUluZm8ubm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZCB0byB1cGRhdGUgbm9kZSdzIGNvbm5lY3Rpb24gc3RhdHVzXG4gIHVwZGF0ZU5vZGVDb25uZWN0aW9ucyhub2RlOiBXRk5vZGUpOiB2b2lkIHtcbiAgICAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIG91dGdvaW5nIGNvbm5lY3Rpb25zIHRoYXQgY29ubmVjdCB0byBzdGFnZXNcbiAgICBjb25zdCBvdXRnb2luZ0Nvbm5lY3Rpb25zID0gdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5maWx0ZXIoXG4gICAgICAoY29ubikgPT4gY29ubi5zb3VyY2VOb2RlSWQgPT09IG5vZGUuaWRcbiAgICApO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHRhcmdldCBub2RlcyBhcmUgc3RhZ2VzXG4gICAgY29uc3QgY29ubmVjdGVkU3RhZ2VOb2RlcyA9IG91dGdvaW5nQ29ubmVjdGlvbnNcbiAgICAgIC5tYXAoKGNvbm4pID0+IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKGNvbm4udGFyZ2V0Tm9kZUlkKSlcbiAgICAgIC5maWx0ZXIoKG5vZGVJbmZvKSA9PiBub2RlSW5mbyAmJiBub2RlSW5mby5ub2RlLnR5cGUgPT09ICdzdGFnZScpO1xuXG4gICAgbm9kZS5oYXNNdWx0aXBsZUNvbm5lY3RlZFN0YWdlcyA9IGNvbm5lY3RlZFN0YWdlTm9kZXMubGVuZ3RoID4gMTtcbiAgICBub2RlLmhhc1BhcmFsbGVsU3RhZ2VzID0gY29ubmVjdGVkU3RhZ2VOb2Rlcy5ldmVyeShcbiAgICAgIChuZCkgPT4gbmQ/Lm5vZGUuc3RhZ2VEYXRhPy5Jc1BhcmFsbGVsXG4gICAgKTtcbiAgfVxuXG4gIG9uRWRpdFN3aW1sYW5lKFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50LFxuICAgIHN3aW1sYW5lOiBTd2ltbGFuZUl0ZW0sXG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyXG4gICk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyAvLyBQcmV2ZW50IHRoZSBjYW52YXMgY2xpY2sgZXZlbnQgZnJvbSBmaXJpbmdcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnNvbGUubG9nKCdFZGl0IHN3aW1sYW5lIGJ1dHRvbiBjbGlja2VkIGZvciBzd2ltbGFuZTonLCBzd2ltbGFuZUluZGV4KTtcblxuICAgIC8vIEVtaXQgYSBzcGVjaWFsIGV2ZW50IGZvciBlZGl0aW5nIGEgc3dpbWxhbmVcbiAgICB0aGlzLmNsaWNrZWRQb3NpdGlvbi5lbWl0KHtcbiAgICAgIHg6IC0xLCAvLyBTcGVjaWFsIHZhbHVlIHRvIGluZGljYXRlIGVkaXQgbW9kZVxuICAgICAgeTogc3dpbWxhbmVJbmRleCxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHNob3dTdGFydE5vZGVGb3JtUG9wdXAoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgLy8gICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAvLyAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gIC8vICAgLy8gSW1wbGVtZW50YXRpb24gd2lsbCBiZSBzaW1pbGFyIHRvIHRoZSBzdGFnZSBmb3JtIHBvcHVwXG4gIC8vICAgLy8gV2UnbGwgbmVlZCB0byBhZGQgVUkgZWxlbWVudHMgZm9yIHRoaXNcbiAgLy8gICBjb25zb2xlLmxvZygnU3RhcnQgbm9kZSBmb3JtIHBvcHVwIHJlcXVlc3RlZCcpO1xuXG4gIC8vICAgLy8gRm9yIG5vdywgdGhpcyBpcyBhIHBsYWNlaG9sZGVyXG4gIC8vICAgLy8gVGhlIGFjdHVhbCBpbXBsZW1lbnRhdGlvbiB3b3VsZCBsb2FkIGZvcm1zIGFuZCBhZGQgdGhlbSB0byB0aGUgd29ya2Zsb3dcbiAgLy8gfVxuXG4gIHRvZ2dsZVN0YXJ0Tm9kZUZvcm1Qb3B1cChcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBub2RlWDogbnVtYmVyLFxuICAgIG5vZGVZOiBudW1iZXIsXG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyLFxuICAgIG5vZGU/OiBOb2RlXG4gICk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAvLyBTZXQgcG9wdXAgcG9zaXRpb24gLSBjb252ZXJ0IGNhbnZhcyBjb29yZGluYXRlcyB0byB2aWV3cG9ydCBjb29yZGluYXRlc1xuICAgIGNvbnN0IHN3aW1sYW5lT2Zmc2V0ID0gc3dpbWxhbmVJbmRleCAqIDI2MztcbiAgICBjb25zdCBjYW52YXNYID0gbm9kZVggLSAoIW5vZGUgPyAzMCA6IDApO1xuICAgIGNvbnN0IGNhbnZhc1kgPSBub2RlWSArIHN3aW1sYW5lT2Zmc2V0O1xuXG4gICAgY29uc3Qgdmlld3BvcnRQb3MgPSB0aGlzLmdldFZpZXdwb3J0UG9zaXRpb24oY2FudmFzWCwgY2FudmFzWSk7XG4gICAgdGhpcy5zdGFydE5vZGVGb3JtUG9wdXBYID0gdmlld3BvcnRQb3MueDtcbiAgICB0aGlzLnN0YXJ0Tm9kZUZvcm1Qb3B1cFkgPSB2aWV3cG9ydFBvcy55O1xuXG4gICAgLy8gSWYgd2UncmUgb3BlbmluZyB0aGUgcG9wdXAsIGxvYWQgZm9ybXNcbiAgICBpZiAoIXRoaXMuc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cCkge1xuICAgICAgdGhpcy5pc0xvYWRpbmdTdGFydE5vZGVGb3JtcyA9IHRydWU7XG4gICAgICB0aGlzLmRhdGFTZXJ2aWNlXG4gICAgICAgIC5nZXRGb3JtcygpXG4gICAgICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgIHRoaXMuc3RhcnROb2RlRm9ybXNMaXN0ID0gcmVzcG9uc2UuUmVzdWx0O1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nU3RhcnROb2RlRm9ybXMgPSBmYWxzZTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxvYWRpbmcgZm9ybXM6JywgZXJyb3IpO1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nU3RhcnROb2RlRm9ybXMgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRoaXMuYWN0aXZlTm9kZUZvckZvcm1TZWxlY3Rpb24gPSBub2RlO1xuICAgICAgY29uc29sZS5sb2coJ0FjdGl2ZSBub2RlIGZvciBmb3JtIHNlbGVjdGlvbjonLCBub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5zaG93U3RhcnROb2RlRm9ybVBvcHVwID0gIXRoaXMuc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cDtcbiAgfVxuXG4gIHNlbGVjdFN0YXJ0Tm9kZUZvcm0oZm9ybTogRm9ybSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbikge1xuICAgICAgdGhpcy5zZWxlY3RGb3JtRm9yU3RhZ2UoZm9ybSwgdGhpcy5hY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChmb3JtKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc2V0V29ya2Zsb3dGb3JtKGZvcm0uQ29kZSwgZm9ybS5OYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc2V0V29ya2Zsb3dGb3JtKG51bGwsIG51bGwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENsb3NlIHRoZSBwb3B1cFxuICAgIHRoaXMuc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cCA9IGZhbHNlO1xuICB9XG5cbiAgc2hvd1N1YmZsb3dTZWxlY3Rpb25Qb3B1cCh4OiBudW1iZXIsIHk6IG51bWJlciwgc3dpbWxhbmVJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gQ29udmVydCBjYW52YXMgY29vcmRpbmF0ZXMgdG8gdmlld3BvcnQgY29vcmRpbmF0ZXMgZm9yIHBvcHVwIHBvc2l0aW9uaW5nXG4gICAgY29uc3Qgdmlld3BvcnRQb3MgPSB0aGlzLmdldFZpZXdwb3J0UG9zaXRpb24oeCwgeSk7XG4gICAgdGhpcy5zdWJmbG93UG9wdXBYID0gdmlld3BvcnRQb3MueDtcbiAgICB0aGlzLnN1YmZsb3dQb3B1cFkgPSB2aWV3cG9ydFBvcy55O1xuICAgIHRoaXMucGVuZGluZ1N1YmZsb3dQb3NpdGlvbiA9IHsgc3dpbWxhbmVJbmRleCwgeCwgeSB9O1xuXG4gICAgLy8gU3RvcmUgY29ubmVjdGlvbiBkYXRhIGlmIHdlJ3JlIGNyZWF0aW5nIGZyb20gYSBjb25uZWN0aW9uXG4gICAgaWYgKHRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSkge1xuICAgICAgLy8gU3RvcmUgdGhlIHNvdXJjZSBjb25uZWN0aW9uIGRhdGFcbiAgICAgIHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VQb2ludCA9XG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdDb25uZWN0aW9uRGF0YS5zb3VyY2VQb2ludCA/PyBudWxsO1xuICAgICAgdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVN3aW1sYW5lSW5kZXggPVxuICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuc291cmNlU3dpbWxhbmVJbmRleCA/PyBudWxsO1xuICAgICAgY29uc29sZS5sb2coJ1N0b3JlZCBjb25uZWN0aW9uIGRhdGEgZm9yIHN1YmZsb3c6Jywge1xuICAgICAgICBzb3VyY2VQb2ludDogdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVBvaW50LFxuICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4OiB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlU3dpbWxhbmVJbmRleCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIExvYWQgd29ya2Zsb3dzXG4gICAgdGhpcy5pc0xvYWRpbmdXb3JrZmxvd3MgPSB0cnVlO1xuICAgIHRoaXMuZGF0YVNlcnZpY2VcbiAgICAgIC5nZXRXb3JrZmxvd3MoKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHRoaXMud29ya2Zsb3dzTGlzdCA9IHJlc3BvbnNlLlJlc3VsdDtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdXb3JrZmxvd3MgPSBmYWxzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxvYWRpbmcgd29ya2Zsb3dzOicsIGVycm9yKTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdXb3JrZmxvd3MgPSBmYWxzZTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5zaG93U3ViZmxvd1BvcHVwID0gdHJ1ZTtcbiAgfVxuXG4gIHNlbGVjdFN1YmZsb3dXb3JrZmxvdyh3b3JrZmxvdzogV29ya2Zsb3cpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnU2VsZWN0aW5nIHdvcmtmbG93IGZvciBzdWJmbG93OicsIHdvcmtmbG93Lk5hbWUpO1xuICAgIGNvbnNvbGUubG9nKCdQZW5kaW5nIGNvbm5lY3Rpb24gZGF0YTonLCB7XG4gICAgICBzb3VyY2VQb2ludDogdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVBvaW50LFxuICAgICAgc291cmNlU3dpbWxhbmVJbmRleDogdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVN3aW1sYW5lSW5kZXgsXG4gICAgICBwb3NpdGlvbjogdGhpcy5wZW5kaW5nU3ViZmxvd1Bvc2l0aW9uLFxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMucGVuZGluZ1N1YmZsb3dQb3NpdGlvbikge1xuICAgICAgY29uc3QgeyBzd2ltbGFuZUluZGV4LCB4LCB5IH0gPSB0aGlzLnBlbmRpbmdTdWJmbG93UG9zaXRpb247XG5cbiAgICAgIC8vIENyZWF0ZSB0aGUgc3ViZmxvdyBub2RlIHdpdGggdGhlIHNlbGVjdGVkIHdvcmtmbG93IGRhdGFcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLnN0YXRlLmFkZE5vZGUoXG4gICAgICAgIHN3aW1sYW5lSW5kZXgsXG4gICAgICAgICdzdWJmbG93JyxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgeyBOYW1lOiB3b3JrZmxvdy5OYW1lIH0sIC8vIEluaXRpYWxpemUgc3RhZ2UgbmFtZSBmcm9tIHdvcmtmbG93XG4gICAgICAgIHsgaWQ6IHdvcmtmbG93LkNvZGUsIG5hbWU6IHdvcmtmbG93Lk5hbWUgfVxuICAgICAgKTtcblxuICAgICAgY29uc29sZS5sb2coJ0NyZWF0ZWQgc3ViZmxvdyBub2RlOicsIG5vZGUpO1xuXG4gICAgICAvLyBJZiB0aGlzIHdhcyBjcmVhdGVkIGZyb20gYSBjb25uZWN0aW9uLCBjcmVhdGUgdGhlIGNvbm5lY3Rpb25cbiAgICAgIGlmIChub2RlICYmIHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VQb2ludCkge1xuICAgICAgICBjb25zb2xlLmxvZygnQ3JlYXRpbmcgY29ubmVjdGlvbiB0byBuZXcgc3ViZmxvdyBub2RlJyk7XG5cbiAgICAgICAgLy8gRmluZCBhIHN1aXRhYmxlIGNvbm5lY3Rpb24gcG9pbnQgb24gdGhlIG5ldyBub2RlXG4gICAgICAgIGlmIChub2RlLmNvbm5lY3Rpb25Qb2ludHMgJiYgbm9kZS5jb25uZWN0aW9uUG9pbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBzb3VyY2VQb2ludCA9IHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VQb2ludDtcblxuICAgICAgICAgIC8vIEZpbmQgb3Bwb3NpbmcgdHlwZSBjb25uZWN0aW9uIHBvaW50XG4gICAgICAgICAgY29uc3Qgb3Bwb3NpbmdUeXBlID0ge1xuICAgICAgICAgICAgcmlnaHQ6ICdsZWZ0JyxcbiAgICAgICAgICAgIGxlZnQ6ICdyaWdodCcsXG4gICAgICAgICAgICB0b3A6ICdib3R0b20nLFxuICAgICAgICAgICAgYm90dG9tOiAndG9wJyxcbiAgICAgICAgICB9W3NvdXJjZVBvaW50LnR5cGVdIGFzICd0b3AnIHwgJ3JpZ2h0JyB8ICdib3R0b20nIHwgJ2xlZnQnO1xuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0UG9pbnQgPSBub2RlLmNvbm5lY3Rpb25Qb2ludHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBwLnR5cGUgPT09IG9wcG9zaW5nVHlwZVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAodGFyZ2V0UG9pbnQpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0ge1xuICAgICAgICAgICAgICBpZDogYGNvbm4tJHtEYXRlLm5vdygpfS0ke01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDApfWAsXG4gICAgICAgICAgICAgIHNvdXJjZU5vZGVJZDogc291cmNlUG9pbnQubm9kZUlkLFxuICAgICAgICAgICAgICB0YXJnZXROb2RlSWQ6IG5vZGUuaWQsXG4gICAgICAgICAgICAgIHNvdXJjZVBvaW50SWQ6IHNvdXJjZVBvaW50LmlkLFxuICAgICAgICAgICAgICB0YXJnZXRQb2ludElkOiB0YXJnZXRQb2ludC5pZCxcbiAgICAgICAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleDogdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVN3aW1sYW5lSW5kZXghLFxuICAgICAgICAgICAgICB0YXJnZXRTd2ltbGFuZUluZGV4OiBzd2ltbGFuZUluZGV4LFxuICAgICAgICAgICAgICBsYWJlbDogJycsXG4gICAgICAgICAgICAgIGFjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIEFkZCBjb25uZWN0aW9uIGRpcmVjdGx5IHRvIHRoZSBzdGF0ZSdzIGNvbm5lY3Rpb25zIGFycmF5XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnQWRkZWQgY29ubmVjdGlvbiB0byBzdGF0ZTonLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW9ucyBhZnRlciBhZGRpbmc6JywgdGhpcy5zdGF0ZS5jb25uZWN0aW9ucyk7XG4gICAgICAgICAgICB0aGlzLm9uQ29ubmVjdGlvbkNyZWF0ZWQoY29ubmVjdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUuZW5kQ29ubmVjdGlvbkRyYWcoKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVzZXQgc2VsZWN0aW9uIHRvb2wgaW4gcGFyZW50IGNvbXBvbmVudFxuICAgICAgdGhpcy5zdWJmbG93U2VsZWN0ZWQuZW1pdCgpO1xuICAgIH1cblxuICAgIC8vIENsZWFuIHVwXG4gICAgdGhpcy5zaG93U3ViZmxvd1BvcHVwID0gZmFsc2U7XG4gICAgdGhpcy5wZW5kaW5nU3ViZmxvd1Bvc2l0aW9uID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlUG9pbnQgPSBudWxsO1xuICAgIHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VTd2ltbGFuZUluZGV4ID0gbnVsbDtcbiAgfVxuXG4gIHNob3dEZWNpc2lvbkNvbmRpdGlvbnNQb3B1cChcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBub2RlOiBXRk5vZGUsXG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyXG4gICk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAvLyBHZXQgdGhlIHBvc2l0aW9uIGZvciB0aGUgcG9wdXBcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuZ2V0TW91c2VQb3NpdGlvbihldmVudCk7XG5cbiAgICAvLyBDb252ZXJ0IGNhbnZhcyBjb29yZGluYXRlcyB0byB2aWV3cG9ydCBjb29yZGluYXRlcyBmb3IgcG9wdXAgcG9zaXRpb25pbmdcbiAgICBjb25zdCB2aWV3cG9ydFBvcyA9IHRoaXMuZ2V0Vmlld3BvcnRQb3NpdGlvbihwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcblxuICAgIC8vIEZpbmQgYWxsIGNvbm5lY3Rpb25zIGZyb20gdGhpcyBkZWNpc2lvbiBub2RlXG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSB0aGlzLnN0YXRlLmNvbm5lY3Rpb25zLmZpbHRlcihcbiAgICAgIChjb25uKSA9PiBjb25uLnNvdXJjZU5vZGVJZCA9PT0gbm9kZS5pZFxuICAgICk7XG5cbiAgICBpZiAoY29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBObyBjb25uZWN0aW9ucyB0byBzaG93XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2hvdyB0aGUgZGVjaXNpb24gY29uZGl0aW9ucyBwb3B1cFxuICAgIHRoaXMuYWN0aXZlRGVjaXNpb25Ob2RlSWQgPSBub2RlLmlkO1xuICAgIHRoaXMuZGVjaXNpb25Db25kaXRpb25Qb3B1cFggPSB2aWV3cG9ydFBvcy54O1xuICAgIHRoaXMuZGVjaXNpb25Db25kaXRpb25Qb3B1cFkgPSB2aWV3cG9ydFBvcy55O1xuXG4gICAgLy8gU2V0IHRoZSBjb3JyZWN0IHBvcHVwIHZpc2liaWxpdHkgZmxhZyAtIHRoaXMgaXMgbGlrZWx5IHRoZSBpc3N1ZVxuICAgIHRoaXMuc2hvd0RlY2lzaW9uQ29uZGl0aW9uRGlhbG9nID0gdHJ1ZTtcblxuICAgIC8vIGNvbnNvbGUubG9nKCdTaG93aW5nIGRlY2lzaW9uIHBvcHVwOicsIHtcbiAgICAvLyAgIHk6IGdsb2JhbFksXG4gICAgLy8gICBub2RlSWQ6IG5vZGUuaWQsXG4gICAgLy8gICBpc1Zpc2libGU6IHRoaXMuc2hvd0RlY2lzaW9uQ29uZGl0aW9uRGlhbG9nLFxuICAgIC8vIH0pO1xuICB9XG5cbiAgZW5zdXJlU3dpbWxhbmVJblZpZXcoc3dpbWxhbmVJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gRW5zdXJlIHdlIGhhdmUgZW5vdWdoIHN3aW1sYW5lcyB2aXNpYmxlXG4gICAgY29uc3QgcmVxdWlyZWRIZWlnaHQgPSAoc3dpbWxhbmVJbmRleCArIDEpICogdGhpcy5zd2ltbGFuZUhlaWdodDtcbiAgICBpZiAodGhpcy5jYW52YXNIZWlnaHQgPCByZXF1aXJlZEhlaWdodCkge1xuICAgICAgdGhpcy5jYW52YXNIZWlnaHQgPSByZXF1aXJlZEhlaWdodDtcbiAgICB9XG4gIH1cblxuICBnZXRMYWJlbFBvc2l0aW9uKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXRoRGF0YSA9IHRoaXMuc3RhdGUuZ2V0Q29ubmVjdGlvbkRhdGEoY29ubmVjdGlvbik7XG4gICAgICBpZiAoIXBhdGhEYXRhKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ05vIHBhdGggZGF0YSBmb3IgY29ubmVjdGlvbjonLCBjb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHsgeDogMCwgeTogMCB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHN0YXJ0WCwgc3RhcnRZLCBlbmRYLCBlbmRZIH0gPSBwYXRoRGF0YTtcblxuICAgICAgY29uc3Qgc291cmNlTm9kZUluZm8gPSB0aGlzLnN0YXRlLmZpbmROb2RlQnlJZChjb25uZWN0aW9uLnNvdXJjZU5vZGVJZCk7XG4gICAgICBpZiAoIXNvdXJjZU5vZGVJbmZvKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1NvdXJjZSBub2RlIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbjonLCBjb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHsgeDogMCwgeTogMCB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3VyY2VOb2RlID0gc291cmNlTm9kZUluZm8ubm9kZTtcbiAgICAgIGNvbnN0IHNvdXJjZVBvaW50ID0gc291cmNlTm9kZS5jb25uZWN0aW9uUG9pbnRzPy5maW5kKFxuICAgICAgICAocCkgPT4gcC5pZCA9PT0gY29ubmVjdGlvbi5zb3VyY2VQb2ludElkXG4gICAgICApO1xuXG4gICAgICBpZiAoIXNvdXJjZVBvaW50KSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1NvdXJjZSBwb2ludCBub3QgZm91bmQgZm9yIGNvbm5lY3Rpb246JywgY29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiB7IHg6IDAsIHk6IDAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2FsY3VsYXRlIG1pZHBvaW50IGJhc2VkIG9uIHRoZSBjb25uZWN0aW9uIHBvaW50IHR5cGVcbiAgICAgIGlmIChzb3VyY2VQb2ludC50eXBlID09PSAnbGVmdCcgfHwgc291cmNlUG9pbnQudHlwZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICBjb25zdCBob3Jpem9udGFsRGlzdCA9IGVuZFggLSBzdGFydFg7XG5cbiAgICAgICAgaWYgKE1hdGguYWJzKGhvcml6b250YWxEaXN0KSA8IDMwKSB7XG4gICAgICAgICAgLy8gRm9yIHNob3J0IGhvcml6b250YWwgY29ubmVjdGlvbnNcbiAgICAgICAgICBjb25zdCBtaWRZID0gKHN0YXJ0WSArIGVuZFkpIC8gMjtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogc3RhcnRYICsgKGVuZFggLSBzdGFydFgpIC8gMixcbiAgICAgICAgICAgIHk6IG1pZFksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGb3IgcmVndWxhciBjb25uZWN0aW9ucyBzdGFydGluZyBob3Jpem9udGFsbHlcbiAgICAgICAgICBjb25zdCBtaWRYID0gc3RhcnRYICsgaG9yaXpvbnRhbERpc3QgLyAyO1xuICAgICAgICAgIGNvbnN0IG1pZFkgPSBlbmRZO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBtaWRYLFxuICAgICAgICAgICAgeTogKHN0YXJ0WSArIGVuZFkpIC8gMixcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyAndG9wJyBvciAnYm90dG9tJ1xuICAgICAgICBjb25zdCB2ZXJ0aWNhbERpc3QgPSBlbmRZIC0gc3RhcnRZO1xuXG4gICAgICAgIGlmIChNYXRoLmFicyh2ZXJ0aWNhbERpc3QpIDwgMzApIHtcbiAgICAgICAgICAvLyBGb3Igc2hvcnQgdmVydGljYWwgY29ubmVjdGlvbnNcbiAgICAgICAgICBjb25zdCBtaWRYID0gKHN0YXJ0WCArIGVuZFgpIC8gMjtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogbWlkWCxcbiAgICAgICAgICAgIHk6IHN0YXJ0WSArIChlbmRZIC0gc3RhcnRZKSAvIDIsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGb3IgcmVndWxhciBjb25uZWN0aW9ucyBzdGFydGluZyB2ZXJ0aWNhbGx5XG4gICAgICAgICAgY29uc3QgbWlkWCA9IGVuZFg7XG4gICAgICAgICAgY29uc3QgbWlkWSA9IHN0YXJ0WSArIHZlcnRpY2FsRGlzdCAvIDI7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IChzdGFydFggKyBlbmRYKSAvIDIsXG4gICAgICAgICAgICB5OiBtaWRZLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgJ0Vycm9yIGNhbGN1bGF0aW5nIGxhYmVsIHBvc2l0aW9uIGZvciBjb25uZWN0aW9uOicsXG4gICAgICAgIGNvbm5lY3Rpb24sXG4gICAgICAgIGVycm9yXG4gICAgICApO1xuICAgICAgcmV0dXJuIHsgeDogMCwgeTogMCB9O1xuICAgIH1cbiAgfVxuXG4gIHNhdmVDb25uZWN0aW9uTGFiZWwoY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgbGFiZWw6IHN0cmluZykge1xuICAgIC8vIFVwZGF0ZSB0aGUgY29ubmVjdGlvbiBsYWJlbCBpbiB0aGUgc3RhdGVcbiAgICB0aGlzLnN0YXRlLmNvbm5lY3Rpb25zID0gdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5tYXAoKGNvbm4pID0+IHtcbiAgICAgIGlmIChjb25uLmlkID09PSBjb25uZWN0aW9uLmlkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uY29ubixcbiAgICAgICAgICBsYWJlbDogbGFiZWwsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gY29ubjtcbiAgICB9KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNhbnZhcy1jb250YWluZXJcIj5cbiAgPHN2ZyAjY2FudmFzIFthdHRyLndpZHRoXT1cImNhbnZhc1dpZHRoXCIgW2F0dHIuaGVpZ2h0XT1cImNhbnZhc0hlaWdodFwiIGNsYXNzPVwiZGVzaWduZXItY2FudmFzXCJcbiAgICAoY2xpY2spPVwib25DYW52YXNDbGljaygkZXZlbnQpXCI+XG4gICAgPGRlZnM+XG4gICAgICA8IS0tIEdyaWQgcGF0dGVybiBkZWZpbml0aW9uIC0tPlxuXG4gICAgICA8cGF0dGVybiBpZD1cImdyaWRcIiBbYXR0ci53aWR0aF09XCJncmlkU2l6ZVwiIFthdHRyLmhlaWdodF09XCJncmlkU2l6ZVwiIHBhdHRlcm5Vbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+XG4gICAgICAgIDxwYXRoIGQ9XCJNIDIwIDAgTCAwIDAgMCAyMFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiI2UyZThmMFwiIHN0cm9rZS13aWR0aD1cIjAuNVwiIC8+XG4gICAgICA8L3BhdHRlcm4+XG5cbiAgICAgIDwhLS0gQXJyb3cgaGVhZCBtYXJrZXIgZGVmaW5pdGlvbiAtLT5cbiAgICAgIDxtYXJrZXIgaWQ9XCJhcnJvd2hlYWRcIiBtYXJrZXJXaWR0aD1cIjEwXCIgbWFya2VySGVpZ2h0PVwiN1wiIHJlZlg9XCI5XCIgcmVmWT1cIjMuNVwiIG9yaWVudD1cImF1dG9cIj5cbiAgICAgICAgPHBvbHlnb24gcG9pbnRzPVwiMCAwLCAxMCAzLjUsIDAgN1wiIGZpbGw9XCIjRDM2Q0ZGXCIgLz5cbiAgICAgIDwvbWFya2VyPlxuXG4gICAgICA8IS0tIENvbm5lY3Rpb24gcG9pbnQgc3R5bGVzIC0tPlxuICAgICAgPGNpcmNsZSBpZD1cImNvbm5lY3Rpb24tcG9pbnQtdGVtcGxhdGVcIiByPVwiNVwiIGZpbGw9XCIjRDM2Q0ZGXCIgc3Ryb2tlPVwiI0ZGRkZGRlwiIHN0cm9rZS13aWR0aD1cIjFcIiAvPlxuXG4gICAgICA8IS0tIERhc2hlZCBsaW5lIHN0eWxlIGZvciBjb25uZWN0aW9uIHByZXZpZXcgLS0+XG4gICAgICA8cGF0dGVybiBpZD1cImRhc2hlZC1saW5lXCIgd2lkdGg9XCIxMFwiIGhlaWdodD1cIjEwXCIgcGF0dGVyblVuaXRzPVwidXNlclNwYWNlT25Vc2VcIj5cbiAgICAgICAgPGxpbmUgeDE9XCIwXCIgeTE9XCI1XCIgeDI9XCIxMFwiIHkyPVwiNVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWRhc2hhcnJheT1cIjUsNVwiIC8+XG4gICAgICA8L3BhdHRlcm4+XG5cbiAgICAgIEBmb3IgKHN3aW1sYW5lIG9mIHN0YXRlLnN3aW1sYW5lczsgdHJhY2sgc3dpbWxhbmUub3JkZXIpIHtcbiAgICAgIDxjbGlwUGF0aCBbYXR0ci5pZF09XCInc3dpbWxhbmUtY2xpcC0nICsgc3dpbWxhbmUub3JkZXJcIj5cbiAgICAgICAgPHJlY3QgeD1cIjBcIiB5PVwiMFwiIFthdHRyLndpZHRoXT1cImNhbnZhc1dpZHRoXCIgaGVpZ2h0PVwiMjYzXCIgLz5cbiAgICAgIDwvY2xpcFBhdGg+XG4gICAgICB9XG4gICAgPC9kZWZzPlxuXG4gICAgPCEtLSBCYWNrZ3JvdW5kIGdyaWQgLS0+XG4gICAgPHJlY3Qgd2lkdGg9XCIxMDAlXCIgaGVpZ2h0PVwiMTAwJVwiIGZpbGw9XCJ1cmwoI2dyaWQpXCIgLz5cblxuICAgIDwhLS0gRGlzcGxheSBhIG1lc3NhZ2Ugd2hlbiBubyBzd2ltbGFuZXMgZXhpc3QgLS0+XG4gICAgQGlmIChzdGF0ZS5zd2ltbGFuZXMubGVuZ3RoID09PSAwKSB7XG4gICAgPHRleHQgeD1cIjUwJVwiIHk9XCI1MCVcIiBmb250LWZhbWlseT1cInNhbnMtc2VyaWZcIiBmb250LXNpemU9XCIxNlwiIGZpbGw9XCIjOTRhM2I4XCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIj5cbiAgICAgIFNlbGVjdCB0aGUgU3dpbWxhbmUgdG9vbCBhbmQgY2xpY2sgb24gdGhlIGNhbnZhcyB0byBhZGQgYSBzd2ltbGFuZVxuICAgIDwvdGV4dD5cbiAgICB9XG5cbiAgICA8IS0tIFRoaXMgaXMgd2hlcmUgd29ya2Zsb3cgZWxlbWVudHMgd2lsbCBiZSBhZGRlZCBsYXRlciAtLT5cbiAgICBAZm9yIChzd2ltbGFuZSBvZiBzdGF0ZS5zd2ltbGFuZXM7IHRyYWNrIHN3aW1sYW5lLm9yZGVyKSB7XG4gICAgPCEtLSA8Z1xuICAgICAgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoMCwnICsgc3dpbWxhbmUub3JkZXIgKiAyNjMgKyAnKSdcIlxuICAgICAgW2F0dHIuY2xpcC1wYXRoXT1cIid1cmwoI3N3aW1sYW5lLWNsaXAtJyArIHN3aW1sYW5lLm9yZGVyICsgJyknXCJcbiAgICA+XG4gICAgICA8cmVjdFxuICAgICAgICB4PVwiMFwiXG4gICAgICAgIHk9XCIwXCJcbiAgICAgICAgW2F0dHIud2lkdGhdPVwiY2FudmFzV2lkdGhcIlxuICAgICAgICBbYXR0ci5oZWlnaHRdPVwiMjYzXCJcbiAgICAgICAgZmlsbD1cIiNmZmZmZmZcIlxuICAgICAgICBzdHJva2U9XCIjZTJlOGYwXCJcbiAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMVwiXG4gICAgICA+PC9yZWN0PlxuXG4gICAgICA8cmVjdFxuICAgICAgICB4PVwiMFwiXG4gICAgICAgIHk9XCIwXCJcbiAgICAgICAgW2F0dHIud2lkdGhdPVwiY2FudmFzV2lkdGhcIlxuICAgICAgICBoZWlnaHQ9XCI0MFwiXG4gICAgICAgIGZpbGw9XCIjZjhmYWZjXCJcbiAgICAgICAgc3Ryb2tlPVwiI2UyZThmMFwiXG4gICAgICAgIHN0cm9rZS13aWR0aD1cIjFcIlxuICAgICAgPjwvcmVjdD5cblxuICAgICAgPHRleHRcbiAgICAgICAgeD1cIjIwXCJcbiAgICAgICAgeT1cIjI1XCJcbiAgICAgICAgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCJcbiAgICAgICAgZm9udC1zaXplPVwiMTRcIlxuICAgICAgICBmaWxsPVwiIzMzMzMzM1wiXG4gICAgICAgIGZvbnQtd2VpZ2h0PVwiYm9sZFwiXG4gICAgICA+XG4gICAgICAgIHt7IHN3aW1sYW5lLmxhYmVsIH19XG4gICAgICA8L3RleHQ+XG5cbiAgICAgIDxnXG4gICAgICAgIGNsYXNzPVwiZWRpdC1zd2ltbGFuZS1idXR0b25cIlxuICAgICAgICBbYXR0ci50cmFuc2Zvcm1dPVwiJ3RyYW5zbGF0ZSgxMDAsIDIwKSdcIlxuICAgICAgICAoY2xpY2spPVwiXG4gICAgICAgICAgb25FZGl0U3dpbWxhbmUoJGV2ZW50LCBzd2ltbGFuZSwgc3dpbWxhbmUub3JkZXIpO1xuICAgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8cmVjdFxuICAgICAgICAgIHg9XCItNVwiXG4gICAgICAgICAgeT1cIi0xNVwiXG4gICAgICAgICAgd2lkdGg9XCI0MFwiXG4gICAgICAgICAgaGVpZ2h0PVwiMjBcIlxuICAgICAgICAgIGZpbGw9XCIjZjNlOGZmXCJcbiAgICAgICAgICByeD1cIjNcIlxuICAgICAgICAgIHJ5PVwiM1wiXG4gICAgICAgICAgc3Ryb2tlPVwiI2Q4YjRmZVwiXG4gICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMVwiXG4gICAgICAgID48L3JlY3Q+XG4gICAgICAgIDx0ZXh0XG4gICAgICAgICAgeD1cIjE1XCJcbiAgICAgICAgICB5PVwiMFwiXG4gICAgICAgICAgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCJcbiAgICAgICAgICBmb250LXNpemU9XCIxMlwiXG4gICAgICAgICAgZmlsbD1cIiM3ZTIyY2VcIlxuICAgICAgICAgIHRleHQtYW5jaG9yPVwibWlkZGxlXCJcbiAgICAgICAgPlxuICAgICAgICAgIEVkaXRcbiAgICAgICAgPC90ZXh0PlxuICAgICAgPC9nPlxuXG4gICAgICA8ZyBbYXR0ci50cmFuc2Zvcm1dPVwiJ3RyYW5zbGF0ZSgyMDAsIDIwKSdcIj5cbiAgICAgICAgQGZvciAodGFnIG9mIHN3aW1sYW5lLnRhZ3Muc2xpY2UoMCwgMyk7IHRyYWNrIHRhZy5OYW1lOyBsZXQgaSA9ICRpbmRleClcbiAgICAgICAge1xuICAgICAgICA8dGV4dFxuICAgICAgICAgIFthdHRyLnhdPVwiaSAqIDEwMFwiXG4gICAgICAgICAgeT1cIjVcIlxuICAgICAgICAgIGZvbnQtZmFtaWx5PVwic2Fucy1zZXJpZlwiXG4gICAgICAgICAgZm9udC1zaXplPVwiMTJcIlxuICAgICAgICAgIGZpbGw9XCIjNjY2NjY2XCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IHRhZy5OYW1lIH19XG4gICAgICAgIDwvdGV4dD5cbiAgICAgICAgfSBAaWYgKHN3aW1sYW5lLnRhZ3MubGVuZ3RoID4gMykge1xuICAgICAgICA8dGV4dFxuICAgICAgICAgIFthdHRyLnhdPVwiMyAqIDEwMCArIDEwXCJcbiAgICAgICAgICB5PVwiNVwiXG4gICAgICAgICAgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCJcbiAgICAgICAgICBmb250LXNpemU9XCIxMlwiXG4gICAgICAgICAgZmlsbD1cIiM2NjY2NjZcIlxuICAgICAgICA+XG4gICAgICAgICAgK3t7IHN3aW1sYW5lLnRhZ3MubGVuZ3RoIC0gMyB9fSBtb3JlXG4gICAgICAgIDwvdGV4dD5cbiAgICAgICAgfVxuICAgICAgPC9nPlxuICAgIDwvZz4gLS0+XG5cbiAgICA8ZyBbYXR0ci50cmFuc2Zvcm1dPVwiJ3RyYW5zbGF0ZSgwLCcgKyBzd2ltbGFuZS5vcmRlciAqIDI2MyArICcpJ1wiPlxuICAgICAgPCEtLSBTd2ltbGFuZSBjb250YWluZXIgLSByZW1vdmUgc3Ryb2tlIHRvIG1ha2UgaXQgcHVyZWx5IGJhY2tncm91bmQgLS0+XG4gICAgICA8cmVjdCB4PVwiMFwiIHk9XCIwXCIgW2F0dHIud2lkdGhdPVwiY2FudmFzV2lkdGhcIiBbYXR0ci5oZWlnaHRdPVwiMjYzXCJcbiAgICAgICAgW2F0dHIuZmlsbF09XCJzd2ltbGFuZS5vcmRlciAlIDIgPT09IDAgPyAnI0ZDRjNGRicgOiAnI0VDRkZGNSdcIiBzdHJva2U9XCJub25lXCI+PC9yZWN0PlxuXG4gICAgICA8IS0tIFZlcnRpY2FsIHN3aW1sYW5lIGxhYmVsIG9uIHRoZSBsZWZ0IC0tPlxuICAgICAgPGcgY2xhc3M9XCJzd2ltbGFuZS1sYWJlbFwiPlxuICAgICAgICA8IS0tIFB1cnBsZSBiYWNrZ3JvdW5kIGZvciB0aGUgbGFiZWwgLS0+XG4gICAgICAgIDxyZWN0IHg9XCIwLjVcIiB5PVwiMC41XCIgd2lkdGg9XCI0M1wiIGhlaWdodD1cIjIxNVwiIHJ4PVwiMTAuNVwiIGZpbGw9XCJ3aGl0ZVwiIHN0cm9rZT1cIiNEMzZDRkZcIj48L3JlY3Q+XG5cbiAgICAgICAgPCEtLSBQbHVzIGJ1dHRvbiBhdCB0aGUgdG9wIC0tPlxuICAgICAgICA8ZyAoY2xpY2spPVwiXG4gICAgICAgICAgICBvbkVkaXRTd2ltbGFuZSgkZXZlbnQsIHN3aW1sYW5lLCBzd2ltbGFuZS5vcmRlcik7XG4gICAgICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgICBcIj5cbiAgICAgICAgICA8cmVjdCB4PVwiMTIuNVwiIHk9XCIxMFwiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIGZpbGw9XCJ0cmFuc3BhcmVudFwiIHN0eWxlPVwiY3Vyc29yOiBwb2ludGVyXCI+PC9yZWN0PlxuXG4gICAgICAgICAgPHBhdGggZD1cIk0yMi41MiAxMi4xNzRWMTcuMDhIMjcuNDdWMTguNTFIMjIuNTJWMjMuMzk0SDIxLjJWMTguNTFIMTYuMjVWMTcuMDhIMjEuMlYxMi4xNzRIMjIuNTJaXCJcbiAgICAgICAgICAgIGZpbGw9XCIjMDAwMEZGXCIgY2xhc3M9XCJwbHVzLWljb25cIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlclwiPjwvcGF0aD5cbiAgICAgICAgPC9nPlxuXG4gICAgICAgIDwhLS0gU3dpbWxhbmUgbGFiZWwgLS0+XG4gICAgICAgIDx0ZXh0IHg9XCIyMlwiIHk9XCIxMDZcIiBmb250LWZhbWlseT1cInNhbnMtc2VyaWZcIiBmb250LXNpemU9XCIxNFwiIGZpbGw9XCIjMzMzMzMzXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIlxuICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtOTAsIDIyLCAxMDApXCI+XG4gICAgICAgICAge3tcbiAgICAgICAgICBzd2ltbGFuZS5sYWJlbC5sZW5ndGggPiAxMlxuICAgICAgICAgID8gc3dpbWxhbmUubGFiZWwuc3Vic3RyaW5nKDAsIDEwKSArIFwiLi4uXCJcbiAgICAgICAgICA6IHN3aW1sYW5lLmxhYmVsXG4gICAgICAgICAgfX1cbiAgICAgICAgPC90ZXh0PlxuXG4gICAgICAgIDwhLS0gVGFnIGNvdW50IGluZGljYXRvciBhdCB0aGUgYm90dG9tIC0tPlxuICAgICAgICA8cmVjdCB4PVwiMTEuNVwiIHk9XCIxODdcIiB3aWR0aD1cIjIxXCIgaGVpZ2h0PVwiMTlcIiByeD1cIjkuNVwiIGZpbGw9XCIjOUU5RTlFXCI+PC9yZWN0PlxuICAgICAgICA8dGV4dCB4PVwiMjRcIiB5PVwiMjA2XCIgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCIgZm9udC1zaXplPVwiMTJcIiBmaWxsPVwiYmxhY2tcIiB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiXG4gICAgICAgICAgdHJhbnNmb3JtPVwicm90YXRlKC05MCwgMjIsIDIwMClcIj5cbiAgICAgICAgICB7eyBzd2ltbGFuZS50YWdzLmxlbmd0aCB9fVxuICAgICAgICA8L3RleHQ+XG4gICAgICA8L2c+XG4gICAgPC9nPlxuXG4gICAgfVxuXG4gICAgPCEtLSBOb2RlcyAtLT5cbiAgICBAZm9yIChzd2ltbGFuZSBvZiBzdGF0ZS5zd2ltbGFuZXM7IHRyYWNrIHN3aW1sYW5lLm9yZGVyKSB7XG4gICAgPCEtLSBSZW5kZXIgbm9kZXMgaW4gdGhpcyBzd2ltbGFuZSAtLT5cbiAgICBAZm9yIChub2RlIG9mIHN3aW1sYW5lLm5vZGVzOyB0cmFjayBub2RlLmlkKSB7XG4gICAgPGcgY2xhc3M9XCJub2RlLWVsZW1lbnRcIiBbYXR0ci50cmFuc2Zvcm1dPVwiXG4gICAgICAgICd0cmFuc2xhdGUoJyArIG5vZGUueCArICcsJyArIChub2RlLnkgLSBzd2ltbGFuZS5vcmRlciAqIDI2MykgKyAnKSdcbiAgICAgIFwiIChtb3VzZWVudGVyKT1cInNob3dDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQsIHN3aW1sYW5lLm9yZGVyKVwiIChtb3VzZWxlYXZlKT1cImhpZGVDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQpXCI+XG4gICAgICA8IS0tIFN0YXJ0IG5vZGUgaW5kaWNhdG9yIChjaXJjbGUgYW5kIGFycm93KSBmb3IgdGhlIGZpcnN0IG5vZGUgLS0+XG4gICAgICBAaWYgKG5vZGUuaXNTdGFydE5vZGUpIHtcbiAgICAgIDwhLS0gQ2lyY2xlIC0tPlxuICAgICAgPGNpcmNsZSBjeD1cIi01MFwiIGN5PVwiNTBcIiByPVwiMzBcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCI+PC9jaXJjbGU+XG4gICAgICA8IS0tIEZvcm0gaWNvbiBmb3Igc3RhcnQgbm9kZSAtLT5cbiAgICAgIDxzdmc6ZyAoY2xpY2spPVwiXG4gICAgICAgICAgdG9nZ2xlU3RhcnROb2RlRm9ybVBvcHVwKCRldmVudCwgbm9kZS54LCBub2RlLnksIHN3aW1sYW5lLm9yZGVyKVxuICAgICAgICBcIiBjbGFzcz1cInN0YWdlLWljb25cIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQ1LCA0MilcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjsgcG9pbnRlci1ldmVudHM6IGFsbFwiPlxuICAgICAgICA8IS0tIFRyYW5zcGFyZW50IHJlY3RhbmdsZSB0byBjYXB0dXJlIGNsaWNrcyAtLT5cbiAgICAgICAgPHN2ZzpyZWN0IHg9XCItMlwiIHk9XCItMlwiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIGZpbGw9XCJ0cmFuc3BhcmVudFwiIHN0eWxlPVwiY3Vyc29yOiBwb2ludGVyXCIgLz5cbiAgICAgICAgPHN2ZzpwYXRoXG4gICAgICAgICAgZD1cIk0xNi41IDIwLjQ3NVYxNy40NzVIMTMuNVYxNi40NzVIMTYuNVYxMy40NzVIMTcuNVYxNi40NzVIMjAuNVYxNy40NzVIMTcuNVYyMC40NzVIMTYuNVpNMy41IDE3LjVWMTYuNUg0LjVWMTcuNUgzLjVaTTYuNSAxNy41VjE2LjVIMTEuNTE3QzExLjUwNTcgMTYuNjc2NyAxMS41MDQzIDE2Ljg0NSAxMS41MTMgMTcuMDA1QzExLjUyMSAxNy4xNjUgMTEuNTMxIDE3LjMzIDExLjU0MyAxNy41SDYuNVpNMy41IDEzLjVWMTIuNUg0LjVWMTMuNUgzLjVaTTYuNSAxMy41VjEyLjVIMTMuODA0QzEzLjYxMjcgMTIuNjM4NyAxMy40MzMzIDEyLjc5MTMgMTMuMjY2IDEyLjk1OEMxMy4wOTkzIDEzLjEyNDcgMTIuOTM3NyAxMy4zMDUzIDEyLjc4MSAxMy41SDYuNVpNMy41IDkuNVY4LjVINC41VjkuNUgzLjVaTTYuNSA5LjVWOC41SDE4LjVWOS41SDYuNVpNMy41IDUuNVY0LjVINC41VjUuNUgzLjVaTTYuNSA1LjVWNC41SDE4LjVWNS41SDYuNVpcIlxuICAgICAgICAgIFthdHRyLmZpbGxdPVwic3RhdGUud29ya2Zsb3dGb3JtSWQgPyAnI0QzNkNGRicgOiAnYmxhY2snXCIgdHJhbnNmb3JtPVwic2NhbGUoMC43KVwiIC8+XG4gICAgICA8L3N2ZzpnPlxuICAgICAgPCEtLSBBcnJvdyBmcm9tIGNpcmNsZSB0byBub2RlIC0tPlxuICAgICAgPHBhdGggZD1cIk0gLTIwIDUwIEwgMCA1MFwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCIgbWFya2VyLWVuZD1cInVybCgjYXJyb3doZWFkKVwiPjwvcGF0aD5cbiAgICAgIH1cblxuICAgICAgPCEtLSBFeGl0IHBvaW50IGluZGljYXRvciAoY2lyY2xlIGFuZCBhcnJvdykgLS0+XG4gICAgICBAaWYgKG5vZGUuc3RhZ2VEYXRhPy5Jc0V4aXRQb2ludCkge1xuICAgICAgPCEtLSBBcnJvdyBmcm9tIG5vZGUgdG8gY2lyY2xlIC0tPlxuICAgICAgPHBhdGggW2F0dHIuZF09XCInTSAnICsgbm9kZS53aWR0aCArICcgNTAgTCAnICsgKG5vZGUud2lkdGggKyAyMCkgKyAnIDUwJ1wiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgbWFya2VyLWVuZD1cInVybCgjYXJyb3doZWFkKVwiPjwvcGF0aD5cbiAgICAgIDwhLS0gQ2lyY2xlIC0tPlxuICAgICAgPGNpcmNsZSBbYXR0ci5jeF09XCJub2RlLndpZHRoICsgNTBcIiBjeT1cIjUwXCIgcj1cIjMwXCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjRDM2Q0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPjwvY2lyY2xlPlxuICAgICAgfVxuXG4gICAgICA8IS0tIFN0YWdlIG5vZGUgLS0+XG4gICAgICBAaWYgKG5vZGUudHlwZSA9PT0gJ3N0YWdlJykge1xuICAgICAgPCEtLSA8cmVjdFxuICAgICAgICAgICAgICAgICAgeD1cIjBcIlxuICAgICAgICAgICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgICAgICAgICAgW2F0dHIud2lkdGhdPVwibm9kZS53aWR0aFwiXG4gICAgICAgICAgICAgICAgICBbYXR0ci5oZWlnaHRdPVwibm9kZS5oZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiI0QzNkNGRlwiXG4gICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgICAgICAgICA+PC9yZWN0PiAtLT5cbiAgICAgIDxzdmc6ZyBsaWItc3RhZ2Utbm9kZSBbbm9kZV09XCJub2RlXCIgW2lzU3RhcnROb2RlXT1cIm5vZGUuaXNTdGFydE5vZGVcIlxuICAgICAgICAoc3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCk9XCJvblN0YWdlUHJvcGVydGllc1VwZGF0ZWQoJGV2ZW50KVwiIChzaG93U2hpZWxkRGlhbG9nKT1cIm9uU2hvd1NoaWVsZERpYWxvZygkZXZlbnQpXCJcbiAgICAgICAgKHNob3dFc2NhbGF0aW9uRGlhbG9nKT1cIm9uU2hvd0VzY2FsYXRpb25EaWFsb2coJGV2ZW50KVwiIChzaG93Rm9ybURpYWxvZyk9XCJcbiAgICAgICAgICB0b2dnbGVTdGFydE5vZGVGb3JtUG9wdXAoJGV2ZW50LCBub2RlLngsIG5vZGUueSwgc3dpbWxhbmUub3JkZXIsIG5vZGUpXG4gICAgICAgIFwiPjwvc3ZnOmc+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gRGVjaXNpb24gbm9kZSAtLT5cbiAgICAgIEBpZiAobm9kZS50eXBlID09PSAnZGVjaXNpb24nKSB7XG4gICAgICA8cGF0aCBbYXR0ci5kXT1cIlxuICAgICAgICAgICdNIDAgJyArXG4gICAgICAgICAgbm9kZS5oZWlnaHQgLyAyICtcbiAgICAgICAgICAnIEwgJyArXG4gICAgICAgICAgbm9kZS53aWR0aCAvIDIgK1xuICAgICAgICAgICcgMCcgK1xuICAgICAgICAgICcgTCAnICtcbiAgICAgICAgICBub2RlLndpZHRoICtcbiAgICAgICAgICAnICcgK1xuICAgICAgICAgIG5vZGUuaGVpZ2h0IC8gMiArXG4gICAgICAgICAgJyBMICcgK1xuICAgICAgICAgIG5vZGUud2lkdGggLyAyICtcbiAgICAgICAgICAnICcgK1xuICAgICAgICAgIG5vZGUuaGVpZ2h0ICtcbiAgICAgICAgICAnIFonXG4gICAgICAgIFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiI0QzNkNGRlwiIHN0cm9rZS13aWR0aD1cIjFcIj48L3BhdGg+XG5cbiAgICAgIDwhLS0gRGVjaXNpb24gbm9kZSBjb25kaXRpb24gaW5kaWNhdG9yIGljb24gLS0+XG4gICAgICA8c3ZnOmcgKGNsaWNrKT1cInNob3dEZWNpc2lvbkNvbmRpdGlvbnNQb3B1cCgkZXZlbnQsIG5vZGUsIHN3aW1sYW5lLm9yZGVyKVwiIGNsYXNzPVwiZGVjaXNpb24tY29uZGl0aW9uLWljb25cIlxuICAgICAgICBbYXR0ci50cmFuc2Zvcm1dPVwiXG4gICAgICAgICAgJ3RyYW5zbGF0ZSgnICtcbiAgICAgICAgICAobm9kZS53aWR0aCAvIDIgLSAxMCkgK1xuICAgICAgICAgICcsJyArXG4gICAgICAgICAgKG5vZGUuaGVpZ2h0IC8gMiAtIDEwKSArXG4gICAgICAgICAgJyknXG4gICAgICAgIFwiPlxuICAgICAgICA8c3ZnOnJlY3QgeD1cIi01XCIgeT1cIi01XCIgd2lkdGg9XCIzMFwiIGhlaWdodD1cIjMwXCIgZmlsbD1cInRyYW5zcGFyZW50XCIgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXJcIiAvPlxuICAgICAgICA8c3ZnOnBhdGggZD1cIk0xMCAwSDIwVjJIMTBWMFpNMTAgOEgyMFYxMEgxMFY4Wk0xMCA0SDIwVjZIMTBWNFpNMCAwSDhWMkgwVjBaTTAgOEg4VjEwSDBWOFpNMCA0SDhWNkgwVjRaXCJcbiAgICAgICAgICBmaWxsPVwiI0QzNkNGRlwiIC8+XG4gICAgICA8L3N2ZzpnPlxuICAgICAgfVxuXG4gICAgICA8IS0tIEZvcm0gbm9kZSAtLT5cbiAgICAgIEBpZiAobm9kZS50eXBlID09PSAnZm9ybScpIHtcbiAgICAgIDxwYXRoXG4gICAgICAgIGQ9XCJNOTUuMDYyNSA1MC41NTkxVjk1LjA2MjVDOTUuMDYyNSA5Ny45NzE2IDkzLjkwNjkgMTAwLjc2MiA5MS44NDk4IDEwMi44MTlDODkuNzkyOCAxMDQuODc2IDg3LjAwMjggMTA2LjAzMSA4NC4wOTM4IDEwNi4wMzFIMzIuOTA2MkMyOS45OTcyIDEwNi4wMzEgMjcuMjA3MiAxMDQuODc2IDI1LjE1MDIgMTAyLjgxOUMyMy4wOTMxIDEwMC43NjIgMjEuOTM3NSA5Ny45NzE2IDIxLjkzNzUgOTUuMDYyNVYyMS45Mzc1QzIxLjkzNzUgMTkuMDI4NCAyMy4wOTMxIDE2LjIzODUgMjUuMTUwMiAxNC4xODE0QzI3LjIwNzIgMTIuMTI0NCAyOS45OTcyIDEwLjk2ODggMzIuOTA2MiAxMC45Njg4SDU1LjQ3MjJDNTcuNDEwOSAxMC45NjkgNTkuMjcwMSAxMS43MzkyIDYwLjY0MTIgMTMuMTA5OUw5Mi45MjEzIDQ1LjM5MDFDOTQuMjkyIDQ2Ljc2MTEgOTUuMDYyMiA0OC42MjA0IDk1LjA2MjUgNTAuNTU5MVpcIlxuICAgICAgICB0cmFuc2Zvcm09XCJzY2FsZSgwLjcpXCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjRDM2Q0ZGXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk01OC41IDEyLjc5NjlWNDAuMjE4OEM1OC41IDQyLjE1ODEgNTkuMjcwNCA0NC4wMTgxIDYwLjY0MTggNDUuMzg5NUM2Mi4wMTMxIDQ2Ljc2MDggNjMuODczMSA0Ny41MzEyIDY1LjgxMjUgNDcuNTMxMkg5My4yMzQ0XCJcbiAgICAgICAgdHJhbnNmb3JtPVwic2NhbGUoMC43KVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPHRleHQgeD1cIjUwJVwiIHk9XCI1MCVcIiB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiIGRvbWluYW50LWJhc2VsaW5lPVwibWlkZGxlXCIgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCIgZm9udC1zaXplPVwiMTRcIlxuICAgICAgICBmaWxsPVwiI0QzNkNGRlwiPlxuICAgICAgICBGb3JtXG4gICAgICA8L3RleHQ+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gU3ViZmxvdyBub2RlIC0tPlxuICAgICAgQGlmIChub2RlLnR5cGUgPT09ICdzdWJmbG93Jykge1xuICAgICAgPHN2ZzpnIGxpYi1zdGFnZS1ub2RlIFtub2RlXT1cIm5vZGVcIiBbaXNTdGFydE5vZGVdPVwibm9kZS5pc1N0YXJ0Tm9kZVwiIFtpc1N1YmZsb3ddPVwidHJ1ZVwiXG4gICAgICAgIChzdGFnZVByb3BlcnRpZXNVcGRhdGVkKT1cIm9uU3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCgkZXZlbnQpXCIgKHNob3dTaGllbGREaWFsb2cpPVwib25TaG93U2hpZWxkRGlhbG9nKCRldmVudClcIlxuICAgICAgICAoc2hvd0VzY2FsYXRpb25EaWFsb2cpPVwib25TaG93RXNjYWxhdGlvbkRpYWxvZygkZXZlbnQpXCIgKHNob3dGb3JtRGlhbG9nKT1cIlxuICAgICAgICAgIHRvZ2dsZVN0YXJ0Tm9kZUZvcm1Qb3B1cCgkZXZlbnQsIG5vZGUueCwgbm9kZS55LCBzd2ltbGFuZS5vcmRlciwgbm9kZSlcbiAgICAgICAgXCI+PC9zdmc6Zz5cbiAgICAgIH1cblxuICAgICAgPCEtLSBDb25uZWN0aW9uIHBvaW50cyBmb3IgdGhpcyBub2RlIC0tPlxuICAgICAgQGZvciAocG9pbnQgb2Ygbm9kZS5jb25uZWN0aW9uUG9pbnRzIHx8IFtdOyB0cmFjayBwb2ludC5pZCkgeyBAaWZcbiAgICAgIChpc0Nvbm5lY3Rpb25Qb2ludFZpc2libGUobm9kZS5pZCkpIHtcbiAgICAgIDx1c2UgW2F0dHIuaHJlZl09XCInI2Nvbm5lY3Rpb24tcG9pbnQtdGVtcGxhdGUnXCIgW2F0dHIueF09XCJwb2ludC54XCIgW2F0dHIueV09XCJwb2ludC55XCIgW2F0dHIuaWRdPVwicG9pbnQuaWRcIlxuICAgICAgICAobW91c2Vkb3duKT1cInN0YXJ0Q29ubmVjdGlvbkRyYWcoJGV2ZW50LCBwb2ludCwgc3dpbWxhbmUub3JkZXIpXCIgLz5cbiAgICAgIH0gfVxuICAgIDwvZz5cbiAgICA8IS0tIEEgdHJhbnNwYXJlbnQgaG92ZXIgYXJlYSBmb3IgaW1wcm92ZWQgaG92ZXIgZGV0ZWN0aW9uIC0tPlxuICAgIDxyZWN0IFthdHRyLnhdPVwibm9kZS54IC0gMTBcIiBbYXR0ci55XT1cIm5vZGUueSAtIDEwXCIgW2F0dHIud2lkdGhdPVwibm9kZS53aWR0aCArIDIwXCIgW2F0dHIuaGVpZ2h0XT1cIm5vZGUuaGVpZ2h0ICsgMjBcIlxuICAgICAgZmlsbD1cInRyYW5zcGFyZW50XCIgKG1vdXNlb3Zlcik9XCJzaG93Q29ubmVjdGlvblBvaW50cyhub2RlLmlkLCBzd2ltbGFuZS5vcmRlcilcIlxuICAgICAgKG1vdXNlb3V0KT1cImhpZGVDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQpXCIgc3R5bGU9XCJwb2ludGVyLWV2ZW50czogbm9uZVwiIC8+XG4gICAgfSB9XG5cbiAgICA8IS0tIENvbm5lY3Rpb25zIC0tPlxuICAgIEBmb3IgKGNvbm5lY3Rpb24gb2Ygc3RhdGUuY29ubmVjdGlvbnM7IHRyYWNrIGNvbm5lY3Rpb24uaWQpIHtcbiAgICA8ZyBjbGFzcz1cImNvbm5lY3Rpb24tZWxlbWVudFwiPlxuICAgICAgPHBhdGggW2F0dHIuZF09XCJnZXRDb25uZWN0aW9uUGF0aEZvclNhdmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIyXCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICBtYXJrZXItZW5kPVwidXJsKCNhcnJvd2hlYWQpXCI+PC9wYXRoPlxuXG4gICAgICA8IS0tIENvbm5lY3Rpb24gTGFiZWwgLS0+XG4gICAgICBAaWYgKGNvbm5lY3Rpb24uc291cmNlTm9kZUlkICYmIGNvbm5lY3Rpb24udGFyZ2V0Tm9kZUlkKSB7XG4gICAgICA8Zm9yZWlnbk9iamVjdCBbYXR0ci54XT1cImdldExhYmVsUG9zaXRpb24oY29ubmVjdGlvbikueFwiIFthdHRyLnldPVwiZ2V0TGFiZWxQb3NpdGlvbihjb25uZWN0aW9uKS55XCIgd2lkdGg9XCIxNTBcIlxuICAgICAgICBoZWlnaHQ9XCI0MFwiIHN0eWxlPVwib3ZlcmZsb3c6IHZpc2libGU7IHBvaW50ZXItZXZlbnRzOiBhbGw7XCIgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoLTc1LCAtMTApJ1wiPlxuICAgICAgICA8d2YtbGFiZWwtZWRpdG9yIFtsYWJlbF09XCJjb25uZWN0aW9uLmxhYmVsIHx8ICdOZXcgQWN0aW9uJ1wiIFt4XT1cIjBcIiBbeV09XCIwXCIgW2lzQ29ubmVjdGlvbl09XCJ0cnVlXCJcbiAgICAgICAgICAobGFiZWxDaGFuZ2UpPVwic2F2ZUNvbm5lY3Rpb25MYWJlbChjb25uZWN0aW9uLCAkZXZlbnQpXCIgKG9wZW5EaWFsb2cpPVwib25TaG93QWN0aW9uRGlhbG9nKGNvbm5lY3Rpb24pXCIgLz5cbiAgICAgIDwvZm9yZWlnbk9iamVjdD5cbiAgICAgIH1cbiAgICA8L2c+XG4gICAgfVxuXG4gICAgPCEtLSBDb25uZWN0aW9uIHByZXZpZXcgbGluZSAtLT5cbiAgICBAaWYgKHN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpIHtcbiAgICA8Zz5cbiAgICAgIDxwYXRoIFthdHRyLmRdPVwiZ2V0Q29ubmVjdGlvblBhdGgoKVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWRhc2hhcnJheT1cIjUsNVwiIGZpbGw9XCJub25lXCI+PC9wYXRoPlxuICAgIDwvZz5cbiAgICB9XG4gIDwvc3ZnPlxuXG4gIDxkaXYgKm5nSWY9XCJwb3B1cFZpc2libGVcIiBbc3R5bGUucG9zaXRpb25dPVwiJ2Fic29sdXRlJ1wiIFtzdHlsZS5sZWZ0LnB4XT1cInBvcHVwWFwiIFtzdHlsZS50b3AucHhdPVwicG9wdXBZXCI+XG4gICAgPHZlcmJlbi1wb3AtVXAgW2Ryb3Bkb3duT3Blbl09XCJ0cnVlXCIgW2N1c3RvbVN0eWxlc109XCJ7ICd6LWluZGV4JzogJzk5JyB9XCIgW2VuYWJsZU1vdXNlTGVhdmVdPVwiZmFsc2VcIlxuICAgICAgKGRyb3Bkb3duT3BlbkNoYW5nZSk9XCIkZXZlbnQgPyBudWxsIDogaGlkZUNvbm5lY3Rpb25Qb3B1cCgpXCI+XG4gICAgICA8ZGl2IGRyb3Bkb3duLXRyaWdnZXIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+XG4gICAgICAgIDwhLS0gSGlkZGVuIHRyaWdnZXIgZWxlbWVudCAtLT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInAtMyBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgc2hhZG93LW1kXCIgZHJvcGRvd24tY29udGVudD5cbiAgICAgICAgPGg0IGNsYXNzPVwibWItMiBmb250LW1lZGl1bVwiPkNyZWF0ZSBDb25uZWN0aW9uPC9oND5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTJcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0eXBlIG9mIGFsbG93ZWROb2RlVHlwZXNcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJweC0zIHB5LTIgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCByb3VuZGVkIHRleHQtc20gaG92ZXI6YmctZ3JheS01MFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjcmVhdGVOb2RlQ29ubmVjdGlvbih0eXBlKVwiPlxuICAgICAgICAgICAgICBDcmVhdGUge3sgdHlwZSB8IHRpdGxlY2FzZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInB4LTMgcHktMiBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgdGV4dC1zbSBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICAgIChjbGljayk9XCJoaWRlQ29ubmVjdGlvblBvcHVwKClcIj5cbiAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvdmVyYmVuLXBvcC1VcD5cbiAgPC9kaXY+XG5cbiAgPGRpdiAqbmdJZj1cInNob3dTdGFydE5vZGVGb3JtUG9wdXBcIiBbc3R5bGUucG9zaXRpb25dPVwiJ2Fic29sdXRlJ1wiIFtzdHlsZS5sZWZ0LnB4XT1cInN0YXJ0Tm9kZUZvcm1Qb3B1cFhcIlxuICAgIFtzdHlsZS50b3AucHhdPVwic3RhcnROb2RlRm9ybVBvcHVwWVwiPlxuICAgIDx2ZXJiZW4tcG9wLVVwIFtkcm9wZG93bk9wZW5dPVwidHJ1ZVwiIFtjdXN0b21TdHlsZXNdPVwieyAnei1pbmRleCc6ICcxMDAnIH1cIj5cbiAgICAgIDxkaXYgZHJvcGRvd24tdHJpZ2dlciBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIj5cbiAgICAgICAgPCEtLSBIaWRkZW4gdHJpZ2dlciBlbGVtZW50IC0tPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwicC0zIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0yMDAgcm91bmRlZCBzaGFkb3ctbWQgdy02NFwiIGRyb3Bkb3duLWNvbnRlbnRcbiAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgei1pbmRleDogMTAwMFwiPlxuICAgICAgICA8aDQgY2xhc3M9XCJtYi0yIGZvbnQtbWVkaXVtXCI+U2VsZWN0IFdvcmtmbG93IEZvcm08L2g0PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNMb2FkaW5nU3RhcnROb2RlRm9ybXNcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTJcIj5cbiAgICAgICAgICBMb2FkaW5nIGZvcm1zLi4uXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWlzTG9hZGluZ1N0YXJ0Tm9kZUZvcm1zXCIgY2xhc3M9XCJtYXgtaC00OCBvdmVyZmxvdy15LWF1dG9cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBweC0zIHB5LTIgYmctZ3JheS01MCBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgdGV4dC1zbSBob3ZlcjpiZy1ncmF5LTUwIHRleHQtbGVmdFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTdGFydE5vZGVGb3JtKG51bGwpXCI+XG4gICAgICAgICAgICAgIENsZWFyIGZvcm0gc2VsZWN0aW9uXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBmb3JtIG9mIHN0YXJ0Tm9kZUZvcm1zTGlzdFwiIGNsYXNzPVwibWItMVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInctZnVsbCBweC0zIHB5LTIgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCByb3VuZGVkIHRleHQtc20gaG92ZXI6YmctZ3JheS01MCB0ZXh0LWxlZnRcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdiZy1ibHVlLTUwICFib3JkZXItYmx1ZS01MDAgIWJvcmRlci0yIGZvbnQtc2VtaWJvbGQnOiBmb3JtPy5Db2RlID09PSBhY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbj8uc3RhZ2VEYXRhPy5mb3JtSWR9XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFN0YXJ0Tm9kZUZvcm0oZm9ybSlcIj5cbiAgICAgICAgICAgICAge3sgZm9ybS5OYW1lIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwic3RhcnROb2RlRm9ybXNMaXN0Lmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktMiB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICBObyBmb3JtcyBhdmFpbGFibGVcbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3ZlcmJlbi1wb3AtVXA+XG4gIDwvZGl2PlxuXG4gIDxkaXYgKm5nSWY9XCJzaG93U3ViZmxvd1BvcHVwXCIgW3N0eWxlLnBvc2l0aW9uXT1cIidhYnNvbHV0ZSdcIiBbc3R5bGUubGVmdC5weF09XCJzdWJmbG93UG9wdXBYXCJcbiAgICBbc3R5bGUudG9wLnB4XT1cInN1YmZsb3dQb3B1cFlcIj5cbiAgICA8dmVyYmVuLXBvcC1VcCBbZHJvcGRvd25PcGVuXT1cInRydWVcIiBbY3VzdG9tU3R5bGVzXT1cInsgJ3otaW5kZXgnOiAnMTAwJyB9XCI+XG4gICAgICA8ZGl2IGRyb3Bkb3duLXRyaWdnZXIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+XG4gICAgICAgIDwhLS0gSGlkZGVuIHRyaWdnZXIgZWxlbWVudCAtLT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInAtMyBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgc2hhZG93LW1kIHctNjRcIiBkcm9wZG93bi1jb250ZW50XG4gICAgICAgIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IHotaW5kZXg6IDEwMDBcIj5cbiAgICAgICAgPGg0IGNsYXNzPVwibWItMiBmb250LW1lZGl1bVwiPlNlbGVjdCBXb3JrZmxvdzwvaDQ+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJpc0xvYWRpbmdXb3JrZmxvd3NcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTJcIj5cbiAgICAgICAgICBMb2FkaW5nIHdvcmtmbG93cy4uLlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFpc0xvYWRpbmdXb3JrZmxvd3NcIiBjbGFzcz1cIm1heC1oLTQ4IG92ZXJmbG93LXktYXV0b1wiPlxuICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHdvcmtmbG93IG9mIHdvcmtmbG93c0xpc3RcIiBjbGFzcz1cIm1iLTFcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ3LWZ1bGwgcHgtMyBweS0yIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0yMDAgcm91bmRlZCB0ZXh0LXNtIGhvdmVyOmJnLWdyYXktNTAgdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFN1YmZsb3dXb3JrZmxvdyh3b3JrZmxvdylcIj5cbiAgICAgICAgICAgICAge3sgd29ya2Zsb3cuTmFtZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cIndvcmtmbG93c0xpc3QubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS0yIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgIE5vIHdvcmtmbG93cyBhdmFpbGFibGVcbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3ZlcmJlbi1wb3AtVXA+XG4gIDwvZGl2PlxuXG4gIDxsaWItY29uZGl0aW9ucy1wb3B1cCBbdmlzaWJsZV09XCJzaG93RGVjaXNpb25Db25kaXRpb25EaWFsb2dcIiBbZGVjaXNpb25Ob2RlSWRdPVwiYWN0aXZlRGVjaXNpb25Ob2RlSWRcIlxuICAgIFtuZXdDb25uZWN0aW9uSWRdPVwiYWN0aXZlQ29ubmVjdGlvbklkXCIgW3BvcHVwWF09XCJkZWNpc2lvbkNvbmRpdGlvblBvcHVwWFwiIFtwb3B1cFldPVwiZGVjaXNpb25Db25kaXRpb25Qb3B1cFlcIlxuICAgIChjbG9zZWQpPVwib25EZWNpc2lvbkNvbmRpdGlvbkNhbmNlbGxlZCgpXCIgKHNhdmVkKT1cIm9uRGVjaXNpb25Db25kaXRpb25TYXZlZCgkZXZlbnQpXCI+PC9saWItY29uZGl0aW9ucy1wb3B1cD5cblxuICA8IS0tIDxsaWItZGVjaXNpb24tcG9wdXBcbiAgICBbdmlzaWJsZV09XCJzaG93Q29uZGl0aW9uc0RpYWxvZ1wiXG4gICAgW2RlY2lzaW9uTm9kZUlkXT1cImFjdGl2ZURlY2lzaW9uTm9kZUlkXCJcbiAgICBbcG9wdXBYXT1cImRlY2lzaW9uQ29uZGl0aW9uUG9wdXBYXCJcbiAgICBbcG9wdXBZXT1cImRlY2lzaW9uQ29uZGl0aW9uUG9wdXBZXCJcbiAgICAoY2xvc2VkKT1cIm9uRGVjaXNpb25Db25kaXRpb25DYW5jZWxsZWQoKVwiXG4gID48L2xpYi1kZWNpc2lvbi1wb3B1cD4gLS0+XG5cbiAgPGxpYi1zdGFnZS1kaWFsb2cgW3Zpc2libGVdPVwic2hvd1N0YWdlRGlhbG9nTG9jYWxcIiBbc3RhZ2VEYXRhXT1cImFjdGl2ZVN0YWdlRGF0YSB8fCB7fVwiXG4gICAgKGNsb3NlZCk9XCJvblN0YWdlRGlhbG9nQ2xvc2VkKClcIiAoc2F2ZWQpPVwib25TdGFnZURpYWxvZ1NhdmVkKCRldmVudClcIj48L2xpYi1zdGFnZS1kaWFsb2c+XG5cbiAgPGxpYi1hY3Rpb24tZGlhbG9nIFt2aXNpYmxlXT1cInNob3dBY3Rpb25EaWFsb2dMb2NhbFwiIFthY3Rpb25EYXRhXT1cImFjdGl2ZUFjdGlvbkRhdGFcIiAoY2xvc2VkKT1cIm9uQWN0aW9uRGlhbG9nQ2xvc2VkKClcIlxuICAgIChzYXZlZCk9XCJvbkFjdGlvbkRpYWxvZ1NhdmVkKCRldmVudClcIj48L2xpYi1hY3Rpb24tZGlhbG9nPlxuXG4gIDxsaWItZXNjYWxhdGlvbi1kaWFsb2cgW3Zpc2libGVdPVwic2hvd0VzY2FsYXRpb25EaWFsb2dMb2NhbFwiIFt0eXBlXT1cImFjdGl2ZUVzY2FsYXRpb25UeXBlKCkhXCJcbiAgICBbc3RhZ2VDb2RlXT1cImFjdGl2ZVN0YWdlQ29kZSgpIHx8ICcnXCIgW3dvcmtmbG93Q29kZV09XCJzdGF0ZS53b3JrZmxvdz8uQ29kZSB8fCAnJ1wiXG4gICAgKGNsb3NlZCk9XCJvbkVzY2FsYXRpb25EaWFsb2dDbG9zZWQoKVwiPjwvbGliLWVzY2FsYXRpb24tZGlhbG9nPlxuPC9kaXY+XG4iXX0=
1204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduZXItY2FudmFzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3ZlcmJlbi13b3JrZmxvdy11aS9zcmMvbGliL2NvbXBvbmVudHMvd29ya2Zsb3ctZGVzaWduZXIvZGVzaWduZXItY2FudmFzL2Rlc2lnbmVyLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92ZXJiZW4td29ya2Zsb3ctdWkvc3JjL2xpYi9jb21wb25lbnRzL3dvcmtmbG93LWRlc2lnbmVyL2Rlc2lnbmVyLWNhbnZhcy9kZXNpZ25lci1jYW52YXMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsR0FFVixNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7Ozs7O0FBa0J2QixNQUFNLE9BQU8sdUJBQXVCO0lBNkd6QjtJQUNDO0lBN0dELFlBQVksR0FBYSxJQUFJLENBQUM7SUFDN0IsZUFBZSxHQUFHLElBQUksWUFBWSxFQUE0QixDQUFDO0lBQy9ELGVBQWUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQy9DLG9CQUFvQixHQUNsQixJQUFJLENBQUM7SUFDRyxzQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFHL0MsQ0FBQztJQUNLLHVCQUF1QixHQUFHLElBQUksWUFBWSxFQUdoRCxDQUFDO0lBRUwsK0JBQStCO0lBQ1EsU0FBUyxDQUEwQjtJQUcxRSxlQUFlLENBQUMsS0FBaUI7UUFDL0Isc0VBQXNFO1FBQ3RFLElBQ0UsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCO1lBQ3RCLENBQUMsSUFBSSxDQUFDLHNCQUFzQjtZQUM1QixDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksdUNBQXVDO1lBQzdELElBQUks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QkFBaEMsTUFBTTtnQkFNZ0MsU0FBUztzQkFBL0MsU0FBUzt1QkFBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUdyQyxlQUFlO3NCQURkLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIHNpZ25hbCxcbiAgVmlld0NoaWxkLFxuICBXcml0YWJsZVNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFc2NhbGF0aW9uVHlwZSwgRm9ybSwgV29ya2Zsb3csIFdvcmtmbG93QWN0aW9uLCBXb3JrZmxvd1N0YWdlIH0gZnJvbSAndmVyYmVuLXdvcmtmbG93LXVpL3NyYy9saWIvbW9kZWxzJztcbmltcG9ydCB7IFdvcmtmbG93RGF0YVNlcnZpY2UgfSBmcm9tICcuLi93b3JrZmxvdy1kYXRhLnNlcnZpY2UnO1xuaW1wb3J0IHsgV29ya2Zsb3dEZXNpZ25lclN0YXRlIH0gZnJvbSAnLi4vd29ya2Zsb3ctZGVzaWduZXIuc3RhdGUnO1xuaW1wb3J0IHtcbiAgQ29ubmVjdGlvbixcbiAgQ29ubmVjdGlvblBvaW50LFxuICBOb2RlLFxuICBTd2ltbGFuZUl0ZW0sXG4gIFRvb2xUeXBlLFxuICBOb2RlIGFzIFdGTm9kZSxcbn0gZnJvbSAnLi4vd29ya2Zsb3ctZGVzaWduZXIudHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItZGVzaWduZXItY2FudmFzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Rlc2lnbmVyLWNhbnZhcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9kZXNpZ25lci1jYW52YXMuY29tcG9uZW50LmNzcycsXG59KVxuZXhwb3J0IGNsYXNzIERlc2lnbmVyQ2FudmFzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgc2VsZWN0ZWRUb29sOiBUb29sVHlwZSA9IG51bGw7XG4gIEBPdXRwdXQoKSBjbGlja2VkUG9zaXRpb24gPSBuZXcgRXZlbnRFbWl0dGVyPHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfT4oKTtcbiAgQE91dHB1dCgpIHN1YmZsb3dTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgcGVuZGluZ1N0YWdlUG9zaXRpb246IHsgc3dpbWxhbmVJbmRleDogbnVtYmVyOyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHwgbnVsbCA9XG4gICAgbnVsbDtcbiAgQE91dHB1dCgpIHN0YWdlUHJvcGVydGllc1VwZGF0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHtcbiAgICBub2RlSWQ6IHN0cmluZztcbiAgICBzdGFnZURhdGE6IFBhcnRpYWw8V29ya2Zsb3dTdGFnZT47XG4gIH0+KCk7XG4gIEBPdXRwdXQoKSBhY3Rpb25Qcm9wZXJ0aWVzVXBkYXRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuICAgIGFjdGlvbkRhdGE6IFBhcnRpYWw8V29ya2Zsb3dBY3Rpb24+O1xuICB9PigpO1xuXG4gIC8vIFJlZmVyZW5jZSB0byB0aGUgU1ZHIGVsZW1lbnRcbiAgQFZpZXdDaGlsZCgnY2FudmFzJywgeyBzdGF0aWM6IHRydWUgfSkgY2FudmFzUmVmITogRWxlbWVudFJlZjxTVkdFbGVtZW50PjtcblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6bW91c2V1cCcsIFsnJGV2ZW50J10pXG4gIG9uV2luZG93TW91c2VVcChldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIC8vIElmIHdlIGhhdmUgYSBwb3B1cCBvcGVuIGJ1dCB0aGUgbW91c2UgaXMgcmVsZWFzZWQgb3V0c2lkZSwgY2xlYW4gdXBcbiAgICBpZiAoXG4gICAgICAhdGhpcy5zaG93U3ViZmxvd1BvcHVwICYmXG4gICAgICAhdGhpcy5zaG93U3RhcnROb2RlRm9ybVBvcHVwICYmXG4gICAgICAhdGhpcy5wb3B1cFZpc2libGUgJiYgLy8gT25seSBlbmQgZHJhZyBpZiBubyBwb3B1cCBpcyB2aXNpYmxlXG4gICAgICB0aGlzLnN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKClcbiAgICApIHtcbiAgICAgIGNvbnNvbGUubG9nKCdFeHRlcm5hbCBtb3VzZXVwIGRldGVjdGVkIC0gY2xlYW5pbmcgdXAgY29ubmVjdGlvbiBkcmFnJyk7XG4gICAgICB0aGlzLnN0YXRlLmVuZENvbm5lY3Rpb25EcmFnKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2FudmFzIGRpbWVuc2lvbnNcbiAgY2FudmFzV2lkdGggPSAzMDAwO1xuICBjYW52YXNIZWlnaHQgPSAyMDAwO1xuXG4gIC8vIEdyaWQgc2l6ZVxuICBncmlkU2l6ZSA9IDIwO1xuXG4gIHN3aW1sYW5lSGVpZ2h0ID0gMjYzO1xuICB2aXNpYmxlQ29ubmVjdGlvblBvaW50c05vZGVJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHBvcHVwVmlzaWJsZSA9IGZhbHNlO1xuICBwb3B1cFggPSAwO1xuICBwb3B1cFkgPSAwO1xuICBhbGxvd2VkTm9kZVR5cGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHNob3dTdGFydE5vZGVGb3JtUG9wdXA6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc3RhcnROb2RlRm9ybXNMaXN0OiBGb3JtW10gPSBbXTtcbiAgaXNMb2FkaW5nU3RhcnROb2RlRm9ybXM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc3RhcnROb2RlRm9ybVBvcHVwWDogbnVtYmVyID0gMDtcbiAgc3RhcnROb2RlRm9ybVBvcHVwWTogbnVtYmVyID0gMDtcbiAgYWN0aXZlTm9kZUZvckZvcm1TZWxlY3Rpb246IE5vZGUgfCBudWxsID0gbnVsbDtcbiAgbm9kZUZvcm1zOiBXcml0YWJsZVNpZ25hbDxcbiAgICBSZWNvcmQ8c3RyaW5nLCB7IGZvcm1JZDogc3RyaW5nOyBmb3JtTmFtZTogc3RyaW5nIH0+XG4gID4gPSBzaWduYWwoe30pO1xuXG4gIHNob3dTdWJmbG93UG9wdXA6IGJvb2xlYW4gPSBmYWxzZTtcbiAgd29ya2Zsb3dzTGlzdDogV29ya2Zsb3dbXSA9IFtdO1xuICBpc0xvYWRpbmdXb3JrZmxvd3M6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc3ViZmxvd1BvcHVwWDogbnVtYmVyID0gMDtcbiAgc3ViZmxvd1BvcHVwWTogbnVtYmVyID0gMDtcbiAgcGVuZGluZ1N1YmZsb3dQb3NpdGlvbjoge1xuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlcjtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xuICB9IHwgbnVsbCA9IG51bGw7XG5cbiAgcGVuZGluZ0RlY2lzaW9uQ29ubmVjdGlvbjoge1xuICAgIGRlY2lzaW9uTm9kZUlkOiBzdHJpbmc7XG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyO1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBwZW5kaW5nQ29ubmVjdGlvblNvdXJjZVBvaW50OiBDb25uZWN0aW9uUG9pbnQgfCBudWxsID0gbnVsbDtcbiAgcGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VTd2ltbGFuZUluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvLyDilIDilIDilIAgTm9kZS1kcmFnIHN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBpc0RyYWdnaW5nTm9kZSA9IGZhbHNlO1xuICBkcmFnZ2luZ05vZGU6IE5vZGUgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmFnZ2luZ05vZGVTd2ltbGFuZUluZGV4OiBudW1iZXIgPSAtMTtcbiAgLyoqIE1vdXNlIG9mZnNldCByZWxhdGl2ZSB0byBub2RlIHRvcC1sZWZ0IGF0IGRyYWcgc3RhcnQgKGFic29sdXRlIGNhbnZhcyBjb29yZHMpLiAqL1xuICBwcml2YXRlIGRyYWdPZmZzZXRYID0gMDtcbiAgcHJpdmF0ZSBkcmFnT2Zmc2V0WSA9IDA7XG5cbiAgc2hvd0RlY2lzaW9uQ29uZGl0aW9uRGlhbG9nOiBib29sZWFuID0gZmFsc2U7XG4gIHNob3dDb25kaXRpb25zRGlhbG9nOiBib29sZWFuID0gZmFsc2U7XG4gIGFjdGl2ZURlY2lzaW9uTm9kZUlkOiBzdHJpbmcgPSAnJztcbiAgYWN0aXZlQ29ubmVjdGlvbklkOiBzdHJpbmcgPSAnJztcbiAgZGVjaXNpb25Db25kaXRpb25Qb3B1cFg6IG51bWJlciA9IDA7XG4gIGRlY2lzaW9uQ29uZGl0aW9uUG9wdXBZOiBudW1iZXIgPSAwO1xuXG4gIGlzQ3JlYXRpbmdTdGFnZUZyb21EZWNpc2lvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBwZW5kaW5nRGVjaXNpb25Db25kaXRpb246IHN0cmluZyA9ICcnO1xuICBhY3RpdmVTdGFnZUlkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgYWN0aXZlQWN0aW9uSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIHNob3dTdGFnZURpYWxvZ0xvY2FsOiBib29sZWFuID0gZmFsc2U7XG4gIHNob3dFc2NhbGF0aW9uRGlhbG9nTG9jYWw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYWN0aXZlRXNjYWxhdGlvblR5cGU6IFdyaXRhYmxlU2lnbmFsPEVzY2FsYXRpb25UeXBlIHwgbnVsbD4gPSBzaWduYWwobnVsbCk7XG4gIGFjdGl2ZVN0YWdlQ29kZTogV3JpdGFibGVTaWduYWw8c3RyaW5nIHwgbnVsbD4gPSBzaWduYWwobnVsbCk7XG4gIGFjdGl2ZVN0YWdlRGF0YTogUGFydGlhbDxXb3JrZmxvd1N0YWdlPiA9IHt9O1xuICBhY3RpdmVBY3Rpb25EYXRhOiBDb25uZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgc2hvd0FjdGlvbkRpYWxvZ0xvY2FsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcG90ZW50aWFsVGFyZ2V0UG9pbnRJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHN0YXRlOiBXb3JrZmxvd0Rlc2lnbmVyU3RhdGUsXG4gICAgcHJpdmF0ZSBkYXRhU2VydmljZTogV29ya2Zsb3dEYXRhU2VydmljZVxuICApIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlQ2FudmFzU2l6ZSgpO1xuICB9XG5cbiAgLy8gSGFuZGxlIG1vdXNlIGNsaWNrIG9uIGNhbnZhc1xuICBvbkNhbnZhc0NsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gT25seSBwcm9jZXNzIGNhbnZhcyBjbGlja3MgaWYgYSB0b29sIGlzIHNlbGVjdGVkXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkVG9vbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEdldCB0aGUgcG9zaXRpb24gd2hlcmUgdGhlIGNsaWNrIG9jY3VycmVkXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgJ0NhbnZhcyBjbGlja2VkIGF0OicsXG4gICAgICBwb3NpdGlvbixcbiAgICAgICd3aXRoIHRvb2w6JyxcbiAgICAgIHRoaXMuc2VsZWN0ZWRUb29sXG4gICAgKTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgc3dpbWxhbmUgaW5kZXggYmFzZWQgb24gcG9zaXRpb25cbiAgICAvLyBjb25zdCBzd2ltbGFuZUluZGV4ID0gTWF0aC5mbG9vcihwb3NpdGlvbi55IC8gdGhpcy5zd2ltbGFuZUhlaWdodCk7XG5cbiAgICAvLyBPbmx5IGVtaXQgdGhlIHBvc2l0aW9uIGlmIHdlIGhhdmUgYSB0b29sIHNlbGVjdGVkIGFuZCBpdCdzIGEgdmFsaWQgY2xpY2sgYXJlYVxuICAgIGlmICh0aGlzLnNlbGVjdGVkVG9vbCkge1xuICAgICAgdGhpcy5jbGlja2VkUG9zaXRpb24uZW1pdCh7XG4gICAgICAgIHg6IHBvc2l0aW9uLngsXG4gICAgICAgIHk6IHBvc2l0aW9uLnksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvblNob3dTaGllbGREaWFsb2coc3RhZ2VJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgbm9kZVxuICAgIGNvbnN0IG5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoc3RhZ2VJZCk7XG4gICAgaWYgKG5vZGVJbmZvKSB7XG4gICAgICB0aGlzLmFjdGl2ZVN0YWdlSWQgPSBzdGFnZUlkO1xuICAgICAgdGhpcy5hY3RpdmVTdGFnZURhdGEgPSB7IC4uLm5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhLCBpZDogc3RhZ2VJZCB9O1xuICAgICAgY29uc29sZS5sb2codGhpcy5hY3RpdmVTdGFnZURhdGEsIFwiQUNUSVZFIFNUQUdFIERBVEFcIik7XG4gICAgICB0aGlzLnNob3dTdGFnZURpYWxvZ0xvY2FsID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBvblNob3dBY3Rpb25EaWFsb2coY29ubmVjdGlvbkluZm86IENvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyhcIkNPTkVDVElPTlwiLCBjb25uZWN0aW9uSW5mbyk7XG4gICAgLy8gRmluZCB0aGUgbm9kZVxuICAgIC8vIGNvbnN0IGNvbm5lY3Rpb25JbmZvID0gdGhpcy5zdGF0ZS5maW5kQWN0aW9uQnlJZChhY3Rpb25JZCk7XG4gICAgaWYgKGNvbm5lY3Rpb25JbmZvKSB7XG4gICAgICB0aGlzLmFjdGl2ZUFjdGlvbklkID0gY29ubmVjdGlvbkluZm8uaWQ7XG4gICAgICB0aGlzLmFjdGl2ZUFjdGlvbkRhdGEgPSBjb25uZWN0aW9uSW5mbztcbiAgICAgIGNvbnNvbGUubG9nKHRoaXMuYWN0aXZlQWN0aW9uRGF0YSk7XG4gICAgICB0aGlzLnNob3dBY3Rpb25EaWFsb2dMb2NhbCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgb25TaG93RXNjYWxhdGlvbkRpYWxvZyhldmVudDoge1xuICAgIHN0YWdlSWQ6IHN0cmluZztcbiAgICB0eXBlOiBFc2NhbGF0aW9uVHlwZTtcbiAgfSk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIG5vZGVcbiAgICBjb25zdCBub2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKGV2ZW50LnN0YWdlSWQpO1xuICAgIGlmIChub2RlSW5mbykge1xuICAgICAgdGhpcy5hY3RpdmVTdGFnZUlkID0gZXZlbnQuc3RhZ2VJZDtcbiAgICAgIHRoaXMuYWN0aXZlU3RhZ2VEYXRhID0gbm9kZUluZm8ubm9kZS5zdGFnZURhdGEgfHwge1xuICAgICAgICBpZDogdGhpcy5hY3RpdmVTdGFnZUlkLFxuICAgICAgfTtcbiAgICAgIHRoaXMuYWN0aXZlRXNjYWxhdGlvblR5cGUuc2V0KGV2ZW50LnR5cGUpO1xuICAgICAgdGhpcy5hY3RpdmVTdGFnZUNvZGUuc2V0KHRoaXMuYWN0aXZlU3RhZ2VEYXRhPy5Db2RlIHx8ICcnKTtcbiAgICAgIGNvbnNvbGUubG9nKCdBY3RpdmUgU3RhZ2UgRGF0YTonLCB0aGlzLmFjdGl2ZVN0YWdlRGF0YSk7XG4gICAgICBjb25zb2xlLmxvZygnRXNjYWxhdGlvbiBUeXBlOicsIHRoaXMuYWN0aXZlRXNjYWxhdGlvblR5cGUoKSk7XG4gICAgICB0aGlzLnNob3dFc2NhbGF0aW9uRGlhbG9nTG9jYWwgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFkZCB0aGlzIG1ldGhvZCB0byBoYW5kbGUgZGlhbG9nIGNsb3N1cmVcbiAgb25TdGFnZURpYWxvZ0Nsb3NlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dTdGFnZURpYWxvZ0xvY2FsID0gZmFsc2U7XG4gICAgdGhpcy5hY3RpdmVTdGFnZUlkID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZVN0YWdlRGF0YSA9IHt9O1xuICB9XG5cbiAgb25BY3Rpb25EaWFsb2dDbG9zZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93QWN0aW9uRGlhbG9nTG9jYWwgPSBmYWxzZTtcbiAgICB0aGlzLmFjdGl2ZUFjdGlvbklkID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZUFjdGlvbkRhdGEgPSBudWxsO1xuICB9XG5cbiAgLy8gQWRkIHRoaXMgbWV0aG9kIHRvIGhhbmRsZSBkaWFsb2cgY2xvc3VyZVxuICBvbkVzY2FsYXRpb25EaWFsb2dDbG9zZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93RXNjYWxhdGlvbkRpYWxvZ0xvY2FsID0gZmFsc2U7XG4gICAgdGhpcy5hY3RpdmVTdGFnZUlkID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZUVzY2FsYXRpb25UeXBlLnNldChudWxsKTtcbiAgICB0aGlzLmFjdGl2ZVN0YWdlQ29kZS5zZXQobnVsbCk7XG4gICAgdGhpcy5hY3RpdmVTdGFnZURhdGEgPSB7fTtcbiAgfVxuXG4gIC8vIEFkZCB0aGlzIG1ldGhvZCB0byBoYW5kbGUgc2F2aW5nIHN0YWdlIGRhdGFcbiAgb25TdGFnZURpYWxvZ1NhdmVkKHN0YWdlRGF0YTogUGFydGlhbDxXb3JrZmxvd1N0YWdlPik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2ZVN0YWdlSWQpIHtcbiAgICAgIC8vIEVkaXRpbmcgYW4gZXhpc3Rpbmcgc3RhZ2VcbiAgICAgIGNvbnN0IG5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQodGhpcy5hY3RpdmVTdGFnZUlkKTtcbiAgICAgIGlmIChub2RlSW5mbykge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIHN0YWdlIGRhdGFcbiAgICAgICAgbm9kZUluZm8ubm9kZS5zdGFnZURhdGEgPSB7XG4gICAgICAgICAgLi4ubm9kZUluZm8ubm9kZS5zdGFnZURhdGEsXG4gICAgICAgICAgLi4uc3RhZ2VEYXRhLFxuICAgICAgICB9O1xuICAgICAgICBjb25zb2xlLmxvZygnVXBkYXRlZCBzdGFnZSBkYXRhOicsIG5vZGVJbmZvLm5vZGUuc3RhZ2VEYXRhKTtcblxuICAgICAgICAvLyBFbWl0IGV2ZW50IGZvciBwYXJlbnQgY29tcG9uZW50IHRvIGtub3cgYWJvdXQgdGhlIHVwZGF0ZVxuICAgICAgICB0aGlzLnN0YWdlUHJvcGVydGllc1VwZGF0ZWQuZW1pdCh7XG4gICAgICAgICAgbm9kZUlkOiB0aGlzLmFjdGl2ZVN0YWdlSWQsXG4gICAgICAgICAgc3RhZ2VEYXRhOiBub2RlSW5mby5ub2RlLnN0YWdlRGF0YSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xvc2UgdGhlIGRpYWxvZ1xuICAgIHRoaXMub25TdGFnZURpYWxvZ0Nsb3NlZCgpO1xuICB9XG5cbiAgb25BY3Rpb25EaWFsb2dTYXZlZChhY3Rpb25EYXRhOiBDb25uZWN0aW9uKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZlQWN0aW9uSWQpIHtcbiAgICAgIC8vIEVkaXRpbmcgYW4gZXhpc3Rpbmcgc3RhZ2VcbiAgICAgIC8vIGxldCBjb25uZWN0aW9uSW5mbyA9IHRoaXMuc3RhdGUuZmluZEFjdGlvbkJ5SWQodGhpcy5hY3RpdmVBY3Rpb25JZCk7XG4gICAgICB0aGlzLnN0YXRlLmNvbm5lY3Rpb25zID0gdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5tYXAoKGNvbm5lY3Rpb24sIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChjb25uZWN0aW9uLmlkID09PSB0aGlzLmFjdGl2ZUFjdGlvbklkKSB7XG4gICAgICAgICAgY29ubmVjdGlvbi5sYWJlbCA9IGFjdGlvbkRhdGEubGFiZWw7XG4gICAgICAgICAgY29ubmVjdGlvbi5hY3Rpb24gPSBhY3Rpb25EYXRhLmFjdGlvbjtcbiAgICAgICAgICBjb25uZWN0aW9uLnRhcmdldFN0YXR1cyA9IGFjdGlvbkRhdGEudGFyZ2V0U3RhdHVzO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdVcGRhdGVkIGFjdGlvbiBkYXRhOicsIGNvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25uZWN0aW9uO1xuICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyBDbG9zZSB0aGUgZGlhbG9nXG4gICAgdGhpcy5vbkFjdGlvbkRpYWxvZ0Nsb3NlZCgpO1xuICB9XG5cbiAgdXBkYXRlQ2FudmFzU2l6ZSgpOiB2b2lkIHtcbiAgICBjb25zdCByZXF1aXJlZEhlaWdodCA9XG4gICAgICAodGhpcy5zdGF0ZS5zd2ltbGFuZXMubGVuZ3RoICsgMSkgKiB0aGlzLnN3aW1sYW5lSGVpZ2h0O1xuICAgIHRoaXMuY2FudmFzSGVpZ2h0ID0gTWF0aC5tYXgoMjAwMCwgcmVxdWlyZWRIZWlnaHQpOyAvLyBFbnN1cmUgd2UgaGF2ZSBhdCBsZWFzdCBvdXIgZGVmYXVsdCBoZWlnaHRcblxuICAgIC8vIFVwZGF0ZSBhbGwgdGhlIHN3aW1sYW5lIGNsaXAgcGF0aHMgd2hlbiBzaXplIGNoYW5nZXNcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc3RhdGUuc3dpbWxhbmVzLmZvckVhY2goKHN3aW1sYW5lLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBjbGlwUGF0aElkID0gYHN3aW1sYW5lLWNsaXAtJHtpbmRleH1gO1xuICAgICAgICBjb25zdCBjbGlwUGF0aEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjbGlwUGF0aElkKTtcbiAgICAgICAgaWYgKGNsaXBQYXRoRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IHJlY3RFbGVtZW50ID0gY2xpcFBhdGhFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKTtcbiAgICAgICAgICBpZiAocmVjdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJlY3RFbGVtZW50LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCB0aGlzLmNhbnZhc1dpZHRoLnRvU3RyaW5nKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICAvLyBIZWxwZXIgbWV0aG9kIHRvIGdldCB0aGUgbW91c2UgcG9zaXRpb24gcmVsYXRpdmUgdG8gdGhlIFNWRyBjYW52YXNcbiAgcHJpdmF0ZSBnZXRNb3VzZVBvc2l0aW9uKGV2ZW50OiBNb3VzZUV2ZW50KTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgICAvLyBVc2UgY2xpZW50WC9ZIGFuZCBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKSBmb3IgY3Jvc3MtYnJvd3NlciBjb21wYXRpYmlsaXR5XG4gICAgY29uc3QgcmVjdCA9IHRoaXMuY2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQsXG4gICAgICB5OiBldmVudC5jbGllbnRZIC0gcmVjdC50b3AsXG4gICAgfTtcbiAgfVxuXG4gIC8vIEhlbHBlciBtZXRob2QgdG8gZ2V0IHRoZSBtb3VzZSBwb3NpdGlvbiBmb3Igdmlld3BvcnQtYmFzZWQgcG9wdXBzXG4gIC8vIFRoaXMgYWNjb3VudHMgZm9yIGNhbnZhcyBzY3JvbGwgcG9zaXRpb25cbiAgcHJpdmF0ZSBnZXRWaWV3cG9ydFBvc2l0aW9uKGNhbnZhc1g6IG51bWJlciwgY2FudmFzWTogbnVtYmVyKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgICBjb25zdCBwYXJlbnRFbGVtZW50ID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgIGNvbnN0IHNjcm9sbExlZnQgPSBwYXJlbnRFbGVtZW50Py5zY3JvbGxMZWZ0IHx8IDA7XG4gICAgY29uc3Qgc2Nyb2xsVG9wID0gcGFyZW50RWxlbWVudD8uc2Nyb2xsVG9wIHx8IDA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogY2FudmFzWCAtIHNjcm9sbExlZnQsXG4gICAgICB5OiBjYW52YXNZIC0gc2Nyb2xsVG9wLFxuICAgIH07XG4gIH1cblxuICBzaG93Q29ubmVjdGlvblBvaW50cyhub2RlSWQ6IHN0cmluZywgc3dpbWxhbmVJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy52aXNpYmxlQ29ubmVjdGlvblBvaW50c05vZGVJZCA9IG5vZGVJZDtcbiAgfVxuXG4gIGlzTW91c2VPdmVyTm9kZShcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBub2RlOiBXRk5vZGUsXG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICBjb25zdCBub2RlQm91bmRzID0gdGhpcy5nZXROb2RlQm91bmRzV2l0aFBhZGRpbmcobm9kZSwgc3dpbWxhbmVJbmRleCk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgcG9zaXRpb24ueCA+PSBub2RlQm91bmRzLnggJiZcbiAgICAgIHBvc2l0aW9uLnggPD0gbm9kZUJvdW5kcy54ICsgbm9kZUJvdW5kcy53aWR0aCAmJlxuICAgICAgcG9zaXRpb24ueSA+PSBub2RlQm91bmRzLnkgJiZcbiAgICAgIHBvc2l0aW9uLnkgPD0gbm9kZUJvdW5kcy55ICsgbm9kZUJvdW5kcy5oZWlnaHRcbiAgICApO1xuICB9XG5cbiAgLy8gaGVscGVyIG1ldGhvZCB0byBjYWxjdWxhdGUgbm9kZSBib3VuZHMgd2l0aCBwYWRkaW5nXG4gIGdldE5vZGVCb3VuZHNXaXRoUGFkZGluZyhcbiAgICBub2RlOiBXRk5vZGUsXG4gICAgc3dpbWxhbmVJbmRleDogbnVtYmVyXG4gICk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0ge1xuICAgIGNvbnN0IHBhZGRpbmcgPSAxMDsgLy8gQWRkIDEwcHggcGFkZGluZyBhcm91bmQgbm9kZXMgZm9yIGVhc2llciBob3ZlciBkZXRlY3Rpb25cblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgYWJzb2x1dGUgWSBwb3NpdGlvbiBpbmNsdWRpbmcgc3dpbWxhbmUgb2Zmc2V0XG4gICAgY29uc3QgYWJzb2x1dGVZID0gbm9kZS55ICsgc3dpbWxhbmVJbmRleCAqIDI2MztcblxuICAgIHJldHVybiB7XG4gICAgICB4OiBub2RlLnggLSBwYWRkaW5nLFxuICAgICAgeTogYWJzb2x1dGVZIC0gcGFkZGluZyxcbiAgICAgIHdpZHRoOiBub2RlLndpZHRoICsgcGFkZGluZyAqIDIsXG4gICAgICBoZWlnaHQ6IG5vZGUuaGVpZ2h0ICsgcGFkZGluZyAqIDIsXG4gICAgfTtcbiAgfVxuXG4gIGhpZGVDb25uZWN0aW9uUG9pbnRzKG5vZGVJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgdGhpcy52aXNpYmxlQ29ubmVjdGlvblBvaW50c05vZGVJZCA9PT0gbm9kZUlkICYmXG4gICAgICAhdGhpcy5zdGF0ZS5pc0Nvbm5lY3Rpb25EcmFnZ2luZygpXG4gICAgKSB7XG4gICAgICB0aGlzLnZpc2libGVDb25uZWN0aW9uUG9pbnRzTm9kZUlkID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBpc0Nvbm5lY3Rpb25Qb2ludFZpc2libGUobm9kZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52aXNpYmxlQ29ubmVjdGlvblBvaW50c05vZGVJZCA9PT0gbm9kZUlkO1xuICB9XG5cbiAgc3RhcnRDb25uZWN0aW9uRHJhZyhcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBwb2ludDogQ29ubmVjdGlvblBvaW50LFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlclxuICApOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBleGl0IHBvaW50IG5vZGVcbiAgICBjb25zdCBub2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKHBvaW50Lm5vZGVJZCk7XG4gICAgaWYgKFxuICAgICAgbm9kZUluZm8gJiZcbiAgICAgIG5vZGVJbmZvLm5vZGUudHlwZSA9PT0gJ3N0YWdlJyAmJlxuICAgICAgbm9kZUluZm8ubm9kZS5zdGFnZURhdGE/LklzRXhpdFBvaW50XG4gICAgKSB7XG4gICAgICAvLyBEb24ndCBhbGxvdyBjb25uZWN0aW9ucyBmcm9tIGV4aXQgcG9pbnRzXG4gICAgICBjb25zb2xlLmxvZygnQ2Fubm90IGNyZWF0ZSBjb25uZWN0aW9ucyBmcm9tIGV4aXQgcG9pbnRzJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuICAgIHRoaXMuc3RhdGUuc3RhcnRDb25uZWN0aW9uRHJhZyhcbiAgICAgIHBvaW50LFxuICAgICAgc3dpbWxhbmVJbmRleCxcbiAgICAgIHBvc2l0aW9uLngsXG4gICAgICBwb3NpdGlvbi55XG4gICAgKTtcblxuICAgIC8vIEFkZCBtb3VzZSBtb3ZlIGFuZCBtb3VzZSB1cCBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIGRvY3VtZW50XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZVVwKTtcbiAgfVxuXG4gIGhpZ2hsaWdodFBvdGVudGlhbFRhcmdldHMoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSkgcmV0dXJuO1xuXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuICAgIGNvbnN0IHRhcmdldFBvaW50SW5mbyA9IHRoaXMuZmluZENvbm5lY3Rpb25Qb2ludEF0UG9zaXRpb24oXG4gICAgICBwb3NpdGlvbi54LFxuICAgICAgcG9zaXRpb24ueVxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICB0YXJnZXRQb2ludEluZm8gJiZcbiAgICAgIHRhcmdldFBvaW50SW5mby5wb2ludC5pZCAhPT0gdGhpcy5wb3RlbnRpYWxUYXJnZXRQb2ludElkXG4gICAgKSB7XG4gICAgICAvLyBXZSBoYXZlIGEgbmV3IHRhcmdldCBwb2ludFxuICAgICAgdGhpcy5wb3RlbnRpYWxUYXJnZXRQb2ludElkID0gdGFyZ2V0UG9pbnRJbmZvLnBvaW50LmlkO1xuICAgIH0gZWxzZSBpZiAoIXRhcmdldFBvaW50SW5mbyAmJiB0aGlzLnBvdGVudGlhbFRhcmdldFBvaW50SWQpIHtcbiAgICAgIC8vIFdlJ3JlIG5vIGxvbmdlciBvdmVyIGEgdGFyZ2V0IHBvaW50XG4gICAgICB0aGlzLnBvdGVudGlhbFRhcmdldFBvaW50SWQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvLyBOb2RlIGRyYWcgbG9naWNcbiAgLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIENhbGxlZCBmcm9tIHRoZSB0ZW1wbGF0ZSB3aGVuIHRoZSB1c2VyIHByZXNzZXMgdGhlIG1vdXNlIGJ1dHRvbiBvbiBhIG5vZGUuXG4gICAqIFN0YXJ0cyB0aGUgZHJhZyBpbnRlcmFjdGlvbiBhbmQgcmVnaXN0ZXJzIGRvY3VtZW50LWxldmVsIGxpc3RlbmVycyBzbyB0aGVcbiAgICogZHJhZyBjb250aW51ZXMgZXZlbiB3aGVuIHRoZSBjdXJzb3IgbGVhdmVzIHRoZSBTVkcgY2FudmFzLlxuICAgKi9cbiAgb25Ob2RlTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50LCBub2RlOiBOb2RlLCBzd2ltbGFuZUluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBEbyBub3QgaW50ZXJmZXJlIHdpdGggY29ubmVjdGlvbiBkcmFnZ2luZyBvciBvcGVuIHBvcHVwc1xuICAgIGlmIChcbiAgICAgIHRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSB8fFxuICAgICAgdGhpcy5wb3B1cFZpc2libGUgfHxcbiAgICAgIHRoaXMuc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cCB8fFxuICAgICAgdGhpcy5zaG93U3ViZmxvd1BvcHVwXG4gICAgKSByZXR1cm47XG5cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgLy8gUHJldmVudCBvbkNhbnZhc0NsaWNrIGZyb20gZmlyaW5nXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICAvLyBUZW1wbGF0ZSBmb3JtdWxhOiBhYnNvbHV0ZVNWR1kgPSBub2RlLnkgKyBzd2ltbGFuZS5vcmRlciAqIDI2M1xuICAgIGNvbnN0IGFic29sdXRlTm9kZVkgPSBub2RlLnkgKyBzd2ltbGFuZUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcblxuICAgIHRoaXMuaXNEcmFnZ2luZ05vZGUgPSB0cnVlO1xuICAgIHRoaXMuZHJhZ2dpbmdOb2RlID0gbm9kZTtcbiAgICB0aGlzLmRyYWdnaW5nTm9kZVN3aW1sYW5lSW5kZXggPSBzd2ltbGFuZUluZGV4O1xuICAgIC8vIFN0b3JlIHRoZSBvZmZzZXQgZnJvbSB0aGUgbm9kZSdzIHRvcC1sZWZ0IHNvIHRoZSBub2RlIGRvZXNuJ3QganVtcFxuICAgIHRoaXMuZHJhZ09mZnNldFggPSBwb3NpdGlvbi54IC0gbm9kZS54O1xuICAgIHRoaXMuZHJhZ09mZnNldFkgPSBwb3NpdGlvbi55IC0gYWJzb2x1dGVOb2RlWTtcblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25Ob2RlRHJhZ01vdmUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTm9kZURyYWdFbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFycm93IGZ1bmN0aW9uIChwcmVzZXJ2ZXMgYHRoaXNgKSDigJQgcnVucyBvbiBldmVyeSBtb3VzZW1vdmUgd2hpbGUgZHJhZ2dpbmdcbiAgICogYSBub2RlLiAgVXBkYXRlcyBub2RlLnggLyBub2RlLnkgaW4tcGxhY2Ugc28gQW5ndWxhcidzIGNoYW5nZSBkZXRlY3Rpb25cbiAgICogcGlja3MgaXQgdXAgYW5kIHJlZHJhd3MgdGhlIG5vZGUgYW5kIGFsbCBjb25uZWN0ZWQgcGF0aHMgYXV0b21hdGljYWxseS5cbiAgICovXG4gIG9uTm9kZURyYWdNb3ZlID0gKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmdOb2RlIHx8ICF0aGlzLmRyYWdnaW5nTm9kZSkgcmV0dXJuO1xuXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuXG4gICAgLy8gUmF3IGRlc2lyZWQgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIG5vZGUgdG9wLWxlZnRcbiAgICBjb25zdCByYXdBYnNvbHV0ZVggPSBwb3NpdGlvbi54IC0gdGhpcy5kcmFnT2Zmc2V0WDtcbiAgICBjb25zdCByYXdBYnNvbHV0ZVkgPSBwb3NpdGlvbi55IC0gdGhpcy5kcmFnT2Zmc2V0WTtcblxuICAgIC8vIERldGVybWluZSB3aGljaCBzd2ltbGFuZSB0aGUgbm9kZSBpcyBiZWluZyBkcmFnZ2VkIGludG8gIChieSBjdXJzb3IgWSlcbiAgICBsZXQgdGFyZ2V0U3dpbWxhbmVJbmRleCA9IE1hdGguZmxvb3IocG9zaXRpb24ueSAvIHRoaXMuc3dpbWxhbmVIZWlnaHQpO1xuICAgIHRhcmdldFN3aW1sYW5lSW5kZXggPSBNYXRoLm1heChcbiAgICAgIDAsXG4gICAgICBNYXRoLm1pbih0YXJnZXRTd2ltbGFuZUluZGV4LCB0aGlzLnN0YXRlLnN3aW1sYW5lcy5sZW5ndGggLSAxKVxuICAgICk7XG5cbiAgICBjb25zdCBzd2ltbGFuZVRvcFkgPSB0YXJnZXRTd2ltbGFuZUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcbiAgICBjb25zdCBzd2ltbGFuZUJvdHRvbVkgPSBzd2ltbGFuZVRvcFkgKyB0aGlzLnN3aW1sYW5lSGVpZ2h0O1xuICAgIGNvbnN0IHBhZGRpbmcgPSA1O1xuXG4gICAgLy8gWDoga2VlcCBub2RlIGZ1bGx5IG9uIGNhbnZhcyAobm8gbGVmdC9yaWdodCBib3VuZGFyeSBuZWVkZWQgZm9yIHN3aW1sYW5lcylcbiAgICBjb25zdCBuZXdBYnNvbHV0ZVggPSBNYXRoLm1heChwYWRkaW5nLCByYXdBYnNvbHV0ZVgpO1xuXG4gICAgLy8gWTogY2xhbXAgc28gdGhlIG5vZGUgc3RheXMgaW5zaWRlIHRoZSB0YXJnZXRlZCBzd2ltbGFuZVxuICAgIGxldCBuZXdBYnNvbHV0ZVkgPSByYXdBYnNvbHV0ZVk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZHJhZ2dpbmdOb2RlO1xuICAgIGlmIChuZXdBYnNvbHV0ZVkgPCBzd2ltbGFuZVRvcFkgKyBwYWRkaW5nKSB7XG4gICAgICBuZXdBYnNvbHV0ZVkgPSBzd2ltbGFuZVRvcFkgKyBwYWRkaW5nO1xuICAgIH0gZWxzZSBpZiAobmV3QWJzb2x1dGVZICsgbm9kZS5oZWlnaHQgPiBzd2ltbGFuZUJvdHRvbVkgLSBwYWRkaW5nKSB7XG4gICAgICBuZXdBYnNvbHV0ZVkgPSBzd2ltbGFuZUJvdHRvbVkgLSBub2RlLmhlaWdodCAtIHBhZGRpbmc7XG4gICAgfVxuXG4gICAgLy8gQ29udmVydCBhYnNvbHV0ZSBZIHRvIHN3aW1sYW5lLXJlbGF0aXZlIFkgZm9yIHN0b3JhZ2VcbiAgICBjb25zdCBuZXdSZWxhdGl2ZVkgPSBuZXdBYnNvbHV0ZVkgLSB0YXJnZXRTd2ltbGFuZUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcblxuICAgIC8vIExpdmUgcHJldmlldzogdXBkYXRlIHBvc2l0aW9uIGRpcmVjdGx5LlxuICAgIC8vIFRlbXBsYXRlIGZvcm11bGE6IGFic29sdXRlU1ZHWSA9IG5vZGUueSArIHN3aW1sYW5lLm9yZGVyICogMjYzXG4gICAgLy8gPT4gbm9kZS55ID0gYWJzb2x1dGVZIC0gc3dpbWxhbmUub3JkZXIgKiAyNjMgIChzd2ltbGFuZS1yZWxhdGl2ZSlcbiAgICAvLyBUaGUgbm9kZSBpcyBTVElMTCBpbiB0aGUgc291cmNlIHN3aW1sYW5lJ3MgYXJyYXkgZHVyaW5nIHByZXZpZXcsXG4gICAgLy8gc28gc3dpbWxhbmUub3JkZXIgPSBkcmFnZ2luZ05vZGVTd2ltbGFuZUluZGV4LlxuICAgIG5vZGUueCA9IG5ld0Fic29sdXRlWDtcbiAgICBub2RlLnkgPSBuZXdBYnNvbHV0ZVkgLSB0aGlzLmRyYWdnaW5nTm9kZVN3aW1sYW5lSW5kZXggKiB0aGlzLnN3aW1sYW5lSGVpZ2h0O1xuXG4gICAgLy8gU3RvcmUgY29tcHV0ZWQgdmFsdWVzIGZvciBvbk5vZGVEcmFnRW5kXG4gICAgdGhpcy5fcGVuZGluZ1RhcmdldFN3aW1sYW5lSW5kZXggPSB0YXJnZXRTd2ltbGFuZUluZGV4O1xuICAgIHRoaXMuX3BlbmRpbmdBYnNvbHV0ZVkgPSBuZXdBYnNvbHV0ZVk7XG4gIH07XG5cbiAgLyoqIFNjcmF0Y2ggZmllbGRzIHVzZWQgdG8gcGFzcyBjb21wdXRlZCB2YWx1ZXMgZnJvbSBtb3ZlIOKGkiBlbmQgaGFuZGxlcnMuICovXG4gIHByaXZhdGUgX3BlbmRpbmdUYXJnZXRTd2ltbGFuZUluZGV4ID0gLTE7XG4gIHByaXZhdGUgX3BlbmRpbmdBYnNvbHV0ZVkgPSAwO1xuXG4gIC8qKlxuICAgKiBBcnJvdyBmdW5jdGlvbiAocHJlc2VydmVzIGB0aGlzYCkg4oCUIGZpcmVzIG9uIG1vdXNldXAgYWZ0ZXIgYSBub2RlIGRyYWcuXG4gICAqIEZpbmFsaXNlcyB0aGUgbm9kZSBwb3NpdGlvbiBhbmQgcGVyZm9ybXMgc3dpbWxhbmUgbWlncmF0aW9uIGlmIG5lY2Vzc2FyeS5cbiAgICovXG4gIG9uTm9kZURyYWdFbmQgPSAoX2V2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCA9PiB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk5vZGVEcmFnTW92ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Ob2RlRHJhZ0VuZCk7XG5cbiAgICBpZiAoIXRoaXMuaXNEcmFnZ2luZ05vZGUgfHwgIXRoaXMuZHJhZ2dpbmdOb2RlKSB7XG4gICAgICB0aGlzLmlzRHJhZ2dpbmdOb2RlID0gZmFsc2U7XG4gICAgICB0aGlzLmRyYWdnaW5nTm9kZSA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZHJhZ2dpbmdOb2RlO1xuICAgIGNvbnN0IGZyb21JbmRleCA9IHRoaXMuZHJhZ2dpbmdOb2RlU3dpbWxhbmVJbmRleDtcbiAgICBjb25zdCB0b0luZGV4ID0gdGhpcy5fcGVuZGluZ1RhcmdldFN3aW1sYW5lSW5kZXggIT09IC0xXG4gICAgICA/IHRoaXMuX3BlbmRpbmdUYXJnZXRTd2ltbGFuZUluZGV4XG4gICAgICA6IGZyb21JbmRleDtcbiAgICBjb25zdCBhYnNvbHV0ZVkgPSB0aGlzLl9wZW5kaW5nQWJzb2x1dGVZO1xuXG4gICAgaWYgKGZyb21JbmRleCAhPT0gdG9JbmRleCkge1xuICAgICAgLy8gQ3Jvc3Mtc3dpbWxhbmUgZHJvcDogc3RhdGUgaGVscGVyIG1vdmVzIG5vZGUgYmV0d2VlbiBhcnJheXMsXG4gICAgICAvLyB1cGRhdGVzIGNvbm5lY3Rpb25zLCBhbmQgc3luY3MgdGFncy4gSXQgYWxzbyBzZXRzIG5vZGUueSBjb3JyZWN0bHkuXG4gICAgICB0aGlzLnN0YXRlLm1vdmVOb2RlVG9Td2ltbGFuZShub2RlLmlkLCBmcm9tSW5kZXgsIHRvSW5kZXgsIG5vZGUueCwgYWJzb2x1dGVZKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2FtZSBzd2ltbGFuZTogbm9kZS55ID0gYWJzb2x1dGVZIC0gc3dpbWxhbmUub3JkZXIgKiAyNjMgKHN3aW1sYW5lLXJlbGF0aXZlKVxuICAgICAgbm9kZS55ID0gYWJzb2x1dGVZIC0gZnJvbUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBkcmFnIHN0YXRlXG4gICAgdGhpcy5pc0RyYWdnaW5nTm9kZSA9IGZhbHNlO1xuICAgIHRoaXMuZHJhZ2dpbmdOb2RlID0gbnVsbDtcbiAgICB0aGlzLmRyYWdnaW5nTm9kZVN3aW1sYW5lSW5kZXggPSAtMTtcbiAgICB0aGlzLmRyYWdPZmZzZXRYID0gMDtcbiAgICB0aGlzLmRyYWdPZmZzZXRZID0gMDtcbiAgICB0aGlzLl9wZW5kaW5nVGFyZ2V0U3dpbWxhbmVJbmRleCA9IC0xO1xuICAgIHRoaXMuX3BlbmRpbmdBYnNvbHV0ZVkgPSAwO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgQ1NTIGN1cnNvciB2YWx1ZSBmb3IgdGhlIG5vZGUgcmVuZGVyaW5nLlxuICAgKiBTaG93cyAnZ3JhYmJpbmcnIHdoaWxlIHRoZSBub2RlIGlzIGJlaW5nIGRyYWdnZWQsICdncmFiJyBvdGhlcndpc2UuXG4gICAqL1xuICBnZXRDdXJzb3JGb3JOb2RlKG5vZGVJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pc0RyYWdnaW5nTm9kZSAmJiB0aGlzLmRyYWdnaW5nTm9kZT8uaWQgPT09IG5vZGVJZCA/ICdncmFiYmluZycgOiAnZ3JhYic7XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgLy8gQ29ubmVjdGlvbiBkcmFnIGxvZ2ljIChleGlzdGluZylcbiAgLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLy8gVXNlIGFycm93IGZ1bmN0aW9ucyB0byBwcmVzZXJ2ZSAndGhpcycgY29udGV4dFxuICBvbk1vdXNlTW92ZSA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRNb3VzZVBvc2l0aW9uKGV2ZW50KTtcbiAgICB0aGlzLnVwZGF0ZUNvbm5lY3Rpb25EcmFnKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpO1xuICAgIHRoaXMuaGlnaGxpZ2h0UG90ZW50aWFsVGFyZ2V0cyhldmVudCk7XG4gIH07XG5cbiAgdXBkYXRlQ29ubmVjdGlvbkRyYWcoY3VycmVudFg6IG51bWJlciwgY3VycmVudFk6IG51bWJlcikge1xuICAgIGlmICh0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuc291cmNlUG9pbnQpIHtcbiAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdDb25uZWN0aW9uRGF0YS5jdXJyZW50WCA9IGN1cnJlbnRYO1xuICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLmN1cnJlbnRZID0gY3VycmVudFk7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSB3aGljaCBzd2ltbGFuZSB0aGUgY3Vyc29yIGlzIG92ZXJcbiAgICAgIGNvbnN0IHN3aW1sYW5lSW5kZXggPSBNYXRoLmZsb29yKGN1cnJlbnRZIC8gdGhpcy5zd2ltbGFuZUhlaWdodCk7XG4gICAgICBpZiAoc3dpbWxhbmVJbmRleCA+PSAwICYmIHN3aW1sYW5lSW5kZXggPCB0aGlzLnN0YXRlLnN3aW1sYW5lcy5sZW5ndGgpIHtcbiAgICAgICAgLy8gRW5zdXJlIHRoZSB0YXJnZXQgc3dpbWxhbmUgaXMgZnVsbHkgdmlzaWJsZVxuICAgICAgICB0aGlzLmVuc3VyZVN3aW1sYW5lSW5WaWV3KHN3aW1sYW5lSW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uTW91c2VVcCA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25Nb3VzZU1vdmUpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcCk7XG5cbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuZ2V0TW91c2VQb3NpdGlvbihldmVudCk7XG4gICAgY29uc29sZS5sb2coJ01vdXNlIHVwIGF0IHBvc2l0aW9uOicsIHBvc2l0aW9uKTtcbiAgICBjb25zb2xlLmxvZygnSXMgY29ubmVjdGlvbiBkcmFnZ2luZzonLCB0aGlzLnN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpO1xuXG4gICAgLy8gT25seSBwcm9jZWVkIGlmIHdlIGFyZSBkcmFnZ2luZyBhIGNvbm5lY3Rpb25cbiAgICBpZiAoIXRoaXMuc3RhdGUuaXNDb25uZWN0aW9uRHJhZ2dpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGRyb3BwaW5nIG9udG8gYSBjb25uZWN0aW9uIHBvaW50XG4gICAgY29uc3QgdGFyZ2V0UG9pbnRJbmZvID0gdGhpcy5maW5kQ29ubmVjdGlvblBvaW50QXRQb3NpdGlvbihcbiAgICAgIHBvc2l0aW9uLngsXG4gICAgICBwb3NpdGlvbi55XG4gICAgKTtcblxuICAgIGlmICh0YXJnZXRQb2ludEluZm8pIHtcbiAgICAgIC8vIFdlIGZvdW5kIGEgdGFyZ2V0IGNvbm5lY3Rpb24gcG9pbnRcbiAgICAgIGNvbnNvbGUubG9nKCdGb3VuZCB0YXJnZXQgY29ubmVjdGlvbiBwb2ludDonLCB0YXJnZXRQb2ludEluZm8pO1xuXG4gICAgICAvLyBHZXQgdGhlIHNvdXJjZSBwb2ludCBhbmQgc3dpbWxhbmUgaW5kZXhcbiAgICAgIGNvbnN0IHNvdXJjZVBvaW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLnNvdXJjZVBvaW50O1xuICAgICAgY29uc3Qgc291cmNlU3dpbWxhbmVJbmRleCA9XG4gICAgICAgIHRoaXMuc3RhdGUuZHJhZ2dpbmdDb25uZWN0aW9uRGF0YS5zb3VyY2VTd2ltbGFuZUluZGV4O1xuXG4gICAgICBpZiAoc291cmNlUG9pbnQgJiYgc291cmNlU3dpbWxhbmVJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFByZXZlbnQgY29ubmVjdGluZyBhIG5vZGUgdG8gaXRzZWxmXG4gICAgICAgIGlmIChzb3VyY2VQb2ludC5ub2RlSWQgIT09IHRhcmdldFBvaW50SW5mby5ub2RlSWQpIHtcbiAgICAgICAgICAvLyBHZXQgc291cmNlIGFuZCB0YXJnZXQgbm9kZSB0eXBlcyB0byBjaGVjayBpZiBjb25uZWN0aW9uIGlzIGFsbG93ZWRcbiAgICAgICAgICBjb25zdCBzb3VyY2VOb2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKHNvdXJjZVBvaW50Lm5vZGVJZCk7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0Tm9kZUluZm8gPSB0aGlzLnN0YXRlLmZpbmROb2RlQnlJZChcbiAgICAgICAgICAgIHRhcmdldFBvaW50SW5mby5ub2RlSWRcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgc291cmNlTm9kZUluZm8gJiZcbiAgICAgICAgICAgIHRhcmdldE5vZGVJbmZvICYmXG4gICAgICAgICAgICB0aGlzLnN0YXRlLmNhbkNvbm5lY3QoXG4gICAgICAgICAgICAgIHNvdXJjZU5vZGVJbmZvLm5vZGUudHlwZSxcbiAgICAgICAgICAgICAgdGFyZ2V0Tm9kZUluZm8ubm9kZS50eXBlXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB7XG4gICAgICAgICAgICAgIGlkOiBgY29ubi0ke0RhdGUubm93KCl9LSR7TWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9YCxcbiAgICAgICAgICAgICAgc291cmNlTm9kZUlkOiBzb3VyY2VQb2ludC5ub2RlSWQsXG4gICAgICAgICAgICAgIHRhcmdldE5vZGVJZDogdGFyZ2V0UG9pbnRJbmZvLm5vZGVJZCxcbiAgICAgICAgICAgICAgc291cmNlUG9pbnRJZDogc291cmNlUG9pbnQuaWQsXG4gICAgICAgICAgICAgIHRhcmdldFBvaW50SWQ6IHRhcmdldFBvaW50SW5mby5wb2ludC5pZCxcbiAgICAgICAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleDogc291cmNlU3dpbWxhbmVJbmRleCxcbiAgICAgICAgICAgICAgdGFyZ2V0U3dpbWxhbmVJbmRleDogdGFyZ2V0UG9pbnRJbmZvLnN3aW1sYW5lSW5kZXgsXG4gICAgICAgICAgICAgIGxhYmVsOiAnJyxcbiAgICAgICAgICAgICAgYWN0aW9uOiBudWxsLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gQWRkIHRvIGNvbm5lY3Rpb25zIGFycmF5XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnQ3JlYXRlZCBkaXJlY3QgY29ubmVjdGlvbiBiZXR3ZWVuIG5vZGVzOicsIGNvbm5lY3Rpb24pO1xuXG4gICAgICAgICAgICAvLyBOb3RpZnkgYWJvdXQgY29ubmVjdGlvbiBjcmVhdGlvblxuICAgICAgICAgICAgdGhpcy5vbkNvbm5lY3Rpb25DcmVhdGVkKGNvbm5lY3Rpb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgJ0Nhbm5vdCBjb25uZWN0IHRoZXNlIG5vZGUgdHlwZXM6JyxcbiAgICAgICAgICAgICAgc291cmNlTm9kZUluZm8/Lm5vZGUudHlwZSxcbiAgICAgICAgICAgICAgJy0+JyxcbiAgICAgICAgICAgICAgdGFyZ2V0Tm9kZUluZm8/Lm5vZGUudHlwZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0Nhbm5vdCBjb25uZWN0IGEgbm9kZSB0byBpdHNlbGYnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBFbmQgdGhlIGNvbm5lY3Rpb24gZHJhZ1xuICAgICAgdGhpcy5zdGF0ZS5lbmRDb25uZWN0aW9uRHJhZygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRoZSBwb3NpdGlvbiBpcyB3aXRoaW4gYW55IHN3aW1sYW5lXG4gICAgY29uc3QgaXNJbnNpZGVTd2ltbGFuZSA9IHRoaXMuaXNQb3NpdGlvbkluc2lkZVN3aW1sYW5lKHBvc2l0aW9uLnkpO1xuICAgIGNvbnNvbGUubG9nKCdJcyBpbnNpZGUgc3dpbWxhbmU6JywgaXNJbnNpZGVTd2ltbGFuZSk7XG5cbiAgICAvLyBPbmx5IHNob3cgcG9wdXAgaWYgd2l0aGluIGEgc3dpbWxhbmVcbiAgICBpZiAoaXNJbnNpZGVTd2ltbGFuZSAmJiB0aGlzLnN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdTaG93aW5nIGNvbm5lY3Rpb24gcG9wdXAnKTtcbiAgICAgIHRoaXMuc2hvd0Nvbm5lY3Rpb25Qb3B1cChwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRW5kIHRoZSBjb25uZWN0aW9uIGRyYWcgaWYgb3V0c2lkZSBhIHN3aW1sYW5lXG4gICAgICBjb25zb2xlLmxvZygnRW5kaW5nIGNvbm5lY3Rpb24gZHJhZyB3aXRob3V0IHNob3dpbmcgcG9wdXAnKTtcbiAgICAgIHRoaXMuc3RhdGUuZW5kQ29ubmVjdGlvbkRyYWcoKTtcbiAgICB9XG4gIH07XG5cbiAgZmluZENvbm5lY3Rpb25Qb2ludEF0UG9zaXRpb24oXG4gICAgeDogbnVtYmVyLFxuICAgIHk6IG51bWJlcixcbiAgICB0b2xlcmFuY2U6IG51bWJlciA9IDEwXG4gICk6IHtcbiAgICBwb2ludDogQ29ubmVjdGlvblBvaW50O1xuICAgIG5vZGVJZDogc3RyaW5nO1xuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlcjtcbiAgfSB8IG51bGwge1xuICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgc3dpbWxhbmVzIGFuZCBub2RlcyB0byBmaW5kIGNvbm5lY3Rpb24gcG9pbnRzXG4gICAgZm9yIChcbiAgICAgIGxldCBzd2ltbGFuZUluZGV4ID0gMDtcbiAgICAgIHN3aW1sYW5lSW5kZXggPCB0aGlzLnN0YXRlLnN3aW1sYW5lcy5sZW5ndGg7XG4gICAgICBzd2ltbGFuZUluZGV4KytcbiAgICApIHtcbiAgICAgIGNvbnN0IHN3aW1sYW5lID0gdGhpcy5zdGF0ZS5zd2ltbGFuZXNbc3dpbWxhbmVJbmRleF07XG5cbiAgICAgIGlmICghc3dpbWxhbmUubm9kZXMpIGNvbnRpbnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygc3dpbWxhbmUubm9kZXMpIHtcbiAgICAgICAgaWYgKCFub2RlLmNvbm5lY3Rpb25Qb2ludHMpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIG5vZGUgKGluY2x1ZGluZyBzd2ltbGFuZSBvZmZzZXQpXG4gICAgICAgIGNvbnN0IGFic29sdXRlTm9kZVggPSBub2RlLng7XG4gICAgICAgIGNvbnN0IGFic29sdXRlTm9kZVkgPSBub2RlLnkgKyBzd2ltbGFuZUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcblxuICAgICAgICBmb3IgKGNvbnN0IHBvaW50IG9mIG5vZGUuY29ubmVjdGlvblBvaW50cykge1xuICAgICAgICAgIC8vIENhbGN1bGF0ZSBhYnNvbHV0ZSBwb3NpdGlvbiBvZiB0aGUgY29ubmVjdGlvbiBwb2ludFxuICAgICAgICAgIGNvbnN0IHBvaW50WCA9IGFic29sdXRlTm9kZVggKyBwb2ludC54O1xuICAgICAgICAgIGNvbnN0IHBvaW50WSA9IGFic29sdXRlTm9kZVkgKyBwb2ludC55O1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGdpdmVuIHBvc2l0aW9uIGlzIHdpdGhpbiB0b2xlcmFuY2Ugb2YgdGhpcyBwb2ludFxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIE1hdGguYWJzKHggLSBwb2ludFgpIDw9IHRvbGVyYW5jZSAmJlxuICAgICAgICAgICAgTWF0aC5hYnMoeSAtIHBvaW50WSkgPD0gdG9sZXJhbmNlXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBwb2ludDogcG9pbnQsXG4gICAgICAgICAgICAgIG5vZGVJZDogbm9kZS5pZCxcbiAgICAgICAgICAgICAgc3dpbWxhbmVJbmRleDogc3dpbWxhbmVJbmRleCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpc1Bvc2l0aW9uSW5zaWRlU3dpbWxhbmUoeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgLy8gQ2hlY2sgaWYgeSBwb3NpdGlvbiBpcyB3aXRoaW4gYW55IHN3aW1sYW5lXG4gICAgY29uc3Qgc3dpbWxhbmVDb3VudCA9IHRoaXMuc3RhdGUuc3dpbWxhbmVzLmxlbmd0aDtcbiAgICBpZiAoc3dpbWxhbmVDb3VudCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gRWFjaCBzd2ltbGFuZSBoYXMgYSBoZWlnaHQgb2YgMjYzcHhcbiAgICBjb25zdCB0b3RhbFN3aW1sYW5lSGVpZ2h0ID0gc3dpbWxhbmVDb3VudCAqIHRoaXMuc3dpbWxhbmVIZWlnaHQ7XG5cbiAgICAvLyBDaGVjayBpZiB5IGlzIHdpdGhpbiB0aGUgdG90YWwgaGVpZ2h0IG9mIGFsbCBzd2ltbGFuZXNcbiAgICByZXR1cm4geSA+PSAwICYmIHkgPCB0b3RhbFN3aW1sYW5lSGVpZ2h0O1xuICB9XG5cbiAgc2hvd0Nvbm5lY3Rpb25Qb3B1cCh4OiBudW1iZXIsIHk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdTaG93aW5nIGNvbm5lY3Rpb24gcG9wdXAgYXQ6JywgeCwgeSk7XG5cbiAgICAvLyBDb252ZXJ0IGNhbnZhcyBjb29yZGluYXRlcyB0byB2aWV3cG9ydCBjb29yZGluYXRlcyBmb3IgcG9wdXAgcG9zaXRpb25pbmdcbiAgICBjb25zdCB2aWV3cG9ydFBvcyA9IHRoaXMuZ2V0Vmlld3BvcnRQb3NpdGlvbih4LCB5KTtcbiAgICB0aGlzLnBvcHVwWCA9IHZpZXdwb3J0UG9zLng7XG4gICAgdGhpcy5wb3B1cFkgPSB2aWV3cG9ydFBvcy55O1xuXG4gICAgLy8gR2V0IGFsbG93ZWQgbm9kZSB0eXBlcyBiYXNlZCBvbiB0aGUgc291cmNlIG5vZGUgdHlwZVxuICAgIHRoaXMuYWxsb3dlZE5vZGVUeXBlcyA9IHRoaXMuc3RhdGUuZ2V0QWxsb3dlZFRhcmdldE5vZGVUeXBlcygpO1xuICAgIGNvbnNvbGUubG9nKCdBbGxvd2VkIG5vZGUgdHlwZXM6JywgdGhpcy5hbGxvd2VkTm9kZVR5cGVzKTtcblxuICAgIC8vIE9ubHkgc2hvdyB0aGUgcG9wdXAgaWYgd2UgaGF2ZSBhbGxvd2VkIG5vZGUgdHlwZXNcbiAgICBpZiAodGhpcy5hbGxvd2VkTm9kZVR5cGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucG9wdXBWaXNpYmxlID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdQb3B1cCB2aXNpYmlsaXR5IHNldCB0byB0cnVlJyk7XG5cbiAgICAgIC8vIEZvcmNlIHRoZSBwb3B1cCB0byBiZSB2aXNpYmxlIGluIHRoZSBuZXh0IHRpY2tcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnSXMgcG9wdXAgdmlzaWJsZSBpbiBuZXh0IHRpY2s6JywgdGhpcy5wb3B1cFZpc2libGUpO1xuICAgICAgfSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGFsbG93ZWQgbm9kZSB0eXBlcywganVzdCBlbmQgdGhlIGRyYWdcbiAgICAgIGNvbnNvbGUubG9nKCdObyBhbGxvd2VkIG5vZGUgdHlwZXMsIGVuZGluZyBkcmFnJyk7XG4gICAgICB0aGlzLnN0YXRlLmVuZENvbm5lY3Rpb25EcmFnKCk7XG4gICAgfVxuICB9XG5cbiAgaGlkZUNvbm5lY3Rpb25Qb3B1cCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygnQ2FsbCB0byBoaWRlJyk7XG4gICAgdGhpcy5wb3B1cFZpc2libGUgPSBmYWxzZTtcbiAgICB0aGlzLnN0YXRlLmVuZENvbm5lY3Rpb25EcmFnKCk7XG4gIH1cblxuICAvLyBBZGQgdGhpcyBoYW5kbGVyIHRvIGNsb3NlIHRoZSBwb3B1cCB3aGVuIGNsaWNraW5nIG91dHNpZGVcbiAgLy8gQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICAvLyBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgLy8gICBpZiAodGhpcy5wb3B1cFZpc2libGUpIHtcbiAgLy8gICAgIGNvbnN0IHBvcHVwRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3ZlcmJlbi1wb3AtVXAnKTtcbiAgLy8gICAgIGlmIChwb3B1cEVsZW1lbnQgJiYgIXBvcHVwRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQgYXMgTm9kZSkpIHtcbiAgLy8gICAgICAgdGhpcy5oaWRlQ29ubmVjdGlvblBvcHVwKCk7XG4gIC8vICAgICB9XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgY3JlYXRlTm9kZUNvbm5lY3Rpb24obm9kZVR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHBhdGhEYXRhID0gdGhpcy5zdGF0ZS5nZXRDb25uZWN0aW9uUGF0aERhdGEoKTtcbiAgICBpZiAoIXBhdGhEYXRhKSB7XG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGlzIG5vZGUgdHlwZSBpcyBhbGxvd2VkIHRvIGJlIGNyZWF0ZWRcbiAgICBjb25zdCBhbGxvd2VkVHlwZXMgPSB0aGlzLnN0YXRlLmdldEFsbG93ZWRUYXJnZXROb2RlVHlwZXMoKTtcbiAgICBpZiAoIWFsbG93ZWRUeXBlcy5pbmNsdWRlcyhub2RlVHlwZSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBDYW5ub3QgY3JlYXRlIGNvbm5lY3Rpb24gdG8gJHtub2RlVHlwZX0gZnJvbSBjdXJyZW50IG5vZGUgdHlwZWBcbiAgICAgICk7XG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGVuZFgsIGVuZFksIHNvdXJjZVN3aW1sYW5lSW5kZXggfSA9IHBhdGhEYXRhO1xuXG4gICAgLy8gR2V0IHNvdXJjZSBub2RlIGluZm9cbiAgICBjb25zdCBzb3VyY2VQb2ludCA9IHRoaXMuc3RhdGUuZHJhZ2dpbmdDb25uZWN0aW9uRGF0YS5zb3VyY2VQb2ludDtcbiAgICBpZiAoIXNvdXJjZVBvaW50KSB7XG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VOb2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKHNvdXJjZVBvaW50Lm5vZGVJZCk7XG4gICAgaWYgKCFzb3VyY2VOb2RlSW5mbykge1xuICAgICAgdGhpcy5oaWRlQ29ubmVjdGlvblBvcHVwKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSWYgY29ubmVjdGluZyBmcm9tIGEgZGVjaXNpb24gdG8gYSBzdGFnZSwgc2hvdyBjb25kaXRpb24gcG9wdXAgZmlyc3RcbiAgICBpZiAoc291cmNlTm9kZUluZm8ubm9kZS50eXBlID09PSAnZGVjaXNpb24nICYmIG5vZGVUeXBlID09PSAnc3RhZ2UnKSB7XG4gICAgICAvLyBTdG9yZSBpbmZvcm1hdGlvbiBmb3IgbGF0ZXIgc3RhZ2UgY3JlYXRpb25cbiAgICAgIHRoaXMucGVuZGluZ0RlY2lzaW9uQ29ubmVjdGlvbiA9IHtcbiAgICAgICAgZGVjaXNpb25Ob2RlSWQ6IHNvdXJjZU5vZGVJbmZvLm5vZGUuaWQsXG4gICAgICAgIHN3aW1sYW5lSW5kZXg6IHNvdXJjZVN3aW1sYW5lSW5kZXgsXG4gICAgICAgIHg6IGVuZFgsXG4gICAgICAgIHk6IGVuZFksXG4gICAgICB9O1xuXG4gICAgICAvLyBDYWxjdWxhdGUgcG9wdXAgcG9zaXRpb24gLSBwb3NpdGlvbiBpdCBuZWFyIHRoZSBkZWNpc2lvbiBub2RlXG4gICAgICBjb25zdCBzd2ltbGFuZU9mZnNldFkgPSBzb3VyY2VTd2ltbGFuZUluZGV4ICogMjYzO1xuXG4gICAgICAvLyBDZW50ZXIgdGhlIHBvcHVwIG92ZXIgdGhlIGNvbm5lY3Rpb24gZW5kcG9pbnRcbiAgICAgIHRoaXMuZGVjaXNpb25Db25kaXRpb25Qb3B1cFggPSBlbmRYO1xuICAgICAgdGhpcy5kZWNpc2lvbkNvbmRpdGlvblBvcHVwWSA9IGVuZFkgLSAxNTA7IC8vIFBvc2l0aW9uIGFib3ZlIHRoZSBlbmRwb2ludFxuXG4gICAgICAvLyBTZXQgZGVjaXNpb24gbm9kZSBJRFxuICAgICAgdGhpcy5hY3RpdmVEZWNpc2lvbk5vZGVJZCA9IHNvdXJjZU5vZGVJbmZvLm5vZGUuaWQ7XG4gICAgICB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyA9IHRydWU7XG5cbiAgICAgIC8vIEVuZCB0aGUgY29ubmVjdGlvbiBkcmFnXG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzd2ltbGFuZUluZGV4ID0gTWF0aC5mbG9vcihlbmRZIC8gdGhpcy5zd2ltbGFuZUhlaWdodCk7XG4gICAgY29uc3Qgc3dpbWxhbmVUb3AgPSBzd2ltbGFuZUluZGV4ICogdGhpcy5zd2ltbGFuZUhlaWdodDtcbiAgICAvLyBDYWxjdWxhdGUgc3dpbWxhbmUtcmVsYXRpdmUgcG9zaXRpb25cbiAgICBjb25zdCBzd2ltbGFuZU9mZnNldFkgPSBzb3VyY2VTd2ltbGFuZUluZGV4ICogMjYzO1xuICAgIGxldCByZWxhdGl2ZVkgPSBlbmRZIC0gc3dpbWxhbmVPZmZzZXRZIC0gNTA7IC8vIEFkZCBoYWxmIG5vZGUgaGVpZ2h0IGZvciBiZXR0ZXIgYWxpZ25tZW50XG4gICAgY29uc3Qgc3dpbWxhbmVCb3R0b20gPSBzd2ltbGFuZVRvcCArIDI2MztcblxuICAgIC8vIENsYW1wIG5vZGVZIHNvIG5vZGUgc3RheXMgd2l0aGluIHN3aW1sYW5lXG5cbiAgICBjb25zb2xlLmxvZyhlbmRZLCBzd2ltbGFuZUluZGV4LCBzd2ltbGFuZU9mZnNldFksIHN3aW1sYW5lQm90dG9tKTtcblxuICAgIGlmIChlbmRZIC0gNTAgPCBzd2ltbGFuZVRvcCkge1xuICAgICAgY29uc29sZS5sb2coJ0xlc3MnKTtcbiAgICAgIHJlbGF0aXZlWSA9IHN3aW1sYW5lVG9wOyAvLyBOb2RlIHdvdWxkIG92ZXJmbG93IGFib3ZlLCBzbyBhbGlnbiB0byB0b3BcbiAgICB9IGVsc2UgaWYgKGVuZFkgKyA1MCA+IHN3aW1sYW5lQm90dG9tKSB7XG4gICAgICBjb25zb2xlLmxvZygnTW9yZScpO1xuICAgICAgcmVsYXRpdmVZID0gc3dpbWxhbmVCb3R0b20gLSAxMDA7IC8vIE5vZGUgd291bGQgb3ZlcmZsb3cgYmVsb3csIHNvIGFsaWduIHRvIGJvdHRvbVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBwcmVjb25kaXRpb25zIGJhc2VkIG9uIG5vZGUgdHlwZVxuICAgIGlmIChub2RlVHlwZSA9PT0gJ3N0YWdlJykge1xuICAgICAgLy8gQ3JlYXRlIHRoZSBzdGFnZSBkaXJlY3RseSB3aXRoIGRlZmF1bHQgcHJvcGVydGllc1xuICAgICAgY29uc3QgbmV3Tm9kZSA9IHRoaXMuc3RhdGUuYWRkTm9kZShcbiAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleCxcbiAgICAgICAgJ3N0YWdlJyxcbiAgICAgICAgZW5kWCxcbiAgICAgICAgcmVsYXRpdmVZLFxuICAgICAgICB7IE5hbWU6ICdOZXcgU3RhZ2UnIH0gLy8gQWRkIGRlZmF1bHQgcHJvcGVydGllc1xuICAgICAgKTtcblxuICAgICAgaWYgKFxuICAgICAgICBuZXdOb2RlICYmXG4gICAgICAgIG5ld05vZGUuY29ubmVjdGlvblBvaW50cyAmJlxuICAgICAgICBuZXdOb2RlLmNvbm5lY3Rpb25Qb2ludHMubGVuZ3RoID4gMCAmJlxuICAgICAgICBzb3VyY2VQb2ludFxuICAgICAgKSB7XG4gICAgICAgIC8vIEhhbmRsZSBjb25uZWN0aW9uIGNyZWF0aW9uXG4gICAgICAgIGNvbnN0IG9wcG9zaW5nVHlwZSA9IHtcbiAgICAgICAgICByaWdodDogJ2xlZnQnLFxuICAgICAgICAgIGxlZnQ6ICdyaWdodCcsXG4gICAgICAgICAgdG9wOiAnYm90dG9tJyxcbiAgICAgICAgICBib3R0b206ICd0b3AnLFxuICAgICAgICB9W3NvdXJjZVBvaW50LnR5cGVdIGFzICd0b3AnIHwgJ3JpZ2h0JyB8ICdib3R0b20nIHwgJ2xlZnQnO1xuXG4gICAgICAgIGNvbnN0IHRhcmdldFBvaW50ID0gbmV3Tm9kZS5jb25uZWN0aW9uUG9pbnRzLmZpbmQoXG4gICAgICAgICAgKHApID0+IHAudHlwZSA9PT0gb3Bwb3NpbmdUeXBlXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRhcmdldFBvaW50KSB7XG4gICAgICAgICAgLy8gQ3JlYXRlIHRoZSBjb25uZWN0aW9uXG4gICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuc3RhdGUuY3JlYXRlQ29ubmVjdGlvbihcbiAgICAgICAgICAgIG5ld05vZGUuaWQsXG4gICAgICAgICAgICB0YXJnZXRQb2ludC5pZCxcbiAgICAgICAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXhcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMub25Db25uZWN0aW9uQ3JlYXRlZChjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5oaWRlQ29ubmVjdGlvblBvcHVwKCk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmIChub2RlVHlwZSA9PT0gJ3N1YmZsb3cnKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ0NyZWF0aW5nIHN1YmZsb3cgZnJvbSBjb25uZWN0aW9uIGF0OicsXG4gICAgICAgIGVuZFgsXG4gICAgICAgIGVuZFksXG4gICAgICAgICdzd2ltbGFuZTonLFxuICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4XG4gICAgICApO1xuICAgICAgLy8gU2hvdyB3b3JrZmxvdyBzZWxlY3Rpb24gcG9wdXAgYW5kIHN0b3JlIGNvbm5lY3Rpb24gZGF0YSBmb3IgbGF0ZXIgdXNlXG4gICAgICB0aGlzLnNob3dTdWJmbG93U2VsZWN0aW9uUG9wdXAoZW5kWCwgZW5kWSwgc291cmNlU3dpbWxhbmVJbmRleCk7XG4gICAgICB0aGlzLmhpZGVDb25uZWN0aW9uUG9wdXAoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBGb3Igb3RoZXIgbm9kZXMgQ3JlYXRlIHRoZSBuZXcgbm9kZSBhdCB0aGUgZW5kIHBvc2l0aW9uIG9mIHRoZSBjb25uZWN0aW9uXG4gICAgY29uc3QgbmV3Tm9kZSA9IHRoaXMuc3RhdGUuYWRkTm9kZShcbiAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXgsXG4gICAgICBub2RlVHlwZSBhcyBUb29sVHlwZSxcbiAgICAgIGVuZFgsXG4gICAgICByZWxhdGl2ZVlcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgbmV3Tm9kZSAmJlxuICAgICAgbmV3Tm9kZS5jb25uZWN0aW9uUG9pbnRzICYmXG4gICAgICBuZXdOb2RlLmNvbm5lY3Rpb25Qb2ludHMubGVuZ3RoID4gMFxuICAgICkge1xuICAgICAgLy8gRmluZCB0aGUgbW9zdCBhcHByb3ByaWF0ZSBjb25uZWN0aW9uIHBvaW50IChjbG9zZXN0IHRvIHRoZSBzb3VyY2UpXG4gICAgICBpZiAoc291cmNlUG9pbnQpIHtcbiAgICAgICAgLy8gRm9yIHNpbXBsaWNpdHksIHVzZSB0aGUgZmlyc3QgY29ubmVjdGlvbiBwb2ludCBvZiBvcHBvc2luZyB0eXBlXG4gICAgICAgIC8vIEluIGEgcmVhbCBpbXBsZW1lbnRhdGlvbiwgeW91J2QgZmluZCB0aGUgY2xvc2VzdCBvciBtb3N0IGFwcHJvcHJpYXRlIHBvaW50XG4gICAgICAgIGxldCB0YXJnZXRQb2ludDtcblxuICAgICAgICAvLyBJZiBzb3VyY2UgaXMgb24gcmlnaHQsIHRhcmdldCBzaG91bGQgYmUgb24gbGVmdCwgZXRjLlxuICAgICAgICBjb25zdCBvcHBvc2luZ1R5cGUgPSB7XG4gICAgICAgICAgcmlnaHQ6ICdsZWZ0JyxcbiAgICAgICAgICBsZWZ0OiAncmlnaHQnLFxuICAgICAgICAgIHRvcDogJ2JvdHRvbScsXG4gICAgICAgICAgYm90dG9tOiAndG9wJyxcbiAgICAgICAgfVtzb3VyY2VQb2ludC50eXBlXSBhcyAndG9wJyB8ICdyaWdodCcgfCAnYm90dG9tJyB8ICdsZWZ0JztcblxuICAgICAgICB0YXJnZXRQb2ludCA9IG5ld05vZGUuY29ubmVjdGlvblBvaW50cy5maW5kKFxuICAgICAgICAgIChwKSA9PiBwLnR5cGUgPT09IG9wcG9zaW5nVHlwZVxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0YXJnZXRQb2ludCkge1xuICAgICAgICAgIC8vIENyZWF0ZSB0aGUgY29ubmVjdGlvblxuICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnN0YXRlLmNyZWF0ZUNvbm5lY3Rpb24oXG4gICAgICAgICAgICBuZXdOb2RlLmlkLFxuICAgICAgICAgICAgdGFyZ2V0UG9pbnQuaWQsXG4gICAgICAgICAgICBzb3VyY2VTd2ltbGFuZUluZGV4XG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ29ubmVjdGlvbkNyZWF0ZWQoY29ubmVjdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZU5vZGVJbmZvKSB7XG4gICAgICB0aGlzLnVwZGF0ZU5vZGVDb25uZWN0aW9ucyhzb3VyY2VOb2RlSW5mby5ub2RlKTtcbiAgICB9XG5cbiAgICAvLyBFbmQgdGhlIGNvbm5lY3Rpb24gZHJhZ1xuICAgIHRoaXMuaGlkZUNvbm5lY3Rpb25Qb3B1cCgpO1xuICB9XG5cbiAgLy8gTWV0aG9kIHRvIGhhbmRsZSBzYXZpbmcgdGhlIGNvbmRpdGlvblxuICBvbkRlY2lzaW9uQ29uZGl0aW9uU2F2ZWQoZXZlbnQ6IHtcbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBjb25kaXRpb246IHN0cmluZztcbiAgfSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wZW5kaW5nRGVjaXNpb25Db25uZWN0aW9uKSB7XG4gICAgICB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVjaXNpb25Ob2RlSWQsIHN3aW1sYW5lSW5kZXgsIHgsIHkgfSA9XG4gICAgICB0aGlzLnBlbmRpbmdEZWNpc2lvbkNvbm5lY3Rpb247XG5cbiAgICAvLyBDcmVhdGUgdGhlIHN0YWdlIGRpcmVjdGx5IHdpdGggZGVmYXVsdCBwcm9wZXJ0aWVzXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuc3RhdGUuYWRkTm9kZShcbiAgICAgIHN3aW1sYW5lSW5kZXgsXG4gICAgICAnc3RhZ2UnLFxuICAgICAgeCxcbiAgICAgIHksXG4gICAgICB7IE5hbWU6ICdOZXcgU3RhZ2UnIH0gLy8gQWRkIGRlZmF1bHQgcHJvcGVydGllc1xuICAgICk7XG5cbiAgICBpZiAobm9kZSkge1xuICAgICAgY29uc3QgZGVjaXNpb25Ob2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKGRlY2lzaW9uTm9kZUlkKTtcblxuICAgICAgaWYgKFxuICAgICAgICBkZWNpc2lvbk5vZGVJbmZvICYmXG4gICAgICAgIG5vZGUuY29ubmVjdGlvblBvaW50cyAmJlxuICAgICAgICBub2RlLmNvbm5lY3Rpb25Qb2ludHMubGVuZ3RoID4gMFxuICAgICAgKSB7XG4gICAgICAgIC8vIEZpbmQgYSBzdWl0YWJsZSBjb25uZWN0aW9uIHBvaW50IGZyb20gdGhlIGRlY2lzaW9uIG5vZGVcbiAgICAgICAgY29uc3QgZGVjaXNpb25Ob2RlID0gZGVjaXNpb25Ob2RlSW5mby5ub2RlO1xuICAgICAgICBjb25zdCBkZWNpc2lvbk5vZGVQb2ludHMgPSBkZWNpc2lvbk5vZGUuY29ubmVjdGlvblBvaW50cyB8fCBbXTtcbiAgICAgICAgY29uc3Qgc291cmNlUG9pbnQgPSBkZWNpc2lvbk5vZGVQb2ludHMuZmluZChcbiAgICAgICAgICAocCkgPT4gcC50eXBlID09PSAncmlnaHQnIHx8IHAudHlwZSA9PT0gJ2JvdHRvbSdcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoc291cmNlUG9pbnQpIHtcbiAgICAgICAgICAvLyBGaW5kIG9wcG9zaW5nIHR5cGUgY29ubmVjdGlvbiBwb2ludCBvbiB0aGUgbmV3IHN0YWdlXG4gICAgICAgICAgY29uc3Qgb3Bwb3NpbmdUeXBlID0ge1xuICAgICAgICAgICAgcmlnaHQ6ICdsZWZ0JyxcbiAgICAgICAgICAgIGJvdHRvbTogJ3RvcCcsXG4gICAgICAgICAgICBsZWZ0OiAncmlnaHQnLFxuICAgICAgICAgICAgdG9wOiAnYm90dG9tJyxcbiAgICAgICAgICB9W3NvdXJjZVBvaW50LnR5cGVdIGFzICd0b3AnIHwgJ3JpZ2h0JyB8ICdib3R0b20nIHwgJ2xlZnQnO1xuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0UG9pbnQgPSBub2RlLmNvbm5lY3Rpb25Qb2ludHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBwLnR5cGUgPT09IG9wcG9zaW5nVHlwZVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAodGFyZ2V0UG9pbnQpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBjb25uZWN0aW9uIHdpdGggY29uZGl0aW9uXG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0ge1xuICAgICAgICAgICAgICBpZDogYGNvbm4tJHtEYXRlLm5vdygpfS0ke01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDApfWAsXG4gICAgICAgICAgICAgIHNvdXJjZU5vZGVJZDogZGVjaXNpb25Ob2RlLmlkLFxuICAgICAgICAgICAgICB0YXJnZXROb2RlSWQ6IG5vZGUuaWQsXG4gICAgICAgICAgICAgIHNvdXJjZVBvaW50SWQ6IHNvdXJjZVBvaW50LmlkLFxuICAgICAgICAgICAgICB0YXJnZXRQb2ludElkOiB0YXJnZXRQb2ludC5pZCxcbiAgICAgICAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleDogZGVjaXNpb25Ob2RlSW5mby5zd2ltbGFuZUluZGV4LFxuICAgICAgICAgICAgICB0YXJnZXRTd2ltbGFuZUluZGV4OiBzd2ltbGFuZUluZGV4LFxuICAgICAgICAgICAgICBjb25kaXRpb246IGV2ZW50LmNvbmRpdGlvbixcbiAgICAgICAgICAgICAgbGFiZWw6ICcnLFxuICAgICAgICAgICAgICBhY3Rpb246IG51bGwsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBBZGQgY29ubmVjdGlvbiB0byB0aGUgc3RhdGVcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuY29ubmVjdGlvbnMucHVzaChjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAnQ3JlYXRlZCBkZWNpc2lvbiBjb25uZWN0aW9uIHdpdGggY29uZGl0aW9uOicsXG4gICAgICAgICAgICAgIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgcGVuZGluZyBkYXRhXG4gICAgdGhpcy5wZW5kaW5nRGVjaXNpb25Db25uZWN0aW9uID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdEZWNpc2lvbkNvbmRpdGlvbiA9ICcnO1xuXG4gICAgLy8gSGlkZSB0aGUgY29uZGl0aW9uIHBvcHVwXG4gICAgdGhpcy5zaG93RGVjaXNpb25Db25kaXRpb25EaWFsb2cgPSBmYWxzZTtcbiAgfVxuXG4gIG9uRGVjaXNpb25Db25kaXRpb25DYW5jZWxsZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93RGVjaXNpb25Db25kaXRpb25EaWFsb2cgPSBmYWxzZTtcbiAgICAvLyBEb24ndCBjcmVhdGUgdGhlIHN0YWdlIG9yIGNvbm5lY3Rpb25cbiAgfVxuXG4gIGdldENvbm5lY3Rpb25QYXRoKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGF0aERhdGEgPSB0aGlzLnN0YXRlLmdldENvbm5lY3Rpb25QYXRoRGF0YSgpO1xuICAgIGlmICghcGF0aERhdGEpIHJldHVybiAnJztcblxuICAgIGNvbnN0IHsgc3RhcnRYLCBzdGFydFksIGVuZFgsIGVuZFkgfSA9IHBhdGhEYXRhO1xuICAgIGNvbnN0IHNvdXJjZVBvaW50ID0gdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLnNvdXJjZVBvaW50O1xuXG4gICAgaWYgKCFzb3VyY2VQb2ludCkgcmV0dXJuICcnO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0T3J0aG9nb25hbFBhdGgoc3RhcnRYLCBzdGFydFksIGVuZFgsIGVuZFksIHNvdXJjZVBvaW50LnR5cGUpO1xuICB9XG5cbiAgZ2V0Q29ubmVjdGlvblBhdGhGb3JTYXZlZENvbm5lY3Rpb24oY29ubmVjdGlvbjogQ29ubmVjdGlvbik6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhdGhEYXRhID0gdGhpcy5zdGF0ZS5nZXRDb25uZWN0aW9uRGF0YShjb25uZWN0aW9uKTtcbiAgICAgIGlmICghcGF0aERhdGEpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignTm8gcGF0aCBkYXRhIGZvciBjb25uZWN0aW9uOicsIGNvbm5lY3Rpb24pO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgc3RhcnRYLCBzdGFydFksIGVuZFgsIGVuZFkgfSA9IHBhdGhEYXRhO1xuXG4gICAgICBjb25zdCBzb3VyY2VOb2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKGNvbm5lY3Rpb24uc291cmNlTm9kZUlkKTtcbiAgICAgIGlmICghc291cmNlTm9kZUluZm8pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignU291cmNlIG5vZGUgbm90IGZvdW5kIGZvciBjb25uZWN0aW9uOicsIGNvbm5lY3Rpb24pO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvdXJjZU5vZGUgPSBzb3VyY2VOb2RlSW5mby5ub2RlO1xuICAgICAgY29uc3Qgc291cmNlUG9pbnQgPSBzb3VyY2VOb2RlLmNvbm5lY3Rpb25Qb2ludHM/LmZpbmQoXG4gICAgICAgIChwKSA9PiBwLmlkID09PSBjb25uZWN0aW9uLnNvdXJjZVBvaW50SWRcbiAgICAgICk7XG5cbiAgICAgIGlmICghc291cmNlUG9pbnQpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignU291cmNlIHBvaW50IG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbjonLCBjb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5nZXRPcnRob2dvbmFsUGF0aChcbiAgICAgICAgc3RhcnRYLFxuICAgICAgICBzdGFydFksXG4gICAgICAgIGVuZFgsXG4gICAgICAgIGVuZFksXG4gICAgICAgIHNvdXJjZVBvaW50LnR5cGVcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGdlbmVyYXRpbmcgcGF0aCBmb3IgY29ubmVjdGlvbjonLCBjb25uZWN0aW9uLCBlcnJvcik7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICB9XG5cbiAgZ2V0T3J0aG9nb25hbFBhdGgoXG4gICAgc3RhcnRYOiBudW1iZXIsXG4gICAgc3RhcnRZOiBudW1iZXIsXG4gICAgZW5kWDogbnVtYmVyLFxuICAgIGVuZFk6IG51bWJlcixcbiAgICBwb2ludFR5cGU6ICd0b3AnIHwgJ3JpZ2h0JyB8ICdib3R0b20nIHwgJ2xlZnQnXG4gICk6IHN0cmluZyB7XG4gICAgLy8gRGV0ZXJtaW5lIGluaXRpYWwgZGlyZWN0aW9uIGJhc2VkIG9uIGNvbm5lY3Rpb24gcG9pbnQgdHlwZVxuICAgIGxldCBwYXRoID0gJyc7XG5cbiAgICAvLyBGb3Igc2lkZSBwb2ludHMgKGxlZnQvcmlnaHQpLCBzdGFydCB3aXRoIGhvcml6b250YWwgbGluZVxuICAgIGlmIChwb2ludFR5cGUgPT09ICdsZWZ0JyB8fCBwb2ludFR5cGUgPT09ICdyaWdodCcpIHtcbiAgICAgIC8vIENhbGN1bGF0ZSBob3Jpem9udGFsIGRpc3RhbmNlXG4gICAgICBjb25zdCBob3Jpem9udGFsRGlzdCA9IGVuZFggLSBzdGFydFg7XG5cbiAgICAgIC8vIElmIHRoZSBlbmQgcG9pbnQgaXMgdmVyeSBjbG9zZSBob3Jpem9udGFsbHksIHVzZSBhIHNpbXBsZSAzLXNlZ21lbnQgcGF0aFxuICAgICAgaWYgKE1hdGguYWJzKGhvcml6b250YWxEaXN0KSA8IDMwKSB7XG4gICAgICAgIGNvbnN0IG1pZFkgPSAoc3RhcnRZICsgZW5kWSkgLyAyO1xuICAgICAgICBwYXRoID0gYE0gJHtzdGFydFh9ICR7c3RhcnRZfSBIICR7ZW5kWH0gViAke21pZFl9IFYgJHtlbmRZfWA7XG4gICAgICB9XG4gICAgICAvLyBPdGhlcndpc2UsIGNyZWF0ZSBhIHBhdGggd2l0aCBob3Jpem9udGFsIHNlZ21lbnQgZmlyc3QsIHRoZW4gdmVydGljYWwsIHRoZW4gaG9yaXpvbnRhbFxuICAgICAgZWxzZSB7XG4gICAgICAgIHBhdGggPSBgTSAke3N0YXJ0WH0gJHtzdGFydFl9IEggJHtzdGFydFggKyBob3Jpem9udGFsRGlzdCAvIDJcbiAgICAgICAgICB9IFYgJHtlbmRZfSBIICR7ZW5kWH1gO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBGb3IgdG9wL2JvdHRvbSBwb2ludHMsIHN0YXJ0IHdpdGggdmVydGljYWwgbGluZVxuICAgIGVsc2UgaWYgKHBvaW50VHlwZSA9PT0gJ3RvcCcgfHwgcG9pbnRUeXBlID09PSAnYm90dG9tJykge1xuICAgICAgLy8gQ2FsY3VsYXRlIHZlcnRpY2FsIGRpc3RhbmNlXG4gICAgICBjb25zdCB2ZXJ0aWNhbERpc3QgPSBlbmRZIC0gc3RhcnRZO1xuXG4gICAgICAvLyBJZiB0aGUgZW5kIHBvaW50IGlzIHZlcnkgY2xvc2UgdmVydGljYWxseSwgdXNlIGEgc2ltcGxlIDMtc2VnbWVudCBwYXRoXG4gICAgICBpZiAoTWF0aC5hYnModmVydGljYWxEaXN0KSA8IDMwKSB7XG4gICAgICAgIGNvbnN0IG1pZFggPSAoc3RhcnRYICsgZW5kWCkgLyAyO1xuICAgICAgICBwYXRoID0gYE0gJHtzdGFydFh9ICR7c3RhcnRZfSBWICR7ZW5kWX0gSCAke21pZFh9IEggJHtlbmRYfWA7XG4gICAgICB9XG4gICAgICAvLyBPdGhlcndpc2UsIGNyZWF0ZSBhIHBhdGggd2l0aCB2ZXJ0aWNhbCBzZWdtZW50IGZpcnN0LCB0aGVuIGhvcml6b250YWwsIHRoZW4gdmVydGljYWxcbiAgICAgIGVsc2Uge1xuICAgICAgICBwYXRoID0gYE0gJHtzdGFydFh9ICR7c3RhcnRZfSBWICR7c3RhcnRZICsgdmVydGljYWxEaXN0IC8gMlxuICAgICAgICAgIH0gSCAke2VuZFh9IFYgJHtlbmRZfWA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGg7XG4gIH1cblxuICBzZWxlY3RGb3JtRm9yU3RhZ2UoZm9ybTogRm9ybSB8IG51bGwsIG5vZGU6IE5vZGUpIHtcbiAgICAvLyBJZiBmb3JtIGlzIG51bGwsIHdlJ3JlIGNsZWFyaW5nIHRoZSBzZWxlY3Rpb25cbiAgICBpZiAobm9kZSkge1xuICAgICAgaWYgKCFub2RlLnN0YWdlRGF0YSkge1xuICAgICAgICBub2RlLnN0YWdlRGF0YSA9IHt9O1xuICAgICAgfVxuXG4gICAgICBpZiAoZm9ybSkge1xuICAgICAgICBub2RlLnN0YWdlRGF0YS5mb3JtSWQgPSBmb3JtLkNvZGU7XG4gICAgICAgIG5vZGUuc3RhZ2VEYXRhLmZvcm1OYW1lID0gZm9ybS5OYW1lO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2xlYXIgZm9ybSBzZWxlY3Rpb25cbiAgICAgICAgZGVsZXRlIG5vZGUuc3RhZ2VEYXRhLmZvcm1JZDtcbiAgICAgICAgZGVsZXRlIG5vZGUuc3RhZ2VEYXRhLmZvcm1OYW1lO1xuICAgICAgfVxuXG4gICAgICAvLyBFbWl0IGFuIGV2ZW50IHRvIHVwZGF0ZSB0aGUgc3RhZ2UgZGF0YVxuICAgICAgdGhpcy5vblN0YWdlUHJvcGVydGllc1VwZGF0ZWQoe1xuICAgICAgICBub2RlSWQ6IG5vZGUuaWQsXG4gICAgICAgIHN0YWdlRGF0YTogbm9kZS5zdGFnZURhdGEsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvblN0YWdlUHJvcGVydGllc1VwZGF0ZWQoZXZlbnQ6IHtcbiAgICBub2RlSWQ6IHN0cmluZztcbiAgICBzdGFnZURhdGE6IFBhcnRpYWw8V29ya2Zsb3dTdGFnZT47XG4gIH0pOiB2b2lkIHtcbiAgICAvLyBGaW5kIHRoZSBub2RlIGluIHRoZSBzd2ltbGFuZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc3RhdGUuc3dpbWxhbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzd2ltbGFuZSA9IHRoaXMuc3RhdGUuc3dpbWxhbmVzW2ldO1xuICAgICAgY29uc3Qgbm9kZUluZGV4ID0gc3dpbWxhbmUubm9kZXM/LmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gZXZlbnQubm9kZUlkKTtcblxuICAgICAgaWYgKG5vZGVJbmRleCAhPT0gdW5kZWZpbmVkICYmIG5vZGVJbmRleCA+PSAwKSB7XG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgc3RhZ2UgZGF0YVxuICAgICAgICBpZiAoc3dpbWxhbmUubm9kZXMpIHtcbiAgICAgICAgICBzd2ltbGFuZS5ub2Rlc1tub2RlSW5kZXhdLnN0YWdlRGF0YSA9IHtcbiAgICAgICAgICAgIC4uLnN3aW1sYW5lLm5vZGVzW25vZGVJbmRleF0uc3RhZ2VEYXRhLFxuICAgICAgICAgICAgLi4uZXZlbnQuc3RhZ2VEYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAnVXBkYXRlZCBzdGFnZSBkYXRhIGluIHN3aW1sYW5lOicsXG4gICAgICAgICAgICBpLFxuICAgICAgICAgICAgJ25vZGU6JyxcbiAgICAgICAgICAgIG5vZGVJbmRleCxcbiAgICAgICAgICAgICdkYXRhOicsXG4gICAgICAgICAgICBzd2ltbGFuZS5ub2Rlc1tub2RlSW5kZXhdLnN0YWdlRGF0YVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25Db25uZWN0aW9uQ3JlYXRlZChjb25uZWN0aW9uOiBDb25uZWN0aW9uKTogdm9pZCB7XG4gICAgLy8gQWZ0ZXIgYSBjb25uZWN0aW9uIGlzIGNyZWF0ZWQsIHJlZnJlc2ggdGhlIHNvdXJjZSBub2RlIHRvIHVwZGF0ZSBpdHMgc3RhdGVcbiAgICBjb25zdCBzb3VyY2VOb2RlSW5mbyA9IHRoaXMuc3RhdGUuZmluZE5vZGVCeUlkKGNvbm5lY3Rpb24uc291cmNlTm9kZUlkKTtcbiAgICBpZiAoc291cmNlTm9kZUluZm8gJiYgc291cmNlTm9kZUluZm8ubm9kZS50eXBlID09PSAnc3RhZ2UnKSB7XG4gICAgICAvLyBSZWZyZXNoIG5vZGUgc3RhdGVcbiAgICAgIHRoaXMudXBkYXRlTm9kZUNvbm5lY3Rpb25zKHNvdXJjZU5vZGVJbmZvLm5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEhlbHBlciBtZXRob2QgdG8gdXBkYXRlIG5vZGUncyBjb25uZWN0aW9uIHN0YXR1c1xuICB1cGRhdGVOb2RlQ29ubmVjdGlvbnMobm9kZTogV0ZOb2RlKTogdm9pZCB7XG4gICAgLy8gQ291bnQgdGhlIG51bWJlciBvZiBvdXRnb2luZyBjb25uZWN0aW9ucyB0aGF0IGNvbm5lY3QgdG8gc3RhZ2VzXG4gICAgY29uc3Qgb3V0Z29pbmdDb25uZWN0aW9ucyA9IHRoaXMuc3RhdGUuY29ubmVjdGlvbnMuZmlsdGVyKFxuICAgICAgKGNvbm4pID0+IGNvbm4uc291cmNlTm9kZUlkID09PSBub2RlLmlkXG4gICAgKTtcblxuICAgIC8vIENoZWNrIGlmIHRoZSB0YXJnZXQgbm9kZXMgYXJlIHN0YWdlc1xuICAgIGNvbnN0IGNvbm5lY3RlZFN0YWdlTm9kZXMgPSBvdXRnb2luZ0Nvbm5lY3Rpb25zXG4gICAgICAubWFwKChjb25uKSA9PiB0aGlzLnN0YXRlLmZpbmROb2RlQnlJZChjb25uLnRhcmdldE5vZGVJZCkpXG4gICAgICAuZmlsdGVyKChub2RlSW5mbykgPT4gbm9kZUluZm8gJiYgbm9kZUluZm8ubm9kZS50eXBlID09PSAnc3RhZ2UnKTtcblxuICAgIG5vZGUuaGFzTXVsdGlwbGVDb25uZWN0ZWRTdGFnZXMgPSBjb25uZWN0ZWRTdGFnZU5vZGVzLmxlbmd0aCA+IDE7XG4gICAgbm9kZS5oYXNQYXJhbGxlbFN0YWdlcyA9IGNvbm5lY3RlZFN0YWdlTm9kZXMuZXZlcnkoXG4gICAgICAobmQpID0+IG5kPy5ub2RlLnN0YWdlRGF0YT8uSXNQYXJhbGxlbFxuICAgICk7XG4gIH1cblxuICBvbkVkaXRTd2ltbGFuZShcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBzd2ltbGFuZTogU3dpbWxhbmVJdGVtLFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlclxuICApOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgLy8gUHJldmVudCB0aGUgY2FudmFzIGNsaWNrIGV2ZW50IGZyb20gZmlyaW5nXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zb2xlLmxvZygnRWRpdCBzd2ltbGFuZSBidXR0b24gY2xpY2tlZCBmb3Igc3dpbWxhbmU6Jywgc3dpbWxhbmVJbmRleCk7XG5cbiAgICAvLyBFbWl0IGEgc3BlY2lhbCBldmVudCBmb3IgZWRpdGluZyBhIHN3aW1sYW5lXG4gICAgdGhpcy5jbGlja2VkUG9zaXRpb24uZW1pdCh7XG4gICAgICB4OiAtMSwgLy8gU3BlY2lhbCB2YWx1ZSB0byBpbmRpY2F0ZSBlZGl0IG1vZGVcbiAgICAgIHk6IHN3aW1sYW5lSW5kZXgsXG4gICAgfSk7XG4gIH1cblxuICAvLyBzaG93U3RhcnROb2RlRm9ybVBvcHVwKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gIC8vICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgLy8gICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAvLyAgIC8vIEltcGxlbWVudGF0aW9uIHdpbGwgYmUgc2ltaWxhciB0byB0aGUgc3RhZ2UgZm9ybSBwb3B1cFxuICAvLyAgIC8vIFdlJ2xsIG5lZWQgdG8gYWRkIFVJIGVsZW1lbnRzIGZvciB0aGlzXG4gIC8vICAgY29uc29sZS5sb2coJ1N0YXJ0IG5vZGUgZm9ybSBwb3B1cCByZXF1ZXN0ZWQnKTtcblxuICAvLyAgIC8vIEZvciBub3csIHRoaXMgaXMgYSBwbGFjZWhvbGRlclxuICAvLyAgIC8vIFRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gd291bGQgbG9hZCBmb3JtcyBhbmQgYWRkIHRoZW0gdG8gdGhlIHdvcmtmbG93XG4gIC8vIH1cblxuICB0b2dnbGVTdGFydE5vZGVGb3JtUG9wdXAoXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gICAgbm9kZVg6IG51bWJlcixcbiAgICBub2RlWTogbnVtYmVyLFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlcixcbiAgICBub2RlPzogTm9kZVxuICApOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgLy8gU2V0IHBvcHVwIHBvc2l0aW9uIC0gY29udmVydCBjYW52YXMgY29vcmRpbmF0ZXMgdG8gdmlld3BvcnQgY29vcmRpbmF0ZXNcbiAgICBjb25zdCBzd2ltbGFuZU9mZnNldCA9IHN3aW1sYW5lSW5kZXggKiAyNjM7XG4gICAgY29uc3QgY2FudmFzWCA9IG5vZGVYIC0gKCFub2RlID8gMzAgOiAwKTtcbiAgICBjb25zdCBjYW52YXNZID0gbm9kZVkgKyBzd2ltbGFuZU9mZnNldDtcblxuICAgIGNvbnN0IHZpZXdwb3J0UG9zID0gdGhpcy5nZXRWaWV3cG9ydFBvc2l0aW9uKGNhbnZhc1gsIGNhbnZhc1kpO1xuICAgIHRoaXMuc3RhcnROb2RlRm9ybVBvcHVwWCA9IHZpZXdwb3J0UG9zLng7XG4gICAgdGhpcy5zdGFydE5vZGVGb3JtUG9wdXBZID0gdmlld3BvcnRQb3MueTtcblxuICAgIC8vIElmIHdlJ3JlIG9wZW5pbmcgdGhlIHBvcHVwLCBsb2FkIGZvcm1zXG4gICAgaWYgKCF0aGlzLnNob3dTdGFydE5vZGVGb3JtUG9wdXApIHtcbiAgICAgIHRoaXMuaXNMb2FkaW5nU3RhcnROb2RlRm9ybXMgPSB0cnVlO1xuICAgICAgdGhpcy5kYXRhU2VydmljZVxuICAgICAgICAuZ2V0Rm9ybXMoKVxuICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICB0aGlzLnN0YXJ0Tm9kZUZvcm1zTGlzdCA9IHJlc3BvbnNlLlJlc3VsdDtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZ1N0YXJ0Tm9kZUZvcm1zID0gZmFsc2U7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsb2FkaW5nIGZvcm1zOicsIGVycm9yKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZ1N0YXJ0Tm9kZUZvcm1zID0gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChub2RlKSB7XG4gICAgICB0aGlzLmFjdGl2ZU5vZGVGb3JGb3JtU2VsZWN0aW9uID0gbm9kZTtcbiAgICAgIGNvbnNvbGUubG9nKCdBY3RpdmUgbm9kZSBmb3IgZm9ybSBzZWxlY3Rpb246Jywgbm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWN0aXZlTm9kZUZvckZvcm1TZWxlY3Rpb24gPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMuc2hvd1N0YXJ0Tm9kZUZvcm1Qb3B1cCA9ICF0aGlzLnNob3dTdGFydE5vZGVGb3JtUG9wdXA7XG4gIH1cblxuICBzZWxlY3RTdGFydE5vZGVGb3JtKGZvcm06IEZvcm0gfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZlTm9kZUZvckZvcm1TZWxlY3Rpb24pIHtcbiAgICAgIHRoaXMuc2VsZWN0Rm9ybUZvclN0YWdlKGZvcm0sIHRoaXMuYWN0aXZlTm9kZUZvckZvcm1TZWxlY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZm9ybSkge1xuICAgICAgICB0aGlzLnN0YXRlLnNldFdvcmtmbG93Rm9ybShmb3JtLkNvZGUsIGZvcm0uTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0YXRlLnNldFdvcmtmbG93Rm9ybShudWxsLCBudWxsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDbG9zZSB0aGUgcG9wdXBcbiAgICB0aGlzLnNob3dTdGFydE5vZGVGb3JtUG9wdXAgPSBmYWxzZTtcbiAgfVxuXG4gIHNob3dTdWJmbG93U2VsZWN0aW9uUG9wdXAoeDogbnVtYmVyLCB5OiBudW1iZXIsIHN3aW1sYW5lSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIENvbnZlcnQgY2FudmFzIGNvb3JkaW5hdGVzIHRvIHZpZXdwb3J0IGNvb3JkaW5hdGVzIGZvciBwb3B1cCBwb3NpdGlvbmluZ1xuICAgIGNvbnN0IHZpZXdwb3J0UG9zID0gdGhpcy5nZXRWaWV3cG9ydFBvc2l0aW9uKHgsIHkpO1xuICAgIHRoaXMuc3ViZmxvd1BvcHVwWCA9IHZpZXdwb3J0UG9zLng7XG4gICAgdGhpcy5zdWJmbG93UG9wdXBZID0gdmlld3BvcnRQb3MueTtcbiAgICB0aGlzLnBlbmRpbmdTdWJmbG93UG9zaXRpb24gPSB7IHN3aW1sYW5lSW5kZXgsIHgsIHkgfTtcblxuICAgIC8vIFN0b3JlIGNvbm5lY3Rpb24gZGF0YSBpZiB3ZSdyZSBjcmVhdGluZyBmcm9tIGEgY29ubmVjdGlvblxuICAgIGlmICh0aGlzLnN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpIHtcbiAgICAgIC8vIFN0b3JlIHRoZSBzb3VyY2UgY29ubmVjdGlvbiBkYXRhXG4gICAgICB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlUG9pbnQgPVxuICAgICAgICB0aGlzLnN0YXRlLmRyYWdnaW5nQ29ubmVjdGlvbkRhdGEuc291cmNlUG9pbnQgPz8gbnVsbDtcbiAgICAgIHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VTd2ltbGFuZUluZGV4ID1cbiAgICAgICAgdGhpcy5zdGF0ZS5kcmFnZ2luZ0Nvbm5lY3Rpb25EYXRhLnNvdXJjZVN3aW1sYW5lSW5kZXggPz8gbnVsbDtcbiAgICAgIGNvbnNvbGUubG9nKCdTdG9yZWQgY29ubmVjdGlvbiBkYXRhIGZvciBzdWJmbG93OicsIHtcbiAgICAgICAgc291cmNlUG9pbnQ6IHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VQb2ludCxcbiAgICAgICAgc291cmNlU3dpbWxhbmVJbmRleDogdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVN3aW1sYW5lSW5kZXgsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIHdvcmtmbG93c1xuICAgIHRoaXMuaXNMb2FkaW5nV29ya2Zsb3dzID0gdHJ1ZTtcbiAgICB0aGlzLmRhdGFTZXJ2aWNlXG4gICAgICAuZ2V0V29ya2Zsb3dzKClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLndvcmtmbG93c0xpc3QgPSByZXNwb25zZS5SZXN1bHQ7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nV29ya2Zsb3dzID0gZmFsc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsb2FkaW5nIHdvcmtmbG93czonLCBlcnJvcik7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nV29ya2Zsb3dzID0gZmFsc2U7XG4gICAgICB9KTtcblxuICAgIHRoaXMuc2hvd1N1YmZsb3dQb3B1cCA9IHRydWU7XG4gIH1cblxuICBzZWxlY3RTdWJmbG93V29ya2Zsb3cod29ya2Zsb3c6IFdvcmtmbG93KTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ1NlbGVjdGluZyB3b3JrZmxvdyBmb3Igc3ViZmxvdzonLCB3b3JrZmxvdy5OYW1lKTtcbiAgICBjb25zb2xlLmxvZygnUGVuZGluZyBjb25uZWN0aW9uIGRhdGE6Jywge1xuICAgICAgc291cmNlUG9pbnQ6IHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VQb2ludCxcbiAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXg6IHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VTd2ltbGFuZUluZGV4LFxuICAgICAgcG9zaXRpb246IHRoaXMucGVuZGluZ1N1YmZsb3dQb3NpdGlvbixcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLnBlbmRpbmdTdWJmbG93UG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHsgc3dpbWxhbmVJbmRleCwgeCwgeSB9ID0gdGhpcy5wZW5kaW5nU3ViZmxvd1Bvc2l0aW9uO1xuXG4gICAgICAvLyBDcmVhdGUgdGhlIHN1YmZsb3cgbm9kZSB3aXRoIHRoZSBzZWxlY3RlZCB3b3JrZmxvdyBkYXRhXG4gICAgICBjb25zdCBub2RlID0gdGhpcy5zdGF0ZS5hZGROb2RlKFxuICAgICAgICBzd2ltbGFuZUluZGV4LFxuICAgICAgICAnc3ViZmxvdycsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIHsgTmFtZTogd29ya2Zsb3cuTmFtZSB9LCAvLyBJbml0aWFsaXplIHN0YWdlIG5hbWUgZnJvbSB3b3JrZmxvd1xuICAgICAgICB7IGlkOiB3b3JrZmxvdy5Db2RlLCBuYW1lOiB3b3JrZmxvdy5OYW1lIH1cbiAgICAgICk7XG5cbiAgICAgIGNvbnNvbGUubG9nKCdDcmVhdGVkIHN1YmZsb3cgbm9kZTonLCBub2RlKTtcblxuICAgICAgLy8gSWYgdGhpcyB3YXMgY3JlYXRlZCBmcm9tIGEgY29ubmVjdGlvbiwgY3JlYXRlIHRoZSBjb25uZWN0aW9uXG4gICAgICBpZiAobm9kZSAmJiB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlUG9pbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ0NyZWF0aW5nIGNvbm5lY3Rpb24gdG8gbmV3IHN1YmZsb3cgbm9kZScpO1xuXG4gICAgICAgIC8vIEZpbmQgYSBzdWl0YWJsZSBjb25uZWN0aW9uIHBvaW50IG9uIHRoZSBuZXcgbm9kZVxuICAgICAgICBpZiAobm9kZS5jb25uZWN0aW9uUG9pbnRzICYmIG5vZGUuY29ubmVjdGlvblBvaW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3Qgc291cmNlUG9pbnQgPSB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlUG9pbnQ7XG5cbiAgICAgICAgICAvLyBGaW5kIG9wcG9zaW5nIHR5cGUgY29ubmVjdGlvbiBwb2ludFxuICAgICAgICAgIGNvbnN0IG9wcG9zaW5nVHlwZSA9IHtcbiAgICAgICAgICAgIHJpZ2h0OiAnbGVmdCcsXG4gICAgICAgICAgICBsZWZ0OiAncmlnaHQnLFxuICAgICAgICAgICAgdG9wOiAnYm90dG9tJyxcbiAgICAgICAgICAgIGJvdHRvbTogJ3RvcCcsXG4gICAgICAgICAgfVtzb3VyY2VQb2ludC50eXBlXSBhcyAndG9wJyB8ICdyaWdodCcgfCAnYm90dG9tJyB8ICdsZWZ0JztcblxuICAgICAgICAgIGNvbnN0IHRhcmdldFBvaW50ID0gbm9kZS5jb25uZWN0aW9uUG9pbnRzLmZpbmQoXG4gICAgICAgICAgICAocCkgPT4gcC50eXBlID09PSBvcHBvc2luZ1R5cGVcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHRhcmdldFBvaW50KSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgY29ubmVjdGlvblxuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHtcbiAgICAgICAgICAgICAgaWQ6IGBjb25uLSR7RGF0ZS5ub3coKX0tJHtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwKX1gLFxuICAgICAgICAgICAgICBzb3VyY2VOb2RlSWQ6IHNvdXJjZVBvaW50Lm5vZGVJZCxcbiAgICAgICAgICAgICAgdGFyZ2V0Tm9kZUlkOiBub2RlLmlkLFxuICAgICAgICAgICAgICBzb3VyY2VQb2ludElkOiBzb3VyY2VQb2ludC5pZCxcbiAgICAgICAgICAgICAgdGFyZ2V0UG9pbnRJZDogdGFyZ2V0UG9pbnQuaWQsXG4gICAgICAgICAgICAgIHNvdXJjZVN3aW1sYW5lSW5kZXg6IHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25Tb3VyY2VTd2ltbGFuZUluZGV4ISxcbiAgICAgICAgICAgICAgdGFyZ2V0U3dpbWxhbmVJbmRleDogc3dpbWxhbmVJbmRleCxcbiAgICAgICAgICAgICAgbGFiZWw6ICcnLFxuICAgICAgICAgICAgICBhY3Rpb246IG51bGwsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBBZGQgY29ubmVjdGlvbiBkaXJlY3RseSB0byB0aGUgc3RhdGUncyBjb25uZWN0aW9ucyBhcnJheVxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ0FkZGVkIGNvbm5lY3Rpb24gdG8gc3RhdGU6JywgY29ubmVjdGlvbik7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnQ29ubmVjdGlvbnMgYWZ0ZXIgYWRkaW5nOicsIHRoaXMuc3RhdGUuY29ubmVjdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5vbkNvbm5lY3Rpb25DcmVhdGVkKGNvbm5lY3Rpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlLmVuZENvbm5lY3Rpb25EcmFnKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc2V0IHNlbGVjdGlvbiB0b29sIGluIHBhcmVudCBjb21wb25lbnRcbiAgICAgIHRoaXMuc3ViZmxvd1NlbGVjdGVkLmVtaXQoKTtcbiAgICB9XG5cbiAgICAvLyBDbGVhbiB1cFxuICAgIHRoaXMuc2hvd1N1YmZsb3dQb3B1cCA9IGZhbHNlO1xuICAgIHRoaXMucGVuZGluZ1N1YmZsb3dQb3NpdGlvbiA9IG51bGw7XG4gICAgdGhpcy5wZW5kaW5nQ29ubmVjdGlvblNvdXJjZVBvaW50ID0gbnVsbDtcbiAgICB0aGlzLnBlbmRpbmdDb25uZWN0aW9uU291cmNlU3dpbWxhbmVJbmRleCA9IG51bGw7XG4gIH1cblxuICBzaG93RGVjaXNpb25Db25kaXRpb25zUG9wdXAoXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gICAgbm9kZTogV0ZOb2RlLFxuICAgIHN3aW1sYW5lSW5kZXg6IG51bWJlclxuICApOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgLy8gR2V0IHRoZSBwb3NpdGlvbiBmb3IgdGhlIHBvcHVwXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldE1vdXNlUG9zaXRpb24oZXZlbnQpO1xuXG4gICAgLy8gQ29udmVydCBjYW52YXMgY29vcmRpbmF0ZXMgdG8gdmlld3BvcnQgY29vcmRpbmF0ZXMgZm9yIHBvcHVwIHBvc2l0aW9uaW5nXG4gICAgY29uc3Qgdmlld3BvcnRQb3MgPSB0aGlzLmdldFZpZXdwb3J0UG9zaXRpb24ocG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG5cbiAgICAvLyBGaW5kIGFsbCBjb25uZWN0aW9ucyBmcm9tIHRoaXMgZGVjaXNpb24gbm9kZVxuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gdGhpcy5zdGF0ZS5jb25uZWN0aW9ucy5maWx0ZXIoXG4gICAgICAoY29ubikgPT4gY29ubi5zb3VyY2VOb2RlSWQgPT09IG5vZGUuaWRcbiAgICApO1xuXG4gICAgaWYgKGNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gTm8gY29ubmVjdGlvbnMgdG8gc2hvd1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNob3cgdGhlIGRlY2lzaW9uIGNvbmRpdGlvbnMgcG9wdXBcbiAgICB0aGlzLmFjdGl2ZURlY2lzaW9uTm9kZUlkID0gbm9kZS5pZDtcbiAgICB0aGlzLmRlY2lzaW9uQ29uZGl0aW9uUG9wdXBYID0gdmlld3BvcnRQb3MueDtcbiAgICB0aGlzLmRlY2lzaW9uQ29uZGl0aW9uUG9wdXBZID0gdmlld3BvcnRQb3MueTtcblxuICAgIC8vIFNldCB0aGUgY29ycmVjdCBwb3B1cCB2aXNpYmlsaXR5IGZsYWcgLSB0aGlzIGlzIGxpa2VseSB0aGUgaXNzdWVcbiAgICB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyA9IHRydWU7XG5cbiAgICAvLyBjb25zb2xlLmxvZygnU2hvd2luZyBkZWNpc2lvbiBwb3B1cDonLCB7XG4gICAgLy8gICB5OiBnbG9iYWxZLFxuICAgIC8vICAgbm9kZUlkOiBub2RlLmlkLFxuICAgIC8vICAgaXNWaXNpYmxlOiB0aGlzLnNob3dEZWNpc2lvbkNvbmRpdGlvbkRpYWxvZyxcbiAgICAvLyB9KTtcbiAgfVxuXG4gIGVuc3VyZVN3aW1sYW5lSW5WaWV3KHN3aW1sYW5lSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIEVuc3VyZSB3ZSBoYXZlIGVub3VnaCBzd2ltbGFuZXMgdmlzaWJsZVxuICAgIGNvbnN0IHJlcXVpcmVkSGVpZ2h0ID0gKHN3aW1sYW5lSW5kZXggKyAxKSAqIHRoaXMuc3dpbWxhbmVIZWlnaHQ7XG4gICAgaWYgKHRoaXMuY2FudmFzSGVpZ2h0IDwgcmVxdWlyZWRIZWlnaHQpIHtcbiAgICAgIHRoaXMuY2FudmFzSGVpZ2h0ID0gcmVxdWlyZWRIZWlnaHQ7XG4gICAgfVxuICB9XG5cbiAgZ2V0TGFiZWxQb3NpdGlvbihjb25uZWN0aW9uOiBDb25uZWN0aW9uKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGF0aERhdGEgPSB0aGlzLnN0YXRlLmdldENvbm5lY3Rpb25EYXRhKGNvbm5lY3Rpb24pO1xuICAgICAgaWYgKCFwYXRoRGF0YSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdObyBwYXRoIGRhdGEgZm9yIGNvbm5lY3Rpb246JywgY29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiB7IHg6IDAsIHk6IDAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBzdGFydFgsIHN0YXJ0WSwgZW5kWCwgZW5kWSB9ID0gcGF0aERhdGE7XG5cbiAgICAgIGNvbnN0IHNvdXJjZU5vZGVJbmZvID0gdGhpcy5zdGF0ZS5maW5kTm9kZUJ5SWQoY29ubmVjdGlvbi5zb3VyY2VOb2RlSWQpO1xuICAgICAgaWYgKCFzb3VyY2VOb2RlSW5mbykge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdTb3VyY2Ugbm9kZSBub3QgZm91bmQgZm9yIGNvbm5lY3Rpb246JywgY29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiB7IHg6IDAsIHk6IDAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlTm9kZSA9IHNvdXJjZU5vZGVJbmZvLm5vZGU7XG4gICAgICBjb25zdCBzb3VyY2VQb2ludCA9IHNvdXJjZU5vZGUuY29ubmVjdGlvblBvaW50cz8uZmluZChcbiAgICAgICAgKHApID0+IHAuaWQgPT09IGNvbm5lY3Rpb24uc291cmNlUG9pbnRJZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFzb3VyY2VQb2ludCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdTb3VyY2UgcG9pbnQgbm90IGZvdW5kIGZvciBjb25uZWN0aW9uOicsIGNvbm5lY3Rpb24pO1xuICAgICAgICByZXR1cm4geyB4OiAwLCB5OiAwIH07XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBtaWRwb2ludCBiYXNlZCBvbiB0aGUgY29ubmVjdGlvbiBwb2ludCB0eXBlXG4gICAgICBpZiAoc291cmNlUG9pbnQudHlwZSA9PT0gJ2xlZnQnIHx8IHNvdXJjZVBvaW50LnR5cGUgPT09ICdyaWdodCcpIHtcbiAgICAgICAgY29uc3QgaG9yaXpvbnRhbERpc3QgPSBlbmRYIC0gc3RhcnRYO1xuXG4gICAgICAgIGlmIChNYXRoLmFicyhob3Jpem9udGFsRGlzdCkgPCAzMCkge1xuICAgICAgICAgIC8vIEZvciBzaG9ydCBob3Jpem9udGFsIGNvbm5lY3Rpb25zXG4gICAgICAgICAgY29uc3QgbWlkWSA9IChzdGFydFkgKyBlbmRZKSAvIDI7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHN0YXJ0WCArIChlbmRYIC0gc3RhcnRYKSAvIDIsXG4gICAgICAgICAgICB5OiBtaWRZLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRm9yIHJlZ3VsYXIgY29ubmVjdGlvbnMgc3RhcnRpbmcgaG9yaXpvbnRhbGx5XG4gICAgICAgICAgY29uc3QgbWlkWCA9IHN0YXJ0WCArIGhvcml6b250YWxEaXN0IC8gMjtcbiAgICAgICAgICBjb25zdCBtaWRZID0gZW5kWTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogbWlkWCxcbiAgICAgICAgICAgIHk6IChzdGFydFkgKyBlbmRZKSAvIDIsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gJ3RvcCcgb3IgJ2JvdHRvbSdcbiAgICAgICAgY29uc3QgdmVydGljYWxEaXN0ID0gZW5kWSAtIHN0YXJ0WTtcblxuICAgICAgICBpZiAoTWF0aC5hYnModmVydGljYWxEaXN0KSA8IDMwKSB7XG4gICAgICAgICAgLy8gRm9yIHNob3J0IHZlcnRpY2FsIGNvbm5lY3Rpb25zXG4gICAgICAgICAgY29uc3QgbWlkWCA9IChzdGFydFggKyBlbmRYKSAvIDI7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IG1pZFgsXG4gICAgICAgICAgICB5OiBzdGFydFkgKyAoZW5kWSAtIHN0YXJ0WSkgLyAyLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRm9yIHJlZ3VsYXIgY29ubmVjdGlvbnMgc3RhcnRpbmcgdmVydGljYWxseVxuICAgICAgICAgIGNvbnN0IG1pZFggPSBlbmRYO1xuICAgICAgICAgIGNvbnN0IG1pZFkgPSBzdGFydFkgKyB2ZXJ0aWNhbERpc3QgLyAyO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiAoc3RhcnRYICsgZW5kWCkgLyAyLFxuICAgICAgICAgICAgeTogbWlkWSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICdFcnJvciBjYWxjdWxhdGluZyBsYWJlbCBwb3NpdGlvbiBmb3IgY29ubmVjdGlvbjonLFxuICAgICAgICBjb25uZWN0aW9uLFxuICAgICAgICBlcnJvclxuICAgICAgKTtcbiAgICAgIHJldHVybiB7IHg6IDAsIHk6IDAgfTtcbiAgICB9XG4gIH1cblxuICBzYXZlQ29ubmVjdGlvbkxhYmVsKGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIGxhYmVsOiBzdHJpbmcpIHtcbiAgICAvLyBVcGRhdGUgdGhlIGNvbm5lY3Rpb24gbGFiZWwgaW4gdGhlIHN0YXRlXG4gICAgdGhpcy5zdGF0ZS5jb25uZWN0aW9ucyA9IHRoaXMuc3RhdGUuY29ubmVjdGlvbnMubWFwKChjb25uKSA9PiB7XG4gICAgICBpZiAoY29ubi5pZCA9PT0gY29ubmVjdGlvbi5pZCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmNvbm4sXG4gICAgICAgICAgbGFiZWw6IGxhYmVsLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbm47XG4gICAgfSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjYW52YXMtY29udGFpbmVyXCI+XG4gIDxzdmcgI2NhbnZhcyBbYXR0ci53aWR0aF09XCJjYW52YXNXaWR0aFwiIFthdHRyLmhlaWdodF09XCJjYW52YXNIZWlnaHRcIiBjbGFzcz1cImRlc2lnbmVyLWNhbnZhc1wiXG4gICAgKGNsaWNrKT1cIm9uQ2FudmFzQ2xpY2soJGV2ZW50KVwiPlxuICAgIDxkZWZzPlxuICAgICAgPCEtLSBHcmlkIHBhdHRlcm4gZGVmaW5pdGlvbiAtLT5cblxuICAgICAgPHBhdHRlcm4gaWQ9XCJncmlkXCIgW2F0dHIud2lkdGhdPVwiZ3JpZFNpemVcIiBbYXR0ci5oZWlnaHRdPVwiZ3JpZFNpemVcIiBwYXR0ZXJuVW5pdHM9XCJ1c2VyU3BhY2VPblVzZVwiPlxuICAgICAgICA8cGF0aCBkPVwiTSAyMCAwIEwgMCAwIDAgMjBcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiNlMmU4ZjBcIiBzdHJva2Utd2lkdGg9XCIwLjVcIiAvPlxuICAgICAgPC9wYXR0ZXJuPlxuXG4gICAgICA8IS0tIEFycm93IGhlYWQgbWFya2VyIGRlZmluaXRpb24gLS0+XG4gICAgICA8bWFya2VyIGlkPVwiYXJyb3doZWFkXCIgbWFya2VyV2lkdGg9XCIxMFwiIG1hcmtlckhlaWdodD1cIjdcIiByZWZYPVwiOVwiIHJlZlk9XCIzLjVcIiBvcmllbnQ9XCJhdXRvXCI+XG4gICAgICAgIDxwb2x5Z29uIHBvaW50cz1cIjAgMCwgMTAgMy41LCAwIDdcIiBmaWxsPVwiI0QzNkNGRlwiIC8+XG4gICAgICA8L21hcmtlcj5cblxuICAgICAgPCEtLSBDb25uZWN0aW9uIHBvaW50IHN0eWxlcyAtLT5cbiAgICAgIDxjaXJjbGUgaWQ9XCJjb25uZWN0aW9uLXBvaW50LXRlbXBsYXRlXCIgcj1cIjVcIiBmaWxsPVwiI0QzNkNGRlwiIHN0cm9rZT1cIiNGRkZGRkZcIiBzdHJva2Utd2lkdGg9XCIxXCIgLz5cblxuICAgICAgPCEtLSBEYXNoZWQgbGluZSBzdHlsZSBmb3IgY29ubmVjdGlvbiBwcmV2aWV3IC0tPlxuICAgICAgPHBhdHRlcm4gaWQ9XCJkYXNoZWQtbGluZVwiIHdpZHRoPVwiMTBcIiBoZWlnaHQ9XCIxMFwiIHBhdHRlcm5Vbml0cz1cInVzZXJTcGFjZU9uVXNlXCI+XG4gICAgICAgIDxsaW5lIHgxPVwiMFwiIHkxPVwiNVwiIHgyPVwiMTBcIiB5Mj1cIjVcIiBzdHJva2U9XCIjRDM2Q0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1kYXNoYXJyYXk9XCI1LDVcIiAvPlxuICAgICAgPC9wYXR0ZXJuPlxuXG4gICAgICBAZm9yIChzd2ltbGFuZSBvZiBzdGF0ZS5zd2ltbGFuZXM7IHRyYWNrIHN3aW1sYW5lLm9yZGVyKSB7XG4gICAgICA8Y2xpcFBhdGggW2F0dHIuaWRdPVwiJ3N3aW1sYW5lLWNsaXAtJyArIHN3aW1sYW5lLm9yZGVyXCI+XG4gICAgICAgIDxyZWN0IHg9XCIwXCIgeT1cIjBcIiBbYXR0ci53aWR0aF09XCJjYW52YXNXaWR0aFwiIGhlaWdodD1cIjI2M1wiIC8+XG4gICAgICA8L2NsaXBQYXRoPlxuICAgICAgfVxuICAgIDwvZGVmcz5cblxuICAgIDwhLS0gQmFja2dyb3VuZCBncmlkIC0tPlxuICAgIDxyZWN0IHdpZHRoPVwiMTAwJVwiIGhlaWdodD1cIjEwMCVcIiBmaWxsPVwidXJsKCNncmlkKVwiIC8+XG5cbiAgICA8IS0tIERpc3BsYXkgYSBtZXNzYWdlIHdoZW4gbm8gc3dpbWxhbmVzIGV4aXN0IC0tPlxuICAgIEBpZiAoc3RhdGUuc3dpbWxhbmVzLmxlbmd0aCA9PT0gMCkge1xuICAgIDx0ZXh0IHg9XCI1MCVcIiB5PVwiNTAlXCIgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCIgZm9udC1zaXplPVwiMTZcIiBmaWxsPVwiIzk0YTNiOFwiIHRleHQtYW5jaG9yPVwibWlkZGxlXCI+XG4gICAgICBTZWxlY3QgdGhlIFN3aW1sYW5lIHRvb2wgYW5kIGNsaWNrIG9uIHRoZSBjYW52YXMgdG8gYWRkIGEgc3dpbWxhbmVcbiAgICA8L3RleHQ+XG4gICAgfVxuXG4gICAgPCEtLSBUaGlzIGlzIHdoZXJlIHdvcmtmbG93IGVsZW1lbnRzIHdpbGwgYmUgYWRkZWQgbGF0ZXIgLS0+XG4gICAgQGZvciAoc3dpbWxhbmUgb2Ygc3RhdGUuc3dpbWxhbmVzOyB0cmFjayBzd2ltbGFuZS5vcmRlcikge1xuICAgIDwhLS0gPGdcbiAgICAgIFthdHRyLnRyYW5zZm9ybV09XCIndHJhbnNsYXRlKDAsJyArIHN3aW1sYW5lLm9yZGVyICogMjYzICsgJyknXCJcbiAgICAgIFthdHRyLmNsaXAtcGF0aF09XCIndXJsKCNzd2ltbGFuZS1jbGlwLScgKyBzd2ltbGFuZS5vcmRlciArICcpJ1wiXG4gICAgPlxuICAgICAgPHJlY3RcbiAgICAgICAgeD1cIjBcIlxuICAgICAgICB5PVwiMFwiXG4gICAgICAgIFthdHRyLndpZHRoXT1cImNhbnZhc1dpZHRoXCJcbiAgICAgICAgW2F0dHIuaGVpZ2h0XT1cIjI2M1wiXG4gICAgICAgIGZpbGw9XCIjZmZmZmZmXCJcbiAgICAgICAgc3Ryb2tlPVwiI2UyZThmMFwiXG4gICAgICAgIHN0cm9rZS13aWR0aD1cIjFcIlxuICAgICAgPjwvcmVjdD5cblxuICAgICAgPHJlY3RcbiAgICAgICAgeD1cIjBcIlxuICAgICAgICB5PVwiMFwiXG4gICAgICAgIFthdHRyLndpZHRoXT1cImNhbnZhc1dpZHRoXCJcbiAgICAgICAgaGVpZ2h0PVwiNDBcIlxuICAgICAgICBmaWxsPVwiI2Y4ZmFmY1wiXG4gICAgICAgIHN0cm9rZT1cIiNlMmU4ZjBcIlxuICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgID48L3JlY3Q+XG5cbiAgICAgIDx0ZXh0XG4gICAgICAgIHg9XCIyMFwiXG4gICAgICAgIHk9XCIyNVwiXG4gICAgICAgIGZvbnQtZmFtaWx5PVwic2Fucy1zZXJpZlwiXG4gICAgICAgIGZvbnQtc2l6ZT1cIjE0XCJcbiAgICAgICAgZmlsbD1cIiMzMzMzMzNcIlxuICAgICAgICBmb250LXdlaWdodD1cImJvbGRcIlxuICAgICAgPlxuICAgICAgICB7eyBzd2ltbGFuZS5sYWJlbCB9fVxuICAgICAgPC90ZXh0PlxuXG4gICAgICA8Z1xuICAgICAgICBjbGFzcz1cImVkaXQtc3dpbWxhbmUtYnV0dG9uXCJcbiAgICAgICAgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoMTAwLCAyMCknXCJcbiAgICAgICAgKGNsaWNrKT1cIlxuICAgICAgICAgIG9uRWRpdFN3aW1sYW5lKCRldmVudCwgc3dpbWxhbmUsIHN3aW1sYW5lLm9yZGVyKTtcbiAgICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgPHJlY3RcbiAgICAgICAgICB4PVwiLTVcIlxuICAgICAgICAgIHk9XCItMTVcIlxuICAgICAgICAgIHdpZHRoPVwiNDBcIlxuICAgICAgICAgIGhlaWdodD1cIjIwXCJcbiAgICAgICAgICBmaWxsPVwiI2YzZThmZlwiXG4gICAgICAgICAgcng9XCIzXCJcbiAgICAgICAgICByeT1cIjNcIlxuICAgICAgICAgIHN0cm9rZT1cIiNkOGI0ZmVcIlxuICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjFcIlxuICAgICAgICA+PC9yZWN0PlxuICAgICAgICA8dGV4dFxuICAgICAgICAgIHg9XCIxNVwiXG4gICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgIGZvbnQtZmFtaWx5PVwic2Fucy1zZXJpZlwiXG4gICAgICAgICAgZm9udC1zaXplPVwiMTJcIlxuICAgICAgICAgIGZpbGw9XCIjN2UyMmNlXCJcbiAgICAgICAgICB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiXG4gICAgICAgID5cbiAgICAgICAgICBFZGl0XG4gICAgICAgIDwvdGV4dD5cbiAgICAgIDwvZz5cblxuICAgICAgPGcgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoMjAwLCAyMCknXCI+XG4gICAgICAgIEBmb3IgKHRhZyBvZiBzd2ltbGFuZS50YWdzLnNsaWNlKDAsIDMpOyB0cmFjayB0YWcuTmFtZTsgbGV0IGkgPSAkaW5kZXgpXG4gICAgICAgIHtcbiAgICAgICAgPHRleHRcbiAgICAgICAgICBbYXR0ci54XT1cImkgKiAxMDBcIlxuICAgICAgICAgIHk9XCI1XCJcbiAgICAgICAgICBmb250LWZhbWlseT1cInNhbnMtc2VyaWZcIlxuICAgICAgICAgIGZvbnQtc2l6ZT1cIjEyXCJcbiAgICAgICAgICBmaWxsPVwiIzY2NjY2NlwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB0YWcuTmFtZSB9fVxuICAgICAgICA8L3RleHQ+XG4gICAgICAgIH0gQGlmIChzd2ltbGFuZS50YWdzLmxlbmd0aCA+IDMpIHtcbiAgICAgICAgPHRleHRcbiAgICAgICAgICBbYXR0ci54XT1cIjMgKiAxMDAgKyAxMFwiXG4gICAgICAgICAgeT1cIjVcIlxuICAgICAgICAgIGZvbnQtZmFtaWx5PVwic2Fucy1zZXJpZlwiXG4gICAgICAgICAgZm9udC1zaXplPVwiMTJcIlxuICAgICAgICAgIGZpbGw9XCIjNjY2NjY2XCJcbiAgICAgICAgPlxuICAgICAgICAgICt7eyBzd2ltbGFuZS50YWdzLmxlbmd0aCAtIDMgfX0gbW9yZVxuICAgICAgICA8L3RleHQ+XG4gICAgICAgIH1cbiAgICAgIDwvZz5cbiAgICA8L2c+IC0tPlxuXG4gICAgPGcgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoMCwnICsgc3dpbWxhbmUub3JkZXIgKiAyNjMgKyAnKSdcIj5cbiAgICAgIDwhLS0gU3dpbWxhbmUgY29udGFpbmVyIC0gcmVtb3ZlIHN0cm9rZSB0byBtYWtlIGl0IHB1cmVseSBiYWNrZ3JvdW5kIC0tPlxuICAgICAgPHJlY3QgeD1cIjBcIiB5PVwiMFwiIFthdHRyLndpZHRoXT1cImNhbnZhc1dpZHRoXCIgW2F0dHIuaGVpZ2h0XT1cIjI2M1wiXG4gICAgICAgIFthdHRyLmZpbGxdPVwic3dpbWxhbmUub3JkZXIgJSAyID09PSAwID8gJyNGQ0YzRkYnIDogJyNFQ0ZGRjUnXCIgc3Ryb2tlPVwibm9uZVwiPjwvcmVjdD5cblxuICAgICAgPCEtLSBWZXJ0aWNhbCBzd2ltbGFuZSBsYWJlbCBvbiB0aGUgbGVmdCAtLT5cbiAgICAgIDxnIGNsYXNzPVwic3dpbWxhbmUtbGFiZWxcIj5cbiAgICAgICAgPCEtLSBQdXJwbGUgYmFja2dyb3VuZCBmb3IgdGhlIGxhYmVsIC0tPlxuICAgICAgICA8cmVjdCB4PVwiMC41XCIgeT1cIjAuNVwiIHdpZHRoPVwiNDNcIiBoZWlnaHQ9XCIyMTVcIiByeD1cIjEwLjVcIiBmaWxsPVwid2hpdGVcIiBzdHJva2U9XCIjRDM2Q0ZGXCI+PC9yZWN0PlxuXG4gICAgICAgIDwhLS0gUGx1cyBidXR0b24gYXQgdGhlIHRvcCAtLT5cbiAgICAgICAgPGcgKGNsaWNrKT1cIlxuICAgICAgICAgICAgb25FZGl0U3dpbWxhbmUoJGV2ZW50LCBzd2ltbGFuZSwgc3dpbWxhbmUub3JkZXIpO1xuICAgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgXCI+XG4gICAgICAgICAgPHJlY3QgeD1cIjEyLjVcIiB5PVwiMTBcIiB3aWR0aD1cIjE4XCIgaGVpZ2h0PVwiMThcIiBmaWxsPVwidHJhbnNwYXJlbnRcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlclwiPjwvcmVjdD5cblxuICAgICAgICAgIDxwYXRoIGQ9XCJNMjIuNTIgMTIuMTc0VjE3LjA4SDI3LjQ3VjE4LjUxSDIyLjUyVjIzLjM5NEgyMS4yVjE4LjUxSDE2LjI1VjE3LjA4SDIxLjJWMTIuMTc0SDIyLjUyWlwiXG4gICAgICAgICAgICBmaWxsPVwiIzAwMDBGRlwiIGNsYXNzPVwicGx1cy1pY29uXCIgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXJcIj48L3BhdGg+XG4gICAgICAgIDwvZz5cblxuICAgICAgICA8IS0tIFN3aW1sYW5lIGxhYmVsIC0tPlxuICAgICAgICA8dGV4dCB4PVwiMjJcIiB5PVwiMTA2XCIgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCIgZm9udC1zaXplPVwiMTRcIiBmaWxsPVwiIzMzMzMzM1wiIHRleHQtYW5jaG9yPVwibWlkZGxlXCJcbiAgICAgICAgICB0cmFuc2Zvcm09XCJyb3RhdGUoLTkwLCAyMiwgMTAwKVwiPlxuICAgICAgICAgIHt7XG4gICAgICAgICAgc3dpbWxhbmUubGFiZWwubGVuZ3RoID4gMTJcbiAgICAgICAgICA/IHN3aW1sYW5lLmxhYmVsLnN1YnN0cmluZygwLCAxMCkgKyBcIi4uLlwiXG4gICAgICAgICAgOiBzd2ltbGFuZS5sYWJlbFxuICAgICAgICAgIH19XG4gICAgICAgIDwvdGV4dD5cblxuICAgICAgICA8IS0tIFRhZyBjb3VudCBpbmRpY2F0b3IgYXQgdGhlIGJvdHRvbSAtLT5cbiAgICAgICAgPHJlY3QgeD1cIjExLjVcIiB5PVwiMTg3XCIgd2lkdGg9XCIyMVwiIGhlaWdodD1cIjE5XCIgcng9XCI5LjVcIiBmaWxsPVwiIzlFOUU5RVwiPjwvcmVjdD5cbiAgICAgICAgPHRleHQgeD1cIjI0XCIgeT1cIjIwNlwiIGZvbnQtZmFtaWx5PVwic2Fucy1zZXJpZlwiIGZvbnQtc2l6ZT1cIjEyXCIgZmlsbD1cImJsYWNrXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIlxuICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtOTAsIDIyLCAyMDApXCI+XG4gICAgICAgICAge3sgc3dpbWxhbmUudGFncy5sZW5ndGggfX1cbiAgICAgICAgPC90ZXh0PlxuICAgICAgPC9nPlxuICAgIDwvZz5cblxuICAgIH1cblxuICAgIDwhLS0gTm9kZXMgLS0+XG4gICAgQGZvciAoc3dpbWxhbmUgb2Ygc3RhdGUuc3dpbWxhbmVzOyB0cmFjayBzd2ltbGFuZS5vcmRlcikge1xuICAgIDwhLS0gUmVuZGVyIG5vZGVzIGluIHRoaXMgc3dpbWxhbmUgLS0+XG4gICAgQGZvciAobm9kZSBvZiBzd2ltbGFuZS5ub2RlczsgdHJhY2sgbm9kZS5pZCkge1xuICAgIDxnIGNsYXNzPVwibm9kZS1lbGVtZW50XCIgW2F0dHIudHJhbnNmb3JtXT1cIlxuICAgICAgICAndHJhbnNsYXRlKCcgKyBub2RlLnggKyAnLCcgKyAobm9kZS55ICsgc3dpbWxhbmUub3JkZXIgKiAyNjMpICsgJyknXCIgW3N0eWxlLmN1cnNvcl09XCJnZXRDdXJzb3JGb3JOb2RlKG5vZGUuaWQpXCJcbiAgICAgIChtb3VzZWRvd24pPVwib25Ob2RlTW91c2VEb3duKCRldmVudCwgbm9kZSwgc3dpbWxhbmUub3JkZXIpXCJcbiAgICAgIChtb3VzZWVudGVyKT1cInNob3dDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQsIHN3aW1sYW5lLm9yZGVyKVwiIChtb3VzZWxlYXZlKT1cImhpZGVDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQpXCI+XG4gICAgICA8IS0tIFN0YXJ0IG5vZGUgaW5kaWNhdG9yIChjaXJjbGUgYW5kIGFycm93KSBmb3IgdGhlIGZpcnN0IG5vZGUgLS0+XG4gICAgICBAaWYgKG5vZGUuaXNTdGFydE5vZGUpIHtcbiAgICAgIDwhLS0gQ2lyY2xlIC0tPlxuICAgICAgPGNpcmNsZSBjeD1cIi01MFwiIGN5PVwiNTBcIiByPVwiMzBcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCI+PC9jaXJjbGU+XG4gICAgICA8IS0tIEZvcm0gaWNvbiBmb3Igc3RhcnQgbm9kZSAtLT5cbiAgICAgIDxzdmc6ZyAoY2xpY2spPVwiXG4gICAgICAgICAgdG9nZ2xlU3RhcnROb2RlRm9ybVBvcHVwKCRldmVudCwgbm9kZS54LCBub2RlLnksIHN3aW1sYW5lLm9yZGVyKVxuICAgICAgICBcIiBjbGFzcz1cInN0YWdlLWljb25cIiB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTQ1LCA0MilcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjsgcG9pbnRlci1ldmVudHM6IGFsbFwiPlxuICAgICAgICA8IS0tIFRyYW5zcGFyZW50IHJlY3RhbmdsZSB0byBjYXB0dXJlIGNsaWNrcyAtLT5cbiAgICAgICAgPHN2ZzpyZWN0IHg9XCItMlwiIHk9XCItMlwiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIGZpbGw9XCJ0cmFuc3BhcmVudFwiIHN0eWxlPVwiY3Vyc29yOiBwb2ludGVyXCIgLz5cbiAgICAgICAgPHN2ZzpwYXRoXG4gICAgICAgICAgZD1cIk0xNi41IDIwLjQ3NVYxNy40NzVIMTMuNVYxNi40NzVIMTYuNVYxMy40NzVIMTcuNVYxNi40NzVIMjAuNVYxNy40NzVIMTcuNVYyMC40NzVIMTYuNVpNMy41IDE3LjVWMTYuNUg0LjVWMTcuNUgzLjVaTTYuNSAxNy41VjE2LjVIMTEuNTE3QzExLjUwNTcgMTYuNjc2NyAxMS41MDQzIDE2Ljg0NSAxMS41MTMgMTcuMDA1QzExLjUyMSAxNy4xNjUgMTEuNTMxIDE3LjMzIDExLjU0MyAxNy41SDYuNVpNMy41IDEzLjVWMTIuNUg0LjVWMTMuNUgzLjVaTTYuNSAxMy41VjEyLjVIMTMuODA0QzEzLjYxMjcgMTIuNjM4NyAxMy40MzMzIDEyLjc5MTMgMTMuMjY2IDEyLjk1OEMxMy4wOTkzIDEzLjEyNDcgMTIuOTM3NyAxMy4zMDUzIDEyLjc4MSAxMy41SDYuNVpNMy41IDkuNVY4LjVINC41VjkuNUgzLjVaTTYuNSA5LjVWOC41SDE4LjVWOS41SDYuNVpNMy41IDUuNVY0LjVINC41VjUuNUgzLjVaTTYuNSA1LjVWNC41SDE4LjVWNS41SDYuNVpcIlxuICAgICAgICAgIFthdHRyLmZpbGxdPVwic3RhdGUud29ya2Zsb3dGb3JtSWQgPyAnI0QzNkNGRicgOiAnYmxhY2snXCIgdHJhbnNmb3JtPVwic2NhbGUoMC43KVwiIC8+XG4gICAgICA8L3N2ZzpnPlxuICAgICAgPCEtLSBBcnJvdyBmcm9tIGNpcmNsZSB0byBub2RlIC0tPlxuICAgICAgPHBhdGggZD1cIk0gLTIwIDUwIEwgMCA1MFwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCIgbWFya2VyLWVuZD1cInVybCgjYXJyb3doZWFkKVwiPjwvcGF0aD5cbiAgICAgIH1cblxuICAgICAgPCEtLSBFeGl0IHBvaW50IGluZGljYXRvciAoY2lyY2xlIGFuZCBhcnJvdykgLS0+XG4gICAgICBAaWYgKG5vZGUuc3RhZ2VEYXRhPy5Jc0V4aXRQb2ludCkge1xuICAgICAgPCEtLSBBcnJvdyBmcm9tIG5vZGUgdG8gY2lyY2xlIC0tPlxuICAgICAgPHBhdGggW2F0dHIuZF09XCInTSAnICsgbm9kZS53aWR0aCArICcgNTAgTCAnICsgKG5vZGUud2lkdGggKyAyMCkgKyAnIDUwJ1wiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgbWFya2VyLWVuZD1cInVybCgjYXJyb3doZWFkKVwiPjwvcGF0aD5cbiAgICAgIDwhLS0gQ2lyY2xlIC0tPlxuICAgICAgPGNpcmNsZSBbYXR0ci5jeF09XCJub2RlLndpZHRoICsgNTBcIiBjeT1cIjUwXCIgcj1cIjMwXCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjRDM2Q0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPjwvY2lyY2xlPlxuICAgICAgfVxuXG4gICAgICA8IS0tIFN0YWdlIG5vZGUgLS0+XG4gICAgICBAaWYgKG5vZGUudHlwZSA9PT0gJ3N0YWdlJykge1xuICAgICAgPCEtLSA8cmVjdFxuICAgICAgICAgICAgICAgICAgeD1cIjBcIlxuICAgICAgICAgICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgICAgICAgICAgW2F0dHIud2lkdGhdPVwibm9kZS53aWR0aFwiXG4gICAgICAgICAgICAgICAgICBbYXR0ci5oZWlnaHRdPVwibm9kZS5oZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiI0QzNkNGRlwiXG4gICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgICAgICAgICA+PC9yZWN0PiAtLT5cbiAgICAgIDxzdmc6ZyBsaWItc3RhZ2Utbm9kZSBbbm9kZV09XCJub2RlXCIgW2lzU3RhcnROb2RlXT1cIm5vZGUuaXNTdGFydE5vZGVcIlxuICAgICAgICAoc3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCk9XCJvblN0YWdlUHJvcGVydGllc1VwZGF0ZWQoJGV2ZW50KVwiIChzaG93U2hpZWxkRGlhbG9nKT1cIm9uU2hvd1NoaWVsZERpYWxvZygkZXZlbnQpXCJcbiAgICAgICAgKHNob3dFc2NhbGF0aW9uRGlhbG9nKT1cIm9uU2hvd0VzY2FsYXRpb25EaWFsb2coJGV2ZW50KVwiIChzaG93Rm9ybURpYWxvZyk9XCJcbiAgICAgICAgICB0b2dnbGVTdGFydE5vZGVGb3JtUG9wdXAoJGV2ZW50LCBub2RlLngsIG5vZGUueSwgc3dpbWxhbmUub3JkZXIsIG5vZGUpXG4gICAgICAgIFwiPjwvc3ZnOmc+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gRGVjaXNpb24gbm9kZSAtLT5cbiAgICAgIEBpZiAobm9kZS50eXBlID09PSAnZGVjaXNpb24nKSB7XG4gICAgICA8cGF0aCBbYXR0ci5kXT1cIlxuICAgICAgICAgICdNIDAgJyArXG4gICAgICAgICAgbm9kZS5oZWlnaHQgLyAyICtcbiAgICAgICAgICAnIEwgJyArXG4gICAgICAgICAgbm9kZS53aWR0aCAvIDIgK1xuICAgICAgICAgICcgMCcgK1xuICAgICAgICAgICcgTCAnICtcbiAgICAgICAgICBub2RlLndpZHRoICtcbiAgICAgICAgICAnICcgK1xuICAgICAgICAgIG5vZGUuaGVpZ2h0IC8gMiArXG4gICAgICAgICAgJyBMICcgK1xuICAgICAgICAgIG5vZGUud2lkdGggLyAyICtcbiAgICAgICAgICAnICcgK1xuICAgICAgICAgIG5vZGUuaGVpZ2h0ICtcbiAgICAgICAgICAnIFonXG4gICAgICAgIFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiI0QzNkNGRlwiIHN0cm9rZS13aWR0aD1cIjFcIj48L3BhdGg+XG5cbiAgICAgIDwhLS0gRGVjaXNpb24gbm9kZSBjb25kaXRpb24gaW5kaWNhdG9yIGljb24gLS0+XG4gICAgICA8c3ZnOmcgKGNsaWNrKT1cInNob3dEZWNpc2lvbkNvbmRpdGlvbnNQb3B1cCgkZXZlbnQsIG5vZGUsIHN3aW1sYW5lLm9yZGVyKVwiIGNsYXNzPVwiZGVjaXNpb24tY29uZGl0aW9uLWljb25cIlxuICAgICAgICBbYXR0ci50cmFuc2Zvcm1dPVwiXG4gICAgICAgICAgJ3RyYW5zbGF0ZSgnICtcbiAgICAgICAgICAobm9kZS53aWR0aCAvIDIgLSAxMCkgK1xuICAgICAgICAgICcsJyArXG4gICAgICAgICAgKG5vZGUuaGVpZ2h0IC8gMiAtIDEwKSArXG4gICAgICAgICAgJyknXG4gICAgICAgIFwiPlxuICAgICAgICA8c3ZnOnJlY3QgeD1cIi01XCIgeT1cIi01XCIgd2lkdGg9XCIzMFwiIGhlaWdodD1cIjMwXCIgZmlsbD1cInRyYW5zcGFyZW50XCIgc3R5bGU9XCJjdXJzb3I6IHBvaW50ZXJcIiAvPlxuICAgICAgICA8c3ZnOnBhdGggZD1cIk0xMCAwSDIwVjJIMTBWMFpNMTAgOEgyMFYxMEgxMFY4Wk0xMCA0SDIwVjZIMTBWNFpNMCAwSDhWMkgwVjBaTTAgOEg4VjEwSDBWOFpNMCA0SDhWNkgwVjRaXCJcbiAgICAgICAgICBmaWxsPVwiI0QzNkNGRlwiIC8+XG4gICAgICA8L3N2ZzpnPlxuICAgICAgfVxuXG4gICAgICA8IS0tIEZvcm0gbm9kZSAtLT5cbiAgICAgIEBpZiAobm9kZS50eXBlID09PSAnZm9ybScpIHtcbiAgICAgIDxwYXRoXG4gICAgICAgIGQ9XCJNOTUuMDYyNSA1MC41NTkxVjk1LjA2MjVDOTUuMDYyNSA5Ny45NzE2IDkzLjkwNjkgMTAwLjc2MiA5MS44NDk4IDEwMi44MTlDODkuNzkyOCAxMDQuODc2IDg3LjAwMjggMTA2LjAzMSA4NC4wOTM4IDEwNi4wMzFIMzIuOTA2MkMyOS45OTcyIDEwNi4wMzEgMjcuMjA3MiAxMDQuODc2IDI1LjE1MDIgMTAyLjgxOUMyMy4wOTMxIDEwMC43NjIgMjEuOTM3NSA5Ny45NzE2IDIxLjkzNzUgOTUuMDYyNVYyMS45Mzc1QzIxLjkzNzUgMTkuMDI4NCAyMy4wOTMxIDE2LjIzODUgMjUuMTUwMiAxNC4xODE0QzI3LjIwNzIgMTIuMTI0NCAyOS45OTcyIDEwLjk2ODggMzIuOTA2MiAxMC45Njg4SDU1LjQ3MjJDNTcuNDEwOSAxMC45NjkgNTkuMjcwMSAxMS43MzkyIDYwLjY0MTIgMTMuMTA5OUw5Mi45MjEzIDQ1LjM5MDFDOTQuMjkyIDQ2Ljc2MTEgOTUuMDYyMiA0OC42MjA0IDk1LjA2MjUgNTAuNTU5MVpcIlxuICAgICAgICB0cmFuc2Zvcm09XCJzY2FsZSgwLjcpXCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjRDM2Q0ZGXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk01OC41IDEyLjc5NjlWNDAuMjE4OEM1OC41IDQyLjE1ODEgNTkuMjcwNCA0NC4wMTgxIDYwLjY0MTggNDUuMzg5NUM2Mi4wMTMxIDQ2Ljc2MDggNjMuODczMSA0Ny41MzEyIDY1LjgxMjUgNDcuNTMxMkg5My4yMzQ0XCJcbiAgICAgICAgdHJhbnNmb3JtPVwic2NhbGUoMC43KVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgPHRleHQgeD1cIjUwJVwiIHk9XCI1MCVcIiB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiIGRvbWluYW50LWJhc2VsaW5lPVwibWlkZGxlXCIgZm9udC1mYW1pbHk9XCJzYW5zLXNlcmlmXCIgZm9udC1zaXplPVwiMTRcIlxuICAgICAgICBmaWxsPVwiI0QzNkNGRlwiPlxuICAgICAgICBGb3JtXG4gICAgICA8L3RleHQ+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gU3ViZmxvdyBub2RlIC0tPlxuICAgICAgQGlmIChub2RlLnR5cGUgPT09ICdzdWJmbG93Jykge1xuICAgICAgPHN2ZzpnIGxpYi1zdGFnZS1ub2RlIFtub2RlXT1cIm5vZGVcIiBbaXNTdGFydE5vZGVdPVwibm9kZS5pc1N0YXJ0Tm9kZVwiIFtpc1N1YmZsb3ddPVwidHJ1ZVwiXG4gICAgICAgIChzdGFnZVByb3BlcnRpZXNVcGRhdGVkKT1cIm9uU3RhZ2VQcm9wZXJ0aWVzVXBkYXRlZCgkZXZlbnQpXCIgKHNob3dTaGllbGREaWFsb2cpPVwib25TaG93U2hpZWxkRGlhbG9nKCRldmVudClcIlxuICAgICAgICAoc2hvd0VzY2FsYXRpb25EaWFsb2cpPVwib25TaG93RXNjYWxhdGlvbkRpYWxvZygkZXZlbnQpXCIgKHNob3dGb3JtRGlhbG9nKT1cIlxuICAgICAgICAgIHRvZ2dsZVN0YXJ0Tm9kZUZvcm1Qb3B1cCgkZXZlbnQsIG5vZGUueCwgbm9kZS55LCBzd2ltbGFuZS5vcmRlciwgbm9kZSlcbiAgICAgICAgXCI+PC9zdmc6Zz5cbiAgICAgIH1cblxuICAgICAgPCEtLSBDb25uZWN0aW9uIHBvaW50cyBmb3IgdGhpcyBub2RlIC0tPlxuICAgICAgQGZvciAocG9pbnQgb2Ygbm9kZS5jb25uZWN0aW9uUG9pbnRzIHx8IFtdOyB0cmFjayBwb2ludC5pZCkgeyBAaWZcbiAgICAgIChpc0Nvbm5lY3Rpb25Qb2ludFZpc2libGUobm9kZS5pZCkpIHtcbiAgICAgIDx1c2UgW2F0dHIuaHJlZl09XCInI2Nvbm5lY3Rpb24tcG9pbnQtdGVtcGxhdGUnXCIgW2F0dHIueF09XCJwb2ludC54XCIgW2F0dHIueV09XCJwb2ludC55XCIgW2F0dHIuaWRdPVwicG9pbnQuaWRcIlxuICAgICAgICAobW91c2Vkb3duKT1cInN0YXJ0Q29ubmVjdGlvbkRyYWcoJGV2ZW50LCBwb2ludCwgc3dpbWxhbmUub3JkZXIpXCIgLz5cbiAgICAgIH0gfVxuICAgIDwvZz5cbiAgICA8IS0tIEEgdHJhbnNwYXJlbnQgaG92ZXIgYXJlYSBmb3IgaW1wcm92ZWQgaG92ZXIgZGV0ZWN0aW9uIC0tPlxuICAgIDxyZWN0IFthdHRyLnhdPVwibm9kZS54IC0gMTBcIiBbYXR0ci55XT1cIm5vZGUueSAtIDEwXCIgW2F0dHIud2lkdGhdPVwibm9kZS53aWR0aCArIDIwXCIgW2F0dHIuaGVpZ2h0XT1cIm5vZGUuaGVpZ2h0ICsgMjBcIlxuICAgICAgZmlsbD1cInRyYW5zcGFyZW50XCIgKG1vdXNlb3Zlcik9XCJzaG93Q29ubmVjdGlvblBvaW50cyhub2RlLmlkLCBzd2ltbGFuZS5vcmRlcilcIlxuICAgICAgKG1vdXNlb3V0KT1cImhpZGVDb25uZWN0aW9uUG9pbnRzKG5vZGUuaWQpXCIgc3R5bGU9XCJwb2ludGVyLWV2ZW50czogbm9uZVwiIC8+XG4gICAgfSB9XG5cbiAgICA8IS0tIENvbm5lY3Rpb25zIC0tPlxuICAgIEBmb3IgKGNvbm5lY3Rpb24gb2Ygc3RhdGUuY29ubmVjdGlvbnM7IHRyYWNrIGNvbm5lY3Rpb24uaWQpIHtcbiAgICA8ZyBjbGFzcz1cImNvbm5lY3Rpb24tZWxlbWVudFwiPlxuICAgICAgPHBhdGggW2F0dHIuZF09XCJnZXRDb25uZWN0aW9uUGF0aEZvclNhdmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIyXCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICBtYXJrZXItZW5kPVwidXJsKCNhcnJvd2hlYWQpXCI+PC9wYXRoPlxuXG4gICAgICA8IS0tIENvbm5lY3Rpb24gTGFiZWwgLS0+XG4gICAgICBAaWYgKGNvbm5lY3Rpb24uc291cmNlTm9kZUlkICYmIGNvbm5lY3Rpb24udGFyZ2V0Tm9kZUlkKSB7XG4gICAgICA8Zm9yZWlnbk9iamVjdCBbYXR0ci54XT1cImdldExhYmVsUG9zaXRpb24oY29ubmVjdGlvbikueFwiIFthdHRyLnldPVwiZ2V0TGFiZWxQb3NpdGlvbihjb25uZWN0aW9uKS55XCIgd2lkdGg9XCIxNTBcIlxuICAgICAgICBoZWlnaHQ9XCI0MFwiIHN0eWxlPVwib3ZlcmZsb3c6IHZpc2libGU7IHBvaW50ZXItZXZlbnRzOiBhbGw7XCIgW2F0dHIudHJhbnNmb3JtXT1cIid0cmFuc2xhdGUoLTc1LCAtMTApJ1wiPlxuICAgICAgICA8d2YtbGFiZWwtZWRpdG9yIFtsYWJlbF09XCJjb25uZWN0aW9uLmxhYmVsIHx8ICdOZXcgQWN0aW9uJ1wiIFt4XT1cIjBcIiBbeV09XCIwXCIgW2lzQ29ubmVjdGlvbl09XCJ0cnVlXCJcbiAgICAgICAgICAobGFiZWxDaGFuZ2UpPVwic2F2ZUNvbm5lY3Rpb25MYWJlbChjb25uZWN0aW9uLCAkZXZlbnQpXCIgKG9wZW5EaWFsb2cpPVwib25TaG93QWN0aW9uRGlhbG9nKGNvbm5lY3Rpb24pXCIgLz5cbiAgICAgIDwvZm9yZWlnbk9iamVjdD5cbiAgICAgIH1cbiAgICA8L2c+XG4gICAgfVxuXG4gICAgPCEtLSBDb25uZWN0aW9uIHByZXZpZXcgbGluZSAtLT5cbiAgICBAaWYgKHN0YXRlLmlzQ29ubmVjdGlvbkRyYWdnaW5nKCkpIHtcbiAgICA8Zz5cbiAgICAgIDxwYXRoIFthdHRyLmRdPVwiZ2V0Q29ubmVjdGlvblBhdGgoKVwiIHN0cm9rZT1cIiNEMzZDRkZcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWRhc2hhcnJheT1cIjUsNVwiIGZpbGw9XCJub25lXCI+PC9wYXRoPlxuICAgIDwvZz5cbiAgICB9XG4gIDwvc3ZnPlxuXG4gIDxkaXYgKm5nSWY9XCJwb3B1cFZpc2libGVcIiBbc3R5bGUucG9zaXRpb25dPVwiJ2Fic29sdXRlJ1wiIFtzdHlsZS5sZWZ0LnB4XT1cInBvcHVwWFwiIFtzdHlsZS50b3AucHhdPVwicG9wdXBZXCI+XG4gICAgPHZlcmJlbi1wb3AtVXAgW2Ryb3Bkb3duT3Blbl09XCJ0cnVlXCIgW2N1c3RvbVN0eWxlc109XCJ7ICd6LWluZGV4JzogJzk5JyB9XCIgW2VuYWJsZU1vdXNlTGVhdmVdPVwiZmFsc2VcIlxuICAgICAgKGRyb3Bkb3duT3BlbkNoYW5nZSk9XCIkZXZlbnQgPyBudWxsIDogaGlkZUNvbm5lY3Rpb25Qb3B1cCgpXCI+XG4gICAgICA8ZGl2IGRyb3Bkb3duLXRyaWdnZXIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+XG4gICAgICAgIDwhLS0gSGlkZGVuIHRyaWdnZXIgZWxlbWVudCAtLT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInAtMyBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgc2hhZG93LW1kXCIgZHJvcGRvd24tY29udGVudD5cbiAgICAgICAgPGg0IGNsYXNzPVwibWItMiBmb250LW1lZGl1bVwiPkNyZWF0ZSBDb25uZWN0aW9uPC9oND5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTJcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0eXBlIG9mIGFsbG93ZWROb2RlVHlwZXNcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJweC0zIHB5LTIgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCByb3VuZGVkIHRleHQtc20gaG92ZXI6YmctZ3JheS01MFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjcmVhdGVOb2RlQ29ubmVjdGlvbih0eXBlKVwiPlxuICAgICAgICAgICAgICBDcmVhdGUge3sgdHlwZSB8IHRpdGxlY2FzZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInB4LTMgcHktMiBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgdGV4dC1zbSBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICAgIChjbGljayk9XCJoaWRlQ29ubmVjdGlvblBvcHVwKClcIj5cbiAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvdmVyYmVuLXBvcC1VcD5cbiAgPC9kaXY+XG5cbiAgPGRpdiAqbmdJZj1cInNob3dTdGFydE5vZGVGb3JtUG9wdXBcIiBbc3R5bGUucG9zaXRpb25dPVwiJ2Fic29sdXRlJ1wiIFtzdHlsZS5sZWZ0LnB4XT1cInN0YXJ0Tm9kZUZvcm1Qb3B1cFhcIlxuICAgIFtzdHlsZS50b3AucHhdPVwic3RhcnROb2RlRm9ybVBvcHVwWVwiPlxuICAgIDx2ZXJiZW4tcG9wLVVwIFtkcm9wZG93bk9wZW5dPVwidHJ1ZVwiIFtjdXN0b21TdHlsZXNdPVwieyAnei1pbmRleCc6ICcxMDAnIH1cIj5cbiAgICAgIDxkaXYgZHJvcGRvd24tdHJpZ2dlciBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIj5cbiAgICAgICAgPCEtLSBIaWRkZW4gdHJpZ2dlciBlbGVtZW50IC0tPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwicC0zIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0yMDAgcm91bmRlZCBzaGFkb3ctbWQgdy02NFwiIGRyb3Bkb3duLWNvbnRlbnRcbiAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgei1pbmRleDogMTAwMFwiPlxuICAgICAgICA8aDQgY2xhc3M9XCJtYi0yIGZvbnQtbWVkaXVtXCI+U2VsZWN0IFdvcmtmbG93IEZvcm08L2g0PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNMb2FkaW5nU3RhcnROb2RlRm9ybXNcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTJcIj5cbiAgICAgICAgICBMb2FkaW5nIGZvcm1zLi4uXG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWlzTG9hZGluZ1N0YXJ0Tm9kZUZvcm1zXCIgY2xhc3M9XCJtYXgtaC00OCBvdmVyZmxvdy15LWF1dG9cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCBweC0zIHB5LTIgYmctZ3JheS01MCBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgdGV4dC1zbSBob3ZlcjpiZy1ncmF5LTUwIHRleHQtbGVmdFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RTdGFydE5vZGVGb3JtKG51bGwpXCI+XG4gICAgICAgICAgICAgIENsZWFyIGZvcm0gc2VsZWN0aW9uXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBmb3JtIG9mIHN0YXJ0Tm9kZUZvcm1zTGlzdFwiIGNsYXNzPVwibWItMVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInctZnVsbCBweC0zIHB5LTIgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCByb3VuZGVkIHRleHQtc20gaG92ZXI6YmctZ3JheS01MCB0ZXh0LWxlZnRcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdiZy1ibHVlLTUwICFib3JkZXItYmx1ZS01MDAgIWJvcmRlci0yIGZvbnQtc2VtaWJvbGQnOiBmb3JtPy5Db2RlID09PSBhY3RpdmVOb2RlRm9yRm9ybVNlbGVjdGlvbj8uc3RhZ2VEYXRhPy5mb3JtSWR9XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFN0YXJ0Tm9kZUZvcm0oZm9ybSlcIj5cbiAgICAgICAgICAgICAge3sgZm9ybS5OYW1lIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwic3RhcnROb2RlRm9ybXNMaXN0Lmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktMiB0ZXh0LWdyYXktNTAwXCI+XG4gICAgICAgICAgICBObyBmb3JtcyBhdmFpbGFibGVcbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3ZlcmJlbi1wb3AtVXA+XG4gIDwvZGl2PlxuXG4gIDxkaXYgKm5nSWY9XCJzaG93U3ViZmxvd1BvcHVwXCIgW3N0eWxlLnBvc2l0aW9uXT1cIidhYnNvbHV0ZSdcIiBbc3R5bGUubGVmdC5weF09XCJzdWJmbG93UG9wdXBYXCJcbiAgICBbc3R5bGUudG9wLnB4XT1cInN1YmZsb3dQb3B1cFlcIj5cbiAgICA8dmVyYmVuLXBvcC1VcCBbZHJvcGRvd25PcGVuXT1cInRydWVcIiBbY3VzdG9tU3R5bGVzXT1cInsgJ3otaW5kZXgnOiAnMTAwJyB9XCI+XG4gICAgICA8ZGl2IGRyb3Bkb3duLXRyaWdnZXIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCI+XG4gICAgICAgIDwhLS0gSGlkZGVuIHRyaWdnZXIgZWxlbWVudCAtLT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInAtMyBiZy13aGl0ZSBib3JkZXIgYm9yZGVyLWdyYXktMjAwIHJvdW5kZWQgc2hhZG93LW1kIHctNjRcIiBkcm9wZG93bi1jb250ZW50XG4gICAgICAgIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IHotaW5kZXg6IDEwMDBcIj5cbiAgICAgICAgPGg0IGNsYXNzPVwibWItMiBmb250LW1lZGl1bVwiPlNlbGVjdCBXb3JrZmxvdzwvaDQ+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJpc0xvYWRpbmdXb3JrZmxvd3NcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTJcIj5cbiAgICAgICAgICBMb2FkaW5nIHdvcmtmbG93cy4uLlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFpc0xvYWRpbmdXb3JrZmxvd3NcIiBjbGFzcz1cIm1heC1oLTQ4IG92ZXJmbG93LXktYXV0b1wiPlxuICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHdvcmtmbG93IG9mIHdvcmtmbG93c0xpc3RcIiBjbGFzcz1cIm1iLTFcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ3LWZ1bGwgcHgtMyBweS0yIGJnLXdoaXRlIGJvcmRlciBib3JkZXItZ3JheS0yMDAgcm91bmRlZCB0ZXh0LXNtIGhvdmVyOmJnLWdyYXktNTAgdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFN1YmZsb3dXb3JrZmxvdyh3b3JrZmxvdylcIj5cbiAgICAgICAgICAgICAge3sgd29ya2Zsb3cuTmFtZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cIndvcmtmbG93c0xpc3QubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS0yIHRleHQtZ3JheS01MDBcIj5cbiAgICAgICAgICAgIE5vIHdvcmtmbG93cyBhdmFpbGFibGVcbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3ZlcmJlbi1wb3AtVXA+XG4gIDwvZGl2PlxuXG4gIDxsaWItY29uZGl0aW9ucy1wb3B1cCBbdmlzaWJsZV09XCJzaG93RGVjaXNpb25Db25kaXRpb25EaWFsb2dcIiBbZGVjaXNpb25Ob2RlSWRdPVwiYWN0aXZlRGVjaXNpb25Ob2RlSWRcIlxuICAgIFtuZXdDb25uZWN0aW9uSWRdPVwiYWN0aXZlQ29ubmVjdGlvbklkXCIgW3BvcHVwWF09XCJkZWNpc2lvbkNvbmRpdGlvblBvcHVwWFwiIFtwb3B1cFldPVwiZGVjaXNpb25Db25kaXRpb25Qb3B1cFlcIlxuICAgIChjbG9zZWQpPVwib25EZWNpc2lvbkNvbmRpdGlvbkNhbmNlbGxlZCgpXCIgKHNhdmVkKT1cIm9uRGVjaXNpb25Db25kaXRpb25TYXZlZCgkZXZlbnQpXCI+PC9saWItY29uZGl0aW9ucy1wb3B1cD5cblxuICA8IS0tIDxsaWItZGVjaXNpb24tcG9wdXBcbiAgICBbdmlzaWJsZV09XCJzaG93Q29uZGl0aW9uc0RpYWxvZ1wiXG4gICAgW2RlY2lzaW9uTm9kZUlkXT1cImFjdGl2ZURlY2lzaW9uTm9kZUlkXCJcbiAgICBbcG9wdXBYXT1cImRlY2lzaW9uQ29uZGl0aW9uUG9wdXBYXCJcbiAgICBbcG9wdXBZXT1cImRlY2lzaW9uQ29uZGl0aW9uUG9wdXBZXCJcbiAgICAoY2xvc2VkKT1cIm9uRGVjaXNpb25Db25kaXRpb25DYW5jZWxsZWQoKVwiXG4gID48L2xpYi1kZWNpc2lvbi1wb3B1cD4gLS0+XG5cbiAgPGxpYi1zdGFnZS1kaWFsb2cgW3Zpc2libGVdPVwic2hvd1N0YWdlRGlhbG9nTG9jYWxcIiBbc3RhZ2VEYXRhXT1cImFjdGl2ZVN0YWdlRGF0YSB8fCB7fVwiXG4gICAgKGNsb3NlZCk9XCJvblN0YWdlRGlhbG9nQ2xvc2VkKClcIiAoc2F2ZWQpPVwib25TdGFnZURpYWxvZ1NhdmVkKCRldmVudClcIj48L2xpYi1zdGFnZS1kaWFsb2c+XG5cbiAgPGxpYi1hY3Rpb24tZGlhbG9nIFt2aXNpYmxlXT1cInNob3dBY3Rpb25EaWFsb2dMb2NhbFwiIFthY3Rpb25EYXRhXT1cImFjdGl2ZUFjdGlvbkRhdGFcIiAoY2xvc2VkKT1cIm9uQWN0aW9uRGlhbG9nQ2xvc2VkKClcIlxuICAgIChzYXZlZCk9XCJvbkFjdGlvbkRpYWxvZ1NhdmVkKCRldmVudClcIj48L2xpYi1hY3Rpb24tZGlhbG9nPlxuXG4gIDxsaWItZXNjYWxhdGlvbi1kaWFsb2cgW3Zpc2libGVdPVwic2hvd0VzY2FsYXRpb25EaWFsb2dMb2NhbFwiIFt0eXBlXT1cImFjdGl2ZUVzY2FsYXRpb25UeXBlKCkhXCJcbiAgICBbc3RhZ2VDb2RlXT1cImFjdGl2ZVN0YWdlQ29kZSgpIHx8ICcnXCIgW3dvcmtmbG93Q29kZV09XCJzdGF0ZS53b3JrZmxvdz8uQ29kZSB8fCAnJ1wiXG4gICAgKGNsb3NlZCk9XCJvbkVzY2FsYXRpb25EaWFsb2dDbG9zZWQoKVwiPjwvbGliLWVzY2FsYXRpb24tZGlhbG9nPlxuPC9kaXY+XG4iXX0=