@embedpdf/vue 3.0.0-next.15 → 3.0.0-next.16

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.
Files changed (41) hide show
  1. package/dist/{DocumentScope.vue_vue_type_script_setup_true_lang-CtTu1FGX.js → DocumentScope.vue_vue_type_script_setup_true_lang-C-7yeEGh.js} +4 -3
  2. package/dist/DocumentScope.vue_vue_type_script_setup_true_lang-C-7yeEGh.js.map +1 -0
  3. package/dist/{DocumentScope.vue_vue_type_script_setup_true_lang-loLSm4lV.cjs → DocumentScope.vue_vue_type_script_setup_true_lang-czzeUzPl.cjs} +3 -2
  4. package/dist/DocumentScope.vue_vue_type_script_setup_true_lang-czzeUzPl.cjs.map +1 -0
  5. package/dist/annotation/text-box.d.cts +2 -1
  6. package/dist/annotation/text-box.d.ts +2 -1
  7. package/dist/annotation.cjs +1 -1
  8. package/dist/annotation.js +1 -1
  9. package/dist/attachment.cjs +22 -0
  10. package/dist/attachment.cjs.map +1 -0
  11. package/dist/attachment.d.cts +34 -0
  12. package/dist/attachment.d.ts +34 -0
  13. package/dist/attachment.js +17 -0
  14. package/dist/attachment.js.map +1 -0
  15. package/dist/{composables-BuHvnUlo.cjs → composables-Bi6QvJpj.cjs} +18 -43
  16. package/dist/{composables-BuHvnUlo.cjs.map → composables-Bi6QvJpj.cjs.map} +1 -1
  17. package/dist/{composables-CIkhKwAg.js → composables-DK3lwh38.js} +19 -44
  18. package/dist/{composables-CIkhKwAg.js.map → composables-DK3lwh38.js.map} +1 -1
  19. package/dist/index.cjs +25 -2
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +2 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.js +14 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/outline.cjs +22 -0
  26. package/dist/outline.cjs.map +1 -0
  27. package/dist/outline.d.cts +36 -0
  28. package/dist/outline.d.ts +36 -0
  29. package/dist/outline.js +17 -0
  30. package/dist/outline.js.map +1 -0
  31. package/dist/page-edit.cjs +3 -0
  32. package/dist/page-edit.cjs.map +1 -1
  33. package/dist/page-edit.d.cts +14 -2
  34. package/dist/page-edit.d.ts +14 -2
  35. package/dist/page-edit.js +5 -2
  36. package/dist/page-edit.js.map +1 -1
  37. package/dist/runtime.cjs +1 -1
  38. package/dist/runtime.js +1 -1
  39. package/package.json +40 -30
  40. package/dist/DocumentScope.vue_vue_type_script_setup_true_lang-CtTu1FGX.js.map +0 -1
  41. package/dist/DocumentScope.vue_vue_type_script_setup_true_lang-loLSm4lV.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"composables-BuHvnUlo.cjs","sources":["../src/annotation/state.ts","../src/annotation/AnnotationChrome.vue","../src/annotation/AnnotationFrame.vue","../src/annotation/text-box.ts","../src/annotation/AnnotationLook.vue","../src/annotation/FreeTextBox.vue","../src/annotation/AnnotationScene.vue","../src/annotation/NativeDrawing.vue","../src/annotation/StampGhost.vue","../src/annotation/AnnotationLayer.vue","../src/annotation/AnnotationMenu.vue","../src/annotation/AnnotationDraftMenu.vue","../src/annotation/AnnotationRotationBadge.vue","../src/annotation/composables.ts"],"sourcesContent":["/**\n * The annotation composables other feature entries use too (the form layer\n * reads the selection and the settings), kept apart so they don't import the\n * whole annotation feature: the state and the settings, each from its\n * declaration.\n */\nimport { AnnotationToken, annotationState } from '@embedpdf/plugin-annotation/contract';\nimport { settingsComposable, stateComposable } from '../state';\n\n/**\n * The annotation state as refs: `status` (`'loading'` until every annotation\n * is in, then `'ready'`), the `selected` annotations, the one `hovered` under\n * the pointer and the text box being typed in (`editing`). With a selector,\n * one ref that updates only when the value it picks changes. Empty without a\n * document.\n */\nexport const useAnnotationState = stateComposable(annotationState);\n\n/**\n * The annotation settings (`snap`, `chrome`, `afterCreate`, `tools`) as refs,\n * or one ref for the value `select` picks. They belong to the plugin, so they\n * read without a document; change them with `useAnnotation().updateSettings()`.\n */\nexport const useAnnotationSettings = settingsComposable(AnnotationToken);\n","<!--\n The selection's chrome on one page: its outline, handles, rotation handle,\n snapping guides, the lines of a turn in progress and the box dragged to\n select. The plugin lists the nodes and sizes the screen-constant parts for\n the page's zoom; `@embedpdf/web` puts them in pixels and paints them through\n their `--epdf-annotation-*` variables. The layer draws them as SVG; a\n `#handle` or `#rotation-handle` slot draws its handles as HTML over the page\n instead. The viewer still decides where a handle can be grabbed, so what a\n slot draws can't break dragging.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { shallowEqual } from '@embedpdf/core';\nimport type { ChromeNode } from '@embedpdf/core-annotation';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { annotationChromePaint, chromeInPixels } from '@embedpdf/web';\nimport { useOptionalSelector } from '../runtime/capabilities';\nimport { useViewerSettings } from '../runtime/documents';\nimport type { PageContextValue } from '../runtime/page';\nimport { useAnnotationSettings } from './state';\nimport type { HandleProps, RotationHandleProps } from './types';\n\nconst props = defineProps<{ page: PageContextValue }>();\n\nconst slots = defineSlots<{\n /** One handle, drawn your way. */\n handle?(props: HandleProps): unknown;\n /** The rotation handle, drawn your way. */\n 'rotation-handle'?(props: RotationHandleProps): unknown;\n}>();\n\nconst NO_NODES: readonly ChromeNode[] = Object.freeze([]);\n\n// The page's view scale converts the screen-pixel chrome settings into\n// content units inside the plugin (the rotation handle's offset, grab zones):\n// screen-constant at every zoom. What this draws is in screen pixels already.\nconst nodes = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = props.page;\n return host.listChromeNodes(ref, transform.viewScale, transform.rotation, transform.zoom);\n },\n NO_NODES,\n shallowEqual,\n);\nconst chrome = useAnnotationSettings((settings) => settings.chrome);\nconst accent = useViewerSettings((settings) => settings.accent);\n/**\n * The chrome settings, painted, as each part's `style`: follows the settings\n * and the viewer's accent live. Paint goes in `style`, never in SVG\n * attributes, which don't read the `var(--epdf-…)` the paint starts with.\n */\nconst painted = computed(() => {\n const paint = annotationChromePaint(chrome.value, accent.value);\n const style = (part: object): CSSProperties => ({ ...part });\n return {\n outline: style(paint.outline),\n handle: style(paint.handle),\n rotationHandle: style(paint.rotationHandle),\n rotationStalk: style({ stroke: paint.rotationHandle.stroke }),\n guide: style(paint.guide),\n rotationGuide: style(paint.rotationGuide),\n marquee: style(paint.marquee),\n };\n});\nconst pixels = computed(() => chromeInPixels(nodes.value, props.page.transform));\n\n/** Whether there are handles a slot could draw: the slots' own element exists only then. */\nconst hasHandles = computed(() =>\n pixels.value.some((node) => node.kind === 'handle' || node.kind === 'rotation-handle'),\n);\n</script>\n\n<template>\n <svg :style=\"{ position: 'absolute', inset: 0, overflow: 'visible', pointerEvents: 'none' }\">\n <template v-for=\"(node, index) in pixels\" :key=\"index\">\n <template v-if=\"node.kind === 'handle'\">\n <template v-if=\"!slots.handle\">\n <circle\n v-if=\"chrome.handles.shape === 'circle'\"\n :cx=\"node.at.x\"\n :cy=\"node.at.y\"\n :r=\"chrome.handles.size / 2\"\n stroke-width=\"1.5\"\n :style=\"painted.handle\"\n />\n <!-- The square rides a turned box's orientation (it spins about itself). -->\n <rect\n v-else\n :x=\"node.at.x - chrome.handles.size / 2\"\n :y=\"node.at.y - chrome.handles.size / 2\"\n :width=\"chrome.handles.size\"\n :height=\"chrome.handles.size\"\n stroke-width=\"1.5\"\n :style=\"painted.handle\"\n :transform=\"node.rotation ? `rotate(${node.rotation} ${node.at.x} ${node.at.y})` : undefined\"\n />\n </template>\n </template>\n <line\n v-else-if=\"node.kind === 'guide'\"\n :x1=\"node.from.x\"\n :y1=\"node.from.y\"\n :x2=\"node.to.x\"\n :y2=\"node.to.y\"\n shape-rendering=\"crispEdges\"\n :style=\"painted.guide\"\n />\n <polygon\n v-else-if=\"node.kind === 'turned-outline'\"\n :points=\"node.points\"\n fill=\"none\"\n :style=\"painted.outline\"\n />\n <g v-else-if=\"node.kind === 'rotation-guides'\">\n <line\n v-for=\"(line, lineIndex) in node.lines\"\n :key=\"lineIndex\"\n :x1=\"line.from.x\"\n :y1=\"line.from.y\"\n :x2=\"line.to.x\"\n :y2=\"line.to.y\"\n :opacity=\"line.opacity\"\n :style=\"painted.rotationGuide\"\n />\n </g>\n <template v-else-if=\"node.kind === 'rotation-handle'\">\n <g v-if=\"!slots['rotation-handle']\">\n <line\n v-if=\"chrome.rotationHandle.stalk\"\n :x1=\"node.from.x\"\n :y1=\"node.from.y\"\n :x2=\"node.at.x\"\n :y2=\"node.at.y\"\n stroke-width=\"1\"\n :style=\"painted.rotationStalk\"\n />\n <circle\n :cx=\"node.at.x\"\n :cy=\"node.at.y\"\n :r=\"chrome.rotationHandle.size / 2\"\n stroke-width=\"1.5\"\n :style=\"painted.rotationHandle\"\n />\n </g>\n </template>\n <!-- The box dragged to select keeps its own look (a see-through accent\n fill, always dashed); the selection outline follows the settings. -->\n <rect\n v-else-if=\"node.kind === 'marquee'\"\n :x=\"node.box.left\"\n :y=\"node.box.top\"\n :width=\"node.box.width\"\n :height=\"node.box.height\"\n stroke-width=\"1\"\n stroke-dasharray=\"4 3\"\n :style=\"painted.marquee\"\n />\n <rect\n v-else-if=\"node.kind === 'outline'\"\n :x=\"node.box.left\"\n :y=\"node.box.top\"\n :width=\"node.box.width\"\n :height=\"node.box.height\"\n fill=\"none\"\n :style=\"painted.outline\"\n />\n </template>\n </svg>\n <div\n v-if=\"hasHandles && (slots.handle || slots['rotation-handle'])\"\n :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\"\n >\n <template v-for=\"(node, index) in pixels\" :key=\"index\">\n <slot\n v-if=\"node.kind === 'handle' && slots.handle\"\n name=\"handle\"\n :at=\"node.at\"\n :size=\"chrome.handles.size\"\n :rotation=\"node.rotation\"\n :kind=\"node.role\"\n :active=\"node.active\"\n />\n <slot\n v-else-if=\"node.kind === 'rotation-handle' && slots['rotation-handle']\"\n name=\"rotation-handle\"\n :at=\"node.at\"\n :from=\"node.from\"\n :size=\"chrome.rotationHandle.size\"\n :rotation=\"0\"\n :active=\"false\"\n />\n </template>\n </div>\n</template>\n","<!--\n The box an annotation draws into, placed, sized and turned like the\n annotation (`item.frame`) inside the page layer, which the page itself\n turns. The annotation's own drawing and any look of yours draw inside it.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport { frameInPixels } from '@embedpdf/web';\nimport type { PageContextValue } from '../runtime/page';\n\nconst props = withDefaults(\n defineProps<{\n item: RenderItem;\n page: PageContextValue;\n /** An interactive renderer takes the pointer: the layer's own `none` ends here. */\n interactive?: boolean;\n /** No pointer and no focus for the whole subtree: a renderer that only draws. */\n inert?: boolean;\n }>(),\n { interactive: false, inert: false },\n);\n\ndefineSlots<{ default?(): unknown }>();\n\nconst style = computed((): CSSProperties => {\n const box = frameInPixels(props.item.frame, props.page.transform);\n return {\n position: 'absolute',\n left: `${box.left}px`,\n top: `${box.top}px`,\n width: `${box.width}px`,\n height: `${box.height}px`,\n transform: box.transform,\n transformOrigin: 'center',\n // On the frame: a turned frame groups what is inside it, so blending on\n // an inner element would stop blending with the page.\n mixBlendMode: props.item.blend as CSSProperties['mixBlendMode'],\n pointerEvents: props.interactive ? 'auto' : 'none',\n };\n});\n</script>\n\n<template>\n <div :inert=\"inert || undefined\" :style=\"style\">\n <slot />\n </div>\n</template>\n","/**\n * Text boxes you type in. `@embedpdf/web`'s text box editor makes an element\n * the editor of a free text box (rich text, focus and `contentEditable`\n * following the plugin's `editing`, presses kept inside), and its follower\n * attaches when the element and the capability are there and takes the box\n * and the scale whenever they change; this binds the follower to Vue. The\n * layer's own text boxes use it, and so does `useRichTextEditor()`, for a\n * renderer that draws its text box itself.\n */\nimport { computed, inject, onScopeDispose, provide, shallowRef, toValue, watch } from 'vue';\nimport type { ComponentPublicInstance, CSSProperties, InjectionKey, MaybeRefOrGetter, Ref } from 'vue';\nimport { annotationKey } from '@embedpdf/core';\nimport type { Annotation, AnnotationRef, TextItem } from '@embedpdf/plugin-annotation';\n// Typing reaches the plugin through its host lens (drafts, the text selection).\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { createTextBoxEditorFollower, textBoxEditorScaleOf, textBoxStyleOf } from '@embedpdf/web';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport { usePage } from '../runtime/page';\nimport type { RichTextEditor } from './types';\n\n/**\n * Make an element the editor of a text box, following `item` and `scale`\n * (pixels per point). Returns the element's ref: put it on the element, and\n * render nothing inside it, since the editor owns its children.\n */\nexport function useTextBoxEditor(\n item: MaybeRefOrGetter<TextItem | null>,\n scale: MaybeRefOrGetter<number>,\n): Ref<HTMLElement | null> {\n const element = shallowRef<HTMLElement | null>(null);\n const annotation = useOptionalCapability(AnnotationHostToken);\n const follower = createTextBoxEditorFollower<AnnotationRef>();\n // `post`: the element is in the document by then, so focusing it works. The\n // editor redraws only when the text differs, so the caret never jumps while\n // typing; focus follows `editing`.\n watch(\n [annotation, element, () => toValue(item), () => toValue(scale)],\n ([capability, target, current, pixelsPerPoint]) =>\n follower.follow(target, capability, current, pixelsPerPoint),\n { immediate: true, flush: 'post' },\n );\n onScopeDispose(() => follower.detach());\n return element;\n}\n\n/** How much the layer scales the look around it: 1 outside a look, or in one drawn at its size on screen. */\nconst LookScaleKey: InjectionKey<Readonly<Ref<number>>> = Symbol('embedpdf annotation look scale');\nconst UNSCALED = computed(() => 1);\n\n/** Installed by the layer around a look it scales, not by app code. */\nexport function provideLookScale(scale: Readonly<Ref<number>>): void {\n provide(LookScaleKey, scale);\n}\n\nconst NO_STYLE: CSSProperties = Object.freeze({});\n\n/**\n * Make your own element the editor of a text box you draw yourself (a\n * renderer for free text): it draws the runs, turns typing back into runs,\n * keeps the caret when the style changes, and handles pasting, input methods\n * and the format shortcuts. The formatting calls (`text.toggleFormat`,\n * `selection.update`) work on it as they do on the built-in one.\n *\n * ```vue\n * const { ref: editorRef, editing, style } = useRichTextEditor(() => props.annotation);\n * <div :ref=\"editorRef\" :class=\"{ editing }\" :style=\"style\" />\n * ```\n *\n * `ref` goes on your element (render nothing inside it: the editor owns what's\n * in it); `style` and `editing` are refs.\n */\nexport function useRichTextEditor(annotation: MaybeRefOrGetter<Annotation>): RichTextEditor {\n const page = usePage();\n const item = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const key = annotationKey(toValue(annotation).ref);\n const { transform } = page.value;\n return (\n host\n .listTextItems(page.value.ref, { zoom: transform.zoom, rotation: transform.rotation })\n .find((text) => text.ref !== null && annotationKey(text.ref) === key) ?? null\n );\n },\n null,\n );\n // Pixels per point where the element is: inside a scaled look, at the\n // annotation's 100% size; the look's scale does the rest.\n const lookScale = inject(LookScaleKey, UNSCALED);\n const scale = computed(() =>\n textBoxEditorScaleOf(item.value, page.value.transform, lookScale.value),\n );\n const element = useTextBoxEditor(item, scale);\n // While typing, the element takes the pointer (the caret, a drag over words).\n const style = computed((): CSSProperties => {\n const text = item.value;\n if (!text) return NO_STYLE;\n return {\n ...textBoxStyleOf(text.css, scale.value),\n ...(text.editing ? { pointerEvents: 'auto' } : {}),\n };\n });\n return {\n ref: (target: Element | ComponentPublicInstance | null) => {\n element.value = target instanceof HTMLElement ? target : null;\n },\n style,\n editing: computed(() => item.value?.editing ?? false),\n };\n}\n","<!--\n Your look for one annotation, inside its frame: your renderer's component,\n drawn at the annotation's 100% size and scaled with the page, unless the\n renderer opts out (`scale: false`) and draws at its size on screen.\n `useRichTextEditor()` inside it divides by that scale.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { Component, CSSProperties } from 'vue';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport type { Annotation } from '@embedpdf/plugin-annotation';\nimport { frameInPixels, lookFrameOf } from '@embedpdf/web';\nimport type { PageContextValue } from '../runtime/page';\nimport { provideLookScale } from './text-box';\n\nconst props = defineProps<{\n /** Your renderer's component. */\n component: Component;\n /** Draw at the annotation's 100% size and let the layer scale it (the default), or at its size on screen. */\n scaled: boolean;\n annotation: Annotation;\n item: RenderItem;\n page: PageContextValue;\n native: Component;\n appearance: { url: string } | null;\n interactive: boolean;\n}>();\n\nconst pixels = computed(() => frameInPixels(props.item.frame, props.page.transform));\nconst frame = computed(() => lookFrameOf(pixels.value, props.scaled));\n// What `useRichTextEditor()` in the look divides by: 1 when it draws at its size on screen.\nprovideLookScale(computed(() => (props.scaled ? pixels.value.scale : 1)));\n\nconst scaledBox = computed(\n (): CSSProperties => ({\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${pixels.value.design.width}px`,\n height: `${pixels.value.design.height}px`,\n transform: `scale(${pixels.value.scale})`,\n transformOrigin: '0 0',\n }),\n);\n</script>\n\n<template>\n <div v-if=\"scaled\" :style=\"scaledBox\">\n <component\n :is=\"component\"\n :annotation=\"annotation\"\n :frame=\"frame\"\n :native=\"native\"\n :appearance=\"appearance\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"interactive\"\n />\n </div>\n <component\n :is=\"component\"\n v-else\n :annotation=\"annotation\"\n :frame=\"frame\"\n :native=\"native\"\n :appearance=\"appearance\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"interactive\"\n />\n</template>\n","<!--\n A free text annotation's text: the same styled element for reading and for\n typing, placed on the engine's text plate (the box inset by its padding).\n The editor binding owns what's inside it, so the template renders nothing\n there, and the element lives as long as the text box does (keyed by its id),\n so the caret never jumps while someone types. Focus and `contentEditable`\n follow the plugin's `editing`.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport type { TextItem } from '@embedpdf/plugin-annotation';\nimport { annotationChromePaint, textBoxStyleOf, textPlateInPixels } from '@embedpdf/web';\nimport { useViewerSettings } from '../runtime/documents';\nimport type { PageContextValue } from '../runtime/page';\nimport { useAnnotationSettings } from './state';\nimport { useTextBoxEditor } from './text-box';\n\nconst props = defineProps<{ item: TextItem; page: PageContextValue }>();\n\n// The element is the engine's text plate: the box inset by its padding.\nconst plate = computed(() => textPlateInPixels(props.item, props.page.transform));\nconst element = useTextBoxEditor(\n () => props.item,\n () => plate.value.scale,\n);\n\nconst chrome = useAnnotationSettings((settings) => settings.chrome);\nconst accent = useViewerSettings((settings) => settings.accent);\nconst outline = computed(() => annotationChromePaint(chrome.value, accent.value).textOutline);\n\nconst style = computed((): CSSProperties => {\n const { item } = props;\n const { left, top, width, height, scale } = plate.value;\n return {\n position: 'absolute',\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n // Fixed to the plate: the box never grows with its text; it scrolls while\n // typing and clips otherwise, where the baked appearance clips.\n height: `${height}px`,\n ...textBoxStyleOf(item.css, scale),\n boxSizing: 'border-box',\n // The box's fill and border are the vector scene's, under this layer.\n background: 'transparent',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'break-word',\n overflowY: item.editing ? 'auto' : 'hidden',\n overflowX: 'hidden',\n outline: item.editing ? `1px solid ${outline.value}` : 'none',\n cursor: item.editing ? 'text' : 'default',\n // A plain text box turns about its centre, as the baked appearance does.\n ...(item.rot ? { transform: `rotate(${item.rot}deg)`, transformOrigin: 'center' } : {}),\n // Not typing: clicks fall through to the shapes (select, move, resize).\n pointerEvents: item.editing ? 'auto' : 'none',\n };\n});\n</script>\n\n<template>\n <div ref=\"element\" :style=\"style\" />\n</template>\n","<!--\n An annotation's scene, filling its frame: drawn upright in it, the frame\n turns it. The core computed the box and the painted scene; `@embedpdf/web`\n describes each scene node as one SVG element (its tag, its attributes under\n their SVG names, its text), so there is no per-kind logic and no bounds math\n here: one loop draws every kind.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { MITER_LIMIT, scene } from '@embedpdf/core-annotation';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport { ghostOpacity, sceneViewBox, svgShapesOf } from '@embedpdf/web';\nimport SvgShapes from '../runtime/SvgShapes.vue';\n\nconst props = defineProps<{ item: RenderItem }>();\n\n// Nothing to draw until the annotation has area (the 0×0 draft at mouse-down).\nconst viewBox = computed(() => sceneViewBox(props.item.box));\nconst shapes = computed(() => svgShapesOf(scene(props.item), { miterLimit: MITER_LIMIT }));\nconst style = computed(\n (): CSSProperties => ({\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n overflow: 'visible',\n pointerEvents: 'none',\n // A ghost is see-through as a whole, so its fill and stroke don't stack.\n ...(props.item.source === 'ghost'\n ? { opacity: ghostOpacity(props.item.ghostOpacity ?? 0.5) }\n : {}),\n }),\n);\n</script>\n\n<template>\n <svg v-if=\"viewBox\" :viewBox=\"viewBox\" :style=\"style\">\n <SvgShapes :shapes=\"shapes\" />\n </svg>\n</template>\n","<!--\n The layer's own drawing of one annotation, inside its frame: the engine's\n raster where the core places it (following a move as it happens), or the\n vector scene for everything drawn live (shapes, clouds, markup, a drawing\n in progress, a tool's ghost, a picture older than the annotation). One rule\n picks (`pictureOrPainting`). A renderer gets it as `native`.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { hasLiveDrawing, type RenderItem } from '@embedpdf/core-annotation';\nimport {\n pictureOrPainting,\n rasterInFrame,\n shownAppearance,\n type AppearanceUrl,\n} from '@embedpdf/web';\nimport AnnotationScene from './AnnotationScene.vue';\n\nconst props = defineProps<{\n item: RenderItem;\n /** The page's loaded pictures, by item and state; `null` until the first ones arrive. */\n urls: Readonly<Record<string, AppearanceUrl>> | null;\n}>();\n\nconst shows = computed(() => {\n const { item, urls } = props;\n return pictureOrPainting({\n pending: item.source !== 'baked',\n picture: urls && shownAppearance(urls, item.id, item.annotation?.appearanceState ?? null),\n version: item.pictureVersion ?? 0,\n loaded: urls !== null,\n paint: () => (hasLiveDrawing(item) ? item : null),\n });\n});\n\n/** The engine's raster inside the item's frame, where `item.raster` puts it, at any frame size. */\nconst baked = computed((): { url: string; style: CSSProperties } | null => {\n const { item } = props;\n const look = shows.value;\n if (look?.kind !== 'picture' || !item.raster) return null;\n const box = rasterInFrame(item.raster, item.frame);\n return {\n url: look.picture.url,\n style: {\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n // The appearance box is sized in content units; a global\n // `img { max-width: 100% }` reset would otherwise clamp it to the\n // containing block and distort the aspect (a landscape stamp on a turned,\n // portrait page), so honour the explicit size.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n // The turn the engine took out of the raster, put back about its middle.\n transform: box.transform,\n transformOrigin: 'center',\n },\n };\n});\n</script>\n\n<template>\n <img v-if=\"baked\" :src=\"baked.url\" alt=\"\" draggable=\"false\" :style=\"baked.style\" />\n <AnnotationScene v-else-if=\"shows?.kind === 'painting'\" :item=\"item\" />\n</template>\n","<!--\n The armed stamp's ghost: a see-through render of the stamp, in the exact box\n a click would place it (the plugin computes it with the same fit and clamp\n as the placement). Every other tool's ghost is a render item, drawn like a\n drawing in progress. The preview bytes live in the plugin; this owns only\n the object URL, keyed on the armed stamp: a new arm swaps the image, a\n disarm (or another tool) drops it.\n-->\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport {\n AnnotationToken as AnnotationHostToken,\n previewBucket,\n} from '@embedpdf/plugin-annotation/contract/host';\nimport { ghostOpacity, loadObjectUrl, rectInPixels } from '@embedpdf/web';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport type { PageContextValue } from '../runtime/page';\n\nconst props = defineProps<{ page: PageContextValue }>();\n\nconst annotation = useOptionalCapability(AnnotationHostToken);\nconst ghost = useOptionalSelector(\n AnnotationHostToken,\n (host) => host.getImageGhost(props.page.ref),\n null,\n);\nconst armed = useOptionalSelector(AnnotationHostToken, (host) => host.getArmedStamp(), null);\n// The ghost is a bitmap of vector artwork, right at one size: ask for the\n// bucket that covers the box's device width (points × device pixels per\n// point), so it stays sharp at every zoom and density. The plugin caches per\n// bucket.\nconst bucket = computed(() =>\n ghost.value ? previewBucket(ghost.value.box.width * props.page.transform.renderScale) : 0,\n);\n\nconst url = ref<string | null>(null);\nwatch(\n [annotation, armed, bucket],\n ([host, _armed, size], _previous, onCleanup) => {\n if (!host || !size) {\n url.value = null;\n return;\n }\n // The previous bucket's image stays up until this one arrives: no flicker\n // while a zoom crosses a bucket boundary.\n onCleanup(\n loadObjectUrl(\n () => host.renderArmedStampPreview(size),\n (next) => (url.value = next),\n ),\n );\n },\n { immediate: true },\n);\n\nconst style = computed((): CSSProperties | null => {\n const current = ghost.value;\n if (!current) return null;\n const frame = rectInPixels(current.box, props.page.transform);\n return {\n position: 'absolute',\n left: `${frame.left}px`,\n top: `${frame.top}px`,\n width: `${frame.width}px`,\n height: `${frame.height}px`,\n // Never let a global `img` reset clamp the box and distort the aspect.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n opacity: ghostOpacity(current.opacity),\n ...(current.rot ? { transform: `rotate(${current.rot}deg)`, transformOrigin: 'center' } : {}),\n };\n});\n</script>\n\n<template>\n <img v-if=\"style && url\" :src=\"url\" alt=\"\" draggable=\"false\" :style=\"style\" />\n</template>\n","<!--\n <AnnotationLayer>: a page's annotations, the selection's outline and\n handles, the tool's preview and the text boxes being typed in. Put it in the\n Stage's #page slot above the rendered page: while it's there, the render\n layer leaves the annotations out of the page's picture.\n\n Pure paint: it reads the plugin's per-page render items and chrome and draws\n them. Pointer events reach the plugin through the interaction hub (the\n Stage forwards them), and so does the cursor. Each annotation is one drawing:\n its vector scene, the engine's baked appearance, or a look of yours from\n `renderers`, which may keep the layer's own drawing (`native`) and add to it.\n The `#handle` and `#rotation-handle` slots draw the handles your way.\n-->\n<script setup lang=\"ts\">\nimport { computed, h, markRaw, onUnmounted, shallowRef, toRaw, watch } from 'vue';\nimport type { Component } from 'vue';\nimport { annotationKey, shallowEqual } from '@embedpdf/core';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport type { Annotation, TextItem } from '@embedpdf/plugin-annotation';\n// The layer is framework code, so it resolves the full host lens (page items,\n// chrome, appearances…): the same runtime token as the public one, typed wider.\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport { RenderToken } from '@embedpdf/plugin-render/contract/host';\nimport {\n annotationDrawingOf,\n bakedAppearanceOf,\n createShownUrls,\n editingTextKeyOf,\n layerTextBoxesOf,\n loadAppearanceUrls,\n registerRendererBehaviors,\n} from '@embedpdf/web';\nimport type { AnnotationDrawing, AppearanceUrl } from '@embedpdf/web';\nimport { devWarn } from '../dev';\nimport { usePaintsPagePart } from '../page-layers';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport { usePage } from '../runtime/page';\nimport AnnotationChrome from './AnnotationChrome.vue';\nimport AnnotationFrame from './AnnotationFrame.vue';\nimport AnnotationLook from './AnnotationLook.vue';\nimport FreeTextBox from './FreeTextBox.vue';\nimport NativeDrawing from './NativeDrawing.vue';\nimport StampGhost from './StampGhost.vue';\nimport type { AnnotationRenderer, HandleProps, RotationHandleProps } from './types';\n\nconst props = defineProps<{\n /**\n * Your own look for some annotations: each renderer says which ones (`for`)\n * and with which component. Define the list once, in `<script setup>`.\n */\n renderers?: AnnotationRenderer[];\n}>();\n\nconst slots = defineSlots<{\n /** Draw each handle yourself, in place of the layer's: it gets {@link HandleProps}. */\n handle?(props: HandleProps): unknown;\n /** Draw the rotation handle yourself: it gets {@link RotationHandleProps}. */\n 'rotation-handle'?(props: RotationHandleProps): unknown;\n}>();\n\ntype Drawing = AnnotationDrawing<AnnotationRenderer>;\n\nconst NO_ITEMS: readonly RenderItem[] = Object.freeze([]);\nconst NO_TEXTS: readonly TextItem[] = Object.freeze([]);\n\nconst page = usePage();\n// While it's here, the page's picture leaves the annotations to it.\nusePaintsPagePart(\n computed(() => page.value.ref),\n 'annotations',\n);\nconst annotation = useOptionalCapability(AnnotationHostToken);\nconst interaction = useOptionalCapability(InteractionToken);\n// The active tool decides which interactive renderers take the pointer, so a\n// tool change draws the layer again (`interactive` functions read it live).\nconst activeToolId = useOptionalSelector(\n InteractionToken,\n (hub) => hub.getActiveToolId() as string,\n '',\n);\n\n// The page's view (its zoom and turn) projects annotations that keep their\n// size or stay upright on screen (`noZoom`, `noRotate`) inside the plugin: no\n// flag logic lives here. `zoom`, not `viewScale`: 1 is the page's 100%.\nconst items = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = page.value;\n return host.listPageItems(ref, { zoom: transform.zoom, rotation: transform.rotation });\n },\n NO_ITEMS,\n shallowEqual,\n);\nconst texts = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = page.value;\n return host.listTextItems(ref, { zoom: transform.zoom, rotation: transform.rotation });\n },\n NO_TEXTS,\n shallowEqual,\n);\n\n// ── your renderers ───────────────────────────────────────────────────────────\n\n/** Bumped when the renderers' behaviors register again, so the drawings are read again. */\nconst registrations = shallowRef(0);\n// An `interactive` renderer takes the pointer through a behavior the plugin\n// knows, registered once per capability and entry however many pages mount\n// the layer. Entry identity is the key, so a list written inline in the\n// template (a new array on every render) registers again each time: say so.\nwatch(\n [annotation, () => props.renderers],\n ([host, renderers], previous, onCleanup) => {\n const before = previous?.[1];\n if (renderers && before && renderers !== before && shallowEqual(renderers, before)) {\n devWarn(\n 'annotation-renderers-inline',\n '<AnnotationLayer :renderers> was given a new array with the same entries — define it ' +\n 'once in <script setup>, because entry identity keys the behavior registration.',\n );\n }\n if (host && renderers) {\n onCleanup(\n registerRendererBehaviors(host, renderers, () =>\n String(interaction.value?.getActiveToolId() ?? ''),\n ),\n );\n }\n registrations.value += 1;\n },\n { immediate: true },\n);\n\n// ── baked appearances ────────────────────────────────────────────────────────\n\n// `null` until the page's first pictures arrive.\nconst urls = shallowRef<Record<string, AppearanceUrl> | null>(null);\n// The pictures shown stay valid until the next ones are shown.\nconst shown = createShownUrls();\nonUnmounted(() => shown.release());\n// Baked annotations draw from engine rasters: load them again when the page's\n// baked set or an appearance version changes (a stamp just placed, a resize\n// whose new appearance arrived), and when the bake scale does. A move or a\n// turn leaves the epoch as it is (the same pixels, placed elsewhere), and live\n// gestures don't touch it: nothing loads mid-drag.\nconst bakedKey = useOptionalSelector(\n AnnotationHostToken,\n (host) => host.getAppearanceEpoch(page.value.ref),\n '',\n);\n// The appearance scale follows the document's render policy: zoom steps inside\n// one rung of the appearance lattice bake nothing again. Without the render\n// plugin, only this session's pictures load.\nconst bakeScale = useOptionalSelector(\n RenderToken,\n (render) => render.getAppearanceScale(page.value.transform.renderScale),\n page.value.transform.renderScale,\n);\nwatch(\n [annotation, () => page.value.ref, bakeScale, bakedKey],\n ([host, pageRef, scale], _previous, onCleanup) => {\n if (!host || !scale) return;\n onCleanup(\n loadAppearanceUrls(\n shown,\n (signal) => host.renderAppearances(pageRef, scale, signal),\n annotationKey,\n (loaded) => (urls.value = loaded),\n ),\n );\n },\n { immediate: true },\n);\n\n// ── what each annotation draws ───────────────────────────────────────────────\n\n/** The text box being typed in, by key: while it is, a look's editor takes the keys. */\nconst editingKey = computed(() => editingTextKeyOf(texts.value, annotationKey));\n\ninterface Drawn {\n item: RenderItem;\n annotation: Annotation | null;\n drawing: Drawing;\n}\n\n/** The layer's own drawing, for what isn't an annotation yet (a drawing in progress, a ghost). */\nconst NATIVE: Drawing = { kind: 'native', inert: false };\n\n// Ownership beats looks: an engaged behavior's renderer is authoritative (the\n// form plugin's controls own their DOM); `for` rules apply only to what the\n// layer owns, and draw without the pointer. Read whenever the items, the\n// active tool or the registrations change: `interactive` functions and the\n// plugin's behaviors are asked here.\nconst drawn = computed((): Drawn[] => {\n void activeToolId.value;\n void registrations.value;\n const host = annotation.value;\n const renderers = props.renderers;\n return items.value.map((item): Drawn => {\n const record = item.annotation ?? null;\n if (!record || !host) return { item, annotation: null, drawing: NATIVE };\n const typing = editingKey.value !== null && annotationKey(record.ref) === editingKey.value;\n return { item, annotation: record, drawing: annotationDrawingOf(record, host, renderers, typing) };\n });\n});\n\n/** The text boxes the layer draws itself: one your renderer draws is edited there (`useRichTextEditor()`). */\nconst ownTexts = computed(() =>\n layerTextBoxesOf(texts.value, items.value, props.renderers, annotationKey),\n);\n\n// `native` for a renderer: one component per annotation, kept by its id, that\n// draws the layer's current drawing of it. The same component across renders,\n// so a drag moves the drawing instead of replacing it.\nconst itemsById = computed(() => new Map(items.value.map((item) => [item.id, item])));\nconst natives = new Map<string, Component>();\nconst framedNatives = new Map<string, Component>();\nfunction nativeOf(id: string): Component {\n let native = natives.get(id);\n if (!native) {\n native = markRaw(() => {\n const item = itemsById.value.get(id);\n return item ? h(NativeDrawing, { item, urls: urls.value }) : null;\n });\n natives.set(id, native);\n }\n return native;\n}\n/** The native drawing in its frame: what a sibling plugin's renderer keeps where the layer draws it. */\nfunction framedNativeOf(id: string): Component {\n let native = framedNatives.get(id);\n if (!native) {\n native = markRaw(() => {\n const item = itemsById.value.get(id);\n return item\n ? h(AnnotationFrame, { item, page: page.value }, () => h(nativeOf(id)))\n : null;\n });\n framedNatives.set(id, native);\n }\n return native;\n}\n// Forget the drawings of annotations that are gone.\nwatch(itemsById, (shown) => {\n for (const id of natives.keys()) if (!shown.has(id)) natives.delete(id);\n for (const id of framedNatives.keys()) if (!shown.has(id)) framedNatives.delete(id);\n});\n\n/** A renderer's component, never a reactive proxy of it (a list kept in a `ref`). */\nconst componentOf = (component: Component): Component => toRaw(component);\n</script>\n\n<template>\n <div :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\">\n <template v-for=\"{ item, annotation: record, drawing } in drawn\" :key=\"item.id\">\n <component\n :is=\"componentOf(drawing.entry.component)\"\n v-if=\"drawing.kind === 'owned' && record\"\n :annotation=\"record\"\n :item=\"item\"\n :page=\"page\"\n :native=\"framedNativeOf(item.id)\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"true\"\n />\n <AnnotationFrame\n v-else-if=\"drawing.kind === 'look' && record\"\n :item=\"item\"\n :page=\"page\"\n :interactive=\"drawing.interactive\"\n :inert=\"drawing.inert\"\n >\n <AnnotationLook\n :component=\"componentOf(drawing.entry.component)\"\n :scaled=\"drawing.entry.scale !== false\"\n :annotation=\"record\"\n :item=\"item\"\n :page=\"page\"\n :native=\"nativeOf(item.id)\"\n :appearance=\"\n urls && bakedAppearanceOf(urls, item.id, item.annotation?.appearanceState ?? null)\n \"\n :interactive=\"drawing.interactive\"\n />\n </AnnotationFrame>\n <!-- Inert when an engaged behavior has no renderer of yours: its plugin\n owns the input (a link's anchor takes the click), and the annotation\n keeps its own look. -->\n <AnnotationFrame\n v-else\n :item=\"item\"\n :page=\"page\"\n :inert=\"drawing.kind === 'native' && drawing.inert\"\n >\n <NativeDrawing :item=\"item\" :urls=\"urls\" />\n </AnnotationFrame>\n </template>\n <FreeTextBox v-for=\"text in ownTexts\" :key=\"text.id\" :item=\"text\" :page=\"page\" />\n <StampGhost :page=\"page\" />\n <AnnotationChrome :page=\"page\">\n <template v-if=\"slots.handle\" #handle=\"handle\">\n <slot name=\"handle\" v-bind=\"handle\" />\n </template>\n <template v-if=\"slots['rotation-handle']\" #rotation-handle=\"handle\">\n <slot name=\"rotation-handle\" v-bind=\"handle\" />\n </template>\n </AnnotationChrome>\n </div>\n</template>\n","<!--\n <AnnotationMenu>: your own menu next to the selection (one anchor, also for a\n selection over several pages), clear of the rotation handle. It hides while\n the selection is dragged, resized or turned. What's in it is yours: build it\n from `useAnnotation()` and `useAnnotationState()`. Put it in the Stage's\n #overlay slot; it works inside a <PageView> too (the surface provides the\n projection).\n-->\n<script setup lang=\"ts\">\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { sameSelectionAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useProjectorBinding } from '../anchored/projector';\nimport { useOptionalSelector } from '../runtime/capabilities';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the selection box and the menu. Default 15. */\n gap?: number;\n /** Where the menu sits around the selection. Default `'top'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 15, placement: 'top' },\n);\n\ndefineSlots<{\n /** The menu: compose it from `useAnnotation()` and `useAnnotationState()`. */\n default?(): unknown;\n}>();\n\n// Reading the binding makes the anchor follow projection changes in the same\n// update as the pages: the rotation handle's offset is screen-constant, so its\n// place on the page depends on the page's live view scale.\nconst binding = useProjectorBinding();\nconst anchor = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const selection = host.selection.getAnchor();\n if (!selection) return null;\n const view = binding.value.projector.viewEnv(selection.page);\n return view ? host.getSelectionAnchorIn(view) : selection;\n },\n null,\n sameSelectionAnchor,\n);\n</script>\n\n<template>\n <Anchored\n v-if=\"anchor\"\n :anchor=\"{\n page: anchor.page,\n bounds: anchor.bounds,\n ...(anchor.rotationHandle ? { avoid: [anchor.rotationHandle] } : {}),\n }\"\n :placement=\"placement\"\n :gap=\"gap\"\n >\n <slot />\n </Anchored>\n</template>\n","<!--\n <AnnotationDraftMenu>: floats over a shape being drawn with several clicks\n (a polygon, a polyline). Its default slot gets the `draft`: its `subtype`,\n `pointCount`, `minPoints`, `canFinish` and where it is. The verbs are\n capability calls: `useAnnotation().draft.finish()` and `.draft.cancel()`.\n-->\n<script setup lang=\"ts\">\nimport type { CreationDraftAnchor } from '@embedpdf/core-annotation';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport { sameCreationDraftAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useOptionalSelector } from '../runtime/capabilities';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the shape and the menu. Default 8. */\n gap?: number;\n /** Where the menu sits around the shape. Default `'top'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 8, placement: 'top' },\n);\n\ndefineSlots<{\n /** The menu, with the shape being drawn. */\n default?(props: { draft: CreationDraftAnchor }): unknown;\n}>();\n\n// The plugin reads a new anchor object every time: compared by value, so the\n// menu moves only when the shape did.\nconst draft = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.draft.get(),\n null,\n sameCreationDraftAnchor,\n);\n</script>\n\n<template>\n <Anchored v-if=\"draft\" :anchor=\"draft\" :placement=\"placement\" :gap=\"gap\">\n <slot :draft=\"draft\" />\n </Anchored>\n</template>\n","<!--\n <AnnotationRotationBadge>: follows the pointer while a selection is being\n turned, upright however the page is shown: it floats over the page like the\n menus, not in it. Shows nothing when no turn is in progress. Without a slot\n it shows the angle in the `chrome.readout` colors, when\n `chrome.readout.enabled`; its default slot gets the `rotation` (`angle`,\n degrees clockwise, as the commit will apply it) to draw it your way.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport type { RotationAnchor } from '@embedpdf/core-annotation';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport { paint, paintDefault, sameRotationAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useOptionalSelector } from '../runtime/capabilities';\nimport { useAnnotationSettings } from './state';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the pointer and the badge. Default 16. */\n gap?: number;\n /** Where the badge sits around the pointer. Default `'right'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 16, placement: 'right' },\n);\n\nconst slots = defineSlots<{\n /** The badge, drawn your way, with the turn in progress. */\n default?(props: { rotation: RotationAnchor }): unknown;\n}>();\n\nconst rotation = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.selection.getRotationAnchor(),\n null,\n sameRotationAnchor,\n);\nconst readout = useAnnotationSettings((settings) => settings.chrome.readout);\n\nconst badge = computed(\n (): CSSProperties => ({\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n borderRadius: '4px',\n padding: '2px 6px',\n fontFamily: paintDefault('font-mono'),\n fontSize: '12px',\n background: paint('readout-background', readout.value.background),\n color: paint('readout-color', readout.value.color),\n }),\n);\n</script>\n\n<template>\n <Anchored\n v-if=\"rotation && (slots.default || readout.enabled)\"\n :anchor=\"{ page: rotation.page, bounds: { ...rotation.at, width: 0, height: 0 } }\"\n :placement=\"placement\"\n :gap=\"gap\"\n >\n <slot v-if=\"slots.default\" :rotation=\"rotation\" />\n <div v-else :style=\"badge\">{{ rotation.angle }}°</div>\n </Anchored>\n</template>\n","/**\n * The annotation composables: `useAnnotation()` (the API) and\n * `useAnnotationEvent()`; the reads a component follows on their own, each a\n * ref (`useAnnotationList()`, `useAnnotationDefaults()`,\n * `useAnnotationProperties()`, `useAnnotationAnchor()`); the comments\n * (`useComments()`, `useCommentThreads()`, `useCommentThread()`); and\n * `useFilePickerProvider()`, the file dialog behind click-then-pick tools.\n * The state and the settings are in `./state`.\n */\nimport { computed, markRaw, toValue, unref, watch } from 'vue';\nimport type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { annotationKey, shallowEqual } from '@embedpdf/core';\nimport type { EventHook, PageLayout } from '@embedpdf/core';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport type {\n Annotation,\n AnnotationAnchor,\n AnnotationCapability,\n AnnotationFilter,\n AnnotationProperties,\n AnnotationRef,\n CommentThread,\n CommentsApi,\n FilePickerProvider,\n ToolDefaults,\n} from '@embedpdf/plugin-annotation';\n// The anchor of one annotation is a host read: it projects a drag in progress.\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport {\n enrichCommentThreads,\n installFilePickerProvider,\n pickRequestedFile,\n sameAnnotationAnchor,\n} from '@embedpdf/web';\nimport { devWarn } from '../dev';\nimport {\n useCapability,\n useCapabilityEvent,\n useOptionalCapability,\n useOptionalSelector,\n} from '../runtime/capabilities';\nimport { useDocumentId, useKernelValue } from '../runtime/kernel';\nimport type { CommentThreadView } from './types';\n\n/**\n * The annotation API (`create`, `update`, `selection`, `tools`, `text`,\n * `comments`, …) for your chrome. The object never changes, so it's safe to\n * keep in a closure; keep it whole (`annotation.selection.delete()`), since a\n * member taken out of it once stays the one of that moment.\n */\nexport function useAnnotation(): AnnotationCapability {\n return useCapability(AnnotationToken);\n}\n\n/** Subscribe to one annotation event while the component lives: `useAnnotationEvent((annotation) => annotation.onCreated, handler)`. */\nexport function useAnnotationEvent<Event>(\n select: (annotation: AnnotationCapability) => EventHook<Event>,\n handler: (event: Event) => void,\n): void {\n useCapabilityEvent(AnnotationToken, select, handler);\n}\n\nconst NO_ANNOTATIONS: readonly Annotation[] = Object.freeze([]);\n\n/**\n * The annotations matching `filter` (some pages, one kind), in drawing order,\n * as the user sees them, as a ref: the same array while they stay the same.\n * A getter follows a filter that changes. Empty without a document.\n */\nexport function useAnnotationList(\n filter?: MaybeRefOrGetter<AnnotationFilter | undefined>,\n): Readonly<Ref<readonly Annotation[]>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.list(toValue(filter)),\n NO_ANNOTATIONS,\n shallowEqual,\n );\n}\n\nconst NO_DEFAULTS: ToolDefaults = Object.freeze({});\n\n/**\n * A tool's defaults, as a ref: the fields its next annotation starts with,\n * over the engine's. It follows them, so a color picker always shows the\n * current color. Empty without a document.\n */\nexport function useAnnotationDefaults(toolId: MaybeRefOrGetter<string>): Readonly<Ref<ToolDefaults>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.tools.getDefaults(toValue(toolId)),\n NO_DEFAULTS,\n );\n}\n\nconst NO_PROPERTIES: AnnotationProperties = Object.freeze({\n properties: [],\n values: {},\n mixed: [],\n});\n\n/**\n * What a style panel shows, as a ref: the selection's properties\n * (`selection.getProperties()`), or, given a tool id, the tool's\n * (`tools.getProperties(id)`). It follows them. Empty without a document.\n */\nexport function useAnnotationProperties(\n toolId?: MaybeRefOrGetter<string | undefined>,\n): Readonly<Ref<AnnotationProperties>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => {\n const tool = toValue(toolId);\n return tool === undefined\n ? annotation.selection.getProperties()\n : annotation.tools.getProperties(tool);\n },\n NO_PROPERTIES,\n );\n}\n\n/**\n * An anchor for `<Anchored>` that keeps a card or a badge attached to one\n * annotation, as a ref: its page and the box around what it shows, following\n * a move as it happens. `null` for `null`, or an annotation that isn't here.\n * It changes when the annotation moves, not while people scroll or zoom: a\n * note that keeps its size on screen hands `<Anchored>` its `boundsIn`. A\n * getter follows a ref that changes (`() => hovered.value?.ref ?? null`).\n */\nexport function useAnnotationAnchor(\n ref: MaybeRefOrGetter<AnnotationRef | null>,\n): Readonly<Ref<AnnotationAnchor | null>> {\n return useOptionalSelector(\n AnnotationHostToken,\n (annotation) => {\n const wanted = toValue(ref);\n return wanted ? annotation.getAnnotationAnchor(wanted) : null;\n },\n null,\n sameAnnotationAnchor,\n );\n}\n\n// ── comments (the conversation plane) ────────────────────────────────────────\n\n/**\n * The comments API: the `comments` part of `useAnnotation()`, for the\n * document in scope. Like `useAnnotation()`, the object never changes and\n * always reaches the current document. Pair it with {@link useCommentThreads}\n * for the threads to show.\n */\nexport function useComments(): CommentsApi {\n const annotation = useAnnotation();\n // Read `comments` at each use, never once here: the document in scope may change.\n const target = markRaw({});\n return new Proxy(target, {\n get: (_target, key) =>\n typeof key === 'string' && key.startsWith('__v_')\n ? Reflect.get(target, key)\n : Reflect.get(annotation.comments, key),\n has: (_target, key) => Reflect.has(annotation.comments, key),\n }) as CommentsApi;\n}\n\nconst NO_PAGES: readonly PageLayout[] = Object.freeze([]);\nconst NO_THREADS: readonly CommentThread[] = Object.freeze([]);\n\n/**\n * Every comment thread in the document as a ref, display-ordered (page\n * position, then top of page, then creation date) and with where its page is\n * shown (`pageIndex`, `pageLabel`). It follows annotation writes (your own,\n * remote ones, loading) and page moves and deletes; the same array between\n * changes.\n */\nexport function useCommentThreads(): Readonly<Ref<readonly CommentThreadView[]>> {\n const documentId = useDocumentId();\n const threads = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.comments.listThreads(),\n NO_THREADS,\n );\n const pages = useKernelValue((kernel) =>\n documentId.value ? kernel.documents.listPages(documentId.value) : NO_PAGES,\n );\n return computed(() => enrichCommentThreads(threads.value, pages.value));\n}\n\n/**\n * The thread holding any of its annotations (the root, a reply, a grouped\n * part, a review state), as a ref, or null. A getter follows a ref that changes.\n */\nexport function useCommentThread(\n ref: MaybeRefOrGetter<AnnotationRef | null>,\n): Readonly<Ref<CommentThreadView | null>> {\n const views = useCommentThreads();\n const annotation = useOptionalCapability(AnnotationToken);\n return computed(() => {\n const wanted = toValue(ref);\n const api = annotation.value;\n if (wanted == null || !api) return null;\n const thread = api.comments.getThread(wanted);\n if (!thread) return null;\n const root = annotationKey(thread.root.ref);\n return views.value.find((view) => annotationKey(view.root.ref) === root) ?? null;\n });\n}\n\n// ── the file picker ──────────────────────────────────────────────────────────\n\n/**\n * The default file-picker provider: the browser's file dialog (from\n * `@embedpdf/web`), honouring the tool's `accept` filter. The adapter fulfils\n * the plugin's DOM-free port; the dialog never lives in the plugin.\n */\nexport const filePickerProvider: FilePickerProvider = pickRequestedFile;\n\n/**\n * Install the file-picker provider for the document in scope while the\n * component lives: the one port behind every click-then-pick tool (a stamp\n * whose source is `'prompt'`, the file attachment tool). Call it once, at a\n * document-wide spot (not in a page layer). Without an argument it installs\n * {@link filePickerProvider}, so those tools work out of the box; pass your\n * own (an asset library, a cloud drive: switch on `toolId` or `subtype`), or\n * `null` to make them do nothing. A ref follows a provider that changes.\n */\nexport function useFilePickerProvider(\n provider: MaybeRef<FilePickerProvider | null> = filePickerProvider,\n): void {\n const annotation = useOptionalCapability(AnnotationToken);\n // Not a getter: the provider is itself a function.\n watch(\n [annotation, () => unref(provider)],\n ([capability, current], _previous, onCleanup) => {\n if (!capability) return;\n // One port per document: a second caller silently replaces the first.\n onCleanup(\n installFilePickerProvider(capability, current, () =>\n devWarn(\n 'file-picker-provider-twice',\n 'useFilePickerProvider() is called from two mounted components for the same ' +\n 'document — the later one wins. Call it once, at a document-scoped spot.',\n ),\n ),\n );\n },\n { immediate: true },\n );\n}\n"],"names":["stateComposable","annotationState","settingsComposable","AnnotationToken","_useSlots","useOptionalSelector","AnnotationHostToken","host","shallowEqual","useViewerSettings","computed","annotationChromePaint","chromeInPixels","_openBlock","_createElementBlock","_hoisted_1","_Fragment","_renderList","_unref","_normalizeStyle","_createElementVNode","_renderSlot","frameInPixels","shallowRef","useOptionalCapability","createTextBoxEditorFollower","watch","toValue","onScopeDispose","provide","page","usePage","annotationKey","inject","textBoxEditorScaleOf","textBoxStyleOf","lookFrameOf","_createBlock","_resolveDynamicComponent","textPlateInPixels","sceneViewBox","svgShapesOf","scene","MITER_LIMIT","ghostOpacity","_createVNode","SvgShapes","pictureOrPainting","shownAppearance","hasLiveDrawing","rasterInFrame","AnnotationScene","previewBucket","ref","loadObjectUrl","rectInPixels","usePaintsPagePart","InteractionToken","devWarn","registerRendererBehaviors","createShownUrls","onUnmounted","RenderToken","loadAppearanceUrls","editingTextKeyOf","annotationDrawingOf","layerTextBoxesOf","markRaw","h","NativeDrawing","AnnotationFrame","shown","toRaw","AnnotationLook","bakedAppearanceOf","FreeTextBox","StampGhost","AnnotationChrome","_createSlots","_withCtx","useProjectorBinding","sameSelectionAnchor","Anchored","sameCreationDraftAnchor","sameRotationAnchor","paintDefault","paint","useCapability","useCapabilityEvent","sameAnnotationAnchor","useDocumentId","useKernelValue","enrichCommentThreads","pickRequestedFile","unref","installFilePickerProvider"],"mappings":"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"}
1
+ {"version":3,"file":"composables-Bi6QvJpj.cjs","sources":["../src/annotation/state.ts","../src/annotation/AnnotationChrome.vue","../src/annotation/AnnotationFrame.vue","../src/annotation/text-box.ts","../src/annotation/AnnotationLook.vue","../src/annotation/FreeTextBox.vue","../src/annotation/AnnotationScene.vue","../src/annotation/NativeDrawing.vue","../src/annotation/StampGhost.vue","../src/annotation/AnnotationLayer.vue","../src/annotation/AnnotationMenu.vue","../src/annotation/AnnotationDraftMenu.vue","../src/annotation/AnnotationRotationBadge.vue","../src/annotation/composables.ts"],"sourcesContent":["/**\n * The annotation composables other feature entries use too (the form layer\n * reads the selection and the settings), kept apart so they don't import the\n * whole annotation feature: the state and the settings, each from its\n * declaration.\n */\nimport { AnnotationToken, annotationState } from '@embedpdf/plugin-annotation/contract';\nimport { settingsComposable, stateComposable } from '../state';\n\n/**\n * The annotation state as refs: `status` (`'loading'` until every annotation\n * is in, then `'ready'`), the `selected` annotations, the one `hovered` under\n * the pointer and the text box being typed in (`editing`). With a selector,\n * one ref that updates only when the value it picks changes. Empty without a\n * document.\n */\nexport const useAnnotationState = stateComposable(annotationState);\n\n/**\n * The annotation settings (`snap`, `chrome`, `afterCreate`, `tools`) as refs,\n * or one ref for the value `select` picks. They belong to the plugin, so they\n * read without a document; change them with `useAnnotation().updateSettings()`.\n */\nexport const useAnnotationSettings = settingsComposable(AnnotationToken);\n","<!--\n The selection's chrome on one page: its outline, handles, rotation handle,\n snapping guides, the lines of a turn in progress and the box dragged to\n select. The plugin lists the nodes and sizes the screen-constant parts for\n the page's zoom; `@embedpdf/web` puts them in pixels and paints them through\n their `--epdf-annotation-*` variables. The layer draws them as SVG; a\n `#handle` or `#rotation-handle` slot draws its handles as HTML over the page\n instead. The viewer still decides where a handle can be grabbed, so what a\n slot draws can't break dragging.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { shallowEqual } from '@embedpdf/core';\nimport type { ChromeNode } from '@embedpdf/core-annotation';\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { annotationChromePaint, chromeInPixels } from '@embedpdf/web';\nimport { useOptionalSelector } from '../runtime/capabilities';\nimport { useViewerSettings } from '../runtime/documents';\nimport type { PageContextValue } from '../runtime/page';\nimport { useAnnotationSettings } from './state';\nimport type { HandleProps, RotationHandleProps } from './types';\n\nconst props = defineProps<{ page: PageContextValue }>();\n\nconst slots = defineSlots<{\n /** One handle, drawn your way. */\n handle?(props: HandleProps): unknown;\n /** The rotation handle, drawn your way. */\n 'rotation-handle'?(props: RotationHandleProps): unknown;\n}>();\n\nconst NO_NODES: readonly ChromeNode[] = Object.freeze([]);\n\n// The page's view scale converts the screen-pixel chrome settings into\n// content units inside the plugin (the rotation handle's offset, grab zones):\n// screen-constant at every zoom. What this draws is in screen pixels already.\nconst nodes = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = props.page;\n return host.listChromeNodes(ref, transform.viewScale, transform.rotation, transform.zoom);\n },\n NO_NODES,\n shallowEqual,\n);\nconst chrome = useAnnotationSettings((settings) => settings.chrome);\nconst accent = useViewerSettings((settings) => settings.accent);\n/**\n * The chrome settings, painted, as each part's `style`: follows the settings\n * and the viewer's accent live. Paint goes in `style`, never in SVG\n * attributes, which don't read the `var(--epdf-…)` the paint starts with.\n */\nconst painted = computed(() => {\n const paint = annotationChromePaint(chrome.value, accent.value);\n const style = (part: object): CSSProperties => ({ ...part });\n return {\n outline: style(paint.outline),\n handle: style(paint.handle),\n rotationHandle: style(paint.rotationHandle),\n rotationStalk: style({ stroke: paint.rotationHandle.stroke }),\n guide: style(paint.guide),\n rotationGuide: style(paint.rotationGuide),\n marquee: style(paint.marquee),\n };\n});\nconst pixels = computed(() => chromeInPixels(nodes.value, props.page.transform));\n\n/** Whether there are handles a slot could draw: the slots' own element exists only then. */\nconst hasHandles = computed(() =>\n pixels.value.some((node) => node.kind === 'handle' || node.kind === 'rotation-handle'),\n);\n</script>\n\n<template>\n <svg :style=\"{ position: 'absolute', inset: 0, overflow: 'visible', pointerEvents: 'none' }\">\n <template v-for=\"(node, index) in pixels\" :key=\"index\">\n <template v-if=\"node.kind === 'handle'\">\n <template v-if=\"!slots.handle\">\n <circle\n v-if=\"chrome.handles.shape === 'circle'\"\n :cx=\"node.at.x\"\n :cy=\"node.at.y\"\n :r=\"chrome.handles.size / 2\"\n stroke-width=\"1.5\"\n :style=\"painted.handle\"\n />\n <!-- The square rides a turned box's orientation (it spins about itself). -->\n <rect\n v-else\n :x=\"node.at.x - chrome.handles.size / 2\"\n :y=\"node.at.y - chrome.handles.size / 2\"\n :width=\"chrome.handles.size\"\n :height=\"chrome.handles.size\"\n stroke-width=\"1.5\"\n :style=\"painted.handle\"\n :transform=\"node.rotation ? `rotate(${node.rotation} ${node.at.x} ${node.at.y})` : undefined\"\n />\n </template>\n </template>\n <line\n v-else-if=\"node.kind === 'guide'\"\n :x1=\"node.from.x\"\n :y1=\"node.from.y\"\n :x2=\"node.to.x\"\n :y2=\"node.to.y\"\n shape-rendering=\"crispEdges\"\n :style=\"painted.guide\"\n />\n <polygon\n v-else-if=\"node.kind === 'turned-outline'\"\n :points=\"node.points\"\n fill=\"none\"\n :style=\"painted.outline\"\n />\n <g v-else-if=\"node.kind === 'rotation-guides'\">\n <line\n v-for=\"(line, lineIndex) in node.lines\"\n :key=\"lineIndex\"\n :x1=\"line.from.x\"\n :y1=\"line.from.y\"\n :x2=\"line.to.x\"\n :y2=\"line.to.y\"\n :opacity=\"line.opacity\"\n :style=\"painted.rotationGuide\"\n />\n </g>\n <template v-else-if=\"node.kind === 'rotation-handle'\">\n <g v-if=\"!slots['rotation-handle']\">\n <line\n v-if=\"chrome.rotationHandle.stalk\"\n :x1=\"node.from.x\"\n :y1=\"node.from.y\"\n :x2=\"node.at.x\"\n :y2=\"node.at.y\"\n stroke-width=\"1\"\n :style=\"painted.rotationStalk\"\n />\n <circle\n :cx=\"node.at.x\"\n :cy=\"node.at.y\"\n :r=\"chrome.rotationHandle.size / 2\"\n stroke-width=\"1.5\"\n :style=\"painted.rotationHandle\"\n />\n </g>\n </template>\n <!-- The box dragged to select keeps its own look (a see-through accent\n fill, always dashed); the selection outline follows the settings. -->\n <rect\n v-else-if=\"node.kind === 'marquee'\"\n :x=\"node.box.left\"\n :y=\"node.box.top\"\n :width=\"node.box.width\"\n :height=\"node.box.height\"\n stroke-width=\"1\"\n stroke-dasharray=\"4 3\"\n :style=\"painted.marquee\"\n />\n <rect\n v-else-if=\"node.kind === 'outline'\"\n :x=\"node.box.left\"\n :y=\"node.box.top\"\n :width=\"node.box.width\"\n :height=\"node.box.height\"\n fill=\"none\"\n :style=\"painted.outline\"\n />\n </template>\n </svg>\n <div\n v-if=\"hasHandles && (slots.handle || slots['rotation-handle'])\"\n :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\"\n >\n <template v-for=\"(node, index) in pixels\" :key=\"index\">\n <slot\n v-if=\"node.kind === 'handle' && slots.handle\"\n name=\"handle\"\n :at=\"node.at\"\n :size=\"chrome.handles.size\"\n :rotation=\"node.rotation\"\n :kind=\"node.role\"\n :active=\"node.active\"\n />\n <slot\n v-else-if=\"node.kind === 'rotation-handle' && slots['rotation-handle']\"\n name=\"rotation-handle\"\n :at=\"node.at\"\n :from=\"node.from\"\n :size=\"chrome.rotationHandle.size\"\n :rotation=\"0\"\n :active=\"false\"\n />\n </template>\n </div>\n</template>\n","<!--\n The box an annotation draws into, placed, sized and turned like the\n annotation (`item.frame`) inside the page layer, which the page itself\n turns. The annotation's own drawing and any look of yours draw inside it.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport { frameInPixels } from '@embedpdf/web';\nimport type { PageContextValue } from '../runtime/page';\n\nconst props = withDefaults(\n defineProps<{\n item: RenderItem;\n page: PageContextValue;\n /** An interactive renderer takes the pointer: the layer's own `none` ends here. */\n interactive?: boolean;\n /** No pointer and no focus for the whole subtree: a renderer that only draws. */\n inert?: boolean;\n }>(),\n { interactive: false, inert: false },\n);\n\ndefineSlots<{ default?(): unknown }>();\n\nconst style = computed((): CSSProperties => {\n const box = frameInPixels(props.item.frame, props.page.transform);\n return {\n position: 'absolute',\n left: `${box.left}px`,\n top: `${box.top}px`,\n width: `${box.width}px`,\n height: `${box.height}px`,\n transform: box.transform,\n transformOrigin: 'center',\n // On the frame: a turned frame groups what is inside it, so blending on\n // an inner element would stop blending with the page.\n mixBlendMode: props.item.blend as CSSProperties['mixBlendMode'],\n pointerEvents: props.interactive ? 'auto' : 'none',\n };\n});\n</script>\n\n<template>\n <div :inert=\"inert || undefined\" :style=\"style\">\n <slot />\n </div>\n</template>\n","/**\n * Text boxes you type in. `@embedpdf/web`'s text box editor makes an element\n * the editor of a free text box (rich text, focus and `contentEditable`\n * following the plugin's `editing`, presses kept inside), and its follower\n * attaches when the element and the capability are there and takes the box\n * and the scale whenever they change; this binds the follower to Vue. The\n * layer's own text boxes use it, and so does `useRichTextEditor()`, for a\n * renderer that draws its text box itself.\n */\nimport { computed, inject, onScopeDispose, provide, shallowRef, toValue, watch } from 'vue';\nimport type {\n ComponentPublicInstance,\n CSSProperties,\n InjectionKey,\n MaybeRefOrGetter,\n Ref,\n} from 'vue';\nimport type { Annotation, AnnotationRef, TextItem } from '@embedpdf/plugin-annotation';\n// Typing reaches the plugin through its host lens (drafts, the text selection).\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { createTextBoxEditorFollower, ownTextBoxOf, textBoxEditorScaleOf } from '@embedpdf/web';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport { usePage } from '../runtime/page';\nimport type { RichTextEditor } from './types';\n\n/**\n * Make an element the editor of a text box, following `item` and `scale`\n * (pixels per point). Returns the element's ref: put it on the element, and\n * render nothing inside it, since the editor owns its children.\n */\nexport function useTextBoxEditor(\n item: MaybeRefOrGetter<TextItem | null>,\n scale: MaybeRefOrGetter<number>,\n): Ref<HTMLElement | null> {\n const element = shallowRef<HTMLElement | null>(null);\n const annotation = useOptionalCapability(AnnotationHostToken);\n const follower = createTextBoxEditorFollower<AnnotationRef>();\n // `post`: the element is in the document by then, so focusing it works. The\n // editor redraws only when the text differs, so the caret never jumps while\n // typing; focus follows `editing`.\n watch(\n [annotation, element, () => toValue(item), () => toValue(scale)],\n ([capability, target, current, pixelsPerPoint]) =>\n follower.follow(target, capability, current, pixelsPerPoint),\n { immediate: true, flush: 'post' },\n );\n onScopeDispose(() => follower.detach());\n return element;\n}\n\n/** How much the layer scales the look around it: 1 outside a look, or in one drawn at its size on screen. */\nconst LookScaleKey: InjectionKey<Readonly<Ref<number>>> = Symbol('embedpdf annotation look scale');\nconst UNSCALED = computed(() => 1);\n\n/** Installed by the layer around a look it scales, not by app code. */\nexport function provideLookScale(scale: Readonly<Ref<number>>): void {\n provide(LookScaleKey, scale);\n}\n\nconst NO_STYLE: CSSProperties = Object.freeze({});\n\n/**\n * Make your own element the editor of a text box you draw yourself (a\n * renderer for free text): it draws the runs, turns typing back into runs,\n * keeps the caret when the style changes, and handles pasting, input methods\n * and the format shortcuts. The formatting calls (`text.toggleFormat`,\n * `selection.update`) work on it as they do on the built-in one.\n *\n * ```vue\n * const { ref: editorRef, editing, style } = useRichTextEditor(() => props.annotation);\n * <div :ref=\"editorRef\" :class=\"{ editing }\" :style=\"style\" />\n * ```\n *\n * `ref` goes on your element (render nothing inside it: the editor owns what's\n * in it); `style` and `editing` are refs. `style` fills the element's parent at\n * a legible size: draw the box's frame on the parent.\n */\nexport function useRichTextEditor(annotation: MaybeRefOrGetter<Annotation>): RichTextEditor {\n const page = usePage();\n // Saved and idle too: your element draws its text, no engine picture does.\n const item = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform } = page.value;\n return host.getTextItem(toValue(annotation).ref, {\n zoom: transform.zoom,\n rotation: transform.rotation,\n });\n },\n null,\n );\n // Pixels per point where the element is: inside a scaled look, at the\n // annotation's 100% size; the look's scale does the rest.\n const lookScale = inject(LookScaleKey, UNSCALED);\n const scale = computed(() =>\n textBoxEditorScaleOf(item.value, page.value.transform, lookScale.value),\n );\n const own = computed(() => (item.value ? ownTextBoxOf(item.value, scale.value) : null));\n const element = useTextBoxEditor(item, () => own.value?.scale ?? scale.value);\n const style = computed((): CSSProperties => own.value?.style ?? NO_STYLE);\n return {\n ref: (target: Element | ComponentPublicInstance | null) => {\n element.value = target instanceof HTMLElement ? target : null;\n },\n style,\n editing: computed(() => item.value?.editing ?? false),\n };\n}\n","<!--\n Your look for one annotation, inside its frame: your renderer's component,\n drawn at the annotation's 100% size and scaled with the page, unless the\n renderer opts out (`scale: false`) and draws at its size on screen.\n `useRichTextEditor()` inside it divides by that scale.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { Component, CSSProperties } from 'vue';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport type { Annotation } from '@embedpdf/plugin-annotation';\nimport { frameInPixels, lookFrameOf } from '@embedpdf/web';\nimport type { PageContextValue } from '../runtime/page';\nimport { provideLookScale } from './text-box';\n\nconst props = defineProps<{\n /** Your renderer's component. */\n component: Component;\n /** Draw at the annotation's 100% size and let the layer scale it (the default), or at its size on screen. */\n scaled: boolean;\n annotation: Annotation;\n item: RenderItem;\n page: PageContextValue;\n native: Component;\n appearance: { url: string } | null;\n interactive: boolean;\n}>();\n\nconst pixels = computed(() => frameInPixels(props.item.frame, props.page.transform));\nconst frame = computed(() => lookFrameOf(pixels.value, props.scaled));\n// What `useRichTextEditor()` in the look divides by: 1 when it draws at its size on screen.\nprovideLookScale(computed(() => (props.scaled ? pixels.value.scale : 1)));\n\nconst scaledBox = computed(\n (): CSSProperties => ({\n position: 'absolute',\n left: 0,\n top: 0,\n width: `${pixels.value.design.width}px`,\n height: `${pixels.value.design.height}px`,\n transform: `scale(${pixels.value.scale})`,\n transformOrigin: '0 0',\n }),\n);\n</script>\n\n<template>\n <div v-if=\"scaled\" :style=\"scaledBox\">\n <component\n :is=\"component\"\n :annotation=\"annotation\"\n :frame=\"frame\"\n :native=\"native\"\n :appearance=\"appearance\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"interactive\"\n />\n </div>\n <component\n :is=\"component\"\n v-else\n :annotation=\"annotation\"\n :frame=\"frame\"\n :native=\"native\"\n :appearance=\"appearance\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"interactive\"\n />\n</template>\n","<!--\n A free text annotation's text: the same styled element for reading and for\n typing, placed on the engine's text plate (the box inset by its padding).\n The editor binding owns what's inside it, so the template renders nothing\n there, and the element lives as long as the text box does (keyed by its id),\n so the caret never jumps while someone types. Focus and `contentEditable`\n follow the plugin's `editing`.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TextItem } from '@embedpdf/plugin-annotation';\nimport { annotationChromePaint, freeTextBoxOf } from '@embedpdf/web';\nimport { useViewerSettings } from '../runtime/documents';\nimport type { PageContextValue } from '../runtime/page';\nimport { useAnnotationSettings } from './state';\nimport { useTextBoxEditor } from './text-box';\n\nconst props = defineProps<{ item: TextItem; page: PageContextValue }>();\n\nconst chrome = useAnnotationSettings((settings) => settings.chrome);\nconst accent = useViewerSettings((settings) => settings.accent);\nconst outline = computed(() => annotationChromePaint(chrome.value, accent.value).textOutline);\n\n// On the engine's text plate (the box inset by its padding), laid out at a legible size.\nconst box = computed(() => freeTextBoxOf(props.item, props.page.transform, outline.value));\nconst element = useTextBoxEditor(\n () => props.item,\n () => box.value.scale,\n);\n</script>\n\n<template>\n <div ref=\"element\" :style=\"box.style\" />\n</template>\n","<!--\n An annotation's scene, filling its frame: drawn upright in it, the frame\n turns it. The core computed the box and the painted scene; `@embedpdf/web`\n describes each scene node as one SVG element (its tag, its attributes under\n their SVG names, its text), so there is no per-kind logic and no bounds math\n here: one loop draws every kind.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { MITER_LIMIT, scene } from '@embedpdf/core-annotation';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport { ghostOpacity, sceneViewBox, svgShapesOf } from '@embedpdf/web';\nimport SvgShapes from '../runtime/SvgShapes.vue';\n\nconst props = defineProps<{ item: RenderItem }>();\n\n// Nothing to draw until the annotation has area (the 0×0 draft at mouse-down).\nconst viewBox = computed(() => sceneViewBox(props.item.box));\nconst shapes = computed(() => svgShapesOf(scene(props.item), { miterLimit: MITER_LIMIT }));\nconst style = computed(\n (): CSSProperties => ({\n position: 'absolute',\n left: 0,\n top: 0,\n width: '100%',\n height: '100%',\n overflow: 'visible',\n pointerEvents: 'none',\n // A ghost is see-through as a whole, so its fill and stroke don't stack.\n ...(props.item.source === 'ghost'\n ? { opacity: ghostOpacity(props.item.ghostOpacity ?? 0.5) }\n : {}),\n }),\n);\n</script>\n\n<template>\n <svg v-if=\"viewBox\" :viewBox=\"viewBox\" :style=\"style\">\n <SvgShapes :shapes=\"shapes\" />\n </svg>\n</template>\n","<!--\n The layer's own drawing of one annotation, inside its frame: the engine's\n raster where the core places it (following a move as it happens), or the\n vector scene for everything drawn live (shapes, clouds, markup, a drawing\n in progress, a tool's ghost, a picture older than the annotation). One rule\n picks (`pictureOrPainting`). A renderer gets it as `native`.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport { hasLiveDrawing, type RenderItem } from '@embedpdf/core-annotation';\nimport {\n pictureOrPainting,\n rasterInFrame,\n shownAppearance,\n type AppearanceUrl,\n} from '@embedpdf/web';\nimport AnnotationScene from './AnnotationScene.vue';\n\nconst props = defineProps<{\n item: RenderItem;\n /** The page's loaded pictures, by item and state; `null` until the first ones arrive. */\n urls: Readonly<Record<string, AppearanceUrl>> | null;\n}>();\n\nconst shows = computed(() => {\n const { item, urls } = props;\n return pictureOrPainting({\n pending: item.source !== 'baked',\n picture: urls && shownAppearance(urls, item.id, item.annotation?.appearanceState ?? null),\n version: item.pictureVersion ?? 0,\n loaded: urls !== null,\n paint: () => (hasLiveDrawing(item) ? item : null),\n });\n});\n\n/** The engine's raster inside the item's frame, where `item.raster` puts it, at any frame size. */\nconst baked = computed((): { url: string; style: CSSProperties } | null => {\n const { item } = props;\n const look = shows.value;\n if (look?.kind !== 'picture' || !item.raster) return null;\n const box = rasterInFrame(item.raster, item.frame);\n return {\n url: look.picture.url,\n style: {\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n // The appearance box is sized in content units; a global\n // `img { max-width: 100% }` reset would otherwise clamp it to the\n // containing block and distort the aspect (a landscape stamp on a turned,\n // portrait page), so honour the explicit size.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n // The turn the engine took out of the raster, put back about its middle.\n transform: box.transform,\n transformOrigin: 'center',\n },\n };\n});\n</script>\n\n<template>\n <img v-if=\"baked\" :src=\"baked.url\" alt=\"\" draggable=\"false\" :style=\"baked.style\" />\n <AnnotationScene v-else-if=\"shows?.kind === 'painting'\" :item=\"item\" />\n</template>\n","<!--\n The armed stamp's ghost: a see-through render of the stamp, in the exact box\n a click would place it (the plugin computes it with the same fit and clamp\n as the placement). Every other tool's ghost is a render item, drawn like a\n drawing in progress. The preview bytes live in the plugin; this owns only\n the object URL, keyed on the armed stamp: a new arm swaps the image, a\n disarm (or another tool) drops it.\n-->\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport {\n AnnotationToken as AnnotationHostToken,\n previewBucket,\n} from '@embedpdf/plugin-annotation/contract/host';\nimport { ghostOpacity, loadObjectUrl, rectInPixels } from '@embedpdf/web';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport type { PageContextValue } from '../runtime/page';\n\nconst props = defineProps<{ page: PageContextValue }>();\n\nconst annotation = useOptionalCapability(AnnotationHostToken);\nconst ghost = useOptionalSelector(\n AnnotationHostToken,\n (host) => host.getImageGhost(props.page.ref),\n null,\n);\nconst armed = useOptionalSelector(AnnotationHostToken, (host) => host.getArmedStamp(), null);\n// The ghost is a bitmap of vector artwork, right at one size: ask for the\n// bucket that covers the box's device width (points × device pixels per\n// point), so it stays sharp at every zoom and density. The plugin caches per\n// bucket.\nconst bucket = computed(() =>\n ghost.value ? previewBucket(ghost.value.box.width * props.page.transform.renderScale) : 0,\n);\n\nconst url = ref<string | null>(null);\nwatch(\n [annotation, armed, bucket],\n ([host, _armed, size], _previous, onCleanup) => {\n if (!host || !size) {\n url.value = null;\n return;\n }\n // The previous bucket's image stays up until this one arrives: no flicker\n // while a zoom crosses a bucket boundary.\n onCleanup(\n loadObjectUrl(\n () => host.renderArmedStampPreview(size),\n (next) => (url.value = next),\n ),\n );\n },\n { immediate: true },\n);\n\nconst style = computed((): CSSProperties | null => {\n const current = ghost.value;\n if (!current) return null;\n const frame = rectInPixels(current.box, props.page.transform);\n return {\n position: 'absolute',\n left: `${frame.left}px`,\n top: `${frame.top}px`,\n width: `${frame.width}px`,\n height: `${frame.height}px`,\n // Never let a global `img` reset clamp the box and distort the aspect.\n maxWidth: 'none',\n maxHeight: 'none',\n pointerEvents: 'none',\n opacity: ghostOpacity(current.opacity),\n ...(current.rot ? { transform: `rotate(${current.rot}deg)`, transformOrigin: 'center' } : {}),\n };\n});\n</script>\n\n<template>\n <img v-if=\"style && url\" :src=\"url\" alt=\"\" draggable=\"false\" :style=\"style\" />\n</template>\n","<!--\n <AnnotationLayer>: a page's annotations, the selection's outline and\n handles, the tool's preview and the text boxes being typed in. Put it in the\n Stage's #page slot above the rendered page: while it's there, the render\n layer leaves the annotations out of the page's picture.\n\n Pure paint: it reads the plugin's per-page render items and chrome and draws\n them. Pointer events reach the plugin through the interaction hub (the\n Stage forwards them), and so does the cursor. Each annotation is one drawing:\n its vector scene, the engine's baked appearance, or a look of yours from\n `renderers`, which may keep the layer's own drawing (`native`) and add to it.\n The `#handle` and `#rotation-handle` slots draw the handles your way.\n-->\n<script setup lang=\"ts\">\nimport { computed, h, markRaw, onUnmounted, shallowRef, toRaw, watch } from 'vue';\nimport type { Component } from 'vue';\nimport { annotationKey, shallowEqual } from '@embedpdf/core';\nimport type { RenderItem } from '@embedpdf/core-annotation';\nimport type { Annotation, TextItem } from '@embedpdf/plugin-annotation';\n// The layer is framework code, so it resolves the full host lens (page items,\n// chrome, appearances…): the same runtime token as the public one, typed wider.\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport { RenderToken } from '@embedpdf/plugin-render/contract/host';\nimport {\n annotationDrawingOf,\n bakedAppearanceOf,\n createShownUrls,\n editingTextKeyOf,\n layerTextBoxesOf,\n loadAppearanceUrls,\n registerRendererBehaviors,\n} from '@embedpdf/web';\nimport type { AnnotationDrawing, AppearanceUrl } from '@embedpdf/web';\nimport { devWarn } from '../dev';\nimport { usePaintsPagePart } from '../page-layers';\nimport { useOptionalCapability, useOptionalSelector } from '../runtime/capabilities';\nimport { usePage } from '../runtime/page';\nimport AnnotationChrome from './AnnotationChrome.vue';\nimport AnnotationFrame from './AnnotationFrame.vue';\nimport AnnotationLook from './AnnotationLook.vue';\nimport FreeTextBox from './FreeTextBox.vue';\nimport NativeDrawing from './NativeDrawing.vue';\nimport StampGhost from './StampGhost.vue';\nimport type { AnnotationRenderer, HandleProps, RotationHandleProps } from './types';\n\nconst props = defineProps<{\n /**\n * Your own look for some annotations: each renderer says which ones (`for`)\n * and with which component. Define the list once, in `<script setup>`.\n */\n renderers?: AnnotationRenderer[];\n}>();\n\nconst slots = defineSlots<{\n /** Draw each handle yourself, in place of the layer's: it gets {@link HandleProps}. */\n handle?(props: HandleProps): unknown;\n /** Draw the rotation handle yourself: it gets {@link RotationHandleProps}. */\n 'rotation-handle'?(props: RotationHandleProps): unknown;\n}>();\n\ntype Drawing = AnnotationDrawing<AnnotationRenderer>;\n\nconst NO_ITEMS: readonly RenderItem[] = Object.freeze([]);\nconst NO_TEXTS: readonly TextItem[] = Object.freeze([]);\n\nconst page = usePage();\n// While it's here, the page's picture leaves the annotations to it.\nusePaintsPagePart(\n computed(() => page.value.ref),\n 'annotations',\n);\nconst annotation = useOptionalCapability(AnnotationHostToken);\nconst interaction = useOptionalCapability(InteractionToken);\n// The active tool decides which interactive renderers take the pointer, so a\n// tool change draws the layer again (`interactive` functions read it live).\nconst activeToolId = useOptionalSelector(\n InteractionToken,\n (hub) => hub.getActiveToolId() as string,\n '',\n);\n\n// The page's view (its zoom and turn) projects annotations that keep their\n// size or stay upright on screen (`noZoom`, `noRotate`) inside the plugin: no\n// flag logic lives here. `zoom`, not `viewScale`: 1 is the page's 100%.\nconst items = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = page.value;\n return host.listPageItems(ref, { zoom: transform.zoom, rotation: transform.rotation });\n },\n NO_ITEMS,\n shallowEqual,\n);\nconst texts = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const { transform, ref } = page.value;\n return host.listTextItems(ref, { zoom: transform.zoom, rotation: transform.rotation });\n },\n NO_TEXTS,\n shallowEqual,\n);\n\n// ── your renderers ───────────────────────────────────────────────────────────\n\n/** Bumped when the renderers' behaviors register again, so the drawings are read again. */\nconst registrations = shallowRef(0);\n// An `interactive` renderer takes the pointer through a behavior the plugin\n// knows, registered once per capability and entry however many pages mount\n// the layer. Entry identity is the key, so a list written inline in the\n// template (a new array on every render) registers again each time: say so.\nwatch(\n [annotation, () => props.renderers],\n ([host, renderers], previous, onCleanup) => {\n const before = previous?.[1];\n if (renderers && before && renderers !== before && shallowEqual(renderers, before)) {\n devWarn(\n 'annotation-renderers-inline',\n '<AnnotationLayer :renderers> was given a new array with the same entries — define it ' +\n 'once in <script setup>, because entry identity keys the behavior registration.',\n );\n }\n if (host && renderers) {\n onCleanup(\n registerRendererBehaviors(host, renderers, () =>\n String(interaction.value?.getActiveToolId() ?? ''),\n ),\n );\n }\n registrations.value += 1;\n },\n { immediate: true },\n);\n\n// ── baked appearances ────────────────────────────────────────────────────────\n\n// `null` until the page's first pictures arrive.\nconst urls = shallowRef<Record<string, AppearanceUrl> | null>(null);\n// The pictures shown stay valid until the next ones are shown.\nconst shown = createShownUrls();\nonUnmounted(() => shown.release());\n// Baked annotations draw from engine rasters: load them again when the page's\n// baked set or an appearance version changes (a stamp just placed, a resize\n// whose new appearance arrived), and when the bake scale does. A move or a\n// turn leaves the epoch as it is (the same pixels, placed elsewhere), and live\n// gestures don't touch it: nothing loads mid-drag.\nconst bakedKey = useOptionalSelector(\n AnnotationHostToken,\n (host) => host.getAppearanceEpoch(page.value.ref),\n '',\n);\n// The appearance scale follows the document's render policy: zoom steps inside\n// one rung of the appearance lattice bake nothing again. Without the render\n// plugin, only this session's pictures load.\nconst bakeScale = useOptionalSelector(\n RenderToken,\n (render) => render.getAppearanceScale(page.value.transform.renderScale),\n page.value.transform.renderScale,\n);\nwatch(\n [annotation, () => page.value.ref, bakeScale, bakedKey],\n ([host, pageRef, scale], _previous, onCleanup) => {\n if (!host || !scale) return;\n onCleanup(\n loadAppearanceUrls(\n shown,\n (signal) => host.renderAppearances(pageRef, scale, signal),\n annotationKey,\n (loaded) => (urls.value = loaded),\n ),\n );\n },\n { immediate: true },\n);\n\n// ── what each annotation draws ───────────────────────────────────────────────\n\n/** The text box being typed in, by key: while it is, a look's editor takes the keys. */\nconst editingKey = computed(() => editingTextKeyOf(texts.value, annotationKey));\n\ninterface Drawn {\n item: RenderItem;\n annotation: Annotation | null;\n drawing: Drawing;\n}\n\n/** The layer's own drawing, for what isn't an annotation yet (a drawing in progress, a ghost). */\nconst NATIVE: Drawing = { kind: 'native', inert: false };\n\n// Ownership beats looks: an engaged behavior's renderer is authoritative (the\n// form plugin's controls own their DOM); `for` rules apply only to what the\n// layer owns, and draw without the pointer. Read whenever the items, the\n// active tool or the registrations change: `interactive` functions and the\n// plugin's behaviors are asked here.\nconst drawn = computed((): Drawn[] => {\n void activeToolId.value;\n void registrations.value;\n const host = annotation.value;\n const renderers = props.renderers;\n return items.value.map((item): Drawn => {\n const record = item.annotation ?? null;\n if (!record || !host) return { item, annotation: null, drawing: NATIVE };\n const typing = editingKey.value !== null && annotationKey(record.ref) === editingKey.value;\n return { item, annotation: record, drawing: annotationDrawingOf(record, host, renderers, typing) };\n });\n});\n\n/** The text boxes the layer draws itself: one your renderer draws is edited there (`useRichTextEditor()`). */\nconst ownTexts = computed(() =>\n layerTextBoxesOf(texts.value, items.value, props.renderers, annotationKey),\n);\n\n// `native` for a renderer: one component per annotation, kept by its id, that\n// draws the layer's current drawing of it. The same component across renders,\n// so a drag moves the drawing instead of replacing it.\nconst itemsById = computed(() => new Map(items.value.map((item) => [item.id, item])));\nconst natives = new Map<string, Component>();\nconst framedNatives = new Map<string, Component>();\nfunction nativeOf(id: string): Component {\n let native = natives.get(id);\n if (!native) {\n native = markRaw(() => {\n const item = itemsById.value.get(id);\n return item ? h(NativeDrawing, { item, urls: urls.value }) : null;\n });\n natives.set(id, native);\n }\n return native;\n}\n/** The native drawing in its frame: what a sibling plugin's renderer keeps where the layer draws it. */\nfunction framedNativeOf(id: string): Component {\n let native = framedNatives.get(id);\n if (!native) {\n native = markRaw(() => {\n const item = itemsById.value.get(id);\n return item\n ? h(AnnotationFrame, { item, page: page.value }, () => h(nativeOf(id)))\n : null;\n });\n framedNatives.set(id, native);\n }\n return native;\n}\n// Forget the drawings of annotations that are gone.\nwatch(itemsById, (shown) => {\n for (const id of natives.keys()) if (!shown.has(id)) natives.delete(id);\n for (const id of framedNatives.keys()) if (!shown.has(id)) framedNatives.delete(id);\n});\n\n/** A renderer's component, never a reactive proxy of it (a list kept in a `ref`). */\nconst componentOf = (component: Component): Component => toRaw(component);\n</script>\n\n<template>\n <div :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\">\n <template v-for=\"{ item, annotation: record, drawing } in drawn\" :key=\"item.id\">\n <component\n :is=\"componentOf(drawing.entry.component)\"\n v-if=\"drawing.kind === 'owned' && record\"\n :annotation=\"record\"\n :item=\"item\"\n :page=\"page\"\n :native=\"framedNativeOf(item.id)\"\n :hovered=\"item.hovered ?? false\"\n :selected=\"item.selected\"\n :interactive=\"true\"\n />\n <AnnotationFrame\n v-else-if=\"drawing.kind === 'look' && record\"\n :item=\"item\"\n :page=\"page\"\n :interactive=\"drawing.interactive\"\n :inert=\"drawing.inert\"\n >\n <AnnotationLook\n :component=\"componentOf(drawing.entry.component)\"\n :scaled=\"drawing.entry.scale !== false\"\n :annotation=\"record\"\n :item=\"item\"\n :page=\"page\"\n :native=\"nativeOf(item.id)\"\n :appearance=\"\n urls && bakedAppearanceOf(urls, item.id, item.annotation?.appearanceState ?? null)\n \"\n :interactive=\"drawing.interactive\"\n />\n </AnnotationFrame>\n <!-- Inert when an engaged behavior has no renderer of yours: its plugin\n owns the input (a link's anchor takes the click), and the annotation\n keeps its own look. -->\n <AnnotationFrame\n v-else\n :item=\"item\"\n :page=\"page\"\n :inert=\"drawing.kind === 'native' && drawing.inert\"\n >\n <NativeDrawing :item=\"item\" :urls=\"urls\" />\n </AnnotationFrame>\n </template>\n <FreeTextBox v-for=\"text in ownTexts\" :key=\"text.id\" :item=\"text\" :page=\"page\" />\n <StampGhost :page=\"page\" />\n <AnnotationChrome :page=\"page\">\n <template v-if=\"slots.handle\" #handle=\"handle\">\n <slot name=\"handle\" v-bind=\"handle\" />\n </template>\n <template v-if=\"slots['rotation-handle']\" #rotation-handle=\"handle\">\n <slot name=\"rotation-handle\" v-bind=\"handle\" />\n </template>\n </AnnotationChrome>\n </div>\n</template>\n","<!--\n <AnnotationMenu>: your own menu next to the selection (one anchor, also for a\n selection over several pages), clear of the rotation handle. It hides while\n the selection is dragged, resized or turned. What's in it is yours: build it\n from `useAnnotation()` and `useAnnotationState()`. Put it in the Stage's\n #overlay slot; it works inside a <PageView> too (the surface provides the\n projection).\n-->\n<script setup lang=\"ts\">\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport { sameSelectionAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useProjectorBinding } from '../anchored/projector';\nimport { useOptionalSelector } from '../runtime/capabilities';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the selection box and the menu. Default 15. */\n gap?: number;\n /** Where the menu sits around the selection. Default `'top'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 15, placement: 'top' },\n);\n\ndefineSlots<{\n /** The menu: compose it from `useAnnotation()` and `useAnnotationState()`. */\n default?(): unknown;\n}>();\n\n// Reading the binding makes the anchor follow projection changes in the same\n// update as the pages: the rotation handle's offset is screen-constant, so its\n// place on the page depends on the page's live view scale.\nconst binding = useProjectorBinding();\nconst anchor = useOptionalSelector(\n AnnotationHostToken,\n (host) => {\n const selection = host.selection.getAnchor();\n if (!selection) return null;\n const view = binding.value.projector.viewEnv(selection.page);\n return view ? host.getSelectionAnchorIn(view) : selection;\n },\n null,\n sameSelectionAnchor,\n);\n</script>\n\n<template>\n <Anchored\n v-if=\"anchor\"\n :anchor=\"{\n page: anchor.page,\n bounds: anchor.bounds,\n ...(anchor.rotationHandle ? { avoid: [anchor.rotationHandle] } : {}),\n }\"\n :placement=\"placement\"\n :gap=\"gap\"\n >\n <slot />\n </Anchored>\n</template>\n","<!--\n <AnnotationDraftMenu>: floats over a shape being drawn with several clicks\n (a polygon, a polyline). Its default slot gets the `draft`: its `subtype`,\n `pointCount`, `minPoints`, `canFinish` and where it is. The verbs are\n capability calls: `useAnnotation().draft.finish()` and `.draft.cancel()`.\n-->\n<script setup lang=\"ts\">\nimport type { CreationDraftAnchor } from '@embedpdf/core-annotation';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport { sameCreationDraftAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useOptionalSelector } from '../runtime/capabilities';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the shape and the menu. Default 8. */\n gap?: number;\n /** Where the menu sits around the shape. Default `'top'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 8, placement: 'top' },\n);\n\ndefineSlots<{\n /** The menu, with the shape being drawn. */\n default?(props: { draft: CreationDraftAnchor }): unknown;\n}>();\n\n// The plugin reads a new anchor object every time: compared by value, so the\n// menu moves only when the shape did.\nconst draft = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.draft.get(),\n null,\n sameCreationDraftAnchor,\n);\n</script>\n\n<template>\n <Anchored v-if=\"draft\" :anchor=\"draft\" :placement=\"placement\" :gap=\"gap\">\n <slot :draft=\"draft\" />\n </Anchored>\n</template>\n","<!--\n <AnnotationRotationBadge>: follows the pointer while a selection is being\n turned, upright however the page is shown: it floats over the page like the\n menus, not in it. Shows nothing when no turn is in progress. Without a slot\n it shows the angle in the `chrome.readout` colors, when\n `chrome.readout.enabled`; its default slot gets the `rotation` (`angle`,\n degrees clockwise, as the commit will apply it) to draw it your way.\n-->\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { CSSProperties } from 'vue';\nimport type { RotationAnchor } from '@embedpdf/core-annotation';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport { paint, paintDefault, sameRotationAnchor } from '@embedpdf/web';\nimport type { AnchoredPlacement } from '@embedpdf/web';\nimport Anchored from '../anchored/Anchored.vue';\nimport { useOptionalSelector } from '../runtime/capabilities';\nimport { useAnnotationSettings } from './state';\n\nwithDefaults(\n defineProps<{\n /** Gap in screen px between the pointer and the badge. Default 16. */\n gap?: number;\n /** Where the badge sits around the pointer. Default `'right'`. */\n placement?: AnchoredPlacement;\n }>(),\n { gap: 16, placement: 'right' },\n);\n\nconst slots = defineSlots<{\n /** The badge, drawn your way, with the turn in progress. */\n default?(props: { rotation: RotationAnchor }): unknown;\n}>();\n\nconst rotation = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.selection.getRotationAnchor(),\n null,\n sameRotationAnchor,\n);\nconst readout = useAnnotationSettings((settings) => settings.chrome.readout);\n\nconst badge = computed(\n (): CSSProperties => ({\n pointerEvents: 'none',\n whiteSpace: 'nowrap',\n borderRadius: '4px',\n padding: '2px 6px',\n fontFamily: paintDefault('font-mono'),\n fontSize: '12px',\n background: paint('readout-background', readout.value.background),\n color: paint('readout-color', readout.value.color),\n }),\n);\n</script>\n\n<template>\n <Anchored\n v-if=\"rotation && (slots.default || readout.enabled)\"\n :anchor=\"{ page: rotation.page, bounds: { ...rotation.at, width: 0, height: 0 } }\"\n :placement=\"placement\"\n :gap=\"gap\"\n >\n <slot v-if=\"slots.default\" :rotation=\"rotation\" />\n <div v-else :style=\"badge\">{{ rotation.angle }}°</div>\n </Anchored>\n</template>\n","/**\n * The annotation composables: `useAnnotation()` (the API) and\n * `useAnnotationEvent()`; the reads a component follows on their own, each a\n * ref (`useAnnotationList()`, `useAnnotationDefaults()`,\n * `useAnnotationProperties()`, `useAnnotationAnchor()`); the comments\n * (`useComments()`, `useCommentThreads()`, `useCommentThread()`); and\n * `useFilePickerProvider()`, the file dialog behind click-then-pick tools.\n * The state and the settings are in `./state`.\n */\nimport { computed, markRaw, toValue, unref, watch } from 'vue';\nimport type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { annotationKey, shallowEqual } from '@embedpdf/core';\nimport type { EventHook, PageLayout } from '@embedpdf/core';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation';\nimport type {\n Annotation,\n AnnotationAnchor,\n AnnotationCapability,\n AnnotationFilter,\n AnnotationProperties,\n AnnotationRef,\n CommentThread,\n CommentsApi,\n FilePickerProvider,\n ToolDefaults,\n} from '@embedpdf/plugin-annotation';\n// The anchor of one annotation is a host read: it projects a drag in progress.\nimport { AnnotationToken as AnnotationHostToken } from '@embedpdf/plugin-annotation/contract/host';\nimport {\n enrichCommentThreads,\n installFilePickerProvider,\n pickRequestedFile,\n sameAnnotationAnchor,\n} from '@embedpdf/web';\nimport { devWarn } from '../dev';\nimport {\n useCapability,\n useCapabilityEvent,\n useOptionalCapability,\n useOptionalSelector,\n} from '../runtime/capabilities';\nimport { useDocumentId, useKernelValue } from '../runtime/kernel';\nimport type { CommentThreadView } from './types';\n\n/**\n * The annotation API (`create`, `update`, `selection`, `tools`, `text`,\n * `comments`, …) for your chrome. The object never changes, so it's safe to\n * keep in a closure; keep it whole (`annotation.selection.delete()`), since a\n * member taken out of it once stays the one of that moment.\n */\nexport function useAnnotation(): AnnotationCapability {\n return useCapability(AnnotationToken);\n}\n\n/** Subscribe to one annotation event while the component lives: `useAnnotationEvent((annotation) => annotation.onCreated, handler)`. */\nexport function useAnnotationEvent<Event>(\n select: (annotation: AnnotationCapability) => EventHook<Event>,\n handler: (event: Event) => void,\n): void {\n useCapabilityEvent(AnnotationToken, select, handler);\n}\n\nconst NO_ANNOTATIONS: readonly Annotation[] = Object.freeze([]);\n\n/**\n * The annotations matching `filter` (some pages, one kind), in drawing order,\n * as the user sees them, as a ref: the same array while they stay the same.\n * A getter follows a filter that changes. Empty without a document.\n */\nexport function useAnnotationList(\n filter?: MaybeRefOrGetter<AnnotationFilter | undefined>,\n): Readonly<Ref<readonly Annotation[]>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.list(toValue(filter)),\n NO_ANNOTATIONS,\n shallowEqual,\n );\n}\n\nconst NO_DEFAULTS: ToolDefaults = Object.freeze({});\n\n/**\n * A tool's defaults, as a ref: the fields its next annotation starts with,\n * over the engine's. It follows them, so a color picker always shows the\n * current color. Empty without a document.\n */\nexport function useAnnotationDefaults(toolId: MaybeRefOrGetter<string>): Readonly<Ref<ToolDefaults>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.tools.getDefaults(toValue(toolId)),\n NO_DEFAULTS,\n );\n}\n\nconst NO_PROPERTIES: AnnotationProperties = Object.freeze({\n properties: [],\n values: {},\n mixed: [],\n});\n\n/**\n * What a style panel shows, as a ref: the selection's properties\n * (`selection.getProperties()`), or, given a tool id, the tool's\n * (`tools.getProperties(id)`). It follows them. Empty without a document.\n */\nexport function useAnnotationProperties(\n toolId?: MaybeRefOrGetter<string | undefined>,\n): Readonly<Ref<AnnotationProperties>> {\n return useOptionalSelector(\n AnnotationToken,\n (annotation) => {\n const tool = toValue(toolId);\n return tool === undefined\n ? annotation.selection.getProperties()\n : annotation.tools.getProperties(tool);\n },\n NO_PROPERTIES,\n );\n}\n\n/**\n * An anchor for `<Anchored>` that keeps a card or a badge attached to one\n * annotation, as a ref: its page and the box around what it shows, following\n * a move as it happens. `null` for `null`, or an annotation that isn't here.\n * It changes when the annotation moves, not while people scroll or zoom: a\n * note that keeps its size on screen hands `<Anchored>` its `boundsIn`. A\n * getter follows a ref that changes (`() => hovered.value?.ref ?? null`).\n */\nexport function useAnnotationAnchor(\n ref: MaybeRefOrGetter<AnnotationRef | null>,\n): Readonly<Ref<AnnotationAnchor | null>> {\n return useOptionalSelector(\n AnnotationHostToken,\n (annotation) => {\n const wanted = toValue(ref);\n return wanted ? annotation.getAnnotationAnchor(wanted) : null;\n },\n null,\n sameAnnotationAnchor,\n );\n}\n\n// ── comments (the conversation plane) ────────────────────────────────────────\n\n/**\n * The comments API: the `comments` part of `useAnnotation()`, for the\n * document in scope. Like `useAnnotation()`, the object never changes and\n * always reaches the current document. Pair it with {@link useCommentThreads}\n * for the threads to show.\n */\nexport function useComments(): CommentsApi {\n const annotation = useAnnotation();\n // Read `comments` at each use, never once here: the document in scope may change.\n const target = markRaw({});\n return new Proxy(target, {\n get: (_target, key) =>\n typeof key === 'string' && key.startsWith('__v_')\n ? Reflect.get(target, key)\n : Reflect.get(annotation.comments, key),\n has: (_target, key) => Reflect.has(annotation.comments, key),\n }) as CommentsApi;\n}\n\nconst NO_PAGES: readonly PageLayout[] = Object.freeze([]);\nconst NO_THREADS: readonly CommentThread[] = Object.freeze([]);\n\n/**\n * Every comment thread in the document as a ref, display-ordered (page\n * position, then top of page, then creation date) and with where its page is\n * shown (`pageIndex`, `pageLabel`). It follows annotation writes (your own,\n * remote ones, loading) and page moves and deletes; the same array between\n * changes.\n */\nexport function useCommentThreads(): Readonly<Ref<readonly CommentThreadView[]>> {\n const documentId = useDocumentId();\n const threads = useOptionalSelector(\n AnnotationToken,\n (annotation) => annotation.comments.listThreads(),\n NO_THREADS,\n );\n const pages = useKernelValue((kernel) =>\n documentId.value ? kernel.documents.listPages(documentId.value) : NO_PAGES,\n );\n return computed(() => enrichCommentThreads(threads.value, pages.value));\n}\n\n/**\n * The thread holding any of its annotations (the root, a reply, a grouped\n * part, a review state), as a ref, or null. A getter follows a ref that changes.\n */\nexport function useCommentThread(\n ref: MaybeRefOrGetter<AnnotationRef | null>,\n): Readonly<Ref<CommentThreadView | null>> {\n const views = useCommentThreads();\n const annotation = useOptionalCapability(AnnotationToken);\n return computed(() => {\n const wanted = toValue(ref);\n const api = annotation.value;\n if (wanted == null || !api) return null;\n const thread = api.comments.getThread(wanted);\n if (!thread) return null;\n const root = annotationKey(thread.root.ref);\n return views.value.find((view) => annotationKey(view.root.ref) === root) ?? null;\n });\n}\n\n// ── the file picker ──────────────────────────────────────────────────────────\n\n/**\n * The default file-picker provider: the browser's file dialog (from\n * `@embedpdf/web`), honouring the tool's `accept` filter. The adapter fulfils\n * the plugin's DOM-free port; the dialog never lives in the plugin.\n */\nexport const filePickerProvider: FilePickerProvider = pickRequestedFile;\n\n/**\n * Install the file-picker provider for the document in scope while the\n * component lives: the one port behind every click-then-pick tool (a stamp\n * whose source is `'prompt'`, the file attachment tool). Call it once, at a\n * document-wide spot (not in a page layer). Without an argument it installs\n * {@link filePickerProvider}, so those tools work out of the box; pass your\n * own (an asset library, a cloud drive: switch on `toolId` or `subtype`), or\n * `null` to make them do nothing. A ref follows a provider that changes.\n */\nexport function useFilePickerProvider(\n provider: MaybeRef<FilePickerProvider | null> = filePickerProvider,\n): void {\n const annotation = useOptionalCapability(AnnotationToken);\n // Not a getter: the provider is itself a function.\n watch(\n [annotation, () => unref(provider)],\n ([capability, current], _previous, onCleanup) => {\n if (!capability) return;\n // One port per document: a second caller silently replaces the first.\n onCleanup(\n installFilePickerProvider(capability, current, () =>\n devWarn(\n 'file-picker-provider-twice',\n 'useFilePickerProvider() is called from two mounted components for the same ' +\n 'document — the later one wins. Call it once, at a document-scoped spot.',\n ),\n ),\n );\n },\n { immediate: true },\n );\n}\n"],"names":["stateComposable","annotationState","settingsComposable","AnnotationToken","_useSlots","useOptionalSelector","AnnotationHostToken","host","shallowEqual","useViewerSettings","computed","annotationChromePaint","chromeInPixels","_openBlock","_createElementBlock","_hoisted_1","_Fragment","_renderList","_unref","_normalizeStyle","_createElementVNode","_renderSlot","frameInPixels","shallowRef","useOptionalCapability","createTextBoxEditorFollower","watch","toValue","onScopeDispose","provide","page","usePage","inject","textBoxEditorScaleOf","ownTextBoxOf","lookFrameOf","_createBlock","_resolveDynamicComponent","freeTextBoxOf","sceneViewBox","svgShapesOf","scene","MITER_LIMIT","ghostOpacity","_createVNode","SvgShapes","pictureOrPainting","shownAppearance","hasLiveDrawing","rasterInFrame","AnnotationScene","previewBucket","ref","loadObjectUrl","rectInPixels","usePaintsPagePart","InteractionToken","devWarn","registerRendererBehaviors","createShownUrls","onUnmounted","RenderToken","loadAppearanceUrls","annotationKey","editingTextKeyOf","annotationDrawingOf","layerTextBoxesOf","markRaw","h","NativeDrawing","AnnotationFrame","shown","toRaw","AnnotationLook","bakedAppearanceOf","FreeTextBox","StampGhost","AnnotationChrome","_createSlots","_withCtx","useProjectorBinding","sameSelectionAnchor","Anchored","sameCreationDraftAnchor","sameRotationAnchor","paintDefault","paint","useCapability","useCapabilityEvent","sameAnnotationAnchor","useDocumentId","useKernelValue","enrichCommentThreads","pickRequestedFile","unref","installFilePickerProvider"],"mappings":";;;;;;;;;;;;;;;;;;;AAgBO,MAAM,qBAAqBA,MAAAA,gBAAgBC,SAAAA,eAAe;AAO1D,MAAM,wBAAwBC,MAAAA,mBAAmBC,SAAAA,eAAe;;;;;;;;;;;;;;;;;;;;;;;ACAvE,UAAM,QAAQ;AAEd,UAAM,QAAQC,IAAAA,SAAA;AAOd,UAAM,WAAkC,OAAO,OAAO,EAAE;AAKxD,UAAM,QAAQC,aAAAA;AAAAA,MACZC,KAAAA;AAAAA,MACA,CAACC,UAAS;AACR,cAAM,EAAE,WAAW,IAAA,IAAQ,MAAM;AACjC,eAAOA,MAAK,gBAAgB,KAAK,UAAU,WAAW,UAAU,UAAU,UAAU,IAAI;AAAA,MAC1F;AAAA,MACA;AAAA,MACAC,KAAAA;AAAAA,IAAA;AAEF,UAAM,SAAS,sBAAsB,CAAC,aAAa,SAAS,MAAM;AAClE,UAAM,SAASC,UAAAA,kBAAkB,CAAC,aAAa,SAAS,MAAM;AAM9D,UAAM,UAAUC,IAAAA,SAAS,MAAM;AAC7B,YAAM,QAAQC,IAAAA,sBAAsB,OAAO,OAAO,OAAO,KAAK;AAC9D,YAAM,QAAQ,CAAC,UAAiC,EAAE,GAAG,KAAA;AACrD,aAAO;AAAA,QACL,SAAS,MAAM,MAAM,OAAO;AAAA,QAC5B,QAAQ,MAAM,MAAM,MAAM;AAAA,QAC1B,gBAAgB,MAAM,MAAM,cAAc;AAAA,QAC1C,eAAe,MAAM,EAAE,QAAQ,MAAM,eAAe,QAAQ;AAAA,QAC5D,OAAO,MAAM,MAAM,KAAK;AAAA,QACxB,eAAe,MAAM,MAAM,aAAa;AAAA,QACxC,SAAS,MAAM,MAAM,OAAO;AAAA,MAAA;AAAA,IAEhC,CAAC;AACD,UAAM,SAASD,aAAS,MAAME,mBAAe,MAAM,OAAO,MAAM,KAAK,SAAS,CAAC;AAG/E,UAAM,aAAaF,IAAAA;AAAAA,MAAS,MAC1B,OAAO,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,iBAAiB;AAAA,IAAA;;;SAKrFG,IAAAA,aAAAC,IAAAA,mBA8FM,OA9FNC,cA8FM;AAAA,WA7FJF,IAAAA,UAAA,IAAA,GAAAC,IAAAA,mBA4FWE,cAAA,MAAAC,IAAAA,WA5FuB,OAAA,OAAM,CAAtB,MAAM,UAAK;gFAAmB,SAAK;AAAA,cACnC,KAAK,SAAI,6BAAzBH,IAAAA,mBAsBWE,cAAA,EAAA,KAAA,KAAA;AAAA,gBArBQ,CAAA,MAAM,2BAAvBF,IAAAA,mBAoBWE,cAAA,EAAA,KAAA,KAAA;AAAA,kBAlBDE,UAAA,MAAA,EAAO,QAAQ,UAAK,6BAD5BJ,IAAAA,mBAOE,UAAA;AAAA;oBALC,IAAI,KAAK,GAAG;AAAA,oBACZ,IAAI,KAAK,GAAG;AAAA,oBACZ,GAAGI,IAAAA,MAAA,MAAA,EAAO,QAAQ,OAAI;AAAA,oBACvB,gBAAa;AAAA,oBACZ,OAAKC,IAAAA,eAAE,QAAA,MAAQ,MAAM;AAAA,kBAAA,8CAGxBL,IAAAA,mBASE,QAAA;AAAA;oBAPC,GAAG,KAAK,GAAG,IAAII,IAAAA,MAAA,MAAA,EAAO,QAAQ,OAAI;AAAA,oBAClC,GAAG,KAAK,GAAG,IAAIA,IAAAA,MAAA,MAAA,EAAO,QAAQ,OAAI;AAAA,oBAClC,OAAOA,IAAAA,MAAA,MAAA,EAAO,QAAQ;AAAA,oBACtB,QAAQA,IAAAA,MAAA,MAAA,EAAO,QAAQ;AAAA,oBACxB,gBAAa;AAAA,oBACZ,OAAKC,IAAAA,eAAE,QAAA,MAAQ,MAAM;AAAA,oBACrB,WAAW,KAAK,qBAAqB,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM;AAAA,kBAAA;;wBAK5E,KAAK,SAAI,4BADtBL,IAAAA,mBAQE,QAAA;AAAA;gBANC,IAAI,KAAK,KAAK;AAAA,gBACd,IAAI,KAAK,KAAK;AAAA,gBACd,IAAI,KAAK,GAAG;AAAA,gBACZ,IAAI,KAAK,GAAG;AAAA,gBACb,mBAAgB;AAAA,gBACf,OAAKK,IAAAA,eAAE,QAAA,MAAQ,KAAK;AAAA,cAAA,4BAGV,KAAK,SAAI,qCADtBL,IAAAA,mBAKE,WAAA;AAAA;gBAHC,QAAQ,KAAK;AAAA,gBACd,MAAK;AAAA,gBACJ,OAAKK,IAAAA,eAAE,QAAA,MAAQ,OAAO;AAAA,cAAA,4BAEX,KAAK,SAAI,sCAAvBL,uBAWI,KAAA,YAAA;AAAA,iBAVFD,IAAAA,UAAA,IAAA,GAAAC,IAAAA,mBASEE,mCAR4B,KAAK,OAAK,CAA9B,MAAM,cAAS;0CADzBF,IAAAA,mBASE,QAAA;AAAA,oBAPC,KAAK;AAAA,oBACL,IAAI,KAAK,KAAK;AAAA,oBACd,IAAI,KAAK,KAAK;AAAA,oBACd,IAAI,KAAK,GAAG;AAAA,oBACZ,IAAI,KAAK,GAAG;AAAA,oBACZ,SAAS,KAAK;AAAA,oBACd,OAAKK,IAAAA,eAAE,QAAA,MAAQ,aAAa;AAAA,kBAAA;;oBAGZ,KAAK,SAAI,sCAA9BL,IAAAA,mBAmBWE,cAAA,EAAA,KAAA,KAAA;AAAA,iBAlBC,MAAK,iBAAA,sBAAfF,IAAAA,mBAiBI,KAAA,YAAA;AAAA,kBAfMI,IAAAA,MAAA,MAAA,EAAO,eAAe,0BAD9BJ,IAAAA,mBAQE,QAAA;AAAA;oBANC,IAAI,KAAK,KAAK;AAAA,oBACd,IAAI,KAAK,KAAK;AAAA,oBACd,IAAI,KAAK,GAAG;AAAA,oBACZ,IAAI,KAAK,GAAG;AAAA,oBACb,gBAAa;AAAA,oBACZ,OAAKK,IAAAA,eAAE,QAAA,MAAQ,aAAa;AAAA,kBAAA;kBAE/BC,IAAAA,mBAME,UAAA;AAAA,oBALC,IAAI,KAAK,GAAG;AAAA,oBACZ,IAAI,KAAK,GAAG;AAAA,oBACZ,GAAGF,IAAAA,MAAA,MAAA,EAAO,eAAe,OAAI;AAAA,oBAC9B,gBAAa;AAAA,oBACZ,OAAKC,IAAAA,eAAE,QAAA,MAAQ,cAAc;AAAA,kBAAA;;wBAOvB,KAAK,SAAI,8BADtBL,IAAAA,mBASE,QAAA;AAAA;gBAPC,GAAG,KAAK,IAAI;AAAA,gBACZ,GAAG,KAAK,IAAI;AAAA,gBACZ,OAAO,KAAK,IAAI;AAAA,gBAChB,QAAQ,KAAK,IAAI;AAAA,gBAClB,gBAAa;AAAA,gBACb,oBAAiB;AAAA,gBAChB,OAAKK,IAAAA,eAAE,QAAA,MAAQ,OAAO;AAAA,cAAA,6BAGZ,KAAK,SAAI,8BADtBL,IAAAA,mBAQE,QAAA;AAAA;gBANC,GAAG,KAAK,IAAI;AAAA,gBACZ,GAAG,KAAK,IAAI;AAAA,gBACZ,OAAO,KAAK,IAAI;AAAA,gBAChB,QAAQ,KAAK,IAAI;AAAA,gBAClB,MAAK;AAAA,gBACJ,OAAKK,IAAAA,eAAE,QAAA,MAAQ,OAAO;AAAA,cAAA;;;;QAKrB,WAAA,UAAe,MAAM,UAAU,MAAK,iBAAA,MAD5CN,cAAA,GAAAC,uBAwBM,OAxBN,aAwBM;AAAA,WApBJD,IAAAA,UAAA,IAAA,GAAAC,IAAAA,mBAmBWE,cAAA,MAAAC,IAAAA,WAnBuB,OAAA,OAAM,CAAtB,MAAM,UAAK;gFAAmB,SAAK;AAAA,cAE3C,KAAK,SAAI,YAAiB,MAAM,SADxCI,eAQE,KAAA,QAAA,UAAA;AAAA,gBALC,IAAI,KAAK;AAAA,gBACT,MAAMH,IAAAA,MAAA,MAAA,EAAO,QAAQ;AAAA,gBACrB,UAAU,KAAK;AAAA,gBACf,MAAM,KAAK;AAAA,gBACX,QAAQ,KAAK;AAAA,cAAA,wBAGH,KAAK,SAAI,qBAA0B,MAAK,iBAAA,IADrDG,IAAAA,WAQE,KAAA,QAAA,mBAAA;AAAA,gBALC,IAAI,KAAK;AAAA,gBACT,MAAM,KAAK;AAAA,gBACX,MAAMH,IAAAA,MAAA,MAAA,EAAO,eAAe;AAAA,gBAC5B,UAAU;AAAA,gBACV,QAAQ;AAAA,cAAA;;;;;;;;;;;;;;;;;;ACnLjB,UAAM,QAAQ;AAcd,UAAM,QAAQR,IAAAA,SAAS,MAAqB;AAC1C,YAAM,MAAMY,IAAAA,cAAc,MAAM,KAAK,OAAO,MAAM,KAAK,SAAS;AAChE,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,GAAG,IAAI,IAAI;AAAA,QACjB,KAAK,GAAG,IAAI,GAAG;AAAA,QACf,OAAO,GAAG,IAAI,KAAK;AAAA,QACnB,QAAQ,GAAG,IAAI,MAAM;AAAA,QACrB,WAAW,IAAI;AAAA,QACf,iBAAiB;AAAA;AAAA;AAAA,QAGjB,cAAc,MAAM,KAAK;AAAA,QACzB,eAAe,MAAM,cAAc,SAAS;AAAA,MAAA;AAAA,IAEhD,CAAC;;8BAICR,IAAAA,mBAEM,OAAA;AAAA,QAFA,OAAO,QAAA,SAAS;AAAA,QAAY,0BAAO,MAAA,KAAK;AAAA,MAAA;QAC5CO,eAAQ,KAAA,QAAA,SAAA;AAAA,MAAA;;;;AChBL,SAAS,iBACd,MACA,OACyB;AACzB,QAAM,UAAUE,IAAAA,WAA+B,IAAI;AACnD,QAAM,aAAaC,aAAAA,sBAAsBlB,oBAAmB;AAC5D,QAAM,WAAWmB,IAAAA,4BAAA;AAIjBC,MAAAA;AAAAA,IACE,CAAC,YAAY,SAAS,MAAMC,IAAAA,QAAQ,IAAI,GAAG,MAAMA,IAAAA,QAAQ,KAAK,CAAC;AAAA,IAC/D,CAAC,CAAC,YAAY,QAAQ,SAAS,cAAc,MAC3C,SAAS,OAAO,QAAQ,YAAY,SAAS,cAAc;AAAA,IAC7D,EAAE,WAAW,MAAM,OAAO,OAAA;AAAA,EAAO;AAEnCC,qBAAe,MAAM,SAAS,QAAQ;AACtC,SAAO;AACT;AAGA,MAAM,eAAoD,OAAO,gCAAgC;AACjG,MAAM,WAAWlB,IAAAA,SAAS,MAAM,CAAC;AAG1B,SAAS,iBAAiB,OAAoC;AACnEmB,MAAAA,QAAQ,cAAc,KAAK;AAC7B;AAEA,MAAM,WAA0B,OAAO,OAAO,EAAE;AAkBzC,SAAS,kBAAkB,YAA0D;AAC1F,QAAMC,SAAOC,KAAAA,QAAA;AAEb,QAAM,OAAO1B,aAAAA;AAAAA,IACXC,KAAAA;AAAAA,IACA,CAACC,UAAS;AACR,YAAM,EAAE,cAAcuB,OAAK;AAC3B,aAAOvB,MAAK,YAAYoB,IAAAA,QAAQ,UAAU,EAAE,KAAK;AAAA,QAC/C,MAAM,UAAU;AAAA,QAChB,UAAU,UAAU;AAAA,MAAA,CACrB;AAAA,IACH;AAAA,IACA;AAAA,EAAA;AAIF,QAAM,YAAYK,IAAAA,OAAO,cAAc,QAAQ;AAC/C,QAAM,QAAQtB,IAAAA;AAAAA,IAAS,MACrBuB,IAAAA,qBAAqB,KAAK,OAAOH,OAAK,MAAM,WAAW,UAAU,KAAK;AAAA,EAAA;AAExE,QAAM,MAAMpB,IAAAA,SAAS,MAAO,KAAK,QAAQwB,IAAAA,aAAa,KAAK,OAAO,MAAM,KAAK,IAAI,IAAK;AACtF,QAAM,UAAU,iBAAiB,MAAM,MAAA;;AAAM,sBAAI,UAAJ,mBAAW,UAAS,MAAM;AAAA,GAAK;AAC5E,QAAM,QAAQxB,IAAAA,SAAS,MAAA;;AAAqB,sBAAI,UAAJ,mBAAW,UAAS;AAAA,GAAQ;AACxE,SAAO;AAAA,IACL,KAAK,CAAC,WAAqD;AACzD,cAAQ,QAAQ,kBAAkB,cAAc,SAAS;AAAA,IAC3D;AAAA,IACA;AAAA,IACA,SAASA,IAAAA,SAAS,MAAA;;AAAM,yBAAK,UAAL,mBAAY,YAAW;AAAA,KAAK;AAAA,EAAA;AAExD;;;;;;;;;;;;;;AC5FA,UAAM,QAAQ;AAad,UAAM,SAASA,IAAAA,SAAS,MAAMY,IAAAA,cAAc,MAAM,KAAK,OAAO,MAAM,KAAK,SAAS,CAAC;AACnF,UAAM,QAAQZ,IAAAA,SAAS,MAAMyB,IAAAA,YAAY,OAAO,OAAO,MAAM,MAAM,CAAC;AAEpE,qBAAiBzB,IAAAA,SAAS,MAAO,MAAM,SAAS,OAAO,MAAM,QAAQ,CAAE,CAAC;AAExE,UAAM,YAAYA,IAAAA;AAAAA,MAChB,OAAsB;AAAA,QACpB,UAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,OAAO,GAAG,OAAO,MAAM,OAAO,KAAK;AAAA,QACnC,QAAQ,GAAG,OAAO,MAAM,OAAO,MAAM;AAAA,QACrC,WAAW,SAAS,OAAO,MAAM,KAAK;AAAA,QACtC,iBAAiB;AAAA,MAAA;AAAA,IACnB;;aAKW,QAAA,2BAAXI,IAAAA,mBAWM,OAAA;AAAA;QAXc,0BAAO,UAAA,KAAS;AAAA,MAAA;SAClCD,IAAAA,aAAAuB,IAAAA,YASEC,IAAAA,wBARK,QAAA,SAAS,GAAA;AAAA,UACb,YAAY,QAAA;AAAA,UACZ,OAAO,MAAA;AAAA,UACP,QAAQ,QAAA;AAAA,UACR,YAAY,QAAA;AAAA,UACZ,SAAS,QAAA,KAAK,WAAO;AAAA,UACrB,UAAU,QAAA,KAAK;AAAA,UACf,aAAa,QAAA;AAAA,QAAA;gBAGlBxB,cAAA,GAAAuB,IAAAA,YAUEC,4BATK,QAAA,SAAS,GAAA;AAAA;QAEb,YAAY,QAAA;AAAA,QACZ,OAAO,MAAA;AAAA,QACP,QAAQ,QAAA;AAAA,QACR,YAAY,QAAA;AAAA,QACZ,SAAS,QAAA,KAAK,WAAO;AAAA,QACrB,UAAU,QAAA,KAAK;AAAA,QACf,aAAa,QAAA;AAAA,MAAA;;;;;;;;;;;ACnDlB,UAAM,QAAQ;AAEd,UAAM,SAAS,sBAAsB,CAAC,aAAa,SAAS,MAAM;AAClE,UAAM,SAAS5B,UAAAA,kBAAkB,CAAC,aAAa,SAAS,MAAM;AAC9D,UAAM,UAAUC,aAAS,MAAMC,0BAAsB,OAAO,OAAO,OAAO,KAAK,EAAE,WAAW;AAG5F,UAAM,MAAMD,IAAAA,SAAS,MAAM4B,IAAAA,cAAc,MAAM,MAAM,MAAM,KAAK,WAAW,QAAQ,KAAK,CAAC;AACzF,UAAM,UAAU;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,MAAM,IAAI,MAAM;AAAA,IAAA;;8BAKhBxB,IAAAA,mBAAwC,OAAA;AAAA,iBAA/B;AAAA,QAAJ,KAAI;AAAA,QAAW,OAAKK,IAAAA,eAAE,IAAA,MAAI,KAAK;AAAA,MAAA;;;;;;;;;;;ACjBtC,UAAM,QAAQ;AAGd,UAAM,UAAUT,IAAAA,SAAS,MAAM6B,IAAAA,aAAa,MAAM,KAAK,GAAG,CAAC;AAC3D,UAAM,SAAS7B,IAAAA,SAAS,MAAM8B,IAAAA,YAAYC,eAAAA,MAAM,MAAM,IAAI,GAAG,EAAE,YAAYC,eAAAA,YAAA,CAAa,CAAC;AACzF,UAAM,QAAQhC,IAAAA;AAAAA,MACZ,OAAsB;AAAA,QACpB,UAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,eAAe;AAAA;AAAA,QAEf,GAAI,MAAM,KAAK,WAAW,UACtB,EAAE,SAASiC,IAAAA,aAAa,MAAM,KAAK,gBAAgB,GAAG,EAAA,IACtD,CAAA;AAAA,MAAC;AAAA,IACP;;aAKW,QAAA,0BAAX7B,IAAAA,mBAEM,OAAA;AAAA;QAFe,SAAS,QAAA;AAAA,QAAU,0BAAO,MAAA,KAAK;AAAA,MAAA;QAClD8B,gBAA8BC,8CAAAA,WAAA,EAAlB,QAAQ,OAAA,MAAA,GAAM,MAAA,GAAA,CAAA,QAAA,CAAA;AAAA,MAAA;;;;;;;;;;;;ACpB9B,UAAM,QAAQ;AAMd,UAAM,QAAQnC,IAAAA,SAAS,MAAM;;AAC3B,YAAM,EAAE,MAAM,KAAA,IAAS;AACvB,aAAOoC,sBAAkB;AAAA,QACvB,SAAS,KAAK,WAAW;AAAA,QACzB,SAAS,QAAQC,IAAAA,gBAAgB,MAAM,KAAK,MAAI,UAAK,eAAL,mBAAiB,oBAAmB,IAAI;AAAA,QACxF,SAAS,KAAK,kBAAkB;AAAA,QAChC,QAAQ,SAAS;AAAA,QACjB,OAAO,MAAOC,eAAAA,eAAe,IAAI,IAAI,OAAO;AAAA,MAAA,CAC7C;AAAA,IACH,CAAC;AAGD,UAAM,QAAQtC,IAAAA,SAAS,MAAoD;AACzE,YAAM,EAAE,SAAS;AACjB,YAAM,OAAO,MAAM;AACnB,WAAI,6BAAM,UAAS,aAAa,CAAC,KAAK,OAAQ,QAAO;AACrD,YAAM,MAAMuC,IAAAA,cAAc,KAAK,QAAQ,KAAK,KAAK;AACjD,aAAO;AAAA,QACL,KAAK,KAAK,QAAQ;AAAA,QAClB,OAAO;AAAA,UACL,UAAU;AAAA,UACV,MAAM,IAAI;AAAA,UACV,KAAK,IAAI;AAAA,UACT,OAAO,IAAI;AAAA,UACX,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,UAKZ,UAAU;AAAA,UACV,WAAW;AAAA,UACX,eAAe;AAAA;AAAA,UAEf,WAAW,IAAI;AAAA,UACf,iBAAiB;AAAA,QAAA;AAAA,MACnB;AAAA,IAEJ,CAAC;;;aAIY,MAAA,0BAAXnC,IAAAA,mBAAmF,OAAA;AAAA;QAAhE,KAAK,MAAA,MAAM;AAAA,QAAK,KAAI;AAAA,QAAG,WAAU;AAAA,QAAS,OAAKK,IAAAA,eAAE,MAAA,MAAM,KAAK;AAAA,MAAA,gCACnD,WAAA,UAAA,mBAAO,UAAI,+BAAvCiB,IAAAA,YAAuEc,aAAA;AAAA;QAAd,MAAM,QAAA;AAAA,MAAA;;;;;;;;;;;AChDjE,UAAM,QAAQ;AAEd,UAAM,aAAa1B,aAAAA,sBAAsBlB,oBAAmB;AAC5D,UAAM,QAAQD,aAAAA;AAAAA,MACZC,KAAAA;AAAAA,MACA,CAACC,UAASA,MAAK,cAAc,MAAM,KAAK,GAAG;AAAA,MAC3C;AAAA,IAAA;AAEF,UAAM,QAAQF,aAAAA,oBAAoBC,sBAAqB,CAACC,UAASA,MAAK,cAAA,GAAiB,IAAI;AAK3F,UAAM,SAASG,IAAAA;AAAAA,MAAS,MACtB,MAAM,QAAQyC,KAAAA,cAAc,MAAM,MAAM,IAAI,QAAQ,MAAM,KAAK,UAAU,WAAW,IAAI;AAAA,IAAA;AAG1F,UAAM,MAAMC,IAAAA,IAAmB,IAAI;AACnC1B,QAAAA;AAAAA,MACE,CAAC,YAAY,OAAO,MAAM;AAAA,MAC1B,CAAC,CAACnB,OAAM,QAAQ,IAAI,GAAG,WAAW,cAAc;AAC9C,YAAI,CAACA,SAAQ,CAAC,MAAM;AAClB,cAAI,QAAQ;AACZ;AAAA,QACF;AAGA;AAAA,UACE8C,IAAAA;AAAAA,YACE,MAAM9C,MAAK,wBAAwB,IAAI;AAAA,YACvC,CAAC,SAAU,IAAI,QAAQ;AAAA,UAAA;AAAA,QACzB;AAAA,MAEJ;AAAA,MACA,EAAE,WAAW,KAAA;AAAA,IAAK;AAGpB,UAAM,QAAQG,IAAAA,SAAS,MAA4B;AACjD,YAAM,UAAU,MAAM;AACtB,UAAI,CAAC,QAAS,QAAO;AACrB,YAAM,QAAQ4C,IAAAA,aAAa,QAAQ,KAAK,MAAM,KAAK,SAAS;AAC5D,aAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,GAAG,MAAM,IAAI;AAAA,QACnB,KAAK,GAAG,MAAM,GAAG;AAAA,QACjB,OAAO,GAAG,MAAM,KAAK;AAAA,QACrB,QAAQ,GAAG,MAAM,MAAM;AAAA;AAAA,QAEvB,UAAU;AAAA,QACV,WAAW;AAAA,QACX,eAAe;AAAA,QACf,SAASX,IAAAA,aAAa,QAAQ,OAAO;AAAA,QACrC,GAAI,QAAQ,MAAM,EAAE,WAAW,UAAU,QAAQ,GAAG,QAAQ,iBAAiB,SAAA,IAAa,CAAA;AAAA,MAAC;AAAA,IAE/F,CAAC;;AAIY,aAAA,MAAA,SAAS,IAAA,0BAApB7B,IAAAA,mBAA8E,OAAA;AAAA;QAApD,KAAK,IAAA;AAAA,QAAK,KAAI;AAAA,QAAG,WAAU;AAAA,QAAS,0BAAO,MAAA,KAAK;AAAA,MAAA;;;;;;;;;;;AC/B5E,UAAM,QAAQ;AAQd,UAAM,QAAQV,IAAAA,SAAA;AASd,UAAM,WAAkC,OAAO,OAAO,EAAE;AACxD,UAAM,WAAgC,OAAO,OAAO,EAAE;AAEtD,UAAM0B,SAAOC,KAAAA,QAAA;AAEbwB,eAAAA;AAAAA,MACE7C,IAAAA,SAAS,MAAMoB,OAAK,MAAM,GAAG;AAAA,MAC7B;AAAA,IAAA;AAEF,UAAM,aAAaN,aAAAA,sBAAsBlB,oBAAmB;AAC5D,UAAM,cAAckB,aAAAA,sBAAsBgC,2BAAgB;AAG1D,UAAM,eAAenD,aAAAA;AAAAA,MACnBmD,WAAAA;AAAAA,MACA,CAAC,QAAQ,IAAI,gBAAA;AAAA,MACb;AAAA,IAAA;AAMF,UAAM,QAAQnD,aAAAA;AAAAA,MACZC,KAAAA;AAAAA,MACA,CAACC,UAAS;AACR,cAAM,EAAE,WAAW,IAAA,IAAQuB,OAAK;AAChC,eAAOvB,MAAK,cAAc,KAAK,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,UAAU;AAAA,MACvF;AAAA,MACA;AAAA,MACAC,KAAAA;AAAAA,IAAA;AAEF,UAAM,QAAQH,aAAAA;AAAAA,MACZC,KAAAA;AAAAA,MACA,CAACC,UAAS;AACR,cAAM,EAAE,WAAW,IAAA,IAAQuB,OAAK;AAChC,eAAOvB,MAAK,cAAc,KAAK,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,UAAU;AAAA,MACvF;AAAA,MACA;AAAA,MACAC,KAAAA;AAAAA,IAAA;AAMF,UAAM,gBAAgBe,IAAAA,WAAW,CAAC;AAKlCG,QAAAA;AAAAA,MACE,CAAC,YAAY,MAAM,MAAM,SAAS;AAAA,MAClC,CAAC,CAACnB,OAAM,SAAS,GAAG,UAAU,cAAc;AAC1C,cAAM,SAAS,qCAAW;AAC1B,YAAI,aAAa,UAAU,cAAc,UAAUC,kBAAa,WAAW,MAAM,GAAG;AAClFiD,cAAAA;AAAAA,YACE;AAAA,YACA;AAAA,UAAA;AAAA,QAGJ;AACA,YAAIlD,SAAQ,WAAW;AACrB;AAAA,YACEmD,IAAAA;AAAAA,cAA0BnD;AAAA,cAAM;AAAA,cAAW,MAAA;;AACzC,gCAAO,iBAAY,UAAZ,mBAAmB,sBAAqB,EAAE;AAAA;AAAA,YAAA;AAAA,UACnD;AAAA,QAEJ;AACA,sBAAc,SAAS;AAAA,MACzB;AAAA,MACA,EAAE,WAAW,KAAA;AAAA,IAAK;AAMpB,UAAM,OAAOgB,IAAAA,WAAiD,IAAI;AAElE,UAAM,QAAQoC,IAAAA,gBAAA;AACdC,oBAAY,MAAM,MAAM,SAAS;AAMjC,UAAM,WAAWvD,aAAAA;AAAAA,MACfC,KAAAA;AAAAA,MACA,CAACC,UAASA,MAAK,mBAAmBuB,OAAK,MAAM,GAAG;AAAA,MAChD;AAAA,IAAA;AAKF,UAAM,YAAYzB,aAAAA;AAAAA,MAChBwD,OAAAA;AAAAA,MACA,CAAC,WAAW,OAAO,mBAAmB/B,OAAK,MAAM,UAAU,WAAW;AAAA,MACtEA,OAAK,MAAM,UAAU;AAAA,IAAA;AAEvBJ,QAAAA;AAAAA,MACE,CAAC,YAAY,MAAMI,OAAK,MAAM,KAAK,WAAW,QAAQ;AAAA,MACtD,CAAC,CAACvB,OAAM,SAAS,KAAK,GAAG,WAAW,cAAc;AAChD,YAAI,CAACA,SAAQ,CAAC,MAAO;AACrB;AAAA,UACEuD,IAAAA;AAAAA,YACE;AAAA,YACA,CAAC,WAAWvD,MAAK,kBAAkB,SAAS,OAAO,MAAM;AAAA,YACzDwD,KAAAA;AAAAA,YACA,CAAC,WAAY,KAAK,QAAQ;AAAA,UAAA;AAAA,QAC5B;AAAA,MAEJ;AAAA,MACA,EAAE,WAAW,KAAA;AAAA,IAAK;AAMpB,UAAM,aAAarD,IAAAA,SAAS,MAAMsD,IAAAA,iBAAiB,MAAM,OAAOD,KAAAA,aAAa,CAAC;AAS9E,UAAM,SAAkB,EAAE,MAAM,UAAU,OAAO,MAAA;AAOjD,UAAM,QAAQrD,IAAAA,SAAS,MAAe;AACpC,WAAK,aAAa;AAClB,WAAK,cAAc;AACnB,YAAMH,QAAO,WAAW;AACxB,YAAM,YAAY,MAAM;AACxB,aAAO,MAAM,MAAM,IAAI,CAAC,SAAgB;AACtC,cAAM,SAAS,KAAK,cAAc;AAClC,YAAI,CAAC,UAAU,CAACA,MAAM,QAAO,EAAE,MAAM,YAAY,MAAM,SAAS,OAAA;AAChE,cAAM,SAAS,WAAW,UAAU,QAAQwD,KAAAA,cAAc,OAAO,GAAG,MAAM,WAAW;AACrF,eAAO,EAAE,MAAM,YAAY,QAAQ,SAASE,wBAAoB,QAAQ1D,OAAM,WAAW,MAAM,EAAA;AAAA,MACjG,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,WAAWG,IAAAA;AAAAA,MAAS,MACxBwD,IAAAA,iBAAiB,MAAM,OAAO,MAAM,OAAO,MAAM,WAAWH,KAAAA,aAAa;AAAA,IAAA;AAM3E,UAAM,YAAYrD,IAAAA,SAAS,MAAM,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;AACpF,UAAM,8BAAc,IAAA;AACpB,UAAM,oCAAoB,IAAA;AAC1B,aAAS,SAAS,IAAuB;AACvC,UAAI,SAAS,QAAQ,IAAI,EAAE;AAC3B,UAAI,CAAC,QAAQ;AACX,iBAASyD,IAAAA,QAAQ,MAAM;AACrB,gBAAM,OAAO,UAAU,MAAM,IAAI,EAAE;AACnC,iBAAO,OAAOC,MAAEC,aAAe,EAAE,MAAM,MAAM,KAAK,MAAA,CAAO,IAAI;AAAA,QAC/D,CAAC;AACD,gBAAQ,IAAI,IAAI,MAAM;AAAA,MACxB;AACA,aAAO;AAAA,IACT;AAEA,aAAS,eAAe,IAAuB;AAC7C,UAAI,SAAS,cAAc,IAAI,EAAE;AACjC,UAAI,CAAC,QAAQ;AACX,iBAASF,IAAAA,QAAQ,MAAM;AACrB,gBAAM,OAAO,UAAU,MAAM,IAAI,EAAE;AACnC,iBAAO,OACHC,IAAAA,EAAEE,aAAiB,EAAE,MAAM,MAAMxC,OAAK,MAAA,GAAS,MAAMsC,IAAAA,EAAE,SAAS,EAAE,CAAC,CAAC,IACpE;AAAA,QACN,CAAC;AACD,sBAAc,IAAI,IAAI,MAAM;AAAA,MAC9B;AACA,aAAO;AAAA,IACT;AAEA1C,cAAM,WAAW,CAAC6C,WAAU;AAC1B,iBAAW,MAAM,QAAQ,KAAA,EAAQ,KAAI,CAACA,OAAM,IAAI,EAAE,EAAG,SAAQ,OAAO,EAAE;AACtE,iBAAW,MAAM,cAAc,KAAA,EAAQ,KAAI,CAACA,OAAM,IAAI,EAAE,EAAG,eAAc,OAAO,EAAE;AAAA,IACpF,CAAC;AAGD,UAAM,cAAc,CAAC,cAAoCC,IAAAA,MAAM,SAAS;;AAItE,aAAA3D,cAAA,GAAAC,uBAuDM,OAvDN,YAuDM;AAAA,SAtDJD,IAAAA,UAAA,IAAA,GAAAC,IAAAA,mBA2CWE,IAAAA,+BA3C+C,MAAA,OAAK,CAAA,EAA5C,MAAI,YAAc,QAAQ,cAAO;;YAAmB,KAAA,KAAK;AAAA,UAAA;YAGlE,QAAQ,SAAI,WAAgB,UAFpCH,IAAAA,UAAA,GAAAuB,IAAAA,YAUEC,IAAAA,wBATK,YAAY,QAAQ,MAAM,SAAS,CAAA,GAAA;AAAA;cAEvC,YAAY;AAAA,cACZ;AAAA,cACA,MAAMnB,IAAAA,MAAAY,MAAA;AAAA,cACN,QAAQ,eAAe,KAAK,EAAE;AAAA,cAC9B,SAAS,KAAK,WAAO;AAAA,cACrB,UAAU,KAAK;AAAA,cACf,aAAa;AAAA,YAAA,gFAGH,QAAQ,SAAI,UAAe,2BADxCM,IAAAA,YAmBkBkC,aAAA;AAAA;cAjBf;AAAA,cACA,MAAMpD,IAAAA,MAAAY,MAAA;AAAA,cACN,aAAa,QAAQ;AAAA,cACrB,OAAO,QAAQ;AAAA,YAAA;mCAEhB,MAAA;;AAWE;AAAA,kBAXFc,IAAAA,YAWE6B,aAAA;AAAA,oBAVC,WAAW,YAAY,QAAQ,MAAM,SAAS;AAAA,oBAC9C,QAAQ,QAAQ,MAAM,UAAK;AAAA,oBAC3B,YAAY;AAAA,oBACZ;AAAA,oBACA,MAAMvD,IAAAA,MAAAY,MAAA;AAAA,oBACN,QAAQ,SAAS,KAAK,EAAE;AAAA,oBACxB,YAAyB,KAAA,SAAQZ,IAAAA,MAAAwD,IAAAA,iBAAA,EAAkB,KAAA,OAAM,KAAK,MAAI,UAAK,eAAL,mBAAiB,oBAAe,IAAA;AAAA,oBAGlG,aAAa,QAAQ;AAAA,kBAAA;;;;oFAM1BtC,IAAAA,YAOkBkC,aAAA;AAAA;cALf;AAAA,cACA,MAAMpD,IAAAA,MAAAY,MAAA;AAAA,cACN,OAAO,QAAQ,SAAI,YAAiB,QAAQ;AAAA,YAAA;mCAE7C,MAA2C;AAAA,gBAA3Cc,IAAAA,YAA2CyB,aAAA;AAAA,kBAA3B;AAAA,kBAAa,MAAM,KAAA;AAAA,gBAAA;;;;;;8BAGvCvD,IAAAA,mBAAiFE,IAAAA,UAAA,MAAAC,IAAAA,WAArD,SAAA,OAAQ,CAAhB,SAAI;kCAAxBmB,IAAAA,YAAiFuC,aAAA;AAAA,YAA1C,KAAK,KAAK;AAAA,YAAK,MAAM;AAAA,YAAO,MAAMzD,IAAAA,MAAAY,MAAA;AAAA,UAAA;;QACzEc,IAAAA,YAA2BgC,aAAA,EAAd,MAAM1D,UAAAY,MAAA,EAAA,GAAI,MAAA,GAAA,CAAA,MAAA,CAAA;AAAA,QACvBc,IAAAA,YAOmBiC,aAAA,EAPA,MAAM3D,UAAAY,MAAA,EAAA,GAAIgD,gBAAA,EAAA,GAAA,KAAA;AAAA,UACX,MAAM;kBAAS;AAAA,YAC7B,IAAAC,IAAAA,QAAA,CADqC,WAAM;AAAA,cAC3C1D,IAAAA,WAAsC,iEAAV,MAAM,CAAA,CAAA;AAAA,YAAA;;;UAEpB,MAAK,iBAAA;kBAAsB;AAAA,YACzC,IAAA0D,IAAAA,QAAA,CAD0D,WAAM;AAAA,cAChE1D,IAAAA,WAA+C,0EAAV,MAAM,CAAA,CAAA;AAAA,YAAA;;;;;;;;;;;;;;;ACjRnD,UAAM,UAAU2D,UAAAA,oBAAA;AAChB,UAAM,SAAS3E,aAAAA;AAAAA,MACbC,KAAAA;AAAAA,MACA,CAACC,UAAS;AACR,cAAM,YAAYA,MAAK,UAAU,UAAA;AACjC,YAAI,CAAC,UAAW,QAAO;AACvB,cAAM,OAAO,QAAQ,MAAM,UAAU,QAAQ,UAAU,IAAI;AAC3D,eAAO,OAAOA,MAAK,qBAAqB,IAAI,IAAI;AAAA,MAClD;AAAA,MACA;AAAA,MACA0E,IAAAA;AAAAA,IAAA;;aAMQ/D,IAAAA,MAAA,MAAA,sBADRkB,IAAAA,YAWW8C,6CAAAA,WAAA;AAAA;QATR,QAAM;AAAA,UAAgB,MAAAhE,IAAAA,MAAA,MAAA,EAAO;AAAA,UAAoB,QAAAA,IAAAA,MAAA,MAAA,EAAO;AAAA,UAAkB,GAAAA,UAAA,MAAA,EAAO,iBAAc,EAAA,OAAA,CAAaA,IAAAA,MAAA,MAAA,EAAO,cAAc,MAAA,CAAA;AAAA,QAAA;AAAA,QAKjI,WAAW,QAAA;AAAA,QACX,KAAK,QAAA;AAAA,MAAA;6BAEN,MAAQ;AAAA,UAARG,eAAQ,KAAA,QAAA,SAAA;AAAA,QAAA;;;;;;;;;;;;;AC5BZ,UAAM,QAAQhB,aAAAA;AAAAA,MACZF,iBAAAA;AAAAA,MACA,CAAC,eAAe,WAAW,MAAM,IAAA;AAAA,MACjC;AAAA,MACAgF,IAAAA;AAAAA,IAAA;;aAKgBjE,IAAAA,MAAA,KAAA,sBAAhBkB,IAAAA,YAEW8C,6CAAAA,WAAA;AAAA;QAFa,QAAQhE,IAAAA,MAAA,KAAA;AAAA,QAAQ,WAAW,QAAA;AAAA,QAAY,KAAK,QAAA;AAAA,MAAA;6BAClE,MAAuB;AAAA,UAAvBG,IAAAA,WAAuB,KAAA,QAAA,WAAA,EAAhB,OAAOH,IAAAA,MAAA,KAAA,EAAA,CAAK;AAAA,QAAA;;;;;;;;;;;;;ACZvB,UAAM,QAAQd,IAAAA,SAAA;AAKd,UAAM,WAAWC,aAAAA;AAAAA,MACfF,iBAAAA;AAAAA,MACA,CAAC,eAAe,WAAW,UAAU,kBAAA;AAAA,MACrC;AAAA,MACAiF,IAAAA;AAAAA,IAAA;AAEF,UAAM,UAAU,sBAAsB,CAAC,aAAa,SAAS,OAAO,OAAO;AAE3E,UAAM,QAAQ1E,IAAAA;AAAAA,MACZ,OAAsB;AAAA,QACpB,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,SAAS;AAAA,QACT,YAAY2E,IAAAA,aAAa,WAAW;AAAA,QACpC,UAAU;AAAA,QACV,YAAYC,IAAAA,MAAM,sBAAsB,QAAQ,MAAM,UAAU;AAAA,QAChE,OAAOA,IAAAA,MAAM,iBAAiB,QAAQ,MAAM,KAAK;AAAA,MAAA;AAAA,IACnD;;AAMQ,aAAApE,IAAAA,MAAA,QAAA,MAAa,MAAM,WAAWA,IAAAA,MAAA,OAAA,EAAQ,6BAD9CkB,IAAAA,YAQW8C,6CAAAA,WAAA;AAAA;QANR,gBAAgBhE,IAAAA,MAAA,QAAA,EAAS,MAAI,QAAA,EAAA,GAAeA,IAAAA,MAAA,QAAA,EAAS,IAAE,OAAA,GAAA,QAAA,IAAA;AAAA,QACvD,WAAW,QAAA;AAAA,QACX,KAAK,QAAA;AAAA,MAAA;6BAEN,MAAkD;AAAA,UAAtC,MAAM,UAAlBG,eAAkD,KAAA,QAAA,WAAA,EAAtB,UAAUH,IAAAA,MAAA,QAAA,EAAA,GAAQ,QAAA,QAAA,CAAA,sBAC9CJ,IAAAA,mBAAsD,OAAA;AAAA;YAAzC,0BAAO,MAAA,KAAK;AAAA,UAAA,uBAAKI,IAAAA,MAAA,QAAA,EAAS,KAAK,IAAG,KAAC,CAAA;AAAA,QAAA;;;;;;ACd7C,SAAS,gBAAsC;AACpD,SAAOqE,aAAAA,cAAcpF,iBAAAA,eAAe;AACtC;AAGO,SAAS,mBACd,QACA,SACM;AACNqF,kCAAmBrF,iBAAAA,iBAAiB,QAAQ,OAAO;AACrD;AAEA,MAAM,iBAAwC,OAAO,OAAO,EAAE;AAOvD,SAAS,kBACd,QACsC;AACtC,SAAOE,aAAAA;AAAAA,IACLF,iBAAAA;AAAAA,IACA,CAAC,eAAe,WAAW,KAAKwB,IAAAA,QAAQ,MAAM,CAAC;AAAA,IAC/C;AAAA,IACAnB,KAAAA;AAAAA,EAAA;AAEJ;AAEA,MAAM,cAA4B,OAAO,OAAO,EAAE;AAO3C,SAAS,sBAAsB,QAA+D;AACnG,SAAOH,aAAAA;AAAAA,IACLF,iBAAAA;AAAAA,IACA,CAAC,eAAe,WAAW,MAAM,YAAYwB,IAAAA,QAAQ,MAAM,CAAC;AAAA,IAC5D;AAAA,EAAA;AAEJ;AAEA,MAAM,gBAAsC,OAAO,OAAO;AAAA,EACxD,YAAY,CAAA;AAAA,EACZ,QAAQ,CAAA;AAAA,EACR,OAAO,CAAA;AACT,CAAC;AAOM,SAAS,wBACd,QACqC;AACrC,SAAOtB,aAAAA;AAAAA,IACLF,iBAAAA;AAAAA,IACA,CAAC,eAAe;AACd,YAAM,OAAOwB,IAAAA,QAAQ,MAAM;AAC3B,aAAO,SAAS,SACZ,WAAW,UAAU,kBACrB,WAAW,MAAM,cAAc,IAAI;AAAA,IACzC;AAAA,IACA;AAAA,EAAA;AAEJ;AAUO,SAAS,oBACd,KACwC;AACxC,SAAOtB,aAAAA;AAAAA,IACLC,KAAAA;AAAAA,IACA,CAAC,eAAe;AACd,YAAM,SAASqB,IAAAA,QAAQ,GAAG;AAC1B,aAAO,SAAS,WAAW,oBAAoB,MAAM,IAAI;AAAA,IAC3D;AAAA,IACA;AAAA,IACA8D,IAAAA;AAAAA,EAAA;AAEJ;AAUO,SAAS,cAA2B;AACzC,QAAM,aAAa,cAAA;AAEnB,QAAM,SAAStB,IAAAA,QAAQ,EAAE;AACzB,SAAO,IAAI,MAAM,QAAQ;AAAA,IACvB,KAAK,CAAC,SAAS,QACb,OAAO,QAAQ,YAAY,IAAI,WAAW,MAAM,IAC5C,QAAQ,IAAI,QAAQ,GAAG,IACvB,QAAQ,IAAI,WAAW,UAAU,GAAG;AAAA,IAC1C,KAAK,CAAC,SAAS,QAAQ,QAAQ,IAAI,WAAW,UAAU,GAAG;AAAA,EAAA,CAC5D;AACH;AAEA,MAAM,WAAkC,OAAO,OAAO,EAAE;AACxD,MAAM,aAAuC,OAAO,OAAO,EAAE;AAStD,SAAS,oBAAiE;AAC/E,QAAM,aAAauB,aAAAA,cAAA;AACnB,QAAM,UAAUrF,aAAAA;AAAAA,IACdF,iBAAAA;AAAAA,IACA,CAAC,eAAe,WAAW,SAAS,YAAA;AAAA,IACpC;AAAA,EAAA;AAEF,QAAM,QAAQwF,aAAAA;AAAAA,IAAe,CAAC,WAC5B,WAAW,QAAQ,OAAO,UAAU,UAAU,WAAW,KAAK,IAAI;AAAA,EAAA;AAEpE,SAAOjF,IAAAA,SAAS,MAAMkF,yBAAqB,QAAQ,OAAO,MAAM,KAAK,CAAC;AACxE;AAMO,SAAS,iBACd,KACyC;AACzC,QAAM,QAAQ,kBAAA;AACd,QAAM,aAAapE,aAAAA,sBAAsBrB,gCAAe;AACxD,SAAOO,IAAAA,SAAS,MAAM;AACpB,UAAM,SAASiB,IAAAA,QAAQ,GAAG;AAC1B,UAAM,MAAM,WAAW;AACvB,QAAI,UAAU,QAAQ,CAAC,IAAK,QAAO;AACnC,UAAM,SAAS,IAAI,SAAS,UAAU,MAAM;AAC5C,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,OAAOoC,KAAAA,cAAc,OAAO,KAAK,GAAG;AAC1C,WAAO,MAAM,MAAM,KAAK,CAAC,SAASA,KAAAA,cAAc,KAAK,KAAK,GAAG,MAAM,IAAI,KAAK;AAAA,EAC9E,CAAC;AACH;AASO,MAAM,qBAAyC8B,IAAAA;AAW/C,SAAS,sBACd,WAAgD,oBAC1C;AACN,QAAM,aAAarE,aAAAA,sBAAsBrB,gCAAe;AAExDuB,MAAAA;AAAAA,IACE,CAAC,YAAY,MAAMoE,UAAM,QAAQ,CAAC;AAAA,IAClC,CAAC,CAAC,YAAY,OAAO,GAAG,WAAW,cAAc;AAC/C,UAAI,CAAC,WAAY;AAEjB;AAAA,QACEC,IAAAA;AAAAA,UAA0B;AAAA,UAAY;AAAA,UAAS,MAC7CtC,IAAAA;AAAAA,YACE;AAAA,YACA;AAAA,UAAA;AAAA,QAEF;AAAA,MACF;AAAA,IAEJ;AAAA,IACA,EAAE,WAAW,KAAA;AAAA,EAAK;AAEtB;;;;;;;;;;;;;;;;;;;"}
@@ -3,7 +3,7 @@ import { shallowEqual, annotationKey } from "@embedpdf/core";
3
3
  import { AnnotationToken as AnnotationToken$1, previewBucket } from "@embedpdf/plugin-annotation/contract/host";
4
4
  import { InteractionToken } from "@embedpdf/plugin-interaction/contract";
5
5
  import { RenderToken } from "@embedpdf/plugin-render/contract/host";
6
- import { annotationChromePaint, chromeInPixels, frameInPixels, createTextBoxEditorFollower, textBoxEditorScaleOf, textBoxStyleOf, lookFrameOf, textPlateInPixels, sceneViewBox, svgShapesOf, ghostOpacity, pictureOrPainting, shownAppearance, rasterInFrame, loadObjectUrl, rectInPixels, registerRendererBehaviors, createShownUrls, loadAppearanceUrls, editingTextKeyOf, annotationDrawingOf, layerTextBoxesOf, bakedAppearanceOf, sameSelectionAnchor, sameCreationDraftAnchor, paint, paintDefault, sameRotationAnchor, pickRequestedFile, sameAnnotationAnchor, enrichCommentThreads, installFilePickerProvider } from "@embedpdf/web";
6
+ import { annotationChromePaint, chromeInPixels, frameInPixels, createTextBoxEditorFollower, textBoxEditorScaleOf, ownTextBoxOf, lookFrameOf, freeTextBoxOf, sceneViewBox, svgShapesOf, ghostOpacity, pictureOrPainting, shownAppearance, rasterInFrame, loadObjectUrl, rectInPixels, registerRendererBehaviors, createShownUrls, loadAppearanceUrls, editingTextKeyOf, annotationDrawingOf, layerTextBoxesOf, bakedAppearanceOf, sameSelectionAnchor, sameCreationDraftAnchor, paint, paintDefault, sameRotationAnchor, pickRequestedFile, sameAnnotationAnchor, enrichCommentThreads, installFilePickerProvider } from "@embedpdf/web";
7
7
  import { d as devWarn } from "./dev-CtMlvxjZ.js";
8
8
  import { a as usePaintsPagePart } from "./page-layers-rlh4-1qr.js";
9
9
  import { i as useOptionalSelector, h as useOptionalCapability, a as useCapability, b as useCapabilityEvent, d as useDocumentId, g as useKernelValue } from "./capabilities-C7YzgPCX.js";
@@ -244,9 +244,11 @@ function useRichTextEditor(annotation) {
244
244
  const item = useOptionalSelector(
245
245
  AnnotationToken$1,
246
246
  (host) => {
247
- const key = annotationKey(toValue(annotation).ref);
248
247
  const { transform } = page.value;
249
- return host.listTextItems(page.value.ref, { zoom: transform.zoom, rotation: transform.rotation }).find((text) => text.ref !== null && annotationKey(text.ref) === key) ?? null;
248
+ return host.getTextItem(toValue(annotation).ref, {
249
+ zoom: transform.zoom,
250
+ rotation: transform.rotation
251
+ });
250
252
  },
251
253
  null
252
254
  );
@@ -254,14 +256,14 @@ function useRichTextEditor(annotation) {
254
256
  const scale = computed(
255
257
  () => textBoxEditorScaleOf(item.value, page.value.transform, lookScale.value)
256
258
  );
257
- const element = useTextBoxEditor(item, scale);
259
+ const own = computed(() => item.value ? ownTextBoxOf(item.value, scale.value) : null);
260
+ const element = useTextBoxEditor(item, () => {
261
+ var _a;
262
+ return ((_a = own.value) == null ? void 0 : _a.scale) ?? scale.value;
263
+ });
258
264
  const style = computed(() => {
259
- const text = item.value;
260
- if (!text) return NO_STYLE;
261
- return {
262
- ...textBoxStyleOf(text.css, scale.value),
263
- ...text.editing ? { pointerEvents: "auto" } : {}
264
- };
265
+ var _a;
266
+ return ((_a = own.value) == null ? void 0 : _a.style) ?? NO_STYLE;
265
267
  });
266
268
  return {
267
269
  ref: (target) => {
@@ -337,46 +339,19 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
337
339
  },
338
340
  setup(__props) {
339
341
  const props = __props;
340
- const plate = computed(() => textPlateInPixels(props.item, props.page.transform));
341
- const element = useTextBoxEditor(
342
- () => props.item,
343
- () => plate.value.scale
344
- );
345
342
  const chrome = useAnnotationSettings((settings) => settings.chrome);
346
343
  const accent = useViewerSettings((settings) => settings.accent);
347
344
  const outline = computed(() => annotationChromePaint(chrome.value, accent.value).textOutline);
348
- const style = computed(() => {
349
- const { item } = props;
350
- const { left, top, width, height, scale } = plate.value;
351
- return {
352
- position: "absolute",
353
- left: `${left}px`,
354
- top: `${top}px`,
355
- width: `${width}px`,
356
- // Fixed to the plate: the box never grows with its text; it scrolls while
357
- // typing and clips otherwise, where the baked appearance clips.
358
- height: `${height}px`,
359
- ...textBoxStyleOf(item.css, scale),
360
- boxSizing: "border-box",
361
- // The box's fill and border are the vector scene's, under this layer.
362
- background: "transparent",
363
- whiteSpace: "pre-wrap",
364
- overflowWrap: "break-word",
365
- overflowY: item.editing ? "auto" : "hidden",
366
- overflowX: "hidden",
367
- outline: item.editing ? `1px solid ${outline.value}` : "none",
368
- cursor: item.editing ? "text" : "default",
369
- // A plain text box turns about its centre, as the baked appearance does.
370
- ...item.rot ? { transform: `rotate(${item.rot}deg)`, transformOrigin: "center" } : {},
371
- // Not typing: clicks fall through to the shapes (select, move, resize).
372
- pointerEvents: item.editing ? "auto" : "none"
373
- };
374
- });
345
+ const box = computed(() => freeTextBoxOf(props.item, props.page.transform, outline.value));
346
+ const element = useTextBoxEditor(
347
+ () => props.item,
348
+ () => box.value.scale
349
+ );
375
350
  return (_ctx, _cache) => {
376
351
  return openBlock(), createElementBlock("div", {
377
352
  ref_key: "element",
378
353
  ref: element,
379
- style: normalizeStyle(style.value)
354
+ style: normalizeStyle(box.value.style)
380
355
  }, null, 4);
381
356
  };
382
357
  }
@@ -1001,4 +976,4 @@ export {
1001
976
  useRichTextEditor as p,
1002
977
  useAnnotation as u
1003
978
  };
1004
- //# sourceMappingURL=composables-CIkhKwAg.js.map
979
+ //# sourceMappingURL=composables-DK3lwh38.js.map