@particle-academy/react-fancy 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/dist/badge.cjs +3 -2
- package/dist/badge.js +2 -1
- package/dist/button.cjs +3 -3
- package/dist/button.js +1 -1
- package/dist/callout.cjs +2 -2
- package/dist/callout.js +1 -1
- package/dist/chat-thread.cjs +7 -6
- package/dist/chat-thread.js +5 -4
- package/dist/{chunk-PACFMPSX.js → chunk-23KQF47X.js} +5 -5
- package/dist/{chunk-PACFMPSX.js.map → chunk-23KQF47X.js.map} +1 -1
- package/dist/{chunk-GBR4Q6CP.js → chunk-3AA2KGZG.js} +3 -3
- package/dist/{chunk-GBR4Q6CP.js.map → chunk-3AA2KGZG.js.map} +1 -1
- package/dist/{chunk-WLDDGIGC.js → chunk-4GPH7HOR.js} +11 -3
- package/dist/chunk-4GPH7HOR.js.map +1 -0
- package/dist/{chunk-LWOA2ET6.js → chunk-B6WTCAGY.js} +3 -3
- package/dist/{chunk-LWOA2ET6.js.map → chunk-B6WTCAGY.js.map} +1 -1
- package/dist/{chunk-JKH5ODNG.cjs → chunk-CKO2KCUN.cjs} +9 -9
- package/dist/{chunk-JKH5ODNG.cjs.map → chunk-CKO2KCUN.cjs.map} +1 -1
- package/dist/{chunk-BQFPC5FL.js → chunk-ESCIXKFT.js} +3 -3
- package/dist/{chunk-BQFPC5FL.js.map → chunk-ESCIXKFT.js.map} +1 -1
- package/dist/{chunk-VZ7IDHUY.js → chunk-F4OYQ2XZ.js} +4 -4
- package/dist/{chunk-VZ7IDHUY.js.map → chunk-F4OYQ2XZ.js.map} +1 -1
- package/dist/{chunk-ND5SBHGH.cjs → chunk-FKZB27OM.cjs} +6 -6
- package/dist/{chunk-ND5SBHGH.cjs.map → chunk-FKZB27OM.cjs.map} +1 -1
- package/dist/{chunk-EZA6GWZL.cjs → chunk-GK7IGL7N.cjs} +195 -8
- package/dist/chunk-GK7IGL7N.cjs.map +1 -0
- package/dist/{chunk-KOECVLC4.js → chunk-GSMD5NK5.js} +3 -3
- package/dist/{chunk-KOECVLC4.js.map → chunk-GSMD5NK5.js.map} +1 -1
- package/dist/{chunk-ZXGX5RI5.cjs → chunk-I2VAGZXY.cjs} +4 -4
- package/dist/{chunk-ZXGX5RI5.cjs.map → chunk-I2VAGZXY.cjs.map} +1 -1
- package/dist/{chunk-IA6JKI4P.cjs → chunk-K7JOZQRK.cjs} +15 -15
- package/dist/{chunk-IA6JKI4P.cjs.map → chunk-K7JOZQRK.cjs.map} +1 -1
- package/dist/{chunk-H2YRZYKK.cjs → chunk-KFA7B6WP.cjs} +4 -4
- package/dist/{chunk-H2YRZYKK.cjs.map → chunk-KFA7B6WP.cjs.map} +1 -1
- package/dist/{chunk-ZXZJYVWP.js → chunk-KPRSRWNM.js} +3 -3
- package/dist/{chunk-ZXZJYVWP.js.map → chunk-KPRSRWNM.js.map} +1 -1
- package/dist/{chunk-VNOUXFZ2.cjs → chunk-KSSTFLV2.cjs} +20 -20
- package/dist/{chunk-VNOUXFZ2.cjs.map → chunk-KSSTFLV2.cjs.map} +1 -1
- package/dist/{chunk-YJHP5FVA.js → chunk-MTDOFZIB.js} +196 -9
- package/dist/chunk-MTDOFZIB.js.map +1 -0
- package/dist/{chunk-BX6ZVWTO.cjs → chunk-NZHVDWOM.cjs} +11 -3
- package/dist/chunk-NZHVDWOM.cjs.map +1 -0
- package/dist/chunk-OCHUZ7J3.cjs +60 -0
- package/dist/chunk-OCHUZ7J3.cjs.map +1 -0
- package/dist/{chunk-BGRVHPGP.cjs → chunk-OUNGGQIS.cjs} +6 -6
- package/dist/{chunk-BGRVHPGP.cjs.map → chunk-OUNGGQIS.cjs.map} +1 -1
- package/dist/chunk-OZ4QFJ7N.js +58 -0
- package/dist/chunk-OZ4QFJ7N.js.map +1 -0
- package/dist/{chunk-MOU6O324.cjs → chunk-S53A6JIE.js} +3 -58
- package/dist/chunk-S53A6JIE.js.map +1 -0
- package/dist/{chunk-X354OVSC.cjs → chunk-SRICSNL4.cjs} +12 -12
- package/dist/{chunk-X354OVSC.cjs.map → chunk-SRICSNL4.cjs.map} +1 -1
- package/dist/{chunk-3RIBZZLT.js → chunk-TH4JZAMK.js} +5 -5
- package/dist/{chunk-3RIBZZLT.js.map → chunk-TH4JZAMK.js.map} +1 -1
- package/dist/{chunk-CWWMT57K.js → chunk-WF6AYHOS.js} +4 -4
- package/dist/{chunk-CWWMT57K.js.map → chunk-WF6AYHOS.js.map} +1 -1
- package/dist/{chunk-LCNHEYIM.cjs → chunk-WNWEC5OU.cjs} +3 -3
- package/dist/{chunk-LCNHEYIM.cjs.map → chunk-WNWEC5OU.cjs.map} +1 -1
- package/dist/{chunk-6FCQD2KQ.js → chunk-X6LGRB4H.cjs} +7 -55
- package/dist/chunk-X6LGRB4H.cjs.map +1 -0
- package/dist/content-renderer.cjs +5 -5
- package/dist/content-renderer.js +2 -2
- package/dist/editor.cjs +5 -5
- package/dist/editor.js +3 -3
- package/dist/index.cjs +51 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/json-editor.cjs +16 -15
- package/dist/json-editor.js +5 -4
- package/dist/magic-wand.cjs +5 -4
- package/dist/magic-wand.js +4 -3
- package/dist/prompt-input.cjs +5 -5
- package/dist/prompt-input.js +2 -2
- package/dist/reason-tag.cjs +3 -3
- package/dist/reason-tag.js +2 -2
- package/dist/sidebar.cjs +4 -3
- package/dist/sidebar.d.cts +49 -4
- package/dist/sidebar.d.ts +49 -4
- package/dist/sidebar.js +2 -1
- package/dist/toast.cjs +5 -4
- package/dist/toast.js +3 -2
- package/docs/Button.md +8 -0
- package/docs/Sidebar.md +75 -1
- package/package.json +1 -1
- package/dist/chunk-6FCQD2KQ.js.map +0 -1
- package/dist/chunk-BX6ZVWTO.cjs.map +0 -1
- package/dist/chunk-EZA6GWZL.cjs.map +0 -1
- package/dist/chunk-MOU6O324.cjs.map +0 -1
- package/dist/chunk-WLDDGIGC.js.map +0 -1
- package/dist/chunk-YJHP5FVA.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,56 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [6.1.0] - 2026-11-01
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`Sidebar.Item` `dot` / `dotLabel`: attention marks that survive
|
|
19
|
+
collapsing.** A collapsed (`icons`) rail rendered only the icon, so it had no
|
|
20
|
+
way to show unread, warning or "needs you". `dot` is a small indicator at the
|
|
21
|
+
icon's corner (at the letters' corner on a lettered rail, at the item's
|
|
22
|
+
corner with no icon), shown expanded AND collapsed. `dot` takes `true` (red)
|
|
23
|
+
or any Badge colour. `dotLabel` ("3 unread") is visually hidden text added to
|
|
24
|
+
the item's accessible name, since a coloured dot alone says nothing to a
|
|
25
|
+
screen reader. On a collapsed item a visually hidden copy of the label keeps
|
|
26
|
+
the item named by its label rather than by the dot label. Handles:
|
|
27
|
+
`data-react-fancy-sidebar-dot` (`data-color`, `data-position`),
|
|
28
|
+
`data-react-fancy-sidebar-dot-label`. New type: `SidebarDotColor`.
|
|
29
|
+
- **`Sidebar.Item` `collapsedBadge`.** Opts `badge` into the collapsed rail, as
|
|
30
|
+
an overlay at the icon's corner (`data-react-fancy-sidebar-badge`). Opt-in
|
|
31
|
+
rather than default: collapsed rails have never shown badges, and a wide one
|
|
32
|
+
("Beta") over a 20px icon is not a change to make for every consumer. With a
|
|
33
|
+
`dot` as well, the dot moves to the bottom corner.
|
|
34
|
+
- **`Sidebar` `navLabel`.** Wraps the children in `<nav aria-label>` inside the
|
|
35
|
+
`<aside>`, so the items form a navigation landmark. The `<nav>`
|
|
36
|
+
(`data-react-fancy-sidebar-nav`) takes over the column layout and fills the
|
|
37
|
+
rail.
|
|
38
|
+
- **`Sidebar` `keyboardNav`.** ArrowUp / ArrowDown / Home / End between items
|
|
39
|
+
with a roving tabindex: the rail is one tab stop (the active item, else the
|
|
40
|
+
first enabled one). Skips disabled items and the items of a closed submenu,
|
|
41
|
+
includes submenu triggers (which then get `aria-expanded`), never intercepts
|
|
42
|
+
keys in an input, textarea, select or contenteditable, and leaves
|
|
43
|
+
`Sidebar.Toggle` its own tab stop. Opt-in because a roving tabindex changes
|
|
44
|
+
Tab order.
|
|
45
|
+
|
|
46
|
+
All four are opt-in: a Sidebar that passes none of them renders byte-identical
|
|
47
|
+
markup to 6.0.0 (pinned by a snapshot written by 6.0.0). **No consumer action
|
|
48
|
+
needed.**
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- **`Button` no longer keeps a focus ring after a mouse click.** The ring was
|
|
53
|
+
on `:focus`, which a click also triggers, and it had no colour, so it fell
|
|
54
|
+
back to `currentColor`: a highlighted row showed a thick near-black outline
|
|
55
|
+
after every click. It is now on `:focus-visible` (keyboard focus) and uses the
|
|
56
|
+
focus token (`--fancy-focus`, blue-500; `--fancy-focus-dark`, blue-400 in
|
|
57
|
+
dark mode), offset against the surface token so dark mode has no white gap.
|
|
58
|
+
`Callout`'s dismiss button had the same `:focus` ring and gets the same
|
|
59
|
+
change (its `currentColor` ring is kept: there it is the callout's own hue).
|
|
60
|
+
A visual fix: **no consumer action needed.** If you overrode the ring with
|
|
61
|
+
`focus:ring-*` classes in `className`, switch them to `focus-visible:ring-*`
|
|
62
|
+
to keep the override.
|
|
63
|
+
|
|
14
64
|
## [6.0.0] - 2026-11-01
|
|
15
65
|
|
|
16
66
|
### Changed
|
package/dist/badge.cjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('./chunk-VBWRH4UW.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkOCHUZ7J3_cjs = require('./chunk-OCHUZ7J3.cjs');
|
|
5
|
+
require('./chunk-X6LGRB4H.cjs');
|
|
5
6
|
require('./chunk-ZU5Q77OT.cjs');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
Object.defineProperty(exports, "Badge", {
|
|
10
11
|
enumerable: true,
|
|
11
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkOCHUZ7J3_cjs.Badge; }
|
|
12
13
|
});
|
|
13
14
|
//# sourceMappingURL=badge.cjs.map
|
|
14
15
|
//# sourceMappingURL=badge.cjs.map
|
package/dist/badge.js
CHANGED
package/dist/button.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('./chunk-M5MUGSON.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkNZHVDWOM_cjs = require('./chunk-NZHVDWOM.cjs');
|
|
5
5
|
require('./chunk-XCZZVRBY.cjs');
|
|
6
6
|
require('./chunk-MXWR3T3N.cjs');
|
|
7
7
|
require('./chunk-ZU5Q77OT.cjs');
|
|
@@ -10,11 +10,11 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
10
10
|
|
|
11
11
|
Object.defineProperty(exports, "Action", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkNZHVDWOM_cjs.Action; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "Button", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkNZHVDWOM_cjs.Button; }
|
|
18
18
|
});
|
|
19
19
|
//# sourceMappingURL=button.cjs.map
|
|
20
20
|
//# sourceMappingURL=button.cjs.map
|
package/dist/button.js
CHANGED
package/dist/callout.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('./chunk-3I2KWNXT.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkWNWEC5OU_cjs = require('./chunk-WNWEC5OU.cjs');
|
|
5
5
|
require('./chunk-ZU5Q77OT.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
Object.defineProperty(exports, "Callout", {
|
|
10
10
|
enumerable: true,
|
|
11
|
-
get: function () { return
|
|
11
|
+
get: function () { return chunkWNWEC5OU_cjs.Callout; }
|
|
12
12
|
});
|
|
13
13
|
//# sourceMappingURL=callout.cjs.map
|
|
14
14
|
//# sourceMappingURL=callout.cjs.map
|
package/dist/callout.js
CHANGED
package/dist/chat-thread.cjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkK7JOZQRK_cjs = require('./chunk-K7JOZQRK.cjs');
|
|
4
4
|
require('./chunk-S3TRSECD.cjs');
|
|
5
|
-
require('./chunk-
|
|
5
|
+
require('./chunk-CKO2KCUN.cjs');
|
|
6
6
|
require('./chunk-2C64OVOZ.cjs');
|
|
7
7
|
require('./chunk-BJL3VDRK.cjs');
|
|
8
8
|
require('./chunk-VBWRH4UW.cjs');
|
|
9
|
-
require('./chunk-
|
|
9
|
+
require('./chunk-OCHUZ7J3.cjs');
|
|
10
|
+
require('./chunk-X6LGRB4H.cjs');
|
|
10
11
|
require('./chunk-M5MUGSON.cjs');
|
|
11
|
-
require('./chunk-
|
|
12
|
+
require('./chunk-NZHVDWOM.cjs');
|
|
12
13
|
require('./chunk-XCZZVRBY.cjs');
|
|
13
14
|
require('./chunk-MXWR3T3N.cjs');
|
|
14
15
|
require('./chunk-ZU5Q77OT.cjs');
|
|
@@ -17,11 +18,11 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
17
18
|
|
|
18
19
|
Object.defineProperty(exports, "ChatMessage", {
|
|
19
20
|
enumerable: true,
|
|
20
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkK7JOZQRK_cjs.ChatMessage; }
|
|
21
22
|
});
|
|
22
23
|
Object.defineProperty(exports, "ChatThread", {
|
|
23
24
|
enumerable: true,
|
|
24
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkK7JOZQRK_cjs.ChatThread; }
|
|
25
26
|
});
|
|
26
27
|
//# sourceMappingURL=chat-thread.cjs.map
|
|
27
28
|
//# sourceMappingURL=chat-thread.cjs.map
|
package/dist/chat-thread.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export { ChatMessage, ChatThread } from './chunk-
|
|
1
|
+
export { ChatMessage, ChatThread } from './chunk-23KQF47X.js';
|
|
2
2
|
import './chunk-AUTW5O4W.js';
|
|
3
|
-
import './chunk-
|
|
3
|
+
import './chunk-3AA2KGZG.js';
|
|
4
4
|
import './chunk-I3LAFKJU.js';
|
|
5
5
|
import './chunk-UZCR7DK5.js';
|
|
6
6
|
import './chunk-IQ4KQJAO.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-OZ4QFJ7N.js';
|
|
8
|
+
import './chunk-S53A6JIE.js';
|
|
8
9
|
import './chunk-LQ4ICCN2.js';
|
|
9
|
-
import './chunk-
|
|
10
|
+
import './chunk-4GPH7HOR.js';
|
|
10
11
|
import './chunk-45BBNJQD.js';
|
|
11
12
|
import './chunk-J3A4Z2P7.js';
|
|
12
13
|
import './chunk-MMW2JGKZ.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ContentRenderer } from './chunk-
|
|
1
|
+
import { ContentRenderer } from './chunk-3AA2KGZG.js';
|
|
2
2
|
import { Avatar } from './chunk-UZCR7DK5.js';
|
|
3
|
-
import { Badge } from './chunk-
|
|
4
|
-
import { Button, sanitizeComponentHref } from './chunk-
|
|
3
|
+
import { Badge } from './chunk-OZ4QFJ7N.js';
|
|
4
|
+
import { Button, sanitizeComponentHref } from './chunk-4GPH7HOR.js';
|
|
5
5
|
import { cn } from './chunk-MMW2JGKZ.js';
|
|
6
6
|
import { useId, useRef, useState, useCallback, useEffect, useImperativeHandle, Fragment as Fragment$1, useLayoutEffect } from 'react';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -616,5 +616,5 @@ function ChatThread({
|
|
|
616
616
|
ChatThread.displayName = "ChatThread";
|
|
617
617
|
|
|
618
618
|
export { ChatMessage, ChatThread };
|
|
619
|
-
//# sourceMappingURL=chunk-
|
|
620
|
-
//# sourceMappingURL=chunk-
|
|
619
|
+
//# sourceMappingURL=chunk-23KQF47X.js.map
|
|
620
|
+
//# sourceMappingURL=chunk-23KQF47X.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ChatThread/chat-utils.ts","../src/components/ChatThread/ChatMessage.tsx","../src/components/ChatThread/ChatThread.tsx"],"names":["TEXT_MUTED","BORDER","useEffect","useRef","useState","useCallback","jsxs","jsx","Fragment"],"mappings":";;;;;;;;;AAEO,IAAM,cAAA,GAAmC;AAAA,EAC9C,GAAA,EAAK,cAAA;AAAA,EACL,WAAA,EAAa,uBAAA;AAAA,EACb,cAAA,EAAgB,6BAAA;AAAA,EAChB,aAAa,CAAC,CAAA,KAAO,MAAM,CAAA,GAAI,eAAA,GAAkB,GAAG,CAAC,CAAA,aAAA,CAAA;AAAA,EACrD,QAAA,EAAU,eAAA;AAAA,EACV,OAAA,EAAS,YAAA;AAAA,EACT,MAAA,EAAQ,UAAA;AAAA,EACR,QAAA,EAAU,UAAA;AAAA,EACV,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,SAAA,EAAW,WAAA;AAAA,EACX,WAAA,EAAa,aAAA;AAAA,EACb,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,SAAA,EAAW,WAAA;AAAA,IACX,MAAA,EAAQ,QAAA;AAAA,IACR,KAAA,EAAO,OAAA;AAAA,IACP,KAAA,EAAO,OAAA;AAAA,IACP,QAAA,EAAU;AAAA;AAEd,CAAA;AAEO,SAAS,YAAY,MAAA,EAAsD;AAChF,EAAA,IAAI,CAAC,QAAQ,OAAO,cAAA;AACpB,EAAA,OAAO;AAAA,IACL,GAAG,cAAA;AAAA,IACH,GAAG,MAAA;AAAA,IACH,OAAO,EAAE,GAAG,eAAe,KAAA,EAAO,GAAG,OAAO,KAAA;AAAM,GACpD;AACF;AAGO,SAAS,OAAO,KAAA,EAAiD;AACtE,EAAA,IAAI,UAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,IAAI,OAAO,IAAA;AAClE,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,KAAK,CAAA;AACxB,EAAA,OAAO,OAAO,KAAA,CAAM,CAAA,CAAE,OAAA,EAAS,IAAI,IAAA,GAAO,CAAA;AAC5C;AAGO,SAAS,OAAO,CAAA,EAAiB;AACtC,EAAA,MAAM,CAAA,GAAI,CAAC,CAAA,KAAc,MAAA,CAAO,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAClD,EAAA,OAAO,GAAG,CAAA,CAAE,WAAA,EAAa,CAAA,CAAA,EAAI,EAAE,CAAA,CAAE,QAAA,EAAS,GAAI,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAA,CAAE,OAAA,EAAS,CAAC,CAAA,CAAA;AACpE;AAEO,SAAS,kBAAkB,CAAA,EAAiB;AACjD,EAAA,OAAO,CAAA,CAAE,mBAAmB,MAAA,EAAW,EAAE,MAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,CAAA;AAC/E;AAEO,SAAS,iBAAiB,CAAA,EAAiB;AAChD,EAAA,OAAO,EAAE,kBAAA,CAAmB,MAAA,EAAW,EAAE,SAAA,EAAW,UAAU,CAAA;AAChE;AAEO,SAAS,SAAA,CAAU,MAAc,MAAA,EAAkC;AACxE,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,EAAA,IAAI,OAAO,OAAO,KAAA;AAClB,EAAA,OAAO,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,aAAY,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,EAAA;AAC/D;AAEO,SAAS,SAAS,IAAA,EAAsB;AAC7C,EAAA,MAAM,KAAA,GAAQ,KAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,GAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,MAAA,GAAS,CAAA,GAAK,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,GAAM,EAAA;AACrE,EAAA,OAAA,CAAQ,KAAA,GAAQ,MAAM,WAAA,EAAY;AACpC;AAEO,SAAS,KAAA,CAAM,SAA0B,QAAA,EAA6B;AAC3E,EAAA,OAAO,OAAA,CAAQ,GAAA,IAAO,QAAA,CAAS,QAAA,CAAS,QAAQ,IAAI,CAAA;AACtD;AAEO,IAAM,uBAAA,GAA0B,IAAI,EAAA,GAAK,GAAA;AAGzC,SAAS,cAAA,CACd,IAAA,EACA,IAAA,EACA,QAAA,EACS;AACT,EAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,OAAO,KAAA;AACpC,EAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,IAAA,IAAQ,EAAA,OAAS,KAAK,MAAA,EAAQ,IAAA,IAAQ,KAAK,OAAO,KAAA;AACpE,EAAA,IAAA,CAAK,KAAK,UAAA,IAAc,QAAA,OAAe,IAAA,CAAK,UAAA,IAAc,WAAW,OAAO,KAAA;AAC5E,EAAA,IAAI,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA,EAAU,OAAO,KAAA;AAC3C,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU,OAAO,KAAA;AACnC,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAC/B,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA;AAC/B,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG,OAAO,KAAA;AACrB,EAAA,MAAM,GAAA,GAAM,CAAA,CAAE,OAAA,EAAQ,GAAI,EAAE,OAAA,EAAQ;AACpC,EAAA,OAAO,GAAA,IAAO,KAAK,GAAA,IAAO,QAAA;AAC5B;AAEO,SAAS,YAAY,CAAA,EAAmB;AAC7C,EAAA,IAAI,CAAA,GAAI,IAAA,EAAM,OAAO,CAAA,EAAG,CAAC,CAAA,EAAA,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,OAAO,IAAA,EAAM,OAAO,IAAI,CAAA,GAAI,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AACpD,EAAA,OAAO,IAAI,CAAA,IAAK,IAAA,GAAO,IAAA,CAAA,EAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAA,CAAA;AAC1C;AC3EA,IAAM,MAAA,GACJ,6HAAA;AACF,IAAM,OAAA,GACJ,oHAAA;AACF,IAAM,aAAA,GACJ,mIAAA;AACF,IAAM,IAAA,GACJ,qHAAA;AACF,IAAM,UAAA,GACJ,iIAAA;AASK,SAAS,sBACd,aAAA,EACgG;AAChG,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAC5B,EAAA,MAAM,OAAA,GAAU,OAAO,IAAI,CAAA;AAC3B,EAAA,MAAM,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAA,UAAA,CAAW,OAAA,GAAU,aAAA;AAErB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,CAAQ,OAAA,GAAU,KAAA;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,GAAA,GAAM,WAAA,CAAY,CAAC,EAAA,EAAkC,GAAA,KAAiC;AAC1F,IAAA,IAAI,QAAQ,OAAA,EAAS;AACrB,IAAA,MAAM,SAAS,EAAA,EAAG;AAClB,IAAA,IAAI,CAAC,MAAA,IAAU,OAAQ,MAAA,CAA4B,SAAS,UAAA,EAAY;AAExE,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,OAAA,CAAQ,OAAA,GAAU,KAAA;AAClB,MAAA,IAAI,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,KAAK,CAAA;AAAA,IACpC,CAAA;AACA,IAAA,KAAK,QAAQ,OAAA,CAAQ,MAAM,EAAE,IAAA,CAAK,MAAA,EAAQ,CAAC,KAAA,KAAmB;AAC5D,MAAA,MAAA,EAAO;AACP,MAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,MAAA,IAAI,OAAA,EAAS,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AAAA,WAC1B,MAAM,KAAA;AAAA,IACb,CAAC,CAAA;AAAA,EACH,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,CAAC,MAAM,GAAG,CAAA;AACnB;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,IAAA,GAAO,gBAAA,CAAiB,YAAY,OAAO,CAAA;AAAA,EAC7C,CAAA,MAAO;AACL,IAAA,MAAM,IAAA,GAAO,qBAAA,CAAsB,aAAA,EAAe,UAAA,CAAW,GAAG,CAAA;AAChE,IAAA,MAAM,IAAA,GAAO,OAAO,UAAA,CAAW,IAAA,KAAS,QAAA,mBACtC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,MAAA,EAAQ,UAAU,CAAA,EAAG,QAAA,EAAA;AAAA,MAAA,GAAA;AAAA,MAAE,WAAA,CAAY,WAAW,IAAI,CAAA;AAAA,MAAE;AAAA,KAAA,EAAC,CAAA,GACvE,IAAA;AACJ,IAAA,IAAA,GAAO,IAAA,wBACJ,GAAA,EAAA,EAAE,IAAA,EAAY,QAAO,QAAA,EAAS,GAAA,EAAI,qBAAA,EAAsB,SAAA,EAAU,wCAAA,EAChE,QAAA,EAAA;AAAA,MAAA,UAAA,CAAW,IAAA;AAAA,MACX;AAAA,KAAA,EACH,CAAA,mBAEA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,MAAA,UAAA,CAAW,IAAA;AAAA,MACX;AAAA,KAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,2BACG,IAAA,EAAA,EAAG,sBAAA,EAAsB,WAAW,EAAA,EAAI,SAAA,EAAU,WAChD,QAAA,EAAA,IAAA,EACH,CAAA;AAEJ;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,MAAM,WAAW,OAAA,CAAQ,QAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,SAAS,KAAA,IAAS,SAAA;AAEhC,EAAA,IAAI,UAAU,SAAA,EAAW;AACvB,IAAA,MAAM,IAAA,GAAO,UAAU,UAAA,GAAa,MAAA,CAAO,WAAW,KAAA,KAAU,UAAA,GAAa,MAAA,CAAO,QAAA,GAAW,MAAA,CAAO,SAAA;AACtG,IAAA,MAAM,QAAQ,KAAA,KAAU,UAAA,GAAa,SAAA,GAAY,KAAA,KAAU,aAAa,KAAA,GAAQ,MAAA;AAChF,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,MAAA,EACb,8BAAC,KAAA,EAAA,EAAM,KAAA,EAAc,OAAA,EAAQ,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,2BAAA,EAA2B,KAAA,EACtE,gBACH,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,QAAA,EAAU,OAAO,IAAA;AAEnC,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACZ,QAAA,EAAA;AAAA,IAAA,QAAA,oBACC,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,IAAA;AAAA,QACL,KAAA,EAAM,SAAA;AAAA,QACN,QAAA,EAAU,IAAA;AAAA,QACV,aAAW,IAAA,IAAQ,MAAA;AAAA,QACnB,2BAAA,EAA0B,QAAA;AAAA,QAC1B,OAAA,EAAS,QAAA;AAAA,QAER,QAAA,EAAA,QAAA,CAAS,eAAe,MAAA,CAAO;AAAA;AAAA,KAClC;AAAA,IAED,QAAA,oBACC,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,IAAA;AAAA,QACL,OAAA,EAAQ,OAAA;AAAA,QACR,QAAA,EAAU,IAAA;AAAA,QACV,aAAW,IAAA,IAAQ,MAAA;AAAA,QACnB,2BAAA,EAA0B,QAAA;AAAA,QAC1B,OAAA,EAAS,QAAA;AAAA,QAER,QAAA,EAAA,QAAA,CAAS,eAAe,MAAA,CAAO;AAAA;AAAA;AAClC,GAAA,EAEJ,CAAA;AAEJ;AAWO,SAAS,WAAA,CAAY;AAAA,EAC1B,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,SAAA;AAAA,EACA,QAAA,GAAW,CAAC,MAAM,CAAA;AAAA,EAClB,SAAA,GAAY,IAAA;AAAA,EACZ,cAAA;AAAA,EACA,MAAA,EAAQ,UAAA;AAAA,EACR,UAAA,GAAa,iBAAA;AAAA,EACb,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,MAAA,GAAS,YAAY,UAAU,CAAA;AACrC,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,CAAA,GAAI,sBAAsB,aAAa,CAAA;AAEvD,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,MAAA;AACjC,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,QAAA;AACzC,EAAA,MAAM,WAAW,UAAA,KAAe,UAAA;AAChC,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,EAAS,QAAQ,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,QAAQ,IAAA,KAAS,QAAA;AAChC,EAAA,MAAM,WAAW,OAAA,CAAQ,QAAA;AACzB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA;AAErC,EAAA,MAAM,OAAO,OAAA,CAAQ,MAAA,EAAQ,QAAQ,SAAA,CAAU,OAAA,CAAQ,MAAM,MAAM,CAAA;AAEnE,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAA8B;AAC5C,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,MAAM,EAAA,GAAK,IAAA,KAAS,QAAA,GAAW,gBAAA,GAAmB,gBAAA;AAClD,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,MAAM,GAAA,GAA+B;AAAA,MACnC,IAAA,EAAM,IAAA,KAAS,QAAA,GAAW,iBAAA,GAAoB,iBAAA;AAAA,MAC9C,WAAW,OAAA,CAAQ,EAAA;AAAA,MACnB,YAAY,QAAA,CAAS;AAAA,KACvB;AACA,IAAA,GAAA,CAAI,MAAM;AACR,MAAA,UAAA,GAAa,GAAG,CAAA;AAChB,MAAA,OAAO,GAAG,OAAO,CAAA;AAAA,IACnB,GAAG,GAAG,CAAA;AAAA,EACR,CAAA;AAEA,EAAA,MAAM,OACJ,OAAA,CAAQ,MAAA,KAAW,yBACjB,GAAA,CAAC,KAAA,EAAA,EAAI,qBAAkB,EAAA,EAAG,SAAA,EAAU,iCAAA,EACjC,QAAA,EAAA,OAAA,CAAQ,SACX,CAAA,mBAEA,GAAA,CAAC,SAAI,mBAAA,EAAkB,EAAA,EAAG,WAAU,qBAAA,EAClC,QAAA,kBAAA,GAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACE,GAAG,cAAA;AAAA,MACJ,OAAO,OAAA,CAAQ,OAAA;AAAA,MACf,MAAA,EAAO,UAAA;AAAA,MACP,SAAA,EAAW,MAAA,KAAW,WAAA,GAAc,SAAA,GAAY;AAAA;AAAA,GAClD,EACF,CAAA;AAGJ,EAAA,MAAM,WAAA,GACJ,OAAA,CAAQ,WAAA,IAAe,OAAA,CAAQ,WAAA,CAAY,MAAA,GAAS,CAAA,mBAClD,GAAA,CAAC,IAAA,EAAA,EAAG,uBAAA,EAAsB,EAAA,EAAG,YAAA,EAAY,OAAO,WAAA,EAAa,SAAA,EAAU,0BAAA,EACpE,QAAA,EAAA,OAAA,CAAQ,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,yBACvB,cAAA,EAAA,EAA0B,UAAA,EAAY,CAAA,EAAG,OAAA,EAAkB,gBAAA,EAAA,EAAvC,CAAA,CAAE,EAAyE,CACjG,GACH,CAAA,GACE,IAAA;AAEN,EAAA,MAAM,UAAA,GACJ,MAAA,KAAW,SAAA,mBACT,GAAA,CAAC,KAAA,EAAA,EAAI,yBAAsB,SAAA,EAAU,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,UAAU,CAAA,EAC1E,iBAAO,OAAA,EACV,CAAA,GACE,MAAA,KAAW,QAAA,mBACb,GAAA,CAAC,KAAA,EAAA,EAAI,uBAAA,EAAsB,QAAA,EAAS,SAAA,EAAU,6CAAA,EAC3C,QAAA,EAAA,MAAA,CAAO,MAAA,EACV,CAAA,GACE,IAAA;AAEN,EAAA,MAAM,cACJ,OAAA,KAAY,MAAA,IAAa,YAAY,IAAA,IAAQ,OAAA,KAAY,wBACvD,GAAA,CAAC,KAAA,EAAA,EAAI,2BAAA,EAA0B,EAAA,EAAG,WAAW,EAAA,CAAG,wCAAA,EAA0C,YAAY,OAAO,CAAA,EAC1G,mBACH,CAAA,GACE,IAAA;AAEN,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,qBAAqB,OAAA,CAAQ,EAAA;AAAA,IAC7B,kBAAkB,OAAA,CAAQ,IAAA;AAAA,IAC1B,kBAAA,EAAoB,MAAA;AAAA,IACpB,sBAAA,EAAwB,UAAA;AAAA,IACxB,eAAA,EAAiB,MAAM,EAAA,GAAK,MAAA;AAAA,IAC5B,mBAAA,EAAqB,UAAU,EAAA,GAAK,MAAA;AAAA,IACpC,WAAA,EAAa,MAAA,KAAW,WAAA,GAAc,IAAA,GAAO;AAAA,GAC/C;AAEA,EAAA,IAAI,MAAA,IAAU,CAAC,QAAA,EAAU;AACvB,IAAA,uBACE,IAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACE,GAAG,SAAA;AAAA,QACJ,WAAW,EAAA,CAAG,0DAAA,EAA4D,UAAA,EAAY,SAAA,EAAW,YAAY,OAAO,CAAA;AAAA,QAEnH,QAAA,EAAA;AAAA,UAAA,QAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAM,KAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,0BAAA,EAAyB,EAAA,EACpE,QAAA,EAAA,MAAA,CAAO,QAAA,EACV,CAAA;AAAA,0BAEF,GAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,eAAe,UAAA,EAAY,MAAM,GAAI,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,UAC5D,WAAA;AAAA,UACA;AAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,MAAM,WAAA,GAAc,EAAA;AAAA,IAClB,mCAAA;AAAA,IACA,IAAA;AAAA,IACA,QAAA,GACI,iGAAA,GACA,QAAA,GACE,EAAA,CAAG,sDAAA,EAAwD,OAAO,CAAA,GAClE,GAAA,GACE,EAAA,CAAG,QAAA,EAAU,MAAA,EAAQ,OAAO,CAAA,GAC5B,aAAA;AAAA,IACR,WAAW,QAAA,IAAY,wBAAA;AAAA,IACvB,UAAA,EAAY,MAAA;AAAA,IACZ,YAAY,UAAA,EAAY;AAAA,GAC1B;AAEA,EAAA,MAAM,8BACJ,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,QAAA,wBACE,KAAA,EAAA,EAAI,SAAA,EAAU,QAAA,EACb,QAAA,kBAAA,GAAA,CAAC,SAAM,KAAA,EAAM,OAAA,EAAQ,OAAA,EAAQ,MAAA,EAAO,MAAK,IAAA,EAAK,0BAAA,EAAyB,EAAA,EACpE,QAAA,EAAA,MAAA,CAAO,UACV,CAAA,EACF,CAAA;AAAA,IAED,4BACC,IAAA,CAAC,KAAA,EAAA,EAAI,2BAAA,EAA0B,EAAA,EAAG,WAAU,0CAAA,EAC1C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,OAAM,QAAA,EAAS,OAAA,EAAQ,QAAO,IAAA,EAAK,IAAA,EACvC,iBAAO,QAAA,EACV,CAAA;AAAA,MACC,SAAS,KAAA,oBAAS,GAAA,CAAC,UAAK,SAAA,EAAU,aAAA,EAAe,mBAAS,KAAA,EAAM;AAAA,KAAA,EACnE,CAAA;AAAA,IAED,IAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA,oBACC,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,QAAA,EAAU,gBAAA,GAAmB,MAAM,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,QACtD,QAAA,EAAU,gBAAA,GAAmB,MAAM,MAAA,CAAO,QAAQ,CAAA,GAAI;AAAA;AAAA;AACxD,GAAA,EAEJ,CAAA;AAGF,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACJ,SAAA,EAAW,EAAA;AAAA,QACT,mBAAA;AAAA,QACA,UAAU,QAAA,GAAW,MAAA;AAAA,QACrB,GAAA,IAAO,kBAAA;AAAA,QACP,SAAA;AAAA,QACA,UAAA,EAAY;AAAA,OACd;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAU,cAAA,EAAe,aAAA,EAAa,WAAW,MAAA,EACnD,QAAA,EAAA,CAAC,OAAA,oBACA,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,MAAK,GAAA,EAAK,OAAA,CAAQ,QAAQ,MAAA,EAAQ,GAAA,EAAI,IAAG,QAAA,EAAU,QAAA,CAAS,IAAI,CAAA,EAAG,CAAA,EAEpF,CAAA;AAAA,wBACA,IAAA,CAAC,SAAI,SAAA,EAAW,EAAA,CAAG,qCAAqC,GAAA,GAAM,WAAA,GAAc,aAAa,CAAA,EACtF,QAAA,EAAA;AAAA,UAAA,CAAC,OAAA,oBACA,IAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,kBAAA,EAAiB,EAAA;AAAA,cACjB,WAAW,EAAA,CAAG,wCAAA,EAA0C,GAAA,IAAO,kBAAA,EAAoB,YAAY,MAAM,CAAA;AAAA,cAErG,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,oBAAiB,EAAA,EAAG,SAAA,EAAW,GAAG,aAAA,EAAe,IAAI,GACxD,QAAA,EAAA,IAAA,EACH,CAAA;AAAA,gBACC,IAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,IAAA,CAAK,WAAA,EAAY,EAAG,SAAA,EAAW,UAAA,EAC5C,QAAA,EAAA,UAAA,CAAW,IAAI,CAAA,EAClB;AAAA;AAAA;AAAA,WAEJ;AAAA,UAED,QAAA,mBACC,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,sBAAoB,QAAA,CAAS,EAAA;AAAA,cAC7B,0BAAA,EAA0B,SAAS,KAAA,IAAS,SAAA;AAAA,cAC5C,aAAW,IAAA,IAAQ,MAAA;AAAA,cACnB,SAAA,EAAW,EAAA,CAAG,oBAAA,EAAsB,WAAW,CAAA;AAAA,cAE9C,QAAA,EAAA;AAAA;AAAA,WACH,mBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,kBAAA,EAAiB,EAAA,EAAG,WAAW,EAAA,CAAG,oBAAA,EAAsB,WAAW,CAAA,EACrE,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,UAED,UAAA;AAAA,UACA;AAAA,SAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA;AC1X1B,IAAMA,WAAAA,GACJ,iIAAA;AACF,IAAMC,OAAAA,GACJ,6HAAA;AAIF,IAAM,kBAAA,GAAqB,OAAO,MAAA,KAAW,WAAA,GAAcC,SAAAA,GAAY,eAAA;AAgChE,SAAS,UAAA,CAAW;AAAA,EACzB,GAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA,GAAe,CAAA;AAAA,EACf,aAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA,GAAiB,KAAA;AAAA,EACjB,aAAA,GAAgB,IAAA;AAAA,EAChB,eAAA,GAAkB,EAAA;AAAA,EAClB,gBAAA;AAAA,EACA,UAAA,GAAa,MAAA;AAAA,EACb,SAAA,GAAY,gBAAA;AAAA,EACZ,gBAAA,GAAmB,KAAA;AAAA,EACnB,aAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA;AAAA,EAEA,QAAA,GAAW,CAAC,MAAM,CAAA;AAAA,EAClB,SAAA,GAAY,IAAA;AAAA,EACZ,cAAA;AAAA,EACA,MAAA,EAAQ,UAAA;AAAA,EACR,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA,EAAU,YAAA;AAAA,EACV,GAAG;AACL,CAAA,EAAoB;AAClB,EAAA,MAAM,MAAA,GAAS,YAAY,UAAU,CAAA;AACrC,EAAA,MAAM,YAAY,KAAA,EAAM;AACxB,EAAA,MAAM,MAAA,GAASC,OAAuB,IAAI,CAAA;AAC1C,EAAA,MAAM,UAAA,GAAaA,OAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,WAAA,GAAcA,OAAO,IAAI,CAAA;AAC/B,EAAA,MAAM,OAAA,GAAUA,OAAoB,IAAI,CAAA;AACxC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,SAAS,IAAI,CAAA;AAC7C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,SAAS,CAAC,CAAA;AACtC,EAAA,MAAM,CAAC,QAAA,EAAU,OAAO,CAAA,GAAI,sBAAsB,aAAa,CAAA;AAE/D,EAAA,MAAM,mBAAA,GAAsBD,OAAO,gBAAgB,CAAA;AACnD,EAAA,mBAAA,CAAoB,OAAA,GAAU,gBAAA;AAE9B,EAAA,MAAM,OAAA,GAAUE,WAAAA;AAAA,IACd,CAAC,EAAA,KAAoB,EAAA,CAAG,eAAe,EAAA,CAAG,SAAA,GAAY,GAAG,YAAA,IAAgB,eAAA;AAAA,IACzE,CAAC,eAAe;AAAA,GAClB;AAEA,EAAA,MAAM,cAAA,GAAiBA,WAAAA,CAAY,CAAC,KAAA,KAAmB;AACrD,IAAA,MAAM,OAAA,GAAU,YAAY,OAAA,KAAY,KAAA;AACxC,IAAA,WAAA,CAAY,OAAA,GAAU,KAAA;AACtB,IAAA,WAAA,CAAY,KAAK,CAAA;AACjB,IAAA,IAAI,KAAA,YAAiB,CAAC,CAAA;AACtB,IAAA,IAAI,OAAA,EAAS,mBAAA,CAAoB,OAAA,GAAU,KAAK,CAAA;AAAA,EAClD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,iBAAA,GAAoBA,YAAY,MAAM;AAC1C,IAAA,MAAM,KAAK,MAAA,CAAO,OAAA;AAClB,IAAA,IAAI,CAAC,EAAA,EAAI;AAGT,IAAA,EAAA,CAAG,YAAY,EAAA,CAAG,YAAA;AAAA,EACpB,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,kBAAA,CAAmB,MAAM;AACvB,IAAA,MAAM,KAAK,MAAA,CAAO,OAAA;AAClB,IAAA,IAAI,CAAC,EAAA,EAAI;AAET,IAAA,MAAM,MAAM,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AACpC,IAAA,MAAM,KAAA,GAAQ,IAAI,CAAC,CAAA;AACnB,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,GAAA,CAAI,MAAA,GAAS,CAAC,CAAA;AAC/B,IAAA,MAAM,OAAO,OAAA,CAAQ,OAAA;AAErB,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,IAAI,eAAe,iBAAA,EAAkB;AAAA,IACvC,CAAA,MAAO;AACL,MAAA,MAAM,YACJ,IAAA,CAAK,IAAA,KAAS,MAAA,IACd,IAAA,CAAK,SAAS,IAAA,IACd,IAAA,CAAK,KAAA,KAAU,MAAA,IACf,KAAK,KAAA,KAAU,KAAA,IACf,GAAA,CAAI,QAAA,CAAS,KAAK,KAAK,CAAA;AAEzB,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,IAAI,aAAA,IAAiB,WAAA,CAAY,OAAA,EAAS,iBAAA,EAAkB;AAAA,gBAIpD,SAAA,GAAY,IAAA,CAAK,SAAA,IAAa,EAAA,CAAG,eAAe,IAAA,CAAK,YAAA,CAAA;AAAA,MAC/D,CAAA,MAAO;AACL,QAAA,MAAM,SAAA,GAAY,KAAK,IAAA,KAAS,MAAA,GAAY,KAAK,GAAA,CAAI,OAAA,CAAQ,KAAK,IAAI,CAAA;AACtE,QAAA,MAAM,WAA8B,EAAC;AACrC,QAAA,KAAA,IAAS,IAAI,SAAA,GAAY,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACpD,UAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,QAAA,CAAS,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,QAC9D;AAEA,QAAA,IAAI,aAAA,IAAiB,YAAY,OAAA,EAAS;AACxC,UAAA,iBAAA,EAAkB;AAAA,QACpB,CAAA,MAAA,IAAW,aAAA,IAAiB,QAAA,CAAS,IAAA,CAAK,CAAC,MAAM,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAC,CAAA,EAAG;AAEpE,UAAA,iBAAA,EAAkB;AAAA,QACpB,CAAA,MAAA,IAAW,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AAC9B,UAAA,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,GAAI,QAAA,CAAS,MAAM,CAAA;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,OAAA,GAAU,EAAE,GAAA,EAAK,IAAI,IAAI,GAAG,CAAA,EAAG,KAAA,EAAO,IAAA,EAAM,YAAA,EAAc,EAAA,CAAG,YAAA,EAAc,SAAA,EAAW,GAAG,SAAA,EAAU;AAC3G,IAAA,MAAM,WAAA,GAAc,QAAQ,EAAE,CAAA;AAC9B,IAAA,IAAI,WAAA,KAAgB,WAAA,CAAY,OAAA,IAAW,WAAA,iBAA4B,WAAW,CAAA;AAAA,EAGpF,GAAG,CAAC,QAAA,EAAU,eAAe,OAAA,EAAS,cAAA,EAAgB,iBAAiB,CAAC,CAAA;AAIxE,EAAAH,UAAU,MAAM;AACd,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,aAAA,IAAiB,OAAO,mBAAmB,WAAA,EAAa;AACzE,IAAA,MAAM,EAAA,GAAK,IAAI,cAAA,CAAe,MAAM;AAClC,MAAA,IAAI,WAAA,CAAY,SAAS,iBAAA,EAAkB;AAAA,IAC7C,CAAC,CAAA;AACD,IAAA,EAAA,CAAG,QAAQ,OAAO,CAAA;AAClB,IAAA,OAAO,MAAM,GAAG,UAAA,EAAW;AAAA,EAC7B,CAAA,EAAG,CAAC,aAAA,EAAe,iBAAiB,CAAC,CAAA;AAErC,EAAA,MAAM,QAAA,GAAWG,WAAAA;AAAA,IACf,CAAC,CAAA,KAA+B;AAC9B,MAAA,YAAA,GAAe,CAAC,CAAA;AAChB,MAAA,IAAI,QAAQ,OAAA,EAAS,OAAA,CAAQ,OAAA,CAAQ,SAAA,GAAY,EAAE,aAAA,CAAc,SAAA;AACjE,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,CAAA,CAAE,aAAa,CAAA;AACnC,MAAA,IAAI,GAAA,KAAQ,WAAA,CAAY,OAAA,IAAW,GAAA,iBAAoB,GAAG,CAAA;AAAA,IAC5D,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,cAAA,EAAgB,YAAY;AAAA,GACxC;AAEA,EAAA,MAAM,YAAA,GAAeA,YAAY,MAAM;AACrC,IAAA,UAAA,GAAa,EAAE,IAAA,EAAM,gBAAA,EAAkB,MAAA,EAAQ,CAAA;AAC/C,IAAA,iBAAA,EAAkB;AAClB,IAAA,cAAA,CAAe,IAAI,CAAA;AAGnB,IAAA,MAAA,CAAO,OAAA,EAAS,KAAA,CAAM,EAAE,aAAA,EAAe,MAAM,CAAA;AAAA,EAC/C,GAAG,CAAC,UAAA,EAAY,MAAA,EAAQ,iBAAA,EAAmB,cAAc,CAAC,CAAA;AAE1D,EAAA,mBAAA;AAAA,IACE,GAAA;AAAA,IACA,OAAO;AAAA,MACL,cAAA,GAAiB;AACf,QAAA,iBAAA,EAAkB;AAClB,QAAA,MAAM,KAAK,MAAA,CAAO,OAAA;AAClB,QAAA,IAAI,EAAA,EAAI,cAAA,CAAe,OAAA,CAAQ,EAAE,CAAC,CAAA;AAAA,MACpC,CAAA;AAAA,MACA,gBAAgB,EAAA,EAAY;AAC1B,QAAA,MAAM,KAAK,MAAA,CAAO,OAAA;AAClB,QAAA,IAAI,CAAC,IAAI,OAAO,KAAA;AAChB,QAAA,MAAM,SAAS,CAAC,GAAG,GAAG,gBAAA,CAA8B,qBAAqB,CAAC,CAAA,CAAE,IAAA;AAAA,UAC1E,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,CAAa,mBAAmB,CAAA,KAAM;AAAA,SACjD;AACA,QAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AACpB,QAAA,EAAA,CAAG,YAAY,MAAA,CAAO,SAAA;AACtB,QAAA,cAAA,CAAe,OAAA,CAAQ,EAAE,CAAC,CAAA;AAC1B,QAAA,OAAO,IAAA;AAAA,MACT,CAAA;AAAA,MACA,IAAI,OAAA,GAAU;AACZ,QAAA,OAAO,MAAA,CAAO,OAAA;AAAA,MAChB;AAAA,KACF,CAAA;AAAA,IACA,CAAC,iBAAA,EAAmB,cAAA,EAAgB,OAAO;AAAA,GAC7C;AAEA,EAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,aAAa,CAAA,KAAM,UAAA,IAAc,IAAA,CAAA;AACjE,EAAA,MAAM,cAAc,cAAA,IAAkB,QAAA;AACtC,EAAA,MAAM,QAAA,GAAW,MAAA,GAAS,CAAA,IAAK,CAAC,QAAA;AAChC,EAAA,MAAM,cACJ,gBAAA,KAAqB,IAAA,GAAO,0BAA0B,OAAO,gBAAA,KAAqB,WAAW,gBAAA,GAAmB,CAAA;AAElH,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,IAAI,OAAA;AACJ,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACzB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,CAAA,CAAE,SAAS,CAAA;AAC/B,IAAA,IAAI,SAAA,GAAuB,IAAA;AAC3B,IAAA,IAAI,UAAA,KAAe,SAAS,IAAA,EAAM;AAChC,MAAA,MAAM,GAAA,GAAM,OAAO,IAAI,CAAA;AACvB,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,SAAA,mBACEC,IAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,yBAAA,EAAyB,GAAA;AAAA,YACzB,SAAA,EAAW,EAAA,CAAG,2CAAA,EAA6CN,WAAAA,EAAY,YAAY,SAAS,CAAA;AAAA,YAE5F,QAAA,EAAA;AAAA,8BAAAO,GAAAA,CAAC,UAAK,aAAA,EAAY,MAAA,EAAO,WAAW,EAAA,CAAG,sBAAA,EAAwBN,OAAM,CAAA,EAAG,CAAA;AAAA,8BACxEM,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,SAAA,CAAU,IAAI,CAAA,EAAE,CAAA;AAAA,8BACvBA,IAAC,MAAA,EAAA,EAAK,aAAA,EAAY,QAAO,SAAA,EAAW,EAAA,CAAG,sBAAA,EAAwBN,OAAM,CAAA,EAAG;AAAA;AAAA;AAAA,SAC1E;AAEF,QAAA,OAAA,GAAU,GAAA;AAAA,MACZ;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,WAAA,GAAc,CAAA,IAAK,CAAC,SAAA,IAAa,cAAA,CAAe,QAAA,CAAS,CAAA,GAAI,CAAC,CAAA,EAAG,CAAA,EAAG,WAAW,CAAA;AAE/F,IAAA,KAAA,CAAM,IAAA;AAAA,sBACJK,IAAAA,CAACE,UAAAA,EAAA,EACE,QAAA,EAAA;AAAA,QAAA,SAAA;AAAA,wBACDD,GAAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,CAAA;AAAA,YACT,OAAA;AAAA,YACA,OAAA,EAAS,gBAAgB,CAAC,CAAA;AAAA,YAC1B,QAAA;AAAA,YACA,SAAA;AAAA,YACA,cAAA;AAAA,YACA,MAAA,EAAQ,UAAA;AAAA,YACR,UAAA;AAAA,YACA,gBAAA;AAAA,YACA,gBAAA;AAAA,YACA,gBAAA;AAAA,YACA,UAAA;AAAA,YACA,aAAA;AAAA,YACA;AAAA;AAAA;AACF,OAAA,EAAA,EAjBa,EAAE,EAkBjB;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,CAAA,GAAI,IAAI,YAAY,CAAA,CAAA;AAE1B,EAAA,uBACED,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,8BAAA,EAA6B,EAAA;AAAA,MAC5B,GAAG,IAAA;AAAA,MACJ,SAAA,EAAW,EAAA,CAAG,uBAAA,EAAyB,SAAA,EAAW,YAAY,IAAI,CAAA;AAAA,MAEjE,QAAA,EAAA;AAAA,QAAA,OAAA,KAAY,MAAA,IAAa,OAAA,KAAY,IAAA,oBACpCC,GAAAA;AAAA,UAAC,CAAA;AAAA,UAAA;AAAA,YACC,EAAA,EAAI,SAAA;AAAA,YACJ,sCAAA,EAAqC,EAAA;AAAA,YACrC,SAAA,EAAW,EAAA,CAAG,0CAAA,EAA4C,UAAA,EAAY,OAAO,CAAA;AAAA,YAE5E,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,wBAEFD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uCAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,GAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,MAAA;AAAA,cACL,kCAAA,EAAiC,EAAA;AAAA,cACjC,IAAA,EAAK,KAAA;AAAA,cACL,WAAA,EAAU,QAAA;AAAA,cACV,eAAA,EAAc,WAAA;AAAA,cACd,YAAA,EAAY,OAAA,GAAU,MAAA,GAAY,MAAA,CAAO,GAAA;AAAA,cACzC,iBAAA,EAAiB,UAAU,SAAA,GAAY,MAAA;AAAA,cACvC,QAAA,EAAU,CAAA;AAAA,cACV,QAAA;AAAA,cACA,SAAA,EAAW,EAAA;AAAA,gBACT,iMAAA;AAAA,gBACA,UAAA,EAAY;AAAA,eACd;AAAA,cAEA,0BAAAD,IAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,UAAA,EAAY,WAAU,oBAAA,EAC7B,QAAA,EAAA;AAAA,gBAAA,eAAA,oBACCC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BACb,QAAA,kBAAAA,GAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,IAAA,EAAK,IAAA;AAAA,oBACL,OAAA,EAAQ,OAAA;AAAA,oBACR,2CAAA,EAA0C,EAAA;AAAA,oBAC1C,QAAA,EAAU,WAAA;AAAA,oBACV,aAAW,WAAA,IAAe,MAAA;AAAA,oBAC1B,OAAA,EAAS,MACP,OAAA,CAAQ,MAAM;AACZ,sBAAA,UAAA,GAAa,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA;AACrC,sBAAA,OAAO,aAAA,EAAe;AAAA,oBACxB,CAAA,EAAG,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA;AAAA,oBAG5B,QAAA,EAAA,WAAA,GAAc,MAAA,CAAO,cAAA,GAAiB,MAAA,CAAO;AAAA;AAAA,iBAChD,EACF,CAAA;AAAA,gBAED,QAAA,CAAS,MAAA,KAAW,CAAA,IAAK,KAAA,KAAU,0BAClCA,GAAAA,CAAC,KAAA,EAAA,EAAI,oCAAA,EAAmC,IAAG,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiCP,WAAU,GACjG,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,gBAED;AAAA,eAAA,EACH;AAAA;AAAA,WACF;AAAA,UACC,4BACCO,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uEACb,QAAA,kBAAAA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAK,IAAA;AAAA,cACL,mCAAA,EAAkC,EAAA;AAAA,cAClC,aAAA,EAAa,MAAA;AAAA,cACb,YAAA,EAAa,cAAA;AAAA,cACb,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,UAAA,EAAY,IAAI,CAAA;AAAA,cAC/D,OAAA,EAAS,YAAA;AAAA,cAER,QAAA,EAAA,MAAA,CAAO,YAAY,MAAM;AAAA;AAAA,WAC5B,EACF;AAAA,SAAA,EAEJ,CAAA;AAAA,QACC,QAAA,KAAa,MAAA,IAAa,QAAA,KAAa,IAAA,oBACtCA,GAAAA,CAAC,KAAA,EAAA,EAAI,uCAAA,EAAsC,EAAA,EAAG,WAAW,EAAA,CAAG,UAAA,EAAY,UAAA,EAAY,QAAQ,GACzF,QAAA,EAAA,QAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA","file":"chunk-PACFMPSX.js","sourcesContent":["import type { ChatMessageData, ChatThreadLabels } from \"./ChatThread.types\";\n\nexport const DEFAULT_LABELS: ChatThreadLabels = {\n log: \"Conversation\",\n loadEarlier: \"Load earlier messages\",\n loadingEarlier: \"Loading earlier messages...\",\n newMessages: (n) => (n === 1 ? \"1 new message\" : `${n} new messages`),\n internal: \"Internal note\",\n pending: \"Sending...\",\n failed: \"Not sent\",\n proposal: \"Proposed\",\n accept: \"Accept\",\n reject: \"Reject\",\n accepted: \"Accepted\",\n rejected: \"Rejected\",\n withdrawn: \"Withdrawn\",\n attachments: \"Attachments\",\n roles: {\n user: \"You\",\n assistant: \"Assistant\",\n system: \"System\",\n agent: \"Agent\",\n staff: \"Staff\",\n customer: \"Customer\",\n },\n};\n\nexport function mergeLabels(labels?: Partial<ChatThreadLabels>): ChatThreadLabels {\n if (!labels) return DEFAULT_LABELS;\n return {\n ...DEFAULT_LABELS,\n ...labels,\n roles: { ...DEFAULT_LABELS.roles, ...labels.roles },\n };\n}\n\n/** `null` for a missing or unparseable time: no time renders rather than \"Invalid Date\". */\nexport function toDate(value: string | number | undefined): Date | null {\n if (value === undefined || value === null || value === \"\") return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n/** Local calendar day, `YYYY-MM-DD`. */\nexport function dayKey(d: Date): string {\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\nexport function defaultFormatTime(d: Date): string {\n return d.toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function defaultFormatDay(d: Date): string {\n return d.toLocaleDateString(undefined, { dateStyle: \"medium\" });\n}\n\nexport function roleLabel(role: string, labels: ChatThreadLabels): string {\n const known = labels.roles[role];\n if (known) return known;\n return role ? role.charAt(0).toUpperCase() + role.slice(1) : \"\";\n}\n\nexport function initials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n const first = parts[0][0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n}\n\nexport function isOwn(message: ChatMessageData, ownRoles: string[]): boolean {\n return message.own ?? ownRoles.includes(message.role);\n}\n\nexport const DEFAULT_GROUP_WINDOW_MS = 5 * 60 * 1000;\n\n/** Does `curr` continue `prev`'s group? Same role, same author, same visibility, within the window. */\nexport function continuesGroup(\n prev: ChatMessageData | undefined,\n curr: ChatMessageData,\n windowMs: number,\n): boolean {\n if (!prev) return false;\n if (prev.role !== curr.role) return false;\n if ((prev.author?.name ?? \"\") !== (curr.author?.name ?? \"\")) return false;\n if ((prev.visibility ?? \"public\") !== (curr.visibility ?? \"public\")) return false;\n if (prev.proposal || curr.proposal) return false;\n if (curr.role === \"system\") return false;\n const a = toDate(prev.createdAt);\n const b = toDate(curr.createdAt);\n if (!a || !b) return false;\n const gap = b.getTime() - a.getTime();\n return gap >= 0 && gap <= windowMs;\n}\n\nexport function formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { sanitizeComponentHref } from \"../../utils/sanitize\";\nimport { Avatar } from \"../Avatar\";\nimport { Badge } from \"../Badge\";\nimport { Button } from \"../Button\";\nimport { ContentRenderer } from \"../ContentRenderer\";\nimport type {\n ChatAction,\n ChatAttachment,\n ChatMessageData,\n ChatMessageProps,\n ChatThreadActionContext,\n ChatThreadLabels,\n} from \"./ChatThread.types\";\nimport {\n defaultFormatTime,\n formatBytes,\n initials,\n isOwn,\n mergeLabels,\n roleLabel,\n toDate,\n} from \"./chat-utils\";\n\nconst BORDER =\n \"border-[color:var(--fancy-border,var(--color-zinc-200))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\";\nconst SURFACE =\n \"bg-[color:var(--fancy-surface,var(--color-white))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\";\nconst SURFACE_MUTED =\n \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\";\nconst TEXT =\n \"text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\";\nconst TEXT_MUTED =\n \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\";\n\n/**\n * Run a host callback that may return a Promise. While it is pending the\n * control is busy and a second run is refused. A rejection goes to\n * `onActionError`, or is left unhandled so it still reaches the console.\n *\n * @internal shared by ChatMessage (proposal decisions) and ChatThread (load earlier)\n */\nexport function useAcknowledgedAction(\n onActionError?: (error: unknown, action: ChatThreadActionContext) => void,\n): [busy: boolean, run: (fn: () => ReturnType<ChatAction>, ctx: ChatThreadActionContext) => void] {\n const [busy, setBusy] = useState(false);\n const busyRef = useRef(false);\n const mounted = useRef(true);\n const onErrorRef = useRef(onActionError);\n onErrorRef.current = onActionError;\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const run = useCallback((fn: () => ReturnType<ChatAction>, ctx: ChatThreadActionContext) => {\n if (busyRef.current) return;\n const result = fn();\n if (!result || typeof (result as Promise<unknown>).then !== \"function\") return;\n\n busyRef.current = true;\n setBusy(true);\n const settle = () => {\n busyRef.current = false;\n if (mounted.current) setBusy(false);\n };\n void Promise.resolve(result).then(settle, (error: unknown) => {\n settle();\n const onError = onErrorRef.current;\n if (onError) onError(error, ctx);\n else throw error;\n });\n }, []);\n\n return [busy, run];\n}\n\nfunction AttachmentItem({\n attachment,\n message,\n renderAttachment,\n}: {\n attachment: ChatAttachment;\n message: ChatMessageData;\n renderAttachment?: ChatMessageProps[\"renderAttachment\"];\n}) {\n let body: ReactNode;\n if (renderAttachment) {\n body = renderAttachment(attachment, message);\n } else {\n const href = sanitizeComponentHref(\"ChatMessage\", attachment.url);\n const size = typeof attachment.size === \"number\" ? (\n <span className={cn(\"ml-1\", TEXT_MUTED)}>({formatBytes(attachment.size)})</span>\n ) : null;\n body = href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"underline underline-offset-2 break-all\">\n {attachment.name}\n {size}\n </a>\n ) : (\n <span className=\"break-all\">\n {attachment.name}\n {size}\n </span>\n );\n }\n\n return (\n <li data-chat-attachment={attachment.id} className=\"text-sm\">\n {body}\n </li>\n );\n}\n\nfunction ProposalFooter({\n message,\n labels,\n busy,\n onAccept,\n onReject,\n}: {\n message: ChatMessageData;\n labels: ChatThreadLabels;\n busy: boolean;\n onAccept?: () => void;\n onReject?: () => void;\n}) {\n const proposal = message.proposal!;\n const state = proposal.state ?? \"pending\";\n\n if (state !== \"pending\") {\n const text = state === \"accepted\" ? labels.accepted : state === \"rejected\" ? labels.rejected : labels.withdrawn;\n const color = state === \"accepted\" ? \"emerald\" : state === \"rejected\" ? \"red\" : \"zinc\";\n return (\n <div className=\"mt-2\">\n <Badge color={color} variant=\"soft\" size=\"sm\" data-chat-proposal-status={state}>\n {text}\n </Badge>\n </div>\n );\n }\n\n if (!onAccept && !onReject) return null;\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n {onAccept && (\n <Button\n type=\"button\"\n size=\"sm\"\n color=\"emerald\"\n disabled={busy}\n aria-busy={busy || undefined}\n data-chat-proposal-action=\"accept\"\n onClick={onAccept}\n >\n {proposal.acceptLabel ?? labels.accept}\n </Button>\n )}\n {onReject && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n disabled={busy}\n aria-busy={busy || undefined}\n data-chat-proposal-action=\"reject\"\n onClick={onReject}\n >\n {proposal.rejectLabel ?? labels.reject}\n </Button>\n )}\n </div>\n );\n}\n\n/**\n * ChatMessage — one message of a `ChatThread`, usable on its own.\n *\n * Content is markdown through `ContentRenderer`, always sanitised (there is no\n * `unsafe` here on purpose: message bodies are text the host did not author).\n * `format: \"text\"` renders it literally. A message with a `proposal` is an\n * approval card: the host owns its state and decides it through\n * `onProposalAccept` / `onProposalReject`; the card never acts on its own.\n */\nexport function ChatMessage({\n message,\n actions,\n grouped = false,\n className,\n ownRoles = [\"user\"],\n streaming = true,\n contentOptions,\n labels: labelsProp,\n formatTime = defaultFormatTime,\n renderAttachment,\n onProposalAccept,\n onProposalReject,\n onActivity,\n onActionError,\n classNames,\n}: ChatMessageProps) {\n const labels = mergeLabels(labelsProp);\n const [busy, run] = useAcknowledgedAction(onActionError);\n\n const status = message.status ?? \"sent\";\n const visibility = message.visibility ?? \"public\";\n const internal = visibility === \"internal\";\n const own = isOwn(message, ownRoles);\n const system = message.role === \"system\";\n const proposal = message.proposal;\n const date = toDate(message.createdAt);\n // Always a name: the author's, else the role's (\"Assistant\", or the host's own role capitalised).\n const name = message.author?.name || roleLabel(message.role, labels);\n\n const decide = (kind: \"accept\" | \"reject\") => {\n if (!proposal) return;\n const cb = kind === \"accept\" ? onProposalAccept : onProposalReject;\n if (!cb) return;\n const ctx: ChatThreadActionContext = {\n type: kind === \"accept\" ? \"proposal-accept\" : \"proposal-reject\",\n messageId: message.id,\n proposalId: proposal.id,\n };\n run(() => {\n onActivity?.(ctx);\n return cb(message);\n }, ctx);\n };\n\n const body =\n message.format === \"text\" ? (\n <div data-chat-content=\"\" className=\"whitespace-pre-wrap break-words\">\n {message.content}\n </div>\n ) : (\n <div data-chat-content=\"\" className=\"min-w-0 break-words\">\n <ContentRenderer\n {...contentOptions}\n value={message.content}\n format=\"markdown\"\n streaming={status === \"streaming\" ? streaming : false}\n />\n </div>\n );\n\n const attachments =\n message.attachments && message.attachments.length > 0 ? (\n <ul data-chat-attachments=\"\" aria-label={labels.attachments} className=\"mt-2 flex flex-col gap-1\">\n {message.attachments.map((a) => (\n <AttachmentItem key={a.id} attachment={a} message={message} renderAttachment={renderAttachment} />\n ))}\n </ul>\n ) : null;\n\n const statusText =\n status === \"pending\" ? (\n <div data-chat-status-text=\"pending\" className={cn(\"mt-1 text-xs\", TEXT_MUTED)}>\n {labels.pending}\n </div>\n ) : status === \"failed\" ? (\n <div data-chat-status-text=\"failed\" className=\"mt-1 text-xs text-red-600 dark:text-red-400\">\n {labels.failed}\n </div>\n ) : null;\n\n const actionsSlot =\n actions !== undefined && actions !== null && actions !== false ? (\n <div data-chat-message-actions=\"\" className={cn(\"mt-1 flex flex-wrap items-center gap-1\", classNames?.actions)}>\n {actions}\n </div>\n ) : null;\n\n const rootAttrs = {\n \"data-chat-message\": message.id,\n \"data-chat-role\": message.role,\n \"data-chat-status\": status,\n \"data-chat-visibility\": visibility,\n \"data-chat-own\": own ? \"\" : undefined,\n \"data-chat-grouped\": grouped ? \"\" : undefined,\n \"aria-busy\": status === \"streaming\" ? true : undefined,\n };\n\n if (system && !proposal) {\n return (\n <article\n {...rootAttrs}\n className={cn(\"flex flex-col items-center px-4 py-1 text-center text-xs\", TEXT_MUTED, className, classNames?.message)}\n >\n {internal && (\n <Badge color=\"amber\" variant=\"soft\" size=\"sm\" data-chat-internal-label=\"\">\n {labels.internal}\n </Badge>\n )}\n <div className={cn(\"max-w-prose\", classNames?.bubble)}>{body}</div>\n {attachments}\n {actionsSlot}\n </article>\n );\n }\n\n const bubbleClass = cn(\n \"rounded-2xl px-3.5 py-2.5 text-sm\",\n TEXT,\n internal\n ? \"border border-dashed border-amber-400 bg-amber-50 dark:border-amber-500/60 dark:bg-amber-950/30\"\n : proposal\n ? cn(\"border-2 border-violet-300 dark:border-violet-500/60\", SURFACE)\n : own\n ? cn(\"border\", BORDER, SURFACE)\n : SURFACE_MUTED,\n status === \"failed\" && \"ring-1 ring-red-400/70\",\n classNames?.bubble,\n proposal && classNames?.proposal,\n );\n\n const bubbleInner = (\n <>\n {internal && (\n <div className=\"mb-1.5\">\n <Badge color=\"amber\" variant=\"soft\" size=\"sm\" data-chat-internal-label=\"\">\n {labels.internal}\n </Badge>\n </div>\n )}\n {proposal && (\n <div data-chat-proposal-header=\"\" className=\"mb-1.5 flex flex-wrap items-center gap-2\">\n <Badge color=\"violet\" variant=\"soft\" size=\"sm\">\n {labels.proposal}\n </Badge>\n {proposal.title && <span className=\"font-medium\">{proposal.title}</span>}\n </div>\n )}\n {body}\n {attachments}\n {proposal && (\n <ProposalFooter\n message={message}\n labels={labels}\n busy={busy}\n onAccept={onProposalAccept ? () => decide(\"accept\") : undefined}\n onReject={onProposalReject ? () => decide(\"reject\") : undefined}\n />\n )}\n </>\n );\n\n return (\n <article\n {...rootAttrs}\n className={cn(\n \"flex gap-2.5 px-3\",\n grouped ? \"pt-0.5\" : \"pt-3\",\n own && \"flex-row-reverse\",\n className,\n classNames?.message,\n )}\n >\n <div className=\"w-8 shrink-0\" aria-hidden={grouped || undefined}>\n {!grouped && (\n <Avatar size=\"sm\" src={message.author?.avatar} alt=\"\" fallback={initials(name)} />\n )}\n </div>\n <div className={cn(\"flex min-w-0 max-w-[85%] flex-col\", own ? \"items-end\" : \"items-start\")}>\n {!grouped && (\n <div\n data-chat-header=\"\"\n className={cn(\"mb-1 flex items-baseline gap-2 text-xs\", own && \"flex-row-reverse\", classNames?.header)}\n >\n <span data-chat-author=\"\" className={cn(\"font-medium\", TEXT)}>\n {name}\n </span>\n {date && (\n <time dateTime={date.toISOString()} className={TEXT_MUTED}>\n {formatTime(date)}\n </time>\n )}\n </div>\n )}\n {proposal ? (\n <div\n data-chat-proposal={proposal.id}\n data-chat-proposal-state={proposal.state ?? \"pending\"}\n aria-busy={busy || undefined}\n className={cn(\"min-w-0 max-w-full\", bubbleClass)}\n >\n {bubbleInner}\n </div>\n ) : (\n <div data-chat-bubble=\"\" className={cn(\"min-w-0 max-w-full\", bubbleClass)}>\n {bubbleInner}\n </div>\n )}\n {statusText}\n {actionsSlot}\n </div>\n </article>\n );\n}\n\nChatMessage.displayName = \"ChatMessage\";\n","import {\n Fragment,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type UIEvent,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button\";\nimport { ChatMessage, useAcknowledgedAction } from \"./ChatMessage\";\nimport type { ChatMessageData, ChatThreadProps } from \"./ChatThread.types\";\nimport {\n DEFAULT_GROUP_WINDOW_MS,\n continuesGroup,\n dayKey,\n defaultFormatDay,\n isOwn,\n mergeLabels,\n toDate,\n} from \"./chat-utils\";\n\nconst TEXT_MUTED =\n \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\";\nconst BORDER =\n \"border-[color:var(--fancy-border,var(--color-zinc-200))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\";\n\n// The isomorphic layout effect: scroll work must happen before paint in the\n// browser, and must not warn during SSR.\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\ninterface Seen {\n ids: Set<string>;\n first?: string;\n last?: string;\n scrollHeight: number;\n /** The reader's position as of the last render or scroll event, before any browser adjustment. */\n scrollTop: number;\n}\n\n/**\n * ChatThread — a controlled message list for agent and support conversations.\n *\n * - **Controlled.** It renders exactly `messages`, oldest first. Loading\n * earlier history and deciding a proposal go through callbacks; nothing is\n * held internally that an agent would need to read or write.\n * - **Stick to the bottom without yanking.** New messages are followed only\n * while the reader is at the bottom. A reader who scrolled up stays put and\n * gets an \"N new messages\" jump control. Prepended history keeps the\n * reader's place. Only the log's own `scrollTop` is ever set, and focus moves\n * with `preventScroll`, so no ancestor (or the page) scrolls (the 5.69 rule).\n * - **Visibility is the host's.** `visibility: \"internal\"` is labelled and\n * styled, never filtered: pass only what the viewer may see.\n * - **Handles:** `data-react-fancy-chat-thread`, `data-chat-message=\"<id>\"`,\n * `data-chat-role`, `data-chat-status`, `data-chat-visibility`,\n * `data-chat-proposal=\"<id>\"`, `data-chat-proposal-action`.\n * - **Observable:** `onActivity` reports every interaction as one stream.\n *\n * Pair it with `Composer` or `PromptInput` in the `composer` slot (both have\n * acknowledged send). It does not ship an input of its own.\n */\nexport function ChatThread({\n ref,\n messages,\n heading,\n headingLevel = 2,\n onLoadEarlier,\n hasEarlier,\n loadingEarlier = false,\n stickToBottom = true,\n bottomThreshold = 48,\n onAtBottomChange,\n separators = \"none\",\n formatDay = defaultFormatDay,\n groupConsecutive = false,\n renderActions,\n composer,\n empty,\n classNames,\n className,\n // message display\n ownRoles = [\"user\"],\n streaming = true,\n contentOptions,\n labels: labelsProp,\n formatTime,\n renderAttachment,\n onProposalAccept,\n onProposalReject,\n onActivity,\n onActionError,\n onScroll: onScrollProp,\n ...rest\n}: ChatThreadProps) {\n const labels = mergeLabels(labelsProp);\n const headingId = useId();\n const logRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const atBottomRef = useRef(true);\n const seenRef = useRef<Seen | null>(null);\n const [atBottom, setAtBottom] = useState(true);\n const [unseen, setUnseen] = useState(0);\n const [loadBusy, runLoad] = useAcknowledgedAction(onActionError);\n\n const onAtBottomChangeRef = useRef(onAtBottomChange);\n onAtBottomChangeRef.current = onAtBottomChange;\n\n const measure = useCallback(\n (el: HTMLElement) => el.scrollHeight - el.scrollTop - el.clientHeight <= bottomThreshold,\n [bottomThreshold],\n );\n\n const commitAtBottom = useCallback((value: boolean) => {\n const changed = atBottomRef.current !== value;\n atBottomRef.current = value;\n setAtBottom(value);\n if (value) setUnseen(0);\n if (changed) onAtBottomChangeRef.current?.(value);\n }, []);\n\n const scrollLogToBottom = useCallback(() => {\n const el = logRef.current;\n if (!el) return;\n // The log's own scrollTop only. Never scrollIntoView: that scrolls every\n // scrollable ancestor too, up to the page.\n el.scrollTop = el.scrollHeight;\n }, []);\n\n // Follow, hold, or keep place, every time the messages change.\n useIsoLayoutEffect(() => {\n const el = logRef.current;\n if (!el) return;\n\n const ids = messages.map((m) => m.id);\n const first = ids[0];\n const last = ids[ids.length - 1];\n const prev = seenRef.current;\n\n if (!prev) {\n if (stickToBottom) scrollLogToBottom();\n } else {\n const prepended =\n prev.last !== undefined &&\n prev.last === last &&\n prev.first !== undefined &&\n prev.first !== first &&\n ids.includes(prev.first);\n\n if (prepended) {\n if (stickToBottom && atBottomRef.current) scrollLogToBottom();\n // From the position BEFORE the change, never the current one: the\n // browser's scroll anchoring (overflow-anchor) may already have moved\n // scrollTop by the inserted height, and adding it again overshoots.\n else el.scrollTop = prev.scrollTop + (el.scrollHeight - prev.scrollHeight);\n } else {\n const lastIndex = prev.last === undefined ? -1 : ids.indexOf(prev.last);\n const appended: ChatMessageData[] = [];\n for (let i = lastIndex + 1; i < messages.length; i++) {\n if (!prev.ids.has(messages[i].id)) appended.push(messages[i]);\n }\n\n if (stickToBottom && atBottomRef.current) {\n scrollLogToBottom();\n } else if (stickToBottom && appended.some((m) => isOwn(m, ownRoles))) {\n // The viewer's own send: show it, wherever they were reading.\n scrollLogToBottom();\n } else if (appended.length > 0) {\n setUnseen((n) => n + appended.length);\n }\n }\n }\n\n seenRef.current = { ids: new Set(ids), first, last, scrollHeight: el.scrollHeight, scrollTop: el.scrollTop };\n const nowAtBottom = measure(el);\n if (nowAtBottom !== atBottomRef.current || nowAtBottom) commitAtBottom(nowAtBottom);\n // ownRoles is compared by content inside; a new array each render must not re-run this.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages, stickToBottom, measure, commitAtBottom, scrollLogToBottom]);\n\n // Content that grows without a messages change (images, fonts, a\n // ContentRenderer extension resolving) keeps a reader at the bottom there.\n useEffect(() => {\n const content = contentRef.current;\n if (!content || !stickToBottom || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n if (atBottomRef.current) scrollLogToBottom();\n });\n ro.observe(content);\n return () => ro.disconnect();\n }, [stickToBottom, scrollLogToBottom]);\n\n const onScroll = useCallback(\n (e: UIEvent<HTMLDivElement>) => {\n onScrollProp?.(e);\n if (seenRef.current) seenRef.current.scrollTop = e.currentTarget.scrollTop;\n const now = measure(e.currentTarget);\n if (now !== atBottomRef.current || now) commitAtBottom(now);\n },\n [measure, commitAtBottom, onScrollProp],\n );\n\n const jumpToLatest = useCallback(() => {\n onActivity?.({ type: \"jump-to-latest\", unseen });\n scrollLogToBottom();\n commitAtBottom(true);\n // The jump control is about to unmount; keep focus in the conversation\n // without scrolling anything (genie#1290).\n logRef.current?.focus({ preventScroll: true });\n }, [onActivity, unseen, scrollLogToBottom, commitAtBottom]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToLatest() {\n scrollLogToBottom();\n const el = logRef.current;\n if (el) commitAtBottom(measure(el));\n },\n scrollToMessage(id: string) {\n const el = logRef.current;\n if (!el) return false;\n const target = [...el.querySelectorAll<HTMLElement>(\"[data-chat-message]\")].find(\n (n) => n.getAttribute(\"data-chat-message\") === id,\n );\n if (!target) return false;\n el.scrollTop = target.offsetTop;\n commitAtBottom(measure(el));\n return true;\n },\n get element() {\n return logRef.current;\n },\n }),\n [scrollLogToBottom, commitAtBottom, measure],\n );\n\n const showLoadEarlier = Boolean(onLoadEarlier) && (hasEarlier ?? true);\n const earlierBusy = loadingEarlier || loadBusy;\n const showJump = unseen > 0 && !atBottom;\n const groupWindow =\n groupConsecutive === true ? DEFAULT_GROUP_WINDOW_MS : typeof groupConsecutive === \"number\" ? groupConsecutive : 0;\n\n const items: ReactNode[] = [];\n let prevDay: string | undefined;\n messages.forEach((m, i) => {\n const date = toDate(m.createdAt);\n let separator: ReactNode = null;\n if (separators === \"day\" && date) {\n const key = dayKey(date);\n if (key !== prevDay) {\n separator = (\n <div\n data-chat-day-separator={key}\n className={cn(\"flex items-center gap-3 px-4 pt-4 text-xs\", TEXT_MUTED, classNames?.separator)}\n >\n <span aria-hidden=\"true\" className={cn(\"h-px flex-1 border-t\", BORDER)} />\n <span>{formatDay(date)}</span>\n <span aria-hidden=\"true\" className={cn(\"h-px flex-1 border-t\", BORDER)} />\n </div>\n );\n prevDay = key;\n }\n }\n const grouped = groupWindow > 0 && !separator && continuesGroup(messages[i - 1], m, groupWindow);\n\n items.push(\n <Fragment key={m.id}>\n {separator}\n <ChatMessage\n message={m}\n grouped={grouped}\n actions={renderActions?.(m)}\n ownRoles={ownRoles}\n streaming={streaming}\n contentOptions={contentOptions}\n labels={labelsProp}\n formatTime={formatTime}\n renderAttachment={renderAttachment}\n onProposalAccept={onProposalAccept}\n onProposalReject={onProposalReject}\n onActivity={onActivity}\n onActionError={onActionError}\n classNames={classNames}\n />\n </Fragment>,\n );\n });\n\n const H = `h${headingLevel}` as \"h2\";\n\n return (\n <div\n data-react-fancy-chat-thread=\"\"\n {...rest}\n className={cn(\"flex min-h-0 flex-col\", className, classNames?.root)}\n >\n {heading !== undefined && heading !== null && (\n <H\n id={headingId}\n data-react-fancy-chat-thread-heading=\"\"\n className={cn(\"shrink-0 px-4 py-3 text-sm font-semibold\", classNames?.heading)}\n >\n {heading}\n </H>\n )}\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={logRef}\n data-react-fancy-chat-thread-log=\"\"\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions\"\n aria-label={heading ? undefined : labels.log}\n aria-labelledby={heading ? headingId : undefined}\n tabIndex={0}\n onScroll={onScroll}\n className={cn(\n \"relative min-h-0 flex-1 overflow-y-auto overscroll-contain focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))]\",\n classNames?.log,\n )}\n >\n <div ref={contentRef} className=\"flex flex-col pb-3\">\n {showLoadEarlier && (\n <div className=\"flex justify-center pt-3\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n data-react-fancy-chat-thread-load-earlier=\"\"\n disabled={earlierBusy}\n aria-busy={earlierBusy || undefined}\n onClick={() =>\n runLoad(() => {\n onActivity?.({ type: \"load-earlier\" });\n return onLoadEarlier!();\n }, { type: \"load-earlier\" })\n }\n >\n {earlierBusy ? labels.loadingEarlier : labels.loadEarlier}\n </Button>\n </div>\n )}\n {messages.length === 0 && empty !== undefined && (\n <div data-react-fancy-chat-thread-empty=\"\" className={cn(\"px-4 py-8 text-center text-sm\", TEXT_MUTED)}>\n {empty}\n </div>\n )}\n {items}\n </div>\n </div>\n {showJump && (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-3 flex justify-center\">\n <Button\n type=\"button\"\n size=\"sm\"\n data-react-fancy-chat-thread-jump=\"\"\n data-unseen={unseen}\n iconTrailing=\"chevron-down\"\n className={cn(\"pointer-events-auto shadow-md\", classNames?.jump)}\n onClick={jumpToLatest}\n >\n {labels.newMessages(unseen)}\n </Button>\n </div>\n )}\n </div>\n {composer !== undefined && composer !== null && (\n <div data-react-fancy-chat-thread-composer=\"\" className={cn(\"shrink-0\", classNames?.composer)}>\n {composer}\n </div>\n )}\n </div>\n );\n}\n\nChatThread.displayName = \"ChatThread\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ChatThread/chat-utils.ts","../src/components/ChatThread/ChatMessage.tsx","../src/components/ChatThread/ChatThread.tsx"],"names":["TEXT_MUTED","BORDER","useEffect","useRef","useState","useCallback","jsxs","jsx","Fragment"],"mappings":"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","file":"chunk-23KQF47X.js","sourcesContent":["import type { ChatMessageData, ChatThreadLabels } from \"./ChatThread.types\";\n\nexport const DEFAULT_LABELS: ChatThreadLabels = {\n log: \"Conversation\",\n loadEarlier: \"Load earlier messages\",\n loadingEarlier: \"Loading earlier messages...\",\n newMessages: (n) => (n === 1 ? \"1 new message\" : `${n} new messages`),\n internal: \"Internal note\",\n pending: \"Sending...\",\n failed: \"Not sent\",\n proposal: \"Proposed\",\n accept: \"Accept\",\n reject: \"Reject\",\n accepted: \"Accepted\",\n rejected: \"Rejected\",\n withdrawn: \"Withdrawn\",\n attachments: \"Attachments\",\n roles: {\n user: \"You\",\n assistant: \"Assistant\",\n system: \"System\",\n agent: \"Agent\",\n staff: \"Staff\",\n customer: \"Customer\",\n },\n};\n\nexport function mergeLabels(labels?: Partial<ChatThreadLabels>): ChatThreadLabels {\n if (!labels) return DEFAULT_LABELS;\n return {\n ...DEFAULT_LABELS,\n ...labels,\n roles: { ...DEFAULT_LABELS.roles, ...labels.roles },\n };\n}\n\n/** `null` for a missing or unparseable time: no time renders rather than \"Invalid Date\". */\nexport function toDate(value: string | number | undefined): Date | null {\n if (value === undefined || value === null || value === \"\") return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n/** Local calendar day, `YYYY-MM-DD`. */\nexport function dayKey(d: Date): string {\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\nexport function defaultFormatTime(d: Date): string {\n return d.toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function defaultFormatDay(d: Date): string {\n return d.toLocaleDateString(undefined, { dateStyle: \"medium\" });\n}\n\nexport function roleLabel(role: string, labels: ChatThreadLabels): string {\n const known = labels.roles[role];\n if (known) return known;\n return role ? role.charAt(0).toUpperCase() + role.slice(1) : \"\";\n}\n\nexport function initials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n const first = parts[0][0] ?? \"\";\n const last = parts.length > 1 ? (parts[parts.length - 1][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n}\n\nexport function isOwn(message: ChatMessageData, ownRoles: string[]): boolean {\n return message.own ?? ownRoles.includes(message.role);\n}\n\nexport const DEFAULT_GROUP_WINDOW_MS = 5 * 60 * 1000;\n\n/** Does `curr` continue `prev`'s group? Same role, same author, same visibility, within the window. */\nexport function continuesGroup(\n prev: ChatMessageData | undefined,\n curr: ChatMessageData,\n windowMs: number,\n): boolean {\n if (!prev) return false;\n if (prev.role !== curr.role) return false;\n if ((prev.author?.name ?? \"\") !== (curr.author?.name ?? \"\")) return false;\n if ((prev.visibility ?? \"public\") !== (curr.visibility ?? \"public\")) return false;\n if (prev.proposal || curr.proposal) return false;\n if (curr.role === \"system\") return false;\n const a = toDate(prev.createdAt);\n const b = toDate(curr.createdAt);\n if (!a || !b) return false;\n const gap = b.getTime() - a.getTime();\n return gap >= 0 && gap <= windowMs;\n}\n\nexport function formatBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { sanitizeComponentHref } from \"../../utils/sanitize\";\nimport { Avatar } from \"../Avatar\";\nimport { Badge } from \"../Badge\";\nimport { Button } from \"../Button\";\nimport { ContentRenderer } from \"../ContentRenderer\";\nimport type {\n ChatAction,\n ChatAttachment,\n ChatMessageData,\n ChatMessageProps,\n ChatThreadActionContext,\n ChatThreadLabels,\n} from \"./ChatThread.types\";\nimport {\n defaultFormatTime,\n formatBytes,\n initials,\n isOwn,\n mergeLabels,\n roleLabel,\n toDate,\n} from \"./chat-utils\";\n\nconst BORDER =\n \"border-[color:var(--fancy-border,var(--color-zinc-200))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\";\nconst SURFACE =\n \"bg-[color:var(--fancy-surface,var(--color-white))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\";\nconst SURFACE_MUTED =\n \"bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]\";\nconst TEXT =\n \"text-[color:var(--fancy-text,var(--color-zinc-900))] dark:text-[color:var(--fancy-text-dark,var(--color-zinc-100))]\";\nconst TEXT_MUTED =\n \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\";\n\n/**\n * Run a host callback that may return a Promise. While it is pending the\n * control is busy and a second run is refused. A rejection goes to\n * `onActionError`, or is left unhandled so it still reaches the console.\n *\n * @internal shared by ChatMessage (proposal decisions) and ChatThread (load earlier)\n */\nexport function useAcknowledgedAction(\n onActionError?: (error: unknown, action: ChatThreadActionContext) => void,\n): [busy: boolean, run: (fn: () => ReturnType<ChatAction>, ctx: ChatThreadActionContext) => void] {\n const [busy, setBusy] = useState(false);\n const busyRef = useRef(false);\n const mounted = useRef(true);\n const onErrorRef = useRef(onActionError);\n onErrorRef.current = onActionError;\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n\n const run = useCallback((fn: () => ReturnType<ChatAction>, ctx: ChatThreadActionContext) => {\n if (busyRef.current) return;\n const result = fn();\n if (!result || typeof (result as Promise<unknown>).then !== \"function\") return;\n\n busyRef.current = true;\n setBusy(true);\n const settle = () => {\n busyRef.current = false;\n if (mounted.current) setBusy(false);\n };\n void Promise.resolve(result).then(settle, (error: unknown) => {\n settle();\n const onError = onErrorRef.current;\n if (onError) onError(error, ctx);\n else throw error;\n });\n }, []);\n\n return [busy, run];\n}\n\nfunction AttachmentItem({\n attachment,\n message,\n renderAttachment,\n}: {\n attachment: ChatAttachment;\n message: ChatMessageData;\n renderAttachment?: ChatMessageProps[\"renderAttachment\"];\n}) {\n let body: ReactNode;\n if (renderAttachment) {\n body = renderAttachment(attachment, message);\n } else {\n const href = sanitizeComponentHref(\"ChatMessage\", attachment.url);\n const size = typeof attachment.size === \"number\" ? (\n <span className={cn(\"ml-1\", TEXT_MUTED)}>({formatBytes(attachment.size)})</span>\n ) : null;\n body = href ? (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"underline underline-offset-2 break-all\">\n {attachment.name}\n {size}\n </a>\n ) : (\n <span className=\"break-all\">\n {attachment.name}\n {size}\n </span>\n );\n }\n\n return (\n <li data-chat-attachment={attachment.id} className=\"text-sm\">\n {body}\n </li>\n );\n}\n\nfunction ProposalFooter({\n message,\n labels,\n busy,\n onAccept,\n onReject,\n}: {\n message: ChatMessageData;\n labels: ChatThreadLabels;\n busy: boolean;\n onAccept?: () => void;\n onReject?: () => void;\n}) {\n const proposal = message.proposal!;\n const state = proposal.state ?? \"pending\";\n\n if (state !== \"pending\") {\n const text = state === \"accepted\" ? labels.accepted : state === \"rejected\" ? labels.rejected : labels.withdrawn;\n const color = state === \"accepted\" ? \"emerald\" : state === \"rejected\" ? \"red\" : \"zinc\";\n return (\n <div className=\"mt-2\">\n <Badge color={color} variant=\"soft\" size=\"sm\" data-chat-proposal-status={state}>\n {text}\n </Badge>\n </div>\n );\n }\n\n if (!onAccept && !onReject) return null;\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n {onAccept && (\n <Button\n type=\"button\"\n size=\"sm\"\n color=\"emerald\"\n disabled={busy}\n aria-busy={busy || undefined}\n data-chat-proposal-action=\"accept\"\n onClick={onAccept}\n >\n {proposal.acceptLabel ?? labels.accept}\n </Button>\n )}\n {onReject && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n disabled={busy}\n aria-busy={busy || undefined}\n data-chat-proposal-action=\"reject\"\n onClick={onReject}\n >\n {proposal.rejectLabel ?? labels.reject}\n </Button>\n )}\n </div>\n );\n}\n\n/**\n * ChatMessage — one message of a `ChatThread`, usable on its own.\n *\n * Content is markdown through `ContentRenderer`, always sanitised (there is no\n * `unsafe` here on purpose: message bodies are text the host did not author).\n * `format: \"text\"` renders it literally. A message with a `proposal` is an\n * approval card: the host owns its state and decides it through\n * `onProposalAccept` / `onProposalReject`; the card never acts on its own.\n */\nexport function ChatMessage({\n message,\n actions,\n grouped = false,\n className,\n ownRoles = [\"user\"],\n streaming = true,\n contentOptions,\n labels: labelsProp,\n formatTime = defaultFormatTime,\n renderAttachment,\n onProposalAccept,\n onProposalReject,\n onActivity,\n onActionError,\n classNames,\n}: ChatMessageProps) {\n const labels = mergeLabels(labelsProp);\n const [busy, run] = useAcknowledgedAction(onActionError);\n\n const status = message.status ?? \"sent\";\n const visibility = message.visibility ?? \"public\";\n const internal = visibility === \"internal\";\n const own = isOwn(message, ownRoles);\n const system = message.role === \"system\";\n const proposal = message.proposal;\n const date = toDate(message.createdAt);\n // Always a name: the author's, else the role's (\"Assistant\", or the host's own role capitalised).\n const name = message.author?.name || roleLabel(message.role, labels);\n\n const decide = (kind: \"accept\" | \"reject\") => {\n if (!proposal) return;\n const cb = kind === \"accept\" ? onProposalAccept : onProposalReject;\n if (!cb) return;\n const ctx: ChatThreadActionContext = {\n type: kind === \"accept\" ? \"proposal-accept\" : \"proposal-reject\",\n messageId: message.id,\n proposalId: proposal.id,\n };\n run(() => {\n onActivity?.(ctx);\n return cb(message);\n }, ctx);\n };\n\n const body =\n message.format === \"text\" ? (\n <div data-chat-content=\"\" className=\"whitespace-pre-wrap break-words\">\n {message.content}\n </div>\n ) : (\n <div data-chat-content=\"\" className=\"min-w-0 break-words\">\n <ContentRenderer\n {...contentOptions}\n value={message.content}\n format=\"markdown\"\n streaming={status === \"streaming\" ? streaming : false}\n />\n </div>\n );\n\n const attachments =\n message.attachments && message.attachments.length > 0 ? (\n <ul data-chat-attachments=\"\" aria-label={labels.attachments} className=\"mt-2 flex flex-col gap-1\">\n {message.attachments.map((a) => (\n <AttachmentItem key={a.id} attachment={a} message={message} renderAttachment={renderAttachment} />\n ))}\n </ul>\n ) : null;\n\n const statusText =\n status === \"pending\" ? (\n <div data-chat-status-text=\"pending\" className={cn(\"mt-1 text-xs\", TEXT_MUTED)}>\n {labels.pending}\n </div>\n ) : status === \"failed\" ? (\n <div data-chat-status-text=\"failed\" className=\"mt-1 text-xs text-red-600 dark:text-red-400\">\n {labels.failed}\n </div>\n ) : null;\n\n const actionsSlot =\n actions !== undefined && actions !== null && actions !== false ? (\n <div data-chat-message-actions=\"\" className={cn(\"mt-1 flex flex-wrap items-center gap-1\", classNames?.actions)}>\n {actions}\n </div>\n ) : null;\n\n const rootAttrs = {\n \"data-chat-message\": message.id,\n \"data-chat-role\": message.role,\n \"data-chat-status\": status,\n \"data-chat-visibility\": visibility,\n \"data-chat-own\": own ? \"\" : undefined,\n \"data-chat-grouped\": grouped ? \"\" : undefined,\n \"aria-busy\": status === \"streaming\" ? true : undefined,\n };\n\n if (system && !proposal) {\n return (\n <article\n {...rootAttrs}\n className={cn(\"flex flex-col items-center px-4 py-1 text-center text-xs\", TEXT_MUTED, className, classNames?.message)}\n >\n {internal && (\n <Badge color=\"amber\" variant=\"soft\" size=\"sm\" data-chat-internal-label=\"\">\n {labels.internal}\n </Badge>\n )}\n <div className={cn(\"max-w-prose\", classNames?.bubble)}>{body}</div>\n {attachments}\n {actionsSlot}\n </article>\n );\n }\n\n const bubbleClass = cn(\n \"rounded-2xl px-3.5 py-2.5 text-sm\",\n TEXT,\n internal\n ? \"border border-dashed border-amber-400 bg-amber-50 dark:border-amber-500/60 dark:bg-amber-950/30\"\n : proposal\n ? cn(\"border-2 border-violet-300 dark:border-violet-500/60\", SURFACE)\n : own\n ? cn(\"border\", BORDER, SURFACE)\n : SURFACE_MUTED,\n status === \"failed\" && \"ring-1 ring-red-400/70\",\n classNames?.bubble,\n proposal && classNames?.proposal,\n );\n\n const bubbleInner = (\n <>\n {internal && (\n <div className=\"mb-1.5\">\n <Badge color=\"amber\" variant=\"soft\" size=\"sm\" data-chat-internal-label=\"\">\n {labels.internal}\n </Badge>\n </div>\n )}\n {proposal && (\n <div data-chat-proposal-header=\"\" className=\"mb-1.5 flex flex-wrap items-center gap-2\">\n <Badge color=\"violet\" variant=\"soft\" size=\"sm\">\n {labels.proposal}\n </Badge>\n {proposal.title && <span className=\"font-medium\">{proposal.title}</span>}\n </div>\n )}\n {body}\n {attachments}\n {proposal && (\n <ProposalFooter\n message={message}\n labels={labels}\n busy={busy}\n onAccept={onProposalAccept ? () => decide(\"accept\") : undefined}\n onReject={onProposalReject ? () => decide(\"reject\") : undefined}\n />\n )}\n </>\n );\n\n return (\n <article\n {...rootAttrs}\n className={cn(\n \"flex gap-2.5 px-3\",\n grouped ? \"pt-0.5\" : \"pt-3\",\n own && \"flex-row-reverse\",\n className,\n classNames?.message,\n )}\n >\n <div className=\"w-8 shrink-0\" aria-hidden={grouped || undefined}>\n {!grouped && (\n <Avatar size=\"sm\" src={message.author?.avatar} alt=\"\" fallback={initials(name)} />\n )}\n </div>\n <div className={cn(\"flex min-w-0 max-w-[85%] flex-col\", own ? \"items-end\" : \"items-start\")}>\n {!grouped && (\n <div\n data-chat-header=\"\"\n className={cn(\"mb-1 flex items-baseline gap-2 text-xs\", own && \"flex-row-reverse\", classNames?.header)}\n >\n <span data-chat-author=\"\" className={cn(\"font-medium\", TEXT)}>\n {name}\n </span>\n {date && (\n <time dateTime={date.toISOString()} className={TEXT_MUTED}>\n {formatTime(date)}\n </time>\n )}\n </div>\n )}\n {proposal ? (\n <div\n data-chat-proposal={proposal.id}\n data-chat-proposal-state={proposal.state ?? \"pending\"}\n aria-busy={busy || undefined}\n className={cn(\"min-w-0 max-w-full\", bubbleClass)}\n >\n {bubbleInner}\n </div>\n ) : (\n <div data-chat-bubble=\"\" className={cn(\"min-w-0 max-w-full\", bubbleClass)}>\n {bubbleInner}\n </div>\n )}\n {statusText}\n {actionsSlot}\n </div>\n </article>\n );\n}\n\nChatMessage.displayName = \"ChatMessage\";\n","import {\n Fragment,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type UIEvent,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button\";\nimport { ChatMessage, useAcknowledgedAction } from \"./ChatMessage\";\nimport type { ChatMessageData, ChatThreadProps } from \"./ChatThread.types\";\nimport {\n DEFAULT_GROUP_WINDOW_MS,\n continuesGroup,\n dayKey,\n defaultFormatDay,\n isOwn,\n mergeLabels,\n toDate,\n} from \"./chat-utils\";\n\nconst TEXT_MUTED =\n \"text-[color:var(--fancy-text-muted,var(--color-zinc-500))] dark:text-[color:var(--fancy-text-muted-dark,var(--color-zinc-400))]\";\nconst BORDER =\n \"border-[color:var(--fancy-border,var(--color-zinc-200))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))]\";\n\n// The isomorphic layout effect: scroll work must happen before paint in the\n// browser, and must not warn during SSR.\nconst useIsoLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\ninterface Seen {\n ids: Set<string>;\n first?: string;\n last?: string;\n scrollHeight: number;\n /** The reader's position as of the last render or scroll event, before any browser adjustment. */\n scrollTop: number;\n}\n\n/**\n * ChatThread — a controlled message list for agent and support conversations.\n *\n * - **Controlled.** It renders exactly `messages`, oldest first. Loading\n * earlier history and deciding a proposal go through callbacks; nothing is\n * held internally that an agent would need to read or write.\n * - **Stick to the bottom without yanking.** New messages are followed only\n * while the reader is at the bottom. A reader who scrolled up stays put and\n * gets an \"N new messages\" jump control. Prepended history keeps the\n * reader's place. Only the log's own `scrollTop` is ever set, and focus moves\n * with `preventScroll`, so no ancestor (or the page) scrolls (the 5.69 rule).\n * - **Visibility is the host's.** `visibility: \"internal\"` is labelled and\n * styled, never filtered: pass only what the viewer may see.\n * - **Handles:** `data-react-fancy-chat-thread`, `data-chat-message=\"<id>\"`,\n * `data-chat-role`, `data-chat-status`, `data-chat-visibility`,\n * `data-chat-proposal=\"<id>\"`, `data-chat-proposal-action`.\n * - **Observable:** `onActivity` reports every interaction as one stream.\n *\n * Pair it with `Composer` or `PromptInput` in the `composer` slot (both have\n * acknowledged send). It does not ship an input of its own.\n */\nexport function ChatThread({\n ref,\n messages,\n heading,\n headingLevel = 2,\n onLoadEarlier,\n hasEarlier,\n loadingEarlier = false,\n stickToBottom = true,\n bottomThreshold = 48,\n onAtBottomChange,\n separators = \"none\",\n formatDay = defaultFormatDay,\n groupConsecutive = false,\n renderActions,\n composer,\n empty,\n classNames,\n className,\n // message display\n ownRoles = [\"user\"],\n streaming = true,\n contentOptions,\n labels: labelsProp,\n formatTime,\n renderAttachment,\n onProposalAccept,\n onProposalReject,\n onActivity,\n onActionError,\n onScroll: onScrollProp,\n ...rest\n}: ChatThreadProps) {\n const labels = mergeLabels(labelsProp);\n const headingId = useId();\n const logRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const atBottomRef = useRef(true);\n const seenRef = useRef<Seen | null>(null);\n const [atBottom, setAtBottom] = useState(true);\n const [unseen, setUnseen] = useState(0);\n const [loadBusy, runLoad] = useAcknowledgedAction(onActionError);\n\n const onAtBottomChangeRef = useRef(onAtBottomChange);\n onAtBottomChangeRef.current = onAtBottomChange;\n\n const measure = useCallback(\n (el: HTMLElement) => el.scrollHeight - el.scrollTop - el.clientHeight <= bottomThreshold,\n [bottomThreshold],\n );\n\n const commitAtBottom = useCallback((value: boolean) => {\n const changed = atBottomRef.current !== value;\n atBottomRef.current = value;\n setAtBottom(value);\n if (value) setUnseen(0);\n if (changed) onAtBottomChangeRef.current?.(value);\n }, []);\n\n const scrollLogToBottom = useCallback(() => {\n const el = logRef.current;\n if (!el) return;\n // The log's own scrollTop only. Never scrollIntoView: that scrolls every\n // scrollable ancestor too, up to the page.\n el.scrollTop = el.scrollHeight;\n }, []);\n\n // Follow, hold, or keep place, every time the messages change.\n useIsoLayoutEffect(() => {\n const el = logRef.current;\n if (!el) return;\n\n const ids = messages.map((m) => m.id);\n const first = ids[0];\n const last = ids[ids.length - 1];\n const prev = seenRef.current;\n\n if (!prev) {\n if (stickToBottom) scrollLogToBottom();\n } else {\n const prepended =\n prev.last !== undefined &&\n prev.last === last &&\n prev.first !== undefined &&\n prev.first !== first &&\n ids.includes(prev.first);\n\n if (prepended) {\n if (stickToBottom && atBottomRef.current) scrollLogToBottom();\n // From the position BEFORE the change, never the current one: the\n // browser's scroll anchoring (overflow-anchor) may already have moved\n // scrollTop by the inserted height, and adding it again overshoots.\n else el.scrollTop = prev.scrollTop + (el.scrollHeight - prev.scrollHeight);\n } else {\n const lastIndex = prev.last === undefined ? -1 : ids.indexOf(prev.last);\n const appended: ChatMessageData[] = [];\n for (let i = lastIndex + 1; i < messages.length; i++) {\n if (!prev.ids.has(messages[i].id)) appended.push(messages[i]);\n }\n\n if (stickToBottom && atBottomRef.current) {\n scrollLogToBottom();\n } else if (stickToBottom && appended.some((m) => isOwn(m, ownRoles))) {\n // The viewer's own send: show it, wherever they were reading.\n scrollLogToBottom();\n } else if (appended.length > 0) {\n setUnseen((n) => n + appended.length);\n }\n }\n }\n\n seenRef.current = { ids: new Set(ids), first, last, scrollHeight: el.scrollHeight, scrollTop: el.scrollTop };\n const nowAtBottom = measure(el);\n if (nowAtBottom !== atBottomRef.current || nowAtBottom) commitAtBottom(nowAtBottom);\n // ownRoles is compared by content inside; a new array each render must not re-run this.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages, stickToBottom, measure, commitAtBottom, scrollLogToBottom]);\n\n // Content that grows without a messages change (images, fonts, a\n // ContentRenderer extension resolving) keeps a reader at the bottom there.\n useEffect(() => {\n const content = contentRef.current;\n if (!content || !stickToBottom || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => {\n if (atBottomRef.current) scrollLogToBottom();\n });\n ro.observe(content);\n return () => ro.disconnect();\n }, [stickToBottom, scrollLogToBottom]);\n\n const onScroll = useCallback(\n (e: UIEvent<HTMLDivElement>) => {\n onScrollProp?.(e);\n if (seenRef.current) seenRef.current.scrollTop = e.currentTarget.scrollTop;\n const now = measure(e.currentTarget);\n if (now !== atBottomRef.current || now) commitAtBottom(now);\n },\n [measure, commitAtBottom, onScrollProp],\n );\n\n const jumpToLatest = useCallback(() => {\n onActivity?.({ type: \"jump-to-latest\", unseen });\n scrollLogToBottom();\n commitAtBottom(true);\n // The jump control is about to unmount; keep focus in the conversation\n // without scrolling anything (genie#1290).\n logRef.current?.focus({ preventScroll: true });\n }, [onActivity, unseen, scrollLogToBottom, commitAtBottom]);\n\n useImperativeHandle(\n ref,\n () => ({\n scrollToLatest() {\n scrollLogToBottom();\n const el = logRef.current;\n if (el) commitAtBottom(measure(el));\n },\n scrollToMessage(id: string) {\n const el = logRef.current;\n if (!el) return false;\n const target = [...el.querySelectorAll<HTMLElement>(\"[data-chat-message]\")].find(\n (n) => n.getAttribute(\"data-chat-message\") === id,\n );\n if (!target) return false;\n el.scrollTop = target.offsetTop;\n commitAtBottom(measure(el));\n return true;\n },\n get element() {\n return logRef.current;\n },\n }),\n [scrollLogToBottom, commitAtBottom, measure],\n );\n\n const showLoadEarlier = Boolean(onLoadEarlier) && (hasEarlier ?? true);\n const earlierBusy = loadingEarlier || loadBusy;\n const showJump = unseen > 0 && !atBottom;\n const groupWindow =\n groupConsecutive === true ? DEFAULT_GROUP_WINDOW_MS : typeof groupConsecutive === \"number\" ? groupConsecutive : 0;\n\n const items: ReactNode[] = [];\n let prevDay: string | undefined;\n messages.forEach((m, i) => {\n const date = toDate(m.createdAt);\n let separator: ReactNode = null;\n if (separators === \"day\" && date) {\n const key = dayKey(date);\n if (key !== prevDay) {\n separator = (\n <div\n data-chat-day-separator={key}\n className={cn(\"flex items-center gap-3 px-4 pt-4 text-xs\", TEXT_MUTED, classNames?.separator)}\n >\n <span aria-hidden=\"true\" className={cn(\"h-px flex-1 border-t\", BORDER)} />\n <span>{formatDay(date)}</span>\n <span aria-hidden=\"true\" className={cn(\"h-px flex-1 border-t\", BORDER)} />\n </div>\n );\n prevDay = key;\n }\n }\n const grouped = groupWindow > 0 && !separator && continuesGroup(messages[i - 1], m, groupWindow);\n\n items.push(\n <Fragment key={m.id}>\n {separator}\n <ChatMessage\n message={m}\n grouped={grouped}\n actions={renderActions?.(m)}\n ownRoles={ownRoles}\n streaming={streaming}\n contentOptions={contentOptions}\n labels={labelsProp}\n formatTime={formatTime}\n renderAttachment={renderAttachment}\n onProposalAccept={onProposalAccept}\n onProposalReject={onProposalReject}\n onActivity={onActivity}\n onActionError={onActionError}\n classNames={classNames}\n />\n </Fragment>,\n );\n });\n\n const H = `h${headingLevel}` as \"h2\";\n\n return (\n <div\n data-react-fancy-chat-thread=\"\"\n {...rest}\n className={cn(\"flex min-h-0 flex-col\", className, classNames?.root)}\n >\n {heading !== undefined && heading !== null && (\n <H\n id={headingId}\n data-react-fancy-chat-thread-heading=\"\"\n className={cn(\"shrink-0 px-4 py-3 text-sm font-semibold\", classNames?.heading)}\n >\n {heading}\n </H>\n )}\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n ref={logRef}\n data-react-fancy-chat-thread-log=\"\"\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions\"\n aria-label={heading ? undefined : labels.log}\n aria-labelledby={heading ? headingId : undefined}\n tabIndex={0}\n onScroll={onScroll}\n className={cn(\n \"relative min-h-0 flex-1 overflow-y-auto overscroll-contain focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))]\",\n classNames?.log,\n )}\n >\n <div ref={contentRef} className=\"flex flex-col pb-3\">\n {showLoadEarlier && (\n <div className=\"flex justify-center pt-3\">\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n data-react-fancy-chat-thread-load-earlier=\"\"\n disabled={earlierBusy}\n aria-busy={earlierBusy || undefined}\n onClick={() =>\n runLoad(() => {\n onActivity?.({ type: \"load-earlier\" });\n return onLoadEarlier!();\n }, { type: \"load-earlier\" })\n }\n >\n {earlierBusy ? labels.loadingEarlier : labels.loadEarlier}\n </Button>\n </div>\n )}\n {messages.length === 0 && empty !== undefined && (\n <div data-react-fancy-chat-thread-empty=\"\" className={cn(\"px-4 py-8 text-center text-sm\", TEXT_MUTED)}>\n {empty}\n </div>\n )}\n {items}\n </div>\n </div>\n {showJump && (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-3 flex justify-center\">\n <Button\n type=\"button\"\n size=\"sm\"\n data-react-fancy-chat-thread-jump=\"\"\n data-unseen={unseen}\n iconTrailing=\"chevron-down\"\n className={cn(\"pointer-events-auto shadow-md\", classNames?.jump)}\n onClick={jumpToLatest}\n >\n {labels.newMessages(unseen)}\n </Button>\n </div>\n )}\n </div>\n {composer !== undefined && composer !== null && (\n <div data-react-fancy-chat-thread-composer=\"\" className={cn(\"shrink-0\", classNames?.composer)}>\n {composer}\n </div>\n )}\n </div>\n );\n}\n\nChatThread.displayName = \"ChatThread\";\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { visuallyHidden } from './chunk-I3LAFKJU.js';
|
|
2
|
-
import { sanitizeHtml, sanitizeHref, Button } from './chunk-
|
|
2
|
+
import { sanitizeHtml, sanitizeHref, Button } from './chunk-4GPH7HOR.js';
|
|
3
3
|
import { cn } from './chunk-MMW2JGKZ.js';
|
|
4
4
|
import { marked } from 'marked';
|
|
5
5
|
import { createContext, useMemo, useRef, useState, useCallback, useContext, useLayoutEffect, useEffect } from 'react';
|
|
@@ -1400,5 +1400,5 @@ function ContentRenderer({
|
|
|
1400
1400
|
ContentRenderer.displayName = "ContentRenderer";
|
|
1401
1401
|
|
|
1402
1402
|
export { ContentRenderer, detectFormat, extensionEditorClasses, htmlToMarkdown, markdownToEditorHtml, mergeExtensions, proseClasses, registerExtension, registerExtensions, renderMarkdown };
|
|
1403
|
-
//# sourceMappingURL=chunk-
|
|
1404
|
-
//# sourceMappingURL=chunk-
|
|
1403
|
+
//# sourceMappingURL=chunk-3AA2KGZG.js.map
|
|
1404
|
+
//# sourceMappingURL=chunk-3AA2KGZG.js.map
|