@embedpdf/plugin-annotation 1.0.7 → 1.0.9

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/dist/index.cjs CHANGED
@@ -193,6 +193,9 @@ var AnnotationPlugin = class extends import_core.BasePlugin {
193
193
  });
194
194
  this.selection?.onEndSelection(() => {
195
195
  if (!this.state.annotationMode) return;
196
+ if (!(this.state.annotationMode === import_models.PdfAnnotationSubtype.HIGHLIGHT || this.state.annotationMode === import_models.PdfAnnotationSubtype.UNDERLINE || this.state.annotationMode === import_models.PdfAnnotationSubtype.STRIKEOUT || this.state.annotationMode === import_models.PdfAnnotationSubtype.SQUIGGLY)) {
197
+ return;
198
+ }
196
199
  const formattedSelection = this.selection?.getFormattedSelection();
197
200
  if (!formattedSelection) return;
198
201
  for (const selection of formattedSelection) {
@@ -271,18 +274,22 @@ var AnnotationPlugin = class extends import_core.BasePlugin {
271
274
  createAnnotation: (pageIndex, annotation) => this.createAnnotation(pageIndex, annotation),
272
275
  updateAnnotation: (pageIndex, localId, patch) => this.updateAnnotation(pageIndex, localId, patch),
273
276
  deleteAnnotation: (pageIndex, localId) => this.deleteAnnotation(pageIndex, localId),
277
+ renderAnnotation: (options) => this.renderAnnotation(options),
274
278
  onStateChange: this.state$.on,
275
279
  onModeChange: this.modeChange$.on,
276
280
  onActiveToolChange: this.activeTool$.on,
277
281
  commit: () => this.commit()
278
282
  };
279
283
  }
284
+ createActiveTool(mode, toolDefaults) {
285
+ if (mode === null) {
286
+ return { mode: null, defaults: null };
287
+ }
288
+ return { mode, defaults: toolDefaults[mode] };
289
+ }
280
290
  emitActiveTool(state) {
281
- const mode = state.annotationMode;
282
- this.activeTool$.emit({
283
- mode,
284
- defaults: mode ? state.toolDefaults[mode] : null
285
- });
291
+ const activeTool = this.createActiveTool(state.annotationMode, state.toolDefaults);
292
+ this.activeTool$.emit(activeTool);
286
293
  }
287
294
  onStoreUpdated(prev, next) {
288
295
  this.state$.emit(next);
@@ -306,6 +313,34 @@ var AnnotationPlugin = class extends import_core.BasePlugin {
306
313
  }
307
314
  return this.engine.getPageAnnotations(doc, page);
308
315
  }
316
+ renderAnnotation({
317
+ pageIndex,
318
+ annotation,
319
+ scaleFactor = 1,
320
+ rotation = import_models.Rotation.Degree0,
321
+ dpr = 1,
322
+ mode = import_models.AppearanceMode.Normal,
323
+ imageType = "image/webp"
324
+ }) {
325
+ const coreState = this.coreState.core;
326
+ if (!coreState.document) {
327
+ throw new Error("document does not open");
328
+ }
329
+ const page = coreState.document.pages.find((page2) => page2.index === pageIndex);
330
+ if (!page) {
331
+ throw new Error("page does not exist");
332
+ }
333
+ return this.engine.renderAnnotation(
334
+ coreState.document,
335
+ page,
336
+ annotation,
337
+ scaleFactor,
338
+ rotation,
339
+ dpr,
340
+ mode,
341
+ imageType
342
+ );
343
+ }
309
344
  selectAnnotation(pageIndex, annotationId) {
310
345
  this.dispatch(selectAnnotation(pageIndex, annotationId));
311
346
  }
@@ -494,6 +529,14 @@ var initialState = (cfg) => ({
494
529
  interaction: { mode: "squiggly", exclusive: false },
495
530
  textSelection: true
496
531
  },
532
+ [import_models2.PdfAnnotationSubtype.INK]: {
533
+ name: "Ink",
534
+ color: "#E44234",
535
+ opacity: 1,
536
+ strokeWidth: 11,
537
+ interaction: { mode: "ink", exclusive: true, cursor: "crosshair" },
538
+ textSelection: false
539
+ },
497
540
  ...cfg.toolDefaults
498
541
  },
499
542
  colorPresets: cfg.colorPresets ?? DEFAULT_COLORS,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/manifest.ts","../src/lib/annotation-plugin.ts","../src/lib/actions.ts","../src/lib/utils.ts","../src/lib/selectors.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { PluginManifest } from '@embedpdf/core';\nimport { AnnotationPluginConfig } from './types';\n\nexport const ANNOTATION_PLUGIN_ID = 'annotation';\n\nexport const manifest: PluginManifest<AnnotationPluginConfig> = {\n id: ANNOTATION_PLUGIN_ID,\n name: 'Annotation Plugin',\n version: '1.0.0',\n provides: ['annotation'],\n requires: ['interaction-manager', 'selection'],\n optional: ['history'],\n defaultConfig: {\n enabled: true,\n autoCommit: true,\n },\n};\n","import {\n BasePlugin,\n createBehaviorEmitter,\n enumEntries,\n PluginRegistry,\n SET_DOCUMENT,\n} from '@embedpdf/core';\nimport {\n ignore,\n PdfAnnotationObject,\n PdfDocumentObject,\n PdfEngine,\n PdfErrorReason,\n Task,\n PdfAnnotationSubtype,\n PdfTaskHelper,\n PdfErrorCode,\n PdfTask,\n} from '@embedpdf/models';\nimport {\n ActiveTool,\n AnnotationCapability,\n AnnotationPluginConfig,\n AnnotationState,\n BaseAnnotationDefaults,\n GetPageAnnotationsOptions,\n StylableSubtype,\n TrackedAnnotation,\n} from './types';\nimport {\n setAnnotations,\n selectAnnotation,\n deselectAnnotation,\n setAnnotationMode,\n AnnotationAction,\n updateToolDefaults,\n addColorPreset,\n createAnnotation,\n patchAnnotation,\n deleteAnnotation,\n commitPendingChanges,\n storePdfId,\n purgeAnnotation,\n reindexPageAnnotations,\n} from './actions';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n InteractionMode,\n} from '@embedpdf/plugin-interaction-manager';\nimport { SelectionPlugin, SelectionCapability } from '@embedpdf/plugin-selection';\nimport { HistoryPlugin, HistoryCapability, Command } from '@embedpdf/plugin-history';\nimport { getSelectedAnnotation } from './selectors';\nimport { makeUid, parseUid } from './utils';\n\nexport class AnnotationPlugin extends BasePlugin<\n AnnotationPluginConfig,\n AnnotationCapability,\n AnnotationState,\n AnnotationAction\n> {\n static readonly id = 'annotation' as const;\n\n private readonly ANNOTATION_HISTORY_TOPIC = 'annotations';\n\n private readonly config: AnnotationPluginConfig;\n\n private engine: PdfEngine;\n private readonly state$ = createBehaviorEmitter<AnnotationState>();\n private readonly interactionManager: InteractionManagerCapability | null;\n private readonly selection: SelectionCapability | null;\n private readonly history: HistoryCapability | null;\n\n /** Map <subtype> → <modeId>. Filled once in `initialize()`. */\n private readonly modeBySubtype = new Map<StylableSubtype, string>();\n /** The inverse map for quick lookup in onModeChange(). */\n private readonly subtypeByMode = new Map<string, StylableSubtype>();\n private readonly modeChange$ = createBehaviorEmitter<StylableSubtype | null>();\n private readonly activeTool$ = createBehaviorEmitter<ActiveTool>({\n mode: null,\n defaults: null,\n });\n\n constructor(\n id: string,\n registry: PluginRegistry,\n engine: PdfEngine,\n config: AnnotationPluginConfig,\n ) {\n super(id, registry);\n this.engine = engine;\n this.config = config;\n\n const selection = registry.getPlugin<SelectionPlugin>('selection');\n this.selection = selection?.provides() ?? null;\n\n const history = registry.getPlugin<HistoryPlugin>('history');\n this.history = history?.provides() ?? null;\n\n const interactionManager = registry.getPlugin<InteractionManagerPlugin>('interaction-manager');\n this.interactionManager = interactionManager?.provides() ?? null;\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n const doc = state.core.document;\n if (doc) {\n this.getAllAnnotations(doc);\n }\n });\n }\n\n async initialize(): Promise<void> {\n for (const [subtype, defaults] of enumEntries(this.state.toolDefaults)) {\n this.registerTool(subtype, defaults);\n }\n\n this.history?.onHistoryChange((topic) => {\n if (topic === this.ANNOTATION_HISTORY_TOPIC && this.config.autoCommit !== false) {\n this.commit();\n }\n });\n\n this.interactionManager?.onModeChange((s) => {\n const newSubtype = this.subtypeByMode.get(s.activeMode) ?? null;\n if (newSubtype !== this.state.annotationMode) {\n this.dispatch(setAnnotationMode(newSubtype));\n this.modeChange$.emit(newSubtype);\n }\n });\n\n this.selection?.onEndSelection(() => {\n if (!this.state.annotationMode) return;\n\n const formattedSelection = this.selection?.getFormattedSelection();\n if (!formattedSelection) return;\n\n for (const selection of formattedSelection) {\n const rect = selection.rect;\n const segmentRects = selection.segmentRects;\n const type = this.state.annotationMode;\n const color = this.state.toolDefaults[type].color;\n const opacity = this.state.toolDefaults[type].opacity;\n\n this.createAnnotation(selection.pageIndex, {\n type,\n rect,\n segmentRects,\n color,\n opacity,\n pageIndex: selection.pageIndex,\n id: Date.now() + Math.random(),\n });\n }\n\n this.selection?.clear();\n });\n }\n\n private registerTool(subtype: StylableSubtype, defaults: BaseAnnotationDefaults) {\n const modeId = defaults.interaction.mode;\n const interactionMode: InteractionMode = {\n id: modeId,\n scope: 'page',\n exclusive: defaults.interaction.exclusive,\n cursor: defaults.interaction.cursor,\n };\n\n this.interactionManager?.registerMode(interactionMode);\n\n if (defaults.textSelection) {\n this.selection?.enableForMode(modeId);\n }\n this.modeBySubtype.set(subtype, modeId);\n this.subtypeByMode.set(modeId, subtype);\n }\n\n protected buildCapability(): AnnotationCapability {\n return {\n getPageAnnotations: (options: GetPageAnnotationsOptions) => {\n return this.getPageAnnotations(options);\n },\n getSelectedAnnotation: () => {\n return getSelectedAnnotation(this.state);\n },\n selectAnnotation: (pageIndex: number, annotationId: number) => {\n this.selectAnnotation(pageIndex, annotationId);\n },\n deselectAnnotation: () => {\n this.dispatch(deselectAnnotation());\n },\n getAnnotationMode: () => {\n return this.state.annotationMode;\n },\n setAnnotationMode: (subtype: StylableSubtype | null) => {\n if (subtype === this.state.annotationMode) return;\n if (subtype) {\n const mode = this.modeBySubtype.get(subtype);\n if (!mode) throw new Error(`Mode missing for subtype ${subtype}`);\n this.interactionManager?.activate(mode);\n } else {\n this.interactionManager?.activate('default');\n }\n },\n getToolDefaults: (subtype) => {\n const defaults = this.state.toolDefaults[subtype];\n if (!defaults) {\n throw new Error(`No defaults found for subtype: ${subtype}`);\n }\n return defaults;\n },\n setToolDefaults: (subtype, patch) => {\n this.dispatch(updateToolDefaults(subtype, patch));\n },\n getColorPresets: () => [...this.state.colorPresets],\n addColorPreset: (color) => this.dispatch(addColorPreset(color)),\n createAnnotation: (pageIndex: number, annotation: PdfAnnotationObject) =>\n this.createAnnotation(pageIndex, annotation),\n updateAnnotation: (pageIndex: number, localId: number, patch: Partial<PdfAnnotationObject>) =>\n this.updateAnnotation(pageIndex, localId, patch),\n deleteAnnotation: (pageIndex: number, localId: number) =>\n this.deleteAnnotation(pageIndex, localId),\n onStateChange: this.state$.on,\n onModeChange: this.modeChange$.on,\n onActiveToolChange: this.activeTool$.on,\n commit: () => this.commit(),\n };\n }\n\n private emitActiveTool(state: AnnotationState) {\n const mode = state.annotationMode;\n this.activeTool$.emit({\n mode,\n defaults: mode ? state.toolDefaults[mode] : null,\n });\n }\n\n override onStoreUpdated(prev: AnnotationState, next: AnnotationState): void {\n this.state$.emit(next);\n if (\n prev.annotationMode !== next.annotationMode ||\n prev.toolDefaults[prev.annotationMode ?? PdfAnnotationSubtype.HIGHLIGHT] !==\n next.toolDefaults[next.annotationMode ?? PdfAnnotationSubtype.HIGHLIGHT]\n ) {\n this.emitActiveTool(next);\n }\n }\n\n private getAllAnnotations(doc: PdfDocumentObject) {\n const task = this.engine.getAllAnnotations(doc);\n task.wait((annotations) => this.dispatch(setAnnotations(annotations)), ignore);\n }\n\n private getPageAnnotations(\n options: GetPageAnnotationsOptions,\n ): Task<PdfAnnotationObject[], PdfErrorReason> {\n const { pageIndex } = options;\n\n const doc = this.coreState.core.document;\n\n if (!doc) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n }\n\n const page = doc.pages.find((p) => p.index === pageIndex);\n\n if (!page) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Page not found' });\n }\n\n return this.engine.getPageAnnotations(doc, page);\n }\n\n private selectAnnotation(pageIndex: number, annotationId: number) {\n this.dispatch(selectAnnotation(pageIndex, annotationId));\n }\n\n private createAnnotation(pageIndex: number, annotation: PdfAnnotationObject) {\n const localId = annotation.id;\n const execute = () => this.dispatch(createAnnotation(pageIndex, localId, annotation));\n\n if (!this.history) {\n execute();\n if (this.config.autoCommit) this.commit();\n return;\n }\n const command: Command = {\n execute,\n undo: () => {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n },\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private updateAnnotation(\n pageIndex: number,\n localId: number,\n patch: Partial<PdfAnnotationObject>,\n ) {\n if (!this.history) {\n this.dispatch(patchAnnotation(pageIndex, localId, patch));\n if (this.config.autoCommit !== false) {\n this.commit();\n }\n return;\n }\n const originalObject = this.state.byUid[makeUid(pageIndex, localId)].object;\n const originalPatch = Object.fromEntries(\n Object.keys(patch).map((key) => [key, originalObject[key as keyof PdfAnnotationObject]]),\n );\n const command: Command = {\n execute: () => this.dispatch(patchAnnotation(pageIndex, localId, patch)),\n undo: () => this.dispatch(patchAnnotation(pageIndex, localId, originalPatch)),\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private deleteAnnotation(pageIndex: number, localId: number) {\n if (!this.history) {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n if (this.config.autoCommit !== false) {\n this.commit();\n }\n return;\n }\n const originalAnnotation = this.state.byUid[makeUid(pageIndex, localId)].object;\n const command: Command = {\n execute: () => {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n },\n undo: () => this.dispatch(createAnnotation(pageIndex, localId, originalAnnotation)),\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private commit(): Task<boolean, PdfErrorReason> {\n const task = new Task<boolean, PdfErrorReason>();\n\n if (!this.state.hasPendingChanges) return PdfTaskHelper.resolve(true);\n\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n const creations: Task<any, PdfErrorReason>[] = [];\n const updates: Task<any, PdfErrorReason>[] = [];\n const deletionsByPage = new Map<number, { ta: TrackedAnnotation; uid: string }[]>();\n const affectedPages = new Set<number>();\n\n // 1. Group all pending changes by operation type\n for (const [uid, ta] of Object.entries(this.state.byUid)) {\n if (ta.commitState === 'synced') continue;\n\n const { pageIndex } = parseUid(uid);\n const page = doc.pages.find((p) => p.index === pageIndex);\n if (!page) continue;\n\n affectedPages.add(pageIndex);\n\n switch (ta.commitState) {\n case 'new':\n const task = this.engine.createPageAnnotation!(doc, page, ta.object);\n task.wait((annoId) => this.dispatch(storePdfId(uid, annoId)), ignore);\n creations.push(task);\n break;\n case 'dirty':\n updates.push(\n this.engine.updatePageAnnotation!(doc, page, { ...ta.object, id: ta.pdfId! }),\n );\n break;\n case 'deleted':\n if (!deletionsByPage.has(pageIndex)) {\n deletionsByPage.set(pageIndex, []);\n }\n deletionsByPage.get(pageIndex)!.push({ ta, uid });\n break;\n }\n }\n\n // 2. Create deletion tasks, sorted by ID descending\n const deletionTasks: Task<any, PdfErrorReason>[] = [];\n for (const [pageIndex, deletions] of deletionsByPage.entries()) {\n const page = doc.pages.find((p) => p.index === pageIndex)!;\n\n deletions.sort((a, b) => (b.ta.pdfId ?? -1) - (a.ta.pdfId ?? -1));\n\n for (const { ta, uid } of deletions) {\n if (ta.pdfId !== undefined) {\n const task = new Task<any, PdfErrorReason>();\n const removeTask = this.engine.removePageAnnotation!(doc, page, {\n ...ta.object,\n id: ta.pdfId!,\n });\n removeTask.wait(() => {\n this.dispatch(purgeAnnotation(uid));\n task.resolve(true);\n }, task.fail);\n deletionTasks.push(task);\n } else {\n this.dispatch(purgeAnnotation(uid));\n }\n }\n }\n\n // 3. Chain the operations: creations/updates -> deletions -> re-sync\n const allWriteTasks = [...creations, ...updates, ...deletionTasks];\n\n Task.allSettled(allWriteTasks).wait(() => {\n // 4. Client-Side Re-indexing\n // After all engine operations are done, tell the reducer to re-index each affected page.\n for (const pageIndex of affectedPages) {\n this.dispatch(reindexPageAnnotations(pageIndex));\n }\n\n // 5. Finalize the commit by updating the commitState of all items.\n this.dispatch(commitPendingChanges());\n task.resolve(true);\n }, task.fail);\n\n return task;\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { PdfAnnotationObject } from '@embedpdf/models';\nimport { StylableSubtype, ToolDefaultsBySubtype } from './types';\n\n/* ─────────── action constants ─────────── */\nexport const SET_ANNOTATIONS = 'ANNOTATION/SET_ANNOTATIONS';\nexport const REINDEX_PAGE_ANNOTATIONS = 'ANNOTATION/REINDEX_PAGE';\nexport const SELECT_ANNOTATION = 'ANNOTATION/SELECT_ANNOTATION';\nexport const DESELECT_ANNOTATION = 'ANNOTATION/DESELECT_ANNOTATION';\nexport const SET_ANNOTATION_MODE = 'ANNOTATION/SET_ANNOTATION_MODE';\nexport const UPDATE_TOOL_DEFAULTS = 'ANNOTATION/UPDATE_TOOL_DEFAULTS';\nexport const ADD_COLOR_PRESET = 'ANNOTATION/ADD_COLOR_PRESET';\nexport const CREATE_ANNOTATION = 'ANNOTATION/CREATE_ANNOTATION';\nexport const PATCH_ANNOTATION = 'ANNOTATION/PATCH_ANNOTATION';\nexport const DELETE_ANNOTATION = 'ANNOTATION/DELETE_ANNOTATION';\nexport const COMMIT_PENDING_CHANGES = 'ANNOTATION/COMMIT';\nexport const STORE_PDF_ID = 'ANNOTATION/STORE_PDF_ID';\nexport const PURGE_ANNOTATION = 'ANNOTATION/PURGE_ANNOTATION';\n\n/* ─────────── action interfaces ─────────── */\nexport interface SetAnnotationsAction extends Action {\n type: typeof SET_ANNOTATIONS;\n payload: Record<number, PdfAnnotationObject[]>;\n}\nexport interface ReindexPageAnnotationsAction extends Action {\n type: typeof REINDEX_PAGE_ANNOTATIONS;\n payload: { pageIndex: number };\n}\nexport interface SelectAnnotationAction extends Action {\n type: typeof SELECT_ANNOTATION;\n payload: { pageIndex: number; localId: number };\n}\nexport interface DeselectAnnotationAction extends Action {\n type: typeof DESELECT_ANNOTATION;\n}\nexport interface SetAnnotationModeAction extends Action {\n type: typeof SET_ANNOTATION_MODE;\n payload: StylableSubtype | null;\n}\n\nexport interface UpdateToolDefaultsAction extends Action {\n type: typeof UPDATE_TOOL_DEFAULTS;\n payload: { subtype: StylableSubtype; patch: Partial<ToolDefaultsBySubtype[StylableSubtype]> };\n}\n\nexport interface AddColorPresetAction extends Action {\n type: typeof ADD_COLOR_PRESET;\n payload: string;\n}\nexport interface CreateAnnotationAction extends Action {\n type: typeof CREATE_ANNOTATION;\n payload: { pageIndex: number; localId: number; annotation: PdfAnnotationObject };\n}\nexport interface PatchAnnotationAction extends Action {\n type: typeof PATCH_ANNOTATION;\n payload: { pageIndex: number; localId: number; patch: Partial<PdfAnnotationObject> };\n}\nexport interface DeleteAnnotationAction extends Action {\n type: typeof DELETE_ANNOTATION;\n payload: { pageIndex: number; localId: number };\n}\nexport interface CommitAction extends Action {\n type: typeof COMMIT_PENDING_CHANGES;\n}\n\nexport interface StorePdfIdAction extends Action {\n type: typeof STORE_PDF_ID;\n payload: { uid: string; pdfId: number };\n}\n\nexport interface PurgeAnnotationAction extends Action {\n type: typeof PURGE_ANNOTATION;\n payload: { uid: string };\n}\n\nexport type AnnotationAction =\n | SetAnnotationsAction\n | ReindexPageAnnotationsAction\n | SelectAnnotationAction\n | DeselectAnnotationAction\n | SetAnnotationModeAction\n | UpdateToolDefaultsAction\n | AddColorPresetAction\n | CreateAnnotationAction\n | PatchAnnotationAction\n | DeleteAnnotationAction\n | CommitAction\n | StorePdfIdAction\n | PurgeAnnotationAction;\n\n/* ─────────── action creators ─────────── */\nexport const setAnnotations = (p: Record<number, PdfAnnotationObject[]>): SetAnnotationsAction => ({\n type: SET_ANNOTATIONS,\n payload: p,\n});\n\nexport const reindexPageAnnotations = (pageIndex: number): ReindexPageAnnotationsAction => ({\n type: REINDEX_PAGE_ANNOTATIONS,\n payload: { pageIndex },\n});\n\nexport const selectAnnotation = (pageIndex: number, localId: number): SelectAnnotationAction => ({\n type: SELECT_ANNOTATION,\n payload: { pageIndex, localId },\n});\n\nexport const deselectAnnotation = (): DeselectAnnotationAction => ({ type: DESELECT_ANNOTATION });\n\nexport const setAnnotationMode = (m: StylableSubtype | null): SetAnnotationModeAction => ({\n type: SET_ANNOTATION_MODE,\n payload: m,\n});\n\nexport const updateToolDefaults = <S extends StylableSubtype>(\n subtype: S,\n patch: Partial<ToolDefaultsBySubtype[S]>,\n): UpdateToolDefaultsAction => ({ type: UPDATE_TOOL_DEFAULTS, payload: { subtype, patch } });\n\nexport const addColorPreset = (c: string): AddColorPresetAction => ({\n type: ADD_COLOR_PRESET,\n payload: c,\n});\n\nexport const createAnnotation = (\n pageIndex: number,\n localId: number,\n annotation: PdfAnnotationObject,\n): CreateAnnotationAction => ({\n type: CREATE_ANNOTATION,\n payload: { pageIndex, localId, annotation },\n});\n\nexport const patchAnnotation = (\n pageIndex: number,\n localId: number,\n patch: Partial<PdfAnnotationObject>,\n): PatchAnnotationAction => ({\n type: PATCH_ANNOTATION,\n payload: { pageIndex, localId, patch },\n});\n\nexport const deleteAnnotation = (pageIndex: number, localId: number): DeleteAnnotationAction => ({\n type: DELETE_ANNOTATION,\n payload: { pageIndex, localId },\n});\n\nexport const commitPendingChanges = (): CommitAction => ({ type: COMMIT_PENDING_CHANGES });\n\nexport const storePdfId = (uid: string, pdfId: number): StorePdfIdAction => ({\n type: STORE_PDF_ID,\n payload: { uid, pdfId },\n});\n\nexport const purgeAnnotation = (uid: string): PurgeAnnotationAction => ({\n type: PURGE_ANNOTATION,\n payload: { uid },\n});\n","/**\n * Creates a stable, document-wide unique ID from a page index and a stable local ID.\n */\nexport const makeUid = (pageIndex: number, localId: number): string => `p${pageIndex}#${localId}`;\n\n/**\n * Parses a UID string back into its constituent page index and stable local ID.\n */\nexport const parseUid = (uid: string): { pageIndex: number; localId: number } => {\n const [pg, rest] = uid.slice(1).split('#');\n return { pageIndex: Number(pg), localId: Number(rest) };\n};\n","import { AnnotationState, SelectedAnnotation } from './types';\nimport { parseUid } from './utils';\n\n/* helper – mirrors the one in reducer */\nconst makeUid = (page: number, id: number) => `p${page}#${id}`;\n\n/* ─────────── public selectors ─────────── */\n\n/** All annotations _objects_ on a single page (order preserved). */\nexport const getAnnotationsByPageIndex = (s: AnnotationState, page: number) =>\n (s.pages[page] ?? []).map((uid) => s.byUid[uid]);\n\n/** Shortcut: every page → list of annotation objects. */\nexport const getAnnotations = (s: AnnotationState) => {\n const out: Record<number, ReturnType<typeof getAnnotationsByPageIndex>> = {};\n for (const p of Object.keys(s.pages).map(Number)) out[p] = getAnnotationsByPageIndex(s, p);\n return out;\n};\n\n/** The full `TrackedAnnotation` for the current selection. */\nexport const getSelectedAnnotation = (s: AnnotationState) =>\n s.selectedUid ? s.byUid[s.selectedUid] : null;\n\nexport const getSelectedAnnotationWithPageIndex = (\n s: AnnotationState,\n): SelectedAnnotation | null => {\n if (!s.selectedUid) return null;\n const { pageIndex, localId } = parseUid(s.selectedUid);\n return { pageIndex, localId, annotation: s.byUid[s.selectedUid].object };\n};\n\nexport const getSelectedAnnotationByPageIndex = (s: AnnotationState, pageIndex: number) => {\n if (!s.selectedUid) return null;\n\n const pageUids = s.pages[pageIndex] ?? [];\n\n // Check if the selected UID is on the requested page\n if (pageUids.includes(s.selectedUid)) {\n return s.byUid[s.selectedUid];\n }\n\n return null;\n};\n\nexport const isInAnnotationMode = (s: AnnotationState) => s.annotationMode !== null;\nexport const getSelectedAnnotationMode = (s: AnnotationState) => s.annotationMode;\n\n/** Check if a given anno on a page is the current selection. */\nexport const isAnnotationSelected = (s: AnnotationState, page: number, id: number) =>\n s.selectedUid === makeUid(page, id);\n","import { Reducer } from '@embedpdf/core';\nimport { PdfAnnotationSubtype } from '@embedpdf/models';\nimport {\n ADD_COLOR_PRESET,\n COMMIT_PENDING_CHANGES,\n CREATE_ANNOTATION,\n DESELECT_ANNOTATION,\n PATCH_ANNOTATION,\n DELETE_ANNOTATION,\n SELECT_ANNOTATION,\n SET_ANNOTATION_MODE,\n SET_ANNOTATIONS,\n UPDATE_TOOL_DEFAULTS,\n AnnotationAction,\n PURGE_ANNOTATION,\n STORE_PDF_ID,\n REINDEX_PAGE_ANNOTATIONS,\n} from './actions';\nimport { AnnotationPluginConfig, AnnotationState, TrackedAnnotation } from './types';\nimport { makeUid } from './utils';\n\n/* ─────────── util helpers ─────────── */\nconst DEFAULT_COLORS = [\n '#E44234',\n '#FF8D00',\n '#FFCD45',\n '#5CC96E',\n '#25D2D1',\n '#597CE2',\n '#C544CE',\n '#7D2E25',\n];\n\n/* helper to immutably replace one annotation (preserving pdfId) */\nconst patchAnno = (\n state: AnnotationState,\n uid: string,\n patch: Partial<TrackedAnnotation['object']>,\n): AnnotationState => {\n const prev = state.byUid[uid];\n if (!prev) return state;\n return {\n ...state,\n byUid: {\n ...state.byUid,\n [uid]: {\n ...prev,\n commitState: prev.commitState === 'synced' ? 'dirty' : prev.commitState,\n object: { ...prev.object, ...patch },\n } as TrackedAnnotation,\n },\n hasPendingChanges: true,\n };\n};\n\n/* ─────────── initialState ─────────── */\nexport const initialState = (cfg: AnnotationPluginConfig): AnnotationState => ({\n pages: {},\n byUid: {},\n selectedUid: null,\n annotationMode: null,\n\n toolDefaults: {\n [PdfAnnotationSubtype.HIGHLIGHT]: {\n name: 'Highlight',\n color: '#FFCD45',\n opacity: 1,\n interaction: { mode: 'highlight', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.UNDERLINE]: {\n name: 'Underline',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'underline', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.STRIKEOUT]: {\n name: 'Strikeout',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'strikeout', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.SQUIGGLY]: {\n name: 'Squiggly',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'squiggly', exclusive: false },\n textSelection: true,\n },\n ...cfg.toolDefaults,\n },\n colorPresets: cfg.colorPresets ?? DEFAULT_COLORS,\n hasPendingChanges: false,\n});\n\n/* ─────────── reducer ─────────── */\nexport const reducer: Reducer<AnnotationState, AnnotationAction> = (state, action) => {\n switch (action.type) {\n /* ───── bulk load from engine ───── */\n case SET_ANNOTATIONS: {\n const newPages = { ...state.pages };\n const newByUid = { ...state.byUid };\n for (const [pgStr, list] of Object.entries(action.payload)) {\n const pageIndex = Number(pgStr);\n const oldUidsOnPage = state.pages[pageIndex] || [];\n for (const uid of oldUidsOnPage) {\n delete newByUid[uid];\n }\n const newUidsOnPage = list.map((a, index) => {\n const localId = Date.now() + Math.random() + index;\n const uid = makeUid(pageIndex, localId);\n newByUid[uid] = { localId, pdfId: a.id, commitState: 'synced', object: a };\n return uid;\n });\n newPages[pageIndex] = newUidsOnPage;\n }\n return { ...state, pages: newPages, byUid: newByUid };\n }\n\n /* ───── GUI bits ───── */\n case SET_ANNOTATION_MODE:\n return { ...state, annotationMode: action.payload };\n case SELECT_ANNOTATION:\n return {\n ...state,\n selectedUid: makeUid(action.payload.pageIndex, action.payload.localId),\n };\n case DESELECT_ANNOTATION:\n return { ...state, selectedUid: null };\n\n case ADD_COLOR_PRESET:\n return state.colorPresets.includes(action.payload)\n ? state\n : { ...state, colorPresets: [...state.colorPresets, action.payload] };\n\n case UPDATE_TOOL_DEFAULTS: {\n const { subtype, patch } = action.payload;\n return {\n ...state,\n toolDefaults: {\n ...state.toolDefaults,\n [subtype]: { ...state.toolDefaults[subtype], ...patch },\n },\n };\n }\n\n /* ───── create ───── */\n case CREATE_ANNOTATION: {\n const { pageIndex, localId, annotation } = action.payload;\n const uid = makeUid(pageIndex, localId);\n\n return {\n ...state,\n pages: { ...state.pages, [pageIndex]: [...(state.pages[pageIndex] ?? []), uid] },\n byUid: {\n ...state.byUid,\n [uid]: { localId, pdfId: undefined, commitState: 'new', object: annotation },\n },\n hasPendingChanges: true,\n };\n }\n\n /* ───── delete ───── */\n case DELETE_ANNOTATION: {\n const { pageIndex, localId } = action.payload;\n const uid = makeUid(pageIndex, localId);\n if (!state.byUid[uid]) return state;\n\n /* keep the object but mark it as deleted */\n return {\n ...state,\n pages: {\n ...state.pages,\n [pageIndex]: (state.pages[pageIndex] ?? []).filter((u) => u !== uid),\n },\n byUid: {\n ...state.byUid,\n [uid]: { ...state.byUid[uid], commitState: 'deleted' },\n },\n hasPendingChanges: true,\n };\n }\n\n /* ───── field edits ───── */\n case PATCH_ANNOTATION: {\n const uid = makeUid(action.payload.pageIndex, action.payload.localId);\n return patchAnno(state, uid, action.payload.patch);\n }\n\n /* ───── commit bookkeeping ───── */\n case COMMIT_PENDING_CHANGES: {\n const cleaned: AnnotationState['byUid'] = {};\n for (const [uid, ta] of Object.entries(state.byUid)) {\n cleaned[uid] = {\n ...ta,\n commitState:\n ta.commitState === 'dirty' || ta.commitState === 'new' ? 'synced' : ta.commitState,\n };\n }\n return { ...state, byUid: cleaned, hasPendingChanges: false };\n }\n\n case REINDEX_PAGE_ANNOTATIONS: {\n const { pageIndex } = action.payload;\n const newByUid = { ...state.byUid };\n\n const uidsOnPage = state.pages[pageIndex] || [];\n const annosOnPage = uidsOnPage\n .map((uid) => state.byUid[uid])\n .filter((ta) => ta && ta.commitState !== 'deleted'); // Filter out annotations pending deletion\n\n // CORRECTED: Sort by the existing pdfId to maintain relative order.\n annosOnPage.sort((a, b) => (a.pdfId ?? Infinity) - (b.pdfId ?? Infinity));\n\n // Update the pdfId for each annotation based on its new sorted index\n annosOnPage.forEach((ta, newPdfId) => {\n const uid = makeUid(pageIndex, ta.localId);\n newByUid[uid] = { ...newByUid[uid], pdfId: newPdfId };\n });\n\n return { ...state, byUid: newByUid };\n }\n\n case STORE_PDF_ID: {\n const { uid, pdfId } = action.payload;\n\n const ta = state.byUid[uid];\n if (!ta) return state;\n return {\n ...state,\n byUid: {\n ...state.byUid,\n [uid]: { ...ta, pdfId, commitState: 'synced' },\n },\n };\n }\n\n case PURGE_ANNOTATION: {\n const { uid } = action.payload;\n const { [uid]: _gone, ...rest } = state.byUid;\n return { ...state, byUid: rest };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ANNOTATION_PLUGIN_ID } from './manifest';\nimport { AnnotationPluginConfig, AnnotationState } from './types';\nimport { AnnotationPlugin } from './annotation-plugin';\nimport { initialState, reducer } from './reducer';\nimport { AnnotationAction } from './actions';\n\nexport const AnnotationPluginPackage: PluginPackage<\n AnnotationPlugin,\n AnnotationPluginConfig,\n AnnotationState,\n AnnotationAction\n> = {\n manifest,\n create: (registry, engine, config) =>\n new AnnotationPlugin(ANNOTATION_PLUGIN_ID, registry, engine, config),\n reducer,\n initialState: (_, config) => initialState(config),\n};\n\nexport * from './annotation-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './selectors';\n"],"mappings":"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","names":["makeUid","task","import_models"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/manifest.ts","../src/lib/annotation-plugin.ts","../src/lib/actions.ts","../src/lib/utils.ts","../src/lib/selectors.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { PluginManifest } from '@embedpdf/core';\nimport { AnnotationPluginConfig } from './types';\n\nexport const ANNOTATION_PLUGIN_ID = 'annotation';\n\nexport const manifest: PluginManifest<AnnotationPluginConfig> = {\n id: ANNOTATION_PLUGIN_ID,\n name: 'Annotation Plugin',\n version: '1.0.0',\n provides: ['annotation'],\n requires: ['interaction-manager', 'selection'],\n optional: ['history'],\n defaultConfig: {\n enabled: true,\n autoCommit: true,\n },\n};\n","import {\n BasePlugin,\n createBehaviorEmitter,\n enumEntries,\n PluginRegistry,\n SET_DOCUMENT,\n} from '@embedpdf/core';\nimport {\n ignore,\n PdfAnnotationObject,\n PdfDocumentObject,\n PdfEngine,\n PdfErrorReason,\n Task,\n PdfAnnotationSubtype,\n PdfTaskHelper,\n PdfErrorCode,\n PdfTask,\n Rotation,\n AppearanceMode,\n} from '@embedpdf/models';\nimport {\n ActiveTool,\n AnnotationCapability,\n AnnotationPluginConfig,\n AnnotationState,\n BaseAnnotationDefaults,\n GetPageAnnotationsOptions,\n RenderAnnotationOptions,\n StylableSubtype,\n ToolDefaultsBySubtype,\n TrackedAnnotation,\n} from './types';\nimport {\n setAnnotations,\n selectAnnotation,\n deselectAnnotation,\n setAnnotationMode,\n AnnotationAction,\n updateToolDefaults,\n addColorPreset,\n createAnnotation,\n patchAnnotation,\n deleteAnnotation,\n commitPendingChanges,\n storePdfId,\n purgeAnnotation,\n reindexPageAnnotations,\n} from './actions';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n InteractionMode,\n} from '@embedpdf/plugin-interaction-manager';\nimport { SelectionPlugin, SelectionCapability } from '@embedpdf/plugin-selection';\nimport { HistoryPlugin, HistoryCapability, Command } from '@embedpdf/plugin-history';\nimport { getSelectedAnnotation } from './selectors';\nimport { makeUid, parseUid } from './utils';\n\nexport class AnnotationPlugin extends BasePlugin<\n AnnotationPluginConfig,\n AnnotationCapability,\n AnnotationState,\n AnnotationAction\n> {\n static readonly id = 'annotation' as const;\n\n private readonly ANNOTATION_HISTORY_TOPIC = 'annotations';\n\n private readonly config: AnnotationPluginConfig;\n\n private engine: PdfEngine;\n private readonly state$ = createBehaviorEmitter<AnnotationState>();\n private readonly interactionManager: InteractionManagerCapability | null;\n private readonly selection: SelectionCapability | null;\n private readonly history: HistoryCapability | null;\n\n /** Map <subtype> → <modeId>. Filled once in `initialize()`. */\n private readonly modeBySubtype = new Map<StylableSubtype, string>();\n /** The inverse map for quick lookup in onModeChange(). */\n private readonly subtypeByMode = new Map<string, StylableSubtype>();\n private readonly modeChange$ = createBehaviorEmitter<StylableSubtype | null>();\n private readonly activeTool$ = createBehaviorEmitter<ActiveTool>({\n mode: null,\n defaults: null,\n });\n\n constructor(\n id: string,\n registry: PluginRegistry,\n engine: PdfEngine,\n config: AnnotationPluginConfig,\n ) {\n super(id, registry);\n this.engine = engine;\n this.config = config;\n\n const selection = registry.getPlugin<SelectionPlugin>('selection');\n this.selection = selection?.provides() ?? null;\n\n const history = registry.getPlugin<HistoryPlugin>('history');\n this.history = history?.provides() ?? null;\n\n const interactionManager = registry.getPlugin<InteractionManagerPlugin>('interaction-manager');\n this.interactionManager = interactionManager?.provides() ?? null;\n\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n const doc = state.core.document;\n if (doc) {\n this.getAllAnnotations(doc);\n }\n });\n }\n\n async initialize(): Promise<void> {\n for (const [subtype, defaults] of enumEntries(this.state.toolDefaults)) {\n this.registerTool(subtype, defaults);\n }\n\n this.history?.onHistoryChange((topic) => {\n if (topic === this.ANNOTATION_HISTORY_TOPIC && this.config.autoCommit !== false) {\n this.commit();\n }\n });\n\n this.interactionManager?.onModeChange((s) => {\n const newSubtype = this.subtypeByMode.get(s.activeMode) ?? null;\n if (newSubtype !== this.state.annotationMode) {\n this.dispatch(setAnnotationMode(newSubtype));\n this.modeChange$.emit(newSubtype);\n }\n });\n\n this.selection?.onEndSelection(() => {\n if (!this.state.annotationMode) return;\n\n if (\n !(\n this.state.annotationMode === PdfAnnotationSubtype.HIGHLIGHT ||\n this.state.annotationMode === PdfAnnotationSubtype.UNDERLINE ||\n this.state.annotationMode === PdfAnnotationSubtype.STRIKEOUT ||\n this.state.annotationMode === PdfAnnotationSubtype.SQUIGGLY\n )\n ) {\n return;\n }\n\n const formattedSelection = this.selection?.getFormattedSelection();\n if (!formattedSelection) return;\n\n for (const selection of formattedSelection) {\n const rect = selection.rect;\n const segmentRects = selection.segmentRects;\n const type = this.state.annotationMode;\n const color = this.state.toolDefaults[type].color;\n const opacity = this.state.toolDefaults[type].opacity;\n\n this.createAnnotation(selection.pageIndex, {\n type,\n rect,\n segmentRects,\n color,\n opacity,\n pageIndex: selection.pageIndex,\n id: Date.now() + Math.random(),\n });\n }\n\n this.selection?.clear();\n });\n }\n\n private registerTool(subtype: StylableSubtype, defaults: BaseAnnotationDefaults) {\n const modeId = defaults.interaction.mode;\n const interactionMode: InteractionMode = {\n id: modeId,\n scope: 'page',\n exclusive: defaults.interaction.exclusive,\n cursor: defaults.interaction.cursor,\n };\n\n this.interactionManager?.registerMode(interactionMode);\n\n if (defaults.textSelection) {\n this.selection?.enableForMode(modeId);\n }\n this.modeBySubtype.set(subtype, modeId);\n this.subtypeByMode.set(modeId, subtype);\n }\n\n protected buildCapability(): AnnotationCapability {\n return {\n getPageAnnotations: (options: GetPageAnnotationsOptions) => {\n return this.getPageAnnotations(options);\n },\n getSelectedAnnotation: () => {\n return getSelectedAnnotation(this.state);\n },\n selectAnnotation: (pageIndex: number, annotationId: number) => {\n this.selectAnnotation(pageIndex, annotationId);\n },\n deselectAnnotation: () => {\n this.dispatch(deselectAnnotation());\n },\n getAnnotationMode: () => {\n return this.state.annotationMode;\n },\n setAnnotationMode: (subtype: StylableSubtype | null) => {\n if (subtype === this.state.annotationMode) return;\n if (subtype) {\n const mode = this.modeBySubtype.get(subtype);\n if (!mode) throw new Error(`Mode missing for subtype ${subtype}`);\n this.interactionManager?.activate(mode);\n } else {\n this.interactionManager?.activate('default');\n }\n },\n getToolDefaults: (subtype) => {\n const defaults = this.state.toolDefaults[subtype];\n if (!defaults) {\n throw new Error(`No defaults found for subtype: ${subtype}`);\n }\n return defaults;\n },\n setToolDefaults: (subtype, patch) => {\n this.dispatch(updateToolDefaults(subtype, patch));\n },\n getColorPresets: () => [...this.state.colorPresets],\n addColorPreset: (color) => this.dispatch(addColorPreset(color)),\n createAnnotation: (pageIndex: number, annotation: PdfAnnotationObject) =>\n this.createAnnotation(pageIndex, annotation),\n updateAnnotation: (pageIndex: number, localId: number, patch: Partial<PdfAnnotationObject>) =>\n this.updateAnnotation(pageIndex, localId, patch),\n deleteAnnotation: (pageIndex: number, localId: number) =>\n this.deleteAnnotation(pageIndex, localId),\n renderAnnotation: (options: RenderAnnotationOptions) => this.renderAnnotation(options),\n onStateChange: this.state$.on,\n onModeChange: this.modeChange$.on,\n onActiveToolChange: this.activeTool$.on,\n commit: () => this.commit(),\n };\n }\n\n private createActiveTool(\n mode: StylableSubtype | null,\n toolDefaults: ToolDefaultsBySubtype,\n ): ActiveTool {\n if (mode === null) {\n return { mode: null, defaults: null };\n }\n return { mode, defaults: toolDefaults[mode] } as ActiveTool;\n }\n\n private emitActiveTool(state: AnnotationState) {\n const activeTool = this.createActiveTool(state.annotationMode, state.toolDefaults);\n this.activeTool$.emit(activeTool);\n }\n\n override onStoreUpdated(prev: AnnotationState, next: AnnotationState): void {\n this.state$.emit(next);\n if (\n prev.annotationMode !== next.annotationMode ||\n prev.toolDefaults[prev.annotationMode ?? PdfAnnotationSubtype.HIGHLIGHT] !==\n next.toolDefaults[next.annotationMode ?? PdfAnnotationSubtype.HIGHLIGHT]\n ) {\n this.emitActiveTool(next);\n }\n }\n\n private getAllAnnotations(doc: PdfDocumentObject) {\n const task = this.engine.getAllAnnotations(doc);\n task.wait((annotations) => this.dispatch(setAnnotations(annotations)), ignore);\n }\n\n private getPageAnnotations(\n options: GetPageAnnotationsOptions,\n ): Task<PdfAnnotationObject[], PdfErrorReason> {\n const { pageIndex } = options;\n\n const doc = this.coreState.core.document;\n\n if (!doc) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n }\n\n const page = doc.pages.find((p) => p.index === pageIndex);\n\n if (!page) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Page not found' });\n }\n\n return this.engine.getPageAnnotations(doc, page);\n }\n\n private renderAnnotation({\n pageIndex,\n annotation,\n scaleFactor = 1,\n rotation = Rotation.Degree0,\n dpr = 1,\n mode = AppearanceMode.Normal,\n imageType = 'image/webp',\n }: RenderAnnotationOptions) {\n const coreState = this.coreState.core;\n\n if (!coreState.document) {\n throw new Error('document does not open');\n }\n\n const page = coreState.document.pages.find((page) => page.index === pageIndex);\n if (!page) {\n throw new Error('page does not exist');\n }\n\n return this.engine.renderAnnotation(\n coreState.document,\n page,\n annotation,\n scaleFactor,\n rotation,\n dpr,\n mode,\n imageType,\n );\n }\n\n private selectAnnotation(pageIndex: number, annotationId: number) {\n this.dispatch(selectAnnotation(pageIndex, annotationId));\n }\n\n private createAnnotation(pageIndex: number, annotation: PdfAnnotationObject) {\n const localId = annotation.id;\n const execute = () => this.dispatch(createAnnotation(pageIndex, localId, annotation));\n\n if (!this.history) {\n execute();\n if (this.config.autoCommit) this.commit();\n return;\n }\n const command: Command = {\n execute,\n undo: () => {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n },\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private updateAnnotation(\n pageIndex: number,\n localId: number,\n patch: Partial<PdfAnnotationObject>,\n ) {\n if (!this.history) {\n this.dispatch(patchAnnotation(pageIndex, localId, patch));\n if (this.config.autoCommit !== false) {\n this.commit();\n }\n return;\n }\n const originalObject = this.state.byUid[makeUid(pageIndex, localId)].object;\n const originalPatch = Object.fromEntries(\n Object.keys(patch).map((key) => [key, originalObject[key as keyof PdfAnnotationObject]]),\n );\n const command: Command = {\n execute: () => this.dispatch(patchAnnotation(pageIndex, localId, patch)),\n undo: () => this.dispatch(patchAnnotation(pageIndex, localId, originalPatch)),\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private deleteAnnotation(pageIndex: number, localId: number) {\n if (!this.history) {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n if (this.config.autoCommit !== false) {\n this.commit();\n }\n return;\n }\n const originalAnnotation = this.state.byUid[makeUid(pageIndex, localId)].object;\n const command: Command = {\n execute: () => {\n this.dispatch(deselectAnnotation());\n this.dispatch(deleteAnnotation(pageIndex, localId));\n },\n undo: () => this.dispatch(createAnnotation(pageIndex, localId, originalAnnotation)),\n };\n this.history.register(command, this.ANNOTATION_HISTORY_TOPIC);\n }\n\n private commit(): Task<boolean, PdfErrorReason> {\n const task = new Task<boolean, PdfErrorReason>();\n\n if (!this.state.hasPendingChanges) return PdfTaskHelper.resolve(true);\n\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n const creations: Task<any, PdfErrorReason>[] = [];\n const updates: Task<any, PdfErrorReason>[] = [];\n const deletionsByPage = new Map<number, { ta: TrackedAnnotation; uid: string }[]>();\n const affectedPages = new Set<number>();\n\n // 1. Group all pending changes by operation type\n for (const [uid, ta] of Object.entries(this.state.byUid)) {\n if (ta.commitState === 'synced') continue;\n\n const { pageIndex } = parseUid(uid);\n const page = doc.pages.find((p) => p.index === pageIndex);\n if (!page) continue;\n\n affectedPages.add(pageIndex);\n\n switch (ta.commitState) {\n case 'new':\n const task = this.engine.createPageAnnotation!(doc, page, ta.object);\n task.wait((annoId) => this.dispatch(storePdfId(uid, annoId)), ignore);\n creations.push(task);\n break;\n case 'dirty':\n updates.push(\n this.engine.updatePageAnnotation!(doc, page, { ...ta.object, id: ta.pdfId! }),\n );\n break;\n case 'deleted':\n if (!deletionsByPage.has(pageIndex)) {\n deletionsByPage.set(pageIndex, []);\n }\n deletionsByPage.get(pageIndex)!.push({ ta, uid });\n break;\n }\n }\n\n // 2. Create deletion tasks, sorted by ID descending\n const deletionTasks: Task<any, PdfErrorReason>[] = [];\n for (const [pageIndex, deletions] of deletionsByPage.entries()) {\n const page = doc.pages.find((p) => p.index === pageIndex)!;\n\n deletions.sort((a, b) => (b.ta.pdfId ?? -1) - (a.ta.pdfId ?? -1));\n\n for (const { ta, uid } of deletions) {\n if (ta.pdfId !== undefined) {\n const task = new Task<any, PdfErrorReason>();\n const removeTask = this.engine.removePageAnnotation!(doc, page, {\n ...ta.object,\n id: ta.pdfId!,\n });\n removeTask.wait(() => {\n this.dispatch(purgeAnnotation(uid));\n task.resolve(true);\n }, task.fail);\n deletionTasks.push(task);\n } else {\n this.dispatch(purgeAnnotation(uid));\n }\n }\n }\n\n // 3. Chain the operations: creations/updates -> deletions -> re-sync\n const allWriteTasks = [...creations, ...updates, ...deletionTasks];\n\n Task.allSettled(allWriteTasks).wait(() => {\n // 4. Client-Side Re-indexing\n // After all engine operations are done, tell the reducer to re-index each affected page.\n for (const pageIndex of affectedPages) {\n this.dispatch(reindexPageAnnotations(pageIndex));\n }\n\n // 5. Finalize the commit by updating the commitState of all items.\n this.dispatch(commitPendingChanges());\n task.resolve(true);\n }, task.fail);\n\n return task;\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { PdfAnnotationObject } from '@embedpdf/models';\nimport { StylableSubtype, ToolDefaultsBySubtype } from './types';\n\n/* ─────────── action constants ─────────── */\nexport const SET_ANNOTATIONS = 'ANNOTATION/SET_ANNOTATIONS';\nexport const REINDEX_PAGE_ANNOTATIONS = 'ANNOTATION/REINDEX_PAGE';\nexport const SELECT_ANNOTATION = 'ANNOTATION/SELECT_ANNOTATION';\nexport const DESELECT_ANNOTATION = 'ANNOTATION/DESELECT_ANNOTATION';\nexport const SET_ANNOTATION_MODE = 'ANNOTATION/SET_ANNOTATION_MODE';\nexport const UPDATE_TOOL_DEFAULTS = 'ANNOTATION/UPDATE_TOOL_DEFAULTS';\nexport const ADD_COLOR_PRESET = 'ANNOTATION/ADD_COLOR_PRESET';\nexport const CREATE_ANNOTATION = 'ANNOTATION/CREATE_ANNOTATION';\nexport const PATCH_ANNOTATION = 'ANNOTATION/PATCH_ANNOTATION';\nexport const DELETE_ANNOTATION = 'ANNOTATION/DELETE_ANNOTATION';\nexport const COMMIT_PENDING_CHANGES = 'ANNOTATION/COMMIT';\nexport const STORE_PDF_ID = 'ANNOTATION/STORE_PDF_ID';\nexport const PURGE_ANNOTATION = 'ANNOTATION/PURGE_ANNOTATION';\n\n/* ─────────── action interfaces ─────────── */\nexport interface SetAnnotationsAction extends Action {\n type: typeof SET_ANNOTATIONS;\n payload: Record<number, PdfAnnotationObject[]>;\n}\nexport interface ReindexPageAnnotationsAction extends Action {\n type: typeof REINDEX_PAGE_ANNOTATIONS;\n payload: { pageIndex: number };\n}\nexport interface SelectAnnotationAction extends Action {\n type: typeof SELECT_ANNOTATION;\n payload: { pageIndex: number; localId: number };\n}\nexport interface DeselectAnnotationAction extends Action {\n type: typeof DESELECT_ANNOTATION;\n}\nexport interface SetAnnotationModeAction extends Action {\n type: typeof SET_ANNOTATION_MODE;\n payload: StylableSubtype | null;\n}\n\nexport interface UpdateToolDefaultsAction extends Action {\n type: typeof UPDATE_TOOL_DEFAULTS;\n payload: { subtype: StylableSubtype; patch: Partial<ToolDefaultsBySubtype[StylableSubtype]> };\n}\n\nexport interface AddColorPresetAction extends Action {\n type: typeof ADD_COLOR_PRESET;\n payload: string;\n}\nexport interface CreateAnnotationAction extends Action {\n type: typeof CREATE_ANNOTATION;\n payload: { pageIndex: number; localId: number; annotation: PdfAnnotationObject };\n}\nexport interface PatchAnnotationAction extends Action {\n type: typeof PATCH_ANNOTATION;\n payload: { pageIndex: number; localId: number; patch: Partial<PdfAnnotationObject> };\n}\nexport interface DeleteAnnotationAction extends Action {\n type: typeof DELETE_ANNOTATION;\n payload: { pageIndex: number; localId: number };\n}\nexport interface CommitAction extends Action {\n type: typeof COMMIT_PENDING_CHANGES;\n}\n\nexport interface StorePdfIdAction extends Action {\n type: typeof STORE_PDF_ID;\n payload: { uid: string; pdfId: number };\n}\n\nexport interface PurgeAnnotationAction extends Action {\n type: typeof PURGE_ANNOTATION;\n payload: { uid: string };\n}\n\nexport type AnnotationAction =\n | SetAnnotationsAction\n | ReindexPageAnnotationsAction\n | SelectAnnotationAction\n | DeselectAnnotationAction\n | SetAnnotationModeAction\n | UpdateToolDefaultsAction\n | AddColorPresetAction\n | CreateAnnotationAction\n | PatchAnnotationAction\n | DeleteAnnotationAction\n | CommitAction\n | StorePdfIdAction\n | PurgeAnnotationAction;\n\n/* ─────────── action creators ─────────── */\nexport const setAnnotations = (p: Record<number, PdfAnnotationObject[]>): SetAnnotationsAction => ({\n type: SET_ANNOTATIONS,\n payload: p,\n});\n\nexport const reindexPageAnnotations = (pageIndex: number): ReindexPageAnnotationsAction => ({\n type: REINDEX_PAGE_ANNOTATIONS,\n payload: { pageIndex },\n});\n\nexport const selectAnnotation = (pageIndex: number, localId: number): SelectAnnotationAction => ({\n type: SELECT_ANNOTATION,\n payload: { pageIndex, localId },\n});\n\nexport const deselectAnnotation = (): DeselectAnnotationAction => ({ type: DESELECT_ANNOTATION });\n\nexport const setAnnotationMode = (m: StylableSubtype | null): SetAnnotationModeAction => ({\n type: SET_ANNOTATION_MODE,\n payload: m,\n});\n\nexport const updateToolDefaults = <S extends StylableSubtype>(\n subtype: S,\n patch: Partial<ToolDefaultsBySubtype[S]>,\n): UpdateToolDefaultsAction => ({ type: UPDATE_TOOL_DEFAULTS, payload: { subtype, patch } });\n\nexport const addColorPreset = (c: string): AddColorPresetAction => ({\n type: ADD_COLOR_PRESET,\n payload: c,\n});\n\nexport const createAnnotation = (\n pageIndex: number,\n localId: number,\n annotation: PdfAnnotationObject,\n): CreateAnnotationAction => ({\n type: CREATE_ANNOTATION,\n payload: { pageIndex, localId, annotation },\n});\n\nexport const patchAnnotation = (\n pageIndex: number,\n localId: number,\n patch: Partial<PdfAnnotationObject>,\n): PatchAnnotationAction => ({\n type: PATCH_ANNOTATION,\n payload: { pageIndex, localId, patch },\n});\n\nexport const deleteAnnotation = (pageIndex: number, localId: number): DeleteAnnotationAction => ({\n type: DELETE_ANNOTATION,\n payload: { pageIndex, localId },\n});\n\nexport const commitPendingChanges = (): CommitAction => ({ type: COMMIT_PENDING_CHANGES });\n\nexport const storePdfId = (uid: string, pdfId: number): StorePdfIdAction => ({\n type: STORE_PDF_ID,\n payload: { uid, pdfId },\n});\n\nexport const purgeAnnotation = (uid: string): PurgeAnnotationAction => ({\n type: PURGE_ANNOTATION,\n payload: { uid },\n});\n","/**\n * Creates a stable, document-wide unique ID from a page index and a stable local ID.\n */\nexport const makeUid = (pageIndex: number, localId: number): string => `p${pageIndex}#${localId}`;\n\n/**\n * Parses a UID string back into its constituent page index and stable local ID.\n */\nexport const parseUid = (uid: string): { pageIndex: number; localId: number } => {\n const [pg, rest] = uid.slice(1).split('#');\n return { pageIndex: Number(pg), localId: Number(rest) };\n};\n","import { AnnotationState, SelectedAnnotation } from './types';\nimport { parseUid } from './utils';\n\n/* helper – mirrors the one in reducer */\nconst makeUid = (page: number, id: number) => `p${page}#${id}`;\n\n/* ─────────── public selectors ─────────── */\n\n/** All annotations _objects_ on a single page (order preserved). */\nexport const getAnnotationsByPageIndex = (s: AnnotationState, page: number) =>\n (s.pages[page] ?? []).map((uid) => s.byUid[uid]);\n\n/** Shortcut: every page → list of annotation objects. */\nexport const getAnnotations = (s: AnnotationState) => {\n const out: Record<number, ReturnType<typeof getAnnotationsByPageIndex>> = {};\n for (const p of Object.keys(s.pages).map(Number)) out[p] = getAnnotationsByPageIndex(s, p);\n return out;\n};\n\n/** The full `TrackedAnnotation` for the current selection. */\nexport const getSelectedAnnotation = (s: AnnotationState) =>\n s.selectedUid ? s.byUid[s.selectedUid] : null;\n\nexport const getSelectedAnnotationWithPageIndex = (\n s: AnnotationState,\n): SelectedAnnotation | null => {\n if (!s.selectedUid) return null;\n const { pageIndex, localId } = parseUid(s.selectedUid);\n return { pageIndex, localId, annotation: s.byUid[s.selectedUid].object };\n};\n\nexport const getSelectedAnnotationByPageIndex = (s: AnnotationState, pageIndex: number) => {\n if (!s.selectedUid) return null;\n\n const pageUids = s.pages[pageIndex] ?? [];\n\n // Check if the selected UID is on the requested page\n if (pageUids.includes(s.selectedUid)) {\n return s.byUid[s.selectedUid];\n }\n\n return null;\n};\n\nexport const isInAnnotationMode = (s: AnnotationState) => s.annotationMode !== null;\nexport const getSelectedAnnotationMode = (s: AnnotationState) => s.annotationMode;\n\n/** Check if a given anno on a page is the current selection. */\nexport const isAnnotationSelected = (s: AnnotationState, page: number, id: number) =>\n s.selectedUid === makeUid(page, id);\n","import { Reducer } from '@embedpdf/core';\nimport { PdfAnnotationSubtype } from '@embedpdf/models';\nimport {\n ADD_COLOR_PRESET,\n COMMIT_PENDING_CHANGES,\n CREATE_ANNOTATION,\n DESELECT_ANNOTATION,\n PATCH_ANNOTATION,\n DELETE_ANNOTATION,\n SELECT_ANNOTATION,\n SET_ANNOTATION_MODE,\n SET_ANNOTATIONS,\n UPDATE_TOOL_DEFAULTS,\n AnnotationAction,\n PURGE_ANNOTATION,\n STORE_PDF_ID,\n REINDEX_PAGE_ANNOTATIONS,\n} from './actions';\nimport { AnnotationPluginConfig, AnnotationState, TrackedAnnotation } from './types';\nimport { makeUid } from './utils';\n\n/* ─────────── util helpers ─────────── */\nconst DEFAULT_COLORS = [\n '#E44234',\n '#FF8D00',\n '#FFCD45',\n '#5CC96E',\n '#25D2D1',\n '#597CE2',\n '#C544CE',\n '#7D2E25',\n];\n\n/* helper to immutably replace one annotation (preserving pdfId) */\nconst patchAnno = (\n state: AnnotationState,\n uid: string,\n patch: Partial<TrackedAnnotation['object']>,\n): AnnotationState => {\n const prev = state.byUid[uid];\n if (!prev) return state;\n return {\n ...state,\n byUid: {\n ...state.byUid,\n [uid]: {\n ...prev,\n commitState: prev.commitState === 'synced' ? 'dirty' : prev.commitState,\n object: { ...prev.object, ...patch },\n } as TrackedAnnotation,\n },\n hasPendingChanges: true,\n };\n};\n\n/* ─────────── initialState ─────────── */\nexport const initialState = (cfg: AnnotationPluginConfig): AnnotationState => ({\n pages: {},\n byUid: {},\n selectedUid: null,\n annotationMode: null,\n\n toolDefaults: {\n [PdfAnnotationSubtype.HIGHLIGHT]: {\n name: 'Highlight',\n color: '#FFCD45',\n opacity: 1,\n interaction: { mode: 'highlight', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.UNDERLINE]: {\n name: 'Underline',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'underline', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.STRIKEOUT]: {\n name: 'Strikeout',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'strikeout', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.SQUIGGLY]: {\n name: 'Squiggly',\n color: '#E44234',\n opacity: 1,\n interaction: { mode: 'squiggly', exclusive: false },\n textSelection: true,\n },\n [PdfAnnotationSubtype.INK]: {\n name: 'Ink',\n color: '#E44234',\n opacity: 1,\n strokeWidth: 11,\n interaction: { mode: 'ink', exclusive: true, cursor: 'crosshair' },\n textSelection: false,\n },\n ...cfg.toolDefaults,\n },\n colorPresets: cfg.colorPresets ?? DEFAULT_COLORS,\n hasPendingChanges: false,\n});\n\n/* ─────────── reducer ─────────── */\nexport const reducer: Reducer<AnnotationState, AnnotationAction> = (state, action) => {\n switch (action.type) {\n /* ───── bulk load from engine ───── */\n case SET_ANNOTATIONS: {\n const newPages = { ...state.pages };\n const newByUid = { ...state.byUid };\n for (const [pgStr, list] of Object.entries(action.payload)) {\n const pageIndex = Number(pgStr);\n const oldUidsOnPage = state.pages[pageIndex] || [];\n for (const uid of oldUidsOnPage) {\n delete newByUid[uid];\n }\n const newUidsOnPage = list.map((a, index) => {\n const localId = Date.now() + Math.random() + index;\n const uid = makeUid(pageIndex, localId);\n newByUid[uid] = { localId, pdfId: a.id, commitState: 'synced', object: a };\n return uid;\n });\n newPages[pageIndex] = newUidsOnPage;\n }\n return { ...state, pages: newPages, byUid: newByUid };\n }\n\n /* ───── GUI bits ───── */\n case SET_ANNOTATION_MODE:\n return { ...state, annotationMode: action.payload };\n case SELECT_ANNOTATION:\n return {\n ...state,\n selectedUid: makeUid(action.payload.pageIndex, action.payload.localId),\n };\n case DESELECT_ANNOTATION:\n return { ...state, selectedUid: null };\n\n case ADD_COLOR_PRESET:\n return state.colorPresets.includes(action.payload)\n ? state\n : { ...state, colorPresets: [...state.colorPresets, action.payload] };\n\n case UPDATE_TOOL_DEFAULTS: {\n const { subtype, patch } = action.payload;\n return {\n ...state,\n toolDefaults: {\n ...state.toolDefaults,\n [subtype]: { ...state.toolDefaults[subtype], ...patch },\n },\n };\n }\n\n /* ───── create ───── */\n case CREATE_ANNOTATION: {\n const { pageIndex, localId, annotation } = action.payload;\n const uid = makeUid(pageIndex, localId);\n\n return {\n ...state,\n pages: { ...state.pages, [pageIndex]: [...(state.pages[pageIndex] ?? []), uid] },\n byUid: {\n ...state.byUid,\n [uid]: { localId, pdfId: undefined, commitState: 'new', object: annotation },\n },\n hasPendingChanges: true,\n };\n }\n\n /* ───── delete ───── */\n case DELETE_ANNOTATION: {\n const { pageIndex, localId } = action.payload;\n const uid = makeUid(pageIndex, localId);\n if (!state.byUid[uid]) return state;\n\n /* keep the object but mark it as deleted */\n return {\n ...state,\n pages: {\n ...state.pages,\n [pageIndex]: (state.pages[pageIndex] ?? []).filter((u) => u !== uid),\n },\n byUid: {\n ...state.byUid,\n [uid]: { ...state.byUid[uid], commitState: 'deleted' },\n },\n hasPendingChanges: true,\n };\n }\n\n /* ───── field edits ───── */\n case PATCH_ANNOTATION: {\n const uid = makeUid(action.payload.pageIndex, action.payload.localId);\n return patchAnno(state, uid, action.payload.patch);\n }\n\n /* ───── commit bookkeeping ───── */\n case COMMIT_PENDING_CHANGES: {\n const cleaned: AnnotationState['byUid'] = {};\n for (const [uid, ta] of Object.entries(state.byUid)) {\n cleaned[uid] = {\n ...ta,\n commitState:\n ta.commitState === 'dirty' || ta.commitState === 'new' ? 'synced' : ta.commitState,\n };\n }\n return { ...state, byUid: cleaned, hasPendingChanges: false };\n }\n\n case REINDEX_PAGE_ANNOTATIONS: {\n const { pageIndex } = action.payload;\n const newByUid = { ...state.byUid };\n\n const uidsOnPage = state.pages[pageIndex] || [];\n const annosOnPage = uidsOnPage\n .map((uid) => state.byUid[uid])\n .filter((ta) => ta && ta.commitState !== 'deleted'); // Filter out annotations pending deletion\n\n // CORRECTED: Sort by the existing pdfId to maintain relative order.\n annosOnPage.sort((a, b) => (a.pdfId ?? Infinity) - (b.pdfId ?? Infinity));\n\n // Update the pdfId for each annotation based on its new sorted index\n annosOnPage.forEach((ta, newPdfId) => {\n const uid = makeUid(pageIndex, ta.localId);\n newByUid[uid] = { ...newByUid[uid], pdfId: newPdfId };\n });\n\n return { ...state, byUid: newByUid };\n }\n\n case STORE_PDF_ID: {\n const { uid, pdfId } = action.payload;\n\n const ta = state.byUid[uid];\n if (!ta) return state;\n return {\n ...state,\n byUid: {\n ...state.byUid,\n [uid]: { ...ta, pdfId, commitState: 'synced' },\n },\n };\n }\n\n case PURGE_ANNOTATION: {\n const { uid } = action.payload;\n const { [uid]: _gone, ...rest } = state.byUid;\n return { ...state, byUid: rest };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ANNOTATION_PLUGIN_ID } from './manifest';\nimport { AnnotationPluginConfig, AnnotationState } from './types';\nimport { AnnotationPlugin } from './annotation-plugin';\nimport { initialState, reducer } from './reducer';\nimport { AnnotationAction } from './actions';\n\nexport const AnnotationPluginPackage: PluginPackage<\n AnnotationPlugin,\n AnnotationPluginConfig,\n AnnotationState,\n AnnotationAction\n> = {\n manifest,\n create: (registry, engine, config) =>\n new AnnotationPlugin(ANNOTATION_PLUGIN_ID, registry, engine, config),\n reducer,\n initialState: (_, config) => initialState(config),\n};\n\nexport * from './annotation-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './selectors';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,uBAAuB;AAE7B,IAAM,WAAmD;AAAA,EAC9D,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,CAAC,YAAY;AAAA,EACvB,UAAU,CAAC,uBAAuB,WAAW;AAAA,EAC7C,UAAU,CAAC,SAAS;AAAA,EACpB,eAAe;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AACF;;;AChBA,kBAMO;AACP,oBAaO;;;ACfA,IAAM,kBAAkB;AACxB,IAAM,2BAA2B;AACjC,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,yBAAyB;AAC/B,IAAM,eAAe;AACrB,IAAM,mBAAmB;AA0EzB,IAAM,iBAAiB,CAAC,OAAoE;AAAA,EACjG,MAAM;AAAA,EACN,SAAS;AACX;AAEO,IAAM,yBAAyB,CAAC,eAAqD;AAAA,EAC1F,MAAM;AAAA,EACN,SAAS,EAAE,UAAU;AACvB;AAEO,IAAM,mBAAmB,CAAC,WAAmB,aAA6C;AAAA,EAC/F,MAAM;AAAA,EACN,SAAS,EAAE,WAAW,QAAQ;AAChC;AAEO,IAAM,qBAAqB,OAAiC,EAAE,MAAM,oBAAoB;AAExF,IAAM,oBAAoB,CAAC,OAAwD;AAAA,EACxF,MAAM;AAAA,EACN,SAAS;AACX;AAEO,IAAM,qBAAqB,CAChC,SACA,WAC8B,EAAE,MAAM,sBAAsB,SAAS,EAAE,SAAS,MAAM,EAAE;AAEnF,IAAM,iBAAiB,CAAC,OAAqC;AAAA,EAClE,MAAM;AAAA,EACN,SAAS;AACX;AAEO,IAAM,mBAAmB,CAC9B,WACA,SACA,gBAC4B;AAAA,EAC5B,MAAM;AAAA,EACN,SAAS,EAAE,WAAW,SAAS,WAAW;AAC5C;AAEO,IAAM,kBAAkB,CAC7B,WACA,SACA,WAC2B;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS,EAAE,WAAW,SAAS,MAAM;AACvC;AAEO,IAAM,mBAAmB,CAAC,WAAmB,aAA6C;AAAA,EAC/F,MAAM;AAAA,EACN,SAAS,EAAE,WAAW,QAAQ;AAChC;AAEO,IAAM,uBAAuB,OAAqB,EAAE,MAAM,uBAAuB;AAEjF,IAAM,aAAa,CAAC,KAAa,WAAqC;AAAA,EAC3E,MAAM;AAAA,EACN,SAAS,EAAE,KAAK,MAAM;AACxB;AAEO,IAAM,kBAAkB,CAAC,SAAwC;AAAA,EACtE,MAAM;AAAA,EACN,SAAS,EAAE,IAAI;AACjB;;;ACzJO,IAAM,UAAU,CAAC,WAAmB,YAA4B,IAAI,SAAS,IAAI,OAAO;AAKxF,IAAM,WAAW,CAAC,QAAwD;AAC/E,QAAM,CAAC,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG;AACzC,SAAO,EAAE,WAAW,OAAO,EAAE,GAAG,SAAS,OAAO,IAAI,EAAE;AACxD;;;ACPA,IAAMA,WAAU,CAAC,MAAc,OAAe,IAAI,IAAI,IAAI,EAAE;AAKrD,IAAM,4BAA4B,CAAC,GAAoB,UAC3D,EAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC;AAG1C,IAAM,iBAAiB,CAAC,MAAuB;AACpD,QAAM,MAAoE,CAAC;AAC3E,aAAW,KAAK,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,MAAM,EAAG,KAAI,CAAC,IAAI,0BAA0B,GAAG,CAAC;AACzF,SAAO;AACT;AAGO,IAAM,wBAAwB,CAAC,MACpC,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,IAAI;AAEpC,IAAM,qCAAqC,CAChD,MAC8B;AAC9B,MAAI,CAAC,EAAE,YAAa,QAAO;AAC3B,QAAM,EAAE,WAAW,QAAQ,IAAI,SAAS,EAAE,WAAW;AACrD,SAAO,EAAE,WAAW,SAAS,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO;AACzE;AAEO,IAAM,mCAAmC,CAAC,GAAoB,cAAsB;AACzF,MAAI,CAAC,EAAE,YAAa,QAAO;AAE3B,QAAM,WAAW,EAAE,MAAM,SAAS,KAAK,CAAC;AAGxC,MAAI,SAAS,SAAS,EAAE,WAAW,GAAG;AACpC,WAAO,EAAE,MAAM,EAAE,WAAW;AAAA,EAC9B;AAEA,SAAO;AACT;AAEO,IAAM,qBAAqB,CAAC,MAAuB,EAAE,mBAAmB;AACxE,IAAM,4BAA4B,CAAC,MAAuB,EAAE;AAG5D,IAAM,uBAAuB,CAAC,GAAoB,MAAc,OACrE,EAAE,gBAAgBA,SAAQ,MAAM,EAAE;;;AHU7B,IAAM,mBAAN,cAA+B,uBAKpC;AAAA,EAuBA,YACE,IACA,UACA,QACA,QACA;AACA,UAAM,IAAI,QAAQ;AA1BpB,SAAiB,2BAA2B;AAK5C,SAAiB,aAAS,mCAAuC;AAMjE;AAAA,SAAiB,gBAAgB,oBAAI,IAA6B;AAElE;AAAA,SAAiB,gBAAgB,oBAAI,IAA6B;AAClE,SAAiB,kBAAc,mCAA8C;AAC7E,SAAiB,kBAAc,mCAAkC;AAAA,MAC/D,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AASC,SAAK,SAAS;AACd,SAAK,SAAS;AAEd,UAAM,YAAY,SAAS,UAA2B,WAAW;AACjE,SAAK,YAAY,WAAW,SAAS,KAAK;AAE1C,UAAM,UAAU,SAAS,UAAyB,SAAS;AAC3D,SAAK,UAAU,SAAS,SAAS,KAAK;AAEtC,UAAM,qBAAqB,SAAS,UAAoC,qBAAqB;AAC7F,SAAK,qBAAqB,oBAAoB,SAAS,KAAK;AAE5D,SAAK,UAAU,SAAS,0BAAc,CAAC,SAAS,UAAU;AACxD,YAAM,MAAM,MAAM,KAAK;AACvB,UAAI,KAAK;AACP,aAAK,kBAAkB,GAAG;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAA4B;AAChC,eAAW,CAAC,SAAS,QAAQ,SAAK,yBAAY,KAAK,MAAM,YAAY,GAAG;AACtE,WAAK,aAAa,SAAS,QAAQ;AAAA,IACrC;AAEA,SAAK,SAAS,gBAAgB,CAAC,UAAU;AACvC,UAAI,UAAU,KAAK,4BAA4B,KAAK,OAAO,eAAe,OAAO;AAC/E,aAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AAED,SAAK,oBAAoB,aAAa,CAAC,MAAM;AAC3C,YAAM,aAAa,KAAK,cAAc,IAAI,EAAE,UAAU,KAAK;AAC3D,UAAI,eAAe,KAAK,MAAM,gBAAgB;AAC5C,aAAK,SAAS,kBAAkB,UAAU,CAAC;AAC3C,aAAK,YAAY,KAAK,UAAU;AAAA,MAClC;AAAA,IACF,CAAC;AAED,SAAK,WAAW,eAAe,MAAM;AACnC,UAAI,CAAC,KAAK,MAAM,eAAgB;AAEhC,UACE,EACE,KAAK,MAAM,mBAAmB,mCAAqB,aACnD,KAAK,MAAM,mBAAmB,mCAAqB,aACnD,KAAK,MAAM,mBAAmB,mCAAqB,aACnD,KAAK,MAAM,mBAAmB,mCAAqB,WAErD;AACA;AAAA,MACF;AAEA,YAAM,qBAAqB,KAAK,WAAW,sBAAsB;AACjE,UAAI,CAAC,mBAAoB;AAEzB,iBAAW,aAAa,oBAAoB;AAC1C,cAAM,OAAO,UAAU;AACvB,cAAM,eAAe,UAAU;AAC/B,cAAM,OAAO,KAAK,MAAM;AACxB,cAAM,QAAQ,KAAK,MAAM,aAAa,IAAI,EAAE;AAC5C,cAAM,UAAU,KAAK,MAAM,aAAa,IAAI,EAAE;AAE9C,aAAK,iBAAiB,UAAU,WAAW;AAAA,UACzC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW,UAAU;AAAA,UACrB,IAAI,KAAK,IAAI,IAAI,KAAK,OAAO;AAAA,QAC/B,CAAC;AAAA,MACH;AAEA,WAAK,WAAW,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEQ,aAAa,SAA0B,UAAkC;AAC/E,UAAM,SAAS,SAAS,YAAY;AACpC,UAAM,kBAAmC;AAAA,MACvC,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,WAAW,SAAS,YAAY;AAAA,MAChC,QAAQ,SAAS,YAAY;AAAA,IAC/B;AAEA,SAAK,oBAAoB,aAAa,eAAe;AAErD,QAAI,SAAS,eAAe;AAC1B,WAAK,WAAW,cAAc,MAAM;AAAA,IACtC;AACA,SAAK,cAAc,IAAI,SAAS,MAAM;AACtC,SAAK,cAAc,IAAI,QAAQ,OAAO;AAAA,EACxC;AAAA,EAEU,kBAAwC;AAChD,WAAO;AAAA,MACL,oBAAoB,CAAC,YAAuC;AAC1D,eAAO,KAAK,mBAAmB,OAAO;AAAA,MACxC;AAAA,MACA,uBAAuB,MAAM;AAC3B,eAAO,sBAAsB,KAAK,KAAK;AAAA,MACzC;AAAA,MACA,kBAAkB,CAAC,WAAmB,iBAAyB;AAC7D,aAAK,iBAAiB,WAAW,YAAY;AAAA,MAC/C;AAAA,MACA,oBAAoB,MAAM;AACxB,aAAK,SAAS,mBAAmB,CAAC;AAAA,MACpC;AAAA,MACA,mBAAmB,MAAM;AACvB,eAAO,KAAK,MAAM;AAAA,MACpB;AAAA,MACA,mBAAmB,CAAC,YAAoC;AACtD,YAAI,YAAY,KAAK,MAAM,eAAgB;AAC3C,YAAI,SAAS;AACX,gBAAM,OAAO,KAAK,cAAc,IAAI,OAAO;AAC3C,cAAI,CAAC,KAAM,OAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAChE,eAAK,oBAAoB,SAAS,IAAI;AAAA,QACxC,OAAO;AACL,eAAK,oBAAoB,SAAS,SAAS;AAAA,QAC7C;AAAA,MACF;AAAA,MACA,iBAAiB,CAAC,YAAY;AAC5B,cAAM,WAAW,KAAK,MAAM,aAAa,OAAO;AAChD,YAAI,CAAC,UAAU;AACb,gBAAM,IAAI,MAAM,kCAAkC,OAAO,EAAE;AAAA,QAC7D;AACA,eAAO;AAAA,MACT;AAAA,MACA,iBAAiB,CAAC,SAAS,UAAU;AACnC,aAAK,SAAS,mBAAmB,SAAS,KAAK,CAAC;AAAA,MAClD;AAAA,MACA,iBAAiB,MAAM,CAAC,GAAG,KAAK,MAAM,YAAY;AAAA,MAClD,gBAAgB,CAAC,UAAU,KAAK,SAAS,eAAe,KAAK,CAAC;AAAA,MAC9D,kBAAkB,CAAC,WAAmB,eACpC,KAAK,iBAAiB,WAAW,UAAU;AAAA,MAC7C,kBAAkB,CAAC,WAAmB,SAAiB,UACrD,KAAK,iBAAiB,WAAW,SAAS,KAAK;AAAA,MACjD,kBAAkB,CAAC,WAAmB,YACpC,KAAK,iBAAiB,WAAW,OAAO;AAAA,MAC1C,kBAAkB,CAAC,YAAqC,KAAK,iBAAiB,OAAO;AAAA,MACrF,eAAe,KAAK,OAAO;AAAA,MAC3B,cAAc,KAAK,YAAY;AAAA,MAC/B,oBAAoB,KAAK,YAAY;AAAA,MACrC,QAAQ,MAAM,KAAK,OAAO;AAAA,IAC5B;AAAA,EACF;AAAA,EAEQ,iBACN,MACA,cACY;AACZ,QAAI,SAAS,MAAM;AACjB,aAAO,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,IACtC;AACA,WAAO,EAAE,MAAM,UAAU,aAAa,IAAI,EAAE;AAAA,EAC9C;AAAA,EAEQ,eAAe,OAAwB;AAC7C,UAAM,aAAa,KAAK,iBAAiB,MAAM,gBAAgB,MAAM,YAAY;AACjF,SAAK,YAAY,KAAK,UAAU;AAAA,EAClC;AAAA,EAES,eAAe,MAAuB,MAA6B;AAC1E,SAAK,OAAO,KAAK,IAAI;AACrB,QACE,KAAK,mBAAmB,KAAK,kBAC7B,KAAK,aAAa,KAAK,kBAAkB,mCAAqB,SAAS,MACrE,KAAK,aAAa,KAAK,kBAAkB,mCAAqB,SAAS,GACzE;AACA,WAAK,eAAe,IAAI;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,kBAAkB,KAAwB;AAChD,UAAM,OAAO,KAAK,OAAO,kBAAkB,GAAG;AAC9C,SAAK,KAAK,CAAC,gBAAgB,KAAK,SAAS,eAAe,WAAW,CAAC,GAAG,oBAAM;AAAA,EAC/E;AAAA,EAEQ,mBACN,SAC6C;AAC7C,UAAM,EAAE,UAAU,IAAI;AAEtB,UAAM,MAAM,KAAK,UAAU,KAAK;AAEhC,QAAI,CAAC,KAAK;AACR,aAAO,4BAAc,OAAO,EAAE,MAAM,2BAAa,UAAU,SAAS,qBAAqB,CAAC;AAAA,IAC5F;AAEA,UAAM,OAAO,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS;AAExD,QAAI,CAAC,MAAM;AACT,aAAO,4BAAc,OAAO,EAAE,MAAM,2BAAa,UAAU,SAAS,iBAAiB,CAAC;AAAA,IACxF;AAEA,WAAO,KAAK,OAAO,mBAAmB,KAAK,IAAI;AAAA,EACjD;AAAA,EAEQ,iBAAiB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,WAAW,uBAAS;AAAA,IACpB,MAAM;AAAA,IACN,OAAO,6BAAe;AAAA,IACtB,YAAY;AAAA,EACd,GAA4B;AAC1B,UAAM,YAAY,KAAK,UAAU;AAEjC,QAAI,CAAC,UAAU,UAAU;AACvB,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AAEA,UAAM,OAAO,UAAU,SAAS,MAAM,KAAK,CAACC,UAASA,MAAK,UAAU,SAAS;AAC7E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAEA,WAAO,KAAK,OAAO;AAAA,MACjB,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,WAAmB,cAAsB;AAChE,SAAK,SAAS,iBAAiB,WAAW,YAAY,CAAC;AAAA,EACzD;AAAA,EAEQ,iBAAiB,WAAmB,YAAiC;AAC3E,UAAM,UAAU,WAAW;AAC3B,UAAM,UAAU,MAAM,KAAK,SAAS,iBAAiB,WAAW,SAAS,UAAU,CAAC;AAEpF,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ;AACR,UAAI,KAAK,OAAO,WAAY,MAAK,OAAO;AACxC;AAAA,IACF;AACA,UAAM,UAAmB;AAAA,MACvB;AAAA,MACA,MAAM,MAAM;AACV,aAAK,SAAS,mBAAmB,CAAC;AAClC,aAAK,SAAS,iBAAiB,WAAW,OAAO,CAAC;AAAA,MACpD;AAAA,IACF;AACA,SAAK,QAAQ,SAAS,SAAS,KAAK,wBAAwB;AAAA,EAC9D;AAAA,EAEQ,iBACN,WACA,SACA,OACA;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,SAAS,gBAAgB,WAAW,SAAS,KAAK,CAAC;AACxD,UAAI,KAAK,OAAO,eAAe,OAAO;AACpC,aAAK,OAAO;AAAA,MACd;AACA;AAAA,IACF;AACA,UAAM,iBAAiB,KAAK,MAAM,MAAM,QAAQ,WAAW,OAAO,CAAC,EAAE;AACrE,UAAM,gBAAgB,OAAO;AAAA,MAC3B,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,eAAe,GAAgC,CAAC,CAAC;AAAA,IACzF;AACA,UAAM,UAAmB;AAAA,MACvB,SAAS,MAAM,KAAK,SAAS,gBAAgB,WAAW,SAAS,KAAK,CAAC;AAAA,MACvE,MAAM,MAAM,KAAK,SAAS,gBAAgB,WAAW,SAAS,aAAa,CAAC;AAAA,IAC9E;AACA,SAAK,QAAQ,SAAS,SAAS,KAAK,wBAAwB;AAAA,EAC9D;AAAA,EAEQ,iBAAiB,WAAmB,SAAiB;AAC3D,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,SAAS,mBAAmB,CAAC;AAClC,WAAK,SAAS,iBAAiB,WAAW,OAAO,CAAC;AAClD,UAAI,KAAK,OAAO,eAAe,OAAO;AACpC,aAAK,OAAO;AAAA,MACd;AACA;AAAA,IACF;AACA,UAAM,qBAAqB,KAAK,MAAM,MAAM,QAAQ,WAAW,OAAO,CAAC,EAAE;AACzE,UAAM,UAAmB;AAAA,MACvB,SAAS,MAAM;AACb,aAAK,SAAS,mBAAmB,CAAC;AAClC,aAAK,SAAS,iBAAiB,WAAW,OAAO,CAAC;AAAA,MACpD;AAAA,MACA,MAAM,MAAM,KAAK,SAAS,iBAAiB,WAAW,SAAS,kBAAkB,CAAC;AAAA,IACpF;AACA,SAAK,QAAQ,SAAS,SAAS,KAAK,wBAAwB;AAAA,EAC9D;AAAA,EAEQ,SAAwC;AAC9C,UAAM,OAAO,IAAI,mBAA8B;AAE/C,QAAI,CAAC,KAAK,MAAM,kBAAmB,QAAO,4BAAc,QAAQ,IAAI;AAEpE,UAAM,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,CAAC;AACH,aAAO,4BAAc,OAAO,EAAE,MAAM,2BAAa,UAAU,SAAS,qBAAqB,CAAC;AAE5F,UAAM,YAAyC,CAAC;AAChD,UAAM,UAAuC,CAAC;AAC9C,UAAM,kBAAkB,oBAAI,IAAsD;AAClF,UAAM,gBAAgB,oBAAI,IAAY;AAGtC,eAAW,CAAC,KAAK,EAAE,KAAK,OAAO,QAAQ,KAAK,MAAM,KAAK,GAAG;AACxD,UAAI,GAAG,gBAAgB,SAAU;AAEjC,YAAM,EAAE,UAAU,IAAI,SAAS,GAAG;AAClC,YAAM,OAAO,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS;AACxD,UAAI,CAAC,KAAM;AAEX,oBAAc,IAAI,SAAS;AAE3B,cAAQ,GAAG,aAAa;AAAA,QACtB,KAAK;AACH,gBAAMC,QAAO,KAAK,OAAO,qBAAsB,KAAK,MAAM,GAAG,MAAM;AACnE,UAAAA,MAAK,KAAK,CAAC,WAAW,KAAK,SAAS,WAAW,KAAK,MAAM,CAAC,GAAG,oBAAM;AACpE,oBAAU,KAAKA,KAAI;AACnB;AAAA,QACF,KAAK;AACH,kBAAQ;AAAA,YACN,KAAK,OAAO,qBAAsB,KAAK,MAAM,EAAE,GAAG,GAAG,QAAQ,IAAI,GAAG,MAAO,CAAC;AAAA,UAC9E;AACA;AAAA,QACF,KAAK;AACH,cAAI,CAAC,gBAAgB,IAAI,SAAS,GAAG;AACnC,4BAAgB,IAAI,WAAW,CAAC,CAAC;AAAA,UACnC;AACA,0BAAgB,IAAI,SAAS,EAAG,KAAK,EAAE,IAAI,IAAI,CAAC;AAChD;AAAA,MACJ;AAAA,IACF;AAGA,UAAM,gBAA6C,CAAC;AACpD,eAAW,CAAC,WAAW,SAAS,KAAK,gBAAgB,QAAQ,GAAG;AAC9D,YAAM,OAAO,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS;AAExD,gBAAU,KAAK,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,OAAO,EAAE,GAAG,SAAS,GAAG;AAEhE,iBAAW,EAAE,IAAI,IAAI,KAAK,WAAW;AACnC,YAAI,GAAG,UAAU,QAAW;AAC1B,gBAAMA,QAAO,IAAI,mBAA0B;AAC3C,gBAAM,aAAa,KAAK,OAAO,qBAAsB,KAAK,MAAM;AAAA,YAC9D,GAAG,GAAG;AAAA,YACN,IAAI,GAAG;AAAA,UACT,CAAC;AACD,qBAAW,KAAK,MAAM;AACpB,iBAAK,SAAS,gBAAgB,GAAG,CAAC;AAClC,YAAAA,MAAK,QAAQ,IAAI;AAAA,UACnB,GAAGA,MAAK,IAAI;AACZ,wBAAc,KAAKA,KAAI;AAAA,QACzB,OAAO;AACL,eAAK,SAAS,gBAAgB,GAAG,CAAC;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,CAAC,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa;AAEjE,uBAAK,WAAW,aAAa,EAAE,KAAK,MAAM;AAGxC,iBAAW,aAAa,eAAe;AACrC,aAAK,SAAS,uBAAuB,SAAS,CAAC;AAAA,MACjD;AAGA,WAAK,SAAS,qBAAqB,CAAC;AACpC,WAAK,QAAQ,IAAI;AAAA,IACnB,GAAG,KAAK,IAAI;AAEZ,WAAO;AAAA,EACT;AACF;AAnaa,iBAMK,KAAK;;;AIhEvB,IAAAC,iBAAqC;AAqBrC,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,YAAY,CAChB,OACA,KACA,UACoB;AACpB,QAAM,OAAO,MAAM,MAAM,GAAG;AAC5B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,MAAM;AAAA,MACT,CAAC,GAAG,GAAG;AAAA,QACL,GAAG;AAAA,QACH,aAAa,KAAK,gBAAgB,WAAW,UAAU,KAAK;AAAA,QAC5D,QAAQ,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM;AAAA,MACrC;AAAA,IACF;AAAA,IACA,mBAAmB;AAAA,EACrB;AACF;AAGO,IAAM,eAAe,CAAC,SAAkD;AAAA,EAC7E,OAAO,CAAC;AAAA,EACR,OAAO,CAAC;AAAA,EACR,aAAa;AAAA,EACb,gBAAgB;AAAA,EAEhB,cAAc;AAAA,IACZ,CAAC,oCAAqB,SAAS,GAAG;AAAA,MAChC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,EAAE,MAAM,aAAa,WAAW,MAAM;AAAA,MACnD,eAAe;AAAA,IACjB;AAAA,IACA,CAAC,oCAAqB,SAAS,GAAG;AAAA,MAChC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,EAAE,MAAM,aAAa,WAAW,MAAM;AAAA,MACnD,eAAe;AAAA,IACjB;AAAA,IACA,CAAC,oCAAqB,SAAS,GAAG;AAAA,MAChC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,EAAE,MAAM,aAAa,WAAW,MAAM;AAAA,MACnD,eAAe;AAAA,IACjB;AAAA,IACA,CAAC,oCAAqB,QAAQ,GAAG;AAAA,MAC/B,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa,EAAE,MAAM,YAAY,WAAW,MAAM;AAAA,MAClD,eAAe;AAAA,IACjB;AAAA,IACA,CAAC,oCAAqB,GAAG,GAAG;AAAA,MAC1B,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,aAAa,EAAE,MAAM,OAAO,WAAW,MAAM,QAAQ,YAAY;AAAA,MACjE,eAAe;AAAA,IACjB;AAAA,IACA,GAAG,IAAI;AAAA,EACT;AAAA,EACA,cAAc,IAAI,gBAAgB;AAAA,EAClC,mBAAmB;AACrB;AAGO,IAAM,UAAsD,CAAC,OAAO,WAAW;AACpF,UAAQ,OAAO,MAAM;AAAA;AAAA,IAEnB,KAAK,iBAAiB;AACpB,YAAM,WAAW,EAAE,GAAG,MAAM,MAAM;AAClC,YAAM,WAAW,EAAE,GAAG,MAAM,MAAM;AAClC,iBAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AAC1D,cAAM,YAAY,OAAO,KAAK;AAC9B,cAAM,gBAAgB,MAAM,MAAM,SAAS,KAAK,CAAC;AACjD,mBAAW,OAAO,eAAe;AAC/B,iBAAO,SAAS,GAAG;AAAA,QACrB;AACA,cAAM,gBAAgB,KAAK,IAAI,CAAC,GAAG,UAAU;AAC3C,gBAAM,UAAU,KAAK,IAAI,IAAI,KAAK,OAAO,IAAI;AAC7C,gBAAM,MAAM,QAAQ,WAAW,OAAO;AACtC,mBAAS,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,IAAI,aAAa,UAAU,QAAQ,EAAE;AACzE,iBAAO;AAAA,QACT,CAAC;AACD,iBAAS,SAAS,IAAI;AAAA,MACxB;AACA,aAAO,EAAE,GAAG,OAAO,OAAO,UAAU,OAAO,SAAS;AAAA,IACtD;AAAA;AAAA,IAGA,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,gBAAgB,OAAO,QAAQ;AAAA,IACpD,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,QAAQ,OAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO;AAAA,MACvE;AAAA,IACF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,aAAa,KAAK;AAAA,IAEvC,KAAK;AACH,aAAO,MAAM,aAAa,SAAS,OAAO,OAAO,IAC7C,QACA,EAAE,GAAG,OAAO,cAAc,CAAC,GAAG,MAAM,cAAc,OAAO,OAAO,EAAE;AAAA,IAExE,KAAK,sBAAsB;AACzB,YAAM,EAAE,SAAS,MAAM,IAAI,OAAO;AAClC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,cAAc;AAAA,UACZ,GAAG,MAAM;AAAA,UACT,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,aAAa,OAAO,GAAG,GAAG,MAAM;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAGA,KAAK,mBAAmB;AACtB,YAAM,EAAE,WAAW,SAAS,WAAW,IAAI,OAAO;AAClD,YAAM,MAAM,QAAQ,WAAW,OAAO;AAEtC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,SAAS,GAAG,CAAC,GAAI,MAAM,MAAM,SAAS,KAAK,CAAC,GAAI,GAAG,EAAE;AAAA,QAC/E,OAAO;AAAA,UACL,GAAG,MAAM;AAAA,UACT,CAAC,GAAG,GAAG,EAAE,SAAS,OAAO,QAAW,aAAa,OAAO,QAAQ,WAAW;AAAA,QAC7E;AAAA,QACA,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA;AAAA,IAGA,KAAK,mBAAmB;AACtB,YAAM,EAAE,WAAW,QAAQ,IAAI,OAAO;AACtC,YAAM,MAAM,QAAQ,WAAW,OAAO;AACtC,UAAI,CAAC,MAAM,MAAM,GAAG,EAAG,QAAO;AAG9B,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,UACL,GAAG,MAAM;AAAA,UACT,CAAC,SAAS,IAAI,MAAM,MAAM,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,MAAM,GAAG;AAAA,QACrE;AAAA,QACA,OAAO;AAAA,UACL,GAAG,MAAM;AAAA,UACT,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,MAAM,GAAG,GAAG,aAAa,UAAU;AAAA,QACvD;AAAA,QACA,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA;AAAA,IAGA,KAAK,kBAAkB;AACrB,YAAM,MAAM,QAAQ,OAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO;AACpE,aAAO,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK;AAAA,IACnD;AAAA;AAAA,IAGA,KAAK,wBAAwB;AAC3B,YAAM,UAAoC,CAAC;AAC3C,iBAAW,CAAC,KAAK,EAAE,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AACnD,gBAAQ,GAAG,IAAI;AAAA,UACb,GAAG;AAAA,UACH,aACE,GAAG,gBAAgB,WAAW,GAAG,gBAAgB,QAAQ,WAAW,GAAG;AAAA,QAC3E;AAAA,MACF;AACA,aAAO,EAAE,GAAG,OAAO,OAAO,SAAS,mBAAmB,MAAM;AAAA,IAC9D;AAAA,IAEA,KAAK,0BAA0B;AAC7B,YAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,YAAM,WAAW,EAAE,GAAG,MAAM,MAAM;AAElC,YAAM,aAAa,MAAM,MAAM,SAAS,KAAK,CAAC;AAC9C,YAAM,cAAc,WACjB,IAAI,CAAC,QAAQ,MAAM,MAAM,GAAG,CAAC,EAC7B,OAAO,CAAC,OAAO,MAAM,GAAG,gBAAgB,SAAS;AAGpD,kBAAY,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,aAAa,EAAE,SAAS,SAAS;AAGxE,kBAAY,QAAQ,CAAC,IAAI,aAAa;AACpC,cAAM,MAAM,QAAQ,WAAW,GAAG,OAAO;AACzC,iBAAS,GAAG,IAAI,EAAE,GAAG,SAAS,GAAG,GAAG,OAAO,SAAS;AAAA,MACtD,CAAC;AAED,aAAO,EAAE,GAAG,OAAO,OAAO,SAAS;AAAA,IACrC;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,EAAE,KAAK,MAAM,IAAI,OAAO;AAE9B,YAAM,KAAK,MAAM,MAAM,GAAG;AAC1B,UAAI,CAAC,GAAI,QAAO;AAChB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,UACL,GAAG,MAAM;AAAA,UACT,CAAC,GAAG,GAAG,EAAE,GAAG,IAAI,OAAO,aAAa,SAAS;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,IAEA,KAAK,kBAAkB;AACrB,YAAM,EAAE,IAAI,IAAI,OAAO;AACvB,YAAM,EAAE,CAAC,GAAG,GAAG,OAAO,GAAG,KAAK,IAAI,MAAM;AACxC,aAAO,EAAE,GAAG,OAAO,OAAO,KAAK;AAAA,IACjC;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;;;ACzPO,IAAM,0BAKT;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,UAAU,QAAQ,WACzB,IAAI,iBAAiB,sBAAsB,UAAU,QAAQ,MAAM;AAAA,EACrE;AAAA,EACA,cAAc,CAAC,GAAG,WAAW,aAAa,MAAM;AAClD;","names":["makeUid","page","task","import_models"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BasePluginConfig, EventHook, Action, BasePlugin, PluginRegistry, PluginManifest, PluginPackage } from '@embedpdf/core';
2
- import { PdfAnnotationSubtype, WebAlphaColor, Task, PdfAnnotationObject, PdfErrorReason, PdfEngine } from '@embedpdf/models';
2
+ import { PdfAnnotationSubtype, WebAlphaColor, Task, PdfAnnotationObject, PdfErrorReason, Rotation, AppearanceMode, ImageConversionTypes, PdfEngine } from '@embedpdf/models';
3
3
 
4
4
  type CommitState = 'new' | 'dirty' | 'deleted' | 'synced' | 'ignored';
5
5
  interface TrackedAnnotation {
@@ -16,6 +16,15 @@ interface TrackedAnnotation {
16
16
  /** the actual annotation object */
17
17
  object: PdfAnnotationObject;
18
18
  }
19
+ interface RenderAnnotationOptions {
20
+ pageIndex: number;
21
+ annotation: PdfAnnotationObject;
22
+ scaleFactor?: number;
23
+ rotation?: Rotation;
24
+ dpr?: number;
25
+ mode?: AppearanceMode;
26
+ imageType?: ImageConversionTypes;
27
+ }
19
28
  interface BaseAnnotationDefaults extends WebAlphaColor {
20
29
  interaction: {
21
30
  mode: string;
@@ -36,19 +45,29 @@ interface StrikeoutDefaults extends BaseAnnotationDefaults {
36
45
  interface SquigglyDefaults extends BaseAnnotationDefaults {
37
46
  name: 'Squiggly';
38
47
  }
39
- type AnnotationDefaults = HighlightDefaults | UnderlineDefaults | StrikeoutDefaults | SquigglyDefaults;
48
+ interface InkDefaults extends BaseAnnotationDefaults {
49
+ name: 'Ink';
50
+ strokeWidth: number;
51
+ }
52
+ type AnnotationDefaults = HighlightDefaults | UnderlineDefaults | StrikeoutDefaults | SquigglyDefaults | InkDefaults;
40
53
  type ToolDefaultsBySubtype = {
41
54
  [PdfAnnotationSubtype.HIGHLIGHT]: HighlightDefaults;
42
55
  [PdfAnnotationSubtype.UNDERLINE]: UnderlineDefaults;
43
56
  [PdfAnnotationSubtype.STRIKEOUT]: StrikeoutDefaults;
44
57
  [PdfAnnotationSubtype.SQUIGGLY]: SquigglyDefaults;
58
+ [PdfAnnotationSubtype.INK]: InkDefaults;
45
59
  };
46
60
  type StylableSubtype = keyof ToolDefaultsBySubtype;
47
61
  type ToolDefaults<S extends PdfAnnotationSubtype> = ToolDefaultsBySubtype[Extract<S, keyof ToolDefaultsBySubtype>];
48
- interface ActiveTool {
49
- mode: StylableSubtype | null;
50
- defaults: AnnotationDefaults | null;
51
- }
62
+ type ActiveTool = {
63
+ mode: null;
64
+ defaults: null;
65
+ } | {
66
+ [K in StylableSubtype]: {
67
+ mode: K;
68
+ defaults: ToolDefaultsBySubtype[K];
69
+ };
70
+ }[StylableSubtype];
52
71
  interface AnnotationState {
53
72
  pages: Record<number, string[]>;
54
73
  byUid: Record<string, TrackedAnnotation>;
@@ -85,6 +104,7 @@ interface AnnotationCapability {
85
104
  createAnnotation: (pageIndex: number, annotation: PdfAnnotationObject) => void;
86
105
  updateAnnotation: (pageIndex: number, annotationId: number, patch: Partial<PdfAnnotationObject>) => void;
87
106
  deleteAnnotation: (pageIndex: number, annotationId: number) => void;
107
+ renderAnnotation: (options: RenderAnnotationOptions) => Task<Blob, PdfErrorReason>;
88
108
  /** undo / redo */
89
109
  onStateChange: EventHook<AnnotationState>;
90
110
  onModeChange: EventHook<StylableSubtype | null>;
@@ -212,10 +232,12 @@ declare class AnnotationPlugin extends BasePlugin<AnnotationPluginConfig, Annota
212
232
  initialize(): Promise<void>;
213
233
  private registerTool;
214
234
  protected buildCapability(): AnnotationCapability;
235
+ private createActiveTool;
215
236
  private emitActiveTool;
216
237
  onStoreUpdated(prev: AnnotationState, next: AnnotationState): void;
217
238
  private getAllAnnotations;
218
239
  private getPageAnnotations;
240
+ private renderAnnotation;
219
241
  private selectAnnotation;
220
242
  private createAnnotation;
221
243
  private updateAnnotation;
@@ -241,4 +263,4 @@ declare const isAnnotationSelected: (s: AnnotationState, page: number, id: numbe
241
263
 
242
264
  declare const AnnotationPluginPackage: PluginPackage<AnnotationPlugin, AnnotationPluginConfig, AnnotationState, AnnotationAction>;
243
265
 
244
- export { ANNOTATION_PLUGIN_ID, type ActiveTool, type AnnotationCapability, type AnnotationDefaults, AnnotationPlugin, type AnnotationPluginConfig, AnnotationPluginPackage, type AnnotationState, type BaseAnnotationDefaults, type CommitState, type GetPageAnnotationsOptions, type HighlightDefaults, type SelectedAnnotation, type SquigglyDefaults, type StrikeoutDefaults, type StylableSubtype, type ToolDefaults, type ToolDefaultsBySubtype, type TrackedAnnotation, type UnderlineDefaults, type UpdateAnnotationColorOptions, getAnnotations, getAnnotationsByPageIndex, getSelectedAnnotation, getSelectedAnnotationByPageIndex, getSelectedAnnotationMode, getSelectedAnnotationWithPageIndex, isAnnotationSelected, isInAnnotationMode, manifest };
266
+ export { ANNOTATION_PLUGIN_ID, type ActiveTool, type AnnotationCapability, type AnnotationDefaults, AnnotationPlugin, type AnnotationPluginConfig, AnnotationPluginPackage, type AnnotationState, type BaseAnnotationDefaults, type CommitState, type GetPageAnnotationsOptions, type HighlightDefaults, type InkDefaults, type RenderAnnotationOptions, type SelectedAnnotation, type SquigglyDefaults, type StrikeoutDefaults, type StylableSubtype, type ToolDefaults, type ToolDefaultsBySubtype, type TrackedAnnotation, type UnderlineDefaults, type UpdateAnnotationColorOptions, getAnnotations, getAnnotationsByPageIndex, getSelectedAnnotation, getSelectedAnnotationByPageIndex, getSelectedAnnotationMode, getSelectedAnnotationWithPageIndex, isAnnotationSelected, isInAnnotationMode, manifest };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BasePluginConfig, EventHook, Action, BasePlugin, PluginRegistry, PluginManifest, PluginPackage } from '@embedpdf/core';
2
- import { PdfAnnotationSubtype, WebAlphaColor, Task, PdfAnnotationObject, PdfErrorReason, PdfEngine } from '@embedpdf/models';
2
+ import { PdfAnnotationSubtype, WebAlphaColor, Task, PdfAnnotationObject, PdfErrorReason, Rotation, AppearanceMode, ImageConversionTypes, PdfEngine } from '@embedpdf/models';
3
3
 
4
4
  type CommitState = 'new' | 'dirty' | 'deleted' | 'synced' | 'ignored';
5
5
  interface TrackedAnnotation {
@@ -16,6 +16,15 @@ interface TrackedAnnotation {
16
16
  /** the actual annotation object */
17
17
  object: PdfAnnotationObject;
18
18
  }
19
+ interface RenderAnnotationOptions {
20
+ pageIndex: number;
21
+ annotation: PdfAnnotationObject;
22
+ scaleFactor?: number;
23
+ rotation?: Rotation;
24
+ dpr?: number;
25
+ mode?: AppearanceMode;
26
+ imageType?: ImageConversionTypes;
27
+ }
19
28
  interface BaseAnnotationDefaults extends WebAlphaColor {
20
29
  interaction: {
21
30
  mode: string;
@@ -36,19 +45,29 @@ interface StrikeoutDefaults extends BaseAnnotationDefaults {
36
45
  interface SquigglyDefaults extends BaseAnnotationDefaults {
37
46
  name: 'Squiggly';
38
47
  }
39
- type AnnotationDefaults = HighlightDefaults | UnderlineDefaults | StrikeoutDefaults | SquigglyDefaults;
48
+ interface InkDefaults extends BaseAnnotationDefaults {
49
+ name: 'Ink';
50
+ strokeWidth: number;
51
+ }
52
+ type AnnotationDefaults = HighlightDefaults | UnderlineDefaults | StrikeoutDefaults | SquigglyDefaults | InkDefaults;
40
53
  type ToolDefaultsBySubtype = {
41
54
  [PdfAnnotationSubtype.HIGHLIGHT]: HighlightDefaults;
42
55
  [PdfAnnotationSubtype.UNDERLINE]: UnderlineDefaults;
43
56
  [PdfAnnotationSubtype.STRIKEOUT]: StrikeoutDefaults;
44
57
  [PdfAnnotationSubtype.SQUIGGLY]: SquigglyDefaults;
58
+ [PdfAnnotationSubtype.INK]: InkDefaults;
45
59
  };
46
60
  type StylableSubtype = keyof ToolDefaultsBySubtype;
47
61
  type ToolDefaults<S extends PdfAnnotationSubtype> = ToolDefaultsBySubtype[Extract<S, keyof ToolDefaultsBySubtype>];
48
- interface ActiveTool {
49
- mode: StylableSubtype | null;
50
- defaults: AnnotationDefaults | null;
51
- }
62
+ type ActiveTool = {
63
+ mode: null;
64
+ defaults: null;
65
+ } | {
66
+ [K in StylableSubtype]: {
67
+ mode: K;
68
+ defaults: ToolDefaultsBySubtype[K];
69
+ };
70
+ }[StylableSubtype];
52
71
  interface AnnotationState {
53
72
  pages: Record<number, string[]>;
54
73
  byUid: Record<string, TrackedAnnotation>;
@@ -85,6 +104,7 @@ interface AnnotationCapability {
85
104
  createAnnotation: (pageIndex: number, annotation: PdfAnnotationObject) => void;
86
105
  updateAnnotation: (pageIndex: number, annotationId: number, patch: Partial<PdfAnnotationObject>) => void;
87
106
  deleteAnnotation: (pageIndex: number, annotationId: number) => void;
107
+ renderAnnotation: (options: RenderAnnotationOptions) => Task<Blob, PdfErrorReason>;
88
108
  /** undo / redo */
89
109
  onStateChange: EventHook<AnnotationState>;
90
110
  onModeChange: EventHook<StylableSubtype | null>;
@@ -212,10 +232,12 @@ declare class AnnotationPlugin extends BasePlugin<AnnotationPluginConfig, Annota
212
232
  initialize(): Promise<void>;
213
233
  private registerTool;
214
234
  protected buildCapability(): AnnotationCapability;
235
+ private createActiveTool;
215
236
  private emitActiveTool;
216
237
  onStoreUpdated(prev: AnnotationState, next: AnnotationState): void;
217
238
  private getAllAnnotations;
218
239
  private getPageAnnotations;
240
+ private renderAnnotation;
219
241
  private selectAnnotation;
220
242
  private createAnnotation;
221
243
  private updateAnnotation;
@@ -241,4 +263,4 @@ declare const isAnnotationSelected: (s: AnnotationState, page: number, id: numbe
241
263
 
242
264
  declare const AnnotationPluginPackage: PluginPackage<AnnotationPlugin, AnnotationPluginConfig, AnnotationState, AnnotationAction>;
243
265
 
244
- export { ANNOTATION_PLUGIN_ID, type ActiveTool, type AnnotationCapability, type AnnotationDefaults, AnnotationPlugin, type AnnotationPluginConfig, AnnotationPluginPackage, type AnnotationState, type BaseAnnotationDefaults, type CommitState, type GetPageAnnotationsOptions, type HighlightDefaults, type SelectedAnnotation, type SquigglyDefaults, type StrikeoutDefaults, type StylableSubtype, type ToolDefaults, type ToolDefaultsBySubtype, type TrackedAnnotation, type UnderlineDefaults, type UpdateAnnotationColorOptions, getAnnotations, getAnnotationsByPageIndex, getSelectedAnnotation, getSelectedAnnotationByPageIndex, getSelectedAnnotationMode, getSelectedAnnotationWithPageIndex, isAnnotationSelected, isInAnnotationMode, manifest };
266
+ export { ANNOTATION_PLUGIN_ID, type ActiveTool, type AnnotationCapability, type AnnotationDefaults, AnnotationPlugin, type AnnotationPluginConfig, AnnotationPluginPackage, type AnnotationState, type BaseAnnotationDefaults, type CommitState, type GetPageAnnotationsOptions, type HighlightDefaults, type InkDefaults, type RenderAnnotationOptions, type SelectedAnnotation, type SquigglyDefaults, type StrikeoutDefaults, type StylableSubtype, type ToolDefaults, type ToolDefaultsBySubtype, type TrackedAnnotation, type UnderlineDefaults, type UpdateAnnotationColorOptions, getAnnotations, getAnnotationsByPageIndex, getSelectedAnnotation, getSelectedAnnotationByPageIndex, getSelectedAnnotationMode, getSelectedAnnotationWithPageIndex, isAnnotationSelected, isInAnnotationMode, manifest };
package/dist/index.js CHANGED
@@ -25,7 +25,9 @@ import {
25
25
  Task,
26
26
  PdfAnnotationSubtype,
27
27
  PdfTaskHelper,
28
- PdfErrorCode
28
+ PdfErrorCode,
29
+ Rotation,
30
+ AppearanceMode
29
31
  } from "@embedpdf/models";
30
32
 
31
33
  // src/lib/actions.ts
@@ -167,6 +169,9 @@ var AnnotationPlugin = class extends BasePlugin {
167
169
  });
168
170
  this.selection?.onEndSelection(() => {
169
171
  if (!this.state.annotationMode) return;
172
+ if (!(this.state.annotationMode === PdfAnnotationSubtype.HIGHLIGHT || this.state.annotationMode === PdfAnnotationSubtype.UNDERLINE || this.state.annotationMode === PdfAnnotationSubtype.STRIKEOUT || this.state.annotationMode === PdfAnnotationSubtype.SQUIGGLY)) {
173
+ return;
174
+ }
170
175
  const formattedSelection = this.selection?.getFormattedSelection();
171
176
  if (!formattedSelection) return;
172
177
  for (const selection of formattedSelection) {
@@ -245,18 +250,22 @@ var AnnotationPlugin = class extends BasePlugin {
245
250
  createAnnotation: (pageIndex, annotation) => this.createAnnotation(pageIndex, annotation),
246
251
  updateAnnotation: (pageIndex, localId, patch) => this.updateAnnotation(pageIndex, localId, patch),
247
252
  deleteAnnotation: (pageIndex, localId) => this.deleteAnnotation(pageIndex, localId),
253
+ renderAnnotation: (options) => this.renderAnnotation(options),
248
254
  onStateChange: this.state$.on,
249
255
  onModeChange: this.modeChange$.on,
250
256
  onActiveToolChange: this.activeTool$.on,
251
257
  commit: () => this.commit()
252
258
  };
253
259
  }
260
+ createActiveTool(mode, toolDefaults) {
261
+ if (mode === null) {
262
+ return { mode: null, defaults: null };
263
+ }
264
+ return { mode, defaults: toolDefaults[mode] };
265
+ }
254
266
  emitActiveTool(state) {
255
- const mode = state.annotationMode;
256
- this.activeTool$.emit({
257
- mode,
258
- defaults: mode ? state.toolDefaults[mode] : null
259
- });
267
+ const activeTool = this.createActiveTool(state.annotationMode, state.toolDefaults);
268
+ this.activeTool$.emit(activeTool);
260
269
  }
261
270
  onStoreUpdated(prev, next) {
262
271
  this.state$.emit(next);
@@ -280,6 +289,34 @@ var AnnotationPlugin = class extends BasePlugin {
280
289
  }
281
290
  return this.engine.getPageAnnotations(doc, page);
282
291
  }
292
+ renderAnnotation({
293
+ pageIndex,
294
+ annotation,
295
+ scaleFactor = 1,
296
+ rotation = Rotation.Degree0,
297
+ dpr = 1,
298
+ mode = AppearanceMode.Normal,
299
+ imageType = "image/webp"
300
+ }) {
301
+ const coreState = this.coreState.core;
302
+ if (!coreState.document) {
303
+ throw new Error("document does not open");
304
+ }
305
+ const page = coreState.document.pages.find((page2) => page2.index === pageIndex);
306
+ if (!page) {
307
+ throw new Error("page does not exist");
308
+ }
309
+ return this.engine.renderAnnotation(
310
+ coreState.document,
311
+ page,
312
+ annotation,
313
+ scaleFactor,
314
+ rotation,
315
+ dpr,
316
+ mode,
317
+ imageType
318
+ );
319
+ }
283
320
  selectAnnotation(pageIndex, annotationId) {
284
321
  this.dispatch(selectAnnotation(pageIndex, annotationId));
285
322
  }
@@ -468,6 +505,14 @@ var initialState = (cfg) => ({
468
505
  interaction: { mode: "squiggly", exclusive: false },
469
506
  textSelection: true
470
507
  },
508
+ [PdfAnnotationSubtype2.INK]: {
509
+ name: "Ink",
510
+ color: "#E44234",
511
+ opacity: 1,
512
+ strokeWidth: 11,
513
+ interaction: { mode: "ink", exclusive: true, cursor: "crosshair" },
514
+ textSelection: false
515
+ },
471
516
  ...cfg.toolDefaults
472
517
  },
473
518
  colorPresets: cfg.colorPresets ?? DEFAULT_COLORS,