@embedpdf/angular 3.0.0-next.13 → 3.0.0-next.15
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/README.md +309 -0
- package/dist/README.md +309 -0
- package/dist/actions/index.d.ts +34 -16
- package/dist/anchored/index.d.ts +67 -0
- package/dist/annotation/index.d.ts +599 -0
- package/dist/commands/index.d.ts +109 -0
- package/dist/fesm2022/embedpdf-angular-actions.mjs +117 -36
- package/dist/fesm2022/embedpdf-angular-actions.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-anchored.mjs +148 -0
- package/dist/fesm2022/embedpdf-angular-anchored.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs +1960 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs +235 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs +1074 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs +54 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs +100 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs +157 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs +306 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs +106 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs +77 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs +65 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs +297 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs +93 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-render.mjs +331 -69
- package/dist/fesm2022/embedpdf-angular-render.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-runtime.mjs +1147 -390
- package/dist/fesm2022/embedpdf-angular-runtime.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-search.mjs +251 -0
- package/dist/fesm2022/embedpdf-angular-search.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs +477 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs +177 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs +120 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-stage.mjs +688 -288
- package/dist/fesm2022/embedpdf-angular-stage.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-stamp.mjs +169 -0
- package/dist/fesm2022/embedpdf-angular-stamp.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs +89 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs +1123 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs +69 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular.mjs +23 -3
- package/dist/fesm2022/embedpdf-angular.mjs.map +1 -1
- package/dist/form/index.d.ts +79 -0
- package/dist/history/index.d.ts +28 -0
- package/dist/i18n/index.d.ts +52 -0
- package/dist/index.d.ts +20 -0
- package/dist/interaction/index.d.ts +58 -0
- package/dist/link/index.d.ts +77 -0
- package/dist/measurement/index.d.ts +46 -0
- package/dist/metadata/index.d.ts +51 -0
- package/dist/page-edit/index.d.ts +22 -0
- package/dist/page-view/index.d.ts +94 -0
- package/dist/redaction/index.d.ts +38 -0
- package/dist/render/index.d.ts +45 -6
- package/dist/runtime/index.d.ts +579 -199
- package/dist/search/index.d.ts +71 -0
- package/dist/selection/index.d.ts +141 -0
- package/dist/shell/index.d.ts +88 -0
- package/dist/signature/index.d.ts +45 -0
- package/dist/stage/index.d.ts +242 -141
- package/dist/stamp/index.d.ts +58 -0
- package/dist/testing/index.d.ts +53 -0
- package/dist/toolbar/index.d.ts +257 -0
- package/dist/view-manager/index.d.ts +23 -0
- package/package.json +135 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedpdf-angular-runtime.mjs","sources":["../../runtime/src/kernel-host.ts","../../runtime/src/tokens.ts","../../runtime/src/inject.ts","../../runtime/src/scope.ts","../../runtime/src/viewer.ts","../../runtime/src/page-context.ts","../../runtime/src/public_api.ts","../../runtime/src/embedpdf-angular-runtime.ts"],"sourcesContent":["/**\n * The kernel host — one service owns the kernel; ONE tick signal bridges the\n * kernel's single change stream into Angular's signal graph. Everything else in\n * this adapter is `computed()` over it (`value()` is Angular's `useKernelValue`).\n *\n * Two hosting modes share this class:\n * component-hosted `<epdf-viewer [engine] [plugins]>` (framework parity)\n * provider-hosted `provideEmbedPdf({...})` at route/app level\n *\n * CONSTRUCTION RULE (library law): nothing may read `host.kernel` while a\n * component is being CONSTRUCTED. Component-hosted configs resolve their inputs\n * lazily, so the kernel materializes on first real read (a template binding, an\n * effect) — after inputs are set. Every inject* primitive returns signals or\n * lazy methods and therefore respects this for free; only the raw\n * `injectKernel()` escape hatch can violate it (its doc says so).\n *\n * SSR CONTRACT: the EmbedPDF subtree is browser-only. On the server the host\n * never boots and any `kernel` read throws — wrap the viewer region in `@defer`\n * (which renders its placeholder on the server) or a platform-guarded `@if`.\n */\nimport {\n computed,\n inject,\n Injectable,\n makeEnvironmentProviders,\n PLATFORM_ID,\n signal,\n type EnvironmentProviders,\n type OnDestroy,\n type Signal,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { createKernel } from '@embedpdf/core';\nimport type {\n AnyPlugin,\n Engine,\n EngineFactory,\n InitialDocument,\n Kernel,\n Unsubscribe,\n} from '@embedpdf/core';\n\n/** One boot document — the KERNEL's shared `InitialDocument` shape (same as\n * the React adapter's), aliased under the package's Epdf naming. */\nexport type EpdfInitialDocument = InitialDocument;\n\nexport interface EmbedPdfConfig {\n /**\n * The engine, as an instance or a thunk. Engines construct synchronously and\n * boot lazily (`localEngine()` allocates nothing until first use), so\n * ownership follows the SHAPE of what you pass:\n *\n * - An **instance** is BORROWED: used as-is, never destroyed here. The\n * common path — a module-scope `const engine = localEngine()` shared\n * across viewers and route changes. The host calls `engine.warmup?.()`\n * when the kernel materializes so the boot overlaps initialization.\n * - A **thunk** (`() => localEngine()`) is HOST-OWNED: the host calls it\n * when the kernel materializes and `destroy()`s the result on teardown.\n * Use it for per-host isolation.\n *\n * Init-only: the kernel is never rebuilt for a new engine — tear the host\n * down (destroy the viewer / injector) and create a new one.\n */\n engine: Engine | EngineFactory;\n /** Init-only, like `engine`. */\n plugins: AnyPlugin[];\n /** Documents to open on startup (with optional tab names). They open in the\n * BACKGROUND after start and stream into the registry — `injectDocuments()`\n * is reactive; per-document loading UI is the Stage's job. A source that\n * fails to open lands in `error` and does NOT block the ones after it. */\n initialDocuments?: EpdfInitialDocument[];\n}\n\n/** `starting` covers construction through `kernel.start()`; `ready` means the\n * workspace is live (documents may still be opening in the background). */\nexport type EpdfKernelStatus = 'starting' | 'ready' | 'error';\n\n@Injectable()\nexport class EpdfKernelHost implements OnDestroy {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private config: (() => EmbedPdfConfig) | null = null;\n private _kernel: Kernel | null = null;\n /** The engine backing the kernel, and whether WE created it (a recipe) and\n * therefore must destroy it. A borrowed instance is left untouched. */\n private _engine: Engine | null = null;\n private ownsEngine = false;\n private unsubscribe: Unsubscribe | null = null;\n private initialDocuments: EpdfInitialDocument[] | undefined;\n private booted = false;\n private destroyed = false;\n\n /** Bumped on every kernel notification — THE bridge from kernel-world to signals. */\n private readonly tick = signal(0);\n\n /** Boot lifecycle. `ready`/`error` are derived sugar over it. */\n readonly status = signal<EpdfKernelStatus>('starting');\n /** The STARTUP failure, if any. Per-document open failures are tab state\n * (`DocInfo.status === 'error'`), not host state. */\n readonly error = signal<unknown>(null);\n /** True once `kernel.start()` resolved — which never touches the engine, so\n * the shell (and every workspace capability: i18n, view-manager, …) is alive\n * while WASM compiles or the transport connects. Workspace chrome may render\n * before this; gate on it (or on the document gate) where it matters. */\n readonly ready: Signal<boolean> = computed(() => this.status() === 'ready');\n\n /** Register the (deferred) config. Called exactly once, by `EpdfViewer`'s\n * constructor or `provideEmbedPdf`'s factory. */\n connect(config: () => EmbedPdfConfig): void {\n if (this.config || this._kernel) {\n throw new Error('[embedpdf] kernel already configured for this injector');\n }\n this.config = config;\n }\n\n /** The kernel — materialized on first read (see the construction rule above). */\n get kernel(): Kernel {\n if (!this._kernel) {\n if (!this.browser) {\n throw new Error(\n '[embedpdf] the viewer does not render on the server — wrap the EmbedPDF subtree in @defer (its placeholder renders during SSR) or a browser-only @if',\n );\n }\n if (!this.config) {\n throw new Error(\n '[embedpdf] no kernel: wrap this subtree in <epdf-viewer> or add provideEmbedPdf(...) to your providers',\n );\n }\n const { engine, plugins, initialDocuments } = this.config();\n // A thunk is host-owned: call it now, destroy on teardown. An instance is\n // borrowed and left untouched. Either way construction is synchronous and\n // inert (engines boot lazily on first use).\n this.ownsEngine = typeof engine === 'function';\n this._engine = this.ownsEngine ? (engine as EngineFactory)() : (engine as Engine);\n try {\n this._kernel = createKernel({ engine: this._engine, plugins });\n } catch (error) {\n // ngOnDestroy() only tears down via `_kernel`, which stays null on this\n // path — so an owned engine must be destroyed HERE or it leaks.\n if (this.ownsEngine) void this._engine.destroy();\n this._engine = null;\n this.ownsEngine = false;\n throw error;\n }\n // Warm up only once the kernel exists (a plugin-planning throw must not\n // start a boot we'd immediately have to unwind) — `warmup()` overlaps the\n // WASM/transport boot with the rest of initialization.\n this._engine.warmup?.();\n this.initialDocuments = initialDocuments;\n this.unsubscribe = this._kernel.subscribe(() => this.tick.update((n) => n + 1));\n }\n return this._kernel;\n }\n\n /** Start the kernel and open initial documents in the background. Idempotent;\n * a no-op on the server and after destroy. */\n boot(): void {\n if (this.booted || this.destroyed || !this.browser) return;\n this.booted = true;\n const kernel = this.kernel;\n void (async () => {\n try {\n await kernel.start();\n } catch (err) {\n if (!this.destroyed) {\n this.error.set(err);\n this.status.set('error');\n }\n return;\n }\n if (this.destroyed) return;\n this.status.set('ready');\n // Kernel-owned boot policy: all tabs appear immediately in array order;\n // the `active` entry (else the first) is selected; per-document\n // failures surface as that tab's `error`/`locked` status (this host's\n // `error` signal reports only startup failures).\n kernel.documents.openAll(this.initialDocuments ?? []);\n })();\n }\n\n /** Read a value derived from the kernel, cached by equality — Angular's\n * `useKernelValue`. The selector re-runs per kernel notification (cheap);\n * `equal` decides whether dependents ever see it. */\n value<R>(select: (kernel: Kernel) => R, equal: (a: R, b: R) => boolean = Object.is): Signal<R> {\n return computed(\n () => {\n this.tick();\n return select(this.kernel);\n },\n { equal },\n );\n }\n\n ngOnDestroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.unsubscribe?.();\n // destroy() owns the full teardown now: it joins an in-flight start, closes\n // every document (engine handles included), and unwinds workspace plugins.\n // Async + idempotent, so fire-and-forget is safe in a sync ngOnDestroy.\n // Then destroy the engine IF we own it (a thunk) — kernel first so handles\n // close before the engine goes; `engine.destroy()` joins any in-flight\n // boot or no-ops if it never started.\n if (this._kernel) {\n const engine = this._engine;\n const owns = this.ownsEngine;\n void this._kernel.destroy().then(() => {\n if (owns && engine) void engine.destroy();\n });\n }\n }\n}\n\n/**\n * Host the kernel in an environment injector (route or application providers).\n * The kernel's lifetime is the injector's — a route-level workspace tears down\n * when the route does. Unlocks chrome OUTSIDE any viewer subtree: a toolbar in\n * the app header and the stage in the main outlet share this one kernel.\n */\nexport function provideEmbedPdf(config: EmbedPdfConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: EpdfKernelHost,\n useFactory: () => {\n const host = new EpdfKernelHost();\n host.connect(() => config);\n host.boot();\n return host;\n },\n },\n ]);\n}\n","/**\n * DI tokens shared by the runtime's primitives and directives — split out so\n * `inject.ts` (consumers) and `scope.ts` (providers) never import each other.\n */\nimport { InjectionToken, type Signal } from '@angular/core';\n\n/** The document a subtree is bound to (provided by `[epdfDocumentScope]`).\n * Absent => the subtree follows the ACTIVE document. */\nexport interface EpdfDocumentScopeRef {\n readonly id: Signal<string>;\n}\n\nexport const EPDF_DOCUMENT_SCOPE = new InjectionToken<EpdfDocumentScopeRef>('EPDF_DOCUMENT_SCOPE');\n","/**\n * The inject* primitives — Angular's spelling of the React runtime hooks\n * (`use*` → `inject*`, plain values → signals, same names otherwise).\n *\n * All of them must run in an injection context (a constructor / field\n * initializer, like `inject()` itself). None of them read `host.kernel` during\n * construction — they return signals or lazy methods, so they are safe in\n * component-hosted mode where the kernel materializes after construction.\n */\nimport { computed, inject, type Signal } from '@angular/core';\nimport { docInfoListEquals } from '@embedpdf/core';\nimport type { CapabilityToken, DocInfo, Kernel } from '@embedpdf/core';\nimport { EpdfKernelHost } from './kernel-host';\nimport { EPDF_DOCUMENT_SCOPE } from './tokens';\n\nexport const shallowArray = <T>(a: readonly T[], b: readonly T[]): boolean =>\n a === b || (a.length === b.length && a.every((x, i) => x === b[i]));\n\nexport function injectKernelHost(): EpdfKernelHost {\n const host = inject(EpdfKernelHost, { optional: true });\n if (!host) {\n throw new Error(\n '[embedpdf] no kernel: wrap this subtree in <epdf-viewer> or add provideEmbedPdf(...) to your providers',\n );\n }\n return host;\n}\n\n/** The raw kernel — materializes it immediately. Do NOT call while a component\n * is being constructed in component-hosted mode (inputs are not set yet);\n * prefer the signal-returning primitives, which defer the first kernel read. */\nexport function injectKernel(): Kernel {\n return injectKernelHost().kernel;\n}\n\n/** Read a value derived from the kernel, cached by equality — `useKernelValue`. */\nexport function injectKernelValue<R>(\n select: (kernel: Kernel) => R,\n equal?: (a: R, b: R) => boolean,\n): Signal<R> {\n return injectKernelHost().value(select, equal);\n}\n\nexport function injectActiveDocumentId(): Signal<string | null> {\n return injectKernelValue((k) => k.documents.activeId());\n}\n\n/** The document id for this injector subtree: the nearest `[epdfDocumentScope]`,\n * else the active document. */\nexport function injectDocumentId(): Signal<string | null> {\n const scope = inject(EPDF_DOCUMENT_SCOPE, { optional: true });\n const active = injectActiveDocumentId();\n return computed(() => scope?.id() ?? active());\n}\n\n/**\n * Resolve a capability against a REACTIVE token — for components that take the\n * token as an input (`injectCapability` is the fixed-token sugar). Resolution\n * is a REACTIVE read (`tryCapability` through the kernel's one change\n * stream), not a computed over the document id — under the request-time\n * lifecycle a document can become resolvable while its id stays the same, so\n * any id-keyed cache goes stale; subscribing makes staleness structurally\n * impossible. Fail-fast like React's `useCapability`: while unresolvable,\n * this re-runs the strict resolver so the kernel's truthful reason (`no\n * capability` / `no document` / `document is loading|locked`) is what throws.\n */\nexport function injectCapabilityFor<T>(token: () => CapabilityToken<T>): Signal<T> {\n const host = injectKernelHost();\n const scope = inject(EPDF_DOCUMENT_SCOPE, { optional: true });\n const cap = host.value((k) => k.tryCapability(token(), scope?.id() ?? undefined));\n return computed(() => cap() ?? host.kernel.capability(token(), scope?.id() ?? undefined));\n}\n\nexport function injectCapability<T>(token: CapabilityToken<T>): Signal<T> {\n return injectCapabilityFor(() => token);\n}\n\n/** Like `injectCapabilityFor`, but null while the token can't resolve (no\n * plugin, no document, or a document that isn't ready yet). */\nexport function injectOptionalCapabilityFor<T>(token: () => CapabilityToken<T>): Signal<T | null> {\n const host = injectKernelHost();\n const scope = inject(EPDF_DOCUMENT_SCOPE, { optional: true });\n return host.value((k) => k.tryCapability(token(), scope?.id() ?? undefined));\n}\n\nexport function injectOptionalCapability<T>(token: CapabilityToken<T>): Signal<T | null> {\n return injectOptionalCapabilityFor(() => token);\n}\n\n/** Subscribe to a selector over a (document-resolved) capability. */\nexport function injectSelectorFor<C, R>(\n token: () => CapabilityToken<C>,\n select: (cap: C) => R,\n equal?: (a: R, b: R) => boolean,\n): Signal<R> {\n const host = injectKernelHost();\n const cap = injectCapabilityFor(token);\n return host.value(() => select(cap()), equal);\n}\n\nexport function injectSelector<C, R>(\n token: CapabilityToken<C>,\n select: (cap: C) => R,\n equal?: (a: R, b: R) => boolean,\n): Signal<R> {\n return injectSelectorFor(() => token, select, equal);\n}\n\n/**\n * Null-safe `injectSelector`: `fallback` whenever the token can't resolve — no\n * provider, or a document-scoped token with no document. For chrome that stays\n * mounted across the empty-workspace state (a zoom readout, a mode band).\n * `injectSelector` stays strict (fail-fast) for code that KNOWS a document\n * exists — e.g. anything behind the document gate.\n *\n * The `select` guard also swallows reads through a capability whose document\n * closed between the store notification and this read — that teardown race\n * resolves to `fallback` for one frame, then recomputes against the new state.\n */\nexport function injectOptionalSelectorFor<C, R>(\n token: () => CapabilityToken<C>,\n select: (cap: C) => R,\n fallback: R,\n equal?: (a: R, b: R) => boolean,\n): Signal<R> {\n const host = injectKernelHost();\n const cap = injectOptionalCapabilityFor(token);\n return host.value(() => {\n const c = cap();\n if (c === null) return fallback;\n try {\n return select(c);\n } catch {\n return fallback;\n }\n }, equal);\n}\n\nexport function injectOptionalSelector<C, R>(\n token: CapabilityToken<C>,\n select: (cap: C) => R,\n fallback: R,\n equal?: (a: R, b: R) => boolean,\n): Signal<R> {\n return injectOptionalSelectorFor(() => token, select, fallback, equal);\n}\n\n/** The document registry (open/close/active/list), reactive — `useDocuments`.\n * Methods late-bind the kernel, so this is construction-safe. */\nexport interface EpdfDocuments {\n docs: Signal<DocInfo[]>;\n activeId: Signal<string | null>;\n open: Kernel['documents']['open'];\n unlock: Kernel['documents']['unlock'];\n close: Kernel['documents']['close'];\n setActive: Kernel['documents']['setActive'];\n move: Kernel['documents']['move'];\n swap: Kernel['documents']['swap'];\n download: Kernel['documents']['download'];\n downloadLayer: Kernel['documents']['downloadLayer'];\n}\n\nexport function injectDocuments(): EpdfDocuments {\n const host = injectKernelHost();\n return {\n docs: host.value((k) => k.documents.list(), docInfoListEquals),\n activeId: host.value((k) => k.documents.activeId()),\n open: (input, options) => host.kernel.documents.open(input, options),\n unlock: (id, input) => host.kernel.documents.unlock(id, input),\n close: (id) => host.kernel.documents.close(id),\n setActive: (id) => host.kernel.documents.setActive(id),\n move: (id, toIndex) => host.kernel.documents.move(id, toIndex),\n swap: (a, b) => host.kernel.documents.swap(a, b),\n download: (id, opts) => host.kernel.documents.download(id, opts),\n downloadLayer: (id) => host.kernel.documents.downloadLayer(id),\n };\n}\n","/**\n * Document scoping — hierarchical DI is Angular's native React-context.\n *\n * `[epdfDocumentScope]` binds a subtree to a SPECIFIC document (panes,\n * comparison); `*epdfDocumentGate` renders a subtree only WHILE it has one.\n * The gate is a structural directive on purpose: a template genuinely defers\n * creation, which a conditional `<ng-content>` slot cannot (Angular\n * instantiates projected content eagerly). Document-scoped UI — the Stage,\n * zoom/page controls, panels — belongs behind it (or behind the app's own\n * `@if (documentId())`); workspace chrome lives outside it.\n */\nimport {\n computed,\n Directive,\n effect,\n forwardRef,\n inject,\n input,\n TemplateRef,\n ViewContainerRef,\n} from '@angular/core';\nimport { injectDocumentId } from './inject';\nimport { EPDF_DOCUMENT_SCOPE, type EpdfDocumentScopeRef } from './tokens';\n\n@Directive({\n selector: '[epdfDocumentScope]',\n standalone: true,\n providers: [{ provide: EPDF_DOCUMENT_SCOPE, useExisting: forwardRef(() => EpdfDocumentScope) }],\n})\nexport class EpdfDocumentScope implements EpdfDocumentScopeRef {\n readonly id = input.required<string>({ alias: 'epdfDocumentScope' });\n}\n\n/**\n * Render the host template only while this subtree has a document — the\n * structural way to say \"this UI is defined over a document\". Sibling of\n * `[epdfDocumentScope]`, which picks WHICH document; this one handles WHETHER.\n *\n * <section *epdfDocumentGate=\"; fallback: empty\">…document UI…</section>\n * <ng-template #empty>Drop a PDF to get started</ng-template>\n *\n * The subtree stays mounted across a CHANGE of document (active-tab switch) —\n * only the has-a-document boolean creates/destroys it.\n */\n@Directive({ selector: '[epdfDocumentGate]', standalone: true })\nexport class EpdfDocumentGate {\n /** Shown while this subtree has NO document (empty workspace, docs still opening). */\n readonly fallback = input<TemplateRef<unknown> | null>(null, {\n alias: 'epdfDocumentGateFallback',\n });\n\n constructor() {\n const docId = injectDocumentId();\n const hasDocument = computed(() => docId() !== null);\n const container = inject(ViewContainerRef);\n const content = inject<TemplateRef<unknown>>(TemplateRef);\n effect(() => {\n container.clear();\n if (hasDocument()) {\n container.createEmbeddedView(content);\n } else {\n // `fallback` is only tracked while gated — swapping fallback templates\n // never recreates live document UI.\n const fallbackTemplate = this.fallback();\n if (fallbackTemplate) container.createEmbeddedView(fallbackTemplate);\n }\n });\n }\n}\n","/**\n * `<epdf-viewer>` — component-hosted kernel (framework parity with React's\n * `<Viewer>`). Provides `EpdfKernelHost` at its element injector, boots it, and\n * projects content UNCONDITIONALLY: it is NOT a gate. Angular instantiates\n * projected content eagerly whether or not a slot renders it, so a conditional\n * `<ng-content>` cannot defer anything — real gating belongs to templates the\n * APP owns: `@if (ready())` for boot chrome, `*epdfDocumentGate` (or\n * `@if (documentId())`) for document UI.\n *\n * Prefer `provideEmbedPdf(...)` at route/app level when chrome lives outside\n * one subtree; this component is sugar over the same host.\n */\nimport { ChangeDetectionStrategy, Component, inject, input, type OnInit } from '@angular/core';\nimport type { AnyPlugin, Engine, EngineFactory } from '@embedpdf/core';\nimport { EpdfKernelHost, type EpdfInitialDocument } from './kernel-host';\n\n@Component({\n selector: 'epdf-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [EpdfKernelHost],\n // Layout-transparent, like React's element-less <Viewer>.\n host: { style: 'display: contents;' },\n template: `<ng-content />`,\n})\nexport class EpdfViewer implements OnInit {\n /** The engine, as an instance OR a thunk ({@link EngineFactory}). An\n * instance is borrowed (never destroyed here); a thunk is host-owned\n * (constructed then destroyed with the viewer). See EmbedPdfConfig.\n * Init-only: the kernel is built once from the first values; recreate the\n * viewer (e.g. with @if) to swap it. */\n readonly engine = input.required<Engine | EngineFactory>();\n readonly plugins = input.required<AnyPlugin[]>();\n readonly initialDocuments = input<EpdfInitialDocument[]>();\n\n /** The host this viewer provides — exposed so a template reference can read\n * `viewer.host.ready()` / `.status()` without extra imports. */\n readonly host = inject(EpdfKernelHost, { self: true });\n\n constructor() {\n // Deferred config: inputs are READ on first kernel access, which happens\n // after construction (a template binding or effect) — never here.\n this.host.connect(() => ({\n engine: this.engine(),\n plugins: this.plugins(),\n initialDocuments: this.initialDocuments(),\n }));\n }\n\n ngOnInit(): void {\n // Inputs are set by now; materializes the kernel and starts it (no-op on\n // the server — the SSR contract lives on the host).\n this.host.boot();\n }\n}\n","/**\n * PageContext — the seam. A layer depends ONLY on this, never on the Stage, so\n * the same layer works inside a virtualized `<epdf-stage>` page and a future\n * standalone `<epdf-page-view>`.\n *\n * THE STABILITY INVARIANT (the one performance rule of this adapter): a page's\n * context is ONE STABLE OBJECT per mounted surface — identity never changes;\n * the volatile parts (`transform`, `frame`, `pageIndex`) are signals INSIDE it.\n * The per-page injector providing `EPDF_PAGE` is likewise created once. Camera\n * frames then flow as signal writes — `NgTemplateOutlet` never recreates the\n * embedded views, in-flight renders survive, and updates stay per-binding.\n * Never rebuild the context or the injector per frame.\n *\n * Coordinate math lives in `@embedpdf/core-geometry`'s `PageTransform` — verified\n * once, not re-derived per framework adapter (`toContentPoint` mirrors React's\n * `makePageContext` exactly).\n */\nimport { InjectionToken, inject, type Signal } from '@angular/core';\nimport type { PageFrame, PageTransform, Point, Rect } from '@embedpdf/core-geometry';\n\nexport interface EpdfPageContext {\n readonly documentId: string;\n /** Durable page identity (PDF object number) — use for keys / render / annotations. */\n readonly pon: number;\n /** Display index (page N) — can shift under page reorders, hence a signal. */\n readonly pageIndex: Signal<number>;\n /** Reserved chrome bands around the page (screen px per side). */\n readonly frame: Signal<PageFrame>;\n /** The single bridge between PDF points, view px, and device px for this\n * page. Layers do ALL coordinate work through it — never re-derive\n * `x * scale` or `* dpr`. Updates per camera frame. */\n readonly transform: Signal<PageTransform>;\n /** Client (screen) point → the viewer's coordinates (content point) — the\n * one platform-bound hit-test. */\n toContentPoint(clientX: number, clientY: number): Point;\n /** Content point → client (screen) px — the exact inverse of `toContentPoint`. */\n toClientPoint(p: Point): Point;\n /** Content rect → client (screen) px AABB. */\n toClientRect(rect: Rect): Rect;\n}\n\nexport const EPDF_PAGE = new InjectionToken<EpdfPageContext>('EPDF_PAGE');\n\nexport function injectPage(): EpdfPageContext {\n const page = inject(EPDF_PAGE, { optional: true });\n if (!page) {\n throw new Error('[embedpdf] injectPage() must be used inside an <epdf-stage> page template');\n }\n return page;\n}\n\n/** Build a page context from its reactive parts. `documentId`/`pon` are thunks\n * because inputs aren't readable at construction — both are stable per surface. */\nexport function createPageContext(parts: {\n documentId: () => string;\n pon: () => number;\n pageIndex: Signal<number>;\n frame: Signal<PageFrame>;\n transform: Signal<PageTransform>;\n /** The rotated content wrapper's LIVE bounding box (the page's display box). */\n getRect: () => DOMRect;\n}): EpdfPageContext {\n const { transform, getRect } = parts;\n return {\n get documentId() {\n return parts.documentId();\n },\n get pon() {\n return parts.pon();\n },\n pageIndex: parts.pageIndex,\n frame: parts.frame,\n transform,\n toContentPoint: (clientX, clientY) => {\n // Client → box-local view px, then invert rotation + scale via the\n // transform (verified once in geometry, not re-derived per adapter).\n const r = getRect();\n return transform().viewToContent({ x: clientX - r.left, y: clientY - r.top });\n },\n toClientPoint: (p) => {\n // Exact inverse of `toContentPoint`, offset by the same live display-box\n // origin — the two can never drift.\n const r = getRect();\n const v = transform().contentToView(p);\n return { x: r.left + v.x, y: r.top + v.y };\n },\n toClientRect: (rect) => {\n const r = getRect();\n const v = transform().contentToViewRect(rect);\n return { x: r.left + v.x, y: r.top + v.y, width: v.width, height: v.height };\n },\n };\n}\n","/**\n * @embedpdf/angular/runtime — the trunk: the generic kernel binding.\n *\n * Binds the kernel's one change stream to Angular signals (one tick signal +\n * computed), resolves capabilities (document-scoped ones against the active or\n * `[epdfDocumentScope]`-given document), and provides the page context seam.\n * Every feature entry point and layer rides on this — there is no per-plugin\n * framework code.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/core';\nexport * from './kernel-host';\nexport * from './tokens';\nexport * from './inject';\nexport * from './scope';\nexport * from './viewer';\nexport * from './page-context';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;AAAA;;;;;;;;;;;;;;;;;;;AAmBG;MA2DU,cAAc,CAAA;IACR,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,GAAkC,IAAI;IAC5C,OAAO,GAAkB,IAAI;AACrC;AACwE;IAChE,OAAO,GAAkB,IAAI;IAC7B,UAAU,GAAG,KAAK;IAClB,WAAW,GAAuB,IAAI;AACtC,IAAA,gBAAgB;IAChB,MAAM,GAAG,KAAK;IACd,SAAS,GAAG,KAAK;;AAGR,IAAA,IAAI,GAAG,MAAM,CAAC,CAAC,gDAAC;;AAGxB,IAAA,MAAM,GAAG,MAAM,CAAmB,UAAU,kDAAC;AACtD;AACsD;AAC7C,IAAA,KAAK,GAAG,MAAM,CAAU,IAAI,iDAAC;AACtC;;;AAG0E;AACjE,IAAA,KAAK,GAAoB,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,OAAO,iDAAC;AAE3E;AACkD;AAClD,IAAA,OAAO,CAAC,MAA4B,EAAA;QAClC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE;AAC/B,YAAA,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC;QAC3E;AACA,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACtB;;AAGA,IAAA,IAAI,MAAM,GAAA;AACR,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,gBAAA,MAAM,IAAI,KAAK,CACb,sJAAsJ,CACvJ;YACH;AACA,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAChB,gBAAA,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG;YACH;AACA,YAAA,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE;;;;AAI3D,YAAA,IAAI,CAAC,UAAU,GAAG,OAAO,MAAM,KAAK,UAAU;AAC9C,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,GAAI,MAAwB,EAAE,GAAI,MAAiB;AACjF,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAChE;YAAE,OAAO,KAAK,EAAE;;;gBAGd,IAAI,IAAI,CAAC,UAAU;AAAE,oBAAA,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;AAChD,gBAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,gBAAA,IAAI,CAAC,UAAU,GAAG,KAAK;AACvB,gBAAA,MAAM,KAAK;YACb;;;;AAIA,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI;AACvB,YAAA,IAAI,CAAC,gBAAgB,GAAG,gBAAgB;AACxC,YAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjF;QACA,OAAO,IAAI,CAAC,OAAO;IACrB;AAEA;AAC+C;IAC/C,IAAI,GAAA;QACF,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AACpD,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;QAC1B,KAAK,CAAC,YAAW;AACf,YAAA,IAAI;AACF,gBAAA,MAAM,MAAM,CAAC,KAAK,EAAE;YACtB;YAAE,OAAO,GAAG,EAAE;AACZ,gBAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AACnB,oBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AACnB,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;gBAC1B;gBACA;YACF;YACA,IAAI,IAAI,CAAC,SAAS;gBAAE;AACpB,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;;;;;YAKxB,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC;QACvD,CAAC,GAAG;IACN;AAEA;;AAEsD;AACtD,IAAA,KAAK,CAAI,MAA6B,EAAE,KAAA,GAAiC,MAAM,CAAC,EAAE,EAAA;QAChF,OAAO,QAAQ,CACb,MAAK;YACH,IAAI,CAAC,IAAI,EAAE;AACX,YAAA,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5B,QAAA,CAAC,EACD,EAAE,KAAK,EAAE,CACV;IACH;IAEA,WAAW,GAAA;QACT,IAAI,IAAI,CAAC,SAAS;YAAE;AACpB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,CAAC,WAAW,IAAI;;;;;;;AAOpB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO;AAC3B,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU;YAC5B,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAK;gBACpC,IAAI,IAAI,IAAI,MAAM;AAAE,oBAAA,KAAK,MAAM,CAAC,OAAO,EAAE;AAC3C,YAAA,CAAC,CAAC;QACJ;IACF;uGAnIW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAd,cAAc,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B;;AAuID;;;;;AAKG;AACG,SAAU,eAAe,CAAC,MAAsB,EAAA;AACpD,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,cAAc;YACvB,UAAU,EAAE,MAAK;AACf,gBAAA,MAAM,IAAI,GAAG,IAAI,cAAc,EAAE;gBACjC,IAAI,CAAC,OAAO,CAAC,MAAM,MAAM,CAAC;gBAC1B,IAAI,CAAC,IAAI,EAAE;AACX,gBAAA,OAAO,IAAI;YACb,CAAC;AACF,SAAA;AACF,KAAA,CAAC;AACJ;;ACtOA;;;AAGG;MASU,mBAAmB,GAAG,IAAI,cAAc,CAAuB,qBAAqB;;ACZjG;;;;;;;;AAQG;AAOI,MAAM,YAAY,GAAG,CAAI,CAAe,EAAE,CAAe,KAC9D,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;SAEpD,gBAAgB,GAAA;AAC9B,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,MAAM,IAAI,KAAK,CACb,wGAAwG,CACzG;IACH;AACA,IAAA,OAAO,IAAI;AACb;AAEA;;AAEiF;SACjE,YAAY,GAAA;AAC1B,IAAA,OAAO,gBAAgB,EAAE,CAAC,MAAM;AAClC;AAEA;AACM,SAAU,iBAAiB,CAC/B,MAA6B,EAC7B,KAA+B,EAAA;IAE/B,OAAO,gBAAgB,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AAChD;SAEgB,sBAAsB,GAAA;AACpC,IAAA,OAAO,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;AACzD;AAEA;AACgC;SAChB,gBAAgB,GAAA;AAC9B,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC7D,IAAA,MAAM,MAAM,GAAG,sBAAsB,EAAE;AACvC,IAAA,OAAO,QAAQ,CAAC,MAAM,KAAK,EAAE,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;AAChD;AAEA;;;;;;;;;;AAUG;AACG,SAAU,mBAAmB,CAAI,KAA+B,EAAA;AACpE,IAAA,MAAM,IAAI,GAAG,gBAAgB,EAAE;AAC/B,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,SAAS,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,SAAS,CAAC,CAAC;AAC3F;AAEM,SAAU,gBAAgB,CAAI,KAAyB,EAAA;AAC3D,IAAA,OAAO,mBAAmB,CAAC,MAAM,KAAK,CAAC;AACzC;AAEA;AACgE;AAC1D,SAAU,2BAA2B,CAAI,KAA+B,EAAA;AAC5E,IAAA,MAAM,IAAI,GAAG,gBAAgB,EAAE;AAC/B,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC7D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,SAAS,CAAC,CAAC;AAC9E;AAEM,SAAU,wBAAwB,CAAI,KAAyB,EAAA;AACnE,IAAA,OAAO,2BAA2B,CAAC,MAAM,KAAK,CAAC;AACjD;AAEA;SACgB,iBAAiB,CAC/B,KAA+B,EAC/B,MAAqB,EACrB,KAA+B,EAAA;AAE/B,IAAA,MAAM,IAAI,GAAG,gBAAgB,EAAE;AAC/B,IAAA,MAAM,GAAG,GAAG,mBAAmB,CAAC,KAAK,CAAC;AACtC,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC;AAC/C;SAEgB,cAAc,CAC5B,KAAyB,EACzB,MAAqB,EACrB,KAA+B,EAAA;IAE/B,OAAO,iBAAiB,CAAC,MAAM,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC;AACtD;AAEA;;;;;;;;;;AAUG;AACG,SAAU,yBAAyB,CACvC,KAA+B,EAC/B,MAAqB,EACrB,QAAW,EACX,KAA+B,EAAA;AAE/B,IAAA,MAAM,IAAI,GAAG,gBAAgB,EAAE;AAC/B,IAAA,MAAM,GAAG,GAAG,2BAA2B,CAAC,KAAK,CAAC;AAC9C,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,MAAK;AACrB,QAAA,MAAM,CAAC,GAAG,GAAG,EAAE;QACf,IAAI,CAAC,KAAK,IAAI;AAAE,YAAA,OAAO,QAAQ;AAC/B,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,CAAC,CAAC,CAAC;QAClB;AAAE,QAAA,MAAM;AACN,YAAA,OAAO,QAAQ;QACjB;IACF,CAAC,EAAE,KAAK,CAAC;AACX;AAEM,SAAU,sBAAsB,CACpC,KAAyB,EACzB,MAAqB,EACrB,QAAW,EACX,KAA+B,EAAA;AAE/B,IAAA,OAAO,yBAAyB,CAAC,MAAM,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;AACxE;SAiBgB,eAAe,GAAA;AAC7B,IAAA,MAAM,IAAI,GAAG,gBAAgB,EAAE;IAC/B,OAAO;AACL,QAAA,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,iBAAiB,CAAC;AAC9D,QAAA,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;AACnD,QAAA,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;AACpE,QAAA,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC;AAC9D,QAAA,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,QAAA,SAAS,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;AACtD,QAAA,IAAI,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC;AAC9D,QAAA,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;AAChD,QAAA,QAAQ,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;AAChE,QAAA,aAAa,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;KAC/D;AACH;;AChLA;;;;;;;;;;AAUG;MAmBU,iBAAiB,CAAA;AACnB,IAAA,EAAE,GAAG,KAAK,CAAC,QAAQ,qCAAW,KAAK,EAAE,mBAAmB,EAAA,CAAA,GAAA,CAA5B,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAC;uGADzD,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,2MAFjB,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,iBAAiB,CAAC,EAAE,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAEpF,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAL7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAK,iBAAkB,CAAC,EAAE,CAAC;AAChG,iBAAA;;AAKD;;;;;;;;;;AAUG;MAEU,gBAAgB,CAAA;;IAElB,QAAQ,GAAG,KAAK,CAA8B,IAAI,4CACzD,KAAK,EAAE,0BAA0B,EAAA,CAAA,GAAA,CAD0B;AAC3D,YAAA,KAAK,EAAE,0BAA0B;AAClC,SAAA,CAAA,CAAA,CAAC;AAEF,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,KAAK,GAAG,gBAAgB,EAAE;AAChC,QAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,KAAK,EAAE,KAAK,IAAI,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;AACpD,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC1C,QAAA,MAAM,OAAO,GAAG,MAAM,CAAuB,WAAW,CAAC;QACzD,MAAM,CAAC,MAAK;YACV,SAAS,CAAC,KAAK,EAAE;YACjB,IAAI,WAAW,EAAE,EAAE;AACjB,gBAAA,SAAS,CAAC,kBAAkB,CAAC,OAAO,CAAC;YACvC;iBAAO;;;AAGL,gBAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE;AACxC,gBAAA,IAAI,gBAAgB;AAAE,oBAAA,SAAS,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;YACtE;AACF,QAAA,CAAC,CAAC;IACJ;uGAtBW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,0BAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA,EAAE,QAAQ,EAAE,oBAAoB,EAAE,UAAU,EAAE,IAAI,EAAE;;;AC5C/D;;;;;;;;;;;AAWG;MAcU,UAAU,CAAA;AACrB;;;;AAIyC;AAChC,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAA0B;AACjD,IAAA,OAAO,GAAG,KAAK,CAAC,QAAQ,kDAAe;IACvC,gBAAgB,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAyB;AAE1D;AACiE;IACxD,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAEtD,IAAA,WAAA,GAAA;;;QAGE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;AACvB,YAAA,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;AACrB,YAAA,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;AACvB,YAAA,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAC1C,SAAA,CAAC,CAAC;IACL;IAEA,QAAQ,GAAA;;;AAGN,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IAClB;uGA5BW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,oBAAA,EAAA,EAAA,SAAA,EALV,CAAC,cAAc,CAAC,0BAGjB,CAAA,cAAA,CAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAEf,UAAU,EAAA,UAAA,EAAA,CAAA;kBATtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,UAAU,EAAE,IAAI;oBAChB,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,SAAS,EAAE,CAAC,cAAc,CAAC;;AAE3B,oBAAA,IAAI,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE;AACrC,oBAAA,QAAQ,EAAE,CAAA,cAAA,CAAgB;AAC3B,iBAAA;;;ACxBD;;;;;;;;;;;;;;;;AAgBG;MAyBU,SAAS,GAAG,IAAI,cAAc,CAAkB,WAAW;SAExD,UAAU,GAAA;AACxB,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC;IAC9F;AACA,IAAA,OAAO,IAAI;AACb;AAEA;AACoF;AAC9E,SAAU,iBAAiB,CAAC,KAQjC,EAAA;AACC,IAAA,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK;IACpC,OAAO;AACL,QAAA,IAAI,UAAU,GAAA;AACZ,YAAA,OAAO,KAAK,CAAC,UAAU,EAAE;QAC3B,CAAC;AACD,QAAA,IAAI,GAAG,GAAA;AACL,YAAA,OAAO,KAAK,CAAC,GAAG,EAAE;QACpB,CAAC;QACD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS;AACT,QAAA,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,KAAI;;;AAGnC,YAAA,MAAM,CAAC,GAAG,OAAO,EAAE;YACnB,OAAO,SAAS,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/E,CAAC;AACD,QAAA,aAAa,EAAE,CAAC,CAAC,KAAI;;;AAGnB,YAAA,MAAM,CAAC,GAAG,OAAO,EAAE;YACnB,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;YACtC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE;QAC5C,CAAC;AACD,QAAA,YAAY,EAAE,CAAC,IAAI,KAAI;AACrB,YAAA,MAAM,CAAC,GAAG,OAAO,EAAE;YACnB,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;AAC7C,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAC9E,CAAC;KACF;AACH;;AC5FA;;;;;;;;AAQG;AAEH;;ACVA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-runtime.mjs","sources":["../../runtime/src/errors.ts","../../runtime/src/tokens.ts","../../runtime/src/settings-before-start.ts","../../runtime/src/kernel-host.ts","../../runtime/src/capability.ts","../../runtime/src/service.ts","../../runtime/src/services.ts","../../runtime/src/provide.ts","../../runtime/src/scope.ts","../../runtime/src/page-context.ts","../../runtime/src/page-layers.ts","../../runtime/src/svg-shapes.ts","../../runtime/src/dev.ts","../../runtime/src/theme.ts","../../runtime/src/public_api.ts","../../runtime/src/embedpdf-angular-runtime.ts"],"sourcesContent":["/**\n * The adapter's numbered errors, written like Angular's own (`NG0201`): a code, what went wrong,\n * how to fix it, and the page that explains it. A code keeps its meaning once it ships, so a\n * search for `EPDF-101` always finds the right answer.\n *\n * Errors about the document (no document open yet, a permission missing) are the plugins'\n * `PluginError`s, the same in every framework; these are only about how the app set up the\n * adapter.\n */\nconst ERRORS_PAGE = 'https://www.embedpdf.com/docs/headless/angular/errors';\n\n/** A setup mistake, with its code: `EPDF-101`. */\nexport class EpdfError extends Error {\n override readonly name = 'EpdfError';\n\n constructor(\n readonly code: `EPDF-${number}`,\n problem: string,\n ) {\n super(`${code}: ${problem} See ${ERRORS_PAGE}#${code.toLowerCase()}`);\n }\n}\n\n/** EPDF-101: a service, component or directive of the viewer, with no viewer above it. */\nexport const noViewerError = (what: string): EpdfError =>\n new EpdfError(\n 'EPDF-101',\n `${what} found no viewer. Add provideEmbedPdf() to this component's providers, or to your app config.`,\n );\n\n/** EPDF-102: a plugin's service, where no viewer above it has that plugin. */\nexport const noPluginError = (service: string, feature: string): EpdfError =>\n new EpdfError(\n 'EPDF-102',\n `inject(${service}) found no viewer with its plugin. Add ${feature} to provideEmbedPdf() ` +\n `in this component's providers, or in your app config.`,\n );\n\n/** EPDF-103: something that draws on a page, outside a page. */\nexport const outsidePageError = (what: string): EpdfError =>\n new EpdfError(\n 'EPDF-103',\n `${what} draws on a page. Put it inside <ng-template epdfPage> in an <epdf-stage>.`,\n );\n\n/** EPDF-104: part of a Stage, outside one. */\nexport const outsideStageError = (what: string): EpdfError =>\n new EpdfError('EPDF-104', `${what} belongs to a Stage. Put it inside <epdf-stage>.`);\n\n/** EPDF-105: a call that needs the engine, made while rendering on the server. */\nexport const onServerError = (what: string): EpdfError =>\n new EpdfError(\n 'EPDF-105',\n `${what} needs the engine, which runs in the browser only. Call it from an event or ` +\n `afterNextRender(), or put the viewer in a @defer block.`,\n );\n","/**\n * The DI tokens the runtime's pieces share, in a file of their own so the pieces that provide\n * them and the ones that read them never import each other.\n */\nimport { InjectionToken, type Signal } from '@angular/core';\nimport type { EmbedPdfConfig, EmbedPdfFeature, EmbedPdfKernelConfig } from './config';\n\n/**\n * The document a part of the template talks to: `[epdfDocumentScope]`, or a Stage that opened\n * its own `[document]`. A null id follows the active document.\n */\nexport interface EpdfDocumentScopeRef {\n readonly id: Signal<string | null>;\n}\n\nexport const EPDF_DOCUMENT_SCOPE = new InjectionToken<EpdfDocumentScopeRef>('EPDF_DOCUMENT_SCOPE');\n\n/** What `provideEmbedPdf()` was given, for the viewer it creates. */\nexport interface EmbedPdfSetup {\n readonly config: EmbedPdfConfig | EmbedPdfKernelConfig;\n readonly features: readonly EmbedPdfFeature[];\n}\n\nexport const EPDF_SETUP = new InjectionToken<EmbedPdfSetup>('EPDF_SETUP');\n","/**\n * Settings before the kernel exists. With an engine that loads lazily, the app can read and\n * change a plugin's settings (and the viewer's) before the kernel is there to keep them. This\n * keeps the changes in order, shows what they add up to, and hands them to the kernel when it\n * arrives, so `settings()` and `updateSettings()` work from the first moment, as they do in\n * every other framework.\n *\n * The merge is the kernel's own (`mergeSettings` from `@embedpdf/core`), so the settings shown\n * before the kernel exists are the ones it then has.\n */\nimport { computed, signal, type Signal } from '@angular/core';\nimport { mergeSettings } from '@embedpdf/core';\nimport type { DeepPartial, SettingsDeclaration } from '@embedpdf/core';\n\n/** One settings store's changes, kept until the kernel takes them. */\nexport class SettingsBeforeStart<T extends object> {\n private readonly changes = signal<readonly (DeepPartial<T> | 'reset')[]>([]);\n\n /** The settings the changes add up to, over what the app registered. */\n readonly current: Signal<T>;\n\n constructor(declaration: SettingsDeclaration<T>) {\n const registered = mergeSettings(\n declaration.defaults,\n declaration.registered,\n declaration.whole,\n );\n this.current = computed(() =>\n this.changes().reduce<T>(\n (settings, change) =>\n change === 'reset' ? registered : mergeSettings(settings, change, declaration.whole),\n registered,\n ),\n );\n }\n\n update(change: DeepPartial<T>): void {\n this.changes.update((changes) => [...changes, change]);\n }\n\n reset(): void {\n this.changes.update((changes) => [...changes, 'reset']);\n }\n\n /** Hand the changes to the kernel's store, in order, and forget them. */\n applyTo(store: { updateSettings(change: DeepPartial<T>): void; resetSettings(): void }): void {\n for (const change of this.changes()) {\n if (change === 'reset') store.resetSettings();\n else store.updateSettings(change);\n }\n this.changes.set([]);\n }\n}\n","/**\n * The viewer behind `provideEmbedPdf()`: one per injector that provides it. In the browser it\n * creates the kernel as soon as the engine is there (at once for an engine instance, later for a\n * factory that loads one), starts it, opens the initial documents, runs the features' `setup`,\n * and destroys it all with the injector. Given a kernel (`provideEmbedPdf({ kernel })`), it uses\n * that one as it is, and leaves starting and destroying it to whoever made it.\n *\n * The kernel has one change stream; the host turns each change into a write of `revision`, and\n * every signal in the adapter is a `computed()` over it (`read()`), which keeps its value, and\n * wakes nothing, while what it reads is unchanged.\n *\n * On the server the host creates no kernel: every read gives its empty value and a call that\n * needs the engine throws EPDF-105, so the page around the viewer still renders.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n computed,\n DestroyRef,\n inject,\n Injectable,\n Injector,\n PLATFORM_ID,\n runInInjectionContext,\n signal,\n untracked,\n type Signal,\n} from '@angular/core';\nimport {\n createKernel,\n DocumentsToken,\n isLocalEngine,\n PluginError,\n shallowEqual,\n VIEWER_DEFAULTS,\n VIEWER_WHOLE_SETTINGS,\n viewerSettingsOf,\n} from '@embedpdf/core';\nimport type {\n AnyPlugin,\n CapabilityToken,\n DeepPartial,\n Engine,\n EventHook,\n Kernel,\n KernelStatus,\n SettingsApi,\n SettingsDeclaration,\n ViewerSettings,\n} from '@embedpdf/core';\nimport { browserClock } from '@embedpdf/web';\nimport { Observable } from 'rxjs';\nimport type { EmbedPdfConfig, EmbedPdfKernelConfig, EpdfViewerStatus } from './config';\nimport { onServerError } from './errors';\nimport { SettingsBeforeStart } from './settings-before-start';\nimport { EPDF_SETUP } from './tokens';\n\n/**\n * The viewer's settings as the config gives them (a setting left out is its default), the same\n * way every framework's viewer reads its props; what `resetSettings()` goes back to. A kernel\n * given has its own.\n */\nconst registeredViewerSettings = (config: EmbedPdfConfig | EmbedPdfKernelConfig): ViewerSettings =>\n viewerSettingsOf('kernel' in config ? {} : config);\n\n/**\n * Whether `kernel` has a plugin that provides `token`. A document plugin's token has its scope\n * (any other token reads as a workspace one), and a workspace plugin's capability is there from\n * the moment the kernel is created.\n */\nconst kernelProvides = (kernel: Kernel, token: CapabilityToken<unknown>): boolean =>\n kernel.scopeOf(token) === 'document' || kernel.tryCapability(token) !== null;\n\n/** The settings of the plugin that provides `token` in `kernel`, or null when it has none. */\nfunction kernelSettingsOf<T extends object>(\n kernel: Kernel,\n token: CapabilityToken<unknown>,\n): SettingsApi<T> | null {\n try {\n return kernel.settingsOf(token) as unknown as SettingsApi<T>;\n } catch {\n // The kernel's answer for a token no plugin provides, or a plugin without settings.\n return null;\n }\n}\n\n/** What the viewer is doing, as a kernel someone else started says it. */\nconst statusOfKernel = (status: KernelStatus): EpdfViewerStatus =>\n status === 'started' ? 'ready' : status === 'failed' ? 'error' : 'starting';\n\n/** A plugin's settings, readable and changeable before the kernel exists and after. */\nexport interface PluginSettingsBinding<T> {\n readonly current: Signal<T>;\n update(change: DeepPartial<T>): void;\n reset(): void;\n}\n\nconst isPromiseLike = <T>(value: T | Promise<T>): value is Promise<T> =>\n typeof (value as { then?: unknown }).then === 'function';\n\n@Injectable()\nexport class EpdfKernelHost {\n private readonly setup = inject(EPDF_SETUP);\n private readonly injector = inject(Injector);\n /** Whether this is a browser. On the server the host creates no kernel. */\n readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n /** The kernel `provideEmbedPdf({ kernel })` was given: someone else's, used as it is. */\n private readonly given: Kernel | null =\n 'kernel' in this.setup.config ? this.setup.config.kernel : null;\n /** Every plugin the features register, in their order: none for a kernel given, which has its own. */\n readonly plugins: readonly AnyPlugin[] = this.given\n ? []\n : this.setup.features.flatMap((feature) => feature.plugins);\n\n private readonly kernelState = signal<Kernel | null>(null);\n private readonly revisionState = signal(0);\n private readonly statusState = signal<EpdfViewerStatus>('starting');\n private readonly errorState = signal<unknown>(null);\n private readonly listeners = new Set<() => void>();\n private readonly viewerSettingsBeforeStart = new SettingsBeforeStart<ViewerSettings>({\n defaults: VIEWER_DEFAULTS,\n registered: registeredViewerSettings(this.setup.config),\n whole: VIEWER_WHOLE_SETTINGS,\n });\n private readonly pluginSettings = new Map<\n CapabilityToken<unknown>,\n PluginSettingsBinding<object>\n >();\n private readonly pluginSettingsBeforeStart = new Map<AnyPlugin, SettingsBeforeStart<object>>();\n private engine: Engine | null = null;\n private ownsEngine = false;\n private stopListening: (() => void) | null = null;\n private destroyed = false;\n\n /**\n * The kernel, once it exists: null while a lazily loaded engine is on its way, and on the\n * server, where only a kernel given is there.\n */\n readonly kernel: Signal<Kernel | null> = this.kernelState.asReadonly();\n /** Goes up on every change of the kernel's state. */\n readonly revision: Signal<number> = this.revisionState.asReadonly();\n /** A kernel given says it itself: someone else starts it. */\n readonly status: Signal<EpdfViewerStatus> = this.given\n ? this.read(\n (kernel) => statusOfKernel(kernel.status()),\n () => 'starting',\n )\n : this.statusState.asReadonly();\n /** Why the viewer failed to start, when `status()` is `'error'`. */\n readonly error: Signal<unknown> = this.errorState.asReadonly();\n /** The viewer's own settings, before the kernel exists and after. */\n readonly viewerSettings: Signal<ViewerSettings> = this.read(\n (kernel) => kernel.getSettings(),\n () => this.viewerSettingsBeforeStart.current(),\n shallowEqual,\n );\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.destroy());\n const { config } = this.setup;\n // A kernel given is the kernel, wherever it was made.\n if ('kernel' in config) this.adopt(config.kernel);\n if (!this.browser) return;\n if (!('kernel' in config)) this.start(config);\n // After construction, because a feature's setup injects services, and they inject this host.\n queueMicrotask(() => this.runFeatureSetups());\n }\n\n /**\n * A value read from the kernel, as a signal: `select` runs again after each change of the\n * kernel's state, and the signal changes only when `equal` says the value did. `empty` is its\n * value while there is no kernel.\n */\n read<R>(\n select: (kernel: Kernel) => R,\n empty: () => R,\n equal: (left: R, right: R) => boolean = Object.is,\n ): Signal<R> {\n return computed(\n () => {\n this.revisionState();\n const kernel = this.kernelState();\n return kernel ? select(kernel) : empty();\n },\n { equal },\n );\n }\n\n /** Call `listener` after each change of the kernel's state, and once when the kernel arrives. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * An event of the kernel itself (its settings, a plugin's settings store), as an RxJS\n * stream. A subscription made before the kernel exists starts listening when it arrives.\n */\n stream<T>(pick: (kernel: Kernel) => EventHook<T>): Observable<T> {\n return new Observable<T>((subscriber) => {\n let listening: AbortController | null = null;\n const listen = () => {\n const kernel = untracked(this.kernelState);\n if (!kernel || listening) return;\n listening = new AbortController();\n pick(kernel)((event) => subscriber.next(event), { signal: listening.signal });\n };\n const stop = this.subscribe(listen);\n listen();\n return () => {\n stop();\n listening?.abort();\n };\n });\n }\n\n /** Whether a plugin of this viewer provides `token` (the documents are always there). */\n provides(token: CapabilityToken<unknown>): boolean {\n if (token === DocumentsToken) return true;\n return this.given ? kernelProvides(this.given, token) : this.pluginFor(token) !== null;\n }\n\n /** Whether the plugin of this viewer that provides `token` has settings. */\n hasSettings(token: CapabilityToken<unknown>): boolean {\n return this.given\n ? kernelSettingsOf(this.given, token) !== null\n : Boolean(this.pluginFor(token)?.settings);\n }\n\n /**\n * The kernel, for `call` (`'zoomIn()'`) on `capability` (`'stage'`), which needs it now:\n * `not-ready` while the engine is still on its way, EPDF-105 on the server.\n */\n requireKernel(capability: string, call: string): Kernel {\n const kernel = this.kernelState();\n if (kernel) return kernel;\n if (!this.browser) throw onServerError(call);\n throw new PluginError('not-ready', capability, 'the viewer is still starting');\n }\n\n updateViewerSettings(change: DeepPartial<ViewerSettings>): void {\n const kernel = this.kernelState();\n if (kernel) kernel.updateSettings(change);\n else this.viewerSettingsBeforeStart.update(change);\n }\n\n resetViewerSettings(): void {\n const kernel = this.kernelState();\n if (kernel) kernel.resetSettings();\n else this.viewerSettingsBeforeStart.reset();\n }\n\n /**\n * A plugin's settings, with or without a document, and before the kernel too: they belong to\n * the plugin as the app registered it. One binding per plugin, shared by every service.\n */\n settingsOf<T extends object>(token: CapabilityToken<unknown>): PluginSettingsBinding<T> {\n const known = this.pluginSettings.get(token);\n if (known) return known as PluginSettingsBinding<T>;\n const binding = this.given\n ? this.givenSettingsOf<T>(this.given, token)\n : this.registeredSettingsOf<T>(token);\n this.pluginSettings.set(token, binding as PluginSettingsBinding<object>);\n return binding;\n }\n\n /** A registered plugin's settings, kept from before the kernel exists. */\n private registeredSettingsOf<T extends object>(\n token: CapabilityToken<unknown>,\n ): PluginSettingsBinding<T> {\n const plugin = this.pluginFor(token);\n const declaration = plugin?.settings as SettingsDeclaration<T> | undefined;\n if (!plugin || !declaration) {\n throw new PluginError('unsupported', token.name, 'this plugin has no settings');\n }\n\n const before = new SettingsBeforeStart<T>(declaration);\n this.pluginSettingsBeforeStart.set(plugin, before as SettingsBeforeStart<object>);\n const store = (kernel: Kernel) => kernel.settingsOf(token) as unknown as SettingsApi<T>;\n return {\n current: this.read(\n (kernel) => store(kernel).getSettings(),\n () => before.current(),\n shallowEqual,\n ),\n update: (change) => {\n const kernel = this.kernelState();\n if (kernel) store(kernel).updateSettings(change);\n else before.update(change);\n },\n reset: () => {\n const kernel = this.kernelState();\n if (kernel) store(kernel).resetSettings();\n else before.reset();\n },\n };\n }\n\n /** A plugin's settings in a kernel given, which is there from the start. */\n private givenSettingsOf<T extends object>(\n kernel: Kernel,\n token: CapabilityToken<unknown>,\n ): PluginSettingsBinding<T> {\n const store = kernelSettingsOf<T>(kernel, token);\n if (!store) throw new PluginError('unsupported', token.name, 'this plugin has no settings');\n const current = () => store.getSettings();\n return {\n current: this.read(current, current, shallowEqual),\n update: (change) => store.updateSettings(change),\n reset: () => store.resetSettings(),\n };\n }\n\n private pluginFor(token: CapabilityToken<unknown>): AnyPlugin | null {\n return this.plugins.find((plugin) => plugin.token === token) ?? null;\n }\n\n // ── lifetime ────────────────────────────────────────────────────────────────\n\n /** Follow a kernel someone else made: its changes, and nothing of its lifetime. */\n private adopt(kernel: Kernel): void {\n this.stopListening = kernel.subscribe(() => this.changed());\n this.kernelState.set(kernel);\n this.changed();\n }\n\n private start(config: EmbedPdfConfig): void {\n const source = config.engine;\n const owned = typeof source === 'function';\n let made: Engine | Promise<Engine>;\n try {\n made = owned ? source() : source;\n } catch (error) {\n this.fail(error);\n return;\n }\n if (isPromiseLike(made)) {\n made.then(\n (engine) => this.attach(config, engine, owned),\n (error: unknown) => this.fail(error),\n );\n } else {\n this.attach(config, made, owned);\n }\n }\n\n /** Create and start the kernel over `engine`. An engine this viewer made is destroyed with it. */\n private attach(config: EmbedPdfConfig, engine: Engine, owned: boolean): void {\n if (this.destroyed) {\n if (owned) void engine.destroy();\n return;\n }\n // Warming a local engine up now overlaps its WebAssembly boot with the plugins' setup.\n if (isLocalEngine(engine)) engine.warmup();\n let kernel: Kernel;\n try {\n kernel = createKernel({\n engine,\n plugins: [...this.plugins],\n settings: registeredViewerSettings(config),\n clock: browserClock(),\n });\n } catch (error) {\n if (owned) void engine.destroy();\n this.fail(error);\n return;\n }\n this.engine = engine;\n this.ownsEngine = owned;\n this.viewerSettingsBeforeStart.applyTo(kernel);\n for (const [plugin, before] of this.pluginSettingsBeforeStart) {\n before.applyTo(kernel.settingsOf(plugin.token as CapabilityToken<unknown>));\n }\n this.stopListening = kernel.subscribe(() => this.changed());\n this.kernelState.set(kernel);\n this.changed();\n kernel.start().then(\n () => {\n if (this.destroyed) return;\n this.statusState.set('ready');\n // Every tab appears at once, in order; a document that fails shows it in its own tab.\n kernel.documents.openAll(config.initialDocuments ?? []);\n },\n (error: unknown) => {\n if (!this.destroyed) this.fail(error);\n },\n );\n }\n\n private changed(): void {\n this.revisionState.update((revision) => revision + 1);\n for (const listener of [...this.listeners]) listener();\n }\n\n private fail(error: unknown): void {\n this.errorState.set(error);\n this.statusState.set('error');\n console.error('[embedpdf] the viewer failed to start', error);\n }\n\n private runFeatureSetups(): void {\n if (this.destroyed) return;\n for (const feature of this.setup.features) {\n if (feature.setup) runInInjectionContext(this.injector, feature.setup);\n }\n }\n\n private destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.stopListening?.();\n this.listeners.clear();\n // A kernel given is its maker's to destroy.\n if (this.given) return;\n const kernel = this.kernelState();\n const engine = this.engine;\n const owned = this.ownsEngine;\n // The kernel first, which closes every document's engine handle, then the engine it ran on.\n if (kernel) {\n void kernel.destroy().then(() => {\n if (owned && engine) void engine.destroy();\n });\n }\n }\n}\n","/**\n * How the adapter reaches a plugin: its capability token, resolved for one document (the one in\n * scope, else the active one) after every change of the kernel. A `CapabilityBinding` turns that\n * into what Angular code wants: signals for values, late-bound methods for calls, and RxJS\n * streams for events. Services, the Stage and the page layers are all built on it.\n *\n * Resolution is a read, not a cache: a document becomes resolvable when it's ready, while its\n * id stays the same, so a capability looked up once by id would go stale.\n */\nimport { computed, inject, signal, untracked, type Signal } from '@angular/core';\nimport {\n isPluginError,\n isReadMember,\n PluginError,\n returnsPromise,\n shallowEqual,\n} from '@embedpdf/core';\nimport type { CapabilityToken, EventHook, Kernel } from '@embedpdf/core';\nimport { Observable } from 'rxjs';\nimport { noViewerError } from './errors';\nimport { EpdfKernelHost } from './kernel-host';\nimport { EPDF_DOCUMENT_SCOPE } from './tokens';\n\n/** The viewer above this injection context; EPDF-101, naming `what`, when there is none. */\nexport function injectKernelHost(what: string): EpdfKernelHost {\n const host = inject(EpdfKernelHost, { optional: true });\n if (!host) throw noViewerError(what);\n return host;\n}\n\nconst FOLLOW_ACTIVE: Signal<string | null> = signal(null).asReadonly();\n\n/**\n * The document this injection context talks to: the id the nearest `[epdfDocumentScope]` (or a\n * Stage with a `[document]`) gives, or null to follow the active document.\n */\nexport function injectDocumentScope(): Signal<string | null> {\n return inject(EPDF_DOCUMENT_SCOPE, { optional: true })?.id ?? FOLLOW_ACTIVE;\n}\n\n/**\n * A plugin's capability for this injection context's document, as a signal: null while it\n * can't resolve (no such plugin, no document, or one that isn't ready yet). For plugin authors;\n * apps use a plugin's service (`inject(EpdfSearch)`). Call it in an injection context.\n */\nexport function injectCapability<Capability>(\n token: CapabilityToken<Capability>,\n): Signal<Capability | null> {\n const binding = new CapabilityBinding(\n injectKernelHost(`injectCapability(${token.name})`),\n () => token,\n injectDocumentScope(),\n );\n return binding.capability;\n}\n\n/** One capability token, for one document, as signals, calls and streams. */\nexport class CapabilityBinding<Capability> {\n /** The capability, or null while it can't resolve. */\n readonly capability: Signal<Capability | null>;\n\n /**\n * @param token the token to resolve; a function, because a component's token is an input\n * @param documentId the document to resolve it for, or null for the active one\n */\n constructor(\n readonly host: EpdfKernelHost,\n private readonly token: () => CapabilityToken<Capability>,\n private readonly documentId: () => string | null,\n ) {\n this.capability = host.read(\n (kernel) => this.resolve(kernel),\n () => null,\n );\n }\n\n /**\n * A value read through the capability, as a signal that changes only when `equal` says the\n * value did. `empty` while the capability can't resolve, and for the one read that can land\n * between a document closing and its capability going away.\n */\n select<R>(\n read: (capability: Capability) => R,\n empty: R,\n equal: (left: R, right: R) => boolean = shallowEqual,\n ): Signal<R> {\n return this.host.read(\n (kernel) => {\n const capability = this.resolve(kernel);\n if (!capability) return empty;\n try {\n return read(capability);\n } catch {\n return empty;\n }\n },\n () => empty,\n equal,\n );\n }\n\n /**\n * The capability, for `call`, which needs it now. Without a document a document plugin\n * refuses with `not-ready` (\"no document is open\"), the same refusal every framework's\n * stand-in gives (`standInFor` in `@embedpdf/core`); a token no plugin provides throws the\n * kernel's reason, because that is a setup mistake.\n */\n require(call: string): Capability {\n const token = this.token();\n const kernel = this.host.requireKernel(token.name, call);\n const documentId = untracked(this.documentId) ?? undefined;\n const capability = kernel.tryCapability(token, documentId);\n if (capability) return capability;\n if (kernel.scopeOf(token) === 'document') {\n throw new PluginError('not-ready', token.name, 'no document is open');\n }\n return kernel.capability(token, documentId);\n }\n\n /**\n * The capability's method `name`, looked up when it's called, so a method kept in a field\n * acts on the document current at that moment. The same function for the binding's lifetime.\n *\n * A read (a method named `get*`, `list*`, `is*`, `has*` or `can*`: `canUpdate()`,\n * `getZoomLevel()`) is state too: called in a template, a `computed()` or an `effect()`, it's\n * read again after each change of the kernel and of the document in scope, and wakes its\n * reader only when its answer changes. So a button it disables follows the selection, the\n * active document and its permissions. Other methods track nothing: an `effect()` that calls a\n * verb doesn't run again because the verb changed the document.\n *\n * Without a document a method refuses with `not-ready`: one that returns a promise (the token's\n * `promises`) returns the refusal as a rejected promise, so `.catch()` sees it; others throw.\n */\n method<Name extends keyof Capability>(name: Name): Capability[Name] {\n return this.late(String(name), (capability) => capability, name);\n }\n\n /**\n * The method `name` of the capability's namespace `namespace` (`custom.update()`), late-bound\n * the way {@link method} is. A service gives a namespace an object of its own\n * (`metadata.custom`), built from these, {@link select} and {@link stream}.\n */\n namespaceMethod<Key extends keyof Capability, Name extends keyof Capability[Key]>(\n namespace: Key,\n name: Name,\n ): Capability[Key][Name] {\n return this.late(\n `${String(namespace)}.${String(name)}`,\n (capability) => capability[namespace],\n name,\n );\n }\n\n /**\n * One of the capability's events, as an RxJS stream. A subscription follows the document:\n * when it changes (another tab, a document that opens or closes), it moves to the new\n * document's capability. Nothing is emitted while there is none.\n */\n stream<T>(pick: (capability: Capability) => EventHook<T>): Observable<T> {\n return new Observable<T>((subscriber) => {\n let current: Capability | null = null;\n let listening: AbortController | null = null;\n const follow = () => {\n const kernel = untracked(this.host.kernel);\n const next = kernel ? untracked(() => this.resolve(kernel)) : null;\n if (next === current) return;\n listening?.abort();\n listening = null;\n current = next;\n if (!next) return;\n listening = new AbortController();\n pick(next)((event) => subscriber.next(event), { signal: listening.signal });\n };\n const stop = this.host.subscribe(follow);\n follow();\n return () => {\n stop();\n listening?.abort();\n };\n });\n }\n\n private resolve(kernel: Kernel): Capability | null {\n return kernel.tryCapability(this.token(), this.documentId() ?? undefined);\n }\n\n /** `owner(capability)[name]`, looked up when called; a read tracks what its answer reads. */\n private late<Owner, Name extends keyof Owner>(\n label: string,\n owner: (capability: Capability) => Owner,\n name: Name,\n ): Owner[Name] {\n const call = `${label}()`;\n const run = (args: unknown[]): unknown => {\n let target: Owner;\n try {\n target = owner(this.require(call));\n } catch (error) {\n // Not ready: a method that returns a promise rejects, as the capability would.\n if (isPluginError(error, 'not-ready') && returnsPromise(this.token(), label)) {\n return Promise.reject(error);\n }\n throw error;\n }\n return (target[name] as unknown as (...args: unknown[]) => unknown).apply(target, args);\n };\n if (!isReadMember(String(name))) {\n return ((...args: unknown[]) => untracked(() => run(args))) as Owner[Name];\n }\n // A computed of its own for each call: whoever reads the check depends on its answer, not\n // on every change of the kernel. Outside a reactive context it's one plain call.\n return ((...args: unknown[]) =>\n computed(() => {\n this.documentId();\n this.host.revision();\n return run(args);\n })()) as Owner[Name];\n }\n}\n","/**\n * One service per plugin: `inject(EpdfSearch)` has the plugin's methods, every value of its\n * State table as a signal (`search.hitCount()`), its events as RxJS streams\n * (`search.completed$`), and, when the plugin has settings, `settings()`, `getSettings()`,\n * `updateSettings()`, `resetSettings()` and `settingsChanged$`. `pluginService()` builds all of that from what the\n * plugin declares already, so a plugin's service is a few lines; the package README's \"Adding a\n * plugin binding\" shows one.\n *\n * A service acts on the document of the injector that created it: under `[epdfDocumentScope]`\n * that document, else the active one. Its methods are looked up when they're called, so a\n * method kept in a field acts on the document current at that moment.\n */\nimport { computed, effect, inject, untracked, type Signal } from '@angular/core';\nimport type {\n CapabilityToken,\n EventHook,\n SettingsChangedEvent,\n SettingsOf,\n StateDeclaration,\n} from '@embedpdf/core';\nimport type { Observable } from 'rxjs';\nimport { CapabilityBinding, injectDocumentScope } from './capability';\nimport { noPluginError, noViewerError } from './errors';\nimport { EpdfKernelHost } from './kernel-host';\n\n/** The names of a capability's events: its `on…` members. */\nexport type EventName<Capability> = {\n [Key in keyof Capability]-?: Key extends `on${string}`\n ? Capability[Key] extends EventHook<infer _Payload>\n ? Key\n : never\n : never;\n}[keyof Capability];\n\n/** An event's stream on a service: `onCompleted` is `completed$`. */\nexport type StreamName<Event> = Event extends `on${infer Name}` ? `${Uncapitalize<Name>}$` : never;\n\ntype EventOf<Hook> = Hook extends EventHook<infer Event> ? Event : never;\n\n/** The settings members, for a capability that has the settings calls. */\ntype SettingsMembers<Capability> = [SettingsOf<Capability>] extends [never]\n ? unknown\n : {\n /** The plugin's settings, with or without a document. */\n readonly settings: Signal<SettingsOf<Capability>>;\n /** Fires once for each call that changed a setting. */\n readonly settingsChanged$: Observable<SettingsChangedEvent<SettingsOf<Capability>>>;\n } & Pick<Capability, ('getSettings' | 'updateSettings' | 'resetSettings') & keyof Capability>;\n\n/** What a plugin service built by `pluginService()` has, on top of the members its class adds. */\nexport type PluginServiceMembers<\n Capability,\n State extends object,\n Method extends keyof Capability,\n Event extends EventName<Capability>,\n> = { readonly [Key in Method]-?: Capability[Key] } & {\n readonly [Key in keyof State]-?: Signal<State[Key]>;\n} & {\n readonly [Key in Event as StreamName<Key>]: Observable<EventOf<Capability[Key]>>;\n} & SettingsMembers<Capability>;\n\n/**\n * The class `pluginService()` returns, which a plugin's service extends. It has a name so the\n * built declarations say `PluginServiceClass<SearchCapability, …>` and the app's compiler works\n * out each member from the plugin's own types, instead of spelling out every member's type,\n * which would name packages the app may not have installed.\n */\nexport type PluginServiceClass<\n Capability,\n State extends object,\n Method extends keyof Capability,\n Event extends EventName<Capability>,\n> = abstract new () => EpdfPluginService<Capability> &\n PluginServiceMembers<Capability, State, Method, Event>;\n\nexport interface PluginServiceSpec<\n Capability,\n State extends object,\n Method extends keyof Capability,\n Event extends EventName<Capability>,\n> {\n /** The service's class name, as errors show it: `'EpdfSearch'`. */\n readonly name: string;\n /**\n * The feature that registers the plugin, as errors show it: `'withSearch()'`. Left out for\n * the viewer's own services, which `provideEmbedPdf()` always has.\n */\n readonly feature?: string;\n readonly token: CapabilityToken<Capability>;\n /** The plugin's State table (`defineState`): each field becomes a signal of the same name. */\n readonly state?: StateDeclaration<Capability, State>;\n /**\n * For a plugin that loads its state on demand: the verb that loads it (its declaration's\n * `ensure`), called once a ready document's capability is in scope, for every document the\n * service comes to read. Taken from `state` when the spec has one.\n */\n readonly ensure?: (capability: Capability) => Promise<void>;\n /** The plugin's Methods table: each becomes a method of the same name. */\n readonly methods: readonly Method[];\n /** The plugin's events: `onCompleted` becomes the stream `completed$`. */\n readonly events?: readonly Event[];\n}\n\n/**\n * The base every plugin service extends. Its members are for the service's own class, which\n * adds what the generic part can't: a signal with arguments (`hitsOn(page)`), a namespace\n * (`custom.fields()`), a helper that needs the caller's injection context.\n */\nexport abstract class EpdfPluginService<Capability> {\n /** The plugin's capability for this service's document. */\n protected readonly binding: CapabilityBinding<Capability>;\n\n protected constructor(spec: {\n name: string;\n feature?: string;\n token: CapabilityToken<Capability>;\n }) {\n const host = inject(EpdfKernelHost, { optional: true });\n // A plugin's service names its feature, whether the viewer is missing or only the plugin.\n if (spec.feature && !host?.provides(spec.token)) throw noPluginError(spec.name, spec.feature);\n if (!host) throw noViewerError(`inject(${spec.name})`);\n this.binding = new CapabilityBinding(host, () => spec.token, injectDocumentScope());\n }\n}\n\n/**\n * The base class of a plugin's service, built from the plugin's declarations:\n *\n * @Injectable({ providedIn: 'root' })\n * export class EpdfSearch extends pluginService({\n * name: 'EpdfSearch',\n * feature: 'withSearch()',\n * token: SearchToken,\n * state: searchState,\n * methods: ['search', 'clear', 'goToHit'],\n * events: ['onCompleted'],\n * }) {}\n *\n * `providedIn: 'root'` is only the fallback that turns a missing viewer into EPDF-102: the\n * service's feature provides it next to the viewer, and `[epdfDocumentScope]` again.\n */\nexport function pluginService<\n Capability,\n State extends object = Record<never, never>,\n Method extends keyof Capability = never,\n Event extends EventName<Capability> = never,\n>(\n spec: PluginServiceSpec<Capability, State, Method, Event>,\n): PluginServiceClass<Capability, State, Method, Event> {\n abstract class PluginService extends EpdfPluginService<Capability> {\n constructor() {\n super(spec);\n const members = this as unknown as Record<string, unknown>;\n const binding = this.binding;\n\n if (spec.state) {\n const state = spec.state;\n // One read of the whole table, compared field by field, then one signal per field: a\n // template that reads `hitCount()` wakes only when the hit count changes.\n const whole = binding.select((capability) => state.read(capability), state.empty);\n for (const field of Object.keys(state.empty) as (keyof State & string)[]) {\n members[field] = computed(() => whole()[field]);\n }\n }\n\n const ensure = spec.ensure ?? spec.state?.ensure;\n if (ensure) {\n effect(() => {\n const capability = binding.capability();\n // The state says when the load fails (its status), so the rejection has nothing to add.\n if (capability) untracked(() => ensure(capability).catch(() => {}));\n });\n }\n\n for (const name of spec.methods) members[name as string] = binding.method(name);\n\n for (const event of spec.events ?? []) {\n const stream = `${event.charAt(2).toLowerCase()}${event.slice(3)}$`;\n members[stream] = binding.stream(\n (capability) => capability[event] as unknown as EventHook<unknown>,\n );\n }\n\n // Settings belong to the plugin as the app registered it, not to a document: they work\n // with no document open, and before the kernel exists.\n const host = binding.host;\n if (host.hasSettings(spec.token)) {\n const settings = host.settingsOf<object>(spec.token);\n members['settings'] = settings.current;\n // A read, like every `get*` method: a template or an effect that calls it follows it.\n members['getSettings'] = () => settings.current();\n members['updateSettings'] = settings.update;\n members['resetSettings'] = settings.reset;\n members['settingsChanged$'] = host.stream(\n (kernel) => kernel.settingsOf(spec.token).onSettingsChanged,\n );\n }\n }\n }\n return PluginService as unknown as PluginServiceClass<Capability, State, Method, Event>;\n}\n","/**\n * The viewer's own services, which `provideEmbedPdf()` always has:\n *\n * inject(EpdfViewer) the viewer's settings (`identity`, `scope`, `accent`, `page`) and status\n * inject(EpdfDocuments) open, close, unlock and download documents; every tab, as signals\n * inject(EpdfDocument) the document this part of the template talks to, as signals\n */\nimport { Injectable, type Signal } from '@angular/core';\nimport { DocumentsToken, documentState, documentsState } from '@embedpdf/core';\nimport type { DeepPartial, PageInfo, SettingsChangedEvent, ViewerSettings } from '@embedpdf/core';\nimport type { Observable } from 'rxjs';\nimport { injectKernelHost } from './capability';\nimport type { EpdfViewerStatus } from './config';\n// The services below extend a `PluginServiceClass`. Importing the type lets their built\n// declarations name it from this file; without it they import this entry point by its own\n// package name (`@embedpdf/angular/runtime`), which resolves only where the package can refer\n// to itself.\nimport { pluginService, type PluginServiceClass } from './service';\n\n/**\n * The viewer itself: its settings, and whether it started. The config given to\n * `provideEmbedPdf()` is read once; what may change while the app runs changes here:\n *\n * effect(() => viewer.updateSettings({ identity: auth.identity() }));\n *\n * Documents opened after a change of `identity` or `scope` use the new value; open ones keep\n * theirs.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfViewer {\n private readonly host = injectKernelHost('inject(EpdfViewer)');\n\n /** The viewer's settings: `identity`, `scope`, `accent` and `page`. */\n readonly settings: Signal<ViewerSettings> = this.host.viewerSettings;\n /** `'starting'`, `'ready'`, or `'error'` when the engine or a plugin failed to start. */\n readonly status: Signal<EpdfViewerStatus> = this.host.status;\n /** Why the viewer failed to start, when `status()` is `'error'`. */\n readonly error: Signal<unknown> = this.host.error;\n /** Fires once for each call that changed a setting. */\n readonly settingsChanged$: Observable<SettingsChangedEvent<ViewerSettings>> = this.host.stream(\n (kernel) => kernel.onSettingsChanged,\n );\n\n /** Merge `changes` into the viewer's settings: `page` merges, `identity` and `scope` replace. */\n updateSettings(changes: DeepPartial<ViewerSettings>): void {\n this.host.updateViewerSettings(changes);\n }\n\n /** Go back to the settings `provideEmbedPdf()` was given. */\n resetSettings(): void {\n this.host.resetViewerSettings();\n }\n}\n\n/**\n * The documents: open, close, unlock, retry and download them, and every tab with the active\n * one as signals (`documents()`, `activeId()`). Under `[epdfDocumentScope]` the calls that\n * leave out the document use that one: `download()` downloads the document in scope.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfDocuments extends pluginService({\n name: 'EpdfDocuments',\n token: DocumentsToken,\n state: documentsState,\n methods: [\n 'open',\n 'canOpenFiles',\n 'openAll',\n 'retry',\n 'rename',\n 'unlock',\n 'close',\n 'closeAll',\n 'setActive',\n 'getActiveId',\n 'getActive',\n 'list',\n 'get',\n 'has',\n 'getCount',\n 'getOrder',\n 'setOrder',\n 'move',\n 'swap',\n 'download',\n 'downloadLayer',\n 'canDownload',\n 'canPrint',\n 'listPages',\n 'getPage',\n 'getPageIndex',\n 'getRevision',\n ],\n events: [\n 'onOpened',\n 'onOpenFailed',\n 'onLocked',\n 'onClosed',\n 'onActiveChanged',\n 'onPagesChanged',\n 'onUnsavedChangesChanged',\n ],\n}) {}\n\nconst NO_PAGES: readonly PageInfo[] = Object.freeze([]);\n\n/**\n * The document this part of the template talks to: the one `[epdfDocumentScope]` names, else\n * the active one. Its fields are signals (`id()`, `name()`, `status()`, `pageCount()`,\n * `hasUnsavedChanges()`, `passwordProvided()`, `error()`), and `pages()` its pages. With no\n * document it reads as one still on its way: an empty `id` and `status() === 'loading'`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfDocument extends pluginService({\n name: 'EpdfDocument',\n token: DocumentsToken,\n state: documentState,\n methods: [],\n}) {\n /**\n * The document's pages, in order: each with its `ref`, `index`, `label`, size and rotation.\n * Needs no Stage. The same array until a page is added, removed, moved or rotated; empty\n * with no document.\n */\n readonly pages: Signal<readonly PageInfo[]> = this.binding.select(\n (documents) => documents.listPages(),\n NO_PAGES,\n Object.is,\n );\n}\n","/**\n * `provideEmbedPdf(config, ...features)`: the viewer as Angular providers, in Angular's own\n * style (`provideRouter(routes, withViewTransitions())`).\n *\n * providers: [provideEmbedPdf({ engine }, withStage(), withRender(), withSearch())]\n *\n * It works in a component's `providers` (that component and everything in its template share\n * one viewer, and the component can inject its services itself), in a route's `providers`, and\n * in the app config. Each injector that provides it gets its own viewer, created in the browser\n * and destroyed with the injector. `provideEmbedPdf({ kernel })` gives the injector a kernel\n * someone else made instead, which it neither starts nor destroys.\n */\nimport type { Provider, Type } from '@angular/core';\nimport type { EmbedPdfConfig, EmbedPdfFeature, EmbedPdfKernelConfig } from './config';\nimport { EpdfKernelHost } from './kernel-host';\nimport { EpdfDocument, EpdfDocuments, EpdfViewer } from './services';\nimport { EPDF_SETUP, type EmbedPdfSetup } from './tokens';\n\nconst scopedServices: Type<unknown>[] = [EpdfDocuments, EpdfDocument];\n\n/**\n * Every service that acts on one document: the viewer's own, and each feature's, added when a\n * `provideEmbedPdf()` call names the feature. `[epdfDocumentScope]` and a Stage list this array\n * in their `providers`, so a service injected under them acts on their document.\n *\n * It is one array that grows, not a copy: Angular reads a directive's providers when its\n * template is first created, which is after the `provideEmbedPdf()` calls in decorators and the\n * app config ran. A service whose feature is first named later (a lazily loaded route's\n * providers) is still provided by its viewer, and acts on the active document there.\n */\nexport const EPDF_SCOPED_SERVICES: Provider[] = scopedServices;\n\n/** The viewer, with the plugins its features register; or the viewer of a kernel given. */\nexport function provideEmbedPdf(\n config: EmbedPdfConfig | EmbedPdfKernelConfig,\n ...features: EmbedPdfFeature[]\n): Provider[] {\n for (const feature of features) {\n for (const service of feature.services ?? []) {\n if (!scopedServices.includes(service)) scopedServices.push(service);\n }\n }\n const setup: EmbedPdfSetup = { config, features };\n return [\n { provide: EPDF_SETUP, useValue: setup },\n EpdfKernelHost,\n EpdfViewer,\n EpdfDocuments,\n EpdfDocument,\n ...features.flatMap((feature) => [...(feature.services ?? []), ...(feature.providers ?? [])]),\n ];\n}\n","/**\n * Which document a part of the template talks to, and whether it has one:\n *\n * <div [epdfDocumentScope]=\"id\"> everything inside talks to that document\n * <epdf-stage *epdfDocumentGate=\"let document; fallback: opening; locked: locked; error: failed\">\n *\n * The gate is a structural directive on purpose: a template really defers creating what's\n * inside, which a conditional `<ng-content>` can't (Angular creates projected content whether\n * or not it's shown). Document UI (the Stage, a page counter) goes behind it; workspace UI (a\n * toolbar frame, an open button) stays outside and renders at once.\n */\nimport {\n ChangeDetectorRef,\n Directive,\n effect,\n forwardRef,\n inject,\n input,\n TemplateRef,\n untracked,\n ViewContainerRef,\n type EmbeddedViewRef,\n} from '@angular/core';\nimport { documentState, DocumentsToken } from '@embedpdf/core';\nimport type { DocumentInfo, FailedDocumentInfo, LockedDocumentInfo } from '@embedpdf/core';\nimport { CapabilityBinding, injectDocumentScope, injectKernelHost } from './capability';\nimport { EPDF_SCOPED_SERVICES } from './provide';\nimport { EPDF_DOCUMENT_SCOPE, type EpdfDocumentScopeRef } from './tokens';\n\n/**\n * Binds everything inside the element to one document: services injected there, the Stage\n * and its layers act on it instead of the active document.\n */\n@Directive({\n selector: '[epdfDocumentScope]',\n providers: [\n { provide: EPDF_DOCUMENT_SCOPE, useExisting: forwardRef(() => EpdfDocumentScope) },\n // A service injected inside gets an instance of its own here, bound to this document.\n EPDF_SCOPED_SERVICES,\n ],\n})\nexport class EpdfDocumentScope implements EpdfDocumentScopeRef {\n /** The document's id. */\n readonly id = input.required<string>({ alias: 'epdfDocumentScope' });\n}\n\n/** What the gate's content gets: `let document` is the ready document. */\nexport interface EpdfDocumentGateContext {\n $implicit: DocumentInfo;\n}\n\n/** What the `locked` template gets: `let-document` is the document waiting for its password. */\nexport interface EpdfLockedDocumentContext {\n $implicit: LockedDocumentInfo;\n}\n\n/** What the `error` template gets: `let-document` is the document that failed, with `error`. */\nexport interface EpdfFailedDocumentContext {\n $implicit: FailedDocumentInfo;\n}\n\n/**\n * Renders its content only while this part of the template has a ready document, with that\n * document as `let document`. Otherwise it renders `locked` for a document waiting for its\n * password, `error` for one that couldn't be opened, and `fallback` for everything else (none\n * open yet, still opening), each with the document as `let-document`. Without `locked` or\n * `error` those states show `fallback` too.\n *\n * <epdf-stage *epdfDocumentGate=\"let document; fallback: opening; locked: locked; error: failed\">\n * <ng-template #opening>Opening…</ng-template>\n * <ng-template #locked let-document><app-password-form [document]=\"document\" /></ng-template>\n *\n * The content stays mounted when another ready document becomes the active one; only its\n * `document` changes.\n */\n@Directive({ selector: '[epdfDocumentGate]' })\nexport class EpdfDocumentGate {\n /** Shown while there is no ready document: none is open, or it's still opening. */\n readonly fallback = input<TemplateRef<unknown> | null | undefined>(null, {\n alias: 'epdfDocumentGateFallback',\n });\n /** Shown while the document waits for its password; `fallback` without it. */\n readonly locked = input<TemplateRef<EpdfLockedDocumentContext> | null | undefined>(null, {\n alias: 'epdfDocumentGateLocked',\n });\n /** Shown when the document couldn't be opened; `fallback` without it. */\n readonly error = input<TemplateRef<EpdfFailedDocumentContext> | null | undefined>(null, {\n alias: 'epdfDocumentGateError',\n });\n\n static ngTemplateContextGuard(\n _gate: EpdfDocumentGate,\n context: unknown,\n ): context is EpdfDocumentGateContext {\n return true;\n }\n\n constructor() {\n const document = new CapabilityBinding(\n injectKernelHost('*epdfDocumentGate'),\n () => DocumentsToken,\n injectDocumentScope(),\n ).select(documentState.read, documentState.empty);\n const content = inject<TemplateRef<EpdfDocumentGateContext>>(TemplateRef);\n const container = inject(ViewContainerRef);\n const changes = inject(ChangeDetectorRef);\n let shown: {\n template: TemplateRef<unknown>;\n view: EmbeddedViewRef<{ $implicit: DocumentInfo }>;\n } | null = null;\n\n effect(() => {\n const current = document();\n const template = this.templateFor(current, content);\n untracked(() => {\n if (shown && shown.template === template) {\n // The same template for another document (a tab switch): keep the view, pass it on.\n shown.view.context.$implicit = current;\n shown.view.markForCheck();\n return;\n }\n container.clear();\n shown = template\n ? { template, view: container.createEmbeddedView(template, { $implicit: current }) }\n : null;\n changes.markForCheck();\n });\n });\n }\n\n private templateFor(\n document: DocumentInfo,\n content: TemplateRef<EpdfDocumentGateContext>,\n ): TemplateRef<{ $implicit: DocumentInfo }> | null {\n if (document.status === 'ready') return content;\n const locked = this.locked();\n if (document.status === 'locked' && locked)\n return locked as TemplateRef<{ $implicit: DocumentInfo }>;\n const failed = this.error();\n if (document.status === 'error' && failed)\n return failed as TemplateRef<{ $implicit: DocumentInfo }>;\n return (this.fallback() as TemplateRef<{ $implicit: DocumentInfo }> | null | undefined) ?? null;\n }\n}\n","/**\n * The page context: what a layer drawn on a page knows about that page. A layer reads only\n * this, never the Stage, so the same layer works on a Stage's page and on a standalone page\n * view. Inside `<ng-template epdfPage>`, `let-page` gives it to the template and `injectPage()`\n * to a component.\n *\n * One context per page on screen, for as long as the page is shown: its identity never\n * changes, and what moves (`pageIndex`, `frame`, `transform`) are signals inside it. The\n * template outlet then keeps every layer while the camera moves, and a camera frame updates\n * only the bindings that read the transform. Never build a new context per frame.\n *\n * The coordinate math is `PageTransform` from `@embedpdf/core-geometry`, and the client-space\n * conversions are `pageClientSpace` from `@embedpdf/web`, both shared by every framework.\n */\nimport { inject, InjectionToken, type Signal } from '@angular/core';\nimport type { PageRef } from '@embedpdf/core';\nimport type { PageFrame, PageTransform, Point, Rect } from '@embedpdf/core-geometry';\nimport type { PageViewDemand } from '@embedpdf/plugin-render/contract';\nimport { pageClientSpace } from '@embedpdf/web';\nimport { outsidePageError } from './errors';\n\nexport interface EpdfPageContext {\n readonly documentId: string;\n /**\n * The page's address, the same for as long as the page is shown: use it for keys and calls.\n * An `<epdf-page-view>` whose `[page]` changes shows another page in the same context; its\n * `ref` and `documentId` are read through signals there, so a `computed()` or an `effect()`\n * that reads them follows.\n */\n readonly ref: PageRef;\n /** The page's place in the document, from 0. It moves when pages are reordered. */\n readonly pageIndex: Signal<number>;\n /** The bands reserved around the page for labels and buttons, in screen pixels per side. */\n readonly frame: Signal<PageFrame>;\n /**\n * Between PDF points, view pixels and device pixels on this page: `pageToViewRect` places\n * something on the page, `renderScale` and `deviceWidth` size a picture of it. Changes with\n * every camera frame.\n */\n readonly transform: Signal<PageTransform>;\n /**\n * Which view shows the page (a Stage's lens id). Per-view work, such as which tiles to draw,\n * is kept per view, so a thumbnail strip never disturbs the main view.\n */\n readonly view: string;\n /** A point on the screen (client pixels) to a point on the page: the one hit test. */\n toPagePoint(clientX: number, clientY: number): Point;\n /** A point on the page to client pixels: the exact inverse of `toPagePoint`. */\n toClientPoint(point: Point): Point;\n /** A box on the page to the client-pixel box around it. */\n toClientRect(rect: Rect): Rect;\n /**\n * How much of the page the view wants drawn, read when asked: a Stage gives the part on\n * screen (an empty rect when the page left the screen); a standalone page view gives none,\n * which means the whole page.\n */\n readonly getViewDemand?: () => PageViewDemand;\n}\n\nexport const EPDF_PAGE = new InjectionToken<EpdfPageContext>('EPDF_PAGE');\n\n/** The page this component is drawn on; EPDF-103, naming `what`, outside a page. */\nexport function injectPage(what = 'This component'): EpdfPageContext {\n const page = inject(EPDF_PAGE, { optional: true });\n if (!page) throw outsidePageError(what);\n return page;\n}\n\n/**\n * A page context from its parts. `documentId` and `ref` are functions because a component's\n * inputs aren't set yet when it's constructed; both stay the same for the page's lifetime.\n */\nexport function createPageContext(parts: {\n documentId: () => string;\n ref: () => PageRef;\n view: () => string;\n pageIndex: Signal<number>;\n frame: Signal<PageFrame>;\n transform: Signal<PageTransform>;\n /** The page's box on screen: the turned content box's bounding box. */\n getRect: () => DOMRect;\n getViewDemand?: () => PageViewDemand;\n}): EpdfPageContext {\n const { transform, getRect } = parts;\n return {\n get documentId() {\n return parts.documentId();\n },\n get ref() {\n return parts.ref();\n },\n get view() {\n return parts.view();\n },\n pageIndex: parts.pageIndex,\n frame: parts.frame,\n transform,\n ...(parts.getViewDemand ? { getViewDemand: parts.getViewDemand } : {}),\n // Client pixels to pixels in the page's box, then the transform undoes the turn and the scale,\n // against the transform the signal holds when a conversion runs.\n ...pageClientSpace(transform, getRect),\n };\n}\n","/**\n * The Angular side of `@embedpdf/web`'s page layers: a layer says, for as long as it's there,\n * which part of its page it paints, and the render layer reads which parts are painted, to leave\n * them out of the page's picture.\n */\nimport {\n afterNextRender,\n effect,\n inject,\n Injector,\n signal,\n untracked,\n type Signal,\n} from '@angular/core';\nimport { pageLayersOf, type PagePart, type PaintedParts } from '@embedpdf/web';\n\n/**\n * Say, for as long as this component is there, that it paints `part` of its page (`pageRef()`,\n * the page context's `ref`; `null` while it paints nothing). Call it in an injection context.\n */\nexport function paintsPagePart(pageRef: () => object | null, part: PagePart): void {\n effect((onCleanup) => {\n const ref = pageRef();\n if (ref) onCleanup(untracked(() => pageLayersOf(ref).paint(part)));\n });\n}\n\n/**\n * Which parts of the page (`pageRef()`, the page context's `ref`) the layers on it paint: `null`\n * until the first render is done, when every layer made with this one has said what it paints,\n * so the page's picture is never asked for with a part another layer is about to take. Call it\n * in an injection context.\n */\nexport function injectPaintedParts(pageRef: () => object): Signal<PaintedParts | null> {\n const painted = signal<PaintedParts | null>(null);\n const injector = inject(Injector);\n afterNextRender(() => {\n effect(\n (onCleanup) => {\n const layers = pageLayersOf(pageRef());\n untracked(() => painted.set(layers.painted()));\n onCleanup(layers.subscribe(() => painted.set(layers.painted())));\n },\n { injector },\n );\n });\n return painted.asReadonly();\n}\n","/**\n * Scene shapes as SVG elements: `@embedpdf/web`'s element descriptions (`svgShapesOf`), one\n * element each, a clipping `svg` with its children. The annotation and form layers draw their\n * scenes through `<svg:g [epdfSvgShapes]>` inside an `<svg>`.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n} from '@angular/core';\nimport { createFontMounts, type SvgShape } from '@embedpdf/web';\n\n/**\n * An SVG element's attributes from a record of SVG names (`stroke-width`), as `@embedpdf/web`\n * describes a scene node (templates can't spread). Set again when the record changes; an\n * attribute that left the record is removed.\n */\n@Directive({ selector: '[epdfSvgAttributes]' })\nexport class EpdfSvgAttributes {\n readonly attributes = input.required<Readonly<Record<string, string | number>>>({\n alias: 'epdfSvgAttributes',\n });\n\n constructor() {\n const element = inject<ElementRef<SVGElement>>(ElementRef).nativeElement;\n let shown: Readonly<Record<string, string | number>> = {};\n effect(() => {\n const next = this.attributes();\n for (const name of Object.keys(shown)) {\n if (!(name in next)) element.removeAttribute(name);\n }\n for (const [name, value] of Object.entries(next)) {\n if (shown[name] !== value) element.setAttribute(name, String(value));\n }\n shown = next;\n });\n }\n}\n\n/** The shapes, in drawing order, in the `<svg:g>` it's on, and the faces their text draws in. */\n@Component({\n selector: 'g[epdfSvgShapes]',\n imports: [EpdfSvgAttributes],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @for (shape of shapes(); track $index) {\n @switch (shape.tag) {\n @case ('rect') {\n <svg:rect\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:rect>\n }\n @case ('ellipse') {\n <svg:ellipse\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:ellipse>\n }\n @case ('line') {\n <svg:line\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:line>\n }\n @case ('path') {\n <svg:path\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:path>\n }\n @case ('polygon') {\n <svg:polygon\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:polygon>\n }\n @case ('polyline') {\n <svg:polyline\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n ></svg:polyline>\n }\n @case ('text') {\n <svg:text\n [epdfSvgAttributes]=\"shape.attributes\"\n [style.mix-blend-mode]=\"shape.blend ?? null\"\n [textContent]=\"shape.text ?? ''\"\n ></svg:text>\n }\n @case ('svg') {\n <svg:svg [epdfSvgAttributes]=\"shape.attributes\">\n <svg:g [epdfSvgShapes]=\"shape.children ?? []\"></svg:g>\n </svg:svg>\n }\n }\n }\n `,\n})\nexport class EpdfSvgShapes {\n readonly shapes = input.required<readonly SvgShape[]>({ alias: 'epdfSvgShapes' });\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n // The faces of this level's text, while it shows: a clipping `svg` mounts its children's.\n const mounts = createFontMounts();\n inject(DestroyRef).onDestroy(() => mounts.release());\n effect(() =>\n mounts.mount(this.shapes().flatMap((shape) => (shape.program ? [shape.program] : []))),\n );\n }\n}\n","/**\n * Development-time guardrails. Each warning fires once (by key), says what is wrong and what to\n * do instead, and stays quiet in production builds (Angular's `isDevMode()`).\n */\nimport { isDevMode } from '@angular/core';\n\nconst warned = new Set<string>();\n\n/** Warn once per key. Quiet in production. */\nexport function devWarn(key: string, message: string): void {\n if (!isDevMode() || warned.has(key)) return;\n warned.add(key);\n console.warn(`[embedpdf] ${message}`);\n}\n\n/** For tests: forget every warning, so one can fire again. */\nexport function resetDevWarnings(): void {\n warned.clear();\n}\n","/**\n * `epdfTheme()`: a theme written with setting names, as the CSS variables for the element\n * around your viewer. The variables and their lookup are framework-free (`@embedpdf/web`); this\n * types the result for Angular's `[style]` binding, which sets custom properties as they are.\n */\nimport { epdfThemeVariables, type EpdfTheme } from '@embedpdf/web';\n\nexport type { EpdfTheme } from '@embedpdf/web';\n\n/**\n * The CSS variables of a theme: `<div [style]=\"theme()\">` with\n * `theme = computed(() => epdfTheme({ accent: this.accent() }))`. Everything inside follows\n * them, and a CSS variable set in a stylesheet still wins over a setting.\n */\nexport function epdfTheme(theme: EpdfTheme): Record<string, string> {\n return epdfThemeVariables(theme) as Record<string, string>;\n}\n","/**\n * @embedpdf/angular/runtime: the viewer and what every feature builds on.\n *\n * provideEmbedPdf(config, ...features) the viewer, as providers\n * inject(EpdfViewer) its settings and status\n * inject(EpdfDocuments), EpdfDocument the documents, as methods, signals and streams\n * [epdfDocumentScope], *epdfDocumentGate which document a part of the template talks to\n * pluginService(), EpdfPluginService how a plugin's service is built\n * EPDF_PAGE, injectPage() the page a layer draws on\n * paintsPagePart(), injectPaintedParts() which parts of a page its layers paint\n * <svg:g [epdfSvgShapes]> a scene's shapes as SVG elements\n */\n\n// The core's types and helpers, so app code has one import for the viewer.\nexport * from '@embedpdf/core';\n// What a page with a viewer needs from the browser: handing bytes to the user as a download,\n// and a font the engine draws with, for text you draw yourself.\nexport { mountWebFont, saveFile } from '@embedpdf/web';\nexport * from './errors';\nexport * from './config';\nexport * from './tokens';\nexport { EpdfKernelHost } from './kernel-host';\nexport type { PluginSettingsBinding } from './kernel-host';\nexport * from './capability';\nexport * from './service';\nexport * from './services';\nexport { provideEmbedPdf, EPDF_SCOPED_SERVICES } from './provide';\nexport * from './scope';\nexport * from './page-context';\nexport * from './page-layers';\nexport * from './svg-shapes';\nexport * from './dev';\nexport * from './theme';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;;;;;AAAA;;;;;;;;AAQG;AACH,MAAM,WAAW,GAAG,uDAAuD;AAE3E;AACM,MAAO,SAAU,SAAQ,KAAK,CAAA;AAIvB,IAAA,IAAA;IAHO,IAAI,GAAG,WAAW;IAEpC,WAAA,CACW,IAAsB,EAC/B,OAAe,EAAA;AAEf,QAAA,KAAK,CAAC,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,OAAO,CAAA,KAAA,EAAQ,WAAW,CAAA,CAAA,EAAI,IAAI,CAAC,WAAW,EAAE,CAAA,CAAE,CAAC;QAH5D,IAAA,CAAA,IAAI,GAAJ,IAAI;IAIf;AACD;AAED;AACO,MAAM,aAAa,GAAG,CAAC,IAAY,KACxC,IAAI,SAAS,CACX,UAAU,EACV,GAAG,IAAI,CAAA,6FAAA,CAA+F;AAG1G;MACa,aAAa,GAAG,CAAC,OAAe,EAAE,OAAe,KAC5D,IAAI,SAAS,CACX,UAAU,EACV,UAAU,OAAO,CAAA,uCAAA,EAA0C,OAAO,CAAA,sBAAA,CAAwB;AACxF,IAAA,CAAA,qDAAA,CAAuD;AAG7D;AACO,MAAM,gBAAgB,GAAG,CAAC,IAAY,KAC3C,IAAI,SAAS,CACX,UAAU,EACV,GAAG,IAAI,CAAA,0EAAA,CAA4E;AAGvF;AACO,MAAM,iBAAiB,GAAG,CAAC,IAAY,KAC5C,IAAI,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAA,gDAAA,CAAkD;AAErF;AACO,MAAM,aAAa,GAAG,CAAC,IAAY,KACxC,IAAI,SAAS,CACX,UAAU,EACV,CAAA,EAAG,IAAI,CAAA,4EAAA,CAA8E;AACnF,IAAA,CAAA,uDAAA,CAAyD;;ACtD/D;;;AAGG;MAYU,mBAAmB,GAAG,IAAI,cAAc,CAAuB,qBAAqB;MAQpF,UAAU,GAAG,IAAI,cAAc,CAAgB,YAAY;;ACvBxE;;;;;;;;;AASG;AAKH;MACa,mBAAmB,CAAA;AACb,IAAA,OAAO,GAAG,MAAM,CAAwC,EAAE,mDAAC;;AAGnE,IAAA,OAAO;AAEhB,IAAA,WAAA,CAAY,WAAmC,EAAA;AAC7C,QAAA,MAAM,UAAU,GAAG,aAAa,CAC9B,WAAW,CAAC,QAAQ,EACpB,WAAW,CAAC,UAAU,EACtB,WAAW,CAAC,KAAK,CAClB;QACD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,MACtB,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CACnB,CAAC,QAAQ,EAAE,MAAM,KACf,MAAM,KAAK,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,EACtF,UAAU,CACX,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CACF;IACH;AAEA,IAAA,MAAM,CAAC,MAAsB,EAAA;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC;IACxD;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;IACzD;;AAGA,IAAA,OAAO,CAAC,KAA8E,EAAA;QACpF,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YACnC,IAAI,MAAM,KAAK,OAAO;gBAAE,KAAK,CAAC,aAAa,EAAE;;AACxC,gBAAA,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;QACnC;AACA,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IACtB;AACD;;ACpDD;;;;;;;;;;;;;AAaG;AA2CH;;;;AAIG;AACH,MAAM,wBAAwB,GAAG,CAAC,MAA6C,KAC7E,gBAAgB,CAAC,QAAQ,IAAI,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;AAEpD;;;;AAIG;AACH,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,KAA+B,KACrE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,UAAU,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI;AAE9E;AACA,SAAS,gBAAgB,CACvB,MAAc,EACd,KAA+B,EAAA;AAE/B,IAAA,IAAI;AACF,QAAA,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAA8B;IAC9D;AAAE,IAAA,MAAM;;AAEN,QAAA,OAAO,IAAI;IACb;AACF;AAEA;AACA,MAAM,cAAc,GAAG,CAAC,MAAoB,KAC1C,MAAM,KAAK,SAAS,GAAG,OAAO,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,GAAG,UAAU;AAS7E,MAAM,aAAa,GAAG,CAAI,KAAqB,KAC7C,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU;MAG7C,cAAc,CAAA;AACR,IAAA,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;AAC1B,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;;IAEnC,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;;IAExC,KAAK,GACpB,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI;;IAExD,OAAO,GAAyB,IAAI,CAAC;AAC5C,UAAE;AACF,UAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC;AAE5C,IAAA,WAAW,GAAG,MAAM,CAAgB,IAAI,uDAAC;AACzC,IAAA,aAAa,GAAG,MAAM,CAAC,CAAC,yDAAC;AACzB,IAAA,WAAW,GAAG,MAAM,CAAmB,UAAU,uDAAC;AAClD,IAAA,UAAU,GAAG,MAAM,CAAU,IAAI,sDAAC;AAClC,IAAA,SAAS,GAAG,IAAI,GAAG,EAAc;IACjC,yBAAyB,GAAG,IAAI,mBAAmB,CAAiB;AACnF,QAAA,QAAQ,EAAE,eAAe;QACzB,UAAU,EAAE,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACvD,QAAA,KAAK,EAAE,qBAAqB;AAC7B,KAAA,CAAC;AACe,IAAA,cAAc,GAAG,IAAI,GAAG,EAGtC;AACc,IAAA,yBAAyB,GAAG,IAAI,GAAG,EAA0C;IACtF,MAAM,GAAkB,IAAI;IAC5B,UAAU,GAAG,KAAK;IAClB,aAAa,GAAwB,IAAI;IACzC,SAAS,GAAG,KAAK;AAEzB;;;AAGG;AACM,IAAA,MAAM,GAA0B,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;;AAE7D,IAAA,QAAQ,GAAmB,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;;IAE1D,MAAM,GAA6B,IAAI,CAAC;UAC7C,IAAI,CAAC,IAAI,CACP,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAC3C,MAAM,UAAU;AAEpB,UAAE,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;;AAExB,IAAA,KAAK,GAAoB,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE;;IAErD,cAAc,GAA2B,IAAI,CAAC,IAAI,CACzD,CAAC,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE,EAChC,MAAM,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,EAC9C,YAAY,CACb;AAED,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AAClD,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK;;QAE7B,IAAI,QAAQ,IAAI,MAAM;AAAE,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE;AACnB,QAAA,IAAI,EAAE,QAAQ,IAAI,MAAM,CAAC;AAAE,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;;QAE7C,cAAc,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC/C;AAEA;;;;AAIG;IACH,IAAI,CACF,MAA6B,EAC7B,KAAc,EACd,KAAA,GAAwC,MAAM,CAAC,EAAE,EAAA;QAEjD,OAAO,QAAQ,CACb,MAAK;YACH,IAAI,CAAC,aAAa,EAAE;AACpB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,YAAA,OAAO,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE;AAC1C,QAAA,CAAC,EACD,EAAE,KAAK,EAAE,CACV;IACH;;AAGA,IAAA,SAAS,CAAC,QAAoB,EAAA;AAC5B,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC5B,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC9C;AAEA;;;AAGG;AACH,IAAA,MAAM,CAAI,IAAsC,EAAA;AAC9C,QAAA,OAAO,IAAI,UAAU,CAAI,CAAC,UAAU,KAAI;YACtC,IAAI,SAAS,GAA2B,IAAI;YAC5C,MAAM,MAAM,GAAG,MAAK;gBAClB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,MAAM,IAAI,SAAS;oBAAE;AAC1B,gBAAA,SAAS,GAAG,IAAI,eAAe,EAAE;gBACjC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AAC/E,YAAA,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AACnC,YAAA,MAAM,EAAE;AACR,YAAA,OAAO,MAAK;AACV,gBAAA,IAAI,EAAE;gBACN,SAAS,EAAE,KAAK,EAAE;AACpB,YAAA,CAAC;AACH,QAAA,CAAC,CAAC;IACJ;;AAGA,IAAA,QAAQ,CAAC,KAA+B,EAAA;QACtC,IAAI,KAAK,KAAK,cAAc;AAAE,YAAA,OAAO,IAAI;QACzC,OAAO,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI;IACxF;;AAGA,IAAA,WAAW,CAAC,KAA+B,EAAA;QACzC,OAAO,IAAI,CAAC;cACR,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK;AAC1C,cAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC9C;AAEA;;;AAGG;IACH,aAAa,CAAC,UAAkB,EAAE,IAAY,EAAA;AAC5C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,QAAA,IAAI,MAAM;AAAE,YAAA,OAAO,MAAM;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,MAAM,aAAa,CAAC,IAAI,CAAC;QAC5C,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,UAAU,EAAE,8BAA8B,CAAC;IAChF;AAEA,IAAA,oBAAoB,CAAC,MAAmC,EAAA;AACtD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,QAAA,IAAI,MAAM;AAAE,YAAA,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;;AACpC,YAAA,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,MAAM,CAAC;IACpD;IAEA,mBAAmB,GAAA;AACjB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,QAAA,IAAI,MAAM;YAAE,MAAM,CAAC,aAAa,EAAE;;AAC7B,YAAA,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE;IAC7C;AAEA;;;AAGG;AACH,IAAA,UAAU,CAAmB,KAA+B,EAAA;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5C,QAAA,IAAI,KAAK;AAAE,YAAA,OAAO,KAAiC;AACnD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC;cACjB,IAAI,CAAC,eAAe,CAAI,IAAI,CAAC,KAAK,EAAE,KAAK;AAC3C,cAAE,IAAI,CAAC,oBAAoB,CAAI,KAAK,CAAC;QACvC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,OAAwC,CAAC;AACxE,QAAA,OAAO,OAAO;IAChB;;AAGQ,IAAA,oBAAoB,CAC1B,KAA+B,EAAA;QAE/B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACpC,QAAA,MAAM,WAAW,GAAG,MAAM,EAAE,QAA8C;AAC1E,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE;YAC3B,MAAM,IAAI,WAAW,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,6BAA6B,CAAC;QACjF;AAEA,QAAA,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAI,WAAW,CAAC;QACtD,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAqC,CAAC;AACjF,QAAA,MAAM,KAAK,GAAG,CAAC,MAAc,KAAK,MAAM,CAAC,UAAU,CAAC,KAAK,CAA8B;QACvF,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,IAAI,CAChB,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EACvC,MAAM,MAAM,CAAC,OAAO,EAAE,EACtB,YAAY,CACb;AACD,YAAA,MAAM,EAAE,CAAC,MAAM,KAAI;AACjB,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,gBAAA,IAAI,MAAM;oBAAE,KAAK,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC;;AAC3C,oBAAA,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5B,CAAC;YACD,KAAK,EAAE,MAAK;AACV,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,gBAAA,IAAI,MAAM;AAAE,oBAAA,KAAK,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE;;oBACpC,MAAM,CAAC,KAAK,EAAE;YACrB,CAAC;SACF;IACH;;IAGQ,eAAe,CACrB,MAAc,EACd,KAA+B,EAAA;QAE/B,MAAM,KAAK,GAAG,gBAAgB,CAAI,MAAM,EAAE,KAAK,CAAC;AAChD,QAAA,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,WAAW,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,6BAA6B,CAAC;QAC3F,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;QACzC,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC;YAClD,MAAM,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;AAChD,YAAA,KAAK,EAAE,MAAM,KAAK,CAAC,aAAa,EAAE;SACnC;IACH;AAEQ,IAAA,SAAS,CAAC,KAA+B,EAAA;AAC/C,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI;IACtE;;;AAKQ,IAAA,KAAK,CAAC,MAAc,EAAA;AAC1B,QAAA,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AAC3D,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE;IAChB;AAEQ,IAAA,KAAK,CAAC,MAAsB,EAAA;AAClC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM;AAC5B,QAAA,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,UAAU;AAC1C,QAAA,IAAI,IAA8B;AAClC,QAAA,IAAI;YACF,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,MAAM;QAClC;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAChB;QACF;AACA,QAAA,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE;AACvB,YAAA,IAAI,CAAC,IAAI,CACP,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAC9C,CAAC,KAAc,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CACrC;QACH;aAAO;YACL,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;QAClC;IACF;;AAGQ,IAAA,MAAM,CAAC,MAAsB,EAAE,MAAc,EAAE,KAAc,EAAA;AACnE,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,KAAK;AAAE,gBAAA,KAAK,MAAM,CAAC,OAAO,EAAE;YAChC;QACF;;QAEA,IAAI,aAAa,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,MAAM,EAAE;AAC1C,QAAA,IAAI,MAAc;AAClB,QAAA,IAAI;YACF,MAAM,GAAG,YAAY,CAAC;gBACpB,MAAM;AACN,gBAAA,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;AAC1B,gBAAA,QAAQ,EAAE,wBAAwB,CAAC,MAAM,CAAC;gBAC1C,KAAK,EAAE,YAAY,EAAE;AACtB,aAAA,CAAC;QACJ;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK;AAAE,gBAAA,KAAK,MAAM,CAAC,OAAO,EAAE;AAChC,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAChB;QACF;AACA,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,UAAU,GAAG,KAAK;AACvB,QAAA,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9C,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,yBAAyB,EAAE;AAC7D,YAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAiC,CAAC,CAAC;QAC7E;AACA,QAAA,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;AAC3D,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE;AACd,QAAA,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CACjB,MAAK;YACH,IAAI,IAAI,CAAC,SAAS;gBAAE;AACpB,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;;YAE7B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC;AACzD,QAAA,CAAC,EACD,CAAC,KAAc,KAAI;YACjB,IAAI,CAAC,IAAI,CAAC,SAAS;AAAE,gBAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACvC,QAAA,CAAC,CACF;IACH;IAEQ,OAAO,GAAA;AACb,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,GAAG,CAAC,CAAC;QACrD,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;AAAE,YAAA,QAAQ,EAAE;IACxD;AAEQ,IAAA,IAAI,CAAC,KAAc,EAAA;AACzB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;AAC1B,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;AAC7B,QAAA,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC;IAC/D;IAEQ,gBAAgB,GAAA;QACtB,IAAI,IAAI,CAAC,SAAS;YAAE;QACpB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;YACzC,IAAI,OAAO,CAAC,KAAK;gBAAE,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC;QACxE;IACF;IAEQ,OAAO,GAAA;QACb,IAAI,IAAI,CAAC,SAAS;YAAE;AACpB,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,CAAC,aAAa,IAAI;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;;QAEtB,IAAI,IAAI,CAAC,KAAK;YAAE;AAChB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AACjC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;AAC1B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;;QAE7B,IAAI,MAAM,EAAE;YACV,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAK;gBAC9B,IAAI,KAAK,IAAI,MAAM;AAAE,oBAAA,KAAK,MAAM,CAAC,OAAO,EAAE;AAC5C,YAAA,CAAC,CAAC;QACJ;IACF;uGAlUW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAd,cAAc,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B;;;ACnGD;;;;;;;;AAQG;AAeH;AACM,SAAU,gBAAgB,CAAC,IAAY,EAAA;AAC3C,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACvD,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,MAAM,aAAa,CAAC,IAAI,CAAC;AACpC,IAAA,OAAO,IAAI;AACb;AAEA,MAAM,aAAa,GAA0B,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE;AAEtE;;;AAGG;SACa,mBAAmB,GAAA;AACjC,IAAA,OAAO,MAAM,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,aAAa;AAC7E;AAEA;;;;AAIG;AACG,SAAU,gBAAgB,CAC9B,KAAkC,EAAA;IAElC,MAAM,OAAO,GAAG,IAAI,iBAAiB,CACnC,gBAAgB,CAAC,CAAA,iBAAA,EAAoB,KAAK,CAAC,IAAI,GAAG,CAAC,EACnD,MAAM,KAAK,EACX,mBAAmB,EAAE,CACtB;IACD,OAAO,OAAO,CAAC,UAAU;AAC3B;AAEA;MACa,iBAAiB,CAAA;AASjB,IAAA,IAAA;AACQ,IAAA,KAAA;AACA,IAAA,UAAA;;AATV,IAAA,UAAU;AAEnB;;;AAGG;AACH,IAAA,WAAA,CACW,IAAoB,EACZ,KAAwC,EACxC,UAA+B,EAAA;QAFvC,IAAA,CAAA,IAAI,GAAJ,IAAI;QACI,IAAA,CAAA,KAAK,GAAL,KAAK;QACL,IAAA,CAAA,UAAU,GAAV,UAAU;QAE3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CACzB,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAChC,MAAM,IAAI,CACX;IACH;AAEA;;;;AAIG;AACH,IAAA,MAAM,CACJ,IAAmC,EACnC,KAAQ,EACR,QAAwC,YAAY,EAAA;QAEpD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,CAAC,MAAM,KAAI;YACT,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;AACvC,YAAA,IAAI,CAAC,UAAU;AAAE,gBAAA,OAAO,KAAK;AAC7B,YAAA,IAAI;AACF,gBAAA,OAAO,IAAI,CAAC,UAAU,CAAC;YACzB;AAAE,YAAA,MAAM;AACN,gBAAA,OAAO,KAAK;YACd;QACF,CAAC,EACD,MAAM,KAAK,EACX,KAAK,CACN;IACH;AAEA;;;;;AAKG;AACH,IAAA,OAAO,CAAC,IAAY,EAAA;AAClB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QACxD,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,SAAS;QAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC;AAC1D,QAAA,IAAI,UAAU;AAAE,YAAA,OAAO,UAAU;QACjC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,UAAU,EAAE;YACxC,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,qBAAqB,CAAC;QACvE;QACA,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC;IAC7C;AAEA;;;;;;;;;;;;;AAaG;AACH,IAAA,MAAM,CAAgC,IAAU,EAAA;AAC9C,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,UAAU,EAAE,IAAI,CAAC;IAClE;AAEA;;;;AAIG;IACH,eAAe,CACb,SAAc,EACd,IAAU,EAAA;AAEV,QAAA,OAAO,IAAI,CAAC,IAAI,CACd,CAAA,EAAG,MAAM,CAAC,SAAS,CAAC,CAAA,CAAA,EAAI,MAAM,CAAC,IAAI,CAAC,CAAA,CAAE,EACtC,CAAC,UAAU,KAAK,UAAU,CAAC,SAAS,CAAC,EACrC,IAAI,CACL;IACH;AAEA;;;;AAIG;AACH,IAAA,MAAM,CAAI,IAA8C,EAAA;AACtD,QAAA,OAAO,IAAI,UAAU,CAAI,CAAC,UAAU,KAAI;YACtC,IAAI,OAAO,GAAsB,IAAI;YACrC,IAAI,SAAS,GAA2B,IAAI;YAC5C,MAAM,MAAM,GAAG,MAAK;gBAClB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC1C,MAAM,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI;gBAClE,IAAI,IAAI,KAAK,OAAO;oBAAE;gBACtB,SAAS,EAAE,KAAK,EAAE;gBAClB,SAAS,GAAG,IAAI;gBAChB,OAAO,GAAG,IAAI;AACd,gBAAA,IAAI,CAAC,IAAI;oBAAE;AACX,gBAAA,SAAS,GAAG,IAAI,eAAe,EAAE;gBACjC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;AAC7E,YAAA,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AACxC,YAAA,MAAM,EAAE;AACR,YAAA,OAAO,MAAK;AACV,gBAAA,IAAI,EAAE;gBACN,SAAS,EAAE,KAAK,EAAE;AACpB,YAAA,CAAC;AACH,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,OAAO,CAAC,MAAc,EAAA;AAC5B,QAAA,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,SAAS,CAAC;IAC3E;;AAGQ,IAAA,IAAI,CACV,KAAa,EACb,KAAwC,EACxC,IAAU,EAAA;AAEV,QAAA,MAAM,IAAI,GAAG,CAAA,EAAG,KAAK,IAAI;AACzB,QAAA,MAAM,GAAG,GAAG,CAAC,IAAe,KAAa;AACvC,YAAA,IAAI,MAAa;AACjB,YAAA,IAAI;gBACF,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpC;YAAE,OAAO,KAAK,EAAE;;AAEd,gBAAA,IAAI,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE;AAC5E,oBAAA,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC9B;AACA,gBAAA,MAAM,KAAK;YACb;YACA,OAAQ,MAAM,CAAC,IAAI,CAAgD,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC;AACzF,QAAA,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;AAC/B,YAAA,QAAQ,CAAC,GAAG,IAAe,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5D;;;QAGA,QAAQ,CAAC,GAAG,IAAe,KACzB,QAAQ,CAAC,MAAK;YACZ,IAAI,CAAC,UAAU,EAAE;AACjB,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AACpB,YAAA,OAAO,GAAG,CAAC,IAAI,CAAC;QAClB,CAAC,CAAC,EAAE;IACR;AACD;;AC1ND;;;;;;;;;;;AAWG;AA4FH;;;;AAIG;MACmB,iBAAiB,CAAA;;AAElB,IAAA,OAAO;AAE1B,IAAA,WAAA,CAAsB,IAIrB,EAAA;AACC,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;AAEvD,QAAA,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC;AAC7F,QAAA,IAAI,CAAC,IAAI;YAAE,MAAM,aAAa,CAAC,CAAA,OAAA,EAAU,IAAI,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC;AACtD,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACrF;AACD;AAED;;;;;;;;;;;;;;;AAeG;AACG,SAAU,aAAa,CAM3B,IAAyD,EAAA;IAEzD,MAAe,aAAc,SAAQ,iBAA6B,CAAA;AAChE,QAAA,WAAA,GAAA;YACE,KAAK,CAAC,IAAI,CAAC;YACX,MAAM,OAAO,GAAG,IAA0C;AAC1D,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO;AAE5B,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;;;gBAGxB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;AACjF,gBAAA,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAA6B,EAAE;AACxE,oBAAA,OAAO,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,MAAM,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;gBACjD;YACF;YAEA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM;YAChD,IAAI,MAAM,EAAE;gBACV,MAAM,CAAC,MAAK;AACV,oBAAA,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE;;AAEvC,oBAAA,IAAI,UAAU;AAAE,wBAAA,SAAS,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,QAAO,CAAC,CAAC,CAAC;AACrE,gBAAA,CAAC,CAAC;YACJ;AAEA,YAAA,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,CAAC,IAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YAE/E,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,CAAA,EAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA,EAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACnE,gBAAA,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAC9B,CAAC,UAAU,KAAK,UAAU,CAAC,KAAK,CAAkC,CACnE;YACH;;;AAIA,YAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI;YACzB,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gBAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAS,IAAI,CAAC,KAAK,CAAC;AACpD,gBAAA,OAAO,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,OAAO;;gBAEtC,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE;AACjD,gBAAA,OAAO,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM;AAC3C,gBAAA,OAAO,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK;gBACzC,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,MAAM,CACvC,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAC5D;YACH;QACF;AACD;AACD,IAAA,OAAO,aAAgF;AACzF;;ACxMA;;;;;;AAMG;AAaH;;;;;;;;AAQG;MAEU,UAAU,CAAA;AACJ,IAAA,IAAI,GAAG,gBAAgB,CAAC,oBAAoB,CAAC;;AAGrD,IAAA,QAAQ,GAA2B,IAAI,CAAC,IAAI,CAAC,cAAc;;AAE3D,IAAA,MAAM,GAA6B,IAAI,CAAC,IAAI,CAAC,MAAM;;AAEnD,IAAA,KAAK,GAAoB,IAAI,CAAC,IAAI,CAAC,KAAK;;AAExC,IAAA,gBAAgB,GAAqD,IAAI,CAAC,IAAI,CAAC,MAAM,CAC5F,CAAC,MAAM,KAAK,MAAM,CAAC,iBAAiB,CACrC;;AAGD,IAAA,cAAc,CAAC,OAAoC,EAAA;AACjD,QAAA,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;IACzC;;IAGA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE;IACjC;uGAtBW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAV,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cADG,MAAM,EAAA,CAAA;;2FACnB,UAAU,EAAA,UAAA,EAAA,CAAA;kBADtB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA0BlC;;;;AAIG;AAEG,MAAO,aAAc,SAAQ,aAAa,CAAC;AAC/C,IAAA,IAAI,EAAE,eAAe;AACrB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,OAAO,EAAE;QACP,MAAM;QACN,cAAc;QACd,SAAS;QACT,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,UAAU;QACV,WAAW;QACX,aAAa;QACb,WAAW;QACX,MAAM;QACN,KAAK;QACL,KAAK;QACL,UAAU;QACV,UAAU;QACV,UAAU;QACV,MAAM;QACN,MAAM;QACN,UAAU;QACV,eAAe;QACf,aAAa;QACb,UAAU;QACV,WAAW;QACX,SAAS;QACT,cAAc;QACd,aAAa;AACd,KAAA;AACD,IAAA,MAAM,EAAE;QACN,UAAU;QACV,cAAc;QACd,UAAU;QACV,UAAU;QACV,iBAAiB;QACjB,gBAAgB;QAChB,yBAAyB;AAC1B,KAAA;CACF,CAAC,CAAA;uGA1CW,aAAa,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cADA,MAAM,EAAA,CAAA;;2FACnB,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;AA6ClC,MAAM,QAAQ,GAAwB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AAEvD;;;;;AAKG;AAEG,MAAO,YAAa,SAAQ,aAAa,CAAC;AAC9C,IAAA,IAAI,EAAE,cAAc;AACpB,IAAA,KAAK,EAAE,cAAc;AACrB,IAAA,KAAK,EAAE,aAAa;AACpB,IAAA,OAAO,EAAE,EAAE;CACZ,CAAC,CAAA;AACA;;;;AAIG;IACM,KAAK,GAAgC,IAAI,CAAC,OAAO,CAAC,MAAM,CAC/D,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,EAAE,EACpC,QAAQ,EACR,MAAM,CAAC,EAAE,CACV;uGAfU,YAAY,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cADC,MAAM,EAAA,CAAA;;2FACnB,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;AC9FlC,MAAM,cAAc,GAAoB,CAAC,aAAa,EAAE,YAAY,CAAC;AAErE;;;;;;;;;AASG;AACI,MAAM,oBAAoB,GAAe;AAEhD;SACgB,eAAe,CAC7B,MAA6C,EAC7C,GAAG,QAA2B,EAAA;AAE9B,IAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC9B,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE;AAC5C,YAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,gBAAA,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QACrE;IACF;AACA,IAAA,MAAM,KAAK,GAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE;IACjD,OAAO;AACL,QAAA,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;QACxC,cAAc;QACd,UAAU;QACV,aAAa;QACb,YAAY;AACZ,QAAA,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;KAC9F;AACH;;ACnDA;;;;;;;;;;AAUG;AAmBH;;;AAGG;MASU,iBAAiB,CAAA;;AAEnB,IAAA,EAAE,GAAG,KAAK,CAAC,QAAQ,qCAAW,KAAK,EAAE,mBAAmB,EAAA,CAAA,GAAA,CAA5B,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAC;uGAFzD,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EANjB;AACT,YAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,iBAAiB,CAAC,EAAE;;YAElF,oBAAoB;AACrB,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAEU,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAR7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,qBAAqB;AAC/B,oBAAA,SAAS,EAAE;AACT,wBAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAK,iBAAkB,CAAC,EAAE;;wBAElF,oBAAoB;AACrB,qBAAA;AACF,iBAAA;;AAqBD;;;;;;;;;;;;;AAaG;MAEU,gBAAgB,CAAA;;IAElB,QAAQ,GAAG,KAAK,CAA0C,IAAI,4CACrE,KAAK,EAAE,0BAA0B,EAAA,CAAA,GAAA,CADsC;AACvE,YAAA,KAAK,EAAE,0BAA0B;AAClC,SAAA,CAAA,CAAA,CAAC;;IAEO,MAAM,GAAG,KAAK,CAA4D,IAAI,0CACrF,KAAK,EAAE,wBAAwB,EAAA,CAAA,GAAA,CADwD;AACvF,YAAA,KAAK,EAAE,wBAAwB;AAChC,SAAA,CAAA,CAAA,CAAC;;IAEO,KAAK,GAAG,KAAK,CAA4D,IAAI,yCACpF,KAAK,EAAE,uBAAuB,EAAA,CAAA,GAAA,CADwD;AACtF,YAAA,KAAK,EAAE,uBAAuB;AAC/B,SAAA,CAAA,CAAA,CAAC;AAEF,IAAA,OAAO,sBAAsB,CAC3B,KAAuB,EACvB,OAAgB,EAAA;AAEhB,QAAA,OAAO,IAAI;IACb;AAEA,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CACpC,gBAAgB,CAAC,mBAAmB,CAAC,EACrC,MAAM,cAAc,EACpB,mBAAmB,EAAE,CACtB,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC;AACjD,QAAA,MAAM,OAAO,GAAG,MAAM,CAAuC,WAAW,CAAC;AACzE,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAC1C,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;QACzC,IAAI,KAAK,GAGE,IAAI;QAEf,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,OAAO,GAAG,QAAQ,EAAE;YAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC;YACnD,SAAS,CAAC,MAAK;gBACb,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE;;oBAExC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO;AACtC,oBAAA,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE;oBACzB;gBACF;gBACA,SAAS,CAAC,KAAK,EAAE;AACjB,gBAAA,KAAK,GAAG;AACN,sBAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,kBAAkB,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;sBAChF,IAAI;gBACR,OAAO,CAAC,YAAY,EAAE;AACxB,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEQ,WAAW,CACjB,QAAsB,EACtB,OAA6C,EAAA;AAE7C,QAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO;AAAE,YAAA,OAAO,OAAO;AAC/C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;AAC5B,QAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM;AACxC,YAAA,OAAO,MAAkD;AAC3D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE;AAC3B,QAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM;AACvC,YAAA,OAAO,MAAkD;AAC3D,QAAA,OAAQ,IAAI,CAAC,QAAQ,EAAkE,IAAI,IAAI;IACjG;uGAlEW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,0BAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,SAAS;mBAAC,EAAE,QAAQ,EAAE,oBAAoB,EAAE;;;AC3E7C;;;;;;;;;;;;;AAaG;MA8CU,SAAS,GAAG,IAAI,cAAc,CAAkB,WAAW;AAExE;AACM,SAAU,UAAU,CAAC,IAAI,GAAG,gBAAgB,EAAA;AAChD,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAClD,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,MAAM,gBAAgB,CAAC,IAAI,CAAC;AACvC,IAAA,OAAO,IAAI;AACb;AAEA;;;AAGG;AACG,SAAU,iBAAiB,CAAC,KAUjC,EAAA;AACC,IAAA,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK;IACpC,OAAO;AACL,QAAA,IAAI,UAAU,GAAA;AACZ,YAAA,OAAO,KAAK,CAAC,UAAU,EAAE;QAC3B,CAAC;AACD,QAAA,IAAI,GAAG,GAAA;AACL,YAAA,OAAO,KAAK,CAAC,GAAG,EAAE;QACpB,CAAC;AACD,QAAA,IAAI,IAAI,GAAA;AACN,YAAA,OAAO,KAAK,CAAC,IAAI,EAAE;QACrB,CAAC;QACD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS;AACT,QAAA,IAAI,KAAK,CAAC,aAAa,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC;;;AAGtE,QAAA,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC;KACvC;AACH;;ACtGA;;;;AAIG;AAYH;;;AAGG;AACG,SAAU,cAAc,CAAC,OAA4B,EAAE,IAAc,EAAA;AACzE,IAAA,MAAM,CAAC,CAAC,SAAS,KAAI;AACnB,QAAA,MAAM,GAAG,GAAG,OAAO,EAAE;AACrB,QAAA,IAAI,GAAG;AAAE,YAAA,SAAS,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACpE,IAAA,CAAC,CAAC;AACJ;AAEA;;;;;AAKG;AACG,SAAU,kBAAkB,CAAC,OAAqB,EAAA;AACtD,IAAA,MAAM,OAAO,GAAG,MAAM,CAAsB,IAAI,mDAAC;AACjD,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,eAAe,CAAC,MAAK;AACnB,QAAA,MAAM,CACJ,CAAC,SAAS,KAAI;AACZ,YAAA,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;AACtC,YAAA,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9C,YAAA,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAClE,QAAA,CAAC,EACD,EAAE,QAAQ,EAAE,CACb;AACH,IAAA,CAAC,CAAC;AACF,IAAA,OAAO,OAAO,CAAC,UAAU,EAAE;AAC7B;;AC/CA;;;;AAIG;AAeH;;;;AAIG;MAEU,iBAAiB,CAAA;IACnB,UAAU,GAAG,KAAK,CAAC,QAAQ,6CAClC,KAAK,EAAE,mBAAmB,EAAA,CAAA,GAAA,CADoD;AAC9E,YAAA,KAAK,EAAE,mBAAmB;AAC3B,SAAA,CAAA,CAAA,CAAC;AAEF,IAAA,WAAA,GAAA;QACE,MAAM,OAAO,GAAG,MAAM,CAAyB,UAAU,CAAC,CAAC,aAAa;QACxE,IAAI,KAAK,GAA8C,EAAE;QACzD,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;YAC9B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACrC,gBAAA,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;AAAE,oBAAA,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;YACpD;AACA,YAAA,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAChD,gBAAA,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK;oBAAE,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE;YACA,KAAK,GAAG,IAAI;AACd,QAAA,CAAC,CAAC;IACJ;uGAlBW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,SAAS;mBAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE;;AAsB9C;MA4Da,aAAa,CAAA;AACf,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,yCAAwB,KAAK,EAAE,eAAe,EAAA,CAAA,GAAA,CAAxB,EAAE,KAAK,EAAE,eAAe,EAAE,GAAC;AAEjF,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAAE;;AAE7C,QAAA,MAAM,MAAM,GAAG,gBAAgB,EAAE;AACjC,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;AACpD,QAAA,MAAM,CAAC,MACL,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,MAAM,KAAK,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CACvF;IACH;uGAXW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvDd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAEU,aAAa,wFAjFb,iBAAiB,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAiFjB,aAAa,EAAA,UAAA,EAAA,CAAA;kBA3DzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,kBAAkB;oBAC5B,OAAO,EAAE,CAAC,iBAAiB,CAAC;oBAC5B,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDT,EAAA,CAAA;AACF,iBAAA;;;ACzGD;;;AAGG;AAGH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU;AAEhC;AACM,SAAU,OAAO,CAAC,GAAW,EAAE,OAAe,EAAA;IAClD,IAAI,CAAC,SAAS,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE;AACrC,IAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AACf,IAAA,OAAO,CAAC,IAAI,CAAC,cAAc,OAAO,CAAA,CAAE,CAAC;AACvC;AAEA;SACgB,gBAAgB,GAAA;IAC9B,MAAM,CAAC,KAAK,EAAE;AAChB;;AClBA;;;;AAIG;AAKH;;;;AAIG;AACG,SAAU,SAAS,CAAC,KAAgB,EAAA;AACxC,IAAA,OAAO,kBAAkB,CAAC,KAAK,CAA2B;AAC5D;;AChBA;;;;;;;;;;;AAWG;AAEH;;ACbA;;AAEG;;;;"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { searchState, SearchToken, searchPlugin, SEARCH_DEFAULTS } from '@embedpdf/plugin-search';
|
|
2
|
+
export * from '@embedpdf/plugin-search';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Injectable, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
5
|
+
import { pluginService, injectPage, CapabilityBinding, injectKernelHost } from '@embedpdf/angular/runtime';
|
|
6
|
+
import { outputFromObservable } from '@angular/core/rxjs-interop';
|
|
7
|
+
import { Subject } from 'rxjs';
|
|
8
|
+
import { paint, searchHighlightsOf, createClickDetector } from '@embedpdf/web';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The search plugin's service and feature:
|
|
12
|
+
*
|
|
13
|
+
* withSearch(options) the plugin, for provideEmbedPdf()
|
|
14
|
+
* inject(EpdfSearch) search and step through the matches, the State table as signals
|
|
15
|
+
* (`hitCount()`, `activeHitIndex()`, `status()`, …), the matches
|
|
16
|
+
* (`hits()`, `hitsOn(page)`), the events as streams (`completed$`, …),
|
|
17
|
+
* and the settings
|
|
18
|
+
*/
|
|
19
|
+
const NO_HITS$1 = Object.freeze([]);
|
|
20
|
+
/**
|
|
21
|
+
* Search: `search({ text })`, `nextHit()`, `goToHit(hit)` and the rest of the Search page's
|
|
22
|
+
* methods, every value of its State table as a signal (`search.hitCount()`), its events as
|
|
23
|
+
* streams (`search.completed$`), and its settings (`search.updateSettings({ highlight })`).
|
|
24
|
+
* Without a document the signals read empty and the methods refuse with `not-ready`.
|
|
25
|
+
*/
|
|
26
|
+
class EpdfSearch extends pluginService({
|
|
27
|
+
name: 'EpdfSearch',
|
|
28
|
+
feature: 'withSearch()',
|
|
29
|
+
token: SearchToken,
|
|
30
|
+
state: searchState,
|
|
31
|
+
methods: [
|
|
32
|
+
'search',
|
|
33
|
+
'nextHit',
|
|
34
|
+
'previousHit',
|
|
35
|
+
'goToHit',
|
|
36
|
+
'revealActiveHit',
|
|
37
|
+
'listHits',
|
|
38
|
+
'listPagesWithHits',
|
|
39
|
+
'cancel',
|
|
40
|
+
'clear',
|
|
41
|
+
'refresh',
|
|
42
|
+
'findAll',
|
|
43
|
+
'canSearch',
|
|
44
|
+
'getQuery',
|
|
45
|
+
'getStatus',
|
|
46
|
+
'getHitCount',
|
|
47
|
+
'getActiveHitIndex',
|
|
48
|
+
'getActiveHit',
|
|
49
|
+
'getProgress',
|
|
50
|
+
'getError',
|
|
51
|
+
],
|
|
52
|
+
events: [
|
|
53
|
+
'onStarted',
|
|
54
|
+
'onProgressChanged',
|
|
55
|
+
'onCompleted',
|
|
56
|
+
'onCancelled',
|
|
57
|
+
'onFailed',
|
|
58
|
+
'onActiveHitChanged',
|
|
59
|
+
'onCleared',
|
|
60
|
+
],
|
|
61
|
+
}) {
|
|
62
|
+
/**
|
|
63
|
+
* Every match found so far, for a list of results. The plugin hands out the same array until
|
|
64
|
+
* matches are added, so a list redraws only when there are new ones. Empty without a document.
|
|
65
|
+
*/
|
|
66
|
+
hits = this.binding.select((search) => search.listHits(), NO_HITS$1, Object.is);
|
|
67
|
+
/**
|
|
68
|
+
* The matches on one page (its ref or its index), for a count on a thumbnail. Pass a function
|
|
69
|
+
* (`() => this.page().ref`) and it follows the page you show. Empty for a page that isn't in
|
|
70
|
+
* the document, and without one.
|
|
71
|
+
*/
|
|
72
|
+
hitsOn(page) {
|
|
73
|
+
const pageOf = typeof page === 'function' ? page : () => page;
|
|
74
|
+
return this.binding.select((search) => search.listHits({ page: pageOf() }), NO_HITS$1, Object.is);
|
|
75
|
+
}
|
|
76
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfSearch, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
77
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfSearch, providedIn: 'root' });
|
|
78
|
+
}
|
|
79
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfSearch, decorators: [{
|
|
80
|
+
type: Injectable,
|
|
81
|
+
args: [{ providedIn: 'root' }]
|
|
82
|
+
}] });
|
|
83
|
+
/** The search plugin, with its settings: `withSearch({ highlight: { color: '#fde047' } })`. */
|
|
84
|
+
function withSearch(options) {
|
|
85
|
+
return { plugins: [searchPlugin(options)], services: [EpdfSearch] };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* `<epdf-search-layer>`: the matches of the search on one page, highlighted. It makes no
|
|
90
|
+
* engine calls; your search box drives the search through `inject(EpdfSearch)`.
|
|
91
|
+
*
|
|
92
|
+
* An upright match is a rounded box; a turned one is its true four corners. Both are placed
|
|
93
|
+
* through the page context, in the colors of the plugin's `highlight` setting, which the
|
|
94
|
+
* `--epdf-search-highlight`, `--epdf-search-highlight-active` and `--epdf-search-blend-mode`
|
|
95
|
+
* CSS variables win over.
|
|
96
|
+
*
|
|
97
|
+
* Each painted line carries `data-epdf-search-hit`, and `data-active` on the active match's, for
|
|
98
|
+
* tests (`EpdfSearchLayerHarness`) and your own CSS.
|
|
99
|
+
*
|
|
100
|
+
* Listen to `(hitClick)` and matches become clickable: it emits the match someone clicks, for
|
|
101
|
+
* example for `search.goToHit($event)`. The press still reaches the page, so a drag that starts
|
|
102
|
+
* on a match selects text, and only a click emits. Without a listener, matches are only paint
|
|
103
|
+
* and the pointer goes straight through.
|
|
104
|
+
*/
|
|
105
|
+
const NO_HITS = Object.freeze([]);
|
|
106
|
+
class EpdfSearchLayer {
|
|
107
|
+
clicks$ = new Subject();
|
|
108
|
+
/** A match was clicked (not dragged across): makes matches clickable while it's listened to. */
|
|
109
|
+
hitClick = outputFromObservable(this.clicks$);
|
|
110
|
+
page = injectPage('<epdf-search-layer>');
|
|
111
|
+
/** The search plugin of the page's own document. */
|
|
112
|
+
search = new CapabilityBinding(injectKernelHost('<epdf-search-layer>'), () => SearchToken, () => this.page.documentId);
|
|
113
|
+
/** This page's matches: the plugin's own array, the same until matches land on this page. */
|
|
114
|
+
hits = this.search.select((search) => search.listHits({ page: this.page.ref }), NO_HITS, Object.is);
|
|
115
|
+
active = this.search.select((search) => search.getActiveHit(), null, Object.is);
|
|
116
|
+
highlight = this.search.select((search) => search.getSettings().highlight, SEARCH_DEFAULTS.highlight);
|
|
117
|
+
// Each color is its CSS variable first, then the setting: CSS wins.
|
|
118
|
+
color = computed(() => paint('search-highlight', this.highlight().color), ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
119
|
+
activeColor = computed(() => paint('search-highlight-active', this.highlight().activeColor), ...(ngDevMode ? [{ debugName: "activeColor" }] : []));
|
|
120
|
+
blendMode = computed(() => paint('search-blend-mode', this.highlight().blendMode), ...(ngDevMode ? [{ debugName: "blendMode" }] : []));
|
|
121
|
+
/** One painted piece per line of each match: a box when upright, a polygon when turned. */
|
|
122
|
+
pieces = computed(() => searchHighlightsOf(this.hits(), {
|
|
123
|
+
active: this.active(),
|
|
124
|
+
page: this.page.transform(),
|
|
125
|
+
color: this.color(),
|
|
126
|
+
activeColor: this.activeColor(),
|
|
127
|
+
}), ...(ngDevMode ? [{ debugName: "pieces" }] : []));
|
|
128
|
+
/** Tells a click on a match from a drag that starts there (and selects text). */
|
|
129
|
+
clickDetector = createClickDetector();
|
|
130
|
+
/** Whether `(hitClick)` is listened to: only then do matches take the pointer. */
|
|
131
|
+
get clickable() {
|
|
132
|
+
return this.clicks$.observed;
|
|
133
|
+
}
|
|
134
|
+
press(event) {
|
|
135
|
+
// Nothing stops the press: it reaches the page as well.
|
|
136
|
+
if (this.clickable)
|
|
137
|
+
this.clickDetector.press(event);
|
|
138
|
+
}
|
|
139
|
+
click(event, hit) {
|
|
140
|
+
if (this.clickable && this.clickDetector.isClick(event))
|
|
141
|
+
this.clicks$.next(hit);
|
|
142
|
+
}
|
|
143
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfSearchLayer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
144
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: EpdfSearchLayer, isStandalone: true, selector: "epdf-search-layer", outputs: { hitClick: "hitClick" }, ngImport: i0, template: `
|
|
145
|
+
@if (pieces().length > 0) {
|
|
146
|
+
<div style="position: absolute; inset: 0; pointer-events: none">
|
|
147
|
+
@for (piece of pieces(); track piece.key) {
|
|
148
|
+
@if (piece.box; as box) {
|
|
149
|
+
<div
|
|
150
|
+
data-epdf-search-hit
|
|
151
|
+
style="position: absolute; border-radius: 2px"
|
|
152
|
+
[attr.data-active]="piece.active || null"
|
|
153
|
+
[style.left.px]="box.left"
|
|
154
|
+
[style.top.px]="box.top"
|
|
155
|
+
[style.width.px]="box.width"
|
|
156
|
+
[style.height.px]="box.height"
|
|
157
|
+
[style.background-color]="piece.fill"
|
|
158
|
+
[style.mix-blend-mode]="blendMode()"
|
|
159
|
+
[style.pointer-events]="clickable ? 'auto' : null"
|
|
160
|
+
[style.cursor]="clickable ? 'pointer' : null"
|
|
161
|
+
(pointerdown)="press($event)"
|
|
162
|
+
(click)="click($event, piece.hit)"
|
|
163
|
+
></div>
|
|
164
|
+
} @else {
|
|
165
|
+
<svg
|
|
166
|
+
style="position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible"
|
|
167
|
+
[style.mix-blend-mode]="blendMode()"
|
|
168
|
+
>
|
|
169
|
+
<!-- The fill goes in style: an SVG attribute doesn't read var(). -->
|
|
170
|
+
<polygon
|
|
171
|
+
data-epdf-search-hit
|
|
172
|
+
[attr.data-active]="piece.active || null"
|
|
173
|
+
[attr.points]="piece.points"
|
|
174
|
+
[style.fill]="piece.fill"
|
|
175
|
+
[style.pointer-events]="clickable ? 'auto' : null"
|
|
176
|
+
[style.cursor]="clickable ? 'pointer' : null"
|
|
177
|
+
(pointerdown)="press($event)"
|
|
178
|
+
(click)="click($event, piece.hit)"
|
|
179
|
+
/>
|
|
180
|
+
</svg>
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
</div>
|
|
184
|
+
}
|
|
185
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
186
|
+
}
|
|
187
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfSearchLayer, decorators: [{
|
|
188
|
+
type: Component,
|
|
189
|
+
args: [{
|
|
190
|
+
selector: 'epdf-search-layer',
|
|
191
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
192
|
+
template: `
|
|
193
|
+
@if (pieces().length > 0) {
|
|
194
|
+
<div style="position: absolute; inset: 0; pointer-events: none">
|
|
195
|
+
@for (piece of pieces(); track piece.key) {
|
|
196
|
+
@if (piece.box; as box) {
|
|
197
|
+
<div
|
|
198
|
+
data-epdf-search-hit
|
|
199
|
+
style="position: absolute; border-radius: 2px"
|
|
200
|
+
[attr.data-active]="piece.active || null"
|
|
201
|
+
[style.left.px]="box.left"
|
|
202
|
+
[style.top.px]="box.top"
|
|
203
|
+
[style.width.px]="box.width"
|
|
204
|
+
[style.height.px]="box.height"
|
|
205
|
+
[style.background-color]="piece.fill"
|
|
206
|
+
[style.mix-blend-mode]="blendMode()"
|
|
207
|
+
[style.pointer-events]="clickable ? 'auto' : null"
|
|
208
|
+
[style.cursor]="clickable ? 'pointer' : null"
|
|
209
|
+
(pointerdown)="press($event)"
|
|
210
|
+
(click)="click($event, piece.hit)"
|
|
211
|
+
></div>
|
|
212
|
+
} @else {
|
|
213
|
+
<svg
|
|
214
|
+
style="position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible"
|
|
215
|
+
[style.mix-blend-mode]="blendMode()"
|
|
216
|
+
>
|
|
217
|
+
<!-- The fill goes in style: an SVG attribute doesn't read var(). -->
|
|
218
|
+
<polygon
|
|
219
|
+
data-epdf-search-hit
|
|
220
|
+
[attr.data-active]="piece.active || null"
|
|
221
|
+
[attr.points]="piece.points"
|
|
222
|
+
[style.fill]="piece.fill"
|
|
223
|
+
[style.pointer-events]="clickable ? 'auto' : null"
|
|
224
|
+
[style.cursor]="clickable ? 'pointer' : null"
|
|
225
|
+
(pointerdown)="press($event)"
|
|
226
|
+
(click)="click($event, piece.hit)"
|
|
227
|
+
/>
|
|
228
|
+
</svg>
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
</div>
|
|
232
|
+
}
|
|
233
|
+
`,
|
|
234
|
+
}]
|
|
235
|
+
}] });
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @embedpdf/angular/search: finding text.
|
|
239
|
+
*
|
|
240
|
+
* withSearch(options) the plugin, for provideEmbedPdf()
|
|
241
|
+
* inject(EpdfSearch) search, the matches, the state, the events
|
|
242
|
+
* <epdf-search-layer (hitClick)> the matches on each page, clickable when listened to
|
|
243
|
+
*/
|
|
244
|
+
// The plugin's types and helpers, so app code has one import for the feature.
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Generated bundle index. Do not edit.
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
export { EpdfSearch, EpdfSearchLayer, withSearch };
|
|
251
|
+
//# sourceMappingURL=embedpdf-angular-search.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-search.mjs","sources":["../../search/src/search.ts","../../search/src/search-layer.ts","../../search/src/public_api.ts","../../search/src/embedpdf-angular-search.ts"],"sourcesContent":["/**\n * The search plugin's service and feature:\n *\n * withSearch(options) the plugin, for provideEmbedPdf()\n * inject(EpdfSearch) search and step through the matches, the State table as signals\n * (`hitCount()`, `activeHitIndex()`, `status()`, …), the matches\n * (`hits()`, `hitsOn(page)`), the events as streams (`completed$`, …),\n * and the settings\n */\nimport { Injectable, type Signal } from '@angular/core';\nimport type { PageRef } from '@embedpdf/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport {\n searchPlugin,\n searchState,\n SearchToken,\n type SearchConfig,\n type SearchHit,\n} from '@embedpdf/plugin-search';\n\nconst NO_HITS: readonly SearchHit[] = Object.freeze([]);\n\n/**\n * Search: `search({ text })`, `nextHit()`, `goToHit(hit)` and the rest of the Search page's\n * methods, every value of its State table as a signal (`search.hitCount()`), its events as\n * streams (`search.completed$`), and its settings (`search.updateSettings({ highlight })`).\n * Without a document the signals read empty and the methods refuse with `not-ready`.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfSearch extends pluginService({\n name: 'EpdfSearch',\n feature: 'withSearch()',\n token: SearchToken,\n state: searchState,\n methods: [\n 'search',\n 'nextHit',\n 'previousHit',\n 'goToHit',\n 'revealActiveHit',\n 'listHits',\n 'listPagesWithHits',\n 'cancel',\n 'clear',\n 'refresh',\n 'findAll',\n 'canSearch',\n 'getQuery',\n 'getStatus',\n 'getHitCount',\n 'getActiveHitIndex',\n 'getActiveHit',\n 'getProgress',\n 'getError',\n ],\n events: [\n 'onStarted',\n 'onProgressChanged',\n 'onCompleted',\n 'onCancelled',\n 'onFailed',\n 'onActiveHitChanged',\n 'onCleared',\n ],\n}) {\n /**\n * Every match found so far, for a list of results. The plugin hands out the same array until\n * matches are added, so a list redraws only when there are new ones. Empty without a document.\n */\n readonly hits: Signal<readonly SearchHit[]> = this.binding.select(\n (search) => search.listHits(),\n NO_HITS,\n Object.is,\n );\n\n /**\n * The matches on one page (its ref or its index), for a count on a thumbnail. Pass a function\n * (`() => this.page().ref`) and it follows the page you show. Empty for a page that isn't in\n * the document, and without one.\n */\n hitsOn(page: PageRef | number | (() => PageRef | number)): Signal<readonly SearchHit[]> {\n const pageOf = typeof page === 'function' ? page : () => page;\n return this.binding.select((search) => search.listHits({ page: pageOf() }), NO_HITS, Object.is);\n }\n}\n\n/** The search plugin, with its settings: `withSearch({ highlight: { color: '#fde047' } })`. */\nexport function withSearch(options?: SearchConfig): EmbedPdfFeature {\n return { plugins: [searchPlugin(options)], services: [EpdfSearch] };\n}\n","/**\n * `<epdf-search-layer>`: the matches of the search on one page, highlighted. It makes no\n * engine calls; your search box drives the search through `inject(EpdfSearch)`.\n *\n * An upright match is a rounded box; a turned one is its true four corners. Both are placed\n * through the page context, in the colors of the plugin's `highlight` setting, which the\n * `--epdf-search-highlight`, `--epdf-search-highlight-active` and `--epdf-search-blend-mode`\n * CSS variables win over.\n *\n * Each painted line carries `data-epdf-search-hit`, and `data-active` on the active match's, for\n * tests (`EpdfSearchLayerHarness`) and your own CSS.\n *\n * Listen to `(hitClick)` and matches become clickable: it emits the match someone clicks, for\n * example for `search.goToHit($event)`. The press still reaches the page, so a drag that starts\n * on a match selects text, and only a click emits. Without a listener, matches are only paint\n * and the pointer goes straight through.\n */\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { Subject } from 'rxjs';\nimport {\n SEARCH_DEFAULTS,\n SearchToken,\n type SearchCapability,\n type SearchHit,\n} from '@embedpdf/plugin-search';\nimport {\n createClickDetector,\n paint,\n searchHighlightsOf,\n type SearchHighlightPiece,\n} from '@embedpdf/web';\nimport { CapabilityBinding, injectKernelHost, injectPage } from '@embedpdf/angular/runtime';\n\nconst NO_HITS: readonly SearchHit[] = Object.freeze([]);\n\n@Component({\n selector: 'epdf-search-layer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (pieces().length > 0) {\n <div style=\"position: absolute; inset: 0; pointer-events: none\">\n @for (piece of pieces(); track piece.key) {\n @if (piece.box; as box) {\n <div\n data-epdf-search-hit\n style=\"position: absolute; border-radius: 2px\"\n [attr.data-active]=\"piece.active || null\"\n [style.left.px]=\"box.left\"\n [style.top.px]=\"box.top\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\"\n [style.background-color]=\"piece.fill\"\n [style.mix-blend-mode]=\"blendMode()\"\n [style.pointer-events]=\"clickable ? 'auto' : null\"\n [style.cursor]=\"clickable ? 'pointer' : null\"\n (pointerdown)=\"press($event)\"\n (click)=\"click($event, piece.hit)\"\n ></div>\n } @else {\n <svg\n style=\"position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible\"\n [style.mix-blend-mode]=\"blendMode()\"\n >\n <!-- The fill goes in style: an SVG attribute doesn't read var(). -->\n <polygon\n data-epdf-search-hit\n [attr.data-active]=\"piece.active || null\"\n [attr.points]=\"piece.points\"\n [style.fill]=\"piece.fill\"\n [style.pointer-events]=\"clickable ? 'auto' : null\"\n [style.cursor]=\"clickable ? 'pointer' : null\"\n (pointerdown)=\"press($event)\"\n (click)=\"click($event, piece.hit)\"\n />\n </svg>\n }\n }\n </div>\n }\n `,\n})\nexport class EpdfSearchLayer {\n private readonly clicks$ = new Subject<SearchHit>();\n /** A match was clicked (not dragged across): makes matches clickable while it's listened to. */\n readonly hitClick = outputFromObservable(this.clicks$);\n\n private readonly page = injectPage('<epdf-search-layer>');\n /** The search plugin of the page's own document. */\n private readonly search = new CapabilityBinding<SearchCapability>(\n injectKernelHost('<epdf-search-layer>'),\n () => SearchToken,\n () => this.page.documentId,\n );\n /** This page's matches: the plugin's own array, the same until matches land on this page. */\n private readonly hits = this.search.select(\n (search) => search.listHits({ page: this.page.ref }),\n NO_HITS,\n Object.is,\n );\n private readonly active = this.search.select((search) => search.getActiveHit(), null, Object.is);\n private readonly highlight = this.search.select(\n (search) => search.getSettings().highlight,\n SEARCH_DEFAULTS.highlight,\n );\n // Each color is its CSS variable first, then the setting: CSS wins.\n private readonly color = computed(() => paint('search-highlight', this.highlight().color));\n private readonly activeColor = computed(() =>\n paint('search-highlight-active', this.highlight().activeColor),\n );\n protected readonly blendMode = computed(() =>\n paint('search-blend-mode', this.highlight().blendMode),\n );\n\n /** One painted piece per line of each match: a box when upright, a polygon when turned. */\n protected readonly pieces = computed((): readonly SearchHighlightPiece<SearchHit>[] =>\n searchHighlightsOf(this.hits(), {\n active: this.active(),\n page: this.page.transform(),\n color: this.color(),\n activeColor: this.activeColor(),\n }),\n );\n\n /** Tells a click on a match from a drag that starts there (and selects text). */\n private readonly clickDetector = createClickDetector();\n\n /** Whether `(hitClick)` is listened to: only then do matches take the pointer. */\n protected get clickable(): boolean {\n return this.clicks$.observed;\n }\n\n protected press(event: PointerEvent): void {\n // Nothing stops the press: it reaches the page as well.\n if (this.clickable) this.clickDetector.press(event);\n }\n\n protected click(event: MouseEvent, hit: SearchHit): void {\n if (this.clickable && this.clickDetector.isClick(event)) this.clicks$.next(hit);\n }\n}\n","/**\n * @embedpdf/angular/search: finding text.\n *\n * withSearch(options) the plugin, for provideEmbedPdf()\n * inject(EpdfSearch) search, the matches, the state, the events\n * <epdf-search-layer (hitClick)> the matches on each page, clickable when listened to\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-search';\nexport * from './search';\nexport { EpdfSearchLayer } from './search-layer';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["NO_HITS"],"mappings":"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"}
|