ngx-editor
Version:
Rich Text Editor for angular using ProseMirror
161 lines • 20.3 kB
JavaScript
import { Component, HostBinding, HostListener, Input } from '@angular/core';
import { NodeSelection } from 'prosemirror-state';
import { asyncScheduler, fromEvent } from 'rxjs';
import { throttleTime } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "../../../pipes/sanitize/sanitize-html.pipe";
import * as i2 from "../bubble/bubble.component";
import * as i3 from "@angular/common";
export class FloatingMenuComponent {
constructor(el, sanitizeHTML) {
this.el = el;
this.sanitizeHTML = sanitizeHTML;
this.posLeft = 0;
this.posTop = 0;
this.showMenu = false;
this.dragging = false;
this.execulableItems = [];
this.activeItems = [];
}
get display() {
return {
visibility: this.showMenu ? 'visible' : 'hidden',
opacity: this.showMenu ? '1' : '0',
top: this.posTop + 'px',
left: this.posLeft + 'px',
};
}
get view() {
return this.editor.view;
}
onMouseDown(e) {
const target = e.target;
if (this.el.nativeElement.contains(target) && target.nodeName !== 'INPUT') {
e.preventDefault();
return;
}
this.dragging = true;
}
onKeyDown(e) {
const target = e.target;
if (target.nodeName === 'INPUT') {
return;
}
this.dragging = true;
this.hide();
}
onMouseUp(e) {
const target = e.target;
if (this.el.nativeElement.contains(target) || target.nodeName === 'INPUT') {
e.preventDefault();
return;
}
this.dragging = false;
this.useUpdate();
}
onKeyUp(e) {
const target = e.target;
if (target.nodeName === 'INPUT') {
return;
}
this.dragging = false;
this.useUpdate();
}
useUpdate() {
if (!this.view) {
return;
}
this.update(this.view);
}
hide() {
this.showMenu = false;
}
show() {
this.showMenu = true;
}
calculateBubblePosition(view) {
const { state: { selection } } = view;
const { from } = selection;
// the floating bubble itself
const bubbleEl = this.el.nativeElement;
const bubble = bubbleEl.getBoundingClientRect();
// The box in which the tooltip is positioned, to use as base
const box = bubbleEl.parentElement.getBoundingClientRect();
const start = view.coordsAtPos(from);
let left = start.left - box.left;
const overflowsRight = (box.right < (start.left + bubble.width) ||
bubble.right > box.right);
if (overflowsRight) {
left = box.width - bubble.width;
}
if (left < 0) {
left = 0;
}
const bubbleHeight = bubble.height + parseInt(getComputedStyle(bubbleEl).marginBottom, 10);
const top = (start.top - box.top) - bubbleHeight;
return {
left,
top
};
}
update(view) {
const { state } = view;
const { selection } = state;
const { empty } = selection;
if (selection instanceof NodeSelection) {
if (selection.node.type.name === 'image') {
this.hide();
return;
}
}
const hasFocus = this.view.hasFocus();
if (!hasFocus || empty || this.dragging) {
this.hide();
return;
}
const { top, left } = this.calculateBubblePosition(this.view);
this.posLeft = left;
this.posTop = top;
this.show();
}
ngOnInit() {
if (!this.editor) {
throw new Error('NgxEditor: Required editor instance');
}
this.updateSubscription = this.editor.update
.subscribe((view) => {
this.update(view);
});
this.resizeSubscription = fromEvent(window, 'resize').pipe(throttleTime(500, asyncScheduler, { leading: true, trailing: true })).subscribe(() => {
this.useUpdate();
});
}
ngOnDestroy() {
this.updateSubscription.unsubscribe();
this.resizeSubscription.unsubscribe();
}
}
FloatingMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: FloatingMenuComponent, deps: [{ token: i0.ElementRef }, { token: i1.SanitizeHtmlPipe }], target: i0.ɵɵFactoryTarget.Component });
FloatingMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.0", type: FloatingMenuComponent, selector: "ngx-editor-floating-menu", inputs: { editor: "editor" }, host: { listeners: { "document:mousedown": "onMouseDown($event)", "document:keydown": "onKeyDown($event)", "document:mouseup": "onMouseUp($event)", "document:keyup": "onKeyUp($event)" }, properties: { "style": "this.display" } }, ngImport: i0, template: "<div #ref>\n <ng-content></ng-content>\n</div>\n<ng-container *ngIf=\"ref.children.length === 0\">\n <ngx-bubble [editor]=\"editor\"></ngx-bubble>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{position:absolute;z-index:20;margin-bottom:5px;visibility:hidden;opacity:0}\n"], components: [{ type: i2.BubbleComponent, selector: "ngx-bubble", inputs: ["editor"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: FloatingMenuComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-editor-floating-menu', template: "<div #ref>\n <ng-content></ng-content>\n</div>\n<ng-container *ngIf=\"ref.children.length === 0\">\n <ngx-bubble [editor]=\"editor\"></ngx-bubble>\n</ng-container>\n", styles: ["*,*:before,*:after{box-sizing:border-box}:host{position:absolute;z-index:20;margin-bottom:5px;visibility:hidden;opacity:0}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.SanitizeHtmlPipe }]; }, propDecorators: { display: [{
type: HostBinding,
args: ['style']
}], editor: [{
type: Input
}], onMouseDown: [{
type: HostListener,
args: ['document:mousedown', ['$event']]
}], onKeyDown: [{
type: HostListener,
args: ['document:keydown', ['$event']]
}], onMouseUp: [{
type: HostListener,
args: ['document:mouseup', ['$event']]
}], onKeyUp: [{
type: HostListener,
args: ['document:keyup', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvYXRpbmctbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L2Zsb2F0aW5nLW1lbnUvZmxvYXRpbmctbWVudS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L2Zsb2F0aW5nLW1lbnUvZmxvYXRpbmctbWVudS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUFjLFdBQVcsRUFDbEMsWUFBWSxFQUFFLEtBQUssRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWxELE9BQU8sRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7O0FBaUI5QyxNQUFNLE9BQU8scUJBQXFCO0lBRWhDLFlBQW1CLEVBQTJCLEVBQVUsWUFBOEI7UUFBbkUsT0FBRSxHQUFGLEVBQUUsQ0FBeUI7UUFBVSxpQkFBWSxHQUFaLFlBQVksQ0FBa0I7UUFpQjlFLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUVqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRXpCLG9CQUFlLEdBQWMsRUFBRSxDQUFDO1FBQ2hDLGdCQUFXLEdBQWMsRUFBRSxDQUFDO0lBeEI4RCxDQUFDO0lBRTNGLElBQTBCLE9BQU87UUFDL0IsT0FBTztZQUNMLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVE7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c0dBQXJCLHFCQUFxQixvVUN6QmxDLHlLQU1BOzJGRG1CYSxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsMEJBQTBCO2dJQVFWLE9BQU87c0JBQWhDLFdBQVc7dUJBQUMsT0FBTztnQkFhWCxNQUFNO3NCQUFkLEtBQUs7Z0JBVzBDLFdBQVc7c0JBQTFELFlBQVk7dUJBQUMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBV0EsU0FBUztzQkFBdEQsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFXRSxTQUFTO3NCQUF0RCxZQUFZO3VCQUFDLGtCQUFrQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVlBLE9BQU87c0JBQWxELFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ3Byb3NlbWlycm9yLXZpZXcnO1xuaW1wb3J0IHsgYXN5bmNTY2hlZHVsZXIsIGZyb21FdmVudCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCBFZGl0b3IgZnJvbSAnLi4vLi4vLi4vRWRpdG9yJztcbmltcG9ydCBJY29uIGZyb20gJy4uLy4uLy4uL2ljb25zJztcbmltcG9ydCB7IFRCSXRlbXMgfSBmcm9tICcuLi8uLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBTYW5pdGl6ZUh0bWxQaXBlIH0gZnJvbSAnLi4vLi4vLi4vcGlwZXMvc2FuaXRpemUvc2FuaXRpemUtaHRtbC5waXBlJztcblxuaW50ZXJmYWNlIEJ1YmJsZVBvc2l0aW9uIHtcbiAgdG9wOiBudW1iZXI7XG4gIGxlZnQ6IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWVkaXRvci1mbG9hdGluZy1tZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Zsb2F0aW5nLW1lbnUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9mbG9hdGluZy1tZW51LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRmxvYXRpbmdNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBlbDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sIHByaXZhdGUgc2FuaXRpemVIVE1MOiBTYW5pdGl6ZUh0bWxQaXBlKSB7IH1cblxuICBASG9zdEJpbmRpbmcoJ3N0eWxlJykgZ2V0IGRpc3BsYXkoKTogUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZpc2liaWxpdHk6IHRoaXMuc2hvd01lbnUgPyAndmlzaWJsZScgOiAnaGlkZGVuJyxcbiAgICAgIG9wYWNpdHk6IHRoaXMuc2hvd01lbnUgPyAnMScgOiAnMCcsXG4gICAgICB0b3A6IHRoaXMucG9zVG9wICsgJ3B4JyxcbiAgICAgIGxlZnQ6IHRoaXMucG9zTGVmdCArICdweCcsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHZpZXcoKTogRWRpdG9yVmlldyB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yLnZpZXc7XG4gIH1cblxuICBASW5wdXQoKSBlZGl0b3I6IEVkaXRvcjtcblxuICBwcml2YXRlIHBvc0xlZnQgPSAwO1xuICBwcml2YXRlIHBvc1RvcCA9IDA7XG4gIHByaXZhdGUgc2hvd01lbnUgPSBmYWxzZTtcbiAgcHJpdmF0ZSB1cGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBkcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHJlc2l6ZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBleGVjdWxhYmxlSXRlbXM6IFRCSXRlbXNbXSA9IFtdO1xuICBhY3RpdmVJdGVtczogVEJJdGVtc1tdID0gW107XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vkb3duJywgWyckZXZlbnQnXSkgb25Nb3VzZURvd24oZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSAmJiB0YXJnZXQubm9kZU5hbWUgIT09ICdJTlBVVCcpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24nLCBbJyRldmVudCddKSBvbktleURvd24oZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0YXJnZXQubm9kZU5hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmhpZGUoKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnLCBbJyRldmVudCddKSBvbk1vdXNlVXAoZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIE5vZGVcblxuICAgIGlmICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSB8fCB0YXJnZXQubm9kZU5hbWUgPT09ICdJTlBVVCcpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnVzZVVwZGF0ZSgpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5dXAnLCBbJyRldmVudCddKSBvbktleVVwKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBOb2RlXG5cbiAgICBpZiAodGFyZ2V0Lm5vZGVOYW1lID09PSAnSU5QVVQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMudXNlVXBkYXRlKCk7XG4gIH1cblxuICBwcml2YXRlIHVzZVVwZGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudmlldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlKHRoaXMudmlldyk7XG4gIH1cblxuICBwcml2YXRlIGhpZGUoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93TWVudSA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG93KCk6IHZvaWQge1xuICAgIHRoaXMuc2hvd01lbnUgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVCdWJibGVQb3NpdGlvbih2aWV3OiBFZGl0b3JWaWV3KTogQnViYmxlUG9zaXRpb24ge1xuICAgIGNvbnN0IHsgc3RhdGU6IHsgc2VsZWN0aW9uIH0gfSA9IHZpZXc7XG4gICAgY29uc3QgeyBmcm9tIH0gPSBzZWxlY3Rpb247XG5cbiAgICAvLyB0aGUgZmxvYXRpbmcgYnViYmxlIGl0c2VsZlxuICAgIGNvbnN0IGJ1YmJsZUVsID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGJ1YmJsZSA9IGJ1YmJsZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgLy8gVGhlIGJveCBpbiB3aGljaCB0aGUgdG9vbHRpcCBpcyBwb3NpdGlvbmVkLCB0byB1c2UgYXMgYmFzZVxuICAgIGNvbnN0IGJveCA9IGJ1YmJsZUVsLnBhcmVudEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCBzdGFydCA9IHZpZXcuY29vcmRzQXRQb3MoZnJvbSk7XG5cbiAgICBsZXQgbGVmdCA9IHN0YXJ0LmxlZnQgLSBib3gubGVmdDtcblxuICAgIGNvbnN0IG92ZXJmbG93c1JpZ2h0ID0gKFxuICAgICAgYm94LnJpZ2h0IDwgKHN0YXJ0LmxlZnQgKyBidWJibGUud2lkdGgpIHx8XG4gICAgICBidWJibGUucmlnaHQgPiBib3gucmlnaHRcbiAgICApO1xuXG4gICAgaWYgKG92ZXJmbG93c1JpZ2h0KSB7XG4gICAgICBsZWZ0ID0gYm94LndpZHRoIC0gYnViYmxlLndpZHRoO1xuICAgIH1cblxuICAgIGlmIChsZWZ0IDwgMCkge1xuICAgICAgbGVmdCA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgYnViYmxlSGVpZ2h0ID0gYnViYmxlLmhlaWdodCArIHBhcnNlSW50KGdldENvbXB1dGVkU3R5bGUoYnViYmxlRWwpLm1hcmdpbkJvdHRvbSwgMTApO1xuICAgIGNvbnN0IHRvcCA9IChzdGFydC50b3AgLSBib3gudG9wKSAtIGJ1YmJsZUhlaWdodDtcblxuICAgIHJldHVybiB7XG4gICAgICBsZWZ0LFxuICAgICAgdG9wXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlKHZpZXc6IEVkaXRvclZpZXcpOiB2b2lkIHtcbiAgICBjb25zdCB7IHN0YXRlIH0gPSB2aWV3O1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZTtcbiAgICBjb25zdCB7IGVtcHR5IH0gPSBzZWxlY3Rpb247XG5cbiAgICBpZiAoc2VsZWN0aW9uIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbikge1xuICAgICAgaWYgKHNlbGVjdGlvbi5ub2RlLnR5cGUubmFtZSA9PT0gJ2ltYWdlJykge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGhhc0ZvY3VzID0gdGhpcy52aWV3Lmhhc0ZvY3VzKCk7XG5cbiAgICBpZiAoIWhhc0ZvY3VzIHx8IGVtcHR5IHx8IHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdG9wLCBsZWZ0IH0gPSB0aGlzLmNhbGN1bGF0ZUJ1YmJsZVBvc2l0aW9uKHRoaXMudmlldyk7XG5cbiAgICB0aGlzLnBvc0xlZnQgPSBsZWZ0O1xuICAgIHRoaXMucG9zVG9wID0gdG9wO1xuXG4gICAgdGhpcy5zaG93KCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05neEVkaXRvcjogUmVxdWlyZWQgZWRpdG9yIGluc3RhbmNlJyk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVTdWJzY3JpcHRpb24gPSB0aGlzLmVkaXRvci51cGRhdGVcbiAgICAgIC5zdWJzY3JpYmUoKHZpZXcpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGUodmlldyk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVzaXplU3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpLnBpcGUoXG4gICAgICB0aHJvdHRsZVRpbWUoNTAwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogdHJ1ZSB9KVxuICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMudXNlVXBkYXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMucmVzaXplU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxkaXYgI3JlZj5cbiAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9kaXY+XG48bmctY29udGFpbmVyICpuZ0lmPVwicmVmLmNoaWxkcmVuLmxlbmd0aCA9PT0gMFwiPlxuICA8bmd4LWJ1YmJsZSBbZWRpdG9yXT1cImVkaXRvclwiPjwvbmd4LWJ1YmJsZT5cbjwvbmctY29udGFpbmVyPlxuIl19