@tutti-os/ui-rich-text 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor/index.js +62 -48
- package/dist/editor/index.js.map +1 -1
- package/package.json +3 -3
package/dist/editor/index.js
CHANGED
|
@@ -198,7 +198,14 @@ import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
|
198
198
|
|
|
199
199
|
// src/extensions/MentionReferenceNodeView.tsx
|
|
200
200
|
import { NodeViewWrapper } from "@tiptap/react";
|
|
201
|
-
import {
|
|
201
|
+
import {
|
|
202
|
+
MentionPill
|
|
203
|
+
} from "@tutti-os/ui-system/components";
|
|
204
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
205
|
+
var richTextMentionReferencePillClassName = "max-w-[16rem]";
|
|
206
|
+
function readStringAttr(value) {
|
|
207
|
+
return typeof value === "string" ? value.trim() : "";
|
|
208
|
+
}
|
|
202
209
|
function readMentionPresentationUrl(presentation) {
|
|
203
210
|
if (!presentation || typeof presentation !== "object") {
|
|
204
211
|
return null;
|
|
@@ -210,49 +217,56 @@ function readMentionPresentationUrl(presentation) {
|
|
|
210
217
|
const trimmed = value.trim();
|
|
211
218
|
return trimmed || null;
|
|
212
219
|
}
|
|
220
|
+
function readMentionScopeValue(scope, key) {
|
|
221
|
+
if (!scope || typeof scope !== "object") {
|
|
222
|
+
return "";
|
|
223
|
+
}
|
|
224
|
+
return readStringAttr(scope[key]);
|
|
225
|
+
}
|
|
226
|
+
function resolveMentionPillKind(providerId, scope) {
|
|
227
|
+
const id = providerId.trim();
|
|
228
|
+
if (id === "agent-session" || id === "session") {
|
|
229
|
+
return "session";
|
|
230
|
+
}
|
|
231
|
+
if (id === "workspace-app") {
|
|
232
|
+
return "app";
|
|
233
|
+
}
|
|
234
|
+
if (id === "workspace-issue") {
|
|
235
|
+
return "issue";
|
|
236
|
+
}
|
|
237
|
+
if (id === "workspace-reference") {
|
|
238
|
+
return readMentionScopeValue(scope, "source") === "task" ? "issue" : "app";
|
|
239
|
+
}
|
|
240
|
+
if (id === "file") {
|
|
241
|
+
return "file";
|
|
242
|
+
}
|
|
243
|
+
return "issue";
|
|
244
|
+
}
|
|
213
245
|
function MentionReferenceNodeView({
|
|
214
246
|
node,
|
|
215
247
|
selected
|
|
216
248
|
}) {
|
|
217
249
|
const label = typeof node.attrs.label === "string" ? node.attrs.label.trim().replace(/^@+/, "").trim() : "";
|
|
218
|
-
const iconUrl = readMentionPresentationUrl(node.attrs.presentation);
|
|
250
|
+
const iconUrl = readMentionPresentationUrl(node.attrs.presentation) || readMentionScopeValue(node.attrs.scope, "icon");
|
|
251
|
+
const kind = resolveMentionPillKind(
|
|
252
|
+
readStringAttr(node.attrs.providerId),
|
|
253
|
+
node.attrs.scope
|
|
254
|
+
);
|
|
219
255
|
return /* @__PURE__ */ jsx2(
|
|
220
256
|
NodeViewWrapper,
|
|
221
257
|
{
|
|
222
258
|
as: "span",
|
|
223
|
-
className: selected ? "is-selected" :
|
|
259
|
+
className: `inline-flex max-w-full align-baseline${selected ? " is-selected" : ""}`,
|
|
224
260
|
contentEditable: false,
|
|
225
261
|
"data-rich-text-mention-reference": "true",
|
|
226
|
-
children: /* @__PURE__ */
|
|
227
|
-
|
|
262
|
+
children: /* @__PURE__ */ jsx2(
|
|
263
|
+
MentionPill,
|
|
228
264
|
{
|
|
229
|
-
className:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
children: [
|
|
235
|
-
iconUrl ? /* @__PURE__ */ jsx2(
|
|
236
|
-
"span",
|
|
237
|
-
{
|
|
238
|
-
"aria-hidden": "true",
|
|
239
|
-
className: "inline-grid size-4 flex-none place-items-center overflow-hidden rounded",
|
|
240
|
-
"data-rich-text-mention-icon": "true",
|
|
241
|
-
children: /* @__PURE__ */ jsx2(
|
|
242
|
-
"img",
|
|
243
|
-
{
|
|
244
|
-
alt: "",
|
|
245
|
-
className: "block size-full object-cover object-center",
|
|
246
|
-
decoding: "async",
|
|
247
|
-
draggable: false,
|
|
248
|
-
loading: "lazy",
|
|
249
|
-
src: iconUrl
|
|
250
|
-
}
|
|
251
|
-
)
|
|
252
|
-
}
|
|
253
|
-
) : null,
|
|
254
|
-
label ? iconUrl ? label : `@${label}` : ""
|
|
255
|
-
]
|
|
265
|
+
className: richTextMentionReferencePillClassName,
|
|
266
|
+
iconUrl: iconUrl || void 0,
|
|
267
|
+
kind,
|
|
268
|
+
label,
|
|
269
|
+
removable: false
|
|
256
270
|
}
|
|
257
271
|
)
|
|
258
272
|
}
|
|
@@ -319,7 +333,7 @@ import { ReactNodeViewRenderer as ReactNodeViewRenderer2 } from "@tiptap/react";
|
|
|
319
333
|
import { useEffect, useState } from "react";
|
|
320
334
|
import { NodeViewWrapper as NodeViewWrapper2 } from "@tiptap/react";
|
|
321
335
|
import {
|
|
322
|
-
MentionPill,
|
|
336
|
+
MentionPill as MentionPill2,
|
|
323
337
|
Tooltip,
|
|
324
338
|
TooltipContent,
|
|
325
339
|
TooltipTrigger
|
|
@@ -366,7 +380,7 @@ function isPathRoot(path) {
|
|
|
366
380
|
}
|
|
367
381
|
|
|
368
382
|
// src/extensions/WorkspaceReferenceNodeView.tsx
|
|
369
|
-
import { jsx as jsx3, jsxs as
|
|
383
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
370
384
|
var richTextWorkspaceReferencePillClassName = "max-w-[18rem]";
|
|
371
385
|
function WorkspaceReferenceNodeView({
|
|
372
386
|
deleteNode,
|
|
@@ -410,9 +424,9 @@ function WorkspaceReferenceNodeView({
|
|
|
410
424
|
className: `inline-flex max-w-full align-baseline ${selected ? "is-selected" : ""}`,
|
|
411
425
|
contentEditable: false,
|
|
412
426
|
"data-rich-text-workspace-reference": "true",
|
|
413
|
-
children: /* @__PURE__ */
|
|
427
|
+
children: /* @__PURE__ */ jsxs2(Tooltip, { children: [
|
|
414
428
|
/* @__PURE__ */ jsx3(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx3(
|
|
415
|
-
|
|
429
|
+
MentionPill2,
|
|
416
430
|
{
|
|
417
431
|
className: richTextWorkspaceReferencePillClassName,
|
|
418
432
|
fileKind: kind,
|
|
@@ -510,7 +524,7 @@ var WorkspaceReference = Node2.create({
|
|
|
510
524
|
});
|
|
511
525
|
|
|
512
526
|
// src/editor/RichTextTriggerEditor.tsx
|
|
513
|
-
import { jsx as jsx4, jsxs as
|
|
527
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
514
528
|
var RICH_TEXT_MENTION_PRESENTATION_KEYS = [
|
|
515
529
|
"agentProviderId",
|
|
516
530
|
"agentIconUrl",
|
|
@@ -847,7 +861,7 @@ function RichTextTriggerEditor({
|
|
|
847
861
|
return;
|
|
848
862
|
}
|
|
849
863
|
};
|
|
850
|
-
return /* @__PURE__ */
|
|
864
|
+
return /* @__PURE__ */ jsxs3(
|
|
851
865
|
"div",
|
|
852
866
|
{
|
|
853
867
|
className: cn("relative min-w-0 w-full", className),
|
|
@@ -1189,9 +1203,9 @@ function getTextareaPresentationStyle(textarea) {
|
|
|
1189
1203
|
}
|
|
1190
1204
|
|
|
1191
1205
|
// src/editor/richTextTextareaDecorations.tsx
|
|
1192
|
-
import { MentionPill as
|
|
1206
|
+
import { MentionPill as MentionPill3 } from "@tutti-os/ui-system/components";
|
|
1193
1207
|
import { cn as cn2 } from "@tutti-os/ui-system/utils";
|
|
1194
|
-
import { jsx as jsx5, jsxs as
|
|
1208
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1195
1209
|
var richTextWorkspaceReferencePillClassName2 = "max-w-[18rem]";
|
|
1196
1210
|
function RichTextTextareaDecoratedContent({
|
|
1197
1211
|
onClickSegment,
|
|
@@ -1214,10 +1228,10 @@ function RichTextTextareaDecoratedContent({
|
|
|
1214
1228
|
if (segment.type === "text") {
|
|
1215
1229
|
return /* @__PURE__ */ jsx5("span", { children: segment.text }, index);
|
|
1216
1230
|
}
|
|
1217
|
-
return /* @__PURE__ */
|
|
1231
|
+
return /* @__PURE__ */ jsxs4("span", { className: "relative", children: [
|
|
1218
1232
|
/* @__PURE__ */ jsx5("span", { "aria-hidden": "true", className: "text-transparent", children: segment.text }),
|
|
1219
1233
|
/* @__PURE__ */ jsx5(
|
|
1220
|
-
|
|
1234
|
+
MentionPill3,
|
|
1221
1235
|
{
|
|
1222
1236
|
className: cn2(
|
|
1223
1237
|
"pointer-events-auto absolute inset-y-0 left-0 pr-1 pl-1.5",
|
|
@@ -1359,7 +1373,7 @@ function getTextareaCaretViewportPoint(textarea, selectionStart) {
|
|
|
1359
1373
|
}
|
|
1360
1374
|
|
|
1361
1375
|
// src/editor/RichTextTriggerTextarea.tsx
|
|
1362
|
-
import { jsx as jsx6, jsxs as
|
|
1376
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1363
1377
|
function RichTextTriggerTextarea({
|
|
1364
1378
|
value,
|
|
1365
1379
|
onChange,
|
|
@@ -1615,7 +1629,7 @@ function RichTextTriggerTextarea({
|
|
|
1615
1629
|
closeMenu();
|
|
1616
1630
|
}
|
|
1617
1631
|
};
|
|
1618
|
-
return /* @__PURE__ */
|
|
1632
|
+
return /* @__PURE__ */ jsxs5("div", { className: cn3("relative min-w-0 w-full", className), children: [
|
|
1619
1633
|
hasDecorations && textareaPresentationStyle ? /* @__PURE__ */ jsx6(
|
|
1620
1634
|
RichTextTextareaDecoratedContent,
|
|
1621
1635
|
{
|
|
@@ -1840,7 +1854,7 @@ function RichTextMentionReadonly({
|
|
|
1840
1854
|
|
|
1841
1855
|
// src/editor/RichTextReadonlyContent.tsx
|
|
1842
1856
|
import {
|
|
1843
|
-
MentionPill as
|
|
1857
|
+
MentionPill as MentionPill4,
|
|
1844
1858
|
Tooltip as Tooltip2,
|
|
1845
1859
|
TooltipContent as TooltipContent2,
|
|
1846
1860
|
TooltipTrigger as TooltipTrigger2
|
|
@@ -1875,7 +1889,7 @@ function buildRichTextReadonlyInlineSegments(content) {
|
|
|
1875
1889
|
}
|
|
1876
1890
|
|
|
1877
1891
|
// src/editor/RichTextReadonlyContent.tsx
|
|
1878
|
-
import { jsx as jsx8, jsxs as
|
|
1892
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1879
1893
|
var externalHrefPattern = /^(?:[a-z]+:)?\/\//i;
|
|
1880
1894
|
var richTextWorkspaceReferencePillClassName3 = "max-w-[18rem]";
|
|
1881
1895
|
function RichTextReadonlyContent({
|
|
@@ -1983,7 +1997,7 @@ function WorkspaceReferenceReadonly({
|
|
|
1983
1997
|
reference.path
|
|
1984
1998
|
);
|
|
1985
1999
|
const content = /* @__PURE__ */ jsx8(
|
|
1986
|
-
|
|
2000
|
+
MentionPill4,
|
|
1987
2001
|
{
|
|
1988
2002
|
className: richTextWorkspaceReferencePillClassName3,
|
|
1989
2003
|
fileKind: reference.kind,
|
|
@@ -1992,7 +2006,7 @@ function WorkspaceReferenceReadonly({
|
|
|
1992
2006
|
removable: false
|
|
1993
2007
|
}
|
|
1994
2008
|
);
|
|
1995
|
-
return /* @__PURE__ */
|
|
2009
|
+
return /* @__PURE__ */ jsxs6(Tooltip2, { children: [
|
|
1996
2010
|
/* @__PURE__ */ jsx8(TooltipTrigger2, { asChild: true, children: onOpenWorkspaceReference ? /* @__PURE__ */ jsx8(
|
|
1997
2011
|
"button",
|
|
1998
2012
|
{
|
package/dist/editor/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/editor/RichTextTriggerEditor.tsx","../../src/editor/richTextTriggerQuery.ts","../../src/editor/richTextIme.ts","../../src/editor/richTextTriggerText.ts","../../src/editor/RichTextTriggerMenuItem.tsx","../../src/extensions/mentionReference.ts","../../src/extensions/MentionReferenceNodeView.tsx","../../src/extensions/workspaceReference.ts","../../src/extensions/WorkspaceReferenceNodeView.tsx","../../src/extensions/workspaceReferencePresentation.ts","../../src/editor/RichTextTriggerTextarea.tsx","../../src/editor/richTextTextareaDecorationModel.ts","../../src/editor/richTextTextareaDecorations.tsx","../../src/editor/richTextTextareaCaret.ts","../../src/editor/RichTextMentionReadonly.tsx","../../src/editor/RichTextReadonlyContent.tsx","../../src/editor/richTextReadonlyContentModel.ts"],"sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n type JSX\n} from \"react\";\nimport Document from \"@tiptap/extension-document\";\nimport HardBreak from \"@tiptap/extension-hard-break\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Text from \"@tiptap/extension-text\";\nimport type { Editor as TiptapEditor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextMentionAttrs } from \"../plugins/index.ts\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionPresentation\n} from \"../types/mention.ts\";\nimport type {\n RichTextTriggerInsertResult,\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch,\n RichTextTrigger,\n RichTextTriggerConfig\n} from \"../types/trigger.ts\";\nimport {\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextContentToDocument,\n serializeRichTextDocumentToContent\n} from \"../core/richTextDocument.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { MentionReference } from \"../extensions/mentionReference.ts\";\nimport { WorkspaceReference } from \"../extensions/workspaceReference.ts\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\n\nexport interface RichTextTriggerEditorProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n placeholderClassName?: string;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n focusSignal?: unknown;\n menuZIndex?: string | number;\n}\n\ntype RichTextEditorTriggerQueryState = {\n from: number;\n keyword: string;\n trigger: RichTextTrigger;\n to: number;\n};\n\nconst RICH_TEXT_MENTION_PRESENTATION_KEYS = [\n \"agentProviderId\",\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"subtitle\",\n \"description\",\n \"participant\",\n \"status\",\n \"statusDataStatus\",\n \"statusLabel\",\n \"statusPulse\",\n \"userAvatarPlaceholderUrl\"\n] as const satisfies readonly (keyof RichTextMentionPresentation)[];\n\nexport function RichTextTriggerEditor({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n placeholderClassName,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay,\n focusSignal,\n menuZIndex\n}: RichTextTriggerEditorProps): JSX.Element {\n const menuOffset = 6;\n const normalizedValue = normalizeRichTextContent(value);\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const latestOnChangeRef = useRef(onChange);\n const lastSerializedValueRef = useRef(normalizedValue);\n const lastFocusSignalRef = useRef(focusSignal);\n const mentionHydrationRequestRef = useRef(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const [isFocused, setIsFocused] = useState(false);\n const [query, setQuery] = useState<RichTextEditorTriggerQueryState | null>(\n null\n );\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n\n latestOnChangeRef.current = onChange;\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak,\n WorkspaceReference.configure({\n removeActionAriaLabel: text.removeReferenceActionLabel\n }),\n MentionReference\n ],\n content: parseRichTextContentToDocument(normalizedValue),\n editorProps: {\n attributes: {\n class: cn(\n \"w-full whitespace-pre-wrap break-words outline-none\",\n textareaClassName\n )\n }\n },\n onBlur() {\n window.setTimeout(() => {\n setIsFocused(false);\n setQuery(null);\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n }, 100);\n },\n onFocus() {\n setIsFocused(true);\n },\n onUpdate({ editor }) {\n const serialized = serializeRichTextDocumentToContent(editor.getJSON());\n lastSerializedValueRef.current = serialized;\n latestOnChangeRef.current(serialized);\n }\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (lastSerializedValueRef.current === normalizedValue) {\n return;\n }\n\n const currentSerialized = serializeRichTextDocumentToContent(\n editor.getJSON()\n );\n if (currentSerialized === normalizedValue) {\n lastSerializedValueRef.current = normalizedValue;\n return;\n }\n\n editor.commands.setContent(\n parseRichTextContentToDocument(normalizedValue),\n {\n emitUpdate: false\n }\n );\n lastSerializedValueRef.current = normalizedValue;\n }, [editor, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const requestId = mentionHydrationRequestRef.current + 1;\n mentionHydrationRequestRef.current = requestId;\n const mentions = collectHydratableMentionNodes(editor);\n if (mentions.length === 0) {\n return;\n }\n\n for (const mention of mentions) {\n const provider = registry.getProvider(mention.attrs.providerId);\n if (!provider?.resolveMention) {\n continue;\n }\n\n void Promise.resolve(provider.resolveMention(mention.attrs))\n .then((resolved) => {\n if (\n !resolved ||\n mentionHydrationRequestRef.current !== requestId ||\n editor.isDestroyed\n ) {\n return;\n }\n\n applyResolvedMentionAttrs(editor, mention.pos, mention.attrs, {\n label: resolved.label,\n presentation: resolved.presentation\n });\n })\n .catch(() => {\n // Resolver failures keep the fallback label-only mention.\n });\n }\n }, [editor, registry, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (Object.is(lastFocusSignalRef.current, focusSignal)) {\n return;\n }\n\n lastFocusSignalRef.current = focusSignal;\n editor.commands.focus(\"end\");\n }, [editor, focusSignal]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n editor.setEditable(!disabled);\n editor.view.dispatch(\n editor.state.tr.setMeta(\"richTextEditable\", !disabled)\n );\n }, [disabled, editor]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const updateQueryState = () => {\n const nextQuery = findEditorAtQuery(editor, activeTriggerConfigs);\n setQuery(nextQuery);\n };\n\n const updateFocus = () => {\n const nextFocused = editor.isFocused;\n setIsFocused(nextFocused);\n updateQueryState();\n };\n\n updateQueryState();\n editor.on(\"selectionUpdate\", updateQueryState);\n editor.on(\"transaction\", updateQueryState);\n editor.on(\"focus\", updateFocus);\n editor.on(\"blur\", updateFocus);\n return () => {\n editor.off(\"selectionUpdate\", updateQueryState);\n editor.off(\"transaction\", updateQueryState);\n editor.off(\"focus\", updateFocus);\n editor.off(\"blur\", updateFocus);\n };\n }, [activeTriggerConfigs, editor]);\n\n useEffect(() => {\n if (!editor || !query || activeTriggerConfigs.length === 0) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n if (query.keyword.length < minQueryLength) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n blockText: editor.state.selection.$from.parent.textBetween(\n 0,\n editor.state.selection.$from.parent.content.size,\n \"\\n\",\n \"\\uFFFC\"\n ),\n documentText: serializeRichTextDocumentToContent(editor.getJSON())\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [\n editor,\n maxResults,\n minQueryLength,\n activeTriggerConfigs.length,\n query,\n registry\n ]);\n\n useLayoutEffect(() => {\n if (!editor || !query) {\n setMenuPoint(null);\n return;\n }\n\n const updateMenuPoint = () => {\n const coords = editor.view.coordsAtPos(editor.state.selection.from);\n const nextMenuPoint = {\n x: coords.left,\n y: coords.bottom + menuOffset\n };\n setMenuPoint(nextMenuPoint);\n };\n\n updateMenuPoint();\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n return () => {\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [editor, menuOffset, query]);\n\n const canQueryTrigger =\n !!query &&\n activeTriggerConfigs.length > 0 &&\n query.keyword.length >= minQueryLength;\n const isMenuOpen = canQueryTrigger && (isFocused || !!menuPoint);\n const isEmpty =\n !editor ||\n serializeRichTextDocumentToContent(editor.getJSON()).trim().length === 0;\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n if (!editor || !query) {\n return;\n }\n\n const content = renderInsertResultAsEditorContent(\n match.providerId,\n match.insertResult\n );\n if (!content) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt({ from: query.from, to: query.to }, content)\n .run();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (!isMenuOpen) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n };\n\n return (\n <div\n className={cn(\"relative min-w-0 w-full\", className)}\n ref={containerRef}\n >\n <div className=\"w-full min-w-0\" onKeyDownCapture={handleKeyDown}>\n <EditorContent editor={editor} />\n </div>\n {isEmpty && placeholder ? (\n <div className=\"pointer-events-none absolute top-0 right-0 left-0 px-0 py-0 text-[var(--text-placeholder)]\">\n <div\n className={cn(\n \"min-w-0 w-full whitespace-pre-wrap\",\n placeholderClassName ?? textareaClassName,\n \"text-[var(--text-placeholder)]\"\n )}\n >\n {placeholder}\n </div>\n </div>\n ) : null}\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n style={menuZIndex === undefined ? undefined : { zIndex: menuZIndex }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n workspaceReferenceFileKind={getWorkspaceReferenceFileKind(\n match.insertResult\n )}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n\nfunction findEditorAtQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const query = findEditorTriggerQuery(editor, triggers);\n if (!query) {\n return null;\n }\n return query;\n}\n\nfunction findEditorTriggerQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const { selection } = editor.state;\n if (!selection.empty) {\n return null;\n }\n\n const { $from } = selection;\n if (!$from.parent.isTextblock) {\n return null;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n \"\\n\",\n \"\\uFFFC\"\n );\n const query = findRichTextTriggerQuery(\n textBeforeCursor,\n textBeforeCursor.length,\n triggers\n );\n if (!query) {\n return null;\n }\n\n const distanceFromQueryStart = textBeforeCursor.length - query.from;\n return {\n from: selection.from - distanceFromQueryStart,\n keyword: query.keyword,\n trigger: query.trigger,\n to: selection.from\n };\n}\n\nfunction renderInsertResultAsEditorContent(\n providerId: string,\n result: RichTextTriggerInsertResult\n) {\n switch (result.kind) {\n case \"mention\":\n return {\n type: mentionReferenceNodeName,\n attrs: createRichTextMentionAttrs(providerId, result.mention)\n };\n case \"markdown-link\": {\n const kind = result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n return {\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label: result.label,\n path: normalizeRichTextLinkHref(result.href, kind)\n }\n };\n }\n case \"text\":\n return result.text;\n default:\n return null;\n }\n}\n\nfunction getWorkspaceReferenceFileKind(\n result: RichTextTriggerInsertResult\n): \"file\" | \"folder\" | undefined {\n if (result.kind !== \"markdown-link\") {\n return undefined;\n }\n return result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n}\n\nfunction collectHydratableMentionNodes(\n editor: TiptapEditor\n): Array<{ attrs: RichTextMentionAttrs; pos: number }> {\n const mentions: Array<{ attrs: RichTextMentionAttrs; pos: number }> = [];\n\n editor.state.doc.descendants((node, pos) => {\n if (node.type.name !== mentionReferenceNodeName) {\n return;\n }\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.trigger !== \"@\" ||\n typeof attrs.providerId !== \"string\" ||\n !attrs.providerId.trim() ||\n typeof attrs.entityId !== \"string\" ||\n !attrs.entityId.trim() ||\n typeof attrs.label !== \"string\" ||\n !attrs.label.trim()\n ) {\n return;\n }\n\n mentions.push({\n pos,\n attrs: {\n trigger: \"@\",\n providerId: attrs.providerId.trim(),\n entityId: attrs.entityId.trim(),\n label: attrs.label.trim().replace(/^@+/, \"\").trim(),\n scope: normalizeMentionStringRecord(attrs.scope),\n presentation: normalizeMentionPresentation(attrs.presentation)\n }\n });\n });\n\n return mentions;\n}\n\nfunction applyResolvedMentionAttrs(\n editor: TiptapEditor,\n pos: number,\n currentAttrs: RichTextMentionAttrs,\n resolved: {\n label?: string;\n presentation?: RichTextMentionPresentation;\n }\n): void {\n const node = editor.state.doc.nodeAt(pos);\n if (!node || node.type.name !== mentionReferenceNodeName) {\n return;\n }\n\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.providerId !== currentAttrs.providerId ||\n attrs.entityId !== currentAttrs.entityId ||\n JSON.stringify(normalizeMentionStringRecord(attrs.scope) ?? {}) !==\n JSON.stringify(currentAttrs.scope ?? {})\n ) {\n return;\n }\n\n const nextLabel = resolved.label?.trim().replace(/^@+/, \"\").trim();\n const nextPresentation = normalizeMentionPresentation(resolved.presentation);\n const nextAttrs: RichTextMentionAttrs = {\n trigger: \"@\",\n providerId: currentAttrs.providerId,\n entityId: currentAttrs.entityId,\n label: nextLabel || currentAttrs.label,\n scope: currentAttrs.scope,\n presentation: nextPresentation ?? currentAttrs.presentation\n };\n\n if (\n attrs.label === nextAttrs.label &&\n JSON.stringify(normalizeMentionPresentation(attrs.presentation) ?? {}) ===\n JSON.stringify(nextAttrs.presentation ?? {})\n ) {\n return;\n }\n\n const transaction = editor.state.tr.setNodeMarkup(pos, undefined, nextAttrs);\n transaction.setMeta(\"addToHistory\", false);\n transaction.setMeta(\"preventUpdate\", true);\n editor.view.dispatch(transaction);\n}\n\nfunction normalizeMentionStringRecord(\n value: unknown\n): Readonly<Record<string, string>> | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .map(\n ([key, entryValue]) =>\n [\n key.trim(),\n typeof entryValue === \"string\" ? entryValue.trim() : \"\"\n ] as const\n )\n .filter(([key, entryValue]) => key.length > 0 && entryValue.length > 0)\n .sort(([left], [right]) => left.localeCompare(right));\n\n return entries.length > 0\n ? Object.freeze(Object.fromEntries(entries))\n : undefined;\n}\n\nfunction normalizeMentionPresentation(\n value: unknown\n): RichTextMentionPresentation | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const source = value as Record<keyof RichTextMentionPresentation, unknown>;\n const next: RichTextMentionPresentation = {};\n\n for (const key of RICH_TEXT_MENTION_PRESENTATION_KEYS) {\n const fieldValue = source[key];\n if (typeof fieldValue !== \"string\") {\n continue;\n }\n const trimmed = fieldValue.trim();\n if (trimmed) {\n next[key] = trimmed;\n }\n }\n\n return Object.keys(next).length > 0 ? Object.freeze(next) : undefined;\n}\n","import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nexport interface RichTextTriggerQueryState {\n from: number;\n to: number;\n keyword: string;\n trigger: RichTextTrigger;\n}\n\nexport function isRichTextTriggerPrefixBoundary(\n character: string,\n boundary: RichTextTriggerBoundary\n): boolean {\n if (boundary === \"whitespace\") {\n return /\\s/.test(character);\n }\n return /[\\s,;:!?<>{}|\\\\'\"`~()[\\]]/.test(character);\n}\n\nexport function findRichTextTriggerQuery(\n value: string,\n caret: number,\n triggerConfigs: readonly RichTextTriggerConfig[]\n): RichTextTriggerQueryState | null {\n const cursor = Math.max(0, Math.min(caret, value.length));\n if (triggerConfigs.length === 0) {\n return null;\n }\n let segmentStart = cursor;\n while (segmentStart > 0) {\n const previous = value[segmentStart - 1] ?? \"\";\n if (/\\s/.test(previous)) {\n break;\n }\n segmentStart -= 1;\n }\n\n const segment = value.slice(segmentStart, cursor);\n for (let index = segment.length - 1; index >= 0; index -= 1) {\n const trigger = segment[index] as RichTextTrigger;\n const matchingConfigs = triggerConfigs.filter(\n (config) => config.trigger === trigger\n );\n if (matchingConfigs.length === 0) {\n continue;\n }\n const previous = segment[index - 1] ?? \"\";\n if (\n index > 0 &&\n !matchingConfigs.some((config) =>\n isRichTextTriggerPrefixBoundary(previous, config.boundary)\n )\n ) {\n continue;\n }\n\n const candidate = segment.slice(index);\n if (/[[\\]()]/.test(candidate.slice(1))) {\n return null;\n }\n\n return {\n from: segmentStart + index,\n to: cursor,\n trigger,\n keyword: candidate.slice(1)\n };\n }\n\n return null;\n}\n\nexport async function queryRichTextTriggerMatches(\n registry: RichTextTriggerRegistry,\n input: RichTextTriggerQueryInput\n): Promise<readonly RichTextTriggerQueryMatch[]> {\n try {\n return await registry.query(input);\n } catch {\n return [];\n }\n}\n","export interface RichTextImeKeyboardEventLike {\n isComposing?: boolean;\n keyCode?: number;\n nativeEvent?: {\n isComposing?: boolean;\n keyCode?: number;\n which?: number;\n };\n which?: number;\n}\n\nexport function isRichTextImeComposing(\n event: RichTextImeKeyboardEventLike\n): boolean {\n if (event.isComposing || event.nativeEvent?.isComposing) {\n return true;\n }\n\n const keyCode = event.keyCode ?? event.nativeEvent?.keyCode;\n const which = event.which ?? event.nativeEvent?.which;\n return keyCode === 229 || which === 229;\n}\n","import {\n createDefaultRichTextI18nRuntime,\n type RichTextI18nRuntime\n} from \"../i18n/richTextI18n.ts\";\n\nexport interface RichTextTriggerTextOverrides {\n loadingLabel?: string;\n noMatchesLabel?: string;\n removeReferenceActionLabel?: string;\n}\n\nexport interface ResolvedRichTextTriggerText {\n loadingLabel: string;\n noMatchesLabel: string;\n removeReferenceActionLabel: string;\n}\n\nconst defaultRichTextI18n = createDefaultRichTextI18nRuntime();\n\nexport function resolveRichTextTriggerText(\n overrides?: RichTextTriggerTextOverrides,\n removeDecorationAriaLabel?: string,\n i18n: RichTextI18nRuntime = defaultRichTextI18n\n): ResolvedRichTextTriggerText {\n return {\n loadingLabel:\n overrides?.loadingLabel?.trim() || i18n.t(\"richTextAt.loading\"),\n noMatchesLabel:\n overrides?.noMatchesLabel?.trim() || i18n.t(\"richTextAt.noMatches\"),\n removeReferenceActionLabel:\n removeDecorationAriaLabel?.trim() ||\n overrides?.removeReferenceActionLabel?.trim() ||\n i18n.t(\"richTextAt.removeReferenceActionLabel\")\n };\n}\n\nexport const defaultRichTextTriggerText = resolveRichTextTriggerText();\n","import type { JSX, MouseEvent } from \"react\";\nimport { FileIcon, FolderFilledIcon } from \"@tutti-os/ui-system/icons\";\n\ntype RichTextTriggerMenuItemProps = {\n iconUrl?: string;\n label: string;\n selected: boolean;\n subtitle?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n onSelect: () => void;\n};\n\nexport function RichTextTriggerMenuItem({\n iconUrl,\n label,\n selected,\n subtitle,\n workspaceReferenceFileKind,\n onSelect\n}: RichTextTriggerMenuItemProps): JSX.Element {\n return (\n <button\n aria-selected={selected}\n className={[\n \"flex w-full cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-[var(--text-primary)] outline-0 transition-colors duration-100\",\n selected ? \"bg-[var(--transparency-block)]\" : \"\",\n \"hover:bg-[var(--transparency-block)]\"\n ].join(\" \")}\n type=\"button\"\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n onSelect();\n }}\n >\n <RichTextTriggerMenuIcon\n iconUrl={iconUrl}\n workspaceReferenceFileKind={workspaceReferenceFileKind}\n />\n <span className=\"flex min-w-0 flex-auto flex-col items-start gap-0.5\">\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[13px] leading-5 font-semibold\">\n {label}\n </span>\n {subtitle ? (\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[11px] leading-4 text-[var(--text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </span>\n </button>\n );\n}\n\nfunction RichTextTriggerMenuIcon({\n iconUrl,\n workspaceReferenceFileKind\n}: {\n iconUrl?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n}): JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n\n if (workspaceReferenceFileKind) {\n const Icon =\n workspaceReferenceFileKind === \"folder\" ? FolderFilledIcon : FileIcon;\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center text-[var(--folder)]\"\n data-rich-text-trigger-icon=\"true\"\n >\n <Icon className=\"size-4\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center overflow-hidden rounded bg-[var(--bg-block,var(--transparency-block))]\"\n data-rich-text-trigger-icon=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n alt=\"\"\n className=\"block size-full object-cover object-center\"\n decoding=\"async\"\n draggable={false}\n loading=\"lazy\"\n src={normalizedIconUrl}\n />\n ) : (\n <span className=\"block size-3 rounded-[3px] bg-[var(--transparency-block)]\" />\n )}\n </span>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { mentionReferenceNodeName } from \"./names.ts\";\nimport { MentionReferenceNodeView } from \"./MentionReferenceNodeView.tsx\";\n\nexport interface MentionReferenceAttrs {\n entityId: string;\n label: string;\n presentation?: Readonly<Record<string, string>>;\n providerId: string;\n scope?: Readonly<Record<string, string>>;\n trigger: \"@\";\n}\n\nexport const MentionReference = Node.create({\n name: mentionReferenceNodeName,\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n entityId: {\n default: \"\"\n },\n label: {\n default: \"\"\n },\n presentation: {\n default: null\n },\n providerId: {\n default: \"\"\n },\n scope: {\n default: null\n },\n trigger: {\n default: \"@\"\n }\n };\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-mention-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const displayLabel = label.trim().replace(/^@+/, \"\").trim();\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-mention-reference\": \"true\",\n class:\n \"inline-flex max-w-full items-center overflow-hidden rounded-md bg-transparency-block px-1.5 py-0.5 align-baseline text-[13px] font-medium text-[var(--text-primary)]\"\n }),\n displayLabel ? `@${displayLabel}` : \"\"\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MentionReferenceNodeView, {\n as: \"span\",\n className: \"inline-flex max-w-full align-baseline\"\n });\n }\n});\n","import type { JSX } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\n\nfunction readMentionPresentationUrl(presentation: unknown): string | null {\n if (!presentation || typeof presentation !== \"object\") {\n return null;\n }\n const value =\n (presentation as { iconUrl?: unknown; thumbnailUrl?: unknown }).iconUrl ??\n (presentation as { thumbnailUrl?: unknown }).thumbnailUrl;\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nexport function MentionReferenceNodeView({\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const label =\n typeof node.attrs.label === \"string\"\n ? node.attrs.label.trim().replace(/^@+/, \"\").trim()\n : \"\";\n const iconUrl = readMentionPresentationUrl(node.attrs.presentation);\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={selected ? \"is-selected\" : undefined}\n contentEditable={false}\n data-rich-text-mention-reference=\"true\"\n >\n <span\n className={[\n \"inline-flex max-w-full items-center gap-1 overflow-hidden rounded-md px-[7px] py-0.5 text-[13px] leading-[18px] font-semibold align-baseline text-[var(--text-primary)]\",\n selected\n ? \"bg-[var(--background-fronted)] shadow-[var(--shadow-soft,0_1px_2px_rgb(0_0_0/8%))]\"\n : \"bg-[var(--transparency-block)]\"\n ].join(\" \")}\n data-rich-text-mention-chip=\"true\"\n >\n {iconUrl ? (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center overflow-hidden rounded\"\n data-rich-text-mention-icon=\"true\"\n >\n <img\n alt=\"\"\n className=\"block size-full object-cover object-center\"\n decoding=\"async\"\n draggable={false}\n loading=\"lazy\"\n src={iconUrl}\n />\n </span>\n ) : null}\n {label ? (iconUrl ? label : `@${label}`) : \"\"}\n </span>\n </NodeViewWrapper>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { workspaceReferenceNodeName } from \"./names.ts\";\nimport { WorkspaceReferenceNodeView } from \"./WorkspaceReferenceNodeView.tsx\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nexport interface WorkspaceReferenceAttrs {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport const WorkspaceReference = Node.create({\n name: workspaceReferenceNodeName,\n addOptions() {\n return {\n removeActionAriaLabel:\n defaultRichTextTriggerText.removeReferenceActionLabel\n };\n },\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n kind: {\n default: \"file\"\n },\n label: {\n default: \"\"\n },\n path: {\n default: \"\"\n }\n } satisfies Record<keyof WorkspaceReferenceAttrs, { default: string }>;\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-workspace-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const kind = HTMLAttributes.kind === \"folder\" ? \"folder\" : \"file\";\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const path =\n typeof HTMLAttributes.path === \"string\" ? HTMLAttributes.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const referenceColorClassName =\n kind === \"folder\"\n ? \"text-[var(--rich-text-folder)]\"\n : \"text-[var(--rich-text-mention-file)]\";\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-workspace-reference\": \"true\",\n \"data-rich-text-workspace-kind\": kind,\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": \"file\",\n \"data-slot\": \"mention-pill\",\n title: presentation.fullPath,\n class: [\n \"group relative top-[3px] inline-flex max-w-full cursor-default items-center gap-1.5 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1.5 py-0.5 align-baseline text-[13px] font-medium leading-5 no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]\",\n referenceColorClassName\n ].join(\" \")\n }),\n [\n \"span\",\n {\n \"aria-hidden\": \"true\",\n class: \"grid size-4 shrink-0 place-items-center text-current\"\n },\n kind === \"folder\" ? \"D\" : \"F\"\n ],\n [\n \"span\",\n {\n class: \"min-w-0 max-w-[20rem] truncate text-[13px] font-medium\"\n },\n presentation.displayLabel\n ]\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(WorkspaceReferenceNodeView);\n }\n});\n","import { useEffect, useState, type JSX, type PointerEvent } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function WorkspaceReferenceNodeView({\n deleteNode,\n editor,\n extension,\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const [isEditable, setIsEditable] = useState(editor.isEditable);\n const attrs = node.attrs as {\n kind?: string;\n label?: string;\n path?: string;\n };\n const extensionOptions = extension.options as {\n removeActionAriaLabel?: string;\n };\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const label = typeof attrs.label === \"string\" ? attrs.label : \"\";\n const path = typeof attrs.path === \"string\" ? attrs.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const removeActionAriaLabel =\n typeof extensionOptions.removeActionAriaLabel === \"string\"\n ? extensionOptions.removeActionAriaLabel\n : defaultRichTextTriggerText.removeReferenceActionLabel;\n\n useEffect(() => {\n const syncEditable = () => {\n setIsEditable(editor.isEditable);\n };\n\n syncEditable();\n editor.on(\"transaction\", syncEditable);\n editor.on(\"update\", syncEditable);\n return () => {\n editor.off(\"transaction\", syncEditable);\n editor.off(\"update\", syncEditable);\n };\n }, [editor]);\n\n const handleRemove = (event: PointerEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!editor.isEditable) {\n return;\n }\n deleteNode();\n };\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline ${\n selected ? \"is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-workspace-reference=\"true\"\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={isEditable}\n removeButtonProps={\n isEditable\n ? {\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: handleRemove,\n tabIndex: -1\n }\n : undefined\n }\n />\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n </NodeViewWrapper>\n );\n}\n","export interface WorkspaceReferencePresentation {\n displayLabel: string;\n fullPath: string;\n}\n\nexport function getWorkspaceReferencePresentation(\n label: string,\n path: string\n): WorkspaceReferencePresentation {\n const displayLabel = normalizeReferenceLabel(label, path);\n const fullPath = normalizeFullPath(path);\n\n return {\n displayLabel,\n fullPath\n };\n}\n\nfunction normalizeReferenceLabel(label: string, path: string): string {\n const trimmedLabel = label.trim();\n\n if (trimmedLabel !== \"\") {\n return trimmedLabel;\n }\n\n return getPathBasename(path) || path.trim();\n}\n\nfunction normalizeFullPath(path: string): string {\n return trimTrailingSeparators(path.trim());\n}\n\nfunction getPathBasename(path: string): string {\n const normalizedPath = trimTrailingSeparators(path.trim());\n\n if (normalizedPath === \"\" || isPathRoot(normalizedPath)) {\n return normalizedPath;\n }\n\n const segments = normalizedPath.split(/[\\\\/]+/).filter(Boolean);\n\n return segments.at(-1) ?? \"\";\n}\n\nfunction trimTrailingSeparators(path: string): string {\n if (path === \"\") {\n return \"\";\n }\n\n if (isPathRoot(path)) {\n return path;\n }\n\n return path.replace(/[\\\\/]+$/, \"\");\n}\n\nfunction isPathRoot(path: string): boolean {\n return (\n path === \"/\" ||\n path === \"\\\\\" ||\n path === \"//\" ||\n path === \"\\\\\\\\\" ||\n /^[A-Za-z]:[\\\\/]?$/.test(path)\n );\n}\n","import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type PointerEvent,\n type ReactNode,\n type JSX,\n type KeyboardEvent\n} from \"react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport { renderRichTextTriggerInsertResult } from \"../plugins/trigger.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch\n} from \"../types/trigger.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n buildRichTextTextareaDecorationSegments,\n getTextareaPresentationStyle,\n hasRichTextTextareaDecorations,\n resolveRichTextTextareaSelectionBoundary\n} from \"./richTextTextareaDecorationModel.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { RichTextTextareaDecoratedContent } from \"./richTextTextareaDecorations.tsx\";\nimport { getTextareaCaretViewportPoint } from \"./richTextTextareaCaret.ts\";\nimport type { CSSProperties } from \"react\";\n\nexport interface RichTextTriggerTextareaProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n rows?: number;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n}\n\nexport function RichTextTriggerTextarea({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n rows,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay\n}: RichTextTriggerTextareaProps): JSX.Element {\n const menuOffset = 6;\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [selectionStart, setSelectionStart] = useState(0);\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n const [scrollPosition, setScrollPosition] = useState({ left: 0, top: 0 });\n const [textareaPresentationStyle, setTextareaPresentationStyle] =\n useState<CSSProperties | null>(null);\n const pendingSelectionRef = useRef<number | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const decorationSegments = useMemo(\n () => buildRichTextTextareaDecorationSegments(value),\n [value]\n );\n const hasDecorations = hasRichTextTextareaDecorations(decorationSegments);\n const query = useMemo(\n () =>\n isFocused\n ? findRichTextTriggerQuery(value, selectionStart, activeTriggerConfigs)\n : null,\n [activeTriggerConfigs, isFocused, selectionStart, value]\n );\n const shouldQuery =\n query !== null &&\n query.keyword.length >= minQueryLength &&\n activeTriggerConfigs.length > 0;\n const isMenuOpen =\n isFocused && shouldQuery && (isLoading || matches.length > 0);\n\n useEffect(() => {\n const nextSelection = pendingSelectionRef.current;\n if (nextSelection === null || !textareaRef.current) {\n return;\n }\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }, [value]);\n\n useEffect(() => {\n if (!shouldQuery || !query) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n documentText: value,\n blockText: value\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [maxResults, query, registry, shouldQuery, value]);\n\n useLayoutEffect(() => {\n if (!textareaRef.current || !hasDecorations) {\n setTextareaPresentationStyle(null);\n return;\n }\n\n const textarea = textareaRef.current;\n setTextareaPresentationStyle(getTextareaPresentationStyle(textarea));\n setScrollPosition({\n left: textarea.scrollLeft,\n top: textarea.scrollTop\n });\n }, [hasDecorations, textareaClassName, value]);\n\n useLayoutEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n setMenuPoint(null);\n return;\n }\n\n const caretPoint = getTextareaCaretViewportPoint(\n textareaRef.current,\n query.to\n );\n const textareaRect = textareaRef.current.getBoundingClientRect();\n\n if (!caretPoint) {\n setMenuPoint({\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n });\n return;\n }\n\n setMenuPoint({\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n });\n }, [isMenuOpen, menuOffset, query, selectionStart, value]);\n\n useEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n return;\n }\n\n const textarea = textareaRef.current;\n const updateMenuPoint = () => {\n const caretPoint = getTextareaCaretViewportPoint(textarea, query.to);\n const textareaRect = textarea.getBoundingClientRect();\n\n setMenuPoint(\n caretPoint\n ? {\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n }\n : {\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n }\n );\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => {\n updateMenuPoint();\n });\n resizeObserver?.observe(textarea);\n textarea.addEventListener(\"scroll\", updateMenuPoint, { passive: true });\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n\n return () => {\n resizeObserver?.disconnect();\n textarea.removeEventListener(\"scroll\", updateMenuPoint);\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [isMenuOpen, menuOffset, query]);\n\n const closeMenu = () => {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const setSelection = (nextSelection: number) => {\n pendingSelectionRef.current = nextSelection;\n setSelectionStart(nextSelection);\n if (textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }\n };\n\n const handleClickDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => {\n event.preventDefault();\n const bounds = event.currentTarget.getBoundingClientRect();\n const nextSelection =\n event.clientX < bounds.left + bounds.width / 2\n ? segment.from\n : segment.to;\n setSelection(nextSelection);\n };\n\n const handleRemoveDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>\n ) => {\n const nextValue = `${value.slice(0, segment.from)}${value.slice(segment.to)}`;\n const nextSelection = Math.min(segment.from, nextValue.length);\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n setSelectionStart(nextSelection);\n window.requestAnimationFrame(() => {\n if (!textareaRef.current) {\n return;\n }\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n });\n };\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n const currentQuery = findRichTextTriggerQuery(\n value,\n textareaRef.current?.selectionStart ?? selectionStart,\n activeTriggerConfigs\n );\n if (!currentQuery) {\n return;\n }\n const insertedValue = renderRichTextTriggerInsertResult(\n match.providerId,\n match.insertResult\n );\n const nextValue = `${value.slice(0, currentQuery.from)}${insertedValue}${value.slice(currentQuery.to)}`;\n const nextSelection = currentQuery.from + insertedValue.length;\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n closeMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n closeMenu();\n }\n };\n\n return (\n <div className={cn(\"relative min-w-0 w-full\", className)}>\n {hasDecorations && textareaPresentationStyle ? (\n <RichTextTextareaDecoratedContent\n onClickSegment={handleClickDecoration}\n onRemoveSegment={handleRemoveDecoration}\n removeActionAriaLabel={text.removeReferenceActionLabel}\n scrollLeft={scrollPosition.left}\n scrollTop={scrollPosition.top}\n segments={decorationSegments}\n textareaStyle={textareaPresentationStyle}\n />\n ) : null}\n <textarea\n ref={textareaRef}\n className={textareaClassName}\n disabled={disabled}\n placeholder={placeholder}\n rows={rows}\n style={\n hasDecorations\n ? {\n WebkitTextFillColor: \"transparent\",\n caretColor: \"var(--text-primary)\",\n color: \"transparent\",\n position: \"relative\",\n zIndex: 0\n }\n : undefined\n }\n value={value}\n onBlur={() => {\n window.setTimeout(() => {\n setIsFocused(false);\n closeMenu();\n }, 100);\n }}\n onChange={(event) => {\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n onChange(event.target.value);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n setScrollPosition({\n left: event.target.scrollLeft,\n top: event.target.scrollTop\n });\n }}\n onKeyDown={handleKeyDown}\n onScroll={(event) => {\n setScrollPosition({\n left: event.currentTarget.scrollLeft,\n top: event.currentTarget.scrollTop\n });\n }}\n onSelect={(event) => {\n const rawSelectionStart = event.currentTarget.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.currentTarget.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n }}\n />\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n dismissIgnoreRefs={[textareaRef]}\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\n\nconst TEXTAREA_PRESENTATION_STYLE_PROPERTIES = [\n { styleName: \"paddingTop\", cssName: \"padding-top\" },\n { styleName: \"paddingRight\", cssName: \"padding-right\" },\n { styleName: \"paddingBottom\", cssName: \"padding-bottom\" },\n { styleName: \"paddingLeft\", cssName: \"padding-left\" },\n { styleName: \"fontFamily\", cssName: \"font-family\" },\n { styleName: \"fontFeatureSettings\", cssName: \"font-feature-settings\" },\n { styleName: \"fontKerning\", cssName: \"font-kerning\" },\n { styleName: \"fontOpticalSizing\", cssName: \"font-optical-sizing\" },\n { styleName: \"fontSize\", cssName: \"font-size\" },\n { styleName: \"fontStretch\", cssName: \"font-stretch\" },\n { styleName: \"fontStyle\", cssName: \"font-style\" },\n { styleName: \"fontVariant\", cssName: \"font-variant\" },\n { styleName: \"fontVariationSettings\", cssName: \"font-variation-settings\" },\n { styleName: \"fontWeight\", cssName: \"font-weight\" },\n { styleName: \"letterSpacing\", cssName: \"letter-spacing\" },\n { styleName: \"lineHeight\", cssName: \"line-height\" },\n { styleName: \"textAlign\", cssName: \"text-align\" },\n { styleName: \"textIndent\", cssName: \"text-indent\" },\n { styleName: \"textTransform\", cssName: \"text-transform\" },\n { styleName: \"tabSize\", cssName: \"tab-size\" },\n { styleName: \"MozTabSize\", cssName: \"-moz-tab-size\" }\n] as const satisfies readonly {\n styleName: keyof CSSProperties;\n cssName: string;\n}[];\n\ntype RichTextTextareaTextDecorationSegment = {\n type: \"text\";\n text: string;\n from: number;\n to: number;\n};\n\ntype RichTextTextareaLinkDecorationSegment = {\n type: \"link\";\n text: string;\n from: number;\n to: number;\n label: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextTextareaDecorationSegment =\n | RichTextTextareaTextDecorationSegment\n | RichTextTextareaLinkDecorationSegment;\n\nfunction isDecoratableMarkdownHref(href: string): boolean {\n const trimmedHref = href.trim();\n if (!trimmedHref) {\n return false;\n }\n if (\n EXTERNAL_LINK_PREFIX.test(trimmedHref) ||\n MENTION_LINK_PREFIX.test(trimmedHref)\n ) {\n return false;\n }\n return true;\n}\n\nexport function buildRichTextTextareaDecorationSegments(\n value: string\n): RichTextTextareaDecorationSegment[] {\n const segments: RichTextTextareaDecorationSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const { index, source, to } = match;\n\n if (index > cursor) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor, index),\n from: cursor,\n to: index\n });\n }\n\n if (label && href && isDecoratableMarkdownHref(href)) {\n segments.push({\n type: \"link\",\n text: source,\n from: index,\n to,\n label,\n href,\n kind: href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n } else {\n segments.push({\n type: \"text\",\n text: source,\n from: index,\n to\n });\n }\n\n cursor = to;\n }\n\n if (cursor < value.length) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor),\n from: cursor,\n to: value.length\n });\n }\n\n return segments;\n}\n\nexport function hasRichTextTextareaDecorations(\n segments: readonly RichTextTextareaDecorationSegment[]\n): boolean {\n return segments.some((segment) => segment.type === \"link\");\n}\n\nexport function resolveRichTextTextareaSelectionBoundary(\n segments: readonly RichTextTextareaDecorationSegment[],\n selectionStart: number\n): number | null {\n for (const segment of segments) {\n if (segment.type !== \"link\") {\n continue;\n }\n if (selectionStart <= segment.from || selectionStart >= segment.to) {\n continue;\n }\n const midpoint = segment.from + (segment.to - segment.from) / 2;\n return selectionStart < midpoint ? segment.from : segment.to;\n }\n return null;\n}\n\nfunction setTextareaPresentationStyleValue<K extends keyof CSSProperties>(\n styleRecord: CSSProperties,\n styleName: K,\n value: string\n): void {\n styleRecord[styleName] = value as CSSProperties[K];\n}\n\nexport function getTextareaPresentationStyle(\n textarea: HTMLTextAreaElement\n): CSSProperties {\n const computedStyle = window.getComputedStyle(textarea);\n const styleRecord: CSSProperties = {\n whiteSpace: \"pre-wrap\"\n };\n\n setTextareaPresentationStyleValue(\n styleRecord,\n \"wordBreak\",\n computedStyle.wordBreak\n );\n setTextareaPresentationStyleValue(\n styleRecord,\n \"overflowWrap\",\n computedStyle.overflowWrap\n );\n\n for (const { styleName, cssName } of TEXTAREA_PRESENTATION_STYLE_PROPERTIES) {\n setTextareaPresentationStyleValue(\n styleRecord,\n styleName,\n computedStyle.getPropertyValue(cssName)\n );\n }\n\n return styleRecord;\n}\n","import type { CSSProperties, JSX, PointerEvent } from \"react\";\nimport { MentionPill } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport type { RichTextTextareaDecorationSegment } from \"./richTextTextareaDecorationModel.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextTextareaDecoratedContent({\n onClickSegment,\n onRemoveSegment,\n removeActionAriaLabel,\n scrollLeft,\n scrollTop,\n segments,\n textareaStyle\n}: {\n onClickSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => void;\n onRemoveSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>\n ) => void;\n removeActionAriaLabel?: string;\n scrollLeft: number;\n scrollTop: number;\n segments: readonly RichTextTextareaDecorationSegment[];\n textareaStyle: CSSProperties;\n}): JSX.Element {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-10 overflow-hidden\">\n <div\n className=\"min-h-full min-w-full\"\n style={{\n ...textareaStyle,\n transform: `translate(${-scrollLeft}px, ${-scrollTop}px)`\n }}\n >\n {segments.map((segment, index) => {\n if (segment.type === \"text\") {\n return <span key={index}>{segment.text}</span>;\n }\n\n return (\n <span key={index} className=\"relative\">\n <span aria-hidden=\"true\" className=\"text-transparent\">\n {segment.text}\n </span>\n <MentionPill\n className={cn(\n \"pointer-events-auto absolute inset-y-0 left-0 pr-1 pl-1.5\",\n richTextWorkspaceReferencePillClassName\n )}\n fileKind={segment.kind}\n kind=\"file\"\n label={segment.label}\n removeButtonProps={{\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: (event) => {\n event.preventDefault();\n event.stopPropagation();\n onRemoveSegment(segment);\n }\n }}\n summary={\n <span\n className={cn(\n \"min-w-0 truncate text-[11px] text-current opacity-80\",\n segment.kind === \"folder\"\n ? \"max-w-[18rem]\"\n : \"max-w-[20rem]\"\n )}\n >\n {segment.href}\n </span>\n }\n onPointerDown={(event) => {\n onClickSegment(segment, event);\n }}\n />\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","const TEXTAREA_MIRROR_STYLE_PROPERTIES = [\n \"boxSizing\",\n \"width\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"borderTopStyle\",\n \"borderRightStyle\",\n \"borderBottomStyle\",\n \"borderLeftStyle\",\n \"borderTopColor\",\n \"borderRightColor\",\n \"borderBottomColor\",\n \"borderLeftColor\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontFeatureSettings\",\n \"fontKerning\",\n \"fontOpticalSizing\",\n \"fontSize\",\n \"fontStretch\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontVariationSettings\",\n \"fontWeight\",\n \"letterSpacing\",\n \"lineHeight\",\n \"textAlign\",\n \"textDecoration\",\n \"textIndent\",\n \"textTransform\",\n \"wordBreak\",\n \"overflowWrap\",\n \"tabSize\",\n \"MozTabSize\"\n] as const;\n\nexport interface TextareaCaretViewportPoint {\n x: number;\n y: number;\n lineHeight: number;\n}\n\nfunction parsePixelValue(value: string | null | undefined): number | null {\n if (!value || value === \"normal\") {\n return null;\n }\n\n const parsedValue = Number.parseFloat(value);\n return Number.isFinite(parsedValue) ? parsedValue : null;\n}\n\nfunction resolveLineHeight(computedStyle: CSSStyleDeclaration): number {\n const explicitLineHeight = parsePixelValue(computedStyle.lineHeight);\n if (explicitLineHeight !== null) {\n return explicitLineHeight;\n }\n\n const fontSize = parsePixelValue(computedStyle.fontSize);\n return fontSize !== null ? fontSize * 1.4 : 20;\n}\n\nexport function getTextareaCaretViewportPoint(\n textarea: HTMLTextAreaElement,\n selectionStart: number\n): TextareaCaretViewportPoint | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const safeSelectionStart = Math.max(\n 0,\n Math.min(selectionStart, textarea.value.length)\n );\n const textareaRect = textarea.getBoundingClientRect();\n const computedStyle = window.getComputedStyle(textarea);\n const mirror = document.createElement(\"div\");\n const marker = document.createElement(\"span\");\n\n mirror.setAttribute(\"aria-hidden\", \"true\");\n mirror.style.position = \"fixed\";\n mirror.style.left = `${textareaRect.left}px`;\n mirror.style.top = `${textareaRect.top}px`;\n mirror.style.visibility = \"hidden\";\n mirror.style.pointerEvents = \"none\";\n mirror.style.overflow = \"hidden\";\n\n for (const propertyName of TEXTAREA_MIRROR_STYLE_PROPERTIES) {\n (mirror.style as CSSStyleDeclaration & Record<string, string>)[\n propertyName\n ] =\n (\n computedStyle as CSSStyleDeclaration &\n Record<string, string | undefined>\n )[propertyName] ?? \"\";\n }\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordBreak = computedStyle.wordBreak;\n mirror.style.overflowWrap = computedStyle.overflowWrap;\n\n const preSelectionText = textarea.value.slice(0, safeSelectionStart);\n mirror.textContent = preSelectionText.length > 0 ? preSelectionText : \"\";\n if (preSelectionText.endsWith(\"\\n\")) {\n mirror.append(document.createTextNode(\"\\u200b\"));\n }\n\n marker.textContent = \"\\u200b\";\n mirror.append(marker);\n document.body.append(mirror);\n\n try {\n const markerRect = marker.getBoundingClientRect();\n const lineHeight = resolveLineHeight(computedStyle);\n\n return {\n x: markerRect.left - textarea.scrollLeft,\n y: markerRect.top - textarea.scrollTop,\n lineHeight\n };\n } finally {\n mirror.remove();\n }\n}\n","import type { CSSProperties, JSX, MouseEvent, ReactNode } from \"react\";\nimport {\n getRichTextMentionDisplayText,\n resolveRichTextMentionView\n} from \"../plugins/mention.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nexport interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved: RichTextResolvedMentionView<TResolved>;\n}\n\nexport interface RichTextMentionReadonlyProps<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved?: RichTextResolvedMention<TResolved> | null;\n className?: string;\n title?: string;\n onClick?: (payload: RichTextMentionReadonlyClickPayload<TResolved>) => void;\n renderLabel?: (\n payload: RichTextMentionReadonlyClickPayload<TResolved>\n ) => ReactNode;\n}\n\nconst baseStyle: CSSProperties = {\n alignItems: \"center\",\n border: \"1px solid transparent\",\n borderRadius: \"999px\",\n display: \"inline-flex\",\n fontSize: \"0.95em\",\n gap: \"0.25rem\",\n lineHeight: 1.4,\n maxWidth: \"100%\",\n padding: \"0.05rem 0.45rem\",\n textDecoration: \"none\",\n verticalAlign: \"baseline\",\n whiteSpace: \"nowrap\"\n};\n\nconst stateStyles: Record<RichTextResolvedMentionView[\"state\"], CSSProperties> =\n {\n active: {\n background:\n \"var(--tutti-rich-text-mention-active-bg, color-mix(in srgb, currentColor 12%, transparent))\",\n color: \"var(--tutti-rich-text-mention-active-fg, inherit)\",\n cursor: \"pointer\"\n },\n missing: {\n background:\n \"var(--tutti-rich-text-mention-missing-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-missing-fg, color-mix(in srgb, currentColor 48%, transparent))\",\n cursor: \"default\",\n textDecoration: \"line-through\"\n },\n disabled: {\n background:\n \"var(--tutti-rich-text-mention-disabled-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-disabled-fg, color-mix(in srgb, currentColor 58%, transparent))\",\n cursor: \"not-allowed\",\n opacity: 0.88\n },\n loading: {\n background:\n \"var(--tutti-rich-text-mention-loading-bg, color-mix(in srgb, currentColor 8%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-loading-fg, color-mix(in srgb, currentColor 82%, transparent))\",\n cursor: \"progress\",\n opacity: 0.92\n }\n };\n\nfunction joinClassNames(\n ...parts: Array<string | null | undefined | false>\n): string | undefined {\n const value = parts.filter(Boolean).join(\" \").trim();\n return value || undefined;\n}\n\nexport function RichTextMentionReadonly<TResolved = unknown>({\n mention,\n resolved,\n className,\n title,\n onClick,\n renderLabel\n}: RichTextMentionReadonlyProps<TResolved>): JSX.Element {\n const view = resolveRichTextMentionView(mention, resolved);\n const payload: RichTextMentionReadonlyClickPayload<TResolved> = {\n mention,\n resolved: view as RichTextResolvedMentionView<TResolved>\n };\n const label =\n renderLabel?.(payload) ??\n getRichTextMentionDisplayText({\n ...mention,\n label: view.label\n });\n const elementTitle = title ?? view.tooltip;\n const handleClick = (event: MouseEvent<HTMLElement>) => {\n if (!view.interactive) {\n event.preventDefault();\n return;\n }\n onClick?.(payload);\n };\n\n const sharedProps = {\n \"aria-busy\": view.state === \"loading\" || undefined,\n \"aria-disabled\": !view.interactive || undefined,\n className: joinClassNames(\n \"tutti-rich-text-mention\",\n `tutti-rich-text-mention--${view.state}`,\n className\n ),\n \"data-provider-id\": mention.providerId,\n \"data-state\": view.state,\n style: {\n ...baseStyle,\n ...stateStyles[view.state]\n },\n title: elementTitle\n } as const;\n\n if (view.interactive && onClick) {\n return (\n <button\n {...sharedProps}\n onClick={(event) => {\n handleClick(event);\n }}\n style={{\n ...sharedProps.style,\n appearance: \"none\",\n font: \"inherit\"\n }}\n type=\"button\"\n >\n {label}\n </button>\n );\n }\n\n return <span {...sharedProps}>{label}</span>;\n}\n","import type { JSX } from \"react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport {\n isRichTextMentionHref,\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextMentionHref\n} from \"../core/richTextDocument.ts\";\nimport { getWorkspaceReferencePresentation } from \"../extensions/workspaceReferencePresentation.ts\";\nimport { RichTextMentionReadonly } from \"./RichTextMentionReadonly.tsx\";\nimport { buildRichTextReadonlyInlineSegments } from \"./richTextReadonlyContentModel.ts\";\nimport type { RichTextMentionAttrs } from \"../types/mention.ts\";\n\nexport interface RichTextReadonlyWorkspaceReference {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport interface RichTextReadonlyContentProps {\n value: string;\n className?: string;\n paragraphClassName?: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}\n\nconst externalHrefPattern = /^(?:[a-z]+:)?\\/\\//i;\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextReadonlyContent({\n value,\n className,\n paragraphClassName,\n onMentionAction,\n onOpenWorkspaceReference\n}: RichTextReadonlyContentProps): JSX.Element | null {\n const normalizedValue = normalizeRichTextContent(value).trim();\n\n if (!normalizedValue) {\n return null;\n }\n\n const paragraphs = normalizedValue\n .split(/\\n{2,}/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {paragraphs.map((paragraph, paragraphIndex) => (\n <p\n className={cn(\"whitespace-pre-wrap\", paragraphClassName)}\n key={`${paragraphIndex}:${paragraph}`}\n >\n {renderReadonlyInlineMarkdown(\n paragraph,\n onOpenWorkspaceReference,\n onMentionAction\n )}\n </p>\n ))}\n </div>\n );\n}\n\nfunction renderReadonlyInlineMarkdown(\n content: string,\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>,\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>\n): JSX.Element[] {\n const parts: JSX.Element[] = [];\n const segments = buildRichTextReadonlyInlineSegments(content);\n\n segments.forEach((segment, index) => {\n if (segment.type === \"text\") {\n parts.push(<span key={`text:${index}`}>{segment.text}</span>);\n return;\n }\n\n parts.push(\n <RichTextReadonlyInlineLink\n href={segment.href}\n key={`link:${index}:${segment.href}`}\n label={segment.label}\n onMentionAction={onMentionAction}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n });\n\n return parts;\n}\n\nfunction RichTextReadonlyInlineLink({\n href,\n label,\n onMentionAction,\n onOpenWorkspaceReference\n}: {\n href: string;\n label: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const trimmedHref = href.trim();\n const mention = parseRichTextMentionHref(trimmedHref, label);\n\n if (mention) {\n return (\n <RichTextMentionReadonly\n mention={mention}\n onClick={\n onMentionAction\n ? ({ mention }) => {\n void onMentionAction(mention);\n }\n : undefined\n }\n />\n );\n }\n\n if (!trimmedHref) {\n return <span>{label}</span>;\n }\n\n if (\n externalHrefPattern.test(trimmedHref) &&\n !isRichTextMentionHref(trimmedHref)\n ) {\n return (\n <a\n className=\"font-medium text-[var(--text-primary)] underline decoration-[var(--border-1)] underline-offset-4 hover:text-[var(--text-primary-hover)]\"\n href={trimmedHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n </a>\n );\n }\n\n const kind = trimmedHref.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(trimmedHref, kind);\n\n return (\n <WorkspaceReferenceReadonly\n reference={{\n kind,\n label,\n path\n }}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n}\n\nfunction WorkspaceReferenceReadonly({\n reference,\n onOpenWorkspaceReference\n}: {\n reference: RichTextReadonlyWorkspaceReference;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const presentation = getWorkspaceReferencePresentation(\n reference.label,\n reference.path\n );\n const content = (\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={reference.kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={false}\n />\n );\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {onOpenWorkspaceReference ? (\n <button\n className=\"inline-flex max-w-full appearance-none items-baseline bg-transparent p-0 text-inherit\"\n type=\"button\"\n onClick={() => {\n void onOpenWorkspaceReference(reference);\n }}\n >\n {content}\n </button>\n ) : (\n <span className=\"inline-flex max-w-full align-baseline\">\n {content}\n </span>\n )}\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n );\n}\n","import { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nexport type RichTextReadonlyInlineSegment =\n | {\n text: string;\n type: \"text\";\n }\n | {\n href: string;\n label: string;\n type: \"link\";\n };\n\nexport function buildRichTextReadonlyInlineSegments(\n content: string\n): RichTextReadonlyInlineSegment[] {\n const segments: RichTextReadonlyInlineSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(content)) {\n if (match.index > cursor) {\n segments.push({\n text: content.slice(cursor, match.index),\n type: \"text\"\n });\n }\n\n segments.push({\n href: match.href,\n label: match.label || match.href,\n type: \"link\"\n });\n cursor = match.to;\n }\n\n if (cursor < content.length) {\n segments.push({\n text: content.slice(cursor),\n type: \"text\"\n });\n }\n\n return segments;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,aAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OAIK;AACP,OAAO,cAAc;AACrB,OAAO,eAAe;AACtB,OAAO,eAAe;AACtB,OAAO,UAAU;AAEjB,SAAS,eAAe,iBAAiB;AACzC,SAAS,2BAA2B;AACpC,SAAS,UAAU;;;ACDZ,SAAS,gCACd,WACA,UACS;AACT,MAAI,aAAa,cAAc;AAC7B,WAAO,KAAK,KAAK,SAAS;AAAA,EAC5B;AACA,SAAO,4BAA4B,KAAK,SAAS;AACnD;AAEO,SAAS,yBACd,OACA,OACA,gBACkC;AAClC,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AACxD,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,eAAe;AACnB,SAAO,eAAe,GAAG;AACvB,UAAM,WAAW,MAAM,eAAe,CAAC,KAAK;AAC5C,QAAI,KAAK,KAAK,QAAQ,GAAG;AACvB;AAAA,IACF;AACA,oBAAgB;AAAA,EAClB;AAEA,QAAM,UAAU,MAAM,MAAM,cAAc,MAAM;AAChD,WAAS,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAC3D,UAAM,UAAU,QAAQ,KAAK;AAC7B,UAAM,kBAAkB,eAAe;AAAA,MACrC,CAAC,WAAW,OAAO,YAAY;AAAA,IACjC;AACA,QAAI,gBAAgB,WAAW,GAAG;AAChC;AAAA,IACF;AACA,UAAM,WAAW,QAAQ,QAAQ,CAAC,KAAK;AACvC,QACE,QAAQ,KACR,CAAC,gBAAgB;AAAA,MAAK,CAAC,WACrB,gCAAgC,UAAU,OAAO,QAAQ;AAAA,IAC3D,GACA;AACA;AAAA,IACF;AAEA,UAAM,YAAY,QAAQ,MAAM,KAAK;AACrC,QAAI,UAAU,KAAK,UAAU,MAAM,CAAC,CAAC,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,MAAM,eAAe;AAAA,MACrB,IAAI;AAAA,MACJ;AAAA,MACA,SAAS,UAAU,MAAM,CAAC;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,4BACpB,UACA,OAC+C;AAC/C,MAAI;AACF,WAAO,MAAM,SAAS,MAAM,KAAK;AAAA,EACnC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;AC7EO,SAAS,uBACd,OACS;AACT,MAAI,MAAM,eAAe,MAAM,aAAa,aAAa;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,WAAW,MAAM,aAAa;AACpD,QAAM,QAAQ,MAAM,SAAS,MAAM,aAAa;AAChD,SAAO,YAAY,OAAO,UAAU;AACtC;;;ACJA,IAAM,sBAAsB,iCAAiC;AAEtD,SAAS,2BACd,WACA,2BACA,OAA4B,qBACC;AAC7B,SAAO;AAAA,IACL,cACE,WAAW,cAAc,KAAK,KAAK,KAAK,EAAE,oBAAoB;AAAA,IAChE,gBACE,WAAW,gBAAgB,KAAK,KAAK,KAAK,EAAE,sBAAsB;AAAA,IACpE,4BACE,2BAA2B,KAAK,KAChC,WAAW,4BAA4B,KAAK,KAC5C,KAAK,EAAE,uCAAuC;AAAA,EAClD;AACF;AAEO,IAAM,6BAA6B,2BAA2B;;;ACnCrE,SAAS,UAAU,wBAAwB;AAiCrC,cAIA,YAJA;AAtBC,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,iBAAe;AAAA,MACf,WAAW;AAAA,QACT;AAAA,QACA,WAAW,mCAAmC;AAAA,QAC9C;AAAA,MACF,EAAE,KAAK,GAAG;AAAA,MACV,MAAK;AAAA,MACL,aAAa,CAAC,UAAyC;AACrD,cAAM,eAAe;AACrB,iBAAS;AAAA,MACX;AAAA,MAEA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QACA,qBAAC,UAAK,WAAU,uDACd;AAAA,8BAAC,UAAK,WAAU,8FACb,iBACH;AAAA,UACC,WACC,oBAAC,UAAK,WAAU,6GACb,oBACH,IACE;AAAA,WACN;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AACF,GAGgB;AACd,QAAM,oBAAoB,SAAS,KAAK,KAAK;AAE7C,MAAI,4BAA4B;AAC9B,UAAM,OACJ,+BAA+B,WAAW,mBAAmB;AAC/D,WACE;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAU;AAAA,QACV,+BAA4B;AAAA,QAE5B,8BAAC,QAAK,WAAU,UAAS;AAAA;AAAA,IAC3B;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,WAAU;AAAA,MACV,+BAA4B;AAAA,MAE3B,8BACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAI;AAAA,UACJ,WAAU;AAAA,UACV,UAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAQ;AAAA,UACR,KAAK;AAAA;AAAA,MACP,IAEA,oBAAC,UAAK,WAAU,6DAA4D;AAAA;AAAA,EAEhF;AAEJ;;;AC/FA,SAAS,iBAAiB,YAAY;AACtC,SAAS,6BAA6B;;;ACAtC,SAAS,uBAA2C;AAiC9C,SAeM,OAAAC,MAfN,QAAAC,aAAA;AA/BN,SAAS,2BAA2B,cAAsC;AACxE,MAAI,CAAC,gBAAgB,OAAO,iBAAiB,UAAU;AACrD,WAAO;AAAA,EACT;AACA,QAAM,QACH,aAA+D,WAC/D,aAA4C;AAC/C,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,WAAW;AACpB;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,QACJ,OAAO,KAAK,MAAM,UAAU,WACxB,KAAK,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK,IAChD;AACN,QAAM,UAAU,2BAA2B,KAAK,MAAM,YAAY;AAElE,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAW,WAAW,gBAAgB;AAAA,MACtC,iBAAiB;AAAA,MACjB,oCAAiC;AAAA,MAEjC,0BAAAC;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,WACI,uFACA;AAAA,UACN,EAAE,KAAK,GAAG;AAAA,UACV,+BAA4B;AAAA,UAE3B;AAAA,sBACC,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,WAAU;AAAA,gBACV,+BAA4B;AAAA,gBAE5B,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,KAAI;AAAA,oBACJ,WAAU;AAAA,oBACV,UAAS;AAAA,oBACT,WAAW;AAAA,oBACX,SAAQ;AAAA,oBACR,KAAK;AAAA;AAAA,gBACP;AAAA;AAAA,YACF,IACE;AAAA,YACH,QAAS,UAAU,QAAQ,IAAI,KAAK,KAAM;AAAA;AAAA;AAAA,MAC7C;AAAA;AAAA,EACF;AAEJ;;;ADjDO,IAAM,mBAAmB,KAAK,OAAO;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AAAA,EAEZ,gBAAgB;AACd,WAAO;AAAA,MACL,UAAU;AAAA,QACR,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,cAAc;AAAA,QACZ,SAAS;AAAA,MACX;AAAA,MACA,YAAY;AAAA,QACV,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,SAAS;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,yCAAyC,CAAC;AAAA,EAC3D;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,UAAM,QACJ,OAAO,eAAe,UAAU,WAAW,eAAe,QAAQ;AACpE,UAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AAE1D,WAAO;AAAA,MACL;AAAA,MACA,gBAAgB,gBAAgB;AAAA,QAC9B,oCAAoC;AAAA,QACpC,OACE;AAAA,MACJ,CAAC;AAAA,MACD,eAAe,IAAI,YAAY,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO,sBAAsB,0BAA0B;AAAA,MACrD,IAAI;AAAA,MACJ,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF,CAAC;;;AEtED,SAAS,mBAAAE,kBAAiB,QAAAC,aAAY;AACtC,SAAS,yBAAAC,8BAA6B;;;ACDtC,SAAS,WAAW,gBAA6C;AACjE,SAAS,mBAAAC,wBAA2C;AACpD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACFA,SAAS,kCACd,OACA,MACgC;AAChC,QAAM,eAAe,wBAAwB,OAAO,IAAI;AACxD,QAAM,WAAW,kBAAkB,IAAI;AAEvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,OAAe,MAAsB;AACpE,QAAM,eAAe,MAAM,KAAK;AAEhC,MAAI,iBAAiB,IAAI;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,IAAI,KAAK,KAAK,KAAK;AAC5C;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,SAAO,uBAAuB,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,gBAAgB,MAAsB;AAC7C,QAAM,iBAAiB,uBAAuB,KAAK,KAAK,CAAC;AAEzD,MAAI,mBAAmB,MAAM,WAAW,cAAc,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,eAAe,MAAM,QAAQ,EAAE,OAAO,OAAO;AAE9D,SAAO,SAAS,GAAG,EAAE,KAAK;AAC5B;AAEA,SAAS,uBAAuB,MAAsB;AACpD,MAAI,SAAS,IAAI;AACf,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,WAAW,EAAE;AACnC;AAEA,SAAS,WAAW,MAAuB;AACzC,SACE,SAAS,OACT,SAAS,QACT,SAAS,QACT,SAAS,UACT,oBAAoB,KAAK,IAAI;AAEjC;;;ADMM,SAEI,OAAAC,MAFJ,QAAAC,aAAA;AA3DN,IAAM,0CAA0C;AAEzC,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,OAAO,UAAU;AAC9D,QAAM,QAAQ,KAAK;AAKnB,QAAM,mBAAmB,UAAU;AAGnC,QAAM,OAAO,MAAM,SAAS,WAAW,WAAW;AAClD,QAAM,QAAQ,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAC9D,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC3D,QAAM,eAAe,kCAAkC,OAAO,IAAI;AAClE,QAAM,wBACJ,OAAO,iBAAiB,0BAA0B,WAC9C,iBAAiB,wBACjB,2BAA2B;AAEjC,YAAU,MAAM;AACd,UAAM,eAAe,MAAM;AACzB,oBAAc,OAAO,UAAU;AAAA,IACjC;AAEA,iBAAa;AACb,WAAO,GAAG,eAAe,YAAY;AACrC,WAAO,GAAG,UAAU,YAAY;AAChC,WAAO,MAAM;AACX,aAAO,IAAI,eAAe,YAAY;AACtC,aAAO,IAAI,UAAU,YAAY;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe,CAAC,UAA2C;AAC/D,UAAM,eAAe;AACrB,UAAM,gBAAgB;AACtB,QAAI,CAAC,OAAO,YAAY;AACtB;AAAA,IACF;AACA,eAAW;AAAA,EACb;AAEA,SACE,gBAAAD;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAW,yCACT,WAAW,gBAAgB,EAC7B;AAAA,MACA,iBAAiB;AAAA,MACjB,sCAAmC;AAAA,MAEnC,0BAAAD,MAAC,WACC;AAAA,wBAAAD,KAAC,kBAAe,SAAO,MACrB,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,YACX,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO,aAAa;AAAA,YACpB,WAAW;AAAA,YACX,mBACE,aACI;AAAA,cACE,cAAc;AAAA,cACd,eAAe;AAAA,cACf,UAAU;AAAA,YACZ,IACA;AAAA;AAAA,QAER,GACF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,YAAY;AAAA,YAEX,uBAAa;AAAA;AAAA,QAChB;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;;;ADrFO,IAAM,qBAAqBG,MAAK,OAAO;AAAA,EAC5C,MAAM;AAAA,EACN,aAAa;AACX,WAAO;AAAA,MACL,uBACE,2BAA2B;AAAA,IAC/B;AAAA,EACF;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AAAA,EAEZ,gBAAgB;AACd,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,2CAA2C,CAAC;AAAA,EAC7D;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,UAAM,OAAO,eAAe,SAAS,WAAW,WAAW;AAC3D,UAAM,QACJ,OAAO,eAAe,UAAU,WAAW,eAAe,QAAQ;AACpE,UAAM,OACJ,OAAO,eAAe,SAAS,WAAW,eAAe,OAAO;AAClE,UAAM,eAAe,kCAAkC,OAAO,IAAI;AAClE,UAAM,0BACJ,SAAS,WACL,mCACA;AAEN,WAAO;AAAA,MACL;AAAA,MACAC,iBAAgB,gBAAgB;AAAA,QAC9B,sCAAsC;AAAA,QACtC,iCAAiC;AAAA,QACjC,2BAA2B;AAAA,QAC3B,2BAA2B;AAAA,QAC3B,aAAa;AAAA,QACb,OAAO,aAAa;AAAA,QACpB,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA,MACZ,CAAC;AAAA,MACD;AAAA,QACE;AAAA,QACA;AAAA,UACE,eAAe;AAAA,UACf,OAAO;AAAA,QACT;AAAA,QACA,SAAS,WAAW,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,QACT;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAOC,uBAAsB,0BAA0B;AAAA,EACzD;AACF,CAAC;;;APoYG,SAKI,OAAAC,MALJ,QAAAC,aAAA;AA9YJ,IAAM,sCAAsC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,mBAAmB,CAAC;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,aAAa;AACnB,QAAM,kBAAkB,yBAAyB,KAAK;AACtD,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,oBAAoB,OAAO,QAAQ;AACzC,QAAM,yBAAyB,OAAO,eAAe;AACrD,QAAM,qBAAqB,OAAO,WAAW;AAC7C,QAAM,6BAA6B,OAAO,CAAC;AAC3C,QAAM,eAAe,OAA8B,IAAI;AACvD,QAAM,WAAW;AAAA,IACf,MAAM,8BAA8B,gBAAgB;AAAA,IACpD,CAAC,gBAAgB;AAAA,EACnB;AACA,QAAM,uBAAuB;AAAA,IAC3B,MAAM,SAAS,mBAAmB;AAAA,IAClC,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAIA;AAAA,IACxB;AAAA,EACF;AACA,QAAM,CAAC,SAAS,UAAU,IAAIA;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,CAAC;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA;AAAA,IAChC;AAAA,EACF;AAEA,oBAAkB,UAAU;AAE5B,QAAM,SAAS,UAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,UAAU,CAAC;AAAA,IACX,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB,UAAU;AAAA,QAC3B,uBAAuB,KAAK;AAAA,MAC9B,CAAC;AAAA,MACD;AAAA,IACF;AAAA,IACA,SAAS,+BAA+B,eAAe;AAAA,IACvD,aAAa;AAAA,MACX,YAAY;AAAA,QACV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AACP,aAAO,WAAW,MAAM;AACtB,qBAAa,KAAK;AAClB,iBAAS,IAAI;AACb,mBAAW,CAAC,CAAC;AACb,uBAAe,CAAC;AAChB,qBAAa,KAAK;AAClB,qBAAa,IAAI;AAAA,MACnB,GAAG,GAAG;AAAA,IACR;AAAA,IACA,UAAU;AACR,mBAAa,IAAI;AAAA,IACnB;AAAA,IACA,SAAS,EAAE,QAAAC,QAAO,GAAG;AACnB,YAAM,aAAa,mCAAmCA,QAAO,QAAQ,CAAC;AACtE,6BAAuB,UAAU;AACjC,wBAAkB,QAAQ,UAAU;AAAA,IACtC;AAAA,EACF,CAAC;AAED,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,QAAI,uBAAuB,YAAY,iBAAiB;AACtD;AAAA,IACF;AAEA,UAAM,oBAAoB;AAAA,MACxB,OAAO,QAAQ;AAAA,IACjB;AACA,QAAI,sBAAsB,iBAAiB;AACzC,6BAAuB,UAAU;AACjC;AAAA,IACF;AAEA,WAAO,SAAS;AAAA,MACd,+BAA+B,eAAe;AAAA,MAC9C;AAAA,QACE,YAAY;AAAA,MACd;AAAA,IACF;AACA,2BAAuB,UAAU;AAAA,EACnC,GAAG,CAAC,QAAQ,eAAe,CAAC;AAE5B,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,YAAY,2BAA2B,UAAU;AACvD,+BAA2B,UAAU;AACrC,UAAM,WAAW,8BAA8B,MAAM;AACrD,QAAI,SAAS,WAAW,GAAG;AACzB;AAAA,IACF;AAEA,eAAW,WAAW,UAAU;AAC9B,YAAM,WAAW,SAAS,YAAY,QAAQ,MAAM,UAAU;AAC9D,UAAI,CAAC,UAAU,gBAAgB;AAC7B;AAAA,MACF;AAEA,WAAK,QAAQ,QAAQ,SAAS,eAAe,QAAQ,KAAK,CAAC,EACxD,KAAK,CAAC,aAAa;AAClB,YACE,CAAC,YACD,2BAA2B,YAAY,aACvC,OAAO,aACP;AACA;AAAA,QACF;AAEA,kCAA0B,QAAQ,QAAQ,KAAK,QAAQ,OAAO;AAAA,UAC5D,OAAO,SAAS;AAAA,UAChB,cAAc,SAAS;AAAA,QACzB,CAAC;AAAA,MACH,CAAC,EACA,MAAM,MAAM;AAAA,MAEb,CAAC;AAAA,IACL;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,eAAe,CAAC;AAEtC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,QAAI,OAAO,GAAG,mBAAmB,SAAS,WAAW,GAAG;AACtD;AAAA,IACF;AAEA,uBAAmB,UAAU;AAC7B,WAAO,SAAS,MAAM,KAAK;AAAA,EAC7B,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,WAAO,YAAY,CAAC,QAAQ;AAC5B,WAAO,KAAK;AAAA,MACV,OAAO,MAAM,GAAG,QAAQ,oBAAoB,CAAC,QAAQ;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM;AAC7B,YAAM,YAAY,kBAAkB,QAAQ,oBAAoB;AAChE,eAAS,SAAS;AAAA,IACpB;AAEA,UAAM,cAAc,MAAM;AACxB,YAAM,cAAc,OAAO;AAC3B,mBAAa,WAAW;AACxB,uBAAiB;AAAA,IACnB;AAEA,qBAAiB;AACjB,WAAO,GAAG,mBAAmB,gBAAgB;AAC7C,WAAO,GAAG,eAAe,gBAAgB;AACzC,WAAO,GAAG,SAAS,WAAW;AAC9B,WAAO,GAAG,QAAQ,WAAW;AAC7B,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,gBAAgB;AAC9C,aAAO,IAAI,eAAe,gBAAgB;AAC1C,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,IAAI,QAAQ,WAAW;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,sBAAsB,MAAM,CAAC;AAEjC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,SAAS,qBAAqB,WAAW,GAAG;AAC1D,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,SAAS,gBAAgB;AACzC,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,iBAAa,IAAI;AAEjB,SAAK,4BAA4B,UAAU;AAAA,MACzC,aAAa,gBAAgB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf;AAAA,MACA,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,WAAW,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,UAC7C;AAAA,UACA,OAAO,MAAM,UAAU,MAAM,OAAO,QAAQ;AAAA,UAC5C;AAAA,UACA;AAAA,QACF;AAAA,QACA,cAAc,mCAAmC,OAAO,QAAQ,CAAC;AAAA,MACnE;AAAA,IACF,CAAC,EACE,KAAK,CAAC,gBAAgB;AACrB,UAAI,gBAAgB,OAAO,SAAS;AAClC;AAAA,MACF;AACA,iBAAW,WAAW;AACtB;AAAA,QAAe,CAAC,YACd,YAAY,WAAW,IACnB,IACA,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,YAAY,SAAS,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AAED,kBAAgB,MAAM;AACpB,QAAI,CAAC,UAAU,CAAC,OAAO;AACrB,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,UAAM,kBAAkB,MAAM;AAC5B,YAAM,SAAS,OAAO,KAAK,YAAY,OAAO,MAAM,UAAU,IAAI;AAClE,YAAM,gBAAgB;AAAA,QACpB,GAAG,OAAO;AAAA,QACV,GAAG,OAAO,SAAS;AAAA,MACrB;AACA,mBAAa,aAAa;AAAA,IAC5B;AAEA,oBAAgB;AAChB,WAAO,iBAAiB,UAAU,eAAe;AACjD,WAAO,iBAAiB,UAAU,iBAAiB;AAAA,MACjD,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AACD,WAAO,MAAM;AACX,aAAO,oBAAoB,UAAU,eAAe;AACpD,aAAO,oBAAoB,UAAU,iBAAiB,IAAI;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,QAAQ,YAAY,KAAK,CAAC;AAE9B,QAAM,kBACJ,CAAC,CAAC,SACF,qBAAqB,SAAS,KAC9B,MAAM,QAAQ,UAAU;AAC1B,QAAM,aAAa,oBAAoB,aAAa,CAAC,CAAC;AACtD,QAAM,UACJ,CAAC,UACD,mCAAmC,OAAO,QAAQ,CAAC,EAAE,KAAK,EAAE,WAAW;AAEzE,QAAM,aAAa,CAAC,UAAqC;AACvD,QAAI,CAAC,UAAU,CAAC,OAAO;AACrB;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,WACG,MAAM,EACN,MAAM,EACN,gBAAgB,EAAE,MAAM,MAAM,MAAM,IAAI,MAAM,GAAG,GAAG,OAAO,EAC3D,IAAI;AACP,eAAW,CAAC,CAAC;AACb,mBAAe,CAAC;AAChB,iBAAa,KAAK;AAClB,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,gBAAgB,CAAC,UAAyC;AAC9D,QAAI,uBAAuB,KAAK,GAAG;AACjC;AAAA,IACF;AAEA,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,UAAU;AAC1B,YAAM,eAAe;AACrB,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,aAAa;AAC7B,YAAM,eAAe;AACrB,qBAAe,CAAC,aAAa,UAAU,KAAK,QAAQ,MAAM;AAC1D;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW;AAC3B,YAAM,eAAe;AACrB;AAAA,QACE,CAAC,aAAa,UAAU,IAAI,QAAQ,UAAU,QAAQ;AAAA,MACxD;AACA;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,OAAO;AAChD,YAAM,QAAQ,QAAQ,WAAW;AACjC,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,YAAM,eAAe;AACrB,iBAAW,KAAK;AAChB;AAAA,IACF;AAAA,EACF;AAEA,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,2BAA2B,SAAS;AAAA,MAClD,KAAK;AAAA,MAEL;AAAA,wBAAAD,KAAC,SAAI,WAAU,kBAAiB,kBAAkB,eAChD,0BAAAA,KAAC,iBAAc,QAAgB,GACjC;AAAA,QACC,WAAW,cACV,gBAAAA,KAAC,SAAI,WAAU,8FACb,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,wBAAwB;AAAA,cACxB;AAAA,YACF;AAAA,YAEC;AAAA;AAAA,QACH,GACF,IACE;AAAA,QACH;AAAA,QACA,cAAc,YACb,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAI;AAAA,YACJ,WAAU;AAAA,YACV,WAAW;AAAA,cACT,MAAM;AAAA,cACN,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,eAAe;AAAA,gBACb,OAAO;AAAA,gBACP,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,YACA,OAAO,eAAe,SAAY,SAAY,EAAE,QAAQ,WAAW;AAAA,YAElE,kBAAQ,SAAS,IAChB,QAAQ,IAAI,CAAC,OAAO,UAClB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO,MAAM;AAAA,gBACb,UAAU,UAAU;AAAA,gBACpB,UAAU,MAAM;AAAA,gBAChB,SAAS,MAAM;AAAA,gBACf,4BAA4B;AAAA,kBAC1B,MAAM;AAAA,gBACR;AAAA,gBACA,UAAU,MAAM,WAAW,KAAK;AAAA;AAAA,cAR3B,GAAG,MAAM,UAAU,IAAI,MAAM,GAAG;AAAA,YASvC,CACD,IAED,gBAAAA,KAAC,SAAI,WAAU,gEACZ,sBAAY,KAAK,eAAe,KAAK,gBACxC;AAAA;AAAA,QAEJ,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBACP,QACA,UACwC;AACxC,QAAM,QAAQ,uBAAuB,QAAQ,QAAQ;AACrD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBACP,QACA,UACwC;AACxC,QAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,MAAI,CAAC,UAAU,OAAO;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,CAAC,MAAM,OAAO,aAAa;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM,OAAO;AAAA,IACpC;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,EACF;AACA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,iBAAiB,SAAS,MAAM;AAC/D,SAAO;AAAA,IACL,MAAM,UAAU,OAAO;AAAA,IACvB,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,IAAI,UAAU;AAAA,EAChB;AACF;AAEA,SAAS,kCACP,YACA,QACA;AACA,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,2BAA2B,YAAY,OAAO,OAAO;AAAA,MAC9D;AAAA,IACF,KAAK,iBAAiB;AACpB,YAAM,OAAO,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AACpD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA,OAAO,OAAO;AAAA,UACd,MAAM,0BAA0B,OAAO,MAAM,IAAI;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO,OAAO;AAAA,IAChB;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,8BACP,QAC+B;AAC/B,MAAI,OAAO,SAAS,iBAAiB;AACnC,WAAO;AAAA,EACT;AACA,SAAO,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AAChD;AAEA,SAAS,8BACP,QACqD;AACrD,QAAM,WAAgE,CAAC;AAEvE,SAAO,MAAM,IAAI,YAAY,CAAC,MAAM,QAAQ;AAC1C,QAAI,KAAK,KAAK,SAAS,0BAA0B;AAC/C;AAAA,IACF;AACA,UAAM,QAAQ,KAAK;AACnB,QACE,MAAM,YAAY,OAClB,OAAO,MAAM,eAAe,YAC5B,CAAC,MAAM,WAAW,KAAK,KACvB,OAAO,MAAM,aAAa,YAC1B,CAAC,MAAM,SAAS,KAAK,KACrB,OAAO,MAAM,UAAU,YACvB,CAAC,MAAM,MAAM,KAAK,GAClB;AACA;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY,MAAM,WAAW,KAAK;AAAA,QAClC,UAAU,MAAM,SAAS,KAAK;AAAA,QAC9B,OAAO,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AAAA,QAClD,OAAO,6BAA6B,MAAM,KAAK;AAAA,QAC/C,cAAc,6BAA6B,MAAM,YAAY;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEA,SAAS,0BACP,QACA,KACA,cACA,UAIM;AACN,QAAM,OAAO,OAAO,MAAM,IAAI,OAAO,GAAG;AACxC,MAAI,CAAC,QAAQ,KAAK,KAAK,SAAS,0BAA0B;AACxD;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK;AACnB,MACE,MAAM,eAAe,aAAa,cAClC,MAAM,aAAa,aAAa,YAChC,KAAK,UAAU,6BAA6B,MAAM,KAAK,KAAK,CAAC,CAAC,MAC5D,KAAK,UAAU,aAAa,SAAS,CAAC,CAAC,GACzC;AACA;AAAA,EACF;AAEA,QAAM,YAAY,SAAS,OAAO,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AACjE,QAAM,mBAAmB,6BAA6B,SAAS,YAAY;AAC3E,QAAM,YAAkC;AAAA,IACtC,SAAS;AAAA,IACT,YAAY,aAAa;AAAA,IACzB,UAAU,aAAa;AAAA,IACvB,OAAO,aAAa,aAAa;AAAA,IACjC,OAAO,aAAa;AAAA,IACpB,cAAc,oBAAoB,aAAa;AAAA,EACjD;AAEA,MACE,MAAM,UAAU,UAAU,SAC1B,KAAK,UAAU,6BAA6B,MAAM,YAAY,KAAK,CAAC,CAAC,MACnE,KAAK,UAAU,UAAU,gBAAgB,CAAC,CAAC,GAC7C;AACA;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,MAAM,GAAG,cAAc,KAAK,QAAW,SAAS;AAC3E,cAAY,QAAQ,gBAAgB,KAAK;AACzC,cAAY,QAAQ,iBAAiB,IAAI;AACzC,SAAO,KAAK,SAAS,WAAW;AAClC;AAEA,SAAS,6BACP,OAC8C;AAC9C,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,KAAgC,EAC5D;AAAA,IACC,CAAC,CAAC,KAAK,UAAU,MACf;AAAA,MACE,IAAI,KAAK;AAAA,MACT,OAAO,eAAe,WAAW,WAAW,KAAK,IAAI;AAAA,IACvD;AAAA,EACJ,EACC,OAAO,CAAC,CAAC,KAAK,UAAU,MAAM,IAAI,SAAS,KAAK,WAAW,SAAS,CAAC,EACrE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC;AAEtD,SAAO,QAAQ,SAAS,IACpB,OAAO,OAAO,OAAO,YAAY,OAAO,CAAC,IACzC;AACN;AAEA,SAAS,6BACP,OACyC;AACzC,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAM,SAAS;AACf,QAAM,OAAoC,CAAC;AAE3C,aAAW,OAAO,qCAAqC;AACrD,UAAM,aAAa,OAAO,GAAG;AAC7B,QAAI,OAAO,eAAe,UAAU;AAClC;AAAA,IACF;AACA,UAAM,UAAU,WAAW,KAAK;AAChC,QAAI,SAAS;AACX,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF;AAEA,SAAO,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO,OAAO,IAAI,IAAI;AAC9D;;;AUrvBA;AAAA,EACE,aAAAK;AAAA,EACA,mBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAKK;AACP,SAAS,uBAAAC,4BAA2B;AACpC,SAAS,MAAAC,WAAU;;;ACTnB,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAE5B,IAAM,yCAAyC;AAAA,EAC7C,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,gBAAgB,SAAS,gBAAgB;AAAA,EACtD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,uBAAuB,SAAS,wBAAwB;AAAA,EACrE,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,qBAAqB,SAAS,sBAAsB;AAAA,EACjE,EAAE,WAAW,YAAY,SAAS,YAAY;AAAA,EAC9C,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,aAAa,SAAS,aAAa;AAAA,EAChD,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,yBAAyB,SAAS,0BAA0B;AAAA,EACzE,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,aAAa,SAAS,aAAa;AAAA,EAChD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,WAAW,SAAS,WAAW;AAAA,EAC5C,EAAE,WAAW,cAAc,SAAS,gBAAgB;AACtD;AA0BA,SAAS,0BAA0B,MAAuB;AACxD,QAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,MACE,qBAAqB,KAAK,WAAW,KACrC,oBAAoB,KAAK,WAAW,GACpC;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,wCACd,OACqC;AACrC,QAAM,WAAgD,CAAC;AACvD,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,KAAK,GAAG;AACpD,UAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,EAAE,OAAO,QAAQ,GAAG,IAAI;AAE9B,QAAI,QAAQ,QAAQ;AAClB,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,MAAM,MAAM,QAAQ,KAAK;AAAA,QAC/B,MAAM;AAAA,QACN,IAAI;AAAA,MACN,CAAC;AAAA,IACH;AAEA,QAAI,SAAS,QAAQ,0BAA0B,IAAI,GAAG;AACpD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,SAAS,GAAG,IAAI,WAAW;AAAA,MACxC,CAAC;AAAA,IACH,OAAO;AACL,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAEA,aAAS;AAAA,EACX;AAEA,MAAI,SAAS,MAAM,QAAQ;AACzB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM,MAAM,MAAM,MAAM;AAAA,MACxB,MAAM;AAAA,MACN,IAAI,MAAM;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,+BACd,UACS;AACT,SAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,MAAM;AAC3D;AAEO,SAAS,yCACd,UACA,gBACe;AACf,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,SAAS,QAAQ;AAC3B;AAAA,IACF;AACA,QAAI,kBAAkB,QAAQ,QAAQ,kBAAkB,QAAQ,IAAI;AAClE;AAAA,IACF;AACA,UAAM,WAAW,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,QAAQ;AAC9D,WAAO,iBAAiB,WAAW,QAAQ,OAAO,QAAQ;AAAA,EAC5D;AACA,SAAO;AACT;AAEA,SAAS,kCACP,aACA,WACA,OACM;AACN,cAAY,SAAS,IAAI;AAC3B;AAEO,SAAS,6BACd,UACe;AACf,QAAM,gBAAgB,OAAO,iBAAiB,QAAQ;AACtD,QAAM,cAA6B;AAAA,IACjC,YAAY;AAAA,EACd;AAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,aAAW,EAAE,WAAW,QAAQ,KAAK,wCAAwC;AAC3E;AAAA,MACE;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;;;ACpLA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,MAAAC,WAAU;AAsCA,gBAAAC,MAIP,QAAAC,aAJO;AAnCnB,IAAMC,2CAA0C;AAEzC,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAagB;AACd,SACE,gBAAAF,KAAC,SAAI,WAAU,6DACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,aAAa,CAAC,UAAU,OAAO,CAAC,SAAS;AAAA,MACtD;AAAA,MAEC,mBAAS,IAAI,CAAC,SAAS,UAAU;AAChC,YAAI,QAAQ,SAAS,QAAQ;AAC3B,iBAAO,gBAAAA,KAAC,UAAkB,kBAAQ,QAAhB,KAAqB;AAAA,QACzC;AAEA,eACE,gBAAAC,MAAC,UAAiB,WAAU,YAC1B;AAAA,0BAAAD,KAAC,UAAK,eAAY,QAAO,WAAU,oBAChC,kBAAQ,MACX;AAAA,UACA,gBAAAA;AAAA,YAACF;AAAA,YAAA;AAAA,cACC,WAAWC;AAAA,gBACT;AAAA,gBACAG;AAAA,cACF;AAAA,cACA,UAAU,QAAQ;AAAA,cAClB,MAAK;AAAA,cACL,OAAO,QAAQ;AAAA,cACf,mBAAmB;AAAA,gBACjB,cAAc;AAAA,gBACd,eAAe,CAAC,UAAU;AACxB,wBAAM,eAAe;AACrB,wBAAM,gBAAgB;AACtB,kCAAgB,OAAO;AAAA,gBACzB;AAAA,cACF;AAAA,cACA,SACE,gBAAAF;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAWD;AAAA,oBACT;AAAA,oBACA,QAAQ,SAAS,WACb,kBACA;AAAA,kBACN;AAAA,kBAEC,kBAAQ;AAAA;AAAA,cACX;AAAA,cAEF,eAAe,CAAC,UAAU;AACxB,+BAAe,SAAS,KAAK;AAAA,cAC/B;AAAA;AAAA,UACF;AAAA,aAnCS,KAoCX;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH,GACF;AAEJ;;;ACtFA,IAAM,mCAAmC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQA,SAAS,gBAAgB,OAAiD;AACxE,MAAI,CAAC,SAAS,UAAU,UAAU;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,WAAW,KAAK;AAC3C,SAAO,OAAO,SAAS,WAAW,IAAI,cAAc;AACtD;AAEA,SAAS,kBAAkB,eAA4C;AACrE,QAAM,qBAAqB,gBAAgB,cAAc,UAAU;AACnE,MAAI,uBAAuB,MAAM;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,gBAAgB,cAAc,QAAQ;AACvD,SAAO,aAAa,OAAO,WAAW,MAAM;AAC9C;AAEO,SAAS,8BACd,UACA,gBACmC;AACnC,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,KAAK;AAAA,IAC9B;AAAA,IACA,KAAK,IAAI,gBAAgB,SAAS,MAAM,MAAM;AAAA,EAChD;AACA,QAAM,eAAe,SAAS,sBAAsB;AACpD,QAAM,gBAAgB,OAAO,iBAAiB,QAAQ;AACtD,QAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,QAAM,SAAS,SAAS,cAAc,MAAM;AAE5C,SAAO,aAAa,eAAe,MAAM;AACzC,SAAO,MAAM,WAAW;AACxB,SAAO,MAAM,OAAO,GAAG,aAAa,IAAI;AACxC,SAAO,MAAM,MAAM,GAAG,aAAa,GAAG;AACtC,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,gBAAgB;AAC7B,SAAO,MAAM,WAAW;AAExB,aAAW,gBAAgB,kCAAkC;AAC3D,IAAC,OAAO,MACN,YACF,IAEI,cAEA,YAAY,KAAK;AAAA,EACvB;AACA,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,YAAY,cAAc;AACvC,SAAO,MAAM,eAAe,cAAc;AAE1C,QAAM,mBAAmB,SAAS,MAAM,MAAM,GAAG,kBAAkB;AACnE,SAAO,cAAc,iBAAiB,SAAS,IAAI,mBAAmB;AACtE,MAAI,iBAAiB,SAAS,IAAI,GAAG;AACnC,WAAO,OAAO,SAAS,eAAe,QAAQ,CAAC;AAAA,EACjD;AAEA,SAAO,cAAc;AACrB,SAAO,OAAO,MAAM;AACpB,WAAS,KAAK,OAAO,MAAM;AAE3B,MAAI;AACF,UAAM,aAAa,OAAO,sBAAsB;AAChD,UAAM,aAAa,kBAAkB,aAAa;AAElD,WAAO;AAAA,MACL,GAAG,WAAW,OAAO,SAAS;AAAA,MAC9B,GAAG,WAAW,MAAM,SAAS;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,UAAE;AACA,WAAO,OAAO;AAAA,EAChB;AACF;;;AH+OI,SAEI,OAAAI,MAFJ,QAAAC,aAAA;AArTG,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA,mBAAmB,CAAC;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,QAAM,aAAa;AACnB,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,cAAcC,QAAmC,IAAI;AAC3D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,UAAS,CAAC;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,CAAC;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA;AAAA,IAChC;AAAA,EACF;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,EAAE,MAAM,GAAG,KAAK,EAAE,CAAC;AACxE,QAAM,CAAC,2BAA2B,4BAA4B,IAC5DA,UAA+B,IAAI;AACrC,QAAM,sBAAsBD,QAAsB,IAAI;AACtD,QAAM,WAAWE;AAAA,IACf,MAAM,8BAA8B,gBAAgB;AAAA,IACpD,CAAC,gBAAgB;AAAA,EACnB;AACA,QAAM,uBAAuBA;AAAA,IAC3B,MAAM,SAAS,mBAAmB;AAAA,IAClC,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,qBAAqBA;AAAA,IACzB,MAAM,wCAAwC,KAAK;AAAA,IACnD,CAAC,KAAK;AAAA,EACR;AACA,QAAM,iBAAiB,+BAA+B,kBAAkB;AACxE,QAAM,QAAQA;AAAA,IACZ,MACE,YACI,yBAAyB,OAAO,gBAAgB,oBAAoB,IACpE;AAAA,IACN,CAAC,sBAAsB,WAAW,gBAAgB,KAAK;AAAA,EACzD;AACA,QAAM,cACJ,UAAU,QACV,MAAM,QAAQ,UAAU,kBACxB,qBAAqB,SAAS;AAChC,QAAM,aACJ,aAAa,gBAAgB,aAAa,QAAQ,SAAS;AAE7D,EAAAC,WAAU,MAAM;AACd,UAAM,gBAAgB,oBAAoB;AAC1C,QAAI,kBAAkB,QAAQ,CAAC,YAAY,SAAS;AAClD;AAAA,IACF;AACA,gBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,wBAAoB,UAAU;AAAA,EAChC,GAAG,CAAC,KAAK,CAAC;AAEV,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,OAAO;AAC1B,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,iBAAa,IAAI;AAEjB,SAAK,4BAA4B,UAAU;AAAA,MACzC,aAAa,gBAAgB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf;AAAA,MACA,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,cAAc;AAAA,QACd,WAAW;AAAA,MACb;AAAA,IACF,CAAC,EACE,KAAK,CAAC,gBAAgB;AACrB,UAAI,gBAAgB,OAAO,SAAS;AAClC;AAAA,MACF;AACA,iBAAW,WAAW;AACtB;AAAA,QAAe,CAAC,YACd,YAAY,WAAW,IACnB,IACA,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,YAAY,SAAS,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,YAAY,OAAO,UAAU,aAAa,KAAK,CAAC;AAEpD,EAAAC,iBAAgB,MAAM;AACpB,QAAI,CAAC,YAAY,WAAW,CAAC,gBAAgB;AAC3C,mCAA6B,IAAI;AACjC;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC7B,iCAA6B,6BAA6B,QAAQ,CAAC;AACnE,sBAAkB;AAAA,MAChB,MAAM,SAAS;AAAA,MACf,KAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH,GAAG,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAE7C,EAAAA,iBAAgB,MAAM;AACpB,QAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,SAAS;AACjD,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,UAAM,aAAa;AAAA,MACjB,YAAY;AAAA,MACZ,MAAM;AAAA,IACR;AACA,UAAM,eAAe,YAAY,QAAQ,sBAAsB;AAE/D,QAAI,CAAC,YAAY;AACf,mBAAa;AAAA,QACX,GAAG,aAAa,OAAO;AAAA,QACvB,GAAG,aAAa,SAAS;AAAA,MAC3B,CAAC;AACD;AAAA,IACF;AAEA,iBAAa;AAAA,MACX,GAAG,WAAW;AAAA,MACd,GAAG,WAAW,IAAI,WAAW,aAAa;AAAA,IAC5C,CAAC;AAAA,EACH,GAAG,CAAC,YAAY,YAAY,OAAO,gBAAgB,KAAK,CAAC;AAEzD,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,SAAS;AACjD;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC7B,UAAM,kBAAkB,MAAM;AAC5B,YAAM,aAAa,8BAA8B,UAAU,MAAM,EAAE;AACnE,YAAM,eAAe,SAAS,sBAAsB;AAEpD;AAAA,QACE,aACI;AAAA,UACE,GAAG,WAAW;AAAA,UACd,GAAG,WAAW,IAAI,WAAW,aAAa;AAAA,QAC5C,IACA;AAAA,UACE,GAAG,aAAa,OAAO;AAAA,UACvB,GAAG,aAAa,SAAS;AAAA,QAC3B;AAAA,MACN;AAAA,IACF;AAEA,UAAM,iBACJ,OAAO,mBAAmB,cACtB,OACA,IAAI,eAAe,MAAM;AACvB,sBAAgB;AAAA,IAClB,CAAC;AACP,oBAAgB,QAAQ,QAAQ;AAChC,aAAS,iBAAiB,UAAU,iBAAiB,EAAE,SAAS,KAAK,CAAC;AACtE,WAAO,iBAAiB,UAAU,eAAe;AACjD,WAAO,iBAAiB,UAAU,iBAAiB;AAAA,MACjD,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAED,WAAO,MAAM;AACX,sBAAgB,WAAW;AAC3B,eAAS,oBAAoB,UAAU,eAAe;AACtD,aAAO,oBAAoB,UAAU,eAAe;AACpD,aAAO,oBAAoB,UAAU,iBAAiB,IAAI;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,YAAY,YAAY,KAAK,CAAC;AAElC,QAAM,YAAY,MAAM;AACtB,eAAW,CAAC,CAAC;AACb,mBAAe,CAAC;AAChB,iBAAa,KAAK;AAClB,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,eAAe,CAAC,kBAA0B;AAC9C,wBAAoB,UAAU;AAC9B,sBAAkB,aAAa;AAC/B,QAAI,YAAY,SAAS;AACvB,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,0BAAoB,UAAU;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,wBAAwB,CAC5B,SACA,UACG;AACH,UAAM,eAAe;AACrB,UAAM,SAAS,MAAM,cAAc,sBAAsB;AACzD,UAAM,gBACJ,MAAM,UAAU,OAAO,OAAO,OAAO,QAAQ,IACzC,QAAQ,OACR,QAAQ;AACd,iBAAa,aAAa;AAAA,EAC5B;AAEA,QAAM,yBAAyB,CAC7B,YACG;AACH,UAAM,YAAY,GAAG,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,GAAG,MAAM,MAAM,QAAQ,EAAE,CAAC;AAC3E,UAAM,gBAAgB,KAAK,IAAI,QAAQ,MAAM,UAAU,MAAM;AAC7D,wBAAoB,UAAU;AAC9B,aAAS,SAAS;AAClB,sBAAkB,aAAa;AAC/B,WAAO,sBAAsB,MAAM;AACjC,UAAI,CAAC,YAAY,SAAS;AACxB;AAAA,MACF;AACA,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,0BAAoB,UAAU;AAAA,IAChC,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,CAAC,UAAqC;AACvD,UAAM,eAAe;AAAA,MACnB;AAAA,MACA,YAAY,SAAS,kBAAkB;AAAA,MACvC;AAAA,IACF;AACA,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AACA,UAAM,gBAAgB;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,UAAM,YAAY,GAAG,MAAM,MAAM,GAAG,aAAa,IAAI,CAAC,GAAG,aAAa,GAAG,MAAM,MAAM,aAAa,EAAE,CAAC;AACrG,UAAM,gBAAgB,aAAa,OAAO,cAAc;AACxD,wBAAoB,UAAU;AAC9B,aAAS,SAAS;AAClB,cAAU;AAAA,EACZ;AAEA,QAAM,gBAAgB,CAAC,UAA8C;AACnE,QAAI,uBAAuB,KAAK,GAAG;AACjC;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,aAAa;AAC7B,YAAM,eAAe;AACrB,qBAAe,CAAC,aAAa,UAAU,KAAK,QAAQ,MAAM;AAC1D;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW;AAC3B,YAAM,eAAe;AACrB;AAAA,QACE,CAAC,aAAa,UAAU,IAAI,QAAQ,UAAU,QAAQ;AAAA,MACxD;AACA;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,OAAO;AAChD,YAAM,QAAQ,QAAQ,WAAW;AACjC,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,YAAM,eAAe;AACrB,iBAAW,KAAK;AAChB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,UAAU;AAC1B,YAAM,eAAe;AACrB,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SACE,gBAAAJ,MAAC,SAAI,WAAWM,IAAG,2BAA2B,SAAS,GACpD;AAAA,sBAAkB,4BACjB,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,uBAAuB,KAAK;AAAA,QAC5B,YAAY,eAAe;AAAA,QAC3B,WAAW,eAAe;AAAA,QAC1B,UAAU;AAAA,QACV,eAAe;AAAA;AAAA,IACjB,IACE;AAAA,IACJ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA,OACE,iBACI;AAAA,UACE,qBAAqB;AAAA,UACrB,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ;AAAA,QACV,IACA;AAAA,QAEN;AAAA,QACA,QAAQ,MAAM;AACZ,iBAAO,WAAW,MAAM;AACtB,yBAAa,KAAK;AAClB,sBAAU;AAAA,UACZ,GAAG,GAAG;AAAA,QACR;AAAA,QACA,UAAU,CAAC,UAAU;AACnB,gBAAM,oBAAoB,MAAM,OAAO,kBAAkB;AACzD,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,OAAO,kBAAkB,eAAe,aAAa;AAAA,UAC7D;AACA,4BAAkB,aAAa;AAC/B,mBAAS,MAAM,OAAO,KAAK;AAAA,QAC7B;AAAA,QACA,SAAS,CAAC,UAAU;AAClB,uBAAa,IAAI;AACjB,gBAAM,oBAAoB,MAAM,OAAO,kBAAkB;AACzD,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,OAAO,kBAAkB,eAAe,aAAa;AAAA,UAC7D;AACA,4BAAkB,aAAa;AAC/B,4BAAkB;AAAA,YAChB,MAAM,MAAM,OAAO;AAAA,YACnB,KAAK,MAAM,OAAO;AAAA,UACpB,CAAC;AAAA,QACH;AAAA,QACA,WAAW;AAAA,QACX,UAAU,CAAC,UAAU;AACnB,4BAAkB;AAAA,YAChB,MAAM,MAAM,cAAc;AAAA,YAC1B,KAAK,MAAM,cAAc;AAAA,UAC3B,CAAC;AAAA,QACH;AAAA,QACA,UAAU,CAAC,UAAU;AACnB,gBAAM,oBAAoB,MAAM,cAAc,kBAAkB;AAChE,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,cAAc,kBAAkB,eAAe,aAAa;AAAA,UACpE;AACA,4BAAkB,aAAa;AAAA,QACjC;AAAA;AAAA,IACF;AAAA,IACC;AAAA,IACA,cAAc,YACb,gBAAAA;AAAA,MAACQ;AAAA,MAAA;AAAA,QACC,MAAI;AAAA,QACJ,WAAU;AAAA,QACV,mBAAmB,CAAC,WAAW;AAAA,QAC/B,WAAW;AAAA,UACT,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,eAAe;AAAA,YACb,OAAO;AAAA,YACP,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,QAEC,kBAAQ,SAAS,IAChB,QAAQ,IAAI,CAAC,OAAO,UAClB,gBAAAR;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,MAAM;AAAA,YACb,UAAU,UAAU;AAAA,YACpB,UAAU,MAAM;AAAA,YAChB,SAAS,MAAM;AAAA,YACf,UAAU,MAAM,WAAW,KAAK;AAAA;AAAA,UAL3B,GAAG,MAAM,UAAU,IAAI,MAAM,GAAG;AAAA,QAMvC,CACD,IAED,gBAAAA,KAAC,SAAI,WAAU,gEACZ,sBAAY,KAAK,eAAe,KAAK,gBACxC;AAAA;AAAA,IAEJ,IACE;AAAA,KACN;AAEJ;;;AIvWM,gBAAAS,YAAA;AAvGN,IAAM,YAA2B;AAAA,EAC/B,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,SAAS;AAAA,EACT,UAAU;AAAA,EACV,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,YAAY;AACd;AAEA,IAAM,cACJ;AAAA,EACE,QAAQ;AAAA,IACN,YACE;AAAA,IACF,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,SAAS;AAAA,IACP,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB;AAAA,EACA,UAAU;AAAA,IACR,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAEF,SAAS,kBACJ,OACiB;AACpB,QAAM,QAAQ,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK;AACnD,SAAO,SAAS;AAClB;AAEO,SAAS,wBAA6C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyD;AACvD,QAAM,OAAO,2BAA2B,SAAS,QAAQ;AACzD,QAAM,UAA0D;AAAA,IAC9D;AAAA,IACA,UAAU;AAAA,EACZ;AACA,QAAM,QACJ,cAAc,OAAO,KACrB,8BAA8B;AAAA,IAC5B,GAAG;AAAA,IACH,OAAO,KAAK;AAAA,EACd,CAAC;AACH,QAAM,eAAe,SAAS,KAAK;AACnC,QAAM,cAAc,CAAC,UAAmC;AACtD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,eAAe;AACrB;AAAA,IACF;AACA,cAAU,OAAO;AAAA,EACnB;AAEA,QAAM,cAAc;AAAA,IAClB,aAAa,KAAK,UAAU,aAAa;AAAA,IACzC,iBAAiB,CAAC,KAAK,eAAe;AAAA,IACtC,WAAW;AAAA,MACT;AAAA,MACA,4BAA4B,KAAK,KAAK;AAAA,MACtC;AAAA,IACF;AAAA,IACA,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,KAAK;AAAA,IACnB,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,YAAY,KAAK,KAAK;AAAA,IAC3B;AAAA,IACA,OAAO;AAAA,EACT;AAEA,MAAI,KAAK,eAAe,SAAS;AAC/B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,SAAS,CAAC,UAAU;AAClB,sBAAY,KAAK;AAAA,QACnB;AAAA,QACA,OAAO;AAAA,UACL,GAAG,YAAY;AAAA,UACf,YAAY;AAAA,UACZ,MAAM;AAAA,QACR;AAAA,QACA,MAAK;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,gBAAAA,KAAC,UAAM,GAAG,aAAc,iBAAM;AACvC;;;ACnJA;AAAA,EACE,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,OACK;AACP,SAAS,MAAAC,WAAU;;;ACMZ,SAAS,oCACd,SACiC;AACjC,QAAM,WAA4C,CAAC;AACnD,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,OAAO,GAAG;AACtD,QAAI,MAAM,QAAQ,QAAQ;AACxB,eAAS,KAAK;AAAA,QACZ,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK;AAAA,QACvC,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,aAAS,KAAK;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM,SAAS,MAAM;AAAA,MAC5B,MAAM;AAAA,IACR,CAAC;AACD,aAAS,MAAM;AAAA,EACjB;AAEA,MAAI,SAAS,QAAQ,QAAQ;AAC3B,aAAS,KAAK;AAAA,MACZ,MAAM,QAAQ,MAAM,MAAM;AAAA,MAC1B,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ADgBQ,gBAAAC,MAuIJ,QAAAC,aAvII;AAxBR,IAAM,sBAAsB;AAC5B,IAAMC,2CAA0C;AAEzC,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqD;AACnD,QAAM,kBAAkB,yBAAyB,KAAK,EAAE,KAAK;AAE7D,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,gBAChB,MAAM,QAAQ,EACd,IAAI,CAAC,cAAc,UAAU,KAAK,CAAC,EACnC,OAAO,OAAO;AAEjB,SACE,gBAAAF,KAAC,SAAI,WAAWG,IAAG,aAAa,SAAS,GACtC,qBAAW,IAAI,CAAC,WAAW,mBAC1B,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAWG,IAAG,uBAAuB,kBAAkB;AAAA,MAGtD;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA;AAAA,IANK,GAAG,cAAc,IAAI,SAAS;AAAA,EAOrC,CACD,GACH;AAEJ;AAEA,SAAS,6BACP,SACA,0BAGA,iBACe;AACf,QAAM,QAAuB,CAAC;AAC9B,QAAM,WAAW,oCAAoC,OAAO;AAE5D,WAAS,QAAQ,CAAC,SAAS,UAAU;AACnC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,YAAM,KAAK,gBAAAH,KAAC,UAA4B,kBAAQ,QAA1B,QAAQ,KAAK,EAAkB,CAAO;AAC5D;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,QAAQ;AAAA,UAEd,OAAO,QAAQ;AAAA,UACf;AAAA,UACA;AAAA;AAAA,QAHK,QAAQ,KAAK,IAAI,QAAQ,IAAI;AAAA,MAIpC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOgB;AACd,QAAM,cAAc,KAAK,KAAK;AAC9B,QAAM,UAAU,yBAAyB,aAAa,KAAK;AAE3D,MAAI,SAAS;AACX,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,SACE,kBACI,CAAC,EAAE,SAAAI,SAAQ,MAAM;AACf,eAAK,gBAAgBA,QAAO;AAAA,QAC9B,IACA;AAAA;AAAA,IAER;AAAA,EAEJ;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,gBAAAJ,KAAC,UAAM,iBAAM;AAAA,EACtB;AAEA,MACE,oBAAoB,KAAK,WAAW,KACpC,CAAC,sBAAsB,WAAW,GAClC;AACA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAI;AAAA,QACJ,QAAO;AAAA,QAEN;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,QAAM,OAAO,YAAY,SAAS,GAAG,IAAI,WAAW;AACpD,QAAM,OAAO,0BAA0B,aAAa,IAAI;AAExD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AACF,GAKgB;AACd,QAAM,eAAe;AAAA,IACnB,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACA,QAAM,UACJ,gBAAAA;AAAA,IAACK;AAAA,IAAA;AAAA,MACC,WAAWH;AAAA,MACX,UAAU,UAAU;AAAA,MACpB,MAAK;AAAA,MACL,OAAO,aAAa;AAAA,MACpB,WAAW;AAAA;AAAA,EACb;AAGF,SACE,gBAAAD,MAACK,UAAA,EACC;AAAA,oBAAAN,KAACO,iBAAA,EAAe,SAAO,MACpB,qCACC,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,SAAS,MAAM;AACb,eAAK,yBAAyB,SAAS;AAAA,QACzC;AAAA,QAEC;AAAA;AAAA,IACH,IAEA,gBAAAA,KAAC,UAAK,WAAU,yCACb,mBACH,GAEJ;AAAA,IACA,gBAAAA;AAAA,MAACQ;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,YAAY;AAAA,QAEX,uBAAa;AAAA;AAAA,IAChB;AAAA,KACF;AAEJ;","names":["useEffect","useState","jsx","jsxs","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","jsx","jsxs","NodeViewWrapper","Node","mergeAttributes","ReactNodeViewRenderer","jsx","jsxs","useState","editor","useEffect","useEffect","useLayoutEffect","useMemo","useRef","useState","ViewportMenuSurface","cn","MentionPill","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","jsx","jsxs","useRef","useState","useMemo","useEffect","useLayoutEffect","cn","ViewportMenuSurface","jsx","MentionPill","Tooltip","TooltipContent","TooltipTrigger","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","cn","mention","MentionPill","Tooltip","TooltipTrigger","TooltipContent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/editor/RichTextTriggerEditor.tsx","../../src/editor/richTextTriggerQuery.ts","../../src/editor/richTextIme.ts","../../src/editor/richTextTriggerText.ts","../../src/editor/RichTextTriggerMenuItem.tsx","../../src/extensions/mentionReference.ts","../../src/extensions/MentionReferenceNodeView.tsx","../../src/extensions/workspaceReference.ts","../../src/extensions/WorkspaceReferenceNodeView.tsx","../../src/extensions/workspaceReferencePresentation.ts","../../src/editor/RichTextTriggerTextarea.tsx","../../src/editor/richTextTextareaDecorationModel.ts","../../src/editor/richTextTextareaDecorations.tsx","../../src/editor/richTextTextareaCaret.ts","../../src/editor/RichTextMentionReadonly.tsx","../../src/editor/RichTextReadonlyContent.tsx","../../src/editor/richTextReadonlyContentModel.ts"],"sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n type JSX\n} from \"react\";\nimport Document from \"@tiptap/extension-document\";\nimport HardBreak from \"@tiptap/extension-hard-break\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Text from \"@tiptap/extension-text\";\nimport type { Editor as TiptapEditor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextMentionAttrs } from \"../plugins/index.ts\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionPresentation\n} from \"../types/mention.ts\";\nimport type {\n RichTextTriggerInsertResult,\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch,\n RichTextTrigger,\n RichTextTriggerConfig\n} from \"../types/trigger.ts\";\nimport {\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextContentToDocument,\n serializeRichTextDocumentToContent\n} from \"../core/richTextDocument.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { MentionReference } from \"../extensions/mentionReference.ts\";\nimport { WorkspaceReference } from \"../extensions/workspaceReference.ts\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\n\nexport interface RichTextTriggerEditorProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n placeholderClassName?: string;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n focusSignal?: unknown;\n menuZIndex?: string | number;\n}\n\ntype RichTextEditorTriggerQueryState = {\n from: number;\n keyword: string;\n trigger: RichTextTrigger;\n to: number;\n};\n\nconst RICH_TEXT_MENTION_PRESENTATION_KEYS = [\n \"agentProviderId\",\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"subtitle\",\n \"description\",\n \"participant\",\n \"status\",\n \"statusDataStatus\",\n \"statusLabel\",\n \"statusPulse\",\n \"userAvatarPlaceholderUrl\"\n] as const satisfies readonly (keyof RichTextMentionPresentation)[];\n\nexport function RichTextTriggerEditor({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n placeholderClassName,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay,\n focusSignal,\n menuZIndex\n}: RichTextTriggerEditorProps): JSX.Element {\n const menuOffset = 6;\n const normalizedValue = normalizeRichTextContent(value);\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const latestOnChangeRef = useRef(onChange);\n const lastSerializedValueRef = useRef(normalizedValue);\n const lastFocusSignalRef = useRef(focusSignal);\n const mentionHydrationRequestRef = useRef(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const [isFocused, setIsFocused] = useState(false);\n const [query, setQuery] = useState<RichTextEditorTriggerQueryState | null>(\n null\n );\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n\n latestOnChangeRef.current = onChange;\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak,\n WorkspaceReference.configure({\n removeActionAriaLabel: text.removeReferenceActionLabel\n }),\n MentionReference\n ],\n content: parseRichTextContentToDocument(normalizedValue),\n editorProps: {\n attributes: {\n class: cn(\n \"w-full whitespace-pre-wrap break-words outline-none\",\n textareaClassName\n )\n }\n },\n onBlur() {\n window.setTimeout(() => {\n setIsFocused(false);\n setQuery(null);\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n }, 100);\n },\n onFocus() {\n setIsFocused(true);\n },\n onUpdate({ editor }) {\n const serialized = serializeRichTextDocumentToContent(editor.getJSON());\n lastSerializedValueRef.current = serialized;\n latestOnChangeRef.current(serialized);\n }\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (lastSerializedValueRef.current === normalizedValue) {\n return;\n }\n\n const currentSerialized = serializeRichTextDocumentToContent(\n editor.getJSON()\n );\n if (currentSerialized === normalizedValue) {\n lastSerializedValueRef.current = normalizedValue;\n return;\n }\n\n editor.commands.setContent(\n parseRichTextContentToDocument(normalizedValue),\n {\n emitUpdate: false\n }\n );\n lastSerializedValueRef.current = normalizedValue;\n }, [editor, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const requestId = mentionHydrationRequestRef.current + 1;\n mentionHydrationRequestRef.current = requestId;\n const mentions = collectHydratableMentionNodes(editor);\n if (mentions.length === 0) {\n return;\n }\n\n for (const mention of mentions) {\n const provider = registry.getProvider(mention.attrs.providerId);\n if (!provider?.resolveMention) {\n continue;\n }\n\n void Promise.resolve(provider.resolveMention(mention.attrs))\n .then((resolved) => {\n if (\n !resolved ||\n mentionHydrationRequestRef.current !== requestId ||\n editor.isDestroyed\n ) {\n return;\n }\n\n applyResolvedMentionAttrs(editor, mention.pos, mention.attrs, {\n label: resolved.label,\n presentation: resolved.presentation\n });\n })\n .catch(() => {\n // Resolver failures keep the fallback label-only mention.\n });\n }\n }, [editor, registry, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (Object.is(lastFocusSignalRef.current, focusSignal)) {\n return;\n }\n\n lastFocusSignalRef.current = focusSignal;\n editor.commands.focus(\"end\");\n }, [editor, focusSignal]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n editor.setEditable(!disabled);\n editor.view.dispatch(\n editor.state.tr.setMeta(\"richTextEditable\", !disabled)\n );\n }, [disabled, editor]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const updateQueryState = () => {\n const nextQuery = findEditorAtQuery(editor, activeTriggerConfigs);\n setQuery(nextQuery);\n };\n\n const updateFocus = () => {\n const nextFocused = editor.isFocused;\n setIsFocused(nextFocused);\n updateQueryState();\n };\n\n updateQueryState();\n editor.on(\"selectionUpdate\", updateQueryState);\n editor.on(\"transaction\", updateQueryState);\n editor.on(\"focus\", updateFocus);\n editor.on(\"blur\", updateFocus);\n return () => {\n editor.off(\"selectionUpdate\", updateQueryState);\n editor.off(\"transaction\", updateQueryState);\n editor.off(\"focus\", updateFocus);\n editor.off(\"blur\", updateFocus);\n };\n }, [activeTriggerConfigs, editor]);\n\n useEffect(() => {\n if (!editor || !query || activeTriggerConfigs.length === 0) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n if (query.keyword.length < minQueryLength) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n blockText: editor.state.selection.$from.parent.textBetween(\n 0,\n editor.state.selection.$from.parent.content.size,\n \"\\n\",\n \"\\uFFFC\"\n ),\n documentText: serializeRichTextDocumentToContent(editor.getJSON())\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [\n editor,\n maxResults,\n minQueryLength,\n activeTriggerConfigs.length,\n query,\n registry\n ]);\n\n useLayoutEffect(() => {\n if (!editor || !query) {\n setMenuPoint(null);\n return;\n }\n\n const updateMenuPoint = () => {\n const coords = editor.view.coordsAtPos(editor.state.selection.from);\n const nextMenuPoint = {\n x: coords.left,\n y: coords.bottom + menuOffset\n };\n setMenuPoint(nextMenuPoint);\n };\n\n updateMenuPoint();\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n return () => {\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [editor, menuOffset, query]);\n\n const canQueryTrigger =\n !!query &&\n activeTriggerConfigs.length > 0 &&\n query.keyword.length >= minQueryLength;\n const isMenuOpen = canQueryTrigger && (isFocused || !!menuPoint);\n const isEmpty =\n !editor ||\n serializeRichTextDocumentToContent(editor.getJSON()).trim().length === 0;\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n if (!editor || !query) {\n return;\n }\n\n const content = renderInsertResultAsEditorContent(\n match.providerId,\n match.insertResult\n );\n if (!content) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt({ from: query.from, to: query.to }, content)\n .run();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (!isMenuOpen) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n };\n\n return (\n <div\n className={cn(\"relative min-w-0 w-full\", className)}\n ref={containerRef}\n >\n <div className=\"w-full min-w-0\" onKeyDownCapture={handleKeyDown}>\n <EditorContent editor={editor} />\n </div>\n {isEmpty && placeholder ? (\n <div className=\"pointer-events-none absolute top-0 right-0 left-0 px-0 py-0 text-[var(--text-placeholder)]\">\n <div\n className={cn(\n \"min-w-0 w-full whitespace-pre-wrap\",\n placeholderClassName ?? textareaClassName,\n \"text-[var(--text-placeholder)]\"\n )}\n >\n {placeholder}\n </div>\n </div>\n ) : null}\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n style={menuZIndex === undefined ? undefined : { zIndex: menuZIndex }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n workspaceReferenceFileKind={getWorkspaceReferenceFileKind(\n match.insertResult\n )}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n\nfunction findEditorAtQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const query = findEditorTriggerQuery(editor, triggers);\n if (!query) {\n return null;\n }\n return query;\n}\n\nfunction findEditorTriggerQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const { selection } = editor.state;\n if (!selection.empty) {\n return null;\n }\n\n const { $from } = selection;\n if (!$from.parent.isTextblock) {\n return null;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n \"\\n\",\n \"\\uFFFC\"\n );\n const query = findRichTextTriggerQuery(\n textBeforeCursor,\n textBeforeCursor.length,\n triggers\n );\n if (!query) {\n return null;\n }\n\n const distanceFromQueryStart = textBeforeCursor.length - query.from;\n return {\n from: selection.from - distanceFromQueryStart,\n keyword: query.keyword,\n trigger: query.trigger,\n to: selection.from\n };\n}\n\nfunction renderInsertResultAsEditorContent(\n providerId: string,\n result: RichTextTriggerInsertResult\n) {\n switch (result.kind) {\n case \"mention\":\n return {\n type: mentionReferenceNodeName,\n attrs: createRichTextMentionAttrs(providerId, result.mention)\n };\n case \"markdown-link\": {\n const kind = result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n return {\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label: result.label,\n path: normalizeRichTextLinkHref(result.href, kind)\n }\n };\n }\n case \"text\":\n return result.text;\n default:\n return null;\n }\n}\n\nfunction getWorkspaceReferenceFileKind(\n result: RichTextTriggerInsertResult\n): \"file\" | \"folder\" | undefined {\n if (result.kind !== \"markdown-link\") {\n return undefined;\n }\n return result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n}\n\nfunction collectHydratableMentionNodes(\n editor: TiptapEditor\n): Array<{ attrs: RichTextMentionAttrs; pos: number }> {\n const mentions: Array<{ attrs: RichTextMentionAttrs; pos: number }> = [];\n\n editor.state.doc.descendants((node, pos) => {\n if (node.type.name !== mentionReferenceNodeName) {\n return;\n }\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.trigger !== \"@\" ||\n typeof attrs.providerId !== \"string\" ||\n !attrs.providerId.trim() ||\n typeof attrs.entityId !== \"string\" ||\n !attrs.entityId.trim() ||\n typeof attrs.label !== \"string\" ||\n !attrs.label.trim()\n ) {\n return;\n }\n\n mentions.push({\n pos,\n attrs: {\n trigger: \"@\",\n providerId: attrs.providerId.trim(),\n entityId: attrs.entityId.trim(),\n label: attrs.label.trim().replace(/^@+/, \"\").trim(),\n scope: normalizeMentionStringRecord(attrs.scope),\n presentation: normalizeMentionPresentation(attrs.presentation)\n }\n });\n });\n\n return mentions;\n}\n\nfunction applyResolvedMentionAttrs(\n editor: TiptapEditor,\n pos: number,\n currentAttrs: RichTextMentionAttrs,\n resolved: {\n label?: string;\n presentation?: RichTextMentionPresentation;\n }\n): void {\n const node = editor.state.doc.nodeAt(pos);\n if (!node || node.type.name !== mentionReferenceNodeName) {\n return;\n }\n\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.providerId !== currentAttrs.providerId ||\n attrs.entityId !== currentAttrs.entityId ||\n JSON.stringify(normalizeMentionStringRecord(attrs.scope) ?? {}) !==\n JSON.stringify(currentAttrs.scope ?? {})\n ) {\n return;\n }\n\n const nextLabel = resolved.label?.trim().replace(/^@+/, \"\").trim();\n const nextPresentation = normalizeMentionPresentation(resolved.presentation);\n const nextAttrs: RichTextMentionAttrs = {\n trigger: \"@\",\n providerId: currentAttrs.providerId,\n entityId: currentAttrs.entityId,\n label: nextLabel || currentAttrs.label,\n scope: currentAttrs.scope,\n presentation: nextPresentation ?? currentAttrs.presentation\n };\n\n if (\n attrs.label === nextAttrs.label &&\n JSON.stringify(normalizeMentionPresentation(attrs.presentation) ?? {}) ===\n JSON.stringify(nextAttrs.presentation ?? {})\n ) {\n return;\n }\n\n const transaction = editor.state.tr.setNodeMarkup(pos, undefined, nextAttrs);\n transaction.setMeta(\"addToHistory\", false);\n transaction.setMeta(\"preventUpdate\", true);\n editor.view.dispatch(transaction);\n}\n\nfunction normalizeMentionStringRecord(\n value: unknown\n): Readonly<Record<string, string>> | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .map(\n ([key, entryValue]) =>\n [\n key.trim(),\n typeof entryValue === \"string\" ? entryValue.trim() : \"\"\n ] as const\n )\n .filter(([key, entryValue]) => key.length > 0 && entryValue.length > 0)\n .sort(([left], [right]) => left.localeCompare(right));\n\n return entries.length > 0\n ? Object.freeze(Object.fromEntries(entries))\n : undefined;\n}\n\nfunction normalizeMentionPresentation(\n value: unknown\n): RichTextMentionPresentation | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const source = value as Record<keyof RichTextMentionPresentation, unknown>;\n const next: RichTextMentionPresentation = {};\n\n for (const key of RICH_TEXT_MENTION_PRESENTATION_KEYS) {\n const fieldValue = source[key];\n if (typeof fieldValue !== \"string\") {\n continue;\n }\n const trimmed = fieldValue.trim();\n if (trimmed) {\n next[key] = trimmed;\n }\n }\n\n return Object.keys(next).length > 0 ? Object.freeze(next) : undefined;\n}\n","import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nexport interface RichTextTriggerQueryState {\n from: number;\n to: number;\n keyword: string;\n trigger: RichTextTrigger;\n}\n\nexport function isRichTextTriggerPrefixBoundary(\n character: string,\n boundary: RichTextTriggerBoundary\n): boolean {\n if (boundary === \"whitespace\") {\n return /\\s/.test(character);\n }\n return /[\\s,;:!?<>{}|\\\\'\"`~()[\\]]/.test(character);\n}\n\nexport function findRichTextTriggerQuery(\n value: string,\n caret: number,\n triggerConfigs: readonly RichTextTriggerConfig[]\n): RichTextTriggerQueryState | null {\n const cursor = Math.max(0, Math.min(caret, value.length));\n if (triggerConfigs.length === 0) {\n return null;\n }\n let segmentStart = cursor;\n while (segmentStart > 0) {\n const previous = value[segmentStart - 1] ?? \"\";\n if (/\\s/.test(previous)) {\n break;\n }\n segmentStart -= 1;\n }\n\n const segment = value.slice(segmentStart, cursor);\n for (let index = segment.length - 1; index >= 0; index -= 1) {\n const trigger = segment[index] as RichTextTrigger;\n const matchingConfigs = triggerConfigs.filter(\n (config) => config.trigger === trigger\n );\n if (matchingConfigs.length === 0) {\n continue;\n }\n const previous = segment[index - 1] ?? \"\";\n if (\n index > 0 &&\n !matchingConfigs.some((config) =>\n isRichTextTriggerPrefixBoundary(previous, config.boundary)\n )\n ) {\n continue;\n }\n\n const candidate = segment.slice(index);\n if (/[[\\]()]/.test(candidate.slice(1))) {\n return null;\n }\n\n return {\n from: segmentStart + index,\n to: cursor,\n trigger,\n keyword: candidate.slice(1)\n };\n }\n\n return null;\n}\n\nexport async function queryRichTextTriggerMatches(\n registry: RichTextTriggerRegistry,\n input: RichTextTriggerQueryInput\n): Promise<readonly RichTextTriggerQueryMatch[]> {\n try {\n return await registry.query(input);\n } catch {\n return [];\n }\n}\n","export interface RichTextImeKeyboardEventLike {\n isComposing?: boolean;\n keyCode?: number;\n nativeEvent?: {\n isComposing?: boolean;\n keyCode?: number;\n which?: number;\n };\n which?: number;\n}\n\nexport function isRichTextImeComposing(\n event: RichTextImeKeyboardEventLike\n): boolean {\n if (event.isComposing || event.nativeEvent?.isComposing) {\n return true;\n }\n\n const keyCode = event.keyCode ?? event.nativeEvent?.keyCode;\n const which = event.which ?? event.nativeEvent?.which;\n return keyCode === 229 || which === 229;\n}\n","import {\n createDefaultRichTextI18nRuntime,\n type RichTextI18nRuntime\n} from \"../i18n/richTextI18n.ts\";\n\nexport interface RichTextTriggerTextOverrides {\n loadingLabel?: string;\n noMatchesLabel?: string;\n removeReferenceActionLabel?: string;\n}\n\nexport interface ResolvedRichTextTriggerText {\n loadingLabel: string;\n noMatchesLabel: string;\n removeReferenceActionLabel: string;\n}\n\nconst defaultRichTextI18n = createDefaultRichTextI18nRuntime();\n\nexport function resolveRichTextTriggerText(\n overrides?: RichTextTriggerTextOverrides,\n removeDecorationAriaLabel?: string,\n i18n: RichTextI18nRuntime = defaultRichTextI18n\n): ResolvedRichTextTriggerText {\n return {\n loadingLabel:\n overrides?.loadingLabel?.trim() || i18n.t(\"richTextAt.loading\"),\n noMatchesLabel:\n overrides?.noMatchesLabel?.trim() || i18n.t(\"richTextAt.noMatches\"),\n removeReferenceActionLabel:\n removeDecorationAriaLabel?.trim() ||\n overrides?.removeReferenceActionLabel?.trim() ||\n i18n.t(\"richTextAt.removeReferenceActionLabel\")\n };\n}\n\nexport const defaultRichTextTriggerText = resolveRichTextTriggerText();\n","import type { JSX, MouseEvent } from \"react\";\nimport { FileIcon, FolderFilledIcon } from \"@tutti-os/ui-system/icons\";\n\ntype RichTextTriggerMenuItemProps = {\n iconUrl?: string;\n label: string;\n selected: boolean;\n subtitle?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n onSelect: () => void;\n};\n\nexport function RichTextTriggerMenuItem({\n iconUrl,\n label,\n selected,\n subtitle,\n workspaceReferenceFileKind,\n onSelect\n}: RichTextTriggerMenuItemProps): JSX.Element {\n return (\n <button\n aria-selected={selected}\n className={[\n \"flex w-full cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-[var(--text-primary)] outline-0 transition-colors duration-100\",\n selected ? \"bg-[var(--transparency-block)]\" : \"\",\n \"hover:bg-[var(--transparency-block)]\"\n ].join(\" \")}\n type=\"button\"\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n onSelect();\n }}\n >\n <RichTextTriggerMenuIcon\n iconUrl={iconUrl}\n workspaceReferenceFileKind={workspaceReferenceFileKind}\n />\n <span className=\"flex min-w-0 flex-auto flex-col items-start gap-0.5\">\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[13px] leading-5 font-semibold\">\n {label}\n </span>\n {subtitle ? (\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[11px] leading-4 text-[var(--text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </span>\n </button>\n );\n}\n\nfunction RichTextTriggerMenuIcon({\n iconUrl,\n workspaceReferenceFileKind\n}: {\n iconUrl?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n}): JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n\n if (workspaceReferenceFileKind) {\n const Icon =\n workspaceReferenceFileKind === \"folder\" ? FolderFilledIcon : FileIcon;\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center text-[var(--folder)]\"\n data-rich-text-trigger-icon=\"true\"\n >\n <Icon className=\"size-4\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center overflow-hidden rounded bg-[var(--bg-block,var(--transparency-block))]\"\n data-rich-text-trigger-icon=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n alt=\"\"\n className=\"block size-full object-cover object-center\"\n decoding=\"async\"\n draggable={false}\n loading=\"lazy\"\n src={normalizedIconUrl}\n />\n ) : (\n <span className=\"block size-3 rounded-[3px] bg-[var(--transparency-block)]\" />\n )}\n </span>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { mentionReferenceNodeName } from \"./names.ts\";\nimport { MentionReferenceNodeView } from \"./MentionReferenceNodeView.tsx\";\n\nexport interface MentionReferenceAttrs {\n entityId: string;\n label: string;\n presentation?: Readonly<Record<string, string>>;\n providerId: string;\n scope?: Readonly<Record<string, string>>;\n trigger: \"@\";\n}\n\nexport const MentionReference = Node.create({\n name: mentionReferenceNodeName,\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n entityId: {\n default: \"\"\n },\n label: {\n default: \"\"\n },\n presentation: {\n default: null\n },\n providerId: {\n default: \"\"\n },\n scope: {\n default: null\n },\n trigger: {\n default: \"@\"\n }\n };\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-mention-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const displayLabel = label.trim().replace(/^@+/, \"\").trim();\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-mention-reference\": \"true\",\n class:\n \"inline-flex max-w-full items-center overflow-hidden rounded-md bg-transparency-block px-1.5 py-0.5 align-baseline text-[13px] font-medium text-[var(--text-primary)]\"\n }),\n displayLabel ? `@${displayLabel}` : \"\"\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MentionReferenceNodeView, {\n as: \"span\",\n className: \"inline-flex max-w-full align-baseline\"\n });\n }\n});\n","import type { JSX } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n type MentionPillKind\n} from \"@tutti-os/ui-system/components\";\n\nconst richTextMentionReferencePillClassName = \"max-w-[16rem]\";\n\nfunction readStringAttr(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction readMentionPresentationUrl(presentation: unknown): string | null {\n if (!presentation || typeof presentation !== \"object\") {\n return null;\n }\n const value =\n (presentation as { iconUrl?: unknown; thumbnailUrl?: unknown }).iconUrl ??\n (presentation as { thumbnailUrl?: unknown }).thumbnailUrl;\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\n// 句柄类 mention(如 workspace-reference 项目引用)的图标随 href 的 scope 编码,\n// markdown 带不了 presentation,故回退读 scope.icon,使 chip 与 agent 一样显示来源图标。\nfunction readMentionScopeValue(scope: unknown, key: string): string {\n if (!scope || typeof scope !== \"object\") {\n return \"\";\n }\n return readStringAttr((scope as Record<string, unknown>)[key]);\n}\n\n// providerId(+ workspace-reference 的 source)映射到设计系统 MentionPill 的 kind,\n// 让颜色/图标与 agent GUI 的 mention chip 完全一致。\nfunction resolveMentionPillKind(\n providerId: string,\n scope: unknown\n): MentionPillKind {\n const id = providerId.trim();\n if (id === \"agent-session\" || id === \"session\") {\n return \"session\";\n }\n if (id === \"workspace-app\") {\n return \"app\";\n }\n if (id === \"workspace-issue\") {\n return \"issue\";\n }\n if (id === \"workspace-reference\") {\n return readMentionScopeValue(scope, \"source\") === \"task\" ? \"issue\" : \"app\";\n }\n if (id === \"file\") {\n return \"file\";\n }\n return \"issue\";\n}\n\nexport function MentionReferenceNodeView({\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const label =\n typeof node.attrs.label === \"string\"\n ? node.attrs.label.trim().replace(/^@+/, \"\").trim()\n : \"\";\n const iconUrl =\n readMentionPresentationUrl(node.attrs.presentation) ||\n readMentionScopeValue(node.attrs.scope, \"icon\");\n const kind = resolveMentionPillKind(\n readStringAttr(node.attrs.providerId),\n node.attrs.scope\n );\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline${\n selected ? \" is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-mention-reference=\"true\"\n >\n <MentionPill\n className={richTextMentionReferencePillClassName}\n iconUrl={iconUrl || undefined}\n kind={kind}\n label={label}\n removable={false}\n />\n </NodeViewWrapper>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { workspaceReferenceNodeName } from \"./names.ts\";\nimport { WorkspaceReferenceNodeView } from \"./WorkspaceReferenceNodeView.tsx\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nexport interface WorkspaceReferenceAttrs {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport const WorkspaceReference = Node.create({\n name: workspaceReferenceNodeName,\n addOptions() {\n return {\n removeActionAriaLabel:\n defaultRichTextTriggerText.removeReferenceActionLabel\n };\n },\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n kind: {\n default: \"file\"\n },\n label: {\n default: \"\"\n },\n path: {\n default: \"\"\n }\n } satisfies Record<keyof WorkspaceReferenceAttrs, { default: string }>;\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-workspace-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const kind = HTMLAttributes.kind === \"folder\" ? \"folder\" : \"file\";\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const path =\n typeof HTMLAttributes.path === \"string\" ? HTMLAttributes.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const referenceColorClassName =\n kind === \"folder\"\n ? \"text-[var(--rich-text-folder)]\"\n : \"text-[var(--rich-text-mention-file)]\";\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-workspace-reference\": \"true\",\n \"data-rich-text-workspace-kind\": kind,\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": \"file\",\n \"data-slot\": \"mention-pill\",\n title: presentation.fullPath,\n class: [\n \"group relative top-[3px] inline-flex max-w-full cursor-default items-center gap-1.5 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1.5 py-0.5 align-baseline text-[13px] font-medium leading-5 no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]\",\n referenceColorClassName\n ].join(\" \")\n }),\n [\n \"span\",\n {\n \"aria-hidden\": \"true\",\n class: \"grid size-4 shrink-0 place-items-center text-current\"\n },\n kind === \"folder\" ? \"D\" : \"F\"\n ],\n [\n \"span\",\n {\n class: \"min-w-0 max-w-[20rem] truncate text-[13px] font-medium\"\n },\n presentation.displayLabel\n ]\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(WorkspaceReferenceNodeView);\n }\n});\n","import { useEffect, useState, type JSX, type PointerEvent } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function WorkspaceReferenceNodeView({\n deleteNode,\n editor,\n extension,\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const [isEditable, setIsEditable] = useState(editor.isEditable);\n const attrs = node.attrs as {\n kind?: string;\n label?: string;\n path?: string;\n };\n const extensionOptions = extension.options as {\n removeActionAriaLabel?: string;\n };\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const label = typeof attrs.label === \"string\" ? attrs.label : \"\";\n const path = typeof attrs.path === \"string\" ? attrs.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const removeActionAriaLabel =\n typeof extensionOptions.removeActionAriaLabel === \"string\"\n ? extensionOptions.removeActionAriaLabel\n : defaultRichTextTriggerText.removeReferenceActionLabel;\n\n useEffect(() => {\n const syncEditable = () => {\n setIsEditable(editor.isEditable);\n };\n\n syncEditable();\n editor.on(\"transaction\", syncEditable);\n editor.on(\"update\", syncEditable);\n return () => {\n editor.off(\"transaction\", syncEditable);\n editor.off(\"update\", syncEditable);\n };\n }, [editor]);\n\n const handleRemove = (event: PointerEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!editor.isEditable) {\n return;\n }\n deleteNode();\n };\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline ${\n selected ? \"is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-workspace-reference=\"true\"\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={isEditable}\n removeButtonProps={\n isEditable\n ? {\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: handleRemove,\n tabIndex: -1\n }\n : undefined\n }\n />\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n </NodeViewWrapper>\n );\n}\n","export interface WorkspaceReferencePresentation {\n displayLabel: string;\n fullPath: string;\n}\n\nexport function getWorkspaceReferencePresentation(\n label: string,\n path: string\n): WorkspaceReferencePresentation {\n const displayLabel = normalizeReferenceLabel(label, path);\n const fullPath = normalizeFullPath(path);\n\n return {\n displayLabel,\n fullPath\n };\n}\n\nfunction normalizeReferenceLabel(label: string, path: string): string {\n const trimmedLabel = label.trim();\n\n if (trimmedLabel !== \"\") {\n return trimmedLabel;\n }\n\n return getPathBasename(path) || path.trim();\n}\n\nfunction normalizeFullPath(path: string): string {\n return trimTrailingSeparators(path.trim());\n}\n\nfunction getPathBasename(path: string): string {\n const normalizedPath = trimTrailingSeparators(path.trim());\n\n if (normalizedPath === \"\" || isPathRoot(normalizedPath)) {\n return normalizedPath;\n }\n\n const segments = normalizedPath.split(/[\\\\/]+/).filter(Boolean);\n\n return segments.at(-1) ?? \"\";\n}\n\nfunction trimTrailingSeparators(path: string): string {\n if (path === \"\") {\n return \"\";\n }\n\n if (isPathRoot(path)) {\n return path;\n }\n\n return path.replace(/[\\\\/]+$/, \"\");\n}\n\nfunction isPathRoot(path: string): boolean {\n return (\n path === \"/\" ||\n path === \"\\\\\" ||\n path === \"//\" ||\n path === \"\\\\\\\\\" ||\n /^[A-Za-z]:[\\\\/]?$/.test(path)\n );\n}\n","import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type PointerEvent,\n type ReactNode,\n type JSX,\n type KeyboardEvent\n} from \"react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport { renderRichTextTriggerInsertResult } from \"../plugins/trigger.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch\n} from \"../types/trigger.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n buildRichTextTextareaDecorationSegments,\n getTextareaPresentationStyle,\n hasRichTextTextareaDecorations,\n resolveRichTextTextareaSelectionBoundary\n} from \"./richTextTextareaDecorationModel.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { RichTextTextareaDecoratedContent } from \"./richTextTextareaDecorations.tsx\";\nimport { getTextareaCaretViewportPoint } from \"./richTextTextareaCaret.ts\";\nimport type { CSSProperties } from \"react\";\n\nexport interface RichTextTriggerTextareaProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n rows?: number;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n}\n\nexport function RichTextTriggerTextarea({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n rows,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay\n}: RichTextTriggerTextareaProps): JSX.Element {\n const menuOffset = 6;\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [selectionStart, setSelectionStart] = useState(0);\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n const [scrollPosition, setScrollPosition] = useState({ left: 0, top: 0 });\n const [textareaPresentationStyle, setTextareaPresentationStyle] =\n useState<CSSProperties | null>(null);\n const pendingSelectionRef = useRef<number | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const decorationSegments = useMemo(\n () => buildRichTextTextareaDecorationSegments(value),\n [value]\n );\n const hasDecorations = hasRichTextTextareaDecorations(decorationSegments);\n const query = useMemo(\n () =>\n isFocused\n ? findRichTextTriggerQuery(value, selectionStart, activeTriggerConfigs)\n : null,\n [activeTriggerConfigs, isFocused, selectionStart, value]\n );\n const shouldQuery =\n query !== null &&\n query.keyword.length >= minQueryLength &&\n activeTriggerConfigs.length > 0;\n const isMenuOpen =\n isFocused && shouldQuery && (isLoading || matches.length > 0);\n\n useEffect(() => {\n const nextSelection = pendingSelectionRef.current;\n if (nextSelection === null || !textareaRef.current) {\n return;\n }\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }, [value]);\n\n useEffect(() => {\n if (!shouldQuery || !query) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n documentText: value,\n blockText: value\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [maxResults, query, registry, shouldQuery, value]);\n\n useLayoutEffect(() => {\n if (!textareaRef.current || !hasDecorations) {\n setTextareaPresentationStyle(null);\n return;\n }\n\n const textarea = textareaRef.current;\n setTextareaPresentationStyle(getTextareaPresentationStyle(textarea));\n setScrollPosition({\n left: textarea.scrollLeft,\n top: textarea.scrollTop\n });\n }, [hasDecorations, textareaClassName, value]);\n\n useLayoutEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n setMenuPoint(null);\n return;\n }\n\n const caretPoint = getTextareaCaretViewportPoint(\n textareaRef.current,\n query.to\n );\n const textareaRect = textareaRef.current.getBoundingClientRect();\n\n if (!caretPoint) {\n setMenuPoint({\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n });\n return;\n }\n\n setMenuPoint({\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n });\n }, [isMenuOpen, menuOffset, query, selectionStart, value]);\n\n useEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n return;\n }\n\n const textarea = textareaRef.current;\n const updateMenuPoint = () => {\n const caretPoint = getTextareaCaretViewportPoint(textarea, query.to);\n const textareaRect = textarea.getBoundingClientRect();\n\n setMenuPoint(\n caretPoint\n ? {\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n }\n : {\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n }\n );\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => {\n updateMenuPoint();\n });\n resizeObserver?.observe(textarea);\n textarea.addEventListener(\"scroll\", updateMenuPoint, { passive: true });\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n\n return () => {\n resizeObserver?.disconnect();\n textarea.removeEventListener(\"scroll\", updateMenuPoint);\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [isMenuOpen, menuOffset, query]);\n\n const closeMenu = () => {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const setSelection = (nextSelection: number) => {\n pendingSelectionRef.current = nextSelection;\n setSelectionStart(nextSelection);\n if (textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }\n };\n\n const handleClickDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => {\n event.preventDefault();\n const bounds = event.currentTarget.getBoundingClientRect();\n const nextSelection =\n event.clientX < bounds.left + bounds.width / 2\n ? segment.from\n : segment.to;\n setSelection(nextSelection);\n };\n\n const handleRemoveDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>\n ) => {\n const nextValue = `${value.slice(0, segment.from)}${value.slice(segment.to)}`;\n const nextSelection = Math.min(segment.from, nextValue.length);\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n setSelectionStart(nextSelection);\n window.requestAnimationFrame(() => {\n if (!textareaRef.current) {\n return;\n }\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n });\n };\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n const currentQuery = findRichTextTriggerQuery(\n value,\n textareaRef.current?.selectionStart ?? selectionStart,\n activeTriggerConfigs\n );\n if (!currentQuery) {\n return;\n }\n const insertedValue = renderRichTextTriggerInsertResult(\n match.providerId,\n match.insertResult\n );\n const nextValue = `${value.slice(0, currentQuery.from)}${insertedValue}${value.slice(currentQuery.to)}`;\n const nextSelection = currentQuery.from + insertedValue.length;\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n closeMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n closeMenu();\n }\n };\n\n return (\n <div className={cn(\"relative min-w-0 w-full\", className)}>\n {hasDecorations && textareaPresentationStyle ? (\n <RichTextTextareaDecoratedContent\n onClickSegment={handleClickDecoration}\n onRemoveSegment={handleRemoveDecoration}\n removeActionAriaLabel={text.removeReferenceActionLabel}\n scrollLeft={scrollPosition.left}\n scrollTop={scrollPosition.top}\n segments={decorationSegments}\n textareaStyle={textareaPresentationStyle}\n />\n ) : null}\n <textarea\n ref={textareaRef}\n className={textareaClassName}\n disabled={disabled}\n placeholder={placeholder}\n rows={rows}\n style={\n hasDecorations\n ? {\n WebkitTextFillColor: \"transparent\",\n caretColor: \"var(--text-primary)\",\n color: \"transparent\",\n position: \"relative\",\n zIndex: 0\n }\n : undefined\n }\n value={value}\n onBlur={() => {\n window.setTimeout(() => {\n setIsFocused(false);\n closeMenu();\n }, 100);\n }}\n onChange={(event) => {\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n onChange(event.target.value);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n setScrollPosition({\n left: event.target.scrollLeft,\n top: event.target.scrollTop\n });\n }}\n onKeyDown={handleKeyDown}\n onScroll={(event) => {\n setScrollPosition({\n left: event.currentTarget.scrollLeft,\n top: event.currentTarget.scrollTop\n });\n }}\n onSelect={(event) => {\n const rawSelectionStart = event.currentTarget.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.currentTarget.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n }}\n />\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n dismissIgnoreRefs={[textareaRef]}\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\n\nconst TEXTAREA_PRESENTATION_STYLE_PROPERTIES = [\n { styleName: \"paddingTop\", cssName: \"padding-top\" },\n { styleName: \"paddingRight\", cssName: \"padding-right\" },\n { styleName: \"paddingBottom\", cssName: \"padding-bottom\" },\n { styleName: \"paddingLeft\", cssName: \"padding-left\" },\n { styleName: \"fontFamily\", cssName: \"font-family\" },\n { styleName: \"fontFeatureSettings\", cssName: \"font-feature-settings\" },\n { styleName: \"fontKerning\", cssName: \"font-kerning\" },\n { styleName: \"fontOpticalSizing\", cssName: \"font-optical-sizing\" },\n { styleName: \"fontSize\", cssName: \"font-size\" },\n { styleName: \"fontStretch\", cssName: \"font-stretch\" },\n { styleName: \"fontStyle\", cssName: \"font-style\" },\n { styleName: \"fontVariant\", cssName: \"font-variant\" },\n { styleName: \"fontVariationSettings\", cssName: \"font-variation-settings\" },\n { styleName: \"fontWeight\", cssName: \"font-weight\" },\n { styleName: \"letterSpacing\", cssName: \"letter-spacing\" },\n { styleName: \"lineHeight\", cssName: \"line-height\" },\n { styleName: \"textAlign\", cssName: \"text-align\" },\n { styleName: \"textIndent\", cssName: \"text-indent\" },\n { styleName: \"textTransform\", cssName: \"text-transform\" },\n { styleName: \"tabSize\", cssName: \"tab-size\" },\n { styleName: \"MozTabSize\", cssName: \"-moz-tab-size\" }\n] as const satisfies readonly {\n styleName: keyof CSSProperties;\n cssName: string;\n}[];\n\ntype RichTextTextareaTextDecorationSegment = {\n type: \"text\";\n text: string;\n from: number;\n to: number;\n};\n\ntype RichTextTextareaLinkDecorationSegment = {\n type: \"link\";\n text: string;\n from: number;\n to: number;\n label: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextTextareaDecorationSegment =\n | RichTextTextareaTextDecorationSegment\n | RichTextTextareaLinkDecorationSegment;\n\nfunction isDecoratableMarkdownHref(href: string): boolean {\n const trimmedHref = href.trim();\n if (!trimmedHref) {\n return false;\n }\n if (\n EXTERNAL_LINK_PREFIX.test(trimmedHref) ||\n MENTION_LINK_PREFIX.test(trimmedHref)\n ) {\n return false;\n }\n return true;\n}\n\nexport function buildRichTextTextareaDecorationSegments(\n value: string\n): RichTextTextareaDecorationSegment[] {\n const segments: RichTextTextareaDecorationSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const { index, source, to } = match;\n\n if (index > cursor) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor, index),\n from: cursor,\n to: index\n });\n }\n\n if (label && href && isDecoratableMarkdownHref(href)) {\n segments.push({\n type: \"link\",\n text: source,\n from: index,\n to,\n label,\n href,\n kind: href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n } else {\n segments.push({\n type: \"text\",\n text: source,\n from: index,\n to\n });\n }\n\n cursor = to;\n }\n\n if (cursor < value.length) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor),\n from: cursor,\n to: value.length\n });\n }\n\n return segments;\n}\n\nexport function hasRichTextTextareaDecorations(\n segments: readonly RichTextTextareaDecorationSegment[]\n): boolean {\n return segments.some((segment) => segment.type === \"link\");\n}\n\nexport function resolveRichTextTextareaSelectionBoundary(\n segments: readonly RichTextTextareaDecorationSegment[],\n selectionStart: number\n): number | null {\n for (const segment of segments) {\n if (segment.type !== \"link\") {\n continue;\n }\n if (selectionStart <= segment.from || selectionStart >= segment.to) {\n continue;\n }\n const midpoint = segment.from + (segment.to - segment.from) / 2;\n return selectionStart < midpoint ? segment.from : segment.to;\n }\n return null;\n}\n\nfunction setTextareaPresentationStyleValue<K extends keyof CSSProperties>(\n styleRecord: CSSProperties,\n styleName: K,\n value: string\n): void {\n styleRecord[styleName] = value as CSSProperties[K];\n}\n\nexport function getTextareaPresentationStyle(\n textarea: HTMLTextAreaElement\n): CSSProperties {\n const computedStyle = window.getComputedStyle(textarea);\n const styleRecord: CSSProperties = {\n whiteSpace: \"pre-wrap\"\n };\n\n setTextareaPresentationStyleValue(\n styleRecord,\n \"wordBreak\",\n computedStyle.wordBreak\n );\n setTextareaPresentationStyleValue(\n styleRecord,\n \"overflowWrap\",\n computedStyle.overflowWrap\n );\n\n for (const { styleName, cssName } of TEXTAREA_PRESENTATION_STYLE_PROPERTIES) {\n setTextareaPresentationStyleValue(\n styleRecord,\n styleName,\n computedStyle.getPropertyValue(cssName)\n );\n }\n\n return styleRecord;\n}\n","import type { CSSProperties, JSX, PointerEvent } from \"react\";\nimport { MentionPill } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport type { RichTextTextareaDecorationSegment } from \"./richTextTextareaDecorationModel.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextTextareaDecoratedContent({\n onClickSegment,\n onRemoveSegment,\n removeActionAriaLabel,\n scrollLeft,\n scrollTop,\n segments,\n textareaStyle\n}: {\n onClickSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => void;\n onRemoveSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>\n ) => void;\n removeActionAriaLabel?: string;\n scrollLeft: number;\n scrollTop: number;\n segments: readonly RichTextTextareaDecorationSegment[];\n textareaStyle: CSSProperties;\n}): JSX.Element {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-10 overflow-hidden\">\n <div\n className=\"min-h-full min-w-full\"\n style={{\n ...textareaStyle,\n transform: `translate(${-scrollLeft}px, ${-scrollTop}px)`\n }}\n >\n {segments.map((segment, index) => {\n if (segment.type === \"text\") {\n return <span key={index}>{segment.text}</span>;\n }\n\n return (\n <span key={index} className=\"relative\">\n <span aria-hidden=\"true\" className=\"text-transparent\">\n {segment.text}\n </span>\n <MentionPill\n className={cn(\n \"pointer-events-auto absolute inset-y-0 left-0 pr-1 pl-1.5\",\n richTextWorkspaceReferencePillClassName\n )}\n fileKind={segment.kind}\n kind=\"file\"\n label={segment.label}\n removeButtonProps={{\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: (event) => {\n event.preventDefault();\n event.stopPropagation();\n onRemoveSegment(segment);\n }\n }}\n summary={\n <span\n className={cn(\n \"min-w-0 truncate text-[11px] text-current opacity-80\",\n segment.kind === \"folder\"\n ? \"max-w-[18rem]\"\n : \"max-w-[20rem]\"\n )}\n >\n {segment.href}\n </span>\n }\n onPointerDown={(event) => {\n onClickSegment(segment, event);\n }}\n />\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","const TEXTAREA_MIRROR_STYLE_PROPERTIES = [\n \"boxSizing\",\n \"width\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"borderTopStyle\",\n \"borderRightStyle\",\n \"borderBottomStyle\",\n \"borderLeftStyle\",\n \"borderTopColor\",\n \"borderRightColor\",\n \"borderBottomColor\",\n \"borderLeftColor\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontFeatureSettings\",\n \"fontKerning\",\n \"fontOpticalSizing\",\n \"fontSize\",\n \"fontStretch\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontVariationSettings\",\n \"fontWeight\",\n \"letterSpacing\",\n \"lineHeight\",\n \"textAlign\",\n \"textDecoration\",\n \"textIndent\",\n \"textTransform\",\n \"wordBreak\",\n \"overflowWrap\",\n \"tabSize\",\n \"MozTabSize\"\n] as const;\n\nexport interface TextareaCaretViewportPoint {\n x: number;\n y: number;\n lineHeight: number;\n}\n\nfunction parsePixelValue(value: string | null | undefined): number | null {\n if (!value || value === \"normal\") {\n return null;\n }\n\n const parsedValue = Number.parseFloat(value);\n return Number.isFinite(parsedValue) ? parsedValue : null;\n}\n\nfunction resolveLineHeight(computedStyle: CSSStyleDeclaration): number {\n const explicitLineHeight = parsePixelValue(computedStyle.lineHeight);\n if (explicitLineHeight !== null) {\n return explicitLineHeight;\n }\n\n const fontSize = parsePixelValue(computedStyle.fontSize);\n return fontSize !== null ? fontSize * 1.4 : 20;\n}\n\nexport function getTextareaCaretViewportPoint(\n textarea: HTMLTextAreaElement,\n selectionStart: number\n): TextareaCaretViewportPoint | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const safeSelectionStart = Math.max(\n 0,\n Math.min(selectionStart, textarea.value.length)\n );\n const textareaRect = textarea.getBoundingClientRect();\n const computedStyle = window.getComputedStyle(textarea);\n const mirror = document.createElement(\"div\");\n const marker = document.createElement(\"span\");\n\n mirror.setAttribute(\"aria-hidden\", \"true\");\n mirror.style.position = \"fixed\";\n mirror.style.left = `${textareaRect.left}px`;\n mirror.style.top = `${textareaRect.top}px`;\n mirror.style.visibility = \"hidden\";\n mirror.style.pointerEvents = \"none\";\n mirror.style.overflow = \"hidden\";\n\n for (const propertyName of TEXTAREA_MIRROR_STYLE_PROPERTIES) {\n (mirror.style as CSSStyleDeclaration & Record<string, string>)[\n propertyName\n ] =\n (\n computedStyle as CSSStyleDeclaration &\n Record<string, string | undefined>\n )[propertyName] ?? \"\";\n }\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordBreak = computedStyle.wordBreak;\n mirror.style.overflowWrap = computedStyle.overflowWrap;\n\n const preSelectionText = textarea.value.slice(0, safeSelectionStart);\n mirror.textContent = preSelectionText.length > 0 ? preSelectionText : \"\";\n if (preSelectionText.endsWith(\"\\n\")) {\n mirror.append(document.createTextNode(\"\\u200b\"));\n }\n\n marker.textContent = \"\\u200b\";\n mirror.append(marker);\n document.body.append(mirror);\n\n try {\n const markerRect = marker.getBoundingClientRect();\n const lineHeight = resolveLineHeight(computedStyle);\n\n return {\n x: markerRect.left - textarea.scrollLeft,\n y: markerRect.top - textarea.scrollTop,\n lineHeight\n };\n } finally {\n mirror.remove();\n }\n}\n","import type { CSSProperties, JSX, MouseEvent, ReactNode } from \"react\";\nimport {\n getRichTextMentionDisplayText,\n resolveRichTextMentionView\n} from \"../plugins/mention.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nexport interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved: RichTextResolvedMentionView<TResolved>;\n}\n\nexport interface RichTextMentionReadonlyProps<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved?: RichTextResolvedMention<TResolved> | null;\n className?: string;\n title?: string;\n onClick?: (payload: RichTextMentionReadonlyClickPayload<TResolved>) => void;\n renderLabel?: (\n payload: RichTextMentionReadonlyClickPayload<TResolved>\n ) => ReactNode;\n}\n\nconst baseStyle: CSSProperties = {\n alignItems: \"center\",\n border: \"1px solid transparent\",\n borderRadius: \"999px\",\n display: \"inline-flex\",\n fontSize: \"0.95em\",\n gap: \"0.25rem\",\n lineHeight: 1.4,\n maxWidth: \"100%\",\n padding: \"0.05rem 0.45rem\",\n textDecoration: \"none\",\n verticalAlign: \"baseline\",\n whiteSpace: \"nowrap\"\n};\n\nconst stateStyles: Record<RichTextResolvedMentionView[\"state\"], CSSProperties> =\n {\n active: {\n background:\n \"var(--tutti-rich-text-mention-active-bg, color-mix(in srgb, currentColor 12%, transparent))\",\n color: \"var(--tutti-rich-text-mention-active-fg, inherit)\",\n cursor: \"pointer\"\n },\n missing: {\n background:\n \"var(--tutti-rich-text-mention-missing-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-missing-fg, color-mix(in srgb, currentColor 48%, transparent))\",\n cursor: \"default\",\n textDecoration: \"line-through\"\n },\n disabled: {\n background:\n \"var(--tutti-rich-text-mention-disabled-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-disabled-fg, color-mix(in srgb, currentColor 58%, transparent))\",\n cursor: \"not-allowed\",\n opacity: 0.88\n },\n loading: {\n background:\n \"var(--tutti-rich-text-mention-loading-bg, color-mix(in srgb, currentColor 8%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-loading-fg, color-mix(in srgb, currentColor 82%, transparent))\",\n cursor: \"progress\",\n opacity: 0.92\n }\n };\n\nfunction joinClassNames(\n ...parts: Array<string | null | undefined | false>\n): string | undefined {\n const value = parts.filter(Boolean).join(\" \").trim();\n return value || undefined;\n}\n\nexport function RichTextMentionReadonly<TResolved = unknown>({\n mention,\n resolved,\n className,\n title,\n onClick,\n renderLabel\n}: RichTextMentionReadonlyProps<TResolved>): JSX.Element {\n const view = resolveRichTextMentionView(mention, resolved);\n const payload: RichTextMentionReadonlyClickPayload<TResolved> = {\n mention,\n resolved: view as RichTextResolvedMentionView<TResolved>\n };\n const label =\n renderLabel?.(payload) ??\n getRichTextMentionDisplayText({\n ...mention,\n label: view.label\n });\n const elementTitle = title ?? view.tooltip;\n const handleClick = (event: MouseEvent<HTMLElement>) => {\n if (!view.interactive) {\n event.preventDefault();\n return;\n }\n onClick?.(payload);\n };\n\n const sharedProps = {\n \"aria-busy\": view.state === \"loading\" || undefined,\n \"aria-disabled\": !view.interactive || undefined,\n className: joinClassNames(\n \"tutti-rich-text-mention\",\n `tutti-rich-text-mention--${view.state}`,\n className\n ),\n \"data-provider-id\": mention.providerId,\n \"data-state\": view.state,\n style: {\n ...baseStyle,\n ...stateStyles[view.state]\n },\n title: elementTitle\n } as const;\n\n if (view.interactive && onClick) {\n return (\n <button\n {...sharedProps}\n onClick={(event) => {\n handleClick(event);\n }}\n style={{\n ...sharedProps.style,\n appearance: \"none\",\n font: \"inherit\"\n }}\n type=\"button\"\n >\n {label}\n </button>\n );\n }\n\n return <span {...sharedProps}>{label}</span>;\n}\n","import type { JSX } from \"react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport {\n isRichTextMentionHref,\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextMentionHref\n} from \"../core/richTextDocument.ts\";\nimport { getWorkspaceReferencePresentation } from \"../extensions/workspaceReferencePresentation.ts\";\nimport { RichTextMentionReadonly } from \"./RichTextMentionReadonly.tsx\";\nimport { buildRichTextReadonlyInlineSegments } from \"./richTextReadonlyContentModel.ts\";\nimport type { RichTextMentionAttrs } from \"../types/mention.ts\";\n\nexport interface RichTextReadonlyWorkspaceReference {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport interface RichTextReadonlyContentProps {\n value: string;\n className?: string;\n paragraphClassName?: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}\n\nconst externalHrefPattern = /^(?:[a-z]+:)?\\/\\//i;\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextReadonlyContent({\n value,\n className,\n paragraphClassName,\n onMentionAction,\n onOpenWorkspaceReference\n}: RichTextReadonlyContentProps): JSX.Element | null {\n const normalizedValue = normalizeRichTextContent(value).trim();\n\n if (!normalizedValue) {\n return null;\n }\n\n const paragraphs = normalizedValue\n .split(/\\n{2,}/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {paragraphs.map((paragraph, paragraphIndex) => (\n <p\n className={cn(\"whitespace-pre-wrap\", paragraphClassName)}\n key={`${paragraphIndex}:${paragraph}`}\n >\n {renderReadonlyInlineMarkdown(\n paragraph,\n onOpenWorkspaceReference,\n onMentionAction\n )}\n </p>\n ))}\n </div>\n );\n}\n\nfunction renderReadonlyInlineMarkdown(\n content: string,\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>,\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>\n): JSX.Element[] {\n const parts: JSX.Element[] = [];\n const segments = buildRichTextReadonlyInlineSegments(content);\n\n segments.forEach((segment, index) => {\n if (segment.type === \"text\") {\n parts.push(<span key={`text:${index}`}>{segment.text}</span>);\n return;\n }\n\n parts.push(\n <RichTextReadonlyInlineLink\n href={segment.href}\n key={`link:${index}:${segment.href}`}\n label={segment.label}\n onMentionAction={onMentionAction}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n });\n\n return parts;\n}\n\nfunction RichTextReadonlyInlineLink({\n href,\n label,\n onMentionAction,\n onOpenWorkspaceReference\n}: {\n href: string;\n label: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const trimmedHref = href.trim();\n const mention = parseRichTextMentionHref(trimmedHref, label);\n\n if (mention) {\n return (\n <RichTextMentionReadonly\n mention={mention}\n onClick={\n onMentionAction\n ? ({ mention }) => {\n void onMentionAction(mention);\n }\n : undefined\n }\n />\n );\n }\n\n if (!trimmedHref) {\n return <span>{label}</span>;\n }\n\n if (\n externalHrefPattern.test(trimmedHref) &&\n !isRichTextMentionHref(trimmedHref)\n ) {\n return (\n <a\n className=\"font-medium text-[var(--text-primary)] underline decoration-[var(--border-1)] underline-offset-4 hover:text-[var(--text-primary-hover)]\"\n href={trimmedHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n </a>\n );\n }\n\n const kind = trimmedHref.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(trimmedHref, kind);\n\n return (\n <WorkspaceReferenceReadonly\n reference={{\n kind,\n label,\n path\n }}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n}\n\nfunction WorkspaceReferenceReadonly({\n reference,\n onOpenWorkspaceReference\n}: {\n reference: RichTextReadonlyWorkspaceReference;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const presentation = getWorkspaceReferencePresentation(\n reference.label,\n reference.path\n );\n const content = (\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={reference.kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={false}\n />\n );\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {onOpenWorkspaceReference ? (\n <button\n className=\"inline-flex max-w-full appearance-none items-baseline bg-transparent p-0 text-inherit\"\n type=\"button\"\n onClick={() => {\n void onOpenWorkspaceReference(reference);\n }}\n >\n {content}\n </button>\n ) : (\n <span className=\"inline-flex max-w-full align-baseline\">\n {content}\n </span>\n )}\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n );\n}\n","import { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nexport type RichTextReadonlyInlineSegment =\n | {\n text: string;\n type: \"text\";\n }\n | {\n href: string;\n label: string;\n type: \"link\";\n };\n\nexport function buildRichTextReadonlyInlineSegments(\n content: string\n): RichTextReadonlyInlineSegment[] {\n const segments: RichTextReadonlyInlineSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(content)) {\n if (match.index > cursor) {\n segments.push({\n text: content.slice(cursor, match.index),\n type: \"text\"\n });\n }\n\n segments.push({\n href: match.href,\n label: match.label || match.href,\n type: \"link\"\n });\n cursor = match.to;\n }\n\n if (cursor < content.length) {\n segments.push({\n text: content.slice(cursor),\n type: \"text\"\n });\n }\n\n return segments;\n}\n"],"mappings":"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","names":["useEffect","useState","jsx","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","MentionPill","jsx","jsxs","NodeViewWrapper","MentionPill","Node","mergeAttributes","ReactNodeViewRenderer","jsx","jsxs","useState","editor","useEffect","useEffect","useLayoutEffect","useMemo","useRef","useState","ViewportMenuSurface","cn","MentionPill","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","jsx","jsxs","useRef","useState","useMemo","useEffect","useLayoutEffect","cn","ViewportMenuSurface","jsx","MentionPill","Tooltip","TooltipContent","TooltipTrigger","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","cn","mention","MentionPill","Tooltip","TooltipTrigger","TooltipContent"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/ui-rich-text",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"directory": "packages/ui/rich-text"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@tutti-os/ui-i18n-runtime": "0.0.
|
|
48
|
-
"@tutti-os/ui-system": "0.0.
|
|
47
|
+
"@tutti-os/ui-i18n-runtime": "0.0.18",
|
|
48
|
+
"@tutti-os/ui-system": "0.0.18",
|
|
49
49
|
"@tiptap/core": "^3.23.6",
|
|
50
50
|
"@tiptap/extension-document": "^3.23.6",
|
|
51
51
|
"@tiptap/extension-hard-break": "^3.23.6",
|