@icen.ai/ui 0.9.0 → 0.10.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/AGENTS.md +138 -80
- package/README.md +66 -91
- package/dist/base.css +208 -179
- package/dist/behaviors/accordion.mjs +8 -8
- package/dist/behaviors/ai-branch.d.mts +1 -1
- package/dist/behaviors/ai-branch.mjs +1010 -94
- package/dist/behaviors/ai-chat.d.mts +7 -7
- package/dist/behaviors/ai-chat.mjs +1071 -161
- package/dist/behaviors/ai-composer.d.mts +44 -12
- package/dist/behaviors/ai-composer.mjs +1997 -524
- package/dist/behaviors/ai-core.d.mts +1 -1
- package/dist/behaviors/ai-core.mjs +1016 -107
- package/dist/behaviors/ai-diff.mjs +1019 -127
- package/dist/behaviors/ai-feedback.d.mts +1 -1
- package/dist/behaviors/ai-feedback.mjs +1035 -126
- package/dist/behaviors/ai-panel.d.mts +8 -8
- package/dist/behaviors/ai-panel.mjs +1284 -266
- package/dist/behaviors/ai-provider.mjs +1003 -101
- package/dist/behaviors/ai-threads.d.mts +1 -1
- package/dist/behaviors/ai-threads.mjs +1068 -154
- package/dist/behaviors/ai-tool.d.mts +2 -2
- package/dist/behaviors/ai-tool.mjs +2037 -396
- package/dist/behaviors/ai-tools.d.mts +89 -16
- package/dist/behaviors/ai-tools.mjs +4448 -372
- package/dist/behaviors/autocomplete.d.mts +53 -0
- package/dist/behaviors/autocomplete.mjs +1600 -0
- package/dist/behaviors/back-top.d.mts +1 -1
- package/dist/behaviors/back-top.mjs +951 -14
- package/dist/behaviors/carousel.d.mts +1 -1
- package/dist/behaviors/carousel.mjs +906 -11
- package/dist/behaviors/cascader.d.mts +48 -0
- package/dist/behaviors/cascader.mjs +1853 -0
- package/dist/behaviors/charts.d.mts +72 -8
- package/dist/behaviors/charts.mjs +1901 -256
- package/dist/behaviors/code-block.d.mts +36 -0
- package/dist/behaviors/code-block.mjs +1611 -0
- package/dist/behaviors/command-palette.d.mts +9 -6
- package/dist/behaviors/command-palette.mjs +161 -59
- package/dist/behaviors/context-menu.d.mts +9 -8
- package/dist/behaviors/context-menu.mjs +1112 -44
- package/dist/behaviors/controls.d.mts +13 -13
- package/dist/behaviors/controls.mjs +989 -130
- package/dist/behaviors/copy.d.mts +21 -2
- package/dist/behaviors/copy.mjs +1206 -42
- package/dist/behaviors/datatable.d.mts +53 -3
- package/dist/behaviors/datatable.mjs +1963 -207
- package/dist/behaviors/date-picker.d.mts +0 -1
- package/dist/behaviors/date-picker.mjs +1340 -293
- package/dist/behaviors/design.d.mts +54 -0
- package/dist/behaviors/design.mjs +109 -0
- package/dist/behaviors/dropdown.d.mts +5 -6
- package/dist/behaviors/dropdown.mjs +262 -110
- package/dist/behaviors/events.d.mts +120 -3
- package/dist/behaviors/events.mjs +47 -2
- package/dist/behaviors/feedback.d.mts +30 -0
- package/dist/behaviors/feedback.mjs +296 -0
- package/dist/behaviors/focus.d.mts +8 -0
- package/dist/behaviors/focus.mjs +24 -0
- package/dist/behaviors/form-validate.d.mts +102 -0
- package/dist/behaviors/form-validate.mjs +6091 -0
- package/dist/behaviors/i18n.d.mts +789 -0
- package/dist/behaviors/i18n.mjs +1711 -0
- package/dist/behaviors/icons.d.mts +93 -0
- package/dist/behaviors/icons.mjs +113 -0
- package/dist/behaviors/input.d.mts +9 -1
- package/dist/behaviors/input.mjs +1056 -60
- package/dist/behaviors/kb-access.d.mts +1 -1
- package/dist/behaviors/kb-access.mjs +2129 -239
- package/dist/behaviors/kb-acl.d.mts +6 -6
- package/dist/behaviors/kb-acl.mjs +1119 -179
- package/dist/behaviors/kb-answer.mjs +2070 -418
- package/dist/behaviors/kb-audit.d.mts +1 -1
- package/dist/behaviors/kb-audit.mjs +1076 -154
- package/dist/behaviors/kb-canvas.mjs +1100 -177
- package/dist/behaviors/kb-chain.mjs +1022 -100
- package/dist/behaviors/kb-checkpoint.d.mts +1 -1
- package/dist/behaviors/kb-checkpoint.mjs +1319 -169
- package/dist/behaviors/kb-chunks.mjs +1152 -213
- package/dist/behaviors/kb-citation.d.mts +1 -1
- package/dist/behaviors/kb-citation.mjs +1201 -179
- package/dist/behaviors/kb-clarify.mjs +1058 -130
- package/dist/behaviors/kb-conflict.mjs +1041 -119
- package/dist/behaviors/kb-connector.mjs +1104 -176
- package/dist/behaviors/kb-core.d.mts +6 -1
- package/dist/behaviors/kb-core.mjs +1077 -162
- package/dist/behaviors/kb-eval.mjs +1971 -144
- package/dist/behaviors/kb-explain.d.mts +1 -1
- package/dist/behaviors/kb-explain.mjs +1024 -102
- package/dist/behaviors/kb-filter.mjs +2008 -178
- package/dist/behaviors/kb-gap.d.mts +1 -1
- package/dist/behaviors/kb-gap.mjs +1043 -121
- package/dist/behaviors/kb-hittest.d.mts +1 -1
- package/dist/behaviors/kb-hittest.mjs +1093 -150
- package/dist/behaviors/kb-metadata.mjs +1052 -130
- package/dist/behaviors/kb-passage.d.mts +2 -2
- package/dist/behaviors/kb-passage.mjs +1101 -161
- package/dist/behaviors/kb-pipeline.d.mts +2 -2
- package/dist/behaviors/kb-pipeline.mjs +1082 -162
- package/dist/behaviors/kb-qa.mjs +1088 -160
- package/dist/behaviors/kb-rerank.mjs +1047 -114
- package/dist/behaviors/kb-retrieval.mjs +2063 -224
- package/dist/behaviors/kb-review.mjs +1990 -159
- package/dist/behaviors/kb-sandbox.d.mts +1 -1
- package/dist/behaviors/kb-sandbox.mjs +1026 -104
- package/dist/behaviors/kb-segment.mjs +1111 -179
- package/dist/behaviors/kb-select.d.mts +24 -0
- package/dist/behaviors/kb-select.mjs +1989 -0
- package/dist/behaviors/kb-sources.d.mts +1 -1
- package/dist/behaviors/kb-sources.mjs +1084 -170
- package/dist/behaviors/kb-sql.d.mts +1 -1
- package/dist/behaviors/kb-sql.mjs +1143 -226
- package/dist/behaviors/kb-trace.d.mts +1 -1
- package/dist/behaviors/kb-trace.mjs +1042 -128
- package/dist/behaviors/kb-visibility.mjs +1086 -158
- package/dist/behaviors/kb-who-can.mjs +1974 -137
- package/dist/behaviors/mentions.d.mts +93 -0
- package/dist/behaviors/mentions.mjs +2152 -0
- package/dist/behaviors/modal.d.mts +4 -3
- package/dist/behaviors/modal.mjs +1055 -33
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +6 -6
- package/dist/behaviors/notification.d.mts +16 -8
- package/dist/behaviors/notification.mjs +1615 -265
- package/dist/behaviors/panel.d.mts +4 -0
- package/dist/behaviors/panel.mjs +994 -0
- package/dist/behaviors/popover.d.mts +28 -5
- package/dist/behaviors/popover.mjs +225 -24
- package/dist/behaviors/select.d.mts +5 -2
- package/dist/behaviors/select.mjs +1410 -117
- package/dist/behaviors/sidebar.d.mts +1 -1
- package/dist/behaviors/sidebar.mjs +13 -13
- package/dist/behaviors/slider.d.mts +1 -1
- package/dist/behaviors/slider.mjs +9 -9
- package/dist/behaviors/split-pane.d.mts +1 -1
- package/dist/behaviors/split-pane.mjs +7 -7
- package/dist/behaviors/suggestions.d.mts +27 -0
- package/dist/behaviors/suggestions.mjs +1089 -0
- package/dist/behaviors/svg-parse.d.mts +14 -0
- package/dist/behaviors/svg-parse.mjs +37 -0
- package/dist/behaviors/tabs.d.mts +2 -2
- package/dist/behaviors/tabs.mjs +25 -25
- package/dist/behaviors/tag-input.d.mts +23 -5
- package/dist/behaviors/tag-input.mjs +1359 -104
- package/dist/behaviors/theme-switcher.d.mts +24 -0
- package/dist/behaviors/theme-switcher.mjs +1981 -0
- package/dist/behaviors/theme.d.mts +15 -8
- package/dist/behaviors/theme.mjs +390 -28
- package/dist/behaviors/toast.d.mts +24 -25
- package/dist/behaviors/toast.mjs +1266 -88
- package/dist/behaviors/tooltip.d.mts +4 -0
- package/dist/behaviors/tooltip.mjs +378 -0
- package/dist/behaviors/tree-select.d.mts +69 -0
- package/dist/behaviors/tree-select.mjs +1907 -0
- package/dist/behaviors/tree.d.mts +1 -1
- package/dist/behaviors/tree.mjs +15 -15
- package/dist/behaviors/upload.d.mts +3 -2
- package/dist/behaviors/upload.mjs +1076 -66
- package/dist/cli.mjs +5 -6
- package/dist/components/ai-chat.css +666 -573
- package/dist/components/ai-diff.css +153 -132
- package/dist/components/ai-panel.css +351 -343
- package/dist/components/ai-tool.css +393 -238
- package/dist/components/autocomplete.css +61 -0
- package/dist/components/autocomplete.mjs +3 -0
- package/dist/components/back-top.css +34 -31
- package/dist/components/badge.css +44 -41
- package/dist/components/breadcrumb.css +67 -46
- package/dist/components/btn.css +80 -74
- package/dist/components/card.css +117 -106
- package/dist/components/cascader.css +311 -0
- package/dist/components/cascader.mjs +3 -0
- package/dist/components/chart-area.css +8 -2
- package/dist/components/chart-bar.css +95 -33
- package/dist/components/chart-gauge.css +14 -11
- package/dist/components/chart-graph.css +20 -17
- package/dist/components/chart-heatmap.css +96 -90
- package/dist/components/chart-line.css +8 -3
- package/dist/components/chart-pie.css +9 -6
- package/dist/components/chart-radar.css +8 -5
- package/dist/components/chart-scatter.css +9 -6
- package/dist/components/chart-sparkline.css +5 -2
- package/dist/components/chart-stack.css +14 -11
- package/dist/components/charts.css +164 -73
- package/dist/components/code-block.css +418 -0
- package/dist/components/code-block.mjs +4 -0
- package/dist/components/command-palette.css +138 -117
- package/dist/components/content.css +257 -251
- package/dist/components/copy.css +72 -44
- package/dist/components/datatable.css +423 -181
- package/dist/components/date-picker.css +135 -104
- package/dist/components/empty.css +68 -65
- package/dist/components/feedback.css +201 -183
- package/dist/components/form-validate.css +120 -0
- package/dist/components/form-validate.mjs +3 -0
- package/dist/components/form.css +150 -127
- package/dist/components/icon.css +102 -0
- package/dist/components/icon.mjs +3 -0
- package/dist/components/input.css +159 -104
- package/dist/components/kb-agent.css +188 -173
- package/dist/components/kb-data.css +257 -253
- package/dist/components/kb-ground.css +197 -185
- package/dist/components/kb-ingest.css +334 -350
- package/dist/components/kb-ops.css +265 -259
- package/dist/components/kb-perm.css +260 -271
- package/dist/components/kb-search.css +317 -360
- package/dist/components/kb.css +120 -109
- package/dist/components/layout.css +85 -82
- package/dist/components/material-chinese.css +73 -0
- package/dist/components/material-soviet.css +76 -0
- package/dist/components/material.css +275 -0
- package/dist/components/media.css +220 -166
- package/dist/components/mentions.css +189 -0
- package/dist/components/mentions.mjs +3 -0
- package/dist/components/menu.css +113 -105
- package/dist/components/modal.css +107 -112
- package/dist/components/nav.css +118 -115
- package/dist/components/notification.css +238 -174
- package/dist/components/pagination.css +56 -53
- package/dist/components/panel.css +66 -63
- package/dist/components/panel.mjs +1 -0
- package/dist/components/pill.css +81 -71
- package/dist/components/popover.css +67 -53
- package/dist/components/scroll-area.css +113 -110
- package/dist/components/segmented.css +146 -143
- package/dist/components/select.css +206 -186
- package/dist/components/sidebar.css +137 -127
- package/dist/components/slider.css +117 -114
- package/dist/components/split-pane.css +112 -109
- package/dist/components/stat.css +112 -106
- package/dist/components/steps.css +109 -103
- package/dist/components/switch.css +138 -134
- package/dist/components/table.css +131 -107
- package/dist/components/tabs.css +114 -108
- package/dist/components/tag-input.css +48 -133
- package/dist/components/tag.css +81 -71
- package/dist/components/theme-switcher.css +105 -0
- package/dist/components/theme-switcher.mjs +3 -0
- package/dist/components/toast.css +100 -86
- package/dist/components/toolbar.css +45 -42
- package/dist/components/tooltip.css +102 -43
- package/dist/components/tooltip.mjs +1 -0
- package/dist/components/tree-select.css +416 -0
- package/dist/components/tree-select.mjs +3 -0
- package/dist/components/upload.css +135 -92
- package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
- package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
- package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/README.md +14 -0
- package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
- package/dist/index.d.mts +28 -14
- package/dist/index.mjs +20705 -9601
- package/dist/react.d.mts +91 -0
- package/dist/react.mjs +8208 -0
- package/dist/registry.json +130 -13
- package/dist/tokens/chinese.css +44 -0
- package/dist/tokens/colors.css +365 -1222
- package/dist/tokens/design.css +109 -0
- package/dist/tokens/dtcg.json +11198 -0
- package/dist/tokens/figma.variables.json +7017 -0
- package/dist/tokens/icon-masks.css +78 -0
- package/dist/tokens/pixel.css +50 -0
- package/dist/tokens/soviet.css +44 -0
- package/dist/tokens/style-profiles.css +36 -547
- package/dist/tokens/themes.json +308 -0
- package/dist/tokens/tokens-studio.json +6728 -0
- package/dist/tokens/typography.css +21 -18
- package/dist/tokens.css +1555 -1801
- package/dist/ui.css +11975 -9831
- package/dist/vue.d.mts +344 -0
- package/dist/vue.mjs +7781 -0
- package/docs/spec/ai-input-experience.md +75 -0
- package/docs/spec/ai-native.md +238 -147
- package/docs/spec/design-philosophy.md +189 -0
- package/docs/spec/design-primitives.md +196 -0
- package/docs/spec/kb-family.md +147 -115
- package/package.json +43 -8
- package/dist/retro-effects.css +0 -255
- package/dist/tokens/retro-effects.css +0 -255
- package/docs/research/2026-10-03-ai-kb-components.md +0 -392
- package/docs/research/2026-10-03-kb-permissions.md +0 -992
|
@@ -1,3 +1,989 @@
|
|
|
1
|
+
// src/behaviors/icons.ts
|
|
2
|
+
var ICON_PATHS = {
|
|
3
|
+
file: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16",
|
|
4
|
+
folder: "M3 5a1.5 1.5 0 0 1 1.5-1.5H8l2 2h5.5A1.5 1.5 0 0 1 17 7v8a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 3 15Z",
|
|
5
|
+
globe: "M17.5 10a7.5 7.5 0 1 1-15 0 7.5 7.5 0 0 1 15 0ZM2.5 10h15M10 2.5c-4 4-4 11 0 15 4-4 4-11 0-15Z",
|
|
6
|
+
document: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16M7 10.5h6M7 13.5h6",
|
|
7
|
+
agent: "M10 6V3M8 3h2M5 6h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2ZM1.5 10h1.5M17 10h1.5M7 10v2M13 10v2M8 14h4",
|
|
8
|
+
paperclip: "M14 7 8.3 12.7a1.6 1.6 0 0 1-2.3-2.3l6.3-6.3a3.2 3.2 0 0 1 4.5 4.5l-7 7a4.7 4.7 0 0 1-6.7-6.7l7-7",
|
|
9
|
+
stop: "M6.5 5h7A1.5 1.5 0 0 1 15 6.5v7a1.5 1.5 0 0 1-1.5 1.5h-7A1.5 1.5 0 0 1 5 13.5v-7A1.5 1.5 0 0 1 6.5 5Z",
|
|
10
|
+
terminal: "M5 3.5h10a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2ZM6 7l3 3-3 3M11 13h3",
|
|
11
|
+
branch: "M6 6v8M14 6v2a4 4 0 0 1-4 4H6M8 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM8 16a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM16 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z",
|
|
12
|
+
"line-numbers": "M3 5h2M3 10h2M3 15h2M8 5h9M8 10h9M8 15h9",
|
|
13
|
+
wrap: "M3 5h14M3 10h10a3 3 0 0 1 0 6h-3M12.5 13.5 10 16l2.5 2.5",
|
|
14
|
+
calendar: "M5.5 4h9A2.5 2.5 0 0 1 17 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 3 14.5v-8A2.5 2.5 0 0 1 5.5 4ZM6.5 2.5v3M13.5 2.5v3M3 8h14M6.5 11h.1M10 11h.1M13.5 11h.1M6.5 14h.1M10 14h.1",
|
|
15
|
+
close: "M6 6l8 8M14 6l-8 8",
|
|
16
|
+
check: "M4.5 10.2l3.6 3.6 7.4-7.6",
|
|
17
|
+
"chevron-down": "M5.5 7.75 10 12.25l4.5-4.5",
|
|
18
|
+
"chevron-up": "M5.5 12.25 10 7.75l4.5 4.5",
|
|
19
|
+
"chevron-right": "M7.75 5.5 12.25 10l-4.5 4.5",
|
|
20
|
+
"chevron-left": "M12.25 5.5 7.75 10l4.5 4.5",
|
|
21
|
+
"arrow-right": "M3.5 10h13M11 4.5l5.5 5.5-5.5 5.5",
|
|
22
|
+
"arrow-left": "M16.5 10h-13M9 4.5 3.5 10 9 15.5",
|
|
23
|
+
"arrow-up": "M10 16.5v-13M4.5 9 10 3.5 15.5 9",
|
|
24
|
+
"arrow-down": "M10 3.5v13M4.5 11l5.5 5.5 5.5-5.5",
|
|
25
|
+
plus: "M10 4v12M4 10h12",
|
|
26
|
+
minus: "M4 10h12",
|
|
27
|
+
sort: "M6 15V4M3 7l3-3 3 3M14 5v11M11 13l3 3 3-3",
|
|
28
|
+
search: "M13.3 13.3 17 17M14.5 8.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0",
|
|
29
|
+
sun: "M13.5 10a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0M10 1.75v1.5M10 16.75v1.5M1.75 10h1.5M16.75 10h1.5M4.17 4.17l1.06 1.06M14.77 14.77l1.06 1.06M4.17 15.83l1.06-1.06M14.77 5.23l1.06-1.06",
|
|
30
|
+
moon: "M17.25 11.15A7.5 7.5 0 0 1 8.85 2.75a7.5 7.5 0 1 0 8.4 8.4Z",
|
|
31
|
+
modern: "M6.5 3h7A3.5 3.5 0 0 1 17 6.5v7a3.5 3.5 0 0 1-3.5 3.5h-7A3.5 3.5 0 0 1 3 13.5v-7A3.5 3.5 0 0 1 6.5 3ZM7 10l3-3 3 3-3 3Z",
|
|
32
|
+
pixel: "M3 3h5v5H3ZM12 3h5v5h-5ZM3 12h5v5H3ZM12 12h5v5h-5Z",
|
|
33
|
+
chinese: "M3 8c3 0 5-2 7-5 2 3 4 5 7 5M4 8h12M6 8v8m8-8v8M3 16h14M8 16v-5h4v5",
|
|
34
|
+
soviet: "M3 17h14M5 17V8h4v9m0-12h6v12M7 8V5h2m2 3h2m-2 3h2m-2 3h2M10 5V3h4v2",
|
|
35
|
+
more: "M4 9.9v.2M10 9.9v.2M16 9.9v.2",
|
|
36
|
+
copy: "M7 7h8a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V7ZM13 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",
|
|
37
|
+
edit: "M11.5 4.5l4 4M4 12l9-9a1.4 1.4 0 0 1 2 0l2 2a1.4 1.4 0 0 1 0 2l-9 9-5 1Z",
|
|
38
|
+
link: "M8 6l2-2a4.2 4.2 0 0 1 6 6l-2 2M12 14l-2 2a4.2 4.2 0 0 1-6-6l2-2M7 13l6-6",
|
|
39
|
+
trash: "M3.5 5.5h13M7 5.5V3h6v2.5M5 5.5l.7 11.5h8.6L15 5.5M8 9v5M12 9v5",
|
|
40
|
+
spinner: "M10 3a7 7 0 1 1-7 7",
|
|
41
|
+
"circle-check": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM6 10l2.7 2.7 5.3-5.4",
|
|
42
|
+
"circle-error": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM7.2 7.2l5.6 5.6M12.8 7.2l-5.6 5.6",
|
|
43
|
+
"circle-info": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM10 9v5M10 6.1v.15",
|
|
44
|
+
"triangle-alert": "M8.7 3.5a1.5 1.5 0 0 1 2.6 0l6.4 11.3a1.5 1.5 0 0 1-1.3 2.2H3.6a1.5 1.5 0 0 1-1.3-2.2ZM10 7.2v4.4M10 14v.15",
|
|
45
|
+
refresh: "M16.5 7.2A7 7 0 0 0 4.3 5.9L2.5 8M2.5 3.5V8H7M3.5 12.8a7 7 0 0 0 12.2 1.3l1.8-2.1M13 12h4.5v4.5",
|
|
46
|
+
external: "M11.5 3H17v5.5M17 3l-8 8M8 3H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3",
|
|
47
|
+
home: "M3.5 10.25 10 4l6.5 6.25M5.75 8.75v7a.75.75 0 0 0 .75.75h7.5a.75.75 0 0 0 .75-.75v-7",
|
|
48
|
+
settings: "M3.5 5.5h13M3.5 10h13M3.5 14.5h13M7 4v3M12.5 8.5v3M8 13v3",
|
|
49
|
+
star: "M10 2.5l2.4 5.1 5.6.4-4.2 3.7 1.3 5.5-5.1-3-5.1 3 1.3-5.5L1.8 8l5.6-.4Z",
|
|
50
|
+
eye: "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8Z",
|
|
51
|
+
"eye-off": "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8ZM3.5 3.5l13 13",
|
|
52
|
+
inbox: "M3.5 12.25h3.7l1.5 2.5h2.6l1.5-2.5h3.7M4.7 5.5l-1.2 6.75v3.25a1.5 1.5 0 0 0 1.5 1.5h10a1.5 1.5 0 0 0 1.5-1.5v-3.25L15.3 5.5a1.3 1.3 0 0 0-1.25-1H5.95a1.3 1.3 0 0 0-1.25 1Z",
|
|
53
|
+
bell: "M10 3.5a4.5 4.5 0 0 1 4.5 4.5c0 4.5 1.8 5.7 2.5 6.5H3c.7-.8 2.5-2 2.5-6.5A4.5 4.5 0 0 1 10 3.5ZM8.5 16.5a1.6 1.6 0 0 0 3 0",
|
|
54
|
+
users: "M13.8 16.5v-1.5a3.5 3.5 0 0 0-3.5-3.5H6.3a3.5 3.5 0 0 0-3.5 3.5v1.5M8.3 8.9a2.7 2.7 0 1 0 0-5.4 2.7 2.7 0 0 0 0 5.4ZM16.5 16.5v-1.3a3.3 3.3 0 0 0-2.3-3.1M12.3 3.7a2.7 2.7 0 0 1 0 5.2",
|
|
55
|
+
activity: "M17 10h-2.6l-2 5.8L8 4.2 6 10H3",
|
|
56
|
+
"trend-up": "M3.5 14.5l4.2-4.2 2.8 2.8 5.9-5.9M12.4 7.2h4.2v4.2",
|
|
57
|
+
"trend-down": "M3.5 5.5l4.2 4.2 2.8-2.8 5.9 5.9M12.4 12.8h4.2V8.6",
|
|
58
|
+
rocket: "M10 2.5c2 1.5 3.2 4 3.2 6.8 0 1.5-.3 2.9-.8 4.2H7.6c-.5-1.3-.8-2.7-.8-4.2 0-2.8 1.2-5.3 3.2-6.8ZM10 8.6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM7.6 12.5 5.6 15.4c-.9.3-1.6 1-2 2M12.4 12.5l2 2.9c.9.3 1.6 1 2 2M8.7 13.8c0 1.8.5 3.1 1.3 4.2.8-1.1 1.3-2.4 1.3-4.2",
|
|
59
|
+
bold: "M6.5 4h4.2a3 3 0 0 1 0 6H6.5M6.5 10h5a3 3 0 0 1 0 6H6.5M6.5 4v12",
|
|
60
|
+
italic: "M8.5 4.5h7M4.5 15.5h7M12.5 4.5l-5 11",
|
|
61
|
+
underline: "M6 4v5.5a4 4 0 0 0 8 0V4M4.5 16h11",
|
|
62
|
+
"align-left": "M3.5 4.5h13M3.5 10h8.5M3.5 15.5h11",
|
|
63
|
+
"align-center": "M3.5 4.5h13M5.75 10h8.5M4.5 15.5h11",
|
|
64
|
+
"align-right": "M3.5 4.5h13M8 10h8.5M5.5 15.5h11",
|
|
65
|
+
list: "M6.5 5h10M6.5 10h10M6.5 15h10M3.5 5h.01M3.5 10h.01M3.5 15h.01",
|
|
66
|
+
server: "M3 3h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 8H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 3ZM3 12h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 17H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 12ZM5 5.5h.01M5 14.5h.01",
|
|
67
|
+
sparkle: "M10 2.5l1.6 4.3 4.3 1.6-4.3 1.6L10 14.3l-1.6-4.3-4.3-1.6 4.3-1.6ZM15.5 12.5l.8 2.1 2.1.8-2.1.8-.8 2.1-.8-2.1-2.1-.8 2.1-.8Z",
|
|
68
|
+
play: "M6.5 4.8v10.4c0 .9 1 1.5 1.8 1l8.3-5.2a1.2 1.2 0 0 0 0-2L8.3 3.8a1.2 1.2 0 0 0-1.8 1Z",
|
|
69
|
+
"chart-line": "M3.5 3.5v13h13M6.5 12l2.8-2.8 2.2 2.2 4-4.4",
|
|
70
|
+
layers: "M10 3.2 3.6 6.5 10 9.8l6.4-3.3ZM4.5 10.4 10 13.2l5.5-2.8M4.5 13.6 10 16.4l5.5-2.8",
|
|
71
|
+
box: "M17 6 10 3.2 3 6v8l7 2.8 7-2.8ZM3 6l7 2.8L17 6M10 9v7.8",
|
|
72
|
+
filter: "M4 4.5h12l-4.4 5.1v5l-3.2-1.6V9.6Z",
|
|
73
|
+
columns: "M3.5 4h13v12h-13ZM8.2 4v12M12.8 4v12",
|
|
74
|
+
download: "M10 3.5v8M6.8 8.3 10 11.5l3.2-3.2M4 15v2.5a1.5 1.5 0 0 0 1.5 1.5h9a1.5 1.5 0 0 0 1.5-1.5V15"
|
|
75
|
+
};
|
|
76
|
+
var custom = /* @__PURE__ */ new Map();
|
|
77
|
+
var escape = (s) => s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
78
|
+
function iconPath(name) {
|
|
79
|
+
return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
|
|
80
|
+
}
|
|
81
|
+
function iconAttributes(o = {}) {
|
|
82
|
+
const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
|
|
83
|
+
return { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", width: String(size), height: String(size), fill: "none", stroke: "currentColor", "stroke-width": "1.6", "stroke-linecap": "round", "stroke-linejoin": "round", focusable: "false", class: ["icen-symbol", o.className].filter(Boolean).join(" "), ...o.label ? { role: "img", "aria-label": o.label } : { "aria-hidden": "true" } };
|
|
84
|
+
}
|
|
85
|
+
function iconHTML(name, o = {}) {
|
|
86
|
+
const path = iconPath(name);
|
|
87
|
+
if (!path) return "";
|
|
88
|
+
return `<svg${Object.entries(iconAttributes(o)).map(([k, v]) => ` ${k}="${escape(v)}"`).join("")}><path d="${escape(path)}"></path></svg>`;
|
|
89
|
+
}
|
|
90
|
+
function createIcon(name, o = {}) {
|
|
91
|
+
if (typeof document === "undefined") return null;
|
|
92
|
+
const path = iconPath(name);
|
|
93
|
+
if (!path) return null;
|
|
94
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
95
|
+
for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
|
|
96
|
+
const line = document.createElementNS(svg.namespaceURI, "path");
|
|
97
|
+
line.setAttribute("d", path);
|
|
98
|
+
svg.append(line);
|
|
99
|
+
return svg;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/behaviors/events.ts
|
|
103
|
+
function emitIcen(source, type, detail) {
|
|
104
|
+
return source.dispatchEvent(
|
|
105
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/behaviors/i18n.ts
|
|
110
|
+
var ICEN_LOCALE_ZH_CN = {
|
|
111
|
+
/* ── aiBranch ── */
|
|
112
|
+
"aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
|
|
113
|
+
"aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
|
|
114
|
+
"aiBranch.version": "\u5206\u652F\u7248\u672C",
|
|
115
|
+
/* ── aiChat ── */
|
|
116
|
+
"aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
|
|
117
|
+
"aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
|
|
118
|
+
"aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
|
|
119
|
+
"aiChat.download": "\u4E0B\u8F7D",
|
|
120
|
+
"aiChat.file": "\u6587\u4EF6",
|
|
121
|
+
"aiChat.roleSystem": "\u7CFB",
|
|
122
|
+
"aiChat.roleTool": "\u5DE5",
|
|
123
|
+
"aiChat.roleUser": "\u6211",
|
|
124
|
+
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
125
|
+
/* ── aiComposer ── */
|
|
126
|
+
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
127
|
+
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
128
|
+
"aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
|
|
129
|
+
"aiComposer.all": "\u5168\u90E8",
|
|
130
|
+
"aiComposer.skills": "\u6280\u80FD",
|
|
131
|
+
"aiComposer.tools": "\u5DE5\u5177",
|
|
132
|
+
"aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
|
|
133
|
+
"aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
|
|
134
|
+
"aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
|
|
135
|
+
"aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
|
|
136
|
+
"aiComposer.filesNeedAdapter": "\u9644\u4EF6\u5C1A\u672A\u63A5\u901A\u4E0A\u4F20\u3002\u8BF7\u914D\u7F6E prepareMessage \u540E\u91CD\u8BD5\uFF0C\u6587\u4EF6\u4ECD\u4FDD\u7559\u5728\u6B64\u8BF7\u6C42\u4E2D\u3002",
|
|
137
|
+
"aiComposer.attachDoc": "\u6587\u6863",
|
|
138
|
+
"aiComposer.attachFile": "\u6587\u4EF6",
|
|
139
|
+
"aiComposer.attachFolder": "\u6587\u4EF6\u5939",
|
|
140
|
+
"aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
|
|
141
|
+
"aiComposer.commands": "\u547D\u4EE4",
|
|
142
|
+
"aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
|
|
143
|
+
"aiComposer.done": "\u5B8C\u6210",
|
|
144
|
+
"aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
|
|
145
|
+
"aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
|
|
146
|
+
"aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
|
|
147
|
+
"aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
|
|
148
|
+
"aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
|
|
149
|
+
"aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
|
|
150
|
+
"aiComposer.refs": "\u5F15\u7528",
|
|
151
|
+
"aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
|
|
152
|
+
"aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
|
|
153
|
+
"aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
|
|
154
|
+
"aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
|
|
155
|
+
"aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
|
|
156
|
+
"aiComposer.send": "\u53D1\u9001",
|
|
157
|
+
"aiComposer.stop": "\u505C\u6B62\u751F\u6210",
|
|
158
|
+
"aiComposer.stopped": "\u5DF2\u505C\u6B62",
|
|
159
|
+
"aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
|
|
160
|
+
"aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
|
|
161
|
+
/* ── aiCore ── */
|
|
162
|
+
"aiCore.kindBrowser": "\u6D4F\u89C8",
|
|
163
|
+
"aiCore.kindChart": "\u56FE\u8868",
|
|
164
|
+
"aiCore.kindDelete": "\u5220\u9664",
|
|
165
|
+
"aiCore.kindEdit": "\u7F16\u8F91",
|
|
166
|
+
"aiCore.kindFetch": "\u8BF7\u6C42",
|
|
167
|
+
"aiCore.kindGlob": "\u5339\u914D",
|
|
168
|
+
"aiCore.kindGrep": "\u641C\u7D22",
|
|
169
|
+
"aiCore.kindNote": "\u7B14\u8BB0",
|
|
170
|
+
"aiCore.kindPlan": "\u8BA1\u5212",
|
|
171
|
+
"aiCore.kindRead": "\u8BFB\u53D6",
|
|
172
|
+
"aiCore.kindSearch": "\u68C0\u7D22",
|
|
173
|
+
"aiCore.kindShell": "\u547D\u4EE4",
|
|
174
|
+
"aiCore.kindSkill": "\u6280\u80FD",
|
|
175
|
+
"aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
|
|
176
|
+
"aiCore.kindTodo": "\u5F85\u529E",
|
|
177
|
+
"aiCore.kindWrite": "\u5199\u5165",
|
|
178
|
+
"aiCore.statusApproval": "\u5F85\u786E\u8BA4",
|
|
179
|
+
"aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
|
|
180
|
+
"aiCore.statusDone": "\u5B8C\u6210",
|
|
181
|
+
"aiCore.statusError": "\u5931\u8D25",
|
|
182
|
+
"aiCore.statusPending": "\u7B49\u5F85",
|
|
183
|
+
"aiCore.statusRunning": "\u6267\u884C\u4E2D",
|
|
184
|
+
"aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
|
|
185
|
+
"aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
|
|
186
|
+
/* ── aiDiff ── */
|
|
187
|
+
"aiDiff.accepted": "\u5DF2\u63A5\u53D7",
|
|
188
|
+
"aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
|
|
189
|
+
"aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
|
|
190
|
+
"aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
|
|
191
|
+
/* ── aiFeedback ── */
|
|
192
|
+
"aiFeedback.helpful": "\u6709\u5E2E\u52A9",
|
|
193
|
+
"aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
|
|
194
|
+
"aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
|
|
195
|
+
"aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
|
|
196
|
+
"aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
|
|
197
|
+
"aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
|
|
198
|
+
"aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
|
|
199
|
+
"aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
|
|
200
|
+
/* ── aiPanel ── */
|
|
201
|
+
"aiPanel.audit": "\u5BA1\u8BA1",
|
|
202
|
+
"aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
|
|
203
|
+
"aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
|
|
204
|
+
"aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
|
|
205
|
+
"aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
|
|
206
|
+
"aiPanel.context": "\u4E0A\u4E0B\u6587",
|
|
207
|
+
"aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
208
|
+
"aiPanel.errorsCount": "{p0} \u5931\u8D25",
|
|
209
|
+
"aiPanel.files": "\u6587\u4EF6 ({p0})",
|
|
210
|
+
"aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
|
|
211
|
+
"aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
|
|
212
|
+
"aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
|
|
213
|
+
"aiPanel.reasoning": "\u63A8\u7406",
|
|
214
|
+
"aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
|
|
215
|
+
"aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
216
|
+
"aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
217
|
+
"aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
218
|
+
"aiPanel.toolsCount": "{p0} \u5DE5\u5177",
|
|
219
|
+
"aiPanel.usage": "\u7528\u91CF",
|
|
220
|
+
"aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
|
|
221
|
+
/* ── aiProvider ── */
|
|
222
|
+
"aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
|
|
223
|
+
"aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
|
|
224
|
+
"aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
|
|
225
|
+
"aiProvider.corsHint": "\uFF1B\u6D4F\u89C8\u5668\u76F4\u8FDE {p0}\uFF08{p1}\uFF09\u5F88\u53EF\u80FD\u88AB CORS \u62E6\u622A\uFF0C\u5EFA\u8BAE\u7ECF\u4EE3\u7406/\u81EA\u5EFA\u7F51\u5173\u8F6C\u53D1",
|
|
226
|
+
"aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
|
|
227
|
+
"aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
|
|
228
|
+
"aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
|
|
229
|
+
"aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
|
|
230
|
+
"aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
|
|
231
|
+
"aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
|
|
232
|
+
"aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
|
|
233
|
+
"aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
|
|
234
|
+
"aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
|
|
235
|
+
"aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
|
|
236
|
+
"aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
|
|
237
|
+
"aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
|
|
238
|
+
"aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
|
|
239
|
+
"aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
|
|
240
|
+
/* ── aiThreads ── */
|
|
241
|
+
"aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
|
|
242
|
+
"aiThreads.archived": "\u5DF2\u5F52\u6863",
|
|
243
|
+
/* ── aiTool ── */
|
|
244
|
+
"aiTool.allow": "\u5141\u8BB8",
|
|
245
|
+
"aiTool.reject": "\u62D2\u7EDD",
|
|
246
|
+
/* ── aiTools ── */
|
|
247
|
+
"aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
|
|
248
|
+
"aiTools.chart.data": "\u4EFB\u610F\u7EF4\u5EA6\u539F\u59CB\u8BB0\u5F55 + dims \u5B57\u6BB5\u6620\u5C04\uFF08\u81EA\u52A8\u900F\u89C6\u6210 \u7C7B\u76EE \xD7 \u7CFB\u5217\uFF09",
|
|
249
|
+
"aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
|
|
250
|
+
"aiTools.chart.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u5F20\u56FE\u8868\u53EF\u89C6\u5316\u3002\u8F93\u5165\u4E00\u4EFD\u56FE\u8868\u89C4\u683C\uFF08\u7EAF JSON\uFF09\uFF1Alabels+values\uFF08\u7C7B\u76EE\u6570\u503C\uFF09\u3001series\uFF08\u591A\u7CFB\u5217\uFF09\u3001segments\uFF08\u5360\u6BD4\uFF09\u3001points\uFF08\u6563\u70B9\u6C14\u6CE1\uFF09\u3001dates\uFF08\u8D21\u732E\u65E5\u5386\uFF09\u4EFB\u7ED9\u5176\u4E00\uFF1Btype \u7F3A\u7701\u65F6\u6309\u6570\u636E\u5F62\u6001\u81EA\u52A8\u9009\u578B\uFF08\u65F6\u95F4\u5E8F\u5217\u2192\u6298\u7EBF\u3001\u5360\u6BD4\u2192\u73AF\u5F62\u3001\u65E5\u671F\u2192\u8D21\u732E\u65E5\u5386\u3001\u5750\u6807\u70B9\u2192\u6563\u70B9\uFF09\u3002\u56FE\u8868\u5E26\u4EA4\u4E92\uFF08\u60AC\u505C\u63D0\u793A/\u70B9\u51FB/\u53F3\u952E\uFF09\u4E0E\u53EF\u9690\u85CF\u56FE\u4F8B\u3002",
|
|
251
|
+
"aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
|
|
252
|
+
"aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
|
|
253
|
+
"aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
|
|
254
|
+
"aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
|
|
255
|
+
"aiTools.chart.lttb": "\u5927\u6570\u636E\u91CF\u964D\u91C7\u6837\uFF1Atrue=\u81EA\u52A8\u4E0A\u9650\uFF0C\u6570\u5B57=\u6700\u5927\u4FDD\u7559\u70B9\u6570\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
|
|
256
|
+
"aiTools.chart.marks": "\u6807\u8BB0\u5C42\uFF08\u9608\u503C\u7EBF/\u53C2\u8003\u533A\u95F4/\u5F3A\u8C03\u70B9\uFF09\uFF0C\u5143\u7D20\u4E3A\u7EAF JSON \u63CF\u8FF0\u5B50\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
|
|
257
|
+
"aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
|
|
258
|
+
"aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
|
|
259
|
+
"aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
|
|
260
|
+
"aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
|
|
261
|
+
"aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
|
|
262
|
+
"aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
|
|
263
|
+
"aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
|
|
264
|
+
"aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
|
|
265
|
+
"aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
|
|
266
|
+
"aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
|
|
267
|
+
"aiTools.datatable.columns": "\u5217\u5B9A\u4E49\u6570\u7EC4\uFF1A\u6BCF\u9879 { key, title, sortable?, filterable? }\uFF08key \u5BF9\u5E94 rows \u5143\u7D20\u5B57\u6BB5\u540D\uFF09",
|
|
268
|
+
"aiTools.datatable.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u4E2A\u53EF\u641C\u7D22\u3001\u5206\u9875\u3001\u53EF\u5BFC\u51FA CSV \u7684\u6570\u636E\u8868\u683C\u3002\u8F93\u5165\u7EAF JSON\uFF1Acolumns \u4E3A\u5217\u5B9A\u4E49\uFF08key/title \u5FC5\u586B\uFF09\uFF0Crows \u4E3A\u884C\u5BF9\u8C61\u6570\u7EC4\uFF08\u5B57\u6BB5\u540D\u5BF9\u9F50\u5217 key\uFF09\u3002\u8FD4\u56DE { title, rows: \u884C\u6570 } \u6458\u8981\u3002",
|
|
269
|
+
"aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
|
|
270
|
+
"aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
|
|
271
|
+
"aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
|
|
272
|
+
"aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
273
|
+
"aiTools.manifestHeader": "\u53EF\u7528 UI \u5DE5\u5177\uFF08\u8C03\u7528\u540E\u5728\u7528\u6237\u754C\u9762\u6302\u8F7D\u53EF\u89C6\u5316\u7ED3\u679C\uFF09\uFF1A",
|
|
274
|
+
"aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
|
|
275
|
+
"aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
|
|
276
|
+
"aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
|
|
277
|
+
"aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
|
|
278
|
+
"aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
|
|
279
|
+
"aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
|
|
280
|
+
"aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
|
|
281
|
+
"aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
|
|
282
|
+
"aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
|
|
283
|
+
"aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
|
|
284
|
+
/* ── autocomplete ── */
|
|
285
|
+
"suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
|
|
286
|
+
"suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
287
|
+
"suggestions.options": "\u5EFA\u8BAE",
|
|
288
|
+
"suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
|
|
289
|
+
"autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
290
|
+
/* ── backTop ── */
|
|
291
|
+
"backTop.label": "\u56DE\u5230\u9876\u90E8",
|
|
292
|
+
/* ── carousel ── */
|
|
293
|
+
"carousel.item": "\u7B2C {p0} \u5F20",
|
|
294
|
+
"carousel.region": "\u8F6E\u64AD",
|
|
295
|
+
"carousel.slide": "\u5E7B\u706F\u7247",
|
|
296
|
+
"carousel.status": "\u7B2C {p0} / {p1} \u5F20",
|
|
297
|
+
/* ── charts ── */
|
|
298
|
+
"charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
|
|
299
|
+
"charts.few": "\u5C11",
|
|
300
|
+
"charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
|
|
301
|
+
"charts.loading": "\u52A0\u8F7D\u4E2D",
|
|
302
|
+
"charts.many": "\u591A",
|
|
303
|
+
"charts.monthLabel": "{p0}\u6708",
|
|
304
|
+
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
305
|
+
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
306
|
+
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
307
|
+
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
308
|
+
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
309
|
+
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
310
|
+
"charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
|
|
311
|
+
"charts.type.heatmap": "\u70ED\u529B\u56FE",
|
|
312
|
+
"charts.type.line": "\u6298\u7EBF\u56FE",
|
|
313
|
+
"charts.type.map": "\u5730\u56FE",
|
|
314
|
+
"charts.type.radar": "\u96F7\u8FBE\u56FE",
|
|
315
|
+
"charts.type.scatter": "\u6563\u70B9\u56FE",
|
|
316
|
+
"charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
|
|
317
|
+
"charts.seriesName": "\u7CFB\u5217{p0}",
|
|
318
|
+
"charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
|
|
319
|
+
"charts.value": "\u6570\u503C",
|
|
320
|
+
/* ── themeSwitcher ── */
|
|
321
|
+
"themeSwitcher.appearance": "\u5916\u89C2",
|
|
322
|
+
"themeSwitcher.theme": "\u4E3B\u9898",
|
|
323
|
+
"themeSwitcher.primitive": "\u539F\u8BED",
|
|
324
|
+
"themeSwitcher.mode": "\u660E\u6697",
|
|
325
|
+
"themeSwitcher.light": "\u6D45\u8272",
|
|
326
|
+
"themeSwitcher.dark": "\u6DF1\u8272",
|
|
327
|
+
"themeSwitcher.modern": "\u73B0\u4EE3",
|
|
328
|
+
"themeSwitcher.dongyun": "\u4E1C\u97F5",
|
|
329
|
+
"themeSwitcher.jugou": "\u5DE8\u6784",
|
|
330
|
+
"themeSwitcher.piano": "\u94A2\u7434",
|
|
331
|
+
"themeSwitcher.monet": "\u83AB\u5948",
|
|
332
|
+
"themeSwitcher.vangogh": "\u68B5\u9AD8",
|
|
333
|
+
"themeSwitcher.chinese": "\u4E2D\u5F0F",
|
|
334
|
+
"themeSwitcher.soviet": "\u82CF\u5F0F",
|
|
335
|
+
"themeSwitcher.pixel": "\u50CF\u7D20",
|
|
336
|
+
/* ── codeBlock ── */
|
|
337
|
+
"codeBlock.collapse": "\u6536\u8D77",
|
|
338
|
+
"codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
|
|
339
|
+
"codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
340
|
+
"codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
|
|
341
|
+
"codeBlock.copy": "\u590D\u5236",
|
|
342
|
+
"codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
|
|
343
|
+
"codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
|
|
344
|
+
"codeBlock.linesTotal": "\u5171 {p0} \u884C",
|
|
345
|
+
"codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
|
|
346
|
+
"codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
|
|
347
|
+
"codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
|
|
348
|
+
"codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
|
|
349
|
+
"codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
|
|
350
|
+
/* ── common ── */
|
|
351
|
+
"common.accept": "\u63A5\u53D7",
|
|
352
|
+
"common.add": "\u65B0\u589E",
|
|
353
|
+
"common.all": "\u5168\u90E8",
|
|
354
|
+
"common.approve": "\u6279\u51C6",
|
|
355
|
+
"common.cancel": "\u53D6\u6D88",
|
|
356
|
+
"common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
357
|
+
"common.close": "\u5173\u95ED",
|
|
358
|
+
"common.confirm": "\u786E\u8BA4",
|
|
359
|
+
"common.copied": "\u5DF2\u590D\u5236",
|
|
360
|
+
"common.copy": "\u590D\u5236",
|
|
361
|
+
"common.delete": "\u5220\u9664",
|
|
362
|
+
"common.enable": "\u542F\u7528",
|
|
363
|
+
"common.exportCsv": "\u5BFC\u51FA CSV",
|
|
364
|
+
"common.healthy": "\u6B63\u5E38",
|
|
365
|
+
"common.input": "\u8F93\u5165",
|
|
366
|
+
"common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
|
|
367
|
+
"common.official": "\u5B98\u65B9",
|
|
368
|
+
"common.output": "\u8F93\u51FA",
|
|
369
|
+
"common.page": "\u7B2C {p0} \u9875",
|
|
370
|
+
"common.reject": "\u62D2\u7EDD",
|
|
371
|
+
"common.remove": "\u79FB\u9664",
|
|
372
|
+
"common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
|
|
373
|
+
"common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
|
|
374
|
+
"common.restricted": "\u53D7\u9650",
|
|
375
|
+
"common.retry": "\u91CD\u8BD5",
|
|
376
|
+
"common.rows": "{p0} \u884C",
|
|
377
|
+
"common.run": "\u8FD0\u884C",
|
|
378
|
+
"common.steps": "{p0} \u6B65",
|
|
379
|
+
"common.submit": "\u63D0\u4EA4",
|
|
380
|
+
"common.unknown": "\u672A\u77E5",
|
|
381
|
+
/* ── contextMenu ── */
|
|
382
|
+
"contextMenu.back": "\u540E\u9000",
|
|
383
|
+
"contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
|
|
384
|
+
"contextMenu.forward": "\u524D\u8FDB",
|
|
385
|
+
"contextMenu.refresh": "\u5237\u65B0",
|
|
386
|
+
/* ── copy ── */
|
|
387
|
+
"copy.copied": "\u5DF2\u590D\u5236",
|
|
388
|
+
"copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
389
|
+
"copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
|
|
390
|
+
"copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
|
|
391
|
+
"copy.unknown": "\u672A\u77E5\u9519\u8BEF",
|
|
392
|
+
/* ── datatable ── */
|
|
393
|
+
"datatable.clear": "\u6E05\u7A7A",
|
|
394
|
+
"datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
|
|
395
|
+
"datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
|
|
396
|
+
"datatable.countUnit": "{p0} \u6761",
|
|
397
|
+
"datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
|
|
398
|
+
"datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
|
|
399
|
+
"datatable.empty": "\u6682\u65E0\u6570\u636E",
|
|
400
|
+
"datatable.emptyValue": "\uFF08\u7A7A\uFF09",
|
|
401
|
+
"datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
|
|
402
|
+
"datatable.expandRow": "\u5C55\u5F00\u884C",
|
|
403
|
+
"datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
|
|
404
|
+
"datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
|
|
405
|
+
"datatable.paginationAria": "\u5206\u9875",
|
|
406
|
+
"datatable.reset": "\u91CD\u7F6E",
|
|
407
|
+
"datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
|
|
408
|
+
"datatable.searchAria": "\u641C\u7D22\u8868\u683C",
|
|
409
|
+
"datatable.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
410
|
+
"datatable.selectAll": "\u5168\u9009",
|
|
411
|
+
"datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
|
|
412
|
+
"datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
|
|
413
|
+
"datatable.totalCount": "\u5171 {p0} \u6761",
|
|
414
|
+
"datatable.totalLabel": "\u5408\u8BA1",
|
|
415
|
+
/* ── datePicker ── */
|
|
416
|
+
"datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
|
|
417
|
+
"datePicker.clear": "\u6E05\u9664",
|
|
418
|
+
"datePicker.nextMonth": "\u4E0B\u4E00\u6708",
|
|
419
|
+
"datePicker.prevMonth": "\u4E0A\u4E00\u6708",
|
|
420
|
+
"datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
|
|
421
|
+
"datePicker.today": "\u4ECA\u5929",
|
|
422
|
+
"datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
|
|
423
|
+
"datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
|
|
424
|
+
"datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
|
|
425
|
+
/* ── formValidate ── */
|
|
426
|
+
"formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
|
|
427
|
+
"formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
|
|
428
|
+
"formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
|
|
429
|
+
"formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
|
|
430
|
+
"formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
|
|
431
|
+
"formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
|
|
432
|
+
"formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
|
|
433
|
+
"formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
|
|
434
|
+
"formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
435
|
+
"formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
|
|
436
|
+
"formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
|
|
437
|
+
"formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
|
|
438
|
+
"formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
|
|
439
|
+
"formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
|
|
440
|
+
"formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
|
|
441
|
+
"formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
|
|
442
|
+
"formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
|
|
443
|
+
"formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
|
|
444
|
+
"formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
|
|
445
|
+
"formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
|
|
446
|
+
"formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
|
|
447
|
+
"formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
|
|
448
|
+
"formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
|
|
449
|
+
"formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
|
|
450
|
+
"formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
|
|
451
|
+
"formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
|
|
452
|
+
"formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
|
|
453
|
+
/* ── input ── */
|
|
454
|
+
"input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
|
|
455
|
+
"input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
|
|
456
|
+
"input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
|
|
457
|
+
"panel.expand": "\u5C55\u5F00",
|
|
458
|
+
"panel.collapse": "\u6298\u53E0",
|
|
459
|
+
"input.showPassword": "\u663E\u793A\u5BC6\u7801",
|
|
460
|
+
/* ── kbAccess ── */
|
|
461
|
+
"kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
462
|
+
"kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
|
|
463
|
+
"kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
464
|
+
"kbAccess.daysLeft": "{p0} \u5929\u540E",
|
|
465
|
+
"kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
|
|
466
|
+
"kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
|
|
467
|
+
"kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
468
|
+
"kbAccess.duration30d": "30 \u5929",
|
|
469
|
+
"kbAccess.duration7d": "7 \u5929",
|
|
470
|
+
"kbAccess.durationForever": "\u6C38\u4E45",
|
|
471
|
+
"kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
|
|
472
|
+
"kbAccess.expired": "\u5DF2\u5230\u671F",
|
|
473
|
+
"kbAccess.expiresAt": "{p0}\u5230\u671F",
|
|
474
|
+
"kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
|
|
475
|
+
"kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
|
|
476
|
+
"kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
|
|
477
|
+
"kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
|
|
478
|
+
"kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
|
|
479
|
+
"kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
|
|
480
|
+
"kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
|
|
481
|
+
"kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
|
|
482
|
+
"kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
|
|
483
|
+
"kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
484
|
+
"kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
|
|
485
|
+
"kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
|
|
486
|
+
"kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
|
|
487
|
+
"kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
|
|
488
|
+
"kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
|
|
489
|
+
"kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
|
|
490
|
+
"kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
|
|
491
|
+
"kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
|
|
492
|
+
"kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
|
|
493
|
+
"kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
|
|
494
|
+
"kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
|
|
495
|
+
/* ── kbAcl ── */
|
|
496
|
+
"kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
|
|
497
|
+
"kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
|
|
498
|
+
"kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
|
|
499
|
+
"kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
|
|
500
|
+
"kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
|
|
501
|
+
"kbAcl.exception": "\u4F8B\u5916",
|
|
502
|
+
"kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
|
|
503
|
+
"kbAcl.expiresIn": "{p0} \u5230\u671F",
|
|
504
|
+
"kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
|
|
505
|
+
"kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
|
|
506
|
+
"kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
|
|
507
|
+
"kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
|
|
508
|
+
"kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
|
|
509
|
+
"kbAcl.noLinks": "\u65E0\u94FE\u63A5",
|
|
510
|
+
"kbAcl.removeEntry": "\u79FB\u9664 {p0}",
|
|
511
|
+
"kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
|
|
512
|
+
"kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
|
|
513
|
+
"kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
|
|
514
|
+
"kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
|
|
515
|
+
"kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
|
|
516
|
+
"kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
|
|
517
|
+
"kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
|
|
518
|
+
/* ── kbAnswer ── */
|
|
519
|
+
"kbAnswer.chartBar": "\u67F1\u72B6",
|
|
520
|
+
"kbAnswer.chartLine": "\u6298\u7EBF",
|
|
521
|
+
"kbAnswer.chartPie": "\u997C\u56FE",
|
|
522
|
+
"kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
|
|
523
|
+
"kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
|
|
524
|
+
"kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
|
|
525
|
+
"kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
|
|
526
|
+
"kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
|
|
527
|
+
"kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
|
|
528
|
+
"kbAnswer.kindFunction": "\u51FD\u6570",
|
|
529
|
+
"kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
|
|
530
|
+
"kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
|
|
531
|
+
"kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
|
|
532
|
+
"kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
|
|
533
|
+
"kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
|
|
534
|
+
/* ── kbAudit ── */
|
|
535
|
+
"kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
|
|
536
|
+
"kbAudit.actionLabel": "\u5904\u7F6E",
|
|
537
|
+
"kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
|
|
538
|
+
"kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
|
|
539
|
+
"kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
|
|
540
|
+
"kbAudit.channelRead": "\u8BFB\u53D6",
|
|
541
|
+
"kbAudit.channelRequest": "\u7533\u8BF7",
|
|
542
|
+
"kbAudit.channelSystem": "\u7CFB\u7EDF",
|
|
543
|
+
"kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
|
|
544
|
+
"kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
|
|
545
|
+
"kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
|
|
546
|
+
"kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
|
|
547
|
+
/* ── kbCanvas ── */
|
|
548
|
+
"kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
|
|
549
|
+
"kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
|
|
550
|
+
/* ── kbCheckpoint ── */
|
|
551
|
+
"kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
|
|
552
|
+
"kbCheckpoint.label": "\u68C0\u67E5\u70B9",
|
|
553
|
+
"kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
|
|
554
|
+
"kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
|
|
555
|
+
"kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
|
|
556
|
+
"kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
|
|
557
|
+
"kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
|
|
558
|
+
/* ── kbChunks ── */
|
|
559
|
+
"kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
|
|
560
|
+
"kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
|
|
561
|
+
"kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
|
|
562
|
+
"kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
|
|
563
|
+
"kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
|
|
564
|
+
"kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
|
|
565
|
+
"kbChunks.edited": "\u5DF2\u7F16\u8F91",
|
|
566
|
+
"kbChunks.empty": "\u6682\u65E0 chunk",
|
|
567
|
+
"kbChunks.modeFull": "\u5168\u6587",
|
|
568
|
+
"kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
|
|
569
|
+
"kbChunks.modeVector": "\u8BED\u4E49",
|
|
570
|
+
"kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
|
|
571
|
+
"kbChunks.searchAria": "\u641C\u7D22 chunk",
|
|
572
|
+
"kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
|
|
573
|
+
"kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
|
|
574
|
+
/* ── kbCitation ── */
|
|
575
|
+
"kbCitation.sourceN": "\u6765\u6E90 {p0}",
|
|
576
|
+
"kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
|
|
577
|
+
/* ── kbClarify ── */
|
|
578
|
+
"kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
|
|
579
|
+
/* ── kbConflict ── */
|
|
580
|
+
"kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
|
|
581
|
+
/* ── kbConnector ── */
|
|
582
|
+
"kbConnector.changeRate": "\u53D8\u66F4\u7387",
|
|
583
|
+
"kbConnector.crawlRate": "\u6293\u53D6\u7387",
|
|
584
|
+
"kbConnector.credentials": "\u51ED\u8BC1",
|
|
585
|
+
"kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
|
|
586
|
+
"kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
|
|
587
|
+
"kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
|
|
588
|
+
"kbConnector.failing": "\u5F02\u5E38",
|
|
589
|
+
"kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
|
|
590
|
+
"kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
|
|
591
|
+
"kbConnector.notConfigured": "\u672A\u914D\u7F6E",
|
|
592
|
+
"kbConnector.off": "\u5DF2\u505C\u7528",
|
|
593
|
+
"kbConnector.perDay": "{p0}/\u5929",
|
|
594
|
+
"kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
|
|
595
|
+
"kbConnector.stale": "\u505C\u6EDE",
|
|
596
|
+
"kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
|
|
597
|
+
"kbConnector.synced": "\u5DF2\u540C\u6B65",
|
|
598
|
+
/* ── kbCore ── */
|
|
599
|
+
"kbCore.accessDenied": "\u672A\u901A\u8FC7",
|
|
600
|
+
"kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
|
|
601
|
+
"kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
|
|
602
|
+
"kbCore.accessGranted": "\u5DF2\u5F00\u901A",
|
|
603
|
+
"kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
|
|
604
|
+
"kbCore.accessPending": "\u5F85\u5BA1\u6279",
|
|
605
|
+
"kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
|
|
606
|
+
"kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
|
|
607
|
+
"kbCore.auditApprove": "\u6279\u51C6",
|
|
608
|
+
"kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
|
|
609
|
+
"kbCore.auditDelegation": "\u59D4\u6D3E",
|
|
610
|
+
"kbCore.auditDeny": "\u62D2\u7EDD",
|
|
611
|
+
"kbCore.auditGrant": "\u6388\u4E88",
|
|
612
|
+
"kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
|
|
613
|
+
"kbCore.auditPreview": "\u9884\u89C8",
|
|
614
|
+
"kbCore.auditRead": "\u8BFB\u53D6",
|
|
615
|
+
"kbCore.auditRequest": "\u7533\u8BF7",
|
|
616
|
+
"kbCore.auditRevoke": "\u6536\u56DE",
|
|
617
|
+
"kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
|
|
618
|
+
"kbCore.daysAgo": "{p0} \u5929\u524D",
|
|
619
|
+
"kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
|
|
620
|
+
"kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
|
|
621
|
+
"kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
|
|
622
|
+
"kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
|
|
623
|
+
"kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
|
|
624
|
+
"kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
|
|
625
|
+
"kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
|
|
626
|
+
"kbCore.justNow": "\u521A\u521A",
|
|
627
|
+
"kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
|
|
628
|
+
"kbCore.levelEdit": "\u53EF\u7F16\u8F91",
|
|
629
|
+
"kbCore.levelNone": "\u65E0\u6743\u9650",
|
|
630
|
+
"kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
|
|
631
|
+
"kbCore.levelView": "\u53EF\u67E5\u770B",
|
|
632
|
+
"kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
|
|
633
|
+
"kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
|
|
634
|
+
"kbCore.runDone": "\u5DF2\u5B8C\u6210",
|
|
635
|
+
"kbCore.runFailed": "\u5931\u8D25",
|
|
636
|
+
"kbCore.runQueued": "\u6392\u961F\u4E2D",
|
|
637
|
+
"kbCore.runRunning": "\u8FDB\u884C\u4E2D",
|
|
638
|
+
"kbCore.runUnstarted": "\u672A\u5F00\u59CB",
|
|
639
|
+
"kbCore.stageAgent": "\u4EE3\u7406",
|
|
640
|
+
"kbCore.stageChunk": "\u5207\u7247",
|
|
641
|
+
"kbCore.stageEmbed": "\u5411\u91CF\u5316",
|
|
642
|
+
"kbCore.stageGeneration": "\u751F\u6210",
|
|
643
|
+
"kbCore.stageGuard": "\u62A4\u680F",
|
|
644
|
+
"kbCore.stageQuery": "\u67E5\u8BE2",
|
|
645
|
+
"kbCore.stageRerank": "\u91CD\u6392",
|
|
646
|
+
"kbCore.stageRetrieval": "\u68C0\u7D22",
|
|
647
|
+
"kbCore.stageTool": "\u5DE5\u5177",
|
|
648
|
+
"kbCore.typeApi": "\u63A5\u53E3",
|
|
649
|
+
"kbCore.typeCode": "\u4EE3\u7801",
|
|
650
|
+
"kbCore.typeDatabase": "\u6570\u636E\u5E93",
|
|
651
|
+
"kbCore.typeDocument": "\u6587\u6863",
|
|
652
|
+
"kbCore.typeEmail": "\u90AE\u4EF6",
|
|
653
|
+
"kbCore.typeImage": "\u56FE\u7247",
|
|
654
|
+
"kbCore.typeKb": "\u77E5\u8BC6\u5E93",
|
|
655
|
+
"kbCore.typeTable": "\u8868\u683C",
|
|
656
|
+
"kbCore.typeTicket": "\u5DE5\u5355",
|
|
657
|
+
"kbCore.typeWebpage": "\u7F51\u9875",
|
|
658
|
+
"kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
|
|
659
|
+
"kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
|
|
660
|
+
"kbCore.visHidden": "\u4E0D\u53EF\u89C1",
|
|
661
|
+
"kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
|
|
662
|
+
"kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
|
|
663
|
+
"kbCore.visVisible": "\u53EF\u89C1",
|
|
664
|
+
/* ── kbEval ── */
|
|
665
|
+
"kbEval.avgA": "A \u5747\u5206 {p0}",
|
|
666
|
+
"kbEval.avgB": "B \u5747\u5206 {p0}",
|
|
667
|
+
"kbEval.compare": "\u5BF9\u6BD4",
|
|
668
|
+
"kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
|
|
669
|
+
"kbEval.expected": "\u671F\u671B",
|
|
670
|
+
"kbEval.gradeImprovement": "\u63D0\u5347",
|
|
671
|
+
"kbEval.gradeRegression": "\u56DE\u5F52",
|
|
672
|
+
"kbEval.gradeTie": "\u6301\u5E73",
|
|
673
|
+
"kbEval.gradeTradeoff": "\u6743\u8861",
|
|
674
|
+
"kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
|
|
675
|
+
"kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
|
|
676
|
+
"kbEval.outputA": "\u8F93\u51FA A",
|
|
677
|
+
"kbEval.outputB": "\u8F93\u51FA B",
|
|
678
|
+
"kbEval.outputN": "\u8F93\u51FA {p0}",
|
|
679
|
+
/* ── kbExplain ── */
|
|
680
|
+
"kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
|
|
681
|
+
"kbExplain.groupAgg": "\u805A\u5408",
|
|
682
|
+
"kbExplain.groupColumn": "\u5217",
|
|
683
|
+
"kbExplain.groupFilter": "\u7B5B\u9009",
|
|
684
|
+
"kbExplain.groupTable": "\u8868",
|
|
685
|
+
"kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
|
|
686
|
+
"kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
|
|
687
|
+
/* ── kbFilter ── */
|
|
688
|
+
"kbFilter.addGroup": "+ \u7EC4",
|
|
689
|
+
"kbFilter.addRule": "+ \u89C4\u5219",
|
|
690
|
+
"kbFilter.and": "\u4E14",
|
|
691
|
+
"kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
|
|
692
|
+
"kbFilter.copyDsl": "\u590D\u5236 DSL",
|
|
693
|
+
"kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
|
|
694
|
+
"kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
|
|
695
|
+
"kbFilter.fieldLabel": "\u5B57\u6BB5",
|
|
696
|
+
"kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
|
|
697
|
+
"kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
|
|
698
|
+
"kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
|
|
699
|
+
"kbFilter.opContains": "\u5305\u542B",
|
|
700
|
+
"kbFilter.opEq": "\u7B49\u4E8E",
|
|
701
|
+
"kbFilter.opExists": "\u5B58\u5728",
|
|
702
|
+
"kbFilter.opGt": "\u5927\u4E8E",
|
|
703
|
+
"kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
|
|
704
|
+
"kbFilter.opIn": "\u5C5E\u4E8E",
|
|
705
|
+
"kbFilter.opLt": "\u5C0F\u4E8E",
|
|
706
|
+
"kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
707
|
+
"kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
|
|
708
|
+
"kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
|
|
709
|
+
"kbFilter.or": "\u6216",
|
|
710
|
+
"kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
|
|
711
|
+
"kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
|
|
712
|
+
"kbFilter.valueLabel": "\u503C",
|
|
713
|
+
"kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
|
|
714
|
+
/* ── kbGap ── */
|
|
715
|
+
"kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
|
|
716
|
+
"kbGap.colCount": "\u6B21\u6570",
|
|
717
|
+
"kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
|
|
718
|
+
"kbGap.colQuery": "\u67E5\u8BE2",
|
|
719
|
+
"kbGap.colShare": "\u5360\u6BD4",
|
|
720
|
+
"kbGap.createDoc": "\u5EFA\u6587\u6863",
|
|
721
|
+
"kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
|
|
722
|
+
"kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
|
|
723
|
+
"kbGap.zeroClickHint": "\u7528\u6237\u53EF\u80FD\u5DF2\u4ECE\u5F15\u7528\u7247\u6BB5\u5F97\u5230\u7B54\u6848\uFF1B\u96F6\u70B9\u51FB\u9700\u4EBA\u5DE5\u5224\u8BFB\uFF0C\u4E0D\u76F4\u63A5\u89C6\u4E3A\u5931\u8D25",
|
|
724
|
+
"kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
|
|
725
|
+
"kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
|
|
726
|
+
/* ── kbHittest ── */
|
|
727
|
+
"kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
|
|
728
|
+
"kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
|
|
729
|
+
"kbHittest.avgScore": "\u5747\u5206",
|
|
730
|
+
"kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
|
|
731
|
+
"kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
|
|
732
|
+
"kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
|
|
733
|
+
"kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
|
|
734
|
+
"kbHittest.hitRate": "\u547D\u4E2D\u7387",
|
|
735
|
+
"kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
|
|
736
|
+
"kbHittest.notRun": "\u672A\u8FD0\u884C",
|
|
737
|
+
"kbHittest.pass": "\u901A\u8FC7",
|
|
738
|
+
"kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
|
|
739
|
+
"kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
|
|
740
|
+
"kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
741
|
+
"kbHittest.sessionOnlyHint": "\u6D4B\u8BD5\u8FD0\u884C\u7684\u68C0\u7D22\u53C2\u6570\uFF08topK/\u9608\u503C/\u91CD\u6392\uFF09\u4E0D\u843D\u5E93\uFF0C\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
742
|
+
"kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
|
|
743
|
+
/* ── kbMetadata ── */
|
|
744
|
+
"kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
|
|
745
|
+
"kbMetadata.builtIn": "\u5185\u7F6E",
|
|
746
|
+
"kbMetadata.colField": "\u5B57\u6BB5",
|
|
747
|
+
"kbMetadata.colType": "\u7C7B\u578B",
|
|
748
|
+
"kbMetadata.colValue": "\u503C",
|
|
749
|
+
"kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
|
|
750
|
+
"kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
|
|
751
|
+
"kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
|
|
752
|
+
"kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
|
|
753
|
+
"kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
|
|
754
|
+
"kbMetadata.valueOf": "{p0} \u7684\u503C",
|
|
755
|
+
/* ── kbPassage ── */
|
|
756
|
+
"kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
|
|
757
|
+
"kbPassage.close": "\u5173\u95ED\u539F\u6587",
|
|
758
|
+
"kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
|
|
759
|
+
"kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
|
|
760
|
+
"kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
|
|
761
|
+
"kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
|
|
762
|
+
"kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
|
|
763
|
+
"kbPassage.unitByte": "\u5B57\u8282",
|
|
764
|
+
"kbPassage.unitChar": "\u5B57\u7B26",
|
|
765
|
+
/* ── kbPipeline ── */
|
|
766
|
+
"kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
|
|
767
|
+
"kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
|
|
768
|
+
"kbPipeline.rerun": "\u91CD\u8DD1",
|
|
769
|
+
"kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
|
|
770
|
+
/* ── kbQa ── */
|
|
771
|
+
"kbQa.colAnswer": "\u7B54\u6848",
|
|
772
|
+
"kbQa.colQuestion": "\u95EE\u9898",
|
|
773
|
+
"kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
|
|
774
|
+
"kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
|
|
775
|
+
"kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
|
|
776
|
+
"kbQa.importCsv": "\u5BFC\u5165 CSV",
|
|
777
|
+
/* ── kbRerank ── */
|
|
778
|
+
"kbRerank.after": "\u91CD\u6392\u540E",
|
|
779
|
+
"kbRerank.before": "\u91CD\u6392\u524D",
|
|
780
|
+
"kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
|
|
781
|
+
"kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
|
|
782
|
+
"kbRerank.dropped": "\u843D\u9009",
|
|
783
|
+
"kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
|
|
784
|
+
"kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
|
|
785
|
+
"kbRerank.newIn": "\u65B0\u8FDB",
|
|
786
|
+
"kbRerank.unmarked": "\u672A\u6807",
|
|
787
|
+
"kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
|
|
788
|
+
/* ── kbRetrieval ── */
|
|
789
|
+
"kbRetrieval.breakdown": "\u62C6\u89E3",
|
|
790
|
+
"kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
|
|
791
|
+
"kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
|
|
792
|
+
"kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
793
|
+
"kbRetrieval.failOpenNotice": "fail-open\uFF1A\u5F53\u524D\u67E5\u8BE2\u672A\u643A\u5E26\u8EAB\u4EFD\u8FC7\u6EE4\uFF0C\u5C06\u8FD4\u56DE\u5168\u90E8\u5019\u9009\uFF08\u4EC5\u9650\u8C03\u8BD5\uFF09",
|
|
794
|
+
"kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
|
|
795
|
+
"kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
|
|
796
|
+
"kbRetrieval.identityShort": "\u8EAB\u4EFD",
|
|
797
|
+
"kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
|
|
798
|
+
"kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
|
|
799
|
+
"kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
|
|
800
|
+
"kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
|
|
801
|
+
"kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
|
|
802
|
+
"kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
|
|
803
|
+
"kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
|
|
804
|
+
"kbRetrieval.modeHybrid": "\u6DF7\u5408",
|
|
805
|
+
"kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
|
|
806
|
+
"kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
|
|
807
|
+
"kbRetrieval.modeVector": "\u5411\u91CF",
|
|
808
|
+
"kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
|
|
809
|
+
"kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
|
|
810
|
+
"kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
|
|
811
|
+
"kbRetrieval.rerankLabel": "\u91CD\u6392",
|
|
812
|
+
"kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
|
|
813
|
+
"kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
|
|
814
|
+
"kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
|
|
815
|
+
"kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
|
|
816
|
+
"kbRetrieval.thresholdValue": "\u9608\u503C N/A",
|
|
817
|
+
"kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
|
|
818
|
+
"kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
|
|
819
|
+
"kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
|
|
820
|
+
/* ── kbReview ── */
|
|
821
|
+
"kbReview.assignee": "\u5206\u914D\u4EBA",
|
|
822
|
+
"kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
|
|
823
|
+
"kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
|
|
824
|
+
"kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
|
|
825
|
+
"kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
|
|
826
|
+
"kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
|
|
827
|
+
"kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
|
|
828
|
+
"kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
|
|
829
|
+
"kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
|
|
830
|
+
"kbReview.shortcuts": "? \u5FEB\u6377\u952E",
|
|
831
|
+
"kbReview.typeAnswer": "\u56DE\u7B54",
|
|
832
|
+
"kbReview.typeMessage": "\u6D88\u606F",
|
|
833
|
+
"kbReview.typeTrace": "\u8F68\u8FF9",
|
|
834
|
+
"kbReview.unassigned": "\u672A\u5206\u914D",
|
|
835
|
+
/* ── kbSandbox ── */
|
|
836
|
+
"kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
|
|
837
|
+
"kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
|
|
838
|
+
"kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
|
|
839
|
+
"kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
840
|
+
"kbSandbox.title": "MCP App \u6C99\u7BB1",
|
|
841
|
+
/* ── kbSegment ── */
|
|
842
|
+
"kbSegment.avgLength": "\u5747\u957F {p0}",
|
|
843
|
+
"kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
|
|
844
|
+
"kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
|
|
845
|
+
"kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
|
|
846
|
+
"kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
|
|
847
|
+
"kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
|
|
848
|
+
"kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
|
|
849
|
+
"kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
|
|
850
|
+
"kbSegment.modeAuto": "\u81EA\u52A8",
|
|
851
|
+
"kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
|
|
852
|
+
"kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
|
|
853
|
+
"kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
|
|
854
|
+
"kbSegment.modeParentChild": "\u7236\u5B50",
|
|
855
|
+
"kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
|
|
856
|
+
"kbSegment.overlapLabel": "\u91CD\u53E0",
|
|
857
|
+
"kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
|
|
858
|
+
"kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
|
|
859
|
+
"kbSegment.segmentsCount": "{p0} \u6BB5",
|
|
860
|
+
"kbSegment.separatorLabel": "\u5206\u9694\u7B26",
|
|
861
|
+
"kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
|
|
862
|
+
"kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
|
|
863
|
+
/* ── kbSources ── */
|
|
864
|
+
"kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
|
|
865
|
+
"kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
866
|
+
/* ── kbSql ── */
|
|
867
|
+
"kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
|
|
868
|
+
"kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
|
|
869
|
+
"kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
|
|
870
|
+
"kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
|
|
871
|
+
"kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
|
|
872
|
+
"kbSql.generated": "\u751F\u6210\u7684 SQL",
|
|
873
|
+
/* ── kbTrace ── */
|
|
874
|
+
"kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
|
|
875
|
+
"kbTrace.hits": "\u547D\u4E2D {p0}",
|
|
876
|
+
/* ── kbVisibility ── */
|
|
877
|
+
"kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
|
|
878
|
+
"kbVisibility.adminWarn": "admin \u5BA1\u8BA1\u89C6\u56FE\u2014\u2014\u547D\u4E2D\u5DEE\u5F02\u5BF9\u7167\u5BF9\u666E\u901A\u7528\u6237\u6784\u6210\u6CC4\u9732\uFF0C\u52FF\u5D4C\u5165\u7EC8\u7AEF\u7528\u6237\u754C\u9762",
|
|
879
|
+
"kbVisibility.failOpenNote": "fail-open\uFF1AKendra \u65E0\u8EAB\u4EFD\u4E0A\u4E0B\u6587\u8FD4\u56DE\u5168\u90E8\u6587\u6863\u2014\u2014\u68C0\u7D22\u5FC5\u987B\u643A\u5E26\u670D\u52A1\u7AEF\u8EAB\u4EFD",
|
|
880
|
+
"kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
|
|
881
|
+
"kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
|
|
882
|
+
"kbVisibility.leakageNote": "\u8BA1\u6570\u5DEE\u5F02\u5373 volume leakage\uFF1A\u5BF9\u666E\u901A\u7528\u6237\u53EA\u53EF\u7ED9\u300C\u5DF2\u6309\u6743\u9650\u8FC7\u6EE4\u300D\u6052\u5B9A\u6587\u6848\uFF0C\u7F13\u89E3\u53EA\u6709 padding \u53D6\u6574",
|
|
883
|
+
"kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
|
|
884
|
+
"kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
|
|
885
|
+
"kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
|
|
886
|
+
"kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
|
|
887
|
+
"kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
|
|
888
|
+
/* ── kbWhoCan ── */
|
|
889
|
+
"kbWhoCan.check": "\u68C0\u67E5",
|
|
890
|
+
"kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
|
|
891
|
+
"kbWhoCan.daysUntil": "{p0} \u5929\u540E",
|
|
892
|
+
"kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
|
|
893
|
+
"kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
|
|
894
|
+
"kbWhoCan.direct": "\u76F4\u63A5",
|
|
895
|
+
"kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
|
|
896
|
+
"kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
|
|
897
|
+
"kbWhoCan.inherit": "\u7EE7\u627F",
|
|
898
|
+
"kbWhoCan.link": "\u94FE\u63A5",
|
|
899
|
+
"kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
|
|
900
|
+
"kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
|
|
901
|
+
"kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
|
|
902
|
+
"kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
|
|
903
|
+
"kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
|
|
904
|
+
/* ── mentions ── */
|
|
905
|
+
"mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
|
|
906
|
+
"mentions.customBadge": "\u81EA\u5B9A\u4E49",
|
|
907
|
+
"mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
908
|
+
/* ── notification ── */
|
|
909
|
+
"notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
|
|
910
|
+
"notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
|
|
911
|
+
"notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
|
|
912
|
+
"notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
|
|
913
|
+
"notification.ariaLabel": "\u901A\u77E5",
|
|
914
|
+
"notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
|
|
915
|
+
/* ── pagination ── */
|
|
916
|
+
"pagination.next": "\u4E0B\u4E00\u9875",
|
|
917
|
+
"pagination.pageSize": "{p0} \u6761/\u9875",
|
|
918
|
+
"pagination.prev": "\u4E0A\u4E00\u9875",
|
|
919
|
+
/* ── select ── */
|
|
920
|
+
"select.fieldLabel": "\u9009\u62E9\u9009\u9879",
|
|
921
|
+
"select.noMatch": "\u65E0\u5339\u914D\u9879",
|
|
922
|
+
"select.remove": "\u79FB\u9664 {p0}",
|
|
923
|
+
"select.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
924
|
+
/* ── cascader / tree-select ── */
|
|
925
|
+
"cascader.placeholder": "\u8BF7\u9009\u62E9",
|
|
926
|
+
"cascader.noMatch": "\u65E0\u5339\u914D",
|
|
927
|
+
"cascader.search": "\u641C\u7D22",
|
|
928
|
+
"treeSelect.placeholder": "\u8BF7\u9009\u62E9",
|
|
929
|
+
"treeSelect.noMatch": "\u65E0\u5339\u914D",
|
|
930
|
+
"treeSelect.search": "\u641C\u7D22",
|
|
931
|
+
/* ── tagInput ── */
|
|
932
|
+
"tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
|
|
933
|
+
"tagInput.remove": "\u79FB\u9664 {p0}",
|
|
934
|
+
"tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
|
|
935
|
+
"tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
|
|
936
|
+
"tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
|
|
937
|
+
"tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
|
|
938
|
+
"tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
|
|
939
|
+
/* ── upload ── */
|
|
940
|
+
"upload.remove": "\u79FB\u9664 {p0}",
|
|
941
|
+
"upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
|
|
942
|
+
"upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
|
|
943
|
+
"upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
|
|
944
|
+
};
|
|
945
|
+
var current = { ...ICEN_LOCALE_ZH_CN };
|
|
946
|
+
function t(key, vars) {
|
|
947
|
+
const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
|
|
948
|
+
if (vars == null || Array.isArray(raw)) return raw;
|
|
949
|
+
return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/behaviors/svg-parse.ts
|
|
953
|
+
function parseSvg(source) {
|
|
954
|
+
if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
|
|
955
|
+
const trimmed = source.trimStart();
|
|
956
|
+
if (!trimmed.startsWith("<svg")) return null;
|
|
957
|
+
const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
|
|
958
|
+
let parsed;
|
|
959
|
+
try {
|
|
960
|
+
parsed = new DOMParser().parseFromString(src, "image/svg+xml");
|
|
961
|
+
} catch {
|
|
962
|
+
return null;
|
|
963
|
+
}
|
|
964
|
+
const root = parsed.documentElement;
|
|
965
|
+
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
|
|
966
|
+
const sanitize = (el) => {
|
|
967
|
+
for (const attr of Array.from(el.attributes)) {
|
|
968
|
+
const name = attr.name.toLowerCase();
|
|
969
|
+
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
970
|
+
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
971
|
+
el.removeAttribute(attr.name);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
for (const child of Array.from(el.children)) {
|
|
975
|
+
const tag = child.tagName.toLowerCase();
|
|
976
|
+
if (tag === "script" || tag === "foreignobject") {
|
|
977
|
+
child.remove();
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
sanitize(child);
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
sanitize(root);
|
|
984
|
+
return document.importNode(root, true);
|
|
985
|
+
}
|
|
986
|
+
|
|
1
987
|
// src/behaviors/ai-core.ts
|
|
2
988
|
var USAGE_KEYS = ["input", "output", "cacheRead", "cacheWrite", "reasoning", "total"];
|
|
3
989
|
function addUsage(sum2, u) {
|
|
@@ -8,54 +994,23 @@ function addUsage(sum2, u) {
|
|
|
8
994
|
}
|
|
9
995
|
return out;
|
|
10
996
|
}
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
);
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
);
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
);
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
);
|
|
29
|
-
var ICON_SCAN_SEARCH = svg(
|
|
30
|
-
'<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/>'
|
|
31
|
-
);
|
|
32
|
-
var ICON_GLOBE = svg(
|
|
33
|
-
'<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>'
|
|
34
|
-
);
|
|
35
|
-
var ICON_DOWNLOAD = svg(
|
|
36
|
-
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>'
|
|
37
|
-
);
|
|
38
|
-
var ICON_BLOCKS = svg(
|
|
39
|
-
'<rect width="7" height="7" x="4" y="4" rx="1"/><rect width="7" height="7" x="13" y="4" rx="1"/><rect width="7" height="7" x="4" y="13" rx="1"/><rect width="7" height="7" x="13" y="13" rx="1"/>'
|
|
40
|
-
);
|
|
41
|
-
var ICON_ZAP = svg(
|
|
42
|
-
'<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>'
|
|
43
|
-
);
|
|
44
|
-
var ICON_LIST = svg(
|
|
45
|
-
'<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>'
|
|
46
|
-
);
|
|
47
|
-
var ICON_LIST_CHECKS = svg(
|
|
48
|
-
'<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>'
|
|
49
|
-
);
|
|
50
|
-
var ICON_BOT = svg(
|
|
51
|
-
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
52
|
-
);
|
|
53
|
-
var ICON_CHART = svg(
|
|
54
|
-
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
55
|
-
);
|
|
56
|
-
var ICON_FILE_TEXT = svg(
|
|
57
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
58
|
-
);
|
|
997
|
+
var ICON_TERMINAL = iconHTML("terminal");
|
|
998
|
+
var ICON_FILE = iconHTML("file");
|
|
999
|
+
var ICON_FILE_PEN = iconHTML("edit");
|
|
1000
|
+
var ICON_FILE_PLUS = iconHTML("plus");
|
|
1001
|
+
var ICON_TRASH = iconHTML("trash");
|
|
1002
|
+
var ICON_SEARCH = iconHTML("search");
|
|
1003
|
+
var ICON_FOLDER_SEARCH = iconHTML("folder");
|
|
1004
|
+
var ICON_SCAN_SEARCH = iconHTML("search");
|
|
1005
|
+
var ICON_GLOBE = iconHTML("globe");
|
|
1006
|
+
var ICON_DOWNLOAD = iconHTML("download");
|
|
1007
|
+
var ICON_BLOCKS = iconHTML("server");
|
|
1008
|
+
var ICON_ZAP = iconHTML("sparkle");
|
|
1009
|
+
var ICON_LIST = iconHTML("list");
|
|
1010
|
+
var ICON_LIST_CHECKS = iconHTML("list");
|
|
1011
|
+
var ICON_BOT = iconHTML("agent");
|
|
1012
|
+
var ICON_CHART = iconHTML("chart-line");
|
|
1013
|
+
var ICON_FILE_TEXT = iconHTML("document");
|
|
59
1014
|
function isObj(v) {
|
|
60
1015
|
return typeof v === "object" && v !== null;
|
|
61
1016
|
}
|
|
@@ -105,32 +1060,32 @@ var sum = (fn) => {
|
|
|
105
1060
|
return (input) => fn(input) ?? "";
|
|
106
1061
|
};
|
|
107
1062
|
var BUILTIN_KINDS = {
|
|
108
|
-
shell: { label: "
|
|
109
|
-
read: { label: "
|
|
110
|
-
edit: { label: "
|
|
111
|
-
write: { label: "
|
|
112
|
-
rm: { label: "
|
|
113
|
-
grep: { label: "
|
|
114
|
-
glob: { label: "
|
|
115
|
-
browser: { label: "
|
|
116
|
-
search: { label: "
|
|
117
|
-
fetch: { label: "
|
|
1063
|
+
shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
1064
|
+
read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
1065
|
+
edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
1066
|
+
write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
1067
|
+
rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
1068
|
+
grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
1069
|
+
glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
1070
|
+
browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
1071
|
+
search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
1072
|
+
fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
118
1073
|
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
119
|
-
skill: { label: "
|
|
1074
|
+
skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
120
1075
|
todo: {
|
|
121
|
-
label: "
|
|
1076
|
+
label: t("aiCore.kindTodo"),
|
|
122
1077
|
icon: ICON_LIST,
|
|
123
1078
|
tint: "info",
|
|
124
1079
|
summarize: sum((input) => {
|
|
125
1080
|
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
126
1081
|
const done = items.filter((it) => it?.status === "done").length;
|
|
127
|
-
return items.length > 0 ?
|
|
1082
|
+
return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
|
|
128
1083
|
})
|
|
129
1084
|
},
|
|
130
|
-
plan: { label: "
|
|
131
|
-
subagent: { label: "
|
|
132
|
-
note: { label: "
|
|
133
|
-
chart: { label: "
|
|
1085
|
+
plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
|
|
1086
|
+
subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
1087
|
+
note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
|
|
1088
|
+
chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
134
1089
|
};
|
|
135
1090
|
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
136
1091
|
function normalizeUsage(raw) {
|
|
@@ -185,51 +1140,45 @@ function contextEstimate(usage) {
|
|
|
185
1140
|
return (u.input ?? 0) + (u.cacheRead ?? 0) + (u.cacheWrite ?? 0) + (u.output ?? 0) + (u.reasoning ?? 0);
|
|
186
1141
|
}
|
|
187
1142
|
function h(tag, className, text) {
|
|
1143
|
+
if (typeof document === "undefined") throw new Error("h() \u4EC5\u6D4F\u89C8\u5668\u73AF\u5883\u53EF\u7528\uFF08SSR \u65F6\u7531\u8C03\u7528\u65B9\u5B88\u536B\uFF0C\u89C1\u6A21\u5757\u5934\u6CE8\u91CA\uFF09");
|
|
188
1144
|
const node = document.createElement(tag);
|
|
189
1145
|
if (className) node.className = className;
|
|
190
1146
|
if (text != null) node.textContent = text;
|
|
191
1147
|
return node;
|
|
192
1148
|
}
|
|
193
|
-
function svgIcon(
|
|
194
|
-
|
|
195
|
-
let parsed;
|
|
196
|
-
try {
|
|
197
|
-
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
198
|
-
} catch {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
const root = parsed.documentElement;
|
|
202
|
-
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
const sanitize = (el) => {
|
|
206
|
-
for (const attr of Array.from(el.attributes)) {
|
|
207
|
-
const name = attr.name.toLowerCase();
|
|
208
|
-
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
209
|
-
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
210
|
-
el.removeAttribute(attr.name);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
for (const child of Array.from(el.children)) {
|
|
214
|
-
const tag = child.tagName.toLowerCase();
|
|
215
|
-
if (tag === "script" || tag === "foreignobject") {
|
|
216
|
-
child.remove();
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
sanitize(child);
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
sanitize(root);
|
|
223
|
-
return document.importNode(root, true);
|
|
1149
|
+
function svgIcon(svg) {
|
|
1150
|
+
return parseSvg(svg);
|
|
224
1151
|
}
|
|
225
1152
|
|
|
226
1153
|
// src/behaviors/popover.ts
|
|
1154
|
+
function revealPopoverItem(item, scrollport, opts = {}) {
|
|
1155
|
+
if (typeof document === "undefined") return;
|
|
1156
|
+
if (opts.focus) item.focus({ preventScroll: true });
|
|
1157
|
+
const rect = item.getBoundingClientRect(), bounds = scrollport.getBoundingClientRect();
|
|
1158
|
+
const style = getComputedStyle(scrollport);
|
|
1159
|
+
const inset = (value, extent) => {
|
|
1160
|
+
const amount = Number.parseFloat(value) || 0;
|
|
1161
|
+
return value.endsWith("%") ? amount * extent / 100 : amount;
|
|
1162
|
+
};
|
|
1163
|
+
if (opts.axis !== "inline") {
|
|
1164
|
+
const top = bounds.top + scrollport.clientTop + inset(style.scrollPaddingTop, scrollport.clientHeight);
|
|
1165
|
+
const bottom = bounds.top + scrollport.clientTop + scrollport.clientHeight - inset(style.scrollPaddingBottom, scrollport.clientHeight);
|
|
1166
|
+
if (rect.top < top) scrollport.scrollTop -= top - rect.top;
|
|
1167
|
+
else if (rect.bottom > bottom) scrollport.scrollTop += rect.bottom - bottom;
|
|
1168
|
+
}
|
|
1169
|
+
if (opts.axis === "inline" || opts.axis === "both") {
|
|
1170
|
+
const left = bounds.left + scrollport.clientLeft + inset(style.scrollPaddingLeft, scrollport.clientWidth);
|
|
1171
|
+
const right = bounds.left + scrollport.clientLeft + scrollport.clientWidth - inset(style.scrollPaddingRight, scrollport.clientWidth);
|
|
1172
|
+
if (rect.left < left) scrollport.scrollLeft -= left - rect.left;
|
|
1173
|
+
else if (rect.right > right) scrollport.scrollLeft += rect.right - right;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
227
1176
|
var PANEL_SIZING_ATTRS = {
|
|
228
|
-
width: "data-panel-width",
|
|
229
|
-
minWidth: "data-panel-min",
|
|
230
|
-
maxWidth: "data-panel-max",
|
|
231
|
-
minHeight: "data-panel-min-height",
|
|
232
|
-
maxHeight: "data-panel-max-height"
|
|
1177
|
+
width: "data-icen-panel-width",
|
|
1178
|
+
minWidth: "data-icen-panel-min",
|
|
1179
|
+
maxWidth: "data-icen-panel-max",
|
|
1180
|
+
minHeight: "data-icen-panel-min-height",
|
|
1181
|
+
maxHeight: "data-icen-panel-max-height"
|
|
233
1182
|
};
|
|
234
1183
|
function readPanelSizing(el) {
|
|
235
1184
|
const out = {};
|
|
@@ -289,10 +1238,10 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
289
1238
|
const preferredSide = opts.side ?? "top";
|
|
290
1239
|
const align = opts.align ?? "start";
|
|
291
1240
|
if (preferredSide === "left" || preferredSide === "right") {
|
|
1241
|
+
const minWidth2 = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
292
1242
|
const availableLeft = Math.max(0, anchor.left - margin - offset);
|
|
293
1243
|
const availableRight = Math.max(0, viewport.width - anchor.right - margin - offset);
|
|
294
|
-
const side2 = (preferredSide === "left" ? availableLeft : availableRight) >=
|
|
295
|
-
const minWidth2 = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
1244
|
+
const side2 = (preferredSide === "left" ? availableLeft : availableRight) >= minWidth2 ? preferredSide : preferredSide === "left" ? "right" : "left";
|
|
296
1245
|
const maxWidth2 = Math.min(
|
|
297
1246
|
Math.max(opts.maxWidth ?? DEFAULT_MAX_WIDTH, minWidth2),
|
|
298
1247
|
side2 === "left" ? availableLeft : availableRight
|
|
@@ -321,7 +1270,7 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
321
1270
|
const minHeight = Math.min(Math.max(80, opts.minHeight ?? DEFAULT_MIN_HEIGHT), availableHeight);
|
|
322
1271
|
const requestedMaxHeight = Math.max(minHeight, opts.maxHeight ?? DEFAULT_MAX_HEIGHT);
|
|
323
1272
|
const fallbackHeight = Math.min(260, requestedMaxHeight);
|
|
324
|
-
const contentHeight =
|
|
1273
|
+
const contentHeight = opts.contentHeightHint != null && opts.contentHeightHint > 0 ? opts.contentHeightHint : fallbackHeight;
|
|
325
1274
|
const desiredHeight = clamp(contentHeight, minHeight, Math.min(requestedMaxHeight, availableHeight));
|
|
326
1275
|
const side = chooseSide(preferredSide, availableTop, availableBottom, desiredHeight);
|
|
327
1276
|
const sideSpace = side === "top" ? availableTop : availableBottom;
|
|
@@ -338,6 +1287,9 @@ function computePopoverLayout(anchor, viewport, opts = {}) {
|
|
|
338
1287
|
return { side, left, top, width, maxHeight };
|
|
339
1288
|
}
|
|
340
1289
|
var openPanels = /* @__PURE__ */ new Map();
|
|
1290
|
+
var closingPanels = /* @__PURE__ */ new Map();
|
|
1291
|
+
var EXIT_FALLBACK_MS = 240;
|
|
1292
|
+
var menuCloser = null;
|
|
341
1293
|
function rectFromElement(el) {
|
|
342
1294
|
const r = el.getBoundingClientRect();
|
|
343
1295
|
return { left: r.left, top: r.top, right: r.right, bottom: r.bottom, width: r.width, height: r.height };
|
|
@@ -355,21 +1307,54 @@ function relayout(state) {
|
|
|
355
1307
|
closePopover(state.panel);
|
|
356
1308
|
return;
|
|
357
1309
|
}
|
|
358
|
-
|
|
1310
|
+
let layout = computePopoverLayout(
|
|
359
1311
|
anchor,
|
|
360
1312
|
{ width: window.innerWidth, height: window.innerHeight },
|
|
361
1313
|
state.opts
|
|
362
1314
|
);
|
|
363
1315
|
const { panel } = state;
|
|
1316
|
+
const scrollPositions = [panel, ...panel.querySelectorAll("*")].filter((node) => node.scrollTop !== 0 || node.scrollLeft !== 0).map((node) => ({ node, top: node.scrollTop, left: node.scrollLeft }));
|
|
1317
|
+
panel.style.width = `${layout.width}px`;
|
|
1318
|
+
if (state.opts.contentHeightHint == null && (layout.side === "top" || layout.side === "bottom")) {
|
|
1319
|
+
panel.style.maxHeight = `${Math.min(state.opts.maxHeight ?? DEFAULT_MAX_HEIGHT, Math.max(80, window.innerHeight - (state.opts.margin ?? 12) * 2))}px`;
|
|
1320
|
+
const measured = panel.offsetHeight;
|
|
1321
|
+
if (measured > 0) layout = computePopoverLayout(anchor, { width: window.innerWidth, height: window.innerHeight }, { ...state.opts, contentHeightHint: measured });
|
|
1322
|
+
}
|
|
364
1323
|
panel.style.left = `${layout.left}px`;
|
|
365
|
-
panel.style.top = `${layout.top}px`;
|
|
366
1324
|
panel.style.width = `${layout.width}px`;
|
|
367
1325
|
panel.style.maxHeight = `${layout.maxHeight}px`;
|
|
368
|
-
|
|
1326
|
+
let top = layout.top;
|
|
1327
|
+
const actualHeight = panel.offsetHeight;
|
|
1328
|
+
if (actualHeight > 0 && (layout.side === "top" || layout.side === "bottom")) {
|
|
1329
|
+
const desired = layout.side === "top" ? anchor.top - (state.opts.offset ?? 8) - actualHeight : anchor.bottom + (state.opts.offset ?? 8);
|
|
1330
|
+
const margin = state.opts.margin ?? 12;
|
|
1331
|
+
top = clamp(desired, margin, window.innerHeight - margin - actualHeight);
|
|
1332
|
+
}
|
|
1333
|
+
panel.style.top = `${top}px`;
|
|
1334
|
+
for (const pos of scrollPositions) {
|
|
1335
|
+
pos.node.scrollTop = pos.top;
|
|
1336
|
+
pos.node.scrollLeft = pos.left;
|
|
1337
|
+
}
|
|
1338
|
+
panel.dataset.icenSide = layout.side;
|
|
369
1339
|
panel.style.visibility = state.prevVisibility;
|
|
370
1340
|
}
|
|
371
|
-
function
|
|
372
|
-
|
|
1341
|
+
function observeOpenPanel(state) {
|
|
1342
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
1343
|
+
state.resizeObserver = new ResizeObserver(() => {
|
|
1344
|
+
if (state.layoutFrame != null) return;
|
|
1345
|
+
state.layoutFrame = window.requestAnimationFrame(() => {
|
|
1346
|
+
state.layoutFrame = void 0;
|
|
1347
|
+
if (openPanels.get(state.panel) === state) relayout(state);
|
|
1348
|
+
});
|
|
1349
|
+
});
|
|
1350
|
+
state.resizeObserver.observe(state.panel);
|
|
1351
|
+
if (state.anchor instanceof Element) state.resizeObserver.observe(state.anchor);
|
|
1352
|
+
}
|
|
1353
|
+
function onWindowChange(event) {
|
|
1354
|
+
openPanels.forEach((state) => {
|
|
1355
|
+
if (event?.type === "scroll" && event.target instanceof Node && state.panel.contains(event.target)) return;
|
|
1356
|
+
relayout(state);
|
|
1357
|
+
});
|
|
373
1358
|
}
|
|
374
1359
|
function onOutsidePointerDown(e) {
|
|
375
1360
|
const target = e.target;
|
|
@@ -381,18 +1366,40 @@ function onOutsidePointerDown(e) {
|
|
|
381
1366
|
});
|
|
382
1367
|
}
|
|
383
1368
|
function onKeyDown(e) {
|
|
384
|
-
if (e.key !== "Escape") return;
|
|
1369
|
+
if (e.key !== "Escape" || e.defaultPrevented || e.isComposing || e.keyCode === 229 || menuCloser) return;
|
|
385
1370
|
const states = Array.from(openPanels.values());
|
|
386
1371
|
const top = states[states.length - 1];
|
|
387
1372
|
if (top) {
|
|
388
1373
|
e.preventDefault();
|
|
1374
|
+
e.stopPropagation();
|
|
389
1375
|
closePopover(top.panel);
|
|
390
1376
|
}
|
|
391
1377
|
}
|
|
392
1378
|
function openPopover(panel, options) {
|
|
393
1379
|
if (typeof document === "undefined") return;
|
|
1380
|
+
const pending = closingPanels.get(panel);
|
|
1381
|
+
if (pending) {
|
|
1382
|
+
window.clearTimeout(pending.timer);
|
|
1383
|
+
panel.removeEventListener("transitionend", pending.onEnd);
|
|
1384
|
+
closingPanels.delete(panel);
|
|
1385
|
+
delete panel.dataset.icenState;
|
|
1386
|
+
openPanels.set(panel, pending.state);
|
|
1387
|
+
panel.hidden = false;
|
|
1388
|
+
panel.style.visibility = "hidden";
|
|
1389
|
+
relayout(pending.state);
|
|
1390
|
+
observeOpenPanel(pending.state);
|
|
1391
|
+
if (openPanels.size === 1) {
|
|
1392
|
+
window.addEventListener("resize", onWindowChange);
|
|
1393
|
+
window.addEventListener("scroll", onWindowChange, true);
|
|
1394
|
+
document.addEventListener("pointerdown", onOutsidePointerDown, true);
|
|
1395
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
1396
|
+
}
|
|
1397
|
+
const ifs = options.initialFocus;
|
|
1398
|
+
if (ifs && panel.contains(ifs)) ifs.focus({ preventScroll: true });
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
394
1401
|
if (openPanels.has(panel)) closePopover(panel);
|
|
395
|
-
const { anchor, onClose, sizing, ...rest } = options;
|
|
1402
|
+
const { anchor, onClose, sizing, initialFocus, restoreFocus, ...rest } = options;
|
|
396
1403
|
const layoutOpts = sizingToLayout(resolvePanelSizing(panel, sizing), rest);
|
|
397
1404
|
const placeholder = document.createComment("popover-anchor");
|
|
398
1405
|
panel.parentNode?.insertBefore(placeholder, panel);
|
|
@@ -405,25 +1412,25 @@ function openPopover(panel, options) {
|
|
|
405
1412
|
onClose,
|
|
406
1413
|
placeholder,
|
|
407
1414
|
wasHidden,
|
|
408
|
-
prevVisibility
|
|
1415
|
+
prevVisibility,
|
|
1416
|
+
returnFocus: restoreFocus === false ? null : anchor instanceof HTMLElement ? anchor : document.activeElement instanceof HTMLElement ? document.activeElement : null
|
|
409
1417
|
};
|
|
410
1418
|
openPanels.set(panel, state);
|
|
411
1419
|
document.body.appendChild(panel);
|
|
412
1420
|
panel.hidden = false;
|
|
413
1421
|
panel.style.visibility = "hidden";
|
|
414
1422
|
relayout(state);
|
|
1423
|
+
observeOpenPanel(state);
|
|
1424
|
+
if (initialFocus && panel.contains(initialFocus)) initialFocus.focus({ preventScroll: true });
|
|
415
1425
|
if (openPanels.size === 1) {
|
|
416
1426
|
window.addEventListener("resize", onWindowChange);
|
|
417
1427
|
window.addEventListener("scroll", onWindowChange, true);
|
|
418
1428
|
document.addEventListener("pointerdown", onOutsidePointerDown, true);
|
|
419
|
-
window.addEventListener("keydown", onKeyDown);
|
|
1429
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
420
1430
|
}
|
|
421
1431
|
}
|
|
422
|
-
function
|
|
423
|
-
|
|
424
|
-
const state = openPanels.get(panel);
|
|
425
|
-
if (!state) return;
|
|
426
|
-
openPanels.delete(panel);
|
|
1432
|
+
function finalizeClose(panel, state) {
|
|
1433
|
+
delete panel.dataset.icenState;
|
|
427
1434
|
panel.style.visibility = state.prevVisibility;
|
|
428
1435
|
if (typeof state.wasHidden === "string") panel.setAttribute("hidden", state.wasHidden);
|
|
429
1436
|
else panel.hidden = state.wasHidden;
|
|
@@ -431,37 +1438,66 @@ function closePopover(panel) {
|
|
|
431
1438
|
panel.style.top = "";
|
|
432
1439
|
panel.style.width = "";
|
|
433
1440
|
panel.style.maxHeight = "";
|
|
434
|
-
delete panel.dataset.
|
|
1441
|
+
delete panel.dataset.icenSide;
|
|
435
1442
|
if (state.placeholder.parentNode) {
|
|
436
1443
|
state.placeholder.parentNode.insertBefore(panel, state.placeholder);
|
|
437
1444
|
state.placeholder.remove();
|
|
438
1445
|
}
|
|
1446
|
+
}
|
|
1447
|
+
function closePopover(panel, opts) {
|
|
1448
|
+
if (typeof document === "undefined") return;
|
|
1449
|
+
const state = openPanels.get(panel);
|
|
1450
|
+
if (!state) return;
|
|
1451
|
+
openPanels.delete(panel);
|
|
1452
|
+
state.resizeObserver?.disconnect();
|
|
1453
|
+
if (state.layoutFrame != null) {
|
|
1454
|
+
window.cancelAnimationFrame(state.layoutFrame);
|
|
1455
|
+
state.layoutFrame = void 0;
|
|
1456
|
+
}
|
|
1457
|
+
const ownsFocus = panel.contains(document.activeElement);
|
|
1458
|
+
if (ownsFocus && state.returnFocus?.isConnected) state.returnFocus.focus({ preventScroll: true });
|
|
439
1459
|
if (openPanels.size === 0) {
|
|
440
1460
|
window.removeEventListener("resize", onWindowChange);
|
|
441
1461
|
window.removeEventListener("scroll", onWindowChange, true);
|
|
442
1462
|
document.removeEventListener("pointerdown", onOutsidePointerDown, true);
|
|
443
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
1463
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
444
1464
|
}
|
|
445
1465
|
state.onClose?.();
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
)
|
|
1466
|
+
const calm = opts?.immediate || typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1467
|
+
if (calm || !panel.isConnected) {
|
|
1468
|
+
finalizeClose(panel, state);
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
panel.dataset.icenState = "closing";
|
|
1472
|
+
const finalize = () => {
|
|
1473
|
+
const pending = closingPanels.get(panel);
|
|
1474
|
+
if (!pending || pending.state !== state) return;
|
|
1475
|
+
window.clearTimeout(pending.timer);
|
|
1476
|
+
panel.removeEventListener("transitionend", pending.onEnd);
|
|
1477
|
+
closingPanels.delete(panel);
|
|
1478
|
+
finalizeClose(panel, state);
|
|
1479
|
+
};
|
|
1480
|
+
const onEnd = (event) => {
|
|
1481
|
+
if (event.target === panel && event.propertyName === "opacity") finalize();
|
|
1482
|
+
};
|
|
1483
|
+
panel.addEventListener("transitionend", onEnd);
|
|
1484
|
+
closingPanels.set(panel, {
|
|
1485
|
+
state,
|
|
1486
|
+
timer: window.setTimeout(finalize, EXIT_FALLBACK_MS),
|
|
1487
|
+
onEnd
|
|
1488
|
+
});
|
|
453
1489
|
}
|
|
454
1490
|
|
|
455
1491
|
// src/behaviors/ai-panel.ts
|
|
456
1492
|
function buildTodoHead(done, total) {
|
|
457
|
-
const head = h("div", "ai-todo-head");
|
|
458
|
-
head.appendChild(h("span", "ai-todo-progress", `${done}/${total}`));
|
|
459
|
-
const bar = h("div", "ai-todo-bar");
|
|
1493
|
+
const head = h("div", "icen-ai-todo-head");
|
|
1494
|
+
head.appendChild(h("span", "icen-ai-todo-progress", `${done}/${total}`));
|
|
1495
|
+
const bar = h("div", "icen-ai-todo-bar");
|
|
460
1496
|
bar.setAttribute("role", "progressbar");
|
|
461
1497
|
bar.setAttribute("aria-valuemin", "0");
|
|
462
1498
|
bar.setAttribute("aria-valuemax", String(total));
|
|
463
1499
|
bar.setAttribute("aria-valuenow", String(done));
|
|
464
|
-
bar.setAttribute("aria-label", "
|
|
1500
|
+
bar.setAttribute("aria-label", t("aiPanel.taskProgress"));
|
|
465
1501
|
const fill = document.createElement("i");
|
|
466
1502
|
fill.style.width = total > 0 ? `${Math.round(done / total * 100)}%` : "0%";
|
|
467
1503
|
bar.appendChild(fill);
|
|
@@ -470,22 +1506,22 @@ function buildTodoHead(done, total) {
|
|
|
470
1506
|
}
|
|
471
1507
|
var ICON_TODO_CHECK = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="m3.5 12.5 5 5L20.5 6" pathLength="1"/></svg>';
|
|
472
1508
|
function buildTodoItem(item, index) {
|
|
473
|
-
const row = h("div", `ai-todo-item is-${item.status}`);
|
|
474
|
-
row.dataset.
|
|
475
|
-
row.appendChild(h("span", "ai-item-status"));
|
|
476
|
-
const check = h("span", "ai-todo-check is-anim");
|
|
1509
|
+
const row = h("div", `icen-ai-todo-item is-${item.status}`);
|
|
1510
|
+
row.dataset.icenIndex = String(index);
|
|
1511
|
+
row.appendChild(h("span", "icen-ai-item-status"));
|
|
1512
|
+
const check = h("span", "icen-ai-todo-check is-anim");
|
|
477
1513
|
check.setAttribute("aria-hidden", "true");
|
|
478
1514
|
const checkSvg = svgIcon(ICON_TODO_CHECK);
|
|
479
1515
|
if (checkSvg) check.appendChild(checkSvg);
|
|
480
1516
|
row.appendChild(check);
|
|
481
|
-
row.appendChild(h("span", "ai-todo-text", item.content));
|
|
482
|
-
row.appendChild(h("span", "ai-todo-active", item.activeForm ?? item.content));
|
|
1517
|
+
row.appendChild(h("span", "icen-ai-todo-text", item.content));
|
|
1518
|
+
row.appendChild(h("span", "icen-ai-todo-active", item.activeForm ?? item.content));
|
|
483
1519
|
return row;
|
|
484
1520
|
}
|
|
485
1521
|
function renderAiTodo(el, items) {
|
|
486
1522
|
if (typeof document === "undefined") return el;
|
|
487
1523
|
el.textContent = "";
|
|
488
|
-
const root = h("div", "ai-todo");
|
|
1524
|
+
const root = h("div", "icen-ai-todo");
|
|
489
1525
|
const list = Array.isArray(items) ? items : [];
|
|
490
1526
|
const done = list.filter((i) => i.status === "done").length;
|
|
491
1527
|
root.appendChild(buildTodoHead(done, list.length));
|
|
@@ -510,38 +1546,38 @@ function renderAiUsage(el, usage, opts = {}) {
|
|
|
510
1546
|
if (typeof document === "undefined") return el;
|
|
511
1547
|
const u = normalizeUsage(usage);
|
|
512
1548
|
const segs = [
|
|
513
|
-
{ key: "input", className: "ai-usage-seg--input", label: "
|
|
514
|
-
{ key: "output", className: "ai-usage-seg--output", label: "
|
|
515
|
-
{ key: "cacheRead", className: "ai-usage-seg--cache-read", label: "
|
|
516
|
-
{ key: "cacheWrite", className: "ai-usage-seg--cache-write", label: "
|
|
517
|
-
{ key: "reasoning", className: "ai-usage-seg--reasoning", label: "
|
|
1549
|
+
{ key: "input", className: "icen-ai-usage-seg--input", label: t("common.input"), value: u.input ?? 0 },
|
|
1550
|
+
{ key: "output", className: "icen-ai-usage-seg--output", label: t("common.output"), value: u.output ?? 0 },
|
|
1551
|
+
{ key: "cacheRead", className: "icen-ai-usage-seg--cache-read", label: t("aiPanel.cacheRead"), value: u.cacheRead ?? 0 },
|
|
1552
|
+
{ key: "cacheWrite", className: "icen-ai-usage-seg--cache-write", label: t("aiPanel.cacheWrite"), value: u.cacheWrite ?? 0 },
|
|
1553
|
+
{ key: "reasoning", className: "icen-ai-usage-seg--reasoning", label: t("aiPanel.reasoning"), value: u.reasoning ?? 0 }
|
|
518
1554
|
];
|
|
519
1555
|
const activeSegs = segs.filter((s) => s.value > 0);
|
|
520
1556
|
const sum2 = activeSegs.reduce((acc, s) => acc + s.value, 0);
|
|
521
1557
|
const total = u.total ?? sum2;
|
|
522
1558
|
el.textContent = "";
|
|
523
|
-
const root = h("div", "ai-usage");
|
|
524
|
-
const bar = h("div", "ai-usage-bar");
|
|
525
|
-
const summary = activeSegs.length > 0 ? activeSegs.map((s) => `${s.label} ${formatTokens(s.value)}`).join("\uFF0C") : "
|
|
1559
|
+
const root = h("div", "icen-ai-usage");
|
|
1560
|
+
const bar = h("div", "icen-ai-usage-bar");
|
|
1561
|
+
const summary = activeSegs.length > 0 ? activeSegs.map((s) => `${s.label} ${formatTokens(s.value)}`).join("\uFF0C") : t("aiPanel.noUsage");
|
|
526
1562
|
bar.setAttribute("role", "img");
|
|
527
|
-
bar.setAttribute("aria-label",
|
|
1563
|
+
bar.setAttribute("aria-label", t("aiPanel.usageAria", { p0: summary }));
|
|
528
1564
|
for (const s of activeSegs) {
|
|
529
1565
|
const seg = document.createElement("i");
|
|
530
|
-
seg.className = `ai-usage-seg ${s.className}`;
|
|
1566
|
+
seg.className = `icen-ai-usage-seg ${s.className}`;
|
|
531
1567
|
seg.style.width = sum2 > 0 ? `${s.value / sum2 * 100}%` : "0%";
|
|
532
1568
|
bar.appendChild(seg);
|
|
533
1569
|
}
|
|
534
1570
|
root.appendChild(bar);
|
|
535
1571
|
if (activeSegs.length > 0) {
|
|
536
|
-
const legend = h("div", "ai-usage-legend");
|
|
1572
|
+
const legend = h("div", "icen-ai-usage-legend");
|
|
537
1573
|
for (const s of activeSegs) {
|
|
538
|
-
const item = h("span", "ai-usage-legend-item");
|
|
1574
|
+
const item = h("span", "icen-ai-usage-legend-item");
|
|
539
1575
|
const dot = document.createElement("i");
|
|
540
|
-
dot.className = `ai-usage-dot ${s.className}`;
|
|
1576
|
+
dot.className = `icen-ai-usage-dot ${s.className}`;
|
|
541
1577
|
dot.setAttribute("aria-hidden", "true");
|
|
542
1578
|
item.appendChild(dot);
|
|
543
|
-
item.appendChild(h("span", "ai-usage-legend-label", s.label));
|
|
544
|
-
item.appendChild(h("span", "ai-usage-legend-value", formatTokens(s.value)));
|
|
1579
|
+
item.appendChild(h("span", "icen-ai-usage-legend-label", s.label));
|
|
1580
|
+
item.appendChild(h("span", "icen-ai-usage-legend-value", formatTokens(s.value)));
|
|
545
1581
|
legend.appendChild(item);
|
|
546
1582
|
}
|
|
547
1583
|
root.appendChild(legend);
|
|
@@ -553,7 +1589,7 @@ function renderAiUsage(el, usage, opts = {}) {
|
|
|
553
1589
|
if (ttft != null) metricBits.push(`TTFT ${formatDuration(ttft)}`);
|
|
554
1590
|
if (tps != null && tps > 0) metricBits.push(`${trimNum(tps)} tok/s`);
|
|
555
1591
|
if (finish) metricBits.push(`finish: ${finish}`);
|
|
556
|
-
if (metricBits.length > 0) root.appendChild(h("div", "ai-usage-metrics", metricBits.join(" \xB7 ")));
|
|
1592
|
+
if (metricBits.length > 0) root.appendChild(h("div", "icen-ai-usage-metrics", metricBits.join(" \xB7 ")));
|
|
557
1593
|
const totalParts = [formatTokens(total)];
|
|
558
1594
|
if (typeof opts.total === "number" && opts.total > 0) {
|
|
559
1595
|
const pct = Math.min(100, Math.round(total / opts.total * 100));
|
|
@@ -562,7 +1598,7 @@ function renderAiUsage(el, usage, opts = {}) {
|
|
|
562
1598
|
if (typeof opts.cost === "number" && Number.isFinite(opts.cost)) {
|
|
563
1599
|
totalParts.push(` \xB7 $${opts.cost.toFixed(4)}`);
|
|
564
1600
|
}
|
|
565
|
-
root.appendChild(h("div", "ai-usage-total", totalParts.join("")));
|
|
1601
|
+
root.appendChild(h("div", "icen-ai-usage-total", totalParts.join("")));
|
|
566
1602
|
el.appendChild(root);
|
|
567
1603
|
return el;
|
|
568
1604
|
}
|
|
@@ -573,31 +1609,33 @@ function renderAiUsageRing(el, usage, opts = {}) {
|
|
|
573
1609
|
const hasLimit = typeof opts.total === "number" && opts.total > 0;
|
|
574
1610
|
const pct = hasLimit ? Math.min(100, Math.max(0, Math.round(used / opts.total * 100))) : 0;
|
|
575
1611
|
el.textContent = "";
|
|
576
|
-
const btn = h("button", "ai-usage-ring");
|
|
1612
|
+
const btn = h("button", "icen-ai-usage-ring");
|
|
577
1613
|
btn.type = "button";
|
|
578
1614
|
btn.classList.add(pct >= 85 ? "is-hot" : pct >= 60 ? "is-warn" : "is-ok");
|
|
579
1615
|
btn.setAttribute("aria-haspopup", "true");
|
|
580
1616
|
btn.setAttribute(
|
|
581
1617
|
"aria-label",
|
|
582
|
-
hasLimit ?
|
|
1618
|
+
hasLimit ? t("aiPanel.ringPercent", { p0: pct }) : t("aiPanel.ringUsed", { p0: formatTokens(used) })
|
|
583
1619
|
);
|
|
584
1620
|
const NS = "http://www.w3.org/2000/svg";
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
1621
|
+
const svg = document.createElementNS(NS, "svg");
|
|
1622
|
+
svg.setAttribute("viewBox", "0 0 36 36");
|
|
1623
|
+
svg.setAttribute("width", "36");
|
|
1624
|
+
svg.setAttribute("height", "36");
|
|
1625
|
+
svg.setAttribute("aria-hidden", "true");
|
|
588
1626
|
const track = document.createElementNS(NS, "circle");
|
|
589
|
-
track.setAttribute("class", "ai-usage-ring-track");
|
|
1627
|
+
track.setAttribute("class", "icen-ai-usage-ring-track");
|
|
590
1628
|
const fill = document.createElementNS(NS, "circle");
|
|
591
|
-
fill.setAttribute("class", "ai-usage-ring-fill");
|
|
1629
|
+
fill.setAttribute("class", "icen-ai-usage-ring-fill");
|
|
592
1630
|
fill.setAttribute("stroke-dasharray", `${pct} 100`);
|
|
593
1631
|
for (const c of [track, fill]) {
|
|
594
1632
|
c.setAttribute("cx", "18");
|
|
595
1633
|
c.setAttribute("cy", "18");
|
|
596
1634
|
c.setAttribute("r", "15.9155");
|
|
597
|
-
|
|
1635
|
+
svg.appendChild(c);
|
|
598
1636
|
}
|
|
599
|
-
btn.appendChild(
|
|
600
|
-
btn.appendChild(h("span", "ai-usage-ring-pct", hasLimit ? `${pct}%` : formatTokens(used)));
|
|
1637
|
+
btn.appendChild(svg);
|
|
1638
|
+
btn.appendChild(h("span", "icen-ai-usage-ring-pct", hasLimit ? `${pct}%` : formatTokens(used)));
|
|
601
1639
|
let panel = null;
|
|
602
1640
|
const closePanel = () => {
|
|
603
1641
|
if (!panel) return;
|
|
@@ -611,9 +1649,9 @@ function renderAiUsageRing(el, usage, opts = {}) {
|
|
|
611
1649
|
closePanel();
|
|
612
1650
|
return;
|
|
613
1651
|
}
|
|
614
|
-
const p = h("div", "popover ai-usage-popover");
|
|
1652
|
+
const p = h("div", "icen-popover icen-ai-usage-popover");
|
|
615
1653
|
p.hidden = true;
|
|
616
|
-
p.appendChild(h("div", "ai-usage-popover-title", opts.title ?? "
|
|
1654
|
+
p.appendChild(h("div", "icen-ai-usage-popover-title", opts.title ?? t("aiPanel.contextWindow")));
|
|
617
1655
|
const body = h("div", "ai-usage-popover-body");
|
|
618
1656
|
renderAiUsage(body, usage, opts);
|
|
619
1657
|
p.appendChild(body);
|
|
@@ -650,26 +1688,26 @@ var ICON_SPARKLES = svgWrap(
|
|
|
650
1688
|
);
|
|
651
1689
|
|
|
652
1690
|
// src/behaviors/ai-chat.ts
|
|
653
|
-
var ICON_COPY =
|
|
654
|
-
var ICON_RETRY =
|
|
1691
|
+
var ICON_COPY = iconHTML("copy");
|
|
1692
|
+
var ICON_RETRY = iconHTML("refresh");
|
|
655
1693
|
function emit(target, name, detail) {
|
|
656
1694
|
emitIcen(target, name, detail);
|
|
657
1695
|
}
|
|
658
1696
|
var REASONING_AUTO_CLOSE_MS = 1e3;
|
|
659
1697
|
function setReasoningOpen(reasoning, open) {
|
|
660
|
-
const head = reasoning.querySelector(".ai-reasoning-head");
|
|
661
|
-
const body = reasoning.querySelector(".ai-reasoning-body");
|
|
1698
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1699
|
+
const body = reasoning.querySelector(".icen-ai-reasoning-body");
|
|
662
1700
|
head?.setAttribute("aria-expanded", String(open));
|
|
663
1701
|
reasoning.classList.toggle("is-open", open);
|
|
664
1702
|
if (body) body.hidden = !open;
|
|
665
1703
|
}
|
|
666
1704
|
function clearContinueSlot(scope) {
|
|
667
|
-
scope?.querySelectorAll(".ai-msg-continue").forEach((n) => n.remove());
|
|
1705
|
+
scope?.querySelectorAll(".icen-ai-msg-continue").forEach((n) => n.remove());
|
|
668
1706
|
}
|
|
669
1707
|
function createAiStream(el) {
|
|
670
|
-
const reasoning = el.closest(".ai-reasoning");
|
|
671
|
-
const msgBody = el.closest(".ai-msg-body");
|
|
672
|
-
const msg = el.closest(".ai-msg");
|
|
1708
|
+
const reasoning = el.closest(".icen-ai-reasoning");
|
|
1709
|
+
const msgBody = el.closest(".icen-ai-msg-body");
|
|
1710
|
+
const msg = el.closest(".icen-ai-msg");
|
|
673
1711
|
const startedAt = Date.now();
|
|
674
1712
|
let state = "streaming";
|
|
675
1713
|
el.classList.add("is-streaming");
|
|
@@ -677,18 +1715,18 @@ function createAiStream(el) {
|
|
|
677
1715
|
if (reasoning) {
|
|
678
1716
|
reasoning.classList.add("is-streaming");
|
|
679
1717
|
setReasoningOpen(reasoning, true);
|
|
680
|
-
const head = reasoning.querySelector(".ai-reasoning-head");
|
|
681
|
-
if (head && head.dataset.
|
|
1718
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1719
|
+
if (head && head.dataset.icenReasoningStart == null) head.dataset.icenReasoningStart = String(startedAt);
|
|
682
1720
|
}
|
|
683
1721
|
clearContinueSlot(msg ?? msgBody ?? el);
|
|
684
1722
|
const fillReasoningTime = () => {
|
|
685
1723
|
if (!reasoning) return;
|
|
686
|
-
const time = reasoning.querySelector(".ai-reasoning-time");
|
|
1724
|
+
const time = reasoning.querySelector(".icen-ai-reasoning-time");
|
|
687
1725
|
if (!time) return;
|
|
688
|
-
const head = reasoning.querySelector(".ai-reasoning-head");
|
|
689
|
-
const raw = Number(head?.dataset.
|
|
1726
|
+
const head = reasoning.querySelector(".icen-ai-reasoning-head");
|
|
1727
|
+
const raw = Number(head?.dataset.icenReasoningStart ?? "");
|
|
690
1728
|
const t0 = Number.isFinite(raw) && raw > 0 ? raw : startedAt;
|
|
691
|
-
time.textContent =
|
|
1729
|
+
time.textContent = t("aiChat.thinking", { p0: formatDuration(Math.max(0, Date.now() - t0)) });
|
|
692
1730
|
};
|
|
693
1731
|
const scheduleReasoningAutoClose = () => {
|
|
694
1732
|
if (!reasoning) return;
|
|
@@ -708,11 +1746,11 @@ function createAiStream(el) {
|
|
|
708
1746
|
const appendContinueSlot = () => {
|
|
709
1747
|
if (typeof document === "undefined") return;
|
|
710
1748
|
const mount = msgBody ?? msg ?? (el.parentElement instanceof HTMLElement ? el.parentElement : null);
|
|
711
|
-
if (!mount || mount.querySelector(":scope > .ai-msg-continue")) return;
|
|
1749
|
+
if (!mount || mount.querySelector(":scope > .icen-ai-msg-continue")) return;
|
|
712
1750
|
const btn = document.createElement("button");
|
|
713
1751
|
btn.type = "button";
|
|
714
|
-
btn.className = "ai-msg-continue";
|
|
715
|
-
btn.textContent = "
|
|
1752
|
+
btn.className = "icen-ai-msg-continue";
|
|
1753
|
+
btn.textContent = t("aiChat.continue");
|
|
716
1754
|
btn.addEventListener("click", () => {
|
|
717
1755
|
const target = msg ?? btn;
|
|
718
1756
|
emit(target, "icen:ai-retry", { el: target });
|
|
@@ -758,10 +1796,10 @@ function createAiStream(el) {
|
|
|
758
1796
|
};
|
|
759
1797
|
}
|
|
760
1798
|
var ROLE_AVATAR = {
|
|
761
|
-
user: "
|
|
1799
|
+
user: t("aiChat.roleUser"),
|
|
762
1800
|
assistant: "AI",
|
|
763
|
-
system: "
|
|
764
|
-
tool: "
|
|
1801
|
+
system: t("aiChat.roleSystem"),
|
|
1802
|
+
tool: t("aiChat.roleTool")
|
|
765
1803
|
};
|
|
766
1804
|
function safeHref(uri) {
|
|
767
1805
|
const s = uri.trim().toLowerCase();
|
|
@@ -770,7 +1808,7 @@ function safeHref(uri) {
|
|
|
770
1808
|
}
|
|
771
1809
|
function renderAiContentPart(part) {
|
|
772
1810
|
if (part.type === "text") {
|
|
773
|
-
const span = h("span", "ai-msg-text");
|
|
1811
|
+
const span = h("span", "icen-ai-msg-text");
|
|
774
1812
|
span.textContent = part.text;
|
|
775
1813
|
if (part.state === "streaming") span.classList.add("is-streaming");
|
|
776
1814
|
return span;
|
|
@@ -779,7 +1817,7 @@ function renderAiContentPart(part) {
|
|
|
779
1817
|
const src = aiContentUrl(part);
|
|
780
1818
|
if (!src) return void 0;
|
|
781
1819
|
const img = document.createElement("img");
|
|
782
|
-
img.className = "ai-msg-media ai-msg-media--image";
|
|
1820
|
+
img.className = "icen-ai-msg-media icen-ai-msg-media--image";
|
|
783
1821
|
img.alt = part.alt ?? "";
|
|
784
1822
|
img.setAttribute("loading", "lazy");
|
|
785
1823
|
img.setAttribute("src", src);
|
|
@@ -789,7 +1827,7 @@ function renderAiContentPart(part) {
|
|
|
789
1827
|
const src = aiContentUrl(part);
|
|
790
1828
|
if (!src) return void 0;
|
|
791
1829
|
const audio = document.createElement("audio");
|
|
792
|
-
audio.className = "ai-msg-media ai-msg-media--audio";
|
|
1830
|
+
audio.className = "icen-ai-msg-media icen-ai-msg-media--audio";
|
|
793
1831
|
audio.controls = true;
|
|
794
1832
|
audio.setAttribute("src", src);
|
|
795
1833
|
return audio;
|
|
@@ -798,28 +1836,28 @@ function renderAiContentPart(part) {
|
|
|
798
1836
|
const src = aiContentUrl(part);
|
|
799
1837
|
if (!src) return void 0;
|
|
800
1838
|
const video = document.createElement("video");
|
|
801
|
-
video.className = "ai-msg-media ai-msg-media--video";
|
|
1839
|
+
video.className = "icen-ai-msg-media icen-ai-msg-media--video";
|
|
802
1840
|
video.controls = true;
|
|
803
1841
|
video.setAttribute("playsinline", "");
|
|
804
1842
|
video.setAttribute("src", src);
|
|
805
1843
|
return video;
|
|
806
1844
|
}
|
|
807
1845
|
if (part.type === "file") {
|
|
808
|
-
const chip = h("span", "ai-msg-file");
|
|
809
|
-
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? "
|
|
1846
|
+
const chip = h("span", "icen-ai-msg-file");
|
|
1847
|
+
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? t("aiChat.file")));
|
|
810
1848
|
const href2 = part.url ? safeHref(part.url) : void 0;
|
|
811
1849
|
if (href2 && /^(https?:|data:)/i.test(href2)) {
|
|
812
1850
|
const a2 = document.createElement("a");
|
|
813
|
-
a2.className = "ai-msg-file-link";
|
|
1851
|
+
a2.className = "icen-ai-msg-file-link";
|
|
814
1852
|
a2.href = href2;
|
|
815
1853
|
a2.download = part.filename ?? "";
|
|
816
|
-
a2.textContent = "
|
|
1854
|
+
a2.textContent = t("aiChat.download");
|
|
817
1855
|
chip.appendChild(a2);
|
|
818
1856
|
}
|
|
819
1857
|
return chip;
|
|
820
1858
|
}
|
|
821
1859
|
const a = document.createElement("a");
|
|
822
|
-
a.className = "ai-msg-link";
|
|
1860
|
+
a.className = "icen-ai-msg-link";
|
|
823
1861
|
const href = safeHref(part.uri);
|
|
824
1862
|
if (href) a.href = href;
|
|
825
1863
|
a.textContent = part.name ?? part.uri;
|
|
@@ -836,9 +1874,9 @@ function renderAiMessage(scrollEl, model) {
|
|
|
836
1874
|
stream: () => createAiStream(scrollEl)
|
|
837
1875
|
};
|
|
838
1876
|
}
|
|
839
|
-
const row = h("div", `ai-msg ai-msg--${model.role}`);
|
|
840
|
-
const avatar = h("span", "ai-msg-avatar", ROLE_AVATAR[model.role] ?? "");
|
|
841
|
-
const body = h("div", "ai-msg-body");
|
|
1877
|
+
const row = h("div", `icen-ai-msg icen-ai-msg--${model.role}`);
|
|
1878
|
+
const avatar = h("span", "icen-ai-msg-avatar", ROLE_AVATAR[model.role] ?? "");
|
|
1879
|
+
const body = h("div", "icen-ai-msg-body");
|
|
842
1880
|
row.appendChild(avatar);
|
|
843
1881
|
row.appendChild(body);
|
|
844
1882
|
const parts = typeof model.content === "string" ? [{ type: "text", text: model.content }] : model.content;
|
|
@@ -846,21 +1884,21 @@ function renderAiMessage(scrollEl, model) {
|
|
|
846
1884
|
const node = renderAiContentPart(part);
|
|
847
1885
|
if (node) body.appendChild(node);
|
|
848
1886
|
}
|
|
849
|
-
if (model.model) body.appendChild(h("span", "ai-msg-model", model.model));
|
|
850
|
-
const metaEl = h("div", "ai-msg-meta");
|
|
1887
|
+
if (model.model) body.appendChild(h("span", "icen-ai-msg-model", model.model));
|
|
1888
|
+
const metaEl = h("div", "icen-ai-msg-meta");
|
|
851
1889
|
if (model.meta != null) metaEl.textContent = model.meta;
|
|
852
1890
|
row.appendChild(metaEl);
|
|
853
|
-
const actions = h("div", "ai-msg-actions");
|
|
1891
|
+
const actions = h("div", "icen-ai-msg-actions");
|
|
854
1892
|
const copyBtn = h("button", "ai-msg-action");
|
|
855
1893
|
copyBtn.type = "button";
|
|
856
|
-
copyBtn.setAttribute("data-ai-msg-action", "copy");
|
|
857
|
-
copyBtn.setAttribute("aria-label", "
|
|
1894
|
+
copyBtn.setAttribute("data-icen-ai-msg-action", "copy");
|
|
1895
|
+
copyBtn.setAttribute("aria-label", t("common.copy"));
|
|
858
1896
|
const copyIcon = svgIcon(ICON_COPY);
|
|
859
1897
|
if (copyIcon) copyBtn.appendChild(copyIcon);
|
|
860
1898
|
const retryBtn = h("button", "ai-msg-action");
|
|
861
1899
|
retryBtn.type = "button";
|
|
862
|
-
retryBtn.setAttribute("data-ai-msg-action", "retry");
|
|
863
|
-
retryBtn.setAttribute("aria-label", "
|
|
1900
|
+
retryBtn.setAttribute("data-icen-ai-msg-action", "retry");
|
|
1901
|
+
retryBtn.setAttribute("aria-label", t("common.retry"));
|
|
864
1902
|
const retryIcon = svgIcon(ICON_RETRY);
|
|
865
1903
|
if (retryIcon) retryBtn.appendChild(retryIcon);
|
|
866
1904
|
actions.append(copyBtn, retryBtn);
|
|
@@ -872,10 +1910,11 @@ function renderAiMessage(scrollEl, model) {
|
|
|
872
1910
|
metaEl.textContent = meta;
|
|
873
1911
|
},
|
|
874
1912
|
setError(message) {
|
|
875
|
-
row.classList.add("ai-msg--error");
|
|
876
|
-
let errEl = row.querySelector(".ai-msg-error-text");
|
|
1913
|
+
row.classList.add("icen-ai-msg--error");
|
|
1914
|
+
let errEl = row.querySelector(".icen-ai-msg-error-text");
|
|
877
1915
|
if (!errEl) {
|
|
878
|
-
errEl = h("div", "ai-msg-error-text");
|
|
1916
|
+
errEl = h("div", "icen-ai-msg-error-text");
|
|
1917
|
+
errEl.setAttribute("role", "status");
|
|
879
1918
|
body.appendChild(errEl);
|
|
880
1919
|
}
|
|
881
1920
|
errEl.textContent = message;
|
|
@@ -892,34 +1931,102 @@ function renderAiMessage(scrollEl, model) {
|
|
|
892
1931
|
return handle;
|
|
893
1932
|
}
|
|
894
1933
|
|
|
1934
|
+
// src/behaviors/input.ts
|
|
1935
|
+
var searchFields = /* @__PURE__ */ new WeakMap();
|
|
1936
|
+
function enhanceSearchField(input) {
|
|
1937
|
+
if (typeof document === "undefined" || !input.parentElement) return { refresh() {
|
|
1938
|
+
}, destroy() {
|
|
1939
|
+
} };
|
|
1940
|
+
const previous = searchFields.get(input);
|
|
1941
|
+
if (previous) return previous;
|
|
1942
|
+
const host = input.parentElement;
|
|
1943
|
+
const wasFocused = document.activeElement === input;
|
|
1944
|
+
const hadHostClass = host.classList.contains("icen-search-field");
|
|
1945
|
+
const hadInputClass = input.classList.contains("icen-search-input");
|
|
1946
|
+
const hadStandardClass = input.classList.contains("icen-input");
|
|
1947
|
+
const ownedWrap = !host.classList.contains("icen-input-wrap");
|
|
1948
|
+
const next = input.nextSibling;
|
|
1949
|
+
const wrap = ownedWrap ? document.createElement("div") : host;
|
|
1950
|
+
if (ownedWrap) {
|
|
1951
|
+
wrap.className = "icen-input-wrap icen-input-wrap--sm icen-input-wrap--search icen-control";
|
|
1952
|
+
host.insertBefore(wrap, input);
|
|
1953
|
+
wrap.append(input);
|
|
1954
|
+
}
|
|
1955
|
+
const leading = wrap.querySelector(".icen-input-leading") ? null : document.createElement("span");
|
|
1956
|
+
if (leading) {
|
|
1957
|
+
leading.className = "icen-input-leading";
|
|
1958
|
+
leading.append(createIcon("search"));
|
|
1959
|
+
wrap.prepend(leading);
|
|
1960
|
+
}
|
|
1961
|
+
host.classList.add("icen-search-field");
|
|
1962
|
+
input.classList.add("icen-search-input", "icen-input");
|
|
1963
|
+
const clear = document.createElement("button");
|
|
1964
|
+
clear.type = "button";
|
|
1965
|
+
clear.className = "icen-input-clear icen-search-clear";
|
|
1966
|
+
clear.append(createIcon("close"));
|
|
1967
|
+
wrap.append(clear);
|
|
1968
|
+
const ac = new AbortController();
|
|
1969
|
+
let disposed = false;
|
|
1970
|
+
const refresh = () => {
|
|
1971
|
+
if (disposed) return;
|
|
1972
|
+
clear.hidden = !input.value || input.disabled || input.readOnly;
|
|
1973
|
+
clear.setAttribute("aria-label", t("input.clearSearch"));
|
|
1974
|
+
};
|
|
1975
|
+
clear.addEventListener("pointerdown", (event) => event.preventDefault(), { signal: ac.signal });
|
|
1976
|
+
clear.addEventListener("click", () => {
|
|
1977
|
+
if (input.disabled || input.readOnly) return;
|
|
1978
|
+
input.value = "";
|
|
1979
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
1980
|
+
input.focus({ preventScroll: true });
|
|
1981
|
+
refresh();
|
|
1982
|
+
}, { signal: ac.signal });
|
|
1983
|
+
for (const event of ["input", "change", "focus"]) input.addEventListener(event, refresh, { signal: ac.signal });
|
|
1984
|
+
document.addEventListener("icen:locale-change", refresh, { signal: ac.signal });
|
|
1985
|
+
const observer = new MutationObserver(refresh);
|
|
1986
|
+
observer.observe(input, { attributes: true, attributeFilter: ["disabled", "readonly"] });
|
|
1987
|
+
refresh();
|
|
1988
|
+
if (wasFocused) input.focus({ preventScroll: true });
|
|
1989
|
+
const handle = { refresh, destroy() {
|
|
1990
|
+
if (disposed) return;
|
|
1991
|
+
disposed = true;
|
|
1992
|
+
observer.disconnect();
|
|
1993
|
+
ac.abort();
|
|
1994
|
+
clear.remove();
|
|
1995
|
+
leading?.remove();
|
|
1996
|
+
searchFields.delete(input);
|
|
1997
|
+
const focused = document.activeElement === input;
|
|
1998
|
+
if (ownedWrap) {
|
|
1999
|
+
host.insertBefore(input, next?.parentNode === host ? next : null);
|
|
2000
|
+
wrap.remove();
|
|
2001
|
+
}
|
|
2002
|
+
if (focused) input.focus({ preventScroll: true });
|
|
2003
|
+
if (!hadHostClass) host.classList.remove("icen-search-field");
|
|
2004
|
+
if (!hadInputClass) input.classList.remove("icen-search-input");
|
|
2005
|
+
if (!hadStandardClass) input.classList.remove("icen-input");
|
|
2006
|
+
} };
|
|
2007
|
+
searchFields.set(input, handle);
|
|
2008
|
+
return handle;
|
|
2009
|
+
}
|
|
2010
|
+
|
|
895
2011
|
// src/behaviors/ai-composer.ts
|
|
896
2012
|
var MAX_ROWS_DEFAULT = 8;
|
|
897
2013
|
var HISTORY_LIMIT = 50;
|
|
898
2014
|
var CACHE_WARN_RATIO = 0.4;
|
|
899
|
-
var SEND_ICON =
|
|
900
|
-
var STOP_ICON =
|
|
901
|
-
var ATTACH_ICON =
|
|
902
|
-
var
|
|
903
|
-
var
|
|
904
|
-
var
|
|
905
|
-
var
|
|
906
|
-
var
|
|
907
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>'
|
|
908
|
-
);
|
|
909
|
-
var ICON_FOLDER = svgWrap2(
|
|
910
|
-
'<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>'
|
|
911
|
-
);
|
|
912
|
-
var ICON_DOC = svgWrap2(
|
|
913
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
914
|
-
);
|
|
915
|
-
var ICON_BOT2 = svgWrap2(
|
|
916
|
-
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
917
|
-
);
|
|
2015
|
+
var SEND_ICON = iconHTML("arrow-up");
|
|
2016
|
+
var STOP_ICON = iconHTML("stop");
|
|
2017
|
+
var ATTACH_ICON = iconHTML("paperclip");
|
|
2018
|
+
var ICON_INFO = iconHTML("circle-info");
|
|
2019
|
+
var ICON_FILE3 = iconHTML("file");
|
|
2020
|
+
var ICON_FOLDER = iconHTML("folder");
|
|
2021
|
+
var ICON_DOC = iconHTML("document");
|
|
2022
|
+
var ICON_BOT2 = iconHTML("agent");
|
|
918
2023
|
var REF_KIND_BUILTIN = {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
2024
|
+
skill: { label: t("aiComposer.skills"), icon: iconHTML("sparkle"), order: -2 },
|
|
2025
|
+
tool: { label: t("aiComposer.tools"), icon: iconHTML("box"), order: -1 },
|
|
2026
|
+
file: { label: t("aiComposer.attachFile"), icon: ICON_FILE3, order: 0 },
|
|
2027
|
+
folder: { label: t("aiComposer.attachFolder"), icon: ICON_FOLDER, order: 1 },
|
|
2028
|
+
doc: { label: t("aiComposer.attachDoc"), icon: ICON_DOC, order: 2 },
|
|
2029
|
+
agent: { label: t("aiComposer.attachAgent"), icon: ICON_BOT2, order: 3 }
|
|
923
2030
|
};
|
|
924
2031
|
var REF_KIND_ORDER_LAST = Number.MAX_SAFE_INTEGER;
|
|
925
2032
|
var REF_KIND_REGISTRY = /* @__PURE__ */ new Map();
|
|
@@ -946,6 +2053,7 @@ function knownRefKinds(sources) {
|
|
|
946
2053
|
}
|
|
947
2054
|
var RUNNING = /* @__PURE__ */ new WeakMap();
|
|
948
2055
|
var QUEUES = /* @__PURE__ */ new WeakMap();
|
|
2056
|
+
var FILES = /* @__PURE__ */ new WeakMap();
|
|
949
2057
|
var MODELS = /* @__PURE__ */ new WeakMap();
|
|
950
2058
|
var MODEL_CTX = /* @__PURE__ */ new WeakMap();
|
|
951
2059
|
var COMMANDS = /* @__PURE__ */ new WeakMap();
|
|
@@ -964,14 +2072,14 @@ function emit2(target, name, detail) {
|
|
|
964
2072
|
emitIcen(target, name, detail);
|
|
965
2073
|
}
|
|
966
2074
|
function resolveComposer(el) {
|
|
967
|
-
return el.closest("[data-ai-composer]");
|
|
2075
|
+
return el.closest("[data-icen-ai-composer]");
|
|
968
2076
|
}
|
|
969
2077
|
function getTextarea(composer) {
|
|
970
|
-
return composer.querySelector(".ai-composer-input");
|
|
2078
|
+
return composer.querySelector(".icen-ai-composer-input");
|
|
971
2079
|
}
|
|
972
2080
|
function autosizeTa(ta) {
|
|
973
|
-
const composer = ta.closest("[data-ai-composer]");
|
|
974
|
-
const maxRows = Number(composer?.getAttribute("data-max-rows")) || MAX_ROWS_DEFAULT;
|
|
2081
|
+
const composer = ta.closest("[data-icen-ai-composer]");
|
|
2082
|
+
const maxRows = Number(composer?.getAttribute("data-icen-max-rows")) || MAX_ROWS_DEFAULT;
|
|
975
2083
|
const cs = window.getComputedStyle(ta);
|
|
976
2084
|
const lineHeight = parseFloat(cs.lineHeight) || 20;
|
|
977
2085
|
const padY = (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0);
|
|
@@ -982,51 +2090,58 @@ function autosizeTa(ta) {
|
|
|
982
2090
|
ta.style.height = `${Math.max(minH, Math.min(ta.scrollHeight, maxH))}px`;
|
|
983
2091
|
}
|
|
984
2092
|
function ensureIcons(composer) {
|
|
985
|
-
const sendBtn = composer.querySelector("[data-ai-send]");
|
|
2093
|
+
const sendBtn = composer.querySelector("[data-icen-ai-send]");
|
|
986
2094
|
if (sendBtn && !sendBtn.hasChildNodes()) {
|
|
987
2095
|
const sendWrap = document.createElement("span");
|
|
988
|
-
sendWrap.className = "ai-composer-send-icon";
|
|
989
|
-
sendWrap.dataset.
|
|
2096
|
+
sendWrap.className = "icen-ai-composer-send-icon";
|
|
2097
|
+
sendWrap.dataset.icenAiSendIcon = "send";
|
|
990
2098
|
const stopWrap = document.createElement("span");
|
|
991
|
-
stopWrap.className = "ai-composer-send-icon";
|
|
992
|
-
stopWrap.dataset.
|
|
2099
|
+
stopWrap.className = "icen-ai-composer-send-icon";
|
|
2100
|
+
stopWrap.dataset.icenAiSendIcon = "stop";
|
|
993
2101
|
const sendSvg = svgIcon(SEND_ICON);
|
|
994
2102
|
const stopSvg = svgIcon(STOP_ICON);
|
|
995
2103
|
if (sendSvg) sendWrap.appendChild(sendSvg);
|
|
996
2104
|
if (stopSvg) stopWrap.appendChild(stopSvg);
|
|
997
2105
|
sendBtn.append(sendWrap, stopWrap);
|
|
998
2106
|
}
|
|
999
|
-
const attachBtn = composer.querySelector("[data-ai-attach]");
|
|
2107
|
+
const attachBtn = composer.querySelector("[data-icen-ai-attach]");
|
|
1000
2108
|
if (attachBtn && !attachBtn.hasChildNodes()) {
|
|
1001
2109
|
const icon = svgIcon(ATTACH_ICON);
|
|
1002
2110
|
if (icon) attachBtn.appendChild(icon);
|
|
1003
2111
|
}
|
|
1004
|
-
const sendIcon = sendBtn?.querySelector('[data-ai-send-icon="send"]') ?? null;
|
|
1005
|
-
const stopIcon = sendBtn?.querySelector('[data-ai-send-icon="stop"]') ?? null;
|
|
2112
|
+
const sendIcon = sendBtn?.querySelector('[data-icen-ai-send-icon="send"]') ?? null;
|
|
2113
|
+
const stopIcon = sendBtn?.querySelector('[data-icen-ai-send-icon="stop"]') ?? null;
|
|
1006
2114
|
return { sendBtn, sendIcon, stopIcon };
|
|
1007
2115
|
}
|
|
1008
|
-
function makeChip(text, removable, ariaLabel) {
|
|
2116
|
+
function makeChip(text, removable, ariaLabel, icon) {
|
|
1009
2117
|
const chip = document.createElement("span");
|
|
1010
|
-
chip.className = "ai-composer-chip";
|
|
2118
|
+
chip.className = "icen-ai-composer-chip";
|
|
2119
|
+
if (icon) {
|
|
2120
|
+
const mark = document.createElement("span");
|
|
2121
|
+
mark.className = "icen-ai-composer-chip-icon";
|
|
2122
|
+
const svg = createIcon(icon);
|
|
2123
|
+
if (svg) mark.append(svg);
|
|
2124
|
+
chip.append(mark);
|
|
2125
|
+
}
|
|
1011
2126
|
const label = document.createElement("span");
|
|
1012
|
-
label.className = "ai-composer-chip-text";
|
|
2127
|
+
label.className = "icen-ai-composer-chip-text";
|
|
1013
2128
|
label.textContent = text;
|
|
1014
2129
|
chip.appendChild(label);
|
|
1015
2130
|
if (removable) {
|
|
1016
2131
|
const remove = document.createElement("button");
|
|
1017
2132
|
remove.type = "button";
|
|
1018
|
-
remove.className = "ai-composer-chip-remove";
|
|
2133
|
+
remove.className = "icen-ai-composer-chip-remove";
|
|
1019
2134
|
remove.setAttribute("aria-label", ariaLabel);
|
|
1020
|
-
remove.
|
|
2135
|
+
remove.replaceChildren(createIcon("close"));
|
|
1021
2136
|
chip.appendChild(remove);
|
|
1022
2137
|
}
|
|
1023
2138
|
return chip;
|
|
1024
2139
|
}
|
|
1025
2140
|
function renderQueueChips(composer) {
|
|
1026
|
-
const queueEl = composer.querySelector(".ai-composer-queue");
|
|
2141
|
+
const queueEl = composer.querySelector(".icen-ai-composer-queue");
|
|
1027
2142
|
if (!queueEl) return;
|
|
1028
2143
|
const queue = QUEUES.get(composer) ?? [];
|
|
1029
|
-
queueEl.replaceChildren(...queue.map((
|
|
2144
|
+
queueEl.replaceChildren(...queue.map((draft, i) => makeChip(draft.text || [...draft.files?.map((f) => f.name) ?? [], ...draft.refs?.map((r) => r.label) ?? []].join(" \xB7 "), true, t("aiComposer.removeQueued", { p0: i + 1 }), "layers")));
|
|
1030
2145
|
queueEl.hidden = queue.length === 0;
|
|
1031
2146
|
}
|
|
1032
2147
|
function setComposerRunning(el, running) {
|
|
@@ -1039,24 +2154,24 @@ function setComposerRunning(el, running) {
|
|
|
1039
2154
|
} else {
|
|
1040
2155
|
composer.removeAttribute("aria-busy");
|
|
1041
2156
|
}
|
|
1042
|
-
const sendBtn = composer.querySelector("[data-ai-send]");
|
|
2157
|
+
const sendBtn = composer.querySelector("[data-icen-ai-send]");
|
|
1043
2158
|
if (!sendBtn) return;
|
|
1044
2159
|
sendBtn.classList.toggle("is-stop", running);
|
|
1045
|
-
sendBtn.setAttribute("aria-label", running ? "
|
|
1046
|
-
const sendIcon = sendBtn.querySelector('[data-ai-send-icon="send"]');
|
|
1047
|
-
const stopIcon = sendBtn.querySelector('[data-ai-send-icon="stop"]');
|
|
2160
|
+
sendBtn.setAttribute("aria-label", running ? t("aiComposer.stop") : t("aiComposer.send"));
|
|
2161
|
+
const sendIcon = sendBtn.querySelector('[data-icen-ai-send-icon="send"]');
|
|
2162
|
+
const stopIcon = sendBtn.querySelector('[data-icen-ai-send-icon="stop"]');
|
|
1048
2163
|
if (sendIcon) sendIcon.hidden = running;
|
|
1049
2164
|
if (stopIcon) stopIcon.hidden = !running;
|
|
1050
2165
|
}
|
|
1051
2166
|
function providerMark(provider, badgeClass) {
|
|
1052
2167
|
const slot = document.createElement("span");
|
|
1053
2168
|
slot.className = badgeClass;
|
|
1054
|
-
const
|
|
1055
|
-
if (
|
|
1056
|
-
slot.appendChild(
|
|
2169
|
+
const svg = provider.icon ? svgIcon(provider.icon) : null;
|
|
2170
|
+
if (svg) {
|
|
2171
|
+
slot.appendChild(svg);
|
|
1057
2172
|
} else {
|
|
1058
2173
|
const badge = document.createElement("span");
|
|
1059
|
-
badge.className = "ai-composer-model-badge";
|
|
2174
|
+
badge.className = "icen-ai-composer-model-badge";
|
|
1060
2175
|
badge.textContent = (provider.label.trim()[0] ?? "?").toUpperCase();
|
|
1061
2176
|
slot.appendChild(badge);
|
|
1062
2177
|
}
|
|
@@ -1065,8 +2180,8 @@ function providerMark(provider, badgeClass) {
|
|
|
1065
2180
|
function buildModelButton(composer) {
|
|
1066
2181
|
const btn = document.createElement("button");
|
|
1067
2182
|
btn.type = "button";
|
|
1068
|
-
btn.className = "ai-composer-model";
|
|
1069
|
-
btn.setAttribute("data-ai-model-open", "");
|
|
2183
|
+
btn.className = "icen-ai-composer-model";
|
|
2184
|
+
btn.setAttribute("data-icen-ai-model-open", "");
|
|
1070
2185
|
btn.setAttribute("aria-haspopup", "listbox");
|
|
1071
2186
|
btn.setAttribute("aria-expanded", "false");
|
|
1072
2187
|
btn.addEventListener("click", () => {
|
|
@@ -1077,66 +2192,59 @@ function buildModelButton(composer) {
|
|
|
1077
2192
|
}
|
|
1078
2193
|
function updateModelButton(composer) {
|
|
1079
2194
|
const cfg = MODELS.get(composer);
|
|
1080
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
2195
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
1081
2196
|
if (!cfg || !btn) return;
|
|
1082
2197
|
const provider = cfg.providers.find((p) => p.id === cfg.current.provider) ?? cfg.providers[0];
|
|
1083
2198
|
if (!provider) return;
|
|
1084
2199
|
const model = provider.models.find((m) => m.id === cfg.current.model) ?? provider.models[0];
|
|
1085
2200
|
if (!model) return;
|
|
1086
|
-
const iconSlot = btn.querySelector(".ai-composer-model-icon") ?? (() => {
|
|
2201
|
+
const iconSlot = btn.querySelector(".icen-ai-composer-model-icon") ?? (() => {
|
|
1087
2202
|
const slot = document.createElement("span");
|
|
1088
|
-
slot.className = "ai-composer-model-icon";
|
|
2203
|
+
slot.className = "icen-ai-composer-model-icon";
|
|
1089
2204
|
btn.prepend(slot);
|
|
1090
2205
|
return slot;
|
|
1091
2206
|
})();
|
|
1092
|
-
iconSlot.replaceChildren(providerMark(provider, "ai-composer-model-provider-icon"));
|
|
1093
|
-
let name = btn.querySelector(".ai-composer-model-name");
|
|
2207
|
+
iconSlot.replaceChildren(providerMark(provider, "icen-ai-composer-model-provider-icon"));
|
|
2208
|
+
let name = btn.querySelector(".icen-ai-composer-model-name");
|
|
1094
2209
|
if (!name) {
|
|
1095
2210
|
name = document.createElement("span");
|
|
1096
|
-
name.className = "ai-composer-model-name";
|
|
1097
|
-
btn.insertBefore(name, btn.querySelector(".ai-composer-model-chevron"));
|
|
2211
|
+
name.className = "icen-ai-composer-model-name";
|
|
2212
|
+
btn.insertBefore(name, btn.querySelector(".icen-ai-composer-model-chevron"));
|
|
1098
2213
|
}
|
|
1099
2214
|
name.textContent = model.label;
|
|
1100
|
-
btn.setAttribute("aria-label",
|
|
1101
|
-
|
|
1102
|
-
const chev = svgIcon(ICON_CHEVRON);
|
|
1103
|
-
if (chev) {
|
|
1104
|
-
const wrap = document.createElement("span");
|
|
1105
|
-
wrap.className = "ai-composer-model-chevron";
|
|
1106
|
-
wrap.appendChild(chev);
|
|
1107
|
-
btn.appendChild(wrap);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
2215
|
+
btn.setAttribute("aria-label", t("aiComposer.modelAria", { p0: model.label, p1: provider.label }));
|
|
2216
|
+
btn.querySelector(".icen-ai-composer-model-chevron")?.remove();
|
|
1110
2217
|
}
|
|
1111
2218
|
function syncToolbar(composer) {
|
|
1112
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
2219
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
1113
2220
|
if (!box || !getTextarea(composer)) return;
|
|
1114
2221
|
const modelsCfg = MODELS.get(composer);
|
|
1115
2222
|
const usageCfg = USAGE.get(composer);
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
let
|
|
2223
|
+
const hasLibrary = !!(COMMANDS.get(composer)?.length || REF_SOURCES.get(composer)?.length);
|
|
2224
|
+
if (!modelsCfg && !usageCfg && !hasLibrary && !composer.querySelector(".icen-ai-composer-toolbar")) return;
|
|
2225
|
+
let bar = composer.querySelector(".icen-ai-composer-toolbar");
|
|
2226
|
+
let modelBtn = composer.querySelector("[data-icen-ai-model-open]");
|
|
1119
2227
|
if (modelsCfg && !modelBtn) {
|
|
1120
2228
|
modelBtn = buildModelButton(composer);
|
|
1121
|
-
modelBtn.dataset.
|
|
2229
|
+
modelBtn.dataset.icenAiModelOpen = "auto";
|
|
1122
2230
|
updateModelButton(composer);
|
|
1123
2231
|
}
|
|
1124
|
-
if (!modelsCfg && modelBtn?.dataset.
|
|
2232
|
+
if (!modelsCfg && modelBtn?.dataset.icenAiModelOpen === "auto") {
|
|
1125
2233
|
modelBtn.remove();
|
|
1126
2234
|
modelBtn = null;
|
|
1127
2235
|
}
|
|
1128
|
-
let usageMount = composer.querySelector(".ai-composer-usage");
|
|
2236
|
+
let usageMount = composer.querySelector(".icen-ai-composer-usage");
|
|
1129
2237
|
if (usageCfg && !usageMount) {
|
|
1130
2238
|
usageMount = document.createElement("span");
|
|
1131
|
-
usageMount.className = "ai-composer-usage";
|
|
1132
|
-
usageMount.dataset.
|
|
2239
|
+
usageMount.className = "icen-ai-composer-usage";
|
|
2240
|
+
usageMount.dataset.icenAiUsage = "auto";
|
|
1133
2241
|
}
|
|
1134
|
-
if (!usageCfg && usageMount?.dataset.
|
|
2242
|
+
if (!usageCfg && usageMount?.dataset.icenAiUsage === "auto") {
|
|
1135
2243
|
usageMount.remove();
|
|
1136
2244
|
usageMount = null;
|
|
1137
2245
|
}
|
|
1138
|
-
const attach = composer.querySelector("[data-ai-attach]");
|
|
1139
|
-
const send = composer.querySelector("[data-ai-send]");
|
|
2246
|
+
const attach = composer.querySelector("[data-icen-ai-attach]");
|
|
2247
|
+
const send = composer.querySelector("[data-icen-ai-send]");
|
|
1140
2248
|
if (bar) {
|
|
1141
2249
|
if (modelBtn && modelBtn.parentElement !== bar) bar.insertBefore(modelBtn, bar.firstChild);
|
|
1142
2250
|
if (usageMount && usageMount.parentElement !== bar) {
|
|
@@ -1144,24 +2252,36 @@ function syncToolbar(composer) {
|
|
|
1144
2252
|
}
|
|
1145
2253
|
} else {
|
|
1146
2254
|
bar = document.createElement("div");
|
|
1147
|
-
bar.className = "ai-composer-toolbar";
|
|
2255
|
+
bar.className = "icen-ai-composer-toolbar";
|
|
1148
2256
|
bar.appendChild(modelBtn ?? document.createComment("model"));
|
|
1149
2257
|
const spacer = document.createElement("span");
|
|
1150
|
-
spacer.className = "ai-composer-spacer";
|
|
2258
|
+
spacer.className = "icen-ai-composer-spacer";
|
|
1151
2259
|
bar.appendChild(spacer);
|
|
1152
2260
|
if (usageMount) bar.appendChild(usageMount);
|
|
1153
2261
|
if (attach) bar.appendChild(attach);
|
|
1154
2262
|
if (send) bar.appendChild(send);
|
|
1155
2263
|
box.appendChild(bar);
|
|
1156
2264
|
}
|
|
1157
|
-
|
|
1158
|
-
if (
|
|
1159
|
-
|
|
1160
|
-
|
|
2265
|
+
let library = composer.querySelector("[data-icen-ai-library]");
|
|
2266
|
+
if (hasLibrary && !library) {
|
|
2267
|
+
library = document.createElement("button");
|
|
2268
|
+
library.type = "button";
|
|
2269
|
+
library.className = "icen-ai-composer-btn icen-ai-composer-library";
|
|
2270
|
+
library.dataset.icenAiLibrary = "auto";
|
|
2271
|
+
library.setAttribute("aria-label", t("aiComposer.library"));
|
|
2272
|
+
library.setAttribute("aria-haspopup", "dialog");
|
|
2273
|
+
library.setAttribute("aria-expanded", "false");
|
|
2274
|
+
library.append(createIcon("plus"));
|
|
2275
|
+
library.addEventListener("click", () => {
|
|
2276
|
+
if (POPUP.get(composer)?.mode === "library") closePopup(composer);
|
|
2277
|
+
else openComposerLibrary(composer);
|
|
2278
|
+
});
|
|
2279
|
+
bar.prepend(library);
|
|
2280
|
+
} else if (!hasLibrary && library?.dataset.icenAiLibrary === "auto") library.remove();
|
|
1161
2281
|
}
|
|
1162
2282
|
function refreshUsageRing(composer) {
|
|
1163
2283
|
const cfg = USAGE.get(composer);
|
|
1164
|
-
const mount = composer.querySelector(".ai-composer-usage");
|
|
2284
|
+
const mount = composer.querySelector(".icen-ai-composer-usage");
|
|
1165
2285
|
if (!cfg || !mount) return;
|
|
1166
2286
|
const explicit = typeof cfg.opts.total === "number" && cfg.opts.total > 0;
|
|
1167
2287
|
renderAiUsageRing(mount, cfg.usage, {
|
|
@@ -1169,18 +2289,21 @@ function refreshUsageRing(composer) {
|
|
|
1169
2289
|
total: explicit ? cfg.opts.total : MODEL_CTX.get(composer)
|
|
1170
2290
|
});
|
|
1171
2291
|
}
|
|
1172
|
-
var visibleOptions = (s) => s.options.filter((o) => !o.hidden);
|
|
2292
|
+
var visibleOptions = (s) => s.options.filter((o) => !o.hidden && o.getAttribute("aria-disabled") !== "true");
|
|
2293
|
+
var popupId = 0;
|
|
1173
2294
|
function setPopupFocus(s, idx) {
|
|
1174
2295
|
const vis = visibleOptions(s);
|
|
1175
2296
|
s.options.forEach((o) => o.classList.remove("is-focused"));
|
|
1176
2297
|
if (vis.length === 0) {
|
|
1177
2298
|
s.focused = -1;
|
|
2299
|
+
s.control?.removeAttribute("aria-activedescendant");
|
|
1178
2300
|
return;
|
|
1179
2301
|
}
|
|
1180
2302
|
s.focused = Math.max(0, Math.min(idx, vis.length - 1));
|
|
1181
2303
|
const cur = vis[s.focused];
|
|
1182
2304
|
cur.classList.add("is-focused");
|
|
1183
|
-
|
|
2305
|
+
s.control?.setAttribute("aria-activedescendant", cur.id);
|
|
2306
|
+
revealPopoverItem(cur, s.panel.querySelector(".icen-ai-composer-popup-list") ?? s.panel);
|
|
1184
2307
|
}
|
|
1185
2308
|
function movePopupFocus(s, delta) {
|
|
1186
2309
|
const vis = visibleOptions(s);
|
|
@@ -1189,15 +2312,25 @@ function movePopupFocus(s, delta) {
|
|
|
1189
2312
|
}
|
|
1190
2313
|
function settlePopup(s) {
|
|
1191
2314
|
for (const g of s.groups) {
|
|
1192
|
-
g.hidden = !Array.from(g.querySelectorAll(".ai-composer-popup-option")).some((o) => !o.hidden);
|
|
2315
|
+
g.hidden = !Array.from(g.querySelectorAll(".icen-ai-composer-popup-option")).some((o) => !o.hidden);
|
|
1193
2316
|
}
|
|
1194
|
-
s.emptyEl.hidden =
|
|
2317
|
+
s.emptyEl.hidden = s.options.some((o) => !o.hidden);
|
|
1195
2318
|
setPopupFocus(s, 0);
|
|
1196
2319
|
}
|
|
1197
2320
|
function filterPopupOptions(s, q) {
|
|
1198
2321
|
const needle = q.trim().toLowerCase();
|
|
1199
2322
|
for (const opt of s.options) {
|
|
1200
|
-
opt.hidden = needle !== "" && !(opt.dataset.hay ?? "").includes(needle);
|
|
2323
|
+
opt.hidden = !!s.category && s.category !== "all" && opt.dataset.category !== s.category || needle !== "" && !(opt.dataset.hay ?? "").includes(needle);
|
|
2324
|
+
for (const label of opt.querySelectorAll("[data-icen-search-text]")) {
|
|
2325
|
+
const text = label.dataset.icenSearchText ?? "";
|
|
2326
|
+
const at = needle ? text.toLowerCase().indexOf(needle) : -1;
|
|
2327
|
+
if (at < 0) label.textContent = text;
|
|
2328
|
+
else {
|
|
2329
|
+
const mark = document.createElement("mark");
|
|
2330
|
+
mark.textContent = text.slice(at, at + needle.length);
|
|
2331
|
+
label.replaceChildren(document.createTextNode(text.slice(0, at)), mark, document.createTextNode(text.slice(at + needle.length)));
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
1201
2334
|
}
|
|
1202
2335
|
settlePopup(s);
|
|
1203
2336
|
}
|
|
@@ -1214,6 +2347,9 @@ function popupKeydown(composer, s, e) {
|
|
|
1214
2347
|
return;
|
|
1215
2348
|
case "Enter":
|
|
1216
2349
|
case "Tab": {
|
|
2350
|
+
if (e.key === "Tab" && (s.mode === "library" || s.mode === "model")) {
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
1217
2353
|
e.preventDefault();
|
|
1218
2354
|
const vis = visibleOptions(s);
|
|
1219
2355
|
const opt = vis[s.focused] ?? vis[0];
|
|
@@ -1221,10 +2357,18 @@ function popupKeydown(composer, s, e) {
|
|
|
1221
2357
|
s.pick(opt);
|
|
1222
2358
|
return;
|
|
1223
2359
|
}
|
|
2360
|
+
if (s.mode === "library" || s.mode === "model") return;
|
|
1224
2361
|
closePopup(composer, false);
|
|
1225
2362
|
if (e.key === "Enter") SUBMITS.get(composer)?.();
|
|
1226
2363
|
return;
|
|
1227
2364
|
}
|
|
2365
|
+
case "Home":
|
|
2366
|
+
case "End":
|
|
2367
|
+
if (e.altKey || e.ctrlKey || e.metaKey) {
|
|
2368
|
+
e.preventDefault();
|
|
2369
|
+
setPopupFocus(s, e.key === "Home" ? 0 : visibleOptions(s).length - 1);
|
|
2370
|
+
}
|
|
2371
|
+
return;
|
|
1228
2372
|
case "Escape":
|
|
1229
2373
|
e.preventDefault();
|
|
1230
2374
|
closePopup(composer);
|
|
@@ -1234,14 +2378,19 @@ function popupKeydown(composer, s, e) {
|
|
|
1234
2378
|
function closePopup(composer, restoreFocus = true) {
|
|
1235
2379
|
const s = POPUP.get(composer);
|
|
1236
2380
|
if (!s) return;
|
|
2381
|
+
s.restoreFocus = restoreFocus;
|
|
1237
2382
|
POPUP.delete(composer);
|
|
1238
2383
|
if (s.searchInput && s.keydownHandler) {
|
|
1239
2384
|
s.searchInput.removeEventListener("keydown", s.keydownHandler);
|
|
1240
2385
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
2386
|
+
s.control?.removeAttribute("aria-activedescendant");
|
|
2387
|
+
s.control?.removeAttribute("aria-controls");
|
|
2388
|
+
if (s.mode === "library") {
|
|
2389
|
+
composer.querySelector("[data-icen-ai-library]")?.setAttribute("aria-expanded", "false");
|
|
2390
|
+
} else if (s.mode === "model") {
|
|
2391
|
+
composer.querySelector("[data-icen-ai-model-open]")?.setAttribute("aria-expanded", "false");
|
|
1243
2392
|
} else {
|
|
1244
|
-
getTextarea(composer)?.
|
|
2393
|
+
getTextarea(composer)?.removeAttribute("aria-expanded");
|
|
1245
2394
|
}
|
|
1246
2395
|
closePopover(s.panel);
|
|
1247
2396
|
if (restoreFocus && s.returnFocus && s.returnFocus.isConnected) s.returnFocus.focus();
|
|
@@ -1253,7 +2402,9 @@ function resolvePopupSizing(composer, defaults) {
|
|
|
1253
2402
|
function mountPopup(composer, init) {
|
|
1254
2403
|
closePopup(composer, false);
|
|
1255
2404
|
const panel = document.createElement("div");
|
|
1256
|
-
panel.className = "ai-composer-popup";
|
|
2405
|
+
panel.className = "icen-ai-composer-popup";
|
|
2406
|
+
panel.dataset.icenMaterial = "floating";
|
|
2407
|
+
panel.dataset.icenMode = init.mode;
|
|
1257
2408
|
panel.hidden = true;
|
|
1258
2409
|
const session = {
|
|
1259
2410
|
mode: init.mode,
|
|
@@ -1269,49 +2420,245 @@ function mountPopup(composer, init) {
|
|
|
1269
2420
|
pick: init.pick
|
|
1270
2421
|
};
|
|
1271
2422
|
init.build(session);
|
|
2423
|
+
if (session.searchInput) session.searchField = enhanceSearchField(session.searchInput);
|
|
2424
|
+
const list = panel.querySelector('[role="listbox"]');
|
|
2425
|
+
if (list) {
|
|
2426
|
+
list.id = `icen-composer-list-${++popupId}`;
|
|
2427
|
+
session.options.forEach((o, i) => {
|
|
2428
|
+
o.id = `${list.id}-${i}`;
|
|
2429
|
+
o.tabIndex = -1;
|
|
2430
|
+
});
|
|
2431
|
+
session.control = session.searchInput ?? getTextarea(composer);
|
|
2432
|
+
session.control?.setAttribute("aria-controls", list.id);
|
|
2433
|
+
session.control?.setAttribute("aria-haspopup", "listbox");
|
|
2434
|
+
}
|
|
1272
2435
|
openPopover(panel, {
|
|
1273
2436
|
anchor: init.anchor,
|
|
1274
2437
|
side: "top",
|
|
1275
2438
|
align: "start",
|
|
1276
2439
|
offset: 8,
|
|
1277
2440
|
sizing: resolvePopupSizing(composer, init.sizing),
|
|
2441
|
+
restoreFocus: false,
|
|
1278
2442
|
onClose: () => {
|
|
1279
2443
|
if (POPUP.get(composer) === session) POPUP.delete(composer);
|
|
2444
|
+
session.control?.removeAttribute("aria-activedescendant");
|
|
2445
|
+
session.control?.removeAttribute("aria-controls");
|
|
2446
|
+
composer.querySelector("[data-icen-ai-library]")?.setAttribute("aria-expanded", "false");
|
|
2447
|
+
composer.querySelector("[data-icen-ai-model-open]")?.setAttribute("aria-expanded", "false");
|
|
2448
|
+
getTextarea(composer)?.removeAttribute("aria-expanded");
|
|
2449
|
+
if (session.restoreFocus !== false && panel.contains(document.activeElement) && session.returnFocus?.isConnected) {
|
|
2450
|
+
session.returnFocus.focus({ preventScroll: true });
|
|
2451
|
+
}
|
|
2452
|
+
session.searchField?.destroy();
|
|
1280
2453
|
panel.remove();
|
|
1281
2454
|
}
|
|
1282
2455
|
});
|
|
1283
2456
|
POPUP.set(composer, session);
|
|
1284
2457
|
panel.addEventListener("click", (e) => {
|
|
1285
|
-
const
|
|
1286
|
-
if (!(
|
|
1287
|
-
const opt =
|
|
1288
|
-
if (opt && panel.contains(opt) && !opt.hidden) session.pick(opt);
|
|
2458
|
+
const t2 = e.target;
|
|
2459
|
+
if (!(t2 instanceof Element)) return;
|
|
2460
|
+
const opt = t2.closest(".icen-ai-composer-popup-option");
|
|
2461
|
+
if (opt && panel.contains(opt) && !opt.hidden && opt.getAttribute("aria-disabled") !== "true") session.pick(opt);
|
|
1289
2462
|
});
|
|
1290
2463
|
panel.addEventListener("mouseover", (e) => {
|
|
1291
|
-
const
|
|
1292
|
-
if (!(
|
|
1293
|
-
const opt =
|
|
1294
|
-
if (!opt || opt.hidden) return;
|
|
2464
|
+
const t2 = e.target;
|
|
2465
|
+
if (!(t2 instanceof Element)) return;
|
|
2466
|
+
const opt = t2.closest(".icen-ai-composer-popup-option");
|
|
2467
|
+
if (!opt || opt.hidden || opt.getAttribute("aria-disabled") === "true") return;
|
|
1295
2468
|
const idx = visibleOptions(session).indexOf(opt);
|
|
1296
2469
|
if (idx >= 0) setPopupFocus(session, idx);
|
|
1297
2470
|
});
|
|
2471
|
+
panel.addEventListener("focusout", (e) => {
|
|
2472
|
+
const next = e.relatedTarget;
|
|
2473
|
+
if (next instanceof Node && !panel.contains(next) && next !== session.returnFocus) closePopup(composer, false);
|
|
2474
|
+
});
|
|
2475
|
+
panel.addEventListener("keydown", (e) => {
|
|
2476
|
+
if (e.key === "Escape" && !e.isComposing) {
|
|
2477
|
+
e.preventDefault();
|
|
2478
|
+
closePopup(composer);
|
|
2479
|
+
} else if (e.target instanceof Element && e.target.closest(".icen-ai-composer-popup-option") && ["ArrowUp", "ArrowDown"].includes(e.key)) {
|
|
2480
|
+
popupKeydown(composer, session, e);
|
|
2481
|
+
session.searchInput?.focus({ preventScroll: true });
|
|
2482
|
+
}
|
|
2483
|
+
});
|
|
1298
2484
|
return session;
|
|
1299
2485
|
}
|
|
1300
2486
|
function appendPopupEmpty(s, text) {
|
|
1301
|
-
s.emptyEl.className = "ai-composer-popup-empty";
|
|
2487
|
+
s.emptyEl.className = "icen-ai-composer-popup-empty";
|
|
1302
2488
|
s.emptyEl.textContent = text;
|
|
1303
2489
|
s.emptyEl.hidden = true;
|
|
1304
2490
|
s.panel.appendChild(s.emptyEl);
|
|
1305
2491
|
}
|
|
1306
2492
|
function popupSizingFor(box) {
|
|
1307
2493
|
const w = box.getBoundingClientRect().width;
|
|
1308
|
-
return {
|
|
2494
|
+
return { width: Math.min(Math.max(w, 280), 440), maxWidth: 440, maxHeight: 400 };
|
|
2495
|
+
}
|
|
2496
|
+
function searchLeaf(text, className) {
|
|
2497
|
+
const el = document.createElement("span");
|
|
2498
|
+
el.className = className;
|
|
2499
|
+
el.textContent = text;
|
|
2500
|
+
el.dataset.icenSearchText = text;
|
|
2501
|
+
return el;
|
|
2502
|
+
}
|
|
2503
|
+
function resourceIcon(source) {
|
|
2504
|
+
const mark = document.createElement("span");
|
|
2505
|
+
mark.className = "icen-ai-composer-popup-option-icon";
|
|
2506
|
+
const svg = (source.icon ? createIcon(source.icon) : null) ?? svgIcon(getRefKindDef(source.kind).icon);
|
|
2507
|
+
if (svg) mark.append(svg);
|
|
2508
|
+
return mark;
|
|
2509
|
+
}
|
|
2510
|
+
function resourceOption(source) {
|
|
2511
|
+
const opt = document.createElement("button");
|
|
2512
|
+
opt.type = "button";
|
|
2513
|
+
opt.className = "icen-ai-composer-popup-option";
|
|
2514
|
+
opt.setAttribute("role", "option");
|
|
2515
|
+
opt.dataset.refId = source.id;
|
|
2516
|
+
opt.dataset.refKind = source.kind;
|
|
2517
|
+
opt.dataset.category = source.kind;
|
|
2518
|
+
opt.dataset.hay = [source.label, source.description, source.sub, getRefKindDef(source.kind).label, ...source.keywords ?? []].join(" ").toLowerCase();
|
|
2519
|
+
opt.setAttribute("aria-selected", "false");
|
|
2520
|
+
if (source.disabled) opt.setAttribute("aria-disabled", "true");
|
|
2521
|
+
const body = document.createElement("span");
|
|
2522
|
+
body.className = "icen-ai-composer-popup-option-copy";
|
|
2523
|
+
body.append(searchLeaf(source.label, "icen-ai-composer-popup-option-label"));
|
|
2524
|
+
if (source.description || source.sub) body.append(searchLeaf(source.description ?? source.sub ?? "", "icen-ai-composer-popup-option-sub"));
|
|
2525
|
+
opt.append(resourceIcon(source), body);
|
|
2526
|
+
return opt;
|
|
2527
|
+
}
|
|
2528
|
+
function commandOption(c) {
|
|
2529
|
+
const opt = document.createElement("button");
|
|
2530
|
+
opt.type = "button";
|
|
2531
|
+
opt.className = "icen-ai-composer-popup-option icen-ai-composer-popup-cmd";
|
|
2532
|
+
opt.setAttribute("role", "option");
|
|
2533
|
+
opt.setAttribute("aria-selected", "false");
|
|
2534
|
+
if (c.disabled) opt.setAttribute("aria-disabled", "true");
|
|
2535
|
+
opt.dataset.name = c.name;
|
|
2536
|
+
opt.dataset.category = "command";
|
|
2537
|
+
opt.dataset.hay = [c.name, c.label, c.description, c.group, ...c.keywords ?? []].join(" ").toLowerCase();
|
|
2538
|
+
const mark = document.createElement("span");
|
|
2539
|
+
mark.className = "icen-ai-composer-popup-option-icon";
|
|
2540
|
+
mark.append(createIcon(c.icon ?? "terminal") ?? createIcon("terminal"));
|
|
2541
|
+
const body = document.createElement("span");
|
|
2542
|
+
body.className = "icen-ai-composer-popup-option-copy";
|
|
2543
|
+
const line = document.createElement("span");
|
|
2544
|
+
line.className = "icen-ai-composer-popup-cmd-line";
|
|
2545
|
+
line.append(searchLeaf(c.label ?? `/${c.name}`, "icen-ai-composer-popup-option-label"));
|
|
2546
|
+
if (c.label) line.append(searchLeaf(`/${c.name}`, "icen-ai-composer-popup-cmd-name"));
|
|
2547
|
+
if (c.argsHint) line.append(searchLeaf(c.argsHint, "icen-ai-composer-popup-cmd-args"));
|
|
2548
|
+
body.append(line);
|
|
2549
|
+
if (c.description) body.append(searchLeaf(c.description, "icen-ai-composer-popup-option-sub"));
|
|
2550
|
+
opt.append(mark, body);
|
|
2551
|
+
return opt;
|
|
2552
|
+
}
|
|
2553
|
+
function popupFoot(s, text) {
|
|
2554
|
+
const foot = document.createElement("div");
|
|
2555
|
+
foot.className = "icen-ai-composer-popup-foot";
|
|
2556
|
+
foot.textContent = text;
|
|
2557
|
+
s.panel.append(foot);
|
|
2558
|
+
}
|
|
2559
|
+
function openComposerLibrary(el, category = "all") {
|
|
2560
|
+
if (!isBrowser()) return;
|
|
2561
|
+
const composer = resolveComposer(el);
|
|
2562
|
+
if (!composer) return;
|
|
2563
|
+
const ta = getTextarea(composer);
|
|
2564
|
+
if (!ta || ta.disabled || ta.readOnly) return;
|
|
2565
|
+
const anchor = composer.querySelector("[data-icen-ai-library]") ?? ta;
|
|
2566
|
+
const sources = REF_SOURCES.get(composer) ?? [], commands = COMMANDS.get(composer) ?? [];
|
|
2567
|
+
if (!sources.length && !commands.length) return;
|
|
2568
|
+
const session = mountPopup(composer, {
|
|
2569
|
+
mode: "library",
|
|
2570
|
+
anchor: composer,
|
|
2571
|
+
sizing: popupSizingFor(composer),
|
|
2572
|
+
returnFocus: anchor,
|
|
2573
|
+
pick: (opt) => {
|
|
2574
|
+
if (opt.dataset.name) {
|
|
2575
|
+
const draft = ta.value.replace(/^\/\S*\s?/, "");
|
|
2576
|
+
ta.value = `/${opt.dataset.name} ${draft}`;
|
|
2577
|
+
autosizeTa(ta);
|
|
2578
|
+
closePopup(composer, false);
|
|
2579
|
+
ta.focus();
|
|
2580
|
+
ta.setSelectionRange(ta.value.length, ta.value.length);
|
|
2581
|
+
return;
|
|
2582
|
+
}
|
|
2583
|
+
const source = sources.find((r) => r.id === opt.dataset.refId && r.kind === opt.dataset.refKind);
|
|
2584
|
+
if (!source) return;
|
|
2585
|
+
const active = (ACTIVE_REFS.get(composer) ?? []).some((r) => r.id === source.id && r.kind === source.kind);
|
|
2586
|
+
if (active) removeActiveRef(composer, source);
|
|
2587
|
+
else addActiveRef(composer, source);
|
|
2588
|
+
opt.setAttribute("aria-selected", String(!active));
|
|
2589
|
+
},
|
|
2590
|
+
build: (s) => {
|
|
2591
|
+
s.panel.setAttribute("role", "dialog");
|
|
2592
|
+
s.panel.setAttribute("aria-label", t("aiComposer.library"));
|
|
2593
|
+
const search = document.createElement("div");
|
|
2594
|
+
search.className = "icen-ai-composer-popup-search";
|
|
2595
|
+
const input = document.createElement("input");
|
|
2596
|
+
input.type = "search";
|
|
2597
|
+
input.className = "icen-ai-composer-popup-search-input";
|
|
2598
|
+
input.placeholder = t("aiComposer.searchLibrary");
|
|
2599
|
+
input.setAttribute("aria-label", t("aiComposer.searchLibrary"));
|
|
2600
|
+
search.append(input);
|
|
2601
|
+
s.searchInput = input;
|
|
2602
|
+
s.panel.append(search);
|
|
2603
|
+
const categories = [{ id: "all", label: t("aiComposer.all") }, ...knownRefKinds(sources).filter((k) => sources.some((r) => r.kind === k)).map((k) => ({ id: k, label: getRefKindDef(k).label })), ...commands.length ? [{ id: "command", label: t("aiComposer.commands") }] : []];
|
|
2604
|
+
s.category = categories.some((c) => c.id === category) ? category : "all";
|
|
2605
|
+
const filters = document.createElement("div");
|
|
2606
|
+
filters.className = "icen-ai-composer-popup-filters";
|
|
2607
|
+
filters.setAttribute("role", "group");
|
|
2608
|
+
filters.setAttribute("aria-label", t("aiComposer.refs"));
|
|
2609
|
+
for (const c of categories) {
|
|
2610
|
+
const b = document.createElement("button");
|
|
2611
|
+
b.type = "button";
|
|
2612
|
+
b.textContent = c.label;
|
|
2613
|
+
b.setAttribute("aria-pressed", String(c.id === s.category));
|
|
2614
|
+
b.addEventListener("click", () => {
|
|
2615
|
+
s.category = c.id;
|
|
2616
|
+
for (const node of filters.querySelectorAll("button")) node.setAttribute("aria-pressed", String(node === b));
|
|
2617
|
+
filterPopupOptions(s, input.value);
|
|
2618
|
+
});
|
|
2619
|
+
filters.append(b);
|
|
2620
|
+
}
|
|
2621
|
+
s.panel.append(filters);
|
|
2622
|
+
const list = document.createElement("div");
|
|
2623
|
+
list.className = "icen-ai-composer-popup-list";
|
|
2624
|
+
list.setAttribute("role", "listbox");
|
|
2625
|
+
list.setAttribute("aria-label", t("aiComposer.library"));
|
|
2626
|
+
list.setAttribute("aria-multiselectable", "true");
|
|
2627
|
+
const addGroup = (title, options) => {
|
|
2628
|
+
const g = document.createElement("div");
|
|
2629
|
+
g.className = "icen-ai-composer-popup-group";
|
|
2630
|
+
g.setAttribute("role", "group");
|
|
2631
|
+
g.setAttribute("aria-label", title);
|
|
2632
|
+
g.append(searchLeaf(title, "icen-ai-composer-popup-group-label"), ...options);
|
|
2633
|
+
list.append(g);
|
|
2634
|
+
s.groups.push(g);
|
|
2635
|
+
s.options.push(...options);
|
|
2636
|
+
};
|
|
2637
|
+
for (const kind of knownRefKinds(sources)) {
|
|
2638
|
+
const options = sources.filter((r) => r.kind === kind).map((r) => {
|
|
2639
|
+
const opt = resourceOption(r);
|
|
2640
|
+
opt.setAttribute("aria-selected", String((ACTIVE_REFS.get(composer) ?? []).some((a) => a.id === r.id && a.kind === r.kind)));
|
|
2641
|
+
return opt;
|
|
2642
|
+
});
|
|
2643
|
+
if (options.length) addGroup(getRefKindDef(kind).label, options);
|
|
2644
|
+
}
|
|
2645
|
+
for (const group of new Set(commands.map((c) => c.group ?? t("aiComposer.commands")))) addGroup(group, commands.filter((c) => (c.group ?? t("aiComposer.commands")) === group).map(commandOption));
|
|
2646
|
+
s.panel.append(list);
|
|
2647
|
+
appendPopupEmpty(s, t("aiComposer.noLibraryMatch"));
|
|
2648
|
+
popupFoot(s, t("aiComposer.libraryHint"));
|
|
2649
|
+
input.addEventListener("input", () => filterPopupOptions(s, input.value));
|
|
2650
|
+
input.addEventListener("keydown", (e) => popupKeydown(composer, s, e));
|
|
2651
|
+
}
|
|
2652
|
+
});
|
|
2653
|
+
anchor.setAttribute("aria-expanded", "true");
|
|
2654
|
+
filterPopupOptions(session, "");
|
|
2655
|
+
session.searchInput?.focus({ preventScroll: true });
|
|
1309
2656
|
}
|
|
1310
2657
|
function openModelPopup(composer) {
|
|
1311
2658
|
const cfg = MODELS.get(composer);
|
|
1312
2659
|
if (!cfg) return;
|
|
1313
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
1314
|
-
const anchor = btn ?? composer.querySelector(".ai-composer-box") ?? composer;
|
|
2660
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
2661
|
+
const anchor = btn ?? composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1315
2662
|
const ta = getTextarea(composer);
|
|
1316
2663
|
const session = mountPopup(composer, {
|
|
1317
2664
|
mode: "model",
|
|
@@ -1321,7 +2668,7 @@ function openModelPopup(composer) {
|
|
|
1321
2668
|
pick: (opt) => {
|
|
1322
2669
|
const provider = opt.dataset.provider ?? "";
|
|
1323
2670
|
const model = opt.dataset.model ?? "";
|
|
1324
|
-
const label = opt.dataset.
|
|
2671
|
+
const label = opt.dataset.icenLabel ?? model;
|
|
1325
2672
|
const context = typeof opt.dataset.context === "string" ? Number(opt.dataset.context) : void 0;
|
|
1326
2673
|
MODELS.set(composer, { providers: cfg.providers, current: { provider, model } });
|
|
1327
2674
|
if (typeof context === "number" && Number.isFinite(context) && context > 0) {
|
|
@@ -1336,25 +2683,25 @@ function openModelPopup(composer) {
|
|
|
1336
2683
|
},
|
|
1337
2684
|
build: (s) => {
|
|
1338
2685
|
const search = document.createElement("div");
|
|
1339
|
-
search.className = "ai-composer-popup-search";
|
|
2686
|
+
search.className = "icen-ai-composer-popup-search";
|
|
1340
2687
|
const input = document.createElement("input");
|
|
1341
2688
|
input.type = "search";
|
|
1342
|
-
input.className = "ai-composer-popup-search-input";
|
|
1343
|
-
input.placeholder = "
|
|
1344
|
-
input.setAttribute("aria-label", "
|
|
2689
|
+
input.className = "icen-ai-composer-popup-search-input";
|
|
2690
|
+
input.placeholder = t("aiComposer.searchModels");
|
|
2691
|
+
input.setAttribute("aria-label", t("aiComposer.searchModels"));
|
|
1345
2692
|
search.appendChild(input);
|
|
1346
2693
|
s.panel.appendChild(search);
|
|
1347
2694
|
s.searchInput = input;
|
|
1348
2695
|
const list = document.createElement("div");
|
|
1349
|
-
list.className = "ai-composer-popup-list";
|
|
2696
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1350
2697
|
list.setAttribute("role", "listbox");
|
|
1351
|
-
list.setAttribute("aria-label", "
|
|
2698
|
+
list.setAttribute("aria-label", t("aiComposer.selectModel"));
|
|
1352
2699
|
for (const p of cfg.providers) {
|
|
1353
2700
|
const group = document.createElement("div");
|
|
1354
|
-
group.className = "ai-composer-popup-group";
|
|
2701
|
+
group.className = "icen-ai-composer-popup-group";
|
|
1355
2702
|
const glabel = document.createElement("div");
|
|
1356
|
-
glabel.className = "ai-composer-popup-group-label";
|
|
1357
|
-
glabel.appendChild(providerMark(p, "ai-composer-popup-group-icon"));
|
|
2703
|
+
glabel.className = "icen-ai-composer-popup-group-label";
|
|
2704
|
+
glabel.appendChild(providerMark(p, "icen-ai-composer-popup-group-icon"));
|
|
1358
2705
|
const gtext = document.createElement("span");
|
|
1359
2706
|
gtext.textContent = p.label;
|
|
1360
2707
|
glabel.appendChild(gtext);
|
|
@@ -1362,30 +2709,26 @@ function openModelPopup(composer) {
|
|
|
1362
2709
|
for (const m of p.models) {
|
|
1363
2710
|
const opt = document.createElement("button");
|
|
1364
2711
|
opt.type = "button";
|
|
1365
|
-
opt.className = "ai-composer-popup-option";
|
|
2712
|
+
opt.className = "icen-ai-composer-popup-option";
|
|
1366
2713
|
opt.setAttribute("role", "option");
|
|
1367
2714
|
opt.dataset.provider = p.id;
|
|
1368
2715
|
opt.dataset.providerLabel = p.label;
|
|
1369
2716
|
opt.dataset.model = m.id;
|
|
1370
|
-
opt.dataset.
|
|
2717
|
+
opt.dataset.icenLabel = m.label;
|
|
1371
2718
|
opt.dataset.hay = `${m.label} ${p.label}`.toLowerCase();
|
|
1372
2719
|
if (typeof m.context === "number") opt.dataset.context = String(m.context);
|
|
1373
2720
|
const selected = cfg.current.provider === p.id && cfg.current.model === m.id;
|
|
1374
2721
|
opt.setAttribute("aria-selected", String(selected));
|
|
1375
2722
|
const icon = document.createElement("span");
|
|
1376
|
-
icon.className = "ai-composer-popup-option-icon";
|
|
2723
|
+
icon.className = "icen-ai-composer-popup-option-icon";
|
|
1377
2724
|
icon.appendChild(providerMark(p, "ai-composer-popup-option-provider-icon"));
|
|
1378
2725
|
const label = document.createElement("span");
|
|
1379
|
-
label.className = "ai-composer-popup-option-label";
|
|
2726
|
+
label.className = "icen-ai-composer-popup-option-label";
|
|
1380
2727
|
label.textContent = m.label;
|
|
1381
2728
|
const meta = document.createElement("span");
|
|
1382
|
-
meta.className = "ai-composer-popup-option-meta";
|
|
2729
|
+
meta.className = "icen-ai-composer-popup-option-meta";
|
|
1383
2730
|
meta.textContent = typeof m.context === "number" ? formatTokens(m.context) : "";
|
|
1384
|
-
|
|
1385
|
-
check.className = "ai-composer-popup-option-check";
|
|
1386
|
-
const checkSvg = svgIcon(ICON_CHECK);
|
|
1387
|
-
if (checkSvg) check.appendChild(checkSvg);
|
|
1388
|
-
opt.append(icon, label, meta, check);
|
|
2731
|
+
opt.append(icon, label, meta);
|
|
1389
2732
|
group.appendChild(opt);
|
|
1390
2733
|
s.options.push(opt);
|
|
1391
2734
|
}
|
|
@@ -1393,9 +2736,9 @@ function openModelPopup(composer) {
|
|
|
1393
2736
|
s.groups.push(group);
|
|
1394
2737
|
}
|
|
1395
2738
|
s.panel.appendChild(list);
|
|
1396
|
-
appendPopupEmpty(s, "
|
|
2739
|
+
appendPopupEmpty(s, t("aiComposer.noModelMatch"));
|
|
1397
2740
|
const foot = document.createElement("div");
|
|
1398
|
-
foot.className = "ai-composer-popup-foot";
|
|
2741
|
+
foot.className = "icen-ai-composer-popup-foot";
|
|
1399
2742
|
const usageCfg = USAGE.get(composer);
|
|
1400
2743
|
if (usageCfg) {
|
|
1401
2744
|
const u = usageCfg.usage;
|
|
@@ -1407,7 +2750,7 @@ function openModelPopup(composer) {
|
|
|
1407
2750
|
const info = svgIcon(ICON_INFO);
|
|
1408
2751
|
if (info) foot.appendChild(info);
|
|
1409
2752
|
const footText = document.createElement("span");
|
|
1410
|
-
footText.textContent = "
|
|
2753
|
+
footText.textContent = t("aiComposer.cacheInvalidHint");
|
|
1411
2754
|
foot.appendChild(footText);
|
|
1412
2755
|
s.panel.appendChild(foot);
|
|
1413
2756
|
s.keydownHandler = (e) => popupKeydown(composer, s, e);
|
|
@@ -1420,10 +2763,21 @@ function openModelPopup(composer) {
|
|
|
1420
2763
|
btn?.setAttribute("aria-expanded", "true");
|
|
1421
2764
|
session.searchInput?.focus();
|
|
1422
2765
|
}
|
|
2766
|
+
function runComposerCommand(composer, name) {
|
|
2767
|
+
const command = COMMANDS.get(composer)?.find((c) => c.name === name && !c.disabled);
|
|
2768
|
+
const ta = getTextarea(composer);
|
|
2769
|
+
if (!command || !ta || ta.disabled || ta.readOnly) return false;
|
|
2770
|
+
const args = /^\/\S*\s+([\s\S]*)$/.exec(ta.value)?.[1] ?? "";
|
|
2771
|
+
ta.value = "";
|
|
2772
|
+
autosizeTa(ta);
|
|
2773
|
+
emit2(composer, "icen:ai-command", { name: command.name, args });
|
|
2774
|
+
closePopup(composer);
|
|
2775
|
+
return true;
|
|
2776
|
+
}
|
|
1423
2777
|
function openCommandPopup(composer, token) {
|
|
1424
2778
|
const commands = COMMANDS.get(composer);
|
|
1425
2779
|
if (!commands || commands.length === 0) return;
|
|
1426
|
-
const box = composer.querySelector(".ai-composer-box") ?? composer;
|
|
2780
|
+
const box = composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1427
2781
|
const ta = getTextarea(composer);
|
|
1428
2782
|
const session = mountPopup(composer, {
|
|
1429
2783
|
mode: "command",
|
|
@@ -1431,59 +2785,27 @@ function openCommandPopup(composer, token) {
|
|
|
1431
2785
|
sizing: popupSizingFor(box),
|
|
1432
2786
|
returnFocus: ta,
|
|
1433
2787
|
pick: (opt) => {
|
|
1434
|
-
|
|
1435
|
-
const m = /^\/\S*\s+([\s\S]*)$/.exec(ta?.value ?? "");
|
|
1436
|
-
const args = m ? m[1] : "";
|
|
1437
|
-
if (ta) {
|
|
1438
|
-
ta.value = "";
|
|
1439
|
-
autosizeTa(ta);
|
|
1440
|
-
}
|
|
1441
|
-
emit2(composer, "icen:ai-command", { name, args });
|
|
1442
|
-
closePopup(composer);
|
|
2788
|
+
runComposerCommand(composer, opt.dataset.name ?? "");
|
|
1443
2789
|
},
|
|
1444
2790
|
build: (s) => {
|
|
1445
2791
|
const list = document.createElement("div");
|
|
1446
|
-
list.className = "ai-composer-popup-list";
|
|
2792
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1447
2793
|
list.setAttribute("role", "listbox");
|
|
1448
|
-
list.setAttribute("aria-label", "
|
|
2794
|
+
list.setAttribute("aria-label", t("aiComposer.commands"));
|
|
1449
2795
|
const group = document.createElement("div");
|
|
1450
|
-
group.className = "ai-composer-popup-group";
|
|
2796
|
+
group.className = "icen-ai-composer-popup-group";
|
|
1451
2797
|
for (const c of commands) {
|
|
1452
|
-
const opt =
|
|
1453
|
-
opt.type = "button";
|
|
1454
|
-
opt.className = "ai-composer-popup-option ai-composer-popup-cmd";
|
|
1455
|
-
opt.setAttribute("role", "option");
|
|
1456
|
-
opt.dataset.name = c.name;
|
|
1457
|
-
opt.dataset.hay = `${c.name} ${c.description ?? ""}`.toLowerCase();
|
|
1458
|
-
const line = document.createElement("span");
|
|
1459
|
-
line.className = "ai-composer-popup-cmd-line";
|
|
1460
|
-
const nameEl = document.createElement("span");
|
|
1461
|
-
nameEl.className = "ai-composer-popup-cmd-name";
|
|
1462
|
-
nameEl.textContent = `/${c.name}`;
|
|
1463
|
-
line.appendChild(nameEl);
|
|
1464
|
-
if (c.argsHint) {
|
|
1465
|
-
const argsEl = document.createElement("span");
|
|
1466
|
-
argsEl.className = "ai-composer-popup-cmd-args";
|
|
1467
|
-
argsEl.textContent = c.argsHint;
|
|
1468
|
-
line.appendChild(argsEl);
|
|
1469
|
-
}
|
|
1470
|
-
opt.appendChild(line);
|
|
1471
|
-
if (c.description) {
|
|
1472
|
-
opt.appendChild(Object.assign(document.createElement("span"), {
|
|
1473
|
-
className: "ai-composer-popup-cmd-desc",
|
|
1474
|
-
textContent: c.description
|
|
1475
|
-
}));
|
|
1476
|
-
}
|
|
2798
|
+
const opt = commandOption(c);
|
|
1477
2799
|
group.appendChild(opt);
|
|
1478
2800
|
s.options.push(opt);
|
|
1479
2801
|
}
|
|
1480
2802
|
list.appendChild(group);
|
|
1481
2803
|
s.groups.push(group);
|
|
1482
2804
|
s.panel.appendChild(list);
|
|
1483
|
-
appendPopupEmpty(s, "
|
|
2805
|
+
appendPopupEmpty(s, t("aiComposer.noCommandMatch"));
|
|
2806
|
+
popupFoot(s, t("aiComposer.commandHint"));
|
|
1484
2807
|
}
|
|
1485
2808
|
});
|
|
1486
|
-
ta?.setAttribute("aria-expanded", "true");
|
|
1487
2809
|
filterPopupOptions(session, token);
|
|
1488
2810
|
}
|
|
1489
2811
|
function commandToken(value) {
|
|
@@ -1502,7 +2824,7 @@ function updateCommandPopup(composer, s) {
|
|
|
1502
2824
|
function openRefPopup(composer, range, filter) {
|
|
1503
2825
|
const sources = REF_SOURCES.get(composer);
|
|
1504
2826
|
if (!sources || sources.length === 0) return;
|
|
1505
|
-
const box = composer.querySelector(".ai-composer-box") ?? composer;
|
|
2827
|
+
const box = composer.querySelector(".icen-ai-composer-box") ?? composer;
|
|
1506
2828
|
const ta = getTextarea(composer);
|
|
1507
2829
|
const session = mountPopup(composer, {
|
|
1508
2830
|
mode: "ref",
|
|
@@ -1511,7 +2833,7 @@ function openRefPopup(composer, range, filter) {
|
|
|
1511
2833
|
returnFocus: ta,
|
|
1512
2834
|
refRange: range,
|
|
1513
2835
|
pick: (opt) => {
|
|
1514
|
-
const source = (REF_SOURCES.get(composer) ?? []).find((r2) => r2.id === opt.dataset.refId);
|
|
2836
|
+
const source = (REF_SOURCES.get(composer) ?? []).find((r2) => r2.id === opt.dataset.refId && r2.kind === opt.dataset.refKind);
|
|
1515
2837
|
const cur = POPUP.get(composer);
|
|
1516
2838
|
const r = cur?.refRange ?? (ta ? findRefToken(ta) : null);
|
|
1517
2839
|
if (source && ta && r) {
|
|
@@ -1527,41 +2849,23 @@ function openRefPopup(composer, range, filter) {
|
|
|
1527
2849
|
},
|
|
1528
2850
|
build: (s) => {
|
|
1529
2851
|
const list = document.createElement("div");
|
|
1530
|
-
list.className = "ai-composer-popup-list";
|
|
2852
|
+
list.className = "icen-ai-composer-popup-list";
|
|
1531
2853
|
list.setAttribute("role", "listbox");
|
|
1532
|
-
list.setAttribute("aria-label", "
|
|
2854
|
+
list.setAttribute("aria-label", t("aiComposer.refs"));
|
|
1533
2855
|
for (const kind of knownRefKinds(sources)) {
|
|
1534
2856
|
const def = getRefKindDef(kind);
|
|
1535
2857
|
const items = sources.filter((r) => r.kind === kind);
|
|
1536
2858
|
if (items.length === 0) continue;
|
|
1537
2859
|
const group = document.createElement("div");
|
|
1538
|
-
group.className = "ai-composer-popup-group";
|
|
1539
|
-
group.dataset.
|
|
2860
|
+
group.className = "icen-ai-composer-popup-group";
|
|
2861
|
+
group.dataset.icenKind = kind;
|
|
1540
2862
|
group.appendChild(Object.assign(document.createElement("div"), {
|
|
1541
|
-
className: "ai-composer-popup-group-label",
|
|
2863
|
+
className: "icen-ai-composer-popup-group-label",
|
|
1542
2864
|
textContent: def.label
|
|
1543
2865
|
}));
|
|
1544
2866
|
for (const r of items) {
|
|
1545
|
-
const opt =
|
|
1546
|
-
opt.
|
|
1547
|
-
opt.className = "ai-composer-popup-option";
|
|
1548
|
-
opt.setAttribute("role", "option");
|
|
1549
|
-
opt.dataset.refId = r.id;
|
|
1550
|
-
opt.dataset.hay = `${r.label} ${r.sub ?? ""}`.toLowerCase();
|
|
1551
|
-
const icon = document.createElement("span");
|
|
1552
|
-
icon.className = "ai-composer-popup-option-icon";
|
|
1553
|
-
const svg2 = svgIcon(def.icon);
|
|
1554
|
-
if (svg2) icon.appendChild(svg2);
|
|
1555
|
-
const label = document.createElement("span");
|
|
1556
|
-
label.className = "ai-composer-popup-option-label";
|
|
1557
|
-
label.textContent = r.label;
|
|
1558
|
-
if (r.sub) {
|
|
1559
|
-
const sub = document.createElement("span");
|
|
1560
|
-
sub.className = "ai-composer-popup-option-sub";
|
|
1561
|
-
sub.textContent = r.sub;
|
|
1562
|
-
label.appendChild(sub);
|
|
1563
|
-
}
|
|
1564
|
-
opt.append(icon, label);
|
|
2867
|
+
const opt = resourceOption(r);
|
|
2868
|
+
opt.setAttribute("aria-selected", String((ACTIVE_REFS.get(composer) ?? []).some((a) => a.id === r.id && a.kind === r.kind)));
|
|
1565
2869
|
group.appendChild(opt);
|
|
1566
2870
|
s.options.push(opt);
|
|
1567
2871
|
}
|
|
@@ -1569,22 +2873,22 @@ function openRefPopup(composer, range, filter) {
|
|
|
1569
2873
|
s.groups.push(group);
|
|
1570
2874
|
}
|
|
1571
2875
|
s.panel.appendChild(list);
|
|
1572
|
-
appendPopupEmpty(s, "
|
|
2876
|
+
appendPopupEmpty(s, t("aiComposer.noRefMatch"));
|
|
2877
|
+
popupFoot(s, t("aiComposer.refHint"));
|
|
1573
2878
|
}
|
|
1574
2879
|
});
|
|
1575
|
-
ta?.setAttribute("aria-expanded", "true");
|
|
1576
2880
|
filterPopupOptions(session, filter);
|
|
1577
2881
|
}
|
|
1578
2882
|
function updateRefPopup(composer, s) {
|
|
1579
2883
|
const ta = getTextarea(composer);
|
|
1580
|
-
const
|
|
1581
|
-
if (!
|
|
2884
|
+
const t2 = ta ? findRefToken(ta) : null;
|
|
2885
|
+
if (!t2) {
|
|
1582
2886
|
closePopup(composer, false);
|
|
1583
2887
|
maybeOpenTriggerPopups(composer);
|
|
1584
2888
|
return;
|
|
1585
2889
|
}
|
|
1586
|
-
s.refRange = { start:
|
|
1587
|
-
filterPopupOptions(s,
|
|
2890
|
+
s.refRange = { start: t2.start, end: t2.end };
|
|
2891
|
+
filterPopupOptions(s, t2.filter);
|
|
1588
2892
|
}
|
|
1589
2893
|
function findRefToken(ta) {
|
|
1590
2894
|
const value = ta.value;
|
|
@@ -1606,30 +2910,34 @@ function maybeOpenTriggerPopups(composer) {
|
|
|
1606
2910
|
}
|
|
1607
2911
|
const sources = REF_SOURCES.get(composer);
|
|
1608
2912
|
if (sources && sources.length > 0) {
|
|
1609
|
-
const
|
|
1610
|
-
if (
|
|
2913
|
+
const t2 = findRefToken(ta);
|
|
2914
|
+
if (t2) openRefPopup(composer, { start: t2.start, end: t2.end }, t2.filter);
|
|
1611
2915
|
}
|
|
1612
2916
|
}
|
|
1613
2917
|
function ensureRefsRow(composer) {
|
|
1614
|
-
const existing = composer.querySelector(".ai-composer-refs");
|
|
2918
|
+
const existing = composer.querySelector(".icen-ai-composer-refs");
|
|
1615
2919
|
if (existing) return existing;
|
|
1616
2920
|
const row = document.createElement("div");
|
|
1617
|
-
row.className = "ai-composer-refs";
|
|
2921
|
+
row.className = "icen-ai-composer-refs";
|
|
1618
2922
|
row.dataset.aiRefs = "auto";
|
|
1619
2923
|
row.hidden = true;
|
|
1620
|
-
const attach = composer.querySelector(".ai-composer-attach");
|
|
1621
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
2924
|
+
const attach = composer.querySelector(".icen-ai-composer-attach");
|
|
2925
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
1622
2926
|
composer.insertBefore(row, attach ?? box ?? null);
|
|
1623
2927
|
return row;
|
|
1624
2928
|
}
|
|
1625
2929
|
function renderRefs(composer) {
|
|
1626
|
-
const row = composer.querySelector(".ai-composer-refs");
|
|
2930
|
+
const row = composer.querySelector(".icen-ai-composer-refs");
|
|
1627
2931
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1628
2932
|
if (!row) return;
|
|
1629
2933
|
row.replaceChildren(
|
|
1630
2934
|
...actives.map((src) => {
|
|
1631
|
-
const chip = makeChip(src.label, true,
|
|
2935
|
+
const chip = makeChip(src.label, true, t("aiComposer.removeRef", { p0: src.label }));
|
|
2936
|
+
chip.prepend(resourceIcon(src));
|
|
2937
|
+
chip.dataset.icenKind = src.kind;
|
|
1632
2938
|
chip.dataset.refId = src.id;
|
|
2939
|
+
chip.dataset.refKind = src.kind;
|
|
2940
|
+
chip.title = [src.label, src.description ?? src.sub].filter(Boolean).join(" \xB7 ");
|
|
1633
2941
|
return chip;
|
|
1634
2942
|
})
|
|
1635
2943
|
);
|
|
@@ -1637,7 +2945,7 @@ function renderRefs(composer) {
|
|
|
1637
2945
|
}
|
|
1638
2946
|
function addActiveRef(composer, source) {
|
|
1639
2947
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1640
|
-
if (actives.some((r) => r.id === source.id)) return;
|
|
2948
|
+
if (actives.some((r) => r.id === source.id && r.kind === source.kind)) return;
|
|
1641
2949
|
actives.push(source);
|
|
1642
2950
|
ACTIVE_REFS.set(composer, actives);
|
|
1643
2951
|
renderRefs(composer);
|
|
@@ -1645,24 +2953,62 @@ function addActiveRef(composer, source) {
|
|
|
1645
2953
|
}
|
|
1646
2954
|
function removeActiveRef(composer, source) {
|
|
1647
2955
|
const actives = ACTIVE_REFS.get(composer) ?? [];
|
|
1648
|
-
const idx = actives.findIndex((r) => r.id === source.id);
|
|
2956
|
+
const idx = actives.findIndex((r) => r.id === source.id && r.kind === source.kind);
|
|
1649
2957
|
if (idx === -1) return;
|
|
1650
2958
|
actives.splice(idx, 1);
|
|
1651
2959
|
ACTIVE_REFS.set(composer, actives);
|
|
2960
|
+
const activeButton = document.activeElement;
|
|
2961
|
+
const restore = activeButton instanceof Element && !!activeButton.closest(".icen-ai-composer-refs");
|
|
1652
2962
|
renderRefs(composer);
|
|
2963
|
+
if (restore) {
|
|
2964
|
+
const buttons = composer.querySelectorAll(".icen-ai-composer-refs .icen-ai-composer-chip-remove");
|
|
2965
|
+
(buttons[Math.min(idx, buttons.length - 1)] ?? getTextarea(composer))?.focus({ preventScroll: true });
|
|
2966
|
+
}
|
|
1653
2967
|
const ta = getTextarea(composer);
|
|
1654
|
-
if (ta) {
|
|
2968
|
+
if (ta && !actives.some((r) => r.label === source.label)) {
|
|
1655
2969
|
const needle = `@${source.label}`;
|
|
1656
|
-
|
|
2970
|
+
let at = ta.value.indexOf(needle);
|
|
2971
|
+
while (at !== -1 && (at > 0 && !/\s/.test(ta.value[at - 1]) || ta.value[at + needle.length] !== void 0 && !/\s/.test(ta.value[at + needle.length]))) at = ta.value.indexOf(needle, at + needle.length);
|
|
1657
2972
|
if (at !== -1) {
|
|
2973
|
+
const start = ta.selectionStart, end = ta.selectionEnd, direction = ta.selectionDirection;
|
|
1658
2974
|
let endIdx = at + needle.length;
|
|
1659
2975
|
if (ta.value[endIdx] === " ") endIdx += 1;
|
|
1660
2976
|
ta.value = ta.value.slice(0, at) + ta.value.slice(endIdx);
|
|
2977
|
+
const shifted = (pos) => pos <= at ? pos : pos < endIdx ? at : pos - (endIdx - at);
|
|
2978
|
+
ta.setSelectionRange(shifted(start), shifted(end), direction);
|
|
1661
2979
|
autosizeTa(ta);
|
|
1662
2980
|
}
|
|
1663
2981
|
}
|
|
1664
2982
|
emit2(composer, "icen:ai-ref", { action: "remove", ref: source });
|
|
1665
2983
|
}
|
|
2984
|
+
function renderFiles(composer) {
|
|
2985
|
+
let row = composer.querySelector(".icen-ai-composer-attach");
|
|
2986
|
+
const files = FILES.get(composer) ?? [];
|
|
2987
|
+
if (!row && files.length) {
|
|
2988
|
+
row = document.createElement("div");
|
|
2989
|
+
row.className = "icen-ai-composer-attach";
|
|
2990
|
+
composer.insertBefore(row, composer.querySelector(".icen-ai-composer-box"));
|
|
2991
|
+
}
|
|
2992
|
+
if (!row) return;
|
|
2993
|
+
row.replaceChildren(...files.map((file, index) => {
|
|
2994
|
+
const chip = makeChip(file.name, true, t("aiComposer.removeAttachment", { p0: file.name }), "file");
|
|
2995
|
+
chip.dataset.icenFile = String(index);
|
|
2996
|
+
const size = document.createElement("span");
|
|
2997
|
+
size.className = "icen-ai-composer-chip-meta";
|
|
2998
|
+
size.textContent = file.size < 1024 ? `${file.size} B` : `${Math.ceil(file.size / 1024)} KB`;
|
|
2999
|
+
chip.insertBefore(size, chip.lastElementChild);
|
|
3000
|
+
chip.title = file.name;
|
|
3001
|
+
return chip;
|
|
3002
|
+
}));
|
|
3003
|
+
row.hidden = !files.length;
|
|
3004
|
+
}
|
|
3005
|
+
function getComposerDraft(el) {
|
|
3006
|
+
if (!isBrowser()) return { text: "" };
|
|
3007
|
+
const c = resolveComposer(el);
|
|
3008
|
+
if (!c) return { text: "" };
|
|
3009
|
+
const refs = ACTIVE_REFS.get(c) ?? [], files = FILES.get(c) ?? [];
|
|
3010
|
+
return { text: getTextarea(c)?.value ?? "", ...refs.length ? { refs: refs.map((r) => ({ ...r })) } : {}, ...files.length ? { files: [...files] } : {} };
|
|
3011
|
+
}
|
|
1666
3012
|
function pushHistory(composer, text) {
|
|
1667
3013
|
const h2 = HISTORIES.get(composer) ?? { items: [], index: -1 };
|
|
1668
3014
|
if (h2.items[h2.items.length - 1] !== text) {
|
|
@@ -1681,31 +3027,35 @@ function setupComposer(composer) {
|
|
|
1681
3027
|
el.__icenAiComposerInit = false;
|
|
1682
3028
|
return void 0;
|
|
1683
3029
|
}
|
|
1684
|
-
const queueEl = composer.querySelector(".ai-composer-queue");
|
|
1685
|
-
const attachEl = composer.querySelector(".ai-composer-attach");
|
|
3030
|
+
const queueEl = composer.querySelector(".icen-ai-composer-queue");
|
|
1686
3031
|
const { sendBtn, sendIcon, stopIcon } = ensureIcons(composer);
|
|
1687
3032
|
if (!ta.hasAttribute("placeholder")) {
|
|
1688
|
-
ta.setAttribute("placeholder", "
|
|
3033
|
+
ta.setAttribute("placeholder", t("aiComposer.placeholder"));
|
|
1689
3034
|
}
|
|
1690
3035
|
const renderQueue = () => renderQueueChips(composer);
|
|
1691
|
-
const enqueue = (
|
|
3036
|
+
const enqueue = (draft) => {
|
|
1692
3037
|
const queue = QUEUES.get(composer) ?? [];
|
|
1693
|
-
queue.push(
|
|
3038
|
+
queue.push({ ...draft, ...draft.refs ? { refs: draft.refs.map((r) => ({ ...r })) } : {}, ...draft.files ? { files: [...draft.files] } : {} });
|
|
1694
3039
|
QUEUES.set(composer, queue);
|
|
1695
3040
|
renderQueue();
|
|
1696
3041
|
};
|
|
1697
3042
|
const isRunning = () => RUNNING.get(composer) ?? false;
|
|
1698
3043
|
const submit = () => {
|
|
1699
|
-
|
|
1700
|
-
|
|
3044
|
+
if (ta.disabled || ta.readOnly || composing) return;
|
|
3045
|
+
const draft = getComposerDraft(composer);
|
|
3046
|
+
if (!draft.text.trim() && !draft.files?.length && !draft.refs?.length) return;
|
|
1701
3047
|
ta.value = "";
|
|
1702
3048
|
autosizeTa(ta);
|
|
3049
|
+
ACTIVE_REFS.set(composer, []);
|
|
3050
|
+
FILES.set(composer, []);
|
|
3051
|
+
renderRefs(composer);
|
|
3052
|
+
renderFiles(composer);
|
|
1703
3053
|
if (isRunning()) {
|
|
1704
|
-
enqueue(
|
|
1705
|
-
emit2(composer, "icen:ai-queue",
|
|
3054
|
+
enqueue(draft);
|
|
3055
|
+
emit2(composer, "icen:ai-queue", draft);
|
|
1706
3056
|
} else {
|
|
1707
|
-
pushHistory(composer, text);
|
|
1708
|
-
emit2(composer, "icen:ai-send",
|
|
3057
|
+
pushHistory(composer, draft.text);
|
|
3058
|
+
emit2(composer, "icen:ai-send", draft);
|
|
1709
3059
|
}
|
|
1710
3060
|
};
|
|
1711
3061
|
SUBMITS.set(composer, submit);
|
|
@@ -1713,10 +3063,14 @@ function setupComposer(composer) {
|
|
|
1713
3063
|
const queue = QUEUES.get(composer) ?? [];
|
|
1714
3064
|
if (queue.length === 0) return;
|
|
1715
3065
|
const index = queue.length - 1;
|
|
1716
|
-
const
|
|
3066
|
+
const draft = queue.pop();
|
|
1717
3067
|
QUEUES.set(composer, queue);
|
|
1718
3068
|
renderQueue();
|
|
1719
|
-
ta.value = text;
|
|
3069
|
+
ta.value = draft.text;
|
|
3070
|
+
for (const ref of draft.refs ?? []) addActiveRef(composer, ref);
|
|
3071
|
+
const files = FILES.get(composer) ?? [];
|
|
3072
|
+
FILES.set(composer, Array.from(/* @__PURE__ */ new Set([...files, ...draft.files ?? []])));
|
|
3073
|
+
renderFiles(composer);
|
|
1720
3074
|
autosizeTa(ta);
|
|
1721
3075
|
emit2(composer, "icen:ai-dequeue", { index });
|
|
1722
3076
|
};
|
|
@@ -1738,7 +3092,7 @@ function setupComposer(composer) {
|
|
|
1738
3092
|
autosizeTa(ta);
|
|
1739
3093
|
};
|
|
1740
3094
|
const onKeydown = (e) => {
|
|
1741
|
-
if (composing || e.isComposing) return;
|
|
3095
|
+
if (composing || e.isComposing || ta.disabled || ta.readOnly) return;
|
|
1742
3096
|
const session = POPUP.get(composer);
|
|
1743
3097
|
if (session) {
|
|
1744
3098
|
popupKeydown(composer, session, e);
|
|
@@ -1746,6 +3100,7 @@ function setupComposer(composer) {
|
|
|
1746
3100
|
}
|
|
1747
3101
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
1748
3102
|
e.preventDefault();
|
|
3103
|
+
if (ta.value.startsWith("/") && runComposerCommand(composer, commandToken(ta.value))) return;
|
|
1749
3104
|
submit();
|
|
1750
3105
|
return;
|
|
1751
3106
|
}
|
|
@@ -1753,7 +3108,7 @@ function setupComposer(composer) {
|
|
|
1753
3108
|
const h2 = HISTORIES.get(composer);
|
|
1754
3109
|
const browsing = (h2?.index ?? -1) >= 0;
|
|
1755
3110
|
if (ta.value === "") {
|
|
1756
|
-
if (
|
|
3111
|
+
if ((QUEUES.get(composer) ?? []).length > 0) {
|
|
1757
3112
|
e.preventDefault();
|
|
1758
3113
|
takeBackLastQueued();
|
|
1759
3114
|
return;
|
|
@@ -1778,6 +3133,7 @@ function setupComposer(composer) {
|
|
|
1778
3133
|
};
|
|
1779
3134
|
const onInput = () => {
|
|
1780
3135
|
autosizeTa(ta);
|
|
3136
|
+
if (composing) return;
|
|
1781
3137
|
const h2 = HISTORIES.get(composer);
|
|
1782
3138
|
if (h2 && h2.index >= 0 && ta.value !== h2.items[h2.index]) h2.index = -1;
|
|
1783
3139
|
const session = POPUP.get(composer);
|
|
@@ -1791,9 +3147,11 @@ function setupComposer(composer) {
|
|
|
1791
3147
|
let composing = false;
|
|
1792
3148
|
const onCompositionStart = () => {
|
|
1793
3149
|
composing = true;
|
|
3150
|
+
closePopup(composer, false);
|
|
1794
3151
|
};
|
|
1795
3152
|
const onCompositionEnd = () => {
|
|
1796
3153
|
composing = false;
|
|
3154
|
+
onInput();
|
|
1797
3155
|
};
|
|
1798
3156
|
const onSendClick = () => {
|
|
1799
3157
|
if (isRunning()) {
|
|
@@ -1803,22 +3161,25 @@ function setupComposer(composer) {
|
|
|
1803
3161
|
}
|
|
1804
3162
|
};
|
|
1805
3163
|
const onQueueClick = (e) => {
|
|
1806
|
-
const btn = e.target instanceof Element ? e.target.closest(".ai-composer-chip-remove") : null;
|
|
3164
|
+
const btn = e.target instanceof Element ? e.target.closest(".icen-ai-composer-chip-remove") : null;
|
|
1807
3165
|
if (!btn) return;
|
|
1808
|
-
const index = Array.from(queueEl?.querySelectorAll(".ai-composer-chip-remove") ?? []).indexOf(btn);
|
|
3166
|
+
const index = Array.from(queueEl?.querySelectorAll(".icen-ai-composer-chip-remove") ?? []).indexOf(btn);
|
|
1809
3167
|
const queue = QUEUES.get(composer) ?? [];
|
|
1810
3168
|
if (index >= 0 && index < queue.length) {
|
|
1811
3169
|
queue.splice(index, 1);
|
|
1812
3170
|
QUEUES.set(composer, queue);
|
|
1813
3171
|
renderQueue();
|
|
3172
|
+
const buttons = queueEl?.querySelectorAll(".icen-ai-composer-chip-remove");
|
|
3173
|
+
(buttons?.[Math.min(index, buttons.length - 1)] ?? ta).focus({ preventScroll: true });
|
|
1814
3174
|
emit2(composer, "icen:ai-dequeue", { index });
|
|
1815
3175
|
}
|
|
1816
3176
|
};
|
|
1817
3177
|
const onRefsClick = (e) => {
|
|
1818
|
-
const btn = e.target instanceof Element ? e.target.closest(".ai-composer-chip-remove") : null;
|
|
1819
|
-
if (!btn || !btn.closest(".ai-composer-refs")) return;
|
|
1820
|
-
const id = btn.closest(".ai-composer-chip")?.dataset.refId;
|
|
1821
|
-
const
|
|
3178
|
+
const btn = e.target instanceof Element ? e.target.closest(".icen-ai-composer-chip-remove") : null;
|
|
3179
|
+
if (!btn || !btn.closest(".icen-ai-composer-refs")) return;
|
|
3180
|
+
const id = btn.closest(".icen-ai-composer-chip")?.dataset.refId;
|
|
3181
|
+
const kind = btn.closest(".icen-ai-composer-chip")?.dataset.refKind;
|
|
3182
|
+
const source = (ACTIVE_REFS.get(composer) ?? []).find((r) => r.id === id && r.kind === kind);
|
|
1822
3183
|
if (source) removeActiveRef(composer, source);
|
|
1823
3184
|
};
|
|
1824
3185
|
const fileInput = document.createElement("input");
|
|
@@ -1827,20 +3188,32 @@ function setupComposer(composer) {
|
|
|
1827
3188
|
fileInput.multiple = true;
|
|
1828
3189
|
composer.appendChild(fileInput);
|
|
1829
3190
|
const onAttachClick = () => {
|
|
1830
|
-
fileInput.click();
|
|
3191
|
+
if (!ta.disabled && !ta.readOnly) fileInput.click();
|
|
1831
3192
|
};
|
|
1832
3193
|
const addFiles = (files) => {
|
|
1833
|
-
if (files.length
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
remove?.addEventListener("click", () => chip.remove(), { once: true });
|
|
1839
|
-
attachEl.appendChild(chip);
|
|
1840
|
-
}
|
|
1841
|
-
attachEl.hidden = false;
|
|
3194
|
+
if (!files.length || ta.disabled || ta.readOnly) return;
|
|
3195
|
+
const current2 = FILES.get(composer) ?? [];
|
|
3196
|
+
const accepted = [];
|
|
3197
|
+
for (const file of files) {
|
|
3198
|
+
if (![...current2, ...accepted].some((c) => c.name === file.name && c.size === file.size && c.lastModified === file.lastModified && c.type === file.type)) accepted.push(file);
|
|
1842
3199
|
}
|
|
1843
|
-
|
|
3200
|
+
if (!accepted.length) return;
|
|
3201
|
+
FILES.set(composer, [...current2, ...accepted]);
|
|
3202
|
+
renderFiles(composer);
|
|
3203
|
+
emit2(composer, "icen:ai-attach", { files: accepted });
|
|
3204
|
+
};
|
|
3205
|
+
const onRemoveFile = (e) => {
|
|
3206
|
+
const button = e.target instanceof Element ? e.target.closest(".icen-ai-composer-attach .icen-ai-composer-chip-remove") : null;
|
|
3207
|
+
if (!button) return;
|
|
3208
|
+
const index = Number(button.closest("[data-icen-file]")?.dataset.icenFile);
|
|
3209
|
+
const files = FILES.get(composer) ?? [];
|
|
3210
|
+
if (!Number.isInteger(index) || index < 0 || index >= files.length) return;
|
|
3211
|
+
const [file] = files.splice(index, 1);
|
|
3212
|
+
FILES.set(composer, files);
|
|
3213
|
+
renderFiles(composer);
|
|
3214
|
+
const buttons = composer.querySelectorAll(".icen-ai-composer-attach .icen-ai-composer-chip-remove");
|
|
3215
|
+
(buttons[Math.min(index, buttons.length - 1)] ?? ta).focus({ preventScroll: true });
|
|
3216
|
+
emit2(composer, "icen:ai-attachment-remove", { file, files: [...files] });
|
|
1844
3217
|
};
|
|
1845
3218
|
const onFileChange = () => {
|
|
1846
3219
|
const files = Array.from(fileInput.files ?? []);
|
|
@@ -1853,7 +3226,7 @@ function setupComposer(composer) {
|
|
|
1853
3226
|
e.preventDefault();
|
|
1854
3227
|
addFiles(files);
|
|
1855
3228
|
};
|
|
1856
|
-
const boxEl = composer.querySelector(".ai-composer-box");
|
|
3229
|
+
const boxEl = composer.querySelector(".icen-ai-composer-box");
|
|
1857
3230
|
const onDragOver = (e) => {
|
|
1858
3231
|
if (!e.dataTransfer?.types.includes("Files")) return;
|
|
1859
3232
|
e.preventDefault();
|
|
@@ -1880,7 +3253,8 @@ function setupComposer(composer) {
|
|
|
1880
3253
|
sendBtn?.addEventListener("click", onSendClick);
|
|
1881
3254
|
queueEl?.addEventListener("click", onQueueClick);
|
|
1882
3255
|
composer.addEventListener("click", onRefsClick);
|
|
1883
|
-
composer.
|
|
3256
|
+
composer.addEventListener("click", onRemoveFile);
|
|
3257
|
+
composer.querySelector("[data-icen-ai-attach]")?.addEventListener("click", onAttachClick);
|
|
1884
3258
|
fileInput.addEventListener("change", onFileChange);
|
|
1885
3259
|
const initialRunning = RUNNING.get(composer) ?? composer.classList.contains("is-running");
|
|
1886
3260
|
if (initialRunning) setComposerRunning(composer, true);
|
|
@@ -1891,6 +3265,7 @@ function setupComposer(composer) {
|
|
|
1891
3265
|
autosizeTa(ta);
|
|
1892
3266
|
renderQueue();
|
|
1893
3267
|
renderRefs(composer);
|
|
3268
|
+
renderFiles(composer);
|
|
1894
3269
|
return () => {
|
|
1895
3270
|
closePopup(composer, false);
|
|
1896
3271
|
ta.removeEventListener("keydown", onKeydown);
|
|
@@ -1904,7 +3279,8 @@ function setupComposer(composer) {
|
|
|
1904
3279
|
sendBtn?.removeEventListener("click", onSendClick);
|
|
1905
3280
|
queueEl?.removeEventListener("click", onQueueClick);
|
|
1906
3281
|
composer.removeEventListener("click", onRefsClick);
|
|
1907
|
-
composer.
|
|
3282
|
+
composer.removeEventListener("click", onRemoveFile);
|
|
3283
|
+
composer.querySelector("[data-icen-ai-attach]")?.removeEventListener("click", onAttachClick);
|
|
1908
3284
|
fileInput.removeEventListener("change", onFileChange);
|
|
1909
3285
|
fileInput.remove();
|
|
1910
3286
|
el.__icenAiComposerInit = false;
|
|
@@ -1915,10 +3291,10 @@ function initAiComposer(root) {
|
|
|
1915
3291
|
if (isBrowser()) {
|
|
1916
3292
|
const scope = root ?? document;
|
|
1917
3293
|
const candidates = [];
|
|
1918
|
-
if (scope instanceof Element && scope.matches("[data-ai-composer]")) {
|
|
3294
|
+
if (scope instanceof Element && scope.matches("[data-icen-ai-composer]")) {
|
|
1919
3295
|
candidates.push(scope);
|
|
1920
3296
|
}
|
|
1921
|
-
candidates.push(...Array.from(scope.querySelectorAll("[data-ai-composer]")));
|
|
3297
|
+
candidates.push(...Array.from(scope.querySelectorAll("[data-icen-ai-composer]")));
|
|
1922
3298
|
for (const composer of candidates) {
|
|
1923
3299
|
const cleanup = setupComposer(composer);
|
|
1924
3300
|
if (cleanup) cleanups.push(cleanup);
|
|
@@ -1929,7 +3305,7 @@ function initAiComposer(root) {
|
|
|
1929
3305
|
cleanups.length = 0;
|
|
1930
3306
|
};
|
|
1931
3307
|
}
|
|
1932
|
-
function setComposerModels(el, providers,
|
|
3308
|
+
function setComposerModels(el, providers, current2) {
|
|
1933
3309
|
if (!isBrowser()) return;
|
|
1934
3310
|
const composer = resolveComposer(el);
|
|
1935
3311
|
if (!composer) return;
|
|
@@ -1939,13 +3315,13 @@ function setComposerModels(el, providers, current) {
|
|
|
1939
3315
|
if (list.length === 0) {
|
|
1940
3316
|
MODELS.delete(composer);
|
|
1941
3317
|
MODEL_CTX.delete(composer);
|
|
1942
|
-
const btn = composer.querySelector("[data-ai-model-open]");
|
|
1943
|
-
if (btn?.dataset.
|
|
3318
|
+
const btn = composer.querySelector("[data-icen-ai-model-open]");
|
|
3319
|
+
if (btn?.dataset.icenAiModelOpen === "auto") btn.remove();
|
|
1944
3320
|
syncToolbar(composer);
|
|
1945
3321
|
refreshUsageRing(composer);
|
|
1946
3322
|
return;
|
|
1947
3323
|
}
|
|
1948
|
-
const cur =
|
|
3324
|
+
const cur = current2 ?? { provider: list[0].id, model: list[0].models[0].id };
|
|
1949
3325
|
MODELS.set(composer, { providers: list, current: cur });
|
|
1950
3326
|
const provider = list.find((p) => p.id === cur.provider) ?? list[0];
|
|
1951
3327
|
const model = provider.models.find((m) => m.id === cur.model) ?? provider.models[0];
|
|
@@ -1966,10 +3342,13 @@ function setComposerCommands(el, commands) {
|
|
|
1966
3342
|
if (list.length === 0) {
|
|
1967
3343
|
COMMANDS.delete(composer);
|
|
1968
3344
|
const session = POPUP.get(composer);
|
|
1969
|
-
if (session?.mode === "command") closePopup(composer);
|
|
3345
|
+
if (session?.mode === "command" || session?.mode === "library") closePopup(composer);
|
|
3346
|
+
syncToolbar(composer);
|
|
1970
3347
|
return;
|
|
1971
3348
|
}
|
|
1972
3349
|
COMMANDS.set(composer, list);
|
|
3350
|
+
syncToolbar(composer);
|
|
3351
|
+
if (POPUP.get(composer)) closePopup(composer);
|
|
1973
3352
|
}
|
|
1974
3353
|
function setComposerRefs(el, sources) {
|
|
1975
3354
|
if (!isBrowser()) return;
|
|
@@ -1977,6 +3356,8 @@ function setComposerRefs(el, sources) {
|
|
|
1977
3356
|
if (!composer) return;
|
|
1978
3357
|
const list = (Array.isArray(sources) ? sources : []).filter((s) => s && typeof s.label === "string" && s.label);
|
|
1979
3358
|
REF_SOURCES.set(composer, list);
|
|
3359
|
+
syncToolbar(composer);
|
|
3360
|
+
if (POPUP.get(composer)) closePopup(composer);
|
|
1980
3361
|
if (list.length === 0) {
|
|
1981
3362
|
const session = POPUP.get(composer);
|
|
1982
3363
|
if (session?.mode === "ref") closePopup(composer);
|
|
@@ -1990,8 +3371,8 @@ function setComposerUsage(el, usage, opts = {}) {
|
|
|
1990
3371
|
if (!composer) return;
|
|
1991
3372
|
if (!usage) {
|
|
1992
3373
|
USAGE.delete(composer);
|
|
1993
|
-
const mount = composer.querySelector(".ai-composer-usage");
|
|
1994
|
-
if (mount?.dataset.
|
|
3374
|
+
const mount = composer.querySelector(".icen-ai-composer-usage");
|
|
3375
|
+
if (mount?.dataset.icenAiUsage === "auto") mount.remove();
|
|
1995
3376
|
syncToolbar(composer);
|
|
1996
3377
|
return;
|
|
1997
3378
|
}
|
|
@@ -2003,7 +3384,7 @@ function setComposerTodo(el, items) {
|
|
|
2003
3384
|
if (!isBrowser()) return;
|
|
2004
3385
|
const composer = resolveComposer(el);
|
|
2005
3386
|
if (!composer) return;
|
|
2006
|
-
let chip = composer.querySelector(".ai-composer-todo");
|
|
3387
|
+
let chip = composer.querySelector(".icen-ai-composer-todo");
|
|
2007
3388
|
if (!items || items.length === 0) {
|
|
2008
3389
|
TODO_STATES.delete(composer);
|
|
2009
3390
|
chip?.remove();
|
|
@@ -2013,17 +3394,17 @@ function setComposerTodo(el, items) {
|
|
|
2013
3394
|
if (!chip) {
|
|
2014
3395
|
const btn = document.createElement("button");
|
|
2015
3396
|
btn.type = "button";
|
|
2016
|
-
btn.className = "ai-composer-todo";
|
|
3397
|
+
btn.className = "icen-ai-composer-todo";
|
|
2017
3398
|
btn.setAttribute("aria-haspopup", "true");
|
|
2018
3399
|
btn.addEventListener("click", () => {
|
|
2019
3400
|
const cur = TODO_STATES.get(composer);
|
|
2020
3401
|
if (!cur) return;
|
|
2021
3402
|
const p = document.createElement("div");
|
|
2022
|
-
p.className = "popover ai-composer-todo-pop";
|
|
3403
|
+
p.className = "icen-popover icen-ai-composer-todo-pop";
|
|
2023
3404
|
p.hidden = true;
|
|
2024
3405
|
const title = document.createElement("div");
|
|
2025
|
-
title.className = "ai-usage-popover-title";
|
|
2026
|
-
title.textContent = "
|
|
3406
|
+
title.className = "icen-ai-usage-popover-title";
|
|
3407
|
+
title.textContent = t("aiComposer.currentTodos");
|
|
2027
3408
|
const body = document.createElement("div");
|
|
2028
3409
|
body.className = "ai-usage-popover-body";
|
|
2029
3410
|
renderAiTodo(body, cur);
|
|
@@ -2041,39 +3422,42 @@ function setComposerTodo(el, items) {
|
|
|
2041
3422
|
);
|
|
2042
3423
|
if (icon) chip.appendChild(icon);
|
|
2043
3424
|
chip.appendChild(document.createElement("span")).className = "ai-composer-todo-label";
|
|
2044
|
-
const toolbar = composer.querySelector(".ai-composer-toolbar");
|
|
2045
|
-
const usage = composer.querySelector(".ai-composer-usage");
|
|
3425
|
+
const toolbar = composer.querySelector(".icen-ai-composer-toolbar");
|
|
3426
|
+
const usage = composer.querySelector(".icen-ai-composer-usage");
|
|
2046
3427
|
if (toolbar) toolbar.insertBefore(chip, usage ?? null);
|
|
2047
3428
|
else {
|
|
2048
|
-
const box = composer.querySelector(".ai-composer-box");
|
|
3429
|
+
const box = composer.querySelector(".icen-ai-composer-box");
|
|
2049
3430
|
box?.before(chip);
|
|
2050
3431
|
}
|
|
2051
3432
|
}
|
|
2052
|
-
const done = items.filter((
|
|
2053
|
-
const failed = items.some((
|
|
3433
|
+
const done = items.filter((t2) => t2.status === "done").length;
|
|
3434
|
+
const failed = items.some((t2) => t2.status === "error" || t2.status === "cancelled");
|
|
2054
3435
|
chip.classList.toggle("is-done", done === items.length && !failed);
|
|
2055
3436
|
chip.classList.toggle("is-error", failed);
|
|
2056
|
-
chip.setAttribute("aria-label",
|
|
3437
|
+
chip.setAttribute("aria-label", t("aiComposer.todoChip", { p0: done, p1: items.length, p2: failed ? t("aiComposer.todoHasError") : "" }));
|
|
2057
3438
|
const label = chip.querySelector(".ai-composer-todo-label");
|
|
2058
3439
|
if (label) label.textContent = `${done}/${items.length}`;
|
|
2059
3440
|
}
|
|
2060
3441
|
var BOUND = /* @__PURE__ */ new WeakSet();
|
|
2061
3442
|
function bindComposer(el, opts = {}) {
|
|
2062
3443
|
const noop = () => void 0;
|
|
2063
|
-
if (!isBrowser()) return { unbind: noop };
|
|
3444
|
+
if (!isBrowser()) return { unbind: noop, retry: () => false };
|
|
2064
3445
|
const composer = resolveComposer(el);
|
|
2065
|
-
if (!composer) return { unbind: noop };
|
|
2066
|
-
if (BOUND.has(composer)) return { unbind: noop };
|
|
3446
|
+
if (!composer) return { unbind: noop, retry: () => false };
|
|
3447
|
+
if (BOUND.has(composer)) return { unbind: noop, retry: () => false };
|
|
2067
3448
|
BOUND.add(composer);
|
|
2068
3449
|
if (opts.popoverSizing) POPUP_SIZING.set(composer, opts.popoverSizing);
|
|
2069
3450
|
const disposers = [];
|
|
2070
3451
|
const usageCfg = opts.usage;
|
|
2071
3452
|
const manageRunning = opts.running ?? true;
|
|
3453
|
+
let bound = true;
|
|
3454
|
+
let retry = () => false;
|
|
3455
|
+
let updateUsage = (_detail) => {
|
|
3456
|
+
};
|
|
2072
3457
|
if (usageCfg) {
|
|
2073
3458
|
let cost = 0;
|
|
2074
3459
|
let billing = {};
|
|
2075
|
-
|
|
2076
|
-
const detail = e.detail;
|
|
3460
|
+
updateUsage = (detail) => {
|
|
2077
3461
|
if (!detail?.usage) return;
|
|
2078
3462
|
if (typeof detail.cost === "number") cost += detail.cost;
|
|
2079
3463
|
let usage;
|
|
@@ -2098,8 +3482,12 @@ function bindComposer(el, opts = {}) {
|
|
|
2098
3482
|
cost: cost > 0 ? Math.round(cost * 1e6) / 1e6 : void 0
|
|
2099
3483
|
});
|
|
2100
3484
|
};
|
|
2101
|
-
|
|
2102
|
-
|
|
3485
|
+
if (!opts.client || !opts.messages) {
|
|
3486
|
+
const onDone = (e) => updateUsage(e.detail);
|
|
3487
|
+
const target = opts.eventTarget ?? document;
|
|
3488
|
+
target.addEventListener("icen:ai-done", onDone);
|
|
3489
|
+
disposers.push(() => target.removeEventListener("icen:ai-done", onDone));
|
|
3490
|
+
}
|
|
2103
3491
|
}
|
|
2104
3492
|
if (opts.client && !opts.messages) {
|
|
2105
3493
|
console.warn("[ai-composer] client \u6A21\u5F0F\u9700\u8981 opts.messages\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u7EAF\u72B6\u6001\u7ED1\u5B9A");
|
|
@@ -2108,81 +3496,164 @@ function bindComposer(el, opts = {}) {
|
|
|
2108
3496
|
const client = opts.client;
|
|
2109
3497
|
const messages = opts.messages;
|
|
2110
3498
|
const history = [];
|
|
2111
|
-
let
|
|
3499
|
+
let active = null;
|
|
3500
|
+
let retryable = null;
|
|
2112
3501
|
const metaOf = (r) => {
|
|
2113
3502
|
const tok = r.usage.total ?? 0;
|
|
2114
|
-
const parts = [tok > 0 ? `${formatTokens(tok)} tok` : "
|
|
3503
|
+
const parts = [tok > 0 ? `${formatTokens(tok)} tok` : t("aiComposer.done")];
|
|
2115
3504
|
if (typeof r.cost === "number") parts.push(`$${r.cost.toFixed(4)}`);
|
|
2116
|
-
return
|
|
3505
|
+
return t("aiComposer.justNow", { p0: parts.join(" \xB7 ") });
|
|
2117
3506
|
};
|
|
2118
|
-
const startTurn = () => {
|
|
2119
|
-
const assistant = renderAiMessage(messages, {
|
|
3507
|
+
const startTurn = (previous, draft) => {
|
|
3508
|
+
const assistant = previous?.assistant ?? renderAiMessage(messages, {
|
|
2120
3509
|
role: "assistant",
|
|
2121
3510
|
content: "",
|
|
2122
3511
|
streaming: true,
|
|
2123
3512
|
model: client.config.model
|
|
2124
3513
|
});
|
|
3514
|
+
if (previous) {
|
|
3515
|
+
const restoreRetryFocus = assistant.body.contains(document.activeElement);
|
|
3516
|
+
previous.textNode?.remove();
|
|
3517
|
+
assistant.body.querySelectorAll(".icen-ai-msg-continue,.icen-ai-msg-error-text").forEach((node) => node.remove());
|
|
3518
|
+
assistant.el.classList.remove("icen-ai-msg--error");
|
|
3519
|
+
assistant.setMeta("");
|
|
3520
|
+
if (restoreRetryFocus) assistant.el.querySelector('[data-icen-ai-msg-action="retry"]')?.focus({ preventScroll: true });
|
|
3521
|
+
}
|
|
2125
3522
|
const streamH = assistant.stream();
|
|
3523
|
+
assistant.el.classList.add("is-streaming");
|
|
3524
|
+
const turn = { assistant, stream: streamH, textNode: assistant.body.lastElementChild, request: [...history], session: null, text: "", draft: previous?.draft ?? draft, preparation: new AbortController() };
|
|
3525
|
+
active = turn;
|
|
3526
|
+
retryable = null;
|
|
2126
3527
|
setComposerRunning(composer, true);
|
|
2127
|
-
const s = client.stream({ messages: [...history] });
|
|
2128
|
-
session = s;
|
|
2129
3528
|
let failed = false;
|
|
2130
3529
|
void (async () => {
|
|
2131
|
-
|
|
2132
|
-
if (
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
3530
|
+
try {
|
|
3531
|
+
if (turn.draft && opts.prepareMessage) {
|
|
3532
|
+
const content = await opts.prepareMessage(turn.draft, { signal: turn.preparation.signal });
|
|
3533
|
+
if (!bound || active !== turn) return;
|
|
3534
|
+
turn.request[turn.request.length - 1] = { role: "user", content };
|
|
3535
|
+
history.splice(0, history.length, ...turn.request);
|
|
3536
|
+
} else if (turn.draft?.files?.length) throw new Error(t("aiComposer.filesNeedAdapter"));
|
|
3537
|
+
const s = client.stream({ messages: turn.request });
|
|
3538
|
+
turn.session = s;
|
|
3539
|
+
void s.done.catch(() => {
|
|
3540
|
+
});
|
|
3541
|
+
for await (const chunk of s) {
|
|
3542
|
+
if (!bound || active !== turn) return;
|
|
3543
|
+
if (chunk.type === "text") {
|
|
3544
|
+
turn.text += chunk.delta;
|
|
3545
|
+
streamH.append(chunk.delta);
|
|
3546
|
+
} else if (chunk.type === "error") {
|
|
3547
|
+
failed = true;
|
|
3548
|
+
streamH.fail();
|
|
3549
|
+
assistant.setError(chunk.message);
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
const result = await s.done;
|
|
3553
|
+
if (!bound || active !== turn) return;
|
|
3554
|
+
if (!failed) {
|
|
3555
|
+
streamH.done();
|
|
3556
|
+
assistant.setMeta(metaOf(result));
|
|
3557
|
+
updateUsage(result);
|
|
3558
|
+
}
|
|
3559
|
+
if (result.text) history.push({ role: "assistant", content: result.text });
|
|
3560
|
+
} catch (error) {
|
|
3561
|
+
if (!bound || active !== turn) return;
|
|
3562
|
+
failed = true;
|
|
3563
|
+
streamH.fail();
|
|
3564
|
+
assistant.setError(error instanceof Error ? error.message : String(error));
|
|
3565
|
+
} finally {
|
|
3566
|
+
if (!bound || active !== turn) return;
|
|
3567
|
+
active = null;
|
|
3568
|
+
assistant.el.classList.remove("is-streaming");
|
|
3569
|
+
setComposerRunning(composer, false);
|
|
3570
|
+
if (failed) {
|
|
3571
|
+
retryable = turn;
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
const queue = QUEUES.get(composer) ?? [];
|
|
3575
|
+
if (queue.length > 0) {
|
|
3576
|
+
const next = queue.shift();
|
|
3577
|
+
QUEUES.set(composer, queue);
|
|
3578
|
+
renderQueueChips(composer);
|
|
3579
|
+
emit2(composer, "icen:ai-dequeue", { index: 0 });
|
|
3580
|
+
if (bound) send(next);
|
|
2137
3581
|
}
|
|
2138
|
-
}
|
|
2139
|
-
const result = await s.done;
|
|
2140
|
-
session = null;
|
|
2141
|
-
if (!failed) streamH.done();
|
|
2142
|
-
assistant.setMeta(metaOf(result));
|
|
2143
|
-
if (result.text) history.push({ role: "assistant", content: result.text });
|
|
2144
|
-
setComposerRunning(composer, false);
|
|
2145
|
-
const queue = QUEUES.get(composer) ?? [];
|
|
2146
|
-
if (queue.length > 0) {
|
|
2147
|
-
const next = queue.shift() ?? "";
|
|
2148
|
-
QUEUES.set(composer, queue);
|
|
2149
|
-
renderQueueChips(composer);
|
|
2150
|
-
emit2(composer, "icen:ai-dequeue", { index: 0 });
|
|
2151
|
-
send(next);
|
|
2152
3582
|
}
|
|
2153
3583
|
})();
|
|
2154
3584
|
};
|
|
2155
|
-
const send = (
|
|
2156
|
-
|
|
3585
|
+
const send = (draft) => {
|
|
3586
|
+
if (!bound || active) return;
|
|
3587
|
+
const missingRefs = (draft.refs ?? []).filter((r) => !draft.text.includes(`@${r.label}`));
|
|
3588
|
+
const text = [draft.text, ...missingRefs.map((r) => `@${r.label}`)].filter(Boolean).join("\n");
|
|
3589
|
+
const message = renderAiMessage(messages, { role: "user", content: draft.text });
|
|
3590
|
+
if (draft.refs?.length || draft.files?.length) {
|
|
3591
|
+
const context = document.createElement("div");
|
|
3592
|
+
context.className = "icen-ai-msg-context";
|
|
3593
|
+
for (const ref of draft.refs ?? []) {
|
|
3594
|
+
const chip = makeChip(ref.label, false, "");
|
|
3595
|
+
chip.prepend(resourceIcon(ref));
|
|
3596
|
+
context.append(chip);
|
|
3597
|
+
}
|
|
3598
|
+
for (const file of draft.files ?? []) context.append(makeChip(file.name, false, "", "file"));
|
|
3599
|
+
message.body.append(context);
|
|
3600
|
+
}
|
|
2157
3601
|
history.push({ role: "user", content: text });
|
|
2158
|
-
startTurn();
|
|
3602
|
+
startTurn(void 0, draft);
|
|
2159
3603
|
};
|
|
2160
3604
|
const onSend = (e) => {
|
|
2161
|
-
const
|
|
2162
|
-
if (typeof text === "string" && text) send(
|
|
3605
|
+
const draft = e.detail;
|
|
3606
|
+
if (typeof draft?.text === "string" && (draft.text || draft.files?.length || draft.refs?.length)) send(draft);
|
|
2163
3607
|
};
|
|
2164
3608
|
const onStop = () => {
|
|
2165
|
-
|
|
3609
|
+
const turn = active;
|
|
3610
|
+
if (!turn) return;
|
|
3611
|
+
active = null;
|
|
3612
|
+
turn.preparation.abort();
|
|
3613
|
+
retryable = turn;
|
|
3614
|
+
turn.stream.cancel();
|
|
3615
|
+
turn.assistant.el.classList.remove("is-streaming");
|
|
3616
|
+
turn.assistant.setMeta(t("aiComposer.stopped"));
|
|
3617
|
+
if (turn.text) history.push({ role: "assistant", content: turn.text });
|
|
3618
|
+
setComposerRunning(composer, false);
|
|
3619
|
+
turn.session?.cancel();
|
|
3620
|
+
};
|
|
3621
|
+
retry = () => {
|
|
3622
|
+
if (!bound || active || !retryable) return false;
|
|
3623
|
+
const turn = retryable;
|
|
3624
|
+
history.splice(0, history.length, ...turn.request);
|
|
3625
|
+
startTurn(turn);
|
|
3626
|
+
return true;
|
|
3627
|
+
};
|
|
3628
|
+
const onRetry = (event) => {
|
|
3629
|
+
if (event.detail?.el === retryable?.assistant.el) retry();
|
|
2166
3630
|
};
|
|
2167
3631
|
composer.addEventListener("icen:ai-send", onSend);
|
|
2168
3632
|
composer.addEventListener("icen:ai-stop", onStop);
|
|
3633
|
+
messages.addEventListener("icen:ai-retry", onRetry);
|
|
2169
3634
|
disposers.push(() => {
|
|
2170
3635
|
composer.removeEventListener("icen:ai-send", onSend);
|
|
2171
3636
|
composer.removeEventListener("icen:ai-stop", onStop);
|
|
2172
|
-
|
|
3637
|
+
messages.removeEventListener("icen:ai-retry", onRetry);
|
|
3638
|
+
onStop();
|
|
3639
|
+
retryable = null;
|
|
2173
3640
|
});
|
|
2174
3641
|
} else if (manageRunning) {
|
|
2175
3642
|
const onSend = () => setComposerRunning(composer, true);
|
|
2176
3643
|
const onDone = () => setComposerRunning(composer, false);
|
|
2177
3644
|
composer.addEventListener("icen:ai-send", onSend);
|
|
2178
|
-
|
|
3645
|
+
const target = opts.eventTarget ?? document;
|
|
3646
|
+
target.addEventListener("icen:ai-done", onDone);
|
|
2179
3647
|
disposers.push(() => {
|
|
2180
3648
|
composer.removeEventListener("icen:ai-send", onSend);
|
|
2181
|
-
|
|
3649
|
+
target.removeEventListener("icen:ai-done", onDone);
|
|
2182
3650
|
});
|
|
2183
3651
|
}
|
|
2184
3652
|
return {
|
|
3653
|
+
retry: () => retry(),
|
|
2185
3654
|
unbind() {
|
|
3655
|
+
if (!bound) return;
|
|
3656
|
+
bound = false;
|
|
2186
3657
|
for (const dispose of disposers) dispose();
|
|
2187
3658
|
disposers.length = 0;
|
|
2188
3659
|
BOUND.delete(composer);
|
|
@@ -2191,7 +3662,9 @@ function bindComposer(el, opts = {}) {
|
|
|
2191
3662
|
}
|
|
2192
3663
|
export {
|
|
2193
3664
|
bindComposer,
|
|
3665
|
+
getComposerDraft,
|
|
2194
3666
|
initAiComposer,
|
|
3667
|
+
openComposerLibrary,
|
|
2195
3668
|
registerRefKind,
|
|
2196
3669
|
setComposerCommands,
|
|
2197
3670
|
setComposerModels,
|