@alauda-fe/common
Version:
Alauda frontend team common codes.
356 lines • 50.5 kB
JavaScript
import { ContentChildren, Directive, ElementRef, EventEmitter, HostListener, Input, Output, QueryList, } from '@angular/core';
import { coerceElement, isSelfOrParent } from './element';
import { isL, isT, toNumber, toPx } from './util';
import * as i0 from "@angular/core";
export const MUTABLE_BASIC_OPTIONS = {
directions: [true, true, true, true],
resizeThreshold: 5,
cursors: {
move: 'move',
},
};
export class DragHandleDirective {
static { this.ɵfac = function DragHandleDirective_Factory(t) { return new (t || DragHandleDirective)(); }; }
static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: DragHandleDirective, selectors: [["", "aclDragHandle", ""]] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DragHandleDirective, [{
type: Directive,
args: [{
selector: '[aclDragHandle]',
}]
}], null, null); })();
export class MutableDirective {
set aclMutableOptions(options) {
this.computedOptions = {
...MUTABLE_BASIC_OPTIONS,
...options,
};
}
onMouseDown(event) {
if (!isSelfOrParent(event.target, this.element)) {
return;
}
const cursor = this.getMutableCursor(event);
if (cursor === this.computedOptions.cursors.move) {
this.setDragging(cursor, event);
this.aclDragStarted.emit(this.element);
}
else if (this.aclResizable && cursor.includes('-resize')) {
this.setResizing(cursor, event);
this.aclResizeStarted.emit(this.element);
}
}
onMouseMove(event) {
this.element.style.cursor = this.getMutableCursor(event);
if (this.isDragging) {
this.dragElement(event);
this.aclOnDrag.emit(this.element);
}
if (this.isResizingX || this.isResizingY) {
this.isResizingX && this.resizeElementX(event);
this.isResizingY && this.resizeElementY(event);
this.aclOnResize.emit(this.element);
}
}
onMouseUp() {
if (this.aclDraggable) {
this.setDragging(null, null);
this.aclDragEnded.emit(this.element);
}
if (this.aclResizable) {
this.setResizing(null, null);
this.aclResizeEnded.emit(this.element);
}
}
constructor(el) {
this.el = el;
this.computedOptions = MUTABLE_BASIC_OPTIONS;
/** Allow for stretch shrink, the default is open */
this.aclResizable = true;
/** Allow for drag and drop, the default is open */
this.aclDraggable = true;
/** In the process of the resize triggering events */
this.aclOnResize = new EventEmitter();
/** Drag in the process of the triggering event */
this.aclOnDrag = new EventEmitter();
/** Emits when the user start drag. */
this.aclDragStarted = new EventEmitter();
this.aclDragEnded = new EventEmitter();
/** Emits when the user start resize */
this.aclResizeStarted = new EventEmitter();
this.aclResizeEnded = new EventEmitter();
this.isDragging = false;
this.isResizingX = false;
this.isResizingY = false;
this.mousePoint = { x: 0, y: 0 };
this.element = null;
this.resizeInitXRight = 0;
this.resizeInitYBottom = 0;
this.element = this.el.nativeElement;
this._initCursor = this.element.style.cursor;
}
/** Gets the boundary element, based on the `boundaryElement` value. */
getBoundaryElement() {
const boundary = this.aclDragBoundary;
if (!boundary) {
return this.element.parentNode;
}
if (typeof boundary === 'string') {
return this.element.closest(boundary);
}
return coerceElement(boundary);
}
ensureInParent(point) {
const parent = this.getBoundaryElement();
const elementRect = this.element.getBoundingClientRect();
if (point.x < 0) {
point.x = 0;
}
else if (point.x >= parent.clientWidth - elementRect.width) {
point.x = parent.clientWidth - elementRect.width;
}
if (point.y < 0) {
point.y = 0;
}
else if (point.y >= parent.clientHeight - elementRect.height) {
point.y = parent.clientHeight - elementRect.height;
}
return point;
}
dragElement(event) {
const parentElement = this.getBoundaryElement();
const parentRect = {
left: parentElement.getBoundingClientRect().left + parentElement.scrollLeft,
top: parentElement.getBoundingClientRect().top + parentElement.scrollTop,
};
const { x, y } = this.ensureInParent({
x: event.clientX -
parentRect.left -
this.parentBorder.left -
this.mousePoint.x,
y: event.clientY -
parentRect.top -
this.parentBorder.top -
this.mousePoint.y,
});
if (this.computedOptions.dragRange) {
const [t, r, b, l] = this.computedOptions.dragRange.map((key, index) => {
if (typeof key === 'number') {
return ((key / 100) *
([1, 3].includes(index)
? parentElement.clientWidth
: parentElement.clientHeight));
}
if (typeof key === 'string' && key.includes('px')) {
return toNumber(key);
}
console.error('DragRange in mutableOptions is invalid!');
return 0;
});
this.element.style.left = toPx(Math.max(l, Math.min(x, parentElement.clientWidth - r)));
this.element.style.top = toPx(Math.max(t, Math.min(y, parentElement.clientHeight - b)));
return;
}
this.element.style.left = toPx(x);
this.element.style.top = toPx(y);
}
initDragging(event) {
const rect = this.element.getBoundingClientRect();
this.mousePoint.x = event.clientX - rect.left;
this.mousePoint.y = event.clientY - rect.top;
const { borderLeft, borderTop } = getComputedStyle(this.getBoundaryElement());
this.parentBorder = {
left: toNumber(borderLeft),
top: toNumber(borderTop),
};
}
setDragging(cursor, event) {
this.isDragging = cursor === this.computedOptions.cursors.move;
if (this.isDragging) {
this.initDragging(event);
}
}
resizeElementX(event) {
if (this.isResizeOutOfBoundary(event, 'horizontal')) {
return;
}
const elementRect = this.element.getBoundingClientRect();
let width;
const { minWidth, maxWidth, left } = getComputedStyle(this.element);
const computedMinWidth = Math.max(toNumber(minWidth), this.elementBorder.left + this.elementBorder.right);
if (isL(this.resizeCursor)) {
const targetLeft = event.clientX - this.mousePoint.x;
const computedWidth = this.resizeInitXRight - targetLeft;
width = Math.max(toNumber(maxWidth)
? Math.min(computedWidth, toNumber(maxWidth))
: computedWidth, computedMinWidth);
this.element.style.left = toPx(toNumber(left) + elementRect.width - width);
}
else {
const targetRight = event.clientX + this.mousePoint.x;
const computedWidth = targetRight - elementRect.left;
width = Math.max(toNumber(maxWidth)
? Math.min(computedWidth, toNumber(maxWidth))
: computedWidth, computedMinWidth);
}
if (width < this.elementBorder.left + this.elementBorder.right) {
return;
}
this.element.style.width = toPx(width);
}
resizeElementY(event) {
if (this.isResizeOutOfBoundary(event, 'vertical')) {
return;
}
const elementRect = this.element.getBoundingClientRect();
const { minHeight, maxHeight, top } = getComputedStyle(this.element);
const computedMinHeight = Math.max(toNumber(minHeight), this.elementBorder.top + this.elementBorder.bottom);
let height;
if (isT(this.resizeCursor)) {
const targetTop = event.clientY - this.mousePoint.y;
const computedHeight = this.resizeInitYBottom - targetTop;
height = Math.max(toNumber(maxHeight)
? Math.min(computedHeight, toNumber(maxHeight))
: computedHeight, computedMinHeight);
this.element.style.top = toPx(toNumber(top) + elementRect.height - height);
}
else {
const targetBottom = event.clientY + this.mousePoint.y;
const computedHeight = targetBottom - elementRect.top;
height = Math.max(toNumber(maxHeight)
? Math.min(computedHeight, toNumber(maxHeight))
: computedHeight, computedMinHeight);
}
if (height < this.elementBorder.top + this.elementBorder.bottom) {
return;
}
this.element.style.height = toPx(height);
}
initResizing(event) {
const elementRect = this.element.getBoundingClientRect();
this.resizeInitXRight = elementRect.right;
this.resizeInitYBottom = elementRect.bottom;
this.mousePoint.x = isL(this.resizeCursor)
? event.clientX - elementRect.left
: elementRect.right - event.clientX;
this.mousePoint.y = isT(this.resizeCursor)
? event.clientY - elementRect.top
: elementRect.bottom - event.clientY;
const { borderLeft, borderTop, borderBottom, borderRight } = getComputedStyle(this.element);
this.elementBorder = {
left: toNumber(borderLeft),
top: toNumber(borderTop),
bottom: toNumber(borderBottom),
right: toNumber(borderRight),
};
}
setResizing(cursor, event) {
if (cursor == null || !cursor.includes('-resize')) {
this.isResizingX = false;
this.isResizingY = false;
return;
}
cursor = cursor.replace('-resize', '');
this.isResizingX = cursor.includes('e') || cursor.includes('w');
this.isResizingY = cursor.includes('s') || cursor.includes('n');
this.initResizing(event);
}
// eslint-disable-next-line sonarjs/cognitive-complexity
getMutableCursor(event) {
if (this.isResizingX || this.isResizingY) {
return;
}
const elementRect = this.element.getBoundingClientRect();
const resizeThreshold = this.computedOptions.resizeThreshold;
const pt = {
x: event.clientX,
y: event.clientY,
};
let cursor = '';
const dragThreshold = this.aclResizable ? resizeThreshold : 0;
if (this.aclDraggable &&
pt.x < elementRect.right - dragThreshold &&
pt.x > elementRect.left + dragThreshold &&
pt.y < elementRect.bottom - dragThreshold &&
pt.y > elementRect.top + dragThreshold &&
(!this.handles?.length ||
this.handles?.some(h => isSelfOrParent(event.target, h.nativeElement)))) {
cursor = this.computedOptions.cursors.move;
}
if (this.aclResizable && !cursor) {
if (pt.y >= elementRect.top &&
pt.y <= elementRect.top + resizeThreshold) {
cursor += 'n';
}
else if (pt.y >= elementRect.bottom - resizeThreshold &&
pt.y <= elementRect.bottom) {
cursor += 's';
}
if (pt.x >= elementRect.left &&
pt.x <= elementRect.left + resizeThreshold) {
cursor += 'w';
}
else if (pt.x >= elementRect.right - resizeThreshold &&
pt.x <= elementRect.right) {
cursor += 'e';
}
cursor = cursor ? cursor + '-resize' : '';
}
this.resizeCursor = cursor;
return cursor || this._initCursor;
}
isResizeOutOfBoundary(event, direction) {
const parentElement = this.getBoundaryElement();
const eventProp = direction === 'horizontal' ? 'clientX' : 'clientY';
const parentProp = direction === 'horizontal' ? 'clientWidth' : 'clientHeight';
return event[eventProp] < 0 || event[eventProp] > parentElement[parentProp];
}
static { this.ɵfac = function MutableDirective_Factory(t) { return new (t || MutableDirective)(i0.ɵɵdirectiveInject(i0.ElementRef)); }; }
static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: MutableDirective, selectors: [["", "aclMutable", ""]], contentQueries: function MutableDirective_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
i0.ɵɵcontentQuery(dirIndex, DragHandleDirective, 5, ElementRef);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.handles = _t);
} }, hostBindings: function MutableDirective_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵlistener("mousedown", function MutableDirective_mousedown_HostBindingHandler($event) { return ctx.onMouseDown($event); }, false, i0.ɵɵresolveDocument)("mousemove", function MutableDirective_mousemove_HostBindingHandler($event) { return ctx.onMouseMove($event); }, false, i0.ɵɵresolveDocument)("mouseup", function MutableDirective_mouseup_HostBindingHandler() { return ctx.onMouseUp(); }, false, i0.ɵɵresolveDocument);
} }, inputs: { aclResizable: "aclResizable", aclDraggable: "aclDraggable", aclDragBoundary: "aclDragBoundary", aclMutableOptions: "aclMutableOptions" }, outputs: { aclOnResize: "aclOnResize", aclOnDrag: "aclOnDrag", aclDragStarted: "aclDragStarted", aclDragEnded: "aclDragEnded", aclResizeStarted: "aclResizeStarted", aclResizeEnded: "aclResizeEnded" } }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MutableDirective, [{
type: Directive,
args: [{
selector: '[aclMutable]',
}]
}], () => [{ type: i0.ElementRef }], { aclResizable: [{
type: Input
}], aclDraggable: [{
type: Input
}], aclDragBoundary: [{
type: Input
}], aclMutableOptions: [{
type: Input
}], aclOnResize: [{
type: Output
}], aclOnDrag: [{
type: Output
}], aclDragStarted: [{
type: Output
}], aclDragEnded: [{
type: Output
}], aclResizeStarted: [{
type: Output
}], aclResizeEnded: [{
type: Output
}], handles: [{
type: ContentChildren,
args: [DragHandleDirective, { read: ElementRef, descendants: true }]
}], onMouseDown: [{
type: HostListener,
args: ['document:mousedown', ['$event']]
}], onMouseMove: [{
type: HostListener,
args: ['document:mousemove', ['$event']]
}], onMouseUp: [{
type: HostListener,
args: ['document:mouseup']
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV0YWJsZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvbXV0YWJsZS9tdXRhYmxlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMxRCxPQUFPLEVBQWdCLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7QUFZaEUsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQW1CO0lBQ25ELFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQztJQUNwQyxlQUFlLEVBQUUsQ0FBQztJQUNsQixPQUFPLEVBQUU7UUFDUCxJQUFJLEVBQUUsTUFBTTtLQUNiO0NBQ0YsQ0FBQztBQVVGLE1BQU0sT0FBTyxtQkFBbUI7b0ZBQW5CLG1CQUFtQjtvRUFBbkIsbUJBQW1COztpRkFBbkIsbUJBQW1CO2NBSC9CLFNBQVM7ZUFBQztnQkFDVCxRQUFRLEVBQUUsaUJBQWlCO2FBQzVCOztBQU1ELE1BQU0sT0FBTyxnQkFBZ0I7SUFVM0IsSUFDSSxpQkFBaUIsQ0FBQyxPQUF1QjtRQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHO1lBQ3JCLEdBQUcscUJBQXFCO1lBQ3hCLEdBQUcsT0FBTztTQUNYLENBQUM7SUFDSixDQUFDO0lBdUNELFdBQVcsQ0FBQyxLQUFpQjtRQUMzQixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxNQUFxQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lB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WTtrQkFBcEIsS0FBSztZQUVHLGVBQWU7a0JBQXZCLEtBQUs7WUFHRixpQkFBaUI7a0JBRHBCLEtBQUs7WUFVRyxXQUFXO2tCQURuQixNQUFNO1lBSVksU0FBUztrQkFBM0IsTUFBTTtZQUVZLGNBQWM7a0JBQWhDLE1BQU07WUFDWSxZQUFZO2tCQUE5QixNQUFNO1lBRVksZ0JBQWdCO2tCQUFsQyxNQUFNO1lBQ1ksY0FBYztrQkFBaEMsTUFBTTtZQUdQLE9BQU87a0JBRE4sZUFBZTttQkFBQyxtQkFBbUIsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtZQXdCN0UsV0FBVztrQkFEVixZQUFZO21CQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO1lBaUI5QyxXQUFXO2tCQURWLFlBQVk7bUJBQUMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7WUFpQjlDLFNBQVM7a0JBRFIsWUFBWTttQkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb250ZW50Q2hpbGRyZW4sXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGNvZXJjZUVsZW1lbnQsIGlzU2VsZk9yUGFyZW50IH0gZnJvbSAnLi9lbGVtZW50JztcbmltcG9ydCB7IFJlc2l6ZUN1cnNvciwgaXNMLCBpc1QsIHRvTnVtYmVyLCB0b1B4IH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IHR5cGUgRHJhZ1JhbmdlID0gbnVtYmVyIHwgc3RyaW5nO1xuZXhwb3J0IGludGVyZmFjZSBNdXRhYmxlT3B0aW9ucyB7XG4gIGRpcmVjdGlvbnM/OiBbYm9vbGVhbiwgYm9vbGVhbiwgYm9vbGVhbiwgYm9vbGVhbl07IC8vIHRvcCByaWdodCBib3R0b20gbGVmdDtcbiAgcmVzaXplVGhyZXNob2xkPzogbnVtYmVyO1xuICBjdXJzb3JzPzoge1xuICAgIG1vdmU6IHN0cmluZztcbiAgfTtcbiAgZHJhZ1JhbmdlPzogW0RyYWdSYW5nZSwgRHJhZ1JhbmdlLCBEcmFnUmFuZ2UsIERyYWdSYW5nZV07XG59XG5cbmV4cG9ydCBjb25zdCBNVVRBQkxFX0JBU0lDX09QVElPTlM6IE11dGFibGVPcHRpb25zID0ge1xuICBkaXJlY3Rpb25zOiBbdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZV0sXG4gIHJlc2l6ZVRocmVzaG9sZDogNSxcbiAgY3Vyc29yczoge1xuICAgIG1vdmU6ICdtb3ZlJyxcbiAgfSxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9pbnQge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2FjbERyYWdIYW5kbGVdJyxcbn0pXG5leHBvcnQgY2xhc3MgRHJhZ0hhbmRsZURpcmVjdGl2ZSB7fVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbYWNsTXV0YWJsZV0nLFxufSlcbmV4cG9ydCBjbGFzcyBNdXRhYmxlRGlyZWN0aXZlIHtcbiAgcHJpdmF0ZSBjb21wdXRlZE9wdGlvbnM6IE11dGFibGVPcHRpb25zID0gTVVUQUJMRV9CQVNJQ19PUFRJT05TO1xuXG4gIC8qKiBBbGxvdyBmb3Igc3RyZXRjaCBzaHJpbmssIHRoZSBkZWZhdWx0IGlzIG9wZW4gKi9cbiAgQElucHV0KCkgYWNsUmVzaXphYmxlID0gdHJ1ZTtcbiAgLyoqIEFsbG93IGZvciBkcmFnIGFuZCBkcm9wLCB0aGUgZGVmYXVsdCBpcyBvcGVuICovXG4gIEBJbnB1dCgpIGFjbERyYWdnYWJsZSA9IHRydWU7XG4gIC8qKiBEZWZpbmUgZHJhZyBib3VuZGFyeSwgYXMgYm9keSAqL1xuICBASW5wdXQoKSBhY2xEcmFnQm91bmRhcnk6IHN0cmluZyB8IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQ7XG5cbiAgQElucHV0KClcbiAgc2V0IGFjbE11dGFibGVPcHRpb25zKG9wdGlvbnM6IE11dGFibGVPcHRpb25zKSB7XG4gICAgdGhpcy5jb21wdXRlZE9wdGlvbnMgPSB7XG4gICAgICAuLi5NVVRBQkxFX0JBU0lDX09QVElPTlMsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH07XG4gIH1cblxuICAvKiogSW4gdGhlIHByb2Nlc3Mgb2YgdGhlIHJlc2l6ZSB0cmlnZ2VyaW5nIGV2ZW50cyAqL1xuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgYWNsT25SZXNpemUgPSBuZXcgRXZlbnRFbWl0dGVyPEhUTUxFbGVtZW50PigpO1xuXG4gIC8qKiBEcmFnIGluIHRoZSBwcm9jZXNzIG9mIHRoZSB0cmlnZ2VyaW5nIGV2ZW50ICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBhY2xPbkRyYWcgPSBuZXcgRXZlbnRFbWl0dGVyPEhUTUxFbGVtZW50PigpO1xuICAvKiogRW1pdHMgd2hlbiB0aGUgdXNlciBzdGFydCBkcmFnLiAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgYWNsRHJhZ1N0YXJ0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEhUTUxFbGVtZW50PigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgYWNsRHJhZ0VuZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxIVE1MRWxlbWVudD4oKTtcbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgc3RhcnQgcmVzaXplICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBhY2xSZXNpemVTdGFydGVkID0gbmV3IEV2ZW50RW1pdHRlcjxIVE1MRWxlbWVudD4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGFjbFJlc2l6ZUVuZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxIVE1MRWxlbWVudD4oKTtcblxuICBAQ29udGVudENoaWxkcmVuKERyYWdIYW5kbGVEaXJlY3RpdmUsIHsgcmVhZDogRWxlbWVudFJlZiwgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgaGFuZGxlczogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xuXG4gIGlzRHJhZ2dpbmcgPSBmYWxzZTtcblxuICBpc1Jlc2l6aW5nWCA9IGZhbHNlO1xuXG4gIGlzUmVzaXppbmdZID0gZmFsc2U7XG5cbiAgbW91c2VQb2ludCA9IHsgeDogMCwgeTogMCB9O1xuXG4gIHBhcmVudEJvcmRlcjogeyBsZWZ0OiBudW1iZXI7IHRvcDogbnVtYmVyIH07XG5cbiAgZWxlbWVudEJvcmRlcjogeyBsZWZ0OiBudW1iZXI7IHRvcDogbnVtYmVyOyByaWdodDogbnVtYmVyOyBib3R0b206IG51bWJlciB9O1xuXG4gIGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbDtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9pbml0Q3Vyc29yOiBzdHJpbmc7XG5cbiAgcmVzaXplQ3Vyc29yOiBSZXNpemVDdXJzb3I7XG4gIHJlc2l6ZUluaXRYUmlnaHQgPSAwO1xuICByZXNpemVJbml0WUJvdHRvbSA9IDA7XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vkb3duJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIWlzU2VsZk9yUGFyZW50KGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCwgdGhpcy5lbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjdXJzb3IgPSB0aGlzLmdldE11dGFibGVDdXJzb3IoZXZlbnQpO1xuXG4gICAgaWYgKGN1cnNvciA9PT0gdGhpcy5jb21wdXRlZE9wdGlvbnMuY3Vyc29ycy5tb3ZlKSB7XG4gICAgICB0aGlzLnNldERyYWdnaW5nKGN1cnNvciwgZXZlbnQpO1xuICAgICAgdGhpcy5hY2xEcmFnU3RhcnRlZC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFjbFJlc2l6YWJsZSAmJiBjdXJzb3IuaW5jbHVkZXMoJy1yZXNpemUnKSkge1xuICAgICAgdGhpcy5zZXRSZXNpemluZyhjdXJzb3IsIGV2ZW50KTtcbiAgICAgIHRoaXMuYWNsUmVzaXplU3RhcnRlZC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZU1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuY3Vyc29yID0gdGhpcy5nZXRNdXRhYmxlQ3Vyc29yKGV2ZW50KTtcblxuICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcbiAgICAgIHRoaXMuZHJhZ0VsZW1lbnQoZXZlbnQpO1xuICAgICAgdGhpcy5hY2xPbkRyYWcuZW1pdCh0aGlzLmVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUmVzaXppbmdYIHx8IHRoaXMuaXNSZXNpemluZ1kpIHtcbiAgICAgIHRoaXMuaXNSZXNpemluZ1ggJiYgdGhpcy5yZXNpemVFbGVtZW50WChldmVudCk7XG4gICAgICB0aGlzLmlzUmVzaXppbmdZICYmIHRoaXMucmVzaXplRWxlbWVudFkoZXZlbnQpO1xuICAgICAgdGhpcy5hY2xPblJlc2l6ZS5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2V1cCcpXG4gIG9uTW91c2VVcCgpIHtcbiAgICBpZiAodGhpcy5hY2xEcmFnZ2FibGUpIHtcbiAgICAgIHRoaXMuc2V0RHJhZ2dpbmcobnVsbCwgbnVsbCk7XG4gICAgICB0aGlzLmFjbERyYWdFbmRlZC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWNsUmVzaXphYmxlKSB7XG4gICAgICB0aGlzLnNldFJlc2l6aW5nKG51bGwsIG51bGwpO1xuICAgICAgdGhpcy5hY2xSZXNpemVFbmRlZC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBlbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4pIHtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5faW5pdEN1cnNvciA9IHRoaXMuZWxlbWVudC5zdHlsZS5jdXJzb3I7XG4gIH1cblxuICAvKiogR2V0cyB0aGUgYm91bmRhcnkgZWxlbWVudCwgYmFzZWQgb24gdGhlIGBib3VuZGFyeUVsZW1lbnRgIHZhbHVlLiAqL1xuICBwcml2YXRlIGdldEJvdW5kYXJ5RWxlbWVudCgpIHtcbiAgICBjb25zdCBib3VuZGFyeSA9IHRoaXMuYWNsRHJhZ0JvdW5kYXJ5O1xuXG4gICAgaWYgKCFib3VuZGFyeSkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5wYXJlbnROb2RlIGFzIEhUTUxFbGVtZW50O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYm91bmRhcnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbGVtZW50LmNsb3Nlc3QoYm91bmRhcnkpO1xuICAgIH1cblxuICAgIHJldHVybiBjb2VyY2VFbGVtZW50KGJvdW5kYXJ5KTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlSW5QYXJlbnQocG9pbnQ6IFBvaW50KSB7XG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5nZXRCb3VuZGFyeUVsZW1lbnQoKTtcbiAgICBjb25zdCBlbGVtZW50UmVjdCA9IHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocG9pbnQueCA8IDApIHtcbiAgICAgIHBvaW50LnggPSAwO1xuICAgIH0gZWxzZSBpZiAocG9pbnQueCA+PSBwYXJlbnQuY2xpZW50V2lkdGggLSBlbGVtZW50UmVjdC53aWR0aCkge1xuICAgICAgcG9pbnQueCA9IHBhcmVudC5jbGllbnRXaWR0aCAtIGVsZW1lbnRSZWN0LndpZHRoO1xuICAgIH1cblxuICAgIGlmIChwb2ludC55IDwgMCkge1xuICAgICAgcG9pbnQueSA9IDA7XG4gICAgfSBlbHNlIGlmIChwb2ludC55ID49IHBhcmVudC5jbGllbnRIZWlnaHQgLSBlbGVtZW50UmVjdC5oZWlnaHQpIHtcbiAgICAgIHBvaW50LnkgPSBwYXJlbnQuY2xpZW50SGVpZ2h0IC0gZWxlbWVudFJlY3QuaGVpZ2h0O1xuICAgIH1cbiAgICByZXR1cm4gcG9pbnQ7XG4gIH1cblxuICBkcmFnRWxlbWVudChldmVudDogTW91c2VFdmVudCkge1xuICAgIGNvbnN0IHBhcmVudEVsZW1lbnQgPSB0aGlzLmdldEJvdW5kYXJ5RWxlbWVudCgpO1xuICAgIGNvbnN0IHBhcmVudFJlY3QgPSB7XG4gICAgICBsZWZ0OlxuICAgICAgICBwYXJlbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKyBwYXJlbnRFbGVtZW50LnNjcm9sbExlZnQsXG4gICAgICB0b3A6IHBhcmVudEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wICsgcGFyZW50RWxlbWVudC5zY3JvbGxUb3AsXG4gICAgfTtcblxuICAgIGNvbnN0IHsgeCwgeSB9ID0gdGhpcy5lbnN1cmVJblBhcmVudCh7XG4gICAgICB4OlxuICAgICAgICBldmVudC5jbGllbnRYIC1cbiAgICAgICAgcGFyZW50UmVjdC5sZWZ0IC1cbiAgICAgICAgdGhpcy5wYXJlbnRCb3JkZXIubGVmdCAtXG4gICAgICAgIHRoaXMubW91c2VQb2ludC54LFxuICAgICAgeTpcbiAgICAgICAgZXZlbnQuY2xpZW50WSAtXG4gICAgICAgIHBhcmVudFJlY3QudG9wIC1cbiAgICAgICAgdGhpcy5wYXJlbnRCb3JkZXIudG9wIC1cbiAgICAgICAgdGhpcy5tb3VzZVBvaW50LnksXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5jb21wdXRlZE9wdGlvbnMuZHJhZ1JhbmdlKSB7XG4gICAgICBjb25zdCBbdCwgciwgYiwgbF0gPSB0aGlzLmNvbXB1dGVkT3B0aW9ucy5kcmFnUmFuZ2UubWFwKChrZXksIGluZGV4KSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAoa2V5IC8gMTAwKSAqXG4gICAgICAgICAgICAoWzEsIDNdLmluY2x1ZGVzKGluZGV4KVxuICAgICAgICAgICAgICA/IHBhcmVudEVsZW1lbnQuY2xpZW50V2lkdGhcbiAgICAgICAgICAgICAgOiBwYXJlbnRFbGVtZW50LmNsaWVudEhlaWdodClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyAmJiBrZXkuaW5jbHVkZXMoJ3B4JykpIHtcbiAgICAgICAgICByZXR1cm4gdG9OdW1iZXIoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmVycm9yKCdEcmFnUmFuZ2UgaW4gbXV0YWJsZU9wdGlvbnMgaXMgaW52YWxpZCEnKTtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gdG9QeChcbiAgICAgICAgTWF0aC5tYXgobCwgTWF0aC5taW4oeCwgcGFyZW50RWxlbWVudC5jbGllbnRXaWR0aCAtIHIpKSxcbiAgICAgICk7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUudG9wID0gdG9QeChcbiAgICAgICAgTWF0aC5tYXgodCwgTWF0aC5taW4oeSwgcGFyZW50RWxlbWVudC5jbGllbnRIZWlnaHQgLSBiKSksXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5sZWZ0ID0gdG9QeCh4KTtcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUudG9wID0gdG9QeCh5KTtcbiAgfVxuXG4gIGluaXREcmFnZ2luZyhldmVudDogTW91c2VFdmVudCkge1xuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB0aGlzLm1vdXNlUG9pbnQueCA9IGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQ7XG5cbiAgICB0aGlzLm1vdXNlUG9pbnQueSA9IGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcDtcblxuICAgIGNvbnN0IHsgYm9yZGVyTGVmdCwgYm9yZGVyVG9wIH0gPSBnZXRDb21wdXRlZFN0eWxlKFxuICAgICAgdGhpcy5nZXRCb3VuZGFyeUVsZW1lbnQoKSxcbiAgICApO1xuXG4gICAgdGhpcy5wYXJlbnRCb3JkZXIgPSB7XG4gICAgICBsZWZ0OiB0b051bWJlcihib3JkZXJMZWZ0KSxcbiAgICAgIHRvcDogdG9OdW1iZXIoYm9yZGVyVG9wKSxcbiAgICB9O1xuICB9XG5cbiAgc2V0RHJhZ2dpbmcoY3Vyc29yOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgdGhpcy5pc0RyYWdnaW5nID0gY3Vyc29yID09PSB0aGlzLmNvbXB1dGVkT3B0aW9ucy5jdXJzb3JzLm1vdmU7XG5cbiAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICB0aGlzLmluaXREcmFnZ2luZyhldmVudCk7XG4gICAgfVxuICB9XG5cbiAgcmVzaXplRWxlbWVudFgoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc1Jlc2l6ZU91dE9mQm91bmRhcnkoZXZlbnQsICdob3Jpem9udGFsJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50UmVjdCA9IHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBsZXQgd2lkdGg7XG4gICAgY29uc3QgeyBtaW5XaWR0aCwgbWF4V2lkdGgsIGxlZnQgfSA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50KTtcbiAgICBjb25zdCBjb21wdXRlZE1pbldpZHRoID0gTWF0aC5tYXgoXG4gICAgICB0b051bWJlcihtaW5XaWR0aCksXG4gICAgICB0aGlzLmVsZW1lbnRCb3JkZXIubGVmdCArIHRoaXMuZWxlbWVudEJvcmRlci5yaWdodCxcbiAgICApO1xuXG4gICAgaWYgKGlzTCh0aGlzLnJlc2l6ZUN1cnNvcikpIHtcbiAgICAgIGNvbnN0IHRhcmdldExlZnQgPSBldmVudC5jbGllbnRYIC0gdGhpcy5tb3VzZVBvaW50Lng7XG4gICAgICBjb25zdCBjb21wdXRlZFdpZHRoID0gdGhpcy5yZXNpemVJbml0WFJpZ2h0IC0gdGFyZ2V0TGVmdDtcblxuICAgICAgd2lkdGggPSBNYXRoLm1heChcbiAgICAgICAgdG9OdW1iZXIobWF4V2lkdGgpXG4gICAgICAgICAgPyBNYXRoLm1pbihjb21wdXRlZFdpZHRoLCB0b051bWJlcihtYXhXaWR0aCkpXG4gICAgICAgICAgOiBjb21wdXRlZFdpZHRoLFxuICAgICAgICBjb21wdXRlZE1pbldpZHRoLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmxlZnQgPSB0b1B4KFxuICAgICAgICB0b051bWJlcihsZWZ0KSArIGVsZW1lbnRSZWN0LndpZHRoIC0gd2lkdGgsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0YXJnZXRSaWdodCA9IGV2ZW50LmNsaWVudFggKyB0aGlzLm1vdXNlUG9pbnQueDtcblxuICAgICAgY29uc3QgY29tcHV0ZWRXaWR0aCA9IHRhcmdldFJpZ2h0IC0gZWxlbWVudFJlY3QubGVmdDtcbiAgICAgIHdpZHRoID0gTWF0aC5tYXgoXG4gICAgICAgIHRvTnVtYmVyKG1heFdpZHRoKVxuICAgICAgICAgID8gTWF0aC5taW4oY29tcHV0ZWRXaWR0aCwgdG9OdW1iZXIobWF4V2lkdGgpKVxuICAgICAgICAgIDogY29tcHV0ZWRXaWR0aCxcbiAgICAgICAgY29tcHV0ZWRNaW5XaWR0aCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHdpZHRoIDwgdGhpcy5lbGVtZW50Qm9yZGVyLmxlZnQgKyB0aGlzLmVsZW1lbnRCb3JkZXIucmlnaHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGggPSB0b1B4KHdpZHRoKTtcbiAgfVxuXG4gIHJlc2l6ZUVsZW1lbnRZKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNSZXNpemVPdXRPZkJvdW5kYXJ5KGV2ZW50LCAndmVydGljYWwnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnRSZWN0ID0gdGhpcy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHsgbWluSGVpZ2h0LCBtYXhIZWlnaHQsIHRvcCB9ID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsZW1lbnQpO1xuICAgIGNvbnN0IGNvbXB1dGVkTWluSGVpZ2h0ID0gTWF0aC5tYXgoXG4gICAgICB0b051bWJlcihtaW5IZWlnaHQpLFxuICAgICAgdGhpcy5lbGVtZW50Qm9yZGVyLnRvcCArIHRoaXMuZWxlbWVudEJvcmRlci5ib3R0b20sXG4gICAgKTtcblxuICAgIGxldCBoZWlnaHQ7XG5cbiAgICBpZiAoaXNUKHRoaXMucmVzaXplQ3Vyc29yKSkge1xuICAgICAgY29uc3QgdGFyZ2V0VG9wID0gZXZlbnQuY2xpZW50WSAtIHRoaXMubW91c2VQb2ludC55O1xuXG4gICAgICBjb25zdCBjb21wdXRlZEhlaWdodCA9IHRoaXMucmVzaXplSW5pdFlCb3R0b20gLSB0YXJnZXRUb3A7XG5cbiAgICAgIGhlaWdodCA9IE1hdGgubWF4KFxuICAgICAgICB0b051bWJlcihtYXhIZWlnaHQpXG4gICAgICAgICAgPyBNYXRoLm1pbihjb21wdXRlZEhlaWdodCwgdG9OdW1iZXIobWF4SGVpZ2h0KSlcbiAgICAgICAgICA6IGNvbXB1dGVkSGVpZ2h0LFxuICAgICAgICBjb21wdXRlZE1pbkhlaWdodCxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS50b3AgPSB0b1B4KFxuICAgICAgICB0b051bWJlcih0b3ApICsgZWxlbWVudFJlY3QuaGVpZ2h0IC0gaGVpZ2h0LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGFyZ2V0Qm90dG9tID0gZXZlbnQuY2xpZW50WSArIHRoaXMubW91c2VQb2ludC55O1xuXG4gICAgICBjb25zdCBjb21wdXRlZEhlaWdodCA9IHRhcmdldEJvdHRvbSAtIGVsZW1lbnRSZWN0LnRvcDtcblxuICAgICAgaGVpZ2h0ID0gTWF0aC5tYXgoXG4gICAgICAgIHRvTnVtYmVyKG1heEhlaWdodClcbiAgICAgICAgICA/IE1hdGgubWluKGNvbXB1dGVkSGVpZ2h0LCB0b051bWJlcihtYXhIZWlnaHQpKVxuICAgICAgICAgIDogY29tcHV0ZWRIZWlnaHQsXG4gICAgICAgIGNvbXB1dGVkTWluSGVpZ2h0LFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKGhlaWdodCA8IHRoaXMuZWxlbWVudEJvcmRlci50b3AgKyB0aGlzLmVsZW1lbnRCb3JkZXIuYm90dG9tKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0b1B4KGhlaWdodCk7XG4gIH1cblxuICBpbml0UmVzaXppbmcoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBjb25zdCBlbGVtZW50UmVjdCA9IHRoaXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIHRoaXMucmVzaXplSW5pdFhSaWdodCA9IGVsZW1lbnRSZWN0LnJpZ2h0O1xuICAgIHRoaXMucmVzaXplSW5pdFlCb3R0b20gPSBlbGVtZW50UmVjdC5ib3R0b207XG5cbiAgICB0aGlzLm1vdXNlUG9pbnQueCA9IGlzTCh0aGlzLnJlc2l6ZUN1cnNvcilcbiAgICAgID8gZXZlbnQuY2xpZW50WCAtIGVsZW1lbnRSZWN0LmxlZnRcbiAgICAgIDogZWxlbWVudFJlY3QucmlnaHQgLSBldmVudC5jbGllbnRYO1xuXG4gICAgdGhpcy5tb3VzZVBvaW50LnkgPSBpc1QodGhpcy5yZXNpemVDdXJzb3IpXG4gICAgICA/IGV2ZW50LmNsaWVudFkgLSBlbGVtZW50UmVjdC50b3BcbiAgICAgIDogZWxlbWVudFJlY3QuYm90dG9tIC0gZXZlbnQuY2xpZW50WTtcblxuICAgIGNvbnN0IHsgYm9yZGVyTGVmdCwgYm9yZGVyVG9wLCBib3JkZXJCb3R0b20sIGJvcmRlclJpZ2h0IH0gPVxuICAgICAgZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsZW1lbnQpO1xuICAgIHRoaXMuZWxlbWVudEJvcmRlciA9IHtcbiAgICAgIGxlZnQ6IHRvTnVtYmVyKGJvcmRlckxlZnQpLFxuICAgICAgdG9wOiB0b051bWJlcihib3JkZXJUb3ApLFxuICAgICAgYm90dG9tOiB0b051bWJlcihib3JkZXJCb3R0b20pLFxuICAgICAgcmlnaHQ6IHRvTnVtYmVyKGJvcmRlclJpZ2h0KSxcbiAgICB9O1xuICB9XG5cbiAgc2V0UmVzaXppbmcoY3Vyc29yOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKGN1cnNvciA9PSBudWxsIHx8ICFjdXJzb3IuaW5jbHVkZXMoJy1yZXNpemUnKSkge1xuICAgICAgdGhpcy5pc1Jlc2l6aW5nWCA9IGZhbHNlO1xuXG4gICAgICB0aGlzLmlzUmVzaXppbmdZID0gZmFsc2U7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjdXJzb3IgPSBjdXJzb3IucmVwbGFjZSgnLXJlc2l6ZScsICcnKTtcblxuICAgIHRoaXMuaXNSZXNpemluZ1ggPSBjdXJzb3IuaW5jbHVkZXMoJ2UnKSB8fCBjdXJzb3IuaW5jbHVkZXMoJ3cnKTtcblxuICAgIHRoaXMuaXNSZXNpemluZ1kgPSBjdXJzb3IuaW5jbHVkZXMoJ3MnKSB8fCBjdXJzb3IuaW5jbHVkZXMoJ24nKTtcblxuICAgIHRoaXMuaW5pdFJlc2l6aW5nKGV2ZW50KTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzb25hcmpzL2NvZ25pdGl2ZS1jb21wbGV4aXR5XG4gIGdldE11dGFibGVDdXJzb3IoZXZlbnQ6IE1vdXNlRXZlbnQpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmlzUmVzaXppbmdYIHx8IHRoaXMuaXNSZXNpemluZ1kpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudFJlY3QgPSB0aGlzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCByZXNpemVUaHJlc2hvbGQgPSB0aGlzLmNvbXB1dGVkT3B0aW9ucy5yZXNpemVUaHJlc2hvbGQ7XG5cbiAgICBjb25zdCBwdCA9IHtcbiAgICAgIHg6IGV2ZW50LmNsaWVudFgsXG4gICAgICB5OiBldmVudC5jbGllbnRZLFxuICAgIH07XG5cbiAgICBsZXQgY3Vyc29yID0gJyc7XG4gICAgY29uc3QgZHJhZ1RocmVzaG9sZCA9IHRoaXMuYWNsUmVzaXphYmxlID8gcmVzaXplVGhyZXNob2xkIDogMDtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuYWNsRHJhZ2dhYmxlICYmXG4gICAgICBwdC54IDwgZWxlbWVudFJlY3QucmlnaHQgLSBkcmFnVGhyZXNob2xkICYmXG4gICAgICBwdC54ID4gZWxlbWVudFJlY3QubGVmdCArIGRyYWdUaHJlc2hvbGQgJiZcbiAgICAgIHB0LnkgPCBlbGVtZW50UmVjdC5ib3R0b20gLSBkcmFnVGhyZXNob2xkICYmXG4gICAgICBwdC55ID4gZWxlbWVudFJlY3QudG9wICsgZHJhZ1RocmVzaG9sZCAmJlxuICAgICAgKCF0aGlzLmhhbmRsZXM/Lmxlbmd0aCB8fFxuICAgICAgICB0aGlzLmhhbmRsZXM/LnNvbWUoaCA9PlxuICAgICAgICAgIGlzU2VsZk9yUGFyZW50KGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCwgaC5uYXRpdmVFbGVtZW50KSxcbiAgICAgICAgKSlcbiAgICApIHtcbiAgICAgIGN1cnNvciA9IHRoaXMuY29tcHV0ZWRPcHRpb25zLmN1cnNvcnMubW92ZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY2xSZXNpemFibGUgJiYgIWN1cnNvcikge1xuICAgICAgaWYgKFxuICAgICAgICBwdC55ID49IGVsZW1lbnRSZWN0LnRvcCAmJlxuICAgICAgICBwdC55IDw9IGVsZW1lbnRSZWN0LnRvcCArIHJlc2l6ZVRocmVzaG9sZFxuICAgICAgKSB7XG4gICAgICAgIGN1cnNvciArPSAnbic7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwdC55ID49IGVsZW1lbnRSZWN0LmJvdHRvbSAtIHJlc2l6ZVRocmVzaG9sZCAmJlxuICAgICAgICBwdC55IDw9IGVsZW1lbnRSZWN0LmJvdHRvbVxuICAgICAgKSB7XG4gICAgICAgIGN1cnNvciArPSAncyc7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcHQueCA+PSBlbGVtZW50UmVjdC5sZWZ0ICYmXG4gICAgICAgIHB0LnggPD0gZWxlbWVudFJlY3QubGVmdCArIHJlc2l6ZVRocmVzaG9sZFxuICAgICAgKSB7XG4gICAgICAgIGN1cnNvciArPSAndyc7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwdC54ID49IGVsZW1lbnRSZWN0LnJpZ2h0IC0gcmVzaXplVGhyZXNob2xkICYmXG4gICAgICAgIHB0LnggPD0gZWxlbWVudFJlY3QucmlnaHRcbiAgICAgICkge1xuICAgICAgICBjdXJzb3IgKz0gJ2UnO1xuICAgICAgfVxuXG4gICAgICBjdXJzb3IgPSBjdXJzb3IgPyBjdXJzb3IgKyAnLXJlc2l6ZScgOiAnJztcbiAgICB9XG5cbiAgICB0aGlzLnJlc2l6ZUN1cnNvciA9IGN1cnNvciBhcyBSZXNpemVDdXJzb3I7XG5cbiAgICByZXR1cm4gY3Vyc29yIHx8IHRoaXMuX2luaXRDdXJzb3I7XG4gIH1cblxuICBwcml2YXRlIGlzUmVzaXplT3V0T2ZCb3VuZGFyeShcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICBkaXJlY3Rpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0