@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,52 +1,1007 @@
|
|
|
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
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
);
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
);
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
);
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
);
|
|
20
|
-
var ICON_SCAN_SEARCH = svg(
|
|
21
|
-
'<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"/>'
|
|
22
|
-
);
|
|
23
|
-
var ICON_GLOBE = svg(
|
|
24
|
-
'<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"/>'
|
|
25
|
-
);
|
|
26
|
-
var ICON_DOWNLOAD = svg(
|
|
27
|
-
'<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"/>'
|
|
28
|
-
);
|
|
29
|
-
var ICON_BLOCKS = svg(
|
|
30
|
-
'<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"/>'
|
|
31
|
-
);
|
|
32
|
-
var ICON_ZAP = svg(
|
|
33
|
-
'<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"/>'
|
|
34
|
-
);
|
|
35
|
-
var ICON_LIST = svg(
|
|
36
|
-
'<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"/>'
|
|
37
|
-
);
|
|
38
|
-
var ICON_LIST_CHECKS = svg(
|
|
39
|
-
'<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"/>'
|
|
40
|
-
);
|
|
41
|
-
var ICON_BOT = svg(
|
|
42
|
-
'<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"/>'
|
|
43
|
-
);
|
|
44
|
-
var ICON_CHART = svg(
|
|
45
|
-
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
46
|
-
);
|
|
47
|
-
var ICON_FILE_TEXT = svg(
|
|
48
|
-
'<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"/>'
|
|
49
|
-
);
|
|
988
|
+
var ICON_TERMINAL = iconHTML("terminal");
|
|
989
|
+
var ICON_FILE = iconHTML("file");
|
|
990
|
+
var ICON_FILE_PEN = iconHTML("edit");
|
|
991
|
+
var ICON_FILE_PLUS = iconHTML("plus");
|
|
992
|
+
var ICON_TRASH = iconHTML("trash");
|
|
993
|
+
var ICON_SEARCH = iconHTML("search");
|
|
994
|
+
var ICON_FOLDER_SEARCH = iconHTML("folder");
|
|
995
|
+
var ICON_SCAN_SEARCH = iconHTML("search");
|
|
996
|
+
var ICON_GLOBE = iconHTML("globe");
|
|
997
|
+
var ICON_DOWNLOAD = iconHTML("download");
|
|
998
|
+
var ICON_BLOCKS = iconHTML("server");
|
|
999
|
+
var ICON_ZAP = iconHTML("sparkle");
|
|
1000
|
+
var ICON_LIST = iconHTML("list");
|
|
1001
|
+
var ICON_LIST_CHECKS = iconHTML("list");
|
|
1002
|
+
var ICON_BOT = iconHTML("agent");
|
|
1003
|
+
var ICON_CHART = iconHTML("chart-line");
|
|
1004
|
+
var ICON_FILE_TEXT = iconHTML("document");
|
|
50
1005
|
function isObj(v) {
|
|
51
1006
|
return typeof v === "object" && v !== null;
|
|
52
1007
|
}
|
|
@@ -96,86 +1051,58 @@ var sum = (fn) => {
|
|
|
96
1051
|
return (input) => fn(input) ?? "";
|
|
97
1052
|
};
|
|
98
1053
|
var BUILTIN_KINDS = {
|
|
99
|
-
shell: { label: "
|
|
100
|
-
read: { label: "
|
|
101
|
-
edit: { label: "
|
|
102
|
-
write: { label: "
|
|
103
|
-
rm: { label: "
|
|
104
|
-
grep: { label: "
|
|
105
|
-
glob: { label: "
|
|
106
|
-
browser: { label: "
|
|
107
|
-
search: { label: "
|
|
108
|
-
fetch: { label: "
|
|
1054
|
+
shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
1055
|
+
read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
1056
|
+
edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
1057
|
+
write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
1058
|
+
rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
1059
|
+
grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
1060
|
+
glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
1061
|
+
browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
1062
|
+
search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
1063
|
+
fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
109
1064
|
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
110
|
-
skill: { label: "
|
|
1065
|
+
skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
111
1066
|
todo: {
|
|
112
|
-
label: "
|
|
1067
|
+
label: t("aiCore.kindTodo"),
|
|
113
1068
|
icon: ICON_LIST,
|
|
114
1069
|
tint: "info",
|
|
115
1070
|
summarize: sum((input) => {
|
|
116
1071
|
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
117
1072
|
const done = items.filter((it) => it?.status === "done").length;
|
|
118
|
-
return items.length > 0 ?
|
|
1073
|
+
return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
|
|
119
1074
|
})
|
|
120
1075
|
},
|
|
121
|
-
plan: { label: "
|
|
122
|
-
subagent: { label: "
|
|
123
|
-
note: { label: "
|
|
124
|
-
chart: { label: "
|
|
1076
|
+
plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
|
|
1077
|
+
subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
1078
|
+
note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
|
|
1079
|
+
chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
125
1080
|
};
|
|
126
1081
|
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
127
1082
|
function h(tag, className, text) {
|
|
1083
|
+
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");
|
|
128
1084
|
const node = document.createElement(tag);
|
|
129
1085
|
if (className) node.className = className;
|
|
130
1086
|
if (text != null) node.textContent = text;
|
|
131
1087
|
return node;
|
|
132
1088
|
}
|
|
133
|
-
function svgIcon(
|
|
134
|
-
|
|
135
|
-
let parsed;
|
|
136
|
-
try {
|
|
137
|
-
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
138
|
-
} catch {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
const root = parsed.documentElement;
|
|
142
|
-
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
const sanitize = (el) => {
|
|
146
|
-
for (const attr of Array.from(el.attributes)) {
|
|
147
|
-
const name = attr.name.toLowerCase();
|
|
148
|
-
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
149
|
-
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
150
|
-
el.removeAttribute(attr.name);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
for (const child of Array.from(el.children)) {
|
|
154
|
-
const tag = child.tagName.toLowerCase();
|
|
155
|
-
if (tag === "script" || tag === "foreignobject") {
|
|
156
|
-
child.remove();
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
sanitize(child);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
sanitize(root);
|
|
163
|
-
return document.importNode(root, true);
|
|
1089
|
+
function svgIcon(svg) {
|
|
1090
|
+
return parseSvg(svg);
|
|
164
1091
|
}
|
|
165
1092
|
|
|
166
1093
|
// src/behaviors/kb-core.ts
|
|
167
1094
|
var ic = (label, d) => ({ label, icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${d}</svg>` });
|
|
168
1095
|
var BUILTIN_SOURCE_TYPES = {
|
|
169
|
-
doc: ic("
|
|
170
|
-
web: ic("
|
|
171
|
-
wiki: ic("
|
|
172
|
-
sheet: ic("
|
|
173
|
-
db: ic("
|
|
174
|
-
ticket: ic("
|
|
175
|
-
code: ic("
|
|
176
|
-
api: ic("
|
|
177
|
-
image: ic("
|
|
178
|
-
mail: ic("
|
|
1096
|
+
doc: ic(t("kbCore.typeDocument"), '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/>'),
|
|
1097
|
+
web: ic(t("kbCore.typeWebpage"), '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>'),
|
|
1098
|
+
wiki: ic(t("kbCore.typeKb"), '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>'),
|
|
1099
|
+
sheet: ic(t("kbCore.typeTable"), '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>'),
|
|
1100
|
+
db: ic(t("kbCore.typeDatabase"), '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5"/><path d="M3 12c0 1.7 4 3 9 3s9-1.3 9-3"/>'),
|
|
1101
|
+
ticket: ic(t("kbCore.typeTicket"), '<path d="M3 9V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 6v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-6z"/><path d="M13 5v14"/>'),
|
|
1102
|
+
code: ic(t("kbCore.typeCode"), '<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>'),
|
|
1103
|
+
api: ic(t("kbCore.typeApi"), '<path d="M4 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4z"/>'),
|
|
1104
|
+
image: ic(t("kbCore.typeImage"), '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-4.6-4.6a2 2 0 0 0-2.8 0L3 21"/>'),
|
|
1105
|
+
mail: ic(t("kbCore.typeEmail"), '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/>')
|
|
179
1106
|
};
|
|
180
1107
|
var sourceTypeRegistry = new Map(Object.entries(BUILTIN_SOURCE_TYPES));
|
|
181
1108
|
var CITE_RE = /\[(\d{1,3})\]/g;
|
|
@@ -193,6 +1120,14 @@ function parseInlineCitations(text) {
|
|
|
193
1120
|
if (last < text.length) out.push({ text: text.slice(last) });
|
|
194
1121
|
return out;
|
|
195
1122
|
}
|
|
1123
|
+
var RUN_LABELS = {
|
|
1124
|
+
unstart: t("kbCore.runUnstarted"),
|
|
1125
|
+
queued: t("kbCore.runQueued"),
|
|
1126
|
+
running: t("kbCore.runRunning"),
|
|
1127
|
+
cancel: t("kbCore.runCancelled"),
|
|
1128
|
+
done: t("kbCore.runDone"),
|
|
1129
|
+
fail: t("kbCore.runFailed")
|
|
1130
|
+
};
|
|
196
1131
|
function normalizeQueryResult(raw) {
|
|
197
1132
|
const columns = Array.isArray(raw.columns) ? raw.columns.map((c) => typeof c === "string" ? { name: c } : { name: String(c.name ?? ""), type: c.type }) : [];
|
|
198
1133
|
return {
|
|
@@ -206,19 +1141,23 @@ function normalizeQueryResult(raw) {
|
|
|
206
1141
|
exportFormats: Array.isArray(raw.exportFormats) ? raw.exportFormats.map(String) : void 0
|
|
207
1142
|
};
|
|
208
1143
|
}
|
|
1144
|
+
var SPAN_LABELS = {
|
|
1145
|
+
retrieval: t("kbCore.stageRetrieval"),
|
|
1146
|
+
generation: t("kbCore.stageGeneration"),
|
|
1147
|
+
rerank: t("kbCore.stageRerank"),
|
|
1148
|
+
embed: t("kbCore.stageEmbed"),
|
|
1149
|
+
tool: t("kbCore.stageTool"),
|
|
1150
|
+
guard: t("kbCore.stageGuard"),
|
|
1151
|
+
chunk: t("kbCore.stageChunk"),
|
|
1152
|
+
query: t("kbCore.stageQuery"),
|
|
1153
|
+
agent: t("kbCore.stageAgent")
|
|
1154
|
+
};
|
|
209
1155
|
function formatCount(n) {
|
|
210
1156
|
if (n == null || !Number.isFinite(n)) return "\u2014";
|
|
211
1157
|
if (Math.abs(n) >= 1e4) return `${(n / 1e3).toFixed(1)}k`;
|
|
212
1158
|
return n.toLocaleString("en-US");
|
|
213
1159
|
}
|
|
214
1160
|
|
|
215
|
-
// src/behaviors/events.ts
|
|
216
|
-
function emitIcen(source, type, detail) {
|
|
217
|
-
return source.dispatchEvent(
|
|
218
|
-
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
1161
|
// src/behaviors/kb-clarify.ts
|
|
223
1162
|
var ICON_HELP = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.1 9a3 3 0 0 1 5.8 1c0 2-3 2.4-3 4"/><path d="M12 17.5h.01"/></svg>';
|
|
224
1163
|
function toClarification(raw) {
|
|
@@ -235,44 +1174,44 @@ function renderKbClarify(el, c, opts) {
|
|
|
235
1174
|
if (typeof document === "undefined") return el;
|
|
236
1175
|
const clar = toClarification(c);
|
|
237
1176
|
el.textContent = "";
|
|
238
|
-
const root = h("div", "kb-clarify");
|
|
239
|
-
if (clar.id) root.dataset.
|
|
240
|
-
const q = h("div", "kb-clarify-q");
|
|
241
|
-
const iconBox = h("span", "kb-clarify-qicon");
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
1177
|
+
const root = h("div", "icen-kb-clarify");
|
|
1178
|
+
if (clar.id) root.dataset.icenClarifyId = clar.id;
|
|
1179
|
+
const q = h("div", "icen-kb-clarify-q");
|
|
1180
|
+
const iconBox = h("span", "icen-kb-clarify-qicon");
|
|
1181
|
+
const svg = svgIcon(ICON_HELP);
|
|
1182
|
+
if (svg) iconBox.appendChild(svg);
|
|
244
1183
|
q.appendChild(iconBox);
|
|
245
|
-
q.appendChild(h("span", "kb-clarify-qtext", clar.question));
|
|
1184
|
+
q.appendChild(h("span", "icen-kb-clarify-qtext", clar.question));
|
|
246
1185
|
root.appendChild(q);
|
|
247
|
-
const optsWrap = h("div", "kb-clarify-opts");
|
|
248
|
-
const resolved = h("div", "kb-clarify-resolved");
|
|
1186
|
+
const optsWrap = h("div", "icen-kb-clarify-opts");
|
|
1187
|
+
const resolved = h("div", "icen-kb-clarify-resolved");
|
|
249
1188
|
resolved.hidden = true;
|
|
250
1189
|
const pick = (btn) => {
|
|
251
1190
|
if (root.classList.contains("is-answered")) return;
|
|
252
1191
|
root.classList.add("is-answered");
|
|
253
1192
|
btn.classList.add("is-picked");
|
|
254
|
-
Array.from(optsWrap.querySelectorAll(".kb-clarify-opt")).forEach((b) => {
|
|
1193
|
+
Array.from(optsWrap.querySelectorAll(".icen-kb-clarify-opt")).forEach((b) => {
|
|
255
1194
|
if (b !== btn) b.disabled = true;
|
|
256
1195
|
});
|
|
257
1196
|
resolved.textContent = "";
|
|
258
|
-
resolved.appendChild(document.createTextNode("
|
|
259
|
-
resolved.appendChild(h("b", "kb-clarify-picked", btn.dataset.
|
|
1197
|
+
resolved.appendChild(document.createTextNode(t("kbClarify.parsedPrefix")));
|
|
1198
|
+
resolved.appendChild(h("b", "icen-kb-clarify-picked", btn.dataset.icenLabel ?? ""));
|
|
260
1199
|
resolved.hidden = false;
|
|
261
|
-
const answer = { id: clar.id, value: btn.dataset.
|
|
1200
|
+
const answer = { id: clar.id, value: btn.dataset.icenValue ?? "", label: btn.dataset.icenLabel ?? "" };
|
|
262
1201
|
emitIcen(btn, "icen:kb-clarify-answer", answer);
|
|
263
1202
|
opts?.onAnswer?.(answer);
|
|
264
1203
|
};
|
|
265
1204
|
for (const o of clar.options) {
|
|
266
|
-
const btn = h("button", "kb-clarify-opt", o.label);
|
|
1205
|
+
const btn = h("button", "icen-kb-clarify-opt", o.label);
|
|
267
1206
|
btn.type = "button";
|
|
268
|
-
btn.dataset.
|
|
269
|
-
btn.dataset.
|
|
1207
|
+
btn.dataset.icenValue = o.value;
|
|
1208
|
+
btn.dataset.icenLabel = o.label;
|
|
270
1209
|
btn.addEventListener("click", () => pick(btn));
|
|
271
1210
|
optsWrap.appendChild(btn);
|
|
272
1211
|
}
|
|
273
1212
|
if (optsWrap.children.length > 0) root.appendChild(optsWrap);
|
|
274
1213
|
root.appendChild(resolved);
|
|
275
|
-
if (clar.reason) root.appendChild(h("div", "kb-clarify-reason", clar.reason));
|
|
1214
|
+
if (clar.reason) root.appendChild(h("div", "icen-kb-clarify-reason", clar.reason));
|
|
276
1215
|
el.appendChild(root);
|
|
277
1216
|
return el;
|
|
278
1217
|
}
|
|
@@ -299,46 +1238,46 @@ function toExplainFact(raw) {
|
|
|
299
1238
|
}
|
|
300
1239
|
function renderGroup(label, items) {
|
|
301
1240
|
if (!items?.length) return null;
|
|
302
|
-
const group = h("div", "kb-explain-group");
|
|
303
|
-
group.appendChild(h("span", "kb-explain-group-label", label));
|
|
304
|
-
for (const item of items) group.appendChild(h("span", "kb-chip", item));
|
|
1241
|
+
const group = h("div", "icen-kb-explain-group");
|
|
1242
|
+
group.appendChild(h("span", "icen-kb-explain-group-label", label));
|
|
1243
|
+
for (const item of items) group.appendChild(h("span", "icen-kb-chip", item));
|
|
305
1244
|
return group;
|
|
306
1245
|
}
|
|
307
1246
|
function renderKbExplain(el, fact) {
|
|
308
1247
|
if (typeof document === "undefined") return el;
|
|
309
1248
|
const f = toExplainFact(fact);
|
|
310
1249
|
el.textContent = "";
|
|
311
|
-
const root = h("div", "kb-explain");
|
|
312
|
-
root.dataset.
|
|
1250
|
+
const root = h("div", "icen-kb-explain");
|
|
1251
|
+
root.dataset.icenKbExplain = "";
|
|
313
1252
|
const count = (f.tables?.length ?? 0) + (f.columns?.length ?? 0) + (f.filters?.length ?? 0) + (f.aggregates?.length ?? 0) + (f.metrics?.length ?? 0);
|
|
314
|
-
const head = h("button", "kb-fold-head kb-explain-head");
|
|
1253
|
+
const head = h("button", "icen-kb-fold-head icen-kb-explain-head");
|
|
315
1254
|
head.type = "button";
|
|
316
1255
|
head.setAttribute("aria-expanded", "false");
|
|
317
|
-
head.appendChild(h("span", "kb-fold-caret", "\u25B8"));
|
|
318
|
-
head.appendChild(h("span", "kb-explain-title", "
|
|
1256
|
+
head.appendChild(h("span", "icen-kb-fold-caret", "\u25B8"));
|
|
1257
|
+
head.appendChild(h("span", "icen-kb-explain-title", t("kbExplain.trigger")));
|
|
319
1258
|
if (count > 0) {
|
|
320
|
-
const countBox = h("span", "kb-num kb-explain-count", String(count));
|
|
321
|
-
countBox.classList.add("kb-fold-count");
|
|
1259
|
+
const countBox = h("span", "icen-kb-num icen-kb-explain-count", String(count));
|
|
1260
|
+
countBox.classList.add("icen-kb-fold-count");
|
|
322
1261
|
head.appendChild(countBox);
|
|
323
1262
|
}
|
|
324
1263
|
root.appendChild(head);
|
|
325
|
-
const body = h("div", "kb-explain-body");
|
|
1264
|
+
const body = h("div", "icen-kb-explain-body");
|
|
326
1265
|
body.hidden = true;
|
|
327
1266
|
const groups = [
|
|
328
|
-
renderGroup("
|
|
329
|
-
renderGroup("
|
|
330
|
-
renderGroup("
|
|
331
|
-
renderGroup("
|
|
1267
|
+
renderGroup(t("kbExplain.groupTable"), f.tables),
|
|
1268
|
+
renderGroup(t("kbExplain.groupColumn"), f.columns),
|
|
1269
|
+
renderGroup(t("kbExplain.groupFilter"), f.filters),
|
|
1270
|
+
renderGroup(t("kbExplain.groupAgg"), f.aggregates)
|
|
332
1271
|
];
|
|
333
1272
|
for (const g of groups) if (g) body.appendChild(g);
|
|
334
1273
|
if (f.metrics?.length) {
|
|
335
|
-
const metrics = h("div", "kb-explain-metrics");
|
|
1274
|
+
const metrics = h("div", "icen-kb-explain-metrics");
|
|
336
1275
|
for (const m of f.metrics) {
|
|
337
|
-
const row = h("div", "kb-explain-metric");
|
|
338
|
-
row.appendChild(h("span", "kb-explain-metric-name", m.name));
|
|
1276
|
+
const row = h("div", "icen-kb-explain-metric");
|
|
1277
|
+
row.appendChild(h("span", "icen-kb-explain-metric-name", m.name));
|
|
339
1278
|
if (m.ref) {
|
|
340
1279
|
if (!/^\s*(javascript|data|vbscript)\s*:/i.test(m.ref)) {
|
|
341
|
-
const a = h("a", "kb-explain-metric-ref", "
|
|
1280
|
+
const a = h("a", "icen-kb-explain-metric-ref", t("kbExplain.viewDefinition"));
|
|
342
1281
|
a.href = m.ref;
|
|
343
1282
|
a.rel = "noopener";
|
|
344
1283
|
row.appendChild(a);
|
|
@@ -349,7 +1288,7 @@ function renderKbExplain(el, fact) {
|
|
|
349
1288
|
body.appendChild(metrics);
|
|
350
1289
|
}
|
|
351
1290
|
if (body.children.length === 0) {
|
|
352
|
-
body.appendChild(h("div", "kb-empty", "
|
|
1291
|
+
body.appendChild(h("div", "icen-kb-empty", t("kbExplain.empty")));
|
|
353
1292
|
}
|
|
354
1293
|
root.appendChild(body);
|
|
355
1294
|
head.addEventListener("click", () => {
|
|
@@ -370,16 +1309,16 @@ function toneVar(tone = "accent") {
|
|
|
370
1309
|
if (registered) return registered;
|
|
371
1310
|
switch (tone) {
|
|
372
1311
|
case "success":
|
|
373
|
-
return "var(--token-success)";
|
|
1312
|
+
return "var(--icen-token-success)";
|
|
374
1313
|
case "warning":
|
|
375
|
-
return "var(--token-warning)";
|
|
1314
|
+
return "var(--icen-token-warning)";
|
|
376
1315
|
case "error":
|
|
377
|
-
return "var(--token-error)";
|
|
1316
|
+
return "var(--icen-token-error)";
|
|
378
1317
|
case "muted":
|
|
379
|
-
return "var(--token-text-faint)";
|
|
1318
|
+
return "var(--icen-token-text-faint)";
|
|
380
1319
|
case "accent":
|
|
381
1320
|
default:
|
|
382
|
-
return "var(--token-accent)";
|
|
1321
|
+
return "var(--icen-token-accent)";
|
|
383
1322
|
}
|
|
384
1323
|
}
|
|
385
1324
|
function fmt(opts, value) {
|
|
@@ -390,13 +1329,66 @@ function maxOf(values) {
|
|
|
390
1329
|
for (const v of values) if (v > max) max = v;
|
|
391
1330
|
return max;
|
|
392
1331
|
}
|
|
393
|
-
function
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
1332
|
+
function pointLabelsRow(labels, width, pad) {
|
|
1333
|
+
const row = document.createElement("div");
|
|
1334
|
+
row.className = "icen-chart-labels icen-chart-labels--points";
|
|
1335
|
+
const count = Math.min(labels.length, Math.max(2, Math.min(7, Math.floor(width / 64))));
|
|
1336
|
+
const step = count > 1 ? (width - 2 * pad) / (count - 1) : width;
|
|
1337
|
+
for (let tick = 0; tick < count; tick++) {
|
|
1338
|
+
const index = count <= 1 ? 0 : Math.round(tick * (labels.length - 1) / (count - 1));
|
|
1339
|
+
const x = labels.length <= 1 ? width / 2 : pad + index / (labels.length - 1) * (width - 2 * pad);
|
|
1340
|
+
const span = document.createElement("span");
|
|
1341
|
+
span.textContent = labels[index] ?? "";
|
|
1342
|
+
span.title = span.textContent;
|
|
1343
|
+
span.dir = "auto";
|
|
1344
|
+
span.dataset.icenChartIndex = String(index);
|
|
1345
|
+
span.style.left = `${x / width * 100}%`;
|
|
1346
|
+
span.style.width = `${Math.max(0, Math.min(step * 0.9, 2 * x, 2 * (width - x)))}px`;
|
|
1347
|
+
row.appendChild(span);
|
|
398
1348
|
}
|
|
399
|
-
return
|
|
1349
|
+
return row;
|
|
1350
|
+
}
|
|
1351
|
+
function clampNum(v, lo, hi) {
|
|
1352
|
+
return Math.min(hi, Math.max(lo, v));
|
|
1353
|
+
}
|
|
1354
|
+
function lttb(points, threshold, getX, getY) {
|
|
1355
|
+
const len = points.length;
|
|
1356
|
+
const n = Math.floor(threshold);
|
|
1357
|
+
if (!Number.isFinite(n) || n < 3 || n >= len || len <= 3) return points;
|
|
1358
|
+
const sampled = new Array(n);
|
|
1359
|
+
sampled[0] = points[0];
|
|
1360
|
+
sampled[n - 1] = points[len - 1];
|
|
1361
|
+
const every = (len - 2) / (n - 2);
|
|
1362
|
+
let a = 0;
|
|
1363
|
+
for (let i = 0; i < n - 2; i++) {
|
|
1364
|
+
const avgStart = Math.floor((i + 1) * every) + 1;
|
|
1365
|
+
const avgEnd = Math.min(Math.floor((i + 2) * every) + 1, len);
|
|
1366
|
+
let avgX = 0;
|
|
1367
|
+
let avgY = 0;
|
|
1368
|
+
for (let j = avgStart; j < avgEnd; j++) {
|
|
1369
|
+
avgX += getX(points[j]);
|
|
1370
|
+
avgY += getY(points[j]);
|
|
1371
|
+
}
|
|
1372
|
+
const avgLen = Math.max(1, avgEnd - avgStart);
|
|
1373
|
+
avgX /= avgLen;
|
|
1374
|
+
avgY /= avgLen;
|
|
1375
|
+
const rangeStart = Math.floor(i * every) + 1;
|
|
1376
|
+
const rangeEnd = Math.min(Math.floor((i + 1) * every) + 1, len);
|
|
1377
|
+
const ax = getX(points[a]);
|
|
1378
|
+
const ay = getY(points[a]);
|
|
1379
|
+
let maxArea = -1;
|
|
1380
|
+
let nextA = rangeStart;
|
|
1381
|
+
for (let j = rangeStart; j < rangeEnd; j++) {
|
|
1382
|
+
const area = Math.abs((ax - avgX) * (getY(points[j]) - ay) - (ax - getX(points[j])) * (avgY - ay)) * 0.5;
|
|
1383
|
+
if (area > maxArea) {
|
|
1384
|
+
maxArea = area;
|
|
1385
|
+
nextA = j;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
sampled[i + 1] = points[nextA];
|
|
1389
|
+
a = nextA;
|
|
1390
|
+
}
|
|
1391
|
+
return sampled;
|
|
400
1392
|
}
|
|
401
1393
|
function svgEl(tag, attrs) {
|
|
402
1394
|
const el = document.createElementNS(SVG_NS, tag);
|
|
@@ -405,28 +1397,28 @@ function svgEl(tag, attrs) {
|
|
|
405
1397
|
}
|
|
406
1398
|
function renderEmpty(el, label) {
|
|
407
1399
|
const box = document.createElement("div");
|
|
408
|
-
box.className = "chart-empty";
|
|
409
|
-
box.textContent = label ?? "
|
|
1400
|
+
box.className = "icen-chart-empty";
|
|
1401
|
+
box.textContent = label ?? t("charts.noData");
|
|
410
1402
|
el.appendChild(box);
|
|
411
1403
|
}
|
|
412
1404
|
function legendItem(label, valueText, tone) {
|
|
413
1405
|
const row = document.createElement("div");
|
|
414
|
-
row.className = "chart-legend-item";
|
|
1406
|
+
row.className = "icen-chart-legend-item";
|
|
415
1407
|
const dot = document.createElement("span");
|
|
416
|
-
dot.className = "chart-legend-dot";
|
|
1408
|
+
dot.className = "icen-chart-legend-dot";
|
|
417
1409
|
if (tone) dot.style.setProperty("--chart-tone", toneVar(tone));
|
|
418
1410
|
const name = document.createElement("span");
|
|
419
|
-
name.className = "chart-legend-label";
|
|
1411
|
+
name.className = "icen-chart-legend-label";
|
|
420
1412
|
name.textContent = label;
|
|
421
1413
|
const val = document.createElement("span");
|
|
422
|
-
val.className = "chart-legend-value";
|
|
1414
|
+
val.className = "icen-chart-legend-value";
|
|
423
1415
|
val.textContent = valueText;
|
|
424
1416
|
row.append(dot, name, val);
|
|
425
1417
|
return row;
|
|
426
1418
|
}
|
|
427
1419
|
function labelsRow(labels) {
|
|
428
1420
|
const row = document.createElement("div");
|
|
429
|
-
row.className = "chart-labels";
|
|
1421
|
+
row.className = "icen-chart-labels";
|
|
430
1422
|
for (const label of labels) {
|
|
431
1423
|
const span = document.createElement("span");
|
|
432
1424
|
span.textContent = label;
|
|
@@ -441,85 +1433,90 @@ function normalizeSeriesInput(opts) {
|
|
|
441
1433
|
function toneOf(tone, seriesIndex) {
|
|
442
1434
|
if (typeof tone === "string") return toneVar(tone);
|
|
443
1435
|
if (typeof tone === "number") return paletteVar(tone);
|
|
444
|
-
return seriesIndex > 0 ? paletteVar(
|
|
1436
|
+
return seriesIndex > 0 ? paletteVar(seriesIndex % 6 + 1) : void 0;
|
|
445
1437
|
}
|
|
446
1438
|
var PALETTE_VARS = [
|
|
447
|
-
"var(--token-accent)",
|
|
448
|
-
"var(--token-accent-cold)",
|
|
449
|
-
"var(--token-success)",
|
|
450
|
-
"var(--token-warning)",
|
|
451
|
-
"var(--token-info)",
|
|
452
|
-
"color-mix(in srgb, var(--token-text) 50%, transparent)"
|
|
1439
|
+
"var(--icen-token-accent)",
|
|
1440
|
+
"var(--icen-token-accent-cold)",
|
|
1441
|
+
"var(--icen-token-success)",
|
|
1442
|
+
"var(--icen-token-warning)",
|
|
1443
|
+
"var(--icen-token-info)",
|
|
1444
|
+
"color-mix(in srgb, var(--icen-token-text) 50%, transparent)"
|
|
453
1445
|
];
|
|
454
1446
|
function paletteVar(index) {
|
|
455
1447
|
const i = ((Math.floor(index) - 1) % 6 + 6) % 6;
|
|
456
1448
|
return PALETTE_VARS[i];
|
|
457
1449
|
}
|
|
458
1450
|
function setMarkData(node, data) {
|
|
459
|
-
node.setAttribute("data-chart-mark", "1");
|
|
460
|
-
if (data.index != null) node.setAttribute("data-chart-index", String(data.index));
|
|
461
|
-
if (data.seriesIndex != null) node.setAttribute("data-chart-series", String(data.seriesIndex));
|
|
462
|
-
if (data.seriesName != null) node.setAttribute("data-chart-series-name", String(data.seriesName));
|
|
463
|
-
if (data.label != null) node.setAttribute("data-chart-label", String(data.label));
|
|
464
|
-
if (data.value != null) node.setAttribute("data-chart-value", String(data.value));
|
|
1451
|
+
node.setAttribute("data-icen-chart-mark", "1");
|
|
1452
|
+
if (data.index != null) node.setAttribute("data-icen-chart-index", String(data.index));
|
|
1453
|
+
if (data.seriesIndex != null) node.setAttribute("data-icen-chart-series", String(data.seriesIndex));
|
|
1454
|
+
if (data.seriesName != null) node.setAttribute("data-icen-chart-series-name", String(data.seriesName));
|
|
1455
|
+
if (data.label != null) node.setAttribute("data-icen-chart-label", String(data.label));
|
|
1456
|
+
if (data.value != null) node.setAttribute("data-icen-chart-value", String(data.value));
|
|
465
1457
|
}
|
|
466
1458
|
function copyMarkData(target, source) {
|
|
467
1459
|
for (const attr of Array.from(source.attributes)) {
|
|
468
|
-
if (attr.name.startsWith("data-chart-")) target.setAttribute(attr.name, attr.value);
|
|
1460
|
+
if (attr.name.startsWith("data-icen-chart-")) target.setAttribute(attr.name, attr.value);
|
|
469
1461
|
}
|
|
470
1462
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
function parseChartSvg(svg2) {
|
|
474
|
-
try {
|
|
475
|
-
const doc = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
476
|
-
const el = doc.documentElement;
|
|
477
|
-
return el && el.tagName.toLowerCase() === "svg" && !doc.querySelector("parsererror") ? document.importNode(el, true) : null;
|
|
478
|
-
} catch {
|
|
479
|
-
return null;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function withChrome(el, opts, hasLegend, paint, state) {
|
|
483
|
-
if (el.dataset.chartBody != null) {
|
|
1463
|
+
function withChrome(el, opts, hasLegend, paint, state, extras) {
|
|
1464
|
+
if (el.dataset.icenChartBody != null) {
|
|
484
1465
|
el.textContent = "";
|
|
485
1466
|
paint(el);
|
|
486
1467
|
return;
|
|
487
1468
|
}
|
|
488
1469
|
el.textContent = "";
|
|
489
1470
|
const body = document.createElement("div");
|
|
490
|
-
body.className = "chart-body";
|
|
491
|
-
body.dataset.
|
|
492
|
-
|
|
1471
|
+
body.className = "icen-chart-body";
|
|
1472
|
+
body.dataset.icenChartBody = "";
|
|
1473
|
+
const note = extras?.note ?? null;
|
|
1474
|
+
const onZoomReset = extras?.onZoomReset ?? null;
|
|
1475
|
+
if (!opts.title && !hasLegend && note == null && !onZoomReset) {
|
|
493
1476
|
el.appendChild(body);
|
|
494
1477
|
paint(body);
|
|
495
1478
|
return;
|
|
496
1479
|
}
|
|
497
1480
|
let hidden = state && state.hidden != null ? state.hidden : opts.legend === false;
|
|
498
1481
|
if (state) state.hidden = hidden;
|
|
499
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1482
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
500
1483
|
const head = document.createElement("div");
|
|
501
|
-
head.className = "chart-head";
|
|
1484
|
+
head.className = "icen-chart-head";
|
|
502
1485
|
const title = document.createElement("div");
|
|
503
|
-
title.className = "chart-title";
|
|
1486
|
+
title.className = "icen-chart-title";
|
|
504
1487
|
title.textContent = opts.title ?? "";
|
|
505
1488
|
if (!opts.title) title.setAttribute("aria-hidden", "true");
|
|
1489
|
+
if (note != null) {
|
|
1490
|
+
const noteEl = document.createElement("span");
|
|
1491
|
+
noteEl.className = "icen-chart-note";
|
|
1492
|
+
noteEl.textContent = note;
|
|
1493
|
+
head.appendChild(noteEl);
|
|
1494
|
+
}
|
|
1495
|
+
if (onZoomReset) {
|
|
1496
|
+
const chip = document.createElement("button");
|
|
1497
|
+
chip.type = "button";
|
|
1498
|
+
chip.className = "icen-chart-zoom-reset";
|
|
1499
|
+
chip.textContent = t("charts.resetZoom");
|
|
1500
|
+
chip.addEventListener("click", onZoomReset);
|
|
1501
|
+
head.appendChild(chip);
|
|
1502
|
+
}
|
|
506
1503
|
const eye = document.createElement("button");
|
|
507
1504
|
eye.type = "button";
|
|
508
|
-
eye.className = "chart-legend-eye";
|
|
509
|
-
eye.dataset.
|
|
1505
|
+
eye.className = "icen-chart-legend-eye";
|
|
1506
|
+
eye.dataset.icenChartLegendEye = "";
|
|
510
1507
|
const syncEye = () => {
|
|
511
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1508
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
512
1509
|
eye.setAttribute("aria-pressed", String(!nowHidden));
|
|
513
|
-
eye.setAttribute("aria-label", nowHidden ? "
|
|
514
|
-
eye.setAttribute("title", nowHidden ? "
|
|
515
|
-
const icon =
|
|
1510
|
+
eye.setAttribute("aria-label", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1511
|
+
eye.setAttribute("title", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1512
|
+
const icon = createIcon(nowHidden ? "eye-off" : "eye");
|
|
516
1513
|
if (icon) eye.replaceChildren(icon);
|
|
517
1514
|
};
|
|
518
1515
|
eye.addEventListener("click", () => {
|
|
519
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1516
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
520
1517
|
hidden = !nowHidden;
|
|
521
1518
|
if (state) state.hidden = hidden;
|
|
522
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1519
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
523
1520
|
syncEye();
|
|
524
1521
|
emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
|
|
525
1522
|
});
|
|
@@ -528,23 +1525,30 @@ function withChrome(el, opts, hasLegend, paint, state) {
|
|
|
528
1525
|
el.append(head, body);
|
|
529
1526
|
paint(body);
|
|
530
1527
|
}
|
|
1528
|
+
var hiddenLegendKeys = /* @__PURE__ */ new WeakMap();
|
|
531
1529
|
function toggleLegend(items, scope) {
|
|
532
1530
|
const legend = document.createElement("div");
|
|
533
|
-
legend.className = "chart-legend chart-legend--toggle";
|
|
1531
|
+
legend.className = "icen-chart-legend icen-chart-legend--toggle";
|
|
1532
|
+
const owner = scope instanceof Element ? scope.closest("[data-icen-chart-body]")?.parentElement ?? scope : null;
|
|
1533
|
+
const hidden = owner ? hiddenLegendKeys.get(owner) ?? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
|
|
1534
|
+
if (owner) hiddenLegendKeys.set(owner, hidden);
|
|
534
1535
|
for (const item of items) {
|
|
535
1536
|
const row = legendItem(item.label, "", item.tone);
|
|
536
|
-
row.classList.add("chart-legend-toggle-item");
|
|
1537
|
+
row.classList.add("icen-chart-legend-toggle-item");
|
|
537
1538
|
row.setAttribute("role", "button");
|
|
538
1539
|
row.tabIndex = 0;
|
|
539
|
-
row.
|
|
540
|
-
row.
|
|
541
|
-
|
|
542
|
-
const
|
|
1540
|
+
row.classList.toggle("is-off", hidden.has(item.key));
|
|
1541
|
+
row.setAttribute("aria-pressed", String(!hidden.has(item.key)));
|
|
1542
|
+
row.dataset.icenChartKey = item.key;
|
|
1543
|
+
const dot = row.querySelector(".icen-chart-legend-dot");
|
|
1544
|
+
const toneColor = toneOf(item.tone, item.si);
|
|
543
1545
|
if (dot && toneColor) dot.style.setProperty("--chart-tone", toneColor);
|
|
544
1546
|
const toggle = () => {
|
|
545
1547
|
const off = row.classList.toggle("is-off");
|
|
1548
|
+
if (off) hidden.add(item.key);
|
|
1549
|
+
else hidden.delete(item.key);
|
|
546
1550
|
row.setAttribute("aria-pressed", String(!off));
|
|
547
|
-
scope.querySelectorAll(`[data-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
1551
|
+
scope.querySelectorAll(`[data-icen-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
548
1552
|
m.classList.toggle("is-off", off);
|
|
549
1553
|
});
|
|
550
1554
|
emitIcen(legend, "icen:chart-legend-toggle", { key: item.key, seriesIndex: item.si, hidden: off });
|
|
@@ -559,8 +1563,9 @@ function toggleLegend(items, scope) {
|
|
|
559
1563
|
legend.appendChild(row);
|
|
560
1564
|
}
|
|
561
1565
|
for (const item of items) {
|
|
562
|
-
scope.querySelectorAll(`[data-chart-series="${item.si}"]`).forEach((m) => {
|
|
563
|
-
if (!m.hasAttribute("data-chart-key")) m.setAttribute("data-chart-key", item.key);
|
|
1566
|
+
scope.querySelectorAll(`[data-icen-chart-series="${item.si}"]`).forEach((m) => {
|
|
1567
|
+
if (!m.hasAttribute("data-icen-chart-key")) m.setAttribute("data-icen-chart-key", item.key);
|
|
1568
|
+
m.classList.toggle("is-off", hidden.has(item.key));
|
|
564
1569
|
});
|
|
565
1570
|
}
|
|
566
1571
|
return legend;
|
|
@@ -587,19 +1592,19 @@ function renderVBar(el, opts) {
|
|
|
587
1592
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
588
1593
|
}
|
|
589
1594
|
const wrap = document.createElement("div");
|
|
590
|
-
wrap.className = "chart-vbar";
|
|
1595
|
+
wrap.className = "icen-chart-vbar";
|
|
591
1596
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
592
1597
|
for (let i = 0; i < n; i++) {
|
|
593
1598
|
const track = document.createElement("div");
|
|
594
|
-
track.className = "chart-vbar-track";
|
|
1599
|
+
track.className = "icen-chart-vbar-track";
|
|
595
1600
|
if (seriesList.length > 1) {
|
|
596
|
-
track.classList.add("chart-vbar-track--multi");
|
|
597
|
-
if (opts.stacked) track.classList.add("chart-vbar-track--stacked");
|
|
1601
|
+
track.classList.add("icen-chart-vbar-track--multi");
|
|
1602
|
+
if (opts.stacked) track.classList.add("icen-chart-vbar-track--stacked");
|
|
598
1603
|
}
|
|
599
1604
|
seriesList.forEach((s, si) => {
|
|
600
1605
|
const value = s.values[i] ?? 0;
|
|
601
1606
|
const bar = document.createElement("div");
|
|
602
|
-
bar.className = "chart-vbar-bar";
|
|
1607
|
+
bar.className = "icen-chart-vbar-bar";
|
|
603
1608
|
const height = value > 0 ? Math.max(6, value / max * 100) : 0;
|
|
604
1609
|
bar.style.height = `${height}%`;
|
|
605
1610
|
const toneColor = toneOf(s.tone, si);
|
|
@@ -617,7 +1622,7 @@ function renderVBar(el, opts) {
|
|
|
617
1622
|
wrap.appendChild(track);
|
|
618
1623
|
}
|
|
619
1624
|
body.append(wrap, labelsRow(labelsUsed));
|
|
620
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone, si })), wrap));
|
|
1625
|
+
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));
|
|
621
1626
|
});
|
|
622
1627
|
attachChartInteraction(el, "vbar");
|
|
623
1628
|
return el;
|
|
@@ -634,22 +1639,22 @@ function renderHBar(el, opts) {
|
|
|
634
1639
|
const values = opts.values.slice(0, n);
|
|
635
1640
|
const max = maxOf(values);
|
|
636
1641
|
const wrap = document.createElement("div");
|
|
637
|
-
wrap.className = "chart-hbar";
|
|
1642
|
+
wrap.className = "icen-chart-hbar";
|
|
638
1643
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
639
1644
|
values.forEach((value, i) => {
|
|
640
1645
|
const row = document.createElement("div");
|
|
641
|
-
row.className = "chart-hbar-row";
|
|
1646
|
+
row.className = "icen-chart-hbar-row";
|
|
642
1647
|
const label = document.createElement("span");
|
|
643
|
-
label.className = "chart-hbar-label";
|
|
1648
|
+
label.className = "icen-chart-hbar-label";
|
|
644
1649
|
label.textContent = labels[i] ?? "";
|
|
645
1650
|
const track = document.createElement("div");
|
|
646
|
-
track.className = "chart-hbar-track";
|
|
1651
|
+
track.className = "icen-chart-hbar-track";
|
|
647
1652
|
const bar = document.createElement("div");
|
|
648
|
-
bar.className = "chart-hbar-bar";
|
|
1653
|
+
bar.className = "icen-chart-hbar-bar";
|
|
649
1654
|
bar.style.width = value > 0 ? `${Math.max(2, value / max * 100)}%` : "0%";
|
|
650
1655
|
setMarkData(bar, { index: i, label: labels[i] ?? "", value });
|
|
651
1656
|
const val = document.createElement("span");
|
|
652
|
-
val.className = "chart-hbar-value";
|
|
1657
|
+
val.className = "icen-chart-hbar-value";
|
|
653
1658
|
val.textContent = fmt(opts, value);
|
|
654
1659
|
track.appendChild(bar);
|
|
655
1660
|
row.append(label, track, val);
|
|
@@ -669,10 +1674,10 @@ function renderStack(el, opts) {
|
|
|
669
1674
|
return;
|
|
670
1675
|
}
|
|
671
1676
|
const bar = document.createElement("div");
|
|
672
|
-
bar.className = "chart-stack";
|
|
1677
|
+
bar.className = "icen-chart-stack";
|
|
673
1678
|
for (const [segIndex, seg] of opts.segments.entries()) {
|
|
674
1679
|
const s = document.createElement("div");
|
|
675
|
-
s.className = "chart-stack-seg";
|
|
1680
|
+
s.className = "icen-chart-stack-seg";
|
|
676
1681
|
s.style.width = `${seg.value / total * 100}%`;
|
|
677
1682
|
if (seg.tone) s.style.setProperty("--chart-tone", toneVar(seg.tone));
|
|
678
1683
|
s.setAttribute("title", `${seg.label}: ${fmt(opts, seg.value)}`);
|
|
@@ -680,7 +1685,7 @@ function renderStack(el, opts) {
|
|
|
680
1685
|
bar.appendChild(s);
|
|
681
1686
|
}
|
|
682
1687
|
const legend = document.createElement("div");
|
|
683
|
-
legend.className = "chart-legend";
|
|
1688
|
+
legend.className = "icen-chart-legend";
|
|
684
1689
|
for (const seg of opts.segments) {
|
|
685
1690
|
legend.appendChild(legendItem(seg.label, fmt(opts, seg.value), seg.tone));
|
|
686
1691
|
}
|
|
@@ -700,15 +1705,15 @@ function renderDonut(el, opts) {
|
|
|
700
1705
|
const radius = 42;
|
|
701
1706
|
const circumference = 2 * Math.PI * radius;
|
|
702
1707
|
const wrap = document.createElement("div");
|
|
703
|
-
wrap.className = "chart-donut";
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
1708
|
+
wrap.className = "icen-chart-donut";
|
|
1709
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.donut")) });
|
|
1710
|
+
svg.style.transform = "rotate(-90deg)";
|
|
1711
|
+
svg.appendChild(svgEl("circle", {
|
|
707
1712
|
cx: "60",
|
|
708
1713
|
cy: "60",
|
|
709
1714
|
r: String(radius),
|
|
710
1715
|
fill: "none",
|
|
711
|
-
stroke: "var(--token-line-soft)",
|
|
1716
|
+
stroke: "var(--icen-token-line-soft)",
|
|
712
1717
|
"stroke-width": "14"
|
|
713
1718
|
}));
|
|
714
1719
|
let offset = 0;
|
|
@@ -726,15 +1731,15 @@ function renderDonut(el, opts) {
|
|
|
726
1731
|
"stroke-linecap": "butt"
|
|
727
1732
|
});
|
|
728
1733
|
setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
|
|
729
|
-
|
|
1734
|
+
svg.appendChild(arc);
|
|
730
1735
|
offset += dash;
|
|
731
1736
|
});
|
|
732
1737
|
const legend = document.createElement("div");
|
|
733
|
-
legend.className = "chart-legend";
|
|
1738
|
+
legend.className = "icen-chart-legend";
|
|
734
1739
|
for (const seg of opts.segments) {
|
|
735
1740
|
legend.appendChild(legendItem(seg.label, `${Math.round(seg.value / total * 100)}%`, seg.tone));
|
|
736
1741
|
}
|
|
737
|
-
wrap.append(
|
|
1742
|
+
wrap.append(svg, legend);
|
|
738
1743
|
body.appendChild(wrap);
|
|
739
1744
|
});
|
|
740
1745
|
attachChartInteraction(el, "donut");
|
|
@@ -752,23 +1757,23 @@ function renderLine(el, opts) {
|
|
|
752
1757
|
return;
|
|
753
1758
|
}
|
|
754
1759
|
const labelsUsed = labels.slice(0, n);
|
|
755
|
-
const width =
|
|
1760
|
+
const width = fluidWidth(body);
|
|
756
1761
|
const height = 150;
|
|
757
1762
|
const pad = 14;
|
|
758
1763
|
let max = 1;
|
|
759
1764
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
760
1765
|
const wrap = document.createElement("div");
|
|
761
|
-
wrap.className = "chart-line";
|
|
762
|
-
const
|
|
1766
|
+
wrap.className = "icen-chart-line";
|
|
1767
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
|
|
763
1768
|
const defs = svgEl("defs", {});
|
|
764
1769
|
for (let i = 0; i < 4; i++) {
|
|
765
1770
|
const y = pad + i * (height - pad * 2) / 3;
|
|
766
|
-
|
|
1771
|
+
svg.appendChild(svgEl("line", {
|
|
767
1772
|
x1: String(pad),
|
|
768
1773
|
x2: String(width - pad),
|
|
769
1774
|
y1: String(y),
|
|
770
1775
|
y2: String(y),
|
|
771
|
-
stroke: "var(--token-line-soft)",
|
|
1776
|
+
stroke: "var(--icen-token-line-soft)",
|
|
772
1777
|
"stroke-width": "1"
|
|
773
1778
|
}));
|
|
774
1779
|
}
|
|
@@ -798,7 +1803,7 @@ function renderLine(el, opts) {
|
|
|
798
1803
|
if (seriesList.length > 1) {
|
|
799
1804
|
setMarkData(areaPath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values.reduce((a, b) => a + b, 0) });
|
|
800
1805
|
}
|
|
801
|
-
|
|
1806
|
+
svg.appendChild(areaPath);
|
|
802
1807
|
}
|
|
803
1808
|
const linePath = svgEl("path", {
|
|
804
1809
|
d: line,
|
|
@@ -809,16 +1814,16 @@ function renderLine(el, opts) {
|
|
|
809
1814
|
"stroke-linejoin": "round"
|
|
810
1815
|
});
|
|
811
1816
|
const lineTitle = svgEl("title", {});
|
|
812
|
-
lineTitle.textContent = s.name || "
|
|
1817
|
+
lineTitle.textContent = s.name || t("charts.value");
|
|
813
1818
|
linePath.appendChild(lineTitle);
|
|
814
1819
|
setMarkData(linePath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values[values.length - 1] ?? 0 });
|
|
815
|
-
|
|
1820
|
+
svg.appendChild(linePath);
|
|
816
1821
|
for (const p of points) {
|
|
817
1822
|
const dot = svgEl("circle", {
|
|
818
1823
|
cx: p.x.toFixed(1),
|
|
819
1824
|
cy: p.y.toFixed(1),
|
|
820
1825
|
r: "3",
|
|
821
|
-
fill: "var(--token-card)",
|
|
1826
|
+
fill: "var(--icen-token-card)",
|
|
822
1827
|
stroke: tone,
|
|
823
1828
|
"stroke-width": "2"
|
|
824
1829
|
});
|
|
@@ -832,23 +1837,24 @@ function renderLine(el, opts) {
|
|
|
832
1837
|
label: p.label,
|
|
833
1838
|
value: p.value
|
|
834
1839
|
});
|
|
835
|
-
|
|
1840
|
+
svg.appendChild(dot);
|
|
836
1841
|
const hit = svgEl("circle", {
|
|
837
1842
|
cx: p.x.toFixed(1),
|
|
838
1843
|
cy: p.y.toFixed(1),
|
|
839
1844
|
r: "8",
|
|
840
1845
|
fill: "transparent",
|
|
841
|
-
"data-chart-hit": "1"
|
|
1846
|
+
"data-icen-chart-hit": "1"
|
|
842
1847
|
});
|
|
843
1848
|
copyMarkData(hit, dot);
|
|
844
|
-
|
|
1849
|
+
svg.appendChild(hit);
|
|
845
1850
|
}
|
|
846
1851
|
});
|
|
847
|
-
if (defs.firstChild)
|
|
848
|
-
wrap.append(
|
|
1852
|
+
if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
|
|
1853
|
+
wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
|
|
849
1854
|
body.appendChild(wrap);
|
|
850
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone, si })), wrap));
|
|
1855
|
+
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));
|
|
851
1856
|
});
|
|
1857
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
|
|
852
1858
|
attachChartInteraction(el, "line");
|
|
853
1859
|
return el;
|
|
854
1860
|
}
|
|
@@ -880,30 +1886,30 @@ function renderRadar(el, opts) {
|
|
|
880
1886
|
y: cy + r * Math.sin(angleOf(i))
|
|
881
1887
|
});
|
|
882
1888
|
const wrap = document.createElement("div");
|
|
883
|
-
wrap.className = "chart-radar";
|
|
884
|
-
const
|
|
1889
|
+
wrap.className = "icen-chart-radar";
|
|
1890
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${size} ${size}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.radar")) });
|
|
885
1891
|
for (let lv = 1; lv <= levels; lv++) {
|
|
886
1892
|
const r = radius * lv / levels;
|
|
887
1893
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
888
1894
|
const p = pointAt(i, r);
|
|
889
1895
|
return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;
|
|
890
1896
|
}).join(" ");
|
|
891
|
-
|
|
1897
|
+
svg.appendChild(svgEl("polygon", {
|
|
892
1898
|
points: pts,
|
|
893
1899
|
fill: "none",
|
|
894
|
-
stroke: "var(--token-line-soft)",
|
|
1900
|
+
stroke: "var(--icen-token-line-soft)",
|
|
895
1901
|
"stroke-width": "1",
|
|
896
1902
|
"stroke-dasharray": lv === levels ? "0" : "3 2"
|
|
897
1903
|
}));
|
|
898
1904
|
}
|
|
899
1905
|
for (let i = 0; i < n; i++) {
|
|
900
1906
|
const edge = pointAt(i, radius);
|
|
901
|
-
|
|
1907
|
+
svg.appendChild(svgEl("line", {
|
|
902
1908
|
x1: String(cx),
|
|
903
1909
|
y1: String(cy),
|
|
904
1910
|
x2: edge.x.toFixed(1),
|
|
905
1911
|
y2: edge.y.toFixed(1),
|
|
906
|
-
stroke: "var(--token-line-soft)",
|
|
1912
|
+
stroke: "var(--icen-token-line-soft)",
|
|
907
1913
|
"stroke-width": "1"
|
|
908
1914
|
}));
|
|
909
1915
|
const labelP = pointAt(i, radius + 14);
|
|
@@ -913,14 +1919,14 @@ function renderRadar(el, opts) {
|
|
|
913
1919
|
"text-anchor": "middle",
|
|
914
1920
|
"dominant-baseline": "middle",
|
|
915
1921
|
"font-size": "9",
|
|
916
|
-
fill: "var(--token-text-muted)"
|
|
1922
|
+
fill: "var(--icen-token-text-muted)"
|
|
917
1923
|
});
|
|
918
1924
|
txt.textContent = axes[i] ?? "";
|
|
919
|
-
|
|
1925
|
+
svg.appendChild(txt);
|
|
920
1926
|
}
|
|
921
1927
|
const legendItems = [];
|
|
922
1928
|
opts.series.forEach((s, si) => {
|
|
923
|
-
const tone = toneVar(s.tone);
|
|
1929
|
+
const tone = toneOf(s.tone, si) ?? toneVar(s.tone);
|
|
924
1930
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
925
1931
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
926
1932
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -938,7 +1944,7 @@ function renderRadar(el, opts) {
|
|
|
938
1944
|
title.textContent = `${s.name}: ${s.values.map((v) => fmt(opts, v)).join(" / ")}`;
|
|
939
1945
|
polyFill.appendChild(title);
|
|
940
1946
|
setMarkData(polyFill, { seriesIndex: si, seriesName: s.name || void 0, label: s.name, value: s.values.reduce((a, b) => a + (b || 0), 0) });
|
|
941
|
-
|
|
1947
|
+
svg.appendChild(polyFill);
|
|
942
1948
|
for (let i = 0; i < n; i++) {
|
|
943
1949
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
944
1950
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -946,18 +1952,19 @@ function renderRadar(el, opts) {
|
|
|
946
1952
|
cx: p.x.toFixed(1),
|
|
947
1953
|
cy: p.y.toFixed(1),
|
|
948
1954
|
r: "2.5",
|
|
949
|
-
fill: "var(--token-card)",
|
|
1955
|
+
fill: "var(--icen-token-card)",
|
|
950
1956
|
stroke: tone,
|
|
951
1957
|
"stroke-width": "1.5"
|
|
952
1958
|
});
|
|
953
1959
|
setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
|
|
954
|
-
|
|
1960
|
+
svg.appendChild(dot);
|
|
955
1961
|
}
|
|
956
|
-
legendItems.push({ key: s.name ||
|
|
1962
|
+
legendItems.push({ key: s.name || t("charts.seriesName", { p0: si + 1 }), label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
|
|
957
1963
|
});
|
|
958
|
-
|
|
959
|
-
wrap.append(svg2, ...legend ? [legend] : []);
|
|
1964
|
+
wrap.appendChild(svg);
|
|
960
1965
|
body.appendChild(wrap);
|
|
1966
|
+
const legend = opts.series.length > 1 ? toggleLegend(legendItems, wrap) : null;
|
|
1967
|
+
if (legend) wrap.appendChild(legend);
|
|
961
1968
|
});
|
|
962
1969
|
attachChartInteraction(el, "radar");
|
|
963
1970
|
return el;
|
|
@@ -990,23 +1997,23 @@ function padFirstWeek(grid, firstDate, weekStart) {
|
|
|
990
1997
|
const pad = (first.getDay() + 7 - weekStart) % 7;
|
|
991
1998
|
for (let i = 0; i < pad; i++) {
|
|
992
1999
|
const blank = document.createElement("span");
|
|
993
|
-
blank.className = "chart-heatmap-cell is-blank";
|
|
2000
|
+
blank.className = "icen-chart-heatmap-cell is-blank";
|
|
994
2001
|
grid.appendChild(blank);
|
|
995
2002
|
}
|
|
996
2003
|
return pad;
|
|
997
2004
|
}
|
|
998
2005
|
function heatmapLegend(labels) {
|
|
999
2006
|
const legend = document.createElement("div");
|
|
1000
|
-
legend.className = "chart-heatmap-legend";
|
|
2007
|
+
legend.className = "icen-chart-heatmap-legend";
|
|
1001
2008
|
const less = document.createElement("span");
|
|
1002
|
-
less.textContent = labels?.less ?? "
|
|
2009
|
+
less.textContent = labels?.less ?? t("charts.few");
|
|
1003
2010
|
const more = document.createElement("span");
|
|
1004
|
-
more.textContent = labels?.more ?? "
|
|
2011
|
+
more.textContent = labels?.more ?? t("charts.many");
|
|
1005
2012
|
legend.appendChild(less);
|
|
1006
2013
|
for (let lv = 0; lv <= 4; lv++) {
|
|
1007
2014
|
const cell = document.createElement("span");
|
|
1008
|
-
cell.className = "chart-heatmap-cell";
|
|
1009
|
-
cell.dataset.
|
|
2015
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2016
|
+
cell.dataset.icenLevel = String(lv);
|
|
1010
2017
|
legend.appendChild(cell);
|
|
1011
2018
|
}
|
|
1012
2019
|
legend.appendChild(more);
|
|
@@ -1033,16 +2040,17 @@ function renderHeatmap(el, opts) {
|
|
|
1033
2040
|
if (entries.length > weeks * 7) entries = entries.slice(entries.length - weeks * 7);
|
|
1034
2041
|
const max = maxOf(entries.map((e) => e.value));
|
|
1035
2042
|
const wrap = document.createElement("div");
|
|
1036
|
-
wrap.className = "chart-heatmap";
|
|
2043
|
+
wrap.className = "icen-chart-heatmap";
|
|
1037
2044
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1038
2045
|
const grid = document.createElement("div");
|
|
1039
|
-
grid.className = "chart-heatmap-grid";
|
|
2046
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1040
2047
|
grid.setAttribute("role", "img");
|
|
2048
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1041
2049
|
padFirstWeek(grid, entries[0].date, opts.weekStart === 0 ? 0 : 1);
|
|
1042
2050
|
for (const [i, entry] of entries.entries()) {
|
|
1043
2051
|
const cell = document.createElement("span");
|
|
1044
|
-
cell.className = "chart-heatmap-cell";
|
|
1045
|
-
cell.dataset.
|
|
2052
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2053
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1046
2054
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1047
2055
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1048
2056
|
grid.appendChild(cell);
|
|
@@ -1077,16 +2085,16 @@ function renderSparkline(el, opts) {
|
|
|
1077
2085
|
const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
|
|
1078
2086
|
const gradientId = `icen-chart-line-${++lineGradientSeq}`;
|
|
1079
2087
|
const wrap = document.createElement("div");
|
|
1080
|
-
wrap.className = "chart-sparkline";
|
|
1081
|
-
const
|
|
2088
|
+
wrap.className = "icen-chart-sparkline";
|
|
2089
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.sparkline")) });
|
|
1082
2090
|
const defs = svgEl("defs", {});
|
|
1083
2091
|
const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
|
|
1084
2092
|
gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.28" }));
|
|
1085
2093
|
gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.02" }));
|
|
1086
2094
|
defs.appendChild(gradient);
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
2095
|
+
svg.appendChild(defs);
|
|
2096
|
+
svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
|
|
2097
|
+
svg.appendChild(svgEl("path", {
|
|
1090
2098
|
d: line,
|
|
1091
2099
|
fill: "none",
|
|
1092
2100
|
stroke: tone,
|
|
@@ -1098,15 +2106,15 @@ function renderSparkline(el, opts) {
|
|
|
1098
2106
|
cx: last.x.toFixed(1),
|
|
1099
2107
|
cy: last.y.toFixed(1),
|
|
1100
2108
|
r: "2.4",
|
|
1101
|
-
fill: "var(--token-card)",
|
|
2109
|
+
fill: "var(--icen-token-card)",
|
|
1102
2110
|
stroke: tone,
|
|
1103
2111
|
"stroke-width": "1.6"
|
|
1104
2112
|
});
|
|
1105
2113
|
const title = svgEl("title", {});
|
|
1106
2114
|
title.textContent = fmt(opts, last.value);
|
|
1107
2115
|
dot.appendChild(title);
|
|
1108
|
-
|
|
1109
|
-
wrap.appendChild(
|
|
2116
|
+
svg.appendChild(dot);
|
|
2117
|
+
wrap.appendChild(svg);
|
|
1110
2118
|
body.appendChild(wrap);
|
|
1111
2119
|
});
|
|
1112
2120
|
attachChartInteraction(el, "sparkline");
|
|
@@ -1120,20 +2128,20 @@ function renderGauge(el, opts) {
|
|
|
1120
2128
|
const radius = 42;
|
|
1121
2129
|
const circumference = 2 * Math.PI * radius;
|
|
1122
2130
|
const wrap = document.createElement("div");
|
|
1123
|
-
wrap.className = "chart-gauge";
|
|
2131
|
+
wrap.className = "icen-chart-gauge";
|
|
1124
2132
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
2133
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.label, t("charts.type.gauge")) });
|
|
2134
|
+
svg.style.transform = "rotate(-90deg)";
|
|
2135
|
+
svg.appendChild(svgEl("circle", {
|
|
1128
2136
|
cx: "60",
|
|
1129
2137
|
cy: "60",
|
|
1130
2138
|
r: String(radius),
|
|
1131
2139
|
fill: "none",
|
|
1132
|
-
stroke: "var(--token-line-soft)",
|
|
2140
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1133
2141
|
"stroke-width": "10"
|
|
1134
2142
|
}));
|
|
1135
2143
|
const dash = ratio * circumference;
|
|
1136
|
-
|
|
2144
|
+
svg.appendChild(svgEl("circle", {
|
|
1137
2145
|
cx: "60",
|
|
1138
2146
|
cy: "60",
|
|
1139
2147
|
r: String(radius),
|
|
@@ -1144,18 +2152,18 @@ function renderGauge(el, opts) {
|
|
|
1144
2152
|
"stroke-linecap": "round"
|
|
1145
2153
|
}));
|
|
1146
2154
|
const center = document.createElement("div");
|
|
1147
|
-
center.className = "chart-gauge-center";
|
|
2155
|
+
center.className = "icen-chart-gauge-center";
|
|
1148
2156
|
const val = document.createElement("span");
|
|
1149
|
-
val.className = "chart-gauge-value";
|
|
2157
|
+
val.className = "icen-chart-gauge-value";
|
|
1150
2158
|
val.textContent = opts.formatValue ? opts.formatValue(opts.value) : `${Math.round(ratio * 100)}%`;
|
|
1151
2159
|
center.appendChild(val);
|
|
1152
2160
|
if (opts.label) {
|
|
1153
2161
|
const lab = document.createElement("span");
|
|
1154
|
-
lab.className = "chart-gauge-label";
|
|
2162
|
+
lab.className = "icen-chart-gauge-label";
|
|
1155
2163
|
lab.textContent = opts.label;
|
|
1156
2164
|
center.appendChild(lab);
|
|
1157
2165
|
}
|
|
1158
|
-
wrap.append(
|
|
2166
|
+
wrap.append(svg, center);
|
|
1159
2167
|
el.appendChild(wrap);
|
|
1160
2168
|
attachChartInteraction(el, "gauge");
|
|
1161
2169
|
return el;
|
|
@@ -1173,19 +2181,20 @@ function renderCalendar(el, opts) {
|
|
|
1173
2181
|
return;
|
|
1174
2182
|
}
|
|
1175
2183
|
const wrap = document.createElement("div");
|
|
1176
|
-
wrap.className = "chart-calendar";
|
|
2184
|
+
wrap.className = "icen-chart-calendar";
|
|
1177
2185
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1178
2186
|
const weekStart = opts.weekStart === 0 ? 0 : 1;
|
|
1179
|
-
const weekdayDefaults =
|
|
2187
|
+
const weekdayDefaults = t("charts.calendarWeekdays");
|
|
1180
2188
|
const weekdayLabels = opts.labels?.weekdays ?? weekdayDefaults.map((_, i) => weekdayLabelAt(weekdayDefaults, (weekStart + i) % 7));
|
|
1181
|
-
const monthLabel = (m) => opts.labels?.months?.[m] ??
|
|
2189
|
+
const monthLabel = (m) => opts.labels?.months?.[m] ?? t("charts.monthLabel", { p0: m + 1 });
|
|
1182
2190
|
const grid = document.createElement("div");
|
|
1183
|
-
grid.className = "chart-heatmap-grid";
|
|
2191
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1184
2192
|
grid.setAttribute("role", "img");
|
|
2193
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1185
2194
|
const months = document.createElement("div");
|
|
1186
|
-
months.className = "chart-calendar-months";
|
|
2195
|
+
months.className = "icen-chart-calendar-months";
|
|
1187
2196
|
const weekdayRow = document.createElement("div");
|
|
1188
|
-
weekdayRow.className = "chart-calendar-weekdays";
|
|
2197
|
+
weekdayRow.className = "icen-chart-calendar-weekdays";
|
|
1189
2198
|
weekdayLabels.forEach((w) => {
|
|
1190
2199
|
const s = document.createElement("span");
|
|
1191
2200
|
s.textContent = w;
|
|
@@ -1200,14 +2209,14 @@ function renderCalendar(el, opts) {
|
|
|
1200
2209
|
if (d.getMonth() !== lastMonth) {
|
|
1201
2210
|
lastMonth = d.getMonth();
|
|
1202
2211
|
const label = document.createElement("span");
|
|
1203
|
-
label.className = "chart-calendar-month";
|
|
2212
|
+
label.className = "icen-chart-calendar-month";
|
|
1204
2213
|
label.textContent = monthLabel(d.getMonth());
|
|
1205
2214
|
label.style.setProperty("--col", String(col));
|
|
1206
2215
|
months.appendChild(label);
|
|
1207
2216
|
}
|
|
1208
2217
|
const cell = document.createElement("span");
|
|
1209
|
-
cell.className = "chart-heatmap-cell";
|
|
1210
|
-
cell.dataset.
|
|
2218
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2219
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1211
2220
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1212
2221
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1213
2222
|
grid.appendChild(cell);
|
|
@@ -1229,7 +2238,7 @@ function renderScatter(el, opts) {
|
|
|
1229
2238
|
renderEmpty(body, opts.emptyLabel);
|
|
1230
2239
|
return;
|
|
1231
2240
|
}
|
|
1232
|
-
const width =
|
|
2241
|
+
const width = fluidWidth(body);
|
|
1233
2242
|
const height = 220;
|
|
1234
2243
|
const pad = 30;
|
|
1235
2244
|
let xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, sMax = 0;
|
|
@@ -1244,19 +2253,19 @@ function renderScatter(el, opts) {
|
|
|
1244
2253
|
if (yMax === yMin) yMax = yMin + 1;
|
|
1245
2254
|
const rOf = (size) => size && sMax > 0 ? 3 + size / sMax * 7 : 4;
|
|
1246
2255
|
const wrap = document.createElement("div");
|
|
1247
|
-
wrap.className = "chart-scatter";
|
|
2256
|
+
wrap.className = "icen-chart-scatter";
|
|
1248
2257
|
const tone = toneVar(opts.tone);
|
|
1249
|
-
const
|
|
2258
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.scatter")) });
|
|
1250
2259
|
const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
|
|
1251
2260
|
const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
|
|
1252
2261
|
for (let i = 0; i <= 3; i++) {
|
|
1253
2262
|
const y = pad + i * (height - pad * 2) / 3;
|
|
1254
|
-
|
|
2263
|
+
svg.appendChild(svgEl("line", {
|
|
1255
2264
|
x1: String(pad),
|
|
1256
2265
|
x2: String(width - pad),
|
|
1257
2266
|
y1: String(y),
|
|
1258
2267
|
y2: String(y),
|
|
1259
|
-
stroke: "var(--token-line-soft)",
|
|
2268
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1260
2269
|
"stroke-width": "1"
|
|
1261
2270
|
}));
|
|
1262
2271
|
const tv = yMin + (yMax - yMin) * (3 - i) / 3;
|
|
@@ -1265,19 +2274,19 @@ function renderScatter(el, opts) {
|
|
|
1265
2274
|
y: String(y + 3),
|
|
1266
2275
|
"text-anchor": "end",
|
|
1267
2276
|
"font-size": "8",
|
|
1268
|
-
fill: "var(--token-text-faint)"
|
|
2277
|
+
fill: "var(--icen-token-text-faint)"
|
|
1269
2278
|
});
|
|
1270
2279
|
txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
|
|
1271
|
-
|
|
2280
|
+
svg.appendChild(txt);
|
|
1272
2281
|
}
|
|
1273
2282
|
for (let i = 0; i <= 4; i++) {
|
|
1274
2283
|
const x = pad + i * (width - pad * 2) / 4;
|
|
1275
|
-
|
|
2284
|
+
svg.appendChild(svgEl("line", {
|
|
1276
2285
|
x1: String(x),
|
|
1277
2286
|
x2: String(x),
|
|
1278
2287
|
y1: String(pad),
|
|
1279
2288
|
y2: String(height - pad),
|
|
1280
|
-
stroke: "var(--token-line-soft)",
|
|
2289
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1281
2290
|
"stroke-width": "1",
|
|
1282
2291
|
"stroke-dasharray": "2 3"
|
|
1283
2292
|
}));
|
|
@@ -1287,20 +2296,20 @@ function renderScatter(el, opts) {
|
|
|
1287
2296
|
y: String(height - pad + 12),
|
|
1288
2297
|
"text-anchor": "middle",
|
|
1289
2298
|
"font-size": "8",
|
|
1290
|
-
fill: "var(--token-text-faint)"
|
|
2299
|
+
fill: "var(--icen-token-text-faint)"
|
|
1291
2300
|
});
|
|
1292
2301
|
txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
|
|
1293
|
-
|
|
2302
|
+
svg.appendChild(txt);
|
|
1294
2303
|
}
|
|
1295
2304
|
if (opts.yLabel) {
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1298
|
-
|
|
2305
|
+
const t2 = svgEl("text", { x: "10", y: String(pad - 10), "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2306
|
+
t2.textContent = opts.yLabel;
|
|
2307
|
+
svg.appendChild(t2);
|
|
1299
2308
|
}
|
|
1300
2309
|
if (opts.xLabel) {
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
|
|
2310
|
+
const t2 = svgEl("text", { x: String(width - pad), y: String(pad - 10), "text-anchor": "end", "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2311
|
+
t2.textContent = opts.xLabel;
|
|
2312
|
+
svg.appendChild(t2);
|
|
1304
2313
|
}
|
|
1305
2314
|
pts.forEach((p, i) => {
|
|
1306
2315
|
const c = svgEl("circle", {
|
|
@@ -1317,11 +2326,12 @@ function renderScatter(el, opts) {
|
|
|
1317
2326
|
c.appendChild(title);
|
|
1318
2327
|
setMarkData(c, { index: i, label: p.label ?? `#${i + 1}`, value: p.y });
|
|
1319
2328
|
c.dataset.chartX = String(p.x);
|
|
1320
|
-
|
|
2329
|
+
svg.appendChild(c);
|
|
1321
2330
|
});
|
|
1322
|
-
wrap.appendChild(
|
|
2331
|
+
wrap.appendChild(svg);
|
|
1323
2332
|
body.appendChild(wrap);
|
|
1324
2333
|
});
|
|
2334
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderScatter(el, opts));
|
|
1325
2335
|
attachChartInteraction(el, "scatter");
|
|
1326
2336
|
return el;
|
|
1327
2337
|
}
|
|
@@ -1371,7 +2381,7 @@ function pivotData(spec) {
|
|
|
1371
2381
|
const labels = [];
|
|
1372
2382
|
const seenLabel = /* @__PURE__ */ new Set();
|
|
1373
2383
|
const hasSeries = data.some((r) => r[seriesField] != null && r[seriesField] !== "");
|
|
1374
|
-
const seriesNames = [];
|
|
2384
|
+
const seriesNames = hasSeries ? [] : [""];
|
|
1375
2385
|
const seenSeries = /* @__PURE__ */ new Set();
|
|
1376
2386
|
for (const r of data) {
|
|
1377
2387
|
const l = str(r[labelField]);
|
|
@@ -1460,8 +2470,8 @@ function normalizeChartSpec(raw) {
|
|
|
1460
2470
|
const s = src;
|
|
1461
2471
|
const spec = {};
|
|
1462
2472
|
if (typeof s.type === "string") {
|
|
1463
|
-
const
|
|
1464
|
-
spec.type = CHART_TYPE_ALIASES[
|
|
2473
|
+
const t2 = s.type.trim().toLowerCase();
|
|
2474
|
+
spec.type = CHART_TYPE_ALIASES[t2] ?? t2;
|
|
1465
2475
|
}
|
|
1466
2476
|
for (const k of ["title", "tone", "emptyLabel"]) {
|
|
1467
2477
|
if (typeof s[k] === "string") spec[k] = s[k];
|
|
@@ -1483,7 +2493,7 @@ function normalizeChartSpec(raw) {
|
|
|
1483
2493
|
if (Array.isArray(s.series)) {
|
|
1484
2494
|
const series = s.series.filter((v) => !!v && typeof v === "object").map((v, i) => {
|
|
1485
2495
|
const values = Array.isArray(v.values) ? v.values.map(toNum).filter((n) => n != null) : [];
|
|
1486
|
-
const sv = { name: String(v.name ??
|
|
2496
|
+
const sv = { name: String(v.name ?? t("charts.seriesName", { p0: i + 1 })), values };
|
|
1487
2497
|
const tone = v.tone;
|
|
1488
2498
|
if (typeof tone === "string" || typeof tone === "number") sv.tone = tone;
|
|
1489
2499
|
return sv;
|
|
@@ -1518,6 +2528,40 @@ function normalizeChartSpec(raw) {
|
|
|
1518
2528
|
}
|
|
1519
2529
|
spec.format = format;
|
|
1520
2530
|
}
|
|
2531
|
+
if (typeof s.downsample === "boolean") spec.downsample = s.downsample;
|
|
2532
|
+
else {
|
|
2533
|
+
const n = toNum(s.downsample);
|
|
2534
|
+
if (n != null) spec.downsample = n;
|
|
2535
|
+
}
|
|
2536
|
+
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2537
|
+
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2538
|
+
if (Array.isArray(s.marks)) {
|
|
2539
|
+
const marks = [];
|
|
2540
|
+
for (const raw2 of s.marks) {
|
|
2541
|
+
if (!raw2 || typeof raw2 !== "object" || Array.isArray(raw2)) continue;
|
|
2542
|
+
const m = raw2;
|
|
2543
|
+
if (m.type === "line") {
|
|
2544
|
+
if (m.axis !== "x" && m.axis !== "y") continue;
|
|
2545
|
+
if (typeof m.value !== "number" && typeof m.value !== "string") continue;
|
|
2546
|
+
const mark = { type: "line", axis: m.axis, value: m.value };
|
|
2547
|
+
if (typeof m.label === "string" && m.label !== "") mark.label = m.label;
|
|
2548
|
+
if (m.tone === "success" || m.tone === "warning" || m.tone === "error" || m.tone === "info") {
|
|
2549
|
+
mark.tone = m.tone;
|
|
2550
|
+
}
|
|
2551
|
+
marks.push(mark);
|
|
2552
|
+
} else if (m.type === "point") {
|
|
2553
|
+
if (typeof m.label !== "string" || m.label === "") continue;
|
|
2554
|
+
const mark = { type: "point", label: m.label };
|
|
2555
|
+
const si = toNum(m.seriesIndex);
|
|
2556
|
+
if (si != null && si >= 0) mark.seriesIndex = Math.floor(si);
|
|
2557
|
+
const v = toNum(m.value);
|
|
2558
|
+
if (v != null) mark.value = v;
|
|
2559
|
+
if (typeof m.text === "string") mark.text = m.text;
|
|
2560
|
+
marks.push(mark);
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
if (marks.length > 0) spec.marks = marks;
|
|
2564
|
+
}
|
|
1521
2565
|
const isDateRecords = spec.data?.length && spec.data[0] && "date" in spec.data[0];
|
|
1522
2566
|
if (spec.data && spec.data.length > 0 && !isDateRecords && !spec.series && !spec.points && !spec.values && !spec.segments) {
|
|
1523
2567
|
Object.assign(spec, pivotData(spec));
|
|
@@ -1557,6 +2601,391 @@ function inferChartType(spec) {
|
|
|
1557
2601
|
if (typeof spec.max === "number" && spec.values && spec.values.length === 1) return "gauge";
|
|
1558
2602
|
return "vbar";
|
|
1559
2603
|
}
|
|
2604
|
+
var DOWNSAMPLE_DEFAULT_THRESHOLD = 1e3;
|
|
2605
|
+
var CHART_ZOOM_DRAG_MIN_PX = 5;
|
|
2606
|
+
var CHART_LINE_W = 360;
|
|
2607
|
+
var CHART_LINE_H = 150;
|
|
2608
|
+
var CHART_LINE_PAD = 14;
|
|
2609
|
+
function isDownsampleableType(type) {
|
|
2610
|
+
return type === "line" || type === "area" || type === "scatter";
|
|
2611
|
+
}
|
|
2612
|
+
function isZoomableType(type) {
|
|
2613
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2614
|
+
}
|
|
2615
|
+
function isStreamableType(type) {
|
|
2616
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2617
|
+
}
|
|
2618
|
+
function downsampleView(view, type) {
|
|
2619
|
+
const raw = view.downsample;
|
|
2620
|
+
if (raw == null || raw === false) return { view, note: null };
|
|
2621
|
+
const threshold = raw === true ? DOWNSAMPLE_DEFAULT_THRESHOLD : Math.floor(raw);
|
|
2622
|
+
if (!Number.isFinite(threshold)) return { view, note: null };
|
|
2623
|
+
if (type === "scatter") {
|
|
2624
|
+
const pts = view.points ?? [];
|
|
2625
|
+
if (pts.length === 0) return { view, note: null };
|
|
2626
|
+
const sampled2 = lttb(pts, threshold, (p) => p.x, (p) => p.y);
|
|
2627
|
+
if (sampled2.length === pts.length) return { view, note: null };
|
|
2628
|
+
return { view: { ...view, points: sampled2 }, note: t("charts.sampled", { p0: pts.length, p1: sampled2.length }) };
|
|
2629
|
+
}
|
|
2630
|
+
const labels = view.labels ?? [];
|
|
2631
|
+
if (labels.length === 0) return { view, note: null };
|
|
2632
|
+
const guide = view.series && view.series.length > 0 ? view.series[0]?.values ?? [] : view.values ?? [];
|
|
2633
|
+
const count = Math.min(labels.length, guide.length);
|
|
2634
|
+
if (count === 0) return { view, note: null };
|
|
2635
|
+
const indexed = guide.slice(0, count).map((v, i) => ({ i, v }));
|
|
2636
|
+
const sampled = lttb(indexed, threshold, (p) => p.i, (p) => p.v);
|
|
2637
|
+
if (sampled.length >= count) return { view, note: null };
|
|
2638
|
+
const idx = sampled.map((p) => p.i);
|
|
2639
|
+
return {
|
|
2640
|
+
view: {
|
|
2641
|
+
...view,
|
|
2642
|
+
labels: idx.map((i) => labels[i] ?? ""),
|
|
2643
|
+
values: view.values ? idx.map((i) => view.values?.[i] ?? 0) : void 0,
|
|
2644
|
+
series: view.series?.map((s) => ({ ...s, values: idx.map((i) => s.values[i] ?? 0) }))
|
|
2645
|
+
},
|
|
2646
|
+
note: t("charts.sampled", { p0: count, p1: idx.length })
|
|
2647
|
+
};
|
|
2648
|
+
}
|
|
2649
|
+
function renderChartSkeleton(body) {
|
|
2650
|
+
const box = document.createElement("div");
|
|
2651
|
+
box.className = "icen-chart-skeleton";
|
|
2652
|
+
box.setAttribute("role", "status");
|
|
2653
|
+
box.setAttribute("aria-busy", "true");
|
|
2654
|
+
box.setAttribute("aria-label", t("charts.loading"));
|
|
2655
|
+
const widths = [100, 84, 92, 68, 76, 52];
|
|
2656
|
+
for (const w of widths) {
|
|
2657
|
+
const bar = document.createElement("div");
|
|
2658
|
+
bar.className = "icen-chart-skeleton-bar";
|
|
2659
|
+
bar.style.width = `${w}%`;
|
|
2660
|
+
box.appendChild(bar);
|
|
2661
|
+
}
|
|
2662
|
+
body.appendChild(box);
|
|
2663
|
+
}
|
|
2664
|
+
var CHART_MARK_ACCENT = "var(--icen-token-accent)";
|
|
2665
|
+
function markToneVar(tone) {
|
|
2666
|
+
switch (tone) {
|
|
2667
|
+
case "success":
|
|
2668
|
+
return "var(--icen-token-success)";
|
|
2669
|
+
case "warning":
|
|
2670
|
+
return "var(--icen-token-warning)";
|
|
2671
|
+
case "error":
|
|
2672
|
+
return "var(--icen-token-error)";
|
|
2673
|
+
case "info":
|
|
2674
|
+
return "var(--icen-token-info)";
|
|
2675
|
+
default:
|
|
2676
|
+
return "var(--icen-token-text-faint)";
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
function markWarnOnce(warned, mark, reason) {
|
|
2680
|
+
const key = JSON.stringify(mark);
|
|
2681
|
+
if (warned.has(key)) return;
|
|
2682
|
+
warned.add(key);
|
|
2683
|
+
console.warn(`[icen:chart] \u65E0\u6548\u6807\u8BB0\u5DF2\u8DF3\u8FC7\uFF08${reason}\uFF09`, mark);
|
|
2684
|
+
}
|
|
2685
|
+
function paintChartMarks(root, view, spec, formatValue, warned) {
|
|
2686
|
+
const marks = spec.marks;
|
|
2687
|
+
if (!marks || marks.length === 0) return;
|
|
2688
|
+
const type = spec.type;
|
|
2689
|
+
if (type === "line" || type === "area") paintSvgChartMarks(root, view, marks, formatValue, warned);
|
|
2690
|
+
else if (type === "vbar") paintVBarChartMarks(root, view, spec, marks, formatValue, warned);
|
|
2691
|
+
}
|
|
2692
|
+
function paintSvgChartMarks(root, view, marks, formatValue, warned) {
|
|
2693
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
2694
|
+
if (!svg) return;
|
|
2695
|
+
const labels = view.labels ?? [];
|
|
2696
|
+
const n = labels.length;
|
|
2697
|
+
if (n === 0) return;
|
|
2698
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2699
|
+
let max = 1;
|
|
2700
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2701
|
+
const dims = svgDimsOf(svg);
|
|
2702
|
+
const W = dims.w;
|
|
2703
|
+
const H = dims.h;
|
|
2704
|
+
const PAD = CHART_LINE_PAD;
|
|
2705
|
+
const xAt = (i) => n <= 1 ? W / 2 : PAD + i / (n - 1) * (W - PAD * 2);
|
|
2706
|
+
const yAt = (v) => H - PAD - Math.max(0, v) / max * (H - PAD * 2);
|
|
2707
|
+
for (const mark of marks) {
|
|
2708
|
+
if (mark.type === "line") {
|
|
2709
|
+
const color = markToneVar(mark.tone);
|
|
2710
|
+
if (mark.axis === "y") {
|
|
2711
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2712
|
+
if (!Number.isFinite(v)) {
|
|
2713
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2714
|
+
continue;
|
|
2715
|
+
}
|
|
2716
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2717
|
+
svg.appendChild(svgEl("line", {
|
|
2718
|
+
class: "icen-chart-mark-line",
|
|
2719
|
+
x1: String(PAD),
|
|
2720
|
+
x2: String(W - PAD),
|
|
2721
|
+
y1: y.toFixed(1),
|
|
2722
|
+
y2: y.toFixed(1),
|
|
2723
|
+
stroke: color,
|
|
2724
|
+
"stroke-width": "1",
|
|
2725
|
+
"stroke-dasharray": "4 3"
|
|
2726
|
+
}));
|
|
2727
|
+
const label = svgEl("text", {
|
|
2728
|
+
class: "icen-chart-mark-label",
|
|
2729
|
+
x: String(W - PAD),
|
|
2730
|
+
y: String(clampNum(y - 4, 8, CHART_LINE_H - 4)),
|
|
2731
|
+
"text-anchor": "end",
|
|
2732
|
+
"font-size": "8",
|
|
2733
|
+
fill: color
|
|
2734
|
+
});
|
|
2735
|
+
label.textContent = mark.label ?? formatValue(v);
|
|
2736
|
+
svg.appendChild(label);
|
|
2737
|
+
} else {
|
|
2738
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2739
|
+
if (idx < 0 || idx >= n) {
|
|
2740
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2741
|
+
continue;
|
|
2742
|
+
}
|
|
2743
|
+
const x = xAt(idx);
|
|
2744
|
+
svg.appendChild(svgEl("line", {
|
|
2745
|
+
class: "icen-chart-mark-line",
|
|
2746
|
+
x1: x.toFixed(1),
|
|
2747
|
+
x2: x.toFixed(1),
|
|
2748
|
+
y1: String(PAD),
|
|
2749
|
+
y2: String(H - PAD),
|
|
2750
|
+
stroke: color,
|
|
2751
|
+
"stroke-width": "1",
|
|
2752
|
+
"stroke-dasharray": "4 3"
|
|
2753
|
+
}));
|
|
2754
|
+
const label = svgEl("text", {
|
|
2755
|
+
class: "icen-chart-mark-label",
|
|
2756
|
+
x: String(clampNum(x, 10, W - 10)),
|
|
2757
|
+
y: String(PAD + 8),
|
|
2758
|
+
"text-anchor": "middle",
|
|
2759
|
+
"font-size": "8",
|
|
2760
|
+
fill: color
|
|
2761
|
+
});
|
|
2762
|
+
label.textContent = mark.label ?? labels[idx] ?? "";
|
|
2763
|
+
svg.appendChild(label);
|
|
2764
|
+
}
|
|
2765
|
+
} else {
|
|
2766
|
+
const idx = labels.indexOf(mark.label);
|
|
2767
|
+
if (idx < 0 || idx >= n) {
|
|
2768
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2769
|
+
continue;
|
|
2770
|
+
}
|
|
2771
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2772
|
+
const s = seriesList[si];
|
|
2773
|
+
if (!s) {
|
|
2774
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2775
|
+
continue;
|
|
2776
|
+
}
|
|
2777
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2778
|
+
if (!Number.isFinite(v)) {
|
|
2779
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2780
|
+
continue;
|
|
2781
|
+
}
|
|
2782
|
+
const x = xAt(idx);
|
|
2783
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2784
|
+
const g = svgEl("g", { class: "icen-chart-mark-point" });
|
|
2785
|
+
g.appendChild(svgEl("circle", {
|
|
2786
|
+
cx: x.toFixed(1),
|
|
2787
|
+
cy: y.toFixed(1),
|
|
2788
|
+
r: "6",
|
|
2789
|
+
fill: "none",
|
|
2790
|
+
stroke: CHART_MARK_ACCENT,
|
|
2791
|
+
"stroke-width": "1.5"
|
|
2792
|
+
}));
|
|
2793
|
+
g.appendChild(svgEl("circle", { cx: x.toFixed(1), cy: y.toFixed(1), r: "2", fill: CHART_MARK_ACCENT }));
|
|
2794
|
+
const label = svgEl("text", {
|
|
2795
|
+
class: "icen-chart-mark-label",
|
|
2796
|
+
x: String(clampNum(x, 12, W - 12)),
|
|
2797
|
+
y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
|
|
2798
|
+
"text-anchor": "middle",
|
|
2799
|
+
"font-size": "8",
|
|
2800
|
+
fill: CHART_MARK_ACCENT
|
|
2801
|
+
});
|
|
2802
|
+
label.textContent = mark.text ?? mark.label;
|
|
2803
|
+
g.appendChild(label);
|
|
2804
|
+
svg.appendChild(g);
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
2809
|
+
const wrap = root.querySelector(".icen-chart-vbar");
|
|
2810
|
+
if (!wrap) return;
|
|
2811
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2812
|
+
const labels = view.labels ?? [];
|
|
2813
|
+
const n = Math.min(labels.length, ...seriesList.map((s) => s.values.length));
|
|
2814
|
+
if (n === 0 || seriesList.length === 0) return;
|
|
2815
|
+
const multi = seriesList.length > 1;
|
|
2816
|
+
let max = 1;
|
|
2817
|
+
if (spec.stacked && multi) {
|
|
2818
|
+
for (let i = 0; i < n; i++) {
|
|
2819
|
+
let sum2 = 0;
|
|
2820
|
+
for (const s of seriesList) sum2 += Math.max(0, s.values[i] ?? 0);
|
|
2821
|
+
if (sum2 > max) max = sum2;
|
|
2822
|
+
}
|
|
2823
|
+
} else {
|
|
2824
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2825
|
+
}
|
|
2826
|
+
const centerPct = (i) => (i + 0.5) / n * 100;
|
|
2827
|
+
for (const mark of marks) {
|
|
2828
|
+
if (mark.type === "line") {
|
|
2829
|
+
if (mark.axis === "y") {
|
|
2830
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2831
|
+
if (!Number.isFinite(v)) {
|
|
2832
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2833
|
+
continue;
|
|
2834
|
+
}
|
|
2835
|
+
const line = document.createElement("div");
|
|
2836
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--h";
|
|
2837
|
+
line.style.top = `${(clampNum(1 - Math.max(0, v) / max, 0.02, 0.98) * 100).toFixed(2)}%`;
|
|
2838
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2839
|
+
const lab = document.createElement("span");
|
|
2840
|
+
lab.className = "icen-chart-mark-label";
|
|
2841
|
+
lab.textContent = mark.label ?? formatValue(v);
|
|
2842
|
+
line.appendChild(lab);
|
|
2843
|
+
wrap.appendChild(line);
|
|
2844
|
+
} else {
|
|
2845
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2846
|
+
if (idx < 0 || idx >= n) {
|
|
2847
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2848
|
+
continue;
|
|
2849
|
+
}
|
|
2850
|
+
const line = document.createElement("div");
|
|
2851
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--v";
|
|
2852
|
+
line.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2853
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2854
|
+
const lab = document.createElement("span");
|
|
2855
|
+
lab.className = "icen-chart-mark-label";
|
|
2856
|
+
lab.textContent = mark.label ?? labels[idx] ?? "";
|
|
2857
|
+
line.appendChild(lab);
|
|
2858
|
+
wrap.appendChild(line);
|
|
2859
|
+
}
|
|
2860
|
+
} else {
|
|
2861
|
+
const idx = labels.indexOf(mark.label);
|
|
2862
|
+
if (idx < 0 || idx >= n) {
|
|
2863
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2864
|
+
continue;
|
|
2865
|
+
}
|
|
2866
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2867
|
+
const s = seriesList[si];
|
|
2868
|
+
if (!s) {
|
|
2869
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2870
|
+
continue;
|
|
2871
|
+
}
|
|
2872
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2873
|
+
if (!Number.isFinite(v)) {
|
|
2874
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2875
|
+
continue;
|
|
2876
|
+
}
|
|
2877
|
+
const dot = document.createElement("div");
|
|
2878
|
+
dot.className = "icen-chart-mark-point";
|
|
2879
|
+
dot.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2880
|
+
dot.style.bottom = `${(clampNum(Math.max(0, v) / max, 0, 1) * 100).toFixed(2)}%`;
|
|
2881
|
+
const lab = document.createElement("span");
|
|
2882
|
+
lab.className = "icen-chart-mark-label";
|
|
2883
|
+
lab.textContent = mark.text ?? mark.label;
|
|
2884
|
+
dot.appendChild(lab);
|
|
2885
|
+
wrap.appendChild(dot);
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
function chartAriaLabel(title, typeName) {
|
|
2890
|
+
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2891
|
+
}
|
|
2892
|
+
function svgDimsOf(svg) {
|
|
2893
|
+
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2894
|
+
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
2895
|
+
const h2 = Number.isFinite(vb[3]) && (vb[3] ?? 0) > 0 ? vb[3] : CHART_LINE_H;
|
|
2896
|
+
return { w, h: h2 };
|
|
2897
|
+
}
|
|
2898
|
+
var fluidObservers = /* @__PURE__ */ new WeakMap();
|
|
2899
|
+
function fluidWidth(host) {
|
|
2900
|
+
const w = Math.round(host.getBoundingClientRect().width);
|
|
2901
|
+
return w > 0 ? Math.max(29, w) : 360;
|
|
2902
|
+
}
|
|
2903
|
+
function observeFluidWidth(el, rerender) {
|
|
2904
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2905
|
+
fluidObservers.get(el)?.disconnect();
|
|
2906
|
+
let last = Math.round(el.getBoundingClientRect().width);
|
|
2907
|
+
const ro = new ResizeObserver(() => {
|
|
2908
|
+
if (!el.isConnected) {
|
|
2909
|
+
ro.disconnect();
|
|
2910
|
+
fluidObservers.delete(el);
|
|
2911
|
+
return;
|
|
2912
|
+
}
|
|
2913
|
+
const w = Math.round(el.getBoundingClientRect().width);
|
|
2914
|
+
if (Math.abs(w - last) < 2) return;
|
|
2915
|
+
last = w;
|
|
2916
|
+
rerender();
|
|
2917
|
+
});
|
|
2918
|
+
ro.observe(el);
|
|
2919
|
+
fluidObservers.set(el, ro);
|
|
2920
|
+
}
|
|
2921
|
+
function releaseFluidWidth(el) {
|
|
2922
|
+
fluidObservers.get(el)?.disconnect();
|
|
2923
|
+
fluidObservers.delete(el);
|
|
2924
|
+
}
|
|
2925
|
+
function createChartToDataURL(root) {
|
|
2926
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2927
|
+
return (opts) => {
|
|
2928
|
+
if (typeof document === "undefined") return void 0;
|
|
2929
|
+
const scale = clampNum(toNum(opts?.scale) ?? 2, 0.5, 4);
|
|
2930
|
+
const svgs = Array.from(root.querySelectorAll("svg"));
|
|
2931
|
+
if (svgs.length === 0) return void 0;
|
|
2932
|
+
const parts = [];
|
|
2933
|
+
for (const svg of svgs) {
|
|
2934
|
+
const { w, h: h2 } = svgDimsOf(svg);
|
|
2935
|
+
const clone = svg.cloneNode(true);
|
|
2936
|
+
clone.setAttribute("xmlns", SVG_NS);
|
|
2937
|
+
clone.setAttribute("width", String(w));
|
|
2938
|
+
clone.setAttribute("height", String(h2));
|
|
2939
|
+
let str;
|
|
2940
|
+
try {
|
|
2941
|
+
str = new XMLSerializer().serializeToString(clone);
|
|
2942
|
+
} catch {
|
|
2943
|
+
return void 0;
|
|
2944
|
+
}
|
|
2945
|
+
parts.push({ src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(str)}`, w, h: h2 });
|
|
2946
|
+
}
|
|
2947
|
+
const key = `${scale}|${parts.map((p) => p.src).join("")}`;
|
|
2948
|
+
const hit = cache.get(key);
|
|
2949
|
+
if (hit) return hit;
|
|
2950
|
+
const canvas = document.createElement("canvas");
|
|
2951
|
+
let ctx = null;
|
|
2952
|
+
try {
|
|
2953
|
+
ctx = canvas.getContext("2d");
|
|
2954
|
+
} catch {
|
|
2955
|
+
return void 0;
|
|
2956
|
+
}
|
|
2957
|
+
if (!ctx) return void 0;
|
|
2958
|
+
const context = ctx;
|
|
2959
|
+
const totalW = Math.max(...parts.map((p) => p.w));
|
|
2960
|
+
const totalH = parts.reduce((sum2, p) => sum2 + p.h, 0);
|
|
2961
|
+
canvas.width = Math.max(1, Math.round(totalW * scale));
|
|
2962
|
+
canvas.height = Math.max(1, Math.round(totalH * scale));
|
|
2963
|
+
let loaded = 0;
|
|
2964
|
+
let failed = false;
|
|
2965
|
+
let offsetY = 0;
|
|
2966
|
+
for (const part of parts) {
|
|
2967
|
+
const dy = offsetY;
|
|
2968
|
+
offsetY += part.h;
|
|
2969
|
+
const img = new Image();
|
|
2970
|
+
img.onload = () => {
|
|
2971
|
+
if (failed) return;
|
|
2972
|
+
context.drawImage(img, 0, dy * scale, part.w * scale, part.h * scale);
|
|
2973
|
+
loaded += 1;
|
|
2974
|
+
if (loaded === parts.length) {
|
|
2975
|
+
try {
|
|
2976
|
+
cache.set(key, canvas.toDataURL("image/png"));
|
|
2977
|
+
} catch {
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
img.onerror = () => {
|
|
2982
|
+
failed = true;
|
|
2983
|
+
};
|
|
2984
|
+
img.src = part.src;
|
|
2985
|
+
}
|
|
2986
|
+
return cache.get(key);
|
|
2987
|
+
};
|
|
2988
|
+
}
|
|
1560
2989
|
function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
1561
2990
|
const read = (name) => mark.getAttribute(name) ?? void 0;
|
|
1562
2991
|
const numOr = (v) => v == null ? void 0 : Number(v);
|
|
@@ -1564,11 +2993,11 @@ function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
|
1564
2993
|
type,
|
|
1565
2994
|
phase,
|
|
1566
2995
|
chart,
|
|
1567
|
-
index: numOr(read("data-chart-index")),
|
|
1568
|
-
seriesIndex: numOr(read("data-chart-series")),
|
|
1569
|
-
seriesName: read("data-chart-series-name"),
|
|
1570
|
-
label: read("data-chart-label"),
|
|
1571
|
-
value: numOr(read("data-chart-value")),
|
|
2996
|
+
index: numOr(read("data-icen-chart-index")),
|
|
2997
|
+
seriesIndex: numOr(read("data-icen-chart-series")),
|
|
2998
|
+
seriesName: read("data-icen-chart-series-name"),
|
|
2999
|
+
label: read("data-icen-chart-label"),
|
|
3000
|
+
value: numOr(read("data-icen-chart-value")),
|
|
1572
3001
|
target: mark,
|
|
1573
3002
|
pointerX: pointer?.x,
|
|
1574
3003
|
pointerY: pointer?.y
|
|
@@ -1579,7 +3008,7 @@ var tooltipEl = null;
|
|
|
1579
3008
|
function chartTooltip() {
|
|
1580
3009
|
if (!tooltipEl) {
|
|
1581
3010
|
tooltipEl = document.createElement("div");
|
|
1582
|
-
tooltipEl.className = "chart-tooltip";
|
|
3011
|
+
tooltipEl.className = "icen-chart-tooltip";
|
|
1583
3012
|
tooltipEl.setAttribute("role", "tooltip");
|
|
1584
3013
|
tooltipEl.hidden = true;
|
|
1585
3014
|
document.body.appendChild(tooltipEl);
|
|
@@ -1588,14 +3017,14 @@ function chartTooltip() {
|
|
|
1588
3017
|
}
|
|
1589
3018
|
function applyTooltipSizing(host) {
|
|
1590
3019
|
const tip = chartTooltip();
|
|
1591
|
-
const raw = host?.closest(".chart, [data-chart-root]")?.getAttribute("data-panel-max") ?? null;
|
|
3020
|
+
const raw = host?.closest(".icen-chart, [data-icen-chart-root]")?.getAttribute("data-icen-panel-max") ?? null;
|
|
1592
3021
|
const n = raw != null ? Number(raw) : NaN;
|
|
1593
3022
|
tip.style.maxWidth = Number.isFinite(n) && n > 0 ? `${n}px` : "";
|
|
1594
3023
|
}
|
|
1595
3024
|
function tooltipText(mark) {
|
|
1596
|
-
const label = mark.getAttribute("data-chart-label") ?? "";
|
|
1597
|
-
const series = mark.getAttribute("data-chart-series-name");
|
|
1598
|
-
const value = mark.getAttribute("data-chart-value");
|
|
3025
|
+
const label = mark.getAttribute("data-icen-chart-label") ?? "";
|
|
3026
|
+
const series = mark.getAttribute("data-icen-chart-series-name");
|
|
3027
|
+
const value = mark.getAttribute("data-icen-chart-value");
|
|
1599
3028
|
const head = series ? label ? `${series} \xB7 ${label}` : series : label;
|
|
1600
3029
|
return value != null ? `${head}\uFF1A${value}` : head;
|
|
1601
3030
|
}
|
|
@@ -1627,8 +3056,8 @@ function bindChartEvents(root) {
|
|
|
1627
3056
|
const typeNow = () => chartDelegateMeta.get(root)?.type() ?? "vbar";
|
|
1628
3057
|
const tipEnabled = () => chartDelegateMeta.get(root)?.tooltip() ?? true;
|
|
1629
3058
|
const markOf = (e) => {
|
|
1630
|
-
const
|
|
1631
|
-
return
|
|
3059
|
+
const t2 = e.target;
|
|
3060
|
+
return t2 instanceof Element ? t2.closest("[data-icen-chart-mark]") : null;
|
|
1632
3061
|
};
|
|
1633
3062
|
let hoverMark = null;
|
|
1634
3063
|
const enterMark = (mark, x, y) => {
|
|
@@ -1725,70 +3154,277 @@ function hasLegendOf(spec) {
|
|
|
1725
3154
|
function renderChart(el, raw) {
|
|
1726
3155
|
const noop = () => void 0;
|
|
1727
3156
|
if (typeof document === "undefined") {
|
|
1728
|
-
return {
|
|
3157
|
+
return {
|
|
3158
|
+
el,
|
|
3159
|
+
spec: {},
|
|
3160
|
+
update: noop,
|
|
3161
|
+
append: noop,
|
|
3162
|
+
toDataURL: () => void 0,
|
|
3163
|
+
on: () => noop,
|
|
3164
|
+
destroy: noop
|
|
3165
|
+
};
|
|
1729
3166
|
}
|
|
1730
3167
|
const root = el;
|
|
1731
|
-
let
|
|
1732
|
-
const typeOf = () =>
|
|
3168
|
+
let current2 = normalizeChartSpec(raw);
|
|
3169
|
+
const typeOf = () => current2.type ?? "vbar";
|
|
1733
3170
|
const legendState = { hidden: null };
|
|
3171
|
+
let zoomWindow = null;
|
|
3172
|
+
const warnedMarks = /* @__PURE__ */ new Set();
|
|
3173
|
+
let warnedAppend = false;
|
|
3174
|
+
let zoomDragCleanup = null;
|
|
3175
|
+
const fullLength = () => {
|
|
3176
|
+
if (current2.type === "scatter") return current2.points?.length ?? 0;
|
|
3177
|
+
if (current2.series && current2.series.length > 0) {
|
|
3178
|
+
return Math.max(current2.labels?.length ?? 0, ...current2.series.map((s) => s.values.length));
|
|
3179
|
+
}
|
|
3180
|
+
return Math.max(current2.labels?.length ?? 0, current2.values?.length ?? 0);
|
|
3181
|
+
};
|
|
3182
|
+
const viewOf = () => {
|
|
3183
|
+
if (!zoomWindow) return current2;
|
|
3184
|
+
const { from, to } = zoomWindow;
|
|
3185
|
+
return {
|
|
3186
|
+
...current2,
|
|
3187
|
+
labels: current2.labels?.slice(from, to + 1),
|
|
3188
|
+
values: current2.values?.slice(from, to + 1),
|
|
3189
|
+
series: current2.series?.map((s) => ({ ...s, values: s.values.slice(from, to + 1) })),
|
|
3190
|
+
points: current2.points?.slice(from, to + 1)
|
|
3191
|
+
};
|
|
3192
|
+
};
|
|
3193
|
+
const applyZoomSelection = (x0, x1) => {
|
|
3194
|
+
const len = fullLength();
|
|
3195
|
+
if (len < 2) return;
|
|
3196
|
+
const base = zoomWindow?.from ?? 0;
|
|
3197
|
+
const viewLen = zoomWindow ? zoomWindow.to - zoomWindow.from + 1 : len;
|
|
3198
|
+
const lo = Math.min(x0, x1);
|
|
3199
|
+
const hi = Math.max(x0, x1);
|
|
3200
|
+
let i0;
|
|
3201
|
+
let i1;
|
|
3202
|
+
const vbar = root.querySelector(".icen-chart-vbar");
|
|
3203
|
+
if (vbar) {
|
|
3204
|
+
const rect = vbar.getBoundingClientRect();
|
|
3205
|
+
const rel0 = rect.width > 0 ? Math.floor((lo - rect.left) / rect.width * viewLen) : 0;
|
|
3206
|
+
const rel1 = rect.width > 0 ? Math.max(rel0, Math.floor((hi - rect.left) / rect.width * viewLen)) : viewLen - 1;
|
|
3207
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3208
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3209
|
+
} else {
|
|
3210
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3211
|
+
if (!svg) return;
|
|
3212
|
+
const dims = svgDimsOf(svg);
|
|
3213
|
+
const p0 = svgClientPoint(svg, lo, 0, dims.w, dims.h);
|
|
3214
|
+
const p1 = svgClientPoint(svg, hi, 0, dims.w, dims.h);
|
|
3215
|
+
const rel0 = Math.round((p0.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3216
|
+
const rel1 = Math.round((p1.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3217
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3218
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3219
|
+
}
|
|
3220
|
+
if (i0 > i1) [i0, i1] = [i1, i0];
|
|
3221
|
+
if (i0 <= 0 && i1 >= len - 1) zoomWindow = null;
|
|
3222
|
+
else zoomWindow = { from: i0, to: Math.max(i1, i0) };
|
|
3223
|
+
render();
|
|
3224
|
+
emitIcen(root, "icen:chart-zoom", { chart: String(current2.type ?? ""), from: i0, to: Math.max(i1, i0) });
|
|
3225
|
+
};
|
|
3226
|
+
const bindZoomGesture = () => {
|
|
3227
|
+
if (current2.zoom !== "x" && current2.zoom !== "brush") return;
|
|
3228
|
+
const t2 = typeOf();
|
|
3229
|
+
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
3230
|
+
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
3231
|
+
if (!plot) return;
|
|
3232
|
+
const on = (type, fn) => {
|
|
3233
|
+
plot.addEventListener(type, fn);
|
|
3234
|
+
};
|
|
3235
|
+
let drag = null;
|
|
3236
|
+
const onMove = (e) => {
|
|
3237
|
+
if (!drag) return;
|
|
3238
|
+
drag.x1 = e.clientX;
|
|
3239
|
+
drag.y1 = e.clientY;
|
|
3240
|
+
if (!drag.active && Math.hypot(drag.x1 - drag.x0, drag.y1 - drag.y0) >= CHART_ZOOM_DRAG_MIN_PX) {
|
|
3241
|
+
drag.active = true;
|
|
3242
|
+
const rect = document.createElement("div");
|
|
3243
|
+
rect.className = "icen-chart-zoom-rect";
|
|
3244
|
+
document.body.appendChild(rect);
|
|
3245
|
+
drag.rect = rect;
|
|
3246
|
+
}
|
|
3247
|
+
if (drag.active && drag.rect) {
|
|
3248
|
+
drag.rect.style.left = `${Math.round(Math.min(drag.x0, drag.x1))}px`;
|
|
3249
|
+
drag.rect.style.width = `${Math.round(Math.abs(drag.x1 - drag.x0))}px`;
|
|
3250
|
+
if (current2.zoom === "brush") {
|
|
3251
|
+
drag.rect.style.top = `${Math.round(Math.min(drag.y0, drag.y1))}px`;
|
|
3252
|
+
drag.rect.style.height = `${Math.round(Math.abs(drag.y1 - drag.y0))}px`;
|
|
3253
|
+
} else {
|
|
3254
|
+
const pr = plot.getBoundingClientRect();
|
|
3255
|
+
drag.rect.style.top = `${Math.round(pr.top)}px`;
|
|
3256
|
+
drag.rect.style.height = `${Math.round(pr.height)}px`;
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3259
|
+
};
|
|
3260
|
+
const onUp = () => {
|
|
3261
|
+
window.removeEventListener("pointermove", onMove);
|
|
3262
|
+
window.removeEventListener("pointerup", onUp);
|
|
3263
|
+
window.removeEventListener("pointercancel", onUp);
|
|
3264
|
+
zoomDragCleanup = null;
|
|
3265
|
+
if (!drag) return;
|
|
3266
|
+
const d = drag;
|
|
3267
|
+
drag = null;
|
|
3268
|
+
d.rect?.remove();
|
|
3269
|
+
if (!d.active) return;
|
|
3270
|
+
applyZoomSelection(d.x0, d.x1);
|
|
3271
|
+
};
|
|
3272
|
+
const onDown = (e) => {
|
|
3273
|
+
if (e.button !== 0) return;
|
|
3274
|
+
drag = { x0: e.clientX, y0: e.clientY, x1: e.clientX, y1: e.clientY, active: false, rect: null };
|
|
3275
|
+
window.addEventListener("pointermove", onMove);
|
|
3276
|
+
window.addEventListener("pointerup", onUp);
|
|
3277
|
+
window.addEventListener("pointercancel", onUp);
|
|
3278
|
+
zoomDragCleanup = onUp;
|
|
3279
|
+
};
|
|
3280
|
+
on("pointerdown", onDown);
|
|
3281
|
+
on("dblclick", () => {
|
|
3282
|
+
if (!zoomWindow) return;
|
|
3283
|
+
zoomWindow = null;
|
|
3284
|
+
render();
|
|
3285
|
+
});
|
|
3286
|
+
};
|
|
1734
3287
|
const render = () => {
|
|
1735
|
-
if (!
|
|
1736
|
-
const spec =
|
|
3288
|
+
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
3289
|
+
const spec = current2;
|
|
3290
|
+
const type = spec.type;
|
|
1737
3291
|
const formatValue = chartFormatValue(spec.format);
|
|
1738
3292
|
if (spec.legend !== void 0) legendState.hidden = spec.legend === false;
|
|
3293
|
+
const loading = spec.loading === true;
|
|
3294
|
+
root.classList.toggle("is-loading", loading);
|
|
3295
|
+
let view = viewOf();
|
|
3296
|
+
let note = null;
|
|
3297
|
+
if (!loading && isDownsampleableType(type)) {
|
|
3298
|
+
const r = downsampleView(view, type);
|
|
3299
|
+
view = r.view;
|
|
3300
|
+
note = r.note;
|
|
3301
|
+
}
|
|
3302
|
+
const zoomReset = zoomWindow && (spec.zoom === "x" || spec.zoom === "brush") ? () => {
|
|
3303
|
+
zoomWindow = null;
|
|
3304
|
+
render();
|
|
3305
|
+
} : null;
|
|
1739
3306
|
withChrome(root, spec, hasLegendOf(spec), (body) => {
|
|
1740
|
-
|
|
3307
|
+
if (loading) {
|
|
3308
|
+
renderChartSkeleton(body);
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3311
|
+
switch (type) {
|
|
1741
3312
|
case "line":
|
|
1742
|
-
renderLine(body, { labels:
|
|
3313
|
+
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 });
|
|
1743
3314
|
break;
|
|
1744
3315
|
case "area":
|
|
1745
|
-
renderLine(body, { labels:
|
|
3316
|
+
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 });
|
|
1746
3317
|
break;
|
|
1747
3318
|
case "vbar":
|
|
1748
|
-
renderVBar(body, { labels:
|
|
3319
|
+
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 });
|
|
1749
3320
|
break;
|
|
1750
3321
|
case "hbar":
|
|
1751
|
-
renderHBar(body, { labels:
|
|
3322
|
+
renderHBar(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1752
3323
|
break;
|
|
1753
3324
|
case "stack":
|
|
1754
|
-
renderStack(body, { segments:
|
|
3325
|
+
renderStack(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1755
3326
|
break;
|
|
1756
3327
|
case "donut":
|
|
1757
|
-
renderDonut(body, { segments:
|
|
3328
|
+
renderDonut(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1758
3329
|
break;
|
|
1759
3330
|
case "radar": {
|
|
1760
|
-
const series =
|
|
1761
|
-
renderRadar(body, { axes:
|
|
3331
|
+
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 }] : [];
|
|
3332
|
+
renderRadar(body, { axes: view.axes ?? view.labels ?? [], series, max: view.max, levels: view.levels, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1762
3333
|
break;
|
|
1763
3334
|
}
|
|
1764
3335
|
case "heatmap":
|
|
1765
|
-
renderHeatmap(body, { values:
|
|
3336
|
+
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 });
|
|
1766
3337
|
break;
|
|
1767
3338
|
case "calendar":
|
|
1768
|
-
renderCalendar(body, { dates:
|
|
3339
|
+
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 });
|
|
1769
3340
|
break;
|
|
1770
3341
|
case "sparkline":
|
|
1771
|
-
renderSparkline(body, { labels:
|
|
3342
|
+
renderSparkline(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1772
3343
|
break;
|
|
1773
3344
|
case "gauge":
|
|
1774
|
-
renderGauge(body, { value:
|
|
3345
|
+
renderGauge(body, { value: view.values?.[0] ?? 0, max: view.max, tone: view.tone, label: view.labels?.[0], formatValue });
|
|
1775
3346
|
break;
|
|
1776
3347
|
case "scatter":
|
|
1777
|
-
renderScatter(body, { points:
|
|
3348
|
+
renderScatter(body, { points: view.points ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1778
3349
|
break;
|
|
1779
3350
|
default:
|
|
1780
|
-
renderEmpty(body,
|
|
3351
|
+
renderEmpty(body, view.emptyLabel);
|
|
1781
3352
|
}
|
|
1782
|
-
});
|
|
3353
|
+
}, legendState, { note, onZoomReset: zoomReset });
|
|
3354
|
+
if (!loading) {
|
|
3355
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3356
|
+
if (graphic && !graphic.getAttribute("aria-label")) {
|
|
3357
|
+
graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
if (loading) return;
|
|
3361
|
+
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3362
|
+
bindZoomGesture();
|
|
1783
3363
|
};
|
|
1784
|
-
chartDelegateMeta.set(root, { type: typeOf, tooltip: () =>
|
|
3364
|
+
chartDelegateMeta.set(root, { type: typeOf, tooltip: () => current2.tooltip !== false });
|
|
1785
3365
|
const unbindEvents = bindChartEvents(root);
|
|
1786
3366
|
render();
|
|
3367
|
+
observeFluidWidth(root, render);
|
|
1787
3368
|
return {
|
|
1788
3369
|
el: root,
|
|
1789
|
-
|
|
3370
|
+
/** 归一 + 推断后的当前规格(getter:update/append 换引用后永远读到最新) */
|
|
3371
|
+
get spec() {
|
|
3372
|
+
return current2;
|
|
3373
|
+
},
|
|
1790
3374
|
update(next) {
|
|
1791
|
-
|
|
3375
|
+
const prev = current2;
|
|
3376
|
+
current2 = normalizeChartSpec(next);
|
|
3377
|
+
if (zoomWindow) {
|
|
3378
|
+
const sameLabels = JSON.stringify(prev.labels ?? null) === JSON.stringify(current2.labels ?? null);
|
|
3379
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3380
|
+
const zoomable = isZoomableType(t2) && (current2.zoom === "x" || current2.zoom === "brush");
|
|
3381
|
+
if (!sameLabels || !zoomable) zoomWindow = null;
|
|
3382
|
+
else {
|
|
3383
|
+
const len = fullLength();
|
|
3384
|
+
if (len < 2) zoomWindow = null;
|
|
3385
|
+
else {
|
|
3386
|
+
const from = clampNum(zoomWindow.from, 0, len - 1);
|
|
3387
|
+
const to = clampNum(zoomWindow.to, 0, len - 1);
|
|
3388
|
+
zoomWindow = from <= to ? { from, to } : null;
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
render();
|
|
3393
|
+
},
|
|
3394
|
+
append(label, values, opts) {
|
|
3395
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3396
|
+
if (!isStreamableType(t2)) {
|
|
3397
|
+
if (!warnedAppend) {
|
|
3398
|
+
warnedAppend = true;
|
|
3399
|
+
console.warn(`[icen:chart] append \u4EC5\u652F\u6301 line/area/vbar\uFF08\u5F53\u524D ${String(current2.type ?? t2)}\uFF09\uFF0C\u5DF2\u5FFD\u7565`);
|
|
3400
|
+
}
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
const labels = current2.labels ?? (current2.labels = []);
|
|
3404
|
+
labels.push(String(label ?? ""));
|
|
3405
|
+
const vals = Array.isArray(values) ? values : [];
|
|
3406
|
+
if (current2.series && current2.series.length > 0) {
|
|
3407
|
+
for (const [i, s] of current2.series.entries()) s.values.push(toNum(vals[i]) ?? 0);
|
|
3408
|
+
} else {
|
|
3409
|
+
const v = current2.values ?? (current2.values = []);
|
|
3410
|
+
v.push(toNum(vals[0]) ?? 0);
|
|
3411
|
+
}
|
|
3412
|
+
const maxPoints = opts?.maxPoints != null ? Math.max(1, Math.floor(toNum(opts.maxPoints) ?? 0)) : 0;
|
|
3413
|
+
let dropped = 0;
|
|
3414
|
+
if (maxPoints > 0) {
|
|
3415
|
+
while (labels.length > maxPoints) {
|
|
3416
|
+
labels.shift();
|
|
3417
|
+
if (current2.series) for (const s of current2.series) s.values.shift();
|
|
3418
|
+
else current2.values?.shift();
|
|
3419
|
+
dropped += 1;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
if (zoomWindow) {
|
|
3423
|
+
const len = Math.max(1, labels.length);
|
|
3424
|
+
const size = zoomWindow.to - zoomWindow.from + 1;
|
|
3425
|
+
const to = clampNum(zoomWindow.to - dropped + 1, 0, len - 1);
|
|
3426
|
+
zoomWindow = { from: Math.max(0, to - size + 1), to };
|
|
3427
|
+
}
|
|
1792
3428
|
render();
|
|
1793
3429
|
},
|
|
1794
3430
|
on(name, listener) {
|
|
@@ -1798,13 +3434,29 @@ function renderChart(el, raw) {
|
|
|
1798
3434
|
root.addEventListener(`icen:chart-${name}`, handler);
|
|
1799
3435
|
return () => root.removeEventListener(`icen:chart-${name}`, handler);
|
|
1800
3436
|
},
|
|
3437
|
+
toDataURL: createChartToDataURL(root),
|
|
1801
3438
|
destroy() {
|
|
3439
|
+
releaseFluidWidth(root);
|
|
3440
|
+
hiddenLegendKeys.delete(root);
|
|
3441
|
+
zoomDragCleanup?.();
|
|
1802
3442
|
root.textContent = "";
|
|
3443
|
+
root.classList.remove("is-loading");
|
|
1803
3444
|
unbindEvents();
|
|
1804
3445
|
chartTooltip().hidden = true;
|
|
1805
3446
|
}
|
|
1806
3447
|
};
|
|
1807
3448
|
}
|
|
3449
|
+
function svgClientPoint(svg, clientX, clientY, viewBoxWidth, viewBoxHeight) {
|
|
3450
|
+
const rect = svg.getBoundingClientRect();
|
|
3451
|
+
const scale = Math.min(rect.width / viewBoxWidth, rect.height / viewBoxHeight);
|
|
3452
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
3453
|
+
return { x: viewBoxWidth / 2, y: viewBoxHeight / 2 };
|
|
3454
|
+
}
|
|
3455
|
+
return {
|
|
3456
|
+
x: (clientX - rect.left - (rect.width - viewBoxWidth * scale) / 2) / scale,
|
|
3457
|
+
y: (clientY - rect.top - (rect.height - viewBoxHeight * scale) / 2) / scale
|
|
3458
|
+
};
|
|
3459
|
+
}
|
|
1808
3460
|
var GRAPH_W = 360;
|
|
1809
3461
|
var GRAPH_H = 260;
|
|
1810
3462
|
var GRAPH_PAD = 28;
|
|
@@ -1813,24 +3465,24 @@ var GRAPH_LH = GRAPH_H - GRAPH_PAD * 2;
|
|
|
1813
3465
|
|
|
1814
3466
|
// src/behaviors/kb-answer.ts
|
|
1815
3467
|
var ASSET_TYPE_LABELS = {
|
|
1816
|
-
"parameterized-query": "
|
|
1817
|
-
function: "
|
|
1818
|
-
curated: "
|
|
3468
|
+
"parameterized-query": t("kbAnswer.kindParameterized"),
|
|
3469
|
+
function: t("kbAnswer.kindFunction"),
|
|
3470
|
+
curated: t("kbAnswer.kindCurated")
|
|
1819
3471
|
};
|
|
1820
3472
|
var ICON_TRUSTED = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.7 9a.6.6 0 0 1-.6 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.2-2.7a1.2 1.2 0 0 1 1.6 0C14.5 3.8 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></svg>';
|
|
1821
3473
|
var ICON_SHIELD = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.7 9a.6.6 0 0 1-.6 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.2-2.7a1.2 1.2 0 0 1 1.6 0C14.5 3.8 17 5 19 5a1 1 0 0 1 1 1z"/></svg>';
|
|
1822
3474
|
function renderVerifiedBadge(via, opts) {
|
|
1823
|
-
const btn = h("button", "kb-verified");
|
|
3475
|
+
const btn = h("button", "icen-kb-verified");
|
|
1824
3476
|
btn.type = "button";
|
|
1825
|
-
if (via.assetId) btn.dataset.
|
|
1826
|
-
const badge = h("span", "kb-badge kb-badge--trusted");
|
|
1827
|
-
const
|
|
1828
|
-
if (
|
|
1829
|
-
badge.appendChild(document.createTextNode("
|
|
3477
|
+
if (via.assetId) btn.dataset.icenAssetId = via.assetId;
|
|
3478
|
+
const badge = h("span", "icen-kb-badge icen-kb-badge--trusted");
|
|
3479
|
+
const svg = svgIcon(ICON_TRUSTED);
|
|
3480
|
+
if (svg) badge.appendChild(svg);
|
|
3481
|
+
badge.appendChild(document.createTextNode(t("kbAnswer.verifiedBadge")));
|
|
1830
3482
|
btn.appendChild(badge);
|
|
1831
|
-
btn.appendChild(h("span", "kb-verified-via",
|
|
1832
|
-
if (via.note) btn.appendChild(h("span", "kb-verified-note", via.note));
|
|
1833
|
-
btn.appendChild(h("span", "kb-verified-hint", "
|
|
3483
|
+
btn.appendChild(h("span", "icen-kb-verified-via", t("kbAnswer.hitAssets", { p0: ASSET_TYPE_LABELS[via.assetType] ?? via.assetType })));
|
|
3484
|
+
if (via.note) btn.appendChild(h("span", "icen-kb-verified-note", via.note));
|
|
3485
|
+
btn.appendChild(h("span", "icen-kb-verified-hint", t("kbAnswer.rerunTip")));
|
|
1834
3486
|
btn.addEventListener("click", () => {
|
|
1835
3487
|
emitIcen(btn, "icen:kb-verified-open", { assetId: via.assetId });
|
|
1836
3488
|
opts?.onVerifiedOpen?.(via.assetId);
|
|
@@ -1838,26 +3490,26 @@ function renderVerifiedBadge(via, opts) {
|
|
|
1838
3490
|
return btn;
|
|
1839
3491
|
}
|
|
1840
3492
|
function renderPermissionNotice(p) {
|
|
1841
|
-
const box = h("div", "kb-perm");
|
|
1842
|
-
const iconBox = h("span", "kb-perm-icon");
|
|
1843
|
-
const
|
|
1844
|
-
if (
|
|
3493
|
+
const box = h("div", "icen-kb-perm");
|
|
3494
|
+
const iconBox = h("span", "icen-kb-perm-icon");
|
|
3495
|
+
const svg = svgIcon(ICON_SHIELD);
|
|
3496
|
+
if (svg) iconBox.appendChild(svg);
|
|
1845
3497
|
box.appendChild(iconBox);
|
|
1846
|
-
box.appendChild(h("span", "kb-perm-text", p.rowLevelPolicy ?
|
|
3498
|
+
box.appendChild(h("span", "kb-perm-text", p.rowLevelPolicy ? t("kbAnswer.filteredDetail", { p0: p.rowLevelPolicy }) : t("kbAnswer.filtered")));
|
|
1847
3499
|
if (p.maskedColumns?.length) {
|
|
1848
|
-
const mask = h("span", "kb-perm-mask");
|
|
1849
|
-
mask.appendChild(h("span", "kb-perm-mask-label", "
|
|
1850
|
-
for (const col of p.maskedColumns) mask.appendChild(h("span", "kb-chip", col));
|
|
3500
|
+
const mask = h("span", "icen-kb-perm-mask");
|
|
3501
|
+
mask.appendChild(h("span", "icen-kb-perm-mask-label", t("kbAnswer.maskedPrefix")));
|
|
3502
|
+
for (const col of p.maskedColumns) mask.appendChild(h("span", "icen-kb-chip", col));
|
|
1851
3503
|
box.appendChild(mask);
|
|
1852
3504
|
}
|
|
1853
3505
|
return box;
|
|
1854
3506
|
}
|
|
1855
3507
|
function renderBody(text, citations) {
|
|
1856
|
-
const box = h("div", "kb-answer-body");
|
|
3508
|
+
const box = h("div", "icen-kb-answer-body");
|
|
1857
3509
|
for (const seg of parseInlineCitations(text)) {
|
|
1858
3510
|
if (typeof seg.n === "number" && citations && seg.n >= 1 && seg.n <= citations.length) {
|
|
1859
|
-
const sup = h("sup", "kb-citation", `[${seg.n}]`);
|
|
1860
|
-
sup.dataset.
|
|
3511
|
+
const sup = h("sup", "icen-kb-citation", `[${seg.n}]`);
|
|
3512
|
+
sup.dataset.icenCite = String(seg.n);
|
|
1861
3513
|
const c = citations[seg.n - 1];
|
|
1862
3514
|
if (c?.title) sup.title = c.title;
|
|
1863
3515
|
box.appendChild(sup);
|
|
@@ -1890,18 +3542,18 @@ function isNumericColumn(col, colIndex, rows) {
|
|
|
1890
3542
|
}
|
|
1891
3543
|
function renderResult(result, opts) {
|
|
1892
3544
|
if (!result.columns.length) return null;
|
|
1893
|
-
const wrap = h("div", "kb-answer-results");
|
|
1894
|
-
const meta = h("div", "kb-result-meta");
|
|
1895
|
-
meta.appendChild(h("span", "kb-num",
|
|
3545
|
+
const wrap = h("div", "icen-kb-answer-results");
|
|
3546
|
+
const meta = h("div", "icen-kb-result-meta");
|
|
3547
|
+
meta.appendChild(h("span", "icen-kb-num", t("common.rows", { p0: formatCount(result.rowCount) })));
|
|
1896
3548
|
if (result.durationMs != null) {
|
|
1897
|
-
meta.appendChild(h("span", "kb-num kb-result-dur", `${Math.round(result.durationMs)} ms`));
|
|
3549
|
+
meta.appendChild(h("span", "icen-kb-num kb-result-dur", `${Math.round(result.durationMs)} ms`));
|
|
1898
3550
|
}
|
|
1899
3551
|
if (result.exportFormats?.length) {
|
|
1900
|
-
const exports = h("span", "kb-result-export");
|
|
3552
|
+
const exports = h("span", "icen-kb-result-export");
|
|
1901
3553
|
for (const fmt2 of result.exportFormats) {
|
|
1902
|
-
const btn = h("button", "kb-result-export-btn",
|
|
3554
|
+
const btn = h("button", "icen-kb-result-export-btn", t("kbAnswer.exportNoun", { p0: fmt2 }));
|
|
1903
3555
|
btn.type = "button";
|
|
1904
|
-
btn.dataset.
|
|
3556
|
+
btn.dataset.icenFormat = fmt2;
|
|
1905
3557
|
if (!opts?.onExport) btn.disabled = true;
|
|
1906
3558
|
else btn.addEventListener("click", () => opts.onExport?.(fmt2));
|
|
1907
3559
|
exports.appendChild(btn);
|
|
@@ -1909,13 +3561,13 @@ function renderResult(result, opts) {
|
|
|
1909
3561
|
meta.appendChild(exports);
|
|
1910
3562
|
}
|
|
1911
3563
|
wrap.appendChild(meta);
|
|
1912
|
-
const scroll = h("div", "kb-result-scroll");
|
|
1913
|
-
const table = h("table", "kb-result-table");
|
|
3564
|
+
const scroll = h("div", "icen-kb-result-scroll");
|
|
3565
|
+
const table = h("table", "icen-kb-result-table");
|
|
1914
3566
|
const numCols = result.columns.map((c, i) => isNumericColumn(c, i, result.rows));
|
|
1915
3567
|
const thead = document.createElement("thead");
|
|
1916
3568
|
const headRow = document.createElement("tr");
|
|
1917
3569
|
result.columns.forEach((c, i) => {
|
|
1918
|
-
headRow.appendChild(h("th", numCols[i] ? "kb-num" : "", c.name));
|
|
3570
|
+
headRow.appendChild(h("th", numCols[i] ? "icen-kb-num" : "", c.name));
|
|
1919
3571
|
});
|
|
1920
3572
|
thead.appendChild(headRow);
|
|
1921
3573
|
table.appendChild(thead);
|
|
@@ -1925,10 +3577,10 @@ function renderResult(result, opts) {
|
|
|
1925
3577
|
result.columns.forEach((_, i) => {
|
|
1926
3578
|
const v = row[i];
|
|
1927
3579
|
if (v == null) {
|
|
1928
|
-
const td = h("td", "kb-result-null", "\u2014");
|
|
3580
|
+
const td = h("td", "icen-kb-result-null", "\u2014");
|
|
1929
3581
|
tr.appendChild(td);
|
|
1930
3582
|
} else {
|
|
1931
|
-
tr.appendChild(h("td", typeof v === "number" ? "kb-num" : "", String(v)));
|
|
3583
|
+
tr.appendChild(h("td", typeof v === "number" ? "icen-kb-num" : "", String(v)));
|
|
1932
3584
|
}
|
|
1933
3585
|
});
|
|
1934
3586
|
tbody.appendChild(tr);
|
|
@@ -1939,14 +3591,14 @@ function renderResult(result, opts) {
|
|
|
1939
3591
|
if (result.truncated) {
|
|
1940
3592
|
const total = result.totalRows != null ? formatCount(result.totalRows) : "\u2014";
|
|
1941
3593
|
const limitPart = result.limit != null ? `\uFF08LIMIT ${formatCount(result.limit)}\uFF09` : "";
|
|
1942
|
-
wrap.appendChild(h("div", "kb-notice kb-result-truncated",
|
|
3594
|
+
wrap.appendChild(h("div", "icen-kb-notice icen-kb-result-truncated", t("kbAnswer.truncated", { p0: formatCount(result.rowCount), p1: total, p2: limitPart })));
|
|
1943
3595
|
}
|
|
1944
3596
|
return wrap;
|
|
1945
3597
|
}
|
|
1946
3598
|
var CHART_SWITCHES = [
|
|
1947
|
-
{ type: "line", label: "
|
|
1948
|
-
{ type: "vbar", label: "
|
|
1949
|
-
{ type: "donut", label: "
|
|
3599
|
+
{ type: "line", label: t("kbAnswer.chartLine") },
|
|
3600
|
+
{ type: "vbar", label: t("kbAnswer.chartBar") },
|
|
3601
|
+
{ type: "donut", label: t("kbAnswer.chartPie") }
|
|
1950
3602
|
];
|
|
1951
3603
|
function switchable(spec) {
|
|
1952
3604
|
const hasCat = (spec.labels?.length ?? 0) > 0 && ((spec.values?.length ?? 0) > 0 || (spec.series?.length ?? 0) > 0);
|
|
@@ -1977,14 +3629,14 @@ function specAsType(base, target) {
|
|
|
1977
3629
|
function renderChartArea(raw) {
|
|
1978
3630
|
if (raw == null) return null;
|
|
1979
3631
|
const norm = normalizeChartSpec(raw);
|
|
1980
|
-
const area = h("div", "kb-answer-chart");
|
|
1981
|
-
const mount = h("div", "chart kb-chart-mount");
|
|
3632
|
+
const area = h("div", "icen-kb-answer-chart");
|
|
3633
|
+
const mount = h("div", "icen-chart icen-kb-chart-mount");
|
|
1982
3634
|
const handle = renderChart(mount, norm);
|
|
1983
3635
|
if (switchable(handle.spec)) {
|
|
1984
|
-
const switchRow = h("div", "kb-chart-switch");
|
|
3636
|
+
const switchRow = h("div", "icen-kb-chart-switch");
|
|
1985
3637
|
const chips = /* @__PURE__ */ new Map();
|
|
1986
3638
|
for (const s of CHART_SWITCHES) {
|
|
1987
|
-
const chip = h("button", "kb-chart-chip", s.label);
|
|
3639
|
+
const chip = h("button", "icen-kb-chart-chip", s.label);
|
|
1988
3640
|
chip.type = "button";
|
|
1989
3641
|
chip.dataset.chartType = s.type;
|
|
1990
3642
|
if (handle.spec.type === s.type) chip.classList.add("is-active");
|
|
@@ -2006,9 +3658,9 @@ function renderKbAnswer(el, model, opts) {
|
|
|
2006
3658
|
if (typeof document === "undefined") return el;
|
|
2007
3659
|
const m = model ?? {};
|
|
2008
3660
|
el.textContent = "";
|
|
2009
|
-
const root = h("article", "kb-answer");
|
|
2010
|
-
root.dataset.
|
|
2011
|
-
const badges = h("div", "kb-answer-badges");
|
|
3661
|
+
const root = h("article", "icen-kb-answer");
|
|
3662
|
+
root.dataset.icenKind = m.kind === "verified" ? "verified" : "generated";
|
|
3663
|
+
const badges = h("div", "icen-kb-answer-badges");
|
|
2012
3664
|
if (m.kind === "verified" && m.verifiedVia) badges.appendChild(renderVerifiedBadge(m.verifiedVia, opts));
|
|
2013
3665
|
if (m.permissionNotice && (m.permissionNotice.rowLevelPolicy || m.permissionNotice.maskedColumns?.length)) {
|
|
2014
3666
|
badges.appendChild(renderPermissionNotice(m.permissionNotice));
|
|
@@ -2016,7 +3668,7 @@ function renderKbAnswer(el, model, opts) {
|
|
|
2016
3668
|
if (badges.children.length > 0) root.appendChild(badges);
|
|
2017
3669
|
if (typeof m.body === "string" && m.body) root.appendChild(renderBody(m.body, m.citations));
|
|
2018
3670
|
if (m.clarify && (m.clarify.question || m.clarify.options?.length)) {
|
|
2019
|
-
const slot = h("div", "kb-answer-clarify");
|
|
3671
|
+
const slot = h("div", "icen-kb-answer-clarify");
|
|
2020
3672
|
renderKbClarify(slot, m.clarify);
|
|
2021
3673
|
root.appendChild(slot);
|
|
2022
3674
|
}
|
|
@@ -2024,7 +3676,7 @@ function renderKbAnswer(el, model, opts) {
|
|
|
2024
3676
|
const f = m.explain;
|
|
2025
3677
|
const hasAny = f.tables?.length || f.columns?.length || f.filters?.length || f.aggregates?.length || f.metrics?.length;
|
|
2026
3678
|
if (hasAny) {
|
|
2027
|
-
const slot = h("div", "kb-answer-explain");
|
|
3679
|
+
const slot = h("div", "icen-kb-answer-explain");
|
|
2028
3680
|
renderKbExplain(slot, f);
|
|
2029
3681
|
root.appendChild(slot);
|
|
2030
3682
|
}
|
|
@@ -2037,10 +3689,10 @@ function renderKbAnswer(el, model, opts) {
|
|
|
2037
3689
|
if (chartArea) root.appendChild(chartArea);
|
|
2038
3690
|
const followUps = (m.followUps ?? []).map((s) => String(s ?? "").trim()).filter(Boolean);
|
|
2039
3691
|
if (followUps.length > 0) {
|
|
2040
|
-
const row = h("div", "kb-answer-followups");
|
|
2041
|
-
row.appendChild(h("span", "kb-followups-label", "
|
|
3692
|
+
const row = h("div", "icen-kb-answer-followups");
|
|
3693
|
+
row.appendChild(h("span", "icen-kb-followups-label", t("kbAnswer.followups")));
|
|
2042
3694
|
for (const text of followUps) {
|
|
2043
|
-
const chip = h("button", "kb-chip kb-followup", text);
|
|
3695
|
+
const chip = h("button", "icen-kb-chip icen-kb-followup", text);
|
|
2044
3696
|
chip.type = "button";
|
|
2045
3697
|
chip.addEventListener("click", () => opts?.onFollowUp?.(text));
|
|
2046
3698
|
row.appendChild(chip);
|