@burdenoff/fe-libs 2026.713.2 → 2026.713.3
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/shared/components/assistantWidget/AssistantWidget.d.ts +16 -0
- package/dist/shared/components/assistantWidget/AssistantWidget.d.ts.map +1 -1
- package/dist/shared/components/assistantWidget/AssistantWidget.js +251 -163
- package/dist/shared/components/assistantWidget/MessageContent.d.ts +11 -0
- package/dist/shared/components/assistantWidget/MessageContent.d.ts.map +1 -0
- package/dist/shared/components/assistantWidget/MessageContent.js +32 -0
- package/dist/shared/components/assistantWidget/types.d.ts +17 -0
- package/dist/shared/components/assistantWidget/types.d.ts.map +1 -1
- package/dist/shared/components/index.d.ts +1 -1
- package/dist/shared/components/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -13,6 +13,22 @@ export interface AssistantWidgetProps {
|
|
|
13
13
|
launcherClassName?: string;
|
|
14
14
|
/** Speech-recognition language tag. */
|
|
15
15
|
voiceLang?: string;
|
|
16
|
+
/**
|
|
17
|
+
* `floating` (default) — the small bottom-right popover every product uses.
|
|
18
|
+
* `sidebar` — a full-height panel docked to the right edge, for products whose
|
|
19
|
+
* assistant does long multi-step work worth watching (BigConsole).
|
|
20
|
+
*
|
|
21
|
+
* Defaulted, so a product that passes nothing keeps the exact UI it has today.
|
|
22
|
+
*/
|
|
23
|
+
layout?: 'floating' | 'sidebar';
|
|
24
|
+
/**
|
|
25
|
+
* Show the conversations rail (New chat / Clear chat / History).
|
|
26
|
+
* Ignored unless the transport actually implements session management —
|
|
27
|
+
* a panel whose buttons do nothing is worse than no panel.
|
|
28
|
+
*/
|
|
29
|
+
showSessionPanel?: boolean;
|
|
30
|
+
/** Route in-app links from assistant replies without a full page reload. */
|
|
31
|
+
onNavigate?: (href: string) => void;
|
|
16
32
|
}
|
|
17
33
|
/** External toggle hook so command palettes / plugins can open the widget. */
|
|
18
34
|
export declare const ASSISTANT_WIDGET_TOGGLE_EVENT = "bf:toggle-assistant-widget";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantWidget.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/AssistantWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantWidget.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/AssistantWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AAef,OAAO,KAAK,EAA2B,kBAAkB,EAA0B,MAAM,SAAS,CAAC;AAEnG,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,+BAA+B,CAAC;AAyB1E,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA+epD,CAAC"}
|
|
@@ -1,86 +1,120 @@
|
|
|
1
1
|
import { cn as e } from "../../utils/cn.js";
|
|
2
2
|
import { useVoiceInput as t } from "./useVoiceInput.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { MessageContent as n } from "./MessageContent.js";
|
|
4
|
+
import { useCallback as r, useEffect as i, useMemo as ee, useRef as a, useState as o } from "react";
|
|
5
|
+
import { History as te, Loader2 as s, MessageCircle as ne, Mic as c, Plus as re, Send as ie, Sparkles as l, Trash2 as u, X as d } from "lucide-react";
|
|
6
|
+
import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
6
7
|
//#region src/shared/components/assistantWidget/AssistantWidget.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
8
|
+
var h = "bf:toggle-assistant-widget", g = "bf:assistant-widget:isOpen";
|
|
9
|
+
function _() {
|
|
9
10
|
if (typeof window > "u") return !1;
|
|
10
11
|
try {
|
|
11
|
-
return window.sessionStorage.getItem(
|
|
12
|
+
return window.sessionStorage.getItem(g) === "1";
|
|
12
13
|
} catch {
|
|
13
14
|
return !1;
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
|
-
function
|
|
17
|
+
function v(e) {
|
|
17
18
|
if (!(typeof window > "u")) try {
|
|
18
|
-
window.sessionStorage.setItem(
|
|
19
|
+
window.sessionStorage.setItem(g, e ? "1" : "0");
|
|
19
20
|
} catch {}
|
|
20
21
|
}
|
|
21
|
-
function
|
|
22
|
+
function y() {
|
|
22
23
|
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
23
24
|
}
|
|
24
|
-
var
|
|
25
|
-
let [
|
|
26
|
-
|
|
27
|
-
}, []),
|
|
28
|
-
|
|
29
|
-
}, []),
|
|
30
|
-
|
|
25
|
+
var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do things on this screen — I can run them for you.", placeholder: ae = "Ask anything, or describe what to create…", launcherClassName: S, voiceLang: C = "en-US", layout: w = "floating", showSessionPanel: T = !1, onNavigate: E }) => {
|
|
26
|
+
let [D, O] = o(() => _()), [k, A] = o([]), [j, M] = o(""), [N, P] = o(!1), [F, I] = o(!1), [L, R] = o([]), [z, B] = o(!1), V = a(null), H = a(null), U = a(null), W = a(!1), G = w === "sidebar", K = T && !!(g.newSession && g.clearSession), q = t(C), J = r(() => {
|
|
27
|
+
v(!0), O(!0);
|
|
28
|
+
}, []), Y = r(() => {
|
|
29
|
+
v(!1), O(!1);
|
|
30
|
+
}, []), X = r(() => {
|
|
31
|
+
O((e) => {
|
|
31
32
|
let t = !e;
|
|
32
|
-
return
|
|
33
|
+
return v(t), t;
|
|
33
34
|
});
|
|
34
35
|
}, []);
|
|
35
|
-
|
|
36
|
+
i(() => {
|
|
36
37
|
let e = (e) => {
|
|
37
38
|
let t = e.detail;
|
|
38
|
-
t?.open === !0 ?
|
|
39
|
+
t?.open === !0 ? J() : t?.open === !1 ? Y() : X();
|
|
39
40
|
};
|
|
40
|
-
return window.addEventListener(
|
|
41
|
+
return window.addEventListener(h, e), () => window.removeEventListener(h, e);
|
|
41
42
|
}, [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
]),
|
|
46
|
-
|
|
47
|
-
}, [
|
|
48
|
-
if (!
|
|
49
|
-
let e =
|
|
43
|
+
J,
|
|
44
|
+
Y,
|
|
45
|
+
X
|
|
46
|
+
]), i(() => {
|
|
47
|
+
q.isListening && q.transcript && M(q.transcript);
|
|
48
|
+
}, [q.transcript, q.isListening]), i(() => {
|
|
49
|
+
if (!D || W.current) return;
|
|
50
|
+
let e = g.loadHistory;
|
|
50
51
|
if (!e) {
|
|
51
|
-
|
|
52
|
+
W.current = !0;
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
W.current = !0;
|
|
55
56
|
let t = !1;
|
|
56
|
-
return
|
|
57
|
+
return I(!0), (async () => {
|
|
57
58
|
try {
|
|
58
59
|
let n = await e();
|
|
59
|
-
!t && n.length > 0 &&
|
|
60
|
+
!t && n.length > 0 && A((e) => e.length === 0 ? n : e);
|
|
60
61
|
} catch {} finally {
|
|
61
|
-
t ||
|
|
62
|
+
t || I(!1);
|
|
62
63
|
}
|
|
63
64
|
})(), () => {
|
|
64
65
|
t = !0;
|
|
65
66
|
};
|
|
66
|
-
}, [
|
|
67
|
-
|
|
68
|
-
}, [
|
|
69
|
-
let
|
|
70
|
-
|
|
67
|
+
}, [D, g]), i(() => {
|
|
68
|
+
D && H.current && (H.current.scrollTop = H.current.scrollHeight);
|
|
69
|
+
}, [k, D]);
|
|
70
|
+
let Z = r((e, t) => {
|
|
71
|
+
A((n) => n.map((n) => n.id === e ? {
|
|
71
72
|
...n,
|
|
72
73
|
...t
|
|
73
74
|
} : n));
|
|
74
|
-
}, []),
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
}, []), Q = r(async () => {
|
|
76
|
+
if (g.listSessions) try {
|
|
77
|
+
R(await g.listSessions());
|
|
78
|
+
} catch {
|
|
79
|
+
R([]);
|
|
80
|
+
}
|
|
81
|
+
}, [g]), oe = r(async () => {
|
|
82
|
+
!g.newSession || N || (await g.newSession(), A([]), M(""), Q());
|
|
83
|
+
}, [
|
|
84
|
+
g,
|
|
85
|
+
N,
|
|
86
|
+
Q
|
|
87
|
+
]), se = r(async () => {
|
|
88
|
+
!g.clearSession || N || (await g.clearSession(), A([]), M(""), Q());
|
|
89
|
+
}, [
|
|
90
|
+
g,
|
|
91
|
+
N,
|
|
92
|
+
Q
|
|
93
|
+
]), ce = r(() => {
|
|
94
|
+
B((e) => (e || Q(), !e));
|
|
95
|
+
}, [Q]), le = r(async (e) => {
|
|
96
|
+
if (!(!g.selectSession || N)) {
|
|
97
|
+
I(!0);
|
|
98
|
+
try {
|
|
99
|
+
A(await g.selectSession(e)), B(!1), Q();
|
|
100
|
+
} catch {} finally {
|
|
101
|
+
I(!1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}, [
|
|
105
|
+
g,
|
|
106
|
+
N,
|
|
107
|
+
Q
|
|
108
|
+
]), $ = r(async () => {
|
|
109
|
+
let e = j.trim();
|
|
110
|
+
if (!e || N) return;
|
|
111
|
+
q.isListening && q.stop(), q.reset(), M(""), V.current && (V.current.style.height = "auto");
|
|
78
112
|
let t = {
|
|
79
|
-
id:
|
|
113
|
+
id: y(),
|
|
80
114
|
role: "user",
|
|
81
115
|
content: e
|
|
82
|
-
}, n =
|
|
83
|
-
|
|
116
|
+
}, n = y();
|
|
117
|
+
A((e) => [
|
|
84
118
|
...e,
|
|
85
119
|
t,
|
|
86
120
|
{
|
|
@@ -89,149 +123,203 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
|
|
|
89
123
|
content: "",
|
|
90
124
|
pending: !0
|
|
91
125
|
}
|
|
92
|
-
]),
|
|
126
|
+
]), P(!0);
|
|
93
127
|
let r = new AbortController();
|
|
94
|
-
|
|
128
|
+
U.current = r;
|
|
95
129
|
try {
|
|
96
|
-
let { text: t } = await
|
|
130
|
+
let { text: t } = await g.sendPrompt({
|
|
97
131
|
prompt: e,
|
|
98
132
|
signal: r.signal,
|
|
99
|
-
onProgress: (e) =>
|
|
133
|
+
onProgress: (e) => Z(n, { content: e })
|
|
100
134
|
});
|
|
101
|
-
|
|
135
|
+
Z(n, {
|
|
102
136
|
content: t,
|
|
103
137
|
pending: !1
|
|
104
138
|
});
|
|
105
139
|
} catch (e) {
|
|
106
|
-
|
|
140
|
+
Z(n, {
|
|
107
141
|
content: `Sorry, I couldn't complete that: ${e instanceof Error ? e.message : "Something went wrong. Please try again."}`,
|
|
108
142
|
pending: !1,
|
|
109
143
|
error: !0
|
|
110
144
|
});
|
|
111
145
|
} finally {
|
|
112
|
-
|
|
146
|
+
P(!1), U.current = null, z && Q();
|
|
113
147
|
}
|
|
114
148
|
}, [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
149
|
+
j,
|
|
150
|
+
N,
|
|
151
|
+
Z,
|
|
152
|
+
g,
|
|
153
|
+
q,
|
|
154
|
+
z,
|
|
155
|
+
Q
|
|
156
|
+
]), ue = r((e) => {
|
|
157
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), $());
|
|
158
|
+
}, [$]), de = r(() => {
|
|
159
|
+
let e = V.current;
|
|
124
160
|
e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 120)}px`);
|
|
125
|
-
}, []),
|
|
126
|
-
|
|
127
|
-
}, [
|
|
128
|
-
return /* @__PURE__ */
|
|
161
|
+
}, []), fe = r(() => {
|
|
162
|
+
q.isListening ? q.stop() : q.start();
|
|
163
|
+
}, [q]);
|
|
164
|
+
return /* @__PURE__ */ m(f, { children: [ee(() => /* @__PURE__ */ p("button", {
|
|
129
165
|
type: "button",
|
|
130
|
-
onClick:
|
|
131
|
-
"aria-label":
|
|
132
|
-
"aria-expanded":
|
|
166
|
+
onClick: X,
|
|
167
|
+
"aria-label": D ? "Close AI assistant" : "Open AI assistant",
|
|
168
|
+
"aria-expanded": D,
|
|
133
169
|
"data-testid": "assistant-widget-launcher",
|
|
134
|
-
className: e("fixed bottom-6 right-6 z-[100] inline-flex size-14 items-center justify-center rounded-full", "bg-action-primary-bg text-action-primary-text shadow-xl transition-transform duration-200", "hover:scale-105 hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer",
|
|
135
|
-
children:
|
|
170
|
+
className: e("fixed bottom-6 right-6 z-[100] inline-flex size-14 items-center justify-center rounded-full", "bg-action-primary-bg text-action-primary-text shadow-xl transition-transform duration-200", "hover:scale-105 hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", S),
|
|
171
|
+
children: p(D ? d : l, { className: "size-6" })
|
|
136
172
|
}), [
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
]),
|
|
173
|
+
D,
|
|
174
|
+
X,
|
|
175
|
+
S
|
|
176
|
+
]), D ? /* @__PURE__ */ m("div", {
|
|
141
177
|
role: "dialog",
|
|
142
|
-
"aria-label":
|
|
178
|
+
"aria-label": b,
|
|
143
179
|
"data-testid": "assistant-widget-window",
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
className: "inline-flex size-7 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-action-primary-bg",
|
|
152
|
-
children: /* @__PURE__ */ m(d, { className: "size-4" })
|
|
153
|
-
}), /* @__PURE__ */ m("h2", {
|
|
154
|
-
className: "truncate text-sm font-semibold text-text-primary",
|
|
155
|
-
children: x
|
|
156
|
-
})]
|
|
157
|
-
}), /* @__PURE__ */ m("button", {
|
|
180
|
+
"data-layout": w,
|
|
181
|
+
className: e("fixed z-[100] flex overflow-hidden border-border-default bg-bg-surface shadow-2xl", G ? "inset-y-0 right-0 h-screen w-full border-l sm:w-[480px] lg:w-[560px] animate-in slide-in-from-right duration-200" : "flex-col rounded-xl border bottom-24 right-6 h-[560px] max-h-[calc(100vh-7rem)] w-[calc(100vw-3rem)] sm:w-[400px] animate-in slide-in-from-bottom-2 fade-in duration-200"),
|
|
182
|
+
children: [G && K ? /* @__PURE__ */ m("aside", {
|
|
183
|
+
"data-testid": "assistant-session-panel",
|
|
184
|
+
className: "flex w-[168px] shrink-0 flex-col gap-1 border-r border-border-subtle bg-bg-sunken p-2",
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ m("button", {
|
|
158
187
|
type: "button",
|
|
159
|
-
onClick:
|
|
160
|
-
|
|
161
|
-
"data-testid": "assistant-
|
|
162
|
-
className: "
|
|
163
|
-
children: /* @__PURE__ */
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
className: "flex
|
|
179
|
-
children: [/* @__PURE__ */
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
children: /* @__PURE__ */ h("div", {
|
|
189
|
-
"data-testid": `assistant-widget-message-${t.role}`,
|
|
190
|
-
className: e("max-w-[85%] whitespace-pre-wrap break-words rounded-lg px-3 py-2 text-xs leading-relaxed", t.role === "user" ? "bg-action-primary-bg text-action-primary-text" : t.error ? "bg-status-error-bg/10 text-status-error-bg" : "bg-bg-sunken text-text-primary"),
|
|
191
|
-
children: [t.content || (t.pending, ""), t.pending ? /* @__PURE__ */ h("span", {
|
|
192
|
-
className: "mt-1 inline-flex items-center gap-1 text-text-secondary",
|
|
193
|
-
children: [/* @__PURE__ */ m(s, { className: "size-3 animate-spin" }), /* @__PURE__ */ m("span", { children: "Thinking…" })]
|
|
194
|
-
}) : null]
|
|
195
|
-
})
|
|
196
|
-
}, t.id))
|
|
197
|
-
}),
|
|
198
|
-
/* @__PURE__ */ h("div", {
|
|
199
|
-
className: "flex items-end gap-2 border-t border-border-default bg-bg-surface px-3 py-2.5",
|
|
200
|
-
children: [
|
|
201
|
-
B.isSupported ? /* @__PURE__ */ m("button", {
|
|
188
|
+
onClick: () => void oe(),
|
|
189
|
+
disabled: N,
|
|
190
|
+
"data-testid": "assistant-new-chat",
|
|
191
|
+
className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface disabled:opacity-50 cursor-pointer",
|
|
192
|
+
children: [/* @__PURE__ */ p(re, { className: "size-4 shrink-0" }), "New chat"]
|
|
193
|
+
}),
|
|
194
|
+
/* @__PURE__ */ m("button", {
|
|
195
|
+
type: "button",
|
|
196
|
+
onClick: () => void se(),
|
|
197
|
+
disabled: N || k.length === 0,
|
|
198
|
+
"data-testid": "assistant-clear-chat",
|
|
199
|
+
className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface disabled:opacity-50 cursor-pointer",
|
|
200
|
+
children: [/* @__PURE__ */ p(u, { className: "size-4 shrink-0" }), "Clear chat"]
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ m("button", {
|
|
203
|
+
type: "button",
|
|
204
|
+
onClick: ce,
|
|
205
|
+
"aria-expanded": z,
|
|
206
|
+
"data-testid": "assistant-history-toggle",
|
|
207
|
+
className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface cursor-pointer",
|
|
208
|
+
children: [/* @__PURE__ */ p(te, { className: "size-4 shrink-0" }), "History"]
|
|
209
|
+
}),
|
|
210
|
+
z ? /* @__PURE__ */ p("div", {
|
|
211
|
+
"data-testid": "assistant-history-list",
|
|
212
|
+
className: "mt-1 flex-1 space-y-0.5 overflow-y-auto border-t border-border-subtle pt-2",
|
|
213
|
+
children: L.length === 0 ? /* @__PURE__ */ p("p", {
|
|
214
|
+
className: "px-2 py-1 text-[11px] leading-relaxed text-text-muted",
|
|
215
|
+
children: "No past chats yet."
|
|
216
|
+
}) : L.map((t) => /* @__PURE__ */ p("button", {
|
|
202
217
|
type: "button",
|
|
203
|
-
onClick:
|
|
204
|
-
|
|
205
|
-
"
|
|
206
|
-
"
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
218
|
+
onClick: () => void le(t.id),
|
|
219
|
+
title: t.title,
|
|
220
|
+
"data-testid": "assistant-history-item",
|
|
221
|
+
className: e("w-full truncate rounded px-2 py-1.5 text-left text-[11px] leading-relaxed transition-colors cursor-pointer", t.active ? "bg-bg-surface font-medium text-text-primary" : "text-text-secondary hover:bg-bg-surface hover:text-text-primary"),
|
|
222
|
+
children: t.title
|
|
223
|
+
}, t.id))
|
|
224
|
+
}) : null
|
|
225
|
+
]
|
|
226
|
+
}) : null, /* @__PURE__ */ m("div", {
|
|
227
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
228
|
+
children: [
|
|
229
|
+
/* @__PURE__ */ m("div", {
|
|
230
|
+
className: "flex items-center justify-between gap-2 border-b border-border-subtle bg-bg-surface px-4 py-3",
|
|
231
|
+
children: [/* @__PURE__ */ m("div", {
|
|
232
|
+
className: "flex min-w-0 items-center gap-2",
|
|
233
|
+
children: [/* @__PURE__ */ p("span", {
|
|
234
|
+
className: "inline-flex size-7 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-action-primary-bg",
|
|
235
|
+
children: /* @__PURE__ */ p(l, { className: "size-4" })
|
|
236
|
+
}), /* @__PURE__ */ p("h2", {
|
|
237
|
+
className: "truncate text-sm font-semibold text-text-primary",
|
|
238
|
+
children: b
|
|
239
|
+
})]
|
|
240
|
+
}), /* @__PURE__ */ p("button", {
|
|
223
241
|
type: "button",
|
|
224
|
-
onClick:
|
|
225
|
-
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
242
|
+
onClick: Y,
|
|
243
|
+
"aria-label": "Close AI assistant",
|
|
244
|
+
"data-testid": "assistant-widget-close",
|
|
245
|
+
className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer",
|
|
246
|
+
children: /* @__PURE__ */ p(d, { className: "size-4" })
|
|
247
|
+
})]
|
|
248
|
+
}),
|
|
249
|
+
/* @__PURE__ */ p("div", {
|
|
250
|
+
ref: H,
|
|
251
|
+
className: "flex-1 space-y-3 overflow-y-auto px-4 py-4",
|
|
252
|
+
"data-testid": "assistant-widget-messages",
|
|
253
|
+
children: k.length === 0 && F ? /* @__PURE__ */ m("div", {
|
|
254
|
+
"data-testid": "assistant-widget-restoring",
|
|
255
|
+
className: "flex h-full flex-col items-center justify-center gap-3 text-center",
|
|
256
|
+
children: [/* @__PURE__ */ p(s, { className: "size-5 animate-spin text-text-secondary" }), /* @__PURE__ */ p("p", {
|
|
257
|
+
className: "text-xs leading-relaxed text-text-secondary",
|
|
258
|
+
children: "Restoring your conversation…"
|
|
259
|
+
})]
|
|
260
|
+
}) : k.length === 0 ? /* @__PURE__ */ m("div", {
|
|
261
|
+
className: "flex h-full flex-col items-center justify-center gap-3 text-center",
|
|
262
|
+
children: [/* @__PURE__ */ p("span", {
|
|
263
|
+
className: "inline-flex size-12 items-center justify-center rounded-full bg-bg-sunken text-action-primary-bg",
|
|
264
|
+
children: /* @__PURE__ */ p(ne, { className: "size-6" })
|
|
265
|
+
}), /* @__PURE__ */ p("p", {
|
|
266
|
+
className: "max-w-[16rem] text-xs leading-relaxed text-text-secondary",
|
|
267
|
+
children: x
|
|
268
|
+
})]
|
|
269
|
+
}) : k.map((t) => /* @__PURE__ */ p("div", {
|
|
270
|
+
className: e("flex", t.role === "user" ? "justify-end" : "justify-start"),
|
|
271
|
+
children: /* @__PURE__ */ m("div", {
|
|
272
|
+
"data-testid": `assistant-widget-message-${t.role}`,
|
|
273
|
+
className: e("whitespace-pre-wrap break-words rounded-lg px-3 py-2 text-xs leading-relaxed", G ? "max-w-[92%]" : "max-w-[85%]", t.role === "user" ? "bg-action-primary-bg text-action-primary-text" : t.error ? "bg-status-error-bg/10 text-status-error-bg" : "bg-bg-sunken text-text-primary"),
|
|
274
|
+
children: [t.content ? /* @__PURE__ */ p(n, {
|
|
275
|
+
content: t.content,
|
|
276
|
+
onNavigate: E
|
|
277
|
+
}) : null, t.pending ? /* @__PURE__ */ m("span", {
|
|
278
|
+
"data-testid": "assistant-widget-working",
|
|
279
|
+
className: e("inline-flex items-center gap-1 text-text-secondary", t.content ? "mt-1" : ""),
|
|
280
|
+
children: [/* @__PURE__ */ p(s, { className: "size-3 animate-spin" }), t.content ? null : /* @__PURE__ */ p("span", { children: "Working on it…" })]
|
|
281
|
+
}) : null]
|
|
282
|
+
})
|
|
283
|
+
}, t.id))
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ m("div", {
|
|
286
|
+
className: "flex items-end gap-2 border-t border-border-default bg-bg-surface px-3 py-2.5",
|
|
287
|
+
children: [
|
|
288
|
+
q.isSupported ? /* @__PURE__ */ p("button", {
|
|
289
|
+
type: "button",
|
|
290
|
+
onClick: fe,
|
|
291
|
+
"aria-label": q.isListening ? "Stop voice input" : "Start voice input",
|
|
292
|
+
"aria-pressed": q.isListening,
|
|
293
|
+
"data-testid": "assistant-widget-mic",
|
|
294
|
+
className: e("flex size-9 shrink-0 items-center justify-center rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", q.isListening ? "animate-pulse bg-status-error-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
|
|
295
|
+
children: /* @__PURE__ */ p(c, { className: "size-4" })
|
|
296
|
+
}) : null,
|
|
297
|
+
/* @__PURE__ */ p("textarea", {
|
|
298
|
+
ref: V,
|
|
299
|
+
value: j,
|
|
300
|
+
onChange: (e) => M(e.target.value),
|
|
301
|
+
onKeyDown: ue,
|
|
302
|
+
onInput: de,
|
|
303
|
+
rows: 1,
|
|
304
|
+
placeholder: ae,
|
|
305
|
+
"aria-label": "Message the assistant",
|
|
306
|
+
"data-testid": "assistant-widget-input",
|
|
307
|
+
className: "flex-1 resize-none rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs leading-relaxed text-text-primary placeholder:text-text-muted focus:border-action-primary-bg focus:outline-none"
|
|
308
|
+
}),
|
|
309
|
+
/* @__PURE__ */ p("button", {
|
|
310
|
+
type: "button",
|
|
311
|
+
onClick: () => void $(),
|
|
312
|
+
disabled: N || j.trim().length === 0,
|
|
313
|
+
"aria-label": "Send message",
|
|
314
|
+
"data-testid": "assistant-widget-send",
|
|
315
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-action-primary-bg text-action-primary-text transition-colors hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:opacity-50 cursor-pointer",
|
|
316
|
+
children: N ? /* @__PURE__ */ p(s, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(ie, { className: "size-4" })
|
|
317
|
+
})
|
|
318
|
+
]
|
|
319
|
+
})
|
|
320
|
+
]
|
|
321
|
+
})]
|
|
234
322
|
}) : null] });
|
|
235
323
|
};
|
|
236
324
|
//#endregion
|
|
237
|
-
export {
|
|
325
|
+
export { h as ASSISTANT_WIDGET_TOGGLE_EVENT, b as AssistantWidget };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
export interface MessageContentProps {
|
|
3
|
+
content: string;
|
|
4
|
+
/**
|
|
5
|
+
* Called for in-app (`/…`) links so the host can route without a full page
|
|
6
|
+
* reload. When omitted, in-app links fall back to a normal anchor.
|
|
7
|
+
*/
|
|
8
|
+
onNavigate?: (href: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const MessageContent: FC<MessageContentProps>;
|
|
11
|
+
//# sourceMappingURL=MessageContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageContent.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/MessageContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAY,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAW1D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAqDlD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Fragment as e } from "react";
|
|
2
|
+
import { Fragment as t, jsx as n } from "react/jsx-runtime";
|
|
3
|
+
//#region src/shared/components/assistantWidget/MessageContent.tsx
|
|
4
|
+
var r = /\[([^\]]+)\]\(([^)\s]+)\)/g;
|
|
5
|
+
function i(e) {
|
|
6
|
+
return e.startsWith("/") && !e.startsWith("//") ? !0 : e.startsWith("https://");
|
|
7
|
+
}
|
|
8
|
+
var a = ({ content: a, onNavigate: o }) => {
|
|
9
|
+
let s = [], c = 0, l = new RegExp(r.source, "g");
|
|
10
|
+
for (let t of a.matchAll(l)) {
|
|
11
|
+
let [r, l, u] = t, d = t.index ?? 0;
|
|
12
|
+
if (d > c && s.push(/* @__PURE__ */ n(e, { children: a.slice(c, d) }, `t${String(c)}`)), l && u && i(u)) {
|
|
13
|
+
let e = u.startsWith("/");
|
|
14
|
+
s.push(/* @__PURE__ */ n("a", {
|
|
15
|
+
href: u,
|
|
16
|
+
"data-testid": "assistant-message-link",
|
|
17
|
+
...e ? { onClick: o ? (e) => {
|
|
18
|
+
e.preventDefault(), o(u);
|
|
19
|
+
} : void 0 } : {
|
|
20
|
+
target: "_blank",
|
|
21
|
+
rel: "noopener noreferrer"
|
|
22
|
+
},
|
|
23
|
+
className: "font-medium text-action-primary-bg underline underline-offset-2 hover:opacity-80",
|
|
24
|
+
children: l
|
|
25
|
+
}, `l${String(d)}`));
|
|
26
|
+
} else s.push(/* @__PURE__ */ n(e, { children: l ?? r }, `u${String(d)}`));
|
|
27
|
+
c = d + r.length;
|
|
28
|
+
}
|
|
29
|
+
return c < a.length && s.push(/* @__PURE__ */ n(e, { children: a.slice(c) }, `t${String(c)}`)), /* @__PURE__ */ n(t, { children: s });
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { a as MessageContent };
|
|
@@ -33,10 +33,27 @@ export interface AssistantSendArgs {
|
|
|
33
33
|
* Backend adapter the host product supplies. A single transport instance is
|
|
34
34
|
* reused across turns so it can keep a warm session/sandbox between sends.
|
|
35
35
|
*/
|
|
36
|
+
/** One past conversation, for the history list. */
|
|
37
|
+
export interface AssistantSessionSummary {
|
|
38
|
+
id: string;
|
|
39
|
+
title: string;
|
|
40
|
+
/** epoch ms — used only for ordering/labelling. */
|
|
41
|
+
updatedAt?: number;
|
|
42
|
+
/** True for the conversation currently on screen. */
|
|
43
|
+
active?: boolean;
|
|
44
|
+
}
|
|
36
45
|
export interface AssistantTransport {
|
|
37
46
|
sendPrompt: (args: AssistantSendArgs) => Promise<{
|
|
38
47
|
text: string;
|
|
39
48
|
}>;
|
|
49
|
+
/** All conversations for this user/sandbox, newest first. */
|
|
50
|
+
listSessions?: () => Promise<AssistantSessionSummary[]>;
|
|
51
|
+
/** Start an empty conversation and make it active. */
|
|
52
|
+
newSession?: () => Promise<void>;
|
|
53
|
+
/** Delete the active conversation and start a fresh one in its place. */
|
|
54
|
+
clearSession?: () => Promise<void>;
|
|
55
|
+
/** Switch to a past conversation; returns its messages. */
|
|
56
|
+
selectSession?: (sessionId: string) => Promise<AssistantWidgetMessage[]>;
|
|
40
57
|
/**
|
|
41
58
|
* Optional: restore the conversation from the backend when the widget opens.
|
|
42
59
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAOnE,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IACxD,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACzE;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;CACvD"}
|
|
@@ -30,5 +30,5 @@ export { AssistantWidget, ASSISTANT_WIDGET_TOGGLE_EVENT } from './assistantWidge
|
|
|
30
30
|
export type { AssistantWidgetProps } from './assistantWidget/AssistantWidget';
|
|
31
31
|
export { useVoiceInput } from './assistantWidget/useVoiceInput';
|
|
32
32
|
export type { UseVoiceInputReturn } from './assistantWidget/useVoiceInput';
|
|
33
|
-
export type { AssistantTransport, AssistantSendArgs, AssistantWidgetMessage, AssistantWidgetRole, } from './assistantWidget/types';
|
|
33
|
+
export type { AssistantTransport, AssistantSendArgs, AssistantSessionSummary, AssistantWidgetMessage, AssistantWidgetRole, } from './assistantWidget/types';
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAGlF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACnG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAGlF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACnG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|