@aprova.ch/ngx-next-pdf-viewer 20.0.9 → 20.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,6 +28,16 @@ import * as pdfjsLib from 'pdfjs-dist';
28
28
  */
29
29
  const NGX_PDF_WORKER_SRC = new InjectionToken('NGX_PDF_WORKER_SRC', { factory: () => 'assets/pdf.worker.min.mjs' });
30
30
 
31
+ // ── RSA-2048 public key (SPKI DER, base64) ────────────────────────────────
32
+ // Generated with api-keys/generate.js. The matching private key lives in
33
+ // api-keys/private.key (never ship that file with the library).
34
+ const API_PUBLIC_KEY_B64 = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA32o40ciAzk12XQ7RQpjy' +
35
+ 'YUa22NNDh4jlntE8UPls2PDZLcSTORMyZTASnXzzUq4RodplBaySFbQUHNwYzYYT' +
36
+ 'H8+/GZPInigDqpVVJ+8sHiI+5jA9b4hl6alGzBmnSKaGnJYxy9DnUG/NM5cGK6+' +
37
+ 'MaZJrnjKrrWjQ2ttkuXRmDHLwcvfva06Lv8BEBDmbt1dVnTGPjwUjJelZeu5xVZU' +
38
+ 'gm9QlbhVR0P+vUM11jWzoq7W1bzyoDuToqZ+tQCLSVZ7Pz8FdHn3Wh/Qnw/VhqW' +
39
+ 'IeaHTgswOB1Cti0Oh1o+tpuv3LgIeGyZxyudnWnkDInQ2LvCP9z8aLVI9io/RA3a' +
40
+ 'PiwwIDAQAB';
31
41
  // ──────────────────────────────────────────────
32
42
  // Component
33
43
  // ──────────────────────────────────────────────
@@ -135,6 +145,9 @@ class NgxNextPdfViewerComponent {
135
145
  // ── Loading ──────────────────────────────────
136
146
  this.loading = false;
137
147
  this.loadError = false;
148
+ // ── API-key state ────────────────────────────
149
+ /** True once the current apiKey has been verified against the embedded public key. */
150
+ this.apiKeyValid = false;
138
151
  this.renderTasks = new Map();
139
152
  this.textLayers = new Map();
140
153
  pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;
@@ -156,6 +169,15 @@ class NgxNextPdfViewerComponent {
156
169
  });
157
170
  }
158
171
  ngOnChanges(changes) {
172
+ if (changes['apiKey']) {
173
+ this.apiKeyValid = false;
174
+ if (this.apiKey) {
175
+ this.verifyApiKey(this.apiKey).then(valid => {
176
+ this.apiKeyValid = valid;
177
+ this.cdr.detectChanges();
178
+ });
179
+ }
180
+ }
159
181
  if (changes['blob'] && this.blob) {
160
182
  console.log('load new file');
161
183
  this.loadPdf(this.blob);
@@ -176,6 +198,54 @@ class NgxNextPdfViewerComponent {
176
198
  this.pdfDoc?.destroy();
177
199
  }
178
200
  // ─────────────────────────────────────────────
201
+ // API-key verification (Web Crypto API)
202
+ // ─────────────────────────────────────────────
203
+ /** Decodes a base64url string to a Uint8Array (no external dependencies). */
204
+ b64urlToBytes(b64url) {
205
+ const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/');
206
+ const padded = b64.padEnd(b64.length + (4 - (b64.length % 4)) % 4, '=');
207
+ return Uint8Array.from(atob(padded), c => c.charCodeAt(0));
208
+ }
209
+ /**
210
+ * Verifies an API key against the embedded RSA-2048 public key.
211
+ * Format: <payload_base64url>.<signature_base64url>
212
+ *
213
+ * Returns false when:
214
+ * - the format is invalid
215
+ * - the RSA signature does not match
216
+ * - the key type is "trial" and its expiry timestamp has passed
217
+ */
218
+ async verifyApiKey(key) {
219
+ try {
220
+ const dotIndex = key.lastIndexOf('.');
221
+ if (dotIndex < 1)
222
+ return false;
223
+ const payloadB64 = key.slice(0, dotIndex);
224
+ const sigB64 = key.slice(dotIndex + 1);
225
+ // Import the embedded public key (SPKI DER, standard base64 → CryptoKey)
226
+ const derBytes = Uint8Array.from(atob(API_PUBLIC_KEY_B64), c => c.charCodeAt(0));
227
+ const cryptoKey = await crypto.subtle.importKey('spki', derBytes, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['verify']);
228
+ // Verify RSA signature (computed over the UTF-8 bytes of the payload string)
229
+ const data = new TextEncoder().encode(payloadB64);
230
+ const sig = this.b64urlToBytes(sigB64);
231
+ const signatureValid = await crypto.subtle.verify('RSASSA-PKCS1-v1_5', cryptoKey, sig, data);
232
+ if (!signatureValid)
233
+ return false;
234
+ // Decode payload and check expiry for trial keys
235
+ const payloadJson = atob(payloadB64.replace(/-/g, '+').replace(/_/g, '/')
236
+ .padEnd(payloadB64.length + (4 - (payloadB64.length % 4)) % 4, '='));
237
+ const payload = JSON.parse(payloadJson);
238
+ if (payload.type === 'trial' && payload.expires != null) {
239
+ if (Date.now() > payload.expires)
240
+ return false; // trial key expired
241
+ }
242
+ return true;
243
+ }
244
+ catch {
245
+ return false;
246
+ }
247
+ }
248
+ // ─────────────────────────────────────────────
179
249
  // PDF loading & rendering
180
250
  // ─────────────────────────────────────────────
181
251
  async loadPdf(blob) {
@@ -402,7 +472,9 @@ class NgxNextPdfViewerComponent {
402
472
  const wasSelected = this.clickedBoxKey === key;
403
473
  this.clickedBoxKey = wasSelected ? null : key;
404
474
  this.cdr.detectChanges();
405
- this.boxClicked.emit({ box, selected: !wasSelected });
475
+ if (this.apiKeyValid) {
476
+ this.boxClicked.emit({ box, selected: !wasSelected });
477
+ }
406
478
  }
407
479
  // ─────────────────────────────────────────────
408
480
  // Drag-select
@@ -477,7 +549,9 @@ class NgxNextPdfViewerComponent {
477
549
  onContextMenuAction(item) {
478
550
  this.ctxVisible = false;
479
551
  const selected = this.annotations.filter(b => this.multiSelectedKeys.has(this.boxKey(b)));
480
- this.boxesSelected.emit({ boxes: selected, action: item.action });
552
+ if (this.apiKeyValid) {
553
+ this.boxesSelected.emit({ boxes: selected, action: item.action });
554
+ }
481
555
  this.multiSelectedKeys.clear();
482
556
  this.cdr.detectChanges();
483
557
  }
@@ -632,7 +706,9 @@ class NgxNextPdfViewerComponent {
632
706
  this.clickedBoxKey = this.boxKey(box);
633
707
  this.cdr.detectChanges();
634
708
  this.scrollToBox(box);
635
- this.boxClicked.emit({ box, selected: true });
709
+ if (this.apiKeyValid) {
710
+ this.boxClicked.emit({ box, selected: true });
711
+ }
636
712
  }
637
713
  // ─────────────────────────────────────────────
638
714
  // Toolbar – selection mode
@@ -744,7 +820,7 @@ class NgxNextPdfViewerComponent {
744
820
  }
745
821
  }
746
822
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxNextPdfViewerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: NGX_PDF_WORKER_SRC }], target: i0.ɵɵFactoryTarget.Component }); }
747
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: NgxNextPdfViewerComponent, isStandalone: true, selector: "ngx-next-pdf-viewer", inputs: { blob: "blob", annotations: "annotations", contextMenuItems: "contextMenuItems", highlightingColor: "highlightingColor", selectedColor: "selectedColor", annotationStroke: "annotationStroke", initialZoom: "initialZoom", labels: "labels", showZoom: "showZoom", showRotation: "showRotation", showPageNavigation: "showPageNavigation", showAnnotationNavigation: "showAnnotationNavigation", showSelectionMode: "showSelectionMode", showSearch: "showSearch" }, outputs: { boxClicked: "boxClicked", boxesSelected: "boxesSelected" }, host: { listeners: { "mousemove": "onDocMouseMove($event)", "mouseup": "onDocMouseUp($event)", "document:click": "onDocClick()" } }, viewQueries: [{ propertyName: "pdfContainer", first: true, predicate: ["pdfContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"npv-root\">\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-toolbar\">\n\n <!-- Zoom -->\n <ng-container *ngIf=\"showZoom\">\n <button mat-icon-button [matTooltip]=\"l.zoomOut\" (click)=\"zoomOut()\" [disabled]=\"zoom <= 0.25\">\n <mat-icon>zoom_out</mat-icon>\n </button>\n <span class=\"npv-label\">{{ zoomPercent }}%</span>\n <button mat-icon-button [matTooltip]=\"l.zoomIn\" (click)=\"zoomIn()\" [disabled]=\"zoom >= 5\">\n <mat-icon>zoom_in</mat-icon>\n </button>\n </ng-container>\n\n <!-- Rotation -->\n <ng-container *ngIf=\"showRotation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom\"></div>\n <button mat-icon-button [matTooltip]=\"l.rotateLeft\" (click)=\"rotateLeft()\">\n <mat-icon>rotate_left</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.rotateRight\" (click)=\"rotateRight()\">\n <mat-icon>rotate_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Page navigation -->\n <ng-container *ngIf=\"showPageNavigation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousPage\" (click)=\"goToPrevPage()\" [disabled]=\"currentPage <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <span class=\"npv-label\">{{ currentPage }} / {{ totalPages }}</span>\n <button mat-icon-button [matTooltip]=\"l.nextPage\" (click)=\"goToNextPage()\" [disabled]=\"currentPage >= totalPages\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Annotation navigation -->\n <ng-container *ngIf=\"showAnnotationNavigation && annotations.length\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousAnnotation\" (click)=\"goToPrevAnnotation()\">\n <mat-icon>navigate_before</mat-icon>\n </button>\n <span class=\"npv-label\">\n {{ annotationIndex >= 0 ? annotationIndex + 1 : '\u2013' }} / {{ annotations.length }}\n </span>\n <button mat-icon-button [matTooltip]=\"l.nextAnnotation\" (click)=\"goToNextAnnotation()\">\n <mat-icon>navigate_next</mat-icon>\n </button>\n </ng-container>\n\n <!-- Selection mode toggle -->\n <ng-container *ngIf=\"showSelectionMode\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0)\"></div>\n <button mat-icon-button\n [matTooltip]=\"selectionMode === 'select-area' ? l.selectText : l.selectArea\"\n (click)=\"toggleSelectionMode()\"\n [class.npv-active]=\"selectionMode === 'select-text'\">\n <mat-icon>text_fields</mat-icon>\n </button>\n </ng-container>\n\n <!-- Search -->\n <ng-container *ngIf=\"showSearch\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0) || showSelectionMode\"></div>\n <button mat-icon-button [matTooltip]=\"l.search\" (click)=\"toggleSearch()\" [class.npv-active]=\"searchVisible\">\n <mat-icon>search</mat-icon>\n </button>\n <ng-container *ngIf=\"searchVisible\">\n <input\n class=\"npv-search-input\"\n type=\"text\"\n [placeholder]=\"l.searchPlaceholder\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchInput()\"\n (keydown.enter)=\"searchNext()\"\n (keydown.shift.enter)=\"searchPrev()\"\n autofocus\n />\n <button mat-icon-button [matTooltip]=\"l.previousResult\"\n (click)=\"searchPrev()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_less</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.nextResult\"\n (click)=\"searchNext()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_more</mat-icon>\n </button>\n <span class=\"npv-search-count\" *ngIf=\"searchMatches.length\">\n {{ searchIndex + 1 }} / {{ searchMatches.length }}\n </span>\n <span class=\"npv-search-count npv-no-match\" *ngIf=\"searchQuery && !searchMatches.length\">\n {{ l.noResults }}\n </span>\n </ng-container>\n </ng-container>\n\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-loading\" *ngIf=\"loading\">\n <span class=\"npv-spinner\"></span> {{ l.loading }}\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Scroll area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-scroll-area\" #pdfContainer\n (scroll)=\"onContainerScroll()\" (click)=\"ctxVisible = false\">\n <div class=\"npv-scroll-inner\">\n\n <ng-container *ngFor=\"let p of pageRange()\">\n <div class=\"npv-page-wrapper\" [id]=\"'npv-page-' + p\">\n\n <canvas [id]=\"'npv-canvas-' + p\" class=\"npv-canvas\"></canvas>\n\n <svg *ngIf=\"getPageInfo(p) as pi\"\n [id]=\"'npv-svg-' + p\"\n class=\"npv-overlay\"\n [class.npv-overlay--text-mode]=\"selectionMode === 'select-text'\"\n [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n [attr.viewBox]=\"'0 0 ' + pi.width + ' ' + pi.height\"\n (mousedown)=\"onSvgMouseDown($event, p)\">\n\n <!-- Hit area for drag selection on empty page space -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n fill=\"transparent\"></rect>\n\n <!-- Annotation boxes -->\n <polygon\n *ngFor=\"let box of getBoxesForPage(p)\"\n [attr.points]=\"getSvgPoints(box, pi)\"\n class=\"npv-box\"\n [class.npv-box--clicked]=\"isClicked(box)\"\n [class.npv-box--multi]=\"isMultiSelected(box)\"\n [style.fill]=\"isClicked(box) ? highlightingColor : (isMultiSelected(box) ? selectedColor : 'transparent')\"\n [style.stroke]=\"annotationStroke\"\n (click)=\"onBoxClick($event, box)\">\n <title>{{ box.content || '' }}</title>\n </polygon>\n\n <!-- Search highlights -->\n <polygon\n *ngFor=\"let m of getSearchMatchesForPage(p); let mi = index\"\n [attr.points]=\"searchMatchPoints(m)\"\n class=\"npv-search-highlight\"\n [class.npv-search-highlight--current]=\"isCurrentSearchMatch(p, mi)\">\n </polygon>\n\n <!-- Drag selection rectangle -->\n <rect *ngIf=\"getDragRect(p) as dr\"\n [attr.x]=\"dr.x\" [attr.y]=\"dr.y\"\n [attr.width]=\"dr.w\" [attr.height]=\"dr.h\"\n class=\"npv-drag-rect\">\n </rect>\n\n </svg>\n </div>\n </ng-container>\n\n <div class=\"npv-placeholder npv-placeholder--error\" *ngIf=\"!loading && loadError\">\n {{ l.loadError }}\n </div>\n <div class=\"npv-placeholder\" *ngIf=\"!loading && !loadError && totalPages === 0\">\n {{ l.noDocument }}\n </div>\n\n </div><!-- /npv-scroll-inner -->\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Context menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div *ngIf=\"ctxVisible && contextMenuItems.length\"\n class=\"npv-context-menu\"\n [style.left.px]=\"ctxX\" [style.top.px]=\"ctxY\"\n (click)=\"$event.stopPropagation()\">\n <div *ngFor=\"let item of contextMenuItems\"\n class=\"npv-context-item\"\n (click)=\"onContextMenuAction(item)\">\n {{ item.label }}\n </div>\n </div>\n\n</div>\n", styles: [".npv-root{display:flex;flex-direction:column;height:100%;overflow:hidden;background:#e9ecee;position:relative;font-family:Roboto,sans-serif}.npv-toolbar{display:flex;align-items:center;gap:2px;padding:4px 8px;background:#fff;color:#000;min-height:48px;flex-shrink:0;z-index:10;box-shadow:0 2px 4px #0006}.npv-toolbar button{color:#505050}.npv-toolbar button:hover:not([disabled]){background:#0000000f}.npv-toolbar button[disabled]{opacity:.35}.npv-toolbar button.npv-active{color:#1976d2;background:#e3f0fd;box-shadow:inset 0 2px 4px #00000026}.npv-toolbar button.npv-active:hover:not([disabled]){background:#cce0fa}.npv-toolbar .npv-sep{width:1px;height:24px;background:#00000026;margin:0 4px}.npv-toolbar .npv-label{font-size:13px;min-width:50px;text-align:center;color:#505050;-webkit-user-select:none;user-select:none}.npv-toolbar .npv-search-input{background:#0000000f;border:1px solid rgba(0,0,0,.2);border-radius:4px;color:#000;font-size:13px;padding:4px 8px;outline:none;width:180px}.npv-toolbar .npv-search-input::placeholder{color:#0006}.npv-toolbar .npv-search-input:focus{border-color:#1976d2}.npv-toolbar .npv-search-count{font-size:12px;color:#607d8b;white-space:nowrap;min-width:60px}.npv-toolbar .npv-search-count.npv-no-match{color:#e53935}.npv-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:16px;color:#666;font-size:14px;flex-shrink:0}.npv-spinner{width:20px;height:20px;border:3px solid rgba(0,0,0,.1);border-top-color:#1976d2;border-radius:50%;animation:npv-spin .8s linear infinite}@keyframes npv-spin{to{transform:rotate(360deg)}}.npv-scroll-area{flex:1;overflow:auto}.npv-scroll-inner{display:flex;flex-direction:column;align-items:center;min-width:max-content;padding:16px;gap:16px}.npv-page-wrapper{position:relative;display:inline-block;box-shadow:0 4px 12px #00000080;line-height:0}.npv-canvas{display:block}.npv-overlay{position:absolute;top:0;left:0;pointer-events:all;overflow:visible;cursor:crosshair;user-select:none;-webkit-user-select:none}.npv-overlay.npv-overlay--text-mode{pointer-events:none}.npv-box{pointer-events:all;stroke-width:2;fill:transparent;cursor:pointer;transition:fill .15s ease,stroke-width .15s ease}.npv-box:hover{stroke-width:3;filter:drop-shadow(0 0 3px rgba(233,115,50,.7))}.npv-box.npv-box--clicked{stroke-width:3}.npv-box.npv-box--multi{stroke-width:2.5}.npv-search-highlight{fill:#ffeb3b59;stroke:#ffc800cc;stroke-width:1.5;pointer-events:none}.npv-search-highlight.npv-search-highlight--current{fill:#ff980073;stroke:#ff6400e6;stroke-width:2}.npv-drag-rect{fill:#0078d71a;stroke:#0078d7b3;stroke-width:1.5;stroke-dasharray:5 3;pointer-events:none}.npv-placeholder{color:#aaa;font-size:14px;padding:40px;text-align:center}.npv-placeholder.npv-placeholder--error{color:#e53935}.npv-context-menu{position:fixed;z-index:9999;background:#fff;border:1px solid rgba(0,0,0,.12);border-radius:4px;box-shadow:0 4px 16px #0003;padding:4px 0;min-width:160px}.npv-context-item{padding:10px 16px;font-size:14px;cursor:pointer;color:#000000de;-webkit-user-select:none;user-select:none}.npv-context-item:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatFormFieldModule }] }); }
823
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: NgxNextPdfViewerComponent, isStandalone: true, selector: "ngx-next-pdf-viewer", inputs: { blob: "blob", annotations: "annotations", contextMenuItems: "contextMenuItems", highlightingColor: "highlightingColor", selectedColor: "selectedColor", annotationStroke: "annotationStroke", initialZoom: "initialZoom", labels: "labels", showZoom: "showZoom", showRotation: "showRotation", showPageNavigation: "showPageNavigation", showAnnotationNavigation: "showAnnotationNavigation", showSelectionMode: "showSelectionMode", showSearch: "showSearch", apiKey: "apiKey" }, outputs: { boxClicked: "boxClicked", boxesSelected: "boxesSelected" }, host: { listeners: { "mousemove": "onDocMouseMove($event)", "mouseup": "onDocMouseUp($event)", "document:click": "onDocClick()" } }, viewQueries: [{ propertyName: "pdfContainer", first: true, predicate: ["pdfContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"npv-root\">\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-toolbar\">\n\n <!-- Zoom -->\n <ng-container *ngIf=\"showZoom\">\n <button mat-icon-button [matTooltip]=\"l.zoomOut\" (click)=\"zoomOut()\" [disabled]=\"zoom <= 0.25\">\n <mat-icon>zoom_out</mat-icon>\n </button>\n <span class=\"npv-label\">{{ zoomPercent }}%</span>\n <button mat-icon-button [matTooltip]=\"l.zoomIn\" (click)=\"zoomIn()\" [disabled]=\"zoom >= 5\">\n <mat-icon>zoom_in</mat-icon>\n </button>\n </ng-container>\n\n <!-- Rotation -->\n <ng-container *ngIf=\"showRotation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom\"></div>\n <button mat-icon-button [matTooltip]=\"l.rotateLeft\" (click)=\"rotateLeft()\">\n <mat-icon>rotate_left</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.rotateRight\" (click)=\"rotateRight()\">\n <mat-icon>rotate_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Page navigation -->\n <ng-container *ngIf=\"showPageNavigation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousPage\" (click)=\"goToPrevPage()\" [disabled]=\"currentPage <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <span class=\"npv-label\">{{ currentPage }} / {{ totalPages }}</span>\n <button mat-icon-button [matTooltip]=\"l.nextPage\" (click)=\"goToNextPage()\" [disabled]=\"currentPage >= totalPages\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Annotation navigation -->\n <ng-container *ngIf=\"showAnnotationNavigation && annotations.length\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousAnnotation\" (click)=\"goToPrevAnnotation()\">\n <mat-icon>navigate_before</mat-icon>\n </button>\n <span class=\"npv-label\">\n {{ annotationIndex >= 0 ? annotationIndex + 1 : '\u2013' }} / {{ annotations.length }}\n </span>\n <button mat-icon-button [matTooltip]=\"l.nextAnnotation\" (click)=\"goToNextAnnotation()\">\n <mat-icon>navigate_next</mat-icon>\n </button>\n </ng-container>\n\n <!-- Selection mode toggle -->\n <ng-container *ngIf=\"showSelectionMode\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0)\"></div>\n <button mat-icon-button\n [matTooltip]=\"selectionMode === 'select-area' ? l.selectText : l.selectArea\"\n (click)=\"toggleSelectionMode()\"\n [class.npv-active]=\"selectionMode === 'select-text'\">\n <mat-icon>text_fields</mat-icon>\n </button>\n </ng-container>\n\n <!-- Search -->\n <ng-container *ngIf=\"showSearch\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0) || showSelectionMode\"></div>\n <button mat-icon-button [matTooltip]=\"l.search\" (click)=\"toggleSearch()\" [class.npv-active]=\"searchVisible\">\n <mat-icon>search</mat-icon>\n </button>\n <ng-container *ngIf=\"searchVisible\">\n <input\n class=\"npv-search-input\"\n type=\"text\"\n [placeholder]=\"l.searchPlaceholder\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchInput()\"\n (keydown.enter)=\"searchNext()\"\n (keydown.shift.enter)=\"searchPrev()\"\n autofocus\n />\n <button mat-icon-button [matTooltip]=\"l.previousResult\"\n (click)=\"searchPrev()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_less</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.nextResult\"\n (click)=\"searchNext()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_more</mat-icon>\n </button>\n <span class=\"npv-search-count\" *ngIf=\"searchMatches.length\">\n {{ searchIndex + 1 }} / {{ searchMatches.length }}\n </span>\n <span class=\"npv-search-count npv-no-match\" *ngIf=\"searchQuery && !searchMatches.length\">\n {{ l.noResults }}\n </span>\n </ng-container>\n </ng-container>\n\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-loading\" *ngIf=\"loading\">\n <span class=\"npv-spinner\"></span> {{ l.loading }}\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Scroll area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div class=\"npv-scroll-area\" #pdfContainer\n (scroll)=\"onContainerScroll()\" (click)=\"ctxVisible = false\">\n <div class=\"npv-scroll-inner\">\n\n <ng-container *ngFor=\"let p of pageRange()\">\n <div class=\"npv-page-wrapper\" [id]=\"'npv-page-' + p\">\n\n <canvas [id]=\"'npv-canvas-' + p\" class=\"npv-canvas\"></canvas>\n\n <svg *ngIf=\"getPageInfo(p) as pi\"\n [id]=\"'npv-svg-' + p\"\n class=\"npv-overlay\"\n [class.npv-overlay--text-mode]=\"selectionMode === 'select-text'\"\n [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n [attr.viewBox]=\"'0 0 ' + pi.width + ' ' + pi.height\"\n (mousedown)=\"onSvgMouseDown($event, p)\">\n\n <!-- Hit area for drag selection on empty page space -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n fill=\"transparent\"></rect>\n\n <!-- Annotation boxes -->\n <polygon\n *ngFor=\"let box of getBoxesForPage(p)\"\n [attr.points]=\"getSvgPoints(box, pi)\"\n class=\"npv-box\"\n [class.npv-box--clicked]=\"isClicked(box)\"\n [class.npv-box--multi]=\"isMultiSelected(box)\"\n [style.fill]=\"isClicked(box) ? highlightingColor : (isMultiSelected(box) ? selectedColor : 'transparent')\"\n [style.stroke]=\"annotationStroke\"\n (click)=\"onBoxClick($event, box)\">\n <title>{{ box.content || '' }}</title>\n </polygon>\n\n <!-- Search highlights -->\n <polygon\n *ngFor=\"let m of getSearchMatchesForPage(p); let mi = index\"\n [attr.points]=\"searchMatchPoints(m)\"\n class=\"npv-search-highlight\"\n [class.npv-search-highlight--current]=\"isCurrentSearchMatch(p, mi)\">\n </polygon>\n\n <!-- Drag selection rectangle -->\n <rect *ngIf=\"getDragRect(p) as dr\"\n [attr.x]=\"dr.x\" [attr.y]=\"dr.y\"\n [attr.width]=\"dr.w\" [attr.height]=\"dr.h\"\n class=\"npv-drag-rect\">\n </rect>\n\n </svg>\n </div>\n </ng-container>\n\n <div class=\"npv-placeholder npv-placeholder--error\" *ngIf=\"!loading && loadError\">\n {{ l.loadError }}\n </div>\n <div class=\"npv-placeholder\" *ngIf=\"!loading && !loadError && totalPages === 0\">\n {{ l.noDocument }}\n </div>\n\n </div><!-- /npv-scroll-inner -->\n </div>\n\n <!-- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Context menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <div *ngIf=\"ctxVisible && contextMenuItems.length\"\n class=\"npv-context-menu\"\n [style.left.px]=\"ctxX\" [style.top.px]=\"ctxY\"\n (click)=\"$event.stopPropagation()\">\n <div *ngFor=\"let item of contextMenuItems\"\n class=\"npv-context-item\"\n (click)=\"onContextMenuAction(item)\">\n {{ item.label }}\n </div>\n </div>\n\n</div>\n", styles: [".npv-root{display:flex;flex-direction:column;height:100%;overflow:hidden;background:#e9ecee;position:relative;font-family:Roboto,sans-serif}.npv-toolbar{display:flex;align-items:center;gap:2px;padding:4px 8px;background:#fff;color:#000;min-height:48px;flex-shrink:0;z-index:10;box-shadow:0 2px 4px #0006}.npv-toolbar button{color:#505050}.npv-toolbar button:hover:not([disabled]){background:#0000000f}.npv-toolbar button[disabled]{opacity:.35}.npv-toolbar button.npv-active{color:#1976d2;background:#e3f0fd;box-shadow:inset 0 2px 4px #00000026}.npv-toolbar button.npv-active:hover:not([disabled]){background:#cce0fa}.npv-toolbar .npv-sep{width:1px;height:24px;background:#00000026;margin:0 4px}.npv-toolbar .npv-label{font-size:13px;min-width:50px;text-align:center;color:#505050;-webkit-user-select:none;user-select:none}.npv-toolbar .npv-search-input{background:#0000000f;border:1px solid rgba(0,0,0,.2);border-radius:4px;color:#000;font-size:13px;padding:4px 8px;outline:none;width:180px}.npv-toolbar .npv-search-input::placeholder{color:#0006}.npv-toolbar .npv-search-input:focus{border-color:#1976d2}.npv-toolbar .npv-search-count{font-size:12px;color:#607d8b;white-space:nowrap;min-width:60px}.npv-toolbar .npv-search-count.npv-no-match{color:#e53935}.npv-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:16px;color:#666;font-size:14px;flex-shrink:0}.npv-spinner{width:20px;height:20px;border:3px solid rgba(0,0,0,.1);border-top-color:#1976d2;border-radius:50%;animation:npv-spin .8s linear infinite}@keyframes npv-spin{to{transform:rotate(360deg)}}.npv-scroll-area{flex:1;overflow:auto}.npv-scroll-inner{display:flex;flex-direction:column;align-items:center;min-width:max-content;padding:16px;gap:16px}.npv-page-wrapper{position:relative;display:inline-block;box-shadow:0 4px 12px #00000080;line-height:0}.npv-canvas{display:block}.npv-overlay{position:absolute;top:0;left:0;pointer-events:all;overflow:visible;cursor:crosshair;user-select:none;-webkit-user-select:none}.npv-overlay.npv-overlay--text-mode{pointer-events:none}.npv-box{pointer-events:all;stroke-width:2;fill:transparent;cursor:pointer;transition:fill .15s ease,stroke-width .15s ease}.npv-box:hover{stroke-width:3;filter:drop-shadow(0 0 3px rgba(233,115,50,.7))}.npv-box.npv-box--clicked{stroke-width:3}.npv-box.npv-box--multi{stroke-width:2.5}.npv-search-highlight{fill:#ffeb3b59;stroke:#ffc800cc;stroke-width:1.5;pointer-events:none}.npv-search-highlight.npv-search-highlight--current{fill:#ff980073;stroke:#ff6400e6;stroke-width:2}.npv-drag-rect{fill:#0078d71a;stroke:#0078d7b3;stroke-width:1.5;stroke-dasharray:5 3;pointer-events:none}.npv-placeholder{color:#aaa;font-size:14px;padding:40px;text-align:center}.npv-placeholder.npv-placeholder--error{color:#e53935}.npv-context-menu{position:fixed;z-index:9999;background:#fff;border:1px solid rgba(0,0,0,.12);border-radius:4px;box-shadow:0 4px 16px #0003;padding:4px 0;min-width:160px}.npv-context-item{padding:10px 16px;font-size:14px;cursor:pointer;color:#000000de;-webkit-user-select:none;user-select:none}.npv-context-item:hover{background:#0000000d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatFormFieldModule }] }); }
748
824
  }
749
825
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxNextPdfViewerComponent, decorators: [{
750
826
  type: Component,
@@ -788,6 +864,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
788
864
  type: Input
789
865
  }], showSearch: [{
790
866
  type: Input
867
+ }], apiKey: [{
868
+ type: Input
791
869
  }], boxClicked: [{
792
870
  type: Output
793
871
  }], boxesSelected: [{
@@ -1 +1 @@
1
- {"version":3,"file":"aprova.ch-ngx-next-pdf-viewer.mjs","sources":["../../../projects/ngx-next-pdf-viewer/src/lib/tokens.ts","../../../projects/ngx-next-pdf-viewer/src/lib/ngx-next-pdf-viewer.component.ts","../../../projects/ngx-next-pdf-viewer/src/lib/ngx-next-pdf-viewer.component.html","../../../projects/ngx-next-pdf-viewer/src/aprova.ch-ngx-next-pdf-viewer.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * URL to the PDF.js worker script.\n *\n * Default: `'assets/pdf.worker.min.mjs'`\n *\n * Override in your application by providing this token:\n * ```ts\n * providers: [\n * { provide: NGX_PDF_WORKER_SRC, useValue: 'assets/pdf.worker.min.mjs' }\n * ]\n * ```\n */\nexport const NGX_PDF_WORKER_SRC = new InjectionToken<string>(\n 'NGX_PDF_WORKER_SRC',\n { factory: () => 'assets/pdf.worker.min.mjs' }\n);\n","import {\n Component, Input, Output, EventEmitter, Inject,\n OnChanges, OnDestroy, SimpleChanges,\n ViewChild, ElementRef, ChangeDetectorRef,\n HostListener, NgZone, AfterViewInit\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';\n\nimport { BoundingBox, ContextMenuItem, PdfViewerLabels, ZoomMode } from './models';\nimport { NGX_PDF_WORKER_SRC } from './tokens';\n\n// ──────────────────────────────────────────────\n// Internal helpers\n// ──────────────────────────────────────────────\n\ninterface RenderedPage {\n pageNum: number;\n width: number;\n height: number;\n rotation: number;\n}\n\ninterface DragState {\n active: boolean;\n pageNum: number;\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n}\n\ninterface SearchMatch {\n pageNum: number;\n polygon: number[];\n}\n\n// ──────────────────────────────────────────────\n// Component\n// ──────────────────────────────────────────────\n\n@Component({\n selector: 'ngx-next-pdf-viewer',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n MatIconModule,\n MatButtonModule,\n MatTooltipModule,\n MatInputModule,\n MatFormFieldModule\n ],\n templateUrl: './ngx-next-pdf-viewer.component.html',\n styleUrl: './ngx-next-pdf-viewer.component.scss'\n})\nexport class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterViewInit {\n\n // ── Inputs ──────────────────────────────────\n /** PDF file to display */\n @Input() blob: Blob | undefined;\n /** Bounding-box annotations to overlay */\n @Input() annotations: BoundingBox[] = [];\n /** Items shown in the context menu after drag-selecting boxes */\n @Input() contextMenuItems: ContextMenuItem[] = [];\n /** Fill colour for a single-clicked box (CSS colour string) */\n @Input() highlightingColor = 'rgba(255, 200, 0, 0.35)';\n /** Fill colour for drag-selected boxes (CSS colour string) */\n @Input() selectedColor = 'rgba(0, 120, 215, 0.35)';\n /** Stroke colour for all annotation polygons */\n @Input() annotationStroke = '#e97332';\n /** Initial zoom: numeric level (1.0 = 100 %) or 'fit-to-page' | 'fit-to-width' | 'fit-to-height' */\n @Input() initialZoom: ZoomMode = 1.5;\n /** Override any subset of the viewer's user-visible strings */\n @Input() labels: Partial<PdfViewerLabels> = {};\n /** Show / hide the zoom buttons and percentage label */\n @Input() showZoom = true;\n /** Show / hide the rotate-left and rotate-right buttons */\n @Input() showRotation = true;\n /** Show / hide the previous/next page buttons and page counter */\n @Input() showPageNavigation = true;\n /** Show / hide the previous/next annotation buttons and annotation counter */\n @Input() showAnnotationNavigation = true;\n /** Show / hide the select-area / select-text toggle button */\n @Input() showSelectionMode = true;\n /** Show / hide the search button and search bar */\n @Input() showSearch = true;\n\n private static readonly DEFAULT_LABELS: PdfViewerLabels = {\n zoomOut: 'Zoom out',\n zoomIn: 'Zoom in',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n previousPage: 'Previous page',\n nextPage: 'Next page',\n search: 'Search',\n previousResult: 'Previous result',\n nextResult: 'Next result',\n previousAnnotation: 'Previous annotation',\n nextAnnotation: 'Next annotation',\n selectArea: 'Select area',\n selectText: 'Select & copy text',\n searchPlaceholder: 'Search in PDF…',\n noResults: 'No results',\n loading: 'Loading PDF…',\n noDocument: 'No PDF loaded',\n loadError: 'Failed to load PDF',\n };\n\n get l(): PdfViewerLabels {\n return { ...NgxNextPdfViewerComponent.DEFAULT_LABELS, ...this.labels };\n }\n\n // ── Outputs ─────────────────────────────────\n /** Fired when the user clicks a single annotation box */\n @Output() boxClicked = new EventEmitter<{ box: BoundingBox; selected: boolean }>();\n /** Fired when the user picks a context-menu item after drag-selection */\n @Output() boxesSelected = new EventEmitter<{ boxes: BoundingBox[]; action: string }>();\n\n // ── View refs ────────────────────────────────\n @ViewChild('pdfContainer') pdfContainer!: ElementRef<HTMLDivElement>;\n\n // ── PDF state ────────────────────────────────\n pdfDoc: PDFDocumentProxy | null = null;\n renderedPages: RenderedPage[] = [];\n currentPage = 1;\n totalPages = 0;\n zoom = 1.5;\n userRotation = 0;\n\n // ── Annotation state ─────────────────────────\n clickedBoxKey: string | null = null;\n multiSelectedKeys: Set<string> = new Set();\n\n // ── Drag-select state ────────────────────────\n drag: DragState = { active: false, pageNum: 0, startX: 0, startY: 0, currentX: 0, currentY: 0 };\n\n // ── Context-menu state ───────────────────────\n ctxVisible = false;\n ctxX = 0;\n ctxY = 0;\n\n // ── Search state ─────────────────────────────\n searchVisible = false;\n searchQuery = '';\n searchMatches: SearchMatch[] = [];\n searchIndex = -1;\n\n // ── Selection mode ───────────────────────────\n selectionMode: 'select-area' | 'select-text' = 'select-area';\n\n // ── Loading ──────────────────────────────────\n loading = false;\n loadError = false;\n\n private renderTasks: Map<number, any> = new Map();\n private textLayers: Map<number, any> = new Map();\n private wheelListener?: (e: WheelEvent) => void;\n\n // ── One-time global CSS for the pdfjs text layer ─────────────────────────\n private static textLayerStylesInjected = false;\n\n private static injectTextLayerStyles(): void {\n if (NgxNextPdfViewerComponent.textLayerStylesInjected) return;\n const style = document.createElement('style');\n style.id = 'npv-text-layer-styles';\n style.textContent =\n '.textLayer{position:absolute;top:0;left:0;overflow:hidden;line-height:1;' +\n 'text-size-adjust:none;forced-color-adjust:none;transform-origin:0 0;z-index:0}' +\n '.textLayer :is(span,br){color:transparent;position:absolute;white-space:pre;' +\n 'cursor:text;transform-origin:0% 0%}' +\n '.textLayer>:not(.markedContent),' +\n '.textLayer .markedContent span:not(.markedContent){z-index:1}' +\n '.textLayer ::selection{background:rgba(0,120,215,.25);color:transparent}' +\n '.textLayer br::selection{background:transparent}';\n document.head.appendChild(style);\n NgxNextPdfViewerComponent.textLayerStylesInjected = true;\n }\n\n constructor(\n private cdr: ChangeDetectorRef,\n private zone: NgZone,\n private el: ElementRef,\n @Inject(NGX_PDF_WORKER_SRC) workerSrc: string\n ) {\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n NgxNextPdfViewerComponent.injectTextLayerStyles();\n }\n\n ngAfterViewInit(): void {\n if (typeof this.initialZoom === 'number') {\n this.zoom = this.initialZoom;\n }\n // Ctrl+scroll zooming – requires passive:false to call preventDefault()\n this.zone.runOutsideAngular(() => {\n this.wheelListener = (e: WheelEvent) => {\n if (!e.ctrlKey) return;\n e.preventDefault();\n this.zone.run(() => e.deltaY < 0 ? this.zoomIn() : this.zoomOut());\n };\n this.el.nativeElement.addEventListener('wheel', this.wheelListener, { passive: false });\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['blob'] && this.blob) {\n console.log('load new file');\n this.loadPdf(this.blob);\n }\n if (changes['annotations'] && !changes['blob']) {\n console.log('set new annotations', this.annotations.length);\n this.cdr.detectChanges();\n if (this.annotations.length === 1) {\n this.scrollToBox(this.annotations[0]);\n }\n }\n }\n\n ngOnDestroy(): void {\n if (this.wheelListener) {\n this.el.nativeElement.removeEventListener('wheel', this.wheelListener);\n }\n this.removeAllTextLayers();\n this.pdfDoc?.destroy();\n }\n\n // ─────────────────────────────────────────────\n // PDF loading & rendering\n // ─────────────────────────────────────────────\n\n private async loadPdf(blob: Blob): Promise<void> {\n this.loading = true;\n this.loadError = false;\n this.renderedPages = [];\n this.clickedBoxKey = null;\n this.multiSelectedKeys.clear();\n this.searchMatches = [];\n this.searchIndex = -1;\n this.removeAllTextLayers();\n this.cdr.detectChanges();\n\n try {\n this.pdfDoc?.destroy();\n const buf = await blob.arrayBuffer();\n this.pdfDoc = await pdfjsLib.getDocument({ data: buf }).promise;\n this.totalPages = this.pdfDoc.numPages;\n this.currentPage = 1;\n if (typeof this.initialZoom !== 'number') {\n this.zoom = await this.computeFitZoom(this.initialZoom);\n }\n this.loading = false;\n this.cdr.detectChanges();\n\n for (let p = 1; p <= this.totalPages; p++) {\n await this.renderPage(p);\n }\n\n if (this.annotations.length === 1) {\n this.scrollToBox(this.annotations[0]);\n }\n } catch {\n this.loading = false;\n this.loadError = true;\n }\n this.cdr.detectChanges();\n }\n\n private async computeFitZoom(mode: Exclude<ZoomMode, number>): Promise<number> {\n if (!this.pdfDoc) return 1;\n const page = await this.pdfDoc.getPage(1);\n const rotation = (page.rotate + this.userRotation) % 360;\n const vp = page.getViewport({ scale: 1, rotation });\n page.cleanup();\n\n const container = this.pdfContainer?.nativeElement;\n if (!container) return 1;\n\n // Subtract the 16 px padding on each side defined in npv-scroll-inner\n const availW = container.clientWidth - 32;\n const availH = container.clientHeight - 32;\n const scaleW = availW / vp.width;\n const scaleH = availH / vp.height;\n\n switch (mode) {\n case 'fit-to-width': return scaleW;\n case 'fit-to-height': return scaleH;\n case 'fit-to-page': return Math.min(scaleW, scaleH);\n }\n }\n\n private async renderPage(pageNum: number): Promise<void> {\n if (!this.pdfDoc) return;\n const page: PDFPageProxy = await this.pdfDoc.getPage(pageNum);\n const totalRotation = (page.rotate + this.userRotation) % 360;\n const viewport = page.getViewport({ scale: this.zoom, rotation: totalRotation });\n\n // HiDPI: render at physical pixel density, display at CSS size\n const dpr = window.devicePixelRatio || 1;\n const hiResViewport = page.getViewport({ scale: this.zoom * dpr, rotation: totalRotation });\n\n const canvas = document.getElementById(`npv-canvas-${pageNum}`) as HTMLCanvasElement | null;\n if (!canvas) return;\n\n canvas.width = hiResViewport.width;\n canvas.height = hiResViewport.height;\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n\n if (this.renderTasks.has(pageNum)) {\n try { this.renderTasks.get(pageNum).cancel(); } catch (_) {}\n }\n\n const ctx = canvas.getContext('2d')!;\n const task = page.render({ canvasContext: ctx, viewport: hiResViewport });\n this.renderTasks.set(pageNum, task);\n try {\n await task.promise;\n } catch (e: any) {\n if (e?.name !== 'RenderingCancelledException') console.error(e);\n return;\n }\n this.renderTasks.delete(pageNum);\n\n const existing = this.renderedPages.find(r => r.pageNum === pageNum);\n if (existing) {\n existing.width = viewport.width;\n existing.height = viewport.height;\n existing.rotation = totalRotation;\n } else {\n this.renderedPages.push({ pageNum, width: viewport.width, height: viewport.height, rotation: totalRotation });\n }\n this.cdr.detectChanges();\n page.cleanup();\n }\n\n private async rerenderAll(): Promise<void> {\n if (!this.pdfDoc) return;\n if (this.selectionMode === 'select-text') {\n this.removeAllTextLayers();\n }\n for (let p = 1; p <= this.totalPages; p++) {\n await this.renderPage(p);\n if (this.selectionMode === 'select-text') {\n await this.renderTextLayer(p);\n }\n }\n this.cdr.detectChanges();\n }\n\n // ─────────────────────────────────────────────\n // Coordinate transformation\n // ─────────────────────────────────────────────\n\n /** Converts a polygon (y=0 at top, any consistent unit) to SVG canvas coordinates */\n transformPolygon(\n polygon: number[],\n pdfWidth: number,\n pdfHeight: number,\n canvasWidth: number,\n canvasHeight: number,\n rotation: number\n ): number[] {\n const norm = ((rotation % 360) + 360) % 360;\n const result: number[] = [];\n for (let i = 0; i < polygon.length; i += 2) {\n const px = polygon[i];\n const py = polygon[i + 1];\n let cx: number, cy: number;\n switch (norm) {\n case 90:\n cx = (pdfHeight - py) * canvasWidth / pdfHeight;\n cy = px * canvasHeight / pdfWidth;\n break;\n case 180:\n cx = (pdfWidth - px) * canvasWidth / pdfWidth;\n cy = (pdfHeight - py) * canvasHeight / pdfHeight;\n break;\n case 270:\n cx = py * canvasWidth / pdfHeight;\n cy = (pdfWidth - px) * canvasHeight / pdfWidth;\n break;\n default:\n cx = px * canvasWidth / pdfWidth;\n cy = py * canvasHeight / pdfHeight;\n }\n result.push(cx, cy);\n }\n return result;\n }\n\n getSvgPoints(box: BoundingBox, pi: RenderedPage): string {\n const pts = this.transformPolygon(\n box.polygon, box.width, box.height, pi.width, pi.height, pi.rotation\n );\n const pairs: string[] = [];\n for (let i = 0; i < pts.length; i += 2) {\n pairs.push(`${pts[i].toFixed(2)},${pts[i + 1].toFixed(2)}`);\n }\n return pairs.join(' ');\n }\n\n private polygonBBox(pts: number[]): { x: number; y: number; w: number; h: number } {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (let i = 0; i < pts.length; i += 2) {\n minX = Math.min(minX, pts[i]); maxX = Math.max(maxX, pts[i]);\n minY = Math.min(minY, pts[i+1]); maxY = Math.max(maxY, pts[i+1]);\n }\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\n }\n\n private boxKey(box: BoundingBox): string {\n return JSON.stringify({ page: box.page, polygon: box.polygon });\n }\n\n // ─────────────────────────────────────────────\n // Template helpers\n // ─────────────────────────────────────────────\n\n getPageInfo(pageNum: number): RenderedPage | undefined {\n return this.renderedPages.find(r => r.pageNum === pageNum);\n }\n\n getBoxesForPage(pageNum: number): BoundingBox[] {\n return this.annotations.filter(b => b.page === pageNum);\n }\n\n isClicked(box: BoundingBox): boolean {\n return this.clickedBoxKey === this.boxKey(box);\n }\n\n isMultiSelected(box: BoundingBox): boolean {\n return this.multiSelectedKeys.has(this.boxKey(box));\n }\n\n pageRange(): number[] {\n return Array.from({ length: this.totalPages }, (_, i) => i + 1);\n }\n\n getDragRect(pageNum: number): { x: number; y: number; w: number; h: number } | null {\n if (!this.drag.active || this.drag.pageNum !== pageNum) return null;\n return {\n x: Math.min(this.drag.startX, this.drag.currentX),\n y: Math.min(this.drag.startY, this.drag.currentY),\n w: Math.abs(this.drag.currentX - this.drag.startX),\n h: Math.abs(this.drag.currentY - this.drag.startY)\n };\n }\n\n getSearchMatchesForPage(pageNum: number): SearchMatch[] {\n return this.searchMatches.filter(m => m.pageNum === pageNum);\n }\n\n getSearchIndexOffset(pageNum: number): number {\n return this.searchMatches.findIndex(m => m.pageNum === pageNum);\n }\n\n isCurrentSearchMatch(pageNum: number, localIndex: number): boolean {\n const offset = this.getSearchIndexOffset(pageNum);\n return offset >= 0 && offset + localIndex === this.searchIndex;\n }\n\n searchMatchPoints(m: SearchMatch): string {\n const pairs: string[] = [];\n for (let i = 0; i < m.polygon.length; i += 2) {\n pairs.push(`${m.polygon[i].toFixed(2)},${m.polygon[i + 1].toFixed(2)}`);\n }\n return pairs.join(' ');\n }\n\n // ─────────────────────────────────────────────\n // Box interaction\n // ─────────────────────────────────────────────\n\n onBoxClick(event: MouseEvent, box: BoundingBox): void {\n event.stopPropagation();\n this.ctxVisible = false;\n this.multiSelectedKeys.clear();\n const key = this.boxKey(box);\n const wasSelected = this.clickedBoxKey === key;\n this.clickedBoxKey = wasSelected ? null : key;\n this.cdr.detectChanges();\n this.boxClicked.emit({ box, selected: !wasSelected });\n }\n\n // ─────────────────────────────────────────────\n // Drag-select\n // ─────────────────────────────────────────────\n\n onSvgMouseDown(event: MouseEvent, pageNum: number): void {\n if (this.selectionMode === 'select-text') return;\n if (event.button !== 0) return;\n const tag = (event.target as Element).tagName?.toLowerCase();\n if (tag === 'polygon' || tag === 'title') return;\n this.ctxVisible = false;\n this.clickedBoxKey = null;\n const pt = this.svgPoint(event, pageNum);\n if (!pt) return;\n this.drag = { active: true, pageNum, startX: pt.x, startY: pt.y, currentX: pt.x, currentY: pt.y };\n }\n\n @HostListener('mousemove', ['$event'])\n onDocMouseMove(event: MouseEvent): void {\n if (!this.drag.active) return;\n const pt = this.svgPoint(event, this.drag.pageNum);\n if (!pt) return;\n this.drag.currentX = pt.x;\n this.drag.currentY = pt.y;\n this.cdr.detectChanges();\n }\n\n @HostListener('mouseup', ['$event'])\n onDocMouseUp(event: MouseEvent): void {\n if (!this.drag.active) return;\n const rect = this.getDragRect(this.drag.pageNum);\n this.drag.active = false;\n\n if (!rect || (rect.w < 5 && rect.h < 5)) { this.cdr.detectChanges(); return; }\n\n const pageInfo = this.getPageInfo(this.drag.pageNum);\n if (!pageInfo) { this.cdr.detectChanges(); return; }\n\n const hits: BoundingBox[] = [];\n for (const box of this.annotations) {\n const pts = this.transformPolygon(\n box.polygon, box.width, box.height, pageInfo.width, pageInfo.height, pageInfo.rotation\n );\n const bb = this.polygonBBox(pts);\n if (this.rectsIntersect(rect, bb)) hits.push(box);\n }\n\n this.multiSelectedKeys = new Set(hits.map(b => this.boxKey(b)));\n\n if (hits.length > 0 && this.contextMenuItems.length > 0) {\n this.ctxX = event.clientX;\n this.ctxY = event.clientY;\n this.ctxVisible = true;\n }\n this.cdr.detectChanges();\n }\n\n private svgPoint(event: MouseEvent, pageNum: number): { x: number; y: number } | null {\n const svg = document.getElementById(`npv-svg-${pageNum}`) as SVGSVGElement | null;\n if (!svg) return null;\n const r = svg.getBoundingClientRect();\n return { x: event.clientX - r.left, y: event.clientY - r.top };\n }\n\n private rectsIntersect(\n a: { x: number; y: number; w: number; h: number },\n b: { x: number; y: number; w: number; h: number }\n ): boolean {\n return !(a.x + a.w < b.x || b.x + b.w < a.x || a.y + a.h < b.y || b.y + b.h < a.y);\n }\n\n // ─────────────────────────────────────────────\n // Context menu\n // ─────────────────────────────────────────────\n\n onContextMenuAction(item: ContextMenuItem): void {\n this.ctxVisible = false;\n const selected = this.annotations.filter(b => this.multiSelectedKeys.has(this.boxKey(b)));\n this.boxesSelected.emit({ boxes: selected, action: item.action });\n this.multiSelectedKeys.clear();\n this.cdr.detectChanges();\n }\n\n @HostListener('document:click')\n onDocClick(): void {\n if (this.ctxVisible) { this.ctxVisible = false; this.cdr.detectChanges(); }\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – zoom\n // ─────────────────────────────────────────────\n\n zoomIn(): void { this.zoom = Math.min(this.zoom + 0.25, 5); this.rerenderAll(); }\n zoomOut(): void { this.zoom = Math.max(this.zoom - 0.25, 0.25); this.rerenderAll(); }\n\n get zoomPercent(): number { return Math.round(this.zoom * 100); }\n\n // ─────────────────────────────────────────────\n // Toolbar – rotation\n // ─────────────────────────────────────────────\n\n rotateLeft(): void { this.userRotation = (this.userRotation + 270) % 360; this.rerenderAll(); }\n rotateRight(): void { this.userRotation = (this.userRotation + 90) % 360; this.rerenderAll(); }\n\n // ─────────────────────────────────────────────\n // Toolbar – page navigation\n // ─────────────────────────────────────────────\n\n goToPrevPage(): void { if (this.currentPage > 1) this.scrollToPageNum(this.currentPage - 1); }\n goToNextPage(): void { if (this.currentPage < this.totalPages) this.scrollToPageNum(this.currentPage + 1); }\n\n scrollToPageNum(pageNum: number): void {\n this.currentPage = pageNum;\n document.getElementById(`npv-page-${pageNum}`)?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n scrollToBox(box: BoundingBox): void {\n this.currentPage = box.page;\n console.log('scroll to page', this.currentPage)\n const pageEl = document.getElementById(`npv-page-${box.page}`);\n if (!pageEl) {\n console.log('no page element found, stop scrolling')\n return;\n }\n const pi = this.getPageInfo(box.page);\n if (!pi) {\n pageEl.scrollIntoView({ behavior: 'smooth', block: 'start' });\n console.log('scroll into view done')\n return;\n }\n const pts = this.transformPolygon(box.polygon, box.width, box.height, pi.width, pi.height, pi.rotation);\n const bb = this.polygonBBox(pts);\n const top = (pageEl as HTMLElement).offsetTop + bb.y - window.innerHeight / 2;\n this.pdfContainer?.nativeElement.scrollTo({ top, behavior: 'smooth' });\n console.log('scrolling to element done')\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – search\n // ─────────────────────────────────────────────\n\n toggleSearch(): void {\n this.searchVisible = !this.searchVisible;\n if (!this.searchVisible) {\n this.searchQuery = '';\n this.searchMatches = [];\n this.searchIndex = -1;\n this.cdr.detectChanges();\n }\n }\n\n async onSearchInput(): Promise<void> {\n const q = this.searchQuery.trim().toLowerCase();\n this.searchMatches = [];\n this.searchIndex = -1;\n if (!q || !this.pdfDoc) { this.cdr.detectChanges(); return; }\n\n for (let p = 1; p <= this.totalPages; p++) {\n const pi = this.getPageInfo(p);\n if (!pi) continue;\n const page = await this.pdfDoc.getPage(p);\n const text = await page.getTextContent();\n const vp = page.getViewport({ scale: this.zoom, rotation: pi.rotation });\n\n for (const item of text.items as any[]) {\n if (!item.str) continue;\n const idx = item.str.toLowerCase().indexOf(q);\n if (idx < 0) continue;\n\n const charW = (item.width / item.str.length) || 6;\n const itemH = Math.abs(item.transform[3]) || 10;\n const x0 = item.transform[4] + idx * charW;\n const y0 = item.transform[5];\n\n const t = vp.transform;\n const applyT = (x: number, y: number): [number, number] =>\n [t[0]*x + t[2]*y + t[4], t[1]*x + t[3]*y + t[5]];\n\n const [cx0, cy0] = applyT(x0, y0 + itemH);\n const [cx1, cy1] = applyT(x0 + q.length * charW, y0);\n\n this.searchMatches.push({\n pageNum: p,\n polygon: [cx0, cy0, cx1, cy0, cx1, cy1, cx0, cy1]\n });\n }\n page.cleanup();\n }\n\n if (this.searchMatches.length > 0) {\n this.searchIndex = 0;\n this.scrollToSearchMatch(0);\n }\n this.cdr.detectChanges();\n }\n\n searchNext(): void {\n if (!this.searchMatches.length) return;\n this.searchIndex = (this.searchIndex + 1) % this.searchMatches.length;\n this.scrollToSearchMatch(this.searchIndex);\n this.cdr.detectChanges();\n }\n\n searchPrev(): void {\n if (!this.searchMatches.length) return;\n this.searchIndex = (this.searchIndex - 1 + this.searchMatches.length) % this.searchMatches.length;\n this.scrollToSearchMatch(this.searchIndex);\n this.cdr.detectChanges();\n }\n\n private scrollToSearchMatch(idx: number): void {\n const m = this.searchMatches[idx];\n if (!m) return;\n document.getElementById(`npv-page-${m.pageNum}`)?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – annotation navigation\n // ─────────────────────────────────────────────\n\n get annotationIndex(): number {\n if (!this.clickedBoxKey) return -1;\n return this.annotations.findIndex(b => this.boxKey(b) === this.clickedBoxKey);\n }\n\n goToPrevAnnotation(): void {\n if (!this.annotations.length) return;\n const prev = (this.annotationIndex - 1 + this.annotations.length) % this.annotations.length;\n this.selectAnnotation(prev);\n }\n\n goToNextAnnotation(): void {\n if (!this.annotations.length) return;\n const next = (this.annotationIndex + 1) % this.annotations.length;\n this.selectAnnotation(next);\n }\n\n private selectAnnotation(index: number): void {\n const box = this.annotations[index];\n if (!box) return;\n this.multiSelectedKeys.clear();\n this.ctxVisible = false;\n this.clickedBoxKey = this.boxKey(box);\n this.cdr.detectChanges();\n this.scrollToBox(box);\n this.boxClicked.emit({ box, selected: true });\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – selection mode\n // ─────────────────────────────────────────────\n\n toggleSelectionMode(): void {\n this.selectionMode = this.selectionMode === 'select-area' ? 'select-text' : 'select-area';\n if (this.selectionMode === 'select-text') {\n this.renderedPages.forEach(rp => this.renderTextLayer(rp.pageNum));\n } else {\n this.removeAllTextLayers();\n }\n this.cdr.detectChanges();\n }\n\n /**\n * Returns the CSS matrix() transform that aligns the pdfjs text layer\n * (always sized in *unrotated* page space) with the rotated canvas.\n * pi.width / pi.height are the *canvas* (rotated) pixel dimensions.\n */\n private textLayerTransform(totalRotation: number, canvasW: number, canvasH: number): string {\n const norm = ((totalRotation % 360) + 360) % 360;\n switch (norm) {\n // 90 ° CW: (x,y) → (H−y, x) where H = canvas width after swap\n case 90: return `matrix(0,1,-1,0,${canvasW},0)`;\n // 180 °: (x,y) → (W−x, H−y)\n case 180: return `matrix(-1,0,0,-1,${canvasW},${canvasH})`;\n // 270 ° CW: (x,y) → (y, W−x) where W = canvas height after swap\n case 270: return `matrix(0,-1,1,0,0,${canvasH})`;\n default: return '';\n }\n }\n\n private async renderTextLayer(pageNum: number): Promise<void> {\n if (!this.pdfDoc) return;\n const pi = this.getPageInfo(pageNum);\n if (!pi) return;\n\n const wrapper = document.getElementById(`npv-page-${pageNum}`) as HTMLElement | null;\n if (!wrapper) return;\n\n this.removeTextLayer(pageNum);\n\n const page = await this.pdfDoc.getPage(pageNum);\n const totalRotation = (page.rotate + this.userRotation) % 360;\n const viewport = page.getViewport({ scale: this.zoom, rotation: totalRotation });\n\n const div = document.createElement('div');\n // 'textLayer' class is required for the injected pdfjs CSS rules to apply.\n div.className = 'npv-text-layer textLayer';\n // pdfjs sizes the container with calc(var(--scale-factor) * rawPageWidth).\n // Without this variable every calc() is invalid → container collapses to 0.\n div.style.setProperty('--scale-factor', String(this.zoom));\n // pdfjs always lays text out in unrotated page space; align with rotated canvas.\n const transform = this.textLayerTransform(totalRotation, pi.width, pi.height);\n if (transform) div.style.transform = transform;\n\n wrapper.appendChild(div);\n\n const textLayer = new (pdfjsLib as any).TextLayer({\n textContentSource: page.streamTextContent(),\n container: div,\n viewport,\n });\n\n this.textLayers.set(pageNum, textLayer);\n try {\n await textLayer.render();\n } catch (e: any) {\n if (e?.name !== 'AbortException') console.error('TextLayer render error:', e);\n }\n page.cleanup();\n }\n\n private removeTextLayer(pageNum: number): void {\n const tl = this.textLayers.get(pageNum);\n if (tl) {\n try { tl.cancel(); } catch (_) {}\n this.textLayers.delete(pageNum);\n }\n const wrapper = document.getElementById(`npv-page-${pageNum}`);\n wrapper?.querySelector('.npv-text-layer')?.remove();\n }\n\n private removeAllTextLayers(): void {\n for (const pageNum of Array.from(this.textLayers.keys())) {\n this.removeTextLayer(pageNum);\n }\n }\n\n // ─────────────────────────────────────────────\n // Scroll tracking\n // ─────────────────────────────────────────────\n\n onContainerScroll(): void {\n if (!this.pdfContainer) return;\n const top = this.pdfContainer.nativeElement.scrollTop;\n let closest = 1, minDist = Infinity;\n for (let p = 1; p <= this.totalPages; p++) {\n const el = document.getElementById(`npv-page-${p}`) as HTMLElement | null;\n if (!el) continue;\n const dist = Math.abs(el.offsetTop - top);\n if (dist < minDist) { minDist = dist; closest = p; }\n }\n if (this.currentPage !== closest) { this.currentPage = closest; this.cdr.detectChanges(); }\n }\n}\n","<div class=\"npv-root\">\n\n <!-- ─────────── Toolbar ─────────── -->\n <div class=\"npv-toolbar\">\n\n <!-- Zoom -->\n <ng-container *ngIf=\"showZoom\">\n <button mat-icon-button [matTooltip]=\"l.zoomOut\" (click)=\"zoomOut()\" [disabled]=\"zoom <= 0.25\">\n <mat-icon>zoom_out</mat-icon>\n </button>\n <span class=\"npv-label\">{{ zoomPercent }}%</span>\n <button mat-icon-button [matTooltip]=\"l.zoomIn\" (click)=\"zoomIn()\" [disabled]=\"zoom >= 5\">\n <mat-icon>zoom_in</mat-icon>\n </button>\n </ng-container>\n\n <!-- Rotation -->\n <ng-container *ngIf=\"showRotation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom\"></div>\n <button mat-icon-button [matTooltip]=\"l.rotateLeft\" (click)=\"rotateLeft()\">\n <mat-icon>rotate_left</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.rotateRight\" (click)=\"rotateRight()\">\n <mat-icon>rotate_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Page navigation -->\n <ng-container *ngIf=\"showPageNavigation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousPage\" (click)=\"goToPrevPage()\" [disabled]=\"currentPage <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <span class=\"npv-label\">{{ currentPage }} / {{ totalPages }}</span>\n <button mat-icon-button [matTooltip]=\"l.nextPage\" (click)=\"goToNextPage()\" [disabled]=\"currentPage >= totalPages\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Annotation navigation -->\n <ng-container *ngIf=\"showAnnotationNavigation && annotations.length\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousAnnotation\" (click)=\"goToPrevAnnotation()\">\n <mat-icon>navigate_before</mat-icon>\n </button>\n <span class=\"npv-label\">\n {{ annotationIndex >= 0 ? annotationIndex + 1 : '–' }} / {{ annotations.length }}\n </span>\n <button mat-icon-button [matTooltip]=\"l.nextAnnotation\" (click)=\"goToNextAnnotation()\">\n <mat-icon>navigate_next</mat-icon>\n </button>\n </ng-container>\n\n <!-- Selection mode toggle -->\n <ng-container *ngIf=\"showSelectionMode\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0)\"></div>\n <button mat-icon-button\n [matTooltip]=\"selectionMode === 'select-area' ? l.selectText : l.selectArea\"\n (click)=\"toggleSelectionMode()\"\n [class.npv-active]=\"selectionMode === 'select-text'\">\n <mat-icon>text_fields</mat-icon>\n </button>\n </ng-container>\n\n <!-- Search -->\n <ng-container *ngIf=\"showSearch\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0) || showSelectionMode\"></div>\n <button mat-icon-button [matTooltip]=\"l.search\" (click)=\"toggleSearch()\" [class.npv-active]=\"searchVisible\">\n <mat-icon>search</mat-icon>\n </button>\n <ng-container *ngIf=\"searchVisible\">\n <input\n class=\"npv-search-input\"\n type=\"text\"\n [placeholder]=\"l.searchPlaceholder\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchInput()\"\n (keydown.enter)=\"searchNext()\"\n (keydown.shift.enter)=\"searchPrev()\"\n autofocus\n />\n <button mat-icon-button [matTooltip]=\"l.previousResult\"\n (click)=\"searchPrev()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_less</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.nextResult\"\n (click)=\"searchNext()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_more</mat-icon>\n </button>\n <span class=\"npv-search-count\" *ngIf=\"searchMatches.length\">\n {{ searchIndex + 1 }} / {{ searchMatches.length }}\n </span>\n <span class=\"npv-search-count npv-no-match\" *ngIf=\"searchQuery && !searchMatches.length\">\n {{ l.noResults }}\n </span>\n </ng-container>\n </ng-container>\n\n </div>\n\n <!-- ─────────── Loading ─────────── -->\n <div class=\"npv-loading\" *ngIf=\"loading\">\n <span class=\"npv-spinner\"></span> {{ l.loading }}\n </div>\n\n <!-- ─────────── Scroll area ─────────── -->\n <div class=\"npv-scroll-area\" #pdfContainer\n (scroll)=\"onContainerScroll()\" (click)=\"ctxVisible = false\">\n <div class=\"npv-scroll-inner\">\n\n <ng-container *ngFor=\"let p of pageRange()\">\n <div class=\"npv-page-wrapper\" [id]=\"'npv-page-' + p\">\n\n <canvas [id]=\"'npv-canvas-' + p\" class=\"npv-canvas\"></canvas>\n\n <svg *ngIf=\"getPageInfo(p) as pi\"\n [id]=\"'npv-svg-' + p\"\n class=\"npv-overlay\"\n [class.npv-overlay--text-mode]=\"selectionMode === 'select-text'\"\n [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n [attr.viewBox]=\"'0 0 ' + pi.width + ' ' + pi.height\"\n (mousedown)=\"onSvgMouseDown($event, p)\">\n\n <!-- Hit area for drag selection on empty page space -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n fill=\"transparent\"></rect>\n\n <!-- Annotation boxes -->\n <polygon\n *ngFor=\"let box of getBoxesForPage(p)\"\n [attr.points]=\"getSvgPoints(box, pi)\"\n class=\"npv-box\"\n [class.npv-box--clicked]=\"isClicked(box)\"\n [class.npv-box--multi]=\"isMultiSelected(box)\"\n [style.fill]=\"isClicked(box) ? highlightingColor : (isMultiSelected(box) ? selectedColor : 'transparent')\"\n [style.stroke]=\"annotationStroke\"\n (click)=\"onBoxClick($event, box)\">\n <title>{{ box.content || '' }}</title>\n </polygon>\n\n <!-- Search highlights -->\n <polygon\n *ngFor=\"let m of getSearchMatchesForPage(p); let mi = index\"\n [attr.points]=\"searchMatchPoints(m)\"\n class=\"npv-search-highlight\"\n [class.npv-search-highlight--current]=\"isCurrentSearchMatch(p, mi)\">\n </polygon>\n\n <!-- Drag selection rectangle -->\n <rect *ngIf=\"getDragRect(p) as dr\"\n [attr.x]=\"dr.x\" [attr.y]=\"dr.y\"\n [attr.width]=\"dr.w\" [attr.height]=\"dr.h\"\n class=\"npv-drag-rect\">\n </rect>\n\n </svg>\n </div>\n </ng-container>\n\n <div class=\"npv-placeholder npv-placeholder--error\" *ngIf=\"!loading && loadError\">\n {{ l.loadError }}\n </div>\n <div class=\"npv-placeholder\" *ngIf=\"!loading && !loadError && totalPages === 0\">\n {{ l.noDocument }}\n </div>\n\n </div><!-- /npv-scroll-inner -->\n </div>\n\n <!-- ─────────── Context menu ─────────── -->\n <div *ngIf=\"ctxVisible && contextMenuItems.length\"\n class=\"npv-context-menu\"\n [style.left.px]=\"ctxX\" [style.top.px]=\"ctxY\"\n (click)=\"$event.stopPropagation()\">\n <div *ngFor=\"let item of contextMenuItems\"\n class=\"npv-context-item\"\n (click)=\"onContextMenuAction(item)\">\n {{ item.label }}\n </div>\n </div>\n\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aprova.ch-ngx-next-pdf-viewer.mjs","sources":["../../../projects/ngx-next-pdf-viewer/src/lib/tokens.ts","../../../projects/ngx-next-pdf-viewer/src/lib/ngx-next-pdf-viewer.component.ts","../../../projects/ngx-next-pdf-viewer/src/lib/ngx-next-pdf-viewer.component.html","../../../projects/ngx-next-pdf-viewer/src/aprova.ch-ngx-next-pdf-viewer.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * URL to the PDF.js worker script.\n *\n * Default: `'assets/pdf.worker.min.mjs'`\n *\n * Override in your application by providing this token:\n * ```ts\n * providers: [\n * { provide: NGX_PDF_WORKER_SRC, useValue: 'assets/pdf.worker.min.mjs' }\n * ]\n * ```\n */\nexport const NGX_PDF_WORKER_SRC = new InjectionToken<string>(\n 'NGX_PDF_WORKER_SRC',\n { factory: () => 'assets/pdf.worker.min.mjs' }\n);\n","import {\n Component, Input, Output, EventEmitter, Inject,\n OnChanges, OnDestroy, SimpleChanges,\n ViewChild, ElementRef, ChangeDetectorRef,\n HostListener, NgZone, AfterViewInit\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';\n\nimport { BoundingBox, ContextMenuItem, PdfViewerLabels, ZoomMode } from './models';\nimport { NGX_PDF_WORKER_SRC } from './tokens';\n\n// ── RSA-2048 public key (SPKI DER, base64) ────────────────────────────────\n// Generated with api-keys/generate.js. The matching private key lives in\n// api-keys/private.key (never ship that file with the library).\nconst API_PUBLIC_KEY_B64 =\n 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA32o40ciAzk12XQ7RQpjy' +\n 'YUa22NNDh4jlntE8UPls2PDZLcSTORMyZTASnXzzUq4RodplBaySFbQUHNwYzYYT' +\n 'H8+/GZPInigDqpVVJ+8sHiI+5jA9b4hl6alGzBmnSKaGnJYxy9DnUG/NM5cGK6+' +\n 'MaZJrnjKrrWjQ2ttkuXRmDHLwcvfva06Lv8BEBDmbt1dVnTGPjwUjJelZeu5xVZU' +\n 'gm9QlbhVR0P+vUM11jWzoq7W1bzyoDuToqZ+tQCLSVZ7Pz8FdHn3Wh/Qnw/VhqW' +\n 'IeaHTgswOB1Cti0Oh1o+tpuv3LgIeGyZxyudnWnkDInQ2LvCP9z8aLVI9io/RA3a' +\n 'PiwwIDAQAB';\n\n// ──────────────────────────────────────────────\n// Internal helpers\n// ──────────────────────────────────────────────\n\ninterface RenderedPage {\n pageNum: number;\n width: number;\n height: number;\n rotation: number;\n}\n\ninterface DragState {\n active: boolean;\n pageNum: number;\n startX: number;\n startY: number;\n currentX: number;\n currentY: number;\n}\n\ninterface SearchMatch {\n pageNum: number;\n polygon: number[];\n}\n\n// ──────────────────────────────────────────────\n// Component\n// ──────────────────────────────────────────────\n\n@Component({\n selector: 'ngx-next-pdf-viewer',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n MatIconModule,\n MatButtonModule,\n MatTooltipModule,\n MatInputModule,\n MatFormFieldModule\n ],\n templateUrl: './ngx-next-pdf-viewer.component.html',\n styleUrl: './ngx-next-pdf-viewer.component.scss'\n})\nexport class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterViewInit {\n\n // ── Inputs ──────────────────────────────────\n /** PDF file to display */\n @Input() blob: Blob | undefined;\n /** Bounding-box annotations to overlay */\n @Input() annotations: BoundingBox[] = [];\n /** Items shown in the context menu after drag-selecting boxes */\n @Input() contextMenuItems: ContextMenuItem[] = [];\n /** Fill colour for a single-clicked box (CSS colour string) */\n @Input() highlightingColor = 'rgba(255, 200, 0, 0.35)';\n /** Fill colour for drag-selected boxes (CSS colour string) */\n @Input() selectedColor = 'rgba(0, 120, 215, 0.35)';\n /** Stroke colour for all annotation polygons */\n @Input() annotationStroke = '#e97332';\n /** Initial zoom: numeric level (1.0 = 100 %) or 'fit-to-page' | 'fit-to-width' | 'fit-to-height' */\n @Input() initialZoom: ZoomMode = 1.5;\n /** Override any subset of the viewer's user-visible strings */\n @Input() labels: Partial<PdfViewerLabels> = {};\n /** Show / hide the zoom buttons and percentage label */\n @Input() showZoom = true;\n /** Show / hide the rotate-left and rotate-right buttons */\n @Input() showRotation = true;\n /** Show / hide the previous/next page buttons and page counter */\n @Input() showPageNavigation = true;\n /** Show / hide the previous/next annotation buttons and annotation counter */\n @Input() showAnnotationNavigation = true;\n /** Show / hide the select-area / select-text toggle button */\n @Input() showSelectionMode = true;\n /** Show / hide the search button and search bar */\n @Input() showSearch = true;\n /**\n * API key for enabling output triggers (boxClicked, boxesSelected).\n * When provided it must be a valid key generated by api-keys/generate.js.\n * Output events are silently suppressed while the key is absent or invalid.\n */\n @Input() apiKey: string | undefined;\n\n private static readonly DEFAULT_LABELS: PdfViewerLabels = {\n zoomOut: 'Zoom out',\n zoomIn: 'Zoom in',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n previousPage: 'Previous page',\n nextPage: 'Next page',\n search: 'Search',\n previousResult: 'Previous result',\n nextResult: 'Next result',\n previousAnnotation: 'Previous annotation',\n nextAnnotation: 'Next annotation',\n selectArea: 'Select area',\n selectText: 'Select & copy text',\n searchPlaceholder: 'Search in PDF…',\n noResults: 'No results',\n loading: 'Loading PDF…',\n noDocument: 'No PDF loaded',\n loadError: 'Failed to load PDF',\n };\n\n get l(): PdfViewerLabels {\n return { ...NgxNextPdfViewerComponent.DEFAULT_LABELS, ...this.labels };\n }\n\n // ── Outputs ─────────────────────────────────\n /** Fired when the user clicks a single annotation box */\n @Output() boxClicked = new EventEmitter<{ box: BoundingBox; selected: boolean }>();\n /** Fired when the user picks a context-menu item after drag-selection */\n @Output() boxesSelected = new EventEmitter<{ boxes: BoundingBox[]; action: string }>();\n\n // ── View refs ────────────────────────────────\n @ViewChild('pdfContainer') pdfContainer!: ElementRef<HTMLDivElement>;\n\n // ── PDF state ────────────────────────────────\n pdfDoc: PDFDocumentProxy | null = null;\n renderedPages: RenderedPage[] = [];\n currentPage = 1;\n totalPages = 0;\n zoom = 1.5;\n userRotation = 0;\n\n // ── Annotation state ─────────────────────────\n clickedBoxKey: string | null = null;\n multiSelectedKeys: Set<string> = new Set();\n\n // ── Drag-select state ────────────────────────\n drag: DragState = { active: false, pageNum: 0, startX: 0, startY: 0, currentX: 0, currentY: 0 };\n\n // ── Context-menu state ───────────────────────\n ctxVisible = false;\n ctxX = 0;\n ctxY = 0;\n\n // ── Search state ─────────────────────────────\n searchVisible = false;\n searchQuery = '';\n searchMatches: SearchMatch[] = [];\n searchIndex = -1;\n\n // ── Selection mode ───────────────────────────\n selectionMode: 'select-area' | 'select-text' = 'select-area';\n\n // ── Loading ──────────────────────────────────\n loading = false;\n loadError = false;\n\n // ── API-key state ────────────────────────────\n /** True once the current apiKey has been verified against the embedded public key. */\n apiKeyValid = false;\n\n private renderTasks: Map<number, any> = new Map();\n private textLayers: Map<number, any> = new Map();\n private wheelListener?: (e: WheelEvent) => void;\n\n // ── One-time global CSS for the pdfjs text layer ─────────────────────────\n private static textLayerStylesInjected = false;\n\n private static injectTextLayerStyles(): void {\n if (NgxNextPdfViewerComponent.textLayerStylesInjected) return;\n const style = document.createElement('style');\n style.id = 'npv-text-layer-styles';\n style.textContent =\n '.textLayer{position:absolute;top:0;left:0;overflow:hidden;line-height:1;' +\n 'text-size-adjust:none;forced-color-adjust:none;transform-origin:0 0;z-index:0}' +\n '.textLayer :is(span,br){color:transparent;position:absolute;white-space:pre;' +\n 'cursor:text;transform-origin:0% 0%}' +\n '.textLayer>:not(.markedContent),' +\n '.textLayer .markedContent span:not(.markedContent){z-index:1}' +\n '.textLayer ::selection{background:rgba(0,120,215,.25);color:transparent}' +\n '.textLayer br::selection{background:transparent}';\n document.head.appendChild(style);\n NgxNextPdfViewerComponent.textLayerStylesInjected = true;\n }\n\n constructor(\n private cdr: ChangeDetectorRef,\n private zone: NgZone,\n private el: ElementRef,\n @Inject(NGX_PDF_WORKER_SRC) workerSrc: string\n ) {\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n NgxNextPdfViewerComponent.injectTextLayerStyles();\n }\n\n ngAfterViewInit(): void {\n if (typeof this.initialZoom === 'number') {\n this.zoom = this.initialZoom;\n }\n // Ctrl+scroll zooming – requires passive:false to call preventDefault()\n this.zone.runOutsideAngular(() => {\n this.wheelListener = (e: WheelEvent) => {\n if (!e.ctrlKey) return;\n e.preventDefault();\n this.zone.run(() => e.deltaY < 0 ? this.zoomIn() : this.zoomOut());\n };\n this.el.nativeElement.addEventListener('wheel', this.wheelListener, { passive: false });\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['apiKey']) {\n this.apiKeyValid = false;\n if (this.apiKey) {\n this.verifyApiKey(this.apiKey).then(valid => {\n this.apiKeyValid = valid;\n this.cdr.detectChanges();\n });\n }\n }\n if (changes['blob'] && this.blob) {\n console.log('load new file');\n this.loadPdf(this.blob);\n }\n if (changes['annotations'] && !changes['blob']) {\n console.log('set new annotations', this.annotations.length);\n this.cdr.detectChanges();\n if (this.annotations.length === 1) {\n this.scrollToBox(this.annotations[0]);\n }\n }\n }\n\n ngOnDestroy(): void {\n if (this.wheelListener) {\n this.el.nativeElement.removeEventListener('wheel', this.wheelListener);\n }\n this.removeAllTextLayers();\n this.pdfDoc?.destroy();\n }\n\n // ─────────────────────────────────────────────\n // API-key verification (Web Crypto API)\n // ─────────────────────────────────────────────\n\n /** Decodes a base64url string to a Uint8Array (no external dependencies). */\n private b64urlToBytes(b64url: string): Uint8Array {\n const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/');\n const padded = b64.padEnd(b64.length + (4 - (b64.length % 4)) % 4, '=');\n return Uint8Array.from(atob(padded), c => c.charCodeAt(0));\n }\n\n /**\n * Verifies an API key against the embedded RSA-2048 public key.\n * Format: <payload_base64url>.<signature_base64url>\n *\n * Returns false when:\n * - the format is invalid\n * - the RSA signature does not match\n * - the key type is \"trial\" and its expiry timestamp has passed\n */\n private async verifyApiKey(key: string): Promise<boolean> {\n try {\n const dotIndex = key.lastIndexOf('.');\n if (dotIndex < 1) return false;\n const payloadB64 = key.slice(0, dotIndex);\n const sigB64 = key.slice(dotIndex + 1);\n\n // Import the embedded public key (SPKI DER, standard base64 → CryptoKey)\n const derBytes = Uint8Array.from(atob(API_PUBLIC_KEY_B64), c => c.charCodeAt(0));\n const cryptoKey = await crypto.subtle.importKey(\n 'spki',\n derBytes,\n { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },\n false,\n ['verify']\n );\n\n // Verify RSA signature (computed over the UTF-8 bytes of the payload string)\n const data = new TextEncoder().encode(payloadB64);\n const sig = this.b64urlToBytes(sigB64);\n const signatureValid = await crypto.subtle.verify('RSASSA-PKCS1-v1_5', cryptoKey, sig, data);\n if (!signatureValid) return false;\n\n // Decode payload and check expiry for trial keys\n const payloadJson = atob(\n payloadB64.replace(/-/g, '+').replace(/_/g, '/')\n .padEnd(payloadB64.length + (4 - (payloadB64.length % 4)) % 4, '=')\n );\n const payload = JSON.parse(payloadJson) as { type?: string; expires?: number | null };\n\n if (payload.type === 'trial' && payload.expires != null) {\n if (Date.now() > payload.expires) return false; // trial key expired\n }\n\n return true;\n } catch {\n return false;\n }\n }\n\n // ─────────────────────────────────────────────\n // PDF loading & rendering\n // ─────────────────────────────────────────────\n\n private async loadPdf(blob: Blob): Promise<void> {\n this.loading = true;\n this.loadError = false;\n this.renderedPages = [];\n this.clickedBoxKey = null;\n this.multiSelectedKeys.clear();\n this.searchMatches = [];\n this.searchIndex = -1;\n this.removeAllTextLayers();\n this.cdr.detectChanges();\n\n try {\n this.pdfDoc?.destroy();\n const buf = await blob.arrayBuffer();\n this.pdfDoc = await pdfjsLib.getDocument({ data: buf }).promise;\n this.totalPages = this.pdfDoc.numPages;\n this.currentPage = 1;\n if (typeof this.initialZoom !== 'number') {\n this.zoom = await this.computeFitZoom(this.initialZoom);\n }\n this.loading = false;\n this.cdr.detectChanges();\n\n for (let p = 1; p <= this.totalPages; p++) {\n await this.renderPage(p);\n }\n\n if (this.annotations.length === 1) {\n this.scrollToBox(this.annotations[0]);\n }\n } catch {\n this.loading = false;\n this.loadError = true;\n }\n this.cdr.detectChanges();\n }\n\n private async computeFitZoom(mode: Exclude<ZoomMode, number>): Promise<number> {\n if (!this.pdfDoc) return 1;\n const page = await this.pdfDoc.getPage(1);\n const rotation = (page.rotate + this.userRotation) % 360;\n const vp = page.getViewport({ scale: 1, rotation });\n page.cleanup();\n\n const container = this.pdfContainer?.nativeElement;\n if (!container) return 1;\n\n // Subtract the 16 px padding on each side defined in npv-scroll-inner\n const availW = container.clientWidth - 32;\n const availH = container.clientHeight - 32;\n const scaleW = availW / vp.width;\n const scaleH = availH / vp.height;\n\n switch (mode) {\n case 'fit-to-width': return scaleW;\n case 'fit-to-height': return scaleH;\n case 'fit-to-page': return Math.min(scaleW, scaleH);\n }\n }\n\n private async renderPage(pageNum: number): Promise<void> {\n if (!this.pdfDoc) return;\n const page: PDFPageProxy = await this.pdfDoc.getPage(pageNum);\n const totalRotation = (page.rotate + this.userRotation) % 360;\n const viewport = page.getViewport({ scale: this.zoom, rotation: totalRotation });\n\n // HiDPI: render at physical pixel density, display at CSS size\n const dpr = window.devicePixelRatio || 1;\n const hiResViewport = page.getViewport({ scale: this.zoom * dpr, rotation: totalRotation });\n\n const canvas = document.getElementById(`npv-canvas-${pageNum}`) as HTMLCanvasElement | null;\n if (!canvas) return;\n\n canvas.width = hiResViewport.width;\n canvas.height = hiResViewport.height;\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n\n if (this.renderTasks.has(pageNum)) {\n try { this.renderTasks.get(pageNum).cancel(); } catch (_) {}\n }\n\n const ctx = canvas.getContext('2d')!;\n const task = page.render({ canvasContext: ctx, viewport: hiResViewport });\n this.renderTasks.set(pageNum, task);\n try {\n await task.promise;\n } catch (e: any) {\n if (e?.name !== 'RenderingCancelledException') console.error(e);\n return;\n }\n this.renderTasks.delete(pageNum);\n\n const existing = this.renderedPages.find(r => r.pageNum === pageNum);\n if (existing) {\n existing.width = viewport.width;\n existing.height = viewport.height;\n existing.rotation = totalRotation;\n } else {\n this.renderedPages.push({ pageNum, width: viewport.width, height: viewport.height, rotation: totalRotation });\n }\n this.cdr.detectChanges();\n page.cleanup();\n }\n\n private async rerenderAll(): Promise<void> {\n if (!this.pdfDoc) return;\n if (this.selectionMode === 'select-text') {\n this.removeAllTextLayers();\n }\n for (let p = 1; p <= this.totalPages; p++) {\n await this.renderPage(p);\n if (this.selectionMode === 'select-text') {\n await this.renderTextLayer(p);\n }\n }\n this.cdr.detectChanges();\n }\n\n // ─────────────────────────────────────────────\n // Coordinate transformation\n // ─────────────────────────────────────────────\n\n /** Converts a polygon (y=0 at top, any consistent unit) to SVG canvas coordinates */\n transformPolygon(\n polygon: number[],\n pdfWidth: number,\n pdfHeight: number,\n canvasWidth: number,\n canvasHeight: number,\n rotation: number\n ): number[] {\n const norm = ((rotation % 360) + 360) % 360;\n const result: number[] = [];\n for (let i = 0; i < polygon.length; i += 2) {\n const px = polygon[i];\n const py = polygon[i + 1];\n let cx: number, cy: number;\n switch (norm) {\n case 90:\n cx = (pdfHeight - py) * canvasWidth / pdfHeight;\n cy = px * canvasHeight / pdfWidth;\n break;\n case 180:\n cx = (pdfWidth - px) * canvasWidth / pdfWidth;\n cy = (pdfHeight - py) * canvasHeight / pdfHeight;\n break;\n case 270:\n cx = py * canvasWidth / pdfHeight;\n cy = (pdfWidth - px) * canvasHeight / pdfWidth;\n break;\n default:\n cx = px * canvasWidth / pdfWidth;\n cy = py * canvasHeight / pdfHeight;\n }\n result.push(cx, cy);\n }\n return result;\n }\n\n getSvgPoints(box: BoundingBox, pi: RenderedPage): string {\n const pts = this.transformPolygon(\n box.polygon, box.width, box.height, pi.width, pi.height, pi.rotation\n );\n const pairs: string[] = [];\n for (let i = 0; i < pts.length; i += 2) {\n pairs.push(`${pts[i].toFixed(2)},${pts[i + 1].toFixed(2)}`);\n }\n return pairs.join(' ');\n }\n\n private polygonBBox(pts: number[]): { x: number; y: number; w: number; h: number } {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (let i = 0; i < pts.length; i += 2) {\n minX = Math.min(minX, pts[i]); maxX = Math.max(maxX, pts[i]);\n minY = Math.min(minY, pts[i+1]); maxY = Math.max(maxY, pts[i+1]);\n }\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\n }\n\n private boxKey(box: BoundingBox): string {\n return JSON.stringify({ page: box.page, polygon: box.polygon });\n }\n\n // ─────────────────────────────────────────────\n // Template helpers\n // ─────────────────────────────────────────────\n\n getPageInfo(pageNum: number): RenderedPage | undefined {\n return this.renderedPages.find(r => r.pageNum === pageNum);\n }\n\n getBoxesForPage(pageNum: number): BoundingBox[] {\n return this.annotations.filter(b => b.page === pageNum);\n }\n\n isClicked(box: BoundingBox): boolean {\n return this.clickedBoxKey === this.boxKey(box);\n }\n\n isMultiSelected(box: BoundingBox): boolean {\n return this.multiSelectedKeys.has(this.boxKey(box));\n }\n\n pageRange(): number[] {\n return Array.from({ length: this.totalPages }, (_, i) => i + 1);\n }\n\n getDragRect(pageNum: number): { x: number; y: number; w: number; h: number } | null {\n if (!this.drag.active || this.drag.pageNum !== pageNum) return null;\n return {\n x: Math.min(this.drag.startX, this.drag.currentX),\n y: Math.min(this.drag.startY, this.drag.currentY),\n w: Math.abs(this.drag.currentX - this.drag.startX),\n h: Math.abs(this.drag.currentY - this.drag.startY)\n };\n }\n\n getSearchMatchesForPage(pageNum: number): SearchMatch[] {\n return this.searchMatches.filter(m => m.pageNum === pageNum);\n }\n\n getSearchIndexOffset(pageNum: number): number {\n return this.searchMatches.findIndex(m => m.pageNum === pageNum);\n }\n\n isCurrentSearchMatch(pageNum: number, localIndex: number): boolean {\n const offset = this.getSearchIndexOffset(pageNum);\n return offset >= 0 && offset + localIndex === this.searchIndex;\n }\n\n searchMatchPoints(m: SearchMatch): string {\n const pairs: string[] = [];\n for (let i = 0; i < m.polygon.length; i += 2) {\n pairs.push(`${m.polygon[i].toFixed(2)},${m.polygon[i + 1].toFixed(2)}`);\n }\n return pairs.join(' ');\n }\n\n // ─────────────────────────────────────────────\n // Box interaction\n // ─────────────────────────────────────────────\n\n onBoxClick(event: MouseEvent, box: BoundingBox): void {\n event.stopPropagation();\n this.ctxVisible = false;\n this.multiSelectedKeys.clear();\n const key = this.boxKey(box);\n const wasSelected = this.clickedBoxKey === key;\n this.clickedBoxKey = wasSelected ? null : key;\n this.cdr.detectChanges();\n if (this.apiKeyValid) {\n this.boxClicked.emit({ box, selected: !wasSelected });\n }\n }\n\n // ─────────────────────────────────────────────\n // Drag-select\n // ─────────────────────────────────────────────\n\n onSvgMouseDown(event: MouseEvent, pageNum: number): void {\n if (this.selectionMode === 'select-text') return;\n if (event.button !== 0) return;\n const tag = (event.target as Element).tagName?.toLowerCase();\n if (tag === 'polygon' || tag === 'title') return;\n this.ctxVisible = false;\n this.clickedBoxKey = null;\n const pt = this.svgPoint(event, pageNum);\n if (!pt) return;\n this.drag = { active: true, pageNum, startX: pt.x, startY: pt.y, currentX: pt.x, currentY: pt.y };\n }\n\n @HostListener('mousemove', ['$event'])\n onDocMouseMove(event: MouseEvent): void {\n if (!this.drag.active) return;\n const pt = this.svgPoint(event, this.drag.pageNum);\n if (!pt) return;\n this.drag.currentX = pt.x;\n this.drag.currentY = pt.y;\n this.cdr.detectChanges();\n }\n\n @HostListener('mouseup', ['$event'])\n onDocMouseUp(event: MouseEvent): void {\n if (!this.drag.active) return;\n const rect = this.getDragRect(this.drag.pageNum);\n this.drag.active = false;\n\n if (!rect || (rect.w < 5 && rect.h < 5)) { this.cdr.detectChanges(); return; }\n\n const pageInfo = this.getPageInfo(this.drag.pageNum);\n if (!pageInfo) { this.cdr.detectChanges(); return; }\n\n const hits: BoundingBox[] = [];\n for (const box of this.annotations) {\n const pts = this.transformPolygon(\n box.polygon, box.width, box.height, pageInfo.width, pageInfo.height, pageInfo.rotation\n );\n const bb = this.polygonBBox(pts);\n if (this.rectsIntersect(rect, bb)) hits.push(box);\n }\n\n this.multiSelectedKeys = new Set(hits.map(b => this.boxKey(b)));\n\n if (hits.length > 0 && this.contextMenuItems.length > 0) {\n this.ctxX = event.clientX;\n this.ctxY = event.clientY;\n this.ctxVisible = true;\n }\n this.cdr.detectChanges();\n }\n\n private svgPoint(event: MouseEvent, pageNum: number): { x: number; y: number } | null {\n const svg = document.getElementById(`npv-svg-${pageNum}`) as SVGSVGElement | null;\n if (!svg) return null;\n const r = svg.getBoundingClientRect();\n return { x: event.clientX - r.left, y: event.clientY - r.top };\n }\n\n private rectsIntersect(\n a: { x: number; y: number; w: number; h: number },\n b: { x: number; y: number; w: number; h: number }\n ): boolean {\n return !(a.x + a.w < b.x || b.x + b.w < a.x || a.y + a.h < b.y || b.y + b.h < a.y);\n }\n\n // ─────────────────────────────────────────────\n // Context menu\n // ─────────────────────────────────────────────\n\n onContextMenuAction(item: ContextMenuItem): void {\n this.ctxVisible = false;\n const selected = this.annotations.filter(b => this.multiSelectedKeys.has(this.boxKey(b)));\n if (this.apiKeyValid) {\n this.boxesSelected.emit({ boxes: selected, action: item.action });\n }\n this.multiSelectedKeys.clear();\n this.cdr.detectChanges();\n }\n\n @HostListener('document:click')\n onDocClick(): void {\n if (this.ctxVisible) { this.ctxVisible = false; this.cdr.detectChanges(); }\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – zoom\n // ─────────────────────────────────────────────\n\n zoomIn(): void { this.zoom = Math.min(this.zoom + 0.25, 5); this.rerenderAll(); }\n zoomOut(): void { this.zoom = Math.max(this.zoom - 0.25, 0.25); this.rerenderAll(); }\n\n get zoomPercent(): number { return Math.round(this.zoom * 100); }\n\n // ─────────────────────────────────────────────\n // Toolbar – rotation\n // ─────────────────────────────────────────────\n\n rotateLeft(): void { this.userRotation = (this.userRotation + 270) % 360; this.rerenderAll(); }\n rotateRight(): void { this.userRotation = (this.userRotation + 90) % 360; this.rerenderAll(); }\n\n // ─────────────────────────────────────────────\n // Toolbar – page navigation\n // ─────────────────────────────────────────────\n\n goToPrevPage(): void { if (this.currentPage > 1) this.scrollToPageNum(this.currentPage - 1); }\n goToNextPage(): void { if (this.currentPage < this.totalPages) this.scrollToPageNum(this.currentPage + 1); }\n\n scrollToPageNum(pageNum: number): void {\n this.currentPage = pageNum;\n document.getElementById(`npv-page-${pageNum}`)?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n scrollToBox(box: BoundingBox): void {\n this.currentPage = box.page;\n console.log('scroll to page', this.currentPage)\n const pageEl = document.getElementById(`npv-page-${box.page}`);\n if (!pageEl) {\n console.log('no page element found, stop scrolling')\n return;\n }\n const pi = this.getPageInfo(box.page);\n if (!pi) {\n pageEl.scrollIntoView({ behavior: 'smooth', block: 'start' });\n console.log('scroll into view done')\n return;\n }\n const pts = this.transformPolygon(box.polygon, box.width, box.height, pi.width, pi.height, pi.rotation);\n const bb = this.polygonBBox(pts);\n const top = (pageEl as HTMLElement).offsetTop + bb.y - window.innerHeight / 2;\n this.pdfContainer?.nativeElement.scrollTo({ top, behavior: 'smooth' });\n console.log('scrolling to element done')\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – search\n // ─────────────────────────────────────────────\n\n toggleSearch(): void {\n this.searchVisible = !this.searchVisible;\n if (!this.searchVisible) {\n this.searchQuery = '';\n this.searchMatches = [];\n this.searchIndex = -1;\n this.cdr.detectChanges();\n }\n }\n\n async onSearchInput(): Promise<void> {\n const q = this.searchQuery.trim().toLowerCase();\n this.searchMatches = [];\n this.searchIndex = -1;\n if (!q || !this.pdfDoc) { this.cdr.detectChanges(); return; }\n\n for (let p = 1; p <= this.totalPages; p++) {\n const pi = this.getPageInfo(p);\n if (!pi) continue;\n const page = await this.pdfDoc.getPage(p);\n const text = await page.getTextContent();\n const vp = page.getViewport({ scale: this.zoom, rotation: pi.rotation });\n\n for (const item of text.items as any[]) {\n if (!item.str) continue;\n const idx = item.str.toLowerCase().indexOf(q);\n if (idx < 0) continue;\n\n const charW = (item.width / item.str.length) || 6;\n const itemH = Math.abs(item.transform[3]) || 10;\n const x0 = item.transform[4] + idx * charW;\n const y0 = item.transform[5];\n\n const t = vp.transform;\n const applyT = (x: number, y: number): [number, number] =>\n [t[0]*x + t[2]*y + t[4], t[1]*x + t[3]*y + t[5]];\n\n const [cx0, cy0] = applyT(x0, y0 + itemH);\n const [cx1, cy1] = applyT(x0 + q.length * charW, y0);\n\n this.searchMatches.push({\n pageNum: p,\n polygon: [cx0, cy0, cx1, cy0, cx1, cy1, cx0, cy1]\n });\n }\n page.cleanup();\n }\n\n if (this.searchMatches.length > 0) {\n this.searchIndex = 0;\n this.scrollToSearchMatch(0);\n }\n this.cdr.detectChanges();\n }\n\n searchNext(): void {\n if (!this.searchMatches.length) return;\n this.searchIndex = (this.searchIndex + 1) % this.searchMatches.length;\n this.scrollToSearchMatch(this.searchIndex);\n this.cdr.detectChanges();\n }\n\n searchPrev(): void {\n if (!this.searchMatches.length) return;\n this.searchIndex = (this.searchIndex - 1 + this.searchMatches.length) % this.searchMatches.length;\n this.scrollToSearchMatch(this.searchIndex);\n this.cdr.detectChanges();\n }\n\n private scrollToSearchMatch(idx: number): void {\n const m = this.searchMatches[idx];\n if (!m) return;\n document.getElementById(`npv-page-${m.pageNum}`)?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – annotation navigation\n // ─────────────────────────────────────────────\n\n get annotationIndex(): number {\n if (!this.clickedBoxKey) return -1;\n return this.annotations.findIndex(b => this.boxKey(b) === this.clickedBoxKey);\n }\n\n goToPrevAnnotation(): void {\n if (!this.annotations.length) return;\n const prev = (this.annotationIndex - 1 + this.annotations.length) % this.annotations.length;\n this.selectAnnotation(prev);\n }\n\n goToNextAnnotation(): void {\n if (!this.annotations.length) return;\n const next = (this.annotationIndex + 1) % this.annotations.length;\n this.selectAnnotation(next);\n }\n\n private selectAnnotation(index: number): void {\n const box = this.annotations[index];\n if (!box) return;\n this.multiSelectedKeys.clear();\n this.ctxVisible = false;\n this.clickedBoxKey = this.boxKey(box);\n this.cdr.detectChanges();\n this.scrollToBox(box);\n if (this.apiKeyValid) {\n this.boxClicked.emit({ box, selected: true });\n }\n }\n\n // ─────────────────────────────────────────────\n // Toolbar – selection mode\n // ─────────────────────────────────────────────\n\n toggleSelectionMode(): void {\n this.selectionMode = this.selectionMode === 'select-area' ? 'select-text' : 'select-area';\n if (this.selectionMode === 'select-text') {\n this.renderedPages.forEach(rp => this.renderTextLayer(rp.pageNum));\n } else {\n this.removeAllTextLayers();\n }\n this.cdr.detectChanges();\n }\n\n /**\n * Returns the CSS matrix() transform that aligns the pdfjs text layer\n * (always sized in *unrotated* page space) with the rotated canvas.\n * pi.width / pi.height are the *canvas* (rotated) pixel dimensions.\n */\n private textLayerTransform(totalRotation: number, canvasW: number, canvasH: number): string {\n const norm = ((totalRotation % 360) + 360) % 360;\n switch (norm) {\n // 90 ° CW: (x,y) → (H−y, x) where H = canvas width after swap\n case 90: return `matrix(0,1,-1,0,${canvasW},0)`;\n // 180 °: (x,y) → (W−x, H−y)\n case 180: return `matrix(-1,0,0,-1,${canvasW},${canvasH})`;\n // 270 ° CW: (x,y) → (y, W−x) where W = canvas height after swap\n case 270: return `matrix(0,-1,1,0,0,${canvasH})`;\n default: return '';\n }\n }\n\n private async renderTextLayer(pageNum: number): Promise<void> {\n if (!this.pdfDoc) return;\n const pi = this.getPageInfo(pageNum);\n if (!pi) return;\n\n const wrapper = document.getElementById(`npv-page-${pageNum}`) as HTMLElement | null;\n if (!wrapper) return;\n\n this.removeTextLayer(pageNum);\n\n const page = await this.pdfDoc.getPage(pageNum);\n const totalRotation = (page.rotate + this.userRotation) % 360;\n const viewport = page.getViewport({ scale: this.zoom, rotation: totalRotation });\n\n const div = document.createElement('div');\n // 'textLayer' class is required for the injected pdfjs CSS rules to apply.\n div.className = 'npv-text-layer textLayer';\n // pdfjs sizes the container with calc(var(--scale-factor) * rawPageWidth).\n // Without this variable every calc() is invalid → container collapses to 0.\n div.style.setProperty('--scale-factor', String(this.zoom));\n // pdfjs always lays text out in unrotated page space; align with rotated canvas.\n const transform = this.textLayerTransform(totalRotation, pi.width, pi.height);\n if (transform) div.style.transform = transform;\n\n wrapper.appendChild(div);\n\n const textLayer = new (pdfjsLib as any).TextLayer({\n textContentSource: page.streamTextContent(),\n container: div,\n viewport,\n });\n\n this.textLayers.set(pageNum, textLayer);\n try {\n await textLayer.render();\n } catch (e: any) {\n if (e?.name !== 'AbortException') console.error('TextLayer render error:', e);\n }\n page.cleanup();\n }\n\n private removeTextLayer(pageNum: number): void {\n const tl = this.textLayers.get(pageNum);\n if (tl) {\n try { tl.cancel(); } catch (_) {}\n this.textLayers.delete(pageNum);\n }\n const wrapper = document.getElementById(`npv-page-${pageNum}`);\n wrapper?.querySelector('.npv-text-layer')?.remove();\n }\n\n private removeAllTextLayers(): void {\n for (const pageNum of Array.from(this.textLayers.keys())) {\n this.removeTextLayer(pageNum);\n }\n }\n\n // ─────────────────────────────────────────────\n // Scroll tracking\n // ─────────────────────────────────────────────\n\n onContainerScroll(): void {\n if (!this.pdfContainer) return;\n const top = this.pdfContainer.nativeElement.scrollTop;\n let closest = 1, minDist = Infinity;\n for (let p = 1; p <= this.totalPages; p++) {\n const el = document.getElementById(`npv-page-${p}`) as HTMLElement | null;\n if (!el) continue;\n const dist = Math.abs(el.offsetTop - top);\n if (dist < minDist) { minDist = dist; closest = p; }\n }\n if (this.currentPage !== closest) { this.currentPage = closest; this.cdr.detectChanges(); }\n }\n}\n","<div class=\"npv-root\">\n\n <!-- ─────────── Toolbar ─────────── -->\n <div class=\"npv-toolbar\">\n\n <!-- Zoom -->\n <ng-container *ngIf=\"showZoom\">\n <button mat-icon-button [matTooltip]=\"l.zoomOut\" (click)=\"zoomOut()\" [disabled]=\"zoom <= 0.25\">\n <mat-icon>zoom_out</mat-icon>\n </button>\n <span class=\"npv-label\">{{ zoomPercent }}%</span>\n <button mat-icon-button [matTooltip]=\"l.zoomIn\" (click)=\"zoomIn()\" [disabled]=\"zoom >= 5\">\n <mat-icon>zoom_in</mat-icon>\n </button>\n </ng-container>\n\n <!-- Rotation -->\n <ng-container *ngIf=\"showRotation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom\"></div>\n <button mat-icon-button [matTooltip]=\"l.rotateLeft\" (click)=\"rotateLeft()\">\n <mat-icon>rotate_left</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.rotateRight\" (click)=\"rotateRight()\">\n <mat-icon>rotate_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Page navigation -->\n <ng-container *ngIf=\"showPageNavigation\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousPage\" (click)=\"goToPrevPage()\" [disabled]=\"currentPage <= 1\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <span class=\"npv-label\">{{ currentPage }} / {{ totalPages }}</span>\n <button mat-icon-button [matTooltip]=\"l.nextPage\" (click)=\"goToNextPage()\" [disabled]=\"currentPage >= totalPages\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </ng-container>\n\n <!-- Annotation navigation -->\n <ng-container *ngIf=\"showAnnotationNavigation && annotations.length\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation\"></div>\n <button mat-icon-button [matTooltip]=\"l.previousAnnotation\" (click)=\"goToPrevAnnotation()\">\n <mat-icon>navigate_before</mat-icon>\n </button>\n <span class=\"npv-label\">\n {{ annotationIndex >= 0 ? annotationIndex + 1 : '–' }} / {{ annotations.length }}\n </span>\n <button mat-icon-button [matTooltip]=\"l.nextAnnotation\" (click)=\"goToNextAnnotation()\">\n <mat-icon>navigate_next</mat-icon>\n </button>\n </ng-container>\n\n <!-- Selection mode toggle -->\n <ng-container *ngIf=\"showSelectionMode\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0)\"></div>\n <button mat-icon-button\n [matTooltip]=\"selectionMode === 'select-area' ? l.selectText : l.selectArea\"\n (click)=\"toggleSelectionMode()\"\n [class.npv-active]=\"selectionMode === 'select-text'\">\n <mat-icon>text_fields</mat-icon>\n </button>\n </ng-container>\n\n <!-- Search -->\n <ng-container *ngIf=\"showSearch\">\n <div class=\"npv-sep\" *ngIf=\"showZoom || showRotation || showPageNavigation || (showAnnotationNavigation && annotations.length > 0) || showSelectionMode\"></div>\n <button mat-icon-button [matTooltip]=\"l.search\" (click)=\"toggleSearch()\" [class.npv-active]=\"searchVisible\">\n <mat-icon>search</mat-icon>\n </button>\n <ng-container *ngIf=\"searchVisible\">\n <input\n class=\"npv-search-input\"\n type=\"text\"\n [placeholder]=\"l.searchPlaceholder\"\n [(ngModel)]=\"searchQuery\"\n (input)=\"onSearchInput()\"\n (keydown.enter)=\"searchNext()\"\n (keydown.shift.enter)=\"searchPrev()\"\n autofocus\n />\n <button mat-icon-button [matTooltip]=\"l.previousResult\"\n (click)=\"searchPrev()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_less</mat-icon>\n </button>\n <button mat-icon-button [matTooltip]=\"l.nextResult\"\n (click)=\"searchNext()\" [disabled]=\"!searchMatches.length\">\n <mat-icon>expand_more</mat-icon>\n </button>\n <span class=\"npv-search-count\" *ngIf=\"searchMatches.length\">\n {{ searchIndex + 1 }} / {{ searchMatches.length }}\n </span>\n <span class=\"npv-search-count npv-no-match\" *ngIf=\"searchQuery && !searchMatches.length\">\n {{ l.noResults }}\n </span>\n </ng-container>\n </ng-container>\n\n </div>\n\n <!-- ─────────── Loading ─────────── -->\n <div class=\"npv-loading\" *ngIf=\"loading\">\n <span class=\"npv-spinner\"></span> {{ l.loading }}\n </div>\n\n <!-- ─────────── Scroll area ─────────── -->\n <div class=\"npv-scroll-area\" #pdfContainer\n (scroll)=\"onContainerScroll()\" (click)=\"ctxVisible = false\">\n <div class=\"npv-scroll-inner\">\n\n <ng-container *ngFor=\"let p of pageRange()\">\n <div class=\"npv-page-wrapper\" [id]=\"'npv-page-' + p\">\n\n <canvas [id]=\"'npv-canvas-' + p\" class=\"npv-canvas\"></canvas>\n\n <svg *ngIf=\"getPageInfo(p) as pi\"\n [id]=\"'npv-svg-' + p\"\n class=\"npv-overlay\"\n [class.npv-overlay--text-mode]=\"selectionMode === 'select-text'\"\n [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n [attr.viewBox]=\"'0 0 ' + pi.width + ' ' + pi.height\"\n (mousedown)=\"onSvgMouseDown($event, p)\">\n\n <!-- Hit area for drag selection on empty page space -->\n <rect x=\"0\" y=\"0\" [attr.width]=\"pi.width\" [attr.height]=\"pi.height\"\n fill=\"transparent\"></rect>\n\n <!-- Annotation boxes -->\n <polygon\n *ngFor=\"let box of getBoxesForPage(p)\"\n [attr.points]=\"getSvgPoints(box, pi)\"\n class=\"npv-box\"\n [class.npv-box--clicked]=\"isClicked(box)\"\n [class.npv-box--multi]=\"isMultiSelected(box)\"\n [style.fill]=\"isClicked(box) ? highlightingColor : (isMultiSelected(box) ? selectedColor : 'transparent')\"\n [style.stroke]=\"annotationStroke\"\n (click)=\"onBoxClick($event, box)\">\n <title>{{ box.content || '' }}</title>\n </polygon>\n\n <!-- Search highlights -->\n <polygon\n *ngFor=\"let m of getSearchMatchesForPage(p); let mi = index\"\n [attr.points]=\"searchMatchPoints(m)\"\n class=\"npv-search-highlight\"\n [class.npv-search-highlight--current]=\"isCurrentSearchMatch(p, mi)\">\n </polygon>\n\n <!-- Drag selection rectangle -->\n <rect *ngIf=\"getDragRect(p) as dr\"\n [attr.x]=\"dr.x\" [attr.y]=\"dr.y\"\n [attr.width]=\"dr.w\" [attr.height]=\"dr.h\"\n class=\"npv-drag-rect\">\n </rect>\n\n </svg>\n </div>\n </ng-container>\n\n <div class=\"npv-placeholder npv-placeholder--error\" *ngIf=\"!loading && loadError\">\n {{ l.loadError }}\n </div>\n <div class=\"npv-placeholder\" *ngIf=\"!loading && !loadError && totalPages === 0\">\n {{ l.noDocument }}\n </div>\n\n </div><!-- /npv-scroll-inner -->\n </div>\n\n <!-- ─────────── Context menu ─────────── -->\n <div *ngIf=\"ctxVisible && contextMenuItems.length\"\n class=\"npv-context-menu\"\n [style.left.px]=\"ctxX\" [style.top.px]=\"ctxY\"\n (click)=\"$event.stopPropagation()\">\n <div *ngFor=\"let item of contextMenuItems\"\n class=\"npv-context-item\"\n (click)=\"onContextMenuAction(item)\">\n {{ item.label }}\n </div>\n </div>\n\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -109,6 +109,12 @@ declare class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterVi
109
109
  showSelectionMode: boolean;
110
110
  /** Show / hide the search button and search bar */
111
111
  showSearch: boolean;
112
+ /**
113
+ * API key for enabling output triggers (boxClicked, boxesSelected).
114
+ * When provided it must be a valid key generated by api-keys/generate.js.
115
+ * Output events are silently suppressed while the key is absent or invalid.
116
+ */
117
+ apiKey: string | undefined;
112
118
  private static readonly DEFAULT_LABELS;
113
119
  get l(): PdfViewerLabels;
114
120
  /** Fired when the user clicks a single annotation box */
@@ -141,6 +147,8 @@ declare class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterVi
141
147
  selectionMode: 'select-area' | 'select-text';
142
148
  loading: boolean;
143
149
  loadError: boolean;
150
+ /** True once the current apiKey has been verified against the embedded public key. */
151
+ apiKeyValid: boolean;
144
152
  private renderTasks;
145
153
  private textLayers;
146
154
  private wheelListener?;
@@ -150,6 +158,18 @@ declare class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterVi
150
158
  ngAfterViewInit(): void;
151
159
  ngOnChanges(changes: SimpleChanges): void;
152
160
  ngOnDestroy(): void;
161
+ /** Decodes a base64url string to a Uint8Array (no external dependencies). */
162
+ private b64urlToBytes;
163
+ /**
164
+ * Verifies an API key against the embedded RSA-2048 public key.
165
+ * Format: <payload_base64url>.<signature_base64url>
166
+ *
167
+ * Returns false when:
168
+ * - the format is invalid
169
+ * - the RSA signature does not match
170
+ * - the key type is "trial" and its expiry timestamp has passed
171
+ */
172
+ private verifyApiKey;
153
173
  private loadPdf;
154
174
  private computeFitZoom;
155
175
  private renderPage;
@@ -212,7 +232,7 @@ declare class NgxNextPdfViewerComponent implements OnChanges, OnDestroy, AfterVi
212
232
  private removeAllTextLayers;
213
233
  onContainerScroll(): void;
214
234
  static ɵfac: i0.ɵɵFactoryDeclaration<NgxNextPdfViewerComponent, never>;
215
- static ɵcmp: i0.ɵɵComponentDeclaration<NgxNextPdfViewerComponent, "ngx-next-pdf-viewer", never, { "blob": { "alias": "blob"; "required": false; }; "annotations": { "alias": "annotations"; "required": false; }; "contextMenuItems": { "alias": "contextMenuItems"; "required": false; }; "highlightingColor": { "alias": "highlightingColor"; "required": false; }; "selectedColor": { "alias": "selectedColor"; "required": false; }; "annotationStroke": { "alias": "annotationStroke"; "required": false; }; "initialZoom": { "alias": "initialZoom"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "showZoom": { "alias": "showZoom"; "required": false; }; "showRotation": { "alias": "showRotation"; "required": false; }; "showPageNavigation": { "alias": "showPageNavigation"; "required": false; }; "showAnnotationNavigation": { "alias": "showAnnotationNavigation"; "required": false; }; "showSelectionMode": { "alias": "showSelectionMode"; "required": false; }; "showSearch": { "alias": "showSearch"; "required": false; }; }, { "boxClicked": "boxClicked"; "boxesSelected": "boxesSelected"; }, never, never, true, never>;
235
+ static ɵcmp: i0.ɵɵComponentDeclaration<NgxNextPdfViewerComponent, "ngx-next-pdf-viewer", never, { "blob": { "alias": "blob"; "required": false; }; "annotations": { "alias": "annotations"; "required": false; }; "contextMenuItems": { "alias": "contextMenuItems"; "required": false; }; "highlightingColor": { "alias": "highlightingColor"; "required": false; }; "selectedColor": { "alias": "selectedColor"; "required": false; }; "annotationStroke": { "alias": "annotationStroke"; "required": false; }; "initialZoom": { "alias": "initialZoom"; "required": false; }; "labels": { "alias": "labels"; "required": false; }; "showZoom": { "alias": "showZoom"; "required": false; }; "showRotation": { "alias": "showRotation"; "required": false; }; "showPageNavigation": { "alias": "showPageNavigation"; "required": false; }; "showAnnotationNavigation": { "alias": "showAnnotationNavigation"; "required": false; }; "showSelectionMode": { "alias": "showSelectionMode"; "required": false; }; "showSearch": { "alias": "showSearch"; "required": false; }; "apiKey": { "alias": "apiKey"; "required": false; }; }, { "boxClicked": "boxClicked"; "boxesSelected": "boxesSelected"; }, never, never, true, never>;
216
236
  }
217
237
 
218
238
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aprova.ch/ngx-next-pdf-viewer",
3
- "version": "20.0.9",
3
+ "version": "20.0.10",
4
4
  "description": "Angular PDF viewer with bounding-box annotations, search, zoom and page rotation",
5
5
  "keywords": [
6
6
  "angular",