@designfever/web-review-kit 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -4
- package/dist/{chunk-UNDQZ4Y2.js → chunk-XP2IACXL.js} +80 -46
- package/dist/chunk-XP2IACXL.js.map +1 -0
- package/dist/{chunk-4ZP7B7R6.js → chunk-ZWJNUOYV.js} +150 -35
- package/dist/chunk-ZWJNUOYV.js.map +1 -0
- package/dist/index.cjs +229 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react-shell.cjs +1880 -949
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +2 -1
- package/dist/react-shell.d.ts +2 -1
- package/dist/react-shell.js +1624 -806
- package/dist/react-shell.js.map +1 -1
- package/dist/{types-BM8E7BFV.d.cts → types-DKDtZjTH.d.cts} +8 -0
- package/dist/{types-BM8E7BFV.d.ts → types-DKDtZjTH.d.ts} +8 -0
- package/dist/vite.cjs +13 -5
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +2 -0
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +14 -6
- package/dist/vite.js.map +1 -1
- package/docs/README.md +1 -0
- package/docs/installation.md +3 -5
- package/docs/release-notes-0.8.2.md +50 -0
- package/package.json +1 -1
- package/dist/chunk-4ZP7B7R6.js.map +0 -1
- package/dist/chunk-UNDQZ4Y2.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/status.ts","../src/route.ts","../src/adapters/local.ts","../src/figma/image.types.ts","../src/core/review/scope.ts","../src/core/geometry.ts","../src/core/dom.anchor.ts","../src/core/id.ts","../src/core/hotkey.ts","../src/core/location.ts","../src/core/review/item.ts","../src/core/scroll.ts","../src/core/draft.metrics.ts","../src/core/draft.preview.ts","../src/core/typography.tokens.ts","../src/core/overlay.style.ts","../src/core/draft.attachments.ts","../src/core/view/composer.position.ts","../src/core/view/icons.ts","../src/core/view/draft.capture.ts","../src/core/view/draft.text.ts","../src/core/view/form.widgets.ts","../src/core/review/format.ts","../src/core/view/markers.ts","../src/core/view/area.draft.ts","../src/core/view/dom.draft.ts","../src/core/view/panel.ts","../src/core/view/selection.layers.ts","../src/core/web.review.kit.view.ts","../src/core/web.review.kit.app.ts"],"sourcesContent":["import type { ReviewItemStatus, ReviewWorkflowStatus } from './types';\n\nexport const REVIEW_WORKFLOW_STATUS_OPTIONS: Array<{\n value: ReviewWorkflowStatus;\n label: string;\n}> = [\n { value: 'todo', label: 'Todo' },\n { value: 'doing', label: 'Doing' },\n { value: 'review', label: 'Review' },\n { value: 'hold', label: 'Hold' },\n { value: 'done', label: 'Done' },\n];\n\nexport function normalizeReviewItemStatus(\n status: ReviewItemStatus | undefined\n): ReviewWorkflowStatus {\n if (status === 'resolved') return 'done';\n if (status === 'open' || !status) return 'todo';\n return status;\n}\n\nexport function matchesReviewItemStatus(\n itemStatus: ReviewItemStatus | undefined,\n queryStatus: ReviewItemStatus\n) {\n return (\n normalizeReviewItemStatus(itemStatus) === normalizeReviewItemStatus(queryStatus)\n );\n}\n","import type { ReviewItem } from './types';\n\nexport function getItemRouteKey(\n item: Pick<ReviewItem, 'routeKey' | 'normalizedPath'>\n) {\n return item.routeKey || normalizeRoutePath(item.normalizedPath);\n}\n\nexport function normalizeRoutePath(pathname: string) {\n const [pathWithoutQuery] = pathname.split(/[?#]/);\n const path = (pathWithoutQuery || '/').replace(/\\/index\\.html$/, '/');\n return path.startsWith('/') ? path : `/${path}`;\n}\n","import { getItemRouteKey } from '../route';\nimport { matchesReviewItemStatus } from '../status';\nimport type {\n LocalAdapterOptions,\n ReviewItem,\n WebReviewKitAdapter,\n} from '../types';\n\nconst DEFAULT_STORAGE_KEY = 'df-web-review-kit:items';\n\nexport function localAdapter(\n options: LocalAdapterOptions = {}\n): WebReviewKitAdapter {\n const storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;\n\n const write = (items: ReviewItem[]) => {\n window.localStorage.setItem(storageKey, JSON.stringify(items));\n };\n\n const read = (): ReviewItem[] => {\n if (typeof window === 'undefined') return [];\n\n const raw = window.localStorage.getItem(storageKey);\n if (!raw) return [];\n\n try {\n const value = JSON.parse(raw);\n if (!Array.isArray(value)) return [];\n\n let changed = false;\n const items = value.flatMap((item) => {\n const normalized = normalizeStoredReviewItem(item);\n if (!normalized || normalized !== item) changed = true;\n return normalized ? [normalized] : [];\n });\n\n if (changed) write(items);\n return items;\n } catch {\n return [];\n }\n };\n\n return {\n async get(id) {\n return read().find((item) => item.id === id) ?? null;\n },\n\n async list(query) {\n return read().filter((item) => {\n if (item.projectId !== query.projectId) return false;\n const queryRouteKey = query.routeKey ?? query.normalizedPath;\n if (\n queryRouteKey &&\n getItemRouteKey(item) !== queryRouteKey\n ) {\n return false;\n }\n if (query.status && !matchesReviewItemStatus(item.status, query.status)) {\n return false;\n }\n return true;\n });\n },\n\n async create(item) {\n const items = read();\n items.unshift(item);\n write(items);\n return item;\n },\n\n async update(id, patch) {\n const items = read();\n const index = items.findIndex((item) => item.id === id);\n\n if (index < 0) {\n throw new Error(`Review item not found: ${id}`);\n }\n\n const next: ReviewItem = {\n ...items[index],\n ...patch,\n id,\n createdAt: items[index].createdAt,\n updatedAt: new Date().toISOString(),\n };\n\n items[index] = next;\n write(items);\n return next;\n },\n\n async remove(id) {\n write(read().filter((item) => item.id !== id));\n },\n };\n}\n\nfunction normalizeStoredReviewItem(value: unknown): ReviewItem | undefined {\n if (!value || typeof value !== 'object') return undefined;\n\n const raw = value as Omit<ReviewItem, 'kind'> & {\n kind?: string;\n reviewNumber?: unknown;\n screenshot?: unknown;\n };\n const kind = raw.kind === 'capture' ? 'area' : raw.kind;\n\n if (kind !== 'dom' && kind !== 'area') return undefined;\n\n const { screenshot: _screenshot, reviewNumber: _reviewNumber, ...item } = raw;\n\n if (\n kind === raw.kind &&\n _screenshot === undefined &&\n _reviewNumber === undefined\n ) {\n return raw as ReviewItem;\n }\n\n return {\n ...item,\n kind,\n } as ReviewItem;\n}\n","export type ReviewFigmaImageFormat = 'webp' | 'png' | 'jpg';\n\nexport const DEFAULT_REVIEW_FIGMA_IMAGE_FORMAT =\n 'webp' satisfies ReviewFigmaImageFormat;\n\nexport type ReviewFigmaImageViewport = {\n label?: string;\n width?: number;\n height?: number;\n scope?: 'mobile' | 'tablet' | 'desktop' | 'wide';\n};\n\nexport type ReviewFigmaRouteTarget = {\n type: 'route';\n projectId: string;\n pageUrl: string;\n viewport?: ReviewFigmaImageViewport;\n slot?: string;\n};\n\nexport type ReviewFigmaNodeTarget = {\n type: 'figma-node';\n projectId: string;\n fileKey: string;\n nodeId: string;\n};\n\nexport type ReviewFigmaImageTarget =\n | ReviewFigmaRouteTarget\n | ReviewFigmaNodeTarget;\n\nexport type ReviewFigmaImage = {\n id: string;\n projectId: string;\n target: ReviewFigmaImageTarget;\n figmaUrl: string;\n fileKey: string;\n nodeId: string;\n imageUrl: string;\n imageFormat: ReviewFigmaImageFormat;\n mimeType: string;\n label?: string;\n order: number;\n storageKey?: string;\n width?: number;\n height?: number;\n byteSize?: number;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type ReviewFigmaImageAssetInput = {\n dataUrl: string;\n imageFormat: ReviewFigmaImageFormat;\n mimeType: string;\n byteSize?: number;\n width?: number;\n height?: number;\n};\n\nexport type AddReviewFigmaImageInput = {\n target: ReviewFigmaImageTarget;\n figmaUrl: string;\n label?: string;\n order?: number;\n imageFormat?: ReviewFigmaImageFormat;\n asset?: ReviewFigmaImageAssetInput;\n};\n\nexport type UpdateReviewFigmaImageInput = Partial<\n Pick<ReviewFigmaImage, 'label' | 'order'>\n>;\n\nexport type ReorderReviewFigmaImagesInput = {\n target: ReviewFigmaImageTarget;\n imageIds: string[];\n};\n\nexport interface ReviewFigmaImageStore {\n listImages(target: ReviewFigmaImageTarget): Promise<ReviewFigmaImage[]>;\n addImage(input: AddReviewFigmaImageInput): Promise<ReviewFigmaImage>;\n updateImage(\n id: string,\n patch: UpdateReviewFigmaImageInput\n ): Promise<ReviewFigmaImage>;\n reorderImages(\n input: ReorderReviewFigmaImagesInput\n ): Promise<ReviewFigmaImage[]>;\n deleteImage(id: string): Promise<void>;\n}\n","import type {\n NumberedReviewItem,\n ReviewItem,\n ReviewItemScope,\n ReviewViewportPreset,\n ViewportSize,\n} from '../../types';\n\n/** Default viewport presets used when a host project does not provide its own. */\nexport const DEFAULT_REVIEW_VIEWPORTS: ReviewViewportPreset[] = [\n { label: 'Mobile', width: 390, height: 720, scope: 'mobile' },\n { label: 'Tablet', width: 768, height: 1024, scope: 'tablet' },\n { label: 'Desktop', width: 1440, height: 900, scope: 'desktop' },\n { label: 'Wide', width: 1980, height: 1080, scope: 'wide' },\n];\n\nconst REVIEW_SCOPE_LABELS: Record<Exclude<ReviewItemScope, 'dom'>, string> = {\n mobile: 'Mobile',\n tablet: 'Tablet',\n desktop: 'Desktop',\n wide: 'Wide',\n};\n\nconst normalizeReviewItemScope = (value: unknown): ReviewItemScope | undefined => {\n if (value === 'element') return 'dom';\n if (\n value === 'mobile' ||\n value === 'tablet' ||\n value === 'desktop' ||\n value === 'wide' ||\n value === 'dom'\n ) {\n return value;\n }\n\n return undefined;\n};\n\nconst getViewportPresetDistance = (\n preset: ReviewViewportPreset,\n viewport: ViewportSize\n) =>\n Math.abs(preset.width - viewport.width) +\n Math.abs(preset.height - viewport.height);\n\nconst inferViewportScope = (\n preset: ReviewViewportPreset\n): Exclude<ReviewItemScope, 'dom'> => {\n if (preset.scope) return preset.scope;\n\n const label = preset.label.toLowerCase();\n\n if (label.includes('mobile') || label.includes('phone')) return 'mobile';\n if (label.includes('tablet') || label.includes('pad')) return 'tablet';\n if (\n label.includes('wide') ||\n label.includes('1980') ||\n label.includes('1940') ||\n label.includes('1920')\n ) {\n return 'wide';\n }\n if (label.includes('desktop')) return 'desktop';\n if (preset.width >= 1800) return 'wide';\n if (preset.width >= 1000) return 'desktop';\n if (preset.width >= 700) return 'tablet';\n return 'mobile';\n};\n\n/** Finds the nearest configured preset for a viewport size. */\nexport function findReviewViewportPreset(\n viewport: ViewportSize,\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n) {\n const fallback = presets[0] ?? DEFAULT_REVIEW_VIEWPORTS[0];\n const exact = presets.find(\n (preset) =>\n preset.width === viewport.width && preset.height === viewport.height\n );\n\n if (exact) return exact;\n\n return presets.reduce((closest, preset) => {\n const closestDistance = getViewportPresetDistance(closest, viewport);\n const presetDistance = getViewportPresetDistance(preset, viewport);\n return presetDistance < closestDistance ? preset : closest;\n }, fallback);\n}\n\n/** Resolves a viewport size to the review scope used for item grouping. */\nexport function getReviewViewportScope(\n viewport: ViewportSize,\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n): Exclude<ReviewItemScope, 'dom'> {\n return inferViewportScope(findReviewViewportPreset(viewport, presets));\n}\n\n/**\n * Resolves an item's persisted scope, falling back to its captured viewport.\n *\n * 'dom'(구버전 'element') scope 는 의도적으로 뷰포트 scope 로 폴백한다.\n * 마커 표시 조건이 `scope === currentScope`(현재 뷰포트 scope)라서 'dom' 을\n * 그대로 반환하면 레거시 아이템의 마커가 어느 뷰포트에서도 보이지 않게 된다.\n * 현재 코드는 'dom' scope 를 저장하지 않으므로 이 폴백은 레거시 데이터 전용이다.\n */\nexport function getReviewItemScope(\n item: ReviewItem,\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n): Exclude<ReviewItemScope, 'dom'> {\n const scope = normalizeReviewItemScope(item.scope);\n if (scope && scope !== 'dom') return scope;\n return getReviewViewportScope(item.viewport, presets);\n}\n\n/** Returns the display label for an item's resolved review scope. */\nexport function getReviewItemScopeLabel(\n item: ReviewItem,\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n) {\n const scope = getReviewItemScope(item, presets);\n const preset = findReviewViewportPreset(item.viewport, presets);\n return preset.label || REVIEW_SCOPE_LABELS[scope];\n}\n\n/** Adds scope-aware display labels to review items without mutating them. */\nexport function getNumberedReviewItems(\n items: ReviewItem[],\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n): NumberedReviewItem[] {\n const draftLabels = new Map<string, string>();\n let nextDraftNumber = 1;\n\n [...items]\n .sort((a, b) => {\n const createdOrder = a.createdAt.localeCompare(b.createdAt);\n if (createdOrder !== 0) return createdOrder;\n return a.id.localeCompare(b.id);\n })\n .forEach((item) => {\n if (!getReviewItemNumber(item)) {\n draftLabels.set(item.id, `draft-${nextDraftNumber++}`);\n }\n });\n\n return items.map((item) => {\n const scope = getReviewItemScope(item, presets);\n const label = getReviewItemScopeLabel(item, presets);\n const number = getReviewItemNumber(item);\n\n return {\n item,\n scope,\n label,\n number,\n displayLabel: number ? `#${number}` : draftLabels.get(item.id) ?? 'draft',\n };\n });\n}\n\n/** Reads a persisted review number when present. */\nfunction getReviewItemNumber(item: Pick<ReviewItem, 'reviewNumber'>) {\n return normalizeReviewNumber(item.reviewNumber);\n}\n\n\nfunction normalizeReviewNumber(value: unknown) {\n if (typeof value !== 'number') return undefined;\n if (!Number.isInteger(value) || value < 1) return undefined;\n return value;\n}\n","import type {\n RelativeSelection,\n ReviewPoint,\n ReviewViewportCaptureInput,\n ReviewViewportCaptureResult,\n ViewportSize,\n} from '../types';\n\n/** Rectangle expressed in the target viewport coordinate space. */\nexport interface ViewportSelection {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/** Same-origin target document plus its placement inside the host shell. */\nexport interface ReviewEnvironment {\n window: Window;\n document: Document;\n viewportRect: {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n scaleX?: number;\n scaleY?: number;\n overlayRect: {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n composerHost?: HTMLElement | null;\n captureViewport?: (\n input: ReviewViewportCaptureInput\n ) => Promise<ReviewViewportCaptureResult>;\n}\n\n/** Returns true when two viewport rectangles overlap. */\nfunction rectanglesIntersect(\n a: ViewportSelection,\n b: ViewportSelection\n) {\n return (\n a.left < b.left + b.width &&\n a.left + a.width > b.left &&\n a.top < b.top + b.height &&\n a.top + a.height > b.top\n );\n}\n\n/** Converts a point into a 1x1 selection for shared selection handling. */\nexport function getPointSelection(point: ReviewPoint): ViewportSelection {\n return {\n left: point.x,\n top: point.y,\n width: 1,\n height: 1,\n };\n}\n\n/** Converts public API selection fields into internal viewport rectangle fields. */\nexport function toViewportSelection(\n selection: RelativeSelection\n): ViewportSelection {\n return {\n left: selection.x,\n top: selection.y,\n width: selection.width,\n height: selection.height,\n };\n}\n\n/** Rounds an internal viewport rectangle back to the public selection shape. */\nexport function toPublicSelection(\n selection: ViewportSelection\n): RelativeSelection {\n return {\n x: Math.round(selection.left),\n y: Math.round(selection.top),\n width: Math.round(selection.width),\n height: Math.round(selection.height),\n };\n}\n\n/** Finds the center point of either internal or public selection shapes. */\nexport function getSelectionCenter(\n selection: ViewportSelection | RelativeSelection\n): ReviewPoint {\n if ('left' in selection) {\n return {\n x: selection.left + selection.width / 2,\n y: selection.top + selection.height / 2,\n };\n }\n\n return {\n x: selection.x + selection.width / 2,\n y: selection.y + selection.height / 2,\n };\n}\n\n/** Runtime guard for legacy and current persisted selection values. */\nexport function isRelativeSelection(value: unknown): value is RelativeSelection {\n if (!value || typeof value !== 'object') return false;\n\n const selection = value as Partial<RelativeSelection>;\n return (\n typeof selection.x === 'number' &&\n typeof selection.y === 'number' &&\n typeof selection.width === 'number' &&\n typeof selection.height === 'number'\n );\n}\n\n/** Reads the active target viewport size, falling back to the host window. */\nexport function getViewportSize(\n environment?: ReviewEnvironment\n): ViewportSize {\n const targetWindow = environment?.window ?? window;\n return {\n width: targetWindow.innerWidth,\n height: targetWindow.innerHeight,\n };\n}\n\n/** Returns whether a target-space point is currently visible in the target viewport. */\nexport function isPointInViewport(\n point: ReviewPoint,\n environment?: ReviewEnvironment\n) {\n const viewport = getViewportSize(environment);\n return (\n point.x >= 0 &&\n point.y >= 0 &&\n point.x <= viewport.width &&\n point.y <= viewport.height\n );\n}\n\n/** Returns whether any part of a target-space selection is visible. */\nexport function isSelectionInViewport(\n selection: ViewportSelection,\n environment?: ReviewEnvironment\n) {\n const viewport = getViewportSize(environment);\n return rectanglesIntersect(selection, {\n left: 0,\n top: 0,\n width: viewport.width,\n height: viewport.height,\n });\n}\n\n/** Clamps a target-space point to the visible target viewport. */\nexport function clampPoint(\n point: ReviewPoint,\n environment?: ReviewEnvironment\n) {\n const viewport = getViewportSize(environment);\n return {\n x: clamp(point.x, 0, viewport.width),\n y: clamp(point.y, 0, viewport.height),\n };\n}\n\n/** Places a popover inside the current overlay bounds near a host-space point. */\nexport function getPopoverPosition(\n point: ReviewPoint,\n environment?: ReviewEnvironment,\n options?: {\n width?: number;\n estimatedHeight?: number;\n offset?: number;\n }\n) {\n const bounds = getPopoverBounds(environment);\n const margin = 12;\n const width = Math.min(\n options?.width ?? 320,\n Math.max(240, bounds.width - margin * 2)\n );\n const estimatedHeight = options?.estimatedHeight ?? 178;\n const offset = options?.offset ?? 12;\n\n return {\n left: clamp(\n point.x + offset,\n bounds.left + margin,\n bounds.left + bounds.width - width - margin\n ),\n top: clamp(\n point.y + offset,\n bounds.top + margin,\n bounds.top + bounds.height - estimatedHeight - margin\n ),\n };\n}\n\n\n/** Uses overlay bounds when embedded in a shell, otherwise the host viewport. */\nfunction getPopoverBounds(environment?: ReviewEnvironment) {\n if (!environment) {\n return {\n left: 0,\n top: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n };\n }\n\n return environment.overlayRect;\n}\n\nfunction getEnvironmentScale(environment: ReviewEnvironment) {\n const scaleX =\n typeof environment.scaleX === 'number' &&\n Number.isFinite(environment.scaleX) &&\n environment.scaleX > 0\n ? environment.scaleX\n : 1;\n const scaleY =\n typeof environment.scaleY === 'number' &&\n Number.isFinite(environment.scaleY) &&\n environment.scaleY > 0\n ? environment.scaleY\n : 1;\n\n return { scaleX, scaleY };\n}\n\n/** Converts a target-space point to the host shell coordinate space. */\nexport function toHostPoint(\n point: ReviewPoint,\n environment?: ReviewEnvironment\n) {\n if (!environment) return point;\n const { scaleX, scaleY } = getEnvironmentScale(environment);\n\n return {\n x: point.x * scaleX + environment.viewportRect.left,\n y: point.y * scaleY + environment.viewportRect.top,\n };\n}\n\n/** Converts a target-space rectangle to the host shell coordinate space. */\nexport function toHostSelection(\n selection: ViewportSelection,\n environment: ReviewEnvironment\n): ViewportSelection {\n const { scaleX, scaleY } = getEnvironmentScale(environment);\n\n return {\n left: selection.left * scaleX + environment.viewportRect.left,\n top: selection.top * scaleY + environment.viewportRect.top,\n width: selection.width * scaleX,\n height: selection.height * scaleY,\n };\n}\n\n/** Converts a host-space point back into target viewport coordinates. */\nexport function toTargetPoint(\n point: ReviewPoint,\n environment?: ReviewEnvironment\n) {\n if (!environment) return point;\n const { scaleX, scaleY } = getEnvironmentScale(environment);\n\n return {\n x: (point.x - environment.viewportRect.left) / scaleX,\n y: (point.y - environment.viewportRect.top) / scaleY,\n };\n}\n\n/** Extracts a host pointer event position as a target-space point. */\nexport function toTargetPointFromHostEvent(\n event: Pick<PointerEvent, 'clientX' | 'clientY'>,\n environment?: ReviewEnvironment\n) {\n return toTargetPoint(\n {\n x: event.clientX,\n y: event.clientY,\n },\n environment\n );\n}\n\n/** Sizes and positions an overlay layer to cover the target viewport in host space. */\nexport function placeLayerOverTarget(\n layer: HTMLElement,\n environment: ReviewEnvironment\n) {\n layer.style.left = `${environment.viewportRect.left}px`;\n layer.style.top = `${environment.viewportRect.top}px`;\n layer.style.width = `${environment.viewportRect.width}px`;\n layer.style.height = `${environment.viewportRect.height}px`;\n layer.style.right = 'auto';\n layer.style.bottom = 'auto';\n}\n\n/** Clamps a value even when max is smaller than min. */\nexport function clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), Math.max(min, max));\n}\n\n/** Keeps persisted relative coordinates stable without excessive precision. */\nexport function roundRatio(value: number) {\n // 4 decimal places: sub-pixel accurate at any realistic viewport size while\n // avoiding long floating-point tails in stored data.\n return Math.round(value * 10000) / 10000;\n}\n\n/** Rounds a point to pixel coordinates for persisted review data. */\nexport function roundPoint(point: ReviewPoint): ReviewPoint {\n return {\n x: Math.round(point.x),\n y: Math.round(point.y),\n };\n}\n","import type {\n DomAnchor,\n DomAnchorCandidate,\n DomSourceHint,\n RelativeSelection,\n ReviewPoint,\n} from '../types';\nimport {\n clamp,\n roundRatio,\n type ReviewEnvironment,\n type ViewportSelection,\n} from './geometry';\n\nconst COMMON_ANCHOR_ATTRIBUTES = [\n 'data-testid',\n 'data-test-id',\n 'data-cy',\n 'data-test',\n 'data-qa',\n 'data-section-id',\n 'data-component',\n];\n\nconst SEMANTIC_ANCHOR_ATTRIBUTES = [\n 'aria-label',\n 'title',\n 'name',\n 'href',\n];\n\n/** Builds the best DOM anchor candidate set from a target-space point. */\nexport function getDomAnchorFromPoint(\n point: ReviewPoint,\n configuredAttribute = 'data-qa-id',\n environment: ReviewEnvironment\n): DomAnchor | undefined {\n const target = environment.document.elementFromPoint(point.x, point.y);\n if (!target) return undefined;\n\n const candidates = createAnchorCandidates(target, configuredAttribute);\n const primaryCandidate = candidates[0];\n if (!primaryCandidate) return undefined;\n\n return {\n ...primaryCandidate,\n candidates,\n htmlSnippet: getElementHtmlSnippet(\n getAnchorSourceElement(target, primaryCandidate, configuredAttribute) ?? target\n ),\n source: getDomSourceHint(target),\n };\n}\n\n/** Builds the best DOM anchor candidate set from an exact target element. */\nexport function getDomAnchorFromElement(\n target: Element,\n configuredAttribute = 'data-qa-id',\n environment: ReviewEnvironment\n): DomAnchor | undefined {\n if (target.ownerDocument !== environment.document) return undefined;\n\n const candidates = createAnchorCandidates(target, configuredAttribute);\n const primaryCandidate = candidates[0];\n if (!primaryCandidate) return undefined;\n\n return {\n ...primaryCandidate,\n candidates,\n htmlSnippet: getElementHtmlSnippet(\n getAnchorSourceElement(target, primaryCandidate, configuredAttribute) ?? target\n ),\n source: getDomSourceHint(target),\n };\n}\n\n/** Reads the current target-space rectangle for a previously captured anchor. */\nexport function getElementViewportSelection(\n anchor: DomAnchor,\n environment: ReviewEnvironment,\n preferredSelection?: ViewportSelection\n): ViewportSelection | undefined {\n const element = getAnchorElement(anchor, environment, preferredSelection);\n if (!element) return undefined;\n\n const rect = element.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return undefined;\n\n return {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n}\n\n/** Stores a selection relative to an anchor so it can survive layout shifts. */\nexport function getRelativeSelection(\n selection: ViewportSelection,\n anchor: DomAnchor | string,\n environment: ReviewEnvironment\n): RelativeSelection | undefined {\n const element = getAnchorElement(anchor, environment);\n if (!element) return undefined;\n\n const rect = element.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return undefined;\n\n return {\n x: roundRatio((selection.left - rect.left) / rect.width),\n y: roundRatio((selection.top - rect.top) / rect.height),\n width: roundRatio(selection.width / rect.width),\n height: roundRatio(selection.height / rect.height),\n };\n}\n\n/** Stores a point relative to an anchor so marker positions can be rebound. */\nexport function getRelativePoint(\n point: ReviewPoint,\n anchor: DomAnchor | string,\n environment: ReviewEnvironment\n): ReviewPoint | undefined {\n const element = getAnchorElement(anchor, environment);\n if (!element) return undefined;\n\n const rect = element.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return undefined;\n\n return {\n x: roundRatio((point.x - rect.left) / rect.width),\n y: roundRatio((point.y - rect.top) / rect.height),\n };\n}\n\n/** Returns the primary anchor plus any fallback candidates without duplicates. */\nexport function getAnchorCandidates(anchor: DomAnchor) {\n return dedupeAnchorCandidates([\n anchor,\n ...(anchor.candidates ?? []),\n ]);\n}\n\n/** Finds the best current DOM element for a persisted anchor candidate set. */\nexport function resolveAnchorElement(\n anchor: DomAnchor,\n environment: ReviewEnvironment,\n preferredSelection?: ViewportSelection\n) {\n // Try every persisted candidate because IDs/classes can disappear between builds.\n const matches = getAnchorCandidates(anchor).flatMap((candidate) => {\n const textFingerprint = candidate.textFingerprint ?? anchor.textFingerprint;\n\n if (!preferredSelection) {\n const match = queryBestAnchorCandidate(\n candidate,\n textFingerprint,\n environment\n );\n\n if (!match) return [];\n\n const confidence = roundRatio(\n (candidate.confidence ?? 0.5) * match.score\n );\n\n return [{\n element: match.element,\n candidate,\n confidence,\n }];\n }\n\n return queryAnchorElements(candidate.selector, environment).map((element) => {\n const confidence = roundRatio(\n (candidate.confidence ?? 0.5) *\n getTextFingerprintScore(textFingerprint, getTextFingerprint(element)) *\n getSelectionMatchScore(element, preferredSelection)\n );\n\n return {\n element,\n candidate,\n confidence,\n };\n });\n });\n\n return matches.sort((a, b) => b.confidence - a.confidence)[0];\n}\n\n/** CSS.escape wrapper with a small fallback for older browsers. */\nexport function cssEscape(value: string) {\n if ('CSS' in window && typeof window.CSS.escape === 'function') {\n return window.CSS.escape(value);\n }\n\n return value.replace(/[^a-zA-Z0-9_-]/g, '\\\\$&');\n}\n\nfunction getAnchorElement(\n anchor: DomAnchor | string,\n environment: ReviewEnvironment,\n preferredSelection?: ViewportSelection\n) {\n return typeof anchor === 'string'\n ? queryAnchorElement(anchor, environment)\n : resolveAnchorElement(anchor, environment, preferredSelection)?.element;\n}\n\nfunction createAnchorCandidates(\n target: Element,\n configuredAttribute: string\n): DomAnchorCandidate[] {\n const targetCandidates: DomAnchorCandidate[] = [];\n\n // Prefer the deepest clicked element. Ancestor anchors are kept as fallbacks.\n const configuredAnchor = getExactAttributeAnchorCandidate(\n target,\n configuredAttribute,\n 0.98,\n 'configured-attribute'\n );\n if (configuredAnchor) targetCandidates.push(configuredAnchor);\n\n const targetAttributeAnchor = getAttributeAnchorCandidate(\n target,\n COMMON_ANCHOR_ATTRIBUTES.filter((name) => name !== configuredAttribute),\n 0.9\n );\n if (targetAttributeAnchor) targetCandidates.push(targetAttributeAnchor);\n\n if (isMeaningfulId(target.id)) {\n targetCandidates.push({\n selector: `#${cssEscape(target.id)}`,\n strategy: 'id',\n confidence: 0.94,\n textFingerprint: getTextFingerprint(target),\n });\n }\n\n const semanticAnchor = getAttributeAnchorCandidate(\n target,\n SEMANTIC_ANCHOR_ATTRIBUTES,\n 0.84\n );\n if (semanticAnchor) targetCandidates.push(semanticAnchor);\n\n const targetClassName = getMeaningfulClassName(target);\n if (targetClassName) {\n targetCandidates.push({\n selector: `${target.tagName.toLowerCase()}.${cssEscape(targetClassName)}`,\n strategy: 'class',\n confidence: 0.82,\n textFingerprint: getTextFingerprint(target),\n });\n }\n\n const scopedPath = getScopedDomPathCandidate(target, configuredAttribute);\n if (scopedPath) targetCandidates.push(scopedPath);\n\n const targetDomPath: DomAnchorCandidate = {\n selector: getDomPath(target),\n strategy: 'dom-path',\n confidence: targetCandidates.length > 0 ? 0.8 : 0.5,\n textFingerprint: getTextFingerprint(target),\n };\n\n const parentCandidates: DomAnchorCandidate[] = [];\n\n const parent = target.parentElement;\n const parentConfiguredAnchor = parent\n ? findClosestAttributeAnchor(parent, [configuredAttribute], 0.72, {\n strategy: 'configured-attribute',\n })\n : undefined;\n if (parentConfiguredAnchor) parentCandidates.push(parentConfiguredAnchor);\n\n const anchoredByAttribute = parent\n ? findClosestAttributeAnchor(\n parent,\n COMMON_ANCHOR_ATTRIBUTES.filter((name) => name !== configuredAttribute),\n 0.7\n )\n : undefined;\n if (anchoredByAttribute) parentCandidates.push(anchoredByAttribute);\n\n const anchoredById = parent\n ? findClosest(parent, (element) => isMeaningfulId(element.id))\n : undefined;\n if (anchoredById?.id) {\n parentCandidates.push({\n selector: `#${cssEscape(anchoredById.id)}`,\n strategy: 'id',\n confidence: 0.72,\n textFingerprint: getTextFingerprint(anchoredById),\n });\n }\n\n const anchoredByClass = parent\n ? findClosest(parent, (element) => Boolean(getMeaningfulClassName(element)))\n : undefined;\n const className = anchoredByClass\n ? getMeaningfulClassName(anchoredByClass)\n : undefined;\n\n if (anchoredByClass && className) {\n parentCandidates.push({\n selector: `${anchoredByClass.tagName.toLowerCase()}.${cssEscape(\n className\n )}`,\n strategy: 'class',\n confidence: 0.58,\n textFingerprint: getTextFingerprint(anchoredByClass),\n });\n }\n\n const candidates =\n targetCandidates.length > 0\n ? [...targetCandidates, targetDomPath, ...parentCandidates]\n : [...parentCandidates, targetDomPath];\n\n return dedupeAnchorCandidates(candidates);\n}\n\nfunction findClosestAttributeAnchor(\n target: Element,\n attributeNames: string[],\n confidence: number,\n options?: {\n strategy?: DomAnchorCandidate['strategy'];\n }\n): DomAnchorCandidate | undefined {\n for (const attributeName of attributeNames) {\n const selector = `[${attributeName}]`;\n const element = tryClosest(target, selector);\n if (!element) continue;\n\n const value = getStableAttributeValue(element, attributeName);\n if (!value) continue;\n\n return {\n selector: `[${attributeName}=\"${cssEscape(value)}\"]`,\n strategy: options?.strategy ?? 'attribute',\n confidence,\n textFingerprint: getTextFingerprint(element),\n };\n }\n\n return undefined;\n}\n\nfunction getExactAttributeAnchorCandidate(\n element: Element,\n attributeName: string,\n confidence: number,\n strategy: DomAnchorCandidate['strategy']\n): DomAnchorCandidate | undefined {\n const value = getStableAttributeValue(element, attributeName);\n if (!value) return undefined;\n\n return {\n selector: `[${attributeName}=\"${cssEscape(value)}\"]`,\n strategy,\n confidence,\n textFingerprint: getTextFingerprint(element),\n };\n}\n\nfunction getAttributeAnchorCandidate(\n element: Element,\n attributeNames: string[],\n confidence: number\n): DomAnchorCandidate | undefined {\n for (const attributeName of attributeNames) {\n const value = getStableAttributeValue(element, attributeName);\n if (!value) continue;\n\n return {\n selector: `${element.tagName.toLowerCase()}[${attributeName}=\"${cssEscape(\n value\n )}\"]`,\n strategy: 'attribute',\n confidence,\n textFingerprint: getTextFingerprint(element),\n };\n }\n\n return undefined;\n}\n\nfunction getScopedDomPathCandidate(\n target: Element,\n configuredAttribute: string\n): DomAnchorCandidate | undefined {\n const parent = target.parentElement;\n if (!parent) return undefined;\n\n const anchor = findStableAncestorSelector(parent, configuredAttribute);\n if (!anchor) return undefined;\n\n const selector = getDomPathBetween(anchor.element, target, anchor.selector);\n if (!selector) return undefined;\n\n return {\n selector,\n strategy: 'dom-path',\n confidence: anchor.confidence,\n textFingerprint: getTextFingerprint(target),\n };\n}\n\nfunction findStableAncestorSelector(\n start: Element,\n configuredAttribute: string\n) {\n let element: Element | null = start;\n const root = start.ownerDocument.documentElement;\n\n while (element && element !== root) {\n const configuredValue = getStableAttributeValue(element, configuredAttribute);\n if (configuredValue) {\n return {\n element,\n selector: `[${configuredAttribute}=\"${cssEscape(configuredValue)}\"]`,\n confidence: 0.88,\n };\n }\n\n const attributeAnchor = getAttributeAnchorCandidate(\n element,\n COMMON_ANCHOR_ATTRIBUTES.filter((name) => name !== configuredAttribute),\n 0.84\n );\n if (attributeAnchor) {\n return {\n element,\n selector: attributeAnchor.selector,\n confidence: 0.84,\n };\n }\n\n if (isMeaningfulId(element.id)) {\n return {\n element,\n selector: `#${cssEscape(element.id)}`,\n confidence: 0.82,\n };\n }\n\n const className = getMeaningfulClassName(element);\n if (className) {\n return {\n element,\n selector: `${element.tagName.toLowerCase()}.${cssEscape(className)}`,\n confidence: 0.76,\n };\n }\n\n element = element.parentElement;\n }\n\n return undefined;\n}\n\nfunction getAnchorSourceElement(\n target: Element,\n candidate: DomAnchorCandidate,\n configuredAttribute: string\n) {\n if (candidate.strategy === 'configured-attribute') {\n return target.closest(`[${configuredAttribute}]`);\n }\n\n if (candidate.strategy === 'dom-path') return target;\n\n try {\n return target.closest(candidate.selector);\n } catch {\n return target;\n }\n}\n\nfunction tryClosest(element: Element, selector: string) {\n try {\n return element.closest(selector);\n } catch {\n return null;\n }\n}\n\nfunction getElementHtmlSnippet(element: Element, maxLength = 1000) {\n const html = decodeHtmlEntities(element.outerHTML.replace(/\\s+/g, ' ').trim());\n if (html.length <= maxLength) return html;\n return `${html.slice(0, maxLength - 3)}...`;\n}\n\nfunction decodeHtmlEntities(value: string) {\n return value.replace(\n /&(#\\d+|#x[\\da-f]+|lt|gt|quot|apos|amp);/gi,\n (match, entity: string) => {\n const normalized = entity.toLowerCase();\n\n if (normalized === 'lt') return '<';\n if (normalized === 'gt') return '>';\n if (normalized === 'quot') return '\"';\n if (normalized === 'apos') return \"'\";\n if (normalized === 'amp') return '&';\n\n const codePoint = normalized.startsWith('#x')\n ? Number.parseInt(normalized.slice(2), 16)\n : Number.parseInt(normalized.slice(1), 10);\n\n return Number.isFinite(codePoint)\n ? String.fromCodePoint(codePoint)\n : match;\n }\n );\n}\n\nfunction getDomSourceHint(target: Element): DomSourceHint | undefined {\n const sourceElement = target.closest(\n [\n '[data-wrk-source-file]',\n '[data-wrk-source-component]',\n '[data-wrk-source-line]',\n '[data-wrk-source-column]',\n '[data-file]',\n '[data-component]',\n '[data-section-index]',\n '[data-section-id]',\n ].join(', ')\n );\n if (!sourceElement) return undefined;\n\n const source: DomSourceHint = {\n component: getSourceAttribute(\n sourceElement,\n 'data-wrk-source-component',\n 'data-component'\n ),\n file: getSourceAttribute(sourceElement, 'data-wrk-source-file', 'data-file'),\n line: getSourceAttribute(sourceElement, 'data-wrk-source-line'),\n column: getSourceAttribute(sourceElement, 'data-wrk-source-column'),\n sectionId: getSourceAttribute(sourceElement, 'data-section-id'),\n sectionIndex: getSourceAttribute(sourceElement, 'data-section-index'),\n };\n\n return Object.values(source).some(Boolean) ? source : undefined;\n}\n\nfunction getSourceAttribute(element: Element, ...names: string[]) {\n for (const name of names) {\n const value = element.getAttribute(name)?.trim();\n if (value) return value;\n }\n\n return undefined;\n}\n\nfunction dedupeAnchorCandidates(candidates: DomAnchorCandidate[]) {\n const seen = new Set<string>();\n\n return candidates.filter((candidate) => {\n const key = `${candidate.strategy}:${candidate.selector}`;\n if (seen.has(key)) return false;\n\n seen.add(key);\n return true;\n });\n}\n\nfunction queryBestAnchorCandidate(\n candidate: DomAnchorCandidate,\n textFingerprint: string | undefined,\n environment: ReviewEnvironment\n) {\n const elements = queryAnchorElements(candidate.selector, environment);\n if (elements.length === 0) return undefined;\n if (!textFingerprint) {\n return {\n element: elements[0],\n score: 1,\n };\n }\n\n // If a selector matches multiple nodes, text similarity keeps restore deterministic.\n return elements\n .map((element) => ({\n element,\n score: getTextFingerprintScore(\n textFingerprint,\n getTextFingerprint(element)\n ),\n }))\n .sort((a, b) => b.score - a.score)[0];\n}\n\nfunction queryAnchorElement(selector: string, environment: ReviewEnvironment) {\n return queryAnchorElements(selector, environment)[0];\n}\n\nfunction queryAnchorElements(selector: string, environment: ReviewEnvironment) {\n try {\n return Array.from(environment.document.querySelectorAll(selector));\n } catch {\n return [];\n }\n}\n\nfunction findClosest(\n start: Element,\n predicate: (element: Element) => boolean\n) {\n let element: Element | null = start;\n const root = start.ownerDocument.documentElement;\n\n while (element && element !== root) {\n if (predicate(element)) return element;\n element = element.parentElement;\n }\n\n return undefined;\n}\n\n// Builds an absolute CSS selector from <body> down to the element.\n// Each step uses :nth-of-type so the path stays stable even when siblings\n// share the same tag and carry no id/class to anchor on.\nfunction getDomPath(element: Element) {\n const parts: string[] = [];\n let current: Element | null = element;\n const ownerDocument = element.ownerDocument;\n\n while (\n current &&\n current !== ownerDocument.body &&\n current !== ownerDocument.documentElement\n ) {\n const parent: Element | null = current.parentElement;\n const tag = current.tagName.toLowerCase();\n\n if (!parent) {\n parts.unshift(tag);\n break;\n }\n\n const currentTagName = current.tagName;\n const siblings: Element[] = Array.from(parent.children).filter(\n (child) => child.tagName === currentTagName\n );\n const index = siblings.indexOf(current) + 1;\n parts.unshift(`${tag}:nth-of-type(${index})`);\n current = parent;\n }\n\n return `body > ${parts.join(' > ')}`;\n}\n\n// Like getDomPath but relative: the selector is scoped under a known ancestor\n// (e.g. an element with a stable attribute) so it survives layout changes above\n// that ancestor. Returns undefined if target is not actually inside ancestor.\nfunction getDomPathBetween(\n ancestor: Element,\n target: Element,\n ancestorSelector: string\n) {\n const parts: string[] = [];\n let current: Element | null = target;\n\n while (current && current !== ancestor) {\n parts.unshift(getDomPathPart(current));\n current = current.parentElement;\n }\n\n if (current !== ancestor || parts.length === 0) return undefined;\n\n return `${ancestorSelector} > ${parts.join(' > ')}`;\n}\n\nfunction getDomPathPart(element: Element) {\n const parent: Element | null = element.parentElement;\n const tag = element.tagName.toLowerCase();\n\n if (!parent) return tag;\n\n const currentTagName = element.tagName;\n const siblings: Element[] = Array.from(parent.children).filter(\n (child) => child.tagName === currentTagName\n );\n const index = siblings.indexOf(element) + 1;\n return `${tag}:nth-of-type(${index})`;\n}\n\nfunction getTextFingerprint(element: Element) {\n const text = element.textContent?.replace(/\\s+/g, ' ').trim();\n // Cap at 120 chars: enough to identify the element, short enough to keep\n // stored anchors small and to tolerate minor trailing-content edits.\n return text ? text.slice(0, 120) : undefined;\n}\n\n// Returns an attribute value only if it looks like a stable identifier.\n// Rejects overly long values (>160 chars, likely generated/serialized data),\n// booleans, and short numeric values (1-2 digits, likely volatile indexes).\nfunction getStableAttributeValue(element: Element, attributeName: string) {\n const value = element.getAttribute(attributeName)?.trim();\n if (!value || value.length > 160) return undefined;\n if (/^(true|false)$/i.test(value)) return undefined;\n if (/^\\d+$/.test(value) && value.length < 3) return undefined;\n\n return value;\n}\n\n// Scores how well a candidate's text matches the fingerprint captured earlier.\n// Tiered confidence: exact match = 1, substring containment = 0.82, otherwise\n// a token-overlap ratio. Missing data returns a neutral 0.5 so it neither\n// confirms nor rules out the candidate.\nfunction getTextFingerprintScore(expected?: string, actual?: string) {\n if (!expected) return 1;\n if (!actual) return 0.5;\n if (expected === actual) return 1;\n if (actual.includes(expected) || expected.includes(actual)) return 0.82;\n\n const expectedTokens = getFingerprintTokens(expected);\n const actualTokens = new Set(getFingerprintTokens(actual));\n if (expectedTokens.length === 0 || actualTokens.size === 0) return 0.5;\n\n const matches = expectedTokens.filter((token) => actualTokens.has(token));\n return clamp(matches.length / expectedTokens.length, 0.25, 0.76);\n}\n\n// Scores how well an element's box matches the original selection rectangle.\n// Overlapping elements score >1 (1 + overlap ratio) so any overlap always beats\n// the non-overlapping branch, which falls back to a center-distance score in\n// (0.05, 0.95). This keeps the closest enclosing element ranked highest.\nfunction getSelectionMatchScore(\n element: Element,\n selection: ViewportSelection\n) {\n const rect = element.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return 0.05;\n\n const overlapLeft = Math.max(rect.left, selection.left);\n const overlapTop = Math.max(rect.top, selection.top);\n const overlapRight = Math.min(rect.right, selection.left + selection.width);\n const overlapBottom = Math.min(rect.bottom, selection.top + selection.height);\n const overlapWidth = Math.max(0, overlapRight - overlapLeft);\n const overlapHeight = Math.max(0, overlapBottom - overlapTop);\n const overlapArea = overlapWidth * overlapHeight;\n\n if (overlapArea > 0) {\n const selectionArea = Math.max(1, selection.width * selection.height);\n const rectArea = Math.max(1, rect.width * rect.height);\n return 1 + overlapArea / Math.min(selectionArea, rectArea);\n }\n\n const rectCenterX = rect.left + rect.width / 2;\n const rectCenterY = rect.top + rect.height / 2;\n const selectionCenterX = selection.left + selection.width / 2;\n const selectionCenterY = selection.top + selection.height / 2;\n const distance = Math.hypot(\n rectCenterX - selectionCenterX,\n rectCenterY - selectionCenterY\n );\n const basis = Math.max(\n 1,\n rect.width,\n rect.height,\n selection.width,\n selection.height\n );\n\n return clamp(1 / (1 + distance / basis), 0.05, 0.95);\n}\n\nfunction getFingerprintTokens(value: string) {\n return value\n .toLowerCase()\n .split(/[\\s/|,.:;()[\\]{}\"'`~!?<>]+/)\n .map((token) => token.trim())\n .filter((token) => token.length > 1);\n}\n\nfunction isMeaningfulId(value: string) {\n const normalized = value.trim().toLowerCase();\n if (normalized.length <= 1) return false;\n\n return ![\n 'app',\n 'main',\n 'page',\n 'root',\n '__next',\n '__nuxt',\n ].includes(normalized);\n}\n\nfunction getMeaningfulClassName(element: Element) {\n return Array.from(element.classList).find((name) => isMeaningfulClass(name));\n}\n\nfunction isMeaningfulClass(value: string) {\n const normalized = value.trim();\n if (\n [\n 'absolute',\n 'block',\n 'contents',\n 'fixed',\n 'flex',\n 'grid',\n 'hidden',\n 'relative',\n 'sticky',\n ].includes(normalized)\n ) {\n return false;\n }\n\n return (\n normalized.length > 2 &&\n !normalized.includes(':') &&\n !/^(aspect|basis|bg|border|bottom|col|content|delay|duration|ease|font|from|gap|grow|h|inset|items|justify|leading|left|m|max-h|max-w|mb|ml|mr|mt|mx|my|min-h|min-w|object|opacity|order|origin|overflow|p|pb|pl|place|pointer|pr|pt|px|py|right|rotate|rounded|row|scale|self|shadow|shrink|text|to|top|tracking|transition|translate|via|w|z)-/.test(\n normalized\n ) &&\n !normalized.startsWith('mq-')\n );\n}\n","/** Creates a stable item id with crypto UUID when available. */\nexport function createId() {\n if ('randomUUID' in crypto) return crypto.randomUUID();\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n","const HOTKEY_KEY_ALIASES: Record<string, string[]> = {\n q: ['ㅂ', 'ㅃ'],\n w: ['ㅈ', 'ㅉ'],\n e: ['ㄷ', 'ㄸ'],\n r: ['ㄱ', 'ㄲ'],\n t: ['ㅅ', 'ㅆ'],\n y: ['ㅛ'],\n u: ['ㅕ'],\n i: ['ㅑ'],\n o: ['ㅐ', 'ㅒ'],\n p: ['ㅔ', 'ㅖ'],\n a: ['ㅁ'],\n s: ['ㄴ'],\n d: ['ㅇ'],\n f: ['ㄹ'],\n g: ['ㅎ'],\n h: ['ㅗ'],\n j: ['ㅓ'],\n k: ['ㅏ'],\n l: ['ㅣ'],\n z: ['ㅋ'],\n x: ['ㅌ'],\n c: ['ㅊ'],\n v: ['ㅍ'],\n b: ['ㅠ'],\n n: ['ㅜ'],\n m: ['ㅡ'],\n};\n\n/** Matches configured hotkeys while supporting common Korean keyboard aliases. */\nexport function isHotkey(event: KeyboardEvent, hotkey: string) {\n const parts = hotkey\n .split('+')\n .map((part) => part.trim().toLowerCase())\n .filter(Boolean);\n const key = parts.find(\n (part) => !['shift', 'ctrl', 'control', 'alt', 'meta', 'cmd'].includes(part)\n );\n\n if (!key) return false;\n if (parts.includes('shift') !== event.shiftKey) return false;\n if (\n (parts.includes('ctrl') || parts.includes('control')) !== event.ctrlKey\n ) {\n return false;\n }\n if (parts.includes('alt') !== event.altKey) return false;\n if ((parts.includes('meta') || parts.includes('cmd')) !== event.metaKey) {\n return false;\n }\n\n return isHotkeyKey(event, key);\n}\n\nexport function getHotkeyActionKey(\n event: KeyboardEvent,\n keys: readonly string[]\n) {\n return keys.find((key) => isHotkeyKey(event, key));\n}\n\nexport function isHotkeyKey(event: KeyboardEvent, key: string) {\n const normalizedKey = key.toLowerCase();\n\n if (event.key.toLowerCase() === normalizedKey) return true;\n\n if (getHotkeyCode(normalizedKey) === event.code) return true;\n\n return HOTKEY_KEY_ALIASES[normalizedKey]?.includes(event.key) ?? false;\n}\n\nfunction getHotkeyCode(key: string) {\n if (/^[a-z]$/.test(key)) return `Key${key.toUpperCase()}`;\n if (/^[0-9]$/.test(key)) return `Digit${key}`;\n return undefined;\n}\n","import { normalizeRoutePath } from '../route';\nimport type { ReviewEnvironment } from './geometry';\n\nconst INTERNAL_QUERY_PARAMS = ['__dfwr_target'];\n\n/** Returns the public target URL without review-only query params. */\nexport function getPageUrl(environment?: ReviewEnvironment) {\n const location = environment?.window.location ?? window.location;\n const search = getPublicSearch(location);\n return `${location.origin}${location.pathname}${search}${location.hash}`;\n}\n\n/** Mirrors page URL today, kept separate for future canonical/original URL support. */\nexport function getOriginalUrl(environment?: ReviewEnvironment) {\n const location = environment?.window.location ?? window.location;\n const search = getPublicSearch(location);\n return `${location.origin}${location.pathname}${search}${location.hash}`;\n}\n\n/** Returns the normalized route key used for adapter queries. */\nexport function getRouteKey(environment?: ReviewEnvironment) {\n const location = environment?.window.location ?? window.location;\n return normalizeRoutePath(location.pathname);\n}\n\n\nfunction getPublicSearch(location: Location) {\n const params = new URLSearchParams(location.search);\n\n INTERNAL_QUERY_PARAMS.forEach((key) => params.delete(key));\n\n const value = params.toString();\n return value ? `?${value}` : '';\n}\n","import type {\n DomAnchor,\n RelativeSelection,\n ReviewItem,\n ReviewItemScope,\n ReviewMarker,\n ReviewSelection,\n} from '../../types';\nimport {\n getElementViewportSelection,\n getRelativePoint,\n resolveAnchorElement,\n} from '../dom.anchor';\nimport {\n isRelativeSelection,\n isSelectionInViewport,\n roundPoint,\n toViewportSelection,\n type ReviewEnvironment,\n type ViewportSelection,\n} from '../geometry';\n\n/** Rendering mode used by marker and highlight overlays. */\nexport type ReviewItemHighlightMode = 'area' | 'dom';\n\n/** Target-space highlight rectangle plus whether it was rebound to an anchor. */\nexport interface ReviewItemHighlightSelection {\n viewport: ViewportSelection;\n isBound: boolean;\n}\n\n/** Resolves a review marker to its current viewport point, with scroll fallback. */\nexport function getBoundMarkerPoint(\n item: ReviewItem,\n environment: ReviewEnvironment\n) {\n const marker = getItemMarker(item);\n if (!marker) return undefined;\n\n // Prefer anchor-relative positions because absolute viewport points drift after layout changes.\n if (item.anchor && marker.relative) {\n const resolved = resolveAnchorElement(item.anchor, environment);\n const element = resolved?.element;\n\n if (element) {\n const rect = element.getBoundingClientRect();\n\n if (rect.width > 0 && rect.height > 0) {\n return {\n viewport: roundPoint({\n x: rect.left + rect.width * marker.relative.x,\n y: rect.top + rect.height * marker.relative.y,\n }),\n isBound: true,\n confidence: resolved.confidence,\n selector: resolved.candidate.selector,\n };\n }\n }\n }\n\n const sourceScroll = item.scroll ?? { x: 0, y: 0 };\n\n return {\n viewport: roundPoint({\n x: marker.viewport.x + sourceScroll.x - environment.window.scrollX,\n y: marker.viewport.y + sourceScroll.y - environment.window.scrollY,\n }),\n isBound: false,\n confidence: 0,\n };\n}\n\n/** Chooses the best visible highlight selection for the current target viewport. */\nexport function getItemHighlightSelection(\n item: ReviewItem,\n environment: ReviewEnvironment\n): ReviewItemHighlightSelection | undefined {\n if (item.kind === 'area') {\n return getVisibleHighlightSelection(\n [\n getBoundSelection(item, environment),\n getPointHighlightSelection(item, environment),\n ],\n environment\n );\n }\n\n if (isDomReviewItem(item)) {\n return getVisibleHighlightSelection(\n [\n getAnchorHighlightSelection(item, environment),\n getBoundSelection(item, environment),\n getPointHighlightSelection(item, environment),\n ],\n environment\n );\n }\n\n return undefined;\n}\n\n/** Maps an item to its overlay visual treatment. */\nexport function getReviewItemHighlightMode(\n item: ReviewItem\n): ReviewItemHighlightMode {\n if (isDomReviewItem(item)) return 'dom';\n return 'area';\n}\n\n/** Returns an explicit marker or derives one from the item's selection origin. */\nexport function getItemMarker(item: ReviewItem): ReviewMarker | undefined {\n if (item.marker) return item.marker;\n\n const selection = getItemSelection(item);\n if (!selection?.viewport) return undefined;\n\n return {\n viewport: roundPoint({\n x: selection.viewport.x,\n y: selection.viewport.y,\n }),\n relative: selection.relative\n ? roundPoint({\n x: selection.relative.x,\n y: selection.relative.y,\n })\n : undefined,\n };\n}\n\n/** Normalizes current and legacy selection shapes into ReviewSelection. */\nexport function getItemSelection(item: ReviewItem): ReviewSelection | undefined {\n const value = item.selection as\n | ReviewSelection\n | RelativeSelection\n | undefined;\n if (!value) return undefined;\n\n if ('viewport' in value && isRelativeSelection(value.viewport)) {\n return value;\n }\n\n if (isRelativeSelection(value)) {\n return {\n viewport: value,\n };\n }\n\n return undefined;\n}\n\n/** Filters markers to the active viewport scope. */\nexport function shouldShowMarkerForScope(\n scope: ReviewItemScope,\n currentScope: ReviewItemScope\n) {\n return scope === currentScope;\n}\n\n/** Creates a marker at the selection origin and stores an anchor-relative fallback. */\nexport function createSelectionStartMarker(\n selection: ViewportSelection,\n anchor: DomAnchor | undefined,\n environment: ReviewEnvironment\n): ReviewMarker {\n const startPoint = {\n x: selection.left,\n y: selection.top,\n };\n\n return {\n viewport: roundPoint(startPoint),\n relative: anchor\n ? getRelativePoint(startPoint, anchor, environment)\n : undefined,\n };\n}\n\nfunction getBoundSelection(item: ReviewItem, environment: ReviewEnvironment) {\n const selection = getItemSelection(item);\n if (!selection?.viewport) return undefined;\n\n // Rebuild the rectangle from the anchor when possible, then fall back to scroll offset.\n if (item.anchor && selection.relative) {\n const resolved = resolveAnchorElement(item.anchor, environment);\n const element = resolved?.element;\n\n if (element) {\n const rect = element.getBoundingClientRect();\n\n if (rect.width > 0 && rect.height > 0) {\n return {\n viewport: {\n left: rect.left + rect.width * selection.relative.x,\n top: rect.top + rect.height * selection.relative.y,\n width: rect.width * selection.relative.width,\n height: rect.height * selection.relative.height,\n },\n isBound: true,\n confidence: resolved.confidence,\n selector: resolved.candidate.selector,\n };\n }\n }\n }\n\n const sourceScroll = item.scroll ?? { x: 0, y: 0 };\n const viewportSelection = toViewportSelection(selection.viewport);\n\n return {\n viewport: {\n left: viewportSelection.left + sourceScroll.x - environment.window.scrollX,\n top: viewportSelection.top + sourceScroll.y - environment.window.scrollY,\n width: viewportSelection.width,\n height: viewportSelection.height,\n },\n isBound: item.kind === 'area',\n confidence: 0,\n };\n}\n\nfunction getAnchorHighlightSelection(\n item: ReviewItem,\n environment: ReviewEnvironment\n): ReviewItemHighlightSelection | undefined {\n if (!item.anchor) return undefined;\n\n const viewport = getElementViewportSelection(item.anchor, environment);\n if (!viewport) return undefined;\n\n return {\n viewport,\n isBound: true,\n };\n}\n\nfunction getPointHighlightSelection(\n item: ReviewItem,\n environment: ReviewEnvironment\n): ReviewItemHighlightSelection | undefined {\n const point = getBoundMarkerPoint(item, environment);\n if (!point) return undefined;\n\n const size = 16;\n return {\n viewport: {\n left: point.viewport.x - size / 2,\n top: point.viewport.y - size / 2,\n width: size,\n height: size,\n },\n isBound: point.isBound,\n };\n}\n\nfunction getVisibleHighlightSelection(\n candidates: Array<ReviewItemHighlightSelection | undefined>,\n environment: ReviewEnvironment\n): ReviewItemHighlightSelection | undefined {\n // Candidate order encodes item-type priority; this only discards offscreen options.\n return candidates.find(\n (candidate): candidate is ReviewItemHighlightSelection =>\n Boolean(candidate && isSelectionInViewport(candidate.viewport, environment))\n );\n}\n\nfunction isDomReviewItem(item: ReviewItem) {\n return item.kind === 'dom' || item.scope === 'dom';\n}\n","import type { ReviewEnvironment } from './geometry';\n\n/** Waits one target animation frame before reading/restoring overlay state. */\nexport function waitForNextFrame(environment?: ReviewEnvironment) {\n return new Promise<void>((resolve) => {\n (environment?.window ?? window).requestAnimationFrame(() => resolve());\n });\n}\n\n/** Temporarily disables smooth scroll so restore lands synchronously. */\nexport function runWithAutoScrollBehavior(\n targetDocument: Document,\n callback: () => void\n) {\n const elements = [\n targetDocument.documentElement,\n targetDocument.body,\n ].filter((element): element is HTMLElement => Boolean(element));\n const previousValues = elements.map((element) => element.style.scrollBehavior);\n\n elements.forEach((element) => {\n element.style.scrollBehavior = 'auto';\n });\n\n try {\n callback();\n } finally {\n elements.forEach((element, index) => {\n element.style.scrollBehavior = previousValues[index] ?? '';\n });\n }\n}\n\n/** Restores target document scroll without relying on smooth scrolling behavior. */\nexport function setDocumentScrollInstantly(\n environment: ReviewEnvironment,\n position: { x: number; y: number }\n) {\n const scrollElement = environment.document.scrollingElement as HTMLElement | null;\n\n if (scrollElement) {\n scrollElement.scrollLeft = Math.max(0, Math.round(position.x));\n scrollElement.scrollTop = Math.max(0, Math.round(position.y));\n return;\n }\n\n environment.window.scrollTo(\n Math.max(0, Math.round(position.x)),\n Math.max(0, Math.round(position.y))\n );\n}\n","// Pure geometry for draft \"adjustment\" (nudge/scale) previews.\n// Extracted from web.review.kit.view.ts so the renderer keeps only DOM wiring.\n// Each function takes the viewport presets explicitly instead of reading config,\n// which keeps them side-effect free and unit-testable.\nimport type { ReviewPoint, ReviewViewportPreset, ViewportSize } from '../types';\nimport type { DomDraft } from './review/draft';\nimport { toViewportSelection, type ViewportSelection } from './geometry';\nimport { findReviewViewportPreset } from './review/scope';\n\nexport interface DraftAdjustmentMetrics {\n x: number;\n y: number;\n scale: number;\n cssX: number;\n cssY: number;\n scaleFactor: number;\n viewportScale: number;\n designWidth: number;\n presetLabel: string;\n viewportWidth: number;\n}\n\n// Maps a viewport size to the matching preset's design scale.\nexport function getDraftViewportScale(\n viewport: ViewportSize,\n presets?: ReviewViewportPreset[]\n) {\n const preset = findReviewViewportPreset(viewport, presets);\n const designWidth =\n typeof preset.designWidth === 'number' && preset.designWidth > 0\n ? preset.designWidth\n : viewport.width;\n const scale = designWidth > 0 ? viewport.width / designWidth : 1;\n\n return { scale, designWidth, presetLabel: preset.label };\n}\n\n// Resolves the raw adjustment (design-space x/y/scale) into CSS-space deltas.\nexport function getDraftAdjustmentMetrics(\n draft: DomDraft,\n presets?: ReviewViewportPreset[]\n): DraftAdjustmentMetrics {\n const adjustment = draft.adjustment;\n const x = adjustment?.x ?? 0;\n const y = adjustment?.y ?? 0;\n const scale = adjustment?.scale ?? 0;\n const {\n scale: viewportScale,\n designWidth,\n presetLabel,\n } = getDraftViewportScale(draft.viewport, presets);\n const selection = draft.selection\n ? toViewportSelection(draft.selection.viewport)\n : undefined;\n const scaleCssDelta = scale * viewportScale;\n const scaleFactor =\n selection && selection.width > 0\n ? Math.max(\n 1 / selection.width,\n (selection.width + scaleCssDelta) / selection.width\n )\n : 1;\n\n return {\n x,\n y,\n scale,\n cssX: x * viewportScale,\n cssY: y * viewportScale,\n scaleFactor,\n viewportScale,\n designWidth,\n presetLabel,\n viewportWidth: draft.viewport.width,\n };\n}\n\nexport function hasDraftAdjustment(\n draft: DomDraft,\n presets?: ReviewViewportPreset[]\n) {\n const metrics = getDraftAdjustmentMetrics(draft, presets);\n return metrics.x !== 0 || metrics.y !== 0 || metrics.scale !== 0;\n}\n\nexport function getAdjustedDraftPoint(\n point: ReviewPoint,\n draft: DomDraft,\n presets?: ReviewViewportPreset[]\n) {\n const metrics = getDraftAdjustmentMetrics(draft, presets);\n return {\n x: point.x + metrics.cssX,\n y: point.y + metrics.cssY,\n };\n}\n\nexport function getAdjustedDraftSelection(\n selection: ViewportSelection,\n draft: DomDraft,\n presets?: ReviewViewportPreset[]\n) {\n const metrics = getDraftAdjustmentMetrics(draft, presets);\n return {\n ...selection,\n left: selection.left + metrics.cssX,\n top: selection.top + metrics.cssY,\n width: selection.width * metrics.scaleFactor,\n height: selection.height * metrics.scaleFactor,\n };\n}\n","import type { ReviewEnvironment } from './geometry';\nimport { toViewportSelection } from './geometry';\nimport { resolveAnchorElement } from './dom.anchor';\nimport type { DraftAdjustmentMetrics } from './draft.metrics';\nimport type { DomDraft, ReviewDraftPreviewElement } from './review/draft';\n\ninterface DraftPreviewControllerConfig {\n getEnvironment: () => ReviewEnvironment | undefined;\n getMetrics: (draft: DomDraft) => DraftAdjustmentMetrics;\n hasAdjustment: (draft: DomDraft) => boolean;\n}\n\ninterface DraftPreviewSnapshot {\n element: ReviewDraftPreviewElement;\n clone: ReviewDraftPreviewElement;\n visibility: string;\n}\n\nexport class DraftPreviewController {\n private snapshot?: DraftPreviewSnapshot;\n\n constructor(private readonly config: DraftPreviewControllerConfig) {}\n\n clear() {\n if (!this.snapshot) return;\n\n const { element, clone, visibility } = this.snapshot;\n clone.remove();\n element.style.visibility = visibility;\n this.snapshot = undefined;\n }\n\n sync(draft?: DomDraft) {\n const environment = this.config.getEnvironment();\n if (!draft || !environment || !this.config.hasAdjustment(draft)) {\n this.clear();\n return;\n }\n\n const element = this.getStyleableDraftElement(draft, environment);\n if (!element) {\n this.clear();\n return;\n }\n\n if (this.snapshot?.element !== element) {\n this.clear();\n }\n\n if (!this.snapshot) {\n const computedStyle = environment.window.getComputedStyle(element);\n const clone = element.cloneNode(true) as ReviewDraftPreviewElement;\n removeDuplicateIds(clone);\n copyComputedStyle(element, clone, environment);\n positionDraftPreviewClone(clone, element, computedStyle);\n environment.document.body?.appendChild(clone);\n this.snapshot = {\n element,\n clone,\n visibility: element.style.visibility,\n };\n element.style.visibility = 'hidden';\n }\n\n const metrics = this.config.getMetrics(draft);\n const translate = `translate(${toCssNumber(metrics.cssX)}px, ${toCssNumber(\n metrics.cssY\n )}px)`;\n const scale =\n metrics.scaleFactor === 1\n ? ''\n : `scale(${toCssNumber(metrics.scaleFactor)})`;\n this.snapshot.clone.style.transform = [translate, scale]\n .filter(Boolean)\n .join(' ');\n }\n\n private getStyleableDraftElement(\n draft: DomDraft,\n environment: ReviewEnvironment\n ): ReviewDraftPreviewElement | undefined {\n if (\n draft.previewElement &&\n draft.previewElement.ownerDocument === environment.document &&\n 'style' in draft.previewElement\n ) {\n return draft.previewElement;\n }\n\n if (!draft.anchor) return undefined;\n\n const preferredSelection = draft.selection\n ? toViewportSelection(draft.selection.viewport)\n : undefined;\n const element = resolveAnchorElement(\n draft.anchor,\n environment,\n preferredSelection\n )?.element;\n if (!element) return undefined;\n\n if ('style' in element) return element as ReviewDraftPreviewElement;\n\n return undefined;\n }\n}\n\nfunction positionDraftPreviewClone(\n clone: ReviewDraftPreviewElement,\n element: ReviewDraftPreviewElement,\n computedStyle: CSSStyleDeclaration\n) {\n const rect = element.getBoundingClientRect();\n clone.setAttribute('data-dfwr-adjust-preview', 'true');\n clone.setAttribute('aria-hidden', 'true');\n clone.style.position = 'fixed';\n clone.style.left = `${toCssNumber(rect.left)}px`;\n clone.style.top = `${toCssNumber(rect.top)}px`;\n clone.style.right = 'auto';\n clone.style.bottom = 'auto';\n clone.style.width = `${toCssNumber(rect.width)}px`;\n clone.style.height = `${toCssNumber(rect.height)}px`;\n clone.style.maxWidth = 'none';\n clone.style.maxHeight = 'none';\n clone.style.margin = '0';\n clone.style.boxSizing = 'border-box';\n clone.style.display = getDraftPreviewDisplay(computedStyle.display);\n clone.style.zIndex = '2147483646';\n clone.style.pointerEvents = 'none';\n clone.style.transition = 'none';\n clone.style.willChange = 'transform';\n clone.style.transformOrigin = 'top left';\n clone.style.transform = 'none';\n}\n\nfunction getDraftPreviewDisplay(display: string) {\n if (display === 'inline' || display === 'contents') return 'inline-block';\n return display || 'block';\n}\n\nfunction copyComputedStyle(\n element: ReviewDraftPreviewElement,\n clone: ReviewDraftPreviewElement,\n environment: ReviewEnvironment\n) {\n const computedStyle = environment.window.getComputedStyle(element);\n for (let index = 0; index < computedStyle.length; index += 1) {\n const property = computedStyle.item(index);\n clone.style.setProperty(\n property,\n computedStyle.getPropertyValue(property),\n computedStyle.getPropertyPriority(property)\n );\n }\n}\n\nfunction removeDuplicateIds(element: Element) {\n element.removeAttribute('id');\n element.querySelectorAll('[id]').forEach((child) => {\n child.removeAttribute('id');\n });\n}\n\nfunction toCssNumber(value: number) {\n return Math.round(value * 1000) / 1000;\n}\n","/**\n * Single source of truth for review-kit typography tokens.\n *\n * Edit font sizes / weights here once; both the React shell chrome\n * (style/base.ts → body) and the in-page overlay (overlay.style.ts → :host)\n * consume the same declarations. This is a debug surface, so sizes stay small.\n * Weights are intentionally flat: `normal` for everything, `emphasis` for the\n * few elements that must stand out.\n */\nexport const reviewTypographyTokens = `\n --df-review-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --df-review-font-mono: \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, monospace;\n --df-review-font-size-3xs: 9px;\n --df-review-font-size-2xs: 10px;\n --df-review-font-size-xs: 11px;\n --df-review-font-size-sm: 12px;\n --df-review-font-size-md: 13px;\n --df-review-font-size-lg: 14px;\n --df-review-font-size-xl: 15px;\n --df-review-font-size-2xl: 18px;\n --df-review-font-weight-normal: 400;\n --df-review-font-weight-emphasis: 500;\n --df-review-line-height-tight: 1.25;\n --df-review-line-height-base: 1.42;\n --df-review-line-height-relaxed: 1.55;\n`;\n","import { reviewTypographyTokens } from './typography.tokens';\n\n/** Creates the shadow-root stylesheet for the standalone core overlay. */\nexport function createStyleElement() {\n const style = document.createElement('style');\n style.textContent = `\n :host {\n color-scheme: dark;\n ${reviewTypographyTokens}\n --df-review-space-1: 4px;\n --df-review-space-1-5: 6px;\n --df-review-space-2: 8px;\n --df-review-space-2-5: 10px;\n --df-review-space-3: 12px;\n --df-review-space-3-5: 14px;\n --df-review-space-4: 16px;\n --df-review-control-height-sm: 32px;\n --df-review-control-height-md: 34px;\n --df-review-radius-xs: 3px;\n --df-review-radius-sm: 6px;\n --df-review-radius-md: 8px;\n --df-review-radius-pill: 999px;\n --df-review-color-canvas: #111820;\n --df-review-color-panel: #1f2428;\n --df-review-color-panel-strong: #15191d;\n --df-review-color-control: #2c3338;\n --df-review-color-control-hover: #3b444b;\n --df-review-color-border: rgba(255, 255, 255, 0.14);\n --df-review-color-border-strong: rgba(255, 255, 255, 0.18);\n --df-review-color-text: #f7f7f2;\n --df-review-color-text-muted: rgba(247, 247, 242, 0.62);\n --df-review-color-text-subtle: rgba(247, 247, 242, 0.46);\n --df-review-color-accent: #d7ff5f;\n --df-review-color-accent-contrast: #171b1e;\n --df-review-color-accent-soft: rgba(215, 255, 95, 0.16);\n --df-review-color-accent-ring: rgba(215, 255, 95, 0.6);\n --df-review-color-area: #63d7c7;\n --df-review-color-error: #ffb7a7;\n --df-review-shadow-panel: 0 18px 48px rgba(0, 0, 0, 0.34);\n --df-review-shadow-popover: 0 16px 38px rgba(0, 0, 0, 0.32);\n --df-review-shadow-highlight: 0 10px 30px rgba(0, 0, 0, 0.22);\n font-family: var(--df-review-font-sans);\n }\n\n * {\n box-sizing: border-box;\n }\n\n .dfwr-shell {\n display: none;\n position: fixed;\n inset: 0;\n z-index: 500;\n pointer-events: none;\n }\n\n .dfwr-shell.is-open {\n display: block;\n }\n\n .dfwr-shell.has-dismissible-draft {\n z-index: 900;\n }\n\n .dfwr-draft-cancel-layer {\n position: fixed;\n inset: 0;\n z-index: 2;\n pointer-events: auto;\n background: transparent;\n cursor: default;\n }\n\n .dfwr-shell.is-docked-composer {\n position: relative;\n inset: auto;\n z-index: auto;\n padding: 0;\n pointer-events: auto;\n }\n\n .dfwr-panel {\n position: fixed;\n right: 16px;\n top: 16px;\n z-index: 3;\n width: min(380px, calc(100vw - 32px));\n max-height: calc(100vh - 32px);\n overflow: auto;\n pointer-events: auto;\n color: var(--df-review-color-text);\n background: var(--df-review-color-panel);\n border: 1px solid var(--df-review-color-border);\n border-radius: var(--df-review-radius-md);\n box-shadow: var(--df-review-shadow-panel);\n }\n\n .dfwr-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n padding: 14px 14px 10px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n }\n\n .dfwr-title {\n font-size: var(--df-review-font-size-xl);\n font-weight: var(--df-review-font-weight-emphasis);\n line-height: 1.25;\n }\n\n .dfwr-meta {\n max-width: 292px;\n margin-top: 4px;\n overflow: hidden;\n color: rgba(247, 247, 242, 0.56);\n font-size: var(--df-review-font-size-xs);\n line-height: 1.35;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .dfwr-toolbar,\n .dfwr-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 12px 14px;\n }\n\n .dfwr-body,\n .dfwr-list {\n padding: 0 14px 14px;\n }\n\n .dfwr-list {\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n padding-top: 12px;\n }\n\n .dfwr-button,\n .dfwr-icon-button {\n appearance: none;\n border: 1px solid var(--df-review-color-border-strong);\n background: var(--df-review-color-control);\n color: var(--df-review-color-text);\n cursor: pointer;\n font: inherit;\n }\n\n .dfwr-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n min-height: var(--df-review-control-height-md);\n padding: 0 12px;\n border-radius: var(--df-review-radius-sm);\n font-size: var(--df-review-font-size-sm);\n font-weight: var(--df-review-font-weight-emphasis);\n }\n\n .dfwr-button:hover,\n .dfwr-icon-button:hover,\n .dfwr-button.is-active {\n border-color: rgba(255, 255, 255, 0.4);\n background: var(--df-review-color-control-hover);\n }\n\n .dfwr-button.is-primary {\n border-color: var(--df-review-color-accent);\n background: var(--df-review-color-accent);\n color: var(--df-review-color-accent-contrast);\n }\n\n .dfwr-button:disabled {\n cursor: default;\n opacity: 0.62;\n }\n\n .dfwr-spinner {\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 999px;\n animation: dfwr-spin 720ms linear infinite;\n }\n\n .dfwr-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: var(--df-review-control-height-sm);\n padding: 0 8px;\n border-radius: var(--df-review-radius-sm);\n font-size: var(--df-review-font-size-xs);\n font-weight: var(--df-review-font-weight-emphasis);\n line-height: 1;\n text-transform: uppercase;\n }\n\n .dfwr-marker-layer {\n position: fixed;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n }\n\n .dfwr-area-preview-layer {\n position: fixed;\n inset: 0;\n z-index: 3;\n pointer-events: none;\n }\n\n .dfwr-selection-highlight {\n position: fixed;\n z-index: 1;\n border: 2px solid #d7ff5f;\n border-radius: var(--df-review-radius-xs);\n background: rgba(215, 255, 95, 0.08);\n box-shadow:\n 0 0 0 1px rgba(31, 36, 40, 0.72),\n 0 0 0 9999px rgba(0, 0, 0, 0.12),\n 0 10px 30px rgba(0, 0, 0, 0.22);\n animation: dfwr-selection-pulse 900ms ease 0s 2;\n }\n\n .dfwr-selection-highlight.is-draft {\n border-color: #63d7c7;\n background: rgba(99, 215, 199, 0.1);\n box-shadow:\n 0 0 0 1px rgba(31, 36, 40, 0.72),\n 0 0 0 9999px rgba(0, 0, 0, 0.08),\n 0 10px 30px rgba(0, 0, 0, 0.2);\n animation: none;\n }\n\n .dfwr-dom-hover {\n position: fixed;\n z-index: 2;\n border: 1px solid #d7ff5f;\n border-radius: var(--df-review-radius-xs);\n background: rgba(215, 255, 95, 0.1);\n box-shadow:\n 0 0 0 1px rgba(31, 36, 40, 0.72),\n 0 0 0 9999px rgba(0, 0, 0, 0.08);\n pointer-events: none;\n }\n\n .dfwr-dom-hover[hidden] {\n display: none;\n }\n\n .dfwr-bound-marker,\n .dfwr-item-scope {\n --dfwr-scope: #7cc7ff;\n --dfwr-scope-rgb: 124, 199, 255;\n }\n\n .dfwr-bound-marker.is-scope-tablet,\n .dfwr-item-scope.is-scope-tablet {\n --dfwr-scope: #63d7c7;\n --dfwr-scope-rgb: 99, 215, 199;\n }\n\n .dfwr-bound-marker.is-scope-desktop,\n .dfwr-item-scope.is-scope-desktop {\n --dfwr-scope: #f3b75f;\n --dfwr-scope-rgb: 243, 183, 95;\n }\n\n .dfwr-bound-marker.is-scope-wide,\n .dfwr-item-scope.is-scope-wide {\n --dfwr-scope: #c99cff;\n --dfwr-scope-rgb: 201, 156, 255;\n }\n\n .dfwr-bound-marker.is-scope-dom,\n .dfwr-item-scope.is-scope-dom {\n --dfwr-scope: #ff8f61;\n --dfwr-scope-rgb: 255, 143, 97;\n }\n\n .dfwr-item-target-highlight,\n .dfwr-item-target-label {\n --dfwr-item-color: #7cc7ff;\n --dfwr-item-color-rgb: 124, 199, 255;\n }\n\n .dfwr-item-target-highlight.is-mode-area,\n .dfwr-item-target-label.is-mode-area {\n --dfwr-item-color: #63d7c7;\n --dfwr-item-color-rgb: 99, 215, 199;\n }\n\n .dfwr-item-target-highlight.is-mode-dom,\n .dfwr-item-target-label.is-mode-dom {\n --dfwr-item-color: #ff8f61;\n --dfwr-item-color-rgb: 255, 143, 97;\n }\n\n .dfwr-item-target-highlight.is-scope-mobile,\n .dfwr-item-target-label.is-scope-mobile {\n --dfwr-item-color: #7cc7ff;\n --dfwr-item-color-rgb: 124, 199, 255;\n }\n\n .dfwr-item-target-highlight.is-scope-tablet,\n .dfwr-item-target-label.is-scope-tablet {\n --dfwr-item-color: #63d7c7;\n --dfwr-item-color-rgb: 99, 215, 199;\n }\n\n .dfwr-item-target-highlight.is-scope-desktop,\n .dfwr-item-target-label.is-scope-desktop {\n --dfwr-item-color: #f3b75f;\n --dfwr-item-color-rgb: 243, 183, 95;\n }\n\n .dfwr-item-target-highlight.is-scope-wide,\n .dfwr-item-target-label.is-scope-wide {\n --dfwr-item-color: #c99cff;\n --dfwr-item-color-rgb: 201, 156, 255;\n }\n\n .dfwr-item-target-highlight.is-scope-dom,\n .dfwr-item-target-label.is-scope-dom {\n --dfwr-item-color: #ff8f61;\n --dfwr-item-color-rgb: 255, 143, 97;\n }\n\n .dfwr-item-target-highlight {\n position: fixed;\n z-index: 2;\n border: 2px solid var(--dfwr-item-color);\n border-radius: 4px;\n background: rgba(var(--dfwr-item-color-rgb), 0.08);\n box-shadow:\n 0 0 0 1px rgba(31, 36, 40, 0.78),\n 0 12px 30px rgba(0, 0, 0, 0.24);\n pointer-events: none;\n }\n\n .dfwr-item-target-highlight.is-fallback {\n border-style: dashed;\n }\n\n .dfwr-item-target-highlight.is-highlighted {\n border-width: 3px;\n background: rgba(var(--dfwr-item-color-rgb), 0.12);\n }\n\n .dfwr-item-target-highlight.is-highlighted::after {\n content: \"\";\n position: absolute;\n inset: -6px;\n border: 2px solid var(--dfwr-item-color);\n border-radius: var(--df-review-radius-md);\n opacity: 0;\n animation: dfwr-target-ring-blink 1000ms ease-in-out infinite;\n pointer-events: none;\n }\n\n .dfwr-item-target-label {\n position: fixed;\n z-index: 3;\n display: inline-flex;\n align-items: center;\n min-width: 24px;\n height: 20px;\n padding: 0 7px;\n border: 1px solid var(--dfwr-item-color);\n border-radius: 4px;\n background: var(--dfwr-item-color);\n box-shadow:\n 0 0 0 3px rgba(var(--dfwr-item-color-rgb), 0.2),\n 0 8px 18px rgba(0, 0, 0, 0.28);\n color: #111820;\n font-size: var(--df-review-font-size-2xs);\n font-weight: var(--df-review-font-weight-emphasis);\n line-height: 1;\n pointer-events: none;\n }\n\n .dfwr-item-target-label.is-highlighted {\n animation: dfwr-selected-blink 1000ms ease-in-out infinite;\n }\n\n .dfwr-bound-marker {\n position: fixed;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n min-width: 28px;\n height: 22px;\n padding: 0 6px;\n transform: translate(-50%, -50%);\n border: 1px solid var(--dfwr-scope);\n border-radius: var(--df-review-radius-pill);\n background: var(--df-review-color-panel);\n box-shadow: 0 0 0 4px rgba(var(--dfwr-scope-rgb), 0.18);\n color: var(--dfwr-scope);\n font-size: var(--df-review-font-size-2xs);\n font-weight: var(--df-review-font-weight-emphasis);\n }\n\n .dfwr-bound-marker.is-highlighted {\n min-width: 32px;\n height: 26px;\n border-width: 2px;\n box-shadow:\n 0 0 0 5px rgba(var(--dfwr-scope-rgb), 0.22),\n 0 12px 26px rgba(0, 0, 0, 0.34);\n animation: dfwr-selected-blink 1000ms ease-in-out infinite;\n }\n\n .dfwr-bound-marker.is-fallback {\n border-style: dashed;\n }\n\n .dfwr-area-preview-layer .dfwr-bound-marker {\n border-color: #63d7c7;\n background: var(--df-review-color-panel);\n box-shadow:\n 0 0 0 5px rgba(99, 215, 199, 0.2),\n 0 12px 26px rgba(0, 0, 0, 0.3);\n color: #63d7c7;\n }\n\n .dfwr-bound-marker-icon {\n position: relative;\n display: inline-block;\n width: 10px;\n height: 10px;\n flex: 0 0 auto;\n }\n\n .dfwr-bound-marker-icon::before,\n .dfwr-bound-marker-icon::after {\n content: \"\";\n position: absolute;\n display: block;\n }\n\n .dfwr-bound-marker-icon::before {\n inset: 1px 2px;\n border: 1.5px solid currentColor;\n border-radius: 2px;\n }\n\n .dfwr-bound-marker.is-scope-mobile .dfwr-bound-marker-icon::before {\n inset: 0 2.5px;\n border-radius: 2px;\n }\n\n .dfwr-bound-marker.is-scope-tablet .dfwr-bound-marker-icon::before {\n inset: 0.5px 1.5px;\n border-radius: 2px;\n }\n\n .dfwr-bound-marker.is-scope-desktop .dfwr-bound-marker-icon::before {\n inset: 1px 0 3px;\n border-radius: 1px;\n }\n\n .dfwr-bound-marker.is-scope-desktop .dfwr-bound-marker-icon::after {\n left: 3px;\n right: 3px;\n bottom: 0;\n height: 1.5px;\n background: currentColor;\n }\n\n .dfwr-bound-marker.is-scope-wide .dfwr-bound-marker-icon::before {\n inset: 2px 0;\n border-radius: 1px;\n }\n\n .dfwr-bound-marker.is-scope-dom .dfwr-bound-marker-icon::before {\n inset: 2px;\n border-radius: 1px;\n transform: rotate(45deg);\n }\n\n .dfwr-bound-marker-number {\n min-width: 6px;\n text-align: center;\n line-height: 1;\n }\n\n .dfwr-dom-draft {\n position: fixed;\n inset: 0;\n z-index: 4;\n pointer-events: none;\n }\n\n .dfwr-dom-pin {\n appearance: none;\n position: fixed;\n z-index: 5;\n width: 18px;\n height: 18px;\n padding: 0;\n transform: translate(-50%, -50%);\n border: 2px solid #1f2428;\n border-radius: var(--df-review-radius-pill);\n background: var(--df-review-color-accent);\n box-shadow:\n 0 0 0 4px rgba(215, 255, 95, 0.22),\n 0 8px 18px rgba(0, 0, 0, 0.28);\n cursor: grab;\n pointer-events: auto;\n }\n\n .dfwr-dom-pin:active {\n cursor: grabbing;\n }\n\n .dfwr-dom-popover {\n position: fixed;\n z-index: 4;\n width: min(320px, calc(100vw - 24px));\n padding: 12px;\n pointer-events: auto;\n color: var(--df-review-color-text);\n background: var(--df-review-color-panel);\n border: 1px solid rgba(215, 255, 95, 0.56);\n border-radius: var(--df-review-radius-md);\n box-shadow: var(--df-review-shadow-popover);\n }\n\n .dfwr-dom-popover.is-composer,\n .dfwr-area-draft.is-composer {\n max-height: min(360px, calc(100vh - 32px));\n overflow: auto;\n border-color: rgba(99, 215, 199, 0.56);\n }\n\n .dfwr-shell.is-docked-composer .dfwr-dom-popover.is-docked-composer,\n .dfwr-shell.is-docked-composer .dfwr-area-draft.is-docked-composer {\n position: relative;\n left: auto;\n right: auto;\n top: auto;\n z-index: auto;\n max-height: none;\n }\n\n .dfwr-shell.is-docked-composer .dfwr-textarea {\n min-height: 184px;\n }\n\n .dfwr-dom-popover.is-dragging,\n .dfwr-area-draft.is-dragging {\n user-select: none;\n }\n\n .dfwr-draft-drag-handle {\n display: block;\n width: 42px;\n height: 6px;\n margin: 0 auto 10px;\n padding: 0;\n cursor: grab;\n pointer-events: auto;\n background: rgba(247, 247, 242, 0.28);\n border: 0;\n border-radius: 999px;\n }\n\n .dfwr-draft-drag-handle:hover,\n .dfwr-draft-drag-handle:focus-visible {\n background: rgba(215, 255, 95, 0.62);\n }\n\n .dfwr-draft-drag-handle:active {\n cursor: grabbing;\n }\n\n .dfwr-area-draft {\n position: fixed;\n right: 16px;\n top: 16px;\n z-index: 4;\n width: min(360px, calc(100vw - 32px));\n max-height: calc(100vh - 32px);\n overflow: auto;\n padding: 12px;\n pointer-events: auto;\n color: var(--df-review-color-text);\n background: var(--df-review-color-panel);\n border: 1px solid rgba(215, 255, 95, 0.56);\n border-radius: var(--df-review-radius-md);\n box-shadow: var(--df-review-shadow-popover);\n }\n\n .dfwr-dom-popover .dfwr-actions {\n padding: 0;\n }\n\n .dfwr-actions.has-leading {\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n\n .dfwr-actions-leading,\n .dfwr-actions-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n }\n\n .dfwr-actions-primary {\n margin-left: auto;\n }\n\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading {\n align-items: stretch;\n }\n\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-button,\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle {\n height: var(--df-review-control-height-md);\n min-height: var(--df-review-control-height-md);\n border-radius: var(--df-review-radius-sm);\n }\n\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-button {\n min-width: 96px;\n padding: 0 12px;\n font-size: var(--df-review-font-size-sm);\n }\n\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle {\n width: var(--df-review-control-height-md);\n }\n\n .dfwr-shell.is-docked-composer .dfwr-actions.has-leading .dfwr-adjust-toggle svg {\n width: 18px;\n height: 18px;\n }\n\n .dfwr-area-draft .dfwr-actions {\n padding: 0;\n }\n\n .dfwr-form {\n display: grid;\n gap: 10px;\n }\n\n .dfwr-form-error {\n margin: 0;\n color: #ff8f61;\n font-size: var(--df-review-font-size-sm);\n line-height: 1.4;\n overflow-wrap: anywhere;\n }\n\n .dfwr-attachment-queue {\n display: grid;\n gap: 8px;\n min-width: 0;\n }\n\n .dfwr-attachment-label {\n color: var(--df-review-color-text-muted);\n font-size: var(--df-review-font-size-xs);\n line-height: 1.35;\n }\n\n .dfwr-attachment-list {\n display: grid;\n gap: 8px;\n }\n\n .dfwr-attachment-item {\n display: grid;\n grid-template-columns: 42px minmax(0, 1fr) auto;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 6px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: var(--df-review-radius-sm);\n background: rgba(255, 255, 255, 0.04);\n }\n\n .dfwr-attachment-thumb {\n display: block;\n width: 42px;\n height: 42px;\n object-fit: cover;\n border-radius: var(--df-review-radius-xs);\n background: var(--df-review-color-panel-strong);\n }\n\n .dfwr-attachment-thumb.is-file {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--df-review-color-text-muted);\n font-size: var(--df-review-font-size-xs);\n font-weight: var(--df-review-font-weight-emphasis);\n }\n\n .dfwr-attachment-name {\n min-width: 0;\n overflow: hidden;\n color: var(--df-review-color-text);\n font-size: var(--df-review-font-size-sm);\n line-height: 1.35;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .dfwr-attachment-remove {\n appearance: none;\n min-height: 28px;\n padding: 0 8px;\n border: 1px solid var(--df-review-color-border-strong);\n border-radius: var(--df-review-radius-sm);\n color: var(--df-review-color-text-muted);\n background: var(--df-review-color-control);\n cursor: pointer;\n font: inherit;\n font-size: var(--df-review-font-size-xs);\n line-height: 1;\n }\n\n .dfwr-attachment-remove:hover {\n color: var(--df-review-color-text);\n background: var(--df-review-color-control-hover);\n }\n\n .dfwr-input,\n .dfwr-select,\n .dfwr-textarea {\n width: 100%;\n border: 1px solid rgba(255, 255, 255, 0.16);\n border-radius: var(--df-review-radius-sm);\n padding: 10px;\n color: var(--df-review-color-text);\n background: var(--df-review-color-panel-strong);\n font: inherit;\n font-size: var(--df-review-font-size-md);\n line-height: 1.45;\n }\n\n .dfwr-input,\n .dfwr-select {\n min-height: 38px;\n }\n\n .dfwr-select {\n appearance: none;\n cursor: pointer;\n }\n\n .dfwr-textarea {\n min-height: 92px;\n resize: vertical;\n }\n\n .dfwr-input:focus,\n .dfwr-select:focus,\n .dfwr-textarea:focus {\n outline: 2px solid var(--df-review-color-accent-ring);\n outline-offset: 1px;\n }\n\n @media (hover: none) and (pointer: coarse) {\n .dfwr-input,\n .dfwr-select,\n .dfwr-textarea {\n font-size: var(--df-review-font-size-xl);\n }\n }\n\n @keyframes dfwr-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .dfwr-adjust-panel {\n display: grid;\n gap: 4px;\n padding: 8px 10px;\n border: 1px solid rgba(255, 255, 255, 0.12);\n border-radius: var(--df-review-radius-sm);\n background: rgba(255, 255, 255, 0.04);\n }\n\n .dfwr-adjust-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n min-width: 0;\n }\n\n .dfwr-adjust-panel-header .dfwr-adjust-help {\n flex: 1 1 auto;\n min-width: 0;\n }\n\n .dfwr-adjust-panel.is-active {\n border-color: rgba(215, 255, 95, 0.5);\n background: var(--df-review-color-accent-soft);\n }\n\n .dfwr-adjust-help,\n .dfwr-adjust-status {\n margin: 0;\n color: var(--df-review-color-text-muted);\n font-size: var(--df-review-font-size-xs);\n line-height: 1.35;\n }\n\n .dfwr-adjust-status {\n color: var(--df-review-color-text);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace;\n }\n\n .dfwr-adjust-toggle {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 30px;\n padding: 0;\n border: 1px solid rgba(255, 255, 255, 0.2);\n border-radius: var(--df-review-radius-sm);\n background: rgba(255, 255, 255, 0.04);\n color: var(--df-review-color-text);\n cursor: pointer;\n font: inherit;\n font-size: var(--df-review-font-size-lg);\n font-weight: var(--df-review-font-weight-emphasis);\n line-height: 1;\n }\n\n .dfwr-adjust-toggle:hover,\n .dfwr-adjust-toggle:focus-visible,\n .dfwr-adjust-toggle.is-active {\n border-color: rgba(215, 255, 95, 0.68);\n background: var(--df-review-color-accent-soft);\n outline: none;\n }\n\n .dfwr-adjust-toggle svg {\n width: 18px;\n height: 18px;\n pointer-events: none;\n }\n\n .dfwr-empty,\n .dfwr-error {\n margin: 0;\n color: rgba(247, 247, 242, 0.62);\n font-size: var(--df-review-font-size-sm);\n line-height: 1.45;\n }\n\n .dfwr-error {\n color: var(--df-review-color-error);\n }\n\n .dfwr-preview,\n .dfwr-thumb {\n display: block;\n width: 100%;\n border: 1px solid var(--df-review-color-border);\n border-radius: var(--df-review-radius-sm);\n object-fit: cover;\n background: var(--df-review-color-canvas);\n }\n\n .dfwr-preview {\n max-height: 180px;\n }\n\n .dfwr-thumb {\n max-height: 120px;\n margin-top: 10px;\n }\n\n .dfwr-list-heading {\n margin-bottom: 10px;\n color: rgba(247, 247, 242, 0.74);\n font-size: var(--df-review-font-size-sm);\n font-weight: var(--df-review-font-weight-emphasis);\n }\n\n .dfwr-item {\n display: flex;\n gap: 12px;\n justify-content: space-between;\n padding: 12px 0;\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n cursor: pointer;\n }\n\n .dfwr-item:first-of-type {\n border-top: 0;\n }\n\n .dfwr-item:focus-visible {\n outline: 2px solid rgba(215, 255, 95, 0.72);\n outline-offset: 4px;\n }\n\n .dfwr-item-body {\n display: grid;\n gap: 4px;\n min-width: 0;\n flex: 1;\n }\n\n .dfwr-item-badges {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-wrap: wrap;\n }\n\n .dfwr-item-scope,\n .dfwr-item-kind {\n display: inline-flex;\n align-items: center;\n min-height: 20px;\n border-radius: var(--df-review-radius-pill);\n padding: 0 7px;\n font-size: var(--df-review-font-size-2xs);\n font-weight: var(--df-review-font-weight-emphasis);\n line-height: 1;\n letter-spacing: 0;\n text-transform: uppercase;\n }\n\n .dfwr-item-scope {\n border: 1px solid rgba(var(--dfwr-scope-rgb), 0.38);\n background: rgba(var(--dfwr-scope-rgb), 0.12);\n color: var(--dfwr-scope);\n }\n\n .dfwr-item-kind {\n border: 1px solid rgba(255, 255, 255, 0.12);\n background: rgba(255, 255, 255, 0.05);\n color: rgba(247, 247, 242, 0.64);\n }\n\n .dfwr-item-title {\n margin: 4px 0 0;\n color: var(--df-review-color-text);\n font-size: var(--df-review-font-size-md);\n font-weight: var(--df-review-font-weight-normal);\n line-height: 1.35;\n overflow-wrap: anywhere;\n }\n\n .dfwr-item-comment {\n margin: 0;\n color: var(--df-review-color-text-muted);\n font-size: var(--df-review-font-size-sm);\n line-height: 1.45;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n }\n\n .dfwr-item-comment.is-primary {\n margin: 4px 0;\n color: var(--df-review-color-text);\n font-size: var(--df-review-font-size-md);\n line-height: 1.42;\n }\n\n .dfwr-item-date {\n color: rgba(247, 247, 242, 0.46);\n font-size: var(--df-review-font-size-xs);\n }\n\n .dfwr-item-actions {\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex: 0 0 auto;\n }\n\n .dfwr-text-layer,\n .dfwr-element-layer,\n .dfwr-area-layer {\n position: fixed;\n inset: 0;\n z-index: 1;\n pointer-events: auto;\n }\n\n .dfwr-text-layer {\n cursor: crosshair;\n background: rgba(0, 0, 0, 0.06);\n }\n\n .dfwr-element-layer {\n cursor: cell;\n background: rgba(0, 0, 0, 0.06);\n }\n\n .dfwr-area-layer {\n cursor: crosshair;\n background: rgba(0, 0, 0, 0.22);\n }\n\n .dfwr-area-box {\n position: fixed;\n z-index: 2;\n width: 0;\n height: 0;\n border: 1px solid #d7ff5f;\n background: rgba(215, 255, 95, 0.16);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);\n }\n\n @keyframes dfwr-marker-pulse {\n 0% {\n transform: translate(-50%, -50%) scale(0.92);\n }\n 45% {\n transform: translate(-50%, -50%) scale(1.1);\n }\n 100% {\n transform: translate(-50%, -50%) scale(1);\n }\n }\n\n @keyframes dfwr-selected-blink {\n 0%,\n 100% {\n opacity: 0.78;\n }\n 50% {\n opacity: 1;\n }\n }\n\n @keyframes dfwr-target-ring-blink {\n 0%,\n 100% {\n opacity: 0;\n transform: scale(0.98);\n }\n 50% {\n opacity: 0.82;\n transform: scale(1);\n }\n }\n\n @keyframes dfwr-selection-pulse {\n 0% {\n opacity: 0.72;\n }\n 45% {\n opacity: 1;\n }\n 100% {\n opacity: 0.86;\n }\n }\n\n @media (max-width: 520px) {\n .dfwr-panel {\n left: 8px;\n right: 8px;\n top: auto;\n bottom: 8px;\n width: auto;\n max-height: min(70vh, calc(100vh - 16px));\n }\n }\n `;\n return style;\n}\n","import type { ReviewDraftAttachment } from './review/draft';\n\ninterface DraftAttachmentPasteOptions {\n getAttachments: () => ReviewDraftAttachment[] | undefined;\n onAttachmentsChange: (attachments: ReviewDraftAttachment[]) => void;\n onCommentChange: (comment: string) => void;\n onPasteComplete: () => void;\n}\n\nexport function attachDraftImagePasteQueue(\n textarea: HTMLTextAreaElement,\n options: DraftAttachmentPasteOptions\n) {\n textarea.addEventListener('paste', (event) => {\n const imageFiles = getClipboardImageFiles(event.clipboardData);\n if (imageFiles.length === 0) return;\n\n event.preventDefault();\n const text = event.clipboardData?.getData('text/plain');\n if (text) {\n insertTextAtTextareaSelection(textarea, text);\n options.onCommentChange(textarea.value);\n }\n\n const attachments = imageFiles.map((file, index) =>\n createDraftImageAttachment(file, index)\n );\n options.onAttachmentsChange([\n ...(options.getAttachments() ?? []),\n ...attachments,\n ]);\n options.onPasteComplete();\n });\n}\n\nexport function createDraftAttachmentQueue(\n ownerDocument: Document,\n attachments: ReviewDraftAttachment[] | undefined,\n onRemove: (attachmentId: string) => void\n) {\n if (!attachments?.length) return undefined;\n\n const queue = ownerDocument.createElement('div');\n queue.className = 'dfwr-attachment-queue';\n\n const label = ownerDocument.createElement('div');\n label.className = 'dfwr-attachment-label';\n label.textContent = `Attachments (${attachments.length})`;\n\n const list = ownerDocument.createElement('div');\n list.className = 'dfwr-attachment-list';\n\n attachments.forEach((attachment) => {\n const item = ownerDocument.createElement('div');\n item.className = 'dfwr-attachment-item';\n\n const preview = createDraftAttachmentPreview(ownerDocument, attachment);\n\n const name = ownerDocument.createElement('div');\n name.className = 'dfwr-attachment-name';\n name.textContent = attachment.name;\n name.title = attachment.name;\n\n const remove = ownerDocument.createElement('button');\n remove.className = 'dfwr-attachment-remove';\n remove.type = 'button';\n remove.textContent = 'Remove';\n remove.setAttribute('aria-label', `Remove ${attachment.name}`);\n remove.addEventListener('click', (event) => {\n event.preventDefault();\n event.stopPropagation();\n onRemove(attachment.id);\n });\n\n item.append(preview, name, remove);\n list.append(item);\n });\n\n queue.append(label, list);\n return queue;\n}\n\nexport function removeDraftAttachment(\n attachments: ReviewDraftAttachment[] | undefined,\n attachmentId: string\n) {\n if (!attachments?.length) return [];\n\n const removed = attachments.find((attachment) => attachment.id === attachmentId);\n if (removed?.previewUrl) {\n URL.revokeObjectURL(removed.previewUrl);\n }\n return attachments.filter((attachment) => attachment.id !== attachmentId);\n}\n\nfunction getClipboardImageFiles(data: DataTransfer | null) {\n if (!data) return [];\n\n const itemFiles = Array.from(data.items)\n .filter((item) => item.kind === 'file' && item.type.startsWith('image/'))\n .map((item) => item.getAsFile())\n .filter((file): file is File => Boolean(file));\n if (itemFiles.length > 0) return itemFiles;\n\n return Array.from(data.files).filter((file) => file.type.startsWith('image/'));\n}\n\nfunction createDraftImageAttachment(file: File, index: number) {\n const mime = file.type || 'image/png';\n const name =\n file.name ||\n `pasted-image-${Date.now()}-${index + 1}${getImageExtension(mime)}`;\n return {\n id: createDraftAttachmentId(),\n file,\n name,\n mime,\n size: file.size,\n kind: 'image',\n previewUrl: URL.createObjectURL(file),\n metadata: { source: 'paste' },\n } satisfies ReviewDraftAttachment;\n}\n\nfunction createDraftAttachmentId() {\n return (\n window.crypto?.randomUUID?.() ??\n `draft-attachment-${Date.now()}-${Math.random().toString(36).slice(2)}`\n );\n}\n\nfunction getImageExtension(mime: string) {\n if (mime === 'image/jpeg') return '.jpg';\n if (mime === 'image/gif') return '.gif';\n if (mime === 'image/webp') return '.webp';\n if (mime === 'image/svg+xml') return '.svg';\n return '.png';\n}\n\nfunction insertTextAtTextareaSelection(\n textarea: HTMLTextAreaElement,\n text: string\n) {\n const start = textarea.selectionStart ?? textarea.value.length;\n const end = textarea.selectionEnd ?? start;\n textarea.value = [\n textarea.value.slice(0, start),\n text,\n textarea.value.slice(end),\n ].join('');\n const nextSelection = start + text.length;\n textarea.setSelectionRange(nextSelection, nextSelection);\n}\n\nfunction createDraftAttachmentPreview(\n ownerDocument: Document,\n attachment: ReviewDraftAttachment\n) {\n if (attachment.previewUrl && attachment.mime.startsWith('image/')) {\n const image = ownerDocument.createElement('img');\n image.className = 'dfwr-attachment-thumb';\n image.src = attachment.previewUrl;\n image.alt = '';\n image.decoding = 'async';\n return image;\n }\n\n const fallback = ownerDocument.createElement('div');\n fallback.className = 'dfwr-attachment-thumb is-file';\n fallback.textContent = 'IMG';\n return fallback;\n}\n","// Draft composer(플로팅 코멘트 폼)의 크기/위치 계산과 드래그 이동 와이어링.\n// composer 는 오버레이 안이 아니라 호스트 문서 기준으로 배치되므로\n// overlayRect 와 호스트 뷰포트 두 좌표계를 함께 다룬다.\nimport type { ReviewPoint } from '../../types';\nimport {\n clamp,\n type ReviewEnvironment,\n type ViewportSelection,\n} from '../geometry';\n\nconst COMPOSER_MARGIN = 12;\n\n/** Composer width adapts to the overlay but stays in a readable 240–360px band. */\nfunction getDraftComposerWidth(environment: ReviewEnvironment) {\n const bounds = environment.overlayRect;\n return Math.min(360, Math.max(240, bounds.width - COMPOSER_MARGIN * 2));\n}\n\n/** Host document bounds used when the composer may float outside the overlay. */\nfunction getHostComposerBounds() {\n const root = document.documentElement;\n return {\n left: 0,\n top: 0,\n width: root.clientWidth || window.innerWidth,\n height: root.clientHeight || window.innerHeight,\n };\n}\n\n/** Clamps a composer position so the whole form stays inside the given bounds. */\nfunction getClampedComposerPosition(\n position: ReviewPoint,\n environment: ReviewEnvironment,\n size?: { width?: number; height?: number },\n bounds = environment.overlayRect\n) {\n const width = size?.width ?? getDraftComposerWidth(environment);\n const height = size?.height ?? 236;\n\n return {\n x: clamp(\n position.x,\n bounds.left + COMPOSER_MARGIN,\n bounds.left + bounds.width - width - COMPOSER_MARGIN\n ),\n y: clamp(\n position.y,\n bounds.top + COMPOSER_MARGIN,\n bounds.top + bounds.height - height - COMPOSER_MARGIN\n ),\n };\n}\n\n/**\n * Picks the first-open position: to the right of the selection when there is\n * room, otherwise to the left, always clamped to the host viewport.\n */\nfunction getInitialDraftComposerPosition(\n selection: ViewportSelection | undefined,\n environment: ReviewEnvironment,\n size: { width: number; height?: number }\n) {\n const bounds = getHostComposerBounds();\n const gap = 20;\n\n if (!selection) {\n return getClampedComposerPosition(\n {\n x: environment.overlayRect.left + COMPOSER_MARGIN,\n y: environment.overlayRect.top + COMPOSER_MARGIN,\n },\n environment,\n size,\n bounds\n );\n }\n\n const preferredX = selection.left + selection.width + gap;\n const maxX = bounds.left + bounds.width - size.width - COMPOSER_MARGIN;\n const x =\n preferredX <= maxX ? preferredX : selection.left - size.width - gap;\n\n return getClampedComposerPosition(\n {\n x,\n y: selection.top,\n },\n environment,\n size,\n bounds\n );\n}\n\n/** Resolves the final composer placement, honoring a user-dragged position. */\nexport function getDraftComposerPosition({\n selection,\n environment,\n composerPosition,\n estimatedHeight,\n}: {\n selection?: ViewportSelection;\n environment: ReviewEnvironment;\n composerPosition?: ReviewPoint;\n estimatedHeight?: number;\n}) {\n const width = getDraftComposerWidth(environment);\n\n if (composerPosition) {\n // 사용자가 드래그로 옮긴 위치가 있으면 그 위치를 우선하되 화면 밖은 막는다.\n const clamped = getClampedComposerPosition(\n composerPosition,\n environment,\n { width, height: estimatedHeight },\n getHostComposerBounds()\n );\n return { width, left: clamped.x, top: clamped.y };\n }\n\n const position = getInitialDraftComposerPosition(selection, environment, {\n width,\n height: estimatedHeight,\n });\n\n return { width, left: position.x, top: position.y };\n}\n\n/** Wires pointer-drag on the handle so the whole composer popover can be moved. */\nexport function attachDraftComposerDrag({\n getEnvironment,\n popover,\n handle,\n onMove,\n}: {\n getEnvironment: () => ReviewEnvironment | undefined;\n popover: HTMLDivElement;\n handle: HTMLButtonElement;\n onMove: (position: ReviewPoint) => void;\n}) {\n let isDragging = false;\n let offsetX = 0;\n let offsetY = 0;\n\n const movePopover = (event: PointerEvent) => {\n const environment = getEnvironment();\n if (!environment) return;\n\n const position = getClampedComposerPosition(\n {\n x: event.clientX - offsetX,\n y: event.clientY - offsetY,\n },\n environment,\n {\n width: popover.offsetWidth,\n height: popover.offsetHeight,\n },\n getHostComposerBounds()\n );\n\n popover.style.left = `${position.x}px`;\n popover.style.top = `${position.y}px`;\n onMove(position);\n };\n\n handle.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n\n // 잡은 지점과 popover 좌상단의 offset 을 기억해서 드래그 중 점프를 막는다.\n const rect = popover.getBoundingClientRect();\n offsetX = event.clientX - rect.left;\n offsetY = event.clientY - rect.top;\n isDragging = true;\n\n event.preventDefault();\n event.stopPropagation();\n handle.setPointerCapture(event.pointerId);\n popover.classList.add('is-dragging');\n });\n\n handle.addEventListener('pointermove', (event) => {\n if (!isDragging || !handle.hasPointerCapture(event.pointerId)) return;\n\n event.preventDefault();\n movePopover(event);\n });\n\n const stopDrag = (event: PointerEvent) => {\n if (!isDragging || !handle.hasPointerCapture(event.pointerId)) return;\n\n event.preventDefault();\n event.stopPropagation();\n isDragging = false;\n handle.releasePointerCapture(event.pointerId);\n popover.classList.remove('is-dragging');\n movePopover(event);\n };\n\n handle.addEventListener('pointerup', stopDrag);\n handle.addEventListener('pointercancel', stopDrag);\n}\n","// 오버레이 렌더러가 공유하는 아이콘/스피너 DOM 헬퍼.\n// 뷰 상태에 의존하지 않는 순수 DOM 빌더만 모아둔다.\n\n/** Builds an inline stroke icon from SVG path data. */\nfunction createIcon(paths: string[]) {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('viewBox', '0 0 24 24');\n svg.setAttribute('fill', 'none');\n svg.setAttribute('stroke', 'currentColor');\n svg.setAttribute('stroke-width', '2.4');\n svg.setAttribute('stroke-linecap', 'round');\n svg.setAttribute('stroke-linejoin', 'round');\n\n paths.forEach((d) => {\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute('d', d);\n svg.append(path);\n });\n\n return svg;\n}\n\n/** Swaps the adjustment toggle between \"move\" (idle) and \"check\" (active) icons. */\nexport function setAdjustmentToggleIcon(\n button: HTMLButtonElement,\n isActive: boolean\n) {\n const paths = isActive\n ? ['M20 6 9 17l-5-5']\n : [\n 'M12 2v20',\n 'M2 12h20',\n 'm9 5 3-3 3 3',\n 'm9 19 3 3 3-3',\n 'm5 9-3 3 3 3',\n 'm19 9 3 3-3 3',\n ];\n button.replaceChildren(createIcon(paths));\n}\n\n/** Creates the busy spinner shown inside async buttons. */\nexport function createSpinner(className: string) {\n const spinner = document.createElement('span');\n spinner.className = className;\n spinner.setAttribute('aria-hidden', 'true');\n return spinner;\n}\n","// Draft 폼의 \"Capture\" 버튼과 캡처 요청 페이로드 빌더.\n// 실제 스크린샷은 environment.captureViewport(React 셸이 주입)가 수행한다.\nimport {\n getAdjustedDraftPoint,\n getAdjustedDraftSelection,\n} from '../draft.metrics';\nimport {\n roundPoint,\n toPublicSelection,\n toViewportSelection,\n} from '../geometry';\nimport type { AreaDraft, DomDraft } from '../review/draft';\nimport { createSpinner } from './icons';\nimport type { WebReviewKitViewConfig } from './types';\n\n/** Capture helper is optional; only the React shell provides it today. */\nfunction canCaptureViewport(config: WebReviewKitViewConfig) {\n return Boolean(config.getEnvironment()?.captureViewport);\n}\n\n/** Area draft capture payload: stored coordinates as-is. */\nfunction getCaptureAreaDraft(draft: AreaDraft) {\n return {\n viewport: draft.viewport,\n marker: draft.marker,\n selection: draft.selection,\n };\n}\n\n/**\n * DOM draft capture payload. Element drafts apply the pending adjustment\n * (nudge/scale) so the screenshot matches what the reviewer is previewing.\n */\nfunction getCaptureDomDraft(\n config: WebReviewKitViewConfig,\n draft: DomDraft,\n isElementDraft: boolean\n) {\n if (!isElementDraft) {\n return {\n viewport: draft.viewport,\n marker: draft.marker,\n selection: draft.selection,\n };\n }\n\n const presets = config.options.viewports?.presets;\n const marker = {\n ...draft.marker,\n viewport: roundPoint(\n getAdjustedDraftPoint(draft.marker.viewport, draft, presets)\n ),\n };\n const selection = draft.selection\n ? {\n ...draft.selection,\n viewport: toPublicSelection(\n getAdjustedDraftSelection(\n toViewportSelection(draft.selection.viewport),\n draft,\n presets\n )\n ),\n }\n : undefined;\n\n return {\n viewport: draft.viewport,\n marker,\n selection,\n };\n}\n\n/** Builds the capture button; disabled while capturing/saving or without helper. */\nexport function createDraftCaptureButton(\n config: WebReviewKitViewConfig,\n draft: DomDraft | AreaDraft,\n options:\n | {\n kind: 'dom';\n isElementDraft: boolean;\n textarea: HTMLTextAreaElement;\n }\n | {\n kind: 'area';\n textarea: HTMLTextAreaElement;\n }\n) {\n const button = document.createElement('button');\n const state = config.getState();\n const isCapturing = state.isCapturingViewport;\n const canCapture = canCaptureViewport(config);\n\n button.className = 'dfwr-button';\n button.type = 'button';\n button.disabled = !canCapture || isCapturing || state.isCreatingItem;\n button.setAttribute('aria-busy', isCapturing ? 'true' : 'false');\n button.title = canCapture\n ? 'Capture current viewport'\n : 'Viewport capture helper is not available';\n if (isCapturing) {\n button.append(createSpinner('dfwr-spinner'), 'Capturing...');\n } else {\n button.textContent = 'Capture';\n }\n\n button.addEventListener('click', (event) => {\n event.preventDefault();\n event.stopPropagation();\n // 클릭 시점의 최신 상태로 다시 판정 (렌더 이후 상태가 바뀌었을 수 있음)\n const currentState = config.getState();\n if (!canCaptureViewport(config) || currentState.isCapturingViewport) {\n return;\n }\n\n if (options.kind === 'area') {\n const areaDraft = currentState.areaDraft ?? (draft as AreaDraft);\n // 캡처 전에 작성 중인 코멘트를 draft 에 반영해 유실을 막는다.\n const nextDraft = {\n ...areaDraft,\n comment: options.textarea.value,\n };\n config.actions.setAreaDraft(nextDraft);\n void config.actions.captureAreaDraft(getCaptureAreaDraft(nextDraft));\n return;\n }\n\n const domDraft = currentState.domDraft ?? (draft as DomDraft);\n const nextDraft = {\n ...domDraft,\n comment: options.textarea.value,\n };\n config.actions.setDomDraft(nextDraft);\n void config.actions.captureDomDraft(\n getCaptureDomDraft(config, nextDraft, options.isElementDraft)\n );\n });\n\n return button;\n}\n","// Draft 관련 수치를 사람이 읽을 문자열로 변환하는 모듈.\n// (adjustment 패널의 x/y/scale 표시, area 크기 표시, 저장 코멘트 꼬리표 등)\n// 실제 기하 계산은 draft.metrics.ts 가 담당하고 여기서는 포맷만 한다.\nimport type {\n ReviewViewportPreset,\n ViewportSize,\n WebReviewKitOptions,\n} from '../../types';\nimport * as draftMetrics from '../draft.metrics';\nimport { toViewportSelection, type ViewportSelection } from '../geometry';\nimport type { AreaDraft, DomDraft } from '../review/draft';\n\nconst DEFAULT_ADJUSTMENT_LABEL = 'Responsive CSS px adjustments';\n\n/** Host-configurable label shown on the adjustment panel and saved comments. */\nexport function getAdjustmentLabel(options: WebReviewKitOptions) {\n return options.adjustmentLabel?.trim() || DEFAULT_ADJUSTMENT_LABEL;\n}\n\n/** Formats a delta as \"+3px\" / \"-2px\"; zero keeps the plus for alignment. */\nfunction formatSignedPx(value: number) {\n if (value === 0) return '+0px';\n return `${value > 0 ? '+' : ''}${value}px`;\n}\n\nfunction formatRoundedPx(value: number) {\n return `${Math.round(value)}px`;\n}\n\n/**\n * Converts a viewport-space selection into design-space (media query) pixels\n * using the preset's design width, so reviewers see design values, not CSS px.\n */\nfunction getSelectionMqMetrics(\n selection: ViewportSelection,\n viewport: ViewportSize,\n presets?: ReviewViewportPreset[]\n) {\n const { scale } = draftMetrics.getDraftViewportScale(viewport, presets);\n const ratio = scale > 0 ? 1 / scale : 1;\n\n return {\n x: selection.left * ratio,\n y: selection.top * ratio,\n width: selection.width * ratio,\n height: selection.height * ratio,\n };\n}\n\n/** Three display lines (label / position / size) for the area metrics panel. */\nexport function getSelectionMetricLines(\n selection: ViewportSelection | undefined,\n viewport: ViewportSize,\n presets?: ReviewViewportPreset[]\n) {\n if (!selection) return ['area', 'x none / y none', 'w none / h none'];\n\n const metrics = getSelectionMqMetrics(selection, viewport, presets);\n return [\n 'area',\n `x ${formatRoundedPx(metrics.x)} / y ${formatRoundedPx(metrics.y)}`,\n `w ${formatRoundedPx(metrics.width)} / h ${formatRoundedPx(\n metrics.height\n )}`,\n ];\n}\n\n/** Selection rectangle an area draft should report metrics for, if any. */\nexport function getAreaDraftMetricSelection(draft: AreaDraft) {\n if (!draft.selection) return undefined;\n\n return toViewportSelection(draft.selection.viewport);\n}\n\n/** Two display lines (x/y and scale) for the DOM adjustment panel. */\nexport function getDraftAdjustmentMetricLines(\n draft: DomDraft,\n presets?: ReviewViewportPreset[]\n) {\n const metrics = draftMetrics.getDraftAdjustmentMetrics(draft, presets);\n return [\n `x ${formatSignedPx(metrics.x)} / y ${formatSignedPx(metrics.y)}`,\n `scale ${formatSignedPx(metrics.scale)}`,\n ];\n}\n\n/**\n * Appends the adjustment summary to a saved comment so the reviewed change\n * (x/y/scale in design px) survives even after the draft preview is gone.\n */\nexport function withDraftAdjustmentComment(\n comment: string,\n draft: DomDraft,\n options: WebReviewKitOptions\n) {\n const presets = options.viewports?.presets;\n if (!draftMetrics.hasDraftAdjustment(draft, presets)) return comment;\n\n const trimmedComment = comment.trim();\n const metrics = draftMetrics.getDraftAdjustmentMetrics(draft, presets);\n const adjustment = [\n `${getAdjustmentLabel(options)}: x ${formatSignedPx(\n metrics.x\n )}, y ${formatSignedPx(metrics.y)}, scale ${formatSignedPx(\n metrics.scale\n )}`,\n `(${metrics.presetLabel} viewport, ${Math.round(\n metrics.viewportWidth\n )}/design ${Math.round(metrics.designWidth)})`,\n ].join(' ');\n\n return trimmedComment ? `${trimmedComment}\\n${adjustment}` : adjustment;\n}\n","// DOM/Area draft 폼이 공유하는 입력 위젯 빌더 모음.\n// 모든 함수는 상태를 직접 읽지 않고 값/콜백을 인자로 받는다.\nimport type { WebReviewKitOptions } from '../../types';\nimport { createSpinner } from './icons';\n\n/** Finds the configured assignee option for a stored assignee id. */\nfunction getAssigneeOption(\n options: WebReviewKitOptions,\n assigneeId: string | null | undefined\n) {\n if (!assigneeId) return undefined;\n return options.assigneeOptions?.find(\n (option) => option.value === assigneeId\n );\n}\n\n/** Resolves the display name for an assignee id, if it is still configured. */\nfunction getAssigneeName(\n options: WebReviewKitOptions,\n assigneeId: string | null | undefined\n) {\n return getAssigneeOption(options, assigneeId)?.label;\n}\n\n/** Title input is opt-in per host project. */\nexport function isTitleFieldEnabled(options: WebReviewKitOptions) {\n return options.fields?.title === true;\n}\n\nexport function createDraftTitleInput(\n value: string | undefined,\n onInput: (value: string) => void\n) {\n const input = document.createElement('input');\n input.className = 'dfwr-input';\n input.placeholder = 'Title';\n input.type = 'text';\n input.value = value ?? '';\n input.addEventListener('input', () => onInput(input.value));\n return input;\n}\n\n/**\n * Assignee dropdown. Returns undefined when the host has no assignee options,\n * so callers can skip appending it entirely.\n */\nexport function createDraftAssigneeSelect(\n options: WebReviewKitOptions,\n value: string | null | undefined,\n fallbackLabel: string | undefined,\n onChange: (assigneeId: string | null, assigneeName?: string) => void\n) {\n const assigneeOptions = options.assigneeOptions ?? [];\n if (assigneeOptions.length === 0) return undefined;\n const assigneeTitle = options.assigneeTitle?.trim() || 'Assignee';\n\n const select = document.createElement('select');\n select.className = 'dfwr-select';\n\n const emptyOption = document.createElement('option');\n emptyOption.value = '';\n emptyOption.textContent = assigneeTitle;\n select.append(emptyOption);\n\n // 저장된 담당자가 옵션 목록에서 빠졌어도 선택 값이 유실되지 않게 유지한다.\n const hasUnknownAssignee =\n Boolean(value) && !assigneeOptions.some((option) => option.value === value);\n if (hasUnknownAssignee && value) {\n const option = document.createElement('option');\n option.value = value;\n option.textContent = fallbackLabel ?? value;\n select.append(option);\n }\n\n assigneeOptions.forEach((assigneeOption) => {\n const option = document.createElement('option');\n option.value = assigneeOption.value;\n option.textContent = assigneeOption.label;\n select.append(option);\n });\n\n select.value = value ?? '';\n select.addEventListener('change', () => {\n onChange(select.value || null, getAssigneeName(options, select.value));\n });\n\n return select;\n}\n\n/** Collects trimmed form values in the shape createItem expects. */\nexport function getDraftFields(\n options: WebReviewKitOptions,\n titleInput: HTMLInputElement | undefined,\n textarea: HTMLTextAreaElement,\n assigneeSelect: HTMLSelectElement | undefined\n) {\n const title = titleInput?.value.trim();\n const comment = textarea.value.trim();\n const assigneeId = assigneeSelect?.value.trim() || undefined;\n return {\n title: title || undefined,\n comment,\n assigneeId,\n assigneeName: getAssigneeName(options, assigneeId),\n };\n}\n\n/**\n * Save/Cancel action row. Three layouts:\n * - leading: 캡처/조정 버튼을 왼쪽에, Save/Cancel 을 오른쪽 그룹으로\n * - beforeSave/className: Cancel → 추가 버튼 → Save 순서 (커스텀 배치)\n * - 기본: Save → Cancel\n */\nexport function createFormActions({\n saveLabel,\n onSave,\n onCancel,\n isSaving,\n beforeSave,\n className,\n leading,\n}: {\n saveLabel: string;\n onSave: () => void;\n onCancel: (event?: Event) => void;\n isSaving: boolean;\n beforeSave?: HTMLButtonElement[];\n className?: string;\n leading?: HTMLElement[];\n}) {\n const actions = document.createElement('div');\n actions.className = ['dfwr-actions', className].filter(Boolean).join(' ');\n\n const save = document.createElement('button');\n save.className = 'dfwr-button is-primary';\n save.type = 'button';\n save.disabled = isSaving;\n save.setAttribute('aria-busy', isSaving ? 'true' : 'false');\n if (isSaving) {\n save.append(createSpinner('dfwr-spinner'), 'Saving...');\n } else {\n save.textContent = saveLabel;\n }\n save.addEventListener('click', (event) => {\n event.preventDefault();\n event.stopPropagation();\n if (save.disabled) return;\n onSave();\n });\n\n const cancel = document.createElement('button');\n cancel.className = 'dfwr-button';\n cancel.type = 'button';\n cancel.disabled = isSaving;\n cancel.textContent = 'Cancel';\n cancel.addEventListener('click', (event) => {\n onCancel(event);\n });\n\n if (leading?.length) {\n actions.classList.add('has-leading');\n const leadingGroup = document.createElement('div');\n leadingGroup.className = 'dfwr-actions-leading';\n leadingGroup.append(...leading);\n const primary = document.createElement('div');\n primary.className = 'dfwr-actions-primary';\n primary.append(save, cancel);\n actions.append(leadingGroup, primary);\n return actions;\n }\n\n if (beforeSave?.length || className) {\n actions.append(cancel, ...(beforeSave ?? []), save);\n return actions;\n }\n\n actions.append(save, cancel);\n return actions;\n}\n\n/** Inline error line under the draft form; hidden when there is no error. */\nexport function createDraftError(message: string | undefined) {\n if (!message) return undefined;\n\n const error = document.createElement('p');\n error.className = 'dfwr-form-error';\n error.setAttribute('role', 'alert');\n error.textContent = message;\n return error;\n}\n\n/** Grab handle shown on floating composers so they can be dragged around. */\nexport function createDraftDragHandle(label: string) {\n const handle = document.createElement('button');\n handle.className = 'dfwr-draft-drag-handle';\n handle.type = 'button';\n handle.setAttribute('aria-label', label);\n return handle;\n}\n","import type {\n DomAnchor,\n RelativeSelection,\n ReviewItem,\n ReviewPoint,\n ViewportSize,\n} from '../../types';\nimport { getAnchorCandidates } from '../dom.anchor';\nimport type { DomDraft } from './draft';\nimport { getItemMarker, getItemSelection } from './item';\n\n/** Formats DOM draft metadata for compact debug display in the overlay UI. */\nexport function formatDomDraftMeta(draft: DomDraft) {\n const parts = [\n `viewport ${formatSize(draft.viewport)}`,\n `point ${formatPoint(draft.marker.viewport)}`,\n ];\n\n if (draft.anchor) {\n parts.push(formatAnchorMeta(draft.anchor));\n }\n\n return parts.join(' / ');\n}\n\n/** Formats persisted item metadata for list rows, marker titles, and overlays. */\nexport function formatItemMeta(item: ReviewItem) {\n const parts = [formatDate(item.createdAt)];\n const marker = getItemMarker(item);\n const selection = getItemSelection(item);\n\n if (item.viewport) {\n parts.push(`viewport ${formatSize(item.viewport)}`);\n }\n\n if (marker) {\n parts.push(`point ${formatPoint(marker.viewport)}`);\n }\n\n if (selection) {\n parts.push(`rect ${formatSelection(selection.viewport)}`);\n }\n\n if (item.anchor) {\n parts.push(formatAnchorMeta(item.anchor));\n }\n\n return parts.join(' / ');\n}\n\nfunction formatDate(value: string) {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n\n return date.toLocaleString(undefined, {\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction formatSize(size: ViewportSize) {\n return `${Math.round(size.width)}x${Math.round(size.height)}`;\n}\n\nfunction formatPoint(point: ReviewPoint) {\n return `${Math.round(point.x)},${Math.round(point.y)}`;\n}\n\nfunction formatSelection(selection: RelativeSelection) {\n return [\n Math.round(selection.x),\n Math.round(selection.y),\n Math.round(selection.width),\n Math.round(selection.height),\n ].join(',');\n}\n\nfunction formatAnchorMeta(anchor: DomAnchor) {\n const parts = [`dom ${anchor.strategy}`];\n\n if (typeof anchor.confidence === 'number') {\n parts.push(`${Math.round(anchor.confidence * 100)}%`);\n }\n\n const candidates = getAnchorCandidates(anchor);\n if (candidates.length > 1) {\n parts.push(`${candidates.length} candidates`);\n }\n\n return parts.join(' ');\n}\n","// 저장된 리뷰 아이템을 페이지 위에 그리는 마커/하이라이트 레이어.\n// 모든 좌표는 target(대상 페이지) 좌표를 host(셸) 좌표로 변환해서 그린다.\nimport type {\n ReviewItem,\n ReviewItemScope,\n ReviewPoint,\n ReviewViewportPreset,\n} from '../../types';\nimport {\n getViewportSize,\n isPointInViewport,\n toHostPoint,\n toHostSelection,\n type ReviewEnvironment,\n type ViewportSelection,\n} from '../geometry';\nimport { formatItemMeta } from '../review/format';\nimport {\n getBoundMarkerPoint,\n getItemHighlightSelection,\n getReviewItemHighlightMode,\n shouldShowMarkerForScope,\n} from '../review/item';\nimport {\n getNumberedReviewItems,\n getReviewViewportScope,\n} from '../review/scope';\n\n/** Numbered pin marker for a stored item (or the transient area draft dot). */\nexport function createMarkerElement(\n itemId: string | undefined,\n hostPoint: ReviewPoint,\n label: string,\n scope: ReviewItemScope,\n isBound: boolean,\n isHighlighted: boolean\n) {\n const marker = document.createElement('div');\n marker.className = [\n 'dfwr-bound-marker',\n `is-scope-${scope}`,\n isBound ? 'is-bound' : 'is-fallback',\n isHighlighted ? 'is-highlighted' : '',\n ]\n .filter(Boolean)\n .join(' ');\n marker.style.left = `${hostPoint.x}px`;\n marker.style.top = `${hostPoint.y}px`;\n marker.dataset.scope = scope;\n if (itemId) {\n marker.dataset.reviewItemId = itemId;\n }\n\n const iconElement = document.createElement('span');\n iconElement.className = 'dfwr-bound-marker-icon';\n iconElement.setAttribute('aria-hidden', 'true');\n const labelElement = document.createElement('span');\n labelElement.className = 'dfwr-bound-marker-number';\n labelElement.textContent = label;\n marker.append(iconElement, labelElement);\n\n return marker;\n}\n\n/** Dashed rectangle shown while drafting or when restoring a selection. */\nexport function createSelectionHighlight(\n selection: ViewportSelection,\n environment: ReviewEnvironment,\n isDraft: boolean\n) {\n const rect = toHostSelection(selection, environment);\n const highlight = document.createElement('div');\n highlight.className = `dfwr-selection-highlight${\n isDraft ? ' is-draft' : ''\n }`;\n highlight.style.left = `${rect.left}px`;\n highlight.style.top = `${rect.top}px`;\n highlight.style.width = `${rect.width}px`;\n highlight.style.height = `${rect.height}px`;\n return highlight;\n}\n\n/** Highlight box + floating label pair for a stored item's target area. */\nfunction createItemHighlightElements(\n selection: ViewportSelection,\n environment: ReviewEnvironment,\n item: ReviewItem,\n label: string,\n scope: ReviewItemScope,\n isBound: boolean,\n isHighlighted: boolean\n) {\n const rect = toHostSelection(selection, environment);\n const mode = getReviewItemHighlightMode(item);\n const highlight = document.createElement('div');\n highlight.className = [\n 'dfwr-item-target-highlight',\n `is-mode-${mode}`,\n `is-scope-${scope}`,\n isBound ? 'is-bound' : 'is-fallback',\n isHighlighted ? 'is-highlighted' : '',\n ]\n .filter(Boolean)\n .join(' ');\n highlight.style.left = `${rect.left}px`;\n highlight.style.top = `${rect.top}px`;\n highlight.style.width = `${rect.width}px`;\n highlight.style.height = `${rect.height}px`;\n highlight.dataset.reviewItemId = item.id;\n\n const labelElement = document.createElement('div');\n labelElement.className = [\n 'dfwr-item-target-label',\n `is-mode-${mode}`,\n `is-scope-${scope}`,\n isHighlighted ? 'is-highlighted' : '',\n ]\n .filter(Boolean)\n .join(' ');\n labelElement.textContent = label;\n // 라벨은 하이라이트 위쪽에 두되 화면 밖으로 나가지 않게 최소 4px 를 지킨다.\n labelElement.style.left = `${Math.max(4, rect.left)}px`;\n labelElement.style.top = `${Math.max(4, rect.top - 24)}px`;\n labelElement.dataset.reviewItemId = item.id;\n\n return [highlight, labelElement];\n}\n\n/**\n * Renders all visible item markers for the current viewport scope.\n * highlightedItemId 가 있으면 그 아이템만 하이라이트 형태로 강조한다.\n */\nexport function createMarkerLayer({\n items,\n highlightedItemId,\n environment,\n presets,\n showCompactMarkers = true,\n}: {\n items: ReviewItem[];\n highlightedItemId?: string;\n environment: ReviewEnvironment | undefined;\n presets?: ReviewViewportPreset[];\n showCompactMarkers?: boolean;\n}) {\n const layer = document.createElement('div');\n layer.className = 'dfwr-marker-layer';\n if (!environment) return layer;\n\n const currentScope = getReviewViewportScope(\n getViewportSize(environment),\n presets\n );\n\n getNumberedReviewItems(items, presets).forEach((numberedItem) => {\n const { item, scope, displayLabel } = numberedItem;\n // 다른 뷰포트(scope)에서 남긴 아이템은 현재 화면에서 숨긴다.\n if (!shouldShowMarkerForScope(scope, currentScope)) {\n return;\n }\n\n const isHighlighted = item.id === highlightedItemId;\n if (isHighlighted) {\n const selection = getItemHighlightSelection(item, environment);\n if (selection) {\n layer.append(\n ...createItemHighlightElements(\n selection.viewport,\n environment,\n item,\n displayLabel,\n scope,\n selection.isBound,\n isHighlighted\n )\n );\n return;\n }\n }\n\n if (!showCompactMarkers && !isHighlighted) {\n return;\n }\n\n const point = getBoundMarkerPoint(item, environment);\n if (!point || !isPointInViewport(point.viewport, environment)) {\n return;\n }\n\n const hostPoint = toHostPoint(point.viewport, environment);\n const marker = createMarkerElement(\n item.id,\n hostPoint,\n displayLabel,\n scope,\n point.isBound,\n isHighlighted\n );\n marker.title = `${displayLabel} / ${item.comment}\\n${formatItemMeta(item)}`;\n layer.append(marker);\n });\n\n return layer;\n}\n","// Area draft(영역 지정 QA)의 작성 폼, 페이지 오버레이, 플로팅 popover.\n// 폼은 내장 패널(코어 단독)과 플로팅 popover(React 셸) 양쪽에서 재사용된다.\nimport {\n attachDraftImagePasteQueue,\n createDraftAttachmentQueue,\n removeDraftAttachment,\n} from '../draft.attachments';\nimport {\n toHostPoint,\n toHostSelection,\n toViewportSelection,\n} from '../geometry';\nimport type { AreaDraft } from '../review/draft';\nimport { getReviewViewportScope } from '../review/scope';\nimport {\n attachDraftComposerDrag,\n getDraftComposerPosition,\n} from './composer.position';\nimport { createDraftCaptureButton } from './draft.capture';\nimport {\n getAreaDraftMetricSelection,\n getSelectionMetricLines,\n} from './draft.text';\nimport {\n createDraftAssigneeSelect,\n createDraftDragHandle,\n createDraftError,\n createDraftTitleInput,\n createFormActions,\n getDraftFields,\n isTitleFieldEnabled,\n} from './form.widgets';\nimport { createMarkerElement, createSelectionHighlight } from './markers';\nimport type { DraftLayerContext } from './types';\n\n/** Area draft form: metrics, comment, attachments, assignee, save/cancel. */\nexport function createAreaForm(context: DraftLayerContext) {\n const { config } = context;\n const form = document.createElement('form');\n form.className = 'dfwr-form';\n const areaDraft = config.getState().areaDraft;\n\n if (!areaDraft) {\n const empty = document.createElement('p');\n empty.className = 'dfwr-empty';\n empty.textContent = 'Drag on the page to select an area.';\n form.append(empty);\n return form;\n }\n\n form.append(createAreaMetricsPanel(context, areaDraft));\n\n const titleInput = isTitleFieldEnabled(config.options)\n ? createDraftTitleInput(areaDraft.title, (title) => {\n const draft = config.getState().areaDraft;\n if (!draft) return;\n config.actions.setAreaDraft({\n ...draft,\n title,\n });\n })\n : undefined;\n\n const textarea = document.createElement('textarea');\n textarea.className = 'dfwr-textarea';\n textarea.placeholder = 'Area comment';\n textarea.rows = 4;\n textarea.value = areaDraft.comment ?? '';\n textarea.addEventListener('input', () => {\n const draft = config.getState().areaDraft;\n if (!draft) return;\n config.actions.setAreaDraft({\n ...draft,\n comment: textarea.value,\n });\n });\n // textarea 에 이미지를 붙여넣으면 첨부 큐로 들어간다.\n attachDraftImagePasteQueue(textarea, {\n getAttachments: () =>\n config.getState().areaDraft?.attachments ?? areaDraft.attachments,\n onAttachmentsChange: (attachments) => {\n const draft = config.getState().areaDraft ?? areaDraft;\n config.actions.setAreaDraft({\n ...draft,\n comment: textarea.value,\n attachments,\n });\n },\n onCommentChange: (comment) => {\n const draft = config.getState().areaDraft ?? areaDraft;\n config.actions.setAreaDraft({\n ...draft,\n comment,\n });\n },\n onPasteComplete: () => config.actions.render(),\n });\n\n const assigneeSelect = createDraftAssigneeSelect(\n config.options,\n areaDraft.assigneeId,\n areaDraft.assigneeName,\n (assigneeId, assigneeName) => {\n const draft = config.getState().areaDraft;\n if (!draft) return;\n config.actions.setAreaDraft({\n ...draft,\n assigneeId,\n assigneeName,\n });\n }\n );\n\n const actions = createFormActions({\n saveLabel: 'Save area',\n isSaving: config.getState().isCreatingItem,\n onCancel: context.cancelDraft,\n onSave: () => {\n const draft = config.getState().areaDraft;\n const fields = getDraftFields(\n config.options,\n titleInput,\n textarea,\n assigneeSelect\n );\n const comment = fields.comment;\n // 코멘트도 첨부도 없는 빈 draft 는 저장하지 않는다.\n if ((!comment && !draft?.attachments?.length) || !draft) return;\n void config.actions.createItem({\n kind: 'area',\n title: fields.title,\n comment,\n assigneeId: fields.assigneeId,\n assigneeName: fields.assigneeName,\n viewport: draft.viewport,\n anchor: draft.anchor,\n marker: draft.marker,\n selection: draft.selection,\n attachments: draft.attachments,\n });\n },\n leading: [\n createDraftCaptureButton(config, areaDraft, {\n kind: 'area',\n textarea,\n }),\n ],\n });\n const error = createDraftError(config.getState().draftError);\n const attachmentQueue = createDraftAttachmentQueue(\n document,\n areaDraft.attachments,\n (attachmentId) => {\n const draft = config.getState().areaDraft ?? areaDraft;\n const attachments = removeDraftAttachment(\n draft.attachments,\n attachmentId\n );\n config.actions.setAreaDraft({\n ...draft,\n comment: textarea.value,\n attachments: attachments.length > 0 ? attachments : undefined,\n });\n config.actions.render();\n }\n );\n\n form.append(\n ...(titleInput ? [titleInput] : []),\n textarea,\n ...(attachmentQueue ? [attachmentQueue] : []),\n ...(assigneeSelect ? [assigneeSelect] : []),\n ...(error ? [error] : []),\n actions\n );\n return form;\n}\n\n/** Read-only metrics header (design-px position/size) above the area form. */\nfunction createAreaMetricsPanel(context: DraftLayerContext, draft: AreaDraft) {\n const panel = document.createElement('div');\n panel.className = 'dfwr-adjust-panel is-area-metrics-panel';\n\n const [labelLine, xyLine, sizeLine] = getSelectionMetricLines(\n getAreaDraftMetricSelection(draft),\n draft.viewport,\n context.config.options.viewports?.presets\n );\n\n const help = document.createElement('div');\n help.className = 'dfwr-adjust-help';\n help.textContent = labelLine;\n\n const xyStatus = document.createElement('div');\n xyStatus.className = 'dfwr-adjust-status';\n xyStatus.textContent = xyLine;\n\n const sizeStatus = document.createElement('div');\n sizeStatus.className = 'dfwr-adjust-status';\n sizeStatus.textContent = sizeLine;\n\n panel.append(help, xyStatus, sizeStatus);\n return panel;\n}\n\n/** Selection highlight + center dot shown on the page while drafting an area. */\nexport function createAreaDraftOverlay(\n context: DraftLayerContext,\n draft: AreaDraft\n) {\n const { config } = context;\n const layer = document.createElement('div');\n layer.className = 'dfwr-area-preview-layer';\n\n const environment = config.getEnvironment();\n if (!environment || !draft.selection) return layer;\n\n const selection = toViewportSelection(draft.selection.viewport);\n layer.append(createSelectionHighlight(selection, environment, true));\n\n if (draft.marker) {\n const hostPoint = toHostPoint(draft.marker.viewport, environment);\n layer.append(\n createMarkerElement(\n undefined,\n hostPoint,\n '•',\n getReviewViewportScope(\n draft.viewport,\n config.options.viewports?.presets\n ),\n true,\n true\n )\n );\n }\n\n return layer;\n}\n\n/** Floating (or docked) composer popover wrapping the area form. */\nexport function createAreaDraftPopover(\n context: DraftLayerContext,\n draft: AreaDraft,\n options: { dockComposer?: boolean } = {}\n) {\n const { config } = context;\n const environment = config.getEnvironment();\n const popover = document.createElement('div');\n popover.className = [\n 'dfwr-area-draft',\n 'is-composer',\n options.dockComposer ? 'is-docked-composer' : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (options.dockComposer) {\n // 도킹 모드에서는 셸 패널이 폭을 결정한다.\n popover.style.width = '100%';\n } else if (environment && draft.selection) {\n const selection = toHostSelection(\n toViewportSelection(draft.selection.viewport),\n environment\n );\n const composer = getDraftComposerPosition({\n selection,\n environment,\n composerPosition: draft.composerPosition,\n estimatedHeight: 220,\n });\n popover.style.left = `${composer.left}px`;\n popover.style.top = `${composer.top}px`;\n popover.style.width = `${composer.width}px`;\n popover.style.right = 'auto';\n }\n const dragHandle = options.dockComposer\n ? undefined\n : createDraftDragHandle('Move area composer');\n popover.append(\n ...(dragHandle ? [dragHandle] : []),\n createAreaForm(context)\n );\n if (dragHandle) {\n attachDraftComposerDrag({\n getEnvironment: () => config.getEnvironment(),\n popover,\n handle: dragHandle,\n onMove: (composerPosition) => {\n const areaDraft = config.getState().areaDraft ?? draft;\n config.actions.setAreaDraft({\n ...areaDraft,\n composerPosition,\n });\n },\n });\n }\n return popover;\n}\n","// DOM draft(요소 지정 QA)의 페이지 레이어 전체:\n// 마커 핀 + 선택 하이라이트 + 작성 popover + adjustment(위치/스케일 미세조정) 패널.\n// dockComposer 옵션이 켜지면 popover 를 페이지 대신 셸 패널에 도킹한다.\nimport type { ReviewPoint } from '../../types';\nimport {\n attachDraftImagePasteQueue,\n createDraftAttachmentQueue,\n removeDraftAttachment,\n} from '../draft.attachments';\nimport {\n getAdjustedDraftPoint,\n getAdjustedDraftSelection,\n hasDraftAdjustment,\n} from '../draft.metrics';\nimport {\n clampPoint,\n getPopoverPosition,\n roundPoint,\n toHostPoint,\n toHostSelection,\n toTargetPoint,\n toTargetPointFromHostEvent,\n toViewportSelection,\n} from '../geometry';\nimport type { DomDraft } from '../review/draft';\nimport { formatDomDraftMeta } from '../review/format';\nimport {\n attachDraftComposerDrag,\n getDraftComposerPosition,\n} from './composer.position';\nimport { createDraftCaptureButton } from './draft.capture';\nimport {\n getAdjustmentLabel,\n getDraftAdjustmentMetricLines,\n withDraftAdjustmentComment,\n} from './draft.text';\nimport {\n createDraftAssigneeSelect,\n createDraftDragHandle,\n createDraftError,\n createDraftTitleInput,\n createFormActions,\n getDraftFields,\n isTitleFieldEnabled,\n} from './form.widgets';\nimport { setAdjustmentToggleIcon } from './icons';\nimport { createSelectionHighlight } from './markers';\nimport type { DraftLayerContext } from './types';\n\n/**\n * Builds the DOM draft layer: the on-page marker/highlight plus its composer\n * popover. When dockComposer is set the composer element is returned separately\n * so the caller can render it into the side panel instead.\n */\nexport function createDomDraftLayer(\n context: DraftLayerContext,\n draft: DomDraft,\n options: { dockComposer?: boolean } = {}\n): { layer: HTMLElement; composer?: HTMLElement } {\n const { config } = context;\n const presets = config.options.viewports?.presets;\n const environment = config.getEnvironment();\n const group = document.createElement('div');\n group.className = 'dfwr-dom-draft';\n if (!environment) return { layer: group, composer: undefined };\n\n // element 모드에서 selection 이 있으면 \"요소 draft\" — adjustment 조작이 가능하다.\n const isElementDraft =\n config.getState().mode === 'element' && Boolean(draft.selection);\n const hostPoint = toHostPoint(\n isElementDraft\n ? getAdjustedDraftPoint(draft.marker.viewport, draft, presets)\n : draft.marker.viewport,\n environment\n );\n let selectionHighlight: HTMLDivElement | undefined;\n\n if (draft.selection) {\n const selection = toViewportSelection(draft.selection.viewport);\n selectionHighlight = createSelectionHighlight(\n isElementDraft\n ? getAdjustedDraftSelection(selection, draft, presets)\n : selection,\n environment,\n true\n );\n group.append(selectionHighlight);\n }\n\n const pin = document.createElement('button');\n pin.className = 'dfwr-dom-pin';\n pin.type = 'button';\n pin.setAttribute('aria-label', 'Move DOM point');\n pin.style.left = `${hostPoint.x}px`;\n pin.style.top = `${hostPoint.y}px`;\n\n const popover = document.createElement('div');\n const position = getPopoverPosition(hostPoint, environment);\n\n popover.className = [\n 'dfwr-dom-popover',\n isElementDraft ? 'is-composer' : '',\n options.dockComposer ? 'is-docked-composer' : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (options.dockComposer) {\n popover.style.width = '100%';\n } else if (isElementDraft) {\n const selection = draft.selection\n ? toHostSelection(\n getAdjustedDraftSelection(\n toViewportSelection(draft.selection.viewport),\n draft,\n presets\n ),\n environment\n )\n : undefined;\n const composer = getDraftComposerPosition({\n selection,\n environment,\n composerPosition: draft.composerPosition,\n estimatedHeight: 252,\n });\n popover.style.left = `${composer.left}px`;\n popover.style.top = `${composer.top}px`;\n popover.style.width = `${composer.width}px`;\n } else {\n popover.style.left = `${position.left}px`;\n popover.style.top = `${position.top}px`;\n }\n\n const form = document.createElement('form');\n form.className = 'dfwr-form';\n\n // 요소 draft 가 아닐 때만 좌표 메타 라인을 노출한다.\n const meta = isElementDraft ? undefined : document.createElement('div');\n if (meta) {\n meta.className = 'dfwr-item-date';\n meta.textContent = formatDomDraftMeta(draft);\n }\n\n const titleInput = isTitleFieldEnabled(config.options)\n ? createDraftTitleInput(draft.title, (title) => {\n const domDraft = config.getState().domDraft;\n if (!domDraft) return;\n config.actions.setDomDraft({\n ...domDraft,\n title,\n });\n })\n : undefined;\n\n const textarea = document.createElement('textarea');\n textarea.className = 'dfwr-textarea';\n textarea.placeholder = 'Review comment';\n textarea.rows = 4;\n textarea.value = draft.comment ?? '';\n textarea.addEventListener('input', () => {\n const domDraft = config.getState().domDraft;\n if (!domDraft) return;\n config.actions.setDomDraft({\n ...domDraft,\n comment: textarea.value,\n });\n });\n attachDraftImagePasteQueue(textarea, {\n getAttachments: () =>\n config.getState().domDraft?.attachments ?? draft.attachments,\n onAttachmentsChange: (attachments) => {\n const domDraft = config.getState().domDraft ?? draft;\n config.actions.setDomDraft({\n ...domDraft,\n comment: textarea.value,\n attachments,\n });\n },\n onCommentChange: (comment) => {\n const domDraft = config.getState().domDraft ?? draft;\n config.actions.setDomDraft({\n ...domDraft,\n comment,\n });\n },\n onPasteComplete: () => config.actions.render(),\n });\n\n const assigneeSelect = createDraftAssigneeSelect(\n config.options,\n draft.assigneeId,\n draft.assigneeName,\n (assigneeId, assigneeName) => {\n const domDraft = config.getState().domDraft;\n if (!domDraft) return;\n config.actions.setDomDraft({\n ...domDraft,\n assigneeId,\n assigneeName,\n });\n }\n );\n\n const saveDraft = () => {\n const currentDraft = config.getState().domDraft ?? draft;\n const fields = getDraftFields(\n config.options,\n titleInput,\n textarea,\n assigneeSelect\n );\n const comment = fields.comment;\n const hasAttachments = Boolean(currentDraft.attachments?.length);\n // 코멘트/adjustment/첨부 중 하나는 있어야 저장 의미가 있다.\n if (\n !comment &&\n !hasDraftAdjustment(currentDraft, presets) &&\n !hasAttachments\n ) {\n return;\n }\n void config.actions.createItem({\n kind: 'dom',\n title: fields.title,\n comment: withDraftAdjustmentComment(\n comment,\n currentDraft,\n config.options\n ),\n assigneeId: fields.assigneeId,\n assigneeName: fields.assigneeName,\n viewport: currentDraft.viewport,\n anchor: currentDraft.anchor,\n marker: currentDraft.marker,\n selection: currentDraft.selection,\n attachments: currentDraft.attachments,\n });\n };\n\n const adjustmentControls = isElementDraft\n ? createAdjustmentControls(context, {\n draft,\n pin,\n popover,\n selectionHighlight,\n textarea,\n dockToggle: options.dockComposer,\n })\n : undefined;\n const leadingActions = [\n adjustmentControls?.actionButton,\n createDraftCaptureButton(config, draft, {\n kind: 'dom',\n isElementDraft,\n textarea,\n }),\n ].filter((element): element is HTMLButtonElement => Boolean(element));\n\n const actions = createFormActions({\n saveLabel: 'Save DOM QA',\n isSaving: config.getState().isCreatingItem,\n onSave: saveDraft,\n onCancel: context.cancelDraft,\n leading: leadingActions.length > 0 ? leadingActions : undefined,\n });\n const error = createDraftError(config.getState().draftError);\n const attachmentQueue = createDraftAttachmentQueue(\n document,\n draft.attachments,\n (attachmentId) => {\n const domDraft = config.getState().domDraft ?? draft;\n const attachments = removeDraftAttachment(\n domDraft.attachments,\n attachmentId\n );\n config.actions.setDomDraft({\n ...domDraft,\n comment: textarea.value,\n attachments: attachments.length > 0 ? attachments : undefined,\n });\n config.actions.render();\n }\n );\n\n form.append(\n ...(meta ? [meta] : []),\n ...(adjustmentControls ? [adjustmentControls.panel] : []),\n ...(titleInput ? [titleInput] : []),\n textarea,\n ...(attachmentQueue ? [attachmentQueue] : []),\n ...(assigneeSelect ? [assigneeSelect] : []),\n ...(error ? [error] : []),\n actions\n );\n const dragHandle =\n isElementDraft && !options.dockComposer\n ? createDraftDragHandle('Move DOM composer')\n : undefined;\n popover.append(...(dragHandle ? [dragHandle] : []), form);\n group.append(pin);\n if (!options.dockComposer) {\n group.append(popover);\n }\n\n if (dragHandle) {\n attachDraftComposerDrag({\n getEnvironment: () => config.getEnvironment(),\n popover,\n handle: dragHandle,\n onMove: (composerPosition) => {\n const domDraft = config.getState().domDraft ?? draft;\n config.actions.setDomDraft({\n ...domDraft,\n composerPosition,\n comment: textarea.value,\n });\n },\n });\n }\n\n // 요소 draft 는 popover 가 자체 드래그 핸들로 움직이므로 핀만 이동시킨다.\n attachDraftPinDrag(context, {\n pin,\n popover: isElementDraft || options.dockComposer ? undefined : popover,\n meta,\n textarea,\n });\n\n if (!options.dockComposer) {\n // 렌더 직후 포커스: adjustment 조작 중이면 토글, 아니면 코멘트 입력으로.\n window.setTimeout(() => {\n if (draft.adjustment?.isActive) {\n adjustmentControls?.focusTarget.focus();\n return;\n }\n\n textarea.focus();\n }, 0);\n }\n\n return {\n layer: group,\n composer: options.dockComposer ? popover : undefined,\n };\n}\n\n/**\n * Element-adjustment controls (nudge the previewed element via arrow keys /\n * buttons). Wires keyboard deltas to the draft transform and keeps the pin,\n * popover, highlight and textarea in sync as the value changes.\n */\nfunction createAdjustmentControls(\n context: DraftLayerContext,\n {\n draft,\n pin,\n popover,\n selectionHighlight,\n textarea,\n dockToggle,\n }: {\n draft: DomDraft;\n pin: HTMLButtonElement;\n popover: HTMLDivElement;\n selectionHighlight?: HTMLDivElement;\n textarea: HTMLTextAreaElement;\n dockToggle?: boolean;\n }\n) {\n const { config } = context;\n const presets = config.options.viewports?.presets;\n const panel = document.createElement('div');\n panel.className = 'dfwr-adjust-panel is-dom-adjust-panel';\n\n const header = document.createElement('div');\n header.className = 'dfwr-adjust-panel-header';\n const help = document.createElement('div');\n help.className = 'dfwr-adjust-help';\n help.textContent = getAdjustmentLabel(config.options);\n\n const adjust = document.createElement('button');\n adjust.className = 'dfwr-adjust-toggle';\n adjust.type = 'button';\n adjust.title = 'Adjust DOM element with keyboard arrows';\n adjust.setAttribute('aria-label', 'Adjust DOM element with keyboard arrows');\n\n const xyStatus = document.createElement('div');\n xyStatus.className = 'dfwr-adjust-status';\n\n const scaleStatus = document.createElement('div');\n scaleStatus.className = 'dfwr-adjust-status';\n\n const syncControls = (nextDraft: DomDraft) => {\n const isActive = nextDraft.adjustment?.isActive === true;\n panel.classList.toggle('is-active', isActive);\n adjust.classList.toggle('is-active', isActive);\n adjust.setAttribute('aria-pressed', isActive ? 'true' : 'false');\n setAdjustmentToggleIcon(adjust, isActive);\n adjust.title = isActive\n ? 'Finish DOM adjustment'\n : 'Adjust DOM element with keyboard arrows';\n adjust.setAttribute(\n 'aria-label',\n isActive\n ? 'Finish DOM adjustment'\n : 'Adjust DOM element with keyboard arrows'\n );\n const [xyLine, scaleLine] = getDraftAdjustmentMetricLines(\n nextDraft,\n presets\n );\n xyStatus.textContent = xyLine;\n scaleStatus.textContent = scaleLine;\n syncDraftAdjustmentUi(context, {\n draft: nextDraft,\n pin,\n selectionHighlight,\n });\n };\n\n const updateDraft = (updater: (current: DomDraft) => DomDraft) => {\n const currentDraft = config.getState().domDraft ?? draft;\n const nextDraft = updater(currentDraft);\n config.actions.setDomDraft({\n ...nextDraft,\n comment: textarea.value,\n });\n syncControls(nextDraft);\n };\n\n adjust.addEventListener('click', () => {\n updateDraft((currentDraft) => ({\n ...currentDraft,\n adjustment: {\n x: currentDraft.adjustment?.x ?? 0,\n y: currentDraft.adjustment?.y ?? 0,\n scale: currentDraft.adjustment?.scale ?? 0,\n isActive: currentDraft.adjustment?.isActive !== true,\n },\n }));\n adjust.focus();\n });\n\n popover.addEventListener('keydown', (event) => {\n const currentDraft = config.getState().domDraft ?? draft;\n if (currentDraft.adjustment?.isActive !== true) return;\n\n const keyDelta = getAdjustmentKeyDelta(event);\n if (!keyDelta) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n updateDraft((activeDraft) => ({\n ...activeDraft,\n adjustment: {\n x: (activeDraft.adjustment?.x ?? 0) + keyDelta.x,\n y: (activeDraft.adjustment?.y ?? 0) + keyDelta.y,\n scale: (activeDraft.adjustment?.scale ?? 0) + keyDelta.scale,\n isActive: true,\n },\n }));\n });\n\n header.append(help);\n if (!dockToggle) {\n header.append(adjust);\n }\n panel.append(header, xyStatus, scaleStatus);\n syncControls(draft);\n\n return {\n panel,\n focusTarget: adjust,\n // 도킹 모드에서는 토글 버튼을 폼 액션 줄(leading)로 옮긴다.\n actionButton: dockToggle ? adjust : undefined,\n };\n}\n\n/** 화살표 = x/y 이동, w/s = 스케일. Shift 는 10px 단위. */\nfunction getAdjustmentKeyDelta(event: KeyboardEvent) {\n const step = event.shiftKey ? 10 : 1;\n\n if (event.key === 'ArrowLeft') return { x: -step, y: 0, scale: 0 };\n if (event.key === 'ArrowRight') return { x: step, y: 0, scale: 0 };\n if (event.key === 'ArrowUp') return { x: 0, y: -step, scale: 0 };\n if (event.key === 'ArrowDown') return { x: 0, y: step, scale: 0 };\n if (event.key.toLowerCase() === 'w') return { x: 0, y: 0, scale: step };\n if (event.key.toLowerCase() === 's') return { x: 0, y: 0, scale: -step };\n\n return undefined;\n}\n\n/** Re-applies adjusted coordinates to the pin/highlight and the live preview. */\nfunction syncDraftAdjustmentUi(\n context: DraftLayerContext,\n {\n draft,\n pin,\n selectionHighlight,\n }: {\n draft: DomDraft;\n pin: HTMLButtonElement;\n selectionHighlight?: HTMLDivElement;\n }\n) {\n const { config } = context;\n const presets = config.options.viewports?.presets;\n const environment = config.getEnvironment();\n if (!environment) return;\n\n const hostPoint = toHostPoint(\n getAdjustedDraftPoint(draft.marker.viewport, draft, presets),\n environment\n );\n pin.style.left = `${hostPoint.x}px`;\n pin.style.top = `${hostPoint.y}px`;\n\n if (draft.selection && selectionHighlight) {\n const rect = toHostSelection(\n getAdjustedDraftSelection(\n toViewportSelection(draft.selection.viewport),\n draft,\n presets\n ),\n environment\n );\n selectionHighlight.style.left = `${rect.left}px`;\n selectionHighlight.style.top = `${rect.top}px`;\n selectionHighlight.style.width = `${rect.width}px`;\n selectionHighlight.style.height = `${rect.height}px`;\n }\n\n context.syncDraftPreview(draft);\n}\n\n/**\n * Pin drag: moves the marker point. On release the draft is re-bound to the\n * element under the new point (bindElementDraftToPoint), carrying form fields.\n */\nfunction attachDraftPinDrag(\n context: DraftLayerContext,\n {\n pin,\n popover,\n meta,\n textarea,\n }: {\n pin: HTMLButtonElement;\n popover: HTMLDivElement | undefined;\n meta: HTMLDivElement | undefined;\n textarea: HTMLTextAreaElement;\n }\n) {\n const { config } = context;\n let isDragging = false;\n\n const moveDraftUi = (hostPoint: ReviewPoint) => {\n const environment = config.getEnvironment();\n if (!environment) return;\n\n const nextPoint = clampPoint(\n toTargetPoint(hostPoint, environment),\n environment\n );\n const nextHostPoint = toHostPoint(nextPoint, environment);\n\n pin.style.left = `${nextHostPoint.x}px`;\n pin.style.top = `${nextHostPoint.y}px`;\n if (popover) {\n const position = getPopoverPosition(nextHostPoint, environment);\n popover.style.left = `${position.left}px`;\n popover.style.top = `${position.top}px`;\n }\n\n const domDraft = config.getState().domDraft;\n if (!domDraft) return;\n\n const nextDraft = {\n ...domDraft,\n marker: {\n ...domDraft.marker,\n viewport: roundPoint(nextPoint),\n },\n comment: textarea.value,\n };\n config.actions.setDomDraft(nextDraft);\n if (meta) {\n meta.textContent = formatDomDraftMeta(nextDraft);\n }\n };\n\n pin.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n\n event.preventDefault();\n event.stopPropagation();\n isDragging = true;\n pin.setPointerCapture(event.pointerId);\n });\n\n pin.addEventListener('pointermove', (event) => {\n if (!isDragging || !pin.hasPointerCapture(event.pointerId)) return;\n\n event.preventDefault();\n moveDraftUi({\n x: event.clientX,\n y: event.clientY,\n });\n });\n\n pin.addEventListener('pointerup', (event) => {\n if (!isDragging || !pin.hasPointerCapture(event.pointerId)) return;\n\n event.preventDefault();\n event.stopPropagation();\n isDragging = false;\n pin.releasePointerCapture(event.pointerId);\n\n const nextPoint = toTargetPointFromHostEvent(\n event,\n config.getEnvironment()\n );\n const currentDraft = config.getState().domDraft;\n const fields = {\n title: currentDraft?.title,\n comment: textarea.value,\n assigneeId: currentDraft?.assigneeId,\n assigneeName: currentDraft?.assigneeName,\n };\n void config.actions.bindElementDraftToPoint(nextPoint, fields);\n });\n}\n","// 코어 단독 사용 시 노출되는 내장 사이드 패널 (React 셸 모드에서는 비활성).\n// 헤더/툴바/본문/아이템 리스트를 렌더링한다.\nimport type { NumberedReviewItem } from '../../types';\nimport { getRouteKey } from '../location';\nimport { formatItemMeta } from '../review/format';\nimport { getNumberedReviewItems } from '../review/scope';\nimport { isTitleFieldEnabled } from './form.widgets';\nimport type { WebReviewKitViewConfig } from './types';\n\n/** Builds the whole built-in panel; area draft form is injected by the caller. */\nexport function createReviewPanel(\n config: WebReviewKitViewConfig,\n renderAreaForm: () => HTMLElement\n) {\n const panel = document.createElement('div');\n panel.className = 'dfwr-panel';\n panel.setAttribute('role', 'dialog');\n panel.setAttribute('aria-label', 'Web review kit');\n\n panel.append(\n createHeader(config),\n createToolbar(config),\n createBody(config, renderAreaForm),\n createList(config)\n );\n\n return panel;\n}\n\nfunction createHeader(config: WebReviewKitViewConfig) {\n const header = document.createElement('div');\n header.className = 'dfwr-header';\n\n const title = document.createElement('div');\n title.className = 'dfwr-title';\n title.textContent = 'Review Kit';\n\n const meta = document.createElement('div');\n meta.className = 'dfwr-meta';\n meta.textContent = getRouteKey(config.getEnvironment());\n\n const titleGroup = document.createElement('div');\n titleGroup.append(title, meta);\n\n const close = document.createElement('button');\n close.className = 'dfwr-icon-button';\n close.type = 'button';\n close.textContent = 'x';\n close.setAttribute('aria-label', 'Close');\n close.addEventListener('click', () => config.actions.close());\n\n header.append(titleGroup, close);\n return header;\n}\n\nfunction createToolbar(config: WebReviewKitViewConfig) {\n const state = config.getState();\n const toolbar = document.createElement('div');\n toolbar.className = 'dfwr-toolbar';\n\n // 모드 버튼은 토글: 같은 모드를 다시 누르면 idle 로 돌아간다.\n const toggleMode = (target: 'element' | 'area') => {\n const mode = config.getState().mode;\n config.actions.setModeState(mode === target ? 'idle' : target);\n config.actions.clearDrafts();\n config.actions.render();\n };\n\n toolbar.append(\n createToolbarButton('Element', state.mode === 'element', () =>\n toggleMode('element')\n ),\n createToolbarButton(\n state.isSelectingArea ? 'Selecting' : 'Area',\n state.mode === 'area',\n () => toggleMode('area')\n ),\n createToolbarButton('Refresh', false, () => {\n void config.actions.reload();\n })\n );\n\n return toolbar;\n}\n\nfunction createToolbarButton(\n label: string,\n active: boolean,\n onClick: () => void\n) {\n const button = document.createElement('button');\n button.className = `dfwr-button${active ? ' is-active' : ''}`;\n button.type = 'button';\n button.textContent = label;\n button.addEventListener('click', onClick);\n return button;\n}\n\nfunction createBody(\n config: WebReviewKitViewConfig,\n renderAreaForm: () => HTMLElement\n) {\n const body = document.createElement('div');\n body.className = 'dfwr-body';\n const state = config.getState();\n\n if (state.mode === 'idle') {\n body.append(\n createEmptyText('Select an element or mark an area.')\n );\n return body;\n }\n\n if (state.mode === 'element') {\n // element 모드의 작성 폼은 페이지 위 popover 로 뜨므로 안내문만 표시.\n body.append(\n createEmptyText(\n state.domDraft\n ? 'Write the QA in the page box.'\n : 'Click an element to add QA.'\n )\n );\n return body;\n }\n\n body.append(renderAreaForm());\n return body;\n}\n\nfunction createEmptyText(text: string) {\n const empty = document.createElement('p');\n empty.className = 'dfwr-empty';\n empty.textContent = text;\n return empty;\n}\n\nfunction createList(config: WebReviewKitViewConfig) {\n const section = document.createElement('div');\n section.className = 'dfwr-list';\n const state = config.getState();\n\n const heading = document.createElement('div');\n heading.className = 'dfwr-list-heading';\n heading.textContent = `Review items (${state.items.length})`;\n section.append(heading);\n\n if (state.items.length === 0) {\n section.append(createEmptyText('No review items on this page.'));\n return section;\n }\n\n for (const numberedItem of getNumberedReviewItems(\n state.items,\n config.options.viewports?.presets\n )) {\n section.append(createListItem(config, numberedItem));\n }\n\n return section;\n}\n\nfunction createListItem(\n config: WebReviewKitViewConfig,\n numberedItem: NumberedReviewItem\n) {\n const { item } = numberedItem;\n const row = document.createElement('article');\n row.className = 'dfwr-item';\n row.tabIndex = 0;\n row.setAttribute('role', 'button');\n row.setAttribute(\n 'aria-label',\n `Restore review item: ${item.title ?? item.comment}`\n );\n row.addEventListener('click', () => {\n void config.actions.restoreItem(item);\n });\n row.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n event.preventDefault();\n void config.actions.restoreItem(item);\n });\n\n const body = document.createElement('div');\n body.className = 'dfwr-item-body';\n\n const badges = document.createElement('div');\n badges.className = 'dfwr-item-badges';\n\n const scope = document.createElement('div');\n scope.className = `dfwr-item-scope is-scope-${numberedItem.scope}`;\n scope.textContent = numberedItem.displayLabel;\n\n const kind = document.createElement('div');\n kind.className = 'dfwr-item-kind';\n kind.textContent = item.kind;\n badges.append(scope, kind);\n\n const title = isTitleFieldEnabled(config.options) ? item.title?.trim() : '';\n const titleElement = title ? document.createElement('strong') : undefined;\n if (title && titleElement) {\n titleElement.className = 'dfwr-item-title';\n titleElement.textContent = title;\n }\n\n const comment = document.createElement('p');\n comment.className = `dfwr-item-comment${title ? '' : ' is-primary'}`;\n comment.textContent = item.comment;\n\n const date = document.createElement('time');\n date.className = 'dfwr-item-date';\n date.dateTime = item.createdAt;\n date.textContent = formatItemMeta(item);\n\n body.append(badges, ...(titleElement ? [titleElement] : []), comment, date);\n\n const actions = document.createElement('div');\n actions.className = 'dfwr-item-actions';\n // 삭제 버튼 클릭이 행 전체의 restore 클릭으로 전파되지 않게 차단.\n actions.addEventListener('click', (event) => event.stopPropagation());\n actions.addEventListener('keydown', (event) => event.stopPropagation());\n\n const remove = document.createElement('button');\n remove.className = 'dfwr-icon-button';\n remove.type = 'button';\n remove.textContent = 'x';\n remove.setAttribute('aria-label', 'Delete');\n remove.addEventListener('click', (event) => {\n event.stopPropagation();\n void config.actions\n .removeItem(item.id)\n .then(() => config.actions.reload());\n });\n\n actions.append(remove);\n row.append(body, actions);\n return row;\n}\n","// 리뷰 대상 선택용 전면 레이어 두 종류.\n// - element layer: hover 로 DOM 요소를 하이라이트하고 클릭으로 draft 를 바인딩\n// - area layer: 드래그로 사각형 영역을 선택해 area draft 를 시작\nimport type { ReviewPoint } from '../../types';\nimport {\n getDomAnchorFromPoint,\n getElementViewportSelection,\n} from '../dom.anchor';\nimport {\n clampPoint,\n placeLayerOverTarget,\n toHostSelection,\n toTargetPointFromHostEvent,\n type ViewportSelection,\n} from '../geometry';\nimport type { WebReviewKitViewConfig } from './types';\n\n/** Element-pick layer: hover highlight + click-to-bind for DOM QA drafts. */\nexport function createElementLayer(config: WebReviewKitViewConfig) {\n const layer = document.createElement('div');\n layer.className = 'dfwr-element-layer';\n const environment = config.getEnvironment();\n const hover = document.createElement('div');\n hover.className = 'dfwr-dom-hover';\n hover.hidden = true;\n layer.append(hover);\n\n if (environment) {\n placeLayerOverTarget(layer, environment);\n }\n\n const updateHover = (point: ReviewPoint) => {\n // 스크롤/리사이즈로 environment 가 바뀔 수 있어 매번 다시 읽는다.\n const nextEnvironment = config.getEnvironment();\n if (!nextEnvironment) return;\n\n const anchor = getDomAnchorFromPoint(\n clampPoint(point, nextEnvironment),\n config.options.anchors?.attribute,\n nextEnvironment\n );\n const selection = anchor\n ? getElementViewportSelection(anchor, nextEnvironment)\n : undefined;\n\n if (!selection) {\n hover.hidden = true;\n return;\n }\n\n const rect = toHostSelection(selection, nextEnvironment);\n hover.hidden = false;\n hover.style.left = `${rect.left}px`;\n hover.style.top = `${rect.top}px`;\n hover.style.width = `${rect.width}px`;\n hover.style.height = `${rect.height}px`;\n };\n\n layer.addEventListener('pointermove', (event) => {\n updateHover(toTargetPointFromHostEvent(event, config.getEnvironment()));\n });\n\n layer.addEventListener('pointerleave', () => {\n hover.hidden = true;\n });\n\n layer.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n event.preventDefault();\n void config.actions.bindElementDraftToPoint(\n toTargetPointFromHostEvent(event, config.getEnvironment())\n );\n });\n\n return layer;\n}\n\n/** Area-select layer: drag a rectangle, then hand it off as an area draft. */\nexport function createAreaLayer(config: WebReviewKitViewConfig) {\n const layer = document.createElement('div');\n layer.className = 'dfwr-area-layer';\n const environment = config.getEnvironment();\n\n if (environment) {\n placeLayerOverTarget(layer, environment);\n }\n\n const box = document.createElement('div');\n box.className = 'dfwr-area-box';\n layer.append(box);\n\n let startX = 0;\n let startY = 0;\n let selection: ViewportSelection | undefined;\n let activePointerId: number | undefined;\n let isDragging = false;\n // iframe 안에서 렌더될 수 있어 layer 가 속한 window 의 이벤트를 쓴다.\n const ownerWindow = layer.ownerDocument.defaultView ?? window;\n\n const updateBox = (event: PointerEvent) => {\n const nextEnvironment = config.getEnvironment();\n const nextPoint = toTargetPointFromHostEvent(event, nextEnvironment);\n const left = Math.min(startX, nextPoint.x);\n const top = Math.min(startY, nextPoint.y);\n const width = Math.abs(nextPoint.x - startX);\n const height = Math.abs(nextPoint.y - startY);\n\n selection = { left, top, width, height };\n const rect = nextEnvironment\n ? toHostSelection(selection, nextEnvironment)\n : selection;\n box.style.left = `${rect.left}px`;\n box.style.top = `${rect.top}px`;\n box.style.width = `${rect.width}px`;\n box.style.height = `${rect.height}px`;\n };\n\n // pointer capture 가 끊기는 환경(iframe 리플로우 등)에 대비해\n // window 레벨 리스너를 드래그 동안에만 추가로 건다.\n const addDragListeners = () => {\n ownerWindow.addEventListener('pointermove', handlePointerMove, true);\n ownerWindow.addEventListener('pointerup', handlePointerUp, true);\n ownerWindow.addEventListener('pointercancel', handlePointerCancel, true);\n };\n\n const removeDragListeners = () => {\n ownerWindow.removeEventListener('pointermove', handlePointerMove, true);\n ownerWindow.removeEventListener('pointerup', handlePointerUp, true);\n ownerWindow.removeEventListener(\n 'pointercancel',\n handlePointerCancel,\n true\n );\n };\n\n const releasePointerCapture = (event: PointerEvent) => {\n try {\n if (layer.hasPointerCapture(event.pointerId)) {\n layer.releasePointerCapture(event.pointerId);\n }\n } catch {\n // Pointer capture can be gone when the iframe/overlay reflows mid-drag.\n }\n };\n\n function isActivePointer(event: PointerEvent) {\n return isDragging && event.pointerId === activePointerId;\n }\n\n const finishAreaSelection = (event: PointerEvent) => {\n if (!isActivePointer(event)) return;\n\n event.preventDefault();\n updateBox(event);\n releasePointerCapture(event);\n removeDragListeners();\n isDragging = false;\n activePointerId = undefined;\n\n // 실수로 스친 드래그(8px 미만)는 무시한다.\n if (!selection || selection.width < 8 || selection.height < 8) return;\n\n config.actions.setSelectingArea(true);\n config.actions.render();\n void config.actions.createAreaDraft(selection);\n };\n\n function handlePointerMove(event: PointerEvent) {\n if (!isActivePointer(event)) return;\n\n event.preventDefault();\n updateBox(event);\n }\n\n const handlePointerUp = (event: PointerEvent) => {\n finishAreaSelection(event);\n };\n\n const handlePointerCancel = (event: PointerEvent) => {\n if (!isActivePointer(event)) return;\n\n releasePointerCapture(event);\n removeDragListeners();\n isDragging = false;\n activePointerId = undefined;\n };\n\n layer.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n\n event.preventDefault();\n activePointerId = event.pointerId;\n isDragging = true;\n\n try {\n layer.setPointerCapture(event.pointerId);\n } catch {\n // Continue with window-level listeners when capture is unavailable.\n }\n\n const startPoint = toTargetPointFromHostEvent(\n event,\n config.getEnvironment()\n );\n startX = startPoint.x;\n startY = startPoint.y;\n updateBox(event);\n addDragListeners();\n });\n\n layer.addEventListener('pointermove', handlePointerMove);\n layer.addEventListener('pointerup', handlePointerUp);\n layer.addEventListener('pointercancel', handlePointerCancel);\n\n return layer;\n}\n","// 코어 오버레이의 진입 렌더러. 실제 DOM 조립은 view/* 모듈이 담당하고\n// 이 클래스는 상태를 읽어 어떤 레이어를 그릴지 결정하는 오케스트레이션과\n// 셸 패널로의 composer 도킹만 책임진다.\n//\n// 모듈 구성:\n// - view/panel.ts 내장 사이드 패널 (헤더/툴바/리스트)\n// - view/markers.ts 저장된 아이템 마커/하이라이트 레이어\n// - view/selection.layers.ts 요소 클릭 / 영역 드래그 선택 레이어\n// - view/dom.draft.ts DOM draft 작성 popover + adjustment 조작\n// - view/area.draft.ts Area draft 폼/오버레이/popover\n// - view/form.widgets.ts 폼 공용 위젯, view/draft.capture.ts 캡처 버튼\n// - view/composer.position.ts / draft.text.ts / icons.ts 순수 헬퍼\nimport * as draftMetrics from './draft.metrics';\nimport { DraftPreviewController } from './draft.preview';\nimport { createStyleElement } from './overlay.style';\nimport { createAreaDraftOverlay, createAreaDraftPopover, createAreaForm } from './view/area.draft';\nimport { createDomDraftLayer } from './view/dom.draft';\nimport { createMarkerLayer } from './view/markers';\nimport { createReviewPanel } from './view/panel';\nimport { createAreaLayer, createElementLayer } from './view/selection.layers';\nimport type {\n DraftLayerContext,\n WebReviewKitViewConfig,\n} from './view/types';\n\nexport type {\n CreateReviewItemInput,\n WebReviewKitViewConfig,\n} from './view/types';\n\n/** Vanilla DOM renderer for the core overlay, separate from React shell chrome. */\nexport class WebReviewKitView {\n private readonly draftPreview: DraftPreviewController;\n private readonly draftContext: DraftLayerContext;\n /** React 셸 패널 안에 composer 를 도킹했을 때의 호스트 요소. */\n private shellComposerHost?: HTMLElement;\n\n constructor(private readonly config: WebReviewKitViewConfig) {\n const presets = () => this.config.options.viewports?.presets;\n this.draftPreview = new DraftPreviewController({\n getEnvironment: () => this.config.getEnvironment(),\n getMetrics: (draft) =>\n draftMetrics.getDraftAdjustmentMetrics(draft, presets()),\n hasAdjustment: (draft) =>\n draftMetrics.hasDraftAdjustment(draft, presets()),\n });\n // draft 레이어 모듈들이 공유하는 컨텍스트. config 외에 뷰 인스턴스가\n // 소유한 preview 동기화/취소 동작을 콜백으로 넘긴다.\n this.draftContext = {\n config: this.config,\n cancelDraft: (event) => this.cancelDraft(event),\n syncDraftPreview: (draft) => this.draftPreview.sync(draft),\n };\n }\n\n clearDraftPreview() {\n this.draftPreview.clear();\n this.clearShellComposer();\n }\n\n /** Rebuilds the entire shadow-root UI from the current state snapshot. */\n render(shadow: ShadowRoot, hiddenItemsStyle: HTMLStyleElement) {\n const state = this.state;\n this.draftPreview.sync(\n state.isOpen && state.mode === 'element' ? state.domDraft : undefined\n );\n\n shadow.replaceChildren();\n shadow.append(createStyleElement());\n shadow.append(hiddenItemsStyle);\n\n const hasDismissableDraft = Boolean(state.domDraft || state.areaDraft);\n // 셸 모드(panel: false)에서 composerHost 가 준비돼 있으면 폼을 패널에 도킹.\n const shouldDockComposer =\n this.config.options.ui?.panel === false &&\n hasDismissableDraft &&\n Boolean(this.getShellComposerHost());\n let dockedComposer: HTMLElement | undefined;\n const shell = document.createElement('div');\n shell.className = [\n 'dfwr-shell',\n state.isOpen ? 'is-open' : '',\n hasDismissableDraft && !shouldDockComposer ? 'has-dismissible-draft' : '',\n ]\n .filter(Boolean)\n .join(' ');\n shell.setAttribute('aria-hidden', state.isOpen ? 'false' : 'true');\n\n if (this.config.options.ui?.panel !== false) {\n // Standalone core usage gets a built-in panel; React shell disables this.\n shell.append(\n createReviewPanel(this.config, () =>\n createAreaForm(this.draftContext)\n )\n );\n }\n\n shell.append(\n createMarkerLayer({\n items: state.items,\n highlightedItemId: state.highlightedItemId,\n environment: this.config.getEnvironment(),\n presets: this.config.options.viewports?.presets,\n showCompactMarkers: this.config.options.ui?.markers !== 'external',\n })\n );\n if (state.isOpen && hasDismissableDraft && !shouldDockComposer) {\n shell.append(this.createDraftCancelLayer());\n }\n\n if (state.isOpen && state.mode === 'element') {\n if (state.domDraft) {\n const domDraft = createDomDraftLayer(this.draftContext, state.domDraft, {\n dockComposer: shouldDockComposer,\n });\n shell.append(domDraft.layer);\n dockedComposer = domDraft.composer;\n } else {\n shell.append(createElementLayer(this.config));\n }\n }\n\n if (\n state.isOpen &&\n state.mode === 'area' &&\n !state.areaDraft &&\n !state.isSelectingArea\n ) {\n shell.append(createAreaLayer(this.config));\n }\n\n if (\n state.isOpen &&\n state.mode === 'area' &&\n state.areaDraft &&\n this.config.options.ui?.panel === false\n ) {\n // Shell mode renders the draft form near the target because the side panel is React-owned.\n if (state.areaDraft.selection) {\n shell.append(createAreaDraftOverlay(this.draftContext, state.areaDraft));\n }\n const areaComposer = createAreaDraftPopover(\n this.draftContext,\n state.areaDraft,\n { dockComposer: shouldDockComposer }\n );\n if (shouldDockComposer) {\n dockedComposer = areaComposer;\n } else {\n shell.append(areaComposer);\n }\n }\n\n shadow.append(shell);\n this.renderShellComposer(dockedComposer);\n }\n\n private get state() {\n return this.config.getState();\n }\n\n private getShellComposerHost() {\n const environment = this.config.getEnvironment();\n if (this.config.options.ui?.panel !== false) return undefined;\n return environment?.composerHost ?? undefined;\n }\n\n /** Mounts the docked composer into the shell-provided host element. */\n private renderShellComposer(composer?: HTMLElement) {\n const host = composer ? this.getShellComposerHost() : undefined;\n if (!host || !composer) {\n this.clearShellComposer();\n return;\n }\n\n if (this.shellComposerHost && this.shellComposerHost !== host) {\n this.clearShellComposer();\n }\n\n this.shellComposerHost = host;\n // React 셸이 CSS 로 도킹 상태를 표시할 수 있게 data 속성을 남긴다.\n host.dataset.hasDraftComposer = 'true';\n if (host.parentElement) {\n host.parentElement.dataset.hasDraftComposer = 'true';\n }\n\n const shell = document.createElement('div');\n shell.className = 'dfwr-shell is-open is-shell-draft is-docked-composer';\n shell.append(composer);\n\n host.replaceChildren(createStyleElement(), shell);\n }\n\n private clearShellComposer() {\n const host = this.shellComposerHost;\n host?.replaceChildren();\n if (host) {\n delete host.dataset.hasDraftComposer;\n delete host.parentElement?.dataset.hasDraftComposer;\n }\n this.shellComposerHost = undefined;\n }\n\n /** Full-screen click-away layer that cancels the active draft. */\n private createDraftCancelLayer() {\n const layer = document.createElement('div');\n layer.className = 'dfwr-draft-cancel-layer';\n layer.setAttribute('aria-hidden', 'true');\n\n layer.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n this.cancelDraft(event);\n });\n\n return layer;\n }\n\n private cancelDraft(event?: Event) {\n event?.preventDefault();\n event?.stopPropagation();\n event?.stopImmediatePropagation();\n this.config.actions.setModeState('idle');\n this.config.actions.clearDrafts();\n this.config.actions.setSelectingArea(false);\n this.config.actions.render();\n }\n}\n","import { localAdapter } from '../adapters/local';\nimport type {\n DomAnchor,\n ReviewAttachment,\n ReviewItem,\n ReviewMarker,\n ReviewMode,\n ReviewPoint,\n ReviewSelection,\n RelativeSelection,\n ReviewViewportCaptureInput,\n ReviewViewportCaptureResult,\n WebReviewKitAdapter,\n WebReviewKitController,\n WebReviewKitOptions,\n} from '../types';\nimport {\n cssEscape,\n getDomAnchorFromElement,\n getDomAnchorFromPoint,\n getElementViewportSelection,\n getRelativePoint,\n getRelativeSelection,\n} from './dom.anchor';\nimport {\n createId,\n} from './id';\nimport {\n clampPoint,\n getPointSelection,\n getSelectionCenter,\n getViewportSize,\n roundPoint,\n toPublicSelection,\n type ReviewEnvironment,\n type ViewportSelection,\n} from './geometry';\nimport { isHotkey } from './hotkey';\nimport {\n getOriginalUrl,\n getPageUrl,\n getRouteKey,\n} from './location';\nimport { getReviewViewportScope } from './review/scope';\nimport { createSelectionStartMarker } from './review/item';\nimport type {\n AreaDraft,\n DomDraft,\n ReviewDraftAttachment,\n ReviewDraftPreviewElement,\n} from './review/draft';\nimport {\n runWithAutoScrollBehavior,\n setDocumentScrollInstantly,\n waitForNextFrame,\n} from './scroll';\nimport {\n WebReviewKitView,\n type CreateReviewItemInput,\n} from './web.review.kit.view';\n\nconst ROOT_ID = 'df-web-review-kit-root';\n\ntype DraftItemFields = Partial<\n Pick<ReviewItem, 'title' | 'comment' | 'assigneeId' | 'assigneeName'>\n>;\n\ntype CaptureDraftInput = Pick<\n AreaDraft,\n 'marker' | 'selection' | 'viewport'\n>;\n\nfunction isEditableEventTarget(event: KeyboardEvent) {\n const path = event.composedPath?.() ?? [];\n const element = (path[0] ?? event.target) as HTMLElement | null;\n if (!element || typeof element.tagName !== 'string') return false;\n\n const tag = element.tagName;\n return (\n tag === 'INPUT' ||\n tag === 'TEXTAREA' ||\n tag === 'SELECT' ||\n element.isContentEditable === true\n );\n}\n\n/** Creates the vanilla runtime controller that mounts review overlays on a target page. */\nexport function createWebReviewKit(\n options: WebReviewKitOptions\n): WebReviewKitController {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return createNoopController();\n }\n\n const app = new WebReviewKitApp(options);\n app.mount();\n\n return {\n open: () => app.open(),\n close: () => app.close(),\n toggle: () => app.toggle(),\n setMode: (mode) => app.setMode(mode),\n startElementReview: (element, comment) =>\n app.startElementReview(element, comment),\n getMode: () => app.getMode(),\n highlightItem: (itemId) => app.highlightItem(itemId),\n setHiddenItemIds: (itemIds) => app.setHiddenItemIds(itemIds),\n reload: () => app.reload(),\n getItems: () => app.getItems(),\n destroy: () => app.destroy(),\n };\n}\n\nclass WebReviewKitApp {\n private readonly adapter: WebReviewKitAdapter;\n private readonly hotkey: string;\n private readonly view: WebReviewKitView;\n private root?: HTMLDivElement;\n private shadow?: ShadowRoot;\n private isOpen = false;\n private mode: ReviewMode = 'idle';\n private items: ReviewItem[] = [];\n private domDraft?: DomDraft;\n private areaDraft?: AreaDraft;\n private draftError = '';\n private isCreatingItem = false;\n private isCapturingViewport = false;\n private isSelectingArea = false;\n private highlightedItemId?: string;\n private hiddenItemIds?: Set<string>;\n private renderFrame?: number;\n\n constructor(private readonly options: WebReviewKitOptions) {\n this.adapter = options.adapter ?? localAdapter();\n this.hotkey = options.hotkeys?.qa ?? 'Shift+Q';\n this.view = new WebReviewKitView({\n options,\n getState: () => ({\n isOpen: this.isOpen,\n mode: this.mode,\n items: this.items,\n domDraft: this.domDraft,\n areaDraft: this.areaDraft,\n draftError: this.draftError,\n isCreatingItem: this.isCreatingItem,\n isCapturingViewport: this.isCapturingViewport,\n isSelectingArea: this.isSelectingArea,\n highlightedItemId: this.highlightedItemId,\n }),\n getEnvironment: () => this.getEnvironment(),\n actions: {\n close: () => this.close(),\n render: () => this.render(),\n reload: () => this.reload(),\n restoreItem: (item) => this.restoreItem(item),\n removeItem: (itemId) => this.adapter.remove(itemId),\n setModeState: (mode) => this.setModeState(mode),\n clearDrafts: () => this.clearDrafts(),\n setDomDraft: (draft) => {\n this.domDraft = draft;\n this.draftError = '';\n },\n setAreaDraft: (draft) => {\n this.areaDraft = draft;\n this.draftError = '';\n },\n setSelectingArea: (isSelectingArea) => {\n this.isSelectingArea = isSelectingArea;\n },\n createItem: (input) => this.createItem(input),\n captureDomDraft: (input) => this.captureDomDraft(input),\n captureAreaDraft: (input) => this.captureAreaDraft(input),\n bindElementDraftToPoint: (point, fields) =>\n this.bindElementDraftToPoint(point, fields),\n createAreaDraft: (selection) => this.createAreaDraft(selection),\n },\n });\n }\n\n mount() {\n if (this.root) return;\n\n const existing = document.getElementById(ROOT_ID);\n if (existing) existing.remove();\n\n this.root = document.createElement('div');\n this.root.id = ROOT_ID;\n this.root.style.display = 'contents';\n\n this.shadow = this.root.attachShadow({ mode: 'open' });\n document.body.appendChild(this.root);\n document.addEventListener('keydown', this.handleKeyDown, true);\n window.addEventListener('scroll', this.handleViewportChange, true);\n window.addEventListener('resize', this.handleViewportChange);\n\n this.render();\n }\n\n destroy() {\n this.view.clearDraftPreview();\n this.clearDrafts();\n document.removeEventListener('keydown', this.handleKeyDown, true);\n window.removeEventListener('scroll', this.handleViewportChange, true);\n window.removeEventListener('resize', this.handleViewportChange);\n if (this.renderFrame) {\n window.cancelAnimationFrame(this.renderFrame);\n this.renderFrame = undefined;\n }\n this.root?.remove();\n this.root = undefined;\n this.shadow = undefined;\n }\n\n open() {\n if (this.isOpen) return;\n\n this.isOpen = true;\n void this.reload();\n }\n\n close() {\n this.isOpen = false;\n this.setModeState('idle');\n this.clearDrafts();\n this.isSelectingArea = false;\n this.render();\n }\n\n toggle() {\n if (this.isOpen) {\n this.close();\n return;\n }\n\n this.open();\n }\n\n setMode(mode: ReviewMode) {\n if (!this.isOpen) {\n this.isOpen = true;\n }\n\n this.setModeState(this.mode === mode ? 'idle' : mode);\n this.clearDrafts();\n this.render();\n }\n\n async startElementReview(element: Element, comment?: string) {\n if (!this.isOpen) {\n this.isOpen = true;\n }\n\n this.setModeState('element');\n this.clearDrafts();\n this.isSelectingArea = false;\n await this.bindElementDraftToElement(element, { comment });\n }\n\n getMode() {\n return this.mode;\n }\n\n getItems() {\n return this.items;\n }\n\n highlightItem(itemId?: string) {\n if (!itemId) {\n this.clearHighlightedItem();\n return;\n }\n\n if (!this.isOpen) {\n this.isOpen = true;\n }\n\n this.highlightedItemId = itemId;\n this.render();\n }\n\n setHiddenItemIds(itemIds?: string[]) {\n this.hiddenItemIds = itemIds ? new Set(itemIds) : undefined;\n this.updateHiddenItemsStyle();\n }\n\n private clearDrafts() {\n this.revokeDraftAttachmentPreviews(this.domDraft);\n this.revokeDraftAttachmentPreviews(this.areaDraft);\n this.domDraft = undefined;\n this.areaDraft = undefined;\n this.draftError = '';\n }\n\n private revokeDraftAttachmentPreviews(draft?: DomDraft | AreaDraft) {\n draft?.attachments?.forEach((attachment) => {\n if (attachment.previewUrl) {\n URL.revokeObjectURL(attachment.previewUrl);\n }\n });\n }\n\n private clearHighlightedItem() {\n if (!this.highlightedItemId) return;\n\n this.highlightedItemId = undefined;\n this.render();\n }\n\n private createHiddenItemsStyleElement() {\n const style = document.createElement('style');\n style.dataset.dfwrHiddenItems = 'true';\n style.textContent = this.getHiddenItemsCss();\n return style;\n }\n\n private updateHiddenItemsStyle() {\n if (!this.shadow) return;\n\n let style = this.shadow.querySelector<HTMLStyleElement>(\n 'style[data-dfwr-hidden-items=\"true\"]'\n );\n if (!style) {\n style = this.createHiddenItemsStyleElement();\n this.shadow.prepend(style);\n return;\n }\n\n style.textContent = this.getHiddenItemsCss();\n }\n\n private getHiddenItemsCss() {\n if (!this.hiddenItemIds?.size) return '';\n\n return Array.from(this.hiddenItemIds)\n .map(\n (itemId) =>\n `[data-review-item-id=\"${cssEscape(itemId)}\"] { display: none !important; }`\n )\n .join('\\n');\n }\n\n private setModeState(mode: ReviewMode) {\n if (this.mode === mode) return;\n\n this.mode = mode;\n this.options.onModeChange?.(mode);\n }\n\n private cancelMode() {\n if (\n this.mode === 'idle' &&\n !this.domDraft &&\n !this.areaDraft &&\n !this.isSelectingArea\n ) {\n return false;\n }\n\n this.setModeState('idle');\n this.clearDrafts();\n this.isSelectingArea = false;\n this.render();\n return true;\n }\n\n private readonly handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && this.cancelMode()) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n if (isEditableEventTarget(event) || !isHotkey(event, this.hotkey)) return;\n\n event.preventDefault();\n event.stopPropagation();\n this.toggle();\n };\n\n private readonly handleViewportChange = () => {\n if (!this.isOpen || this.renderFrame || this.isDraftComposerFocused()) return;\n\n this.renderFrame = window.requestAnimationFrame(() => {\n this.renderFrame = undefined;\n if (this.isDraftComposerFocused()) return;\n this.render();\n });\n };\n\n private isDraftComposerFocused() {\n if (!this.domDraft && !this.areaDraft) return false;\n const composerHost = this.getEnvironment()?.composerHost;\n const activeElement = composerHost?.ownerDocument.activeElement;\n return Boolean(\n composerHost &&\n activeElement &&\n composerHost.contains(activeElement)\n );\n }\n\n private getEnvironment(): ReviewEnvironment | undefined {\n const target =\n typeof this.options.target === 'function'\n ? this.options.target()\n : this.options.target;\n\n if (!target) {\n return {\n window,\n document,\n viewportRect: {\n left: 0,\n top: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n },\n overlayRect: {\n left: 0,\n top: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n },\n };\n }\n\n try {\n const rect = target.getViewportRect?.() ?? {\n left: 0,\n top: 0,\n width: target.window.innerWidth,\n height: target.window.innerHeight,\n };\n const overlayRect = target.getOverlayRect?.() ?? rect;\n const composerHost = target.getComposerHost?.();\n const scaleX =\n target.window.innerWidth > 0\n ? rect.width / target.window.innerWidth\n : 1;\n const scaleY =\n target.window.innerHeight > 0\n ? rect.height / target.window.innerHeight\n : 1;\n\n return {\n window: target.window,\n document: target.document,\n viewportRect: {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n },\n scaleX,\n scaleY,\n overlayRect: {\n left: overlayRect.left,\n top: overlayRect.top,\n width: overlayRect.width,\n height: overlayRect.height,\n },\n composerHost,\n captureViewport: target.captureViewport,\n };\n } catch {\n return undefined;\n }\n }\n\n async reload() {\n const environment = this.getEnvironment();\n if (!environment) return this.items;\n\n this.items = await this.adapter.list({\n projectId: this.options.projectId,\n routeKey: getRouteKey(environment),\n });\n this.options.onItemsChange?.(this.items);\n if (this.isOpen) {\n this.render();\n }\n return this.items;\n }\n\n private render() {\n if (!this.shadow) return;\n\n this.view.render(this.shadow, this.createHiddenItemsStyleElement());\n }\n\n private async bindElementDraftToPoint(\n point: ReviewPoint,\n fields: DraftItemFields = {}\n ) {\n const environment = this.getEnvironment();\n if (!environment) return;\n\n const viewport = getViewportSize(environment);\n const nextPoint = clampPoint(point, environment);\n\n const draft = await this.withOverlayHidden(() => {\n const pointSelection = getPointSelection(nextPoint);\n const targetElement = environment.document.elementFromPoint(\n nextPoint.x,\n nextPoint.y\n );\n const previewElement =\n targetElement && 'style' in targetElement\n ? (targetElement as ReviewDraftPreviewElement)\n : undefined;\n const targetRect = targetElement?.getBoundingClientRect();\n const clickedSelection =\n targetRect && targetRect.width > 0 && targetRect.height > 0\n ? {\n left: targetRect.left,\n top: targetRect.top,\n width: targetRect.width,\n height: targetRect.height,\n }\n : undefined;\n const anchor = getDomAnchorFromPoint(\n nextPoint,\n this.options.anchors?.attribute,\n environment\n );\n const elementSelection = anchor\n ? (clickedSelection ??\n getElementViewportSelection(anchor, environment, pointSelection))\n : undefined;\n const selection = elementSelection ?? pointSelection;\n const markerPoint = elementSelection\n ? { x: selection.left, y: selection.top }\n : getSelectionCenter(selection);\n const reviewSelection = elementSelection\n ? {\n viewport: toPublicSelection(elementSelection),\n relative: getRelativeSelection(\n elementSelection,\n anchor as DomAnchor,\n environment\n ),\n }\n : undefined;\n const marker: ReviewMarker = {\n viewport: roundPoint(markerPoint),\n relative: anchor\n ? getRelativePoint(markerPoint, anchor, environment)\n : undefined,\n };\n\n return {\n viewport,\n anchor,\n marker,\n selection: reviewSelection,\n ...fields,\n previewElement,\n };\n });\n\n this.domDraft = draft;\n this.render();\n }\n\n private async bindElementDraftToElement(\n element: Element,\n fields: DraftItemFields = {}\n ) {\n const environment = this.getEnvironment();\n if (!environment || element.ownerDocument !== environment.document) return;\n\n const viewport = getViewportSize(environment);\n\n const draft = await this.withOverlayHidden(() => {\n const rect = element.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) return undefined;\n\n const selection: ViewportSelection = {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n };\n const anchor = getDomAnchorFromElement(\n element,\n this.options.anchors?.attribute,\n environment\n );\n const markerPoint = { x: selection.left, y: selection.top };\n const marker: ReviewMarker = {\n viewport: roundPoint(markerPoint),\n relative: anchor\n ? getRelativePoint(markerPoint, anchor, environment)\n : undefined,\n };\n const reviewSelection: ReviewSelection = {\n viewport: toPublicSelection(selection),\n relative: anchor\n ? getRelativeSelection(selection, anchor, environment)\n : undefined,\n };\n const previewElement =\n 'style' in element ? (element as ReviewDraftPreviewElement) : undefined;\n\n return {\n viewport,\n anchor,\n marker,\n selection: reviewSelection,\n ...fields,\n previewElement,\n };\n });\n\n if (!draft) return;\n\n this.domDraft = draft;\n this.render();\n }\n\n private async createAreaDraft(selection: ViewportSelection) {\n const environment = this.getEnvironment();\n if (!environment) {\n this.isSelectingArea = false;\n this.render();\n return;\n }\n\n try {\n const viewport = getViewportSize(environment);\n\n this.areaDraft = await this.withOverlayHidden(() => {\n const anchorPoint = clampPoint(\n getSelectionCenter(selection),\n environment\n );\n const anchor = getDomAnchorFromPoint(\n anchorPoint,\n this.options.anchors?.attribute,\n environment\n );\n const marker = createSelectionStartMarker(\n selection,\n anchor,\n environment\n );\n const reviewSelection: ReviewSelection = {\n viewport: toPublicSelection(selection),\n relative: anchor\n ? getRelativeSelection(selection, anchor, environment)\n : undefined,\n };\n\n return {\n viewport,\n anchor,\n marker,\n selection: reviewSelection,\n };\n });\n this.setModeState('area');\n } finally {\n this.isSelectingArea = false;\n this.render();\n }\n }\n\n private async withOverlayHidden<T>(callback: () => Promise<T> | T) {\n if (!this.root) return callback();\n\n const previousDisplay = this.root.style.display;\n this.root.style.display = 'none';\n\n try {\n // Hide our own overlay while sampling elementFromPoint so we anchor to the page.\n return await callback();\n } finally {\n this.root.style.display = previousDisplay;\n }\n }\n\n private async captureDomDraft(input: CaptureDraftInput) {\n if (this.isCapturingViewport) return;\n\n const environment = this.getEnvironment();\n const draft = this.domDraft;\n if (!draft) return;\n if (!environment?.captureViewport) {\n this.draftError = 'Viewport capture helper is not available.';\n this.render();\n return;\n }\n\n const captureInput = this.createViewportCaptureInput(\n environment,\n input,\n input.selection?.viewport\n );\n this.draftError = '';\n this.isCapturingViewport = true;\n this.render();\n\n try {\n const result = await environment.captureViewport(captureInput);\n const attachment = this.createCaptureDraftAttachment(result, captureInput);\n const currentDraft = this.domDraft ?? draft;\n this.domDraft = {\n ...currentDraft,\n attachments: [...(currentDraft.attachments ?? []), attachment],\n };\n } catch (error) {\n this.draftError = this.getErrorMessage(\n error,\n 'Failed to capture viewport.'\n );\n } finally {\n this.isCapturingViewport = false;\n this.render();\n }\n }\n\n private async captureAreaDraft(input: CaptureDraftInput) {\n if (this.isCapturingViewport) return;\n\n const environment = this.getEnvironment();\n const draft = this.areaDraft;\n if (!draft) return;\n if (!environment?.captureViewport) {\n this.draftError = 'Viewport capture helper is not available.';\n this.render();\n return;\n }\n\n const captureInput = this.createViewportCaptureInput(\n environment,\n input,\n input.selection?.viewport\n );\n this.draftError = '';\n this.isCapturingViewport = true;\n this.render();\n\n try {\n const result = await environment.captureViewport(captureInput);\n const attachment = this.createCaptureDraftAttachment(result, captureInput);\n const currentDraft = this.areaDraft ?? draft;\n this.areaDraft = {\n ...currentDraft,\n attachments: [...(currentDraft.attachments ?? []), attachment],\n };\n } catch (error) {\n this.draftError = this.getErrorMessage(\n error,\n 'Failed to capture viewport.'\n );\n } finally {\n this.isCapturingViewport = false;\n this.render();\n }\n }\n\n private createViewportCaptureInput(\n environment: ReviewEnvironment,\n draft: CaptureDraftInput,\n captureRegion?: RelativeSelection\n ): ReviewViewportCaptureInput {\n const timestamp = new Date().toISOString();\n const viewport = draft.viewport ?? getViewportSize(environment);\n const routeKey = getRouteKey(environment);\n\n return {\n routeKey,\n pageUrl: getPageUrl(environment),\n originalUrl: getOriginalUrl(environment),\n viewport,\n captureRegion,\n devicePixelRatio: environment.window.devicePixelRatio || 1,\n scroll: {\n x: environment.window.scrollX,\n y: environment.window.scrollY,\n },\n marker: draft.marker,\n selection: draft.selection,\n timestamp,\n };\n }\n\n private createCaptureDraftAttachment(\n result: ReviewViewportCaptureResult,\n input: ReviewViewportCaptureInput\n ): ReviewDraftAttachment {\n const mime = result.mime || result.file.type || 'image/png';\n const name = result.name || `review-capture-${Date.now()}.png`;\n return {\n id: createId(),\n file: result.file,\n name,\n mime,\n size: result.file.size,\n kind: 'capture',\n previewUrl: mime.startsWith('image/')\n ? URL.createObjectURL(result.file)\n : undefined,\n metadata: {\n ...result.metadata,\n source: 'viewport-capture',\n target: 'iframe',\n routeKey: input.routeKey,\n pageUrl: input.pageUrl,\n originalUrl: input.originalUrl,\n viewport: input.viewport,\n scroll: input.scroll,\n marker: input.marker,\n selection: input.selection,\n timestamp: input.timestamp,\n devicePixelRatio: input.devicePixelRatio,\n width: result.width,\n height: result.height,\n },\n };\n }\n\n private async createItem(input: CreateReviewItemInput) {\n const environment = this.getEnvironment();\n if (!environment || this.isCreatingItem) return;\n\n const now = new Date().toISOString();\n const routeKey = getRouteKey(environment);\n const viewport = input.viewport ?? getViewportSize(environment);\n const createdBy = this.options.userId?.trim();\n const title = input.title?.trim();\n const assigneeId = input.assigneeId?.trim() || undefined;\n const assigneeOption = this.options.assigneeOptions?.find(\n (option) => option.value === assigneeId\n );\n const item: ReviewItem = {\n id: createId(),\n projectId: this.options.projectId,\n routeKey,\n pageUrl: getPageUrl(environment),\n originalUrl: getOriginalUrl(environment),\n normalizedPath: routeKey,\n scope:\n input.scope ??\n getReviewViewportScope(viewport, this.options.viewports?.presets),\n kind: input.kind,\n title: title || undefined,\n comment: input.comment,\n assigneeId,\n assigneeName: input.assigneeName ?? assigneeOption?.label,\n createdBy: createdBy || undefined,\n status: 'todo',\n viewport,\n devicePixelRatio: environment.window.devicePixelRatio || 1,\n scroll: {\n x: environment.window.scrollX,\n y: environment.window.scrollY,\n },\n anchor: input.anchor,\n marker: input.marker,\n selection: input.selection,\n createdAt: now,\n updatedAt: now,\n };\n\n this.draftError = '';\n this.isCreatingItem = true;\n this.render();\n\n try {\n const attachments = await this.uploadDraftAttachments(\n input.attachments,\n item\n );\n const itemWithAttachments =\n attachments.length > 0 ? { ...item, attachments } : item;\n const createdItem = await this.adapter.create(itemWithAttachments);\n this.setModeState('idle');\n this.clearDrafts();\n this.highlightItem(createdItem.id);\n await this.reload();\n await this.options.onCreateItem?.(createdItem);\n } catch (error) {\n this.draftError = this.getCreateItemErrorMessage(\n error,\n Boolean(input.attachments?.length)\n );\n } finally {\n this.isCreatingItem = false;\n this.render();\n }\n }\n\n private async uploadDraftAttachments(\n attachments: ReviewDraftAttachment[] | undefined,\n item: ReviewItem\n ): Promise<ReviewAttachment[]> {\n if (!attachments?.length) return [];\n const uploadAttachment = this.adapter.uploadAttachment;\n if (!uploadAttachment) {\n throw new Error('Attachment upload adapter is not configured.');\n }\n\n return Promise.all(\n attachments.map((attachment) =>\n uploadAttachment({\n file: attachment.file,\n name: attachment.name,\n mime: attachment.mime,\n kind: attachment.kind,\n item,\n metadata: attachment.metadata,\n })\n )\n );\n }\n\n private getCreateItemErrorMessage(\n error: unknown,\n wasUploadingAttachments: boolean\n ) {\n const message = this.getErrorMessage(error, 'Failed to save QA.');\n const reason =\n error && typeof error === 'object' && 'reason' in error &&\n typeof error.reason === 'string'\n ? ` (${error.reason})`\n : '';\n return wasUploadingAttachments && reason\n ? `Attachment upload failed${reason}: ${message}`\n : message;\n }\n\n private getErrorMessage(error: unknown, fallback: string) {\n if (error instanceof Error) return error.message;\n if (\n error &&\n typeof error === 'object' &&\n 'message' in error &&\n typeof error.message === 'string'\n ) {\n return error.message;\n }\n return fallback;\n }\n\n private async restoreItem(item: ReviewItem) {\n this.setModeState('idle');\n this.clearDrafts();\n\n if (this.options.onRestoreItem) {\n await this.options.onRestoreItem(item);\n return;\n }\n\n const environment = this.getEnvironment();\n if (!environment) return;\n\n const scroll = item.scroll;\n if (scroll) {\n runWithAutoScrollBehavior(environment.document, () => {\n setDocumentScrollInstantly(environment, scroll);\n });\n await waitForNextFrame(environment);\n }\n\n this.highlightItem(item.id);\n this.render();\n }\n}\n\nfunction createNoopController(): WebReviewKitController {\n return {\n open() {},\n close() {},\n toggle() {},\n setMode() {},\n async startElementReview() {},\n getMode() {\n return 'idle';\n },\n highlightItem() {},\n setHiddenItemIds() {},\n async reload() {\n return [];\n },\n getItems() {\n return [];\n },\n destroy() {},\n };\n}\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["nextDraft"]}
|