@rybos/angular2gridster
Version:
[](https://badge.fury.io/js/angular2gridster)
246 lines • 42.8 kB
JavaScript
import { fromEvent, merge } from 'rxjs';
import { share, map, filter, tap, switchMap, takeUntil, take, skip } from 'rxjs/operators';
import { DraggableEvent } from './DraggableEvent';
import { utils } from './utils';
export class Draggable {
constructor(element, config = {}) {
this.mousemove = merge(fromEvent(document, 'mousemove'), fromEvent(document, 'touchmove', { passive: false })).pipe(share());
this.mouseup = merge(fromEvent(document, 'mouseup'), fromEvent(document, 'touchend'), fromEvent(document, 'touchcancel')).pipe(share());
this.config = {
handlerClass: null,
scroll: true,
scrollEdge: 36,
scrollDirection: null
};
// reference to auto scrolling listeners
this.autoScrollingInterval = [];
this.element = element;
this.mousedown = merge(fromEvent(element, 'mousedown'), fromEvent(element, 'touchstart')).pipe(share());
this.config = { ...this.config, ...config };
this.dragStart = this.createDragStartObservable().pipe(share());
this.dragMove = this.createDragMoveObservable(this.dragStart);
this.dragStop = this.createDragStopObservable(this.dragStart);
this.fixProblemWithDnDForIE(element);
this.requestAnimationFrame =
window.requestAnimationFrame || (callback => setTimeout(callback, 1000 / 60));
this.cancelAnimationFrame = window.cancelAnimationFrame || (cafID => clearTimeout(cafID));
}
createDragStartObservable() {
return this.mousedown.pipe(map(md => new DraggableEvent(md)), filter((event) => this.isDragingByHandler(event)), tap(e => {
if (!e.isTouchEvent()) {
e.pauseEvent();
}
if (document.activeElement) {
document.activeElement.blur();
}
// prevents rendering performance issues while dragging item with selection inside
utils.clearSelection();
}), switchMap((startEvent) => {
return this.mousemove.pipe(map(mm => new DraggableEvent(mm)), filter((moveEvent) => this.inRange(startEvent, moveEvent, 5)), map(() => startEvent), takeUntil(this.mouseup), take(1));
}));
}
createDragMoveObservable(dragStart) {
return dragStart.pipe(tap(event => {
this.addTouchActionNone(event.target);
}), switchMap(startEvent => {
return this.mousemove.pipe(skip(1), map(mm => new DraggableEvent(mm)), tap(event => {
event.pauseEvent();
startEvent.pauseEvent();
}), takeUntil(this.mouseup));
}), filter(val => !!val), tap((event) => {
if (this.config.scroll) {
this.startScroll(this.element, event);
}
}));
}
createDragStopObservable(dragStart) {
return dragStart.pipe(switchMap(() => {
return this.mouseup.pipe(take(1));
}), map(e => new DraggableEvent(e)), tap(e => {
if (e.target) {
this.removeTouchActionNone(e.target);
}
this.autoScrollingInterval.forEach(raf => this.cancelAnimationFrame(raf));
}));
}
startScroll(item, event) {
const scrollContainer = this.getScrollContainer(item);
this.autoScrollingInterval.forEach(raf => this.cancelAnimationFrame(raf));
if (scrollContainer) {
this.startScrollForContainer(event, scrollContainer);
}
else {
this.startScrollForWindow(event);
}
}
startScrollForContainer(event, scrollContainer) {
if (!this.config.scrollDirection || this.config.scrollDirection === 'vertical') {
this.startScrollVerticallyForContainer(event, scrollContainer);
}
if (!this.config.scrollDirection || this.config.scrollDirection === 'horizontal') {
this.startScrollHorizontallyForContainer(event, scrollContainer);
}
}
startScrollVerticallyForContainer(event, scrollContainer) {
if (event.pageY - this.getOffset(scrollContainer).top < this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, -Draggable.SCROLL_SPEED, 'scrollTop');
}
else if (this.getOffset(scrollContainer).top +
scrollContainer.getBoundingClientRect().height -
event.pageY <
this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, Draggable.SCROLL_SPEED, 'scrollTop');
}
}
startScrollHorizontallyForContainer(event, scrollContainer) {
if (event.pageX - scrollContainer.getBoundingClientRect().left < this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, -Draggable.SCROLL_SPEED, 'scrollLeft');
}
else if (this.getOffset(scrollContainer).left +
scrollContainer.getBoundingClientRect().width -
event.pageX <
this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, Draggable.SCROLL_SPEED, 'scrollLeft');
}
}
startScrollForWindow(event) {
if (!this.config.scrollDirection || this.config.scrollDirection === 'vertical') {
this.startScrollVerticallyForWindow(event);
}
if (!this.config.scrollDirection || this.config.scrollDirection === 'horizontal') {
this.startScrollHorizontallyForWindow(event);
}
}
startScrollVerticallyForWindow(event) {
const scrollingElement = document.scrollingElement || document.documentElement || document.body;
// NOTE: Using `window.pageYOffset` here because IE doesn't have `window.scrollY`.
if (event.pageY - window.pageYOffset < this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, -Draggable.SCROLL_SPEED, 'scrollTop');
}
else if (window.innerHeight - (event.pageY - window.pageYOffset) <
this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, Draggable.SCROLL_SPEED, 'scrollTop');
}
}
startScrollHorizontallyForWindow(event) {
const scrollingElement = document.scrollingElement || document.documentElement || document.body;
// NOTE: Using `window.pageXOffset` here because IE doesn't have `window.scrollX`.
if (event.pageX - window.pageXOffset < this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, -Draggable.SCROLL_SPEED, 'scrollLeft');
}
else if (window.innerWidth - (event.pageX - window.pageXOffset) <
this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, Draggable.SCROLL_SPEED, 'scrollLeft');
}
}
getScrollContainer(node) {
const nodeOuterHeight = utils.getElementOuterHeight(node);
if (node.scrollHeight > Math.ceil(nodeOuterHeight)) {
return node;
}
if (!new RegExp('(body|html)', 'i').test(node.parentNode.tagName)) {
return this.getScrollContainer(node.parentNode);
}
return null;
}
startAutoScrolling(node, amount, direction) {
this.autoScrollingInterval.push(this.requestAnimationFrame(function () {
this.startAutoScrolling(node, amount, direction);
}.bind(this)));
return (node[direction] += amount * 0.25);
}
getOffset(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + this.getScroll('scrollLeft', 'pageXOffset'),
top: rect.top + this.getScroll('scrollTop', 'pageYOffset')
};
}
getScroll(scrollProp, offsetProp) {
if (typeof window[offsetProp] !== 'undefined') {
return window[offsetProp];
}
if (document.documentElement.clientHeight) {
return document.documentElement[scrollProp];
}
return document.body[scrollProp];
}
isDragingByHandler(event) {
if (!this.isValidDragHandler(event.target)) {
return false;
}
return (!this.config.handlerClass ||
(this.config.handlerClass &&
this.hasElementWithClass(this.config.handlerClass, event.target)));
}
isValidDragHandler(targetEl) {
return ['input', 'textarea'].indexOf(targetEl.tagName.toLowerCase()) === -1;
}
inRange(startEvent, moveEvent, range) {
return (Math.abs(moveEvent.clientX - startEvent.clientX) > range ||
Math.abs(moveEvent.clientY - startEvent.clientY) > range);
}
hasElementWithClass(className, target) {
while (target !== this.element) {
if (target.classList.contains(className)) {
return true;
}
target = target.parentElement;
}
return false;
}
pauseEvent(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (e.preventDefault) {
e.preventDefault();
}
e.cancelBubble = true;
e.returnValue = false;
}
fixProblemWithDnDForIE(element) {
if (this.isTouchDevice() && this.isIEorEdge() && element.style) {
element.style['touch-action'] = 'none';
}
}
removeTouchActionNone(element) {
if (!element.style) {
return;
}
element.style['touch-action'] = '';
}
addTouchActionNone(element) {
if (!element.style) {
return;
}
element.style['touch-action'] = 'none';
}
isTouchDevice() {
return ('ontouchstart' in window || navigator.maxTouchPoints // works on most browsers
); // works on IE10/11 and Surface
}
isIEorEdge() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
const trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
const rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
const edge = ua.indexOf('Edge/');
if (edge > 0) {
// Edge (IE 12+) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
}
}
Draggable.SCROLL_SPEED = 20;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhcjJncmlkc3Rlci9zcmMvbGliL3V0aWxzL2RyYWdnYWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWMsU0FBUyxFQUFFLEtBQUssRUFBUSxNQUFNLE1BQU0sQ0FBQztBQUMxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRWhDLE1BQU0sT0FBTyxTQUFTO0lBNkJsQixZQUFZLE9BQWdCLEVBQUUsTUFBTSxHQUFHLEVBQUU7UUFuQmpDLGNBQVMsR0FBMkIsS0FBSyxDQUM3QyxTQUFTLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxFQUNoQyxTQUFTLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUN2RCxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ1IsWUFBTyxHQUEyQixLQUFLLENBQzNDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLEVBQzlCLFNBQVMsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEVBQy9CLFNBQVMsQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQ3JDLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFUixXQUFNLEdBQUc7WUFDYixZQUFZLEVBQUUsSUFBSTtZQUNsQixNQUFNLEVBQUUsSUFBSTtZQUNaLFVBQVUsRUFBRSxFQUFFO1lBQ2QsZUFBZSxFQUFFLElBQUk7U0FDeEIs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LE9BQU8sUUFBUSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ2xFO1FBRUQsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqQyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUU7WUFDVix5Q0FBeUM7WUFDekMsT0FBTyxRQUFRLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDdEU7UUFFRCxnQkFBZ0I7UUFDaEIsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQzs7QUEzVk0sc0JBQVksR0FBRyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBmcm9tRXZlbnQsIG1lcmdlLCBwaXBlIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHNoYXJlLCBtYXAsIGZpbHRlciwgdGFwLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFrZSwgc2tpcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IERyYWdnYWJsZUV2ZW50IH0gZnJvbSAnLi9EcmFnZ2FibGVFdmVudCc7XHJcbmltcG9ydCB7IHV0aWxzIH0gZnJvbSAnLi91dGlscyc7XHJcblxyXG5leHBvcnQgY2xhc3MgRHJhZ2dhYmxlIHtcclxuICAgIHN0YXRpYyBTQ1JPTExfU1BFRUQgPSAyMDtcclxuICAgIGVsZW1lbnQ6IEVsZW1lbnQ7XHJcblxyXG4gICAgZHJhZ1N0YXJ0OiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PjtcclxuICAgIGRyYWdNb3ZlOiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PjtcclxuICAgIGRyYWdTdG9wOiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PjtcclxuICAgIC8vIEEgc2ltcGxlIHJlcXVlc3RBbmltYXRpb25GcmFtZSBwb2x5ZmlsbFxyXG4gICAgcHJpdmF0ZSByZXF1ZXN0QW5pbWF0aW9uRnJhbWU6IEZ1bmN0aW9uO1xyXG4gICAgcHJpdmF0ZSBjYW5jZWxBbmltYXRpb25GcmFtZTogRnVuY3Rpb247XHJcbiAgICBwcml2YXRlIG1vdXNlbW92ZTogT2JzZXJ2YWJsZTx7fSB8IEV2ZW50PiA9IG1lcmdlKFxyXG4gICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ21vdXNlbW92ZScpLFxyXG4gICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ3RvdWNobW92ZScsIHsgcGFzc2l2ZTogZmFsc2UgfSlcclxuICAgICkucGlwZShzaGFyZSgpKTtcclxuICAgIHByaXZhdGUgbW91c2V1cDogT2JzZXJ2YWJsZTx7fSB8IEV2ZW50PiA9IG1lcmdlKFxyXG4gICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ21vdXNldXAnKSxcclxuICAgICAgICBmcm9tRXZlbnQoZG9jdW1lbnQsICd0b3VjaGVuZCcpLFxyXG4gICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ3RvdWNoY2FuY2VsJylcclxuICAgICkucGlwZShzaGFyZSgpKTtcclxuICAgIHByaXZhdGUgbW91c2Vkb3duOiBPYnNlcnZhYmxlPHt9IHwgRXZlbnQ+O1xyXG4gICAgcHJpdmF0ZSBjb25maWcgPSB7XHJcbiAgICAgICAgaGFuZGxlckNsYXNzOiBudWxsLFxyXG4gICAgICAgIHNjcm9sbDogdHJ1ZSxcclxuICAgICAgICBzY3JvbGxFZGdlOiAzNixcclxuICAgICAgICBzY3JvbGxEaXJlY3Rpb246IG51bGxcclxuICAgIH07XHJcbiAgICAvLyByZWZlcmVuY2UgdG8gYXV0byBzY3JvbGxpbmcgbGlzdGVuZXJzXHJcbiAgICBwcml2YXRlIGF1dG9TY3JvbGxpbmdJbnRlcnZhbCA9IFtdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEVsZW1lbnQsIGNvbmZpZyA9IHt9KSB7XHJcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICB0aGlzLm1vdXNlZG93biA9IG1lcmdlKFxyXG4gICAgICAgICAgICBmcm9tRXZlbnQoZWxlbWVudCwgJ21vdXNlZG93bicpLFxyXG4gICAgICAgICAgICBmcm9tRXZlbnQoZWxlbWVudCwgJ3RvdWNoc3RhcnQnKVxyXG4gICAgICAgICkucGlwZShzaGFyZSgpKTtcclxuXHJcbiAgICAgICAgdGhpcy5jb25maWcgPSB7IC4uLnRoaXMuY29uZmlnLCAuLi5jb25maWcgfTtcclxuXHJcbiAgICAgICAgdGhpcy5kcmFnU3RhcnQgPSB0aGlzLmNyZWF0ZURyYWdTdGFydE9ic2VydmFibGUoKS5waXBlKHNoYXJlKCkpO1xyXG4gICAgICAgIHRoaXMuZHJhZ01vdmUgPSB0aGlzLmNyZWF0ZURyYWdNb3ZlT2JzZXJ2YWJsZSh0aGlzLmRyYWdTdGFydCk7XHJcbiAgICAgICAgdGhpcy5kcmFnU3RvcCA9IHRoaXMuY3JlYXRlRHJhZ1N0b3BPYnNlcnZhYmxlKHRoaXMuZHJhZ1N0YXJ0KTtcclxuXHJcbiAgICAgICAgdGhpcy5maXhQcm9ibGVtV2l0aERuREZvcklFKGVsZW1lbnQpO1xyXG5cclxuICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZSA9XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgKGNhbGxiYWNrID0+IHNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCkpO1xyXG4gICAgICAgIHRoaXMuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwgKGNhZklEID0+IGNsZWFyVGltZW91dChjYWZJRCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlRHJhZ1N0YXJ0T2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubW91c2Vkb3duLnBpcGUoXHJcbiAgICAgICAgICAgIG1hcChtZCA9PiBuZXcgRHJhZ2dhYmxlRXZlbnQobWQpKSxcclxuICAgICAgICAgICAgZmlsdGVyKChldmVudDogRHJhZ2dhYmxlRXZlbnQpID0+IHRoaXMuaXNEcmFnaW5nQnlIYW5kbGVyKGV2ZW50KSksXHJcbiAgICAgICAgICAgIHRhcChlID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghZS5pc1RvdWNoRXZlbnQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGUucGF1c2VFdmVudCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAoPGFueT5kb2N1bWVudC5hY3RpdmVFbGVtZW50KS5ibHVyKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwcmV2ZW50cyByZW5kZXJpbmcgcGVyZm9ybWFuY2UgaXNzdWVzIHdoaWxlIGRyYWdnaW5nIGl0ZW0gd2l0aCBzZWxlY3Rpb24gaW5zaWRlXHJcbiAgICAgICAgICAgICAgICB1dGlscy5jbGVhclNlbGVjdGlvbigpO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgc3dpdGNoTWFwKChzdGFydEV2ZW50OiBEcmFnZ2FibGVFdmVudCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW91c2Vtb3ZlLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKG1tID0+IG5ldyBEcmFnZ2FibGVFdmVudChtbSkpLFxyXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcigobW92ZUV2ZW50OiBEcmFnZ2FibGVFdmVudCkgPT4gdGhpcy5pblJhbmdlKHN0YXJ0RXZlbnQsIG1vdmVFdmVudCwgNSkpLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiBzdGFydEV2ZW50KSxcclxuICAgICAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5tb3VzZXVwKSxcclxuICAgICAgICAgICAgICAgICAgICB0YWtlKDEpXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVEcmFnTW92ZU9ic2VydmFibGUoXHJcbiAgICAgICAgZHJhZ1N0YXJ0OiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PlxyXG4gICAgKTogT2JzZXJ2YWJsZTxEcmFnZ2FibGVFdmVudD4ge1xyXG4gICAgICAgIHJldHVybiBkcmFnU3RhcnQucGlwZShcclxuICAgICAgICAgICAgdGFwKGV2ZW50ID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWRkVG91Y2hBY3Rpb25Ob25lKGV2ZW50LnRhcmdldCk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoc3RhcnRFdmVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tb3VzZW1vdmUucGlwZShcclxuICAgICAgICAgICAgICAgICAgICBza2lwKDEpLFxyXG4gICAgICAgICAgICAgICAgICAgIG1hcChtbSA9PiBuZXcgRHJhZ2dhYmxlRXZlbnQobW0pKSxcclxuICAgICAgICAgICAgICAgICAgICB0YXAoZXZlbnQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wYXVzZUV2ZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0RXZlbnQucGF1c2VFdmVudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLm1vdXNldXApXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgZmlsdGVyKHZhbCA9PiAhIXZhbCksXHJcbiAgICAgICAgICAgIHRhcCgoZXZlbnQ6IERyYWdnYWJsZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcuc2Nyb2xsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydFNjcm9sbCh0aGlzLmVsZW1lbnQsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY3JlYXRlRHJhZ1N0b3BPYnNlcnZhYmxlKGRyYWdTdGFydDogT2JzZXJ2YWJsZTxEcmFnZ2FibGVFdmVudD4pOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgICAgIHJldHVybiBkcmFnU3RhcnQucGlwZShcclxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1vdXNldXAucGlwZSh0YWtlKDEpKTtcclxuICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgIG1hcChlID0+IG5ldyBEcmFnZ2FibGVFdmVudChlKSksXHJcbiAgICAgICAgICAgIHRhcChlID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlVG91Y2hBY3Rpb25Ob25lKGUudGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuYXV0b1Njcm9sbGluZ0ludGVydmFsLmZvckVhY2gocmFmID0+IHRoaXMuY2FuY2VsQW5pbWF0aW9uRnJhbWUocmFmKSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsKGl0ZW06IEVsZW1lbnQsIGV2ZW50OiBEcmFnZ2FibGVFdmVudCkge1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbENvbnRhaW5lciA9IHRoaXMuZ2V0U2Nyb2xsQ29udGFpbmVyKGl0ZW0pO1xyXG4gICAgICAgIHRoaXMuYXV0b1Njcm9sbGluZ0ludGVydmFsLmZvckVhY2gocmFmID0+IHRoaXMuY2FuY2VsQW5pbWF0aW9uRnJhbWUocmFmKSk7XHJcblxyXG4gICAgICAgIGlmIChzY3JvbGxDb250YWluZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNjcm9sbEZvckNvbnRhaW5lcihldmVudCwgc2Nyb2xsQ29udGFpbmVyKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0U2Nyb2xsRm9yV2luZG93KGV2ZW50KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGFydFNjcm9sbEZvckNvbnRhaW5lcihldmVudDogRHJhZ2dhYmxlRXZlbnQsIHNjcm9sbENvbnRhaW5lcjogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiB8fCB0aGlzLmNvbmZpZy5zY3JvbGxEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNjcm9sbFZlcnRpY2FsbHlGb3JDb250YWluZXIoZXZlbnQsIHNjcm9sbENvbnRhaW5lcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiB8fCB0aGlzLmNvbmZpZy5zY3JvbGxEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0U2Nyb2xsSG9yaXpvbnRhbGx5Rm9yQ29udGFpbmVyKGV2ZW50LCBzY3JvbGxDb250YWluZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsVmVydGljYWxseUZvckNvbnRhaW5lcihcclxuICAgICAgICBldmVudDogRHJhZ2dhYmxlRXZlbnQsXHJcbiAgICAgICAgc2Nyb2xsQ29udGFpbmVyOiBIVE1MRWxlbWVudFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGV2ZW50LnBhZ2VZIC0gdGhpcy5nZXRPZmZzZXQoc2Nyb2xsQ29udGFpbmVyKS50b3AgPCB0aGlzLmNvbmZpZy5zY3JvbGxFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsaW5nKHNjcm9sbENvbnRhaW5lciwgLURyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxUb3AnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICB0aGlzLmdldE9mZnNldChzY3JvbGxDb250YWluZXIpLnRvcCArXHJcbiAgICAgICAgICAgICAgICBzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0IC1cclxuICAgICAgICAgICAgICAgIGV2ZW50LnBhZ2VZIDxcclxuICAgICAgICAgICAgdGhpcy5jb25maWcuc2Nyb2xsRWRnZVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhzY3JvbGxDb250YWluZXIsIERyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxUb3AnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGFydFNjcm9sbEhvcml6b250YWxseUZvckNvbnRhaW5lcihcclxuICAgICAgICBldmVudDogRHJhZ2dhYmxlRXZlbnQsXHJcbiAgICAgICAgc2Nyb2xsQ29udGFpbmVyOiBIVE1MRWxlbWVudFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGV2ZW50LnBhZ2VYIC0gc2Nyb2xsQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgPCB0aGlzLmNvbmZpZy5zY3JvbGxFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsaW5nKHNjcm9sbENvbnRhaW5lciwgLURyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxMZWZ0Jyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgdGhpcy5nZXRPZmZzZXQoc2Nyb2xsQ29udGFpbmVyKS5sZWZ0ICtcclxuICAgICAgICAgICAgICAgIHNjcm9sbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCAtXHJcbiAgICAgICAgICAgICAgICBldmVudC5wYWdlWCA8XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNjcm9sbEVkZ2VcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsQ29udGFpbmVyLCBEcmFnZ2FibGUuU0NST0xMX1NQRUVELCAnc2Nyb2xsTGVmdCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsRm9yV2luZG93KGV2ZW50KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5zY3JvbGxEaXJlY3Rpb24gfHwgdGhpcy5jb25maWcuc2Nyb2xsRGlyZWN0aW9uID09PSAndmVydGljYWwnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRTY3JvbGxWZXJ0aWNhbGx5Rm9yV2luZG93KGV2ZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuc2Nyb2xsRGlyZWN0aW9uIHx8IHRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRTY3JvbGxIb3Jpem9udGFsbHlGb3JXaW5kb3coZXZlbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsVmVydGljYWxseUZvcldpbmRvdyhldmVudDogRHJhZ2dhYmxlRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzY3JvbGxpbmdFbGVtZW50ID1cclxuICAgICAgICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keTtcclxuXHJcbiAgICAgICAgLy8gTk9URTogVXNpbmcgYHdpbmRvdy5wYWdlWU9mZnNldGAgaGVyZSBiZWNhdXNlIElFIGRvZXNuJ3QgaGF2ZSBgd2luZG93LnNjcm9sbFlgLlxyXG4gICAgICAgIGlmIChldmVudC5wYWdlWSAtIHdpbmRvdy5wYWdlWU9mZnNldCA8IHRoaXMuY29uZmlnLnNjcm9sbEVkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsaW5nRWxlbWVudCwgLURyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxUb3AnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICB3aW5kb3cuaW5uZXJIZWlnaHQgLSAoZXZlbnQucGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQpIDxcclxuICAgICAgICAgICAgdGhpcy5jb25maWcuc2Nyb2xsRWRnZVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhzY3JvbGxpbmdFbGVtZW50LCBEcmFnZ2FibGUuU0NST0xMX1NQRUVELCAnc2Nyb2xsVG9wJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTY3JvbGxIb3Jpem9udGFsbHlGb3JXaW5kb3coZXZlbnQ6IERyYWdnYWJsZUV2ZW50KTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc2Nyb2xsaW5nRWxlbWVudCA9XHJcbiAgICAgICAgICAgIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHk7XHJcblxyXG4gICAgICAgIC8vIE5PVEU6IFVzaW5nIGB3aW5kb3cucGFnZVhPZmZzZXRgIGhlcmUgYmVjYXVzZSBJRSBkb2Vzbid0IGhhdmUgYHdpbmRvdy5zY3JvbGxYYC5cclxuICAgICAgICBpZiAoZXZlbnQucGFnZVggLSB3aW5kb3cucGFnZVhPZmZzZXQgPCB0aGlzLmNvbmZpZy5zY3JvbGxFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsaW5nKHNjcm9sbGluZ0VsZW1lbnQsIC1EcmFnZ2FibGUuU0NST0xMX1NQRUVELCAnc2Nyb2xsTGVmdCcpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgIHdpbmRvdy5pbm5lcldpZHRoIC0gKGV2ZW50LnBhZ2VYIC0gd2luZG93LnBhZ2VYT2Zmc2V0KSA8XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnNjcm9sbEVkZ2VcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsaW5nRWxlbWVudCwgRHJhZ2dhYmxlLlNDUk9MTF9TUEVFRCwgJ3Njcm9sbExlZnQnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRTY3JvbGxDb250YWluZXIobm9kZSk6IEhUTUxFbGVtZW50IHtcclxuICAgICAgICBjb25zdCBub2RlT3V0ZXJIZWlnaHQgPSB1dGlscy5nZXRFbGVtZW50T3V0ZXJIZWlnaHQobm9kZSk7XHJcblxyXG4gICAgICAgIGlmIChub2RlLnNjcm9sbEhlaWdodCA+IE1hdGguY2VpbChub2RlT3V0ZXJIZWlnaHQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFuZXcgUmVnRXhwKCcoYm9keXxodG1sKScsICdpJykudGVzdChub2RlLnBhcmVudE5vZGUudGFnTmFtZSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2Nyb2xsQ29udGFpbmVyKG5vZGUucGFyZW50Tm9kZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0QXV0b1Njcm9sbGluZyhub2RlLCBhbW91bnQsIGRpcmVjdGlvbikge1xyXG4gICAgICAgIHRoaXMuYXV0b1Njcm9sbGluZ0ludGVydmFsLnB1c2goXHJcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcobm9kZSwgYW1vdW50LCBkaXJlY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICByZXR1cm4gKG5vZGVbZGlyZWN0aW9uXSArPSBhbW91bnQgKiAwLjI1KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldE9mZnNldChlbCkge1xyXG4gICAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBsZWZ0OiByZWN0LmxlZnQgKyB0aGlzLmdldFNjcm9sbCgnc2Nyb2xsTGVmdCcsICdwYWdlWE9mZnNldCcpLFxyXG4gICAgICAgICAgICB0b3A6IHJlY3QudG9wICsgdGhpcy5nZXRTY3JvbGwoJ3Njcm9sbFRvcCcsICdwYWdlWU9mZnNldCcpXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFNjcm9sbChzY3JvbGxQcm9wLCBvZmZzZXRQcm9wKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3dbb2Zmc2V0UHJvcF0gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB3aW5kb3dbb2Zmc2V0UHJvcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbc2Nyb2xsUHJvcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5ib2R5W3Njcm9sbFByb3BdO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNEcmFnaW5nQnlIYW5kbGVyKGV2ZW50OiBEcmFnZ2FibGVFdmVudCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkRHJhZ0hhbmRsZXIoZXZlbnQudGFyZ2V0KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAhdGhpcy5jb25maWcuaGFuZGxlckNsYXNzIHx8XHJcbiAgICAgICAgICAgICh0aGlzLmNvbmZpZy5oYW5kbGVyQ2xhc3MgJiZcclxuICAgICAgICAgICAgICAgIHRoaXMuaGFzRWxlbWVudFdpdGhDbGFzcyh0aGlzLmNvbmZpZy5oYW5kbGVyQ2xhc3MsIGV2ZW50LnRhcmdldCkpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGlzVmFsaWREcmFnSGFuZGxlcih0YXJnZXRFbDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIFsnaW5wdXQnLCAndGV4dGFyZWEnXS5pbmRleE9mKHRhcmdldEVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSkgPT09IC0xO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5SYW5nZShzdGFydEV2ZW50OiBEcmFnZ2FibGVFdmVudCwgbW92ZUV2ZW50OiBEcmFnZ2FibGVFdmVudCwgcmFuZ2U6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIE1hdGguYWJzKG1vdmVFdmVudC5jbGllbnRYIC0gc3RhcnRFdmVudC5jbGllbnRYKSA+IHJhbmdlIHx8XHJcbiAgICAgICAgICAgIE1hdGguYWJzKG1vdmVFdmVudC5jbGllbnRZIC0gc3RhcnRFdmVudC5jbGllbnRZKSA+IHJhbmdlXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhc0VsZW1lbnRXaXRoQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHRhcmdldDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgICAgd2hpbGUgKHRhcmdldCAhPT0gdGhpcy5lbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmICh0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnRFbGVtZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBwYXVzZUV2ZW50KGU6IEV2ZW50KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGUuc3RvcFByb3BhZ2F0aW9uKSB7XHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlO1xyXG4gICAgICAgIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGZpeFByb2JsZW1XaXRoRG5ERm9ySUUoZWxlbWVudDogRWxlbWVudCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzVG91Y2hEZXZpY2UoKSAmJiB0aGlzLmlzSUVvckVkZ2UoKSAmJiAoPEhUTUxFbGVtZW50PmVsZW1lbnQpLnN0eWxlKSB7XHJcbiAgICAgICAgICAgICg8SFRNTEVsZW1lbnQ+ZWxlbWVudCkuc3R5bGVbJ3RvdWNoLWFjdGlvbiddID0gJ25vbmUnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlbW92ZVRvdWNoQWN0aW9uTm9uZShlbGVtZW50OiBFbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKCEoPEhUTUxFbGVtZW50PmVsZW1lbnQpLnN0eWxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgKDxIVE1MRWxlbWVudD5lbGVtZW50KS5zdHlsZVsndG91Y2gtYWN0aW9uJ10gPSAnJztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZFRvdWNoQWN0aW9uTm9uZShlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKCEoPEhUTUxFbGVtZW50PmVsZW1lbnQpLnN0eWxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgKDxIVE1MRWxlbWVudD5lbGVtZW50KS5zdHlsZVsndG91Y2gtYWN0aW9uJ10gPSAnbm9uZSc7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpc1RvdWNoRGV2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCBuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgLy8gd29ya3Mgb24gbW9zdCBicm93c2Vyc1xyXG4gICAgICAgICk7IC8vIHdvcmtzIG9uIElFMTAvMTEgYW5kIFN1cmZhY2VcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGlzSUVvckVkZ2UoKSB7XHJcbiAgICAgICAgY29uc3QgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuXHJcbiAgICAgICAgY29uc3QgbXNpZSA9IHVhLmluZGV4T2YoJ01TSUUgJyk7XHJcbiAgICAgICAgaWYgKG1zaWUgPiAwKSB7XHJcbiAgICAgICAgICAgIC8vIElFIDEwIG9yIG9sZGVyID0+IHJldHVybiB2ZXJzaW9uIG51bWJlclxyXG4gICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKG1zaWUgKyA1LCB1YS5pbmRleE9mKCcuJywgbXNpZSkpLCAxMCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTtcclxuICAgICAgICBpZiAodHJpZGVudCA+IDApIHtcclxuICAgICAgICAgICAgLy8gSUUgMTEgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgIGNvbnN0IHJ2ID0gdWEuaW5kZXhPZigncnY6Jyk7XHJcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcocnYgKyAzLCB1YS5pbmRleE9mKCcuJywgcnYpKSwgMTApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZWRnZSA9IHVhLmluZGV4T2YoJ0VkZ2UvJyk7XHJcbiAgICAgICAgaWYgKGVkZ2UgPiAwKSB7XHJcbiAgICAgICAgICAgIC8vIEVkZ2UgKElFIDEyKykgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcoZWRnZSArIDUsIHVhLmluZGV4T2YoJy4nLCBlZGdlKSksIDEwKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG90aGVyIGJyb3dzZXJcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuIl19