dsh-bill-ilife 0.3.13 → 0.3.15
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/dist/client.js +121 -24
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +0 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +0 -1
- package/dist/settings.js.map +1 -1
- package/package.json +3 -3
package/dist/client.js
CHANGED
|
@@ -43,9 +43,12 @@ window.__ModuleLoader__.load({
|
|
|
43
43
|
const RPC_ENDPOINT_CONFIG_GET = "config.get";
|
|
44
44
|
const RPC_ENDPOINT_CONFIG_SAVE = "config.save";
|
|
45
45
|
const RPC_ENDPOINT_CONFIG_RESET = "config.reset";
|
|
46
|
-
/**
|
|
46
|
+
/** 高级组标题(六家逐字相同,收在这里一处)。
|
|
47
|
+
*
|
|
48
|
+
* #934:原先还有一条副文案 `ADVANCED_GROUP_NOTE`(「不常改。留空=用默认值。」),
|
|
49
|
+
* 维护者裁定**整条删除、删后不另找地方说**——理由:三家高级项全是只读行、不参与保存、根本没有"留空",
|
|
50
|
+
* 而"留空会怎样"这条口径本就逐行住在每条的 `hint` 里(见本件 `ConfigItem.hint` 的契约)。 */
|
|
47
51
|
const ADVANCED_GROUP_TITLE = "高级";
|
|
48
|
-
const ADVANCED_GROUP_NOTE = "不常改。留空=用默认值。";
|
|
49
52
|
/** 请求超时毫秒:与宿主侧 SPAWN_TIMEOUT_MS 同级,界面永不无限转圈。 */
|
|
50
53
|
const READ_TIMEOUT_MS = 2e4;
|
|
51
54
|
/** 复制那一枚按钮就地变「已复制」之后,多久变回「复制」(定稿 v3 第三条:1.5 秒,不弹提示)。 */
|
|
@@ -832,7 +835,7 @@ window.__ModuleLoader__.load({
|
|
|
832
835
|
textOverflow: "ellipsis",
|
|
833
836
|
whiteSpace: "nowrap"
|
|
834
837
|
},
|
|
835
|
-
error: { color: "var(--dsw-alias-
|
|
838
|
+
error: { color: "var(--dsw-alias-state-error-primary, #e66)" }
|
|
836
839
|
};
|
|
837
840
|
/** 面包屑:从文件系统根到当前层,每一格都是跳转目标(`listing.crumbs` 由取数方给)。 */
|
|
838
841
|
function crumbRow(state, onEnter) {
|
|
@@ -1087,6 +1090,23 @@ window.__ModuleLoader__.load({
|
|
|
1087
1090
|
* 键名一个都不许改:六家附加块真消费 `okText`/`error`/`rows`/`label`/`muted`/`hint`/`info`/
|
|
1088
1091
|
* `bar`/`btn` 这九格(`plugin-memo-ilife/src/client.ts`、`plugin-schedule-ilife/src/client.ts` 的
|
|
1089
1092
|
* `PanelStyleSlots`),跨包锁另钉 `card`/`input`/`btnPrimary`/`btnPick`/`summary`/`title`/`version`。 */
|
|
1093
|
+
/** #941/丁:**浅色档距自合成**——宿主在浅色下四层底同白(`bg-base = bg-layer-1/2/3`),
|
|
1094
|
+
* 拿不到可用的层级差,所以三处面(卡描边/沉底盒底/输入框描边)由我们自己按墨色派生。
|
|
1095
|
+
*
|
|
1096
|
+
* 取 `label-primary` 当墨色分母:浅色下它是近黑、深色下它是近白 ⇒ **同一条表达式两套主题都成立**
|
|
1097
|
+
* (浅色补出可用的档距,深色退化成今天那几档观感)。百分比来自维护者选定的方案丁:
|
|
1098
|
+
* 卡描边 19%/沉底盒底 9%/输入框描边 24%/骨架条 21%。这是本仓第一处"自定值",属真源增补
|
|
1099
|
+
* (v3.1 只有深色一套 token,从未覆盖浅色)。 */
|
|
1100
|
+
const PANEL_INK = "var(--dsw-alias-label-primary, #f9fafb)";
|
|
1101
|
+
const inkMix = (percent, into) => into === void 0 ? `color-mix(in srgb, ${PANEL_INK} ${percent}%, transparent)` : `color-mix(in srgb, ${PANEL_INK} ${percent}%, ${into})`;
|
|
1102
|
+
/** 卡片描边:浅色 ≈`#cfcfcf` ⇔ 深色 ≈`#4a4b4d`。 */
|
|
1103
|
+
const PANEL_CARD_EDGE = inkMix(19);
|
|
1104
|
+
/** 沉底盒底(母版行/高级组体/状态行):浅色 ≈`#e9e9e9` ⇔ 深色 ≈`#3a3b3d`。 */
|
|
1105
|
+
const PANEL_SUNKEN_FILL = inkMix(9, "var(--dsw-alias-bg-layer-1, #232324)");
|
|
1106
|
+
/** 输入框描边:浅色 ≈`#c4c4c4` ⇔ 深色 ≈`#5a5b5d`。 */
|
|
1107
|
+
const PANEL_FIELD_EDGE = inkMix(24);
|
|
1108
|
+
/** 骨架条:浅色 ≈`#c9ccd2`(1.6:1)⇔ 深色 ≈`#404143`。 */
|
|
1109
|
+
const PANEL_SKELETON_FILL = inkMix(21);
|
|
1090
1110
|
const S = {
|
|
1091
1111
|
/** `.ic-card`:`background:var(--ic-surface)`(=bg-layer-1)+`border:1px solid var(--ic-line-strong)`
|
|
1092
1112
|
* +`border-radius:12px`+`padding:14px`+`box-shadow:inset 0 1px 0 rgba(255,255,255,.06)`。
|
|
@@ -1094,7 +1114,7 @@ window.__ModuleLoader__.load({
|
|
|
1094
1114
|
card: {
|
|
1095
1115
|
padding: 14,
|
|
1096
1116
|
borderRadius: 12,
|
|
1097
|
-
border: "1px solid
|
|
1117
|
+
border: "1px solid " + PANEL_CARD_EDGE,
|
|
1098
1118
|
background: "var(--dsw-alias-bg-layer-1, #232324)",
|
|
1099
1119
|
color: "var(--dsw-alias-label-primary, #f9fafb)",
|
|
1100
1120
|
boxShadow: "inset 0 1px 0 rgba(255,255,255,.06)"
|
|
@@ -1114,6 +1134,83 @@ window.__ModuleLoader__.load({
|
|
|
1114
1134
|
/** `.ic-file{margin-top:4px}` 的那 4px 挂在两行的公共容器上:`info` 自己一格 margin 都不写
|
|
1115
1135
|
* (#743 ①:头部两行间距不一家一个数,故这一项一律不写 margin)。 */
|
|
1116
1136
|
fileWrap: { marginTop: 4 },
|
|
1137
|
+
/** #939:骨架条(照真源 `.ic-sk`:`display:block;height:17px;border-radius:4px`)。
|
|
1138
|
+
* 高度按一行正文画——inline-block 跟着父级行高走会让骨架行比填充后的文字行高 4px、六家叠起来就是一片下移。
|
|
1139
|
+
* 底色走派生值(宿主专用骨架档 `bg-skeleton` 在浅色下只有 1.09:1,等于看不见)。 */
|
|
1140
|
+
skeleton: {
|
|
1141
|
+
display: "block",
|
|
1142
|
+
height: 17,
|
|
1143
|
+
borderRadius: 4,
|
|
1144
|
+
background: PANEL_SKELETON_FILL
|
|
1145
|
+
},
|
|
1146
|
+
/** #936:状态行那一块(照真源 `.ic-status`)——沉底面盒子,里面三行:状态行/路径行/官网行。 */
|
|
1147
|
+
statusBox: {
|
|
1148
|
+
marginTop: 11,
|
|
1149
|
+
padding: "10px 12px",
|
|
1150
|
+
background: PANEL_SUNKEN_FILL,
|
|
1151
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
|
|
1152
|
+
borderRadius: 8
|
|
1153
|
+
},
|
|
1154
|
+
/** `.ic-srow{display:flex;align-items:center;gap:8px;font-size:12px;flex-wrap:wrap}`(12px ⇒ 0.86em)。 */
|
|
1155
|
+
statusRow: {
|
|
1156
|
+
display: "flex",
|
|
1157
|
+
alignItems: "center",
|
|
1158
|
+
gap: 8,
|
|
1159
|
+
fontSize: "0.86em",
|
|
1160
|
+
flexWrap: "wrap"
|
|
1161
|
+
},
|
|
1162
|
+
/** `.ic-dot{width:8px;height:8px;border-radius:50%}`——底色按档位在组件里补。 */
|
|
1163
|
+
statusDot: {
|
|
1164
|
+
width: 8,
|
|
1165
|
+
height: 8,
|
|
1166
|
+
borderRadius: "50%",
|
|
1167
|
+
flex: "0 0 auto"
|
|
1168
|
+
},
|
|
1169
|
+
/** `.ic-sname{font-weight:600;white-space:nowrap}`。 */
|
|
1170
|
+
statusName: {
|
|
1171
|
+
fontWeight: 600,
|
|
1172
|
+
whiteSpace: "nowrap"
|
|
1173
|
+
},
|
|
1174
|
+
/** `.ic-stxt{color:var(--ic-muted);min-width:0}`。 */
|
|
1175
|
+
statusText: {
|
|
1176
|
+
color: "var(--dsw-alias-label-secondary, #cfd3d6)",
|
|
1177
|
+
minWidth: 0
|
|
1178
|
+
},
|
|
1179
|
+
/** `.ic-sfind{display:flex;align-items:center;gap:8px;margin-top:7px}`。 */
|
|
1180
|
+
statusFind: {
|
|
1181
|
+
display: "flex",
|
|
1182
|
+
alignItems: "center",
|
|
1183
|
+
gap: 8,
|
|
1184
|
+
marginTop: 7
|
|
1185
|
+
},
|
|
1186
|
+
/** `.ic-spath{font-size:10.5px;color:var(--ic-faint);white-space:nowrap;overflow:hidden}`
|
|
1187
|
+
* ——单行不折、超出裁掉(**不写省略号**:本件有一条"零省略号"的跨包锁)。
|
|
1188
|
+
* **不写 `fontFamily`**:v3.1 这一格要 `var(--ic-mono)`,但 `#739 ①` 明令共用件零字族(宿主没有界面字族
|
|
1189
|
+
* token,钉死会在别的窗口尺寸上失真)——与真源的同一处已知不同,账在 #920 证据件里。 */
|
|
1190
|
+
statusPath: {
|
|
1191
|
+
fontSize: "0.75em",
|
|
1192
|
+
color: "var(--dsw-alias-label-tertiary, #adb2b8)",
|
|
1193
|
+
minWidth: 0,
|
|
1194
|
+
whiteSpace: "nowrap",
|
|
1195
|
+
overflow: "hidden"
|
|
1196
|
+
},
|
|
1197
|
+
/** `.ic-ver{font-size:10px;border:1px solid var(--ic-line-strong);border-radius:999px;padding:0 6px}`。 */
|
|
1198
|
+
statusVersion: {
|
|
1199
|
+
fontSize: "0.72em",
|
|
1200
|
+
color: "var(--dsw-alias-label-tertiary, #adb2b8)",
|
|
1201
|
+
border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
|
|
1202
|
+
borderRadius: 999,
|
|
1203
|
+
padding: "0 6px",
|
|
1204
|
+
whiteSpace: "nowrap"
|
|
1205
|
+
},
|
|
1206
|
+
/** `.ic-url{display:inline-block;margin-top:7px;font-size:10.5px;color:var(--ic-faint)}`
|
|
1207
|
+
* ——字族同样继承宿主(`#739 ①`:共用件零 `fontFamily`),理由同上一格。 */
|
|
1208
|
+
statusUrl: {
|
|
1209
|
+
display: "inline-block",
|
|
1210
|
+
marginTop: 7,
|
|
1211
|
+
fontSize: "0.75em",
|
|
1212
|
+
color: "var(--dsw-alias-label-tertiary, #adb2b8)"
|
|
1213
|
+
},
|
|
1117
1214
|
/** `.ic-file b{color:var(--ic-faint);font-weight:400;margin-right:5px}`(「配置文件」「数据目录」那两个字)。 */
|
|
1118
1215
|
fileLabel: {
|
|
1119
1216
|
color: "var(--dsw-alias-label-tertiary, #adb2b8)",
|
|
@@ -1239,7 +1336,7 @@ window.__ModuleLoader__.load({
|
|
|
1239
1336
|
/** `.ic-master`:母版行那一块盒子(`--ic-sunken` 底 + `border-radius:8px` + `padding:11px 12px`
|
|
1240
1337
|
* + `margin-top:11px` + 内高光)。 */
|
|
1241
1338
|
master: {
|
|
1242
|
-
background:
|
|
1339
|
+
background: PANEL_SUNKEN_FILL,
|
|
1243
1340
|
border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
|
|
1244
1341
|
borderRadius: 8,
|
|
1245
1342
|
padding: "11px 12px",
|
|
@@ -1279,7 +1376,7 @@ window.__ModuleLoader__.load({
|
|
|
1279
1376
|
padding: "5px 8px",
|
|
1280
1377
|
boxSizing: "border-box",
|
|
1281
1378
|
background: "var(--dsw-alias-bg-base, #151517)",
|
|
1282
|
-
border: "1px solid
|
|
1379
|
+
border: "1px solid " + PANEL_FIELD_EDGE,
|
|
1283
1380
|
borderRadius: 6,
|
|
1284
1381
|
color: "var(--dsw-alias-label-primary, #f9fafb)"
|
|
1285
1382
|
},
|
|
@@ -1346,18 +1443,13 @@ window.__ModuleLoader__.load({
|
|
|
1346
1443
|
},
|
|
1347
1444
|
/** `.ic-ghead::before{content:'›';color:var(--ic-muted)}`——画成真的那一个字符(内联样式给不出伪元素)。 */
|
|
1348
1445
|
groupMark: { color: "var(--dsw-alias-label-secondary, #cfd3d6)" },
|
|
1349
|
-
/**
|
|
1350
|
-
groupNote: {
|
|
1351
|
-
color: "var(--dsw-alias-label-tertiary, #adb2b8)",
|
|
1352
|
-
fontWeight: 400,
|
|
1353
|
-
fontSize: "0.92em"
|
|
1354
|
-
},
|
|
1446
|
+
/** #934:`.ic-gnote` 那条副文案的样式随之删除——副文案本身已按维护者裁定整条撤掉(零消费者的槽位不留)。 */
|
|
1355
1447
|
/** `.ic-group > .ic-gbody{margin-top:9px;padding:11px 12px;background:var(--ic-sunken);
|
|
1356
1448
|
* border-radius:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}`。 */
|
|
1357
1449
|
groupBody: {
|
|
1358
1450
|
marginTop: 9,
|
|
1359
1451
|
padding: "11px 12px",
|
|
1360
|
-
background:
|
|
1452
|
+
background: PANEL_SUNKEN_FILL,
|
|
1361
1453
|
border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
|
|
1362
1454
|
borderRadius: 8,
|
|
1363
1455
|
boxShadow: "inset 0 1px 0 rgba(255,255,255,.04)"
|
|
@@ -1413,14 +1505,8 @@ window.__ModuleLoader__.load({
|
|
|
1413
1505
|
cursor: "pointer",
|
|
1414
1506
|
whiteSpace: "nowrap"
|
|
1415
1507
|
},
|
|
1416
|
-
/**
|
|
1417
|
-
|
|
1418
|
-
marginTop: 8,
|
|
1419
|
-
paddingTop: 8,
|
|
1420
|
-
borderTop: "1px dashed var(--dsw-alias-border-l1, rgba(255,255,255,.06))",
|
|
1421
|
-
color: "var(--dsw-alias-label-tertiary, #adb2b8)",
|
|
1422
|
-
fontSize: "0.92em"
|
|
1423
|
-
},
|
|
1508
|
+
/** #934:原先这里有一格 `version`(各家附加块的版本行字面)。版本行已按维护者裁定整条撤掉
|
|
1509
|
+
*(那两家面板内的渲染点 + 六家各自那份字面副本),这一格随之删除:没人取的槽位不留。 */
|
|
1424
1510
|
/** `.ic-badge{font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;white-space:nowrap;
|
|
1425
1511
|
* display:inline-flex;align-items:center;gap:6px;border:1px solid transparent}`(11px ⇒ `0.88em`)。 */
|
|
1426
1512
|
badge: {
|
|
@@ -1619,7 +1705,18 @@ window.__ModuleLoader__.load({
|
|
|
1619
1705
|
kind: badge,
|
|
1620
1706
|
dirtyCount
|
|
1621
1707
|
}));
|
|
1622
|
-
|
|
1708
|
+
/** #939:这一块的高度由**客户端常量**决定、不由回执时序决定——加载期就把两行连标签一起画出来,
|
|
1709
|
+
* 值位画骨架条(`.ic-sk`),回执到了**原地填值** ⇒ 回执零位移(原先加载期只画一行小灰字、
|
|
1710
|
+
* 回执到了才长出两行,整块下移 21px)。
|
|
1711
|
+
*
|
|
1712
|
+
* 判断式按 `state.kind`:**不许**照 `surface === null` 写——它同时覆盖失败态,照写会让失败屏长出两行假骨架。 */
|
|
1713
|
+
const loading = state.kind === "loading";
|
|
1714
|
+
const fileValue = (text) => text === null ? react.createElement("span", {
|
|
1715
|
+
style: S.skeleton,
|
|
1716
|
+
"data-ilife-skeleton": "value"
|
|
1717
|
+
}) : text;
|
|
1718
|
+
const fileRow = (label, text, tail) => react.createElement("div", { style: S.info }, react.createElement("b", { style: S.fileLabel }, label), fileValue(text), tail === void 0 ? null : tail);
|
|
1719
|
+
const fileLines = !loading && surface === null ? null : react.createElement("div", { style: S.fileWrap }, fileRow("配置文件", surface === null ? null : surface.path, surface !== null && surface.created ? react.createElement("span", { style: S.muted }, "(配置文件刚按默认值生成)") : null), fileRow("数据目录", surface === null ? null : headDataDir));
|
|
1623
1720
|
const parts = {
|
|
1624
1721
|
styles: S,
|
|
1625
1722
|
reply: surface
|
|
@@ -1663,7 +1760,7 @@ window.__ModuleLoader__.load({
|
|
|
1663
1760
|
const commonLast = lastIndexOf(common);
|
|
1664
1761
|
const advancedLast = lastIndexOf(advanced);
|
|
1665
1762
|
const dirty = ready && dirtyCount > 0;
|
|
1666
|
-
return react.createElement("div", { style: S.card }, head, fileLines,
|
|
1763
|
+
return react.createElement("div", { style: S.card }, head, fileLines, react.createElement("div", { style: S.rows }, common.map((item, index) => renderRow(item, index === commonLast))), advanced.length === 0 ? null : react.createElement("details", { style: S.advanced }, react.createElement("summary", { style: S.summary }, react.createElement("span", { style: S.groupMark }, "›"), ADVANCED_GROUP_TITLE), react.createElement("div", { style: S.groupBody }, advanced.map((item, index) => renderRow(item, index === advancedLast)))), extra, react.createElement("div", { style: S.bar }, react.createElement("button", {
|
|
1667
1764
|
style: dirty ? S.btnPrimary : S.btn,
|
|
1668
1765
|
type: "button",
|
|
1669
1766
|
disabled: frozen || !dirty,
|
|
@@ -1678,7 +1775,7 @@ window.__ModuleLoader__.load({
|
|
|
1678
1775
|
type: "button",
|
|
1679
1776
|
disabled: frozen,
|
|
1680
1777
|
onClick: props.onRetry
|
|
1681
|
-
}, "重新读取"), dirty ? react.createElement("div", { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`) : ready ? react.createElement("div", { style: S.barNote }, "没有未保存的改动") :
|
|
1778
|
+
}, "重新读取"), dirty ? react.createElement("div", { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`) : ready ? react.createElement("div", { style: S.barNote }, "没有未保存的改动") : react.createElement("div", { style: S.barNote }, "配置读取中")), props.picking ? react.createElement("div", { style: S.muted }, "已唤起系统文件夹对话框:选中后自动填上,取消则不动。") : null, props.browseRow !== null ? react.createElement(DirectoryBrowserFromRow, {
|
|
1682
1779
|
open: true,
|
|
1683
1780
|
row: props.browseRow,
|
|
1684
1781
|
labels: BROWSER_LABELS
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["S","React","React","S","React","React","React"],"sources":["../../plugin-manager/dist/config-panel-contract.js","../../plugin-manager/dist/config-panel-value.js","../../plugin-manager/dist/directory-browser-contract.js","../../plugin-manager/dist/directory-browser-state.js","../../plugin-manager/dist/directory-browser-parts.js","../../plugin-manager/dist/directory-browser-ui.js","../../plugin-manager/dist/config-panel-view.js","../../plugin-manager/dist/directory-browser-roots.js","../../plugin-manager/dist/update-contract.js","../../plugin-manager/dist/config-panel.js","../src/contract.ts","../src/slot.ts","../src/settings.ts","../src/client.ts"],"sourcesContent":["/** 共用配置面板 · 契约:行表形状、配置面回执、几条两侧共用的常量。\n *\n * 为什么住这里:六个单品插件的设置页各有一份逐字相同的那套代码(卡片骨架/行渲染/样式表/\n * 状态机/配置面三通电话约 3105 行)。本件是抽件之后的**唯一一处定义地**。\n *\n * 本件不认识任何一家能力:行表由调用方给,分支只能由行表数据与配置面回执决定,\n * 里面不出现任何一个能力的名字(结构纪律「依赖方向」)。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\n/** 面板对配置面的三通电话:读整面/保存一份取值/重置为默认。三个名字各家逐字相同,收在这里一处。 */\nexport const RPC_ENDPOINT_CONFIG_GET = 'config.get';\nexport const RPC_ENDPOINT_CONFIG_SAVE = 'config.save';\nexport const RPC_ENDPOINT_CONFIG_RESET = 'config.reset';\n/** 高级组标题与副文案(六家逐字相同,收在这里一处)。 */\nexport const ADVANCED_GROUP_TITLE = '高级';\nexport const ADVANCED_GROUP_NOTE = '不常改。留空=用默认值。';\n/** 请求超时毫秒:与宿主侧 SPAWN_TIMEOUT_MS 同级,界面永不无限转圈。 */\nexport const READ_TIMEOUT_MS = 20_000;\n/** 复制那一枚按钮就地变「已复制」之后,多久变回「复制」(定稿 v3 第三条:1.5 秒,不弹提示)。 */\nexport const COPY_FEEDBACK_MS = 1500;\n/** 宿主给「这是哪一种目录选择能力」时用的那两格原语的名字(软依赖:按名字现取,缺席即没有入口)。 */\nexport const REMOTE_DIRECTORY_PICKER = 'remote.directoryPicker';\n/** 宿主在「这条路不给」时回的那个码(`directory-browser-state` 的 `openRowBrowser` 只照比不认名)。 */\nexport const DIRECTORY_PICKER_REFUSED = 'directory-picker/unavailable';\n/** 信封守卫:拆包前校验(信封形状的定义地在这里)。 */\nexport function isRpcResult(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return raw.ok === true || raw.ok === false;\n}\n//# sourceMappingURL=config-panel-contract.js.map","/** 共用配置面板 · 取值与填值半:一份配置取值 ↔ 一张表单态,外加脏基线、跟随键、人话报错与三通电话。\n *\n * 本件**不认识 React**,也不认识宿主:喂一份配置面回执与一张行表,它把「页面上每一行该显示什么」\n * 算出来(取值),再把「表单态里哪几格真能改」还原成一份取值(填值)。因此它在 Node 里就能直测。\n *\n * 三条口径(照 #749 起的定稿):\n * · **只读行显示技能算好的绝对值**(回执 `resolved` 组那一格):面板一个字都不算;回执缺那一格\n * (旧技能)就显示空串,绝不编一条路径出来。\n * · **可改行取值空着**时,直接把回执里那个落点绝对路径显示上去——用户不必自己拼路径。\n * · **保存只提交真能改的行**:只读行显示的是绝对路径,把它当配置值写回去就是把「显示」当「配置」。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport { RPC_ENDPOINT_CONFIG_GET, RPC_ENDPOINT_CONFIG_RESET, RPC_ENDPOINT_CONFIG_SAVE, READ_TIMEOUT_MS, isRpcResult, } from './config-panel-contract.js';\n/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */\nexport function readPath(values, key) {\n const parts = key.split('.');\n let cur = values;\n for (const part of parts) {\n if (typeof cur !== 'object' || cur === null || Array.isArray(cur))\n return undefined;\n cur = cur[part];\n }\n return cur;\n}\n/** 按 `a.b` 路径把值写进配置取值(中间层缺就建一层空组;已存在非组即覆盖成组)。 */\nexport function writePath(values, key, value) {\n const parts = key.split('.');\n let cur = values;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const next = cur[part];\n if (typeof next !== 'object' || next === null || Array.isArray(next))\n cur[part] = {};\n cur = cur[part];\n }\n cur[parts[parts.length - 1]] = value;\n}\n/** 落点来源取一格:先看回执 `resolved` 组同名格,再看回执顶层同名格(两种写法收成同一格)。\n *\n * 顶层那一格为什么只认 `dataDir`:它是**技能算出来的生效数据目录**这个概念的格名,各家的回执\n * 都叫它 `dataDir`;其余落点(照片目录、附件目录等)一律住在 `resolved` 组里。本件不猜别的名字。 */\nfunction prefillValueOf(source, name) {\n const fromResolved = source.resolved?.[name];\n if (typeof fromResolved === 'string' && fromResolved !== '')\n return fromResolved;\n if (name === 'dataDir' && typeof source.dataDir === 'string' && source.dataDir !== '')\n return source.dataDir;\n return undefined;\n}\n/** 只读行显示什么:标了 `resolveFrom` ⇒ 回执 `resolved` 组那一格(技能算好的绝对路径);\n * 没标 ⇒ 配置文件里那个值本身(数字类只读项走这一档:显示的是生效数字)。 */\nfunction readonlyTextOf(item, raw, source) {\n if (item.resolveFrom === undefined)\n return raw;\n const shown = source.resolved?.[item.resolveFrom];\n return typeof shown === 'string' ? shown : '';\n}\n/** 把配置取值铺成「行键 → 控件里的文本」(页面表单态;值缺项即空串,不返空留白)。 */\nexport function toDraft(items, values, source) {\n const draft = {};\n for (const item of items) {\n const v = readPath(values, item.key);\n const raw = v === undefined || v === null ? '' : String(v);\n if (item.readonly === true) {\n draft[item.key] = readonlyTextOf(item, raw, source);\n continue;\n }\n const fallback = item.prefillFrom === undefined ? undefined : prefillValueOf(source, item.prefillFrom);\n draft[item.key] = raw === '' && fallback !== undefined ? fallback : raw;\n }\n return draft;\n}\n/** 表单态 → 配置取值(按控件种类还原类型;空串对文本项照收,语义由「按默认落点」承担)。\n *\n * **只读行不收**:它们显示的是技能算好的绝对路径,写回配置就是把「显示的路径」当成「配置值」——\n * 保存只提交真能改的那些行,其余键由技能侧做组内合并保留现值。 */\nexport function fromDraft(items, draft) {\n const values = {};\n for (const item of items) {\n if (item.readonly === true)\n continue;\n const raw = draft[item.key] ?? '';\n if (item.control === 'number') {\n const n = Number(raw);\n writePath(values, item.key, Number.isFinite(n) ? n : 0);\n }\n else if (item.control === 'switch') {\n writePath(values, item.key, raw === 'true');\n }\n else {\n writePath(values, item.key, raw);\n }\n }\n return values;\n}\n/** 可改行(脏基线只看这一档)。 */\nexport function editableItemsOf(items) {\n return items.filter((item) => item.readonly !== true);\n}\n/** 常用项与高级项按行表自己的分级切开(不再另要一个「常用几行」的数:那是同一件事的第二处定义)。 */\nexport function tiersOf(items) {\n return {\n common: items.filter((item) => item.tier === 'common'),\n advanced: items.filter((item) => item.tier === 'advanced'),\n };\n}\n/** 脏键:表单态里与「刚读到的整面」不一致的**可改行**。\n *\n * 只读行不进来:它们显示的是技能算好的绝对路径,拿它当「改动」会让面板一打开就显示「未保存」。 */\nexport function dirtyKeysOf(items, draft, baseline) {\n return editableItemsOf(items)\n .filter((item) => (draft[item.key] ?? '') !== (baseline[item.key] ?? ''))\n .map((item) => item.key);\n}\n/** 跟随映射的缺省:没有映射就是「一行都不跟随」。 */\nexport function noFollowKeys() {\n return [];\n}\n/* 「写的值 ≠ 生效值」那支黄字已删(#915):面板手上只有「配置里写的」与「技能回执里的默认落点」\n * 两个事实,凭这两个比字符串**判不出**值用不用得了——写的是相对路径、尾分隔符写法不同、大小写不同、\n * 或者(本项目维护者自己的六份配置就是如此)写了一个完全正常、正在用的自定义目录,都会让两个字符串不等。\n * 后果是那行黄字对合法值恒亮,还声称「现在生效的是 <默认落点>」——那是面板替技能侧下的判断,\n * 而技能侧**有意不做隐式回落**(例 `packages/skill-bill/src/fetch/paths.ts:6`:「拒绝隐式写生产」)。\n * 要恢复这一支,事实必须由技能侧给出(布尔 + 故障码 + 报文),面板只画、不比较。 */\n/** 配置面报错 → 人话指引。\n *\n * 报文由技能侧给出(`base-link-core` 的 `ConfigError` 已带行号与文件名,技能 `cli/config.ts`\n * 原样交出,插件 bridge 原样带上),所以这里**不重写报文**,只按报错类补一句「接下来怎么办」。 */\nexport function humanizeConfigFailure(code, message) {\n const text = message.trim().length > 0 ? message.trim() : `(${code},宿主未给报文)`;\n if (/解析|YAML|parse/i.test(text))\n return `${text}\\n改回「键: 值」的写法,或点「重置为默认」。`;\n if (/不认识|未知键|UNKNOWN_KEY/i.test(text))\n return `${text}\\n删掉页面上没有的行,或点「重置为默认」。`;\n if (/类型|TYPE_MISMATCH/i.test(text))\n return `${text}\\n按本页的控件形状填,或点「重置为默认」。`;\n if (/缺席|missing-cli/i.test(text))\n return `${text}\\n技能出口没找到:先确认技能包已装好,再点「重新读取」。`;\n return `${text}\\n改不动就点「重置为默认」,或照上面那条路径手工改配置文件。`;\n}\n/** 有界等待:借平台 `AbortSignal.timeout` 的 abort 事件做**一次**超时拒绝。\n *\n * 为什么不自建定时器:本仓冻结边界是「无数据轮询」,而设置页等的是一次电话回执,不是轮询;\n * 用平台自带的一次性超时既守住边界的本意,也把「不转圈」落到实处。同一个 signal 也交给传输,\n * 双保险:它搭理 signal 就早收工,不理也有这一道兜底(桌面端自研传输会忽略 signal,见 #760)。 */\nfunction withDeadline(promise, ms) {\n const signal = AbortSignal.timeout(ms);\n const limit = new Promise((_, reject) => {\n signal.addEventListener('abort', () => {\n const e = new Error(`配置请求超时(${Math.round(ms / 1000)}s):宿主未回`);\n e.name = 'TimeoutError';\n reject(e);\n }, { once: true });\n });\n return Promise.race([promise, limit]);\n}\n/** 一次配置电话(走调用方给的那条通道,靠端点名分发;永不抛,失败落字)。 */\nasync function configRpc(call, channel, method, payload) {\n if (typeof call !== 'function')\n return { ok: false, message: '宿主连接缺席:connection.rpc.call 不可用' };\n try {\n const raw = await withDeadline(call('/api', channel.replace(/^\\//, ''), { method, payload }, AbortSignal.timeout(READ_TIMEOUT_MS)), READ_TIMEOUT_MS);\n if (!isRpcResult(raw))\n return { ok: false, message: '回执信封异常(非 ok 信封)' };\n if (!raw.ok) {\n return { ok: false, message: humanizeConfigFailure(raw.error?.code ?? 'unknown', raw.error?.message ?? '') };\n }\n return { ok: true, surface: raw.value };\n }\n catch (e) {\n if (e instanceof Error && (e.name === 'AbortError' || e.name === 'TimeoutError')) {\n return { ok: false, message: `配置请求超时(${Math.round(READ_TIMEOUT_MS / 1000)}s):宿主未回` };\n }\n return { ok: false, message: `配置失败:${e instanceof Error ? e.message : String(e)}` };\n }\n}\n/** 读设置页整面。 */\nexport function fetchConfigSurface(call, channel) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_GET, {});\n}\n/** 保存一份取值(回执只有 `{path, values}`,**不是**整面:写完要重新读一份整面)。 */\nexport function saveConfigSurface(call, channel, values) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_SAVE, { values });\n}\n/** 重置为默认(技能侧先落一份备份;回执同样不是整面,写完要重新读一份整面)。 */\nexport function resetConfigSurface(call, channel) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_RESET, {});\n}\n//# sourceMappingURL=config-panel-value.js.map","/** 目录浏览器的纯逻辑半(**不认识宿主**:只认两格原语)。\n *\n * 为什么在这里:六个单品插件的设置页各有一批「值是一个目录」的行,它们要的界面是同一个东西。\n * 界面的**取数**来自宿主给的两个原语(`list`/`createDirectory`),而这两个原语的形状是**调用方喂进来的**\n * ——本件不 import 宿主的任何实现,也不认识 `remote.directoryPicker` 这个名字(那两件住在各家的\n * `dsh-ctx.ts` 镜像里)。于是本件在 Windows 桌面、远程浏览器、SSH 三种部署下是同一份代码。\n *\n * 装什么:本次要浏览的那一层怎么走(进子目录/回上一级/跳面包屑)、路径怎么切出「目录部分」与\n * 「筛选词」、回执怎么认。**不装**任何 IO、不装任何持久化——`list`/`createDirectory` 由调用方执行。\n *\n * 与平台自带浏览器件的关系:`@deepseek-ai/dsh-client-ui-directory-picker-browse` 的 `DirectoryBrowser`\n * 是包内私有件(只经 `ui-workspace` 的流程空位暴露),插件侧取不到,所以这里是一份独立实现,\n * 只对齐它的**交互结果**(进/选/新建),不对齐它的 DOM。\n */\n/** 认一认某个值是不是可用的目录取数面(软依赖守卫用:认不出就当没有,绝不把页面带下来)。 */\nexport function isBrowseFace(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n const face = raw;\n return typeof face.list === 'function' && typeof face.createDirectory === 'function';\n}\n/** 认一认某个值有没有 `pick`(对应宿主 composition 里的 `native` 能力)。 */\nexport function hasPickFn(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return typeof raw.pick === 'function';\n}\n/** 三态判定:**先看两格浏览原语**(都在=应用内浏览器这条路在),再看单独的 `pick`,都没有=`none`。\n *\n * 为什么浏览优先:客户端命名空间上三条动词一定都在(由 `TYPERT_REMOTE.descriptors` 生成,\n * 与组合里服务哪种能力无关),所以两格原语在=这台宿主**可能**给浏览;真调一次才知道给不给,\n * 不给({@link CAPABILITY_REFUSED})再由调用方换系统对话框。反过来先认 `pick` 就会在\n * Desktop 这种「只服务 browse」的宿主上每次都去唤一次系统对话框、被拒一次(#744 实测)。 */\nexport function pickerModeOf(raw) {\n if (isBrowseFace(raw))\n return 'browse';\n return hasPickFn(raw) ? 'native' : 'none';\n}\n/** 平台回执 → 三态(**永不抛**):成功回的是信封里的 `value` 不是路径;`ok:false` 是「供不了」不是「取消」。\n *\n * 出处:`@deepseek-ai/dsh-api-gateway/lib/client.js` 的 `invoke()`(失败不抛、成功也不回裸值),\n * 第一方消费方 `@deepseek-ai/dsh-client-ui-workspace/lib/client.js:99-103` 就照这个信封拆。\n * 裸串照收(老形状兜底),认不出的形状当「供不了」报出来,不当取消吞掉(#743 的教训)。 */\nexport function readPickAnswer(raw) {\n if (typeof raw === 'string')\n return raw.trim() === '' ? { kind: 'cancelled' } : { kind: 'picked', path: raw };\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok === true) {\n const value = answer.value;\n return typeof value === 'string' && value.trim() !== '' ? { kind: 'picked', path: value } : { kind: 'cancelled' };\n }\n const detail = answer.error?.message?.trim() ?? '';\n const code = answer.error?.code;\n return {\n kind: 'unavailable',\n ...(typeof code === 'string' && code !== '' ? { code } : {}),\n message: '打不开系统文件夹对话框' + (detail === '' ? '' : '(' + detail + ')') + ':请直接在框里填绝对路径。',\n };\n}\n/** 取数原语失败:带上宿主给的回执码,好让调用方分辨「没这条路」与「这一层读不出来」。\n *\n * `code` 就是 `humanize`(状态那半)读的那一格,人话直接上图。 */\nexport class BrowseAnswerError extends Error {\n code;\n constructor(code, message) {\n super(message);\n this.name = 'BrowseAnswerError';\n this.code = code;\n }\n}\n/** 宿主 browse 原语的**信封** → 值,或按信封里的 `error` 抛。\n *\n * 为什么必须走这一道:`list`/`createDirectory` 与 `pick` 一样是 Remote 动词,客户端拿到的是\n * `{ok:true,value}`/`{ok:false,error}`(`@deepseek-ai/dsh-api-gateway/lib/client.js` 的 `invoke()`)。\n * 把信封当值用,图上就会是一层「读出来了但一行都没有」的空目录(#744 实测),\n * 而不是报错——所以宁可在这里抛,也不许把它当列举结果传下去。\n * 第一方消费方同口径:`@deepseek-ai/dsh-client-ui-workspace/lib/client.js:105-113` 也是这么拆的。 */\nexport function readBrowseAnswer(raw, what) {\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok === true && answer.value !== undefined && answer.value !== null)\n return answer.value;\n const detail = answer.error?.message?.trim() ?? '';\n const code = answer.error?.code;\n throw new BrowseAnswerError(typeof code === 'string' && code !== '' ? code : 'browse-failed', detail === '' ? what + '没有回执' : detail);\n}\n/** 宿主命名空间 → 本件的取数面:把两条原语的信封拆开,成功给值、失败按码抛。\n *\n * 命名空间上两格原语不在就回 null(调用方据此不画入口)。**透传参数个数照宿主的规矩**:\n * 描述符声明了可选 `AbortSignal`(`cancellation: {parameter:'signal'}`),而客户端按\n * `values.length === 业务参数个数 + 1` 判有没有 signal——显式传一个 `undefined` 会被当成 signal\n * 去 `AbortSignal.any([…, undefined])` 而炸。本件的界面不做取消,故**从不传 signal**。 */\nexport function browseFaceOf(raw) {\n if (!isBrowseFace(raw))\n return null;\n const namespace = raw;\n return {\n list: async (path) => readBrowseAnswer(path === undefined ? await namespace.list() : await namespace.list(path), '列举目录'),\n createDirectory: async (path, name) => readBrowseAnswer(await namespace.createDirectory(path, name), '新建文件夹'),\n };\n}\n/** 一段路径里最后那个分隔符的位置(Windows 上 `\\` 与 `/` 都算;POSIX 上 `\\` 是合法文件名字符,不算)。 */\nfunction lastSeparator(path) {\n const back = path.lastIndexOf('\\\\');\n const slash = path.lastIndexOf('/');\n // 只含 `\\` 的路径按 Windows 规则解;两者都有时取更靠后的那个。\n return back > slash ? back : slash;\n}\n/** 上一层:`'C:\\\\a\\\\b\\\\'` → `'C:\\\\a'`;已经是根则回自身;相对名(没有任何分隔符)也回自身。\n *\n * 尾分隔符先吃掉再切——否则「回上一级」会在原地打转。**盘根单独认**:`C:\\` 掐掉尾分隔符会剩成\n * `C:`,而 `C:` 是「当前盘」不是「上一层」,回它就会多跑一趟、还可能跨到别的盘上去。\n * UNC(`\\\\server\\share`)不特殊处理:切到头就是共享名本身,浏览停在共享根。 */\nexport function parentOf(path) {\n const trimmed = path.replace(/[\\\\/]+$/, '');\n if (trimmed === '')\n return path;\n const sep = path.includes('\\\\') ? '\\\\' : '/';\n if (/^[A-Za-z]:$/.test(trimmed))\n return trimmed + sep;\n const cut = lastSeparator(trimmed);\n if (cut === -1)\n return trimmed;\n if (cut === 0)\n return path.slice(0, 1);\n if (cut === 2 && /^[A-Za-z]:/.test(trimmed))\n return trimmed.slice(0, 2) + sep;\n return trimmed.slice(0, cut);\n}\n/** 把「当前路径 + 一段输入」拼成一个目标路径。 */\nexport function joinPath(directory, name) {\n const sep = directory.includes('\\\\') ? '\\\\' : '/';\n const base = directory.replace(/[\\\\/]+$/, '');\n if (base === '')\n return sep + name;\n return base + sep + name;\n}\n/** 一层列举里,哪些行可进:隐藏目录按开关过滤,其余照宿主给的顺序。 */\nexport function visibleEntries(listing, showHidden) {\n return showHidden ? listing.entries : listing.entries.filter((entry) => !entry.hidden);\n}\n/** 这一层有多少个被藏起来的目录(用来决定「显示隐藏目录」那个开关要不要出现在图上)。 */\nexport function hiddenCount(listing) {\n return listing.entries.filter((entry) => entry.hidden).length;\n}\n/** 拿一段文本按「最后一个分隔符」切成「目录部分 + 筛选词」。\n *\n * 没打过任何分隔符时目录部分=null(那段文字还不指任何目录,只当筛选词用)。\n * Windows 上 `/` 也当分隔符(宿主那边两种都收),POSIX 上不。 */\nexport function splitDraft(draft) {\n const cut = lastSeparator(draft);\n if (cut === -1)\n return { directory: null, filter: draft };\n return { directory: draft.slice(0, cut + 1), filter: draft.slice(cut + 1) };\n}\n/** 按筛选词过一层目录(大小写不敏感;空筛选词=全留)。 */\nexport function filterEntries(entries, filter) {\n const needle = filter.trim().toLowerCase();\n if (needle === '')\n return entries;\n return entries.filter((entry) => entry.name.toLowerCase().includes(needle));\n}\n/** 新建文件夹的名字合不合法(单个路径段:不许分隔符、不许空、不许 `.`/`..`)。\n *\n * 与宿主 browse 后端的校验同口径——这里先拦一道,是为了在图上给得出人话,不是替代宿主校验。 */\nexport function validateFolderName(name) {\n const trimmed = name.trim();\n if (trimmed === '')\n return { ok: false, reason: '文件夹名不能为空。' };\n if (/[\\\\/]/.test(trimmed))\n return { ok: false, reason: '文件夹名里不能带路径分隔符。' };\n if (trimmed === '.' || trimmed === '..')\n return { ok: false, reason: '「.」与「..」不是文件夹名。' };\n return { ok: true };\n}\n//# sourceMappingURL=directory-browser-contract.js.map","/** 文件浏览器的操作半:把「进哪一层、这一层显示什么、选到了什么」算成状态,**IO 全部由调用方注入**。\n *\n * 分两层的原因:本件(操作)在 Node 里就能直测——喂一个假的取数面,就能把「进目录/回上一级/\n * 跳面包屑/筛选/新建文件夹/失败出人话」全跑一遍;视图那半(`directory-browser-ui.ts`)\n * 只负责把这份状态画成 DOM。两边都不认识宿主。\n *\n * 数据来源只有两格:`list(path?)` 与 `createDirectory(path, name)`(调用方注入的 `DirectoryBrowseFace`)。\n */\nimport { browseFaceOf, filterEntries, joinPath, parentOf, splitDraft, validateFolderName, visibleEntries, } from './directory-browser-contract.js';\n/** 建一个浏览器控制器。取数、回调、初值全部由调用方给。 */\nexport function createBrowseController(deps) {\n const label = deps.failureLabel ?? '浏览失败';\n const listeners = new Set();\n let state = {\n phase: 'idle',\n listing: null,\n failure: null,\n selected: null,\n showHidden: false,\n draft: deps.initialPath,\n filter: '',\n creating: null,\n notice: null,\n roots: [],\n };\n /** 每次列举带一个序号:晚回来的旧回执直接丢掉,不许覆盖新一层。 */\n let generation = 0;\n const emit = (next) => {\n state = { ...state, ...next };\n for (const listener of [...listeners])\n listener(state);\n };\n /** 根清单只问一次:取不到就是空(不报错、不重试——它只是图上的一行入口)。\n *\n * 「问一次」钉在这里而不是图里:视图那半每次重画都会重新求值,问在这里才谈得上一次。 */\n let rootsAsked = false;\n const loadRoots = async () => {\n if (rootsAsked || deps.rootsSource === undefined)\n return;\n rootsAsked = true;\n try {\n const roots = await deps.rootsSource();\n if (roots.length > 0)\n emit({ roots });\n }\n catch {\n /* 取不到就当没有这一行:浏览本身照常。 */\n }\n };\n const humanize = (cause) => {\n const raw = (typeof cause === 'object' && cause !== null ? cause : {});\n const message = typeof raw.message === 'string' && raw.message.trim() !== '' ? raw.message.trim() : String(cause);\n const code = typeof raw.code === 'string' && raw.code !== '' ? raw.code : 'browse-failed';\n return { code, message: `${label}:${message}` };\n };\n const load = async (path) => {\n const mine = ++generation;\n emit({ phase: 'loading', failure: null, notice: null });\n try {\n const listing = path === null ? await deps.face.list() : await deps.face.list(path);\n if (mine !== generation)\n return;\n emit({\n phase: 'ready',\n listing,\n failure: null,\n selected: null,\n draft: listing.path,\n filter: '',\n });\n }\n catch (cause) {\n if (mine !== generation)\n return;\n emit({ phase: 'failed', listing: null, failure: humanize(cause), selected: null });\n }\n };\n /** 草稿指到的那一层已经列举过时,按末段筛当前这一层的行;否则不过滤。\n *\n * 两边都先掐掉尾分隔符再比:草稿那边切开后天然带尾分隔符(`C:\\a\\` + `b`),\n * 而这一层的 `path` 由宿主给、不带尾分隔符。 */\n const applyDraft = (draft) => {\n const { directory, filter } = splitDraft(draft);\n const listing = state.listing;\n const sameLevel = listing !== null && directory !== null && normalize(directory) === normalize(listing.path);\n emit({ draft, filter: sameLevel ? filter : '' });\n };\n const normalize = (path) => path.replace(/[\\\\/]+$/, '');\n return {\n getState: () => state,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n async open() {\n // 根清单一并去问,但**不等它**:它只是图上的一行入口,落定了自会推一次重画;\n // 等它就等于让「宿主那台机器列盘符快不快」决定对话框什么时候开。\n void loadRoots();\n const wanted = deps.initialPath.trim();\n if (wanted !== '') {\n await load(wanted);\n if (state.phase === 'ready')\n return state;\n }\n await load(null);\n return state;\n },\n enter: (path) => load(path),\n async up() {\n const listing = state.listing;\n if (listing === null)\n return;\n const parent = parentOf(listing.path);\n if (parent === listing.path)\n return;\n await load(parent);\n },\n pick() {\n const target = state.selected ?? state.listing?.path ?? null;\n if (target === null)\n return;\n deps.onPicked(target);\n },\n cancel() {\n deps.onClose();\n },\n close() {\n deps.onClose();\n },\n select(path) {\n emit({ selected: state.selected === path ? null : path, notice: null });\n },\n toggleHidden() {\n emit({ showHidden: !state.showHidden });\n },\n setDraft(draft) {\n applyDraft(draft);\n },\n async commitDraft() {\n const trimmed = state.draft.trim();\n if (trimmed === '')\n return;\n await load(trimmed);\n },\n setCreating(name) {\n emit({ creating: name, notice: null });\n },\n async createFolder(name) {\n const checked = validateFolderName(name);\n if (!checked.ok) {\n emit({ notice: checked.reason });\n return;\n }\n const base = state.selected ?? state.listing?.path ?? null;\n if (base === null) {\n emit({ notice: '还没有打开任何目录,无法新建文件夹。' });\n return;\n }\n try {\n const created = await deps.face.createDirectory(base, name.trim());\n emit({ creating: null, notice: null });\n await load(created);\n emit({ selected: created });\n }\n catch (cause) {\n const failure = humanize(cause);\n emit({ notice: failure.message, creating: null });\n }\n },\n };\n}\n/** 图上这一层要画的行(按隐藏开关与草稿末段过滤之后的)。 */\nexport function rowsOf(state) {\n if (state.listing === null)\n return [];\n return filterEntries(visibleEntries(state.listing, state.showHidden), state.filter);\n}\n/** 图上这一层能不能回上一级(根目录不能)。 */\nexport function canGoUp(state) {\n if (state.listing === null)\n return false;\n return parentOf(state.listing.path) !== state.listing.path;\n}\n/** 「打开」这颗按钮的目标:选中行优先,没选中就是当前层。 */\nexport function targetOf(state) {\n return state.selected ?? state.listing?.path ?? null;\n}\n/** 新建文件夹那一行要展示的位置(\"在 <这里> 下新建\")。 */\nexport function createBaseOf(state) {\n return state.selected ?? state.listing?.path ?? null;\n}\n/** 一段路径拼成可读的一句话(给用例与调试用;图上不直接显示)。 */\nexport function describe(state) {\n if (state.phase === 'failed')\n return `${state.failure?.code ?? 'browse-failed'} @ ${state.draft}`;\n if (state.listing === null)\n return `${state.phase}`;\n return `${state.listing.path}(${rowsOf(state).length} 行)`;\n}\n/** 一行子目录的完整路径(图上点行时用)。 */\nexport function entryPath(directory, entry) {\n return entry.path === '' ? joinPath(directory, entry.name) : entry.path;\n}\n/** 建一份「目录行接线」:给一个取数面与初值,回一组动作。\n *\n * 只做接线:把控制器算出来的状态与回调打包好,不取数、不画图、不认宿主。 */\nexport function createDirectoryRowBrowser(deps) {\n const controller = createBrowseController({\n face: deps.face,\n initialPath: deps.initialPath,\n onPicked: deps.onPicked,\n onClose: () => deps.onClosed?.(),\n ...(deps.failureLabel === undefined ? {} : { failureLabel: deps.failureLabel }),\n ...(deps.rootsSource === undefined ? {} : { rootsSource: deps.rootsSource }),\n });\n return {\n open: () => controller.open(),\n subscribe: (listener) => controller.subscribe(listener),\n state: () => controller.getState(),\n summary: () => describe(controller.getState()),\n actions: {\n onPick: () => controller.pick(),\n onClose: () => controller.cancel(),\n onEnter: (path) => void controller.enter(path),\n onUp: () => void controller.up(),\n onSelect: (path) => controller.select(path),\n onToggleHidden: () => controller.toggleHidden(),\n onDraft: (draft) => controller.setDraft(draft),\n onCommitDraft: () => void controller.commitDraft(),\n onCreate: (name) => void controller.createFolder(name),\n onCreatingChange: (name) => controller.setCreating(name),\n },\n };\n}\n/** 一条目录行点下去该走哪条路(**六家共用这一处策略**,单独写在各家就会各错各的)。\n *\n * 顺序是「先应用内浏览,被拒再换系统对话框」,因为客户端命名空间上三条动词都在、问不出组合里服务哪种\n * 能力(见 `pickerModeOf`)。回执:\n * - `undefined`=连两格浏览原语都没有(这条路没有,调用方自己想办法);\n * - `'refused'`=宿主回了 `refusalCode`(组合里是系统对话框),图已收起;\n * - `'open'`=图开着,后面的事都在图里。\n *\n * **状态由调用方持有**:`onRow` 收到刚建好的那条(或 null=收起),React 那边据此决定画不画图。\n *\n * `refusalCode` 是**宿主的回执码**(各家自己从宿主镜像里拿,本件只照比不认名):\n * 它换名字本件照样跑,六家一起换。 */\nexport function openRowBrowser(input) {\n const face = browseFaceOf(input.picker);\n if (face === null)\n return undefined;\n const row = createDirectoryRowBrowser({\n face,\n initialPath: input.initialPath,\n onPicked: (picked) => {\n input.onChange(picked);\n input.onRow(null);\n },\n onClosed: () => input.onRow(null),\n ...(input.rootsSource === undefined ? {} : { rootsSource: input.rootsSource }),\n });\n input.onRow(row);\n return row.open().then((settled) => {\n if (settled.phase === 'failed' && settled.failure?.code === input.refusalCode) {\n input.onRow(null);\n return 'refused';\n }\n return 'open';\n });\n}\n//# sourceMappingURL=directory-browser-state.js.map","/** 文件浏览器视图半的**零件**:样式表与四行控件(面包屑/根/一行子目录/新建行)。\n *\n * 为什么拆出来:整张对话框的组版与这些零件的变化频率不同——零件跟着「图上多一行/少一行」动,\n * 组版跟着「对话框长什么样」动。拆开之后两边都在 350 行告警线内,而对外面不变\n * (`directory-browser-ui.ts` 照旧转出组件与两个接线函数)。\n *\n * 本件与视图半同样**不认识宿主**:只认状态与文案。\n */\nimport * as React from 'react';\n/** 根的类型说明(悬停可见):**本件自己的词汇**,与取数方无关。 */\nconst ROOT_KIND_TEXT = {\n fixed: '固定磁盘',\n network: '网络驱动器',\n removable: '可移动磁盘',\n optical: '光驱',\n other: '磁盘',\n};\nexport const S = {\n scrim: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.35)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n },\n dialog: {\n width: 680,\n maxWidth: '92vw',\n height: 500,\n maxHeight: '86vh',\n display: 'flex',\n flexDirection: 'column',\n background: 'var(--dsw-alias-bg-layer-1, #1f1f23)',\n color: 'var(--dsw-alias-label-primary, inherit)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 10,\n boxShadow: '0 12px 32px rgba(0,0,0,0.35)',\n overflow: 'hidden',\n },\n head: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 12px',\n borderBottom: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n },\n title: { fontSize: 14, fontWeight: 700 },\n crumbs: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 2, padding: '8px 12px 0', fontSize: 12 },\n chromeButton: {\n background: 'transparent',\n border: 'none',\n color: 'var(--dsw-alias-label-primary, inherit)',\n cursor: 'pointer',\n padding: '2px 4px',\n fontSize: 12,\n opacity: 0.85,\n },\n crumbSep: { opacity: 0.45, fontSize: 12 },\n roots: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 6, padding: '0 12px 8px', fontSize: 12 },\n rootButton: {\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n padding: '3px 8px',\n opacity: 1,\n },\n pathRow: { display: 'flex', gap: 6, padding: '8px 12px' },\n input: {\n flex: 1,\n minWidth: 0,\n fontSize: 12,\n padding: '5px 8px',\n background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.12))',\n color: 'inherit',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n },\n button: {\n fontSize: 12,\n padding: '5px 10px',\n cursor: 'pointer',\n background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.12))',\n color: 'inherit',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n },\n buttonOff: { opacity: 0.45, cursor: 'default' },\n list: {\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n margin: '0 12px',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n borderRadius: 6,\n },\n row: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n width: '100%',\n padding: '6px 10px',\n textAlign: 'left',\n background: 'transparent',\n color: 'inherit',\n border: 'none',\n borderBottom: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.12))',\n cursor: 'pointer',\n fontSize: 13,\n },\n rowSelected: { background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.18))' },\n empty: { padding: '14px 12px', fontSize: 12, opacity: 0.7 },\n footNote: { padding: '6px 12px 0', fontSize: 12, minHeight: 20 },\n foot: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 12px',\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n },\n target: { marginRight: 'auto', fontSize: 12, opacity: 0.8, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n error: { color: 'var(--dsw-alias-label-error, #e66)' },\n};\n/** 面包屑:从文件系统根到当前层,每一格都是跳转目标(`listing.crumbs` 由取数方给)。 */\nexport function crumbRow(state, onEnter) {\n const listing = state.listing;\n if (listing === null || listing.crumbs.length === 0)\n return null;\n const parts = [];\n listing.crumbs.forEach((crumb, index) => {\n if (index > 0)\n parts.push(React.createElement('span', { key: 'sep-' + crumb.path, style: S.crumbSep }, '›'));\n const isCurrent = crumb.path === listing.path;\n parts.push(React.createElement('button', {\n key: crumb.path,\n type: 'button',\n style: { ...S.chromeButton, fontWeight: isCurrent ? 700 : 400 },\n title: crumb.path,\n onClick: () => onEnter(crumb.path),\n }, \n // 每一格都写**它自己那一层的名字**:第一格是文件系统根(`C:\\`),不是「上一级」——\n // 「上一级」是路径行那颗按钮的活(#744 返修:这一格原先串了那颗按钮的文案)。\n crumb.name));\n });\n return React.createElement('div', { style: S.crumbs }, parts);\n}\n/** 可跳转的根那一行(Windows 上的盘符等):**就是本机全部磁盘**,故不加行首说明。\n * **少于两个根就不画**:一个根没有「跳到别处」可言。 */\nexport function rootsRow(state, onEnter) {\n if (state.roots.length < 2)\n return null;\n const parts = state.roots.map((root) => React.createElement('button', {\n key: root.path,\n type: 'button',\n style: { ...S.chromeButton, ...S.rootButton },\n title: ROOT_KIND_TEXT[root.kind] ?? ROOT_KIND_TEXT.other,\n onClick: () => onEnter(root.path),\n }, root.path));\n return React.createElement('div', { style: S.roots }, parts);\n}\n/** 一行子目录:点名字进它,点「选」把它当目标(「选」再点一次取消)。 */\nexport function entryRow(entry, selected, labels, onToggleSelect, onEnter) {\n return React.createElement('div', { key: entry.path, style: { ...S.row, padding: 0, ...(selected ? S.rowSelected : {}) } }, React.createElement('button', { type: 'button', style: { ...S.row, flex: 1, border: 'none' }, onClick: () => onEnter(entry.path) }, '📁 ' + entry.name), React.createElement('button', {\n type: 'button',\n style: { ...S.button, marginRight: 8, padding: '2px 8px' },\n 'aria-pressed': selected,\n title: selected ? labels.selected : labels.select,\n onClick: () => onToggleSelect(entry.path),\n }, selected ? '✓' : labels.select));\n}\n/** 「新建文件夹」那一行(`creatingName === null` 时收起)。 */\nexport function createRow(labels, onName, onCancel, onCreate, creatingName) {\n if (creatingName === null)\n return null;\n return React.createElement('div', { style: { ...S.pathRow, borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))' } }, React.createElement('input', {\n style: S.input,\n value: creatingName,\n placeholder: labels.newFolder,\n 'aria-label': labels.newFolder,\n onChange: (event) => onName(event.currentTarget.value),\n onKeyDown: (event) => {\n if (event.key === 'Enter')\n onCreate(creatingName);\n if (event.key === 'Escape')\n onCancel();\n },\n }), React.createElement('button', { type: 'button', style: S.button, onClick: () => onCreate(creatingName) }, labels.createConfirm), React.createElement('button', { type: 'button', style: S.button, onClick: onCancel }, labels.createCancel));\n}\n//# sourceMappingURL=directory-browser-parts.js.map","/** 文件浏览器的视图半:把 `BrowseState` 画成一张对话框。**不认识宿主**,也不自己做 IO。\n *\n * 手写 `React.createElement`(本包 client 束禁 JSX,见 `tsdown.config.ts` 的既成口径)。\n * 只读状态、只回调;进哪一层、选到什么由操作半(`directory-browser-state.ts`)算。\n * 样式与四行控件在 `directory-browser-parts.ts`(那里跟着「多一行/少一行」动,本件只管组版)。\n */\nimport * as React from 'react';\nimport { rowsOf, targetOf } from './directory-browser-state.js';\nimport { hiddenCount } from './directory-browser-contract.js';\nimport { S, createRow, crumbRow, entryRow, rootsRow } from './directory-browser-parts.js';\nconst EMPTY_LISTING = { path: '', home: '', crumbs: [], entries: [], truncated: false };\n/** 画一张文件浏览器对话框。`open=false` 时返回 null(本件不挂 portal,由调用方决定挂在哪)。 */\nexport function DirectoryBrowser(props) {\n const { open, state, labels } = props;\n if (!open)\n return null;\n const rows = rowsOf(state);\n const target = targetOf(state);\n const listing = state.listing ?? EMPTY_LISTING;\n const hidden = hiddenCount(listing);\n const body = [];\n body.push(crumbRow(state, props.onEnter));\n body.push(rootsRow(state, props.onEnter));\n body.push(React.createElement('div', { style: S.pathRow }, React.createElement('input', {\n style: S.input,\n value: state.draft,\n placeholder: labels.pathPlaceholder,\n 'aria-label': labels.pathPlaceholder,\n onChange: (event) => props.onDraft(event.currentTarget.value),\n onKeyDown: (event) => {\n if (event.key === 'Enter')\n props.onCommitDraft();\n },\n }), React.createElement('button', { type: 'button', style: S.button, onClick: props.onUp }, labels.up), React.createElement('button', { type: 'button', style: S.button, onClick: props.onCommitDraft }, labels.go)));\n body.push(React.createElement('div', { style: S.list, role: 'listbox', 'aria-label': labels.title }, rows.length === 0\n ? React.createElement('div', { style: S.empty }, state.phase === 'loading' ? labels.loading : labels.empty)\n : rows.map((entry) => entryRow(entry, state.selected === entry.path, labels, props.onSelect, props.onEnter))));\n body.push(createRow(labels, props.onDraft, () => props.onCreatingChange(null), props.onCreate, state.creating));\n body.push(React.createElement('div', { style: S.footNote }, hidden > 0\n ? React.createElement('label', { style: { fontSize: 12, cursor: 'pointer', marginRight: 10 } }, React.createElement('input', { type: 'checkbox', checked: state.showHidden, onChange: props.onToggleHidden }), ' ' + labels.showHidden(hidden))\n : null, state.creating === null\n ? React.createElement('button', { type: 'button', style: { ...S.chromeButton, textDecoration: 'underline' }, onClick: () => props.onCreatingChange('') }, labels.newFolder)\n : null, state.notice !== null ? React.createElement('div', { style: S.error }, state.notice) : null, state.phase === 'failed' && state.failure !== null\n ? React.createElement('div', { style: S.error }, state.failure.message)\n : null));\n body.push(React.createElement('div', { style: S.foot }, React.createElement('span', { style: S.target, title: target ?? '' }, target === null ? '' : labels.willPick + target), React.createElement('button', { type: 'button', style: { ...S.button, ...(target === null ? S.buttonOff : {}) }, onClick: props.onPick }, labels.open), React.createElement('button', { type: 'button', style: S.button, onClick: props.onClose }, labels.cancel)));\n return React.createElement('div', {\n style: S.scrim,\n role: 'presentation',\n onMouseDown: (event) => {\n if (event.target === event.currentTarget)\n props.onClose();\n },\n }, React.createElement('div', { style: S.dialog, role: 'dialog', 'aria-modal': true, 'aria-label': labels.title }, React.createElement('div', { style: S.head }, React.createElement('span', { style: S.title }, labels.title), \n // 标题右侧**不再重复当前路径**:同一条路径下面已经出现两次(面包屑与路径框),\n // 而盘符那行也要地方——头一行越干净越好(#744 第三轮现场反馈)。\n React.createElement('button', { type: 'button', style: { ...S.button, marginLeft: 'auto' }, 'aria-label': labels.close, title: labels.close, onClick: props.onClose }, '✕')), body));\n}\n/** 目录行接线的 React 半边:把操作半那组动作直接喂给组件。\n *\n * 操作半(`directory-browser-state.ts` 的 `createDirectoryRowBrowser`)不碰 React,\n * 这里只把它的 `actions` 摊进 props —— 于是「进哪一层」那套在 Node 里可测,这里只做接线。\n *\n * `useSyncExternalStore` 是**必需**的:列举是异步落定的,不订阅的话这一帧画完就再没有重画,\n * 图上会永远停在「正在读取…」(#744 实测)。 */\nexport function DirectoryBrowserFromRow(props) {\n const state = React.useSyncExternalStore(props.row.subscribe, props.row.state);\n return DirectoryBrowser({\n open: props.open,\n state,\n labels: props.labels,\n ...props.row.actions,\n });\n}\nexport { createBrowseController, createDirectoryRowBrowser, describe, rowsOf, targetOf } from './directory-browser-state.js';\n//# sourceMappingURL=directory-browser-ui.js.map","/** 共用配置面板 · 视图半:一行怎么画(`Row`)、整面怎么画(`PanelBody`)。\n *\n * 本件是**纯函数**:吃一份状态与一组回调,回一棵 React 元素树,自己不留任何状态、不取任何数。\n * 为什么这么分:状态机与副作用住在 `config-panel.ts` 那一层,于是本件在 Node 里就能直测\n * (照 `directory-browser-ui.ts` 的既有作法:用例把组件当普通函数调,直接读回那棵树)。\n *\n * 手写 `React.createElement`(本包 client 束禁 JSX)。样式表 `S` 就在本件里——面板怎么画只有这一处。\n *\n * **外观真源=`docs/agents/配置区域视觉模型-v3.1.html`(#920 阶段二起)**:本件的 `S` 逐项照它的\n * CSS(`:32-205`)、行模板照它的 `rowShell`/`masterShell`/`cardShell`(`:349-451`)、状态徽标照它的\n * `badgeHTML`(`:544-552`)那七档。**颜色/间距/圆角/字号/层级一律照取值,不许自己重新设计**;\n * 与本件不同的只有下面这四条(每条都在这里写明为什么,改之前先读 #920 的证据件):\n * ① **字号一律 em,没有 px**:跨包锁 `test/panel-type-739.test.mjs` 钉死「零 `font:` 简写/零字族/\n * 字号一律相对单位」——宿主没有界面字号 token,绝对 px 会在别的窗口尺寸上失真。v3.1 的 px 按它\n * 自己已锁死的那两对锚点换算(`13.5px↔1.08em`、`11.5px↔0.92em` ⇒ **1px=0.08em**),一个不丢。\n * ② **值列不写等宽字族**:v3.1 的值列要 `font-family: var(--ic-mono)`,而 `#739 ①` 明令共用件零\n * `fontFamily`/零 `font:` 简写 ⇒ 值继承宿主字族。这是与 v3.1 的**一处已知不同**(#920 证据件有账)。\n * ③ **换行判据交给 CSS,不按字符数估宽**:v3.1 靠 JS 量文本宽在两套模板间两选一(审查 P0-4/P0-5:\n * 每列 6.048px、真阈值 40–43 列而注释按 34 估 ⇒ 9 行被无谓拆两行、快面一次性长高 194px)。\n * 本件没有 DOM 可量,故照审查给的修法把同一个决定交给排版引擎:行是 `flex-wrap` 容器,标签列定宽、\n * 值列 `flex-basis:auto`(=内容的自然宽)——装不下时**整行让位**(值落第二行、按钮仍在第一行行尾,\n * 与 v3.1 的 `.is-wide` 同形);值再长就在自己那一行里 `overflow-wrap:anywhere` 折下去。\n * **零省略号、零截断**(`white-space` 不用 `nowrap`、`text-overflow` 一次都不出现)。\n * ④ **画不出来的三样**用等价形态顶上:分组箭头 `::before`/`[open]` 旋转/keyframes 动画内联样式\n * 给不出 ⇒ 画静态「›」与静态环(形状与 v3.1 同,只少了动)。\n *\n * 三条定稿(v3)在本件落地:\n * ① **只读行的目录按钮不画**(不画一枚点了也没反应的死按钮);\n * ② 目录行的按钮字面**两档合一**,一律「浏览文件夹」(入口供不了时整枚不画);\n * ③ **每行一枚「复制」**:复制这一行完好的值文本;点下去按钮就地变「已复制」再变回,不弹提示。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport * as React from 'react';\nimport { ADVANCED_GROUP_NOTE, ADVANCED_GROUP_TITLE } from './config-panel-contract.js';\nimport { DirectoryBrowserFromRow } from './directory-browser-ui.js';\n/** 面板的样式表:取值逐项照 v3.1(颜色走 DSH 主题别名,写死值只做回退;字号一律相对单位 em)。\n *\n * 键名一个都不许改:六家附加块真消费 `okText`/`error`/`rows`/`label`/`muted`/`hint`/`info`/\n * `bar`/`btn` 这九格(`plugin-memo-ilife/src/client.ts`、`plugin-schedule-ilife/src/client.ts` 的\n * `PanelStyleSlots`),跨包锁另钉 `card`/`input`/`btnPrimary`/`btnPick`/`summary`/`title`/`version`。 */\nconst S = {\n /** `.ic-card`:`background:var(--ic-surface)`(=bg-layer-1)+`border:1px solid var(--ic-line-strong)`\n * +`border-radius:12px`+`padding:14px`+`box-shadow:inset 0 1px 0 rgba(255,255,255,.06)`。\n * 基准字号**不钉在卡片上**(#739 ⑤:跟着宿主走)。 */\n card: {\n padding: 14,\n borderRadius: 12,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n background: 'var(--dsw-alias-bg-layer-1, #232324)',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.06)',\n },\n /** `.ic-head{display:flex;align-items:center;gap:10px;min-height:22px}`(徽标靠 `margin-left:auto` 右贴)。 */\n head: { display: 'flex', alignItems: 'center', gap: 10, minHeight: 22 },\n /** `.ic-title{font-size:13.5px;font-weight:640}`——字号按 60 行那条锚点换算成 `1.08em`。 */\n title: { fontSize: '1.08em', fontWeight: 640 },\n /** `.ic-file{margin-top:4px}` 的那 4px 挂在两行的公共容器上:`info` 自己一格 margin 都不写\n * (#743 ①:头部两行间距不一家一个数,故这一项一律不写 margin)。 */\n fileWrap: { marginTop: 4 },\n /** `.ic-file b{color:var(--ic-faint);font-weight:400;margin-right:5px}`(「配置文件」「数据目录」那两个字)。 */\n fileLabel: {\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontWeight: 400,\n marginRight: 5,\n },\n /** `.ic-file{color:var(--ic-muted);font-size:11.5px;word-break:break-all}`(11.5px ⇒ `0.92em`)。 */\n info: {\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n fontSize: '0.92em',\n wordBreak: 'break-all',\n },\n /** `.ic-muted` 那一档(次要字)。 */\n muted: { color: 'var(--dsw-alias-label-secondary, #cfd3d6)', fontSize: '0.92em' },\n /** 错误字:取 v3.1 的 `--ic-danger`;字号 `1em`(#739 钉死)。 */\n error: {\n marginTop: 8,\n color: 'var(--dsw-alias-state-error-primary, #e0685f)',\n fontSize: '1em',\n whiteSpace: 'pre-wrap',\n },\n /** 成功字:取 v3.1 的 `--ic-ok`;字号 `0.96em`(#739 钉死)。 */\n okText: {\n marginTop: 8,\n color: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n fontSize: '0.96em',\n },\n /** 行组的容器(六家附加块也拿它当外框;v3.1 没有对应类,故只给一个中性块)。 */\n rows: { display: 'block' },\n /** `.ic-row`:三列栅格 + `gap:4px 10px` + `padding:7px 0` + 一条 `.ic-line` 下边线。\n * 本件把它落成**换行弹性盒**(见文件头 ③):标签定宽在第一行,值装不下时整行让位,\n * 动作槽绝对定位贴在行尾(`.ic-row .ic-slot[data-slot^=\"a:\"]` 那一格)。 */\n row: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0',\n borderBottom: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n },\n /** `.ic-row:last-child{border-bottom:0}`——内联样式没有 `:last-child`,由画它的人明说。 */\n rowLast: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0',\n },\n /** `.ic-under{margin:9px 0 0 8px;border-left:1px solid var(--ic-line-strong);padding-left:13px}`:\n * **跟随行**相对它的可改行(母版行)缩进 8+1+13=**22px**,左边挂一条线。\n *\n * 取值逐字照抄;只有一处形态差别要说清:`.ic-under` 在 v3.1 里是**一整块**(同一个可改行的一批\n * 跟随者共用一个 div、共一条左边线、块首还有 9px 上边距),而共用件手上只有「谁是跟随行」这一个\n * 集合(由六家交的 `followKeysOf` 钩子逐键探出),**没有**「这一行归哪一块」的分块归属\n * (同一个键可以同时挂在两张跟随表上,钩子只回一个去重后的并集)。故这里按**行**落这条缩进:\n * 缩进量与左边线同值,块首那 9px 上边距不落(落下去会在每两行之间多出一道 9px 的缝)。 */\n followerRow: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0 7px 13px',\n marginLeft: 8,\n borderLeft: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderBottom: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n },\n /** 跟随行的最后一行:同上,去掉下边线(照 `.ic-row:last-child{border-bottom:0}`)。 */\n followerRowLast: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0 7px 13px',\n marginLeft: 8,\n borderLeft: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n },\n /** `.ic-row .ic-k{font-size:11.5px;color:var(--ic-muted)}`;`--ic-kw:118px` 是标签列的定宽。 */\n rowKey: {\n flex: '0 0 auto',\n minWidth: 118,\n fontSize: '0.92em',\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n },\n /** `.ic-row .ic-v{font-size:11px;min-width:0}`(11px ⇒ `0.88em`)+ 文件头 ③ 的让位口径:\n * `flex:1 1 auto` ⇒ 装不下整行让位;`overflow-wrap:anywhere` ⇒ 折下去、零省略号;\n * `paddingRight` 给行尾那枚按钮(+列间距)让出宽度——就是 `.ic-row` 第三列那一格。 */\n rowValue: {\n flex: '1 1 auto',\n minWidth: 0,\n paddingRight: 56,\n fontSize: '0.88em',\n whiteSpace: 'normal',\n overflowWrap: 'anywhere',\n lineHeight: 1.5,\n },\n /** 行尾动作槽(复制/跟随标记):绝对定位贴行尾,行一换行它仍留在第一行行尾(=`.is-wide` 那一形)。 */\n rowActs: {\n position: 'absolute',\n right: 0,\n top: 7,\n display: 'flex',\n gap: 4,\n alignItems: 'center',\n },\n /** `.ic-follow{font-size:11px;color:var(--ic-attn);white-space:nowrap}`(11px ⇒ `0.88em`)。 */\n follow: {\n fontSize: '0.88em',\n color: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n },\n /** `.ic-follow::before{content:'↳';opacity:.8}`——内联样式给不出伪元素,画成真的那一个字符。 */\n followMark: { opacity: 0.8 },\n /** `.ic-master`:母版行那一块盒子(`--ic-sunken` 底 + `border-radius:8px` + `padding:11px 12px`\n * + `margin-top:11px` + 内高光)。 */\n master: {\n background: 'var(--dsw-alias-bg-layer-3, #353638)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 8,\n padding: '11px 12px',\n marginTop: 11,\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.05)',\n },\n /** `.ic-master .ic-lab{font-weight:600;display:flex;align-items:center;gap:7px}`;\n * 字号**不写**(#739 ④:`label` 这一项该继承宿主字号)。 */\n label: { display: 'flex', alignItems: 'center', gap: 7, fontWeight: 600 },\n /** `.ic-chip{font-size:10.5px;border:1px solid var(--ic-accent);border-radius:999px;padding:0 6px}`(10.5px ⇒ `0.84em`)。 */\n chip: {\n fontSize: '0.84em',\n border: '1px solid var(--dsw-alias-brand-primary, #f9fafb)',\n borderRadius: 999,\n padding: '0 6px',\n color: 'var(--dsw-alias-brand-primary, #f9fafb)',\n whiteSpace: 'nowrap',\n },\n /** `.ic-master .ic-hint{color:var(--ic-muted);font-size:11.5px;margin-top:3px;line-height:1.5}`。 */\n hint: {\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n fontSize: '0.92em',\n marginTop: 3,\n lineHeight: 1.5,\n },\n /** `.ic-master input`:整行宽、`margin-top:7px`、`padding:5px 8px`、`--ic-bg` 底、`--ic-line-strong` 描边、\n * `border-radius:6px`。字号与字族**不写**(#739 ④/①:`input` 继承宿主)。 */\n input: {\n display: 'block',\n width: '100%',\n marginTop: 7,\n padding: '5px 8px',\n boxSizing: 'border-box',\n background: 'var(--dsw-alias-bg-base, #151517)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 6,\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n },\n /** `.ic-master input.is-dirty`:`border:2px solid var(--ic-attn)` + `padding:4px 7px`\n * + `box-shadow:0 0 0 3px <琥珀 22%>`;2px 描边与 5→4 的内边距对消,宽高不变\n * (审查「站得住」第 7 条)。 */\n inputDirty: {\n display: 'block',\n width: '100%',\n marginTop: 7,\n padding: '4px 7px',\n boxSizing: 'border-box',\n background: 'var(--dsw-alias-bg-base, #151517)',\n border: '2px solid var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderRadius: 6,\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n boxShadow: '0 0 0 3px color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e0a33e) 22%, transparent)',\n },\n /** 布尔档那枚方框(v3.1 的母版行只有文本框,这一格按输入框的同一套外边距对齐)。 */\n checkbox: { marginTop: 7 },\n /** `.ic-acts{display:flex;gap:5px;margin-top:7px;flex-wrap:wrap;align-items:center}`(母版行的按钮行)。 */\n acts: { display: 'flex', gap: 5, marginTop: 7, flexWrap: 'wrap', alignItems: 'center' },\n /** `.ic-btn.is-mini{font-size:11px;padding:2px 7px;color:var(--ic-muted)}`——`btnPick` 是锁钉死的那一格,\n * 字号**不写**(#739 ④:该继承宿主字号),形状照 v3.1。 */\n btnPick: {\n padding: '2px 7px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n background: 'transparent',\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** `.ic-invalid{margin-top:7px;padding:7px 9px;border-radius:6px;font-size:11.5px;line-height:1.5;\n * background:color-mix(in srgb, var(--ic-attn) 16%, transparent);border:1px solid var(--ic-attn)}`。 */\n invalid: {\n marginTop: 7,\n padding: '7px 9px',\n borderRadius: 6,\n fontSize: '0.92em',\n lineHeight: 1.5,\n background: 'color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e0a33e) 16%, transparent)',\n border: '1px solid var(--dsw-alias-state-warn-primary, #e0a33e)',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n },\n /** `.ic-group{margin-top:14px}`(高级组默认收起)。 */\n advanced: { marginTop: 14 },\n /** `.ic-group > .ic-ghead{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;\n * font-weight:600;padding:2px 0}`——字号**不写**(#739 ④:`summary` 该继承宿主字号)。 */\n summary: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n cursor: 'pointer',\n listStyle: 'none',\n fontWeight: 600,\n padding: '2px 0',\n },\n /** `.ic-ghead::before{content:'›';color:var(--ic-muted)}`——画成真的那一个字符(内联样式给不出伪元素)。 */\n groupMark: { color: 'var(--dsw-alias-label-secondary, #cfd3d6)' },\n /** `.ic-ghead .ic-gnote{color:var(--ic-faint);font-weight:400;font-size:11.5px}`(11.5px ⇒ `0.92em`)。 */\n groupNote: {\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontWeight: 400,\n fontSize: '0.92em',\n },\n /** `.ic-group > .ic-gbody{margin-top:9px;padding:11px 12px;background:var(--ic-sunken);\n * border-radius:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}`。 */\n groupBody: {\n marginTop: 9,\n padding: '11px 12px',\n background: 'var(--dsw-alias-bg-layer-3, #353638)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 8,\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.04)',\n },\n /** `.ic-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px;padding-top:12px;\n * border-top:1px solid var(--ic-line)}` + **贴下沿吸住**(v3.1 的 `.ic-attnbar.is-sticky` 是它唯一的\n * 吸底口径:`position:sticky;bottom:6px;z-index:3`;本票按票面「贴下沿」取 0,好让底栏与下沿齐平)。 */\n bar: {\n display: 'flex',\n gap: 8,\n alignItems: 'center',\n flexWrap: 'wrap',\n marginTop: 14,\n paddingTop: 12,\n borderTop: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n position: 'sticky',\n bottom: 0,\n zIndex: 3,\n background: 'var(--dsw-alias-bg-layer-1, #232324)',\n },\n /** `.ic-bar .ic-note{margin-left:auto;color:var(--ic-faint);font-size:11.5px}`(就绪态那半句)。 */\n barNote: {\n marginLeft: 'auto',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontSize: '0.92em',\n },\n /** 有改动时底栏那半句(黄字,粘在按钮组左侧)。 */\n saveMsg: {\n marginLeft: 'auto',\n color: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontSize: '0.92em',\n },\n /** `.ic-btn{font-size:12px;padding:4px 10px;border-radius:6px;border:1px solid var(--ic-line-strong);\n * background:transparent;color:var(--ic-text)}`——字号**不写**(#739 ④)。 */\n btn: {\n padding: '4px 10px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** `.ic-btn.is-primary{background:var(--ic-accent);border-color:var(--ic-accent);color:var(--ic-accent-ink);\n * font-weight:500}`——`--ic-accent` 取 `--dsw-alias-brand-primary`,前景取 `label-primary-foreground`。 */\n btnPrimary: {\n padding: '4px 10px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-brand-primary, #f9fafb)',\n background: 'var(--dsw-alias-brand-primary, #f9fafb)',\n color: 'var(--dsw-alias-label-primary-foreground, #0f1115)',\n fontWeight: 500,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** 附加块(版本行/状态行)那份字面:`--ic-faint` + `0.92em`(#739 ③ 钉死这一格)。 */\n version: {\n marginTop: 8,\n paddingTop: 8,\n borderTop: '1px dashed var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontSize: '0.92em',\n },\n /** `.ic-badge{font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;white-space:nowrap;\n * display:inline-flex;align-items:center;gap:6px;border:1px solid transparent}`(11px ⇒ `0.88em`)。 */\n badge: {\n fontSize: '0.88em',\n lineHeight: 1,\n padding: '4px 9px',\n borderRadius: 999,\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n border: '1px solid transparent',\n },\n /** `.ic-badge .ic-bd{width:6px;height:6px;border-radius:50%;background:currentColor}`。 */\n badgeDot: { width: 6, height: 6, borderRadius: '50%', background: 'currentColor' },\n /** `.ic-spin{width:11px;height:11px;border-radius:50%;border:1.5px solid rgba(0,0,0,.25);\n * border-top-color:currentColor}`——旋转那半要 `@keyframes`(内联样式给不出),故只画环。 */\n badgeSpinner: {\n width: 11,\n height: 11,\n borderRadius: '50%',\n border: '1.5px solid rgba(0,0,0,.25)',\n borderTopColor: 'currentColor',\n display: 'inline-block',\n },\n /** `.ic-badge.is-dirty`:`--ic-attn` 实底 + `--ic-attn-ink` 深字(那 3:1 是设计专门解过的对比度)。 */\n badgeDirty: {\n color: '#241703',\n background: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderColor: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontWeight: 600,\n },\n /** `.ic-badge.is-busy`:与 dirty 同色(写的时候还在那一档上)。 */\n badgeBusy: {\n color: '#241703',\n background: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderColor: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontWeight: 600,\n },\n /** `.ic-badge.is-ok{color:var(--ic-ok);border-color:var(--ic-ok);background:color-mix(in srgb, var(--ic-ok) 14%, transparent)}`。 */\n badgeOk: {\n color: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n borderColor: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n background: 'color-mix(in srgb, var(--dsw-alias-state-success-primary, #4ec9a0) 14%, transparent)',\n },\n /** `.ic-badge.is-bad{color:var(--ic-danger-ink);background:var(--ic-danger);border-color:var(--ic-danger)}`。 */\n badgeBad: {\n color: '#fff5f4',\n background: 'var(--dsw-alias-state-error-primary, #e0685f)',\n borderColor: 'var(--dsw-alias-state-error-primary, #e0685f)',\n fontWeight: 600,\n },\n};\n/** 复制那一枚按钮的字面(定稿 v3 第三条:就地变,不弹提示)。 */\nexport function copyLabelOf(state) {\n if (state === 'done')\n return '已复制';\n if (state === 'failed')\n return '复制失败';\n return '复制';\n}\n/** 状态 → 徽标那一档(v3.1 `paint()` 里的先后次序:读取失败/写入中/写入失败/值非法/有改动/已保存/就绪)。 */\nexport function panelBadgeOf(facts) {\n if (facts.readFailed)\n return 'readFailed';\n if (facts.busy)\n return 'busy';\n if (facts.writeFailed)\n return 'writeFailed';\n if (facts.invalid)\n return 'invalid';\n if (facts.dirtyCount > 0)\n return 'dirty';\n if (facts.saved)\n return 'saved';\n return 'ready';\n}\n/** 徽标那一档画的字(v3.1 `badgeHTML` 的字面,只把「已保存 · 刚刚」的演示时刻换成档名)。 */\nexport function badgeTextOf(kind, dirtyCount) {\n if (kind === 'dirty')\n return `${dirtyCount} 项未保存`;\n if (kind === 'busy')\n return '正在写入';\n if (kind === 'saved')\n return '已保存';\n if (kind === 'invalid')\n return '配置里有值用不了';\n if (kind === 'writeFailed')\n return '写入失败';\n return '';\n}\n/** 徽标那一档的底色(v3.1 的四条 `.ic-badge.is-*`)。 */\nfunction badgeStyleOf(kind) {\n if (kind === 'dirty' || kind === 'invalid')\n return { ...S.badge, ...S.badgeDirty };\n if (kind === 'busy')\n return { ...S.badge, ...S.badgeBusy };\n if (kind === 'saved')\n return { ...S.badge, ...S.badgeOk };\n if (kind === 'writeFailed')\n return { ...S.badge, ...S.badgeBad };\n return S.badge;\n}\n/** 画卡片标题行右端那枚状态徽标(就绪态与读取失败那一支不画)。 */\nexport function PanelBadgeView(props) {\n const text = badgeTextOf(props.kind, props.dirtyCount);\n if (text === '')\n return null;\n return React.createElement('span', { style: badgeStyleOf(props.kind) }, props.kind === 'busy'\n ? React.createElement('span', { style: S.badgeSpinner })\n : React.createElement('span', { style: S.badgeDot }), text);\n}\n/** 一行怎么画(照 v3.1 的两套行模板):\n *\n * **只读行**(`.ic-row`)=标签—值同行、值装不下整行让位、行尾一枚「复制」——**不画输入框**\n * (值来自技能侧解析,页面上本来就不给改),也不画那行说明(v3.1 的 `rowShell` 里没有它)。\n * **可改行**(`.ic-master`)=标签 +「可改」小徽标 + 说明 + 整行输入框 + 按钮行。\n *\n * 目录档=文本框 + 一枚唤起目录选择的按钮;入口三态是 `none`(命名空间拿不到、或这条路已被拒)\n * **就不画按钮**,文本框照旧——那是该缝自己的契约(供不了就收起入口,不是失败)。\n * 只读行:目录入口**一枚都不画**(定稿 v3 ①)。 */\nexport function Row(props) {\n const { item } = props;\n const readonly = item.readonly === true;\n const disabled = props.disabled || readonly;\n const copy = React.createElement('button', {\n style: S.btnPick,\n type: 'button',\n disabled: props.onCopy === undefined,\n onClick: () => props.onCopy?.(item.key, props.value),\n }, copyLabelOf(props.copyState));\n const follow = props.follow === true\n ? React.createElement('span', { style: S.follow }, React.createElement('span', { style: S.followMark }, '↳'), '将跟随更新')\n : null;\n if (readonly) {\n /** 跟随行落 `.ic-under` 那一档缩进;其余按是不是本组最后一行挑有没有下边线。 */\n const rowStyle = props.nested === true ? (props.last === true ? S.followerRowLast : S.followerRow) : props.last === true ? S.rowLast : S.row;\n return React.createElement('div', { style: rowStyle }, React.createElement('span', { style: S.rowKey }, item.title), React.createElement('span', { style: S.rowValue }, props.value), React.createElement('span', { style: S.rowActs }, follow, copy));\n }\n const onChange = (e) => props.onChange(item.key, e.target.value);\n const control = item.control === 'switch'\n ? React.createElement('input', {\n type: 'checkbox',\n style: S.checkbox,\n checked: props.value === 'true',\n disabled,\n onChange: (e) => props.onChange(item.key, e.target.checked ? 'true' : 'false'),\n })\n : React.createElement('input', {\n style: props.dirty === true ? S.inputDirty : S.input,\n type: item.control === 'number' ? 'number' : 'text',\n value: props.value,\n disabled,\n spellCheck: false,\n onChange,\n });\n /** 目录入口:只读行不画(定稿 v3 ①),供不了(`none`/缺席)也不画。 */\n const entry = props.browser ?? null;\n const browse = item.control === 'directory' && entry !== null && entry.mode !== 'none'\n ? React.createElement('button', {\n style: S.btnPick,\n type: 'button',\n disabled,\n // 回这枚 Promise 是有意的:React 不看 onClick 的返回值,而用例能直接 await 它。\n onClick: () => entry.onOpen(item.key),\n }, '浏览文件夹')\n : null;\n return React.createElement('div', { style: S.master }, React.createElement('div', { style: S.label }, item.title, React.createElement('span', { style: S.chip }, '可改')), React.createElement('div', { style: S.hint }, item.hint), control, React.createElement('div', { style: S.acts }, browse, copy), props.alert == null\n ? null\n : React.createElement('div', { style: S.invalid }, props.alert.message));\n}\n/** 应用内浏览器对话框的文案(面板自带,逐条对应图上那几个位置)。 */\nconst BROWSER_LABELS = {\n title: '选择文件夹',\n close: '关闭',\n up: '上一级',\n pathPlaceholder: '直接填绝对路径,回车即进入',\n go: '转到',\n showHidden: (n) => '显示隐藏目录(' + n + ')',\n empty: '这个目录里没有子目录。',\n loading: '正在读取',\n newFolder: '新建文件夹',\n createConfirm: '创建',\n createCancel: '取消',\n select: '选',\n selected: '已选',\n open: '选定这个目录',\n cancel: '取消',\n willPick: '将选定:',\n};\n/** 画整面(四支控件、三支错误落位、底栏、附加块槽都在这里)。 */\nexport function PanelBody(props) {\n const { state, title } = props;\n const surface = state.kind === 'ready' ? state.surface : null;\n const headText = title === undefined ? '配置' : `${title} · 配置`;\n const headDataDir = surface === null ? '' : surface.resolved?.['dbDir'] ?? surface.dataDir;\n const ready = state.kind === 'ready';\n const dirtyCount = ready ? props.dirtyKeys.length : 0;\n const badge = panelBadgeOf({\n readFailed: state.kind === 'failed',\n busy: props.busy,\n writeFailed: props.writeError !== null,\n invalid: props.invalid === true,\n dirtyCount,\n saved: props.notice !== null,\n });\n const head = React.createElement('div', { style: S.head }, React.createElement('div', { style: S.title }, headText), React.createElement(PanelBadgeView, { kind: badge, dirtyCount }));\n const fileLines = surface === null\n ? null\n : React.createElement('div', { style: S.fileWrap }, React.createElement('div', { style: S.info }, React.createElement('b', { style: S.fileLabel }, '配置文件'), surface.path), React.createElement('div', { style: S.info }, React.createElement('b', { style: S.fileLabel }, '数据目录'), headDataDir), surface.created ? React.createElement('div', { style: S.muted }, '(配置文件刚按默认值生成)') : null);\n const parts = { styles: S, reply: surface };\n const extra = props.extra === undefined ? null : props.extra(parts);\n if (state.kind === 'failed') {\n return React.createElement('div', { style: S.card }, head, fileLines, React.createElement('div', { style: S.error }, state.message), extra, React.createElement('div', { style: S.bar }, React.createElement('button', { style: S.btn, type: 'button', onClick: props.onRetry }, '重试'), React.createElement('button', { style: S.btn, type: 'button', onClick: props.onReset }, '重置为默认')));\n }\n const common = props.items.filter((item) => item.tier === 'common');\n const advanced = props.items.filter((item) => item.tier === 'advanced');\n /** 还没读到整面(`loading`)时**框架照画**:行表与控件形状是客户端常量,不必等任何回执。\n * 值先空着、控件与三枚底栏键一律不可用;回执到了由 `ready` 那一支把值填上(见 `config-panel.ts`)。 */\n const frozen = props.busy || !ready;\n const followers = props.followerKeys ?? [];\n const renderRow = (item, last) => React.createElement(Row, {\n key: item.key,\n item,\n value: props.draft[item.key] ?? '',\n disabled: frozen,\n onChange: props.onChange,\n browser: props.rowEntry,\n dirty: ready && props.dirtyKeys.includes(item.key),\n follow: ready && props.followKeys.includes(item.key),\n onCopy: ready ? props.onCopy : undefined,\n copyState: props.copy !== null && props.copy.key === item.key ? (props.copy.ok ? 'done' : 'failed') : 'idle',\n alert: ready ? surface?.alerts?.[item.key] ?? null : null,\n last,\n nested: followers.includes(item.key),\n });\n /** 每组最后那一行才免掉下边线(`.ic-row:last-child`);母版行自己不带线,不必管。 */\n const lastIndexOf = (list) => {\n for (let i = list.length - 1; i >= 0; i -= 1)\n if (list[i].readonly === true)\n return i;\n return -1;\n };\n const commonLast = lastIndexOf(common);\n const advancedLast = lastIndexOf(advanced);\n const dirty = ready && dirtyCount > 0;\n return React.createElement('div', { style: S.card }, head, fileLines, ready ? null : React.createElement('div', { style: S.muted }, '配置读取中'), React.createElement('div', { style: S.rows }, common.map((item, index) => renderRow(item, index === commonLast))), advanced.length === 0\n ? null\n : React.createElement('details', { style: S.advanced }, React.createElement('summary', { style: S.summary }, React.createElement('span', { style: S.groupMark }, '›'), ADVANCED_GROUP_TITLE, React.createElement('span', { style: S.groupNote }, ADVANCED_GROUP_NOTE)), React.createElement('div', { style: S.groupBody }, advanced.map((item, index) => renderRow(item, index === advancedLast)))), extra, React.createElement('div', { style: S.bar }, React.createElement('button', { style: dirty ? S.btnPrimary : S.btn, type: 'button', disabled: frozen || !dirty, onClick: props.onSave }, props.busy ? '处理中' : dirty ? `保存(${dirtyCount} 项未保存)` : '保存'), React.createElement('button', { style: S.btn, type: 'button', disabled: frozen, onClick: props.onReset }, '重置为默认'), React.createElement('button', { style: S.btn, type: 'button', disabled: frozen, onClick: props.onRetry }, '重新读取'), \n // 那半句话是**最后一个孩子**:v3.1 的 `.ic-bar .ic-note{margin-left:auto}` 靠它把说明顶到行尾,\n // 三枚按钮留在左边(顺序反了就会成「说明靠左、按钮靠右」,与真源相反)。\n dirty\n ? React.createElement('div', { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`)\n : ready\n ? React.createElement('div', { style: S.barNote }, '没有未保存的改动')\n : null), props.picking ? React.createElement('div', { style: S.muted }, '已唤起系统文件夹对话框:选中后自动填上,取消则不动。') : null, props.browseRow !== null\n ? React.createElement(DirectoryBrowserFromRow, { open: true, row: props.browseRow, labels: BROWSER_LABELS })\n : null, props.writeError !== null\n ? React.createElement('div', { style: S.error, role: 'alert' }, props.writeError)\n : null, props.error !== null ? React.createElement('div', { style: S.error }, props.error) : null, props.notice !== null ? React.createElement('div', { style: S.okText }, props.notice) : null);\n}\n//# sourceMappingURL=config-panel-view.js.map","/** 「本机根清单」的取数接线(客户端半):把一通电话变成图上那一行可跳转的根。\n *\n * **不认识宿主**:载体基段、通道名(第二段)、电话名全由调用方传进来——各家从自己的宿主镜像里拿\n * 那几个字面量(和 `openRowBrowser` 的 `refusalCode` 同一条规矩)。本件只做两件事:\n * 发一次调用、把回执信封拆成根清单;**任何失败都当空清单**(图上少画一行,不报错、不挡路)。\n */\n/** 认一认某个值像不像一个根(认不出的行丢掉:图的干净比多画一行重要)。 */\nfunction isRootRow(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n const row = raw;\n return typeof row.path === 'string' && row.path !== '' && typeof row.kind === 'string';\n}\n/** 信封 → 根清单(纯函数,**永不抛**):`{ok:true, value:{roots:[…]}}` 之外的形状一律当空。 */\nexport function readRootsAnswer(raw) {\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok !== true)\n return [];\n const value = (typeof answer.value === 'object' && answer.value !== null ? answer.value : {});\n if (!Array.isArray(value.roots))\n return [];\n return value.roots.filter(isRootRow).map((row) => ({ path: row.path, kind: row.kind }));\n}\n/** 建一个「根清单取数器」:给调用口与三个名字,回一个 `() => Promise<RootRow[]>`。\n *\n * 界面按需调它(开图一次),不在渲染里调,也不缓存到这里——缓存是宿主半的事。 */\nexport function createRootsSource(input) {\n return async () => {\n const call = input.getCall();\n if (typeof call !== 'function')\n return [];\n try {\n return readRootsAnswer(await call(input.base, input.endpoint, { method: input.method, payload: {} }));\n }\n catch {\n return [];\n }\n };\n}\n//# sourceMappingURL=directory-browser-roots.js.map","/** 爱生活页签槽名(总管声明 `children`、各单品技能设置页注册进来;单段名,避开官方 `settings.*` 前缀)。\n *\n * 为什么住这里:这个名字**两侧都要用**——面板侧 `client.ts` 拿它注册/投影槽,\n * 宿主侧(`update-env.ts` 的 `readPanelRegistered`)拿它判「已装产物里到底有没有注册代码」。\n * 一处定义、两边引用(结构纪律「概念唯一」):名字改了只有这一行要动。\n * 宿主判据为什么要读这个字面量、以及它的边界,见 `readPanelRegistered` 的头注。 */\nexport const CONFIG_TAB_SLOT = 'ilife.config-tab';\n/** 载体基段:`connection.rpc.call` 的**第一段**参数,宿主注册路径与它同源(`'/api' + 通道名`)。\n *\n * 一处定义(#735):总管自己的电话、以及面板到各家的每一通电话,第一段都必须是它。\n * 真机实现(`dsh-client-connection/lib/client.js`):URL = `${第一段}/${第二段}`、信封 `method` = 第二段。\n * 传错第一段就是 404:总管自己的电话在 #678 栽过一次,各家的配置体检在 #735 又栽过一次\n * (那次传的是通道名 `/ilife-<技能>`,拼出来的地址上没有注册过那条路由,六家全 404)。 */\nexport const CARRIER_BASE = '/api';\n/** 载体:宿主注册 `connection.fetch.register` 的路径 / 面板 `connection.rpc.call` 的两段参数。 */\nexport const MANAGER_RPC = {\n /** 载体基段(`connection.rpc.call` 的**第一段**参数)。传错第一段就是 404:真机上踩过一次。 */\n base: CARRIER_BASE,\n /** 单段通道名,须 match `/^\\/[A-Za-z0-9._~-]+$/`(cookbook §6)。 */\n channel: '/ilife-manager',\n /** 面板侧第二段参数(等于通道名去掉前导斜杠那一段)。 */\n endpoint: 'ilife-manager',\n /** 宿主侧注册的完整路径(= `base` + `channel`)。 */\n path: '/api/ilife-manager',\n};\n/** 总管自有电话名:更新包的三个动作名是冻结集合(`config.ts:14`),这里另起名字不撞车。 */\nexport const MANAGER_ACTIONS = {\n /** 装上缺席的目标包:入参 `{packageName, version}`,回包 `{packageName, version}`。 */\n install: 'ilife-manager.install',\n /** 七个更新目标的表:入参 `{}`,回包 `{targets: [{key, title, packageName, phones, runningVersion, installedVersion, panelRegistered, skill}]}`。\n *\n * 电话名为什么由宿主转交而不是面板侧写死:更新包的三个电话名只有它自己知道\n * (`update.phoneNames`,`host.ts:335`);面板侧既不能 import 更新包(浏览器产物纯度门)\n * 也不该把名字再写一份(写两份必然走散)。宿主把名字表连同版本行一起交出去,\n * 面板一行字面量都不留。 */\n targets: 'ilife-manager.targets',\n /** 总管自述版本(票 #737):入参 `{}`,回包 `{version}`。\n *\n * 宿主读**自己这份已安装包**的 `package.json`(`manager-version.ts`),面板只渲染读到的值。\n * 为什么走电话:面板是浏览器产物,禁 node 内建(`test/client-bundle-48.test.mjs` 看门),\n * 读盘只许在宿主半;与卡路里 #130 同一条路(host 读 → RPC → client 纯渲染)。 */\n version: 'ilife-manager.version',\n /** 本机「根」清单(票 #744):入参 `{}`,回包 `{roots: [{path, kind}]}`。\n *\n * 为什么这条能力住在总管:浏览器里没有卷清单接口,而宿主那条目录选择接缝只有\n * `list`/`createDirectory` 两格——「这台机器上有哪些盘」只能由宿主去问操作系统。\n * 六家的目录浏览器都取这一通电话,故名字与实现都只有这一处(清单本身见 `roots.ts`)。\n * 回包**恒成功**:列不出来是空清单,不是错误码(界面据此只是不画那一行)。 */\n roots: 'ilife-manager.roots',\n};\n/** 版本读不到时两侧共用的降级字面量(面板照原样显示,不假装知道版本)。\n *\n * 一处定义、两侧引用:宿主半 `manager-version.ts` 读失败时回它,面板半 `update-client.ts`\n * 归一化时也认它——面板侧不许 import 宿主半(会把 node 内建带进浏览器束)。 */\nexport const VERSION_UNKNOWN = 'unknown';\n/** 更新包默认官方源(`config.ts:20`,总管侧拼手工命令时用同一个值)。 */\nexport const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';\n/** 装不了 / 装不成的人话原因表:八种 `blockedReason` + 过程错误码(更新包 README 第 8、12 节)。\n *\n * 每条都要三段齐全(票 #740 的文案判据):**事实**(哪里对不上)→ **后果**(这家现在能不能装)\n * → **动作**(用户做得到、且面板上真有的那一步;面板代劳不了的走「下面这条命令」)。\n * 禁用口语与自造词:「半截任务」「电话没接上」「回执异常」「还出现就重装」「查宿主日志」一律不写。\n *\n * 点名的按钮必须是**这一行上真够得着**的那颗(票 #740 第三轮):结果浮层一开就盖住题头的\n * 「检查更新」,所以「改完再读一次」这类下一步一律写「重新检查」(画在那一行上);\n * 只有发生在**重启之后**的下一步才写「检查更新」。反过来,凡是写着「下面这条命令」的那几句,\n * 那一行的命令块必须真出来(判据 `Verdict.manualHint`)——两处都由门禁守着。 */\nconst REASON_TEXT = {\n 'unknown-profile': '认不出这台机器上的安装位置(使用范围的目录不存在,或名字不合法)。把使用范围目录建好,再点「重新检查」。',\n 'source-install': '这一份不是从 npm 发行包装的(源码装),面板不能更新它。要更新,照下面这条命令重装,装完再点「重新检查」。',\n 'invalid-installation': '磁盘上这一份装得不完整(包名或版本对不上、入口文件缺失)。照下面这条命令重装,装完再点「重新检查」。',\n 'installation-changed': '这台机器的安装清单变了(在别处装过、或清单被手工改过),这一家现在不能装。点「重新检查」重新读一次,再点「装上更新」。',\n 'pending-restart': '新版已装到磁盘,正在运行的是旧版本。重启 DSH(退出后重新打开)后生效。',\n 'registry-conflict': '使用范围清单里写的版本与磁盘上的实际版本对不上。打开使用范围的 `package.json`,把这一行改成磁盘上的版本号,再点「重新检查」。',\n 'incompatible-node': '新版本要求 Node 22 或更高,当前运行的是更低版本。升级 Node、重启 DSH 后,再点「检查更新」。',\n // 这条只在「磁盘上的版本与正在运行的一致(或磁盘那份读不到)」时才会印出来——「磁盘 ≠ 运行中」\n // 那一态被事实判据先截走,印的是 `restartLine`。故这里**不许**再教人去重启(那在眼下没用)。\n 'recovery-required': '上次安装没有收尾。点「重试安装」再跑一次;还出现这一条,就用下面这条命令重装。',\n 'check-failed': '查不到最新版本:联网失败,或官方源(registry.npmjs.org)不可达。确认网络与源地址后,再点「重新检查」。',\n 'invalid-release': '官方源上这个版本的元数据不完整(包名或版本不合法、包地址或校验值缺失)。换一个版本,或稍后重试。',\n 'check-expired': '上次检查的结果已过期。点「重新检查」重查一次,再点「装上更新」。',\n 'update-busy': '同一时间只能安装一个插件。等这次装完,再点「装上更新」。',\n 'install-failed': '安装没有完成。在终端里执行下面这条命令把它装完,装完再点「重新检查」。',\n 'manager-unreachable': '面板连不上总管插件(宿主里没注册,或版本对不上)。重启 DSH 后重试;仍不行就在 DSH 日志里找 `[dsh-life-pack]` 的报错。',\n 'bad-request': '面板与总管之间的请求出错了(属程序缺陷)。请在 DSH 日志里找 `[dsh-life-pack]` 的报错,连同这家插件的名字报到本仓 issue。',\n internal: '面板与总管之间的请求出错了(属程序缺陷)。请在 DSH 日志里找 `[dsh-life-pack]` 的报错,连同这家插件的名字报到本仓 issue。',\n};\n/** 原因码 → 人话(认不出的码不猜、原样回码并说明这是未知原因)。 */\nexport function reasonText(code) {\n return REASON_TEXT[code] ?? '面板不认识这个原因码(' + code + ')。请在 DSH 日志里找同一处报错,报到本仓 issue。';\n}\n/** 手工兜底命令(更新包 README 第 9 节形状):使用范围名含特殊字符时加引号。 */\nexport function manualInstallCommand(input) {\n const name = typeof input.profileName === 'string' ? input.profileName.trim() : '';\n if (!name || name.length > 255 || name.startsWith('-') || ['.', '..', 'node_modules'].includes(name))\n return null;\n const version = typeof input.version === 'string' && /^\\d+\\.\\d+\\.\\d+$/.test(input.version) ? input.version : '';\n if (!version)\n return null;\n const registry = input.registryUrl ?? DEFAULT_REGISTRY;\n const profileArg = /^[A-Za-z0-9_.-]+$/.test(name) ? name : JSON.stringify(name);\n return 'dsh plugin --profile ' + profileArg + ' add --save-exact ' + input.packageName + '@' + version + ' --registry=' + registry;\n}\n/** 八种装不了原因码(给门禁与测试对表用;值就是 `BlockedReason` 全集)。 */\nexport const BLOCKED_REASONS = [\n 'unknown-profile',\n 'source-install',\n 'invalid-installation',\n 'installation-changed',\n 'pending-restart',\n 'registry-conflict',\n 'incompatible-node',\n 'recovery-required',\n];\n//# sourceMappingURL=update-contract.js.map","/** 共用配置面板 · 组件本体:一台状态机 + 一圈副作用,渲染交给 `config-panel-view.ts`。\n *\n * 这一件就是六个技能设置页的那张卡片:六家只交「连哪条通道」与「有哪些配置项」(行表),\n * 另加三个可选钩子(跟随映射/卡片标题/自家附加块)。卡片怎么画、值怎么取又怎么填回去、\n * 哪些行被改过还没保存、保存/重置/重新读取怎么走、出错时说什么话,全在本件与它下面那几件里。\n *\n * 状态:读到了没(loading/ready/failed)、哪些行被改过(脏基线)、正在写(busy)、\n * 写完的结果(notice/writeError)、就地失败(error)、目录选择那一路(picking/browseRow)、\n * 复制回执(copy)。**脏基线只看可改行**:只读行显示的是技能算好的绝对路径,拿它当「改动」\n * 会让面板一打开就显示「未保存」。**写完一律重新读一份整面**:写回执不是整面,拿它当整面用\n * 会让页头那行「数据目录」显示成空。\n *\n * 只挂一个副作用(挂载期读一次整面):取数口是**取用器**,每次调它现取,所以那个 effect\n * 不需要跟着任何一格重跑——否则回执一落定就再读一次,会自己把自己转起来。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport * as React from 'react';\nimport { COPY_FEEDBACK_MS, DIRECTORY_PICKER_REFUSED, REMOTE_DIRECTORY_PICKER } from './config-panel-contract.js';\nimport { dirtyKeysOf, fetchConfigSurface, fromDraft, noFollowKeys, resetConfigSurface, saveConfigSurface, toDraft, } from './config-panel-value.js';\nimport { PanelBody } from './config-panel-view.js';\nimport { openRowBrowser, pickerModeOf, readPickAnswer } from './directory-browser-api.js';\nimport { createRootsSource } from './directory-browser-roots.js';\nimport { MANAGER_ACTIONS, MANAGER_RPC } from './update-contract.js';\n/** 认一认某个值像不像目录选择命名空间(认不出就当没有,绝不把设置页带下来)。 */\nfunction isPickerFace(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return typeof raw.pick === 'function';\n}\n/** 现取目录选择命名空间:**软依赖**,拿不到回 null(页面据此不出入口)。 */\nfunction resolvePicker(getService) {\n if (getService === undefined)\n return null;\n try {\n const raw = getService(REMOTE_DIRECTORY_PICKER);\n return isPickerFace(raw) ? raw : null;\n }\n catch {\n return null;\n }\n}\n/** 唤起一次系统文件夹选择器并归一结果(**永不抛**)。 */\nasync function pickDirectory(picker) {\n try {\n return readPickAnswer(await picker.pick());\n }\n catch (e) {\n const reason = e instanceof Error ? e.message : String(e);\n return { kind: 'unavailable', message: '打不开系统文件夹对话框(' + reason + '):请直接在框里填绝对路径。' };\n }\n}\n/** 写一次剪贴板:**不碰 DOM**,只读当刻环境的 `globalThis.navigator`(拿不到就回 false,不抛)。\n *\n * 为什么不照原型那样退到 `document.execCommand`:本仓插件侧禁 DOM 直写(`document`/`window`),\n * 所以没有那条兜底;拿不到剪贴板就如实回 false,界面上那一枚按钮就地显示「复制失败」。 */\nasync function writeClipboard(text) {\n try {\n const nav = globalThis.navigator;\n const clip = nav?.clipboard;\n if (clip === undefined || typeof clip.writeText !== 'function')\n return false;\n await clip.writeText(text);\n return true;\n }\n catch {\n return false;\n }\n}\n/** **静态**跟随行名单:给行表里每个键喂一遍六家交的钩子,收它返回的跟随者。\n *\n * 为什么能这么探:`followKeysOf` 是**纯函数**,六家的实现都只是「脏键里有没有这一格」那一下判断\n * (各家 `src/client.ts`),喂单键即得「谁跟着它」——**与当刻脏不脏无关**。有了这个集合,共用件就能\n * 照 v3.1 的 `.ic-under` 把跟随行相对它的可改行缩进(#920 补),**六家源码一个字节不用改**。\n * 拿不到钩子时回空表(一行都不缩进,照旧平铺)。 */\nexport function followerKeysOf(items, hook) {\n if (hook === undefined)\n return [];\n const out = new Set();\n for (const item of items)\n for (const key of hook([item.key]))\n out.add(key);\n return [...out];\n}\n/** 技能设置页:承载一家自己的全部可配置项(只配置,不干活)。 */\nexport function ConfigPanel(props) {\n const [state, setState] = React.useState({ kind: 'loading' });\n const [pickerGone, setPickerGone] = React.useState(false);\n const [picking, setPicking] = React.useState(false);\n const [draft, setDraft] = React.useState({});\n const [busy, setBusy] = React.useState(false);\n const [notice, setNotice] = React.useState(null);\n const [writeError, setWriteError] = React.useState(null);\n const [error, setError] = React.useState(null);\n const [browseRow, setBrowseRow] = React.useState(null);\n const [copy, setCopy] = React.useState(null);\n /** 复制回执的复位定时器:**一次性 UI 回执**,不是数据轮询——点一次起一个,到点自我复位,\n * 下一次点击先清掉旧的,卸载时也清掉(下面那个清扫 effect 就是那一半)。 */\n const copyTimer = React.useRef(null);\n React.useEffect(() => () => {\n if (copyTimer.current !== null) {\n clearTimeout(copyTimer.current);\n copyTimer.current = null;\n }\n }, []);\n /** 挂载期读一次整面:卸载之后回来的回执丢掉(不许往已经没了的页面上写)。 */\n React.useEffect(() => {\n let alive = true;\n void (async () => {\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (!alive)\n return;\n if (r.ok) {\n setState({ kind: 'ready', surface: r.surface });\n setDraft(toDraft(props.items, r.surface.values, r.surface));\n }\n else {\n setState({ kind: 'failed', message: r.message });\n }\n })();\n return () => {\n alive = false;\n };\n // 只跑一次:`getCall` 本身是取用器,调用时现取连接;行表与通道在一张卡片里不会换。\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n /** 把一份整面铺到页面上(读到之后唯一那一处落点)。 */\n const apply = (surface) => {\n setState({ kind: 'ready', surface });\n setDraft(toDraft(props.items, surface.values, surface));\n };\n const load = async () => {\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (r.ok)\n apply(r.surface);\n else\n setState({ kind: 'failed', message: r.message });\n };\n /** 写完(保存/重置)之后重新读一份整面:写回执只有 `{path, values}`、重置回执只有\n * `{path, backupPath}`,都不是整面——拿它当整面用,页头那行「数据目录」会显示成空。 */\n const writeThenReload = async (done) => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (r.ok) {\n apply(r.surface);\n setNotice(done);\n }\n else {\n setState({ kind: 'failed', message: r.message });\n }\n setBusy(false);\n };\n const onChange = (key, next) => {\n setDraft((prev) => ({ ...prev, [key]: next }));\n setNotice(null);\n setWriteError(null);\n setError(null);\n };\n const picker = pickerGone ? null : resolvePicker(props.getService);\n /** 唤起系统文件夹选择器那一条路(应用内浏览被拒时的兜底,也是命名空间只给 `pick` 时的唯一一条)。 */\n const openNative = async (key) => {\n const face = pickerGone ? null : resolvePicker(props.getService);\n if (face === null)\n return;\n // 系统对话框是模态的:等它回来的这段时间给一行字,免得看着像「点了没反应」。\n setPicking(true);\n setError(null);\n const outcome = await pickDirectory(face);\n setPicking(false);\n if (outcome.kind === 'picked')\n onChange(key, outcome.path);\n else if (outcome.kind === 'unavailable') {\n setError(outcome.message);\n setPickerGone(true);\n }\n };\n /** 目录行的入口动作:**先应用内浏览,宿主没给这条路再换系统对话框**(判断在共用件里)。 */\n const onOpenRow = async (key) => {\n setError(null);\n const opened = openRowBrowser({\n picker,\n initialPath: draft[key] ?? '',\n onChange: (next) => onChange(key, next),\n onRow: setBrowseRow,\n refusalCode: DIRECTORY_PICKER_REFUSED,\n rootsSource: createRootsSource({\n getCall: props.getCall,\n base: MANAGER_RPC.base,\n endpoint: MANAGER_RPC.endpoint,\n method: MANAGER_ACTIONS.roots,\n }),\n });\n if (opened === undefined || (await opened) === 'refused')\n await openNative(key);\n };\n /** 复制一行(定稿 v3 第三条):写完就地变「已复制」(写不进去就地变「复制失败」),1.5 秒后复位,不弹提示。 */\n const onCopy = (key, text) => {\n void writeClipboard(text).then((ok) => {\n setCopy({ key, ok });\n if (copyTimer.current !== null)\n clearTimeout(copyTimer.current);\n copyTimer.current = setTimeout(() => {\n copyTimer.current = null;\n setCopy(null);\n }, COPY_FEEDBACK_MS);\n });\n };\n const onSave = async () => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await saveConfigSurface(props.getCall(), props.channel, fromDraft(props.items, draft));\n setBusy(false);\n if (r.ok)\n await writeThenReload('已保存,立即生效(不用重启宿主)');\n else\n setWriteError(r.message);\n };\n const onReset = async () => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await resetConfigSurface(props.getCall(), props.channel);\n setBusy(false);\n if (r.ok)\n await writeThenReload('已重置为默认(原配置已另存一份 .bak)');\n else\n setWriteError(r.message);\n };\n const surface = state.kind === 'ready' ? state.surface : null;\n const baseline = surface !== null ? toDraft(props.items, surface.values, surface) : null;\n const dirtyKeys = baseline === null ? [] : dirtyKeysOf(props.items, draft, baseline);\n const followKeys = (props.followKeysOf ?? noFollowKeys)(dirtyKeys);\n /** 技能侧报出「有格子真用不了」⇒ 标题行那枚「配置里有值用不了」徽标才亮(#915 第二步)。 */\n const hasAlert = surface !== null && surface.alerts !== undefined && Object.keys(surface.alerts).length > 0;\n /** 静态那一份(与脏不脏无关):画跟随行的缩进用(v3.1 的 `.ic-under`)。 */\n const followerKeys = followerKeysOf(props.items, props.followKeysOf);\n const mode = pickerModeOf(picker);\n const rowEntry = mode === 'none' ? null : { mode, onOpen: onOpenRow };\n return React.createElement(PanelBody, {\n title: props.title,\n items: props.items,\n state,\n draft,\n busy,\n notice,\n writeError,\n error,\n picking,\n browseRow,\n rowEntry,\n dirtyKeys,\n followKeys,\n followerKeys,\n invalid: hasAlert,\n copy,\n onCopy,\n onChange,\n onSave: () => void onSave(),\n onReset: () => void onReset(),\n onRetry: () => void load(),\n extra: props.extra,\n });\n}\n//# sourceMappingURL=config-panel.js.map","/** dsh-bill-ilife 端口(port):DSH 世界与饼干记账 hexagon 之间的契约。\n *\n * browser 安全:零 node 导入。host 适配器(注册 RPC 通道)与 client\n * 适配器(调用 RPC)共用同一份定义;单测与 loader 回路以此为准。\n * 通道命名遵守宿主约束:单段且不等于 /api(见 cookbook「RPC 通道」)。\n *\n * 照 #56 卡路里样板同形(`packages/plugin-calorie/src/contract.ts`):记账插件原先\n * **没有任何 RPC 通道**,本件是它第一份端口定义(#677)。\n */\nexport const RPC_CHANNEL = '/ilife-bill-ilife' as const;\nexport const RPC_ENDPOINT_READ = 'read' as const;\n\n/** #677 配置端点:读设置页整面、保存一份取值、重置为默认。同走一条通道,靠端点名分发。 */\nexport const RPC_ENDPOINT_CONFIG_GET = 'config.get' as const;\nexport const RPC_ENDPOINT_CONFIG_SAVE = 'config.save' as const;\nexport const RPC_ENDPOINT_CONFIG_RESET = 'config.reset' as const;\n/** #706 配置体检端点:只读一次,回一份报告(判据由技能侧出,本包只透传,不重写一个字)。\n *\n * 端点名与技能侧那条只读命令同名(`<技能>.config.check`);报告形状的唯一真相在技能侧\n * `packages/skill-<技能>/src/health.ts`,面板侧镜像在 `packages/plugin-manager/src/health-contract.ts`。 */\nexport const RPC_ENDPOINT_CONFIG_CHECK = 'config.check' as const;\n\n/** 读请求载荷:与技能 CLI 的 key/params 同形(见 skill-bill SKILL.md)。 */\nexport interface ReadPayload {\n readonly key: string;\n readonly params: Record<string, unknown>;\n}\n\n/** 保存载荷:一份键值(键路径 → 值)。缺项由技能侧按默认值补齐,故只收用户真改的那些。 */\nexport interface SavePayload {\n readonly values: Record<string, unknown>;\n}\n\nexport interface RpcError {\n readonly code: string;\n readonly message: string;\n readonly details: Record<string, unknown>;\n}\n\nexport type RpcResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly error: RpcError };\n\nexport function ok(value: unknown): RpcResult {\n return { ok: true, value };\n}\n\nexport function fail(code: string, message: string): RpcResult {\n return { ok: false, error: { code, message, details: {} } };\n}\n\n/** 读载荷校验:形状不对返回 null,由调用方按 bad-request 回绝(不抛)。 */\nexport function parseReadPayload(raw: unknown): ReadPayload | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const { key, params } = raw as { key?: unknown; params?: unknown };\n if (typeof key !== 'string' || key.length === 0) return null;\n if (typeof params !== 'object' || params === null || Array.isArray(params)) return null;\n return { key, params: params as Record<string, unknown> };\n}\n\n/** 保存载荷校验:形状不对返回 null,由调用方按 bad-request 回绝(不抛)。 */\nexport function parseSavePayload(raw: unknown): SavePayload | null {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return null;\n const { values } = raw as { values?: unknown };\n if (typeof values !== 'object' || values === null || Array.isArray(values)) return null;\n return { values: values as Record<string, unknown> };\n}\n\n/** 解析后的绝对路径组(#749):技能侧算好的落点,设置页的只读行**只显示、不计算**\n * (口径「面板不算默认值、不拼路径」,见 #677 冻结的边界)。\n *\n * 格名与技能侧 `packages/skill-bill/src/fetch/paths.ts` 的 `BillResolvedPaths` 逐字同形\n * (那是算式与取值的唯一定义地);六家的 `*.config.read` 都扩这样一组,各自的格子按自家落点项来。 */\nexport interface ResolvedPaths {\n /** 生效数据目录(面板上唯一可改的那一项的生效值)。 */\n readonly dbDir: string;\n /** 库文件绝对路径。 */\n readonly dbFile: string;\n /** 第二份库(预算/账户)绝对路径。 */\n readonly goalsFile: string;\n /** HELP 产物目录绝对路径。 */\n readonly htmlDir: string;\n /** 备份目录绝对路径。 */\n readonly backupDir: string;\n /** 备份文件名示例(`<前缀><时间戳>.db`,前缀按当刻配置)。 */\n readonly backupSample: string;\n}\n\n/** 配置面回执:形状与技能侧 `bill.config.read` 的 data 逐字段同形(唯一定义地在那边的 cli/config.ts)。 */\nexport interface ConfigSurfaceReply {\n /** 配置文件绝对路径。 */\n readonly path: string;\n /** 数据目录绝对路径。 */\n readonly dataDir: string;\n /** 本次是不是「文件不存在、按默认值落了一份」。 */\n readonly created: boolean;\n /** 当前取值(文件里的 ⊕ 缺项按默认值补)。 */\n readonly values: Record<string, unknown>;\n /** 一组解析后的绝对路径(#749 起技能侧回执带上)。\n * **可选**:装的是旧技能时这一格缺席,只读行显示空串(面板不自己拼路径,绝不编一条出来)。 */\n readonly resolved?: ResolvedPaths;\n}\n\n/** 信封守卫:供 client 拆包前校验(port 拥有信封定义,守卫住 port)。 */\nexport function isRpcResult(raw: unknown): raw is RpcResult {\n if (typeof raw !== 'object' || raw === null) return false;\n const okFlag = (raw as { ok?: unknown }).ok;\n return okFlag === true || okFlag === false;\n}\n","/** dsh-bill-ilife 槽位描述(P10 脚手架,P3 #4 定案)。\n *\n * 写死槽位原生组件:id 命名空间 ilife:cookie,order 95。\n * 注册与打开只走 registerTab/openTab 的路径导航;子页后缀(如 ilife:cookie:*)\n * 只在主面板内导航,不占栏。缺席纯条件渲染,不轮询(本文件无定时器;\n * 有界重试归一由 base-render 拥有,单品不自建)。\n */\n\nexport const SKILL = 'bill' as const;\nexport const SLOT_ID = 'ilife:cookie' as const;\nexport const SLOT_ORDER = 70 as const;\nexport const SLOT_TITLE = '饼干记账' as const;\nexport const PLUGIN = 'dsh-bill-ilife' as const;\nexport const MANAGER_PLUGIN = 'dsh-life-pack' as const;\n\nexport interface SlotDescriptor {\n readonly skill: string;\n readonly slotId: string;\n readonly order: number;\n readonly title: string;\n readonly kind: 'page';\n}\n\nexport function slotDescriptor(): SlotDescriptor {\n return { skill: SKILL, slotId: SLOT_ID, order: SLOT_ORDER, title: SLOT_TITLE, kind: 'page' };\n}\n\n/** 写死原生组件描述(纯数据,无按需加载,无外嵌页)。 */\nexport const TAB_COMPONENT = { kind: 'native', name: 'BillPanel' } as const;\n\nexport interface TabsPort {\n hasTabs(): boolean;\n registerTab(entry: { readonly id: string; readonly title: string; readonly order: number; readonly single: boolean; readonly component: unknown }): () => void;\n openTab(seed: { readonly type: string; readonly path: string }, scope?: { readonly sessionId?: string }): void;\n}\n\n/** 自注册:幂等(调用方持 disposer),失败返回 false 由调用方决定重试。 */\nexport function registerSingle(port: TabsPort): (() => void) | null {\n if (!port.hasTabs()) return null;\n return port.registerTab({ id: SLOT_ID, title: SLOT_TITLE, order: SLOT_ORDER, single: true, component: TAB_COMPONENT });\n}\n\n/** 内容型打开:path seed,折叠面板自动展开。 */\nexport function openSingle(port: TabsPort, sessionId?: string): void {\n if (!port.hasTabs()) return;\n port.openTab({ type: SLOT_ID, path: SLOT_ID }, sessionId ? { sessionId } : undefined);\n}\n","/** dsh-bill-ilife 设置页元数据(#677:从只读脚手架换成真配置页)。\n *\n * 本文件是**设置页的行表**:一个可配置项一行,写清它在配置文件里的键、中文标题、\n * 分级(常用 / 高级)、控件种类、只读与否与人话指引。它是页面渲染的唯一依据。\n *\n * **本文件必须零 node 依赖**:`tsconfig.client.json` 把它收进 client 侧编译,\n * 浏览器产物不许带 node 内建。取值一律由宿主经技能 CLI 的 `bill.config.read` 端点现取\n * (见 bridge.ts)。\n *\n * 口径:\n * · 配置表形状(键与默认值)的**唯一定义地**是技能侧 `packages/skill-bill/src/config.ts`\n * 的 `BILL_CONFIG_DEFAULTS`(本文件是它在页面上的投影,逐键对齐由\n * `test/config-surface-677.test.mjs` 用编译产物锁死);\n * · **空串=按默认落点**(老落点由技能各取用处算),所以「空」不是「没配」,\n * 而是「还走改造前那个位置」,老数据不会看起来丢了——行文案按这个语义写;\n * · `db.dir` 那一行的落点由配置面回执的 `dataDir` 带回(解析好的绝对路径),页面上把它**预填**进\n * 该行(`prefillFrom: 'dataDir'`),用户不必自己拼路径(#743)。\n *\n * **#749 起本家是六家的样板**:页面从「可改表单」收窄成**一处可改 + 其余只读展示**——\n * · 可改 1 项:数据目录(`db.dir`,显示生效绝对路径,值非法/空 ⇒ 回落默认数据目录);\n * · 只读 5 项:库文件名/预算账户文件名/HELP 产物目录名/备份目录/备份文件名前缀——它们\n * **只显示技能算好的绝对路径**(`resolveFrom` 指向回执 `resolved` 组的那一格),面板既不重算也不提交;\n * · 只读目录行(备份目录)的「浏览」按钮**保留但不可点击**(#747 定稿:入口不作废,只是不能改)。\n *\n * 清单出处:「六家技能的路径类配置全量调查」记账 8 项去掉 1 项包内固定(包内页面模板目录)\n * =上设置页候选 7 项,其中「产物文件名主体」在源码里是两个值(#677 起行数 8)。\n * **#762 起那两个产物名主体出配置表**(键已退休、文件名回到技能侧代码常量);\n * **#749 起那 5 行转只读**,故本表仍是 6 行(可改 1 + 只读 5)。\n */\nexport const SETTINGS_OWNER = 'dsh-bill-ilife' as const;\nexport const SETTINGS_SLOT = 'ilife:cookie' as const;\n\n/** 配置文件主体名:落点 `~/.ilife/bill.yaml`。 */\nexport const CONFIG_STEM = 'bill' as const;\n\n/** 分级:常用项直接画在页面上,其余进默认收起的「高级」组(#675 冻结口径)。 */\nexport type ConfigTier = 'common' | 'advanced';\n\n/** 控件种类:只有这四种(前三种与受限 YAML 子集的字符串/数字/布尔一一对应,没有数组;\n * `directory` 是**字符串那一档的页面形态**——取值仍是串,只是多一个唤起系统文件夹选择器的入口,见 #736)。 */\nexport type ConfigControl = 'text' | 'number' | 'switch' | 'directory';\n\n/** 只读行显示的那一格:技能侧回执 `resolved` 组里的格名(面板只显示、不计算)。 */\nexport type ResolvedField = 'dbDir' | 'dbFile' | 'goalsFile' | 'htmlDir' | 'backupDir' | 'backupSample';\n\nexport interface ConfigItem {\n /** 配置文件里的键路径,一层嵌套用 `.` 连接,例 `backup.dir`。 */\n readonly key: string;\n /** 页面上那一行的中文标题。 */\n readonly title: string;\n readonly tier: ConfigTier;\n readonly control: ConfigControl;\n /** 一行人话:这一项管什么、留空会怎样(一到两句,不写开发期口径)。 */\n readonly hint: string;\n /** **只读行**(#749):页面上不给改,值只经技能侧解析后显示;改它要编辑配置文件。\n * 只读行**不参与**保存(`fromDraft` 不收它,免得把显示用的绝对路径写回配置)。 */\n readonly readonly?: boolean;\n /** 只读行的**显示值来源**:回执 `resolved` 组里的哪一格。标了它 ⇒ 显示技能算好的绝对路径;\n * 不标 ⇒ 显示配置文件里那个值本身(数字类只读项走这一档,见 #749 补注二的甲档)。 */\n readonly resolveFrom?: ResolvedField;\n /** 目录行的落点来源:这一行取值空着时,页面上拿配置面回执里的哪一格当它显示的绝对路径。\n * 只有 `db.dir` 标它——回执里的 `dataDir` 就是技能真会用的那个目录,逐字相同。 */\n readonly prefillFrom?: 'dataDir';\n}\n\n/** 常用项:改了就影响「库与产物落在哪」,放页面上。 */\nconst COMMON: readonly ConfigItem[] = [\n {\n key: 'db.dir',\n title: '数据目录',\n tier: 'common',\n control: 'directory',\n // 留空=技能按默认目录落文件;页面上把解析出来的绝对路径直接填进这一行(见 client.ts 的 toDraft)。\n prefillFrom: 'dataDir',\n hint: '库文件与备份的根目录。留空=用默认目录。',\n },\n {\n key: 'db.name',\n title: '库文件名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'dbFile',\n hint: '数据目录下的库文件。',\n },\n {\n key: 'db.goals',\n title: '预算/账户文件名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'goalsFile',\n hint: '与库同目录的预算与账户文件。',\n },\n {\n key: 'html.dir',\n title: 'HELP 产物目录名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'htmlDir',\n hint: 'HELP 与速查表的存放目录。',\n },\n];\n\n/** 高级项:默认收起。改错了多半只是自己撞上麻烦,不确定就别动。 */\nconst ADVANCED: readonly ConfigItem[] = [\n {\n key: 'backup.dir',\n title: '备份目录',\n tier: 'advanced',\n control: 'directory',\n readonly: true,\n resolveFrom: 'backupDir',\n hint: '备份与恢复的读写目录。',\n },\n {\n key: 'backup.stem',\n title: '备份文件名前缀',\n tier: 'advanced',\n control: 'text',\n readonly: true,\n resolveFrom: 'backupSample',\n hint: '备份文件名的前缀,后面自动加时间戳。',\n },\n];\n\n/** 设置页的行表,顺序即页面顺序。 */\nexport const CONFIG_ITEMS: readonly ConfigItem[] = [...COMMON, ...ADVANCED];\n\n/** 常用项行数(页面上直接画出来的那些)。 */\nexport const COMMON_ITEM_COUNT = COMMON.length;\n\n/** 高级组标题与副文案。 */\nexport const ADVANCED_GROUP_TITLE = '高级' as const;\nexport const ADVANCED_GROUP_NOTE = '不常改。留空=用默认值。' as const;\n\n/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */\nexport function readPath(values: Record<string, unknown>, key: string): unknown {\n const parts = key.split('.');\n let cur: unknown = values;\n for (const part of parts) {\n if (typeof cur !== 'object' || cur === null || Array.isArray(cur)) return undefined;\n cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\n/** 按 `a.b` 路径把值写进配置取值(中间层缺就建一层空组;已存在非组即覆盖成组)。 */\nexport function writePath(values: Record<string, unknown>, key: string, value: unknown): void {\n const parts = key.split('.');\n let cur: Record<string, unknown> = values;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n const next = cur[part];\n if (typeof next !== 'object' || next === null || Array.isArray(next)) cur[part] = {};\n cur = cur[part] as Record<string, unknown>;\n }\n cur[parts[parts.length - 1]!] = value;\n}\n","/** dsh-bill-ilife client 适配器(六边形:port=contract,adapter=本文件)。\n *\n * 产物经 tsdown 打成 loader 工厂包(browser/CJS,见 tsdown.config.ts)。\n * 本文件传递闭包:禁 node、禁 DOM 直写(document/window/process)。\n * 注册一处:**技能设置页** → 爱生活页签槽(总管声明的 children,各技能自研自家配置页)。\n * 取数只经 connection.rpc.call 进 host 通道;缺席/错误纯条件渲染,不返空冒充。\n *\n * #909:设置页本体(样式表/行渲染/卡片骨架/状态机/取值与填值/配置面三通电话/\n * 目录选择入口)**收进共用件** `dsh-life-pack/config-panel`,本文件只留四处接线:\n * ① 行表(住 `settings.ts`——那是本家自己的配置数据,不是 UI);\n * ② 通道路由名(`RPC_CHANNEL`,本家唯一那个真变量);\n * ③ 三个可选钩子(卡片标题/跟随映射/自家附加块;本家只用到前两个);\n * ④ 两格宿主取数接线(`getCall`/`getService`)。\n * 本家**不再有**自己的样式表与行渲染函数:改一次共用面板,六家一起变;跨包那两道锁改指向\n * 共用件之后仍然守住「六家同形」这条性质(见 #910)。\n * 照 CONTEXT.md,「技能设置页」只配置、不干活:本页没有查账、记一笔之类的入口。\n */\nimport * as React from 'react';\nimport { ConfigPanel } from 'dsh-life-pack/config-panel';\nimport { RPC_CHANNEL } from './contract.js';\nimport { PLUGIN, SLOT_ORDER, SLOT_TITLE } from './slot.js';\nimport { CONFIG_ITEMS } from './settings.js';\nimport type { ClientCtx } from './dsh-ctx.js';\n\n/** client 短名声明:只有这两个(#736 的目录选择走**可选查找**,不写进来——\n * 写进来=硬依赖,提供方缺席时整包被停靠,设置页会跟着装不上;见 cookbook §13)。 */\nexport const inject: readonly string[] = ['slots', 'connection'];\n\n/** 跟随映射(#863):触发键一脏,这些只读派生行就进“将跟随更新”态。纯函数,面板与单测共用。 */\nconst DB_FOLLOWERS: readonly string[] = ['db.name', 'db.goals', 'html.dir', 'backup.dir', 'backup.stem'];\n\n/** 脏键 → 跟随行(#863 纯函数,交给共用面板当钩子)。 */\nexport function followKeysOf(dirtyKeys: readonly string[]): readonly string[] {\n return dirtyKeys.includes('db.dir') ? [...DB_FOLLOWERS] : [];\n}\n\nexport function apply(ctx: ClientCtx): void {\n // 调用口取用器:每次取数时现取(connection 后到也不永久缺席)。\n const getCall = (): unknown => ctx.connection?.rpc?.call ?? null;\n // #736 目录选择:**软依赖**。形状守卫与「拿不到就不出入口」都住在共用件里(判断只有一处),\n // 本处只把宿主服务查找原样交出去;提供方后到/中途卸载都不留痕(不声明、不停靠,见 cookbook §13)。\n const getService = (name: string): unknown => (typeof ctx.get === 'function' ? ctx.get(name) : undefined);\n\n // 技能设置页 → 爱生活页签槽(总管声明;总管缺席时 inject 等待,不断链)。\n ctx.slots.inject('ilife.config-tab', () =>\n ctx.slots.register(\n {\n name: 'ilife.config-tab',\n id: PLUGIN,\n order: SLOT_ORDER,\n label: () => SLOT_TITLE,\n // #706:本包自己那条 RPC 通道交给总管(各家都写这一格),总管据此调配置体检——\n // 它因此不必在源码里写死任何一家的通道名(零单品依赖照旧成立)。\n channel: RPC_CHANNEL,\n },\n () => React.createElement(ConfigPanel, {\n channel: RPC_CHANNEL,\n items: CONFIG_ITEMS,\n title: SLOT_TITLE,\n followKeysOf,\n getCall,\n getService,\n }),\n ),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["S","React","React","S","React","React","React"],"sources":["../../plugin-manager/dist/config-panel-contract.js","../../plugin-manager/dist/config-panel-value.js","../../plugin-manager/dist/directory-browser-contract.js","../../plugin-manager/dist/directory-browser-state.js","../../plugin-manager/dist/directory-browser-parts.js","../../plugin-manager/dist/directory-browser-ui.js","../../plugin-manager/dist/config-panel-view.js","../../plugin-manager/dist/directory-browser-roots.js","../../plugin-manager/dist/update-contract.js","../../plugin-manager/dist/config-panel.js","../src/contract.ts","../src/slot.ts","../src/settings.ts","../src/client.ts"],"sourcesContent":["/** 共用配置面板 · 契约:行表形状、配置面回执、几条两侧共用的常量。\n *\n * 为什么住这里:六个单品插件的设置页各有一份逐字相同的那套代码(卡片骨架/行渲染/样式表/\n * 状态机/配置面三通电话约 3105 行)。本件是抽件之后的**唯一一处定义地**。\n *\n * 本件不认识任何一家能力:行表由调用方给,分支只能由行表数据与配置面回执决定,\n * 里面不出现任何一个能力的名字(结构纪律「依赖方向」)。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\n/** 面板对配置面的三通电话:读整面/保存一份取值/重置为默认。三个名字各家逐字相同,收在这里一处。 */\nexport const RPC_ENDPOINT_CONFIG_GET = 'config.get';\nexport const RPC_ENDPOINT_CONFIG_SAVE = 'config.save';\nexport const RPC_ENDPOINT_CONFIG_RESET = 'config.reset';\n/** 高级组标题(六家逐字相同,收在这里一处)。\n *\n * #934:原先还有一条副文案 `ADVANCED_GROUP_NOTE`(「不常改。留空=用默认值。」),\n * 维护者裁定**整条删除、删后不另找地方说**——理由:三家高级项全是只读行、不参与保存、根本没有\"留空\",\n * 而\"留空会怎样\"这条口径本就逐行住在每条的 `hint` 里(见本件 `ConfigItem.hint` 的契约)。 */\nexport const ADVANCED_GROUP_TITLE = '高级';\n/** 请求超时毫秒:与宿主侧 SPAWN_TIMEOUT_MS 同级,界面永不无限转圈。 */\nexport const READ_TIMEOUT_MS = 20_000;\n/** 复制那一枚按钮就地变「已复制」之后,多久变回「复制」(定稿 v3 第三条:1.5 秒,不弹提示)。 */\nexport const COPY_FEEDBACK_MS = 1500;\n/** 宿主给「这是哪一种目录选择能力」时用的那两格原语的名字(软依赖:按名字现取,缺席即没有入口)。 */\nexport const REMOTE_DIRECTORY_PICKER = 'remote.directoryPicker';\n/** 宿主在「这条路不给」时回的那个码(`directory-browser-state` 的 `openRowBrowser` 只照比不认名)。 */\nexport const DIRECTORY_PICKER_REFUSED = 'directory-picker/unavailable';\n/** 信封守卫:拆包前校验(信封形状的定义地在这里)。 */\nexport function isRpcResult(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return raw.ok === true || raw.ok === false;\n}\n//# sourceMappingURL=config-panel-contract.js.map","/** 共用配置面板 · 取值与填值半:一份配置取值 ↔ 一张表单态,外加脏基线、跟随键、人话报错与三通电话。\n *\n * 本件**不认识 React**,也不认识宿主:喂一份配置面回执与一张行表,它把「页面上每一行该显示什么」\n * 算出来(取值),再把「表单态里哪几格真能改」还原成一份取值(填值)。因此它在 Node 里就能直测。\n *\n * 三条口径(照 #749 起的定稿):\n * · **只读行显示技能算好的绝对值**(回执 `resolved` 组那一格):面板一个字都不算;回执缺那一格\n * (旧技能)就显示空串,绝不编一条路径出来。\n * · **可改行取值空着**时,直接把回执里那个落点绝对路径显示上去——用户不必自己拼路径。\n * · **保存只提交真能改的行**:只读行显示的是绝对路径,把它当配置值写回去就是把「显示」当「配置」。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport { RPC_ENDPOINT_CONFIG_GET, RPC_ENDPOINT_CONFIG_RESET, RPC_ENDPOINT_CONFIG_SAVE, READ_TIMEOUT_MS, isRpcResult, } from './config-panel-contract.js';\n/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */\nexport function readPath(values, key) {\n const parts = key.split('.');\n let cur = values;\n for (const part of parts) {\n if (typeof cur !== 'object' || cur === null || Array.isArray(cur))\n return undefined;\n cur = cur[part];\n }\n return cur;\n}\n/** 按 `a.b` 路径把值写进配置取值(中间层缺就建一层空组;已存在非组即覆盖成组)。 */\nexport function writePath(values, key, value) {\n const parts = key.split('.');\n let cur = values;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n const next = cur[part];\n if (typeof next !== 'object' || next === null || Array.isArray(next))\n cur[part] = {};\n cur = cur[part];\n }\n cur[parts[parts.length - 1]] = value;\n}\n/** 落点来源取一格:先看回执 `resolved` 组同名格,再看回执顶层同名格(两种写法收成同一格)。\n *\n * 顶层那一格为什么只认 `dataDir`:它是**技能算出来的生效数据目录**这个概念的格名,各家的回执\n * 都叫它 `dataDir`;其余落点(照片目录、附件目录等)一律住在 `resolved` 组里。本件不猜别的名字。 */\nfunction prefillValueOf(source, name) {\n const fromResolved = source.resolved?.[name];\n if (typeof fromResolved === 'string' && fromResolved !== '')\n return fromResolved;\n if (name === 'dataDir' && typeof source.dataDir === 'string' && source.dataDir !== '')\n return source.dataDir;\n return undefined;\n}\n/** 只读行显示什么:标了 `resolveFrom` ⇒ 回执 `resolved` 组那一格(技能算好的绝对路径);\n * 没标 ⇒ 配置文件里那个值本身(数字类只读项走这一档:显示的是生效数字)。 */\nfunction readonlyTextOf(item, raw, source) {\n if (item.resolveFrom === undefined)\n return raw;\n const shown = source.resolved?.[item.resolveFrom];\n return typeof shown === 'string' ? shown : '';\n}\n/** 把配置取值铺成「行键 → 控件里的文本」(页面表单态;值缺项即空串,不返空留白)。 */\nexport function toDraft(items, values, source) {\n const draft = {};\n for (const item of items) {\n const v = readPath(values, item.key);\n const raw = v === undefined || v === null ? '' : String(v);\n if (item.readonly === true) {\n draft[item.key] = readonlyTextOf(item, raw, source);\n continue;\n }\n const fallback = item.prefillFrom === undefined ? undefined : prefillValueOf(source, item.prefillFrom);\n draft[item.key] = raw === '' && fallback !== undefined ? fallback : raw;\n }\n return draft;\n}\n/** 表单态 → 配置取值(按控件种类还原类型;空串对文本项照收,语义由「按默认落点」承担)。\n *\n * **只读行不收**:它们显示的是技能算好的绝对路径,写回配置就是把「显示的路径」当成「配置值」——\n * 保存只提交真能改的那些行,其余键由技能侧做组内合并保留现值。 */\nexport function fromDraft(items, draft) {\n const values = {};\n for (const item of items) {\n if (item.readonly === true)\n continue;\n const raw = draft[item.key] ?? '';\n if (item.control === 'number') {\n const n = Number(raw);\n writePath(values, item.key, Number.isFinite(n) ? n : 0);\n }\n else if (item.control === 'switch') {\n writePath(values, item.key, raw === 'true');\n }\n else {\n writePath(values, item.key, raw);\n }\n }\n return values;\n}\n/** 可改行(脏基线只看这一档)。 */\nexport function editableItemsOf(items) {\n return items.filter((item) => item.readonly !== true);\n}\n/** 常用项与高级项按行表自己的分级切开(不再另要一个「常用几行」的数:那是同一件事的第二处定义)。 */\nexport function tiersOf(items) {\n return {\n common: items.filter((item) => item.tier === 'common'),\n advanced: items.filter((item) => item.tier === 'advanced'),\n };\n}\n/** 脏键:表单态里与「刚读到的整面」不一致的**可改行**。\n *\n * 只读行不进来:它们显示的是技能算好的绝对路径,拿它当「改动」会让面板一打开就显示「未保存」。 */\nexport function dirtyKeysOf(items, draft, baseline) {\n return editableItemsOf(items)\n .filter((item) => (draft[item.key] ?? '') !== (baseline[item.key] ?? ''))\n .map((item) => item.key);\n}\n/** 跟随映射的缺省:没有映射就是「一行都不跟随」。 */\nexport function noFollowKeys() {\n return [];\n}\n/* 「写的值 ≠ 生效值」那支黄字已删(#915):面板手上只有「配置里写的」与「技能回执里的默认落点」\n * 两个事实,凭这两个比字符串**判不出**值用不用得了——写的是相对路径、尾分隔符写法不同、大小写不同、\n * 或者(本项目维护者自己的六份配置就是如此)写了一个完全正常、正在用的自定义目录,都会让两个字符串不等。\n * 后果是那行黄字对合法值恒亮,还声称「现在生效的是 <默认落点>」——那是面板替技能侧下的判断,\n * 而技能侧**有意不做隐式回落**(例 `packages/skill-bill/src/fetch/paths.ts:6`:「拒绝隐式写生产」)。\n * 要恢复这一支,事实必须由技能侧给出(布尔 + 故障码 + 报文),面板只画、不比较。 */\n/** 配置面报错 → 人话指引。\n *\n * 报文由技能侧给出(`base-link-core` 的 `ConfigError` 已带行号与文件名,技能 `cli/config.ts`\n * 原样交出,插件 bridge 原样带上),所以这里**不重写报文**,只按报错类补一句「接下来怎么办」。 */\nexport function humanizeConfigFailure(code, message) {\n const text = message.trim().length > 0 ? message.trim() : `(${code},宿主未给报文)`;\n if (/解析|YAML|parse/i.test(text))\n return `${text}\\n改回「键: 值」的写法,或点「重置为默认」。`;\n if (/不认识|未知键|UNKNOWN_KEY/i.test(text))\n return `${text}\\n删掉页面上没有的行,或点「重置为默认」。`;\n if (/类型|TYPE_MISMATCH/i.test(text))\n return `${text}\\n按本页的控件形状填,或点「重置为默认」。`;\n if (/缺席|missing-cli/i.test(text))\n return `${text}\\n技能出口没找到:先确认技能包已装好,再点「重新读取」。`;\n return `${text}\\n改不动就点「重置为默认」,或照上面那条路径手工改配置文件。`;\n}\n/** 有界等待:借平台 `AbortSignal.timeout` 的 abort 事件做**一次**超时拒绝。\n *\n * 为什么不自建定时器:本仓冻结边界是「无数据轮询」,而设置页等的是一次电话回执,不是轮询;\n * 用平台自带的一次性超时既守住边界的本意,也把「不转圈」落到实处。同一个 signal 也交给传输,\n * 双保险:它搭理 signal 就早收工,不理也有这一道兜底(桌面端自研传输会忽略 signal,见 #760)。 */\nfunction withDeadline(promise, ms) {\n const signal = AbortSignal.timeout(ms);\n const limit = new Promise((_, reject) => {\n signal.addEventListener('abort', () => {\n const e = new Error(`配置请求超时(${Math.round(ms / 1000)}s):宿主未回`);\n e.name = 'TimeoutError';\n reject(e);\n }, { once: true });\n });\n return Promise.race([promise, limit]);\n}\n/** 一次配置电话(走调用方给的那条通道,靠端点名分发;永不抛,失败落字)。 */\nasync function configRpc(call, channel, method, payload) {\n if (typeof call !== 'function')\n return { ok: false, message: '宿主连接缺席:connection.rpc.call 不可用' };\n try {\n const raw = await withDeadline(call('/api', channel.replace(/^\\//, ''), { method, payload }, AbortSignal.timeout(READ_TIMEOUT_MS)), READ_TIMEOUT_MS);\n if (!isRpcResult(raw))\n return { ok: false, message: '回执信封异常(非 ok 信封)' };\n if (!raw.ok) {\n return { ok: false, message: humanizeConfigFailure(raw.error?.code ?? 'unknown', raw.error?.message ?? '') };\n }\n return { ok: true, surface: raw.value };\n }\n catch (e) {\n if (e instanceof Error && (e.name === 'AbortError' || e.name === 'TimeoutError')) {\n return { ok: false, message: `配置请求超时(${Math.round(READ_TIMEOUT_MS / 1000)}s):宿主未回` };\n }\n return { ok: false, message: `配置失败:${e instanceof Error ? e.message : String(e)}` };\n }\n}\n/** 读设置页整面。 */\nexport function fetchConfigSurface(call, channel) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_GET, {});\n}\n/** 保存一份取值(回执只有 `{path, values}`,**不是**整面:写完要重新读一份整面)。 */\nexport function saveConfigSurface(call, channel, values) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_SAVE, { values });\n}\n/** 重置为默认(技能侧先落一份备份;回执同样不是整面,写完要重新读一份整面)。 */\nexport function resetConfigSurface(call, channel) {\n return configRpc(call, channel, RPC_ENDPOINT_CONFIG_RESET, {});\n}\n//# sourceMappingURL=config-panel-value.js.map","/** 目录浏览器的纯逻辑半(**不认识宿主**:只认两格原语)。\n *\n * 为什么在这里:六个单品插件的设置页各有一批「值是一个目录」的行,它们要的界面是同一个东西。\n * 界面的**取数**来自宿主给的两个原语(`list`/`createDirectory`),而这两个原语的形状是**调用方喂进来的**\n * ——本件不 import 宿主的任何实现,也不认识 `remote.directoryPicker` 这个名字(那两件住在各家的\n * `dsh-ctx.ts` 镜像里)。于是本件在 Windows 桌面、远程浏览器、SSH 三种部署下是同一份代码。\n *\n * 装什么:本次要浏览的那一层怎么走(进子目录/回上一级/跳面包屑)、路径怎么切出「目录部分」与\n * 「筛选词」、回执怎么认。**不装**任何 IO、不装任何持久化——`list`/`createDirectory` 由调用方执行。\n *\n * 与平台自带浏览器件的关系:`@deepseek-ai/dsh-client-ui-directory-picker-browse` 的 `DirectoryBrowser`\n * 是包内私有件(只经 `ui-workspace` 的流程空位暴露),插件侧取不到,所以这里是一份独立实现,\n * 只对齐它的**交互结果**(进/选/新建),不对齐它的 DOM。\n */\n/** 认一认某个值是不是可用的目录取数面(软依赖守卫用:认不出就当没有,绝不把页面带下来)。 */\nexport function isBrowseFace(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n const face = raw;\n return typeof face.list === 'function' && typeof face.createDirectory === 'function';\n}\n/** 认一认某个值有没有 `pick`(对应宿主 composition 里的 `native` 能力)。 */\nexport function hasPickFn(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return typeof raw.pick === 'function';\n}\n/** 三态判定:**先看两格浏览原语**(都在=应用内浏览器这条路在),再看单独的 `pick`,都没有=`none`。\n *\n * 为什么浏览优先:客户端命名空间上三条动词一定都在(由 `TYPERT_REMOTE.descriptors` 生成,\n * 与组合里服务哪种能力无关),所以两格原语在=这台宿主**可能**给浏览;真调一次才知道给不给,\n * 不给({@link CAPABILITY_REFUSED})再由调用方换系统对话框。反过来先认 `pick` 就会在\n * Desktop 这种「只服务 browse」的宿主上每次都去唤一次系统对话框、被拒一次(#744 实测)。 */\nexport function pickerModeOf(raw) {\n if (isBrowseFace(raw))\n return 'browse';\n return hasPickFn(raw) ? 'native' : 'none';\n}\n/** 平台回执 → 三态(**永不抛**):成功回的是信封里的 `value` 不是路径;`ok:false` 是「供不了」不是「取消」。\n *\n * 出处:`@deepseek-ai/dsh-api-gateway/lib/client.js` 的 `invoke()`(失败不抛、成功也不回裸值),\n * 第一方消费方 `@deepseek-ai/dsh-client-ui-workspace/lib/client.js:99-103` 就照这个信封拆。\n * 裸串照收(老形状兜底),认不出的形状当「供不了」报出来,不当取消吞掉(#743 的教训)。 */\nexport function readPickAnswer(raw) {\n if (typeof raw === 'string')\n return raw.trim() === '' ? { kind: 'cancelled' } : { kind: 'picked', path: raw };\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok === true) {\n const value = answer.value;\n return typeof value === 'string' && value.trim() !== '' ? { kind: 'picked', path: value } : { kind: 'cancelled' };\n }\n const detail = answer.error?.message?.trim() ?? '';\n const code = answer.error?.code;\n return {\n kind: 'unavailable',\n ...(typeof code === 'string' && code !== '' ? { code } : {}),\n message: '打不开系统文件夹对话框' + (detail === '' ? '' : '(' + detail + ')') + ':请直接在框里填绝对路径。',\n };\n}\n/** 取数原语失败:带上宿主给的回执码,好让调用方分辨「没这条路」与「这一层读不出来」。\n *\n * `code` 就是 `humanize`(状态那半)读的那一格,人话直接上图。 */\nexport class BrowseAnswerError extends Error {\n code;\n constructor(code, message) {\n super(message);\n this.name = 'BrowseAnswerError';\n this.code = code;\n }\n}\n/** 宿主 browse 原语的**信封** → 值,或按信封里的 `error` 抛。\n *\n * 为什么必须走这一道:`list`/`createDirectory` 与 `pick` 一样是 Remote 动词,客户端拿到的是\n * `{ok:true,value}`/`{ok:false,error}`(`@deepseek-ai/dsh-api-gateway/lib/client.js` 的 `invoke()`)。\n * 把信封当值用,图上就会是一层「读出来了但一行都没有」的空目录(#744 实测),\n * 而不是报错——所以宁可在这里抛,也不许把它当列举结果传下去。\n * 第一方消费方同口径:`@deepseek-ai/dsh-client-ui-workspace/lib/client.js:105-113` 也是这么拆的。 */\nexport function readBrowseAnswer(raw, what) {\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok === true && answer.value !== undefined && answer.value !== null)\n return answer.value;\n const detail = answer.error?.message?.trim() ?? '';\n const code = answer.error?.code;\n throw new BrowseAnswerError(typeof code === 'string' && code !== '' ? code : 'browse-failed', detail === '' ? what + '没有回执' : detail);\n}\n/** 宿主命名空间 → 本件的取数面:把两条原语的信封拆开,成功给值、失败按码抛。\n *\n * 命名空间上两格原语不在就回 null(调用方据此不画入口)。**透传参数个数照宿主的规矩**:\n * 描述符声明了可选 `AbortSignal`(`cancellation: {parameter:'signal'}`),而客户端按\n * `values.length === 业务参数个数 + 1` 判有没有 signal——显式传一个 `undefined` 会被当成 signal\n * 去 `AbortSignal.any([…, undefined])` 而炸。本件的界面不做取消,故**从不传 signal**。 */\nexport function browseFaceOf(raw) {\n if (!isBrowseFace(raw))\n return null;\n const namespace = raw;\n return {\n list: async (path) => readBrowseAnswer(path === undefined ? await namespace.list() : await namespace.list(path), '列举目录'),\n createDirectory: async (path, name) => readBrowseAnswer(await namespace.createDirectory(path, name), '新建文件夹'),\n };\n}\n/** 一段路径里最后那个分隔符的位置(Windows 上 `\\` 与 `/` 都算;POSIX 上 `\\` 是合法文件名字符,不算)。 */\nfunction lastSeparator(path) {\n const back = path.lastIndexOf('\\\\');\n const slash = path.lastIndexOf('/');\n // 只含 `\\` 的路径按 Windows 规则解;两者都有时取更靠后的那个。\n return back > slash ? back : slash;\n}\n/** 上一层:`'C:\\\\a\\\\b\\\\'` → `'C:\\\\a'`;已经是根则回自身;相对名(没有任何分隔符)也回自身。\n *\n * 尾分隔符先吃掉再切——否则「回上一级」会在原地打转。**盘根单独认**:`C:\\` 掐掉尾分隔符会剩成\n * `C:`,而 `C:` 是「当前盘」不是「上一层」,回它就会多跑一趟、还可能跨到别的盘上去。\n * UNC(`\\\\server\\share`)不特殊处理:切到头就是共享名本身,浏览停在共享根。 */\nexport function parentOf(path) {\n const trimmed = path.replace(/[\\\\/]+$/, '');\n if (trimmed === '')\n return path;\n const sep = path.includes('\\\\') ? '\\\\' : '/';\n if (/^[A-Za-z]:$/.test(trimmed))\n return trimmed + sep;\n const cut = lastSeparator(trimmed);\n if (cut === -1)\n return trimmed;\n if (cut === 0)\n return path.slice(0, 1);\n if (cut === 2 && /^[A-Za-z]:/.test(trimmed))\n return trimmed.slice(0, 2) + sep;\n return trimmed.slice(0, cut);\n}\n/** 把「当前路径 + 一段输入」拼成一个目标路径。 */\nexport function joinPath(directory, name) {\n const sep = directory.includes('\\\\') ? '\\\\' : '/';\n const base = directory.replace(/[\\\\/]+$/, '');\n if (base === '')\n return sep + name;\n return base + sep + name;\n}\n/** 一层列举里,哪些行可进:隐藏目录按开关过滤,其余照宿主给的顺序。 */\nexport function visibleEntries(listing, showHidden) {\n return showHidden ? listing.entries : listing.entries.filter((entry) => !entry.hidden);\n}\n/** 这一层有多少个被藏起来的目录(用来决定「显示隐藏目录」那个开关要不要出现在图上)。 */\nexport function hiddenCount(listing) {\n return listing.entries.filter((entry) => entry.hidden).length;\n}\n/** 拿一段文本按「最后一个分隔符」切成「目录部分 + 筛选词」。\n *\n * 没打过任何分隔符时目录部分=null(那段文字还不指任何目录,只当筛选词用)。\n * Windows 上 `/` 也当分隔符(宿主那边两种都收),POSIX 上不。 */\nexport function splitDraft(draft) {\n const cut = lastSeparator(draft);\n if (cut === -1)\n return { directory: null, filter: draft };\n return { directory: draft.slice(0, cut + 1), filter: draft.slice(cut + 1) };\n}\n/** 按筛选词过一层目录(大小写不敏感;空筛选词=全留)。 */\nexport function filterEntries(entries, filter) {\n const needle = filter.trim().toLowerCase();\n if (needle === '')\n return entries;\n return entries.filter((entry) => entry.name.toLowerCase().includes(needle));\n}\n/** 新建文件夹的名字合不合法(单个路径段:不许分隔符、不许空、不许 `.`/`..`)。\n *\n * 与宿主 browse 后端的校验同口径——这里先拦一道,是为了在图上给得出人话,不是替代宿主校验。 */\nexport function validateFolderName(name) {\n const trimmed = name.trim();\n if (trimmed === '')\n return { ok: false, reason: '文件夹名不能为空。' };\n if (/[\\\\/]/.test(trimmed))\n return { ok: false, reason: '文件夹名里不能带路径分隔符。' };\n if (trimmed === '.' || trimmed === '..')\n return { ok: false, reason: '「.」与「..」不是文件夹名。' };\n return { ok: true };\n}\n//# sourceMappingURL=directory-browser-contract.js.map","/** 文件浏览器的操作半:把「进哪一层、这一层显示什么、选到了什么」算成状态,**IO 全部由调用方注入**。\n *\n * 分两层的原因:本件(操作)在 Node 里就能直测——喂一个假的取数面,就能把「进目录/回上一级/\n * 跳面包屑/筛选/新建文件夹/失败出人话」全跑一遍;视图那半(`directory-browser-ui.ts`)\n * 只负责把这份状态画成 DOM。两边都不认识宿主。\n *\n * 数据来源只有两格:`list(path?)` 与 `createDirectory(path, name)`(调用方注入的 `DirectoryBrowseFace`)。\n */\nimport { browseFaceOf, filterEntries, joinPath, parentOf, splitDraft, validateFolderName, visibleEntries, } from './directory-browser-contract.js';\n/** 建一个浏览器控制器。取数、回调、初值全部由调用方给。 */\nexport function createBrowseController(deps) {\n const label = deps.failureLabel ?? '浏览失败';\n const listeners = new Set();\n let state = {\n phase: 'idle',\n listing: null,\n failure: null,\n selected: null,\n showHidden: false,\n draft: deps.initialPath,\n filter: '',\n creating: null,\n notice: null,\n roots: [],\n };\n /** 每次列举带一个序号:晚回来的旧回执直接丢掉,不许覆盖新一层。 */\n let generation = 0;\n const emit = (next) => {\n state = { ...state, ...next };\n for (const listener of [...listeners])\n listener(state);\n };\n /** 根清单只问一次:取不到就是空(不报错、不重试——它只是图上的一行入口)。\n *\n * 「问一次」钉在这里而不是图里:视图那半每次重画都会重新求值,问在这里才谈得上一次。 */\n let rootsAsked = false;\n const loadRoots = async () => {\n if (rootsAsked || deps.rootsSource === undefined)\n return;\n rootsAsked = true;\n try {\n const roots = await deps.rootsSource();\n if (roots.length > 0)\n emit({ roots });\n }\n catch {\n /* 取不到就当没有这一行:浏览本身照常。 */\n }\n };\n const humanize = (cause) => {\n const raw = (typeof cause === 'object' && cause !== null ? cause : {});\n const message = typeof raw.message === 'string' && raw.message.trim() !== '' ? raw.message.trim() : String(cause);\n const code = typeof raw.code === 'string' && raw.code !== '' ? raw.code : 'browse-failed';\n return { code, message: `${label}:${message}` };\n };\n const load = async (path) => {\n const mine = ++generation;\n emit({ phase: 'loading', failure: null, notice: null });\n try {\n const listing = path === null ? await deps.face.list() : await deps.face.list(path);\n if (mine !== generation)\n return;\n emit({\n phase: 'ready',\n listing,\n failure: null,\n selected: null,\n draft: listing.path,\n filter: '',\n });\n }\n catch (cause) {\n if (mine !== generation)\n return;\n emit({ phase: 'failed', listing: null, failure: humanize(cause), selected: null });\n }\n };\n /** 草稿指到的那一层已经列举过时,按末段筛当前这一层的行;否则不过滤。\n *\n * 两边都先掐掉尾分隔符再比:草稿那边切开后天然带尾分隔符(`C:\\a\\` + `b`),\n * 而这一层的 `path` 由宿主给、不带尾分隔符。 */\n const applyDraft = (draft) => {\n const { directory, filter } = splitDraft(draft);\n const listing = state.listing;\n const sameLevel = listing !== null && directory !== null && normalize(directory) === normalize(listing.path);\n emit({ draft, filter: sameLevel ? filter : '' });\n };\n const normalize = (path) => path.replace(/[\\\\/]+$/, '');\n return {\n getState: () => state,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n async open() {\n // 根清单一并去问,但**不等它**:它只是图上的一行入口,落定了自会推一次重画;\n // 等它就等于让「宿主那台机器列盘符快不快」决定对话框什么时候开。\n void loadRoots();\n const wanted = deps.initialPath.trim();\n if (wanted !== '') {\n await load(wanted);\n if (state.phase === 'ready')\n return state;\n }\n await load(null);\n return state;\n },\n enter: (path) => load(path),\n async up() {\n const listing = state.listing;\n if (listing === null)\n return;\n const parent = parentOf(listing.path);\n if (parent === listing.path)\n return;\n await load(parent);\n },\n pick() {\n const target = state.selected ?? state.listing?.path ?? null;\n if (target === null)\n return;\n deps.onPicked(target);\n },\n cancel() {\n deps.onClose();\n },\n close() {\n deps.onClose();\n },\n select(path) {\n emit({ selected: state.selected === path ? null : path, notice: null });\n },\n toggleHidden() {\n emit({ showHidden: !state.showHidden });\n },\n setDraft(draft) {\n applyDraft(draft);\n },\n async commitDraft() {\n const trimmed = state.draft.trim();\n if (trimmed === '')\n return;\n await load(trimmed);\n },\n setCreating(name) {\n emit({ creating: name, notice: null });\n },\n async createFolder(name) {\n const checked = validateFolderName(name);\n if (!checked.ok) {\n emit({ notice: checked.reason });\n return;\n }\n const base = state.selected ?? state.listing?.path ?? null;\n if (base === null) {\n emit({ notice: '还没有打开任何目录,无法新建文件夹。' });\n return;\n }\n try {\n const created = await deps.face.createDirectory(base, name.trim());\n emit({ creating: null, notice: null });\n await load(created);\n emit({ selected: created });\n }\n catch (cause) {\n const failure = humanize(cause);\n emit({ notice: failure.message, creating: null });\n }\n },\n };\n}\n/** 图上这一层要画的行(按隐藏开关与草稿末段过滤之后的)。 */\nexport function rowsOf(state) {\n if (state.listing === null)\n return [];\n return filterEntries(visibleEntries(state.listing, state.showHidden), state.filter);\n}\n/** 图上这一层能不能回上一级(根目录不能)。 */\nexport function canGoUp(state) {\n if (state.listing === null)\n return false;\n return parentOf(state.listing.path) !== state.listing.path;\n}\n/** 「打开」这颗按钮的目标:选中行优先,没选中就是当前层。 */\nexport function targetOf(state) {\n return state.selected ?? state.listing?.path ?? null;\n}\n/** 新建文件夹那一行要展示的位置(\"在 <这里> 下新建\")。 */\nexport function createBaseOf(state) {\n return state.selected ?? state.listing?.path ?? null;\n}\n/** 一段路径拼成可读的一句话(给用例与调试用;图上不直接显示)。 */\nexport function describe(state) {\n if (state.phase === 'failed')\n return `${state.failure?.code ?? 'browse-failed'} @ ${state.draft}`;\n if (state.listing === null)\n return `${state.phase}`;\n return `${state.listing.path}(${rowsOf(state).length} 行)`;\n}\n/** 一行子目录的完整路径(图上点行时用)。 */\nexport function entryPath(directory, entry) {\n return entry.path === '' ? joinPath(directory, entry.name) : entry.path;\n}\n/** 建一份「目录行接线」:给一个取数面与初值,回一组动作。\n *\n * 只做接线:把控制器算出来的状态与回调打包好,不取数、不画图、不认宿主。 */\nexport function createDirectoryRowBrowser(deps) {\n const controller = createBrowseController({\n face: deps.face,\n initialPath: deps.initialPath,\n onPicked: deps.onPicked,\n onClose: () => deps.onClosed?.(),\n ...(deps.failureLabel === undefined ? {} : { failureLabel: deps.failureLabel }),\n ...(deps.rootsSource === undefined ? {} : { rootsSource: deps.rootsSource }),\n });\n return {\n open: () => controller.open(),\n subscribe: (listener) => controller.subscribe(listener),\n state: () => controller.getState(),\n summary: () => describe(controller.getState()),\n actions: {\n onPick: () => controller.pick(),\n onClose: () => controller.cancel(),\n onEnter: (path) => void controller.enter(path),\n onUp: () => void controller.up(),\n onSelect: (path) => controller.select(path),\n onToggleHidden: () => controller.toggleHidden(),\n onDraft: (draft) => controller.setDraft(draft),\n onCommitDraft: () => void controller.commitDraft(),\n onCreate: (name) => void controller.createFolder(name),\n onCreatingChange: (name) => controller.setCreating(name),\n },\n };\n}\n/** 一条目录行点下去该走哪条路(**六家共用这一处策略**,单独写在各家就会各错各的)。\n *\n * 顺序是「先应用内浏览,被拒再换系统对话框」,因为客户端命名空间上三条动词都在、问不出组合里服务哪种\n * 能力(见 `pickerModeOf`)。回执:\n * - `undefined`=连两格浏览原语都没有(这条路没有,调用方自己想办法);\n * - `'refused'`=宿主回了 `refusalCode`(组合里是系统对话框),图已收起;\n * - `'open'`=图开着,后面的事都在图里。\n *\n * **状态由调用方持有**:`onRow` 收到刚建好的那条(或 null=收起),React 那边据此决定画不画图。\n *\n * `refusalCode` 是**宿主的回执码**(各家自己从宿主镜像里拿,本件只照比不认名):\n * 它换名字本件照样跑,六家一起换。 */\nexport function openRowBrowser(input) {\n const face = browseFaceOf(input.picker);\n if (face === null)\n return undefined;\n const row = createDirectoryRowBrowser({\n face,\n initialPath: input.initialPath,\n onPicked: (picked) => {\n input.onChange(picked);\n input.onRow(null);\n },\n onClosed: () => input.onRow(null),\n ...(input.rootsSource === undefined ? {} : { rootsSource: input.rootsSource }),\n });\n input.onRow(row);\n return row.open().then((settled) => {\n if (settled.phase === 'failed' && settled.failure?.code === input.refusalCode) {\n input.onRow(null);\n return 'refused';\n }\n return 'open';\n });\n}\n//# sourceMappingURL=directory-browser-state.js.map","/** 文件浏览器视图半的**零件**:样式表与四行控件(面包屑/根/一行子目录/新建行)。\n *\n * 为什么拆出来:整张对话框的组版与这些零件的变化频率不同——零件跟着「图上多一行/少一行」动,\n * 组版跟着「对话框长什么样」动。拆开之后两边都在 350 行告警线内,而对外面不变\n * (`directory-browser-ui.ts` 照旧转出组件与两个接线函数)。\n *\n * 本件与视图半同样**不认识宿主**:只认状态与文案。\n */\nimport * as React from 'react';\n/** 根的类型说明(悬停可见):**本件自己的词汇**,与取数方无关。 */\nconst ROOT_KIND_TEXT = {\n fixed: '固定磁盘',\n network: '网络驱动器',\n removable: '可移动磁盘',\n optical: '光驱',\n other: '磁盘',\n};\nexport const S = {\n scrim: {\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.35)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 9999,\n },\n dialog: {\n width: 680,\n maxWidth: '92vw',\n height: 500,\n maxHeight: '86vh',\n display: 'flex',\n flexDirection: 'column',\n background: 'var(--dsw-alias-bg-layer-1, #1f1f23)',\n color: 'var(--dsw-alias-label-primary, inherit)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 10,\n boxShadow: '0 12px 32px rgba(0,0,0,0.35)',\n overflow: 'hidden',\n },\n head: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 12px',\n borderBottom: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n },\n title: { fontSize: 14, fontWeight: 700 },\n crumbs: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 2, padding: '8px 12px 0', fontSize: 12 },\n chromeButton: {\n background: 'transparent',\n border: 'none',\n color: 'var(--dsw-alias-label-primary, inherit)',\n cursor: 'pointer',\n padding: '2px 4px',\n fontSize: 12,\n opacity: 0.85,\n },\n crumbSep: { opacity: 0.45, fontSize: 12 },\n roots: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 6, padding: '0 12px 8px', fontSize: 12 },\n rootButton: {\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n padding: '3px 8px',\n opacity: 1,\n },\n pathRow: { display: 'flex', gap: 6, padding: '8px 12px' },\n input: {\n flex: 1,\n minWidth: 0,\n fontSize: 12,\n padding: '5px 8px',\n background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.12))',\n color: 'inherit',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n },\n button: {\n fontSize: 12,\n padding: '5px 10px',\n cursor: 'pointer',\n background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.12))',\n color: 'inherit',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.35))',\n borderRadius: 6,\n },\n buttonOff: { opacity: 0.45, cursor: 'default' },\n list: {\n flex: 1,\n minHeight: 0,\n overflowY: 'auto',\n margin: '0 12px',\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n borderRadius: 6,\n },\n row: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n width: '100%',\n padding: '6px 10px',\n textAlign: 'left',\n background: 'transparent',\n color: 'inherit',\n border: 'none',\n borderBottom: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.12))',\n cursor: 'pointer',\n fontSize: 13,\n },\n rowSelected: { background: 'var(--dsw-alias-bg-layer-2, rgba(128,128,128,0.18))' },\n empty: { padding: '14px 12px', fontSize: 12, opacity: 0.7 },\n footNote: { padding: '6px 12px 0', fontSize: 12, minHeight: 20 },\n foot: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '10px 12px',\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))',\n },\n target: { marginRight: 'auto', fontSize: 12, opacity: 0.8, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n error: { color: 'var(--dsw-alias-state-error-primary, #e66)' },\n};\n/** 面包屑:从文件系统根到当前层,每一格都是跳转目标(`listing.crumbs` 由取数方给)。 */\nexport function crumbRow(state, onEnter) {\n const listing = state.listing;\n if (listing === null || listing.crumbs.length === 0)\n return null;\n const parts = [];\n listing.crumbs.forEach((crumb, index) => {\n if (index > 0)\n parts.push(React.createElement('span', { key: 'sep-' + crumb.path, style: S.crumbSep }, '›'));\n const isCurrent = crumb.path === listing.path;\n parts.push(React.createElement('button', {\n key: crumb.path,\n type: 'button',\n style: { ...S.chromeButton, fontWeight: isCurrent ? 700 : 400 },\n title: crumb.path,\n onClick: () => onEnter(crumb.path),\n }, \n // 每一格都写**它自己那一层的名字**:第一格是文件系统根(`C:\\`),不是「上一级」——\n // 「上一级」是路径行那颗按钮的活(#744 返修:这一格原先串了那颗按钮的文案)。\n crumb.name));\n });\n return React.createElement('div', { style: S.crumbs }, parts);\n}\n/** 可跳转的根那一行(Windows 上的盘符等):**就是本机全部磁盘**,故不加行首说明。\n * **少于两个根就不画**:一个根没有「跳到别处」可言。 */\nexport function rootsRow(state, onEnter) {\n if (state.roots.length < 2)\n return null;\n const parts = state.roots.map((root) => React.createElement('button', {\n key: root.path,\n type: 'button',\n style: { ...S.chromeButton, ...S.rootButton },\n title: ROOT_KIND_TEXT[root.kind] ?? ROOT_KIND_TEXT.other,\n onClick: () => onEnter(root.path),\n }, root.path));\n return React.createElement('div', { style: S.roots }, parts);\n}\n/** 一行子目录:点名字进它,点「选」把它当目标(「选」再点一次取消)。 */\nexport function entryRow(entry, selected, labels, onToggleSelect, onEnter) {\n return React.createElement('div', { key: entry.path, style: { ...S.row, padding: 0, ...(selected ? S.rowSelected : {}) } }, React.createElement('button', { type: 'button', style: { ...S.row, flex: 1, border: 'none' }, onClick: () => onEnter(entry.path) }, '📁 ' + entry.name), React.createElement('button', {\n type: 'button',\n style: { ...S.button, marginRight: 8, padding: '2px 8px' },\n 'aria-pressed': selected,\n title: selected ? labels.selected : labels.select,\n onClick: () => onToggleSelect(entry.path),\n }, selected ? '✓' : labels.select));\n}\n/** 「新建文件夹」那一行(`creatingName === null` 时收起)。 */\nexport function createRow(labels, onName, onCancel, onCreate, creatingName) {\n if (creatingName === null)\n return null;\n return React.createElement('div', { style: { ...S.pathRow, borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.25))' } }, React.createElement('input', {\n style: S.input,\n value: creatingName,\n placeholder: labels.newFolder,\n 'aria-label': labels.newFolder,\n onChange: (event) => onName(event.currentTarget.value),\n onKeyDown: (event) => {\n if (event.key === 'Enter')\n onCreate(creatingName);\n if (event.key === 'Escape')\n onCancel();\n },\n }), React.createElement('button', { type: 'button', style: S.button, onClick: () => onCreate(creatingName) }, labels.createConfirm), React.createElement('button', { type: 'button', style: S.button, onClick: onCancel }, labels.createCancel));\n}\n//# sourceMappingURL=directory-browser-parts.js.map","/** 文件浏览器的视图半:把 `BrowseState` 画成一张对话框。**不认识宿主**,也不自己做 IO。\n *\n * 手写 `React.createElement`(本包 client 束禁 JSX,见 `tsdown.config.ts` 的既成口径)。\n * 只读状态、只回调;进哪一层、选到什么由操作半(`directory-browser-state.ts`)算。\n * 样式与四行控件在 `directory-browser-parts.ts`(那里跟着「多一行/少一行」动,本件只管组版)。\n */\nimport * as React from 'react';\nimport { rowsOf, targetOf } from './directory-browser-state.js';\nimport { hiddenCount } from './directory-browser-contract.js';\nimport { S, createRow, crumbRow, entryRow, rootsRow } from './directory-browser-parts.js';\nconst EMPTY_LISTING = { path: '', home: '', crumbs: [], entries: [], truncated: false };\n/** 画一张文件浏览器对话框。`open=false` 时返回 null(本件不挂 portal,由调用方决定挂在哪)。 */\nexport function DirectoryBrowser(props) {\n const { open, state, labels } = props;\n if (!open)\n return null;\n const rows = rowsOf(state);\n const target = targetOf(state);\n const listing = state.listing ?? EMPTY_LISTING;\n const hidden = hiddenCount(listing);\n const body = [];\n body.push(crumbRow(state, props.onEnter));\n body.push(rootsRow(state, props.onEnter));\n body.push(React.createElement('div', { style: S.pathRow }, React.createElement('input', {\n style: S.input,\n value: state.draft,\n placeholder: labels.pathPlaceholder,\n 'aria-label': labels.pathPlaceholder,\n onChange: (event) => props.onDraft(event.currentTarget.value),\n onKeyDown: (event) => {\n if (event.key === 'Enter')\n props.onCommitDraft();\n },\n }), React.createElement('button', { type: 'button', style: S.button, onClick: props.onUp }, labels.up), React.createElement('button', { type: 'button', style: S.button, onClick: props.onCommitDraft }, labels.go)));\n body.push(React.createElement('div', { style: S.list, role: 'listbox', 'aria-label': labels.title }, rows.length === 0\n ? React.createElement('div', { style: S.empty }, state.phase === 'loading' ? labels.loading : labels.empty)\n : rows.map((entry) => entryRow(entry, state.selected === entry.path, labels, props.onSelect, props.onEnter))));\n body.push(createRow(labels, props.onDraft, () => props.onCreatingChange(null), props.onCreate, state.creating));\n body.push(React.createElement('div', { style: S.footNote }, hidden > 0\n ? React.createElement('label', { style: { fontSize: 12, cursor: 'pointer', marginRight: 10 } }, React.createElement('input', { type: 'checkbox', checked: state.showHidden, onChange: props.onToggleHidden }), ' ' + labels.showHidden(hidden))\n : null, state.creating === null\n ? React.createElement('button', { type: 'button', style: { ...S.chromeButton, textDecoration: 'underline' }, onClick: () => props.onCreatingChange('') }, labels.newFolder)\n : null, state.notice !== null ? React.createElement('div', { style: S.error }, state.notice) : null, state.phase === 'failed' && state.failure !== null\n ? React.createElement('div', { style: S.error }, state.failure.message)\n : null));\n body.push(React.createElement('div', { style: S.foot }, React.createElement('span', { style: S.target, title: target ?? '' }, target === null ? '' : labels.willPick + target), React.createElement('button', { type: 'button', style: { ...S.button, ...(target === null ? S.buttonOff : {}) }, onClick: props.onPick }, labels.open), React.createElement('button', { type: 'button', style: S.button, onClick: props.onClose }, labels.cancel)));\n return React.createElement('div', {\n style: S.scrim,\n role: 'presentation',\n onMouseDown: (event) => {\n if (event.target === event.currentTarget)\n props.onClose();\n },\n }, React.createElement('div', { style: S.dialog, role: 'dialog', 'aria-modal': true, 'aria-label': labels.title }, React.createElement('div', { style: S.head }, React.createElement('span', { style: S.title }, labels.title), \n // 标题右侧**不再重复当前路径**:同一条路径下面已经出现两次(面包屑与路径框),\n // 而盘符那行也要地方——头一行越干净越好(#744 第三轮现场反馈)。\n React.createElement('button', { type: 'button', style: { ...S.button, marginLeft: 'auto' }, 'aria-label': labels.close, title: labels.close, onClick: props.onClose }, '✕')), body));\n}\n/** 目录行接线的 React 半边:把操作半那组动作直接喂给组件。\n *\n * 操作半(`directory-browser-state.ts` 的 `createDirectoryRowBrowser`)不碰 React,\n * 这里只把它的 `actions` 摊进 props —— 于是「进哪一层」那套在 Node 里可测,这里只做接线。\n *\n * `useSyncExternalStore` 是**必需**的:列举是异步落定的,不订阅的话这一帧画完就再没有重画,\n * 图上会永远停在「正在读取…」(#744 实测)。 */\nexport function DirectoryBrowserFromRow(props) {\n const state = React.useSyncExternalStore(props.row.subscribe, props.row.state);\n return DirectoryBrowser({\n open: props.open,\n state,\n labels: props.labels,\n ...props.row.actions,\n });\n}\nexport { createBrowseController, createDirectoryRowBrowser, describe, rowsOf, targetOf } from './directory-browser-state.js';\n//# sourceMappingURL=directory-browser-ui.js.map","/** 共用配置面板 · 视图半:一行怎么画(`Row`)、整面怎么画(`PanelBody`)。\n *\n * 本件是**纯函数**:吃一份状态与一组回调,回一棵 React 元素树,自己不留任何状态、不取任何数。\n * 为什么这么分:状态机与副作用住在 `config-panel.ts` 那一层,于是本件在 Node 里就能直测\n * (照 `directory-browser-ui.ts` 的既有作法:用例把组件当普通函数调,直接读回那棵树)。\n *\n * 手写 `React.createElement`(本包 client 束禁 JSX)。样式表 `S` 就在本件里——面板怎么画只有这一处。\n *\n * **外观真源=`docs/agents/配置区域视觉模型-v3.1.html`(#920 阶段二起)**:本件的 `S` 逐项照它的\n * CSS(`:32-205`)、行模板照它的 `rowShell`/`masterShell`/`cardShell`(`:349-451`)、状态徽标照它的\n * `badgeHTML`(`:544-552`)那七档。**颜色/间距/圆角/字号/层级一律照取值,不许自己重新设计**;\n * 与本件不同的只有下面这四条(每条都在这里写明为什么,改之前先读 #920 的证据件):\n * ① **字号一律 em,没有 px**:跨包锁 `test/panel-type-739.test.mjs` 钉死「零 `font:` 简写/零字族/\n * 字号一律相对单位」——宿主没有界面字号 token,绝对 px 会在别的窗口尺寸上失真。v3.1 的 px 按它\n * 自己已锁死的那两对锚点换算(`13.5px↔1.08em`、`11.5px↔0.92em` ⇒ **1px=0.08em**),一个不丢。\n * ② **值列不写等宽字族**:v3.1 的值列要 `font-family: var(--ic-mono)`,而 `#739 ①` 明令共用件零\n * `fontFamily`/零 `font:` 简写 ⇒ 值继承宿主字族。这是与 v3.1 的**一处已知不同**(#920 证据件有账)。\n * ③ **换行判据交给 CSS,不按字符数估宽**:v3.1 靠 JS 量文本宽在两套模板间两选一(审查 P0-4/P0-5:\n * 每列 6.048px、真阈值 40–43 列而注释按 34 估 ⇒ 9 行被无谓拆两行、快面一次性长高 194px)。\n * 本件没有 DOM 可量,故照审查给的修法把同一个决定交给排版引擎:行是 `flex-wrap` 容器,标签列定宽、\n * 值列 `flex-basis:auto`(=内容的自然宽)——装不下时**整行让位**(值落第二行、按钮仍在第一行行尾,\n * 与 v3.1 的 `.is-wide` 同形);值再长就在自己那一行里 `overflow-wrap:anywhere` 折下去。\n * **零省略号、零截断**(`white-space` 不用 `nowrap`、`text-overflow` 一次都不出现)。\n * ④ **画不出来的三样**用等价形态顶上:分组箭头 `::before`/`[open]` 旋转/keyframes 动画内联样式\n * 给不出 ⇒ 画静态「›」与静态环(形状与 v3.1 同,只少了动)。\n *\n * 三条定稿(v3)在本件落地:\n * ① **只读行的目录按钮不画**(不画一枚点了也没反应的死按钮);\n * ② 目录行的按钮字面**两档合一**,一律「浏览文件夹」(入口供不了时整枚不画);\n * ③ **每行一枚「复制」**:复制这一行完好的值文本;点下去按钮就地变「已复制」再变回,不弹提示。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport * as React from 'react';\nimport { ADVANCED_GROUP_TITLE } from './config-panel-contract.js';\nimport { DirectoryBrowserFromRow } from './directory-browser-ui.js';\n/** 面板的样式表:取值逐项照 v3.1(颜色走 DSH 主题别名,写死值只做回退;字号一律相对单位 em)。\n *\n * 键名一个都不许改:六家附加块真消费 `okText`/`error`/`rows`/`label`/`muted`/`hint`/`info`/\n * `bar`/`btn` 这九格(`plugin-memo-ilife/src/client.ts`、`plugin-schedule-ilife/src/client.ts` 的\n * `PanelStyleSlots`),跨包锁另钉 `card`/`input`/`btnPrimary`/`btnPick`/`summary`/`title`/`version`。 */\n/** #941/丁:**浅色档距自合成**——宿主在浅色下四层底同白(`bg-base = bg-layer-1/2/3`),\n * 拿不到可用的层级差,所以三处面(卡描边/沉底盒底/输入框描边)由我们自己按墨色派生。\n *\n * 取 `label-primary` 当墨色分母:浅色下它是近黑、深色下它是近白 ⇒ **同一条表达式两套主题都成立**\n * (浅色补出可用的档距,深色退化成今天那几档观感)。百分比来自维护者选定的方案丁:\n * 卡描边 19%/沉底盒底 9%/输入框描边 24%/骨架条 21%。这是本仓第一处\"自定值\",属真源增补\n * (v3.1 只有深色一套 token,从未覆盖浅色)。 */\nconst PANEL_INK = 'var(--dsw-alias-label-primary, #f9fafb)';\nconst inkMix = (percent, into) => into === undefined\n ? `color-mix(in srgb, ${PANEL_INK} ${percent}%, transparent)`\n : `color-mix(in srgb, ${PANEL_INK} ${percent}%, ${into})`;\n/** 卡片描边:浅色 ≈`#cfcfcf` ⇔ 深色 ≈`#4a4b4d`。 */\nconst PANEL_CARD_EDGE = inkMix(19);\n/** 沉底盒底(母版行/高级组体/状态行):浅色 ≈`#e9e9e9` ⇔ 深色 ≈`#3a3b3d`。 */\nconst PANEL_SUNKEN_FILL = inkMix(9, 'var(--dsw-alias-bg-layer-1, #232324)');\n/** 输入框描边:浅色 ≈`#c4c4c4` ⇔ 深色 ≈`#5a5b5d`。 */\nconst PANEL_FIELD_EDGE = inkMix(24);\n/** 骨架条:浅色 ≈`#c9ccd2`(1.6:1)⇔ 深色 ≈`#404143`。 */\nconst PANEL_SKELETON_FILL = inkMix(21);\nconst S = {\n /** `.ic-card`:`background:var(--ic-surface)`(=bg-layer-1)+`border:1px solid var(--ic-line-strong)`\n * +`border-radius:12px`+`padding:14px`+`box-shadow:inset 0 1px 0 rgba(255,255,255,.06)`。\n * 基准字号**不钉在卡片上**(#739 ⑤:跟着宿主走)。 */\n card: {\n padding: 14,\n borderRadius: 12,\n // #941:卡片的边界在浅色下原本等于没有(四层底同白)⇒ 改成按墨色派生的可见描边。\n border: '1px solid ' + PANEL_CARD_EDGE,\n background: 'var(--dsw-alias-bg-layer-1, #232324)',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.06)',\n },\n /** `.ic-head{display:flex;align-items:center;gap:10px;min-height:22px}`(徽标靠 `margin-left:auto` 右贴)。 */\n head: { display: 'flex', alignItems: 'center', gap: 10, minHeight: 22 },\n /** `.ic-title{font-size:13.5px;font-weight:640}`——字号按 60 行那条锚点换算成 `1.08em`。 */\n title: { fontSize: '1.08em', fontWeight: 640 },\n /** `.ic-file{margin-top:4px}` 的那 4px 挂在两行的公共容器上:`info` 自己一格 margin 都不写\n * (#743 ①:头部两行间距不一家一个数,故这一项一律不写 margin)。 */\n fileWrap: { marginTop: 4 },\n /** #939:骨架条(照真源 `.ic-sk`:`display:block;height:17px;border-radius:4px`)。\n * 高度按一行正文画——inline-block 跟着父级行高走会让骨架行比填充后的文字行高 4px、六家叠起来就是一片下移。\n * 底色走派生值(宿主专用骨架档 `bg-skeleton` 在浅色下只有 1.09:1,等于看不见)。 */\n skeleton: {\n display: 'block',\n height: 17,\n borderRadius: 4,\n background: PANEL_SKELETON_FILL,\n },\n /** #936:状态行那一块(照真源 `.ic-status`)——沉底面盒子,里面三行:状态行/路径行/官网行。 */\n statusBox: {\n marginTop: 11,\n padding: '10px 12px',\n background: PANEL_SUNKEN_FILL,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 8,\n },\n /** `.ic-srow{display:flex;align-items:center;gap:8px;font-size:12px;flex-wrap:wrap}`(12px ⇒ 0.86em)。 */\n statusRow: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: '0.86em',\n flexWrap: 'wrap',\n },\n /** `.ic-dot{width:8px;height:8px;border-radius:50%}`——底色按档位在组件里补。 */\n statusDot: { width: 8, height: 8, borderRadius: '50%', flex: '0 0 auto' },\n /** `.ic-sname{font-weight:600;white-space:nowrap}`。 */\n statusName: { fontWeight: 600, whiteSpace: 'nowrap' },\n /** `.ic-stxt{color:var(--ic-muted);min-width:0}`。 */\n statusText: { color: 'var(--dsw-alias-label-secondary, #cfd3d6)', minWidth: 0 },\n /** `.ic-sfind{display:flex;align-items:center;gap:8px;margin-top:7px}`。 */\n statusFind: { display: 'flex', alignItems: 'center', gap: 8, marginTop: 7 },\n /** `.ic-spath{font-size:10.5px;color:var(--ic-faint);white-space:nowrap;overflow:hidden}`\n * ——单行不折、超出裁掉(**不写省略号**:本件有一条\"零省略号\"的跨包锁)。\n * **不写 `fontFamily`**:v3.1 这一格要 `var(--ic-mono)`,但 `#739 ①` 明令共用件零字族(宿主没有界面字族\n * token,钉死会在别的窗口尺寸上失真)——与真源的同一处已知不同,账在 #920 证据件里。 */\n statusPath: {\n fontSize: '0.75em',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n minWidth: 0,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n },\n /** `.ic-ver{font-size:10px;border:1px solid var(--ic-line-strong);border-radius:999px;padding:0 6px}`。 */\n statusVersion: {\n fontSize: '0.72em',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 999,\n padding: '0 6px',\n whiteSpace: 'nowrap',\n },\n /** `.ic-url{display:inline-block;margin-top:7px;font-size:10.5px;color:var(--ic-faint)}`\n * ——字族同样继承宿主(`#739 ①`:共用件零 `fontFamily`),理由同上一格。 */\n statusUrl: {\n display: 'inline-block',\n marginTop: 7,\n fontSize: '0.75em',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n },\n /** `.ic-file b{color:var(--ic-faint);font-weight:400;margin-right:5px}`(「配置文件」「数据目录」那两个字)。 */\n fileLabel: {\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontWeight: 400,\n marginRight: 5,\n },\n /** `.ic-file{color:var(--ic-muted);font-size:11.5px;word-break:break-all}`(11.5px ⇒ `0.92em`)。 */\n info: {\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n fontSize: '0.92em',\n wordBreak: 'break-all',\n },\n /** `.ic-muted` 那一档(次要字)。 */\n muted: { color: 'var(--dsw-alias-label-secondary, #cfd3d6)', fontSize: '0.92em' },\n /** 错误字:取 v3.1 的 `--ic-danger`;字号 `1em`(#739 钉死)。 */\n error: {\n marginTop: 8,\n color: 'var(--dsw-alias-state-error-primary, #e0685f)',\n fontSize: '1em',\n whiteSpace: 'pre-wrap',\n },\n /** 成功字:取 v3.1 的 `--ic-ok`;字号 `0.96em`(#739 钉死)。 */\n okText: {\n marginTop: 8,\n color: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n fontSize: '0.96em',\n },\n /** 行组的容器(六家附加块也拿它当外框;v3.1 没有对应类,故只给一个中性块)。 */\n rows: { display: 'block' },\n /** `.ic-row`:三列栅格 + `gap:4px 10px` + `padding:7px 0` + 一条 `.ic-line` 下边线。\n * 本件把它落成**换行弹性盒**(见文件头 ③):标签定宽在第一行,值装不下时整行让位,\n * 动作槽绝对定位贴在行尾(`.ic-row .ic-slot[data-slot^=\"a:\"]` 那一格)。 */\n row: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0',\n borderBottom: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n },\n /** `.ic-row:last-child{border-bottom:0}`——内联样式没有 `:last-child`,由画它的人明说。 */\n rowLast: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0',\n },\n /** `.ic-under{margin:9px 0 0 8px;border-left:1px solid var(--ic-line-strong);padding-left:13px}`:\n * **跟随行**相对它的可改行(母版行)缩进 8+1+13=**22px**,左边挂一条线。\n *\n * 取值逐字照抄;只有一处形态差别要说清:`.ic-under` 在 v3.1 里是**一整块**(同一个可改行的一批\n * 跟随者共用一个 div、共一条左边线、块首还有 9px 上边距),而共用件手上只有「谁是跟随行」这一个\n * 集合(由六家交的 `followKeysOf` 钩子逐键探出),**没有**「这一行归哪一块」的分块归属\n * (同一个键可以同时挂在两张跟随表上,钩子只回一个去重后的并集)。故这里按**行**落这条缩进:\n * 缩进量与左边线同值,块首那 9px 上边距不落(落下去会在每两行之间多出一道 9px 的缝)。 */\n followerRow: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0 7px 13px',\n marginLeft: 8,\n borderLeft: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderBottom: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n },\n /** 跟随行的最后一行:同上,去掉下边线(照 `.ic-row:last-child{border-bottom:0}`)。 */\n followerRowLast: {\n position: 'relative',\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '4px 10px',\n padding: '7px 0 7px 13px',\n marginLeft: 8,\n borderLeft: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n },\n /** `.ic-row .ic-k{font-size:11.5px;color:var(--ic-muted)}`;`--ic-kw:118px` 是标签列的定宽。 */\n rowKey: {\n flex: '0 0 auto',\n minWidth: 118,\n fontSize: '0.92em',\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n },\n /** `.ic-row .ic-v{font-size:11px;min-width:0}`(11px ⇒ `0.88em`)+ 文件头 ③ 的让位口径:\n * `flex:1 1 auto` ⇒ 装不下整行让位;`overflow-wrap:anywhere` ⇒ 折下去、零省略号;\n * `paddingRight` 给行尾那枚按钮(+列间距)让出宽度——就是 `.ic-row` 第三列那一格。 */\n rowValue: {\n flex: '1 1 auto',\n minWidth: 0,\n paddingRight: 56,\n fontSize: '0.88em',\n whiteSpace: 'normal',\n overflowWrap: 'anywhere',\n lineHeight: 1.5,\n },\n /** 行尾动作槽(复制/跟随标记):绝对定位贴行尾,行一换行它仍留在第一行行尾(=`.is-wide` 那一形)。 */\n rowActs: {\n position: 'absolute',\n right: 0,\n top: 7,\n display: 'flex',\n gap: 4,\n alignItems: 'center',\n },\n /** `.ic-follow{font-size:11px;color:var(--ic-attn);white-space:nowrap}`(11px ⇒ `0.88em`)。 */\n follow: {\n fontSize: '0.88em',\n color: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n },\n /** `.ic-follow::before{content:'↳';opacity:.8}`——内联样式给不出伪元素,画成真的那一个字符。 */\n followMark: { opacity: 0.8 },\n /** `.ic-master`:母版行那一块盒子(`--ic-sunken` 底 + `border-radius:8px` + `padding:11px 12px`\n * + `margin-top:11px` + 内高光)。 */\n master: {\n // #941:沉底盒的底改成按墨色派生——浅色下 `bg-layer-3` 与卡面同白(盒子看不见),派生值给出一档可见的面差。\n background: PANEL_SUNKEN_FILL,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 8,\n padding: '11px 12px',\n marginTop: 11,\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.05)',\n },\n /** `.ic-master .ic-lab{font-weight:600;display:flex;align-items:center;gap:7px}`;\n * 字号**不写**(#739 ④:`label` 这一项该继承宿主字号)。 */\n label: { display: 'flex', alignItems: 'center', gap: 7, fontWeight: 600 },\n /** `.ic-chip{font-size:10.5px;border:1px solid var(--ic-accent);border-radius:999px;padding:0 6px}`(10.5px ⇒ `0.84em`)。 */\n chip: {\n fontSize: '0.84em',\n border: '1px solid var(--dsw-alias-brand-primary, #f9fafb)',\n borderRadius: 999,\n padding: '0 6px',\n color: 'var(--dsw-alias-brand-primary, #f9fafb)',\n whiteSpace: 'nowrap',\n },\n /** `.ic-master .ic-hint{color:var(--ic-muted);font-size:11.5px;margin-top:3px;line-height:1.5}`。 */\n hint: {\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n fontSize: '0.92em',\n marginTop: 3,\n lineHeight: 1.5,\n },\n /** `.ic-master input`:整行宽、`margin-top:7px`、`padding:5px 8px`、`--ic-bg` 底、`--ic-line-strong` 描边、\n * `border-radius:6px`。字号与字族**不写**(#739 ④/①:`input` 继承宿主)。 */\n input: {\n display: 'block',\n width: '100%',\n marginTop: 7,\n padding: '5px 8px',\n boxSizing: 'border-box',\n background: 'var(--dsw-alias-bg-base, #151517)',\n // #932/#941:描边换成按墨色派生的可见档——原 `border-l2` 在浅色下只有 1.26:1,等于没有边界\n //(维护者判\"不够明显\"),派生值给到 ≈1.6:1;深色下比原先略亮一档。\n border: '1px solid ' + PANEL_FIELD_EDGE,\n borderRadius: 6,\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n },\n /** `.ic-master input.is-dirty`:`border:2px solid var(--ic-attn)` + `padding:4px 7px`\n * + `box-shadow:0 0 0 3px <琥珀 22%>`;2px 描边与 5→4 的内边距对消,宽高不变\n * (审查「站得住」第 7 条)。 */\n inputDirty: {\n display: 'block',\n width: '100%',\n marginTop: 7,\n padding: '4px 7px',\n boxSizing: 'border-box',\n background: 'var(--dsw-alias-bg-base, #151517)',\n border: '2px solid var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderRadius: 6,\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n boxShadow: '0 0 0 3px color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e0a33e) 22%, transparent)',\n },\n /** 布尔档那枚方框(v3.1 的母版行只有文本框,这一格按输入框的同一套外边距对齐)。 */\n checkbox: { marginTop: 7 },\n /** `.ic-acts{display:flex;gap:5px;margin-top:7px;flex-wrap:wrap;align-items:center}`(母版行的按钮行)。 */\n acts: { display: 'flex', gap: 5, marginTop: 7, flexWrap: 'wrap', alignItems: 'center' },\n /** `.ic-btn.is-mini{font-size:11px;padding:2px 7px;color:var(--ic-muted)}`——`btnPick` 是锁钉死的那一格,\n * 字号**不写**(#739 ④:该继承宿主字号),形状照 v3.1。 */\n btnPick: {\n padding: '2px 7px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n background: 'transparent',\n color: 'var(--dsw-alias-label-secondary, #cfd3d6)',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** `.ic-invalid{margin-top:7px;padding:7px 9px;border-radius:6px;font-size:11.5px;line-height:1.5;\n * background:color-mix(in srgb, var(--ic-attn) 16%, transparent);border:1px solid var(--ic-attn)}`。 */\n invalid: {\n marginTop: 7,\n padding: '7px 9px',\n borderRadius: 6,\n fontSize: '0.92em',\n lineHeight: 1.5,\n background: 'color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e0a33e) 16%, transparent)',\n border: '1px solid var(--dsw-alias-state-warn-primary, #e0a33e)',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n },\n /** `.ic-group{margin-top:14px}`(高级组默认收起)。 */\n advanced: { marginTop: 14 },\n /** `.ic-group > .ic-ghead{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;\n * font-weight:600;padding:2px 0}`——字号**不写**(#739 ④:`summary` 该继承宿主字号)。 */\n summary: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n cursor: 'pointer',\n listStyle: 'none',\n fontWeight: 600,\n padding: '2px 0',\n },\n /** `.ic-ghead::before{content:'›';color:var(--ic-muted)}`——画成真的那一个字符(内联样式给不出伪元素)。 */\n groupMark: { color: 'var(--dsw-alias-label-secondary, #cfd3d6)' },\n /** #934:`.ic-gnote` 那条副文案的样式随之删除——副文案本身已按维护者裁定整条撤掉(零消费者的槽位不留)。 */\n /** `.ic-group > .ic-gbody{margin-top:9px;padding:11px 12px;background:var(--ic-sunken);\n * border-radius:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}`。 */\n groupBody: {\n marginTop: 9,\n padding: '11px 12px',\n // #941:同母版行——沉底面走派生值(浅色下 `bg-layer-3` 与卡面同白)。\n background: PANEL_SUNKEN_FILL,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n borderRadius: 8,\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,.04)',\n },\n /** `.ic-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px;padding-top:12px;\n * border-top:1px solid var(--ic-line)}` + **贴下沿吸住**(v3.1 的 `.ic-attnbar.is-sticky` 是它唯一的\n * 吸底口径:`position:sticky;bottom:6px;z-index:3`;本票按票面「贴下沿」取 0,好让底栏与下沿齐平)。 */\n bar: {\n display: 'flex',\n gap: 8,\n alignItems: 'center',\n flexWrap: 'wrap',\n marginTop: 14,\n paddingTop: 12,\n borderTop: '1px solid var(--dsw-alias-border-l1, rgba(255,255,255,.06))',\n position: 'sticky',\n bottom: 0,\n zIndex: 3,\n background: 'var(--dsw-alias-bg-layer-1, #232324)',\n },\n /** `.ic-bar .ic-note{margin-left:auto;color:var(--ic-faint);font-size:11.5px}`(就绪态那半句)。 */\n barNote: {\n marginLeft: 'auto',\n color: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n fontSize: '0.92em',\n },\n /** 有改动时底栏那半句(黄字,粘在按钮组左侧)。 */\n saveMsg: {\n marginLeft: 'auto',\n color: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontSize: '0.92em',\n },\n /** `.ic-btn{font-size:12px;padding:4px 10px;border-radius:6px;border:1px solid var(--ic-line-strong);\n * background:transparent;color:var(--ic-text)}`——字号**不写**(#739 ④)。 */\n btn: {\n padding: '4px 10px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary, #f9fafb)',\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** `.ic-btn.is-primary{background:var(--ic-accent);border-color:var(--ic-accent);color:var(--ic-accent-ink);\n * font-weight:500}`——`--ic-accent` 取 `--dsw-alias-brand-primary`,前景取 `label-primary-foreground`。 */\n btnPrimary: {\n padding: '4px 10px',\n borderRadius: 6,\n border: '1px solid var(--dsw-alias-brand-primary, #f9fafb)',\n background: 'var(--dsw-alias-brand-primary, #f9fafb)',\n color: 'var(--dsw-alias-label-primary-foreground, #0f1115)',\n fontWeight: 500,\n cursor: 'pointer',\n whiteSpace: 'nowrap',\n },\n /** #934:原先这里有一格 `version`(各家附加块的版本行字面)。版本行已按维护者裁定整条撤掉\n *(那两家面板内的渲染点 + 六家各自那份字面副本),这一格随之删除:没人取的槽位不留。 */\n /** `.ic-badge{font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;white-space:nowrap;\n * display:inline-flex;align-items:center;gap:6px;border:1px solid transparent}`(11px ⇒ `0.88em`)。 */\n badge: {\n fontSize: '0.88em',\n lineHeight: 1,\n padding: '4px 9px',\n borderRadius: 999,\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n border: '1px solid transparent',\n },\n /** `.ic-badge .ic-bd{width:6px;height:6px;border-radius:50%;background:currentColor}`。 */\n badgeDot: { width: 6, height: 6, borderRadius: '50%', background: 'currentColor' },\n /** `.ic-spin{width:11px;height:11px;border-radius:50%;border:1.5px solid rgba(0,0,0,.25);\n * border-top-color:currentColor}`——旋转那半要 `@keyframes`(内联样式给不出),故只画环。 */\n badgeSpinner: {\n width: 11,\n height: 11,\n borderRadius: '50%',\n border: '1.5px solid rgba(0,0,0,.25)',\n borderTopColor: 'currentColor',\n display: 'inline-block',\n },\n /** `.ic-badge.is-dirty`:`--ic-attn` 实底 + `--ic-attn-ink` 深字(那 3:1 是设计专门解过的对比度)。 */\n badgeDirty: {\n color: '#241703',\n background: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderColor: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontWeight: 600,\n },\n /** `.ic-badge.is-busy`:与 dirty 同色(写的时候还在那一档上)。 */\n badgeBusy: {\n color: '#241703',\n background: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n borderColor: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n fontWeight: 600,\n },\n /** `.ic-badge.is-ok{color:var(--ic-ok);border-color:var(--ic-ok);background:color-mix(in srgb, var(--ic-ok) 14%, transparent)}`。 */\n badgeOk: {\n color: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n borderColor: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n background: 'color-mix(in srgb, var(--dsw-alias-state-success-primary, #4ec9a0) 14%, transparent)',\n },\n /** `.ic-badge.is-bad{color:var(--ic-danger-ink);background:var(--ic-danger);border-color:var(--ic-danger)}`。 */\n badgeBad: {\n color: '#fff5f4',\n background: 'var(--dsw-alias-state-error-primary, #e0685f)',\n borderColor: 'var(--dsw-alias-state-error-primary, #e0685f)',\n fontWeight: 600,\n },\n};\n/** 复制那一枚按钮的字面(定稿 v3 第三条:就地变,不弹提示)。 */\nexport function copyLabelOf(state) {\n if (state === 'done')\n return '已复制';\n if (state === 'failed')\n return '复制失败';\n return '复制';\n}\n/** 状态 → 徽标那一档(v3.1 `paint()` 里的先后次序:读取失败/写入中/写入失败/值非法/有改动/已保存/就绪)。 */\nexport function panelBadgeOf(facts) {\n if (facts.readFailed)\n return 'readFailed';\n if (facts.busy)\n return 'busy';\n if (facts.writeFailed)\n return 'writeFailed';\n if (facts.invalid)\n return 'invalid';\n if (facts.dirtyCount > 0)\n return 'dirty';\n if (facts.saved)\n return 'saved';\n return 'ready';\n}\n/** 徽标那一档画的字(v3.1 `badgeHTML` 的字面,只把「已保存 · 刚刚」的演示时刻换成档名)。 */\nexport function badgeTextOf(kind, dirtyCount) {\n if (kind === 'dirty')\n return `${dirtyCount} 项未保存`;\n if (kind === 'busy')\n return '正在写入';\n if (kind === 'saved')\n return '已保存';\n if (kind === 'invalid')\n return '配置里有值用不了';\n if (kind === 'writeFailed')\n return '写入失败';\n return '';\n}\n/** 徽标那一档的底色(v3.1 的四条 `.ic-badge.is-*`)。 */\nfunction badgeStyleOf(kind) {\n if (kind === 'dirty' || kind === 'invalid')\n return { ...S.badge, ...S.badgeDirty };\n if (kind === 'busy')\n return { ...S.badge, ...S.badgeBusy };\n if (kind === 'saved')\n return { ...S.badge, ...S.badgeOk };\n if (kind === 'writeFailed')\n return { ...S.badge, ...S.badgeBad };\n return S.badge;\n}\n/** 画卡片标题行右端那枚状态徽标(就绪态与读取失败那一支不画)。 */\nexport function PanelBadgeView(props) {\n const text = badgeTextOf(props.kind, props.dirtyCount);\n if (text === '')\n return null;\n return React.createElement('span', { style: badgeStyleOf(props.kind) }, props.kind === 'busy'\n ? React.createElement('span', { style: S.badgeSpinner })\n : React.createElement('span', { style: S.badgeDot }), text);\n}\n/** 一行怎么画(照 v3.1 的两套行模板):\n *\n * **只读行**(`.ic-row`)=标签—值同行、值装不下整行让位、行尾一枚「复制」——**不画输入框**\n * (值来自技能侧解析,页面上本来就不给改),也不画那行说明(v3.1 的 `rowShell` 里没有它)。\n * **可改行**(`.ic-master`)=标签 +「可改」小徽标 + 说明 + 整行输入框 + 按钮行。\n *\n * 目录档=文本框 + 一枚唤起目录选择的按钮;入口三态是 `none`(命名空间拿不到、或这条路已被拒)\n * **就不画按钮**,文本框照旧——那是该缝自己的契约(供不了就收起入口,不是失败)。\n * 只读行:目录入口**一枚都不画**(定稿 v3 ①)。 */\nexport function Row(props) {\n const { item } = props;\n const readonly = item.readonly === true;\n const disabled = props.disabled || readonly;\n const copy = React.createElement('button', {\n style: S.btnPick,\n type: 'button',\n disabled: props.onCopy === undefined,\n onClick: () => props.onCopy?.(item.key, props.value),\n }, copyLabelOf(props.copyState));\n const follow = props.follow === true\n ? React.createElement('span', { style: S.follow }, React.createElement('span', { style: S.followMark }, '↳'), '将跟随更新')\n : null;\n if (readonly) {\n /** 跟随行落 `.ic-under` 那一档缩进;其余按是不是本组最后一行挑有没有下边线。 */\n const rowStyle = props.nested === true ? (props.last === true ? S.followerRowLast : S.followerRow) : props.last === true ? S.rowLast : S.row;\n return React.createElement('div', { style: rowStyle }, React.createElement('span', { style: S.rowKey }, item.title), React.createElement('span', { style: S.rowValue }, props.value), React.createElement('span', { style: S.rowActs }, follow, copy));\n }\n const onChange = (e) => props.onChange(item.key, e.target.value);\n const control = item.control === 'switch'\n ? React.createElement('input', {\n type: 'checkbox',\n style: S.checkbox,\n checked: props.value === 'true',\n disabled,\n onChange: (e) => props.onChange(item.key, e.target.checked ? 'true' : 'false'),\n })\n : React.createElement('input', {\n style: props.dirty === true ? S.inputDirty : S.input,\n type: item.control === 'number' ? 'number' : 'text',\n value: props.value,\n disabled,\n spellCheck: false,\n onChange,\n });\n /** 目录入口:只读行不画(定稿 v3 ①),供不了(`none`/缺席)也不画。 */\n const entry = props.browser ?? null;\n const browse = item.control === 'directory' && entry !== null && entry.mode !== 'none'\n ? React.createElement('button', {\n style: S.btnPick,\n type: 'button',\n disabled,\n // 回这枚 Promise 是有意的:React 不看 onClick 的返回值,而用例能直接 await 它。\n onClick: () => entry.onOpen(item.key),\n }, '浏览文件夹')\n : null;\n return React.createElement('div', { style: S.master }, React.createElement('div', { style: S.label }, item.title, React.createElement('span', { style: S.chip }, '可改')), React.createElement('div', { style: S.hint }, item.hint), control, React.createElement('div', { style: S.acts }, browse, copy), props.alert == null\n ? null\n : React.createElement('div', { style: S.invalid }, props.alert.message));\n}\n/** 应用内浏览器对话框的文案(面板自带,逐条对应图上那几个位置)。 */\nconst BROWSER_LABELS = {\n title: '选择文件夹',\n close: '关闭',\n up: '上一级',\n pathPlaceholder: '直接填绝对路径,回车即进入',\n go: '转到',\n showHidden: (n) => '显示隐藏目录(' + n + ')',\n empty: '这个目录里没有子目录。',\n loading: '正在读取',\n newFolder: '新建文件夹',\n createConfirm: '创建',\n createCancel: '取消',\n select: '选',\n selected: '已选',\n open: '选定这个目录',\n cancel: '取消',\n willPick: '将选定:',\n};\n/** 画整面(四支控件、三支错误落位、底栏、附加块槽都在这里)。 */\nexport function PanelBody(props) {\n const { state, title } = props;\n const surface = state.kind === 'ready' ? state.surface : null;\n const headText = title === undefined ? '配置' : `${title} · 配置`;\n const headDataDir = surface === null ? '' : surface.resolved?.['dbDir'] ?? surface.dataDir;\n const ready = state.kind === 'ready';\n const dirtyCount = ready ? props.dirtyKeys.length : 0;\n const badge = panelBadgeOf({\n readFailed: state.kind === 'failed',\n busy: props.busy,\n writeFailed: props.writeError !== null,\n invalid: props.invalid === true,\n dirtyCount,\n saved: props.notice !== null,\n });\n const head = React.createElement('div', { style: S.head }, React.createElement('div', { style: S.title }, headText), React.createElement(PanelBadgeView, { kind: badge, dirtyCount }));\n /** #939:这一块的高度由**客户端常量**决定、不由回执时序决定——加载期就把两行连标签一起画出来,\n * 值位画骨架条(`.ic-sk`),回执到了**原地填值** ⇒ 回执零位移(原先加载期只画一行小灰字、\n * 回执到了才长出两行,整块下移 21px)。\n *\n * 判断式按 `state.kind`:**不许**照 `surface === null` 写——它同时覆盖失败态,照写会让失败屏长出两行假骨架。 */\n const loading = state.kind === 'loading';\n const fileValue = (text) => text === null ? React.createElement('span', { style: S.skeleton, 'data-ilife-skeleton': 'value' }) : text;\n const fileRow = (label, text, tail) => React.createElement('div', { style: S.info }, React.createElement('b', { style: S.fileLabel }, label), fileValue(text), tail === undefined ? null : tail);\n const fileLines = !loading && surface === null\n ? null\n : React.createElement('div', { style: S.fileWrap }, fileRow('配置文件', surface === null ? null : surface.path, \n // #939:这一句原先独占第三行、首次运行时会多 17px ⇒ 挂到同一行的行尾,两行高度恒定。\n surface !== null && surface.created\n ? React.createElement('span', { style: S.muted }, '(配置文件刚按默认值生成)')\n : null), fileRow('数据目录', surface === null ? null : headDataDir));\n const parts = { styles: S, reply: surface };\n const extra = props.extra === undefined ? null : props.extra(parts);\n if (state.kind === 'failed') {\n return React.createElement('div', { style: S.card }, head, fileLines, React.createElement('div', { style: S.error }, state.message), extra, React.createElement('div', { style: S.bar }, React.createElement('button', { style: S.btn, type: 'button', onClick: props.onRetry }, '重试'), React.createElement('button', { style: S.btn, type: 'button', onClick: props.onReset }, '重置为默认')));\n }\n const common = props.items.filter((item) => item.tier === 'common');\n const advanced = props.items.filter((item) => item.tier === 'advanced');\n /** 还没读到整面(`loading`)时**框架照画**:行表与控件形状是客户端常量,不必等任何回执。\n * 值先空着、控件与三枚底栏键一律不可用;回执到了由 `ready` 那一支把值填上(见 `config-panel.ts`)。 */\n const frozen = props.busy || !ready;\n const followers = props.followerKeys ?? [];\n const renderRow = (item, last) => React.createElement(Row, {\n key: item.key,\n item,\n value: props.draft[item.key] ?? '',\n disabled: frozen,\n onChange: props.onChange,\n browser: props.rowEntry,\n dirty: ready && props.dirtyKeys.includes(item.key),\n follow: ready && props.followKeys.includes(item.key),\n onCopy: ready ? props.onCopy : undefined,\n copyState: props.copy !== null && props.copy.key === item.key ? (props.copy.ok ? 'done' : 'failed') : 'idle',\n alert: ready ? surface?.alerts?.[item.key] ?? null : null,\n last,\n nested: followers.includes(item.key),\n });\n /** 每组最后那一行才免掉下边线(`.ic-row:last-child`);母版行自己不带线,不必管。 */\n const lastIndexOf = (list) => {\n for (let i = list.length - 1; i >= 0; i -= 1)\n if (list[i].readonly === true)\n return i;\n return -1;\n };\n const commonLast = lastIndexOf(common);\n const advancedLast = lastIndexOf(advanced);\n const dirty = ready && dirtyCount > 0;\n return React.createElement('div', { style: S.card }, head, fileLines, React.createElement('div', { style: S.rows }, common.map((item, index) => renderRow(item, index === commonLast))), advanced.length === 0\n ? null\n : React.createElement('details', { style: S.advanced }, React.createElement('summary', { style: S.summary }, React.createElement('span', { style: S.groupMark }, '›'), ADVANCED_GROUP_TITLE), React.createElement('div', { style: S.groupBody }, advanced.map((item, index) => renderRow(item, index === advancedLast)))), extra, React.createElement('div', { style: S.bar }, React.createElement('button', { style: dirty ? S.btnPrimary : S.btn, type: 'button', disabled: frozen || !dirty, onClick: props.onSave }, props.busy ? '处理中' : dirty ? `保存(${dirtyCount} 项未保存)` : '保存'), React.createElement('button', { style: S.btn, type: 'button', disabled: frozen, onClick: props.onReset }, '重置为默认'), React.createElement('button', { style: S.btn, type: 'button', disabled: frozen, onClick: props.onRetry }, '重新读取'), \n // 那半句话是**最后一个孩子**:v3.1 的 `.ic-bar .ic-note{margin-left:auto}` 靠它把说明顶到行尾,\n // 三枚按钮留在左边(顺序反了就会成「说明靠左、按钮靠右」,与真源相反)。\n dirty\n ? React.createElement('div', { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`)\n : ready\n ? React.createElement('div', { style: S.barNote }, '没有未保存的改动')\n // #939:原先加载期在头部独占一行「配置读取中」;搬到底栏这一格——不删(首屏没有第二个\"正在读\"的表示),\n // 但也不占头部那两行的高度(`config-panel-908` 仍按文字断言它在这张卡里)。\n : React.createElement('div', { style: S.barNote }, '配置读取中')), props.picking ? React.createElement('div', { style: S.muted }, '已唤起系统文件夹对话框:选中后自动填上,取消则不动。') : null, props.browseRow !== null\n ? React.createElement(DirectoryBrowserFromRow, { open: true, row: props.browseRow, labels: BROWSER_LABELS })\n : null, props.writeError !== null\n ? React.createElement('div', { style: S.error, role: 'alert' }, props.writeError)\n : null, props.error !== null ? React.createElement('div', { style: S.error }, props.error) : null, props.notice !== null ? React.createElement('div', { style: S.okText }, props.notice) : null);\n}\n/** 状态点的底色:三档状态色 + 默认灰(照真源 `.is-ok/.is-warn/.is-bad` 与 `.ic-dot` 的默认档)。 */\nconst STATUS_DOT_COLOR = {\n ok: 'var(--dsw-alias-state-success-primary, #4ec9a0)',\n warn: 'var(--dsw-alias-state-warn-primary, #e0a33e)',\n bad: 'var(--dsw-alias-state-error-primary, #e0685f)',\n pending: 'var(--dsw-alias-label-tertiary, #adb2b8)',\n};\nexport function StatusBlock(props) {\n const actions = props.actions ?? [];\n return React.createElement('div', { style: S.statusBox, 'data-ilife-status': 'block' }, React.createElement('div', { style: S.statusRow }, React.createElement('span', { style: { ...S.statusDot, background: STATUS_DOT_COLOR[props.tone] } }), React.createElement('span', { style: S.statusName }, props.name), React.createElement('span', { style: S.statusText }, props.text), ...actions.map((action, index) => React.createElement('button', {\n key: action.text,\n style: index === 0 ? { ...S.btnPick, marginLeft: 'auto' } : S.btnPick,\n type: 'button',\n onClick: action.onPress,\n }, action.text))), React.createElement('div', { style: S.statusFind }, props.path === null\n ? React.createElement('span', { style: S.skeleton, 'data-ilife-skeleton': 'statusPath' })\n : React.createElement('span', { style: S.statusPath }, props.path), props.version === undefined || props.version === null || props.version === ''\n ? null\n : React.createElement('span', { style: S.statusVersion }, props.version)), props.link === undefined\n ? null\n : React.createElement('a', { style: S.statusUrl, href: props.link.href, target: '_blank', rel: 'noreferrer' }, props.link.text));\n}\n//# sourceMappingURL=config-panel-view.js.map","/** 「本机根清单」的取数接线(客户端半):把一通电话变成图上那一行可跳转的根。\n *\n * **不认识宿主**:载体基段、通道名(第二段)、电话名全由调用方传进来——各家从自己的宿主镜像里拿\n * 那几个字面量(和 `openRowBrowser` 的 `refusalCode` 同一条规矩)。本件只做两件事:\n * 发一次调用、把回执信封拆成根清单;**任何失败都当空清单**(图上少画一行,不报错、不挡路)。\n */\n/** 认一认某个值像不像一个根(认不出的行丢掉:图的干净比多画一行重要)。 */\nfunction isRootRow(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n const row = raw;\n return typeof row.path === 'string' && row.path !== '' && typeof row.kind === 'string';\n}\n/** 信封 → 根清单(纯函数,**永不抛**):`{ok:true, value:{roots:[…]}}` 之外的形状一律当空。 */\nexport function readRootsAnswer(raw) {\n const answer = (typeof raw === 'object' && raw !== null ? raw : {});\n if (answer.ok !== true)\n return [];\n const value = (typeof answer.value === 'object' && answer.value !== null ? answer.value : {});\n if (!Array.isArray(value.roots))\n return [];\n return value.roots.filter(isRootRow).map((row) => ({ path: row.path, kind: row.kind }));\n}\n/** 建一个「根清单取数器」:给调用口与三个名字,回一个 `() => Promise<RootRow[]>`。\n *\n * 界面按需调它(开图一次),不在渲染里调,也不缓存到这里——缓存是宿主半的事。 */\nexport function createRootsSource(input) {\n return async () => {\n const call = input.getCall();\n if (typeof call !== 'function')\n return [];\n try {\n return readRootsAnswer(await call(input.base, input.endpoint, { method: input.method, payload: {} }));\n }\n catch {\n return [];\n }\n };\n}\n//# sourceMappingURL=directory-browser-roots.js.map","/** 爱生活页签槽名(总管声明 `children`、各单品技能设置页注册进来;单段名,避开官方 `settings.*` 前缀)。\n *\n * 为什么住这里:这个名字**两侧都要用**——面板侧 `client.ts` 拿它注册/投影槽,\n * 宿主侧(`update-env.ts` 的 `readPanelRegistered`)拿它判「已装产物里到底有没有注册代码」。\n * 一处定义、两边引用(结构纪律「概念唯一」):名字改了只有这一行要动。\n * 宿主判据为什么要读这个字面量、以及它的边界,见 `readPanelRegistered` 的头注。 */\nexport const CONFIG_TAB_SLOT = 'ilife.config-tab';\n/** 载体基段:`connection.rpc.call` 的**第一段**参数,宿主注册路径与它同源(`'/api' + 通道名`)。\n *\n * 一处定义(#735):总管自己的电话、以及面板到各家的每一通电话,第一段都必须是它。\n * 真机实现(`dsh-client-connection/lib/client.js`):URL = `${第一段}/${第二段}`、信封 `method` = 第二段。\n * 传错第一段就是 404:总管自己的电话在 #678 栽过一次,各家的配置体检在 #735 又栽过一次\n * (那次传的是通道名 `/ilife-<技能>`,拼出来的地址上没有注册过那条路由,六家全 404)。 */\nexport const CARRIER_BASE = '/api';\n/** 载体:宿主注册 `connection.fetch.register` 的路径 / 面板 `connection.rpc.call` 的两段参数。 */\nexport const MANAGER_RPC = {\n /** 载体基段(`connection.rpc.call` 的**第一段**参数)。传错第一段就是 404:真机上踩过一次。 */\n base: CARRIER_BASE,\n /** 单段通道名,须 match `/^\\/[A-Za-z0-9._~-]+$/`(cookbook §6)。 */\n channel: '/ilife-manager',\n /** 面板侧第二段参数(等于通道名去掉前导斜杠那一段)。 */\n endpoint: 'ilife-manager',\n /** 宿主侧注册的完整路径(= `base` + `channel`)。 */\n path: '/api/ilife-manager',\n};\n/** 总管自有电话名:更新包的三个动作名是冻结集合(`config.ts:14`),这里另起名字不撞车。 */\nexport const MANAGER_ACTIONS = {\n /** 装上缺席的目标包:入参 `{packageName, version}`,回包 `{packageName, version}`。 */\n install: 'ilife-manager.install',\n /** 七个更新目标的表:入参 `{}`,回包 `{targets: [{key, title, packageName, phones, runningVersion, installedVersion, panelRegistered, skill}]}`。\n *\n * 电话名为什么由宿主转交而不是面板侧写死:更新包的三个电话名只有它自己知道\n * (`update.phoneNames`,`host.ts:335`);面板侧既不能 import 更新包(浏览器产物纯度门)\n * 也不该把名字再写一份(写两份必然走散)。宿主把名字表连同版本行一起交出去,\n * 面板一行字面量都不留。 */\n targets: 'ilife-manager.targets',\n /** 总管自述版本(票 #737):入参 `{}`,回包 `{version}`。\n *\n * 宿主读**自己这份已安装包**的 `package.json`(`manager-version.ts`),面板只渲染读到的值。\n * 为什么走电话:面板是浏览器产物,禁 node 内建(`test/client-bundle-48.test.mjs` 看门),\n * 读盘只许在宿主半;与卡路里 #130 同一条路(host 读 → RPC → client 纯渲染)。 */\n version: 'ilife-manager.version',\n /** 本机「根」清单(票 #744):入参 `{}`,回包 `{roots: [{path, kind}]}`。\n *\n * 为什么这条能力住在总管:浏览器里没有卷清单接口,而宿主那条目录选择接缝只有\n * `list`/`createDirectory` 两格——「这台机器上有哪些盘」只能由宿主去问操作系统。\n * 六家的目录浏览器都取这一通电话,故名字与实现都只有这一处(清单本身见 `roots.ts`)。\n * 回包**恒成功**:列不出来是空清单,不是错误码(界面据此只是不画那一行)。 */\n roots: 'ilife-manager.roots',\n};\n/** 版本读不到时两侧共用的降级字面量(面板照原样显示,不假装知道版本)。\n *\n * 一处定义、两侧引用:宿主半 `manager-version.ts` 读失败时回它,面板半 `update-client.ts`\n * 归一化时也认它——面板侧不许 import 宿主半(会把 node 内建带进浏览器束)。 */\nexport const VERSION_UNKNOWN = 'unknown';\n/** 更新包默认官方源(`config.ts:20`,总管侧拼手工命令时用同一个值)。 */\nexport const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';\n/** 装不了 / 装不成的人话原因表:八种 `blockedReason` + 过程错误码(更新包 README 第 8、12 节)。\n *\n * 每条都要三段齐全(票 #740 的文案判据):**事实**(哪里对不上)→ **后果**(这家现在能不能装)\n * → **动作**(用户做得到、且面板上真有的那一步;面板代劳不了的走「下面这条命令」)。\n * 禁用口语与自造词:「半截任务」「电话没接上」「回执异常」「还出现就重装」「查宿主日志」一律不写。\n *\n * 点名的按钮必须是**这一行上真够得着**的那颗(票 #740 第三轮):结果浮层一开就盖住题头的\n * 「检查更新」,所以「改完再读一次」这类下一步一律写「重新检查」(画在那一行上);\n * 只有发生在**重启之后**的下一步才写「检查更新」。反过来,凡是写着「下面这条命令」的那几句,\n * 那一行的命令块必须真出来(判据 `Verdict.manualHint`)——两处都由门禁守着。 */\nconst REASON_TEXT = {\n 'unknown-profile': '认不出这台机器上的安装位置(使用范围的目录不存在,或名字不合法)。把使用范围目录建好,再点「重新检查」。',\n 'source-install': '这一份不是从 npm 发行包装的(源码装),面板不能更新它。要更新,照下面这条命令重装,装完再点「重新检查」。',\n 'invalid-installation': '磁盘上这一份装得不完整(包名或版本对不上、入口文件缺失)。照下面这条命令重装,装完再点「重新检查」。',\n 'installation-changed': '这台机器的安装清单变了(在别处装过、或清单被手工改过),这一家现在不能装。点「重新检查」重新读一次,再点「装上更新」。',\n 'pending-restart': '新版已装到磁盘,正在运行的是旧版本。重启 DSH(退出后重新打开)后生效。',\n 'registry-conflict': '使用范围清单里写的版本与磁盘上的实际版本对不上。打开使用范围的 `package.json`,把这一行改成磁盘上的版本号,再点「重新检查」。',\n 'incompatible-node': '新版本要求 Node 22 或更高,当前运行的是更低版本。升级 Node、重启 DSH 后,再点「检查更新」。',\n // 这条只在「磁盘上的版本与正在运行的一致(或磁盘那份读不到)」时才会印出来——「磁盘 ≠ 运行中」\n // 那一态被事实判据先截走,印的是 `restartLine`。故这里**不许**再教人去重启(那在眼下没用)。\n 'recovery-required': '上次安装没有收尾。点「重试安装」再跑一次;还出现这一条,就用下面这条命令重装。',\n 'check-failed': '查不到最新版本:联网失败,或官方源(registry.npmjs.org)不可达。确认网络与源地址后,再点「重新检查」。',\n 'invalid-release': '官方源上这个版本的元数据不完整(包名或版本不合法、包地址或校验值缺失)。换一个版本,或稍后重试。',\n 'check-expired': '上次检查的结果已过期。点「重新检查」重查一次,再点「装上更新」。',\n 'update-busy': '同一时间只能安装一个插件。等这次装完,再点「装上更新」。',\n 'install-failed': '安装没有完成。在终端里执行下面这条命令把它装完,装完再点「重新检查」。',\n 'manager-unreachable': '面板连不上总管插件(宿主里没注册,或版本对不上)。重启 DSH 后重试;仍不行就在 DSH 日志里找 `[dsh-life-pack]` 的报错。',\n 'bad-request': '面板与总管之间的请求出错了(属程序缺陷)。请在 DSH 日志里找 `[dsh-life-pack]` 的报错,连同这家插件的名字报到本仓 issue。',\n internal: '面板与总管之间的请求出错了(属程序缺陷)。请在 DSH 日志里找 `[dsh-life-pack]` 的报错,连同这家插件的名字报到本仓 issue。',\n};\n/** 原因码 → 人话(认不出的码不猜、原样回码并说明这是未知原因)。 */\nexport function reasonText(code) {\n return REASON_TEXT[code] ?? '面板不认识这个原因码(' + code + ')。请在 DSH 日志里找同一处报错,报到本仓 issue。';\n}\n/** 手工兜底命令(更新包 README 第 9 节形状):使用范围名含特殊字符时加引号。 */\nexport function manualInstallCommand(input) {\n const name = typeof input.profileName === 'string' ? input.profileName.trim() : '';\n if (!name || name.length > 255 || name.startsWith('-') || ['.', '..', 'node_modules'].includes(name))\n return null;\n const version = typeof input.version === 'string' && /^\\d+\\.\\d+\\.\\d+$/.test(input.version) ? input.version : '';\n if (!version)\n return null;\n const registry = input.registryUrl ?? DEFAULT_REGISTRY;\n const profileArg = /^[A-Za-z0-9_.-]+$/.test(name) ? name : JSON.stringify(name);\n return 'dsh plugin --profile ' + profileArg + ' add --save-exact ' + input.packageName + '@' + version + ' --registry=' + registry;\n}\n/** 八种装不了原因码(给门禁与测试对表用;值就是 `BlockedReason` 全集)。 */\nexport const BLOCKED_REASONS = [\n 'unknown-profile',\n 'source-install',\n 'invalid-installation',\n 'installation-changed',\n 'pending-restart',\n 'registry-conflict',\n 'incompatible-node',\n 'recovery-required',\n];\n//# sourceMappingURL=update-contract.js.map","/** 共用配置面板 · 组件本体:一台状态机 + 一圈副作用,渲染交给 `config-panel-view.ts`。\n *\n * 这一件就是六个技能设置页的那张卡片:六家只交「连哪条通道」与「有哪些配置项」(行表),\n * 另加三个可选钩子(跟随映射/卡片标题/自家附加块)。卡片怎么画、值怎么取又怎么填回去、\n * 哪些行被改过还没保存、保存/重置/重新读取怎么走、出错时说什么话,全在本件与它下面那几件里。\n *\n * 状态:读到了没(loading/ready/failed)、哪些行被改过(脏基线)、正在写(busy)、\n * 写完的结果(notice/writeError)、就地失败(error)、目录选择那一路(picking/browseRow)、\n * 复制回执(copy)。**脏基线只看可改行**:只读行显示的是技能算好的绝对路径,拿它当「改动」\n * 会让面板一打开就显示「未保存」。**写完一律重新读一份整面**:写回执不是整面,拿它当整面用\n * 会让页头那行「数据目录」显示成空。\n *\n * 只挂一个副作用(挂载期读一次整面):取数口是**取用器**,每次调它现取,所以那个 effect\n * 不需要跟着任何一格重跑——否则回执一落定就再读一次,会自己把自己转起来。\n *\n * 对外只经 `config-panel-api.ts` 那一道门;本件自己不出门。\n */\nimport * as React from 'react';\nimport { COPY_FEEDBACK_MS, DIRECTORY_PICKER_REFUSED, REMOTE_DIRECTORY_PICKER } from './config-panel-contract.js';\nimport { dirtyKeysOf, fetchConfigSurface, fromDraft, noFollowKeys, resetConfigSurface, saveConfigSurface, toDraft, } from './config-panel-value.js';\nimport { PanelBody } from './config-panel-view.js';\nimport { openRowBrowser, pickerModeOf, readPickAnswer } from './directory-browser-api.js';\nimport { createRootsSource } from './directory-browser-roots.js';\nimport { MANAGER_ACTIONS, MANAGER_RPC } from './update-contract.js';\n/** 认一认某个值像不像目录选择命名空间(认不出就当没有,绝不把设置页带下来)。 */\nfunction isPickerFace(raw) {\n if (typeof raw !== 'object' || raw === null)\n return false;\n return typeof raw.pick === 'function';\n}\n/** 现取目录选择命名空间:**软依赖**,拿不到回 null(页面据此不出入口)。 */\nfunction resolvePicker(getService) {\n if (getService === undefined)\n return null;\n try {\n const raw = getService(REMOTE_DIRECTORY_PICKER);\n return isPickerFace(raw) ? raw : null;\n }\n catch {\n return null;\n }\n}\n/** 唤起一次系统文件夹选择器并归一结果(**永不抛**)。 */\nasync function pickDirectory(picker) {\n try {\n return readPickAnswer(await picker.pick());\n }\n catch (e) {\n const reason = e instanceof Error ? e.message : String(e);\n return { kind: 'unavailable', message: '打不开系统文件夹对话框(' + reason + '):请直接在框里填绝对路径。' };\n }\n}\n/** 写一次剪贴板:**不碰 DOM**,只读当刻环境的 `globalThis.navigator`(拿不到就回 false,不抛)。\n *\n * 为什么不照原型那样退到 `document.execCommand`:本仓插件侧禁 DOM 直写(`document`/`window`),\n * 所以没有那条兜底;拿不到剪贴板就如实回 false,界面上那一枚按钮就地显示「复制失败」。 */\nasync function writeClipboard(text) {\n try {\n const nav = globalThis.navigator;\n const clip = nav?.clipboard;\n if (clip === undefined || typeof clip.writeText !== 'function')\n return false;\n await clip.writeText(text);\n return true;\n }\n catch {\n return false;\n }\n}\n/** **静态**跟随行名单:给行表里每个键喂一遍六家交的钩子,收它返回的跟随者。\n *\n * 为什么能这么探:`followKeysOf` 是**纯函数**,六家的实现都只是「脏键里有没有这一格」那一下判断\n * (各家 `src/client.ts`),喂单键即得「谁跟着它」——**与当刻脏不脏无关**。有了这个集合,共用件就能\n * 照 v3.1 的 `.ic-under` 把跟随行相对它的可改行缩进(#920 补),**六家源码一个字节不用改**。\n * 拿不到钩子时回空表(一行都不缩进,照旧平铺)。 */\nexport function followerKeysOf(items, hook) {\n if (hook === undefined)\n return [];\n const out = new Set();\n for (const item of items)\n for (const key of hook([item.key]))\n out.add(key);\n return [...out];\n}\n/** 技能设置页:承载一家自己的全部可配置项(只配置,不干活)。 */\nexport function ConfigPanel(props) {\n const [state, setState] = React.useState({ kind: 'loading' });\n const [pickerGone, setPickerGone] = React.useState(false);\n const [picking, setPicking] = React.useState(false);\n const [draft, setDraft] = React.useState({});\n const [busy, setBusy] = React.useState(false);\n const [notice, setNotice] = React.useState(null);\n const [writeError, setWriteError] = React.useState(null);\n const [error, setError] = React.useState(null);\n const [browseRow, setBrowseRow] = React.useState(null);\n const [copy, setCopy] = React.useState(null);\n /** 复制回执的复位定时器:**一次性 UI 回执**,不是数据轮询——点一次起一个,到点自我复位,\n * 下一次点击先清掉旧的,卸载时也清掉(下面那个清扫 effect 就是那一半)。 */\n const copyTimer = React.useRef(null);\n React.useEffect(() => () => {\n if (copyTimer.current !== null) {\n clearTimeout(copyTimer.current);\n copyTimer.current = null;\n }\n }, []);\n /** 挂载期读一次整面:卸载之后回来的回执丢掉(不许往已经没了的页面上写)。 */\n React.useEffect(() => {\n let alive = true;\n void (async () => {\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (!alive)\n return;\n if (r.ok) {\n setState({ kind: 'ready', surface: r.surface });\n setDraft(toDraft(props.items, r.surface.values, r.surface));\n }\n else {\n setState({ kind: 'failed', message: r.message });\n }\n })();\n return () => {\n alive = false;\n };\n // 只跑一次:`getCall` 本身是取用器,调用时现取连接;行表与通道在一张卡片里不会换。\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n /** 把一份整面铺到页面上(读到之后唯一那一处落点)。 */\n const apply = (surface) => {\n setState({ kind: 'ready', surface });\n setDraft(toDraft(props.items, surface.values, surface));\n };\n const load = async () => {\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (r.ok)\n apply(r.surface);\n else\n setState({ kind: 'failed', message: r.message });\n };\n /** 写完(保存/重置)之后重新读一份整面:写回执只有 `{path, values}`、重置回执只有\n * `{path, backupPath}`,都不是整面——拿它当整面用,页头那行「数据目录」会显示成空。 */\n const writeThenReload = async (done) => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await fetchConfigSurface(props.getCall(), props.channel);\n if (r.ok) {\n apply(r.surface);\n setNotice(done);\n }\n else {\n setState({ kind: 'failed', message: r.message });\n }\n setBusy(false);\n };\n const onChange = (key, next) => {\n setDraft((prev) => ({ ...prev, [key]: next }));\n setNotice(null);\n setWriteError(null);\n setError(null);\n };\n const picker = pickerGone ? null : resolvePicker(props.getService);\n /** 唤起系统文件夹选择器那一条路(应用内浏览被拒时的兜底,也是命名空间只给 `pick` 时的唯一一条)。 */\n const openNative = async (key) => {\n const face = pickerGone ? null : resolvePicker(props.getService);\n if (face === null)\n return;\n // 系统对话框是模态的:等它回来的这段时间给一行字,免得看着像「点了没反应」。\n setPicking(true);\n setError(null);\n const outcome = await pickDirectory(face);\n setPicking(false);\n if (outcome.kind === 'picked')\n onChange(key, outcome.path);\n else if (outcome.kind === 'unavailable') {\n setError(outcome.message);\n setPickerGone(true);\n }\n };\n /** 目录行的入口动作:**先应用内浏览,宿主没给这条路再换系统对话框**(判断在共用件里)。 */\n const onOpenRow = async (key) => {\n setError(null);\n const opened = openRowBrowser({\n picker,\n initialPath: draft[key] ?? '',\n onChange: (next) => onChange(key, next),\n onRow: setBrowseRow,\n refusalCode: DIRECTORY_PICKER_REFUSED,\n rootsSource: createRootsSource({\n getCall: props.getCall,\n base: MANAGER_RPC.base,\n endpoint: MANAGER_RPC.endpoint,\n method: MANAGER_ACTIONS.roots,\n }),\n });\n if (opened === undefined || (await opened) === 'refused')\n await openNative(key);\n };\n /** 复制一行(定稿 v3 第三条):写完就地变「已复制」(写不进去就地变「复制失败」),1.5 秒后复位,不弹提示。 */\n const onCopy = (key, text) => {\n void writeClipboard(text).then((ok) => {\n setCopy({ key, ok });\n if (copyTimer.current !== null)\n clearTimeout(copyTimer.current);\n copyTimer.current = setTimeout(() => {\n copyTimer.current = null;\n setCopy(null);\n }, COPY_FEEDBACK_MS);\n });\n };\n const onSave = async () => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await saveConfigSurface(props.getCall(), props.channel, fromDraft(props.items, draft));\n setBusy(false);\n if (r.ok)\n await writeThenReload('已保存,立即生效(不用重启宿主)');\n else\n setWriteError(r.message);\n };\n const onReset = async () => {\n setBusy(true);\n setNotice(null);\n setWriteError(null);\n setError(null);\n const r = await resetConfigSurface(props.getCall(), props.channel);\n setBusy(false);\n if (r.ok)\n await writeThenReload('已重置为默认(原配置已另存一份 .bak)');\n else\n setWriteError(r.message);\n };\n const surface = state.kind === 'ready' ? state.surface : null;\n const baseline = surface !== null ? toDraft(props.items, surface.values, surface) : null;\n const dirtyKeys = baseline === null ? [] : dirtyKeysOf(props.items, draft, baseline);\n const followKeys = (props.followKeysOf ?? noFollowKeys)(dirtyKeys);\n /** 技能侧报出「有格子真用不了」⇒ 标题行那枚「配置里有值用不了」徽标才亮(#915 第二步)。 */\n const hasAlert = surface !== null && surface.alerts !== undefined && Object.keys(surface.alerts).length > 0;\n /** 静态那一份(与脏不脏无关):画跟随行的缩进用(v3.1 的 `.ic-under`)。 */\n const followerKeys = followerKeysOf(props.items, props.followKeysOf);\n const mode = pickerModeOf(picker);\n const rowEntry = mode === 'none' ? null : { mode, onOpen: onOpenRow };\n return React.createElement(PanelBody, {\n title: props.title,\n items: props.items,\n state,\n draft,\n busy,\n notice,\n writeError,\n error,\n picking,\n browseRow,\n rowEntry,\n dirtyKeys,\n followKeys,\n followerKeys,\n invalid: hasAlert,\n copy,\n onCopy,\n onChange,\n onSave: () => void onSave(),\n onReset: () => void onReset(),\n onRetry: () => void load(),\n extra: props.extra,\n });\n}\n//# sourceMappingURL=config-panel.js.map","/** dsh-bill-ilife 端口(port):DSH 世界与饼干记账 hexagon 之间的契约。\n *\n * browser 安全:零 node 导入。host 适配器(注册 RPC 通道)与 client\n * 适配器(调用 RPC)共用同一份定义;单测与 loader 回路以此为准。\n * 通道命名遵守宿主约束:单段且不等于 /api(见 cookbook「RPC 通道」)。\n *\n * 照 #56 卡路里样板同形(`packages/plugin-calorie/src/contract.ts`):记账插件原先\n * **没有任何 RPC 通道**,本件是它第一份端口定义(#677)。\n */\nexport const RPC_CHANNEL = '/ilife-bill-ilife' as const;\nexport const RPC_ENDPOINT_READ = 'read' as const;\n\n/** #677 配置端点:读设置页整面、保存一份取值、重置为默认。同走一条通道,靠端点名分发。 */\nexport const RPC_ENDPOINT_CONFIG_GET = 'config.get' as const;\nexport const RPC_ENDPOINT_CONFIG_SAVE = 'config.save' as const;\nexport const RPC_ENDPOINT_CONFIG_RESET = 'config.reset' as const;\n/** #706 配置体检端点:只读一次,回一份报告(判据由技能侧出,本包只透传,不重写一个字)。\n *\n * 端点名与技能侧那条只读命令同名(`<技能>.config.check`);报告形状的唯一真相在技能侧\n * `packages/skill-<技能>/src/health.ts`,面板侧镜像在 `packages/plugin-manager/src/health-contract.ts`。 */\nexport const RPC_ENDPOINT_CONFIG_CHECK = 'config.check' as const;\n\n/** 读请求载荷:与技能 CLI 的 key/params 同形(见 skill-bill SKILL.md)。 */\nexport interface ReadPayload {\n readonly key: string;\n readonly params: Record<string, unknown>;\n}\n\n/** 保存载荷:一份键值(键路径 → 值)。缺项由技能侧按默认值补齐,故只收用户真改的那些。 */\nexport interface SavePayload {\n readonly values: Record<string, unknown>;\n}\n\nexport interface RpcError {\n readonly code: string;\n readonly message: string;\n readonly details: Record<string, unknown>;\n}\n\nexport type RpcResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly error: RpcError };\n\nexport function ok(value: unknown): RpcResult {\n return { ok: true, value };\n}\n\nexport function fail(code: string, message: string): RpcResult {\n return { ok: false, error: { code, message, details: {} } };\n}\n\n/** 读载荷校验:形状不对返回 null,由调用方按 bad-request 回绝(不抛)。 */\nexport function parseReadPayload(raw: unknown): ReadPayload | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const { key, params } = raw as { key?: unknown; params?: unknown };\n if (typeof key !== 'string' || key.length === 0) return null;\n if (typeof params !== 'object' || params === null || Array.isArray(params)) return null;\n return { key, params: params as Record<string, unknown> };\n}\n\n/** 保存载荷校验:形状不对返回 null,由调用方按 bad-request 回绝(不抛)。 */\nexport function parseSavePayload(raw: unknown): SavePayload | null {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return null;\n const { values } = raw as { values?: unknown };\n if (typeof values !== 'object' || values === null || Array.isArray(values)) return null;\n return { values: values as Record<string, unknown> };\n}\n\n/** 解析后的绝对路径组(#749):技能侧算好的落点,设置页的只读行**只显示、不计算**\n * (口径「面板不算默认值、不拼路径」,见 #677 冻结的边界)。\n *\n * 格名与技能侧 `packages/skill-bill/src/fetch/paths.ts` 的 `BillResolvedPaths` 逐字同形\n * (那是算式与取值的唯一定义地);六家的 `*.config.read` 都扩这样一组,各自的格子按自家落点项来。 */\nexport interface ResolvedPaths {\n /** 生效数据目录(面板上唯一可改的那一项的生效值)。 */\n readonly dbDir: string;\n /** 库文件绝对路径。 */\n readonly dbFile: string;\n /** 第二份库(预算/账户)绝对路径。 */\n readonly goalsFile: string;\n /** HELP 产物目录绝对路径。 */\n readonly htmlDir: string;\n /** 备份目录绝对路径。 */\n readonly backupDir: string;\n /** 备份文件名示例(`<前缀><时间戳>.db`,前缀按当刻配置)。 */\n readonly backupSample: string;\n}\n\n/** 配置面回执:形状与技能侧 `bill.config.read` 的 data 逐字段同形(唯一定义地在那边的 cli/config.ts)。 */\nexport interface ConfigSurfaceReply {\n /** 配置文件绝对路径。 */\n readonly path: string;\n /** 数据目录绝对路径。 */\n readonly dataDir: string;\n /** 本次是不是「文件不存在、按默认值落了一份」。 */\n readonly created: boolean;\n /** 当前取值(文件里的 ⊕ 缺项按默认值补)。 */\n readonly values: Record<string, unknown>;\n /** 一组解析后的绝对路径(#749 起技能侧回执带上)。\n * **可选**:装的是旧技能时这一格缺席,只读行显示空串(面板不自己拼路径,绝不编一条出来)。 */\n readonly resolved?: ResolvedPaths;\n}\n\n/** 信封守卫:供 client 拆包前校验(port 拥有信封定义,守卫住 port)。 */\nexport function isRpcResult(raw: unknown): raw is RpcResult {\n if (typeof raw !== 'object' || raw === null) return false;\n const okFlag = (raw as { ok?: unknown }).ok;\n return okFlag === true || okFlag === false;\n}\n","/** dsh-bill-ilife 槽位描述(P10 脚手架,P3 #4 定案)。\n *\n * 写死槽位原生组件:id 命名空间 ilife:cookie,order 95。\n * 注册与打开只走 registerTab/openTab 的路径导航;子页后缀(如 ilife:cookie:*)\n * 只在主面板内导航,不占栏。缺席纯条件渲染,不轮询(本文件无定时器;\n * 有界重试归一由 base-render 拥有,单品不自建)。\n */\n\nexport const SKILL = 'bill' as const;\nexport const SLOT_ID = 'ilife:cookie' as const;\nexport const SLOT_ORDER = 70 as const;\nexport const SLOT_TITLE = '饼干记账' as const;\nexport const PLUGIN = 'dsh-bill-ilife' as const;\nexport const MANAGER_PLUGIN = 'dsh-life-pack' as const;\n\nexport interface SlotDescriptor {\n readonly skill: string;\n readonly slotId: string;\n readonly order: number;\n readonly title: string;\n readonly kind: 'page';\n}\n\nexport function slotDescriptor(): SlotDescriptor {\n return { skill: SKILL, slotId: SLOT_ID, order: SLOT_ORDER, title: SLOT_TITLE, kind: 'page' };\n}\n\n/** 写死原生组件描述(纯数据,无按需加载,无外嵌页)。 */\nexport const TAB_COMPONENT = { kind: 'native', name: 'BillPanel' } as const;\n\nexport interface TabsPort {\n hasTabs(): boolean;\n registerTab(entry: { readonly id: string; readonly title: string; readonly order: number; readonly single: boolean; readonly component: unknown }): () => void;\n openTab(seed: { readonly type: string; readonly path: string }, scope?: { readonly sessionId?: string }): void;\n}\n\n/** 自注册:幂等(调用方持 disposer),失败返回 false 由调用方决定重试。 */\nexport function registerSingle(port: TabsPort): (() => void) | null {\n if (!port.hasTabs()) return null;\n return port.registerTab({ id: SLOT_ID, title: SLOT_TITLE, order: SLOT_ORDER, single: true, component: TAB_COMPONENT });\n}\n\n/** 内容型打开:path seed,折叠面板自动展开。 */\nexport function openSingle(port: TabsPort, sessionId?: string): void {\n if (!port.hasTabs()) return;\n port.openTab({ type: SLOT_ID, path: SLOT_ID }, sessionId ? { sessionId } : undefined);\n}\n","/** dsh-bill-ilife 设置页元数据(#677:从只读脚手架换成真配置页)。\n *\n * 本文件是**设置页的行表**:一个可配置项一行,写清它在配置文件里的键、中文标题、\n * 分级(常用 / 高级)、控件种类、只读与否与人话指引。它是页面渲染的唯一依据。\n *\n * **本文件必须零 node 依赖**:`tsconfig.client.json` 把它收进 client 侧编译,\n * 浏览器产物不许带 node 内建。取值一律由宿主经技能 CLI 的 `bill.config.read` 端点现取\n * (见 bridge.ts)。\n *\n * 口径:\n * · 配置表形状(键与默认值)的**唯一定义地**是技能侧 `packages/skill-bill/src/config.ts`\n * 的 `BILL_CONFIG_DEFAULTS`(本文件是它在页面上的投影,逐键对齐由\n * `test/config-surface-677.test.mjs` 用编译产物锁死);\n * · **空串=按默认落点**(老落点由技能各取用处算),所以「空」不是「没配」,\n * 而是「还走改造前那个位置」,老数据不会看起来丢了——行文案按这个语义写;\n * · `db.dir` 那一行的落点由配置面回执的 `dataDir` 带回(解析好的绝对路径),页面上把它**预填**进\n * 该行(`prefillFrom: 'dataDir'`),用户不必自己拼路径(#743)。\n *\n * **#749 起本家是六家的样板**:页面从「可改表单」收窄成**一处可改 + 其余只读展示**——\n * · 可改 1 项:数据目录(`db.dir`,显示生效绝对路径,值非法/空 ⇒ 回落默认数据目录);\n * · 只读 5 项:库文件名/预算账户文件名/HELP 产物目录名/备份目录/备份文件名前缀——它们\n * **只显示技能算好的绝对路径**(`resolveFrom` 指向回执 `resolved` 组的那一格),面板既不重算也不提交;\n * · 只读目录行(备份目录)的「浏览」按钮**保留但不可点击**(#747 定稿:入口不作废,只是不能改)。\n *\n * 清单出处:「六家技能的路径类配置全量调查」记账 8 项去掉 1 项包内固定(包内页面模板目录)\n * =上设置页候选 7 项,其中「产物文件名主体」在源码里是两个值(#677 起行数 8)。\n * **#762 起那两个产物名主体出配置表**(键已退休、文件名回到技能侧代码常量);\n * **#749 起那 5 行转只读**,故本表仍是 6 行(可改 1 + 只读 5)。\n */\nexport const SETTINGS_OWNER = 'dsh-bill-ilife' as const;\nexport const SETTINGS_SLOT = 'ilife:cookie' as const;\n\n/** 配置文件主体名:落点 `~/.ilife/bill.yaml`。 */\nexport const CONFIG_STEM = 'bill' as const;\n\n/** 分级:常用项直接画在页面上,其余进默认收起的「高级」组(#675 冻结口径)。 */\nexport type ConfigTier = 'common' | 'advanced';\n\n/** 控件种类:只有这四种(前三种与受限 YAML 子集的字符串/数字/布尔一一对应,没有数组;\n * `directory` 是**字符串那一档的页面形态**——取值仍是串,只是多一个唤起系统文件夹选择器的入口,见 #736)。 */\nexport type ConfigControl = 'text' | 'number' | 'switch' | 'directory';\n\n/** 只读行显示的那一格:技能侧回执 `resolved` 组里的格名(面板只显示、不计算)。 */\nexport type ResolvedField = 'dbDir' | 'dbFile' | 'goalsFile' | 'htmlDir' | 'backupDir' | 'backupSample';\n\nexport interface ConfigItem {\n /** 配置文件里的键路径,一层嵌套用 `.` 连接,例 `backup.dir`。 */\n readonly key: string;\n /** 页面上那一行的中文标题。 */\n readonly title: string;\n readonly tier: ConfigTier;\n readonly control: ConfigControl;\n /** 一行人话:这一项管什么、留空会怎样(一到两句,不写开发期口径)。 */\n readonly hint: string;\n /** **只读行**(#749):页面上不给改,值只经技能侧解析后显示;改它要编辑配置文件。\n * 只读行**不参与**保存(`fromDraft` 不收它,免得把显示用的绝对路径写回配置)。 */\n readonly readonly?: boolean;\n /** 只读行的**显示值来源**:回执 `resolved` 组里的哪一格。标了它 ⇒ 显示技能算好的绝对路径;\n * 不标 ⇒ 显示配置文件里那个值本身(数字类只读项走这一档,见 #749 补注二的甲档)。 */\n readonly resolveFrom?: ResolvedField;\n /** 目录行的落点来源:这一行取值空着时,页面上拿配置面回执里的哪一格当它显示的绝对路径。\n * 只有 `db.dir` 标它——回执里的 `dataDir` 就是技能真会用的那个目录,逐字相同。 */\n readonly prefillFrom?: 'dataDir';\n}\n\n/** 常用项:改了就影响「库与产物落在哪」,放页面上。 */\nconst COMMON: readonly ConfigItem[] = [\n {\n key: 'db.dir',\n title: '数据目录',\n tier: 'common',\n control: 'directory',\n // 留空=技能按默认目录落文件;页面上把解析出来的绝对路径直接填进这一行(见 client.ts 的 toDraft)。\n prefillFrom: 'dataDir',\n hint: '库文件与备份的根目录。留空=用默认目录。',\n },\n {\n key: 'db.name',\n title: '库文件名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'dbFile',\n hint: '数据目录下的库文件。',\n },\n {\n key: 'db.goals',\n title: '预算/账户文件名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'goalsFile',\n hint: '与库同目录的预算与账户文件。',\n },\n {\n key: 'html.dir',\n title: 'HELP 产物目录名',\n tier: 'common',\n control: 'text',\n readonly: true,\n resolveFrom: 'htmlDir',\n hint: 'HELP 与速查表的存放目录。',\n },\n];\n\n/** 高级项:默认收起。改错了多半只是自己撞上麻烦,不确定就别动。 */\nconst ADVANCED: readonly ConfigItem[] = [\n {\n key: 'backup.dir',\n title: '备份目录',\n tier: 'advanced',\n control: 'directory',\n readonly: true,\n resolveFrom: 'backupDir',\n hint: '备份与恢复的读写目录。',\n },\n {\n key: 'backup.stem',\n title: '备份文件名前缀',\n tier: 'advanced',\n control: 'text',\n readonly: true,\n resolveFrom: 'backupSample',\n hint: '备份文件名的前缀,后面自动加时间戳。',\n },\n];\n\n/** 设置页的行表,顺序即页面顺序。 */\nexport const CONFIG_ITEMS: readonly ConfigItem[] = [...COMMON, ...ADVANCED];\n\n/** 常用项行数(页面上直接画出来的那些)。 */\nexport const COMMON_ITEM_COUNT = COMMON.length;\n\n/** 高级组标题与副文案。 */\nexport const ADVANCED_GROUP_TITLE = '高级' as const;\n\n/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */\nexport function readPath(values: Record<string, unknown>, key: string): unknown {\n const parts = key.split('.');\n let cur: unknown = values;\n for (const part of parts) {\n if (typeof cur !== 'object' || cur === null || Array.isArray(cur)) return undefined;\n cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\n/** 按 `a.b` 路径把值写进配置取值(中间层缺就建一层空组;已存在非组即覆盖成组)。 */\nexport function writePath(values: Record<string, unknown>, key: string, value: unknown): void {\n const parts = key.split('.');\n let cur: Record<string, unknown> = values;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n const next = cur[part];\n if (typeof next !== 'object' || next === null || Array.isArray(next)) cur[part] = {};\n cur = cur[part] as Record<string, unknown>;\n }\n cur[parts[parts.length - 1]!] = value;\n}\n","/** dsh-bill-ilife client 适配器(六边形:port=contract,adapter=本文件)。\n *\n * 产物经 tsdown 打成 loader 工厂包(browser/CJS,见 tsdown.config.ts)。\n * 本文件传递闭包:禁 node、禁 DOM 直写(document/window/process)。\n * 注册一处:**技能设置页** → 爱生活页签槽(总管声明的 children,各技能自研自家配置页)。\n * 取数只经 connection.rpc.call 进 host 通道;缺席/错误纯条件渲染,不返空冒充。\n *\n * #909:设置页本体(样式表/行渲染/卡片骨架/状态机/取值与填值/配置面三通电话/\n * 目录选择入口)**收进共用件** `dsh-life-pack/config-panel`,本文件只留四处接线:\n * ① 行表(住 `settings.ts`——那是本家自己的配置数据,不是 UI);\n * ② 通道路由名(`RPC_CHANNEL`,本家唯一那个真变量);\n * ③ 三个可选钩子(卡片标题/跟随映射/自家附加块;本家只用到前两个);\n * ④ 两格宿主取数接线(`getCall`/`getService`)。\n * 本家**不再有**自己的样式表与行渲染函数:改一次共用面板,六家一起变;跨包那两道锁改指向\n * 共用件之后仍然守住「六家同形」这条性质(见 #910)。\n * 照 CONTEXT.md,「技能设置页」只配置、不干活:本页没有查账、记一笔之类的入口。\n */\nimport * as React from 'react';\nimport { ConfigPanel } from 'dsh-life-pack/config-panel';\nimport { RPC_CHANNEL } from './contract.js';\nimport { PLUGIN, SLOT_ORDER, SLOT_TITLE } from './slot.js';\nimport { CONFIG_ITEMS } from './settings.js';\nimport type { ClientCtx } from './dsh-ctx.js';\n\n/** client 短名声明:只有这两个(#736 的目录选择走**可选查找**,不写进来——\n * 写进来=硬依赖,提供方缺席时整包被停靠,设置页会跟着装不上;见 cookbook §13)。 */\nexport const inject: readonly string[] = ['slots', 'connection'];\n\n/** 跟随映射(#863):触发键一脏,这些只读派生行就进“将跟随更新”态。纯函数,面板与单测共用。 */\nconst DB_FOLLOWERS: readonly string[] = ['db.name', 'db.goals', 'html.dir', 'backup.dir', 'backup.stem'];\n\n/** 脏键 → 跟随行(#863 纯函数,交给共用面板当钩子)。 */\nexport function followKeysOf(dirtyKeys: readonly string[]): readonly string[] {\n return dirtyKeys.includes('db.dir') ? [...DB_FOLLOWERS] : [];\n}\n\nexport function apply(ctx: ClientCtx): void {\n // 调用口取用器:每次取数时现取(connection 后到也不永久缺席)。\n const getCall = (): unknown => ctx.connection?.rpc?.call ?? null;\n // #736 目录选择:**软依赖**。形状守卫与「拿不到就不出入口」都住在共用件里(判断只有一处),\n // 本处只把宿主服务查找原样交出去;提供方后到/中途卸载都不留痕(不声明、不停靠,见 cookbook §13)。\n const getService = (name: string): unknown => (typeof ctx.get === 'function' ? ctx.get(name) : undefined);\n\n // 技能设置页 → 爱生活页签槽(总管声明;总管缺席时 inject 等待,不断链)。\n ctx.slots.inject('ilife.config-tab', () =>\n ctx.slots.register(\n {\n name: 'ilife.config-tab',\n id: PLUGIN,\n order: SLOT_ORDER,\n label: () => SLOT_TITLE,\n // #706:本包自己那条 RPC 通道交给总管(各家都写这一格),总管据此调配置体检——\n // 它因此不必在源码里写死任何一家的通道名(零单品依赖照旧成立)。\n channel: RPC_CHANNEL,\n },\n () => React.createElement(ConfigPanel, {\n channel: RPC_CHANNEL,\n items: CONFIG_ITEMS,\n title: SLOT_TITLE,\n followKeysOf,\n getCall,\n getService,\n }),\n ),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWA,MAAa,0BAA0B;EACvC,MAAa,2BAA2B;EACxC,MAAa,4BAA4B;;;;;;EAMzC,MAAa,uBAAuB;;EAEpC,MAAa,kBAAkB;;EAE/B,MAAa,mBAAmB;;EAEhC,MAAa,0BAA0B;;EAEvC,MAAa,2BAA2B;;EAExC,SAAgB,YAAY,KAAK;GAC7B,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACnC,OAAO;GACX,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO;EACzC;;;;;;;;;;;;;;;;;EClBA,SAAgB,SAAS,QAAQ,KAAK;GAClC,MAAM,QAAQ,IAAI,MAAM,GAAG;GAC3B,IAAI,MAAM;GACV,KAAK,MAAM,QAAQ,OAAO;IACtB,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAC5D,OAAO,KAAA;IACX,MAAM,IAAI;GACd;GACA,OAAO;EACX;;EAEA,SAAgB,UAAU,QAAQ,KAAK,OAAO;GAC1C,MAAM,QAAQ,IAAI,MAAM,GAAG;GAC3B,IAAI,MAAM;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;IACvC,MAAM,OAAO,MAAM;IACnB,MAAM,OAAO,IAAI;IACjB,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAC/D,IAAI,QAAQ,CAAC;IACjB,MAAM,IAAI;GACd;GACA,IAAI,MAAM,MAAM,SAAS,MAAM;EACnC;;;;;EAKA,SAAS,eAAe,QAAQ,MAAM;GAClC,MAAM,eAAe,OAAO,WAAW;GACvC,IAAI,OAAO,iBAAiB,YAAY,iBAAiB,IACrD,OAAO;GACX,IAAI,SAAS,aAAa,OAAO,OAAO,YAAY,YAAY,OAAO,YAAY,IAC/E,OAAO,OAAO;EAEtB;;;EAGA,SAAS,eAAe,MAAM,KAAK,QAAQ;GACvC,IAAI,KAAK,gBAAgB,KAAA,GACrB,OAAO;GACX,MAAM,QAAQ,OAAO,WAAW,KAAK;GACrC,OAAO,OAAO,UAAU,WAAW,QAAQ;EAC/C;;EAEA,SAAgB,QAAQ,OAAO,QAAQ,QAAQ;GAC3C,MAAM,QAAQ,CAAC;GACf,KAAK,MAAM,QAAQ,OAAO;IACtB,MAAM,IAAI,SAAS,QAAQ,KAAK,GAAG;IACnC,MAAM,MAAM,MAAM,KAAA,KAAa,MAAM,OAAO,KAAK,OAAO,CAAC;IACzD,IAAI,KAAK,aAAa,MAAM;KACxB,MAAM,KAAK,OAAO,eAAe,MAAM,KAAK,MAAM;KAClD;IACJ;IACA,MAAM,WAAW,KAAK,gBAAgB,KAAA,IAAY,KAAA,IAAY,eAAe,QAAQ,KAAK,WAAW;IACrG,MAAM,KAAK,OAAO,QAAQ,MAAM,aAAa,KAAA,IAAY,WAAW;GACxE;GACA,OAAO;EACX;;;;;EAKA,SAAgB,UAAU,OAAO,OAAO;GACpC,MAAM,SAAS,CAAC;GAChB,KAAK,MAAM,QAAQ,OAAO;IACtB,IAAI,KAAK,aAAa,MAClB;IACJ,MAAM,MAAM,MAAM,KAAK,QAAQ;IAC/B,IAAI,KAAK,YAAY,UAAU;KAC3B,MAAM,IAAI,OAAO,GAAG;KACpB,UAAU,QAAQ,KAAK,KAAK,OAAO,SAAS,CAAC,IAAI,IAAI,CAAC;IAC1D,OACK,IAAI,KAAK,YAAY,UACtB,UAAU,QAAQ,KAAK,KAAK,QAAQ,MAAM;SAG1C,UAAU,QAAQ,KAAK,KAAK,GAAG;GAEvC;GACA,OAAO;EACX;;EAEA,SAAgB,gBAAgB,OAAO;GACnC,OAAO,MAAM,QAAQ,SAAS,KAAK,aAAa,IAAI;EACxD;;;;EAWA,SAAgB,YAAY,OAAO,OAAO,UAAU;GAChD,OAAO,gBAAgB,KAAK,CAAC,CACxB,QAAQ,UAAU,MAAM,KAAK,QAAQ,SAAS,SAAS,KAAK,QAAQ,GAAG,CAAC,CACxE,KAAK,SAAS,KAAK,GAAG;EAC/B;;EAEA,SAAgB,eAAe;GAC3B,OAAO,CAAC;EACZ;;;;;EAWA,SAAgB,sBAAsB,MAAM,SAAS;GACjD,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK;GACnE,IAAI,iBAAiB,KAAK,IAAI,GAC1B,OAAO,GAAG,KAAK;GACnB,IAAI,uBAAuB,KAAK,IAAI,GAChC,OAAO,GAAG,KAAK;GACnB,IAAI,oBAAoB,KAAK,IAAI,GAC7B,OAAO,GAAG,KAAK;GACnB,IAAI,kBAAkB,KAAK,IAAI,GAC3B,OAAO,GAAG,KAAK;GACnB,OAAO,GAAG,KAAK;EACnB;;;;;;EAMA,SAAS,aAAa,SAAS,IAAI;GAC/B,MAAM,SAAS,YAAY,QAAQ,EAAE;GACrC,MAAM,QAAQ,IAAI,SAAS,GAAG,WAAW;IACrC,OAAO,iBAAiB,eAAe;KACnC,MAAM,oBAAI,IAAI,MAAM,UAAU,KAAK,MAAM,KAAK,GAAI,EAAE,QAAQ;KAC5D,EAAE,OAAO;KACT,OAAO,CAAC;IACZ,GAAG,EAAE,MAAM,KAAK,CAAC;GACrB,CAAC;GACD,OAAO,QAAQ,KAAK,CAAC,SAAS,KAAK,CAAC;EACxC;;EAEA,eAAe,UAAU,MAAM,SAAS,QAAQ,SAAS;GACrD,IAAI,OAAO,SAAS,YAChB,OAAO;IAAE,IAAI;IAAO,SAAS;GAAiC;GAClE,IAAI;IACA,MAAM,MAAM,MAAM,aAAa,KAAK,QAAQ,QAAQ,QAAQ,OAAO,EAAE,GAAG;KAAE;KAAQ;IAAQ,GAAG,YAAY,QAAQ,eAAe,CAAC,GAAG,eAAe;IACnJ,IAAI,CAAC,YAAY,GAAG,GAChB,OAAO;KAAE,IAAI;KAAO,SAAS;IAAkB;IACnD,IAAI,CAAC,IAAI,IACL,OAAO;KAAE,IAAI;KAAO,SAAS,sBAAsB,IAAI,OAAO,QAAQ,WAAW,IAAI,OAAO,WAAW,EAAE;IAAE;IAE/G,OAAO;KAAE,IAAI;KAAM,SAAS,IAAI;IAAM;GAC1C,SACO,GAAG;IACN,IAAI,aAAa,UAAU,EAAE,SAAS,gBAAgB,EAAE,SAAS,iBAC7D,OAAO;KAAE,IAAI;KAAO,SAAS,UAAU,KAAK,MAAM,kBAAkB,GAAI,EAAE;IAAS;IAEvF,OAAO;KAAE,IAAI;KAAO,SAAS,QAAQ,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;IAAI;GACtF;EACJ;;EAEA,SAAgB,mBAAmB,MAAM,SAAS;GAC9C,OAAO,UAAU,MAAM,SAAS,yBAAyB,CAAC,CAAC;EAC/D;;EAEA,SAAgB,kBAAkB,MAAM,SAAS,QAAQ;GACrD,OAAO,UAAU,MAAM,SAAS,0BAA0B,EAAE,OAAO,CAAC;EACxE;;EAEA,SAAgB,mBAAmB,MAAM,SAAS;GAC9C,OAAO,UAAU,MAAM,SAAS,2BAA2B,CAAC,CAAC;EACjE;;;;;;;;;;;;;;;;;;EC7KA,SAAgB,aAAa,KAAK;GAC9B,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACnC,OAAO;GACX,MAAM,OAAO;GACb,OAAO,OAAO,KAAK,SAAS,cAAc,OAAO,KAAK,oBAAoB;EAC9E;;EAEA,SAAgB,UAAU,KAAK;GAC3B,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACnC,OAAO;GACX,OAAO,OAAO,IAAI,SAAS;EAC/B;;;;;;;EAOA,SAAgB,aAAa,KAAK;GAC9B,IAAI,aAAa,GAAG,GAChB,OAAO;GACX,OAAO,UAAU,GAAG,IAAI,WAAW;EACvC;;;;;;EAMA,SAAgB,eAAe,KAAK;GAChC,IAAI,OAAO,QAAQ,UACf,OAAO,IAAI,KAAK,MAAM,KAAK,EAAE,MAAM,YAAY,IAAI;IAAE,MAAM;IAAU,MAAM;GAAI;GACnF,MAAM,SAAU,OAAO,QAAQ,YAAY,QAAQ,OAAO,MAAM,CAAC;GACjE,IAAI,OAAO,OAAO,MAAM;IACpB,MAAM,QAAQ,OAAO;IACrB,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,KAAK;KAAE,MAAM;KAAU,MAAM;IAAM,IAAI,EAAE,MAAM,YAAY;GACpH;GACA,MAAM,SAAS,OAAO,OAAO,SAAS,KAAK,KAAK;GAChD,MAAM,OAAO,OAAO,OAAO;GAC3B,OAAO;IACH,MAAM;IACN,GAAI,OAAO,SAAS,YAAY,SAAS,KAAK,EAAE,KAAK,IAAI,CAAC;IAC1D,SAAS,iBAAiB,WAAW,KAAK,KAAK,MAAM,SAAS,OAAO;GACzE;EACJ;;;;EAIA,IAAa,oBAAb,cAAuC,MAAM;GACzC;GACA,YAAY,MAAM,SAAS;IACvB,MAAM,OAAO;IACb,KAAK,OAAO;IACZ,KAAK,OAAO;GAChB;EACJ;;;;;;;;EAQA,SAAgB,iBAAiB,KAAK,MAAM;GACxC,MAAM,SAAU,OAAO,QAAQ,YAAY,QAAQ,OAAO,MAAM,CAAC;GACjE,IAAI,OAAO,OAAO,QAAQ,OAAO,UAAU,KAAA,KAAa,OAAO,UAAU,MACrE,OAAO,OAAO;GAClB,MAAM,SAAS,OAAO,OAAO,SAAS,KAAK,KAAK;GAChD,MAAM,OAAO,OAAO,OAAO;GAC3B,MAAM,IAAI,kBAAkB,OAAO,SAAS,YAAY,SAAS,KAAK,OAAO,iBAAiB,WAAW,KAAK,OAAO,SAAS,MAAM;EACxI;;;;;;;EAOA,SAAgB,aAAa,KAAK;GAC9B,IAAI,CAAC,aAAa,GAAG,GACjB,OAAO;GACX,MAAM,YAAY;GAClB,OAAO;IACH,MAAM,OAAO,SAAS,iBAAiB,SAAS,KAAA,IAAY,MAAM,UAAU,KAAK,IAAI,MAAM,UAAU,KAAK,IAAI,GAAG,MAAM;IACvH,iBAAiB,OAAO,MAAM,SAAS,iBAAiB,MAAM,UAAU,gBAAgB,MAAM,IAAI,GAAG,OAAO;GAChH;EACJ;;EAEA,SAAS,cAAc,MAAM;GACzB,MAAM,OAAO,KAAK,YAAY,IAAI;GAClC,MAAM,QAAQ,KAAK,YAAY,GAAG;GAElC,OAAO,OAAO,QAAQ,OAAO;EACjC;;;;;;EAMA,SAAgB,SAAS,MAAM;GAC3B,MAAM,UAAU,KAAK,QAAQ,WAAW,EAAE;GAC1C,IAAI,YAAY,IACZ,OAAO;GACX,MAAM,MAAM,KAAK,SAAS,IAAI,IAAI,OAAO;GACzC,IAAI,cAAc,KAAK,OAAO,GAC1B,OAAO,UAAU;GACrB,MAAM,MAAM,cAAc,OAAO;GACjC,IAAI,QAAQ,IACR,OAAO;GACX,IAAI,QAAQ,GACR,OAAO,KAAK,MAAM,GAAG,CAAC;GAC1B,IAAI,QAAQ,KAAK,aAAa,KAAK,OAAO,GACtC,OAAO,QAAQ,MAAM,GAAG,CAAC,IAAI;GACjC,OAAO,QAAQ,MAAM,GAAG,GAAG;EAC/B;;EAUA,SAAgB,eAAe,SAAS,YAAY;GAChD,OAAO,aAAa,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,UAAU,CAAC,MAAM,MAAM;EACzF;;EAEA,SAAgB,YAAY,SAAS;GACjC,OAAO,QAAQ,QAAQ,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC;EAC3D;;;;;EAKA,SAAgB,WAAW,OAAO;GAC9B,MAAM,MAAM,cAAc,KAAK;GAC/B,IAAI,QAAQ,IACR,OAAO;IAAE,WAAW;IAAM,QAAQ;GAAM;GAC5C,OAAO;IAAE,WAAW,MAAM,MAAM,GAAG,MAAM,CAAC;IAAG,QAAQ,MAAM,MAAM,MAAM,CAAC;GAAE;EAC9E;;EAEA,SAAgB,cAAc,SAAS,QAAQ;GAC3C,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC,YAAY;GACzC,IAAI,WAAW,IACX,OAAO;GACX,OAAO,QAAQ,QAAQ,UAAU,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC;EAC9E;;;;EAIA,SAAgB,mBAAmB,MAAM;GACrC,MAAM,UAAU,KAAK,KAAK;GAC1B,IAAI,YAAY,IACZ,OAAO;IAAE,IAAI;IAAO,QAAQ;GAAY;GAC5C,IAAI,QAAQ,KAAK,OAAO,GACpB,OAAO;IAAE,IAAI;IAAO,QAAQ;GAAiB;GACjD,IAAI,YAAY,OAAO,YAAY,MAC/B,OAAO;IAAE,IAAI;IAAO,QAAQ;GAAkB;GAClD,OAAO,EAAE,IAAI,KAAK;EACtB;;;;;;;;;;;;ECnKA,SAAgB,uBAAuB,MAAM;GACzC,MAAM,QAAQ,KAAK,gBAAgB;GACnC,MAAM,4BAAY,IAAI,IAAI;GAC1B,IAAI,QAAQ;IACR,OAAO;IACP,SAAS;IACT,SAAS;IACT,UAAU;IACV,YAAY;IACZ,OAAO,KAAK;IACZ,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,OAAO,CAAC;GACZ;;GAEA,IAAI,aAAa;GACjB,MAAM,QAAQ,SAAS;IACnB,QAAQ;KAAE,GAAG;KAAO,GAAG;IAAK;IAC5B,KAAK,MAAM,YAAY,CAAC,GAAG,SAAS,GAChC,SAAS,KAAK;GACtB;;;;GAIA,IAAI,aAAa;GACjB,MAAM,YAAY,YAAY;IAC1B,IAAI,cAAc,KAAK,gBAAgB,KAAA,GACnC;IACJ,aAAa;IACb,IAAI;KACA,MAAM,QAAQ,MAAM,KAAK,YAAY;KACrC,IAAI,MAAM,SAAS,GACf,KAAK,EAAE,MAAM,CAAC;IACtB,QACM,CAEN;GACJ;GACA,MAAM,YAAY,UAAU;IACxB,MAAM,MAAO,OAAO,UAAU,YAAY,UAAU,OAAO,QAAQ,CAAC;IACpE,MAAM,UAAU,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,KAAK,MAAM,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,KAAK;IAEhH,OAAO;KAAE,MADI,OAAO,IAAI,SAAS,YAAY,IAAI,SAAS,KAAK,IAAI,OAAO;KAC3D,SAAS,GAAG,MAAM,GAAG;IAAU;GAClD;GACA,MAAM,OAAO,OAAO,SAAS;IACzB,MAAM,OAAO,EAAE;IACf,KAAK;KAAE,OAAO;KAAW,SAAS;KAAM,QAAQ;IAAK,CAAC;IACtD,IAAI;KACA,MAAM,UAAU,SAAS,OAAO,MAAM,KAAK,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;KAClF,IAAI,SAAS,YACT;KACJ,KAAK;MACD,OAAO;MACP;MACA,SAAS;MACT,UAAU;MACV,OAAO,QAAQ;MACf,QAAQ;KACZ,CAAC;IACL,SACO,OAAO;KACV,IAAI,SAAS,YACT;KACJ,KAAK;MAAE,OAAO;MAAU,SAAS;MAAM,SAAS,SAAS,KAAK;MAAG,UAAU;KAAK,CAAC;IACrF;GACJ;;;;;GAKA,MAAM,cAAc,UAAU;IAC1B,MAAM,EAAE,WAAW,WAAW,WAAW,KAAK;IAC9C,MAAM,UAAU,MAAM;IACtB,MAAM,YAAY,YAAY,QAAQ,cAAc,QAAQ,UAAU,SAAS,MAAM,UAAU,QAAQ,IAAI;IAC3G,KAAK;KAAE;KAAO,QAAQ,YAAY,SAAS;IAAG,CAAC;GACnD;GACA,MAAM,aAAa,SAAS,KAAK,QAAQ,WAAW,EAAE;GACtD,OAAO;IACH,gBAAgB;IAChB,UAAU,UAAU;KAChB,UAAU,IAAI,QAAQ;KACtB,aAAa,UAAU,OAAO,QAAQ;IAC1C;IACA,MAAM,OAAO;KAGT,UAAe;KACf,MAAM,SAAS,KAAK,YAAY,KAAK;KACrC,IAAI,WAAW,IAAI;MACf,MAAM,KAAK,MAAM;MACjB,IAAI,MAAM,UAAU,SAChB,OAAO;KACf;KACA,MAAM,KAAK,IAAI;KACf,OAAO;IACX;IACA,QAAQ,SAAS,KAAK,IAAI;IAC1B,MAAM,KAAK;KACP,MAAM,UAAU,MAAM;KACtB,IAAI,YAAY,MACZ;KACJ,MAAM,SAAS,SAAS,QAAQ,IAAI;KACpC,IAAI,WAAW,QAAQ,MACnB;KACJ,MAAM,KAAK,MAAM;IACrB;IACA,OAAO;KACH,MAAM,SAAS,MAAM,YAAY,MAAM,SAAS,QAAQ;KACxD,IAAI,WAAW,MACX;KACJ,KAAK,SAAS,MAAM;IACxB;IACA,SAAS;KACL,KAAK,QAAQ;IACjB;IACA,QAAQ;KACJ,KAAK,QAAQ;IACjB;IACA,OAAO,MAAM;KACT,KAAK;MAAE,UAAU,MAAM,aAAa,OAAO,OAAO;MAAM,QAAQ;KAAK,CAAC;IAC1E;IACA,eAAe;KACX,KAAK,EAAE,YAAY,CAAC,MAAM,WAAW,CAAC;IAC1C;IACA,SAAS,OAAO;KACZ,WAAW,KAAK;IACpB;IACA,MAAM,cAAc;KAChB,MAAM,UAAU,MAAM,MAAM,KAAK;KACjC,IAAI,YAAY,IACZ;KACJ,MAAM,KAAK,OAAO;IACtB;IACA,YAAY,MAAM;KACd,KAAK;MAAE,UAAU;MAAM,QAAQ;KAAK,CAAC;IACzC;IACA,MAAM,aAAa,MAAM;KACrB,MAAM,UAAU,mBAAmB,IAAI;KACvC,IAAI,CAAC,QAAQ,IAAI;MACb,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC;MAC/B;KACJ;KACA,MAAM,OAAO,MAAM,YAAY,MAAM,SAAS,QAAQ;KACtD,IAAI,SAAS,MAAM;MACf,KAAK,EAAE,QAAQ,qBAAqB,CAAC;MACrC;KACJ;KACA,IAAI;MACA,MAAM,UAAU,MAAM,KAAK,KAAK,gBAAgB,MAAM,KAAK,KAAK,CAAC;MACjE,KAAK;OAAE,UAAU;OAAM,QAAQ;MAAK,CAAC;MACrC,MAAM,KAAK,OAAO;MAClB,KAAK,EAAE,UAAU,QAAQ,CAAC;KAC9B,SACO,OAAO;MACV,MAAM,UAAU,SAAS,KAAK;MAC9B,KAAK;OAAE,QAAQ,QAAQ;OAAS,UAAU;MAAK,CAAC;KACpD;IACJ;GACJ;EACJ;;EAEA,SAAgB,OAAO,OAAO;GAC1B,IAAI,MAAM,YAAY,MAClB,OAAO,CAAC;GACZ,OAAO,cAAc,eAAe,MAAM,SAAS,MAAM,UAAU,GAAG,MAAM,MAAM;EACtF;;EAQA,SAAgB,SAAS,OAAO;GAC5B,OAAO,MAAM,YAAY,MAAM,SAAS,QAAQ;EACpD;;EAMA,SAAgB,SAAS,OAAO;GAC5B,IAAI,MAAM,UAAU,UAChB,OAAO,GAAG,MAAM,SAAS,QAAQ,gBAAgB,KAAK,MAAM;GAChE,IAAI,MAAM,YAAY,MAClB,OAAO,GAAG,MAAM;GACpB,OAAO,GAAG,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAK,CAAC,CAAC,OAAO;EACzD;;;;EAQA,SAAgB,0BAA0B,MAAM;GAC5C,MAAM,aAAa,uBAAuB;IACtC,MAAM,KAAK;IACX,aAAa,KAAK;IAClB,UAAU,KAAK;IACf,eAAe,KAAK,WAAW;IAC/B,GAAI,KAAK,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,KAAK,aAAa;IAC7E,GAAI,KAAK,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,KAAK,YAAY;GAC9E,CAAC;GACD,OAAO;IACH,YAAY,WAAW,KAAK;IAC5B,YAAY,aAAa,WAAW,UAAU,QAAQ;IACtD,aAAa,WAAW,SAAS;IACjC,eAAe,SAAS,WAAW,SAAS,CAAC;IAC7C,SAAS;KACL,cAAc,WAAW,KAAK;KAC9B,eAAe,WAAW,OAAO;KACjC,UAAU,SAAS,KAAK,WAAW,MAAM,IAAI;KAC7C,YAAY,KAAK,WAAW,GAAG;KAC/B,WAAW,SAAS,WAAW,OAAO,IAAI;KAC1C,sBAAsB,WAAW,aAAa;KAC9C,UAAU,UAAU,WAAW,SAAS,KAAK;KAC7C,qBAAqB,KAAK,WAAW,YAAY;KACjD,WAAW,SAAS,KAAK,WAAW,aAAa,IAAI;KACrD,mBAAmB,SAAS,WAAW,YAAY,IAAI;IAC3D;GACJ;EACJ;;;;;;;;;;;;;EAaA,SAAgB,eAAe,OAAO;GAClC,MAAM,OAAO,aAAa,MAAM,MAAM;GACtC,IAAI,SAAS,MACT,OAAO,KAAA;GACX,MAAM,MAAM,0BAA0B;IAClC;IACA,aAAa,MAAM;IACnB,WAAW,WAAW;KAClB,MAAM,SAAS,MAAM;KACrB,MAAM,MAAM,IAAI;IACpB;IACA,gBAAgB,MAAM,MAAM,IAAI;IAChC,GAAI,MAAM,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;GAChF,CAAC;GACD,MAAM,MAAM,GAAG;GACf,OAAO,IAAI,KAAK,CAAC,CAAC,MAAM,YAAY;IAChC,IAAI,QAAQ,UAAU,YAAY,QAAQ,SAAS,SAAS,MAAM,aAAa;KAC3E,MAAM,MAAM,IAAI;KAChB,OAAO;IACX;IACA,OAAO;GACX,CAAC;EACL;;;;;;;;;;;;EClQA,MAAM,iBAAiB;GACnB,OAAO;GACP,SAAS;GACT,WAAW;GACX,SAAS;GACT,OAAO;EACX;EACA,MAAaA,MAAI;GACb,OAAO;IACH,UAAU;IACV,OAAO;IACP,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,gBAAgB;IAChB,QAAQ;GACZ;GACA,QAAQ;IACJ,OAAO;IACP,UAAU;IACV,QAAQ;IACR,WAAW;IACX,SAAS;IACT,eAAe;IACf,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,cAAc;IACd,WAAW;IACX,UAAU;GACd;GACA,MAAM;IACF,SAAS;IACT,YAAY;IACZ,KAAK;IACL,SAAS;IACT,cAAc;GAClB;GACA,OAAO;IAAE,UAAU;IAAI,YAAY;GAAI;GACvC,QAAQ;IAAE,SAAS;IAAQ,UAAU;IAAQ,YAAY;IAAU,KAAK;IAAG,SAAS;IAAc,UAAU;GAAG;GAC/G,cAAc;IACV,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,SAAS;GACb;GACA,UAAU;IAAE,SAAS;IAAM,UAAU;GAAG;GACxC,OAAO;IAAE,SAAS;IAAQ,UAAU;IAAQ,YAAY;IAAU,KAAK;IAAG,SAAS;IAAc,UAAU;GAAG;GAC9G,YAAY;IACR,QAAQ;IACR,cAAc;IACd,SAAS;IACT,SAAS;GACb;GACA,SAAS;IAAE,SAAS;IAAQ,KAAK;IAAG,SAAS;GAAW;GACxD,OAAO;IACH,MAAM;IACN,UAAU;IACV,UAAU;IACV,SAAS;IACT,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,cAAc;GAClB;GACA,QAAQ;IACJ,UAAU;IACV,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,cAAc;GAClB;GACA,WAAW;IAAE,SAAS;IAAM,QAAQ;GAAU;GAC9C,MAAM;IACF,MAAM;IACN,WAAW;IACX,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,cAAc;GAClB;GACA,KAAK;IACD,SAAS;IACT,YAAY;IACZ,KAAK;IACL,OAAO;IACP,SAAS;IACT,WAAW;IACX,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,cAAc;IACd,QAAQ;IACR,UAAU;GACd;GACA,aAAa,EAAE,YAAY,sDAAsD;GACjF,OAAO;IAAE,SAAS;IAAa,UAAU;IAAI,SAAS;GAAI;GAC1D,UAAU;IAAE,SAAS;IAAc,UAAU;IAAI,WAAW;GAAG;GAC/D,MAAM;IACF,SAAS;IACT,YAAY;IACZ,KAAK;IACL,SAAS;IACT,WAAW;GACf;GACA,QAAQ;IAAE,aAAa;IAAQ,UAAU;IAAI,SAAS;IAAK,UAAU;IAAU,cAAc;IAAY,YAAY;GAAS;GAC9H,OAAO,EAAE,OAAO,6CAA6C;EACjE;;EAEA,SAAgB,SAAS,OAAO,SAAS;GACrC,MAAM,UAAU,MAAM;GACtB,IAAI,YAAY,QAAQ,QAAQ,OAAO,WAAW,GAC9C,OAAO;GACX,MAAM,QAAQ,CAAC;GACf,QAAQ,OAAO,SAAS,OAAO,UAAU;IACrC,IAAI,QAAQ,GACR,MAAM,KAAKC,MAAM,cAAc,QAAQ;KAAE,KAAK,SAAS,MAAM;KAAM,OAAOD,IAAE;IAAS,GAAG,GAAG,CAAC;IAChG,MAAM,YAAY,MAAM,SAAS,QAAQ;IACzC,MAAM,KAAKC,MAAM,cAAc,UAAU;KACrC,KAAK,MAAM;KACX,MAAM;KACN,OAAO;MAAE,GAAGD,IAAE;MAAc,YAAY,YAAY,MAAM;KAAI;KAC9D,OAAO,MAAM;KACb,eAAe,QAAQ,MAAM,IAAI;IACrC,GAGA,MAAM,IAAI,CAAC;GACf,CAAC;GACD,OAAOC,MAAM,cAAc,OAAO,EAAE,OAAOD,IAAE,OAAO,GAAG,KAAK;EAChE;;;EAGA,SAAgB,SAAS,OAAO,SAAS;GACrC,IAAI,MAAM,MAAM,SAAS,GACrB,OAAO;GACX,MAAM,QAAQ,MAAM,MAAM,KAAK,SAASC,MAAM,cAAc,UAAU;IAClE,KAAK,KAAK;IACV,MAAM;IACN,OAAO;KAAE,GAAGD,IAAE;KAAc,GAAGA,IAAE;IAAW;IAC5C,OAAO,eAAe,KAAK,SAAS,eAAe;IACnD,eAAe,QAAQ,KAAK,IAAI;GACpC,GAAG,KAAK,IAAI,CAAC;GACb,OAAOC,MAAM,cAAc,OAAO,EAAE,OAAOD,IAAE,MAAM,GAAG,KAAK;EAC/D;;EAEA,SAAgB,SAAS,OAAO,UAAU,QAAQ,gBAAgB,SAAS;GACvE,OAAOC,MAAM,cAAc,OAAO;IAAE,KAAK,MAAM;IAAM,OAAO;KAAE,GAAGD,IAAE;KAAK,SAAS;KAAG,GAAI,WAAWA,IAAE,cAAc,CAAC;IAAG;GAAE,GAAGC,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAO;KAAE,GAAGD,IAAE;KAAK,MAAM;KAAG,QAAQ;IAAO;IAAG,eAAe,QAAQ,MAAM,IAAI;GAAE,GAAG,QAAQ,MAAM,IAAI,GAAGC,MAAM,cAAc,UAAU;IAC/S,MAAM;IACN,OAAO;KAAE,GAAGD,IAAE;KAAQ,aAAa;KAAG,SAAS;IAAU;IACzD,gBAAgB;IAChB,OAAO,WAAW,OAAO,WAAW,OAAO;IAC3C,eAAe,eAAe,MAAM,IAAI;GAC5C,GAAG,WAAW,MAAM,OAAO,MAAM,CAAC;EACtC;;EAEA,SAAgB,UAAU,QAAQ,QAAQ,UAAU,UAAU,cAAc;GACxE,IAAI,iBAAiB,MACjB,OAAO;GACX,OAAOC,MAAM,cAAc,OAAO,EAAE,OAAO;IAAE,GAAGD,IAAE;IAAS,WAAW;GAA+D,EAAE,GAAGC,MAAM,cAAc,SAAS;IACnK,OAAOD,IAAE;IACT,OAAO;IACP,aAAa,OAAO;IACpB,cAAc,OAAO;IACrB,WAAW,UAAU,OAAO,MAAM,cAAc,KAAK;IACrD,YAAY,UAAU;KAClB,IAAI,MAAM,QAAQ,SACd,SAAS,YAAY;KACzB,IAAI,MAAM,QAAQ,UACd,SAAS;IACjB;GACJ,CAAC,GAAGC,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAOD,IAAE;IAAQ,eAAe,SAAS,YAAY;GAAE,GAAG,OAAO,aAAa,GAAGC,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAOD,IAAE;IAAQ,SAAS;GAAS,GAAG,OAAO,YAAY,CAAC;EACnP;;;;;;;;;ECjLA,MAAM,gBAAgB;GAAE,MAAM;GAAI,MAAM;GAAI,QAAQ,CAAC;GAAG,SAAS,CAAC;GAAG,WAAW;EAAM;;EAEtF,SAAgB,iBAAiB,OAAO;GACpC,MAAM,EAAE,MAAM,OAAO,WAAW;GAChC,IAAI,CAAC,MACD,OAAO;GACX,MAAM,OAAO,OAAO,KAAK;GACzB,MAAM,SAAS,SAAS,KAAK;GAE7B,MAAM,SAAS,YADC,MAAM,WAAW,aACC;GAClC,MAAM,OAAO,CAAC;GACd,KAAK,KAAK,SAAS,OAAO,MAAM,OAAO,CAAC;GACxC,KAAK,KAAK,SAAS,OAAO,MAAM,OAAO,CAAC;GACxC,KAAK,KAAKE,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,QAAQ,GAAGD,MAAM,cAAc,SAAS;IACpF,OAAOC,IAAE;IACT,OAAO,MAAM;IACb,aAAa,OAAO;IACpB,cAAc,OAAO;IACrB,WAAW,UAAU,MAAM,QAAQ,MAAM,cAAc,KAAK;IAC5D,YAAY,UAAU;KAClB,IAAI,MAAM,QAAQ,SACd,MAAM,cAAc;IAC5B;GACJ,CAAC,GAAGD,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAOC,IAAE;IAAQ,SAAS,MAAM;GAAK,GAAG,OAAO,EAAE,GAAGD,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAOC,IAAE;IAAQ,SAAS,MAAM;GAAc,GAAG,OAAO,EAAE,CAAC,CAAC;GACpN,KAAK,KAAKD,MAAM,cAAc,OAAO;IAAE,OAAOC,IAAE;IAAM,MAAM;IAAW,cAAc,OAAO;GAAM,GAAG,KAAK,WAAW,IAC/GD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,MAAM,GAAG,MAAM,UAAU,YAAY,OAAO,UAAU,OAAO,KAAK,IACxG,KAAK,KAAK,UAAU,SAAS,OAAO,MAAM,aAAa,MAAM,MAAM,QAAQ,MAAM,UAAU,MAAM,OAAO,CAAC,CAAC,CAAC;GACjH,KAAK,KAAK,UAAU,QAAQ,MAAM,eAAe,MAAM,iBAAiB,IAAI,GAAG,MAAM,UAAU,MAAM,QAAQ,CAAC;GAC9G,KAAK,KAAKD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,SAAS,GAAG,SAAS,IAC/DD,MAAM,cAAc,SAAS,EAAE,OAAO;IAAE,UAAU;IAAI,QAAQ;IAAW,aAAa;GAAG,EAAE,GAAGA,MAAM,cAAc,SAAS;IAAE,MAAM;IAAY,SAAS,MAAM;IAAY,UAAU,MAAM;GAAe,CAAC,GAAG,MAAM,OAAO,WAAW,MAAM,CAAC,IAC5O,MAAM,MAAM,aAAa,OACzBA,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAO;KAAE,GAAGC,IAAE;KAAc,gBAAgB;IAAY;IAAG,eAAe,MAAM,iBAAiB,EAAE;GAAE,GAAG,OAAO,SAAS,IACxK,MAAM,MAAM,WAAW,OAAOD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,MAAM,GAAG,MAAM,MAAM,IAAI,MAAM,MAAM,UAAU,YAAY,MAAM,YAAY,OACjJD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,MAAM,GAAG,MAAM,QAAQ,OAAO,IACpE,IAAI,CAAC;GACX,KAAK,KAAKD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,KAAK,GAAGD,MAAM,cAAc,QAAQ;IAAE,OAAOC,IAAE;IAAQ,OAAO,UAAU;GAAG,GAAG,WAAW,OAAO,KAAK,OAAO,WAAW,MAAM,GAAGD,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAO;KAAE,GAAGC,IAAE;KAAQ,GAAI,WAAW,OAAOA,IAAE,YAAY,CAAC;IAAG;IAAG,SAAS,MAAM;GAAO,GAAG,OAAO,IAAI,GAAGD,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAOC,IAAE;IAAQ,SAAS,MAAM;GAAQ,GAAG,OAAO,MAAM,CAAC,CAAC;GAClb,OAAOD,MAAM,cAAc,OAAO;IAC9B,OAAOC,IAAE;IACT,MAAM;IACN,cAAc,UAAU;KACpB,IAAI,MAAM,WAAW,MAAM,eACvB,MAAM,QAAQ;IACtB;GACJ,GAAGD,MAAM,cAAc,OAAO;IAAE,OAAOC,IAAE;IAAQ,MAAM;IAAU,cAAc;IAAM,cAAc,OAAO;GAAM,GAAGD,MAAM,cAAc,OAAO,EAAE,OAAOC,IAAE,KAAK,GAAGD,MAAM,cAAc,QAAQ,EAAE,OAAOC,IAAE,MAAM,GAAG,OAAO,KAAK,GAG7ND,MAAM,cAAc,UAAU;IAAE,MAAM;IAAU,OAAO;KAAE,GAAGC,IAAE;KAAQ,YAAY;IAAO;IAAG,cAAc,OAAO;IAAO,OAAO,OAAO;IAAO,SAAS,MAAM;GAAQ,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;EACvL;;;;;;;;EAQA,SAAgB,wBAAwB,OAAO;GAC3C,MAAM,QAAQD,MAAM,qBAAqB,MAAM,IAAI,WAAW,MAAM,IAAI,KAAK;GAC7E,OAAO,iBAAiB;IACpB,MAAM,MAAM;IACZ;IACA,QAAQ,MAAM;IACd,GAAG,MAAM,IAAI;GACjB,CAAC;EACL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECzBA,MAAM,YAAY;EAClB,MAAM,UAAU,SAAS,SAAS,SAAS,KAAA,IACrC,sBAAsB,UAAU,GAAG,QAAQ,mBAC3C,sBAAsB,UAAU,GAAG,QAAQ,KAAK,KAAK;;EAE3D,MAAM,kBAAkB,OAAO,EAAE;;EAEjC,MAAM,oBAAoB,OAAO,GAAG,sCAAsC;;EAE1E,MAAM,mBAAmB,OAAO,EAAE;;EAElC,MAAM,sBAAsB,OAAO,EAAE;EACrC,MAAM,IAAI;;;;GAIN,MAAM;IACF,SAAS;IACT,cAAc;IAEd,QAAQ,eAAe;IACvB,YAAY;IACZ,OAAO;IACP,WAAW;GACf;;GAEA,MAAM;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;IAAI,WAAW;GAAG;;GAEtE,OAAO;IAAE,UAAU;IAAU,YAAY;GAAI;;;GAG7C,UAAU,EAAE,WAAW,EAAE;;;;GAIzB,UAAU;IACN,SAAS;IACT,QAAQ;IACR,cAAc;IACd,YAAY;GAChB;;GAEA,WAAW;IACP,WAAW;IACX,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,cAAc;GAClB;;GAEA,WAAW;IACP,SAAS;IACT,YAAY;IACZ,KAAK;IACL,UAAU;IACV,UAAU;GACd;;GAEA,WAAW;IAAE,OAAO;IAAG,QAAQ;IAAG,cAAc;IAAO,MAAM;GAAW;;GAExE,YAAY;IAAE,YAAY;IAAK,YAAY;GAAS;;GAEpD,YAAY;IAAE,OAAO;IAA6C,UAAU;GAAE;;GAE9E,YAAY;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;IAAG,WAAW;GAAE;;;;;GAK1E,YAAY;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,YAAY;IACZ,UAAU;GACd;;GAEA,eAAe;IACX,UAAU;IACV,OAAO;IACP,QAAQ;IACR,cAAc;IACd,SAAS;IACT,YAAY;GAChB;;;GAGA,WAAW;IACP,SAAS;IACT,WAAW;IACX,UAAU;IACV,OAAO;GACX;;GAEA,WAAW;IACP,OAAO;IACP,YAAY;IACZ,aAAa;GACjB;;GAEA,MAAM;IACF,OAAO;IACP,UAAU;IACV,WAAW;GACf;;GAEA,OAAO;IAAE,OAAO;IAA6C,UAAU;GAAS;;GAEhF,OAAO;IACH,WAAW;IACX,OAAO;IACP,UAAU;IACV,YAAY;GAChB;;GAEA,QAAQ;IACJ,WAAW;IACX,OAAO;IACP,UAAU;GACd;;GAEA,MAAM,EAAE,SAAS,QAAQ;;;;GAIzB,KAAK;IACD,UAAU;IACV,SAAS;IACT,UAAU;IACV,YAAY;IACZ,KAAK;IACL,SAAS;IACT,cAAc;GAClB;;GAEA,SAAS;IACL,UAAU;IACV,SAAS;IACT,UAAU;IACV,YAAY;IACZ,KAAK;IACL,SAAS;GACb;;;;;;;;;GASA,aAAa;IACT,UAAU;IACV,SAAS;IACT,UAAU;IACV,YAAY;IACZ,KAAK;IACL,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,cAAc;GAClB;;GAEA,iBAAiB;IACb,UAAU;IACV,SAAS;IACT,UAAU;IACV,YAAY;IACZ,KAAK;IACL,SAAS;IACT,YAAY;IACZ,YAAY;GAChB;;GAEA,QAAQ;IACJ,MAAM;IACN,UAAU;IACV,UAAU;IACV,OAAO;GACX;;;;GAIA,UAAU;IACN,MAAM;IACN,UAAU;IACV,cAAc;IACd,UAAU;IACV,YAAY;IACZ,cAAc;IACd,YAAY;GAChB;;GAEA,SAAS;IACL,UAAU;IACV,OAAO;IACP,KAAK;IACL,SAAS;IACT,KAAK;IACL,YAAY;GAChB;;GAEA,QAAQ;IACJ,UAAU;IACV,OAAO;IACP,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,KAAK;GACT;;GAEA,YAAY,EAAE,SAAS,GAAI;;;GAG3B,QAAQ;IAEJ,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,SAAS;IACT,WAAW;IACX,WAAW;GACf;;;GAGA,OAAO;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;IAAG,YAAY;GAAI;;GAExE,MAAM;IACF,UAAU;IACV,QAAQ;IACR,cAAc;IACd,SAAS;IACT,OAAO;IACP,YAAY;GAChB;;GAEA,MAAM;IACF,OAAO;IACP,UAAU;IACV,WAAW;IACX,YAAY;GAChB;;;GAGA,OAAO;IACH,SAAS;IACT,OAAO;IACP,WAAW;IACX,SAAS;IACT,WAAW;IACX,YAAY;IAGZ,QAAQ,eAAe;IACvB,cAAc;IACd,OAAO;GACX;;;;GAIA,YAAY;IACR,SAAS;IACT,OAAO;IACP,WAAW;IACX,SAAS;IACT,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,OAAO;IACP,WAAW;GACf;;GAEA,UAAU,EAAE,WAAW,EAAE;;GAEzB,MAAM;IAAE,SAAS;IAAQ,KAAK;IAAG,WAAW;IAAG,UAAU;IAAQ,YAAY;GAAS;;;GAGtF,SAAS;IACL,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,YAAY;GAChB;;;GAGA,SAAS;IACL,WAAW;IACX,SAAS;IACT,cAAc;IACd,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,OAAO;GACX;;GAEA,UAAU,EAAE,WAAW,GAAG;;;GAG1B,SAAS;IACL,SAAS;IACT,YAAY;IACZ,KAAK;IACL,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,SAAS;GACb;;GAEA,WAAW,EAAE,OAAO,4CAA4C;;;;GAIhE,WAAW;IACP,WAAW;IACX,SAAS;IAET,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,WAAW;GACf;;;;GAIA,KAAK;IACD,SAAS;IACT,KAAK;IACL,YAAY;IACZ,UAAU;IACV,WAAW;IACX,YAAY;IACZ,WAAW;IACX,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,YAAY;GAChB;;GAEA,SAAS;IACL,YAAY;IACZ,OAAO;IACP,UAAU;GACd;;GAEA,SAAS;IACL,YAAY;IACZ,OAAO;IACP,UAAU;GACd;;;GAGA,KAAK;IACD,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,YAAY;GAChB;;;GAGA,YAAY;IACR,SAAS;IACT,cAAc;IACd,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,YAAY;GAChB;;;;;GAKA,OAAO;IACH,UAAU;IACV,YAAY;IACZ,SAAS;IACT,cAAc;IACd,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,KAAK;IACL,QAAQ;GACZ;;GAEA,UAAU;IAAE,OAAO;IAAG,QAAQ;IAAG,cAAc;IAAO,YAAY;GAAe;;;GAGjF,cAAc;IACV,OAAO;IACP,QAAQ;IACR,cAAc;IACd,QAAQ;IACR,gBAAgB;IAChB,SAAS;GACb;;GAEA,YAAY;IACR,OAAO;IACP,YAAY;IACZ,aAAa;IACb,YAAY;GAChB;;GAEA,WAAW;IACP,OAAO;IACP,YAAY;IACZ,aAAa;IACb,YAAY;GAChB;;GAEA,SAAS;IACL,OAAO;IACP,aAAa;IACb,YAAY;GAChB;;GAEA,UAAU;IACN,OAAO;IACP,YAAY;IACZ,aAAa;IACb,YAAY;GAChB;EACJ;;EAEA,SAAgB,YAAY,OAAO;GAC/B,IAAI,UAAU,QACV,OAAO;GACX,IAAI,UAAU,UACV,OAAO;GACX,OAAO;EACX;;EAEA,SAAgB,aAAa,OAAO;GAChC,IAAI,MAAM,YACN,OAAO;GACX,IAAI,MAAM,MACN,OAAO;GACX,IAAI,MAAM,aACN,OAAO;GACX,IAAI,MAAM,SACN,OAAO;GACX,IAAI,MAAM,aAAa,GACnB,OAAO;GACX,IAAI,MAAM,OACN,OAAO;GACX,OAAO;EACX;;EAEA,SAAgB,YAAY,MAAM,YAAY;GAC1C,IAAI,SAAS,SACT,OAAO,GAAG,WAAW;GACzB,IAAI,SAAS,QACT,OAAO;GACX,IAAI,SAAS,SACT,OAAO;GACX,IAAI,SAAS,WACT,OAAO;GACX,IAAI,SAAS,eACT,OAAO;GACX,OAAO;EACX;;EAEA,SAAS,aAAa,MAAM;GACxB,IAAI,SAAS,WAAW,SAAS,WAC7B,OAAO;IAAE,GAAG,EAAE;IAAO,GAAG,EAAE;GAAW;GACzC,IAAI,SAAS,QACT,OAAO;IAAE,GAAG,EAAE;IAAO,GAAG,EAAE;GAAU;GACxC,IAAI,SAAS,SACT,OAAO;IAAE,GAAG,EAAE;IAAO,GAAG,EAAE;GAAQ;GACtC,IAAI,SAAS,eACT,OAAO;IAAE,GAAG,EAAE;IAAO,GAAG,EAAE;GAAS;GACvC,OAAO,EAAE;EACb;;EAEA,SAAgB,eAAe,OAAO;GAClC,MAAM,OAAO,YAAY,MAAM,MAAM,MAAM,UAAU;GACrD,IAAI,SAAS,IACT,OAAO;GACX,OAAOE,MAAM,cAAc,QAAQ,EAAE,OAAO,aAAa,MAAM,IAAI,EAAE,GAAG,MAAM,SAAS,SACjFA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,IACrDA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,IAAI;EAClE;;;;;;;;;;EAUA,SAAgB,IAAI,OAAO;GACvB,MAAM,EAAE,SAAS;GACjB,MAAM,WAAW,KAAK,aAAa;GACnC,MAAM,WAAW,MAAM,YAAY;GACnC,MAAM,OAAOA,MAAM,cAAc,UAAU;IACvC,OAAO,EAAE;IACT,MAAM;IACN,UAAU,MAAM,WAAW,KAAA;IAC3B,eAAe,MAAM,SAAS,KAAK,KAAK,MAAM,KAAK;GACvD,GAAG,YAAY,MAAM,SAAS,CAAC;GAC/B,MAAM,SAAS,MAAM,WAAW,OAC1BA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAGA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,WAAW,GAAG,GAAG,GAAG,OAAO,IACnH;GACN,IAAI,UAAU;;IAEV,MAAM,WAAW,MAAM,WAAW,OAAQ,MAAM,SAAS,OAAO,EAAE,kBAAkB,EAAE,cAAe,MAAM,SAAS,OAAO,EAAE,UAAU,EAAE;IACzI,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,SAAS,GAAGA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,KAAK,KAAK,GAAGA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,KAAK,GAAGA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,IAAI,CAAC;GACzP;GACA,MAAM,YAAY,MAAM,MAAM,SAAS,KAAK,KAAK,EAAE,OAAO,KAAK;GAC/D,MAAM,UAAU,KAAK,YAAY,WAC3BA,MAAM,cAAc,SAAS;IAC3B,MAAM;IACN,OAAO,EAAE;IACT,SAAS,MAAM,UAAU;IACzB;IACA,WAAW,MAAM,MAAM,SAAS,KAAK,KAAK,EAAE,OAAO,UAAU,SAAS,OAAO;GACjF,CAAC,IACCA,MAAM,cAAc,SAAS;IAC3B,OAAO,MAAM,UAAU,OAAO,EAAE,aAAa,EAAE;IAC/C,MAAM,KAAK,YAAY,WAAW,WAAW;IAC7C,OAAO,MAAM;IACb;IACA,YAAY;IACZ;GACJ,CAAC;;GAEL,MAAM,QAAQ,MAAM,WAAW;GAC/B,MAAM,SAAS,KAAK,YAAY,eAAe,UAAU,QAAQ,MAAM,SAAS,SAC1EA,MAAM,cAAc,UAAU;IAC5B,OAAO,EAAE;IACT,MAAM;IACN;IAEA,eAAe,MAAM,OAAO,KAAK,GAAG;GACxC,GAAG,OAAO,IACR;GACN,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,OAAO,GAAGA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,OAAOA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC,GAAGA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,KAAK,IAAI,GAAG,SAASA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,IAAI,GAAG,MAAM,SAAS,OAClT,OACAA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG,MAAM,MAAM,OAAO,CAAC;EAC/E;;EAEA,MAAM,iBAAiB;GACnB,OAAO;GACP,OAAO;GACP,IAAI;GACJ,iBAAiB;GACjB,IAAI;GACJ,aAAa,MAAM,YAAY,IAAI;GACnC,OAAO;GACP,SAAS;GACT,WAAW;GACX,eAAe;GACf,cAAc;GACd,QAAQ;GACR,UAAU;GACV,MAAM;GACN,QAAQ;GACR,UAAU;EACd;;EAEA,SAAgB,UAAU,OAAO;GAC7B,MAAM,EAAE,OAAO,UAAU;GACzB,MAAM,UAAU,MAAM,SAAS,UAAU,MAAM,UAAU;GACzD,MAAM,WAAW,UAAU,KAAA,IAAY,OAAO,GAAG,MAAM;GACvD,MAAM,cAAc,YAAY,OAAO,KAAK,QAAQ,WAAW,YAAY,QAAQ;GACnF,MAAM,QAAQ,MAAM,SAAS;GAC7B,MAAM,aAAa,QAAQ,MAAM,UAAU,SAAS;GACpD,MAAM,QAAQ,aAAa;IACvB,YAAY,MAAM,SAAS;IAC3B,MAAM,MAAM;IACZ,aAAa,MAAM,eAAe;IAClC,SAAS,MAAM,YAAY;IAC3B;IACA,OAAO,MAAM,WAAW;GAC5B,CAAC;GACD,MAAM,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAGA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAGA,MAAM,cAAc,gBAAgB;IAAE,MAAM;IAAO;GAAW,CAAC,CAAC;;;;;;GAMrL,MAAM,UAAU,MAAM,SAAS;GAC/B,MAAM,aAAa,SAAS,SAAS,OAAOA,MAAM,cAAc,QAAQ;IAAE,OAAO,EAAE;IAAU,uBAAuB;GAAQ,CAAC,IAAI;GACjI,MAAM,WAAW,OAAO,MAAM,SAASA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAGA,MAAM,cAAc,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,KAAK,GAAG,UAAU,IAAI,GAAG,SAAS,KAAA,IAAY,OAAO,IAAI;GAC/L,MAAM,YAAY,CAAC,WAAW,YAAY,OACpC,OACAA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,SAAS,GAAG,QAAQ,QAAQ,YAAY,OAAO,OAAO,QAAQ,MAEtG,YAAY,QAAQ,QAAQ,UACtBA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,eAAe,IAC/D,IAAI,GAAG,QAAQ,QAAQ,YAAY,OAAO,OAAO,WAAW,CAAC;GACvE,MAAM,QAAQ;IAAE,QAAQ;IAAG,OAAO;GAAQ;GAC1C,MAAM,QAAQ,MAAM,UAAU,KAAA,IAAY,OAAO,MAAM,MAAM,KAAK;GAClE,IAAI,MAAM,SAAS,UACf,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,MAAM,WAAWA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,OAAO,GAAG,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,IAAI,GAAGA,MAAM,cAAc,UAAU;IAAE,OAAO,EAAE;IAAK,MAAM;IAAU,SAAS,MAAM;GAAQ,GAAG,IAAI,GAAGA,MAAM,cAAc,UAAU;IAAE,OAAO,EAAE;IAAK,MAAM;IAAU,SAAS,MAAM;GAAQ,GAAG,OAAO,CAAC,CAAC;GAE7X,MAAM,SAAS,MAAM,MAAM,QAAQ,SAAS,KAAK,SAAS,QAAQ;GAClE,MAAM,WAAW,MAAM,MAAM,QAAQ,SAAS,KAAK,SAAS,UAAU;;;GAGtE,MAAM,SAAS,MAAM,QAAQ,CAAC;GAC9B,MAAM,YAAY,MAAM,gBAAgB,CAAC;GACzC,MAAM,aAAa,MAAM,SAASA,MAAM,cAAc,KAAK;IACvD,KAAK,KAAK;IACV;IACA,OAAO,MAAM,MAAM,KAAK,QAAQ;IAChC,UAAU;IACV,UAAU,MAAM;IAChB,SAAS,MAAM;IACf,OAAO,SAAS,MAAM,UAAU,SAAS,KAAK,GAAG;IACjD,QAAQ,SAAS,MAAM,WAAW,SAAS,KAAK,GAAG;IACnD,QAAQ,QAAQ,MAAM,SAAS,KAAA;IAC/B,WAAW,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ,KAAK,MAAO,MAAM,KAAK,KAAK,SAAS,WAAY;IACtG,OAAO,QAAQ,SAAS,SAAS,KAAK,QAAQ,OAAO;IACrD;IACA,QAAQ,UAAU,SAAS,KAAK,GAAG;GACvC,CAAC;;GAED,MAAM,eAAe,SAAS;IAC1B,KAAK,IAAI,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK,GACvC,IAAI,KAAK,EAAE,CAAC,aAAa,MACrB,OAAO;IACf,OAAO;GACX;GACA,MAAM,aAAa,YAAY,MAAM;GACrC,MAAM,eAAe,YAAY,QAAQ;GACzC,MAAM,QAAQ,SAAS,aAAa;GACpC,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,MAAM,WAAWA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,KAAK,MAAM,UAAU,UAAU,MAAM,UAAU,UAAU,CAAC,CAAC,GAAG,SAAS,WAAW,IACvM,OACAA,MAAM,cAAc,WAAW,EAAE,OAAO,EAAE,SAAS,GAAGA,MAAM,cAAc,WAAW,EAAE,OAAO,EAAE,QAAQ,GAAGA,MAAM,cAAc,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,GAAG,GAAG,oBAAoB,GAAGA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,MAAM,UAAU,UAAU,MAAM,UAAU,YAAY,CAAC,CAAC,CAAC,GAAG,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,IAAI,GAAGA,MAAM,cAAc,UAAU;IAAE,OAAO,QAAQ,EAAE,aAAa,EAAE;IAAK,MAAM;IAAU,UAAU,UAAU,CAAC;IAAO,SAAS,MAAM;GAAO,GAAG,MAAM,OAAO,QAAQ,QAAQ,MAAM,WAAW,UAAU,IAAI,GAAGA,MAAM,cAAc,UAAU;IAAE,OAAO,EAAE;IAAK,MAAM;IAAU,UAAU;IAAQ,SAAS,MAAM;GAAQ,GAAG,OAAO,GAAGA,MAAM,cAAc,UAAU;IAAE,OAAO,EAAE;IAAK,MAAM;IAAU,UAAU;IAAQ,SAAS,MAAM;GAAQ,GAAG,MAAM,GAGhyB,QACMA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG,aAAa,WAAW,kBAAkB,IAC3F,QACIA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAG3DA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,MAAM,UAAUA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,4BAA4B,IAAI,MAAM,MAAM,cAAc,OACzLA,MAAM,cAAc,yBAAyB;IAAE,MAAM;IAAM,KAAK,MAAM;IAAW,QAAQ;GAAe,CAAC,IACzG,MAAM,MAAM,eAAe,OAC3BA,MAAM,cAAc,OAAO;IAAE,OAAO,EAAE;IAAO,MAAM;GAAQ,GAAG,MAAM,UAAU,IAC9E,MAAM,MAAM,UAAU,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,MAAM,MAAM,WAAW,OAAOA,MAAM,cAAc,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,MAAM,IAAI,IAAI;EACvM;;;;;;;;;;ECtrBA,SAAS,UAAU,KAAK;GACpB,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACnC,OAAO;GACX,MAAM,MAAM;GACZ,OAAO,OAAO,IAAI,SAAS,YAAY,IAAI,SAAS,MAAM,OAAO,IAAI,SAAS;EAClF;;EAEA,SAAgB,gBAAgB,KAAK;GACjC,MAAM,SAAU,OAAO,QAAQ,YAAY,QAAQ,OAAO,MAAM,CAAC;GACjE,IAAI,OAAO,OAAO,MACd,OAAO,CAAC;GACZ,MAAM,QAAS,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,OAAO,OAAO,QAAQ,CAAC;GAC3F,IAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,GAC1B,OAAO,CAAC;GACZ,OAAO,MAAM,MAAM,OAAO,SAAS,CAAC,CAAC,KAAK,SAAS;IAAE,MAAM,IAAI;IAAM,MAAM,IAAI;GAAK,EAAE;EAC1F;;;;EAIA,SAAgB,kBAAkB,OAAO;GACrC,OAAO,YAAY;IACf,MAAM,OAAO,MAAM,QAAQ;IAC3B,IAAI,OAAO,SAAS,YAChB,OAAO,CAAC;IACZ,IAAI;KACA,OAAO,gBAAgB,MAAM,KAAK,MAAM,MAAM,MAAM,UAAU;MAAE,QAAQ,MAAM;MAAQ,SAAS,CAAC;KAAE,CAAC,CAAC;IACxG,QACM;KACF,OAAO,CAAC;IACZ;GACJ;EACJ;;ECvBA,MAAa,cAAc;;GAEvB,MAAM;;GAEN,SAAS;;GAET,UAAU;;GAEV,MAAM;EACV;;EAEA,MAAa,kBAAkB;;GAE3B,SAAS;;;;;;;GAOT,SAAS;;;;;;GAMT,SAAS;;;;;;;GAOT,OAAO;EACX;;;;;;;;;;;;;;;;;;;;;ECxBA,SAAS,aAAa,KAAK;GACvB,IAAI,OAAO,QAAQ,YAAY,QAAQ,MACnC,OAAO;GACX,OAAO,OAAO,IAAI,SAAS;EAC/B;;EAEA,SAAS,cAAc,YAAY;GAC/B,IAAI,eAAe,KAAA,GACf,OAAO;GACX,IAAI;IACA,MAAM,MAAM,WAAW,uBAAuB;IAC9C,OAAO,aAAa,GAAG,IAAI,MAAM;GACrC,QACM;IACF,OAAO;GACX;EACJ;;EAEA,eAAe,cAAc,QAAQ;GACjC,IAAI;IACA,OAAO,eAAe,MAAM,OAAO,KAAK,CAAC;GAC7C,SACO,GAAG;IAEN,OAAO;KAAE,MAAM;KAAe,SAAS,kBADxB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,KACS;IAAiB;GACtF;EACJ;;;;;EAKA,eAAe,eAAe,MAAM;GAChC,IAAI;IAEA,MAAM,OADM,WAAW,WACL;IAClB,IAAI,SAAS,KAAA,KAAa,OAAO,KAAK,cAAc,YAChD,OAAO;IACX,MAAM,KAAK,UAAU,IAAI;IACzB,OAAO;GACX,QACM;IACF,OAAO;GACX;EACJ;;;;;;;EAOA,SAAgB,eAAe,OAAO,MAAM;GACxC,IAAI,SAAS,KAAA,GACT,OAAO,CAAC;GACZ,MAAM,sBAAM,IAAI,IAAI;GACpB,KAAK,MAAM,QAAQ,OACf,KAAK,MAAM,OAAO,KAAK,CAAC,KAAK,GAAG,CAAC,GAC7B,IAAI,IAAI,GAAG;GACnB,OAAO,CAAC,GAAG,GAAG;EAClB;;EAEA,SAAgB,YAAY,OAAO;GAC/B,MAAM,CAAC,OAAO,YAAYC,MAAM,SAAS,EAAE,MAAM,UAAU,CAAC;GAC5D,MAAM,CAAC,YAAY,iBAAiBA,MAAM,SAAS,KAAK;GACxD,MAAM,CAAC,SAAS,cAAcA,MAAM,SAAS,KAAK;GAClD,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,CAAC,CAAC;GAC3C,MAAM,CAAC,MAAM,WAAWA,MAAM,SAAS,KAAK;GAC5C,MAAM,CAAC,QAAQ,aAAaA,MAAM,SAAS,IAAI;GAC/C,MAAM,CAAC,YAAY,iBAAiBA,MAAM,SAAS,IAAI;GACvD,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,IAAI;GAC7C,MAAM,CAAC,WAAW,gBAAgBA,MAAM,SAAS,IAAI;GACrD,MAAM,CAAC,MAAM,WAAWA,MAAM,SAAS,IAAI;;;GAG3C,MAAM,YAAYA,MAAM,OAAO,IAAI;GACnC,MAAM,sBAAsB;IACxB,IAAI,UAAU,YAAY,MAAM;KAC5B,aAAa,UAAU,OAAO;KAC9B,UAAU,UAAU;IACxB;GACJ,GAAG,CAAC,CAAC;;GAEL,MAAM,gBAAgB;IAClB,IAAI,QAAQ;IACZ,CAAM,YAAY;KACd,MAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,GAAG,MAAM,OAAO;KACjE,IAAI,CAAC,OACD;KACJ,IAAI,EAAE,IAAI;MACN,SAAS;OAAE,MAAM;OAAS,SAAS,EAAE;MAAQ,CAAC;MAC9C,SAAS,QAAQ,MAAM,OAAO,EAAE,QAAQ,QAAQ,EAAE,OAAO,CAAC;KAC9D,OAEI,SAAS;MAAE,MAAM;MAAU,SAAS,EAAE;KAAQ,CAAC;IAEvD,EAAA,CAAG;IACH,aAAa;KACT,QAAQ;IACZ;GAGJ,GAAG,CAAC,CAAC;;GAEL,MAAM,SAAS,YAAY;IACvB,SAAS;KAAE,MAAM;KAAS;IAAQ,CAAC;IACnC,SAAS,QAAQ,MAAM,OAAO,QAAQ,QAAQ,OAAO,CAAC;GAC1D;GACA,MAAM,OAAO,YAAY;IACrB,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,SAAS,IAAI;IACb,MAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,GAAG,MAAM,OAAO;IACjE,IAAI,EAAE,IACF,MAAM,EAAE,OAAO;SAEf,SAAS;KAAE,MAAM;KAAU,SAAS,EAAE;IAAQ,CAAC;GACvD;;;GAGA,MAAM,kBAAkB,OAAO,SAAS;IACpC,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,SAAS,IAAI;IACb,MAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,GAAG,MAAM,OAAO;IACjE,IAAI,EAAE,IAAI;KACN,MAAM,EAAE,OAAO;KACf,UAAU,IAAI;IAClB,OAEI,SAAS;KAAE,MAAM;KAAU,SAAS,EAAE;IAAQ,CAAC;IAEnD,QAAQ,KAAK;GACjB;GACA,MAAM,YAAY,KAAK,SAAS;IAC5B,UAAU,UAAU;KAAE,GAAG;MAAO,MAAM;IAAK,EAAE;IAC7C,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,SAAS,IAAI;GACjB;GACA,MAAM,SAAS,aAAa,OAAO,cAAc,MAAM,UAAU;;GAEjE,MAAM,aAAa,OAAO,QAAQ;IAC9B,MAAM,OAAO,aAAa,OAAO,cAAc,MAAM,UAAU;IAC/D,IAAI,SAAS,MACT;IAEJ,WAAW,IAAI;IACf,SAAS,IAAI;IACb,MAAM,UAAU,MAAM,cAAc,IAAI;IACxC,WAAW,KAAK;IAChB,IAAI,QAAQ,SAAS,UACjB,SAAS,KAAK,QAAQ,IAAI;SACzB,IAAI,QAAQ,SAAS,eAAe;KACrC,SAAS,QAAQ,OAAO;KACxB,cAAc,IAAI;IACtB;GACJ;;GAEA,MAAM,YAAY,OAAO,QAAQ;IAC7B,SAAS,IAAI;IACb,MAAM,SAAS,eAAe;KAC1B;KACA,aAAa,MAAM,QAAQ;KAC3B,WAAW,SAAS,SAAS,KAAK,IAAI;KACtC,OAAO;KACP,aAAa;KACb,aAAa,kBAAkB;MAC3B,SAAS,MAAM;MACf,MAAM,YAAY;MAClB,UAAU,YAAY;MACtB,QAAQ,gBAAgB;KAC5B,CAAC;IACL,CAAC;IACD,IAAI,WAAW,KAAA,KAAc,MAAM,WAAY,WAC3C,MAAM,WAAW,GAAG;GAC5B;;GAEA,MAAM,UAAU,KAAK,SAAS;IAC1B,eAAoB,IAAI,CAAC,CAAC,MAAM,OAAO;KACnC,QAAQ;MAAE;MAAK;KAAG,CAAC;KACnB,IAAI,UAAU,YAAY,MACtB,aAAa,UAAU,OAAO;KAClC,UAAU,UAAU,iBAAiB;MACjC,UAAU,UAAU;MACpB,QAAQ,IAAI;KAChB,GAAG,gBAAgB;IACvB,CAAC;GACL;GACA,MAAM,SAAS,YAAY;IACvB,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,SAAS,IAAI;IACb,MAAM,IAAI,MAAM,kBAAkB,MAAM,QAAQ,GAAG,MAAM,SAAS,UAAU,MAAM,OAAO,KAAK,CAAC;IAC/F,QAAQ,KAAK;IACb,IAAI,EAAE,IACF,MAAM,gBAAgB,kBAAkB;SAExC,cAAc,EAAE,OAAO;GAC/B;GACA,MAAM,UAAU,YAAY;IACxB,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,cAAc,IAAI;IAClB,SAAS,IAAI;IACb,MAAM,IAAI,MAAM,mBAAmB,MAAM,QAAQ,GAAG,MAAM,OAAO;IACjE,QAAQ,KAAK;IACb,IAAI,EAAE,IACF,MAAM,gBAAgB,uBAAuB;SAE7C,cAAc,EAAE,OAAO;GAC/B;GACA,MAAM,UAAU,MAAM,SAAS,UAAU,MAAM,UAAU;GACzD,MAAM,WAAW,YAAY,OAAO,QAAQ,MAAM,OAAO,QAAQ,QAAQ,OAAO,IAAI;GACpF,MAAM,YAAY,aAAa,OAAO,CAAC,IAAI,YAAY,MAAM,OAAO,OAAO,QAAQ;GACnF,MAAM,cAAc,MAAM,gBAAgB,aAAA,CAAc,SAAS;;GAEjE,MAAM,WAAW,YAAY,QAAQ,QAAQ,WAAW,KAAA,KAAa,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,SAAS;;GAE1G,MAAM,eAAe,eAAe,MAAM,OAAO,MAAM,YAAY;GACnE,MAAM,OAAO,aAAa,MAAM;GAChC,MAAM,WAAW,SAAS,SAAS,OAAO;IAAE;IAAM,QAAQ;GAAU;GACpE,OAAOA,MAAM,cAAc,WAAW;IAClC,OAAO,MAAM;IACb,OAAO,MAAM;IACb;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,SAAS;IACT;IACA;IACA;IACA,cAAc,KAAK,OAAO;IAC1B,eAAe,KAAK,QAAQ;IAC5B,eAAe,KAAK,KAAK;IACzB,OAAO,MAAM;GACjB,CAAC;EACL;;;;;;;;;;;;ECtQA,MAAa,cAAc;;;ECE3B,MAAa,aAAa;EAC1B,MAAa,SAAS;;;;ECsDtB,MAAM,SAAgC;GACpC;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,SAAS;IAET,aAAa;IACb,MAAM;GACR;GACA;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,SAAS;IACT,UAAU;IACV,aAAa;IACb,MAAM;GACR;GACA;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,SAAS;IACT,UAAU;IACV,aAAa;IACb,MAAM;GACR;GACA;IACE,KAAK;IACL,OAAO;IACP,MAAM;IACN,SAAS;IACT,UAAU;IACV,aAAa;IACb,MAAM;GACR;EACF;;EAGA,MAAM,WAAkC,CACtC;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,SAAS;GACT,UAAU;GACV,aAAa;GACb,MAAM;EACR,GACA;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,SAAS;GACT,UAAU;GACV,aAAa;GACb,MAAM;EACR,CACF;;EAGA,MAAa,eAAsC,CAAC,GAAG,QAAQ,GAAG,QAAQ;EAGzC,OAAO;;;;;;;;;;;;;;;;;;;;;;ECzGxC,MAAa,SAA4B,CAAC,SAAS,YAAY;;EAG/D,MAAM,eAAkC;GAAC;GAAW;GAAY;GAAY;GAAc;EAAa;;EAGvG,SAAgB,aAAa,WAAiD;GAC5E,OAAO,UAAU,SAAS,QAAQ,IAAI,CAAC,GAAG,YAAY,IAAI,CAAC;EAC7D;EAEA,SAAgB,MAAM,KAAsB;GAE1C,MAAM,gBAAyB,IAAI,YAAY,KAAK,QAAQ;GAG5D,MAAM,cAAc,SAA2B,OAAO,IAAI,QAAQ,aAAa,IAAI,IAAI,IAAI,IAAI,KAAA;GAG/F,IAAI,MAAM,OAAO,0BACf,IAAI,MAAM,SACR;IACE,MAAM;IACN,IAAI;IACJ,OAAA;IACA,aAAa;IAGb,SAAS;GACX,SACMC,MAAM,cAAc,aAAa;IACrC,SAAS;IACT,OAAO;IACP,OAAO;IACP;IACA;IACA;GACF,CAAC,CACH,CACF;EACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const inject: readonly string[];
|
|
|
4
4
|
export declare function apply(ctx: SkillHostCtx): void;
|
|
5
5
|
export { SKILL, SLOT_ID, SLOT_ORDER, SLOT_TITLE, PLUGIN, MANAGER_PLUGIN, slotDescriptor, TAB_COMPONENT, registerSingle, openSingle } from './slot.js';
|
|
6
6
|
export type { SlotDescriptor, TabsPort } from './slot.js';
|
|
7
|
-
export { SETTINGS_OWNER, SETTINGS_SLOT, CONFIG_STEM, CONFIG_ITEMS, COMMON_ITEM_COUNT, ADVANCED_GROUP_TITLE,
|
|
7
|
+
export { SETTINGS_OWNER, SETTINGS_SLOT, CONFIG_STEM, CONFIG_ITEMS, COMMON_ITEM_COUNT, ADVANCED_GROUP_TITLE, readPath, writePath } from './settings.js';
|
|
8
8
|
export type { ConfigItem, ConfigTier, ConfigControl } from './settings.js';
|
|
9
9
|
export { SKILL_PACKAGE, SKILL_CLI, SKILL_CLI_REL, HOST_CALL_METHOD, MANAGER_MISSING_HINT, SkillBridgeError, cliPath, assertCliPresent, handleHostCall, requestViaHost, readViaCli, readConfigSurface, writeConfigValues, resetConfigToDefaults, readConfigHealth, CONFIG_READ_KEY, CONFIG_WRITE_KEY, CONFIG_RESET_KEY, CONFIG_CHECK_KEY } from './bridge.js';
|
|
10
10
|
export { RPC_CHANNEL, RPC_ENDPOINT_READ, RPC_ENDPOINT_CONFIG_GET, RPC_ENDPOINT_CONFIG_SAVE, RPC_ENDPOINT_CONFIG_RESET, RPC_ENDPOINT_CONFIG_CHECK, ok, fail, parseReadPayload, parseSavePayload, isRpcResult } from './contract.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,cAAc,CAAC;AAG7D,eAAO,MAAM,IAAI,mBAAmB,CAAC;AACrC,eAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EAAmD,CAAC;AAsCxF,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAgE7C;AAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtJ,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,cAAc,CAAC;AAG7D,eAAO,MAAM,IAAI,mBAAmB,CAAC;AACrC,eAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EAAmD,CAAC;AAsCxF,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAgE7C;AAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtJ,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvJ,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7V,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACnO,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAKvG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChK,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,qBAAqB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -134,7 +134,7 @@ export function apply(ctx) {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
export { SKILL, SLOT_ID, SLOT_ORDER, SLOT_TITLE, PLUGIN, MANAGER_PLUGIN, slotDescriptor, TAB_COMPONENT, registerSingle, openSingle } from './slot.js';
|
|
137
|
-
export { SETTINGS_OWNER, SETTINGS_SLOT, CONFIG_STEM, CONFIG_ITEMS, COMMON_ITEM_COUNT, ADVANCED_GROUP_TITLE,
|
|
137
|
+
export { SETTINGS_OWNER, SETTINGS_SLOT, CONFIG_STEM, CONFIG_ITEMS, COMMON_ITEM_COUNT, ADVANCED_GROUP_TITLE, readPath, writePath } from './settings.js';
|
|
138
138
|
export { SKILL_PACKAGE, SKILL_CLI, SKILL_CLI_REL, HOST_CALL_METHOD, MANAGER_MISSING_HINT, SkillBridgeError, cliPath, assertCliPresent, handleHostCall, requestViaHost, readViaCli, readConfigSurface, writeConfigValues, resetConfigToDefaults, readConfigHealth, CONFIG_READ_KEY, CONFIG_WRITE_KEY, CONFIG_RESET_KEY, CONFIG_CHECK_KEY } from './bridge.js';
|
|
139
139
|
export { RPC_CHANNEL, RPC_ENDPOINT_READ, RPC_ENDPOINT_CONFIG_GET, RPC_ENDPOINT_CONFIG_SAVE, RPC_ENDPOINT_CONFIG_RESET, RPC_ENDPOINT_CONFIG_CHECK, ok, fail, parseReadPayload, parseSavePayload, isRpcResult } from './contract.js';
|
|
140
140
|
// #310 拆雷(照 #218 大厨/居家样板):宿主**不**导出 `./client.js` 的值也不引用它的类型——
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/settings.d.ts
CHANGED
|
@@ -63,7 +63,6 @@ export declare const CONFIG_ITEMS: readonly ConfigItem[];
|
|
|
63
63
|
export declare const COMMON_ITEM_COUNT: number;
|
|
64
64
|
/** 高级组标题与副文案。 */
|
|
65
65
|
export declare const ADVANCED_GROUP_TITLE: "\u9AD8\u7EA7";
|
|
66
|
-
export declare const ADVANCED_GROUP_NOTE: "\u4E0D\u5E38\u6539\u3002\u7559\u7A7A\uFF1D\u7528\u9ED8\u8BA4\u503C\u3002";
|
|
67
66
|
/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */
|
|
68
67
|
export declare function readPath(values: Record<string, unknown>, key: string): unknown;
|
|
69
68
|
/** 按 `a.b` 路径把值写进配置取值(中间层缺就建一层空组;已存在非组即覆盖成组)。 */
|
package/dist/settings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,EAAG,gBAAyB,CAAC;AACxD,eAAO,MAAM,aAAa,EAAG,cAAuB,CAAC;AAErD,uCAAuC;AACvC,eAAO,MAAM,WAAW,EAAG,MAAe,CAAC;AAE3C,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C;qEACqE;AACrE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvE,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;AAExG,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;yDACqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;uDACmD;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC;4DACwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;CAClC;AAgED,sBAAsB;AACtB,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAA6B,CAAC;AAE5E,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,QAAgB,CAAC;AAE/C,iBAAiB;AACjB,eAAO,MAAM,oBAAoB,EAAG,cAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,EAAG,gBAAyB,CAAC;AACxD,eAAO,MAAM,aAAa,EAAG,cAAuB,CAAC;AAErD,uCAAuC;AACvC,eAAO,MAAM,WAAW,EAAG,MAAe,CAAC;AAE3C,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C;qEACqE;AACrE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvE,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;AAExG,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;yDACqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;uDACmD;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC;4DACwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;CAClC;AAgED,sBAAsB;AACtB,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAA6B,CAAC;AAE5E,0BAA0B;AAC1B,eAAO,MAAM,iBAAiB,QAAgB,CAAC;AAE/C,iBAAiB;AACjB,eAAO,MAAM,oBAAoB,EAAG,cAAa,CAAC;AAElD,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQ9E;AAED,iDAAiD;AACjD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAU5F"}
|
package/dist/settings.js
CHANGED
|
@@ -97,7 +97,6 @@ export const CONFIG_ITEMS = [...COMMON, ...ADVANCED];
|
|
|
97
97
|
export const COMMON_ITEM_COUNT = COMMON.length;
|
|
98
98
|
/** 高级组标题与副文案。 */
|
|
99
99
|
export const ADVANCED_GROUP_TITLE = '高级';
|
|
100
|
-
export const ADVANCED_GROUP_NOTE = '不常改。留空=用默认值。';
|
|
101
100
|
/** 按 `a.b` 路径从配置取值里读(缺层或类型不符一律回 undefined)。 */
|
|
102
101
|
export function readPath(values, key) {
|
|
103
102
|
const parts = key.split('.');
|
package/dist/settings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAyB,CAAC;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,cAAuB,CAAC;AAErD,uCAAuC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,MAAe,CAAC;AAgC3C,+BAA+B;AAC/B,MAAM,MAAM,GAA0B;IACpC;QACE,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,WAAW;QACpB,6DAA6D;QAC7D,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,sBAAsB;KAC7B;IACD;QACE,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,QAAQ;QACrB,IAAI,EAAE,YAAY;KACnB;IACD;QACE,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,gBAAgB;KACvB;IACD;QACE,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,iBAAiB;KACxB;CACF,CAAC;AAEF,qCAAqC;AACrC,MAAM,QAAQ,GAA0B;IACtC;QACE,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,aAAa;KACpB;IACD;QACE,GAAG,EAAE,aAAa;QAClB,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,cAAc;QAC3B,IAAI,EAAE,oBAAoB;KAC3B;CACF,CAAC;AAEF,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC;AAE5E,0BAA0B;AAC1B,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;AAE/C,iBAAiB;AACjB,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bill-ilife",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
4
|
"description": "爱生活单品插件 P10 脚手架:记账(ilife:cookie order 95),硬依赖总管 dsh-life-pack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"node": ">=22.13"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"dsh-life-pack": "
|
|
34
|
-
"skill-bill": "0.3.
|
|
33
|
+
"dsh-life-pack": "0.3.15",
|
|
34
|
+
"skill-bill": "0.3.15"
|
|
35
35
|
},
|
|
36
36
|
"dsh": {
|
|
37
37
|
"bundle": {
|