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.

133 lines 43.4 kB
import { ChangeDetectionStrategy, Component, HostListener, Input, ViewEncapsulation } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ArchivePreviewComponent, AudioPreviewComponent, ExcelPreviewComponent, ImagePreviewComponent, MarkdownPreviewComponent, PdfPreviewComponent, PptPreviewComponent, TextPreviewComponent, UnknownPreviewComponent, VideoPreviewComponent, WordPreviewComponent } from '../../preview-types'; import { PreviewIconComponent } from '../preview-icon'; import { ThemeIconComponent } from "../theme-icon/theme-icon.component"; import { I18nPipe } from "../../i18n/i18n.pipe"; import * as i0 from "@angular/core"; import * as i1 from "../../services"; import * as i2 from "@angular/common"; export class PreviewModalComponent { constructor(cdr, themeService, previewService) { this.cdr = cdr; this.themeService = themeService; this.previewService = previewService; this.isVisible = false; this.state$ = this.previewService.getStateObservable(); this.isControlsVisible = true; this.HIDE_DELAY = 2000; this.loading$ = this.previewService.getLoadingObservable(); } ngOnInit() { this.subscription = this.state$.subscribe(state => { this.isVisible = state.isVisible; this.currentFile = state.currentFile; this.cdr.markForCheck(); }); this.themeService.setMode(this.themeMode); this.theme$ = this.themeService.getThemeObservable(); this.subscription.add(this.theme$.subscribe(theme => this.themeMode = theme)); } ngOnDestroy() { this.subscription?.unsubscribe(); if (this.controlsTimeout) { window.clearTimeout(this.controlsTimeout); } if (window.matchMedia) { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); prefersDark.removeEventListener('change', () => { }); } } handleKeyboardEvent(event) { switch (event.key) { case 'Escape': this.close(); break; case 'ArrowLeft': this.previous(); break; case 'ArrowRight': this.next(); break; } } close() { this.previewService.close(); } previous() { this.previewService.previous(); } next() { this.previewService.next(); } canShowPrevious() { const state = this.previewService.state; return state.currentIndex > 0; } canShowNext() { const state = this.previewService.state; return state.currentIndex < state.files.length - 1; } getCurrentFileInfo() { const state = this.previewService.state; return `${state.currentIndex + 1} / ${state.files.length}`; } get hasMultipleFiles() { const state = this.previewService.state; return (state.files?.length || 0) > 1; } handleMouseMove() { this.isControlsVisible = true; this.cdr.markForCheck(); if (this.controlsTimeout) { window.clearTimeout(this.controlsTimeout); } this.controlsTimeout = window.setTimeout(() => { this.hideControls(); }, this.HIDE_DELAY); } hideControls() { this.isControlsVisible = false; this.cdr.markForCheck(); if (this.controlsTimeout) { window.clearTimeout(this.controlsTimeout); } } toggleTheme() { this.themeService.toggleTheme(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PreviewModalComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.ThemeService }, { token: i1.PreviewService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PreviewModalComponent, isStandalone: true, selector: "ngx-file-preview-modal", inputs: { file: "file", themeMode: ["themeMode", "themeMode", (value) => value], autoThemeConfig: "autoThemeConfig" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0, template: "<div class=\"nfp-modal__overlay\" *ngIf=\"isVisible\" (click)=\"close()\">\n <div class=\"nfp-modal__content\"\n (click)=\"$event.stopPropagation()\"\n (mousemove)=\"handleMouseMove()\"\n (mouseleave)=\"hideControls()\">\n <div class=\"nfp-modal__header\" [class.nfp-modal__header--multiple]=\"hasMultipleFiles\">\n <div class=\"nfp-modal__header-left\">\n <span class=\"nfp-modal__filename\">{{ currentFile?.name }}</span>\n <span class=\"nfp-modal__fileindex\" *ngIf=\"hasMultipleFiles\">{{ getCurrentFileInfo() }}</span>\n </div>\n <div class=\"nfp-modal__header-right\">\n <div class=\"nfp-modal__theme-toggle\" (click)=\"toggleTheme()\">\n <ngx-theme-icon [themeMode]=\"theme$|async\"></ngx-theme-icon>\n </div>\n <preview-icon cursor=\"pointer\" name=\"close\" [themeMode]=\"theme$|async\" (click)=\"close()\"></preview-icon>\n </div>\n </div>\n <div class=\"nfp-modal__body\">\n <button class=\"nfp-modal__nav-btn nfp-modal__nav-btn--prev\"\n *ngIf=\"canShowPrevious()\"\n [class.nfp-modal__nav-btn--visible]=\"isControlsVisible\"\n (click)=\"previous()\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"36\" name=\"previous\"></preview-icon>\n </button>\n\n <div class=\"nfp-modal__preview\">\n @if(loading$|async){\n <div class=\"nfp-modal__loading-overlay\">\n <div class=\"spinner\"></div>\n <span>{{'loading'|i18n}}</span>\n </div>\n }\n <ng-container [ngSwitch]=\"currentFile?.type\">\n <ngx-image-preview\n *ngSwitchCase=\"'image'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-image-preview>\n\n <ngx-video-preview\n *ngSwitchCase=\"'video'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-video-preview>\n\n <ngx-pdf-preview\n *ngSwitchCase=\"'pdf'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-pdf-preview>\n\n <ngx-word-preview\n *ngSwitchCase=\"'word'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-word-preview>\n\n <ngx-excel-preview\n *ngSwitchCase=\"'excel'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-excel-preview>\n\n <ngx-ppt-preview\n *ngSwitchCase=\"'ppt'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-ppt-preview>\n\n <ngx-text-preview\n *ngSwitchCase=\"'txt'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-text-preview>\n\n <ngx-markdown-preview\n *ngSwitchCase=\"'markdown'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-markdown-preview>\n\n <ngx-archive-preview\n *ngSwitchCase=\"'zip'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-archive-preview>\n\n <ngx-audio-preview\n *ngSwitchCase=\"'audio'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-audio-preview>\n\n <ngx-unknown-preview\n *ngSwitchCase=\"'unknown'\"\n [file]=\"currentFile!\">\n [themeMode]=\"theme$|async\"\n </ngx-unknown-preview>\n </ng-container>\n </div>\n\n <button class=\"nfp-modal__nav-btn nfp-modal__nav-btn--next\"\n *ngIf=\"canShowNext()\"\n [class.nfp-modal__nav-btn--visible]=\"isControlsVisible\"\n (click)=\"next()\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"36\" name=\"next\"></preview-icon>\n </button>\n </div>\n </div>\n</div>\n", 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:contents}.nfp-modal__overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:var(--nfp-preview-mask);z-index:2147483647;isolation:isolate;display:flex;justify-content:center;align-items:center;-webkit-app-region:no-drag}.nfp-modal__content{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-bg-elevated);color:var(--nfp-text-primary);transition:all .3s ease}.nfp-modal__header{position:absolute;top:0;left:0;right:0;height:44px;padding:0 16px;display:flex;justify-content:space-between;align-items:center;background:var(--nfp-bg-elevated);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:10;opacity:.8;transition:opacity .3s;border-bottom:1px solid var(--nfp-border-color)}.nfp-modal__header:hover{opacity:1}.nfp-modal__header-left{display:flex;align-items:center;gap:8px}.nfp-modal__filename{font-size:14px;font-weight:500;max-width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--nfp-text-primary)}.nfp-modal__fileindex{font-size:12px;color:var(--nfp-text-secondary)}.nfp-modal__header-right{display:flex;align-items:center;gap:8px}.nfp-modal__theme-toggle{cursor:pointer}.nfp-modal__body{flex:1;display:flex;align-items:center;position:relative;overflow:hidden;margin-top:44px;background:var(--nfp-bg-container)}.nfp-modal__preview{flex:1;height:100%;width:100%;position:relative;display:flex;align-items:center;justify-content:center}.nfp-modal__loading-overlay{position:absolute;inset:0;background:var(--nfp-preview-loading-bg);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px}.nfp-modal__loading-overlay .spinner{width:40px;height:40px;border:3px solid var(--nfp-toolbar-bg);border-top-color:var(--nfp-primary-color);border-radius:50%;animation:spin 1s linear infinite}.nfp-modal__loading-overlay span{color:var(--nfp-text-primary)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.nfp-modal__nav-btn{position:absolute;top:50%;transform:translateY(-50%);background:var(--mask-color);border:none;padding:8px;border-radius:50%;color:var(--nfp-text-primary);cursor:pointer;z-index:5;transition:all .3s;opacity:0;pointer-events:none}.nfp-modal__nav-btn--visible{opacity:.8;pointer-events:auto}.nfp-modal__nav-btn:hover{opacity:1;color:#fff;transform:translateY(-50%) scale(1.1)}.nfp-modal__nav-btn--prev{left:16px}.nfp-modal__nav-btn--next{right:16px}.nfp-modal__nav-btn preview-icon{display:block;filter:drop-shadow(0 2px 4px rgba(0,0,0,.3))}.nfp-modal__preview :host ::ng-deep ngx-image-preview,.nfp-modal__preview :host ::ng-deep ngx-video-preview,.nfp-modal__preview :host ::ng-deep ngx-pdf-preview,.nfp-modal__preview :host ::ng-deep ngx-word-preview,.nfp-modal__preview :host ::ng-deep ngx-excel-preview,.nfp-modal__preview :host ::ng-deep ngx-ppt-preview,.nfp-modal__preview :host ::ng-deep ngx-text-preview,.nfp-modal__preview :host ::ng-deep ngx-archive-preview,.nfp-modal__preview :host ::ng-deep ngx-audio-preview,.nfp-modal__preview :host ::ng-deep ngx-unknown-preview{width:100%;height:100%;display:block}body:has(.nfp-modal__overlay){overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: ImagePreviewComponent, selector: "ngx-image-preview" }, { kind: "component", type: VideoPreviewComponent, selector: "ngx-video-preview" }, { kind: "component", type: PdfPreviewComponent, selector: "ngx-pdf-preview" }, { kind: "component", type: TextPreviewComponent, selector: "ngx-text-preview" }, { kind: "component", type: ArchivePreviewComponent, selector: "ngx-archive-preview" }, { kind: "component", type: PreviewIconComponent, selector: "preview-icon", inputs: ["name", "svg", "size", "color", "themeMode", "title", "cursor"] }, { kind: "component", type: WordPreviewComponent, selector: "ngx-word-preview" }, { kind: "component", type: ExcelPreviewComponent, selector: "ngx-excel-preview" }, { kind: "component", type: PptPreviewComponent, selector: "ngx-ppt-preview" }, { kind: "component", type: AudioPreviewComponent, selector: "ngx-audio-preview" }, { kind: "component", type: UnknownPreviewComponent, selector: "ngx-unknown-preview" }, { kind: "component", type: MarkdownPreviewComponent, selector: "ngx-markdown-preview" }, { kind: "component", type: ThemeIconComponent, selector: "ngx-theme-icon", inputs: ["themeMode"] }, { kind: "pipe", type: I18nPipe, name: "i18n" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PreviewModalComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-file-preview-modal', standalone: true, imports: [ CommonModule, ImagePreviewComponent, VideoPreviewComponent, PdfPreviewComponent, TextPreviewComponent, ArchivePreviewComponent, PreviewIconComponent, WordPreviewComponent, ExcelPreviewComponent, PptPreviewComponent, AudioPreviewComponent, UnknownPreviewComponent, MarkdownPreviewComponent, ThemeIconComponent, I18nPipe ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"nfp-modal__overlay\" *ngIf=\"isVisible\" (click)=\"close()\">\n <div class=\"nfp-modal__content\"\n (click)=\"$event.stopPropagation()\"\n (mousemove)=\"handleMouseMove()\"\n (mouseleave)=\"hideControls()\">\n <div class=\"nfp-modal__header\" [class.nfp-modal__header--multiple]=\"hasMultipleFiles\">\n <div class=\"nfp-modal__header-left\">\n <span class=\"nfp-modal__filename\">{{ currentFile?.name }}</span>\n <span class=\"nfp-modal__fileindex\" *ngIf=\"hasMultipleFiles\">{{ getCurrentFileInfo() }}</span>\n </div>\n <div class=\"nfp-modal__header-right\">\n <div class=\"nfp-modal__theme-toggle\" (click)=\"toggleTheme()\">\n <ngx-theme-icon [themeMode]=\"theme$|async\"></ngx-theme-icon>\n </div>\n <preview-icon cursor=\"pointer\" name=\"close\" [themeMode]=\"theme$|async\" (click)=\"close()\"></preview-icon>\n </div>\n </div>\n <div class=\"nfp-modal__body\">\n <button class=\"nfp-modal__nav-btn nfp-modal__nav-btn--prev\"\n *ngIf=\"canShowPrevious()\"\n [class.nfp-modal__nav-btn--visible]=\"isControlsVisible\"\n (click)=\"previous()\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"36\" name=\"previous\"></preview-icon>\n </button>\n\n <div class=\"nfp-modal__preview\">\n @if(loading$|async){\n <div class=\"nfp-modal__loading-overlay\">\n <div class=\"spinner\"></div>\n <span>{{'loading'|i18n}}</span>\n </div>\n }\n <ng-container [ngSwitch]=\"currentFile?.type\">\n <ngx-image-preview\n *ngSwitchCase=\"'image'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-image-preview>\n\n <ngx-video-preview\n *ngSwitchCase=\"'video'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-video-preview>\n\n <ngx-pdf-preview\n *ngSwitchCase=\"'pdf'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-pdf-preview>\n\n <ngx-word-preview\n *ngSwitchCase=\"'word'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-word-preview>\n\n <ngx-excel-preview\n *ngSwitchCase=\"'excel'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-excel-preview>\n\n <ngx-ppt-preview\n *ngSwitchCase=\"'ppt'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-ppt-preview>\n\n <ngx-text-preview\n *ngSwitchCase=\"'txt'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-text-preview>\n\n <ngx-markdown-preview\n *ngSwitchCase=\"'markdown'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-markdown-preview>\n\n <ngx-archive-preview\n *ngSwitchCase=\"'zip'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-archive-preview>\n\n <ngx-audio-preview\n *ngSwitchCase=\"'audio'\"\n [file]=\"currentFile!\"\n [themeMode]=\"theme$|async\"\n ></ngx-audio-preview>\n\n <ngx-unknown-preview\n *ngSwitchCase=\"'unknown'\"\n [file]=\"currentFile!\">\n [themeMode]=\"theme$|async\"\n </ngx-unknown-preview>\n </ng-container>\n </div>\n\n <button class=\"nfp-modal__nav-btn nfp-modal__nav-btn--next\"\n *ngIf=\"canShowNext()\"\n [class.nfp-modal__nav-btn--visible]=\"isControlsVisible\"\n (click)=\"next()\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"36\" name=\"next\"></preview-icon>\n </button>\n </div>\n </div>\n</div>\n", 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:contents}.nfp-modal__overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:var(--nfp-preview-mask);z-index:2147483647;isolation:isolate;display:flex;justify-content:center;align-items:center;-webkit-app-region:no-drag}.nfp-modal__content{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-bg-elevated);color:var(--nfp-text-primary);transition:all .3s ease}.nfp-modal__header{position:absolute;top:0;left:0;right:0;height:44px;padding:0 16px;display:flex;justify-content:space-between;align-items:center;background:var(--nfp-bg-elevated);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:10;opacity:.8;transition:opacity .3s;border-bottom:1px solid var(--nfp-border-color)}.nfp-modal__header:hover{opacity:1}.nfp-modal__header-left{display:flex;align-items:center;gap:8px}.nfp-modal__filename{font-size:14px;font-weight:500;max-width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--nfp-text-primary)}.nfp-modal__fileindex{font-size:12px;color:var(--nfp-text-secondary)}.nfp-modal__header-right{display:flex;align-items:center;gap:8px}.nfp-modal__theme-toggle{cursor:pointer}.nfp-modal__body{flex:1;display:flex;align-items:center;position:relative;overflow:hidden;margin-top:44px;background:var(--nfp-bg-container)}.nfp-modal__preview{flex:1;height:100%;width:100%;position:relative;display:flex;align-items:center;justify-content:center}.nfp-modal__loading-overlay{position:absolute;inset:0;background:var(--nfp-preview-loading-bg);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px}.nfp-modal__loading-overlay .spinner{width:40px;height:40px;border:3px solid var(--nfp-toolbar-bg);border-top-color:var(--nfp-primary-color);border-radius:50%;animation:spin 1s linear infinite}.nfp-modal__loading-overlay span{color:var(--nfp-text-primary)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.nfp-modal__nav-btn{position:absolute;top:50%;transform:translateY(-50%);background:var(--mask-color);border:none;padding:8px;border-radius:50%;color:var(--nfp-text-primary);cursor:pointer;z-index:5;transition:all .3s;opacity:0;pointer-events:none}.nfp-modal__nav-btn--visible{opacity:.8;pointer-events:auto}.nfp-modal__nav-btn:hover{opacity:1;color:#fff;transform:translateY(-50%) scale(1.1)}.nfp-modal__nav-btn--prev{left:16px}.nfp-modal__nav-btn--next{right:16px}.nfp-modal__nav-btn preview-icon{display:block;filter:drop-shadow(0 2px 4px rgba(0,0,0,.3))}.nfp-modal__preview :host ::ng-deep ngx-image-preview,.nfp-modal__preview :host ::ng-deep ngx-video-preview,.nfp-modal__preview :host ::ng-deep ngx-pdf-preview,.nfp-modal__preview :host ::ng-deep ngx-word-preview,.nfp-modal__preview :host ::ng-deep ngx-excel-preview,.nfp-modal__preview :host ::ng-deep ngx-ppt-preview,.nfp-modal__preview :host ::ng-deep ngx-text-preview,.nfp-modal__preview :host ::ng-deep ngx-archive-preview,.nfp-modal__preview :host ::ng-deep ngx-audio-preview,.nfp-modal__preview :host ::ng-deep ngx-unknown-preview{width:100%;height:100%;display:block}body:has(.nfp-modal__overlay){overflow:hidden}\n"] }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.ThemeService }, { type: i1.PreviewService }], propDecorators: { file: [{ type: Input }], themeMode: [{ type: Input, args: [{ transform: (value) => value }] }], autoThemeConfig: [{ type: Input }], handleKeyboardEvent: [{ type: HostListener, args: ['document:keydown', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy1tb2RhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25neC1maWxlLXByZXZpZXcvc3JjL2xpYi9jb21wb25lbnRzL3ByZXZpZXctbW9kYWwvcHJldmlldy1tb2RhbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25neC1maWxlLXByZXZpZXcvc3JjL2xpYi9jb21wb25lbnRzL3ByZXZpZXctbW9kYWwvcHJldmlldy1tb2RhbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVHLGlCQUFpQixFQUMxQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFN0MsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLHFCQUFxQixFQUFFLHdCQUF3QixFQUMvQyxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIscUJBQXFCLEVBQ3JCLG9CQUFvQixFQUNyQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBR3JELE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQzs7OztBQThCOUMsTUFBTSxPQUFPLHFCQUFxQjtJQWVoQyxZQUFvQixHQUFzQixFQUFVLFlBQTBCLEVBQVUsY0FBOEI7UUFBbEcsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUFVLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQVZ0SCxjQUFT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QkFBcUIsOERBQ3JCLG1CQUFtQiw0REFDbkIsb0JBQW9CLDZEQUNwQix1QkFBdUIsZ0VBQ3ZCLG9CQUFvQixtSUFDcEIsb0JBQW9CLDZEQUNwQixxQkFBcUIsOERBQ3JCLG1CQUFtQiw0REFDbkIscUJBQXFCLDhEQUNyQix1QkFBdUIsZ0VBQ3ZCLHdCQUF3QixpRUFDeEIsa0JBQWtCLDZFQUNsQixRQUFROzs0RkFVQyxxQkFBcUI7a0JBNUJqQyxTQUFTOytCQUNFLHdCQUF3QixjQUN0QixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixxQkFBcUI7d0JBQ3JCLHFCQUFxQjt3QkFDckIsbUJBQW1CO3dCQUNuQixvQkFBb0I7d0JBQ3BCLHVCQUF1Qjt3QkFDdkIsb0JBQW9CO3dCQUNwQixvQkFBb0I7d0JBQ3BCLHFCQUFxQjt3QkFDckIsbUJBQW1CO3dCQUNuQixxQkFBcUI7d0JBQ3JCLHVCQUF1Qjt3QkFDdkIsd0JBQXdCO3dCQUN4QixrQkFBa0I7d0JBQ2xCLFFBQVE7cUJBQ1QsbUJBTWdCLHVCQUF1QixDQUFDLE1BQU0saUJBQ2hDLGlCQUFpQixDQUFDLElBQUk7OElBRzVCLElBQUk7c0JBQVosS0FBSztnQkFDOEQsU0FBUztzQkFBNUUsS0FBSzt1QkFBQyxFQUFDLFNBQVMsRUFBRSxDQUFDLEtBQXVCLEVBQWEsRUFBRSxDQUFDLEtBQU0sRUFBQztnQkFDekQsZUFBZTtzQkFBdkIsS0FBSztnQkF3Q04sbUJBQW1CO3NCQURsQixZQUFZO3VCQUFDLGtCQUFrQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LCBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtQcmV2aWV3U2VydmljZSwgVGhlbWVTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcyc7XG5pbXBvcnQge1xuICBBcmNoaXZlUHJldmlld0NvbXBvbmVudCxcbiAgQXVkaW9QcmV2aWV3Q29tcG9uZW50LFxuICBFeGNlbFByZXZpZXdDb21wb25lbnQsXG4gIEltYWdlUHJldmlld0NvbXBvbmVudCwgTWFya2Rvd25QcmV2aWV3Q29tcG9uZW50LFxuICBQZGZQcmV2aWV3Q29tcG9uZW50LFxuICBQcHRQcmV2aWV3Q29tcG9uZW50LFxuICBUZXh0UHJldmlld0NvbXBvbmVudCxcbiAgVW5rbm93blByZXZpZXdDb21wb25lbnQsXG4gIFZpZGVvUHJldmlld0NvbXBvbmVudCxcbiAgV29yZFByZXZpZXdDb21wb25lbnRcbn0gZnJvbSAnLi4vLi4vcHJldmlldy10eXBlcyc7XG5pbXBvcnQge1ByZXZpZXdJY29uQ29tcG9uZW50fSBmcm9tICcuLi9wcmV2aWV3LWljb24nO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtBdXRvVGhlbWVDb25maWcsIFByZXZpZXdGaWxlLCBUaGVtZU1vZGV9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7VGhlbWVJY29uQ29tcG9uZW50fSBmcm9tIFwiLi4vdGhlbWUtaWNvbi90aGVtZS1pY29uLmNvbXBvbmVudFwiO1xuaW1wb3J0IHtJMThuUGlwZX0gZnJvbSBcIi4uLy4uL2kxOG4vaTE4bi5waXBlXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1maWxlLXByZXZpZXctbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEltYWdlUHJldmlld0NvbXBvbmVudCxcbiAgICBWaWRlb1ByZXZpZXdDb21wb25lbnQsXG4gICAgUGRmUHJldmlld0NvbXBvbmVudCxcbiAgICBUZXh0UHJldmlld0NvbXBvbmVudCxcbiAgICBBcmNoaXZlUHJldmlld0NvbXBvbmVudCxcbiAgICBQcmV2aWV3SWNvbkNvbXBvbmVudCxcbiAgICBXb3JkUHJldmlld0NvbXBvbmVudCxcbiAgICBFeGNlbFByZXZpZXdDb21wb25lbnQsXG4gICAgUHB0UHJldmlld0NvbXBvbmVudCxcbiAgICBBdWRpb1ByZXZpZXdDb21wb25lbnQsXG4gICAgVW5rbm93blByZXZpZXdDb21wb25lbnQsXG4gICAgTWFya2Rvd25QcmV2aWV3Q29tcG9uZW50LFxuICAgIFRoZW1lSWNvbkNvbXBvbmVudCxcbiAgICBJMThuUGlwZVxuICBdLFxuICB0ZW1wbGF0ZVVybDogJ3ByZXZpZXctbW9kYWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFtcbiAgICAnLi4vLi4vc3R5bGVzL190aGVtZS5zY3NzJyxcbiAgICAncHJldmlldy1tb2RhbC5jb21wb25lbnQuc2NzcydcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgUHJldmlld01vZGFsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBmaWxlITogUHJldmlld0ZpbGU7XG4gIEBJbnB1dCh7dHJhbnNmb3JtOiAodmFsdWU6IFRoZW1lTW9kZSB8IG51bGwpOiBUaGVtZU1vZGUgPT4gdmFsdWUhfSkgdGhlbWVNb2RlITogVGhlbWVNb2RlO1xuICBASW5wdXQoKSBhdXRvVGhlbWVDb25maWc/OiBBdXRvVGhlbWVDb25maWc7XG5cbiAgaXNWaXNpYmxlID0gZmFsc2U7XG4gIGN1cnJlbnRGaWxlPzogUHJldmlld0ZpbGU7XG4gIHByaXZhdGUgc3RhdGUkID0gdGhpcy5wcmV2aWV3U2VydmljZS5nZXRTdGF0ZU9ic2VydmFibGUoKTtcbiAgaXNDb250cm9sc1Zpc2libGUgPSB0cnVlO1xuICBwcml2YXRlIGNvbnRyb2xzVGltZW91dD86IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBISURFX0RFTEFZID0gMjAwMDtcbiAgdGhlbWUkITogT2JzZXJ2YWJsZTxUaGVtZU1vZGU+O1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICBwdWJsaWMgbG9hZGluZyQ6T2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMucHJldmlld1NlcnZpY2UuZ2V0TG9hZGluZ09ic2VydmFibGUoKTtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHRoZW1lU2VydmljZTogVGhlbWVTZXJ2aWNlLCBwcml2YXRlIHByZXZpZXdTZXJ2aWNlOiBQcmV2aWV3U2VydmljZSkge1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLnN0YXRlJC5zdWJzY3JpYmUoc3RhdGUgPT4ge1xuICAgICAgdGhpcy5pc1Zpc2libGUgPSBzdGF0ZS5pc1Zpc2libGU7XG4gICAgICB0aGlzLmN1cnJlbnRGaWxlID0gc3RhdGUuY3VycmVudEZpbGU7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcblxuICAgIHRoaXMudGhlbWVTZXJ2aWNlLnNldE1vZGUodGhpcy50aGVtZU1vZGUpO1xuICAgIHRoaXMudGhlbWUkID0gdGhpcy50aGVtZVNlcnZpY2UuZ2V0VGhlbWVPYnNlcnZhYmxlKClcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQodGhpcy50aGVtZSQuc3Vic2NyaWJlKHRoZW1lID0+IHRoaXMudGhlbWVNb2RlID0gdGhlbWUpKVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMuY29udHJvbHNUaW1lb3V0KSB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuY29udHJvbHNUaW1lb3V0KTtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICBjb25zdCBwcmVmZXJzRGFyayA9IHdpbmRvdy5tYXRjaE1lZGlhKCcocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspJyk7XG4gICAgICBwcmVmZXJzRGFyay5yZW1vdmVFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duJywgWyckZXZlbnQnXSlcbiAgaGFuZGxlS2V5Ym9hcmRFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICBjYXNlICdFc2NhcGUnOlxuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQXJyb3dMZWZ0JzpcbiAgICAgICAgdGhpcy5wcmV2aW91cygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgICB0aGlzLm5leHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5wcmV2aWV3U2VydmljZS5jbG9zZSgpO1xuICB9XG5cbiAgcHJldmlvdXMoKSB7XG4gICAgdGhpcy5wcmV2aWV3U2VydmljZS5wcmV2aW91cygpO1xuICB9XG5cbiAgbmV4dCgpIHtcbiAgICB0aGlzLnByZXZpZXdTZXJ2aWNlLm5leHQoKTtcbiAgfVxuXG4gIGNhblNob3dQcmV2aW91cygpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMucHJldmlld1NlcnZpY2Uuc3RhdGU7XG4gICAgcmV0dXJuIHN0YXRlLmN1cnJlbnRJbmRleCA+IDA7XG4gIH1cblxuICBjYW5TaG93TmV4dCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMucHJldmlld1NlcnZpY2Uuc3RhdGU7XG4gICAgcmV0dXJuIHN0YXRlLmN1cnJlbnRJbmRleCA8IHN0YXRlLmZpbGVzLmxlbmd0aCAtIDE7XG4gIH1cblxuICBnZXRDdXJyZW50RmlsZUluZm8oKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMucHJldmlld1NlcnZpY2Uuc3RhdGU7XG4gICAgcmV0dXJuIGAke3N0YXRlLmN1cnJlbnRJbmRleCArIDF9IC8gJHtzdGF0ZS5maWxlcy5sZW5ndGh9YDtcbiAgfVxuXG4gIGdldCBoYXNNdWx0aXBsZUZpbGVzKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5wcmV2aWV3U2VydmljZS5zdGF0ZTtcbiAgICByZXR1cm4gKHN0YXRlLmZpbGVzPy5sZW5ndGggfHwgMCkgPiAxO1xuICB9XG5cbiAgaGFuZGxlTW91c2VNb3ZlKCkge1xuICAgIHRoaXMuaXNDb250cm9sc1Zpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgaWYgKHRoaXMuY29udHJvbHNUaW1lb3V0KSB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuY29udHJvbHNUaW1lb3V0KTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRyb2xzVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaGlkZUNvbnRyb2xzKCk7XG4gICAgfSwgdGhpcy5ISURFX0RFTEFZKTtcbiAgfVxuXG4gIGhpZGVDb250cm9scygpIHtcbiAgICB0aGlzLmlzQ29udHJvbHNWaXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICBpZiAodGhpcy5jb250cm9sc1RpbWVvdXQpIHtcbiAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5jb250cm9sc1RpbWVvdXQpO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVRoZW1lKCkge1xuICAgIHRoaXMudGhlbWVTZXJ2aWNlLnRvZ2dsZVRoZW1lKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJuZnAtbW9kYWxfX292ZXJsYXlcIiAqbmdJZj1cImlzVmlzaWJsZVwiIChjbGljayk9XCJjbG9zZSgpXCI+XG4gIDxkaXYgY2xhc3M9XCJuZnAtbW9kYWxfX2NvbnRlbnRcIlxuICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgIChtb3VzZW1vdmUpPVwiaGFuZGxlTW91c2VNb3ZlKClcIlxuICAgICAgIChtb3VzZWxlYXZlKT1cImhpZGVDb250cm9scygpXCI+XG4gICAgPGRpdiBjbGFzcz1cIm5mcC1tb2RhbF9faGVhZGVyXCIgW2NsYXNzLm5mcC1tb2RhbF9faGVhZGVyLS1tdWx0aXBsZV09XCJoYXNNdWx0aXBsZUZpbGVzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibmZwLW1vZGFsX19oZWFkZXItbGVmdFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm5mcC1tb2RhbF9fZmlsZW5hbWVcIj57eyBjdXJyZW50RmlsZT8ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZnAtbW9kYWxfX2ZpbGVpbmRleFwiICpuZ0lmPVwiaGFzTXVsdGlwbGVGaWxlc1wiPnt7IGdldEN1cnJlbnRGaWxlSW5mbygpIH19PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibmZwLW1vZGFsX19oZWFkZXItcmlnaHRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm5mcC1tb2RhbF9fdGhlbWUtdG9nZ2xlXCIgKGNsaWNrKT1cInRvZ2dsZVRoZW1lKClcIj5cbiAgICAgICAgIDxuZ3gtdGhlbWUtaWNvbiBbdGhlbWVNb2RlXT1cInRoZW1lJHxhc3luY1wiPjwvbmd4LXRoZW1lLWljb24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cHJldmlldy1pY29uIGN1cnNvcj1cInBvaW50ZXJcIiBuYW1lPVwiY2xvc2VcIiBbdGhlbWVNb2RlXT1cInRoZW1lJHxhc3luY1wiIChjbGljayk9XCJjbG9zZSgpXCI+PC9wcmV2aWV3LWljb24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibmZwLW1vZGFsX19ib2R5XCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwibmZwLW1vZGFsX19uYXYtYnRuIG5mcC1tb2RhbF9fbmF2LWJ0bi0tcHJldlwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiY2FuU2hvd1ByZXZpb3VzKClcIlxuICAgICAgICAgICAgICBbY2xhc3MubmZwLW1vZGFsX19uYXYtYnRuLS12aXNpYmxlXT1cImlzQ29udHJvbHNWaXNpYmxlXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInByZXZpb3VzKClcIj5cbiAgICAgICAgPHByZXZpZXctaWNvbiBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiIFtzaXplXT1cIjM2XCIgbmFtZT1cInByZXZpb3VzXCI+PC9wcmV2aWV3LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGRpdiBjbGFzcz1cIm5mcC1tb2RhbF9fcHJldmlld1wiPlxuICAgICAgICBAaWYobG9hZGluZyR8YXN5bmMpe1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJuZnAtbW9kYWxfX2xvYWRpbmctb3ZlcmxheVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbiAgICAgICAgICAgIDxzcGFuPnt7J2xvYWRpbmcnfGkxOG59fTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJjdXJyZW50RmlsZT8udHlwZVwiPlxuICAgICAgICAgIDxuZ3gtaW1hZ2UtcHJldmlld1xuICAgICAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIidpbWFnZSdcIlxuICAgICAgICAgICAgW2ZpbGVdPVwiY3VycmVudEZpbGUhXCJcbiAgICAgICAgICAgIFt0aGVtZU1vZGVdPVwidGhlbWUkfGFzeW5jXCJcbiAgICAgICAgICA+PC9uZ3gtaW1hZ2UtcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtdmlkZW8tcHJldmlld1xuICAgICAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIid2aWRlbydcIlxuICAgICAgICAgICAgW2ZpbGVdPVwiY3VycmVudEZpbGUhXCJcbiAgICAgICAgICAgIFt0aGVtZU1vZGVdPVwidGhlbWUkfGFzeW5jXCJcbiAgICAgICAgICA+PC9uZ3gtdmlkZW8tcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtcGRmLXByZXZpZXdcbiAgICAgICAgICAgICpuZ1N3aXRjaENhc2U9XCIncGRmJ1wiXG4gICAgICAgICAgICBbZmlsZV09XCJjdXJyZW50RmlsZSFcIlxuICAgICAgICAgICAgW3RoZW1lTW9kZV09XCJ0aGVtZSR8YXN5bmNcIlxuICAgICAgICAgID48L25neC1wZGYtcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtd29yZC1wcmV2aWV3XG4gICAgICAgICAgICAqbmdTd2l0Y2hDYXNlPVwiJ3dvcmQnXCJcbiAgICAgICAgICAgIFtmaWxlXT1cImN1cnJlbnRGaWxlIVwiXG4gICAgICAgICAgICBbdGhlbWVNb2RlXT1cInRoZW1lJHxhc3luY1wiXG4gICAgICAgICAgPjwvbmd4LXdvcmQtcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtZXhjZWwtcHJldmlld1xuICAgICAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIidleGNlbCdcIlxuICAgICAgICAgICAgW2ZpbGVdPVwiY3VycmVudEZpbGUhXCJcbiAgICAgICAgICAgIFt0aGVtZU1vZGVdPVwidGhlbWUkfGFzeW5jXCJcbiAgICAgICAgICA+PC9uZ3gtZXhjZWwtcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtcHB0LXByZXZpZXdcbiAgICAgICAgICAgICpuZ1N3aXRjaENhc2U9XCIncHB0J1wiXG4gICAgICAgICAgICBbZmlsZV09XCJjdXJyZW50RmlsZSFcIlxuICAgICAgICAgICAgW3RoZW1lTW9kZV09XCJ0aGVtZSR8YXN5bmNcIlxuICAgICAgICAgID48L25neC1wcHQtcHJldmlldz5cblxuICAgICAgICAgIDxuZ3gtdGV4dC1wcmV2aWV3XG4gICAgICAgICAgICAqbmdTd2l0Y2hDYXNlPVwiJ3R4dCdcIlxuICAgICAgICAgICAgW2ZpbGVdPVwiY3VycmVudEZpbGUhXCJcbiAgICAgICAgICAgIFt0aGVtZU1vZGVdPVwidGhlbWUkfGFzeW5jXCJcbiAgICAgICAgICA+PC9uZ3gtdGV4dC1wcmV2aWV3PlxuXG4gICAgICAgICAgPG5neC1tYXJrZG93bi1wcmV2aWV3XG4gICAgICAgICAgICAqbmdTd2l0Y2hDYXNlPVwiJ21hcmtkb3duJ1wiXG4gICAgICAgICAgICBbZmlsZV09XCJjdXJyZW50RmlsZSFcIlxuICAgICAgICAgICAgW3RoZW1lTW9kZV09XCJ0aGVtZSR8YXN5bmNcIlxuICAgICAgICAgID48L25neC1tYXJrZG93bi1wcmV2aWV3PlxuXG4gICAgICAgICAgPG5neC1hcmNoaXZlLXByZXZpZXdcbiAgICAgICAgICAgICpuZ1N3aXRjaENhc2U9XCInemlwJ1wiXG4gICAgICAgICAgICBbZmlsZV09XCJjdXJyZW50RmlsZSFcIlxuICAgICAgICAgICAgW3RoZW1lTW9kZV09XCJ0aGVtZSR8YXN5bmNcIlxuICAgICAgICAgID48L25neC1hcmNoaXZlLXByZXZpZXc+XG5cbiAgICAgICAgICA8bmd4LWF1ZGlvLXByZXZpZXdcbiAgICAgICAgICAgICpuZ1N3aXRjaENhc2U9XCInYXVkaW8nXCJcbiAgICAgICAgICAgIFtmaWxlXT1cImN1cnJlbnRGaWxlIVwiXG4gICAgICAgICAgICBbdGhlbWVNb2RlXT1cInRoZW1lJHxhc3luY1wiXG4gICAgICAgICAgPjwvbmd4LWF1ZGlvLXByZXZpZXc+XG5cbiAgICAgICAgICA8bmd4LXVua25vd24tcHJldmlld1xuICAgICAgICAgICAgKm5nU3dpdGNoQ2FzZT1cIid1bmtub3duJ1wiXG4gICAgICAgICAgICBbZmlsZV09XCJjdXJyZW50RmlsZSFcIj5cbiAgICAgICAgICAgIFt0aGVtZU1vZGVdPVwidGhlbWUkfGFzeW5jXCJcbiAgICAgICAgICA8L25neC11bmtub3duLXByZXZpZXc+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJuZnAtbW9kYWxfX25hdi1idG4gbmZwLW1vZGFsX19uYXYtYnRuLS1uZXh0XCJcbiAgICAgICAgICAgICAgKm5nSWY9XCJjYW5TaG93TmV4dCgpXCJcbiAgICAgICAgICAgICAgW2NsYXNzLm5mcC1tb2RhbF9fbmF2LWJ0bi0tdmlzaWJsZV09XCJpc0NvbnRyb2xzVmlzaWJsZVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJuZXh0KClcIj5cbiAgICAgICAgPHByZXZpZXctaWNvbiBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiIFtzaXplXT1cIjM2XCIgbmFtZT1cIm5leHRcIj48L3ByZXZpZXctaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19