dsh-dock 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/client.js +284 -70
- package/features/animation/host.js +19 -1
- package/features/animation/view.jsx +171 -28
- package/features/games/games/breakout.jsx +3 -3
- package/features/games/games/racer.jsx +1 -1
- package/features/games/games/tetris.jsx +12 -6
- package/features/games/games/xiangqi.jsx +98 -26
- package/features/games/view.jsx +1 -1
- package/features/mobile-relay/host.js +53 -0
- package/package.json +2 -2
- package/src/client.jsx +1 -1
- package/src/host-core.js +2 -0
package/client.js
CHANGED
|
@@ -3876,6 +3876,13 @@ var PHASE_COLORS = { think: "#2f6fed", write: "#0d9488", code: "#b45309", search
|
|
|
3876
3876
|
function phaseColor(p) {
|
|
3877
3877
|
return PHASE_COLORS[p] || "#2f6fed";
|
|
3878
3878
|
}
|
|
3879
|
+
function toolLabel(name) {
|
|
3880
|
+
const n = String(name || "").toLowerCase();
|
|
3881
|
+
if (/bash|shell|terminal|cmd|pwsh|powershell|exec/.test(n)) return "\u6267\u884C\u547D\u4EE4";
|
|
3882
|
+
if (/write|edit|patch|apply|create|mkdir|remove|delete/.test(n)) return "\u4FEE\u6539\u6587\u4EF6";
|
|
3883
|
+
if (/web|fetch|browser|navigate|search/.test(n)) return "\u8BBF\u95EE\u7F51\u9875";
|
|
3884
|
+
return "";
|
|
3885
|
+
}
|
|
3879
3886
|
var END_LABELS = {
|
|
3880
3887
|
completed: { label: "\u5B8C\u6210", cls: "ok" },
|
|
3881
3888
|
error: { label: "\u51FA\u9519", cls: "err" },
|
|
@@ -4109,12 +4116,12 @@ function RobotScene(props) {
|
|
|
4109
4116
|
] });
|
|
4110
4117
|
}
|
|
4111
4118
|
var SOUND_LIBRARY = {
|
|
4112
|
-
chime: { name: "\u6E05\u8106\u53CC\u97F3", notes: { done: [[659.25, 0, 0.14], [880, 0.13, 0.24]], err: [[220, 0, 0.16], [164.81, 0.15, 0.3]] } },
|
|
4113
|
-
ding: { name: "\u53EE", notes: { done: [[987.77, 0, 0.35]], err: [[246.94, 0, 0.4]] } },
|
|
4114
|
-
coin: { name: "\u91D1\u5E01", notes: { done: [[988, 0, 0.08], [1319, 0.08, 0.35], [988, 0, 0.08, "square"], [1319, 0.08, 0.3, "square"]], err: [[196, 0, 0.12], [147, 0.11, 0.35]] } },
|
|
4115
|
-
bell: { name: "\u949F\u58F0", notes: { done: [[523.25, 0, 0.5], [659.25, 0.02, 0.45], [783.99, 0.04, 0.4]], err: [[174.61, 0, 0.5], [130.81, 0.05, 0.5]] } },
|
|
4116
|
-
pulse: { name: "\u8109\u51B2", notes: { done: [[440, 0, 0.09], [440, 0.14, 0.09], [440, 0.28, 0.16]], err: [[174.61, 0, 0.1], [174.61, 0.14, 0.1], [174.61, 0.28, 0.18]] } },
|
|
4117
|
-
arp: { name: "\u7436\u97F3", notes: { done: [[523.25, 0, 0.12], [659.25, 0.09, 0.12], [783.99, 0.18, 0.12], [1046.5, 0.27, 0.3]], err: [[392, 0, 0.12], [329.63, 0.1, 0.12], [261.63, 0.2, 0.12], [196, 0.3, 0.32]] } }
|
|
4119
|
+
chime: { name: "\u6E05\u8106\u53CC\u97F3", notes: { done: [[659.25, 0, 0.14], [880, 0.13, 0.24]], err: [[220, 0, 0.16], [164.81, 0.15, 0.3]], ask: [[587.33, 0, 0.16], [880, 0.19, 0.34]] } },
|
|
4120
|
+
ding: { name: "\u53EE", notes: { done: [[987.77, 0, 0.35]], err: [[246.94, 0, 0.4]], ask: [[783.99, 0, 0.18], [1174.66, 0.2, 0.42]] } },
|
|
4121
|
+
coin: { name: "\u91D1\u5E01", notes: { done: [[988, 0, 0.08], [1319, 0.08, 0.35], [988, 0, 0.08, "square"], [1319, 0.08, 0.3, "square"]], err: [[196, 0, 0.12], [147, 0.11, 0.35]], ask: [[880, 0, 0.09], [1108.73, 0.1, 0.12], [1318.51, 0.22, 0.3]] } },
|
|
4122
|
+
bell: { name: "\u949F\u58F0", notes: { done: [[523.25, 0, 0.5], [659.25, 0.02, 0.45], [783.99, 0.04, 0.4]], err: [[174.61, 0, 0.5], [130.81, 0.05, 0.5]], ask: [[659.25, 0, 0.4], [523.25, 0.05, 0.55]] } },
|
|
4123
|
+
pulse: { name: "\u8109\u51B2", notes: { done: [[440, 0, 0.09], [440, 0.14, 0.09], [440, 0.28, 0.16]], err: [[174.61, 0, 0.1], [174.61, 0.14, 0.1], [174.61, 0.28, 0.18]], ask: [[523.25, 0, 0.09], [523.25, 0.15, 0.09], [659.25, 0.3, 0.22]] } },
|
|
4124
|
+
arp: { name: "\u7436\u97F3", notes: { done: [[523.25, 0, 0.12], [659.25, 0.09, 0.12], [783.99, 0.18, 0.12], [1046.5, 0.27, 0.3]], err: [[392, 0, 0.12], [329.63, 0.1, 0.12], [261.63, 0.2, 0.12], [196, 0.3, 0.32]], ask: [[440, 0, 0.11], [554.37, 0.12, 0.11], [659.25, 0.24, 0.11], [880, 0.36, 0.34]] } }
|
|
4118
4125
|
};
|
|
4119
4126
|
var soundCtx = null;
|
|
4120
4127
|
function playTone(seq) {
|
|
@@ -4146,6 +4153,10 @@ function playDoneSound(success, effect) {
|
|
|
4146
4153
|
const lib = SOUND_LIBRARY[effect] || SOUND_LIBRARY.chime;
|
|
4147
4154
|
playTone(success ? lib.notes.done : lib.notes.err);
|
|
4148
4155
|
}
|
|
4156
|
+
function playAskSound(effect) {
|
|
4157
|
+
const lib = SOUND_LIBRARY[effect] || SOUND_LIBRARY.chime;
|
|
4158
|
+
playTone(lib.notes.ask || lib.notes.done);
|
|
4159
|
+
}
|
|
4149
4160
|
function previewSound(effect) {
|
|
4150
4161
|
const lib = SOUND_LIBRARY[effect] || SOUND_LIBRARY.chime;
|
|
4151
4162
|
playTone(lib.notes.done);
|
|
@@ -4168,11 +4179,14 @@ function Toast(props) {
|
|
|
4168
4179
|
const timer = setTimeout(() => props.onClose(t.id), 240);
|
|
4169
4180
|
return () => clearTimeout(timer);
|
|
4170
4181
|
}, [closing]);
|
|
4171
|
-
const markColor = t.kind === "success" ? "var(--dk-ok)" : t.kind === "error" ? "var(--dk-err)" : "var(--dk-warn)";
|
|
4172
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-toast" + (closing ? " out" : ""), children: [
|
|
4182
|
+
const markColor = t.kind === "success" ? "var(--dk-ok)" : t.kind === "error" ? "var(--dk-err)" : t.kind === "confirm" ? "var(--dk-warn)" : "var(--dk-warn)";
|
|
4183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-toast" + (t.kind === "confirm" ? " dkan-toast-confirm" : "") + (closing ? " out" : ""), children: [
|
|
4173
4184
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-toast-head", children: [
|
|
4174
4185
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-toast-mark", style: { background: markColor } }),
|
|
4175
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-toast-title", title: t.title, children: [
|
|
4187
|
+
t.kind === "confirm" ? "\u270B " : "",
|
|
4188
|
+
t.title
|
|
4189
|
+
] }),
|
|
4176
4190
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dkan-toast-close", "aria-label": "\u5173\u95ED", onClick: close, children: "\u2715" })
|
|
4177
4191
|
] }),
|
|
4178
4192
|
t.body ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-toast-body", children: t.body }) : null
|
|
@@ -4376,6 +4390,24 @@ function visibleRect(el) {
|
|
|
4376
4390
|
const r = el.getBoundingClientRect();
|
|
4377
4391
|
return r.width > 0 && r.height > 0 && r.bottom > 0 && r.top < window.innerHeight ? r : null;
|
|
4378
4392
|
}
|
|
4393
|
+
function currentSessionTitle() {
|
|
4394
|
+
if (typeof document === "undefined") return "";
|
|
4395
|
+
for (const el of document.querySelectorAll('[role="treeitem"][aria-selected="true"]')) {
|
|
4396
|
+
const r = el.getBoundingClientRect();
|
|
4397
|
+
if (r.width > 0 && r.height > 0 && r.right <= window.innerWidth * 0.35) {
|
|
4398
|
+
const text = (el.textContent || "").trim();
|
|
4399
|
+
if (text) return text;
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
return "";
|
|
4403
|
+
}
|
|
4404
|
+
function taskOnScreen(task, titleCache) {
|
|
4405
|
+
const title = task && (task.title || "");
|
|
4406
|
+
if (!title) return true;
|
|
4407
|
+
const current = titleCache !== void 0 ? titleCache : currentSessionTitle();
|
|
4408
|
+
if (!current) return true;
|
|
4409
|
+
return current === title || current.indexOf(title) !== -1 || title.indexOf(current) !== -1;
|
|
4410
|
+
}
|
|
4379
4411
|
var COMPOSER_SEND_SELECTOR = 'button[aria-label="Send message"],button[aria-label*="\u53D1\u9001"],button[data-testid*="send"],button[data-testid*="submit"],button[type="submit"]';
|
|
4380
4412
|
function conversationComposer() {
|
|
4381
4413
|
if (typeof document === "undefined" || typeof window === "undefined") return null;
|
|
@@ -4445,7 +4477,6 @@ function useSpaceDocks(enabled) {
|
|
|
4445
4477
|
let frame = 0;
|
|
4446
4478
|
let idle = 0;
|
|
4447
4479
|
let timer = 0;
|
|
4448
|
-
let pollTimer = 0;
|
|
4449
4480
|
let retries = 0;
|
|
4450
4481
|
let pending = false;
|
|
4451
4482
|
let observedComposer = null;
|
|
@@ -4501,7 +4532,25 @@ function useSpaceDocks(enabled) {
|
|
|
4501
4532
|
}) : null;
|
|
4502
4533
|
if (mutationObserver && document.body) mutationObserver.observe(document.body, { childList: true, subtree: true });
|
|
4503
4534
|
schedule(0, true);
|
|
4504
|
-
|
|
4535
|
+
let calibrationInterval = 700;
|
|
4536
|
+
let lastActivityAt = Date.now();
|
|
4537
|
+
const markActivity = () => {
|
|
4538
|
+
lastActivityAt = Date.now();
|
|
4539
|
+
if (calibrationInterval !== 700) {
|
|
4540
|
+
calibrationInterval = 700;
|
|
4541
|
+
restartPoll();
|
|
4542
|
+
}
|
|
4543
|
+
};
|
|
4544
|
+
const unsubscribeActivity = animationStore.subscribe(markActivity);
|
|
4545
|
+
let pollTimer = 0;
|
|
4546
|
+
function restartPoll() {
|
|
4547
|
+
if (pollTimer) window.clearInterval(pollTimer);
|
|
4548
|
+
pollTimer = window.setInterval(() => {
|
|
4549
|
+
if (Date.now() - lastActivityAt > 2e4 && calibrationInterval !== 5e3) calibrationInterval = 5e3;
|
|
4550
|
+
schedule();
|
|
4551
|
+
}, calibrationInterval);
|
|
4552
|
+
}
|
|
4553
|
+
restartPoll();
|
|
4505
4554
|
const onResize = () => {
|
|
4506
4555
|
if (idle && typeof window.cancelIdleCallback === "function") window.cancelIdleCallback(idle);
|
|
4507
4556
|
if (timer) window.clearTimeout(timer);
|
|
@@ -4517,6 +4566,7 @@ function useSpaceDocks(enabled) {
|
|
|
4517
4566
|
if (pollTimer) window.clearInterval(pollTimer);
|
|
4518
4567
|
if (mutationObserver) mutationObserver.disconnect();
|
|
4519
4568
|
if (resizeObserver) resizeObserver.disconnect();
|
|
4569
|
+
unsubscribeActivity();
|
|
4520
4570
|
window.removeEventListener("resize", onResize);
|
|
4521
4571
|
};
|
|
4522
4572
|
}, [enabled]);
|
|
@@ -4597,13 +4647,14 @@ function MissionDeparture(props) {
|
|
|
4597
4647
|
}, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }) });
|
|
4598
4648
|
}
|
|
4599
4649
|
function ProgrammingStuck(props) {
|
|
4600
|
-
|
|
4650
|
+
const waiting = !!props.waiting;
|
|
4651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-space-stuck" + (waiting ? " waiting" : ""), "aria-hidden": "true", children: [
|
|
4601
4652
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FreighterHull, { units: 3, empty: true }),
|
|
4602
4653
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-stuck-code", children: [
|
|
4603
4654
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("i", {}),
|
|
4604
4655
|
`{ }`
|
|
4605
4656
|
] }),
|
|
4606
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u7F16\u7A0B\u7B49\u5F85\u4E2D" }),
|
|
4657
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: waiting ? "\u7B49\u5F85\u786E\u8BA4" : "\u7F16\u7A0B\u7B49\u5F85\u4E2D" }),
|
|
4607
4658
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("small", { children: truncate(props.task && props.task.title || "\u5DE5\u5177\u6682\u65E0\u65B0\u54CD\u5E94", 28) })
|
|
4608
4659
|
] });
|
|
4609
4660
|
}
|
|
@@ -4725,6 +4776,56 @@ function AnimationOverlay(props) {
|
|
|
4725
4776
|
}
|
|
4726
4777
|
prevActiveRef.current = st2.active.slice();
|
|
4727
4778
|
}, [snap.status]);
|
|
4779
|
+
const remindedApprovalsRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
4780
|
+
(0, import_react8.useEffect)(() => {
|
|
4781
|
+
const st2 = snap.status;
|
|
4782
|
+
if (!st2 || !st2.active) return;
|
|
4783
|
+
const cfg2 = st2.config || {};
|
|
4784
|
+
const activeIds = new Set(st2.active.map((x) => x.sessionId));
|
|
4785
|
+
for (const [sid, seen] of remindedApprovalsRef.current) {
|
|
4786
|
+
if (!activeIds.has(sid)) remindedApprovalsRef.current.delete(sid);
|
|
4787
|
+
}
|
|
4788
|
+
for (const task of st2.active) {
|
|
4789
|
+
const approvals = Array.isArray(task.approvals) ? task.approvals : [];
|
|
4790
|
+
if (approvals.length === 0) continue;
|
|
4791
|
+
let seen = remindedApprovalsRef.current.get(task.sessionId);
|
|
4792
|
+
if (!seen) {
|
|
4793
|
+
seen = /* @__PURE__ */ new Set();
|
|
4794
|
+
remindedApprovalsRef.current.set(task.sessionId, seen);
|
|
4795
|
+
}
|
|
4796
|
+
const fresh = approvals.filter((a) => a && !seen.has(a.id));
|
|
4797
|
+
if (fresh.length === 0) continue;
|
|
4798
|
+
for (const a of fresh) seen.add(a.id);
|
|
4799
|
+
if (!cfg2.notifyEnabled || cfg2.notifyOnConfirm === false) continue;
|
|
4800
|
+
const toolName = fresh[0].toolName || "";
|
|
4801
|
+
const scene = toolLabel(toolName);
|
|
4802
|
+
const lines = [
|
|
4803
|
+
"\u4EFB\u52A1\uFF1A" + (task.title || "(\u65E0\u6807\u9898)"),
|
|
4804
|
+
"\u5DE5\u5177\uFF1A" + (toolName || "\u672A\u77E5") + (scene ? "\uFF08" + scene + "\uFF09" : "")
|
|
4805
|
+
];
|
|
4806
|
+
if (fresh[0].reason) lines.push("\u8BF4\u660E\uFF1A" + truncate(fresh[0].reason, 140));
|
|
4807
|
+
lines.push(fresh.length > 1 ? "\u5171 " + fresh.length + " \u9879\u7B49\u5F85\u4F60\u7684\u786E\u8BA4" : "\u8BF7\u5728\u4F1A\u8BDD\u91CC\u786E\u8BA4\u540E\u7EE7\u7EED");
|
|
4808
|
+
const toast = {
|
|
4809
|
+
id: Date.now() + Math.random(),
|
|
4810
|
+
kind: "confirm",
|
|
4811
|
+
title: "\u4EFB\u52A1\u9700\u8981\u786E\u8BA4",
|
|
4812
|
+
body: lines.join("\n"),
|
|
4813
|
+
// 需确认常驻到用户处理(notifyStayMs=0 同款语义),关掉开关的间隙也不会自动消失
|
|
4814
|
+
stayMs: 0
|
|
4815
|
+
};
|
|
4816
|
+
setToasts((prev) => prev.concat([toast]).slice(-4));
|
|
4817
|
+
if (cfg2.soundNotify !== false) playAskSound(cfg2.soundEffect);
|
|
4818
|
+
if (cfg2.systemNotify && typeof document !== "undefined" && document.hidden && typeof Notification !== "undefined" && Notification.permission === "granted") {
|
|
4819
|
+
try {
|
|
4820
|
+
new Notification("dsh \u4EFB\u52A1\u9700\u8981\u786E\u8BA4", {
|
|
4821
|
+
body: (task.title || "(\u65E0\u6807\u9898)") + " \xB7 " + (toolName || "\u5DE5\u5177") + " \u7B49\u5F85\u786E\u8BA4",
|
|
4822
|
+
tag: "dsh-dock-approval-" + task.sessionId
|
|
4823
|
+
});
|
|
4824
|
+
} catch {
|
|
4825
|
+
}
|
|
4826
|
+
}
|
|
4827
|
+
}
|
|
4828
|
+
}, [snap.status]);
|
|
4728
4829
|
const handleTaskEnd = (task, record, cfg2) => {
|
|
4729
4830
|
const reason = record && record.endReason || "";
|
|
4730
4831
|
const success = isSuccessReason(reason);
|
|
@@ -4795,6 +4896,18 @@ function AnimationOverlay(props) {
|
|
|
4795
4896
|
const animOn = !!(cfg && cfg.animationEnabled && active.length > 0);
|
|
4796
4897
|
const mode = cfg && cfg.effectMode ? cfg.effectMode : "flow";
|
|
4797
4898
|
const phase = active.length > 0 ? active.reduce((best, x) => !best || (x.phaseAt || 0) > (best.phaseAt || 0) ? x : best, null).phase : "think";
|
|
4899
|
+
const waitingTask = active.find((x) => Array.isArray(x.approvals) && x.approvals.length > 0) || null;
|
|
4900
|
+
const sessionTitleRef = (0, import_react8.useRef)({ at: 0, title: "" });
|
|
4901
|
+
const currentTitle = (0, import_react8.useMemo)(() => {
|
|
4902
|
+
const c = sessionTitleRef.current;
|
|
4903
|
+
if (typeof window === "undefined") return "";
|
|
4904
|
+
if (Date.now() - c.at < 1e3) return c.title;
|
|
4905
|
+
c.at = Date.now();
|
|
4906
|
+
c.title = currentSessionTitle();
|
|
4907
|
+
return c.title;
|
|
4908
|
+
}, [snap.status]);
|
|
4909
|
+
const onScreenTasks = (0, import_react8.useMemo)(() => active.filter((x) => taskOnScreen(x, currentTitle)), [active, currentTitle]);
|
|
4910
|
+
const waitingTaskOnScreen = onScreenTasks.find((x) => Array.isArray(x.approvals) && x.approvals.length > 0) || null;
|
|
4798
4911
|
useTicker(ctx, animOn);
|
|
4799
4912
|
const now = Date.now();
|
|
4800
4913
|
const elapsed = active.length > 0 ? fmtClock(now - Math.min(...active.map((x) => x.startTime || now))) : "";
|
|
@@ -4828,7 +4941,7 @@ function AnimationOverlay(props) {
|
|
|
4828
4941
|
const spaceModeOn = !!(cfg && cfg.animationEnabled && mode === "space" && !panelOpen);
|
|
4829
4942
|
const spaceDocks = useSpaceDocks(spaceModeOn);
|
|
4830
4943
|
const spaceGalaxies = spaceModeOn && spaceDocks ? spaceGalaxyLayout() : null;
|
|
4831
|
-
const stuckTask =
|
|
4944
|
+
const stuckTask = onScreenTasks.find((task) => task.phase === "code" && now - (task.lastActivityAt || task.phaseAt || now) >= 18e3) || null;
|
|
4832
4945
|
const robotScaleFromConfig = Math.max(0.85, Math.min(2.2, Number(cfg && cfg.robotScale) || 1.35));
|
|
4833
4946
|
const speedStyle = { "--dkan-speed": Number(speed).toFixed(2) };
|
|
4834
4947
|
const saveRobotScale = (0, import_react8.useCallback)((robotScale) => {
|
|
@@ -4943,7 +5056,7 @@ function AnimationOverlay(props) {
|
|
|
4943
5056
|
ambientOn && mode === "flow" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-line", style: speedStyle, "aria-hidden": "true" }) : null,
|
|
4944
5057
|
ambientOn && AMBIENT_EFFECT_MODES.has(mode) && (mode !== "space" || spaceGalaxies) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AmbientLayer, { mode, phase, speed: Number(speed).toFixed(2), tasks: active, galaxies: spaceGalaxies }) : null,
|
|
4945
5058
|
spaceModeOn && spaceDocks && active.length === 0 && deliveries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReadyFreighter, { dock: spaceDocks.ready }) : null,
|
|
4946
|
-
spaceModeOn && stuckTask ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProgrammingStuck, { task: stuckTask }) : null,
|
|
5059
|
+
spaceModeOn && stuckTask ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProgrammingStuck, { task: stuckTask, waiting: !!(stuckTask.approvals && stuckTask.approvals.length) }) : null,
|
|
4947
5060
|
!panelOpen ? departures.map((departure) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MissionDeparture, { departure }, departure.id)) : null,
|
|
4948
5061
|
ambientOn && mode === "orbit" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-orbit", style: speedStyle, "aria-hidden": "true" }) : null,
|
|
4949
5062
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BurstLayer, { bursts }),
|
|
@@ -4953,8 +5066,8 @@ function AnimationOverlay(props) {
|
|
|
4953
5066
|
className: "dkan-botcard",
|
|
4954
5067
|
role: "button",
|
|
4955
5068
|
tabIndex: 0,
|
|
4956
|
-
style: botCardStyle,
|
|
4957
|
-
title: active.length + " \u4E2A\u4EFB\u52A1 \xB7 " + phaseLabel(phase) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875 \xB7 \u53EF\u62D6\u52A8\u5230\u4EFB\u610F\u4F4D\u7F6E",
|
|
5069
|
+
style: Object.assign({}, botCardStyle, waitingTask ? { "--dkan-phase": "#b45309" } : null),
|
|
5070
|
+
title: active.length + " \u4E2A\u4EFB\u52A1 \xB7 " + (waitingTask ? "\u7B49\u5F85\u786E\u8BA4" : phaseLabel(phase)) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875 \xB7 \u53EF\u62D6\u52A8\u5230\u4EFB\u610F\u4F4D\u7F6E",
|
|
4958
5071
|
onPointerDown: onBotPointerDown,
|
|
4959
5072
|
onPointerMove: onBotPointerMove,
|
|
4960
5073
|
onPointerUp: onBotPointerUp,
|
|
@@ -4973,7 +5086,7 @@ function AnimationOverlay(props) {
|
|
|
4973
5086
|
" \u4E2A\u4EFB\u52A1",
|
|
4974
5087
|
elapsed ? " \xB7 " + elapsed : "",
|
|
4975
5088
|
" \xB7 ",
|
|
4976
|
-
phaseLabel(phase)
|
|
5089
|
+
waitingTask ? "\u7B49\u5F85\u786E\u8BA4" : phaseLabel(phase)
|
|
4977
5090
|
] }),
|
|
4978
5091
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
4979
5092
|
"button",
|
|
@@ -5004,8 +5117,8 @@ function AnimationOverlay(props) {
|
|
|
5004
5117
|
{
|
|
5005
5118
|
type: "button",
|
|
5006
5119
|
className: "dkan-badge" + (mode === "breathe" ? " dkan-badge-breathe" : ""),
|
|
5007
|
-
style: Object.assign({}, speedStyle, { "--dkan-phase": phaseColor(phase) }),
|
|
5008
|
-
title: active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D \xB7 " + phaseLabel(phase) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875",
|
|
5120
|
+
style: Object.assign({}, speedStyle, { "--dkan-phase": phaseColor(waitingTask ? "code" : phase) }),
|
|
5121
|
+
title: active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D \xB7 " + (waitingTask ? "\u7B49\u5F85\u786E\u8BA4" : phaseLabel(phase)) + " \xB7 \u70B9\u51FB\u67E5\u770B\u4EFB\u52A1\u52A8\u753B\u9875",
|
|
5009
5122
|
onClick: () => openPanel("animation"),
|
|
5010
5123
|
children: [
|
|
5011
5124
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dkan-dotwrap", children: [
|
|
@@ -5018,7 +5131,7 @@ function AnimationOverlay(props) {
|
|
|
5018
5131
|
" \u4E2A\u4EFB\u52A1",
|
|
5019
5132
|
elapsed ? " \xB7 " + elapsed : "",
|
|
5020
5133
|
" \xB7 ",
|
|
5021
|
-
phaseLabel(phase)
|
|
5134
|
+
waitingTask ? "\u7B49\u5F85\u786E\u8BA4" : phaseLabel(phase)
|
|
5022
5135
|
] })
|
|
5023
5136
|
]
|
|
5024
5137
|
}
|
|
@@ -5093,10 +5206,11 @@ function ModePreview({ id }) {
|
|
|
5093
5206
|
function TaskRow(props) {
|
|
5094
5207
|
const t = props.t;
|
|
5095
5208
|
const info = endInfo(t.endReason);
|
|
5209
|
+
const waiting = !props.done && Array.isArray(t.approvals) && t.approvals.length > 0;
|
|
5096
5210
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-task", children: [
|
|
5097
5211
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-task-head", children: [
|
|
5098
5212
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-task-title", title: t.title, children: t.title || "(\u65E0\u6807\u9898)" }),
|
|
5099
|
-
props.done ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-tag " + info.cls, children: info.label }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-tag on", children: phaseLabel(t.phase) })
|
|
5213
|
+
props.done ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-tag " + info.cls, children: info.label }) : waiting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-tag warn", children: "\u7B49\u5F85\u786E\u8BA4" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-tag on", children: phaseLabel(t.phase) })
|
|
5100
5214
|
] }),
|
|
5101
5215
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-task-meta", children: [
|
|
5102
5216
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: (t.models && t.models.length ? t.models.join(", ") : "\u672A\u77E5") + (t.provider ? "\uFF08" + t.provider + "\uFF09" : "") }),
|
|
@@ -5105,6 +5219,7 @@ function TaskRow(props) {
|
|
|
5105
5219
|
t.totalTokens ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u21A7" + fmtCompact2(t.inputTokens) + " \u21A5" + fmtCompact2(t.outputTokens) }) : null,
|
|
5106
5220
|
props.done && t.endTime ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: fmtTime2(t.endTime) }) : null
|
|
5107
5221
|
] }),
|
|
5222
|
+
waiting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-task-err", children: t.approvals.map((a, i) => (a && a.toolName ? a.toolName : "\u672A\u77E5\u5DE5\u5177") + (a && a.reason ? "\uFF1A" + truncate(a.reason, 80) : "")).join("\uFF1B") }) : null,
|
|
5108
5223
|
props.done && t.errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-task-err", children: truncate(t.errorMessage, 120) }) : null
|
|
5109
5224
|
] });
|
|
5110
5225
|
}
|
|
@@ -5232,6 +5347,7 @@ function AnimationView(props) {
|
|
|
5232
5347
|
if (!cfg) {
|
|
5233
5348
|
rows.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-note", children: snap.error ? "\u72B6\u6001\u4E0D\u53EF\u7528\uFF1A" + snap.error : snap.loading ? "\u6B63\u5728\u62C9\u53D6\u4EFB\u52A1\u72B6\u6001\u2026" : "\u7B49\u5F85\u4EFB\u52A1\u72B6\u6001" }, "load"));
|
|
5234
5349
|
} else {
|
|
5350
|
+
const waitingCount2 = active.reduce((n, t) => n + (Array.isArray(t.approvals) ? t.approvals.length : 0), 0);
|
|
5235
5351
|
rows.push(
|
|
5236
5352
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-sec", children: [
|
|
5237
5353
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-sec-head", children: [
|
|
@@ -5351,6 +5467,19 @@ function AnimationView(props) {
|
|
|
5351
5467
|
),
|
|
5352
5468
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-sub", children: "\u51FA\u9519 / \u4E2D\u6B62 / \u8FBE\u8F93\u51FA\u4E0A\u9650\u65F6\u901A\u77E5" })
|
|
5353
5469
|
] }),
|
|
5470
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-row", children: [
|
|
5471
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-label", children: "\u9700\u786E\u8BA4\u63D0\u9192" }),
|
|
5472
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5473
|
+
"button",
|
|
5474
|
+
{
|
|
5475
|
+
type: "button",
|
|
5476
|
+
className: "dkm-miniswitch" + (cfg.notifyOnConfirm !== false ? " on" : ""),
|
|
5477
|
+
onClick: () => patch({ notifyOnConfirm: cfg.notifyOnConfirm === false }),
|
|
5478
|
+
children: cfg.notifyOnConfirm !== false ? "\u5F00" : "\u5173"
|
|
5479
|
+
}
|
|
5480
|
+
),
|
|
5481
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-sub", children: "\u5DE5\u5177\u7B49\u5F85\u4F60\u6279\u51C6\u65F6\u5F39\u5361\u7247\u5E76\u54CD\u786E\u8BA4\u97F3\uFF08\u5E38\u9A7B\u4E0D\u81EA\u52A8\u6D88\u5931\uFF09" })
|
|
5482
|
+
] }),
|
|
5354
5483
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-row", children: [
|
|
5355
5484
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-label", children: "\u505C\u7559\u65F6\u957F" }),
|
|
5356
5485
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
@@ -5393,7 +5522,7 @@ function AnimationView(props) {
|
|
|
5393
5522
|
children: cfg.soundNotify !== false ? "\u5F00" : "\u5173"
|
|
5394
5523
|
}
|
|
5395
5524
|
),
|
|
5396
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-sub", children: "\u4EFB\u52A1\u7ED3\u675F\u65F6\u64AD\u653E\uFF08\u8BD5\u542C\u4E3A\u5148\u64AD\u5B8C\u6210\u97F3\u3001\u540E\u64AD\u5F02\u5E38\u97F3\uFF09" })
|
|
5525
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-row-sub", children: "\u4EFB\u52A1\u7ED3\u675F/\u9700\u786E\u8BA4\u65F6\u64AD\u653E\uFF08\u8BD5\u542C\u4E3A\u5148\u64AD\u5B8C\u6210\u97F3\u3001\u540E\u64AD\u5F02\u5E38\u97F3\uFF09" })
|
|
5397
5526
|
] }),
|
|
5398
5527
|
cfg.soundNotify !== false ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-sounds", children: Object.keys(SOUND_LIBRARY).map((key) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
5399
5528
|
"button",
|
|
@@ -5558,7 +5687,7 @@ function AnimationView(props) {
|
|
|
5558
5687
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-sec", children: [
|
|
5559
5688
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dkan-sec-head", children: [
|
|
5560
5689
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-sec-title", children: "\u8FD0\u884C\u72B6\u6001" }),
|
|
5561
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-sec-sub", children: snap.error ? "\u72B6\u6001\u62C9\u53D6\u5931\u8D25\uFF1A" + snap.error : active.length > 0 ? active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D" : recent.length > 0 ? "\u7A7A\u95F2 \xB7 \u663E\u793A\u6700\u8FD1\u5B8C\u6210" : "\u7A7A\u95F2 \xB7 \u6682\u65E0\u4EFB\u52A1\u8BB0\u5F55" }),
|
|
5690
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dkan-sec-sub", children: snap.error ? "\u72B6\u6001\u62C9\u53D6\u5931\u8D25\uFF1A" + snap.error : waitingCount > 0 ? waitingCount + " \u9879\u7B49\u5F85\u786E\u8BA4 \xB7 " + active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D" : active.length > 0 ? active.length + " \u4E2A\u4EFB\u52A1\u8FDB\u884C\u4E2D" : recent.length > 0 ? "\u7A7A\u95F2 \xB7 \u663E\u793A\u6700\u8FD1\u5B8C\u6210" : "\u7A7A\u95F2 \xB7 \u6682\u65E0\u4EFB\u52A1\u8BB0\u5F55" }),
|
|
5562
5691
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "dkan-refresh", onClick: () => animationStore.refresh(), children: snap.loading ? "\u5237\u65B0\u4E2D\u2026" : "\u5237\u65B0" })
|
|
5563
5692
|
] }),
|
|
5564
5693
|
active.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dkan-tasks", children: active.map((t) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TaskRow, { t }, t.sessionId)) }) : null,
|
|
@@ -5630,7 +5759,9 @@ var css2 = [
|
|
|
5630
5759
|
".dkan-delivery-label{position:absolute;left:21px;top:58px;display:flex;align-items:baseline;gap:6px;padding:4px 8px;border:1px solid color-mix(in srgb,#93c5fd 30%,var(--dsw-alias-border-l1));border-radius:999px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 82%,transparent);backdrop-filter:blur(10px);color:var(--dsw-alias-label-secondary);font:10px/1.2 var(--ds-font-family,system-ui,sans-serif);white-space:nowrap;}.dkan-delivery-label b{color:var(--dsw-alias-label-primary);font-weight:650}.dkan-delivery-label span{color:var(--dk-accent);}",
|
|
5631
5760
|
"@media (max-width:1100px){.dkan-space-system,.dkan-space-runner{display:none}}",
|
|
5632
5761
|
".dkan-ready-freighter{position:fixed;width:210px;height:88px;z-index:9994;pointer-events:none;filter:drop-shadow(0 10px 14px rgb(0 0 0 / .18));}.dkan-ready-freighter>span:last-child{position:absolute;left:21px;top:58px;padding:4px 8px;border:1px solid color-mix(in srgb,#93c5fd 28%,var(--dsw-alias-border-l1));border-radius:999px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 80%,transparent);backdrop-filter:blur(10px);color:var(--dsw-alias-label-secondary);font:10px/1.2 var(--ds-font-family,system-ui,sans-serif);white-space:nowrap;}.dkan-departure{position:fixed;left:0;top:0;width:210px;height:88px;z-index:9994;pointer-events:none;will-change:transform,opacity;contain:layout paint style;isolation:isolate;animation:dkan-departure-flight var(--dkan-departure-duration,8600ms) cubic-bezier(.42,0,.85,.45) forwards;}@keyframes dkan-departure-flight{0%{opacity:0;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(1) rotate(var(--dkan-flight-angle,0deg))}6%{opacity:1;transform:translate3d(var(--dkan-from-x),var(--dkan-from-y),0) scale(1) rotate(var(--dkan-flight-angle,0deg))}100%{opacity:0;transform:translate3d(var(--dkan-to-x),var(--dkan-to-y),0) scale(.24) rotate(var(--dkan-flight-angle,0deg))}}",
|
|
5633
|
-
".dkan-space-stuck{position:fixed;
|
|
5762
|
+
".dkan-space-stuck{position:fixed;right:20px;top:88px;width:244px;height:160px;z-index:9993;pointer-events:none;border:1px solid color-mix(in srgb,#f59e0b 48%,var(--dsw-alias-border-l1));border-radius:20px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-2) 88%,transparent);backdrop-filter:blur(16px);box-shadow:0 18px 54px rgb(0 0 0 / .28),0 0 30px color-mix(in srgb,#f59e0b 15%,transparent);}.dkan-space-stuck .dkan-freighter{left:37px;top:11px;transform:scale(.9);transform-origin:top left;}.dkan-stuck-code{position:absolute;left:17px;right:17px;top:60px;height:36px;border-radius:7px;background:linear-gradient(90deg,color-mix(in srgb,#f59e0b 18%,transparent),transparent);color:var(--dk-warn);font:700 14px/36px var(--ds-font-family-code,monospace);letter-spacing:.12em;text-align:center;overflow:hidden;}.dkan-stuck-code::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent,color-mix(in srgb,#fef3c7 70%,transparent),transparent);transform:translateX(-110%);animation:dkan-stuck-scan 1.25s linear infinite;}.dkan-stuck-code i{display:inline-block;width:7px;height:7px;margin-right:8px;border-radius:50%;background:#f59e0b;box-shadow:0 0 9px #f59e0b;animation:dkan-stuck-pulse .8s ease-in-out infinite alternate;}.dkan-space-stuck strong{position:absolute;left:0;right:0;top:108px;color:var(--dsw-alias-label-primary);font:650 13px/1.2 var(--ds-font-family,system-ui,sans-serif);text-align:center;}.dkan-space-stuck small{position:absolute;left:18px;right:18px;top:128px;color:var(--dsw-alias-label-secondary);font:11px/1.25 var(--ds-font-family,system-ui,sans-serif);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}@keyframes dkan-stuck-scan{to{transform:translateX(110%)}}@keyframes dkan-stuck-pulse{to{transform:scale(.55);opacity:.45}}",
|
|
5763
|
+
// 窄屏(手机/分屏)贴右会溢出:回落到水平居中、屏幕上方,避开正文重心
|
|
5764
|
+
"@media (max-width:760px){.dkan-space-stuck{right:50%;transform:translateX(50%);top:64px;}}",
|
|
5634
5765
|
// 极光:顶部柔光带呼吸流动(加浓)
|
|
5635
5766
|
".dkan-aurora i{position:absolute;top:-40%;left:-20%;width:70%;height:80%;border-radius:50%;filter:blur(50px);opacity:.32;animation:dkan-aurora ease-in-out infinite alternate;}",
|
|
5636
5767
|
".dkan-aurora i:nth-child(1){background:#4d9fff;}",
|
|
@@ -5719,6 +5850,9 @@ var css2 = [
|
|
|
5719
5850
|
".dkan-toast-close{cursor:pointer;flex:none;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:6px;width:22px;height:22px;font-size:11px;line-height:1;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;}",
|
|
5720
5851
|
".dkan-toast-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
5721
5852
|
".dkan-toast-body{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.7;white-space:pre-line;word-break:break-word;}",
|
|
5853
|
+
// 需确认卡片:琥珀描边 + 缓慢呼吸光晕,常驻提醒直到用户处理
|
|
5854
|
+
".dkan-toast-confirm{border-color:color-mix(in srgb,var(--dk-warn) 55%,transparent);animation:dkan-toast-in .32s var(--ds-ease-in-out),dkan-confirm-glow 2.4s ease-in-out 0.4s infinite;}",
|
|
5855
|
+
"@keyframes dkan-confirm-glow{0%,100%{box-shadow:0 10px 36px rgb(0 0 0 / .22),0 0 0 0 color-mix(in srgb,var(--dk-warn) 30%,transparent)}50%{box-shadow:0 10px 36px rgb(0 0 0 / .22),0 0 14px 2px color-mix(in srgb,var(--dk-warn) 32%,transparent)}}",
|
|
5722
5856
|
// 面板页布局
|
|
5723
5857
|
".dkan-root{display:flex;flex-direction:column;gap:10px;}",
|
|
5724
5858
|
".dkan-note{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.6;}",
|
|
@@ -6151,11 +6285,16 @@ function rotations(shape) {
|
|
|
6151
6285
|
}
|
|
6152
6286
|
var PIECES = SHAPES.map((s) => ({ color: s.color, rots: rotations(s) }));
|
|
6153
6287
|
var TETRIS_GRID = (() => {
|
|
6154
|
-
const
|
|
6288
|
+
const parts = [];
|
|
6155
6289
|
let k = 0;
|
|
6156
|
-
for (let
|
|
6157
|
-
|
|
6158
|
-
|
|
6290
|
+
for (let j = 0; j < 20; j += 1) {
|
|
6291
|
+
for (let i = 0; i < 10; i += 1) {
|
|
6292
|
+
parts.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { className: "dgame-tetris-pit", x: i * 100 + 7, y: j * 100 + 7, width: 86, height: 86, rx: 10 }, k++));
|
|
6293
|
+
}
|
|
6294
|
+
}
|
|
6295
|
+
for (let i = 1; i < 10; i += 1) parts.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: i * 100, y1: 0, x2: i * 100, y2: 2e3 }, k++));
|
|
6296
|
+
for (let j = 1; j < 20; j += 1) parts.push(/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: 0, y1: j * 100, x2: 1e3, y2: j * 100 }, k++));
|
|
6297
|
+
return parts;
|
|
6159
6298
|
})();
|
|
6160
6299
|
function emptyBoard() {
|
|
6161
6300
|
return Array.from({ length: ROWS }, () => Array(COLS).fill(null));
|
|
@@ -6461,7 +6600,7 @@ function TetrisPreview() {
|
|
|
6461
6600
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dgcov-prev dgcov-prev-tetris", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dgp-tet-grid", children: ROWS3.flatMap((row, r) => row.split("").map((ch, c) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", { className: COLORS2[ch] ? "c" + COLORS2[ch] + (isFall(r) ? " fall" : "") : "" }, r + "-" + c))) }) });
|
|
6462
6601
|
}
|
|
6463
6602
|
var tetrisGame = { Game: TetrisGame, Preview: TetrisPreview, css: `
|
|
6464
|
-
.dgame-tetris{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start;align-self:center;width:fit-content;max-width:100%;margin-inline:auto;justify-content:center}.dgame-tetris-board{position:relative;flex:none;display:grid;grid-template-columns:repeat(10,1fr);grid-template-rows:repeat(20,1fr);width:min(100%,188px);aspect-ratio:10/20;border:1px solid color-mix(in srgb,rgb(34 211 238) 35%,var(--dsw-alias-border-l1));border-radius:8px;overflow:hidden;outline:none;background:linear-gradient(180deg,#0c1024,#131a3d);padding:0;box-shadow:inset 0 0 30px rgb(0 0 0/.45)}.dgame-tetris-board:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,rgb(34 211 238) 40%,transparent)}.dgame-tetris-cell{display:block;background:transparent;border-radius:2px;margin:1px}.dgame-tetris-nextbox{display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,1fr);width:60px;height:32px}.dgame-tetris-side{flex:1 1 96px;display:flex;flex-direction:column;gap:9px;min-width:0;max-width:220px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dgame-tetris-side b{color:var(--dsw-alias-label-secondary);font-size:12px}.dgame-tetris-side span{font-size:11px}.dgame-tetris-nextbox .dgame-tetris-cell{margin:1px}.dgame-tetris-keys span{display:block;line-height:1.6;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere}.dgame-tetris-next{display:flex;flex-direction:column;gap:5px;align-items:center}.dgame-tetris-next span{color:var(--dsw-alias-label-secondary)}.dgame-tetris-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.dgame-tetris-lines line{stroke
|
|
6603
|
+
.dgame-tetris{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start;align-self:center;width:fit-content;max-width:100%;margin-inline:auto;justify-content:center}.dgame-tetris-board{position:relative;flex:none;display:grid;grid-template-columns:repeat(10,1fr);grid-template-rows:repeat(20,1fr);width:min(100%,188px);aspect-ratio:10/20;border:1px solid color-mix(in srgb,rgb(34 211 238) 35%,var(--dsw-alias-border-l1));border-radius:8px;overflow:hidden;outline:none;background:linear-gradient(180deg,#0c1024,#131a3d);padding:0;box-shadow:inset 0 0 30px rgb(0 0 0/.45)}.dgame-tetris-board:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,rgb(34 211 238) 40%,transparent)}.dgame-tetris-cell{position:relative;z-index:1;display:block;background:transparent;border-radius:2px;margin:1px}.dgame-tetris-nextbox{display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,1fr);width:60px;height:32px}.dgame-tetris-side{flex:1 1 96px;display:flex;flex-direction:column;gap:9px;min-width:0;max-width:220px;color:var(--dsw-alias-label-tertiary);font-size:11px}.dgame-tetris-side b{color:var(--dsw-alias-label-secondary);font-size:12px}.dgame-tetris-side span{font-size:11px}.dgame-tetris-nextbox .dgame-tetris-cell{margin:1px}.dgame-tetris-keys span{display:block;line-height:1.6;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere}.dgame-tetris-next{display:flex;flex-direction:column;gap:5px;align-items:center}.dgame-tetris-next span{color:var(--dsw-alias-label-secondary)}.dgame-tetris-lines{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.dgame-tetris-lines line{stroke:rgb(96 165 250/.28);stroke-width:3}.dgame-tetris-lines .dgame-tetris-pit{fill:rgb(0 0 0/.42);stroke:rgb(255 255 255/.07);stroke-width:2}@media (max-width:680px){.dgame-tetris{width:100%;gap:8px}.dgame-tetris-board{width:min(100%,170px)}}
|
|
6465
6604
|
` };
|
|
6466
6605
|
|
|
6467
6606
|
// features/games/games/sokoban.jsx
|
|
@@ -7314,6 +7453,18 @@ var XIANGQI_LINES = (() => {
|
|
|
7314
7453
|
}
|
|
7315
7454
|
return parts;
|
|
7316
7455
|
})();
|
|
7456
|
+
var CN_NUMS = ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
|
|
7457
|
+
function moveNotation(board, fr, fc, tr, tc) {
|
|
7458
|
+
const p = board[fr][fc];
|
|
7459
|
+
if (!p) return "";
|
|
7460
|
+
const red = p.c === "r";
|
|
7461
|
+
const num = (n) => red ? CN_NUMS[n - 1] : String(n);
|
|
7462
|
+
const file = (c) => red ? 9 - c : c + 1;
|
|
7463
|
+
const forward = red ? tr < fr : tr > fr;
|
|
7464
|
+
const verb = fr === tr ? "\u5E73" : forward ? "\u8FDB" : "\u9000";
|
|
7465
|
+
const to = fr === tr || p.t === "h" || p.t === "e" || p.t === "a" ? file(tc) : Math.abs(tr - fr);
|
|
7466
|
+
return pieceChar(p) + num(file(fc)) + verb + num(to);
|
|
7467
|
+
}
|
|
7317
7468
|
function XiangqiGame(props) {
|
|
7318
7469
|
const [board, setBoard] = (0, import_react13.useState)(initialBoard);
|
|
7319
7470
|
const [turn, setTurn] = (0, import_react13.useState)("r");
|
|
@@ -7322,6 +7473,9 @@ function XiangqiGame(props) {
|
|
|
7322
7473
|
const [over, setOver] = (0, import_react13.useState)(null);
|
|
7323
7474
|
const [check, setCheck] = (0, import_react13.useState)(false);
|
|
7324
7475
|
const [last, setLast] = (0, import_react13.useState)(null);
|
|
7476
|
+
const [lastMove, setLastMove] = (0, import_react13.useState)(null);
|
|
7477
|
+
const [moveLog, setMoveLog] = (0, import_react13.useState)([]);
|
|
7478
|
+
const [moving, setMoving] = (0, import_react13.useState)(null);
|
|
7325
7479
|
const [thinking, setThinking] = (0, import_react13.useState)(false);
|
|
7326
7480
|
const [history, setHistory] = (0, import_react13.useState)([]);
|
|
7327
7481
|
const [repKeys, setRepKeys] = (0, import_react13.useState)(() => [posKey(initialBoard())]);
|
|
@@ -7337,7 +7491,43 @@ function XiangqiGame(props) {
|
|
|
7337
7491
|
thinkingRef.current = thinking;
|
|
7338
7492
|
const historyRef = (0, import_react13.useRef)(history);
|
|
7339
7493
|
historyRef.current = history;
|
|
7494
|
+
const movingRef = (0, import_react13.useRef)(false);
|
|
7495
|
+
const pendingRef = (0, import_react13.useRef)(null);
|
|
7496
|
+
const animTimerRef = (0, import_react13.useRef)(null);
|
|
7497
|
+
const animateMove = (0, import_react13.useCallback)((b, fr, fc, tr, tc, after) => {
|
|
7498
|
+
const piece = boardRef.current[fr][fc];
|
|
7499
|
+
const capture = !!boardRef.current[tr][tc];
|
|
7500
|
+
pendingRef.current = { board: b, after };
|
|
7501
|
+
movingRef.current = true;
|
|
7502
|
+
setSel(null);
|
|
7503
|
+
setTargets([]);
|
|
7504
|
+
setMoving({ fr, fc, tr, tc, piece, capture });
|
|
7505
|
+
playSfx(capture ? "capture" : "step");
|
|
7506
|
+
if (animTimerRef.current) clearTimeout(animTimerRef.current);
|
|
7507
|
+
animTimerRef.current = setTimeout(() => {
|
|
7508
|
+
animTimerRef.current = null;
|
|
7509
|
+
const pend = pendingRef.current;
|
|
7510
|
+
pendingRef.current = null;
|
|
7511
|
+
movingRef.current = false;
|
|
7512
|
+
setMoving(null);
|
|
7513
|
+
if (pend) {
|
|
7514
|
+
const text = moveNotation(boardRef.current, fr, fc, tr, tc);
|
|
7515
|
+
boardRef.current = pend.board;
|
|
7516
|
+
setBoard(pend.board);
|
|
7517
|
+
setLastMove({ fr, fc, tr, tc, text });
|
|
7518
|
+
setMoveLog((log) => log.concat({ side: piece.c, text }));
|
|
7519
|
+
setLast([tr, tc]);
|
|
7520
|
+
if (pend.after) pend.after();
|
|
7521
|
+
}
|
|
7522
|
+
}, 260);
|
|
7523
|
+
}, []);
|
|
7340
7524
|
const restart = (0, import_react13.useCallback)(() => {
|
|
7525
|
+
if (animTimerRef.current) {
|
|
7526
|
+
clearTimeout(animTimerRef.current);
|
|
7527
|
+
animTimerRef.current = null;
|
|
7528
|
+
}
|
|
7529
|
+
pendingRef.current = null;
|
|
7530
|
+
movingRef.current = false;
|
|
7341
7531
|
const b = initialBoard();
|
|
7342
7532
|
boardRef.current = b;
|
|
7343
7533
|
setBoard(b);
|
|
@@ -7349,10 +7539,13 @@ function XiangqiGame(props) {
|
|
|
7349
7539
|
setLast(null);
|
|
7350
7540
|
setThinking(false);
|
|
7351
7541
|
setHistory([]);
|
|
7542
|
+
setLastMove(null);
|
|
7543
|
+
setMoveLog([]);
|
|
7544
|
+
setMoving(null);
|
|
7352
7545
|
setRepKeys([posKey(b)]);
|
|
7353
7546
|
}, []);
|
|
7354
7547
|
const undo2 = (0, import_react13.useCallback)(() => {
|
|
7355
|
-
if (thinkingRef.current || overRef.current || turnRef.current !== "r") return;
|
|
7548
|
+
if (thinkingRef.current || overRef.current || turnRef.current !== "r" || movingRef.current) return;
|
|
7356
7549
|
const h = historyRef.current;
|
|
7357
7550
|
if (h.length < 2) return;
|
|
7358
7551
|
const hist = h.slice(0, -2);
|
|
@@ -7363,31 +7556,28 @@ function XiangqiGame(props) {
|
|
|
7363
7556
|
setSel(null);
|
|
7364
7557
|
setTargets([]);
|
|
7365
7558
|
setLast(null);
|
|
7559
|
+
setLastMove(null);
|
|
7560
|
+
setMoveLog((prevLog) => prevLog.slice(0, -2));
|
|
7366
7561
|
setOver(null);
|
|
7367
7562
|
setCheck(inCheck(b, "r"));
|
|
7368
7563
|
setRepKeys(hist.map(posKey).concat(posKey(b)));
|
|
7369
7564
|
}, []);
|
|
7370
7565
|
const moveRed = (0, import_react13.useCallback)((tr, tc) => {
|
|
7371
|
-
if (turnRef.current !== "r" || overRef.current || !sel) return;
|
|
7566
|
+
if (turnRef.current !== "r" || overRef.current || !sel || movingRef.current) return;
|
|
7372
7567
|
const fr = sel[0], fc = sel[1];
|
|
7373
|
-
if (boardRef.current[tr][tc]) playSfx("capture");
|
|
7374
|
-
else playSfx("step");
|
|
7375
7568
|
const nb = applyMove(boardRef.current, fr, fc, tr, tc);
|
|
7376
7569
|
setHistory((h) => [...h, boardRef.current]);
|
|
7377
|
-
boardRef.current = nb;
|
|
7378
7570
|
pushKey(nb);
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
} else setCheck(inCheck(nb, "b"));
|
|
7388
|
-
}, [sel, pushKey]);
|
|
7571
|
+
animateMove(nb, fr, fc, tr, tc, () => {
|
|
7572
|
+
setTurn("b");
|
|
7573
|
+
if (!hasLegalMoves(nb, "b")) {
|
|
7574
|
+
setOver("r");
|
|
7575
|
+
setCheck(false);
|
|
7576
|
+
} else setCheck(inCheck(nb, "b"));
|
|
7577
|
+
});
|
|
7578
|
+
}, [sel, pushKey, animateMove]);
|
|
7389
7579
|
const select = (0, import_react13.useCallback)((r, c) => {
|
|
7390
|
-
if (overRef.current || turnRef.current !== "r" || thinkingRef.current) return;
|
|
7580
|
+
if (overRef.current || turnRef.current !== "r" || thinkingRef.current || movingRef.current) return;
|
|
7391
7581
|
const p = boardRef.current[r][c];
|
|
7392
7582
|
if (p && p.c === "r") {
|
|
7393
7583
|
setSel([r, c]);
|
|
@@ -7403,32 +7593,29 @@ function XiangqiGame(props) {
|
|
|
7403
7593
|
setTargets([]);
|
|
7404
7594
|
}, [sel, targets, moveRed]);
|
|
7405
7595
|
(0, import_react13.useEffect)(() => {
|
|
7406
|
-
if (turn !== "b" || over || props.paused) return;
|
|
7596
|
+
if (turn !== "b" || over || props.paused || movingRef.current) return;
|
|
7407
7597
|
const t = setTimeout(() => {
|
|
7408
7598
|
const seenCounts = /* @__PURE__ */ new Map();
|
|
7409
7599
|
for (const k of repKeys) seenCounts.set(k, (seenCounts.get(k) || 0) + 1);
|
|
7410
7600
|
const mv = bestMove(boardRef.current, "b", 3, seenCounts);
|
|
7411
7601
|
if (mv) {
|
|
7412
7602
|
const [fr, fc, tr, tc] = mv;
|
|
7413
|
-
if (boardRef.current[tr][tc]) playSfx("capture");
|
|
7414
|
-
else playSfx("step");
|
|
7415
7603
|
const nb = applyMove(boardRef.current, fr, fc, tr, tc);
|
|
7416
7604
|
setHistory((h) => [...h, boardRef.current]);
|
|
7417
|
-
boardRef.current = nb;
|
|
7418
7605
|
pushKey(nb);
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
setCheck(
|
|
7425
|
-
}
|
|
7606
|
+
animateMove(nb, fr, fc, tr, tc, () => {
|
|
7607
|
+
setTurn("r");
|
|
7608
|
+
if (!hasLegalMoves(nb, "r")) {
|
|
7609
|
+
setOver("b");
|
|
7610
|
+
setCheck(false);
|
|
7611
|
+
} else setCheck(inCheck(nb, "r"));
|
|
7612
|
+
});
|
|
7426
7613
|
} else setOver("r");
|
|
7427
7614
|
setThinking(false);
|
|
7428
|
-
},
|
|
7615
|
+
}, 420);
|
|
7429
7616
|
setThinking(true);
|
|
7430
7617
|
return () => clearTimeout(t);
|
|
7431
|
-
}, [turn, over, props.paused, repKeys, pushKey]);
|
|
7618
|
+
}, [turn, over, props.paused, repKeys, pushKey, animateMove]);
|
|
7432
7619
|
const onKeyDown = (0, import_react13.useCallback)((event) => {
|
|
7433
7620
|
if (event.key.toLowerCase() === "r") {
|
|
7434
7621
|
event.preventDefault();
|
|
@@ -7439,7 +7626,7 @@ function XiangqiGame(props) {
|
|
|
7439
7626
|
}
|
|
7440
7627
|
}, [restart, undo2]);
|
|
7441
7628
|
useGameControls(stageRef, props.paused, onKeyDown);
|
|
7442
|
-
const status = over === "r" ? "\u7EA2\u65B9\u80DC \xB7 \u606D\u559C" : over === "b" ? "\u9ED1\u65B9\u80DC \xB7 AI \u8D62" : thinking ? "AI \u601D\u8003\u4E2D\u2026" : check ? "\u5C06\u519B\uFF01" : turn === "r" ? "\u8F6E\u5230\u4F60\uFF08\u7EA2\u65B9\uFF09" : "\u8F6E\u5230 AI\uFF08\u9ED1\u65B9\uFF09";
|
|
7629
|
+
const status = over === "r" ? "\u7EA2\u65B9\u80DC \xB7 \u606D\u559C" : over === "b" ? "\u9ED1\u65B9\u80DC \xB7 AI \u8D62" : moving ? moving.piece.c === "r" ? "\u7EA2\u65B9\u8D70\u5B50\u2026" : "AI \u8D70\u5B50\u2026" : thinking ? "AI \u601D\u8003\u4E2D\u2026" : check ? "\u5C06\u519B\uFF01" : turn === "r" ? "\u8F6E\u5230\u4F60\uFF08\u7EA2\u65B9\uFF09" : "\u8F6E\u5230 AI\uFF08\u9ED1\u65B9\uFF09";
|
|
7443
7630
|
const prevCheck = (0, import_react13.useRef)(false);
|
|
7444
7631
|
(0, import_react13.useEffect)(() => {
|
|
7445
7632
|
if (over === "r") playSfx("win");
|
|
@@ -7447,6 +7634,9 @@ function XiangqiGame(props) {
|
|
|
7447
7634
|
else if (!thinking && check && !prevCheck.current) playSfx("check");
|
|
7448
7635
|
prevCheck.current = !thinking && check;
|
|
7449
7636
|
}, [check, thinking, over]);
|
|
7637
|
+
(0, import_react13.useEffect)(() => () => {
|
|
7638
|
+
if (animTimerRef.current) clearTimeout(animTimerRef.current);
|
|
7639
|
+
}, []);
|
|
7450
7640
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "dgame-game", "aria-label": "\u8C61\u68CB", children: [
|
|
7451
7641
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dgame-game-head", children: [
|
|
7452
7642
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
@@ -7467,26 +7657,47 @@ function XiangqiGame(props) {
|
|
|
7467
7657
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("text", { className: "dgame-xiangqi-rivertext", x: 670, y: 505, children: "\u6F22 \u754C" })
|
|
7468
7658
|
] }),
|
|
7469
7659
|
board.map((row, r) => row.map((p, c) => {
|
|
7660
|
+
const mv = moving;
|
|
7661
|
+
const isFlyFrom = mv && mv.fr === r && mv.fc === c;
|
|
7662
|
+
const isDying = mv && mv.capture && mv.tr === r && mv.tc === c;
|
|
7470
7663
|
const isSel = sel && sel[0] === r && sel[1] === c;
|
|
7471
7664
|
const isTargetMark = targets.some(([tr, tc]) => tr === r && tc === c);
|
|
7665
|
+
const isLastMoveFrom = lastMove && lastMove.fr === r && lastMove.fc === c;
|
|
7666
|
+
const isLand = !mv && lastMove && lastMove.tr === r && lastMove.tc === c;
|
|
7472
7667
|
const isLast = last && last[0] === r && last[1] === c;
|
|
7473
7668
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
7474
7669
|
"button",
|
|
7475
7670
|
{
|
|
7476
7671
|
type: "button",
|
|
7477
7672
|
role: "gridcell",
|
|
7478
|
-
className: "dgame-xiangqi-cell" + (isSel ? " sel" : "") + (isTargetMark ? " target" : "") + (isLast ? " last" : ""),
|
|
7673
|
+
className: "dgame-xiangqi-cell" + (isSel ? " sel" : "") + (isTargetMark ? " target" : "") + (isLastMoveFrom ? " from" : "") + (isLand ? " land" : "") + (isLast ? " last" : ""),
|
|
7479
7674
|
"aria-label": "\u7B2C" + (r + 1) + "\u884C\u7B2C" + (c + 1) + "\u5217" + (p ? pieceChar(p) : " \u7A7A"),
|
|
7480
7675
|
onClick: () => {
|
|
7481
7676
|
focusStage(stageRef);
|
|
7482
7677
|
select(r, c);
|
|
7483
7678
|
},
|
|
7484
|
-
children: p ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dgame-xiangqi-pc " + p.c, children: pieceChar(p) }) : isTargetMark ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dgame-xiangqi-dot", "aria-hidden": "true" }) : null
|
|
7679
|
+
children: p && !isFlyFrom ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dgame-xiangqi-pc " + p.c + (isDying ? " dying" : ""), children: pieceChar(p) }) : !p && isTargetMark ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dgame-xiangqi-dot", "aria-hidden": "true" }) : null
|
|
7485
7680
|
},
|
|
7486
7681
|
r + "-" + c
|
|
7487
7682
|
);
|
|
7488
|
-
}))
|
|
7683
|
+
})),
|
|
7684
|
+
moving ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
7685
|
+
"span",
|
|
7686
|
+
{
|
|
7687
|
+
className: "dgame-xiangqi-pc dgame-xiangqi-fly " + moving.piece.c,
|
|
7688
|
+
style: {
|
|
7689
|
+
"--fx0": (moving.fc + 0.5) / 9,
|
|
7690
|
+
"--fy0": (moving.fr + 0.5) / 10,
|
|
7691
|
+
"--fx1": (moving.tc + 0.5) / 9,
|
|
7692
|
+
"--fy1": (moving.tr + 0.5) / 10
|
|
7693
|
+
},
|
|
7694
|
+
"aria-hidden": "true",
|
|
7695
|
+
children: pieceChar(moving.piece)
|
|
7696
|
+
},
|
|
7697
|
+
moving.fr + "-" + moving.fc + "-" + moving.tr + "-" + moving.tc + "-" + moving.piece.c
|
|
7698
|
+
) : null
|
|
7489
7699
|
] }),
|
|
7700
|
+
moveLog.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dgame-xiangqi-log", role: "status", "aria-live": "polite", children: moveLog.slice(-4).map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: m.side, children: m.text }, moveLog.length - 4 + i)) }) : null,
|
|
7490
7701
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dgame-controls", children: [
|
|
7491
7702
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: undo2, children: "\u64A4\u9500" }),
|
|
7492
7703
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
@@ -7524,7 +7735,7 @@ function XiangqiPreview() {
|
|
|
7524
7735
|
] }) });
|
|
7525
7736
|
}
|
|
7526
7737
|
var xiangqiGame = { Game: XiangqiGame, Preview: XiangqiPreview, css: `
|
|
7527
|
-
.dgame-xiangqi-board{position:relative;display:grid;grid-template-columns:repeat(9,1fr);grid-template-rows:repeat(10,1fr);align-self:center;width:min(100%,min(90vw,340px));aspect-ratio:9/10;padding:13px;border-radius:12px;border:1px solid color-mix(in srgb,#7c4f16 65%,transparent);box-shadow:0 12px 32px rgb(0 0 0/.5),inset 0 1px 0 rgba(255,236,200,.55),inset 0 -3px 9px rgba(90,50,10,.35),inset 3px 0 8px rgba(255,224,170,.28),inset -3px 0 8px rgba(120,70,20,.25);outline:none;background:repeating-linear-gradient(94deg,rgba(124,79,22,.05) 0 2px,transparent 2px 11px),repeating-linear-gradient(87deg,rgba(255,238,196,.05) 0 2px,transparent 2px 14px),radial-gradient(130% 105% at 26% 8%,#f0cd86,#ddb067 48%,#cb9a51 78%,#bb8844)}.dgame-xiangqi-lines{position:absolute;inset:13px;pointer-events:none}.dgame-xiangqi-lines line,.dgame-xiangqi-lines path{stroke:#66431a;stroke-width:3.4;fill:none;stroke-linecap:square}.dgame-xiangqi-lines .dgame-xiangqi-mark{stroke-width:2.6}.dgame-xiangqi-rivertext{fill:rgba(102,67,26,.7);font-family:KaiTi,"Kaiti SC","STKaiti","FangSong",serif;font-size:46px;letter-spacing:7px;text-anchor:middle;dominant-baseline:central}.dgame-xiangqi-board:focus-visible{box-shadow:0 0 0 3px rgba(0,0,0,.25)}.dgame-xiangqi-cell{position:relative;z-index:1;background:transparent;border:none;cursor:pointer;padding:0;margin:0;outline:none;display:grid;place-items:center;min-width:0;min-height:0}.dgame-xiangqi-cell.target .dgame-xiangqi-dot{width:12px;height:12px;border-radius:50%;background:rgba(34,211,238,.6);box-shadow:0 0 10px rgba(34,211,238,.65),0 0 0 2px rgba(255,255,255,.28)}.dgame-xiangqi-cell.target .dgame-xiangqi-pc{box-shadow:0 0 0 2px rgba(248,113,113,.85),0 0 10px rgba(248,113,113,.5),0 2px 4px rgb(0 0 0/.4),inset 0 0 0 1.5px rgba(96,62,18,.5),inset 0 1px 2px rgba(255,255,255,.95),inset 0 -2px 3px rgba(120,80,20,.4)}.dgame-xiangqi-cell.sel .dgame-xiangqi-pc::before{content:'';position:absolute;inset:-3px;border-radius:50%;border:2.5px solid rgba(251,191,36,.95);box-shadow:0 0 12px rgba(251,191,36,.6)}.dgame-xiangqi-cell.last .dgame-xiangqi-pc::after{content:'';position:absolute;right:5%;bottom:5%;width:5px;height:5px;border-radius:50%;background:#ef4444;box-shadow:0 0 4px rgba(239,68,68,.8)}.dgame-xiangqi-pc{position:relative;display:grid;place-items:center;z-index:1;width:min(80%,30px);aspect-ratio:1/1;border-radius:50%;box-sizing:border-box;font-family:KaiTi,"Kaiti SC","STKaiti","FangSong","SimSun",serif;font-size:clamp(12px,1.4vw,15px);font-weight:700;line-height:1;background:radial-gradient(circle at 34% 28%,#fff3d4,#eedaa6 46%,#d8b675 72%,#bd9650);box-shadow:0 2px 4px rgb(0 0 0/.45),inset 0 0 0 1.5px rgba(96,62,18,.5),inset 0 1px 2px rgba(255,255,255,.95),inset 0 -2px 3px rgba(120,80,20,.4)}.dgame-xiangqi-pc.r{color:#b91c1c;text-shadow:0 1px 0 rgba(255,255,255,.5)}.dgame-xiangqi-
|
|
7738
|
+
.dgame-xiangqi-board{position:relative;display:grid;grid-template-columns:repeat(9,1fr);grid-template-rows:repeat(10,1fr);align-self:center;width:min(100%,min(90vw,340px));aspect-ratio:9/10;padding:13px;border-radius:12px;border:1px solid color-mix(in srgb,#7c4f16 65%,transparent);box-shadow:0 12px 32px rgb(0 0 0/.5),inset 0 1px 0 rgba(255,236,200,.55),inset 0 -3px 9px rgba(90,50,10,.35),inset 3px 0 8px rgba(255,224,170,.28),inset -3px 0 8px rgba(120,70,20,.25);outline:none;background:repeating-linear-gradient(94deg,rgba(124,79,22,.05) 0 2px,transparent 2px 11px),repeating-linear-gradient(87deg,rgba(255,238,196,.05) 0 2px,transparent 2px 14px),radial-gradient(130% 105% at 26% 8%,#f0cd86,#ddb067 48%,#cb9a51 78%,#bb8844)}.dgame-xiangqi-lines{position:absolute;inset:13px;pointer-events:none}.dgame-xiangqi-lines line,.dgame-xiangqi-lines path,.dgame-xiangqi-lines rect{stroke:#66431a;stroke-width:3.4;fill:none;stroke-linecap:square}.dgame-xiangqi-lines rect{stroke-width:7}.dgame-xiangqi-lines .dgame-xiangqi-mark{stroke-width:2.6}.dgame-xiangqi-rivertext{fill:rgba(102,67,26,.7);font-family:KaiTi,"Kaiti SC","STKaiti","FangSong",serif;font-size:46px;letter-spacing:7px;text-anchor:middle;dominant-baseline:central}.dgame-xiangqi-board:focus-visible{box-shadow:0 0 0 3px rgba(0,0,0,.25)}.dgame-xiangqi-cell{position:relative;z-index:1;background:transparent;border:none;cursor:pointer;padding:0;margin:0;outline:none;display:grid;place-items:center;min-width:0;min-height:0}.dgame-xiangqi-cell.target .dgame-xiangqi-dot{width:12px;height:12px;border-radius:50%;background:rgba(34,211,238,.6);box-shadow:0 0 10px rgba(34,211,238,.65),0 0 0 2px rgba(255,255,255,.28)}.dgame-xiangqi-cell.target .dgame-xiangqi-pc{box-shadow:0 0 0 2px rgba(248,113,113,.85),0 0 10px rgba(248,113,113,.5),0 2px 4px rgb(0 0 0/.4),inset 0 0 0 1.5px rgba(96,62,18,.5),inset 0 1px 2px rgba(255,255,255,.95),inset 0 -2px 3px rgba(120,80,20,.4)}.dgame-xiangqi-cell.sel .dgame-xiangqi-pc::before{content:'';position:absolute;inset:-3px;border-radius:50%;border:2.5px solid rgba(251,191,36,.95);box-shadow:0 0 12px rgba(251,191,36,.6)}.dgame-xiangqi-cell.from::before{content:'';position:absolute;inset:50% auto auto 50%;width:34%;height:34%;transform:translate(-50%,-50%);border-radius:50%;border:2.5px dashed rgba(102,67,26,.75);pointer-events:none}.dgame-xiangqi-cell.land .dgame-xiangqi-pc{animation:dgame-xq-land .28s cubic-bezier(.2,.85,.3,1.25)}.dgame-xiangqi-cell.last .dgame-xiangqi-pc::after{content:'';position:absolute;right:5%;bottom:5%;width:5px;height:5px;border-radius:50%;background:#ef4444;box-shadow:0 0 4px rgba(239,68,68,.8)}.dgame-xiangqi-pc{position:relative;display:grid;place-items:center;z-index:1;width:min(80%,30px);aspect-ratio:1/1;border-radius:50%;box-sizing:border-box;font-family:KaiTi,"Kaiti SC","STKaiti","FangSong","SimSun",serif;font-size:clamp(12px,1.4vw,15px);font-weight:700;line-height:1;background:radial-gradient(circle at 34% 28%,#fff3d4,#eedaa6 46%,#d8b675 72%,#bd9650);box-shadow:0 2px 4px rgb(0 0 0/.45),inset 0 0 0 1.5px rgba(96,62,18,.5),inset 0 1px 2px rgba(255,255,255,.95),inset 0 -2px 3px rgba(120,80,20,.4)}.dgame-xiangqi-pc.dying{animation:dgame-xq-die .26s ease forwards}.dgame-xiangqi-fly{position:absolute;z-index:5;width:calc((100% - 26px)*.0889);aspect-ratio:1/1;border-radius:50%;display:grid;place-items:center;box-sizing:border-box;font-family:KaiTi,"Kaiti SC","STKaiti","FangSong","SimSun",serif;font-size:clamp(12px,1.4vw,15px);font-weight:700;line-height:1;pointer-events:none;background:radial-gradient(circle at 34% 28%,#fff3d4,#eedaa6 46%,#d8b675 72%,#bd9650);box-shadow:0 6px 14px rgb(0 0 0/.5),0 0 0 1.5px rgba(96,62,18,.35),inset 0 0 0 1.5px rgba(96,62,18,.5),inset 0 1px 2px rgba(255,255,255,.95),inset 0 -2px 3px rgba(120,80,20,.4);animation:dgame-xq-hop .26s cubic-bezier(.3,.7,.4,1) forwards}.dgame-xiangqi-fly.r{color:#b91c1c;text-shadow:0 1px 0 rgba(255,255,255,.5)}.dgame-xiangqi-fly.b{color:#1f2937;text-shadow:0 1px 0 rgba(255,255,255,.35)}@keyframes dgame-xq-hop{0%{left:calc(13px + var(--fx0)*(100% - 26px));top:calc(13px + var(--fy0)*(100% - 26px));transform:translate(-50%,-50%) scale(.9);opacity:.85}55%{transform:translate(-50%,-64%) scale(1.16);opacity:1}100%{left:calc(13px + var(--fx1)*(100% - 26px));top:calc(13px + var(--fy1)*(100% - 26px));transform:translate(-50%,-50%) scale(1)}}@keyframes dgame-xq-land{0%{transform:scale(1.18)}100%{transform:scale(1)}}@keyframes dgame-xq-die{to{opacity:0;transform:scale(.55)}}.dgame-xiangqi-log{display:flex;flex-wrap:wrap;justify-content:center;gap:5px 12px;align-self:center;min-height:22px;color:var(--dsw-alias-label-secondary);font-family:KaiTi,"Kaiti SC","STKaiti","FangSong",serif;font-size:13px}.dgame-xiangqi-log span{opacity:.65}.dgame-xiangqi-log span:last-child{opacity:1;font-weight:700}.dgame-xiangqi-log .r{color:#c03434}.dgame-xiangqi-log .b{color:var(--dsw-alias-label-primary)}
|
|
7528
7739
|
` };
|
|
7529
7740
|
|
|
7530
7741
|
// features/games/games/snake.jsx
|
|
@@ -7858,7 +8069,7 @@ function BreakoutGame(props) {
|
|
|
7858
8069
|
if (keys.current.right) g.paddle.x += 5.5;
|
|
7859
8070
|
g.paddle.x = Math.max(0, Math.min(W - PADDLE_W, g.paddle.x));
|
|
7860
8071
|
const b = g.ball;
|
|
7861
|
-
if (!
|
|
8072
|
+
if (!g.launched) {
|
|
7862
8073
|
b.x = g.paddle.x + PADDLE_W / 2;
|
|
7863
8074
|
b.y = g.paddle.y - BALL_R - 1;
|
|
7864
8075
|
} else {
|
|
@@ -7985,7 +8196,10 @@ function BreakoutGame(props) {
|
|
|
7985
8196
|
] })
|
|
7986
8197
|
] }),
|
|
7987
8198
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dgame-breakout", children: [
|
|
7988
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("canvas", { ref: canvasRef, width: W, height: H, tabIndex: 0, onKeyDown, onKeyUp, onPointerMove, onClick: () =>
|
|
8199
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("canvas", { ref: canvasRef, width: W, height: H, tabIndex: 0, onKeyDown, onKeyUp, onPointerMove, onClick: (e) => {
|
|
8200
|
+
focusStage(canvasRef);
|
|
8201
|
+
launchBall();
|
|
8202
|
+
}, className: "dgame-breakout-canvas", "aria-label": "\u6253\u7816\u5757\u6E38\u620F\u533A\u57DF\uFF0C\u5DE6\u53F3\u65B9\u5411\u952E\u6216\u9F20\u6807\u79FB\u52A8\u6321\u677F\uFF0C\u7A7A\u683C\u6216\u70B9\u51FB\u53D1\u7403" }),
|
|
7989
8203
|
status === "win" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "dgame-over", children: [
|
|
7990
8204
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("strong", { children: [
|
|
7991
8205
|
"\u5168\u6D88\uFF01\u8FDB\u5165\u7B2C ",
|
|
@@ -8019,7 +8233,7 @@ function BreakoutGame(props) {
|
|
|
8019
8233
|
keys.current.left = false;
|
|
8020
8234
|
game.current && (game.current.paddle.x = Math.max(0, game.current.paddle.x - 12));
|
|
8021
8235
|
}, children: "\u2190 \u5DE6\u79FB" }),
|
|
8022
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\u2190/\u2192 \u6216\u9F20\u6807\u79FB\u52A8 \xB7 \u7A7A\u683C\u53D1\u7403" }),
|
|
8236
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "\u2190/\u2192 \u6216\u9F20\u6807\u79FB\u52A8 \xB7 \u7A7A\u683C/\u70B9\u51FB\u53D1\u7403" }),
|
|
8023
8237
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", "aria-label": "\u5411\u53F3\u79FB\u52A8", onClick: () => {
|
|
8024
8238
|
keys.current.right = false;
|
|
8025
8239
|
game.current && (game.current.paddle.x = Math.min(W - PADDLE_W, game.current.paddle.x + 12));
|
|
@@ -8083,7 +8297,7 @@ function RacerGame(props) {
|
|
|
8083
8297
|
const reset = (0, import_react16.useCallback)(() => {
|
|
8084
8298
|
game.current = {
|
|
8085
8299
|
stars: Array.from({ length: 50 }, () => ({ x: Math.random() * W2, y: Math.random() * H2, a: 0.2 + Math.random() * 0.5 })),
|
|
8086
|
-
player: { x: laneX(1), y: H2 - CAR_H - 16 },
|
|
8300
|
+
player: { x: laneX(1), y: H2 - CAR_H - 16, w: CAR_W, h: CAR_H },
|
|
8087
8301
|
enemies: [],
|
|
8088
8302
|
coins: [],
|
|
8089
8303
|
dist: 0,
|
|
@@ -8955,7 +9169,7 @@ var GAMES = [
|
|
|
8955
9169
|
cat: "classic",
|
|
8956
9170
|
accent: "#38bdf8",
|
|
8957
9171
|
desc: "\u79FB\u52A8\u6321\u677F\u53CD\u5F39\u5C0F\u7403\uFF0C\u51FB\u788E\u5168\u90E8\u7816\u5757\uFF1B\u7403\u6389\u5230\u5E95\u90E8\u4E22\u4E00\u6761\u547D\u3002",
|
|
8958
|
-
tip: "\u2190/\u2192 \u6216\u9F20\u6807\u79FB\u52A8 \xB7 \u7A7A\u683C\u53D1\u7403",
|
|
9172
|
+
tip: "\u2190/\u2192 \u6216\u9F20\u6807\u79FB\u52A8 \xB7 \u7A7A\u683C/\u70B9\u51FB\u53D1\u7403",
|
|
8959
9173
|
Game: breakoutGame.Game,
|
|
8960
9174
|
Preview: breakoutGame.Preview
|
|
8961
9175
|
},
|
|
@@ -9781,7 +9995,7 @@ var feature8 = {
|
|
|
9781
9995
|
};
|
|
9782
9996
|
|
|
9783
9997
|
// src/client.jsx
|
|
9784
|
-
var DOCK_VERSION = "0.9.
|
|
9998
|
+
var DOCK_VERSION = "0.9.3";
|
|
9785
9999
|
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8];
|
|
9786
10000
|
var PLANNED_FEATURES = [];
|
|
9787
10001
|
var PLANNED_NOTES = {};
|