UNPKG

@yoyoboot/l-52abp-ng-form-generator

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.

277 lines 37.8 kB
import { ContentChild, Directive, EventEmitter, HostListener, Input, Output } from "@angular/core"; import { getDirectChildElement, getDropData, shouldPositionPlaceholderBeforeElement } from "./dnd-utils"; import { getDndType, getDropEffect, isExternalDrag, setDropEffect } from "./dnd-state"; import * as i0 from "@angular/core"; export class DndPlaceholderRefDirective { constructor(elementRef) { this.elementRef = elementRef; } } DndPlaceholderRefDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: DndPlaceholderRefDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); DndPlaceholderRefDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.13", type: DndPlaceholderRefDirective, selector: "[dndPlaceholderRef]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: DndPlaceholderRefDirective, decorators: [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: "[dndPlaceholderRef]" }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } }); export class DndDropzoneDirective { constructor(ngZone, elementRef, renderer) { this.ngZone = ngZone; this.elementRef = elementRef; this.renderer = renderer; this.dndAllowExternal = false; this.dndHorizontal = false; this.dndDragoverClass = "dndDragover"; this.dndDropzoneDisabledClass = "dndDropzoneDisabled"; this.dndDragover = new EventEmitter(); this.dndDrop = new EventEmitter(); this.placeholder = null; this.disabled = false; this.dragEnterEventHandler = (event) => this.onDragEnter(event); this.dragOverEventHandler = (event) => this.onDragOver(event); this.dragLeaveEventHandler = (event) => this.onDragLeave(event); } set dndDisableIf(value) { this.disabled = !!value; if (this.disabled) { this.renderer.addClass(this.elementRef.nativeElement, this.dndDropzoneDisabledClass); } else { this.renderer.removeClass(this.elementRef.nativeElement, this.dndDropzoneDisabledClass); } } set dndDisableDropIf(value) { this.dndDisableIf = value; } ngAfterViewInit() { this.placeholder = this.tryGetPlaceholder(); this.removePlaceholderFromDOM(); this.ngZone.runOutsideAngular(() => { this.elementRef.nativeElement.addEventListener("dragenter", this.dragEnterEventHandler); this.elementRef.nativeElement.addEventListener("dragover", this.dragOverEventHandler); this.elementRef.nativeElement.addEventListener("dragleave", this.dragLeaveEventHandler); }); } ngOnDestroy() { this.elementRef.nativeElement.removeEventListener("dragenter", this.dragEnterEventHandler); this.elementRef.nativeElement.removeEventListener("dragover", this.dragOverEventHandler); this.elementRef.nativeElement.removeEventListener("dragleave", this.dragLeaveEventHandler); } onDragEnter(event) { // check if another dropzone is activated if (event._dndDropzoneActive === true) { this.cleanupDragoverState(); return; } // set as active if the target element is inside this dropzone if (typeof event._dndDropzoneActive === "undefined") { const newTarget = document.elementFromPoint(event.clientX, event.clientY); if (this.elementRef.nativeElement.contains(newTarget)) { event._dndDropzoneActive = true; } } // check if this drag event is allowed to drop on this dropzone const type = getDndType(event); if (this.isDropAllowed(type) === false) { return; } // allow the dragenter event.preventDefault(); } onDragOver(event) { // With nested dropzones, we want to ignore this event if a child dropzone // has already handled a dragover. Historically, event.stopPropagation() was // used to prevent this bubbling, but that prevents any dragovers outside the // ngx-drag-drop component, and stops other use cases such as scrolling on drag. // Instead, we can check if the event was already prevented by a child and bail early. if (event.defaultPrevented) { return; } // check if this drag event is allowed to drop on this dropzone const type = getDndType(event); if (this.isDropAllowed(type) === false) { return; } this.checkAndUpdatePlaceholderPosition(event); const dropEffect = getDropEffect(event, this.dndEffectAllowed); if (dropEffect === "none") { this.cleanupDragoverState(); return; } // allow the dragover event.preventDefault(); // set the drop effect setDropEffect(event, dropEffect); this.dndDragover.emit(event); this.renderer.addClass(this.elementRef.nativeElement, this.dndDragoverClass); } onDrop(event) { try { // check if this drag event is allowed to drop on this dropzone const type = getDndType(event); if (this.isDropAllowed(type) === false) { return; } const data = getDropData(event, isExternalDrag()); if (this.isDropAllowed(data.type) === false) { return; } // signal custom drop handling event.preventDefault(); const dropEffect = getDropEffect(event); setDropEffect(event, dropEffect); if (dropEffect === "none") { return; } const dropIndex = this.getPlaceholderIndex(); // if for whatever reason the placeholder is not present in the DOM but it should be there // we don't allow/emit the drop event since it breaks the contract // seems to only happen if drag and drop is executed faster than the DOM updates if (dropIndex === -1) { return; } this.dndDrop.emit({ event: event, dropEffect: dropEffect, isExternal: isExternalDrag(), data: data.data, index: dropIndex, type: type, }); event.stopPropagation(); } finally { this.cleanupDragoverState(); } } onDragLeave(event) { // check if still inside this dropzone and not yet handled by another dropzone if (typeof event._dndDropzoneActive === "undefined") { const newTarget = document.elementFromPoint(event.clientX, event.clientY); if (this.elementRef.nativeElement.contains(newTarget)) { event._dndDropzoneActive = true; return; } } this.cleanupDragoverState(); // cleanup drop effect when leaving dropzone setDropEffect(event, "none"); } isDropAllowed(type) { // dropzone is disabled -> deny it if (this.disabled === true) { return false; } // if drag did not start from our directive // and external drag sources are not allowed -> deny it if (isExternalDrag() === true && this.dndAllowExternal === false) { return false; } // no filtering by types -> allow it if (!this.dndDropzone) { return true; } // no type set -> allow it if (!type) { return true; } if (Array.isArray(this.dndDropzone) === false) { throw new Error("dndDropzone: bound value to [dndDropzone] must be an array!"); } // if dropzone contains type -> allow it return this.dndDropzone.indexOf(type) !== -1; } tryGetPlaceholder() { if (typeof this.dndPlaceholderRef !== "undefined") { return this.dndPlaceholderRef.elementRef.nativeElement; } // TODO nasty workaround needed because if ng-container / template is used @ContentChild() or DI will fail because // of wrong context see angular bug https://github.com/angular/angular/issues/13517 return this.elementRef.nativeElement.querySelector("[dndPlaceholderRef]"); } removePlaceholderFromDOM() { if (this.placeholder !== null && this.placeholder.parentNode !== null) { this.placeholder.parentNode.removeChild(this.placeholder); } } checkAndUpdatePlaceholderPosition(event) { if (this.placeholder === null) { return; } // make sure the placeholder is in the DOM if (this.placeholder.parentNode !== this.elementRef.nativeElement) { this.renderer.appendChild(this.elementRef.nativeElement, this.placeholder); } // update the position if the event originates from a child element of the dropzone const directChild = getDirectChildElement(this.elementRef.nativeElement, event.target); // early exit if no direct child or direct child is placeholder if (directChild === null || directChild === this.placeholder) { return; } const positionPlaceholderBeforeDirectChild = shouldPositionPlaceholderBeforeElement(event, directChild, this.dndHorizontal); if (positionPlaceholderBeforeDirectChild) { // do insert before only if necessary if (directChild.previousSibling !== this.placeholder) { this.renderer.insertBefore(this.elementRef.nativeElement, this.placeholder, directChild); } } else { // do insert after only if necessary if (directChild.nextSibling !== this.placeholder) { this.renderer.insertBefore(this.elementRef.nativeElement, this.placeholder, directChild.nextSibling); } } } getPlaceholderIndex() { if (this.placeholder === null) { return undefined; } const element = this.elementRef.nativeElement; return Array.prototype.indexOf.call(element.children, this.placeholder); } cleanupDragoverState() { this.renderer.removeClass(this.elementRef.nativeElement, this.dndDragoverClass); this.removePlaceholderFromDOM(); } } DndDropzoneDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: DndDropzoneDirective, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); DndDropzoneDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.13", type: DndDropzoneDirective, selector: "[dndDropZone]", inputs: { dndDropzone: "dndDropzone", dndEffectAllowed: "dndEffectAllowed", dndAllowExternal: "dndAllowExternal", dndHorizontal: "dndHorizontal", dndDragoverClass: "dndDragoverClass", dndDropzoneDisabledClass: "dndDropzoneDisabledClass", dndDisableIf: "dndDisableIf", dndDisableDropIf: "dndDisableDropIf" }, outputs: { dndDragover: "dndDragover", dndDrop: "dndDrop" }, host: { listeners: { "drop": "onDrop($event)" } }, queries: [{ propertyName: "dndPlaceholderRef", first: true, predicate: DndPlaceholderRefDirective, descendants: true }], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.13", ngImport: i0, type: DndDropzoneDirective, decorators: [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: "[dndDropZone]" }] }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { dndDropzone: [{ type: Input }], dndEffectAllowed: [{ type: Input }], dndAllowExternal: [{ type: Input }], dndHorizontal: [{ type: Input }], dndDragoverClass: [{ type: Input }], dndDropzoneDisabledClass: [{ type: Input }], dndDragover: [{ type: Output }], dndDrop: [{ type: Output }], dndPlaceholderRef: [{ type: ContentChild, args: [DndPlaceholderRefDirective] }], dndDisableIf: [{ type: Input }], dndDisableDropIf: [{ type: Input }], onDrop: [{ type: HostListener, args: ["drop", ["$event"]] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5kLWRyb3B6b25lLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2wtNTJhYnAtbmctZm9ybS1nZW5lcmF0b3Ivc3JjL25neC1kcmFnLWRyb3AvZG5kLWRyb3B6b25lLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsWUFBWSxFQUNaLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUdMLHFCQUFxQixFQUNyQixXQUFXLEVBQ1gsc0NBQXNDLEVBQ3ZDLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBZ0J2RixNQUFNLE9BQU8sMEJBQTBCO0lBRXJDLFlBQTZCLFVBQXFCO1FBQXJCLGVBQVUsR0FBVixVQUFVLENBQVc7SUFDbEQsQ0FBQzs7d0hBSFUsMEJBQTBCOzRHQUExQiwwQkFBMEI7NEZBQTFCLDBCQUEwQjtrQkFKdEMsU0FBUzttQkFBRTtvQkFDViw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSxxQkFBcUI7aUJBQ2hDOztBQVdELE1BQU0sT0FBTyxvQkFBb0I7SUF5RC9CLFlBQXFCLE1BQWEsRUFDYixVQUFxQixFQUNyQixRQUFrQjtRQUZsQixXQUFNLEdBQU4sTUFBTSxDQUFPO1FBQ2IsZUFBVSxHQUFWLFVBQVUsQ0FBVztRQUNyQixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBbER2QyxxQkFBZ0IsR0FBVyxLQUFLLENBQUM7UUFHakMsa0JBQWEsR0FBVyxLQUFLLENBQUM7UUFHOUIscUJBQWdCLEdBQVUsYUFBYSxDQUFDO1FBR3hDLDZCQUF3QixHQUFHLHFCQUFxQixDQUFDO1FBR3hDLGdCQUFXLEdBQTJCLElBQUksWUFBWSxFQUFhLENBQUM7UUFH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a0hBM1ZVLG9CQUFvQjtzR0FBcEIsb0JBQW9CLHdnQkEwQmhCLDBCQUEwQjs0RkExQjlCLG9CQUFvQjtrQkFKaEMsU0FBUzttQkFBRTtvQkFDViw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSxlQUFlO2lCQUMxQjs4SUFJQyxXQUFXO3NCQURWLEtBQUs7Z0JBSU4sZ0JBQWdCO3NCQURmLEtBQUs7Z0JBSU4sZ0JBQWdCO3NCQURmLEtBQUs7Z0JBSU4sYUFBYTtzQkFEWixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLHdCQUF3QjtzQkFEdkIsS0FBSztnQkFJRyxXQUFXO3NCQURuQixNQUFNO2dCQUlFLE9BQU87c0JBRGYsTUFBTTtnQkFJVSxpQkFBaUI7c0JBRGpDLFlBQVk7dUJBQUUsMEJBQTBCO2dCQVlyQyxZQUFZO3NCQURmLEtBQUs7Z0JBZ0JGLGdCQUFnQjtzQkFEbkIsS0FBSztnQkFvR04sTUFBTTtzQkFETCxZQUFZO3VCQUFFLE1BQU0sRUFBRSxDQUFFLFFBQVEsQ0FBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgRG5kRXZlbnQsXG4gIERyYWdEcm9wRGF0YSxcbiAgZ2V0RGlyZWN0Q2hpbGRFbGVtZW50LFxuICBnZXREcm9wRGF0YSxcbiAgc2hvdWxkUG9zaXRpb25QbGFjZWhvbGRlckJlZm9yZUVsZW1lbnRcbn0gZnJvbSBcIi4vZG5kLXV0aWxzXCI7XG5pbXBvcnQgeyBnZXREbmRUeXBlLCBnZXREcm9wRWZmZWN0LCBpc0V4dGVybmFsRHJhZywgc2V0RHJvcEVmZmVjdCB9IGZyb20gXCIuL2RuZC1zdGF0ZVwiO1xuaW1wb3J0IHsgRHJvcEVmZmVjdCwgRWZmZWN0QWxsb3dlZCB9IGZyb20gXCIuL2RuZC10eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIERuZERyb3BFdmVudCB7XG4gIGV2ZW50OkRyYWdFdmVudDtcbiAgZHJvcEVmZmVjdDpEcm9wRWZmZWN0O1xuICBpc0V4dGVybmFsOmJvb2xlYW47XG4gIGRhdGE/OmFueTtcbiAgaW5kZXg/Om51bWJlcjtcbiAgdHlwZT86YW55O1xufVxuXG5ARGlyZWN0aXZlKCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gIHNlbGVjdG9yOiBcIltkbmRQbGFjZWhvbGRlclJlZl1cIlxufSApXG5leHBvcnQgY2xhc3MgRG5kUGxhY2Vob2xkZXJSZWZEaXJlY3RpdmUge1xuXG4gIGNvbnN0cnVjdG9yKCBwdWJsaWMgcmVhZG9ubHkgZWxlbWVudFJlZjpFbGVtZW50UmVmICkge1xuICB9XG59XG5cbkBEaXJlY3RpdmUoIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcbiAgc2VsZWN0b3I6IFwiW2RuZERyb3Bab25lXVwiXG59IClcbmV4cG9ydCBjbGFzcyBEbmREcm9wem9uZURpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cbiAgQElucHV0KClcbiAgZG5kRHJvcHpvbmU/OnN0cmluZ1tdO1xuXG4gIEBJbnB1dCgpXG4gIGRuZEVmZmVjdEFsbG93ZWQ6RWZmZWN0QWxsb3dlZDtcblxuICBASW5wdXQoKVxuICBkbmRBbGxvd0V4dGVybmFsOmJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBkbmRIb3Jpem9udGFsOmJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBkbmREcmFnb3ZlckNsYXNzOnN0cmluZyA9IFwiZG5kRHJhZ292ZXJcIjtcblxuICBASW5wdXQoKVxuICBkbmREcm9wem9uZURpc2FibGVkQ2xhc3MgPSBcImRuZERyb3B6b25lRGlzYWJsZWRcIjtcblxuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgZG5kRHJhZ292ZXI6RXZlbnRFbWl0dGVyPERyYWdFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPERyYWdFdmVudD4oKTtcblxuICBAT3V0cHV0KClcbiAgcmVhZG9ubHkgZG5kRHJvcDpFdmVudEVtaXR0ZXI8RG5kRHJvcEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RG5kRHJvcEV2ZW50PigpO1xuXG4gIEBDb250ZW50Q2hpbGQoIERuZFBsYWNlaG9sZGVyUmVmRGlyZWN0aXZlIClcbiAgcHJpdmF0ZSByZWFkb25seSBkbmRQbGFjZWhvbGRlclJlZj86RG5kUGxhY2Vob2xkZXJSZWZEaXJlY3RpdmU7XG5cbiAgcHJpdmF0ZSBwbGFjZWhvbGRlcjpFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBkaXNhYmxlZDpib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBkcmFnRW50ZXJFdmVudEhhbmRsZXI6KCBldmVudDpEcmFnRXZlbnQgKSA9PiB2b2lkID0gKCBldmVudDpEcmFnRXZlbnQgKSA9PiB0aGlzLm9uRHJhZ0VudGVyKCBldmVudCApO1xuICBwcml2YXRlIHJlYWRvbmx5IGRyYWdPdmVyRXZlbnRIYW5kbGVyOiggZXZlbnQ6RHJhZ0V2ZW50ICkgPT4gdm9pZCA9ICggZXZlbnQ6RHJhZ0V2ZW50ICkgPT4gdGhpcy5vbkRyYWdPdmVyKCBldmVudCApO1xuICBwcml2YXRlIHJlYWRvbmx5IGRyYWdMZWF2ZUV2ZW50SGFuZGxlcjooIGV2ZW50OkRyYWdFdmVudCApID0+IHZvaWQgPSAoIGV2ZW50OkRyYWdFdmVudCApID0+IHRoaXMub25EcmFnTGVhdmUoIGV2ZW50ICk7XG5cbiAgQElucHV0KClcbiAgc2V0IGRuZERpc2FibGVJZiggdmFsdWU6Ym9vbGVhbiApIHtcblxuICAgIHRoaXMuZGlzYWJsZWQgPSAhIXZhbHVlO1xuXG4gICAgaWYoIHRoaXMuZGlzYWJsZWQgKSB7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLmRuZERyb3B6b25lRGlzYWJsZWRDbGFzcyApO1xuICAgIH1cbiAgICBlbHNlIHtcblxuICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuZG5kRHJvcHpvbmVEaXNhYmxlZENsYXNzICk7XG4gICAgfVxuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGRuZERpc2FibGVEcm9wSWYoIHZhbHVlOmJvb2xlYW4gKSB7XG4gICAgdGhpcy5kbmREaXNhYmxlSWYgPSB2YWx1ZTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCBwcml2YXRlIG5nWm9uZTpOZ1pvbmUsXG4gICAgICAgICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6RWxlbWVudFJlZixcbiAgICAgICAgICAgICAgIHByaXZhdGUgcmVuZGVyZXI6UmVuZGVyZXIyICkge1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6dm9pZCB7XG5cbiAgICB0aGlzLnBsYWNlaG9sZGVyID0gdGhpcy50cnlHZXRQbGFjZWhvbGRlcigpO1xuXG4gICAgdGhpcy5yZW1vdmVQbGFjZWhvbGRlckZyb21ET00oKTtcblxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCAoKSA9PiB7XG4gICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCBcImRyYWdlbnRlclwiLCB0aGlzLmRyYWdFbnRlckV2ZW50SGFuZGxlciApO1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJkcmFnb3ZlclwiLCB0aGlzLmRyYWdPdmVyRXZlbnRIYW5kbGVyICk7XG4gICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCBcImRyYWdsZWF2ZVwiLCB0aGlzLmRyYWdMZWF2ZUV2ZW50SGFuZGxlciApO1xuICAgIH0gKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6dm9pZCB7XG4gICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJkcmFnZW50ZXJcIiwgdGhpcy5kcmFnRW50ZXJFdmVudEhhbmRsZXIgKTtcbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcImRyYWdvdmVyXCIsIHRoaXMuZHJhZ092ZXJFdmVudEhhbmRsZXIgKTtcbiAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcImRyYWdsZWF2ZVwiLCB0aGlzLmRyYWdMZWF2ZUV2ZW50SGFuZGxlciApO1xuICB9XG5cbiAgb25EcmFnRW50ZXIoIGV2ZW50OkRuZEV2ZW50ICkge1xuXG4gICAgLy8gY2hlY2sgaWYgYW5vdGhlciBkcm9wem9uZSBpcyBhY3RpdmF0ZWRcbiAgICBpZiggZXZlbnQuX2RuZERyb3B6b25lQWN0aXZlID09PSB0cnVlICkge1xuXG4gICAgICB0aGlzLmNsZWFudXBEcmFnb3ZlclN0YXRlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc2V0IGFzIGFjdGl2ZSBpZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgaW5zaWRlIHRoaXMgZHJvcHpvbmVcbiAgICBpZiggdHlwZW9mIGV2ZW50Ll9kbmREcm9wem9uZUFjdGl2ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblxuICAgICAgY29uc3QgbmV3VGFyZ2V0ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCggZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSApO1xuXG4gICAgICBpZiggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoIG5ld1RhcmdldCApICkge1xuXG4gICAgICAgIGV2ZW50Ll9kbmREcm9wem9uZUFjdGl2ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgdGhpcyBkcmFnIGV2ZW50IGlzIGFsbG93ZWQgdG8gZHJvcCBvbiB0aGlzIGRyb3B6b25lXG4gICAgY29uc3QgdHlwZSA9IGdldERuZFR5cGUoIGV2ZW50ICk7XG4gICAgaWYoIHRoaXMuaXNEcm9wQWxsb3dlZCggdHlwZSApID09PSBmYWxzZSApIHtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFsbG93IHRoZSBkcmFnZW50ZXJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgb25EcmFnT3ZlciggZXZlbnQ6RHJhZ0V2ZW50ICkge1xuICAgIC8vIFdpdGggbmVzdGVkIGRyb3B6b25lcywgd2Ugd2FudCB0byBpZ25vcmUgdGhpcyBldmVudCBpZiBhIGNoaWxkIGRyb3B6b25lXG4gICAgLy8gaGFzIGFscmVhZHkgaGFuZGxlZCBhIGRyYWdvdmVyLiAgSGlzdG9yaWNhbGx5LCBldmVudC5zdG9wUHJvcGFnYXRpb24oKSB3YXNcbiAgICAvLyB1c2VkIHRvIHByZXZlbnQgdGhpcyBidWJibGluZywgYnV0IHRoYXQgcHJldmVudHMgYW55IGRyYWdvdmVycyBvdXRzaWRlIHRoZVxuICAgIC8vIG5neC1kcmFnLWRyb3AgY29tcG9uZW50LCBhbmQgc3RvcHMgb3RoZXIgdXNlIGNhc2VzIHN1Y2ggYXMgc2Nyb2xsaW5nIG9uIGRyYWcuXG4gICAgLy8gSW5zdGVhZCwgd2UgY2FuIGNoZWNrIGlmIHRoZSBldmVudCB3YXMgYWxyZWFkeSBwcmV2ZW50ZWQgYnkgYSBjaGlsZCBhbmQgYmFpbCBlYXJseS5cbiAgICBpZiggZXZlbnQuZGVmYXVsdFByZXZlbnRlZCApIHtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIHRoaXMgZHJhZyBldmVudCBpcyBhbGxvd2VkIHRvIGRyb3Agb24gdGhpcyBkcm9wem9uZVxuICAgIGNvbnN0IHR5cGUgPSBnZXREbmRUeXBlKCBldmVudCApO1xuICAgIGlmKCB0aGlzLmlzRHJvcEFsbG93ZWQoIHR5cGUgKSA9PT0gZmFsc2UgKSB7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNoZWNrQW5kVXBkYXRlUGxhY2Vob2xkZXJQb3NpdGlvbiggZXZlbnQgKTtcblxuICAgIGNvbnN0IGRyb3BFZmZlY3QgPSBnZXREcm9wRWZmZWN0KCBldmVudCwgdGhpcy5kbmRFZmZlY3RBbGxvd2VkICk7XG5cbiAgICBpZiggZHJvcEVmZmVjdCA9PT0gXCJub25lXCIgKSB7XG5cbiAgICAgIHRoaXMuY2xlYW51cERyYWdvdmVyU3RhdGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhbGxvdyB0aGUgZHJhZ292ZXJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy8gc2V0IHRoZSBkcm9wIGVmZmVjdFxuICAgIHNldERyb3BFZmZlY3QoIGV2ZW50LCBkcm9wRWZmZWN0ICk7XG5cbiAgICB0aGlzLmRuZERyYWdvdmVyLmVtaXQoIGV2ZW50ICk7XG5cbiAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKCB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5kbmREcmFnb3ZlckNsYXNzICk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCBcImRyb3BcIiwgWyBcIiRldmVudFwiIF0gKVxuICBvbkRyb3AoIGV2ZW50OkRyYWdFdmVudCApIHtcblxuICAgIHRyeSB7XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoaXMgZHJhZyBldmVudCBpcyBhbGxvd2VkIHRvIGRyb3Agb24gdGhpcyBkcm9wem9uZVxuICAgICAgY29uc3QgdHlwZSA9IGdldERuZFR5cGUoIGV2ZW50ICk7XG4gICAgICBpZiggdGhpcy5pc0Ryb3BBbGxvd2VkKCB0eXBlICkgPT09IGZhbHNlICkge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YTpEcmFnRHJvcERhdGEgPSBnZXREcm9wRGF0YSggZXZlbnQsIGlzRXh0ZXJuYWxEcmFnKCkgKTtcblxuICAgICAgaWYoIHRoaXMuaXNEcm9wQWxsb3dlZCggZGF0YS50eXBlICkgPT09IGZhbHNlICkge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gc2lnbmFsIGN1c3RvbSBkcm9wIGhhbmRsaW5nXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICBjb25zdCBkcm9wRWZmZWN0ID0gZ2V0RHJvcEVmZmVjdCggZXZlbnQgKTtcblxuICAgICAgc2V0RHJvcEVmZmVjdCggZXZlbnQsIGRyb3BFZmZlY3QgKTtcblxuICAgICAgaWYoIGRyb3BFZmZlY3QgPT09IFwibm9uZVwiICkge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZHJvcEluZGV4ID0gdGhpcy5nZXRQbGFjZWhvbGRlckluZGV4KCk7XG5cbiAgICAgIC8vIGlmIGZvciB3aGF0ZXZlciByZWFzb24gdGhlIHBsYWNlaG9sZGVyIGlzIG5vdCBwcmVzZW50IGluIHRoZSBET00gYnV0IGl0IHNob3VsZCBiZSB0aGVyZVxuICAgICAgLy8gd2UgZG9uJ3QgYWxsb3cvZW1pdCB0aGUgZHJvcCBldmVudCBzaW5jZSBpdCBicmVha3MgdGhlIGNvbnRyYWN0XG4gICAgICAvLyBzZWVtcyB0byBvbmx5IGhhcHBlbiBpZiBkcmFnIGFuZCBkcm9wIGlzIGV4ZWN1dGVkIGZhc3RlciB0aGFuIHRoZSBET00gdXBkYXRlc1xuICAgICAgaWYoIGRyb3BJbmRleCA9PT0gLTEgKSB7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmRuZERyb3AuZW1pdCgge1xuICAgICAgICBldmVudDogZXZlbnQsXG4gICAgICAgIGRyb3BFZmZlY3Q6IGRyb3BFZmZlY3QsXG4gICAgICAgIGlzRXh0ZXJuYWw6IGlzRXh0ZXJuYWxEcmFnKCksXG4gICAgICAgIGRhdGE6IGRhdGEuZGF0YSxcbiAgICAgICAgaW5kZXg6IGRyb3BJbmRleCxcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgIH0gKTtcblxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICB9XG4gICAgZmluYWxseSB7XG5cbiAgICAgIHRoaXMuY2xlYW51cERyYWdvdmVyU3RhdGUoKTtcbiAgICB9XG4gIH1cblxuICBvbkRyYWdMZWF2ZSggZXZlbnQ6RG5kRXZlbnQgKSB7XG5cbiAgICAvLyBjaGVjayBpZiBzdGlsbCBpbnNpZGUgdGhpcyBkcm9wem9uZSBhbmQgbm90IHlldCBoYW5kbGVkIGJ5IGFub3RoZXIgZHJvcHpvbmVcbiAgICBpZiggdHlwZW9mIGV2ZW50Ll9kbmREcm9wem9uZUFjdGl2ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblxuICAgICAgY29uc3QgbmV3VGFyZ2V0ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCggZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSApO1xuXG4gICAgICBpZiggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoIG5ld1RhcmdldCApICkge1xuXG4gICAgICAgIGV2ZW50Ll9kbmREcm9wem9uZUFjdGl2ZSA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmNsZWFudXBEcmFnb3ZlclN0YXRlKCk7XG5cbiAgICAvLyBjbGVhbnVwIGRyb3AgZWZmZWN0IHdoZW4gbGVhdmluZyBkcm9wem9uZVxuICAgIHNldERyb3BFZmZlY3QoIGV2ZW50LCBcIm5vbmVcIiApO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0Ryb3BBbGxvd2VkKCB0eXBlPzpzdHJpbmcgKTpib29sZWFuIHtcblxuICAgIC8vIGRyb3B6b25lIGlzIGRpc2FibGVkIC0+IGRlbnkgaXRcbiAgICBpZiggdGhpcy5kaXNhYmxlZCA9PT0gdHJ1ZSApIHtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGlmIGRyYWcgZGlkIG5vdCBzdGFydCBmcm9tIG91ciBkaXJlY3RpdmVcbiAgICAvLyBhbmQgZXh0ZXJuYWwgZHJhZyBzb3VyY2VzIGFyZSBub3QgYWxsb3dlZCAtPiBkZW55IGl0XG4gICAgaWYoIGlzRXh0ZXJuYWxEcmFnKCkgPT09IHRydWVcbiAgICAgICYmIHRoaXMuZG5kQWxsb3dFeHRlcm5hbCA9PT0gZmFsc2UgKSB7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBubyBmaWx0ZXJpbmcgYnkgdHlwZXMgLT4gYWxsb3cgaXRcbiAgICBpZiggIXRoaXMuZG5kRHJvcHpvbmUgKSB7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIG5vIHR5cGUgc2V0IC0+IGFsbG93IGl0XG4gICAgaWYoICF0eXBlICkge1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiggQXJyYXkuaXNBcnJheSggdGhpcy5kbmREcm9wem9uZSApID09PSBmYWxzZSApIHtcblxuICAgICAgdGhyb3cgbmV3IEVycm9yKCBcImRuZERyb3B6b25lOiBib3VuZCB2YWx1ZSB0byBbZG5kRHJvcHpvbmVdIG11c3QgYmUgYW4gYXJyYXkhXCIgKTtcbiAgICB9XG5cbiAgICAvLyBpZiBkcm9wem9uZSBjb250YWlucyB0eXBlIC0+IGFsbG93IGl0XG4gICAgcmV0dXJuIHRoaXMuZG5kRHJvcHpvbmUuaW5kZXhPZiggdHlwZSApICE9PSAtMTtcbiAgfVxuXG4gIHByaXZhdGUgdHJ5R2V0UGxhY2Vob2xkZXIoKTpFbGVtZW50IHwgbnVsbCB7XG5cbiAgICBpZiggdHlwZW9mIHRoaXMuZG5kUGxhY2Vob2xkZXJSZWYgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cbiAgICAgIHJldHVybiB0aGlzLmRuZFBsYWNlaG9sZGVyUmVmLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBFbGVtZW50O1xuICAgIH1cblxuICAgIC8vIFRPRE8gbmFzdHkgd29ya2Fyb3VuZCBuZWVkZWQgYmVjYXVzZSBpZiBuZy1jb250YWluZXIgLyB0ZW1wbGF0ZSBpcyB1c2VkIEBDb250ZW50Q2hpbGQoKSBvciBESSB3aWxsIGZhaWwgYmVjYXVzZVxuICAgIC8vIG9mIHdyb25nIGNvbnRleHQgc2VlIGFuZ3VsYXIgYnVnIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzEzNTE3XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoIFwiW2RuZFBsYWNlaG9sZGVyUmVmXVwiICk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVBsYWNlaG9sZGVyRnJvbURPTSgpIHtcblxuICAgIGlmKCB0aGlzLnBsYWNlaG9sZGVyICE9PSBudWxsXG4gICAgICAmJiB0aGlzLnBsYWNlaG9sZGVyLnBhcmVudE5vZGUgIT09IG51bGwgKSB7XG4gICAgICB0aGlzLnBsYWNlaG9sZGVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRoaXMucGxhY2Vob2xkZXIgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kVXBkYXRlUGxhY2Vob2xkZXJQb3NpdGlvbiggZXZlbnQ6RHJhZ0V2ZW50ICk6dm9pZCB7XG5cbiAgICBpZiggdGhpcy5wbGFjZWhvbGRlciA9PT0gbnVsbCApIHtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgcGxhY2Vob2xkZXIgaXMgaW4gdGhlIERPTVxuICAgIGlmKCB0aGlzLnBsYWNlaG9sZGVyLnBhcmVudE5vZGUgIT09IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ICkge1xuXG4gICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKCB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5wbGFjZWhvbGRlciApO1xuICAgIH1cblxuICAgIC8vIHVwZGF0ZSB0aGUgcG9zaXRpb24gaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIGNoaWxkIGVsZW1lbnQgb2YgdGhlIGRyb3B6b25lXG4gICAgY29uc3QgZGlyZWN0Q2hpbGQgPSBnZXREaXJlY3RDaGlsZEVsZW1lbnQoIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBldmVudC50YXJnZXQgYXMgRWxlbWVudCApO1xuXG4gICAgLy8gZWFybHkgZXhpdCBpZiBubyBkaXJlY3QgY2hpbGQgb3IgZGlyZWN0IGNoaWxkIGlzIHBsYWNlaG9sZGVyXG4gICAgaWYoIGRpcmVjdENoaWxkID09PSBudWxsXG4gICAgICB8fCBkaXJlY3RDaGlsZCA9PT0gdGhpcy5wbGFjZWhvbGRlciApIHtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc2l0aW9uUGxhY2Vob2xkZXJCZWZvcmVEaXJlY3RDaGlsZCA9IHNob3VsZFBvc2l0aW9uUGxhY2Vob2xkZXJCZWZvcmVFbGVtZW50KCBldmVudCwgZGlyZWN0Q2hpbGQsIHRoaXMuZG5kSG9yaXpvbnRhbCApO1xuXG4gICAgaWYoIHBvc2l0aW9uUGxhY2Vob2xkZXJCZWZvcmVEaXJlY3RDaGlsZCApIHtcblxuICAgICAgLy8gZG8gaW5zZXJ0IGJlZm9yZSBvbmx5IGlmIG5lY2Vzc2FyeVxuICAgICAgaWYoIGRpcmVjdENoaWxkLnByZXZpb3VzU2libGluZyAhPT0gdGhpcy5wbGFjZWhvbGRlciApIHtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLmluc2VydEJlZm9yZSggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMucGxhY2Vob2xkZXIsIGRpcmVjdENoaWxkICk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuXG4gICAgICAvLyBkbyBpbnNlcnQgYWZ0ZXIgb25seSBpZiBuZWNlc3NhcnlcbiAgICAgIGlmKCBkaXJlY3RDaGlsZC5uZXh0U2libGluZyAhPT0gdGhpcy5wbGFjZWhvbGRlciApIHtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLmluc2VydEJlZm9yZSggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMucGxhY2Vob2xkZXIsIGRpcmVjdENoaWxkLm5leHRTaWJsaW5nICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRQbGFjZWhvbGRlckluZGV4KCk6bnVtYmVyIHwgdW5kZWZpbmVkIHtcblxuICAgIGlmKCB0aGlzLnBsYWNlaG9sZGVyID09PSBudWxsICkge1xuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcblxuICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKCBlbGVtZW50LmNoaWxkcmVuLCB0aGlzLnBsYWNlaG9sZGVyICk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFudXBEcmFnb3ZlclN0YXRlKCkge1xuXG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyggdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuZG5kRHJhZ292ZXJDbGFzcyApO1xuXG4gICAgdGhpcy5yZW1vdmVQbGFjZWhvbGRlckZyb21ET00oKTtcbiAgfVxufVxuIl19