@dan-ai-studio/dshopencodego 0.1.73 → 0.1.75
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/README.en.md +9 -11
- package/README.md +8 -10
- package/lib/client.js +60 -0
- package/lib/index.js +285 -142
- package/lib/types/config.d.ts +21 -6
- package/lib/types/image-budget.d.ts +32 -0
- package/lib/types/index.d.ts +1 -1
- package/package.json +26 -26
package/README.en.md
CHANGED
|
@@ -101,9 +101,7 @@ Configuration lives in the profile's `cordis.patch.yml`:
|
|
|
101
101
|
# the timer restarts on every answer, so a connection in
|
|
102
102
|
# frequent use is never dropped; a long pause in a
|
|
103
103
|
# conversation costs one handshake (about 200ms)
|
|
104
|
-
|
|
105
|
-
requestImagePixelBudget: 1440000 # total-pixel budget for one image
|
|
106
|
-
requestImageMaxBytes: 400000 # encoded-byte target for one image (before base64)
|
|
104
|
+
imageBudgetPreset: dsh # image budget preset: dsh / dshopencodego / pi-ai (default dsh, the host's own values)
|
|
107
105
|
modelVisibility: # per-model switches; unlisted models follow the default rule (see "The model list in the settings page")
|
|
108
106
|
glm-5: true
|
|
109
107
|
modelLimits: # per-model capacity overrides
|
|
@@ -156,13 +154,13 @@ The API key comes from the Harness credential store (reference name `OPENCODE_GO
|
|
|
156
154
|
- The log is a ring buffer (oldest dropped first) that dies with the process; snapshots are read on demand, never polled, so a page nobody opens costs no traffic.
|
|
157
155
|
- The credential never enters a record: the recorder takes no headers argument at all, only the allowlisted session id and user agent. Failed requests are recorded with their error code; a request cut off before any terminal event is not recorded — no total reported, none invented.
|
|
158
156
|
|
|
159
|
-
**Images**:
|
|
157
|
+
**Images**: an over-budget image is refused explicitly rather than silently downscaled or dropped. The budgets ride one preset `imageBudgetPreset` (three choices, default `dsh`), not three numbers:
|
|
160
158
|
|
|
161
|
-
|
|
|
162
|
-
| --- | --- | --- |
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
159
|
+
| Preset | Per-image pixels | Per-image bytes (pre-base64) | Whole-request bytes (post-base64) |
|
|
160
|
+
| --- | --- | --- | --- |
|
|
161
|
+
| `dsh` (default) | 2048×2048 | 1MB | 20 MiB |
|
|
162
|
+
| `dshopencodego` | 1.44M px | 400 KB | 6 MiB |
|
|
163
|
+
| `pi-ai` | 2000×2000 | 4.5MB | 20 MiB |
|
|
166
164
|
|
|
167
165
|
A model that does not accept image input is rejected before the request is sent (`UNSUPPORTED_CONTENT`), so nothing is uploaded only to be refused by the gateway.
|
|
168
166
|
|
|
@@ -253,7 +251,7 @@ The verdict:
|
|
|
253
251
|
| `peerDependencies` (20 `@deepseek-ai/dsh-*` packages) | all `>=0.2.0-rc.1 <0.3.0-0` | takes over only when `engines.dsh` is absent; this plugin declares it, so the peers take no part today |
|
|
254
252
|
| `@deepseek-ai/cordis` | `4.0.4 \|\| 4.0.5-alpha.1 \|\| 4.0.5-alpha.2 \|\| 4.0.5` | the same peer channel |
|
|
255
253
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | the package manager |
|
|
256
|
-
| bundled `@earendil-works/pi-ai` | `~1.
|
|
254
|
+
| bundled `@earendil-works/pi-ai` | `~1.4.0` (within 1.4.x), **compiled into `lib/`** (devDependency) | an independent coupling: a change in pi-ai's request construction changes this plugin's wire behaviour, and its opencode-go builtin catalog is this plugin's fallback data. Bundling leaves the plugin with **no runtime dependencies** for an installer to resolve |
|
|
257
255
|
| bundled `@deepseek-ai/schemastery` | `~3.18.5-alpha.2`, **compiled into `lib/`** (devDependency) | a build-time dependency |
|
|
258
256
|
|
|
259
257
|
Things to keep in mind when maintaining this:
|
|
@@ -277,7 +275,7 @@ Things to keep in mind when maintaining this:
|
|
|
277
275
|
| The usage button shows "unavailable" | An endpoint or credential change invalidated the previous reading. Fix the configuration and press Retry. It never shows `0` in place of a missing reading. |
|
|
278
276
|
| npm publish fails with `ENEEDAUTH` | OIDC did not match: check the Trusted Publisher's **workflow filename** (must be exactly `publish-npm.yml`, case-sensitive) and the organization/repository fields; run on GitHub-hosted runners with `id-token: write`. A `repository.url` that does not match the GitHub repository is rejected as well. |
|
|
279
277
|
| A flood of `Accessing non-existent property 'Allow' of module exports inside circular dependency` | Caused by `pi-ai`'s **named import** of `partial-json`: resolving a named export from CommonJS enumerates the module's exports, and that package's `index.js`/`options.js` require each other, so reading `Allow` before its module initialises prints once per read — **a plugin reload turns it into a flood** (a restart usually clears it). **Removed at the mechanism since v0.1.38**: `pi-ai` and `partial-json` are now **compiled into the bundle**, so Node's ESM→CJS interop is not involved and there is no enumeration of an uninitialised export to begin with. That is a fix, not a filter. |
|
|
280
|
-
| The whole DSH process stalls during ultra-long tool calls (multi-MB arguments) | Observed on pi-ai `0.87.1`: per-delta re-parsing of the accumulated arguments (issue #9265 / PR #9461). This plugin does not port DSH's consumer-side patch (ADR-0005); the bundled dependency is now `~1.
|
|
278
|
+
| The whole DSH process stalls during ultra-long tool calls (multi-MB arguments) | Observed on pi-ai `0.87.1`: per-delta re-parsing of the accumulated arguments (issue #9265 / PR #9461). This plugin does not port DSH's consumer-side patch (ADR-0005); the bundled dependency is now `~1.4.0`, so a recurrence would be upstream behaviour and would be fixed by an upstream release. |
|
|
281
279
|
|
|
282
280
|
## Development
|
|
283
281
|
|
package/README.md
CHANGED
|
@@ -100,9 +100,7 @@ DSH 桌面端是 Electron 壳 + 完整的 dsh Web 应用,本插件对它同样
|
|
|
100
100
|
keepAliveTimeoutMs: 600000 # 连接空闲保留:两次请求之间连接留多久(毫秒,1 ~ 1800000)
|
|
101
101
|
# 每次收到回答后重新计时,所以常用时连接不会被断开;
|
|
102
102
|
# 对话中每次停顿较久都要重新握手一次(约 200ms)
|
|
103
|
-
|
|
104
|
-
requestImagePixelBudget: 1440000 # 单张图的总像素预算
|
|
105
|
-
requestImageMaxBytes: 400000 # 单张图编码前的字节目标(base64 之前)
|
|
103
|
+
imageBudgetPreset: dsh # 图片预算三选一:dsh / dshopencodego / pi-ai(默认 dsh,即宿主自带值)
|
|
106
104
|
modelVisibility: # 逐模型开关;未写到的模型走默认规则(见「设置页里的模型列表」)
|
|
107
105
|
glm-5: true
|
|
108
106
|
modelLimits: # 逐模型容量覆盖
|
|
@@ -157,11 +155,11 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
157
155
|
|
|
158
156
|
**图片**:三个字段各管一层,超限的图片会被明确拒绝,而不是静默降质或丢弃:
|
|
159
157
|
|
|
160
|
-
|
|
|
161
|
-
| --- | --- | --- |
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
158
|
+
| 预设 | 单张像素 | 单张字节(base64 前) | 整单字节(base64 后) |
|
|
159
|
+
| --- | --- | --- | --- |
|
|
160
|
+
| `dsh`(默认) | 2048×2048 | 1MB | 20 MiB |
|
|
161
|
+
| `dshopencodego` | 144 万像素 | 400 KB | 6 MiB |
|
|
162
|
+
| `pi-ai` | 2000×2000 | 4.5MB | 20 MiB |
|
|
165
163
|
|
|
166
164
|
模型自身不支持图片输入时,适配器会在发请求前就拒绝(`UNSUPPORTED_CONTENT`),不会把图发出去再等网关报错。
|
|
167
165
|
|
|
@@ -252,7 +250,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
252
250
|
| `peerDependencies`(20 个 `@deepseek-ai/dsh-*`) | 均为 `>=0.2.0-rc.1 <0.3.0-0` | 仅当 `engines.dsh` 缺席时才接管;本插件声明了它,故当前不参与判定 |
|
|
253
251
|
| `@deepseek-ai/cordis` | `4.0.4 \|\| 4.0.5-alpha.1 \|\| 4.0.5-alpha.2 \|\| 4.0.5` | 同上(peer 通道) |
|
|
254
252
|
| `engines.node` | `^22.19.0 \|\| >=24.0.0` | 包管理器 |
|
|
255
|
-
| 已打包依赖 `@earendil-works/pi-ai` | `~1.
|
|
253
|
+
| 已打包依赖 `@earendil-works/pi-ai` | `~1.4.0`(1.4.x 内),**打进产物**(devDependency) | 独立耦合:pi-ai 改请求构造即影响本插件的线上行为;其 opencode-go 内置目录同时是本插件的打底数据。打包后本插件**没有任何运行时依赖**,安装者不必再解析它 |
|
|
256
254
|
| 已打包依赖 `@deepseek-ai/schemastery` | `~3.18.5-alpha.2`,**打进产物**(devDependency) | 构建期依赖 |
|
|
257
255
|
|
|
258
256
|
维护时需要注意:
|
|
@@ -276,7 +274,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
276
274
|
| 用量按钮显示「不可用」 | 端点或凭证变化导致旧读数作废;配置正确后点「重试」。数值不会以 0 冒充。 |
|
|
277
275
|
| npm 发布报 `ENEEDAUTH` | OIDC 没匹配上:核对包设置里 Trusted Publisher 的 **workflow 文件名**(必须恰为 `publish-npm.yml`、大小写敏感)与组织/仓库字段;确认跑在 GitHub 托管 runner 上且工作流带 `id-token: write`。`package.json` 的 `repository.url` 与仓库不符也会被拒。 |
|
|
278
276
|
| 日志成片出现 `Accessing non-existent property 'Allow' of module exports inside circular dependency` | 成因是 `pi-ai` 对 `partial-json` 的**具名导入**:Node 解析 CJS 的具名导出时会枚举其 exports,而该包内部 `index.js`/`options.js` 互相 require,读到尚未初始化的 `Allow` 就打印一次——**插件重载会让它成片出现**(重启后往往消失)。**自 v0.1.38 起从机制上消除**:`pi-ai` 与 `partial-json` 已**打包进产物**,Node 的 ESM→CJS 互操作不再参与,因此不存在"枚举读到未初始化属性"这一步(不是过滤,是让该路径不存在)。 |
|
|
279
|
-
| 超长工具调用(多 MB 参数)期间整个 DSH 进程卡顿 | 曾在 pi-ai `0.87.1` 上观测到逐 delta 重解析的固有开销(issue #9265 / PR #9461)。本插件不移植 DSH 的消费者侧补丁(ADR-0005);当前自带依赖已是 `~1.
|
|
277
|
+
| 超长工具调用(多 MB 参数)期间整个 DSH 进程卡顿 | 曾在 pi-ai `0.87.1` 上观测到逐 delta 重解析的固有开销(issue #9265 / PR #9461)。本插件不移植 DSH 的消费者侧补丁(ADR-0005);当前自带依赖已是 `~1.4.0`,若仍复现则属上游行为,随其发版解决。 |
|
|
280
278
|
|
|
281
279
|
## 开发
|
|
282
280
|
|
package/lib/client.js
CHANGED
|
@@ -507,6 +507,11 @@ var en = {
|
|
|
507
507
|
refreshHint: "How long requests and the model picker reuse one listing.",
|
|
508
508
|
keepAliveLabel: "Connection kept idle (seconds)",
|
|
509
509
|
keepAliveHint: "How long a connection to the gateway is held between requests. Longer pauses in a conversation cost one handshake each; the timer restarts on every answer.",
|
|
510
|
+
imageBudgetPresetLabel: "Image budget preset",
|
|
511
|
+
imageBudgetPresetHint: "Which budgets size request images: the DSH defaults, this plugin\u2019s tighter set, or pi-ai\u2019s catalog profile.",
|
|
512
|
+
imageBudgetPresetDsh: "DSH default (2048\xD72048 / 1MB / 20MB)",
|
|
513
|
+
imageBudgetPresetDshopencodego: "This plugin (1.44M px / 400KB / 6MB)",
|
|
514
|
+
imageBudgetPresetPiAi: "pi-ai catalog (2000\xD72000 / 4.5MB / 20MB)",
|
|
510
515
|
requestLogTitle: "Request log",
|
|
511
516
|
requestLogHint: "Per-request records for troubleshooting. On by default; turning it off returns the request path to exactly as without the log.",
|
|
512
517
|
requestLogPageHint: "One row per request. Click a column head to sort; the table scrolls and the filters stay put.",
|
|
@@ -700,6 +705,11 @@ var zh = {
|
|
|
700
705
|
refreshHint: "\u8BF7\u6C42\u4E0E\u6A21\u578B\u9009\u62E9\u5668\u590D\u7528\u540C\u4E00\u4EFD\u5217\u8868\u7684\u65F6\u957F\u3002",
|
|
701
706
|
keepAliveLabel: "\u8FDE\u63A5\u7A7A\u95F2\u4FDD\u7559\uFF08\u79D2\uFF09",
|
|
702
707
|
keepAliveHint: "\u4E0E\u7F51\u5173\u7684\u8FDE\u63A5\u5728\u4E24\u6B21\u8BF7\u6C42\u4E4B\u95F4\u4FDD\u7559\u591A\u4E45\u3002\u5BF9\u8BDD\u4E2D\u6BCF\u6B21\u505C\u987F\u8F83\u4E45\u90FD\u8981\u91CD\u65B0\u63E1\u624B\u4E00\u6B21\uFF1B\u6BCF\u6B21\u6536\u5230\u56DE\u7B54\u540E\u8BA1\u65F6\u90FD\u4F1A\u91CD\u65B0\u5F00\u59CB\u3002",
|
|
708
|
+
imageBudgetPresetLabel: "\u56FE\u7247\u9884\u7B97\u9884\u8BBE",
|
|
709
|
+
imageBudgetPresetHint: "\u8BF7\u6C42\u56FE\u7247\u6309\u54EA\u5957\u9884\u7B97\u7F29\u653E\uFF1ADSH \u9ED8\u8BA4\u3001\u672C\u63D2\u4EF6\u7684\u66F4\u7D27\u51D1\u503C\u3001\u6216 pi-ai \u76EE\u5F55\u914D\u7F6E\u3002",
|
|
710
|
+
imageBudgetPresetDsh: "DSH \u9ED8\u8BA4\uFF082048\xD72048 / 1MB / 20MB\uFF09",
|
|
711
|
+
imageBudgetPresetDshopencodego: "\u672C\u63D2\u4EF6\uFF08144\u4E07\u50CF\u7D20 / 400KB / 6MB\uFF09",
|
|
712
|
+
imageBudgetPresetPiAi: "pi-ai \u76EE\u5F55\uFF082000\xD72000 / 4.5MB / 20MB\uFF09",
|
|
703
713
|
requestLogTitle: "\u8BF7\u6C42\u65E5\u5FD7",
|
|
704
714
|
requestLogHint: "\u6392\u67E5\u7528\u7684\u9010\u8BF7\u6C42\u8BB0\u5F55\u3002\u9ED8\u8BA4\u5F00\u542F\uFF1B\u5173\u95ED\u540E\u8BF7\u6C42\u8DEF\u5F84\u4E0E\u6CA1\u6709\u8BE5\u65E5\u5FD7\u9010\u5B57\u8282\u4E00\u81F4\u3002",
|
|
705
715
|
requestLogPageHint: "\u6BCF\u4E2A\u8BF7\u6C42\u4E00\u884C\u3002\u70B9\u5217\u5934\u53EF\u6392\u5E8F\uFF1B\u8868\u683C\u6EDA\u52A8\uFF0C\u7B5B\u9009\u680F\u56FA\u5B9A\u5728\u4E0A\u65B9\u3002",
|
|
@@ -869,6 +879,17 @@ var MAX_KEEP_ALIVE_TIMEOUT_SECONDS = 1800;
|
|
|
869
879
|
var DEFAULT_KEEP_ALIVE_TIMEOUT_MS = DEFAULT_KEEP_ALIVE_TIMEOUT_SECONDS * 1e3;
|
|
870
880
|
var MAX_KEEP_ALIVE_TIMEOUT_MS = MAX_KEEP_ALIVE_TIMEOUT_SECONDS * 1e3;
|
|
871
881
|
|
|
882
|
+
// src/image-budget.ts
|
|
883
|
+
var IMAGE_BUDGET_PRESETS = ["dsh", "dshopencodego", "pi-ai"];
|
|
884
|
+
var IMAGE_BUDGETS = {
|
|
885
|
+
dsh: { maxPixels: 2048 * 2048, maxBytes: 1024 * 1024, maxRequestBytes: 20 * 1024 * 1024 },
|
|
886
|
+
dshopencodego: { maxPixels: 144e4, maxBytes: 4e5, maxRequestBytes: 6 * 1024 * 1024 },
|
|
887
|
+
"pi-ai": { maxPixels: 2e3 * 2e3, maxBytes: 4718592, maxRequestBytes: 20 * 1024 * 1024 }
|
|
888
|
+
};
|
|
889
|
+
function isImageBudgetPreset(value) {
|
|
890
|
+
return typeof value === "string" && IMAGE_BUDGET_PRESETS.includes(value);
|
|
891
|
+
}
|
|
892
|
+
|
|
872
893
|
// src/request-log/limits.ts
|
|
873
894
|
var DEFAULT_REQUEST_LOG_MAX_ENTRIES = 200;
|
|
874
895
|
var MIN_REQUEST_LOG_MAX_ENTRIES = 50;
|
|
@@ -1035,6 +1056,7 @@ function settingsOf(value) {
|
|
|
1035
1056
|
const pins = record["pinnedAddresses"];
|
|
1036
1057
|
const pinEntries = pins !== null && typeof pins === "object" ? Object.entries(pins).filter(([, address]) => typeof address === "string") : [];
|
|
1037
1058
|
const keepAlive = record["keepAliveTimeoutMs"];
|
|
1059
|
+
const imageBudgetPreset = record["imageBudgetPreset"];
|
|
1038
1060
|
const requestLogEnabled = record["requestLogEnabled"];
|
|
1039
1061
|
const requestLogDebug = record["requestLogDebug"];
|
|
1040
1062
|
const requestLogMaxEntries = record["requestLogMaxEntries"];
|
|
@@ -1043,6 +1065,7 @@ function settingsOf(value) {
|
|
|
1043
1065
|
refreshMinutes: minutes,
|
|
1044
1066
|
pinnedAddresses: Object.fromEntries(pinEntries),
|
|
1045
1067
|
keepAliveTimeoutMs: typeof keepAlive === "number" ? keepAlive : DEFAULT_KEEP_ALIVE_TIMEOUT_MS,
|
|
1068
|
+
imageBudgetPreset: isImageBudgetPreset(imageBudgetPreset) ? imageBudgetPreset : "dsh",
|
|
1046
1069
|
requestLogEnabled: typeof requestLogEnabled === "boolean" ? requestLogEnabled : true,
|
|
1047
1070
|
requestLogDebug: typeof requestLogDebug === "boolean" ? requestLogDebug : false,
|
|
1048
1071
|
requestLogMaxEntries: typeof requestLogMaxEntries === "number" ? requestLogMaxEntries : DEFAULT_REQUEST_LOG_MAX_ENTRIES
|
|
@@ -1485,6 +1508,20 @@ var SectionController = class _SectionController {
|
|
|
1485
1508
|
() => this.set({ settings: { ...current, requestLogDebug: debug } })
|
|
1486
1509
|
);
|
|
1487
1510
|
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Switch the image-budget preset. Unknown values are ignored; the page
|
|
1513
|
+
* never writes a preset it cannot name.
|
|
1514
|
+
*/
|
|
1515
|
+
async setImageBudgetPreset(preset) {
|
|
1516
|
+
const scope = this.services.scope;
|
|
1517
|
+
const current = this.state.settings;
|
|
1518
|
+
if (scope === void 0 || current === void 0 || !this.state.writable) return;
|
|
1519
|
+
if (!isImageBudgetPreset(preset)) return;
|
|
1520
|
+
await this.write(
|
|
1521
|
+
() => scope.set("imageBudgetPreset", preset),
|
|
1522
|
+
() => this.set({ settings: { ...current, imageBudgetPreset: preset } })
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1488
1525
|
/**
|
|
1489
1526
|
* Set how many request-log entries the Host keeps, clamped to the schema's
|
|
1490
1527
|
* own bounds. A lowered bound trims on the next read; raising it backfills
|
|
@@ -1898,6 +1935,29 @@ function Section({ controller, t, getLocale, openRequestLog }) {
|
|
|
1898
1935
|
),
|
|
1899
1936
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.hint, children: t("keepAliveHint") })
|
|
1900
1937
|
] }),
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: section_default.row, children: [
|
|
1939
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: section_default.hint, htmlFor: "dshopencodego-image-budget", children: t("imageBudgetPresetLabel") }),
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1941
|
+
"select",
|
|
1942
|
+
{
|
|
1943
|
+
id: "dshopencodego-image-budget",
|
|
1944
|
+
className: section_default.select,
|
|
1945
|
+
disabled: !editable || state.saving,
|
|
1946
|
+
value: state.settings?.imageBudgetPreset ?? "dsh",
|
|
1947
|
+
onChange: (event) => {
|
|
1948
|
+
void act(async () => {
|
|
1949
|
+
await controller.setImageBudgetPreset(event.target.value);
|
|
1950
|
+
});
|
|
1951
|
+
},
|
|
1952
|
+
children: [
|
|
1953
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "dsh", children: t("imageBudgetPresetDsh") }),
|
|
1954
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "dshopencodego", children: t("imageBudgetPresetDshopencodego") }),
|
|
1955
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "pi-ai", children: t("imageBudgetPresetPiAi") })
|
|
1956
|
+
]
|
|
1957
|
+
}
|
|
1958
|
+
),
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.hint, children: t("imageBudgetPresetHint") })
|
|
1960
|
+
] }),
|
|
1901
1961
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: section_default.row, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: t("requestLogTitle") }) }),
|
|
1902
1962
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: section_default.hint, children: t("requestLogHint") }),
|
|
1903
1963
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: section_default.row, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: section_default.hint, children: [
|