UNPKG

@eternalheart/ngx-file-preview

Version:

A powerful Angular file preview component library supporting multiple file formats including images, videos, PDFs, Office documents, text files and more.

172 lines (170 loc) 26.3 kB
import { ChangeDetectionStrategy, Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PreviewIconComponent } from '../../components'; import { BasePreviewComponent } from "../base-preview/base-preview.component"; import { I18nPipe } from "../../i18n/i18n.pipe"; import { TooltipDirective } from "../../directives"; import * as i0 from "@angular/core"; export class TextPreviewComponent extends BasePreviewComponent { constructor() { super(...arguments); this.content = ''; this.isWrapped = false; this.scale = 1; this.SCALE_STEP = 0.1; this.MAX_SCALE = 3; this.MIN_SCALE = 0.1; this.DEFAULT_SCALE = 1; } ngOnInit() { this.setupKeyboardListeners(); } ngOnDestroy() { this.removeKeyboardListeners(); } ngOnChanges(changes) { if (changes['file']) { this.loadFile('text'); } } async handleFileContent(content) { if (content.error) { this.content = '文件加载失败:' + content.error; } else { this.content = content.text || '文件内容为空'; } } setupKeyboardListeners() { this.keydownListener = (e) => { if ((e.ctrlKey || e.metaKey) && e.key === '0') { e.preventDefault(); this.resetZoom(); } }; document.addEventListener('keydown', this.keydownListener); } removeKeyboardListeners() { if (this.keydownListener) { document.removeEventListener('keydown', this.keydownListener); } } handleWheel(event) { if (event.ctrlKey || event.metaKey) { event.preventDefault(); const delta = event.deltaY || event.detail || 0; if (delta < 0) { this.zoomIn(); } else { this.zoomOut(); } } } zoomIn() { if (this.scale < this.MAX_SCALE) { this.scale = Math.min(this.MAX_SCALE, this.scale + this.SCALE_STEP); this.applyZoom(); } } zoomOut() { if (this.scale > this.MIN_SCALE) { this.scale = Math.max(this.MIN_SCALE, this.scale - this.SCALE_STEP); this.applyZoom(); } } resetZoom() { this.scale = this.DEFAULT_SCALE; this.applyZoom(); } applyZoom() { this.cdr.markForCheck(); } toggleWrap() { this.isWrapped = !this.isWrapped; this.cdr.markForCheck(); } toggleFullscreen() { if (!document.fullscreenElement) { document.documentElement.requestFullscreen(); } else { document.exitFullscreen(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextPreviewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TextPreviewComponent, isStandalone: true, selector: "ngx-text-preview", usesInheritance: true, usesOnChanges: true, ngImport: i0, template: ` <div class="text-container"> <div class="toolbar"> <div class="left-controls"> <button class="tool-btn" (click)="zoomOut()"> <preview-icon [themeMode]="themeMode" name="zoom-out" [tooltip]="'preview.toolbar.zoomOut'|i18n"></preview-icon> </button> <span class="zoom-text" (click)="resetZoom()" [tooltip]="'preview.toolbar.resetZoom'|i18n"> {{ (scale * 100).toFixed(0) }}% </span> <button class="tool-btn" (click)="zoomIn()"> <preview-icon [themeMode]="themeMode" name="zoom-in" [tooltip]="'preview.toolbar.zoomIn'|i18n"></preview-icon> </button> <button class="tool-btn" (click)="toggleWrap()"> <preview-icon [themeMode]="themeMode" [name]="isWrapped ? 'nowrap' : 'wrap'" [tooltip]="(isWrapped ? 'preview.toolbar.nowrap' : 'preview.toolbar.wrap')|i18n"></preview-icon> </button> </div> <div class="right-controls"> <button class="tool-btn" (click)="toggleFullscreen()"> <preview-icon [themeMode]="themeMode" name="fullscreen" [tooltip]="'preview.toolbar.fullscreen'|i18n"></preview-icon> </button> </div> </div> <div class="content-container" [class.wrap]="isWrapped" (wheel)="handleWheel($event)"> <div class="content-wrapper" [style]="'--scale:'+scale" [class.wrap]="isWrapped"> <pre [style.transform-origin]="'left top'" [class.wrap]="isWrapped" >{{ content }}</pre> </div> </div> </div> `, isInline: true, styles: [":root{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #d32029;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(0, 0, 0, .85);--nfp-text-secondary: rgba(0, 0, 0, .65);--nfp-text-disabled: rgba(0, 0, 0, .25);--nfp-bg-container: #ffffff;--nfp-bg-elevated: #fafafa;--nfp-bg-layout: #f0f2f5;--nfp-hover-bg: rgba(0, 0, 0, .04);--nfp-border-color: #d9d9d9;--nfp-split-color: rgba(0, 0, 0, .06);--nfp-scrollbar-bg: #ffffff;--nfp-scrollbar-thumb: #d9d9d9;--nfp-toolbar-bg: #fafafa;--nfp-toolbar-border: #d9d9d9;--nfp-toolbar-hover: rgba(0, 0, 0, .04);--nfp-toolbar-active: #e6f4ff;--nfp-preview-mask: rgba(0, 0, 0, .3);--nfp-preview-loading-bg: rgba(255, 255, 255, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .1);--nfp-theme-transition-duration: .3s}[data-nfp-theme=dark]{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #a61d24;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(255, 255, 255, .85);--nfp-text-secondary: rgba(255, 255, 255, .65);--nfp-text-disabled: rgba(255, 255, 255, .25);--nfp-bg-container: #1a1a1a;--nfp-bg-elevated: #262626;--nfp-bg-layout: #141414;--nfp-hover-bg: rgba(255, 255, 255, .08);--nfp-border-color: #303030;--nfp-split-color: rgba(255, 255, 255, .12);--nfp-scrollbar-bg: #1a1a1a;--nfp-scrollbar-thumb: #404040;--nfp-toolbar-bg: #262626;--nfp-toolbar-border: #303030;--nfp-toolbar-hover: rgba(255, 255, 255, .08);--nfp-toolbar-active: #111b26;--nfp-preview-mask: rgba(0, 0, 0, .65);--nfp-preview-loading-bg: rgba(0, 0, 0, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .4);--nfp-theme-transition-duration: .3s}*{transition:background-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),border-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),color var(--nfp-theme-transition-duration) var(--theme-transition-timing)}.no-transition,.no-transition *{transition:none!important}\n", ":host{display:block;width:100%;height:100%}.text-container{width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-bg-container);border-radius:8px;overflow:hidden}.toolbar{height:48px;min-height:48px;background:var(--nfp-toolbar-bg);display:flex;justify-content:space-between;align-items:center;padding:0 16px;border-bottom:1px solid var(--nfp-toolbar-border);gap:16px}.left-controls{display:flex;align-items:center;gap:8px}.content-container{flex:1;overflow:auto;position:relative;background:var(--nfp-bg-container);padding:16px;scrollbar-gutter:stable;scrollbar-width:thin;scrollbar-color:var(--nfp-scrollbar-thumb) var(--nfp-scrollbar-bg)}.content-container.wrap{overflow-x:hidden}.content-container::-webkit-scrollbar{width:8px;height:8px}.content-container::-webkit-scrollbar-track{background:var(--nfp-scrollbar-bg);border-radius:4px}.content-container::-webkit-scrollbar-thumb{background:var(--nfp-scrollbar-thumb);border-radius:4px}.content-container::-webkit-scrollbar-thumb:hover{background:var(--nfp-primary-color)}.content-wrapper{min-width:min-content;width:calc(100% * var(--scale, 1));height:calc(100% * var(--scale, 1));font-size:calc(16px * var(--scale, 1))}.content-wrapper.wrap{min-width:100%;width:100%}pre{margin:0;font-family:Consolas,Monaco,monospace;white-space:pre;tab-size:4;-moz-tab-size:4;transform-origin:left top;background:var(--nfp-bg-container);color:var(--nfp-text-primary);text-align:left;display:inline-block;min-width:100%}pre.wrap{white-space:pre-wrap;word-wrap:break-word;width:100%;display:block}.tool-btn{background:transparent;border:none;color:var(--nfp-text-primary);width:32px;height:32px;padding:0;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:all .2s}.tool-btn:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}.tool-btn:disabled{color:var(--nfp-text-disabled);cursor:not-allowed}.zoom-text{color:var(--nfp-text-primary);font-size:13px;min-width:48px;text-align:center;cursor:pointer;padding:4px;border-radius:4px}.zoom-text:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: PreviewIconComponent, selector: "preview-icon", inputs: ["name", "svg", "size", "color", "themeMode", "title", "cursor"] }, { kind: "pipe", type: I18nPipe, name: "i18n" }, { kind: "directive", type: TooltipDirective, selector: "[tooltip]", inputs: ["tooltip", "delay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextPreviewComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-text-preview', standalone: true, imports: [CommonModule, PreviewIconComponent, I18nPipe, TooltipDirective], template: ` <div class="text-container"> <div class="toolbar"> <div class="left-controls"> <button class="tool-btn" (click)="zoomOut()"> <preview-icon [themeMode]="themeMode" name="zoom-out" [tooltip]="'preview.toolbar.zoomOut'|i18n"></preview-icon> </button> <span class="zoom-text" (click)="resetZoom()" [tooltip]="'preview.toolbar.resetZoom'|i18n"> {{ (scale * 100).toFixed(0) }}% </span> <button class="tool-btn" (click)="zoomIn()"> <preview-icon [themeMode]="themeMode" name="zoom-in" [tooltip]="'preview.toolbar.zoomIn'|i18n"></preview-icon> </button> <button class="tool-btn" (click)="toggleWrap()"> <preview-icon [themeMode]="themeMode" [name]="isWrapped ? 'nowrap' : 'wrap'" [tooltip]="(isWrapped ? 'preview.toolbar.nowrap' : 'preview.toolbar.wrap')|i18n"></preview-icon> </button> </div> <div class="right-controls"> <button class="tool-btn" (click)="toggleFullscreen()"> <preview-icon [themeMode]="themeMode" name="fullscreen" [tooltip]="'preview.toolbar.fullscreen'|i18n"></preview-icon> </button> </div> </div> <div class="content-container" [class.wrap]="isWrapped" (wheel)="handleWheel($event)"> <div class="content-wrapper" [style]="'--scale:'+scale" [class.wrap]="isWrapped"> <pre [style.transform-origin]="'left top'" [class.wrap]="isWrapped" >{{ content }}</pre> </div> </div> </div> `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":root{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #d32029;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(0, 0, 0, .85);--nfp-text-secondary: rgba(0, 0, 0, .65);--nfp-text-disabled: rgba(0, 0, 0, .25);--nfp-bg-container: #ffffff;--nfp-bg-elevated: #fafafa;--nfp-bg-layout: #f0f2f5;--nfp-hover-bg: rgba(0, 0, 0, .04);--nfp-border-color: #d9d9d9;--nfp-split-color: rgba(0, 0, 0, .06);--nfp-scrollbar-bg: #ffffff;--nfp-scrollbar-thumb: #d9d9d9;--nfp-toolbar-bg: #fafafa;--nfp-toolbar-border: #d9d9d9;--nfp-toolbar-hover: rgba(0, 0, 0, .04);--nfp-toolbar-active: #e6f4ff;--nfp-preview-mask: rgba(0, 0, 0, .3);--nfp-preview-loading-bg: rgba(255, 255, 255, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .1);--nfp-theme-transition-duration: .3s}[data-nfp-theme=dark]{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #a61d24;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(255, 255, 255, .85);--nfp-text-secondary: rgba(255, 255, 255, .65);--nfp-text-disabled: rgba(255, 255, 255, .25);--nfp-bg-container: #1a1a1a;--nfp-bg-elevated: #262626;--nfp-bg-layout: #141414;--nfp-hover-bg: rgba(255, 255, 255, .08);--nfp-border-color: #303030;--nfp-split-color: rgba(255, 255, 255, .12);--nfp-scrollbar-bg: #1a1a1a;--nfp-scrollbar-thumb: #404040;--nfp-toolbar-bg: #262626;--nfp-toolbar-border: #303030;--nfp-toolbar-hover: rgba(255, 255, 255, .08);--nfp-toolbar-active: #111b26;--nfp-preview-mask: rgba(0, 0, 0, .65);--nfp-preview-loading-bg: rgba(0, 0, 0, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .4);--nfp-theme-transition-duration: .3s}*{transition:background-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),border-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),color var(--nfp-theme-transition-duration) var(--theme-transition-timing)}.no-transition,.no-transition *{transition:none!important}\n", ":host{display:block;width:100%;height:100%}.text-container{width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-bg-container);border-radius:8px;overflow:hidden}.toolbar{height:48px;min-height:48px;background:var(--nfp-toolbar-bg);display:flex;justify-content:space-between;align-items:center;padding:0 16px;border-bottom:1px solid var(--nfp-toolbar-border);gap:16px}.left-controls{display:flex;align-items:center;gap:8px}.content-container{flex:1;overflow:auto;position:relative;background:var(--nfp-bg-container);padding:16px;scrollbar-gutter:stable;scrollbar-width:thin;scrollbar-color:var(--nfp-scrollbar-thumb) var(--nfp-scrollbar-bg)}.content-container.wrap{overflow-x:hidden}.content-container::-webkit-scrollbar{width:8px;height:8px}.content-container::-webkit-scrollbar-track{background:var(--nfp-scrollbar-bg);border-radius:4px}.content-container::-webkit-scrollbar-thumb{background:var(--nfp-scrollbar-thumb);border-radius:4px}.content-container::-webkit-scrollbar-thumb:hover{background:var(--nfp-primary-color)}.content-wrapper{min-width:min-content;width:calc(100% * var(--scale, 1));height:calc(100% * var(--scale, 1));font-size:calc(16px * var(--scale, 1))}.content-wrapper.wrap{min-width:100%;width:100%}pre{margin:0;font-family:Consolas,Monaco,monospace;white-space:pre;tab-size:4;-moz-tab-size:4;transform-origin:left top;background:var(--nfp-bg-container);color:var(--nfp-text-primary);text-align:left;display:inline-block;min-width:100%}pre.wrap{white-space:pre-wrap;word-wrap:break-word;width:100%;display:block}.tool-btn{background:transparent;border:none;color:var(--nfp-text-primary);width:32px;height:32px;padding:0;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:all .2s}.tool-btn:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}.tool-btn:disabled{color:var(--nfp-text-disabled);cursor:not-allowed}.zoom-text{color:var(--nfp-text-primary);font-size:13px;min-width:48px;text-align:center;cursor:pointer;padding:4px;border-radius:4px}.zoom-text:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}\n"] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1wcmV2aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmd4LWZpbGUtcHJldmlldy9zcmMvbGliL3ByZXZpZXctdHlwZXMvdGV4dC1wcmV2aWV3L3RleHQtcHJldmlldy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBOEMsTUFBTSxlQUFlLENBQUM7QUFDOUcsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHdDQUF3QyxDQUFDO0FBRTVFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QyxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQzs7QUE2Q2xELE1BQU0sT0FBTyxvQkFBcUIsU0FBUSxvQkFBb0I7SUEzQzlEOztRQTRDRSxZQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBRU8sZUFBVSxHQUFHLEdBQUcsQ0FBQztRQUNqQixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsY0FBUyxHQUFHLEdBQUcsQ0FBQztRQUNoQixrQkFBYSxHQUFHLENBQUMsQ0FBQztLQTJGcEM7SUF4RkMsUUFBUTtRQUNOLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxRQUFRLENB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Q0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ2hDLFFBQVEsQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMvQyxDQUFDO2FBQU0sQ0FBQztZQUNOLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQzsrR0FsR1Usb0JBQW9CO21HQUFwQixvQkFBb0Isd0hBdkNyQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQ1QsMnBJQXBDUyxZQUFZLCtCQUFFLG9CQUFvQiw4SEFBRSxRQUFRLDZDQUFFLGdCQUFnQjs7NEZBd0M3RCxvQkFBb0I7a0JBM0NoQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixDQUFDLFlBQy9EOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1DVCxtQkFFZ0IsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgU2ltcGxlQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7UHJldmlld0ljb25Db21wb25lbnR9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMnO1xuaW1wb3J0IHtCYXNlUHJldmlld0NvbXBvbmVudH0gZnJvbSBcIi4uL2Jhc2UtcHJldmlldy9iYXNlLXByZXZpZXcuY29tcG9uZW50XCI7XG5pbXBvcnQge0ZpbGVSZWFkZXJSZXNwb25zZX0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzXCI7XG5pbXBvcnQge0kxOG5QaXBlfSBmcm9tIFwiLi4vLi4vaTE4bi9pMThuLnBpcGVcIjtcbmltcG9ydCB7VG9vbHRpcERpcmVjdGl2ZX0gZnJvbSBcIi4uLy4uL2RpcmVjdGl2ZXNcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXRleHQtcHJldmlldycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFByZXZpZXdJY29uQ29tcG9uZW50LCBJMThuUGlwZSwgVG9vbHRpcERpcmVjdGl2ZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cInRleHQtY29udGFpbmVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidG9vbGJhclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVmdC1jb250cm9sc1wiPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0b29sLWJ0blwiIChjbGljayk9XCJ6b29tT3V0KClcIj5cbiAgICAgICAgICAgIDxwcmV2aWV3LWljb24gW3RoZW1lTW9kZV09XCJ0aGVtZU1vZGVcIiBuYW1lPVwiem9vbS1vdXRcIiBbdG9vbHRpcF09XCIncHJldmlldy50b29sYmFyLnpvb21PdXQnfGkxOG5cIj48L3ByZXZpZXctaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInpvb20tdGV4dFwiIChjbGljayk9XCJyZXNldFpvb20oKVwiIFt0b29sdGlwXT1cIidwcmV2aWV3LnRvb2xiYXIucmVzZXRab29tJ3xpMThuXCI+XG4gICAgICAgICAgICB7eyAoc2NhbGUgKiAxMDApLnRvRml4ZWQoMCkgfX0lXG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0b29sLWJ0blwiIChjbGljayk9XCJ6b29tSW4oKVwiPlxuICAgICAgICAgICAgPHByZXZpZXctaWNvbiBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiIG5hbWU9XCJ6b29tLWluXCIgW3Rvb2x0aXBdPVwiJ3ByZXZpZXcudG9vbGJhci56b29tSW4nfGkxOG5cIj48L3ByZXZpZXctaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidG9vbC1idG5cIiAoY2xpY2spPVwidG9nZ2xlV3JhcCgpXCI+XG4gICAgICAgICAgICA8cHJldmlldy1pY29uIFt0aGVtZU1vZGVdPVwidGhlbWVNb2RlXCIgW25hbWVdPVwiaXNXcmFwcGVkID8gJ25vd3JhcCcgOiAnd3JhcCdcIiBbdG9vbHRpcF09XCIoaXNXcmFwcGVkID8gJ3ByZXZpZXcudG9vbGJhci5ub3dyYXAnIDogJ3ByZXZpZXcudG9vbGJhci53cmFwJyl8aTE4blwiPjwvcHJldmlldy1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0LWNvbnRyb2xzXCI+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wtYnRuXCIgKGNsaWNrKT1cInRvZ2dsZUZ1bGxzY3JlZW4oKVwiPlxuICAgICAgICAgICAgPHByZXZpZXctaWNvbiBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiIG5hbWU9XCJmdWxsc2NyZWVuXCIgW3Rvb2x0aXBdPVwiJ3ByZXZpZXcudG9vbGJhci5mdWxsc2NyZWVuJ3xpMThuXCI+PC9wcmV2aWV3LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LWNvbnRhaW5lclwiXG4gICAgICAgICAgIFtjbGFzcy53cmFwXT1cImlzV3JhcHBlZFwiXG4gICAgICAgICAgICh3aGVlbCk9XCJoYW5kbGVXaGVlbCgkZXZlbnQpXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LXdyYXBwZXJcIiBbc3R5bGVdPVwiJy0tc2NhbGU6JytzY2FsZVwiIFtjbGFzcy53cmFwXT1cImlzV3JhcHBlZFwiPlxuICAgICAgICAgIDxwcmVcbiAgICAgICAgICAgIFtzdHlsZS50cmFuc2Zvcm0tb3JpZ2luXT1cIidsZWZ0IHRvcCdcIlxuICAgICAgICAgICAgW2NsYXNzLndyYXBdPVwiaXNXcmFwcGVkXCJcbiAgICAgICAgICA+e3sgY29udGVudCB9fTwvcHJlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZVVybHM6IFsnLi4vLi4vc3R5bGVzL190aGVtZS5zY3NzJywgJy4vdGV4dC1wcmV2aWV3LmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRleHRQcmV2aWV3Q29tcG9uZW50IGV4dGVuZHMgQmFzZVByZXZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgY29udGVudCA9ICcnO1xuICBpc1dyYXBwZWQgPSBmYWxzZTtcbiAgc2NhbGUgPSAxO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgU0NBTEVfU1RFUCA9IDAuMTtcbiAgcHJpdmF0ZSByZWFkb25seSBNQVhfU0NBTEUgPSAzO1xuICBwcml2YXRlIHJlYWRvbmx5IE1JTl9TQ0FMRSA9IDAuMTtcbiAgcHJpdmF0ZSByZWFkb25seSBERUZBVUxUX1NDQUxFID0gMTtcbiAgcHJpdmF0ZSBrZXlkb3duTGlzdGVuZXI/OiAoZTogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZDtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnNldHVwS2V5Ym9hcmRMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMucmVtb3ZlS2V5Ym9hcmRMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlc1snZmlsZSddKSB7XG4gICAgICB0aGlzLmxvYWRGaWxlKCd0ZXh0JylcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgaGFuZGxlRmlsZUNvbnRlbnQoY29udGVudDogRmlsZVJlYWRlclJlc3BvbnNlKSB7XG4gICAgaWYgKGNvbnRlbnQuZXJyb3IpIHtcbiAgICAgIHRoaXMuY29udGVudCA9ICfmlofku7bliqDovb3lpLHotKU6JyArIGNvbnRlbnQuZXJyb3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQudGV4dCB8fCAn5paH5Lu25YaF5a655Li656m6JztcbiAgICB9XG4gIH1cblxuXG4gIHByaXZhdGUgc2V0dXBLZXlib2FyZExpc3RlbmVycygpIHtcbiAgICB0aGlzLmtleWRvd25MaXN0ZW5lciA9IChlOiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICBpZiAoKGUuY3RybEtleSB8fCBlLm1ldGFLZXkpICYmIGUua2V5ID09PSAnMCcpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJlc2V0Wm9vbSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5rZXlkb3duTGlzdGVuZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVLZXlib2FyZExpc3RlbmVycygpIHtcbiAgICBpZiAodGhpcy5rZXlkb3duTGlzdGVuZXIpIHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmtleWRvd25MaXN0ZW5lcik7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlV2hlZWwoZXZlbnQ6IFdoZWVsRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgY29uc3QgZGVsdGEgPSBldmVudC5kZWx0YVkgfHwgZXZlbnQuZGV0YWlsIHx8IDA7XG5cbiAgICAgIGlmIChkZWx0YSA8IDApIHtcbiAgICAgICAgdGhpcy56b29tSW4oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuem9vbU91dCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMuTUFYX1NDQUxFKSB7XG4gICAgICB0aGlzLnNjYWxlID0gTWF0aC5taW4odGhpcy5NQVhfU0NBTEUsIHRoaXMuc2NhbGUgKyB0aGlzLlNDQUxFX1NURVApO1xuICAgICAgdGhpcy5hcHBseVpvb20oKTtcbiAgICB9XG4gIH1cblxuICB6b29tT3V0KCkge1xuICAgIGlmICh0aGlzLnNjYWxlID4gdGhpcy5NSU5fU0NBTEUpIHtcbiAgICAgIHRoaXMuc2NhbGUgPSBNYXRoLm1heCh0aGlzLk1JTl9TQ0FMRSwgdGhpcy5zY2FsZSAtIHRoaXMuU0NBTEVfU1RFUCk7XG4gICAgICB0aGlzLmFwcGx5Wm9vbSgpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2V0Wm9vbSgpIHtcbiAgICB0aGlzLnNjYWxlID0gdGhpcy5ERUZBVUxUX1NDQUxFO1xuICAgIHRoaXMuYXBwbHlab29tKCk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5Wm9vbSgpIHtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHRvZ2dsZVdyYXAoKSB7XG4gICAgdGhpcy5pc1dyYXBwZWQgPSAhdGhpcy5pc1dyYXBwZWQ7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICB0b2dnbGVGdWxsc2NyZWVuKCkge1xuICAgIGlmICghZG9jdW1lbnQuZnVsbHNjcmVlbkVsZW1lbnQpIHtcbiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5yZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkb2N1bWVudC5leGl0RnVsbHNjcmVlbigpO1xuICAgIH1cbiAgfVxufVxuIl19