ng-devui
Version:
DevUI components based on Angular
326 lines • 57.6 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { Directive, ElementRef, Inject, Input, NgZone } from '@angular/core';
import { fromEvent, merge as mergeStatic, Subscription } from 'rxjs';
import { tap, throttleTime } from 'rxjs/operators';
import { DragDropService } from '../services/drag-drop.service';
import { Utils } from '../shared/utils';
import { DropScrollEnhanceTimingFunctionGroup, DropScrollOrientation } from './drop-scroll-enhance.type';
import * as i0 from "@angular/core";
import * as i1 from "../services/drag-drop.service";
export class DropScrollEnhancedDirective {
constructor(el, zone, dragDropService, doc) {
this.el = el;
this.zone = zone;
this.dragDropService = dragDropService;
this.doc = doc;
this.minSpeed = 50;
this.maxSpeed = 1000;
this.responseEdgeWidth = '100px';
this.speedFn = DropScrollEnhanceTimingFunctionGroup.default;
this.direction = 'v';
this.backSpaceDroppable = true;
this.subscription = new Subscription();
this.document = this.doc;
}
ngAfterViewInit() {
// 设置父元素
this.el.nativeElement.parentNode.style.position = 'relative';
this.el.nativeElement.parentNode.style.display = 'block';
// 创建后退前进区域和对应的滚动函数
this.forwardScrollArea = this.createScrollArea(this.direction, DropScrollOrientation.forward);
this.backwardScrollArea = this.createScrollArea(this.direction, DropScrollOrientation.backward);
this.forwardScrollFn = this.createScrollFn(this.direction, DropScrollOrientation.forward, this.speedFn);
this.backwardScrollFn = this.createScrollFn(this.direction, DropScrollOrientation.backward, this.speedFn);
this.zone.runOutsideAngular(() => {
// 拖拽到其上触发滚动
this.subscription.add(fromEvent(this.forwardScrollArea, 'dragover')
.pipe(tap(event => { event.preventDefault(); event.stopPropagation(); }), throttleTime(100, undefined, { leading: true, trailing: false })).subscribe(event => this.forwardScrollFn(event)));
this.subscription.add(fromEvent(this.backwardScrollArea, 'dragover')
.pipe(tap(event => { event.preventDefault(); event.stopPropagation(); }), throttleTime(100, undefined, { leading: true, trailing: false }))
.subscribe(event => this.backwardScrollFn(event)));
// 拖拽放置委托
this.subscription.add(mergeStatic(fromEvent(this.forwardScrollArea, 'drop'), fromEvent(this.backwardScrollArea, 'drop')).subscribe(event => this.delegateDropEvent(event)));
// 拖拽离开清除参数
this.subscription.add(mergeStatic(fromEvent(this.forwardScrollArea, 'dragleave', { passive: true }), fromEvent(this.backwardScrollArea, 'dragleave', { passive: true })).subscribe(event => this.cleanLastScrollTime()));
// 滚动过程计算区域有效性,滚动条贴到边缘的时候无效,无效的时候设置鼠标事件可用为none
this.subscription.add(fromEvent(this.el.nativeElement, 'scroll', { passive: true })
.pipe(throttleTime(300, undefined, { leading: true, trailing: true }))
.subscribe(event => {
this.toggleScrollToOneEnd(this.el.nativeElement, this.forwardScrollArea, this.direction, DropScrollOrientation.forward);
this.toggleScrollToOneEnd(this.el.nativeElement, this.backwardScrollArea, this.direction, DropScrollOrientation.backward);
}));
// 窗口缩放的时候重绘有效性区域
this.subscription.add(fromEvent(window, 'resize', { passive: true })
.pipe(throttleTime(300, undefined, { leading: true, trailing: true }))
.subscribe(event => this.resizeArea()));
// dragstart的时候显示拖拽滚动边缘面板
this.subscription.add(this.dragDropService.dragStartEvent.subscribe(() => {
if (!this.allowScroll()) {
return;
}
this.zone.runOutsideAngular(() => {
setTimeout(() => {
// 立马出现会打断边缘元素的拖拽
this.forwardScrollArea.style.display = 'block';
this.backwardScrollArea.style.display = 'block';
});
});
}));
// dragEnd或drop的时候结束了拖拽,滚动区域影藏起来
this.subscription.add(mergeStatic(this.dragDropService.dragEndEvent, this.dragDropService.dropEvent)
.subscribe(() => {
this.forwardScrollArea.style.display = 'none';
this.backwardScrollArea.style.display = 'none';
this.lastScrollTime = undefined;
}));
});
setTimeout(() => {
this.resizeArea();
}, 0);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
createScrollFn(direction, orientation, speedFn) {
if (typeof window === 'undefined') {
return;
}
const scrollAttr = (direction === 'v') ? 'scrollTop' : 'scrollLeft';
const eventAttr = (direction === 'v') ? 'clientY' : 'clientX';
const scrollWidthAttr = (direction === 'v') ? 'scrollHeight' : 'scrollWidth';
const offsetWidthAttr = (direction === 'v') ? 'offsetHeight' : 'offsetWidth';
const clientWidthAttr = (direction === 'v') ? 'clientHeight' : 'clientWidth';
const rectWidthAttr = (direction === 'v') ? 'height' : 'width';
const compareTarget = (orientation === DropScrollOrientation.forward) ? this.forwardScrollArea : this.backwardScrollArea;
const targetAttr = this.getCriticalEdge(direction, orientation);
const scrollElement = this.el.nativeElement;
return (event) => {
const compareTargetRect = compareTarget.getBoundingClientRect();
const distance = event[eventAttr] - compareTargetRect[targetAttr];
let speed = speedFn(Math.abs(distance / (compareTargetRect[rectWidthAttr] || 1)));
if (speed < this.minSpeed) {
speed = this.minSpeed;
}
if (speed > this.maxSpeed) {
speed = this.maxSpeed;
}
if (distance < 0) {
speed = -speed;
}
if (this.animationFrameId) {
window.cancelAnimationFrame(this.animationFrameId);
this.animationFrameId = undefined;
}
this.animationFrameId = requestAnimationFrame(() => {
const time = new Date().getTime();
const moveDistance = Math.ceil(speed * (time - (this.lastScrollTime || time)) / 1000);
scrollElement[scrollAttr] -= moveDistance;
this.lastScrollTime = time;
// 判断是不是到尽头
if ((scrollElement[scrollAttr] === 0 && orientation === DropScrollOrientation.backward)
|| ((scrollElement[scrollAttr]
+ (scrollElement.getBoundingClientRect())[rectWidthAttr]
- scrollElement[offsetWidthAttr]
+ scrollElement[clientWidthAttr]) === scrollElement[scrollWidthAttr]
&& orientation === DropScrollOrientation.forward)) {
compareTarget.style.pointerEvents = 'none';
this.toggleActiveClass(compareTarget, false);
}
this.animationFrameId = undefined;
});
if (this.backSpaceDroppable) {
Utils.dispatchEventToUnderElement(event);
}
};
}
delegateDropEvent(event) {
if (this.backSpaceDroppable) {
const ev = Utils.dispatchEventToUnderElement(event);
if (ev.defaultPrevented) {
event.preventDefault();
event.stopPropagation();
}
}
}
getCriticalEdge(direction, orientation) {
return (direction === 'v' && orientation === DropScrollOrientation.forward && 'bottom')
|| (direction === 'v' && orientation === DropScrollOrientation.backward && 'top')
|| (direction !== 'v' && orientation === DropScrollOrientation.forward && 'right')
|| (direction !== 'v' && orientation === DropScrollOrientation.backward && 'left') || 'bottom';
}
getSecondEdge(direction) {
return (direction === 'v' && 'left')
|| (direction !== 'v' && 'top') || 'left';
}
createScrollArea(direction, orientation) {
const area = this.document.createElement('div');
area.className = `dropover-scroll-area dropover-scroll-area-${this.getCriticalEdge(direction, orientation)}`;
// 处理大小
area.classList.add('active');
this.setAreaSize(area, direction, orientation);
// 处理位置
area.style.position = 'absolute';
this.setAreaStyleLayout(area, direction, orientation);
// 默认不展示
area.style.display = 'none';
// 附着元素
this.el.nativeElement.parentNode.appendChild(area, this.el.nativeElement);
return area;
}
setAreaSize(area, direction, orientation) {
const rect = this.el.nativeElement.getBoundingClientRect();
const containerAttr = direction === 'v' ? 'height' : 'width';
const responseEdgeWidth = (typeof this.responseEdgeWidth === 'string')
? this.responseEdgeWidth
: this.responseEdgeWidth(rect[containerAttr]);
const settingOffset = this.viewOffset
&& (orientation === DropScrollOrientation.forward ? this.viewOffset.forward : this.viewOffset.backward);
let width = direction === 'v' ? (rect.width + 'px') : responseEdgeWidth;
let height = direction === 'v' ? responseEdgeWidth : (rect.height + 'px');
if (settingOffset) {
if (settingOffset.widthOffset) {
width = 'calc(' + width + ' + ' + (settingOffset.widthOffset) + 'px)';
}
if (settingOffset.heightOffset) {
height = 'calc(' + height + ' + ' + (settingOffset.heightOffset) + 'px)';
}
}
area.style.width = width;
area.style.height = height;
}
setAreaStyleLayout(area, direction, orientation) {
const target = this.el.nativeElement;
const relatedTarget = this.el.nativeElement.parentNode;
const defaultOffset = { left: 0, right: 0, top: 0, bottom: 0 };
const settingOffset = this.viewOffset
&& (orientation === DropScrollOrientation.forward ? this.viewOffset.forward : this.viewOffset.backward)
|| defaultOffset;
const criticalEdge = this.getCriticalEdge(direction, orientation);
const secondEdge = this.getSecondEdge(direction);
[criticalEdge, secondEdge].forEach(edge => {
area.style[edge] = this.getRelatedPosition(target, relatedTarget, edge, settingOffset[edge]);
});
}
getRelatedPosition(target, relatedTarget, edge, offsetValue) {
if (typeof window === 'undefined') {
return '0px';
}
const relatedComputedStyle = window.getComputedStyle(relatedTarget);
const relatedRect = relatedTarget.getBoundingClientRect();
const selfRect = target.getBoundingClientRect();
const helper = {
left: ['left', 'Left'],
right: ['right', 'Right'],
top: ['top', 'Top'],
bottom: ['bottom', 'Bottom'],
};
let factor = 1;
if (edge === 'right' || edge === 'bottom') {
factor = -1;
}
return (selfRect[helper[edge][0]] - relatedRect[helper[edge][0]]
+ parseInt(relatedComputedStyle['border' + helper[edge][1] + 'Width'], 10)) * factor
+ (offsetValue || 0)
+ 'px';
}
resizeArea() {
[{ area: this.forwardScrollArea, orientation: DropScrollOrientation.forward },
{ area: this.backwardScrollArea, orientation: DropScrollOrientation.backward }
]
.forEach(item => {
this.setAreaSize(item.area, this.direction, item.orientation);
this.setAreaStyleLayout(item.area, this.direction, item.orientation);
});
}
toggleScrollToOneEnd(scrollElement, toggleElement, direction, orientation) {
const scrollAttr = (direction === 'v') ? 'scrollTop' : 'scrollLeft';
const scrollWidthAttr = (direction === 'v') ? 'scrollHeight' : 'scrollWidth';
const offsetWidthAttr = (direction === 'v') ? 'offsetHeight' : 'offsetWidth';
const clientWidthAttr = (direction === 'v') ? 'clientHeight' : 'clientWidth';
const rectWidthAttr = (direction === 'v') ? 'height' : 'width';
if ((scrollElement[scrollAttr] === 0 && orientation === DropScrollOrientation.backward) || (Math.abs(scrollElement[scrollAttr]
+ (scrollElement.getBoundingClientRect())[rectWidthAttr]
- scrollElement[scrollWidthAttr]
- scrollElement[offsetWidthAttr]
+ scrollElement[clientWidthAttr]) < 1
&& orientation === DropScrollOrientation.forward)) {
toggleElement.style.pointerEvents = 'none';
this.toggleActiveClass(toggleElement, false);
}
else {
toggleElement.style.pointerEvents = 'auto';
this.toggleActiveClass(toggleElement, true);
}
}
cleanLastScrollTime() {
if (this.animationFrameId && typeof window !== 'undefined') {
window.cancelAnimationFrame(this.animationFrameId);
this.animationFrameId = undefined;
}
this.lastScrollTime = undefined;
}
toggleActiveClass(target, active) {
if (active) {
target.classList.remove('inactive');
target.classList.add('active');
}
else {
target.classList.remove('active');
target.classList.add('inactive');
}
}
allowScroll() {
if (!this.dropScrollScope) {
return true;
}
let allowed = false;
if (typeof this.dropScrollScope === 'string') {
if (typeof this.dragDropService.scope === 'string') {
allowed = this.dragDropService.scope === this.dropScrollScope;
}
if (this.dragDropService.scope instanceof Array) {
allowed = this.dragDropService.scope.indexOf(this.dropScrollScope) > -1;
}
}
if (this.dropScrollScope instanceof Array) {
if (typeof this.dragDropService.scope === 'string') {
allowed = this.dropScrollScope.indexOf(this.dragDropService.scope) > -1;
}
if (this.dragDropService.scope instanceof Array) {
allowed = this.dropScrollScope.filter((item) => {
return this.dragDropService.scope.indexOf(item) !== -1;
}).length > 0;
}
}
return allowed;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropScrollEnhancedDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.DragDropService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DropScrollEnhancedDirective, selector: "[dDropScrollEnhanced]", inputs: { minSpeed: "minSpeed", maxSpeed: "maxSpeed", responseEdgeWidth: "responseEdgeWidth", speedFn: "speedFn", direction: "direction", viewOffset: "viewOffset", dropScrollScope: "dropScrollScope", backSpaceDroppable: "backSpaceDroppable" }, exportAs: ["dDropScrollEnhanced"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropScrollEnhancedDirective, decorators: [{
type: Directive,
args: [{
selector: '[dDropScrollEnhanced]',
exportAs: 'dDropScrollEnhanced'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.DragDropService }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { minSpeed: [{
type: Input
}], maxSpeed: [{
type: Input
}], responseEdgeWidth: [{
type: Input
}], speedFn: [{
type: Input
}], direction: [{
type: Input
}], viewOffset: [{
type: Input
}], dropScrollScope: [{
type: Input
}], backSpaceDroppable: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1zY3JvbGwtZW5oYW5jZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9kZXZ1aS9kcmFnZHJvcC9kaXJlY3RpdmVzL2Ryb3Atc2Nyb2xsLWVuaGFuY2UuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQWlCLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdkcsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLElBQUksV0FBVyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRSxPQUFPLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEMsT0FBTyxFQUNzQyxvQ0FBb0MsRUFBRSxxQkFBcUIsRUFFdkcsTUFBTSw0QkFBNEIsQ0FBQzs7O0FBTXBDLE1BQU0sT0FBTywyQkFBMkI7SUFzQnRDLFlBQW9CLEVBQWMsRUFBVSxJQUFZLEVBQVUsZUFBZ0MsRUFDNUQsR0FBUTtRQUQxQixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUFVLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUM1RCxRQUFHLEdBQUgsR0FBRyxDQUFLO1FBdEJyQyxhQUFRLEdBQW9CLEVBQUUsQ0FBQztRQUMvQixhQUFRLEdBQW9CLElBQUksQ0FBQztRQUNqQyxzQkFBaUIsR0FBMEMsT0FBTyxDQUFDO1FBQ25FLFlBQU8sR0FBNEIsb0NBQW9DLENBQUMsT0FBTyxDQUFDO1FBQ2hGLGNBQVMsR0FBd0IsR0FBRyxDQUFD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QztJQUNqQixDQUFDOytHQXZVVSwyQkFBMkIsaUdBdUJsQixRQUFRO21HQXZCakIsMkJBQTJCOzs0RkFBM0IsMkJBQTJCO2tCQUp2QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSx1QkFBdUI7b0JBQ2pDLFFBQVEsRUFBRSxxQkFBcUI7aUJBQ2hDOzswQkF3QmMsTUFBTTsyQkFBQyxRQUFRO3lDQXRCbkIsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUlHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBJbmplY3QsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSBhcyBtZXJnZVN0YXRpYywgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YXAsIHRocm90dGxlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERyYWdEcm9wU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2RyYWctZHJvcC5zZXJ2aWNlJztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vc2hhcmVkL3V0aWxzJztcbmltcG9ydCB7XG4gIERyb3BTY3JvbGxBcmVhT2Zmc2V0LCBEcm9wU2Nyb2xsRGlyZWN0aW9uLCBEcm9wU2Nyb2xsRW5oYW5jZVRpbWluZ0Z1bmN0aW9uR3JvdXAsIERyb3BTY3JvbGxPcmllbnRhdGlvbixcbiAgRHJvcFNjcm9sbFNwZWVkLCBEcm9wU2Nyb2xsU3BlZWRGdW5jdGlvbiwgRHJvcFNjcm9sbFRyaWdnZXJFZGdlXG59IGZyb20gJy4vZHJvcC1zY3JvbGwtZW5oYW5jZS50eXBlJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2REcm9wU2Nyb2xsRW5oYW5jZWRdJyxcbiAgZXhwb3J0QXM6ICdkRHJvcFNjcm9sbEVuaGFuY2VkJ1xufSlcbmV4cG9ydCBjbGFzcyBEcm9wU2Nyb2xsRW5oYW5jZWREaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBtaW5TcGVlZDogRHJvcFNjcm9sbFNwZWVkID0gNTA7XG4gIEBJbnB1dCgpIG1heFNwZWVkOiBEcm9wU2Nyb2xsU3BlZWQgPSAxMDAwO1xuICBASW5wdXQoKSByZXNwb25zZUVkZ2VXaWR0aDogc3RyaW5nIHwgKCh0b3RhbDogbnVtYmVyKSA9PiBzdHJpbmcpICA9ICcxMDBweCc7XG4gIEBJbnB1dCgpIHNwZWVkRm46IERyb3BTY3JvbGxTcGVlZEZ1bmN0aW9uID0gRHJvcFNjcm9sbEVuaGFuY2VUaW1pbmdGdW5jdGlvbkdyb3VwLmRlZmF1bHQ7XG4gIEBJbnB1dCgpIGRpcmVjdGlvbjogRHJvcFNjcm9sbERpcmVjdGlvbiA9ICd2JztcbiAgQElucHV0KCkgdmlld09mZnNldDoge1xuICAgIGZvcndhcmQ/OiBEcm9wU2Nyb2xsQXJlYU9mZnNldDsgLy8g5LuF6YeN6KaB6L655ZKM5qyh6KaB6L655pyJ5pWIXG4gICAgYmFja3dhcmQ/OiBEcm9wU2Nyb2xsQXJlYU9mZnNldDtcbiAgfTtcbiAgQElucHV0KCkgZHJvcFNjcm9sbFNjb3BlOiBzdHJpbmcgfCBBcnJheTxzdHJpbmc+O1xuICBASW5wdXQoKSBiYWNrU3BhY2VEcm9wcGFibGUgPSB0cnVlO1xuXG4gIHByaXZhdGUgZm9yd2FyZFNjcm9sbEFyZWE6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGJhY2t3YXJkU2Nyb2xsQXJlYTogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgZm9yd2FyZFNjcm9sbEZuOiAoZXZlbnQ6IERyYWdFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBiYWNrd2FyZFNjcm9sbEZuOiAoZXZlbnQ6IERyYWdFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBsYXN0U2Nyb2xsVGltZTtcbiAgcHJpdmF0ZSBhbmltYXRpb25GcmFtZUlkOiBudW1iZXI7XG4gIGRvY3VtZW50OiBEb2N1bWVudDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBwcml2YXRlIHpvbmU6IE5nWm9uZSwgcHJpdmF0ZSBkcmFnRHJvcFNlcnZpY2U6IERyYWdEcm9wU2VydmljZSxcbiAgICAgICAgICAgICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2M6IGFueSkge1xuICAgIHRoaXMuZG9jdW1lbnQgPSB0aGlzLmRvYztcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAvLyDorr7nva7niLblhYPntKBcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucGFyZW50Tm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnBhcmVudE5vZGUuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgLy8g5Yib5bu65ZCO6YCA5YmN6L+b5Yy65Z+f5ZKM5a+55bqU55qE5rua5Yqo5Ye95pWwXG4gICAgdGhpcy5mb3J3YXJkU2Nyb2xsQXJlYSA9IHRoaXMuY3JlYXRlU2Nyb2xsQXJlYSh0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmZvcndhcmQpO1xuICAgIHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhID0gdGhpcy5jcmVhdGVTY3JvbGxBcmVhKHRoaXMuZGlyZWN0aW9uLCBEcm9wU2Nyb2xsT3JpZW50YXRpb24uYmFja3dhcmQpO1xuICAgIHRoaXMuZm9yd2FyZFNjcm9sbEZuID0gdGhpcy5jcmVhdGVTY3JvbGxGbih0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmZvcndhcmQsIHRoaXMuc3BlZWRGbik7XG4gICAgdGhpcy5iYWNrd2FyZFNjcm9sbEZuID0gdGhpcy5jcmVhdGVTY3JvbGxGbih0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmJhY2t3YXJkLCB0aGlzLnNwZWVkRm4pO1xuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAvLyDmi5bmi73liLDlhbbkuIrop6blj5Hmu5rliqhcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChmcm9tRXZlbnQ8RHJhZ0V2ZW50Pih0aGlzLmZvcndhcmRTY3JvbGxBcmVhLCAnZHJhZ292ZXInKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoZXZlbnQgPT4ge2V2ZW50LnByZXZlbnREZWZhdWx0KCk7IGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyB9KSxcbiAgICAgICAgICB0aHJvdHRsZVRpbWUoMTAwLCB1bmRlZmluZWQsIHtsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogZmFsc2V9KVxuICAgICAgICApLnN1YnNjcmliZShldmVudCA9PiB0aGlzLmZvcndhcmRTY3JvbGxGbihldmVudCkpKTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChmcm9tRXZlbnQ8RHJhZ0V2ZW50Pih0aGlzLmJhY2t3YXJkU2Nyb2xsQXJlYSwgJ2RyYWdvdmVyJylcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKGV2ZW50ID0+IHtldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgfSksXG4gICAgICAgICAgdGhyb3R0bGVUaW1lKDEwMCwgdW5kZWZpbmVkLCB7bGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IGZhbHNlfSkpXG4gICAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4gdGhpcy5iYWNrd2FyZFNjcm9sbEZuKGV2ZW50KSkpO1xuICAgICAgLy8g5ouW5ou95pS+572u5aeU5omYXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXG4gICAgICAgIG1lcmdlU3RhdGljKFxuICAgICAgICAgIGZyb21FdmVudDxEcmFnRXZlbnQ+KHRoaXMuZm9yd2FyZFNjcm9sbEFyZWEsICdkcm9wJyksXG4gICAgICAgICAgZnJvbUV2ZW50PERyYWdFdmVudD4odGhpcy5iYWNrd2FyZFNjcm9sbEFyZWEsICdkcm9wJylcbiAgICAgICAgKS5zdWJzY3JpYmUoZXZlbnQgPT4gdGhpcy5kZWxlZ2F0ZURyb3BFdmVudChldmVudCkpKTtcbiAgICAgIC8vIOaLluaLveemu+W8gOa4hemZpOWPguaVsFxuICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgICBtZXJnZVN0YXRpYyhcbiAgICAgICAgICBmcm9tRXZlbnQodGhpcy5mb3J3YXJkU2Nyb2xsQXJlYSwgJ2RyYWdsZWF2ZScsIHtwYXNzaXZlOiB0cnVlfSksXG4gICAgICAgICAgZnJvbUV2ZW50KHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLCAnZHJhZ2xlYXZlJywge3Bhc3NpdmU6IHRydWV9KVxuICAgICAgICApLnN1YnNjcmliZShldmVudCA9PiB0aGlzLmNsZWFuTGFzdFNjcm9sbFRpbWUoKSlcbiAgICAgICk7XG4gICAgICAvLyDmu5rliqjov4fnqIvorqHnrpfljLrln5/mnInmlYjmgKfvvIzmu5rliqjmnaHotLTliLDovrnnvJjnmoTml7blgJnml6DmlYjvvIzml6DmlYjnmoTml7blgJnorr7nva7pvKDmoIfkuovku7blj6/nlKjkuLpub25lXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoXG4gICAgICAgIGZyb21FdmVudCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICdzY3JvbGwnLCB7cGFzc2l2ZTogdHJ1ZX0pXG4gICAgICAgICAgLnBpcGUodGhyb3R0bGVUaW1lKDMwMCwgdW5kZWZpbmVkLCB7bGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IHRydWV9KSlcbiAgICAgICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMudG9nZ2xlU2Nyb2xsVG9PbmVFbmQodGhpcy5lbC5uYXRpdmVFbGVtZW50LCB0aGlzLmZvcndhcmRTY3JvbGxBcmVhLCB0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmZvcndhcmQpO1xuICAgICAgICAgICAgdGhpcy50b2dnbGVTY3JvbGxUb09uZUVuZCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsIHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLCB0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmJhY2t3YXJkKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIC8vIOeql+WPo+e8qeaUvueahOaXtuWAmemHjee7mOacieaViOaAp+WMuuWfn1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgICBmcm9tRXZlbnQod2luZG93LCAncmVzaXplJywge3Bhc3NpdmU6IHRydWV9KVxuICAgICAgICAgIC5waXBlKHRocm90dGxlVGltZSgzMDAsIHVuZGVmaW5lZCwge2xlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiB0cnVlfSkpXG4gICAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB0aGlzLnJlc2l6ZUFyZWEoKSlcbiAgICAgICk7XG4gICAgICAvLyBkcmFnc3RhcnTnmoTml7blgJnmmL7npLrmi5bmi73mu5rliqjovrnnvJjpnaLmnb9cbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgICAgdGhpcy5kcmFnRHJvcFNlcnZpY2UuZHJhZ1N0YXJ0RXZlbnQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dTY3JvbGwoKSkge3JldHVybjsgfVxuICAgICAgICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgLy8g56uL6ams5Ye6546w5Lya5omT5pat6L6557yY5YWD57Sg55qE5ouW5ou9XG4gICAgICAgICAgICAgIHRoaXMuZm9yd2FyZFNjcm9sbEFyZWEuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICAgIHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgICAgLy8gZHJhZ0VuZOaIlmRyb3DnmoTml7blgJnnu5PmnZ/kuobmi5bmi73vvIzmu5rliqjljLrln5/lvbHol4/otbfmnaVcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgICAgbWVyZ2VTdGF0aWModGhpcy5kcmFnRHJvcFNlcnZpY2UuZHJhZ0VuZEV2ZW50LCB0aGlzLmRyYWdEcm9wU2VydmljZS5kcm9wRXZlbnQpXG4gICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZvcndhcmRTY3JvbGxBcmVhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICB0aGlzLmJhY2t3YXJkU2Nyb2xsQXJlYS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgdGhpcy5sYXN0U2Nyb2xsVGltZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMucmVzaXplQXJlYSgpO1xuICAgIH0sIDApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGNyZWF0ZVNjcm9sbEZuKGRpcmVjdGlvbjogRHJvcFNjcm9sbERpcmVjdGlvbiwgb3JpZW50YXRpb246IERyb3BTY3JvbGxPcmllbnRhdGlvbixcbiAgICAgICAgICAgICAgICAgc3BlZWRGbjogRHJvcFNjcm9sbFNwZWVkRnVuY3Rpb24pIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2Nyb2xsQXR0ciA9IChkaXJlY3Rpb24gPT09ICd2JykgPyAnc2Nyb2xsVG9wJyA6ICdzY3JvbGxMZWZ0JztcbiAgICBjb25zdCBldmVudEF0dHIgPSAoZGlyZWN0aW9uID09PSAndicpID8gJ2NsaWVudFknIDogJ2NsaWVudFgnO1xuICAgIGNvbnN0IHNjcm9sbFdpZHRoQXR0ciA9IChkaXJlY3Rpb24gPT09ICd2JykgPyAnc2Nyb2xsSGVpZ2h0JyA6ICdzY3JvbGxXaWR0aCc7XG4gICAgY29uc3Qgb2Zmc2V0V2lkdGhBdHRyID0gKGRpcmVjdGlvbiA9PT0gJ3YnKSA/ICdvZmZzZXRIZWlnaHQnIDogJ29mZnNldFdpZHRoJztcbiAgICBjb25zdCBjbGllbnRXaWR0aEF0dHIgPSAoZGlyZWN0aW9uID09PSAndicpID8gJ2NsaWVudEhlaWdodCcgOiAnY2xpZW50V2lkdGgnO1xuICAgIGNvbnN0IHJlY3RXaWR0aEF0dHIgPSAoZGlyZWN0aW9uID09PSAndicpID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgIGNvbnN0IGNvbXBhcmVUYXJnZXQgPSAob3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkKSA/IHRoaXMuZm9yd2FyZFNjcm9sbEFyZWEgOiB0aGlzLmJhY2t3YXJkU2Nyb2xsQXJlYTtcbiAgICBjb25zdCB0YXJnZXRBdHRyID0gdGhpcy5nZXRDcml0aWNhbEVkZ2UoZGlyZWN0aW9uLCBvcmllbnRhdGlvbik7XG4gICAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcblxuICAgIHJldHVybiAoZXZlbnQ6IERyYWdFdmVudCkgPT4ge1xuICAgICAgY29uc3QgY29tcGFyZVRhcmdldFJlY3QgPSBjb21wYXJlVGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgZGlzdGFuY2UgPSBldmVudFtldmVudEF0dHJdIC0gY29tcGFyZVRhcmdldFJlY3RbdGFyZ2V0QXR0cl07XG4gICAgICBsZXQgc3BlZWQgPSBzcGVlZEZuKE1hdGguYWJzKGRpc3RhbmNlIC8gKGNvbXBhcmVUYXJnZXRSZWN0W3JlY3RXaWR0aEF0dHJdIHx8IDEpKSk7XG4gICAgICBpZiAoc3BlZWQgPCB0aGlzLm1pblNwZWVkKSB7IHNwZWVkID0gdGhpcy5taW5TcGVlZDsgfVxuICAgICAgaWYgKHNwZWVkID4gdGhpcy5tYXhTcGVlZCkgeyBzcGVlZCA9IHRoaXMubWF4U3BlZWQ7IH1cbiAgICAgIGlmIChkaXN0YW5jZSA8IDApIHsgc3BlZWQgPSAtIHNwZWVkOyB9XG4gICAgICBpZiAodGhpcy5hbmltYXRpb25GcmFtZUlkKSB7XG4gICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkZyYW1lSWQpO1xuICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IG1vdmVEaXN0YW5jZSA9IE1hdGguY2VpbChzcGVlZCAqICh0aW1lIC0gKHRoaXMubGFzdFNjcm9sbFRpbWUgfHwgdGltZSkpIC8gMTAwMCk7XG4gICAgICAgIHNjcm9sbEVsZW1lbnRbc2Nyb2xsQXR0cl0gLT0gbW92ZURpc3RhbmNlO1xuICAgICAgICB0aGlzLmxhc3RTY3JvbGxUaW1lID0gdGltZTtcbiAgICAgICAgLy8g5Yik5pat5piv5LiN5piv5Yiw5bC95aS0XG4gICAgICAgIGlmICgoc2Nyb2xsRWxlbWVudFtzY3JvbGxBdHRyXSA9PT0gMCAmJiBvcmllbnRhdGlvbiA9PT0gRHJvcFNjcm9sbE9yaWVudGF0aW9uLmJhY2t3YXJkKVxuICAgICAgICB8fCAoKHNjcm9sbEVsZW1lbnRbc2Nyb2xsQXR0cl1cbiAgICAgICAgICArIChzY3JvbGxFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKVtyZWN0V2lkdGhBdHRyXVxuICAgICAgICAgIC0gc2Nyb2xsRWxlbWVudFtvZmZzZXRXaWR0aEF0dHJdXG4gICAgICAgICAgKyBzY3JvbGxFbGVtZW50W2NsaWVudFdpZHRoQXR0cl1cbiAgICAgICAgKSA9PT0gc2Nyb2xsRWxlbWVudFtzY3JvbGxXaWR0aEF0dHJdXG4gICAgICAgICAgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkKVxuICAgICAgICApIHtcbiAgICAgICAgICBjb21wYXJlVGFyZ2V0LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgICAgICAgdGhpcy50b2dnbGVBY3RpdmVDbGFzcyhjb21wYXJlVGFyZ2V0LCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hbmltYXRpb25GcmFtZUlkID0gdW5kZWZpbmVkO1xuICAgICAgfSk7XG4gICAgICBpZiAodGhpcy5iYWNrU3BhY2VEcm9wcGFibGUpIHtcbiAgICAgICAgVXRpbHMuZGlzcGF0Y2hFdmVudFRvVW5kZXJFbGVtZW50KGV2ZW50KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIGRlbGVnYXRlRHJvcEV2ZW50KGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICBpZiAodGhpcy5iYWNrU3BhY2VEcm9wcGFibGUpIHtcbiAgICAgIGNvbnN0IGV2ID0gVXRpbHMuZGlzcGF0Y2hFdmVudFRvVW5kZXJFbGVtZW50KGV2ZW50KTtcbiAgICAgIGlmIChldi5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBnZXRDcml0aWNhbEVkZ2UoZGlyZWN0aW9uOiBEcm9wU2Nyb2xsRGlyZWN0aW9uLCBvcmllbnRhdGlvbjogRHJvcFNjcm9sbE9yaWVudGF0aW9uKTogRHJvcFNjcm9sbFRyaWdnZXJFZGdlIHtcbiAgICByZXR1cm4gKGRpcmVjdGlvbiA9PT0gJ3YnICYmIG9yaWVudGF0aW9uID09PSBEcm9wU2Nyb2xsT3JpZW50YXRpb24uZm9yd2FyZCAmJiAnYm90dG9tJylcbiAgICB8fCAoZGlyZWN0aW9uID09PSAndicgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5iYWNrd2FyZCAmJiAndG9wJylcbiAgICB8fCAoZGlyZWN0aW9uICE9PSAndicgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkICYmICdyaWdodCcpXG4gICAgfHwgKGRpcmVjdGlvbiAhPT0gJ3YnICYmIG9yaWVudGF0aW9uID09PSBEcm9wU2Nyb2xsT3JpZW50YXRpb24uYmFja3dhcmQgJiYgJ2xlZnQnKSB8fCAnYm90dG9tJztcbiAgfVxuICBnZXRTZWNvbmRFZGdlKGRpcmVjdGlvbjogRHJvcFNjcm9sbERpcmVjdGlvbik6IERyb3BTY3JvbGxUcmlnZ2VyRWRnZSB7XG4gICAgcmV0dXJuIChkaXJlY3Rpb24gPT09ICd2JyAmJiAnbGVmdCcpXG4gICAgfHwgKGRpcmVjdGlvbiAhPT0gJ3YnICYmICAndG9wJykgfHwgJ2xlZnQnO1xuICB9XG5cbiAgY3JlYXRlU2Nyb2xsQXJlYShkaXJlY3Rpb246IERyb3BTY3JvbGxEaXJlY3Rpb24sIG9yaWVudGF0aW9uOiBEcm9wU2Nyb2xsT3JpZW50YXRpb24pIHtcbiAgICBjb25zdCBhcmVhID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBhcmVhLmNsYXNzTmFtZSA9IGBkcm9wb3Zlci1zY3JvbGwtYXJlYSBkcm9wb3Zlci1zY3JvbGwtYXJlYS0ke3RoaXMuZ2V0Q3JpdGljYWxFZGdlKGRpcmVjdGlvbiwgb3JpZW50YXRpb24pfWA7XG4gICAgLy8g5aSE55CG5aSn5bCPXG4gICAgYXJlYS5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICB0aGlzLnNldEFyZWFTaXplKGFyZWEsIGRpcmVjdGlvbiwgb3JpZW50YXRpb24pO1xuICAgIC8vIOWkhOeQhuS9jee9rlxuICAgIGFyZWEuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIHRoaXMuc2V0QXJlYVN0eWxlTGF5b3V0KGFyZWEsIGRpcmVjdGlvbiwgb3JpZW50YXRpb24pO1xuXG4gICAgLy8g6buY6K6k5LiN5bGV56S6XG4gICAgYXJlYS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIC8vIOmZhOedgOWFg+e0oFxuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKGFyZWEsIHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XG4gICAgcmV0dXJuIGFyZWE7XG4gIH1cblxuICBzZXRBcmVhU2l6ZShhcmVhOiBIVE1MRWxlbWVudCwgZGlyZWN0aW9uOiBEcm9wU2Nyb2xsRGlyZWN0aW9uLCBvcmllbnRhdGlvbjogRHJvcFNjcm9sbE9yaWVudGF0aW9uKSB7XG4gICAgY29uc3QgcmVjdCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBjb250YWluZXJBdHRyID0gZGlyZWN0aW9uID09PSAndicgPyAnaGVpZ2h0JyA6ICd3aW