ngx-drag-and-drop
Version:
Angular library that allow you to build drag and drop without the native HTML5 API
551 lines • 64.3 kB
JavaScript
import { __decorate } from "tslib";
import { Directive, ElementRef, Input, HostListener, EventEmitter, Output, OnInit, OnDestroy } from '@angular/core';
import { myDoc } from './ngx-drag-and-drop.utils';
/*
interface ShadowRoot extends DocumentFragment {
styleSheets : StyleSheetList;
innerHTML : string;
host : Element;
activeElement : Element;
elementFromPoint (x : number, y : number) : Element;
elementsFromPoint (x : number, y : number) : Element[];
caretPositionFromPoint (x : number, y : number); // => CaretPosition
};
interface ElementWithShadowRoot extends HTMLElement {
shadowRoot : ShadowRoot;
};*/
var dragPointerId = 'dragPointer';
var DragManager = /** @class */ (function () {
function DragManager() {
this.draggingPointer = new Map();
this.draggedStructures = new Map();
this.dropZones = new Map();
}
DragManager.prototype.preStartDrag = function (idPointer, x, y, delay, dist) {
var _this = this;
this.draggingPointer.set(idPointer, { x: x, y: y });
return new Promise(function (resolve, reject) {
setTimeout(function () {
var ptr = _this.draggingPointer.get(idPointer);
var gogo = ptr && (Math.abs(x - ptr.x) + Math.abs(y - ptr.y)) < dist;
_this.draggingPointer.delete(idPointer);
gogo ? resolve() : reject();
}, Math.max(0, delay));
});
};
DragManager.prototype.startDrag = function (idPointer, dragged) {
this.draggedStructures.set(idPointer, dragged);
var possibleDropZones = new Map();
this.dropZones.forEach(function (dz) {
if (dz.checkAccept(dragged)) {
dz.appendDropCandidatePointer(idPointer);
possibleDropZones.set(dz.root, dz);
}
});
return possibleDropZones;
};
DragManager.prototype.isAssociatedToDropZone = function (element) {
return this.dropZones.has(element);
};
DragManager.prototype.registerDropZone = function (dropzone) {
this.dropZones.set(dropzone.root, dropzone);
};
DragManager.prototype.unregisterDropZone = function (dropzone) {
this.dropZones.delete(dropzone.root);
};
DragManager.prototype.pointerMove = function (idPointer, x, y) {
var ptr = this.draggingPointer.get(idPointer);
if (ptr) {
ptr.x = x;
ptr.y = y;
}
var dragged = this.draggedStructures.get(idPointer);
if (dragged && dragged instanceof Draggable) {
dragged.move(x, y);
}
return dragged !== undefined;
};
DragManager.prototype.pointerRelease = function (idPointer) {
var dragged = this.draggedStructures.get(idPointer);
if (dragged) {
if (dragged instanceof Draggable) {
dragged.stop();
}
}
this.draggedStructures.delete(idPointer);
this.draggingPointer.delete(idPointer);
return dragged !== undefined;
};
return DragManager;
}());
var DM = new DragManager();
var dragDropInit = false;
var DragDrop = /** @class */ (function () {
function DragDrop() {
this.nbDragEnter = 0;
if (dragDropInit) {
console.error('Do not create multiple instance of directive drag-and-drop-wrapper !');
}
else {
dragDropInit = true;
}
}
DragDrop.prototype.removeFeedbackForDragPointer = function () {
this.nbDragEnter = 0;
DM.dropZones.forEach(function (dz) {
dz.removePointerHover(dragPointerId);
dz.removeDropCandidatePointer(dragPointerId);
});
};
DragDrop.prototype.drop = function (e) {
e.preventDefault();
e.stopPropagation();
this.removeFeedbackForDragPointer();
};
DragDrop.prototype.dragover = function (e) {
e.preventDefault();
e.stopPropagation();
};
DragDrop.prototype.dragenter = function (e) {
this.nbDragEnter++;
if (this.nbDragEnter === 1) {
DM.startDrag(dragPointerId, e);
}
};
DragDrop.prototype.dragleave = function (e) {
this.nbDragEnter--;
if (this.nbDragEnter === 0) {
this.removeFeedbackForDragPointer();
DM.pointerRelease(dragPointerId);
}
};
DragDrop.prototype.dragend = function (e) {
DM.pointerRelease(dragPointerId);
this.removeFeedbackForDragPointer();
e.preventDefault();
};
DragDrop.prototype.mousemove = function (e) {
DM.pointerMove('mouse', e.clientX, e.clientY);
};
DragDrop.prototype.mouseup = function (e) {
DM.pointerRelease('mouse');
};
DragDrop.prototype.touchmove = function (e) {
for (var i = 0; i < e.changedTouches.length; i++) {
var touch = e.changedTouches.item(i);
if (DM.pointerMove(touch.identifier.toString(), touch.clientX, touch.clientY)) {
e.preventDefault();
e.stopPropagation();
}
}
};
DragDrop.prototype.touchend = function (e) {
for (var i = 0; i < e.changedTouches.length; i++) {
var touch = e.changedTouches.item(i);
if (DM.pointerRelease(touch.identifier.toString())) {
e.preventDefault();
e.stopPropagation();
}
}
};
__decorate([
HostListener('document: drop', ['$event'])
], DragDrop.prototype, "drop", null);
__decorate([
HostListener('document: dragover', ['$event'])
], DragDrop.prototype, "dragover", null);
__decorate([
HostListener('document: dragenter', ['$event'])
], DragDrop.prototype, "dragenter", null);
__decorate([
HostListener('document: dragleave', ['$event'])
], DragDrop.prototype, "dragleave", null);
__decorate([
HostListener('document: dragend', ['$event'])
], DragDrop.prototype, "dragend", null);
__decorate([
HostListener('document: mousemove', ['$event'])
], DragDrop.prototype, "mousemove", null);
__decorate([
HostListener('document: mouseup', ['$event'])
], DragDrop.prototype, "mouseup", null);
__decorate([
HostListener('document: touchmove', ['$event'])
], DragDrop.prototype, "touchmove", null);
__decorate([
HostListener('document: touchend', ['$event'])
], DragDrop.prototype, "touchend", null);
DragDrop = __decorate([
Directive({
selector: '*[drag-and-drop-wrapper]'
})
], DragDrop);
return DragDrop;
}());
export { DragDrop };
var offsetElement = function (element) {
var left = 0, top = 0;
while (element) {
top += element.offsetTop - element.scrollTop + element.clientTop;
left += element.offsetLeft - element.scrollLeft + element.clientLeft;
element = element.offsetParent;
}
return { left: left, top: top };
};
var ɵ0 = offsetElement;
var Draggable = /** @class */ (function () {
function Draggable(el) {
this.disabled = false;
this.onDragStart = new EventEmitter();
this.onDragEnd = new EventEmitter();
this.isBeingDragged = false;
this.cloneNode = null;
this.possibleDropZones = new Map();
this.root = el.nativeElement;
if (!dragDropInit) {
console.error('You should add one dragdrop attribute to your code before using draggable');
}
}
Draggable.prototype.ngOnInit = function () {
//
};
Draggable.prototype.ngOnDestroy = function () {
// XXX No stop in case of unplug while dragging... : // this.stop();
};
Draggable.prototype.onMouseDown = function (event) {
if (!this.disabled) {
event.preventDefault();
event.stopPropagation();
this.prestart('mouse', event.clientX, event.clientY);
}
};
Draggable.prototype.onTouchStart = function (event) {
event.stopPropagation();
for (var i = 0; i < event.changedTouches.length; i++) {
var touch = event.changedTouches.item(i);
this.prestart(touch.identifier.toString(), touch.clientX, touch.clientY);
}
};
Draggable.prototype.prestart = function (idPointer, x, y) {
var _this = this;
DM.preStartDrag(idPointer, x, y, this.startDelay || 0, this.startDistance || 10).then(function () {
_this.start(idPointer, x, y);
}, function () {
// console.error('skip the drag');
});
};
Draggable.prototype.start = function (idPointer, x, y) {
if (!this.isBeingDragged) {
this.isBeingDragged = true;
this.idPointer = idPointer;
var offset = offsetElement(this.root);
this.ox = x;
this.oy = y;
this.dx = x - offset.left;
this.dy = y - offset.top;
this.tx = this.root.offsetWidth;
this.ty = this.root.offsetHeight;
this.getClone();
this.cloneNode.style.left = (x - this.dx) + 'px';
this.cloneNode.style.top = (y - this.dy) + 'px';
this.onDragStart.emit(this.draggedData);
this.possibleDropZones = DM.startDrag(idPointer, this);
}
};
Draggable.prototype.stop = function () {
var _this = this;
this.possibleDropZones.forEach(function (dz) {
dz.removePointerHover(_this.idPointer);
dz.removeDropCandidatePointer(_this.idPointer);
});
this.isBeingDragged = false;
this.possibleDropZones.clear();
this.idPointer = null;
if (this.currentDropZone) {
this.currentDropZone.drop(this.draggedData);
}
this.currentDropZone = null;
this.onDragEnd.emit(this.draggedData);
this.deleteClone();
};
Draggable.prototype.move = function (x, y) {
var element = null;
if (this.cloneNode === null) {
this.getClone();
}
if (this.cloneNode) {
this.cloneNode.style.left = (x - this.dx) + 'px';
this.cloneNode.style.top = (y - this.dy) + 'px';
var visibility = this.cloneNode.style.visibility;
this.cloneNode.style.visibility = 'hidden';
var top_1 = this.cloneNode.style.top;
this.cloneNode.style.top = '999999999px';
element = myDoc.elementFromPoint(x, y);
this.cloneNode.style.top = top_1;
this.cloneNode.style.visibility = visibility;
var prevDropZone = this.currentDropZone;
while (element) {
this.currentDropZone = this.possibleDropZones.get(element);
if (this.currentDropZone) {
break;
}
element = element.parentElement;
}
if (prevDropZone !== this.currentDropZone) {
if (prevDropZone) {
prevDropZone.removePointerHover(this.idPointer);
}
if (this.currentDropZone) {
this.currentDropZone.appendPointerHover(this.idPointer);
}
}
}
return this;
};
Draggable.prototype.deepStyle = function (original, clone) {
if (original instanceof HTMLElement) {
var style = window.getComputedStyle(original);
for (var i = 0; i < style.length; i++) {
var att = style[i];
clone.style[att] = style[att];
}
for (var i = 0; i < original.children.length; i++) {
this.deepStyle(original.children.item(i), clone.children.item(i));
}
}
};
Draggable.prototype.deleteClone = function () {
if (this.cloneNode) {
if (this.cloneNode.parentNode) {
this.cloneNode.parentNode.removeChild(this.cloneNode);
}
this.cloneNode = null;
}
};
Draggable.prototype.getClone = function () {
if (this.cloneNode === null) {
this.cloneNode = this.root.cloneNode(true);
this.deepStyle(this.root, this.cloneNode);
document.body.appendChild(this.cloneNode);
this.cloneNode.style.position = 'absolute';
this.cloneNode.style.zIndex = '999';
this.cloneNode.style.marginLeft = '0';
this.cloneNode.style.marginTop = '0';
this.cloneNode.style.marginRight = '0';
this.cloneNode.style.marginBottom = '0';
this.cloneNode.style.opacity = '';
this.cloneNode.style.cursor = '';
this.cloneNode.style.transform = '';
this.cloneNode.style.transformOrigin = '';
this.cloneNode.style.animation = '';
this.cloneNode.style.transition = '';
this.cloneNode.classList.add('drag-and-drop-clone-node');
}
return this.cloneNode;
};
Draggable.ctorParameters = function () { return [
{ type: ElementRef }
]; };
__decorate([
Input('draggable')
], Draggable.prototype, "draggedData", void 0);
__decorate([
Input('drag-start-delay')
], Draggable.prototype, "startDelay", void 0);
__decorate([
Input('start-distance')
], Draggable.prototype, "startDistance", void 0);
__decorate([
Input('disabled')
], Draggable.prototype, "disabled", void 0);
__decorate([
Output('drag-start')
], Draggable.prototype, "onDragStart", void 0);
__decorate([
Output('drag-end')
], Draggable.prototype, "onDragEnd", void 0);
__decorate([
HostListener('mousedown', ['$event'])
], Draggable.prototype, "onMouseDown", null);
__decorate([
HostListener('touchstart', ['$event'])
], Draggable.prototype, "onTouchStart", null);
Draggable = __decorate([
Directive({
selector: '*[draggable]'
})
], Draggable);
return Draggable;
}());
export { Draggable };
var Dropzone = /** @class */ (function () {
function Dropzone(el) {
this.nbDragEnter = 0;
this.onDropEmitter = new EventEmitter();
this.onDragStart = new EventEmitter();
this.onDragEnd = new EventEmitter();
this.onDragEnter = new EventEmitter();
this.onDragLeave = new EventEmitter();
this.dropCandidateofPointers = [];
this.pointersHover = [];
if (!dragDropInit) {
console.error('You should add one dragdrop attribute to your code before using dropzone');
}
this.root = el.nativeElement;
DM.registerDropZone(this);
}
Dropzone.prototype.ngOnInit = function () {
//
};
Dropzone.prototype.ngOnDestroy = function () {
DM.unregisterDropZone(this);
};
Dropzone.prototype.BrowserDragEnter = function (event) {
this.nbDragEnter++;
if (this.nbDragEnter === 1) {
this.appendPointerHover(dragPointerId);
}
};
Dropzone.prototype.BrowserDragLeave = function (event) {
this.nbDragEnter--;
if (this.nbDragEnter === 0) {
this.removePointerHover(dragPointerId);
}
};
Dropzone.prototype.BrowserDrop = function (event) {
DM.pointerRelease(dragPointerId);
this.nbDragEnter = 0;
this.onDropEmitter.emit(event);
};
Dropzone.prototype.drop = function (obj) {
this.onDropEmitter.emit(obj);
};
Dropzone.prototype.checkAccept = function (drag) {
var res;
if (drag instanceof Draggable) {
res = this.acceptFunction ? this.acceptFunction(drag.draggedData) : true;
}
else {
res = this.acceptFunction ? this.acceptFunction(drag) : true;
}
return res;
};
Dropzone.prototype.hasPointerHover = function (idPointer) {
return this.pointersHover.indexOf(idPointer) >= 0;
};
Dropzone.prototype.appendPointerHover = function (idPointer) {
if (this.pointersHover.indexOf(idPointer) === -1) {
var dragged = DM.draggedStructures.get(idPointer);
this.pointersHover.push(idPointer);
if (dragged instanceof Draggable) {
if (this.dragOverCSS_pointer) {
dragged.getClone().classList.add(this.dragOverCSS_pointer);
}
this.onDragEnter.emit(dragged.draggedData);
}
else {
this.onDragEnter.emit(dragged);
}
if (this.dragOverCSS) {
this.root.classList.add(this.dragOverCSS);
}
}
};
Dropzone.prototype.removePointerHover = function (idPointer) {
var pos = this.pointersHover.indexOf(idPointer);
if (pos >= 0) {
var dragged = DM.draggedStructures.get(idPointer);
this.pointersHover.splice(pos, 1);
if (dragged instanceof Draggable) {
if (this.dragOverCSS_pointer) {
dragged.getClone().classList.remove(this.dragOverCSS_pointer);
}
this.onDragLeave.emit(dragged.draggedData);
}
else {
this.onDragLeave.emit(dragged);
}
if (this.pointersHover.length === 0 && this.dragOverCSS) {
this.root.classList.remove(this.dragOverCSS);
}
}
};
Dropzone.prototype.appendDropCandidatePointer = function (idPointer) {
if (this.dropCandidateofPointers.indexOf(idPointer) === -1) {
var dragged = DM.draggedStructures.get(idPointer);
if (dragged instanceof Draggable) {
this.onDragStart.emit(dragged.draggedData);
}
else {
this.onDragStart.emit(dragged);
}
this.dropCandidateofPointers.push(idPointer);
if (this.dragCSS) {
this.root.classList.add(this.dragCSS);
}
}
};
Dropzone.prototype.removeDropCandidatePointer = function (idPointer) {
var pos = this.dropCandidateofPointers.indexOf(idPointer);
if (pos >= 0) {
var dragged = DM.draggedStructures.get(idPointer);
if (dragged instanceof Draggable) {
this.onDragEnd.emit(dragged.draggedData);
}
else {
this.onDragEnd.emit(dragged);
}
this.dropCandidateofPointers.splice(pos, 1);
if (this.dropCandidateofPointers.length === 0 && this.dragCSS) {
this.root.classList.remove(this.dragCSS);
}
}
};
Dropzone.ctorParameters = function () { return [
{ type: ElementRef }
]; };
__decorate([
Input('drag-css')
], Dropzone.prototype, "dragCSS", void 0);
__decorate([
Input('drag-over-css')
], Dropzone.prototype, "dragOverCSS", void 0);
__decorate([
Input('drag-over-css-for-draggable')
], Dropzone.prototype, "dragOverCSS_pointer", void 0);
__decorate([
Input('accept-function')
], Dropzone.prototype, "acceptFunction", void 0);
__decorate([
Output('ondrop')
], Dropzone.prototype, "onDropEmitter", void 0);
__decorate([
Output('drag-start')
], Dropzone.prototype, "onDragStart", void 0);
__decorate([
Output('drag-end')
], Dropzone.prototype, "onDragEnd", void 0);
__decorate([
Output('drag-enter')
], Dropzone.prototype, "onDragEnter", void 0);
__decorate([
Output('drag-leave')
], Dropzone.prototype, "onDragLeave", void 0);
__decorate([
HostListener('dragenter', ['$event'])
], Dropzone.prototype, "BrowserDragEnter", null);
__decorate([
HostListener('dragleave', ['$event'])
], Dropzone.prototype, "BrowserDragLeave", null);
__decorate([
HostListener('drop', ['$event'])
], Dropzone.prototype, "BrowserDrop", null);
Dropzone = __decorate([
Directive({ selector: '*[dropzone]' })
], Dropzone);
return Dropzone;
}());
export { Dropzone };
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRyYWctYW5kLWRyb3AuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWRyYWctYW5kLWRyb3AvIiwic291cmNlcyI6WyJzcmMvYXBwL25neC1kcmFnLWFuZC1kcm9wL25neC1kcmFnLWFuZC1kcm9wLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDcEgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSWxEOzs7Ozs7Ozs7Ozs7O0lBYUk7QUFDSixJQUFNLGFBQWEsR0FBRyxhQUFhLENBQUM7QUFFcEM7SUFBQTtRQUNFLG9CQUFlLEdBQU8sSUFBSSxHQUFHLEVBQW1CLENBQUM7UUFDakQsc0JBQWlCLEdBQUssSUFBSSxHQUFHLEVBQWlDLENBQUM7UUFDL0QsY0FBUyxHQUFhLElBQUksR0FBRyxFQUFzQixDQUFDO0lBeUV0RCxDQUFDO0lBdkVRLGtDQUFZLEdBQW5CLFVBQ0UsU0FBaUIsRUFDakIsQ0FBUyxFQUNULENBQVMsRUFDVCxLQUFhLEVBQ2IsSUFBWTtRQUxkLGlCQWlCQztRQVZDLElBQUksQ0FBQyxlQUFlLENBQUcsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDcEQsT0FBTyxJQUFJLE9BQU8sQ0FBUSxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ3hDLFVBQVUsQ0FBQztnQkFDVCxJQUFNLEdBQUcsR0FBSyxLQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDbEQsSUFBTSxJQUFJLEdBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFD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QjtJQUNYO1FBQXZCLEtBQUssQ0FBQyxlQUFlLENBQUM7aURBQXFCO0lBQ047UUFBckMsS0FBSyxDQUFDLDZCQUE2QixDQUFDO3lEQUE2QjtJQUN4QztRQUF6QixLQUFLLENBQUMsaUJBQWlCLENBQUM7b0RBQXdDO0lBQy9DO1FBQWpCLE1BQU0sQ0FBQyxRQUFRLENBQUM7bURBQXlDO0lBQ3BDO1FBQXJCLE1BQU0sQ0FBQyxZQUFZLENBQUM7aURBQXVDO0lBQ3hDO1FBQW5CLE1BQU0sQ0FBQyxVQUFVLENBQUM7K0NBQXFDO0lBQ2xDO1FBQXJCLE1BQU0sQ0FBQyxZQUFZLENBQUM7aURBQXVDO0lBQ3RDO1FBQXJCLE1BQU0sQ0FBQyxZQUFZLENBQUM7aURBQXVDO0lBcUJyQjtRQUF0QyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7b0RBS3JDO0lBRXNDO1FBQXRDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztvREFLckM7SUFFaUM7UUFBakMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDOytDQUloQztJQWxEVSxRQUFRO1FBRHBCLFNBQVMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsQ0FBQztPQUMxQixRQUFRLENBeUlwQjtJQUFELGVBQUM7Q0FBQSxBQXpJRCxJQXlJQztTQXpJWSxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBJbnB1dCwgSG9zdExpc3RlbmVyLCBFdmVudEVtaXR0ZXIsIE91dHB1dCwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG15RG9jIH0gZnJvbSAnLi9uZ3gtZHJhZy1hbmQtZHJvcC51dGlscyc7XG5cbi8qIFBvbHlmaWxsIFRvdWNoRXZlbnQgKi9cbmV4cG9ydCBpbnRlcmZhY2UgTXlUb3VjaEV2ZW50IGV4dGVuZHMgVG91Y2hFdmVudCB7fVxuLypcbmludGVyZmFjZSBTaGFkb3dSb290IGV4dGVuZHMgRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgc3R5bGVTaGVldHMgICAgIDogU3R5bGVTaGVldExpc3Q7XG4gICAgaW5uZXJIVE1MICAgICAgIDogc3RyaW5nO1xuICAgIGhvc3QgICAgICAgICAgICA6IEVsZW1lbnQ7XG4gICAgYWN0aXZlRWxlbWVudCAgIDogRWxlbWVudDtcbiAgICBlbGVtZW50RnJvbVBvaW50ICAgICAgICAoeCA6IG51bWJlciwgeSA6IG51bWJlcikgOiBFbGVtZW50O1xuICAgIGVsZW1lbnRzRnJvbVBvaW50ICAgICAgICh4IDogbnVtYmVyLCB5IDogbnVtYmVyKSA6IEVsZW1lbnRbXTtcbiAgICBjYXJldFBvc2l0aW9uRnJvbVBvaW50ICAoeCA6IG51bWJlciwgeSA6IG51bWJlcik7IC8vID0+IENhcmV0UG9zaXRpb25cbn07XG5cbmludGVyZmFjZSBFbGVtZW50V2l0aFNoYWRvd1Jvb3QgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gICAgc2hhZG93Um9vdCAgOiBTaGFkb3dSb290O1xufTsqL1xuY29uc3QgZHJhZ1BvaW50ZXJJZCA9ICdkcmFnUG9pbnRlcic7XG50eXBlIFBvaW50ZXIgPSB7eDogbnVtYmVyLCB5OiBudW1iZXJ9O1xuY2xhc3MgRHJhZ01hbmFnZXIge1xuICBkcmFnZ2luZ1BvaW50ZXIgICAgID0gbmV3IE1hcDxzdHJpbmcsIFBvaW50ZXI+KCk7XG4gIGRyYWdnZWRTdHJ1Y3R1cmVzICAgPSBuZXcgTWFwPHN0cmluZywgRHJhZ2dhYmxlIHwgRHJhZ0V2ZW50PigpO1xuICBkcm9wWm9uZXMgICAgICAgICAgID0gbmV3IE1hcDxFbGVtZW50LCBEcm9wem9uZSA+KCk7XG5cbiAgcHVibGljIHByZVN0YXJ0RHJhZyhcbiAgICBpZFBvaW50ZXI6IHN0cmluZyxcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIGRlbGF5OiBudW1iZXIsXG4gICAgZGlzdDogbnVtYmVyLFxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHRoaXMuZHJhZ2dpbmdQb2ludGVyICAuc2V0KGlkUG9pbnRlciwge3g6IHgsIHk6IHl9KTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBwdHIgICA9IHRoaXMuZHJhZ2dpbmdQb2ludGVyLmdldChpZFBvaW50ZXIpO1xuICAgICAgICBjb25zdCBnb2dvICA9IHB0ciAmJiAoTWF0aC5hYnMoeCAtIHB0ci54KSArIE1hdGguYWJzKHkgLSBwdHIueSkpIDwgZGlzdDtcbiAgICAgICAgdGhpcy5kcmFnZ2luZ1BvaW50ZXIuZGVsZXRlKGlkUG9pbnRlcik7XG5cbiAgICAgICAgZ29nbyA/IHJlc29sdmUoKSA6IHJlamVjdCgpO1xuICAgICAgfSwgTWF0aC5tYXgoMCwgZGVsYXkpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydERyYWcoXG4gICAgaWRQb2ludGVyOiBzdHJpbmcsXG4gICAgZHJhZ2dlZDogRHJhZ2dhYmxlIHwgRHJhZ0V2ZW50LFxuICApOiBNYXA8RWxlbWVudCwgRHJvcHpvbmU+IHtcbiAgICB0aGlzLmRyYWdnZWRTdHJ1Y3R1cmVzLnNldChpZFBvaW50ZXIsIGRyYWdnZWQpO1xuICAgIGNvbnN0IHBvc3NpYmxlRHJvcFpvbmVzID0gbmV3IE1hcDxFbGVtZW50LCBEcm9wem9uZT4oKTtcbiAgICB0aGlzLmRyb3Bab25lcy5mb3JFYWNoKGR6ID0+IHtcbiAgICAgICAgaWYgKGR6LmNoZWNrQWNjZXB0KGRyYWdnZWQpKSB7XG4gICAgICAgICAgICBkei5hcHBlbmREcm9wQ2FuZGlkYXRlUG9pbnRlcihpZFBvaW50ZXIpO1xuICAgICAgICAgICAgcG9zc2libGVEcm9wWm9uZXMuc2V0KGR6LnJvb3QsIGR6KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBwb3NzaWJsZURyb3Bab25lcztcbiAgfVxuXG4gIHB1YmxpYyBpc0Fzc29jaWF0ZWRUb0Ryb3Bab25lKGVsZW1lbnQ6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kcm9wWm9uZXMuaGFzKGVsZW1lbnQpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyRHJvcFpvbmUoZHJvcHpvbmU6IERyb3B6b25lKSB7XG4gICAgdGhpcy5kcm9wWm9uZXMuc2V0KGRyb3B6b25lLnJvb3QsIGRyb3B6b25lKTtcbiAgfVxuXG4gIHB1YmxpYyB1bnJlZ2lzdGVyRHJvcFpvbmUoZHJvcHpvbmU6IERyb3B6b25lKSB7XG4gICAgdGhpcy5kcm9wWm9uZXMuZGVsZXRlKGRyb3B6b25lLnJvb3QpO1xuICB9XG5cbiAgcHVibGljIHBvaW50ZXJNb3ZlKGlkUG9pbnRlcjogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHB0ciA9IHRoaXMuZHJhZ2dpbmdQb2ludGVyLmdldChpZFBvaW50ZXIpO1xuICAgIGlmIChwdHIpIHtcbiAgICAgIHB0ci54ID0geDsgcHRyLnkgPSB5O1xuICAgIH1cblxuICAgIGNvbnN0IGRyYWdnZWQgPSB0aGlzLmRyYWdnZWRTdHJ1Y3R1cmVzLmdldChpZFBvaW50ZXIpO1xuXG4gICAgaWYgKGRyYWdnZWQgJiYgZHJhZ2dlZCBpbnN0YW5jZW9mIERyYWdnYWJsZSkge1xuICAgICAgZHJhZ2dlZC5tb3ZlKHgsIHkpO1xuICAgIH1cbiAgICByZXR1cm4gZHJhZ2dlZCAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIHBvaW50ZXJSZWxlYXNlKGlkUG9pbnRlcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZHJhZ2dlZCA9IHRoaXMuZHJhZ2dlZFN0cnVjdHVyZXMuZ2V0KGlkUG9pbnRlcik7XG4gICAgaWYgKGRyYWdnZWQpIHtcbiAgICAgIGlmIChkcmFnZ2VkIGluc3RhbmNlb2YgRHJhZ2dhYmxlKSB7XG4gICAgICAgIGRyYWdnZWQuc3RvcCgpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRyYWdnZWRTdHJ1Y3R1cmVzLmRlbGV0ZShpZFBvaW50ZXIpO1xuICAgIHRoaXMuZHJhZ2dpbmdQb2ludGVyLmRlbGV0ZShpZFBvaW50ZXIpO1xuICAgIHJldHVybiBkcmFnZ2VkICE9PSB1bmRlZmluZWQ7XG4gIH1cbn1cblxuY29uc3QgRE0gPSBuZXcgRHJhZ01hbmFnZXIoKTtcblxubGV0IGRyYWdEcm9wSW5pdCA9IGZhbHNlO1xuXG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnKltkcmFnLWFuZC1kcm9wLXdyYXBwZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBEcmFnRHJvcCB7XG4gIG5iRHJhZ0VudGVyID0gMDtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaWYgKGRyYWdEcm9wSW5pdCkge1xuICAgICAgY29uc29sZS5lcnJvcignRG8gbm90IGNyZWF0ZSBtdWx0aXBsZSBpbnN0YW5jZSBvZiBkaXJlY3RpdmUgZHJhZy1hbmQtZHJvcC13cmFwcGVyICEnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZHJhZ0Ryb3BJbml0ID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVGZWVkYmFja0ZvckRyYWdQb2ludGVyKCkge1xuICAgIHRoaXMubmJEcmFnRW50ZXIgPSAwO1xuICAgIERNLmRyb3Bab25lcy5mb3JFYWNoKGR6ID0+IHtcbiAgICAgIGR6LnJlbW92ZVBvaW50ZXJIb3ZlcihkcmFnUG9pbnRlcklkKTtcbiAgICAgIGR6LnJlbW92ZURyb3BDYW5kaWRhdGVQb2ludGVyKGRyYWdQb2ludGVySWQpO1xuICAgIH0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6IGRyb3AnLCBbJyRldmVudCddKSBkcm9wKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLnJlbW92ZUZlZWRiYWNrRm9yRHJhZ1BvaW50ZXIoKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OiBkcmFnb3ZlcicsIFsnJGV2ZW50J10pIGRyYWdvdmVyKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OiBkcmFnZW50ZXInLCBbJyRldmVudCddKSBkcmFnZW50ZXIoZSkge1xuICAgIHRoaXMubmJEcmFnRW50ZXIrKztcbiAgICBpZiAodGhpcy5uYkRyYWdFbnRlciA9PT0gMSkge1xuICAgICAgRE0uc3RhcnREcmFnKGRyYWdQb2ludGVySWQsIGUpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OiBkcmFnbGVhdmUnLCBbJyRldmVudCddKSBkcmFnbGVhdmUoZSkge1xuICAgIHRoaXMubmJEcmFnRW50ZXItLTtcbiAgICBpZiAodGhpcy5uYkRyYWdFbnRlciA9PT0gMCkge1xuICAgICAgdGhpcy5yZW1vdmVGZWVkYmFja0ZvckRyYWdQb2ludGVyKCk7XG4gICAgICBETS5wb2ludGVyUmVsZWFzZShkcmFnUG9pbnRlcklkKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDogZHJhZ2VuZCcsIFsnJGV2ZW50J10pIGRyYWdlbmQoZSkge1xuICAgIERNLnBvaW50ZXJSZWxlYXNlKGRyYWdQb2ludGVySWQpO1xuICAgIHRoaXMucmVtb3ZlRmVlZGJhY2tGb3JEcmFnUG9pbnRlcigpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OiBtb3VzZW1vdmUnLCBbJyRldmVudCddKSBtb3VzZW1vdmUoZSkge1xuICAgIERNLnBvaW50ZXJNb3ZlKCdtb3VzZScsIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OiBtb3VzZXVwJywgWyckZXZlbnQnXSkgbW91c2V1cChlKSB7XG4gICAgRE0ucG9pbnRlclJlbGVhc2UoJ21vdXNlJyk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDogdG91Y2htb3ZlJywgWyckZXZlbnQnXSkgdG91Y2htb3ZlKGUpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGUuY2hhbmdlZFRvdWNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHRvdWNoOiBUb3VjaCA9IGUuY2hhbmdlZFRvdWNoZXMuaXRlbShpKTtcbiAgICAgIGlmIChETS5wb2ludGVyTW92ZSh0b3VjaC5pZGVudGlmaWVyLnRvU3RyaW5nKCksIHRvdWNoLmNsaWVudFgsIHRvdWNoLmNsaWVudFkpKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDogdG91Y2hlbmQnLCBbJyRldmVudCddKSB0b3VjaGVuZChlKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlLmNoYW5nZWRUb3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB0b3VjaDogVG91Y2ggPSBlLmNoYW5nZWRUb3VjaGVzLml0ZW0oaSk7XG4gICAgICBpZiAoRE0ucG9pbnRlclJlbGVhc2UodG91Y2guaWRlbnRpZmllci50b1N0cmluZygpKSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IG9mZnNldEVsZW1lbnQgPSAoZWxlbWVudDogSFRNTEVsZW1lbnQpOiB7IGxlZnQ6IG51bWJlciwgdG9wOiBudW1iZXIgfSA9PiB7XG4gIGxldCBsZWZ0ID0gMCwgdG9wID0gMDtcbiAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICB0b3AgKz0gZWxlbWVudC5vZmZzZXRUb3AgLSBlbGVtZW50LnNjcm9sbFRvcCArIGVsZW1lbnQuY2xpZW50VG9wO1xuICAgIGxlZnQgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IC0gZWxlbWVudC5zY3JvbGxMZWZ0ICsgZWxlbWVudC5jbGllbnRMZWZ0O1xuICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudCBhcyBIVE1MRWxlbWVudDtcbiAgfVxuICByZXR1cm4geyBsZWZ0OiBsZWZ0LCB0b3A6IHRvcCB9O1xufTtcblxuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICcqW2RyYWdnYWJsZV0nXG59KVxuZXhwb3J0IGNsYXNzIERyYWdnYWJsZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCdkcmFnZ2FibGUnKSBkcmFnZ2VkRGF0YTogYW55O1xuICBASW5wdXQoJ2RyYWctc3RhcnQtZGVsYXknKSBzdGFydERlbGF5OiBudW1iZXI7XG4gIEBJbnB1dCgnc3RhcnQtZGlzdGFuY2UnKSBzdGFydERpc3RhbmNlOiBudW1iZXI7XG4gIEBJbnB1dCgnZGlzYWJsZWQnKSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBAT3V0cHV0KCdkcmFnLXN0YXJ0Jykgb25EcmFnU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgnZHJhZy1lbmQnKSBvbkRyYWdFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHJpdmF0ZSBpc0JlaW5nRHJhZ2dlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIGNsb25lTm9kZTogSFRNTEVsZW1lbnQgPSBudWxsO1xuICBwcml2YXRlIGN1cnJlbnREcm9wWm9uZTogRHJvcHpvbmU7XG4gIHByaXZhdGUgcG9zc2libGVEcm9wWm9uZXMgPSBuZXcgTWFwPEVsZW1lbnQsIERyb3B6b25lPigpO1xuICBwcml2YXRlIGR4OiBudW1iZXI7XG4gIHByaXZhdGUgZHk6IG51bWJlcjtcbiAgcHVibGljIG94OiBudW1iZXI7XG4gIHB1YmxpYyBveTogbnVtYmVyO1xuICBwdWJsaWMgdHg6IG51bWJlcjtcbiAgcHVibGljIHR5OiBudW1iZXI7XG4gIHByaXZhdGUgaWRQb2ludGVyOiBzdHJpbmc7XG4gIHByaXZhdGUgcm9vdDogSFRNTEVsZW1lbnQ7XG5cbiAgY29uc3RydWN0b3IoZWw6IEVsZW1lbnRSZWYpIHtcbiAgICB0aGlzLnJvb3QgPSBlbC5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghZHJhZ0Ryb3BJbml0KSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdZb3Ugc2hvdWxkIGFkZCBvbmUgZHJhZ2Ryb3AgYXR0cmlidXRlIHRvIHlvdXIgY29kZSBiZWZvcmUgdXNpbmcgZHJhZ2dhYmxlJyk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgLy9cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIFhYWCBObyBzdG9wIGluIGNhc2Ugb2YgdW5wbHVnIHdoaWxlIGRyYWdnaW5nLi4uIDogLy8gdGhpcy5zdG9wKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdtb3VzZWRvd24nLCBbJyRldmVudCddKSBvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCkge1xuICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgdGhpcy5wcmVzdGFydCgnbW91c2UnLCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgWyckZXZlbnQnXSkgb25Ub3VjaFN0YXJ0KGV2ZW50OiBNeVRvdWNoRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50LmNoYW5nZWRUb3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB0b3VjaDogVG91Y2ggPSBldmVudC5jaGFuZ2VkVG91Y2hlcy5pdGVtKGkpO1xuICAgICAgdGhpcy5wcmVzdGFydCh0b3VjaC5pZGVudGlmaWVyLnRvU3RyaW5nKCksIHRvdWNoLmNsaWVudFgsIHRvdWNoLmNsaWVudFkpO1xuICAgIH1cbiAgfVxuXG4gIHByZXN0YXJ0KGlkUG9pbnRlcjogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICAgIERNLnByZVN0YXJ0RHJhZyhpZFBvaW50ZXIsIHgsIHksIHRoaXMuc3RhcnREZWxheSB8fCAwLCB0aGlzLnN0YXJ0RGlzdGFuY2UgfHwgMTApLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuc3RhcnQoaWRQb2ludGVyLCB4LCB5KTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ3NraXAgdGhlIGRyYWcnKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgc3RhcnQoaWRQb2ludGVyOiBzdHJpbmcsIHg6IG51bWJlciwgeTogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLmlzQmVpbmdEcmFnZ2VkKSB7XG4gICAgICB0aGlzLmlzQmVpbmdEcmFnZ2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMuaWRQb2ludGVyID0gaWRQb2ludGVyO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gb2Zmc2V0RWxlbWVudCh0aGlzLnJvb3QpO1xuICAgICAgdGhpcy5veCA9IHg7IHRoaXMub3kgPSB5O1xuICAgICAgdGhpcy5keCA9IHggLSBvZmZzZXQubGVmdDtcbiAgICAgIHRoaXMuZHkgPSB5IC0gb2Zmc2V0LnRvcDtcbiAgICAgIHRoaXMudHggPSB0aGlzLnJvb3Qub2Zmc2V0V2lkdGg7XG4gICAgICB0aGlzLnR5ID0gdGhpcy5yb290Lm9mZnNldEhlaWdodDtcblxuICAgICAgdGhpcy5nZXRDbG9uZSgpO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUubGVmdCA9ICh4IC0gdGhpcy5keCkgKyAncHgnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUudG9wID0gKHkgLSB0aGlzLmR5KSArICdweCc7XG4gICAgICB0aGlzLm9uRHJhZ1N0YXJ0LmVtaXQodGhpcy5kcmFnZ2VkRGF0YSk7XG4gICAgICB0aGlzLnBvc3NpYmxlRHJvcFpvbmVzID0gRE0uc3RhcnREcmFnKGlkUG9pbnRlciwgdGhpcyk7XG4gICAgfVxuICB9XG5cbiAgc3RvcCgpIHtcbiAgICB0aGlzLnBvc3NpYmxlRHJvcFpvbmVzLmZvckVhY2goZHogPT4ge1xuICAgICAgZHoucmVtb3ZlUG9pbnRlckhvdmVyKHRoaXMuaWRQb2ludGVyKTtcbiAgICAgIGR6LnJlbW92ZURyb3BDYW5kaWRhdGVQb2ludGVyKHRoaXMuaWRQb2ludGVyKTtcbiAgICB9KTtcbiAgICB0aGlzLmlzQmVpbmdEcmFnZ2VkID0gZmFsc2U7XG4gICAgdGhpcy5wb3NzaWJsZURyb3Bab25lcy5jbGVhcigpO1xuICAgIHRoaXMuaWRQb2ludGVyID0gbnVsbDtcbiAgICBpZiAodGhpcy5jdXJyZW50RHJvcFpvbmUpIHtcbiAgICAgIHRoaXMuY3VycmVudERyb3Bab25lLmRyb3AodGhpcy5kcmFnZ2VkRGF0YSk7XG4gICAgfVxuICAgIHRoaXMuY3VycmVudERyb3Bab25lID0gbnVsbDtcbiAgICB0aGlzLm9uRHJhZ0VuZC5lbWl0KHRoaXMuZHJhZ2dlZERhdGEpO1xuICAgIHRoaXMuZGVsZXRlQ2xvbmUoKTtcbiAgfVxuXG4gIG1vdmUoeDogbnVtYmVyLCB5OiBudW1iZXIpOiB0aGlzIHtcbiAgICBsZXQgZWxlbWVudDogRWxlbWVudCA9IG51bGw7XG4gICAgaWYgKHRoaXMuY2xvbmVOb2RlID09PSBudWxsKSB7XG4gICAgICB0aGlzLmdldENsb25lKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNsb25lTm9kZSkge1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUubGVmdCA9ICh4IC0gdGhpcy5keCkgKyAncHgnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUudG9wID0gKHkgLSB0aGlzLmR5KSArICdweCc7XG4gICAgICBjb25zdCB2aXNpYmlsaXR5ID0gdGhpcy5jbG9uZU5vZGUuc3R5bGUudmlzaWJpbGl0eTtcbiAgICAgIHRoaXMuY2xvbmVOb2RlLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICAgIGNvbnN0IHRvcCA9IHRoaXMuY2xvbmVOb2RlLnN0eWxlLnRvcDtcbiAgICAgIHRoaXMuY2xvbmVOb2RlLnN0eWxlLnRvcCA9ICc5OTk5OTk5OTlweCc7XG5cbiAgICAgIGVsZW1lbnQgPSBteURvYy5lbGVtZW50RnJvbVBvaW50KHgsIHkpO1xuXG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS50b3AgPSB0b3A7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS52aXNpYmlsaXR5ID0gdmlzaWJpbGl0eTtcblxuICAgICAgY29uc3QgcHJldkRyb3Bab25lID0gdGhpcy5jdXJyZW50RHJvcFpvbmU7XG4gICAgICB3aGlsZSAoZWxlbWVudCkge1xuICAgICAgICB0aGlzLmN1cnJlbnREcm9wWm9uZSA9IHRoaXMucG9zc2libGVEcm9wWm9uZXMuZ2V0KGVsZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50RHJvcFpvbmUpIHsgYnJlYWs7IH1cbiAgICAgICAgZWxlbWVudCA9IDxFbGVtZW50PmVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgaWYgKHByZXZEcm9wWm9uZSAhPT0gdGhpcy5jdXJyZW50RHJvcFpvbmUpIHtcbiAgICAgICAgaWYgKHByZXZEcm9wWm9uZSkge1xuICAgICAgICAgIHByZXZEcm9wWm9uZS5yZW1vdmVQb2ludGVySG92ZXIodGhpcy5pZFBvaW50ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnREcm9wWm9uZSkge1xuICAgICAgICAgIHRoaXMuY3VycmVudERyb3Bab25lLmFwcGVuZFBvaW50ZXJIb3Zlcih0aGlzLmlkUG9pbnRlcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBkZWVwU3R5bGUob3JpZ2luYWw6IEVsZW1lbnQsIGNsb25lOiBFbGVtZW50KSB7XG4gICAgaWYgKG9yaWdpbmFsIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0eWxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGF0dCA9IHN0eWxlW2ldO1xuICAgICAgICAoY2xvbmUgYXMgSFRNTEVsZW1lbnQpLnN0eWxlW2F0dF0gPSBzdHlsZVthdHRdO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yaWdpbmFsLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuZGVlcFN0eWxlKG9yaWdpbmFsLmNoaWxkcmVuLml0ZW0oaSksIChjbG9uZSBhcyBIVE1MRWxlbWVudCkuY2hpbGRyZW4uaXRlbShpKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZGVsZXRlQ2xvbmUoKSB7XG4gICAgaWYgKHRoaXMuY2xvbmVOb2RlKSB7XG4gICAgICBpZiAodGhpcy5jbG9uZU5vZGUucGFyZW50Tm9kZSkge1xuICAgICAgICB0aGlzLmNsb25lTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuY2xvbmVOb2RlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2xvbmVOb2RlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBnZXRDbG9uZSgpOiBIVE1MRWxlbWVudCB7XG4gICAgaWYgKHRoaXMuY2xvbmVOb2RlID09PSBudWxsKSB7XG4gICAgICB0aGlzLmNsb25lTm9kZSA9IDxIVE1MRWxlbWVudD50aGlzLnJvb3QuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgdGhpcy5kZWVwU3R5bGUodGhpcy5yb290LCB0aGlzLmNsb25lTm9kZSk7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5jbG9uZU5vZGUpO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUuekluZGV4ID0gJzk5OSc7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS5tYXJnaW5MZWZ0ID0gJzAnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUubWFyZ2luVG9wID0gJzAnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUubWFyZ2luUmlnaHQgPSAnMCc7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnMCc7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS5vcGFjaXR5ID0gJyc7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS5jdXJzb3IgPSAnJztcbiAgICAgIHRoaXMuY2xvbmVOb2RlLnN0eWxlLnRyYW5zZm9ybSA9ICcnO1xuICAgICAgdGhpcy5jbG9uZU5vZGUuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gJyc7XG4gICAgICB0aGlzLmNsb25lTm9kZS5zdHlsZS5hbmltYXRpb24gPSAnJztcbiAgICAgIHRoaXMuY2xvbmVOb2RlLnN0eWxlLnRyYW5zaXRpb24gPSAnJztcbiAgICAgIHRoaXMuY2xvbmVOb2RlLmNsYXNzTGlzdC5hZGQoJ2RyYWctYW5kLWRyb3AtY2xvbmUtbm9kZScpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jbG9uZU5vZGU7XG4gIH1cbn1cblxuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnKltkcm9wem9uZV0nIH0pXG5leHBvcnQgY2xhc3MgRHJvcHpvbmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIG5iRHJhZ0VudGVyID0gMDtcbiAgcHVibGljIHJvb3Q6IEhUTUxFbGVtZW50O1xuICBASW5wdXQoJ2RyYWctY3NzJykgZHJhZ0NTUzogc3RyaW5nO1xuICBASW5wdXQoJ2RyYWctb3Zlci1jc3MnKSBkcmFnT3ZlckNTUzogc3RyaW5nO1xuICBASW5wdXQoJ2RyYWctb3Zlci1jc3MtZm9yLWRyYWdnYWJsZScpIGRyYWdPdmVyQ1NTX3BvaW50ZXI6IHN0cmluZztcbiAgQElucHV0KCdhY2NlcHQtZnVuY3Rpb24nKSBhY2NlcHRGdW5jdGlvbjogKGRhdGE6IGFueSkgPT4gYm9vbGVhbjtcbiAgQE91dHB1dCgnb25kcm9wJykgb25Ecm9wRW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCdkcmFnLXN0YXJ0Jykgb25EcmFnU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgnZHJhZy1lbmQnKSBvbkRyYWdFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgnZHJhZy1lbnRlcicpIG9uRHJhZ0VudGVyID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoJ2RyYWctbGVhdmUnKSBvbkRyYWdMZWF2ZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIHByaXZhdGUgZHJvcENhbmRpZGF0ZW9mUG9pbnRlcnM6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgcHJpdmF0ZSBwb2ludGVyc0hvdmVyOiBBcnJheTxzdHJpbmc+ID0gW107XG5cbiAgY29uc3RydWN0b3IoZWw6IEVsZW1lbnRSZWYpIHtcbiAgICBpZiAoIWRyYWdEcm9wSW5pdCkge1xuICAgICAgY29uc29sZS5lcnJvcignWW91IHNob3VsZCBhZGQgb25lIGRyYWdkcm9wIGF0dHJpYnV0ZSB0byB5b3VyIGNvZGUgYmVmb3JlIHVzaW5nIGRyb3B6b25lJyk7XG4gICAgfVxuICAgIHRoaXMucm9vdCA9IGVsLm5hdGl2ZUVsZW1lbnQ7XG4gICAgRE0ucmVnaXN0ZXJEcm9wWm9uZSh0aGlzKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIC8vXG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBETS51bnJlZ2lzdGVyRHJvcFpvbmUodGhpcyk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcmFnZW50ZXInLCBbJyRldmVudCddKSBCcm93c2VyRHJhZ0VudGVyKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgdGhpcy5uYkRyYWdFbnRlcisrO1xuICAgIGlmICh0aGlzLm5iRHJhZ0VudGVyID09PSAxKSB7XG4gICAgICB0aGlzLmFwcGVuZFBvaW50ZXJIb3ZlcihkcmFnUG9pbnRlcklkKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcmFnbGVhdmUnLCBbJyRldmVudCddKSBCcm93c2VyRHJhZ0xlYXZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgdGhpcy5uYkRyYWdFbnRlci0tO1xuICAgIGlmICh0aGlzLm5iRHJhZ0VudGVyID09PSAwKSB7XG4gICAgICB0aGlzLnJlbW92ZVBvaW50ZXJIb3ZlcihkcmFnUG9pbnRlcklkKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkcm9wJywgWyckZXZlbnQnXSkgQnJvd3NlckRyb3AoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBETS5wb2ludGVyUmVsZWFzZShkcmFnUG9pbnRlcklkKTtcbiAgICB0aGlzLm5iRHJhZ0VudGVyID0gMDtcbiAgICB0aGlzLm9uRHJvcEVtaXR0ZXIuZW1pdChldmVudCk7XG4gIH1cblxuICBkcm9wKG9iaikge1xuICAgIHRoaXMub25Ecm9wRW1pdHRlci5lbWl0KG9iaik7XG4gIH1cblxuICBjaGVja0FjY2VwdChkcmFnOiBEcmFnZ2FibGUgfCBEcmFnRXZlbnQpOiBib29sZWFuIHtcbiAgICBsZXQgcmVzOiBib29sZWFuO1xuICAgIGlmIChkcmFnIGluc3RhbmNlb2YgRHJhZ2dhYmxlKSB7XG4gICAgICByZXMgPSB0aGlzLmFjY2VwdEZ1bmN0aW9uID8gdGhpcy5hY2NlcHRGdW5jdGlvbihkcmFnLmRyYWdnZWREYXRhKSA6IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcyA9IHRoaXMuYWNjZXB0RnVuY3Rpb24gPyB0aGlzLmFjY2VwdEZ1bmN0aW9uKGRyYWcpIDogdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIGhhc1BvaW50ZXJIb3ZlcihpZFBvaW50ZXI6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnBvaW50ZXJzSG92ZXIuaW5kZXhPZihpZFBvaW50ZXIpID49IDA7XG4gIH1cblxuICBhcHBlbmRQb2ludGVySG92ZXIoaWRQb2ludGVyOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5wb2ludGVyc0hvdmVyLmluZGV4T2YoaWRQb2ludGVyKSA9PT0gLTEpIHtcbiAgICAgIGNvbnN0IGRyYWdnZWQgPSBETS5kcmFnZ2VkU3RydWN0dXJlcy5nZXQoaWRQb2ludGVyKTtcbiAgICAgIHRoaXMucG9pbnRlcnNIb3Zlci5wdXNoKGlkUG9pbnRlcik7XG4gICAgICBpZiAoZHJhZ2dlZCBpbnN0YW5jZW9mIERyYWdnYWJsZSkge1xuICAgICAgICBpZiAodGhpcy5kcmFnT3ZlckNTU19wb2ludGVyKSB7XG4gICAgICAgICAgZHJhZ2dlZC5nZXRDbG9uZSgpLmNsYXNzTGlzdC5hZGQodGhpcy5kcmFnT3ZlckNTU19wb2ludGVyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uRHJhZ0VudGVyLmVtaXQoZHJhZ2dlZC5kcmFnZ2VkRGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uRHJhZ0VudGVyLmVtaXQoZHJhZ2dlZCk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5kcmFnT3ZlckNTUykge1xuICAgICAgICB0aGlzLnJvb3QuY2xhc3NMaXN0LmFkZCh0aGlzLmRyYWdPdmVyQ1NTKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVQb2ludGVySG92ZXIoaWRQb2ludGVyOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwb3MgPSB0aGlzLnBvaW50ZXJzSG92ZXIuaW5kZXhPZihpZFBvaW50ZXIpO1xuICAgIGlmIChwb3MgPj0gMCkge1xuICAgICAgY29uc3QgZHJhZ2dlZCA9IERNLmRyYWdnZWRTdHJ1Y3R1cmVzLmdldChpZFBvaW50ZXIpO1xuICAgICAgdGhpcy5wb2ludGVyc0hvdmVyLnNwbGljZShwb3MsIDEpO1xuICAgICAgaWYgKGRyYWdnZWQgaW5zdGFuY2VvZiBEcmFnZ2FibGUpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJhZ092ZXJDU1NfcG9pbnRlcikge1xuICAgICAgICAgIGRyYWdnZWQuZ2V0Q2xvbmUoKS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuZHJhZ092ZXJDU1NfcG9pbnRlcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbkRyYWdMZWF2ZS5lbWl0KGRyYWdnZWQuZHJhZ2dlZERhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkRyYWdMZWF2ZS5lbWl0KGRyYWdnZWQpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucG9pbnRlcnNIb3Zlci5sZW5ndGggPT09IDAgJiYgdGhpcy5kcmFnT3ZlckNTUykge1xuICAgICAgICB0aGlzLnJvb3QuY2xhc3NMaXN0LnJlbW92ZSh0aGlzLmRyYWdPdmVyQ1NTKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhcHBlbmREcm9wQ2FuZGlkYXRlUG9pbnRlcihpZFBvaW50ZXI6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmRyb3BDYW5kaWRhdGVvZlBvaW50ZXJzLmluZGV4T2YoaWRQb2ludGVyKSA9PT0gLTEpIHtcbiAgICAgIGNvbnN0IGRyYWdnZWQgPSBETS5kcmFnZ2VkU3RydWN0dXJlcy5nZXQoaWRQb2ludGVyKTtcbiAgICAgIGlmIChkcmFnZ2VkIGluc3RhbmNlb2YgRHJhZ2dhYmxlKSB7XG4gICAgICAgIHRoaXMub25EcmFnU3RhcnQuZW1pdChkcmFnZ2VkLmRyYWdnZWREYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25EcmFnU3RhcnQuZW1pdChkcmFnZ2VkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZHJvcENhbmRpZGF0ZW9mUG9pbnRlcnMucHVzaChpZFBvaW50ZXIpO1xuICAgICAgaWYgKHRoaXMuZHJhZ0NTUykge1xuICAgICAgICB0aGlzLnJvb3QuY2xhc3NMaXN0LmFkZCh0aGlzLmRyYWdDU1MpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZURyb3BDYW5kaWRhdGVQb2ludGVyKGlkUG9pbnRlcjogc3RyaW5nKSB7XG4gICAgY29uc3QgcG9zID0gdGhpcy5kcm9wQ2FuZGlkYXRlb2ZQb2ludGVycy5pbmRleE9mKGlkUG9pbnRlcik7XG4gICAgaWYgKHBvcyA+PSAwKSB7XG4gICAgICBjb25zdCBkcmFnZ2VkID0gRE0uZHJhZ2dlZFN0cnVjdHVyZXMuZ2V0KGlkUG9pbnRlcik7XG4gICAgICBpZiAoZHJhZ2dlZCBpbnN0YW5jZW9mIERyYWdnYWJsZSkge1xuICAgICAgICB0aGlzLm9uRHJhZ0VuZC5lbWl0KGRyYWdnZWQuZHJhZ2dlZERhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkRyYWdFbmQuZW1pdChkcmFnZ2VkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZHJvcENhbmRpZGF0ZW9mUG9pbnRlcnMuc3BsaWNlKHBvcywgMSk7XG4gICAgICBpZiAodGhpcy5kcm9wQ2FuZGlkYXRlb2ZQb2ludGVycy5sZW5ndGggPT09IDAgJiYgdGhpcy5kcmFnQ1NTKSB7XG4gICAgICAgIHRoaXMucm9vdC5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuZHJhZ0NTUyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=