@greg-md/ng-flex-css-layout
Version:
Flex-CSS-Layout is an alternative behaviour of Flex-Layout directives, that will still work with Angular Universal and App Shell.
667 lines • 70.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { DOCUMENT } from '@angular/common';
import { Injectable, Inject, InjectionToken } from '@angular/core';
import { applyCssPrefixes } from './auto-prefixer';
import { validateValue, buildCSS, isFlowHorizontal } from './layout-validator';
import { generateLayoutClassName, normalizeLayoutAlignValue, generateLayoutAlignClassName, generateLayoutGapClassName, generateFlexClassName, generateFlexOrderClassName, generateFlexOffsetClassName, generateFlexAlignClassName, generateFlexFillClassName, generateFlexShowHideClassName } from './helpers';
import { validateBasis } from './basis-validator';
/**
* @record
*/
export function Breakpoint() { }
function Breakpoint_tsickle_Closure_declarations() {
/** @type {?} */
Breakpoint.prototype.alias;
/** @type {?} */
Breakpoint.prototype.media;
}
export var /** @type {?} */ FLEX_CSS_DEFAULT_BREAKPOINTS = [
{ alias: 'gt-xs', media: ['screen', '(min-width: 600px)'] },
{ alias: 'lt-xl', media: ['screen', '(max-width: 1919px)'] },
{ alias: 'gt-sm', media: ['screen', '(min-width: 960px)'] },
{ alias: 'lt-lg', media: ['screen', '(max-width: 1279px)'] },
{ alias: 'gt-md', media: ['screen', '(min-width: 1280px)'] },
{ alias: 'lt-md', media: ['screen', '(max-width: 959px)'] },
{ alias: 'gt-lg', media: ['screen', '(min-width: 1920px)'] },
{ alias: 'lt-sm', media: ['screen', '(max-width: 599px)'] },
{ alias: 'xl', media: ['screen', '(min-width: 1920px)', '(max-width: 5000px)'] },
{ alias: 'lg', media: ['screen', '(min-width: 1280px)', '(max-width: 1919px)'] },
{ alias: 'md', media: ['screen', '(min-width: 960px)', '(max-width: 1279px)'] },
{ alias: 'sm', media: ['screen', '(min-width: 600px)', '(max-width: 959px)'] },
{ alias: 'xs', media: ['screen', '(max-width: 599px)'] },
];
export var /** @type {?} */ FLEX_CSS_BREAKPOINTS_SMALL_TO_LARGE = [
{ alias: 'lt-sm', media: ['screen', '(max-width: 599px)'] },
{ alias: 'xs', media: ['screen', '(max-width: 599px)'] },
{ alias: 'gt-xs', media: ['screen', '(min-width: 600px)'] },
{ alias: 'lt-md', media: ['screen', '(max-width: 959px)'] },
{ alias: 'sm', media: ['screen', '(min-width: 600px)', '(max-width: 959px)'] },
{ alias: 'gt-sm', media: ['screen', '(min-width: 960px)'] },
{ alias: 'lt-lg', media: ['screen', '(max-width: 1279px)'] },
{ alias: 'md', media: ['screen', '(min-width: 960px)', '(max-width: 1279px)'] },
{ alias: 'gt-md', media: ['screen', '(min-width: 1280px)'] },
{ alias: 'lt-xl', media: ['screen', '(max-width: 1919px)'] },
{ alias: 'lg', media: ['screen', '(min-width: 1280px)', '(max-width: 1919px)'] },
{ alias: 'gt-lg', media: ['screen', '(min-width: 1920px)'] },
{ alias: 'xl', media: ['screen', '(min-width: 1920px)', '(max-width: 5000px)'] },
];
export var /** @type {?} */ FLEX_CSS_BREAKPOINTS = new InjectionToken('flex_css_breakpoints');
var FlexCssStyleElement = /** @class */ (function () {
function FlexCssStyleElement(style) {
this.style = style;
this.storage = {};
}
return FlexCssStyleElement;
}());
export { FlexCssStyleElement };
function FlexCssStyleElement_tsickle_Closure_declarations() {
/** @type {?} */
FlexCssStyleElement.prototype.storage;
/** @type {?} */
FlexCssStyleElement.prototype.style;
}
var FlexCssService = /** @class */ (function () {
function FlexCssService(doc, breakpoints) {
this.doc = doc;
this.breakpoints = breakpoints;
this.initLayout();
this.initFlex();
this.initFill();
}
/**
* @return {?}
*/
FlexCssService.prototype.initLayout = /**
* @return {?}
*/
function () {
var /** @type {?} */ style = this.doc.createElement('style');
style.id = 'fc-layout';
this.doc.head.appendChild(style);
this.layout = new FlexCssStyleElement(style);
};
/**
* @return {?}
*/
FlexCssService.prototype.initFlex = /**
* @return {?}
*/
function () {
var /** @type {?} */ style = this.doc.createElement('style');
style.id = 'fc-flex';
this.doc.head.appendChild(style);
this.flex = new FlexCssStyleElement(style);
};
/**
* @return {?}
*/
FlexCssService.prototype.initFill = /**
* @return {?}
*/
function () {
var /** @type {?} */ style = this.doc.createElement('style');
style.id = 'fc-fill';
this.doc.head.appendChild(style);
this.fill = new FlexCssStyleElement(style);
};
/**
* @param {?} layout
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addLayout = /**
* @param {?} layout
* @param {?} breakpoint
* @return {?}
*/
function (layout, breakpoint) {
var _a = tslib_1.__read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
var /** @type {?} */ className = generateLayoutClassName(direction, wrap, isInline, breakpoint);
if (!this.hasInLayoutStorage(className, breakpoint)) {
var /** @type {?} */ style = buildCSS(direction, wrap, isInline);
this.addToLayoutStorage(className, style, breakpoint);
}
return className;
};
/**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} align
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addLayoutAlign = /**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} align
* @param {?} breakpoint
* @return {?}
*/
function (layout, layoutBreakpoint, align, breakpoint) {
var _a = tslib_1.__read(normalizeLayoutAlignValue(align), 2), mainAxis = _a[0], crossAxis = _a[1];
var /** @type {?} */ layoutAlignClassName = generateLayoutAlignClassName(mainAxis, crossAxis, breakpoint);
if (!this.hasInLayoutStorage(layoutAlignClassName, breakpoint)) {
var /** @type {?} */ style = {
'justify-content': mainAxis,
};
switch (crossAxis) {
case 'baseline':
style['align-items'] = crossAxis;
break;
default:
style['align-items'] = style['align-content'] = crossAxis;
break;
}
this.addToLayoutStorage(layoutAlignClassName, style, breakpoint);
}
if (crossAxis === 'stretch') {
var _b = tslib_1.__read(validateValue(layout), 3), direction = _b[0], wrap = _b[1], isInline = _b[2];
var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
var /** @type {?} */ className = layoutAlignClassName + '.' + layoutClassName;
if (!this.hasInLayoutStorage(className, breakpoint)) {
var /** @type {?} */ style = isFlowHorizontal(layout) ? { 'max-height': '100%' } : { 'max-width': '100%' };
this.addToLayoutStorage(className, style, breakpoint, [layoutBreakpoint]);
}
}
return layoutAlignClassName;
};
/**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} value
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addLayoutGap = /**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} value
* @param {?} breakpoint
* @return {?}
*/
function (layout, layoutBreakpoint, value, breakpoint) {
value = value || '0';
var _a = tslib_1.__read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
var /** @type {?} */ layoutGapClassName = generateLayoutGapClassName(value, breakpoint);
var /** @type {?} */ className = layoutGapClassName + '.' + layoutClassName + ' > *:not(:last-child)';
if (!this.hasInLayoutStorage(className, breakpoint)) {
var /** @type {?} */ style = isFlowHorizontal(layout) ? { 'margin-right': value } : { 'margin-bottom': value };
this.addToLayoutStorage(className, style, breakpoint, [layoutBreakpoint]);
}
return layoutGapClassName;
};
/**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} value
* @param {?} breakpoint
* @param {?=} grow
* @param {?=} shrink
* @return {?}
*/
FlexCssService.prototype.addFlex = /**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} value
* @param {?} breakpoint
* @param {?=} grow
* @param {?=} shrink
* @return {?}
*/
function (layout, layoutBreakpoint, value, breakpoint, grow, shrink) {
value = value.replace(';', '');
var _a = tslib_1.__read(validateBasis(value, grow, shrink), 3), theGrow = _a[0], theShrink = _a[1], theBasis = _a[2];
theGrow = (theGrow === '0') ? 0 : theGrow;
theShrink = (theShrink === '0') ? 0 : theShrink;
// flex-basis allows you to specify the initial/starting main-axis size of the element,
// before anything else is computed. It can either be a percentage or an absolute value.
// It is, however, not the breaking point for flex-grow/shrink properties
//
// flex-grow can be seen as this:
// 0: Do not stretch. Either size to element's content width, or obey 'flex-basis'.
// 1: (Default value). Stretch; will be the same size to all other flex items on
// the same row since they have a default value of 1.
// ≥2 (integer n): Stretch. Will be n times the size of other elements
// with 'flex-grow: 1' on the same row.
var /** @type {?} */ style = {
'box-sizing': 'border-box',
};
switch (theBasis || '') {
case '':
style['flex'] = theGrow + " " + theShrink + " 0.000000001px";
break;
case 'initial': // default
case 'nogrow':
theGrow = 0;
style['flex'] = "0 1 auto";
break;
case 'grow':
style['flex'] = "1 1 100%";
break;
case 'noshrink':
theShrink = 0;
style['flex'] = "1 0 auto";
break;
case 'auto':
style['flex'] = theGrow + " " + theShrink + " auto";
break;
case 'none':
theGrow = 0;
theShrink = 0;
style['flex'] = "0 0 auto";
break;
default:
var /** @type {?} */ isCalc = String(theBasis).indexOf('calc') > -1;
var /** @type {?} */ isPercent = !isCalc && String(theBasis).indexOf('%') > -1;
var /** @type {?} */ isValue = isCalc || isPercent ||
String(theBasis).indexOf('px') > -1 ||
String(theBasis).indexOf('em') > -1 ||
String(theBasis).indexOf('vw') > -1 ||
String(theBasis).indexOf('vh') > -1;
// Defaults to percentage sizing unless `px` is explicitly set
if (!isValue && !isPercent && !isNaN(/** @type {?} */ (theBasis))) {
theBasis = theBasis + '%';
}
if (theBasis === '0px') {
theBasis = '0%';
}
style['flex-grow'] = "" + theGrow;
style['flex-shrink'] = "" + theShrink;
style['flex-basis'] = style['min-width'] = style['max-width'] = isValue ? "" + theBasis : '100%';
break;
}
var /** @type {?} */ flexClassName = generateFlexClassName(theGrow, theShrink, theBasis, breakpoint);
if (!this.hasInFlexStorage(flexClassName, breakpoint)) {
this.addToFlexStorage(flexClassName, style, breakpoint);
}
var _b = tslib_1.__read(validateValue(layout), 3), direction = _b[0], wrap = _b[1], isInline = _b[2];
var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
var /** @type {?} */ className = flexClassName + '.' + layoutClassName;
if (!this.hasInFlexStorage(className, breakpoint)) {
var /** @type {?} */ max = isFlowHorizontal(direction) ? 'max-width' : 'max-height';
var /** @type {?} */ min = isFlowHorizontal(direction) ? 'min-width' : 'min-height';
var /** @type {?} */ usingCalc = (String(theBasis).indexOf('calc') > -1) || (theBasis === 'auto');
var /** @type {?} */ isPx = String(theBasis).indexOf('px') > -1 || usingCalc;
// make box inflexible when shrink and grow are both zero
// should not set a min when the grow is zero
// should not set a max when the shrink is zero
var /** @type {?} */ isFixed = !theGrow && !theShrink;
var /** @type {?} */ layoutStyle = {};
layoutStyle[min] = (theBasis === '0%') ? 0 : isFixed || (isPx && theGrow) ? theBasis : null;
layoutStyle[max] = (theBasis === '0%') ? 0 : isFixed || (!usingCalc && theShrink) ? theBasis : null;
this.addToFlexStorage(className, layoutStyle, breakpoint, [layoutBreakpoint]);
}
return flexClassName;
};
/**
* @param {?} order
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addFlexOrder = /**
* @param {?} order
* @param {?} breakpoint
* @return {?}
*/
function (order, breakpoint) {
order = parseInt(order, 10);
order = isNaN(order) ? 0 : order;
var /** @type {?} */ className = generateFlexOrderClassName(order, breakpoint);
if (!this.hasInFlexStorage(className, breakpoint)) {
var /** @type {?} */ style = { 'order': order };
this.addToFlexStorage(className, style, breakpoint);
}
return className;
};
/**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} offset
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addFlexOffset = /**
* @param {?} layout
* @param {?} layoutBreakpoint
* @param {?} offset
* @param {?} breakpoint
* @return {?}
*/
function (layout, layoutBreakpoint, offset, breakpoint) {
var /** @type {?} */ isPercent = String(offset).indexOf('%') > -1;
var /** @type {?} */ isPx = String(offset).indexOf('px') > -1;
if (!isPx && !isPercent && !isNaN(offset)) {
offset = offset + '%';
}
var _a = tslib_1.__read(validateValue(layout), 3), direction = _a[0], wrap = _a[1], isInline = _a[2];
var /** @type {?} */ offsetClassName = generateFlexOffsetClassName(offset, breakpoint);
var /** @type {?} */ layoutClassName = generateLayoutClassName(direction, wrap, isInline, layoutBreakpoint);
var /** @type {?} */ className = offsetClassName + '.' + layoutClassName;
if (!this.hasInFlexStorage(className, breakpoint)) {
var /** @type {?} */ style = isFlowHorizontal(direction) ? { 'margin-left': "" + offset } : { 'margin-top': "" + offset };
this.addToFlexStorage(className, style, breakpoint, [layoutBreakpoint]);
}
return offsetClassName;
};
/**
* @param {?} align
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addFlexAlign = /**
* @param {?} align
* @param {?} breakpoint
* @return {?}
*/
function (align, breakpoint) {
align = align || 'stretch';
// Cross-axis
switch (align) {
case 'start':
align = 'flex-start';
break;
case 'end':
align = 'flex-end';
break;
}
var /** @type {?} */ className = generateFlexAlignClassName(align, breakpoint);
if (!this.hasInFlexStorage(className, breakpoint)) {
var /** @type {?} */ style = { 'align-self': align };
this.addToFlexStorage(className, style, breakpoint);
}
return className;
};
/**
* @return {?}
*/
FlexCssService.prototype.addFlexFill = /**
* @return {?}
*/
function () {
var /** @type {?} */ className = generateFlexFillClassName();
if (!this.hasInFillStorage(className, 'all')) {
var /** @type {?} */ style = {
'margin': 0,
'width': '100%',
'height': '100%',
'min-width': '100%',
'min-height': '100%',
};
this.addToFillStorage(className, style, 'all');
}
return className;
};
/**
* @param {?} display
* @param {?} show
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.addShowHide = /**
* @param {?} display
* @param {?} show
* @param {?} breakpoint
* @return {?}
*/
function (display, show, breakpoint) {
var /** @type {?} */ className = generateFlexShowHideClassName(display, show, breakpoint);
if (!this.hasInFillStorage(className, breakpoint)) {
var /** @type {?} */ style = {
'display': show ? display || 'block' : 'none',
};
this.addToFillStorage(className, style, breakpoint);
}
return className;
};
/**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.hasInLayoutStorage = /**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
function (className, breakpoint) {
return this.hasInStorage(this.layout, className, breakpoint);
};
/**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
FlexCssService.prototype.addToLayoutStorage = /**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
function (className, style, breakpoint, customBreakpoints) {
return this.addToStorage(this.layout, className, style, breakpoint, customBreakpoints);
};
/**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.hasInFlexStorage = /**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
function (className, breakpoint) {
return this.hasInStorage(this.flex, className, breakpoint);
};
/**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
FlexCssService.prototype.addToFlexStorage = /**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
function (className, style, breakpoint, customBreakpoints) {
return this.addToStorage(this.flex, className, style, breakpoint, customBreakpoints);
};
/**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.hasInFillStorage = /**
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
function (className, breakpoint) {
return this.hasInStorage(this.fill, className, breakpoint);
};
/**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
FlexCssService.prototype.addToFillStorage = /**
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
function (className, style, breakpoint, customBreakpoints) {
return this.addToStorage(this.fill, className, style, breakpoint, customBreakpoints);
};
/**
* @param {?} styleElement
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
FlexCssService.prototype.hasInStorage = /**
* @param {?} styleElement
* @param {?} className
* @param {?} breakpoint
* @return {?}
*/
function (styleElement, className, breakpoint) {
return !!(styleElement.storage[breakpoint] && styleElement.storage[breakpoint][className]);
};
/**
* @param {?} styleElement
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
FlexCssService.prototype.addToStorage = /**
* @param {?} styleElement
* @param {?} className
* @param {?} style
* @param {?} breakpoint
* @param {?=} customBreakpoints
* @return {?}
*/
function (styleElement, className, style, breakpoint, customBreakpoints) {
customBreakpoints = customBreakpoints || [];
var /** @type {?} */ styles = applyCssPrefixes(style);
var /** @type {?} */ css = this.generateCss(styles);
if (css !== '') {
var /** @type {?} */ classCss = '.' + className + ' { ' + css + ' }';
var /** @type {?} */ cssElement = this.doc.createTextNode(this.addBreakpoints([breakpoint].concat(customBreakpoints), classCss));
if (!styleElement.storage[breakpoint]) {
styleElement.storage[breakpoint] = {};
}
styleElement.storage[breakpoint][className] = cssElement;
this.reorderTextElements(styleElement);
}
};
/**
* @param {?} styleElement
* @return {?}
*/
FlexCssService.prototype.reorderTextElements = /**
* @param {?} styleElement
* @return {?}
*/
function (styleElement) {
var _this = this;
var /** @type {?} */ position = this.reorderBreakpointElements(styleElement, 'all');
this.breakpoints.forEach(function (breakpoint) {
position = _this.reorderBreakpointElements(styleElement, breakpoint.alias, position);
});
};
/**
* @param {?} styleElement
* @param {?} breakpoint
* @param {?=} position
* @return {?}
*/
FlexCssService.prototype.reorderBreakpointElements = /**
* @param {?} styleElement
* @param {?} breakpoint
* @param {?=} position
* @return {?}
*/
function (styleElement, breakpoint, position) {
if (position === void 0) { position = 0; }
var /** @type {?} */ breakpointElements = styleElement.storage[breakpoint];
if (!breakpointElements) {
return position;
}
Object.keys(breakpointElements).forEach(function (key) {
if (styleElement.style.children.length) {
styleElement.style.insertBefore(breakpointElements[key], styleElement.style.children[position]);
}
else {
styleElement.style.appendChild(breakpointElements[key]);
}
++position;
});
return position;
};
/**
* @param {?} styles
* @return {?}
*/
FlexCssService.prototype.generateCss = /**
* @param {?} styles
* @return {?}
*/
function (styles) {
var /** @type {?} */ css = [];
Object.keys(styles).sort().forEach(function (key) {
var /** @type {?} */ values = Array.isArray(styles[key]) ? styles[key] : [styles[key]];
values.sort();
values.forEach(function (value) {
if (value !== null && value !== '') {
css.push(key + ': ' + value + ';');
}
});
});
return css.join(' ');
};
/**
* @param {?} breakpointsAliases
* @param {?} css
* @return {?}
*/
FlexCssService.prototype.addBreakpoints = /**
* @param {?} breakpointsAliases
* @param {?} css
* @return {?}
*/
function (breakpointsAliases, css) {
breakpointsAliases = breakpointsAliases.filter(function (breakpoint) { return breakpoint !== 'all'; });
if (!breakpointsAliases.length) {
return css;
}
var /** @type {?} */ theBreakpoints = [];
this.breakpoints
.filter(function (breakpoint) { return breakpointsAliases.indexOf(breakpoint.alias) >= 0; })
.forEach(function (breakpoint) { return theBreakpoints = theBreakpoints.concat(breakpoint.media); });
theBreakpoints = theBreakpoints.filter(function (value, index, self) { return self.indexOf(value) === index; });
return '@media ' + theBreakpoints.join(' and ') + ' { ' + css + ' }';
};
FlexCssService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
FlexCssService.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: undefined, decorators: [{ type: Inject, args: [FLEX_CSS_BREAKPOINTS,] }] }
]; };
return FlexCssService;
}());
export { FlexCssService };
function FlexCssService_tsickle_Closure_declarations() {
/** @type {?} */
FlexCssService.prototype.layout;
/** @type {?} */
FlexCssService.prototype.flex;
/** @type {?} */
FlexCssService.prototype.fill;
/** @type {?} */
FlexCssService.prototype.doc;
/** @type {?} */
FlexCssService.prototype.breakpoints;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxleC1jc3Muc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BncmVnLW1kL25nLWZsZXgtY3NzLWxheW91dC8iLCJzb3VyY2VzIjpbImxpYi9mbGV4LWNzcy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9FLE9BQU8sRUFDTCx1QkFBdUIsRUFBRSx5QkFBeUIsRUFBRSw0QkFBNEIsRUFDaEYsMEJBQTBCLEVBQUUscUJBQXFCLEVBQUUsMEJBQTBCLEVBQUUsMkJBQTJCLEVBQzFHLDBCQUEwQixFQUFFLHlCQUF5QixFQUFFLDZCQUE2QixFQUNyRixNQUFNLFdBQVcsQ0FBQztBQUNuQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7Ozs7Ozs7O0FBT2xELE1BQU0sQ0FBQyxxQkFBTSw0QkFBNEIsR0FBaUI7SUFDeEQsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxvQkFBb0IsQ0FBQyxFQUFFO0lBQzNELEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUscUJBQXFCLENBQUMsRUFBRTtJQUM1RCxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLG9CQUFvQixDQUFDLEVBQUU7SUFDM0QsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxxQkFBcUIsQ0FBQyxF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QUE3QixDQUE2QixDQUFDLENBQUM7UUFFOUYsTUFBTSxDQUFDLFNBQVMsR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDOzs7Z0JBcGJ4RSxVQUFVOzs7O2dEQVNOLE1BQU0sU0FBQyxRQUFRO2dEQUNmLE1BQU0sU0FBQyxvQkFBb0I7O3lCQTNFaEM7O1NBa0VhLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3QsIEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGFwcGx5Q3NzUHJlZml4ZXMgfSBmcm9tICcuL2F1dG8tcHJlZml4ZXInO1xuaW1wb3J0IHsgdmFsaWRhdGVWYWx1ZSwgYnVpbGRDU1MsIGlzRmxvd0hvcml6b250YWwgfSBmcm9tICcuL2xheW91dC12YWxpZGF0b3InO1xuaW1wb3J0IHtcbiAgZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUsIG5vcm1hbGl6ZUxheW91dEFsaWduVmFsdWUsIGdlbmVyYXRlTGF5b3V0QWxpZ25DbGFzc05hbWUsXG4gIGdlbmVyYXRlTGF5b3V0R2FwQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhDbGFzc05hbWUsIGdlbmVyYXRlRmxleE9yZGVyQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhPZmZzZXRDbGFzc05hbWUsXG4gIGdlbmVyYXRlRmxleEFsaWduQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhGaWxsQ2xhc3NOYW1lLCBnZW5lcmF0ZUZsZXhTaG93SGlkZUNsYXNzTmFtZVxufSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IHsgdmFsaWRhdGVCYXNpcyB9IGZyb20gJy4vYmFzaXMtdmFsaWRhdG9yJztcblxuZXhwb3J0IGludGVyZmFjZSBCcmVha3BvaW50IHtcbiAgYWxpYXM6IHN0cmluZztcbiAgbWVkaWE6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfREVGQVVMVF9CUkVBS1BPSU5UUzogQnJlYWtwb2ludFtdID0gW1xuICB7IGFsaWFzOiAnZ3QteHMnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogNjAwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2x0LXhsJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3Qtc20nLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2x0LWxnJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDEyNzlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTI4MHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC1tZCcsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA5NTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KSddIH0sXG4gIHsgYWxpYXM6ICdsdC1zbScsIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuICB7IGFsaWFzOiAneGwnLCAgICBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KScsICcobWF4LXdpZHRoOiA1MDAwcHgpJ10gfSxcbiAgeyBhbGlhczogJ2xnJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDEyODBweCknLCAnKG1heC13aWR0aDogMTkxOXB4KSddIH0sXG4gIHsgYWxpYXM6ICdtZCcsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA5NjBweCknLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdzbScsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA2MDBweCknLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ3hzJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDU5OXB4KSddIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfQlJFQUtQT0lOVFNfU01BTExfVE9fTEFSR0U6IEJyZWFrcG9pbnRbXSA9IFtcbiAgeyBhbGlhczogJ2x0LXNtJywgbWVkaWE6IFsnc2NyZWVuJywgJyhtYXgtd2lkdGg6IDU5OXB4KSddIH0sXG4gIHsgYWxpYXM6ICd4cycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWF4LXdpZHRoOiA1OTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QteHMnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogNjAwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQtbWQnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogOTU5cHgpJ10gfSxcbiAgeyBhbGlhczogJ3NtJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDYwMHB4KScsICcobWF4LXdpZHRoOiA5NTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3Qtc20nLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogOTYwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdtZCcsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiA5NjBweCknLCAnKG1heC13aWR0aDogMTI3OXB4KSddIH0sXG4gIHsgYWxpYXM6ICdndC1tZCcsIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxMjgwcHgpJ10gfSxcblxuICB7IGFsaWFzOiAnbHQteGwnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1heC13aWR0aDogMTkxOXB4KSddIH0sXG4gIHsgYWxpYXM6ICdsZycsICAgIG1lZGlhOiBbJ3NjcmVlbicsICcobWluLXdpZHRoOiAxMjgwcHgpJywgJyhtYXgtd2lkdGg6IDE5MTlweCknXSB9LFxuICB7IGFsaWFzOiAnZ3QtbGcnLCBtZWRpYTogWydzY3JlZW4nLCAnKG1pbi13aWR0aDogMTkyMHB4KSddIH0sXG5cbiAgeyBhbGlhczogJ3hsJywgICAgbWVkaWE6IFsnc2NyZWVuJywgJyhtaW4td2lkdGg6IDE5MjBweCknLCAnKG1heC13aWR0aDogNTAwMHB4KSddIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgRkxFWF9DU1NfQlJFQUtQT0lOVFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPignZmxleF9jc3NfYnJlYWtwb2ludHMnKTtcblxuZXhwb3J0IHR5cGUgU3R5bGVEZWZpbml0aW9uID0gc3RyaW5nIHwgeyBbcHJvcGVydHk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IG51bGwgfTtcblxuZXhwb3J0IGNsYXNzIEZsZXhDc3NTdHlsZUVsZW1lbnQge1xuICBwdWJsaWMgc3RvcmFnZTogeyBbcHJvcGVydHk6IHN0cmluZ106IHsgW3Byb3BlcnR5OiBzdHJpbmddOiBUZXh0IH0gfSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBzdHlsZTogSFRNTFN0eWxlRWxlbWVudCxcbiAgKSB7fVxufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRmxleENzc1NlcnZpY2Uge1xuICBwcml2YXRlIGxheW91dDogRmxleENzc1N0eWxlRWxlbWVudDtcblxuICBwcml2YXRlIGZsZXg6IEZsZXhDc3NTdHlsZUVsZW1lbnQ7XG5cbiAgcHJpdmF0ZSBmaWxsOiBGbGV4Q3NzU3R5bGVFbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jLFxuICAgIEBJbmplY3QoRkxFWF9DU1NfQlJFQUtQT0lOVFMpIHByaXZhdGUgYnJlYWtwb2ludHMsXG4gICkge1xuICAgIHRoaXMuaW5pdExheW91dCgpO1xuICAgIHRoaXMuaW5pdEZsZXgoKTtcbiAgICB0aGlzLmluaXRGaWxsKCk7XG4gIH1cblxuICBpbml0TGF5b3V0KCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgIHN0eWxlLmlkID0gJ2ZjLWxheW91dCc7XG5cbiAgICB0aGlzLmRvYy5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAgIHRoaXMubGF5b3V0ID0gbmV3IEZsZXhDc3NTdHlsZUVsZW1lbnQoc3R5bGUpO1xuICB9XG5cbiAgaW5pdEZsZXgoKSB7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmRvYy5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXG4gICAgc3R5bGUuaWQgPSAnZmMtZmxleCc7XG5cbiAgICB0aGlzLmRvYy5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcblxuICAgIHRoaXMuZmxleCA9IG5ldyBGbGV4Q3NzU3R5bGVFbGVtZW50KHN0eWxlKTtcbiAgfVxuXG4gIGluaXRGaWxsKCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgIHN0eWxlLmlkID0gJ2ZjLWZpbGwnO1xuXG4gICAgdGhpcy5kb2MuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG5cbiAgICB0aGlzLmZpbGwgPSBuZXcgRmxleENzc1N0eWxlRWxlbWVudChzdHlsZSk7XG4gIH1cblxuICBhZGRMYXlvdXQobGF5b3V0OiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlTGF5b3V0Q2xhc3NOYW1lKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUsIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IGJ1aWxkQ1NTKGRpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmUpO1xuXG4gICAgICB0aGlzLmFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkTGF5b3V0QWxpZ24obGF5b3V0OiBzdHJpbmcsIGxheW91dEJyZWFrcG9pbnQ6IHN0cmluZywgYWxpZ246IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBbbWFpbkF4aXMsIGNyb3NzQXhpc10gPSBub3JtYWxpemVMYXlvdXRBbGlnblZhbHVlKGFsaWduKTtcblxuICAgIGNvbnN0IGxheW91dEFsaWduQ2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRBbGlnbkNsYXNzTmFtZShtYWluQXhpcywgY3Jvc3NBeGlzLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkxheW91dFN0b3JhZ2UobGF5b3V0QWxpZ25DbGFzc05hbWUsIGJyZWFrcG9pbnQpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgJ2p1c3RpZnktY29udGVudCc6IG1haW5BeGlzLFxuICAgICAgfTtcblxuICAgICAgc3dpdGNoIChjcm9zc0F4aXMpIHtcbiAgICAgICAgY2FzZSAnYmFzZWxpbmUnOlxuICAgICAgICAgIHN0eWxlWydhbGlnbi1pdGVtcyddID0gY3Jvc3NBeGlzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHN0eWxlWydhbGlnbi1pdGVtcyddID0gc3R5bGVbJ2FsaWduLWNvbnRlbnQnXSA9IGNyb3NzQXhpcztcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZGRUb0xheW91dFN0b3JhZ2UobGF5b3V0QWxpZ25DbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICBpZiAoY3Jvc3NBeGlzID09PSAnc3RyZXRjaCcpIHtcbiAgICAgIGNvbnN0IFtkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lXSA9IHZhbGlkYXRlVmFsdWUobGF5b3V0KTtcblxuICAgICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGxheW91dEFsaWduQ2xhc3NOYW1lICsgJy4nICsgbGF5b3V0Q2xhc3NOYW1lO1xuXG4gICAgICBpZiAoIXRoaXMuaGFzSW5MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBpc0Zsb3dIb3Jpem9udGFsKGxheW91dCkgPyB7ICdtYXgtaGVpZ2h0JzogJzEwMCUnIH0gOiB7ICdtYXgtd2lkdGgnOiAnMTAwJScgfTtcblxuICAgICAgICB0aGlzLmFkZFRvTGF5b3V0U3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsYXlvdXRBbGlnbkNsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZExheW91dEdhcChsYXlvdXQ6IHN0cmluZywgbGF5b3V0QnJlYWtwb2ludDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHZhbHVlID0gdmFsdWUgfHwgJzAnO1xuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBsYXlvdXRHYXBDbGFzc05hbWUgPSBnZW5lcmF0ZUxheW91dEdhcENsYXNzTmFtZSh2YWx1ZSwgYnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBsYXlvdXRHYXBDbGFzc05hbWUgKyAnLicgKyBsYXlvdXRDbGFzc05hbWUgKyAnID4gKjpub3QoOmxhc3QtY2hpbGQpJztcblxuICAgIGlmICghdGhpcy5oYXNJbkxheW91dFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSBpc0Zsb3dIb3Jpem9udGFsKGxheW91dCkgPyB7ICdtYXJnaW4tcmlnaHQnOiB2YWx1ZSB9IDogeyAnbWFyZ2luLWJvdHRvbSc6IHZhbHVlIH07XG5cbiAgICAgIHRoaXMuYWRkVG9MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIFtsYXlvdXRCcmVha3BvaW50XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxheW91dEdhcENsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXgobGF5b3V0OiBzdHJpbmcsIGxheW91dEJyZWFrcG9pbnQ6IHN0cmluZywgdmFsdWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nLCBncm93Pywgc2hyaW5rPykge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgnOycsICcnKTtcblxuICAgIGxldCBbdGhlR3JvdywgdGhlU2hyaW5rLCB0aGVCYXNpc10gPSB2YWxpZGF0ZUJhc2lzKHZhbHVlLCBncm93LCBzaHJpbmspO1xuXG4gICAgdGhlR3JvdyA9ICh0aGVHcm93ID09PSAnMCcpID8gMCA6IHRoZUdyb3c7XG4gICAgdGhlU2hyaW5rID0gKHRoZVNocmluayA9PT0gJzAnKSA/IDAgOiB0aGVTaHJpbms7XG5cbiAgICAvLyBmbGV4LWJhc2lzIGFsbG93cyB5b3UgdG8gc3BlY2lmeSB0aGUgaW5pdGlhbC9zdGFydGluZyBtYWluLWF4aXMgc2l6ZSBvZiB0aGUgZWxlbWVudCxcbiAgICAvLyBiZWZvcmUgYW55dGhpbmcgZWxzZSBpcyBjb21wdXRlZC4gSXQgY2FuIGVpdGhlciBiZSBhIHBlcmNlbnRhZ2Ugb3IgYW4gYWJzb2x1dGUgdmFsdWUuXG4gICAgLy8gSXQgaXMsIGhvd2V2ZXIsIG5vdCB0aGUgYnJlYWtpbmcgcG9pbnQgZm9yIGZsZXgtZ3Jvdy9zaHJpbmsgcHJvcGVydGllc1xuICAgIC8vXG4gICAgLy8gZmxleC1ncm93IGNhbiBiZSBzZWVuIGFzIHRoaXM6XG4gICAgLy8gICAwOiBEbyBub3Qgc3RyZXRjaC4gRWl0aGVyIHNpemUgdG8gZWxlbWVudCdzIGNvbnRlbnQgd2lkdGgsIG9yIG9iZXkgJ2ZsZXgtYmFzaXMnLlxuICAgIC8vICAgMTogKERlZmF1bHQgdmFsdWUpLiBTdHJldGNoOyB3aWxsIGJlIHRoZSBzYW1lIHNpemUgdG8gYWxsIG90aGVyIGZsZXggaXRlbXMgb25cbiAgICAvLyAgICAgICB0aGUgc2FtZSByb3cgc2luY2UgdGhleSBoYXZlIGEgZGVmYXVsdCB2YWx1ZSBvZiAxLlxuICAgIC8vICAg4omlMiAoaW50ZWdlciBuKTogU3RyZXRjaC4gV2lsbCBiZSBuIHRpbWVzIHRoZSBzaXplIG9mIG90aGVyIGVsZW1lbnRzXG4gICAgLy8gICAgICB3aXRoICdmbGV4LWdyb3c6IDEnIG9uIHRoZSBzYW1lIHJvdy5cblxuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgJ2JveC1zaXppbmcnOiAnYm9yZGVyLWJveCcsXG4gICAgfTtcblxuICAgIHN3aXRjaCAodGhlQmFzaXMgfHwgJycpIHtcbiAgICAgIGNhc2UgJyc6XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgJHt0aGVHcm93fSAke3RoZVNocmlua30gMC4wMDAwMDAwMDFweGA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5pdGlhbCc6ICAgLy8gZGVmYXVsdFxuICAgICAgY2FzZSAnbm9ncm93JzpcbiAgICAgICAgdGhlR3JvdyA9IDA7XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgMCAxIGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2dyb3cnOlxuICAgICAgICBzdHlsZVsnZmxleCddID0gYDEgMSAxMDAlYDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdub3Nocmluayc6XG4gICAgICAgIHRoZVNocmluayA9IDA7XG4gICAgICAgIHN0eWxlWydmbGV4J10gPSBgMSAwIGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2F1dG8nOlxuICAgICAgICBzdHlsZVsnZmxleCddID0gYCR7dGhlR3Jvd30gJHt0aGVTaHJpbmt9IGF1dG9gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICB0aGVHcm93ID0gMDtcbiAgICAgICAgdGhlU2hyaW5rID0gMDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgnXSA9IGAwIDAgYXV0b2A7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc3QgaXNDYWxjID0gU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdjYWxjJykgPiAtMTtcbiAgICAgICAgY29uc3QgaXNQZXJjZW50ID0gIWlzQ2FsYyAmJiBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJyUnKSA+IC0xO1xuXG4gICAgICAgIGNvbnN0IGlzVmFsdWUgPSBpc0NhbGMgfHwgaXNQZXJjZW50IHx8XG4gICAgICAgICAgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCdweCcpID4gLTEgfHxcbiAgICAgICAgICBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ2VtJykgPiAtMSB8fFxuICAgICAgICAgIFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZigndncnKSA+IC0xIHx8XG4gICAgICAgICAgU3RyaW5nKHRoZUJhc2lzKS5pbmRleE9mKCd2aCcpID4gLTE7XG5cbiAgICAgICAgLy8gRGVmYXVsdHMgdG8gcGVyY2VudGFnZSBzaXppbmcgdW5sZXNzIGBweGAgaXMgZXhwbGljaXRseSBzZXRcbiAgICAgICAgaWYgKCFpc1ZhbHVlICYmICFpc1BlcmNlbnQgJiYgIWlzTmFOKHRoZUJhc2lzIGFzIGFueSkpIHtcbiAgICAgICAgICB0aGVCYXNpcyA9IHRoZUJhc2lzICsgJyUnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoZUJhc2lzID09PSAnMHB4Jykge1xuICAgICAgICAgIHRoZUJhc2lzID0gJzAlJztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0eWxlWydmbGV4LWdyb3cnXSA9IGAke3RoZUdyb3d9YDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgtc2hyaW5rJ10gPSBgJHt0aGVTaHJpbmt9YDtcbiAgICAgICAgc3R5bGVbJ2ZsZXgtYmFzaXMnXSA9IHN0eWxlWydtaW4td2lkdGgnXSA9IHN0eWxlWydtYXgtd2lkdGgnXSA9IGlzVmFsdWUgPyBgJHt0aGVCYXNpc31gIDogJzEwMCUnO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBmbGV4Q2xhc3NOYW1lID0gZ2VuZXJhdGVGbGV4Q2xhc3NOYW1lKHRoZUdyb3csIHRoZVNocmluaywgdGhlQmFzaXMsIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmxleFN0b3JhZ2UoZmxleENsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShmbGV4Q2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3QgbGF5b3V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVMYXlvdXRDbGFzc05hbWUoZGlyZWN0aW9uLCB3cmFwLCBpc0lubGluZSwgbGF5b3V0QnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBjbGFzc05hbWUgPSBmbGV4Q2xhc3NOYW1lICsgJy4nICsgbGF5b3V0Q2xhc3NOYW1lO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmxleFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3QgbWF4ID0gaXNGbG93SG9yaXpvbnRhbChkaXJlY3Rpb24pID8gJ21heC13aWR0aCcgOiAnbWF4LWhlaWdodCc7XG4gICAgICBjb25zdCBtaW4gPSBpc0Zsb3dIb3Jpem9udGFsKGRpcmVjdGlvbikgPyAnbWluLXdpZHRoJyA6ICdtaW4taGVpZ2h0JztcblxuICAgICAgY29uc3QgdXNpbmdDYWxjID0gKFN0cmluZyh0aGVCYXNpcykuaW5kZXhPZignY2FsYycpID4gLTEpIHx8ICh0aGVCYXNpcyA9PT0gJ2F1dG8nKTtcbiAgICAgIGNvbnN0IGlzUHggPSBTdHJpbmcodGhlQmFzaXMpLmluZGV4T2YoJ3B4JykgPiAtMSB8fCB1c2luZ0NhbGM7XG5cbiAgICAgIC8vIG1ha2UgYm94IGluZmxleGlibGUgd2hlbiBzaHJpbmsgYW5kIGdyb3cgYXJlIGJvdGggemVyb1xuICAgICAgLy8gc2hvdWxkIG5vdCBzZXQgYSBtaW4gd2hlbiB0aGUgZ3JvdyBpcyB6ZXJvXG4gICAgICAvLyBzaG91bGQgbm90IHNldCBhIG1heCB3aGVuIHRoZSBzaHJpbmsgaXMgemVyb1xuICAgICAgY29uc3QgaXNGaXhlZCA9ICF0aGVHcm93ICYmICF0aGVTaHJpbms7XG5cbiAgICAgIGNvbnN0IGxheW91dFN0eWxlID0ge307XG5cbiAgICAgIGxheW91dFN0eWxlW21pbl0gPSAodGhlQmFzaXMgPT09ICcwJScpID8gMCA6IGlzRml4ZWQgfHwgKGlzUHggJiYgdGhlR3JvdykgPyB0aGVCYXNpcyA6IG51bGw7XG4gICAgICBsYXlvdXRTdHlsZVttYXhdID0gKHRoZUJhc2lzID09PSAnMCUnKSA/IDAgOiBpc0ZpeGVkIHx8ICghdXNpbmdDYWxjICYmIHRoZVNocmluaykgPyB0aGVCYXNpcyA6IG51bGw7XG5cbiAgICAgIHRoaXMuYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWUsIGxheW91dFN0eWxlLCBicmVha3BvaW50LCBbbGF5b3V0QnJlYWtwb2ludF0pO1xuICAgIH1cblxuICAgIHJldHVybiBmbGV4Q2xhc3NOYW1lO1xuICB9XG5cbiAgYWRkRmxleE9yZGVyKG9yZGVyLCBicmVha3BvaW50OiBzdHJpbmcpIHtcbiAgICBvcmRlciA9IHBhcnNlSW50KG9yZGVyLCAxMCk7XG5cbiAgICBvcmRlciA9IGlzTmFOKG9yZGVyKSA/IDAgOiBvcmRlcjtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleE9yZGVyQ2xhc3NOYW1lKG9yZGVyLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0geydvcmRlcic6IG9yZGVyfTtcblxuICAgICAgdGhpcy5hZGRUb0ZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxuICBhZGRGbGV4T2Zmc2V0KGxheW91dDogc3RyaW5nLCBsYXlvdXRCcmVha3BvaW50OiBzdHJpbmcsIG9mZnNldCwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gICAgY29uc3QgaXNQZXJjZW50ID0gU3RyaW5nKG9mZnNldCkuaW5kZXhPZignJScpID4gLTE7XG4gICAgY29uc3QgaXNQeCA9IFN0cmluZyhvZmZzZXQpLmluZGV4T2YoJ3B4JykgPiAtMTtcblxuICAgIGlmICghaXNQeCAmJiAhaXNQZXJjZW50ICYmICFpc05hTihvZmZzZXQpKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgKyAnJSc7XG4gICAgfVxuXG4gICAgY29uc3QgW2RpcmVjdGlvbiwgd3JhcCwgaXNJbmxpbmVdID0gdmFsaWRhdGVWYWx1ZShsYXlvdXQpO1xuXG4gICAgY29uc3Qgb2Zmc2V0Q2xhc3NOYW1lID0gZ2VuZXJhdGVGbGV4T2Zmc2V0Q2xhc3NOYW1lKG9mZnNldCwgYnJlYWtwb2ludCk7XG5cbiAgICBjb25zdCBsYXlvdXRDbGFzc05hbWUgPSBnZW5lcmF0ZUxheW91dENsYXNzTmFtZShkaXJlY3Rpb24sIHdyYXAsIGlzSW5saW5lLCBsYXlvdXRCcmVha3BvaW50KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IG9mZnNldENsYXNzTmFtZSArICcuJyArIGxheW91dENsYXNzTmFtZTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0gaXNGbG93SG9yaXpvbnRhbChkaXJlY3Rpb24pID8geydtYXJnaW4tbGVmdCc6IGAke29mZnNldH1gfSA6IHsnbWFyZ2luLXRvcCc6IGAke29mZnNldH1gfTtcblxuICAgICAgdGhpcy5hZGRUb0ZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIFtsYXlvdXRCcmVha3BvaW50XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldENsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXhBbGlnbihhbGlnbiwgYnJlYWtwb2ludDogc3RyaW5nKSB7XG4gICAgYWxpZ24gPSBhbGlnbiB8fCAnc3RyZXRjaCc7XG5cbiAgICAvLyBDcm9zcy1heGlzXG4gICAgc3dpdGNoIChhbGlnbikge1xuICAgICAgY2FzZSAnc3RhcnQnOlxuICAgICAgICBhbGlnbiA9ICdmbGV4LXN0YXJ0JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdlbmQnOlxuICAgICAgICBhbGlnbiA9ICdmbGV4LWVuZCc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleEFsaWduQ2xhc3NOYW1lKGFsaWduLCBicmVha3BvaW50KTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZsZXhTdG9yYWdlKGNsYXNzTmFtZSwgYnJlYWtwb2ludCkpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0geydhbGlnbi1zZWxmJzogYWxpZ259O1xuXG4gICAgICB0aGlzLmFkZFRvRmxleFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNsYXNzTmFtZTtcbiAgfVxuXG4gIGFkZEZsZXhGaWxsKCkge1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleEZpbGxDbGFzc05hbWUoKTtcblxuICAgIGlmICghdGhpcy5oYXNJbkZpbGxTdG9yYWdlKGNsYXNzTmFtZSwgJ2FsbCcpKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgJ21hcmdpbic6IDAsXG4gICAgICAgICd3aWR0aCc6ICcxMDAlJyxcbiAgICAgICAgJ2hlaWdodCc6ICcxMDAlJyxcbiAgICAgICAgJ21pbi13aWR0aCc6ICcxMDAlJyxcbiAgICAgICAgJ21pbi1oZWlnaHQnOiAnMTAwJScsXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmFkZFRvRmlsbFN0b3JhZ2UoY2xhc3NOYW1lLCBzdHlsZSwgJ2FsbCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxuICBhZGRTaG93SGlkZShkaXNwbGF5OiBzdHJpbmcsIHNob3c6IGJvb2xlYW4sIGJyZWFrcG9pbnQ6IHN0cmluZykge1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGdlbmVyYXRlRmxleFNob3dIaWRlQ2xhc3NOYW1lKGRpc3BsYXksIHNob3csIGJyZWFrcG9pbnQpO1xuXG4gICAgaWYgKCF0aGlzLmhhc0luRmlsbFN0b3JhZ2UoY2xhc3NOYW1lLCBicmVha3BvaW50KSkge1xuICAgICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgICdkaXNwbGF5Jzogc2hvdyA/IGRpc3BsYXkgfHwgJ2Jsb2NrJyA6ICdub25lJyxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuYWRkVG9GaWxsU3RvcmFnZShjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNJbkxheW91dFN0b3JhZ2UoY2xhc3NOYW1lOiBzdHJpbmcsIGJyZWFrcG9pbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmhhc0luU3RvcmFnZSh0aGlzLmxheW91dCwgY2xhc3NOYW1lLCBicmVha3BvaW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9MYXlvdXRTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUb1N0b3JhZ2UodGhpcy5sYXlvdXQsIGNsYXNzTmFtZSwgc3R5bGUsIGJyZWFrcG9pbnQsIGN1c3RvbUJyZWFrcG9pbnRzKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFzSW5GbGV4U3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgYnJlYWtwb2ludDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzSW5TdG9yYWdlKHRoaXMuZmxleCwgY2xhc3NOYW1lLCBicmVha3BvaW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVG9GbGV4U3RvcmFnZShjbGFzc05hbWU6IHN0cmluZywgc3R5bGU6IFN0eWxlRGVmaW5pdGlvbiwgYnJlYWtwb2ludDogc3RyaW5nLCBjdXN0b21CcmVha3BvaW50cz86IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkVG9TdG9yYWdlKHRoaXMuZmxleCwgY2xhc3NOYW1lLCBzdHlsZSwgYnJlYWtwb2ludCwgY3VzdG9tQnJlYWtwb2ludHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNJbkZpbGxTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5oYXNJblN0b3JhZ2UodGhpcy5maWxsLCBjbGFzc05hbWUsIGJyZWFrcG9pbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRUb0ZpbGxTdG9yYWdlKGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUb1N0b3JhZ2UodGhpcy5maWxsLCBjbGFzc05hbWUsIHN0eWxlLCBicmVha3BvaW50LCBjdXN0b21CcmVha3BvaW50cyk7XG4gIH1cblxuICBwcml2YXRlIGhhc0luU3RvcmFnZShzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nLCBicmVha3BvaW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEoc3R5bGVFbGVtZW50LnN0b3JhZ2VbYnJlYWtwb2ludF0gJiYgc3R5bGVFbGVtZW50LnN0b3JhZ2VbYnJlYWtwb2ludF1bY2xhc3NOYW1lXSk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRvU3RvcmFnZShcbiAgICBzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nLCBzdHlsZTogU3R5bGVEZWZpbml0aW9uLCBicmVha3BvaW50OiBzdHJpbmcsIGN1c3RvbUJyZWFrcG9pbnRzPzogc3RyaW5nW10pIHtcbiAgICBjdXN0b21CcmVha3BvaW50cyA9IGN1c3RvbUJyZWFrcG9pbnRzIHx8IFtdO1xuXG4gICAgY29uc3Qgc3R5bGVzID0gYXBwbHlDc3NQcmVmaXhlcyhzdHlsZSk7XG5cbiAgICBjb25zdCBjc3MgPSB0aGlzLmdlbmVyYXRlQ3NzKHN0eWxlcyk7XG5cbiAgICBpZiAoY3NzICE9PSAnJykge1xuICAgICAgY29uc3QgY2xhc3NDc3MgPSAnLicgKyBjbGFzc05hbWUgKyAnIHsgJyArIGNzcyArICcgfSc7XG5cbiAgICAgIGNvbnN0IGNzc0VsZW1lbnQgPSB0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh0aGlzLmFkZEJyZWFrcG9pbnRzKFticmVha3BvaW50XS5jb25jYXQoY3VzdG9tQnJlYWtwb2ludHMpLCBjbGFzc0NzcykpO1xuXG4gICAgICBpZiAoIXN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdKSB7XG4gICAgICAgIHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdID0ge307XG4gICAgICB9XG5cbiAgICAgIHN0eWxlRWxlbWVudC5zdG9yYWdlW2JyZWFrcG9pbnRdW2NsYXNzTmFtZV0gPSBjc3NFbGVtZW50O1xuXG4gICAgICB0aGlzLnJlb3JkZXJUZXh0RWxlbWVudHMoc3R5bGVFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlb3JkZXJUZXh0RWxlbWVudHMoc3R5bGVFbGVtZW50OiBGbGV4Q3NzU3R5bGVFbGVtZW50KSB7XG4gICAgbGV0IHBvc2l0aW9uID0gdGhpcy5yZW9yZGVyQnJlYWtwb2ludEVsZW1lbnRzKHN0eWxlRWxlbWVudCwgJ2FsbCcpO1xuXG4gICAgdGhpcy5icmVha3BvaW50cy5mb3JFYWNoKGJyZWFrcG9pbnQgPT4ge1xuICAgICAgcG9zaXRpb24gPSB0aGlzLnJlb3JkZXJCcmVha3BvaW50RWxlbWVudHMoc3R5bGVFbGVtZW50LCBicmVha3BvaW50LmFsaWFzLCBwb3NpdGlvbik7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVvcmRlckJyZWFrcG9pbnRFbGVtZW50cyhzdHlsZUVsZW1lbnQ6IEZsZXhDc3NTdHlsZUVsZW1lbnQsIGJyZWFrcG9pbnQ6IHN0cmluZywgcG9zaXRpb246IG51bWJlciA9IDApIHtcbiAgICBjb25zdCBicmVha3BvaW50RWxlbWVudHMgPSBzdHlsZUVsZW1lbnQuc3RvcmFnZVticmVha3BvaW50XTtcblxuICAgIGlmICghYnJlYWtwb2ludEVsZW1lbnRzKSB7XG4gICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoYnJlYWtwb2ludEVsZW1lbnRzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICBzdHlsZUVsZW1lbnQuc3R5bGUuaW5zZXJ0QmVmb3JlKGJyZWFrcG9pbnRFbGVtZW50c1trZXldLCBzdHlsZUVsZW1lbnQuc3R5bGUuY2hpbGRyZW5bcG9zaXRpb25dKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0eWxlRWxlbWVudC5zdHlsZS5hcHBlbmRDaGlsZChicmVha3BvaW50RWxlbWVudHNba2V5XSk7XG4gICAgICB9XG5cbiAgICAgICsrcG9zaXRpb247XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcG9zaXRpb247XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlQ3NzKHN0eWxlczogT2JqZWN0KSB7XG4gICAgY29uc3QgY3NzID0gW107XG5cbiAgICBPYmplY3Qua2V5cyhzdHlsZXMpLnNvcnQoKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBBcnJheS5pc0FycmF5KHN0eWxlc1trZXldKSA/IHN0eWxlc1trZXldIDogW3N0eWxlc1trZXldXTtcblxuICAgICAgdmFsdWVzLnNvcnQoKTtcblxuICAgICAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgY3NzLnB1c2goa2V5ICsgJzogJyArIHZhbHVlICsgJzsnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3NzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQnJlYWtwb2ludHMoYnJlYWtwb2ludHNBbGlhc2VzOiBzdHJpbmdbXSwgY3NzOiBzdHJpbmcpIHtcbiAgICBicmVha3BvaW50c0FsaWFzZXMgPSBicmVha3BvaW50c0FsaWFzZXMuZmlsdGVyKGJyZWFrcG9pbnQgPT4gYnJlYWtwb2ludCAhPT0gJ2FsbCcpO1xuXG4gICAgaWYgKCFicmVha3BvaW50c0FsaWFzZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gY3NzO1xuICAgIH1cblxuICAgIGxldCB0aGVCcmVha3BvaW50cyA9IFtdO1xuXG4gICAgdGhpcy5icmVha3BvaW50c1xuICAgICAgLmZpbHRlcihicmVha3BvaW50ID0+IGJyZWFrcG9pbnRzQWxpYXNlcy5pbmRleE9mKGJyZWFrcG9pbnQuYWxpYXMpID49IDApXG4gICAgICAuZm9yRWFjaChicmVha3BvaW50ID0+IHRoZUJyZWFrcG9pbnRzID0gdGhlQnJlYWtwb2ludHMuY29uY2F0KGJyZWFrcG9pbnQubWVkaWEpKTtcblxuICAgIHRoZUJyZWFrcG9pbnRzID0gdGhlQnJlYWtwb2ludHMuZmlsdGVyKCh2YWx1ZSwgaW5kZXgsIHNlbGYpID0+IHNlbGYuaW5kZXhPZih2YWx1ZSkgPT09IGluZGV4KTtcblxuICAgIHJldHVybiAnQG1lZGlhICcgKyB0aGVCcmVha3BvaW50cy5qb2luKCcgYW5kICcpICsgJyB7ICcgKyBjc3MgKyAnIH0nO1xuICB9XG59XG4iXX0=