@progress/telerik-angular-native-report-viewer
Version:
Progress® Telerik® Native Report Viewer for Angular
113 lines • 34.4 kB
JavaScript
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { xIcon } from '@progress/kendo-svg-icons';
import * as i0 from "@angular/core";
import * as i1 from "../reporting-angular-viewer.service";
import * as i2 from "@angular/common";
import * as i3 from "@progress/kendo-angular-dialog";
import * as i4 from "@progress/kendo-angular-buttons";
import * as i5 from "@progress/kendo-angular-conversational-ui";
import * as i6 from "@progress/kendo-angular-utils";
export class AiPromptComponent {
constructor(renderer, el, service) {
this.renderer = renderer;
this.el = el;
this.service = service;
this.windowTop = 80;
this.xIcon = xIcon;
this.activeView = 0;
this.showConsent = false;
this.consentAcceptBtnText = "";
this.consentRejectBtnText = "";
this.idCounter = 0;
}
async ngOnInit() {
const reportElemWidth = this.service.reportWidth;
this.windowWidth = 500;
this.windowLeft = reportElemWidth - (this.windowWidth + 20);
this.aiInfo = await this.service.controller.createAIThread();
if (this.aiInfo.predefinedPrompts && this.aiInfo.predefinedPrompts.length > 0) {
this.predefinedPrompts = this.aiInfo.predefinedPrompts;
}
if (this.aiInfo.requireConsent) {
this.showConsent = this.aiInfo.requireConsent && this.service.controller.loadFromSessionStorage("trvAiConsent") !== "true";
this.consentAcceptBtnText = this.getLocaleMessage('ConsentAccept');
;
this.consentRejectBtnText = this.getLocaleMessage('ConsentReject');
;
}
this.onActiveViewChange(this.activeView);
}
toggle(isOpened) {
this.service.isAiPromptWindowOpen = isOpened;
}
onWidthChange(width) {
this.service.windowWidth = width;
}
onHeightChange(height) {
this.service.windowHeight = height;
}
onPromptRequest(event) {
const generateButtonEl = this.el.nativeElement.querySelector('.k-prompt-footer .k-actions .k-button');
generateButtonEl && this.renderer.addClass(generateButtonEl, 'k-disabled');
this.service.controller.getAIResponse(event.prompt)
.then(response => {
this.promptOutputs.unshift(this.createPromptOutputFromResponse(response, event));
generateButtonEl && this.renderer.removeClass(generateButtonEl, 'k-disabled');
this.activeView = 1;
}).catch(error => {
this.promptOutputs.unshift(this.createPromptOutputFromResponse(error?._responseJSON, event));
generateButtonEl && this.renderer.removeClass(generateButtonEl, 'k-disabled');
this.activeView = 1;
});
}
onActiveViewChange(viewId) {
// The Kendo event is triggered before the new AI prompt view is rendered so the textarea doesn't exist
// Wrap the call in setTimeout in order to have the textarea element present before setting the disabled class
if (viewId === 0 && !this.aiInfo.allowCustomPrompts) {
setTimeout(() => {
let promptTextAreaPlaceholder = this.getLocaleMessage('TextAreaPlaceholder');
if (!(this.predefinedPrompts && this.predefinedPrompts.length > 0)) {
const aiPromptGenerateButton = this.el.nativeElement.querySelector('.k-prompt-footer .k-actions');
aiPromptGenerateButton && this.renderer.addClass(aiPromptGenerateButton, 'k-disabled');
promptTextAreaPlaceholder = this.getLocaleMessage('NoPredefinedAndCustomPromptsPlaceholder');
}
else {
promptTextAreaPlaceholder = this.getLocaleMessage('NoCustomPromptsPlaceholder');
}
const textAreaEl = this.el.nativeElement.querySelector('.k-textarea textarea');
if (textAreaEl) {
this.renderer.addClass(textAreaEl, 'k-disabled');
this.renderer.setAttribute(textAreaEl, 'placeholder', promptTextAreaPlaceholder);
}
}, 50);
}
}
consentCancel() {
this.toggle(false);
}
async consentAccept() {
this.showConsent = false;
this.service.controller.saveToSessionStorage('trvAiConsent', 'true');
this.onActiveViewChange(this.activeView);
}
getLocaleMessage(message) {
return this.service.options.messages[`ReportViewer_AiPromptDialog${message}`];
}
createPromptOutputFromResponse(response, promptData) {
return {
id: this.idCounter++,
output: response,
prompt: promptData.prompt,
isRetry: promptData.isRetry,
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiPromptComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.ReportingAngularViewerService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AiPromptComponent, selector: "aiprompt-window", inputs: { promptOutputs: "promptOutputs" }, ngImport: i0, template: "<kendo-window kendoDragTargetContainer\n dragHandle=\".k-prompt-header\"\n dragTargetFilter=\".trv-ai-prompt-dialog\"\n cursorStyle=\"default\"\n title=\"Before you start with AI\"\n (close)=\"toggle(false)\"\n class=\"trv-ai-prompt-dialog\"\n [(top)]=\"windowTop\"\n [(left)]=\"windowLeft\"\n [width]=\"windowWidth\"\n (widthChange)=\"onWidthChange($event)\"\n (heightChange)=\"onHeightChange($event)\">\n <div class=\"trv-window k-window-content\">\n <div *ngIf=\"showConsent\" class=\"trv-ai-consent-dialog\">\n <div class=\"trv-ai-consent-content\" [innerHTML]=\"aiInfo.consentMessage\"></div>\n <div class=\"trv-ai-consent-actions k-actions k-actions-end\">\n <button class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary\"\n (click)=\"consentAccept()\"\n ariaLabel=\"AI Prompt Consent\"\n title=\"Consent\">{{ consentAcceptBtnText }}</button>\n <button class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-base\"\n (click)=\"consentCancel()\"\n ariaLabel=\"AI Prompt Cancel\"\n title=\"Cancel\">{{ consentRejectBtnText }}</button>\n </div>\n </div>\n\n <kendo-aiprompt *ngIf=\"!showConsent\"\n [(activeView)]=\"activeView\"\n [promptOutputs]=\"promptOutputs\"\n [promptSuggestions]=\"predefinedPrompts\"\n (promptRequest)=\"onPromptRequest($event)\"\n (activeViewChange)=\"onActiveViewChange($event)\">\n <kendo-aiprompt-prompt-view></kendo-aiprompt-prompt-view>\n <kendo-aiprompt-messages promptPlaceholder=\"Enter your prompt\"></kendo-aiprompt-messages>\n <kendo-aiprompt-output-view></kendo-aiprompt-output-view>\n <ng-template kendoAIPromptToolbarActionsTemplate>\n <span class=\"k-spacer\"></span>\n <button kendoButton\n [svgIcon]=\"xIcon\"\n fillMode=\"flat\"\n rounded=\"full\"\n (click)=\"toggle(false)\">\n </button>\n </ng-template>\n </kendo-aiprompt>\n </div>\n</kendo-window>", styles: [".trv-ai-prompt-dialog{min-width:400px;min-height:50px;max-height:800px}.trv-ai-prompt-dialog .k-window-content{padding:0}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-window-titlebar{display:none}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-header{border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface-alt, #ffffff)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-header button.k-button{color:inherit}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content{min-height:106px;border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface, #fafafa)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view{padding:20px;display:flex;flex-direction:column;flex:1 1 auto;gap:var(--kendo-spacing-4, 1rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view button.k-button{color:inherit}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view textarea.k-input-inner{height:100px}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view .k-card-body p{white-space:pre-line}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-footer button{border-radius:var(--kendo-border-radius-md, .25rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-suggestion{border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-app-surface, #ffffff);box-shadow:var(--kendo-elevation-1, 0 2px 3px rgba(0, 0, 0, .04), 0 4px 16px rgba(0, 0, 0, .12));border-width:1px;border-style:solid;border-radius:var(--kendo-border-radius-md, .25rem);padding-block:var(--kendo-spacing-2, .5rem);padding-inline:var(--kendo-spacing-2, .5rem);cursor:pointer}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-expander{display:flex;flex-direction:column;flex:1;align-items:flex-start;gap:var(--kendo-spacing-2, .5rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-expander .k-prompt-expander-content{display:flex;flex-flow:column;flex:0 0 auto;gap:var(--kendo-spacing-2, .5rem);align-self:stretch}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar{min-height:23px;background-color:unset}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar [kendowindowminimizeaction],.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar [kendowindowmaximizeaction]{display:none!important}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .trv-ai-consent-content{min-height:102px;padding:16px;border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface, #fafafa)}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .trv-ai-consent-actions{justify-content:flex-start}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.WindowComponent, selector: "kendo-window", inputs: ["autoFocusedElement", "title", "draggable", "resizable", "themeColor", "keepContent", "state", "minWidth", "minHeight", "width", "height", "top", "left"], outputs: ["dragStart", "dragEnd", "resizeStart", "resizeEnd", "close", "widthChange", "heightChange", "topChange", "leftChange", "stateChange"], exportAs: ["kendoWindow"] }, { kind: "component", type: i4.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i5.AIPromptComponent, selector: "kendo-aiprompt", inputs: ["activeView", "promptCommands", "promptSuggestions", "promptOutputs", "showOutputRating"], outputs: ["activeViewChange", "promptRequest", "commandExecute", "outputCopy", "outputRatingChange"], exportAs: ["kendoAIPrompt"] }, { kind: "component", type: i5.PromptViewComponent, selector: "kendo-aiprompt-prompt-view" }, { kind: "component", type: i5.OutputViewComponent, selector: "kendo-aiprompt-output-view" }, { kind: "component", type: i5.AIPromptCustomMessagesComponent, selector: "kendo-aiprompt-messages" }, { kind: "directive", type: i5.AIPromptToolbarActionsDirective, selector: "[kendoAIPromptToolbarActionsTemplate]" }, { kind: "directive", type: i6.DragTargetContainerDirective, selector: "[kendoDragTargetContainer]", inputs: ["hint", "dragTargetFilter", "dragHandle", "dragDelay", "threshold", "dragTargetId", "dragData", "dragDisabled", "mode"], outputs: ["onDragReady", "onPress", "onDragStart", "onDrag", "onRelease", "onDragEnd"], exportAs: ["kendoDragTargetContainer"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiPromptComponent, decorators: [{
type: Component,
args: [{ selector: 'aiprompt-window', encapsulation: ViewEncapsulation.None, template: "<kendo-window kendoDragTargetContainer\n dragHandle=\".k-prompt-header\"\n dragTargetFilter=\".trv-ai-prompt-dialog\"\n cursorStyle=\"default\"\n title=\"Before you start with AI\"\n (close)=\"toggle(false)\"\n class=\"trv-ai-prompt-dialog\"\n [(top)]=\"windowTop\"\n [(left)]=\"windowLeft\"\n [width]=\"windowWidth\"\n (widthChange)=\"onWidthChange($event)\"\n (heightChange)=\"onHeightChange($event)\">\n <div class=\"trv-window k-window-content\">\n <div *ngIf=\"showConsent\" class=\"trv-ai-consent-dialog\">\n <div class=\"trv-ai-consent-content\" [innerHTML]=\"aiInfo.consentMessage\"></div>\n <div class=\"trv-ai-consent-actions k-actions k-actions-end\">\n <button class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary\"\n (click)=\"consentAccept()\"\n ariaLabel=\"AI Prompt Consent\"\n title=\"Consent\">{{ consentAcceptBtnText }}</button>\n <button class=\"k-button k-button-md k-rounded-md k-button-solid k-button-solid-base\"\n (click)=\"consentCancel()\"\n ariaLabel=\"AI Prompt Cancel\"\n title=\"Cancel\">{{ consentRejectBtnText }}</button>\n </div>\n </div>\n\n <kendo-aiprompt *ngIf=\"!showConsent\"\n [(activeView)]=\"activeView\"\n [promptOutputs]=\"promptOutputs\"\n [promptSuggestions]=\"predefinedPrompts\"\n (promptRequest)=\"onPromptRequest($event)\"\n (activeViewChange)=\"onActiveViewChange($event)\">\n <kendo-aiprompt-prompt-view></kendo-aiprompt-prompt-view>\n <kendo-aiprompt-messages promptPlaceholder=\"Enter your prompt\"></kendo-aiprompt-messages>\n <kendo-aiprompt-output-view></kendo-aiprompt-output-view>\n <ng-template kendoAIPromptToolbarActionsTemplate>\n <span class=\"k-spacer\"></span>\n <button kendoButton\n [svgIcon]=\"xIcon\"\n fillMode=\"flat\"\n rounded=\"full\"\n (click)=\"toggle(false)\">\n </button>\n </ng-template>\n </kendo-aiprompt>\n </div>\n</kendo-window>", styles: [".trv-ai-prompt-dialog{min-width:400px;min-height:50px;max-height:800px}.trv-ai-prompt-dialog .k-window-content{padding:0}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-window-titlebar{display:none}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-header{border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface-alt, #ffffff)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-header button.k-button{color:inherit}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content{min-height:106px;border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface, #fafafa)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view{padding:20px;display:flex;flex-direction:column;flex:1 1 auto;gap:var(--kendo-spacing-4, 1rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view button.k-button{color:inherit}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view textarea.k-input-inner{height:100px}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-content .k-prompt-view .k-card-body p{white-space:pre-line}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-footer button{border-radius:var(--kendo-border-radius-md, .25rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-suggestion{border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-app-surface, #ffffff);box-shadow:var(--kendo-elevation-1, 0 2px 3px rgba(0, 0, 0, .04), 0 4px 16px rgba(0, 0, 0, .12));border-width:1px;border-style:solid;border-radius:var(--kendo-border-radius-md, .25rem);padding-block:var(--kendo-spacing-2, .5rem);padding-inline:var(--kendo-spacing-2, .5rem);cursor:pointer}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-expander{display:flex;flex-direction:column;flex:1;align-items:flex-start;gap:var(--kendo-spacing-2, .5rem)}.trv-ai-prompt-dialog:not(:has(.trv-ai-consent-dialog)) .k-prompt-expander .k-prompt-expander-content{display:flex;flex-flow:column;flex:0 0 auto;gap:var(--kendo-spacing-2, .5rem);align-self:stretch}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar{min-height:23px;background-color:unset}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar [kendowindowminimizeaction],.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .k-window-titlebar [kendowindowmaximizeaction]{display:none!important}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .trv-ai-consent-content{min-height:102px;padding:16px;border-color:var(--kendo-color-border, rgba(0, 0, 0, .08));color:var(--kendo-color-on-app-surface, #424242);background-color:var(--kendo-color-surface, #fafafa)}.trv-ai-prompt-dialog:has(.trv-ai-consent-dialog) .trv-ai-consent-actions{justify-content:flex-start}\n"] }]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.ReportingAngularViewerService }]; }, propDecorators: { promptOutputs: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWlwcm9tcHQtd2luZG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvYWlwcm9tcHQvYWlwcm9tcHQtd2luZG93LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3NyYy9saWIvYWlwcm9tcHQvYWlwcm9tcHQtd2luZG93LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFxQixpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUduRyxPQUFPLEVBQVcsS0FBSyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7O0FBUzNELE1BQU0sT0FBTyxpQkFBaUI7SUFnQjFCLFlBQTJCLFFBQW1CLEVBQVUsRUFBYyxFQUFVLE9BQXNDO1FBQTNGLGFBQVEsR0FBUixRQUFRLENBQVc7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQVUsWUFBTyxHQUFQLE9BQU8sQ0FBK0I7UUFiL0csY0FBUyxHQUFXLEVBQUUsQ0FBQztRQUl2QixVQUFLLEdBQVksS0FBSyxDQUFDO1FBQ3ZCLGVBQVUsR0FBVyxDQUFDLENBQUM7UUFDdkIsZ0JBQVcsR0FBWSxLQUFLLENBQUM7UUFHN0IseUJBQW9CLEdBQVcsRUFBRSxDQUFDO1FBQ2xDLHlCQUFvQixHQUFXLEVBQUUsQ0FBQztRQUNqQyxjQUFTLEdBQUcsQ0FBQyxDQUFDO0lBRW1HLENBQUM7SUFFMUgsS0FBSyxDQUFDLFFBQVE7UUFDVixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztRQUNqRCxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLGVBQWUsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFNUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxP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LGdCQUFnQixDQUFDLE9BQWU7UUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsOEJBQThCLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDbEYsQ0FBQztJQUVPLDhCQUE4QixDQUFDLFFBQWdCLEVBQUUsVUFBOEI7UUFDbkYsT0FBTztZQUNILEVBQUUsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ3BCLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTTtZQUN6QixPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87U0FDOUIsQ0FBQztJQUNOLENBQUM7K0dBNUdRLGlCQUFpQjttR0FBakIsaUJBQWlCLG1HQ1o5QiwwdUVBK0NlOzs0RkRuQ0YsaUJBQWlCO2tCQU43QixTQUFTOytCQUNJLGlCQUFpQixpQkFHWixpQkFBaUIsQ0FBQyxJQUFJO3FLQUc1QixhQUFhO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25Jbml0LCBSZW5kZXJlcjIsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBvcnRpbmdBbmd1bGFyVmlld2VyU2VydmljZSB9IGZyb20gJy4uL3JlcG9ydGluZy1hbmd1bGFyLXZpZXdlci5zZXJ2aWNlJztcbmltcG9ydCB7IFByb21wdE91dHB1dCwgUHJvbXB0UmVxdWVzdEV2ZW50IH0gZnJvbSBcIkBwcm9ncmVzcy9rZW5kby1hbmd1bGFyLWNvbnZlcnNhdGlvbmFsLXVpXCI7XG5pbXBvcnQgeyBTVkdJY29uLCB4SWNvbiB9IGZyb20gJ0Bwcm9ncmVzcy9rZW5kby1zdmctaWNvbnMnO1xuaW1wb3J0IHsgQWlJbmZvIH0gZnJvbSAnQHByb2dyZXNzL3RlbGVyaWstY29tbW9uLXJlcG9ydC12aWV3ZXIvZGlzdC9UeXBlcy9BaUluZm9UeXBlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhaXByb21wdC13aW5kb3cnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9haXByb21wdC13aW5kb3cuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2FpcHJvbXB0LXdpbmRvdy5jb21wb25lbnQuc2NzcyddLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgQWlQcm9tcHRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIEBJbnB1dCgpIHByb21wdE91dHB1dHM6IEFycmF5PFByb21wdE91dHB1dD47XG5cbiAgICBwdWJsaWMgd2luZG93VG9wOiBudW1iZXIgPSA4MDtcbiAgICBwdWJsaWMgd2luZG93TGVmdCE6IG51bWJlcjtcbiAgICBwdWJsaWMgd2luZG93V2lkdGghOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgeEljb246IFNWR0ljb24gPSB4SWNvbjtcbiAgICBwdWJsaWMgYWN0aXZlVmlldzogbnVtYmVyID0gMDtcbiAgICBwdWJsaWMgc2hvd0NvbnNlbnQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgYWlJbmZvOiBBaUluZm87XG4gICAgcHVibGljIHByZWRlZmluZWRQcm9tcHRzOiBzdHJpbmdbXTtcbiAgICBwdWJsaWMgY29uc2VudEFjY2VwdEJ0blRleHQ6IHN0cmluZyA9IFwiXCI7XG4gICAgcHVibGljIGNvbnNlbnRSZWplY3RCdG5UZXh0OiBzdHJpbmcgPSBcIlwiO1xuICAgIHByaXZhdGUgaWRDb3VudGVyID0gMDtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsIHByaXZhdGUgc2VydmljZTogUmVwb3J0aW5nQW5ndWxhclZpZXdlclNlcnZpY2UpIHt9XG4gICAgXG4gICAgYXN5bmMgbmdPbkluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHJlcG9ydEVsZW1XaWR0aCA9IHRoaXMuc2VydmljZS5yZXBvcnRXaWR0aDtcbiAgICAgICAgdGhpcy53aW5kb3dXaWR0aCA9IDUwMDtcbiAgICAgICAgdGhpcy53aW5kb3dMZWZ0ID0gcmVwb3J0RWxlbVdpZHRoIC0gKHRoaXMud2luZG93V2lkdGggKyAyMCk7XG5cbiAgICAgICAgdGhpcy5haUluZm8gPSBhd2FpdCB0aGlzLnNlcnZpY2UuY29udHJvbGxlci5jcmVhdGVBSVRocmVhZCgpO1xuICAgICAgICBpZiAodGhpcy5haUluZm8ucHJlZGVmaW5lZFByb21wdHMgJiYgdGhpcy5haUluZm8ucHJlZGVmaW5lZFByb21wdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5wcmVkZWZpbmVkUHJvbXB0cyA9IHRoaXMuYWlJbmZvLnByZWRlZmluZWRQcm9tcHRzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYWlJbmZvLnJlcXVpcmVDb25zZW50KSB7XG4gICAgICAgICAgICB0aGlzLnNob3dDb25zZW50ID0gdGhpcy5haUluZm8ucmVxdWlyZUNvbnNlbnQgJiYgdGhpcy5zZXJ2aWNlLmNvbnRyb2xsZXIubG9hZEZyb21TZXNzaW9uU3RvcmFnZShcInRydkFpQ29uc2VudFwiKSAhPT0gXCJ0cnVlXCI7XG4gICAgICAgICAgICB0aGlzLmNvbnNlbnRBY2NlcHRCdG5UZXh0ID0gdGhpcy5nZXRMb2NhbGVNZXNzYWdlKCdDb25zZW50QWNjZXB0Jyk7O1xuICAgICAgICAgICAgdGhpcy5jb25zZW50UmVqZWN0QnRuVGV4dCA9IHRoaXMuZ2V0TG9jYWxlTWVzc2FnZSgnQ29uc2VudFJlamVjdCcpOztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub25BY3RpdmVWaWV3Q2hhbmdlKHRoaXMuYWN0aXZlVmlldyk7XG4gICAgfVxuXG4gICAgcHVibGljIHRvZ2dsZShpc09wZW5lZDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLnNlcnZpY2UuaXNBaVByb21wdFdpbmRvd09wZW4gPSBpc09wZW5lZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25XaWR0aENoYW5nZSh3aWR0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VydmljZS53aW5kb3dXaWR0aCA9IHdpZHRoO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkhlaWdodENoYW5nZShoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnNlcnZpY2Uud2luZG93SGVpZ2h0ID0gaGVpZ2h0O1xuICAgIH1cblxuICAgIHB1YmxpYyBvblByb21wdFJlcXVlc3QoZXZlbnQ6IFByb21wdFJlcXVlc3RFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBnZW5lcmF0ZUJ1dHRvbkVsID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5rLXByb21wdC1mb290ZXIgLmstYWN0aW9ucyAuay1idXR0b24nKTtcbiAgICAgICAgZ2VuZXJhdGVCdXR0b25FbCAmJiB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKGdlbmVyYXRlQnV0dG9uRWwsICdrLWRpc2FibGVkJyk7XG4gICAgICAgIHRoaXMuc2VydmljZS5jb250cm9sbGVyLmdldEFJUmVzcG9uc2UoZXZlbnQucHJvbXB0KVxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvbXB0T3V0cHV0cy51bnNoaWZ0KHRoaXMuY3JlYXRlUHJvbXB0T3V0cHV0RnJvbVJlc3BvbnNlKHJlc3BvbnNlLCBldmVudCkpO1xuICAgICAgICAgICAgICAgIGdlbmVyYXRlQnV0dG9uRWwgJiYgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhnZW5lcmF0ZUJ1dHRvbkVsLCAnay1kaXNhYmxlZCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlVmlldyA9IDE7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9tcHRPdXRwdXRzLnVuc2hpZnQodGhpcy5jcmVhdGVQcm9tcHRPdXRwdXRGcm9tUmVzcG9uc2UoZXJyb3I/Ll9yZXNwb25zZUpTT04sIGV2ZW50KSk7XG4gICAgICAgICAgICAgICAgZ2VuZXJhdGVCdXR0b25FbCAmJiB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKGdlbmVyYXRlQnV0dG9uRWwsICdrLWRpc2FibGVkJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVWaWV3ID0gMTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkFjdGl2ZVZpZXdDaGFuZ2Uodmlld0lkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgLy8gVGhlIEtlbmRvIGV2ZW50IGlzIHRyaWdnZXJlZCBiZWZvcmUgdGhlIG5ldyBBSSBwcm9tcHQgdmlldyBpcyByZW5kZXJlZCBzbyB0aGUgdGV4dGFyZWEgZG9lc24ndCBleGlzdFxuICAgICAgICAvLyBXcmFwIHRoZSBjYWxsIGluIHNldFRpbWVvdXQgaW4gb3JkZXIgdG8gaGF2ZSB0aGUgdGV4dGFyZWEgZWxlbWVudCBwcmVzZW50IGJlZm9yZSBzZXR0aW5nIHRoZSBkaXNhYmxlZCBjbGFzc1xuICAgICAgICBpZiAodmlld0lkID09PSAwICYmICF0aGlzLmFpSW5mby5hbGxvd0N1c3RvbVByb21wdHMpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBwcm9tcHRUZXh0QXJlYVBsYWNlaG9sZGVyID0gdGhpcy5nZXRMb2NhbGVNZXNzYWdlKCdUZXh0QXJlYVBsYWNlaG9sZGVyJyk7XG4gICAgICAgICAgICAgICAgaWYgKCEodGhpcy5wcmVkZWZpbmVkUHJvbXB0cyAmJiB0aGlzLnByZWRlZmluZWRQcm9tcHRzLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFpUHJvbXB0R2VuZXJhdGVCdXR0b24gPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmstcHJvbXB0LWZvb3RlciAuay1hY3Rpb25zJyk7XG4gICAgICAgICAgICAgICAgICAgIGFpUHJvbXB0R2VuZXJhdGVCdXR0b24gJiYgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhhaVByb21wdEdlbmVyYXRlQnV0dG9uLCAnay1kaXNhYmxlZCcpO1xuICAgICAgICAgICAgICAgICAgICBwcm9tcHRUZXh0QXJlYVBsYWNlaG9sZGVyID0gdGhpcy5nZXRMb2NhbGVNZXNzYWdlKCdOb1ByZWRlZmluZWRBbmRDdXN0b21Qcm9tcHRzUGxhY2Vob2xkZXInKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwcm9tcHRUZXh0QXJlYVBsYWNlaG9sZGVyID0gdGhpcy5nZXRMb2NhbGVNZXNzYWdlKCdOb0N1c3RvbVByb21wdHNQbGFjZWhvbGRlcicpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHRleHRBcmVhRWwgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmstdGV4dGFyZWEgdGV4dGFyZWEnKTtcbiAgICAgICAgICAgICAgICBpZiAodGV4dEFyZWFFbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRleHRBcmVhRWwsICdrLWRpc2FibGVkJylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGV4dEFyZWFFbCwgJ3BsYWNlaG9sZGVyJywgcHJvbXB0VGV4dEFyZWFQbGFjZWhvbGRlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgNTApXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29uc2VudENhbmNlbCgpIHtcbiAgICAgICAgdGhpcy50b2dnbGUoZmFsc2UpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjb25zZW50QWNjZXB0KCkge1xuICAgICAgICB0aGlzLnNob3dDb25zZW50ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VydmljZS5jb250cm9sbGVyLnNhdmVUb1Nlc3Npb25TdG9yYWdlKCd0cnZBaUNvbnNlbnQnLCAndHJ1ZScpO1xuICAgICAgICB0aGlzLm9uQWN0aXZlVmlld0NoYW5nZSh0aGlzLmFjdGl2ZVZpZXcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRMb2NhbGVNZXNzYWdlKG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlcnZpY2Uub3B0aW9ucy5tZXNzYWdlc1tgUmVwb3J0Vmlld2VyX0FpUHJvbXB0RGlhbG9nJHttZXNzYWdlfWBdO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlUHJvbXB0T3V0cHV0RnJvbVJlc3BvbnNlKHJlc3BvbnNlOiBzdHJpbmcsIHByb21wdERhdGE6IFByb21wdFJlcXVlc3RFdmVudCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6IHRoaXMuaWRDb3VudGVyKyssXG4gICAgICAgICAgICBvdXRwdXQ6IHJlc3BvbnNlLFxuICAgICAgICAgICAgcHJvbXB0OiBwcm9tcHREYXRhLnByb21wdCxcbiAgICAgICAgICAgIGlzUmV0cnk6IHByb21wdERhdGEuaXNSZXRyeSxcbiAgICAgICAgfTsgXG4gICAgfVxufVxuIiwiPGtlbmRvLXdpbmRvdyBrZW5kb0RyYWdUYXJnZXRDb250YWluZXJcbiAgICBkcmFnSGFuZGxlPVwiLmstcHJvbXB0LWhlYWRlclwiXG4gICAgZHJhZ1RhcmdldEZpbHRlcj1cIi50cnYtYWktcHJvbXB0LWRpYWxvZ1wiXG4gICAgY3Vyc29yU3R5bGU9XCJkZWZhdWx0XCJcbiAgICB0aXRsZT1cIkJlZm9yZSB5b3Ugc3RhcnQgd2l0aCBBSVwiXG4gICAgKGNsb3NlKT1cInRvZ2dsZShmYWxzZSlcIlxuICAgIGNsYXNzPVwidHJ2LWFpLXByb21wdC1kaWFsb2dcIlxuICAgIFsodG9wKV09XCJ3aW5kb3dUb3BcIlxuICAgIFsobGVmdCldPVwid2luZG93TGVmdFwiXG4gICAgW3dpZHRoXT1cIndpbmRvd1dpZHRoXCJcbiAgICAod2lkdGhDaGFuZ2UpPVwib25XaWR0aENoYW5nZSgkZXZlbnQpXCJcbiAgICAoaGVpZ2h0Q2hhbmdlKT1cIm9uSGVpZ2h0Q2hhbmdlKCRldmVudClcIj5cbiAgICA8ZGl2IGNsYXNzPVwidHJ2LXdpbmRvdyBrLXdpbmRvdy1jb250ZW50XCI+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJzaG93Q29uc2VudFwiIGNsYXNzPVwidHJ2LWFpLWNvbnNlbnQtZGlhbG9nXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJ2LWFpLWNvbnNlbnQtY29udGVudFwiIFtpbm5lckhUTUxdPVwiYWlJbmZvLmNvbnNlbnRNZXNzYWdlXCI+PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJ2LWFpLWNvbnNlbnQtYWN0aW9ucyBrLWFjdGlvbnMgay1hY3Rpb25zLWVuZFwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJrLWJ1dHRvbiBrLWJ1dHRvbi1tZCBrLXJvdW5kZWQtbWQgay1idXR0b24tc29saWQgay1idXR0b24tc29saWQtcHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb25zZW50QWNjZXB0KClcIlxuICAgICAgICAgICAgICAgICAgICBhcmlhTGFiZWw9XCJBSSBQcm9tcHQgQ29uc2VudFwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ29uc2VudFwiPnt7IGNvbnNlbnRBY2NlcHRCdG5UZXh0IH19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImstYnV0dG9uIGstYnV0dG9uLW1kIGstcm91bmRlZC1tZCBrLWJ1dHRvbi1zb2xpZCBrLWJ1dHRvbi1zb2xpZC1iYXNlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnNlbnRDYW5jZWwoKVwiXG4gICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbD1cIkFJIFByb21wdCBDYW5jZWxcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNhbmNlbFwiPnt7IGNvbnNlbnRSZWplY3RCdG5UZXh0IH19PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGtlbmRvLWFpcHJvbXB0ICpuZ0lmPVwiIXNob3dDb25zZW50XCJcbiAgICAgICAgWyhhY3RpdmVWaWV3KV09XCJhY3RpdmVWaWV3XCJcbiAgICAgICAgW3Byb21wdE91dHB1dHNdPVwicHJvbXB0T3V0cHV0c1wiXG4gICAgICAgIFtwcm9tcHRTdWdnZXN0aW9uc109XCJwcmVkZWZpbmVkUHJvbXB0c1wiXG4gICAgICAgIChwcm9tcHRSZXF1ZXN0KT1cIm9uUHJvbXB0UmVxdWVzdCgkZXZlbnQpXCJcbiAgICAgICAgKGFjdGl2ZVZpZXdDaGFuZ2UpPVwib25BY3RpdmVWaWV3Q2hhbmdlKCRldmVudClcIj5cbiAgICAgICAgICAgIDxrZW5kby1haXByb21wdC1wcm9tcHQtdmlldz48L2tlbmRvLWFpcHJvbXB0LXByb21wdC12aWV3PlxuICAgICAgICAgICAgPGtlbmRvLWFpcHJvbXB0LW1lc3NhZ2VzIHByb21wdFBsYWNlaG9sZGVyPVwiRW50ZXIgeW91ciBwcm9tcHRcIj48L2tlbmRvLWFpcHJvbXB0LW1lc3NhZ2VzPlxuICAgICAgICAgICAgPGtlbmRvLWFpcHJvbXB0LW91dHB1dC12aWV3Pjwva2VuZG8tYWlwcm9tcHQtb3V0cHV0LXZpZXc+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUga2VuZG9BSVByb21wdFRvb2xiYXJBY3Rpb25zVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJrLXNwYWNlclwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGtlbmRvQnV0dG9uXG4gICAgICAgICAgICAgICAgW3N2Z0ljb25dPVwieEljb25cIlxuICAgICAgICAgICAgICAgIGZpbGxNb2RlPVwiZmxhdFwiXG4gICAgICAgICAgICAgICAgcm91bmRlZD1cImZ1bGxcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGUoZmFsc2UpXCI+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2tlbmRvLWFpcHJvbXB0PlxuICAgIDwvZGl2PlxuPC9rZW5kby13aW5kb3c+Il19