ng-d3-graphs
Version:
<img src="./assets/ng-d3.png" alt="drawing" width="250" height="250"/>
153 lines • 20.3 kB
JavaScript
import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import * as d3 from 'd3';
import * as i0 from "@angular/core";
export var AxisDirection;
(function (AxisDirection) {
AxisDirection["top"] = "top";
AxisDirection["right"] = "right";
AxisDirection["bottom"] = "bottom";
AxisDirection["left"] = "left";
})(AxisDirection || (AxisDirection = {}));
let D3Service = class D3Service {
constructor() { }
translate(x, y) {
return `translate(${x}, ${y})`;
}
factoryAxis(scale, direction) {
switch (direction) {
case AxisDirection.top:
return d3.axisTop(scale);
case AxisDirection.right:
return d3.axisRight(scale);
case AxisDirection.bottom:
return d3.axisBottom(scale);
case AxisDirection.left:
return d3.axisLeft(scale);
default:
return new Error('No axis Direction Provided');
}
}
factoryLine() {
return d3.line().x((d) => d.x).y((d) => d.y);
}
// ==== Axis =====
scaleLinearX(labels, width) {
return d3.scaleLinear()
.domain(d3.extent(labels)) // does the magic for adjustable axis
.range([0, width]);
}
scaleLinearY(data, height) {
return d3.scaleLinear()
.domain(d3.extent(data)) // does the magic for adjustable axis
.range([height, 0]);
}
scaleBandX(labels, width) {
return d3.scaleBand().domain(labels).rangeRound([0, width]).padding(0.1);
}
scaleLinearYRangeRound(data, height) {
return d3.scaleLinear().domain([0, Math.max(...data)]).rangeRound([
height, 0
]);
}
addLabelAxisY(svg, height, options) {
svg.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 0 - options.margin.left)
.attr('x', 0 - height / 2)
.attr('dy', '1em')
.style('text-anchor', 'middle')
.text(options.yAxisLabel);
}
addLabelAxisX(svg, width, height, options) {
svg.append('text')
.attr('transform', 'translate(' + width / 2 + ' ,' + (height + options.margin.top) +
')')
.style('text-anchor', 'middle')
.text(options.xAxisLabel);
}
getViewBoxDefault(options) {
const res = {
minX: -options.margin.left,
minY: -25,
width: options.width,
height: options.height - options.margin.top,
};
return res;
}
removeAxisTicks(axis) {
axis.selectAll('.tick').selectAll('line').remove();
}
changeAxisColor(axis, config) {
axis.select('path')
.attr('color', config.color)
.attr('opacity', config.opacity)
.attr('rendering', config.rendering)
.attr('stroke-width', config.strokeWidth);
}
getXaxisTime(svg, height, x, timeFormat, xAxisTicks) {
return svg.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat(timeFormat))
.ticks(xAxisTicks));
}
hideTooltip(tooltipText, tooltip) {
tooltipText.selectAll('tspan').remove();
tooltip.attr('visibility', 'hidden');
}
showTooltip(d, xScale, yScale, tooltip, tooltipRect, tooltipText, formatTime) {
const xPos = xScale(d.x) - 150 / 2;
const yPos = yScale(d.y) + 10;
tooltip.attr('transform', `translate(${xPos}, ${yPos})`)
.attr('is', true)
.attr('visibility', 'visible');
tooltipRect.attr('opacity', 0.7);
tooltipText.attr('tranform', 'translate(75,30)')
.attr('fill', 'white')
.attr('font-size', 10)
.attr('font-family', `'Roboto', 'sans-serif'`);
tooltipText.append('tspan')
.attr('text-anchor', 'middle')
.attr('is', true)
.attr('x', 25)
.attr('y', -5)
.text(`${formatTime(d.x)}`);
tooltipText.append('tspan')
.attr('text-anchor', 'middle')
.attr('is', true)
.attr('x', 20)
.attr('dy', 15)
.text(`${d.y}`);
}
addTooltip(container) {
const tooltipConfig = {
width: 100,
height: 40,
fill: '#333',
opacity: 0.7,
rx: 15,
text: {
translateX: 10,
translateY: 20,
},
};
const tooltip = d3.select(container.nativeElement).select('svg').append('g');
const tooltipRect = tooltip.append('rect')
.attr('width', tooltipConfig.width)
.attr('height', tooltipConfig.height)
.attr('fill', tooltipConfig.fill)
.attr('opacity', 0)
.attr('rx', tooltipConfig.rx);
const tooltipText = tooltip.append('text').attr('transform', `translate(
${tooltipConfig.text.translateX},
${tooltipConfig.text.translateY})`);
return { tooltip, tooltipRect, tooltipText, tooltipConfig };
}
};
D3Service.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function D3Service_Factory() { return new D3Service(); }, token: D3Service, providedIn: "root" });
D3Service = tslib_1.__decorate([
Injectable({ providedIn: 'root' })
], D3Service);
export { D3Service };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZDMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWQzLWdyYXBocy8iLCJzb3VyY2VzIjpbInNoYXJlZC9zZXJ2aWNlcy9kMy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDOztBQUd6QixNQUFNLENBQU4sSUFBWSxhQUtYO0FBTEQsV0FBWSxhQUFhO0lBQ3ZCLDRCQUFXLENBQUE7SUFDWCxnQ0FBZSxDQUFBO0lBQ2Ysa0NBQWlCLENBQUE7SUFDakIsOEJBQWEsQ0FBQTtBQUNmLENBQUMsRUFMVyxhQUFhLEtBQWIsYUFBYSxRQUt4QjtBQUVELElBQWEsU0FBUyxHQUF0QixNQUFhLFNBQVM7SUFDcEIsZ0JBQWUsQ0FBQztJQUVoQixTQUFTLENBQUMsQ0FBUyxFQUFFLENBQVM7UUFDNUIsT0FBTyxhQUFhLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUNqQyxDQUFDO0lBRUQsV0FBVyxDQUFDLEtBQVUsRUFBRSxTQUF3QjtRQUM5QyxRQUFRLFNBQVMsRUFBRTtZQUNqQixLQUFLLGFBQWEsQ0FBQyxHQUFHO2dCQUNwQixPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0IsS0FBSyxhQUFhLENBQUMsS0FBSztnQkFDdEIsT0FBTyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzdCLEtBQUssYUFBYSxDQUFDLE1BQU07Z0JBQ3ZCLE9BQU8sRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QixLQUFLLGFBQWEsQ0FBQyxJQUFJO2dCQUNyQixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUI7Z0JBQ0UsT0FBTyxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1NBQ2xEO0lBQ0gsQ0FBQztJ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QUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBQyxDQUFDO0lBQzVELENBQUM7Q0FLRixDQUFBOztBQXhLWSxTQUFTO0lBRHJCLFVBQVUsQ0FBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUMsQ0FBQztHQUNwQixTQUFTLENBd0tyQjtTQXhLWSxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJztcbmltcG9ydCB7Vmlld0JveH0gZnJvbSAnLi4vbW9kZWxzL3ZpZXdib3guaW50ZXJmYWNlJztcblxuZXhwb3J0IGVudW0gQXhpc0RpcmVjdGlvbiB7XG4gIHRvcCA9ICd0b3AnLFxuICByaWdodCA9ICdyaWdodCcsXG4gIGJvdHRvbSA9ICdib3R0b20nLFxuICBsZWZ0ID0gJ2xlZnQnLFxufVxuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290J30pXG5leHBvcnQgY2xhc3MgRDNTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIHRyYW5zbGF0ZSh4OiBudW1iZXIsIHk6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGB0cmFuc2xhdGUoJHt4fSwgJHt5fSlgO1xuICB9XG5cbiAgZmFjdG9yeUF4aXMoc2NhbGU6IGFueSwgZGlyZWN0aW9uOiBBeGlzRGlyZWN0aW9uKTogYW55IHtcbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSBBeGlzRGlyZWN0aW9uLnRvcDpcbiAgICAgICAgcmV0dXJuIGQzLmF4aXNUb3Aoc2NhbGUpO1xuICAgICAgY2FzZSBBeGlzRGlyZWN0aW9uLnJpZ2h0OlxuICAgICAgICByZXR1cm4gZDMuYXhpc1JpZ2h0KHNjYWxlKTtcbiAgICAgIGNhc2UgQXhpc0RpcmVjdGlvbi5ib3R0b206XG4gICAgICAgIHJldHVybiBkMy5heGlzQm90dG9tKHNjYWxlKTtcbiAgICAgIGNhc2UgQXhpc0RpcmVjdGlvbi5sZWZ0OlxuICAgICAgICByZXR1cm4gZDMuYXhpc0xlZnQoc2NhbGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcignTm8gYXhpcyBEaXJlY3Rpb24gUHJvdmlkZWQnKTtcbiAgICB9XG4gIH1cblxuICBmYWN0b3J5TGluZSgpOiBhbnkge1xuICAgIHJldHVybiBkMy5saW5lPGFueT4oKS54KChkKSA9PiBkLngpLnkoKGQpID0+IGQueSk7XG4gIH1cblxuICAvLyA9PT09IEF4aXMgPT09PT1cbiAgc2NhbGVMaW5lYXJYKGxhYmVsczogYW55W10sIHdpZHRoOiBudW1iZXIpIHtcbiAgICByZXR1cm4gZDMuc2NhbGVMaW5lYXIoKVxuICAgICAgICAuZG9tYWluKGQzLmV4dGVudChsYWJlbHMpKSAgLy8gZG9lcyB0aGUgbWFnaWMgZm9yIGFkanVzdGFibGUgYXhpc1xuICAgICAgICAucmFuZ2UoWzAsIHdpZHRoXSk7XG4gIH1cblxuICBzY2FsZUxpbmVhclkoZGF0YTogYW55W10sIGhlaWdodDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGQzLnNjYWxlTGluZWFyKClcbiAgICAgICAgLmRvbWFpbihkMy5leHRlbnQoZGF0YSkpICAvLyBkb2VzIHRoZSBtYWdpYyBmb3IgYWRqdXN0YWJsZSBheGlzXG4gICAgICAgIC5yYW5nZShbaGVpZ2h0LCAwXSk7XG4gIH1cblxuICBzY2FsZUJhbmRYKGxhYmVsczogYW55W10sIHdpZHRoOiBudW1iZXIpIHtcbiAgICByZXR1cm4gZDMuc2NhbGVCYW5kKCkuZG9tYWluKGxhYmVscykucmFuZ2VSb3VuZChbMCwgd2lkdGhdKS5wYWRkaW5nKDAuMSk7XG4gIH1cblxuICBzY2FsZUxpbmVhcllSYW5nZVJvdW5kKGRhdGE6IGFueVtdLCBoZWlnaHQ6IG51bWJlcikge1xuICAgIHJldHVybiBkMy5zY2FsZUxpbmVhcigpLmRvbWFpbihbMCwgTWF0aC5tYXgoLi4uZGF0YSldKS5yYW5nZVJvdW5kKFtcbiAgICAgIGhlaWdodCwgMFxuICAgIF0pO1xuICB9XG5cbiAgYWRkTGFiZWxBeGlzWShcbiAgICAgIHN2ZzogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBudWxsLCB1bmRlZmluZWQ+LCBoZWlnaHQ6IG51bWJlcixcbiAgICAgIG9wdGlvbnM6IGFueSkge1xuICAgIHN2Zy5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAuYXR0cigndHJhbnNmb3JtJywgJ3JvdGF0ZSgtOTApJylcbiAgICAgICAgLmF0dHIoJ3knLCAwIC0gb3B0aW9ucy5tYXJnaW4ubGVmdClcbiAgICAgICAgLmF0dHIoJ3gnLCAwIC0gaGVpZ2h0IC8gMilcbiAgICAgICAgLmF0dHIoJ2R5JywgJzFlbScpXG4gICAgICAgIC5zdHlsZSgndGV4dC1hbmNob3InLCAnbWlkZGxlJylcbiAgICAgICAgLnRleHQob3B0aW9ucy55QXhpc0xhYmVsKTtcbiAgfVxuXG4gIGFkZExhYmVsQXhpc1goXG4gICAgICBzdmc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPiwgd2lkdGg6IG51bWJlcixcbiAgICAgIGhlaWdodDogbnVtYmVyLCBvcHRpb25zOiBhbnkpIHtcbiAgICBzdmcuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgICAgICd0cmFuc2xhdGUoJyArIHdpZHRoIC8gMiArICcgLCcgKyAoaGVpZ2h0ICsgb3B0aW9ucy5tYXJnaW4udG9wKSArXG4gICAgICAgICAgICAgICAgJyknKVxuICAgICAgICAuc3R5bGUoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgIC50ZXh0KG9wdGlvbnMueEF4aXNMYWJlbCk7XG4gIH1cblxuICBnZXRWaWV3Qm94RGVmYXVsdChvcHRpb25zOiBhbnkpOiBWaWV3Qm94IHtcbiAgICBjb25zdCByZXMgPSB7XG4gICAgICBtaW5YOiAtb3B0aW9ucy5tYXJnaW4ubGVmdCxcbiAgICAgIG1pblk6IC0yNSxcbiAgICAgIHdpZHRoOiBvcHRpb25zLndpZHRoLFxuICAgICAgaGVpZ2h0OiBvcHRpb25zLmhlaWdodCAtIG9wdGlvbnMubWFyZ2luLnRvcCxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHJlbW92ZUF4aXNUaWNrcyhheGlzOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4pIHtcbiAgICBheGlzLnNlbGVjdEFsbCgnLnRpY2snKS5zZWxlY3RBbGwoJ2xpbmUnKS5yZW1vdmUoKTtcbiAgfVxuXG4gIGNoYW5nZUF4aXNDb2xvcihcbiAgICAgIGF4aXM6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPiwgY29uZmlnOiBhbnkpIHtcbiAgICBheGlzLnNlbGVjdCgncGF0aCcpXG4gICAgICAgIC5hdHRyKCdjb2xvcicsIGNvbmZpZy5jb2xvcilcbiAgICAgICAgLmF0dHIoJ29wYWNpdHknLCBjb25maWcub3BhY2l0eSlcbiAgICAgICAgLmF0dHIoJ3JlbmRlcmluZycsIGNvbmZpZy5yZW5kZXJpbmcpXG4gICAgICAgIC5hdHRyKCdzdHJva2Utd2lkdGgnLCBjb25maWcuc3Ryb2tlV2lkdGgpO1xuICB9XG5cbiAgZ2V0WGF4aXNUaW1lKFxuICAgICAgc3ZnOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4sIGhlaWdodDogbnVtYmVyLFxuICAgICAgeDogZDMuU2NhbGVUaW1lPG51bWJlciwgbnVtYmVyPiwgdGltZUZvcm1hdDogc3RyaW5nLCB4QXhpc1RpY2tzOiBudW1iZXIpIHtcbiAgICByZXR1cm4gc3ZnLmFwcGVuZCgnZycpXG4gICAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKDAsJHtoZWlnaHR9KWApXG4gICAgICAgIC5jYWxsKGQzLmF4aXNCb3R0b20oeClcbiAgICAgICAgICAgICAgICAgIC50aWNrRm9ybWF0KGQzLnRpbWVGb3JtYXQodGltZUZvcm1hdCkpXG4gICAgICAgICAgICAgICAgICAudGlja3MoeEF4aXNUaWNrcykpO1xuICB9XG5cbiAgaGlkZVRvb2x0aXAodG9vbHRpcFRleHQ6IGFueSwgdG9vbHRpcDogYW55KSB7XG4gICAgdG9vbHRpcFRleHQuc2VsZWN0QWxsKCd0c3BhbicpLnJlbW92ZSgpO1xuICAgIHRvb2x0aXAuYXR0cigndmlzaWJpbGl0eScsICdoaWRkZW4nKTtcbiAgfVxuXG4gIHNob3dUb29sdGlwKFxuICAgICAgZDogYW55LCB4U2NhbGU6IGFueSwgeVNjYWxlOiBhbnksIHRvb2x0aXA6IGFueSwgdG9vbHRpcFJlY3Q6IGFueSxcbiAgICAgIHRvb2x0aXBUZXh0OiBhbnksIGZvcm1hdFRpbWU6IGFueSkge1xuICAgIGNvbnN0IHhQb3MgPSB4U2NhbGUoZC54KSAtIDE1MCAvIDI7XG4gICAgY29uc3QgeVBvcyA9IHlTY2FsZShkLnkpICsgMTA7XG4gICAgdG9vbHRpcC5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKCR7eFBvc30sICR7eVBvc30pYClcbiAgICAgICAgLmF0dHIoJ2lzJywgdHJ1ZSlcbiAgICAgICAgLmF0dHIoJ3Zpc2liaWxpdHknLCAndmlzaWJsZScpO1xuICAgIHRvb2x0aXBSZWN0LmF0dHIoJ29wYWNpdHknLCAwLjcpO1xuICAgIHRvb2x0aXBUZXh0LmF0dHIoJ3RyYW5mb3JtJywgJ3RyYW5zbGF0ZSg3NSwzMCknKVxuICAgICAgICAuYXR0cignZmlsbCcsICd3aGl0ZScpXG4gICAgICAgIC5hdHRyKCdmb250LXNpemUnLCAxMClcbiAgICAgICAgLmF0dHIoJ2ZvbnQtZmFtaWx5JywgYCdSb2JvdG8nLCAnc2Fucy1zZXJpZidgKTtcbiAgICB0b29sdGlwVGV4dC5hcHBlbmQoJ3RzcGFuJylcbiAgICAgICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgIC5hdHRyKCdpcycsIHRydWUpXG4gICAgICAgIC5hdHRyKCd4JywgMjUpXG4gICAgICAgIC5hdHRyKCd5JywgLTUpXG4gICAgICAgIC50ZXh0KGAke2Zvcm1hdFRpbWUoZC54KX1gKTtcbiAgICB0b29sdGlwVGV4dC5hcHBlbmQoJ3RzcGFuJylcbiAgICAgICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgJ21pZGRsZScpXG4gICAgICAgIC5hdHRyKCdpcycsIHRydWUpXG4gICAgICAgIC5hdHRyKCd4JywgMjApXG4gICAgICAgIC5hdHRyKCdkeScsIDE1KVxuICAgICAgICAudGV4dChgJHtkLnl9YCk7XG4gIH1cblxuICBhZGRUb29sdGlwKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IHRvb2x0aXBDb25maWcgPSB7XG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgaGVpZ2h0OiA0MCxcbiAgICAgIGZpbGw6ICcjMzMzJyxcbiAgICAgIG9wYWNpdHk6IDAuNyxcbiAgICAgIHJ4OiAxNSxcbiAgICAgIHRleHQ6IHtcbiAgICAgICAgdHJhbnNsYXRlWDogMTAsXG4gICAgICAgIHRyYW5zbGF0ZVk6IDIwLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGNvbnN0IHRvb2x0aXAgPVxuICAgICAgICBkMy5zZWxlY3QoY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpLnNlbGVjdCgnc3ZnJykuYXBwZW5kKCdnJyk7XG4gICAgY29uc3QgdG9vbHRpcFJlY3QgPSB0b29sdGlwLmFwcGVuZCgncmVjdCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3dpZHRoJywgdG9vbHRpcENvbmZpZy53aWR0aClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignaGVpZ2h0JywgdG9vbHRpcENvbmZpZy5oZWlnaHQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2ZpbGwnLCB0b29sdGlwQ29uZmlnLmZpbGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ29wYWNpdHknLCAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCdyeCcsIHRvb2x0aXBDb25maWcucngpO1xuICAgIGNvbnN0IHRvb2x0aXBUZXh0ID0gdG9vbHRpcC5hcHBlbmQoJ3RleHQnKS5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKFxuICAgICAgICAgICR7dG9vbHRpcENvbmZpZy50ZXh0LnRyYW5zbGF0ZVh9LFxuICAgICAgICAgICR7dG9vbHRpcENvbmZpZy50ZXh0LnRyYW5zbGF0ZVl9KWApO1xuICAgIHJldHVybiB7dG9vbHRpcCwgdG9vbHRpcFJlY3QsIHRvb2x0aXBUZXh0LCB0b29sdGlwQ29uZmlnfTtcbiAgfVxuXG5cblxuICAvLyA9PT09PT09PT09PT09XG59XG4iXX0=