UNPKG

iamferraz-gantt-chart

Version:

Gantt Chart Component using Echarts library

418 lines 65.7 kB
import * as echarts from 'echarts/core'; import { DateManipulator } from './date-manipulator'; import { TaskDataManipulator } from './task-data-manipulator'; export class GanttRenderers { constructor(taskData, mappedData, colours, dateFormat, heightRatio, translation, enableGroup = true, darkTheme = false) { //normal|dark this.arrowColors = ["#000", "#fff"]; this.zebraColor = [["#f2f2f2", "#e6e6e6"], ["#212529", "#2C3034"]]; this._taskData = taskData; this._mappedData = mappedData; this.taskDataManipulator = new TaskDataManipulator(colours, enableGroup); this.DATE_FORMAT = dateFormat; this.HEIGHT_RATIO = heightRatio; this._darkTheme = darkTheme; this._enableGroup = enableGroup; this._translation = translation; } renderGanttItem(params, api) { var index = api.value(0); var taskName = api.value(1); var timeStart = api.coord([api.value(2), index]); var timeEnd = api.coord([api.value(3), index]); var taskId = api.value(4); var donePercentage = api.value(5); var groupColor = api.value(10); var barLength = timeEnd[0] - timeStart[0]; // Get the heigth corresponds to length 1 on y axis. var barHeight = api.size([0, 1])[1] * this.HEIGHT_RATIO; var x = timeStart[0]; var y = (timeStart[1] - barHeight) - (barHeight / 3); var taskNameWidth = echarts.format.getTextRect(taskName).width; var text = (barLength > taskNameWidth + 40 && x + barLength >= 180) ? taskName : ''; var rectNormal = this.clipRectByRect(params, { x: x, y: y, width: (barLength), height: barHeight }); var rectText = this.clipRectByRect(params, { x: x, y: y, width: (barLength), height: barHeight }); var rectPercent = this.clipRectByRect(params, { x: x, y: y, width: (barLength) * donePercentage / 100, height: 3 }); return { type: 'group', children: [{ type: 'rect', ignore: !rectNormal, shape: rectNormal, style: api.style({ fill: groupColor }) }, { type: 'rect', ignore: !rectText, shape: rectText, style: api.style({ fill: 'transparent', stroke: 'transparent', text: text, textFill: '#fff' }) }, { type: 'rect', ignore: !rectPercent, shape: rectPercent, style: api.style({ fill: 'rgba(214, 40, 40, 1)', stroke: 'transparent', }) }] }; } renderAxisLabelItem(params, api) { //console.log("renderAxisLabelItem", api.value(0), api.value(1), api); //console.log("api.coord([0, api.value(0)])", api.coord([0, api.value(0)])) var index = api.value(0); var taskName = api.value(1); var taskId = api.value(4); var donePercentage = api.value(5); var start = api.value(2); var end = api.value(3); var owner = api.value(6); var image = api.value(7); var groupName = api.value(8); var isToDrawGroup = api.value(9); var groupColor = api.value(10); //console.log(taskId, groupName, isToDrawGroup, groupColor) var daysToEnd = DateManipulator.daysLeft(end, this._translation); var y = api.coord([0, index])[1]; var barHeight = api.size([0, 1])[1]; if (donePercentage == 100) { daysToEnd = (this._translation ? this._translation.FINISHED : "FINISHED"); } let groupedElement = { type: 'group', silent: true, position: [ 10, y ], children: [{ type: 'rect', shape: { x: 0, y: (params.coordSys.y - 2 * barHeight) + (barHeight / 6), width: 210, height: 46 }, style: { fill: groupColor, } }, { type: 'image', //left: 'center', // Position at the center horizontally. //bottom: '10%', // Position beyond the bottom boundary 10%. style: { image: image, x: 5, y: (params.coordSys.y - 2 * barHeight) + (barHeight / 3), width: 25, height: 25 } }, { type: 'text', style: { x: 35, y: (params.coordSys.y - 2 * barHeight) + (barHeight * 0.5), text: taskName, textVerticalAlign: 'bottom', textAlign: 'left', textFill: '#000' } }, { type: 'text', style: { x: 35, y: (params.coordSys.y - 2 * barHeight) + (barHeight * 0.7), textVerticalAlign: 'bottom', textAlign: 'left', text: daysToEnd, textFill: '#000', fontSize: 9, } }] }; if (this._enableGroup) { if (isToDrawGroup == 1) { // group agrupator (Vertical rectangle) groupedElement.children.push({ type: 'rect', shape: { x: 105, y: (params.coordSys.y - 2 * barHeight) - (barHeight / 3), width: 10, height: 46 }, style: { fill: groupColor, } }); } else { groupedElement.children.push({ type: 'text', style: { x: -10, y: (params.coordSys.y - 2 * barHeight) + (barHeight / 9), text: groupName, textVerticalAlign: 'bottom', textAlign: 'left', textFill: this._darkTheme ? '#fff' : '#000' } }); } } return groupedElement; } renderArrowsItem(params, api) { var index = api.value(0); var taskName = api.value(1); var timeStart = api.coord([api.value(2), index]); var timeEnd = api.coord([api.value(3), index]); var taskId = api.value(4); var barLength = timeEnd[0] - timeStart[0]; // Get the heigth corresponds to length 1 on y axis. var barHeight = api.size([0, 1])[1] * this.HEIGHT_RATIO; var x = timeStart[0]; var y = (timeStart[1] - barHeight) - (barHeight / 3); //the api.value only suports numeric and string values to get... to get taskDependencies I need to get from my real data variable var currentData = this._taskData[params.dataIndex]; var taskDependencies = currentData.taskDependencies; let links = []; let dependencies = taskDependencies; for (let j = 0; j < dependencies.length; j++) { let taskFather = this.taskDataManipulator.getTaskByIdInMappedData(this._mappedData, dependencies[j]); if (taskFather == null) continue; //console.log("dependencies", taskName, taskFather) var indexFather = taskFather[0]; //index var timeStartFather = api.coord([taskFather[2], indexFather]); var timeEndFather = api.coord([taskFather[3], indexFather]); var barLengthFather = timeEndFather[0] - timeStartFather[0]; // Get the heigth corresponds to length 1 on y axis. var barHeightFather = api.size([0, 1])[1] * this.HEIGHT_RATIO; var xFather = timeStartFather[0]; var yFather = (timeStartFather[1] - barHeightFather) - (barHeightFather / 3); let color = this._darkTheme ? this.arrowColors[1] : this.arrowColors[0]; let arrow = {}; //condition to draw the arrow correctly when a dependent task is exactly below another task if (x < xFather + barLengthFather / 2) { if (y > yFather) { arrow = { type: 'polygon', shape: { points: [[xFather + barLengthFather / 2 - 5, (y) - 10], [xFather + barLengthFather / 2 + 5, (y) - 10], [xFather + barLengthFather / 2, (y)]] }, style: api.style({ fill: color, }) }; } else { arrow = { type: 'polygon', shape: { points: [[xFather + barLengthFather / 2 - 5, (y + barHeightFather + 10)], [xFather + barLengthFather / 2 + 5, (y + barHeightFather + 10)], [xFather + barLengthFather / 2, (y + barHeightFather)]] }, style: api.style({ fill: color, }) }; } } else { //draw normaly arrow = { type: 'polygon', shape: { points: [[x - 5, (y + barHeight / 2) - 5], [x - 5, (y + barHeight / 2) + 5], [x + 5, (y + barHeight / 2)]] }, style: api.style({ fill: color, }) }; } let verticalLine = { type: 'line', shape: { x1: xFather + barLengthFather / 2, y1: yFather + barHeightFather, x2: xFather + barLengthFather / 2, y2: y + barHeightFather / 2 }, style: api.style({ fill: color, stroke: color }) }; let horizontalLine = { type: 'line', shape: { x1: xFather + barLengthFather / 2, y1: y + barHeightFather / 2, x2: x, y2: y + barHeightFather / 2 }, style: api.style({ fill: color, stroke: color }) }; links.push({ type: 'group', children: [verticalLine, horizontalLine, arrow] }); } return { type: 'group', children: links }; } renderArrowsItem2(params, api) { var index = api.value(0); var taskName = api.value(1); var timeStart = api.coord([api.value(2), index]); var timeEnd = api.coord([api.value(3), index]); var taskId = api.value(4); var barLength = timeEnd[0] - timeStart[0]; // Get the heigth corresponds to length 1 on y axis. var barHeight = api.size([0, 1])[1] * this.HEIGHT_RATIO; var x = timeStart[0]; var y = timeStart[1] - barHeight; //the api.value only suports numeric and string values to get... to get taskDependencies I need to get from my real data variable var currentData = this._taskData[params.dataIndex]; var taskDependencies = currentData.taskDependencies; let links = []; let dependencies = taskDependencies; for (let j = 0; j < dependencies.length; j++) { let taskFather = this.taskDataManipulator.getTaskByIdInMappedData(this._mappedData, dependencies[j]); if (taskFather == null) continue; //console.log("dependencies", taskName, taskFather) var indexFather = taskFather[0]; //index var timeStartFather = api.coord([taskFather[2], indexFather]); var timeEndFather = api.coord([taskFather[3], indexFather]); var barLengthFather = timeEndFather[0] - timeStartFather[0]; // Get the heigth corresponds to length 1 on y axis. var barHeightFather = api.size([0, 1])[1] * this.HEIGHT_RATIO; var xFather = timeStartFather[0]; var yFather = timeStartFather[1] - barHeightFather; links.push({ type: 'group', children: [ { type: 'line', shape: { x1: xFather + barLengthFather, y1: yFather + barHeightFather / 2, x2: x, y2: yFather + barHeightFather / 2 }, style: api.style({ fill: "#000", stroke: "#000" }) }, { type: 'line', shape: { x1: x, y1: yFather + barHeightFather / 2, x2: x - 10, y2: y + barHeight / 2 }, style: api.style({ fill: "#000", stroke: "#000" }) }, { type: 'polygon', shape: { points: [[x - 5, (y + barHeight / 2) - 5], [x - 5, (y + barHeight / 2) + 10], [x + 5, (y + barHeight / 2)],] }, style: api.style({ fill: "#000", stroke: "#000" }) } ] }); } return { type: 'group', children: links }; } renderZebra(params, api) { var index = api.value(0); var timeToday = api.coord([new Date(), index]); var timeStart = api.coord([api.value(1), index]); var timeEnd = api.coord([api.value(2), index]); //if time start > timeToday we need to fix the bar lenght and x position var barLength = timeEnd[0] - (timeStart[0] > timeToday[0] ? timeToday[0] : timeStart[0]); // Get the heigth corresponds to length 1 on y axis. var barHeight = api.size([0, 1])[1]; var x = timeStart[0] > timeToday[0] ? timeToday[0] : timeStart[0]; var y = timeStart[1] - barHeight; //console.log("=======>",x, y) var rectNormal = this.clipRectByRect(params, { x: x, y: y, width: barLength, height: barHeight }); return { type: 'group', silent: true, children: [{ type: 'rect', ignore: !rectNormal, shape: rectNormal, style: api.style({ fill: this._darkTheme ? (index % 2 == 0 ? this.zebraColor[1][0] : this.zebraColor[1][1]) : (index % 2 == 0 ? this.zebraColor[0][0] : this.zebraColor[0][1]) }) }] }; } renderToday(params, api) { var today = api.coord([api.value(0), 0]); var barHeight = api.size([0, 1])[1]; var x = today[0]; var y = barHeight; var y_end = barHeight * 1000; let todayText = echarts.time.format((new Date()), this.DATE_FORMAT, false); var todayTextWidth = echarts.format.getTextRect(todayText).width; return { type: 'group', silent: true, children: [{ type: 'text', style: { x: x - todayTextWidth / 2, y: y, text: todayText, textVerticalAlign: 'bottom', textAlign: 'left', textFill: '#a14b27' } }, { type: 'line', shape: { x1: x, y1: y, x2: x, y2: y_end }, style: api.style({ fill: "#a14b27", stroke: "#a14b27" }) }] }; } clipRectByRect(params, rect) { return echarts.graphic.clipRectByRect(rect, { x: params.coordSys.x, y: params.coordSys.y, width: params.coordSys.width, height: params.coordSys.height }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtcmVuZGVyZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FudHQtY2hhcnQvc3JjL2xpYi9zaGFyZWQvZ2FudHQtcmVuZGVyZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUU5RCxNQUFNLE9BQU8sY0FBYztJQWN2QixZQUFZLFFBQW9CLEVBQUUsVUFBZ0IsRUFBRSxPQUFnQixFQUFFLFVBQWlCLEVBQUUsV0FBbUIsRUFBRSxXQUFnQixFQUFFLGNBQXNCLElBQUksRUFBRSxZQUFvQixLQUFLO1FBSnJMLGFBQWE7UUFDTCxnQkFBVyxHQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZDLGVBQVUsR0FBUyxDQUFDLENBQUMsU0FBUyxFQUFDLFNBQVMsQ0FBQyxFQUFDLENBQUMsU0FBUyxFQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7UUFHcEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUE7UUFDekIsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUE7UUFDN0IsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFBO1FBQ3hFLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFBO1FBQzdCLElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFBO1FBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO1FBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFBO1FBQy9CLElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFBO0lBQ25DLENBQUM7SUFFRCxlQUFlLENB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LEVBQUUsUUFBUTt3QkFDM0IsU0FBUyxFQUFFLE1BQU07d0JBQ2pCLFFBQVEsRUFBRSxTQUFTO3FCQUN0QjtpQkFDSixFQUFDO29CQUNFLElBQUksRUFBRSxNQUFNO29CQUNaLEtBQUssRUFBRTt3QkFDSCxFQUFFLEVBQUUsQ0FBQzt3QkFDTCxFQUFFLEVBQUUsQ0FBQzt3QkFDTCxFQUFFLEVBQUUsQ0FBQzt3QkFDTCxFQUFFLEVBQUUsS0FBSztxQkFDWjtvQkFDRCxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQzt3QkFDYixJQUFJLEVBQUUsU0FBUzt3QkFDZixNQUFNLEVBQUUsU0FBUztxQkFDcEIsQ0FBQztpQkFDTCxDQUFDO1NBQ0wsQ0FBQztJQUNOLENBQUM7SUFFRCxjQUFjLENBQUMsTUFBVSxFQUFFLElBQVE7UUFDL0IsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUU7WUFDeEMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwQixDQUFDLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BCLEtBQUssRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUs7WUFDNUIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTTtTQUNqQyxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBlY2hhcnRzIGZyb20gJ2VjaGFydHMvY29yZSc7XHJcbmltcG9ydCB7IFRhc2tNb2RlbCB9IGZyb20gJy4uL21vZGVscy90YXNrLWRhdGEubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXRlTWFuaXB1bGF0b3IgfSBmcm9tICcuL2RhdGUtbWFuaXB1bGF0b3InO1xyXG5pbXBvcnQgeyBUYXNrRGF0YU1hbmlwdWxhdG9yIH0gZnJvbSAnLi90YXNrLWRhdGEtbWFuaXB1bGF0b3InO1xyXG5cclxuZXhwb3J0IGNsYXNzIEdhbnR0UmVuZGVyZXJzIHtcclxuICAgIHByaXZhdGUgSEVJR0hUX1JBVElPOm51bWJlclxyXG4gICAgcHJpdmF0ZSBEQVRFX0ZPUk1BVDpzdHJpbmdcclxuICAgIHByaXZhdGUgX2RhcmtUaGVtZTpib29sZWFuXHJcbiAgICBwcml2YXRlIF9lbmFibGVHcm91cDpib29sZWFuXHJcbiAgICBwcml2YXRlIF90YXNrRGF0YTpUYXNrTW9kZWxbXVxyXG4gICAgcHJpdmF0ZSBfbWFwcGVkRGF0YTphbnlbXVxyXG4gICAgcHJpdmF0ZSB0YXNrRGF0YU1hbmlwdWxhdG9yOlRhc2tEYXRhTWFuaXB1bGF0b3JcclxuICAgIHByaXZhdGUgX3RyYW5zbGF0aW9uOmFueVxyXG5cclxuICAgIC8vbm9ybWFsfGRhcmtcclxuICAgIHByaXZhdGUgYXJyb3dDb2xvcnM6c3RyaW5nW10gPSBbXCIjMDAwXCIsIFwiI2ZmZlwiXVxyXG4gICAgcHJpdmF0ZSB6ZWJyYUNvbG9yOmFueVtdID0gW1tcIiNmMmYyZjJcIixcIiNlNmU2ZTZcIl0sW1wiIzIxMjUyOVwiLFwiIzJDMzAzNFwiXV1cclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih0YXNrRGF0YTpUYXNrTW9kZWxbXSwgbWFwcGVkRGF0YTphbnlbXSwgY29sb3VyczpzdHJpbmdbXSwgZGF0ZUZvcm1hdDpzdHJpbmcsIGhlaWdodFJhdGlvIDpudW1iZXIsIHRyYW5zbGF0aW9uOiBhbnksIGVuYWJsZUdyb3VwOmJvb2xlYW4gPSB0cnVlLCBkYXJrVGhlbWU6Ym9vbGVhbiA9IGZhbHNlKXtcclxuICAgICAgICB0aGlzLl90YXNrRGF0YSA9IHRhc2tEYXRhXHJcbiAgICAgICAgdGhpcy5fbWFwcGVkRGF0YSA9IG1hcHBlZERhdGFcclxuICAgICAgICB0aGlzLnRhc2tEYXRhTWFuaXB1bGF0b3IgPSBuZXcgVGFza0RhdGFNYW5pcHVsYXRvcihjb2xvdXJzLCBlbmFibGVHcm91cClcclxuICAgICAgICB0aGlzLkRBVEVfRk9STUFUID0gZGF0ZUZvcm1hdFxyXG4gICAgICAgIHRoaXMuSEVJR0hUX1JBVElPID0gaGVpZ2h0UmF0aW9cclxuICAgICAgICB0aGlzLl9kYXJrVGhlbWUgPSBkYXJrVGhlbWVcclxuICAgICAgICB0aGlzLl9lbmFibGVHcm91cCA9IGVuYWJsZUdyb3VwXHJcbiAgICAgICAgdGhpcy5fdHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvblxyXG4gICAgfVxyXG5cclxuICAgIHJlbmRlckdhbnR0SXRlbShwYXJhbXM6YW55LCBhcGk6YW55KSB7XHJcbiAgICAgICAgdmFyIGluZGV4ID0gYXBpLnZhbHVlKDApO1xyXG4gICAgICAgIHZhciB0YXNrTmFtZSA9IGFwaS52YWx1ZSgxKTtcclxuICAgICAgICBcclxuICAgICAgICB2YXIgdGltZVN0YXJ0ID0gYXBpLmNvb3JkKFthcGkudmFsdWUoMiksIGluZGV4XSk7XHJcbiAgICAgICAgdmFyIHRpbWVFbmQgPSBhcGkuY29vcmQoW2FwaS52YWx1ZSgzKSwgaW5kZXhdKTtcclxuICAgICAgICB2YXIgdGFza0lkID0gYXBpLnZhbHVlKDQpO1xyXG4gICAgICAgIHZhciBkb25lUGVyY2VudGFnZSA9IGFwaS52YWx1ZSg1KVxyXG4gICAgICAgIHZhciBncm91cENvbG9yID0gYXBpLnZhbHVlKDEwKVxyXG4gICAgICAgIFxyXG4gICAgICAgIHZhciBiYXJMZW5ndGggPSB0aW1lRW5kWzBdIC0gdGltZVN0YXJ0WzBdO1xyXG4gICAgICAgIC8vIEdldCB0aGUgaGVpZ3RoIGNvcnJlc3BvbmRzIHRvIGxlbmd0aCAxIG9uIHkgYXhpcy5cclxuICAgICAgICB2YXIgYmFySGVpZ2h0ID0gYXBpLnNpemUoWzAsIDFdKVsxXSAqIHRoaXMuSEVJR0hUX1JBVElPO1xyXG4gICAgICAgIHZhciB4ID0gdGltZVN0YXJ0WzBdIDtcclxuICAgICAgICB2YXIgeSA9ICh0aW1lU3RhcnRbMV0gLSBiYXJIZWlnaHQpLShiYXJIZWlnaHQvMyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdmFyIHRhc2tOYW1lV2lkdGggPSBlY2hhcnRzLmZvcm1hdC5nZXRUZXh0UmVjdCh0YXNrTmFtZSkud2lkdGg7XHJcbiAgICAgICAgdmFyIHRleHQgPSAoYmFyTGVuZ3RoID4gdGFza05hbWVXaWR0aCArIDQwICYmIHggKyBiYXJMZW5ndGggPj0gMTgwKVxyXG4gICAgICAgICAgICA/IHRhc2tOYW1lIDogJyc7XHJcbiAgICBcclxuICAgICAgICB2YXIgcmVjdE5vcm1hbCA9IHRoaXMuY2xpcFJlY3RCeVJlY3QocGFyYW1zLCB7XHJcbiAgICAgICAgICAgIHg6IHgsIHk6IHksIHdpZHRoOiAoYmFyTGVuZ3RoKSwgaGVpZ2h0OiBiYXJIZWlnaHRcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgcmVjdFRleHQgPSB0aGlzLmNsaXBSZWN0QnlSZWN0KHBhcmFtcywge1xyXG4gICAgICAgICAgICB4OiB4LCB5OiB5LCB3aWR0aDogKGJhckxlbmd0aCksIGhlaWdodDogYmFySGVpZ2h0XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIHJlY3RQZXJjZW50ID0gdGhpcy5jbGlwUmVjdEJ5UmVjdChwYXJhbXMsIHtcclxuICAgICAgICAgICAgeDogeCwgeTogeSwgd2lkdGg6IChiYXJMZW5ndGgpKmRvbmVQZXJjZW50YWdlLzEwMCwgaGVpZ2h0OiAzXHJcbiAgICAgICAgfSk7XHJcbiAgICBcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB0eXBlOiAnZ3JvdXAnLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW3tcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcclxuICAgICAgICAgICAgICAgIGlnbm9yZTogIXJlY3ROb3JtYWwsXHJcbiAgICAgICAgICAgICAgICBzaGFwZTogcmVjdE5vcm1hbCxcclxuICAgICAgICAgICAgICAgIHN0eWxlOiBhcGkuc3R5bGUoe1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6IGdyb3VwQ29sb3JcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcclxuICAgICAgICAgICAgICAgIGlnbm9yZTogIXJlY3RUZXh0LFxyXG4gICAgICAgICAgICAgICAgc2hhcGU6IHJlY3RUZXh0LFxyXG4gICAgICAgICAgICAgICAgc3R5bGU6IGFwaS5zdHlsZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3RyYW5zcGFyZW50JyxcclxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6ICd0cmFuc3BhcmVudCcsXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogdGV4dCxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0RmlsbDogJyNmZmYnXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVjdCcsXHJcbiAgICAgICAgICAgICAgICBpZ25vcmU6ICFyZWN0UGVyY2VudCxcclxuICAgICAgICAgICAgICAgIHNoYXBlOiByZWN0UGVyY2VudCxcclxuICAgICAgICAgICAgICAgIHN0eWxlOiBhcGkuc3R5bGUoe1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGw6ICdyZ2JhKDIxNCwgNDAsIDQwLCAxKScsXHJcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAndHJhbnNwYXJlbnQnLFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfV1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHJlbmRlckF4aXNMYWJlbEl0ZW0ocGFyYW1zOmFueSwgYXBpOmFueSkge1xyXG4gICAgXHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlckF4aXNMYWJlbEl0ZW1cIiwgYXBpLnZhbHVlKDApLCBhcGkudmFsdWUoMSksIGFwaSk7XHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcImFwaS5jb29yZChbMCwgYXBpLnZhbHVlKDApXSlcIiwgYXBpLmNvb3JkKFswLCBhcGkudmFsdWUoMCldKSlcclxuICAgICAgICB2YXIgaW5kZXggPSBhcGkudmFsdWUoMClcclxuICAgICAgICB2YXIgdGFza05hbWUgPSBhcGkudmFsdWUoMSlcclxuICAgICAgICB2YXIgdGFza0lkID0gYXBpLnZhbHVlKDQpXHJcbiAgICAgICAgdmFyIGRvbmVQZXJjZW50YWdlID0gYXBpLnZhbHVlKDUpXHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gYXBpLnZhbHVlKDIpXHJcbiAgICAgICAgdmFyIGVuZCA9IGFwaS52YWx1ZSgzKVxyXG4gICAgICAgIHZhciBvd25lciA9IGFwaS52YWx1ZSg2KVxyXG4gICAgICAgIHZhciBpbWFnZSA9IGFwaS52YWx1ZSg3KVxyXG4gICAgICAgIHZhciBncm91cE5hbWUgPSBhcGkudmFsdWUoOClcclxuICAgICAgICB2YXIgaXNUb0RyYXdHcm91cCA9IGFwaS52YWx1ZSg5KVxyXG4gICAgICAgIHZhciBncm91cENvbG9yID0gYXBpLnZhbHVlKDEwKVxyXG4gICAgICAgIFxyXG4gICAgICAgIC8vY29uc29sZS5sb2codGFza0lkLCBncm91cE5hbWUsIGlzVG9EcmF3R3JvdXAsIGdyb3VwQ29sb3IpXHJcbiAgICAgICAgdmFyIGRheXNUb0VuZCA9IERhdGVNYW5pcHVsYXRvci5kYXlzTGVmdChlbmQsdGhpcy5fdHJhbnNsYXRpb24pXHJcbiAgICAgICAgdmFyIHkgPSBhcGkuY29vcmQoWzAsIGluZGV4XSlbMV07XHJcbiAgICAgICAgdmFyIGJhckhlaWdodCA9IGFwaS5zaXplKFswLCAxXSlbMV07XHJcblxyXG4gICAgICAgIGlmKGRvbmVQZXJjZW50YWdlID09IDEwMCl7XHJcbiAgICAgICAgICAgIGRheXNUb0VuZCA9ICh0aGlzLl90cmFuc2xhdGlvbiA/IHRoaXMuX3RyYW5zbGF0aW9uLkZJTklTSEVEIDogXCJGSU5JU0hFRFwiKVxyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBsZXQgZ3JvdXBlZEVsZW1lbnQgPSB7XHJcbiAgICAgICAgICAgIHR5cGU6ICdncm91cCcsXHJcbiAgICAgICAgICAgIHNpbGVudDogdHJ1ZSxcclxuICAgICAgICAgICAgcG9zaXRpb246IFtcclxuICAgICAgICAgICAgICAgIDEwLFxyXG4gICAgICAgICAgICAgICAgeVxyXG4gICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW3tcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdyZWN0JyxcclxuICAgICAgICAgICAgICAgIHNoYXBlOiB7eDogMCwgeTogKHBhcmFtcy5jb29yZFN5cy55LTIqYmFySGVpZ2h0KSsoYmFySGVpZ2h0LzYpLCB3aWR0aDogMjEwLCBoZWlnaHQ6IDQ2fSxcclxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogZ3JvdXBDb2xvcixcclxuICAgICAgICAgICAgICAgICAgICAvL3N0cm9rZTogJ3JnYigyNDcsIDEyNywgMCknLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vbGluZVdpZHRoOiAyLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2hhZG93Qmx1cjogOCxcclxuICAgICAgICAgICAgICAgICAgICAvL3NoYWRvd09mZnNldFg6IDMsXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zaGFkb3dPZmZzZXRZOiAzLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2hhZG93Q29sb3I6ICdyZ2JhKDAsMCwwLDAuMyknXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0seyAvLyBQb3NpdGlvbiB0aGUgaW1hZ2UgYXQgdGhlIGJvdHRvbSBjZW50ZXIgb2YgaXRzIGNvbnRhaW5lci5cclxuICAgICAgICAgICAgICAgIHR5cGU6ICdpbWFnZScsXHJcbiAgICAgICAgICAgICAgICAvL2xlZnQ6ICdjZW50ZXInLCAvLyBQb3NpdGlvbiBhdCB0aGUgY2VudGVyIGhvcml6b250YWxseS5cclxuICAgICAgICAgICAgICAgIC8vYm90dG9tOiAnMTAlJywgIC8vIFBvc2l0aW9uIGJleW9uZCB0aGUgYm90dG9tIGJvdW5kYXJ5IDEwJS5cclxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2U6IGltYWdlLFxyXG4gICAgICAgICAgICAgICAgICAgIHg6IDUsXHJcbiAgICAgICAgICAgICAgICAgICAgeTogKHBhcmFtcy5jb29yZFN5cy55LTIqYmFySGVpZ2h0KSsoYmFySGVpZ2h0LzMpLFxyXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAyNSxcclxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IDI1XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcclxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgeDogMzUsXHJcbiAgICAgICAgICAgICAgICAgICAgeTogKHBhcmFtcy5jb29yZFN5cy55LTIqYmFySGVpZ2h0KSsoYmFySGVpZ2h0KjAuNSksXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogdGFza05hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dFZlcnRpY2FsQWxpZ246ICdib3R0b20nLFxyXG4gICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxyXG4gICAgICAgICAgICAgICAgICAgIHRleHRGaWxsOiAnIzAwMCdcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RleHQnLFxyXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcclxuICAgICAgICAgICAgICAgICAgICB4OiAzNSxcclxuICAgICAgICAgICAgICAgICAgICB5OiAocGFyYW1zLmNvb3JkU3lzLnktMipiYXJIZWlnaHQpKyhiYXJIZWlnaHQqMC43KSxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0VmVydGljYWxBbGlnbjogJ2JvdHRvbScsXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnbGVmdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogZGF5c1RvRW5kLFxyXG4gICAgICAgICAgICAgICAgICAgIHRleHRGaWxsOiAnIzAwMCcsXHJcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDksXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1dXHJcbiAgICAgICAgfTtcclxuICAgICAgICBcclxuICAgICAgICBpZih0aGlzLl9lbmFibGVHcm91cCl7XHJcbiAgICAgICAgICAgIGlmKGlzVG9EcmF3R3JvdXAgPT0gMSl7IC8vIGdyb3VwIGFncnVwYXRvciAoVmVydGljYWwgcmVjdGFuZ2xlKVxyXG4gICAgICAgICAgICAgICAgZ3JvdXBlZEVsZW1lbnQuY2hpbGRyZW4ucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlY3QnLFxyXG4gICAgICAgICAgICAgICAgICAgIHNoYXBlOiB7eDogMTA1LCB5OiAocGFyYW1zLmNvb3JkU3lzLnktMipiYXJIZWlnaHQpLShiYXJIZWlnaHQvMyksIHdpZHRoOiAxMCwgaGVpZ2h0OiA0Nn0sXHJcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogZ3JvdXBDb2xvcixcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgICAgICAgIGdyb3VwZWRFbGVtZW50LmNoaWxkcmVuLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcclxuICAgICAgICAgICAgICAgICAgICBzdHlsZToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiAtMTAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IChwYXJhbXMuY29vcmRTeXMueS0yKmJhckhlaWdodCkrKGJhckhlaWdodC85KSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogZ3JvdXBOYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0VmVydGljYWxBbGlnbjogJ2JvdHRvbScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0RmlsbDogdGhpcy5fZGFya1RoZW1lID8gJyNmZmYnIDogJyMwMDAnXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gZ3JvdXBlZEVsZW1lbnRcclxuICAgIH1cclxuXHJcbiAgICByZW5kZXJBcnJvd3NJdGVtKHBhcmFtczphbnksIGFwaTphbnkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgdmFyIGluZGV4ID0gYXBpLnZhbHVlKDApO1xyXG4gICAgICAgIHZhciB0YXNrTmFtZSA9IGFwaS52YWx1ZSgxKTtcclxuICAgICAgICB2YXIgdGltZVN0YXJ0ID0gYXBpLmNvb3JkKFthcGkudmFsdWUoMiksIGluZGV4XSk7XHJcbiAgICAgICAgdmFyIHRpbWVFbmQgPSBhcGkuY29vcmQoW2FwaS52YWx1ZSgzKSwgaW5kZXhdKTtcclxuICAgICAgICB2YXIgdGFza0lkID0gYXBpLnZhbHVlKDQpO1xyXG4gICAgICAgIFx