reflet-sdk 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/client-BYuSKJw5.js.map +1 -1
- package/dist/{client-DR_mRfak.d.ts → client-BpEYxx4d.d.ts} +2 -2
- package/dist/{client-DR_mRfak.d.ts.map → client-BpEYxx4d.d.ts.map} +1 -1
- package/dist/feedback.d.ts +17 -7
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +2174 -1147
- package/dist/feedback.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/{types-Dp37I5ES.d.ts → types-wANRMsGI.d.ts} +2 -2
- package/dist/{types-Dp37I5ES.d.ts.map → types-wANRMsGI.d.ts.map} +1 -1
- package/package.json +2 -1
package/dist/feedback.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback.js","names":["toBlob","MAX_TEXT_LENGTH","truncate"],"sources":["../src/feedback/core/capture.ts","../src/feedback/core/react-source.ts","../src/feedback/core/redact.ts","../src/feedback/core/element-selector.ts","../src/feedback/core/page-context.ts","../src/feedback/types.ts","../src/feedback/core/annotations.ts","../src/feedback/core/annotation-renderer.ts","../src/feedback/ui/icons.tsx","../src/feedback/ui/annotator.tsx","../src/feedback/ui/launcher.tsx","../src/feedback/ui/panel.tsx","../src/feedback/ui/picker.tsx","../src/feedback/ui/styles.ts","../src/feedback/ui/shadow-portal.tsx","../src/feedback/core/console-recorder.ts","../src/feedback/core/element-capture.ts","../src/feedback/core/submit.ts","../src/feedback/ui/use-capture-sync.ts","../src/feedback/ui/use-widget-state.ts","../src/feedback/widget.tsx"],"sourcesContent":["import type { CapturedImage } from \"../types\";\n\n/** Marks every node the widget owns, so captures never include the panel. */\nexport const WIDGET_MARKER = \"data-reflet-widget\";\n\nconst MAX_PIXEL_RATIO = 2;\nconst DEFAULT_MAX_WIDTH = 2400;\n\nexport interface CaptureOptions {\n /** Capture this element instead of the visible viewport. */\n element?: Element;\n excludeSelectors?: string[];\n maxWidth?: number;\n}\n\ninterface SnapdomOptions {\n cache: \"disabled\";\n clip?: \"viewport\";\n dpr: number;\n embedFonts: boolean;\n exclude: string[];\n fast: boolean;\n reconcile: boolean;\n}\n\nexport function buildSnapdomOptions(options: {\n devicePixelRatio?: number;\n element?: Element;\n excludeSelectors?: string[];\n}): SnapdomOptions {\n const ratio = options.devicePixelRatio ?? 1;\n\n return {\n cache: \"disabled\",\n clip: options.element ? undefined : \"viewport\",\n dpr: Math.min(Math.max(ratio || 1, 1), MAX_PIXEL_RATIO),\n embedFonts: true,\n exclude: [`[${WIDGET_MARKER}]`, ...(options.excludeSelectors ?? [])],\n fast: true,\n reconcile: true,\n };\n}\n\nexport function fitWithin(\n size: { height: number; width: number },\n maxWidth: number\n): { height: number; scale: number; width: number } {\n if (size.width <= maxWidth) {\n return { height: size.height, scale: 1, width: size.width };\n }\n\n const scale = maxWidth / size.width;\n return {\n height: Math.max(1, Math.round(size.height * scale)),\n scale,\n width: maxWidth,\n };\n}\n\nfunction toBlob(canvas: HTMLCanvasElement): Promise<Blob | null> {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, \"image/png\");\n });\n}\n\nfunction downscale(\n canvas: HTMLCanvasElement,\n target: { height: number; width: number }\n): HTMLCanvasElement {\n const resized = document.createElement(\"canvas\");\n resized.width = target.width;\n resized.height = target.height;\n\n const context = resized.getContext(\"2d\");\n if (!context) {\n return canvas;\n }\n\n context.imageSmoothingQuality = \"high\";\n context.drawImage(canvas, 0, 0, target.width, target.height);\n return resized;\n}\n\n/** Wraps a rendered canvas as an owned capture, downscaled to `maxWidth`. */\nexport async function capturedFromCanvas(\n source: HTMLCanvasElement,\n maxWidth: number\n): Promise<CapturedImage | null> {\n const fitted = fitWithin(\n { height: source.height, width: source.width },\n maxWidth\n );\n const output = fitted.scale === 1 ? source : downscale(source, fitted);\n\n const blob = await toBlob(output);\n if (!blob) {\n return null;\n }\n\n return {\n blob,\n height: output.height,\n mimeType: \"image/png\",\n objectUrl: URL.createObjectURL(blob),\n width: output.width,\n };\n}\n\n/**\n * Renders what the user is looking at right now.\n *\n * Runs off the DOM rather than `getDisplayMedia` on purpose: a screen-share\n * permission prompt on every report would cost more reports than it captures.\n * Returns null instead of throwing — a screenshot is never worth losing the\n * written feedback.\n */\nexport async function captureViewport(\n options: CaptureOptions = {}\n): Promise<CapturedImage | null> {\n try {\n const { snapdom } = await import(\"@zumer/snapdom\");\n const target = options.element ?? document.documentElement;\n\n const canvas = await snapdom.toCanvas(\n target,\n buildSnapdomOptions({\n devicePixelRatio: window.devicePixelRatio,\n element: options.element,\n excludeSelectors: options.excludeSelectors,\n })\n );\n\n return await capturedFromCanvas(\n canvas,\n options.maxWidth ?? DEFAULT_MAX_WIDTH\n );\n } catch {\n return null;\n }\n}\n\nexport function releaseCapture(image: CapturedImage | null | undefined): void {\n if (image) {\n URL.revokeObjectURL(image.objectUrl);\n }\n}\n","const FIBER_KEY_PREFIXES = [\"__reactFiber$\", \"__reactInternalInstance$\"];\nconst MEMO_TYPE = Symbol.for(\"react.memo\");\nconst FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\n\nconst MAX_STACK_DEPTH = 6;\nconst MAX_FIBER_WALK = 60;\nconst MAX_OWNER_WALK = 8;\nconst MIN_NAME_LENGTH = 4;\nconst CAPITALIZED = /^[A-Z]/;\nconst WORD_INSIDE = /[a-z]{2}/;\n\nconst ORIGIN_PREFIX = /^[a-z][\\w+.-]*:\\/\\/[^/]*/i;\nconst WEBPACK_PREFIX = /^webpack-internal:\\/{2,}(\\.\\/)?/;\nconst STACK_LOCATION = /([^\\s()]+):(\\d+):(\\d+)\\)?\\s*$/;\nconst NON_SOURCE_FRAME =\n /node_modules|\\/_next\\/|\\/chunks?\\/|\\/\\.vite\\/|\\/dist\\/|\\/build\\/|hot-update/;\nconst SOURCE_EXTENSION = /\\.(?:[cm]?[jt]sx?)$/;\nconst SOURCE_ROOT_MARKERS = [\n \"src\",\n \"app\",\n \"pages\",\n \"components\",\n \"features\",\n \"lib\",\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** React attaches the fiber under a randomly suffixed key on the host node. */\nexport function getFiberFromNode(node: Node): unknown {\n for (const key of Object.getOwnPropertyNames(node)) {\n for (const prefix of FIBER_KEY_PREFIXES) {\n if (key.startsWith(prefix)) {\n return Reflect.get(node, key) ?? null;\n }\n }\n }\n return null;\n}\n\nfunction readName(value: unknown): string | null {\n if (typeof value !== \"function\" && !isRecord(value)) {\n return null;\n }\n\n const displayName = Reflect.get(value, \"displayName\");\n if (typeof displayName === \"string\" && displayName) {\n return displayName;\n }\n\n const name = Reflect.get(value, \"name\");\n return typeof name === \"string\" && name ? name : null;\n}\n\n/**\n * Minified bundles hand out names like `Ur` or `Sn`. Reporting those as the\n * owning component actively misleads an agent, so only real words get through.\n */\nfunction isMeaningfulName(name: string): boolean {\n if (name.includes(\"/\") || name.includes(\"_\")) {\n return true;\n }\n\n return (\n name.length >= MIN_NAME_LENGTH &&\n CAPITALIZED.test(name) &&\n WORD_INSIDE.test(name)\n );\n}\n\nfunction componentName(type: unknown, depth = 0): string | null {\n if (typeof type === \"string\" || type === null || depth > 3) {\n return null;\n }\n\n if (isRecord(type)) {\n const marker = Reflect.get(type, \"$$typeof\");\n if (marker === MEMO_TYPE) {\n return componentName(Reflect.get(type, \"type\"), depth + 1);\n }\n if (marker === FORWARD_REF_TYPE) {\n return componentName(Reflect.get(type, \"render\"), depth + 1);\n }\n }\n\n const name = readName(type);\n return name && isMeaningfulName(name) ? name : null;\n}\n\n/** Component names owning the fiber, innermost first. */\nexport function resolveComponentStack(fiber: unknown): string[] {\n const stack: string[] = [];\n let current = fiber;\n let steps = 0;\n\n while (isRecord(current) && steps < MAX_FIBER_WALK) {\n const name =\n componentName(Reflect.get(current, \"type\")) ??\n componentName(Reflect.get(current, \"elementType\"));\n\n if (name && stack.at(-1) !== name) {\n stack.push(name);\n if (stack.length >= MAX_STACK_DEPTH) {\n break;\n }\n }\n\n current = Reflect.get(current, \"return\");\n steps++;\n }\n\n return stack;\n}\n\nfunction shortenSourcePath(raw: string): string {\n const path = raw\n .replace(WEBPACK_PREFIX, \"\")\n .replace(ORIGIN_PREFIX, \"\")\n .split(\"?\")[0];\n if (!path) {\n return raw;\n }\n\n for (const marker of SOURCE_ROOT_MARKERS) {\n if (path.startsWith(`${marker}/`)) {\n return path;\n }\n const index = path.lastIndexOf(`/${marker}/`);\n if (index !== -1) {\n return path.slice(index + 1);\n }\n }\n\n return path.split(\"/\").filter(Boolean).slice(-3).join(\"/\");\n}\n\nfunction formatLocation(\n fileName: string,\n line: number,\n column?: number\n): string {\n const base = `${shortenSourcePath(fileName)}:${line}`;\n return column === undefined ? base : `${base}:${column}`;\n}\n\nfunction fromDebugSource(source: unknown): string | undefined {\n if (!isRecord(source)) {\n return;\n }\n\n const fileName = Reflect.get(source, \"fileName\");\n const lineNumber = Reflect.get(source, \"lineNumber\");\n if (typeof fileName !== \"string\" || typeof lineNumber !== \"number\") {\n return;\n }\n\n const columnNumber = Reflect.get(source, \"columnNumber\");\n return formatLocation(\n fileName,\n lineNumber,\n typeof columnNumber === \"number\" ? columnNumber : undefined\n );\n}\n\nfunction fromDebugStack(stack: unknown): string | undefined {\n const raw = isRecord(stack) ? Reflect.get(stack, \"stack\") : stack;\n if (typeof raw !== \"string\") {\n return;\n }\n\n for (const line of raw.split(\"\\n\")) {\n const match = STACK_LOCATION.exec(line);\n const file = match?.[1];\n if (!(match && file) || NON_SOURCE_FRAME.test(file)) {\n continue;\n }\n\n const path = file.replace(ORIGIN_PREFIX, \"\").split(\"?\")[0] ?? \"\";\n if (!SOURCE_EXTENSION.test(path)) {\n continue;\n }\n\n return formatLocation(path, Number(match[2]), Number(match[3]));\n }\n}\n\n/**\n * `src/components/login-form.tsx:46:19` when the React build exposes it.\n * Production bundles strip debug info — callers must treat this as optional.\n */\nexport function resolveSourceLocation(fiber: unknown): string | undefined {\n let current = fiber;\n let steps = 0;\n\n while (isRecord(current) && steps < MAX_OWNER_WALK) {\n const located =\n fromDebugSource(Reflect.get(current, \"_debugSource\")) ??\n fromDebugStack(Reflect.get(current, \"_debugStack\"));\n if (located) {\n return located;\n }\n\n current = Reflect.get(current, \"_debugOwner\");\n steps++;\n }\n}\n\nexport function inspectReactElement(element: Element): {\n componentStack: string[];\n sourceLocation?: string;\n} {\n const fiber = getFiberFromNode(element);\n return {\n componentStack: resolveComponentStack(fiber),\n sourceLocation: resolveSourceLocation(fiber),\n };\n}\n","/**\n * The picked element's markup leaves the reporter's browser and ends up in an\n * agent prompt, so it is scrubbed here: typed-in values, credentials and\n * anything marked `data-reflet-redact` never make the trip.\n */\n\nconst EMAIL = /[\\w.%+-]+@[\\w.-]+\\.[a-z]{2,}/gi;\nconst LONG_TOKEN = /\\b[\\w-]{28,}\\b/g;\nconst OPAQUE_URI = /^(?:data|blob|javascript):/i;\nconst WHITESPACE_RUN = /\\s+/g;\nconst URL_QUERY = /[?#]/;\n\nconst REDACTED = \"[redacted]\";\nconst ELLIPSIS = \"…\";\nexport const REDACT_ATTRIBUTE = \"data-reflet-redact\";\n\nconst MAX_ATTRIBUTE_LENGTH = 120;\nconst MAX_TEXT_LENGTH = 200;\nconst MAX_CHILD_DEPTH = 3;\nconst MAX_CLONED_NODES = 400;\n\nconst DROPPED_TAGS = new Set([\"script\", \"style\", \"noscript\", \"template\"]);\nconst VALUE_HOLDERS = new Set([\"input\", \"textarea\", \"select\", \"option\"]);\nconst URL_ATTRIBUTES = new Set([\n \"src\",\n \"srcset\",\n \"href\",\n \"poster\",\n \"action\",\n \"formaction\",\n]);\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max - 1)}${ELLIPSIS}`;\n}\n\n/** Emails and token-shaped strings, wherever they appear in reported text. */\nexport function maskSecrets(value: string): string {\n return value.replace(EMAIL, REDACTED).replace(LONG_TOKEN, REDACTED);\n}\n\nconst SENSITIVE_PARAM =\n /token|secret|pass(?:word|wd)?|pwd|auth|jwt|credential|session|sid|key|email|ssn|otp|code|signature|nonce/i;\nconst LEADING_QUESTION_MARK = /^\\?/;\n\nfunction decoded(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\n/**\n * Query strings carry signed-in state (`?token=…`, `?userEmail=…`) straight\n * into stored reports and agent prompts. Values of anything credential- or\n * identity-shaped are masked; every other byte of the address stays intact.\n */\nexport function redactUrl(href: string): string {\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return maskSecrets(href);\n }\n\n const pairs = url.search\n .replace(LEADING_QUESTION_MARK, \"\")\n .split(\"&\")\n .filter(Boolean);\n if (\n !pairs.some((pair) =>\n SENSITIVE_PARAM.test(decoded(pair.split(\"=\")[0] ?? \"\"))\n )\n ) {\n return href;\n }\n\n const kept = pairs.map((pair) => {\n const equals = pair.indexOf(\"=\");\n if (\n equals === -1 ||\n !SENSITIVE_PARAM.test(decoded(pair.slice(0, equals)))\n ) {\n return pair;\n }\n return `${pair.slice(0, equals)}=${REDACTED}`;\n });\n\n const query = kept.join(\"&\");\n return `${url.origin}${url.pathname}${query ? `?${query}` : \"\"}${url.hash}`;\n}\n\nfunction sanitizeUrl(value: string): string {\n if (OPAQUE_URI.test(value)) {\n return `${value.slice(0, value.indexOf(\":\"))}:${ELLIPSIS}`;\n }\n return value.split(URL_QUERY)[0] ?? value;\n}\n\nfunction sanitizeAttributes(element: Element): void {\n const holdsTypedValue = VALUE_HOLDERS.has(element.localName);\n\n for (const { name, value } of Array.from(element.attributes)) {\n if (holdsTypedValue && name === \"value\") {\n element.removeAttribute(name);\n continue;\n }\n\n const cleaned = URL_ATTRIBUTES.has(name)\n ? sanitizeUrl(value)\n : maskSecrets(value);\n element.setAttribute(name, truncate(cleaned, MAX_ATTRIBUTE_LENGTH));\n }\n}\n\nfunction collapse(element: Element): void {\n element.replaceChildren(element.ownerDocument.createTextNode(ELLIPSIS));\n}\n\nfunction sanitizeTree(element: Element, depth: number): void {\n sanitizeAttributes(element);\n\n if (element.hasAttribute(REDACT_ATTRIBUTE)) {\n element.replaceChildren(element.ownerDocument.createTextNode(REDACTED));\n return;\n }\n\n if (element.localName === \"svg\") {\n element.replaceChildren();\n return;\n }\n\n for (const child of Array.from(element.childNodes)) {\n if (child.nodeType === Node.COMMENT_NODE) {\n child.remove();\n continue;\n }\n\n if (child.nodeType === Node.TEXT_NODE) {\n child.textContent = truncate(\n maskSecrets(child.textContent ?? \"\"),\n MAX_TEXT_LENGTH\n );\n continue;\n }\n\n if (!(child instanceof Element)) {\n continue;\n }\n\n if (DROPPED_TAGS.has(child.localName)) {\n child.remove();\n continue;\n }\n\n if (depth >= MAX_CHILD_DEPTH) {\n sanitizeAttributes(child);\n collapse(child);\n continue;\n }\n\n sanitizeTree(child, depth + 1);\n }\n}\n\n/** Redacted `outerHTML`, shallow-cloned when the subtree is too large to be useful. */\nexport function sanitizeMarkup(element: Element, maxLength: number): string {\n const isSmallEnough =\n element.querySelectorAll(\"*\").length <= MAX_CLONED_NODES;\n const clone = element.cloneNode(isSmallEnough);\n if (!(clone instanceof Element)) {\n return \"\";\n }\n\n sanitizeTree(clone, 0);\n if (!isSmallEnough) {\n collapse(clone);\n }\n\n return truncate(clone.outerHTML.replace(WHITESPACE_RUN, \" \"), maxLength);\n}\n","import type { ElementRect, ElementSelection } from \"../../types\";\nimport { inspectReactElement } from \"./react-source\";\nimport { maskSecrets, sanitizeMarkup } from \"./redact\";\n\nconst SAFE_ID = /^[A-Za-z][\\w-]*$/;\nconst WHITESPACE = /\\s+/g;\nconst MAX_LABEL_LENGTH = 80;\nconst MAX_HTML_LENGTH = 600;\nconst MAX_TEXT_LENGTH = 300;\nconst MAX_REGION_LENGTH = 160;\nconst MAX_HANDLE_VALUE_LENGTH = 80;\nconst MAX_DEPTH = 12;\nconst MIN_PATH_SEGMENTS = 2;\n// Hard caps enforced by POST /api/v1/feedback/create — over them the whole\n// report is rejected, so clip here rather than lose the submission.\nconst MAX_SELECTOR_LENGTH = 600;\nconst MAX_SOURCE_LOCATION_LENGTH = 400;\n\nconst TEST_ATTRIBUTES = [\n \"data-testid\",\n \"data-test-id\",\n \"data-test\",\n \"data-cy\",\n \"data-qa\",\n];\nconst NAMING_ATTRIBUTES = [\"name\", \"aria-label\"];\n\nconst LANDMARK_SELECTOR =\n 'dialog, [role=\"dialog\"], [role=\"alertdialog\"], main, nav, aside, header, footer, form, section, article';\nconst HEADING_SELECTOR = 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]';\n\n/** Elements that start a new visual block — their text gets separated by a space. */\nconst BLOCK_TAGS = new Set([\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"dd\",\n \"details\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"summary\",\n \"table\",\n \"td\",\n \"th\",\n \"tr\",\n \"ul\",\n]);\n\nfunction visibleText(element: Element): string {\n const clone = element.cloneNode(true);\n if (!(clone instanceof Element)) {\n return \"\";\n }\n\n for (const node of clone.querySelectorAll(\"*\")) {\n if (BLOCK_TAGS.has(node.localName)) {\n node.before(clone.ownerDocument.createTextNode(\" \"));\n }\n }\n\n return collapseText(maskSecrets(clone.textContent ?? \"\"));\n}\n\nfunction isUnique(selector: string): boolean {\n try {\n return document.querySelectorAll(selector).length === 1;\n } catch {\n return false;\n }\n}\n\nfunction escapeAttributeValue(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n\nfunction attributeHandle(\n element: Element,\n attribute: string,\n qualifier: string\n): string | null {\n const value = element.getAttribute(attribute);\n if (!value || value.length > MAX_HANDLE_VALUE_LENGTH) {\n return null;\n }\n\n const selector = `${qualifier}[${attribute}=\"${escapeAttributeValue(value)}\"]`;\n return isUnique(selector) ? selector : null;\n}\n\n/** Something an engineer would have written on purpose, unlike a positional path. */\nfunction uniqueHandle(element: Element): string | null {\n const id = element.getAttribute(\"id\");\n if (id && SAFE_ID.test(id) && isUnique(`#${id}`)) {\n return `#${id}`;\n }\n\n for (const attribute of TEST_ATTRIBUTES) {\n const handle = attributeHandle(element, attribute, \"\");\n if (handle) {\n return handle;\n }\n }\n\n for (const attribute of NAMING_ATTRIBUTES) {\n const handle = attributeHandle(element, attribute, element.localName);\n if (handle) {\n return handle;\n }\n }\n\n return null;\n}\n\nfunction positionalSegment(element: Element): string {\n const tag = element.localName;\n const parent = element.parentElement;\n if (!parent) {\n return tag;\n }\n\n const sameTag = Array.from(parent.children).filter(\n (child) => child.localName === tag\n );\n if (sameTag.length <= 1) {\n return tag;\n }\n\n return `${tag}:nth-of-type(${sameTag.indexOf(element) + 1})`;\n}\n\n/**\n * Shortest selector that still resolves back to `element` from the document.\n * Grows the path one ancestor at a time and stops as soon as it is unique, so\n * a stable handle anywhere up the tree replaces the whole positional chain.\n * A bare tag is never enough: positional paths keep a parent for context.\n */\nexport function buildSelector(element: Element): string {\n if (element === document.documentElement) {\n return \"html\";\n }\n if (element === document.body) {\n return \"body\";\n }\n\n const handle = uniqueHandle(element);\n if (handle) {\n return handle;\n }\n\n const segments: string[] = [];\n let current: Element | null = element;\n\n for (let depth = 0; current && depth < MAX_DEPTH; depth++) {\n const ancestorHandle = current === element ? null : uniqueHandle(current);\n segments.unshift(ancestorHandle ?? positionalSegment(current));\n\n const candidate = segments.join(\" > \");\n const isAnchored = segments.length >= MIN_PATH_SEGMENTS;\n if (\n ancestorHandle ||\n current === document.body ||\n (isAnchored && isUnique(candidate))\n ) {\n return candidate;\n }\n\n current = current.parentElement;\n }\n\n return segments.join(\" > \");\n}\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max - 1)}…`;\n}\n\nfunction collapseText(value: string): string {\n return value.replace(WHITESPACE, \" \").trim();\n}\n\nfunction accessibleLabel(element: Element): string {\n const explicit =\n element.getAttribute(\"aria-label\") ??\n element.getAttribute(\"title\") ??\n element.getAttribute(\"alt\") ??\n element.getAttribute(\"placeholder\");\n if (explicit?.trim()) {\n return explicit.trim();\n }\n\n return collapseText(element.textContent ?? \"\");\n}\n\n/** Short human label such as `button \"Sign in\"` or `div.card`. */\nexport function describeElement(element: Element): string {\n const tag = element.localName;\n const label = maskSecrets(accessibleLabel(element));\n if (label) {\n return truncate(`${tag} \"${label}\"`, MAX_LABEL_LENGTH);\n }\n\n const firstClass = element.classList.item(0);\n return truncate(firstClass ? `${tag}.${firstClass}` : tag, MAX_LABEL_LENGTH);\n}\n\nfunction describeLandmark(element: Element): string | null {\n const landmark = element.parentElement?.closest(LANDMARK_SELECTOR);\n if (!landmark) {\n return null;\n }\n\n const name =\n landmark.getAttribute(\"aria-label\") ?? landmark.getAttribute(\"title\");\n return name?.trim()\n ? `${landmark.localName} \"${collapseText(name)}\"`\n : landmark.localName;\n}\n\nfunction headingAbove(element: Element): string | null {\n const scope = element.closest(LANDMARK_SELECTOR) ?? document.body;\n const probe = document.createRange();\n probe.selectNodeContents(element);\n probe.collapse(true);\n\n let closest: Element | null = null;\n for (const heading of scope.querySelectorAll(HEADING_SELECTOR)) {\n if (probe.comparePoint(heading, 0) < 0) {\n closest = heading;\n }\n }\n\n const text = collapseText(closest?.textContent ?? \"\");\n return text || null;\n}\n\n/**\n * Where the element sits from a reader's point of view — `dialog \"Members\" ›\n * Danger zone` says more to an agent than any DOM path can.\n */\nexport function describeRegion(element: Element): string | undefined {\n const landmark = describeLandmark(element);\n const heading = headingAbove(element);\n const parts = [landmark];\n\n if (heading && !landmark?.includes(`\"${heading}\"`)) {\n parts.push(heading);\n }\n\n const region = parts.filter((part) => part !== null).join(\" › \");\n return region ? truncate(maskSecrets(region), MAX_REGION_LENGTH) : undefined;\n}\n\nexport function getElementRect(element: Element): ElementRect {\n const rect = element.getBoundingClientRect();\n return {\n height: Math.round(rect.height),\n width: Math.round(rect.width),\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n };\n}\n\n/** Everything an agent needs to find the picked element back in the codebase. */\nexport function buildElementSelection(element: Element): ElementSelection {\n const { componentStack, sourceLocation } = inspectReactElement(element);\n const text = truncate(visibleText(element), MAX_TEXT_LENGTH);\n\n return {\n componentStack,\n html: sanitizeMarkup(element, MAX_HTML_LENGTH),\n label: describeElement(element),\n rect: getElementRect(element),\n region: describeRegion(element),\n selector: truncate(buildSelector(element), MAX_SELECTOR_LENGTH),\n sourceLocation: sourceLocation\n ? truncate(sourceLocation, MAX_SOURCE_LOCATION_LENGTH)\n : sourceLocation,\n text: text || undefined,\n };\n}\n","import type { FeedbackContext } from \"../../types\";\nimport { redactUrl } from \"./redact\";\n\ninterface AgentInfo {\n browser?: string;\n device: \"desktop\" | \"mobile\" | \"tablet\";\n os?: string;\n}\n\nconst BROWSER_PATTERNS: [string, RegExp][] = [\n [\"Edge\", /Edg(?:e|A|iOS)?\\/([\\d.]+)/],\n [\"Opera\", /OPR\\/([\\d.]+)/],\n [\"Samsung Internet\", /SamsungBrowser\\/([\\d.]+)/],\n [\"Firefox\", /(?:Firefox|FxiOS)\\/([\\d.]+)/],\n [\"Chrome\", /(?:Chrome|CriOS)\\/([\\d.]+)/],\n [\"Safari\", /Version\\/([\\d.]+).*Safari/],\n];\n\nconst OS_PATTERNS: [string, RegExp][] = [\n [\"iOS\", /iPhone|iPad|iPod/],\n [\"Android\", /Android/],\n [\"Windows\", /Windows NT/],\n [\"macOS\", /Mac OS X|Macintosh/],\n [\"ChromeOS\", /CrOS/],\n [\"Linux\", /Linux|X11/],\n];\n\nconst MOBILE_HINT = /Mobile|iPhone|iPod/;\nconst TABLET_HINT = /iPad|Tablet/;\nconst TRAILING_ZERO = /\\.0$/;\nconst ANDROID = /Android/;\n\nfunction shortenVersion(version: string): string {\n return version.split(\".\").slice(0, 2).join(\".\").replace(TRAILING_ZERO, \"\");\n}\n\nfunction detectDevice(userAgent: string): AgentInfo[\"device\"] {\n if (TABLET_HINT.test(userAgent)) {\n return \"tablet\";\n }\n if (MOBILE_HINT.test(userAgent)) {\n return \"mobile\";\n }\n return ANDROID.test(userAgent) ? \"tablet\" : \"desktop\";\n}\n\nexport function parseUserAgent(userAgent: string): AgentInfo {\n const info: AgentInfo = { device: detectDevice(userAgent) };\n\n for (const [name, pattern] of BROWSER_PATTERNS) {\n const version = pattern.exec(userAgent)?.[1];\n if (version) {\n info.browser = `${name} ${shortenVersion(version)}`;\n break;\n }\n }\n\n for (const [name, pattern] of OS_PATTERNS) {\n if (pattern.test(userAgent)) {\n info.os = name;\n break;\n }\n }\n\n return info;\n}\n\n// Hard caps enforced by POST /api/v1/feedback/create — over them the whole\n// report is rejected, so clip here rather than lose the submission.\nconst MAX_PAGE_TITLE_LENGTH = 300;\nconst MAX_URL_LENGTH = 2000;\nconst MAX_USER_AGENT_LENGTH = 600;\n\nfunction clip(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\nfunction optionalText(\n value: string | undefined,\n max: number\n): string | undefined {\n return value?.trim() ? clip(value, max) : undefined;\n}\n\nfunction resolveTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Intl missing in some embedded webviews\n }\n}\n\n/** Everything about the page that a bug report needs and the DOM already knows. */\nexport function collectPageContext(options?: {\n sdkVersion?: string;\n}): FeedbackContext {\n const userAgent = navigator.userAgent;\n const agent = parseUserAgent(userAgent);\n\n return {\n browser: agent.browser,\n device: agent.device,\n language: navigator.language,\n os: agent.os,\n pageTitle: optionalText(document.title, MAX_PAGE_TITLE_LENGTH),\n referrer: optionalText(document.referrer, MAX_URL_LENGTH),\n screen: { height: window.screen.height, width: window.screen.width },\n scroll: { x: window.scrollX, y: window.scrollY },\n sdkVersion: options?.sdkVersion,\n timezone: resolveTimezone(),\n url: redactUrl(window.location.href),\n userAgent: clip(userAgent, MAX_USER_AGENT_LENGTH),\n viewport: {\n devicePixelRatio: window.devicePixelRatio,\n height: window.innerHeight,\n width: window.innerWidth,\n },\n };\n}\n","import type { RefletUser } from \"../types\";\n\n/** Reported with every submission. */\nexport const SDK_VERSION = \"0.3.2\";\n\nconst FEEDBACK_WIDGET_CATEGORIES = [\"bug\", \"idea\", \"question\"] as const;\n\nexport type FeedbackWidgetCategory =\n (typeof FEEDBACK_WIDGET_CATEGORIES)[number];\n\nconst ANNOTATION_TOOLS = [\n \"pen\",\n \"arrow\",\n \"rectangle\",\n \"highlight\",\n \"blur\",\n] as const;\n\nexport type AnnotationTool = (typeof ANNOTATION_TOOLS)[number];\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface Annotation {\n color: string;\n end: Point;\n id: string;\n /** Freehand path, in image pixels. Only set for the pen tool. */\n points?: Point[];\n start: Point;\n tool: AnnotationTool;\n}\n\nexport interface CapturedImage {\n blob: Blob;\n height: number;\n mimeType: string;\n /** Object URL owned by the caller — revoke it when the capture is dropped. */\n objectUrl: string;\n width: number;\n}\n\nexport interface FeedbackWidgetLabels {\n annotateHint: string;\n attachScreenshot: string;\n back: string;\n cancel: string;\n categoryBug: string;\n categoryIdea: string;\n categoryQuestion: string;\n clearAnnotations: string;\n descriptionPlaceholder: string;\n dismissForDays: string;\n done: string;\n emailLabel: string;\n emailPlaceholder: string;\n errorGeneric: string;\n errorTitleRequired: string;\n pickElement: string;\n pickElementHint: string;\n recapture: string;\n removeScreenshot: string;\n retakeHint: string;\n submit: string;\n successMessage: string;\n successTitle: string;\n title: string;\n titlePlaceholder: string;\n trigger: string;\n undo: string;\n}\n\nexport const DEFAULT_WIDGET_LABELS: FeedbackWidgetLabels = {\n annotateHint: \"Draw on the screenshot to point at the problem.\",\n attachScreenshot: \"Attach a screenshot\",\n back: \"Back\",\n cancel: \"Cancel\",\n categoryBug: \"Bug\",\n categoryIdea: \"Idea\",\n categoryQuestion: \"Question\",\n clearAnnotations: \"Clear drawing\",\n descriptionPlaceholder: \"What happened? What did you expect?\",\n dismissForDays: \"Hide for {days} days\",\n done: \"Done\",\n emailLabel: \"Email\",\n emailPlaceholder: \"you@company.com\",\n errorGeneric: \"Something went wrong. Please try again.\",\n errorTitleRequired: \"Tell us a bit about it first.\",\n pickElement: \"Point at an element\",\n pickElementHint: \"Click the element you are talking about — cancel with\",\n recapture: \"Retake\",\n removeScreenshot: \"Remove\",\n retakeHint: \"Screenshot of this page\",\n submit: \"Send feedback\",\n successMessage: \"We read every report. Thanks for taking the time.\",\n successTitle: \"Feedback sent\",\n title: \"Send feedback\",\n titlePlaceholder: \"Short summary\",\n trigger: \"Feedback\",\n undo: \"Undo\",\n};\n\nexport interface RefletFeedbackProps {\n /** API base URL override. Falls back to the RefletProvider value. */\n baseUrl?: string;\n /** Record console errors and warnings to attach to bug reports. */\n captureConsole?: boolean;\n /** Take a screenshot of the viewport as soon as the panel opens. */\n captureOnOpen?: boolean;\n categories?: FeedbackWidgetCategory[];\n defaultCategory?: FeedbackWidgetCategory;\n /** Let reporters hide the launcher for this many days. */\n dismissForDays?: number;\n /** Render nothing when false — lets an app gate the widget per user. */\n enabled?: boolean;\n /** Keyboard shortcut opening the panel. Set to null to disable. */\n hotkey?: string | null;\n labels?: Partial<FeedbackWidgetLabels>;\n /** Extra fields merged into the reported context. */\n metadata?: Record<string, string>;\n /** Distance in px from the viewport edges. */\n offset?: number;\n onClose?: () => void;\n onDismiss?: (result: { until: number }) => void;\n onOpen?: () => void;\n onSubmit?: (result: { feedbackId: string }) => void;\n position?: \"bottom-left\" | \"bottom-right\" | \"top-left\" | \"top-right\";\n primaryColor?: string;\n publicKey?: string;\n theme?: \"auto\" | \"dark\" | \"light\";\n user?: RefletUser;\n userToken?: string;\n}\n\nexport type WidgetStep = \"annotate\" | \"compose\" | \"picking\" | \"success\";\n","import type { ElementRect, ScreenshotAnnotation } from \"../../types\";\nimport type { Annotation, AnnotationTool, Point } from \"../types\";\n\nexport const ANNOTATION_COLORS = [\n \"#ef4444\",\n \"#f59e0b\",\n \"#22c55e\",\n \"#3b82f6\",\n \"#111827\",\n] as const;\n\nconst BOX_TOOLS: AnnotationTool[] = [\"rectangle\", \"highlight\", \"blur\"];\nconst MIN_GESTURE_LENGTH = 8;\nconst ARROW_HEAD_ANGLE = Math.PI / 7;\nconst DEFAULT_PATH_TOLERANCE = 2.5;\n\nexport function normalizeRect(start: Point, end: Point): ElementRect {\n return {\n height: Math.abs(end.y - start.y),\n width: Math.abs(end.x - start.x),\n x: Math.min(start.x, end.x),\n y: Math.min(start.y, end.y),\n };\n}\n\n/** The two barbs closing the arrow tip, both `size` px away from `end`. */\nexport function arrowHead(\n start: Point,\n end: Point,\n size: number\n): [Point, Point] {\n const angle = Math.atan2(end.y - start.y, end.x - start.x);\n if (Math.hypot(end.x - start.x, end.y - start.y) === 0) {\n return [end, end];\n }\n\n const barb = (offset: number): Point => ({\n x: end.x - size * Math.cos(angle + offset),\n y: end.y - size * Math.sin(angle + offset),\n });\n\n return [barb(-ARROW_HEAD_ANGLE), barb(ARROW_HEAD_ANGLE)];\n}\n\n/** Drops points a user cannot perceive, keeping the payload small. */\nexport function simplifyPath(\n points: Point[],\n tolerance = DEFAULT_PATH_TOLERANCE\n): Point[] {\n if (points.length < 3) {\n return points;\n }\n\n const [first, ...rest] = points;\n if (!first) {\n return points;\n }\n\n const kept: Point[] = [first];\n let anchor = first;\n\n for (const point of rest.slice(0, -1)) {\n if (Math.hypot(point.x - anchor.x, point.y - anchor.y) >= tolerance) {\n kept.push(point);\n anchor = point;\n }\n }\n\n const last = points.at(-1);\n if (last) {\n kept.push(last);\n }\n\n return kept;\n}\n\nexport function isDegenerate(annotation: Annotation): boolean {\n if (annotation.tool === \"pen\") {\n return (annotation.points?.length ?? 0) < 2;\n }\n\n const { start, end } = annotation;\n return Math.hypot(end.x - start.x, end.y - start.y) < MIN_GESTURE_LENGTH;\n}\n\nfunction toWire(annotation: Annotation): ScreenshotAnnotation {\n const { color, start, end, tool } = annotation;\n\n if (tool === \"pen\") {\n return {\n color,\n points: simplifyPath(annotation.points ?? []),\n type: tool,\n x: start.x,\n y: start.y,\n };\n }\n\n if (BOX_TOOLS.includes(tool)) {\n const rect = normalizeRect(start, end);\n return {\n color,\n height: rect.height,\n type: tool,\n width: rect.width,\n x: rect.x,\n y: rect.y,\n };\n }\n\n return {\n color,\n endX: end.x,\n endY: end.y,\n type: tool,\n x: start.x,\n y: start.y,\n };\n}\n\n/** Serializes to the shape the Reflet API stores next to the screenshot. */\nexport function toWireAnnotations(\n annotations: Annotation[]\n): ScreenshotAnnotation[] {\n return annotations.filter((item) => !isDegenerate(item)).map(toWire);\n}\n","import type { ElementRect } from \"../../types\";\nimport type { Annotation, CapturedImage, Point } from \"../types\";\nimport { arrowHead, isDegenerate, normalizeRect } from \"./annotations\";\n\nconst STROKE_WIDTH = 3;\nconst ARROW_HEAD_SIZE = 16;\nconst HIGHLIGHT_ALPHA = 0.3;\nconst REDACTION_FILL = \"#111827\";\nconst PIXEL_BLOCK = 10;\n\n/**\n * The slice of `CanvasRenderingContext2D` the annotation layer needs.\n * Narrowing it keeps the drawing code testable without a canvas polyfill.\n */\nexport interface AnnotationCanvasContext {\n beginPath: () => void;\n canvas: { height: number; width: number };\n closePath: () => void;\n drawImage: (\n image: CanvasImageSource,\n dx: number,\n dy: number,\n dw: number,\n dh: number\n ) => void;\n fill: () => void;\n fillRect: (x: number, y: number, width: number, height: number) => void;\n fillStyle: string | CanvasGradient | CanvasPattern;\n globalAlpha: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n lineTo: (x: number, y: number) => void;\n lineWidth: number;\n moveTo: (x: number, y: number) => void;\n restore: () => void;\n save: () => void;\n stroke: () => void;\n strokeRect: (x: number, y: number, width: number, height: number) => void;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n}\n\nfunction scalePoint(point: Point, scale: number): Point {\n return { x: point.x * scale, y: point.y * scale };\n}\n\nfunction scaleRect(rect: ElementRect, scale: number): ElementRect {\n return {\n height: rect.height * scale,\n width: rect.width * scale,\n x: rect.x * scale,\n y: rect.y * scale,\n };\n}\n\nfunction isCanvasElement(value: unknown): value is HTMLCanvasElement {\n return (\n typeof HTMLCanvasElement !== \"undefined\" &&\n value instanceof HTMLCanvasElement\n );\n}\n\n/**\n * Downsamples the region and paints it back enlarged, so redacted pixels are\n * unrecoverable. Falls back to an opaque block wherever 2d canvases are absent.\n */\nfunction redact(context: AnnotationCanvasContext, rect: ElementRect): void {\n const source = context.canvas;\n const width = Math.max(1, Math.round(rect.width / PIXEL_BLOCK));\n const height = Math.max(1, Math.round(rect.height / PIXEL_BLOCK));\n\n if (isCanvasElement(source)) {\n const offscreen = document.createElement(\"canvas\");\n offscreen.width = width;\n offscreen.height = height;\n const offscreenContext = offscreen.getContext(\"2d\");\n\n if (offscreenContext) {\n offscreenContext.imageSmoothingEnabled = true;\n offscreenContext.drawImage(\n source,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n 0,\n 0,\n width,\n height\n );\n context.drawImage(offscreen, rect.x, rect.y, rect.width, rect.height);\n return;\n }\n }\n\n context.fillStyle = REDACTION_FILL;\n context.fillRect(rect.x, rect.y, rect.width, rect.height);\n}\n\nfunction drawArrow(\n context: AnnotationCanvasContext,\n start: Point,\n end: Point,\n scale: number\n): void {\n context.beginPath();\n context.moveTo(start.x, start.y);\n context.lineTo(end.x, end.y);\n context.stroke();\n\n const [left, right] = arrowHead(start, end, ARROW_HEAD_SIZE * scale);\n context.beginPath();\n context.moveTo(end.x, end.y);\n context.lineTo(left.x, left.y);\n context.lineTo(right.x, right.y);\n context.closePath();\n context.fill();\n}\n\nfunction drawPen(\n context: AnnotationCanvasContext,\n points: Point[],\n scale: number\n): void {\n const [first, ...rest] = points;\n if (!first) {\n return;\n }\n\n const head = scalePoint(first, scale);\n context.beginPath();\n context.moveTo(head.x, head.y);\n for (const point of rest) {\n const scaled = scalePoint(point, scale);\n context.lineTo(scaled.x, scaled.y);\n }\n context.stroke();\n}\n\nfunction drawAnnotation(\n context: AnnotationCanvasContext,\n annotation: Annotation,\n scale: number\n): void {\n const { color, tool } = annotation;\n const rect = scaleRect(\n normalizeRect(annotation.start, annotation.end),\n scale\n );\n\n context.save();\n context.lineWidth = STROKE_WIDTH * scale;\n context.lineCap = \"round\";\n context.lineJoin = \"round\";\n context.strokeStyle = color;\n context.fillStyle = color;\n\n switch (tool) {\n case \"pen\":\n drawPen(context, annotation.points ?? [], scale);\n break;\n case \"arrow\":\n drawArrow(\n context,\n scalePoint(annotation.start, scale),\n scalePoint(annotation.end, scale),\n scale\n );\n break;\n case \"rectangle\":\n context.strokeRect(rect.x, rect.y, rect.width, rect.height);\n break;\n case \"highlight\":\n context.globalAlpha = HIGHLIGHT_ALPHA;\n context.fillRect(rect.x, rect.y, rect.width, rect.height);\n break;\n default:\n redact(context, rect);\n break;\n }\n\n context.restore();\n}\n\nexport function drawAnnotations(\n context: AnnotationCanvasContext,\n annotations: Annotation[],\n options?: { scale?: number }\n): void {\n const scale = options?.scale ?? 1;\n for (const annotation of annotations) {\n if (!isDegenerate(annotation)) {\n drawAnnotation(context, annotation, scale);\n }\n }\n}\n\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(\"Screenshot could not be decoded\"));\n image.src = url;\n });\n}\n\nfunction toBlob(canvas: HTMLCanvasElement): Promise<Blob | null> {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, \"image/png\");\n });\n}\n\n/**\n * Burns the annotations into a copy of the capture so reviewers and agents see\n * the drawing without needing to replay the vector data.\n */\nexport async function renderAnnotatedImage(\n source: CapturedImage,\n annotations: Annotation[]\n): Promise<CapturedImage | null> {\n if (annotations.length === 0) {\n return null;\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = source.width;\n canvas.height = source.height;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n return null;\n }\n\n const image = await loadImage(source.objectUrl);\n context.drawImage(image, 0, 0, source.width, source.height);\n drawAnnotations(context, annotations);\n\n const blob = await toBlob(canvas);\n if (!blob) {\n return null;\n }\n\n return {\n blob,\n height: source.height,\n mimeType: \"image/png\",\n objectUrl: URL.createObjectURL(blob),\n width: source.width,\n };\n}\n","import type { ReactNode } from \"react\";\n\nfunction Svg({\n children,\n className,\n size = 16,\n}: {\n children: ReactNode;\n className?: string;\n size?: number;\n}) {\n return (\n <svg\n aria-hidden=\"true\"\n className={className}\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.8\"\n viewBox=\"0 0 24 24\"\n width={size}\n >\n {children}\n </svg>\n );\n}\n\nexport function ChatIcon({ className }: { className?: string }) {\n return (\n <Svg className={className} size={15}>\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </Svg>\n );\n}\n\nexport function CloseIcon({ className }: { className?: string }) {\n return (\n <Svg className={className}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Svg>\n );\n}\n\nexport function BugIcon() {\n return (\n <Svg size={14}>\n <path d=\"M8 6a4 4 0 0 1 8 0M6 10h12v4a6 6 0 0 1-12 0zM3 12h3M18 12h3M4.5 6.5 7 8M19.5 6.5 17 8M4.5 17.5 7 16M19.5 17.5 17 16\" />\n </Svg>\n );\n}\n\nexport function IdeaIcon() {\n return (\n <Svg size={14}>\n <path d=\"M9 18h6M10 21h4M12 3a6 6 0 0 0-3.6 10.8c.5.4.8.9.9 1.5l.1.7h5.2l.1-.7c.1-.6.4-1.1.9-1.5A6 6 0 0 0 12 3\" />\n </Svg>\n );\n}\n\nexport function QuestionIcon() {\n return (\n <Svg size={14}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M9.6 9.4a2.5 2.5 0 1 1 3.3 2.4c-.6.2-.9.8-.9 1.4v.3M12 17h.01\" />\n </Svg>\n );\n}\n\nexport function CameraIcon() {\n return (\n <Svg>\n <path d=\"M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2l1.2-2h8.2l1.2 2h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.2\" />\n </Svg>\n );\n}\n\nexport function PencilIcon() {\n return (\n <Svg>\n <path d=\"M16.5 4.5a2.1 2.1 0 0 1 3 3L8 19l-4 1 1-4z\" />\n </Svg>\n );\n}\n\nexport function TargetIcon() {\n return (\n <Svg>\n <path d=\"M12 3v3M12 18v3M3 12h3M18 12h3\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n </Svg>\n );\n}\n\nexport function TrashIcon() {\n return (\n <Svg>\n <path d=\"M4 7h16M9 7V5h6v2M6 7l1 13h10l1-13M10 11v5M14 11v5\" />\n </Svg>\n );\n}\n\nexport function ArrowIcon() {\n return (\n <Svg>\n <path d=\"M5 19 19 5M11 5h8v8\" />\n </Svg>\n );\n}\n\nexport function SquareIcon() {\n return (\n <Svg>\n <rect height=\"13\" rx=\"1.5\" width=\"16\" x=\"4\" y=\"5.5\" />\n </Svg>\n );\n}\n\nexport function HighlightIcon() {\n return (\n <Svg>\n <path d=\"M4 15h16M6 5h12v7H6z\" />\n </Svg>\n );\n}\n\nexport function BlurIcon() {\n return (\n <Svg>\n <path d=\"M12 3c3.5 4 5.5 6.6 5.5 9.2A5.5 5.5 0 0 1 6.5 12.2C6.5 9.6 8.5 7 12 3\" />\n <path d=\"M9 13h.01M12 15h.01M15 12h.01\" />\n </Svg>\n );\n}\n\nexport function UndoIcon() {\n return (\n <Svg>\n <path d=\"M4 9h11a5 5 0 0 1 0 10h-5M4 9l4-4M4 9l4 4\" />\n </Svg>\n );\n}\n\nexport function CheckIcon({ size = 28 }: { size?: number }) {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2.4\"\n viewBox=\"0 0 24 24\"\n width={size}\n >\n <path d=\"m5 13 4 4L19 7\" />\n </svg>\n );\n}\n","import {\n type ComponentType,\n type PointerEvent as ReactPointerEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { drawAnnotations } from \"../core/annotation-renderer\";\nimport { ANNOTATION_COLORS, isDegenerate } from \"../core/annotations\";\nimport type {\n Annotation,\n AnnotationTool,\n CapturedImage,\n FeedbackWidgetLabels,\n Point,\n} from \"../types\";\nimport {\n ArrowIcon,\n BlurIcon,\n HighlightIcon,\n PencilIcon,\n SquareIcon,\n TrashIcon,\n UndoIcon,\n} from \"./icons\";\n\nconst TOOLS: Array<{\n icon: ComponentType;\n id: AnnotationTool;\n label: string;\n}> = [\n { icon: PencilIcon, id: \"pen\", label: \"Draw\" },\n { icon: ArrowIcon, id: \"arrow\", label: \"Arrow\" },\n { icon: SquareIcon, id: \"rectangle\", label: \"Box\" },\n { icon: HighlightIcon, id: \"highlight\", label: \"Highlight\" },\n { icon: BlurIcon, id: \"blur\", label: \"Hide\" },\n];\n\nfunction toImagePoint(\n canvas: HTMLCanvasElement,\n clientX: number,\n clientY: number\n): Point {\n const bounds = canvas.getBoundingClientRect();\n return {\n x: ((clientX - bounds.left) / bounds.width) * canvas.width,\n y: ((clientY - bounds.top) / bounds.height) * canvas.height,\n };\n}\n\nexport function Annotator({\n annotations,\n capture,\n labels,\n onChange,\n onDone,\n}: {\n annotations: Annotation[];\n capture: CapturedImage;\n labels: FeedbackWidgetLabels;\n onChange: (annotations: Annotation[]) => void;\n onDone: () => void;\n}) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const nextId = useRef(0);\n const [tool, setTool] = useState<AnnotationTool>(\"pen\");\n const [color, setColor] = useState<string>(ANNOTATION_COLORS[0]);\n const [draft, setDraft] = useState<Annotation | null>(null);\n // State, not a ref: the redraw effect must re-run once the bitmap is decoded.\n const [base, setBase] = useState<HTMLImageElement | null>(null);\n\n useEffect(() => {\n let active = true;\n const image = new Image();\n image.onload = () => {\n if (active) {\n setBase(image);\n }\n };\n image.src = capture.objectUrl;\n return () => {\n active = false;\n setBase(null);\n };\n }, [capture.objectUrl]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const context = canvas?.getContext(\"2d\");\n if (!(canvas && context)) {\n return;\n }\n\n context.clearRect(0, 0, canvas.width, canvas.height);\n if (base) {\n context.drawImage(base, 0, 0, canvas.width, canvas.height);\n }\n drawAnnotations(context, draft ? [...annotations, draft] : annotations);\n }, [annotations, base, draft]);\n\n const onPointerDown = (event: ReactPointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas) {\n return;\n }\n\n canvas.setPointerCapture(event.pointerId);\n const point = toImagePoint(canvas, event.clientX, event.clientY);\n nextId.current += 1;\n\n setDraft({\n color,\n end: point,\n id: `a${nextId.current}`,\n points: tool === \"pen\" ? [point] : undefined,\n start: point,\n tool,\n });\n };\n\n const onPointerMove = (event: ReactPointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!(canvas && draft)) {\n return;\n }\n\n const point = toImagePoint(canvas, event.clientX, event.clientY);\n setDraft(\n draft.tool === \"pen\"\n ? { ...draft, end: point, points: [...(draft.points ?? []), point] }\n : { ...draft, end: point }\n );\n };\n\n const onPointerUp = () => {\n if (!draft) {\n return;\n }\n if (!isDegenerate(draft)) {\n onChange([...annotations, draft]);\n }\n setDraft(null);\n };\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onDone();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [onDone]);\n\n return (\n <div className=\"overlay\">\n <div className=\"editor\">\n <canvas\n height={capture.height}\n onPointerCancel={onPointerUp}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n ref={canvasRef}\n width={capture.width}\n />\n </div>\n\n <div className=\"toolbar\">\n <div className=\"group\">\n {TOOLS.map(({ icon: Icon, id, label }) => (\n <button\n aria-label={label}\n aria-pressed={tool === id}\n className=\"tool\"\n key={id}\n onClick={() => setTool(id)}\n title={label}\n type=\"button\"\n >\n <Icon />\n </button>\n ))}\n </div>\n\n <div className=\"group\">\n {ANNOTATION_COLORS.map((value) => (\n <button\n aria-label={`Color ${value}`}\n aria-pressed={color === value}\n className=\"swatch\"\n key={value}\n onClick={() => setColor(value)}\n style={{ background: value }}\n type=\"button\"\n />\n ))}\n </div>\n\n <div className=\"group\">\n <button\n aria-label={labels.undo}\n className=\"tool\"\n disabled={annotations.length === 0}\n onClick={() => onChange(annotations.slice(0, -1))}\n title={labels.undo}\n type=\"button\"\n >\n <UndoIcon />\n </button>\n <button\n aria-label={labels.clearAnnotations}\n className=\"tool\"\n disabled={annotations.length === 0}\n onClick={() => onChange([])}\n title={labels.clearAnnotations}\n type=\"button\"\n >\n <TrashIcon />\n </button>\n <button className=\"done-btn\" onClick={onDone} type=\"button\">\n {labels.done}\n </button>\n </div>\n </div>\n </div>\n );\n}\n","import { ChatIcon, CloseIcon } from \"./icons\";\n\n/**\n * Never changes size between states — the panel opening must not move the\n * button out from under the pointer.\n */\nexport function Launcher({\n isOpen,\n label,\n onClick,\n}: {\n isOpen: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <button\n aria-expanded={isOpen}\n className=\"launcher\"\n data-open={isOpen}\n onClick={onClick}\n type=\"button\"\n >\n <span className=\"launcher-icon\">\n <ChatIcon className=\"on-open\" />\n <CloseIcon className=\"on-close\" />\n </span>\n {label}\n </button>\n );\n}\n","import { type ComponentType, useEffect, useRef } from \"react\";\nimport type { FeedbackWidgetCategory, FeedbackWidgetLabels } from \"../types\";\nimport {\n BugIcon,\n CameraIcon,\n CheckIcon,\n CloseIcon,\n IdeaIcon,\n PencilIcon,\n QuestionIcon,\n TargetIcon,\n TrashIcon,\n} from \"./icons\";\nimport type { WidgetState } from \"./use-widget-state\";\n\nconst CATEGORY_META: Record<\n FeedbackWidgetCategory,\n { icon: ComponentType; labelKey: keyof FeedbackWidgetLabels }\n> = {\n bug: { icon: BugIcon, labelKey: \"categoryBug\" },\n idea: { icon: IdeaIcon, labelKey: \"categoryIdea\" },\n question: { icon: QuestionIcon, labelKey: \"categoryQuestion\" },\n};\n\nfunction Attachment({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n if (state.isCapturing) {\n return (\n <div className=\"card\">\n <div className=\"thumb\" />\n <div className=\"meta\">\n <strong>{labels.retakeHint}</strong>\n <span>…</span>\n </div>\n </div>\n );\n }\n\n if (!state.capture) {\n return (\n <button\n className=\"ghost-btn\"\n onClick={() => state.takeCapture()}\n type=\"button\"\n >\n <CameraIcon />\n {labels.attachScreenshot}\n </button>\n );\n }\n\n const annotationCount = state.annotations.length;\n\n return (\n <div className=\"card\">\n <div className=\"thumb\">\n <img\n alt=\"\"\n height={state.capture.height}\n src={state.capture.objectUrl}\n width={state.capture.width}\n />\n </div>\n <div className=\"meta\">\n <strong className=\"truncate\">{labels.retakeHint}</strong>\n <span className=\"truncate\">\n {state.capture.width}×{state.capture.height}\n {annotationCount > 0 ? ` · ${annotationCount} marks` : \"\"}\n </span>\n </div>\n <div className=\"actions\">\n <button\n aria-label={labels.annotateHint}\n className=\"icon-btn\"\n onClick={() => state.setStep(\"annotate\")}\n title={labels.annotateHint}\n type=\"button\"\n >\n <PencilIcon />\n </button>\n <button\n aria-label={labels.recapture}\n className=\"icon-btn\"\n onClick={() => state.takeCapture()}\n title={labels.recapture}\n type=\"button\"\n >\n <CameraIcon />\n </button>\n <button\n aria-label={labels.removeScreenshot}\n className=\"icon-btn\"\n onClick={state.removeCapture}\n title={labels.removeScreenshot}\n type=\"button\"\n >\n <TrashIcon />\n </button>\n </div>\n </div>\n );\n}\n\n/** Shows the reporter exactly what will be sent about the element they picked. */\nfunction Selection({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const { elementCapture, selection } = state;\n if (!selection) {\n return (\n <button\n className=\"ghost-btn\"\n onClick={() => state.setStep(\"picking\")}\n type=\"button\"\n >\n <TargetIcon />\n {labels.pickElement}\n </button>\n );\n }\n\n const component = selection.componentStack[0];\n\n return (\n <div className=\"card\">\n <div className=\"thumb contain\">\n {elementCapture && (\n <img\n alt=\"\"\n height={elementCapture.height}\n src={elementCapture.objectUrl}\n width={elementCapture.width}\n />\n )}\n </div>\n <div className=\"meta\">\n <strong className=\"truncate\">\n {component ? `<${component}>` : selection.label}\n </strong>\n <span className=\"truncate\">\n {selection.region ?? selection.sourceLocation ?? selection.selector}\n </span>\n </div>\n <div className=\"actions\">\n <button\n aria-label={labels.pickElement}\n className=\"icon-btn\"\n onClick={() => state.setStep(\"picking\")}\n title={labels.pickElement}\n type=\"button\"\n >\n <TargetIcon />\n </button>\n <button\n aria-label={labels.cancel}\n className=\"icon-btn\"\n onClick={state.clearSelection}\n title={labels.cancel}\n type=\"button\"\n >\n <CloseIcon />\n </button>\n </div>\n </div>\n );\n}\n\nexport function FeedbackPanel({\n categories,\n labels,\n state,\n}: {\n categories: FeedbackWidgetCategory[];\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const messageRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n messageRef.current?.focus();\n }, []);\n\n if (state.step === \"success\") {\n return (\n <section aria-live=\"polite\" className=\"panel\">\n <div className=\"done\">\n <CheckIcon />\n <h2>{labels.successTitle}</h2>\n <p>{labels.successMessage}</p>\n </div>\n </section>\n );\n }\n\n return (\n <section aria-label={labels.title} className=\"panel\">\n <header className=\"head\">\n <h2>{labels.title}</h2>\n <span className=\"spacer\" />\n <button\n aria-label={labels.cancel}\n className=\"icon-btn\"\n onClick={state.close}\n type=\"button\"\n >\n <CloseIcon />\n </button>\n </header>\n\n <form\n className=\"body\"\n onSubmit={(event) => {\n event.preventDefault();\n state.submit();\n }}\n >\n {categories.length > 1 && (\n <fieldset className=\"segmented\">\n {categories.map((value) => {\n const { icon: Icon, labelKey } = CATEGORY_META[value];\n return (\n <button\n aria-pressed={state.category === value}\n key={value}\n onClick={() => state.setCategory(value)}\n type=\"button\"\n >\n <Icon />\n {labels[labelKey]}\n </button>\n );\n })}\n </fieldset>\n )}\n\n <textarea\n aria-label={labels.descriptionPlaceholder}\n maxLength={4000}\n onChange={(event) => state.setMessage(event.target.value)}\n placeholder={labels.descriptionPlaceholder}\n ref={messageRef}\n value={state.message}\n />\n\n <div className=\"attachments\">\n <Attachment labels={labels} state={state} />\n <Selection labels={labels} state={state} />\n </div>\n\n {state.isAnonymous && (\n <input\n aria-label={labels.emailLabel}\n autoComplete=\"email\"\n onChange={(event) => state.setEmail(event.target.value)}\n placeholder={labels.emailPlaceholder}\n type=\"email\"\n value={state.email}\n />\n )}\n\n <div aria-hidden=\"true\" className=\"hp\">\n <input\n autoComplete=\"off\"\n name=\"company-website\"\n onChange={(event) => state.setHoneypot(event.target.value)}\n tabIndex={-1}\n value={state.honeypot}\n />\n </div>\n\n {state.error && <p className=\"error\">{state.error}</p>}\n\n <button\n className=\"submit\"\n disabled={state.isSubmitting || !state.message.trim()}\n type=\"submit\"\n >\n {state.isSubmitting ? <span className=\"spinner\" /> : labels.submit}\n </button>\n </form>\n\n <footer className=\"footer\" data-dismissible={state.canDismiss}>\n {state.canDismiss && (\n <button className=\"dismiss-btn\" onClick={state.dismiss} type=\"button\">\n {labels.dismissForDays.replace(\n \"{days}\",\n String(state.dismissForDays)\n )}\n </button>\n )}\n <span>\n Powered by{\" \"}\n <a\n href=\"https://reflet.app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n Reflet\n </a>\n </span>\n </footer>\n </section>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { WIDGET_MARKER } from \"../core/capture\";\nimport { describeElement, describeRegion } from \"../core/element-selector\";\nimport { getFiberFromNode, resolveComponentStack } from \"../core/react-source\";\n\nconst LABEL_HEIGHT = 24;\nconst LABEL_GAP = 6;\n\ninterface HoverTarget {\n componentName?: string;\n element: Element;\n label: string;\n rect: DOMRect;\n region?: string;\n}\n\nfunction isWidgetOwned(element: Element): boolean {\n return element.closest(`[${WIDGET_MARKER}]`) !== null;\n}\n\nfunction elementUnder(x: number, y: number): Element | null {\n const element = document.elementFromPoint(x, y);\n if (!element || isWidgetOwned(element)) {\n return null;\n }\n return element;\n}\n\nfunction describeTarget(element: Element): HoverTarget {\n return {\n componentName: resolveComponentStack(getFiberFromNode(element))[0],\n element,\n label: describeElement(element),\n rect: element.getBoundingClientRect(),\n region: describeRegion(element),\n };\n}\n\n/**\n * Points at any element in the page the way a coding agent needs it: the React\n * component that owns it plus the page region it lives in.\n */\nexport function ElementPicker({\n hint,\n onCancel,\n onPick,\n}: {\n hint: string;\n onCancel: () => void;\n onPick: (element: Element) => void;\n}) {\n const [target, setTarget] = useState<HoverTarget | null>(null);\n\n useEffect(() => {\n const swallow = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onMove = (event: PointerEvent) => {\n const element = elementUnder(event.clientX, event.clientY);\n if (!element) {\n setTarget(null);\n return;\n }\n\n setTarget((current) =>\n current?.element === element\n ? { ...current, rect: element.getBoundingClientRect() }\n : describeTarget(element)\n );\n };\n\n const onClick = (event: MouseEvent) => {\n swallow(event);\n const element = elementUnder(event.clientX, event.clientY);\n if (element) {\n onPick(element);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n swallow(event);\n onCancel();\n }\n };\n\n // Capture phase everywhere: the host app must not react to the pick.\n document.addEventListener(\"pointermove\", onMove, true);\n document.addEventListener(\"pointerdown\", swallow, true);\n document.addEventListener(\"mousedown\", swallow, true);\n document.addEventListener(\"mouseup\", swallow, true);\n document.addEventListener(\"click\", onClick, true);\n document.addEventListener(\"keydown\", onKeyDown, true);\n\n const previousCursor = document.body.style.cursor;\n document.body.style.cursor = \"crosshair\";\n\n return () => {\n document.removeEventListener(\"pointermove\", onMove, true);\n document.removeEventListener(\"pointerdown\", swallow, true);\n document.removeEventListener(\"mousedown\", swallow, true);\n document.removeEventListener(\"mouseup\", swallow, true);\n document.removeEventListener(\"click\", onClick, true);\n document.removeEventListener(\"keydown\", onKeyDown, true);\n document.body.style.cursor = previousCursor;\n };\n }, [onCancel, onPick]);\n\n const rect = target?.rect;\n const labelAbove = rect ? rect.top > LABEL_HEIGHT + LABEL_GAP : true;\n\n return (\n <div>\n {rect && (\n <div\n className=\"picker-box\"\n style={{\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n }}\n />\n )}\n {rect && target && (\n <div\n className=\"picker-label\"\n style={{\n left: Math.max(4, rect.left),\n top: labelAbove\n ? rect.top - LABEL_HEIGHT - LABEL_GAP\n : rect.bottom + LABEL_GAP,\n }}\n >\n <strong>\n {target.componentName ? `<${target.componentName}>` : target.label}\n </strong>\n {target.region && <span>{target.region}</span>}\n </div>\n )}\n <div className=\"picker-hint\">\n {hint} <kbd>Esc</kbd>\n </div>\n </div>\n );\n}\n","/**\n * Styles for the feedback widget. Injected into a shadow root, so nothing here\n * leaks into the host app and nothing from the host app leaks in.\n */\nexport const WIDGET_STYLES = `\n:host {\n --rf-bg: #ffffff;\n --rf-bg-subtle: rgb(55 53 47 / 4%);\n --rf-bg-hover: rgb(55 53 47 / 7%);\n --rf-border: rgb(55 53 47 / 9%);\n --rf-text: #37352f;\n --rf-text-muted: rgb(55 53 47 / 55%);\n --rf-primary: #37352f;\n --rf-primary-text: #ffffff;\n --rf-accent: #2383e2;\n --rf-danger: #d44c47;\n --rf-success: #448361;\n --rf-radius: 12px;\n --rf-radius-sm: 8px;\n --rf-shadow-inset: inset 0 0 0 1px var(--rf-border);\n --rf-shadow-low: 0 0 0 1px rgb(15 15 15 / 4%), 0 1px 2px rgb(15 15 15 / 6%), 0 4px 10px -4px rgb(15 15 15 / 10%);\n --rf-shadow: 0 0 0 1px rgb(15 15 15 / 4%), 0 2px 5px -1px rgb(15 15 15 / 7%), 0 12px 32px -8px rgb(15 15 15 / 16%);\n --rf-ring: 0 0 0 3px color-mix(in srgb, var(--rf-accent) 20%, transparent);\n --rf-ease: cubic-bezier(0.16, 1, 0.3, 1);\n color-scheme: light;\n all: initial;\n font-family: var(--rf-font, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif);\n}\n\n:host([data-theme=\"dark\"]) {\n --rf-bg: #202020;\n --rf-bg-subtle: rgb(255 255 255 / 5%);\n --rf-bg-hover: rgb(255 255 255 / 9%);\n --rf-border: rgb(255 255 255 / 9%);\n --rf-text: #ebeae8;\n --rf-text-muted: rgb(255 255 255 / 46%);\n --rf-primary: #f1efec;\n --rf-primary-text: #1c1c1b;\n --rf-accent: #529cca;\n --rf-danger: #eb5757;\n --rf-success: #4dab74;\n --rf-shadow-low: 0 0 0 1px rgb(255 255 255 / 6%), 0 1px 2px rgb(0 0 0 / 30%), 0 4px 10px -4px rgb(0 0 0 / 40%);\n --rf-shadow: 0 0 0 1px rgb(255 255 255 / 7%), 0 2px 5px -1px rgb(0 0 0 / 35%), 0 14px 36px -10px rgb(0 0 0 / 55%);\n color-scheme: dark;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n.root {\n position: fixed;\n z-index: 2147483000;\n display: flex;\n flex-direction: column;\n gap: 10px;\n font-family: inherit;\n font-size: 13.5px;\n line-height: 1.45;\n color: var(--rf-text);\n}\n\n.root[data-position$=\"right\"] { right: var(--rf-offset); align-items: flex-end; }\n.root[data-position$=\"left\"] { left: var(--rf-offset); align-items: flex-start; }\n.root[data-position^=\"bottom\"] { bottom: var(--rf-offset); }\n.root[data-position^=\"top\"] { top: var(--rf-offset); flex-direction: column-reverse; }\n\nbutton {\n font: inherit;\n color: inherit;\n margin: 0;\n cursor: pointer;\n border: 0;\n background: none;\n}\n\n:focus-visible { outline: none; box-shadow: var(--rf-ring); }\n\n.launcher {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 11px;\n border-radius: var(--rf-radius-sm);\n background: var(--rf-primary);\n color: var(--rf-primary-text);\n font-size: 13px;\n font-weight: 500;\n letter-spacing: -0.005em;\n box-shadow: var(--rf-shadow-low);\n transition: transform 240ms var(--rf-ease), box-shadow 240ms var(--rf-ease), opacity 160ms var(--rf-ease);\n}\n.launcher:hover { transform: translateY(-1px); box-shadow: var(--rf-shadow); }\n.launcher:active { transform: translateY(0) scale(0.98); }\n\n.launcher-icon { position: relative; width: 15px; height: 15px; flex: none; }\n.launcher-icon svg { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity 200ms var(--rf-ease), transform 320ms var(--rf-ease); }\n.launcher-icon .on-close { opacity: 0; transform: rotate(-90deg) scale(0.6); }\n.launcher[data-open=\"true\"] .on-open { opacity: 0; transform: rotate(90deg) scale(0.6); }\n.launcher[data-open=\"true\"] .on-close { opacity: 1; transform: none; }\n\n.panel {\n width: min(352px, calc(100vw - 24px));\n max-height: min(600px, calc(100vh - 96px));\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--rf-bg);\n border-radius: var(--rf-radius);\n box-shadow: var(--rf-shadow);\n animation: rf-in 220ms var(--rf-ease);\n}\n.root[data-position^=\"bottom\"] .panel { transform-origin: bottom center; }\n.root[data-position^=\"top\"] .panel { transform-origin: top center; animation-name: rf-in-top; }\n\n@keyframes rf-in {\n from { opacity: 0; transform: translateY(6px) scale(0.985); }\n}\n@keyframes rf-in-top {\n from { opacity: 0; transform: translateY(-6px) scale(0.985); }\n}\n@keyframes rf-fade { from { opacity: 0; } }\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after { animation: none !important; transition: none !important; }\n}\n\n.head {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 10px 4px 14px;\n}\n.head h2 { margin: 0; font-size: 13.5px; font-weight: 600; letter-spacing: -0.01em; }\n.head .spacer { flex: 1; }\n\n.icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n flex: none;\n border-radius: 6px;\n color: var(--rf-text-muted);\n transition: background 120ms var(--rf-ease), color 120ms var(--rf-ease);\n}\n.icon-btn:hover { background: var(--rf-bg-hover); color: var(--rf-text); }\n\n.body { display: flex; flex-direction: column; gap: 8px; padding: 6px 14px 14px; overflow-y: auto; }\n\n.segmented {\n border: 0;\n margin: 0;\n min-inline-size: 0;\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n gap: 2px;\n padding: 2px;\n background: var(--rf-bg-subtle);\n border-radius: var(--rf-radius-sm);\n}\n.segmented button {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 5px;\n height: 26px;\n border-radius: 6px;\n font-size: 12.5px;\n font-weight: 500;\n color: var(--rf-text-muted);\n transition: background 160ms var(--rf-ease), color 160ms var(--rf-ease);\n}\n.segmented button:hover { color: var(--rf-text); }\n.segmented button[aria-pressed=\"true\"] {\n background: var(--rf-bg);\n color: var(--rf-text);\n box-shadow: var(--rf-shadow-low);\n}\n\ntextarea, input[type=\"email\"] {\n width: 100%;\n padding: 8px 10px;\n font: inherit;\n color: var(--rf-text);\n background: var(--rf-bg);\n border: 1px solid var(--rf-border);\n border-radius: var(--rf-radius-sm);\n transition: border-color 160ms var(--rf-ease), box-shadow 160ms var(--rf-ease);\n}\ntextarea { min-height: 84px; max-height: 220px; resize: none; }\ntextarea::placeholder, input::placeholder { color: var(--rf-text-muted); }\ntextarea:focus, input:focus { outline: none; border-color: color-mix(in srgb, var(--rf-accent) 55%, transparent); box-shadow: var(--rf-ring); }\n\n.attachments { display: flex; flex-wrap: wrap; gap: 6px; }\n\n.card {\n flex: 1 0 100%;\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n padding: 6px;\n border-radius: 10px;\n background: var(--rf-bg-subtle);\n animation: rf-fade 200ms var(--rf-ease);\n}\n.thumb {\n position: relative;\n flex: 0 0 60px;\n height: 42px;\n overflow: hidden;\n border-radius: 6px;\n background: var(--rf-bg);\n box-shadow: var(--rf-shadow-inset);\n}\n.thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }\n.thumb.contain img { object-fit: contain; object-position: center; }\n.card .meta { display: flex; flex-direction: column; justify-content: center; gap: 1px; min-width: 0; }\n.card .meta strong { font-size: 12.5px; font-weight: 550; }\n.card .meta span { font-size: 11.5px; color: var(--rf-text-muted); }\n.card .actions { display: flex; gap: 2px; margin-left: auto; align-items: center; }\n.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.card code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; }\n\n.ghost-btn {\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 30px;\n padding: 0 10px;\n font-size: 12.5px;\n font-weight: 500;\n color: var(--rf-text-muted);\n border-radius: var(--rf-radius-sm);\n box-shadow: var(--rf-shadow-inset);\n transition: background 160ms var(--rf-ease), color 160ms var(--rf-ease);\n}\n.ghost-btn:hover { background: var(--rf-bg-subtle); color: var(--rf-text); }\n\n.submit {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n margin-top: 2px;\n font-size: 13px;\n font-weight: 550;\n color: var(--rf-primary-text);\n background: var(--rf-primary);\n border-radius: var(--rf-radius-sm);\n transition: opacity 160ms var(--rf-ease), transform 160ms var(--rf-ease);\n}\n.submit:hover:not(:disabled) { opacity: 0.88; }\n.submit:active:not(:disabled) { transform: scale(0.99); }\n.submit:disabled { opacity: 0.35; cursor: not-allowed; }\n\n.error { margin: 0; font-size: 12px; color: var(--rf-danger); }\n\n.footer {\n min-height: 34px;\n padding: 0 14px;\n border-top: 1px solid var(--rf-border);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n font-size: 11px;\n color: var(--rf-text-muted);\n}\n.footer[data-dismissible=\"true\"] { justify-content: space-between; }\n.footer a { color: inherit; text-decoration: none; font-weight: 550; transition: color 120ms var(--rf-ease); }\n.footer a:hover { color: var(--rf-text); }\n.dismiss-btn {\n align-self: stretch;\n color: inherit;\n font-size: 11px;\n transition: color 120ms var(--rf-ease);\n}\n.dismiss-btn:hover { color: var(--rf-text); }\n\n.done { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 30px 20px 34px; text-align: center; }\n.done svg { color: var(--rf-success); }\n.done h2 { margin: 0; font-size: 14px; font-weight: 600; }\n.done p { margin: 0; font-size: 12.5px; color: var(--rf-text-muted); }\n\n.spinner {\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n opacity: 0.6;\n animation: rf-spin 700ms linear infinite;\n}\n@keyframes rf-spin { to { transform: rotate(360deg); } }\n\n.hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n\n.overlay {\n position: fixed;\n inset: 0;\n z-index: 2147483001;\n display: flex;\n flex-direction: column;\n background: rgb(15 15 15 / 76%);\n backdrop-filter: blur(3px);\n animation: rf-fade 180ms var(--rf-ease);\n}\n\n.editor { flex: 1; display: flex; align-items: center; justify-content: center; padding: 24px 24px 0; min-height: 0; }\n.editor canvas {\n max-width: 100%;\n max-height: 100%;\n border-radius: 10px;\n box-shadow: 0 20px 60px -16px rgb(0 0 0 / 70%);\n cursor: crosshair;\n touch-action: none;\n}\n\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: wrap;\n padding: 14px 16px calc(14px + env(safe-area-inset-bottom));\n}\n.toolbar .group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px;\n background: var(--rf-bg);\n border-radius: 10px;\n box-shadow: var(--rf-shadow);\n}\n.tool {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border-radius: 7px;\n color: var(--rf-text-muted);\n transition: background 160ms var(--rf-ease), color 160ms var(--rf-ease);\n}\n.tool:hover { background: var(--rf-bg-hover); color: var(--rf-text); }\n.tool[aria-pressed=\"true\"] { background: var(--rf-bg-hover); color: var(--rf-text); }\n.swatch {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n border: 2px solid transparent;\n transition: transform 200ms var(--rf-ease), border-color 160ms var(--rf-ease);\n}\n.swatch[aria-pressed=\"true\"] { border-color: var(--rf-text); transform: scale(1.15); }\n.toolbar .done-btn {\n height: 30px;\n padding: 0 13px;\n font-size: 13px;\n font-weight: 550;\n border-radius: 7px;\n color: var(--rf-primary-text);\n background: var(--rf-primary);\n transition: opacity 160ms var(--rf-ease);\n}\n.toolbar .done-btn:hover { opacity: 0.88; }\n\n.picker-box {\n position: fixed;\n pointer-events: none;\n border-radius: 5px;\n background: color-mix(in srgb, var(--rf-accent) 10%, transparent);\n box-shadow: 0 0 0 2px var(--rf-accent), 0 0 0 5px color-mix(in srgb, var(--rf-accent) 18%, transparent);\n transition: top 130ms var(--rf-ease), left 130ms var(--rf-ease), width 130ms var(--rf-ease), height 130ms var(--rf-ease);\n}\n.picker-label {\n position: fixed;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: min(420px, 90vw);\n height: 24px;\n padding: 0 8px;\n font-size: 11.5px;\n font-weight: 500;\n color: #ffffff;\n background: var(--rf-accent);\n border-radius: 6px;\n box-shadow: 0 4px 12px -3px rgb(15 15 15 / 35%);\n white-space: nowrap;\n overflow: hidden;\n transition: top 130ms var(--rf-ease), left 130ms var(--rf-ease);\n}\n.picker-label strong { flex: none; font-weight: 600; }\n.picker-label span { min-width: 0; overflow: hidden; text-overflow: ellipsis; opacity: 0.75; }\n.picker-hint {\n position: fixed;\n left: 50%;\n bottom: 24px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n font-size: 12.5px;\n color: var(--rf-text);\n background: var(--rf-bg);\n border-radius: 10px;\n box-shadow: var(--rf-shadow);\n animation: rf-fade 240ms var(--rf-ease);\n}\n.picker-hint kbd {\n padding: 1px 5px;\n font: inherit;\n font-size: 11px;\n color: var(--rf-text-muted);\n border-radius: 4px;\n background: var(--rf-bg-subtle);\n box-shadow: var(--rf-shadow-inset);\n}\n\n@media (pointer: coarse) {\n .icon-btn, .tool, .swatch {\n width: 44px;\n height: 44px;\n }\n\n .launcher, .segmented button, .ghost-btn, .submit, .toolbar .done-btn {\n min-height: 44px;\n }\n\n .dismiss-btn, .footer a {\n display: inline-flex;\n min-height: 44px;\n align-items: center;\n }\n\n .footer a {\n min-width: 44px;\n justify-content: center;\n }\n}\n`;\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { WIDGET_MARKER } from \"../core/capture\";\nimport { WIDGET_STYLES } from \"./styles\";\n\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport type WidgetTheme = \"auto\" | \"dark\" | \"light\";\n\nfunction useResolvedTheme(theme: WidgetTheme): \"dark\" | \"light\" {\n const [systemDark, setSystemDark] = useState(false);\n\n useEffect(() => {\n if (theme !== \"auto\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n\n const query = window.matchMedia(DARK_QUERY);\n setSystemDark(query.matches);\n\n const onChange = (event: MediaQueryListEvent) =>\n setSystemDark(event.matches);\n query.addEventListener(\"change\", onChange);\n return () => query.removeEventListener(\"change\", onChange);\n }, [theme]);\n\n if (theme === \"auto\") {\n return systemDark ? \"dark\" : \"light\";\n }\n return theme;\n}\n\n/**\n * Hosts the widget in a shadow root: the app's CSS cannot reach the panel and\n * the panel's CSS cannot reach the app. Direct DOM work is unavoidable here —\n * React has no declarative way to create a shadow root.\n */\nexport function ShadowPortal({\n children,\n offset,\n primaryColor,\n theme,\n}: {\n children: ReactNode;\n offset: number;\n primaryColor?: string;\n theme: WidgetTheme;\n}) {\n const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);\n const resolvedTheme = useResolvedTheme(theme);\n\n useEffect(() => {\n const host = document.createElement(\"div\");\n host.setAttribute(WIDGET_MARKER, \"\");\n const root = host.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = WIDGET_STYLES;\n root.append(style);\n document.body.append(host);\n setShadowRoot(root);\n\n return () => host.remove();\n }, []);\n\n useEffect(() => {\n const host = shadowRoot?.host;\n if (!(host instanceof HTMLElement)) {\n return;\n }\n\n host.setAttribute(\"data-theme\", resolvedTheme);\n host.style.setProperty(\"--rf-offset\", `${offset}px`);\n if (primaryColor) {\n host.style.setProperty(\"--rf-primary\", primaryColor);\n }\n }, [shadowRoot, resolvedTheme, primaryColor, offset]);\n\n if (!shadowRoot) {\n return null;\n }\n\n return createPortal(children, shadowRoot);\n}\n","import type { ConsoleEvent } from \"../../types\";\n\nconst DEFAULT_LIMIT = 30;\nconst MAX_MESSAGE_LENGTH = 1000;\nconst RECORDED_METHODS = [\"error\", \"warn\"] as const;\n\ntype RecordedMethod = (typeof RECORDED_METHODS)[number];\n\nexport interface ConsoleRecorder {\n events: () => ConsoleEvent[];\n stop: () => void;\n}\n\nfunction serializeArgument(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof Error) {\n return `${value.name}: ${value.message}`;\n }\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value) ?? \"[unserializable]\";\n } catch {\n return \"[unserializable]\";\n }\n }\n if (typeof value === \"function\") {\n return \"[function]\";\n }\n return String(value);\n}\n\nfunction formatMessage(args: unknown[]): string {\n const message = args.map(serializeArgument).join(\" \");\n return message.length > MAX_MESSAGE_LENGTH\n ? `${message.slice(0, MAX_MESSAGE_LENGTH - 1)}…`\n : message;\n}\n\n/**\n * Buffers the console noise a user saw right before reporting a bug.\n * Wrappers delegate to the previous implementation, so nothing is swallowed.\n */\nexport function startConsoleRecorder(options?: {\n limit?: number;\n}): ConsoleRecorder {\n const limit = options?.limit ?? DEFAULT_LIMIT;\n const buffer: ConsoleEvent[] = [];\n let active = true;\n\n const push = (level: ConsoleEvent[\"level\"], message: string) => {\n if (!(active && message)) {\n return;\n }\n buffer.push({ level, message, timestamp: Date.now() });\n if (buffer.length > limit) {\n buffer.splice(0, buffer.length - limit);\n }\n };\n\n const originals = new Map<RecordedMethod, (...args: unknown[]) => void>();\n const wrappers = new Map<RecordedMethod, (...args: unknown[]) => void>();\n\n for (const method of RECORDED_METHODS) {\n const original = console[method];\n const wrapper = (...args: unknown[]) => {\n push(method, formatMessage(args));\n Reflect.apply(original, console, args);\n };\n originals.set(method, original);\n wrappers.set(method, wrapper);\n console[method] = wrapper;\n }\n\n const onError = (event: ErrorEvent) => {\n const where = event.filename\n ? ` (${event.filename}:${event.lineno}:${event.colno})`\n : \"\";\n push(\"error\", `${event.message}${where}`);\n };\n\n const onRejection = (event: PromiseRejectionEvent) => {\n push(\"error\", `Unhandled rejection: ${serializeArgument(event.reason)}`);\n };\n\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n\n return {\n events: () => buffer.slice(),\n stop: () => {\n if (!active) {\n return;\n }\n active = false;\n buffer.length = 0;\n\n for (const method of RECORDED_METHODS) {\n const original = originals.get(method);\n // Another recorder wrapped ours — leave its chain intact.\n if (original && console[method] === wrappers.get(method)) {\n console[method] = original;\n }\n }\n\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n },\n };\n}\n","import type { ElementSelection } from \"../../types\";\nimport type { Annotation, CapturedImage } from \"../types\";\nimport { capturedFromCanvas, captureViewport, releaseCapture } from \"./capture\";\n\nconst MIN_CONTEXT_PADDING = 24;\nconst MAX_CONTEXT_WIDTH = 2000;\nconst CLOSE_UP_MAX_WIDTH = 1200;\nconst SELECTION_COLOR = \"#4f46e5\";\nconst OUTLINE_COLOR = \"#4f46e5\";\nconst OUTLINE_GLOW = \"#ffffff\";\nconst OUTLINE_WIDTH = 3;\nconst GLOW_WIDTH = 6;\nconst DIM_OVERLAY = \"rgba(15, 23, 42, 0.45)\";\n\n/**\n * Tightest ancestor that keeps some breathing room around the pick — the zoom\n * stays zoomed instead of growing to a giant section. Only when nothing up\n * the tree clears the minimum does the widest candidate below the cap win.\n */\nexport function contextRootFor(element: Element): Element {\n const target = element.getBoundingClientRect();\n const coversAtLeast = (box: DOMRect, margin: number): boolean =>\n box.left <= target.left - margin &&\n box.right >= target.right + margin &&\n box.top <= target.top - margin &&\n box.bottom >= target.bottom + margin;\n\n let tightest: Element | null = null;\n let current = element.parentElement;\n\n while (current && current !== document.documentElement) {\n const box = current.getBoundingClientRect();\n\n if (coversAtLeast(box, MIN_CONTEXT_PADDING)) {\n return current;\n }\n tightest ??= box.width < MAX_CONTEXT_WIDTH ? current : null;\n\n current = current.parentElement;\n }\n\n return tightest ?? element;\n}\n\nexport interface CloseUpGeometry {\n height: number;\n scale: number;\n width: number;\n x: number;\n y: number;\n}\n\n/** Where the picked element sits inside the context shot, in image pixels. */\nexport function closeUpGeometry(params: {\n capture: Pick<CapturedImage, \"height\" | \"width\">;\n elementRect: DOMRect;\n rootRect: DOMRect;\n}): CloseUpGeometry {\n const scale =\n params.rootRect.width > 0\n ? params.capture.width / params.rootRect.width\n : 1;\n\n return {\n height: Math.round(params.elementRect.height * scale),\n scale,\n width: Math.round(params.elementRect.width * scale),\n x: Math.round((params.elementRect.left - params.rootRect.left) * scale),\n y: Math.round((params.elementRect.top - params.rootRect.top) * scale),\n };\n}\n\n/** Rectangle annotation marking the picked element on the viewport shot. */\nexport function highlightFor(\n selection: ElementSelection,\n capture: CapturedImage\n): Annotation {\n const scale = capture.width / window.innerWidth;\n const { rect } = selection;\n\n return {\n color: SELECTION_COLOR,\n end: {\n x: (rect.x + rect.width) * scale,\n y: (rect.y + rect.height) * scale,\n },\n id: `selection-${rect.x}-${rect.y}`,\n start: { x: rect.x * scale, y: rect.y * scale },\n tool: \"rectangle\",\n };\n}\n\nfunction drawZoneOverlay(\n context: CanvasRenderingContext2D,\n zone: CloseUpGeometry\n): void {\n context.save();\n context.fillStyle = DIM_OVERLAY;\n context.beginPath();\n context.rect(0, 0, context.canvas.width, context.canvas.height);\n context.rect(zone.x, zone.y, zone.width, zone.height);\n context.fill(\"evenodd\");\n\n for (const [color, width] of [\n [OUTLINE_GLOW, GLOW_WIDTH],\n [OUTLINE_COLOR, OUTLINE_WIDTH],\n ] as const) {\n context.strokeStyle = color;\n context.lineWidth = width * zone.scale;\n context.strokeRect(zone.x, zone.y, zone.width, zone.height);\n }\n context.restore();\n}\n\nfunction drawCloseUp(\n capture: CapturedImage,\n zone: CloseUpGeometry\n): Promise<CapturedImage | null> {\n return new Promise((resolve) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = capture.width;\n canvas.height = capture.height;\n const context = canvas.getContext(\"2d\");\n const image = new Image();\n\n image.onload = () => {\n if (!context) {\n resolve(null);\n return;\n }\n context.drawImage(image, 0, 0, capture.width, capture.height);\n drawZoneOverlay(context, zone);\n resolve(capturedFromCanvas(canvas, CLOSE_UP_MAX_WIDTH));\n };\n image.onerror = () => resolve(null);\n image.src = capture.objectUrl;\n });\n}\n\n/**\n * Zoomed view of the picked zone: the surrounding area captured for context,\n * everything outside the selection dimmed and the zone framed with a glowing\n * outline — unambiguous to eyes and vision models alike.\n * Falls back to the plain context shot when the overlay cannot be drawn.\n */\nexport async function captureElementCloseUp(\n element: Element\n): Promise<CapturedImage | null> {\n try {\n const root = contextRootFor(element);\n const rootRect = root.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n const capture = await captureViewport({\n element: root,\n maxWidth: CLOSE_UP_MAX_WIDTH,\n });\n if (!capture || root === element) {\n return capture;\n }\n\n const zone = closeUpGeometry({ capture, elementRect, rootRect });\n const outlined = await drawCloseUp(capture, zone);\n\n if (outlined) {\n releaseCapture(capture);\n return outlined;\n }\n return capture;\n } catch {\n return null;\n }\n}\n","import type { Reflet } from \"../../client\";\nimport type {\n CreateFeedbackParams,\n CreateFeedbackResponse,\n FeedbackContext,\n SaveScreenshotParams,\n} from \"../../types\";\nimport type {\n Annotation,\n CapturedImage,\n FeedbackWidgetCategory,\n} from \"../types\";\nimport { toWireAnnotations } from \"./annotations\";\n\nconst MAX_TITLE_LENGTH = 100;\nconst NEWLINE = /\\r?\\n/;\n\nexport interface FeedbackTransport {\n create: (params: CreateFeedbackParams) => Promise<CreateFeedbackResponse>;\n getScreenshotUploadUrl: () => Promise<{ uploadUrl: string }>;\n saveScreenshot: (\n params: SaveScreenshotParams\n ) => Promise<{ screenshotId: string }>;\n uploadImage: (uploadUrl: string, image: CapturedImage) => Promise<string>;\n}\n\nexport interface WidgetSubmission {\n annotated: CapturedImage | null;\n annotations: Annotation[];\n category: FeedbackWidgetCategory;\n context: FeedbackContext;\n /** Close-up of the picked element, captured when the reporter pointed at it. */\n element: CapturedImage | null;\n email?: string;\n isAnonymous: boolean;\n message: string;\n screenshot: CapturedImage | null;\n}\n\nexport interface SubmitResult {\n feedbackId: string;\n screenshotSaved: boolean;\n}\n\n/** First line of the message, cut on a word boundary so titles stay readable. */\nexport function deriveTitle(message: string): string {\n const firstLine =\n message\n .split(NEWLINE)\n .map((line) => line.trim())\n .find(Boolean) ?? \"\";\n\n if (firstLine.length <= MAX_TITLE_LENGTH) {\n return firstLine;\n }\n\n const clipped = firstLine.slice(0, MAX_TITLE_LENGTH - 1);\n const lastSpace = clipped.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? clipped.slice(0, lastSpace) : clipped).trimEnd()}…`;\n}\n\nexport function buildDescription(params: {\n category: FeedbackWidgetCategory;\n email?: string;\n isAnonymous: boolean;\n message: string;\n}): string {\n const { category, email, isAnonymous, message } = params;\n const label = category.charAt(0).toUpperCase() + category.slice(1);\n const contact = isAnonymous && email ? `\\n\\n---\\nContact: ${email}` : \"\";\n\n return `[${label}] ${message.trim()}${contact}`;\n}\n\nasync function upload(\n transport: FeedbackTransport,\n image: CapturedImage\n): Promise<string> {\n const { uploadUrl } = await transport.getScreenshotUploadUrl();\n return await transport.uploadImage(uploadUrl, image);\n}\n\nasync function attachScreenshot(\n transport: FeedbackTransport,\n feedbackId: string,\n submission: WidgetSubmission\n): Promise<boolean> {\n const { annotated, annotations, context, screenshot } = submission;\n if (!screenshot) {\n return false;\n }\n\n const storageId = await upload(transport, screenshot);\n const annotatedStorageId = annotated\n ? await upload(transport, annotated)\n : undefined;\n const wireAnnotations = toWireAnnotations(annotations);\n\n await transport.saveScreenshot({\n annotatedStorageId,\n annotations: wireAnnotations.length > 0 ? wireAnnotations : undefined,\n captureSource: \"widget\",\n feedbackId,\n filename: \"screenshot.png\",\n height: screenshot.height,\n mimeType: screenshot.mimeType,\n pageUrl: context.url,\n size: screenshot.blob.size,\n storageId,\n width: screenshot.width,\n });\n\n return true;\n}\n\nasync function attachElement(\n transport: FeedbackTransport,\n feedbackId: string,\n submission: WidgetSubmission\n): Promise<void> {\n const { context, element } = submission;\n if (!element) {\n return;\n }\n\n await transport.saveScreenshot({\n captureSource: \"element\",\n feedbackId,\n filename: \"element.png\",\n height: element.height,\n mimeType: element.mimeType,\n pageUrl: context.url,\n size: element.blob.size,\n storageId: await upload(transport, element),\n width: element.width,\n });\n}\n\n/**\n * Creates the feedback first, then attaches the capture. A failed upload is\n * reported back but never discards what the user wrote.\n */\nexport async function submitWidgetFeedback(\n transport: FeedbackTransport,\n submission: WidgetSubmission\n): Promise<SubmitResult> {\n const title = deriveTitle(submission.message);\n if (!title) {\n throw new Error(\"Please describe your feedback before sending it.\");\n }\n\n const { feedbackId } = await transport.create({\n context: submission.context,\n description: buildDescription(submission),\n title,\n });\n\n const screenshotSaved = await attachScreenshot(\n transport,\n feedbackId,\n submission\n ).catch(() => false);\n await attachElement(transport, feedbackId, submission).catch(() => undefined);\n\n return { feedbackId, screenshotSaved };\n}\n\nfunction isStorageResponse(value: unknown): value is { storageId: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof Reflect.get(value, \"storageId\") === \"string\"\n );\n}\n\nexport function createFeedbackTransport(client: Reflet): FeedbackTransport {\n return {\n create: (params) => client.create(params),\n getScreenshotUploadUrl: () => client.getScreenshotUploadUrl(),\n saveScreenshot: (params) => client.saveScreenshot(params),\n uploadImage: async (uploadUrl, image) => {\n const response = await fetch(uploadUrl, {\n body: image.blob,\n headers: { \"Content-Type\": image.mimeType },\n method: \"POST\",\n });\n\n if (!response.ok) {\n throw new Error(`Screenshot upload failed (${response.status})`);\n }\n\n const payload: unknown = await response.json();\n if (!isStorageResponse(payload)) {\n throw new Error(\"Screenshot upload returned no storage id\");\n }\n\n return payload.storageId;\n },\n };\n}\n","import { useEffect } from \"react\";\n\nconst RESIZE_DEBOUNCE = 400;\n\n/**\n * Calls `refresh` whenever the page the reporter is looking at changes shape:\n * SPA routes (which never fire popstate on push/replace — history methods must\n * be patched) and window resizes, debounced. Keeps the frozen screenshot and\n * page context describing what the reporter currently sees.\n */\nexport function useCaptureSync(enabled: boolean, refresh: () => void): void {\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const history = window.history;\n const originalPush = history.pushState;\n const originalReplace = history.replaceState;\n const hadOwnPush = Object.hasOwn(history, \"pushState\");\n const hadOwnReplace = Object.hasOwn(history, \"replaceState\");\n\n history.pushState = function pushState(data, unused, url) {\n const result = originalPush.call(history, data, unused, url);\n refresh();\n return result;\n };\n history.replaceState = function replaceState(data, unused, url) {\n const result = originalReplace.call(history, data, unused, url);\n refresh();\n return result;\n };\n window.addEventListener(\"popstate\", refresh);\n\n let resizeTimer: number | undefined;\n const onResize = () => {\n window.clearTimeout(resizeTimer);\n resizeTimer = window.setTimeout(refresh, RESIZE_DEBOUNCE);\n };\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n if (hadOwnPush) {\n history.pushState = originalPush;\n } else {\n Reflect.deleteProperty(history, \"pushState\");\n }\n if (hadOwnReplace) {\n history.replaceState = originalReplace;\n } else {\n Reflect.deleteProperty(history, \"replaceState\");\n }\n window.removeEventListener(\"popstate\", refresh);\n window.clearTimeout(resizeTimer);\n window.removeEventListener(\"resize\", onResize);\n };\n }, [enabled, refresh]);\n}\n","import {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Reflet } from \"../../client\";\nimport { RefletContext } from \"../../react-context\";\nimport type { ElementSelection, FeedbackContext } from \"../../types\";\nimport { renderAnnotatedImage } from \"../core/annotation-renderer\";\nimport { captureViewport, releaseCapture } from \"../core/capture\";\nimport {\n type ConsoleRecorder,\n startConsoleRecorder,\n} from \"../core/console-recorder\";\nimport { captureElementCloseUp, highlightFor } from \"../core/element-capture\";\nimport { buildElementSelection } from \"../core/element-selector\";\nimport { collectPageContext } from \"../core/page-context\";\nimport { createFeedbackTransport, submitWidgetFeedback } from \"../core/submit\";\nimport {\n type Annotation,\n type CapturedImage,\n type FeedbackWidgetCategory,\n type RefletFeedbackProps,\n SDK_VERSION,\n type WidgetStep,\n} from \"../types\";\nimport { useCaptureSync } from \"./use-capture-sync\";\n\nconst SUCCESS_CLOSE_DELAY = 2400;\nconst IS_APPLE = /Mac|iPhone|iPad/;\nconst MILLISECONDS_PER_DAY = 86_400_000;\nconst DISMISSAL_STORAGE_PREFIX = \"reflet-feedback-dismissed\";\n\nfunction readDismissedUntil(key: string): number {\n if (typeof window === \"undefined\") {\n return 0;\n }\n\n try {\n const value = Number.parseInt(window.localStorage.getItem(key) ?? \"\", 10);\n if (Number.isFinite(value) && value > Date.now()) {\n return value;\n }\n window.localStorage.removeItem(key);\n } catch {\n return 0;\n }\n\n return 0;\n}\n\nfunction writeDismissedUntil(key: string, until: number): void {\n try {\n window.localStorage.setItem(key, String(until));\n } catch {\n // storage blocked (private mode, quota) — dismissal just does not persist\n }\n}\n\n/**\n * Matches shortcuts written as `alt+f` or `mod+shift+k`, where `mod` is the\n * platform's command key.\n */\nexport function matchesHotkey(\n event: Pick<\n KeyboardEvent,\n \"altKey\" | \"ctrlKey\" | \"key\" | \"metaKey\" | \"shiftKey\"\n >,\n hotkey: string,\n platform = typeof navigator === \"undefined\" ? \"\" : navigator.platform\n): boolean {\n const parts = hotkey\n .toLowerCase()\n .split(\"+\")\n .map((part) => part.trim());\n const key = parts.at(-1);\n if (!key || event.key.toLowerCase() !== key) {\n return false;\n }\n\n const isApple = IS_APPLE.test(platform);\n const wantsMod = parts.includes(\"mod\");\n const expected = {\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n ctrl: parts.includes(\"ctrl\") || (wantsMod && !isApple),\n meta:\n parts.includes(\"meta\") || parts.includes(\"cmd\") || (wantsMod && isApple),\n shift: parts.includes(\"shift\"),\n };\n\n return (\n event.altKey === expected.alt &&\n event.ctrlKey === expected.ctrl &&\n event.metaKey === expected.meta &&\n event.shiftKey === expected.shift\n );\n}\n\n/**\n * A capture whose object URL is revoked the moment it is replaced or dropped —\n * holding one without this leaks the blob for the lifetime of the page.\n */\nfunction useOwnedCapture() {\n const [image, setImage] = useState<CapturedImage | null>(null);\n const ref = useRef<CapturedImage | null>(null);\n\n useEffect(() => {\n ref.current = image;\n }, [image]);\n useEffect(() => () => releaseCapture(ref.current), []);\n\n const replace = useCallback((next: CapturedImage | null) => {\n releaseCapture(ref.current);\n setImage(next);\n }, []);\n\n return [image, replace] as const;\n}\n\nexport function useWidgetState(props: RefletFeedbackProps) {\n const context = useContext(RefletContext);\n const publicKey = props.publicKey ?? context?.publicKey;\n const baseUrl = props.baseUrl ?? context?.baseUrl;\n const user = props.user ?? context?.user;\n const userToken = props.userToken ?? context?.userToken;\n const isAnonymous = !(user || userToken);\n const dismissForDays =\n props.dismissForDays !== undefined &&\n Number.isFinite(props.dismissForDays) &&\n props.dismissForDays > 0\n ? props.dismissForDays\n : null;\n const dismissalKey = `${DISMISSAL_STORAGE_PREFIX}:${publicKey ?? \"default\"}:${user?.id ?? \"anonymous\"}`;\n\n const [isOpen, setIsOpen] = useState(false);\n const [step, setStep] = useState<WidgetStep>(\"compose\");\n const [category, setCategory] = useState<FeedbackWidgetCategory>(\n props.defaultCategory ?? \"bug\"\n );\n const [message, setMessage] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [honeypot, setHoneypot] = useState(\"\");\n const [capture, replaceCapture] = useOwnedCapture();\n const [elementCapture, replaceElementCapture] = useOwnedCapture();\n const [annotations, setAnnotations] = useState<Annotation[]>([]);\n const [selection, setSelection] = useState<ElementSelection | null>(null);\n const [isCapturing, setIsCapturing] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [dismissedUntil, setDismissedUntil] = useState(() =>\n readDismissedUntil(dismissalKey)\n );\n\n const pickRef = useRef(0);\n const consoleRef = useRef<ConsoleRecorder | null>(null);\n const frozenContext = useRef<FeedbackContext | null>(null);\n\n useEffect(() => {\n setDismissedUntil(readDismissedUntil(dismissalKey));\n }, [dismissalKey]);\n\n useEffect(() => {\n if (props.captureConsole === false) {\n return;\n }\n const recorder = startConsoleRecorder();\n consoleRef.current = recorder;\n return () => {\n consoleRef.current = null;\n recorder.stop();\n };\n }, [props.captureConsole]);\n\n /** Frozen at the same instant as the screenshot, so shot and URL always match. */\n const takeCapture = useCallback((): void => {\n const context = collectPageContext({ sdkVersion: SDK_VERSION });\n setIsCapturing(true);\n captureViewport()\n .catch(() => null)\n .then((image) => {\n setIsCapturing(false);\n replaceCapture(image);\n frozenContext.current = image ? context : null;\n });\n }, [replaceCapture]);\n\n useCaptureSync(\n isOpen &&\n step === \"compose\" &&\n annotations.length === 0 &&\n !selection &&\n props.captureOnOpen !== false,\n takeCapture\n );\n\n const reset = useCallback(() => {\n pickRef.current++;\n frozenContext.current = null;\n replaceCapture(null);\n replaceElementCapture(null);\n setAnnotations([]);\n setSelection(null);\n setMessage(\"\");\n setEmail(\"\");\n setHoneypot(\"\");\n setError(null);\n setStep(\"compose\");\n setCategory(props.defaultCategory ?? \"bug\");\n }, [props.defaultCategory, replaceCapture, replaceElementCapture]);\n\n const close = useCallback(() => {\n setIsOpen(false);\n reset();\n props.onClose?.();\n }, [reset, props.onClose]);\n const dismiss = useCallback(() => {\n if (dismissForDays === null) {\n return;\n }\n\n const until = Date.now() + dismissForDays * MILLISECONDS_PER_DAY;\n writeDismissedUntil(dismissalKey, until);\n setIsOpen(false);\n reset();\n setDismissedUntil(until);\n props.onDismiss?.({ until });\n }, [dismissForDays, dismissalKey, props.onDismiss, reset]);\n\n const open = useCallback(() => {\n setIsOpen(true);\n setStep(\"compose\");\n props.onOpen?.();\n if (props.captureOnOpen !== false) {\n takeCapture();\n }\n }, [props.captureOnOpen, props.onOpen, takeCapture]);\n\n /** Fresh pixels so the highlight maps onto the scroll position the element had. */\n const selectElement = useCallback(\n async (element: Element) => {\n const picked = buildElementSelection(element);\n setSelection(picked);\n setStep(\"compose\");\n\n const pick = ++pickRef.current;\n const context = collectPageContext({ sdkVersion: SDK_VERSION });\n const [fresh, closeUp] = await Promise.all([\n captureViewport().catch(() => null),\n captureElementCloseUp(element).catch(() => null),\n ]);\n\n if (pickRef.current !== pick) {\n releaseCapture(fresh);\n releaseCapture(closeUp);\n return;\n }\n\n replaceCapture(fresh);\n replaceElementCapture(closeUp);\n frozenContext.current = fresh ? context : null;\n setAnnotations(fresh ? [highlightFor(picked, fresh)] : []);\n },\n [replaceCapture, replaceElementCapture]\n );\n\n const clearSelection = useCallback(() => {\n pickRef.current++;\n replaceElementCapture(null);\n setSelection(null);\n setAnnotations((previous) =>\n previous.filter((item) => !item.id.startsWith(\"selection-\"))\n );\n }, [replaceElementCapture]);\n\n const removeCapture = useCallback(() => {\n frozenContext.current = null;\n replaceCapture(null);\n setAnnotations([]);\n }, [replaceCapture]);\n\n const client = useMemo(\n () =>\n publicKey ? new Reflet({ baseUrl, publicKey, user, userToken }) : null,\n [baseUrl, publicKey, user, userToken]\n );\n\n const submit = useCallback(async () => {\n if (honeypot) {\n setStep(\"success\");\n return;\n }\n if (!client) {\n setError(\n \"Reflet is missing a publicKey. Pass one to RefletFeedback or RefletProvider.\"\n );\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n let annotated: CapturedImage | null = null;\n\n try {\n annotated = capture\n ? await renderAnnotatedImage(capture, annotations)\n : null;\n\n const result = await submitWidgetFeedback(\n createFeedbackTransport(client),\n {\n annotated,\n annotations,\n category,\n context: {\n ...(frozenContext.current ??\n collectPageContext({ sdkVersion: SDK_VERSION })),\n consoleEvents: consoleRef.current?.events(),\n metadata: props.metadata,\n selection: selection ?? undefined,\n },\n element: elementCapture,\n email,\n isAnonymous,\n message,\n screenshot: capture,\n }\n );\n\n setStep(\"success\");\n props.onSubmit?.({ feedbackId: result.feedbackId });\n setTimeout(close, SUCCESS_CLOSE_DELAY);\n } catch (submitError) {\n setError(\n submitError instanceof Error\n ? submitError.message\n : \"Something went wrong. Please try again.\"\n );\n } finally {\n releaseCapture(annotated);\n setIsSubmitting(false);\n }\n }, [\n annotations,\n capture,\n category,\n client,\n close,\n elementCapture,\n email,\n honeypot,\n isAnonymous,\n message,\n props.metadata,\n props.onSubmit,\n selection,\n ]);\n\n return {\n annotations,\n canDismiss: dismissForDays !== null,\n capture,\n category,\n clearSelection,\n close,\n dismiss,\n dismissForDays,\n elementCapture,\n email,\n error,\n honeypot,\n isAnonymous,\n isCapturing,\n isDismissed: dismissedUntil > Date.now(),\n isOpen,\n isSubmitting,\n message,\n open,\n removeCapture,\n selectElement,\n selection,\n setAnnotations,\n setCategory,\n setEmail,\n setHoneypot,\n setMessage,\n setStep,\n step,\n submit,\n takeCapture,\n };\n}\n\nexport type WidgetState = ReturnType<typeof useWidgetState>;\n","import { useEffect } from \"react\";\nimport {\n DEFAULT_WIDGET_LABELS,\n type FeedbackWidgetCategory,\n type RefletFeedbackProps,\n} from \"./types\";\nimport { Annotator } from \"./ui/annotator\";\nimport { Launcher } from \"./ui/launcher\";\nimport { FeedbackPanel } from \"./ui/panel\";\nimport { ElementPicker } from \"./ui/picker\";\nimport { ShadowPortal } from \"./ui/shadow-portal\";\nimport { matchesHotkey, useWidgetState } from \"./ui/use-widget-state\";\n\nconst DEFAULT_CATEGORIES: FeedbackWidgetCategory[] = [\n \"bug\",\n \"idea\",\n \"question\",\n];\nconst DEFAULT_OFFSET = 20;\n\n/**\n * Floating feedback button with a screenshot, annotation and element picker\n * flow. Mount it once, anywhere below `RefletProvider` or with its own\n * `publicKey`.\n */\nexport function RefletFeedback(props: RefletFeedbackProps) {\n const {\n categories = DEFAULT_CATEGORIES,\n enabled = true,\n hotkey = null,\n offset = DEFAULT_OFFSET,\n position = \"bottom-right\",\n theme = \"auto\",\n } = props;\n\n const labels = { ...DEFAULT_WIDGET_LABELS, ...props.labels };\n const state = useWidgetState(props);\n const { close, isOpen, open } = state;\n\n useEffect(() => {\n if (!(hotkey && enabled)) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (matchesHotkey(event, hotkey)) {\n event.preventDefault();\n if (isOpen) {\n close();\n } else {\n open();\n }\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [close, enabled, hotkey, isOpen, open]);\n\n useEffect(() => {\n if (!isOpen || state.step !== \"compose\") {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n close();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [close, isOpen, state.step]);\n\n if (!enabled || state.isDismissed) {\n return null;\n }\n\n const showPanel =\n isOpen && state.step !== \"picking\" && state.step !== \"annotate\";\n\n return (\n <ShadowPortal\n offset={offset}\n primaryColor={props.primaryColor}\n theme={theme}\n >\n <div className=\"root\" data-position={position}>\n {showPanel && (\n <FeedbackPanel\n categories={categories}\n labels={labels}\n state={state}\n />\n )}\n <Launcher\n isOpen={isOpen}\n label={labels.trigger}\n onClick={isOpen ? close : open}\n />\n </div>\n\n {isOpen && state.step === \"annotate\" && state.capture && (\n <Annotator\n annotations={state.annotations}\n capture={state.capture}\n labels={labels}\n onChange={state.setAnnotations}\n onDone={() => state.setStep(\"compose\")}\n />\n )}\n\n {isOpen && state.step === \"picking\" && (\n <ElementPicker\n hint={labels.pickElementHint}\n onCancel={() => state.setStep(\"compose\")}\n onPick={state.selectElement}\n />\n )}\n </ShadowPortal>\n );\n}\n"],"mappings":";;;;;;;;AAGA,MAAa,gBAAgB;AAE7B,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAmB1B,SAAgB,oBAAoB,SAIjB;CACjB,MAAM,QAAQ,QAAQ,oBAAoB;CAE1C,OAAO;EACL,OAAO;EACP,MAAM,QAAQ,UAAU,KAAA,IAAY;EACpC,KAAK,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,CAAC,GAAG,eAAe;EACtD,YAAY;EACZ,SAAS,CAAC,IAAI,cAAc,IAAI,GAAI,QAAQ,oBAAoB,CAAC,CAAE;EACnE,MAAM;EACN,WAAW;CACb;AACF;AAEA,SAAgB,UACd,MACA,UACkD;CAClD,IAAI,KAAK,SAAS,UAChB,OAAO;EAAE,QAAQ,KAAK;EAAQ,OAAO;EAAG,OAAO,KAAK;CAAM;CAG5D,MAAM,QAAQ,WAAW,KAAK;CAC9B,OAAO;EACL,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,KAAK,CAAC;EACnD;EACA,OAAO;CACT;AACF;AAEA,SAASA,SAAO,QAAiD;CAC/D,OAAO,IAAI,SAAS,YAAY;EAC9B,OAAO,OAAO,SAAS,WAAW;CACpC,CAAC;AACH;AAEA,SAAS,UACP,QACA,QACmB;CACnB,MAAM,UAAU,SAAS,cAAc,QAAQ;CAC/C,QAAQ,QAAQ,OAAO;CACvB,QAAQ,SAAS,OAAO;CAExB,MAAM,UAAU,QAAQ,WAAW,IAAI;CACvC,IAAI,CAAC,SACH,OAAO;CAGT,QAAQ,wBAAwB;CAChC,QAAQ,UAAU,QAAQ,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;CAC3D,OAAO;AACT;;AAGA,eAAsB,mBACpB,QACA,UAC+B;CAC/B,MAAM,SAAS,UACb;EAAE,QAAQ,OAAO;EAAQ,OAAO,OAAO;CAAM,GAC7C,QACF;CACA,MAAM,SAAS,OAAO,UAAU,IAAI,SAAS,UAAU,QAAQ,MAAM;CAErE,MAAM,OAAO,MAAMA,SAAO,MAAM;CAChC,IAAI,CAAC,MACH,OAAO;CAGT,OAAO;EACL;EACA,QAAQ,OAAO;EACf,UAAU;EACV,WAAW,IAAI,gBAAgB,IAAI;EACnC,OAAO,OAAO;CAChB;AACF;;;;;;;;;AAUA,eAAsB,gBACpB,UAA0B,CAAC,GACI;CAC/B,IAAI;EACF,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,SAAS,QAAQ,WAAW,SAAS;EAW3C,OAAO,MAAM,mBACX,MAVmB,QAAQ,SAC3B,QACA,oBAAoB;GAClB,kBAAkB,OAAO;GACzB,SAAS,QAAQ;GACjB,kBAAkB,QAAQ;EAC5B,CAAC,CACH,GAIE,QAAQ,YAAY,iBACtB;CACF,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,eAAe,OAA+C;CAC5E,IAAI,OACF,IAAI,gBAAgB,MAAM,SAAS;AAEvC;;;ACjJA,MAAM,qBAAqB,CAAC,iBAAiB,0BAA0B;AACvE,MAAM,YAAY,OAAO,IAAI,YAAY;AACzC,MAAM,mBAAmB,OAAO,IAAI,mBAAmB;AAEvD,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AACxB,MAAM,cAAc;AACpB,MAAM,cAAc;AAEpB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AACvB,MAAM,mBACJ;AACF,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;;AAGA,SAAgB,iBAAiB,MAAqB;CACpD,KAAK,MAAM,OAAO,OAAO,oBAAoB,IAAI,GAC/C,KAAK,MAAM,UAAU,oBACnB,IAAI,IAAI,WAAW,MAAM,GACvB,OAAO,QAAQ,IAAI,MAAM,GAAG,KAAK;CAIvC,OAAO;AACT;AAEA,SAAS,SAAS,OAA+B;CAC/C,IAAI,OAAO,UAAU,cAAc,CAAC,SAAS,KAAK,GAChD,OAAO;CAGT,MAAM,cAAc,QAAQ,IAAI,OAAO,aAAa;CACpD,IAAI,OAAO,gBAAgB,YAAY,aACrC,OAAO;CAGT,MAAM,OAAO,QAAQ,IAAI,OAAO,MAAM;CACtC,OAAO,OAAO,SAAS,YAAY,OAAO,OAAO;AACnD;;;;;AAMA,SAAS,iBAAiB,MAAuB;CAC/C,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,GACzC,OAAO;CAGT,OACE,KAAK,UAAU,mBACf,YAAY,KAAK,IAAI,KACrB,YAAY,KAAK,IAAI;AAEzB;AAEA,SAAS,cAAc,MAAe,QAAQ,GAAkB;CAC9D,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,QAAQ,GACvD,OAAO;CAGT,IAAI,SAAS,IAAI,GAAG;EAClB,MAAM,SAAS,QAAQ,IAAI,MAAM,UAAU;EAC3C,IAAI,WAAW,WACb,OAAO,cAAc,QAAQ,IAAI,MAAM,MAAM,GAAG,QAAQ,CAAC;EAE3D,IAAI,WAAW,kBACb,OAAO,cAAc,QAAQ,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC;CAE/D;CAEA,MAAM,OAAO,SAAS,IAAI;CAC1B,OAAO,QAAQ,iBAAiB,IAAI,IAAI,OAAO;AACjD;;AAGA,SAAgB,sBAAsB,OAA0B;CAC9D,MAAM,QAAkB,CAAC;CACzB,IAAI,UAAU;CACd,IAAI,QAAQ;CAEZ,OAAO,SAAS,OAAO,KAAK,QAAQ,gBAAgB;EAClD,MAAM,OACJ,cAAc,QAAQ,IAAI,SAAS,MAAM,CAAC,KAC1C,cAAc,QAAQ,IAAI,SAAS,aAAa,CAAC;EAEnD,IAAI,QAAQ,MAAM,GAAG,EAAE,MAAM,MAAM;GACjC,MAAM,KAAK,IAAI;GACf,IAAI,MAAM,UAAU,iBAClB;EAEJ;EAEA,UAAU,QAAQ,IAAI,SAAS,QAAQ;EACvC;CACF;CAEA,OAAO;AACT;AAEA,SAAS,kBAAkB,KAAqB;CAC9C,MAAM,OAAO,IACV,QAAQ,gBAAgB,EAAE,CAAC,CAC3B,QAAQ,eAAe,EAAE,CAAC,CAC1B,MAAM,GAAG,CAAC,CAAC;CACd,IAAI,CAAC,MACH,OAAO;CAGT,KAAK,MAAM,UAAU,qBAAqB;EACxC,IAAI,KAAK,WAAW,GAAG,OAAO,EAAE,GAC9B,OAAO;EAET,MAAM,QAAQ,KAAK,YAAY,IAAI,OAAO,EAAE;EAC5C,IAAI,UAAU,IACZ,OAAO,KAAK,MAAM,QAAQ,CAAC;CAE/B;CAEA,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG;AAC3D;AAEA,SAAS,eACP,UACA,MACA,QACQ;CACR,MAAM,OAAO,GAAG,kBAAkB,QAAQ,EAAE,GAAG;CAC/C,OAAO,WAAW,KAAA,IAAY,OAAO,GAAG,KAAK,GAAG;AAClD;AAEA,SAAS,gBAAgB,QAAqC;CAC5D,IAAI,CAAC,SAAS,MAAM,GAClB;CAGF,MAAM,WAAW,QAAQ,IAAI,QAAQ,UAAU;CAC/C,MAAM,aAAa,QAAQ,IAAI,QAAQ,YAAY;CACnD,IAAI,OAAO,aAAa,YAAY,OAAO,eAAe,UACxD;CAGF,MAAM,eAAe,QAAQ,IAAI,QAAQ,cAAc;CACvD,OAAO,eACL,UACA,YACA,OAAO,iBAAiB,WAAW,eAAe,KAAA,CACpD;AACF;AAEA,SAAS,eAAe,OAAoC;CAC1D,MAAM,MAAM,SAAS,KAAK,IAAI,QAAQ,IAAI,OAAO,OAAO,IAAI;CAC5D,IAAI,OAAO,QAAQ,UACjB;CAGF,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG;EAClC,MAAM,QAAQ,eAAe,KAAK,IAAI;EACtC,MAAM,OAAO,QAAQ;EACrB,IAAI,EAAE,SAAS,SAAS,iBAAiB,KAAK,IAAI,GAChD;EAGF,MAAM,OAAO,KAAK,QAAQ,eAAe,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;EAC9D,IAAI,CAAC,iBAAiB,KAAK,IAAI,GAC7B;EAGF,OAAO,eAAe,MAAM,OAAO,MAAM,EAAE,GAAG,OAAO,MAAM,EAAE,CAAC;CAChE;AACF;;;;;AAMA,SAAgB,sBAAsB,OAAoC;CACxE,IAAI,UAAU;CACd,IAAI,QAAQ;CAEZ,OAAO,SAAS,OAAO,KAAK,QAAQ,gBAAgB;EAClD,MAAM,UACJ,gBAAgB,QAAQ,IAAI,SAAS,cAAc,CAAC,KACpD,eAAe,QAAQ,IAAI,SAAS,aAAa,CAAC;EACpD,IAAI,SACF,OAAO;EAGT,UAAU,QAAQ,IAAI,SAAS,aAAa;EAC5C;CACF;AACF;AAEA,SAAgB,oBAAoB,SAGlC;CACA,MAAM,QAAQ,iBAAiB,OAAO;CACtC,OAAO;EACL,gBAAgB,sBAAsB,KAAK;EAC3C,gBAAgB,sBAAsB,KAAK;CAC7C;AACF;;;;;;;;ACpNA,MAAM,QAAQ;AACd,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAElB,MAAM,WAAW;AACjB,MAAM,WAAW;AAGjB,MAAM,uBAAuB;AAC7B,MAAMC,oBAAkB;AACxB,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AAEzB,MAAM,+BAAe,IAAI,IAAI;CAAC;CAAU;CAAS;CAAY;AAAU,CAAC;AACxE,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAS;CAAY;CAAU;AAAQ,CAAC;AACvE,MAAM,iCAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAASC,WAAS,OAAe,KAAqB;CACpD,OAAO,MAAM,UAAU,MAAM,QAAQ,GAAG,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI;AACpE;;AAGA,SAAgB,YAAY,OAAuB;CACjD,OAAO,MAAM,QAAQ,OAAO,QAAQ,CAAC,CAAC,QAAQ,YAAY,QAAQ;AACpE;AAEA,MAAM,kBACJ;AACF,MAAM,wBAAwB;AAE9B,SAAS,QAAQ,OAAuB;CACtC,IAAI;EACF,OAAO,mBAAmB,KAAK;CACjC,QAAQ;EACN,OAAO;CACT;AACF;;;;;;AAOA,SAAgB,UAAU,MAAsB;CAC9C,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI;CACpB,QAAQ;EACN,OAAO,YAAY,IAAI;CACzB;CAEA,MAAM,QAAQ,IAAI,OACf,QAAQ,uBAAuB,EAAE,CAAC,CAClC,MAAM,GAAG,CAAC,CACV,OAAO,OAAO;CACjB,IACE,CAAC,MAAM,MAAM,SACX,gBAAgB,KAAK,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CACxD,GAEA,OAAO;CAcT,MAAM,QAXO,MAAM,KAAK,SAAS;EAC/B,MAAM,SAAS,KAAK,QAAQ,GAAG;EAC/B,IACE,WAAW,MACX,CAAC,gBAAgB,KAAK,QAAQ,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC,GAEpD,OAAO;EAET,OAAO,GAAG,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG;CACrC,CAEiB,CAAC,CAAC,KAAK,GAAG;CAC3B,OAAO,GAAG,IAAI,SAAS,IAAI,WAAW,QAAQ,IAAI,UAAU,KAAK,IAAI;AACvE;AAEA,SAAS,YAAY,OAAuB;CAC1C,IAAI,WAAW,KAAK,KAAK,GACvB,OAAO,GAAG,MAAM,MAAM,GAAG,MAAM,QAAQ,GAAG,CAAC,EAAE,GAAG;CAElD,OAAO,MAAM,MAAM,SAAS,CAAC,CAAC,MAAM;AACtC;AAEA,SAAS,mBAAmB,SAAwB;CAClD,MAAM,kBAAkB,cAAc,IAAI,QAAQ,SAAS;CAE3D,KAAK,MAAM,EAAE,MAAM,WAAW,MAAM,KAAK,QAAQ,UAAU,GAAG;EAC5D,IAAI,mBAAmB,SAAS,SAAS;GACvC,QAAQ,gBAAgB,IAAI;GAC5B;EACF;EAEA,MAAM,UAAU,eAAe,IAAI,IAAI,IACnC,YAAY,KAAK,IACjB,YAAY,KAAK;EACrB,QAAQ,aAAa,MAAMA,WAAS,SAAS,oBAAoB,CAAC;CACpE;AACF;AAEA,SAAS,SAAS,SAAwB;CACxC,QAAQ,gBAAgB,QAAQ,cAAc,eAAe,QAAQ,CAAC;AACxE;AAEA,SAAS,aAAa,SAAkB,OAAqB;CAC3D,mBAAmB,OAAO;CAE1B,IAAI,QAAQ,aAAA,oBAA6B,GAAG;EAC1C,QAAQ,gBAAgB,QAAQ,cAAc,eAAe,QAAQ,CAAC;EACtE;CACF;CAEA,IAAI,QAAQ,cAAc,OAAO;EAC/B,QAAQ,gBAAgB;EACxB;CACF;CAEA,KAAK,MAAM,SAAS,MAAM,KAAK,QAAQ,UAAU,GAAG;EAClD,IAAI,MAAM,aAAa,KAAK,cAAc;GACxC,MAAM,OAAO;GACb;EACF;EAEA,IAAI,MAAM,aAAa,KAAK,WAAW;GACrC,MAAM,cAAcA,WAClB,YAAY,MAAM,eAAe,EAAE,GACnCD,iBACF;GACA;EACF;EAEA,IAAI,EAAE,iBAAiB,UACrB;EAGF,IAAI,aAAa,IAAI,MAAM,SAAS,GAAG;GACrC,MAAM,OAAO;GACb;EACF;EAEA,IAAI,SAAS,iBAAiB;GAC5B,mBAAmB,KAAK;GACxB,SAAS,KAAK;GACd;EACF;EAEA,aAAa,OAAO,QAAQ,CAAC;CAC/B;AACF;;AAGA,SAAgB,eAAe,SAAkB,WAA2B;CAC1E,MAAM,gBACJ,QAAQ,iBAAiB,GAAG,CAAC,CAAC,UAAU;CAC1C,MAAM,QAAQ,QAAQ,UAAU,aAAa;CAC7C,IAAI,EAAE,iBAAiB,UACrB,OAAO;CAGT,aAAa,OAAO,CAAC;CACrB,IAAI,CAAC,eACH,SAAS,KAAK;CAGhB,OAAOC,WAAS,MAAM,UAAU,QAAQ,gBAAgB,GAAG,GAAG,SAAS;AACzE;;;ACjLA,MAAM,UAAU;AAChB,MAAM,aAAa;AACnB,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAC1B,MAAM,0BAA0B;AAChC,MAAM,YAAY;AAClB,MAAM,oBAAoB;AAG1B,MAAM,sBAAsB;AAC5B,MAAM,6BAA6B;AAEnC,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,oBAAoB,CAAC,QAAQ,YAAY;AAE/C,MAAM,oBACJ;AACF,MAAM,mBAAmB;;AAGzB,MAAM,6BAAa,IAAI,IAAI;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,YAAY,SAA0B;CAC7C,MAAM,QAAQ,QAAQ,UAAU,IAAI;CACpC,IAAI,EAAE,iBAAiB,UACrB,OAAO;CAGT,KAAK,MAAM,QAAQ,MAAM,iBAAiB,GAAG,GAC3C,IAAI,WAAW,IAAI,KAAK,SAAS,GAC/B,KAAK,OAAO,MAAM,cAAc,eAAe,GAAG,CAAC;CAIvD,OAAO,aAAa,YAAY,MAAM,eAAe,EAAE,CAAC;AAC1D;AAEA,SAAS,SAAS,UAA2B;CAC3C,IAAI;EACF,OAAO,SAAS,iBAAiB,QAAQ,CAAC,CAAC,WAAW;CACxD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,qBAAqB,OAAuB;CACnD,OAAO,MAAM,QAAQ,UAAU,MAAM;AACvC;AAEA,SAAS,gBACP,SACA,WACA,WACe;CACf,MAAM,QAAQ,QAAQ,aAAa,SAAS;CAC5C,IAAI,CAAC,SAAS,MAAM,SAAS,yBAC3B,OAAO;CAGT,MAAM,WAAW,GAAG,UAAU,GAAG,UAAU,IAAI,qBAAqB,KAAK,EAAE;CAC3E,OAAO,SAAS,QAAQ,IAAI,WAAW;AACzC;;AAGA,SAAS,aAAa,SAAiC;CACrD,MAAM,KAAK,QAAQ,aAAa,IAAI;CACpC,IAAI,MAAM,QAAQ,KAAK,EAAE,KAAK,SAAS,IAAI,IAAI,GAC7C,OAAO,IAAI;CAGb,KAAK,MAAM,aAAa,iBAAiB;EACvC,MAAM,SAAS,gBAAgB,SAAS,WAAW,EAAE;EACrD,IAAI,QACF,OAAO;CAEX;CAEA,KAAK,MAAM,aAAa,mBAAmB;EACzC,MAAM,SAAS,gBAAgB,SAAS,WAAW,QAAQ,SAAS;EACpE,IAAI,QACF,OAAO;CAEX;CAEA,OAAO;AACT;AAEA,SAAS,kBAAkB,SAA0B;CACnD,MAAM,MAAM,QAAQ;CACpB,MAAM,SAAS,QAAQ;CACvB,IAAI,CAAC,QACH,OAAO;CAGT,MAAM,UAAU,MAAM,KAAK,OAAO,QAAQ,CAAC,CAAC,QACzC,UAAU,MAAM,cAAc,GACjC;CACA,IAAI,QAAQ,UAAU,GACpB,OAAO;CAGT,OAAO,GAAG,IAAI,eAAe,QAAQ,QAAQ,OAAO,IAAI,EAAE;AAC5D;;;;;;;AAQA,SAAgB,cAAc,SAA0B;CACtD,IAAI,YAAY,SAAS,iBACvB,OAAO;CAET,IAAI,YAAY,SAAS,MACvB,OAAO;CAGT,MAAM,SAAS,aAAa,OAAO;CACnC,IAAI,QACF,OAAO;CAGT,MAAM,WAAqB,CAAC;CAC5B,IAAI,UAA0B;CAE9B,KAAK,IAAI,QAAQ,GAAG,WAAW,QAAQ,WAAW,SAAS;EACzD,MAAM,iBAAiB,YAAY,UAAU,OAAO,aAAa,OAAO;EACxE,SAAS,QAAQ,kBAAkB,kBAAkB,OAAO,CAAC;EAE7D,MAAM,YAAY,SAAS,KAAK,KAAK;EACrC,MAAM,aAAa,SAAS,UAAU;EACtC,IACE,kBACA,YAAY,SAAS,QACpB,cAAc,SAAS,SAAS,GAEjC,OAAO;EAGT,UAAU,QAAQ;CACpB;CAEA,OAAO,SAAS,KAAK,KAAK;AAC5B;AAEA,SAAS,SAAS,OAAe,KAAqB;CACpD,OAAO,MAAM,UAAU,MAAM,QAAQ,GAAG,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE;AAClE;AAEA,SAAS,aAAa,OAAuB;CAC3C,OAAO,MAAM,QAAQ,YAAY,GAAG,CAAC,CAAC,KAAK;AAC7C;AAEA,SAAS,gBAAgB,SAA0B;CACjD,MAAM,WACJ,QAAQ,aAAa,YAAY,KACjC,QAAQ,aAAa,OAAO,KAC5B,QAAQ,aAAa,KAAK,KAC1B,QAAQ,aAAa,aAAa;CACpC,IAAI,UAAU,KAAK,GACjB,OAAO,SAAS,KAAK;CAGvB,OAAO,aAAa,QAAQ,eAAe,EAAE;AAC/C;;AAGA,SAAgB,gBAAgB,SAA0B;CACxD,MAAM,MAAM,QAAQ;CACpB,MAAM,QAAQ,YAAY,gBAAgB,OAAO,CAAC;CAClD,IAAI,OACF,OAAO,SAAS,GAAG,IAAI,IAAI,MAAM,IAAI,gBAAgB;CAGvD,MAAM,aAAa,QAAQ,UAAU,KAAK,CAAC;CAC3C,OAAO,SAAS,aAAa,GAAG,IAAI,GAAG,eAAe,KAAK,gBAAgB;AAC7E;AAEA,SAAS,iBAAiB,SAAiC;CACzD,MAAM,WAAW,QAAQ,eAAe,QAAQ,iBAAiB;CACjE,IAAI,CAAC,UACH,OAAO;CAGT,MAAM,OACJ,SAAS,aAAa,YAAY,KAAK,SAAS,aAAa,OAAO;CACtE,OAAO,MAAM,KAAK,IACd,GAAG,SAAS,UAAU,IAAI,aAAa,IAAI,EAAE,KAC7C,SAAS;AACf;AAEA,SAAS,aAAa,SAAiC;CACrD,MAAM,QAAQ,QAAQ,QAAQ,iBAAiB,KAAK,SAAS;CAC7D,MAAM,QAAQ,SAAS,YAAY;CACnC,MAAM,mBAAmB,OAAO;CAChC,MAAM,SAAS,IAAI;CAEnB,IAAI,UAA0B;CAC9B,KAAK,MAAM,WAAW,MAAM,iBAAiB,gBAAgB,GAC3D,IAAI,MAAM,aAAa,SAAS,CAAC,IAAI,GACnC,UAAU;CAKd,OADa,aAAa,SAAS,eAAe,EACxC,KAAK;AACjB;;;;;AAMA,SAAgB,eAAe,SAAsC;CACnE,MAAM,WAAW,iBAAiB,OAAO;CACzC,MAAM,UAAU,aAAa,OAAO;CACpC,MAAM,QAAQ,CAAC,QAAQ;CAEvB,IAAI,WAAW,CAAC,UAAU,SAAS,IAAI,QAAQ,EAAE,GAC/C,MAAM,KAAK,OAAO;CAGpB,MAAM,SAAS,MAAM,QAAQ,SAAS,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK;CAC/D,OAAO,SAAS,SAAS,YAAY,MAAM,GAAG,iBAAiB,IAAI,KAAA;AACrE;AAEA,SAAgB,eAAe,SAA+B;CAC5D,MAAM,OAAO,QAAQ,sBAAsB;CAC3C,OAAO;EACL,QAAQ,KAAK,MAAM,KAAK,MAAM;EAC9B,OAAO,KAAK,MAAM,KAAK,KAAK;EAC5B,GAAG,KAAK,MAAM,KAAK,CAAC;EACpB,GAAG,KAAK,MAAM,KAAK,CAAC;CACtB;AACF;;AAGA,SAAgB,sBAAsB,SAAoC;CACxE,MAAM,EAAE,gBAAgB,mBAAmB,oBAAoB,OAAO;CACtE,MAAM,OAAO,SAAS,YAAY,OAAO,GAAG,eAAe;CAE3D,OAAO;EACL;EACA,MAAM,eAAe,SAAS,eAAe;EAC7C,OAAO,gBAAgB,OAAO;EAC9B,MAAM,eAAe,OAAO;EAC5B,QAAQ,eAAe,OAAO;EAC9B,UAAU,SAAS,cAAc,OAAO,GAAG,mBAAmB;EAC9D,gBAAgB,iBACZ,SAAS,gBAAgB,0BAA0B,IACnD;EACJ,MAAM,QAAQ,KAAA;CAChB;AACF;;;ACpSA,MAAM,mBAAuC;CAC3C,CAAC,QAAQ,2BAA2B;CACpC,CAAC,SAAS,eAAe;CACzB,CAAC,oBAAoB,0BAA0B;CAC/C,CAAC,WAAW,6BAA6B;CACzC,CAAC,UAAU,4BAA4B;CACvC,CAAC,UAAU,2BAA2B;AACxC;AAEA,MAAM,cAAkC;CACtC,CAAC,OAAO,kBAAkB;CAC1B,CAAC,WAAW,SAAS;CACrB,CAAC,WAAW,YAAY;CACxB,CAAC,SAAS,oBAAoB;CAC9B,CAAC,YAAY,MAAM;CACnB,CAAC,SAAS,WAAW;AACvB;AAEA,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAEhB,SAAS,eAAe,SAAyB;CAC/C,OAAO,QAAQ,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,QAAQ,eAAe,EAAE;AAC3E;AAEA,SAAS,aAAa,WAAwC;CAC5D,IAAI,YAAY,KAAK,SAAS,GAC5B,OAAO;CAET,IAAI,YAAY,KAAK,SAAS,GAC5B,OAAO;CAET,OAAO,QAAQ,KAAK,SAAS,IAAI,WAAW;AAC9C;AAEA,SAAgB,eAAe,WAA8B;CAC3D,MAAM,OAAkB,EAAE,QAAQ,aAAa,SAAS,EAAE;CAE1D,KAAK,MAAM,CAAC,MAAM,YAAY,kBAAkB;EAC9C,MAAM,UAAU,QAAQ,KAAK,SAAS,CAAC,GAAG;EAC1C,IAAI,SAAS;GACX,KAAK,UAAU,GAAG,KAAK,GAAG,eAAe,OAAO;GAChD;EACF;CACF;CAEA,KAAK,MAAM,CAAC,MAAM,YAAY,aAC5B,IAAI,QAAQ,KAAK,SAAS,GAAG;EAC3B,KAAK,KAAK;EACV;CACF;CAGF,OAAO;AACT;AAIA,MAAM,wBAAwB;AAC9B,MAAM,iBAAiB;AACvB,MAAM,wBAAwB;AAE9B,SAAS,KAAK,OAAe,KAAqB;CAChD,OAAO,MAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,GAAG,GAAG;AACzD;AAEA,SAAS,aACP,OACA,KACoB;CACpB,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO,GAAG,IAAI,KAAA;AAC5C;AAEA,SAAS,kBAAsC;CAC7C,IAAI;EACF,OAAO,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC;CACjD,QAAQ,CAER;AACF;;AAGA,SAAgB,mBAAmB,SAEf;CAClB,MAAM,YAAY,UAAU;CAC5B,MAAM,QAAQ,eAAe,SAAS;CAEtC,OAAO;EACL,SAAS,MAAM;EACf,QAAQ,MAAM;EACd,UAAU,UAAU;EACpB,IAAI,MAAM;EACV,WAAW,aAAa,SAAS,OAAO,qBAAqB;EAC7D,UAAU,aAAa,SAAS,UAAU,cAAc;EACxD,QAAQ;GAAE,QAAQ,OAAO,OAAO;GAAQ,OAAO,OAAO,OAAO;EAAM;EACnE,QAAQ;GAAE,GAAG,OAAO;GAAS,GAAG,OAAO;EAAQ;EAC/C,YAAY,SAAS;EACrB,UAAU,gBAAgB;EAC1B,KAAK,UAAU,OAAO,SAAS,IAAI;EACnC,WAAW,KAAK,WAAW,qBAAqB;EAChD,UAAU;GACR,kBAAkB,OAAO;GACzB,QAAQ,OAAO;GACf,OAAO,OAAO;EAChB;CACF;AACF;;;;ACnHA,MAAa,cAAc;AAuE3B,MAAa,wBAA8C;CACzD,cAAc;CACd,kBAAkB;CAClB,MAAM;CACN,QAAQ;CACR,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,kBAAkB;CAClB,wBAAwB;CACxB,gBAAgB;CAChB,MAAM;CACN,YAAY;CACZ,kBAAkB;CAClB,cAAc;CACd,oBAAoB;CACpB,aAAa;CACb,iBAAiB;CACjB,WAAW;CACX,kBAAkB;CAClB,YAAY;CACZ,QAAQ;CACR,gBAAgB;CAChB,cAAc;CACd,OAAO;CACP,kBAAkB;CAClB,SAAS;CACT,MAAM;AACR;;;ACnGA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,YAA8B;CAAC;CAAa;CAAa;AAAM;AACrE,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB,KAAK,KAAK;AACnC,MAAM,yBAAyB;AAE/B,SAAgB,cAAc,OAAc,KAAyB;CACnE,OAAO;EACL,QAAQ,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC;EAChC,OAAO,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC;EAC/B,GAAG,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;EAC1B,GAAG,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;CAC5B;AACF;;AAGA,SAAgB,UACd,OACA,KACA,MACgB;CAChB,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,IAAI,MAAM,CAAC;CACzD,IAAI,KAAK,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,GACnD,OAAO,CAAC,KAAK,GAAG;CAGlB,MAAM,QAAQ,YAA2B;EACvC,GAAG,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,MAAM;EACzC,GAAG,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,MAAM;CAC3C;CAEA,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,KAAK,gBAAgB,CAAC;AACzD;;AAGA,SAAgB,aACd,QACA,YAAY,wBACH;CACT,IAAI,OAAO,SAAS,GAClB,OAAO;CAGT,MAAM,CAAC,OAAO,GAAG,QAAQ;CACzB,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,OAAgB,CAAC,KAAK;CAC5B,IAAI,SAAS;CAEb,KAAK,MAAM,SAAS,KAAK,MAAM,GAAG,EAAE,GAClC,IAAI,KAAK,MAAM,MAAM,IAAI,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,KAAK,WAAW;EACnE,KAAK,KAAK,KAAK;EACf,SAAS;CACX;CAGF,MAAM,OAAO,OAAO,GAAG,EAAE;CACzB,IAAI,MACF,KAAK,KAAK,IAAI;CAGhB,OAAO;AACT;AAEA,SAAgB,aAAa,YAAiC;CAC5D,IAAI,WAAW,SAAS,OACtB,QAAQ,WAAW,QAAQ,UAAU,KAAK;CAG5C,MAAM,EAAE,OAAO,QAAQ;CACvB,OAAO,KAAK,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI;AACxD;AAEA,SAAS,OAAO,YAA8C;CAC5D,MAAM,EAAE,OAAO,OAAO,KAAK,SAAS;CAEpC,IAAI,SAAS,OACX,OAAO;EACL;EACA,QAAQ,aAAa,WAAW,UAAU,CAAC,CAAC;EAC5C,MAAM;EACN,GAAG,MAAM;EACT,GAAG,MAAM;CACX;CAGF,IAAI,UAAU,SAAS,IAAI,GAAG;EAC5B,MAAM,OAAO,cAAc,OAAO,GAAG;EACrC,OAAO;GACL;GACA,QAAQ,KAAK;GACb,MAAM;GACN,OAAO,KAAK;GACZ,GAAG,KAAK;GACR,GAAG,KAAK;EACV;CACF;CAEA,OAAO;EACL;EACA,MAAM,IAAI;EACV,MAAM,IAAI;EACV,MAAM;EACN,GAAG,MAAM;EACT,GAAG,MAAM;CACX;AACF;;AAGA,SAAgB,kBACd,aACwB;CACxB,OAAO,YAAY,QAAQ,SAAS,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM;AACrE;;;ACzHA,MAAM,eAAe;AACrB,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;AACvB,MAAM,cAAc;AAiCpB,SAAS,WAAW,OAAc,OAAsB;CACtD,OAAO;EAAE,GAAG,MAAM,IAAI;EAAO,GAAG,MAAM,IAAI;CAAM;AAClD;AAEA,SAAS,UAAU,MAAmB,OAA4B;CAChE,OAAO;EACL,QAAQ,KAAK,SAAS;EACtB,OAAO,KAAK,QAAQ;EACpB,GAAG,KAAK,IAAI;EACZ,GAAG,KAAK,IAAI;CACd;AACF;AAEA,SAAS,gBAAgB,OAA4C;CACnE,OACE,OAAO,sBAAsB,eAC7B,iBAAiB;AAErB;;;;;AAMA,SAAS,OAAO,SAAkC,MAAyB;CACzE,MAAM,SAAS,QAAQ;CACvB,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,QAAQ,WAAW,CAAC;CAC9D,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,WAAW,CAAC;CAEhE,IAAI,gBAAgB,MAAM,GAAG;EAC3B,MAAM,YAAY,SAAS,cAAc,QAAQ;EACjD,UAAU,QAAQ;EAClB,UAAU,SAAS;EACnB,MAAM,mBAAmB,UAAU,WAAW,IAAI;EAElD,IAAI,kBAAkB;GACpB,iBAAiB,wBAAwB;GACzC,iBAAiB,UACf,QACA,KAAK,GACL,KAAK,GACL,KAAK,OACL,KAAK,QACL,GACA,GACA,OACA,MACF;GACA,QAAQ,UAAU,WAAW,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;GACpE;EACF;CACF;CAEA,QAAQ,YAAY;CACpB,QAAQ,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;AAC1D;AAEA,SAAS,UACP,SACA,OACA,KACA,OACM;CACN,QAAQ,UAAU;CAClB,QAAQ,OAAO,MAAM,GAAG,MAAM,CAAC;CAC/B,QAAQ,OAAO,IAAI,GAAG,IAAI,CAAC;CAC3B,QAAQ,OAAO;CAEf,MAAM,CAAC,MAAM,SAAS,UAAU,OAAO,KAAK,kBAAkB,KAAK;CACnE,QAAQ,UAAU;CAClB,QAAQ,OAAO,IAAI,GAAG,IAAI,CAAC;CAC3B,QAAQ,OAAO,KAAK,GAAG,KAAK,CAAC;CAC7B,QAAQ,OAAO,MAAM,GAAG,MAAM,CAAC;CAC/B,QAAQ,UAAU;CAClB,QAAQ,KAAK;AACf;AAEA,SAAS,QACP,SACA,QACA,OACM;CACN,MAAM,CAAC,OAAO,GAAG,QAAQ;CACzB,IAAI,CAAC,OACH;CAGF,MAAM,OAAO,WAAW,OAAO,KAAK;CACpC,QAAQ,UAAU;CAClB,QAAQ,OAAO,KAAK,GAAG,KAAK,CAAC;CAC7B,KAAK,MAAM,SAAS,MAAM;EACxB,MAAM,SAAS,WAAW,OAAO,KAAK;EACtC,QAAQ,OAAO,OAAO,GAAG,OAAO,CAAC;CACnC;CACA,QAAQ,OAAO;AACjB;AAEA,SAAS,eACP,SACA,YACA,OACM;CACN,MAAM,EAAE,OAAO,SAAS;CACxB,MAAM,OAAO,UACX,cAAc,WAAW,OAAO,WAAW,GAAG,GAC9C,KACF;CAEA,QAAQ,KAAK;CACb,QAAQ,YAAY,eAAe;CACnC,QAAQ,UAAU;CAClB,QAAQ,WAAW;CACnB,QAAQ,cAAc;CACtB,QAAQ,YAAY;CAEpB,QAAQ,MAAR;EACE,KAAK;GACH,QAAQ,SAAS,WAAW,UAAU,CAAC,GAAG,KAAK;GAC/C;EACF,KAAK;GACH,UACE,SACA,WAAW,WAAW,OAAO,KAAK,GAClC,WAAW,WAAW,KAAK,KAAK,GAChC,KACF;GACA;EACF,KAAK;GACH,QAAQ,WAAW,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;GAC1D;EACF,KAAK;GACH,QAAQ,cAAc;GACtB,QAAQ,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;GACxD;EACF,SACE,OAAO,SAAS,IAAI;CAExB;CAEA,QAAQ,QAAQ;AAClB;AAEA,SAAgB,gBACd,SACA,aACA,SACM;CACN,MAAM,QAAQ,SAAS,SAAS;CAChC,KAAK,MAAM,cAAc,aACvB,IAAI,CAAC,aAAa,UAAU,GAC1B,eAAe,SAAS,YAAY,KAAK;AAG/C;AAEA,SAAS,UAAU,KAAwC;CACzD,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,IAAI,MAAM;EACxB,MAAM,eAAe,QAAQ,KAAK;EAClC,MAAM,gBAAgB,uBAAO,IAAI,MAAM,iCAAiC,CAAC;EACzE,MAAM,MAAM;CACd,CAAC;AACH;AAEA,SAAS,OAAO,QAAiD;CAC/D,OAAO,IAAI,SAAS,YAAY;EAC9B,OAAO,OAAO,SAAS,WAAW;CACpC,CAAC;AACH;;;;;AAMA,eAAsB,qBACpB,QACA,aAC+B;CAC/B,IAAI,YAAY,WAAW,GACzB,OAAO;CAGT,MAAM,SAAS,SAAS,cAAc,QAAQ;CAC9C,OAAO,QAAQ,OAAO;CACtB,OAAO,SAAS,OAAO;CACvB,MAAM,UAAU,OAAO,WAAW,IAAI;CACtC,IAAI,CAAC,SACH,OAAO;CAGT,MAAM,QAAQ,MAAM,UAAU,OAAO,SAAS;CAC9C,QAAQ,UAAU,OAAO,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;CAC1D,gBAAgB,SAAS,WAAW;CAEpC,MAAM,OAAO,MAAM,OAAO,MAAM;CAChC,IAAI,CAAC,MACH,OAAO;CAGT,OAAO;EACL;EACA,QAAQ,OAAO;EACf,UAAU;EACV,WAAW,IAAI,gBAAgB,IAAI;EACnC,OAAO,OAAO;CAChB;AACF;;;ACrPA,SAAS,IAAI,EACX,UACA,WACA,OAAO,MAKN;CACD,OACE,oBAAC,OAAD;EACE,eAAY;EACD;EACX,MAAK;EACL,QAAQ;EACR,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EACR,OAAO;EAEN;CACE,CAAA;AAET;AAEA,SAAgB,SAAS,EAAE,aAAqC;CAC9D,OACE,oBAAC,KAAD;EAAgB;EAAW,MAAM;EAC/B,UAAA,oBAAC,QAAD,EAAM,GAAE,gEAAiE,CAAA;CACtE,CAAA;AAET;AAEA,SAAgB,UAAU,EAAE,aAAqC;CAC/D,OACE,oBAAC,KAAD;EAAgB;EACd,UAAA,oBAAC,QAAD,EAAM,GAAE,uBAAwB,CAAA;CAC7B,CAAA;AAET;AAEA,SAAgB,UAAU;CACxB,OACE,oBAAC,KAAD;EAAK,MAAM;EACT,UAAA,oBAAC,QAAD,EAAM,GAAE,sHAAuH,CAAA;CAC5H,CAAA;AAET;AAEA,SAAgB,WAAW;CACzB,OACE,oBAAC,KAAD;EAAK,MAAM;EACT,UAAA,oBAAC,QAAD,EAAM,GAAE,yGAA0G,CAAA;CAC/G,CAAA;AAET;AAEA,SAAgB,eAAe;CAC7B,OACE,qBAAC,KAAD;EAAK,MAAM;EAAX,UAAA,CACE,oBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;EAAK,CAAA,GAC/B,oBAAC,QAAD,EAAM,GAAE,gEAAiE,CAAA,CACtE;;AAET;AAEA,SAAgB,aAAa;CAC3B,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD,EAAM,GAAE,4HAA6H,CAAA,GACrI,oBAAC,UAAD;EAAQ,IAAG;EAAK,IAAG;EAAK,GAAE;CAAO,CAAA,CAC9B,EAAA,CAAA;AAET;AAEA,SAAgB,aAAa;CAC3B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,6CAA8C,CAAA,EACnD,CAAA;AAET;AAEA,SAAgB,aAAa;CAC3B,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD,EAAM,GAAE,iCAAkC,CAAA,GAC1C,oBAAC,UAAD;EAAQ,IAAG;EAAK,IAAG;EAAK,GAAE;CAAK,CAAA,CAC5B,EAAA,CAAA;AAET;AAEA,SAAgB,YAAY;CAC1B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,qDAAsD,CAAA,EAC3D,CAAA;AAET;AAEA,SAAgB,YAAY;CAC1B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,sBAAuB,CAAA,EAC5B,CAAA;AAET;AAEA,SAAgB,aAAa;CAC3B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD;EAAM,QAAO;EAAK,IAAG;EAAM,OAAM;EAAK,GAAE;EAAI,GAAE;CAAO,CAAA,EAClD,CAAA;AAET;AAEA,SAAgB,gBAAgB;CAC9B,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,uBAAwB,CAAA,EAC7B,CAAA;AAET;AAEA,SAAgB,WAAW;CACzB,OACE,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,QAAD,EAAM,GAAE,wEAAyE,CAAA,GACjF,oBAAC,QAAD,EAAM,GAAE,gCAAiC,CAAA,CACtC,EAAA,CAAA;AAET;AAEA,SAAgB,WAAW;CACzB,OACE,oBAAC,KAAD,EAAA,UACE,oBAAC,QAAD,EAAM,GAAE,4CAA6C,CAAA,EAClD,CAAA;AAET;AAEA,SAAgB,UAAU,EAAE,OAAO,MAAyB;CAC1D,OACE,oBAAC,OAAD;EACE,eAAY;EACZ,MAAK;EACL,QAAQ;EACR,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EACR,OAAO;EAEP,UAAA,oBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;CACvB,CAAA;AAET;;;ACvIA,MAAM,QAID;CACH;EAAE,MAAM;EAAY,IAAI;EAAO,OAAO;CAAO;CAC7C;EAAE,MAAM;EAAW,IAAI;EAAS,OAAO;CAAQ;CAC/C;EAAE,MAAM;EAAY,IAAI;EAAa,OAAO;CAAM;CAClD;EAAE,MAAM;EAAe,IAAI;EAAa,OAAO;CAAY;CAC3D;EAAE,MAAM;EAAU,IAAI;EAAQ,OAAO;CAAO;AAC9C;AAEA,SAAS,aACP,QACA,SACA,SACO;CACP,MAAM,SAAS,OAAO,sBAAsB;CAC5C,OAAO;EACL,IAAK,UAAU,OAAO,QAAQ,OAAO,QAAS,OAAO;EACrD,IAAK,UAAU,OAAO,OAAO,OAAO,SAAU,OAAO;CACvD;AACF;AAEA,SAAgB,UAAU,EACxB,aACA,SACA,QACA,UACA,UAOC;CACD,MAAM,YAAY,OAA0B,IAAI;CAChD,MAAM,SAAS,OAAO,CAAC;CACvB,MAAM,CAAC,MAAM,WAAW,SAAyB,KAAK;CACtD,MAAM,CAAC,OAAO,YAAY,SAAiB,kBAAkB,EAAE;CAC/D,MAAM,CAAC,OAAO,YAAY,SAA4B,IAAI;CAE1D,MAAM,CAAC,MAAM,WAAW,SAAkC,IAAI;CAE9D,gBAAgB;EACd,IAAI,SAAS;EACb,MAAM,QAAQ,IAAI,MAAM;EACxB,MAAM,eAAe;GACnB,IAAI,QACF,QAAQ,KAAK;EAEjB;EACA,MAAM,MAAM,QAAQ;EACpB,aAAa;GACX,SAAS;GACT,QAAQ,IAAI;EACd;CACF,GAAG,CAAC,QAAQ,SAAS,CAAC;CAEtB,gBAAgB;EACd,MAAM,SAAS,UAAU;EACzB,MAAM,UAAU,QAAQ,WAAW,IAAI;EACvC,IAAI,EAAE,UAAU,UACd;EAGF,QAAQ,UAAU,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;EACnD,IAAI,MACF,QAAQ,UAAU,MAAM,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;EAE3D,gBAAgB,SAAS,QAAQ,CAAC,GAAG,aAAa,KAAK,IAAI,WAAW;CACxE,GAAG;EAAC;EAAa;EAAM;CAAK,CAAC;CAE7B,MAAM,iBAAiB,UAAgD;EACrE,MAAM,SAAS,UAAU;EACzB,IAAI,CAAC,QACH;EAGF,OAAO,kBAAkB,MAAM,SAAS;EACxC,MAAM,QAAQ,aAAa,QAAQ,MAAM,SAAS,MAAM,OAAO;EAC/D,OAAO,WAAW;EAElB,SAAS;GACP;GACA,KAAK;GACL,IAAI,IAAI,OAAO;GACf,QAAQ,SAAS,QAAQ,CAAC,KAAK,IAAI,KAAA;GACnC,OAAO;GACP;EACF,CAAC;CACH;CAEA,MAAM,iBAAiB,UAAgD;EACrE,MAAM,SAAS,UAAU;EACzB,IAAI,EAAE,UAAU,QACd;EAGF,MAAM,QAAQ,aAAa,QAAQ,MAAM,SAAS,MAAM,OAAO;EAC/D,SACE,MAAM,SAAS,QACX;GAAE,GAAG;GAAO,KAAK;GAAO,QAAQ,CAAC,GAAI,MAAM,UAAU,CAAC,GAAI,KAAK;EAAE,IACjE;GAAE,GAAG;GAAO,KAAK;EAAM,CAC7B;CACF;CAEA,MAAM,oBAAoB;EACxB,IAAI,CAAC,OACH;EAEF,IAAI,CAAC,aAAa,KAAK,GACrB,SAAS,CAAC,GAAG,aAAa,KAAK,CAAC;EAElC,SAAS,IAAI;CACf;CAEA,gBAAgB;EACd,MAAM,aAAa,UAAyB;GAC1C,IAAI,MAAM,QAAQ,UAAU;IAC1B,MAAM,eAAe;IACrB,OAAO;GACT;EACF;EACA,SAAS,iBAAiB,WAAW,SAAS;EAC9C,aAAa,SAAS,oBAAoB,WAAW,SAAS;CAChE,GAAG,CAAC,MAAM,CAAC;CAEX,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,UAAD;IACE,QAAQ,QAAQ;IAChB,iBAAiB;IACF;IACA;IACF;IACb,KAAK;IACL,OAAO,QAAQ;GAChB,CAAA;EACE,CAAA,GAEL,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,MAAM,KAAK,EAAE,MAAM,MAAM,IAAI,YAC5B,oBAAC,UAAD;MACE,cAAY;MACZ,gBAAc,SAAS;MACvB,WAAU;MAEV,eAAe,QAAQ,EAAE;MACzB,OAAO;MACP,MAAK;MAEL,UAAA,oBAAC,MAAD,CAAO,CAAA;KACD,GAND,EAMC,CACT;IACE,CAAA;IAEL,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,kBAAkB,KAAK,UACtB,oBAAC,UAAD;MACE,cAAY,SAAS;MACrB,gBAAc,UAAU;MACxB,WAAU;MAEV,eAAe,SAAS,KAAK;MAC7B,OAAO,EAAE,YAAY,MAAM;MAC3B,MAAK;KACN,GAJM,KAIN,CACF;IACE,CAAA;IAEL,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,UAAD;OACE,cAAY,OAAO;OACnB,WAAU;OACV,UAAU,YAAY,WAAW;OACjC,eAAe,SAAS,YAAY,MAAM,GAAG,EAAE,CAAC;OAChD,OAAO,OAAO;OACd,MAAK;OAEL,UAAA,oBAAC,UAAD,CAAW,CAAA;MACL,CAAA;MACR,oBAAC,UAAD;OACE,cAAY,OAAO;OACnB,WAAU;OACV,UAAU,YAAY,WAAW;OACjC,eAAe,SAAS,CAAC,CAAC;OAC1B,OAAO,OAAO;OACd,MAAK;OAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;MACN,CAAA;MACR,oBAAC,UAAD;OAAQ,WAAU;OAAW,SAAS;OAAQ,MAAK;OAChD,UAAA,OAAO;MACF,CAAA;KACL;;GACF;EACF,CAAA,CAAA;;AAET;;;;;;;AC9NA,SAAgB,SAAS,EACvB,QACA,OACA,WAKC;CACD,OACE,qBAAC,UAAD;EACE,iBAAe;EACf,WAAU;EACV,aAAW;EACF;EACT,MAAK;EALP,UAAA,CAOE,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,UAAD,EAAU,WAAU,UAAW,CAAA,GAC/B,oBAAC,WAAD,EAAW,WAAU,WAAY,CAAA,CAC7B;EACL,CAAA,GAAA,KACK;;AAEZ;;;ACfA,MAAM,gBAGF;CACF,KAAK;EAAE,MAAM;EAAS,UAAU;CAAc;CAC9C,MAAM;EAAE,MAAM;EAAU,UAAU;CAAe;CACjD,UAAU;EAAE,MAAM;EAAc,UAAU;CAAmB;AAC/D;AAEA,SAAS,WAAW,EAClB,QACA,SAIC;CACD,IAAI,MAAM,aACR,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,OAAD,EAAK,WAAU,QAAS,CAAA,GACxB,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD,EAAA,UAAS,OAAO,WAAmB,CAAA,GACnC,oBAAC,QAAD,EAAA,UAAM,IAAO,CAAA,CACV;EACF,CAAA,CAAA;;CAIT,IAAI,CAAC,MAAM,SACT,OACE,qBAAC,UAAD;EACE,WAAU;EACV,eAAe,MAAM,YAAY;EACjC,MAAK;EAHP,UAAA,CAKE,oBAAC,YAAD,CAAa,CAAA,GACZ,OAAO,gBACF;;CAIZ,MAAM,kBAAkB,MAAM,YAAY;CAE1C,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,OAAD;KACE,KAAI;KACJ,QAAQ,MAAM,QAAQ;KACtB,KAAK,MAAM,QAAQ;KACnB,OAAO,MAAM,QAAQ;IACtB,CAAA;GACE,CAAA;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KAAQ,WAAU;KAAY,UAAA,OAAO;IAAmB,CAAA,GACxD,qBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA;MACG,MAAM,QAAQ;MAAM;MAAE,MAAM,QAAQ;MACpC,kBAAkB,IAAI,MAAM,gBAAgB,UAAU;KACnD;IACH,CAAA,CAAA;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,UAAD;MACE,cAAY,OAAO;MACnB,WAAU;MACV,eAAe,MAAM,QAAQ,UAAU;MACvC,OAAO,OAAO;MACd,MAAK;MAEL,UAAA,oBAAC,YAAD,CAAa,CAAA;KACP,CAAA;KACR,oBAAC,UAAD;MACE,cAAY,OAAO;MACnB,WAAU;MACV,eAAe,MAAM,YAAY;MACjC,OAAO,OAAO;MACd,MAAK;MAEL,UAAA,oBAAC,YAAD,CAAa,CAAA;KACP,CAAA;KACR,oBAAC,UAAD;MACE,cAAY,OAAO;MACnB,WAAU;MACV,SAAS,MAAM;MACf,OAAO,OAAO;MACd,MAAK;MAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;KACN,CAAA;IACL;;EACF;;AAET;;AAGA,SAAS,UAAU,EACjB,QACA,SAIC;CACD,MAAM,EAAE,gBAAgB,cAAc;CACtC,IAAI,CAAC,WACH,OACE,qBAAC,UAAD;EACE,WAAU;EACV,eAAe,MAAM,QAAQ,SAAS;EACtC,MAAK;EAHP,UAAA,CAKE,oBAAC,YAAD,CAAa,CAAA,GACZ,OAAO,WACF;;CAIZ,MAAM,YAAY,UAAU,eAAe;CAE3C,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;GACE,oBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,kBACC,oBAAC,OAAD;KACE,KAAI;KACJ,QAAQ,eAAe;KACvB,KAAK,eAAe;KACpB,OAAO,eAAe;IACvB,CAAA;GAEA,CAAA;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KAAQ,WAAU;KACf,UAAA,YAAY,IAAI,UAAU,KAAK,UAAU;IACpC,CAAA,GACR,oBAAC,QAAD;KAAM,WAAU;KACb,UAAA,UAAU,UAAU,UAAU,kBAAkB,UAAU;IACvD,CAAA,CACH;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KACE,cAAY,OAAO;KACnB,WAAU;KACV,eAAe,MAAM,QAAQ,SAAS;KACtC,OAAO,OAAO;KACd,MAAK;KAEL,UAAA,oBAAC,YAAD,CAAa,CAAA;IACP,CAAA,GACR,oBAAC,UAAD;KACE,cAAY,OAAO;KACnB,WAAU;KACV,SAAS,MAAM;KACf,OAAO,OAAO;KACd,MAAK;KAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;IACN,CAAA,CACL;;EACF;;AAET;AAEA,SAAgB,cAAc,EAC5B,YACA,QACA,SAKC;CACD,MAAM,aAAa,OAA4B,IAAI;CAEnD,gBAAgB;EACd,WAAW,SAAS,MAAM;CAC5B,GAAG,CAAC,CAAC;CAEL,IAAI,MAAM,SAAS,WACjB,OACE,oBAAC,WAAD;EAAS,aAAU;EAAS,WAAU;EACpC,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,WAAD,CAAY,CAAA;IACZ,oBAAC,MAAD,EAAA,UAAK,OAAO,aAAiB,CAAA;IAC7B,oBAAC,KAAD,EAAA,UAAI,OAAO,eAAkB,CAAA;GAC1B;;CACE,CAAA;CAIb,OACE,qBAAC,WAAD;EAAS,cAAY,OAAO;EAAO,WAAU;EAA7C,UAAA;GACE,qBAAC,UAAD;IAAQ,WAAU;IAAlB,UAAA;KACE,oBAAC,MAAD,EAAA,UAAK,OAAO,MAAU,CAAA;KACtB,oBAAC,QAAD,EAAM,WAAU,SAAU,CAAA;KAC1B,oBAAC,UAAD;MACE,cAAY,OAAO;MACnB,WAAU;MACV,SAAS,MAAM;MACf,MAAK;MAEL,UAAA,oBAAC,WAAD,CAAY,CAAA;KACN,CAAA;IACF;;GAER,qBAAC,QAAD;IACE,WAAU;IACV,WAAW,UAAU;KACnB,MAAM,eAAe;KACrB,MAAM,OAAO;IACf;IALF,UAAA;KAOG,WAAW,SAAS,KACnB,oBAAC,YAAD;MAAU,WAAU;MACjB,UAAA,WAAW,KAAK,UAAU;OACzB,MAAM,EAAE,MAAM,MAAM,aAAa,cAAc;OAC/C,OACE,qBAAC,UAAD;QACE,gBAAc,MAAM,aAAa;QAEjC,eAAe,MAAM,YAAY,KAAK;QACtC,MAAK;QAJP,UAAA,CAME,oBAAC,MAAD,CAAO,CAAA,GACN,OAAO,SACF;OAND,GAAA,KAMC;MAEZ,CAAC;KACO,CAAA;KAGZ,oBAAC,YAAD;MACE,cAAY,OAAO;MACnB,WAAW;MACX,WAAW,UAAU,MAAM,WAAW,MAAM,OAAO,KAAK;MACxD,aAAa,OAAO;MACpB,KAAK;MACL,OAAO,MAAM;KACd,CAAA;KAED,qBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,oBAAC,YAAD;OAAoB;OAAe;MAAQ,CAAA,GAC3C,oBAAC,WAAD;OAAmB;OAAe;MAAQ,CAAA,CACvC;;KAEJ,MAAM,eACL,oBAAC,SAAD;MACE,cAAY,OAAO;MACnB,cAAa;MACb,WAAW,UAAU,MAAM,SAAS,MAAM,OAAO,KAAK;MACtD,aAAa,OAAO;MACpB,MAAK;MACL,OAAO,MAAM;KACd,CAAA;KAGH,oBAAC,OAAD;MAAK,eAAY;MAAO,WAAU;MAChC,UAAA,oBAAC,SAAD;OACE,cAAa;OACb,MAAK;OACL,WAAW,UAAU,MAAM,YAAY,MAAM,OAAO,KAAK;OACzD,UAAU;OACV,OAAO,MAAM;MACd,CAAA;KACE,CAAA;KAEJ,MAAM,SAAS,oBAAC,KAAD;MAAG,WAAU;MAAS,UAAA,MAAM;KAAS,CAAA;KAErD,oBAAC,UAAD;MACE,WAAU;MACV,UAAU,MAAM,gBAAgB,CAAC,MAAM,QAAQ,KAAK;MACpD,MAAK;MAEJ,UAAA,MAAM,eAAe,oBAAC,QAAD,EAAM,WAAU,UAAW,CAAA,IAAI,OAAO;KACtD,CAAA;IACJ;;GAEN,qBAAC,UAAD;IAAQ,WAAU;IAAS,oBAAkB,MAAM;IAAnD,UAAA,CACG,MAAM,cACL,oBAAC,UAAD;KAAQ,WAAU;KAAc,SAAS,MAAM;KAAS,MAAK;KAC1D,UAAA,OAAO,eAAe,QACrB,UACA,OAAO,MAAM,cAAc,CAC7B;IACM,CAAA,GAEV,qBAAC,QAAD,EAAA,UAAA;KAAM;KACO;KACX,oBAAC,KAAD;MACE,MAAK;MACL,KAAI;MACJ,QAAO;MACR,UAAA;KAEE,CAAA;IACC,EAAA,CAAA,CACA;;EACD;;AAEb;;;ACnTA,MAAM,eAAe;AACrB,MAAM,YAAY;AAUlB,SAAS,cAAc,SAA2B;CAChD,OAAO,QAAQ,QAAQ,IAAI,cAAc,EAAE,MAAM;AACnD;AAEA,SAAS,aAAa,GAAW,GAA2B;CAC1D,MAAM,UAAU,SAAS,iBAAiB,GAAG,CAAC;CAC9C,IAAI,CAAC,WAAW,cAAc,OAAO,GACnC,OAAO;CAET,OAAO;AACT;AAEA,SAAS,eAAe,SAA+B;CACrD,OAAO;EACL,eAAe,sBAAsB,iBAAiB,OAAO,CAAC,CAAC,CAAC;EAChE;EACA,OAAO,gBAAgB,OAAO;EAC9B,MAAM,QAAQ,sBAAsB;EACpC,QAAQ,eAAe,OAAO;CAChC;AACF;;;;;AAMA,SAAgB,cAAc,EAC5B,MACA,UACA,UAKC;CACD,MAAM,CAAC,QAAQ,aAAa,SAA6B,IAAI;CAE7D,gBAAgB;EACd,MAAM,WAAW,UAAiB;GAChC,MAAM,eAAe;GACrB,MAAM,gBAAgB;EACxB;EAEA,MAAM,UAAU,UAAwB;GACtC,MAAM,UAAU,aAAa,MAAM,SAAS,MAAM,OAAO;GACzD,IAAI,CAAC,SAAS;IACZ,UAAU,IAAI;IACd;GACF;GAEA,WAAW,YACT,SAAS,YAAY,UACjB;IAAE,GAAG;IAAS,MAAM,QAAQ,sBAAsB;GAAE,IACpD,eAAe,OAAO,CAC5B;EACF;EAEA,MAAM,WAAW,UAAsB;GACrC,QAAQ,KAAK;GACb,MAAM,UAAU,aAAa,MAAM,SAAS,MAAM,OAAO;GACzD,IAAI,SACF,OAAO,OAAO;EAElB;EAEA,MAAM,aAAa,UAAyB;GAC1C,IAAI,MAAM,QAAQ,UAAU;IAC1B,QAAQ,KAAK;IACb,SAAS;GACX;EACF;EAGA,SAAS,iBAAiB,eAAe,QAAQ,IAAI;EACrD,SAAS,iBAAiB,eAAe,SAAS,IAAI;EACtD,SAAS,iBAAiB,aAAa,SAAS,IAAI;EACpD,SAAS,iBAAiB,WAAW,SAAS,IAAI;EAClD,SAAS,iBAAiB,SAAS,SAAS,IAAI;EAChD,SAAS,iBAAiB,WAAW,WAAW,IAAI;EAEpD,MAAM,iBAAiB,SAAS,KAAK,MAAM;EAC3C,SAAS,KAAK,MAAM,SAAS;EAE7B,aAAa;GACX,SAAS,oBAAoB,eAAe,QAAQ,IAAI;GACxD,SAAS,oBAAoB,eAAe,SAAS,IAAI;GACzD,SAAS,oBAAoB,aAAa,SAAS,IAAI;GACvD,SAAS,oBAAoB,WAAW,SAAS,IAAI;GACrD,SAAS,oBAAoB,SAAS,SAAS,IAAI;GACnD,SAAS,oBAAoB,WAAW,WAAW,IAAI;GACvD,SAAS,KAAK,MAAM,SAAS;EAC/B;CACF,GAAG,CAAC,UAAU,MAAM,CAAC;CAErB,MAAM,OAAO,QAAQ;CACrB,MAAM,aAAa,OAAO,KAAK,MAAM,KAA2B;CAEhE,OACE,qBAAC,OAAD,EAAA,UAAA;EACG,QACC,oBAAC,OAAD;GACE,WAAU;GACV,OAAO;IACL,QAAQ,KAAK;IACb,MAAM,KAAK;IACX,KAAK,KAAK;IACV,OAAO,KAAK;GACd;EACD,CAAA;EAEF,QAAQ,UACP,qBAAC,OAAD;GACE,WAAU;GACV,OAAO;IACL,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI;IAC3B,KAAK,aACD,KAAK,MAAM,eAAe,YAC1B,KAAK,SAAS;GACpB;GAPF,UAAA,CASE,oBAAC,UAAD,EAAA,UACG,OAAO,gBAAgB,IAAI,OAAO,cAAc,KAAK,OAAO,MACvD,CAAA,GACP,OAAO,UAAU,oBAAC,QAAD,EAAA,UAAO,OAAO,OAAa,CAAA,CAC1C;;EAEP,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACG;IAAK;IAAC,oBAAC,OAAD,EAAA,UAAK,MAAQ,CAAA;GACjB;;CACF,EAAA,CAAA;AAET;;;;;;;AC/IA,MAAa,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACC7B,MAAM,aAAa;AAInB,SAAS,iBAAiB,OAAsC;CAC9D,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,gBAAgB;EACd,IAAI,UAAU,UAAU,OAAO,OAAO,eAAe,YACnD;EAGF,MAAM,QAAQ,OAAO,WAAW,UAAU;EAC1C,cAAc,MAAM,OAAO;EAE3B,MAAM,YAAY,UAChB,cAAc,MAAM,OAAO;EAC7B,MAAM,iBAAiB,UAAU,QAAQ;EACzC,aAAa,MAAM,oBAAoB,UAAU,QAAQ;CAC3D,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,UAAU,QACZ,OAAO,aAAa,SAAS;CAE/B,OAAO;AACT;;;;;;AAOA,SAAgB,aAAa,EAC3B,UACA,QACA,cACA,SAMC;CACD,MAAM,CAAC,YAAY,iBAAiB,SAA4B,IAAI;CACpE,MAAM,gBAAgB,iBAAiB,KAAK;CAE5C,gBAAgB;EACd,MAAM,OAAO,SAAS,cAAc,KAAK;EACzC,KAAK,aAAa,eAAe,EAAE;EACnC,MAAM,OAAO,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;EAE/C,MAAM,QAAQ,SAAS,cAAc,OAAO;EAC5C,MAAM,cAAc;EACpB,KAAK,OAAO,KAAK;EACjB,SAAS,KAAK,OAAO,IAAI;EACzB,cAAc,IAAI;EAElB,aAAa,KAAK,OAAO;CAC3B,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,OAAO,YAAY;EACzB,IAAI,EAAE,gBAAgB,cACpB;EAGF,KAAK,aAAa,cAAc,aAAa;EAC7C,KAAK,MAAM,YAAY,eAAe,GAAG,OAAO,GAAG;EACnD,IAAI,cACF,KAAK,MAAM,YAAY,gBAAgB,YAAY;CAEvD,GAAG;EAAC;EAAY;EAAe;EAAc;CAAM,CAAC;CAEpD,IAAI,CAAC,YACH,OAAO;CAGT,OAAO,aAAa,UAAU,UAAU;AAC1C;;;ACjFA,MAAM,gBAAgB;AACtB,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB,CAAC,SAAS,MAAM;AASzC,SAAS,kBAAkB,OAAwB;CACjD,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,IAAI,iBAAiB,OACnB,OAAO,GAAG,MAAM,KAAK,IAAI,MAAM;CAEjC,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC9B,OAAO,OAAO,KAAK;CAErB,IAAI,OAAO,UAAU,UACnB,IAAI;EACF,OAAO,KAAK,UAAU,KAAK,KAAK;CAClC,QAAQ;EACN,OAAO;CACT;CAEF,IAAI,OAAO,UAAU,YACnB,OAAO;CAET,OAAO,OAAO,KAAK;AACrB;AAEA,SAAS,cAAc,MAAyB;CAC9C,MAAM,UAAU,KAAK,IAAI,iBAAiB,CAAC,CAAC,KAAK,GAAG;CACpD,OAAO,QAAQ,SAAS,qBACpB,GAAG,QAAQ,MAAM,GAAG,GAAsB,EAAE,KAC5C;AACN;;;;;AAMA,SAAgB,qBAAqB,SAEjB;CAClB,MAAM,QAAQ,SAAS,SAAS;CAChC,MAAM,SAAyB,CAAC;CAChC,IAAI,SAAS;CAEb,MAAM,QAAQ,OAA8B,YAAoB;EAC9D,IAAI,EAAE,UAAU,UACd;EAEF,OAAO,KAAK;GAAE;GAAO;GAAS,WAAW,KAAK,IAAI;EAAE,CAAC;EACrD,IAAI,OAAO,SAAS,OAClB,OAAO,OAAO,GAAG,OAAO,SAAS,KAAK;CAE1C;CAEA,MAAM,4BAAY,IAAI,IAAkD;CACxE,MAAM,2BAAW,IAAI,IAAkD;CAEvE,KAAK,MAAM,UAAU,kBAAkB;EACrC,MAAM,WAAW,QAAQ;EACzB,MAAM,WAAW,GAAG,SAAoB;GACtC,KAAK,QAAQ,cAAc,IAAI,CAAC;GAChC,QAAQ,MAAM,UAAU,SAAS,IAAI;EACvC;EACA,UAAU,IAAI,QAAQ,QAAQ;EAC9B,SAAS,IAAI,QAAQ,OAAO;EAC5B,QAAQ,UAAU;CACpB;CAEA,MAAM,WAAW,UAAsB;EACrC,MAAM,QAAQ,MAAM,WAChB,KAAK,MAAM,SAAS,GAAG,MAAM,OAAO,GAAG,MAAM,MAAM,KACnD;EACJ,KAAK,SAAS,GAAG,MAAM,UAAU,OAAO;CAC1C;CAEA,MAAM,eAAe,UAAiC;EACpD,KAAK,SAAS,wBAAwB,kBAAkB,MAAM,MAAM,GAAG;CACzE;CAEA,OAAO,iBAAiB,SAAS,OAAO;CACxC,OAAO,iBAAiB,sBAAsB,WAAW;CAEzD,OAAO;EACL,cAAc,OAAO,MAAM;EAC3B,YAAY;GACV,IAAI,CAAC,QACH;GAEF,SAAS;GACT,OAAO,SAAS;GAEhB,KAAK,MAAM,UAAU,kBAAkB;IACrC,MAAM,WAAW,UAAU,IAAI,MAAM;IAErC,IAAI,YAAY,QAAQ,YAAY,SAAS,IAAI,MAAM,GACrD,QAAQ,UAAU;GAEtB;GAEA,OAAO,oBAAoB,SAAS,OAAO;GAC3C,OAAO,oBAAoB,sBAAsB,WAAW;EAC9D;CACF;AACF;;;AC7GA,MAAM,sBAAsB;AAC5B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,kBAAkB;AACxB,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,gBAAgB;AACtB,MAAM,aAAa;AACnB,MAAM,cAAc;;;;;;AAOpB,SAAgB,eAAe,SAA2B;CACxD,MAAM,SAAS,QAAQ,sBAAsB;CAC7C,MAAM,iBAAiB,KAAc,WACnC,IAAI,QAAQ,OAAO,OAAO,UAC1B,IAAI,SAAS,OAAO,QAAQ,UAC5B,IAAI,OAAO,OAAO,MAAM,UACxB,IAAI,UAAU,OAAO,SAAS;CAEhC,IAAI,WAA2B;CAC/B,IAAI,UAAU,QAAQ;CAEtB,OAAO,WAAW,YAAY,SAAS,iBAAiB;EACtD,MAAM,MAAM,QAAQ,sBAAsB;EAE1C,IAAI,cAAc,KAAK,mBAAmB,GACxC,OAAO;EAET,aAAa,IAAI,QAAQ,oBAAoB,UAAU;EAEvD,UAAU,QAAQ;CACpB;CAEA,OAAO,YAAY;AACrB;;AAWA,SAAgB,gBAAgB,QAIZ;CAClB,MAAM,QACJ,OAAO,SAAS,QAAQ,IACpB,OAAO,QAAQ,QAAQ,OAAO,SAAS,QACvC;CAEN,OAAO;EACL,QAAQ,KAAK,MAAM,OAAO,YAAY,SAAS,KAAK;EACpD;EACA,OAAO,KAAK,MAAM,OAAO,YAAY,QAAQ,KAAK;EAClD,GAAG,KAAK,OAAO,OAAO,YAAY,OAAO,OAAO,SAAS,QAAQ,KAAK;EACtE,GAAG,KAAK,OAAO,OAAO,YAAY,MAAM,OAAO,SAAS,OAAO,KAAK;CACtE;AACF;;AAGA,SAAgB,aACd,WACA,SACY;CACZ,MAAM,QAAQ,QAAQ,QAAQ,OAAO;CACrC,MAAM,EAAE,SAAS;CAEjB,OAAO;EACL,OAAO;EACP,KAAK;GACH,IAAI,KAAK,IAAI,KAAK,SAAS;GAC3B,IAAI,KAAK,IAAI,KAAK,UAAU;EAC9B;EACA,IAAI,aAAa,KAAK,EAAE,GAAG,KAAK;EAChC,OAAO;GAAE,GAAG,KAAK,IAAI;GAAO,GAAG,KAAK,IAAI;EAAM;EAC9C,MAAM;CACR;AACF;AAEA,SAAS,gBACP,SACA,MACM;CACN,QAAQ,KAAK;CACb,QAAQ,YAAY;CACpB,QAAQ,UAAU;CAClB,QAAQ,KAAK,GAAG,GAAG,QAAQ,OAAO,OAAO,QAAQ,OAAO,MAAM;CAC9D,QAAQ,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;CACpD,QAAQ,KAAK,SAAS;CAEtB,KAAK,MAAM,CAAC,OAAO,UAAU,CAC3B,CAAC,cAAc,UAAU,GACzB,CAAC,eAAe,aAAa,CAC/B,GAAY;EACV,QAAQ,cAAc;EACtB,QAAQ,YAAY,QAAQ,KAAK;EACjC,QAAQ,WAAW,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;CAC5D;CACA,QAAQ,QAAQ;AAClB;AAEA,SAAS,YACP,SACA,MAC+B;CAC/B,OAAO,IAAI,SAAS,YAAY;EAC9B,MAAM,SAAS,SAAS,cAAc,QAAQ;EAC9C,OAAO,QAAQ,QAAQ;EACvB,OAAO,SAAS,QAAQ;EACxB,MAAM,UAAU,OAAO,WAAW,IAAI;EACtC,MAAM,QAAQ,IAAI,MAAM;EAExB,MAAM,eAAe;GACnB,IAAI,CAAC,SAAS;IACZ,QAAQ,IAAI;IACZ;GACF;GACA,QAAQ,UAAU,OAAO,GAAG,GAAG,QAAQ,OAAO,QAAQ,MAAM;GAC5D,gBAAgB,SAAS,IAAI;GAC7B,QAAQ,mBAAmB,QAAQ,kBAAkB,CAAC;EACxD;EACA,MAAM,gBAAgB,QAAQ,IAAI;EAClC,MAAM,MAAM,QAAQ;CACtB,CAAC;AACH;;;;;;;AAQA,eAAsB,sBACpB,SAC+B;CAC/B,IAAI;EACF,MAAM,OAAO,eAAe,OAAO;EACnC,MAAM,WAAW,KAAK,sBAAsB;EAC5C,MAAM,cAAc,QAAQ,sBAAsB;EAElD,MAAM,UAAU,MAAM,gBAAgB;GACpC,SAAS;GACT,UAAU;EACZ,CAAC;EACD,IAAI,CAAC,WAAW,SAAS,SACvB,OAAO;EAIT,MAAM,WAAW,MAAM,YAAY,SADtB,gBAAgB;GAAE;GAAS;GAAa;EAAS,CACf,CAAC;EAEhD,IAAI,UAAU;GACZ,eAAe,OAAO;GACtB,OAAO;EACT;EACA,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;;AC9JA,MAAM,mBAAmB;AACzB,MAAM,UAAU;;AA8BhB,SAAgB,YAAY,SAAyB;CACnD,MAAM,YACJ,QACG,MAAM,OAAO,CAAC,CACd,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,KAAK,OAAO,KAAK;CAEtB,IAAI,UAAU,UAAU,kBACtB,OAAO;CAGT,MAAM,UAAU,UAAU,MAAM,GAAG,EAAoB;CACvD,MAAM,YAAY,QAAQ,YAAY,GAAG;CACzC,OAAO,IAAI,YAAY,IAAI,QAAQ,MAAM,GAAG,SAAS,IAAI,QAAA,CAAS,QAAQ,EAAE;AAC9E;AAEA,SAAgB,iBAAiB,QAKtB;CACT,MAAM,EAAE,UAAU,OAAO,aAAa,YAAY;CAClD,MAAM,QAAQ,SAAS,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;CACjE,MAAM,UAAU,eAAe,QAAQ,qBAAqB,UAAU;CAEtE,OAAO,IAAI,MAAM,IAAI,QAAQ,KAAK,IAAI;AACxC;AAEA,eAAe,OACb,WACA,OACiB;CACjB,MAAM,EAAE,cAAc,MAAM,UAAU,uBAAuB;CAC7D,OAAO,MAAM,UAAU,YAAY,WAAW,KAAK;AACrD;AAEA,eAAe,iBACb,WACA,YACA,YACkB;CAClB,MAAM,EAAE,WAAW,aAAa,SAAS,eAAe;CACxD,IAAI,CAAC,YACH,OAAO;CAGT,MAAM,YAAY,MAAM,OAAO,WAAW,UAAU;CACpD,MAAM,qBAAqB,YACvB,MAAM,OAAO,WAAW,SAAS,IACjC,KAAA;CACJ,MAAM,kBAAkB,kBAAkB,WAAW;CAErD,MAAM,UAAU,eAAe;EAC7B;EACA,aAAa,gBAAgB,SAAS,IAAI,kBAAkB,KAAA;EAC5D,eAAe;EACf;EACA,UAAU;EACV,QAAQ,WAAW;EACnB,UAAU,WAAW;EACrB,SAAS,QAAQ;EACjB,MAAM,WAAW,KAAK;EACtB;EACA,OAAO,WAAW;CACpB,CAAC;CAED,OAAO;AACT;AAEA,eAAe,cACb,WACA,YACA,YACe;CACf,MAAM,EAAE,SAAS,YAAY;CAC7B,IAAI,CAAC,SACH;CAGF,MAAM,UAAU,eAAe;EAC7B,eAAe;EACf;EACA,UAAU;EACV,QAAQ,QAAQ;EAChB,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB,MAAM,QAAQ,KAAK;EACnB,WAAW,MAAM,OAAO,WAAW,OAAO;EAC1C,OAAO,QAAQ;CACjB,CAAC;AACH;;;;;AAMA,eAAsB,qBACpB,WACA,YACuB;CACvB,MAAM,QAAQ,YAAY,WAAW,OAAO;CAC5C,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,kDAAkD;CAGpE,MAAM,EAAE,eAAe,MAAM,UAAU,OAAO;EAC5C,SAAS,WAAW;EACpB,aAAa,iBAAiB,UAAU;EACxC;CACF,CAAC;CAED,MAAM,kBAAkB,MAAM,iBAC5B,WACA,YACA,UACF,CAAC,CAAC,YAAY,KAAK;CACnB,MAAM,cAAc,WAAW,YAAY,UAAU,CAAC,CAAC,YAAY,KAAA,CAAS;CAE5E,OAAO;EAAE;EAAY;CAAgB;AACvC;AAEA,SAAS,kBAAkB,OAAgD;CACzE,OACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAO,QAAQ,IAAI,OAAO,WAAW,MAAM;AAE/C;AAEA,SAAgB,wBAAwB,QAAmC;CACzE,OAAO;EACL,SAAS,WAAW,OAAO,OAAO,MAAM;EACxC,8BAA8B,OAAO,uBAAuB;EAC5D,iBAAiB,WAAW,OAAO,eAAe,MAAM;EACxD,aAAa,OAAO,WAAW,UAAU;GACvC,MAAM,WAAW,MAAM,MAAM,WAAW;IACtC,MAAM,MAAM;IACZ,SAAS,EAAE,gBAAgB,MAAM,SAAS;IAC1C,QAAQ;GACV,CAAC;GAED,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,6BAA6B,SAAS,OAAO,EAAE;GAGjE,MAAM,UAAmB,MAAM,SAAS,KAAK;GAC7C,IAAI,CAAC,kBAAkB,OAAO,GAC5B,MAAM,IAAI,MAAM,0CAA0C;GAG5D,OAAO,QAAQ;EACjB;CACF;AACF;;;ACrMA,MAAM,kBAAkB;;;;;;;AAQxB,SAAgB,eAAe,SAAkB,SAA2B;CAC1E,gBAAgB;EACd,IAAI,CAAC,SACH;EAGF,MAAM,UAAU,OAAO;EACvB,MAAM,eAAe,QAAQ;EAC7B,MAAM,kBAAkB,QAAQ;EAChC,MAAM,aAAa,OAAO,OAAO,SAAS,WAAW;EACrD,MAAM,gBAAgB,OAAO,OAAO,SAAS,cAAc;EAE3D,QAAQ,YAAY,SAAS,UAAU,MAAM,QAAQ,KAAK;GACxD,MAAM,SAAS,aAAa,KAAK,SAAS,MAAM,QAAQ,GAAG;GAC3D,QAAQ;GACR,OAAO;EACT;EACA,QAAQ,eAAe,SAAS,aAAa,MAAM,QAAQ,KAAK;GAC9D,MAAM,SAAS,gBAAgB,KAAK,SAAS,MAAM,QAAQ,GAAG;GAC9D,QAAQ;GACR,OAAO;EACT;EACA,OAAO,iBAAiB,YAAY,OAAO;EAE3C,IAAI;EACJ,MAAM,iBAAiB;GACrB,OAAO,aAAa,WAAW;GAC/B,cAAc,OAAO,WAAW,SAAS,eAAe;EAC1D;EACA,OAAO,iBAAiB,UAAU,QAAQ;EAE1C,aAAa;GACX,IAAI,YACF,QAAQ,YAAY;QAEpB,QAAQ,eAAe,SAAS,WAAW;GAE7C,IAAI,eACF,QAAQ,eAAe;QAEvB,QAAQ,eAAe,SAAS,cAAc;GAEhD,OAAO,oBAAoB,YAAY,OAAO;GAC9C,OAAO,aAAa,WAAW;GAC/B,OAAO,oBAAoB,UAAU,QAAQ;EAC/C;CACF,GAAG,CAAC,SAAS,OAAO,CAAC;AACvB;;;AC1BA,MAAM,sBAAsB;AAC5B,MAAM,WAAW;AACjB,MAAM,uBAAuB;AAC7B,MAAM,2BAA2B;AAEjC,SAAS,mBAAmB,KAAqB;CAC/C,IAAI,OAAO,WAAW,aACpB,OAAO;CAGT,IAAI;EACF,MAAM,QAAQ,OAAO,SAAS,OAAO,aAAa,QAAQ,GAAG,KAAK,IAAI,EAAE;EACxE,IAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,KAAK,IAAI,GAC7C,OAAO;EAET,OAAO,aAAa,WAAW,GAAG;CACpC,QAAQ;EACN,OAAO;CACT;CAEA,OAAO;AACT;AAEA,SAAS,oBAAoB,KAAa,OAAqB;CAC7D,IAAI;EACF,OAAO,aAAa,QAAQ,KAAK,OAAO,KAAK,CAAC;CAChD,QAAQ,CAER;AACF;;;;;AAMA,SAAgB,cACd,OAIA,QACA,WAAW,OAAO,cAAc,cAAc,KAAK,UAAU,UACpD;CACT,MAAM,QAAQ,OACX,YAAY,CAAC,CACb,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC;CAC5B,MAAM,MAAM,MAAM,GAAG,EAAE;CACvB,IAAI,CAAC,OAAO,MAAM,IAAI,YAAY,MAAM,KACtC,OAAO;CAGT,MAAM,UAAU,SAAS,KAAK,QAAQ;CACtC,MAAM,WAAW,MAAM,SAAS,KAAK;CACrC,MAAM,WAAW;EACf,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,QAAQ;EACrD,MAAM,MAAM,SAAS,MAAM,KAAM,YAAY,CAAC;EAC9C,MACE,MAAM,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,KAAM,YAAY;EAClE,OAAO,MAAM,SAAS,OAAO;CAC/B;CAEA,OACE,MAAM,WAAW,SAAS,OAC1B,MAAM,YAAY,SAAS,QAC3B,MAAM,YAAY,SAAS,QAC3B,MAAM,aAAa,SAAS;AAEhC;;;;;AAMA,SAAS,kBAAkB;CACzB,MAAM,CAAC,OAAO,YAAY,SAA+B,IAAI;CAC7D,MAAM,MAAM,OAA6B,IAAI;CAE7C,gBAAgB;EACd,IAAI,UAAU;CAChB,GAAG,CAAC,KAAK,CAAC;CACV,sBAAsB,eAAe,IAAI,OAAO,GAAG,CAAC,CAAC;CAOrD,OAAO,CAAC,OALQ,aAAa,SAA+B;EAC1D,eAAe,IAAI,OAAO;EAC1B,SAAS,IAAI;CACf,GAAG,CAAC,CAEiB,CAAC;AACxB;AAEA,SAAgB,eAAe,OAA4B;CACzD,MAAM,UAAU,WAAW,aAAa;CACxC,MAAM,YAAY,MAAM,aAAa,SAAS;CAC9C,MAAM,UAAU,MAAM,WAAW,SAAS;CAC1C,MAAM,OAAO,MAAM,QAAQ,SAAS;CACpC,MAAM,YAAY,MAAM,aAAa,SAAS;CAC9C,MAAM,cAAc,EAAE,QAAQ;CAC9B,MAAM,iBACJ,MAAM,mBAAmB,KAAA,KACzB,OAAO,SAAS,MAAM,cAAc,KACpC,MAAM,iBAAiB,IACnB,MAAM,iBACN;CACN,MAAM,eAAe,GAAG,yBAAyB,GAAG,aAAa,UAAU,GAAG,MAAM,MAAM;CAE1F,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,MAAM,WAAW,SAAqB,SAAS;CACtD,MAAM,CAAC,UAAU,eAAe,SAC9B,MAAM,mBAAmB,KAC3B;CACA,MAAM,CAAC,SAAS,cAAc,SAAS,EAAE;CACzC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,CAAC,UAAU,eAAe,SAAS,EAAE;CAC3C,MAAM,CAAC,SAAS,kBAAkB,gBAAgB;CAClD,MAAM,CAAC,gBAAgB,yBAAyB,gBAAgB;CAChE,MAAM,CAAC,aAAa,kBAAkB,SAAuB,CAAC,CAAC;CAC/D,MAAM,CAAC,WAAW,gBAAgB,SAAkC,IAAI;CACxE,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CACtD,MAAM,CAAC,gBAAgB,qBAAqB,eAC1C,mBAAmB,YAAY,CACjC;CAEA,MAAM,UAAU,OAAO,CAAC;CACxB,MAAM,aAAa,OAA+B,IAAI;CACtD,MAAM,gBAAgB,OAA+B,IAAI;CAEzD,gBAAgB;EACd,kBAAkB,mBAAmB,YAAY,CAAC;CACpD,GAAG,CAAC,YAAY,CAAC;CAEjB,gBAAgB;EACd,IAAI,MAAM,mBAAmB,OAC3B;EAEF,MAAM,WAAW,qBAAqB;EACtC,WAAW,UAAU;EACrB,aAAa;GACX,WAAW,UAAU;GACrB,SAAS,KAAK;EAChB;CACF,GAAG,CAAC,MAAM,cAAc,CAAC;;CAGzB,MAAM,cAAc,kBAAwB;EAC1C,MAAM,UAAU,mBAAmB,EAAE,YAAY,YAAY,CAAC;EAC9D,eAAe,IAAI;EACnB,gBAAgB,CAAC,CACd,YAAY,IAAI,CAAC,CACjB,MAAM,UAAU;GACf,eAAe,KAAK;GACpB,eAAe,KAAK;GACpB,cAAc,UAAU,QAAQ,UAAU;EAC5C,CAAC;CACL,GAAG,CAAC,cAAc,CAAC;CAEnB,eACE,UACE,SAAS,aACT,YAAY,WAAW,KACvB,CAAC,aACD,MAAM,kBAAkB,OAC1B,WACF;CAEA,MAAM,QAAQ,kBAAkB;EAC9B,QAAQ;EACR,cAAc,UAAU;EACxB,eAAe,IAAI;EACnB,sBAAsB,IAAI;EAC1B,eAAe,CAAC,CAAC;EACjB,aAAa,IAAI;EACjB,WAAW,EAAE;EACb,SAAS,EAAE;EACX,YAAY,EAAE;EACd,SAAS,IAAI;EACb,QAAQ,SAAS;EACjB,YAAY,MAAM,mBAAmB,KAAK;CAC5C,GAAG;EAAC,MAAM;EAAiB;EAAgB;CAAqB,CAAC;CAEjE,MAAM,QAAQ,kBAAkB;EAC9B,UAAU,KAAK;EACf,MAAM;EACN,MAAM,UAAU;CAClB,GAAG,CAAC,OAAO,MAAM,OAAO,CAAC;CACzB,MAAM,UAAU,kBAAkB;EAChC,IAAI,mBAAmB,MACrB;EAGF,MAAM,QAAQ,KAAK,IAAI,IAAI,iBAAiB;EAC5C,oBAAoB,cAAc,KAAK;EACvC,UAAU,KAAK;EACf,MAAM;EACN,kBAAkB,KAAK;EACvB,MAAM,YAAY,EAAE,MAAM,CAAC;CAC7B,GAAG;EAAC;EAAgB;EAAc,MAAM;EAAW;CAAK,CAAC;CAEzD,MAAM,OAAO,kBAAkB;EAC7B,UAAU,IAAI;EACd,QAAQ,SAAS;EACjB,MAAM,SAAS;EACf,IAAI,MAAM,kBAAkB,OAC1B,YAAY;CAEhB,GAAG;EAAC,MAAM;EAAe,MAAM;EAAQ;CAAW,CAAC;;CAGnD,MAAM,gBAAgB,YACpB,OAAO,YAAqB;EAC1B,MAAM,SAAS,sBAAsB,OAAO;EAC5C,aAAa,MAAM;EACnB,QAAQ,SAAS;EAEjB,MAAM,OAAO,EAAE,QAAQ;EACvB,MAAM,UAAU,mBAAmB,EAAE,YAAY,YAAY,CAAC;EAC9D,MAAM,CAAC,OAAO,WAAW,MAAM,QAAQ,IAAI,CACzC,gBAAgB,CAAC,CAAC,YAAY,IAAI,GAClC,sBAAsB,OAAO,CAAC,CAAC,YAAY,IAAI,CACjD,CAAC;EAED,IAAI,QAAQ,YAAY,MAAM;GAC5B,eAAe,KAAK;GACpB,eAAe,OAAO;GACtB;EACF;EAEA,eAAe,KAAK;EACpB,sBAAsB,OAAO;EAC7B,cAAc,UAAU,QAAQ,UAAU;EAC1C,eAAe,QAAQ,CAAC,aAAa,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC;CAC3D,GACA,CAAC,gBAAgB,qBAAqB,CACxC;CAEA,MAAM,iBAAiB,kBAAkB;EACvC,QAAQ;EACR,sBAAsB,IAAI;EAC1B,aAAa,IAAI;EACjB,gBAAgB,aACd,SAAS,QAAQ,SAAS,CAAC,KAAK,GAAG,WAAW,YAAY,CAAC,CAC7D;CACF,GAAG,CAAC,qBAAqB,CAAC;CAE1B,MAAM,gBAAgB,kBAAkB;EACtC,cAAc,UAAU;EACxB,eAAe,IAAI;EACnB,eAAe,CAAC,CAAC;CACnB,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,SAAS,cAEX,YAAY,IAAI,OAAO;EAAE;EAAS;EAAW;EAAM;CAAU,CAAC,IAAI,MACpE;EAAC;EAAS;EAAW;EAAM;CAAS,CACtC;CAEA,MAAM,SAAS,YAAY,YAAY;EACrC,IAAI,UAAU;GACZ,QAAQ,SAAS;GACjB;EACF;EACA,IAAI,CAAC,QAAQ;GACX,SACE,8EACF;GACA;EACF;EAEA,gBAAgB,IAAI;EACpB,SAAS,IAAI;EAEb,IAAI,YAAkC;EAEtC,IAAI;GACF,YAAY,UACR,MAAM,qBAAqB,SAAS,WAAW,IAC/C;GAEJ,MAAM,SAAS,MAAM,qBACnB,wBAAwB,MAAM,GAC9B;IACE;IACA;IACA;IACA,SAAS;KACP,GAAI,cAAc,WAChB,mBAAmB,EAAE,YAAA,QAAwB,CAAC;KAChD,eAAe,WAAW,SAAS,OAAO;KAC1C,UAAU,MAAM;KAChB,WAAW,aAAa,KAAA;IAC1B;IACA,SAAS;IACT;IACA;IACA;IACA,YAAY;GACd,CACF;GAEA,QAAQ,SAAS;GACjB,MAAM,WAAW,EAAE,YAAY,OAAO,WAAW,CAAC;GAClD,WAAW,OAAO,mBAAmB;EACvC,SAAS,aAAa;GACpB,SACE,uBAAuB,QACnB,YAAY,UACZ,yCACN;EACF,UAAU;GACR,eAAe,SAAS;GACxB,gBAAgB,KAAK;EACvB;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACN,MAAM;EACN;CACF,CAAC;CAED,OAAO;EACL;EACA,YAAY,mBAAmB;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAAa,iBAAiB,KAAK,IAAI;EACvC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;AC7XA,MAAM,qBAA+C;CACnD;CACA;CACA;AACF;AACA,MAAM,iBAAiB;;;;;;AAOvB,SAAgB,eAAe,OAA4B;CACzD,MAAM,EACJ,aAAa,oBACb,UAAU,MACV,SAAS,MACT,SAAS,gBACT,WAAW,gBACX,QAAQ,WACN;CAEJ,MAAM,SAAS;EAAE,GAAG;EAAuB,GAAG,MAAM;CAAO;CAC3D,MAAM,QAAQ,eAAe,KAAK;CAClC,MAAM,EAAE,OAAO,QAAQ,SAAS;CAEhC,gBAAgB;EACd,IAAI,EAAE,UAAU,UACd;EAGF,MAAM,aAAa,UAAyB;GAC1C,IAAI,cAAc,OAAO,MAAM,GAAG;IAChC,MAAM,eAAe;IACrB,IAAI,QACF,MAAM;SAEN,KAAK;GAET;EACF;EAEA,SAAS,iBAAiB,WAAW,SAAS;EAC9C,aAAa,SAAS,oBAAoB,WAAW,SAAS;CAChE,GAAG;EAAC;EAAO;EAAS;EAAQ;EAAQ;CAAI,CAAC;CAEzC,gBAAgB;EACd,IAAI,CAAC,UAAU,MAAM,SAAS,WAC5B;EAGF,MAAM,aAAa,UAAyB;GAC1C,IAAI,MAAM,QAAQ,UAChB,MAAM;EAEV;EAEA,SAAS,iBAAiB,WAAW,SAAS;EAC9C,aAAa,SAAS,oBAAoB,WAAW,SAAS;CAChE,GAAG;EAAC;EAAO;EAAQ,MAAM;CAAI,CAAC;CAE9B,IAAI,CAAC,WAAW,MAAM,aACpB,OAAO;CAGT,MAAM,YACJ,UAAU,MAAM,SAAS,aAAa,MAAM,SAAS;CAEvD,OACE,qBAAC,cAAD;EACU;EACR,cAAc,MAAM;EACb;EAHT,UAAA;GAKE,qBAAC,OAAD;IAAK,WAAU;IAAO,iBAAe;IAArC,UAAA,CACG,aACC,oBAAC,eAAD;KACc;KACJ;KACD;IACR,CAAA,GAEH,oBAAC,UAAD;KACU;KACR,OAAO,OAAO;KACd,SAAS,SAAS,QAAQ;IAC3B,CAAA,CACE;;GAEJ,UAAU,MAAM,SAAS,cAAc,MAAM,WAC5C,oBAAC,WAAD;IACE,aAAa,MAAM;IACnB,SAAS,MAAM;IACP;IACR,UAAU,MAAM;IAChB,cAAc,MAAM,QAAQ,SAAS;GACtC,CAAA;GAGF,UAAU,MAAM,SAAS,aACxB,oBAAC,eAAD;IACE,MAAM,OAAO;IACb,gBAAgB,MAAM,QAAQ,SAAS;IACvC,QAAQ,MAAM;GACf,CAAA;EAES;;AAElB"}
|
|
1
|
+
{"version":3,"file":"feedback.js","names":["MAX_TEXT_LENGTH","truncate"],"sources":["../src/feedback/core/capture.ts","../src/feedback/core/react-source.ts","../src/feedback/core/redact.ts","../src/feedback/core/element-selector.ts","../src/feedback/core/page-context.ts","../src/feedback/types.ts","../src/feedback/core/annotations.ts","../src/feedback/ui/annotation/color-value.ts","../src/feedback/ui/icons.tsx","../src/feedback/ui/annotation/text/text-editor.tsx","../src/feedback/ui/annotation/text/use-text-annotation.ts","../src/feedback/ui/floating/use-details-popover.ts","../src/feedback/ui/annotation/color-picker.tsx","../src/feedback/ui/annotation/tool-menu.tsx","../src/feedback/ui/annotation/toolbar.tsx","../src/feedback/core/annotation-renderer.ts","../src/feedback/ui/annotation/use-annotation-canvas.ts","../src/feedback/ui/annotation/use-image-morph.ts","../src/feedback/ui/annotator.tsx","../src/feedback/ui/launcher.tsx","../src/feedback/ui/annotation/screenshot-preview.tsx","../src/feedback/ui/composer/screenshot-card.tsx","../src/feedback/ui/composer/attachments.tsx","../src/feedback/ui/composer/options.tsx","../src/feedback/ui/composer/controls.tsx","../src/feedback/ui/composer/message-input.tsx","../src/feedback/ui/panel.tsx","../src/feedback/ui/floating/use-floating-position.ts","../src/feedback/ui/floating/floating-widget.tsx","../src/feedback/ui/picker.tsx","../src/feedback/ui/annotation/styles.ts","../src/feedback/ui/composer/styles.ts","../src/feedback/ui/floating/picker-styles.ts","../src/feedback/ui/styles.ts","../src/feedback/ui/shadow-portal.tsx","../src/feedback/core/console-recorder.ts","../src/feedback/core/element-capture.ts","../src/feedback/core/submission/upload-screenshots.ts","../src/feedback/core/submit.ts","../src/feedback/ui/state/use-feedback-submission.ts","../src/feedback/ui/state/use-owned-capture.ts","../src/feedback/ui/state/use-screenshot-drafts.ts","../src/feedback/ui/state/use-widget-config.ts","../src/feedback/ui/use-capture-sync.ts","../src/feedback/ui/use-widget-state.ts","../src/feedback/widget.tsx"],"sourcesContent":["import type { CapturedImage } from \"../types\";\n\n/** Marks every node the widget owns, so captures never include the panel. */\nexport const WIDGET_MARKER = \"data-reflet-widget\";\n\nconst MAX_PIXEL_RATIO = 2;\nconst DEFAULT_MAX_WIDTH = 2400;\nconst MAX_INLINE_BYTES = 3_000_000;\nconst TRANSPARENT_PIXEL =\n \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\nconst EXTERNAL_URL = /^(https?:)?\\/\\//i;\nconst CSS_URL = /url\\((['\"]?)([^)'\"]+)\\1\\)/g;\n\n/**\n * snapdom reloads cross-origin images with `crossOrigin=anonymous`; when that\n * reload fails to decode (cached copy without CORS headers — Convex storage\n * does this) its fallback promise never settles and the capture hangs forever.\n * Fetching the bytes ourselves and swapping in data URLs for the duration of\n * the capture starves that path: data URLs always decode.\n */\ninterface SourceSwap {\n element: Element;\n name: string;\n value: string | null;\n}\n\nfunction isExternalImageUrl(url: string): boolean {\n if (!url || url.startsWith(\"data:\") || url.startsWith(\"blob:\")) {\n return false;\n }\n if (!EXTERNAL_URL.test(url)) {\n return false;\n }\n try {\n return new URL(url, window.location.href).origin !== window.location.origin;\n } catch {\n return false;\n }\n}\n\nfunction toDataUrl(url: string): Promise<string | null> {\n return new Promise((resolve) => {\n fetch(url, { mode: \"cors\" })\n .then(async (response) => {\n if (!response.ok) {\n resolve(null);\n return;\n }\n const blob = await response.blob();\n if (blob.size === 0 || blob.size > MAX_INLINE_BYTES) {\n resolve(null);\n return;\n }\n const reader = new FileReader();\n reader.onload = () =>\n resolve(typeof reader.result === \"string\" ? reader.result : null);\n reader.onerror = () => resolve(null);\n reader.readAsDataURL(blob);\n })\n .catch(() => resolve(null));\n });\n}\n\nconst PNG_NORMALIZE_TIMEOUT = 750;\nconst CAPTURE_TIMEOUT = 10_000;\nconst ANIMATION_SETTLE_TIMEOUT = 1000;\n\n/**\n * Tiles and sections routinely animate in or reflow (grid drags, entrance\n * transitions); a capture taken mid-flight freezes them displaced. Waits for\n * animations touching the page to finish, capped so an infinite spinner can\n * never stall the report.\n */\nasync function waitForPageAnimations(): Promise<void> {\n if (typeof document.getAnimations !== \"function\") {\n return;\n }\n const start = performance.now();\n while (performance.now() - start < ANIMATION_SETTLE_TIMEOUT) {\n const running = document\n .getAnimations()\n .filter((animation) => animation.playState === \"running\");\n if (running.length === 0) {\n return;\n }\n await Promise.race([\n Promise.allSettled(running.map((animation) => animation.finished)),\n new Promise((resolve) => setTimeout(resolve, 150)),\n ]);\n }\n}\n\n/**\n * snapdom awaits `decode()` on images created with `decoding=\"sync\"` — a\n * promise Chrome 151 sometimes never settles (observed for cross-origin\n * webp, cached or inlined). Re-encoding through a canvas yields a PNG data\n * url, which decodes reliably; the load itself goes through `onload`, never\n * `decode()`.\n */\nfunction normalizeToPng(dataUrl: string): Promise<string | null> {\n return new Promise((resolve) => {\n const image = new Image();\n const timeout = setTimeout(() => resolve(dataUrl), PNG_NORMALIZE_TIMEOUT);\n image.onload = () => {\n clearTimeout(timeout);\n try {\n if (image.naturalWidth === 0 || image.naturalHeight === 0) {\n resolve(null);\n return;\n }\n const canvas = document.createElement(\"canvas\");\n canvas.width = image.naturalWidth;\n canvas.height = image.naturalHeight;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n resolve(dataUrl);\n return;\n }\n context.drawImage(image, 0, 0);\n resolve(canvas.toDataURL(\"image/png\"));\n } catch {\n resolve(null);\n }\n };\n image.onerror = () => {\n clearTimeout(timeout);\n resolve(null);\n };\n image.src = dataUrl;\n });\n}\n\nasync function toInlineUrl(url: string): Promise<string | null> {\n const dataUrl = await toDataUrl(url);\n if (!dataUrl) {\n return null;\n }\n return normalizeToPng(dataUrl);\n}\n\nfunction remember(swaps: SourceSwap[], element: Element, name: string): void {\n swaps.push({ element, name, value: element.getAttribute(name) });\n}\n\nasync function inlineImgSource(\n img: HTMLImageElement,\n swaps: SourceSwap[]\n): Promise<void> {\n const src = img.getAttribute(\"src\");\n if (!(src && isExternalImageUrl(src))) {\n return;\n }\n\n const dataUrl = await toInlineUrl(src);\n if (dataUrl) {\n if (img.hasAttribute(\"srcset\")) {\n remember(swaps, img, \"srcset\");\n img.removeAttribute(\"srcset\");\n }\n if (img.hasAttribute(\"sizes\")) {\n remember(swaps, img, \"sizes\");\n img.removeAttribute(\"sizes\");\n }\n }\n remember(swaps, img, \"src\");\n img.setAttribute(\"src\", dataUrl ?? TRANSPARENT_PIXEL);\n}\n\nasync function inlineBackgroundImages(\n element: Element,\n swaps: SourceSwap[]\n): Promise<void> {\n const style = element.getAttribute(\"style\");\n if (!style) {\n return;\n }\n const urls = [...style.matchAll(CSS_URL)].map((match) => match[2] ?? \"\");\n if (!urls.some(isExternalImageUrl)) {\n return;\n }\n\n let next = style;\n for (const url of urls) {\n if (!isExternalImageUrl(url)) {\n continue;\n }\n const dataUrl = await toInlineUrl(url);\n next = next.split(url).join(dataUrl ?? TRANSPARENT_PIXEL);\n }\n if (next !== style) {\n remember(swaps, element, \"style\");\n element.setAttribute(\"style\", next);\n }\n}\n\n/**\n * Swaps every cross-origin image under `root` for a data URL so the capture\n * cannot hit snapdom's decode-failure hang. Returns the undo list — always\n * run it, even after a failed capture.\n */\nexport async function inlineExternalImages(\n root: Element\n): Promise<SourceSwap[]> {\n const swaps: SourceSwap[] = [];\n\n for (const img of [...root.querySelectorAll(\"img\")]) {\n await inlineImgSource(img, swaps);\n }\n for (const el of [...root.querySelectorAll(\"[style*='url(']\")]) {\n await inlineBackgroundImages(el, swaps);\n }\n\n return swaps;\n}\n\nexport function restoreInlinedImages(swaps: SourceSwap[]): void {\n for (const swap of swaps) {\n if (swap.value === null) {\n swap.element.removeAttribute(swap.name);\n } else {\n swap.element.setAttribute(swap.name, swap.value);\n }\n }\n}\n\nexport interface CaptureOptions {\n /** Capture this element instead of the visible viewport. */\n element?: Element;\n excludeSelectors?: string[];\n maxWidth?: number;\n /** Hard cap for one capture attempt before falling back. Default 10s. */\n timeout?: number;\n}\n\ninterface SnapdomOptions {\n cache: \"disabled\";\n clip?: \"viewport\";\n dpr: number;\n embedFonts: boolean;\n exclude: string[];\n fast: boolean;\n filter?: (element: Element) => boolean;\n reconcile: boolean;\n}\n\nexport function buildSnapdomOptions(options: {\n devicePixelRatio?: number;\n element?: Element;\n excludeSelectors?: string[];\n filter?: (element: Element) => boolean;\n}): SnapdomOptions {\n const ratio = options.devicePixelRatio ?? 1;\n\n return {\n cache: \"disabled\",\n clip: options.element ? undefined : \"viewport\",\n dpr: Math.min(Math.max(ratio || 1, 1), MAX_PIXEL_RATIO),\n embedFonts: true,\n exclude: [`[${WIDGET_MARKER}]`, ...(options.excludeSelectors ?? [])],\n fast: true,\n filter: options.filter,\n reconcile: true,\n };\n}\n\nexport function fitWithin(\n size: { height: number; width: number },\n maxWidth: number\n): { height: number; scale: number; width: number } {\n if (size.width <= maxWidth) {\n return { height: size.height, scale: 1, width: size.width };\n }\n\n const scale = maxWidth / size.width;\n return {\n height: Math.max(1, Math.round(size.height * scale)),\n scale,\n width: maxWidth,\n };\n}\n\nfunction toBlob(canvas: HTMLCanvasElement): Promise<Blob | null> {\n return new Promise((resolve) => {\n canvas.toBlob(resolve, \"image/png\");\n });\n}\n\nfunction downscale(\n canvas: HTMLCanvasElement,\n target: { height: number; width: number }\n): HTMLCanvasElement {\n const resized = document.createElement(\"canvas\");\n resized.width = target.width;\n resized.height = target.height;\n\n const context = resized.getContext(\"2d\");\n if (!context) {\n return canvas;\n }\n\n context.imageSmoothingQuality = \"high\";\n context.drawImage(canvas, 0, 0, target.width, target.height);\n return resized;\n}\n\n/** Wraps a rendered canvas as an owned capture, downscaled to `maxWidth`. */\nexport async function capturedFromCanvas(\n source: HTMLCanvasElement,\n maxWidth: number\n): Promise<CapturedImage | null> {\n const fitted = fitWithin(\n { height: source.height, width: source.width },\n maxWidth\n );\n const output = fitted.scale === 1 ? source : downscale(source, fitted);\n\n const blob = await toBlob(output);\n if (!blob) {\n return null;\n }\n\n return {\n blob,\n height: output.height,\n mimeType: \"image/png\",\n objectUrl: URL.createObjectURL(blob),\n width: output.width,\n };\n}\n\n/**\n * Renders what the user is looking at right now.\n *\n * Runs off the DOM rather than `getDisplayMedia` on purpose: a screen-share\n * permission prompt on every report would cost more reports than it captures.\n * Returns null instead of throwing — a screenshot is never worth losing the\n * written feedback.\n */\nexport async function captureViewport(\n options: CaptureOptions = {}\n): Promise<CapturedImage | null> {\n try {\n const { snapdom } = await import(\"@zumer/snapdom\");\n const target = options.element ?? document.documentElement;\n await waitForPageAnimations();\n const swaps = await inlineExternalImages(target);\n\n const shoot = (withoutImages = false): Promise<HTMLCanvasElement> => {\n const attempt = snapdom.toCanvas(\n target,\n buildSnapdomOptions({\n devicePixelRatio: window.devicePixelRatio,\n element: options.element,\n excludeSelectors: options.excludeSelectors,\n filter: withoutImages\n ? (element) => element.tagName !== \"IMG\"\n : undefined,\n })\n );\n attempt.catch(() => undefined);\n return Promise.race([\n attempt,\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"capture timed out\")),\n options.timeout ?? CAPTURE_TIMEOUT\n )\n ),\n ]);\n };\n\n let canvas: HTMLCanvasElement;\n try {\n canvas = await shoot();\n } catch {\n canvas = await shoot(true);\n } finally {\n restoreInlinedImages(swaps);\n }\n\n return await capturedFromCanvas(\n canvas,\n options.maxWidth ?? DEFAULT_MAX_WIDTH\n );\n } catch {\n return null;\n }\n}\n\nexport function releaseCapture(image: CapturedImage | null | undefined): void {\n if (image) {\n URL.revokeObjectURL(image.objectUrl);\n }\n}\n","const FIBER_KEY_PREFIXES = [\"__reactFiber$\", \"__reactInternalInstance$\"];\nconst MEMO_TYPE = Symbol.for(\"react.memo\");\nconst FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\n\nconst MAX_STACK_DEPTH = 6;\nconst MAX_FIBER_WALK = 60;\nconst MAX_OWNER_WALK = 8;\nconst MIN_NAME_LENGTH = 4;\nconst CAPITALIZED = /^[A-Z]/;\nconst WORD_INSIDE = /[a-z]{2}/;\n\nconst ORIGIN_PREFIX = /^[a-z][\\w+.-]*:\\/\\/[^/]*/i;\nconst WEBPACK_PREFIX = /^webpack-internal:\\/{2,}(\\.\\/)?/;\nconst STACK_LOCATION = /([^\\s()]+):(\\d+):(\\d+)\\)?\\s*$/;\nconst NON_SOURCE_FRAME =\n /node_modules|\\/_next\\/|\\/chunks?\\/|\\/\\.vite\\/|\\/dist\\/|\\/build\\/|hot-update/;\nconst SOURCE_EXTENSION = /\\.(?:[cm]?[jt]sx?)$/;\nconst SOURCE_ROOT_MARKERS = [\n \"src\",\n \"app\",\n \"pages\",\n \"components\",\n \"features\",\n \"lib\",\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** React attaches the fiber under a randomly suffixed key on the host node. */\nexport function getFiberFromNode(node: Node): unknown {\n for (const key of Object.getOwnPropertyNames(node)) {\n for (const prefix of FIBER_KEY_PREFIXES) {\n if (key.startsWith(prefix)) {\n return Reflect.get(node, key) ?? null;\n }\n }\n }\n return null;\n}\n\nfunction readName(value: unknown): string | null {\n if (typeof value !== \"function\" && !isRecord(value)) {\n return null;\n }\n\n const displayName = Reflect.get(value, \"displayName\");\n if (typeof displayName === \"string\" && displayName) {\n return displayName;\n }\n\n const name = Reflect.get(value, \"name\");\n return typeof name === \"string\" && name ? name : null;\n}\n\n/**\n * Minified bundles hand out names like `Ur` or `Sn`. Reporting those as the\n * owning component actively misleads an agent, so only real words get through.\n */\nfunction isMeaningfulName(name: string): boolean {\n if (name.includes(\"/\") || name.includes(\"_\")) {\n return true;\n }\n\n return (\n name.length >= MIN_NAME_LENGTH &&\n CAPITALIZED.test(name) &&\n WORD_INSIDE.test(name)\n );\n}\n\nfunction componentName(type: unknown, depth = 0): string | null {\n if (typeof type === \"string\" || type === null || depth > 3) {\n return null;\n }\n\n if (isRecord(type)) {\n const marker = Reflect.get(type, \"$$typeof\");\n if (marker === MEMO_TYPE) {\n return componentName(Reflect.get(type, \"type\"), depth + 1);\n }\n if (marker === FORWARD_REF_TYPE) {\n return componentName(Reflect.get(type, \"render\"), depth + 1);\n }\n }\n\n const name = readName(type);\n return name && isMeaningfulName(name) ? name : null;\n}\n\n/** Component names owning the fiber, innermost first. */\nexport function resolveComponentStack(fiber: unknown): string[] {\n const stack: string[] = [];\n let current = fiber;\n let steps = 0;\n\n while (isRecord(current) && steps < MAX_FIBER_WALK) {\n const name =\n componentName(Reflect.get(current, \"type\")) ??\n componentName(Reflect.get(current, \"elementType\"));\n\n if (name && stack.at(-1) !== name) {\n stack.push(name);\n if (stack.length >= MAX_STACK_DEPTH) {\n break;\n }\n }\n\n current = Reflect.get(current, \"return\");\n steps++;\n }\n\n return stack;\n}\n\nfunction shortenSourcePath(raw: string): string {\n const path = raw\n .replace(WEBPACK_PREFIX, \"\")\n .replace(ORIGIN_PREFIX, \"\")\n .split(\"?\")[0];\n if (!path) {\n return raw;\n }\n\n for (const marker of SOURCE_ROOT_MARKERS) {\n if (path.startsWith(`${marker}/`)) {\n return path;\n }\n const index = path.lastIndexOf(`/${marker}/`);\n if (index !== -1) {\n return path.slice(index + 1);\n }\n }\n\n return path.split(\"/\").filter(Boolean).slice(-3).join(\"/\");\n}\n\nfunction formatLocation(\n fileName: string,\n line: number,\n column?: number\n): string {\n const base = `${shortenSourcePath(fileName)}:${line}`;\n return column === undefined ? base : `${base}:${column}`;\n}\n\nfunction fromDebugSource(source: unknown): string | undefined {\n if (!isRecord(source)) {\n return;\n }\n\n const fileName = Reflect.get(source, \"fileName\");\n const lineNumber = Reflect.get(source, \"lineNumber\");\n if (typeof fileName !== \"string\" || typeof lineNumber !== \"number\") {\n return;\n }\n\n const columnNumber = Reflect.get(source, \"columnNumber\");\n return formatLocation(\n fileName,\n lineNumber,\n typeof columnNumber === \"number\" ? columnNumber : undefined\n );\n}\n\nfunction fromDebugStack(stack: unknown): string | undefined {\n const raw = isRecord(stack) ? Reflect.get(stack, \"stack\") : stack;\n if (typeof raw !== \"string\") {\n return;\n }\n\n for (const line of raw.split(\"\\n\")) {\n const match = STACK_LOCATION.exec(line);\n const file = match?.[1];\n if (!(match && file) || NON_SOURCE_FRAME.test(file)) {\n continue;\n }\n\n const path = file.replace(ORIGIN_PREFIX, \"\").split(\"?\")[0] ?? \"\";\n if (!SOURCE_EXTENSION.test(path)) {\n continue;\n }\n\n return formatLocation(path, Number(match[2]), Number(match[3]));\n }\n}\n\n/**\n * `src/components/login-form.tsx:46:19` when the React build exposes it.\n * Production bundles strip debug info — callers must treat this as optional.\n */\nexport function resolveSourceLocation(fiber: unknown): string | undefined {\n let current = fiber;\n let steps = 0;\n\n while (isRecord(current) && steps < MAX_OWNER_WALK) {\n const located =\n fromDebugSource(Reflect.get(current, \"_debugSource\")) ??\n fromDebugStack(Reflect.get(current, \"_debugStack\"));\n if (located) {\n return located;\n }\n\n current = Reflect.get(current, \"_debugOwner\");\n steps++;\n }\n}\n\nexport function inspectReactElement(element: Element): {\n componentStack: string[];\n sourceLocation?: string;\n} {\n const fiber = getFiberFromNode(element);\n return {\n componentStack: resolveComponentStack(fiber),\n sourceLocation: resolveSourceLocation(fiber),\n };\n}\n","/**\n * The picked element's markup leaves the reporter's browser and ends up in an\n * agent prompt, so it is scrubbed here: typed-in values, credentials and\n * anything marked `data-reflet-redact` never make the trip.\n */\n\nconst EMAIL = /[\\w.%+-]+@[\\w.-]+\\.[a-z]{2,}/gi;\nconst LONG_TOKEN = /\\b[\\w-]{28,}\\b/g;\nconst OPAQUE_URI = /^(?:data|blob|javascript):/i;\nconst WHITESPACE_RUN = /\\s+/g;\nconst URL_QUERY = /[?#]/;\n\nconst REDACTED = \"[redacted]\";\nconst ELLIPSIS = \"…\";\nexport const REDACT_ATTRIBUTE = \"data-reflet-redact\";\n\nconst MAX_ATTRIBUTE_LENGTH = 120;\nconst MAX_TEXT_LENGTH = 200;\nconst MAX_CHILD_DEPTH = 3;\nconst MAX_CLONED_NODES = 400;\n\nconst DROPPED_TAGS = new Set([\"script\", \"style\", \"noscript\", \"template\"]);\nconst VALUE_HOLDERS = new Set([\"input\", \"textarea\", \"select\", \"option\"]);\nconst URL_ATTRIBUTES = new Set([\n \"src\",\n \"srcset\",\n \"href\",\n \"poster\",\n \"action\",\n \"formaction\",\n]);\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max - 1)}${ELLIPSIS}`;\n}\n\n/** Emails and token-shaped strings, wherever they appear in reported text. */\nexport function maskSecrets(value: string): string {\n return value.replace(EMAIL, REDACTED).replace(LONG_TOKEN, REDACTED);\n}\n\nconst SENSITIVE_PARAM =\n /token|secret|pass(?:word|wd)?|pwd|auth|jwt|credential|session|sid|key|email|ssn|otp|code|signature|nonce/i;\nconst LEADING_QUESTION_MARK = /^\\?/;\n\nfunction decoded(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\n/**\n * Query strings carry signed-in state (`?token=…`, `?userEmail=…`) straight\n * into stored reports and agent prompts. Values of anything credential- or\n * identity-shaped are masked; every other byte of the address stays intact.\n */\nexport function redactUrl(href: string): string {\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n return maskSecrets(href);\n }\n\n const pairs = url.search\n .replace(LEADING_QUESTION_MARK, \"\")\n .split(\"&\")\n .filter(Boolean);\n if (\n !pairs.some((pair) =>\n SENSITIVE_PARAM.test(decoded(pair.split(\"=\")[0] ?? \"\"))\n )\n ) {\n return href;\n }\n\n const kept = pairs.map((pair) => {\n const equals = pair.indexOf(\"=\");\n if (\n equals === -1 ||\n !SENSITIVE_PARAM.test(decoded(pair.slice(0, equals)))\n ) {\n return pair;\n }\n return `${pair.slice(0, equals)}=${REDACTED}`;\n });\n\n const query = kept.join(\"&\");\n return `${url.origin}${url.pathname}${query ? `?${query}` : \"\"}${url.hash}`;\n}\n\nfunction sanitizeUrl(value: string): string {\n if (OPAQUE_URI.test(value)) {\n return `${value.slice(0, value.indexOf(\":\"))}:${ELLIPSIS}`;\n }\n return value.split(URL_QUERY)[0] ?? value;\n}\n\nfunction sanitizeAttributes(element: Element): void {\n const holdsTypedValue = VALUE_HOLDERS.has(element.localName);\n\n for (const { name, value } of Array.from(element.attributes)) {\n if (holdsTypedValue && name === \"value\") {\n element.removeAttribute(name);\n continue;\n }\n\n const cleaned = URL_ATTRIBUTES.has(name)\n ? sanitizeUrl(value)\n : maskSecrets(value);\n element.setAttribute(name, truncate(cleaned, MAX_ATTRIBUTE_LENGTH));\n }\n}\n\nfunction collapse(element: Element): void {\n element.replaceChildren(element.ownerDocument.createTextNode(ELLIPSIS));\n}\n\nfunction sanitizeTree(element: Element, depth: number): void {\n sanitizeAttributes(element);\n\n if (element.hasAttribute(REDACT_ATTRIBUTE)) {\n element.replaceChildren(element.ownerDocument.createTextNode(REDACTED));\n return;\n }\n\n if (element.localName === \"svg\") {\n element.replaceChildren();\n return;\n }\n\n for (const child of Array.from(element.childNodes)) {\n if (child.nodeType === Node.COMMENT_NODE) {\n child.remove();\n continue;\n }\n\n if (child.nodeType === Node.TEXT_NODE) {\n child.textContent = truncate(\n maskSecrets(child.textContent ?? \"\"),\n MAX_TEXT_LENGTH\n );\n continue;\n }\n\n if (!(child instanceof Element)) {\n continue;\n }\n\n if (DROPPED_TAGS.has(child.localName)) {\n child.remove();\n continue;\n }\n\n if (depth >= MAX_CHILD_DEPTH) {\n sanitizeAttributes(child);\n collapse(child);\n continue;\n }\n\n sanitizeTree(child, depth + 1);\n }\n}\n\n/** Redacted `outerHTML`, shallow-cloned when the subtree is too large to be useful. */\nexport function sanitizeMarkup(element: Element, maxLength: number): string {\n const isSmallEnough =\n element.querySelectorAll(\"*\").length <= MAX_CLONED_NODES;\n const clone = element.cloneNode(isSmallEnough);\n if (!(clone instanceof Element)) {\n return \"\";\n }\n\n sanitizeTree(clone, 0);\n if (!isSmallEnough) {\n collapse(clone);\n }\n\n return truncate(clone.outerHTML.replace(WHITESPACE_RUN, \" \"), maxLength);\n}\n","import type { ElementRect, ElementSelection } from \"../../types\";\nimport { inspectReactElement } from \"./react-source\";\nimport { maskSecrets, sanitizeMarkup } from \"./redact\";\n\nconst SAFE_ID = /^[A-Za-z][\\w-]*$/;\nconst WHITESPACE = /\\s+/g;\nconst MAX_LABEL_LENGTH = 80;\nconst MAX_HTML_LENGTH = 600;\nconst MAX_TEXT_LENGTH = 300;\nconst MAX_REGION_LENGTH = 160;\nconst MAX_HANDLE_VALUE_LENGTH = 80;\nconst MAX_DEPTH = 12;\nconst MIN_PATH_SEGMENTS = 2;\n// Hard caps enforced by POST /api/v1/feedback/create — over them the whole\n// report is rejected, so clip here rather than lose the submission.\nconst MAX_SELECTOR_LENGTH = 600;\nconst MAX_SOURCE_LOCATION_LENGTH = 400;\n\nconst TEST_ATTRIBUTES = [\n \"data-testid\",\n \"data-test-id\",\n \"data-test\",\n \"data-cy\",\n \"data-qa\",\n];\nconst NAMING_ATTRIBUTES = [\"name\", \"aria-label\"];\n\nconst LANDMARK_SELECTOR =\n 'dialog, [role=\"dialog\"], [role=\"alertdialog\"], main, nav, aside, header, footer, form, section, article';\nconst HEADING_SELECTOR = 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]';\n\n/** Elements that start a new visual block — their text gets separated by a space. */\nconst BLOCK_TAGS = new Set([\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"dd\",\n \"details\",\n \"div\",\n \"dl\",\n \"dt\",\n \"fieldset\",\n \"figcaption\",\n \"figure\",\n \"footer\",\n \"form\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"header\",\n \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"ol\",\n \"p\",\n \"pre\",\n \"section\",\n \"summary\",\n \"table\",\n \"td\",\n \"th\",\n \"tr\",\n \"ul\",\n]);\n\nfunction visibleText(element: Element): string {\n const clone = element.cloneNode(true);\n if (!(clone instanceof Element)) {\n return \"\";\n }\n\n for (const node of clone.querySelectorAll(\"*\")) {\n if (BLOCK_TAGS.has(node.localName)) {\n node.before(clone.ownerDocument.createTextNode(\" \"));\n }\n }\n\n return collapseText(maskSecrets(clone.textContent ?? \"\"));\n}\n\nfunction isUnique(selector: string): boolean {\n try {\n return document.querySelectorAll(selector).length === 1;\n } catch {\n return false;\n }\n}\n\nfunction escapeAttributeValue(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n\nfunction attributeHandle(\n element: Element,\n attribute: string,\n qualifier: string\n): string | null {\n const value = element.getAttribute(attribute);\n if (!value || value.length > MAX_HANDLE_VALUE_LENGTH) {\n return null;\n }\n\n const selector = `${qualifier}[${attribute}=\"${escapeAttributeValue(value)}\"]`;\n return isUnique(selector) ? selector : null;\n}\n\n/** Something an engineer would have written on purpose, unlike a positional path. */\nfunction uniqueHandle(element: Element): string | null {\n const id = element.getAttribute(\"id\");\n if (id && SAFE_ID.test(id) && isUnique(`#${id}`)) {\n return `#${id}`;\n }\n\n for (const attribute of TEST_ATTRIBUTES) {\n const handle = attributeHandle(element, attribute, \"\");\n if (handle) {\n return handle;\n }\n }\n\n for (const attribute of NAMING_ATTRIBUTES) {\n const handle = attributeHandle(element, attribute, element.localName);\n if (handle) {\n return handle;\n }\n }\n\n return null;\n}\n\nfunction positionalSegment(element: Element): string {\n const tag = element.localName;\n const parent = element.parentElement;\n if (!parent) {\n return tag;\n }\n\n const sameTag = Array.from(parent.children).filter(\n (child) => child.localName === tag\n );\n if (sameTag.length <= 1) {\n return tag;\n }\n\n return `${tag}:nth-of-type(${sameTag.indexOf(element) + 1})`;\n}\n\n/**\n * Shortest selector that still resolves back to `element` from the document.\n * Grows the path one ancestor at a time and stops as soon as it is unique, so\n * a stable handle anywhere up the tree replaces the whole positional chain.\n * A bare tag is never enough: positional paths keep a parent for context.\n */\nexport function buildSelector(element: Element): string {\n if (element === document.documentElement) {\n return \"html\";\n }\n if (element === document.body) {\n return \"body\";\n }\n\n const handle = uniqueHandle(element);\n if (handle) {\n return handle;\n }\n\n const segments: string[] = [];\n let current: Element | null = element;\n\n for (let depth = 0; current && depth < MAX_DEPTH; depth++) {\n const ancestorHandle = current === element ? null : uniqueHandle(current);\n segments.unshift(ancestorHandle ?? positionalSegment(current));\n\n const candidate = segments.join(\" > \");\n const isAnchored = segments.length >= MIN_PATH_SEGMENTS;\n if (\n ancestorHandle ||\n current === document.body ||\n (isAnchored && isUnique(candidate))\n ) {\n return candidate;\n }\n\n current = current.parentElement;\n }\n\n return segments.join(\" > \");\n}\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max - 1)}…`;\n}\n\nfunction collapseText(value: string): string {\n return value.replace(WHITESPACE, \" \").trim();\n}\n\nfunction accessibleLabel(element: Element): string {\n const explicit =\n element.getAttribute(\"aria-label\") ??\n element.getAttribute(\"title\") ??\n element.getAttribute(\"alt\") ??\n element.getAttribute(\"placeholder\");\n if (explicit?.trim()) {\n return explicit.trim();\n }\n\n return collapseText(element.textContent ?? \"\");\n}\n\n/** Short human label such as `button \"Sign in\"` or `div.card`. */\nexport function describeElement(element: Element): string {\n const tag = element.localName;\n const label = maskSecrets(accessibleLabel(element));\n if (label) {\n return truncate(`${tag} \"${label}\"`, MAX_LABEL_LENGTH);\n }\n\n const firstClass = element.classList.item(0);\n return truncate(firstClass ? `${tag}.${firstClass}` : tag, MAX_LABEL_LENGTH);\n}\n\nfunction describeLandmark(element: Element): string | null {\n const landmark = element.parentElement?.closest(LANDMARK_SELECTOR);\n if (!landmark) {\n return null;\n }\n\n const name =\n landmark.getAttribute(\"aria-label\") ?? landmark.getAttribute(\"title\");\n return name?.trim()\n ? `${landmark.localName} \"${collapseText(name)}\"`\n : landmark.localName;\n}\n\nfunction headingAbove(element: Element): string | null {\n const scope = element.closest(LANDMARK_SELECTOR) ?? document.body;\n const probe = document.createRange();\n probe.selectNodeContents(element);\n probe.collapse(true);\n\n let closest: Element | null = null;\n for (const heading of scope.querySelectorAll(HEADING_SELECTOR)) {\n if (probe.comparePoint(heading, 0) < 0) {\n closest = heading;\n }\n }\n\n const text = collapseText(closest?.textContent ?? \"\");\n return text || null;\n}\n\n/**\n * Where the element sits from a reader's point of view — `dialog \"Members\" ›\n * Danger zone` says more to an agent than any DOM path can.\n */\nexport function describeRegion(element: Element): string | undefined {\n const landmark = describeLandmark(element);\n const heading = headingAbove(element);\n const parts = [landmark];\n\n if (heading && !landmark?.includes(`\"${heading}\"`)) {\n parts.push(heading);\n }\n\n const region = parts.filter((part) => part !== null).join(\" › \");\n return region ? truncate(maskSecrets(region), MAX_REGION_LENGTH) : undefined;\n}\n\nexport function getElementRect(element: Element): ElementRect {\n const rect = element.getBoundingClientRect();\n return {\n height: Math.round(rect.height),\n width: Math.round(rect.width),\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n };\n}\n\n/** Everything an agent needs to find the picked element back in the codebase. */\nexport function buildElementSelection(element: Element): ElementSelection {\n const { componentStack, sourceLocation } = inspectReactElement(element);\n const text = truncate(visibleText(element), MAX_TEXT_LENGTH);\n\n return {\n componentStack,\n html: sanitizeMarkup(element, MAX_HTML_LENGTH),\n label: describeElement(element),\n rect: getElementRect(element),\n region: describeRegion(element),\n selector: truncate(buildSelector(element), MAX_SELECTOR_LENGTH),\n sourceLocation: sourceLocation\n ? truncate(sourceLocation, MAX_SOURCE_LOCATION_LENGTH)\n : sourceLocation,\n text: text || undefined,\n };\n}\n","import type { FeedbackContext } from \"../../types\";\nimport { redactUrl } from \"./redact\";\n\ninterface AgentInfo {\n browser?: string;\n device: \"desktop\" | \"mobile\" | \"tablet\";\n os?: string;\n}\n\nconst BROWSER_PATTERNS: [string, RegExp][] = [\n [\"Edge\", /Edg(?:e|A|iOS)?\\/([\\d.]+)/],\n [\"Opera\", /OPR\\/([\\d.]+)/],\n [\"Samsung Internet\", /SamsungBrowser\\/([\\d.]+)/],\n [\"Firefox\", /(?:Firefox|FxiOS)\\/([\\d.]+)/],\n [\"Chrome\", /(?:Chrome|CriOS)\\/([\\d.]+)/],\n [\"Safari\", /Version\\/([\\d.]+).*Safari/],\n];\n\nconst OS_PATTERNS: [string, RegExp][] = [\n [\"iOS\", /iPhone|iPad|iPod/],\n [\"Android\", /Android/],\n [\"Windows\", /Windows NT/],\n [\"macOS\", /Mac OS X|Macintosh/],\n [\"ChromeOS\", /CrOS/],\n [\"Linux\", /Linux|X11/],\n];\n\nconst MOBILE_HINT = /Mobile|iPhone|iPod/;\nconst TABLET_HINT = /iPad|Tablet/;\nconst TRAILING_ZERO = /\\.0$/;\nconst ANDROID = /Android/;\n\nfunction shortenVersion(version: string): string {\n return version.split(\".\").slice(0, 2).join(\".\").replace(TRAILING_ZERO, \"\");\n}\n\nfunction detectDevice(userAgent: string): AgentInfo[\"device\"] {\n if (TABLET_HINT.test(userAgent)) {\n return \"tablet\";\n }\n if (MOBILE_HINT.test(userAgent)) {\n return \"mobile\";\n }\n return ANDROID.test(userAgent) ? \"tablet\" : \"desktop\";\n}\n\nexport function parseUserAgent(userAgent: string): AgentInfo {\n const info: AgentInfo = { device: detectDevice(userAgent) };\n\n for (const [name, pattern] of BROWSER_PATTERNS) {\n const version = pattern.exec(userAgent)?.[1];\n if (version) {\n info.browser = `${name} ${shortenVersion(version)}`;\n break;\n }\n }\n\n for (const [name, pattern] of OS_PATTERNS) {\n if (pattern.test(userAgent)) {\n info.os = name;\n break;\n }\n }\n\n return info;\n}\n\n// Hard caps enforced by POST /api/v1/feedback/create — over them the whole\n// report is rejected, so clip here rather than lose the submission.\nconst MAX_PAGE_TITLE_LENGTH = 300;\nconst MAX_URL_LENGTH = 2000;\nconst MAX_USER_AGENT_LENGTH = 600;\n\nfunction clip(value: string, max: number): string {\n return value.length <= max ? value : value.slice(0, max);\n}\n\nfunction optionalText(\n value: string | undefined,\n max: number\n): string | undefined {\n return value?.trim() ? clip(value, max) : undefined;\n}\n\nfunction resolveTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // Intl missing in some embedded webviews\n }\n}\n\n/** Everything about the page that a bug report needs and the DOM already knows. */\nexport function collectPageContext(options?: {\n sdkVersion?: string;\n}): FeedbackContext {\n const userAgent = navigator.userAgent;\n const agent = parseUserAgent(userAgent);\n\n return {\n browser: agent.browser,\n device: agent.device,\n language: navigator.language,\n os: agent.os,\n pageTitle: optionalText(document.title, MAX_PAGE_TITLE_LENGTH),\n referrer: optionalText(document.referrer, MAX_URL_LENGTH),\n screen: { height: window.screen.height, width: window.screen.width },\n scroll: { x: window.scrollX, y: window.scrollY },\n sdkVersion: options?.sdkVersion,\n timezone: resolveTimezone(),\n url: redactUrl(window.location.href),\n userAgent: clip(userAgent, MAX_USER_AGENT_LENGTH),\n viewport: {\n devicePixelRatio: window.devicePixelRatio,\n height: window.innerHeight,\n width: window.innerWidth,\n },\n };\n}\n","import type { FeedbackContext, RefletUser } from \"../types\";\n\nexport const SDK_VERSION = \"0.3.4\";\nexport const DEFAULT_WIDGET_OFFSET = 20;\n\nconst FEEDBACK_WIDGET_CATEGORIES = [\"bug\", \"idea\", \"question\"] as const;\n\nexport type FeedbackWidgetCategory =\n (typeof FEEDBACK_WIDGET_CATEGORIES)[number];\n\nconst ANNOTATION_TOOLS = [\n \"pen\",\n \"arrow\",\n \"rectangle\",\n \"text\",\n \"spotlight\",\n \"highlight\",\n \"blur\",\n] as const;\n\nexport type AnnotationTool = (typeof ANNOTATION_TOOLS)[number];\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface Annotation {\n color: string;\n end: Point;\n id: string;\n /** Freehand path, in image pixels. Only set for the pen tool. */\n points?: Point[];\n start: Point;\n text?: string;\n tool: AnnotationTool;\n}\n\nexport interface CapturedImage {\n blob: Blob;\n height: number;\n mimeType: string;\n /** Object URL owned by the caller — revoke it when the capture is dropped. */\n objectUrl: string;\n width: number;\n}\n\nexport interface ScreenshotDraft {\n annotations: Annotation[];\n context: FeedbackContext;\n id: string;\n image: CapturedImage;\n source: \"automatic\" | \"manual\";\n}\n\nexport interface FeedbackWidgetLabels {\n annotateHint: string;\n attachmentUploadFailed: string;\n attachScreenshot: string;\n back: string;\n cancel: string;\n captureFailed: string;\n capturing: string;\n categoryBug: string;\n categoryIdea: string;\n categoryLabel: string;\n categoryQuestion: string;\n clearAnnotations: string;\n clearSelection: string;\n descriptionPlaceholder: string;\n dismissForDays: string;\n done: string;\n emailInvalid: string;\n emailLabel: string;\n emailPlaceholder: string;\n errorGeneric: string;\n errorTitleRequired: string;\n minimize: string;\n moreOptions: string;\n moveFeedback: string;\n pickElement: string;\n pickElementHint: string;\n recapture: string;\n removeScreenshot: string;\n resume: string;\n retakeHint: string;\n retryAttachments: string;\n screenshot: string;\n submit: string;\n successMessage: string;\n successTitle: string;\n title: string;\n titlePlaceholder: string;\n trigger: string;\n undo: string;\n}\n\nexport const DEFAULT_WIDGET_LABELS: FeedbackWidgetLabels = {\n annotateHint: \"Draw on the screenshot to point at the problem.\",\n attachmentUploadFailed:\n \"Your feedback was saved, but some screenshots are still pending. Retry to attach them.\",\n attachScreenshot: \"Attach a screenshot\",\n back: \"Back\",\n cancel: \"Cancel\",\n captureFailed: \"Screenshot unavailable. Try again or send without it.\",\n capturing: \"Taking screenshot…\",\n categoryBug: \"Bug\",\n categoryIdea: \"Idea\",\n categoryLabel: \"Feedback type\",\n categoryQuestion: \"Question\",\n clearAnnotations: \"Clear drawing\",\n clearSelection: \"Remove selected element\",\n descriptionPlaceholder: \"What would you like to share?\",\n dismissForDays: \"Hide for {days} days\",\n done: \"Done\",\n emailInvalid: \"Enter a valid email address.\",\n emailLabel: \"Email\",\n emailPlaceholder: \"you@company.com\",\n errorGeneric: \"Something went wrong. Please try again.\",\n errorTitleRequired: \"Tell us a bit about it first.\",\n minimize: \"Minimize feedback\",\n moreOptions: \"More options\",\n moveFeedback: \"Move feedback\",\n pickElement: \"Point at an element\",\n pickElementHint: \"Click the element you are talking about — cancel with\",\n recapture: \"Retake\",\n removeScreenshot: \"Remove\",\n resume: \"Resume feedback\",\n retakeHint: \"Screenshot of this page\",\n retryAttachments: \"Retry attachments\",\n screenshot: \"Screenshot\",\n submit: \"Send feedback\",\n successMessage: \"We read every report. Thanks for taking the time.\",\n successTitle: \"Feedback sent\",\n title: \"Send feedback\",\n titlePlaceholder: \"Short summary\",\n trigger: \"Feedback\",\n undo: \"Undo\",\n};\n\nexport interface RefletFeedbackProps {\n /** API base URL override. Falls back to the RefletProvider value. */\n baseUrl?: string;\n /** Record console errors and warnings to attach to bug reports. */\n captureConsole?: boolean;\n /** Take a screenshot of the viewport as soon as the panel opens. */\n captureOnOpen?: boolean;\n categories?: FeedbackWidgetCategory[];\n defaultCategory?: FeedbackWidgetCategory;\n /** Let reporters hide the launcher for this many days. */\n dismissForDays?: number;\n /** Render nothing when false — lets an app gate the widget per user. */\n enabled?: boolean;\n /** Keyboard shortcut opening the panel. Set to null to disable. */\n hotkey?: string | null;\n labels?: Partial<FeedbackWidgetLabels>;\n /** Extra fields merged into the reported context. */\n metadata?: Record<string, string>;\n /** Distance in px from the viewport edges. */\n offset?: number;\n onClose?: () => void;\n onDismiss?: (result: { until: number }) => void;\n onOpen?: () => void;\n onSubmit?: (result: { feedbackId: string }) => void;\n position?: \"bottom-left\" | \"bottom-right\" | \"top-left\" | \"top-right\";\n primaryColor?: string;\n publicKey?: string;\n theme?: \"auto\" | \"dark\" | \"light\";\n user?: RefletUser;\n userToken?: string;\n}\n\nexport type WidgetStep = \"annotate\" | \"compose\" | \"picking\" | \"success\";\n","import type { ElementRect, ScreenshotAnnotation } from \"../../types\";\nimport type { Annotation, AnnotationTool, Point } from \"../types\";\n\nconst BOX_TOOLS: AnnotationTool[] = [\n \"text\",\n \"rectangle\",\n \"spotlight\",\n \"highlight\",\n \"blur\",\n];\nconst MIN_GESTURE_LENGTH = 8;\nconst ARROW_HEAD_ANGLE = Math.PI / 7;\nconst DEFAULT_PATH_TOLERANCE = 2.5;\n\nexport function normalizeRect(start: Point, end: Point): ElementRect {\n return {\n height: Math.abs(end.y - start.y),\n width: Math.abs(end.x - start.x),\n x: Math.min(start.x, end.x),\n y: Math.min(start.y, end.y),\n };\n}\n\n/** The two barbs closing the arrow tip, both `size` px away from `end`. */\nexport function arrowHead(\n start: Point,\n end: Point,\n size: number\n): [Point, Point] {\n const angle = Math.atan2(end.y - start.y, end.x - start.x);\n if (Math.hypot(end.x - start.x, end.y - start.y) === 0) {\n return [end, end];\n }\n\n const barb = (offset: number): Point => ({\n x: end.x - size * Math.cos(angle + offset),\n y: end.y - size * Math.sin(angle + offset),\n });\n\n return [barb(-ARROW_HEAD_ANGLE), barb(ARROW_HEAD_ANGLE)];\n}\n\n/** Drops points a user cannot perceive, keeping the payload small. */\nexport function simplifyPath(\n points: Point[],\n tolerance = DEFAULT_PATH_TOLERANCE\n): Point[] {\n if (points.length < 3) {\n return points;\n }\n\n const [first, ...rest] = points;\n if (!first) {\n return points;\n }\n\n const kept: Point[] = [first];\n let anchor = first;\n\n for (const point of rest.slice(0, -1)) {\n if (Math.hypot(point.x - anchor.x, point.y - anchor.y) >= tolerance) {\n kept.push(point);\n anchor = point;\n }\n }\n\n const last = points.at(-1);\n if (last) {\n kept.push(last);\n }\n\n return kept;\n}\n\nexport function isDegenerate(annotation: Annotation): boolean {\n if (annotation.tool === \"text\") {\n return !annotation.text?.trim();\n }\n if (annotation.tool === \"pen\") {\n return (annotation.points?.length ?? 0) < 2;\n }\n\n const { start, end } = annotation;\n return Math.hypot(end.x - start.x, end.y - start.y) < MIN_GESTURE_LENGTH;\n}\n\nfunction toWire(annotation: Annotation): ScreenshotAnnotation {\n const { color, start, end, tool } = annotation;\n\n if (tool === \"pen\") {\n return {\n color,\n points: simplifyPath(annotation.points ?? []),\n type: tool,\n x: start.x,\n y: start.y,\n };\n }\n\n if (BOX_TOOLS.includes(tool)) {\n const rect = normalizeRect(start, end);\n return {\n color,\n height: rect.height,\n ...(tool === \"text\" ? { text: annotation.text } : {}),\n type: tool,\n width: rect.width,\n x: rect.x,\n y: rect.y,\n };\n }\n\n return {\n color,\n endX: end.x,\n endY: end.y,\n type: tool,\n x: start.x,\n y: start.y,\n };\n}\n\n/** Serializes to the shape the Reflet API stores next to the screenshot. */\nexport function toWireAnnotations(\n annotations: Annotation[]\n): ScreenshotAnnotation[] {\n return annotations.filter((item) => !isDegenerate(item)).map(toWire);\n}\n","export interface AnnotationColor {\n baseColor: string;\n strengthPercent: number;\n}\n\nexport const DEFAULT_ANNOTATION_COLOR: AnnotationColor = {\n baseColor: \"#ef4444\",\n strengthPercent: 100,\n};\n\nexport function annotationColorHex({\n baseColor,\n strengthPercent,\n}: AnnotationColor): string {\n const channels = [1, 3, 5].map((offset) => {\n const channel = Number.parseInt(baseColor.slice(offset, offset + 2), 16);\n return Math.round(255 + ((channel - 255) * strengthPercent) / 100)\n .toString(16)\n .padStart(2, \"0\");\n });\n return `#${channels.join(\"\")}`;\n}\n","import type { ReactNode } from \"react\";\n\nfunction Svg({\n children,\n className,\n size = 16,\n}: {\n children: ReactNode;\n className?: string;\n size?: number;\n}) {\n return (\n <svg\n aria-hidden=\"true\"\n className={className}\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.8\"\n viewBox=\"0 0 24 24\"\n width={size}\n >\n {children}\n </svg>\n );\n}\n\nexport function ChatIcon({ className }: { className?: string }) {\n return (\n <Svg className={className} size={15}>\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </Svg>\n );\n}\n\nexport function CloseIcon({ className }: { className?: string }) {\n return (\n <Svg className={className}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Svg>\n );\n}\n\nexport function CameraIcon() {\n return (\n <Svg>\n <path d=\"M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2l1.2-2h8.2l1.2 2h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z\" />\n <circle cx=\"12\" cy=\"13\" r=\"3.2\" />\n </Svg>\n );\n}\n\nexport function PencilIcon() {\n return (\n <Svg>\n <path d=\"M16.5 4.5a2.1 2.1 0 0 1 3 3L8 19l-4 1 1-4z\" />\n </Svg>\n );\n}\n\nexport function TargetIcon() {\n return (\n <Svg>\n <path d=\"M12 3v3M12 18v3M3 12h3M18 12h3\" />\n <circle cx=\"12\" cy=\"12\" r=\"5\" />\n </Svg>\n );\n}\n\nexport function TrashIcon() {\n return (\n <Svg>\n <path d=\"M4 7h16M9 7V5h6v2M6 7l1 13h10l1-13M10 11v5M14 11v5\" />\n </Svg>\n );\n}\n\nexport function ArrowIcon() {\n return (\n <Svg>\n <path d=\"M5 19 19 5M11 5h8v8\" />\n </Svg>\n );\n}\n\nexport function UndoIcon() {\n return (\n <Svg>\n <path d=\"M4 9h11a5 5 0 0 1 0 10h-5M4 9l4-4M4 9l4 4\" />\n </Svg>\n );\n}\n\nexport function CheckIcon({ size = 28 }: { size?: number }) {\n return (\n <svg\n aria-hidden=\"true\"\n fill=\"none\"\n height={size}\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2.4\"\n viewBox=\"0 0 24 24\"\n width={size}\n >\n <path d=\"m5 13 4 4L19 7\" />\n </svg>\n );\n}\n\nexport function GripIcon() {\n return (\n <Svg>\n <path d=\"M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01\" />\n </Svg>\n );\n}\nexport function MinusIcon() {\n return (\n <Svg>\n <path d=\"M5 12h14\" />\n </Svg>\n );\n}\nexport function MoreIcon() {\n return (\n <Svg>\n <path d=\"M5 12h.01M12 12h.01M19 12h.01\" />\n </Svg>\n );\n}\n\nexport function ChevronDownIcon() {\n return (\n <Svg>\n <path d=\"m7 10 5 5 5-5\" />\n </Svg>\n );\n}\n\nexport function SquareIcon() {\n return (\n <Svg>\n <rect height=\"14\" rx=\"2\" width=\"14\" x=\"5\" y=\"5\" />\n </Svg>\n );\n}\nexport function TextIcon() {\n return (\n <Svg>\n <path d=\"M5 6V4h14v2M12 4v16M8 20h8\" />\n </Svg>\n );\n}\nexport function SpotlightIcon() {\n return (\n <Svg>\n <path d=\"M8 4H4v4M16 4h4v4M4 16v4h4M20 16v4h-4\" />\n <rect height=\"8\" rx=\"1\" width=\"8\" x=\"8\" y=\"8\" />\n </Svg>\n );\n}\nexport function HighlightIcon() {\n return (\n <Svg>\n <path d=\"M4 19h16M8 15l8-11 4 3-8 11-4-3ZM7 15l-2 3\" />\n </Svg>\n );\n}\nexport function BlurIcon() {\n return (\n <Svg>\n <rect height=\"14\" rx=\"2\" width=\"14\" x=\"5\" y=\"5\" />\n <path d=\"M8 8h8v8H8z\" />\n </Svg>\n );\n}\n","import { useEffect, useId, useRef, useState } from \"react\";\nimport type { Annotation, Point } from \"../../../types\";\nimport { CheckIcon, CloseIcon } from \"../../icons\";\n\nexport interface TextDraft {\n annotation: Annotation;\n fontSize: number;\n position: Point;\n}\n\nexport function TextAnnotationEditor({\n draft,\n onCommit,\n onCancel,\n}: {\n draft: TextDraft;\n onCommit: (text: string) => void;\n onCancel: () => void;\n}) {\n const [text, setText] = useState(draft.annotation.text ?? \"\");\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const id = useId().replaceAll(\":\", \"\");\n useEffect(() => {\n inputRef.current?.focus();\n }, []);\n return (\n <form\n className=\"glass text-annotation-editor\"\n id={id}\n onSubmit={(event) => {\n event.preventDefault();\n onCommit(text);\n }}\n >\n <style>{`[id=\"${id}\"] { left: clamp(12px, ${draft.position.x}px, calc(100vw - 252px)); top: clamp(12px, ${draft.position.y}px, calc(100dvh - 148px)); }`}</style>\n <textarea\n aria-label=\"Text annotation\"\n maxLength={280}\n onBlur={(event) => {\n if (!event.currentTarget.form?.contains(event.relatedTarget)) {\n onCommit(text);\n }\n }}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n onCancel();\n }\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n onCommit(text);\n }\n }}\n placeholder=\"Type a note…\"\n ref={inputRef}\n rows={2}\n value={text}\n />\n <div className=\"text-annotation-actions\">\n <button\n aria-label=\"Cancel text\"\n className=\"tool\"\n onClick={onCancel}\n type=\"button\"\n >\n <CloseIcon />\n </button>\n <button aria-label=\"Apply text\" className=\"done-btn\" type=\"submit\">\n <CheckIcon size={16} />\n </button>\n </div>\n </form>\n );\n}\n","import { useState } from \"react\";\nimport { normalizeRect } from \"../../../core/annotations\";\nimport type { Annotation, Point } from \"../../../types\";\nimport type { TextDraft } from \"./text-editor\";\n\nfunction containsPoint(annotation: Annotation, point: Point) {\n const bounds = normalizeRect(annotation.start, annotation.end);\n return (\n point.x >= bounds.x &&\n point.x <= bounds.x + bounds.width &&\n point.y >= bounds.y &&\n point.y <= bounds.y + bounds.height\n );\n}\n\nexport function useTextAnnotation(options: {\n annotations: Annotation[];\n color: string;\n onChange: (annotations: Annotation[]) => void;\n}) {\n const [textDraft, setTextDraft] = useState<TextDraft | null>(null);\n\n const beginText = (canvas: HTMLCanvasElement, point: Point) => {\n const bounds = canvas.getBoundingClientRect();\n const existing = [...options.annotations]\n .reverse()\n .find((item) => item.tool === \"text\" && containsPoint(item, point));\n const annotation =\n existing ??\n ({\n color: options.color,\n end: point,\n id: crypto.randomUUID(),\n start: point,\n tool: \"text\",\n } satisfies Annotation);\n const fontSize = existing\n ? (existing.end.y - existing.start.y) /\n (existing.text?.split(\"\\n\").length ?? 1) /\n 1.4\n : (18 * canvas.width) / bounds.width;\n setTextDraft({\n annotation,\n fontSize,\n position: {\n x: bounds.x + (annotation.start.x / canvas.width) * bounds.width,\n y: bounds.y + (annotation.start.y / canvas.height) * bounds.height,\n },\n });\n };\n\n const commitText = (canvas: HTMLCanvasElement, text: string) => {\n const context = canvas.getContext(\"2d\");\n if (!(textDraft && context)) {\n return;\n }\n const value = text.trim();\n const remaining = options.annotations.filter(\n ({ id }) => id !== textDraft.annotation.id\n );\n if (value) {\n context.font = `${textDraft.fontSize}px ui-sans-serif, system-ui, sans-serif`;\n const lines = value.split(\"\\n\");\n remaining.push({\n ...textDraft.annotation,\n end: {\n x:\n textDraft.annotation.start.x +\n Math.max(...lines.map((line) => context.measureText(line).width)),\n y:\n textDraft.annotation.start.y +\n lines.length * textDraft.fontSize * 1.4,\n },\n text: value,\n });\n }\n options.onChange(remaining);\n setTextDraft(null);\n };\n\n return {\n beginText,\n cancelText: () => setTextDraft(null),\n commitText,\n textDraft,\n };\n}\n","import { type MouseEvent, useEffect, useRef, useState } from \"react\";\n\nexport function useDetailsPopover() {\n const [open, setOpen] = useState(false);\n const [placement, setPlacement] = useState(\"above\");\n const [anchorLeft, setAnchorLeft] = useState(0);\n const detailsRef = useRef<HTMLDetailsElement>(null);\n const summaryRef = useRef<HTMLElement>(null);\n\n useEffect(() => {\n const reposition = () => {\n const bounds = summaryRef.current?.getBoundingClientRect();\n if (bounds && detailsRef.current?.open) {\n setAnchorLeft(bounds.left);\n setPlacement(\n bounds.bottom < window.innerHeight / 2 ? \"below\" : \"above\"\n );\n }\n };\n const dismissOutside = (event: globalThis.PointerEvent) => {\n const details = detailsRef.current;\n if (details?.open && !event.composedPath().includes(details)) {\n setOpen(false);\n }\n };\n const dismissWithEscape = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || !detailsRef.current?.open) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n setOpen(false);\n summaryRef.current?.focus();\n };\n document.addEventListener(\"pointerdown\", dismissOutside);\n document.addEventListener(\"keydown\", dismissWithEscape, true);\n window.addEventListener(\"resize\", reposition);\n return () => {\n document.removeEventListener(\"pointerdown\", dismissOutside);\n document.removeEventListener(\"keydown\", dismissWithEscape, true);\n window.removeEventListener(\"resize\", reposition);\n };\n }, []);\n\n const show = () => {\n const bounds = summaryRef.current?.getBoundingClientRect();\n if (bounds) {\n setAnchorLeft(bounds.left);\n setPlacement(bounds.bottom < window.innerHeight / 2 ? \"below\" : \"above\");\n }\n setOpen(true);\n };\n return {\n anchorLeft,\n detailsProps: { \"data-placement\": placement, open, ref: detailsRef },\n hide: () => {\n setOpen(false);\n summaryRef.current?.focus();\n },\n show,\n summaryProps: {\n onClick: (event: MouseEvent<HTMLElement>) => {\n event.preventDefault();\n if (open) {\n setOpen(false);\n } else {\n show();\n }\n },\n ref: summaryRef,\n },\n };\n}\n","import { Slider } from \"@base-ui/react/slider\";\nimport { useId, useRef } from \"react\";\nimport { useDetailsPopover } from \"../floating/use-details-popover\";\nimport { type AnnotationColor, annotationColorHex } from \"./color-value\";\n\ninterface ColorPickerProps {\n onChange: (color: AnnotationColor) => void;\n selection: AnnotationColor;\n}\n\nfunction ColorSpectrum({ selection, onChange }: ColorPickerProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n return (\n <div className=\"color-spectrum\">\n <button\n aria-label=\"Custom color\"\n onClick={() => inputRef.current?.click()}\n title=\"Custom color\"\n type=\"button\"\n />\n <input\n aria-hidden=\"true\"\n onChange={(event) =>\n onChange({ baseColor: event.target.value, strengthPercent: 100 })\n }\n ref={inputRef}\n tabIndex={-1}\n type=\"color\"\n value={selection.baseColor}\n />\n </div>\n );\n}\n\nfunction ColorControls({ selection, onChange }: ColorPickerProps) {\n return (\n <div className=\"color-popover glass\">\n <Slider.Root\n className=\"color-slider\"\n onValueChange={(strengthPercent) =>\n onChange({ ...selection, strengthPercent })\n }\n value={selection.strengthPercent}\n >\n <Slider.Control className=\"color-slider-control\">\n <Slider.Track className=\"color-slider-track\">\n <Slider.Thumb\n aria-label=\"Color strength\"\n className=\"color-slider-thumb\"\n getAriaValueText={(_, value) => `${value}% color`}\n />\n </Slider.Track>\n </Slider.Control>\n </Slider.Root>\n <ColorSpectrum onChange={onChange} selection={selection} />\n </div>\n );\n}\n\nexport function ColorPicker({ selection, onChange }: ColorPickerProps) {\n const popover = useDetailsPopover();\n const id = useId().replaceAll(\":\", \"\");\n return (\n <details className=\"color-picker\" id={id} {...popover.detailsProps}>\n <style>{`[id=\"${id}\"] { --rf-color-anchor: ${popover.anchorLeft}px; --annotation-color: ${annotationColorHex(selection)}; --annotation-base-color: ${selection.baseColor}; }`}</style>\n <summary\n aria-label=\"Annotation color\"\n className=\"tool\"\n {...popover.summaryProps}\n title=\"Annotation color\"\n >\n <span className=\"color-preview\" />\n </summary>\n <ColorControls onChange={onChange} selection={selection} />\n </details>\n );\n}\n","import type { AnnotationTool, FeedbackWidgetLabels } from \"../../types\";\nimport { useDetailsPopover } from \"../floating/use-details-popover\";\nimport {\n BlurIcon,\n CameraIcon,\n ChevronDownIcon,\n HighlightIcon,\n PencilIcon,\n SpotlightIcon,\n TrashIcon,\n} from \"../icons\";\nimport type { AnnotationEditor } from \"./toolbar\";\n\nconst EXTRA_TOOLS = [\n { Icon: SpotlightIcon, id: \"spotlight\", label: \"Spotlight\" },\n { Icon: PencilIcon, id: \"pen\", label: \"Draw\" },\n { Icon: HighlightIcon, id: \"highlight\", label: \"Highlight\" },\n { Icon: BlurIcon, id: \"blur\", label: \"Hide\" },\n] as const;\n\nexport function DrawingToolMenu({\n drawing,\n editor,\n labels,\n}: {\n drawing: { tool: AnnotationTool; setTool: (tool: AnnotationTool) => void };\n editor: AnnotationEditor;\n labels: FeedbackWidgetLabels;\n}) {\n const popover = useDetailsPopover();\n return (\n <details className=\"drawing-menu\" {...popover.detailsProps}>\n <summary\n aria-label=\"More drawing tools\"\n className=\"tool\"\n data-selected={EXTRA_TOOLS.some(({ id }) => id === drawing.tool)}\n title=\"More drawing tools\"\n {...popover.summaryProps}\n >\n <ChevronDownIcon />\n </summary>\n <div className=\"drawing-popover glass\">\n {EXTRA_TOOLS.map(({ id, label, Icon }) => (\n <button\n aria-pressed={drawing.tool === id}\n className=\"drawing-option\"\n key={id}\n onClick={() => {\n drawing.setTool(id);\n popover.hide();\n }}\n type=\"button\"\n >\n <Icon />\n {label}\n </button>\n ))}\n <div className=\"drawing-divider\" />\n <button\n className=\"drawing-option\"\n disabled={editor.annotations.length === 0}\n onClick={() => {\n editor.onChange([]);\n popover.hide();\n }}\n type=\"button\"\n >\n <TrashIcon />\n {labels.clearAnnotations}\n </button>\n {editor.onRetake && (\n <button\n className=\"drawing-option\"\n onClick={editor.onRetake}\n type=\"button\"\n >\n <CameraIcon />\n {labels.recapture}\n </button>\n )}\n </div>\n </details>\n );\n}\n","import type {\n Annotation,\n AnnotationTool,\n FeedbackWidgetLabels,\n} from \"../../types\";\nimport { ArrowIcon, CheckIcon, SquareIcon, TextIcon, UndoIcon } from \"../icons\";\nimport { ColorPicker } from \"./color-picker\";\nimport type { AnnotationColor } from \"./color-value\";\nimport { DrawingToolMenu } from \"./tool-menu\";\n\nconst QUICK_TOOLS = [\n { Icon: SquareIcon, id: \"rectangle\", label: \"Rectangle\" },\n { Icon: ArrowIcon, id: \"arrow\", label: \"Arrow\" },\n { Icon: TextIcon, id: \"text\", label: \"Text\" },\n] as const;\n\nexport interface AnnotationEditor {\n annotations: Annotation[];\n onChange: (annotations: Annotation[]) => void;\n onDone: () => void;\n onRetake?: () => void;\n}\n\nexport function AnnotationToolbar({\n editor,\n labels,\n drawing,\n}: {\n editor: AnnotationEditor;\n labels: FeedbackWidgetLabels;\n drawing: {\n color: AnnotationColor;\n setColor: (color: AnnotationColor) => void;\n tool: AnnotationTool;\n setTool: (tool: AnnotationTool) => void;\n };\n}) {\n return (\n <div className=\"toolbar\">\n <div className=\"group glass\">\n {QUICK_TOOLS.map(({ id, label, Icon }) => (\n <button\n aria-label={label}\n aria-pressed={drawing.tool === id}\n className=\"tool\"\n key={id}\n onClick={() => drawing.setTool(id)}\n title={label}\n type=\"button\"\n >\n <Icon />\n </button>\n ))}\n <DrawingToolMenu drawing={drawing} editor={editor} labels={labels} />\n </div>\n <div className=\"group glass\">\n <ColorPicker onChange={drawing.setColor} selection={drawing.color} />\n <button\n aria-label={labels.undo}\n className=\"tool\"\n disabled={editor.annotations.length === 0}\n onClick={() => editor.onChange(editor.annotations.slice(0, -1))}\n title={labels.undo}\n type=\"button\"\n >\n <UndoIcon />\n </button>\n <button\n aria-label={labels.done}\n className=\"done-btn\"\n onClick={editor.onDone}\n title={labels.done}\n type=\"button\"\n >\n <CheckIcon size={18} />\n </button>\n </div>\n </div>\n );\n}\n","import type { ElementRect } from \"../../types\";\nimport type { Annotation, CapturedImage, Point } from \"../types\";\nimport { arrowHead, isDegenerate, normalizeRect } from \"./annotations\";\nimport { capturedFromCanvas } from \"./capture\";\n\nconst STROKE_WIDTH = 3;\nconst ARROW_HEAD_SIZE = 16;\nconst HIGHLIGHT_ALPHA = 0.3;\nconst REDACTION_FILL = \"#111827\";\nconst PIXEL_BLOCK = 10;\n\n/**\n * The slice of `CanvasRenderingContext2D` the annotation layer needs.\n * Narrowing it keeps the drawing code testable without a canvas polyfill.\n */\nexport interface AnnotationCanvasContext {\n beginPath: () => void;\n canvas: { height: number; width: number };\n closePath: () => void;\n drawImage: (\n image: CanvasImageSource,\n dx: number,\n dy: number,\n dw: number,\n dh: number\n ) => void;\n fill: () => void;\n fillRect: (x: number, y: number, width: number, height: number) => void;\n fillStyle: string | CanvasGradient | CanvasPattern;\n fillText: (text: string, x: number, y: number) => void;\n font: string;\n globalAlpha: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n lineTo: (x: number, y: number) => void;\n lineWidth: number;\n moveTo: (x: number, y: number) => void;\n restore: () => void;\n save: () => void;\n stroke: () => void;\n strokeRect: (x: number, y: number, width: number, height: number) => void;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n textBaseline: CanvasTextBaseline;\n}\n\nfunction scalePoint(point: Point, scale: number): Point {\n return { x: point.x * scale, y: point.y * scale };\n}\n\nfunction scaleRect(rect: ElementRect, scale: number): ElementRect {\n return {\n height: rect.height * scale,\n width: rect.width * scale,\n x: rect.x * scale,\n y: rect.y * scale,\n };\n}\n\nfunction isCanvasElement(value: unknown): value is HTMLCanvasElement {\n return (\n typeof HTMLCanvasElement !== \"undefined\" &&\n value instanceof HTMLCanvasElement\n );\n}\n\n/**\n * Downsamples the region and paints it back enlarged, so redacted pixels are\n * unrecoverable. Falls back to an opaque block wherever 2d canvases are absent.\n */\nfunction redact(context: AnnotationCanvasContext, rect: ElementRect): void {\n const source = context.canvas;\n const width = Math.max(1, Math.round(rect.width / PIXEL_BLOCK));\n const height = Math.max(1, Math.round(rect.height / PIXEL_BLOCK));\n\n if (isCanvasElement(source)) {\n const offscreen = document.createElement(\"canvas\");\n offscreen.width = width;\n offscreen.height = height;\n const offscreenContext = offscreen.getContext(\"2d\");\n\n if (offscreenContext) {\n offscreenContext.imageSmoothingEnabled = true;\n offscreenContext.drawImage(\n source,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n 0,\n 0,\n width,\n height\n );\n context.drawImage(offscreen, rect.x, rect.y, rect.width, rect.height);\n return;\n }\n }\n\n context.fillStyle = REDACTION_FILL;\n context.fillRect(rect.x, rect.y, rect.width, rect.height);\n}\n\nfunction drawArrow(\n context: AnnotationCanvasContext,\n start: Point,\n end: Point,\n scale: number\n): void {\n context.beginPath();\n context.moveTo(start.x, start.y);\n context.lineTo(end.x, end.y);\n context.stroke();\n\n const [left, right] = arrowHead(start, end, ARROW_HEAD_SIZE * scale);\n context.beginPath();\n context.moveTo(end.x, end.y);\n context.lineTo(left.x, left.y);\n context.lineTo(right.x, right.y);\n context.closePath();\n context.fill();\n}\n\nfunction drawPen(\n context: AnnotationCanvasContext,\n points: Point[],\n scale: number\n): void {\n const [first, ...rest] = points;\n if (!first) {\n return;\n }\n\n const head = scalePoint(first, scale);\n context.beginPath();\n context.moveTo(head.x, head.y);\n for (const point of rest) {\n const scaled = scalePoint(point, scale);\n context.lineTo(scaled.x, scaled.y);\n }\n context.stroke();\n}\n\nfunction drawSpotlight(\n context: AnnotationCanvasContext,\n rect: ElementRect\n): void {\n const { width, height } = context.canvas;\n context.save();\n context.fillStyle = REDACTION_FILL;\n context.globalAlpha = 0.55;\n context.fillRect(0, 0, width, rect.y);\n context.fillRect(\n 0,\n rect.y + rect.height,\n width,\n height - rect.y - rect.height\n );\n context.fillRect(0, rect.y, rect.x, rect.height);\n context.fillRect(\n rect.x + rect.width,\n rect.y,\n width - rect.x - rect.width,\n rect.height\n );\n context.restore();\n context.strokeRect(rect.x, rect.y, rect.width, rect.height);\n}\n\nfunction drawAnnotation(\n context: AnnotationCanvasContext,\n annotation: Annotation,\n scale: number\n): void {\n const { color, tool } = annotation;\n const rect = scaleRect(\n normalizeRect(annotation.start, annotation.end),\n scale\n );\n\n context.save();\n context.lineWidth = STROKE_WIDTH * scale;\n context.lineCap = \"round\";\n context.lineJoin = \"round\";\n context.strokeStyle = color;\n context.fillStyle = color;\n\n switch (tool) {\n case \"text\": {\n const lines = (annotation.text ?? \"\").split(\"\\n\");\n const lineHeight = rect.height / lines.length;\n context.font = `${lineHeight / 1.4}px ui-sans-serif, system-ui, sans-serif`;\n context.textBaseline = \"top\";\n for (const [index, line] of lines.entries()) {\n context.fillText(line, rect.x, rect.y + index * lineHeight);\n }\n break;\n }\n case \"pen\":\n drawPen(context, annotation.points ?? [], scale);\n break;\n case \"arrow\":\n drawArrow(\n context,\n scalePoint(annotation.start, scale),\n scalePoint(annotation.end, scale),\n scale\n );\n break;\n case \"spotlight\":\n drawSpotlight(context, rect);\n break;\n case \"rectangle\":\n context.strokeRect(rect.x, rect.y, rect.width, rect.height);\n break;\n case \"highlight\":\n context.globalAlpha = HIGHLIGHT_ALPHA;\n context.fillRect(rect.x, rect.y, rect.width, rect.height);\n break;\n default:\n redact(context, rect);\n break;\n }\n\n context.restore();\n}\n\nexport function drawAnnotations(\n context: AnnotationCanvasContext,\n annotations: Annotation[],\n options?: { scale?: number }\n): void {\n const scale = options?.scale ?? 1;\n for (const annotation of annotations) {\n if (!isDegenerate(annotation)) {\n drawAnnotation(context, annotation, scale);\n }\n }\n}\n\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(\"Screenshot could not be decoded\"));\n image.src = url;\n });\n}\n\n/**\n * Burns the annotations into a copy of the capture so reviewers and agents see\n * the drawing without needing to replay the vector data.\n */\nexport async function renderAnnotatedImage(\n source: CapturedImage,\n annotations: Annotation[]\n): Promise<CapturedImage | null> {\n if (annotations.length === 0) {\n return null;\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = source.width;\n canvas.height = source.height;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n return null;\n }\n\n const image = await loadImage(source.objectUrl);\n context.drawImage(image, 0, 0, source.width, source.height);\n drawAnnotations(context, annotations);\n\n return await capturedFromCanvas(canvas, source.width);\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { drawAnnotations } from \"../../core/annotation-renderer\";\nimport type { Annotation, CapturedImage } from \"../../types\";\n\nexport function useAnnotationCanvas(\n capture: CapturedImage,\n annotations: Annotation[]\n) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [bitmap, setBitmap] = useState<HTMLImageElement | null>(null);\n const [failedUrl, setFailedUrl] = useState<string | null>(null);\n\n useEffect(() => {\n const image = new Image();\n image.onload = () => setBitmap(image);\n image.onerror = () => setFailedUrl(capture.objectUrl);\n image.src = capture.objectUrl;\n return () => {\n image.onload = null;\n image.onerror = null;\n };\n }, [capture.objectUrl]);\n\n const isDecoded = bitmap?.src === capture.objectUrl;\n useEffect(() => {\n const canvas = canvasRef.current;\n const context = canvas?.getContext(\"2d\");\n if (!(canvas && context && bitmap && isDecoded)) {\n return;\n }\n context.clearRect(0, 0, canvas.width, canvas.height);\n context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n drawAnnotations(context, annotations);\n }, [annotations, bitmap, isDecoded]);\n\n return { canvasRef, hasError: failedUrl === capture.objectUrl, isDecoded };\n}\n","import { useLayoutEffect, useRef, useState } from \"react\";\n\nfunction prefersReducedMotion() {\n return window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\nfunction thumbnailFrame(frame: HTMLElement, trigger: HTMLElement) {\n const destination = frame.getBoundingClientRect();\n const thumbnail = trigger.getBoundingClientRect();\n const scale = Math.max(\n thumbnail.width / destination.width,\n thumbnail.height / destination.height\n );\n const insetX = (destination.width - thumbnail.width / scale) / 2;\n const insetBottom = destination.height - thumbnail.height / scale;\n const radius =\n Number.parseFloat(getComputedStyle(trigger).borderRadius) / scale;\n return {\n clipPath: `inset(0px ${insetX}px ${insetBottom}px ${insetX}px round ${radius}px)`,\n transform: `translate(${thumbnail.x - destination.x - insetX * scale}px, ${thumbnail.y - destination.y}px) scale(${scale})`,\n };\n}\n\nfunction expandedFrame(visual: HTMLElement) {\n return {\n clipPath: `inset(0px 0px 0px 0px round ${getComputedStyle(visual).borderRadius})`,\n transform: \"none\",\n };\n}\n\nconst TIMING = { duration: 340, easing: \"cubic-bezier(0.22, 1, 0.36, 1)\" };\n\nexport function useImageMorph(\n trigger: HTMLElement | null | undefined,\n onDone: () => void\n) {\n const frameRef = useRef<HTMLDivElement>(null);\n const visualRef = useRef<HTMLDivElement>(null);\n const entrance = useRef<Animation | null>(null);\n const exit = useRef<Animation | null>(null);\n const [isOpening, setIsOpening] = useState(false);\n const [isClosing, setIsClosing] = useState(false);\n\n useLayoutEffect(() => {\n const frame = frameRef.current;\n const visual = visualRef.current;\n if (frame && visual?.animate && trigger && !prefersReducedMotion()) {\n setIsOpening(true);\n entrance.current = visual.animate(\n [thumbnailFrame(frame, trigger), expandedFrame(visual)],\n TIMING\n );\n entrance.current.finished.then(\n () => setIsOpening(false),\n () => undefined\n );\n }\n return () => {\n entrance.current?.cancel();\n exit.current?.cancel();\n };\n }, [trigger]);\n\n const close = (action = onDone) => {\n if (exit.current) {\n return;\n }\n const frame = frameRef.current;\n const visual = visualRef.current;\n if (!(frame && visual?.animate && trigger) || prefersReducedMotion()) {\n action();\n return;\n }\n const current =\n entrance.current?.playState === \"running\"\n ? {\n clipPath: getComputedStyle(visual).clipPath,\n transform: getComputedStyle(visual).transform,\n }\n : expandedFrame(visual);\n entrance.current?.cancel();\n setIsClosing(true);\n const animation = visual.animate(\n [current, thumbnailFrame(frame, trigger)],\n { ...TIMING, duration: 260, fill: \"forwards\" }\n );\n exit.current = animation;\n animation.finished.then(action, () => undefined);\n };\n\n return { close, frameRef, isClosing, isOpening, visualRef };\n}\n","import {\n type PointerEvent as ReactPointerEvent,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { isDegenerate } from \"../core/annotations\";\nimport type {\n Annotation,\n AnnotationTool,\n CapturedImage,\n FeedbackWidgetLabels,\n Point,\n} from \"../types\";\nimport {\n annotationColorHex,\n DEFAULT_ANNOTATION_COLOR,\n} from \"./annotation/color-value\";\nimport { TextAnnotationEditor } from \"./annotation/text/text-editor\";\nimport { useTextAnnotation } from \"./annotation/text/use-text-annotation\";\nimport { type AnnotationEditor, AnnotationToolbar } from \"./annotation/toolbar\";\nimport { useAnnotationCanvas } from \"./annotation/use-annotation-canvas\";\nimport { useImageMorph } from \"./annotation/use-image-morph\";\n\nfunction toImagePoint(\n canvas: HTMLCanvasElement,\n clientX: number,\n clientY: number\n): Point {\n const bounds = canvas.getBoundingClientRect();\n return {\n x: Math.max(\n 0,\n Math.min(\n canvas.width,\n ((clientX - bounds.left) / bounds.width) * canvas.width\n )\n ),\n y: Math.max(\n 0,\n Math.min(\n canvas.height,\n ((clientY - bounds.top) / bounds.height) * canvas.height\n )\n ),\n };\n}\n\nexport function Annotator({\n capture,\n labels,\n editor,\n}: {\n capture: CapturedImage;\n labels: FeedbackWidgetLabels;\n editor: AnnotationEditor & { trigger?: HTMLElement | null };\n}) {\n const { annotations, onChange, onDone, onRetake } = editor;\n const morph = useImageMorph(editor.trigger, onDone);\n const dialogRef = useRef<HTMLDialogElement>(null);\n const [tool, setTool] = useState<AnnotationTool>(\"rectangle\");\n const [colorSelection, setColorSelection] = useState(\n DEFAULT_ANNOTATION_COLOR\n );\n const color = annotationColorHex(colorSelection);\n const [draft, setDraft] = useState<Annotation | null>(null);\n const { canvasRef, hasError, isDecoded } = useAnnotationCanvas(\n capture,\n draft ? [...annotations, draft] : annotations\n );\n const text = useTextAnnotation({ annotations, color, onChange });\n useEffect(() => {\n const dialog = dialogRef.current;\n dialog?.showModal();\n return () => dialog?.close();\n }, []);\n\n const onPointerDown = (event: ReactPointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!(canvas && isDecoded) || event.button !== 0) {\n return;\n }\n\n const point = toImagePoint(canvas, event.clientX, event.clientY);\n if (tool === \"text\") {\n event.preventDefault();\n text.beginText(canvas, point);\n return;\n }\n canvas.setPointerCapture(event.pointerId);\n\n setDraft({\n color,\n end: point,\n id: crypto.randomUUID(),\n points: tool === \"pen\" ? [point] : undefined,\n start: point,\n tool,\n });\n };\n\n const onPointerMove = (event: ReactPointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!(canvas && draft)) {\n return;\n }\n\n const point = toImagePoint(canvas, event.clientX, event.clientY);\n setDraft(\n draft.tool === \"pen\"\n ? { ...draft, end: point, points: [...(draft.points ?? []), point] }\n : { ...draft, end: point }\n );\n };\n\n const onPointerUp = () => {\n if (!draft) {\n return;\n }\n if (!isDegenerate(draft)) {\n onChange([...annotations, draft]);\n }\n setDraft(null);\n };\n\n return (\n <dialog\n aria-label={labels.annotateHint}\n className=\"overlay\"\n data-closing={morph.isClosing}\n data-opening={morph.isOpening}\n onCancel={(event) => {\n event.preventDefault();\n morph.close();\n }}\n ref={dialogRef}\n >\n {hasError && (\n <p className=\"error\" role=\"alert\">\n {labels.captureFailed}\n </p>\n )}\n <style>{`.editor-image { --rf-capture-ratio: ${capture.width / capture.height}; }`}</style>\n <div className=\"editor\">\n <div className=\"editor-image\" ref={morph.frameRef}>\n <div className=\"editor-visual\" ref={morph.visualRef}>\n <img\n alt=\"\"\n height={capture.height}\n src={capture.objectUrl}\n width={capture.width}\n />\n <canvas\n data-tool={tool}\n height={capture.height}\n onPointerCancel={() => setDraft(null)}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n ref={canvasRef}\n width={capture.width}\n />\n </div>\n </div>\n </div>\n\n {text.textDraft && (\n <TextAnnotationEditor\n draft={text.textDraft}\n key={text.textDraft.annotation.id}\n onCancel={text.cancelText}\n onCommit={(value) => {\n if (canvasRef.current) {\n text.commitText(canvasRef.current, value);\n }\n }}\n />\n )}\n <AnnotationToolbar\n drawing={{\n color: colorSelection,\n setColor: setColorSelection,\n setTool,\n tool,\n }}\n editor={{\n annotations,\n onChange,\n onDone: () => morph.close(),\n onRetake: onRetake ? () => morph.close(onRetake) : undefined,\n }}\n labels={labels}\n />\n </dialog>\n );\n}\n","import type { Ref } from \"react\";\nimport { ChatIcon, CloseIcon } from \"./icons\";\n\nexport function Launcher({\n isOpen,\n label,\n onClick,\n buttonRef,\n}: {\n isOpen: boolean;\n label: string;\n onClick: () => void;\n buttonRef?: Ref<HTMLButtonElement>;\n}) {\n return (\n <button\n aria-expanded={isOpen}\n className=\"launcher glass\"\n data-open={isOpen}\n onClick={onClick}\n ref={buttonRef}\n type=\"button\"\n >\n <span className=\"launcher-icon\">\n <ChatIcon className=\"on-open\" />\n <CloseIcon className=\"on-close\" />\n </span>\n {label}\n </button>\n );\n}\n","import type { Annotation, CapturedImage } from \"../../types\";\nimport { useAnnotationCanvas } from \"./use-annotation-canvas\";\n\nexport function ScreenshotPreview({\n annotations,\n capture,\n}: {\n annotations: Annotation[];\n capture: CapturedImage;\n}) {\n const { canvasRef } = useAnnotationCanvas(capture, annotations);\n return (\n <>\n <img\n alt=\"\"\n draggable={false}\n height={capture.height}\n src={capture.objectUrl}\n width={capture.width}\n />\n {annotations.length > 0 && (\n <canvas height={capture.height} ref={canvasRef} width={capture.width} />\n )}\n </>\n );\n}\n","import type { FeedbackWidgetLabels, ScreenshotDraft } from \"../../types\";\nimport { ScreenshotPreview } from \"../annotation/screenshot-preview\";\nimport { CameraIcon, PencilIcon, TrashIcon } from \"../icons\";\nimport type { WidgetState } from \"../use-widget-state\";\n\nexport function ScreenshotCard({\n item,\n labels,\n state,\n}: {\n item: { draft: ScreenshotDraft; number: number; multiple: boolean };\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const { draft, number, multiple } = item;\n const isCapturing = state.pendingCapture?.id === draft.id;\n const disabled = state.isEditingDisabled || state.isCapturing;\n return (\n <fieldset\n aria-label={`${labels.screenshot} ${number}`}\n className=\"screenshot-attachment glass\"\n >\n <button\n aria-label={labels.annotateHint}\n className=\"screenshot-preview\"\n disabled={disabled}\n onClick={(event) =>\n state.annotateScreenshot(draft.id, event.currentTarget)\n }\n type=\"button\"\n >\n <ScreenshotPreview\n annotations={draft.annotations}\n capture={draft.image}\n />\n <span className=\"attachment-caption glass\">\n <PencilIcon />\n <span className=\"attachment-caption-label\">{labels.screenshot}</span>\n {multiple && <span>{number}</span>}\n {draft.annotations.length > 0 && (\n <span className=\"annotation-count\">{draft.annotations.length}</span>\n )}\n </span>\n </button>\n {isCapturing ? (\n <div className=\"capture-progress glass\" role=\"status\">\n <span className=\"spinner\" />\n {labels.capturing}\n </div>\n ) : (\n <div className=\"attachment-actions glass\">\n <button\n aria-label={labels.recapture}\n className=\"icon-btn\"\n disabled={disabled}\n onClick={() => state.retakeCapture(draft.id)}\n title={labels.recapture}\n type=\"button\"\n >\n <CameraIcon />\n </button>\n <button\n aria-label={labels.removeScreenshot}\n className=\"icon-btn\"\n disabled={disabled}\n onClick={() => state.removeCapture(draft.id)}\n title={labels.removeScreenshot}\n type=\"button\"\n >\n <TrashIcon />\n </button>\n </div>\n )}\n </fieldset>\n );\n}\n","import { ScrollArea } from \"@base-ui/react/scroll-area\";\nimport { useEffect, useRef } from \"react\";\nimport type { FeedbackWidgetLabels } from \"../../types\";\nimport { CameraIcon, CloseIcon, TargetIcon } from \"../icons\";\nimport type { WidgetState } from \"../use-widget-state\";\nimport { ScreenshotCard } from \"./screenshot-card\";\n\nfunction SelectedElement({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n if (!state.selection) {\n return null;\n }\n const component = state.selection.componentStack[0];\n return (\n <div className=\"selection-chip glass\">\n <button\n aria-label={labels.pickElement}\n className=\"selection-label\"\n disabled={state.isEditingDisabled || state.isCapturing}\n onClick={() => state.setStep(\"picking\")}\n title={state.selection.sourceLocation ?? state.selection.selector}\n type=\"button\"\n >\n {state.elementCapture ? (\n <img\n alt=\"\"\n height={32}\n src={state.elementCapture.objectUrl}\n width={32}\n />\n ) : (\n <TargetIcon />\n )}\n <span className=\"truncate\">\n {component ? `<${component}>` : state.selection.label}\n </span>\n </button>\n <button\n aria-label={labels.clearSelection}\n className=\"icon-btn\"\n disabled={state.isEditingDisabled || state.isCapturing}\n onClick={state.clearSelection}\n type=\"button\"\n >\n <CloseIcon />\n </button>\n </div>\n );\n}\n\nexport function Attachments({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const stripRef = useRef<HTMLDivElement>(null);\n const count = state.screenshots.length;\n useEffect(() => {\n const strip = stripRef.current;\n if (strip && count > 0) {\n strip.scrollTo?.({ left: strip.scrollWidth });\n }\n }, [count]);\n const isAdding =\n state.pendingCapture &&\n !state.screenshots.some(({ id }) => id === state.pendingCapture?.id);\n return (\n <div className=\"attachments\">\n <SelectedElement labels={labels} state={state} />\n <ScrollArea.Root className=\"screenshot-scroll-area\">\n <ScrollArea.Viewport\n aria-label={labels.screenshot}\n className=\"screenshot-strip\"\n ref={stripRef}\n role=\"region\"\n >\n <ScrollArea.Content className=\"screenshot-strip-content\">\n {state.screenshots.map((draft, index) => (\n <ScreenshotCard\n item={{ draft, multiple: count > 1, number: index + 1 }}\n key={draft.id}\n labels={labels}\n state={state}\n />\n ))}\n {isAdding && (\n <div\n aria-label={labels.capturing}\n className=\"attachment-skeleton glass\"\n role=\"status\"\n >\n <CameraIcon />\n <span>{labels.capturing}</span>\n </div>\n )}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar\n className=\"screenshot-scrollbar\"\n orientation=\"horizontal\"\n >\n <ScrollArea.Thumb className=\"screenshot-scroll-thumb\" />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { FeedbackWidgetLabels } from \"../../types\";\nimport { SDK_VERSION } from \"../../types\";\nimport { useDetailsPopover } from \"../floating/use-details-popover\";\nimport { CloseIcon, MoreIcon } from \"../icons\";\nimport type { WidgetState } from \"../use-widget-state\";\n\nexport function ComposerOptions({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const popover = useDetailsPopover();\n const [emailInvalid, setEmailInvalid] = useState(false);\n return (\n <details className=\"composer-options\" {...popover.detailsProps}>\n <summary\n aria-label={labels.moreOptions}\n className=\"icon-btn\"\n {...popover.summaryProps}\n title={labels.moreOptions}\n >\n <MoreIcon />\n </summary>\n <div className=\"options-popover glass\">\n {state.isAnonymous && (\n <label className=\"email-field\">\n {labels.emailLabel}\n <input\n aria-invalid={emailInvalid}\n aria-label={labels.emailLabel}\n autoComplete=\"email\"\n disabled={state.isEditingDisabled}\n onChange={(event) => {\n setEmailInvalid(false);\n state.setEmail(event.target.value);\n }}\n onInvalid={(event) => {\n event.preventDefault();\n setEmailInvalid(true);\n popover.show();\n const input = event.currentTarget;\n requestAnimationFrame(() => input.focus());\n }}\n placeholder={labels.emailPlaceholder}\n type=\"email\"\n value={state.email}\n />\n {emailInvalid && <span role=\"alert\">{labels.emailInvalid}</span>}\n </label>\n )}\n <button\n className=\"ghost-btn\"\n disabled={state.isSubmitting}\n onClick={state.close}\n type=\"button\"\n >\n <CloseIcon />\n {labels.cancel}\n </button>\n {state.canDismiss && (\n <button\n className=\"dismiss-btn\"\n disabled={state.isSubmitting}\n onClick={state.dismiss}\n type=\"button\"\n >\n {labels.dismissForDays.replace(\n \"{days}\",\n String(state.dismissForDays)\n )}\n </button>\n )}\n <a\n className=\"version-info\"\n href=\"https://reflet.app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n Reflet SDK {SDK_VERSION}\n </a>\n </div>\n </details>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { FeedbackWidgetCategory, FeedbackWidgetLabels } from \"../../types\";\nimport { CameraIcon, ChevronDownIcon, TargetIcon } from \"../icons\";\nimport type { WidgetState } from \"../use-widget-state\";\nimport { ComposerOptions } from \"./options\";\n\nconst CATEGORY_LABELS = {\n bug: \"categoryBug\",\n idea: \"categoryIdea\",\n question: \"categoryQuestion\",\n} as const;\n\nexport interface ComposerControlOptions {\n categories: FeedbackWidgetCategory[];\n floatingControls: ReactNode;\n}\n\nexport function ComposerControls({\n options,\n labels,\n state,\n}: {\n options: ComposerControlOptions;\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n return (\n <div className=\"composer-toolbar\">\n {options.floatingControls}\n <div className=\"composer-controls glass\">\n {options.categories.length > 1 && (\n <span className=\"select-control\">\n <select\n aria-label={labels.categoryLabel}\n className=\"category-select\"\n disabled={state.isEditingDisabled}\n onChange={(event) => {\n const category = options.categories.find(\n (value) => value === event.target.value\n );\n if (category) {\n state.setCategory(category);\n }\n }}\n value={state.category}\n >\n {options.categories.map((value) => (\n <option key={value} value={value}>\n {labels[CATEGORY_LABELS[value]]}\n </option>\n ))}\n </select>\n <ChevronDownIcon />\n </span>\n )}\n <button\n aria-label={labels.attachScreenshot}\n className=\"icon-btn\"\n disabled={state.isCapturing || state.isEditingDisabled}\n onClick={state.takeCapture}\n title={labels.attachScreenshot}\n type=\"button\"\n >\n <CameraIcon />\n </button>\n <button\n aria-label={labels.pickElement}\n className=\"icon-btn\"\n disabled={state.isEditingDisabled || state.isCapturing}\n onClick={() => state.setStep(\"picking\")}\n title={labels.pickElement}\n type=\"button\"\n >\n <TargetIcon />\n </button>\n <ComposerOptions labels={labels} state={state} />\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport type { FeedbackWidgetLabels } from \"../../types\";\nimport { ArrowIcon } from \"../icons\";\nimport type { WidgetState } from \"../use-widget-state\";\n\nexport function MessageInput({\n labels,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const [expanded, setExpanded] = useState(false);\n const submitLabel = state.hasPendingAttachments\n ? labels.retryAttachments\n : labels.submit;\n return (\n <div className=\"message-row glass\" data-expanded={expanded}>\n <textarea\n aria-label={labels.descriptionPlaceholder}\n disabled={state.isEditingDisabled}\n maxLength={4000}\n onChange={(event) => state.setMessage(event.target.value)}\n onFocus={() => setExpanded(true)}\n placeholder={labels.descriptionPlaceholder}\n rows={expanded ? 3 : 1}\n value={state.message}\n />\n <button\n aria-busy={state.isSubmitting}\n aria-label={submitLabel}\n className=\"submit\"\n disabled={\n state.isSubmitting || state.isCapturing || !state.message.trim()\n }\n title={submitLabel}\n type=\"submit\"\n >\n {state.isSubmitting ? <span className=\"spinner\" /> : <ArrowIcon />}\n </button>\n </div>\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport type { FeedbackWidgetLabels } from \"../types\";\nimport { Attachments } from \"./composer/attachments\";\nimport {\n type ComposerControlOptions,\n ComposerControls,\n} from \"./composer/controls\";\nimport { MessageInput } from \"./composer/message-input\";\nimport { CheckIcon } from \"./icons\";\nimport type { WidgetState } from \"./use-widget-state\";\n\nexport function FeedbackPanel({\n options,\n labels,\n state,\n}: {\n options: ComposerControlOptions;\n labels: FeedbackWidgetLabels;\n state: WidgetState;\n}) {\n const panelRef = useRef<HTMLElement>(null);\n useEffect(() => {\n panelRef.current?.focus();\n }, []);\n\n if (state.step === \"success\") {\n return (\n <section aria-live=\"polite\" className=\"panel\">\n <div className=\"done success-panel glass\">\n <CheckIcon />\n <h2>{labels.successTitle}</h2>\n <p>{labels.successMessage}</p>\n </div>\n <div className=\"composer-toolbar\">{options.floatingControls}</div>\n </section>\n );\n }\n\n return (\n <section\n aria-label={labels.title}\n className=\"panel\"\n ref={panelRef}\n tabIndex={-1}\n >\n <Attachments labels={labels} state={state} />\n <form\n className=\"composer\"\n onSubmit={(event) => {\n event.preventDefault();\n state.submit();\n }}\n >\n <MessageInput labels={labels} state={state} />\n <ComposerControls labels={labels} options={options} state={state} />\n <div aria-hidden=\"true\" className=\"hp\">\n <input\n autoComplete=\"off\"\n name=\"company-website\"\n onChange={(event) => state.setHoneypot(event.target.value)}\n tabIndex={-1}\n value={state.honeypot}\n />\n </div>\n {state.error && (\n <p className=\"error glass\" role=\"alert\">\n {state.error}\n </p>\n )}\n </form>\n </section>\n );\n}\n","import {\n type KeyboardEvent,\n type PointerEvent,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { Point, RefletFeedbackProps } from \"../../types\";\n\nconst EDGE_GAP = 12;\nconst KEYBOARD_STEP = 24;\nconst KEY_DIRECTIONS: Record<string, Point> = {\n ArrowDown: { x: 0, y: KEYBOARD_STEP },\n ArrowLeft: { x: -KEYBOARD_STEP, y: 0 },\n ArrowRight: { x: KEYBOARD_STEP, y: 0 },\n ArrowUp: { x: 0, y: -KEYBOARD_STEP },\n};\n\nfunction visibleViewport() {\n const viewport = window.visualViewport;\n const left = viewport?.offsetLeft ?? 0;\n const top = viewport?.offsetTop ?? 0;\n const width = viewport?.width ?? window.innerWidth;\n const height = viewport?.height ?? window.innerHeight;\n return {\n bottom: window.innerHeight - top - height,\n height,\n left,\n right: window.innerWidth - left - width,\n top,\n width,\n };\n}\n\nfunction clampPosition(\n point: Point,\n bounds: DOMRect,\n viewport = visibleViewport()\n): Point {\n return {\n x: Math.max(\n viewport.left + EDGE_GAP,\n Math.min(\n point.x,\n viewport.left + viewport.width - bounds.width - EDGE_GAP\n )\n ),\n y: Math.max(\n viewport.top + EDGE_GAP,\n Math.min(\n point.y,\n viewport.top + viewport.height - bounds.height - EDGE_GAP\n )\n ),\n };\n}\n\nexport function useFloatingPosition(\n corner: RefletFeedbackProps[\"position\"] = \"bottom-right\"\n) {\n const rootRef = useRef<HTMLDivElement>(null);\n const gesture = useRef<Point | null>(null);\n const [position, setPosition] = useState<Point | null>(null);\n const [viewport, setViewport] = useState(visibleViewport);\n const horizontalEdge = corner.endsWith(\"right\") ? \"right\" : \"left\";\n const verticalEdge = corner.startsWith(\"bottom\") ? \"bottom\" : \"top\";\n\n const moveTo = useCallback(\n (point: Point, bounds: DOMRect) => {\n const fitted = clampPosition(point, bounds);\n const visible = visibleViewport();\n const anchor = {\n x:\n horizontalEdge === \"right\"\n ? visible.left + visible.width - fitted.x - bounds.width\n : fitted.x - visible.left,\n y:\n verticalEdge === \"bottom\"\n ? visible.top + visible.height - fitted.y - bounds.height\n : fitted.y - visible.top,\n };\n setPosition((current) =>\n current?.x === anchor.x && current.y === anchor.y ? current : anchor\n );\n },\n [horizontalEdge, verticalEdge]\n );\n\n const keepInViewport = useCallback(() => {\n const bounds = rootRef.current?.getBoundingClientRect();\n if (!bounds) {\n return;\n }\n const fitted = clampPosition(bounds, bounds, viewport);\n if (\n Math.abs(fitted.x - bounds.x) > 0.5 ||\n Math.abs(fitted.y - bounds.y) > 0.5\n ) {\n moveTo(fitted, bounds);\n }\n }, [moveTo, viewport]);\n\n useLayoutEffect(() => {\n keepInViewport();\n }, [keepInViewport]);\n useEffect(() => {\n const resizeViewport = () => setViewport(visibleViewport());\n const observer =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(keepInViewport);\n if (rootRef.current) {\n observer?.observe(rootRef.current);\n }\n window.addEventListener(\"resize\", resizeViewport);\n window.visualViewport?.addEventListener(\"resize\", resizeViewport);\n window.visualViewport?.addEventListener(\"scroll\", resizeViewport);\n return () => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", resizeViewport);\n window.visualViewport?.removeEventListener(\"resize\", resizeViewport);\n window.visualViewport?.removeEventListener(\"scroll\", resizeViewport);\n };\n }, [keepInViewport]);\n\n const onPointerDown = (event: PointerEvent<HTMLButtonElement>) => {\n const bounds = rootRef.current?.getBoundingClientRect();\n if (!bounds || event.button !== 0) {\n return;\n }\n event.currentTarget.setPointerCapture(event.pointerId);\n gesture.current = {\n x: event.clientX - bounds.x,\n y: event.clientY - bounds.y,\n };\n };\n const onPointerMove = (event: PointerEvent<HTMLButtonElement>) => {\n const bounds = rootRef.current?.getBoundingClientRect();\n if (bounds && gesture.current) {\n moveTo(\n {\n x: event.clientX - gesture.current.x,\n y: event.clientY - gesture.current.y,\n },\n bounds\n );\n }\n };\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n const direction = KEY_DIRECTIONS[event.key];\n const bounds = rootRef.current?.getBoundingClientRect();\n if (!(bounds && direction)) {\n return;\n }\n event.preventDefault();\n moveTo({ x: bounds.x + direction.x, y: bounds.y + direction.y }, bounds);\n };\n\n const viewportStyles = `.root { --rf-viewport-width: ${viewport.width}px; --rf-viewport-top: ${viewport.top}px; --rf-viewport-bottom: ${viewport.bottom}px; --rf-viewport-left: ${viewport.left}px; --rf-viewport-right: ${viewport.right}px; }`;\n const anchorStyles = position\n ? `.root[data-moved=\"true\"] { left: auto; right: auto; top: auto; bottom: auto; ${horizontalEdge}: ${position.x + viewport[horizontalEdge]}px; ${verticalEdge}: ${position.y + viewport[verticalEdge]}px; }`\n : \"\";\n return {\n handleProps: {\n onKeyDown,\n onPointerCancel: () => {\n gesture.current = null;\n },\n onPointerDown,\n onPointerMove,\n onPointerUp: () => {\n gesture.current = null;\n },\n },\n position,\n rootRef,\n styles: viewportStyles + anchorStyles,\n };\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport type {\n FeedbackWidgetCategory,\n FeedbackWidgetLabels,\n RefletFeedbackProps,\n} from \"../../types\";\nimport { GripIcon, MinusIcon } from \"../icons\";\nimport { Launcher } from \"../launcher\";\nimport { FeedbackPanel } from \"../panel\";\nimport type { WidgetState } from \"../use-widget-state\";\nimport { useFloatingPosition } from \"./use-floating-position\";\n\nexport function FloatingWidget({\n labels,\n options,\n state,\n}: {\n labels: FeedbackWidgetLabels;\n options: {\n categories: FeedbackWidgetCategory[];\n position: RefletFeedbackProps[\"position\"];\n };\n state: WidgetState;\n}) {\n const [minimized, setMinimized] = useState(false);\n const launcherRef = useRef<HTMLButtonElement>(null);\n const floating = useFloatingPosition(options.position);\n const showPanel = state.isOpen && !minimized;\n const minimize = () => {\n setMinimized(true);\n requestAnimationFrame(() => launcherRef.current?.focus());\n };\n\n useEffect(() => {\n if (state.step === \"compose\") {\n state.annotationTrigger?.focus({ preventScroll: true });\n }\n }, [state.step, state.annotationTrigger]);\n\n useEffect(() => {\n if (!showPanel || state.step !== \"compose\") {\n return;\n }\n const onKeyDown = (event: globalThis.KeyboardEvent) => {\n if (event.key === \"Escape\" && !event.defaultPrevented) {\n setMinimized(true);\n requestAnimationFrame(() => launcherRef.current?.focus());\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [showPanel, state.step]);\n\n return (\n <div\n className=\"root\"\n data-editing={\n state.isOpen && (state.step === \"picking\" || state.step === \"annotate\")\n }\n data-moved={Boolean(floating.position)}\n data-position={options.position}\n ref={floating.rootRef}\n >\n <style>{floating.styles}</style>\n {showPanel ? (\n <FeedbackPanel\n labels={labels}\n options={{\n categories: options.categories,\n floatingControls: (\n <div className=\"floating-controls glass\">\n <button\n aria-label={labels.moveFeedback}\n className=\"icon-btn drag-handle\"\n title={labels.moveFeedback}\n type=\"button\"\n {...floating.handleProps}\n >\n <GripIcon />\n </button>\n <button\n aria-label={labels.minimize}\n className=\"icon-btn\"\n onClick={minimize}\n title={labels.minimize}\n type=\"button\"\n >\n <MinusIcon />\n </button>\n </div>\n ),\n }}\n state={state}\n />\n ) : (\n <Launcher\n buttonRef={launcherRef}\n isOpen={false}\n label={state.isOpen ? labels.resume : labels.trigger}\n onClick={() => {\n setMinimized(false);\n if (!state.isOpen) {\n state.open();\n }\n }}\n />\n )}\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { WIDGET_MARKER } from \"../core/capture\";\nimport { describeElement, describeRegion } from \"../core/element-selector\";\nimport { getFiberFromNode, resolveComponentStack } from \"../core/react-source\";\n\nconst LABEL_HEIGHT = 24;\nconst LABEL_GAP = 6;\n\ninterface HoverTarget {\n componentName?: string;\n element: Element;\n label: string;\n rect: DOMRect;\n region?: string;\n}\n\nfunction isWidgetOwned(element: Element): boolean {\n return element.closest(`[${WIDGET_MARKER}]`) !== null;\n}\n\nfunction elementUnder(x: number, y: number): Element | null {\n const element = document.elementFromPoint(x, y);\n if (!element || isWidgetOwned(element)) {\n return null;\n }\n return element;\n}\n\nfunction describeTarget(element: Element): HoverTarget {\n return {\n componentName: resolveComponentStack(getFiberFromNode(element))[0],\n element,\n label: describeElement(element),\n rect: element.getBoundingClientRect(),\n region: describeRegion(element),\n };\n}\n\n/**\n * Points at any element in the page the way a coding agent needs it: the React\n * component that owns it plus the page region it lives in.\n */\nexport function ElementPicker({\n hint,\n onCancel,\n onPick,\n}: {\n hint: string;\n onCancel: () => void;\n onPick: (element: Element) => void;\n}) {\n const [target, setTarget] = useState<HoverTarget | null>(null);\n\n useEffect(() => {\n const swallow = (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onMove = (event: PointerEvent) => {\n const element = elementUnder(event.clientX, event.clientY);\n if (!element) {\n setTarget(null);\n return;\n }\n\n setTarget((current) =>\n current?.element === element\n ? { ...current, rect: element.getBoundingClientRect() }\n : describeTarget(element)\n );\n };\n\n const onClick = (event: MouseEvent) => {\n swallow(event);\n const element = elementUnder(event.clientX, event.clientY);\n if (element) {\n onPick(element);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n swallow(event);\n onCancel();\n }\n };\n\n // Capture phase everywhere: the host app must not react to the pick.\n document.addEventListener(\"pointermove\", onMove, true);\n document.addEventListener(\"pointerdown\", swallow, true);\n document.addEventListener(\"mousedown\", swallow, true);\n document.addEventListener(\"mouseup\", swallow, true);\n document.addEventListener(\"click\", onClick, true);\n document.addEventListener(\"keydown\", onKeyDown, true);\n\n const previousCursor = document.body.style.cursor;\n document.body.style.cursor = \"crosshair\";\n\n return () => {\n document.removeEventListener(\"pointermove\", onMove, true);\n document.removeEventListener(\"pointerdown\", swallow, true);\n document.removeEventListener(\"mousedown\", swallow, true);\n document.removeEventListener(\"mouseup\", swallow, true);\n document.removeEventListener(\"click\", onClick, true);\n document.removeEventListener(\"keydown\", onKeyDown, true);\n document.body.style.cursor = previousCursor;\n };\n }, [onCancel, onPick]);\n\n const rect = target?.rect;\n const labelAbove = rect ? rect.top > LABEL_HEIGHT + LABEL_GAP : true;\n\n return (\n <div>\n {rect && (\n <div\n className=\"picker-box\"\n style={{\n height: rect.height,\n left: rect.left,\n top: rect.top,\n width: rect.width,\n }}\n />\n )}\n {rect && target && (\n <div\n className=\"picker-label\"\n style={{\n left: Math.max(4, rect.left),\n top: labelAbove\n ? rect.top - LABEL_HEIGHT - LABEL_GAP\n : rect.bottom + LABEL_GAP,\n }}\n >\n <strong>\n {target.componentName ? `<${target.componentName}>` : target.label}\n </strong>\n {target.region && <span>{target.region}</span>}\n </div>\n )}\n <div className=\"picker-hint\">\n {hint} <kbd>Esc</kbd>\n </div>\n </div>\n );\n}\n","export const ANNOTATOR_STYLES = `\n.overlay { margin: 0; border: 0; padding: 0; width: 100vw; max-width: none; height: 100dvh; max-height: none; position: fixed; inset: 0; z-index: 2147483001; display: flex; flex-direction: column; background: color-mix(in srgb, var(--rf-bg) 94%, transparent); animation: rf-editor-in 260ms var(--rf-ease); transition: background 260ms var(--rf-ease); color: var(--rf-text); font: 13px/1.45 ui-sans-serif, system-ui, sans-serif; }\n.overlay::backdrop { background: transparent; }\n@keyframes rf-editor-in { from { background: transparent; } }\n.editor { flex: 1; position: relative; display: flex; align-items: center; justify-content: center; padding: 20px; min-height: 0; container-type: size; }\n.editor-image { width: min(100cqw, calc(100cqh * var(--rf-capture-ratio))); aspect-ratio: var(--rf-capture-ratio); flex: none; position: relative; }\n.editor-visual { position: absolute; inset: 0; border-radius: var(--rf-radius); box-shadow: var(--rf-shadow); transform-origin: top left; overflow: hidden; }\n.editor-visual img, .editor-visual canvas { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: inherit; object-fit: cover; object-position: top center; }\n.editor-visual canvas { cursor: crosshair; touch-action: none; }\n.overlay[data-opening=\"true\"] .editor { pointer-events: none; }\n.overlay[data-closing=\"true\"] { pointer-events: none; background: transparent; }\n.overlay[data-closing=\"true\"] .toolbar { opacity: 0; transform: translateY(8px); }\n\n.toolbar { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; transition: opacity 180ms var(--rf-ease), transform 180ms var(--rf-ease); padding: 4px 12px max(16px, env(safe-area-inset-bottom)); }\n.toolbar .group { display: flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--rf-pill); }\n.tool[aria-pressed=\"true\"], .tool[data-selected=\"true\"] { background: var(--rf-primary); color: var(--rf-primary-text); }\n.color-picker { position: relative; }\n.color-picker summary { display: flex; justify-content: center; align-items: center; }\n.color-preview { width: 18px; height: 18px; border-radius: 50%; background: var(--annotation-color); box-shadow: inset 0 0 0 1px var(--rf-border); }\n.color-popover { --rf-color-width: 200px; position: absolute; bottom: calc(100% + 14px); left: clamp(calc(12px - var(--rf-color-anchor)), 0px, calc(100vw - var(--rf-color-anchor) - var(--rf-color-width) - 12px)); display: flex; align-items: center; gap: 6px; width: var(--rf-color-width); padding: 4px 4px 4px 14px; border-radius: var(--rf-pill); animation: rf-in 180ms var(--rf-ease); }\n.color-picker[data-placement=\"below\"] .color-popover { top: calc(100% + 14px); bottom: auto; }\n.color-slider { flex: 1; min-width: 0; }\n.color-slider-control { display: flex; align-items: center; height: 32px; width: 100%; touch-action: none; user-select: none; cursor: pointer; }\n.color-slider-track { height: 12px; width: 100%; border-radius: var(--rf-pill); background: linear-gradient(to right, white, var(--annotation-base-color)); box-shadow: inset 0 0 0 1px var(--rf-border); }\n.color-slider-thumb { width: 16px; height: 16px; border: 2px solid white; border-radius: 50%; background: var(--annotation-color); box-shadow: var(--rf-shadow-low); transition: scale 160ms var(--rf-ease); }\n.color-slider-thumb[data-dragging] { scale: 1.12; }\n.color-slider-thumb:has(:focus-visible), .color-spectrum:has(:focus-visible) { outline: 2px solid var(--rf-accent); outline-offset: 3px; }\n.color-spectrum { position: relative; display: flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; }\n.color-spectrum::before { content: \"\"; width: 16px; height: 16px; border-radius: 50%; background: conic-gradient(#ff5757, #ffde59, #6bdb78, #4ac9fa, #8b5cf6, #ef73dc, #ff5757); box-shadow: inset 0 0 0 1px var(--rf-glass-highlight); }\n.color-spectrum:hover { background: var(--rf-bg-hover); }\n.color-spectrum button { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: inherit; }\n.color-spectrum button:focus-visible { outline: none; }\n.color-spectrum input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }\n.done-btn { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border-radius: var(--rf-pill); color: var(--rf-primary-text); background: var(--rf-primary); }\n.drawing-menu { position: relative; }\n.drawing-popover { position: absolute; z-index: 2; right: 0; bottom: calc(100% + 12px); width: 200px; max-height: calc(50dvh - 68px); overflow-y: auto; padding: 6px; border-radius: var(--rf-radius); }\n.drawing-menu[data-placement=\"below\"] .drawing-popover { top: calc(100% + 12px); bottom: auto; }\n.drawing-option { display: flex; align-items: center; width: 100%; min-height: 36px; gap: 10px; padding: 0 10px; border-radius: 12px; text-align: left; }\n.drawing-option:hover, .drawing-option[aria-pressed=\"true\"] { background: var(--rf-bg-hover); }\n.drawing-divider { height: 1px; margin: 5px; background: var(--rf-border); }\n.editor canvas[data-tool=\"text\"] { cursor: text; }\n.text-annotation-editor { position: fixed; z-index: 3; width: 240px; padding: 8px; border-radius: var(--rf-radius); }\n.text-annotation-editor textarea { display: block; width: 100%; min-height: 64px; max-height: 112px; padding: 6px; border: 0; background: transparent; resize: vertical; font-size: 16px; line-height: 24px; }\n.text-annotation-editor textarea:focus { outline: none; }\n.text-annotation-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }\n@media (pointer: coarse) {\n .drawing-option { min-height: 44px; }\n .done-btn { width: 44px; height: 44px; }\n .color-popover { --rf-color-width: 232px; padding-left: 16px; }\n .color-slider-control, .color-spectrum { height: 44px; }\n .color-spectrum { width: 44px; }\n .color-slider-thumb, .color-spectrum::before { width: 18px; height: 18px; }\n .editor { padding: 8px; }\n .toolbar { gap: 6px; }\n .toolbar .group { padding: 3px; gap: 0; }\n}\n@media (pointer: coarse) and (max-width: 360px) {\n .toolbar { gap: 4px; padding-inline: 2px; }\n .toolbar .group { padding: 0; }\n}\n`;\n","export const COMPOSER_STYLES = `\n.panel { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 8px; outline: none; animation: rf-in 240ms var(--rf-ease); }\n.success-panel { border-radius: var(--rf-radius); }\n.composer { position: relative; display: flex; flex-direction: column; gap: 8px; }\n.message-row { display: flex; align-items: flex-end; gap: 4px; padding: 4px; border-radius: 26px; }\n.message-row textarea {\n flex: 1; width: 0; min-height: 36px; height: 36px; max-height: min(140px, 30dvh);\n margin: 0; padding: 8px 10px 8px 12px; border: 0; border-radius: 20px; resize: none;\n background: transparent; line-height: 20px; transition: height 220ms var(--rf-ease);\n}\n.panel:focus-within .message-row[data-expanded=\"true\"] textarea { height: 76px; }\n.message-row textarea::placeholder { color: var(--rf-text-muted); }\n.message-row textarea:focus { outline: none; }\n.message-row:has(textarea:focus-visible) { border-color: color-mix(in srgb, var(--rf-accent) 40%, var(--rf-glass-stroke)); }\n.submit { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; flex: none; border-radius: var(--rf-pill); background: var(--rf-primary); color: var(--rf-primary-text); transition: opacity 160ms var(--rf-ease), transform 160ms var(--rf-ease); }\n.submit svg { transform: rotate(-45deg); }\n.submit:hover:enabled { transform: scale(1.05); }\n.submit:disabled { background: var(--rf-bg-hover); color: var(--rf-text-muted); opacity: .65; }\n.composer-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }\n.composer-controls { display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: var(--rf-pill); }\n.select-control { position: relative; display: flex; align-items: center; min-width: 0; }\n.select-control > svg { position: absolute; right: 9px; width: 12px; height: 12px; pointer-events: none; color: var(--rf-text-muted); }\n.category-select { appearance: none; min-width: 0; max-width: 124px; height: 32px; padding: 0 26px 0 12px; border: 0; border-radius: var(--rf-pill); color: var(--rf-text); background: transparent; cursor: pointer; text-overflow: ellipsis; }\n.category-select:hover:hover { background: var(--rf-bg-hover); }\noption { background: var(--rf-bg); color: var(--rf-text); }\n.composer-options { position: relative; }\nsummary { cursor: pointer; list-style: none; }\nsummary::-webkit-details-marker { display: none; }\n.options-popover { position: absolute; z-index: 2; right: 0; bottom: calc(100% + 12px); width: min(240px, calc(100vw - 40px)); max-height: calc(50dvh - 68px); overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: var(--rf-radius); animation: rf-in 160ms var(--rf-ease); }\n.composer-options[data-placement=\"below\"] .options-popover { top: calc(100% + 12px); bottom: auto; }\n.email-field { display: flex; flex-direction: column; gap: 6px; color: var(--rf-text-muted); font-size: 12px; }\n.email-field [role=\"alert\"] { color: var(--rf-danger); }\n.email-field input { width: 100%; padding: 9px; border: 1px solid var(--rf-border); border-radius: var(--rf-radius-sm); background: var(--rf-bg-subtle); color: var(--rf-text); }\n.dismiss-btn { min-height: 32px; text-align: left; padding: 0 8px; border-radius: var(--rf-radius-sm); color: var(--rf-text-muted); }\n.dismiss-btn:hover { background: var(--rf-bg-hover); }\n.version-info { font-size: 10px; color: var(--rf-text-muted); padding: 4px 8px 0; border-top: 1px solid var(--rf-border); text-decoration: none; }\n.version-info:hover { color: var(--rf-text); }\n.attachments { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }\n.screenshot-scroll-area { position: relative; min-width: 0; max-width: calc(100% + 8px); margin: -4px -4px -8px; }\n.screenshot-strip { width: 100%; padding: 4px 4px 8px; overscroll-behavior-x: contain; --rf-fade-start: 0px; --rf-fade-end: 0px; mask-image: linear-gradient(to right, transparent, black var(--rf-fade-start), black calc(100% - var(--rf-fade-end)), transparent); mask-repeat: no-repeat; }\n.screenshot-strip[data-overflow-x-start] { --rf-fade-start: min(24px, var(--scroll-area-overflow-x-start)); }\n.screenshot-strip[data-overflow-x-end] { --rf-fade-end: min(24px, var(--scroll-area-overflow-x-end)); }\n.screenshot-strip-content { display: flex; align-items: flex-end; gap: 8px; }\n.screenshot-scroll-area:has(.screenshot-strip-content:empty) { display: none; }\n.attachments:has(.screenshot-strip-content:empty):not(:has(.selection-chip)) { display: none; }\n.screenshot-scrollbar { height: 4px; margin: 0 8px 2px; opacity: 0; transition: opacity 150ms var(--rf-ease); }\n.screenshot-scrollbar[data-hovering], .screenshot-scrollbar[data-scrolling] { opacity: 1; }\n.screenshot-scroll-thumb { border-radius: var(--rf-pill); background: var(--rf-border); }\n.capture-progress { position: absolute; inset: 3px; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 6px; border-radius: 16px; color: var(--rf-text-muted); font-size: 10px; }\n.attachments:empty { display: none; }\n.screenshot-attachment, .attachment-skeleton { position: relative; flex: none; margin: 0; min-width: 0; width: 128px; height: 78px; padding: 3px; border-radius: var(--rf-radius); animation: rf-in 260ms var(--rf-ease); }\n.screenshot-preview { display: block; position: relative; width: 100%; height: 100%; padding: 0; overflow: hidden; border-radius: 16px; }\n.screenshot-preview img, .screenshot-preview canvas { width: 100%; height: 100%; display: block; object-fit: cover; object-position: top center; }\n.screenshot-preview canvas { position: absolute; inset: 0; pointer-events: none; }\n.attachment-caption { position: absolute; left: 5px; bottom: 5px; display: flex; align-items: center; gap: 4px; padding: 3px 6px; font-size: 10px; border-radius: var(--rf-pill); color: var(--rf-text); }\n.attachment-caption svg { width: 12px; height: 12px; }\n.annotation-count { color: var(--rf-text); font-weight: 600; }\n.attachment-actions { position: absolute; right: 4px; bottom: -4px; display: flex; gap: 1px; padding: 1px; border-radius: var(--rf-pill); opacity: 0; pointer-events: none; transform: translateY(3px); transition: opacity 150ms var(--rf-ease), transform 150ms var(--rf-ease); }\n.screenshot-attachment:hover .attachment-actions, .screenshot-attachment:focus-within .attachment-actions { opacity: 1; pointer-events: auto; transform: none; }\n.screenshot-attachment:hover .attachment-caption, .screenshot-attachment:focus-within .attachment-caption { opacity: 0; }\n.attachment-skeleton { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: var(--rf-text-muted); font-size: 11px; }\n.attachment-skeleton::after { content: \"\"; position: absolute; inset: 0; border-radius: inherit; background: var(--rf-bg-subtle); animation: rf-fade 800ms alternate infinite; }\n.selection-chip { display: flex; align-items: center; max-width: 100%; padding: 3px; border-radius: var(--rf-pill); }\n.selection-label { display: flex; align-items: center; min-width: 0; gap: 6px; padding: 0 6px; font-size: 11px; }\n.selection-label img { object-fit: contain; border-radius: var(--rf-pill); }\n@media (pointer: coarse) {\n .category-select { height: 44px; max-width: 96px; }\n .message-row { border-radius: 28px; }\n .message-row textarea { font-size: 16px; min-height: 44px; height: 44px; padding-top: 12px; }\n .submit { width: 44px; height: 44px; }\n .attachment-actions { opacity: 1; pointer-events: auto; transform: none; }\n .attachment-caption { top: 4px; bottom: auto; right: 4px; left: auto; }\n .attachment-caption-label { display: none; }\n .screenshot-attachment:hover .attachment-caption, .screenshot-attachment:focus-within .attachment-caption { opacity: 1; }\n .screenshot-attachment, .attachment-skeleton { height: 96px; }\n .email-field input { font-size: 16px; }\n .dismiss-btn, .selection-label { min-height: 44px; }\n}\n`;\n","export const PICKER_STYLES = `\n.picker-box {\n position: fixed;\n pointer-events: none;\n border-radius: 5px;\n background: color-mix(in srgb, var(--rf-accent) 10%, transparent);\n box-shadow: 0 0 0 2px var(--rf-accent), 0 0 0 5px color-mix(in srgb, var(--rf-accent) 18%, transparent);\n transition: top 130ms var(--rf-ease), left 130ms var(--rf-ease), width 130ms var(--rf-ease), height 130ms var(--rf-ease);\n}\n.picker-label {\n position: fixed;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: min(420px, 90vw);\n height: 24px;\n padding: 0 8px;\n font-size: 11.5px;\n font-weight: 500;\n color: #ffffff;\n background: var(--rf-accent);\n border-radius: 6px;\n box-shadow: 0 4px 12px -3px rgb(15 15 15 / 35%);\n white-space: nowrap;\n overflow: hidden;\n transition: top 130ms var(--rf-ease), left 130ms var(--rf-ease);\n}\n.picker-label strong { flex: none; font-weight: 600; }\n.picker-label span { min-width: 0; overflow: hidden; text-overflow: ellipsis; opacity: 0.75; }\n.picker-hint {\n position: fixed;\n left: 50%;\n bottom: 24px;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n font-size: 12.5px;\n color: var(--rf-text);\n background: var(--rf-bg);\n border-radius: 10px;\n box-shadow: var(--rf-shadow);\n animation: rf-fade 240ms var(--rf-ease);\n}\n.picker-hint kbd {\n padding: 1px 5px;\n font: inherit;\n font-size: 11px;\n color: var(--rf-text-muted);\n border-radius: 4px;\n background: var(--rf-bg-subtle);\n box-shadow: var(--rf-shadow-inset);\n}\n\n`;\n","import { DEFAULT_WIDGET_OFFSET } from \"../types\";\nimport { ANNOTATOR_STYLES } from \"./annotation/styles\";\nimport { COMPOSER_STYLES } from \"./composer/styles\";\nimport { PICKER_STYLES } from \"./floating/picker-styles\";\n\nexport const WIDGET_STYLES = `\n:host {\n --rf-offset: ${DEFAULT_WIDGET_OFFSET}px;\n --rf-bg: #ffffff;\n --rf-bg-subtle: rgb(55 53 47 / 4%);\n --rf-bg-hover: rgb(55 53 47 / 7%);\n --rf-border: rgb(55 53 47 / 9%);\n --rf-text: #37352f;\n --rf-text-muted: rgb(55 53 47 / 68%);\n --rf-primary: #37352f;\n --rf-primary-text: #ffffff;\n --rf-accent: #2383e2;\n --rf-danger: #d44c47;\n --rf-success: #448361;\n --rf-radius: 20px;\n --rf-pill: 999px;\n --rf-width: 360px;\n --rf-glass: rgb(255 255 255 / 72%);\n --rf-glass-highlight: rgb(255 255 255 / 90%);\n --rf-glass-stroke: rgb(255 255 255 / 70%);\n --rf-radius-sm: 8px;\n --rf-shadow-inset: inset 0 0 0 1px var(--rf-border);\n --rf-shadow-low: 0 0 0 1px rgb(15 15 15 / 4%), 0 1px 2px rgb(15 15 15 / 6%), 0 4px 10px -4px rgb(15 15 15 / 10%);\n --rf-shadow: 0 0 0 1px rgb(15 15 15 / 4%), 0 2px 5px -1px rgb(15 15 15 / 7%), 0 12px 32px -8px rgb(15 15 15 / 16%);\n --rf-ease: cubic-bezier(0.16, 1, 0.3, 1);\n color-scheme: light;\n all: initial;\n font-family: var(--rf-font, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif);\n}\n\n:host([data-theme=\"dark\"]) {\n --rf-bg: #202020;\n --rf-bg-subtle: rgb(255 255 255 / 5%);\n --rf-bg-hover: rgb(255 255 255 / 9%);\n --rf-border: rgb(255 255 255 / 9%);\n --rf-text: #ebeae8;\n --rf-text-muted: rgb(255 255 255 / 68%);\n --rf-glass: rgb(32 32 32 / 78%);\n --rf-glass-highlight: rgb(255 255 255 / 14%);\n --rf-glass-stroke: rgb(255 255 255 / 12%);\n --rf-primary: #f1efec;\n --rf-primary-text: #1c1c1b;\n --rf-accent: #529cca;\n --rf-danger: #eb5757;\n --rf-success: #4dab74;\n --rf-shadow-low: 0 0 0 1px rgb(255 255 255 / 6%), 0 1px 2px rgb(0 0 0 / 30%), 0 4px 10px -4px rgb(0 0 0 / 40%);\n --rf-shadow: 0 0 0 1px rgb(255 255 255 / 7%), 0 2px 5px -1px rgb(0 0 0 / 35%), 0 14px 36px -10px rgb(0 0 0 / 55%);\n color-scheme: dark;\n}\n\n*, *::before, *::after { box-sizing: border-box; }\n\n\n.root {\n position: fixed;\n z-index: 2147483000;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n font: 13px/1.45 var(--rf-font, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif);\n color: var(--rf-text);\n}\n.root:has(.panel) { width: min(var(--rf-width), calc(var(--rf-viewport-width, 100vw) - 24px)); }\n.root[data-position$=\"right\"] { right: calc(var(--rf-viewport-right, 0px) + max(12px, min(var(--rf-offset), calc((var(--rf-viewport-width, 100vw) - var(--rf-width)) / 2)))); }\n.root[data-position$=\"left\"] { left: calc(var(--rf-viewport-left, 0px) + max(12px, min(var(--rf-offset), calc((var(--rf-viewport-width, 100vw) - var(--rf-width)) / 2)))); }\n.root[data-position^=\"bottom\"] { bottom: calc(var(--rf-viewport-bottom, 0px) + max(var(--rf-offset), env(safe-area-inset-bottom))); }\n.root[data-position^=\"top\"] { top: calc(var(--rf-viewport-top, 0px) + max(var(--rf-offset), env(safe-area-inset-top))); align-items: flex-start; }\n.root[data-position=\"bottom-right\"] .panel { transform-origin: bottom right; }\n.root[data-position=\"bottom-left\"] .panel { transform-origin: bottom left; }\n.root[data-position^=\"top\"] .panel { transform-origin: top center; }\n.root[data-editing=\"true\"] { visibility: hidden; pointer-events: none; }\nbutton, select, input, textarea { font: inherit; color: inherit; }\nbutton { margin: 0; cursor: pointer; border: 0; background: none; }\nbutton:disabled { cursor: not-allowed; opacity: .4; }\nsvg { flex-shrink: 0; }\n:focus-visible { outline: 2px solid var(--rf-accent); outline-offset: 3px; }\n.icon-btn, .tool {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; flex: none; border-radius: var(--rf-pill); color: var(--rf-text-muted);\n transition: background 160ms var(--rf-ease), color 160ms var(--rf-ease);\n}\n.icon-btn:hover, .tool:hover { background: var(--rf-bg-hover); color: var(--rf-text); }\n.launcher {\n display: inline-flex; align-items: center; gap: 7px; height: 40px; padding: 0 15px;\n border-radius: var(--rf-pill); color: var(--rf-text);\n font-weight: 500;\n transition: transform 200ms var(--rf-ease), box-shadow 200ms var(--rf-ease);\n}\n.launcher:hover { transform: translateY(-2px); box-shadow: var(--rf-shadow); }\n.launcher-icon { display: flex; width: 15px; height: 15px; }\n.launcher-icon .on-close { display: none; }\n.floating-controls {\n display: flex; align-items: center; padding: 3px; flex: none;\n border-radius: var(--rf-pill);\n animation: rf-in 220ms var(--rf-ease);\n}\n.drag-handle { touch-action: none; cursor: grab; }\n.drag-handle:active { cursor: grabbing; }\n.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ghost-btn { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 0 8px; border-radius: var(--rf-radius-sm); }\n.ghost-btn:hover { background: var(--rf-bg-hover); }\n.error { margin: 0; padding: 10px 14px; border-radius: var(--rf-radius); font-size: 12px; color: var(--rf-danger); }\n.done { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 24px; text-align: center; }\n.done svg { color: var(--rf-success); }\n.done h2 { margin: 0; font-size: 14px; font-weight: 600; }\n.done p { margin: 0; font-size: 12px; color: var(--rf-text-muted); }\n.spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: rf-spin 700ms linear infinite; }\n.hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n@keyframes rf-spin { to { transform: rotate(360deg); } }\n@keyframes rf-in { from { opacity: 0; transform: translateY(5px) scale(.98); } }\n@keyframes rf-fade { from { opacity: 0; } }\n@media (pointer: coarse) {\n .icon-btn, .tool { width: 44px; height: 44px; }\n .launcher, .ghost-btn { min-height: 44px; }\n}\n.glass {\n position: relative;\n isolation: isolate;\n border: 1px solid var(--rf-glass-stroke);\n box-shadow: inset 0 1px 0 var(--rf-glass-highlight), var(--rf-shadow);\n}\n.glass::before {\n content: \"\";\n position: absolute;\n inset: 0;\n z-index: -1;\n border-radius: inherit;\n background: var(--rf-bg);\n pointer-events: none;\n}\n@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {\n .glass::before {\n background: var(--rf-glass);\n -webkit-backdrop-filter: blur(20px) saturate(1.6);\n backdrop-filter: blur(20px) saturate(1.6);\n }\n}\n@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {\n .glass::before { background: var(--rf-bg); backdrop-filter: none; -webkit-backdrop-filter: none; }\n}\n.capture-halo { position: fixed; inset: 0; z-index: 2147482999; pointer-events: none; opacity: 0; transition: opacity 500ms var(--rf-ease); }\n.capture-halo[data-active=\"true\"] { opacity: 1; transition-duration: 140ms; }\n.capture-halo::before { content: \"\"; position: absolute; inset: 0; border-radius: 20px; box-shadow: inset 14px 0 36px -16px var(--rf-accent), inset -14px 0 36px -16px var(--rf-accent), inset 0 0 4px 1px color-mix(in srgb, var(--rf-accent) 35%, transparent); }\n.capture-halo::after { content: \"\"; position: absolute; inset: 0; background: linear-gradient(90deg, color-mix(in srgb, var(--rf-accent) 20%, transparent), transparent 5%, transparent 95%, color-mix(in srgb, var(--rf-accent) 20%, transparent)); }\n${COMPOSER_STYLES}\n${ANNOTATOR_STYLES}\n${PICKER_STYLES}\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after { animation: none !important; transition: none !important; }\n}\n`;\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { WIDGET_MARKER } from \"../core/capture\";\nimport { WIDGET_STYLES } from \"./styles\";\n\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport type WidgetTheme = \"auto\" | \"dark\" | \"light\";\n\nfunction useResolvedTheme(theme: WidgetTheme): \"dark\" | \"light\" {\n const [systemDark, setSystemDark] = useState(false);\n\n useEffect(() => {\n if (theme !== \"auto\" || typeof window.matchMedia !== \"function\") {\n return;\n }\n\n const query = window.matchMedia(DARK_QUERY);\n setSystemDark(query.matches);\n\n const onChange = (event: MediaQueryListEvent) =>\n setSystemDark(event.matches);\n query.addEventListener(\"change\", onChange);\n return () => query.removeEventListener(\"change\", onChange);\n }, [theme]);\n\n if (theme === \"auto\") {\n return systemDark ? \"dark\" : \"light\";\n }\n return theme;\n}\n\n/**\n * Hosts the widget in a shadow root: the app's CSS cannot reach the panel and\n * the panel's CSS cannot reach the app. Direct DOM work is unavoidable here —\n * React has no declarative way to create a shadow root.\n */\nexport function ShadowPortal({\n children,\n offset,\n primaryColor,\n theme,\n}: {\n children: ReactNode;\n offset: number;\n primaryColor?: string;\n theme: WidgetTheme;\n}) {\n const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);\n const resolvedTheme = useResolvedTheme(theme);\n\n useEffect(() => {\n const host = document.createElement(\"div\");\n host.setAttribute(WIDGET_MARKER, \"\");\n const root = host.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n style.textContent = WIDGET_STYLES;\n root.append(style);\n document.body.append(host);\n setShadowRoot(root);\n\n return () => host.remove();\n }, []);\n\n useEffect(() => {\n const host = shadowRoot?.host;\n if (!(host instanceof HTMLElement)) {\n return;\n }\n\n host.setAttribute(\"data-theme\", resolvedTheme);\n host.style.setProperty(\"--rf-offset\", `${offset}px`);\n if (primaryColor) {\n host.style.setProperty(\"--rf-primary\", primaryColor);\n }\n }, [shadowRoot, resolvedTheme, primaryColor, offset]);\n\n if (!shadowRoot) {\n return null;\n }\n\n return createPortal(children, shadowRoot);\n}\n","import type { ConsoleEvent } from \"../../types\";\n\nconst DEFAULT_LIMIT = 30;\nconst MAX_MESSAGE_LENGTH = 1000;\nconst RECORDED_METHODS = [\"error\", \"warn\"] as const;\n\ntype RecordedMethod = (typeof RECORDED_METHODS)[number];\n\nexport interface ConsoleRecorder {\n events: () => ConsoleEvent[];\n stop: () => void;\n}\n\nfunction serializeArgument(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (value instanceof Error) {\n return `${value.name}: ${value.message}`;\n }\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value) ?? \"[unserializable]\";\n } catch {\n return \"[unserializable]\";\n }\n }\n if (typeof value === \"function\") {\n return \"[function]\";\n }\n return String(value);\n}\n\nfunction formatMessage(args: unknown[]): string {\n const message = args.map(serializeArgument).join(\" \");\n return message.length > MAX_MESSAGE_LENGTH\n ? `${message.slice(0, MAX_MESSAGE_LENGTH - 1)}…`\n : message;\n}\n\n/**\n * Buffers the console noise a user saw right before reporting a bug.\n * Wrappers delegate to the previous implementation, so nothing is swallowed.\n */\nexport function startConsoleRecorder(options?: {\n limit?: number;\n}): ConsoleRecorder {\n const limit = options?.limit ?? DEFAULT_LIMIT;\n const buffer: ConsoleEvent[] = [];\n let active = true;\n\n const push = (level: ConsoleEvent[\"level\"], message: string) => {\n if (!(active && message)) {\n return;\n }\n buffer.push({ level, message, timestamp: Date.now() });\n if (buffer.length > limit) {\n buffer.splice(0, buffer.length - limit);\n }\n };\n\n const originals = new Map<RecordedMethod, (...args: unknown[]) => void>();\n const wrappers = new Map<RecordedMethod, (...args: unknown[]) => void>();\n\n for (const method of RECORDED_METHODS) {\n const original = console[method];\n const wrapper = (...args: unknown[]) => {\n push(method, formatMessage(args));\n Reflect.apply(original, console, args);\n };\n originals.set(method, original);\n wrappers.set(method, wrapper);\n console[method] = wrapper;\n }\n\n const onError = (event: ErrorEvent) => {\n const where = event.filename\n ? ` (${event.filename}:${event.lineno}:${event.colno})`\n : \"\";\n push(\"error\", `${event.message}${where}`);\n };\n\n const onRejection = (event: PromiseRejectionEvent) => {\n push(\"error\", `Unhandled rejection: ${serializeArgument(event.reason)}`);\n };\n\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n\n return {\n events: () => buffer.slice(),\n stop: () => {\n if (!active) {\n return;\n }\n active = false;\n buffer.length = 0;\n\n for (const method of RECORDED_METHODS) {\n const original = originals.get(method);\n // Another recorder wrapped ours — leave its chain intact.\n if (original && console[method] === wrappers.get(method)) {\n console[method] = original;\n }\n }\n\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n },\n };\n}\n","import type { ElementSelection } from \"../../types\";\nimport type { Annotation, CapturedImage } from \"../types\";\nimport { capturedFromCanvas, captureViewport, releaseCapture } from \"./capture\";\n\nconst MIN_CONTEXT_PADDING = 24;\nconst MAX_CONTEXT_WIDTH = 2000;\nconst CLOSE_UP_MAX_WIDTH = 1200;\nconst SELECTION_COLOR = \"#4f46e5\";\nconst OUTLINE_COLOR = \"#4f46e5\";\nconst OUTLINE_GLOW = \"#ffffff\";\nconst OUTLINE_WIDTH = 3;\nconst GLOW_WIDTH = 6;\nconst DIM_OVERLAY = \"rgba(15, 23, 42, 0.45)\";\n\n/**\n * Tightest ancestor that keeps some breathing room around the pick — the zoom\n * stays zoomed instead of growing to a giant section. Only when nothing up\n * the tree clears the minimum does the widest candidate below the cap win.\n */\nexport function contextRootFor(element: Element): Element {\n const target = element.getBoundingClientRect();\n const coversAtLeast = (box: DOMRect, margin: number): boolean =>\n box.left <= target.left - margin &&\n box.right >= target.right + margin &&\n box.top <= target.top - margin &&\n box.bottom >= target.bottom + margin;\n\n let tightest: Element | null = null;\n let current = element.parentElement;\n\n while (current && current !== document.documentElement) {\n const box = current.getBoundingClientRect();\n\n if (coversAtLeast(box, MIN_CONTEXT_PADDING)) {\n return current;\n }\n tightest ??= box.width < MAX_CONTEXT_WIDTH ? current : null;\n\n current = current.parentElement;\n }\n\n return tightest ?? element;\n}\n\nexport interface CloseUpGeometry {\n height: number;\n scale: number;\n width: number;\n x: number;\n y: number;\n}\n\n/** Where the picked element sits inside the context shot, in image pixels. */\nexport function closeUpGeometry(params: {\n capture: Pick<CapturedImage, \"height\" | \"width\">;\n elementRect: DOMRect;\n rootRect: DOMRect;\n}): CloseUpGeometry {\n const scale =\n params.rootRect.width > 0\n ? params.capture.width / params.rootRect.width\n : 1;\n\n return {\n height: Math.round(params.elementRect.height * scale),\n scale,\n width: Math.round(params.elementRect.width * scale),\n x: Math.round((params.elementRect.left - params.rootRect.left) * scale),\n y: Math.round((params.elementRect.top - params.rootRect.top) * scale),\n };\n}\n\n/** Rectangle annotation marking the picked element on the viewport shot. */\nexport function highlightFor(\n selection: ElementSelection,\n capture: CapturedImage\n): Annotation {\n const scale = capture.width / window.innerWidth;\n const { rect } = selection;\n\n return {\n color: SELECTION_COLOR,\n end: {\n x: (rect.x + rect.width) * scale,\n y: (rect.y + rect.height) * scale,\n },\n id: `selection-${rect.x}-${rect.y}`,\n start: { x: rect.x * scale, y: rect.y * scale },\n tool: \"rectangle\",\n };\n}\n\nfunction drawZoneOverlay(\n context: CanvasRenderingContext2D,\n zone: CloseUpGeometry\n): void {\n context.save();\n context.fillStyle = DIM_OVERLAY;\n context.beginPath();\n context.rect(0, 0, context.canvas.width, context.canvas.height);\n context.rect(zone.x, zone.y, zone.width, zone.height);\n context.fill(\"evenodd\");\n\n for (const [color, width] of [\n [OUTLINE_GLOW, GLOW_WIDTH],\n [OUTLINE_COLOR, OUTLINE_WIDTH],\n ] as const) {\n context.strokeStyle = color;\n context.lineWidth = width * zone.scale;\n context.strokeRect(zone.x, zone.y, zone.width, zone.height);\n }\n context.restore();\n}\n\nfunction drawCloseUp(\n capture: CapturedImage,\n zone: CloseUpGeometry\n): Promise<CapturedImage | null> {\n return new Promise((resolve) => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = capture.width;\n canvas.height = capture.height;\n const context = canvas.getContext(\"2d\");\n const image = new Image();\n\n image.onload = () => {\n if (!context) {\n resolve(null);\n return;\n }\n context.drawImage(image, 0, 0, capture.width, capture.height);\n drawZoneOverlay(context, zone);\n resolve(capturedFromCanvas(canvas, CLOSE_UP_MAX_WIDTH));\n };\n image.onerror = () => resolve(null);\n image.src = capture.objectUrl;\n });\n}\n\n/**\n * Zoomed view of the picked zone: the surrounding area captured for context,\n * everything outside the selection dimmed and the zone framed with a glowing\n * outline — unambiguous to eyes and vision models alike.\n * Falls back to the plain context shot when the overlay cannot be drawn.\n */\nexport async function captureElementCloseUp(\n element: Element\n): Promise<CapturedImage | null> {\n try {\n const root = contextRootFor(element);\n const rootRect = root.getBoundingClientRect();\n const elementRect = element.getBoundingClientRect();\n\n const capture = await captureViewport({\n element: root,\n maxWidth: CLOSE_UP_MAX_WIDTH,\n });\n if (!capture || root === element) {\n return capture;\n }\n\n const zone = closeUpGeometry({ capture, elementRect, rootRect });\n const outlined = await drawCloseUp(capture, zone);\n\n if (outlined) {\n releaseCapture(capture);\n return outlined;\n }\n return capture;\n } catch {\n return null;\n }\n}\n","import type { SaveScreenshotParams } from \"../../../types\";\nimport type { CapturedImage, ScreenshotDraft } from \"../../types\";\nimport { renderAnnotatedImage } from \"../annotation-renderer\";\nimport { toWireAnnotations } from \"../annotations\";\nimport { releaseCapture } from \"../capture\";\nimport type { FeedbackTransport, WidgetSubmission } from \"../submit\";\n\nexport type PreparedScreenshot = Omit<SaveScreenshotParams, \"feedbackId\">;\n\nasync function uploadImage(transport: FeedbackTransport, image: CapturedImage) {\n const { uploadUrl } = await transport.getScreenshotUploadUrl();\n return transport.uploadImage(uploadUrl, image);\n}\n\nasync function prepareScreenshot(\n transport: FeedbackTransport,\n screenshot: ScreenshotDraft,\n index: number\n): Promise<PreparedScreenshot> {\n const { image, annotations, context } = screenshot;\n const annotated =\n annotations.length > 0\n ? await renderAnnotatedImage(image, annotations)\n : null;\n if (annotations.length > 0 && !annotated) {\n throw new Error(\"Could not render your annotations. Please try again.\");\n }\n try {\n const storageId = await uploadImage(transport, image);\n const annotatedStorageId = annotated\n ? await uploadImage(transport, annotated)\n : undefined;\n return {\n annotatedStorageId,\n annotations:\n annotations.length > 0 ? toWireAnnotations(annotations) : undefined,\n captureSource: \"widget\",\n filename: `screenshot-${index + 1}.png`,\n height: image.height,\n mimeType: image.mimeType,\n pageUrl: context.url,\n size: image.blob.size,\n storageId,\n width: image.width,\n };\n } finally {\n releaseCapture(annotated);\n }\n}\n\nexport async function uploadScreenshots(\n transport: FeedbackTransport,\n submission: WidgetSubmission\n) {\n const results = await Promise.allSettled(\n submission.screenshots.map((screenshot, index) =>\n prepareScreenshot(transport, screenshot, index)\n )\n );\n const prepared = results.map((result) => {\n if (result.status === \"rejected\") {\n throw result.reason;\n }\n return result.value;\n });\n const element = submission.element;\n if (element) {\n prepared.push({\n captureSource: \"element\",\n filename: \"element.png\",\n height: element.height,\n mimeType: element.mimeType,\n pageUrl: submission.context.url,\n size: element.blob.size,\n storageId: await uploadImage(transport, element),\n width: element.width,\n });\n }\n return prepared;\n}\n","import type { Reflet } from \"../../client\";\nimport type {\n CreateFeedbackParams,\n CreateFeedbackResponse,\n FeedbackContext,\n SaveScreenshotParams,\n} from \"../../types\";\nimport type {\n CapturedImage,\n FeedbackWidgetCategory,\n ScreenshotDraft,\n} from \"../types\";\nimport {\n type PreparedScreenshot,\n uploadScreenshots,\n} from \"./submission/upload-screenshots\";\n\nconst MAX_TITLE_LENGTH = 100;\nconst NEWLINE = /\\r?\\n/;\n\nexport interface FeedbackTransport {\n create: (params: CreateFeedbackParams) => Promise<CreateFeedbackResponse>;\n getScreenshotUploadUrl: () => Promise<{ uploadUrl: string }>;\n saveScreenshot: (\n params: SaveScreenshotParams\n ) => Promise<{ screenshotId: string }>;\n uploadImage: (uploadUrl: string, image: CapturedImage) => Promise<string>;\n}\n\nexport interface WidgetSubmission {\n category: FeedbackWidgetCategory;\n context: FeedbackContext;\n element: CapturedImage | null;\n email?: string;\n isAnonymous: boolean;\n message: string;\n screenshots: ScreenshotDraft[];\n}\n\nexport interface SubmitResult {\n feedbackId: string;\n pendingScreenshots: PreparedScreenshot[];\n}\n\nexport function deriveTitle(message: string): string {\n const firstLine =\n message\n .split(NEWLINE)\n .map((line) => line.trim())\n .find(Boolean) ?? \"\";\n\n if (firstLine.length <= MAX_TITLE_LENGTH) {\n return firstLine;\n }\n\n const clipped = firstLine.slice(0, MAX_TITLE_LENGTH - 1);\n const lastSpace = clipped.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? clipped.slice(0, lastSpace) : clipped).trimEnd()}…`;\n}\n\nexport function buildDescription(params: {\n category: FeedbackWidgetCategory;\n email?: string;\n isAnonymous: boolean;\n message: string;\n}): string {\n const { category, email, isAnonymous, message } = params;\n const label = category.charAt(0).toUpperCase() + category.slice(1);\n const contact = isAnonymous && email ? `\\n\\n---\\nContact: ${email}` : \"\";\n\n return `[${label}] ${message.trim()}${contact}`;\n}\n\nexport async function attachPreparedScreenshots(\n transport: FeedbackTransport,\n result: SubmitResult\n): Promise<SubmitResult> {\n const results = await Promise.allSettled(\n result.pendingScreenshots.map((screenshot) =>\n transport.saveScreenshot({\n ...screenshot,\n feedbackId: result.feedbackId,\n })\n )\n );\n const pendingScreenshots = result.pendingScreenshots.filter(\n (_, index) => results[index]?.status === \"rejected\"\n );\n return { feedbackId: result.feedbackId, pendingScreenshots };\n}\n\nasync function createReportWithScreenshots(\n transport: FeedbackTransport,\n submission: WidgetSubmission,\n pendingScreenshots: PreparedScreenshot[]\n) {\n const { feedbackId } = await transport.create({\n context: submission.context,\n description: buildDescription(submission),\n title: deriveTitle(submission.message),\n });\n return attachPreparedScreenshots(transport, {\n feedbackId,\n pendingScreenshots,\n });\n}\n\nexport async function submitWidgetFeedback(\n transport: FeedbackTransport,\n submission: WidgetSubmission\n): Promise<SubmitResult> {\n const title = deriveTitle(submission.message);\n if (!title) {\n throw new Error(\"Please describe your feedback before sending it.\");\n }\n const pendingScreenshots = await uploadScreenshots(transport, submission);\n return createReportWithScreenshots(transport, submission, pendingScreenshots);\n}\n\nfunction isStorageResponse(value: unknown): value is { storageId: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof Reflect.get(value, \"storageId\") === \"string\"\n );\n}\n\nexport function createFeedbackTransport(client: Reflet): FeedbackTransport {\n return {\n create: (params) => client.create(params),\n getScreenshotUploadUrl: () => client.getScreenshotUploadUrl(),\n saveScreenshot: (params) => client.saveScreenshot(params),\n uploadImage: async (uploadUrl, image) => {\n const response = await fetch(uploadUrl, {\n body: image.blob,\n headers: { \"Content-Type\": image.mimeType },\n method: \"POST\",\n });\n\n if (!response.ok) {\n throw new Error(`Screenshot upload failed (${response.status})`);\n }\n\n const payload: unknown = await response.json();\n if (!isStorageResponse(payload)) {\n throw new Error(\"Screenshot upload returned no storage id\");\n }\n\n return payload.storageId;\n },\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { Reflet } from \"../../../client\";\nimport {\n attachPreparedScreenshots,\n createFeedbackTransport,\n type SubmitResult,\n submitWidgetFeedback,\n type WidgetSubmission,\n} from \"../../core/submit\";\n\nexport function useFeedbackSubmission(options: {\n client: Reflet | null;\n onError: (message: string | null) => void;\n onSubmitted: (feedbackId: string) => void;\n partialUploadMessage: string;\n}) {\n const [activeRequest, setActiveRequest] = useState<object | null>(null);\n const [pendingReport, setPendingReport] = useState<SubmitResult | null>(null);\n const requestRef = useRef<object | null>(null);\n useEffect(\n () => () => {\n requestRef.current = null;\n },\n []\n );\n\n const resetSubmission = useCallback(() => {\n requestRef.current = null;\n setPendingReport(null);\n setActiveRequest(null);\n }, []);\n\n const finishSubmission = (result: SubmitResult) => {\n if (result.pendingScreenshots.length > 0) {\n setPendingReport(result);\n options.onError(options.partialUploadMessage);\n return;\n }\n setPendingReport(null);\n options.onSubmitted(result.feedbackId);\n };\n\n const submit = async (draft: WidgetSubmission) => {\n if (requestRef.current) {\n return;\n }\n if (!options.client) {\n options.onError(\n \"Reflet is missing a publicKey. Pass one to RefletFeedback or RefletProvider.\"\n );\n return;\n }\n const request = {};\n requestRef.current = request;\n setActiveRequest(request);\n options.onError(null);\n try {\n const transport = createFeedbackTransport(options.client);\n const result = pendingReport\n ? await attachPreparedScreenshots(transport, pendingReport)\n : await submitWidgetFeedback(transport, draft);\n if (requestRef.current === request) {\n finishSubmission(result);\n }\n } catch (error) {\n if (requestRef.current === request) {\n options.onError(\n error instanceof Error\n ? error.message\n : \"Something went wrong. Please try again.\"\n );\n }\n } finally {\n if (requestRef.current === request) {\n requestRef.current = null;\n setActiveRequest(null);\n }\n }\n };\n\n return {\n hasPendingAttachments: pendingReport !== null,\n isEditingDisabled: activeRequest !== null || pendingReport !== null,\n isSubmitting: activeRequest !== null,\n resetSubmission,\n submit,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { releaseCapture } from \"../../core/capture\";\nimport type { CapturedImage } from \"../../types\";\n\nexport function useOwnedCapture() {\n const [image, setImage] = useState<CapturedImage | null>(null);\n const ownedImage = useRef<CapturedImage | null>(null);\n useEffect(() => () => releaseCapture(ownedImage.current), []);\n const replace = useCallback((nextImage: CapturedImage | null) => {\n releaseCapture(ownedImage.current);\n ownedImage.current = nextImage;\n setImage(nextImage);\n }, []);\n return [image, replace] as const;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { captureViewport, releaseCapture } from \"../../core/capture\";\nimport { collectPageContext } from \"../../core/page-context\";\nimport {\n type Annotation,\n type CapturedImage,\n type ScreenshotDraft,\n SDK_VERSION,\n} from \"../../types\";\n\nexport interface CaptureRequest {\n id: string;\n source: ScreenshotDraft[\"source\"];\n}\n\nexport function useScreenshotDrafts(\n captureFailed: string,\n onError: (error: string | null) => void\n) {\n const [screenshots, setScreenshots] = useState<ScreenshotDraft[]>([]);\n const [activeId, setActiveId] = useState<string | null>(null);\n const [pendingCapture, setPendingCapture] = useState<CaptureRequest | null>(\n null\n );\n const ownedImages = useRef(new Map<string, CapturedImage>());\n const captureRequest = useRef<CaptureRequest | null>(null);\n\n useEffect(() => {\n const images = ownedImages.current;\n return () => {\n captureRequest.current = null;\n for (const image of images.values()) {\n releaseCapture(image);\n }\n images.clear();\n };\n }, []);\n\n const storeScreenshot = useCallback((screenshot: ScreenshotDraft) => {\n releaseCapture(ownedImages.current.get(screenshot.id));\n ownedImages.current.set(screenshot.id, screenshot.image);\n setScreenshots((previous) => {\n const replacing = previous.some(({ id }) => id === screenshot.id);\n return replacing\n ? previous.map((item) =>\n item.id === screenshot.id ? screenshot : item\n )\n : [...previous, screenshot];\n });\n setActiveId(screenshot.id);\n }, []);\n\n const cancelPendingCapture = useCallback(() => {\n captureRequest.current = null;\n setPendingCapture(null);\n }, []);\n\n const takeScreenshot = useCallback(\n async (request: CaptureRequest) => {\n captureRequest.current = request;\n setPendingCapture(request);\n onError(null);\n const context = collectPageContext({ sdkVersion: SDK_VERSION });\n const image = await captureViewport().catch(() => null);\n if (captureRequest.current !== request) {\n releaseCapture(image);\n return;\n }\n cancelPendingCapture();\n if (!image) {\n onError(captureFailed);\n return;\n }\n storeScreenshot({ ...request, annotations: [], context, image });\n },\n [cancelPendingCapture, captureFailed, onError, storeScreenshot]\n );\n\n const takeCapture = useCallback(() => {\n if (!captureRequest.current) {\n takeScreenshot({ id: crypto.randomUUID(), source: \"manual\" });\n }\n }, [takeScreenshot]);\n\n const refreshAutomatic = useCallback(() => {\n takeScreenshot({\n id:\n ownedImages.current.keys().next().value ??\n captureRequest.current?.id ??\n crypto.randomUUID(),\n source: \"automatic\",\n });\n }, [takeScreenshot]);\n\n const retakeCapture = useCallback(\n (id: string) => {\n if (!captureRequest.current && ownedImages.current.has(id)) {\n takeScreenshot({ id, source: \"manual\" });\n }\n },\n [takeScreenshot]\n );\n\n const removeCapture = useCallback(\n (id: string) => {\n if (captureRequest.current?.id === id) {\n cancelPendingCapture();\n }\n releaseCapture(ownedImages.current.get(id));\n ownedImages.current.delete(id);\n setScreenshots((previous) => previous.filter((item) => item.id !== id));\n setActiveId((current) => (current === id ? null : current));\n },\n [cancelPendingCapture]\n );\n\n const resetScreenshots = useCallback(() => {\n cancelPendingCapture();\n for (const image of ownedImages.current.values()) {\n releaseCapture(image);\n }\n ownedImages.current.clear();\n setScreenshots([]);\n setActiveId(null);\n }, [cancelPendingCapture]);\n\n const setAnnotations = useCallback(\n (annotations: Annotation[]) => {\n setScreenshots((previous) =>\n previous.map((item) =>\n item.id === activeId ? { ...item, annotations } : item\n )\n );\n },\n [activeId]\n );\n\n const clearSelectionAnnotations = useCallback(() => {\n setScreenshots((previous) =>\n previous.map((item) => ({\n ...item,\n annotations: item.annotations.filter(\n ({ id }) => !id.startsWith(\"selection-\")\n ),\n }))\n );\n }, []);\n\n return {\n activeScreenshot:\n screenshots.find(({ id }) => id === activeId) ??\n screenshots.at(-1) ??\n null,\n cancelPendingCapture,\n clearSelectionAnnotations,\n pendingCapture,\n refreshAutomatic,\n removeCapture,\n resetScreenshots,\n retakeCapture,\n screenshots,\n selectScreenshot: setActiveId,\n setAnnotations,\n storeScreenshot,\n takeCapture,\n };\n}\n","import { useContext, useMemo } from \"react\";\nimport { Reflet } from \"../../../client\";\nimport { RefletContext } from \"../../../react-context\";\nimport type { RefletFeedbackProps } from \"../../types\";\n\nfunction defaultCategory(props: RefletFeedbackProps) {\n const preferred = props.defaultCategory ?? \"bug\";\n return (\n props.categories?.find((category) => category === preferred) ??\n props.categories?.[0] ??\n preferred\n );\n}\n\nfunction dismissalDuration(days: number | undefined) {\n return days !== undefined && Number.isFinite(days) && days > 0 ? days : null;\n}\n\nexport function useWidgetConfig(props: RefletFeedbackProps) {\n const context = useContext(RefletContext);\n const publicKey = props.publicKey ?? context?.publicKey;\n const baseUrl = props.baseUrl ?? context?.baseUrl;\n const user = props.user ?? context?.user;\n const userToken = props.userToken ?? context?.userToken;\n const client = useMemo(\n () =>\n publicKey ? new Reflet({ baseUrl, publicKey, user, userToken }) : null,\n [baseUrl, publicKey, user, userToken]\n );\n return {\n client,\n defaultCategory: defaultCategory(props),\n dismissalKey: `reflet-feedback-dismissed:${publicKey ?? \"default\"}:${user?.id ?? \"anonymous\"}`,\n dismissForDays: dismissalDuration(props.dismissForDays),\n isAnonymous: !(user || userToken),\n };\n}\n","import { useEffect } from \"react\";\n\nconst RESIZE_DEBOUNCE = 400;\n\n/**\n * Calls `refresh` whenever the page the reporter is looking at changes shape:\n * SPA routes (which never fire popstate on push/replace — history methods must\n * be patched) and window resizes, debounced. Keeps the frozen screenshot and\n * page context describing what the reporter currently sees.\n */\nexport function useCaptureSync(enabled: boolean, refresh: () => void): void {\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n const history = window.history;\n const originalPush = history.pushState;\n const originalReplace = history.replaceState;\n const hadOwnPush = Object.hasOwn(history, \"pushState\");\n const hadOwnReplace = Object.hasOwn(history, \"replaceState\");\n\n history.pushState = function pushState(data, unused, url) {\n const result = originalPush.call(history, data, unused, url);\n refresh();\n return result;\n };\n history.replaceState = function replaceState(data, unused, url) {\n const result = originalReplace.call(history, data, unused, url);\n refresh();\n return result;\n };\n window.addEventListener(\"popstate\", refresh);\n\n let resizeTimer: number | undefined;\n const onResize = () => {\n window.clearTimeout(resizeTimer);\n resizeTimer = window.setTimeout(refresh, RESIZE_DEBOUNCE);\n };\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n if (hadOwnPush) {\n history.pushState = originalPush;\n } else {\n Reflect.deleteProperty(history, \"pushState\");\n }\n if (hadOwnReplace) {\n history.replaceState = originalReplace;\n } else {\n Reflect.deleteProperty(history, \"replaceState\");\n }\n window.removeEventListener(\"popstate\", refresh);\n window.clearTimeout(resizeTimer);\n window.removeEventListener(\"resize\", onResize);\n };\n }, [enabled, refresh]);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ElementSelection } from \"../../types\";\nimport { captureViewport, releaseCapture } from \"../core/capture\";\nimport {\n type ConsoleRecorder,\n startConsoleRecorder,\n} from \"../core/console-recorder\";\nimport { captureElementCloseUp, highlightFor } from \"../core/element-capture\";\nimport { buildElementSelection } from \"../core/element-selector\";\nimport { collectPageContext } from \"../core/page-context\";\nimport {\n DEFAULT_WIDGET_LABELS,\n type FeedbackWidgetCategory,\n type RefletFeedbackProps,\n SDK_VERSION,\n type WidgetStep,\n} from \"../types\";\nimport { useFeedbackSubmission } from \"./state/use-feedback-submission\";\nimport { useOwnedCapture } from \"./state/use-owned-capture\";\nimport { useScreenshotDrafts } from \"./state/use-screenshot-drafts\";\nimport { useWidgetConfig } from \"./state/use-widget-config\";\nimport { useCaptureSync } from \"./use-capture-sync\";\n\nconst SUCCESS_CLOSE_DELAY = 2400;\nconst IS_APPLE = /Mac|iPhone|iPad/;\nconst MILLISECONDS_PER_DAY = 86_400_000;\n\nfunction readDismissedUntil(key: string): number {\n if (typeof window === \"undefined\") {\n return 0;\n }\n\n try {\n const value = Number.parseInt(window.localStorage.getItem(key) ?? \"\", 10);\n if (Number.isFinite(value) && value > Date.now()) {\n return value;\n }\n window.localStorage.removeItem(key);\n } catch {\n return 0;\n }\n\n return 0;\n}\n\nfunction writeDismissedUntil(key: string, until: number): void {\n try {\n window.localStorage.setItem(key, String(until));\n } catch {\n // storage blocked (private mode, quota) — dismissal just does not persist\n }\n}\n\nexport function matchesHotkey(\n event: Pick<\n KeyboardEvent,\n \"altKey\" | \"ctrlKey\" | \"key\" | \"metaKey\" | \"shiftKey\"\n >,\n hotkey: string,\n platform = typeof navigator === \"undefined\" ? \"\" : navigator.platform\n): boolean {\n const parts = hotkey\n .toLowerCase()\n .split(\"+\")\n .map((part) => part.trim());\n const key = parts.at(-1);\n if (!key || event.key.toLowerCase() !== key) {\n return false;\n }\n\n const isApple = IS_APPLE.test(platform);\n const wantsMod = parts.includes(\"mod\");\n const expected = {\n alt: parts.includes(\"alt\") || parts.includes(\"option\"),\n ctrl: parts.includes(\"ctrl\") || (wantsMod && !isApple),\n meta:\n parts.includes(\"meta\") || parts.includes(\"cmd\") || (wantsMod && isApple),\n shift: parts.includes(\"shift\"),\n };\n\n return (\n event.altKey === expected.alt &&\n event.ctrlKey === expected.ctrl &&\n event.metaKey === expected.meta &&\n event.shiftKey === expected.shift\n );\n}\n\nexport function useWidgetState(props: RefletFeedbackProps) {\n const { client, defaultCategory, dismissalKey, dismissForDays, isAnonymous } =\n useWidgetConfig(props);\n\n const [isOpen, setIsOpen] = useState(false);\n const [annotationTrigger, setAnnotationTrigger] =\n useState<HTMLButtonElement | null>(null);\n const [step, setStep] = useState<WidgetStep>(\"compose\");\n const [category, setCategory] =\n useState<FeedbackWidgetCategory>(defaultCategory);\n const [message, setMessage] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [honeypot, setHoneypot] = useState(\"\");\n const [elementCapture, replaceElementCapture] = useOwnedCapture();\n const [selection, setSelection] = useState<ElementSelection | null>(null);\n const [isElementCapturing, setIsElementCapturing] = useState(false);\n const successTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [dismissedUntil, setDismissedUntil] = useState(() =>\n readDismissedUntil(dismissalKey)\n );\n\n const pickRef = useRef(0);\n useEffect(\n () => () => {\n pickRef.current++;\n if (successTimer.current) {\n clearTimeout(successTimer.current);\n }\n },\n []\n );\n const consoleRef = useRef<ConsoleRecorder | null>(null);\n\n useEffect(() => {\n setDismissedUntil(readDismissedUntil(dismissalKey));\n }, [dismissalKey]);\n\n useEffect(() => {\n if (props.captureConsole === false) {\n return;\n }\n const recorder = startConsoleRecorder();\n consoleRef.current = recorder;\n return () => {\n consoleRef.current = null;\n recorder.stop();\n };\n }, [props.captureConsole]);\n\n const captureFailed =\n props.labels?.captureFailed ?? DEFAULT_WIDGET_LABELS.captureFailed;\n const gallery = useScreenshotDrafts(captureFailed, setError);\n const {\n activeScreenshot,\n cancelPendingCapture,\n clearSelectionAnnotations,\n refreshAutomatic,\n resetScreenshots,\n storeScreenshot,\n } = gallery;\n const capture = activeScreenshot?.image ?? null;\n const annotations = activeScreenshot?.annotations ?? [];\n const isCapturing = gallery.pendingCapture !== null || isElementCapturing;\n const submission = useFeedbackSubmission({\n client,\n onError: setError,\n onSubmitted: (feedbackId) => {\n setStep(\"success\");\n props.onSubmit?.({ feedbackId });\n successTimer.current = setTimeout(close, SUCCESS_CLOSE_DELAY);\n },\n partialUploadMessage:\n props.labels?.attachmentUploadFailed ??\n DEFAULT_WIDGET_LABELS.attachmentUploadFailed,\n });\n const { resetSubmission } = submission;\n const firstCapture = gallery.pendingCapture ?? gallery.screenshots[0];\n const canRefreshAutomatically =\n gallery.screenshots.length <= 1 && firstCapture?.source === \"automatic\";\n\n useCaptureSync(\n isOpen &&\n !submission.isEditingDisabled &&\n step === \"compose\" &&\n canRefreshAutomatically &&\n annotations.length === 0 &&\n !selection &&\n props.captureOnOpen !== false,\n refreshAutomatic\n );\n\n const reset = useCallback(() => {\n if (successTimer.current) {\n clearTimeout(successTimer.current);\n }\n setAnnotationTrigger(null);\n resetSubmission();\n pickRef.current++;\n setIsElementCapturing(false);\n resetScreenshots();\n replaceElementCapture(null);\n setSelection(null);\n setMessage(\"\");\n setEmail(\"\");\n setHoneypot(\"\");\n setError(null);\n setStep(\"compose\");\n setCategory(defaultCategory);\n }, [\n defaultCategory,\n resetSubmission,\n resetScreenshots,\n replaceElementCapture,\n ]);\n\n const close = useCallback(() => {\n setIsOpen(false);\n reset();\n props.onClose?.();\n }, [reset, props.onClose]);\n const dismiss = useCallback(() => {\n if (dismissForDays === null) {\n return;\n }\n\n const until = Date.now() + dismissForDays * MILLISECONDS_PER_DAY;\n writeDismissedUntil(dismissalKey, until);\n setIsOpen(false);\n reset();\n setDismissedUntil(until);\n props.onDismiss?.({ until });\n }, [dismissForDays, dismissalKey, props.onDismiss, reset]);\n\n const open = useCallback(() => {\n setIsOpen(true);\n setStep(\"compose\");\n props.onOpen?.();\n if (props.captureOnOpen !== false) {\n refreshAutomatic();\n }\n }, [props.captureOnOpen, props.onOpen, refreshAutomatic]);\n\n const selectElement = useCallback(\n async (element: Element) => {\n cancelPendingCapture();\n setIsElementCapturing(true);\n const picked = buildElementSelection(element);\n setSelection(picked);\n setStep(\"compose\");\n\n const pick = ++pickRef.current;\n const context = collectPageContext({ sdkVersion: SDK_VERSION });\n const [fresh, closeUp] = await Promise.all([\n captureViewport().catch(() => null),\n captureElementCloseUp(element).catch(() => null),\n ]);\n\n if (pickRef.current !== pick) {\n releaseCapture(fresh);\n releaseCapture(closeUp);\n return;\n }\n\n setIsElementCapturing(false);\n if (fresh) {\n storeScreenshot({\n annotations: [highlightFor(picked, fresh)],\n context,\n id: crypto.randomUUID(),\n image: fresh,\n source: \"manual\",\n });\n } else {\n setError(captureFailed);\n }\n replaceElementCapture(closeUp);\n },\n [\n cancelPendingCapture,\n captureFailed,\n storeScreenshot,\n replaceElementCapture,\n ]\n );\n\n const clearSelection = useCallback(() => {\n pickRef.current++;\n replaceElementCapture(null);\n setSelection(null);\n setIsElementCapturing(false);\n clearSelectionAnnotations();\n }, [clearSelectionAnnotations, replaceElementCapture]);\n\n const submit = () => {\n if (honeypot) {\n setStep(\"success\");\n return;\n }\n return submission.submit({\n category,\n context: {\n ...(activeScreenshot?.context ??\n collectPageContext({ sdkVersion: SDK_VERSION })),\n consoleEvents: consoleRef.current?.events(),\n metadata: props.metadata,\n selection: selection ?? undefined,\n },\n element: elementCapture,\n email,\n isAnonymous,\n message,\n screenshots: gallery.screenshots,\n });\n };\n\n return {\n activeScreenshot,\n annotateScreenshot: (id: string, trigger: HTMLButtonElement) => {\n setAnnotationTrigger(trigger);\n gallery.selectScreenshot(id);\n setStep(\"annotate\");\n },\n annotations,\n annotationTrigger,\n canDismiss: dismissForDays !== null,\n capture,\n category,\n clearSelection,\n close,\n dismiss,\n dismissForDays,\n elementCapture,\n email,\n error,\n hasPendingAttachments: submission.hasPendingAttachments,\n honeypot,\n isAnonymous,\n isCapturing,\n isDismissed: dismissedUntil > Date.now(),\n isEditingDisabled: submission.isEditingDisabled,\n isOpen,\n isSubmitting: submission.isSubmitting,\n message,\n open,\n pendingCapture: gallery.pendingCapture,\n removeCapture: gallery.removeCapture,\n retakeCapture: gallery.retakeCapture,\n screenshots: gallery.screenshots,\n selectElement,\n selection,\n setAnnotations: gallery.setAnnotations,\n setCategory,\n setEmail,\n setHoneypot,\n setMessage,\n setStep,\n step,\n submit,\n takeCapture: gallery.takeCapture,\n };\n}\n\nexport type WidgetState = ReturnType<typeof useWidgetState>;\n","import { useEffect } from \"react\";\nimport {\n DEFAULT_WIDGET_LABELS,\n DEFAULT_WIDGET_OFFSET,\n type FeedbackWidgetCategory,\n type RefletFeedbackProps,\n} from \"./types\";\nimport { Annotator } from \"./ui/annotator\";\nimport { FloatingWidget } from \"./ui/floating/floating-widget\";\nimport { ElementPicker } from \"./ui/picker\";\nimport { ShadowPortal } from \"./ui/shadow-portal\";\nimport { matchesHotkey, useWidgetState } from \"./ui/use-widget-state\";\n\nconst DEFAULT_CATEGORIES: FeedbackWidgetCategory[] = [\n \"bug\",\n \"idea\",\n \"question\",\n];\n\nexport function RefletFeedback(props: RefletFeedbackProps) {\n const {\n categories = DEFAULT_CATEGORIES,\n enabled = true,\n hotkey = null,\n offset = DEFAULT_WIDGET_OFFSET,\n position = \"bottom-right\",\n theme = \"auto\",\n } = props;\n\n const labels = { ...DEFAULT_WIDGET_LABELS, ...props.labels };\n const state = useWidgetState(props);\n const { close, isOpen, open } = state;\n\n useEffect(() => {\n if (!(hotkey && enabled)) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (matchesHotkey(event, hotkey)) {\n event.preventDefault();\n if (isOpen) {\n close();\n } else {\n open();\n }\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [close, enabled, hotkey, isOpen, open]);\n\n if (!enabled || state.isDismissed) {\n return null;\n }\n\n return (\n <ShadowPortal\n offset={offset}\n primaryColor={props.primaryColor}\n theme={theme}\n >\n <div\n aria-hidden=\"true\"\n className=\"capture-halo\"\n data-active={state.isCapturing}\n />\n <FloatingWidget\n labels={labels}\n options={{ categories, position }}\n state={state}\n />\n\n {isOpen && state.step === \"annotate\" && state.activeScreenshot && (\n <Annotator\n capture={state.activeScreenshot.image}\n editor={{\n annotations: state.annotations,\n onChange: state.setAnnotations,\n onDone: () => state.setStep(\"compose\"),\n onRetake: () => {\n state.setStep(\"compose\");\n if (state.activeScreenshot) {\n state.retakeCapture(state.activeScreenshot.id);\n }\n },\n trigger: state.annotationTrigger,\n }}\n labels={labels}\n />\n )}\n\n {isOpen && state.step === \"picking\" && (\n <ElementPicker\n hint={labels.pickElementHint}\n onCancel={() => state.setStep(\"compose\")}\n onPick={state.selectElement}\n />\n )}\n </ShadowPortal>\n );\n}\n"],"mappings":"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"}
|