@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/events.ts
|
|
2
|
+
function emitIcen(source, type, detail) {
|
|
3
|
+
return source.dispatchEvent(
|
|
4
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/behaviors/i18n.ts
|
|
9
|
+
var ICEN_LOCALE_ZH_CN = {
|
|
10
|
+
/* ── aiBranch ── */
|
|
11
|
+
"aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
|
|
12
|
+
"aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
|
|
13
|
+
"aiBranch.version": "\u5206\u652F\u7248\u672C",
|
|
14
|
+
/* ── aiChat ── */
|
|
15
|
+
"aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
|
|
16
|
+
"aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
|
|
17
|
+
"aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
|
|
18
|
+
"aiChat.download": "\u4E0B\u8F7D",
|
|
19
|
+
"aiChat.file": "\u6587\u4EF6",
|
|
20
|
+
"aiChat.roleSystem": "\u7CFB",
|
|
21
|
+
"aiChat.roleTool": "\u5DE5",
|
|
22
|
+
"aiChat.roleUser": "\u6211",
|
|
23
|
+
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
/* ── aiComposer ── */
|
|
25
|
+
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
26
|
+
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
27
|
+
"aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
|
|
28
|
+
"aiComposer.all": "\u5168\u90E8",
|
|
29
|
+
"aiComposer.skills": "\u6280\u80FD",
|
|
30
|
+
"aiComposer.tools": "\u5DE5\u5177",
|
|
31
|
+
"aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
|
|
32
|
+
"aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
|
|
33
|
+
"aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
|
|
34
|
+
"aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
|
|
35
|
+
"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",
|
|
36
|
+
"aiComposer.attachDoc": "\u6587\u6863",
|
|
37
|
+
"aiComposer.attachFile": "\u6587\u4EF6",
|
|
38
|
+
"aiComposer.attachFolder": "\u6587\u4EF6\u5939",
|
|
39
|
+
"aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
|
|
40
|
+
"aiComposer.commands": "\u547D\u4EE4",
|
|
41
|
+
"aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
|
|
42
|
+
"aiComposer.done": "\u5B8C\u6210",
|
|
43
|
+
"aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
|
|
44
|
+
"aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
|
|
45
|
+
"aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
|
|
46
|
+
"aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
|
|
47
|
+
"aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
|
|
48
|
+
"aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
|
|
49
|
+
"aiComposer.refs": "\u5F15\u7528",
|
|
50
|
+
"aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
|
|
51
|
+
"aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
|
|
52
|
+
"aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
|
|
53
|
+
"aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
|
|
54
|
+
"aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
|
|
55
|
+
"aiComposer.send": "\u53D1\u9001",
|
|
56
|
+
"aiComposer.stop": "\u505C\u6B62\u751F\u6210",
|
|
57
|
+
"aiComposer.stopped": "\u5DF2\u505C\u6B62",
|
|
58
|
+
"aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
|
|
59
|
+
"aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
|
|
60
|
+
/* ── aiCore ── */
|
|
61
|
+
"aiCore.kindBrowser": "\u6D4F\u89C8",
|
|
62
|
+
"aiCore.kindChart": "\u56FE\u8868",
|
|
63
|
+
"aiCore.kindDelete": "\u5220\u9664",
|
|
64
|
+
"aiCore.kindEdit": "\u7F16\u8F91",
|
|
65
|
+
"aiCore.kindFetch": "\u8BF7\u6C42",
|
|
66
|
+
"aiCore.kindGlob": "\u5339\u914D",
|
|
67
|
+
"aiCore.kindGrep": "\u641C\u7D22",
|
|
68
|
+
"aiCore.kindNote": "\u7B14\u8BB0",
|
|
69
|
+
"aiCore.kindPlan": "\u8BA1\u5212",
|
|
70
|
+
"aiCore.kindRead": "\u8BFB\u53D6",
|
|
71
|
+
"aiCore.kindSearch": "\u68C0\u7D22",
|
|
72
|
+
"aiCore.kindShell": "\u547D\u4EE4",
|
|
73
|
+
"aiCore.kindSkill": "\u6280\u80FD",
|
|
74
|
+
"aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
|
|
75
|
+
"aiCore.kindTodo": "\u5F85\u529E",
|
|
76
|
+
"aiCore.kindWrite": "\u5199\u5165",
|
|
77
|
+
"aiCore.statusApproval": "\u5F85\u786E\u8BA4",
|
|
78
|
+
"aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
|
|
79
|
+
"aiCore.statusDone": "\u5B8C\u6210",
|
|
80
|
+
"aiCore.statusError": "\u5931\u8D25",
|
|
81
|
+
"aiCore.statusPending": "\u7B49\u5F85",
|
|
82
|
+
"aiCore.statusRunning": "\u6267\u884C\u4E2D",
|
|
83
|
+
"aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
|
|
84
|
+
"aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
|
|
85
|
+
/* ── aiDiff ── */
|
|
86
|
+
"aiDiff.accepted": "\u5DF2\u63A5\u53D7",
|
|
87
|
+
"aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
|
|
88
|
+
"aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
|
|
89
|
+
"aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
|
|
90
|
+
/* ── aiFeedback ── */
|
|
91
|
+
"aiFeedback.helpful": "\u6709\u5E2E\u52A9",
|
|
92
|
+
"aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
|
|
93
|
+
"aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
|
|
94
|
+
"aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
|
|
95
|
+
"aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
|
|
96
|
+
"aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
|
|
97
|
+
"aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
|
|
98
|
+
"aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
|
|
99
|
+
/* ── aiPanel ── */
|
|
100
|
+
"aiPanel.audit": "\u5BA1\u8BA1",
|
|
101
|
+
"aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
|
|
102
|
+
"aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
|
|
103
|
+
"aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
|
|
104
|
+
"aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
|
|
105
|
+
"aiPanel.context": "\u4E0A\u4E0B\u6587",
|
|
106
|
+
"aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
107
|
+
"aiPanel.errorsCount": "{p0} \u5931\u8D25",
|
|
108
|
+
"aiPanel.files": "\u6587\u4EF6 ({p0})",
|
|
109
|
+
"aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
|
|
110
|
+
"aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
|
|
111
|
+
"aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
|
|
112
|
+
"aiPanel.reasoning": "\u63A8\u7406",
|
|
113
|
+
"aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
|
|
114
|
+
"aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
115
|
+
"aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
116
|
+
"aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
117
|
+
"aiPanel.toolsCount": "{p0} \u5DE5\u5177",
|
|
118
|
+
"aiPanel.usage": "\u7528\u91CF",
|
|
119
|
+
"aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
|
|
120
|
+
/* ── aiProvider ── */
|
|
121
|
+
"aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
|
|
122
|
+
"aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
|
|
123
|
+
"aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
|
|
124
|
+
"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",
|
|
125
|
+
"aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
|
|
126
|
+
"aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
|
|
127
|
+
"aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
|
|
128
|
+
"aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
|
|
129
|
+
"aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
|
|
130
|
+
"aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
|
|
131
|
+
"aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
|
|
132
|
+
"aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
|
|
133
|
+
"aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
|
|
134
|
+
"aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
|
|
135
|
+
"aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
|
|
136
|
+
"aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
|
|
137
|
+
"aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
|
|
138
|
+
"aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
|
|
139
|
+
/* ── aiThreads ── */
|
|
140
|
+
"aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
|
|
141
|
+
"aiThreads.archived": "\u5DF2\u5F52\u6863",
|
|
142
|
+
/* ── aiTool ── */
|
|
143
|
+
"aiTool.allow": "\u5141\u8BB8",
|
|
144
|
+
"aiTool.reject": "\u62D2\u7EDD",
|
|
145
|
+
/* ── aiTools ── */
|
|
146
|
+
"aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
|
|
147
|
+
"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",
|
|
148
|
+
"aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
|
|
149
|
+
"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",
|
|
150
|
+
"aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
|
|
151
|
+
"aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
|
|
152
|
+
"aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
|
|
153
|
+
"aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
|
|
154
|
+
"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",
|
|
155
|
+
"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",
|
|
156
|
+
"aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
|
|
157
|
+
"aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
|
|
158
|
+
"aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
|
|
159
|
+
"aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
|
|
160
|
+
"aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
|
|
161
|
+
"aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
|
|
162
|
+
"aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
|
|
163
|
+
"aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
|
|
164
|
+
"aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
|
|
165
|
+
"aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
|
|
166
|
+
"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",
|
|
167
|
+
"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",
|
|
168
|
+
"aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
|
|
169
|
+
"aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
|
|
170
|
+
"aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
|
|
171
|
+
"aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
172
|
+
"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",
|
|
173
|
+
"aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
|
|
174
|
+
"aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
|
|
175
|
+
"aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
|
|
176
|
+
"aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
|
|
177
|
+
"aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
|
|
178
|
+
"aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
|
|
179
|
+
"aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
|
|
180
|
+
"aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
|
|
181
|
+
"aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
|
|
182
|
+
"aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
|
|
183
|
+
/* ── autocomplete ── */
|
|
184
|
+
"suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
|
|
185
|
+
"suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
186
|
+
"suggestions.options": "\u5EFA\u8BAE",
|
|
187
|
+
"suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
|
|
188
|
+
"autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
189
|
+
/* ── backTop ── */
|
|
190
|
+
"backTop.label": "\u56DE\u5230\u9876\u90E8",
|
|
191
|
+
/* ── carousel ── */
|
|
192
|
+
"carousel.item": "\u7B2C {p0} \u5F20",
|
|
193
|
+
"carousel.region": "\u8F6E\u64AD",
|
|
194
|
+
"carousel.slide": "\u5E7B\u706F\u7247",
|
|
195
|
+
"carousel.status": "\u7B2C {p0} / {p1} \u5F20",
|
|
196
|
+
/* ── charts ── */
|
|
197
|
+
"charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
|
|
198
|
+
"charts.few": "\u5C11",
|
|
199
|
+
"charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
|
|
200
|
+
"charts.loading": "\u52A0\u8F7D\u4E2D",
|
|
201
|
+
"charts.many": "\u591A",
|
|
202
|
+
"charts.monthLabel": "{p0}\u6708",
|
|
203
|
+
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
204
|
+
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
205
|
+
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
206
|
+
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
207
|
+
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
208
|
+
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
209
|
+
"charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
|
|
210
|
+
"charts.type.heatmap": "\u70ED\u529B\u56FE",
|
|
211
|
+
"charts.type.line": "\u6298\u7EBF\u56FE",
|
|
212
|
+
"charts.type.map": "\u5730\u56FE",
|
|
213
|
+
"charts.type.radar": "\u96F7\u8FBE\u56FE",
|
|
214
|
+
"charts.type.scatter": "\u6563\u70B9\u56FE",
|
|
215
|
+
"charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
|
|
216
|
+
"charts.seriesName": "\u7CFB\u5217{p0}",
|
|
217
|
+
"charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
|
|
218
|
+
"charts.value": "\u6570\u503C",
|
|
219
|
+
/* ── themeSwitcher ── */
|
|
220
|
+
"themeSwitcher.appearance": "\u5916\u89C2",
|
|
221
|
+
"themeSwitcher.theme": "\u4E3B\u9898",
|
|
222
|
+
"themeSwitcher.primitive": "\u539F\u8BED",
|
|
223
|
+
"themeSwitcher.mode": "\u660E\u6697",
|
|
224
|
+
"themeSwitcher.light": "\u6D45\u8272",
|
|
225
|
+
"themeSwitcher.dark": "\u6DF1\u8272",
|
|
226
|
+
"themeSwitcher.modern": "\u73B0\u4EE3",
|
|
227
|
+
"themeSwitcher.dongyun": "\u4E1C\u97F5",
|
|
228
|
+
"themeSwitcher.jugou": "\u5DE8\u6784",
|
|
229
|
+
"themeSwitcher.piano": "\u94A2\u7434",
|
|
230
|
+
"themeSwitcher.monet": "\u83AB\u5948",
|
|
231
|
+
"themeSwitcher.vangogh": "\u68B5\u9AD8",
|
|
232
|
+
"themeSwitcher.chinese": "\u4E2D\u5F0F",
|
|
233
|
+
"themeSwitcher.soviet": "\u82CF\u5F0F",
|
|
234
|
+
"themeSwitcher.pixel": "\u50CF\u7D20",
|
|
235
|
+
/* ── codeBlock ── */
|
|
236
|
+
"codeBlock.collapse": "\u6536\u8D77",
|
|
237
|
+
"codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
|
|
238
|
+
"codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
239
|
+
"codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
|
|
240
|
+
"codeBlock.copy": "\u590D\u5236",
|
|
241
|
+
"codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
|
|
242
|
+
"codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
|
|
243
|
+
"codeBlock.linesTotal": "\u5171 {p0} \u884C",
|
|
244
|
+
"codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
|
|
245
|
+
"codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
|
|
246
|
+
"codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
|
|
247
|
+
"codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
|
|
248
|
+
"codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
|
|
249
|
+
/* ── common ── */
|
|
250
|
+
"common.accept": "\u63A5\u53D7",
|
|
251
|
+
"common.add": "\u65B0\u589E",
|
|
252
|
+
"common.all": "\u5168\u90E8",
|
|
253
|
+
"common.approve": "\u6279\u51C6",
|
|
254
|
+
"common.cancel": "\u53D6\u6D88",
|
|
255
|
+
"common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
256
|
+
"common.close": "\u5173\u95ED",
|
|
257
|
+
"common.confirm": "\u786E\u8BA4",
|
|
258
|
+
"common.copied": "\u5DF2\u590D\u5236",
|
|
259
|
+
"common.copy": "\u590D\u5236",
|
|
260
|
+
"common.delete": "\u5220\u9664",
|
|
261
|
+
"common.enable": "\u542F\u7528",
|
|
262
|
+
"common.exportCsv": "\u5BFC\u51FA CSV",
|
|
263
|
+
"common.healthy": "\u6B63\u5E38",
|
|
264
|
+
"common.input": "\u8F93\u5165",
|
|
265
|
+
"common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
|
|
266
|
+
"common.official": "\u5B98\u65B9",
|
|
267
|
+
"common.output": "\u8F93\u51FA",
|
|
268
|
+
"common.page": "\u7B2C {p0} \u9875",
|
|
269
|
+
"common.reject": "\u62D2\u7EDD",
|
|
270
|
+
"common.remove": "\u79FB\u9664",
|
|
271
|
+
"common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
|
|
272
|
+
"common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
|
|
273
|
+
"common.restricted": "\u53D7\u9650",
|
|
274
|
+
"common.retry": "\u91CD\u8BD5",
|
|
275
|
+
"common.rows": "{p0} \u884C",
|
|
276
|
+
"common.run": "\u8FD0\u884C",
|
|
277
|
+
"common.steps": "{p0} \u6B65",
|
|
278
|
+
"common.submit": "\u63D0\u4EA4",
|
|
279
|
+
"common.unknown": "\u672A\u77E5",
|
|
280
|
+
/* ── contextMenu ── */
|
|
281
|
+
"contextMenu.back": "\u540E\u9000",
|
|
282
|
+
"contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
|
|
283
|
+
"contextMenu.forward": "\u524D\u8FDB",
|
|
284
|
+
"contextMenu.refresh": "\u5237\u65B0",
|
|
285
|
+
/* ── copy ── */
|
|
286
|
+
"copy.copied": "\u5DF2\u590D\u5236",
|
|
287
|
+
"copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
288
|
+
"copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
|
|
289
|
+
"copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
|
|
290
|
+
"copy.unknown": "\u672A\u77E5\u9519\u8BEF",
|
|
291
|
+
/* ── datatable ── */
|
|
292
|
+
"datatable.clear": "\u6E05\u7A7A",
|
|
293
|
+
"datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
|
|
294
|
+
"datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
|
|
295
|
+
"datatable.countUnit": "{p0} \u6761",
|
|
296
|
+
"datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
|
|
297
|
+
"datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
|
|
298
|
+
"datatable.empty": "\u6682\u65E0\u6570\u636E",
|
|
299
|
+
"datatable.emptyValue": "\uFF08\u7A7A\uFF09",
|
|
300
|
+
"datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
|
|
301
|
+
"datatable.expandRow": "\u5C55\u5F00\u884C",
|
|
302
|
+
"datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
|
|
303
|
+
"datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
|
|
304
|
+
"datatable.paginationAria": "\u5206\u9875",
|
|
305
|
+
"datatable.reset": "\u91CD\u7F6E",
|
|
306
|
+
"datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
|
|
307
|
+
"datatable.searchAria": "\u641C\u7D22\u8868\u683C",
|
|
308
|
+
"datatable.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
309
|
+
"datatable.selectAll": "\u5168\u9009",
|
|
310
|
+
"datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
|
|
311
|
+
"datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
|
|
312
|
+
"datatable.totalCount": "\u5171 {p0} \u6761",
|
|
313
|
+
"datatable.totalLabel": "\u5408\u8BA1",
|
|
314
|
+
/* ── datePicker ── */
|
|
315
|
+
"datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
|
|
316
|
+
"datePicker.clear": "\u6E05\u9664",
|
|
317
|
+
"datePicker.nextMonth": "\u4E0B\u4E00\u6708",
|
|
318
|
+
"datePicker.prevMonth": "\u4E0A\u4E00\u6708",
|
|
319
|
+
"datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
|
|
320
|
+
"datePicker.today": "\u4ECA\u5929",
|
|
321
|
+
"datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
|
|
322
|
+
"datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
|
|
323
|
+
"datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
|
|
324
|
+
/* ── formValidate ── */
|
|
325
|
+
"formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
|
|
326
|
+
"formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
|
|
327
|
+
"formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
|
|
328
|
+
"formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
|
|
329
|
+
"formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
|
|
330
|
+
"formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
|
|
331
|
+
"formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
|
|
332
|
+
"formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
|
|
333
|
+
"formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
334
|
+
"formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
|
|
335
|
+
"formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
|
|
336
|
+
"formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
|
|
337
|
+
"formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
|
|
338
|
+
"formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
|
|
339
|
+
"formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
|
|
340
|
+
"formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
|
|
341
|
+
"formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
|
|
342
|
+
"formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
|
|
343
|
+
"formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
|
|
344
|
+
"formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
|
|
345
|
+
"formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
|
|
346
|
+
"formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
|
|
347
|
+
"formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
|
|
348
|
+
"formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
|
|
349
|
+
"formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
|
|
350
|
+
"formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
|
|
351
|
+
"formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
|
|
352
|
+
/* ── input ── */
|
|
353
|
+
"input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
|
|
354
|
+
"input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
|
|
355
|
+
"input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
|
|
356
|
+
"panel.expand": "\u5C55\u5F00",
|
|
357
|
+
"panel.collapse": "\u6298\u53E0",
|
|
358
|
+
"input.showPassword": "\u663E\u793A\u5BC6\u7801",
|
|
359
|
+
/* ── kbAccess ── */
|
|
360
|
+
"kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
361
|
+
"kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
|
|
362
|
+
"kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
363
|
+
"kbAccess.daysLeft": "{p0} \u5929\u540E",
|
|
364
|
+
"kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
|
|
365
|
+
"kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
|
|
366
|
+
"kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
367
|
+
"kbAccess.duration30d": "30 \u5929",
|
|
368
|
+
"kbAccess.duration7d": "7 \u5929",
|
|
369
|
+
"kbAccess.durationForever": "\u6C38\u4E45",
|
|
370
|
+
"kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
|
|
371
|
+
"kbAccess.expired": "\u5DF2\u5230\u671F",
|
|
372
|
+
"kbAccess.expiresAt": "{p0}\u5230\u671F",
|
|
373
|
+
"kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
|
|
374
|
+
"kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
|
|
375
|
+
"kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
|
|
376
|
+
"kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
|
|
377
|
+
"kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
|
|
378
|
+
"kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
|
|
379
|
+
"kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
|
|
380
|
+
"kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
|
|
381
|
+
"kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
|
|
382
|
+
"kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
383
|
+
"kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
|
|
384
|
+
"kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
|
|
385
|
+
"kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
|
|
386
|
+
"kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
|
|
387
|
+
"kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
|
|
388
|
+
"kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
|
|
389
|
+
"kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
|
|
390
|
+
"kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
|
|
391
|
+
"kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
|
|
392
|
+
"kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
|
|
393
|
+
"kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
|
|
394
|
+
/* ── kbAcl ── */
|
|
395
|
+
"kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
|
|
396
|
+
"kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
|
|
397
|
+
"kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
|
|
398
|
+
"kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
|
|
399
|
+
"kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
|
|
400
|
+
"kbAcl.exception": "\u4F8B\u5916",
|
|
401
|
+
"kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
|
|
402
|
+
"kbAcl.expiresIn": "{p0} \u5230\u671F",
|
|
403
|
+
"kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
|
|
404
|
+
"kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
|
|
405
|
+
"kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
|
|
406
|
+
"kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
|
|
407
|
+
"kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
|
|
408
|
+
"kbAcl.noLinks": "\u65E0\u94FE\u63A5",
|
|
409
|
+
"kbAcl.removeEntry": "\u79FB\u9664 {p0}",
|
|
410
|
+
"kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
|
|
411
|
+
"kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
|
|
412
|
+
"kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
|
|
413
|
+
"kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
|
|
414
|
+
"kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
|
|
415
|
+
"kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
|
|
416
|
+
"kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
|
|
417
|
+
/* ── kbAnswer ── */
|
|
418
|
+
"kbAnswer.chartBar": "\u67F1\u72B6",
|
|
419
|
+
"kbAnswer.chartLine": "\u6298\u7EBF",
|
|
420
|
+
"kbAnswer.chartPie": "\u997C\u56FE",
|
|
421
|
+
"kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
|
|
422
|
+
"kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
|
|
423
|
+
"kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
|
|
424
|
+
"kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
|
|
425
|
+
"kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
|
|
426
|
+
"kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
|
|
427
|
+
"kbAnswer.kindFunction": "\u51FD\u6570",
|
|
428
|
+
"kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
|
|
429
|
+
"kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
|
|
430
|
+
"kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
|
|
431
|
+
"kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
|
|
432
|
+
"kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
|
|
433
|
+
/* ── kbAudit ── */
|
|
434
|
+
"kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
|
|
435
|
+
"kbAudit.actionLabel": "\u5904\u7F6E",
|
|
436
|
+
"kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
|
|
437
|
+
"kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
|
|
438
|
+
"kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
|
|
439
|
+
"kbAudit.channelRead": "\u8BFB\u53D6",
|
|
440
|
+
"kbAudit.channelRequest": "\u7533\u8BF7",
|
|
441
|
+
"kbAudit.channelSystem": "\u7CFB\u7EDF",
|
|
442
|
+
"kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
|
|
443
|
+
"kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
|
|
444
|
+
"kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
|
|
445
|
+
"kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
|
|
446
|
+
/* ── kbCanvas ── */
|
|
447
|
+
"kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
|
|
448
|
+
"kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
|
|
449
|
+
/* ── kbCheckpoint ── */
|
|
450
|
+
"kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
|
|
451
|
+
"kbCheckpoint.label": "\u68C0\u67E5\u70B9",
|
|
452
|
+
"kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
|
|
453
|
+
"kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
|
|
454
|
+
"kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
|
|
455
|
+
"kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
|
|
456
|
+
"kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
|
|
457
|
+
/* ── kbChunks ── */
|
|
458
|
+
"kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
|
|
459
|
+
"kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
|
|
460
|
+
"kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
|
|
461
|
+
"kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
|
|
462
|
+
"kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
|
|
463
|
+
"kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
|
|
464
|
+
"kbChunks.edited": "\u5DF2\u7F16\u8F91",
|
|
465
|
+
"kbChunks.empty": "\u6682\u65E0 chunk",
|
|
466
|
+
"kbChunks.modeFull": "\u5168\u6587",
|
|
467
|
+
"kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
|
|
468
|
+
"kbChunks.modeVector": "\u8BED\u4E49",
|
|
469
|
+
"kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
|
|
470
|
+
"kbChunks.searchAria": "\u641C\u7D22 chunk",
|
|
471
|
+
"kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
|
|
472
|
+
"kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
|
|
473
|
+
/* ── kbCitation ── */
|
|
474
|
+
"kbCitation.sourceN": "\u6765\u6E90 {p0}",
|
|
475
|
+
"kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
|
|
476
|
+
/* ── kbClarify ── */
|
|
477
|
+
"kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
|
|
478
|
+
/* ── kbConflict ── */
|
|
479
|
+
"kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
|
|
480
|
+
/* ── kbConnector ── */
|
|
481
|
+
"kbConnector.changeRate": "\u53D8\u66F4\u7387",
|
|
482
|
+
"kbConnector.crawlRate": "\u6293\u53D6\u7387",
|
|
483
|
+
"kbConnector.credentials": "\u51ED\u8BC1",
|
|
484
|
+
"kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
|
|
485
|
+
"kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
|
|
486
|
+
"kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
|
|
487
|
+
"kbConnector.failing": "\u5F02\u5E38",
|
|
488
|
+
"kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
|
|
489
|
+
"kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
|
|
490
|
+
"kbConnector.notConfigured": "\u672A\u914D\u7F6E",
|
|
491
|
+
"kbConnector.off": "\u5DF2\u505C\u7528",
|
|
492
|
+
"kbConnector.perDay": "{p0}/\u5929",
|
|
493
|
+
"kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
|
|
494
|
+
"kbConnector.stale": "\u505C\u6EDE",
|
|
495
|
+
"kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
|
|
496
|
+
"kbConnector.synced": "\u5DF2\u540C\u6B65",
|
|
497
|
+
/* ── kbCore ── */
|
|
498
|
+
"kbCore.accessDenied": "\u672A\u901A\u8FC7",
|
|
499
|
+
"kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
|
|
500
|
+
"kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
|
|
501
|
+
"kbCore.accessGranted": "\u5DF2\u5F00\u901A",
|
|
502
|
+
"kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
|
|
503
|
+
"kbCore.accessPending": "\u5F85\u5BA1\u6279",
|
|
504
|
+
"kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
|
|
505
|
+
"kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
|
|
506
|
+
"kbCore.auditApprove": "\u6279\u51C6",
|
|
507
|
+
"kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
|
|
508
|
+
"kbCore.auditDelegation": "\u59D4\u6D3E",
|
|
509
|
+
"kbCore.auditDeny": "\u62D2\u7EDD",
|
|
510
|
+
"kbCore.auditGrant": "\u6388\u4E88",
|
|
511
|
+
"kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
|
|
512
|
+
"kbCore.auditPreview": "\u9884\u89C8",
|
|
513
|
+
"kbCore.auditRead": "\u8BFB\u53D6",
|
|
514
|
+
"kbCore.auditRequest": "\u7533\u8BF7",
|
|
515
|
+
"kbCore.auditRevoke": "\u6536\u56DE",
|
|
516
|
+
"kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
|
|
517
|
+
"kbCore.daysAgo": "{p0} \u5929\u524D",
|
|
518
|
+
"kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
|
|
519
|
+
"kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
|
|
520
|
+
"kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
|
|
521
|
+
"kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
|
|
522
|
+
"kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
|
|
523
|
+
"kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
|
|
524
|
+
"kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
|
|
525
|
+
"kbCore.justNow": "\u521A\u521A",
|
|
526
|
+
"kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
|
|
527
|
+
"kbCore.levelEdit": "\u53EF\u7F16\u8F91",
|
|
528
|
+
"kbCore.levelNone": "\u65E0\u6743\u9650",
|
|
529
|
+
"kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
|
|
530
|
+
"kbCore.levelView": "\u53EF\u67E5\u770B",
|
|
531
|
+
"kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
|
|
532
|
+
"kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
|
|
533
|
+
"kbCore.runDone": "\u5DF2\u5B8C\u6210",
|
|
534
|
+
"kbCore.runFailed": "\u5931\u8D25",
|
|
535
|
+
"kbCore.runQueued": "\u6392\u961F\u4E2D",
|
|
536
|
+
"kbCore.runRunning": "\u8FDB\u884C\u4E2D",
|
|
537
|
+
"kbCore.runUnstarted": "\u672A\u5F00\u59CB",
|
|
538
|
+
"kbCore.stageAgent": "\u4EE3\u7406",
|
|
539
|
+
"kbCore.stageChunk": "\u5207\u7247",
|
|
540
|
+
"kbCore.stageEmbed": "\u5411\u91CF\u5316",
|
|
541
|
+
"kbCore.stageGeneration": "\u751F\u6210",
|
|
542
|
+
"kbCore.stageGuard": "\u62A4\u680F",
|
|
543
|
+
"kbCore.stageQuery": "\u67E5\u8BE2",
|
|
544
|
+
"kbCore.stageRerank": "\u91CD\u6392",
|
|
545
|
+
"kbCore.stageRetrieval": "\u68C0\u7D22",
|
|
546
|
+
"kbCore.stageTool": "\u5DE5\u5177",
|
|
547
|
+
"kbCore.typeApi": "\u63A5\u53E3",
|
|
548
|
+
"kbCore.typeCode": "\u4EE3\u7801",
|
|
549
|
+
"kbCore.typeDatabase": "\u6570\u636E\u5E93",
|
|
550
|
+
"kbCore.typeDocument": "\u6587\u6863",
|
|
551
|
+
"kbCore.typeEmail": "\u90AE\u4EF6",
|
|
552
|
+
"kbCore.typeImage": "\u56FE\u7247",
|
|
553
|
+
"kbCore.typeKb": "\u77E5\u8BC6\u5E93",
|
|
554
|
+
"kbCore.typeTable": "\u8868\u683C",
|
|
555
|
+
"kbCore.typeTicket": "\u5DE5\u5355",
|
|
556
|
+
"kbCore.typeWebpage": "\u7F51\u9875",
|
|
557
|
+
"kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
|
|
558
|
+
"kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
|
|
559
|
+
"kbCore.visHidden": "\u4E0D\u53EF\u89C1",
|
|
560
|
+
"kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
|
|
561
|
+
"kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
|
|
562
|
+
"kbCore.visVisible": "\u53EF\u89C1",
|
|
563
|
+
/* ── kbEval ── */
|
|
564
|
+
"kbEval.avgA": "A \u5747\u5206 {p0}",
|
|
565
|
+
"kbEval.avgB": "B \u5747\u5206 {p0}",
|
|
566
|
+
"kbEval.compare": "\u5BF9\u6BD4",
|
|
567
|
+
"kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
|
|
568
|
+
"kbEval.expected": "\u671F\u671B",
|
|
569
|
+
"kbEval.gradeImprovement": "\u63D0\u5347",
|
|
570
|
+
"kbEval.gradeRegression": "\u56DE\u5F52",
|
|
571
|
+
"kbEval.gradeTie": "\u6301\u5E73",
|
|
572
|
+
"kbEval.gradeTradeoff": "\u6743\u8861",
|
|
573
|
+
"kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
|
|
574
|
+
"kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
|
|
575
|
+
"kbEval.outputA": "\u8F93\u51FA A",
|
|
576
|
+
"kbEval.outputB": "\u8F93\u51FA B",
|
|
577
|
+
"kbEval.outputN": "\u8F93\u51FA {p0}",
|
|
578
|
+
/* ── kbExplain ── */
|
|
579
|
+
"kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
|
|
580
|
+
"kbExplain.groupAgg": "\u805A\u5408",
|
|
581
|
+
"kbExplain.groupColumn": "\u5217",
|
|
582
|
+
"kbExplain.groupFilter": "\u7B5B\u9009",
|
|
583
|
+
"kbExplain.groupTable": "\u8868",
|
|
584
|
+
"kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
|
|
585
|
+
"kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
|
|
586
|
+
/* ── kbFilter ── */
|
|
587
|
+
"kbFilter.addGroup": "+ \u7EC4",
|
|
588
|
+
"kbFilter.addRule": "+ \u89C4\u5219",
|
|
589
|
+
"kbFilter.and": "\u4E14",
|
|
590
|
+
"kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
|
|
591
|
+
"kbFilter.copyDsl": "\u590D\u5236 DSL",
|
|
592
|
+
"kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
|
|
593
|
+
"kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
|
|
594
|
+
"kbFilter.fieldLabel": "\u5B57\u6BB5",
|
|
595
|
+
"kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
|
|
596
|
+
"kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
|
|
597
|
+
"kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
|
|
598
|
+
"kbFilter.opContains": "\u5305\u542B",
|
|
599
|
+
"kbFilter.opEq": "\u7B49\u4E8E",
|
|
600
|
+
"kbFilter.opExists": "\u5B58\u5728",
|
|
601
|
+
"kbFilter.opGt": "\u5927\u4E8E",
|
|
602
|
+
"kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
|
|
603
|
+
"kbFilter.opIn": "\u5C5E\u4E8E",
|
|
604
|
+
"kbFilter.opLt": "\u5C0F\u4E8E",
|
|
605
|
+
"kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
606
|
+
"kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
|
|
607
|
+
"kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
|
|
608
|
+
"kbFilter.or": "\u6216",
|
|
609
|
+
"kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
|
|
610
|
+
"kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
|
|
611
|
+
"kbFilter.valueLabel": "\u503C",
|
|
612
|
+
"kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
|
|
613
|
+
/* ── kbGap ── */
|
|
614
|
+
"kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
|
|
615
|
+
"kbGap.colCount": "\u6B21\u6570",
|
|
616
|
+
"kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
|
|
617
|
+
"kbGap.colQuery": "\u67E5\u8BE2",
|
|
618
|
+
"kbGap.colShare": "\u5360\u6BD4",
|
|
619
|
+
"kbGap.createDoc": "\u5EFA\u6587\u6863",
|
|
620
|
+
"kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
|
|
621
|
+
"kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
|
|
622
|
+
"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",
|
|
623
|
+
"kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
|
|
624
|
+
"kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
|
|
625
|
+
/* ── kbHittest ── */
|
|
626
|
+
"kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
|
|
627
|
+
"kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
|
|
628
|
+
"kbHittest.avgScore": "\u5747\u5206",
|
|
629
|
+
"kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
|
|
630
|
+
"kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
|
|
631
|
+
"kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
|
|
632
|
+
"kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
|
|
633
|
+
"kbHittest.hitRate": "\u547D\u4E2D\u7387",
|
|
634
|
+
"kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
|
|
635
|
+
"kbHittest.notRun": "\u672A\u8FD0\u884C",
|
|
636
|
+
"kbHittest.pass": "\u901A\u8FC7",
|
|
637
|
+
"kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
|
|
638
|
+
"kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
|
|
639
|
+
"kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
640
|
+
"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",
|
|
641
|
+
"kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
|
|
642
|
+
/* ── kbMetadata ── */
|
|
643
|
+
"kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
|
|
644
|
+
"kbMetadata.builtIn": "\u5185\u7F6E",
|
|
645
|
+
"kbMetadata.colField": "\u5B57\u6BB5",
|
|
646
|
+
"kbMetadata.colType": "\u7C7B\u578B",
|
|
647
|
+
"kbMetadata.colValue": "\u503C",
|
|
648
|
+
"kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
|
|
649
|
+
"kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
|
|
650
|
+
"kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
|
|
651
|
+
"kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
|
|
652
|
+
"kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
|
|
653
|
+
"kbMetadata.valueOf": "{p0} \u7684\u503C",
|
|
654
|
+
/* ── kbPassage ── */
|
|
655
|
+
"kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
|
|
656
|
+
"kbPassage.close": "\u5173\u95ED\u539F\u6587",
|
|
657
|
+
"kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
|
|
658
|
+
"kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
|
|
659
|
+
"kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
|
|
660
|
+
"kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
|
|
661
|
+
"kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
|
|
662
|
+
"kbPassage.unitByte": "\u5B57\u8282",
|
|
663
|
+
"kbPassage.unitChar": "\u5B57\u7B26",
|
|
664
|
+
/* ── kbPipeline ── */
|
|
665
|
+
"kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
|
|
666
|
+
"kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
|
|
667
|
+
"kbPipeline.rerun": "\u91CD\u8DD1",
|
|
668
|
+
"kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
|
|
669
|
+
/* ── kbQa ── */
|
|
670
|
+
"kbQa.colAnswer": "\u7B54\u6848",
|
|
671
|
+
"kbQa.colQuestion": "\u95EE\u9898",
|
|
672
|
+
"kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
|
|
673
|
+
"kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
|
|
674
|
+
"kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
|
|
675
|
+
"kbQa.importCsv": "\u5BFC\u5165 CSV",
|
|
676
|
+
/* ── kbRerank ── */
|
|
677
|
+
"kbRerank.after": "\u91CD\u6392\u540E",
|
|
678
|
+
"kbRerank.before": "\u91CD\u6392\u524D",
|
|
679
|
+
"kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
|
|
680
|
+
"kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
|
|
681
|
+
"kbRerank.dropped": "\u843D\u9009",
|
|
682
|
+
"kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
|
|
683
|
+
"kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
|
|
684
|
+
"kbRerank.newIn": "\u65B0\u8FDB",
|
|
685
|
+
"kbRerank.unmarked": "\u672A\u6807",
|
|
686
|
+
"kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
|
|
687
|
+
/* ── kbRetrieval ── */
|
|
688
|
+
"kbRetrieval.breakdown": "\u62C6\u89E3",
|
|
689
|
+
"kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
|
|
690
|
+
"kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
|
|
691
|
+
"kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
692
|
+
"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",
|
|
693
|
+
"kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
|
|
694
|
+
"kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
|
|
695
|
+
"kbRetrieval.identityShort": "\u8EAB\u4EFD",
|
|
696
|
+
"kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
|
|
697
|
+
"kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
|
|
698
|
+
"kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
|
|
699
|
+
"kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
|
|
700
|
+
"kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
|
|
701
|
+
"kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
|
|
702
|
+
"kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
|
|
703
|
+
"kbRetrieval.modeHybrid": "\u6DF7\u5408",
|
|
704
|
+
"kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
|
|
705
|
+
"kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
|
|
706
|
+
"kbRetrieval.modeVector": "\u5411\u91CF",
|
|
707
|
+
"kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
|
|
708
|
+
"kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
|
|
709
|
+
"kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
|
|
710
|
+
"kbRetrieval.rerankLabel": "\u91CD\u6392",
|
|
711
|
+
"kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
|
|
712
|
+
"kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
|
|
713
|
+
"kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
|
|
714
|
+
"kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
|
|
715
|
+
"kbRetrieval.thresholdValue": "\u9608\u503C N/A",
|
|
716
|
+
"kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
|
|
717
|
+
"kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
|
|
718
|
+
"kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
|
|
719
|
+
/* ── kbReview ── */
|
|
720
|
+
"kbReview.assignee": "\u5206\u914D\u4EBA",
|
|
721
|
+
"kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
|
|
722
|
+
"kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
|
|
723
|
+
"kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
|
|
724
|
+
"kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
|
|
725
|
+
"kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
|
|
726
|
+
"kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
|
|
727
|
+
"kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
|
|
728
|
+
"kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
|
|
729
|
+
"kbReview.shortcuts": "? \u5FEB\u6377\u952E",
|
|
730
|
+
"kbReview.typeAnswer": "\u56DE\u7B54",
|
|
731
|
+
"kbReview.typeMessage": "\u6D88\u606F",
|
|
732
|
+
"kbReview.typeTrace": "\u8F68\u8FF9",
|
|
733
|
+
"kbReview.unassigned": "\u672A\u5206\u914D",
|
|
734
|
+
/* ── kbSandbox ── */
|
|
735
|
+
"kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
|
|
736
|
+
"kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
|
|
737
|
+
"kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
|
|
738
|
+
"kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
739
|
+
"kbSandbox.title": "MCP App \u6C99\u7BB1",
|
|
740
|
+
/* ── kbSegment ── */
|
|
741
|
+
"kbSegment.avgLength": "\u5747\u957F {p0}",
|
|
742
|
+
"kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
|
|
743
|
+
"kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
|
|
744
|
+
"kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
|
|
745
|
+
"kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
|
|
746
|
+
"kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
|
|
747
|
+
"kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
|
|
748
|
+
"kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
|
|
749
|
+
"kbSegment.modeAuto": "\u81EA\u52A8",
|
|
750
|
+
"kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
|
|
751
|
+
"kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
|
|
752
|
+
"kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
|
|
753
|
+
"kbSegment.modeParentChild": "\u7236\u5B50",
|
|
754
|
+
"kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
|
|
755
|
+
"kbSegment.overlapLabel": "\u91CD\u53E0",
|
|
756
|
+
"kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
|
|
757
|
+
"kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
|
|
758
|
+
"kbSegment.segmentsCount": "{p0} \u6BB5",
|
|
759
|
+
"kbSegment.separatorLabel": "\u5206\u9694\u7B26",
|
|
760
|
+
"kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
|
|
761
|
+
"kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
|
|
762
|
+
/* ── kbSources ── */
|
|
763
|
+
"kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
|
|
764
|
+
"kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
765
|
+
/* ── kbSql ── */
|
|
766
|
+
"kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
|
|
767
|
+
"kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
|
|
768
|
+
"kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
|
|
769
|
+
"kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
|
|
770
|
+
"kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
|
|
771
|
+
"kbSql.generated": "\u751F\u6210\u7684 SQL",
|
|
772
|
+
/* ── kbTrace ── */
|
|
773
|
+
"kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
|
|
774
|
+
"kbTrace.hits": "\u547D\u4E2D {p0}",
|
|
775
|
+
/* ── kbVisibility ── */
|
|
776
|
+
"kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
|
|
777
|
+
"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",
|
|
778
|
+
"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",
|
|
779
|
+
"kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
|
|
780
|
+
"kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
|
|
781
|
+
"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",
|
|
782
|
+
"kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
|
|
783
|
+
"kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
|
|
784
|
+
"kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
|
|
785
|
+
"kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
|
|
786
|
+
"kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
|
|
787
|
+
/* ── kbWhoCan ── */
|
|
788
|
+
"kbWhoCan.check": "\u68C0\u67E5",
|
|
789
|
+
"kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
|
|
790
|
+
"kbWhoCan.daysUntil": "{p0} \u5929\u540E",
|
|
791
|
+
"kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
|
|
792
|
+
"kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
|
|
793
|
+
"kbWhoCan.direct": "\u76F4\u63A5",
|
|
794
|
+
"kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
|
|
795
|
+
"kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
|
|
796
|
+
"kbWhoCan.inherit": "\u7EE7\u627F",
|
|
797
|
+
"kbWhoCan.link": "\u94FE\u63A5",
|
|
798
|
+
"kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
|
|
799
|
+
"kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
|
|
800
|
+
"kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
|
|
801
|
+
"kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
|
|
802
|
+
"kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
|
|
803
|
+
/* ── mentions ── */
|
|
804
|
+
"mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
|
|
805
|
+
"mentions.customBadge": "\u81EA\u5B9A\u4E49",
|
|
806
|
+
"mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
807
|
+
/* ── notification ── */
|
|
808
|
+
"notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
|
|
809
|
+
"notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
|
|
810
|
+
"notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
|
|
811
|
+
"notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
|
|
812
|
+
"notification.ariaLabel": "\u901A\u77E5",
|
|
813
|
+
"notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
|
|
814
|
+
/* ── pagination ── */
|
|
815
|
+
"pagination.next": "\u4E0B\u4E00\u9875",
|
|
816
|
+
"pagination.pageSize": "{p0} \u6761/\u9875",
|
|
817
|
+
"pagination.prev": "\u4E0A\u4E00\u9875",
|
|
818
|
+
/* ── select ── */
|
|
819
|
+
"select.fieldLabel": "\u9009\u62E9\u9009\u9879",
|
|
820
|
+
"select.noMatch": "\u65E0\u5339\u914D\u9879",
|
|
821
|
+
"select.remove": "\u79FB\u9664 {p0}",
|
|
822
|
+
"select.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
823
|
+
/* ── cascader / tree-select ── */
|
|
824
|
+
"cascader.placeholder": "\u8BF7\u9009\u62E9",
|
|
825
|
+
"cascader.noMatch": "\u65E0\u5339\u914D",
|
|
826
|
+
"cascader.search": "\u641C\u7D22",
|
|
827
|
+
"treeSelect.placeholder": "\u8BF7\u9009\u62E9",
|
|
828
|
+
"treeSelect.noMatch": "\u65E0\u5339\u914D",
|
|
829
|
+
"treeSelect.search": "\u641C\u7D22",
|
|
830
|
+
/* ── tagInput ── */
|
|
831
|
+
"tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
|
|
832
|
+
"tagInput.remove": "\u79FB\u9664 {p0}",
|
|
833
|
+
"tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
|
|
834
|
+
"tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
|
|
835
|
+
"tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
|
|
836
|
+
"tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
|
|
837
|
+
"tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
|
|
838
|
+
/* ── upload ── */
|
|
839
|
+
"upload.remove": "\u79FB\u9664 {p0}",
|
|
840
|
+
"upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
|
|
841
|
+
"upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
|
|
842
|
+
"upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
|
|
843
|
+
};
|
|
844
|
+
var current = { ...ICEN_LOCALE_ZH_CN };
|
|
845
|
+
function t(key, vars) {
|
|
846
|
+
const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
|
|
847
|
+
if (vars == null || Array.isArray(raw)) return raw;
|
|
848
|
+
return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// src/behaviors/icons.ts
|
|
852
|
+
var ICON_PATHS = {
|
|
853
|
+
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",
|
|
854
|
+
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",
|
|
855
|
+
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",
|
|
856
|
+
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",
|
|
857
|
+
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",
|
|
858
|
+
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",
|
|
859
|
+
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",
|
|
860
|
+
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",
|
|
861
|
+
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",
|
|
862
|
+
"line-numbers": "M3 5h2M3 10h2M3 15h2M8 5h9M8 10h9M8 15h9",
|
|
863
|
+
wrap: "M3 5h14M3 10h10a3 3 0 0 1 0 6h-3M12.5 13.5 10 16l2.5 2.5",
|
|
864
|
+
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",
|
|
865
|
+
close: "M6 6l8 8M14 6l-8 8",
|
|
866
|
+
check: "M4.5 10.2l3.6 3.6 7.4-7.6",
|
|
867
|
+
"chevron-down": "M5.5 7.75 10 12.25l4.5-4.5",
|
|
868
|
+
"chevron-up": "M5.5 12.25 10 7.75l4.5 4.5",
|
|
869
|
+
"chevron-right": "M7.75 5.5 12.25 10l-4.5 4.5",
|
|
870
|
+
"chevron-left": "M12.25 5.5 7.75 10l4.5 4.5",
|
|
871
|
+
"arrow-right": "M3.5 10h13M11 4.5l5.5 5.5-5.5 5.5",
|
|
872
|
+
"arrow-left": "M16.5 10h-13M9 4.5 3.5 10 9 15.5",
|
|
873
|
+
"arrow-up": "M10 16.5v-13M4.5 9 10 3.5 15.5 9",
|
|
874
|
+
"arrow-down": "M10 3.5v13M4.5 11l5.5 5.5 5.5-5.5",
|
|
875
|
+
plus: "M10 4v12M4 10h12",
|
|
876
|
+
minus: "M4 10h12",
|
|
877
|
+
sort: "M6 15V4M3 7l3-3 3 3M14 5v11M11 13l3 3 3-3",
|
|
878
|
+
search: "M13.3 13.3 17 17M14.5 8.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0",
|
|
879
|
+
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",
|
|
880
|
+
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",
|
|
881
|
+
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",
|
|
882
|
+
pixel: "M3 3h5v5H3ZM12 3h5v5h-5ZM3 12h5v5H3ZM12 12h5v5h-5Z",
|
|
883
|
+
chinese: "M3 8c3 0 5-2 7-5 2 3 4 5 7 5M4 8h12M6 8v8m8-8v8M3 16h14M8 16v-5h4v5",
|
|
884
|
+
soviet: "M3 17h14M5 17V8h4v9m0-12h6v12M7 8V5h2m2 3h2m-2 3h2m-2 3h2M10 5V3h4v2",
|
|
885
|
+
more: "M4 9.9v.2M10 9.9v.2M16 9.9v.2",
|
|
886
|
+
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",
|
|
887
|
+
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",
|
|
888
|
+
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",
|
|
889
|
+
trash: "M3.5 5.5h13M7 5.5V3h6v2.5M5 5.5l.7 11.5h8.6L15 5.5M8 9v5M12 9v5",
|
|
890
|
+
spinner: "M10 3a7 7 0 1 1-7 7",
|
|
891
|
+
"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",
|
|
892
|
+
"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",
|
|
893
|
+
"circle-info": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM10 9v5M10 6.1v.15",
|
|
894
|
+
"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",
|
|
895
|
+
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",
|
|
896
|
+
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",
|
|
897
|
+
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",
|
|
898
|
+
settings: "M3.5 5.5h13M3.5 10h13M3.5 14.5h13M7 4v3M12.5 8.5v3M8 13v3",
|
|
899
|
+
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",
|
|
900
|
+
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",
|
|
901
|
+
"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",
|
|
902
|
+
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",
|
|
903
|
+
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",
|
|
904
|
+
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",
|
|
905
|
+
activity: "M17 10h-2.6l-2 5.8L8 4.2 6 10H3",
|
|
906
|
+
"trend-up": "M3.5 14.5l4.2-4.2 2.8 2.8 5.9-5.9M12.4 7.2h4.2v4.2",
|
|
907
|
+
"trend-down": "M3.5 5.5l4.2 4.2 2.8-2.8 5.9 5.9M12.4 12.8h4.2V8.6",
|
|
908
|
+
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",
|
|
909
|
+
bold: "M6.5 4h4.2a3 3 0 0 1 0 6H6.5M6.5 10h5a3 3 0 0 1 0 6H6.5M6.5 4v12",
|
|
910
|
+
italic: "M8.5 4.5h7M4.5 15.5h7M12.5 4.5l-5 11",
|
|
911
|
+
underline: "M6 4v5.5a4 4 0 0 0 8 0V4M4.5 16h11",
|
|
912
|
+
"align-left": "M3.5 4.5h13M3.5 10h8.5M3.5 15.5h11",
|
|
913
|
+
"align-center": "M3.5 4.5h13M5.75 10h8.5M4.5 15.5h11",
|
|
914
|
+
"align-right": "M3.5 4.5h13M8 10h8.5M5.5 15.5h11",
|
|
915
|
+
list: "M6.5 5h10M6.5 10h10M6.5 15h10M3.5 5h.01M3.5 10h.01M3.5 15h.01",
|
|
916
|
+
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",
|
|
917
|
+
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",
|
|
918
|
+
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",
|
|
919
|
+
"chart-line": "M3.5 3.5v13h13M6.5 12l2.8-2.8 2.2 2.2 4-4.4",
|
|
920
|
+
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",
|
|
921
|
+
box: "M17 6 10 3.2 3 6v8l7 2.8 7-2.8ZM3 6l7 2.8L17 6M10 9v7.8",
|
|
922
|
+
filter: "M4 4.5h12l-4.4 5.1v5l-3.2-1.6V9.6Z",
|
|
923
|
+
columns: "M3.5 4h13v12h-13ZM8.2 4v12M12.8 4v12",
|
|
924
|
+
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"
|
|
925
|
+
};
|
|
926
|
+
var custom = /* @__PURE__ */ new Map();
|
|
927
|
+
var escape = (s) => s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
928
|
+
function iconPath(name) {
|
|
929
|
+
return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
|
|
930
|
+
}
|
|
931
|
+
function iconAttributes(o = {}) {
|
|
932
|
+
const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
|
|
933
|
+
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" } };
|
|
934
|
+
}
|
|
935
|
+
function iconHTML(name, o = {}) {
|
|
936
|
+
const path = iconPath(name);
|
|
937
|
+
if (!path) return "";
|
|
938
|
+
return `<svg${Object.entries(iconAttributes(o)).map(([k, v]) => ` ${k}="${escape(v)}"`).join("")}><path d="${escape(path)}"></path></svg>`;
|
|
939
|
+
}
|
|
940
|
+
function createIcon(name, o = {}) {
|
|
941
|
+
if (typeof document === "undefined") return null;
|
|
942
|
+
const path = iconPath(name);
|
|
943
|
+
if (!path) return null;
|
|
944
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
945
|
+
for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
|
|
946
|
+
const line = document.createElementNS(svg.namespaceURI, "path");
|
|
947
|
+
line.setAttribute("d", path);
|
|
948
|
+
svg.append(line);
|
|
949
|
+
return svg;
|
|
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 AI_STATUSES = [
|
|
3
989
|
"pending",
|
|
@@ -10,64 +996,33 @@ var AI_STATUSES = [
|
|
|
10
996
|
];
|
|
11
997
|
function aiStatusLabel(s) {
|
|
12
998
|
const labels = {
|
|
13
|
-
pending: "
|
|
14
|
-
running: "
|
|
15
|
-
streaming: "
|
|
16
|
-
approval: "
|
|
17
|
-
done: "
|
|
18
|
-
error: "
|
|
19
|
-
cancelled: "
|
|
999
|
+
pending: t("aiCore.statusPending"),
|
|
1000
|
+
running: t("aiCore.statusRunning"),
|
|
1001
|
+
streaming: t("aiCore.statusStreaming"),
|
|
1002
|
+
approval: t("aiCore.statusApproval"),
|
|
1003
|
+
done: t("aiCore.statusDone"),
|
|
1004
|
+
error: t("aiCore.statusError"),
|
|
1005
|
+
cancelled: t("aiCore.statusCancelled")
|
|
20
1006
|
};
|
|
21
1007
|
return labels[s] ?? s;
|
|
22
1008
|
}
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
);
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
);
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
);
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
);
|
|
41
|
-
var ICON_SCAN_SEARCH = svg(
|
|
42
|
-
'<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"/>'
|
|
43
|
-
);
|
|
44
|
-
var ICON_GLOBE = svg(
|
|
45
|
-
'<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"/>'
|
|
46
|
-
);
|
|
47
|
-
var ICON_DOWNLOAD = svg(
|
|
48
|
-
'<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"/>'
|
|
49
|
-
);
|
|
50
|
-
var ICON_BLOCKS = svg(
|
|
51
|
-
'<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"/>'
|
|
52
|
-
);
|
|
53
|
-
var ICON_ZAP = svg(
|
|
54
|
-
'<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"/>'
|
|
55
|
-
);
|
|
56
|
-
var ICON_LIST = svg(
|
|
57
|
-
'<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"/>'
|
|
58
|
-
);
|
|
59
|
-
var ICON_LIST_CHECKS = svg(
|
|
60
|
-
'<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"/>'
|
|
61
|
-
);
|
|
62
|
-
var ICON_BOT = svg(
|
|
63
|
-
'<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"/>'
|
|
64
|
-
);
|
|
65
|
-
var ICON_CHART = svg(
|
|
66
|
-
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
67
|
-
);
|
|
68
|
-
var ICON_FILE_TEXT = svg(
|
|
69
|
-
'<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"/>'
|
|
70
|
-
);
|
|
1009
|
+
var ICON_TERMINAL = iconHTML("terminal");
|
|
1010
|
+
var ICON_FILE = iconHTML("file");
|
|
1011
|
+
var ICON_FILE_PEN = iconHTML("edit");
|
|
1012
|
+
var ICON_FILE_PLUS = iconHTML("plus");
|
|
1013
|
+
var ICON_TRASH = iconHTML("trash");
|
|
1014
|
+
var ICON_SEARCH = iconHTML("search");
|
|
1015
|
+
var ICON_FOLDER_SEARCH = iconHTML("folder");
|
|
1016
|
+
var ICON_SCAN_SEARCH = iconHTML("search");
|
|
1017
|
+
var ICON_GLOBE = iconHTML("globe");
|
|
1018
|
+
var ICON_DOWNLOAD = iconHTML("download");
|
|
1019
|
+
var ICON_BLOCKS = iconHTML("server");
|
|
1020
|
+
var ICON_ZAP = iconHTML("sparkle");
|
|
1021
|
+
var ICON_LIST = iconHTML("list");
|
|
1022
|
+
var ICON_LIST_CHECKS = iconHTML("list");
|
|
1023
|
+
var ICON_BOT = iconHTML("agent");
|
|
1024
|
+
var ICON_CHART = iconHTML("chart-line");
|
|
1025
|
+
var ICON_FILE_TEXT = iconHTML("document");
|
|
71
1026
|
function isObj(v) {
|
|
72
1027
|
return typeof v === "object" && v !== null;
|
|
73
1028
|
}
|
|
@@ -117,32 +1072,32 @@ var sum = (fn) => {
|
|
|
117
1072
|
return (input) => fn(input) ?? "";
|
|
118
1073
|
};
|
|
119
1074
|
var BUILTIN_KINDS = {
|
|
120
|
-
shell: { label: "
|
|
121
|
-
read: { label: "
|
|
122
|
-
edit: { label: "
|
|
123
|
-
write: { label: "
|
|
124
|
-
rm: { label: "
|
|
125
|
-
grep: { label: "
|
|
126
|
-
glob: { label: "
|
|
127
|
-
browser: { label: "
|
|
128
|
-
search: { label: "
|
|
129
|
-
fetch: { label: "
|
|
1075
|
+
shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
1076
|
+
read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
1077
|
+
edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
1078
|
+
write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
1079
|
+
rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
1080
|
+
grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
1081
|
+
glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
1082
|
+
browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
1083
|
+
search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
1084
|
+
fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
130
1085
|
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
131
|
-
skill: { label: "
|
|
1086
|
+
skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
132
1087
|
todo: {
|
|
133
|
-
label: "
|
|
1088
|
+
label: t("aiCore.kindTodo"),
|
|
134
1089
|
icon: ICON_LIST,
|
|
135
1090
|
tint: "info",
|
|
136
1091
|
summarize: sum((input) => {
|
|
137
1092
|
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
138
1093
|
const done = items.filter((it) => it?.status === "done").length;
|
|
139
|
-
return items.length > 0 ?
|
|
1094
|
+
return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
|
|
140
1095
|
})
|
|
141
1096
|
},
|
|
142
|
-
plan: { label: "
|
|
143
|
-
subagent: { label: "
|
|
144
|
-
note: { label: "
|
|
145
|
-
chart: { label: "
|
|
1097
|
+
plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
|
|
1098
|
+
subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
1099
|
+
note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
|
|
1100
|
+
chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
146
1101
|
};
|
|
147
1102
|
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
148
1103
|
function getAiKind(name) {
|
|
@@ -169,10 +1124,10 @@ function formatDuration(ms) {
|
|
|
169
1124
|
var PART_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "file", "resource-link"]);
|
|
170
1125
|
function isAiContentPart(v) {
|
|
171
1126
|
if (!isObj(v)) return false;
|
|
172
|
-
const
|
|
173
|
-
if (typeof
|
|
174
|
-
if (
|
|
175
|
-
if (
|
|
1127
|
+
const t2 = v.type;
|
|
1128
|
+
if (typeof t2 !== "string" || !PART_TYPES.has(t2)) return false;
|
|
1129
|
+
if (t2 === "text") return typeof v.text === "string";
|
|
1130
|
+
if (t2 === "resource-link") return typeof v.uri === "string";
|
|
176
1131
|
return typeof v.url === "string" || typeof v.data === "string" && typeof v.mimeType === "string";
|
|
177
1132
|
}
|
|
178
1133
|
function aiContentUrl(part) {
|
|
@@ -276,52 +1231,25 @@ function normalizeContentParts(raw) {
|
|
|
276
1231
|
return out;
|
|
277
1232
|
}
|
|
278
1233
|
function h(tag, className, text) {
|
|
1234
|
+
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");
|
|
279
1235
|
const node = document.createElement(tag);
|
|
280
1236
|
if (className) node.className = className;
|
|
281
1237
|
if (text != null) node.textContent = text;
|
|
282
1238
|
return node;
|
|
283
1239
|
}
|
|
284
|
-
function svgIcon(
|
|
285
|
-
|
|
286
|
-
let parsed;
|
|
287
|
-
try {
|
|
288
|
-
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
289
|
-
} catch {
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
const root = parsed.documentElement;
|
|
293
|
-
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
294
|
-
return null;
|
|
295
|
-
}
|
|
296
|
-
const sanitize = (el) => {
|
|
297
|
-
for (const attr of Array.from(el.attributes)) {
|
|
298
|
-
const name = attr.name.toLowerCase();
|
|
299
|
-
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
300
|
-
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
301
|
-
el.removeAttribute(attr.name);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
for (const child of Array.from(el.children)) {
|
|
305
|
-
const tag = child.tagName.toLowerCase();
|
|
306
|
-
if (tag === "script" || tag === "foreignobject") {
|
|
307
|
-
child.remove();
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
sanitize(child);
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
sanitize(root);
|
|
314
|
-
return document.importNode(root, true);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// src/behaviors/events.ts
|
|
318
|
-
function emitIcen(source, type, detail) {
|
|
319
|
-
return source.dispatchEvent(
|
|
320
|
-
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
321
|
-
);
|
|
1240
|
+
function svgIcon(svg) {
|
|
1241
|
+
return parseSvg(svg);
|
|
322
1242
|
}
|
|
323
1243
|
|
|
324
1244
|
// src/behaviors/ai-chat.ts
|
|
1245
|
+
var ICON_COPY = iconHTML("copy");
|
|
1246
|
+
var ICON_RETRY = iconHTML("refresh");
|
|
1247
|
+
var ROLE_AVATAR = {
|
|
1248
|
+
user: t("aiChat.roleUser"),
|
|
1249
|
+
assistant: "AI",
|
|
1250
|
+
system: t("aiChat.roleSystem"),
|
|
1251
|
+
tool: t("aiChat.roleTool")
|
|
1252
|
+
};
|
|
325
1253
|
function safeHref(uri) {
|
|
326
1254
|
const s = uri.trim().toLowerCase();
|
|
327
1255
|
if (s.startsWith("javascript:") || s.startsWith("data:text/html")) return void 0;
|
|
@@ -329,7 +1257,7 @@ function safeHref(uri) {
|
|
|
329
1257
|
}
|
|
330
1258
|
function renderAiContentPart(part) {
|
|
331
1259
|
if (part.type === "text") {
|
|
332
|
-
const span = h("span", "ai-msg-text");
|
|
1260
|
+
const span = h("span", "icen-ai-msg-text");
|
|
333
1261
|
span.textContent = part.text;
|
|
334
1262
|
if (part.state === "streaming") span.classList.add("is-streaming");
|
|
335
1263
|
return span;
|
|
@@ -338,7 +1266,7 @@ function renderAiContentPart(part) {
|
|
|
338
1266
|
const src = aiContentUrl(part);
|
|
339
1267
|
if (!src) return void 0;
|
|
340
1268
|
const img = document.createElement("img");
|
|
341
|
-
img.className = "ai-msg-media ai-msg-media--image";
|
|
1269
|
+
img.className = "icen-ai-msg-media icen-ai-msg-media--image";
|
|
342
1270
|
img.alt = part.alt ?? "";
|
|
343
1271
|
img.setAttribute("loading", "lazy");
|
|
344
1272
|
img.setAttribute("src", src);
|
|
@@ -348,7 +1276,7 @@ function renderAiContentPart(part) {
|
|
|
348
1276
|
const src = aiContentUrl(part);
|
|
349
1277
|
if (!src) return void 0;
|
|
350
1278
|
const audio = document.createElement("audio");
|
|
351
|
-
audio.className = "ai-msg-media ai-msg-media--audio";
|
|
1279
|
+
audio.className = "icen-ai-msg-media icen-ai-msg-media--audio";
|
|
352
1280
|
audio.controls = true;
|
|
353
1281
|
audio.setAttribute("src", src);
|
|
354
1282
|
return audio;
|
|
@@ -357,28 +1285,28 @@ function renderAiContentPart(part) {
|
|
|
357
1285
|
const src = aiContentUrl(part);
|
|
358
1286
|
if (!src) return void 0;
|
|
359
1287
|
const video = document.createElement("video");
|
|
360
|
-
video.className = "ai-msg-media ai-msg-media--video";
|
|
1288
|
+
video.className = "icen-ai-msg-media icen-ai-msg-media--video";
|
|
361
1289
|
video.controls = true;
|
|
362
1290
|
video.setAttribute("playsinline", "");
|
|
363
1291
|
video.setAttribute("src", src);
|
|
364
1292
|
return video;
|
|
365
1293
|
}
|
|
366
1294
|
if (part.type === "file") {
|
|
367
|
-
const chip = h("span", "ai-msg-file");
|
|
368
|
-
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? "
|
|
1295
|
+
const chip = h("span", "icen-ai-msg-file");
|
|
1296
|
+
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? t("aiChat.file")));
|
|
369
1297
|
const href2 = part.url ? safeHref(part.url) : void 0;
|
|
370
1298
|
if (href2 && /^(https?:|data:)/i.test(href2)) {
|
|
371
1299
|
const a2 = document.createElement("a");
|
|
372
|
-
a2.className = "ai-msg-file-link";
|
|
1300
|
+
a2.className = "icen-ai-msg-file-link";
|
|
373
1301
|
a2.href = href2;
|
|
374
1302
|
a2.download = part.filename ?? "";
|
|
375
|
-
a2.textContent = "
|
|
1303
|
+
a2.textContent = t("aiChat.download");
|
|
376
1304
|
chip.appendChild(a2);
|
|
377
1305
|
}
|
|
378
1306
|
return chip;
|
|
379
1307
|
}
|
|
380
1308
|
const a = document.createElement("a");
|
|
381
|
-
a.className = "ai-msg-link";
|
|
1309
|
+
a.className = "icen-ai-msg-link";
|
|
382
1310
|
const href = safeHref(part.uri);
|
|
383
1311
|
if (href) a.href = href;
|
|
384
1312
|
a.textContent = part.name ?? part.uri;
|
|
@@ -394,16 +1322,16 @@ function toneVar(tone = "accent") {
|
|
|
394
1322
|
if (registered) return registered;
|
|
395
1323
|
switch (tone) {
|
|
396
1324
|
case "success":
|
|
397
|
-
return "var(--token-success)";
|
|
1325
|
+
return "var(--icen-token-success)";
|
|
398
1326
|
case "warning":
|
|
399
|
-
return "var(--token-warning)";
|
|
1327
|
+
return "var(--icen-token-warning)";
|
|
400
1328
|
case "error":
|
|
401
|
-
return "var(--token-error)";
|
|
1329
|
+
return "var(--icen-token-error)";
|
|
402
1330
|
case "muted":
|
|
403
|
-
return "var(--token-text-faint)";
|
|
1331
|
+
return "var(--icen-token-text-faint)";
|
|
404
1332
|
case "accent":
|
|
405
1333
|
default:
|
|
406
|
-
return "var(--token-accent)";
|
|
1334
|
+
return "var(--icen-token-accent)";
|
|
407
1335
|
}
|
|
408
1336
|
}
|
|
409
1337
|
function fmt(opts, value) {
|
|
@@ -414,13 +1342,66 @@ function maxOf(values) {
|
|
|
414
1342
|
for (const v of values) if (v > max) max = v;
|
|
415
1343
|
return max;
|
|
416
1344
|
}
|
|
417
|
-
function
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
1345
|
+
function pointLabelsRow(labels, width, pad) {
|
|
1346
|
+
const row = document.createElement("div");
|
|
1347
|
+
row.className = "icen-chart-labels icen-chart-labels--points";
|
|
1348
|
+
const count = Math.min(labels.length, Math.max(2, Math.min(7, Math.floor(width / 64))));
|
|
1349
|
+
const step = count > 1 ? (width - 2 * pad) / (count - 1) : width;
|
|
1350
|
+
for (let tick = 0; tick < count; tick++) {
|
|
1351
|
+
const index = count <= 1 ? 0 : Math.round(tick * (labels.length - 1) / (count - 1));
|
|
1352
|
+
const x = labels.length <= 1 ? width / 2 : pad + index / (labels.length - 1) * (width - 2 * pad);
|
|
1353
|
+
const span = document.createElement("span");
|
|
1354
|
+
span.textContent = labels[index] ?? "";
|
|
1355
|
+
span.title = span.textContent;
|
|
1356
|
+
span.dir = "auto";
|
|
1357
|
+
span.dataset.icenChartIndex = String(index);
|
|
1358
|
+
span.style.left = `${x / width * 100}%`;
|
|
1359
|
+
span.style.width = `${Math.max(0, Math.min(step * 0.9, 2 * x, 2 * (width - x)))}px`;
|
|
1360
|
+
row.appendChild(span);
|
|
422
1361
|
}
|
|
423
|
-
return
|
|
1362
|
+
return row;
|
|
1363
|
+
}
|
|
1364
|
+
function clampNum(v, lo, hi) {
|
|
1365
|
+
return Math.min(hi, Math.max(lo, v));
|
|
1366
|
+
}
|
|
1367
|
+
function lttb(points, threshold, getX, getY) {
|
|
1368
|
+
const len = points.length;
|
|
1369
|
+
const n = Math.floor(threshold);
|
|
1370
|
+
if (!Number.isFinite(n) || n < 3 || n >= len || len <= 3) return points;
|
|
1371
|
+
const sampled = new Array(n);
|
|
1372
|
+
sampled[0] = points[0];
|
|
1373
|
+
sampled[n - 1] = points[len - 1];
|
|
1374
|
+
const every = (len - 2) / (n - 2);
|
|
1375
|
+
let a = 0;
|
|
1376
|
+
for (let i = 0; i < n - 2; i++) {
|
|
1377
|
+
const avgStart = Math.floor((i + 1) * every) + 1;
|
|
1378
|
+
const avgEnd = Math.min(Math.floor((i + 2) * every) + 1, len);
|
|
1379
|
+
let avgX = 0;
|
|
1380
|
+
let avgY = 0;
|
|
1381
|
+
for (let j = avgStart; j < avgEnd; j++) {
|
|
1382
|
+
avgX += getX(points[j]);
|
|
1383
|
+
avgY += getY(points[j]);
|
|
1384
|
+
}
|
|
1385
|
+
const avgLen = Math.max(1, avgEnd - avgStart);
|
|
1386
|
+
avgX /= avgLen;
|
|
1387
|
+
avgY /= avgLen;
|
|
1388
|
+
const rangeStart = Math.floor(i * every) + 1;
|
|
1389
|
+
const rangeEnd = Math.min(Math.floor((i + 1) * every) + 1, len);
|
|
1390
|
+
const ax = getX(points[a]);
|
|
1391
|
+
const ay = getY(points[a]);
|
|
1392
|
+
let maxArea = -1;
|
|
1393
|
+
let nextA = rangeStart;
|
|
1394
|
+
for (let j = rangeStart; j < rangeEnd; j++) {
|
|
1395
|
+
const area = Math.abs((ax - avgX) * (getY(points[j]) - ay) - (ax - getX(points[j])) * (avgY - ay)) * 0.5;
|
|
1396
|
+
if (area > maxArea) {
|
|
1397
|
+
maxArea = area;
|
|
1398
|
+
nextA = j;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
sampled[i + 1] = points[nextA];
|
|
1402
|
+
a = nextA;
|
|
1403
|
+
}
|
|
1404
|
+
return sampled;
|
|
424
1405
|
}
|
|
425
1406
|
function svgEl(tag, attrs) {
|
|
426
1407
|
const el = document.createElementNS(SVG_NS, tag);
|
|
@@ -429,28 +1410,28 @@ function svgEl(tag, attrs) {
|
|
|
429
1410
|
}
|
|
430
1411
|
function renderEmpty(el, label) {
|
|
431
1412
|
const box = document.createElement("div");
|
|
432
|
-
box.className = "chart-empty";
|
|
433
|
-
box.textContent = label ?? "
|
|
1413
|
+
box.className = "icen-chart-empty";
|
|
1414
|
+
box.textContent = label ?? t("charts.noData");
|
|
434
1415
|
el.appendChild(box);
|
|
435
1416
|
}
|
|
436
1417
|
function legendItem(label, valueText, tone) {
|
|
437
1418
|
const row = document.createElement("div");
|
|
438
|
-
row.className = "chart-legend-item";
|
|
1419
|
+
row.className = "icen-chart-legend-item";
|
|
439
1420
|
const dot = document.createElement("span");
|
|
440
|
-
dot.className = "chart-legend-dot";
|
|
1421
|
+
dot.className = "icen-chart-legend-dot";
|
|
441
1422
|
if (tone) dot.style.setProperty("--chart-tone", toneVar(tone));
|
|
442
1423
|
const name = document.createElement("span");
|
|
443
|
-
name.className = "chart-legend-label";
|
|
1424
|
+
name.className = "icen-chart-legend-label";
|
|
444
1425
|
name.textContent = label;
|
|
445
1426
|
const val = document.createElement("span");
|
|
446
|
-
val.className = "chart-legend-value";
|
|
1427
|
+
val.className = "icen-chart-legend-value";
|
|
447
1428
|
val.textContent = valueText;
|
|
448
1429
|
row.append(dot, name, val);
|
|
449
1430
|
return row;
|
|
450
1431
|
}
|
|
451
1432
|
function labelsRow(labels) {
|
|
452
1433
|
const row = document.createElement("div");
|
|
453
|
-
row.className = "chart-labels";
|
|
1434
|
+
row.className = "icen-chart-labels";
|
|
454
1435
|
for (const label of labels) {
|
|
455
1436
|
const span = document.createElement("span");
|
|
456
1437
|
span.textContent = label;
|
|
@@ -465,85 +1446,90 @@ function normalizeSeriesInput(opts) {
|
|
|
465
1446
|
function toneOf(tone, seriesIndex) {
|
|
466
1447
|
if (typeof tone === "string") return toneVar(tone);
|
|
467
1448
|
if (typeof tone === "number") return paletteVar(tone);
|
|
468
|
-
return seriesIndex > 0 ? paletteVar(
|
|
1449
|
+
return seriesIndex > 0 ? paletteVar(seriesIndex % 6 + 1) : void 0;
|
|
469
1450
|
}
|
|
470
1451
|
var PALETTE_VARS = [
|
|
471
|
-
"var(--token-accent)",
|
|
472
|
-
"var(--token-accent-cold)",
|
|
473
|
-
"var(--token-success)",
|
|
474
|
-
"var(--token-warning)",
|
|
475
|
-
"var(--token-info)",
|
|
476
|
-
"color-mix(in srgb, var(--token-text) 50%, transparent)"
|
|
1452
|
+
"var(--icen-token-accent)",
|
|
1453
|
+
"var(--icen-token-accent-cold)",
|
|
1454
|
+
"var(--icen-token-success)",
|
|
1455
|
+
"var(--icen-token-warning)",
|
|
1456
|
+
"var(--icen-token-info)",
|
|
1457
|
+
"color-mix(in srgb, var(--icen-token-text) 50%, transparent)"
|
|
477
1458
|
];
|
|
478
1459
|
function paletteVar(index) {
|
|
479
1460
|
const i = ((Math.floor(index) - 1) % 6 + 6) % 6;
|
|
480
1461
|
return PALETTE_VARS[i];
|
|
481
1462
|
}
|
|
482
1463
|
function setMarkData(node, data) {
|
|
483
|
-
node.setAttribute("data-chart-mark", "1");
|
|
484
|
-
if (data.index != null) node.setAttribute("data-chart-index", String(data.index));
|
|
485
|
-
if (data.seriesIndex != null) node.setAttribute("data-chart-series", String(data.seriesIndex));
|
|
486
|
-
if (data.seriesName != null) node.setAttribute("data-chart-series-name", String(data.seriesName));
|
|
487
|
-
if (data.label != null) node.setAttribute("data-chart-label", String(data.label));
|
|
488
|
-
if (data.value != null) node.setAttribute("data-chart-value", String(data.value));
|
|
1464
|
+
node.setAttribute("data-icen-chart-mark", "1");
|
|
1465
|
+
if (data.index != null) node.setAttribute("data-icen-chart-index", String(data.index));
|
|
1466
|
+
if (data.seriesIndex != null) node.setAttribute("data-icen-chart-series", String(data.seriesIndex));
|
|
1467
|
+
if (data.seriesName != null) node.setAttribute("data-icen-chart-series-name", String(data.seriesName));
|
|
1468
|
+
if (data.label != null) node.setAttribute("data-icen-chart-label", String(data.label));
|
|
1469
|
+
if (data.value != null) node.setAttribute("data-icen-chart-value", String(data.value));
|
|
489
1470
|
}
|
|
490
1471
|
function copyMarkData(target, source) {
|
|
491
1472
|
for (const attr of Array.from(source.attributes)) {
|
|
492
|
-
if (attr.name.startsWith("data-chart-")) target.setAttribute(attr.name, attr.value);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
var CHART_EYE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0"/><circle cx="12" cy="12" r="3"/></svg>';
|
|
496
|
-
var CHART_EYE_OFF_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.73 5.08A10.4 10.4 0 0 1 12 5c7 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68"/><path d="M6.61 6.61A13.5 13.5 0 0 0 2 12s3 7 10 7a9.7 9.7 0 0 0 5.39-1.61"/><path d="M2 2l20 20"/><path d="M9.9 9.9a3 3 0 0 0 4.2 4.2"/></svg>';
|
|
497
|
-
function parseChartSvg(svg2) {
|
|
498
|
-
try {
|
|
499
|
-
const doc = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
500
|
-
const el = doc.documentElement;
|
|
501
|
-
return el && el.tagName.toLowerCase() === "svg" && !doc.querySelector("parsererror") ? document.importNode(el, true) : null;
|
|
502
|
-
} catch {
|
|
503
|
-
return null;
|
|
1473
|
+
if (attr.name.startsWith("data-icen-chart-")) target.setAttribute(attr.name, attr.value);
|
|
504
1474
|
}
|
|
505
1475
|
}
|
|
506
|
-
function withChrome(el, opts, hasLegend, paint, state) {
|
|
507
|
-
if (el.dataset.
|
|
1476
|
+
function withChrome(el, opts, hasLegend, paint, state, extras) {
|
|
1477
|
+
if (el.dataset.icenChartBody != null) {
|
|
508
1478
|
el.textContent = "";
|
|
509
1479
|
paint(el);
|
|
510
1480
|
return;
|
|
511
1481
|
}
|
|
512
1482
|
el.textContent = "";
|
|
513
1483
|
const body = document.createElement("div");
|
|
514
|
-
body.className = "chart-body";
|
|
515
|
-
body.dataset.
|
|
516
|
-
|
|
1484
|
+
body.className = "icen-chart-body";
|
|
1485
|
+
body.dataset.icenChartBody = "";
|
|
1486
|
+
const note = extras?.note ?? null;
|
|
1487
|
+
const onZoomReset = extras?.onZoomReset ?? null;
|
|
1488
|
+
if (!opts.title && !hasLegend && note == null && !onZoomReset) {
|
|
517
1489
|
el.appendChild(body);
|
|
518
1490
|
paint(body);
|
|
519
1491
|
return;
|
|
520
1492
|
}
|
|
521
1493
|
let hidden = state && state.hidden != null ? state.hidden : opts.legend === false;
|
|
522
1494
|
if (state) state.hidden = hidden;
|
|
523
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1495
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
524
1496
|
const head = document.createElement("div");
|
|
525
|
-
head.className = "chart-head";
|
|
1497
|
+
head.className = "icen-chart-head";
|
|
526
1498
|
const title = document.createElement("div");
|
|
527
|
-
title.className = "chart-title";
|
|
1499
|
+
title.className = "icen-chart-title";
|
|
528
1500
|
title.textContent = opts.title ?? "";
|
|
529
1501
|
if (!opts.title) title.setAttribute("aria-hidden", "true");
|
|
1502
|
+
if (note != null) {
|
|
1503
|
+
const noteEl = document.createElement("span");
|
|
1504
|
+
noteEl.className = "icen-chart-note";
|
|
1505
|
+
noteEl.textContent = note;
|
|
1506
|
+
head.appendChild(noteEl);
|
|
1507
|
+
}
|
|
1508
|
+
if (onZoomReset) {
|
|
1509
|
+
const chip = document.createElement("button");
|
|
1510
|
+
chip.type = "button";
|
|
1511
|
+
chip.className = "icen-chart-zoom-reset";
|
|
1512
|
+
chip.textContent = t("charts.resetZoom");
|
|
1513
|
+
chip.addEventListener("click", onZoomReset);
|
|
1514
|
+
head.appendChild(chip);
|
|
1515
|
+
}
|
|
530
1516
|
const eye = document.createElement("button");
|
|
531
1517
|
eye.type = "button";
|
|
532
|
-
eye.className = "chart-legend-eye";
|
|
533
|
-
eye.dataset.
|
|
1518
|
+
eye.className = "icen-chart-legend-eye";
|
|
1519
|
+
eye.dataset.icenChartLegendEye = "";
|
|
534
1520
|
const syncEye = () => {
|
|
535
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1521
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
536
1522
|
eye.setAttribute("aria-pressed", String(!nowHidden));
|
|
537
|
-
eye.setAttribute("aria-label", nowHidden ? "
|
|
538
|
-
eye.setAttribute("title", nowHidden ? "
|
|
539
|
-
const icon =
|
|
1523
|
+
eye.setAttribute("aria-label", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1524
|
+
eye.setAttribute("title", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1525
|
+
const icon = createIcon(nowHidden ? "eye-off" : "eye");
|
|
540
1526
|
if (icon) eye.replaceChildren(icon);
|
|
541
1527
|
};
|
|
542
1528
|
eye.addEventListener("click", () => {
|
|
543
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1529
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
544
1530
|
hidden = !nowHidden;
|
|
545
1531
|
if (state) state.hidden = hidden;
|
|
546
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1532
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
547
1533
|
syncEye();
|
|
548
1534
|
emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
|
|
549
1535
|
});
|
|
@@ -552,23 +1538,30 @@ function withChrome(el, opts, hasLegend, paint, state) {
|
|
|
552
1538
|
el.append(head, body);
|
|
553
1539
|
paint(body);
|
|
554
1540
|
}
|
|
1541
|
+
var hiddenLegendKeys = /* @__PURE__ */ new WeakMap();
|
|
555
1542
|
function toggleLegend(items, scope) {
|
|
556
1543
|
const legend = document.createElement("div");
|
|
557
|
-
legend.className = "chart-legend chart-legend--toggle";
|
|
1544
|
+
legend.className = "icen-chart-legend icen-chart-legend--toggle";
|
|
1545
|
+
const owner = scope instanceof Element ? scope.closest("[data-icen-chart-body]")?.parentElement ?? scope : null;
|
|
1546
|
+
const hidden = owner ? hiddenLegendKeys.get(owner) ?? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
|
|
1547
|
+
if (owner) hiddenLegendKeys.set(owner, hidden);
|
|
558
1548
|
for (const item of items) {
|
|
559
1549
|
const row = legendItem(item.label, "", item.tone);
|
|
560
|
-
row.classList.add("chart-legend-toggle-item");
|
|
1550
|
+
row.classList.add("icen-chart-legend-toggle-item");
|
|
561
1551
|
row.setAttribute("role", "button");
|
|
562
1552
|
row.tabIndex = 0;
|
|
563
|
-
row.
|
|
564
|
-
row.
|
|
565
|
-
|
|
566
|
-
const
|
|
1553
|
+
row.classList.toggle("is-off", hidden.has(item.key));
|
|
1554
|
+
row.setAttribute("aria-pressed", String(!hidden.has(item.key)));
|
|
1555
|
+
row.dataset.icenChartKey = item.key;
|
|
1556
|
+
const dot = row.querySelector(".icen-chart-legend-dot");
|
|
1557
|
+
const toneColor = toneOf(item.tone, item.si);
|
|
567
1558
|
if (dot && toneColor) dot.style.setProperty("--chart-tone", toneColor);
|
|
568
1559
|
const toggle = () => {
|
|
569
1560
|
const off = row.classList.toggle("is-off");
|
|
1561
|
+
if (off) hidden.add(item.key);
|
|
1562
|
+
else hidden.delete(item.key);
|
|
570
1563
|
row.setAttribute("aria-pressed", String(!off));
|
|
571
|
-
scope.querySelectorAll(`[data-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
1564
|
+
scope.querySelectorAll(`[data-icen-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
572
1565
|
m.classList.toggle("is-off", off);
|
|
573
1566
|
});
|
|
574
1567
|
emitIcen(legend, "icen:chart-legend-toggle", { key: item.key, seriesIndex: item.si, hidden: off });
|
|
@@ -583,8 +1576,9 @@ function toggleLegend(items, scope) {
|
|
|
583
1576
|
legend.appendChild(row);
|
|
584
1577
|
}
|
|
585
1578
|
for (const item of items) {
|
|
586
|
-
scope.querySelectorAll(`[data-chart-series="${item.si}"]`).forEach((m) => {
|
|
587
|
-
if (!m.hasAttribute("data-chart-key")) m.setAttribute("data-chart-key", item.key);
|
|
1579
|
+
scope.querySelectorAll(`[data-icen-chart-series="${item.si}"]`).forEach((m) => {
|
|
1580
|
+
if (!m.hasAttribute("data-icen-chart-key")) m.setAttribute("data-icen-chart-key", item.key);
|
|
1581
|
+
m.classList.toggle("is-off", hidden.has(item.key));
|
|
588
1582
|
});
|
|
589
1583
|
}
|
|
590
1584
|
return legend;
|
|
@@ -611,19 +1605,19 @@ function renderVBar(el, opts) {
|
|
|
611
1605
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
612
1606
|
}
|
|
613
1607
|
const wrap = document.createElement("div");
|
|
614
|
-
wrap.className = "chart-vbar";
|
|
1608
|
+
wrap.className = "icen-chart-vbar";
|
|
615
1609
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
616
1610
|
for (let i = 0; i < n; i++) {
|
|
617
1611
|
const track = document.createElement("div");
|
|
618
|
-
track.className = "chart-vbar-track";
|
|
1612
|
+
track.className = "icen-chart-vbar-track";
|
|
619
1613
|
if (seriesList.length > 1) {
|
|
620
|
-
track.classList.add("chart-vbar-track--multi");
|
|
621
|
-
if (opts.stacked) track.classList.add("chart-vbar-track--stacked");
|
|
1614
|
+
track.classList.add("icen-chart-vbar-track--multi");
|
|
1615
|
+
if (opts.stacked) track.classList.add("icen-chart-vbar-track--stacked");
|
|
622
1616
|
}
|
|
623
1617
|
seriesList.forEach((s, si) => {
|
|
624
1618
|
const value = s.values[i] ?? 0;
|
|
625
1619
|
const bar = document.createElement("div");
|
|
626
|
-
bar.className = "chart-vbar-bar";
|
|
1620
|
+
bar.className = "icen-chart-vbar-bar";
|
|
627
1621
|
const height = value > 0 ? Math.max(6, value / max * 100) : 0;
|
|
628
1622
|
bar.style.height = `${height}%`;
|
|
629
1623
|
const toneColor = toneOf(s.tone, si);
|
|
@@ -641,7 +1635,7 @@ function renderVBar(el, opts) {
|
|
|
641
1635
|
wrap.appendChild(track);
|
|
642
1636
|
}
|
|
643
1637
|
body.append(wrap, labelsRow(labelsUsed));
|
|
644
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone, si })), wrap));
|
|
1638
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
645
1639
|
});
|
|
646
1640
|
attachChartInteraction(el, "vbar");
|
|
647
1641
|
return el;
|
|
@@ -658,22 +1652,22 @@ function renderHBar(el, opts) {
|
|
|
658
1652
|
const values = opts.values.slice(0, n);
|
|
659
1653
|
const max = maxOf(values);
|
|
660
1654
|
const wrap = document.createElement("div");
|
|
661
|
-
wrap.className = "chart-hbar";
|
|
1655
|
+
wrap.className = "icen-chart-hbar";
|
|
662
1656
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
663
1657
|
values.forEach((value, i) => {
|
|
664
1658
|
const row = document.createElement("div");
|
|
665
|
-
row.className = "chart-hbar-row";
|
|
1659
|
+
row.className = "icen-chart-hbar-row";
|
|
666
1660
|
const label = document.createElement("span");
|
|
667
|
-
label.className = "chart-hbar-label";
|
|
1661
|
+
label.className = "icen-chart-hbar-label";
|
|
668
1662
|
label.textContent = labels[i] ?? "";
|
|
669
1663
|
const track = document.createElement("div");
|
|
670
|
-
track.className = "chart-hbar-track";
|
|
1664
|
+
track.className = "icen-chart-hbar-track";
|
|
671
1665
|
const bar = document.createElement("div");
|
|
672
|
-
bar.className = "chart-hbar-bar";
|
|
1666
|
+
bar.className = "icen-chart-hbar-bar";
|
|
673
1667
|
bar.style.width = value > 0 ? `${Math.max(2, value / max * 100)}%` : "0%";
|
|
674
1668
|
setMarkData(bar, { index: i, label: labels[i] ?? "", value });
|
|
675
1669
|
const val = document.createElement("span");
|
|
676
|
-
val.className = "chart-hbar-value";
|
|
1670
|
+
val.className = "icen-chart-hbar-value";
|
|
677
1671
|
val.textContent = fmt(opts, value);
|
|
678
1672
|
track.appendChild(bar);
|
|
679
1673
|
row.append(label, track, val);
|
|
@@ -693,10 +1687,10 @@ function renderStack(el, opts) {
|
|
|
693
1687
|
return;
|
|
694
1688
|
}
|
|
695
1689
|
const bar = document.createElement("div");
|
|
696
|
-
bar.className = "chart-stack";
|
|
1690
|
+
bar.className = "icen-chart-stack";
|
|
697
1691
|
for (const [segIndex, seg] of opts.segments.entries()) {
|
|
698
1692
|
const s = document.createElement("div");
|
|
699
|
-
s.className = "chart-stack-seg";
|
|
1693
|
+
s.className = "icen-chart-stack-seg";
|
|
700
1694
|
s.style.width = `${seg.value / total * 100}%`;
|
|
701
1695
|
if (seg.tone) s.style.setProperty("--chart-tone", toneVar(seg.tone));
|
|
702
1696
|
s.setAttribute("title", `${seg.label}: ${fmt(opts, seg.value)}`);
|
|
@@ -704,7 +1698,7 @@ function renderStack(el, opts) {
|
|
|
704
1698
|
bar.appendChild(s);
|
|
705
1699
|
}
|
|
706
1700
|
const legend = document.createElement("div");
|
|
707
|
-
legend.className = "chart-legend";
|
|
1701
|
+
legend.className = "icen-chart-legend";
|
|
708
1702
|
for (const seg of opts.segments) {
|
|
709
1703
|
legend.appendChild(legendItem(seg.label, fmt(opts, seg.value), seg.tone));
|
|
710
1704
|
}
|
|
@@ -724,15 +1718,15 @@ function renderDonut(el, opts) {
|
|
|
724
1718
|
const radius = 42;
|
|
725
1719
|
const circumference = 2 * Math.PI * radius;
|
|
726
1720
|
const wrap = document.createElement("div");
|
|
727
|
-
wrap.className = "chart-donut";
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
1721
|
+
wrap.className = "icen-chart-donut";
|
|
1722
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.donut")) });
|
|
1723
|
+
svg.style.transform = "rotate(-90deg)";
|
|
1724
|
+
svg.appendChild(svgEl("circle", {
|
|
731
1725
|
cx: "60",
|
|
732
1726
|
cy: "60",
|
|
733
1727
|
r: String(radius),
|
|
734
1728
|
fill: "none",
|
|
735
|
-
stroke: "var(--token-line-soft)",
|
|
1729
|
+
stroke: "var(--icen-token-line-soft)",
|
|
736
1730
|
"stroke-width": "14"
|
|
737
1731
|
}));
|
|
738
1732
|
let offset = 0;
|
|
@@ -750,15 +1744,15 @@ function renderDonut(el, opts) {
|
|
|
750
1744
|
"stroke-linecap": "butt"
|
|
751
1745
|
});
|
|
752
1746
|
setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
|
|
753
|
-
|
|
1747
|
+
svg.appendChild(arc);
|
|
754
1748
|
offset += dash;
|
|
755
1749
|
});
|
|
756
1750
|
const legend = document.createElement("div");
|
|
757
|
-
legend.className = "chart-legend";
|
|
1751
|
+
legend.className = "icen-chart-legend";
|
|
758
1752
|
for (const seg of opts.segments) {
|
|
759
1753
|
legend.appendChild(legendItem(seg.label, `${Math.round(seg.value / total * 100)}%`, seg.tone));
|
|
760
1754
|
}
|
|
761
|
-
wrap.append(
|
|
1755
|
+
wrap.append(svg, legend);
|
|
762
1756
|
body.appendChild(wrap);
|
|
763
1757
|
});
|
|
764
1758
|
attachChartInteraction(el, "donut");
|
|
@@ -776,23 +1770,23 @@ function renderLine(el, opts) {
|
|
|
776
1770
|
return;
|
|
777
1771
|
}
|
|
778
1772
|
const labelsUsed = labels.slice(0, n);
|
|
779
|
-
const width =
|
|
1773
|
+
const width = fluidWidth(body);
|
|
780
1774
|
const height = 150;
|
|
781
1775
|
const pad = 14;
|
|
782
1776
|
let max = 1;
|
|
783
1777
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
784
1778
|
const wrap = document.createElement("div");
|
|
785
|
-
wrap.className = "chart-line";
|
|
786
|
-
const
|
|
1779
|
+
wrap.className = "icen-chart-line";
|
|
1780
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
|
|
787
1781
|
const defs = svgEl("defs", {});
|
|
788
1782
|
for (let i = 0; i < 4; i++) {
|
|
789
1783
|
const y = pad + i * (height - pad * 2) / 3;
|
|
790
|
-
|
|
1784
|
+
svg.appendChild(svgEl("line", {
|
|
791
1785
|
x1: String(pad),
|
|
792
1786
|
x2: String(width - pad),
|
|
793
1787
|
y1: String(y),
|
|
794
1788
|
y2: String(y),
|
|
795
|
-
stroke: "var(--token-line-soft)",
|
|
1789
|
+
stroke: "var(--icen-token-line-soft)",
|
|
796
1790
|
"stroke-width": "1"
|
|
797
1791
|
}));
|
|
798
1792
|
}
|
|
@@ -822,7 +1816,7 @@ function renderLine(el, opts) {
|
|
|
822
1816
|
if (seriesList.length > 1) {
|
|
823
1817
|
setMarkData(areaPath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values.reduce((a, b) => a + b, 0) });
|
|
824
1818
|
}
|
|
825
|
-
|
|
1819
|
+
svg.appendChild(areaPath);
|
|
826
1820
|
}
|
|
827
1821
|
const linePath = svgEl("path", {
|
|
828
1822
|
d: line,
|
|
@@ -833,16 +1827,16 @@ function renderLine(el, opts) {
|
|
|
833
1827
|
"stroke-linejoin": "round"
|
|
834
1828
|
});
|
|
835
1829
|
const lineTitle = svgEl("title", {});
|
|
836
|
-
lineTitle.textContent = s.name || "
|
|
1830
|
+
lineTitle.textContent = s.name || t("charts.value");
|
|
837
1831
|
linePath.appendChild(lineTitle);
|
|
838
1832
|
setMarkData(linePath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values[values.length - 1] ?? 0 });
|
|
839
|
-
|
|
1833
|
+
svg.appendChild(linePath);
|
|
840
1834
|
for (const p of points) {
|
|
841
1835
|
const dot = svgEl("circle", {
|
|
842
1836
|
cx: p.x.toFixed(1),
|
|
843
1837
|
cy: p.y.toFixed(1),
|
|
844
1838
|
r: "3",
|
|
845
|
-
fill: "var(--token-card)",
|
|
1839
|
+
fill: "var(--icen-token-card)",
|
|
846
1840
|
stroke: tone,
|
|
847
1841
|
"stroke-width": "2"
|
|
848
1842
|
});
|
|
@@ -856,23 +1850,24 @@ function renderLine(el, opts) {
|
|
|
856
1850
|
label: p.label,
|
|
857
1851
|
value: p.value
|
|
858
1852
|
});
|
|
859
|
-
|
|
1853
|
+
svg.appendChild(dot);
|
|
860
1854
|
const hit = svgEl("circle", {
|
|
861
1855
|
cx: p.x.toFixed(1),
|
|
862
1856
|
cy: p.y.toFixed(1),
|
|
863
1857
|
r: "8",
|
|
864
1858
|
fill: "transparent",
|
|
865
|
-
"data-chart-hit": "1"
|
|
1859
|
+
"data-icen-chart-hit": "1"
|
|
866
1860
|
});
|
|
867
1861
|
copyMarkData(hit, dot);
|
|
868
|
-
|
|
1862
|
+
svg.appendChild(hit);
|
|
869
1863
|
}
|
|
870
1864
|
});
|
|
871
|
-
if (defs.firstChild)
|
|
872
|
-
wrap.append(
|
|
1865
|
+
if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
|
|
1866
|
+
wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
|
|
873
1867
|
body.appendChild(wrap);
|
|
874
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone, si })), wrap));
|
|
1868
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
875
1869
|
});
|
|
1870
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
|
|
876
1871
|
attachChartInteraction(el, "line");
|
|
877
1872
|
return el;
|
|
878
1873
|
}
|
|
@@ -904,30 +1899,30 @@ function renderRadar(el, opts) {
|
|
|
904
1899
|
y: cy + r * Math.sin(angleOf(i))
|
|
905
1900
|
});
|
|
906
1901
|
const wrap = document.createElement("div");
|
|
907
|
-
wrap.className = "chart-radar";
|
|
908
|
-
const
|
|
1902
|
+
wrap.className = "icen-chart-radar";
|
|
1903
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${size} ${size}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.radar")) });
|
|
909
1904
|
for (let lv = 1; lv <= levels; lv++) {
|
|
910
1905
|
const r = radius * lv / levels;
|
|
911
1906
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
912
1907
|
const p = pointAt(i, r);
|
|
913
1908
|
return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;
|
|
914
1909
|
}).join(" ");
|
|
915
|
-
|
|
1910
|
+
svg.appendChild(svgEl("polygon", {
|
|
916
1911
|
points: pts,
|
|
917
1912
|
fill: "none",
|
|
918
|
-
stroke: "var(--token-line-soft)",
|
|
1913
|
+
stroke: "var(--icen-token-line-soft)",
|
|
919
1914
|
"stroke-width": "1",
|
|
920
1915
|
"stroke-dasharray": lv === levels ? "0" : "3 2"
|
|
921
1916
|
}));
|
|
922
1917
|
}
|
|
923
1918
|
for (let i = 0; i < n; i++) {
|
|
924
1919
|
const edge = pointAt(i, radius);
|
|
925
|
-
|
|
1920
|
+
svg.appendChild(svgEl("line", {
|
|
926
1921
|
x1: String(cx),
|
|
927
1922
|
y1: String(cy),
|
|
928
1923
|
x2: edge.x.toFixed(1),
|
|
929
1924
|
y2: edge.y.toFixed(1),
|
|
930
|
-
stroke: "var(--token-line-soft)",
|
|
1925
|
+
stroke: "var(--icen-token-line-soft)",
|
|
931
1926
|
"stroke-width": "1"
|
|
932
1927
|
}));
|
|
933
1928
|
const labelP = pointAt(i, radius + 14);
|
|
@@ -937,14 +1932,14 @@ function renderRadar(el, opts) {
|
|
|
937
1932
|
"text-anchor": "middle",
|
|
938
1933
|
"dominant-baseline": "middle",
|
|
939
1934
|
"font-size": "9",
|
|
940
|
-
fill: "var(--token-text-muted)"
|
|
1935
|
+
fill: "var(--icen-token-text-muted)"
|
|
941
1936
|
});
|
|
942
1937
|
txt.textContent = axes[i] ?? "";
|
|
943
|
-
|
|
1938
|
+
svg.appendChild(txt);
|
|
944
1939
|
}
|
|
945
1940
|
const legendItems = [];
|
|
946
1941
|
opts.series.forEach((s, si) => {
|
|
947
|
-
const tone = toneVar(s.tone);
|
|
1942
|
+
const tone = toneOf(s.tone, si) ?? toneVar(s.tone);
|
|
948
1943
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
949
1944
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
950
1945
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -962,7 +1957,7 @@ function renderRadar(el, opts) {
|
|
|
962
1957
|
title.textContent = `${s.name}: ${s.values.map((v) => fmt(opts, v)).join(" / ")}`;
|
|
963
1958
|
polyFill.appendChild(title);
|
|
964
1959
|
setMarkData(polyFill, { seriesIndex: si, seriesName: s.name || void 0, label: s.name, value: s.values.reduce((a, b) => a + (b || 0), 0) });
|
|
965
|
-
|
|
1960
|
+
svg.appendChild(polyFill);
|
|
966
1961
|
for (let i = 0; i < n; i++) {
|
|
967
1962
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
968
1963
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -970,18 +1965,19 @@ function renderRadar(el, opts) {
|
|
|
970
1965
|
cx: p.x.toFixed(1),
|
|
971
1966
|
cy: p.y.toFixed(1),
|
|
972
1967
|
r: "2.5",
|
|
973
|
-
fill: "var(--token-card)",
|
|
1968
|
+
fill: "var(--icen-token-card)",
|
|
974
1969
|
stroke: tone,
|
|
975
1970
|
"stroke-width": "1.5"
|
|
976
1971
|
});
|
|
977
1972
|
setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
|
|
978
|
-
|
|
1973
|
+
svg.appendChild(dot);
|
|
979
1974
|
}
|
|
980
|
-
legendItems.push({ key: s.name ||
|
|
1975
|
+
legendItems.push({ key: s.name || t("charts.seriesName", { p0: si + 1 }), label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
|
|
981
1976
|
});
|
|
982
|
-
|
|
983
|
-
wrap.append(svg2, ...legend ? [legend] : []);
|
|
1977
|
+
wrap.appendChild(svg);
|
|
984
1978
|
body.appendChild(wrap);
|
|
1979
|
+
const legend = opts.series.length > 1 ? toggleLegend(legendItems, wrap) : null;
|
|
1980
|
+
if (legend) wrap.appendChild(legend);
|
|
985
1981
|
});
|
|
986
1982
|
attachChartInteraction(el, "radar");
|
|
987
1983
|
return el;
|
|
@@ -1014,23 +2010,23 @@ function padFirstWeek(grid, firstDate, weekStart) {
|
|
|
1014
2010
|
const pad = (first.getDay() + 7 - weekStart) % 7;
|
|
1015
2011
|
for (let i = 0; i < pad; i++) {
|
|
1016
2012
|
const blank = document.createElement("span");
|
|
1017
|
-
blank.className = "chart-heatmap-cell is-blank";
|
|
2013
|
+
blank.className = "icen-chart-heatmap-cell is-blank";
|
|
1018
2014
|
grid.appendChild(blank);
|
|
1019
2015
|
}
|
|
1020
2016
|
return pad;
|
|
1021
2017
|
}
|
|
1022
2018
|
function heatmapLegend(labels) {
|
|
1023
2019
|
const legend = document.createElement("div");
|
|
1024
|
-
legend.className = "chart-heatmap-legend";
|
|
2020
|
+
legend.className = "icen-chart-heatmap-legend";
|
|
1025
2021
|
const less = document.createElement("span");
|
|
1026
|
-
less.textContent = labels?.less ?? "
|
|
2022
|
+
less.textContent = labels?.less ?? t("charts.few");
|
|
1027
2023
|
const more = document.createElement("span");
|
|
1028
|
-
more.textContent = labels?.more ?? "
|
|
2024
|
+
more.textContent = labels?.more ?? t("charts.many");
|
|
1029
2025
|
legend.appendChild(less);
|
|
1030
2026
|
for (let lv = 0; lv <= 4; lv++) {
|
|
1031
2027
|
const cell = document.createElement("span");
|
|
1032
|
-
cell.className = "chart-heatmap-cell";
|
|
1033
|
-
cell.dataset.
|
|
2028
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2029
|
+
cell.dataset.icenLevel = String(lv);
|
|
1034
2030
|
legend.appendChild(cell);
|
|
1035
2031
|
}
|
|
1036
2032
|
legend.appendChild(more);
|
|
@@ -1057,16 +2053,17 @@ function renderHeatmap(el, opts) {
|
|
|
1057
2053
|
if (entries.length > weeks * 7) entries = entries.slice(entries.length - weeks * 7);
|
|
1058
2054
|
const max = maxOf(entries.map((e) => e.value));
|
|
1059
2055
|
const wrap = document.createElement("div");
|
|
1060
|
-
wrap.className = "chart-heatmap";
|
|
2056
|
+
wrap.className = "icen-chart-heatmap";
|
|
1061
2057
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1062
2058
|
const grid = document.createElement("div");
|
|
1063
|
-
grid.className = "chart-heatmap-grid";
|
|
2059
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1064
2060
|
grid.setAttribute("role", "img");
|
|
2061
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1065
2062
|
padFirstWeek(grid, entries[0].date, opts.weekStart === 0 ? 0 : 1);
|
|
1066
2063
|
for (const [i, entry] of entries.entries()) {
|
|
1067
2064
|
const cell = document.createElement("span");
|
|
1068
|
-
cell.className = "chart-heatmap-cell";
|
|
1069
|
-
cell.dataset.
|
|
2065
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2066
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1070
2067
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1071
2068
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1072
2069
|
grid.appendChild(cell);
|
|
@@ -1101,16 +2098,16 @@ function renderSparkline(el, opts) {
|
|
|
1101
2098
|
const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
|
|
1102
2099
|
const gradientId = `icen-chart-line-${++lineGradientSeq}`;
|
|
1103
2100
|
const wrap = document.createElement("div");
|
|
1104
|
-
wrap.className = "chart-sparkline";
|
|
1105
|
-
const
|
|
2101
|
+
wrap.className = "icen-chart-sparkline";
|
|
2102
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.sparkline")) });
|
|
1106
2103
|
const defs = svgEl("defs", {});
|
|
1107
2104
|
const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
|
|
1108
2105
|
gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.28" }));
|
|
1109
2106
|
gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.02" }));
|
|
1110
2107
|
defs.appendChild(gradient);
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
2108
|
+
svg.appendChild(defs);
|
|
2109
|
+
svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
|
|
2110
|
+
svg.appendChild(svgEl("path", {
|
|
1114
2111
|
d: line,
|
|
1115
2112
|
fill: "none",
|
|
1116
2113
|
stroke: tone,
|
|
@@ -1122,15 +2119,15 @@ function renderSparkline(el, opts) {
|
|
|
1122
2119
|
cx: last.x.toFixed(1),
|
|
1123
2120
|
cy: last.y.toFixed(1),
|
|
1124
2121
|
r: "2.4",
|
|
1125
|
-
fill: "var(--token-card)",
|
|
2122
|
+
fill: "var(--icen-token-card)",
|
|
1126
2123
|
stroke: tone,
|
|
1127
2124
|
"stroke-width": "1.6"
|
|
1128
2125
|
});
|
|
1129
2126
|
const title = svgEl("title", {});
|
|
1130
2127
|
title.textContent = fmt(opts, last.value);
|
|
1131
2128
|
dot.appendChild(title);
|
|
1132
|
-
|
|
1133
|
-
wrap.appendChild(
|
|
2129
|
+
svg.appendChild(dot);
|
|
2130
|
+
wrap.appendChild(svg);
|
|
1134
2131
|
body.appendChild(wrap);
|
|
1135
2132
|
});
|
|
1136
2133
|
attachChartInteraction(el, "sparkline");
|
|
@@ -1144,20 +2141,20 @@ function renderGauge(el, opts) {
|
|
|
1144
2141
|
const radius = 42;
|
|
1145
2142
|
const circumference = 2 * Math.PI * radius;
|
|
1146
2143
|
const wrap = document.createElement("div");
|
|
1147
|
-
wrap.className = "chart-gauge";
|
|
2144
|
+
wrap.className = "icen-chart-gauge";
|
|
1148
2145
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
2146
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.label, t("charts.type.gauge")) });
|
|
2147
|
+
svg.style.transform = "rotate(-90deg)";
|
|
2148
|
+
svg.appendChild(svgEl("circle", {
|
|
1152
2149
|
cx: "60",
|
|
1153
2150
|
cy: "60",
|
|
1154
2151
|
r: String(radius),
|
|
1155
2152
|
fill: "none",
|
|
1156
|
-
stroke: "var(--token-line-soft)",
|
|
2153
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1157
2154
|
"stroke-width": "10"
|
|
1158
2155
|
}));
|
|
1159
2156
|
const dash = ratio * circumference;
|
|
1160
|
-
|
|
2157
|
+
svg.appendChild(svgEl("circle", {
|
|
1161
2158
|
cx: "60",
|
|
1162
2159
|
cy: "60",
|
|
1163
2160
|
r: String(radius),
|
|
@@ -1168,18 +2165,18 @@ function renderGauge(el, opts) {
|
|
|
1168
2165
|
"stroke-linecap": "round"
|
|
1169
2166
|
}));
|
|
1170
2167
|
const center = document.createElement("div");
|
|
1171
|
-
center.className = "chart-gauge-center";
|
|
2168
|
+
center.className = "icen-chart-gauge-center";
|
|
1172
2169
|
const val = document.createElement("span");
|
|
1173
|
-
val.className = "chart-gauge-value";
|
|
2170
|
+
val.className = "icen-chart-gauge-value";
|
|
1174
2171
|
val.textContent = opts.formatValue ? opts.formatValue(opts.value) : `${Math.round(ratio * 100)}%`;
|
|
1175
2172
|
center.appendChild(val);
|
|
1176
2173
|
if (opts.label) {
|
|
1177
2174
|
const lab = document.createElement("span");
|
|
1178
|
-
lab.className = "chart-gauge-label";
|
|
2175
|
+
lab.className = "icen-chart-gauge-label";
|
|
1179
2176
|
lab.textContent = opts.label;
|
|
1180
2177
|
center.appendChild(lab);
|
|
1181
2178
|
}
|
|
1182
|
-
wrap.append(
|
|
2179
|
+
wrap.append(svg, center);
|
|
1183
2180
|
el.appendChild(wrap);
|
|
1184
2181
|
attachChartInteraction(el, "gauge");
|
|
1185
2182
|
return el;
|
|
@@ -1197,19 +2194,20 @@ function renderCalendar(el, opts) {
|
|
|
1197
2194
|
return;
|
|
1198
2195
|
}
|
|
1199
2196
|
const wrap = document.createElement("div");
|
|
1200
|
-
wrap.className = "chart-calendar";
|
|
2197
|
+
wrap.className = "icen-chart-calendar";
|
|
1201
2198
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1202
2199
|
const weekStart = opts.weekStart === 0 ? 0 : 1;
|
|
1203
|
-
const weekdayDefaults =
|
|
2200
|
+
const weekdayDefaults = t("charts.calendarWeekdays");
|
|
1204
2201
|
const weekdayLabels = opts.labels?.weekdays ?? weekdayDefaults.map((_, i) => weekdayLabelAt(weekdayDefaults, (weekStart + i) % 7));
|
|
1205
|
-
const monthLabel = (m) => opts.labels?.months?.[m] ??
|
|
2202
|
+
const monthLabel = (m) => opts.labels?.months?.[m] ?? t("charts.monthLabel", { p0: m + 1 });
|
|
1206
2203
|
const grid = document.createElement("div");
|
|
1207
|
-
grid.className = "chart-heatmap-grid";
|
|
2204
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1208
2205
|
grid.setAttribute("role", "img");
|
|
2206
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1209
2207
|
const months = document.createElement("div");
|
|
1210
|
-
months.className = "chart-calendar-months";
|
|
2208
|
+
months.className = "icen-chart-calendar-months";
|
|
1211
2209
|
const weekdayRow = document.createElement("div");
|
|
1212
|
-
weekdayRow.className = "chart-calendar-weekdays";
|
|
2210
|
+
weekdayRow.className = "icen-chart-calendar-weekdays";
|
|
1213
2211
|
weekdayLabels.forEach((w) => {
|
|
1214
2212
|
const s = document.createElement("span");
|
|
1215
2213
|
s.textContent = w;
|
|
@@ -1224,14 +2222,14 @@ function renderCalendar(el, opts) {
|
|
|
1224
2222
|
if (d.getMonth() !== lastMonth) {
|
|
1225
2223
|
lastMonth = d.getMonth();
|
|
1226
2224
|
const label = document.createElement("span");
|
|
1227
|
-
label.className = "chart-calendar-month";
|
|
2225
|
+
label.className = "icen-chart-calendar-month";
|
|
1228
2226
|
label.textContent = monthLabel(d.getMonth());
|
|
1229
2227
|
label.style.setProperty("--col", String(col));
|
|
1230
2228
|
months.appendChild(label);
|
|
1231
2229
|
}
|
|
1232
2230
|
const cell = document.createElement("span");
|
|
1233
|
-
cell.className = "chart-heatmap-cell";
|
|
1234
|
-
cell.dataset.
|
|
2231
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2232
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1235
2233
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1236
2234
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1237
2235
|
grid.appendChild(cell);
|
|
@@ -1253,7 +2251,7 @@ function renderScatter(el, opts) {
|
|
|
1253
2251
|
renderEmpty(body, opts.emptyLabel);
|
|
1254
2252
|
return;
|
|
1255
2253
|
}
|
|
1256
|
-
const width =
|
|
2254
|
+
const width = fluidWidth(body);
|
|
1257
2255
|
const height = 220;
|
|
1258
2256
|
const pad = 30;
|
|
1259
2257
|
let xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, sMax = 0;
|
|
@@ -1268,19 +2266,19 @@ function renderScatter(el, opts) {
|
|
|
1268
2266
|
if (yMax === yMin) yMax = yMin + 1;
|
|
1269
2267
|
const rOf = (size) => size && sMax > 0 ? 3 + size / sMax * 7 : 4;
|
|
1270
2268
|
const wrap = document.createElement("div");
|
|
1271
|
-
wrap.className = "chart-scatter";
|
|
2269
|
+
wrap.className = "icen-chart-scatter";
|
|
1272
2270
|
const tone = toneVar(opts.tone);
|
|
1273
|
-
const
|
|
2271
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.scatter")) });
|
|
1274
2272
|
const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
|
|
1275
2273
|
const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
|
|
1276
2274
|
for (let i = 0; i <= 3; i++) {
|
|
1277
2275
|
const y = pad + i * (height - pad * 2) / 3;
|
|
1278
|
-
|
|
2276
|
+
svg.appendChild(svgEl("line", {
|
|
1279
2277
|
x1: String(pad),
|
|
1280
2278
|
x2: String(width - pad),
|
|
1281
2279
|
y1: String(y),
|
|
1282
2280
|
y2: String(y),
|
|
1283
|
-
stroke: "var(--token-line-soft)",
|
|
2281
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1284
2282
|
"stroke-width": "1"
|
|
1285
2283
|
}));
|
|
1286
2284
|
const tv = yMin + (yMax - yMin) * (3 - i) / 3;
|
|
@@ -1289,19 +2287,19 @@ function renderScatter(el, opts) {
|
|
|
1289
2287
|
y: String(y + 3),
|
|
1290
2288
|
"text-anchor": "end",
|
|
1291
2289
|
"font-size": "8",
|
|
1292
|
-
fill: "var(--token-text-faint)"
|
|
2290
|
+
fill: "var(--icen-token-text-faint)"
|
|
1293
2291
|
});
|
|
1294
2292
|
txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
|
|
1295
|
-
|
|
2293
|
+
svg.appendChild(txt);
|
|
1296
2294
|
}
|
|
1297
2295
|
for (let i = 0; i <= 4; i++) {
|
|
1298
2296
|
const x = pad + i * (width - pad * 2) / 4;
|
|
1299
|
-
|
|
2297
|
+
svg.appendChild(svgEl("line", {
|
|
1300
2298
|
x1: String(x),
|
|
1301
2299
|
x2: String(x),
|
|
1302
2300
|
y1: String(pad),
|
|
1303
2301
|
y2: String(height - pad),
|
|
1304
|
-
stroke: "var(--token-line-soft)",
|
|
2302
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1305
2303
|
"stroke-width": "1",
|
|
1306
2304
|
"stroke-dasharray": "2 3"
|
|
1307
2305
|
}));
|
|
@@ -1311,20 +2309,20 @@ function renderScatter(el, opts) {
|
|
|
1311
2309
|
y: String(height - pad + 12),
|
|
1312
2310
|
"text-anchor": "middle",
|
|
1313
2311
|
"font-size": "8",
|
|
1314
|
-
fill: "var(--token-text-faint)"
|
|
2312
|
+
fill: "var(--icen-token-text-faint)"
|
|
1315
2313
|
});
|
|
1316
2314
|
txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
|
|
1317
|
-
|
|
2315
|
+
svg.appendChild(txt);
|
|
1318
2316
|
}
|
|
1319
2317
|
if (opts.yLabel) {
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
2318
|
+
const t2 = svgEl("text", { x: "10", y: String(pad - 10), "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2319
|
+
t2.textContent = opts.yLabel;
|
|
2320
|
+
svg.appendChild(t2);
|
|
1323
2321
|
}
|
|
1324
2322
|
if (opts.xLabel) {
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
|
|
2323
|
+
const t2 = svgEl("text", { x: String(width - pad), y: String(pad - 10), "text-anchor": "end", "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2324
|
+
t2.textContent = opts.xLabel;
|
|
2325
|
+
svg.appendChild(t2);
|
|
1328
2326
|
}
|
|
1329
2327
|
pts.forEach((p, i) => {
|
|
1330
2328
|
const c = svgEl("circle", {
|
|
@@ -1341,11 +2339,12 @@ function renderScatter(el, opts) {
|
|
|
1341
2339
|
c.appendChild(title);
|
|
1342
2340
|
setMarkData(c, { index: i, label: p.label ?? `#${i + 1}`, value: p.y });
|
|
1343
2341
|
c.dataset.chartX = String(p.x);
|
|
1344
|
-
|
|
2342
|
+
svg.appendChild(c);
|
|
1345
2343
|
});
|
|
1346
|
-
wrap.appendChild(
|
|
2344
|
+
wrap.appendChild(svg);
|
|
1347
2345
|
body.appendChild(wrap);
|
|
1348
2346
|
});
|
|
2347
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderScatter(el, opts));
|
|
1349
2348
|
attachChartInteraction(el, "scatter");
|
|
1350
2349
|
return el;
|
|
1351
2350
|
}
|
|
@@ -1395,7 +2394,7 @@ function pivotData(spec) {
|
|
|
1395
2394
|
const labels = [];
|
|
1396
2395
|
const seenLabel = /* @__PURE__ */ new Set();
|
|
1397
2396
|
const hasSeries = data.some((r) => r[seriesField] != null && r[seriesField] !== "");
|
|
1398
|
-
const seriesNames = [];
|
|
2397
|
+
const seriesNames = hasSeries ? [] : [""];
|
|
1399
2398
|
const seenSeries = /* @__PURE__ */ new Set();
|
|
1400
2399
|
for (const r of data) {
|
|
1401
2400
|
const l = str2(r[labelField]);
|
|
@@ -1484,8 +2483,8 @@ function normalizeChartSpec(raw) {
|
|
|
1484
2483
|
const s = src;
|
|
1485
2484
|
const spec = {};
|
|
1486
2485
|
if (typeof s.type === "string") {
|
|
1487
|
-
const
|
|
1488
|
-
spec.type = CHART_TYPE_ALIASES[
|
|
2486
|
+
const t2 = s.type.trim().toLowerCase();
|
|
2487
|
+
spec.type = CHART_TYPE_ALIASES[t2] ?? t2;
|
|
1489
2488
|
}
|
|
1490
2489
|
for (const k of ["title", "tone", "emptyLabel"]) {
|
|
1491
2490
|
if (typeof s[k] === "string") spec[k] = s[k];
|
|
@@ -1507,7 +2506,7 @@ function normalizeChartSpec(raw) {
|
|
|
1507
2506
|
if (Array.isArray(s.series)) {
|
|
1508
2507
|
const series = s.series.filter((v) => !!v && typeof v === "object").map((v, i) => {
|
|
1509
2508
|
const values = Array.isArray(v.values) ? v.values.map(toNum).filter((n) => n != null) : [];
|
|
1510
|
-
const sv = { name: String(v.name ??
|
|
2509
|
+
const sv = { name: String(v.name ?? t("charts.seriesName", { p0: i + 1 })), values };
|
|
1511
2510
|
const tone = v.tone;
|
|
1512
2511
|
if (typeof tone === "string" || typeof tone === "number") sv.tone = tone;
|
|
1513
2512
|
return sv;
|
|
@@ -1542,6 +2541,40 @@ function normalizeChartSpec(raw) {
|
|
|
1542
2541
|
}
|
|
1543
2542
|
spec.format = format;
|
|
1544
2543
|
}
|
|
2544
|
+
if (typeof s.downsample === "boolean") spec.downsample = s.downsample;
|
|
2545
|
+
else {
|
|
2546
|
+
const n = toNum(s.downsample);
|
|
2547
|
+
if (n != null) spec.downsample = n;
|
|
2548
|
+
}
|
|
2549
|
+
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2550
|
+
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2551
|
+
if (Array.isArray(s.marks)) {
|
|
2552
|
+
const marks = [];
|
|
2553
|
+
for (const raw2 of s.marks) {
|
|
2554
|
+
if (!raw2 || typeof raw2 !== "object" || Array.isArray(raw2)) continue;
|
|
2555
|
+
const m = raw2;
|
|
2556
|
+
if (m.type === "line") {
|
|
2557
|
+
if (m.axis !== "x" && m.axis !== "y") continue;
|
|
2558
|
+
if (typeof m.value !== "number" && typeof m.value !== "string") continue;
|
|
2559
|
+
const mark = { type: "line", axis: m.axis, value: m.value };
|
|
2560
|
+
if (typeof m.label === "string" && m.label !== "") mark.label = m.label;
|
|
2561
|
+
if (m.tone === "success" || m.tone === "warning" || m.tone === "error" || m.tone === "info") {
|
|
2562
|
+
mark.tone = m.tone;
|
|
2563
|
+
}
|
|
2564
|
+
marks.push(mark);
|
|
2565
|
+
} else if (m.type === "point") {
|
|
2566
|
+
if (typeof m.label !== "string" || m.label === "") continue;
|
|
2567
|
+
const mark = { type: "point", label: m.label };
|
|
2568
|
+
const si = toNum(m.seriesIndex);
|
|
2569
|
+
if (si != null && si >= 0) mark.seriesIndex = Math.floor(si);
|
|
2570
|
+
const v = toNum(m.value);
|
|
2571
|
+
if (v != null) mark.value = v;
|
|
2572
|
+
if (typeof m.text === "string") mark.text = m.text;
|
|
2573
|
+
marks.push(mark);
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
if (marks.length > 0) spec.marks = marks;
|
|
2577
|
+
}
|
|
1545
2578
|
const isDateRecords = spec.data?.length && spec.data[0] && "date" in spec.data[0];
|
|
1546
2579
|
if (spec.data && spec.data.length > 0 && !isDateRecords && !spec.series && !spec.points && !spec.values && !spec.segments) {
|
|
1547
2580
|
Object.assign(spec, pivotData(spec));
|
|
@@ -1581,6 +2614,391 @@ function inferChartType(spec) {
|
|
|
1581
2614
|
if (typeof spec.max === "number" && spec.values && spec.values.length === 1) return "gauge";
|
|
1582
2615
|
return "vbar";
|
|
1583
2616
|
}
|
|
2617
|
+
var DOWNSAMPLE_DEFAULT_THRESHOLD = 1e3;
|
|
2618
|
+
var CHART_ZOOM_DRAG_MIN_PX = 5;
|
|
2619
|
+
var CHART_LINE_W = 360;
|
|
2620
|
+
var CHART_LINE_H = 150;
|
|
2621
|
+
var CHART_LINE_PAD = 14;
|
|
2622
|
+
function isDownsampleableType(type) {
|
|
2623
|
+
return type === "line" || type === "area" || type === "scatter";
|
|
2624
|
+
}
|
|
2625
|
+
function isZoomableType(type) {
|
|
2626
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2627
|
+
}
|
|
2628
|
+
function isStreamableType(type) {
|
|
2629
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2630
|
+
}
|
|
2631
|
+
function downsampleView(view, type) {
|
|
2632
|
+
const raw = view.downsample;
|
|
2633
|
+
if (raw == null || raw === false) return { view, note: null };
|
|
2634
|
+
const threshold = raw === true ? DOWNSAMPLE_DEFAULT_THRESHOLD : Math.floor(raw);
|
|
2635
|
+
if (!Number.isFinite(threshold)) return { view, note: null };
|
|
2636
|
+
if (type === "scatter") {
|
|
2637
|
+
const pts = view.points ?? [];
|
|
2638
|
+
if (pts.length === 0) return { view, note: null };
|
|
2639
|
+
const sampled2 = lttb(pts, threshold, (p) => p.x, (p) => p.y);
|
|
2640
|
+
if (sampled2.length === pts.length) return { view, note: null };
|
|
2641
|
+
return { view: { ...view, points: sampled2 }, note: t("charts.sampled", { p0: pts.length, p1: sampled2.length }) };
|
|
2642
|
+
}
|
|
2643
|
+
const labels = view.labels ?? [];
|
|
2644
|
+
if (labels.length === 0) return { view, note: null };
|
|
2645
|
+
const guide = view.series && view.series.length > 0 ? view.series[0]?.values ?? [] : view.values ?? [];
|
|
2646
|
+
const count = Math.min(labels.length, guide.length);
|
|
2647
|
+
if (count === 0) return { view, note: null };
|
|
2648
|
+
const indexed = guide.slice(0, count).map((v, i) => ({ i, v }));
|
|
2649
|
+
const sampled = lttb(indexed, threshold, (p) => p.i, (p) => p.v);
|
|
2650
|
+
if (sampled.length >= count) return { view, note: null };
|
|
2651
|
+
const idx = sampled.map((p) => p.i);
|
|
2652
|
+
return {
|
|
2653
|
+
view: {
|
|
2654
|
+
...view,
|
|
2655
|
+
labels: idx.map((i) => labels[i] ?? ""),
|
|
2656
|
+
values: view.values ? idx.map((i) => view.values?.[i] ?? 0) : void 0,
|
|
2657
|
+
series: view.series?.map((s) => ({ ...s, values: idx.map((i) => s.values[i] ?? 0) }))
|
|
2658
|
+
},
|
|
2659
|
+
note: t("charts.sampled", { p0: count, p1: idx.length })
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
function renderChartSkeleton(body) {
|
|
2663
|
+
const box = document.createElement("div");
|
|
2664
|
+
box.className = "icen-chart-skeleton";
|
|
2665
|
+
box.setAttribute("role", "status");
|
|
2666
|
+
box.setAttribute("aria-busy", "true");
|
|
2667
|
+
box.setAttribute("aria-label", t("charts.loading"));
|
|
2668
|
+
const widths = [100, 84, 92, 68, 76, 52];
|
|
2669
|
+
for (const w of widths) {
|
|
2670
|
+
const bar = document.createElement("div");
|
|
2671
|
+
bar.className = "icen-chart-skeleton-bar";
|
|
2672
|
+
bar.style.width = `${w}%`;
|
|
2673
|
+
box.appendChild(bar);
|
|
2674
|
+
}
|
|
2675
|
+
body.appendChild(box);
|
|
2676
|
+
}
|
|
2677
|
+
var CHART_MARK_ACCENT = "var(--icen-token-accent)";
|
|
2678
|
+
function markToneVar(tone) {
|
|
2679
|
+
switch (tone) {
|
|
2680
|
+
case "success":
|
|
2681
|
+
return "var(--icen-token-success)";
|
|
2682
|
+
case "warning":
|
|
2683
|
+
return "var(--icen-token-warning)";
|
|
2684
|
+
case "error":
|
|
2685
|
+
return "var(--icen-token-error)";
|
|
2686
|
+
case "info":
|
|
2687
|
+
return "var(--icen-token-info)";
|
|
2688
|
+
default:
|
|
2689
|
+
return "var(--icen-token-text-faint)";
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
function markWarnOnce(warned, mark, reason) {
|
|
2693
|
+
const key = JSON.stringify(mark);
|
|
2694
|
+
if (warned.has(key)) return;
|
|
2695
|
+
warned.add(key);
|
|
2696
|
+
console.warn(`[icen:chart] \u65E0\u6548\u6807\u8BB0\u5DF2\u8DF3\u8FC7\uFF08${reason}\uFF09`, mark);
|
|
2697
|
+
}
|
|
2698
|
+
function paintChartMarks(root, view, spec, formatValue, warned) {
|
|
2699
|
+
const marks = spec.marks;
|
|
2700
|
+
if (!marks || marks.length === 0) return;
|
|
2701
|
+
const type = spec.type;
|
|
2702
|
+
if (type === "line" || type === "area") paintSvgChartMarks(root, view, marks, formatValue, warned);
|
|
2703
|
+
else if (type === "vbar") paintVBarChartMarks(root, view, spec, marks, formatValue, warned);
|
|
2704
|
+
}
|
|
2705
|
+
function paintSvgChartMarks(root, view, marks, formatValue, warned) {
|
|
2706
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
2707
|
+
if (!svg) return;
|
|
2708
|
+
const labels = view.labels ?? [];
|
|
2709
|
+
const n = labels.length;
|
|
2710
|
+
if (n === 0) return;
|
|
2711
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2712
|
+
let max = 1;
|
|
2713
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2714
|
+
const dims = svgDimsOf(svg);
|
|
2715
|
+
const W = dims.w;
|
|
2716
|
+
const H = dims.h;
|
|
2717
|
+
const PAD = CHART_LINE_PAD;
|
|
2718
|
+
const xAt = (i) => n <= 1 ? W / 2 : PAD + i / (n - 1) * (W - PAD * 2);
|
|
2719
|
+
const yAt = (v) => H - PAD - Math.max(0, v) / max * (H - PAD * 2);
|
|
2720
|
+
for (const mark of marks) {
|
|
2721
|
+
if (mark.type === "line") {
|
|
2722
|
+
const color = markToneVar(mark.tone);
|
|
2723
|
+
if (mark.axis === "y") {
|
|
2724
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2725
|
+
if (!Number.isFinite(v)) {
|
|
2726
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2727
|
+
continue;
|
|
2728
|
+
}
|
|
2729
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2730
|
+
svg.appendChild(svgEl("line", {
|
|
2731
|
+
class: "icen-chart-mark-line",
|
|
2732
|
+
x1: String(PAD),
|
|
2733
|
+
x2: String(W - PAD),
|
|
2734
|
+
y1: y.toFixed(1),
|
|
2735
|
+
y2: y.toFixed(1),
|
|
2736
|
+
stroke: color,
|
|
2737
|
+
"stroke-width": "1",
|
|
2738
|
+
"stroke-dasharray": "4 3"
|
|
2739
|
+
}));
|
|
2740
|
+
const label = svgEl("text", {
|
|
2741
|
+
class: "icen-chart-mark-label",
|
|
2742
|
+
x: String(W - PAD),
|
|
2743
|
+
y: String(clampNum(y - 4, 8, CHART_LINE_H - 4)),
|
|
2744
|
+
"text-anchor": "end",
|
|
2745
|
+
"font-size": "8",
|
|
2746
|
+
fill: color
|
|
2747
|
+
});
|
|
2748
|
+
label.textContent = mark.label ?? formatValue(v);
|
|
2749
|
+
svg.appendChild(label);
|
|
2750
|
+
} else {
|
|
2751
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2752
|
+
if (idx < 0 || idx >= n) {
|
|
2753
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2754
|
+
continue;
|
|
2755
|
+
}
|
|
2756
|
+
const x = xAt(idx);
|
|
2757
|
+
svg.appendChild(svgEl("line", {
|
|
2758
|
+
class: "icen-chart-mark-line",
|
|
2759
|
+
x1: x.toFixed(1),
|
|
2760
|
+
x2: x.toFixed(1),
|
|
2761
|
+
y1: String(PAD),
|
|
2762
|
+
y2: String(H - PAD),
|
|
2763
|
+
stroke: color,
|
|
2764
|
+
"stroke-width": "1",
|
|
2765
|
+
"stroke-dasharray": "4 3"
|
|
2766
|
+
}));
|
|
2767
|
+
const label = svgEl("text", {
|
|
2768
|
+
class: "icen-chart-mark-label",
|
|
2769
|
+
x: String(clampNum(x, 10, W - 10)),
|
|
2770
|
+
y: String(PAD + 8),
|
|
2771
|
+
"text-anchor": "middle",
|
|
2772
|
+
"font-size": "8",
|
|
2773
|
+
fill: color
|
|
2774
|
+
});
|
|
2775
|
+
label.textContent = mark.label ?? labels[idx] ?? "";
|
|
2776
|
+
svg.appendChild(label);
|
|
2777
|
+
}
|
|
2778
|
+
} else {
|
|
2779
|
+
const idx = labels.indexOf(mark.label);
|
|
2780
|
+
if (idx < 0 || idx >= n) {
|
|
2781
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2782
|
+
continue;
|
|
2783
|
+
}
|
|
2784
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2785
|
+
const s = seriesList[si];
|
|
2786
|
+
if (!s) {
|
|
2787
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2788
|
+
continue;
|
|
2789
|
+
}
|
|
2790
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2791
|
+
if (!Number.isFinite(v)) {
|
|
2792
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
const x = xAt(idx);
|
|
2796
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2797
|
+
const g = svgEl("g", { class: "icen-chart-mark-point" });
|
|
2798
|
+
g.appendChild(svgEl("circle", {
|
|
2799
|
+
cx: x.toFixed(1),
|
|
2800
|
+
cy: y.toFixed(1),
|
|
2801
|
+
r: "6",
|
|
2802
|
+
fill: "none",
|
|
2803
|
+
stroke: CHART_MARK_ACCENT,
|
|
2804
|
+
"stroke-width": "1.5"
|
|
2805
|
+
}));
|
|
2806
|
+
g.appendChild(svgEl("circle", { cx: x.toFixed(1), cy: y.toFixed(1), r: "2", fill: CHART_MARK_ACCENT }));
|
|
2807
|
+
const label = svgEl("text", {
|
|
2808
|
+
class: "icen-chart-mark-label",
|
|
2809
|
+
x: String(clampNum(x, 12, W - 12)),
|
|
2810
|
+
y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
|
|
2811
|
+
"text-anchor": "middle",
|
|
2812
|
+
"font-size": "8",
|
|
2813
|
+
fill: CHART_MARK_ACCENT
|
|
2814
|
+
});
|
|
2815
|
+
label.textContent = mark.text ?? mark.label;
|
|
2816
|
+
g.appendChild(label);
|
|
2817
|
+
svg.appendChild(g);
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
2822
|
+
const wrap = root.querySelector(".icen-chart-vbar");
|
|
2823
|
+
if (!wrap) return;
|
|
2824
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2825
|
+
const labels = view.labels ?? [];
|
|
2826
|
+
const n = Math.min(labels.length, ...seriesList.map((s) => s.values.length));
|
|
2827
|
+
if (n === 0 || seriesList.length === 0) return;
|
|
2828
|
+
const multi = seriesList.length > 1;
|
|
2829
|
+
let max = 1;
|
|
2830
|
+
if (spec.stacked && multi) {
|
|
2831
|
+
for (let i = 0; i < n; i++) {
|
|
2832
|
+
let sum2 = 0;
|
|
2833
|
+
for (const s of seriesList) sum2 += Math.max(0, s.values[i] ?? 0);
|
|
2834
|
+
if (sum2 > max) max = sum2;
|
|
2835
|
+
}
|
|
2836
|
+
} else {
|
|
2837
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2838
|
+
}
|
|
2839
|
+
const centerPct = (i) => (i + 0.5) / n * 100;
|
|
2840
|
+
for (const mark of marks) {
|
|
2841
|
+
if (mark.type === "line") {
|
|
2842
|
+
if (mark.axis === "y") {
|
|
2843
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2844
|
+
if (!Number.isFinite(v)) {
|
|
2845
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2846
|
+
continue;
|
|
2847
|
+
}
|
|
2848
|
+
const line = document.createElement("div");
|
|
2849
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--h";
|
|
2850
|
+
line.style.top = `${(clampNum(1 - Math.max(0, v) / max, 0.02, 0.98) * 100).toFixed(2)}%`;
|
|
2851
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2852
|
+
const lab = document.createElement("span");
|
|
2853
|
+
lab.className = "icen-chart-mark-label";
|
|
2854
|
+
lab.textContent = mark.label ?? formatValue(v);
|
|
2855
|
+
line.appendChild(lab);
|
|
2856
|
+
wrap.appendChild(line);
|
|
2857
|
+
} else {
|
|
2858
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2859
|
+
if (idx < 0 || idx >= n) {
|
|
2860
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2861
|
+
continue;
|
|
2862
|
+
}
|
|
2863
|
+
const line = document.createElement("div");
|
|
2864
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--v";
|
|
2865
|
+
line.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2866
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2867
|
+
const lab = document.createElement("span");
|
|
2868
|
+
lab.className = "icen-chart-mark-label";
|
|
2869
|
+
lab.textContent = mark.label ?? labels[idx] ?? "";
|
|
2870
|
+
line.appendChild(lab);
|
|
2871
|
+
wrap.appendChild(line);
|
|
2872
|
+
}
|
|
2873
|
+
} else {
|
|
2874
|
+
const idx = labels.indexOf(mark.label);
|
|
2875
|
+
if (idx < 0 || idx >= n) {
|
|
2876
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2877
|
+
continue;
|
|
2878
|
+
}
|
|
2879
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2880
|
+
const s = seriesList[si];
|
|
2881
|
+
if (!s) {
|
|
2882
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2883
|
+
continue;
|
|
2884
|
+
}
|
|
2885
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2886
|
+
if (!Number.isFinite(v)) {
|
|
2887
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2888
|
+
continue;
|
|
2889
|
+
}
|
|
2890
|
+
const dot = document.createElement("div");
|
|
2891
|
+
dot.className = "icen-chart-mark-point";
|
|
2892
|
+
dot.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2893
|
+
dot.style.bottom = `${(clampNum(Math.max(0, v) / max, 0, 1) * 100).toFixed(2)}%`;
|
|
2894
|
+
const lab = document.createElement("span");
|
|
2895
|
+
lab.className = "icen-chart-mark-label";
|
|
2896
|
+
lab.textContent = mark.text ?? mark.label;
|
|
2897
|
+
dot.appendChild(lab);
|
|
2898
|
+
wrap.appendChild(dot);
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
function chartAriaLabel(title, typeName) {
|
|
2903
|
+
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2904
|
+
}
|
|
2905
|
+
function svgDimsOf(svg) {
|
|
2906
|
+
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2907
|
+
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
2908
|
+
const h2 = Number.isFinite(vb[3]) && (vb[3] ?? 0) > 0 ? vb[3] : CHART_LINE_H;
|
|
2909
|
+
return { w, h: h2 };
|
|
2910
|
+
}
|
|
2911
|
+
var fluidObservers = /* @__PURE__ */ new WeakMap();
|
|
2912
|
+
function fluidWidth(host) {
|
|
2913
|
+
const w = Math.round(host.getBoundingClientRect().width);
|
|
2914
|
+
return w > 0 ? Math.max(29, w) : 360;
|
|
2915
|
+
}
|
|
2916
|
+
function observeFluidWidth(el, rerender) {
|
|
2917
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2918
|
+
fluidObservers.get(el)?.disconnect();
|
|
2919
|
+
let last = Math.round(el.getBoundingClientRect().width);
|
|
2920
|
+
const ro = new ResizeObserver(() => {
|
|
2921
|
+
if (!el.isConnected) {
|
|
2922
|
+
ro.disconnect();
|
|
2923
|
+
fluidObservers.delete(el);
|
|
2924
|
+
return;
|
|
2925
|
+
}
|
|
2926
|
+
const w = Math.round(el.getBoundingClientRect().width);
|
|
2927
|
+
if (Math.abs(w - last) < 2) return;
|
|
2928
|
+
last = w;
|
|
2929
|
+
rerender();
|
|
2930
|
+
});
|
|
2931
|
+
ro.observe(el);
|
|
2932
|
+
fluidObservers.set(el, ro);
|
|
2933
|
+
}
|
|
2934
|
+
function releaseFluidWidth(el) {
|
|
2935
|
+
fluidObservers.get(el)?.disconnect();
|
|
2936
|
+
fluidObservers.delete(el);
|
|
2937
|
+
}
|
|
2938
|
+
function createChartToDataURL(root) {
|
|
2939
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2940
|
+
return (opts) => {
|
|
2941
|
+
if (typeof document === "undefined") return void 0;
|
|
2942
|
+
const scale = clampNum(toNum(opts?.scale) ?? 2, 0.5, 4);
|
|
2943
|
+
const svgs = Array.from(root.querySelectorAll("svg"));
|
|
2944
|
+
if (svgs.length === 0) return void 0;
|
|
2945
|
+
const parts = [];
|
|
2946
|
+
for (const svg of svgs) {
|
|
2947
|
+
const { w, h: h2 } = svgDimsOf(svg);
|
|
2948
|
+
const clone = svg.cloneNode(true);
|
|
2949
|
+
clone.setAttribute("xmlns", SVG_NS);
|
|
2950
|
+
clone.setAttribute("width", String(w));
|
|
2951
|
+
clone.setAttribute("height", String(h2));
|
|
2952
|
+
let str2;
|
|
2953
|
+
try {
|
|
2954
|
+
str2 = new XMLSerializer().serializeToString(clone);
|
|
2955
|
+
} catch {
|
|
2956
|
+
return void 0;
|
|
2957
|
+
}
|
|
2958
|
+
parts.push({ src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(str2)}`, w, h: h2 });
|
|
2959
|
+
}
|
|
2960
|
+
const key = `${scale}|${parts.map((p) => p.src).join("")}`;
|
|
2961
|
+
const hit = cache.get(key);
|
|
2962
|
+
if (hit) return hit;
|
|
2963
|
+
const canvas = document.createElement("canvas");
|
|
2964
|
+
let ctx = null;
|
|
2965
|
+
try {
|
|
2966
|
+
ctx = canvas.getContext("2d");
|
|
2967
|
+
} catch {
|
|
2968
|
+
return void 0;
|
|
2969
|
+
}
|
|
2970
|
+
if (!ctx) return void 0;
|
|
2971
|
+
const context = ctx;
|
|
2972
|
+
const totalW = Math.max(...parts.map((p) => p.w));
|
|
2973
|
+
const totalH = parts.reduce((sum2, p) => sum2 + p.h, 0);
|
|
2974
|
+
canvas.width = Math.max(1, Math.round(totalW * scale));
|
|
2975
|
+
canvas.height = Math.max(1, Math.round(totalH * scale));
|
|
2976
|
+
let loaded = 0;
|
|
2977
|
+
let failed = false;
|
|
2978
|
+
let offsetY = 0;
|
|
2979
|
+
for (const part of parts) {
|
|
2980
|
+
const dy = offsetY;
|
|
2981
|
+
offsetY += part.h;
|
|
2982
|
+
const img = new Image();
|
|
2983
|
+
img.onload = () => {
|
|
2984
|
+
if (failed) return;
|
|
2985
|
+
context.drawImage(img, 0, dy * scale, part.w * scale, part.h * scale);
|
|
2986
|
+
loaded += 1;
|
|
2987
|
+
if (loaded === parts.length) {
|
|
2988
|
+
try {
|
|
2989
|
+
cache.set(key, canvas.toDataURL("image/png"));
|
|
2990
|
+
} catch {
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
};
|
|
2994
|
+
img.onerror = () => {
|
|
2995
|
+
failed = true;
|
|
2996
|
+
};
|
|
2997
|
+
img.src = part.src;
|
|
2998
|
+
}
|
|
2999
|
+
return cache.get(key);
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
1584
3002
|
function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
1585
3003
|
const read = (name) => mark.getAttribute(name) ?? void 0;
|
|
1586
3004
|
const numOr = (v) => v == null ? void 0 : Number(v);
|
|
@@ -1588,11 +3006,11 @@ function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
|
1588
3006
|
type,
|
|
1589
3007
|
phase,
|
|
1590
3008
|
chart,
|
|
1591
|
-
index: numOr(read("data-chart-index")),
|
|
1592
|
-
seriesIndex: numOr(read("data-chart-series")),
|
|
1593
|
-
seriesName: read("data-chart-series-name"),
|
|
1594
|
-
label: read("data-chart-label"),
|
|
1595
|
-
value: numOr(read("data-chart-value")),
|
|
3009
|
+
index: numOr(read("data-icen-chart-index")),
|
|
3010
|
+
seriesIndex: numOr(read("data-icen-chart-series")),
|
|
3011
|
+
seriesName: read("data-icen-chart-series-name"),
|
|
3012
|
+
label: read("data-icen-chart-label"),
|
|
3013
|
+
value: numOr(read("data-icen-chart-value")),
|
|
1596
3014
|
target: mark,
|
|
1597
3015
|
pointerX: pointer?.x,
|
|
1598
3016
|
pointerY: pointer?.y
|
|
@@ -1603,7 +3021,7 @@ var tooltipEl = null;
|
|
|
1603
3021
|
function chartTooltip() {
|
|
1604
3022
|
if (!tooltipEl) {
|
|
1605
3023
|
tooltipEl = document.createElement("div");
|
|
1606
|
-
tooltipEl.className = "chart-tooltip";
|
|
3024
|
+
tooltipEl.className = "icen-chart-tooltip";
|
|
1607
3025
|
tooltipEl.setAttribute("role", "tooltip");
|
|
1608
3026
|
tooltipEl.hidden = true;
|
|
1609
3027
|
document.body.appendChild(tooltipEl);
|
|
@@ -1612,14 +3030,14 @@ function chartTooltip() {
|
|
|
1612
3030
|
}
|
|
1613
3031
|
function applyTooltipSizing(host) {
|
|
1614
3032
|
const tip = chartTooltip();
|
|
1615
|
-
const raw = host?.closest(".chart, [data-chart-root]")?.getAttribute("data-panel-max") ?? null;
|
|
3033
|
+
const raw = host?.closest(".icen-chart, [data-icen-chart-root]")?.getAttribute("data-icen-panel-max") ?? null;
|
|
1616
3034
|
const n = raw != null ? Number(raw) : NaN;
|
|
1617
3035
|
tip.style.maxWidth = Number.isFinite(n) && n > 0 ? `${n}px` : "";
|
|
1618
3036
|
}
|
|
1619
3037
|
function tooltipText(mark) {
|
|
1620
|
-
const label = mark.getAttribute("data-chart-label") ?? "";
|
|
1621
|
-
const series = mark.getAttribute("data-chart-series-name");
|
|
1622
|
-
const value = mark.getAttribute("data-chart-value");
|
|
3038
|
+
const label = mark.getAttribute("data-icen-chart-label") ?? "";
|
|
3039
|
+
const series = mark.getAttribute("data-icen-chart-series-name");
|
|
3040
|
+
const value = mark.getAttribute("data-icen-chart-value");
|
|
1623
3041
|
const head = series ? label ? `${series} \xB7 ${label}` : series : label;
|
|
1624
3042
|
return value != null ? `${head}\uFF1A${value}` : head;
|
|
1625
3043
|
}
|
|
@@ -1651,8 +3069,8 @@ function bindChartEvents(root) {
|
|
|
1651
3069
|
const typeNow = () => chartDelegateMeta.get(root)?.type() ?? "vbar";
|
|
1652
3070
|
const tipEnabled = () => chartDelegateMeta.get(root)?.tooltip() ?? true;
|
|
1653
3071
|
const markOf = (e) => {
|
|
1654
|
-
const
|
|
1655
|
-
return
|
|
3072
|
+
const t2 = e.target;
|
|
3073
|
+
return t2 instanceof Element ? t2.closest("[data-icen-chart-mark]") : null;
|
|
1656
3074
|
};
|
|
1657
3075
|
let hoverMark = null;
|
|
1658
3076
|
const enterMark = (mark, x, y) => {
|
|
@@ -1749,70 +3167,277 @@ function hasLegendOf(spec) {
|
|
|
1749
3167
|
function renderChart(el, raw) {
|
|
1750
3168
|
const noop = () => void 0;
|
|
1751
3169
|
if (typeof document === "undefined") {
|
|
1752
|
-
return {
|
|
3170
|
+
return {
|
|
3171
|
+
el,
|
|
3172
|
+
spec: {},
|
|
3173
|
+
update: noop,
|
|
3174
|
+
append: noop,
|
|
3175
|
+
toDataURL: () => void 0,
|
|
3176
|
+
on: () => noop,
|
|
3177
|
+
destroy: noop
|
|
3178
|
+
};
|
|
1753
3179
|
}
|
|
1754
3180
|
const root = el;
|
|
1755
|
-
let
|
|
1756
|
-
const typeOf = () =>
|
|
3181
|
+
let current2 = normalizeChartSpec(raw);
|
|
3182
|
+
const typeOf = () => current2.type ?? "vbar";
|
|
1757
3183
|
const legendState = { hidden: null };
|
|
3184
|
+
let zoomWindow = null;
|
|
3185
|
+
const warnedMarks = /* @__PURE__ */ new Set();
|
|
3186
|
+
let warnedAppend = false;
|
|
3187
|
+
let zoomDragCleanup = null;
|
|
3188
|
+
const fullLength = () => {
|
|
3189
|
+
if (current2.type === "scatter") return current2.points?.length ?? 0;
|
|
3190
|
+
if (current2.series && current2.series.length > 0) {
|
|
3191
|
+
return Math.max(current2.labels?.length ?? 0, ...current2.series.map((s) => s.values.length));
|
|
3192
|
+
}
|
|
3193
|
+
return Math.max(current2.labels?.length ?? 0, current2.values?.length ?? 0);
|
|
3194
|
+
};
|
|
3195
|
+
const viewOf = () => {
|
|
3196
|
+
if (!zoomWindow) return current2;
|
|
3197
|
+
const { from, to } = zoomWindow;
|
|
3198
|
+
return {
|
|
3199
|
+
...current2,
|
|
3200
|
+
labels: current2.labels?.slice(from, to + 1),
|
|
3201
|
+
values: current2.values?.slice(from, to + 1),
|
|
3202
|
+
series: current2.series?.map((s) => ({ ...s, values: s.values.slice(from, to + 1) })),
|
|
3203
|
+
points: current2.points?.slice(from, to + 1)
|
|
3204
|
+
};
|
|
3205
|
+
};
|
|
3206
|
+
const applyZoomSelection = (x0, x1) => {
|
|
3207
|
+
const len = fullLength();
|
|
3208
|
+
if (len < 2) return;
|
|
3209
|
+
const base = zoomWindow?.from ?? 0;
|
|
3210
|
+
const viewLen = zoomWindow ? zoomWindow.to - zoomWindow.from + 1 : len;
|
|
3211
|
+
const lo = Math.min(x0, x1);
|
|
3212
|
+
const hi = Math.max(x0, x1);
|
|
3213
|
+
let i0;
|
|
3214
|
+
let i1;
|
|
3215
|
+
const vbar = root.querySelector(".icen-chart-vbar");
|
|
3216
|
+
if (vbar) {
|
|
3217
|
+
const rect = vbar.getBoundingClientRect();
|
|
3218
|
+
const rel0 = rect.width > 0 ? Math.floor((lo - rect.left) / rect.width * viewLen) : 0;
|
|
3219
|
+
const rel1 = rect.width > 0 ? Math.max(rel0, Math.floor((hi - rect.left) / rect.width * viewLen)) : viewLen - 1;
|
|
3220
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3221
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3222
|
+
} else {
|
|
3223
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3224
|
+
if (!svg) return;
|
|
3225
|
+
const dims = svgDimsOf(svg);
|
|
3226
|
+
const p0 = svgClientPoint(svg, lo, 0, dims.w, dims.h);
|
|
3227
|
+
const p1 = svgClientPoint(svg, hi, 0, dims.w, dims.h);
|
|
3228
|
+
const rel0 = Math.round((p0.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3229
|
+
const rel1 = Math.round((p1.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3230
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3231
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3232
|
+
}
|
|
3233
|
+
if (i0 > i1) [i0, i1] = [i1, i0];
|
|
3234
|
+
if (i0 <= 0 && i1 >= len - 1) zoomWindow = null;
|
|
3235
|
+
else zoomWindow = { from: i0, to: Math.max(i1, i0) };
|
|
3236
|
+
render();
|
|
3237
|
+
emitIcen(root, "icen:chart-zoom", { chart: String(current2.type ?? ""), from: i0, to: Math.max(i1, i0) });
|
|
3238
|
+
};
|
|
3239
|
+
const bindZoomGesture = () => {
|
|
3240
|
+
if (current2.zoom !== "x" && current2.zoom !== "brush") return;
|
|
3241
|
+
const t2 = typeOf();
|
|
3242
|
+
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
3243
|
+
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
3244
|
+
if (!plot) return;
|
|
3245
|
+
const on = (type, fn) => {
|
|
3246
|
+
plot.addEventListener(type, fn);
|
|
3247
|
+
};
|
|
3248
|
+
let drag = null;
|
|
3249
|
+
const onMove = (e) => {
|
|
3250
|
+
if (!drag) return;
|
|
3251
|
+
drag.x1 = e.clientX;
|
|
3252
|
+
drag.y1 = e.clientY;
|
|
3253
|
+
if (!drag.active && Math.hypot(drag.x1 - drag.x0, drag.y1 - drag.y0) >= CHART_ZOOM_DRAG_MIN_PX) {
|
|
3254
|
+
drag.active = true;
|
|
3255
|
+
const rect = document.createElement("div");
|
|
3256
|
+
rect.className = "icen-chart-zoom-rect";
|
|
3257
|
+
document.body.appendChild(rect);
|
|
3258
|
+
drag.rect = rect;
|
|
3259
|
+
}
|
|
3260
|
+
if (drag.active && drag.rect) {
|
|
3261
|
+
drag.rect.style.left = `${Math.round(Math.min(drag.x0, drag.x1))}px`;
|
|
3262
|
+
drag.rect.style.width = `${Math.round(Math.abs(drag.x1 - drag.x0))}px`;
|
|
3263
|
+
if (current2.zoom === "brush") {
|
|
3264
|
+
drag.rect.style.top = `${Math.round(Math.min(drag.y0, drag.y1))}px`;
|
|
3265
|
+
drag.rect.style.height = `${Math.round(Math.abs(drag.y1 - drag.y0))}px`;
|
|
3266
|
+
} else {
|
|
3267
|
+
const pr = plot.getBoundingClientRect();
|
|
3268
|
+
drag.rect.style.top = `${Math.round(pr.top)}px`;
|
|
3269
|
+
drag.rect.style.height = `${Math.round(pr.height)}px`;
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
};
|
|
3273
|
+
const onUp = () => {
|
|
3274
|
+
window.removeEventListener("pointermove", onMove);
|
|
3275
|
+
window.removeEventListener("pointerup", onUp);
|
|
3276
|
+
window.removeEventListener("pointercancel", onUp);
|
|
3277
|
+
zoomDragCleanup = null;
|
|
3278
|
+
if (!drag) return;
|
|
3279
|
+
const d = drag;
|
|
3280
|
+
drag = null;
|
|
3281
|
+
d.rect?.remove();
|
|
3282
|
+
if (!d.active) return;
|
|
3283
|
+
applyZoomSelection(d.x0, d.x1);
|
|
3284
|
+
};
|
|
3285
|
+
const onDown = (e) => {
|
|
3286
|
+
if (e.button !== 0) return;
|
|
3287
|
+
drag = { x0: e.clientX, y0: e.clientY, x1: e.clientX, y1: e.clientY, active: false, rect: null };
|
|
3288
|
+
window.addEventListener("pointermove", onMove);
|
|
3289
|
+
window.addEventListener("pointerup", onUp);
|
|
3290
|
+
window.addEventListener("pointercancel", onUp);
|
|
3291
|
+
zoomDragCleanup = onUp;
|
|
3292
|
+
};
|
|
3293
|
+
on("pointerdown", onDown);
|
|
3294
|
+
on("dblclick", () => {
|
|
3295
|
+
if (!zoomWindow) return;
|
|
3296
|
+
zoomWindow = null;
|
|
3297
|
+
render();
|
|
3298
|
+
});
|
|
3299
|
+
};
|
|
1758
3300
|
const render = () => {
|
|
1759
|
-
if (!
|
|
1760
|
-
const spec =
|
|
3301
|
+
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
3302
|
+
const spec = current2;
|
|
3303
|
+
const type = spec.type;
|
|
1761
3304
|
const formatValue = chartFormatValue(spec.format);
|
|
1762
3305
|
if (spec.legend !== void 0) legendState.hidden = spec.legend === false;
|
|
3306
|
+
const loading = spec.loading === true;
|
|
3307
|
+
root.classList.toggle("is-loading", loading);
|
|
3308
|
+
let view = viewOf();
|
|
3309
|
+
let note = null;
|
|
3310
|
+
if (!loading && isDownsampleableType(type)) {
|
|
3311
|
+
const r = downsampleView(view, type);
|
|
3312
|
+
view = r.view;
|
|
3313
|
+
note = r.note;
|
|
3314
|
+
}
|
|
3315
|
+
const zoomReset = zoomWindow && (spec.zoom === "x" || spec.zoom === "brush") ? () => {
|
|
3316
|
+
zoomWindow = null;
|
|
3317
|
+
render();
|
|
3318
|
+
} : null;
|
|
1763
3319
|
withChrome(root, spec, hasLegendOf(spec), (body) => {
|
|
1764
|
-
|
|
3320
|
+
if (loading) {
|
|
3321
|
+
renderChartSkeleton(body);
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3324
|
+
switch (type) {
|
|
1765
3325
|
case "line":
|
|
1766
|
-
renderLine(body, { labels:
|
|
3326
|
+
renderLine(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, tone: view.tone, fill: view.fill, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1767
3327
|
break;
|
|
1768
3328
|
case "area":
|
|
1769
|
-
renderLine(body, { labels:
|
|
3329
|
+
renderLine(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, tone: view.tone, fill: true, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1770
3330
|
break;
|
|
1771
3331
|
case "vbar":
|
|
1772
|
-
renderVBar(body, { labels:
|
|
3332
|
+
renderVBar(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, stacked: view.stacked, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1773
3333
|
break;
|
|
1774
3334
|
case "hbar":
|
|
1775
|
-
renderHBar(body, { labels:
|
|
3335
|
+
renderHBar(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1776
3336
|
break;
|
|
1777
3337
|
case "stack":
|
|
1778
|
-
renderStack(body, { segments:
|
|
3338
|
+
renderStack(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1779
3339
|
break;
|
|
1780
3340
|
case "donut":
|
|
1781
|
-
renderDonut(body, { segments:
|
|
3341
|
+
renderDonut(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1782
3342
|
break;
|
|
1783
3343
|
case "radar": {
|
|
1784
|
-
const series =
|
|
1785
|
-
renderRadar(body, { axes:
|
|
3344
|
+
const series = view.series ? view.series.map((s) => ({ name: s.name, values: s.values, tone: typeof s.tone === "string" ? s.tone : void 0 })) : view.values ? [{ name: "", values: view.values }] : [];
|
|
3345
|
+
renderRadar(body, { axes: view.axes ?? view.labels ?? [], series, max: view.max, levels: view.levels, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1786
3346
|
break;
|
|
1787
3347
|
}
|
|
1788
3348
|
case "heatmap":
|
|
1789
|
-
renderHeatmap(body, { values:
|
|
3349
|
+
renderHeatmap(body, { values: view.values, data: view.data, weeks: view.weeks, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend, weekStart: view.i18n?.weekStart, labels: view.i18n });
|
|
1790
3350
|
break;
|
|
1791
3351
|
case "calendar":
|
|
1792
|
-
renderCalendar(body, { dates:
|
|
3352
|
+
renderCalendar(body, { dates: view.dates, values: view.values, data: view.data, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend, weekStart: view.i18n?.weekStart, labels: view.i18n });
|
|
1793
3353
|
break;
|
|
1794
3354
|
case "sparkline":
|
|
1795
|
-
renderSparkline(body, { labels:
|
|
3355
|
+
renderSparkline(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1796
3356
|
break;
|
|
1797
3357
|
case "gauge":
|
|
1798
|
-
renderGauge(body, { value:
|
|
3358
|
+
renderGauge(body, { value: view.values?.[0] ?? 0, max: view.max, tone: view.tone, label: view.labels?.[0], formatValue });
|
|
1799
3359
|
break;
|
|
1800
3360
|
case "scatter":
|
|
1801
|
-
renderScatter(body, { points:
|
|
3361
|
+
renderScatter(body, { points: view.points ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1802
3362
|
break;
|
|
1803
3363
|
default:
|
|
1804
|
-
renderEmpty(body,
|
|
3364
|
+
renderEmpty(body, view.emptyLabel);
|
|
1805
3365
|
}
|
|
1806
|
-
});
|
|
3366
|
+
}, legendState, { note, onZoomReset: zoomReset });
|
|
3367
|
+
if (!loading) {
|
|
3368
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3369
|
+
if (graphic && !graphic.getAttribute("aria-label")) {
|
|
3370
|
+
graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
if (loading) return;
|
|
3374
|
+
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3375
|
+
bindZoomGesture();
|
|
1807
3376
|
};
|
|
1808
|
-
chartDelegateMeta.set(root, { type: typeOf, tooltip: () =>
|
|
3377
|
+
chartDelegateMeta.set(root, { type: typeOf, tooltip: () => current2.tooltip !== false });
|
|
1809
3378
|
const unbindEvents = bindChartEvents(root);
|
|
1810
3379
|
render();
|
|
3380
|
+
observeFluidWidth(root, render);
|
|
1811
3381
|
return {
|
|
1812
3382
|
el: root,
|
|
1813
|
-
|
|
3383
|
+
/** 归一 + 推断后的当前规格(getter:update/append 换引用后永远读到最新) */
|
|
3384
|
+
get spec() {
|
|
3385
|
+
return current2;
|
|
3386
|
+
},
|
|
1814
3387
|
update(next) {
|
|
1815
|
-
|
|
3388
|
+
const prev = current2;
|
|
3389
|
+
current2 = normalizeChartSpec(next);
|
|
3390
|
+
if (zoomWindow) {
|
|
3391
|
+
const sameLabels = JSON.stringify(prev.labels ?? null) === JSON.stringify(current2.labels ?? null);
|
|
3392
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3393
|
+
const zoomable = isZoomableType(t2) && (current2.zoom === "x" || current2.zoom === "brush");
|
|
3394
|
+
if (!sameLabels || !zoomable) zoomWindow = null;
|
|
3395
|
+
else {
|
|
3396
|
+
const len = fullLength();
|
|
3397
|
+
if (len < 2) zoomWindow = null;
|
|
3398
|
+
else {
|
|
3399
|
+
const from = clampNum(zoomWindow.from, 0, len - 1);
|
|
3400
|
+
const to = clampNum(zoomWindow.to, 0, len - 1);
|
|
3401
|
+
zoomWindow = from <= to ? { from, to } : null;
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
render();
|
|
3406
|
+
},
|
|
3407
|
+
append(label, values, opts) {
|
|
3408
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3409
|
+
if (!isStreamableType(t2)) {
|
|
3410
|
+
if (!warnedAppend) {
|
|
3411
|
+
warnedAppend = true;
|
|
3412
|
+
console.warn(`[icen:chart] append \u4EC5\u652F\u6301 line/area/vbar\uFF08\u5F53\u524D ${String(current2.type ?? t2)}\uFF09\uFF0C\u5DF2\u5FFD\u7565`);
|
|
3413
|
+
}
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3416
|
+
const labels = current2.labels ?? (current2.labels = []);
|
|
3417
|
+
labels.push(String(label ?? ""));
|
|
3418
|
+
const vals = Array.isArray(values) ? values : [];
|
|
3419
|
+
if (current2.series && current2.series.length > 0) {
|
|
3420
|
+
for (const [i, s] of current2.series.entries()) s.values.push(toNum(vals[i]) ?? 0);
|
|
3421
|
+
} else {
|
|
3422
|
+
const v = current2.values ?? (current2.values = []);
|
|
3423
|
+
v.push(toNum(vals[0]) ?? 0);
|
|
3424
|
+
}
|
|
3425
|
+
const maxPoints = opts?.maxPoints != null ? Math.max(1, Math.floor(toNum(opts.maxPoints) ?? 0)) : 0;
|
|
3426
|
+
let dropped = 0;
|
|
3427
|
+
if (maxPoints > 0) {
|
|
3428
|
+
while (labels.length > maxPoints) {
|
|
3429
|
+
labels.shift();
|
|
3430
|
+
if (current2.series) for (const s of current2.series) s.values.shift();
|
|
3431
|
+
else current2.values?.shift();
|
|
3432
|
+
dropped += 1;
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3435
|
+
if (zoomWindow) {
|
|
3436
|
+
const len = Math.max(1, labels.length);
|
|
3437
|
+
const size = zoomWindow.to - zoomWindow.from + 1;
|
|
3438
|
+
const to = clampNum(zoomWindow.to - dropped + 1, 0, len - 1);
|
|
3439
|
+
zoomWindow = { from: Math.max(0, to - size + 1), to };
|
|
3440
|
+
}
|
|
1816
3441
|
render();
|
|
1817
3442
|
},
|
|
1818
3443
|
on(name, listener) {
|
|
@@ -1822,13 +3447,29 @@ function renderChart(el, raw) {
|
|
|
1822
3447
|
root.addEventListener(`icen:chart-${name}`, handler);
|
|
1823
3448
|
return () => root.removeEventListener(`icen:chart-${name}`, handler);
|
|
1824
3449
|
},
|
|
3450
|
+
toDataURL: createChartToDataURL(root),
|
|
1825
3451
|
destroy() {
|
|
3452
|
+
releaseFluidWidth(root);
|
|
3453
|
+
hiddenLegendKeys.delete(root);
|
|
3454
|
+
zoomDragCleanup?.();
|
|
1826
3455
|
root.textContent = "";
|
|
3456
|
+
root.classList.remove("is-loading");
|
|
1827
3457
|
unbindEvents();
|
|
1828
3458
|
chartTooltip().hidden = true;
|
|
1829
3459
|
}
|
|
1830
3460
|
};
|
|
1831
3461
|
}
|
|
3462
|
+
function svgClientPoint(svg, clientX, clientY, viewBoxWidth, viewBoxHeight) {
|
|
3463
|
+
const rect = svg.getBoundingClientRect();
|
|
3464
|
+
const scale = Math.min(rect.width / viewBoxWidth, rect.height / viewBoxHeight);
|
|
3465
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
3466
|
+
return { x: viewBoxWidth / 2, y: viewBoxHeight / 2 };
|
|
3467
|
+
}
|
|
3468
|
+
return {
|
|
3469
|
+
x: (clientX - rect.left - (rect.width - viewBoxWidth * scale) / 2) / scale,
|
|
3470
|
+
y: (clientY - rect.top - (rect.height - viewBoxHeight * scale) / 2) / scale
|
|
3471
|
+
};
|
|
3472
|
+
}
|
|
1832
3473
|
var GRAPH_W = 360;
|
|
1833
3474
|
var GRAPH_H = 260;
|
|
1834
3475
|
var GRAPH_PAD = 28;
|
|
@@ -1877,23 +3518,23 @@ function buildHead(headClass) {
|
|
|
1877
3518
|
const head = h("button", headClass);
|
|
1878
3519
|
head.type = "button";
|
|
1879
3520
|
head.setAttribute("aria-expanded", "false");
|
|
1880
|
-
const iconEl = h("span", "ai-item-icon");
|
|
3521
|
+
const iconEl = h("span", "icen-ai-item-icon");
|
|
1881
3522
|
iconEl.setAttribute("aria-hidden", "true");
|
|
1882
|
-
const main = h("span", "ai-item-main");
|
|
1883
|
-
const titleEl = h("span", "ai-item-title");
|
|
1884
|
-
const subEl = h("span", "ai-item-sub");
|
|
1885
|
-
const statusEl = h("span", "ai-item-status");
|
|
3523
|
+
const main = h("span", "icen-ai-item-main");
|
|
3524
|
+
const titleEl = h("span", "icen-ai-item-title");
|
|
3525
|
+
const subEl = h("span", "icen-ai-item-sub");
|
|
3526
|
+
const statusEl = h("span", "icen-ai-item-status");
|
|
1886
3527
|
statusEl.setAttribute("role", "img");
|
|
1887
|
-
const metaEl = h("span", "ai-item-meta");
|
|
3528
|
+
const metaEl = h("span", "icen-ai-item-meta");
|
|
1888
3529
|
main.append(titleEl, subEl);
|
|
1889
3530
|
head.append(iconEl, main, statusEl, metaEl);
|
|
1890
3531
|
return { head, iconEl, titleEl, subEl, statusEl, metaEl };
|
|
1891
3532
|
}
|
|
1892
3533
|
function buildIo(label) {
|
|
1893
|
-
const root = h("div", "ai-tool-io");
|
|
1894
|
-
root.append(h("div", "ai-tool-io-label", label));
|
|
1895
|
-
const pre = h("pre", "ai-tool-io-content");
|
|
1896
|
-
const media = h("div", "ai-tool-io-media");
|
|
3534
|
+
const root = h("div", "icen-ai-tool-io");
|
|
3535
|
+
root.append(h("div", "icen-ai-tool-io-label", label));
|
|
3536
|
+
const pre = h("pre", "icen-ai-tool-io-content");
|
|
3537
|
+
const media = h("div", "icen-ai-tool-io-media");
|
|
1897
3538
|
media.hidden = true;
|
|
1898
3539
|
root.append(pre, media);
|
|
1899
3540
|
return { root, pre, media };
|
|
@@ -1902,9 +3543,9 @@ function chartSpecOf(value) {
|
|
|
1902
3543
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
1903
3544
|
const v = value;
|
|
1904
3545
|
if (v.type === "chart" && v.spec && typeof v.spec === "object") return v.spec;
|
|
1905
|
-
const
|
|
3546
|
+
const t2 = typeof v.type === "string" ? v.type : void 0;
|
|
1906
3547
|
const looksChart = Array.isArray(v.series) || Array.isArray(v.segments) || Array.isArray(v.points) || Array.isArray(v.dates) || Array.isArray(v.labels) && Array.isArray(v.values);
|
|
1907
|
-
if (looksChart && (
|
|
3548
|
+
if (looksChart && (t2 === void 0 || typeof t2 === "string")) return v;
|
|
1908
3549
|
return null;
|
|
1909
3550
|
}
|
|
1910
3551
|
function setIo(io, value, allowChart = true) {
|
|
@@ -1914,7 +3555,7 @@ function setIo(io, value, allowChart = true) {
|
|
|
1914
3555
|
io.pre.hidden = true;
|
|
1915
3556
|
io.media.replaceChildren();
|
|
1916
3557
|
const holder = document.createElement("div");
|
|
1917
|
-
holder.className = "ai-tool-io-chart";
|
|
3558
|
+
holder.className = "icen-ai-tool-io-chart";
|
|
1918
3559
|
io.media.appendChild(holder);
|
|
1919
3560
|
renderChart(holder, chartSpec);
|
|
1920
3561
|
io.media.hidden = false;
|
|
@@ -1950,29 +3591,29 @@ function defaultExpanded(m) {
|
|
|
1950
3591
|
return false;
|
|
1951
3592
|
}
|
|
1952
3593
|
function buildApproval() {
|
|
1953
|
-
const root = h("div", "ai-tool-approval");
|
|
1954
|
-
const reason = h("div", "ai-tool-approval-reason");
|
|
3594
|
+
const root = h("div", "icen-ai-tool-approval");
|
|
3595
|
+
const reason = h("div", "icen-ai-tool-approval-reason");
|
|
1955
3596
|
reason.hidden = true;
|
|
1956
|
-
const allow = h("button", "btn btn-sm btn-primary", "
|
|
3597
|
+
const allow = h("button", "icen-btn icen-btn-sm icen-btn-primary", t("aiTool.allow"));
|
|
1957
3598
|
allow.type = "button";
|
|
1958
|
-
allow.setAttribute("data-ai-approve", "");
|
|
1959
|
-
const deny = h("button", "btn btn-sm", "
|
|
3599
|
+
allow.setAttribute("data-icen-ai-approve", "");
|
|
3600
|
+
const deny = h("button", "icen-btn icen-btn-sm", t("aiTool.reject"));
|
|
1960
3601
|
deny.type = "button";
|
|
1961
|
-
deny.setAttribute("data-ai-reject", "");
|
|
3602
|
+
deny.setAttribute("data-icen-ai-reject", "");
|
|
1962
3603
|
root.append(reason, allow, deny);
|
|
1963
3604
|
return { root, reason };
|
|
1964
3605
|
}
|
|
1965
3606
|
function applyTint(item, model) {
|
|
1966
3607
|
const tint = getAiKind(model.kind).tint;
|
|
1967
|
-
if (tint) item.style.setProperty("--ai-item-tint", `var(--token-${tint})`);
|
|
3608
|
+
if (tint) item.style.setProperty("--ai-item-tint", `var(--icen-token-${tint})`);
|
|
1968
3609
|
else item.style.removeProperty("--ai-item-tint");
|
|
1969
3610
|
}
|
|
1970
3611
|
function applyKindVisual(parts, model) {
|
|
1971
3612
|
const kind = getAiKind(model.kind);
|
|
1972
3613
|
parts.titleEl.textContent = kind.label || model.name;
|
|
1973
3614
|
parts.iconEl.replaceChildren();
|
|
1974
|
-
const
|
|
1975
|
-
if (
|
|
3615
|
+
const svg = svgIcon(kind.icon);
|
|
3616
|
+
if (svg) parts.iconEl.append(svg);
|
|
1976
3617
|
const sub = summarizeInput(model);
|
|
1977
3618
|
parts.subEl.textContent = sub;
|
|
1978
3619
|
parts.subEl.hidden = !sub;
|
|
@@ -1987,15 +3628,15 @@ function renderAiToolCall(el, model) {
|
|
|
1987
3628
|
return { el, update: () => void 0 };
|
|
1988
3629
|
}
|
|
1989
3630
|
const item = el;
|
|
1990
|
-
let
|
|
1991
|
-
item.className = `ai-tool ai-tool--${model.kind}`;
|
|
1992
|
-
item.dataset.
|
|
1993
|
-
item.dataset.
|
|
1994
|
-
const parts = buildHead("ai-tool-head");
|
|
1995
|
-
const body = h("div", "ai-tool-body");
|
|
3631
|
+
let current2 = model;
|
|
3632
|
+
item.className = `icen-ai-tool icen-ai-tool--${model.kind}`;
|
|
3633
|
+
item.dataset.icenAiId = model.id;
|
|
3634
|
+
item.dataset.icenAiKind = model.kind;
|
|
3635
|
+
const parts = buildHead("icen-ai-tool-head");
|
|
3636
|
+
const body = h("div", "icen-ai-tool-body");
|
|
1996
3637
|
body.hidden = true;
|
|
1997
|
-
const inputIo = buildIo("
|
|
1998
|
-
const outputIo = buildIo("
|
|
3638
|
+
const inputIo = buildIo(t("common.input"));
|
|
3639
|
+
const outputIo = buildIo(t("common.output"));
|
|
1999
3640
|
const approval = buildApproval();
|
|
2000
3641
|
body.append(inputIo.root, outputIo.root, approval.root);
|
|
2001
3642
|
item.append(parts.head, body);
|
|
@@ -2019,12 +3660,12 @@ function renderAiToolCall(el, model) {
|
|
|
2019
3660
|
approval.reason.hidden = !reason;
|
|
2020
3661
|
if (!item.dataset.aiUserToggled && defaultExpanded(m)) setOpen(true);
|
|
2021
3662
|
};
|
|
2022
|
-
apply(
|
|
3663
|
+
apply(current2);
|
|
2023
3664
|
return {
|
|
2024
3665
|
el: item,
|
|
2025
3666
|
update(patch) {
|
|
2026
|
-
|
|
2027
|
-
apply(
|
|
3667
|
+
current2 = { ...current2, ...patch };
|
|
3668
|
+
apply(current2);
|
|
2028
3669
|
}
|
|
2029
3670
|
};
|
|
2030
3671
|
}
|
|
@@ -2033,15 +3674,15 @@ function renderAiSubagent(el, model) {
|
|
|
2033
3674
|
return { el, update: () => void 0 };
|
|
2034
3675
|
}
|
|
2035
3676
|
const item = el;
|
|
2036
|
-
let
|
|
2037
|
-
item.className = "ai-subagent";
|
|
2038
|
-
item.dataset.
|
|
2039
|
-
item.dataset.
|
|
2040
|
-
const parts = buildHead("ai-subagent-head");
|
|
2041
|
-
const body = h("div", "ai-subagent-body");
|
|
3677
|
+
let current2 = model;
|
|
3678
|
+
item.className = "icen-ai-subagent";
|
|
3679
|
+
item.dataset.icenAiId = model.id;
|
|
3680
|
+
item.dataset.icenAiKind = model.kind;
|
|
3681
|
+
const parts = buildHead("icen-ai-subagent-head");
|
|
3682
|
+
const body = h("div", "icen-ai-subagent-body");
|
|
2042
3683
|
body.hidden = true;
|
|
2043
|
-
const stream = h("div", "ai-subagent-stream");
|
|
2044
|
-
const result = h("div", "ai-subagent-result");
|
|
3684
|
+
const stream = h("div", "icen-ai-subagent-stream");
|
|
3685
|
+
const result = h("div", "icen-ai-subagent-result");
|
|
2045
3686
|
result.hidden = true;
|
|
2046
3687
|
body.append(stream, result);
|
|
2047
3688
|
item.append(parts.head, body);
|
|
@@ -2081,7 +3722,7 @@ function renderAiSubagent(el, model) {
|
|
|
2081
3722
|
applyTint(item, m);
|
|
2082
3723
|
applyKindVisual(parts, m);
|
|
2083
3724
|
const steps = m.activities?.length ?? 0;
|
|
2084
|
-
const meta = [m.durationMs != null ? formatDuration(m.durationMs) : "", steps > 0 ?
|
|
3725
|
+
const meta = [m.durationMs != null ? formatDuration(m.durationMs) : "", steps > 0 ? t("common.steps", { p0: steps }) : ""].filter(Boolean).join(" \xB7 ");
|
|
2085
3726
|
applyStatusMeta(parts, m.status, meta);
|
|
2086
3727
|
renderActivities(m.activities);
|
|
2087
3728
|
const receipt = compactValue(m.output);
|
|
@@ -2089,12 +3730,12 @@ function renderAiSubagent(el, model) {
|
|
|
2089
3730
|
result.hidden = !receipt;
|
|
2090
3731
|
if (!item.dataset.aiUserToggled && defaultExpanded(m)) setOpen(true);
|
|
2091
3732
|
};
|
|
2092
|
-
apply(
|
|
3733
|
+
apply(current2);
|
|
2093
3734
|
return {
|
|
2094
3735
|
el: item,
|
|
2095
3736
|
update(patch) {
|
|
2096
|
-
|
|
2097
|
-
apply(
|
|
3737
|
+
current2 = { ...current2, ...patch };
|
|
3738
|
+
apply(current2);
|
|
2098
3739
|
}
|
|
2099
3740
|
};
|
|
2100
3741
|
}
|
|
@@ -2103,8 +3744,8 @@ function setupItem(item, kind) {
|
|
|
2103
3744
|
const flag = kind === "tool" ? "__icenAiToolInit" : "__icenAiSubagentInit";
|
|
2104
3745
|
if (marked[flag]) return () => void 0;
|
|
2105
3746
|
marked[flag] = true;
|
|
2106
|
-
const headClass = kind === "tool" ? ".ai-tool-head" : ".ai-subagent-head";
|
|
2107
|
-
const bodyClass = kind === "tool" ? ".ai-tool-body" : ".ai-subagent-body";
|
|
3747
|
+
const headClass = kind === "tool" ? ".icen-ai-tool-head" : ".icen-ai-subagent-head";
|
|
3748
|
+
const bodyClass = kind === "tool" ? ".icen-ai-tool-body" : ".icen-ai-subagent-body";
|
|
2108
3749
|
const head = item.querySelector(`:scope > ${headClass}`);
|
|
2109
3750
|
const body = item.querySelector(`:scope > ${bodyClass}`);
|
|
2110
3751
|
const setOpen = (open, fire = true) => {
|
|
@@ -2117,25 +3758,25 @@ function setupItem(item, kind) {
|
|
|
2117
3758
|
const onCardClick = (ev) => {
|
|
2118
3759
|
const target = ev.target;
|
|
2119
3760
|
if (!(target instanceof Element)) return;
|
|
2120
|
-
const ownerOf = (node) => node.closest(".ai-tool, .ai-subagent");
|
|
2121
|
-
const approveBtn = target.closest("[data-ai-approve]");
|
|
3761
|
+
const ownerOf = (node) => node.closest(".icen-ai-tool, .icen-ai-subagent");
|
|
3762
|
+
const approveBtn = target.closest("[data-icen-ai-approve]");
|
|
2122
3763
|
if (approveBtn && ownerOf(approveBtn) === item) {
|
|
2123
|
-
emitIcen(item, "icen:ai-approve", { id: item.dataset.
|
|
3764
|
+
emitIcen(item, "icen:ai-approve", { id: item.dataset.icenAiId ?? "", kind: item.dataset.icenAiKind ?? "" });
|
|
2124
3765
|
return;
|
|
2125
3766
|
}
|
|
2126
|
-
const rejectBtn = target.closest("[data-ai-reject]");
|
|
3767
|
+
const rejectBtn = target.closest("[data-icen-ai-reject]");
|
|
2127
3768
|
if (rejectBtn && ownerOf(rejectBtn) === item) {
|
|
2128
|
-
emitIcen(item, "icen:ai-reject", { id: item.dataset.
|
|
3769
|
+
emitIcen(item, "icen:ai-reject", { id: item.dataset.icenAiId ?? "", kind: item.dataset.icenAiKind ?? "" });
|
|
2129
3770
|
return;
|
|
2130
3771
|
}
|
|
2131
|
-
const headEl = target.closest(".ai-tool-head, .ai-subagent-head");
|
|
3772
|
+
const headEl = target.closest(".icen-ai-tool-head, .icen-ai-subagent-head");
|
|
2132
3773
|
if (!headEl || ownerOf(headEl) !== item || !head) return;
|
|
2133
3774
|
item.dataset.aiUserToggled = "1";
|
|
2134
3775
|
setOpen(head.getAttribute("aria-expanded") !== "true");
|
|
2135
3776
|
};
|
|
2136
3777
|
item.addEventListener("click", onCardClick);
|
|
2137
3778
|
if (body?.hidden) {
|
|
2138
|
-
const kindName = item.dataset.
|
|
3779
|
+
const kindName = item.dataset.icenAiKind ?? "";
|
|
2139
3780
|
const isErr = item.classList.contains("is-error");
|
|
2140
3781
|
const isApproval = item.classList.contains("is-approval");
|
|
2141
3782
|
if (isErr || isApproval || kindName === "chart") {
|
|
@@ -2157,14 +3798,14 @@ function initItems(root, selector, kind) {
|
|
|
2157
3798
|
return items.map((item) => setupItem(item, kind));
|
|
2158
3799
|
}
|
|
2159
3800
|
function initAiTool(root) {
|
|
2160
|
-
const cleanups = initItems(root, ".ai-tool", "tool");
|
|
3801
|
+
const cleanups = initItems(root, ".icen-ai-tool", "tool");
|
|
2161
3802
|
return () => {
|
|
2162
3803
|
for (const fn of cleanups) fn();
|
|
2163
3804
|
cleanups.length = 0;
|
|
2164
3805
|
};
|
|
2165
3806
|
}
|
|
2166
3807
|
function initAiSubagent(root) {
|
|
2167
|
-
const cleanups = initItems(root, ".ai-subagent", "subagent");
|
|
3808
|
+
const cleanups = initItems(root, ".icen-ai-subagent", "subagent");
|
|
2168
3809
|
return () => {
|
|
2169
3810
|
for (const fn of cleanups) fn();
|
|
2170
3811
|
cleanups.length = 0;
|