@forgeroute/ui 0.3.11 → 0.3.13
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.
- package/fesm2022/forgeroute-ui-pdf.mjs +125 -6
- package/fesm2022/forgeroute-ui-pdf.mjs.map +1 -1
- package/fesm2022/forgeroute-ui.mjs +3468 -115
- package/fesm2022/forgeroute-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/forgeroute-ui-pdf.d.ts +75 -4
- package/types/forgeroute-ui.d.ts +1318 -57
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isPlatformBrowser } from "@angular/common";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, InjectionToken, Injector, PLATFORM_ID, afterNextRender, computed, effect, inject, input, output, signal, untracked } from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, InjectionToken, Injector, PLATFORM_ID, afterNextRender, computed, effect, inject, input, makeEnvironmentProviders, output, signal, untracked } from "@angular/core";
|
|
4
4
|
const PDF_VIEWER_WORKER_SRC = new InjectionToken("PDF_VIEWER_WORKER_SRC", {
|
|
5
5
|
providedIn: "root",
|
|
6
6
|
factory: () => ""
|
|
@@ -10,6 +10,34 @@ const DEFAULT_FIELD_HEIGHT = 14;
|
|
|
10
10
|
const MAX_CANVAS_PIXELS = 16e6;
|
|
11
11
|
const MAX_TOTAL_CANVAS_PIXELS = 48e6;
|
|
12
12
|
const WORKER_MISSING = "PDF worker is not configured.";
|
|
13
|
+
const PDF_VIEWER_REQUIRED_FEATURES = [
|
|
14
|
+
"Promise.withResolvers",
|
|
15
|
+
"Promise.try",
|
|
16
|
+
"Map.prototype.getOrInsertComputed",
|
|
17
|
+
"Math.sumPrecise",
|
|
18
|
+
"Iterator",
|
|
19
|
+
"URL.parse"
|
|
20
|
+
];
|
|
21
|
+
function findMissingPdfFeatures(scope = globalThis, needsUrl = true) {
|
|
22
|
+
const g = scope;
|
|
23
|
+
const has = {
|
|
24
|
+
"Promise.withResolvers": () => typeof g["Promise"]?.withResolvers === "function",
|
|
25
|
+
"Promise.try": () => typeof g["Promise"]?.try === "function",
|
|
26
|
+
"Map.prototype.getOrInsertComputed": () => typeof g["Map"]?.prototype?.getOrInsertComputed === "function",
|
|
27
|
+
"Math.sumPrecise": () => typeof g["Math"]?.sumPrecise === "function",
|
|
28
|
+
"Iterator": () => typeof g["Iterator"] === "function" && typeof g["Iterator"].prototype === "object",
|
|
29
|
+
"URL.parse": () => !needsUrl || typeof g["URL"]?.parse === "function"
|
|
30
|
+
};
|
|
31
|
+
return PDF_VIEWER_REQUIRED_FEATURES.filter((f) => !has[f]());
|
|
32
|
+
}
|
|
33
|
+
var PdfViewerUnsupportedError = class extends Error {
|
|
34
|
+
constructor(missing) {
|
|
35
|
+
super("This browser cannot run pdf.js; missing: " + missing.join(", "));
|
|
36
|
+
this.missing = missing;
|
|
37
|
+
this.reason = "unsupported-browser";
|
|
38
|
+
this.name = "PdfViewerUnsupportedError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
13
41
|
var PdfViewerComponent = class PdfViewerComponent {
|
|
14
42
|
constructor() {
|
|
15
43
|
this.src = input(null, ...ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []);
|
|
@@ -23,6 +51,9 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
23
51
|
this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
|
|
24
52
|
this.loadingText = input("Loading document…", ...ngDevMode ? [{ debugName: "loadingText" }] : /* istanbul ignore next */ []);
|
|
25
53
|
this.errorText = input("Failed to load document.", ...ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []);
|
|
54
|
+
this.unsupportedText = input("This browser can't show the document preview.", ...ngDevMode ? [{ debugName: "unsupportedText" }] : /* istanbul ignore next */ []);
|
|
55
|
+
this.openText = input("Open the document", ...ngDevMode ? [{ debugName: "openText" }] : /* istanbul ignore next */ []);
|
|
56
|
+
this.checkBrowserSupport = input(true, ...ngDevMode ? [{ debugName: "checkBrowserSupport" }] : /* istanbul ignore next */ []);
|
|
26
57
|
this.loaded = output();
|
|
27
58
|
this.loadFailed = output();
|
|
28
59
|
this.pagesRendered = output();
|
|
@@ -30,7 +61,12 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
30
61
|
this.pageSizes = signal([], ...ngDevMode ? [{ debugName: "pageSizes" }] : /* istanbul ignore next */ []);
|
|
31
62
|
this.containerWidth = signal(0, ...ngDevMode ? [{ debugName: "containerWidth" }] : /* istanbul ignore next */ []);
|
|
32
63
|
this.customError = signal("", ...ngDevMode ? [{ debugName: "customError" }] : /* istanbul ignore next */ []);
|
|
64
|
+
this.openUrl = computed(() => this.data() == null ? this.src() || "" : "", ...ngDevMode ? [{ debugName: "openUrl" }] : /* istanbul ignore next */ []);
|
|
33
65
|
this.errorMessage = computed(() => this.customError() || this.errorText(), ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
|
|
66
|
+
this.liveText = computed(() => {
|
|
67
|
+
const status = this.status();
|
|
68
|
+
return status === "loading" ? this.loadingText() : status === "unsupported" ? this.unsupportedText() : "";
|
|
69
|
+
}, ...ngDevMode ? [{ debugName: "liveText" }] : /* istanbul ignore next */ []);
|
|
34
70
|
this.drawKey = computed(() => this.views().map((v) => v.canvasWidth + "x" + v.canvasHeight).join("|"), ...ngDevMode ? [{ debugName: "drawKey" }] : /* istanbul ignore next */ []);
|
|
35
71
|
this.effectiveWidth = computed(() => this.widthFor(this.containerWidth()), ...ngDevMode ? [{ debugName: "effectiveWidth" }] : /* istanbul ignore next */ []);
|
|
36
72
|
this.views = computed(() => {
|
|
@@ -115,6 +151,7 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
115
151
|
this.headersKey();
|
|
116
152
|
this.withCredentials();
|
|
117
153
|
this.workerSrc();
|
|
154
|
+
this.checkBrowserSupport();
|
|
118
155
|
if (!this.isBrowser) return;
|
|
119
156
|
untracked(() => void this.startLoad());
|
|
120
157
|
});
|
|
@@ -139,6 +176,9 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
139
176
|
loadPdfJs() {
|
|
140
177
|
return import("pdfjs-dist");
|
|
141
178
|
}
|
|
179
|
+
missingFeatures(needsUrl) {
|
|
180
|
+
return findMissingPdfFeatures(globalThis, needsUrl);
|
|
181
|
+
}
|
|
142
182
|
resolvedRatio() {
|
|
143
183
|
const explicit = this.pixelRatio();
|
|
144
184
|
if (explicit != null && explicit > 0) return explicit;
|
|
@@ -161,6 +201,16 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
161
201
|
this.status.set("idle");
|
|
162
202
|
return;
|
|
163
203
|
}
|
|
204
|
+
if (this.checkBrowserSupport()) {
|
|
205
|
+
const missing = this.missingFeatures(data == null);
|
|
206
|
+
if (missing.length > 0) {
|
|
207
|
+
this.loadToken++;
|
|
208
|
+
this.pageSizes.set([]);
|
|
209
|
+
this.status.set("unsupported");
|
|
210
|
+
this.loadFailed.emit(new PdfViewerUnsupportedError(missing));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
164
214
|
this.containerWidth.set(this.host.nativeElement.clientWidth);
|
|
165
215
|
this.status.set("loading");
|
|
166
216
|
try {
|
|
@@ -391,6 +441,27 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
391
441
|
isSignal: true,
|
|
392
442
|
isRequired: false,
|
|
393
443
|
transformFunction: null
|
|
444
|
+
},
|
|
445
|
+
unsupportedText: {
|
|
446
|
+
classPropertyName: "unsupportedText",
|
|
447
|
+
publicName: "unsupportedText",
|
|
448
|
+
isSignal: true,
|
|
449
|
+
isRequired: false,
|
|
450
|
+
transformFunction: null
|
|
451
|
+
},
|
|
452
|
+
openText: {
|
|
453
|
+
classPropertyName: "openText",
|
|
454
|
+
publicName: "openText",
|
|
455
|
+
isSignal: true,
|
|
456
|
+
isRequired: false,
|
|
457
|
+
transformFunction: null
|
|
458
|
+
},
|
|
459
|
+
checkBrowserSupport: {
|
|
460
|
+
classPropertyName: "checkBrowserSupport",
|
|
461
|
+
publicName: "checkBrowserSupport",
|
|
462
|
+
isSignal: true,
|
|
463
|
+
isRequired: false,
|
|
464
|
+
transformFunction: null
|
|
394
465
|
}
|
|
395
466
|
},
|
|
396
467
|
outputs: {
|
|
@@ -402,10 +473,18 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
402
473
|
template: `
|
|
403
474
|
<div class="pv-root" [attr.role]="ariaLabel() ? 'region' : null" [attr.aria-label]="ariaLabel() || null"
|
|
404
475
|
[attr.aria-busy]="status() === 'loading'">
|
|
405
|
-
<div class="pv-live" role="status" aria-live="polite">{{
|
|
476
|
+
<div class="pv-live" role="status" aria-live="polite">{{ liveText() }}</div>
|
|
406
477
|
@switch (status()) {
|
|
407
478
|
@case ('loading') { <div class="pv-state pv-loading" aria-hidden="true">{{ loadingText() }}</div> }
|
|
408
479
|
@case ('error') { <div class="pv-state pv-error" role="alert">{{ errorMessage() }}</div> }
|
|
480
|
+
@case ('unsupported') {
|
|
481
|
+
<div class="pv-state pv-unsupported">
|
|
482
|
+
<p class="pv-unsupported-text">{{ unsupportedText() }}</p>
|
|
483
|
+
@if (openUrl(); as url) {
|
|
484
|
+
<a class="pv-open" [href]="url" target="_blank" rel="noopener">{{ openText() }}<span class="pv-sr"> (opens in a new tab)</span></a>
|
|
485
|
+
}
|
|
486
|
+
</div>
|
|
487
|
+
}
|
|
409
488
|
@case ('ready') {
|
|
410
489
|
<div class="pv-pages">
|
|
411
490
|
@for (p of views(); track p.number) {
|
|
@@ -427,7 +506,7 @@ var PdfViewerComponent = class PdfViewerComponent {
|
|
|
427
506
|
</div>
|
|
428
507
|
`,
|
|
429
508
|
isInline: true,
|
|
430
|
-
styles: [":host{display:block;width:100%}.pv-root{position:relative}.pv-live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pv-state{display:flex;align-items:center;justify-content:center;width:100%;min-height:12rem;padding:0 16px;text-align:center;font-size:.8125rem;line-height:1.4;overflow-wrap:anywhere;box-sizing:border-box}.pv-loading{color:#64748b}.pv-error{color:#dc2626}.pv-pages{display:flex;flex-direction:column;gap:16px;width:100%;max-width:100%}.pv-page{position:relative;margin:0 auto;max-width:100%}.pv-canvas{display:block;width:100%;height:auto;background:#fff;border-radius:2px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.pv-field{position:absolute;display:flex;align-items:center;box-sizing:border-box;padding:0 4px;overflow:hidden;pointer-events:none;border:1px solid;border-radius:2px;-webkit-user-select:none;user-select:none}.pv-field-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1}.pv-tone-blue{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8}.pv-tone-green{background:#dcfce7;border-color:#86efac;color:#15803d}.pv-tone-amber{background:#fef3c7;border-color:#fcd34d;color:#92400e}.pv-tone-red{background:#fee2e2;border-color:#fca5a5;color:#b91c1c}.pv-tone-slate{background:#f1f5f9;border-color:#cbd5e1;color:#334155}\n"],
|
|
509
|
+
styles: [":host{display:block;width:100%}.pv-root{position:relative}.pv-live,.pv-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pv-state{display:flex;align-items:center;justify-content:center;width:100%;min-height:12rem;padding:0 16px;text-align:center;font-size:.8125rem;line-height:1.4;overflow-wrap:anywhere;box-sizing:border-box}.pv-loading{color:#64748b}.pv-error{color:#dc2626}.pv-unsupported{flex-direction:column;gap:8px;color:#334155}.pv-unsupported-text{margin:0}.pv-open{display:inline-flex;align-items:center;justify-content:center;position:relative;min-height:44px;min-width:44px;padding:0 16px;box-sizing:border-box;color:#1d4ed8;font-weight:600;text-decoration:underline;border-radius:6px}.pv-open:focus-visible{outline:2px solid #1d4ed8;outline-offset:2px}.pv-pages{display:flex;flex-direction:column;gap:16px;width:100%;max-width:100%}.pv-page{position:relative;margin:0 auto;max-width:100%}.pv-canvas{display:block;width:100%;height:auto;background:#fff;border-radius:2px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.pv-field{position:absolute;display:flex;align-items:center;box-sizing:border-box;padding:0 4px;overflow:hidden;pointer-events:none;border:1px solid;border-radius:2px;-webkit-user-select:none;user-select:none}.pv-field-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1}.pv-tone-blue{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8}.pv-tone-green{background:#dcfce7;border-color:#86efac;color:#15803d}.pv-tone-amber{background:#fef3c7;border-color:#fcd34d;color:#92400e}.pv-tone-red{background:#fee2e2;border-color:#fca5a5;color:#b91c1c}.pv-tone-slate{background:#f1f5f9;border-color:#cbd5e1;color:#334155}\n"],
|
|
431
510
|
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
432
511
|
});
|
|
433
512
|
}
|
|
@@ -446,10 +525,18 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
446
525
|
template: `
|
|
447
526
|
<div class="pv-root" [attr.role]="ariaLabel() ? 'region' : null" [attr.aria-label]="ariaLabel() || null"
|
|
448
527
|
[attr.aria-busy]="status() === 'loading'">
|
|
449
|
-
<div class="pv-live" role="status" aria-live="polite">{{
|
|
528
|
+
<div class="pv-live" role="status" aria-live="polite">{{ liveText() }}</div>
|
|
450
529
|
@switch (status()) {
|
|
451
530
|
@case ('loading') { <div class="pv-state pv-loading" aria-hidden="true">{{ loadingText() }}</div> }
|
|
452
531
|
@case ('error') { <div class="pv-state pv-error" role="alert">{{ errorMessage() }}</div> }
|
|
532
|
+
@case ('unsupported') {
|
|
533
|
+
<div class="pv-state pv-unsupported">
|
|
534
|
+
<p class="pv-unsupported-text">{{ unsupportedText() }}</p>
|
|
535
|
+
@if (openUrl(); as url) {
|
|
536
|
+
<a class="pv-open" [href]="url" target="_blank" rel="noopener">{{ openText() }}<span class="pv-sr"> (opens in a new tab)</span></a>
|
|
537
|
+
}
|
|
538
|
+
</div>
|
|
539
|
+
}
|
|
453
540
|
@case ('ready') {
|
|
454
541
|
<div class="pv-pages">
|
|
455
542
|
@for (p of views(); track p.number) {
|
|
@@ -470,7 +557,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
470
557
|
}
|
|
471
558
|
</div>
|
|
472
559
|
`,
|
|
473
|
-
styles: [":host{display:block;width:100%}.pv-root{position:relative}.pv-live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pv-state{display:flex;align-items:center;justify-content:center;width:100%;min-height:12rem;padding:0 16px;text-align:center;font-size:.8125rem;line-height:1.4;overflow-wrap:anywhere;box-sizing:border-box}.pv-loading{color:#64748b}.pv-error{color:#dc2626}.pv-pages{display:flex;flex-direction:column;gap:16px;width:100%;max-width:100%}.pv-page{position:relative;margin:0 auto;max-width:100%}.pv-canvas{display:block;width:100%;height:auto;background:#fff;border-radius:2px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.pv-field{position:absolute;display:flex;align-items:center;box-sizing:border-box;padding:0 4px;overflow:hidden;pointer-events:none;border:1px solid;border-radius:2px;-webkit-user-select:none;user-select:none}.pv-field-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1}.pv-tone-blue{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8}.pv-tone-green{background:#dcfce7;border-color:#86efac;color:#15803d}.pv-tone-amber{background:#fef3c7;border-color:#fcd34d;color:#92400e}.pv-tone-red{background:#fee2e2;border-color:#fca5a5;color:#b91c1c}.pv-tone-slate{background:#f1f5f9;border-color:#cbd5e1;color:#334155}\n"]
|
|
560
|
+
styles: [":host{display:block;width:100%}.pv-root{position:relative}.pv-live,.pv-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.pv-state{display:flex;align-items:center;justify-content:center;width:100%;min-height:12rem;padding:0 16px;text-align:center;font-size:.8125rem;line-height:1.4;overflow-wrap:anywhere;box-sizing:border-box}.pv-loading{color:#64748b}.pv-error{color:#dc2626}.pv-unsupported{flex-direction:column;gap:8px;color:#334155}.pv-unsupported-text{margin:0}.pv-open{display:inline-flex;align-items:center;justify-content:center;position:relative;min-height:44px;min-width:44px;padding:0 16px;box-sizing:border-box;color:#1d4ed8;font-weight:600;text-decoration:underline;border-radius:6px}.pv-open:focus-visible{outline:2px solid #1d4ed8;outline-offset:2px}.pv-pages{display:flex;flex-direction:column;gap:16px;width:100%;max-width:100%}.pv-page{position:relative;margin:0 auto;max-width:100%}.pv-canvas{display:block;width:100%;height:auto;background:#fff;border-radius:2px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.pv-field{position:absolute;display:flex;align-items:center;box-sizing:border-box;padding:0 4px;overflow:hidden;pointer-events:none;border:1px solid;border-radius:2px;-webkit-user-select:none;user-select:none}.pv-field-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1}.pv-tone-blue{background:#dbeafe;border-color:#93c5fd;color:#1d4ed8}.pv-tone-green{background:#dcfce7;border-color:#86efac;color:#15803d}.pv-tone-amber{background:#fef3c7;border-color:#fcd34d;color:#92400e}.pv-tone-red{background:#fee2e2;border-color:#fca5a5;color:#b91c1c}.pv-tone-slate{background:#f1f5f9;border-color:#cbd5e1;color:#334155}\n"]
|
|
474
561
|
}]
|
|
475
562
|
}],
|
|
476
563
|
ctorParameters: () => [],
|
|
@@ -563,6 +650,30 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
563
650
|
required: false
|
|
564
651
|
}]
|
|
565
652
|
}],
|
|
653
|
+
unsupportedText: [{
|
|
654
|
+
type: i0.Input,
|
|
655
|
+
args: [{
|
|
656
|
+
isSignal: true,
|
|
657
|
+
alias: "unsupportedText",
|
|
658
|
+
required: false
|
|
659
|
+
}]
|
|
660
|
+
}],
|
|
661
|
+
openText: [{
|
|
662
|
+
type: i0.Input,
|
|
663
|
+
args: [{
|
|
664
|
+
isSignal: true,
|
|
665
|
+
alias: "openText",
|
|
666
|
+
required: false
|
|
667
|
+
}]
|
|
668
|
+
}],
|
|
669
|
+
checkBrowserSupport: [{
|
|
670
|
+
type: i0.Input,
|
|
671
|
+
args: [{
|
|
672
|
+
isSignal: true,
|
|
673
|
+
alias: "checkBrowserSupport",
|
|
674
|
+
required: false
|
|
675
|
+
}]
|
|
676
|
+
}],
|
|
566
677
|
loaded: [{
|
|
567
678
|
type: i0.Output,
|
|
568
679
|
args: ["loaded"]
|
|
@@ -577,6 +688,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
577
688
|
}]
|
|
578
689
|
}
|
|
579
690
|
});
|
|
580
|
-
|
|
691
|
+
function provideForgeroutePdf(options) {
|
|
692
|
+
const workerSrc = typeof options?.workerSrc === "string" ? options.workerSrc.trim() : "";
|
|
693
|
+
if (!workerSrc) throw new Error("provideForgeroutePdf: \"workerSrc\" must be a non-empty URL of the pdf.js worker script (for example \"/pdf.worker.min.mjs\").");
|
|
694
|
+
return makeEnvironmentProviders([{
|
|
695
|
+
provide: PDF_VIEWER_WORKER_SRC,
|
|
696
|
+
useValue: workerSrc
|
|
697
|
+
}]);
|
|
698
|
+
}
|
|
699
|
+
export { PDF_VIEWER_REQUIRED_FEATURES, PDF_VIEWER_WORKER_SRC, PdfViewerComponent, PdfViewerUnsupportedError, findMissingPdfFeatures, provideForgeroutePdf };
|
|
581
700
|
|
|
582
701
|
//# sourceMappingURL=forgeroute-ui-pdf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forgeroute-ui-pdf.mjs","names":[],"sources":["../../../projects/forgeroute-ui/pdf/src/pdf-viewer/pdf-viewer.component.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n PLATFORM_ID, Component, ChangeDetectionStrategy, DestroyRef, ElementRef, InjectionToken, Injector, afterNextRender, computed, effect,\n inject, input, output, signal, untracked,\n} from '@angular/core';\nimport type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';\n\n/** Where pdf.js finds its worker script. Provide it once in the app (`{ provide: PDF_VIEWER_WORKER_SRC, useValue: '/assets/pdf.worker.min.mjs' }`). */\nexport const PDF_VIEWER_WORKER_SRC = new InjectionToken<string>('PDF_VIEWER_WORKER_SRC', { providedIn: 'root', factory: () => '' });\n\n/** Colour of an overlay badge. */\nexport type PdfViewerTone = 'blue' | 'green' | 'amber' | 'red' | 'slate';\n\n/** A labelled box drawn over a page. Positions are PDF points with the origin at the page's bottom-left corner. */\nexport interface PdfViewerField {\n id: string;\n /** 1-based page number; a field on a page that does not exist is ignored. */\n page: number;\n /** Bottom-left corner of the box, in PDF points. */\n x: number;\n y: number;\n /** Size in PDF points. Without a width the box fits its label; the default height is 14. */\n width?: number;\n height?: number;\n label: string;\n tone?: PdfViewerTone;\n}\n\nexport interface PdfViewerLoadedEvent {\n pageCount: number;\n /** Every page's size in PDF points at scale 1. */\n pages: { width: number; height: number }[];\n /** The loaded pdf.js document, so the host can read text content. The viewer destroys it when it is replaced or the viewer goes away. */\n document: PDFDocumentProxy;\n}\n\nexport interface PdfViewerRenderedEvent {\n pageCount: number;\n /** CSS px per PDF point of the first page. */\n scale: number;\n /** Displayed (CSS px) width of every page. */\n pageWidths: number[];\n}\n\ntype PdfJsModule = typeof import('pdfjs-dist');\ntype Status = 'idle' | 'loading' | 'ready' | 'error';\n\ninterface PageView {\n number: number;\n cssWidth: number;\n cssHeight: number;\n canvasWidth: number;\n canvasHeight: number;\n fields: FieldView[];\n}\ninterface FieldView {\n id: string; label: string; tone: PdfViewerTone;\n left: number; top: number; width: number | null; maxWidth: number; height: number; fontPx: number;\n}\n\nconst DEFAULT_MAX_WIDTH = 700;\nconst DEFAULT_FIELD_HEIGHT = 14;\n/** Most pixels one page's canvas may have; Safari (iOS especially) refuses or blanks bigger ones. */\nconst MAX_CANVAS_PIXELS = 16_000_000;\n/** Most pixels all canvases together may have; iOS Safari limits total canvas memory. */\nconst MAX_TOTAL_CANVAS_PIXELS = 48_000_000;\nconst WORKER_MISSING = 'PDF worker is not configured.';\n\n/**\n * Renders every page of a PDF into a canvas (crisp on high-density screens), with optional labelled boxes overlaid in PDF coordinates.\n * Needs `pdfjs-dist` (loaded on first use, so it stays out of bundles that never show a PDF).\n *\n * <ui-pdf-viewer [data]=\"buffer()\" [fields]=\"badges()\" ariaLabel=\"Contract preview\" (loaded)=\"onLoaded($event)\" />\n * <ui-pdf-viewer src=\"/files/contract.pdf\" [httpHeaders]=\"{ Authorization: 'Bearer ' + token }\" />\n *\n * - `src` / `data`: a URL, or the bytes (`data` wins). The bytes are copied, so your buffer stays usable.\n * - `workerSrc` or the `PDF_VIEWER_WORKER_SRC` token: the pdf.js worker URL. Without either the viewer shows \"PDF worker is not configured.\"\n * - `maxPageWidth` (default 700): pages are drawn this wide, or the container's width when narrower; never larger.\n * - `pixelRatio`: canvas pixels per CSS pixel; default is the screen's ratio between 1 and 3.\n * - `fields`: badges positioned in PDF points (origin bottom-left); they scale with the page.\n * - `loaded` / `pagesRendered` / `loadFailed`: see the event types. A new `src` / `data` replaces the document; a slow older load never paints.\n * A page that fails to draw after `loaded` also emits `loadFailed`, shows the error state and destroys the document that `loaded` handed to the host.\n * - A page's canvas never exceeds 16,000,000 pixels (Safari limit); the pixel ratio is lowered for such a page, its CSS size is unchanged.\n * - All canvases together never exceed 48,000,000 pixels (iOS Safari limits total canvas memory): a long document is drawn at a lower\n * density, the same for every page and never below 1 pixel per CSS pixel. CSS sizes are unchanged.\n * - `httpHeaders` and `withCredentials` apply to `src` only; they are not used when `data` is given.\n * - `fields[].id` is only a display / test hook; duplicates are tolerated. `httpHeaders` is compared by content, but a stable reference is still preferred.\n * - The worker-missing message is fixed text and ignores `errorText`, because it is a setup problem for the developer.\n * - Needs pdf.js 5 (`pdfjs-dist` >= 5), which needs Safari 17.4+; the legacy pdf.js build is not supported by this component.\n * - The public typings reference `pdfjs-dist` types: apps that type-check the library without `pdfjs-dist` installed need `skipLibCheck` or the\n * package (the same trade-off as `@forgeroute/ui/charts` and chart.js).\n */\n@Component({\n selector: 'ui-pdf-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"pv-root\" [attr.role]=\"ariaLabel() ? 'region' : null\" [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-busy]=\"status() === 'loading'\">\n <div class=\"pv-live\" role=\"status\" aria-live=\"polite\">{{ status() === 'loading' ? loadingText() : '' }}</div>\n @switch (status()) {\n @case ('loading') { <div class=\"pv-state pv-loading\" aria-hidden=\"true\">{{ loadingText() }}</div> }\n @case ('error') { <div class=\"pv-state pv-error\" role=\"alert\">{{ errorMessage() }}</div> }\n @case ('ready') {\n <div class=\"pv-pages\">\n @for (p of views(); track p.number) {\n <div class=\"pv-page\" [style.width.px]=\"p.cssWidth\">\n <canvas class=\"pv-canvas\" role=\"img\" [attr.aria-label]=\"'Page ' + p.number + ' of ' + views().length\"\n [attr.width]=\"p.canvasWidth\" [attr.height]=\"p.canvasHeight\"></canvas>\n @for (f of p.fields; track $index) {\n <div class=\"pv-field pv-tone-{{ f.tone }}\"\n [style.left.%]=\"f.left\" [style.top.%]=\"f.top\" [style.width.%]=\"f.width\" [style.max-width.%]=\"f.maxWidth\"\n [style.height.%]=\"f.height\" [style.font-size.px]=\"f.fontPx\">\n <span class=\"pv-field-label\">{{ f.label }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n :host { display: block; width: 100%; }\n .pv-root { position: relative; }\n .pv-live { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }\n .pv-state { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 12rem; padding: 0 16px; text-align: center;\n font-size: 0.8125rem; line-height: 1.4; overflow-wrap: anywhere; box-sizing: border-box; }\n .pv-loading { color: #64748b; }\n .pv-error { color: #dc2626; }\n .pv-pages { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 100%; }\n .pv-page { position: relative; margin: 0 auto; max-width: 100%; }\n .pv-canvas { display: block; width: 100%; height: auto; background: #fff; border-radius: 2px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); }\n .pv-field { position: absolute; display: flex; align-items: center; box-sizing: border-box; padding: 0 4px; overflow: hidden;\n pointer-events: none; border: 1px solid; border-radius: 2px; -webkit-user-select: none; user-select: none; }\n .pv-field-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1; }\n .pv-tone-blue { background: #dbeafe; border-color: #93c5fd; color: #1d4ed8; }\n .pv-tone-green { background: #dcfce7; border-color: #86efac; color: #15803d; }\n .pv-tone-amber { background: #fef3c7; border-color: #fcd34d; color: #92400e; }\n .pv-tone-red { background: #fee2e2; border-color: #fca5a5; color: #b91c1c; }\n .pv-tone-slate { background: #f1f5f9; border-color: #cbd5e1; color: #334155; }\n `],\n})\nexport class PdfViewerComponent {\n /** PDF URL. Ignored while `data` is set. */\n readonly src = input<string | null>(null);\n /** PDF bytes. Wins over `src`. */\n readonly data = input<ArrayBuffer | Uint8Array | null>(null);\n /** Request headers for `src`. Changes are detected by content, but pass a stable reference when you can. */\n readonly httpHeaders = input<Record<string, string>>({});\n readonly withCredentials = input(false);\n /** pdf.js worker URL; falls back to the `PDF_VIEWER_WORKER_SRC` token. */\n readonly workerSrc = input('');\n /** Widest a page is drawn, in CSS px. */\n readonly maxPageWidth = input(DEFAULT_MAX_WIDTH);\n /** Canvas pixels per CSS pixel; null = the screen's ratio, limited to 1..3. */\n readonly pixelRatio = input<number | null>(null);\n readonly fields = input<PdfViewerField[]>([]);\n /** Accessible name of the viewer. */\n readonly ariaLabel = input('');\n readonly loadingText = input('Loading document…');\n readonly errorText = input('Failed to load document.');\n\n readonly loaded = output<PdfViewerLoadedEvent>();\n readonly loadFailed = output<unknown>();\n readonly pagesRendered = output<PdfViewerRenderedEvent>();\n\n protected readonly status = signal<Status>('idle');\n private readonly pageSizes = signal<{ width: number; height: number }[]>([]);\n private readonly containerWidth = signal(0);\n private readonly customError = signal('');\n protected readonly errorMessage = computed(() => this.customError() || this.errorText());\n\n /** Changes exactly when some canvas bitmap changes size (and so is cleared). */\n private readonly drawKey = computed(() => this.views().map(v => v.canvasWidth + 'x' + v.canvasHeight).join('|'));\n private readonly effectiveWidth = computed(() => this.widthFor(this.containerWidth()));\n protected readonly views = computed((): PageView[] => {\n const sizes = this.pageSizes();\n const cssWidth = this.effectiveWidth();\n const ratio = this.resolvedRatio();\n const byPage = new Map<number, PdfViewerField[]>();\n for (const f of this.fields()) {\n if (!Number.isInteger(f.page) || f.page < 1 || f.page > sizes.length) continue;\n const list = byPage.get(f.page) ?? [];\n list.push(f);\n byPage.set(f.page, list);\n }\n const base = sizes.map(size => {\n const scale = cssWidth / size.width;\n const cssHeight = size.height * scale;\n // lower the density for a page whose bitmap would pass the canvas limit; the CSS size stays\n const pageRatio = Math.min(ratio, Math.sqrt(MAX_CANVAS_PIXELS / (cssWidth * cssHeight)));\n return { scale, cssHeight, pageRatio };\n });\n // a total budget for long documents: shrink every page's density by the same factor, but never below 1 (or below a cap-lowered ratio)\n let factor = 1;\n const bitmaps = () => base.map(b => {\n const r = Math.max(Math.min(b.pageRatio, 1), b.pageRatio * factor);\n return { w: Math.floor(cssWidth * r), h: Math.floor(b.cssHeight * r) };\n });\n let sized = bitmaps();\n for (let i = 0; i < 6; i++) {\n const total = sized.reduce((sum, b) => sum + b.w * b.h, 0);\n if (total <= MAX_TOTAL_CANVAS_PIXELS) break;\n factor *= Math.sqrt(MAX_TOTAL_CANVAS_PIXELS / total);\n sized = bitmaps();\n }\n return sizes.map((size, i) => {\n const { scale, cssHeight } = base[i];\n const fields = (byPage.get(i + 1) ?? []).map((f): FieldView => {\n const h = f.height ?? DEFAULT_FIELD_HEIGHT;\n const left = (f.x / size.width) * 100;\n return {\n id: f.id, label: f.label, tone: f.tone ?? 'blue',\n left, top: ((size.height - f.y - h) / size.height) * 100,\n width: f.width == null ? null : (f.width / size.width) * 100,\n maxWidth: Math.max(0, 100 - left),\n height: (h / size.height) * 100,\n fontPx: Math.max(9, h * scale * 0.7),\n };\n });\n return { number: i + 1, cssWidth, cssHeight, canvasWidth: sized[i].w, canvasHeight: sized[i].h, fields };\n });\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n private readonly tokenWorkerSrc = inject(PDF_VIEWER_WORKER_SRC);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly headersKey = computed(() => JSON.stringify(this.httpHeaders()));\n\n /** Bumped by every new load, replacement and destroy; an async step whose token no longer matches stops. */\n private loadToken = 0;\n /** Bumped by every (re)draw so only the newest draw paints. */\n private drawToken = 0;\n private doc: PDFDocumentProxy | null = null;\n private loadingTask: { destroy?: () => unknown } | null = null;\n private pageProxies: PDFPageProxy[] = [];\n private renderTasks: { cancel?: () => void }[] = [];\n private observer: ResizeObserver | null = null;\n private frame = 0;\n private lastDrawKey = '';\n\n constructor() {\n effect(() => {\n this.src(); this.data(); this.headersKey(); this.withCredentials(); this.workerSrc();\n if (!this.isBrowser) return; // nothing to load or draw on the server\n untracked(() => void this.startLoad());\n });\n // Whatever resizes the canvases (maxPageWidth, pixelRatio) clears them, so a changed bitmap size needs a redraw. Draws the code\n // already scheduled record their key in scheduleDraw(), so this only fires for changes nothing else handled.\n effect(() => {\n const key = this.drawKey();\n untracked(() => { if (this.status() === 'ready' && key !== this.lastDrawKey) this.scheduleDraw(); });\n });\n if (this.isBrowser && typeof ResizeObserver !== 'undefined') {\n this.observer = new ResizeObserver(() => this.onResize());\n this.observer.observe(this.host.nativeElement);\n }\n inject(DestroyRef).onDestroy(() => {\n this.loadToken++;\n this.drawToken++;\n this.observer?.disconnect();\n if (this.frame && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(this.frame);\n this.teardown();\n });\n }\n\n /** Test seam: loads pdf.js on first use so apps that never show a PDF do not bundle or fetch it. */\n protected loadPdfJs(): Promise<PdfJsModule> {\n return import('pdfjs-dist');\n }\n\n private resolvedRatio(): number {\n const explicit = this.pixelRatio();\n if (explicit != null && explicit > 0) return explicit;\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n return Math.min(Math.max(dpr, 1), 3);\n }\n\n private widthFor(container: number): number {\n const max = this.maxPageWidth() > 0 ? this.maxPageWidth() : DEFAULT_MAX_WIDTH;\n return container > 0 ? Math.min(max, container) : max;\n }\n\n private async startLoad(): Promise<void> {\n const token = ++this.loadToken;\n this.drawToken++;\n this.teardown();\n this.pageSizes.set([]);\n this.customError.set('');\n const data = this.data();\n const src = this.src();\n if (data == null && !src) { this.status.set('idle'); return; }\n this.containerWidth.set(this.host.nativeElement.clientWidth);\n this.status.set('loading');\n try {\n const pdfjs = await this.loadPdfJs();\n if (token !== this.loadToken) return;\n const worker = this.workerSrc() || this.tokenWorkerSrc;\n if (worker) pdfjs.GlobalWorkerOptions.workerSrc = worker;\n else if (!pdfjs.GlobalWorkerOptions.workerSrc) { this.fail(new Error(WORKER_MISSING), WORKER_MISSING); return; }\n\n const params: Record<string, unknown> = data != null\n ? { data: data instanceof Uint8Array ? data.slice() : new Uint8Array(data.slice(0)) } // pdf.js detaches what it is given\n : { url: src };\n if (data == null) { // request options only make sense for a URL\n const headers = this.httpHeaders();\n if (Object.keys(headers).length > 0) params['httpHeaders'] = headers;\n if (this.withCredentials()) params['withCredentials'] = true;\n }\n const task = pdfjs.getDocument(params as unknown as Parameters<PdfJsModule['getDocument']>[0]);\n this.loadingTask = task;\n const doc = await task.promise;\n if (token !== this.loadToken) { this.destroyDoc(doc); return; }\n this.doc = doc;\n\n const proxies: PDFPageProxy[] = [];\n const sizes: { width: number; height: number }[] = [];\n for (let i = 1; i <= doc.numPages; i++) {\n const page = await doc.getPage(i);\n if (token !== this.loadToken) return;\n const vp = page.getViewport({ scale: 1 });\n if (!(Number.isFinite(vp.width) && Number.isFinite(vp.height) && vp.width > 0 && vp.height > 0)) throw new Error('invalid page size');\n proxies.push(page);\n sizes.push({ width: vp.width, height: vp.height });\n }\n this.pageProxies = proxies;\n this.containerWidth.set(this.host.nativeElement.clientWidth); // the container may have changed while the file loaded\n this.pageSizes.set(sizes);\n this.status.set('ready');\n this.loaded.emit({ pageCount: sizes.length, pages: sizes.map(s => ({ ...s })), document: doc });\n this.scheduleDraw();\n } catch (err) {\n if (token !== this.loadToken) return;\n this.fail(err);\n }\n }\n\n private fail(err: unknown, message = ''): void {\n this.loadToken++; // nothing still in flight may paint over the error\n this.drawToken++;\n this.teardown();\n this.pageSizes.set([]);\n this.customError.set(message);\n this.status.set('error');\n this.loadFailed.emit(err);\n }\n\n private scheduleDraw(): void {\n const id = ++this.drawToken;\n this.lastDrawKey = this.drawKey();\n this.cancelRenders(); // a still-running paint must not land in canvases about to be resized\n afterNextRender(() => void this.draw(id), { injector: this.injector });\n }\n\n private async draw(id: number): Promise<void> {\n const token = this.loadToken;\n const stale = () => id !== this.drawToken || token !== this.loadToken;\n this.cancelRenders();\n const views = this.views();\n const canvases = Array.from(this.host.nativeElement.querySelectorAll<HTMLCanvasElement>('canvas.pv-canvas'));\n const sizes = this.pageSizes();\n const scales: number[] = [];\n try {\n for (let i = 0; i < views.length; i++) {\n if (stale()) return;\n const canvas = canvases[i];\n const page = this.pageProxies[i];\n if (!canvas || !page || !canvas.getContext('2d')) throw new Error('canvas unavailable');\n const cssScale = views[i].cssWidth / sizes[i].width;\n scales.push(cssScale);\n const viewport = page.getViewport({ scale: (views[i].canvasWidth / sizes[i].width) });\n const task = page.render({ canvas, viewport });\n this.renderTasks.push(task);\n await task.promise;\n }\n } catch (err) {\n if (stale() || (err as { name?: string } | null)?.name === 'RenderingCancelledException') return;\n this.fail(err);\n return;\n }\n if (stale()) return;\n this.pagesRendered.emit({ pageCount: views.length, scale: scales[0] ?? 1, pageWidths: views.map(v => v.cssWidth) });\n }\n\n private onResize(): void {\n if (this.frame || typeof requestAnimationFrame !== 'function') return;\n this.frame = requestAnimationFrame(() => {\n this.frame = 0;\n const before = this.effectiveWidth();\n this.containerWidth.set(this.host.nativeElement.clientWidth);\n if (this.effectiveWidth() !== before && this.status() === 'ready') this.scheduleDraw();\n });\n }\n\n private cancelRenders(): void {\n for (const t of this.renderTasks) { try { t.cancel?.(); } catch { /* already finished */ } }\n this.renderTasks = [];\n }\n\n private teardown(): void {\n this.cancelRenders();\n const task = this.loadingTask;\n this.loadingTask = null;\n if (task) { try { Promise.resolve(task.destroy?.()).catch(() => undefined); } catch { /* ignore */ } }\n const doc = this.doc;\n this.doc = null;\n this.pageProxies = [];\n if (doc) this.destroyDoc(doc);\n }\n\n private destroyDoc(doc: PDFDocumentProxy): void {\n try { Promise.resolve(doc.destroy()).catch(() => undefined); } catch { /* ignore */ }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"forgeroute-ui-pdf.mjs","names":[],"sources":["../../../projects/forgeroute-ui/pdf/src/pdf-viewer/pdf-viewer.component.ts","../../../projects/forgeroute-ui/pdf/src/provide-forgeroute-pdf.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n PLATFORM_ID, Component, ChangeDetectionStrategy, DestroyRef, ElementRef, InjectionToken, Injector, afterNextRender, computed, effect,\n inject, input, output, signal, untracked,\n} from '@angular/core';\nimport type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';\n\n/** Where pdf.js finds its worker script. Provide it once in the app (`{ provide: PDF_VIEWER_WORKER_SRC, useValue: '/assets/pdf.worker.min.mjs' }`). */\nexport const PDF_VIEWER_WORKER_SRC = new InjectionToken<string>('PDF_VIEWER_WORKER_SRC', { providedIn: 'root', factory: () => '' });\n\n/** Colour of an overlay badge. */\nexport type PdfViewerTone = 'blue' | 'green' | 'amber' | 'red' | 'slate';\n\n/** A labelled box drawn over a page. Positions are PDF points with the origin at the page's bottom-left corner. */\nexport interface PdfViewerField {\n id: string;\n /** 1-based page number; a field on a page that does not exist is ignored. */\n page: number;\n /** Bottom-left corner of the box, in PDF points. */\n x: number;\n y: number;\n /** Size in PDF points. Without a width the box fits its label; the default height is 14. */\n width?: number;\n height?: number;\n label: string;\n tone?: PdfViewerTone;\n}\n\nexport interface PdfViewerLoadedEvent {\n pageCount: number;\n /** Every page's size in PDF points at scale 1. */\n pages: { width: number; height: number }[];\n /** The loaded pdf.js document, so the host can read text content. The viewer destroys it when it is replaced or the viewer goes away. */\n document: PDFDocumentProxy;\n}\n\nexport interface PdfViewerRenderedEvent {\n pageCount: number;\n /** CSS px per PDF point of the first page. */\n scale: number;\n /** Displayed (CSS px) width of every page. */\n pageWidths: number[];\n}\n\ntype PdfJsModule = typeof import('pdfjs-dist');\ntype Status = 'idle' | 'loading' | 'ready' | 'error' | 'unsupported';\n\ninterface PageView {\n number: number;\n cssWidth: number;\n cssHeight: number;\n canvasWidth: number;\n canvasHeight: number;\n fields: FieldView[];\n}\ninterface FieldView {\n id: string; label: string; tone: PdfViewerTone;\n left: number; top: number; width: number | null; maxWidth: number; height: number; fontPx: number;\n}\n\nconst DEFAULT_MAX_WIDTH = 700;\nconst DEFAULT_FIELD_HEIGHT = 14;\n/** Most pixels one page's canvas may have; Safari (iOS especially) refuses or blanks bigger ones. */\nconst MAX_CANVAS_PIXELS = 16_000_000;\n/** Most pixels all canvases together may have; iOS Safari limits total canvas memory. */\nconst MAX_TOTAL_CANVAS_PIXELS = 48_000_000;\nconst WORKER_MISSING = 'PDF worker is not configured.';\n\n/**\n * Language features the pdf.js modern build calls WITHOUT a polyfill or guard on the path every document takes, found by reading\n * `pdfjs-dist/build/pdf.mjs` + `pdf.worker.mjs` of 5.7.284 (this library's dev copy) and 6.2.108 (the apps' copy). The `legacy/` build\n * polyfills them; this component imports the modern one. Details and the evidence per feature: docs/pdf-viewer.md.\n *\n * - `Promise.withResolvers`, `Promise.try`: the main-thread API and the worker message handler (every message).\n * - `Map.prototype.getOrInsertComputed`: per-page intent state and the object store on every render (6.x also in the message handler).\n * - `Math.sumPrecise`: the worker, when it builds a font's name / glyf tables (every document with text).\n * - `Iterator`: pdf.js 6.x touches `Iterator.prototype` while the module loads, so a browser without the global cannot even import it.\n * - `URL.parse`: opening a document by URL (the stream choice and the worker origin check).\n *\n * Left out on purpose: `Worker` and `structuredClone` (pdf.js falls back to a main-thread worker that only needs one of them),\n * `OffscreenCanvas` / `Float16Array` (feature-tested by pdf.js), `Uint8Array.fromBase64` / `toBase64` and `Iterator` helpers (XFA / editor / text-layer paths only).\n */\nexport const PDF_VIEWER_REQUIRED_FEATURES = [\n 'Promise.withResolvers', 'Promise.try', 'Map.prototype.getOrInsertComputed', 'Math.sumPrecise', 'Iterator', 'URL.parse',\n] as const;\nexport type PdfViewerRequiredFeature = typeof PDF_VIEWER_REQUIRED_FEATURES[number];\n\n/**\n * Names of the required features `scope` (default: the global object) lacks; [] = pdf.js can run. Synchronous and\n * side-effect free. `URL.parse` is only needed to open a URL, so it is skipped when `needsUrl` is false (bytes are given).\n */\nexport function findMissingPdfFeatures(scope: object = globalThis, needsUrl = true): PdfViewerRequiredFeature[] {\n const g = scope as Record<string, any>;\n const has: Record<PdfViewerRequiredFeature, () => boolean> = {\n 'Promise.withResolvers': () => typeof g['Promise']?.withResolvers === 'function',\n 'Promise.try': () => typeof g['Promise']?.try === 'function',\n 'Map.prototype.getOrInsertComputed': () => typeof g['Map']?.prototype?.getOrInsertComputed === 'function',\n 'Math.sumPrecise': () => typeof g['Math']?.sumPrecise === 'function',\n 'Iterator': () => typeof g['Iterator'] === 'function' && typeof g['Iterator'].prototype === 'object',\n 'URL.parse': () => !needsUrl || typeof g['URL']?.parse === 'function',\n };\n return PDF_VIEWER_REQUIRED_FEATURES.filter(f => !has[f]());\n}\n\n/** Emitted by `loadFailed` when the browser lacks a feature pdf.js needs (nothing was loaded). */\nexport class PdfViewerUnsupportedError extends Error {\n readonly reason = 'unsupported-browser' as const;\n constructor(readonly missing: readonly PdfViewerRequiredFeature[]) {\n super('This browser cannot run pdf.js; missing: ' + missing.join(', '));\n this.name = 'PdfViewerUnsupportedError';\n }\n}\n\n/**\n * Renders every page of a PDF into a canvas (crisp on high-density screens), with optional labelled boxes overlaid in PDF coordinates.\n * Needs `pdfjs-dist` (loaded on first use, so it stays out of bundles that never show a PDF).\n *\n * <ui-pdf-viewer [data]=\"buffer()\" [fields]=\"badges()\" ariaLabel=\"Contract preview\" (loaded)=\"onLoaded($event)\" />\n * <ui-pdf-viewer src=\"/files/contract.pdf\" [httpHeaders]=\"{ Authorization: 'Bearer ' + token }\" />\n *\n * - `src` / `data`: a URL, or the bytes (`data` wins). The bytes are copied, so your buffer stays usable.\n * - `workerSrc` or the `PDF_VIEWER_WORKER_SRC` token: the pdf.js worker URL. Without either the viewer shows \"PDF worker is not configured.\"\n * - `maxPageWidth` (default 700): pages are drawn this wide, or the container's width when narrower; never larger.\n * - `pixelRatio`: canvas pixels per CSS pixel; default is the screen's ratio between 1 and 3.\n * - `fields`: badges positioned in PDF points (origin bottom-left); they scale with the page.\n * - `loaded` / `pagesRendered` / `loadFailed`: see the event types. A new `src` / `data` replaces the document; a slow older load never paints.\n * A page that fails to draw after `loaded` also emits `loadFailed`, shows the error state and destroys the document that `loaded` handed to the host.\n * - A page's canvas never exceeds 16,000,000 pixels (Safari limit); the pixel ratio is lowered for such a page, its CSS size is unchanged.\n * - All canvases together never exceed 48,000,000 pixels (iOS Safari limits total canvas memory): a long document is drawn at a lower\n * density, the same for every page and never below 1 pixel per CSS pixel. CSS sizes are unchanged.\n * - `httpHeaders` and `withCredentials` apply to `src` only; they are not used when `data` is given.\n * - `fields[].id` is only a display / test hook; duplicates are tolerated. `httpHeaders` is compared by content, but a stable reference is still preferred.\n * - The worker-missing message is fixed text and ignores `errorText`, because it is a setup problem for the developer.\n * - Needs pdf.js 5 (`pdfjs-dist` >= 5); the legacy pdf.js build is not supported by this component.\n * - Browser check: before pdf.js is imported, the viewer checks (once per load, synchronously) that the browser has the features\n * `PDF_VIEWER_REQUIRED_FEATURES` lists. Without them it shows `unsupportedText` (role=\"status\") and, when `src` is a URL, an\n * \"Open the document\" link (new tab); `loadFailed` emits a `PdfViewerUnsupportedError` (`reason: 'unsupported-browser'`, `missing`).\n * `[checkBrowserSupport]=\"false\"` skips the check. See docs/pdf-viewer.md.\n * - The public typings reference `pdfjs-dist` types: apps that type-check the library without `pdfjs-dist` installed need `skipLibCheck` or the\n * package (the same trade-off as `@forgeroute/ui/charts` and chart.js).\n */\n@Component({\n selector: 'ui-pdf-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"pv-root\" [attr.role]=\"ariaLabel() ? 'region' : null\" [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-busy]=\"status() === 'loading'\">\n <div class=\"pv-live\" role=\"status\" aria-live=\"polite\">{{ liveText() }}</div>\n @switch (status()) {\n @case ('loading') { <div class=\"pv-state pv-loading\" aria-hidden=\"true\">{{ loadingText() }}</div> }\n @case ('error') { <div class=\"pv-state pv-error\" role=\"alert\">{{ errorMessage() }}</div> }\n @case ('unsupported') {\n <div class=\"pv-state pv-unsupported\">\n <p class=\"pv-unsupported-text\">{{ unsupportedText() }}</p>\n @if (openUrl(); as url) {\n <a class=\"pv-open\" [href]=\"url\" target=\"_blank\" rel=\"noopener\">{{ openText() }}<span class=\"pv-sr\"> (opens in a new tab)</span></a>\n }\n </div>\n }\n @case ('ready') {\n <div class=\"pv-pages\">\n @for (p of views(); track p.number) {\n <div class=\"pv-page\" [style.width.px]=\"p.cssWidth\">\n <canvas class=\"pv-canvas\" role=\"img\" [attr.aria-label]=\"'Page ' + p.number + ' of ' + views().length\"\n [attr.width]=\"p.canvasWidth\" [attr.height]=\"p.canvasHeight\"></canvas>\n @for (f of p.fields; track $index) {\n <div class=\"pv-field pv-tone-{{ f.tone }}\"\n [style.left.%]=\"f.left\" [style.top.%]=\"f.top\" [style.width.%]=\"f.width\" [style.max-width.%]=\"f.maxWidth\"\n [style.height.%]=\"f.height\" [style.font-size.px]=\"f.fontPx\">\n <span class=\"pv-field-label\">{{ f.label }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n </div>\n `,\n styles: [`\n :host { display: block; width: 100%; }\n .pv-root { position: relative; }\n .pv-live, .pv-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }\n .pv-state { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 12rem; padding: 0 16px; text-align: center;\n font-size: 0.8125rem; line-height: 1.4; overflow-wrap: anywhere; box-sizing: border-box; }\n .pv-loading { color: #64748b; }\n .pv-error { color: #dc2626; }\n .pv-unsupported { flex-direction: column; gap: 8px; color: #334155; }\n .pv-unsupported-text { margin: 0; }\n .pv-open { display: inline-flex; align-items: center; justify-content: center; position: relative; min-height: 44px; min-width: 44px; padding: 0 16px;\n box-sizing: border-box; color: #1d4ed8; font-weight: 600; text-decoration: underline; border-radius: 6px; }\n .pv-open:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 2px; }\n .pv-pages { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 100%; }\n .pv-page { position: relative; margin: 0 auto; max-width: 100%; }\n .pv-canvas { display: block; width: 100%; height: auto; background: #fff; border-radius: 2px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); }\n .pv-field { position: absolute; display: flex; align-items: center; box-sizing: border-box; padding: 0 4px; overflow: hidden;\n pointer-events: none; border: 1px solid; border-radius: 2px; -webkit-user-select: none; user-select: none; }\n .pv-field-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1; }\n .pv-tone-blue { background: #dbeafe; border-color: #93c5fd; color: #1d4ed8; }\n .pv-tone-green { background: #dcfce7; border-color: #86efac; color: #15803d; }\n .pv-tone-amber { background: #fef3c7; border-color: #fcd34d; color: #92400e; }\n .pv-tone-red { background: #fee2e2; border-color: #fca5a5; color: #b91c1c; }\n .pv-tone-slate { background: #f1f5f9; border-color: #cbd5e1; color: #334155; }\n `],\n})\nexport class PdfViewerComponent {\n /** PDF URL. Ignored while `data` is set. */\n readonly src = input<string | null>(null);\n /** PDF bytes. Wins over `src`. */\n readonly data = input<ArrayBuffer | Uint8Array | null>(null);\n /** Request headers for `src`. Changes are detected by content, but pass a stable reference when you can. */\n readonly httpHeaders = input<Record<string, string>>({});\n readonly withCredentials = input(false);\n /** pdf.js worker URL; falls back to the `PDF_VIEWER_WORKER_SRC` token. */\n readonly workerSrc = input('');\n /** Widest a page is drawn, in CSS px. */\n readonly maxPageWidth = input(DEFAULT_MAX_WIDTH);\n /** Canvas pixels per CSS pixel; null = the screen's ratio, limited to 1..3. */\n readonly pixelRatio = input<number | null>(null);\n readonly fields = input<PdfViewerField[]>([]);\n /** Accessible name of the viewer. */\n readonly ariaLabel = input('');\n readonly loadingText = input('Loading document…');\n readonly errorText = input('Failed to load document.');\n /** Shown when the browser cannot run pdf.js (see `checkBrowserSupport`). */\n readonly unsupportedText = input(\"This browser can't show the document preview.\");\n /** Text of the link that opens `src` in a new tab on such a browser. */\n readonly openText = input('Open the document');\n /** Check for the browser features pdf.js needs before loading it; false = always try to load. */\n readonly checkBrowserSupport = input(true);\n\n readonly loaded = output<PdfViewerLoadedEvent>();\n readonly loadFailed = output<unknown>();\n readonly pagesRendered = output<PdfViewerRenderedEvent>();\n\n protected readonly status = signal<Status>('idle');\n private readonly pageSizes = signal<{ width: number; height: number }[]>([]);\n private readonly containerWidth = signal(0);\n private readonly customError = signal('');\n /** The URL the \"Open the document\" link points at: `src` when no bytes are given. */\n protected readonly openUrl = computed(() => (this.data() == null ? this.src() || '' : ''));\n protected readonly errorMessage = computed(() => this.customError() || this.errorText());\n /** What the always-present live region announces: loading progress, or why no preview is shown (a live region that already exists is announced reliably; one inserted with its text is not). */\n protected readonly liveText = computed(() => {\n const status = this.status();\n return status === 'loading' ? this.loadingText() : status === 'unsupported' ? this.unsupportedText() : '';\n });\n\n /** Changes exactly when some canvas bitmap changes size (and so is cleared). */\n private readonly drawKey = computed(() => this.views().map(v => v.canvasWidth + 'x' + v.canvasHeight).join('|'));\n private readonly effectiveWidth = computed(() => this.widthFor(this.containerWidth()));\n protected readonly views = computed((): PageView[] => {\n const sizes = this.pageSizes();\n const cssWidth = this.effectiveWidth();\n const ratio = this.resolvedRatio();\n const byPage = new Map<number, PdfViewerField[]>();\n for (const f of this.fields()) {\n if (!Number.isInteger(f.page) || f.page < 1 || f.page > sizes.length) continue;\n const list = byPage.get(f.page) ?? [];\n list.push(f);\n byPage.set(f.page, list);\n }\n const base = sizes.map(size => {\n const scale = cssWidth / size.width;\n const cssHeight = size.height * scale;\n // lower the density for a page whose bitmap would pass the canvas limit; the CSS size stays\n const pageRatio = Math.min(ratio, Math.sqrt(MAX_CANVAS_PIXELS / (cssWidth * cssHeight)));\n return { scale, cssHeight, pageRatio };\n });\n // a total budget for long documents: shrink every page's density by the same factor, but never below 1 (or below a cap-lowered ratio)\n let factor = 1;\n const bitmaps = () => base.map(b => {\n const r = Math.max(Math.min(b.pageRatio, 1), b.pageRatio * factor);\n return { w: Math.floor(cssWidth * r), h: Math.floor(b.cssHeight * r) };\n });\n let sized = bitmaps();\n for (let i = 0; i < 6; i++) {\n const total = sized.reduce((sum, b) => sum + b.w * b.h, 0);\n if (total <= MAX_TOTAL_CANVAS_PIXELS) break;\n factor *= Math.sqrt(MAX_TOTAL_CANVAS_PIXELS / total);\n sized = bitmaps();\n }\n return sizes.map((size, i) => {\n const { scale, cssHeight } = base[i];\n const fields = (byPage.get(i + 1) ?? []).map((f): FieldView => {\n const h = f.height ?? DEFAULT_FIELD_HEIGHT;\n const left = (f.x / size.width) * 100;\n return {\n id: f.id, label: f.label, tone: f.tone ?? 'blue',\n left, top: ((size.height - f.y - h) / size.height) * 100,\n width: f.width == null ? null : (f.width / size.width) * 100,\n maxWidth: Math.max(0, 100 - left),\n height: (h / size.height) * 100,\n fontPx: Math.max(9, h * scale * 0.7),\n };\n });\n return { number: i + 1, cssWidth, cssHeight, canvasWidth: sized[i].w, canvasHeight: sized[i].h, fields };\n });\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n private readonly tokenWorkerSrc = inject(PDF_VIEWER_WORKER_SRC);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly headersKey = computed(() => JSON.stringify(this.httpHeaders()));\n\n /** Bumped by every new load, replacement and destroy; an async step whose token no longer matches stops. */\n private loadToken = 0;\n /** Bumped by every (re)draw so only the newest draw paints. */\n private drawToken = 0;\n private doc: PDFDocumentProxy | null = null;\n private loadingTask: { destroy?: () => unknown } | null = null;\n private pageProxies: PDFPageProxy[] = [];\n private renderTasks: { cancel?: () => void }[] = [];\n private observer: ResizeObserver | null = null;\n private frame = 0;\n private lastDrawKey = '';\n\n constructor() {\n effect(() => {\n this.src(); this.data(); this.headersKey(); this.withCredentials(); this.workerSrc(); this.checkBrowserSupport();\n if (!this.isBrowser) return; // nothing to load or draw on the server\n untracked(() => void this.startLoad());\n });\n // Whatever resizes the canvases (maxPageWidth, pixelRatio) clears them, so a changed bitmap size needs a redraw. Draws the code\n // already scheduled record their key in scheduleDraw(), so this only fires for changes nothing else handled.\n effect(() => {\n const key = this.drawKey();\n untracked(() => { if (this.status() === 'ready' && key !== this.lastDrawKey) this.scheduleDraw(); });\n });\n if (this.isBrowser && typeof ResizeObserver !== 'undefined') {\n this.observer = new ResizeObserver(() => this.onResize());\n this.observer.observe(this.host.nativeElement);\n }\n inject(DestroyRef).onDestroy(() => {\n this.loadToken++;\n this.drawToken++;\n this.observer?.disconnect();\n if (this.frame && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(this.frame);\n this.teardown();\n });\n }\n\n /** Test seam: loads pdf.js on first use so apps that never show a PDF do not bundle or fetch it. */\n protected loadPdfJs(): Promise<PdfJsModule> {\n return import('pdfjs-dist');\n }\n\n /** Test seam: the required features this browser lacks. */\n protected missingFeatures(needsUrl: boolean): readonly PdfViewerRequiredFeature[] {\n return findMissingPdfFeatures(globalThis, needsUrl);\n }\n\n private resolvedRatio(): number {\n const explicit = this.pixelRatio();\n if (explicit != null && explicit > 0) return explicit;\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n return Math.min(Math.max(dpr, 1), 3);\n }\n\n private widthFor(container: number): number {\n const max = this.maxPageWidth() > 0 ? this.maxPageWidth() : DEFAULT_MAX_WIDTH;\n return container > 0 ? Math.min(max, container) : max;\n }\n\n private async startLoad(): Promise<void> {\n const token = ++this.loadToken;\n this.drawToken++;\n this.teardown();\n this.pageSizes.set([]);\n this.customError.set('');\n const data = this.data();\n const src = this.src();\n if (data == null && !src) { this.status.set('idle'); return; }\n if (this.checkBrowserSupport()) {\n const missing = this.missingFeatures(data == null);\n if (missing.length > 0) { // pdf.js would throw on first use: do not even import it\n this.loadToken++;\n this.pageSizes.set([]);\n this.status.set('unsupported');\n this.loadFailed.emit(new PdfViewerUnsupportedError(missing));\n return;\n }\n }\n this.containerWidth.set(this.host.nativeElement.clientWidth);\n this.status.set('loading');\n try {\n const pdfjs = await this.loadPdfJs();\n if (token !== this.loadToken) return;\n const worker = this.workerSrc() || this.tokenWorkerSrc;\n if (worker) pdfjs.GlobalWorkerOptions.workerSrc = worker;\n else if (!pdfjs.GlobalWorkerOptions.workerSrc) { this.fail(new Error(WORKER_MISSING), WORKER_MISSING); return; }\n\n const params: Record<string, unknown> = data != null\n ? { data: data instanceof Uint8Array ? data.slice() : new Uint8Array(data.slice(0)) } // pdf.js detaches what it is given\n : { url: src };\n if (data == null) { // request options only make sense for a URL\n const headers = this.httpHeaders();\n if (Object.keys(headers).length > 0) params['httpHeaders'] = headers;\n if (this.withCredentials()) params['withCredentials'] = true;\n }\n const task = pdfjs.getDocument(params as unknown as Parameters<PdfJsModule['getDocument']>[0]);\n this.loadingTask = task;\n const doc = await task.promise;\n if (token !== this.loadToken) { this.destroyDoc(doc); return; }\n this.doc = doc;\n\n const proxies: PDFPageProxy[] = [];\n const sizes: { width: number; height: number }[] = [];\n for (let i = 1; i <= doc.numPages; i++) {\n const page = await doc.getPage(i);\n if (token !== this.loadToken) return;\n const vp = page.getViewport({ scale: 1 });\n if (!(Number.isFinite(vp.width) && Number.isFinite(vp.height) && vp.width > 0 && vp.height > 0)) throw new Error('invalid page size');\n proxies.push(page);\n sizes.push({ width: vp.width, height: vp.height });\n }\n this.pageProxies = proxies;\n this.containerWidth.set(this.host.nativeElement.clientWidth); // the container may have changed while the file loaded\n this.pageSizes.set(sizes);\n this.status.set('ready');\n this.loaded.emit({ pageCount: sizes.length, pages: sizes.map(s => ({ ...s })), document: doc });\n this.scheduleDraw();\n } catch (err) {\n if (token !== this.loadToken) return;\n this.fail(err);\n }\n }\n\n private fail(err: unknown, message = ''): void {\n this.loadToken++; // nothing still in flight may paint over the error\n this.drawToken++;\n this.teardown();\n this.pageSizes.set([]);\n this.customError.set(message);\n this.status.set('error');\n this.loadFailed.emit(err);\n }\n\n private scheduleDraw(): void {\n const id = ++this.drawToken;\n this.lastDrawKey = this.drawKey();\n this.cancelRenders(); // a still-running paint must not land in canvases about to be resized\n afterNextRender(() => void this.draw(id), { injector: this.injector });\n }\n\n private async draw(id: number): Promise<void> {\n const token = this.loadToken;\n const stale = () => id !== this.drawToken || token !== this.loadToken;\n this.cancelRenders();\n const views = this.views();\n const canvases = Array.from(this.host.nativeElement.querySelectorAll<HTMLCanvasElement>('canvas.pv-canvas'));\n const sizes = this.pageSizes();\n const scales: number[] = [];\n try {\n for (let i = 0; i < views.length; i++) {\n if (stale()) return;\n const canvas = canvases[i];\n const page = this.pageProxies[i];\n if (!canvas || !page || !canvas.getContext('2d')) throw new Error('canvas unavailable');\n const cssScale = views[i].cssWidth / sizes[i].width;\n scales.push(cssScale);\n const viewport = page.getViewport({ scale: (views[i].canvasWidth / sizes[i].width) });\n const task = page.render({ canvas, viewport });\n this.renderTasks.push(task);\n await task.promise;\n }\n } catch (err) {\n if (stale() || (err as { name?: string } | null)?.name === 'RenderingCancelledException') return;\n this.fail(err);\n return;\n }\n if (stale()) return;\n this.pagesRendered.emit({ pageCount: views.length, scale: scales[0] ?? 1, pageWidths: views.map(v => v.cssWidth) });\n }\n\n private onResize(): void {\n if (this.frame || typeof requestAnimationFrame !== 'function') return;\n this.frame = requestAnimationFrame(() => {\n this.frame = 0;\n const before = this.effectiveWidth();\n this.containerWidth.set(this.host.nativeElement.clientWidth);\n if (this.effectiveWidth() !== before && this.status() === 'ready') this.scheduleDraw();\n });\n }\n\n private cancelRenders(): void {\n for (const t of this.renderTasks) { try { t.cancel?.(); } catch { /* already finished */ } }\n this.renderTasks = [];\n }\n\n private teardown(): void {\n this.cancelRenders();\n const task = this.loadingTask;\n this.loadingTask = null;\n if (task) { try { Promise.resolve(task.destroy?.()).catch(() => undefined); } catch { /* ignore */ } }\n const doc = this.doc;\n this.doc = null;\n this.pageProxies = [];\n if (doc) this.destroyDoc(doc);\n }\n\n private destroyDoc(doc: PDFDocumentProxy): void {\n try { Promise.resolve(doc.destroy()).catch(() => undefined); } catch { /* ignore */ }\n }\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { PDF_VIEWER_WORKER_SRC } from './pdf-viewer/pdf-viewer.component';\n\nexport interface ForgeroutePdfOptions {\n /** URL of the pdf.js worker script every `ui-pdf-viewer` in the app uses, e.g. `'/pdf.worker.min.mjs'`. Must not be blank. */\n workerSrc: string;\n}\n\n/**\n * Sets the pdf.js worker location once for the whole app (provides `PDF_VIEWER_WORKER_SRC`):\n *\n * providers: [provideForgeroutePdf({ workerSrc: '/pdf.worker.min.mjs' })]\n *\n * A `workerSrc` input on a viewer still wins over this value. Throws at provide time when `workerSrc` is blank, because a viewer\n * without a worker can only show \"PDF worker is not configured.\".\n */\nexport function provideForgeroutePdf(options: ForgeroutePdfOptions): EnvironmentProviders {\n const workerSrc = typeof options?.workerSrc === 'string' ? options.workerSrc.trim() : '';\n if (!workerSrc) {\n throw new Error('provideForgeroutePdf: \"workerSrc\" must be a non-empty URL of the pdf.js worker script (for example \"/pdf.worker.min.mjs\").');\n }\n return makeEnvironmentProviders([{ provide: PDF_VIEWER_WORKER_SRC, useValue: workerSrc }]);\n}\n"],"mappings":"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"}
|