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