dsh-chef 0.3.40 → 0.3.42
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 +366 -50
- package/dist/client.js.map +1 -1
- package/package.json +2 -2
package/dist/client.js
CHANGED
|
@@ -1208,6 +1208,233 @@ window.__ModuleLoader__.load({
|
|
|
1208
1208
|
}, react.createElement("span", { style: S$2.product }, props.product), react.createElement("span", { style: S$2.purpose }, props.purpose));
|
|
1209
1209
|
}
|
|
1210
1210
|
//#endregion
|
|
1211
|
+
//#region ../plugin-manager/src/seal-paper-schemes.ts
|
|
1212
|
+
/** 卷轴纸面字排 + 关闭钮样子 · **定稿件**(2026-10-06 定档,原型选型期结束)。
|
|
1213
|
+
*
|
|
1214
|
+
* 定稿形状(逐值锁死,改动须同步 `test/seal-scroll.test.mjs` 与 `test/seal-bundle-1158.test.mjs`):
|
|
1215
|
+
* 纸面:三段紧凑行内(进展/状态/计划),行首一枚朱砂小方印(进/状/计),标签与正文同行基线对齐;
|
|
1216
|
+
* 末行吃回 0.5em 行距(不然底比顶空一截);饰线上距加宽到 `0.5em 0 0.75em`;纸底与头部沿用原样式。
|
|
1217
|
+
* 档位语:该档金属渐变压进字里(金=鎏金/银=冷银/铜=暖铜),不再一律金。
|
|
1218
|
+
* 关闭钮:右上角斜披的朱砂菱形绦带(正立「收卷」字独立成层),两条飘尾沿菱形两条下边各向底尖收,
|
|
1219
|
+
* 各自朝外 26°(左尾朝左下、右尾朝右下);尾是两层——外层过糙边出毛边,内层纯色芯不受滤镜。
|
|
1220
|
+
*
|
|
1221
|
+
* 为什么单独一件:`seal-scroll.ts` 已接近告警线(外框/纸/浮层/滤镜都住那里),纸面字排与关闭钮住这里。
|
|
1222
|
+
* 本件是纯函数:吃 ctx 回五件,不留状态、不取数。原型期的二十余档方案已按「定稿后只留胜出那一档」删除。
|
|
1223
|
+
*/
|
|
1224
|
+
/** 材质底层:**糙边滤镜只挂这一层**——文字住在它外面,所以字是清晰的(照插件章「金属带+印文」的老做法)。 */
|
|
1225
|
+
function bgLayer(style, children) {
|
|
1226
|
+
return react.createElement("span", {
|
|
1227
|
+
"aria-hidden": true,
|
|
1228
|
+
style: {
|
|
1229
|
+
position: "absolute",
|
|
1230
|
+
inset: 0,
|
|
1231
|
+
...style
|
|
1232
|
+
}
|
|
1233
|
+
}, children ?? null);
|
|
1234
|
+
}
|
|
1235
|
+
/** 清晰字面:压在材质层之上,不参与任何滤镜。 */
|
|
1236
|
+
function crisp(text, style) {
|
|
1237
|
+
return react.createElement("span", { style: {
|
|
1238
|
+
position: "relative",
|
|
1239
|
+
zIndex: 1,
|
|
1240
|
+
...style
|
|
1241
|
+
} }, text);
|
|
1242
|
+
}
|
|
1243
|
+
/** 档位语三档金属(鎏金/冷银/暖铜):主色+渐变(`backgroundClip:text` 描出金属光泽)。 */
|
|
1244
|
+
const TIER_METAL = {
|
|
1245
|
+
gold: {
|
|
1246
|
+
flat: "#b8912a",
|
|
1247
|
+
gradient: "linear-gradient(180deg,#f6e27a 0%,#d9b53c 45%,#a5811b 100%)"
|
|
1248
|
+
},
|
|
1249
|
+
silver: {
|
|
1250
|
+
flat: "#8b959d",
|
|
1251
|
+
gradient: "linear-gradient(180deg,#f7fafc 0%,#c3ccd3 45%,#8b959d 100%)"
|
|
1252
|
+
},
|
|
1253
|
+
copper: {
|
|
1254
|
+
flat: "#a8663a",
|
|
1255
|
+
gradient: "linear-gradient(180deg,#f0bd8e 0%,#c07b45 45%,#8a4a24 100%)"
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
/** 档位金属边(铜/银/金):章与绦带共用这一份取值。 */
|
|
1259
|
+
const TIER_EDGE = {
|
|
1260
|
+
gold: "#f5d97a",
|
|
1261
|
+
silver: "#d8dee3",
|
|
1262
|
+
copper: "#a5652f"
|
|
1263
|
+
};
|
|
1264
|
+
const KAI = "\"Kaiti SC\",\"KaiTi\",\"STKaiti\",serif";
|
|
1265
|
+
/** 关闭钮(定稿:绦带·飘尾)。右上角一枚斜披 45° 的朱砂菱形,两条飘尾分挂两条下边,尾先画、带后画压住尾根。 */
|
|
1266
|
+
function closeLook(tierKey) {
|
|
1267
|
+
const crimson = "linear-gradient(135deg,#c63d2a 8%,#a32216 50%,#7e1a10)";
|
|
1268
|
+
/** 档位金属边(铜/银/金):绦带**只借这一条**——主体恒朱砂,边随档走,跟章「红底+金属边」同构。 */
|
|
1269
|
+
const edge = TIER_EDGE[tierKey] ?? TIER_EDGE["gold"];
|
|
1270
|
+
const ribbon = bgLayer({
|
|
1271
|
+
borderRadius: "0.375em",
|
|
1272
|
+
background: crimson,
|
|
1273
|
+
boxShadow: "0 0 0 1px #5c110a59, 0 2px 8px #3d241066, inset 0 0 0 2px " + edge,
|
|
1274
|
+
transform: "rotate(45deg)",
|
|
1275
|
+
filter: "url(#" + SEAL_ROUGH_METAL_ID + ")"
|
|
1276
|
+
}, null);
|
|
1277
|
+
/** 尾色=绦带上亮一档的朱砂(悬在纸上也不发灰、不发黑):两条尾同色。 */
|
|
1278
|
+
const TAIL_FILL = "linear-gradient(180deg,#e8573c 0%,#c33a24 55%,#a52612 100%)";
|
|
1279
|
+
/** 飘尾:屏幕坐标(不随菱形旋转)——左尾往左下、右尾往右下(CSS 正角=尾梢往左)。
|
|
1280
|
+
* 两层:外层过糙边滤镜出毛边,内层纯色芯不受滤镜——尾悬在纸上还是悬在暗底上都是同一色。 */
|
|
1281
|
+
const loose = (key, left, deg, len, top) => react.createElement("span", {
|
|
1282
|
+
key,
|
|
1283
|
+
"aria-hidden": true,
|
|
1284
|
+
style: {
|
|
1285
|
+
position: "absolute",
|
|
1286
|
+
left,
|
|
1287
|
+
top,
|
|
1288
|
+
width: "0.4375em",
|
|
1289
|
+
height: len,
|
|
1290
|
+
transformOrigin: "top center",
|
|
1291
|
+
transform: "rotate(" + deg + "deg)"
|
|
1292
|
+
}
|
|
1293
|
+
}, bgLayer({
|
|
1294
|
+
borderRadius: "0 0 0.1875em 0.1875em",
|
|
1295
|
+
background: TAIL_FILL,
|
|
1296
|
+
boxShadow: "0 0 0 1.5px " + edge + "cc, 0 1px 3px #00000055",
|
|
1297
|
+
filter: "url(#" + SEAL_ROUGH_METAL_ID + ")"
|
|
1298
|
+
}), react.createElement("span", {
|
|
1299
|
+
"aria-hidden": true,
|
|
1300
|
+
style: {
|
|
1301
|
+
position: "absolute",
|
|
1302
|
+
inset: "0.5px",
|
|
1303
|
+
borderRadius: "0 0 0.15625em 0.15625em",
|
|
1304
|
+
background: TAIL_FILL
|
|
1305
|
+
}
|
|
1306
|
+
}));
|
|
1307
|
+
return {
|
|
1308
|
+
label: crisp("收卷", {
|
|
1309
|
+
fontFamily: KAI,
|
|
1310
|
+
fontSize: "0.8125em",
|
|
1311
|
+
letterSpacing: "0.22em",
|
|
1312
|
+
textIndent: "0.22em",
|
|
1313
|
+
color: "#f8f1e2",
|
|
1314
|
+
textShadow: "0 1px 2px #000000aa"
|
|
1315
|
+
}),
|
|
1316
|
+
decor: react.createElement(react.Fragment, null, loose("tL", "calc(50% - 0.8125em)", 26, "2em", "2.8125em"), loose("tR", "calc(50% + 0.4375em)", -26, "2em", "2.8125em"), ribbon),
|
|
1317
|
+
style: {
|
|
1318
|
+
boxSizing: "border-box",
|
|
1319
|
+
padding: 0,
|
|
1320
|
+
position: "absolute",
|
|
1321
|
+
right: "-1.5em",
|
|
1322
|
+
top: "-1.5em",
|
|
1323
|
+
width: "3.25em",
|
|
1324
|
+
height: "3.25em",
|
|
1325
|
+
display: "flex",
|
|
1326
|
+
alignItems: "center",
|
|
1327
|
+
justifyContent: "center",
|
|
1328
|
+
cursor: "pointer",
|
|
1329
|
+
border: "none",
|
|
1330
|
+
background: "transparent"
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
/** 画一条饰线(方向 90/270 决定渐变朝向;定稿的段上距是 0.5em 0 0.75em)。 */
|
|
1335
|
+
function ornament(st, ruler) {
|
|
1336
|
+
const line = (key, dir) => react.createElement("span", {
|
|
1337
|
+
key,
|
|
1338
|
+
style: {
|
|
1339
|
+
...st.ornLine,
|
|
1340
|
+
background: "linear-gradient(" + dir + "deg,#0000," + ruler + ")"
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1343
|
+
return react.createElement("div", { style: {
|
|
1344
|
+
...st.orn,
|
|
1345
|
+
margin: "0.5em 0 0.75em"
|
|
1346
|
+
} }, line("l", "90"), react.createElement("i", { style: {
|
|
1347
|
+
...st.ornDot,
|
|
1348
|
+
background: ruler
|
|
1349
|
+
} }), line("r", "270"));
|
|
1350
|
+
}
|
|
1351
|
+
/** 行首那枚朱砂小印(进/状/计):**两层**——材质层过印那条糙边滤镜(印泥压出来的毛边与斑驳),
|
|
1352
|
+
* 字独立成层保持清晰;方块各带一点歪斜(真印章不会次次压得方正)。
|
|
1353
|
+
* 外框仍是 0.7em 字/1.6 行高/左右 0.375em 垫——换的是质感,版面逐值不动。 */
|
|
1354
|
+
function inkMark(name) {
|
|
1355
|
+
const tilt = name === "进展" ? -2.4 : name === "状态" ? 1.6 : -1.2;
|
|
1356
|
+
return react.createElement("span", { style: {
|
|
1357
|
+
position: "relative",
|
|
1358
|
+
flex: "0 0 auto",
|
|
1359
|
+
fontSize: "0.7em",
|
|
1360
|
+
lineHeight: 1.6,
|
|
1361
|
+
padding: "0 0.375em",
|
|
1362
|
+
transform: "rotate(" + tilt + "deg)"
|
|
1363
|
+
} }, react.createElement("span", {
|
|
1364
|
+
"aria-hidden": true,
|
|
1365
|
+
style: {
|
|
1366
|
+
position: "absolute",
|
|
1367
|
+
inset: 0,
|
|
1368
|
+
borderRadius: "0.1875em",
|
|
1369
|
+
background: "#d92b1c",
|
|
1370
|
+
filter: "url(#" + SEAL_ROUGH_INK_ID + ")"
|
|
1371
|
+
}
|
|
1372
|
+
}, react.createElement("span", {
|
|
1373
|
+
"aria-hidden": true,
|
|
1374
|
+
style: {
|
|
1375
|
+
position: "absolute",
|
|
1376
|
+
inset: 0,
|
|
1377
|
+
borderRadius: "inherit",
|
|
1378
|
+
background: "radial-gradient(circle at 72% 76%,#a81a0e33 0%,#0000 58%), radial-gradient(circle at 20% 62%,#f0715a3d 0%,#0000 52%), radial-gradient(circle at 52% 12%,#ee6a5233 0%,#0000 46%)"
|
|
1379
|
+
}
|
|
1380
|
+
})), react.createElement("span", { style: {
|
|
1381
|
+
position: "relative",
|
|
1382
|
+
color: "#fdf7ea",
|
|
1383
|
+
opacity: .95
|
|
1384
|
+
} }, name.slice(0, 1)));
|
|
1385
|
+
}
|
|
1386
|
+
/** 三段:一行紧凑(行首朱砂小方印+标签+正文同一基线)。 */
|
|
1387
|
+
function inlineRows(st, ctx) {
|
|
1388
|
+
const one = (key, name, text, last = false) => react.createElement("div", {
|
|
1389
|
+
key,
|
|
1390
|
+
style: {
|
|
1391
|
+
margin: last ? "0 0 -0.5em" : "0 0 0.5em",
|
|
1392
|
+
display: "flex",
|
|
1393
|
+
alignItems: "baseline",
|
|
1394
|
+
gap: "0.5em"
|
|
1395
|
+
}
|
|
1396
|
+
}, inkMark(name), react.createElement("span", { style: {
|
|
1397
|
+
...st.label,
|
|
1398
|
+
flex: "0 0 auto",
|
|
1399
|
+
display: "inline",
|
|
1400
|
+
marginBottom: 0,
|
|
1401
|
+
fontSize: "0.8em",
|
|
1402
|
+
color: ctx.accent
|
|
1403
|
+
} }, name + ":"), react.createElement("span", { style: {
|
|
1404
|
+
...st.text,
|
|
1405
|
+
flex: "1 1 auto",
|
|
1406
|
+
display: "inline",
|
|
1407
|
+
margin: 0,
|
|
1408
|
+
fontSize: "0.9em"
|
|
1409
|
+
} }, text));
|
|
1410
|
+
return react.createElement(react.Fragment, null, one("progress", "进展", ctx.progress), one("status", "状态", ctx.status), one("plan", "计划", ctx.plan, true));
|
|
1411
|
+
}
|
|
1412
|
+
/** 档位语(一行):该档金属渐变压进字里。 */
|
|
1413
|
+
function tierNode(ctx) {
|
|
1414
|
+
const metal = TIER_METAL[ctx.tierKey] ?? TIER_METAL["gold"];
|
|
1415
|
+
return react.createElement("div", { style: {
|
|
1416
|
+
...ctx.styles.tier,
|
|
1417
|
+
fontFamily: KAI,
|
|
1418
|
+
fontSize: "1.0625em",
|
|
1419
|
+
letterSpacing: "0.34em",
|
|
1420
|
+
textIndent: "0.34em",
|
|
1421
|
+
color: "transparent",
|
|
1422
|
+
backgroundImage: metal.gradient,
|
|
1423
|
+
WebkitBackgroundClip: "text",
|
|
1424
|
+
backgroundClip: "text"
|
|
1425
|
+
} }, ctx.tierText);
|
|
1426
|
+
}
|
|
1427
|
+
/** 组装一件:纸底/头部/档位语/饰线/三段(定稿不覆盖纸底与头部,故两者缺席=用 `seal-scroll.ts` 的原样式)。 */
|
|
1428
|
+
function paperParts(ctx) {
|
|
1429
|
+
return {
|
|
1430
|
+
paper: void 0,
|
|
1431
|
+
head: void 0,
|
|
1432
|
+
tier: tierNode(ctx),
|
|
1433
|
+
orn: ornament(ctx.styles, ctx.ruler),
|
|
1434
|
+
body: inlineRows(ctx.styles, ctx)
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
//#endregion
|
|
1211
1438
|
//#region ../plugin-manager/src/seal-scroll.ts
|
|
1212
1439
|
/** 印章卷轴 · 纯组件(`title-seal.ts` 的配套件,不认任何一家)。
|
|
1213
1440
|
*
|
|
@@ -1234,6 +1461,15 @@ window.__ModuleLoader__.load({
|
|
|
1234
1461
|
/** 糙边滤镜 id(文档作用域,故每页只许挂一次 `SealFilterDefs`)。 */
|
|
1235
1462
|
const ROUGH_EDGE = "dshLifeSealRoughEdge";
|
|
1236
1463
|
const ROUGH_FRAME = "dshLifeSealRoughFrame";
|
|
1464
|
+
/** 中等件(轴杆/纸筒/绦带这类几十像素宽的件)那条糙边:2.2 太细、5 会抖过头。 */
|
|
1465
|
+
const ROUGH_METAL = "dshLifeSealRoughMetal";
|
|
1466
|
+
/** 印泥那条(行首那几枚小印):同 2.2 的抖动,末尾再加一点高斯模糊——印泥压在纸上边缘会洇开,
|
|
1467
|
+
* 光有抖动边只会读成「毛边贴纸」。字住在滤镜之外,所以糊的只有泥、不是字。 */
|
|
1468
|
+
const ROUGH_INK = "dshLifeSealInkEdge";
|
|
1469
|
+
/** 中等件那条糙边 id(关闭钮引用;定义只此一处)。 */
|
|
1470
|
+
const SEAL_ROUGH_METAL_ID = ROUGH_METAL;
|
|
1471
|
+
/** 印泥那条糙边 id(纸面行首小印引用;定义只此一处)。 */
|
|
1472
|
+
const SEAL_ROUGH_INK_ID = ROUGH_INK;
|
|
1237
1473
|
/** 档位话:标题下那一行不再印档位字,直接说档位所处的阶段(渲染期用,顶层可放行)。 */
|
|
1238
1474
|
const TIER_TEXT = {
|
|
1239
1475
|
gold: "精雕细琢中",
|
|
@@ -1243,6 +1479,7 @@ window.__ModuleLoader__.load({
|
|
|
1243
1479
|
/** 纸面四色是印自带的(羊皮纸底+ availability 墨色),不跟宿主主题跑——
|
|
1244
1480
|
* 深色下宿主变量会把纸染黑,故这里写死定稿值;字族仍继承(定稿零字族)。 */
|
|
1245
1481
|
const PAPER_BG = "#fdfaf2";
|
|
1482
|
+
const PAPER_EDGE = "#e6d9bd";
|
|
1246
1483
|
const LABEL_SUB = "#4b4335";
|
|
1247
1484
|
/** 九档材质(3 角色 × 3 档)。键就是原型里的 `role`/`tier`。 */
|
|
1248
1485
|
const MATERIALS = {
|
|
@@ -1377,7 +1614,7 @@ window.__ModuleLoader__.load({
|
|
|
1377
1614
|
},
|
|
1378
1615
|
inner: {
|
|
1379
1616
|
position: "relative",
|
|
1380
|
-
padding: "1.75em 2em
|
|
1617
|
+
padding: "1.75em 2em"
|
|
1381
1618
|
},
|
|
1382
1619
|
head: {
|
|
1383
1620
|
textAlign: "center",
|
|
@@ -1441,11 +1678,12 @@ window.__ModuleLoader__.load({
|
|
|
1441
1678
|
justifyContent: "center",
|
|
1442
1679
|
pointerEvents: "auto"
|
|
1443
1680
|
},
|
|
1444
|
-
/**
|
|
1681
|
+
/** 浮层内框:**宽随内容**(`max-content`,正好包住最长那一行;不是固定 25em 那块大纸)。
|
|
1682
|
+
* `maxWidth:100%` 是窄卡的兜底(收满可用宽、永不捅破卡片),此时长行换行、高度自己长。
|
|
1445
1683
|
* 挂卷轴展开动画(从上而下舒卷,240ms;纯声明式,无 hook,纯函数可直测)。 */
|
|
1446
1684
|
popInner: {
|
|
1447
1685
|
position: "relative",
|
|
1448
|
-
width: "
|
|
1686
|
+
width: "max-content",
|
|
1449
1687
|
maxWidth: "100%",
|
|
1450
1688
|
transformOrigin: "50% 0",
|
|
1451
1689
|
animation: "dshLifeSealUnroll 240ms ease-out"
|
|
@@ -1471,9 +1709,11 @@ window.__ModuleLoader__.load({
|
|
|
1471
1709
|
}
|
|
1472
1710
|
/** 糙边滤镜定义:两条分开(印用 edge,卷轴外框用 frame),每页只挂一次。
|
|
1473
1711
|
*
|
|
1474
|
-
* 挂在文档任意位置都行(`width/height=0` 不占位),同页重复挂会撞 id。
|
|
1712
|
+
* 挂在文档任意位置都行(`width/height=0` 不占位),同页重复挂会撞 id。
|
|
1713
|
+
* 印章交互(悬停上浮高亮/按压回缩/焦点环/级别 tooltip)也住这里:scoped 类名,纯 CSS、无 hook。
|
|
1714
|
+
* 悬停高亮须把糙边 url 原样带上(filter 单属性,另写会把糙边冲掉)。 */
|
|
1475
1715
|
function SealFilterDefs() {
|
|
1476
|
-
return react.createElement("svg", {
|
|
1716
|
+
return react.createElement(react.Fragment, null, react.createElement("style", null, ".dshLifeSealBtn{position:relative;transition:transform 160ms ease-out,filter 160ms ease-out}.dshLifeSealBtn:hover{transform:translateY(-2px);filter:url(#dshLifeSealRoughEdge) brightness(1.12)}.dshLifeSealBtn:active{transform:translateY(0) scale(.96)}.dshLifeSealBtn:focus-visible{outline:2px solid #f5d97a;outline-offset:2px}.dshLifeSealBtn::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background:#241f19ee;color:#f8f1e2;font-size:.72em;letter-spacing:.1em;padding:.4em .9em;border-radius:.5em;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity 150ms ease;z-index:30}.dshLifeSealBtn:hover::after,.dshLifeSealBtn:focus-visible::after{opacity:1}"), react.createElement("svg", {
|
|
1477
1717
|
width: 0,
|
|
1478
1718
|
height: 0,
|
|
1479
1719
|
"aria-hidden": true,
|
|
@@ -1497,6 +1737,21 @@ window.__ModuleLoader__.load({
|
|
|
1497
1737
|
y: "-6%",
|
|
1498
1738
|
width: "112%",
|
|
1499
1739
|
height: "112%"
|
|
1740
|
+
}, react.createElement("feTurbulence", {
|
|
1741
|
+
baseFrequency: .6,
|
|
1742
|
+
numOctaves: 3,
|
|
1743
|
+
result: "n"
|
|
1744
|
+
}), react.createElement("feDisplacementMap", {
|
|
1745
|
+
in: "SourceGraphic",
|
|
1746
|
+
in2: "n",
|
|
1747
|
+
scale: 6.5
|
|
1748
|
+
})), react.createElement("filter", {
|
|
1749
|
+
id: ROUGH_METAL,
|
|
1750
|
+
key: ROUGH_METAL,
|
|
1751
|
+
x: "-8%",
|
|
1752
|
+
y: "-14%",
|
|
1753
|
+
width: "116%",
|
|
1754
|
+
height: "128%"
|
|
1500
1755
|
}, react.createElement("feTurbulence", {
|
|
1501
1756
|
baseFrequency: .9,
|
|
1502
1757
|
numOctaves: 2,
|
|
@@ -1504,8 +1759,43 @@ window.__ModuleLoader__.load({
|
|
|
1504
1759
|
}), react.createElement("feDisplacementMap", {
|
|
1505
1760
|
in: "SourceGraphic",
|
|
1506
1761
|
in2: "n",
|
|
1507
|
-
scale:
|
|
1508
|
-
}))
|
|
1762
|
+
scale: 3.2
|
|
1763
|
+
})), react.createElement("filter", {
|
|
1764
|
+
id: ROUGH_INK,
|
|
1765
|
+
key: ROUGH_INK,
|
|
1766
|
+
x: "-25%",
|
|
1767
|
+
y: "-25%",
|
|
1768
|
+
width: "150%",
|
|
1769
|
+
height: "150%"
|
|
1770
|
+
}, react.createElement("feTurbulence", {
|
|
1771
|
+
type: "fractalNoise",
|
|
1772
|
+
baseFrequency: .9,
|
|
1773
|
+
numOctaves: 2,
|
|
1774
|
+
result: "n"
|
|
1775
|
+
}), react.createElement("feDisplacementMap", {
|
|
1776
|
+
in: "SourceGraphic",
|
|
1777
|
+
in2: "n",
|
|
1778
|
+
scale: 2.2,
|
|
1779
|
+
result: "d"
|
|
1780
|
+
}), react.createElement("feGaussianBlur", {
|
|
1781
|
+
in: "d",
|
|
1782
|
+
stdDeviation: .3,
|
|
1783
|
+
result: "b"
|
|
1784
|
+
}), react.createElement("feTurbulence", {
|
|
1785
|
+
type: "fractalNoise",
|
|
1786
|
+
baseFrequency: .75,
|
|
1787
|
+
numOctaves: 3,
|
|
1788
|
+
result: "g"
|
|
1789
|
+
}), react.createElement("feColorMatrix", {
|
|
1790
|
+
in: "g",
|
|
1791
|
+
type: "matrix",
|
|
1792
|
+
values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .7 .45 0 0 .35",
|
|
1793
|
+
result: "mask"
|
|
1794
|
+
}), react.createElement("feComposite", {
|
|
1795
|
+
in: "b",
|
|
1796
|
+
in2: "mask",
|
|
1797
|
+
operator: "in"
|
|
1798
|
+
}))));
|
|
1509
1799
|
}
|
|
1510
1800
|
/** 一卷:外框材质 + 纯纸 + 进展/状态/计划三段。 */
|
|
1511
1801
|
function SealScroll(props) {
|
|
@@ -1548,38 +1838,38 @@ window.__ModuleLoader__.load({
|
|
|
1548
1838
|
}
|
|
1549
1839
|
})
|
|
1550
1840
|
] : [];
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1841
|
+
/** 纸面字排:定稿件直出五件。 */
|
|
1842
|
+
const parts = paperParts({
|
|
1843
|
+
tierKey: props.tier,
|
|
1844
|
+
tierText: TIER_TEXT[props.tier],
|
|
1845
|
+
progress: props.progress,
|
|
1846
|
+
status: props.status,
|
|
1847
|
+
plan: props.plan,
|
|
1848
|
+
accent: material.accent,
|
|
1849
|
+
ruler: material.ruler,
|
|
1850
|
+
paperEdge: PAPER_EDGE,
|
|
1851
|
+
styles: {
|
|
1852
|
+
head: S$1.head,
|
|
1853
|
+
paper: S$1.paper,
|
|
1854
|
+
tier: S$1.tier,
|
|
1855
|
+
orn: S$1.orn,
|
|
1856
|
+
ornLine: S$1.ornLine,
|
|
1857
|
+
ornDot: S$1.ornDot,
|
|
1858
|
+
block: S$1.block,
|
|
1859
|
+
blockDivided: S$1.blockDivided,
|
|
1860
|
+
blockLast: S$1.blockLast,
|
|
1861
|
+
label: S$1.label,
|
|
1862
|
+
text: S$1.text
|
|
1556
1863
|
}
|
|
1557
1864
|
});
|
|
1558
|
-
const block = (key, name, text, divided, last = false) => react.createElement("div", {
|
|
1559
|
-
key,
|
|
1560
|
-
style: last ? divided ? {
|
|
1561
|
-
...S$1.blockLast,
|
|
1562
|
-
paddingTop: "0.9375em",
|
|
1563
|
-
borderTop: "1px solid #e6d9bd"
|
|
1564
|
-
} : S$1.blockLast : divided ? S$1.blockDivided : S$1.block
|
|
1565
|
-
}, react.createElement("div", { style: {
|
|
1566
|
-
...S$1.label,
|
|
1567
|
-
color: material.accent
|
|
1568
|
-
} }, name), react.createElement("p", { style: S$1.text }, text));
|
|
1569
1865
|
return react.createElement("div", { style: S$1.scroll }, react.createElement("div", { style: {
|
|
1570
1866
|
...S$1.frame,
|
|
1571
1867
|
...material.frame
|
|
1572
|
-
} }, ...frameChildren), react.createElement("div", { style: S$1.paper }, react.createElement("div", { style: S$1.inner }, react.createElement("div", { style: S$1.head }, react.createElement(SealStamp, {
|
|
1868
|
+
} }, ...frameChildren), react.createElement("div", { style: parts.paper === void 0 ? S$1.paper : parts.paper }, react.createElement("div", { style: S$1.inner }, react.createElement("div", { style: parts.head === void 0 ? S$1.head : parts.head }, react.createElement(SealStamp, {
|
|
1573
1869
|
role: props.role,
|
|
1574
1870
|
tier: props.tier,
|
|
1575
1871
|
label: props.title
|
|
1576
|
-
}),
|
|
1577
|
-
...S$1.tier,
|
|
1578
|
-
color: material.accent
|
|
1579
|
-
} }, TIER_TEXT[props.tier])), react.createElement("div", { style: S$1.orn }, line("l", "90"), react.createElement("i", { style: {
|
|
1580
|
-
...S$1.ornDot,
|
|
1581
|
-
background: material.accent
|
|
1582
|
-
} }), line("r", "270")), block("progress", "进展", props.progress, false), block("status", "状态", props.status, true), block("plan", "计划", props.plan, true, true))));
|
|
1872
|
+
}), parts.tier), parts.orn, parts.body)));
|
|
1583
1873
|
}
|
|
1584
1874
|
/** 卷轴浮层:popover + 点击别处关闭 + 卷轴展开动画 + 关闭。`open` 为假时不渲染(纯函数,不收自己的状态)。 */
|
|
1585
1875
|
function SealScrollDialog(props) {
|
|
@@ -1602,16 +1892,27 @@ window.__ModuleLoader__.load({
|
|
|
1602
1892
|
"aria-hidden": true,
|
|
1603
1893
|
onClick: props.onClose
|
|
1604
1894
|
}), react.createElement("div", {
|
|
1605
|
-
style: S$1.dialog
|
|
1895
|
+
style: props.anchor === void 0 ? S$1.dialog : {
|
|
1896
|
+
...S$1.dialog,
|
|
1897
|
+
...props.anchor
|
|
1898
|
+
},
|
|
1606
1899
|
role: "dialog",
|
|
1607
1900
|
"aria-modal": false,
|
|
1608
1901
|
"aria-label": props.title
|
|
1609
|
-
}, react.createElement("style", null, "@keyframes dshLifeSealUnroll{from{opacity:0;transform:translateY(-10px) scaleY(.7)}to{opacity:1;transform:none}}"), react.createElement("div", { style: S$1.popInner },
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1902
|
+
}, react.createElement("style", null, "@keyframes dshLifeSealUnroll{from{opacity:0;transform:translateY(-10px) scaleY(.7)}to{opacity:1;transform:none}}"), react.createElement("div", { style: S$1.popInner }, (() => {
|
|
1903
|
+
const look = closeLook(props.tier);
|
|
1904
|
+
return react.createElement("button", {
|
|
1905
|
+
type: "button",
|
|
1906
|
+
className: "dshLifeSealBtn",
|
|
1907
|
+
style: {
|
|
1908
|
+
zIndex: 20,
|
|
1909
|
+
...look.style
|
|
1910
|
+
},
|
|
1911
|
+
"data-ilife-press": "seal-close",
|
|
1912
|
+
"data-ilife-close": "tie",
|
|
1913
|
+
onClick: props.onClose
|
|
1914
|
+
}, look.decor ?? null, look.label);
|
|
1915
|
+
})(), react.createElement(SealScroll, scroll))));
|
|
1615
1916
|
}
|
|
1616
1917
|
//#endregion
|
|
1617
1918
|
//#region ../plugin-manager/src/seal-stamp.ts
|
|
@@ -1720,21 +2021,25 @@ window.__ModuleLoader__.load({
|
|
|
1720
2021
|
function SealStamp(props) {
|
|
1721
2022
|
const face = FACE[props.role][props.tier];
|
|
1722
2023
|
if (face === void 0) throw new Error("未知印章组合:" + String(props.role) + "/" + String(props.tier));
|
|
2024
|
+
const style = {
|
|
2025
|
+
display: "inline-flex",
|
|
2026
|
+
alignItems: "center",
|
|
2027
|
+
cursor: "pointer",
|
|
2028
|
+
fontWeight: 800,
|
|
2029
|
+
lineHeight: 1.2,
|
|
2030
|
+
whiteSpace: "nowrap",
|
|
2031
|
+
filter: "url(#dshLifeSealRoughEdge)",
|
|
2032
|
+
...ROLE_BASE[props.role],
|
|
2033
|
+
...face
|
|
2034
|
+
};
|
|
2035
|
+
const tierName = props.tier === "copper" ? "铜" : props.tier === "silver" ? "银" : "金";
|
|
1723
2036
|
const buttonProps = {
|
|
1724
2037
|
type: "button",
|
|
1725
|
-
style
|
|
1726
|
-
|
|
1727
|
-
alignItems: "center",
|
|
1728
|
-
cursor: "pointer",
|
|
1729
|
-
fontWeight: 800,
|
|
1730
|
-
lineHeight: 1.2,
|
|
1731
|
-
whiteSpace: "nowrap",
|
|
1732
|
-
filter: "url(#dshLifeSealRoughEdge)",
|
|
1733
|
-
...ROLE_BASE[props.role],
|
|
1734
|
-
...face
|
|
1735
|
-
},
|
|
2038
|
+
style,
|
|
2039
|
+
className: "dshLifeSealBtn",
|
|
1736
2040
|
"aria-label": props.label,
|
|
1737
2041
|
"aria-haspopup": "dialog",
|
|
2042
|
+
"data-tip": tierName + "章 · " + TIER_TEXT[props.tier],
|
|
1738
2043
|
onClick: props.onSelect
|
|
1739
2044
|
};
|
|
1740
2045
|
if (props.role !== "plugin") return react.createElement("button", buttonProps, props.label);
|
|
@@ -2490,6 +2795,16 @@ window.__ModuleLoader__.load({
|
|
|
2490
2795
|
onSelect: props.onSealSelect === void 0 ? void 0 : props.onSealSelect.bind(null, dataIndex)
|
|
2491
2796
|
})))));
|
|
2492
2797
|
const openSeal = props.selectedSeal === null || props.selectedSeal === void 0 ? null : seals[props.selectedSeal] ?? null;
|
|
2798
|
+
/** 卷轴浮层跟着**被点的那枚章**:贴在该行下方一小段(1.9em = 章高约 1.5em + 0.4em 缝),
|
|
2799
|
+
* 右缘与那枚章的右缘对齐,再往左让 1.25em 给绦带(关闭钮骑在浮层右上方,不让它越出卡片)。 */
|
|
2800
|
+
const openSlot = props.selectedSeal ?? -1;
|
|
2801
|
+
const anchor = openSlot < 0 || openSlot >= order.length ? void 0 : {
|
|
2802
|
+
top: "calc(" + TOPS[openSlot] + " + 1.9em)",
|
|
2803
|
+
right: "calc(" + padRightOfSlot(openSlot) + " + 1.25em)",
|
|
2804
|
+
left: "auto",
|
|
2805
|
+
justifyContent: "flex-end",
|
|
2806
|
+
maxWidth: "calc(100% - " + padRightOfSlot(openSlot) + " - 1.75em)"
|
|
2807
|
+
};
|
|
2493
2808
|
const dialog = openSeal === null ? null : react.createElement(SealScrollDialog, {
|
|
2494
2809
|
open: true,
|
|
2495
2810
|
onClose: props.onSealClose ?? (() => void 0),
|
|
@@ -2498,7 +2813,8 @@ window.__ModuleLoader__.load({
|
|
|
2498
2813
|
title: openSeal.label,
|
|
2499
2814
|
progress: openSeal.progress,
|
|
2500
2815
|
status: openSeal.status,
|
|
2501
|
-
plan: openSeal.plan
|
|
2816
|
+
plan: openSeal.plan,
|
|
2817
|
+
anchor
|
|
2502
2818
|
});
|
|
2503
2819
|
const headDataDir = surface === null ? "" : surface.resolved?.["dbDir"] ?? surface.dataDir;
|
|
2504
2820
|
const ready = state.kind === "ready";
|