@designfever/web-review-kit 0.7.3 → 0.8.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/route.ts","../src/status.ts","../src/adapters/local.ts","../src/adapters/supabase.ts","../src/figma/image.types.ts","../src/vite/figma-asset.ts","../src/figma/parse.ts","../src/figma/token.ts","../src/figma/render.ts","../src/figma/image.store.ts","../src/figma/remote.image.store.ts","../src/figma/image.snapshot.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/scope.ts","../src/core/review/item.ts","../src/core/scroll.ts","../src/core/draft.metrics.ts","../src/core/typography.tokens.ts","../src/core/overlay.style.ts","../src/core/review/format.ts","../src/core/web.review.kit.view.ts","../src/core/web.review.kit.app.ts"],"sourcesContent":["export { localAdapter } from './adapters/local';\nexport { supabaseAdapter } from './adapters/supabase';\nexport {\n REVIEW_WORKFLOW_STATUS_OPTIONS,\n normalizeReviewItemStatus,\n} from './status';\nexport { DEFAULT_REVIEW_FIGMA_IMAGE_FORMAT } from './figma/image.types';\nexport {\n DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT,\n createEndpointReviewFigmaImageStore,\n createReviewFigmaImageStoreClient,\n getReviewFigmaImageMimeType,\n getReviewFigmaImageTargetKey,\n} from './figma/image.store';\nexport {\n DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE,\n createRemoteReviewFigmaImageStore,\n} from './figma/remote.image.store';\nexport {\n collectReviewFigmaReleaseSnapshot,\n createReviewFigmaImagesSnapshot,\n createReviewFigmaReleaseSnapshot,\n} from './figma/image.snapshot';\nexport {\n DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY,\n REVIEW_FIGMA_TOKEN_MISSING_CODE,\n ReviewFigmaTokenError,\n isReviewFigmaTokenError,\n readReviewFigmaToken,\n requireReviewFigmaToken,\n} from './figma/token';\nexport {\n FIGMA_NODE_REF_SEPARATOR,\n createReviewFigmaFrameUrl,\n createReviewFigmaNodeValue,\n parseReviewFigmaNodeRef,\n requireReviewFigmaNodeRef,\n} from './figma/parse';\nexport { createWebReviewKit } from './core/web.review.kit.app';\nexport {\n DEFAULT_REVIEW_VIEWPORTS,\n findReviewViewportPreset,\n getNumberedReviewItems,\n getReviewItemScope,\n getReviewItemScopeLabel,\n getReviewViewportScope,\n} from './core/review/scope';\nexport type {\n DomAnchor,\n DomAnchorCandidate,\n DomAnchorStrategy,\n DomSourceHint,\n LocalAdapterOptions,\n NumberedReviewItem,\n RelativeSelection,\n ReviewAssigneeOption,\n ReviewItem,\n ReviewItemKind,\n ReviewItemQuery,\n ReviewItemScope,\n ReviewItemStatus,\n ReviewSource,\n ReviewSubmitStatus,\n ReviewMarker,\n ReviewMode,\n ReviewPoint,\n ReviewRulerConfig,\n ReviewSelection,\n SupabaseReviewAdapterOptions,\n SupabaseReviewClient,\n ReviewViewportPreset,\n ReviewViewportScope,\n ReviewWorkflowStatus,\n ViewportSize,\n WebReviewKitAdapter,\n WebReviewKitController,\n WebReviewKitOptions,\n WebReviewKitTarget,\n} from './types';\nexport type {\n AddReviewFigmaImageInput,\n ReorderReviewFigmaImagesInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n ReviewFigmaImageViewport,\n ReviewFigmaNodeTarget,\n ReviewFigmaRouteTarget,\n UpdateReviewFigmaImageInput,\n} from './figma/image.types';\nexport type {\n ReviewFigmaTokenEnv,\n ReviewFigmaTokenOptions,\n} from './figma/token';\nexport type { ReviewFigmaNodeRef } from './figma/parse';\nexport type {\n RemoteReviewFigmaImageStoreOptions,\n ReviewFigmaRemoteAssetUploadResponse,\n ReviewFigmaRemoteDbClient,\n ReviewFigmaRemoteImageRow,\n} from './figma/remote.image.store';\nexport type {\n EndpointReviewFigmaImageStoreOptions,\n ReviewFigmaImageClientRenderOptions,\n ReviewFigmaImageStoreHeadersProvider,\n ReviewFigmaImageStoreClientOptions,\n} from './figma/image.store';\nexport type {\n CollectReviewFigmaReleaseSnapshotOptions,\n CreateReviewFigmaImagesSnapshotOptions,\n CreateReviewFigmaReleaseSnapshotOptions,\n ReviewFigmaImagesSnapshot,\n ReviewFigmaReleaseSnapshot,\n} from './figma/image.snapshot';\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 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 { 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 =\n raw.kind === 'text' ? 'note' :\n raw.kind === 'capture' ? 'area' :\n raw.kind;\n\n if (kind !== 'note' && 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","import { normalizeReviewItemStatus } from '../status';\nimport type {\n ReviewItem,\n ReviewItemStatus,\n ReviewSource,\n SupabaseReviewAdapterOptions,\n WebReviewKitAdapter,\n} from '../types';\n\nconst DEFAULT_SUPABASE_REVIEW_TABLE = 'review_items';\nconst DEFAULT_SUPABASE_REVIEW_SOURCE = 'supabase';\nconst DEFAULT_SUPABASE_CREATE_REVIEW_ITEM_RPC = 'create_review_item';\n\ntype SupabaseReviewRow = {\n id: string;\n project_id: string;\n route_key: string;\n source: string;\n review_number?: number | null;\n status: string;\n item: unknown;\n created_at: string;\n updated_at: string;\n};\n\ntype SupabaseResponse<T> = {\n data: T | null;\n error: { message?: string; code?: string } | null;\n};\n\nexport function supabaseAdapter(\n options: SupabaseReviewAdapterOptions\n): WebReviewKitAdapter {\n const tableName = options.table ?? DEFAULT_SUPABASE_REVIEW_TABLE;\n const source = options.source ?? DEFAULT_SUPABASE_REVIEW_SOURCE;\n\n const fromTable = () => options.client.from(tableName);\n\n return {\n async get(id) {\n const row = await unwrapResponse<SupabaseReviewRow | null>(\n fromTable().select('*').eq('id', id).maybeSingle(),\n 'supabase get review item'\n );\n\n return row ? rowToReviewItem(row, options) : null;\n },\n\n async list(query) {\n let request = fromTable()\n .select('*')\n .eq('project_id', query.projectId)\n .eq('source', query.source ?? source);\n const routeKey = query.routeKey ?? query.normalizedPath;\n\n if (routeKey) {\n request = request.eq('route_key', routeKey);\n }\n if (query.status) {\n request = request.eq(\n 'status',\n normalizeReviewItemStatus(query.status)\n );\n }\n\n const rows = await unwrapResponse<SupabaseReviewRow[]>(\n request.order('created_at', { ascending: false }),\n 'supabase list review items'\n );\n\n return (rows ?? []).flatMap((row) => {\n const item = rowToReviewItem(row, options);\n return item ? [item] : [];\n });\n },\n\n async create(item) {\n const nextItem = normalizeItemForSupabaseCreate(item, source, options);\n\n if (options.unsafeClientReviewNumberFallback) {\n throw new Error(\n 'supabase create review item: unsafeClientReviewNumberFallback is no longer supported. Use create_review_item RPC with database-backed review_number sequence.'\n );\n }\n\n return createItemWithRpc(nextItem, source, options);\n },\n\n async update(id, patch) {\n const current = await this.get(id);\n if (!current) throw new Error(`Review item not found: ${id}`);\n\n const nextStatus = patch.status\n ? normalizeReviewItemStatus(patch.status)\n : current.status;\n const nextItem: ReviewItem = {\n ...current,\n ...patch,\n id,\n status: nextStatus,\n createdAt: current.createdAt,\n updatedAt: new Date().toISOString(),\n };\n const patchRow = itemToRowPatch(nextItem, source, options);\n const updated = await unwrapResponse<SupabaseReviewRow>(\n fromTable().update(patchRow).eq('id', id).select('*').single(),\n 'supabase update review item'\n );\n\n return rowToReviewItem(updated, options) ?? nextItem;\n },\n\n async remove(id) {\n await unwrapResponse<null>(\n fromTable().delete().eq('id', id),\n 'supabase delete review item'\n );\n },\n };\n}\n\nfunction normalizeItemForSupabaseCreate(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n): ReviewItem {\n const now = new Date().toISOString();\n const id = createSupabaseReviewItemId();\n const normalizedStatus = normalizeReviewItemStatus(item.status);\n const routeKey = item.routeKey || item.normalizedPath || '/';\n const viewport = item.viewport ?? { width: 390, height: 720 };\n const nextItem: ReviewItem = {\n ...item,\n id,\n reviewNumber: undefined,\n projectId: options.projectId,\n routeKey,\n normalizedPath: item.normalizedPath || routeKey,\n viewport,\n status: normalizedStatus,\n externalIssueId: id,\n externalIssueUrl: buildSupabaseReviewUrl(\n { routeKey, normalizedPath: item.normalizedPath || routeKey, viewport },\n source,\n options,\n id\n ),\n submittedAt: item.submittedAt ?? now,\n submitStatus: item.submitStatus ?? 'submitted',\n createdAt: now,\n updatedAt: now,\n };\n\n return {\n ...nextItem,\n externalIssueUrl:\n nextItem.externalIssueUrl ??\n buildSupabaseReviewUrl(nextItem, source, options),\n };\n}\n\nasync function createItemWithRpc(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n) {\n const rpcName =\n options.createRpc ?? DEFAULT_SUPABASE_CREATE_REVIEW_ITEM_RPC;\n\n if (!options.client.rpc) {\n throw new Error(\n `supabase create review item: ${rpcName} rpc is required`\n );\n }\n\n const row = await unwrapResponse<SupabaseReviewRow>(\n options.client.rpc(rpcName, {\n p_id: item.id,\n p_project_id: options.projectId,\n p_route_key: item.routeKey || item.normalizedPath || '/',\n p_source: source,\n p_status: normalizeReviewItemStatus(item.status),\n p_item: item,\n }),\n `supabase create review item rpc ${rpcName}`\n );\n\n return rowToReviewItem(row, options) ?? item;\n}\n\nfunction itemToRow(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n): SupabaseReviewRow {\n const now = new Date().toISOString();\n const updatedAt = item.updatedAt || now;\n\n return {\n id: item.id,\n project_id: options.projectId,\n route_key: item.routeKey || item.normalizedPath || '/',\n source,\n review_number: item.reviewNumber ?? null,\n status: normalizeReviewItemStatus(item.status),\n item: {\n ...item,\n projectId: options.projectId,\n status: normalizeReviewItemStatus(item.status),\n updatedAt,\n },\n created_at: item.createdAt || now,\n updated_at: updatedAt,\n };\n}\n\nfunction itemToRowPatch(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n) {\n const row = itemToRow(item, source, options);\n return {\n route_key: row.route_key,\n review_number: row.review_number,\n status: row.status,\n item: row.item,\n updated_at: row.updated_at,\n };\n}\n\nfunction rowToReviewItem(\n row: SupabaseReviewRow,\n options: SupabaseReviewAdapterOptions\n): ReviewItem | null {\n if (!row.item || typeof row.item !== 'object') return null;\n\n const item = row.item as Partial<ReviewItem>;\n const status = normalizeReviewItemStatus(\n (row.status || item.status || 'todo') as ReviewItemStatus\n );\n const routeKey = row.route_key || item.routeKey || item.normalizedPath || '/';\n const viewport = item.viewport ?? { width: 390, height: 720 };\n const now = new Date().toISOString();\n\n return {\n ...(item as ReviewItem),\n id: row.id,\n reviewNumber: row.review_number ?? item.reviewNumber,\n projectId: row.project_id || item.projectId || options.projectId,\n routeKey,\n pageUrl: item.pageUrl || toAbsoluteReviewUrl(routeKey),\n normalizedPath: item.normalizedPath || routeKey,\n kind: item.kind === 'area' ? 'area' : 'note',\n comment: item.comment || '',\n status,\n viewport,\n externalIssueId: item.externalIssueId ?? row.id,\n externalIssueUrl:\n item.externalIssueUrl ??\n buildSupabaseReviewUrl(\n { routeKey, normalizedPath: routeKey, viewport },\n row.source,\n options,\n row.id\n ),\n submittedAt: item.submittedAt ?? row.created_at,\n submitStatus: item.submitStatus ?? 'submitted',\n createdAt: item.createdAt ?? row.created_at ?? now,\n updatedAt: row.updated_at ?? item.updatedAt ?? now,\n };\n}\n\nasync function unwrapResponse<T>(\n request: Promise<SupabaseResponse<T>> | SupabaseResponse<T>,\n label: string\n) {\n const { data, error } = await request;\n if (error) {\n throw new Error(`${label}: ${error.message ?? error.code ?? 'failed'}`);\n }\n return data as T;\n}\n\nfunction buildSupabaseReviewUrl(\n item: Pick<ReviewItem, 'routeKey' | 'normalizedPath' | 'viewport'>,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions,\n itemId?: string\n) {\n if (typeof window === 'undefined') return undefined;\n\n const url = new URL(\n normalizeReviewUrlPath(options.reviewPathPrefix),\n window.location.origin\n );\n url.searchParams.set('source', source);\n url.searchParams.set('target', item.routeKey || item.normalizedPath || '/');\n url.searchParams.set('w', String(Math.round(item.viewport.width)));\n url.searchParams.set('h', String(Math.round(item.viewport.height)));\n if (itemId) url.searchParams.set('item', itemId);\n return url.toString();\n}\n\nfunction normalizeReviewUrlPath(value = '/review') {\n const raw = value.trim() || '/review';\n const path = raw.startsWith('/') ? raw : `/${raw}`;\n return path.endsWith('/') ? path : `${path}/`;\n}\n\nfunction toAbsoluteReviewUrl(path: string) {\n if (typeof window === 'undefined') return path;\n return new URL(path, window.location.origin).toString();\n}\n\nfunction createSupabaseReviewItemId() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n return `review-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\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","// Pure helpers for Figma image asset format conversion and storage-key handling.\n// Extracted from src/vite.ts to keep the plugin entry focused on request flow.\nimport type { ReviewFigmaImageFormat } from '../figma/image.types';\nimport type { ReviewFigmaRenderFormat } from '../figma/render';\n\nexport function parseReviewFigmaImageFormat(value: unknown) {\n return value === 'webp' || value === 'png' || value === 'jpg'\n ? value\n : undefined;\n}\n\nexport function getStoreRenderFormat(\n renderFormat: ReviewFigmaRenderFormat | undefined,\n imageFormat: ReviewFigmaImageFormat | undefined\n): Extract<ReviewFigmaRenderFormat, 'png' | 'jpg'> {\n if (renderFormat === 'jpg' || renderFormat === 'png') return renderFormat;\n if (imageFormat === 'jpg') return 'jpg';\n return 'png';\n}\n\nexport function getReviewFigmaImageFormatFromMimeType(\n mimeType: string\n): ReviewFigmaImageFormat | null {\n if (mimeType === 'image/webp') return 'webp';\n if (mimeType === 'image/png') return 'png';\n if (mimeType === 'image/jpeg') return 'jpg';\n return null;\n}\n\nexport function normalizeImageMimeType(value: string | null | undefined) {\n const mimeType = value?.split(';')[0]?.trim().toLowerCase();\n if (mimeType === 'image/jpg') return 'image/jpeg';\n if (\n mimeType === 'image/jpeg' ||\n mimeType === 'image/png' ||\n mimeType === 'image/webp'\n ) {\n return mimeType;\n }\n return null;\n}\n\nexport function createReviewFigmaAssetStorageKey(\n id: string,\n imageFormat: ReviewFigmaImageFormat\n) {\n return `${id}.${getReviewFigmaAssetExtension(imageFormat)}`;\n}\n\nexport function createReviewFigmaAssetUrl(\n assetEndpoint: string,\n storageKey: string\n) {\n return `${assetEndpoint}/${encodeURIComponent(storageKey)}`;\n}\n\nexport function getReviewFigmaAssetStorageKeyFromPathname(\n pathname: string,\n assetEndpoint: string\n) {\n try {\n const storageKey = decodeURIComponent(\n pathname.slice(assetEndpoint.length + 1)\n );\n return isSafeReviewFigmaAssetStorageKey(storageKey) ? storageKey : null;\n } catch {\n return null;\n }\n}\n\nexport function isSafeReviewFigmaAssetStorageKey(value: string) {\n return /^figma_[a-z0-9_]+\\.(webp|png|jpg)$/.test(value);\n}\n\nfunction getReviewFigmaAssetExtension(format: ReviewFigmaImageFormat) {\n return format === 'jpg' ? 'jpg' : format;\n}\n\nexport function getReviewFigmaAssetMimeType(storageKey: string) {\n if (storageKey.endsWith('.jpg')) return 'image/jpeg';\n if (storageKey.endsWith('.webp')) return 'image/webp';\n return 'image/png';\n}\n","export type ReviewFigmaNodeRef = {\n fileKey: string;\n nodeId: string;\n sourceUrl?: string;\n};\n\nexport const FIGMA_NODE_REF_SEPARATOR = '->';\n\nexport function parseReviewFigmaNodeRef(\n value: string | ReviewFigmaNodeRef\n): ReviewFigmaNodeRef | null {\n if (typeof value !== 'string') return normalizeReviewFigmaNodeRef(value);\n\n const input = value.trim();\n if (!input) return null;\n\n return parseReviewFigmaNodeRefValue(input) ?? parseReviewFigmaUrl(input);\n}\n\nexport function requireReviewFigmaNodeRef(\n value: string | ReviewFigmaNodeRef\n): ReviewFigmaNodeRef {\n const ref = parseReviewFigmaNodeRef(value);\n if (!ref) {\n throw new Error('A Figma node link or fileKey->nodeId value is required.');\n }\n return ref;\n}\n\nexport function createReviewFigmaNodeValue(ref: ReviewFigmaNodeRef) {\n return `${ref.fileKey}${FIGMA_NODE_REF_SEPARATOR}${ref.nodeId}`;\n}\n\nexport function createReviewFigmaFrameUrl(\n value: string | ReviewFigmaNodeRef\n) {\n const ref = parseReviewFigmaNodeRef(value);\n if (!ref) return null;\n\n return `https://www.figma.com/design/${encodeURIComponent(\n ref.fileKey\n )}?node-id=${encodeURIComponent(ref.nodeId.replace(/:/g, '-'))}`;\n}\n\nfunction parseReviewFigmaNodeRefValue(value: string) {\n const [fileKey, nodeId, extra] = value\n .split(FIGMA_NODE_REF_SEPARATOR)\n .map((part) => part.trim());\n\n if (!fileKey || !nodeId || extra !== undefined) return null;\n\n return normalizeReviewFigmaNodeRef({ fileKey, nodeId });\n}\n\nfunction parseReviewFigmaUrl(value: string) {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n const fileKey = getFigmaFileKey(url);\n const nodeId = normalizeFigmaNodeId(url.searchParams.get('node-id'));\n if (!fileKey || !nodeId) return null;\n\n return { fileKey, nodeId, sourceUrl: value };\n}\n\nfunction getFigmaFileKey(url: URL) {\n if (!/(^|\\.)figma\\.com$/i.test(url.hostname)) return null;\n\n const parts = url.pathname.split('/').filter(Boolean);\n const fileKeyIndex = parts.findIndex((part) =>\n ['design', 'file', 'proto', 'board'].includes(part)\n );\n const fileKey = fileKeyIndex >= 0 ? parts[fileKeyIndex + 1] : null;\n\n return normalizeFigmaFileKey(fileKey);\n}\n\nfunction normalizeReviewFigmaNodeRef(\n value: ReviewFigmaNodeRef | null | undefined\n) {\n const fileKey = normalizeFigmaFileKey(value?.fileKey);\n const nodeId = normalizeFigmaNodeId(value?.nodeId);\n if (!fileKey || !nodeId) return null;\n const sourceUrl = normalizeOptionalString(value?.sourceUrl);\n\n return sourceUrl ? { fileKey, nodeId, sourceUrl } : { fileKey, nodeId };\n}\n\nfunction normalizeFigmaFileKey(value: string | null | undefined) {\n return normalizeOptionalString(value)?.replace(/[?#].*$/, '') ?? null;\n}\n\nfunction normalizeFigmaNodeId(value: string | null | undefined) {\n const nodeId = normalizeOptionalString(value);\n if (!nodeId) return null;\n if (nodeId.includes(':')) return nodeId;\n return nodeId.replace(/-/g, ':');\n}\n\nfunction normalizeOptionalString(value: string | null | undefined) {\n if (typeof value !== 'string') return null;\n return value.trim() || null;\n}\n","export const DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY = 'FIGMA_TOKEN';\nexport const REVIEW_FIGMA_TOKEN_MISSING_CODE = 'DFWR_FIGMA_TOKEN_MISSING';\n\nexport type ReviewFigmaTokenEnv = Record<\n string,\n string | null | undefined\n>;\n\nexport type ReviewFigmaTokenOptions = {\n token?: string | null;\n env?: ReviewFigmaTokenEnv;\n envKey?: string;\n enabled?: boolean;\n};\n\nexport class ReviewFigmaTokenError extends Error {\n readonly code = REVIEW_FIGMA_TOKEN_MISSING_CODE;\n readonly envKey: string;\n\n constructor(envKey = DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY) {\n super(\n `Figma image rendering requires server env ${envKey}. Set ${envKey} in the dev/server environment; do not expose it as VITE_${envKey}.`\n );\n this.name = 'ReviewFigmaTokenError';\n this.envKey = envKey;\n }\n}\n\nexport function readReviewFigmaToken(\n options: ReviewFigmaTokenOptions = {}\n): string | null {\n if (options.enabled === false) return null;\n\n const envKey = options.envKey ?? DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY;\n return normalizeReviewFigmaToken(options.token ?? options.env?.[envKey]);\n}\n\nexport function requireReviewFigmaToken(\n options: ReviewFigmaTokenOptions = {}\n): string {\n const envKey = options.envKey ?? DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY;\n const token = readReviewFigmaToken(options);\n\n if (!token) throw new ReviewFigmaTokenError(envKey);\n return token;\n}\n\nexport function isReviewFigmaTokenError(\n error: unknown\n): error is ReviewFigmaTokenError {\n if (!error || typeof error !== 'object') return false;\n\n return (\n error instanceof ReviewFigmaTokenError ||\n ('code' in error && error.code === REVIEW_FIGMA_TOKEN_MISSING_CODE)\n );\n}\n\nfunction normalizeReviewFigmaToken(value: string | null | undefined) {\n if (typeof value !== 'string') return null;\n return value.trim() || null;\n}\n","import {\n requireReviewFigmaNodeRef,\n type ReviewFigmaNodeRef,\n} from './parse';\nimport { requireReviewFigmaToken } from './token';\n\nexport type ReviewFigmaRenderFormat = 'png' | 'jpg' | 'svg' | 'pdf';\n\nexport type ReviewFigmaImageRenderOptions = {\n figmaUrl: string | ReviewFigmaNodeRef;\n token?: string | null;\n format?: ReviewFigmaRenderFormat;\n scale?: number;\n useAbsoluteBounds?: boolean;\n apiBaseUrl?: string;\n fetch?: typeof fetch;\n signal?: AbortSignal;\n};\n\nexport type ReviewFigmaRenderedImage = {\n fileKey: string;\n nodeId: string;\n figmaUrl?: string;\n imageUrl: string;\n renderFormat: ReviewFigmaRenderFormat;\n};\n\ntype FigmaImageResponse = {\n err?: string | null;\n images?: Record<string, string | null | undefined>;\n};\n\nconst DEFAULT_FIGMA_API_BASE_URL = 'https://api.figma.com';\n\nexport async function renderReviewFigmaImage(\n options: ReviewFigmaImageRenderOptions\n): Promise<ReviewFigmaRenderedImage> {\n const token = requireReviewFigmaToken({ token: options.token });\n const ref = requireReviewFigmaNodeRef(options.figmaUrl);\n const renderFormat = options.format ?? 'png';\n const requestUrl = createReviewFigmaImageApiUrl({\n apiBaseUrl: options.apiBaseUrl,\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n format: renderFormat,\n scale: options.scale,\n useAbsoluteBounds: options.useAbsoluteBounds,\n });\n const fetchImage = options.fetch ?? globalThis.fetch;\n if (!fetchImage) throw new Error('Figma image rendering requires fetch.');\n\n const response = await fetchImage(requestUrl, {\n headers: {\n 'X-Figma-Token': token,\n },\n signal: options.signal,\n });\n const body = (await response.json().catch(() => null)) as\n | FigmaImageResponse\n | null;\n\n if (!response.ok) {\n throw new Error(\n body?.err || `Figma image render failed with ${response.status}`\n );\n }\n\n const imageUrl = body?.images?.[ref.nodeId];\n if (!imageUrl) {\n throw new Error(`Figma image render returned no URL for ${ref.nodeId}.`);\n }\n\n return {\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n figmaUrl: typeof options.figmaUrl === 'string'\n ? options.figmaUrl\n : options.figmaUrl.sourceUrl,\n imageUrl,\n renderFormat,\n };\n}\n\nexport function createReviewFigmaImageApiUrl({\n apiBaseUrl = DEFAULT_FIGMA_API_BASE_URL,\n fileKey,\n nodeId,\n format = 'png',\n scale,\n useAbsoluteBounds,\n}: {\n apiBaseUrl?: string;\n fileKey: string;\n nodeId: string;\n format?: ReviewFigmaRenderFormat;\n scale?: number;\n useAbsoluteBounds?: boolean;\n}) {\n const url = new URL(`/v1/images/${encodeURIComponent(fileKey)}`, apiBaseUrl);\n url.searchParams.set('ids', nodeId);\n url.searchParams.set('format', format);\n\n if (typeof scale === 'number' && Number.isFinite(scale) && scale > 0) {\n url.searchParams.set('scale', String(scale));\n }\n if (useAbsoluteBounds !== undefined) {\n url.searchParams.set('use_absolute_bounds', String(useAbsoluteBounds));\n }\n\n return url.toString();\n}\n","import type {\n AddReviewFigmaImageInput,\n ReorderReviewFigmaImagesInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n} from './image.types';\nimport { getReviewFigmaImageFormatFromMimeType } from '../vite/figma-asset';\nimport { parseReviewFigmaNodeRef } from './parse';\nimport {\n createReviewFigmaImageApiUrl,\n type ReviewFigmaRenderFormat,\n} from './render';\n\nexport const DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT =\n '/__dfwr/figma-images';\n\ntype ReviewFigmaImageTokenProvider =\n | string\n | null\n | undefined\n | (() => string | null | undefined);\n\nexport type ReviewFigmaImageStoreHeadersProvider =\n | HeadersInit\n | null\n | undefined\n | (() => HeadersInit | null | undefined | Promise<HeadersInit | null | undefined>);\n\nexport type ReviewFigmaImageStoreClientOptions = {\n endpoint?: string;\n fetch?: typeof fetch;\n token?: ReviewFigmaImageTokenProvider;\n clientRender?: boolean | ReviewFigmaImageClientRenderOptions;\n};\n\nexport type EndpointReviewFigmaImageStoreOptions =\n ReviewFigmaImageStoreClientOptions & {\n headers?: ReviewFigmaImageStoreHeadersProvider;\n };\n\nexport type ReviewFigmaImageClientRenderOptions = {\n token?: string | null | (() => string | null | undefined);\n apiBaseUrl?: string;\n renderFormat?: Extract<ReviewFigmaRenderFormat, 'png' | 'jpg'>;\n renderScale?: number;\n useAbsoluteBounds?: boolean;\n convertToWebp?: boolean;\n webpQuality?: number;\n timeoutMs?: number;\n};\n\nexport type CreateReviewFigmaClientRenderedAssetOptions =\n ReviewFigmaImageClientRenderOptions & {\n figmaUrl: string;\n token: string;\n fetch?: typeof fetch;\n };\n\nexport function createReviewFigmaImageStoreClient(\n options: ReviewFigmaImageStoreClientOptions = {}\n): ReviewFigmaImageStore {\n return createEndpointReviewFigmaImageStore(options);\n}\n\nexport function createEndpointReviewFigmaImageStore(\n options: EndpointReviewFigmaImageStoreOptions = {}\n): ReviewFigmaImageStore {\n const endpoint =\n options.endpoint ?? DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT;\n const request = createReviewFigmaImageStoreRequest(\n options.fetch,\n options.headers\n );\n\n return {\n listImages(target) {\n const url = `${endpoint}?target=${encodeURIComponent(\n JSON.stringify(target)\n )}`;\n return request<ReviewFigmaImage[]>(url);\n },\n async addImage(input) {\n const nextInput = await createClientRenderedAddImageInput(\n input,\n options.clientRender,\n options.fetch\n );\n return request<ReviewFigmaImage>(endpoint, {\n method: 'POST',\n body: JSON.stringify(nextInput),\n figmaToken: readReviewFigmaImageToken(\n options.token ?? getStoredReviewFigmaImageToken\n ),\n });\n },\n updateImage(id, patch) {\n return request<ReviewFigmaImage>(`${endpoint}/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(patch),\n });\n },\n reorderImages(input) {\n return request<ReviewFigmaImage[]>(`${endpoint}/reorder`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n });\n },\n deleteImage(id) {\n return request<void>(`${endpoint}/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n },\n };\n}\n\nasync function createClientRenderedAddImageInput(\n input: AddReviewFigmaImageInput,\n clientRender: ReviewFigmaImageStoreClientOptions['clientRender'],\n fetchOption: typeof fetch | undefined\n): Promise<AddReviewFigmaImageInput> {\n const options = normalizeClientRenderOptions(clientRender);\n if (!options) return input;\n\n const token = readClientRenderToken(options);\n if (!token) return input;\n\n try {\n const asset = await createReviewFigmaClientRenderedAsset({\n ...options,\n fetch: fetchOption,\n figmaUrl: input.figmaUrl,\n token,\n });\n return {\n ...input,\n imageFormat: asset.imageFormat,\n asset,\n };\n } catch {\n return input;\n }\n}\n\nfunction normalizeClientRenderOptions(\n clientRender: ReviewFigmaImageStoreClientOptions['clientRender']\n): ReviewFigmaImageClientRenderOptions | null {\n if (!clientRender) return null;\n if (clientRender === true) return {};\n return clientRender;\n}\n\nfunction readClientRenderToken(options: ReviewFigmaImageClientRenderOptions) {\n const token =\n typeof options.token === 'function' ? options.token() : options.token;\n return typeof token === 'string' ? token.trim() : '';\n}\n\nasync function createClientRenderedFigmaAsset(\n figmaUrl: string,\n token: string,\n options: ReviewFigmaImageClientRenderOptions,\n fetchOption: typeof fetch | undefined\n): Promise<ReviewFigmaImageAssetInput> {\n const ref = parseReviewFigmaNodeRef(figmaUrl);\n if (!ref) throw new Error('A Figma node link is required.');\n\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma client rendering requires fetch.');\n\n const renderFormat = options.renderFormat ?? 'png';\n const response = await requestFetch(\n createReviewFigmaImageApiUrl({\n apiBaseUrl: options.apiBaseUrl,\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n format: renderFormat,\n scale: options.renderScale,\n useAbsoluteBounds: options.useAbsoluteBounds,\n }),\n {\n headers: {\n 'X-Figma-Token': token,\n },\n }\n );\n const body = (await response.json().catch(() => null)) as\n | { err?: string | null; images?: Record<string, string | null | undefined> }\n | null;\n if (!response.ok) {\n throw new Error(body?.err || `Figma image render failed with ${response.status}`);\n }\n\n const imageUrl = body?.images?.[ref.nodeId];\n if (!imageUrl) throw new Error(`Figma image render returned no URL for ${ref.nodeId}.`);\n\n const imageResponse = await requestFetch(imageUrl);\n if (!imageResponse.ok) {\n throw new Error(`Figma image download failed with ${imageResponse.status}`);\n }\n\n const originalBlob = await imageResponse.blob();\n const originalMimeType =\n normalizeClientImageMimeType(originalBlob.type) ??\n getReviewFigmaImageMimeType(renderFormat === 'jpg' ? 'jpg' : 'png');\n const originalFormat =\n getReviewFigmaImageFormatFromMimeType(originalMimeType) ??\n (renderFormat === 'jpg' ? 'jpg' : 'png');\n const dimensions = await readImageBlobDimensions(originalBlob);\n const shouldConvertToWebp = options.convertToWebp ?? true;\n const convertedBlob = shouldConvertToWebp\n ? await convertImageBlobToWebp(\n originalBlob,\n options.webpQuality ?? 0.9,\n dimensions\n ).catch(() => null)\n : null;\n const finalBlob =\n convertedBlob?.type === 'image/webp' ? convertedBlob : originalBlob;\n const finalMimeType =\n normalizeClientImageMimeType(finalBlob.type) ?? originalMimeType;\n const finalFormat =\n getReviewFigmaImageFormatFromMimeType(finalMimeType) ?? originalFormat;\n\n return {\n dataUrl: await blobToDataUrl(finalBlob),\n imageFormat: finalFormat,\n mimeType: finalMimeType,\n byteSize: finalBlob.size,\n width: dimensions.width,\n height: dimensions.height,\n };\n}\n\nexport function createReviewFigmaClientRenderedAsset({\n fetch: fetchOption,\n figmaUrl,\n token,\n ...options\n}: CreateReviewFigmaClientRenderedAssetOptions): Promise<ReviewFigmaImageAssetInput> {\n return withTimeout(\n createClientRenderedFigmaAsset(figmaUrl, token, options, fetchOption),\n options.timeoutMs ?? 10000\n );\n}\n\nasync function readImageBlobDimensions(blob: Blob) {\n const image = await loadImageBlob(blob);\n return {\n width: image.naturalWidth || image.width,\n height: image.naturalHeight || image.height,\n };\n}\n\nasync function convertImageBlobToWebp(\n blob: Blob,\n quality: number,\n dimensions: { width: number; height: number }\n) {\n if (typeof document === 'undefined') return null;\n if (!dimensions.width || !dimensions.height) return null;\n\n const image = await loadImageBlob(blob);\n const canvas = document.createElement('canvas');\n canvas.width = dimensions.width;\n canvas.height = dimensions.height;\n const context = canvas.getContext('2d');\n if (!context) return null;\n\n context.drawImage(image, 0, 0);\n\n return new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, 'image/webp', quality);\n });\n}\n\nfunction loadImageBlob(blob: Blob) {\n return new Promise<HTMLImageElement>((resolve, reject) => {\n if (typeof Image === 'undefined' || typeof URL === 'undefined') {\n reject(new Error('Image decoding is unavailable.'));\n return;\n }\n\n const image = new Image();\n const objectUrl = URL.createObjectURL(blob);\n image.onload = () => {\n URL.revokeObjectURL(objectUrl);\n resolve(image);\n };\n image.onerror = () => {\n URL.revokeObjectURL(objectUrl);\n reject(new Error('Image decoding failed.'));\n };\n image.src = objectUrl;\n });\n}\n\nfunction blobToDataUrl(blob: Blob) {\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n return;\n }\n reject(new Error('Blob encoding failed.'));\n };\n reader.onerror = () => reject(reader.error ?? new Error('Blob encoding failed.'));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction normalizeClientImageMimeType(value: string | null | undefined) {\n const mimeType = value?.split(';')[0]?.trim().toLowerCase();\n if (mimeType === 'image/jpg') return 'image/jpeg';\n if (\n mimeType === 'image/jpeg' ||\n mimeType === 'image/png' ||\n mimeType === 'image/webp'\n ) {\n return mimeType;\n }\n return null;\n}\n\nasync function withTimeout<T>(promise: Promise<T>, timeoutMs: number) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error('Figma client rendering timed out.')),\n timeoutMs\n );\n }),\n ]);\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n}\n\nexport function getReviewFigmaImageTargetKey(target: ReviewFigmaImageTarget) {\n return JSON.stringify(normalizeReviewFigmaImageTarget(target));\n}\n\nexport function getReviewFigmaImageMimeType(\n format: ReviewFigmaImageFormat\n) {\n if (format === 'jpg') return 'image/jpeg';\n if (format === 'png') return 'image/png';\n return 'image/webp';\n}\n\ntype ReviewFigmaImageStoreRequestInit = RequestInit & {\n figmaToken?: string;\n};\n\nfunction createReviewFigmaImageStoreRequest(\n fetchOption: typeof fetch | undefined,\n headersProvider: ReviewFigmaImageStoreHeadersProvider\n) {\n return async <T>(\n input: string,\n init: ReviewFigmaImageStoreRequestInit = {}\n ) => {\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma image store requires fetch.');\n const figmaToken = init.figmaToken ?? '';\n const {\n figmaToken: _figmaToken,\n headers: requestHeaders,\n ...requestInit\n } = init;\n const headers = new Headers();\n headers.set('Content-Type', 'application/json');\n if (figmaToken) headers.set('X-Figma-Token', figmaToken);\n appendReviewFigmaImageStoreHeaders(\n headers,\n await readReviewFigmaImageStoreHeaders(headersProvider)\n );\n appendReviewFigmaImageStoreHeaders(headers, requestHeaders);\n\n const response = await requestFetch(input, {\n ...requestInit,\n headers,\n });\n const text = await response.text();\n const body = text ? JSON.parse(text) : null;\n\n if (!response.ok) {\n const message =\n typeof body?.error === 'string'\n ? body.error\n : `Figma image store request failed: ${response.status}`;\n throw new Error(message);\n }\n\n return body as T;\n };\n}\n\nasync function readReviewFigmaImageStoreHeaders(\n provider: ReviewFigmaImageStoreHeadersProvider\n) {\n return typeof provider === 'function' ? provider() : provider;\n}\n\nfunction appendReviewFigmaImageStoreHeaders(\n target: Headers,\n source: HeadersInit | null | undefined\n) {\n if (!source) return;\n new Headers(source).forEach((value, key) => {\n target.set(key, value);\n });\n}\n\nfunction readReviewFigmaImageToken(provider: ReviewFigmaImageTokenProvider) {\n const token = typeof provider === 'function' ? provider() : provider;\n return typeof token === 'string' ? token.trim() : '';\n}\n\nfunction getStoredReviewFigmaImageToken() {\n if (typeof window === 'undefined') return '';\n\n try {\n return window.localStorage.getItem('figma-token') ?? '';\n } catch {\n return '';\n }\n}\n\nfunction normalizeReviewFigmaImageTarget(target: ReviewFigmaImageTarget) {\n if (target.type === 'figma-node') {\n return {\n type: target.type,\n projectId: target.projectId,\n fileKey: target.fileKey,\n nodeId: target.nodeId,\n };\n }\n\n return {\n type: target.type,\n projectId: target.projectId,\n pageUrl: target.pageUrl,\n slot: target.slot ?? '',\n viewport: target.viewport\n ? {\n label: target.viewport.label ?? '',\n width: target.viewport.width ?? null,\n height: target.viewport.height ?? null,\n scope: target.viewport.scope ?? '',\n }\n : null,\n };\n}\n\nexport type { ReorderReviewFigmaImagesInput };\n","import type {\n AddReviewFigmaImageInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n UpdateReviewFigmaImageInput,\n} from './image.types';\nimport {\n createReviewFigmaClientRenderedAsset,\n getReviewFigmaImageTargetKey,\n type ReviewFigmaImageClientRenderOptions,\n} from './image.store';\nimport { parseReviewFigmaNodeRef } from './parse';\n\nexport const DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE = 'review_figma_images';\nconst DEFAULT_REVIEW_FIGMA_REMOTE_UPLOAD_TIMEOUT_MS = 30000;\nconst FIGMA_TOKEN_STORAGE_KEY = 'figma-token';\n\ntype ReviewFigmaRemoteTokenProvider =\n | string\n | null\n | undefined\n | (() => string | null | undefined);\n\nexport type ReviewFigmaRemoteImageRow = {\n id: string;\n project_id: string;\n target_key: string;\n target: ReviewFigmaImageTarget;\n target_type: 'route' | 'figma-node';\n page_url: string | null;\n viewport_label: string | null;\n viewport_width: number | null;\n viewport_height: number | null;\n viewport_scope: 'mobile' | 'tablet' | 'desktop' | 'wide' | null;\n slot: string | null;\n figma_url: string;\n file_key: string;\n node_id: string;\n image_url: string;\n image_format: ReviewFigmaImageFormat;\n mime_type: string;\n storage_key: string;\n label: string | null;\n sort_order: number;\n width: number | null;\n height: number | null;\n byte_size: number | null;\n created_at: string;\n updated_at: string;\n};\n\ntype ReviewFigmaRemoteDbResult<T = unknown> = {\n data: T | null;\n error: unknown;\n};\n\ntype ReviewFigmaRemoteDbQuery<T = unknown> = PromiseLike<\n ReviewFigmaRemoteDbResult<T>\n> & {\n delete(): ReviewFigmaRemoteDbQuery<T>;\n eq(column: string, value: unknown): ReviewFigmaRemoteDbQuery<T>;\n insert(value: unknown): ReviewFigmaRemoteDbQuery<T>;\n order(\n column: string,\n options?: { ascending?: boolean }\n ): ReviewFigmaRemoteDbQuery<T>;\n select(columns?: string): ReviewFigmaRemoteDbQuery<T>;\n single(): PromiseLike<ReviewFigmaRemoteDbResult<T>>;\n update(value: unknown): ReviewFigmaRemoteDbQuery<T>;\n};\n\nexport type ReviewFigmaRemoteDbClient = {\n from(table: string): ReviewFigmaRemoteDbQuery;\n};\n\nexport type ReviewFigmaRemoteAssetUploadResponse = {\n storageKey?: unknown;\n r2Key?: unknown;\n imageUrl?: unknown;\n publicUrl?: unknown;\n error?: unknown;\n};\n\nexport type RemoteReviewFigmaImageStoreOptions = {\n client: ReviewFigmaRemoteDbClient;\n uploadEndpoint: string;\n table?: string;\n fetch?: typeof fetch;\n token?: ReviewFigmaRemoteTokenProvider;\n clientRender?: boolean | ReviewFigmaImageClientRenderOptions;\n uploadTimeoutMs?: number;\n};\n\nexport function createRemoteReviewFigmaImageStore({\n client,\n uploadEndpoint,\n table = DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE,\n fetch: fetchOption,\n token,\n clientRender = true,\n uploadTimeoutMs = DEFAULT_REVIEW_FIGMA_REMOTE_UPLOAD_TIMEOUT_MS,\n}: RemoteReviewFigmaImageStoreOptions): ReviewFigmaImageStore {\n const listImages = async (target: ReviewFigmaImageTarget) => {\n const targetKey = getReviewFigmaImageTargetKey(target);\n const { data, error } = await client\n .from(table)\n .select('*')\n .eq('project_id', target.projectId)\n .eq('target_key', targetKey)\n .order('sort_order', { ascending: true })\n .order('created_at', { ascending: true });\n\n if (error) throwRemoteStoreError(error, 'list Figma images');\n return ((data ?? []) as ReviewFigmaRemoteImageRow[]).map(rowToFigmaImage);\n };\n\n return {\n listImages,\n async addImage(input) {\n const ref = parseReviewFigmaNodeRef(input.figmaUrl);\n if (!ref) {\n throw new Error('A Figma node link or fileKey->nodeId value is required.');\n }\n\n const id = createFigmaImageId();\n const asset = await resolveFigmaImageAsset({\n input,\n token,\n clientRender,\n fetch: fetchOption,\n });\n const uploaded = await uploadFigmaAsset({\n asset,\n endpoint: uploadEndpoint,\n fetch: fetchOption,\n imageId: id,\n projectId: input.target.projectId,\n timeoutMs: uploadTimeoutMs,\n });\n const order =\n typeof input.order === 'number' && Number.isFinite(input.order)\n ? input.order\n : await getNextImageOrder(listImages, input.target);\n const now = new Date().toISOString();\n const row = createImageRow({\n asset,\n fileKey: ref.fileKey,\n id,\n imageUrl: uploaded.imageUrl,\n input,\n nodeId: ref.nodeId,\n now,\n order,\n storageKey: uploaded.storageKey,\n });\n const { data, error } = await client\n .from(table)\n .insert(row)\n .select('*')\n .single();\n\n if (error) throwRemoteStoreError(error, 'insert Figma image');\n return rowToFigmaImage(data as ReviewFigmaRemoteImageRow);\n },\n async updateImage(id, patch) {\n const { data, error } = await client\n .from(table)\n .update(createUpdatePatch(patch))\n .eq('id', id)\n .select('*')\n .single();\n\n if (error) throwRemoteStoreError(error, 'update Figma image');\n return rowToFigmaImage(data as ReviewFigmaRemoteImageRow);\n },\n async reorderImages(input) {\n const current = await listImages(input.target);\n const currentIds = new Set(current.map((image) => image.id));\n const nextIds = [\n ...input.imageIds.filter((id) => currentIds.has(id)),\n ...current\n .map((image) => image.id)\n .filter((id) => !input.imageIds.includes(id)),\n ];\n const targetKey = getReviewFigmaImageTargetKey(input.target);\n const updatedAt = new Date().toISOString();\n\n const results = await Promise.all(\n nextIds.map((id, index) =>\n client\n .from(table)\n .update({ sort_order: index, updated_at: updatedAt })\n .eq('id', id)\n .eq('project_id', input.target.projectId)\n .eq('target_key', targetKey)\n )\n );\n const failed = results.find((result) => result.error);\n if (failed?.error) throwRemoteStoreError(failed.error, 'reorder Figma images');\n\n return listImages(input.target);\n },\n async deleteImage(id) {\n const { error } = await client.from(table).delete().eq('id', id);\n if (error) throwRemoteStoreError(error, 'delete Figma image');\n },\n };\n}\n\nasync function resolveFigmaImageAsset({\n input,\n token,\n clientRender,\n fetch,\n}: {\n input: AddReviewFigmaImageInput;\n token: ReviewFigmaRemoteTokenProvider;\n clientRender: boolean | ReviewFigmaImageClientRenderOptions;\n fetch: typeof globalThis.fetch | undefined;\n}) {\n if (input.asset) return input.asset;\n if (!clientRender) {\n throw new Error('Figma image asset is required when clientRender is disabled.');\n }\n\n const renderOptions = clientRender === true ? {} : clientRender;\n const figmaToken = readRemoteFigmaToken(renderOptions.token ?? token);\n if (!figmaToken) throw new Error('Figma token is required.');\n\n return createReviewFigmaClientRenderedAsset({\n ...renderOptions,\n fetch,\n figmaUrl: input.figmaUrl,\n token: figmaToken,\n });\n}\n\nasync function uploadFigmaAsset({\n asset,\n endpoint,\n fetch: fetchOption,\n imageId,\n projectId,\n timeoutMs,\n}: {\n asset: ReviewFigmaImageAssetInput;\n endpoint: string;\n fetch: typeof globalThis.fetch | undefined;\n imageId: string;\n projectId: string;\n timeoutMs: number;\n}) {\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma asset upload requires fetch.');\n\n const { blob, mimeType } = decodeAssetDataUrl(asset);\n const response = await withTimeout(\n requestFetch(\n createAssetUploadUrl(endpoint, {\n imageFormat: asset.imageFormat,\n imageId,\n projectId,\n }),\n {\n method: 'POST',\n headers: {\n 'Content-Type': mimeType,\n },\n body: blob,\n }\n ),\n timeoutMs,\n 'Figma asset upload timed out.'\n );\n const data = (await response.json().catch(() => null)) as\n | ReviewFigmaRemoteAssetUploadResponse\n | null;\n\n if (!response.ok) {\n throw new Error(\n readString(data?.error) || `Figma asset upload failed with ${response.status}`\n );\n }\n\n const storageKey = readString(data?.storageKey) ?? readString(data?.r2Key);\n const imageUrl = readString(data?.imageUrl) ?? readString(data?.publicUrl);\n if (!storageKey || !imageUrl) {\n throw new Error('Figma asset upload response is missing image URL.');\n }\n\n return { storageKey, imageUrl };\n}\n\nfunction createAssetUploadUrl(\n endpoint: string,\n params: {\n imageFormat: ReviewFigmaImageFormat;\n imageId: string;\n projectId: string;\n }\n) {\n const base =\n typeof window !== 'undefined' ? window.location.origin : 'http://localhost';\n const url = new URL(endpoint, base);\n url.searchParams.set('projectId', params.projectId);\n url.searchParams.set('imageId', params.imageId);\n url.searchParams.set('imageFormat', params.imageFormat);\n return url.toString();\n}\n\nfunction createImageRow({\n asset,\n fileKey,\n id,\n imageUrl,\n input,\n nodeId,\n now,\n order,\n storageKey,\n}: {\n asset: ReviewFigmaImageAssetInput;\n fileKey: string;\n id: string;\n imageUrl: string;\n input: AddReviewFigmaImageInput;\n nodeId: string;\n now: string;\n order: number;\n storageKey: string;\n}): ReviewFigmaRemoteImageRow {\n const target = input.target;\n const targetKey = getReviewFigmaImageTargetKey(target);\n\n return {\n id,\n project_id: target.projectId,\n target_key: targetKey,\n target,\n target_type: target.type,\n page_url: target.type === 'route' ? target.pageUrl : null,\n viewport_label: target.type === 'route' ? target.viewport?.label ?? null : null,\n viewport_width: target.type === 'route' ? target.viewport?.width ?? null : null,\n viewport_height: target.type === 'route' ? target.viewport?.height ?? null : null,\n viewport_scope: target.type === 'route' ? target.viewport?.scope ?? null : null,\n slot: target.type === 'route' ? target.slot ?? null : null,\n figma_url: input.figmaUrl,\n file_key: fileKey,\n node_id: nodeId,\n image_url: imageUrl,\n image_format: asset.imageFormat,\n mime_type: asset.mimeType,\n storage_key: storageKey,\n label: normalizeOptionalText(input.label) ?? null,\n sort_order: order,\n width: asset.width ?? null,\n height: asset.height ?? null,\n byte_size: asset.byteSize ?? null,\n created_at: now,\n updated_at: now,\n };\n}\n\nfunction createUpdatePatch(patch: UpdateReviewFigmaImageInput) {\n return {\n ...(patch.label !== undefined\n ? { label: normalizeOptionalText(patch.label) ?? null }\n : {}),\n ...(typeof patch.order === 'number' && Number.isFinite(patch.order)\n ? { sort_order: patch.order }\n : {}),\n updated_at: new Date().toISOString(),\n };\n}\n\nasync function getNextImageOrder(\n listImages: (target: ReviewFigmaImageTarget) => Promise<ReviewFigmaImage[]>,\n target: ReviewFigmaImageTarget\n) {\n const images = await listImages(target);\n return images.length\n ? Math.max(...images.map((image) => image.order)) + 1\n : 0;\n}\n\nfunction rowToFigmaImage(row: ReviewFigmaRemoteImageRow): ReviewFigmaImage {\n return {\n id: row.id,\n projectId: row.project_id,\n target: row.target,\n figmaUrl: row.figma_url,\n fileKey: row.file_key,\n nodeId: row.node_id,\n imageUrl: row.image_url,\n imageFormat: row.image_format,\n mimeType: row.mime_type,\n label: row.label ?? undefined,\n order: row.sort_order,\n storageKey: row.storage_key,\n width: row.width ?? undefined,\n height: row.height ?? undefined,\n byteSize: row.byte_size ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction decodeAssetDataUrl(asset: ReviewFigmaImageAssetInput) {\n const match = asset.dataUrl.match(/^data:([^;,]+);base64,(.*)$/);\n if (!match) throw new Error('Valid Figma image asset data URL is required.');\n\n const mimeType = match[1]?.trim();\n if (!mimeType || mimeType !== asset.mimeType) {\n throw new Error('Figma image asset MIME type mismatch.');\n }\n\n const binary = globalThis.atob(match[2] ?? '');\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return {\n blob: new Blob([bytes], { type: mimeType }),\n mimeType,\n };\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string\n) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(message)), timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n}\n\nfunction readRemoteFigmaToken(provider: ReviewFigmaRemoteTokenProvider) {\n const token = typeof provider === 'function' ? provider() : provider;\n if (typeof token === 'string' && token.trim()) return token.trim();\n return readStoredFigmaToken();\n}\n\nfunction readStoredFigmaToken() {\n if (typeof window === 'undefined') return '';\n\n try {\n return window.localStorage.getItem(FIGMA_TOKEN_STORAGE_KEY)?.trim() || '';\n } catch {\n return '';\n }\n}\n\nfunction createFigmaImageId() {\n const id =\n globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n return `figma_${id.replace(/[^A-Za-z0-9_-]+/g, '-')}`;\n}\n\nfunction normalizeOptionalText(value: string | null | undefined) {\n if (typeof value !== 'string') return undefined;\n return value.trim() || undefined;\n}\n\nfunction readString(value: unknown) {\n return typeof value === 'string' && value.trim() ? value.trim() : null;\n}\n\nfunction throwRemoteStoreError(error: unknown, action: string): never {\n const source = error as {\n code?: unknown;\n details?: unknown;\n hint?: unknown;\n message?: unknown;\n };\n const message = readString(source.message) ?? `Remote Figma image ${action} failed.`;\n const code = readString(source.code);\n const details = readString(source.details);\n const hint = readString(source.hint);\n const suffix = [code, details, hint].filter(Boolean).join(' / ');\n\n throw new Error(suffix ? `${message} (${suffix})` : message);\n}\n","import type {\n ReviewFigmaImage,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n} from './image.types';\nimport { getReviewFigmaImageTargetKey } from './image.store';\n\nexport type ReviewFigmaImagesSnapshot = ReviewFigmaImage[];\n\nexport type ReviewFigmaReleaseSnapshot = {\n version: 1;\n projectId: string;\n releaseId?: string;\n label?: string;\n createdAt: string;\n figmaImagesSnapshot: ReviewFigmaImagesSnapshot;\n};\n\nexport type CreateReviewFigmaImagesSnapshotOptions = {\n projectId?: string;\n targets?: readonly ReviewFigmaImageTarget[];\n};\n\nexport type CreateReviewFigmaReleaseSnapshotOptions =\n CreateReviewFigmaImagesSnapshotOptions & {\n images: readonly ReviewFigmaImage[];\n projectId: string;\n releaseId?: string;\n label?: string;\n createdAt?: string;\n };\n\nexport type CollectReviewFigmaReleaseSnapshotOptions = Omit<\n CreateReviewFigmaReleaseSnapshotOptions,\n 'images'\n> & {\n store: ReviewFigmaImageStore;\n targets: readonly ReviewFigmaImageTarget[];\n};\n\nexport function createReviewFigmaImagesSnapshot(\n images: readonly ReviewFigmaImage[],\n options: CreateReviewFigmaImagesSnapshotOptions = {}\n): ReviewFigmaImagesSnapshot {\n const targetKeys = options.targets?.length\n ? new Set(options.targets.map(getReviewFigmaImageTargetKey))\n : null;\n\n return images\n .filter((image) => {\n if (options.projectId && image.projectId !== options.projectId) {\n return false;\n }\n if (\n targetKeys &&\n !targetKeys.has(getReviewFigmaImageTargetKey(image.target))\n ) {\n return false;\n }\n return true;\n })\n .map(cloneReviewFigmaImage)\n .sort(compareReviewFigmaSnapshotImages);\n}\n\nexport function createReviewFigmaReleaseSnapshot({\n images,\n projectId,\n releaseId,\n label,\n createdAt,\n targets,\n}: CreateReviewFigmaReleaseSnapshotOptions): ReviewFigmaReleaseSnapshot {\n return {\n version: 1,\n projectId,\n ...(releaseId ? { releaseId } : null),\n ...(label ? { label } : null),\n createdAt: createdAt ?? new Date().toISOString(),\n figmaImagesSnapshot: createReviewFigmaImagesSnapshot(images, {\n projectId,\n targets,\n }),\n };\n}\n\nexport async function collectReviewFigmaReleaseSnapshot({\n store,\n targets,\n ...snapshotOptions\n}: CollectReviewFigmaReleaseSnapshotOptions): Promise<ReviewFigmaReleaseSnapshot> {\n const imagesByTarget = await Promise.all(\n targets.map((target) => store.listImages(target))\n );\n\n return createReviewFigmaReleaseSnapshot({\n ...snapshotOptions,\n targets,\n images: dedupeReviewFigmaImages(imagesByTarget.flat()),\n });\n}\n\nfunction dedupeReviewFigmaImages(images: readonly ReviewFigmaImage[]) {\n return Array.from(new Map(images.map((image) => [image.id, image])).values());\n}\n\nfunction cloneReviewFigmaImage(image: ReviewFigmaImage): ReviewFigmaImage {\n return {\n ...image,\n target: cloneReviewFigmaImageTarget(image.target),\n };\n}\n\nfunction cloneReviewFigmaImageTarget(\n target: ReviewFigmaImageTarget\n): ReviewFigmaImageTarget {\n if (target.type === 'figma-node') {\n return {\n type: target.type,\n projectId: target.projectId,\n fileKey: target.fileKey,\n nodeId: target.nodeId,\n };\n }\n\n return {\n type: target.type,\n projectId: target.projectId,\n pageUrl: target.pageUrl,\n slot: target.slot,\n viewport: target.viewport\n ? {\n label: target.viewport.label,\n width: target.viewport.width,\n height: target.viewport.height,\n scope: target.viewport.scope,\n }\n : undefined,\n };\n}\n\nfunction compareReviewFigmaSnapshotImages(\n a: ReviewFigmaImage,\n b: ReviewFigmaImage\n) {\n return (\n a.projectId.localeCompare(b.projectId) ||\n getReviewFigmaImageTargetKey(a.target).localeCompare(\n getReviewFigmaImageTargetKey(b.target)\n ) ||\n a.order - b.order ||\n a.createdAt.localeCompare(b.createdAt) ||\n a.id.localeCompare(b.id)\n );\n}\n","import type {\n RelativeSelection,\n ReviewPoint,\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 overlayRect: {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n composerHost?: HTMLElement | null;\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\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\n return {\n x: point.x + environment.viewportRect.left,\n y: point.y + 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 return {\n left: selection.left + environment.viewportRect.left,\n top: selection.top + environment.viewportRect.top,\n width: selection.width,\n height: selection.height,\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\n return {\n x: point.x - environment.viewportRect.left,\n y: point.y - environment.viewportRect.top,\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/** Resolves a DOM anchor from the center of a target-space selection. */\nexport function getDomAnchor(\n selection: ViewportSelection,\n configuredAttribute = 'data-qa-id',\n environment: ReviewEnvironment\n): DomAnchor | undefined {\n const x = selection.left + selection.width / 2;\n const y = selection.top + selection.height / 2;\n return getDomAnchorFromPoint({ x, y }, configuredAttribute, environment);\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","/** 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\nfunction 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 const aliases: Record<string, string[]> = {\n q: ['ㅂ', 'ㅃ'],\n };\n\n return 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 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<ReviewItemScope, string> = {\n mobile: 'Mobile',\n tablet: 'Tablet',\n desktop: 'Desktop',\n wide: 'Wide',\n dom: 'Element',\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/** Resolves an item's persisted scope, falling back to its captured viewport. */\nexport function getReviewItemScope(\n item: ReviewItem,\n presets: ReviewViewportPreset[] = DEFAULT_REVIEW_VIEWPORTS\n): ReviewItemScope {\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 if (scope === 'dom') return REVIEW_SCOPE_LABELS.dom;\n\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 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 getSelectionCenter,\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 = 'note' | '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.kind !== 'area' && 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 getVisibleHighlightSelection(\n [\n getAnchorHighlightSelection(item, environment),\n getBoundSelection(item, environment),\n getPointHighlightSelection(item, environment),\n ],\n environment\n );\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 if (item.kind === 'area') return 'area';\n return 'note';\n}\n\n/** Returns an explicit marker or derives one from the item's selection center. */\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(getSelectionCenter(selection.viewport)),\n relative: selection.relative\n ? roundPoint(getSelectionCenter(selection.relative))\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 ReviewSelection | RelativeSelection | 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 center and stores an anchor-relative fallback. */\nexport function createSelectionCenterMarker(\n selection: ViewportSelection,\n anchor: DomAnchor | undefined,\n environment: ReviewEnvironment\n): ReviewMarker {\n const centerPoint = getSelectionCenter(selection);\n\n return {\n viewport: roundPoint(centerPoint),\n relative: anchor ? getRelativePoint(centerPoint, anchor, environment) : 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.kind !== 'area' && 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 (\n item.scope === 'dom' ||\n (item.kind === 'note' && Boolean(item.anchor && getItemSelection(item)))\n );\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 { NoteDraft } 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: NoteDraft,\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: NoteDraft,\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: NoteDraft,\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: NoteDraft,\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","/**\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 {\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 0 0 9999px rgba(0, 0, 0, 0.08),\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-bound-marker.is-note-callout,\n .dfwr-bound-marker.is-note-callout.is-highlighted {\n --dfwr-scope: #7cc7ff;\n --dfwr-scope-rgb: 124, 199, 255;\n min-width: 0;\n width: 0;\n height: 0;\n padding: 0;\n transform: none;\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n color: var(--dfwr-scope);\n animation: none;\n overflow: visible;\n }\n\n .dfwr-bound-marker.is-note-callout::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n width: 8px;\n height: 8px;\n transform: translate(-50%, -50%);\n border: 2px solid #111820;\n border-radius: var(--df-review-radius-pill);\n background: var(--dfwr-scope);\n box-shadow:\n 0 0 0 3px rgba(var(--dfwr-scope-rgb), 0.22),\n 0 6px 16px rgba(0, 0, 0, 0.28);\n }\n\n .dfwr-bound-marker.is-note-callout.is-highlighted::before {\n animation: dfwr-note-dot-pulse 1000ms ease-in-out infinite;\n }\n\n .dfwr-bound-marker.is-note-callout .dfwr-bound-marker-icon {\n position: absolute;\n left: 0;\n top: 0;\n width: 31px;\n height: 2px;\n transform: rotate(-42deg);\n transform-origin: left center;\n border-radius: var(--df-review-radius-pill);\n background: currentColor;\n opacity: 1;\n }\n\n .dfwr-bound-marker.is-note-callout .dfwr-bound-marker-icon::before,\n .dfwr-bound-marker.is-note-callout .dfwr-bound-marker-icon::after {\n display: none;\n }\n\n .dfwr-bound-marker.is-note-callout .dfwr-bound-marker-number {\n position: absolute;\n left: 24px;\n top: -41px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n height: 20px;\n padding: 0 7px;\n border: 1px solid var(--dfwr-scope);\n border-radius: 4px;\n background: var(--dfwr-scope);\n box-shadow:\n 0 0 0 3px rgba(var(--dfwr-scope-rgb), 0.18),\n 0 8px 18px rgba(0, 0, 0, 0.28);\n color: #111820;\n text-align: center;\n line-height: 1;\n white-space: nowrap;\n }\n\n .dfwr-bound-marker.is-note-callout.is-highlighted .dfwr-bound-marker-icon,\n .dfwr-bound-marker.is-note-callout.is-highlighted .dfwr-bound-marker-number {\n animation: dfwr-selected-blink 1000ms ease-in-out infinite;\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-note-draft {\n position: fixed;\n inset: 0;\n z-index: 4;\n pointer-events: none;\n }\n\n .dfwr-note-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-note-pin:active {\n cursor: grabbing;\n }\n\n .dfwr-note-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-note-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-note-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-note-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-note-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-note-actions {\n justify-content: flex-end;\n }\n\n .dfwr-note-actions .dfwr-button:first-child {\n margin-right: auto;\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-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-note-dot-pulse {\n 0% {\n transform: translate(-50%, -50%) scale(0.88);\n }\n 45% {\n transform: translate(-50%, -50%) scale(1.3);\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 {\n DomAnchor,\n RelativeSelection,\n ReviewItem,\n ReviewPoint,\n ViewportSize,\n} from '../../types';\nimport { getAnchorCandidates } from '../dom.anchor';\nimport type { NoteDraft } from './draft';\nimport { getItemMarker, getItemSelection } from './item';\n\n/** Formats note draft metadata for compact debug display in the overlay UI. */\nexport function formatNoteDraftMeta(draft: NoteDraft) {\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","import type {\n NumberedReviewItem,\n ReviewItem,\n ReviewItemScope,\n ReviewMode,\n ReviewPoint,\n ViewportSize,\n WebReviewKitOptions,\n} from '../types';\nimport {\n getDomAnchorFromPoint,\n getElementViewportSelection,\n resolveAnchorElement,\n} from './dom.anchor';\nimport {\n clampPoint,\n clamp,\n getPopoverPosition,\n getViewportSize,\n isPointInViewport,\n placeLayerOverTarget,\n roundPoint,\n toHostPoint,\n toHostSelection,\n toTargetPoint,\n toTargetPointFromHostEvent,\n toViewportSelection,\n type ReviewEnvironment,\n type ViewportSelection,\n} from './geometry';\nimport { getRouteKey } from './location';\nimport * as draftMetrics from './draft.metrics';\nimport { createStyleElement } from './overlay.style';\nimport type { AreaDraft, NoteDraft } from './review/draft';\nimport { formatItemMeta, formatNoteDraftMeta } 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\ntype DraftItemFields = Partial<\n Pick<ReviewItem, 'title' | 'comment' | 'assigneeId' | 'assigneeName'>\n>;\n\n/** Minimal item payload collected by the view before the app fills persistence metadata. */\nexport type CreateReviewItemInput = Pick<ReviewItem, 'kind' | 'comment'> &\n Partial<\n Pick<\n ReviewItem,\n | 'title'\n | 'assigneeId'\n | 'assigneeName'\n | 'scope'\n | 'viewport'\n | 'anchor'\n | 'marker'\n | 'selection'\n >\n >;\n\nconst DEFAULT_ADJUSTMENT_LABEL = 'Responsive CSS px adjustments';\n\ninterface WebReviewKitViewState {\n isOpen: boolean;\n mode: ReviewMode;\n items: ReviewItem[];\n noteDraft?: NoteDraft;\n areaDraft?: AreaDraft;\n draftError?: string;\n isCreatingItem: boolean;\n isSelectingArea: boolean;\n highlightedItemId?: string;\n}\n\ninterface WebReviewKitViewActions {\n close: () => void;\n render: () => void;\n reload: () => Promise<ReviewItem[]>;\n restoreItem: (item: ReviewItem) => Promise<void>;\n removeItem: (itemId: string) => Promise<void>;\n setModeState: (mode: ReviewMode) => void;\n clearDrafts: () => void;\n setNoteDraft: (draft?: NoteDraft) => void;\n setAreaDraft: (draft?: AreaDraft) => void;\n setSelectingArea: (isSelectingArea: boolean) => void;\n createItem: (input: CreateReviewItemInput) => Promise<void>;\n bindNoteDraftToPoint: (\n point: ReviewPoint,\n fields?: DraftItemFields\n ) => Promise<void>;\n bindElementDraftToPoint: (\n point: ReviewPoint,\n fields?: DraftItemFields\n ) => Promise<void>;\n createAreaDraft: (selection: ViewportSelection) => Promise<void>;\n}\n\ninterface WebReviewKitViewConfig {\n options: WebReviewKitOptions;\n getState: () => WebReviewKitViewState;\n getEnvironment: () => ReviewEnvironment | undefined;\n actions: WebReviewKitViewActions;\n}\n\ntype DraftPreviewElement = HTMLElement | SVGElement;\n\ninterface DraftPreviewSnapshot {\n element: DraftPreviewElement;\n clone: DraftPreviewElement;\n visibility: string;\n}\n\n/** Vanilla DOM renderer for the core overlay, separate from React shell chrome. */\nexport class WebReviewKitView {\n private draftPreview?: DraftPreviewSnapshot;\n private shellComposerHost?: HTMLElement;\n\n constructor(private readonly config: WebReviewKitViewConfig) {}\n\n clearDraftPreview() {\n this.restoreDraftPreview();\n this.clearShellComposer();\n }\n\n render(shadow: ShadowRoot, hiddenItemsStyle: HTMLStyleElement) {\n const state = this.state;\n this.syncDraftPreview(\n state.isOpen && state.mode === 'element' ? state.noteDraft : undefined\n );\n\n shadow.replaceChildren();\n shadow.append(createStyleElement());\n shadow.append(hiddenItemsStyle);\n\n const hasDismissableDraft = Boolean(state.noteDraft || state.areaDraft);\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 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 this.createHeader(),\n this.createToolbar(),\n this.createBody(),\n this.createList()\n );\n\n shell.append(panel);\n }\n\n shell.append(this.createMarkerLayer());\n if (state.isOpen && hasDismissableDraft && !shouldDockComposer) {\n shell.append(this.createDraftCancelLayer());\n }\n\n if (state.isOpen && (state.mode === 'note' || state.mode === 'element')) {\n if (state.noteDraft) {\n const noteDraft = this.createNotePopover(state.noteDraft, {\n dockComposer: shouldDockComposer,\n });\n shell.append(noteDraft.layer);\n dockedComposer = noteDraft.composer;\n } else {\n shell.append(\n state.mode === 'element'\n ? this.createElementLayer()\n : this.createNoteLayer()\n );\n }\n }\n\n if (\n state.isOpen &&\n state.mode === 'area' &&\n !state.areaDraft &&\n !state.isSelectingArea\n ) {\n shell.append(this.createAreaLayer());\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(this.createAreaDraftOverlay(state.areaDraft));\n }\n const areaComposer = this.createAreaDraftPopover(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 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 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 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 // Draft adjustment geometry lives in draft.metrics.ts; these thin wrappers\n // supply the configured viewport presets so call sites stay unchanged.\n private get viewportPresets() {\n return this.config.options.viewports?.presets;\n }\n\n private getDraftAdjustmentMetrics(draft: NoteDraft) {\n return draftMetrics.getDraftAdjustmentMetrics(draft, this.viewportPresets);\n }\n\n private hasDraftAdjustment(draft: NoteDraft) {\n return draftMetrics.hasDraftAdjustment(draft, this.viewportPresets);\n }\n\n private getAdjustedDraftPoint(point: ReviewPoint, draft: NoteDraft) {\n return draftMetrics.getAdjustedDraftPoint(point, draft, this.viewportPresets);\n }\n\n private getAdjustedDraftSelection(\n selection: ViewportSelection,\n draft: NoteDraft\n ) {\n return draftMetrics.getAdjustedDraftSelection(\n selection,\n draft,\n this.viewportPresets\n );\n }\n\n private getDraftViewportScale(viewport: ViewportSize) {\n return draftMetrics.getDraftViewportScale(viewport, this.viewportPresets);\n }\n\n private getDraftComposerWidth(environment: ReviewEnvironment) {\n const bounds = environment.overlayRect;\n const margin = 12;\n return Math.min(360, Math.max(240, bounds.width - margin * 2));\n }\n\n private getClampedComposerPosition(\n position: ReviewPoint,\n environment: ReviewEnvironment,\n size?: { width?: number; height?: number },\n bounds = environment.overlayRect\n ) {\n const margin = 12;\n const width = size?.width ?? this.getDraftComposerWidth(environment);\n const height = size?.height ?? 236;\n\n return {\n x: clamp(\n position.x,\n bounds.left + margin,\n bounds.left + bounds.width - width - margin\n ),\n y: clamp(\n position.y,\n bounds.top + margin,\n bounds.top + bounds.height - height - margin\n ),\n };\n }\n\n private 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 private getInitialDraftComposerPosition(\n selection: ViewportSelection | undefined,\n environment: ReviewEnvironment,\n size: { width: number; height?: number }\n ) {\n const bounds = this.getHostComposerBounds();\n const margin = 12;\n const gap = 20;\n\n if (!selection) {\n return this.getClampedComposerPosition(\n {\n x: environment.overlayRect.left + margin,\n y: environment.overlayRect.top + 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 - margin;\n const x =\n preferredX <= maxX\n ? preferredX\n : selection.left - size.width - gap;\n\n return this.getClampedComposerPosition(\n {\n x,\n y: selection.top,\n },\n environment,\n size,\n bounds\n );\n }\n\n private 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 = this.getDraftComposerWidth(environment);\n\n if (composerPosition) {\n const clamped = this.getClampedComposerPosition(\n composerPosition,\n environment,\n { width, height: estimatedHeight },\n this.getHostComposerBounds()\n );\n return { width, left: clamped.x, top: clamped.y };\n }\n\n const position = this.getInitialDraftComposerPosition(selection, environment, {\n width,\n height: estimatedHeight,\n });\n\n return { width, left: position.x, top: position.y };\n }\n\n private getSelectionMqMetrics(\n selection: ViewportSelection,\n viewport: ViewportSize\n ) {\n const { scale } = this.getDraftViewportScale(viewport);\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 private formatSignedPx(value: number) {\n if (value === 0) return '+0px';\n return `${value > 0 ? '+' : ''}${value}px`;\n }\n\n private formatRoundedPx(value: number) {\n return `${Math.round(value)}px`;\n }\n\n private getAdjustmentLabel() {\n return (\n this.config.options.adjustmentLabel?.trim() || DEFAULT_ADJUSTMENT_LABEL\n );\n }\n\n private getSelectionMetricLines(\n selection: ViewportSelection | undefined,\n viewport: ViewportSize\n ) {\n if (!selection) return ['area', 'x none / y none', 'w none / h none'];\n\n const metrics = this.getSelectionMqMetrics(selection, viewport);\n return [\n 'area',\n `x ${this.formatRoundedPx(metrics.x)} / y ${this.formatRoundedPx(\n metrics.y\n )}`,\n `w ${this.formatRoundedPx(metrics.width)} / h ${this.formatRoundedPx(\n metrics.height\n )}`,\n ];\n }\n\n private getAreaDraftMetricSelection(draft: AreaDraft) {\n if (!draft.selection) return undefined;\n\n return toViewportSelection(draft.selection.viewport);\n }\n\n private getDraftAdjustmentMetricLines(draft: NoteDraft) {\n const metrics = this.getDraftAdjustmentMetrics(draft);\n return [\n `x ${this.formatSignedPx(metrics.x)} / y ${this.formatSignedPx(\n metrics.y\n )}`,\n `scale ${this.formatSignedPx(metrics.scale)}`,\n ];\n }\n\n private withDraftAdjustmentComment(comment: string, draft: NoteDraft) {\n if (!this.hasDraftAdjustment(draft)) return comment;\n\n const trimmedComment = comment.trim();\n const metrics = this.getDraftAdjustmentMetrics(draft);\n const adjustment = [\n `${this.getAdjustmentLabel()}: x ${this.formatSignedPx(\n metrics.x\n )}, y ${this.formatSignedPx(metrics.y)}, scale ${this.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\n private getAssigneeOption(assigneeId: string | null | undefined) {\n if (!assigneeId) return undefined;\n return this.config.options.assigneeOptions?.find(\n (option) => option.value === assigneeId\n );\n }\n\n private getAssigneeName(assigneeId: string | null | undefined) {\n return this.getAssigneeOption(assigneeId)?.label;\n }\n\n private 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 private isTitleFieldEnabled() {\n return this.config.options.fields?.title === true;\n }\n\n private createDraftAssigneeSelect(\n value: string | null | undefined,\n fallbackLabel: string | undefined,\n onChange: (assigneeId: string | null, assigneeName?: string) => void\n ) {\n const assigneeOptions = this.config.options.assigneeOptions ?? [];\n if (assigneeOptions.length === 0) return undefined;\n const assigneeTitle =\n this.config.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 const hasUnknownAssignee =\n Boolean(value) &&\n !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, this.getAssigneeName(select.value));\n });\n\n return select;\n }\n\n private getDraftFields(\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: this.getAssigneeName(assigneeId),\n };\n }\n\n private getStyleableDraftElement(\n draft: NoteDraft,\n environment: ReviewEnvironment\n ): DraftPreviewElement | 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 DraftPreviewElement;\n\n return undefined;\n }\n\n private syncDraftPreview(draft?: NoteDraft) {\n const environment = this.config.getEnvironment();\n if (!draft || !environment || !this.hasDraftAdjustment(draft)) {\n this.restoreDraftPreview();\n return;\n }\n\n const element = this.getStyleableDraftElement(draft, environment);\n if (!element) {\n this.restoreDraftPreview();\n return;\n }\n\n if (this.draftPreview?.element !== element) {\n this.restoreDraftPreview();\n }\n\n if (!this.draftPreview) {\n const computedStyle = environment.window.getComputedStyle(element);\n const clone = element.cloneNode(true) as DraftPreviewElement;\n this.removeDuplicateIds(clone);\n this.copyComputedStyle(element, clone, environment);\n this.positionDraftPreviewClone(clone, element, computedStyle);\n environment.document.body?.appendChild(clone);\n this.draftPreview = {\n element,\n clone,\n visibility: element.style.visibility,\n };\n element.style.visibility = 'hidden';\n }\n\n const metrics = this.getDraftAdjustmentMetrics(draft);\n const translate = `translate(${this.toCssNumber(metrics.cssX)}px, ${this.toCssNumber(\n metrics.cssY\n )}px)`;\n const scale =\n metrics.scaleFactor === 1\n ? ''\n : `scale(${this.toCssNumber(metrics.scaleFactor)})`;\n this.draftPreview.clone.style.transform = [translate, scale]\n .filter(Boolean)\n .join(' ');\n }\n\n private restoreDraftPreview() {\n if (!this.draftPreview) return;\n\n const { element, clone, visibility } = this.draftPreview;\n clone.remove();\n element.style.visibility = visibility;\n this.draftPreview = undefined;\n }\n\n private positionDraftPreviewClone(\n clone: DraftPreviewElement,\n element: DraftPreviewElement,\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 = `${this.toCssNumber(rect.left)}px`;\n clone.style.top = `${this.toCssNumber(rect.top)}px`;\n clone.style.right = 'auto';\n clone.style.bottom = 'auto';\n clone.style.width = `${this.toCssNumber(rect.width)}px`;\n clone.style.height = `${this.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 = this.getDraftPreviewDisplay(computedStyle.display);\n // One below the 32-bit max (2147483647): the preview clone floats above the\n // page but stays under the overlay chrome, which uses the true maximum.\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\n private getDraftPreviewDisplay(display: string) {\n if (display === 'inline' || display === 'contents') return 'inline-block';\n return display || 'block';\n }\n\n private copyComputedStyle(\n element: DraftPreviewElement,\n clone: DraftPreviewElement,\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\n private removeDuplicateIds(element: Element) {\n element.removeAttribute('id');\n element.querySelectorAll('[id]').forEach((child) => {\n child.removeAttribute('id');\n });\n }\n\n private toCssNumber(value: number) {\n return Math.round(value * 1000) / 1000;\n }\n\n private createHeader() {\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(this.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', () => this.config.actions.close());\n\n header.append(titleGroup, close);\n return header;\n }\n\n private createToolbar() {\n const toolbar = document.createElement('div');\n toolbar.className = 'dfwr-toolbar';\n\n toolbar.append(\n this.createToolbarButton('Note', this.state.mode === 'note', () => {\n const mode = this.state.mode;\n this.config.actions.setModeState(mode === 'note' ? 'idle' : 'note');\n this.config.actions.clearDrafts();\n this.config.actions.render();\n }),\n this.createToolbarButton('Element', this.state.mode === 'element', () => {\n const mode = this.state.mode;\n this.config.actions.setModeState(\n mode === 'element' ? 'idle' : 'element'\n );\n this.config.actions.clearDrafts();\n this.config.actions.render();\n }),\n this.createToolbarButton(\n this.state.isSelectingArea ? 'Selecting' : 'Area',\n this.state.mode === 'area',\n () => {\n const mode = this.state.mode;\n this.config.actions.setModeState(mode === 'area' ? 'idle' : 'area');\n this.config.actions.clearDrafts();\n this.config.actions.render();\n }\n ),\n this.createToolbarButton('Refresh', false, () => {\n void this.config.actions.reload();\n })\n );\n\n return toolbar;\n }\n\n private 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\n private createBody() {\n const body = document.createElement('div');\n body.className = 'dfwr-body';\n const state = this.state;\n\n if (state.mode === 'idle') {\n const empty = document.createElement('p');\n empty.className = 'dfwr-empty';\n empty.textContent = 'Add a note or mark an area.';\n body.append(empty);\n return body;\n }\n\n if (state.mode === 'note' || state.mode === 'element') {\n body.append(this.createNoteBody());\n return body;\n }\n\n body.append(this.createAreaForm());\n return body;\n }\n\n private createNoteBody() {\n const empty = document.createElement('p');\n empty.className = 'dfwr-empty';\n empty.textContent = this.state.noteDraft\n ? 'Write the note in the page box.'\n : this.state.mode === 'element'\n ? 'Click an element to add QA.'\n : 'Click on the page to place a note.';\n return empty;\n }\n\n // Builds the note draft layer: the on-page marker/highlight plus its composer\n // popover. When dockComposer is set the composer renders into the side panel\n // instead of floating next to the marker (used for the docked review mode).\n private createNotePopover(\n draft: NoteDraft,\n options: { dockComposer?: boolean } = {}\n ) {\n const environment = this.config.getEnvironment();\n const group = document.createElement('div');\n group.className = 'dfwr-note-draft';\n if (!environment) return { layer: group, composer: undefined };\n\n const isElementDraft =\n this.state.mode === 'element' && Boolean(draft.selection);\n const hostPoint = toHostPoint(\n isElementDraft\n ? this.getAdjustedDraftPoint(draft.marker.viewport, draft)\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 = this.createSelectionHighlight(\n isElementDraft\n ? this.getAdjustedDraftSelection(selection, draft)\n : selection,\n environment,\n true\n );\n group.append(selectionHighlight);\n }\n\n const pin = document.createElement('button');\n pin.className = 'dfwr-note-pin';\n pin.type = 'button';\n pin.setAttribute('aria-label', 'Move note 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-note-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 this.getAdjustedDraftSelection(\n toViewportSelection(draft.selection.viewport),\n draft\n ),\n environment\n )\n : undefined;\n const composer = this.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 const meta =\n isElementDraft ? undefined : document.createElement('div');\n if (meta) {\n meta.className = 'dfwr-item-date';\n meta.textContent = formatNoteDraftMeta(draft);\n }\n\n const titleInput = this.isTitleFieldEnabled()\n ? this.createDraftTitleInput(draft.title, (title) => {\n const noteDraft = this.state.noteDraft;\n if (!noteDraft) return;\n this.config.actions.setNoteDraft({\n ...noteDraft,\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 noteDraft = this.state.noteDraft;\n if (!noteDraft) return;\n this.config.actions.setNoteDraft({\n ...noteDraft,\n comment: textarea.value,\n });\n });\n\n const assigneeSelect = this.createDraftAssigneeSelect(\n draft.assigneeId,\n draft.assigneeName,\n (assigneeId, assigneeName) => {\n const noteDraft = this.state.noteDraft;\n if (!noteDraft) return;\n this.config.actions.setNoteDraft({\n ...noteDraft,\n assigneeId,\n assigneeName,\n });\n }\n );\n\n const saveDraft = () => {\n const currentDraft = this.state.noteDraft ?? draft;\n const fields = this.getDraftFields(titleInput, textarea, assigneeSelect);\n const comment = fields.comment;\n if (!comment && !this.hasDraftAdjustment(currentDraft)) return;\n void this.config.actions.createItem({\n kind: 'note',\n title: fields.title,\n comment: this.withDraftAdjustmentComment(comment, currentDraft),\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 });\n };\n\n const adjustmentControls =\n isElementDraft\n ? this.createAdjustmentControls({\n draft,\n pin,\n popover,\n selectionHighlight,\n textarea,\n dockToggle: options.dockComposer,\n })\n : undefined;\n\n const actions = this.createFormActions('Save note', saveDraft, {\n leading: adjustmentControls?.actionButton\n ? [adjustmentControls.actionButton]\n : undefined,\n });\n const error = this.createDraftError();\n\n form.append(\n ...(meta ? [meta] : []),\n ...(adjustmentControls ? [adjustmentControls.panel] : []),\n ...(titleInput ? [titleInput] : []),\n textarea,\n ...(assigneeSelect ? [assigneeSelect] : []),\n ...(error ? [error] : []),\n actions\n );\n const dragHandle =\n isElementDraft && !options.dockComposer\n ? this.createDraftDragHandle('Move DOM composer')\n : undefined;\n popover.append(\n ...(dragHandle ? [dragHandle] : []),\n form\n );\n group.append(pin);\n if (!options.dockComposer) {\n group.append(popover);\n }\n\n if (dragHandle) {\n this.attachDraftComposerDrag(popover, dragHandle, (composerPosition) => {\n const noteDraft = this.state.noteDraft ?? draft;\n this.config.actions.setNoteDraft({\n ...noteDraft,\n composerPosition,\n comment: textarea.value,\n });\n });\n }\n\n this.attachDraftPinDrag(\n pin,\n isElementDraft || options.dockComposer ? undefined : popover,\n meta,\n textarea\n );\n\n if (!options.dockComposer) {\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 private 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\n private 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 private setAdjustmentToggleIcon(button: HTMLButtonElement, isActive: boolean) {\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(this.createIcon(paths));\n }\n\n private attachDraftComposerDrag(\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 = this.config.getEnvironment();\n if (!environment) return;\n\n const position = this.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 this.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 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\n // Builds the element-adjustment controls (nudge the previewed element via\n // arrow keys / buttons). Wires keyboard deltas to the draft transform and\n // keeps the pin, popover, highlight and textarea in sync as the value changes.\n private createAdjustmentControls({\n draft,\n pin,\n popover,\n selectionHighlight,\n textarea,\n dockToggle,\n }: {\n draft: NoteDraft;\n pin: HTMLButtonElement;\n popover: HTMLDivElement;\n selectionHighlight?: HTMLDivElement;\n textarea: HTMLTextAreaElement;\n dockToggle?: boolean;\n }) {\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 = this.getAdjustmentLabel();\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: NoteDraft) => {\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 this.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] = this.getDraftAdjustmentMetricLines(nextDraft);\n xyStatus.textContent = xyLine;\n scaleStatus.textContent = scaleLine;\n this.syncDraftAdjustmentUi({\n draft: nextDraft,\n pin,\n selectionHighlight,\n });\n };\n\n const updateDraft = (updater: (current: NoteDraft) => NoteDraft) => {\n const currentDraft = this.state.noteDraft ?? draft;\n const nextDraft = updater(currentDraft);\n this.config.actions.setNoteDraft({\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 = this.state.noteDraft ?? draft;\n if (currentDraft.adjustment?.isActive !== true) return;\n\n const keyDelta = this.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 actionButton: dockToggle ? adjust : undefined,\n };\n }\n\n private 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 private syncDraftAdjustmentUi({\n draft,\n pin,\n selectionHighlight,\n }: {\n draft: NoteDraft;\n pin: HTMLButtonElement;\n selectionHighlight?: HTMLDivElement;\n }) {\n const environment = this.config.getEnvironment();\n if (!environment) return;\n\n const hostPoint = toHostPoint(\n this.getAdjustedDraftPoint(draft.marker.viewport, draft),\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 this.getAdjustedDraftSelection(\n toViewportSelection(draft.selection.viewport),\n draft\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 this.syncDraftPreview(draft);\n }\n\n private createAreaForm() {\n const form = document.createElement('form');\n form.className = 'dfwr-form';\n const areaDraft = this.state.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(this.createAreaMetricsPanel(areaDraft));\n\n const titleInput = this.isTitleFieldEnabled()\n ? this.createDraftTitleInput(areaDraft.title, (title) => {\n const draft = this.state.areaDraft;\n if (!draft) return;\n this.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 = this.state.areaDraft;\n if (!draft) return;\n this.config.actions.setAreaDraft({\n ...draft,\n comment: textarea.value,\n });\n });\n\n const assigneeSelect = this.createDraftAssigneeSelect(\n areaDraft.assigneeId,\n areaDraft.assigneeName,\n (assigneeId, assigneeName) => {\n const draft = this.state.areaDraft;\n if (!draft) return;\n this.config.actions.setAreaDraft({\n ...draft,\n assigneeId,\n assigneeName,\n });\n }\n );\n\n const actions = this.createFormActions('Save area', () => {\n const draft = this.state.areaDraft;\n const fields = this.getDraftFields(titleInput, textarea, assigneeSelect);\n const comment = fields.comment;\n if (!comment || !draft) return;\n void this.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 });\n });\n const error = this.createDraftError();\n\n form.append(\n ...(titleInput ? [titleInput] : []),\n textarea,\n ...(assigneeSelect ? [assigneeSelect] : []),\n ...(error ? [error] : []),\n actions\n );\n return form;\n }\n\n private createAreaMetricsPanel(draft: AreaDraft) {\n const panel = document.createElement('div');\n panel.className = 'dfwr-adjust-panel is-area-metrics-panel';\n\n const help = document.createElement('div');\n help.className = 'dfwr-adjust-help';\n const [labelLine, xyLine, sizeLine] = this.getSelectionMetricLines(\n this.getAreaDraftMetricSelection(draft),\n draft.viewport\n );\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 private createAreaDraftOverlay(draft: AreaDraft) {\n const layer = document.createElement('div');\n layer.className = 'dfwr-area-preview-layer';\n\n const environment = this.config.getEnvironment();\n if (!environment || !draft.selection) return layer;\n\n const selection = toViewportSelection(draft.selection.viewport);\n layer.append(this.createSelectionHighlight(selection, environment, true));\n\n if (draft.marker) {\n const hostPoint = toHostPoint(draft.marker.viewport, environment);\n layer.append(\n this.createMarkerElement(\n undefined,\n hostPoint,\n '•',\n getReviewViewportScope(\n draft.viewport,\n this.config.options.viewports?.presets\n ),\n true,\n true\n )\n );\n }\n\n return layer;\n }\n\n private createAreaDraftPopover(\n draft: AreaDraft,\n options: { dockComposer?: boolean } = {}\n ) {\n const environment = this.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 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 = this.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 : this.createDraftDragHandle('Move area composer');\n popover.append(\n ...(dragHandle ? [dragHandle] : []),\n this.createAreaForm()\n );\n if (dragHandle) {\n this.attachDraftComposerDrag(popover, dragHandle, (composerPosition) => {\n const areaDraft = this.state.areaDraft ?? draft;\n this.config.actions.setAreaDraft({\n ...areaDraft,\n composerPosition,\n });\n });\n }\n return popover;\n }\n\n private createFormActions(\n saveLabel: string,\n onSave: () => void,\n options?: {\n beforeSave?: HTMLButtonElement[];\n className?: string;\n leading?: HTMLElement[];\n }\n ) {\n const actions = document.createElement('div');\n actions.className = ['dfwr-actions', options?.className]\n .filter(Boolean)\n .join(' ');\n const isSaving = this.state.isCreatingItem;\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(this.createSpinner('dfwr-spinner'), 'Saving...');\n } else {\n save.textContent = saveLabel;\n }\n save.addEventListener('click', (event) => {\n event.preventDefault();\n event.stopPropagation();\n if (this.state.isCreatingItem) 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 this.cancelDraft(event);\n });\n\n if (options?.leading?.length) {\n actions.classList.add('has-leading');\n const leading = document.createElement('div');\n leading.className = 'dfwr-actions-leading';\n leading.append(...options.leading);\n const primary = document.createElement('div');\n primary.className = 'dfwr-actions-primary';\n primary.append(save, cancel);\n actions.append(leading, primary);\n return actions;\n }\n\n if (options?.beforeSave?.length || options?.className) {\n actions.append(cancel, ...(options.beforeSave ?? []), save);\n return actions;\n }\n\n actions.append(save, cancel);\n return actions;\n }\n\n private createSpinner(className: string) {\n const spinner = document.createElement('span');\n spinner.className = className;\n spinner.setAttribute('aria-hidden', 'true');\n return spinner;\n }\n\n private createDraftError() {\n if (!this.state.draftError) return undefined;\n\n const error = document.createElement('p');\n error.className = 'dfwr-form-error';\n error.setAttribute('role', 'alert');\n error.textContent = this.state.draftError;\n return error;\n }\n\n private createList() {\n const section = document.createElement('div');\n section.className = 'dfwr-list';\n const state = this.state;\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 const empty = document.createElement('p');\n empty.className = 'dfwr-empty';\n empty.textContent = 'No review items on this page.';\n section.append(empty);\n return section;\n }\n\n for (const numberedItem of getNumberedReviewItems(\n state.items,\n this.config.options.viewports?.presets\n )) {\n section.append(this.createListItem(numberedItem));\n }\n\n return section;\n }\n\n private createListItem(numberedItem: NumberedReviewItem) {\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 this.config.actions.restoreItem(item);\n });\n row.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n\n event.preventDefault();\n void this.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 = this.isTitleFieldEnabled() ? 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 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 this.config.actions\n .removeItem(item.id)\n .then(() => this.config.actions.reload());\n });\n\n actions.append(remove);\n row.append(body, actions);\n return row;\n }\n\n private createMarkerLayer() {\n const layer = document.createElement('div');\n layer.className = 'dfwr-marker-layer';\n const environment = this.config.getEnvironment();\n if (!environment) return layer;\n\n const currentScope = getReviewViewportScope(\n getViewportSize(environment),\n this.config.options.viewports?.presets\n );\n\n getNumberedReviewItems(\n this.state.items,\n this.config.options.viewports?.presets\n ).forEach((numberedItem) => {\n const { item, scope, displayLabel } = numberedItem;\n if (!shouldShowMarkerForScope(scope, currentScope)) {\n return;\n }\n\n const isHighlighted = item.id === this.state.highlightedItemId;\n const highlightMode = getReviewItemHighlightMode(item);\n if (\n highlightMode !== 'note' &&\n (!this.state.highlightedItemId || isHighlighted)\n ) {\n const selection = getItemHighlightSelection(item, environment);\n if (selection) {\n layer.append(\n ...this.createItemHighlightElements(\n selection.viewport,\n environment,\n item,\n displayLabel,\n selection.isBound,\n isHighlighted\n )\n );\n return;\n }\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 = this.createMarkerElement(\n item.id,\n hostPoint,\n displayLabel,\n scope,\n point.isBound,\n isHighlighted,\n highlightMode === 'note' ? 'note' : 'default'\n );\n marker.title = `${displayLabel} / ${item.comment}\\n${formatItemMeta(item)}`;\n layer.append(marker);\n });\n\n return layer;\n }\n\n private createItemHighlightElements(\n selection: ViewportSelection,\n environment: ReviewEnvironment,\n item: ReviewItem,\n label: string,\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 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 isHighlighted ? 'is-highlighted' : '',\n ]\n .filter(Boolean)\n .join(' ');\n labelElement.textContent = label;\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 private 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 private createMarkerElement(\n itemId: string | undefined,\n hostPoint: ReviewPoint,\n label: string,\n scope: ReviewItemScope,\n isBound: boolean,\n isHighlighted: boolean,\n variant: 'default' | 'note' = 'default'\n ) {\n const isNoteCallout = variant === 'note';\n const marker = document.createElement('div');\n marker.className = [\n 'dfwr-bound-marker',\n isNoteCallout ? 'is-note-callout' : '',\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 private attachDraftPinDrag(\n pin: HTMLButtonElement,\n popover: HTMLDivElement | undefined,\n meta: HTMLDivElement | undefined,\n textarea: HTMLTextAreaElement\n ) {\n let isDragging = false;\n\n const moveDraftUi = (hostPoint: ReviewPoint) => {\n const environment = this.config.getEnvironment();\n if (!environment) return;\n\n const nextPoint = clampPoint(toTargetPoint(hostPoint, environment), environment);\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 noteDraft = this.state.noteDraft;\n if (!noteDraft) return;\n\n const nextDraft = {\n ...noteDraft,\n marker: {\n ...noteDraft.marker,\n viewport: roundPoint(nextPoint),\n },\n comment: textarea.value,\n };\n this.config.actions.setNoteDraft(nextDraft);\n if (meta) {\n meta.textContent = formatNoteDraftMeta(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 this.config.getEnvironment()\n );\n const currentDraft = this.state.noteDraft;\n const fields = {\n title: currentDraft?.title,\n comment: textarea.value,\n assigneeId: currentDraft?.assigneeId,\n assigneeName: currentDraft?.assigneeName,\n };\n void (this.state.mode === 'element'\n ? this.config.actions.bindElementDraftToPoint(nextPoint, fields)\n : this.config.actions.bindNoteDraftToPoint(nextPoint, fields));\n });\n }\n\n private createNoteLayer() {\n const layer = document.createElement('div');\n layer.className = 'dfwr-text-layer';\n const environment = this.config.getEnvironment();\n\n if (environment) {\n placeLayerOverTarget(layer, environment);\n }\n\n layer.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return;\n event.preventDefault();\n void this.config.actions.bindNoteDraftToPoint(\n toTargetPointFromHostEvent(event, this.config.getEnvironment())\n );\n });\n\n return layer;\n }\n\n private createElementLayer() {\n const layer = document.createElement('div');\n layer.className = 'dfwr-element-layer';\n const environment = this.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 const nextEnvironment = this.config.getEnvironment();\n if (!nextEnvironment) return;\n\n const anchor = getDomAnchorFromPoint(\n clampPoint(point, nextEnvironment),\n this.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, this.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 this.config.actions.bindElementDraftToPoint(\n toTargetPointFromHostEvent(event, this.config.getEnvironment())\n );\n });\n\n return layer;\n }\n\n private createAreaLayer() {\n const layer = document.createElement('div');\n layer.className = 'dfwr-area-layer';\n const environment = this.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 const ownerWindow = layer.ownerDocument.defaultView ?? window;\n\n const updateBox = (event: PointerEvent) => {\n const nextEnvironment = this.config.getEnvironment();\n const nextPoint = toTargetPointFromHostEvent(\n event,\n nextEnvironment\n );\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 const hostPoint = toHostPoint(\n { x: left, y: top },\n nextEnvironment\n );\n\n selection = { left, top, width, height };\n box.style.left = `${hostPoint.x}px`;\n box.style.top = `${hostPoint.y}px`;\n box.style.width = `${width}px`;\n box.style.height = `${height}px`;\n };\n\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 if (!selection || selection.width < 8 || selection.height < 8) return;\n\n this.config.actions.setSelectingArea(true);\n this.config.actions.render();\n void this.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 this.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}\n","import { localAdapter } from '../adapters/local';\nimport type {\n DomAnchor,\n ReviewItem,\n ReviewMarker,\n ReviewMode,\n ReviewPoint,\n ReviewSelection,\n WebReviewKitAdapter,\n WebReviewKitController,\n WebReviewKitOptions,\n} from '../types';\nimport {\n cssEscape,\n getDomAnchor,\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 { createSelectionCenterMarker } from './review/item';\nimport type {\n AreaDraft,\n NoteDraft,\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\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 noteDraft?: NoteDraft;\n private areaDraft?: AreaDraft;\n private draftError = '';\n private isCreatingItem = 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 noteDraft: this.noteDraft,\n areaDraft: this.areaDraft,\n draftError: this.draftError,\n isCreatingItem: this.isCreatingItem,\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: () => {\n this.noteDraft = undefined;\n this.areaDraft = undefined;\n this.draftError = '';\n },\n setNoteDraft: (draft) => {\n this.noteDraft = 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 bindNoteDraftToPoint: (point, fields) =>\n this.bindNoteDraftToPoint(point, fields),\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 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.noteDraft = undefined;\n this.areaDraft = undefined;\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.noteDraft = undefined;\n this.areaDraft = undefined;\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.noteDraft = undefined;\n this.areaDraft = undefined;\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 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.noteDraft &&\n !this.areaDraft &&\n !this.isSelectingArea\n ) {\n return false;\n }\n\n this.setModeState('idle');\n this.noteDraft = undefined;\n this.areaDraft = undefined;\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.noteDraft && !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\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 overlayRect: {\n left: overlayRect.left,\n top: overlayRect.top,\n width: overlayRect.width,\n height: overlayRect.height,\n },\n composerHost,\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 bindNoteDraftToPoint(\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 selection = getPointSelection(nextPoint);\n const anchor = getDomAnchor(\n selection,\n this.options.anchors?.attribute,\n environment\n );\n const marker: ReviewMarker = {\n viewport: roundPoint(nextPoint),\n relative: anchor\n ? getRelativePoint(nextPoint, anchor, environment)\n : undefined,\n };\n\n return {\n viewport,\n anchor,\n marker,\n ...fields,\n };\n });\n\n this.noteDraft = draft;\n this.render();\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.noteDraft = 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.noteDraft = 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 marker = createSelectionCenterMarker(\n selection,\n undefined,\n environment\n );\n const reviewSelection: ReviewSelection = {\n viewport: toPublicSelection(selection),\n };\n\n return {\n viewport,\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 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 createdItem = await this.adapter.create(item);\n this.setModeState('idle');\n this.noteDraft = undefined;\n this.areaDraft = undefined;\n this.highlightItem(createdItem.id);\n await this.reload();\n await this.options.onCreateItem?.(createdItem);\n } catch (error) {\n this.draftError =\n error instanceof Error ? error.message : 'Failed to save QA.';\n } finally {\n this.isCreatingItem = false;\n this.render();\n }\n }\n\n private async restoreItem(item: ReviewItem) {\n this.setModeState('idle');\n this.noteDraft = undefined;\n this.areaDraft = undefined;\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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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0jC5B,SAAO;AACT;;;ACvjCO,SAAS,oBAAoB,OAAkB;AACpD,QAAM,QAAQ;AAAA,IACZ,YAAY,WAAW,MAAM,QAAQ,CAAC;AAAA,IACtC,SAAS,YAAY,MAAM,OAAO,QAAQ,CAAC;AAAA,EAC7C;AAEA,MAAI,MAAM,QAAQ;AAChB,UAAM,KAAK,iBAAiB,MAAM,MAAM,CAAC;AAAA,EAC3C;AAEA,SAAO,MAAM,KAAK,KAAK;AACzB;AAGO,SAAS,eAAe,MAAkB;AAC/C,QAAM,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC;AACzC,QAAM,SAAS,cAAc,IAAI;AACjC,QAAM,YAAY,iBAAiB,IAAI;AAEvC,MAAI,KAAK,UAAU;AACjB,UAAM,KAAK,YAAY,WAAW,KAAK,QAAQ,CAAC,EAAE;AAAA,EACpD;AAEA,MAAI,QAAQ;AACV,UAAM,KAAK,SAAS,YAAY,OAAO,QAAQ,CAAC,EAAE;AAAA,EACpD;AAEA,MAAI,WAAW;AACb,UAAM,KAAK,QAAQ,gBAAgB,UAAU,QAAQ,CAAC,EAAE;AAAA,EAC1D;AAEA,MAAI,KAAK,QAAQ;AACf,UAAM,KAAK,iBAAiB,KAAK,MAAM,CAAC;AAAA,EAC1C;AAEA,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,WAAW,OAAe;AACjC,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AAEzC,SAAO,KAAK,eAAe,QAAW;AAAA,IACpC,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,SAAS,WAAW,MAAoB;AACtC,SAAO,GAAG,KAAK,MAAM,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC;AAC7D;AAEA,SAAS,YAAY,OAAoB;AACvC,SAAO,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC,CAAC;AACtD;AAEA,SAAS,gBAAgB,WAA8B;AACrD,SAAO;AAAA,IACL,KAAK,MAAM,UAAU,CAAC;AAAA,IACtB,KAAK,MAAM,UAAU,CAAC;AAAA,IACtB,KAAK,MAAM,UAAU,KAAK;AAAA,IAC1B,KAAK,MAAM,UAAU,MAAM;AAAA,EAC7B,EAAE,KAAK,GAAG;AACZ;AAEA,SAAS,iBAAiB,QAAmB;AAC3C,QAAM,QAAQ,CAAC,OAAO,OAAO,QAAQ,EAAE;AAEvC,MAAI,OAAO,OAAO,eAAe,UAAU;AACzC,UAAM,KAAK,GAAG,KAAK,MAAM,OAAO,aAAa,GAAG,CAAC,GAAG;AAAA,EACtD;AAEA,QAAM,aAAa,oBAAoB,MAAM;AAC7C,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,KAAK,GAAG,WAAW,MAAM,aAAa;AAAA,EAC9C;AAEA,SAAO,MAAM,KAAK,GAAG;AACvB;;;AC1BA,IAAM,2BAA2B;AAqD1B,IAAM,mBAAN,MAAuB;AAAA,EAI5B,YAA6B,QAAgC;AAAhC;AAAA,EAAiC;AAAA,EAE9D,oBAAoB;AAClB,SAAK,oBAAoB;AACzB,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,OAAO,QAAoB,kBAAoC;AAC7D,UAAM,QAAQ,KAAK;AACnB,SAAK;AAAA,MACH,MAAM,UAAU,MAAM,SAAS,YAAY,MAAM,YAAY;AAAA,IAC/D;AAEA,WAAO,gBAAgB;AACvB,WAAO,OAAO,mBAAmB,CAAC;AAClC,WAAO,OAAO,gBAAgB;AAE9B,UAAM,sBAAsB,QAAQ,MAAM,aAAa,MAAM,SAAS;AACtE,UAAM,qBACJ,KAAK,OAAO,QAAQ,IAAI,UAAU,SAClC,uBACA,QAAQ,KAAK,qBAAqB,CAAC;AACrC,QAAI;AACJ,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,MAAM,SAAS,YAAY;AAAA,MAC3B,uBAAuB,CAAC,qBAAqB,0BAA0B;AAAA,IACzE,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,UAAM,aAAa,eAAe,MAAM,SAAS,UAAU,MAAM;AAEjE,QAAI,KAAK,OAAO,QAAQ,IAAI,UAAU,OAAO;AAE3C,YAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,YAAM,YAAY;AAClB,YAAM,aAAa,QAAQ,QAAQ;AACnC,YAAM,aAAa,cAAc,gBAAgB;AAEjD,YAAM;AAAA,QACJ,KAAK,aAAa;AAAA,QAClB,KAAK,cAAc;AAAA,QACnB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,MAClB;AAEA,YAAM,OAAO,KAAK;AAAA,IACpB;AAEA,UAAM,OAAO,KAAK,kBAAkB,CAAC;AACrC,QAAI,MAAM,UAAU,uBAAuB,CAAC,oBAAoB;AAC9D,YAAM,OAAO,KAAK,uBAAuB,CAAC;AAAA,IAC5C;AAEA,QAAI,MAAM,WAAW,MAAM,SAAS,UAAU,MAAM,SAAS,YAAY;AACvE,UAAI,MAAM,WAAW;AACnB,cAAM,YAAY,KAAK,kBAAkB,MAAM,WAAW;AAAA,UACxD,cAAc;AAAA,QAChB,CAAC;AACD,cAAM,OAAO,UAAU,KAAK;AAC5B,yBAAiB,UAAU;AAAA,MAC7B,OAAO;AACL,cAAM;AAAA,UACJ,MAAM,SAAS,YACX,KAAK,mBAAmB,IACxB,KAAK,gBAAgB;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,QACE,MAAM,UACN,MAAM,SAAS,UACf,CAAC,MAAM,aACP,CAAC,MAAM,iBACP;AACA,YAAM,OAAO,KAAK,gBAAgB,CAAC;AAAA,IACrC;AAEA,QACE,MAAM,UACN,MAAM,SAAS,UACf,MAAM,aACN,KAAK,OAAO,QAAQ,IAAI,UAAU,OAClC;AAEA,UAAI,MAAM,UAAU,WAAW;AAC7B,cAAM,OAAO,KAAK,uBAAuB,MAAM,SAAS,CAAC;AAAA,MAC3D;AACA,YAAM,eAAe,KAAK,uBAAuB,MAAM,WAAW;AAAA,QAChE,cAAc;AAAA,MAChB,CAAC;AACD,UAAI,oBAAoB;AACtB,yBAAiB;AAAA,MACnB,OAAO;AACL,cAAM,OAAO,YAAY;AAAA,MAC3B;AAAA,IACF;AAEA,WAAO,OAAO,KAAK;AACnB,SAAK,oBAAoB,cAAc;AAAA,EACzC;AAAA,EAEA,IAAY,QAAQ;AAClB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEQ,uBAAuB;AAC7B,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,QAAI,KAAK,OAAO,QAAQ,IAAI,UAAU,MAAO,QAAO;AACpD,WAAO,aAAa,gBAAgB;AAAA,EACtC;AAAA,EAEQ,oBAAoB,UAAwB;AAClD,UAAM,OAAO,WAAW,KAAK,qBAAqB,IAAI;AACtD,QAAI,CAAC,QAAQ,CAAC,UAAU;AACtB,WAAK,mBAAmB;AACxB;AAAA,IACF;AAEA,QAAI,KAAK,qBAAqB,KAAK,sBAAsB,MAAM;AAC7D,WAAK,mBAAmB;AAAA,IAC1B;AAEA,SAAK,oBAAoB;AACzB,SAAK,QAAQ,mBAAmB;AAChC,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc,QAAQ,mBAAmB;AAAA,IAChD;AAEA,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,OAAO,QAAQ;AAErB,SAAK,gBAAgB,mBAAmB,GAAG,KAAK;AAAA,EAClD;AAAA,EAEQ,qBAAqB;AAC3B,UAAM,OAAO,KAAK;AAClB,UAAM,gBAAgB;AACtB,QAAI,MAAM;AACR,aAAO,KAAK,QAAQ;AACpB,aAAO,KAAK,eAAe,QAAQ;AAAA,IACrC;AACA,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEQ,yBAAyB;AAC/B,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,aAAa,eAAe,MAAM;AAExC,UAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,UAAI,MAAM,WAAW,EAAG;AACxB,WAAK,YAAY,KAAK;AAAA,IACxB,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,OAAe;AACjC,WAAO,eAAe;AACtB,WAAO,gBAAgB;AACvB,WAAO,yBAAyB;AAChC,SAAK,OAAO,QAAQ,aAAa,MAAM;AACvC,SAAK,OAAO,QAAQ,YAAY;AAChC,SAAK,OAAO,QAAQ,iBAAiB,KAAK;AAC1C,SAAK,OAAO,QAAQ,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA,EAIA,IAAY,kBAAkB;AAC5B,WAAO,KAAK,OAAO,QAAQ,WAAW;AAAA,EACxC;AAAA,EAEQ,0BAA0B,OAAkB;AAClD,WAAoB,0BAA0B,OAAO,KAAK,eAAe;AAAA,EAC3E;AAAA,EAEQ,mBAAmB,OAAkB;AAC3C,WAAoB,mBAAmB,OAAO,KAAK,eAAe;AAAA,EACpE;AAAA,EAEQ,sBAAsB,OAAoB,OAAkB;AAClE,WAAoB,sBAAsB,OAAO,OAAO,KAAK,eAAe;AAAA,EAC9E;AAAA,EAEQ,0BACN,WACA,OACA;AACA,WAAoB;AAAA,MAClB;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,sBAAsB,UAAwB;AACpD,WAAoB,sBAAsB,UAAU,KAAK,eAAe;AAAA,EAC1E;AAAA,EAEQ,sBAAsB,aAAgC;AAC5D,UAAM,SAAS,YAAY;AAC3B,UAAM,SAAS;AACf,WAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,QAAQ,SAAS,CAAC,CAAC;AAAA,EAC/D;AAAA,EAEQ,2BACN,UACA,aACA,MACA,SAAS,YAAY,aACrB;AACA,UAAM,SAAS;AACf,UAAM,QAAQ,MAAM,SAAS,KAAK,sBAAsB,WAAW;AACnE,UAAM,SAAS,MAAM,UAAU;AAE/B,WAAO;AAAA,MACL,GAAG;AAAA,QACD,SAAS;AAAA,QACT,OAAO,OAAO;AAAA,QACd,OAAO,OAAO,OAAO,QAAQ,QAAQ;AAAA,MACvC;AAAA,MACA,GAAG;AAAA,QACD,SAAS;AAAA,QACT,OAAO,MAAM;AAAA,QACb,OAAO,MAAM,OAAO,SAAS,SAAS;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,wBAAwB;AAC9B,UAAM,OAAO,SAAS;AACtB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK;AAAA,MACL,OAAO,KAAK,eAAe,OAAO;AAAA,MAClC,QAAQ,KAAK,gBAAgB,OAAO;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,gCACN,WACA,aACA,MACA;AACA,UAAM,SAAS,KAAK,sBAAsB;AAC1C,UAAM,SAAS;AACf,UAAM,MAAM;AAEZ,QAAI,CAAC,WAAW;AACd,aAAO,KAAK;AAAA,QACV;AAAA,UACE,GAAG,YAAY,YAAY,OAAO;AAAA,UAClC,GAAG,YAAY,YAAY,MAAM;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,UAAU,OAAO,UAAU,QAAQ;AACtD,UAAM,OAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,QAAQ;AACvD,UAAM,IACJ,cAAc,OACV,aACA,UAAU,OAAO,KAAK,QAAQ;AAEpC,WAAO,KAAK;AAAA,MACV;AAAA,QACE;AAAA,QACA,GAAG,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,yBAAyB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAKG;AACD,UAAM,QAAQ,KAAK,sBAAsB,WAAW;AAEpD,QAAI,kBAAkB;AACpB,YAAM,UAAU,KAAK;AAAA,QACnB;AAAA,QACA;AAAA,QACA,EAAE,OAAO,QAAQ,gBAAgB;AAAA,QACjC,KAAK,sBAAsB;AAAA,MAC7B;AACA,aAAO,EAAE,OAAO,MAAM,QAAQ,GAAG,KAAK,QAAQ,EAAE;AAAA,IAClD;AAEA,UAAM,WAAW,KAAK,gCAAgC,WAAW,aAAa;AAAA,MAC5E;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,OAAO,MAAM,SAAS,GAAG,KAAK,SAAS,EAAE;AAAA,EACpD;AAAA,EAEQ,sBACN,WACA,UACA;AACA,UAAM,EAAE,MAAM,IAAI,KAAK,sBAAsB,QAAQ;AACrD,UAAM,QAAQ,QAAQ,IAAI,IAAI,QAAQ;AAEtC,WAAO;AAAA,MACL,GAAG,UAAU,OAAO;AAAA,MACpB,GAAG,UAAU,MAAM;AAAA,MACnB,OAAO,UAAU,QAAQ;AAAA,MACzB,QAAQ,UAAU,SAAS;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,eAAe,OAAe;AACpC,QAAI,UAAU,EAAG,QAAO;AACxB,WAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,GAAG,KAAK;AAAA,EACxC;AAAA,EAEQ,gBAAgB,OAAe;AACrC,WAAO,GAAG,KAAK,MAAM,KAAK,CAAC;AAAA,EAC7B;AAAA,EAEQ,qBAAqB;AAC3B,WACE,KAAK,OAAO,QAAQ,iBAAiB,KAAK,KAAK;AAAA,EAEnD;AAAA,EAEQ,wBACN,WACA,UACA;AACA,QAAI,CAAC,UAAW,QAAO,CAAC,QAAQ,mBAAmB,iBAAiB;AAEpE,UAAM,UAAU,KAAK,sBAAsB,WAAW,QAAQ;AAC9D,WAAO;AAAA,MACL;AAAA,MACA,KAAK,KAAK,gBAAgB,QAAQ,CAAC,CAAC,QAAQ,KAAK;AAAA,QAC/C,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,KAAK,KAAK,gBAAgB,QAAQ,KAAK,CAAC,QAAQ,KAAK;AAAA,QACnD,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,4BAA4B,OAAkB;AACpD,QAAI,CAAC,MAAM,UAAW,QAAO;AAE7B,WAAO,oBAAoB,MAAM,UAAU,QAAQ;AAAA,EACrD;AAAA,EAEQ,8BAA8B,OAAkB;AACtD,UAAM,UAAU,KAAK,0BAA0B,KAAK;AACpD,WAAO;AAAA,MACL,KAAK,KAAK,eAAe,QAAQ,CAAC,CAAC,QAAQ,KAAK;AAAA,QAC9C,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,SAAS,KAAK,eAAe,QAAQ,KAAK,CAAC;AAAA,IAC7C;AAAA,EACF;AAAA,EAEQ,2BAA2B,SAAiB,OAAkB;AACpE,QAAI,CAAC,KAAK,mBAAmB,KAAK,EAAG,QAAO;AAE5C,UAAM,iBAAiB,QAAQ,KAAK;AACpC,UAAM,UAAU,KAAK,0BAA0B,KAAK;AACpD,UAAM,aAAa;AAAA,MACjB,GAAG,KAAK,mBAAmB,CAAC,OAAO,KAAK;AAAA,QACtC,QAAQ;AAAA,MACV,CAAC,OAAO,KAAK,eAAe,QAAQ,CAAC,CAAC,WAAW,KAAK;AAAA,QACpD,QAAQ;AAAA,MACV,CAAC;AAAA,MACD,IAAI,QAAQ,WAAW,cAAc,KAAK;AAAA,QACxC,QAAQ;AAAA,MACV,CAAC,WAAW,KAAK,MAAM,QAAQ,WAAW,CAAC;AAAA,IAC7C,EAAE,KAAK,GAAG;AAEV,WAAO,iBAAiB,GAAG,cAAc;AAAA,EAAK,UAAU,KAAK;AAAA,EAC/D;AAAA,EAEQ,kBAAkB,YAAuC;AAC/D,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,KAAK,OAAO,QAAQ,iBAAiB;AAAA,MAC1C,CAAC,WAAW,OAAO,UAAU;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,gBAAgB,YAAuC;AAC7D,WAAO,KAAK,kBAAkB,UAAU,GAAG;AAAA,EAC7C;AAAA,EAEQ,sBACN,OACA,SACA;AACA,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,YAAY;AAClB,UAAM,cAAc;AACpB,UAAM,OAAO;AACb,UAAM,QAAQ,SAAS;AACvB,UAAM,iBAAiB,SAAS,MAAM,QAAQ,MAAM,KAAK,CAAC;AAC1D,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB;AAC5B,WAAO,KAAK,OAAO,QAAQ,QAAQ,UAAU;AAAA,EAC/C;AAAA,EAEQ,0BACN,OACA,eACA,UACA;AACA,UAAM,kBAAkB,KAAK,OAAO,QAAQ,mBAAmB,CAAC;AAChE,QAAI,gBAAgB,WAAW,EAAG,QAAO;AACzC,UAAM,gBACJ,KAAK,OAAO,QAAQ,eAAe,KAAK,KAAK;AAE/C,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY;AAEnB,UAAM,cAAc,SAAS,cAAc,QAAQ;AACnD,gBAAY,QAAQ;AACpB,gBAAY,cAAc;AAC1B,WAAO,OAAO,WAAW;AAEzB,UAAM,qBACJ,QAAQ,KAAK,KACb,CAAC,gBAAgB,KAAK,CAAC,WAAW,OAAO,UAAU,KAAK;AAC1D,QAAI,sBAAsB,OAAO;AAC/B,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,QAAQ;AACf,aAAO,cAAc,iBAAiB;AACtC,aAAO,OAAO,MAAM;AAAA,IACtB;AAEA,oBAAgB,QAAQ,CAAC,mBAAmB;AAC1C,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,QAAQ,eAAe;AAC9B,aAAO,cAAc,eAAe;AACpC,aAAO,OAAO,MAAM;AAAA,IACtB,CAAC;AAED,WAAO,QAAQ,SAAS;AACxB,WAAO,iBAAiB,UAAU,MAAM;AACtC,eAAS,OAAO,SAAS,MAAM,KAAK,gBAAgB,OAAO,KAAK,CAAC;AAAA,IACnE,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,eACN,YACA,UACA,gBACA;AACA,UAAM,QAAQ,YAAY,MAAM,KAAK;AACrC,UAAM,UAAU,SAAS,MAAM,KAAK;AACpC,UAAM,aAAa,gBAAgB,MAAM,KAAK,KAAK;AACnD,WAAO;AAAA,MACL,OAAO,SAAS;AAAA,MAChB;AAAA,MACA;AAAA,MACA,cAAc,KAAK,gBAAgB,UAAU;AAAA,IAC/C;AAAA,EACF;AAAA,EAEQ,yBACN,OACA,aACiC;AACjC,QACE,MAAM,kBACN,MAAM,eAAe,kBAAkB,YAAY,YACnD,WAAW,MAAM,gBACjB;AACA,aAAO,MAAM;AAAA,IACf;AAEA,QAAI,CAAC,MAAM,OAAQ,QAAO;AAE1B,UAAM,qBAAqB,MAAM,YAC7B,oBAAoB,MAAM,UAAU,QAAQ,IAC5C;AACJ,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,GAAG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,QAAI,WAAW,QAAS,QAAO;AAE/B,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,OAAmB;AAC1C,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,QAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,mBAAmB,KAAK,GAAG;AAC7D,WAAK,oBAAoB;AACzB;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,yBAAyB,OAAO,WAAW;AAChE,QAAI,CAAC,SAAS;AACZ,WAAK,oBAAoB;AACzB;AAAA,IACF;AAEA,QAAI,KAAK,cAAc,YAAY,SAAS;AAC1C,WAAK,oBAAoB;AAAA,IAC3B;AAEA,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,gBAAgB,YAAY,OAAO,iBAAiB,OAAO;AACjE,YAAM,QAAQ,QAAQ,UAAU,IAAI;AACpC,WAAK,mBAAmB,KAAK;AAC7B,WAAK,kBAAkB,SAAS,OAAO,WAAW;AAClD,WAAK,0BAA0B,OAAO,SAAS,aAAa;AAC5D,kBAAY,SAAS,MAAM,YAAY,KAAK;AAC5C,WAAK,eAAe;AAAA,QAClB;AAAA,QACA;AAAA,QACA,YAAY,QAAQ,MAAM;AAAA,MAC5B;AACA,cAAQ,MAAM,aAAa;AAAA,IAC7B;AAEA,UAAM,UAAU,KAAK,0BAA0B,KAAK;AACpD,UAAM,YAAY,aAAa,KAAK,YAAY,QAAQ,IAAI,CAAC,OAAO,KAAK;AAAA,MACvE,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,QACJ,QAAQ,gBAAgB,IACpB,KACA,SAAS,KAAK,YAAY,QAAQ,WAAW,CAAC;AACpD,SAAK,aAAa,MAAM,MAAM,YAAY,CAAC,WAAW,KAAK,EACxD,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,EACb;AAAA,EAEQ,sBAAsB;AAC5B,QAAI,CAAC,KAAK,aAAc;AAExB,UAAM,EAAE,SAAS,OAAO,WAAW,IAAI,KAAK;AAC5C,UAAM,OAAO;AACb,YAAQ,MAAM,aAAa;AAC3B,SAAK,eAAe;AAAA,EACtB;AAAA,EAEQ,0BACN,OACA,SACA,eACA;AACA,UAAM,OAAO,QAAQ,sBAAsB;AAC3C,UAAM,aAAa,4BAA4B,MAAM;AACrD,UAAM,aAAa,eAAe,MAAM;AACxC,UAAM,MAAM,WAAW;AACvB,UAAM,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,IAAI,CAAC;AACjD,UAAM,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,GAAG,CAAC;AAC/C,UAAM,MAAM,QAAQ;AACpB,UAAM,MAAM,SAAS;AACrB,UAAM,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,KAAK,CAAC;AACnD,UAAM,MAAM,SAAS,GAAG,KAAK,YAAY,KAAK,MAAM,CAAC;AACrD,UAAM,MAAM,WAAW;AACvB,UAAM,MAAM,YAAY;AACxB,UAAM,MAAM,SAAS;AACrB,UAAM,MAAM,YAAY;AACxB,UAAM,MAAM,UAAU,KAAK,uBAAuB,cAAc,OAAO;AAGvE,UAAM,MAAM,SAAS;AACrB,UAAM,MAAM,gBAAgB;AAC5B,UAAM,MAAM,aAAa;AACzB,UAAM,MAAM,aAAa;AACzB,UAAM,MAAM,kBAAkB;AAC9B,UAAM,MAAM,YAAY;AAAA,EAC1B;AAAA,EAEQ,uBAAuB,SAAiB;AAC9C,QAAI,YAAY,YAAY,YAAY,WAAY,QAAO;AAC3D,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,kBACN,SACA,OACA,aACA;AACA,UAAM,gBAAgB,YAAY,OAAO,iBAAiB,OAAO;AACjE,aAAS,QAAQ,GAAG,QAAQ,cAAc,QAAQ,SAAS,GAAG;AAC5D,YAAM,WAAW,cAAc,KAAK,KAAK;AACzC,YAAM,MAAM;AAAA,QACV;AAAA,QACA,cAAc,iBAAiB,QAAQ;AAAA,QACvC,cAAc,oBAAoB,QAAQ;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,mBAAmB,SAAkB;AAC3C,YAAQ,gBAAgB,IAAI;AAC5B,YAAQ,iBAAiB,MAAM,EAAE,QAAQ,CAAC,UAAU;AAClD,YAAM,gBAAgB,IAAI;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA,EAEQ,YAAY,OAAe;AACjC,WAAO,KAAK,MAAM,QAAQ,GAAI,IAAI;AAAA,EACpC;AAAA,EAEQ,eAAe;AACrB,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,YAAY;AAEnB,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,cAAc;AAEpB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,SAAK,cAAc,YAAY,KAAK,OAAO,eAAe,CAAC;AAE3D,UAAM,aAAa,SAAS,cAAc,KAAK;AAC/C,eAAW,OAAO,OAAO,IAAI;AAE7B,UAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,UAAM,YAAY;AAClB,UAAM,OAAO;AACb,UAAM,cAAc;AACpB,UAAM,aAAa,cAAc,OAAO;AACxC,UAAM,iBAAiB,SAAS,MAAM,KAAK,OAAO,QAAQ,MAAM,CAAC;AAEjE,WAAO,OAAO,YAAY,KAAK;AAC/B,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB;AACtB,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AAEpB,YAAQ;AAAA,MACN,KAAK,oBAAoB,QAAQ,KAAK,MAAM,SAAS,QAAQ,MAAM;AACjE,cAAM,OAAO,KAAK,MAAM;AACxB,aAAK,OAAO,QAAQ,aAAa,SAAS,SAAS,SAAS,MAAM;AAClE,aAAK,OAAO,QAAQ,YAAY;AAChC,aAAK,OAAO,QAAQ,OAAO;AAAA,MAC7B,CAAC;AAAA,MACD,KAAK,oBAAoB,WAAW,KAAK,MAAM,SAAS,WAAW,MAAM;AACvE,cAAM,OAAO,KAAK,MAAM;AACxB,aAAK,OAAO,QAAQ;AAAA,UAClB,SAAS,YAAY,SAAS;AAAA,QAChC;AACA,aAAK,OAAO,QAAQ,YAAY;AAChC,aAAK,OAAO,QAAQ,OAAO;AAAA,MAC7B,CAAC;AAAA,MACD,KAAK;AAAA,QACH,KAAK,MAAM,kBAAkB,cAAc;AAAA,QAC3C,KAAK,MAAM,SAAS;AAAA,QACpB,MAAM;AACJ,gBAAM,OAAO,KAAK,MAAM;AACxB,eAAK,OAAO,QAAQ,aAAa,SAAS,SAAS,SAAS,MAAM;AAClE,eAAK,OAAO,QAAQ,YAAY;AAChC,eAAK,OAAO,QAAQ,OAAO;AAAA,QAC7B;AAAA,MACF;AAAA,MACA,KAAK,oBAAoB,WAAW,OAAO,MAAM;AAC/C,aAAK,KAAK,OAAO,QAAQ,OAAO;AAAA,MAClC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,oBACN,OACA,QACA,SACA;AACA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY,cAAc,SAAS,eAAe,EAAE;AAC3D,WAAO,OAAO;AACd,WAAO,cAAc;AACrB,WAAO,iBAAiB,SAAS,OAAO;AACxC,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa;AACnB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,UAAM,QAAQ,KAAK;AAEnB,QAAI,MAAM,SAAS,QAAQ;AACzB,YAAM,QAAQ,SAAS,cAAc,GAAG;AACxC,YAAM,YAAY;AAClB,YAAM,cAAc;AACpB,WAAK,OAAO,KAAK;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,SAAS,UAAU,MAAM,SAAS,WAAW;AACrD,WAAK,OAAO,KAAK,eAAe,CAAC;AACjC,aAAO;AAAA,IACT;AAEA,SAAK,OAAO,KAAK,eAAe,CAAC;AACjC,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB;AACvB,UAAM,QAAQ,SAAS,cAAc,GAAG;AACxC,UAAM,YAAY;AAClB,UAAM,cAAc,KAAK,MAAM,YAC3B,oCACA,KAAK,MAAM,SAAS,YAClB,gCACA;AACN,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,kBACN,OACA,UAAsC,CAAC,GACvC;AACA,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,QAAI,CAAC,YAAa,QAAO,EAAE,OAAO,OAAO,UAAU,OAAU;AAE7D,UAAM,iBACJ,KAAK,MAAM,SAAS,aAAa,QAAQ,MAAM,SAAS;AAC1D,UAAM,YAAY;AAAA,MAChB,iBACI,KAAK,sBAAsB,MAAM,OAAO,UAAU,KAAK,IACvD,MAAM,OAAO;AAAA,MACjB;AAAA,IACF;AACA,QAAI;AAEJ,QAAI,MAAM,WAAW;AACnB,YAAM,YAAY,oBAAoB,MAAM,UAAU,QAAQ;AAC9D,2BAAqB,KAAK;AAAA,QACxB,iBACI,KAAK,0BAA0B,WAAW,KAAK,IAC/C;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AACA,YAAM,OAAO,kBAAkB;AAAA,IACjC;AAEA,UAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,QAAI,YAAY;AAChB,QAAI,OAAO;AACX,QAAI,aAAa,cAAc,iBAAiB;AAChD,QAAI,MAAM,OAAO,GAAG,UAAU,CAAC;AAC/B,QAAI,MAAM,MAAM,GAAG,UAAU,CAAC;AAE9B,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAM,WAAW,mBAAmB,WAAW,WAAW;AAE1D,YAAQ,YAAY;AAAA,MAClB;AAAA,MACA,iBAAiB,gBAAgB;AAAA,MACjC,QAAQ,eAAe,uBAAuB;AAAA,IAChD,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,QAAI,QAAQ,cAAc;AACxB,cAAQ,MAAM,QAAQ;AAAA,IACxB,WAAW,gBAAgB;AACzB,YAAM,YAAY,MAAM,YACpB;AAAA,QACE,KAAK;AAAA,UACH,oBAAoB,MAAM,UAAU,QAAQ;AAAA,UAC5C;AAAA,QACF;AAAA,QACA;AAAA,MACF,IACA;AACJ,YAAM,WAAW,KAAK,yBAAyB;AAAA,QAC7C;AAAA,QACA;AAAA,QACA,kBAAkB,MAAM;AAAA,QACxB,iBAAiB;AAAA,MACnB,CAAC;AACD,cAAQ,MAAM,OAAO,GAAG,SAAS,IAAI;AACrC,cAAQ,MAAM,MAAM,GAAG,SAAS,GAAG;AACnC,cAAQ,MAAM,QAAQ,GAAG,SAAS,KAAK;AAAA,IACzC,OAAO;AACL,cAAQ,MAAM,OAAO,GAAG,SAAS,IAAI;AACrC,cAAQ,MAAM,MAAM,GAAG,SAAS,GAAG;AAAA,IACrC;AAEA,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AAEjB,UAAM,OACJ,iBAAiB,SAAY,SAAS,cAAc,KAAK;AAC3D,QAAI,MAAM;AACR,WAAK,YAAY;AACjB,WAAK,cAAc,oBAAoB,KAAK;AAAA,IAC9C;AAEA,UAAM,aAAa,KAAK,oBAAoB,IACxC,KAAK,sBAAsB,MAAM,OAAO,CAAC,UAAU;AACjD,YAAM,YAAY,KAAK,MAAM;AAC7B,UAAI,CAAC,UAAW;AAChB,WAAK,OAAO,QAAQ,aAAa;AAAA,QAC/B,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC,IACD;AAEJ,UAAM,WAAW,SAAS,cAAc,UAAU;AAClD,aAAS,YAAY;AACrB,aAAS,cAAc;AACvB,aAAS,OAAO;AAChB,aAAS,QAAQ,MAAM,WAAW;AAClC,aAAS,iBAAiB,SAAS,MAAM;AACvC,YAAM,YAAY,KAAK,MAAM;AAC7B,UAAI,CAAC,UAAW;AAChB,WAAK,OAAO,QAAQ,aAAa;AAAA,QAC/B,GAAG;AAAA,QACH,SAAS,SAAS;AAAA,MACpB,CAAC;AAAA,IACH,CAAC;AAED,UAAM,iBAAiB,KAAK;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,CAAC,YAAY,iBAAiB;AAC5B,cAAM,YAAY,KAAK,MAAM;AAC7B,YAAI,CAAC,UAAW;AAChB,aAAK,OAAO,QAAQ,aAAa;AAAA,UAC/B,GAAG;AAAA,UACH;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,YAAY,MAAM;AACtB,YAAM,eAAe,KAAK,MAAM,aAAa;AAC7C,YAAM,SAAS,KAAK,eAAe,YAAY,UAAU,cAAc;AACvE,YAAM,UAAU,OAAO;AACvB,UAAI,CAAC,WAAW,CAAC,KAAK,mBAAmB,YAAY,EAAG;AACxD,WAAK,KAAK,OAAO,QAAQ,WAAW;AAAA,QAClC,MAAM;AAAA,QACN,OAAO,OAAO;AAAA,QACd,SAAS,KAAK,2BAA2B,SAAS,YAAY;AAAA,QAC9D,YAAY,OAAO;AAAA,QACnB,cAAc,OAAO;AAAA,QACrB,UAAU,aAAa;AAAA,QACvB,QAAQ,aAAa;AAAA,QACrB,QAAQ,aAAa;AAAA,QACrB,WAAW,aAAa;AAAA,MAC1B,CAAC;AAAA,IACH;AAEA,UAAM,qBACJ,iBACI,KAAK,yBAAyB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,QAAQ;AAAA,IACtB,CAAC,IACD;AAEN,UAAM,UAAU,KAAK,kBAAkB,aAAa,WAAW;AAAA,MAC7D,SAAS,oBAAoB,eACzB,CAAC,mBAAmB,YAAY,IAChC;AAAA,IACN,CAAC;AACD,UAAM,QAAQ,KAAK,iBAAiB;AAEpC,SAAK;AAAA,MACH,GAAI,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,MACrB,GAAI,qBAAqB,CAAC,mBAAmB,KAAK,IAAI,CAAC;AAAA,MACvD,GAAI,aAAa,CAAC,UAAU,IAAI,CAAC;AAAA,MACjC;AAAA,MACA,GAAI,iBAAiB,CAAC,cAAc,IAAI,CAAC;AAAA,MACzC,GAAI,QAAQ,CAAC,KAAK,IAAI,CAAC;AAAA,MACvB;AAAA,IACF;AACA,UAAM,aACJ,kBAAkB,CAAC,QAAQ,eACvB,KAAK,sBAAsB,mBAAmB,IAC9C;AACN,YAAQ;AAAA,MACN,GAAI,aAAa,CAAC,UAAU,IAAI,CAAC;AAAA,MACjC;AAAA,IACF;AACA,UAAM,OAAO,GAAG;AAChB,QAAI,CAAC,QAAQ,cAAc;AACzB,YAAM,OAAO,OAAO;AAAA,IACtB;AAEA,QAAI,YAAY;AACd,WAAK,wBAAwB,SAAS,YAAY,CAAC,qBAAqB;AACtE,cAAM,YAAY,KAAK,MAAM,aAAa;AAC1C,aAAK,OAAO,QAAQ,aAAa;AAAA,UAC/B,GAAG;AAAA,UACH;AAAA,UACA,SAAS,SAAS;AAAA,QACpB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,SAAK;AAAA,MACH;AAAA,MACA,kBAAkB,QAAQ,eAAe,SAAY;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,cAAc;AACzB,aAAO,WAAW,MAAM;AACtB,YAAI,MAAM,YAAY,UAAU;AAC9B,8BAAoB,YAAY,MAAM;AACtC;AAAA,QACF;AAEA,iBAAS,MAAM;AAAA,MACjB,GAAG,CAAC;AAAA,IACN;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,MACP,UAAU,QAAQ,eAAe,UAAU;AAAA,IAC7C;AAAA,EACF;AAAA,EAEQ,sBAAsB,OAAe;AAC3C,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY;AACnB,WAAO,OAAO;AACd,WAAO,aAAa,cAAc,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,OAAiB;AAClC,UAAM,MAAM,SAAS,gBAAgB,8BAA8B,KAAK;AACxE,QAAI,aAAa,eAAe,MAAM;AACtC,QAAI,aAAa,WAAW,WAAW;AACvC,QAAI,aAAa,QAAQ,MAAM;AAC/B,QAAI,aAAa,UAAU,cAAc;AACzC,QAAI,aAAa,gBAAgB,KAAK;AACtC,QAAI,aAAa,kBAAkB,OAAO;AAC1C,QAAI,aAAa,mBAAmB,OAAO;AAE3C,UAAM,QAAQ,CAAC,MAAM;AACnB,YAAM,OAAO,SAAS,gBAAgB,8BAA8B,MAAM;AAC1E,WAAK,aAAa,KAAK,CAAC;AACxB,UAAI,OAAO,IAAI;AAAA,IACjB,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,QAA2B,UAAmB;AAC5E,UAAM,QAAQ,WACV,CAAC,iBAAiB,IAClB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACJ,WAAO,gBAAgB,KAAK,WAAW,KAAK,CAAC;AAAA,EAC/C;AAAA,EAEQ,wBACN,SACA,QACA,QACA;AACA,QAAI,aAAa;AACjB,QAAI,UAAU;AACd,QAAI,UAAU;AAEd,UAAM,cAAc,CAAC,UAAwB;AAC3C,YAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,UAAI,CAAC,YAAa;AAElB,YAAM,WAAW,KAAK;AAAA,QACpB;AAAA,UACE,GAAG,MAAM,UAAU;AAAA,UACnB,GAAG,MAAM,UAAU;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO,QAAQ;AAAA,UACf,QAAQ,QAAQ;AAAA,QAClB;AAAA,QACA,KAAK,sBAAsB;AAAA,MAC7B;AAEA,cAAQ,MAAM,OAAO,GAAG,SAAS,CAAC;AAClC,cAAQ,MAAM,MAAM,GAAG,SAAS,CAAC;AACjC,aAAO,QAAQ;AAAA,IACjB;AAEA,WAAO,iBAAiB,eAAe,CAAC,UAAU;AAChD,UAAI,MAAM,WAAW,EAAG;AAExB,YAAM,OAAO,QAAQ,sBAAsB;AAC3C,gBAAU,MAAM,UAAU,KAAK;AAC/B,gBAAU,MAAM,UAAU,KAAK;AAC/B,mBAAa;AAEb,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,aAAO,kBAAkB,MAAM,SAAS;AACxC,cAAQ,UAAU,IAAI,aAAa;AAAA,IACrC,CAAC;AAED,WAAO,iBAAiB,eAAe,CAAC,UAAU;AAChD,UAAI,CAAC,cAAc,CAAC,OAAO,kBAAkB,MAAM,SAAS,EAAG;AAE/D,YAAM,eAAe;AACrB,kBAAY,KAAK;AAAA,IACnB,CAAC;AAED,UAAM,WAAW,CAAC,UAAwB;AACxC,UAAI,CAAC,cAAc,CAAC,OAAO,kBAAkB,MAAM,SAAS,EAAG;AAE/D,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,mBAAa;AACb,aAAO,sBAAsB,MAAM,SAAS;AAC5C,cAAQ,UAAU,OAAO,aAAa;AACtC,kBAAY,KAAK;AAAA,IACnB;AAEA,WAAO,iBAAiB,aAAa,QAAQ;AAC7C,WAAO,iBAAiB,iBAAiB,QAAQ;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAOG;AACD,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAElB,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,YAAY;AACnB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,SAAK,cAAc,KAAK,mBAAmB;AAE3C,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY;AACnB,WAAO,OAAO;AACd,WAAO,QAAQ;AACf,WAAO,aAAa,cAAc,yCAAyC;AAE3E,UAAM,WAAW,SAAS,cAAc,KAAK;AAC7C,aAAS,YAAY;AAErB,UAAM,cAAc,SAAS,cAAc,KAAK;AAChD,gBAAY,YAAY;AAExB,UAAM,eAAe,CAAC,cAAyB;AAC7C,YAAM,WAAW,UAAU,YAAY,aAAa;AACpD,YAAM,UAAU,OAAO,aAAa,QAAQ;AAC5C,aAAO,UAAU,OAAO,aAAa,QAAQ;AAC7C,aAAO,aAAa,gBAAgB,WAAW,SAAS,OAAO;AAC/D,WAAK,wBAAwB,QAAQ,QAAQ;AAC7C,aAAO,QAAQ,WACX,0BACA;AACJ,aAAO;AAAA,QACL;AAAA,QACA,WACI,0BACA;AAAA,MACN;AACA,YAAM,CAAC,QAAQ,SAAS,IAAI,KAAK,8BAA8B,SAAS;AACxE,eAAS,cAAc;AACvB,kBAAY,cAAc;AAC1B,WAAK,sBAAsB;AAAA,QACzB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,CAAC,YAA+C;AAClE,YAAM,eAAe,KAAK,MAAM,aAAa;AAC7C,YAAM,YAAY,QAAQ,YAAY;AACtC,WAAK,OAAO,QAAQ,aAAa;AAAA,QAC/B,GAAG;AAAA,QACH,SAAS,SAAS;AAAA,MACpB,CAAC;AACD,mBAAa,SAAS;AAAA,IACxB;AAEA,WAAO,iBAAiB,SAAS,MAAM;AACrC,kBAAY,CAAC,kBAAkB;AAAA,QAC7B,GAAG;AAAA,QACH,YAAY;AAAA,UACV,GAAG,aAAa,YAAY,KAAK;AAAA,UACjC,GAAG,aAAa,YAAY,KAAK;AAAA,UACjC,OAAO,aAAa,YAAY,SAAS;AAAA,UACzC,UAAU,aAAa,YAAY,aAAa;AAAA,QAClD;AAAA,MACF,EAAE;AACF,aAAO,MAAM;AAAA,IACf,CAAC;AAED,YAAQ,iBAAiB,WAAW,CAAC,UAAU;AAC7C,YAAM,eAAe,KAAK,MAAM,aAAa;AAC7C,UAAI,aAAa,YAAY,aAAa,KAAM;AAEhD,YAAM,WAAW,KAAK,sBAAsB,KAAK;AACjD,UAAI,CAAC,SAAU;AAEf,YAAM,eAAe;AACrB,YAAM,gBAAgB;AAEtB,kBAAY,CAAC,iBAAiB;AAAA,QAC5B,GAAG;AAAA,QACH,YAAY;AAAA,UACV,IAAI,YAAY,YAAY,KAAK,KAAK,SAAS;AAAA,UAC/C,IAAI,YAAY,YAAY,KAAK,KAAK,SAAS;AAAA,UAC/C,QAAQ,YAAY,YAAY,SAAS,KAAK,SAAS;AAAA,UACvD,UAAU;AAAA,QACZ;AAAA,MACF,EAAE;AAAA,IACJ,CAAC;AAED,WAAO,OAAO,IAAI;AAClB,QAAI,CAAC,YAAY;AACf,aAAO,OAAO,MAAM;AAAA,IACtB;AACA,UAAM,OAAO,QAAQ,UAAU,WAAW;AAC1C,iBAAa,KAAK;AAElB,WAAO;AAAA,MACL;AAAA,MACA,aAAa;AAAA,MACb,cAAc,aAAa,SAAS;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,sBAAsB,OAAsB;AAClD,UAAM,OAAO,MAAM,WAAW,KAAK;AAEnC,QAAI,MAAM,QAAQ,YAAa,QAAO,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,OAAO,EAAE;AACjE,QAAI,MAAM,QAAQ,aAAc,QAAO,EAAE,GAAG,MAAM,GAAG,GAAG,OAAO,EAAE;AACjE,QAAI,MAAM,QAAQ,UAAW,QAAO,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,OAAO,EAAE;AAC/D,QAAI,MAAM,QAAQ,YAAa,QAAO,EAAE,GAAG,GAAG,GAAG,MAAM,OAAO,EAAE;AAChE,QAAI,MAAM,IAAI,YAAY,MAAM,IAAK,QAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK;AACtE,QAAI,MAAM,IAAI,YAAY,MAAM,IAAK,QAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK;AAEvE,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,QAAI,CAAC,YAAa;AAElB,UAAM,YAAY;AAAA,MAChB,KAAK,sBAAsB,MAAM,OAAO,UAAU,KAAK;AAAA,MACvD;AAAA,IACF;AACA,QAAI,MAAM,OAAO,GAAG,UAAU,CAAC;AAC/B,QAAI,MAAM,MAAM,GAAG,UAAU,CAAC;AAE9B,QAAI,MAAM,aAAa,oBAAoB;AACzC,YAAM,OAAO;AAAA,QACX,KAAK;AAAA,UACH,oBAAoB,MAAM,UAAU,QAAQ;AAAA,UAC5C;AAAA,QACF;AAAA,QACA;AAAA,MACF;AACA,yBAAmB,MAAM,OAAO,GAAG,KAAK,IAAI;AAC5C,yBAAmB,MAAM,MAAM,GAAG,KAAK,GAAG;AAC1C,yBAAmB,MAAM,QAAQ,GAAG,KAAK,KAAK;AAC9C,yBAAmB,MAAM,SAAS,GAAG,KAAK,MAAM;AAAA,IAClD;AAEA,SAAK,iBAAiB,KAAK;AAAA,EAC7B;AAAA,EAEQ,iBAAiB;AACvB,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AACjB,UAAM,YAAY,KAAK,MAAM;AAE7B,QAAI,CAAC,WAAW;AACd,YAAM,QAAQ,SAAS,cAAc,GAAG;AACxC,YAAM,YAAY;AAClB,YAAM,cAAc;AACpB,WAAK,OAAO,KAAK;AACjB,aAAO;AAAA,IACT;AAEA,SAAK,OAAO,KAAK,uBAAuB,SAAS,CAAC;AAElD,UAAM,aAAa,KAAK,oBAAoB,IACxC,KAAK,sBAAsB,UAAU,OAAO,CAAC,UAAU;AACrD,YAAM,QAAQ,KAAK,MAAM;AACzB,UAAI,CAAC,MAAO;AACZ,WAAK,OAAO,QAAQ,aAAa;AAAA,QAC/B,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,CAAC,IACD;AAEJ,UAAM,WAAW,SAAS,cAAc,UAAU;AAClD,aAAS,YAAY;AACrB,aAAS,cAAc;AACvB,aAAS,OAAO;AAChB,aAAS,QAAQ,UAAU,WAAW;AACtC,aAAS,iBAAiB,SAAS,MAAM;AACvC,YAAM,QAAQ,KAAK,MAAM;AACzB,UAAI,CAAC,MAAO;AACZ,WAAK,OAAO,QAAQ,aAAa;AAAA,QAC/B,GAAG;AAAA,QACH,SAAS,SAAS;AAAA,MACpB,CAAC;AAAA,IACH,CAAC;AAED,UAAM,iBAAiB,KAAK;AAAA,MAC1B,UAAU;AAAA,MACV,UAAU;AAAA,MACV,CAAC,YAAY,iBAAiB;AAC5B,cAAM,QAAQ,KAAK,MAAM;AACzB,YAAI,CAAC,MAAO;AACZ,aAAK,OAAO,QAAQ,aAAa;AAAA,UAC/B,GAAG;AAAA,UACH;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAU,KAAK,kBAAkB,aAAa,MAAM;AACxD,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,SAAS,KAAK,eAAe,YAAY,UAAU,cAAc;AACvE,YAAM,UAAU,OAAO;AACvB,UAAI,CAAC,WAAW,CAAC,MAAO;AACxB,WAAK,KAAK,OAAO,QAAQ,WAAW;AAAA,QAClC,MAAM;AAAA,QACN,OAAO,OAAO;AAAA,QACd;AAAA,QACA,YAAY,OAAO;AAAA,QACnB,cAAc,OAAO;AAAA,QACrB,UAAU,MAAM;AAAA,QAChB,QAAQ,MAAM;AAAA,QACd,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AACD,UAAM,QAAQ,KAAK,iBAAiB;AAEpC,SAAK;AAAA,MACH,GAAI,aAAa,CAAC,UAAU,IAAI,CAAC;AAAA,MACjC;AAAA,MACA,GAAI,iBAAiB,CAAC,cAAc,IAAI,CAAC;AAAA,MACzC,GAAI,QAAQ,CAAC,KAAK,IAAI,CAAC;AAAA,MACvB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,OAAkB;AAC/C,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAElB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,UAAM,CAAC,WAAW,QAAQ,QAAQ,IAAI,KAAK;AAAA,MACzC,KAAK,4BAA4B,KAAK;AAAA,MACtC,MAAM;AAAA,IACR;AACA,SAAK,cAAc;AAEnB,UAAM,WAAW,SAAS,cAAc,KAAK;AAC7C,aAAS,YAAY;AACrB,aAAS,cAAc;AAEvB,UAAM,aAAa,SAAS,cAAc,KAAK;AAC/C,eAAW,YAAY;AACvB,eAAW,cAAc;AAEzB,UAAM,OAAO,MAAM,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,OAAkB;AAC/C,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAElB,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,QAAI,CAAC,eAAe,CAAC,MAAM,UAAW,QAAO;AAE7C,UAAM,YAAY,oBAAoB,MAAM,UAAU,QAAQ;AAC9D,UAAM,OAAO,KAAK,yBAAyB,WAAW,aAAa,IAAI,CAAC;AAExE,QAAI,MAAM,QAAQ;AAChB,YAAM,YAAY,YAAY,MAAM,OAAO,UAAU,WAAW;AAChE,YAAM;AAAA,QACJ,KAAK;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,KAAK,OAAO,QAAQ,WAAW;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,uBACN,OACA,UAAsC,CAAC,GACvC;AACA,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AAAA,MAClB;AAAA,MACA;AAAA,MACA,QAAQ,eAAe,uBAAuB;AAAA,IAChD,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,QAAI,QAAQ,cAAc;AACxB,cAAQ,MAAM,QAAQ;AAAA,IACxB,WAAW,eAAe,MAAM,WAAW;AACzC,YAAM,YAAY;AAAA,QAChB,oBAAoB,MAAM,UAAU,QAAQ;AAAA,QAC5C;AAAA,MACF;AACA,YAAM,WAAW,KAAK,yBAAyB;AAAA,QAC7C;AAAA,QACA;AAAA,QACA,kBAAkB,MAAM;AAAA,QACxB,iBAAiB;AAAA,MACnB,CAAC;AACD,cAAQ,MAAM,OAAO,GAAG,SAAS,IAAI;AACrC,cAAQ,MAAM,MAAM,GAAG,SAAS,GAAG;AACnC,cAAQ,MAAM,QAAQ,GAAG,SAAS,KAAK;AACvC,cAAQ,MAAM,QAAQ;AAAA,IACxB;AACA,UAAM,aAAa,QAAQ,eACvB,SACA,KAAK,sBAAsB,oBAAoB;AACnD,YAAQ;AAAA,MACN,GAAI,aAAa,CAAC,UAAU,IAAI,CAAC;AAAA,MACjC,KAAK,eAAe;AAAA,IACtB;AACA,QAAI,YAAY;AACd,WAAK,wBAAwB,SAAS,YAAY,CAAC,qBAAqB;AACtE,cAAM,YAAY,KAAK,MAAM,aAAa;AAC1C,aAAK,OAAO,QAAQ,aAAa;AAAA,UAC/B,GAAG;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBACN,WACA,QACA,SAKA;AACA,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY,CAAC,gBAAgB,SAAS,SAAS,EACpD,OAAO,OAAO,EACd,KAAK,GAAG;AACX,UAAM,WAAW,KAAK,MAAM;AAE5B,UAAM,OAAO,SAAS,cAAc,QAAQ;AAC5C,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,aAAa,aAAa,WAAW,SAAS,OAAO;AAC1D,QAAI,UAAU;AACZ,WAAK,OAAO,KAAK,cAAc,cAAc,GAAG,WAAW;AAAA,IAC7D,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AACA,SAAK,iBAAiB,SAAS,CAAC,UAAU;AACxC,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,UAAI,KAAK,MAAM,eAAgB;AAC/B,aAAO;AAAA,IACT,CAAC;AAED,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY;AACnB,WAAO,OAAO;AACd,WAAO,WAAW;AAClB,WAAO,cAAc;AACrB,WAAO,iBAAiB,SAAS,CAAC,UAAU;AAC1C,WAAK,YAAY,KAAK;AAAA,IACxB,CAAC;AAED,QAAI,SAAS,SAAS,QAAQ;AAC5B,cAAQ,UAAU,IAAI,aAAa;AACnC,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,cAAQ,YAAY;AACpB,cAAQ,OAAO,GAAG,QAAQ,OAAO;AACjC,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,cAAQ,YAAY;AACpB,cAAQ,OAAO,MAAM,MAAM;AAC3B,cAAQ,OAAO,SAAS,OAAO;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,YAAY,UAAU,SAAS,WAAW;AACrD,cAAQ,OAAO,QAAQ,GAAI,QAAQ,cAAc,CAAC,GAAI,IAAI;AAC1D,aAAO;AAAA,IACT;AAEA,YAAQ,OAAO,MAAM,MAAM;AAC3B,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,WAAmB;AACvC,UAAM,UAAU,SAAS,cAAc,MAAM;AAC7C,YAAQ,YAAY;AACpB,YAAQ,aAAa,eAAe,MAAM;AAC1C,WAAO;AAAA,EACT;AAAA,EAEQ,mBAAmB;AACzB,QAAI,CAAC,KAAK,MAAM,WAAY,QAAO;AAEnC,UAAM,QAAQ,SAAS,cAAc,GAAG;AACxC,UAAM,YAAY;AAClB,UAAM,aAAa,QAAQ,OAAO;AAClC,UAAM,cAAc,KAAK,MAAM;AAC/B,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa;AACnB,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AACpB,UAAM,QAAQ,KAAK;AAEnB,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AACpB,YAAQ,cAAc,iBAAiB,MAAM,MAAM,MAAM;AACzD,YAAQ,OAAO,OAAO;AAEtB,QAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,YAAM,QAAQ,SAAS,cAAc,GAAG;AACxC,YAAM,YAAY;AAClB,YAAM,cAAc;AACpB,cAAQ,OAAO,KAAK;AACpB,aAAO;AAAA,IACT;AAEA,eAAW,gBAAgB;AAAA,MACzB,MAAM;AAAA,MACN,KAAK,OAAO,QAAQ,WAAW;AAAA,IACjC,GAAG;AACD,cAAQ,OAAO,KAAK,eAAe,YAAY,CAAC;AAAA,IAClD;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,cAAkC;AACvD,UAAM,EAAE,KAAK,IAAI;AACjB,UAAM,MAAM,SAAS,cAAc,SAAS;AAC5C,QAAI,YAAY;AAChB,QAAI,WAAW;AACf,QAAI,aAAa,QAAQ,QAAQ;AACjC,QAAI;AAAA,MACF;AAAA,MACA,wBAAwB,KAAK,SAAS,KAAK,OAAO;AAAA,IACpD;AACA,QAAI,iBAAiB,SAAS,MAAM;AAClC,WAAK,KAAK,OAAO,QAAQ,YAAY,IAAI;AAAA,IAC3C,CAAC;AACD,QAAI,iBAAiB,WAAW,CAAC,UAAU;AACzC,UAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,IAAK;AAEhD,YAAM,eAAe;AACrB,WAAK,KAAK,OAAO,QAAQ,YAAY,IAAI;AAAA,IAC3C,CAAC;AAED,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AAEjB,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,YAAY;AAEnB,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY,4BAA4B,aAAa,KAAK;AAChE,UAAM,cAAc,aAAa;AAEjC,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,SAAK,cAAc,KAAK;AACxB,WAAO,OAAO,OAAO,IAAI;AAEzB,UAAM,QAAQ,KAAK,oBAAoB,IAAI,KAAK,OAAO,KAAK,IAAI;AAChE,UAAM,eAAe,QAAQ,SAAS,cAAc,QAAQ,IAAI;AAChE,QAAI,SAAS,cAAc;AACzB,mBAAa,YAAY;AACzB,mBAAa,cAAc;AAAA,IAC7B;AAEA,UAAM,UAAU,SAAS,cAAc,GAAG;AAC1C,YAAQ,YAAY,oBAAoB,QAAQ,KAAK,aAAa;AAClE,YAAQ,cAAc,KAAK;AAE3B,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AACjB,SAAK,WAAW,KAAK;AACrB,SAAK,cAAc,eAAe,IAAI;AAEtC,SAAK,OAAO,QAAQ,GAAI,eAAe,CAAC,YAAY,IAAI,CAAC,GAAI,SAAS,IAAI;AAE1E,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AACpB,YAAQ,iBAAiB,SAAS,CAAC,UAAU,MAAM,gBAAgB,CAAC;AACpE,YAAQ,iBAAiB,WAAW,CAAC,UAAU,MAAM,gBAAgB,CAAC;AAEtE,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,YAAY;AACnB,WAAO,OAAO;AACd,WAAO,cAAc;AACrB,WAAO,aAAa,cAAc,QAAQ;AAC1C,WAAO,iBAAiB,SAAS,CAAC,UAAU;AAC1C,YAAM,gBAAgB;AACtB,WAAK,KAAK,OAAO,QACd,WAAW,KAAK,EAAE,EAClB,KAAK,MAAM,KAAK,OAAO,QAAQ,OAAO,CAAC;AAAA,IAC5C,CAAC;AAED,YAAQ,OAAO,MAAM;AACrB,QAAI,OAAO,MAAM,OAAO;AACxB,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB;AAC1B,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,eAAe;AAAA,MACnB,gBAAgB,WAAW;AAAA,MAC3B,KAAK,OAAO,QAAQ,WAAW;AAAA,IACjC;AAEA;AAAA,MACE,KAAK,MAAM;AAAA,MACX,KAAK,OAAO,QAAQ,WAAW;AAAA,IACjC,EAAE,QAAQ,CAAC,iBAAiB;AAC1B,YAAM,EAAE,MAAM,OAAO,aAAa,IAAI;AACtC,UAAI,CAAC,yBAAyB,OAAO,YAAY,GAAG;AAClD;AAAA,MACF;AAEA,YAAM,gBAAgB,KAAK,OAAO,KAAK,MAAM;AAC7C,YAAM,gBAAgB,2BAA2B,IAAI;AACrD,UACE,kBAAkB,WACjB,CAAC,KAAK,MAAM,qBAAqB,gBAClC;AACA,cAAM,YAAY,0BAA0B,MAAM,WAAW;AAC7D,YAAI,WAAW;AACb,gBAAM;AAAA,YACJ,GAAG,KAAK;AAAA,cACN,UAAU;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA,UAAU;AAAA,cACV;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAQ,oBAAoB,MAAM,WAAW;AACnD,UAAI,CAAC,SAAS,CAAC,kBAAkB,MAAM,UAAU,WAAW,GAAG;AAC7D;AAAA,MACF;AAEA,YAAM,YAAY,YAAY,MAAM,UAAU,WAAW;AACzD,YAAM,SAAS,KAAK;AAAA,QAClB,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,kBAAkB,SAAS,SAAS;AAAA,MACtC;AACA,aAAO,QAAQ,GAAG,YAAY,MAAM,KAAK,OAAO;AAAA,EAAK,eAAe,IAAI,CAAC;AACzE,YAAM,OAAO,MAAM;AAAA,IACrB,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,4BACN,WACA,aACA,MACA,OACA,SACA,eACA;AACA,UAAM,OAAO,gBAAgB,WAAW,WAAW;AACnD,UAAM,OAAO,2BAA2B,IAAI;AAC5C,UAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,cAAU,YAAY;AAAA,MACpB;AAAA,MACA,WAAW,IAAI;AAAA,MACf,UAAU,aAAa;AAAA,MACvB,gBAAgB,mBAAmB;AAAA,IACrC,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,cAAU,MAAM,OAAO,GAAG,KAAK,IAAI;AACnC,cAAU,MAAM,MAAM,GAAG,KAAK,GAAG;AACjC,cAAU,MAAM,QAAQ,GAAG,KAAK,KAAK;AACrC,cAAU,MAAM,SAAS,GAAG,KAAK,MAAM;AACvC,cAAU,QAAQ,eAAe,KAAK;AAEtC,UAAM,eAAe,SAAS,cAAc,KAAK;AACjD,iBAAa,YAAY;AAAA,MACvB;AAAA,MACA,WAAW,IAAI;AAAA,MACf,gBAAgB,mBAAmB;AAAA,IACrC,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,iBAAa,cAAc;AAC3B,iBAAa,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AACnD,iBAAa,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;AACtD,iBAAa,QAAQ,eAAe,KAAK;AAEzC,WAAO,CAAC,WAAW,YAAY;AAAA,EACjC;AAAA,EAEQ,yBACN,WACA,aACA,SACA;AACA,UAAM,OAAO,gBAAgB,WAAW,WAAW;AACnD,UAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,cAAU,YAAY,2BACpB,UAAU,cAAc,EAC1B;AACA,cAAU,MAAM,OAAO,GAAG,KAAK,IAAI;AACnC,cAAU,MAAM,MAAM,GAAG,KAAK,GAAG;AACjC,cAAU,MAAM,QAAQ,GAAG,KAAK,KAAK;AACrC,cAAU,MAAM,SAAS,GAAG,KAAK,MAAM;AACvC,WAAO;AAAA,EACT;AAAA,EAEQ,oBACN,QACA,WACA,OACA,OACA,SACA,eACA,UAA8B,WAC9B;AACA,UAAM,gBAAgB,YAAY;AAClC,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,WAAO,YAAY;AAAA,MACjB;AAAA,MACA,gBAAgB,oBAAoB;AAAA,MACpC,YAAY,KAAK;AAAA,MACjB,UAAU,aAAa;AAAA,MACvB,gBAAgB,mBAAmB;AAAA,IACrC,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,WAAO,MAAM,OAAO,GAAG,UAAU,CAAC;AAClC,WAAO,MAAM,MAAM,GAAG,UAAU,CAAC;AACjC,WAAO,QAAQ,QAAQ;AACvB,QAAI,QAAQ;AACV,aAAO,QAAQ,eAAe;AAAA,IAChC;AAEA,UAAM,cAAc,SAAS,cAAc,MAAM;AACjD,gBAAY,YAAY;AACxB,gBAAY,aAAa,eAAe,MAAM;AAC9C,UAAM,eAAe,SAAS,cAAc,MAAM;AAClD,iBAAa,YAAY;AACzB,iBAAa,cAAc;AAC3B,WAAO,OAAO,aAAa,YAAY;AAEvC,WAAO;AAAA,EACT;AAAA,EAEQ,mBACN,KACA,SACA,MACA,UACA;AACA,QAAI,aAAa;AAEjB,UAAM,cAAc,CAAC,cAA2B;AAC9C,YAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,UAAI,CAAC,YAAa;AAElB,YAAM,YAAY,WAAW,cAAc,WAAW,WAAW,GAAG,WAAW;AAC/E,YAAM,gBAAgB,YAAY,WAAW,WAAW;AAExD,UAAI,MAAM,OAAO,GAAG,cAAc,CAAC;AACnC,UAAI,MAAM,MAAM,GAAG,cAAc,CAAC;AAClC,UAAI,SAAS;AACX,cAAM,WAAW,mBAAmB,eAAe,WAAW;AAC9D,gBAAQ,MAAM,OAAO,GAAG,SAAS,IAAI;AACrC,gBAAQ,MAAM,MAAM,GAAG,SAAS,GAAG;AAAA,MACrC;AAEA,YAAM,YAAY,KAAK,MAAM;AAC7B,UAAI,CAAC,UAAW;AAEhB,YAAM,YAAY;AAAA,QAChB,GAAG;AAAA,QACH,QAAQ;AAAA,UACN,GAAG,UAAU;AAAA,UACb,UAAU,WAAW,SAAS;AAAA,QAChC;AAAA,QACA,SAAS,SAAS;AAAA,MACpB;AACA,WAAK,OAAO,QAAQ,aAAa,SAAS;AAC1C,UAAI,MAAM;AACR,aAAK,cAAc,oBAAoB,SAAS;AAAA,MAClD;AAAA,IACF;AAEA,QAAI,iBAAiB,eAAe,CAAC,UAAU;AAC7C,UAAI,MAAM,WAAW,EAAG;AAExB,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,mBAAa;AACb,UAAI,kBAAkB,MAAM,SAAS;AAAA,IACvC,CAAC;AAED,QAAI,iBAAiB,eAAe,CAAC,UAAU;AAC7C,UAAI,CAAC,cAAc,CAAC,IAAI,kBAAkB,MAAM,SAAS,EAAG;AAE5D,YAAM,eAAe;AACrB,kBAAY;AAAA,QACV,GAAG,MAAM;AAAA,QACT,GAAG,MAAM;AAAA,MACX,CAAC;AAAA,IACH,CAAC;AAED,QAAI,iBAAiB,aAAa,CAAC,UAAU;AAC3C,UAAI,CAAC,cAAc,CAAC,IAAI,kBAAkB,MAAM,SAAS,EAAG;AAE5D,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,mBAAa;AACb,UAAI,sBAAsB,MAAM,SAAS;AAEzC,YAAM,YAAY;AAAA,QAChB;AAAA,QACA,KAAK,OAAO,eAAe;AAAA,MAC7B;AACA,YAAM,eAAe,KAAK,MAAM;AAChC,YAAM,SAAS;AAAA,QACb,OAAO,cAAc;AAAA,QACrB,SAAS,SAAS;AAAA,QAClB,YAAY,cAAc;AAAA,QAC1B,cAAc,cAAc;AAAA,MAC9B;AACA,YAAM,KAAK,MAAM,SAAS,YACtB,KAAK,OAAO,QAAQ,wBAAwB,WAAW,MAAM,IAC7D,KAAK,OAAO,QAAQ,qBAAqB,WAAW,MAAM;AAAA,IAChE,CAAC;AAAA,EACH;AAAA,EAEQ,kBAAkB;AACxB,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,cAAc,KAAK,OAAO,eAAe;AAE/C,QAAI,aAAa;AACf,2BAAqB,OAAO,WAAW;AAAA,IACzC;AAEA,UAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,UAAI,MAAM,WAAW,EAAG;AACxB,YAAM,eAAe;AACrB,WAAK,KAAK,OAAO,QAAQ;AAAA,QACvB,2BAA2B,OAAO,KAAK,OAAO,eAAe,CAAC;AAAA,MAChE;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,qBAAqB;AAC3B,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,cAAc,KAAK,OAAO,eAAe;AAC/C,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,SAAS;AACf,UAAM,OAAO,KAAK;AAElB,QAAI,aAAa;AACf,2BAAqB,OAAO,WAAW;AAAA,IACzC;AAEA,UAAM,cAAc,CAAC,UAAuB;AAC1C,YAAM,kBAAkB,KAAK,OAAO,eAAe;AACnD,UAAI,CAAC,gBAAiB;AAEtB,YAAM,SAAS;AAAA,QACb,WAAW,OAAO,eAAe;AAAA,QACjC,KAAK,OAAO,QAAQ,SAAS;AAAA,QAC7B;AAAA,MACF;AACA,YAAM,YAAY,SACd,4BAA4B,QAAQ,eAAe,IACnD;AAEJ,UAAI,CAAC,WAAW;AACd,cAAM,SAAS;AACf;AAAA,MACF;AAEA,YAAM,OAAO,gBAAgB,WAAW,eAAe;AACvD,YAAM,SAAS;AACf,YAAM,MAAM,OAAO,GAAG,KAAK,IAAI;AAC/B,YAAM,MAAM,MAAM,GAAG,KAAK,GAAG;AAC7B,YAAM,MAAM,QAAQ,GAAG,KAAK,KAAK;AACjC,YAAM,MAAM,SAAS,GAAG,KAAK,MAAM;AAAA,IACrC;AAEA,UAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,kBAAY,2BAA2B,OAAO,KAAK,OAAO,eAAe,CAAC,CAAC;AAAA,IAC7E,CAAC;AAED,UAAM,iBAAiB,gBAAgB,MAAM;AAC3C,YAAM,SAAS;AAAA,IACjB,CAAC;AAED,UAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,UAAI,MAAM,WAAW,EAAG;AACxB,YAAM,eAAe;AACrB,WAAK,KAAK,OAAO,QAAQ;AAAA,QACvB,2BAA2B,OAAO,KAAK,OAAO,eAAe,CAAC;AAAA,MAChE;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB;AACxB,UAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,UAAM,YAAY;AAClB,UAAM,cAAc,KAAK,OAAO,eAAe;AAE/C,QAAI,aAAa;AACf,2BAAqB,OAAO,WAAW;AAAA,IACzC;AAEA,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,YAAY;AAChB,UAAM,OAAO,GAAG;AAEhB,QAAI,SAAS;AACb,QAAI,SAAS;AACb,QAAI;AACJ,QAAI;AACJ,QAAI,aAAa;AACjB,UAAM,cAAc,MAAM,cAAc,eAAe;AAEvD,UAAM,YAAY,CAAC,UAAwB;AACzC,YAAM,kBAAkB,KAAK,OAAO,eAAe;AACnD,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AACA,YAAM,OAAO,KAAK,IAAI,QAAQ,UAAU,CAAC;AACzC,YAAM,MAAM,KAAK,IAAI,QAAQ,UAAU,CAAC;AACxC,YAAM,QAAQ,KAAK,IAAI,UAAU,IAAI,MAAM;AAC3C,YAAM,SAAS,KAAK,IAAI,UAAU,IAAI,MAAM;AAC5C,YAAM,YAAY;AAAA,QAChB,EAAE,GAAG,MAAM,GAAG,IAAI;AAAA,QAClB;AAAA,MACF;AAEA,kBAAY,EAAE,MAAM,KAAK,OAAO,OAAO;AACvC,UAAI,MAAM,OAAO,GAAG,UAAU,CAAC;AAC/B,UAAI,MAAM,MAAM,GAAG,UAAU,CAAC;AAC9B,UAAI,MAAM,QAAQ,GAAG,KAAK;AAC1B,UAAI,MAAM,SAAS,GAAG,MAAM;AAAA,IAC9B;AAEA,UAAM,mBAAmB,MAAM;AAC7B,kBAAY,iBAAiB,eAAe,mBAAmB,IAAI;AACnE,kBAAY,iBAAiB,aAAa,iBAAiB,IAAI;AAC/D,kBAAY,iBAAiB,iBAAiB,qBAAqB,IAAI;AAAA,IACzE;AAEA,UAAM,sBAAsB,MAAM;AAChC,kBAAY,oBAAoB,eAAe,mBAAmB,IAAI;AACtE,kBAAY,oBAAoB,aAAa,iBAAiB,IAAI;AAClE,kBAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,wBAAwB,CAAC,UAAwB;AACrD,UAAI;AACF,YAAI,MAAM,kBAAkB,MAAM,SAAS,GAAG;AAC5C,gBAAM,sBAAsB,MAAM,SAAS;AAAA,QAC7C;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,aAAS,gBAAgB,OAAqB;AAC5C,aAAO,cAAc,MAAM,cAAc;AAAA,IAC3C;AAEA,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,CAAC,gBAAgB,KAAK,EAAG;AAE7B,YAAM,eAAe;AACrB,gBAAU,KAAK;AACf,4BAAsB,KAAK;AAC3B,0BAAoB;AACpB,mBAAa;AACb,wBAAkB;AAElB,UAAI,CAAC,aAAa,UAAU,QAAQ,KAAK,UAAU,SAAS,EAAG;AAE/D,WAAK,OAAO,QAAQ,iBAAiB,IAAI;AACzC,WAAK,OAAO,QAAQ,OAAO;AAC3B,WAAK,KAAK,OAAO,QAAQ,gBAAgB,SAAS;AAAA,IACpD;AAEA,aAAS,kBAAkB,OAAqB;AAC9C,UAAI,CAAC,gBAAgB,KAAK,EAAG;AAE7B,YAAM,eAAe;AACrB,gBAAU,KAAK;AAAA,IACjB;AAEA,UAAM,kBAAkB,CAAC,UAAwB;AAC/C,0BAAoB,KAAK;AAAA,IAC3B;AAEA,UAAM,sBAAsB,CAAC,UAAwB;AACnD,UAAI,CAAC,gBAAgB,KAAK,EAAG;AAE7B,4BAAsB,KAAK;AAC3B,0BAAoB;AACpB,mBAAa;AACb,wBAAkB;AAAA,IACpB;AAEA,UAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,UAAI,MAAM,WAAW,EAAG;AAExB,YAAM,eAAe;AACrB,wBAAkB,MAAM;AACxB,mBAAa;AAEb,UAAI;AACF,cAAM,kBAAkB,MAAM,SAAS;AAAA,MACzC,QAAQ;AAAA,MAER;AAEA,YAAM,aAAa;AAAA,QACjB;AAAA,QACA,KAAK,OAAO,eAAe;AAAA,MAC7B;AACA,eAAS,WAAW;AACpB,eAAS,WAAW;AACpB,gBAAU,KAAK;AACf,uBAAiB;AAAA,IACnB,CAAC;AAED,UAAM,iBAAiB,eAAe,iBAAiB;AACvD,UAAM,iBAAiB,aAAa,eAAe;AACnD,UAAM,iBAAiB,iBAAiB,mBAAmB;AAE3D,WAAO;AAAA,EACT;AACF;;;ACplEA,IAAM,UAAU;AAMhB,SAAS,sBAAsB,OAAsB;AACnD,QAAM,OAAO,MAAM,eAAe,KAAK,CAAC;AACxC,QAAM,UAAW,KAAK,CAAC,KAAK,MAAM;AAClC,MAAI,CAAC,WAAW,OAAO,QAAQ,YAAY,SAAU,QAAO;AAE5D,QAAM,MAAM,QAAQ;AACpB,SACE,QAAQ,WACR,QAAQ,cACR,QAAQ,YACR,QAAQ,sBAAsB;AAElC;AAGO,SAAS,mBACd,SACwB;AACxB,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,aAAa;AACpE,WAAO,qBAAqB;AAAA,EAC9B;AAEA,QAAM,MAAM,IAAI,gBAAgB,OAAO;AACvC,MAAI,MAAM;AAEV,SAAO;AAAA,IACL,MAAM,MAAM,IAAI,KAAK;AAAA,IACrB,OAAO,MAAM,IAAI,MAAM;AAAA,IACvB,QAAQ,MAAM,IAAI,OAAO;AAAA,IACzB,SAAS,CAAC,SAAS,IAAI,QAAQ,IAAI;AAAA,IACnC,oBAAoB,CAAC,SAAS,YAC5B,IAAI,mBAAmB,SAAS,OAAO;AAAA,IACzC,SAAS,MAAM,IAAI,QAAQ;AAAA,IAC3B,eAAe,CAAC,WAAW,IAAI,cAAc,MAAM;AAAA,IACnD,kBAAkB,CAAC,YAAY,IAAI,iBAAiB,OAAO;AAAA,IAC3D,QAAQ,MAAM,IAAI,OAAO;AAAA,IACzB,UAAU,MAAM,IAAI,SAAS;AAAA,IAC7B,SAAS,MAAM,IAAI,QAAQ;AAAA,EAC7B;AACF;AAEA,IAAM,kBAAN,MAAsB;AAAA,EAkBpB,YAA6B,SAA8B;AAA9B;AAZ7B,SAAQ,SAAS;AACjB,SAAQ,OAAmB;AAC3B,SAAQ,QAAsB,CAAC;AAG/B,SAAQ,aAAa;AACrB,SAAQ,iBAAiB;AACzB,SAAQ,kBAAkB;AAoO1B,SAAiB,gBAAgB,CAAC,UAAyB;AACzD,UAAI,MAAM,QAAQ,YAAY,KAAK,WAAW,GAAG;AAC/C,cAAM,eAAe;AACrB,cAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,UAAI,sBAAsB,KAAK,KAAK,CAAC,SAAS,OAAO,KAAK,MAAM,EAAG;AAEnE,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,WAAK,OAAO;AAAA,IACd;AAEA,SAAiB,uBAAuB,MAAM;AAC5C,UAAI,CAAC,KAAK,UAAU,KAAK,eAAe,KAAK,uBAAuB,EAAG;AAEvE,WAAK,cAAc,OAAO,sBAAsB,MAAM;AACpD,aAAK,cAAc;AACnB,YAAI,KAAK,uBAAuB,EAAG;AACnC,aAAK,OAAO;AAAA,MACd,CAAC;AAAA,IACH;AApPE,SAAK,UAAU,QAAQ,WAAW,aAAa;AAC/C,SAAK,SAAS,QAAQ,SAAS,MAAM;AACrC,SAAK,OAAO,IAAI,iBAAiB;AAAA,MAC/B;AAAA,MACA,UAAU,OAAO;AAAA,QACf,QAAQ,KAAK;AAAA,QACb,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB,YAAY,KAAK;AAAA,QACjB,gBAAgB,KAAK;AAAA,QACrB,iBAAiB,KAAK;AAAA,QACtB,mBAAmB,KAAK;AAAA,MAC1B;AAAA,MACA,gBAAgB,MAAM,KAAK,eAAe;AAAA,MAC1C,SAAS;AAAA,QACP,OAAO,MAAM,KAAK,MAAM;AAAA,QACxB,QAAQ,MAAM,KAAK,OAAO;AAAA,QAC1B,QAAQ,MAAM,KAAK,OAAO;AAAA,QAC1B,aAAa,CAAC,SAAS,KAAK,YAAY,IAAI;AAAA,QAC5C,YAAY,CAAC,WAAW,KAAK,QAAQ,OAAO,MAAM;AAAA,QAClD,cAAc,CAAC,SAAS,KAAK,aAAa,IAAI;AAAA,QAC9C,aAAa,MAAM;AACjB,eAAK,YAAY;AACjB,eAAK,YAAY;AACjB,eAAK,aAAa;AAAA,QACpB;AAAA,QACA,cAAc,CAAC,UAAU;AACvB,eAAK,YAAY;AACjB,eAAK,aAAa;AAAA,QACpB;AAAA,QACA,cAAc,CAAC,UAAU;AACvB,eAAK,YAAY;AACjB,eAAK,aAAa;AAAA,QACpB;AAAA,QACA,kBAAkB,CAAC,oBAAoB;AACrC,eAAK,kBAAkB;AAAA,QACzB;AAAA,QACA,YAAY,CAAC,UAAU,KAAK,WAAW,KAAK;AAAA,QAC5C,sBAAsB,CAAC,OAAO,WAC5B,KAAK,qBAAqB,OAAO,MAAM;AAAA,QACzC,yBAAyB,CAAC,OAAO,WAC/B,KAAK,wBAAwB,OAAO,MAAM;AAAA,QAC5C,iBAAiB,CAAC,cAAc,KAAK,gBAAgB,SAAS;AAAA,MAChE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,QAAQ;AACN,QAAI,KAAK,KAAM;AAEf,UAAM,WAAW,SAAS,eAAe,OAAO;AAChD,QAAI,SAAU,UAAS,OAAO;AAE9B,SAAK,OAAO,SAAS,cAAc,KAAK;AACxC,SAAK,KAAK,KAAK;AACf,SAAK,KAAK,MAAM,UAAU;AAE1B,SAAK,SAAS,KAAK,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AACrD,aAAS,KAAK,YAAY,KAAK,IAAI;AACnC,aAAS,iBAAiB,WAAW,KAAK,eAAe,IAAI;AAC7D,WAAO,iBAAiB,UAAU,KAAK,sBAAsB,IAAI;AACjE,WAAO,iBAAiB,UAAU,KAAK,oBAAoB;AAE3D,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,UAAU;AACR,SAAK,KAAK,kBAAkB;AAC5B,aAAS,oBAAoB,WAAW,KAAK,eAAe,IAAI;AAChE,WAAO,oBAAoB,UAAU,KAAK,sBAAsB,IAAI;AACpE,WAAO,oBAAoB,UAAU,KAAK,oBAAoB;AAC9D,QAAI,KAAK,aAAa;AACpB,aAAO,qBAAqB,KAAK,WAAW;AAC5C,WAAK,cAAc;AAAA,IACrB;AACA,SAAK,MAAM,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,OAAQ;AAEjB,SAAK,SAAS;AACd,SAAK,KAAK,OAAO;AAAA,EACnB;AAAA,EAEA,QAAQ;AACN,SAAK,SAAS;AACd,SAAK,aAAa,MAAM;AACxB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,kBAAkB;AACvB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAS;AACP,QAAI,KAAK,QAAQ;AACf,WAAK,MAAM;AACX;AAAA,IACF;AAEA,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,QAAQ,MAAkB;AACxB,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AAAA,IAChB;AAEA,SAAK,aAAa,KAAK,SAAS,OAAO,SAAS,IAAI;AACpD,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,mBAAmB,SAAkB,SAAkB;AAC3D,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AAAA,IAChB;AAEA,SAAK,aAAa,SAAS;AAC3B,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,kBAAkB;AACvB,UAAM,KAAK,0BAA0B,SAAS,EAAE,QAAQ,CAAC;AAAA,EAC3D;AAAA,EAEA,UAAU;AACR,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW;AACT,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAc,QAAiB;AAC7B,QAAI,CAAC,QAAQ;AACX,WAAK,qBAAqB;AAC1B;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AAAA,IAChB;AAEA,SAAK,oBAAoB;AACzB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,iBAAiB,SAAoB;AACnC,SAAK,gBAAgB,UAAU,IAAI,IAAI,OAAO,IAAI;AAClD,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEQ,uBAAuB;AAC7B,QAAI,CAAC,KAAK,kBAAmB;AAE7B,SAAK,oBAAoB;AACzB,SAAK,OAAO;AAAA,EACd;AAAA,EAEQ,gCAAgC;AACtC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,QAAQ,kBAAkB;AAChC,UAAM,cAAc,KAAK,kBAAkB;AAC3C,WAAO;AAAA,EACT;AAAA,EAEQ,yBAAyB;AAC/B,QAAI,CAAC,KAAK,OAAQ;AAElB,QAAI,QAAQ,KAAK,OAAO;AAAA,MACtB;AAAA,IACF;AACA,QAAI,CAAC,OAAO;AACV,cAAQ,KAAK,8BAA8B;AAC3C,WAAK,OAAO,QAAQ,KAAK;AACzB;AAAA,IACF;AAEA,UAAM,cAAc,KAAK,kBAAkB;AAAA,EAC7C;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,CAAC,KAAK,eAAe,KAAM,QAAO;AAEtC,WAAO,MAAM,KAAK,KAAK,aAAa,EACjC;AAAA,MACC,CAAC,WACC,yBAAyB,UAAU,MAAM,CAAC;AAAA,IAC9C,EACC,KAAK,IAAI;AAAA,EACd;AAAA,EAEQ,aAAa,MAAkB;AACrC,QAAI,KAAK,SAAS,KAAM;AAExB,SAAK,OAAO;AACZ,SAAK,QAAQ,eAAe,IAAI;AAAA,EAClC;AAAA,EAEQ,aAAa;AACnB,QACE,KAAK,SAAS,UACd,CAAC,KAAK,aACN,CAAC,KAAK,aACN,CAAC,KAAK,iBACN;AACA,aAAO;AAAA,IACT;AAEA,SAAK,aAAa,MAAM;AACxB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,kBAAkB;AACvB,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AAAA,EA0BQ,yBAAyB;AAC/B,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,UAAW,QAAO;AAC/C,UAAM,eAAe,KAAK,eAAe,GAAG;AAC5C,UAAM,gBAAgB,cAAc,cAAc;AAClD,WAAO;AAAA,MACL,gBACE,iBACA,aAAa,SAAS,aAAa;AAAA,IACvC;AAAA,EACF;AAAA,EAEQ,iBAAgD;AACtD,UAAM,SACJ,OAAO,KAAK,QAAQ,WAAW,aAC3B,KAAK,QAAQ,OAAO,IACpB,KAAK,QAAQ;AAEnB,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,KAAK;AAAA,UACL,OAAO,OAAO;AAAA,UACd,QAAQ,OAAO;AAAA,QACjB;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,KAAK;AAAA,UACL,OAAO,OAAO;AAAA,UACd,QAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,OAAO,kBAAkB,KAAK;AAAA,QACzC,MAAM;AAAA,QACN,KAAK;AAAA,QACL,OAAO,OAAO,OAAO;AAAA,QACrB,QAAQ,OAAO,OAAO;AAAA,MACxB;AACA,YAAM,cAAc,OAAO,iBAAiB,KAAK;AACjD,YAAM,eAAe,OAAO,kBAAkB;AAE9C,aAAO;AAAA,QACL,QAAQ,OAAO;AAAA,QACf,UAAU,OAAO;AAAA,QACjB,cAAc;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,KAAK,KAAK;AAAA,UACV,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM,YAAY;AAAA,UAClB,KAAK,YAAY;AAAA,UACjB,OAAO,YAAY;AAAA,UACnB,QAAQ,YAAY;AAAA,QACtB;AAAA,QACA;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAS;AACb,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,YAAa,QAAO,KAAK;AAE9B,SAAK,QAAQ,MAAM,KAAK,QAAQ,KAAK;AAAA,MACnC,WAAW,KAAK,QAAQ;AAAA,MACxB,UAAU,YAAY,WAAW;AAAA,IACnC,CAAC;AACD,SAAK,QAAQ,gBAAgB,KAAK,KAAK;AACvC,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO;AAAA,IACd;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,SAAS;AACf,QAAI,CAAC,KAAK,OAAQ;AAElB,SAAK,KAAK,OAAO,KAAK,QAAQ,KAAK,8BAA8B,CAAC;AAAA,EACpE;AAAA,EAEA,MAAc,qBACZ,OACA,SAA0B,CAAC,GAC3B;AACA,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,YAAa;AAElB,UAAM,WAAW,gBAAgB,WAAW;AAC5C,UAAM,YAAY,WAAW,OAAO,WAAW;AAE/C,UAAM,QAAQ,MAAM,KAAK,kBAAkB,MAAM;AAC/C,YAAM,YAAY,kBAAkB,SAAS;AAC7C,YAAM,SAAS;AAAA,QACb;AAAA,QACA,KAAK,QAAQ,SAAS;AAAA,QACtB;AAAA,MACF;AACA,YAAM,SAAuB;AAAA,QAC3B,UAAU,WAAW,SAAS;AAAA,QAC9B,UAAU,SACN,iBAAiB,WAAW,QAAQ,WAAW,IAC/C;AAAA,MACN;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAG;AAAA,MACL;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAc,wBACZ,OACA,SAA0B,CAAC,GAC3B;AACA,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,YAAa;AAElB,UAAM,WAAW,gBAAgB,WAAW;AAC5C,UAAM,YAAY,WAAW,OAAO,WAAW;AAE/C,UAAM,QAAQ,MAAM,KAAK,kBAAkB,MAAM;AAC/C,YAAM,iBAAiB,kBAAkB,SAAS;AAClD,YAAM,gBAAgB,YAAY,SAAS;AAAA,QACzC,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AACA,YAAM,iBACJ,iBAAiB,WAAW,gBACvB,gBACD;AACN,YAAM,aAAa,eAAe,sBAAsB;AACxD,YAAM,mBACJ,cAAc,WAAW,QAAQ,KAAK,WAAW,SAAS,IACtD;AAAA,QACE,MAAM,WAAW;AAAA,QACjB,KAAK,WAAW;AAAA,QAChB,OAAO,WAAW;AAAA,QAClB,QAAQ,WAAW;AAAA,MACrB,IACA;AACN,YAAM,SAAS;AAAA,QACb;AAAA,QACA,KAAK,QAAQ,SAAS;AAAA,QACtB;AAAA,MACF;AACA,YAAM,mBAAmB,SACpB,oBACD,4BAA4B,QAAQ,aAAa,cAAc,IAC/D;AACJ,YAAM,YAAY,oBAAoB;AACtC,YAAM,cAAc,mBAChB,EAAE,GAAG,UAAU,MAAM,GAAG,UAAU,IAAI,IACtC,mBAAmB,SAAS;AAChC,YAAM,kBAAkB,mBACpB;AAAA,QACE,UAAU,kBAAkB,gBAAgB;AAAA,QAC5C,UAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,IACA;AACJ,YAAM,SAAuB;AAAA,QAC3B,UAAU,WAAW,WAAW;AAAA,QAChC,UAAU,SACN,iBAAiB,aAAa,QAAQ,WAAW,IACjD;AAAA,MACN;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAc,0BACZ,SACA,SAA0B,CAAC,GAC3B;AACA,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,eAAe,QAAQ,kBAAkB,YAAY,SAAU;AAEpE,UAAM,WAAW,gBAAgB,WAAW;AAE5C,UAAM,QAAQ,MAAM,KAAK,kBAAkB,MAAM;AAC/C,YAAM,OAAO,QAAQ,sBAAsB;AAC3C,UAAI,KAAK,SAAS,KAAK,KAAK,UAAU,EAAG,QAAO;AAEhD,YAAM,YAA+B;AAAA,QACnC,MAAM,KAAK;AAAA,QACX,KAAK,KAAK;AAAA,QACV,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACf;AACA,YAAM,SAAS;AAAA,QACb;AAAA,QACA,KAAK,QAAQ,SAAS;AAAA,QACtB;AAAA,MACF;AACA,YAAM,cAAc,EAAE,GAAG,UAAU,MAAM,GAAG,UAAU,IAAI;AAC1D,YAAM,SAAuB;AAAA,QAC3B,UAAU,WAAW,WAAW;AAAA,QAChC,UAAU,SACN,iBAAiB,aAAa,QAAQ,WAAW,IACjD;AAAA,MACN;AACA,YAAM,kBAAmC;AAAA,QACvC,UAAU,kBAAkB,SAAS;AAAA,QACrC,UAAU,SACN,qBAAqB,WAAW,QAAQ,WAAW,IACnD;AAAA,MACN;AACA,YAAM,iBACJ,WAAW,UAAW,UAAwC;AAEhE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,GAAG;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,CAAC,MAAO;AAEZ,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAc,gBAAgB,WAA8B;AAC1D,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,aAAa;AAChB,WAAK,kBAAkB;AACvB,WAAK,OAAO;AACZ;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,gBAAgB,WAAW;AAE5C,WAAK,YAAY,MAAM,KAAK,kBAAkB,MAAM;AAClD,cAAM,SAAS;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,cAAM,kBAAmC;AAAA,UACvC,UAAU,kBAAkB,SAAS;AAAA,QACvC;AAEA,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AACD,WAAK,aAAa,MAAM;AAAA,IAC1B,UAAE;AACA,WAAK,kBAAkB;AACvB,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,MAAc,kBAAqB,UAAgC;AACjE,QAAI,CAAC,KAAK,KAAM,QAAO,SAAS;AAEhC,UAAM,kBAAkB,KAAK,KAAK,MAAM;AACxC,SAAK,KAAK,MAAM,UAAU;AAE1B,QAAI;AAEF,aAAO,MAAM,SAAS;AAAA,IACxB,UAAE;AACA,WAAK,KAAK,MAAM,UAAU;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,OAA8B;AACrD,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,eAAe,KAAK,eAAgB;AAEzC,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,WAAW,YAAY,WAAW;AACxC,UAAM,WAAW,MAAM,YAAY,gBAAgB,WAAW;AAC9D,UAAM,YAAY,KAAK,QAAQ,QAAQ,KAAK;AAC5C,UAAM,QAAQ,MAAM,OAAO,KAAK;AAChC,UAAM,aAAa,MAAM,YAAY,KAAK,KAAK;AAC/C,UAAM,iBAAiB,KAAK,QAAQ,iBAAiB;AAAA,MACnD,CAAC,WAAW,OAAO,UAAU;AAAA,IAC/B;AACA,UAAM,OAAmB;AAAA,MACvB,IAAI,SAAS;AAAA,MACb,WAAW,KAAK,QAAQ;AAAA,MACxB;AAAA,MACA,SAAS,WAAW,WAAW;AAAA,MAC/B,aAAa,eAAe,WAAW;AAAA,MACvC,gBAAgB;AAAA,MAChB,OACE,MAAM,SACN,uBAAuB,UAAU,KAAK,QAAQ,WAAW,OAAO;AAAA,MAClE,MAAM,MAAM;AAAA,MACZ,OAAO,SAAS;AAAA,MAChB,SAAS,MAAM;AAAA,MACf;AAAA,MACA,cAAc,MAAM,gBAAgB,gBAAgB;AAAA,MACpD,WAAW,aAAa;AAAA,MACxB,QAAQ;AAAA,MACR;AAAA,MACA,kBAAkB,YAAY,OAAO,oBAAoB;AAAA,MACzD,QAAQ;AAAA,QACN,GAAG,YAAY,OAAO;AAAA,QACtB,GAAG,YAAY,OAAO;AAAA,MACxB;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,MACjB,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAEA,SAAK,aAAa;AAClB,SAAK,iBAAiB;AACtB,SAAK,OAAO;AAEZ,QAAI;AACF,YAAM,cAAc,MAAM,KAAK,QAAQ,OAAO,IAAI;AAClD,WAAK,aAAa,MAAM;AACxB,WAAK,YAAY;AACjB,WAAK,YAAY;AACjB,WAAK,cAAc,YAAY,EAAE;AACjC,YAAM,KAAK,OAAO;AAClB,YAAM,KAAK,QAAQ,eAAe,WAAW;AAAA,IAC/C,SAAS,OAAO;AACd,WAAK,aACH,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAC7C,UAAE;AACA,WAAK,iBAAiB;AACtB,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,MAAkB;AAC1C,SAAK,aAAa,MAAM;AACxB,SAAK,YAAY;AACjB,SAAK,YAAY;AAEjB,QAAI,KAAK,QAAQ,eAAe;AAC9B,YAAM,KAAK,QAAQ,cAAc,IAAI;AACrC;AAAA,IACF;AAEA,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,CAAC,YAAa;AAElB,UAAM,SAAS,KAAK;AACpB,QAAI,QAAQ;AACV,gCAA0B,YAAY,UAAU,MAAM;AACpD,mCAA2B,aAAa,MAAM;AAAA,MAChD,CAAC;AACD,YAAM,iBAAiB,WAAW;AAAA,IACpC;AAEA,SAAK,cAAc,KAAK,EAAE;AAC1B,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,uBAA+C;AACtD,SAAO;AAAA,IACL,OAAO;AAAA,IAAC;AAAA,IACR,QAAQ;AAAA,IAAC;AAAA,IACT,SAAS;AAAA,IAAC;AAAA,IACV,UAAU;AAAA,IAAC;AAAA,IACX,MAAM,qBAAqB;AAAA,IAAC;AAAA,IAC5B,UAAU;AACR,aAAO;AAAA,IACT;AAAA,IACA,gBAAgB;AAAA,IAAC;AAAA,IACjB,mBAAmB;AAAA,IAAC;AAAA,IACpB,MAAM,SAAS;AACb,aAAO,CAAC;AAAA,IACV;AAAA,IACA,WAAW;AACT,aAAO,CAAC;AAAA,IACV;AAAA,IACA,UAAU;AAAA,IAAC;AAAA,EACb;AACF;","names":["withTimeout"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/route.ts","../src/status.ts","../src/adapters/local.ts","../src/adapters/supabase.ts","../src/figma/image.types.ts","../src/vite/figma-asset.ts","../src/figma/parse.ts","../src/figma/token.ts","../src/figma/render.ts","../src/figma/image.store.ts","../src/figma/remote.image.store.ts","../src/figma/image.snapshot.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/scope.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":["export { localAdapter } from './adapters/local';\nexport { supabaseAdapter } from './adapters/supabase';\nexport {\n REVIEW_WORKFLOW_STATUS_OPTIONS,\n normalizeReviewItemStatus,\n} from './status';\nexport { DEFAULT_REVIEW_FIGMA_IMAGE_FORMAT } from './figma/image.types';\nexport {\n DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT,\n createEndpointReviewFigmaImageStore,\n createReviewFigmaImageStoreClient,\n getReviewFigmaImageMimeType,\n getReviewFigmaImageTargetKey,\n} from './figma/image.store';\nexport {\n DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE,\n createRemoteReviewFigmaImageStore,\n} from './figma/remote.image.store';\nexport {\n collectReviewFigmaReleaseSnapshot,\n createReviewFigmaImagesSnapshot,\n createReviewFigmaReleaseSnapshot,\n} from './figma/image.snapshot';\nexport {\n DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY,\n REVIEW_FIGMA_TOKEN_MISSING_CODE,\n ReviewFigmaTokenError,\n isReviewFigmaTokenError,\n readReviewFigmaToken,\n requireReviewFigmaToken,\n} from './figma/token';\nexport {\n FIGMA_NODE_REF_SEPARATOR,\n createReviewFigmaFrameUrl,\n createReviewFigmaNodeValue,\n parseReviewFigmaNodeRef,\n requireReviewFigmaNodeRef,\n} from './figma/parse';\nexport { createWebReviewKit } from './core/web.review.kit.app';\nexport {\n DEFAULT_REVIEW_VIEWPORTS,\n findReviewViewportPreset,\n getNumberedReviewItems,\n getReviewItemScope,\n getReviewItemScopeLabel,\n getReviewViewportScope,\n} from './core/review/scope';\nexport type {\n DomAnchor,\n DomAnchorCandidate,\n DomAnchorStrategy,\n DomSourceHint,\n LocalAdapterOptions,\n NumberedReviewItem,\n RelativeSelection,\n ReviewAssigneeOption,\n ReviewAttachment,\n ReviewAttachmentKind,\n ReviewAttachmentUploadError,\n ReviewAttachmentUploadErrorReason,\n ReviewAttachmentUploadInput,\n ReviewExternalLink,\n ReviewExternalLinkIcon,\n ReviewItem,\n ReviewItemKind,\n ReviewItemQuery,\n ReviewItemScope,\n ReviewItemStatus,\n ReviewSource,\n ReviewSubmitStatus,\n ReviewMarker,\n ReviewMode,\n ReviewPoint,\n ReviewRulerConfig,\n ReviewSelection,\n SupabaseReviewAdapterOptions,\n SupabaseReviewClient,\n ReviewViewportPreset,\n ReviewViewportScope,\n ReviewWorkflowStatus,\n ViewportSize,\n WebReviewKitAdapter,\n WebReviewKitController,\n WebReviewKitOptions,\n WebReviewKitTarget,\n} from './types';\nexport type {\n AddReviewFigmaImageInput,\n ReorderReviewFigmaImagesInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n ReviewFigmaImageViewport,\n ReviewFigmaNodeTarget,\n ReviewFigmaRouteTarget,\n UpdateReviewFigmaImageInput,\n} from './figma/image.types';\nexport type {\n ReviewFigmaTokenEnv,\n ReviewFigmaTokenOptions,\n} from './figma/token';\nexport type { ReviewFigmaNodeRef } from './figma/parse';\nexport type {\n RemoteReviewFigmaImageStoreOptions,\n ReviewFigmaRemoteAssetUploadResponse,\n ReviewFigmaRemoteDbClient,\n ReviewFigmaRemoteImageRow,\n} from './figma/remote.image.store';\nexport type {\n EndpointReviewFigmaImageStoreOptions,\n ReviewFigmaImageClientRenderOptions,\n ReviewFigmaImageStoreHeadersProvider,\n ReviewFigmaImageStoreClientOptions,\n} from './figma/image.store';\nexport type {\n CollectReviewFigmaReleaseSnapshotOptions,\n CreateReviewFigmaImagesSnapshotOptions,\n CreateReviewFigmaReleaseSnapshotOptions,\n ReviewFigmaImagesSnapshot,\n ReviewFigmaReleaseSnapshot,\n} from './figma/image.snapshot';\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 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 { 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","import { normalizeReviewItemStatus } from '../status';\nimport type {\n ReviewItem,\n ReviewItemKind,\n ReviewItemStatus,\n ReviewSource,\n SupabaseReviewAdapterOptions,\n WebReviewKitAdapter,\n} from '../types';\n\nconst DEFAULT_SUPABASE_REVIEW_TABLE = 'review_items';\nconst DEFAULT_SUPABASE_REVIEW_SOURCE = 'supabase';\nconst DEFAULT_SUPABASE_CREATE_REVIEW_ITEM_RPC = 'create_review_item';\n\ntype SupabaseReviewRow = {\n id: string;\n project_id: string;\n route_key: string;\n source: string;\n review_number?: number | null;\n status: string;\n item: unknown;\n created_at: string;\n updated_at: string;\n};\n\ntype SupabaseResponse<T> = {\n data: T | null;\n error: { message?: string; code?: string } | null;\n};\n\nexport function supabaseAdapter(\n options: SupabaseReviewAdapterOptions\n): WebReviewKitAdapter {\n const tableName = options.table ?? DEFAULT_SUPABASE_REVIEW_TABLE;\n const source = options.source ?? DEFAULT_SUPABASE_REVIEW_SOURCE;\n\n const fromTable = () => options.client.from(tableName);\n\n return {\n async get(id) {\n const row = await unwrapResponse<SupabaseReviewRow | null>(\n fromTable().select('*').eq('id', id).maybeSingle(),\n 'supabase get review item'\n );\n\n return row ? rowToReviewItem(row, options) : null;\n },\n\n async list(query) {\n let request = fromTable()\n .select('*')\n .eq('project_id', query.projectId)\n .eq('source', query.source ?? source);\n const routeKey = query.routeKey ?? query.normalizedPath;\n\n if (routeKey) {\n request = request.eq('route_key', routeKey);\n }\n if (query.status) {\n request = request.eq(\n 'status',\n normalizeReviewItemStatus(query.status)\n );\n }\n\n const rows = await unwrapResponse<SupabaseReviewRow[]>(\n request.order('created_at', { ascending: false }),\n 'supabase list review items'\n );\n\n return (rows ?? []).flatMap((row) => {\n const item = rowToReviewItem(row, options);\n return item ? [item] : [];\n });\n },\n\n async create(item) {\n const nextItem = normalizeItemForSupabaseCreate(item, source, options);\n\n if (options.unsafeClientReviewNumberFallback) {\n throw new Error(\n 'supabase create review item: unsafeClientReviewNumberFallback is no longer supported. Use create_review_item RPC with database-backed review_number sequence.'\n );\n }\n\n return createItemWithRpc(nextItem, source, options);\n },\n\n async update(id, patch) {\n const current = await this.get(id);\n if (!current) throw new Error(`Review item not found: ${id}`);\n\n const nextStatus = patch.status\n ? normalizeReviewItemStatus(patch.status)\n : current.status;\n const nextItem: ReviewItem = {\n ...current,\n ...patch,\n id,\n status: nextStatus,\n createdAt: current.createdAt,\n updatedAt: new Date().toISOString(),\n };\n const patchRow = itemToRowPatch(nextItem, source, options);\n const updated = await unwrapResponse<SupabaseReviewRow>(\n fromTable().update(patchRow).eq('id', id).select('*').single(),\n 'supabase update review item'\n );\n\n return rowToReviewItem(updated, options) ?? nextItem;\n },\n\n async remove(id) {\n await unwrapResponse<null>(\n fromTable().delete().eq('id', id),\n 'supabase delete review item'\n );\n },\n };\n}\n\nfunction normalizeItemForSupabaseCreate(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n): ReviewItem {\n const now = new Date().toISOString();\n const id = createSupabaseReviewItemId();\n const normalizedStatus = normalizeReviewItemStatus(item.status);\n const routeKey = item.routeKey || item.normalizedPath || '/';\n const viewport = item.viewport ?? { width: 390, height: 720 };\n const nextItem: ReviewItem = {\n ...item,\n id,\n reviewNumber: undefined,\n projectId: options.projectId,\n routeKey,\n normalizedPath: item.normalizedPath || routeKey,\n viewport,\n status: normalizedStatus,\n externalIssueId: id,\n externalIssueUrl: buildSupabaseReviewUrl(\n { routeKey, normalizedPath: item.normalizedPath || routeKey, viewport },\n source,\n options,\n id\n ),\n submittedAt: item.submittedAt ?? now,\n submitStatus: item.submitStatus ?? 'submitted',\n createdAt: now,\n updatedAt: now,\n };\n\n return {\n ...nextItem,\n externalIssueUrl:\n nextItem.externalIssueUrl ??\n buildSupabaseReviewUrl(nextItem, source, options),\n };\n}\n\nasync function createItemWithRpc(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n) {\n const rpcName =\n options.createRpc ?? DEFAULT_SUPABASE_CREATE_REVIEW_ITEM_RPC;\n\n if (!options.client.rpc) {\n throw new Error(\n `supabase create review item: ${rpcName} rpc is required`\n );\n }\n\n const row = await unwrapResponse<SupabaseReviewRow>(\n options.client.rpc(rpcName, {\n p_id: item.id,\n p_project_id: options.projectId,\n p_route_key: item.routeKey || item.normalizedPath || '/',\n p_source: source,\n p_status: normalizeReviewItemStatus(item.status),\n p_item: item,\n }),\n `supabase create review item rpc ${rpcName}`\n );\n\n return rowToReviewItem(row, options) ?? item;\n}\n\nfunction itemToRow(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n): SupabaseReviewRow {\n const now = new Date().toISOString();\n const updatedAt = item.updatedAt || now;\n\n return {\n id: item.id,\n project_id: options.projectId,\n route_key: item.routeKey || item.normalizedPath || '/',\n source,\n review_number: item.reviewNumber ?? null,\n status: normalizeReviewItemStatus(item.status),\n item: {\n ...item,\n projectId: options.projectId,\n status: normalizeReviewItemStatus(item.status),\n updatedAt,\n },\n created_at: item.createdAt || now,\n updated_at: updatedAt,\n };\n}\n\nfunction itemToRowPatch(\n item: ReviewItem,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions\n) {\n const row = itemToRow(item, source, options);\n return {\n route_key: row.route_key,\n review_number: row.review_number,\n status: row.status,\n item: row.item,\n updated_at: row.updated_at,\n };\n}\n\nfunction rowToReviewItem(\n row: SupabaseReviewRow,\n options: SupabaseReviewAdapterOptions\n): ReviewItem | null {\n if (!row.item || typeof row.item !== 'object') return null;\n\n const item = row.item as Partial<Omit<ReviewItem, 'kind'>> & {\n kind?: string;\n };\n const status = normalizeReviewItemStatus(\n (row.status || item.status || 'todo') as ReviewItemStatus\n );\n const routeKey = row.route_key || item.routeKey || item.normalizedPath || '/';\n const viewport = item.viewport ?? { width: 390, height: 720 };\n const now = new Date().toISOString();\n const kind = normalizeReviewItemKind(item);\n if (!kind) return null;\n\n return {\n ...(item as ReviewItem),\n id: row.id,\n reviewNumber: row.review_number ?? item.reviewNumber,\n projectId: row.project_id || item.projectId || options.projectId,\n routeKey,\n pageUrl: item.pageUrl || toAbsoluteReviewUrl(routeKey),\n normalizedPath: item.normalizedPath || routeKey,\n kind,\n comment: item.comment || '',\n status,\n viewport,\n externalIssueId: item.externalIssueId ?? row.id,\n externalIssueUrl:\n item.externalIssueUrl ??\n buildSupabaseReviewUrl(\n { routeKey, normalizedPath: routeKey, viewport },\n row.source,\n options,\n row.id\n ),\n submittedAt: item.submittedAt ?? row.created_at,\n submitStatus: item.submitStatus ?? 'submitted',\n createdAt: item.createdAt ?? row.created_at ?? now,\n updatedAt: row.updated_at ?? item.updatedAt ?? now,\n };\n}\n\nfunction normalizeReviewItemKind(\n item: Partial<Omit<ReviewItem, 'kind'>> & { kind?: string }\n): ReviewItemKind | null {\n if (item.kind === 'area' || item.kind === 'dom') return item.kind;\n return null;\n}\n\nasync function unwrapResponse<T>(\n request: Promise<SupabaseResponse<T>> | SupabaseResponse<T>,\n label: string\n) {\n const { data, error } = await request;\n if (error) {\n throw new Error(`${label}: ${error.message ?? error.code ?? 'failed'}`);\n }\n return data as T;\n}\n\nfunction buildSupabaseReviewUrl(\n item: Pick<ReviewItem, 'routeKey' | 'normalizedPath' | 'viewport'>,\n source: ReviewSource,\n options: SupabaseReviewAdapterOptions,\n itemId?: string\n) {\n if (typeof window === 'undefined') return undefined;\n\n const url = new URL(\n normalizeReviewUrlPath(options.reviewPathPrefix),\n window.location.origin\n );\n url.searchParams.set('source', source);\n url.searchParams.set('target', item.routeKey || item.normalizedPath || '/');\n url.searchParams.set('w', String(Math.round(item.viewport.width)));\n url.searchParams.set('h', String(Math.round(item.viewport.height)));\n if (itemId) url.searchParams.set('item', itemId);\n return url.toString();\n}\n\nfunction normalizeReviewUrlPath(value = '/review') {\n const raw = value.trim() || '/review';\n const path = raw.startsWith('/') ? raw : `/${raw}`;\n return path.endsWith('/') ? path : `${path}/`;\n}\n\nfunction toAbsoluteReviewUrl(path: string) {\n if (typeof window === 'undefined') return path;\n return new URL(path, window.location.origin).toString();\n}\n\nfunction createSupabaseReviewItemId() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n return `review-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\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","// Pure helpers for Figma image asset format conversion and storage-key handling.\n// Extracted from src/vite.ts to keep the plugin entry focused on request flow.\nimport type { ReviewFigmaImageFormat } from '../figma/image.types';\nimport type { ReviewFigmaRenderFormat } from '../figma/render';\n\nexport function parseReviewFigmaImageFormat(value: unknown) {\n return value === 'webp' || value === 'png' || value === 'jpg'\n ? value\n : undefined;\n}\n\nexport function getStoreRenderFormat(\n renderFormat: ReviewFigmaRenderFormat | undefined,\n imageFormat: ReviewFigmaImageFormat | undefined\n): Extract<ReviewFigmaRenderFormat, 'png' | 'jpg'> {\n if (renderFormat === 'jpg' || renderFormat === 'png') return renderFormat;\n if (imageFormat === 'jpg') return 'jpg';\n return 'png';\n}\n\nexport function getReviewFigmaImageFormatFromMimeType(\n mimeType: string\n): ReviewFigmaImageFormat | null {\n if (mimeType === 'image/webp') return 'webp';\n if (mimeType === 'image/png') return 'png';\n if (mimeType === 'image/jpeg') return 'jpg';\n return null;\n}\n\nexport function normalizeImageMimeType(value: string | null | undefined) {\n const mimeType = value?.split(';')[0]?.trim().toLowerCase();\n if (mimeType === 'image/jpg') return 'image/jpeg';\n if (\n mimeType === 'image/jpeg' ||\n mimeType === 'image/png' ||\n mimeType === 'image/webp'\n ) {\n return mimeType;\n }\n return null;\n}\n\nexport function createReviewFigmaAssetStorageKey(\n id: string,\n imageFormat: ReviewFigmaImageFormat\n) {\n return `${id}.${getReviewFigmaAssetExtension(imageFormat)}`;\n}\n\nexport function createReviewFigmaAssetUrl(\n assetEndpoint: string,\n storageKey: string\n) {\n return `${assetEndpoint}/${encodeURIComponent(storageKey)}`;\n}\n\nexport function getReviewFigmaAssetStorageKeyFromPathname(\n pathname: string,\n assetEndpoint: string\n) {\n try {\n const storageKey = decodeURIComponent(\n pathname.slice(assetEndpoint.length + 1)\n );\n return isSafeReviewFigmaAssetStorageKey(storageKey) ? storageKey : null;\n } catch {\n return null;\n }\n}\n\nexport function isSafeReviewFigmaAssetStorageKey(value: string) {\n return /^figma_[a-z0-9_]+\\.(webp|png|jpg)$/.test(value);\n}\n\nfunction getReviewFigmaAssetExtension(format: ReviewFigmaImageFormat) {\n return format === 'jpg' ? 'jpg' : format;\n}\n\nexport function getReviewFigmaAssetMimeType(storageKey: string) {\n if (storageKey.endsWith('.jpg')) return 'image/jpeg';\n if (storageKey.endsWith('.webp')) return 'image/webp';\n return 'image/png';\n}\n","export type ReviewFigmaNodeRef = {\n fileKey: string;\n nodeId: string;\n sourceUrl?: string;\n};\n\nexport const FIGMA_NODE_REF_SEPARATOR = '->';\n\nexport function parseReviewFigmaNodeRef(\n value: string | ReviewFigmaNodeRef\n): ReviewFigmaNodeRef | null {\n if (typeof value !== 'string') return normalizeReviewFigmaNodeRef(value);\n\n const input = value.trim();\n if (!input) return null;\n\n return parseReviewFigmaNodeRefValue(input) ?? parseReviewFigmaUrl(input);\n}\n\nexport function requireReviewFigmaNodeRef(\n value: string | ReviewFigmaNodeRef\n): ReviewFigmaNodeRef {\n const ref = parseReviewFigmaNodeRef(value);\n if (!ref) {\n throw new Error('A Figma node link or fileKey->nodeId value is required.');\n }\n return ref;\n}\n\nexport function createReviewFigmaNodeValue(ref: ReviewFigmaNodeRef) {\n return `${ref.fileKey}${FIGMA_NODE_REF_SEPARATOR}${ref.nodeId}`;\n}\n\nexport function createReviewFigmaFrameUrl(\n value: string | ReviewFigmaNodeRef\n) {\n const ref = parseReviewFigmaNodeRef(value);\n if (!ref) return null;\n\n return `https://www.figma.com/design/${encodeURIComponent(\n ref.fileKey\n )}?node-id=${encodeURIComponent(ref.nodeId.replace(/:/g, '-'))}`;\n}\n\nfunction parseReviewFigmaNodeRefValue(value: string) {\n const [fileKey, nodeId, extra] = value\n .split(FIGMA_NODE_REF_SEPARATOR)\n .map((part) => part.trim());\n\n if (!fileKey || !nodeId || extra !== undefined) return null;\n\n return normalizeReviewFigmaNodeRef({ fileKey, nodeId });\n}\n\nfunction parseReviewFigmaUrl(value: string) {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n const fileKey = getFigmaFileKey(url);\n const nodeId = normalizeFigmaNodeId(url.searchParams.get('node-id'));\n if (!fileKey || !nodeId) return null;\n\n return { fileKey, nodeId, sourceUrl: value };\n}\n\nfunction getFigmaFileKey(url: URL) {\n if (!/(^|\\.)figma\\.com$/i.test(url.hostname)) return null;\n\n const parts = url.pathname.split('/').filter(Boolean);\n const fileKeyIndex = parts.findIndex((part) =>\n ['design', 'file', 'proto', 'board'].includes(part)\n );\n const fileKey = fileKeyIndex >= 0 ? parts[fileKeyIndex + 1] : null;\n\n return normalizeFigmaFileKey(fileKey);\n}\n\nfunction normalizeReviewFigmaNodeRef(\n value: ReviewFigmaNodeRef | null | undefined\n) {\n const fileKey = normalizeFigmaFileKey(value?.fileKey);\n const nodeId = normalizeFigmaNodeId(value?.nodeId);\n if (!fileKey || !nodeId) return null;\n const sourceUrl = normalizeOptionalString(value?.sourceUrl);\n\n return sourceUrl ? { fileKey, nodeId, sourceUrl } : { fileKey, nodeId };\n}\n\nfunction normalizeFigmaFileKey(value: string | null | undefined) {\n return normalizeOptionalString(value)?.replace(/[?#].*$/, '') ?? null;\n}\n\nfunction normalizeFigmaNodeId(value: string | null | undefined) {\n const nodeId = normalizeOptionalString(value);\n if (!nodeId) return null;\n if (nodeId.includes(':')) return nodeId;\n return nodeId.replace(/-/g, ':');\n}\n\nfunction normalizeOptionalString(value: string | null | undefined) {\n if (typeof value !== 'string') return null;\n return value.trim() || null;\n}\n","export const DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY = 'FIGMA_TOKEN';\nexport const REVIEW_FIGMA_TOKEN_MISSING_CODE = 'DFWR_FIGMA_TOKEN_MISSING';\n\nexport type ReviewFigmaTokenEnv = Record<\n string,\n string | null | undefined\n>;\n\nexport type ReviewFigmaTokenOptions = {\n token?: string | null;\n env?: ReviewFigmaTokenEnv;\n envKey?: string;\n enabled?: boolean;\n};\n\nexport class ReviewFigmaTokenError extends Error {\n readonly code = REVIEW_FIGMA_TOKEN_MISSING_CODE;\n readonly envKey: string;\n\n constructor(envKey = DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY) {\n super(\n `Figma image rendering requires server env ${envKey}. Set ${envKey} in the dev/server environment; do not expose it as VITE_${envKey}.`\n );\n this.name = 'ReviewFigmaTokenError';\n this.envKey = envKey;\n }\n}\n\nexport function readReviewFigmaToken(\n options: ReviewFigmaTokenOptions = {}\n): string | null {\n if (options.enabled === false) return null;\n\n const envKey = options.envKey ?? DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY;\n return normalizeReviewFigmaToken(options.token ?? options.env?.[envKey]);\n}\n\nexport function requireReviewFigmaToken(\n options: ReviewFigmaTokenOptions = {}\n): string {\n const envKey = options.envKey ?? DEFAULT_REVIEW_FIGMA_TOKEN_ENV_KEY;\n const token = readReviewFigmaToken(options);\n\n if (!token) throw new ReviewFigmaTokenError(envKey);\n return token;\n}\n\nexport function isReviewFigmaTokenError(\n error: unknown\n): error is ReviewFigmaTokenError {\n if (!error || typeof error !== 'object') return false;\n\n return (\n error instanceof ReviewFigmaTokenError ||\n ('code' in error && error.code === REVIEW_FIGMA_TOKEN_MISSING_CODE)\n );\n}\n\nfunction normalizeReviewFigmaToken(value: string | null | undefined) {\n if (typeof value !== 'string') return null;\n return value.trim() || null;\n}\n","import {\n requireReviewFigmaNodeRef,\n type ReviewFigmaNodeRef,\n} from './parse';\nimport { requireReviewFigmaToken } from './token';\n\nexport type ReviewFigmaRenderFormat = 'png' | 'jpg' | 'svg' | 'pdf';\n\nexport type ReviewFigmaImageRenderOptions = {\n figmaUrl: string | ReviewFigmaNodeRef;\n token?: string | null;\n format?: ReviewFigmaRenderFormat;\n scale?: number;\n useAbsoluteBounds?: boolean;\n apiBaseUrl?: string;\n fetch?: typeof fetch;\n signal?: AbortSignal;\n};\n\nexport type ReviewFigmaRenderedImage = {\n fileKey: string;\n nodeId: string;\n figmaUrl?: string;\n imageUrl: string;\n renderFormat: ReviewFigmaRenderFormat;\n};\n\ntype FigmaImageResponse = {\n err?: string | null;\n images?: Record<string, string | null | undefined>;\n};\n\nconst DEFAULT_FIGMA_API_BASE_URL = 'https://api.figma.com';\n\nexport async function renderReviewFigmaImage(\n options: ReviewFigmaImageRenderOptions\n): Promise<ReviewFigmaRenderedImage> {\n const token = requireReviewFigmaToken({ token: options.token });\n const ref = requireReviewFigmaNodeRef(options.figmaUrl);\n const renderFormat = options.format ?? 'png';\n const requestUrl = createReviewFigmaImageApiUrl({\n apiBaseUrl: options.apiBaseUrl,\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n format: renderFormat,\n scale: options.scale,\n useAbsoluteBounds: options.useAbsoluteBounds,\n });\n const fetchImage = options.fetch ?? globalThis.fetch;\n if (!fetchImage) throw new Error('Figma image rendering requires fetch.');\n\n const response = await fetchImage(requestUrl, {\n headers: {\n 'X-Figma-Token': token,\n },\n signal: options.signal,\n });\n const body = (await response.json().catch(() => null)) as\n | FigmaImageResponse\n | null;\n\n if (!response.ok) {\n throw new Error(\n body?.err || `Figma image render failed with ${response.status}`\n );\n }\n\n const imageUrl = body?.images?.[ref.nodeId];\n if (!imageUrl) {\n throw new Error(`Figma image render returned no URL for ${ref.nodeId}.`);\n }\n\n return {\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n figmaUrl: typeof options.figmaUrl === 'string'\n ? options.figmaUrl\n : options.figmaUrl.sourceUrl,\n imageUrl,\n renderFormat,\n };\n}\n\nexport function createReviewFigmaImageApiUrl({\n apiBaseUrl = DEFAULT_FIGMA_API_BASE_URL,\n fileKey,\n nodeId,\n format = 'png',\n scale,\n useAbsoluteBounds,\n}: {\n apiBaseUrl?: string;\n fileKey: string;\n nodeId: string;\n format?: ReviewFigmaRenderFormat;\n scale?: number;\n useAbsoluteBounds?: boolean;\n}) {\n const url = new URL(`/v1/images/${encodeURIComponent(fileKey)}`, apiBaseUrl);\n url.searchParams.set('ids', nodeId);\n url.searchParams.set('format', format);\n\n if (typeof scale === 'number' && Number.isFinite(scale) && scale > 0) {\n url.searchParams.set('scale', String(scale));\n }\n if (useAbsoluteBounds !== undefined) {\n url.searchParams.set('use_absolute_bounds', String(useAbsoluteBounds));\n }\n\n return url.toString();\n}\n","import type {\n AddReviewFigmaImageInput,\n ReorderReviewFigmaImagesInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n} from './image.types';\nimport { getReviewFigmaImageFormatFromMimeType } from '../vite/figma-asset';\nimport { parseReviewFigmaNodeRef } from './parse';\nimport {\n createReviewFigmaImageApiUrl,\n type ReviewFigmaRenderFormat,\n} from './render';\n\nexport const DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT =\n '/__dfwr/figma-images';\n\ntype ReviewFigmaImageTokenProvider =\n | string\n | null\n | undefined\n | (() => string | null | undefined);\n\nexport type ReviewFigmaImageStoreHeadersProvider =\n | HeadersInit\n | null\n | undefined\n | (() => HeadersInit | null | undefined | Promise<HeadersInit | null | undefined>);\n\nexport type ReviewFigmaImageStoreClientOptions = {\n endpoint?: string;\n fetch?: typeof fetch;\n token?: ReviewFigmaImageTokenProvider;\n clientRender?: boolean | ReviewFigmaImageClientRenderOptions;\n};\n\nexport type EndpointReviewFigmaImageStoreOptions =\n ReviewFigmaImageStoreClientOptions & {\n headers?: ReviewFigmaImageStoreHeadersProvider;\n };\n\nexport type ReviewFigmaImageClientRenderOptions = {\n token?: string | null | (() => string | null | undefined);\n apiBaseUrl?: string;\n renderFormat?: Extract<ReviewFigmaRenderFormat, 'png' | 'jpg'>;\n renderScale?: number;\n useAbsoluteBounds?: boolean;\n convertToWebp?: boolean;\n webpQuality?: number;\n timeoutMs?: number;\n};\n\nexport type CreateReviewFigmaClientRenderedAssetOptions =\n ReviewFigmaImageClientRenderOptions & {\n figmaUrl: string;\n token: string;\n fetch?: typeof fetch;\n };\n\nexport function createReviewFigmaImageStoreClient(\n options: ReviewFigmaImageStoreClientOptions = {}\n): ReviewFigmaImageStore {\n return createEndpointReviewFigmaImageStore(options);\n}\n\nexport function createEndpointReviewFigmaImageStore(\n options: EndpointReviewFigmaImageStoreOptions = {}\n): ReviewFigmaImageStore {\n const endpoint =\n options.endpoint ?? DEFAULT_REVIEW_FIGMA_IMAGE_STORE_ENDPOINT;\n const request = createReviewFigmaImageStoreRequest(\n options.fetch,\n options.headers\n );\n\n return {\n listImages(target) {\n const url = `${endpoint}?target=${encodeURIComponent(\n JSON.stringify(target)\n )}`;\n return request<ReviewFigmaImage[]>(url);\n },\n async addImage(input) {\n const nextInput = await createClientRenderedAddImageInput(\n input,\n options.clientRender,\n options.fetch\n );\n return request<ReviewFigmaImage>(endpoint, {\n method: 'POST',\n body: JSON.stringify(nextInput),\n figmaToken: readReviewFigmaImageToken(\n options.token ?? getStoredReviewFigmaImageToken\n ),\n });\n },\n updateImage(id, patch) {\n return request<ReviewFigmaImage>(`${endpoint}/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(patch),\n });\n },\n reorderImages(input) {\n return request<ReviewFigmaImage[]>(`${endpoint}/reorder`, {\n method: 'PATCH',\n body: JSON.stringify(input),\n });\n },\n deleteImage(id) {\n return request<void>(`${endpoint}/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n },\n };\n}\n\nasync function createClientRenderedAddImageInput(\n input: AddReviewFigmaImageInput,\n clientRender: ReviewFigmaImageStoreClientOptions['clientRender'],\n fetchOption: typeof fetch | undefined\n): Promise<AddReviewFigmaImageInput> {\n const options = normalizeClientRenderOptions(clientRender);\n if (!options) return input;\n\n const token = readClientRenderToken(options);\n if (!token) return input;\n\n try {\n const asset = await createReviewFigmaClientRenderedAsset({\n ...options,\n fetch: fetchOption,\n figmaUrl: input.figmaUrl,\n token,\n });\n return {\n ...input,\n imageFormat: asset.imageFormat,\n asset,\n };\n } catch {\n return input;\n }\n}\n\nfunction normalizeClientRenderOptions(\n clientRender: ReviewFigmaImageStoreClientOptions['clientRender']\n): ReviewFigmaImageClientRenderOptions | null {\n if (!clientRender) return null;\n if (clientRender === true) return {};\n return clientRender;\n}\n\nfunction readClientRenderToken(options: ReviewFigmaImageClientRenderOptions) {\n const token =\n typeof options.token === 'function' ? options.token() : options.token;\n return typeof token === 'string' ? token.trim() : '';\n}\n\nasync function createClientRenderedFigmaAsset(\n figmaUrl: string,\n token: string,\n options: ReviewFigmaImageClientRenderOptions,\n fetchOption: typeof fetch | undefined\n): Promise<ReviewFigmaImageAssetInput> {\n const ref = parseReviewFigmaNodeRef(figmaUrl);\n if (!ref) throw new Error('A Figma node link is required.');\n\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma client rendering requires fetch.');\n\n const renderFormat = options.renderFormat ?? 'png';\n const response = await requestFetch(\n createReviewFigmaImageApiUrl({\n apiBaseUrl: options.apiBaseUrl,\n fileKey: ref.fileKey,\n nodeId: ref.nodeId,\n format: renderFormat,\n scale: options.renderScale,\n useAbsoluteBounds: options.useAbsoluteBounds,\n }),\n {\n headers: {\n 'X-Figma-Token': token,\n },\n }\n );\n const body = (await response.json().catch(() => null)) as\n | { err?: string | null; images?: Record<string, string | null | undefined> }\n | null;\n if (!response.ok) {\n throw new Error(body?.err || `Figma image render failed with ${response.status}`);\n }\n\n const imageUrl = body?.images?.[ref.nodeId];\n if (!imageUrl) throw new Error(`Figma image render returned no URL for ${ref.nodeId}.`);\n\n const imageResponse = await requestFetch(imageUrl);\n if (!imageResponse.ok) {\n throw new Error(`Figma image download failed with ${imageResponse.status}`);\n }\n\n const originalBlob = await imageResponse.blob();\n const originalMimeType =\n normalizeClientImageMimeType(originalBlob.type) ??\n getReviewFigmaImageMimeType(renderFormat === 'jpg' ? 'jpg' : 'png');\n const originalFormat =\n getReviewFigmaImageFormatFromMimeType(originalMimeType) ??\n (renderFormat === 'jpg' ? 'jpg' : 'png');\n const dimensions = await readImageBlobDimensions(originalBlob);\n const shouldConvertToWebp = options.convertToWebp ?? true;\n const convertedBlob = shouldConvertToWebp\n ? await convertImageBlobToWebp(\n originalBlob,\n options.webpQuality ?? 0.9,\n dimensions\n ).catch(() => null)\n : null;\n const finalBlob =\n convertedBlob?.type === 'image/webp' ? convertedBlob : originalBlob;\n const finalMimeType =\n normalizeClientImageMimeType(finalBlob.type) ?? originalMimeType;\n const finalFormat =\n getReviewFigmaImageFormatFromMimeType(finalMimeType) ?? originalFormat;\n\n return {\n dataUrl: await blobToDataUrl(finalBlob),\n imageFormat: finalFormat,\n mimeType: finalMimeType,\n byteSize: finalBlob.size,\n width: dimensions.width,\n height: dimensions.height,\n };\n}\n\nexport function createReviewFigmaClientRenderedAsset({\n fetch: fetchOption,\n figmaUrl,\n token,\n ...options\n}: CreateReviewFigmaClientRenderedAssetOptions): Promise<ReviewFigmaImageAssetInput> {\n return withTimeout(\n createClientRenderedFigmaAsset(figmaUrl, token, options, fetchOption),\n options.timeoutMs ?? 10000\n );\n}\n\nasync function readImageBlobDimensions(blob: Blob) {\n const image = await loadImageBlob(blob);\n return {\n width: image.naturalWidth || image.width,\n height: image.naturalHeight || image.height,\n };\n}\n\nasync function convertImageBlobToWebp(\n blob: Blob,\n quality: number,\n dimensions: { width: number; height: number }\n) {\n if (typeof document === 'undefined') return null;\n if (!dimensions.width || !dimensions.height) return null;\n\n const image = await loadImageBlob(blob);\n const canvas = document.createElement('canvas');\n canvas.width = dimensions.width;\n canvas.height = dimensions.height;\n const context = canvas.getContext('2d');\n if (!context) return null;\n\n context.drawImage(image, 0, 0);\n\n return new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, 'image/webp', quality);\n });\n}\n\nfunction loadImageBlob(blob: Blob) {\n return new Promise<HTMLImageElement>((resolve, reject) => {\n if (typeof Image === 'undefined' || typeof URL === 'undefined') {\n reject(new Error('Image decoding is unavailable.'));\n return;\n }\n\n const image = new Image();\n const objectUrl = URL.createObjectURL(blob);\n image.onload = () => {\n URL.revokeObjectURL(objectUrl);\n resolve(image);\n };\n image.onerror = () => {\n URL.revokeObjectURL(objectUrl);\n reject(new Error('Image decoding failed.'));\n };\n image.src = objectUrl;\n });\n}\n\nfunction blobToDataUrl(blob: Blob) {\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n if (typeof reader.result === 'string') {\n resolve(reader.result);\n return;\n }\n reject(new Error('Blob encoding failed.'));\n };\n reader.onerror = () => reject(reader.error ?? new Error('Blob encoding failed.'));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction normalizeClientImageMimeType(value: string | null | undefined) {\n const mimeType = value?.split(';')[0]?.trim().toLowerCase();\n if (mimeType === 'image/jpg') return 'image/jpeg';\n if (\n mimeType === 'image/jpeg' ||\n mimeType === 'image/png' ||\n mimeType === 'image/webp'\n ) {\n return mimeType;\n }\n return null;\n}\n\nasync function withTimeout<T>(promise: Promise<T>, timeoutMs: number) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error('Figma client rendering timed out.')),\n timeoutMs\n );\n }),\n ]);\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n}\n\nexport function getReviewFigmaImageTargetKey(target: ReviewFigmaImageTarget) {\n return JSON.stringify(normalizeReviewFigmaImageTarget(target));\n}\n\nexport function getReviewFigmaImageMimeType(\n format: ReviewFigmaImageFormat\n) {\n if (format === 'jpg') return 'image/jpeg';\n if (format === 'png') return 'image/png';\n return 'image/webp';\n}\n\ntype ReviewFigmaImageStoreRequestInit = RequestInit & {\n figmaToken?: string;\n};\n\nfunction createReviewFigmaImageStoreRequest(\n fetchOption: typeof fetch | undefined,\n headersProvider: ReviewFigmaImageStoreHeadersProvider\n) {\n return async <T>(\n input: string,\n init: ReviewFigmaImageStoreRequestInit = {}\n ) => {\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma image store requires fetch.');\n const figmaToken = init.figmaToken ?? '';\n const {\n figmaToken: _figmaToken,\n headers: requestHeaders,\n ...requestInit\n } = init;\n const headers = new Headers();\n headers.set('Content-Type', 'application/json');\n if (figmaToken) headers.set('X-Figma-Token', figmaToken);\n appendReviewFigmaImageStoreHeaders(\n headers,\n await readReviewFigmaImageStoreHeaders(headersProvider)\n );\n appendReviewFigmaImageStoreHeaders(headers, requestHeaders);\n\n const response = await requestFetch(input, {\n ...requestInit,\n headers,\n });\n const text = await response.text();\n const body = text ? JSON.parse(text) : null;\n\n if (!response.ok) {\n const message =\n typeof body?.error === 'string'\n ? body.error\n : `Figma image store request failed: ${response.status}`;\n throw new Error(message);\n }\n\n return body as T;\n };\n}\n\nasync function readReviewFigmaImageStoreHeaders(\n provider: ReviewFigmaImageStoreHeadersProvider\n) {\n return typeof provider === 'function' ? provider() : provider;\n}\n\nfunction appendReviewFigmaImageStoreHeaders(\n target: Headers,\n source: HeadersInit | null | undefined\n) {\n if (!source) return;\n new Headers(source).forEach((value, key) => {\n target.set(key, value);\n });\n}\n\nfunction readReviewFigmaImageToken(provider: ReviewFigmaImageTokenProvider) {\n const token = typeof provider === 'function' ? provider() : provider;\n return typeof token === 'string' ? token.trim() : '';\n}\n\nfunction getStoredReviewFigmaImageToken() {\n if (typeof window === 'undefined') return '';\n\n try {\n return window.localStorage.getItem('figma-token') ?? '';\n } catch {\n return '';\n }\n}\n\nfunction normalizeReviewFigmaImageTarget(target: ReviewFigmaImageTarget) {\n if (target.type === 'figma-node') {\n return {\n type: target.type,\n projectId: target.projectId,\n fileKey: target.fileKey,\n nodeId: target.nodeId,\n };\n }\n\n return {\n type: target.type,\n projectId: target.projectId,\n pageUrl: target.pageUrl,\n slot: target.slot ?? '',\n viewport: target.viewport\n ? {\n label: target.viewport.label ?? '',\n width: target.viewport.width ?? null,\n height: target.viewport.height ?? null,\n scope: target.viewport.scope ?? '',\n }\n : null,\n };\n}\n\nexport type { ReorderReviewFigmaImagesInput };\n","import type {\n AddReviewFigmaImageInput,\n ReviewFigmaImage,\n ReviewFigmaImageAssetInput,\n ReviewFigmaImageFormat,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n UpdateReviewFigmaImageInput,\n} from './image.types';\nimport {\n createReviewFigmaClientRenderedAsset,\n getReviewFigmaImageTargetKey,\n type ReviewFigmaImageClientRenderOptions,\n} from './image.store';\nimport { parseReviewFigmaNodeRef } from './parse';\n\nexport const DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE = 'review_figma_images';\nconst DEFAULT_REVIEW_FIGMA_REMOTE_UPLOAD_TIMEOUT_MS = 30000;\nconst FIGMA_TOKEN_STORAGE_KEY = 'figma-token';\n\ntype ReviewFigmaRemoteTokenProvider =\n | string\n | null\n | undefined\n | (() => string | null | undefined);\n\nexport type ReviewFigmaRemoteImageRow = {\n id: string;\n project_id: string;\n target_key: string;\n target: ReviewFigmaImageTarget;\n target_type: 'route' | 'figma-node';\n page_url: string | null;\n viewport_label: string | null;\n viewport_width: number | null;\n viewport_height: number | null;\n viewport_scope: 'mobile' | 'tablet' | 'desktop' | 'wide' | null;\n slot: string | null;\n figma_url: string;\n file_key: string;\n node_id: string;\n image_url: string;\n image_format: ReviewFigmaImageFormat;\n mime_type: string;\n storage_key: string;\n label: string | null;\n sort_order: number;\n width: number | null;\n height: number | null;\n byte_size: number | null;\n created_at: string;\n updated_at: string;\n};\n\ntype ReviewFigmaRemoteDbResult<T = unknown> = {\n data: T | null;\n error: unknown;\n};\n\ntype ReviewFigmaRemoteDbQuery<T = unknown> = PromiseLike<\n ReviewFigmaRemoteDbResult<T>\n> & {\n delete(): ReviewFigmaRemoteDbQuery<T>;\n eq(column: string, value: unknown): ReviewFigmaRemoteDbQuery<T>;\n insert(value: unknown): ReviewFigmaRemoteDbQuery<T>;\n order(\n column: string,\n options?: { ascending?: boolean }\n ): ReviewFigmaRemoteDbQuery<T>;\n select(columns?: string): ReviewFigmaRemoteDbQuery<T>;\n single(): PromiseLike<ReviewFigmaRemoteDbResult<T>>;\n update(value: unknown): ReviewFigmaRemoteDbQuery<T>;\n};\n\nexport type ReviewFigmaRemoteDbClient = {\n from(table: string): ReviewFigmaRemoteDbQuery;\n};\n\nexport type ReviewFigmaRemoteAssetUploadResponse = {\n storageKey?: unknown;\n r2Key?: unknown;\n imageUrl?: unknown;\n publicUrl?: unknown;\n error?: unknown;\n};\n\nexport type RemoteReviewFigmaImageStoreOptions = {\n client: ReviewFigmaRemoteDbClient;\n uploadEndpoint: string;\n table?: string;\n fetch?: typeof fetch;\n token?: ReviewFigmaRemoteTokenProvider;\n clientRender?: boolean | ReviewFigmaImageClientRenderOptions;\n uploadTimeoutMs?: number;\n};\n\nexport function createRemoteReviewFigmaImageStore({\n client,\n uploadEndpoint,\n table = DEFAULT_REVIEW_FIGMA_REMOTE_IMAGES_TABLE,\n fetch: fetchOption,\n token,\n clientRender = true,\n uploadTimeoutMs = DEFAULT_REVIEW_FIGMA_REMOTE_UPLOAD_TIMEOUT_MS,\n}: RemoteReviewFigmaImageStoreOptions): ReviewFigmaImageStore {\n const listImages = async (target: ReviewFigmaImageTarget) => {\n const targetKey = getReviewFigmaImageTargetKey(target);\n const { data, error } = await client\n .from(table)\n .select('*')\n .eq('project_id', target.projectId)\n .eq('target_key', targetKey)\n .order('sort_order', { ascending: true })\n .order('created_at', { ascending: true });\n\n if (error) throwRemoteStoreError(error, 'list Figma images');\n return ((data ?? []) as ReviewFigmaRemoteImageRow[]).map(rowToFigmaImage);\n };\n\n return {\n listImages,\n async addImage(input) {\n const ref = parseReviewFigmaNodeRef(input.figmaUrl);\n if (!ref) {\n throw new Error('A Figma node link or fileKey->nodeId value is required.');\n }\n\n const id = createFigmaImageId();\n const asset = await resolveFigmaImageAsset({\n input,\n token,\n clientRender,\n fetch: fetchOption,\n });\n const uploaded = await uploadFigmaAsset({\n asset,\n endpoint: uploadEndpoint,\n fetch: fetchOption,\n imageId: id,\n projectId: input.target.projectId,\n timeoutMs: uploadTimeoutMs,\n });\n const order =\n typeof input.order === 'number' && Number.isFinite(input.order)\n ? input.order\n : await getNextImageOrder(listImages, input.target);\n const now = new Date().toISOString();\n const row = createImageRow({\n asset,\n fileKey: ref.fileKey,\n id,\n imageUrl: uploaded.imageUrl,\n input,\n nodeId: ref.nodeId,\n now,\n order,\n storageKey: uploaded.storageKey,\n });\n const { data, error } = await client\n .from(table)\n .insert(row)\n .select('*')\n .single();\n\n if (error) throwRemoteStoreError(error, 'insert Figma image');\n return rowToFigmaImage(data as ReviewFigmaRemoteImageRow);\n },\n async updateImage(id, patch) {\n const { data, error } = await client\n .from(table)\n .update(createUpdatePatch(patch))\n .eq('id', id)\n .select('*')\n .single();\n\n if (error) throwRemoteStoreError(error, 'update Figma image');\n return rowToFigmaImage(data as ReviewFigmaRemoteImageRow);\n },\n async reorderImages(input) {\n const current = await listImages(input.target);\n const currentIds = new Set(current.map((image) => image.id));\n const nextIds = [\n ...input.imageIds.filter((id) => currentIds.has(id)),\n ...current\n .map((image) => image.id)\n .filter((id) => !input.imageIds.includes(id)),\n ];\n const targetKey = getReviewFigmaImageTargetKey(input.target);\n const updatedAt = new Date().toISOString();\n\n const results = await Promise.all(\n nextIds.map((id, index) =>\n client\n .from(table)\n .update({ sort_order: index, updated_at: updatedAt })\n .eq('id', id)\n .eq('project_id', input.target.projectId)\n .eq('target_key', targetKey)\n )\n );\n const failed = results.find((result) => result.error);\n if (failed?.error) throwRemoteStoreError(failed.error, 'reorder Figma images');\n\n return listImages(input.target);\n },\n async deleteImage(id) {\n const { error } = await client.from(table).delete().eq('id', id);\n if (error) throwRemoteStoreError(error, 'delete Figma image');\n },\n };\n}\n\nasync function resolveFigmaImageAsset({\n input,\n token,\n clientRender,\n fetch,\n}: {\n input: AddReviewFigmaImageInput;\n token: ReviewFigmaRemoteTokenProvider;\n clientRender: boolean | ReviewFigmaImageClientRenderOptions;\n fetch: typeof globalThis.fetch | undefined;\n}) {\n if (input.asset) return input.asset;\n if (!clientRender) {\n throw new Error('Figma image asset is required when clientRender is disabled.');\n }\n\n const renderOptions = clientRender === true ? {} : clientRender;\n const figmaToken = readRemoteFigmaToken(renderOptions.token ?? token);\n if (!figmaToken) throw new Error('Figma token is required.');\n\n return createReviewFigmaClientRenderedAsset({\n ...renderOptions,\n fetch,\n figmaUrl: input.figmaUrl,\n token: figmaToken,\n });\n}\n\nasync function uploadFigmaAsset({\n asset,\n endpoint,\n fetch: fetchOption,\n imageId,\n projectId,\n timeoutMs,\n}: {\n asset: ReviewFigmaImageAssetInput;\n endpoint: string;\n fetch: typeof globalThis.fetch | undefined;\n imageId: string;\n projectId: string;\n timeoutMs: number;\n}) {\n const requestFetch = fetchOption ?? globalThis.fetch;\n if (!requestFetch) throw new Error('Figma asset upload requires fetch.');\n\n const { blob, mimeType } = decodeAssetDataUrl(asset);\n const response = await withTimeout(\n requestFetch(\n createAssetUploadUrl(endpoint, {\n imageFormat: asset.imageFormat,\n imageId,\n projectId,\n }),\n {\n method: 'POST',\n headers: {\n 'Content-Type': mimeType,\n },\n body: blob,\n }\n ),\n timeoutMs,\n 'Figma asset upload timed out.'\n );\n const data = (await response.json().catch(() => null)) as\n | ReviewFigmaRemoteAssetUploadResponse\n | null;\n\n if (!response.ok) {\n throw new Error(\n readString(data?.error) || `Figma asset upload failed with ${response.status}`\n );\n }\n\n const storageKey = readString(data?.storageKey) ?? readString(data?.r2Key);\n const imageUrl = readString(data?.imageUrl) ?? readString(data?.publicUrl);\n if (!storageKey || !imageUrl) {\n throw new Error('Figma asset upload response is missing image URL.');\n }\n\n return { storageKey, imageUrl };\n}\n\nfunction createAssetUploadUrl(\n endpoint: string,\n params: {\n imageFormat: ReviewFigmaImageFormat;\n imageId: string;\n projectId: string;\n }\n) {\n const base =\n typeof window !== 'undefined' ? window.location.origin : 'http://localhost';\n const url = new URL(endpoint, base);\n url.searchParams.set('projectId', params.projectId);\n url.searchParams.set('imageId', params.imageId);\n url.searchParams.set('imageFormat', params.imageFormat);\n return url.toString();\n}\n\nfunction createImageRow({\n asset,\n fileKey,\n id,\n imageUrl,\n input,\n nodeId,\n now,\n order,\n storageKey,\n}: {\n asset: ReviewFigmaImageAssetInput;\n fileKey: string;\n id: string;\n imageUrl: string;\n input: AddReviewFigmaImageInput;\n nodeId: string;\n now: string;\n order: number;\n storageKey: string;\n}): ReviewFigmaRemoteImageRow {\n const target = input.target;\n const targetKey = getReviewFigmaImageTargetKey(target);\n\n return {\n id,\n project_id: target.projectId,\n target_key: targetKey,\n target,\n target_type: target.type,\n page_url: target.type === 'route' ? target.pageUrl : null,\n viewport_label: target.type === 'route' ? target.viewport?.label ?? null : null,\n viewport_width: target.type === 'route' ? target.viewport?.width ?? null : null,\n viewport_height: target.type === 'route' ? target.viewport?.height ?? null : null,\n viewport_scope: target.type === 'route' ? target.viewport?.scope ?? null : null,\n slot: target.type === 'route' ? target.slot ?? null : null,\n figma_url: input.figmaUrl,\n file_key: fileKey,\n node_id: nodeId,\n image_url: imageUrl,\n image_format: asset.imageFormat,\n mime_type: asset.mimeType,\n storage_key: storageKey,\n label: normalizeOptionalText(input.label) ?? null,\n sort_order: order,\n width: asset.width ?? null,\n height: asset.height ?? null,\n byte_size: asset.byteSize ?? null,\n created_at: now,\n updated_at: now,\n };\n}\n\nfunction createUpdatePatch(patch: UpdateReviewFigmaImageInput) {\n return {\n ...(patch.label !== undefined\n ? { label: normalizeOptionalText(patch.label) ?? null }\n : {}),\n ...(typeof patch.order === 'number' && Number.isFinite(patch.order)\n ? { sort_order: patch.order }\n : {}),\n updated_at: new Date().toISOString(),\n };\n}\n\nasync function getNextImageOrder(\n listImages: (target: ReviewFigmaImageTarget) => Promise<ReviewFigmaImage[]>,\n target: ReviewFigmaImageTarget\n) {\n const images = await listImages(target);\n return images.length\n ? Math.max(...images.map((image) => image.order)) + 1\n : 0;\n}\n\nfunction rowToFigmaImage(row: ReviewFigmaRemoteImageRow): ReviewFigmaImage {\n return {\n id: row.id,\n projectId: row.project_id,\n target: row.target,\n figmaUrl: row.figma_url,\n fileKey: row.file_key,\n nodeId: row.node_id,\n imageUrl: row.image_url,\n imageFormat: row.image_format,\n mimeType: row.mime_type,\n label: row.label ?? undefined,\n order: row.sort_order,\n storageKey: row.storage_key,\n width: row.width ?? undefined,\n height: row.height ?? undefined,\n byteSize: row.byte_size ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction decodeAssetDataUrl(asset: ReviewFigmaImageAssetInput) {\n const match = asset.dataUrl.match(/^data:([^;,]+);base64,(.*)$/);\n if (!match) throw new Error('Valid Figma image asset data URL is required.');\n\n const mimeType = match[1]?.trim();\n if (!mimeType || mimeType !== asset.mimeType) {\n throw new Error('Figma image asset MIME type mismatch.');\n }\n\n const binary = globalThis.atob(match[2] ?? '');\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n\n return {\n blob: new Blob([bytes], { type: mimeType }),\n mimeType,\n };\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message: string\n) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<T>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(message)), timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n}\n\nfunction readRemoteFigmaToken(provider: ReviewFigmaRemoteTokenProvider) {\n const token = typeof provider === 'function' ? provider() : provider;\n if (typeof token === 'string' && token.trim()) return token.trim();\n return readStoredFigmaToken();\n}\n\nfunction readStoredFigmaToken() {\n if (typeof window === 'undefined') return '';\n\n try {\n return window.localStorage.getItem(FIGMA_TOKEN_STORAGE_KEY)?.trim() || '';\n } catch {\n return '';\n }\n}\n\nfunction createFigmaImageId() {\n const id =\n globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n return `figma_${id.replace(/[^A-Za-z0-9_-]+/g, '-')}`;\n}\n\nfunction normalizeOptionalText(value: string | null | undefined) {\n if (typeof value !== 'string') return undefined;\n return value.trim() || undefined;\n}\n\nfunction readString(value: unknown) {\n return typeof value === 'string' && value.trim() ? value.trim() : null;\n}\n\nfunction throwRemoteStoreError(error: unknown, action: string): never {\n const source = error as {\n code?: unknown;\n details?: unknown;\n hint?: unknown;\n message?: unknown;\n };\n const message = readString(source.message) ?? `Remote Figma image ${action} failed.`;\n const code = readString(source.code);\n const details = readString(source.details);\n const hint = readString(source.hint);\n const suffix = [code, details, hint].filter(Boolean).join(' / ');\n\n throw new Error(suffix ? `${message} (${suffix})` : message);\n}\n","import type {\n ReviewFigmaImage,\n ReviewFigmaImageStore,\n ReviewFigmaImageTarget,\n} from './image.types';\nimport { getReviewFigmaImageTargetKey } from './image.store';\n\nexport type ReviewFigmaImagesSnapshot = ReviewFigmaImage[];\n\nexport type ReviewFigmaReleaseSnapshot = {\n version: 1;\n projectId: string;\n releaseId?: string;\n label?: string;\n createdAt: string;\n figmaImagesSnapshot: ReviewFigmaImagesSnapshot;\n};\n\nexport type CreateReviewFigmaImagesSnapshotOptions = {\n projectId?: string;\n targets?: readonly ReviewFigmaImageTarget[];\n};\n\nexport type CreateReviewFigmaReleaseSnapshotOptions =\n CreateReviewFigmaImagesSnapshotOptions & {\n images: readonly ReviewFigmaImage[];\n projectId: string;\n releaseId?: string;\n label?: string;\n createdAt?: string;\n };\n\nexport type CollectReviewFigmaReleaseSnapshotOptions = Omit<\n CreateReviewFigmaReleaseSnapshotOptions,\n 'images'\n> & {\n store: ReviewFigmaImageStore;\n targets: readonly ReviewFigmaImageTarget[];\n};\n\nexport function createReviewFigmaImagesSnapshot(\n images: readonly ReviewFigmaImage[],\n options: CreateReviewFigmaImagesSnapshotOptions = {}\n): ReviewFigmaImagesSnapshot {\n const targetKeys = options.targets?.length\n ? new Set(options.targets.map(getReviewFigmaImageTargetKey))\n : null;\n\n return images\n .filter((image) => {\n if (options.projectId && image.projectId !== options.projectId) {\n return false;\n }\n if (\n targetKeys &&\n !targetKeys.has(getReviewFigmaImageTargetKey(image.target))\n ) {\n return false;\n }\n return true;\n })\n .map(cloneReviewFigmaImage)\n .sort(compareReviewFigmaSnapshotImages);\n}\n\nexport function createReviewFigmaReleaseSnapshot({\n images,\n projectId,\n releaseId,\n label,\n createdAt,\n targets,\n}: CreateReviewFigmaReleaseSnapshotOptions): ReviewFigmaReleaseSnapshot {\n return {\n version: 1,\n projectId,\n ...(releaseId ? { releaseId } : null),\n ...(label ? { label } : null),\n createdAt: createdAt ?? new Date().toISOString(),\n figmaImagesSnapshot: createReviewFigmaImagesSnapshot(images, {\n projectId,\n targets,\n }),\n };\n}\n\nexport async function collectReviewFigmaReleaseSnapshot({\n store,\n targets,\n ...snapshotOptions\n}: CollectReviewFigmaReleaseSnapshotOptions): Promise<ReviewFigmaReleaseSnapshot> {\n const imagesByTarget = await Promise.all(\n targets.map((target) => store.listImages(target))\n );\n\n return createReviewFigmaReleaseSnapshot({\n ...snapshotOptions,\n targets,\n images: dedupeReviewFigmaImages(imagesByTarget.flat()),\n });\n}\n\nfunction dedupeReviewFigmaImages(images: readonly ReviewFigmaImage[]) {\n return Array.from(new Map(images.map((image) => [image.id, image])).values());\n}\n\nfunction cloneReviewFigmaImage(image: ReviewFigmaImage): ReviewFigmaImage {\n return {\n ...image,\n target: cloneReviewFigmaImageTarget(image.target),\n };\n}\n\nfunction cloneReviewFigmaImageTarget(\n target: ReviewFigmaImageTarget\n): ReviewFigmaImageTarget {\n if (target.type === 'figma-node') {\n return {\n type: target.type,\n projectId: target.projectId,\n fileKey: target.fileKey,\n nodeId: target.nodeId,\n };\n }\n\n return {\n type: target.type,\n projectId: target.projectId,\n pageUrl: target.pageUrl,\n slot: target.slot,\n viewport: target.viewport\n ? {\n label: target.viewport.label,\n width: target.viewport.width,\n height: target.viewport.height,\n scope: target.viewport.scope,\n }\n : undefined,\n };\n}\n\nfunction compareReviewFigmaSnapshotImages(\n a: ReviewFigmaImage,\n b: ReviewFigmaImage\n) {\n return (\n a.projectId.localeCompare(b.projectId) ||\n getReviewFigmaImageTargetKey(a.target).localeCompare(\n getReviewFigmaImageTargetKey(b.target)\n ) ||\n a.order - b.order ||\n a.createdAt.localeCompare(b.createdAt) ||\n a.id.localeCompare(b.id)\n );\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 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 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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","names":["withTimeout","nextDraft"]}