@embedpdf/plugin-redaction 1.3.11 → 1.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +87 -30
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +10 -3
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/redaction-plugin.d.ts +5 -1
- package/dist/lib/types.d.ts +25 -5
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +24 -10
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +24 -10
- package/dist/react/index.js.map +1 -1
- package/dist/shared-preact/components/index.d.ts +1 -0
- package/dist/shared-preact/hooks/use-redaction.d.ts +5 -1
- package/dist/shared-react/components/index.d.ts +1 -0
- package/dist/shared-react/hooks/use-redaction.d.ts +5 -1
- package/dist/vue/hooks/use-redaction.d.ts +102 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +32 -16
- package/dist/vue/index.js.map +1 -1
- package/package.json +14 -9
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/handlers/marquee-redact.handler.ts","../src/lib/redaction-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/selectors.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\nimport { RedactionItem } from './types';\n\nexport const START_REDACTION = 'START_REDACTION';\nexport const END_REDACTION = 'END_REDACTION';\n\nexport const ADD_PENDING = 'ADD_PENDING';\nexport const REMOVE_PENDING = 'REMOVE_PENDING';\nexport const CLEAR_PENDING = 'CLEAR_PENDING';\n\nexport const SELECT_PENDING = 'SELECT_PENDING';\nexport const DESELECT_PENDING = 'DESELECT_PENDING';\n\nexport interface StartRedactionAction extends Action {\n type: typeof START_REDACTION;\n}\nexport interface EndRedactionAction extends Action {\n type: typeof END_REDACTION;\n}\n\nexport interface AddPendingAction extends Action {\n type: typeof ADD_PENDING;\n payload: RedactionItem[];\n}\nexport interface RemovePendingAction extends Action {\n type: typeof REMOVE_PENDING;\n payload: { page: number; id: string };\n}\nexport interface ClearPendingAction extends Action {\n type: typeof CLEAR_PENDING;\n}\n\nexport interface SelectPendingAction extends Action {\n type: typeof SELECT_PENDING;\n payload: { page: number; id: string };\n}\nexport interface DeselectPendingAction extends Action {\n type: typeof DESELECT_PENDING;\n}\n\nexport type RedactionAction =\n | StartRedactionAction\n | EndRedactionAction\n | AddPendingAction\n | RemovePendingAction\n | ClearPendingAction\n | SelectPendingAction\n | DeselectPendingAction;\n\nexport const addPending = (items: RedactionItem[]): AddPendingAction => ({\n type: ADD_PENDING,\n payload: items,\n});\nexport const removePending = (page: number, id: string): RemovePendingAction => ({\n type: REMOVE_PENDING,\n payload: { page, id },\n});\nexport const clearPending = (): ClearPendingAction => ({ type: CLEAR_PENDING });\n\nexport const startRedaction = (): StartRedactionAction => ({ type: START_REDACTION });\nexport const endRedaction = (): EndRedactionAction => ({ type: END_REDACTION });\n\nexport const selectPending = (page: number, id: string): SelectPendingAction => ({\n type: SELECT_PENDING,\n payload: { page, id },\n});\nexport const deselectPending = (): DeselectPendingAction => ({ type: DESELECT_PENDING });\n","import { Position, Rect, Size } from '@embedpdf/models';\nimport { clamp } from '@embedpdf/core';\nimport {\n EmbedPdfPointerEvent,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\n\nexport function createMarqueeHandler(opts: {\n pageSize: Size;\n scale: number;\n minDragPx?: number;\n onPreview?: (rect: Rect | null) => void;\n onCommit?: (rect: Rect) => void;\n}): PointerEventHandlersWithLifecycle<EmbedPdfPointerEvent> {\n const { pageSize, scale, minDragPx = 5, onPreview, onCommit } = opts;\n\n let start: Position | null = null;\n let last: Rect | null = null;\n\n return {\n onPointerDown: (pos, evt) => {\n start = pos;\n last = { origin: { x: pos.x, y: pos.y }, size: { width: 0, height: 0 } };\n onPreview?.(last);\n evt.setPointerCapture?.();\n },\n onPointerMove: (pos) => {\n if (!start) return;\n const x = clamp(pos.x, 0, pageSize.width);\n const y = clamp(pos.y, 0, pageSize.height);\n last = {\n origin: { x: Math.min(start.x, x), y: Math.min(start.y, y) },\n size: { width: Math.abs(x - start.x), height: Math.abs(y - start.y) },\n };\n onPreview?.(last);\n },\n onPointerUp: (_pos, evt) => {\n if (last) {\n const dragPx = Math.max(last.size.width, last.size.height) * scale;\n if (dragPx > minDragPx) onCommit?.(last);\n }\n start = null;\n last = null;\n onPreview?.(null);\n evt.releasePointerCapture?.();\n },\n onPointerCancel: (_pos, evt) => {\n start = null;\n last = null;\n onPreview?.(null);\n evt.releasePointerCapture?.();\n },\n };\n}\n","import {\n RedactionPluginConfig,\n RedactionCapability,\n RedactionState,\n RegisterMarqueeOnPageOptions,\n RedactionItem,\n SelectedRedaction,\n} from './types';\nimport {\n BasePlugin,\n createBehaviorEmitter,\n PluginRegistry,\n refreshDocument,\n refreshPages,\n Unsubscribe,\n} from '@embedpdf/core';\nimport {\n ignore,\n PdfEngine,\n PdfErrorCode,\n PdfErrorReason,\n PdfTask,\n PdfTaskHelper,\n Rect,\n Task,\n uuidV4,\n} from '@embedpdf/models';\nimport {\n FormattedSelection,\n SelectionCapability,\n SelectionPlugin,\n} from '@embedpdf/plugin-selection';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n} from '@embedpdf/plugin-interaction-manager';\nimport {\n addPending,\n clearPending,\n deselectPending,\n endRedaction,\n removePending,\n selectPending,\n startRedaction,\n} from './actions';\nimport { createMarqueeHandler } from './handlers';\n\nexport class RedactionPlugin extends BasePlugin<\n RedactionPluginConfig,\n RedactionCapability,\n RedactionState\n> {\n static readonly id = 'redaction' as const;\n private config: RedactionPluginConfig;\n\n private selectionCapability: SelectionCapability | undefined;\n private interactionManagerCapability: InteractionManagerCapability | undefined;\n\n private readonly redactionSelection$ = createBehaviorEmitter<FormattedSelection[]>();\n private readonly pending$ = createBehaviorEmitter<Record<number, RedactionItem[]>>();\n private readonly selected$ = createBehaviorEmitter<SelectedRedaction | null>();\n\n private readonly unsubscribeSelectionChange: Unsubscribe | undefined;\n private readonly unsubscribeEndSelection: Unsubscribe | undefined;\n private readonly unsubscribeModeChange: Unsubscribe | undefined;\n\n constructor(id: string, registry: PluginRegistry, config: RedactionPluginConfig) {\n super(id, registry);\n this.config = config;\n\n this.selectionCapability = this.registry.getPlugin<SelectionPlugin>('selection')?.provides();\n this.interactionManagerCapability = this.registry\n .getPlugin<InteractionManagerPlugin>('interaction-manager')\n ?.provides();\n\n if (this.interactionManagerCapability) {\n this.interactionManagerCapability.registerMode({\n id: 'marqueeRedact',\n scope: 'page',\n exclusive: true,\n cursor: 'crosshair',\n });\n }\n\n if (this.interactionManagerCapability && this.selectionCapability) {\n this.interactionManagerCapability.registerMode({\n id: 'redactSelection',\n scope: 'page',\n exclusive: false,\n });\n this.selectionCapability.enableForMode('redactSelection');\n }\n\n this.unsubscribeModeChange = this.interactionManagerCapability?.onModeChange((state) => {\n if (state.activeMode === 'redactSelection' || state.activeMode === 'marqueeRedact')\n this.dispatch(startRedaction());\n else this.dispatch(endRedaction());\n });\n\n this.unsubscribeSelectionChange = this.selectionCapability?.onSelectionChange(() => {\n if (!this.selectionCapability) return;\n if (!this.state.isRedacting) return;\n const formattedSelection = this.selectionCapability.getFormattedSelection();\n this.redactionSelection$.emit(formattedSelection);\n });\n\n this.unsubscribeEndSelection = this.selectionCapability?.onEndSelection(() => {\n if (!this.selectionCapability) return;\n if (!this.state.isRedacting) return;\n\n const formattedSelection = this.selectionCapability.getFormattedSelection();\n\n const items: RedactionItem[] = formattedSelection.map((s) => ({\n id: uuidV4(),\n kind: 'text',\n page: s.pageIndex,\n boundingRect: s.rect,\n rects: s.segmentRects,\n }));\n\n this.dispatch(addPending(items));\n this.redactionSelection$.emit([]);\n this.selectionCapability.clear();\n this.pending$.emit(this.state.pending);\n if (items.length) {\n this.selectPending(items[items.length - 1].page, items[items.length - 1].id);\n }\n });\n }\n\n async initialize(_config: RedactionPluginConfig): Promise<void> {}\n\n protected buildCapability(): RedactionCapability {\n return {\n onRedactionSelectionChange: this.redactionSelection$.on,\n\n queueCurrentSelectionAsPending: () => this.queueCurrentSelectionAsPending(),\n\n enableMarqueeRedact: () => this.enableMarqueeRedact(),\n toggleMarqueeRedact: () => this.toggleMarqueeRedact(),\n isMarqueeRedactActive: () =>\n this.interactionManagerCapability?.getActiveMode() === 'marqueeRedact',\n\n enableRedactSelection: () => this.enableRedactSelection(),\n toggleRedactSelection: () => this.toggleRedactSelection(),\n isRedactSelectionActive: () =>\n this.interactionManagerCapability?.getActiveMode() === 'redactSelection',\n\n onPendingChange: this.pending$.on,\n removePending: (page, id) => {\n this.dispatch(removePending(page, id));\n this.pending$.emit(this.state.pending);\n },\n clearPending: () => {\n this.dispatch(clearPending());\n this.pending$.emit(this.state.pending);\n },\n commitAllPending: () => this.commitAllPending(),\n commitPending: (page, id) => this.commitPendingOne(page, id),\n\n endRedaction: () => this.endRedaction(),\n startRedaction: () => this.startRedaction(),\n\n onSelectionChange: this.selected$.on,\n selectPending: (page, id) => this.selectPending(page, id),\n deselectPending: () => this.deselectPending(),\n\n registerMarqueeOnPage: (opts) => this.registerMarqueeOnPage(opts),\n };\n }\n\n private selectPending(page: number, id: string) {\n this.dispatch(selectPending(page, id));\n this.selectionCapability?.clear();\n this.selected$.emit(this.state.selected);\n }\n private deselectPending() {\n this.dispatch(deselectPending());\n this.selected$.emit(this.state.selected);\n }\n\n private enableRedactSelection() {\n this.interactionManagerCapability?.activate('redactSelection');\n }\n private toggleRedactSelection() {\n if (this.interactionManagerCapability?.getActiveMode() === 'redactSelection')\n this.interactionManagerCapability?.activateDefaultMode();\n else this.interactionManagerCapability?.activate('redactSelection');\n }\n\n private enableMarqueeRedact() {\n this.interactionManagerCapability?.activate('marqueeRedact');\n }\n private toggleMarqueeRedact() {\n if (this.interactionManagerCapability?.getActiveMode() === 'marqueeRedact')\n this.interactionManagerCapability?.activateDefaultMode();\n else this.interactionManagerCapability?.activate('marqueeRedact');\n }\n\n private startRedaction() {\n this.interactionManagerCapability?.activate('redactSelection');\n }\n private endRedaction() {\n this.interactionManagerCapability?.activateDefaultMode();\n }\n\n public registerMarqueeOnPage(opts: RegisterMarqueeOnPageOptions) {\n if (!this.interactionManagerCapability) {\n this.logger.warn(\n 'RedactionPlugin',\n 'MissingDependency',\n 'Interaction manager plugin not loaded, marquee redaction disabled',\n );\n return () => {};\n }\n\n const document = this.coreState.core.document;\n if (!document) {\n this.logger.warn('RedactionPlugin', 'DocumentNotFound', 'Document not found');\n return () => {};\n }\n\n const page = document.pages[opts.pageIndex];\n if (!page) {\n this.logger.warn('RedactionPlugin', 'PageNotFound', `Page ${opts.pageIndex} not found`);\n return () => {};\n }\n\n const handlers = createMarqueeHandler({\n pageSize: page.size,\n scale: opts.scale,\n onPreview: opts.callback.onPreview,\n onCommit: (r) => {\n const item: RedactionItem = {\n id: uuidV4(),\n kind: 'area',\n page: opts.pageIndex,\n rect: r,\n };\n this.dispatch(addPending([item]));\n this.pending$.emit(this.state.pending);\n opts.callback.onCommit?.(r);\n this.enableRedactSelection();\n this.selectPending(opts.pageIndex, item.id);\n },\n });\n\n const off = this.interactionManagerCapability.registerAlways({\n handlers: {\n onPointerDown: (_, evt) => {\n if (evt.target === evt.currentTarget) {\n this.deselectPending();\n }\n },\n },\n scope: {\n type: 'page',\n pageIndex: opts.pageIndex,\n },\n });\n\n const off2 = this.interactionManagerCapability.registerHandlers({\n modeId: 'marqueeRedact',\n handlers,\n pageIndex: opts.pageIndex,\n });\n\n return () => {\n off();\n off2();\n };\n }\n\n private queueCurrentSelectionAsPending(): Task<boolean, PdfErrorReason> {\n if (!this.selectionCapability)\n return PdfTaskHelper.reject({\n code: PdfErrorCode.NotFound,\n message: '[RedactionPlugin] selection plugin required',\n });\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 formatted = this.selectionCapability.getFormattedSelection();\n if (!formatted.length) return PdfTaskHelper.resolve(true);\n\n const id = uuidV4();\n\n const items: RedactionItem[] = formatted.map((s) => ({\n id,\n kind: 'text',\n page: s.pageIndex,\n boundingRect: s.rect,\n rects: s.segmentRects,\n }));\n\n this.enableRedactSelection();\n this.dispatch(addPending(items));\n this.pending$.emit(this.state.pending);\n // optional: auto-select the last one added\n const last = items[items.length - 1];\n this.selectPending(last.page, last.id);\n\n // clear live UI selection\n this.redactionSelection$.emit([]);\n this.selectionCapability?.clear();\n\n return PdfTaskHelper.resolve(true);\n }\n\n private commitPendingOne(page: number, id: string): Task<boolean, PdfErrorReason> {\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n const item = (this.state.pending[page] ?? []).find((it) => it.id === id);\n if (!item) return PdfTaskHelper.resolve(true);\n\n const rects: Rect[] = item.kind === 'text' ? item.rects : [item.rect];\n const pdfPage = doc.pages[page];\n if (!pdfPage)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Page not found' });\n\n const task = new Task<boolean, PdfErrorReason>();\n this.engine\n .redactTextInRects(doc, pdfPage, rects, {\n drawBlackBoxes: this.config.drawBlackBoxes,\n })\n .wait(\n () => {\n this.dispatch(removePending(page, id));\n this.pending$.emit(this.state.pending);\n this.dispatchCoreAction(refreshPages([page]));\n task.resolve(true);\n },\n () => task.reject({ code: PdfErrorCode.Unknown, message: 'Failed to commit redactions' }),\n );\n\n return task;\n }\n\n private commitAllPending(): Task<boolean, PdfErrorReason> {\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n // group rects per page\n const perPage = new Map<number, Rect[]>();\n for (const [page, items] of Object.entries(this.state.pending)) {\n const p = Number(page);\n const list = perPage.get(p) ?? [];\n for (const it of items) {\n if (it.kind === 'text') list.push(...it.rects);\n else list.push(it.rect);\n }\n perPage.set(p, list);\n }\n\n const pagesToRefresh = Array.from(perPage.entries())\n .filter(([_, rects]) => rects.length > 0)\n .map(([pageIndex]) => pageIndex);\n\n const tasks: PdfTask<boolean>[] = [];\n for (const [pageIndex, rects] of perPage) {\n const page = doc.pages[pageIndex];\n if (!page) continue;\n if (!rects.length) continue;\n tasks.push(\n this.engine.redactTextInRects(doc, page, rects, {\n drawBlackBoxes: this.config.drawBlackBoxes,\n }),\n );\n }\n\n const task = new Task<boolean, PdfErrorReason>();\n Task.all(tasks).wait(\n () => {\n this.dispatch(clearPending());\n this.dispatchCoreAction(refreshPages(pagesToRefresh));\n this.pending$.emit(this.state.pending);\n task.resolve(true);\n },\n () => task.reject({ code: PdfErrorCode.Unknown, message: 'Failed to commit redactions' }),\n );\n\n return task;\n }\n\n override onStoreUpdated(_: RedactionState, newState: RedactionState): void {\n // keep external listeners in sync\n this.pending$.emit(newState.pending);\n this.selected$.emit(newState.selected);\n }\n\n async destroy(): Promise<void> {\n this.redactionSelection$.clear();\n this.pending$.clear();\n\n this.unsubscribeSelectionChange?.();\n this.unsubscribeEndSelection?.();\n this.unsubscribeModeChange?.();\n\n await super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { RedactionPluginConfig } from './types';\n\nexport const REDACTION_PLUGIN_ID = 'redaction';\n\nexport const manifest: PluginManifest<RedactionPluginConfig> = {\n id: REDACTION_PLUGIN_ID,\n name: 'Redaction Plugin',\n version: '1.0.0',\n provides: ['redaction'],\n requires: [],\n optional: ['interaction-manager', 'selection'],\n defaultConfig: {\n enabled: true,\n drawBlackBoxes: true,\n },\n};\n","import { RedactionState } from './types';\nimport {\n RedactionAction,\n ADD_PENDING,\n CLEAR_PENDING,\n END_REDACTION,\n REMOVE_PENDING,\n START_REDACTION,\n SELECT_PENDING,\n DESELECT_PENDING,\n} from './actions';\n\nexport const initialState: RedactionState = {\n isRedacting: false,\n pending: {},\n selected: null,\n};\n\nexport const redactionReducer = (state = initialState, action: RedactionAction): RedactionState => {\n switch (action.type) {\n case ADD_PENDING: {\n const next = { ...state.pending };\n for (const item of action.payload) {\n next[item.page] = (next[item.page] ?? []).concat(item);\n }\n return { ...state, pending: next };\n }\n\n case REMOVE_PENDING: {\n const { page, id } = action.payload;\n const list = state.pending[page] ?? [];\n const filtered = list.filter((it) => it.id !== id);\n const next = { ...state.pending, [page]: filtered };\n\n // if the removed one was selected → clear selection\n const stillSelected =\n state.selected && !(state.selected.page === page && state.selected.id === id);\n\n return { ...state, pending: next, selected: stillSelected ? state.selected : null };\n }\n\n case CLEAR_PENDING:\n return { ...state, pending: {}, selected: null };\n\n case SELECT_PENDING:\n return { ...state, selected: { page: action.payload.page, id: action.payload.id } };\n\n case DESELECT_PENDING:\n return { ...state, selected: null };\n\n case START_REDACTION:\n return { ...state, isRedacting: true };\n case END_REDACTION:\n return { ...state, pending: {}, selected: null, isRedacting: false };\n default:\n return state;\n }\n};\n","import { RedactionState } from './types';\n\nexport const getPendingRedactionsCount = (s: RedactionState) =>\n Object.values(s.pending).reduce((sum, list) => sum + (list?.length ?? 0), 0);\n\nexport const hasPendingRedactions = (s: RedactionState) =>\n Object.values(s.pending).some((list) => (list?.length ?? 0) > 0);\n","import { PluginPackage } from '@embedpdf/core';\nimport { RedactionPluginConfig, RedactionState } from './types';\nimport { RedactionPlugin } from './redaction-plugin';\nimport { manifest, REDACTION_PLUGIN_ID } from './manifest';\nimport { RedactionAction } from './actions';\nimport { initialState, redactionReducer } from './reducer';\n\nexport const RedactionPluginPackage: PluginPackage<\n RedactionPlugin,\n RedactionPluginConfig,\n RedactionState,\n RedactionAction\n> = {\n manifest,\n create: (registry, config) => new RedactionPlugin(REDACTION_PLUGIN_ID, registry, config),\n reducer: redactionReducer,\n initialState: initialState,\n};\n\nexport * from './redaction-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './selectors';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/types.ts","../src/lib/actions.ts","../src/lib/handlers/marquee-redact.handler.ts","../src/lib/redaction-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/selectors.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, EventHook } from '@embedpdf/core';\nimport { PdfErrorReason, Rect, Task } from '@embedpdf/models';\n\n// Redaction mode enum\nexport enum RedactionMode {\n MarqueeRedact = 'marqueeRedact',\n RedactSelection = 'redactSelection',\n}\n\nexport interface SelectedRedaction {\n page: number;\n id: string | null;\n}\n\nexport interface RedactionState {\n isRedacting: boolean;\n activeType: RedactionMode | null;\n pending: Record<number, RedactionItem[]>;\n pendingCount: number;\n selected: SelectedRedaction | null;\n}\n\nexport type RedactionItem =\n | {\n id: string;\n kind: 'text';\n page: number;\n rect: Rect;\n rects: Rect[];\n }\n | {\n id: string;\n kind: 'area';\n page: number;\n rect: Rect;\n };\n\nexport interface MarqueeRedactCallback {\n onPreview?: (rect: Rect | null) => void;\n onCommit?: (rect: Rect) => void;\n}\n\nexport interface RegisterMarqueeOnPageOptions {\n pageIndex: number;\n scale: number;\n callback: MarqueeRedactCallback;\n}\n\nexport interface RedactionPluginConfig extends BasePluginConfig {\n drawBlackBoxes: boolean;\n}\n\n// Add event types similar to annotation plugin\nexport type RedactionEvent =\n | {\n type: 'add';\n items: RedactionItem[];\n }\n | {\n type: 'remove';\n page: number;\n id: string;\n }\n | {\n type: 'clear';\n }\n | {\n type: 'commit';\n success: boolean;\n error?: PdfErrorReason;\n };\n\nexport interface RedactionCapability {\n queueCurrentSelectionAsPending: () => Task<boolean, PdfErrorReason>;\n\n enableMarqueeRedact: () => void;\n toggleMarqueeRedact: () => void;\n isMarqueeRedactActive: () => boolean;\n\n enableRedactSelection: () => void;\n toggleRedactSelection: () => void;\n isRedactSelectionActive: () => boolean;\n\n onPendingChange: EventHook<Record<number, RedactionItem[]>>;\n addPending: (items: RedactionItem[]) => void;\n removePending: (page: number, id: string) => void;\n clearPending: () => void;\n commitAllPending: () => Task<boolean, PdfErrorReason>;\n commitPending: (page: number, id: string) => Task<boolean, PdfErrorReason>;\n\n endRedaction: () => void;\n startRedaction: () => void;\n\n selectPending: (page: number, id: string) => void;\n deselectPending: () => void;\n\n // Event hook for redaction events\n onSelectedChange: EventHook<SelectedRedaction | null>;\n onRedactionEvent: EventHook<RedactionEvent>;\n onStateChange: EventHook<RedactionState>;\n}\n","import { Action } from '@embedpdf/core';\nimport { RedactionItem, RedactionMode } from './types';\n\nexport const START_REDACTION = 'START_REDACTION';\nexport const END_REDACTION = 'END_REDACTION';\nexport const SET_ACTIVE_TYPE = 'SET_ACTIVE_TYPE';\n\nexport const ADD_PENDING = 'ADD_PENDING';\nexport const REMOVE_PENDING = 'REMOVE_PENDING';\nexport const CLEAR_PENDING = 'CLEAR_PENDING';\n\nexport const SELECT_PENDING = 'SELECT_PENDING';\nexport const DESELECT_PENDING = 'DESELECT_PENDING';\n\nexport interface StartRedactionAction extends Action {\n type: typeof START_REDACTION;\n payload: RedactionMode;\n}\nexport interface EndRedactionAction extends Action {\n type: typeof END_REDACTION;\n}\nexport interface SetActiveTypeAction extends Action {\n type: typeof SET_ACTIVE_TYPE;\n payload: RedactionMode | null;\n}\n\nexport interface AddPendingAction extends Action {\n type: typeof ADD_PENDING;\n payload: RedactionItem[];\n}\nexport interface RemovePendingAction extends Action {\n type: typeof REMOVE_PENDING;\n payload: { page: number; id: string };\n}\nexport interface ClearPendingAction extends Action {\n type: typeof CLEAR_PENDING;\n}\n\nexport interface SelectPendingAction extends Action {\n type: typeof SELECT_PENDING;\n payload: { page: number; id: string };\n}\nexport interface DeselectPendingAction extends Action {\n type: typeof DESELECT_PENDING;\n}\n\nexport type RedactionAction =\n | StartRedactionAction\n | EndRedactionAction\n | SetActiveTypeAction\n | AddPendingAction\n | RemovePendingAction\n | ClearPendingAction\n | SelectPendingAction\n | DeselectPendingAction;\n\nexport const addPending = (items: RedactionItem[]): AddPendingAction => ({\n type: ADD_PENDING,\n payload: items,\n});\nexport const removePending = (page: number, id: string): RemovePendingAction => ({\n type: REMOVE_PENDING,\n payload: { page, id },\n});\nexport const clearPending = (): ClearPendingAction => ({ type: CLEAR_PENDING });\n\nexport const startRedaction = (mode: RedactionMode): StartRedactionAction => ({\n type: START_REDACTION,\n payload: mode,\n});\nexport const endRedaction = (): EndRedactionAction => ({ type: END_REDACTION });\nexport const setActiveType = (mode: RedactionMode | null): SetActiveTypeAction => ({\n type: SET_ACTIVE_TYPE,\n payload: mode,\n});\n\nexport const selectPending = (page: number, id: string): SelectPendingAction => ({\n type: SELECT_PENDING,\n payload: { page, id },\n});\nexport const deselectPending = (): DeselectPendingAction => ({ type: DESELECT_PENDING });\n","import { Position, Rect, Size } from '@embedpdf/models';\nimport { clamp } from '@embedpdf/core';\nimport {\n EmbedPdfPointerEvent,\n PointerEventHandlersWithLifecycle,\n} from '@embedpdf/plugin-interaction-manager';\n\nexport function createMarqueeHandler(opts: {\n pageSize: Size;\n scale: number;\n minDragPx?: number;\n onPreview?: (rect: Rect | null) => void;\n onCommit?: (rect: Rect) => void;\n}): PointerEventHandlersWithLifecycle<EmbedPdfPointerEvent> {\n const { pageSize, scale, minDragPx = 5, onPreview, onCommit } = opts;\n\n let start: Position | null = null;\n let last: Rect | null = null;\n\n return {\n onPointerDown: (pos, evt) => {\n start = pos;\n last = { origin: { x: pos.x, y: pos.y }, size: { width: 0, height: 0 } };\n onPreview?.(last);\n evt.setPointerCapture?.();\n },\n onPointerMove: (pos) => {\n if (!start) return;\n const x = clamp(pos.x, 0, pageSize.width);\n const y = clamp(pos.y, 0, pageSize.height);\n last = {\n origin: { x: Math.min(start.x, x), y: Math.min(start.y, y) },\n size: { width: Math.abs(x - start.x), height: Math.abs(y - start.y) },\n };\n onPreview?.(last);\n },\n onPointerUp: (_pos, evt) => {\n if (last) {\n const dragPx = Math.max(last.size.width, last.size.height) * scale;\n if (dragPx > minDragPx) onCommit?.(last);\n }\n start = null;\n last = null;\n onPreview?.(null);\n evt.releasePointerCapture?.();\n },\n onPointerCancel: (_pos, evt) => {\n start = null;\n last = null;\n onPreview?.(null);\n evt.releasePointerCapture?.();\n },\n };\n}\n","import {\n RedactionPluginConfig,\n RedactionCapability,\n RedactionState,\n RegisterMarqueeOnPageOptions,\n RedactionItem,\n SelectedRedaction,\n RedactionMode,\n RedactionEvent,\n} from './types';\nimport {\n BasePlugin,\n createBehaviorEmitter,\n PluginRegistry,\n refreshPages,\n Unsubscribe,\n} from '@embedpdf/core';\nimport {\n PdfErrorCode,\n PdfErrorReason,\n PdfTask,\n PdfTaskHelper,\n Rect,\n Task,\n uuidV4,\n} from '@embedpdf/models';\nimport {\n FormattedSelection,\n SelectionCapability,\n SelectionPlugin,\n} from '@embedpdf/plugin-selection';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n} from '@embedpdf/plugin-interaction-manager';\nimport {\n addPending,\n clearPending,\n deselectPending,\n endRedaction,\n removePending,\n selectPending,\n startRedaction,\n} from './actions';\nimport { createMarqueeHandler } from './handlers';\n\nexport class RedactionPlugin extends BasePlugin<\n RedactionPluginConfig,\n RedactionCapability,\n RedactionState\n> {\n static readonly id = 'redaction' as const;\n private config: RedactionPluginConfig;\n\n private selectionCapability: SelectionCapability | undefined;\n private interactionManagerCapability: InteractionManagerCapability | undefined;\n\n private readonly redactionSelection$ = createBehaviorEmitter<FormattedSelection[]>();\n private readonly pending$ = createBehaviorEmitter<Record<number, RedactionItem[]>>();\n private readonly selected$ = createBehaviorEmitter<SelectedRedaction | null>();\n private readonly state$ = createBehaviorEmitter<RedactionState>();\n private readonly events$ = createBehaviorEmitter<RedactionEvent>();\n\n private readonly unsubscribeSelectionChange: Unsubscribe | undefined;\n private readonly unsubscribeEndSelection: Unsubscribe | undefined;\n private readonly unsubscribeModeChange: Unsubscribe | undefined;\n\n constructor(id: string, registry: PluginRegistry, config: RedactionPluginConfig) {\n super(id, registry);\n this.config = config;\n\n this.selectionCapability = this.registry.getPlugin<SelectionPlugin>('selection')?.provides();\n this.interactionManagerCapability = this.registry\n .getPlugin<InteractionManagerPlugin>('interaction-manager')\n ?.provides();\n\n if (this.interactionManagerCapability) {\n this.interactionManagerCapability.registerMode({\n id: RedactionMode.MarqueeRedact,\n scope: 'page',\n exclusive: true,\n cursor: 'crosshair',\n });\n }\n\n if (this.interactionManagerCapability && this.selectionCapability) {\n this.interactionManagerCapability.registerMode({\n id: RedactionMode.RedactSelection,\n scope: 'page',\n exclusive: false,\n });\n this.selectionCapability.enableForMode(RedactionMode.RedactSelection);\n }\n\n this.unsubscribeModeChange = this.interactionManagerCapability?.onModeChange((state) => {\n if (state.activeMode === RedactionMode.RedactSelection) {\n this.dispatch(startRedaction(RedactionMode.RedactSelection));\n } else if (state.activeMode === RedactionMode.MarqueeRedact) {\n this.dispatch(startRedaction(RedactionMode.MarqueeRedact));\n } else {\n this.dispatch(endRedaction());\n }\n });\n\n this.unsubscribeSelectionChange = this.selectionCapability?.onSelectionChange(() => {\n if (!this.selectionCapability) return;\n if (!this.state.isRedacting) return;\n const formattedSelection = this.selectionCapability.getFormattedSelection();\n this.redactionSelection$.emit(formattedSelection);\n });\n\n this.unsubscribeEndSelection = this.selectionCapability?.onEndSelection(() => {\n if (!this.selectionCapability) return;\n if (!this.state.isRedacting) return;\n\n const formattedSelection = this.selectionCapability.getFormattedSelection();\n\n const items: RedactionItem[] = formattedSelection.map((s) => ({\n id: uuidV4(),\n kind: 'text',\n page: s.pageIndex,\n rect: s.rect,\n rects: s.segmentRects,\n }));\n\n this.dispatch(addPending(items));\n this.redactionSelection$.emit([]);\n this.selectionCapability.clear();\n this.pending$.emit(this.state.pending);\n if (items.length) {\n this.selectPending(items[items.length - 1].page, items[items.length - 1].id);\n }\n });\n }\n\n async initialize(_config: RedactionPluginConfig): Promise<void> {}\n\n protected buildCapability(): RedactionCapability {\n return {\n queueCurrentSelectionAsPending: () => this.queueCurrentSelectionAsPending(),\n\n enableMarqueeRedact: () => this.enableMarqueeRedact(),\n toggleMarqueeRedact: () => this.toggleMarqueeRedact(),\n isMarqueeRedactActive: () =>\n this.interactionManagerCapability?.getActiveMode() === RedactionMode.MarqueeRedact,\n\n enableRedactSelection: () => this.enableRedactSelection(),\n toggleRedactSelection: () => this.toggleRedactSelection(),\n isRedactSelectionActive: () =>\n this.interactionManagerCapability?.getActiveMode() === RedactionMode.RedactSelection,\n\n addPending: (items) => {\n this.dispatch(addPending(items));\n this.pending$.emit(this.state.pending);\n this.events$.emit({ type: 'add', items });\n },\n removePending: (page, id) => {\n this.dispatch(removePending(page, id));\n this.pending$.emit(this.state.pending);\n this.events$.emit({ type: 'remove', page, id });\n },\n clearPending: () => {\n this.dispatch(clearPending());\n this.pending$.emit(this.state.pending);\n this.events$.emit({ type: 'clear' });\n },\n commitAllPending: () => this.commitAllPending(),\n commitPending: (page, id) => this.commitPendingOne(page, id),\n\n endRedaction: () => this.endRedaction(),\n startRedaction: () => this.startRedaction(),\n\n selectPending: (page, id) => this.selectPending(page, id),\n deselectPending: () => this.deselectPending(),\n\n onSelectedChange: this.selected$.on,\n onRedactionEvent: this.events$.on,\n onStateChange: this.state$.on,\n onPendingChange: this.pending$.on,\n };\n }\n\n public onRedactionSelectionChange(\n callback: (formattedSelection: FormattedSelection[]) => void,\n ): Unsubscribe {\n return this.redactionSelection$.on(callback);\n }\n\n private selectPending(page: number, id: string) {\n this.dispatch(selectPending(page, id));\n this.selectionCapability?.clear();\n this.selected$.emit(this.state.selected);\n }\n private deselectPending() {\n this.dispatch(deselectPending());\n this.selected$.emit(this.state.selected);\n }\n\n private enableRedactSelection() {\n this.interactionManagerCapability?.activate(RedactionMode.RedactSelection);\n }\n private toggleRedactSelection() {\n if (this.interactionManagerCapability?.getActiveMode() === RedactionMode.RedactSelection)\n this.interactionManagerCapability?.activateDefaultMode();\n else this.interactionManagerCapability?.activate(RedactionMode.RedactSelection);\n }\n\n private enableMarqueeRedact() {\n this.interactionManagerCapability?.activate(RedactionMode.MarqueeRedact);\n }\n private toggleMarqueeRedact() {\n if (this.interactionManagerCapability?.getActiveMode() === RedactionMode.MarqueeRedact)\n this.interactionManagerCapability?.activateDefaultMode();\n else this.interactionManagerCapability?.activate(RedactionMode.MarqueeRedact);\n }\n\n private startRedaction() {\n this.interactionManagerCapability?.activate(RedactionMode.RedactSelection);\n }\n private endRedaction() {\n this.interactionManagerCapability?.activateDefaultMode();\n }\n\n public registerMarqueeOnPage(opts: RegisterMarqueeOnPageOptions) {\n if (!this.interactionManagerCapability) {\n this.logger.warn(\n 'RedactionPlugin',\n 'MissingDependency',\n 'Interaction manager plugin not loaded, marquee redaction disabled',\n );\n return () => {};\n }\n\n const document = this.coreState.core.document;\n if (!document) {\n this.logger.warn('RedactionPlugin', 'DocumentNotFound', 'Document not found');\n return () => {};\n }\n\n const page = document.pages[opts.pageIndex];\n if (!page) {\n this.logger.warn('RedactionPlugin', 'PageNotFound', `Page ${opts.pageIndex} not found`);\n return () => {};\n }\n\n const handlers = createMarqueeHandler({\n pageSize: page.size,\n scale: opts.scale,\n onPreview: opts.callback.onPreview,\n onCommit: (r) => {\n const item: RedactionItem = {\n id: uuidV4(),\n kind: 'area',\n page: opts.pageIndex,\n rect: r,\n };\n this.dispatch(addPending([item]));\n this.pending$.emit(this.state.pending);\n opts.callback.onCommit?.(r);\n this.enableRedactSelection();\n this.selectPending(opts.pageIndex, item.id);\n },\n });\n\n const off = this.interactionManagerCapability.registerAlways({\n handlers: {\n onPointerDown: (_, evt) => {\n if (evt.target === evt.currentTarget) {\n this.deselectPending();\n }\n },\n },\n scope: {\n type: 'page',\n pageIndex: opts.pageIndex,\n },\n });\n\n const off2 = this.interactionManagerCapability.registerHandlers({\n modeId: RedactionMode.MarqueeRedact,\n handlers,\n pageIndex: opts.pageIndex,\n });\n\n return () => {\n off();\n off2();\n };\n }\n\n private queueCurrentSelectionAsPending(): Task<boolean, PdfErrorReason> {\n if (!this.selectionCapability)\n return PdfTaskHelper.reject({\n code: PdfErrorCode.NotFound,\n message: '[RedactionPlugin] selection plugin required',\n });\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 formatted = this.selectionCapability.getFormattedSelection();\n if (!formatted.length) return PdfTaskHelper.resolve(true);\n\n const id = uuidV4();\n\n const items: RedactionItem[] = formatted.map((s) => ({\n id,\n kind: 'text',\n page: s.pageIndex,\n rect: s.rect,\n rects: s.segmentRects,\n }));\n\n this.enableRedactSelection();\n this.dispatch(addPending(items));\n this.pending$.emit(this.state.pending);\n // optional: auto-select the last one added\n const last = items[items.length - 1];\n this.selectPending(last.page, last.id);\n\n // clear live UI selection\n this.redactionSelection$.emit([]);\n this.selectionCapability?.clear();\n\n return PdfTaskHelper.resolve(true);\n }\n\n private commitPendingOne(page: number, id: string): Task<boolean, PdfErrorReason> {\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n const item = (this.state.pending[page] ?? []).find((it) => it.id === id);\n if (!item) return PdfTaskHelper.resolve(true);\n\n const rects: Rect[] = item.kind === 'text' ? item.rects : [item.rect];\n const pdfPage = doc.pages[page];\n if (!pdfPage)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Page not found' });\n\n const task = new Task<boolean, PdfErrorReason>();\n this.engine\n .redactTextInRects(doc, pdfPage, rects, {\n drawBlackBoxes: this.config.drawBlackBoxes,\n })\n .wait(\n () => {\n this.dispatch(removePending(page, id));\n this.pending$.emit(this.state.pending);\n this.dispatchCoreAction(refreshPages([page]));\n this.events$.emit({ type: 'commit', success: true });\n task.resolve(true);\n },\n (error) => {\n this.events$.emit({ type: 'commit', success: false, error: error.reason });\n task.reject({ code: PdfErrorCode.Unknown, message: 'Failed to commit redactions' });\n },\n );\n\n return task;\n }\n\n private commitAllPending(): Task<boolean, PdfErrorReason> {\n const doc = this.coreState.core.document;\n if (!doc)\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not found' });\n\n // group rects per page\n const perPage = new Map<number, Rect[]>();\n for (const [page, items] of Object.entries(this.state.pending)) {\n const p = Number(page);\n const list = perPage.get(p) ?? [];\n for (const it of items) {\n if (it.kind === 'text') list.push(...it.rects);\n else list.push(it.rect);\n }\n perPage.set(p, list);\n }\n\n const pagesToRefresh = Array.from(perPage.entries())\n .filter(([_, rects]) => rects.length > 0)\n .map(([pageIndex]) => pageIndex);\n\n const tasks: PdfTask<boolean>[] = [];\n for (const [pageIndex, rects] of perPage) {\n const page = doc.pages[pageIndex];\n if (!page) continue;\n if (!rects.length) continue;\n tasks.push(\n this.engine.redactTextInRects(doc, page, rects, {\n drawBlackBoxes: this.config.drawBlackBoxes,\n }),\n );\n }\n\n const task = new Task<boolean, PdfErrorReason>();\n Task.all(tasks).wait(\n () => {\n this.dispatch(clearPending());\n this.dispatchCoreAction(refreshPages(pagesToRefresh));\n this.pending$.emit(this.state.pending);\n this.events$.emit({ type: 'commit', success: true });\n task.resolve(true);\n },\n (error) => {\n this.events$.emit({ type: 'commit', success: false, error: error.reason });\n task.reject({ code: PdfErrorCode.Unknown, message: 'Failed to commit redactions' });\n },\n );\n\n return task;\n }\n\n override onStoreUpdated(_: RedactionState, newState: RedactionState): void {\n // keep external listeners in sync\n this.pending$.emit(newState.pending);\n this.selected$.emit(newState.selected);\n this.state$.emit(newState);\n }\n\n async destroy(): Promise<void> {\n this.redactionSelection$.clear();\n this.pending$.clear();\n this.state$.clear();\n this.events$.clear();\n\n this.unsubscribeSelectionChange?.();\n this.unsubscribeEndSelection?.();\n this.unsubscribeModeChange?.();\n\n await super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { RedactionPluginConfig } from './types';\n\nexport const REDACTION_PLUGIN_ID = 'redaction';\n\nexport const manifest: PluginManifest<RedactionPluginConfig> = {\n id: REDACTION_PLUGIN_ID,\n name: 'Redaction Plugin',\n version: '1.0.0',\n provides: ['redaction'],\n requires: [],\n optional: ['interaction-manager', 'selection'],\n defaultConfig: {\n enabled: true,\n drawBlackBoxes: true,\n },\n};\n","import { RedactionItem, RedactionState } from './types';\nimport {\n RedactionAction,\n ADD_PENDING,\n CLEAR_PENDING,\n END_REDACTION,\n REMOVE_PENDING,\n START_REDACTION,\n SET_ACTIVE_TYPE,\n SELECT_PENDING,\n DESELECT_PENDING,\n} from './actions';\n\n// Helper function to calculate total pending count\nconst calculatePendingCount = (pending: Record<number, RedactionItem[]>): number => {\n return Object.values(pending).reduce((total, items) => total + items.length, 0);\n};\n\nexport const initialState: RedactionState = {\n isRedacting: false,\n activeType: null,\n pending: {},\n pendingCount: 0,\n selected: null,\n};\n\nexport const redactionReducer = (state = initialState, action: RedactionAction): RedactionState => {\n switch (action.type) {\n case ADD_PENDING: {\n const next = { ...state.pending };\n for (const item of action.payload) {\n next[item.page] = (next[item.page] ?? []).concat(item);\n }\n return { ...state, pending: next, pendingCount: calculatePendingCount(next) };\n }\n\n case REMOVE_PENDING: {\n const { page, id } = action.payload;\n const list = state.pending[page] ?? [];\n const filtered = list.filter((it) => it.id !== id);\n const next = { ...state.pending, [page]: filtered };\n\n // if the removed one was selected → clear selection\n const stillSelected =\n state.selected && !(state.selected.page === page && state.selected.id === id);\n\n return {\n ...state,\n pending: next,\n pendingCount: calculatePendingCount(next),\n selected: stillSelected ? state.selected : null,\n };\n }\n\n case CLEAR_PENDING:\n return { ...state, pending: {}, pendingCount: 0, selected: null };\n\n case SELECT_PENDING:\n return { ...state, selected: { page: action.payload.page, id: action.payload.id } };\n\n case DESELECT_PENDING:\n return { ...state, selected: null };\n\n case START_REDACTION:\n return { ...state, isRedacting: true, activeType: action.payload };\n case END_REDACTION:\n return {\n ...state,\n pending: {},\n pendingCount: 0,\n selected: null,\n isRedacting: false,\n activeType: null,\n };\n case SET_ACTIVE_TYPE:\n return { ...state, activeType: action.payload };\n default:\n return state;\n }\n};\n","import { RedactionState } from './types';\n\nexport const getPendingRedactionsCount = (s: RedactionState) =>\n Object.values(s.pending).reduce((sum, list) => sum + (list?.length ?? 0), 0);\n\nexport const hasPendingRedactions = (s: RedactionState) =>\n Object.values(s.pending).some((list) => (list?.length ?? 0) > 0);\n","import { PluginPackage } from '@embedpdf/core';\nimport { RedactionPluginConfig, RedactionState } from './types';\nimport { RedactionPlugin } from './redaction-plugin';\nimport { manifest, REDACTION_PLUGIN_ID } from './manifest';\nimport { RedactionAction } from './actions';\nimport { initialState, redactionReducer } from './reducer';\n\nexport const RedactionPluginPackage: PluginPackage<\n RedactionPlugin,\n RedactionPluginConfig,\n RedactionState,\n RedactionAction\n> = {\n manifest,\n create: (registry, config) => new RedactionPlugin(REDACTION_PLUGIN_ID, registry, config),\n reducer: redactionReducer,\n initialState: initialState,\n};\n\nexport * from './redaction-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './selectors';\nexport { initialState } from './reducer';\n"],"names":["RedactionMode"],"mappings":";;AAIY,IAAA,kCAAAA,mBAAL;AACLA,iBAAA,eAAgB,IAAA;AAChBA,iBAAA,iBAAkB,IAAA;AAFRA,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;ACDL,MAAM,kBAAkB;AACxB,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AAExB,MAAM,cAAc;AACpB,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AAEtB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AA4CnB,MAAA,aAAa,CAAC,WAA8C;AAAA,EACvE,MAAM;AAAA,EACN,SAAS;AACX;AACa,MAAA,gBAAgB,CAAC,MAAc,QAAqC;AAAA,EAC/E,MAAM;AAAA,EACN,SAAS,EAAE,MAAM,GAAG;AACtB;AACO,MAAM,eAAe,OAA2B,EAAE,MAAM;AAElD,MAAA,iBAAiB,CAAC,UAA+C;AAAA,EAC5E,MAAM;AAAA,EACN,SAAS;AACX;AACO,MAAM,eAAe,OAA2B,EAAE,MAAM;AAMlD,MAAA,gBAAgB,CAAC,MAAc,QAAqC;AAAA,EAC/E,MAAM;AAAA,EACN,SAAS,EAAE,MAAM,GAAG;AACtB;AACO,MAAM,kBAAkB,OAA8B,EAAE,MAAM;ACzE9D,SAAS,qBAAqB,MAMuB;AAC1D,QAAM,EAAE,UAAU,OAAO,YAAY,GAAG,WAAW,aAAa;AAEhE,MAAI,QAAyB;AAC7B,MAAI,OAAoB;AAEjB,SAAA;AAAA,IACL,eAAe,CAAC,KAAK,QAAQ;;AACnB,cAAA;AACR,aAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE,OAAO,GAAG,QAAQ,IAAI;AACvE,6CAAY;AACZ,gBAAI,sBAAJ;AAAA,IACF;AAAA,IACA,eAAe,CAAC,QAAQ;AACtB,UAAI,CAAC,MAAO;AACZ,YAAM,IAAI,MAAM,IAAI,GAAG,GAAG,SAAS,KAAK;AACxC,YAAM,IAAI,MAAM,IAAI,GAAG,GAAG,SAAS,MAAM;AAClC,aAAA;AAAA,QACL,QAAQ,EAAE,GAAG,KAAK,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE;AAAA,QAC3D,MAAM,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,QAAQ,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE;AAAA,MACtE;AACA,6CAAY;AAAA,IACd;AAAA,IACA,aAAa,CAAC,MAAM,QAAQ;;AAC1B,UAAI,MAAM;AACF,cAAA,SAAS,KAAK,IAAI,KAAK,KAAK,OAAO,KAAK,KAAK,MAAM,IAAI;AACzD,YAAA,SAAS,UAAW,sCAAW;AAAA,MAAI;AAEjC,cAAA;AACD,aAAA;AACP,6CAAY;AACZ,gBAAI,0BAAJ;AAAA,IACF;AAAA,IACA,iBAAiB,CAAC,MAAM,QAAQ;;AACtB,cAAA;AACD,aAAA;AACP,6CAAY;AACZ,gBAAI,0BAAJ;AAAA,IAA4B;AAAA,EAEhC;AACF;ACPO,MAAM,mBAAN,MAAM,yBAAwB,WAInC;AAAA,EAiBA,YAAY,IAAY,UAA0B,QAA+B;;AAC/E,UAAM,IAAI,QAAQ;AAXpB,SAAiB,sBAAsB,sBAA4C;AACnF,SAAiB,WAAW,sBAAuD;AACnF,SAAiB,YAAY,sBAAgD;AAC7E,SAAiB,SAAS,sBAAsC;AAChE,SAAiB,UAAU,sBAAsC;AAQ/D,SAAK,SAAS;AAEd,SAAK,uBAAsB,UAAK,SAAS,UAA2B,WAAW,MAApD,mBAAuD;AAClF,SAAK,gCAA+B,UAAK,SACtC,UAAoC,qBAAqB,MADxB,mBAEhC;AAEJ,QAAI,KAAK,8BAA8B;AACrC,WAAK,6BAA6B,aAAa;AAAA,QAC7C,IAAI,cAAc;AAAA,QAClB,OAAO;AAAA,QACP,WAAW;AAAA,QACX,QAAQ;AAAA,MAAA,CACT;AAAA,IAAA;AAGC,QAAA,KAAK,gCAAgC,KAAK,qBAAqB;AACjE,WAAK,6BAA6B,aAAa;AAAA,QAC7C,IAAI,cAAc;AAAA,QAClB,OAAO;AAAA,QACP,WAAW;AAAA,MAAA,CACZ;AACI,WAAA,oBAAoB,cAAc,cAAc,eAAe;AAAA,IAAA;AAGtE,SAAK,yBAAwB,UAAK,iCAAL,mBAAmC,aAAa,CAAC,UAAU;AAClF,UAAA,MAAM,eAAe,cAAc,iBAAiB;AACtD,aAAK,SAAS,eAAe,cAAc,eAAe,CAAC;AAAA,MAClD,WAAA,MAAM,eAAe,cAAc,eAAe;AAC3D,aAAK,SAAS,eAAe,cAAc,aAAa,CAAC;AAAA,MAAA,OACpD;AACA,aAAA,SAAS,cAAc;AAAA,MAAA;AAAA,IAC9B;AAGF,SAAK,8BAA6B,UAAK,wBAAL,mBAA0B,kBAAkB,MAAM;AAC9E,UAAA,CAAC,KAAK,oBAAqB;AAC3B,UAAA,CAAC,KAAK,MAAM,YAAa;AACvB,YAAA,qBAAqB,KAAK,oBAAoB,sBAAsB;AACrE,WAAA,oBAAoB,KAAK,kBAAkB;AAAA,IAAA;AAGlD,SAAK,2BAA0B,UAAK,wBAAL,mBAA0B,eAAe,MAAM;AACxE,UAAA,CAAC,KAAK,oBAAqB;AAC3B,UAAA,CAAC,KAAK,MAAM,YAAa;AAEvB,YAAA,qBAAqB,KAAK,oBAAoB,sBAAsB;AAE1E,YAAM,QAAyB,mBAAmB,IAAI,CAAC,OAAO;AAAA,QAC5D,IAAI,OAAO;AAAA,QACX,MAAM;AAAA,QACN,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,MAAA,EACT;AAEG,WAAA,SAAS,WAAW,KAAK,CAAC;AAC1B,WAAA,oBAAoB,KAAK,EAAE;AAChC,WAAK,oBAAoB,MAAM;AAC/B,WAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,UAAI,MAAM,QAAQ;AAChB,aAAK,cAAc,MAAM,MAAM,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,SAAS,CAAC,EAAE,EAAE;AAAA,MAAA;AAAA,IAC7E;AAAA,EACD;AAAA,EAGH,MAAM,WAAW,SAA+C;AAAA,EAAA;AAAA,EAEtD,kBAAuC;AACxC,WAAA;AAAA,MACL,gCAAgC,MAAM,KAAK,+BAA+B;AAAA,MAE1E,qBAAqB,MAAM,KAAK,oBAAoB;AAAA,MACpD,qBAAqB,MAAM,KAAK,oBAAoB;AAAA,MACpD,uBAAuB,MACrB;;AAAA,2BAAK,iCAAL,mBAAmC,qBAAoB,cAAc;AAAA;AAAA,MAEvE,uBAAuB,MAAM,KAAK,sBAAsB;AAAA,MACxD,uBAAuB,MAAM,KAAK,sBAAsB;AAAA,MACxD,yBAAyB,MACvB;;AAAA,2BAAK,iCAAL,mBAAmC,qBAAoB,cAAc;AAAA;AAAA,MAEvE,YAAY,CAAC,UAAU;AAChB,aAAA,SAAS,WAAW,KAAK,CAAC;AAC/B,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,aAAK,QAAQ,KAAK,EAAE,MAAM,OAAO,OAAO;AAAA,MAC1C;AAAA,MACA,eAAe,CAAC,MAAM,OAAO;AAC3B,aAAK,SAAS,cAAc,MAAM,EAAE,CAAC;AACrC,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,aAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,MAAM,IAAI;AAAA,MAChD;AAAA,MACA,cAAc,MAAM;AACb,aAAA,SAAS,cAAc;AAC5B,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,aAAK,QAAQ,KAAK,EAAE,MAAM,SAAS;AAAA,MACrC;AAAA,MACA,kBAAkB,MAAM,KAAK,iBAAiB;AAAA,MAC9C,eAAe,CAAC,MAAM,OAAO,KAAK,iBAAiB,MAAM,EAAE;AAAA,MAE3D,cAAc,MAAM,KAAK,aAAa;AAAA,MACtC,gBAAgB,MAAM,KAAK,eAAe;AAAA,MAE1C,eAAe,CAAC,MAAM,OAAO,KAAK,cAAc,MAAM,EAAE;AAAA,MACxD,iBAAiB,MAAM,KAAK,gBAAgB;AAAA,MAE5C,kBAAkB,KAAK,UAAU;AAAA,MACjC,kBAAkB,KAAK,QAAQ;AAAA,MAC/B,eAAe,KAAK,OAAO;AAAA,MAC3B,iBAAiB,KAAK,SAAS;AAAA,IACjC;AAAA,EAAA;AAAA,EAGK,2BACL,UACa;AACN,WAAA,KAAK,oBAAoB,GAAG,QAAQ;AAAA,EAAA;AAAA,EAGrC,cAAc,MAAc,IAAY;;AAC9C,SAAK,SAAS,cAAc,MAAM,EAAE,CAAC;AACrC,eAAK,wBAAL,mBAA0B;AAC1B,SAAK,UAAU,KAAK,KAAK,MAAM,QAAQ;AAAA,EAAA;AAAA,EAEjC,kBAAkB;AACnB,SAAA,SAAS,iBAAiB;AAC/B,SAAK,UAAU,KAAK,KAAK,MAAM,QAAQ;AAAA,EAAA;AAAA,EAGjC,wBAAwB;;AACzB,eAAA,iCAAA,mBAA8B,SAAS,cAAc;AAAA,EAAe;AAAA,EAEnE,wBAAwB;;AAC9B,UAAI,UAAK,iCAAL,mBAAmC,qBAAoB,cAAc;AACvE,iBAAK,iCAAL,mBAAmC;AAAA,QAC3B,YAAA,iCAAA,mBAA8B,SAAS,cAAc;AAAA,EAAe;AAAA,EAGxE,sBAAsB;;AACvB,eAAA,iCAAA,mBAA8B,SAAS,cAAc;AAAA,EAAa;AAAA,EAEjE,sBAAsB;;AAC5B,UAAI,UAAK,iCAAL,mBAAmC,qBAAoB,cAAc;AACvE,iBAAK,iCAAL,mBAAmC;AAAA,QAC3B,YAAA,iCAAA,mBAA8B,SAAS,cAAc;AAAA,EAAa;AAAA,EAGtE,iBAAiB;;AAClB,eAAA,iCAAA,mBAA8B,SAAS,cAAc;AAAA,EAAe;AAAA,EAEnE,eAAe;;AACrB,eAAK,iCAAL,mBAAmC;AAAA,EAAoB;AAAA,EAGlD,sBAAsB,MAAoC;AAC3D,QAAA,CAAC,KAAK,8BAA8B;AACtC,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,MAAM;AAAA,MAAC;AAAA,IAAA;AAGV,UAAA,WAAW,KAAK,UAAU,KAAK;AACrC,QAAI,CAAC,UAAU;AACb,WAAK,OAAO,KAAK,mBAAmB,oBAAoB,oBAAoB;AAC5E,aAAO,MAAM;AAAA,MAAC;AAAA,IAAA;AAGhB,UAAM,OAAO,SAAS,MAAM,KAAK,SAAS;AAC1C,QAAI,CAAC,MAAM;AACT,WAAK,OAAO,KAAK,mBAAmB,gBAAgB,QAAQ,KAAK,SAAS,YAAY;AACtF,aAAO,MAAM;AAAA,MAAC;AAAA,IAAA;AAGhB,UAAM,WAAW,qBAAqB;AAAA,MACpC,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK,SAAS;AAAA,MACzB,UAAU,CAAC,MAAM;;AACf,cAAM,OAAsB;AAAA,UAC1B,IAAI,OAAO;AAAA,UACX,MAAM;AAAA,UACN,MAAM,KAAK;AAAA,UACX,MAAM;AAAA,QACR;AACA,aAAK,SAAS,WAAW,CAAC,IAAI,CAAC,CAAC;AAChC,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AAChC,yBAAA,UAAS,aAAT,4BAAoB;AACzB,aAAK,sBAAsB;AAC3B,aAAK,cAAc,KAAK,WAAW,KAAK,EAAE;AAAA,MAAA;AAAA,IAC5C,CACD;AAEK,UAAA,MAAM,KAAK,6BAA6B,eAAe;AAAA,MAC3D,UAAU;AAAA,QACR,eAAe,CAAC,GAAG,QAAQ;AACrB,cAAA,IAAI,WAAW,IAAI,eAAe;AACpC,iBAAK,gBAAgB;AAAA,UAAA;AAAA,QACvB;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,WAAW,KAAK;AAAA,MAAA;AAAA,IAClB,CACD;AAEK,UAAA,OAAO,KAAK,6BAA6B,iBAAiB;AAAA,MAC9D,QAAQ,cAAc;AAAA,MACtB;AAAA,MACA,WAAW,KAAK;AAAA,IAAA,CACjB;AAED,WAAO,MAAM;AACP,UAAA;AACC,WAAA;AAAA,IACP;AAAA,EAAA;AAAA,EAGM,iCAAgE;;AACtE,QAAI,CAAC,KAAK;AACR,aAAO,cAAc,OAAO;AAAA,QAC1B,MAAM,aAAa;AAAA,QACnB,SAAS;AAAA,MAAA,CACV;AAEG,UAAA,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,CAAC;AACI,aAAA,cAAc,OAAO,EAAE,MAAM,aAAa,UAAU,SAAS,sBAAsB;AAEtF,UAAA,YAAY,KAAK,oBAAoB,sBAAsB;AACjE,QAAI,CAAC,UAAU,OAAe,QAAA,cAAc,QAAQ,IAAI;AAExD,UAAM,KAAK,OAAO;AAElB,UAAM,QAAyB,UAAU,IAAI,CAAC,OAAO;AAAA,MACnD;AAAA,MACA,MAAM;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,IAAA,EACT;AAEF,SAAK,sBAAsB;AACtB,SAAA,SAAS,WAAW,KAAK,CAAC;AAC/B,SAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AAErC,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,SAAK,cAAc,KAAK,MAAM,KAAK,EAAE;AAGhC,SAAA,oBAAoB,KAAK,EAAE;AAChC,eAAK,wBAAL,mBAA0B;AAEnB,WAAA,cAAc,QAAQ,IAAI;AAAA,EAAA;AAAA,EAG3B,iBAAiB,MAAc,IAA2C;AAC1E,UAAA,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,CAAC;AACI,aAAA,cAAc,OAAO,EAAE,MAAM,aAAa,UAAU,SAAS,sBAAsB;AAE5F,UAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,EAAE;AACvE,QAAI,CAAC,KAAa,QAAA,cAAc,QAAQ,IAAI;AAEtC,UAAA,QAAgB,KAAK,SAAS,SAAS,KAAK,QAAQ,CAAC,KAAK,IAAI;AAC9D,UAAA,UAAU,IAAI,MAAM,IAAI;AAC9B,QAAI,CAAC;AACI,aAAA,cAAc,OAAO,EAAE,MAAM,aAAa,UAAU,SAAS,kBAAkB;AAElF,UAAA,OAAO,IAAI,KAA8B;AAC/C,SAAK,OACF,kBAAkB,KAAK,SAAS,OAAO;AAAA,MACtC,gBAAgB,KAAK,OAAO;AAAA,IAC7B,CAAA,EACA;AAAA,MACC,MAAM;AACJ,aAAK,SAAS,cAAc,MAAM,EAAE,CAAC;AACrC,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,aAAK,mBAAmB,aAAa,CAAC,IAAI,CAAC,CAAC;AAC5C,aAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,SAAS,MAAM;AACnD,aAAK,QAAQ,IAAI;AAAA,MACnB;AAAA,MACA,CAAC,UAAU;AACJ,aAAA,QAAQ,KAAK,EAAE,MAAM,UAAU,SAAS,OAAO,OAAO,MAAM,OAAA,CAAQ;AACzE,aAAK,OAAO,EAAE,MAAM,aAAa,SAAS,SAAS,+BAA+B;AAAA,MAAA;AAAA,IAEtF;AAEK,WAAA;AAAA,EAAA;AAAA,EAGD,mBAAkD;AAClD,UAAA,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,CAAC;AACI,aAAA,cAAc,OAAO,EAAE,MAAM,aAAa,UAAU,SAAS,sBAAsB;AAGtF,UAAA,8BAAc,IAAoB;AAC7B,eAAA,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,OAAO,GAAG;AACxD,YAAA,IAAI,OAAO,IAAI;AACrB,YAAM,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC;AAChC,iBAAW,MAAM,OAAO;AACtB,YAAI,GAAG,SAAS,aAAa,KAAK,GAAG,GAAG,KAAK;AAAA,YACxC,MAAK,KAAK,GAAG,IAAI;AAAA,MAAA;AAEhB,cAAA,IAAI,GAAG,IAAI;AAAA,IAAA;AAGf,UAAA,iBAAiB,MAAM,KAAK,QAAQ,SAAS,EAChD,OAAO,CAAC,CAAC,GAAG,KAAK,MAAM,MAAM,SAAS,CAAC,EACvC,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS;AAEjC,UAAM,QAA4B,CAAC;AACnC,eAAW,CAAC,WAAW,KAAK,KAAK,SAAS;AAClC,YAAA,OAAO,IAAI,MAAM,SAAS;AAChC,UAAI,CAAC,KAAM;AACP,UAAA,CAAC,MAAM,OAAQ;AACb,YAAA;AAAA,QACJ,KAAK,OAAO,kBAAkB,KAAK,MAAM,OAAO;AAAA,UAC9C,gBAAgB,KAAK,OAAO;AAAA,QAC7B,CAAA;AAAA,MACH;AAAA,IAAA;AAGI,UAAA,OAAO,IAAI,KAA8B;AAC1C,SAAA,IAAI,KAAK,EAAE;AAAA,MACd,MAAM;AACC,aAAA,SAAS,cAAc;AACvB,aAAA,mBAAmB,aAAa,cAAc,CAAC;AACpD,aAAK,SAAS,KAAK,KAAK,MAAM,OAAO;AACrC,aAAK,QAAQ,KAAK,EAAE,MAAM,UAAU,SAAS,MAAM;AACnD,aAAK,QAAQ,IAAI;AAAA,MACnB;AAAA,MACA,CAAC,UAAU;AACJ,aAAA,QAAQ,KAAK,EAAE,MAAM,UAAU,SAAS,OAAO,OAAO,MAAM,OAAA,CAAQ;AACzE,aAAK,OAAO,EAAE,MAAM,aAAa,SAAS,SAAS,+BAA+B;AAAA,MAAA;AAAA,IAEtF;AAEO,WAAA;AAAA,EAAA;AAAA,EAGA,eAAe,GAAmB,UAAgC;AAEpE,SAAA,SAAS,KAAK,SAAS,OAAO;AAC9B,SAAA,UAAU,KAAK,SAAS,QAAQ;AAChC,SAAA,OAAO,KAAK,QAAQ;AAAA,EAAA;AAAA,EAG3B,MAAM,UAAyB;;AAC7B,SAAK,oBAAoB,MAAM;AAC/B,SAAK,SAAS,MAAM;AACpB,SAAK,OAAO,MAAM;AAClB,SAAK,QAAQ,MAAM;AAEnB,eAAK,+BAAL;AACA,eAAK,4BAAL;AACA,eAAK,0BAAL;AAEA,UAAM,MAAM,QAAQ;AAAA,EAAA;AAExB;AA9XE,iBAAgB,KAAK;AALhB,IAAM,kBAAN;AC3CA,MAAM,sBAAsB;AAE5B,MAAM,WAAkD;AAAA,EAC7D,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,CAAC,WAAW;AAAA,EACtB,UAAU,CAAC;AAAA,EACX,UAAU,CAAC,uBAAuB,WAAW;AAAA,EAC7C,eAAe;AAAA,IACb,SAAS;AAAA,IACT,gBAAgB;AAAA,EAAA;AAEpB;ACFA,MAAM,wBAAwB,CAAC,YAAqD;AAC3E,SAAA,OAAO,OAAO,OAAO,EAAE,OAAO,CAAC,OAAO,UAAU,QAAQ,MAAM,QAAQ,CAAC;AAChF;AAEO,MAAM,eAA+B;AAAA,EAC1C,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,SAAS,CAAC;AAAA,EACV,cAAc;AAAA,EACd,UAAU;AACZ;AAEO,MAAM,mBAAmB,CAAC,QAAQ,cAAc,WAA4C;AACjG,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,aAAa;AAChB,YAAM,OAAO,EAAE,GAAG,MAAM,QAAQ;AACrB,iBAAA,QAAQ,OAAO,SAAS;AAC5B,aAAA,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,CAAA,GAAI,OAAO,IAAI;AAAA,MAAA;AAEhD,aAAA,EAAE,GAAG,OAAO,SAAS,MAAM,cAAc,sBAAsB,IAAI,EAAE;AAAA,IAAA;AAAA,IAG9E,KAAK,gBAAgB;AACnB,YAAM,EAAE,MAAM,GAAG,IAAI,OAAO;AAC5B,YAAM,OAAO,MAAM,QAAQ,IAAI,KAAK,CAAC;AACrC,YAAM,WAAW,KAAK,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE;AAC3C,YAAA,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,GAAG,SAAS;AAG5C,YAAA,gBACJ,MAAM,YAAY,EAAE,MAAM,SAAS,SAAS,QAAQ,MAAM,SAAS,OAAO;AAErE,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,cAAc,sBAAsB,IAAI;AAAA,QACxC,UAAU,gBAAgB,MAAM,WAAW;AAAA,MAC7C;AAAA,IAAA;AAAA,IAGF,KAAK;AACI,aAAA,EAAE,GAAG,OAAO,SAAS,CAAA,GAAI,cAAc,GAAG,UAAU,KAAK;AAAA,IAElE,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,UAAU,EAAE,MAAM,OAAO,QAAQ,MAAM,IAAI,OAAO,QAAQ,KAAK;AAAA,IAEpF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,UAAU,KAAK;AAAA,IAEpC,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,aAAa,MAAM,YAAY,OAAO,QAAQ;AAAA,IACnE,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,UAAU;AAAA,QACV,aAAa;AAAA,QACb,YAAY;AAAA,MACd;AAAA,IACF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,YAAY,OAAO,QAAQ;AAAA,IAChD;AACS,aAAA;AAAA,EAAA;AAEb;AC7EO,MAAM,4BAA4B,CAAC,MACxC,OAAO,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,SAAS,QAAO,6BAAM,WAAU,IAAI,CAAC;AAEtE,MAAM,uBAAuB,CAAC,MACnC,OAAO,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,WAAU,6BAAM,WAAU,KAAK,CAAC;ACC1D,MAAM,yBAKT;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,UAAU,WAAW,IAAI,gBAAgB,qBAAqB,UAAU,MAAM;AAAA,EACvF,SAAS;AAAA,EACT;AACF;"}
|
package/dist/lib/actions.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Action } from '@embedpdf/core';
|
|
2
|
-
import { RedactionItem } from './types';
|
|
2
|
+
import { RedactionItem, RedactionMode } from './types';
|
|
3
3
|
export declare const START_REDACTION = "START_REDACTION";
|
|
4
4
|
export declare const END_REDACTION = "END_REDACTION";
|
|
5
|
+
export declare const SET_ACTIVE_TYPE = "SET_ACTIVE_TYPE";
|
|
5
6
|
export declare const ADD_PENDING = "ADD_PENDING";
|
|
6
7
|
export declare const REMOVE_PENDING = "REMOVE_PENDING";
|
|
7
8
|
export declare const CLEAR_PENDING = "CLEAR_PENDING";
|
|
@@ -9,10 +10,15 @@ export declare const SELECT_PENDING = "SELECT_PENDING";
|
|
|
9
10
|
export declare const DESELECT_PENDING = "DESELECT_PENDING";
|
|
10
11
|
export interface StartRedactionAction extends Action {
|
|
11
12
|
type: typeof START_REDACTION;
|
|
13
|
+
payload: RedactionMode;
|
|
12
14
|
}
|
|
13
15
|
export interface EndRedactionAction extends Action {
|
|
14
16
|
type: typeof END_REDACTION;
|
|
15
17
|
}
|
|
18
|
+
export interface SetActiveTypeAction extends Action {
|
|
19
|
+
type: typeof SET_ACTIVE_TYPE;
|
|
20
|
+
payload: RedactionMode | null;
|
|
21
|
+
}
|
|
16
22
|
export interface AddPendingAction extends Action {
|
|
17
23
|
type: typeof ADD_PENDING;
|
|
18
24
|
payload: RedactionItem[];
|
|
@@ -37,11 +43,12 @@ export interface SelectPendingAction extends Action {
|
|
|
37
43
|
export interface DeselectPendingAction extends Action {
|
|
38
44
|
type: typeof DESELECT_PENDING;
|
|
39
45
|
}
|
|
40
|
-
export type RedactionAction = StartRedactionAction | EndRedactionAction | AddPendingAction | RemovePendingAction | ClearPendingAction | SelectPendingAction | DeselectPendingAction;
|
|
46
|
+
export type RedactionAction = StartRedactionAction | EndRedactionAction | SetActiveTypeAction | AddPendingAction | RemovePendingAction | ClearPendingAction | SelectPendingAction | DeselectPendingAction;
|
|
41
47
|
export declare const addPending: (items: RedactionItem[]) => AddPendingAction;
|
|
42
48
|
export declare const removePending: (page: number, id: string) => RemovePendingAction;
|
|
43
49
|
export declare const clearPending: () => ClearPendingAction;
|
|
44
|
-
export declare const startRedaction: () => StartRedactionAction;
|
|
50
|
+
export declare const startRedaction: (mode: RedactionMode) => StartRedactionAction;
|
|
45
51
|
export declare const endRedaction: () => EndRedactionAction;
|
|
52
|
+
export declare const setActiveType: (mode: RedactionMode | null) => SetActiveTypeAction;
|
|
46
53
|
export declare const selectPending: (page: number, id: string) => SelectPendingAction;
|
|
47
54
|
export declare const deselectPending: () => DeselectPendingAction;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RedactionPluginConfig, RedactionCapability, RedactionState, RegisterMarqueeOnPageOptions } from './types';
|
|
2
|
-
import { BasePlugin, PluginRegistry } from '@embedpdf/core';
|
|
2
|
+
import { BasePlugin, PluginRegistry, Unsubscribe } from '@embedpdf/core';
|
|
3
|
+
import { FormattedSelection } from '@embedpdf/plugin-selection';
|
|
3
4
|
export declare class RedactionPlugin extends BasePlugin<RedactionPluginConfig, RedactionCapability, RedactionState> {
|
|
4
5
|
static readonly id: "redaction";
|
|
5
6
|
private config;
|
|
@@ -8,12 +9,15 @@ export declare class RedactionPlugin extends BasePlugin<RedactionPluginConfig, R
|
|
|
8
9
|
private readonly redactionSelection$;
|
|
9
10
|
private readonly pending$;
|
|
10
11
|
private readonly selected$;
|
|
12
|
+
private readonly state$;
|
|
13
|
+
private readonly events$;
|
|
11
14
|
private readonly unsubscribeSelectionChange;
|
|
12
15
|
private readonly unsubscribeEndSelection;
|
|
13
16
|
private readonly unsubscribeModeChange;
|
|
14
17
|
constructor(id: string, registry: PluginRegistry, config: RedactionPluginConfig);
|
|
15
18
|
initialize(_config: RedactionPluginConfig): Promise<void>;
|
|
16
19
|
protected buildCapability(): RedactionCapability;
|
|
20
|
+
onRedactionSelectionChange(callback: (formattedSelection: FormattedSelection[]) => void): Unsubscribe;
|
|
17
21
|
private selectPending;
|
|
18
22
|
private deselectPending;
|
|
19
23
|
private enableRedactSelection;
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { BasePluginConfig, EventHook } from '@embedpdf/core';
|
|
2
2
|
import { PdfErrorReason, Rect, Task } from '@embedpdf/models';
|
|
3
|
-
|
|
3
|
+
export declare enum RedactionMode {
|
|
4
|
+
MarqueeRedact = "marqueeRedact",
|
|
5
|
+
RedactSelection = "redactSelection"
|
|
6
|
+
}
|
|
4
7
|
export interface SelectedRedaction {
|
|
5
8
|
page: number;
|
|
6
9
|
id: string | null;
|
|
7
10
|
}
|
|
8
11
|
export interface RedactionState {
|
|
9
12
|
isRedacting: boolean;
|
|
13
|
+
activeType: RedactionMode | null;
|
|
10
14
|
pending: Record<number, RedactionItem[]>;
|
|
15
|
+
pendingCount: number;
|
|
11
16
|
selected: SelectedRedaction | null;
|
|
12
17
|
}
|
|
13
18
|
export type RedactionItem = {
|
|
14
19
|
id: string;
|
|
15
20
|
kind: 'text';
|
|
16
21
|
page: number;
|
|
17
|
-
|
|
22
|
+
rect: Rect;
|
|
18
23
|
rects: Rect[];
|
|
19
24
|
} | {
|
|
20
25
|
id: string;
|
|
@@ -34,6 +39,20 @@ export interface RegisterMarqueeOnPageOptions {
|
|
|
34
39
|
export interface RedactionPluginConfig extends BasePluginConfig {
|
|
35
40
|
drawBlackBoxes: boolean;
|
|
36
41
|
}
|
|
42
|
+
export type RedactionEvent = {
|
|
43
|
+
type: 'add';
|
|
44
|
+
items: RedactionItem[];
|
|
45
|
+
} | {
|
|
46
|
+
type: 'remove';
|
|
47
|
+
page: number;
|
|
48
|
+
id: string;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'clear';
|
|
51
|
+
} | {
|
|
52
|
+
type: 'commit';
|
|
53
|
+
success: boolean;
|
|
54
|
+
error?: PdfErrorReason;
|
|
55
|
+
};
|
|
37
56
|
export interface RedactionCapability {
|
|
38
57
|
queueCurrentSelectionAsPending: () => Task<boolean, PdfErrorReason>;
|
|
39
58
|
enableMarqueeRedact: () => void;
|
|
@@ -42,16 +61,17 @@ export interface RedactionCapability {
|
|
|
42
61
|
enableRedactSelection: () => void;
|
|
43
62
|
toggleRedactSelection: () => void;
|
|
44
63
|
isRedactSelectionActive: () => boolean;
|
|
45
|
-
onRedactionSelectionChange: EventHook<FormattedSelection[]>;
|
|
46
64
|
onPendingChange: EventHook<Record<number, RedactionItem[]>>;
|
|
65
|
+
addPending: (items: RedactionItem[]) => void;
|
|
47
66
|
removePending: (page: number, id: string) => void;
|
|
48
67
|
clearPending: () => void;
|
|
49
68
|
commitAllPending: () => Task<boolean, PdfErrorReason>;
|
|
50
69
|
commitPending: (page: number, id: string) => Task<boolean, PdfErrorReason>;
|
|
51
70
|
endRedaction: () => void;
|
|
52
71
|
startRedaction: () => void;
|
|
53
|
-
onSelectionChange: EventHook<SelectedRedaction | null>;
|
|
54
72
|
selectPending: (page: number, id: string) => void;
|
|
55
73
|
deselectPending: () => void;
|
|
56
|
-
|
|
74
|
+
onSelectedChange: EventHook<SelectedRedaction | null>;
|
|
75
|
+
onRedactionEvent: EventHook<RedactionEvent>;
|
|
76
|
+
onStateChange: EventHook<RedactionState>;
|
|
57
77
|
}
|
package/dist/preact/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-redaction"),i=require("preact
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-redaction"),i=require("preact"),n=require("preact/hooks"),r=require("preact/jsx-runtime"),o=require("@embedpdf/utils/preact"),s=require("@embedpdf/models"),a=()=>e.usePlugin(t.RedactionPlugin.id),l=()=>e.useCapability(t.RedactionPlugin.id),d=({pageIndex:e,scale:t,className:i,stroke:o="red",fill:s="transparent"})=>{const{plugin:l}=a(),[d,c]=n.useState(null);return n.useEffect((()=>{if(l)return l.registerMarqueeOnPage({pageIndex:e,scale:t,callback:{onPreview:c}})}),[l,e]),d?r.jsx("div",{style:{position:"absolute",pointerEvents:"none",left:d.origin.x*t,top:d.origin.y*t,width:d.size.width*t,height:d.size.height*t,border:`1px solid ${o}`,background:s,boxSizing:"border-box"},className:i}):null};function c({color:e="#FFFF00",opacity:t=1,border:i="1px solid red",rects:n,rect:o,scale:s,onClick:a,style:l,...d}){return r.jsx(r.Fragment,{children:n.map(((n,c)=>r.jsx("div",{onPointerDown:a,onTouchStart:a,style:{position:"absolute",border:i,left:(o?n.origin.x-o.origin.x:n.origin.x)*s,top:(o?n.origin.y-o.origin.y:n.origin.y)*s,width:n.size.width*s,height:n.size.height*s,background:e,opacity:t,pointerEvents:a?"auto":"none",cursor:a?"pointer":"default",zIndex:a?1:void 0,...l},...d},c)))})}function u({pageIndex:e,scale:t}){const{plugin:i}=a(),[o,s]=n.useState([]),[l,d]=n.useState(null);return n.useEffect((()=>{if(i)return i.onRedactionSelectionChange((t=>{const i=t.find((t=>t.pageIndex===e));s((null==i?void 0:i.segmentRects)??[]),d((null==i?void 0:i.rect)??null)}))}),[i,e]),l?r.jsx("div",{style:{mixBlendMode:"normal",pointerEvents:"none",position:"absolute",inset:0},children:r.jsx(c,{color:"transparent",opacity:1,rects:o,scale:t,border:"1px solid red"})}):null}function p({pageIndex:e,scale:t,bboxStroke:a="rgba(0,0,0,0.8)",rotation:d=s.Rotation.Degree0,selectionMenu:u}){const{provides:p}=l(),[g,x]=n.useState([]),[h,b]=n.useState(null);n.useEffect((()=>{if(!p)return;const t=p.onPendingChange((t=>x(t[e]??[]))),i=p.onSelectedChange((t=>{b(t&&t.page===e?t.id:null)}));return()=>{null==t||t(),null==i||i()}}),[p,e]);const f=n.useCallback(((t,i)=>{t.stopPropagation(),p&&p.selectPending(e,i)}),[p,e]);return g.length?r.jsx("div",{style:{position:"absolute",inset:0,pointerEvents:"none"},children:g.map((n=>{if("area"===n.kind){const s=n.rect;return r.jsxs(i.Fragment,{children:[r.jsx("div",{style:{position:"absolute",left:s.origin.x*t,top:s.origin.y*t,width:s.size.width*t,height:s.size.height*t,background:"transparent",outline:h===n.id?`1px solid ${a}`:"none",outlineOffset:"2px",border:"1px solid red",pointerEvents:"auto",cursor:"pointer"},onPointerDown:e=>f(e,n.id),onTouchStart:e=>f(e,n.id)}),r.jsx(o.CounterRotate,{rect:{origin:{x:s.origin.x*t,y:s.origin.y*t},size:{width:s.size.width*t,height:s.size.height*t}},rotation:d,children:({rect:t,menuWrapperProps:i})=>u&&u({item:n,selected:h===n.id,pageIndex:e,menuWrapperProps:i,rect:t})})]},n.id)}const s=n.rect;return r.jsxs(i.Fragment,{children:[r.jsx("div",{style:{position:"absolute",left:s.origin.x*t,top:s.origin.y*t,width:s.size.width*t,height:s.size.height*t,background:"transparent",outline:h===n.id?`1px solid ${a}`:"none",outlineOffset:"2px",pointerEvents:"auto",cursor:h===n.id?"pointer":"default"},children:r.jsx(c,{rect:s,rects:n.rects,color:"transparent",border:"1px solid red",scale:t,onClick:e=>f(e,n.id)})}),r.jsx(o.CounterRotate,{rect:{origin:{x:s.origin.x*t,y:s.origin.y*t},size:{width:s.size.width*t,height:s.size.height*t}},rotation:d,children:({rect:t,menuWrapperProps:i})=>u&&u({item:n,selected:h===n.id,pageIndex:e,menuWrapperProps:i,rect:t})})]},n.id)}))}):null}exports.RedactionLayer=({pageIndex:e,scale:t,rotation:n=s.Rotation.Degree0,selectionMenu:o})=>r.jsxs(i.Fragment,{children:[r.jsx(p,{pageIndex:e,scale:t,rotation:n,selectionMenu:o}),r.jsx(d,{pageIndex:e,scale:t}),r.jsx(u,{pageIndex:e,scale:t})]}),exports.useRedaction=()=>{const{provides:e}=l(),[i,r]=n.useState(t.initialState);return n.useEffect((()=>null==e?void 0:e.onStateChange((e=>{r(e)}))),[e]),{state:i,provides:e}},exports.useRedactionCapability=l,exports.useRedactionPlugin=a,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { RedactionPlugin } from '@embedpdf/plugin-redaction';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n","import { useEffect, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n pageIndex,\n scale,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.registerMarqueeOnPage({\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 0.5,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\n\nimport { useEffect, useState } from '@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ pageIndex, scale }: SelectionRedactProps) {\n const { provides: redactionProvides } = useRedactionCapability();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionProvides) return;\n\n return redactionProvides.onRedactionSelectionChange((formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionProvides, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { SelectionMenuProps } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport function PendingRedactions({\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n const off1 = redaction.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = redaction.onSelectionChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, pageIndex]);\n\n if (!items.length) return null;\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.selectPending(pageIndex, id);\n },\n [redaction, pageIndex],\n );\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n }\n // kind === 'text' → draw bounding box; inner rects are not drawn here to avoid clutter.\n const b = it.boundingRect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment } from '@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { SelectionMenuProps } from './types';\n\ninterface RedactionLayerProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport const RedactionLayer = ({\n pageIndex,\n scale,\n rotation = Rotation.Degree0,\n selectionMenu,\n}: RedactionLayerProps) => {\n return (\n <Fragment>\n <PendingRedactions\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact pageIndex={pageIndex} scale={scale} />\n <SelectionRedact pageIndex={pageIndex} scale={scale} />\n </Fragment>\n );\n};\n"],"names":["useRedactionPlugin","usePlugin","RedactionPlugin","id","useRedactionCapability","useCapability","MarqueeRedact","pageIndex","scale","className","stroke","fill","plugin","redactionPlugin","rect","setRect","useState","useEffect","registerMarqueeOnPage","callback","onPreview","jsxRuntime","jsx","style","position","pointerEvents","left","origin","x","top","y","width","size","height","border","background","boxSizing","Highlight","color","opacity","rects","onClick","props","Fragment","children","map","b","i","onPointerDown","onTouchStart","cursor","zIndex","SelectionRedact","provides","redactionProvides","setRects","boundingRect","setBoundingRect","onRedactionSelectionChange","formattedSelection","selection","find","s","segmentRects","mixBlendMode","inset","PendingRedactions","bboxStroke","rotation","Rotation","Degree0","selectionMenu","redaction","items","setItems","selectedId","setSelectedId","off1","onPendingChange","off2","onSelectionChange","sel","page","length","select","useCallback","e","stopPropagation","selectPending","it","kind","r","outline","outlineOffset","CounterRotate","menuWrapperProps","item","selected"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, RedactionPlugin, RedactionState } from '@embedpdf/plugin-redaction';\nimport { useState, useEffect } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = () => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionState>(initialState);\n\n useEffect(() => {\n return provides?.onStateChange((action) => {\n setState(action);\n });\n }, [provides]);\n\n return {\n state,\n provides,\n };\n};\n","import { useEffect, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n pageIndex,\n scale,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.registerMarqueeOnPage({\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\n\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n\n return redactionPlugin.onRedactionSelectionChange((formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { SelectionMenuProps } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport function PendingRedactions({\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n const off1 = redaction.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = redaction.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.selectPending(pageIndex, id);\n },\n [redaction, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n }\n // kind === 'text' → draw bounding box; inner rects are not drawn here to avoid clutter.\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment } from '@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { SelectionMenuProps } from './types';\n\ninterface RedactionLayerProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport const RedactionLayer = ({\n pageIndex,\n scale,\n rotation = Rotation.Degree0,\n selectionMenu,\n}: RedactionLayerProps) => {\n return (\n <Fragment>\n <PendingRedactions\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact pageIndex={pageIndex} scale={scale} />\n <SelectionRedact pageIndex={pageIndex} scale={scale} />\n </Fragment>\n );\n};\n"],"names":["useRedactionPlugin","usePlugin","RedactionPlugin","id","useRedactionCapability","useCapability","MarqueeRedact","pageIndex","scale","className","stroke","fill","plugin","redactionPlugin","rect","setRect","useState","useEffect","registerMarqueeOnPage","callback","onPreview","jsxRuntime","jsx","style","position","pointerEvents","left","origin","x","top","y","width","size","height","border","background","boxSizing","Highlight","color","opacity","rects","onClick","props","Fragment","children","map","b","i","onPointerDown","onTouchStart","cursor","zIndex","SelectionRedact","setRects","boundingRect","setBoundingRect","onRedactionSelectionChange","formattedSelection","selection","find","s","segmentRects","mixBlendMode","inset","PendingRedactions","bboxStroke","rotation","Rotation","Degree0","selectionMenu","provides","redaction","items","setItems","selectedId","setSelectedId","off1","onPendingChange","off2","onSelectedChange","sel","page","select","useCallback","e","stopPropagation","selectPending","length","it","kind","r","outline","outlineOffset","CounterRotate","menuWrapperProps","item","selected","state","setState","initialState","onStateChange","action"],"mappings":"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"}
|
package/dist/preact/index.js
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import { usePlugin, useCapability } from "@embedpdf/core/preact";
|
|
2
|
-
import { RedactionPlugin } from "@embedpdf/plugin-redaction";
|
|
2
|
+
import { RedactionPlugin, initialState } from "@embedpdf/plugin-redaction";
|
|
3
3
|
export * from "@embedpdf/plugin-redaction";
|
|
4
|
-
import { jsx, Fragment, jsxs } from "preact/jsx-runtime";
|
|
5
4
|
import { Fragment as Fragment$1 } from "preact";
|
|
6
5
|
import { useState, useEffect, useCallback } from "preact/hooks";
|
|
6
|
+
import { jsx, Fragment, jsxs } from "preact/jsx-runtime";
|
|
7
7
|
import { CounterRotate } from "@embedpdf/utils/preact";
|
|
8
8
|
import { Rotation } from "@embedpdf/models";
|
|
9
9
|
const useRedactionPlugin = () => usePlugin(RedactionPlugin.id);
|
|
10
10
|
const useRedactionCapability = () => useCapability(RedactionPlugin.id);
|
|
11
|
+
const useRedaction = () => {
|
|
12
|
+
const { provides } = useRedactionCapability();
|
|
13
|
+
const [state, setState] = useState(initialState);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
return provides == null ? void 0 : provides.onStateChange((action) => {
|
|
16
|
+
setState(action);
|
|
17
|
+
});
|
|
18
|
+
}, [provides]);
|
|
19
|
+
return {
|
|
20
|
+
state,
|
|
21
|
+
provides
|
|
22
|
+
};
|
|
23
|
+
};
|
|
11
24
|
const MarqueeRedact = ({
|
|
12
25
|
pageIndex,
|
|
13
26
|
scale,
|
|
@@ -48,7 +61,7 @@ const MarqueeRedact = ({
|
|
|
48
61
|
};
|
|
49
62
|
function Highlight({
|
|
50
63
|
color = "#FFFF00",
|
|
51
|
-
opacity =
|
|
64
|
+
opacity = 1,
|
|
52
65
|
border = "1px solid red",
|
|
53
66
|
rects,
|
|
54
67
|
rect,
|
|
@@ -82,17 +95,17 @@ function Highlight({
|
|
|
82
95
|
)) });
|
|
83
96
|
}
|
|
84
97
|
function SelectionRedact({ pageIndex, scale }) {
|
|
85
|
-
const {
|
|
98
|
+
const { plugin: redactionPlugin } = useRedactionPlugin();
|
|
86
99
|
const [rects, setRects] = useState([]);
|
|
87
100
|
const [boundingRect, setBoundingRect] = useState(null);
|
|
88
101
|
useEffect(() => {
|
|
89
|
-
if (!
|
|
90
|
-
return
|
|
102
|
+
if (!redactionPlugin) return;
|
|
103
|
+
return redactionPlugin.onRedactionSelectionChange((formattedSelection) => {
|
|
91
104
|
const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);
|
|
92
105
|
setRects((selection == null ? void 0 : selection.segmentRects) ?? []);
|
|
93
106
|
setBoundingRect((selection == null ? void 0 : selection.rect) ?? null);
|
|
94
107
|
});
|
|
95
|
-
}, [
|
|
108
|
+
}, [redactionPlugin, pageIndex]);
|
|
96
109
|
if (!boundingRect) return null;
|
|
97
110
|
return /* @__PURE__ */ jsx(
|
|
98
111
|
"div",
|
|
@@ -129,7 +142,7 @@ function PendingRedactions({
|
|
|
129
142
|
useEffect(() => {
|
|
130
143
|
if (!redaction) return;
|
|
131
144
|
const off1 = redaction.onPendingChange((map) => setItems(map[pageIndex] ?? []));
|
|
132
|
-
const off2 = redaction.
|
|
145
|
+
const off2 = redaction.onSelectedChange((sel) => {
|
|
133
146
|
setSelectedId(sel && sel.page === pageIndex ? sel.id : null);
|
|
134
147
|
});
|
|
135
148
|
return () => {
|
|
@@ -137,7 +150,6 @@ function PendingRedactions({
|
|
|
137
150
|
off2 == null ? void 0 : off2();
|
|
138
151
|
};
|
|
139
152
|
}, [redaction, pageIndex]);
|
|
140
|
-
if (!items.length) return null;
|
|
141
153
|
const select = useCallback(
|
|
142
154
|
(e, id) => {
|
|
143
155
|
e.stopPropagation();
|
|
@@ -146,6 +158,7 @@ function PendingRedactions({
|
|
|
146
158
|
},
|
|
147
159
|
[redaction, pageIndex]
|
|
148
160
|
);
|
|
161
|
+
if (!items.length) return null;
|
|
149
162
|
return /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, pointerEvents: "none" }, children: items.map((it) => {
|
|
150
163
|
if (it.kind === "area") {
|
|
151
164
|
const r = it.rect;
|
|
@@ -189,7 +202,7 @@ function PendingRedactions({
|
|
|
189
202
|
)
|
|
190
203
|
] }, it.id);
|
|
191
204
|
}
|
|
192
|
-
const b = it.
|
|
205
|
+
const b = it.rect;
|
|
193
206
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
194
207
|
/* @__PURE__ */ jsx(
|
|
195
208
|
"div",
|
|
@@ -261,6 +274,7 @@ const RedactionLayer = ({
|
|
|
261
274
|
};
|
|
262
275
|
export {
|
|
263
276
|
RedactionLayer,
|
|
277
|
+
useRedaction,
|
|
264
278
|
useRedactionCapability,
|
|
265
279
|
useRedactionPlugin
|
|
266
280
|
};
|
package/dist/preact/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { RedactionPlugin } from '@embedpdf/plugin-redaction';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n","import { useEffect, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n pageIndex,\n scale,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.registerMarqueeOnPage({\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 0.5,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\n\nimport { useEffect, useState } from '@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ pageIndex, scale }: SelectionRedactProps) {\n const { provides: redactionProvides } = useRedactionCapability();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionProvides) return;\n\n return redactionProvides.onRedactionSelectionChange((formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionProvides, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { SelectionMenuProps } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport function PendingRedactions({\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n const off1 = redaction.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = redaction.onSelectionChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, pageIndex]);\n\n if (!items.length) return null;\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.selectPending(pageIndex, id);\n },\n [redaction, pageIndex],\n );\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n }\n // kind === 'text' → draw bounding box; inner rects are not drawn here to avoid clutter.\n const b = it.boundingRect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment } from '@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { SelectionMenuProps } from './types';\n\ninterface RedactionLayerProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport const RedactionLayer = ({\n pageIndex,\n scale,\n rotation = Rotation.Degree0,\n selectionMenu,\n}: RedactionLayerProps) => {\n return (\n <Fragment>\n <PendingRedactions\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact pageIndex={pageIndex} scale={scale} />\n <SelectionRedact pageIndex={pageIndex} scale={scale} />\n </Fragment>\n );\n};\n"],"names":["Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, RedactionPlugin, RedactionState } from '@embedpdf/plugin-redaction';\nimport { useState, useEffect } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = () => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionState>(initialState);\n\n useEffect(() => {\n return provides?.onStateChange((action) => {\n setState(action);\n });\n }, [provides]);\n\n return {\n state,\n provides,\n };\n};\n","import { useEffect, useState } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n pageIndex,\n scale,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.registerMarqueeOnPage({\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\n\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n\n return redactionPlugin.onRedactionSelectionChange((formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { SelectionMenuProps } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport function PendingRedactions({\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n const off1 = redaction.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = redaction.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.selectPending(pageIndex, id);\n },\n [redaction, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n }\n // kind === 'text' → draw bounding box; inner rects are not drawn here to avoid clutter.\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {({ rect, menuWrapperProps }) =>\n selectionMenu &&\n selectionMenu({\n item: it,\n selected: selectedId === it.id,\n pageIndex,\n menuWrapperProps,\n rect,\n })\n }\n </CounterRotate>\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment } from '@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { SelectionMenuProps } from './types';\n\ninterface RedactionLayerProps {\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n selectionMenu?: (props: SelectionMenuProps) => JSX.Element;\n}\n\nexport const RedactionLayer = ({\n pageIndex,\n scale,\n rotation = Rotation.Degree0,\n selectionMenu,\n}: RedactionLayerProps) => {\n return (\n <Fragment>\n <PendingRedactions\n pageIndex={pageIndex}\n scale={scale}\n rotation={rotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact pageIndex={pageIndex} scale={scale} />\n <SelectionRedact pageIndex={pageIndex} scale={scale} />\n </Fragment>\n );\n};\n"],"names":["Fragment"],"mappings":"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"}
|