labull-framework 0.1.16 → 0.1.17

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.
@@ -1,8 +1,8 @@
1
- import { defineComponent as ot, ref as w, computed as N, watch as fe, nextTick as ut, onMounted as yt, onBeforeUnmount as _t, openBlock as b, createElementBlock as v, normalizeStyle as kt, normalizeClass as W, unref as $e, createElementVNode as l, toDisplayString as m, createCommentVNode as x, Fragment as M, renderList as U, withModifiers as Xt, createBlock as Qt, withDirectives as en, vModelText as tn, createTextVNode as E, createStaticVNode as nn } from "vue";
2
- import { useRouter as $t } from "vue-router";
3
- import { A as on, b as K, c as je, u as wt } from "./chunk-index-BWpDbB19.js";
4
- import { u as sn, o as Ze, b as xt, _ as Ct, d as an } from "./chunk-ProductShell.vue_vue_type_style_index_0_scoped_06035587_lang-BpRKKThg.js";
5
- const Y = "__mb", Et = "call", Xe = "reply", St = "host-ready", Tt = "height", ln = "html, body { overflow: hidden !important; }", rn = `
1
+ import { defineComponent as ot, ref as w, computed as N, watch as fe, nextTick as dt, onMounted as _t, onBeforeUnmount as kt, openBlock as b, createElementBlock as v, normalizeStyle as $t, normalizeClass as W, unref as $e, createElementVNode as l, toDisplayString as m, createCommentVNode as x, Fragment as A, renderList as U, withModifiers as Qt, createBlock as en, withDirectives as tn, vModelText as nn, createTextVNode as C } from "vue";
2
+ import { useRouter as wt } from "vue-router";
3
+ import { A as on, b as K, c as Pe, u as xt } from "./chunk-index-BWpDbB19.js";
4
+ import { u as sn, o as Ze, b as Ct, _ as Et, d as an } from "./chunk-ProductShell.vue_vue_type_style_index_0_scoped_06035587_lang-BpRKKThg.js";
5
+ const Y = "__mb", Tt = "call", Xe = "reply", St = "host-ready", Bt = "height", ln = "html, body { overflow: hidden !important; }", rn = `
6
6
  (function () {
7
7
  var seq = 0, waiting = {}, queue = [], ready = false, last = -1;
8
8
  function call(method, args) {
@@ -10,7 +10,7 @@ const Y = "__mb", Et = "call", Xe = "reply", St = "host-ready", Tt = "height", l
10
10
  function run() {
11
11
  var id = ++seq;
12
12
  waiting[id] = { resolve: resolve, reject: reject };
13
- parent.postMessage({ '${Y}': '${Et}', id: id, method: method, args: args }, '*');
13
+ parent.postMessage({ '${Y}': '${Tt}', id: id, method: method, args: args }, '*');
14
14
  }
15
15
  if (ready) run(); else queue.push(run);
16
16
  });
@@ -60,7 +60,7 @@ const Y = "__mb", Et = "call", Xe = "reply", St = "host-ready", Tt = "height", l
60
60
  if (height > 0) height += 1;
61
61
  if (height === last) return; /* 一样高就不再发:否则「宿主改高度 → 触发观察 → 又发一次」会转个不停 */
62
62
  last = height;
63
- parent.postMessage({ '${Y}': '${Tt}', height: height }, '*');
63
+ parent.postMessage({ '${Y}': '${Bt}', height: height }, '*');
64
64
  }
65
65
  function start() {
66
66
  report();
@@ -70,88 +70,88 @@ const Y = "__mb", Et = "call", Xe = "reply", St = "host-ready", Tt = "height", l
70
70
  setInterval(report, 500);
71
71
  })();
72
72
  `, cn = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)+$/;
73
- function Bt(n) {
73
+ function Mt(n) {
74
74
  const t = typeof window > "u" ? "http://localhost" : window.location.href;
75
75
  return new URL(`${on}${n}`, t);
76
76
  }
77
- const dt = (() => {
77
+ const pt = (() => {
78
78
  try {
79
- return Bt("").origin;
79
+ return Mt("").origin;
80
80
  } catch {
81
81
  return typeof window > "u" ? "" : window.location.origin;
82
82
  }
83
83
  })();
84
84
  async function un(n, t, a) {
85
85
  if (!cn.test(t)) throw new Error(`路由名不合法:${t}(要写成 类名.方法名,例如 Customer.create)`);
86
- const i = Bt(`/bx/${n}/${t}`);
87
- if (i.origin !== dt) throw new Error(`后端地址必须是本应用的(${dt}):${i.origin}`);
86
+ const i = Mt(`/bx/${n}/${t}`);
87
+ if (i.origin !== pt) throw new Error(`后端地址必须是本应用的(${pt}):${i.origin}`);
88
88
  const r = a instanceof Blob ? a : null, u = await fetch(i.toString(), {
89
89
  method: "POST",
90
90
  credentials: "include",
91
91
  // 带上 HttpOnly 会话 cookie;authHeaders('POST') 给 CSRF 头(缺了 403)
92
- headers: r ? { "Content-Type": r.type || "application/octet-stream", ...je("POST") } : { "Content-Type": "application/json", ...je("POST") },
92
+ headers: r ? { "Content-Type": r.type || "application/octet-stream", ...Pe("POST") } : { "Content-Type": "application/json", ...Pe("POST") },
93
93
  body: r ?? JSON.stringify(a ?? {})
94
- }), p = await u.text().catch(() => "");
94
+ }), d = await u.text().catch(() => "");
95
95
  if (u.ok) {
96
- if (!p) return null;
96
+ if (!d) return null;
97
97
  try {
98
- return JSON.parse(p);
98
+ return JSON.parse(d);
99
99
  } catch {
100
- return p;
100
+ return d;
101
101
  }
102
102
  }
103
- let d = p;
103
+ let p = d;
104
104
  try {
105
- const f = JSON.parse(p);
106
- typeof f?.message == "string" && (d = f.message);
105
+ const f = JSON.parse(d);
106
+ typeof f?.message == "string" && (p = f.message);
107
107
  } catch {
108
- d = p;
108
+ p = d;
109
109
  }
110
- throw new Error(d ? `${t} 调用失败:${d.slice(0, 300)}` : `${t} 调用失败(${u.status})`);
110
+ throw new Error(p ? `${t} 调用失败:${p.slice(0, 300)}` : `${t} 调用失败(${u.status})`);
111
111
  }
112
112
  function dn(n, t) {
113
- const a = (p) => {
113
+ const a = (d) => {
114
114
  try {
115
- n.contentWindow?.postMessage(p, "*");
116
- } catch (d) {
117
- console.warn("[magic-block] 有一条宿主消息没能发给块(协议继续走):", d);
115
+ n.contentWindow?.postMessage(d, "*");
116
+ } catch (p) {
117
+ console.warn("[magic-block] 有一条宿主消息没能发给块(协议继续走):", p);
118
118
  }
119
119
  };
120
- async function i(p, d) {
121
- if (p === "getMe") return await K("/auth/me");
122
- if (p === "navigateTab") {
123
- const f = typeof d[0] == "string" ? d[0].trim() : "";
120
+ async function i(d, p) {
121
+ if (d === "getMe") return await K("/auth/me");
122
+ if (d === "navigateTab") {
123
+ const f = typeof p[0] == "string" ? p[0].trim() : "";
124
124
  if (!f || !t.onNavigateTab) throw new Error(`跳不了 ${f || "(空地址)"}:这个页面没有把宿主接到路由上`);
125
125
  return await t.onNavigateTab(f);
126
126
  }
127
- if (p === "context") return t.context ? t.context() : {};
128
- if (p === "setTabTitle") {
129
- const f = typeof d[0] == "string" ? d[0].trim() : "", g = typeof d[1] == "string" ? d[1].trim() : "";
127
+ if (d === "context") return t.context ? t.context() : {};
128
+ if (d === "setTabTitle") {
129
+ const f = typeof p[0] == "string" ? p[0].trim() : "", g = typeof p[1] == "string" ? p[1].trim() : "";
130
130
  if (!f) throw new Error("setTabTitle 要给一个非空的名字");
131
131
  return t.onTabTitle?.(f, g || void 0), !0;
132
132
  }
133
- if (p === "backend") {
134
- const f = typeof d[0] == "string" ? d[0].trim() : "", g = d[1];
133
+ if (d === "backend") {
134
+ const f = typeof p[0] == "string" ? p[0].trim() : "", g = p[1];
135
135
  if (!f) throw new Error("后端调用的路由名是空的:要写成 magicBackendApi.类名.方法名(参数)");
136
136
  if (!g || typeof g != "object" || Array.isArray(g)) throw new Error(`magicBackendApi.${f}(params) 的参数要么是一个对象,要么是一个文件(File / Blob)`);
137
137
  return await un(t.uuid, f, g);
138
138
  }
139
- throw new Error(`不认识的方法:${String(p)}(这块桥只有 getMe / navigateTab / context / setTabTitle / backend 五个)`);
139
+ throw new Error(`不认识的方法:${String(d)}(这块桥只有 getMe / navigateTab / context / setTabTitle / backend 五个)`);
140
140
  }
141
- const r = (p) => {
142
- if (p.source !== n.contentWindow) return;
143
- const d = p.data;
144
- if (!d) return;
145
- if (d[Y] === Tt) {
146
- const g = typeof d.height == "number" ? d.height : NaN;
141
+ const r = (d) => {
142
+ if (d.source !== n.contentWindow) return;
143
+ const p = d.data;
144
+ if (!p) return;
145
+ if (p[Y] === Bt) {
146
+ const g = typeof p.height == "number" ? p.height : NaN;
147
147
  Number.isFinite(g) && g > 0 && t.onHeight?.(g);
148
148
  return;
149
149
  }
150
- if (d[Y] !== Et) return;
151
- const f = d.id;
150
+ if (p[Y] !== Tt) return;
151
+ const f = p.id;
152
152
  (async () => {
153
153
  try {
154
- a({ [Y]: Xe, id: f, ok: !0, value: await i(String(d.method), d.args ?? []) });
154
+ a({ [Y]: Xe, id: f, ok: !0, value: await i(String(p.method), p.args ?? []) });
155
155
  } catch (g) {
156
156
  a({ [Y]: Xe, id: f, ok: !1, error: g instanceof Error ? g.message : String(g) });
157
157
  }
@@ -163,7 +163,7 @@ function dn(n, t) {
163
163
  window.removeEventListener("message", r), n.removeEventListener("load", u);
164
164
  };
165
165
  }
166
- const xe = "index.open.html", Ve = "magic-block.open.yaml", Ae = ["id", "module", "name", "brief"], st = 40, pn = /^(?![A-Za-z]:)(?!\/)[A-Za-z0-9._\-/]+$/, fn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, mn = /^[a-z][a-z0-9]*$/, bn = /^[A-Za-z_][A-Za-z0-9_]*$/;
166
+ const xe = "index.open.html", Ve = "magic-block.open.yaml", Oe = ["id", "module", "name", "brief"], st = 40, pn = /^(?![A-Za-z]:)(?!\/)[A-Za-z0-9._\-/]+$/, fn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, mn = /^[a-z][a-z0-9]*$/, bn = /^[A-Za-z_][A-Za-z0-9_]*$/;
167
167
  function vn(n) {
168
168
  return n.length > 0 && n.length <= st && !/[\u0000-\u001f\u007f]/.test(n);
169
169
  }
@@ -173,7 +173,7 @@ const hn = {
173
173
  name: `可读名:可以用中文,不超过 ${st} 个字符`,
174
174
  brief: "一句话说明这个块解决什么问题"
175
175
  };
176
- function pt(n) {
176
+ function ft(n) {
177
177
  const t = Object.keys(n);
178
178
  return t.length > 0 ? `现在包里有:${t.join(" / ")}` : "现在这个包是空的";
179
179
  }
@@ -205,33 +205,33 @@ function _n(n) {
205
205
  function kn(n) {
206
206
  const t = [], a = {}, i = {};
207
207
  n.split(/\r?\n/).forEach((r, u) => {
208
- const p = u + 1, d = gn(r).trim();
209
- if (!d) return;
210
- if (d.startsWith("-")) {
211
- t.push(`第 ${p} 行是列表写法(${d}):清单只认「键: 值」,四个键各占一行 —— 例如 name: 客户档案`);
208
+ const d = u + 1, p = gn(r).trim();
209
+ if (!p) return;
210
+ if (p.startsWith("-")) {
211
+ t.push(`第 ${d} 行是列表写法(${p}):清单只认「键: 值」,四个键各占一行 —— 例如 name: 客户档案`);
212
212
  return;
213
213
  }
214
- const f = yn(d);
214
+ const f = yn(p);
215
215
  if (f < 0) {
216
- t.push(`第 ${p} 行不是「键: 值」(${d}):清单只认「键: 值」与 # 注释 —— 要么删掉这一行,要么照 name: 客户档案 写`);
216
+ t.push(`第 ${d} 行不是「键: 值」(${p}):清单只认「键: 值」与 # 注释 —— 要么删掉这一行,要么照 name: 客户档案 写`);
217
217
  return;
218
218
  }
219
- const g = d.slice(0, f).trim();
219
+ const g = p.slice(0, f).trim();
220
220
  if (!bn.test(g)) {
221
- t.push(`第 ${p} 行的键名不合法(${g}):键名只许字母或下划线开头,认得的键只有 ${Ae.join(" / ")}`);
221
+ t.push(`第 ${d} 行的键名不合法(${g}):键名只许字母或下划线开头,认得的键只有 ${Oe.join(" / ")}`);
222
222
  return;
223
223
  }
224
- if (!Ae.includes(g)) {
225
- t.push(`第 ${p} 行的键不认识(${g}):清单只有 ${Ae.join(" / ")} 这四个键`);
224
+ if (!Oe.includes(g)) {
225
+ t.push(`第 ${d} 行的键不认识(${g}):清单只有 ${Oe.join(" / ")} 这四个键`);
226
226
  return;
227
227
  }
228
228
  if (g in i) {
229
- t.push(`第 ${p} 行重复写了 ${g}(第 ${i[g]} 行已经写过):一个键只许出现一次`);
229
+ t.push(`第 ${d} 行重复写了 ${g}(第 ${i[g]} 行已经写过):一个键只许出现一次`);
230
230
  return;
231
231
  }
232
- i[g] = p, a[g] = _n(d.slice(f + 1).trim());
232
+ i[g] = d, a[g] = _n(p.slice(f + 1).trim());
233
233
  });
234
- for (const r of Ae) {
234
+ for (const r of Oe) {
235
235
  const u = a[r] ?? "";
236
236
  if (u === "") {
237
237
  t.push(`清单里缺少 ${r}(或者是空的):${hn[r]}`);
@@ -248,16 +248,16 @@ function $n(n) {
248
248
  }
249
249
  function wn(n) {
250
250
  const t = [], a = n[xe];
251
- a === void 0 ? t.push(`包里缺入口:必须有 ${xe}(${pt(n)})`) : a.trim() || t.push(`${xe} 不能是空文件`);
251
+ a === void 0 ? t.push(`包里缺入口:必须有 ${xe}(${ft(n)})`) : a.trim() || t.push(`${xe} 不能是空文件`);
252
252
  const i = n[Ve];
253
253
  let r = {};
254
254
  if (i === void 0)
255
- t.push(`包里缺清单:必须有 ${Ve}(${pt(n)})`);
255
+ t.push(`包里缺清单:必须有 ${Ve}(${ft(n)})`);
256
256
  else if (!i.trim())
257
257
  t.push(`${Ve} 不能是空文件`);
258
258
  else {
259
- const [u, p] = kn(i);
260
- r = u, t.push(...p);
259
+ const [u, d] = kn(i);
260
+ r = u, t.push(...d);
261
261
  }
262
262
  for (const u of Object.keys(n))
263
263
  $n(u) || t.push(`文件名不合法:${u}(只许字母数字与 . _ - /,且不许 .. 与绝对路径)`);
@@ -274,29 +274,29 @@ function xn(n) {
274
274
  return { selected: n.length, issues: t };
275
275
  }
276
276
  const Cn = "backend_open.py", En = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
277
- function ft(n, t) {
277
+ function mt(n, t) {
278
278
  if (En.test(n)) return;
279
279
  const a = (n.split(/[?#]/)[0] ?? "").replace(/^\.\//, "").replace(/^\/+/, "");
280
280
  if (a in t) return a;
281
281
  const i = a.split("/").pop() ?? "";
282
282
  return i ? Object.keys(t).find((r) => (r.split("/").pop() ?? "") === i) : void 0;
283
283
  }
284
- const Mt = "\0mb:";
285
- function Sn(n) {
286
- return `${Mt}${n}\0`;
284
+ const At = "\0mb:";
285
+ function Tn(n) {
286
+ return `${At}${n}\0`;
287
287
  }
288
- const Tn = /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)>\s*<\/script\s*>/gi, Bn = /<link\b([^>]*?)\bhref\s*=\s*(["'])(.*?)\2([^>]*?)\/?>/gi;
288
+ const Sn = /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)>\s*<\/script\s*>/gi, Bn = /<link\b([^>]*?)\bhref\s*=\s*(["'])(.*?)\2([^>]*?)\/?>/gi;
289
289
  function Mn(n, t) {
290
- const a = [], i = (p) => (a.push(p), Sn(a.length - 1));
291
- return { html: n.replace(Tn, (p, d, f, g, C) => {
292
- const y = ft(g, t);
293
- return y === void 0 ? p : i(`<script${d}${C}>
290
+ const a = [], i = (d) => (a.push(d), Tn(a.length - 1));
291
+ return { html: n.replace(Sn, (d, p, f, g, E) => {
292
+ const y = mt(g, t);
293
+ return y === void 0 ? d : i(`<script${p}${E}>
294
294
  ${Ot(t[y] ?? "")}
295
295
  <\/script>`);
296
- }).replace(Bn, (p, d, f, g, C) => {
297
- if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${d}${C}`)) return p;
298
- const y = ft(g, t);
299
- return y === void 0 ? p : i(`<style>
296
+ }).replace(Bn, (d, p, f, g, E) => {
297
+ if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${p}${E}`)) return d;
298
+ const y = mt(g, t);
299
+ return y === void 0 ? d : i(`<style>
300
300
  ${t[y]}
301
301
  </style>`);
302
302
  }), slots: a };
@@ -304,33 +304,33 @@ ${t[y]}
304
304
  function Ot(n) {
305
305
  return n.replace(/<\/(script)/gi, "<\\/$1");
306
306
  }
307
- function At(n, t) {
307
+ function Rt(n, t) {
308
308
  const a = /<\/head\s*>/i.exec(n);
309
309
  return a ? `${n.slice(0, a.index)}${t}${n.slice(a.index)}` : `${t}${n}`;
310
310
  }
311
- function On(n, t) {
312
- return t ? At(n, `<script>
311
+ function An(n, t) {
312
+ return t ? Rt(n, `<script>
313
313
  ${Ot(t)}
314
314
  <\/script>
315
315
  `) : n;
316
316
  }
317
- function mt(n, t) {
318
- return t ? At(n, `<style data-magic-block="host">
317
+ function bt(n, t) {
318
+ return t ? Rt(n, `<style data-magic-block="host">
319
319
  ${t}
320
320
  </style>
321
321
  `) : n;
322
322
  }
323
- function An(n, t = {}) {
323
+ function On(n, t = {}) {
324
324
  const a = t.bootstrap ?? "", i = t.css ?? "", r = t.themeCss ?? "", u = n[xe];
325
325
  if (u === void 0) return "";
326
- const { html: p, slots: d } = Mn(u, n), f = On(mt(mt(p, r), i), a), g = f.split(Mt);
326
+ const { html: d, slots: p } = Mn(u, n), f = An(bt(bt(d, r), i), a), g = f.split(At);
327
327
  if (g.length === 1) return f;
328
- let C = g[0] ?? "";
328
+ let E = g[0] ?? "";
329
329
  for (let y = 1; y < g.length; y += 1) {
330
330
  const _ = g[y] ?? "", z = _.indexOf("\0"), I = Number(_.slice(0, z));
331
- C += (d[I] ?? "") + _.slice(z + 1);
331
+ E += (p[I] ?? "") + _.slice(z + 1);
332
332
  }
333
- return C;
333
+ return E;
334
334
  }
335
335
  const we = /* @__PURE__ */ new Map();
336
336
  let me = null;
@@ -340,11 +340,11 @@ function Rn(n) {
340
340
  Qe.delete(n);
341
341
  };
342
342
  }
343
- function Pn() {
343
+ function jn() {
344
344
  we.clear(), me = null;
345
345
  for (const n of Qe) n();
346
346
  }
347
- async function jn(n) {
347
+ async function Pn(n) {
348
348
  const t = [...new Set(n)].filter(Boolean);
349
349
  if (t.some((a) => !we.has(a))) {
350
350
  me && await me.catch(() => {
@@ -360,45 +360,45 @@ async function jn(n) {
360
360
  }
361
361
  return t.map((a) => we.get(a)).filter((a) => !!a);
362
362
  }
363
- const re = "labull.css", Pe = "CONTROLS.lock.html";
363
+ const re = "labull.css", je = "CONTROLS.lock.html";
364
364
  function Nn(n, t) {
365
365
  const a = String(t || "");
366
366
  if (/@font-face|@keyframes/i.test(a)) return !0;
367
367
  const i = String(n || "");
368
368
  return /(^|[\s,>+~])(\.p-|\.pi(?![a-z])|\.pi-|\.labull-|:root|html(?![a-z-])|body(?![a-z-])|\*|:where\()/.test(i) ? !0 : /--(?:sp|surface|primary|text-color|content|highlight|focus-ring|p-)/.test(a);
369
369
  }
370
- function Rt(n, t, a) {
370
+ function jt(n, t, a) {
371
371
  for (let i = 0; i < n.length; i += 1) {
372
- const r = n[i], u = String(r.cssText || ""), p = String(r.selectorText || "");
372
+ const r = n[i], u = String(r.cssText || ""), d = String(r.selectorText || "");
373
373
  if (r.cssRules && r.cssRules.length > 0) {
374
- const d = [];
375
- if (Rt(r.cssRules, d, a), d.length === 0) continue;
374
+ const p = [];
375
+ if (jt(r.cssRules, p, a), p.length === 0) continue;
376
376
  const f = u.slice(0, u.indexOf("{")).trim();
377
377
  t.push(`${f} {
378
- ${d.map((g) => " " + g).join(`
378
+ ${p.map((g) => " " + g).join(`
379
379
  `)}
380
380
  }`);
381
381
  continue;
382
382
  }
383
- Nn(p, u) && (t.push(u), a.n += 1);
383
+ Nn(d, u) && (t.push(u), a.n += 1);
384
384
  }
385
385
  }
386
386
  function Pt() {
387
387
  const n = [], t = [], a = { n: 0 };
388
388
  let i = 0;
389
389
  const r = typeof document > "u" ? [] : Array.from(document.styleSheets);
390
- for (const p of r) {
391
- const d = p.href || "(内联 <style>)";
390
+ for (const d of r) {
391
+ const p = d.href || "(内联 <style>)";
392
392
  let f = null;
393
393
  try {
394
- f = p.cssRules;
394
+ f = d.cssRules;
395
395
  } catch {
396
- t.push(d);
396
+ t.push(p);
397
397
  continue;
398
398
  }
399
399
  if (!f || f.length === 0) continue;
400
400
  const g = [];
401
- Rt(f, g, a), g.length !== 0 && (i += 1, n.push(`/* ── ${d} ── */`, ...g));
401
+ jt(f, g, a), g.length !== 0 && (i += 1, n.push(`/* ── ${p} ── */`, ...g));
402
402
  }
403
403
  return { css: [
404
404
  "/* 生成物:每次导出都会重写,别手改。",
@@ -409,7 +409,7 @@ function Pt() {
409
409
  " *",
410
410
  " * 怎么用(块里):**什么都不用加** —— 宿主会把这一份注入每个块的 iframe(`MagicBlockHost` 的 `theme` prop),",
411
411
  ' * 所以直接写类名就行:`<button class="p-button">` / `<input class="p-inputtext">` / `<span class="p-tag">`。',
412
- " * 这一份放在开发包里是给你**查 / 对照 / 抄**用的(`" + Pe + "` 里的每一块 markup 都能直接用)。",
412
+ " * 这一份放在开发包里是给你**查 / 对照 / 抄**用的(`" + je + "` 里的每一块 markup 都能直接用)。",
413
413
  " * ⚠️ 别把它当块包文件塞进块里:它 500 KB 上下,而且宿主已经注入了一份(重复只会更慢)。",
414
414
  " * ⚠️ 块里**只有 CSS,没有 JS 组件**:下拉 / 日期 / 弹窗那些要装了 PrimeVue 才有行为,",
415
415
  " * 这里能用的是类名(按钮、输入框、标签、面板、表格、图标)。",
@@ -483,7 +483,7 @@ ${a}
483
483
  }
484
484
  const ce = /* @__PURE__ */ new Map(), et = /* @__PURE__ */ new Set(), Ln = 4e3;
485
485
  let tt = "", Re = null;
486
- function bt() {
486
+ function vt() {
487
487
  for (const n of et) n();
488
488
  }
489
489
  function Dn(n) {
@@ -491,7 +491,7 @@ function Dn(n) {
491
491
  et.delete(n);
492
492
  };
493
493
  }
494
- function Ge() {
494
+ function Je() {
495
495
  return tt;
496
496
  }
497
497
  function zn(n, t) {
@@ -519,15 +519,15 @@ function Hn(n, t, a) {
519
519
  const i = ce.get(String(n || ""));
520
520
  return !i || i.size === 0 || i.has(t) ? null : nt(n, t, a);
521
521
  }
522
- function jt(n, t = Ln) {
522
+ function Nt(n, t = Ln) {
523
523
  tt = String(n || ""), Re !== null && clearTimeout(Re), Re = setTimeout(() => {
524
- Re = null, tt = "", bt();
525
- }, Math.max(1, t)), bt();
524
+ Re = null, tt = "", vt();
525
+ }, Math.max(1, t)), vt();
526
526
  }
527
- const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"], qn = { class: "mb__state" }, Vn = { class: "mb__brief" }, Gn = {
527
+ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"], qn = { class: "mb__state" }, Vn = { class: "mb__brief" }, Jn = {
528
528
  key: 0,
529
529
  class: "mb__reason"
530
- }, Jn = {
530
+ }, Gn = {
531
531
  key: 1,
532
532
  class: "mb__issues"
533
533
  }, Wn = {
@@ -543,13 +543,13 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
543
543
  theme: { type: Boolean, default: !0 }
544
544
  },
545
545
  setup(n) {
546
- const t = n, a = sn(), i = $t(), { isStaff: r } = wt(), u = w(null), p = w(null), d = w(null), f = w(!1), g = w(0), C = w(0);
546
+ const t = n, a = sn(), i = wt(), { isStaff: r } = xt(), u = w(null), d = w(null), p = w(null), f = w(!1), g = w(0), E = w(0);
547
547
  let y = null, _ = null, z = null, I = null, X = null, oe = null;
548
- const P = N(() => t.name.trim() || t.uuid), O = N(() => d.value?.state ?? ""), H = N(() => O.value === "invalid" ? "校验不通过" : O.value === "draft" ? "未开发" : P.value), se = N(() => (d.value?.brief ?? "").trim() || (d.value?.name ?? "").trim() || P.value), q = N(() => (d.value?.reason ?? "").trim()), ue = N(() => d.value?.issues ?? []), Ee = N(() => Math.max(C.value, g.value, 1)), Ie = N(() => ({ height: `${Ee.value}px` })), V = N(() => {
548
+ const j = N(() => t.name.trim() || t.uuid), M = N(() => p.value?.state ?? ""), H = N(() => M.value === "invalid" ? "校验不通过" : M.value === "draft" ? "未开发" : j.value), se = N(() => (p.value?.brief ?? "").trim() || (p.value?.name ?? "").trim() || j.value), q = N(() => (p.value?.reason ?? "").trim()), ue = N(() => p.value?.issues ?? []), Ee = N(() => Math.max(E.value, g.value, 1)), Ie = N(() => ({ height: `${Ee.value}px` })), V = N(() => {
549
549
  const h = {};
550
- for (const [$, S] of Object.entries(d.value?.files ?? {})) $ !== Cn && (h[$] = S);
550
+ for (const [$, T] of Object.entries(p.value?.files ?? {})) $ !== Cn && (h[$] = T);
551
551
  return h;
552
- }), G = N(() => O.value === "ok" && typeof V.value[xe] == "string");
552
+ }), J = N(() => M.value === "ok" && typeof V.value[xe] == "string");
553
553
  let B = null;
554
554
  function Q() {
555
555
  if (!t.theme) return "";
@@ -562,9 +562,9 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
562
562
  return B;
563
563
  }
564
564
  const Z = N(() => {
565
- if (!G.value) return "";
565
+ if (!J.value) return "";
566
566
  const h = { bootstrap: rn, css: ln }, $ = Q();
567
- return $ && (h.themeCss = $), An(V.value, h);
567
+ return $ && (h.themeCss = $), On(V.value, h);
568
568
  });
569
569
  function ae() {
570
570
  return { key: a.key, path: a.path, params: a.params, query: a.query };
@@ -572,14 +572,14 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
572
572
  async function ee(h) {
573
573
  const $ = i.resolve(h);
574
574
  if ($.matched.length === 0) {
575
- const S = i.getRoutes().map((L) => L.path);
576
- throw new Error(`这个应用里没有页面 ${h}。能跳的页面只有:${S.length > 0 ? S.join(" / ") : "(还没有配路由)"}`);
575
+ const T = i.getRoutes().map((L) => L.path);
576
+ throw new Error(`这个应用里没有页面 ${h}。能跳的页面只有:${T.length > 0 ? T.join(" / ") : "(还没有配路由)"}`);
577
577
  }
578
578
  return Ze(h) || $.fullPath;
579
579
  }
580
580
  function be() {
581
581
  z?.(), z = null;
582
- const h = p.value;
582
+ const h = d.value;
583
583
  h && (z = dn(h, {
584
584
  uuid: t.uuid,
585
585
  onHeight: ($) => {
@@ -589,20 +589,20 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
589
589
  context: ae,
590
590
  /* 🔴 块给**自己所属那条标签**起名:整页就是一个块时(`MagicBlockPage`),标签栏上那条
591
591
  * 默认只有路由的 `meta.title`("订单详情"),而"订单 SO-42"只有块自己知道。 */
592
- onTabTitle: ($, S) => a.setTitle($, S)
592
+ onTabTitle: ($, T) => a.setTitle($, T)
593
593
  }));
594
594
  }
595
- async function J() {
596
- const h = t.uuid, $ = await jn([h]);
597
- h === t.uuid && (d.value = $.find((S) => S.id === h) ?? null);
595
+ async function G() {
596
+ const h = t.uuid, $ = await Pn([h]);
597
+ h === t.uuid && (p.value = $.find((T) => T.id === h) ?? null);
598
598
  }
599
599
  function de() {
600
600
  window.dispatchEvent(new CustomEvent("magic-block:open-console", { detail: { uuid: t.uuid } }));
601
601
  }
602
- function Se(h = !1) {
602
+ function Te(h = !1) {
603
603
  h && X?.(), X = zn(t.uuid, a.key);
604
604
  }
605
- const ve = (h) => !xt(h, i), T = N(() => {
605
+ const ve = (h) => !Ct(h, i), S = N(() => {
606
606
  if (!r.value) return "";
607
607
  const h = nt(t.uuid, a.key, ve);
608
608
  return h ? `管理员:切到还挂着这个块的标签 ${h}(点一下这一块会亮红框)` : "管理员:这个块只在这一条标签里挂着 —— 点一下会亮几秒红框";
@@ -610,9 +610,9 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
610
610
  function ie() {
611
611
  if (!r.value) return;
612
612
  const h = nt(t.uuid, a.key, ve);
613
- jt(t.uuid), h && Ze(h);
613
+ Nt(t.uuid), h && Ze(h);
614
614
  }
615
- function Te(h) {
615
+ function Se(h) {
616
616
  let $ = h.parentElement;
617
617
  for (; $; ) {
618
618
  if (getComputedStyle($).overflowY !== "visible" && $.clientHeight > 0) return $;
@@ -623,108 +623,108 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
623
623
  function Le() {
624
624
  const h = u.value;
625
625
  if (!h) return 0;
626
- const $ = Te(h), S = getComputedStyle($), L = parseFloat(S.paddingTop) || 0, he = parseFloat(S.paddingBottom) || 0, ge = parseFloat(S.borderTopWidth) || 0, te = $ === document.documentElement, De = te ? Math.max(0, window.innerHeight - L - he) : Math.max(0, $.clientHeight - L - he), ze = te ? L : $.getBoundingClientRect().top + ge + L, Fe = te ? window.scrollY || 0 : $.scrollTop, He = h.getBoundingClientRect().top - ze + Fe;
626
+ const $ = Se(h), T = getComputedStyle($), L = parseFloat(T.paddingTop) || 0, he = parseFloat(T.paddingBottom) || 0, ge = parseFloat(T.borderTopWidth) || 0, te = $ === document.documentElement, De = te ? Math.max(0, window.innerHeight - L - he) : Math.max(0, $.clientHeight - L - he), ze = te ? L : $.getBoundingClientRect().top + ge + L, Fe = te ? window.scrollY || 0 : $.scrollTop, He = h.getBoundingClientRect().top - ze + Fe;
627
627
  return Math.max(0, Math.floor(De - He));
628
628
  }
629
629
  function Be() {
630
630
  if (!a.active.value || !u.value) return;
631
631
  const h = Le();
632
- h > 0 && Math.abs(h - C.value) > 1 && (C.value = h);
632
+ h > 0 && Math.abs(h - E.value) > 1 && (E.value = h);
633
633
  }
634
- function A() {
634
+ function O() {
635
635
  if (!u.value) return;
636
- const h = Te(u.value);
636
+ const h = Se(u.value);
637
637
  y !== h && (y = h, _?.disconnect(), _ = null), Be(), !(_ || typeof ResizeObserver > "u") && (_ = new ResizeObserver(() => Be()), _.observe(h));
638
638
  }
639
- return fe(p, () => be()), fe(Z, () => {
640
- g.value = 0, C.value = 0, A();
639
+ return fe(d, () => be()), fe(Z, () => {
640
+ g.value = 0, E.value = 0, O();
641
641
  }, { flush: "post" }), fe(() => t.uuid, () => {
642
- ut().then(() => A());
642
+ dt().then(() => O());
643
643
  }), fe(() => a.active.value, (h) => {
644
- h && ut().then(() => {
645
- A();
644
+ h && dt().then(() => {
645
+ O();
646
646
  const $ = u.value;
647
647
  !$ || !$.isConnected || $.offsetParent === null || f.value && $.scrollIntoView({ behavior: "smooth", block: "center" });
648
648
  });
649
649
  }), fe(() => t.uuid, () => {
650
- g.value = 0, d.value = null, Se(!0), f.value = Ge() === t.uuid, J();
651
- }), yt(() => {
652
- I = Rn(() => void J()), oe = Dn(() => {
653
- f.value = Ge() === t.uuid;
654
- }), f.value = Ge() === t.uuid, Se(), A(), J();
650
+ g.value = 0, p.value = null, Te(!0), f.value = Je() === t.uuid, G();
655
651
  }), _t(() => {
652
+ I = Rn(() => void G()), oe = Dn(() => {
653
+ f.value = Je() === t.uuid;
654
+ }), f.value = Je() === t.uuid, Te(), O(), G();
655
+ }), kt(() => {
656
656
  _?.disconnect(), _ = null, I?.(), I = null, oe?.(), oe = null, X?.(), X = null, z?.(), z = null;
657
657
  }), (h, $) => (b(), v("div", {
658
658
  ref_key: "el",
659
659
  ref: u,
660
660
  class: W(["mb", { "mb--admin": $e(r), "mb--lit": $e(r) && f.value }]),
661
- style: kt(Ie.value),
661
+ style: $t(Ie.value),
662
662
  "data-magic-block": n.uuid,
663
663
  "data-magic-module": n.module
664
664
  }, [
665
- G.value ? (b(), v("iframe", {
665
+ J.value ? (b(), v("iframe", {
666
666
  key: 0,
667
667
  ref_key: "frame",
668
- ref: p,
668
+ ref: d,
669
669
  class: "mb__frame",
670
670
  srcdoc: Z.value,
671
- title: P.value,
671
+ title: j.value,
672
672
  scrolling: "no",
673
673
  sandbox: "allow-scripts allow-forms allow-modals allow-popups allow-downloads"
674
674
  }, null, 8, Kn)) : (b(), v("div", {
675
675
  key: 1,
676
- class: W(["mb__empty", { "mb__empty--off": O.value === "invalid", "mb__empty--draft": O.value === "draft" }]),
676
+ class: W(["mb__empty", { "mb__empty--off": M.value === "invalid", "mb__empty--draft": M.value === "draft" }]),
677
677
  onClick: ie
678
678
  }, [
679
679
  l("p", qn, m(H.value), 1),
680
680
  l("p", Vn, m(se.value), 1),
681
- O.value === "invalid" && q.value ? (b(), v("p", Gn, m(q.value), 1)) : x("", !0),
682
- O.value === "invalid" && ue.value.length > 0 ? (b(), v("ul", Jn, [
683
- (b(!0), v(M, null, U(ue.value, (S, L) => (b(), v("li", {
681
+ M.value === "invalid" && q.value ? (b(), v("p", Jn, m(q.value), 1)) : x("", !0),
682
+ M.value === "invalid" && ue.value.length > 0 ? (b(), v("ul", Gn, [
683
+ (b(!0), v(A, null, U(ue.value, (T, L) => (b(), v("li", {
684
684
  key: L,
685
685
  class: "mb__issue"
686
- }, m(S.message), 1))), 128))
686
+ }, m(T.message), 1))), 128))
687
687
  ])) : x("", !0),
688
688
  l("button", {
689
689
  class: "mb__go",
690
690
  type: "button",
691
- onClick: Xt(de, ["stop"])
691
+ onClick: Qt(de, ["stop"])
692
692
  }, "去控制台")
693
693
  ], 2)),
694
694
  $e(r) ? (b(), v("span", Wn)) : x("", !0),
695
- $e(r) && G.value ? (b(), v(M, { key: 3 }, [
695
+ $e(r) && J.value ? (b(), v(A, { key: 3 }, [
696
696
  l("button", {
697
697
  class: "mb__grab mb__grab--top",
698
698
  type: "button",
699
- title: T.value,
700
- "aria-label": T.value,
699
+ title: S.value,
700
+ "aria-label": S.value,
701
701
  onClick: ie
702
702
  }, null, 8, Yn),
703
703
  l("button", {
704
704
  class: "mb__grab mb__grab--right",
705
705
  type: "button",
706
- title: T.value,
707
- "aria-label": T.value,
706
+ title: S.value,
707
+ "aria-label": S.value,
708
708
  onClick: ie
709
709
  }, null, 8, Zn),
710
710
  l("button", {
711
711
  class: "mb__grab mb__grab--bottom",
712
712
  type: "button",
713
- title: T.value,
714
- "aria-label": T.value,
713
+ title: S.value,
714
+ "aria-label": S.value,
715
715
  onClick: ie
716
716
  }, null, 8, Xn),
717
717
  l("button", {
718
718
  class: "mb__grab mb__grab--left",
719
719
  type: "button",
720
- title: T.value,
721
- "aria-label": T.value,
720
+ title: S.value,
721
+ "aria-label": S.value,
722
722
  onClick: ie
723
723
  }, null, 8, Qn)
724
724
  ], 64)) : x("", !0)
725
725
  ], 14, Un));
726
726
  }
727
- }), to = /* @__PURE__ */ Ct(eo, [["__scopeId", "data-v-8e1e849f"]]), ua = /* @__PURE__ */ ot({
727
+ }), to = /* @__PURE__ */ Et(eo, [["__scopeId", "data-v-8e1e849f"]]), fa = /* @__PURE__ */ ot({
728
728
  __name: "MagicBlockPage",
729
729
  props: {
730
730
  uuid: {},
@@ -733,14 +733,14 @@ const Un = ["data-magic-block", "data-magic-module"], Kn = ["srcdoc", "title"],
733
733
  theme: { type: Boolean, default: !0 }
734
734
  },
735
735
  setup(n) {
736
- return (t, a) => (b(), Qt(to, {
736
+ return (t, a) => (b(), en(to, {
737
737
  uuid: n.uuid,
738
738
  name: n.name,
739
739
  module: n.module,
740
740
  theme: n.theme
741
741
  }, null, 8, ["uuid", "name", "module", "theme"]));
742
742
  }
743
- }), Je = "pages.lock.ts";
743
+ }), Ge = "pages.lock.ts";
744
744
  function no(n, t) {
745
745
  const a = String(n || "").split(/[^A-Za-z0-9]+/).filter(Boolean);
746
746
  if (a.length === 0) return `Page${t + 1}`;
@@ -757,10 +757,10 @@ function oo(n, t) {
757
757
  }
758
758
  function so(n) {
759
759
  const t = (n ?? []).filter((u) => u && typeof u.path == "string" && u.path.trim() !== ""), a = /* @__PURE__ */ new Set(), i = [];
760
- t.forEach((u, p) => {
761
- const d = u.group?.trim() || "(没写 meta.group)";
762
- let f = i.find((g) => g.title === d);
763
- f || (f = { title: d, rows: [] }, i.push(f)), f.rows.push({ key: oo(no(u.path, p), a), row: u });
760
+ t.forEach((u, d) => {
761
+ const p = u.group?.trim() || "(没写 meta.group)";
762
+ let f = i.find((g) => g.title === p);
763
+ f || (f = { title: p, rows: [] }, i.push(f)), f.rows.push({ key: oo(no(u.path, d), a), row: u });
764
764
  });
765
765
  const r = [
766
766
  "/* 生成物:**每次导出都会重写**,别手改 —— 改了下次导出就没了。",
@@ -793,8 +793,8 @@ function so(n) {
793
793
  r.push("export const Page = {");
794
794
  for (const u of i) {
795
795
  r.push(` // ── ${u.title} ──`);
796
- for (const p of u.rows)
797
- r.push(` /** ${p.row.title?.trim() || p.row.path}(${p.row.path}) */`), r.push(` ${p.key}: '${p.row.path}',`);
796
+ for (const d of u.rows)
797
+ r.push(` /** ${d.row.title?.trim() || d.row.path}(${d.row.path}) */`), r.push(` ${d.key}: '${d.row.path}',`);
798
798
  }
799
799
  r.push("} as const", "");
800
800
  }
@@ -853,12 +853,12 @@ function so(n) {
853
853
  ), r.join(`
854
854
  `);
855
855
  }
856
- function Nt() {
856
+ function It() {
857
857
  return typeof window < "u" && typeof window.showDirectoryPicker == "function";
858
858
  }
859
859
  const ao = "这个浏览器没法直接写你本机的文件夹(少了 File System Access API):请用 Chrome / Edge,并且从 https 或 http://localhost 打开这个页面(内网 http 会更少 API)。";
860
860
  async function We() {
861
- if (!Nt()) throw new Error(ao);
861
+ if (!It()) throw new Error(ao);
862
862
  try {
863
863
  const n = await window.showDirectoryPicker({ mode: "readwrite", id: "labull-magic-block" });
864
864
  return { name: n.name, handle: n };
@@ -870,7 +870,7 @@ async function We() {
870
870
  function Ne(n) {
871
871
  return (n instanceof Error ? n.message.trim() : String(n)) || "没有说原因";
872
872
  }
873
- function It(n) {
873
+ function Lt(n) {
874
874
  const t = String(n ?? "").split("/");
875
875
  for (const a of t)
876
876
  if (!a || a === "." || a === ".." || a.includes("\\") || /^[A-Za-z]:/.test(a))
@@ -884,25 +884,25 @@ function lo(n) {
884
884
  const i = a.join("\0"), r = t.get(i);
885
885
  if (r) return r;
886
886
  let u = Promise.resolve(n);
887
- for (let p = 0; p < a.length; p += 1) {
888
- const d = a[p], f = a.slice(0, p + 1).join("\0"), g = t.get(f);
889
- u = g ?? u.then((C) => C.getDirectoryHandle(d, { create: !0 })), g || t.set(f, u);
887
+ for (let d = 0; d < a.length; d += 1) {
888
+ const p = a[d], f = a.slice(0, d + 1).join("\0"), g = t.get(f);
889
+ u = g ?? u.then((E) => E.getDirectoryHandle(p, { create: !0 })), g || t.set(f, u);
890
890
  }
891
891
  return u;
892
892
  };
893
893
  }
894
894
  async function ro(n, t, a) {
895
- const i = Object.entries(t ?? {}).map(([C, y]) => ({ path: C, parts: It(C), body: String(y ?? "") })), r = i.length, u = [], p = lo(n.handle);
896
- let d = 0, f = 0;
895
+ const i = Object.entries(t ?? {}).map(([E, y]) => ({ path: E, parts: Lt(E), body: String(y ?? "") })), r = i.length, u = [], d = lo(n.handle);
896
+ let p = 0, f = 0;
897
897
  a?.(0, r);
898
898
  const g = async () => {
899
899
  for (; ; ) {
900
- const C = d;
901
- d += 1;
902
- const y = i[C];
900
+ const E = p;
901
+ p += 1;
902
+ const y = i[E];
903
903
  if (!y) return;
904
904
  try {
905
- const I = await (await (await p(y.parts.slice(0, -1))).getFileHandle(y.parts[y.parts.length - 1], { create: !0 })).createWritable();
905
+ const I = await (await (await d(y.parts.slice(0, -1))).getFileHandle(y.parts[y.parts.length - 1], { create: !0 })).createWritable();
906
906
  try {
907
907
  await I.write(y.body);
908
908
  } finally {
@@ -915,16 +915,16 @@ async function ro(n, t, a) {
915
915
  a?.(f + u.length, r);
916
916
  }
917
917
  };
918
- return await Promise.all(Array.from({ length: Math.max(1, Math.min(io, r)) }, () => g())), u.sort((C, y) => C.path < y.path ? -1 : C.path > y.path ? 1 : 0), { written: f, failed: u, total: r };
918
+ return await Promise.all(Array.from({ length: Math.max(1, Math.min(io, r)) }, () => g())), u.sort((E, y) => E.path < y.path ? -1 : E.path > y.path ? 1 : 0), { written: f, failed: u, total: r };
919
919
  }
920
- async function vt(n, t) {
920
+ async function ht(n, t) {
921
921
  const a = { items: [], topCount: 0, files: 0, dirs: 0 }, i = async (r, u) => {
922
- for (const p of await Ce(r)) {
923
- if (p.kind === "file") {
922
+ for (const d of await Ce(r)) {
923
+ if (d.kind === "file") {
924
924
  a.files += 1;
925
925
  continue;
926
926
  }
927
- a.dirs += 1, !(u >= t.maxDepth) && (t.skipDirs.includes(p.name) || await i(p, u + 1));
927
+ a.dirs += 1, !(u >= t.maxDepth) && (t.skipDirs.includes(d.name) || await i(d, u + 1));
928
928
  }
929
929
  };
930
930
  for (const r of await Ce(n.handle))
@@ -935,7 +935,7 @@ async function vt(n, t) {
935
935
  }
936
936
  return a.topCount = a.items.length, a;
937
937
  }
938
- async function ht(n) {
938
+ async function gt(n) {
939
939
  const t = [];
940
940
  for (const i of await Ce(n.handle)) t.push(i.name);
941
941
  let a = 0;
@@ -961,14 +961,14 @@ function po(n) {
961
961
  const t = n.lastIndexOf(".");
962
962
  return t <= 0 ? "" : n.slice(t).toLowerCase();
963
963
  }
964
- async function Lt(n, t, a, i) {
964
+ async function Dt(n, t, a, i) {
965
965
  const r = {};
966
966
  for (const u of await Ce(n)) {
967
- const p = t ? `${t}/${u.name}` : u.name;
967
+ const d = t ? `${t}/${u.name}` : u.name;
968
968
  if (u.kind === "directory") {
969
969
  if (a.skipDirs.includes(u.name)) continue;
970
- const d = u;
971
- for (const [f, g] of Object.entries(await Lt(d, p, a, i)))
970
+ const p = u;
971
+ for (const [f, g] of Object.entries(await Dt(p, d, a, i)))
972
972
  r[`${u.name}/${f}`] = g;
973
973
  continue;
974
974
  }
@@ -976,42 +976,42 @@ async function Lt(n, t, a, i) {
976
976
  if (!a.textExt.includes(po(u.name))) {
977
977
  i.failures.push({
978
978
  kind: "file",
979
- where: p,
979
+ where: d,
980
980
  message: `不是文本文件(认得的扩展名:${a.textExt.join(" ")}),已跳过`
981
981
  });
982
982
  continue;
983
983
  }
984
984
  try {
985
- const d = await u.getFile();
986
- if (d.size > a.maxFileBytes) {
985
+ const p = await u.getFile();
986
+ if (p.size > a.maxFileBytes) {
987
987
  i.failures.push({
988
988
  kind: "file",
989
- where: p,
990
- message: `文件 ${Math.round(d.size / 1024)} KB 超过上限 ${Math.floor(a.maxFileBytes / 1024)} KB,已跳过`
989
+ where: d,
990
+ message: `文件 ${Math.round(p.size / 1024)} KB 超过上限 ${Math.floor(a.maxFileBytes / 1024)} KB,已跳过`
991
991
  });
992
992
  continue;
993
993
  }
994
- r[u.name] = uo(await d.text());
995
- } catch (d) {
996
- i.failures.push({ kind: "file", where: p, message: `读不了这个文件:${Ne(d)}` });
994
+ r[u.name] = uo(await p.text());
995
+ } catch (p) {
996
+ i.failures.push({ kind: "file", where: d, message: `读不了这个文件:${Ne(p)}` });
997
997
  }
998
998
  }
999
999
  }
1000
1000
  return r;
1001
1001
  }
1002
- async function Dt(n, t, a, i, r) {
1003
- const u = await Ce(n), p = u.filter((f) => f.kind === "directory"), d = u.filter((f) => f.kind === "file");
1004
- if (p.length === 0 || d.some((f) => f.name === i.entry)) {
1005
- r.folders.push({ where: t.join("/"), files: await Lt(n, t.join("/"), i, r) });
1002
+ async function zt(n, t, a, i, r) {
1003
+ const u = await Ce(n), d = u.filter((f) => f.kind === "directory"), p = u.filter((f) => f.kind === "file");
1004
+ if (d.length === 0 || p.some((f) => f.name === i.entry)) {
1005
+ r.folders.push({ where: t.join("/"), files: await Dt(n, t.join("/"), i, r) });
1006
1006
  return;
1007
1007
  }
1008
- for (const f of d)
1008
+ for (const f of p)
1009
1009
  t.length === 0 && i.rootSkipFiles.includes(f.name.toLowerCase()) || r.failures.push({
1010
1010
  kind: "file",
1011
1011
  where: [...t, f.name].join("/"),
1012
1012
  message: `这一层直接放着一份文件,但它自己不是块文件夹、也没有 ${i.entry},文件没有归属`
1013
1013
  });
1014
- for (const f of p)
1014
+ for (const f of d)
1015
1015
  if (!i.skipDirs.includes(f.name)) {
1016
1016
  if (a >= i.maxDepth) {
1017
1017
  r.truncated = !0, r.failures.push({
@@ -1021,113 +1021,119 @@ async function Dt(n, t, a, i, r) {
1021
1021
  });
1022
1022
  continue;
1023
1023
  }
1024
- await Dt(f, [...t, f.name], a + 1, i, r);
1024
+ await zt(f, [...t, f.name], a + 1, i, r);
1025
1025
  }
1026
1026
  }
1027
- function gt(n) {
1027
+ function yt(n) {
1028
1028
  return n >= 1024 * 1024 ? `${(n / 1024 / 1024).toFixed(1)} MB` : `${Math.max(1, Math.round(n / 1024))} KB`;
1029
1029
  }
1030
1030
  async function fo(n, t) {
1031
1031
  const a = { root: n.name, folders: [], failures: [], truncated: !1 };
1032
- await Dt(n.handle, [], 0, t, a);
1032
+ await zt(n.handle, [], 0, t, a);
1033
1033
  const i = a.folders.reduce(
1034
- (r, u) => r + Object.values(u.files).reduce((p, d) => p + d.length, 0),
1034
+ (r, u) => r + Object.values(u.files).reduce((d, p) => d + p.length, 0),
1035
1035
  0
1036
1036
  );
1037
1037
  if (i > t.maxBodyBytes)
1038
1038
  throw new Error(
1039
- `这个目录读到的正文有 ${gt(i)},超过一次读回的上限 ${gt(t.maxBodyBytes)}:请先只留要改的那几个块,或者把大文件挪走。`
1039
+ `这个目录读到的正文有 ${yt(i)},超过一次读回的上限 ${yt(t.maxBodyBytes)}:请先只留要改的那几个块,或者把大文件挪走。`
1040
1040
  );
1041
1041
  return a;
1042
1042
  }
1043
1043
  const mo = {
1044
1044
  key: 0,
1045
- class: "mbc"
1046
- }, bo = { class: "mbc__head" }, vo = ["disabled"], ho = {
1045
+ class: "mbc__shell"
1046
+ }, bo = {
1047
1047
  key: 0,
1048
- class: "mbc__error"
1049
- }, go = {
1050
- key: 1,
1051
- class: "mbc__notice"
1052
- }, yo = { class: "mbc__panel" }, _o = { class: "mbc__title" }, ko = { class: "mbc__list" }, $o = ["title", "onClick"], wo = { class: "mbc__module" }, xo = { class: "mbc__name" }, Co = ["title"], Eo = {
1048
+ class: "mbc"
1049
+ }, vo = { class: "mbc__head" }, ho = ["disabled"], go = { class: "mbc__panel" }, yo = { class: "mbc__title" }, _o = { class: "mbc__list" }, ko = ["title", "onClick"], $o = { class: "mbc__module" }, wo = { class: "mbc__name" }, xo = ["title"], Co = {
1053
1050
  key: 0,
1054
1051
  class: "mbc__where"
1055
- }, So = {
1052
+ }, Eo = {
1056
1053
  key: 0,
1057
1054
  class: "mbc__detail"
1058
1055
  }, To = {
1059
1056
  key: 0,
1060
1057
  class: "mbc__hint"
1061
- }, Bo = { class: "mbc__meta" }, Mo = { class: "mbc__hint" }, Oo = { class: "mbc__mono" }, Ao = { class: "mbc__actions" }, Ro = ["disabled", "onClick"], Po = { class: "mbc__versions" }, jo = { class: "mbc__versions-head" }, No = ["disabled", "onClick"], Io = {
1058
+ }, So = { class: "mbc__meta" }, Bo = { class: "mbc__hint" }, Mo = { class: "mbc__mono" }, Ao = { class: "mbc__actions" }, Oo = ["disabled", "onClick"], Ro = { class: "mbc__versions" }, jo = { class: "mbc__versions-head" }, Po = ["disabled", "onClick"], No = {
1062
1059
  key: 0,
1063
1060
  class: "mbc__hint"
1064
- }, Lo = {
1061
+ }, Io = {
1065
1062
  key: 1,
1066
1063
  class: "mbc__versions-list"
1067
- }, Do = { class: "mbc__mono" }, zo = { class: "mbc__hint" }, Fo = { class: "mbc__actions" }, Ho = ["disabled", "onClick", "title"], Uo = ["disabled", "onClick", "title"], Ko = ["disabled", "onClick", "title"], qo = ["disabled", "onClick", "title"], Vo = {
1064
+ }, Lo = { class: "mbc__mono" }, Do = { class: "mbc__hint" }, zo = { class: "mbc__actions" }, Fo = ["disabled", "onClick", "title"], Ho = ["disabled", "onClick", "title"], Uo = ["disabled", "onClick", "title"], Ko = ["disabled", "onClick", "title"], qo = {
1068
1065
  key: 2,
1069
1066
  class: "mbc__hint"
1070
- }, Go = {
1067
+ }, Vo = {
1071
1068
  key: 3,
1072
1069
  class: "mbc__viewer"
1073
- }, Jo = { class: "mbc__versions-head" }, Wo = { class: "mbc__mono" }, Yo = { class: "mbc__viewer-body" }, Zo = { class: "mbc__panel" }, Xo = { class: "mbc__field" }, Qo = { class: "mbc__radio" }, es = ["checked"], ts = { class: "mbc__radio" }, ns = ["checked"], os = ["value", "disabled"], ss = {
1070
+ }, Jo = { class: "mbc__versions-head" }, Go = { class: "mbc__mono" }, Wo = { class: "mbc__viewer-body" }, Yo = { class: "mbc__panel" }, Zo = { class: "mbc__field" }, Xo = { class: "mbc__radio" }, Qo = ["checked"], es = { class: "mbc__radio" }, ts = ["checked"], ns = ["value", "disabled"], os = {
1074
1071
  key: 0,
1075
1072
  value: ""
1076
- }, as = ["value"], is = { class: "mbc__field" }, ls = ["value"], rs = ["disabled"], cs = ["disabled", "title"], us = { class: "mbc__hint" }, ds = {
1073
+ }, ss = ["value"], as = { class: "mbc__field" }, is = ["value"], ls = ["disabled"], rs = ["disabled", "title"], cs = { class: "mbc__hint" }, us = {
1077
1074
  key: 0,
1078
1075
  class: "mbc__hint"
1079
- }, ps = ["aria-valuenow"], fs = {
1076
+ }, ds = ["aria-valuenow"], ps = {
1080
1077
  key: 3,
1081
1078
  class: "mbc__confirm"
1082
- }, ms = { class: "mbc__confirm-title" }, bs = { class: "mbc__confirm-body" }, vs = {
1079
+ }, fs = { class: "mbc__confirm-title" }, ms = { class: "mbc__confirm-body" }, bs = {
1083
1080
  key: 0,
1084
1081
  class: "mbc__mono"
1085
- }, hs = { class: "mbc__actions" }, gs = ["disabled"], ys = ["disabled"], _s = ["disabled"], ks = {
1082
+ }, vs = { class: "mbc__actions" }, hs = ["disabled"], gs = ["disabled"], ys = ["disabled"], _s = {
1086
1083
  key: 4,
1087
1084
  class: "mbc__confirm"
1088
- }, $s = { class: "mbc__confirm-title" }, ws = { class: "mbc__confirm-body" }, xs = { class: "mbc__mono" }, Cs = { class: "mbc__actions" }, Es = ["disabled"], Ss = ["disabled"], Ts = { class: "mbc__panel" }, Bs = { class: "mbc__field" }, Ms = ["value"], Os = ["disabled"], As = ["disabled"], Rs = {
1085
+ }, ks = { class: "mbc__confirm-title" }, $s = { class: "mbc__confirm-body" }, ws = { class: "mbc__mono" }, xs = { class: "mbc__actions" }, Cs = ["disabled"], Es = ["disabled"], Ts = { class: "mbc__panel" }, Ss = { class: "mbc__field" }, Bs = ["value"], Ms = ["disabled"], As = ["disabled"], Os = {
1089
1086
  key: 0,
1090
1087
  class: "mbc__hint"
1091
- }, Ps = {
1088
+ }, Rs = {
1092
1089
  key: 1,
1093
1090
  class: "mbc__hint"
1094
1091
  }, js = {
1095
1092
  key: 0,
1096
1093
  class: "mbc__hint"
1097
- }, Ns = ["disabled"], Is = ["disabled"], Ls = {
1094
+ }, Ps = ["disabled"], Ns = ["disabled"], Is = {
1098
1095
  key: 1,
1099
1096
  class: "mbc__scan"
1100
- }, Ds = { class: "mbc__pick" }, zs = ["disabled", "checked", "onChange"], Fs = { class: "mbc__name" }, Hs = { class: "mbc__module" }, Us = { class: "mbc__hint" }, Ks = { class: "mbc__mono" }, qs = {
1097
+ }, Ls = { class: "mbc__pick" }, Ds = ["disabled", "checked", "onChange"], zs = { class: "mbc__name" }, Fs = { class: "mbc__module" }, Hs = { class: "mbc__hint" }, Us = { class: "mbc__mono" }, Ks = {
1101
1098
  key: 0,
1102
1099
  class: "mbc__problem"
1103
- }, Vs = { class: "mbc__hint mbc__mono" }, Gs = {
1100
+ }, qs = { class: "mbc__hint mbc__mono" }, Vs = {
1104
1101
  key: 2,
1105
1102
  class: "mbc__hint"
1106
1103
  }, Js = {
1107
1104
  key: 3,
1108
1105
  class: "mbc__problem"
1109
- }, Ws = {
1106
+ }, Gs = {
1110
1107
  key: 4,
1111
1108
  class: "mbc__hint"
1112
- }, Ys = {
1109
+ }, Ws = {
1113
1110
  key: 5,
1114
1111
  class: "mbc__failures"
1115
- }, Zs = { class: "mbc__field mbc__field--end" }, Xs = ["disabled"], Qs = {
1116
- key: 2,
1112
+ }, Ys = { class: "mbc__field mbc__field--end" }, Zs = ["disabled"], Xs = {
1113
+ key: 0,
1117
1114
  class: "mbc__panel"
1118
- }, ea = { class: "mbc__title" }, ta = {
1115
+ }, Qs = { class: "mbc__title" }, ea = {
1119
1116
  key: 0,
1120
1117
  class: "mbc__failures"
1121
- }, na = {
1118
+ }, ta = {
1122
1119
  key: 1,
1123
1120
  class: "mbc__failures"
1124
- }, oa = { key: 0 }, sa = {
1121
+ }, na = { key: 0 }, oa = {
1125
1122
  key: 1,
1126
1123
  class: "mbc__failures mbc__failures--nested"
1127
- }, Ye = 2, aa = /* @__PURE__ */ ot({
1124
+ }, sa = { class: "mbc__foot" }, aa = {
1125
+ key: 0,
1126
+ class: "mbc__error"
1127
+ }, ia = {
1128
+ key: 1,
1129
+ class: "mbc__notice"
1130
+ }, la = {
1131
+ key: 2,
1132
+ class: "mbc__hint mbc__foot-idle"
1133
+ }, Ye = 2, ra = /* @__PURE__ */ ot({
1128
1134
  __name: "MagicBlockConsole",
1129
1135
  setup(n) {
1130
- const t = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: a } = wt(), i = $t(), { active: r } = an(), u = (s) => !xt(s, i), p = w(!1), d = w(""), f = w([]), g = w(""), C = w(""), y = w(""), _ = w(!1), z = w(!1), I = w(!1), X = w(!1), oe = w(!1), P = w(null), O = w(null), H = w("one"), se = w(Ie()), q = N(() => f.value.find((s) => s.id === se.value) ?? null), ue = () => H.value === "all" ? {} : { blocks: [se.value] };
1136
+ const t = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: a } = xt(), i = wt(), { active: r } = an(), u = (s) => !Ct(s, i), d = w(!1), p = w(""), f = w([]), g = w(""), E = w(""), y = w(""), _ = w(!1), z = w(!1), I = w(!1), X = w(!1), oe = w(!1), j = w(null), M = w(null), H = w("one"), se = w(Ie()), q = N(() => f.value.find((s) => s.id === se.value) ?? null), ue = () => H.value === "all" ? {} : { blocks: [se.value] };
1131
1137
  function Ee(s) {
1132
1138
  se.value = s;
1133
1139
  try {
@@ -1145,73 +1151,73 @@ const mo = {
1145
1151
  fe(f, (s) => {
1146
1152
  s.length !== 0 && (s.some((e) => e.id === se.value) || Ee(s[0].id));
1147
1153
  });
1148
- const V = w(null), G = w(""), B = w(null), Q = w({}), Z = w([]), ae = w([]), ee = w({}), be = w(""), J = w(null);
1154
+ const V = w(null), J = w(""), B = w(null), Q = w({}), Z = w([]), ae = w([]), ee = w({}), be = w(""), G = w(null);
1149
1155
  async function de(s) {
1150
1156
  be.value = s;
1151
1157
  try {
1152
1158
  const e = await K(`/magic-blocks/${encodeURIComponent(s)}/versions`);
1153
1159
  ee.value = { ...ee.value, [s]: e.versions ?? [] };
1154
1160
  } catch (e) {
1155
- C.value = ne(e);
1161
+ E.value = ne(e);
1156
1162
  } finally {
1157
1163
  be.value = "";
1158
1164
  }
1159
1165
  }
1160
- function Se(s) {
1166
+ function Te(s) {
1161
1167
  const e = [s.current ? "当前" : "", s.empty ? "空包(代码被删过)" : ""].filter(Boolean).join("、");
1162
1168
  return `v${s.number}${e ? ` · ${e}` : ""}`;
1163
1169
  }
1164
1170
  function ve(s) {
1165
1171
  return s < 1024 ? `${s} B` : s < 1024 * 1024 ? `${Math.round(s / 1024)} KB` : `${(s / 1024 / 1024).toFixed(1)} MB`;
1166
1172
  }
1167
- const T = w(null);
1173
+ const S = w(null);
1168
1174
  function ie(s, e) {
1169
1175
  return `${String(e || "").replace(/[\\/:*?"<>|]/g, "").trim() || "block"}-${s}`;
1170
1176
  }
1171
- const Te = (s) => F(async () => {
1177
+ const Se = (s) => F(async () => {
1172
1178
  const e = ie(s.id, s.name || s.module);
1173
- let o = P.value, c = null;
1179
+ let o = j.value, c = null;
1174
1180
  if (o)
1175
1181
  try {
1176
- c = await vt(o, V.value ?? await Ue());
1182
+ c = await ht(o, V.value ?? await Ue());
1177
1183
  } catch {
1178
1184
  o = null, c = null;
1179
1185
  }
1180
- T.value = { row: s, target: o, folder: e, inventory: c };
1186
+ S.value = { row: s, target: o, folder: e, inventory: c };
1181
1187
  }, _), Le = () => F(async () => {
1182
- const s = T.value;
1183
- if (T.value = null, !s) return;
1188
+ const s = S.value;
1189
+ if (S.value = null, !s) return;
1184
1190
  const e = `「${s.row.module} / ${s.row.name || s.row.id}」`;
1185
1191
  h.value = { active: !0, percent: 0, stage: "清本机那个文件夹…", failed: !1 };
1186
1192
  let o = "";
1187
1193
  if (s.target)
1188
1194
  try {
1189
- const c = await Be(s.target, s.folder), k = await ht(c);
1195
+ const c = await Be(s.target, s.folder), k = await gt(c);
1190
1196
  o = `清掉了本机「${s.target.name}/${s.folder}」里的 ${k} 项`;
1191
1197
  } catch (c) {
1192
1198
  o = `本机那份没清成(${ne(c)})`;
1193
1199
  }
1194
1200
  else
1195
1201
  o = "没选开发目录 ⇒ 本机那份没动";
1196
- S(60, "清库里那份代码…");
1202
+ T(60, "清库里那份代码…");
1197
1203
  try {
1198
1204
  await K(`/magic-blocks/${s.row.id}`, { method: "DELETE" });
1199
1205
  } catch (c) {
1200
1206
  throw L(!1, "本机清了,但库里那份代码没清成"), new Error(`${o};但**库里那份代码没清成**(${ne(c)})—— 再点一次「删除代码文件」`);
1201
1207
  }
1202
- await _e(), G.value = `${e}的代码文件已删除:${o};库里那一份也清空了 ——**块还在**(页面上会显示成占位框),想找回来点「回滚上一版」`, y.value = `删掉了${e}的代码文件(块本身还在)`, L(!0, "完成");
1208
+ await _e(), J.value = `${e}的代码文件已删除:${o};库里那一份也清空了 ——**块还在**(页面上会显示成占位框),想找回来点「回滚上一版」`, y.value = `删掉了${e}的代码文件(块本身还在)`, L(!0, "完成");
1203
1209
  }, _);
1204
1210
  async function Be(s, e) {
1205
1211
  let o = s.handle;
1206
- for (const c of It(e))
1212
+ for (const c of Lt(e))
1207
1213
  o = await o.getDirectoryHandle(c, { create: !0 });
1208
1214
  return { handle: o, name: `${s.name}/${e}` };
1209
1215
  }
1210
- const A = w(null), h = w({ active: !1, percent: 0, stage: "", failed: !1 }), $ = N(() => ({
1216
+ const O = w(null), h = w({ active: !1, percent: 0, stage: "", failed: !1 }), $ = N(() => ({
1211
1217
  width: `${Math.max(0, Math.min(100, h.value.percent))}%`,
1212
1218
  background: h.value.failed ? "var(--sp-color-danger)" : "var(--sp-color-primary, var(--primary-color))"
1213
1219
  }));
1214
- function S(s, e) {
1220
+ function T(s, e) {
1215
1221
  h.value = { active: !0, percent: Math.max(h.value.percent, s), stage: e, failed: !1 };
1216
1222
  try {
1217
1223
  const o = window.localStorage.getItem("mb:progress") ?? "[]", c = JSON.parse(o);
@@ -1220,13 +1226,13 @@ const mo = {
1220
1226
  }
1221
1227
  }
1222
1228
  function L(s, e) {
1223
- S(s ? 100 : h.value.percent, e), h.value = { active: !s, percent: s ? 100 : h.value.percent, stage: e, failed: !s };
1229
+ T(s ? 100 : h.value.percent, e), h.value = { active: !s, percent: s ? 100 : h.value.percent, stage: e, failed: !s };
1224
1230
  }
1225
1231
  const he = (s) => (s.disabledReason ?? "").trim(), ge = (s) => (s.issues ?? []).map((e) => String(e?.message ?? "")).filter(Boolean), te = (s) => Fn(s.id);
1226
1232
  function De(s) {
1227
1233
  g.value = g.value === s.id ? "" : s.id, g.value === s.id && de(s.id);
1228
1234
  const e = r.value;
1229
- jt(s.id);
1235
+ Nt(s.id);
1230
1236
  const o = s.name || s.id, c = te(s);
1231
1237
  if (c.length === 0) {
1232
1238
  y.value = `「${o}」这次会话里还没在哪条标签上露过面:先打开挂着它的那一页,再点一次`;
@@ -1247,7 +1253,7 @@ const mo = {
1247
1253
  const o = await K(
1248
1254
  `/magic-blocks/${encodeURIComponent(s.id)}/versions/${e}`
1249
1255
  );
1250
- J.value = { id: s.id, number: e, files: o.files ?? {} }, y.value = `正在看「${s.name || s.id}」的 v${e}(只读:不会改库里任何东西)`;
1256
+ G.value = { id: s.id, number: e, files: o.files ?? {} }, y.value = `正在看「${s.name || s.id}」的 v${e}(只读:不会改库里任何东西)`;
1251
1257
  }, _), Fe = (s, e) => F(async () => {
1252
1258
  window.confirm(`把「${s.name || s.id}」切回 v${e}?
1253
1259
 
@@ -1256,10 +1262,10 @@ const mo = {
1256
1262
  window.confirm(`删掉「${s.name || s.id}」的 v${e}?
1257
1263
 
1258
1264
  这一版的代码就找不回来了(别的版本不受影响)。`) && (await K(`/magic-blocks/${encodeURIComponent(s.id)}/versions/${e}`, { method: "DELETE" }), y.value = `删掉了「${s.name || s.id}」的 v${e}`, await de(s.id));
1259
- }, _), zt = (s, e) => F(async () => {
1265
+ }, _), Ft = (s, e) => F(async () => {
1260
1266
  const o = await fetch(
1261
1267
  `http://localhost:3000/magic-blocks/${encodeURIComponent(s.id)}/versions/${e}?download=1`,
1262
- { credentials: "include", headers: je("GET", !1) }
1268
+ { credentials: "include", headers: Pe("GET", !1) }
1263
1269
  );
1264
1270
  if (!o.ok) throw new Error(`下载失败(HTTP ${o.status})`);
1265
1271
  const c = await o.blob(), k = URL.createObjectURL(c);
@@ -1271,26 +1277,26 @@ const mo = {
1271
1277
  }
1272
1278
  y.value = `已下载「${s.name || s.id}」的 v${e}`;
1273
1279
  }, _);
1274
- function Ft(s) {
1280
+ function Ht(s) {
1275
1281
  const e = te(s), o = e.length === 0 ? "点一下:这次会话里它还没在哪条标签上露过面" : `点一下:把「${s.name || s.id}」标红,并在需要时切到挂着它的标签(${e.join(" / ")})`, c = he(s);
1276
1282
  return c ? `${c}
1277
1283
  ${o}` : o;
1278
1284
  }
1279
1285
  const at = N(() => {
1280
- const s = d.value.trim().toLowerCase();
1286
+ const s = p.value.trim().toLowerCase();
1281
1287
  return s ? f.value.filter((e) => `${e.module} ${e.name} ${e.brief} ${e.id} v${e.version ?? ""}`.toLowerCase().includes(s)) : f.value;
1282
- }), Me = N(() => (B.value?.blocks ?? []).filter((s) => s.canApply)), Oe = N(() => Me.value.filter((s) => Q.value[s.id] === !0));
1283
- function Ht() {
1288
+ }), Me = N(() => (B.value?.blocks ?? []).filter((s) => s.canApply)), Ae = N(() => Me.value.filter((s) => Q.value[s.id] === !0));
1289
+ function Ut() {
1284
1290
  const s = i?.getRoutes?.() ?? [], e = /* @__PURE__ */ new Set(), o = [];
1285
1291
  for (const c of s) {
1286
1292
  const k = typeof c?.path == "string" ? c.path.trim() : "";
1287
1293
  if (!k || e.has(k) || k.includes(":") || k.includes("*") || c.redirect || !c.components?.default || c.meta?.tab === !1) continue;
1288
1294
  e.add(k);
1289
- const R = c.meta?.title ?? c.meta?.sub, j = c.meta?.group;
1295
+ const R = c.meta?.title ?? c.meta?.sub, P = c.meta?.group;
1290
1296
  o.push({
1291
1297
  path: k,
1292
1298
  title: typeof R == "string" && R.trim() ? R.trim() : k,
1293
- group: typeof j == "string" ? j.trim() : ""
1299
+ group: typeof P == "string" ? P.trim() : ""
1294
1300
  });
1295
1301
  }
1296
1302
  return o;
@@ -1298,7 +1304,7 @@ ${o}` : o;
1298
1304
  function ne(s) {
1299
1305
  return (s instanceof Error ? s.message.trim() : String(s)) || "请求没有到达后端(网络或登录态的问题),请重试";
1300
1306
  }
1301
- function Ut(s) {
1307
+ function Kt(s) {
1302
1308
  const e = s?.issues;
1303
1309
  return Array.isArray(e) ? e.map((o) => typeof o == "string" ? o : String(o?.message ?? "")).filter(Boolean) : [];
1304
1310
  }
@@ -1310,11 +1316,11 @@ ${o}` : o;
1310
1316
  const k = ne(c), R = await fetch(`http://localhost:3000${s}`, {
1311
1317
  method: "POST",
1312
1318
  credentials: "include",
1313
- headers: { "Content-Type": "application/json", ...je("POST", !0) },
1319
+ headers: { "Content-Type": "application/json", ...Pe("POST", !0) },
1314
1320
  body: o
1315
- }).then((pe) => pe.json()).catch(() => null), j = Ut(R);
1316
- throw j.length === 0 ? new Error(k) : new Error(`${String(R?.message ?? k)}
1317
- - ${j.join(`
1321
+ }).then((pe) => pe.json()).catch(() => null), P = Kt(R);
1322
+ throw P.length === 0 ? new Error(k) : new Error(`${String(R?.message ?? k)}
1323
+ - ${P.join(`
1318
1324
  - `)}`);
1319
1325
  }
1320
1326
  }
@@ -1323,20 +1329,20 @@ ${o}` : o;
1323
1329
  const s = await K("/magic-blocks/index");
1324
1330
  f.value = s.blocks ?? [];
1325
1331
  } catch (s) {
1326
- C.value = ne(s);
1332
+ E.value = ne(s);
1327
1333
  }
1328
1334
  }
1329
1335
  async function F(s, e) {
1330
- e.value = !0, C.value = "";
1336
+ e.value = !0, E.value = "";
1331
1337
  try {
1332
- await s(), Pn();
1338
+ await s(), jn();
1333
1339
  } catch (o) {
1334
- C.value = ne(o);
1340
+ E.value = ne(o);
1335
1341
  } finally {
1336
1342
  e.value = !1;
1337
1343
  }
1338
1344
  }
1339
- const Kt = () => F(async () => {
1345
+ const qt = () => F(async () => {
1340
1346
  z.value = !0;
1341
1347
  try {
1342
1348
  await K("/magic-blocks/check", { method: "POST", body: JSON.stringify({}) }), y.value = "全部魔法块重新校验完了", await _e();
@@ -1345,26 +1351,26 @@ ${o}` : o;
1345
1351
  }
1346
1352
  }, _), it = (s) => F(async () => {
1347
1353
  const e = await We();
1348
- s === "export" ? (P.value = e, O.value || (O.value = e)) : (O.value = e, P.value || (P.value = e)), y.value = s === "export" ? `导出目录:${e.name}${O.value === e ? "(读回目录也填成它了)" : ""}` : `读回目录:${e.name}`;
1354
+ s === "export" ? (j.value = e, M.value || (M.value = e)) : (M.value = e, j.value || (j.value = e)), y.value = s === "export" ? `导出目录:${e.name}${M.value === e ? "(读回目录也填成它了)" : ""}` : `读回目录:${e.name}`;
1349
1355
  }, _);
1350
1356
  async function Ue() {
1351
1357
  if (V.value) return V.value;
1352
1358
  const s = await K("/magic-blocks/rules");
1353
1359
  return V.value = s.rules, s.rules;
1354
1360
  }
1355
- const qt = () => F(async () => {
1356
- if (!Nt()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
1361
+ const Vt = () => F(async () => {
1362
+ if (!It()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
1357
1363
  if (H.value === "one" && !q.value)
1358
1364
  throw new Error("还没挑块:上面选「仅这一个块」时要先在下拉里挑一个块(或者把范围改成「全部块」)");
1359
- I.value = !0, y.value = "", G.value = "", C.value = "", h.value = { active: !0, percent: 0, stage: "准备…", failed: !1 };
1365
+ I.value = !0, y.value = "", J.value = "", E.value = "", h.value = { active: !0, percent: 0, stage: "准备…", failed: !1 };
1360
1366
  try {
1361
- const s = P.value ?? await We();
1362
- P.value = s, O.value || (O.value = s);
1367
+ const s = j.value ?? await We();
1368
+ j.value = s, M.value || (M.value = s);
1363
1369
  const e = await ye("/magic-blocks/export", ue());
1364
1370
  V.value = e.rules, co(s, e.rules);
1365
- const o = await vt(s, e.rules);
1371
+ const o = await ht(s, e.rules);
1366
1372
  if (o.topCount > 0) {
1367
- S(5, "等你确认要不要先清空"), A.value = { target: s, inventory: o };
1373
+ T(5, "等你确认要不要先清空"), O.value = { target: s, inventory: o };
1368
1374
  return;
1369
1375
  }
1370
1376
  await Ke(s, e, !1);
@@ -1376,40 +1382,40 @@ ${o}` : o;
1376
1382
  }, _);
1377
1383
  async function Ke(s, e, o) {
1378
1384
  try {
1379
- S(20, "收主题与控件清单…");
1385
+ T(20, "收主题与控件清单…");
1380
1386
  const c = { ...e.files };
1381
1387
  let k = "";
1382
1388
  await new Promise((D) => {
1383
1389
  setTimeout(D, 0);
1384
1390
  });
1385
- const R = so(Ht());
1386
- c[Je] = R;
1391
+ const R = so(Ut());
1392
+ c[Ge] = R;
1387
1393
  try {
1388
1394
  const D = Pt(), ke = In();
1389
- c[re] = D.css, c[Pe] = ke, e.exampleDir && (c[`${e.exampleDir}/${Je}`] = R, c[`${e.exampleDir}/${re}`] = D.css, c[`${e.exampleDir}/${Pe}`] = ke), k = D.skipped.length > 0 ? `;⚠️ 有 ${D.skipped.length} 张样式表读不到规则(跨源):${D.skipped.join(" / ")}` : "";
1395
+ c[re] = D.css, c[je] = ke, e.exampleDir && (c[`${e.exampleDir}/${Ge}`] = R, c[`${e.exampleDir}/${re}`] = D.css, c[`${e.exampleDir}/${je}`] = ke), k = D.skipped.length > 0 ? `;⚠️ 有 ${D.skipped.length} 张样式表读不到规则(跨源):${D.skipped.join(" / ")}` : "";
1390
1396
  } catch (D) {
1391
1397
  k = `;主题 CSS 没收成(${ne(D)}):${re} 没写,其余照旧`;
1392
1398
  }
1393
- let j = "";
1394
- o && (S(35, "清空目录…"), j = `,先清掉了 ${await ht(s)} 项`);
1399
+ let P = "";
1400
+ o && (T(35, "清空目录…"), P = `,先清掉了 ${await gt(s)} 项`);
1395
1401
  const pe = Object.keys(c).length, qe = o ? 45 : 30;
1396
- S(qe, `写文件 0/${pe}…`);
1402
+ T(qe, `写文件 0/${pe}…`);
1397
1403
  const le = await ro(s, c, (D, ke) => {
1398
- S(qe + Math.round(D / Math.max(1, ke) * (95 - qe)), `写文件 ${D}/${ke}…`);
1404
+ T(qe + Math.round(D / Math.max(1, ke) * (95 - qe)), `写文件 ${D}/${ke}…`);
1399
1405
  });
1400
- S(98, "收尾…");
1401
- const Zt = le.failed.length > 0 ? `;⚠️ ${le.failed.length} 个文件没写成:${le.failed.slice(0, 3).map((D) => `${D.path}(${D.message})`).join("、")}` + (le.failed.length > 3 ? ` 等 ${le.failed.length} 条` : "") : "";
1402
- G.value = `铺到「${s.name}」:${e.blocks} 个块、${le.written} 个文件(含 ${Je} / ${re} / ${Pe})${j}${Zt}${k}`, y.value = le.failed.length > 0 ? "导出完了,但有文件没写成(见下面那句)" : "导出完了:用你自己的编辑器改,改完回这里「读回改动」", L(!0, "完成");
1406
+ T(98, "收尾…");
1407
+ const Xt = le.failed.length > 0 ? `;⚠️ ${le.failed.length} 个文件没写成:${le.failed.slice(0, 3).map((D) => `${D.path}(${D.message})`).join("、")}` + (le.failed.length > 3 ? ` 等 ${le.failed.length} 条` : "") : "";
1408
+ J.value = `铺到「${s.name}」:${e.blocks} 个块、${le.written} 个文件(含 ${Ge} / ${re} / ${je})${P}${Xt}${k}`, y.value = le.failed.length > 0 ? "导出完了,但有文件没写成(见下面那句)" : "导出完了:用你自己的编辑器改,改完回这里「读回改动」", L(!0, "完成");
1403
1409
  } catch (c) {
1404
1410
  throw L(!1, "导出中途失败(已经铺进去的文件不会自己删掉)"), c;
1405
1411
  }
1406
1412
  }
1407
- const Vt = () => F(async () => {
1408
- const s = A.value;
1409
- if (A.value = null, !!s) {
1413
+ const Jt = () => F(async () => {
1414
+ const s = O.value;
1415
+ if (O.value = null, !!s) {
1410
1416
  I.value = !0;
1411
1417
  try {
1412
- S(15, "重新取一份开发包…");
1418
+ T(15, "重新取一份开发包…");
1413
1419
  const e = await ye("/magic-blocks/export", ue());
1414
1420
  V.value = e.rules, await Ke(s.target, e, !0);
1415
1421
  } catch (e) {
@@ -1419,11 +1425,11 @@ ${o}` : o;
1419
1425
  }
1420
1426
  }
1421
1427
  }, _), Gt = () => F(async () => {
1422
- const s = A.value;
1423
- if (A.value = null, !!s) {
1428
+ const s = O.value;
1429
+ if (O.value = null, !!s) {
1424
1430
  I.value = !0;
1425
1431
  try {
1426
- S(15, "重新取一份开发包…");
1432
+ T(15, "重新取一份开发包…");
1427
1433
  const e = await ye("/magic-blocks/export", ue());
1428
1434
  V.value = e.rules, await Ke(s.target, e, !1);
1429
1435
  } catch (e) {
@@ -1433,30 +1439,30 @@ ${o}` : o;
1433
1439
  }
1434
1440
  }
1435
1441
  }, _);
1436
- function Jt() {
1437
- A.value = null, h.value = { active: !1, percent: 0, stage: "", failed: !1 }, y.value = "这次没有导出(目录里的东西一个字节都没动)", G.value = "";
1442
+ function Wt() {
1443
+ O.value = null, h.value = { active: !1, percent: 0, stage: "", failed: !1 }, y.value = "这次没有导出(目录里的东西一个字节都没动)", J.value = "";
1438
1444
  }
1439
1445
  const lt = () => F(async () => {
1440
- const s = O.value ?? await We();
1441
- O.value = s, P.value || (P.value = s), X.value = !0, y.value = "", Z.value = [], ae.value = [];
1446
+ const s = M.value ?? await We();
1447
+ M.value = s, j.value || (j.value = s), X.value = !0, y.value = "", Z.value = [], ae.value = [];
1442
1448
  try {
1443
- const e = await Ue().catch((j) => {
1444
- throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${ne(j)}`);
1449
+ const e = await Ue().catch((P) => {
1450
+ throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${ne(P)}`);
1445
1451
  }), o = await fo(s, e), c = await K("/magic-blocks/read", {
1446
1452
  method: "POST",
1447
1453
  body: JSON.stringify({ ...o, includeMissing: !1 })
1448
1454
  });
1449
1455
  B.value = c;
1450
1456
  const k = {};
1451
- for (const j of c.blocks ?? []) k[j.id] = j.status === "modified" && j.canApply;
1457
+ for (const P of c.blocks ?? []) k[P.id] = P.status === "modified" && P.canApply;
1452
1458
  Q.value = k;
1453
- const R = (c.blocks ?? []).reduce((j, pe) => ({ ...j, [pe.status]: (j[pe.status] ?? 0) + 1 }), {});
1459
+ const R = (c.blocks ?? []).reduce((P, pe) => ({ ...P, [pe.status]: (P[pe.status] ?? 0) + 1 }), {});
1454
1460
  y.value = `扫到 ${c.folders} 个文件夹、${c.files} 个文件:有改动 ${R.modified ?? 0} / 没改动 ${R.unchanged ?? 0}` + (c.complete ? "" : "(层数到了上限,没走完,可能还有块没扫到)");
1455
1461
  } finally {
1456
1462
  X.value = !1;
1457
1463
  }
1458
- }, _), Wt = () => F(async () => {
1459
- const s = Oe.value, e = xn(s);
1464
+ }, _), Yt = () => F(async () => {
1465
+ const s = Ae.value, e = xn(s);
1460
1466
  if (Z.value = e.issues, ae.value = [], e.issues.length > 0)
1461
1467
  throw y.value = "", new Error(`前端校验没过(${e.issues.length} 条),没有发请求:
1462
1468
  - ${e.issues.join(`
@@ -1471,7 +1477,7 @@ ${o}` : o;
1471
1477
  oe.value = !1;
1472
1478
  }
1473
1479
  }, _);
1474
- function Yt(s, e) {
1480
+ function Zt(s, e) {
1475
1481
  const o = e.target;
1476
1482
  Q.value[s] = o?.checked === !0;
1477
1483
  }
@@ -1482,169 +1488,172 @@ ${o}` : o;
1482
1488
  }
1483
1489
  function ct(s) {
1484
1490
  const e = s.detail?.uuid ?? "";
1485
- p.value = !0, g.value = e;
1491
+ d.value = !0, g.value = e;
1486
1492
  }
1487
- return yt(() => {
1488
- window.addEventListener("magic-block:open-console", ct), _e(), Ue().catch(() => {
1493
+ function ut(s) {
1494
+ s.key === "Escape" && d.value && (d.value = !1);
1495
+ }
1496
+ return _t(() => {
1497
+ window.addEventListener("magic-block:open-console", ct), window.addEventListener("keydown", ut), _e(), Ue().catch(() => {
1489
1498
  });
1490
- }), _t(() => window.removeEventListener("magic-block:open-console", ct)), (s, e) => $e(a) ? (b(), v(M, { key: 0 }, [
1499
+ }), kt(() => {
1500
+ window.removeEventListener("magic-block:open-console", ct), window.removeEventListener("keydown", ut);
1501
+ }), (s, e) => $e(a) ? (b(), v("div", mo, [
1491
1502
  l("button", {
1492
1503
  class: "fab",
1493
1504
  type: "button",
1494
1505
  title: "magic block 控制台",
1495
- onClick: e[0] || (e[0] = (o) => p.value = !0)
1506
+ onClick: e[0] || (e[0] = (o) => d.value = !0)
1496
1507
  }, "块"),
1497
- p.value ? (b(), v("aside", mo, [
1498
- l("header", bo, [
1499
- e[20] || (e[20] = l("strong", null, "magic block", -1)),
1500
- en(l("input", {
1501
- "onUpdate:modelValue": e[1] || (e[1] = (o) => d.value = o),
1508
+ d.value ? (b(), v("aside", bo, [
1509
+ l("header", vo, [
1510
+ e[21] || (e[21] = l("strong", null, "magic block", -1)),
1511
+ tn(l("input", {
1512
+ "onUpdate:modelValue": e[1] || (e[1] = (o) => p.value = o),
1502
1513
  class: "p-inputtext p-component mbc__grow",
1503
1514
  type: "search",
1504
1515
  placeholder: "筛选 module / 名字 / 备注 / id / 版本号"
1505
1516
  }, null, 512), [
1506
- [tn, d.value]
1517
+ [nn, p.value]
1507
1518
  ]),
1508
1519
  l("button", {
1509
1520
  class: "p-button p-button-sm",
1510
1521
  type: "button",
1511
1522
  disabled: _.value,
1512
- onClick: e[2] || (e[2] = (o) => Kt())
1513
- }, m(z.value ? "校验中…" : "校验全部魔法块"), 9, vo),
1523
+ onClick: e[2] || (e[2] = (o) => qt())
1524
+ }, m(z.value ? "校验中…" : "校验全部魔法块"), 9, ho),
1514
1525
  l("button", {
1515
1526
  class: "p-button p-button-sm p-button-text",
1516
1527
  type: "button",
1517
- onClick: e[3] || (e[3] = (o) => p.value = !1)
1528
+ onClick: e[3] || (e[3] = (o) => d.value = !1)
1518
1529
  }, "关闭")
1519
1530
  ]),
1520
- C.value ? (b(), v("p", ho, m(C.value), 1)) : x("", !0),
1521
- y.value ? (b(), v("p", go, m(y.value), 1)) : x("", !0),
1522
- l("section", yo, [
1523
- l("h3", _o, "库里的块(" + m(at.value.length) + " / " + m(f.value.length) + ")", 1),
1524
- l("ul", ko, [
1525
- (b(!0), v(M, null, U(at.value, (o) => (b(), v("li", {
1531
+ l("section", go, [
1532
+ l("h3", yo, "库里的块(" + m(at.value.length) + " / " + m(f.value.length) + ")", 1),
1533
+ l("ul", _o, [
1534
+ (b(!0), v(A, null, U(at.value, (o) => (b(), v("li", {
1526
1535
  key: o.id
1527
1536
  }, [
1528
1537
  l("button", {
1529
1538
  type: "button",
1530
1539
  class: W(["mbc__row", { "is-active": o.id === g.value }]),
1531
- title: Ft(o),
1540
+ title: Ht(o),
1532
1541
  onClick: (c) => De(o)
1533
1542
  }, [
1534
- l("span", wo, m(o.module || "unassigned"), 1),
1535
- l("span", xo, m(o.name || o.id), 1),
1543
+ l("span", $o, m(o.module || "unassigned"), 1),
1544
+ l("span", wo, m(o.name || o.id), 1),
1536
1545
  l("span", {
1537
1546
  class: "mbc__version-badge",
1538
1547
  title: `当前是第 ${o.version || 1} 版,一共留着 ${o.versionCount ?? 1} 版`
1539
1548
  }, [
1540
- E("v" + m(o.version || 1), 1),
1541
- (o.versionCount ?? 1) > 1 ? (b(), v(M, { key: 0 }, [
1542
- E("/" + m(o.versionCount), 1)
1549
+ C("v" + m(o.version || 1), 1),
1550
+ (o.versionCount ?? 1) > 1 ? (b(), v(A, { key: 0 }, [
1551
+ C("/" + m(o.versionCount), 1)
1543
1552
  ], 64)) : x("", !0)
1544
- ], 8, Co),
1545
- te(o).length > 0 ? (b(), v("span", Eo, m(te(o).join(" / ")), 1)) : x("", !0),
1553
+ ], 8, xo),
1554
+ te(o).length > 0 ? (b(), v("span", Co, m(te(o).join(" / ")), 1)) : x("", !0),
1546
1555
  l("em", {
1547
1556
  class: W({ "is-off": o.enabled === !1 })
1548
1557
  }, m(o.enabled === !1 ? he(o) || "校验失败已停用" : "可用"), 3)
1549
- ], 10, $o),
1550
- g.value === o.id ? (b(), v("div", So, [
1551
- (b(!0), v(M, null, U(ge(o).slice(0, Ye), (c, k) => (b(), v("p", {
1558
+ ], 10, ko),
1559
+ g.value === o.id ? (b(), v("div", Eo, [
1560
+ (b(!0), v(A, null, U(ge(o).slice(0, Ye), (c, k) => (b(), v("p", {
1552
1561
  key: k,
1553
1562
  class: "mbc__problem"
1554
1563
  }, m(c), 1))), 128)),
1555
1564
  ge(o).length > Ye ? (b(), v("p", To, "还有 " + m(ge(o).length - Ye) + " 条问题没显示出来:点上面的「校验全部魔法块」重算一遍(这几条是上次校验的结论)", 1)) : x("", !0),
1556
- l("dl", Bo, [
1557
- e[21] || (e[21] = l("dt", null, "文件", -1)),
1565
+ l("dl", So, [
1566
+ e[22] || (e[22] = l("dt", null, "文件", -1)),
1558
1567
  l("dd", null, m((o.fileNames || []).join(" / ") || "(没有文件)"), 1),
1559
- e[22] || (e[22] = l("dt", null, "版本", -1)),
1568
+ e[23] || (e[23] = l("dt", null, "版本", -1)),
1560
1569
  l("dd", null, [
1561
- E("v" + m(o.version || 1), 1),
1562
- l("span", Mo, "(一共留着 " + m(o.versionCount ?? ee.value[o.id]?.length ?? 1) + " 版)", 1)
1570
+ C("v" + m(o.version || 1), 1),
1571
+ l("span", Bo, "(一共留着 " + m(o.versionCount ?? ee.value[o.id]?.length ?? 1) + " 版)", 1)
1563
1572
  ]),
1564
- e[23] || (e[23] = l("dt", null, "更新", -1)),
1573
+ e[24] || (e[24] = l("dt", null, "更新", -1)),
1565
1574
  l("dd", null, m(o.updatedAt || "—"), 1),
1566
- e[24] || (e[24] = l("dt", null, "id", -1)),
1567
- l("dd", Oo, m(o.id), 1)
1575
+ e[25] || (e[25] = l("dt", null, "id", -1)),
1576
+ l("dd", Mo, m(o.id), 1)
1568
1577
  ]),
1569
1578
  l("div", Ao, [
1570
1579
  l("button", {
1571
1580
  class: "p-button p-button-sm p-button-outlined",
1572
1581
  type: "button",
1573
1582
  disabled: _.value,
1574
- onClick: (c) => Te(o),
1583
+ onClick: (c) => Se(o),
1575
1584
  title: "删掉这一块的代码文件:本机的文件夹 + 库里那份代码正文(点下去会先问你确认)。块本身留着,页面上会显示成占位框"
1576
- }, "删除代码文件", 8, Ro)
1585
+ }, "删除代码文件", 8, Oo)
1577
1586
  ]),
1578
- l("div", Po, [
1587
+ l("div", Ro, [
1579
1588
  l("div", jo, [
1580
- e[25] || (e[25] = l("strong", null, "版本(每次上传 +1,旧的都留着)", -1)),
1589
+ e[26] || (e[26] = l("strong", null, "版本(每次上传 +1,旧的都留着)", -1)),
1581
1590
  l("button", {
1582
1591
  class: "p-button p-button-sm p-button-text",
1583
1592
  type: "button",
1584
1593
  disabled: _.value,
1585
1594
  onClick: (c) => de(o.id)
1586
- }, m(be.value === o.id ? "读版本中…" : "刷新版本"), 9, No)
1595
+ }, m(be.value === o.id ? "读版本中…" : "刷新版本"), 9, Po)
1587
1596
  ]),
1588
- ee.value[o.id] ? ee.value[o.id].length > 0 ? (b(), v("ul", Lo, [
1589
- (b(!0), v(M, null, U(ee.value[o.id], (c) => (b(), v("li", {
1597
+ ee.value[o.id] ? ee.value[o.id].length > 0 ? (b(), v("ul", Io, [
1598
+ (b(!0), v(A, null, U(ee.value[o.id], (c) => (b(), v("li", {
1590
1599
  key: c.number,
1591
1600
  class: W({ "is-current": c.current })
1592
1601
  }, [
1593
- l("span", Do, m(Se(c)), 1),
1594
- l("span", zo, [
1595
- E(m(c.fileCount) + " 个文件 · " + m(ve(c.sizeBytes)), 1),
1596
- c.createdBy ? (b(), v(M, { key: 0 }, [
1597
- E(" · " + m(c.createdBy), 1)
1602
+ l("span", Lo, m(Te(c)), 1),
1603
+ l("span", Do, [
1604
+ C(m(c.fileCount) + " 个文件 · " + m(ve(c.sizeBytes)), 1),
1605
+ c.createdBy ? (b(), v(A, { key: 0 }, [
1606
+ C(" · " + m(c.createdBy), 1)
1598
1607
  ], 64)) : x("", !0),
1599
- E(" · " + m(c.createdAt || "—"), 1)
1608
+ C(" · " + m(c.createdAt || "—"), 1)
1600
1609
  ]),
1601
- l("span", Fo, [
1610
+ l("span", zo, [
1602
1611
  l("button", {
1603
1612
  class: "p-button p-button-sm p-button-text",
1604
1613
  type: "button",
1605
1614
  disabled: _.value || c.empty,
1606
1615
  onClick: (k) => ze(o, c.number),
1607
1616
  title: c.empty ? "这一版是空包(代码被删过),没有正文可看" : "看这一版的正文(只读)"
1608
- }, "查看", 8, Ho),
1617
+ }, "查看", 8, Fo),
1609
1618
  l("button", {
1610
1619
  class: "p-button p-button-sm p-button-text",
1611
1620
  type: "button",
1612
1621
  disabled: _.value || c.current || c.empty,
1613
1622
  onClick: (k) => Fe(o, c.number),
1614
1623
  title: c.current ? "这一版正在跑" : "把这一版变成当前版(会记成一个新版本)"
1615
- }, "切回", 8, Uo),
1624
+ }, "切回", 8, Ho),
1616
1625
  l("button", {
1617
1626
  class: "p-button p-button-sm p-button-text",
1618
1627
  type: "button",
1619
1628
  disabled: _.value || c.empty,
1620
- onClick: (k) => zt(o, c.number),
1629
+ onClick: (k) => Ft(o, c.number),
1621
1630
  title: c.empty ? "空包没什么可下的" : "下载这一版(一个 zip)"
1622
- }, "下载", 8, Ko),
1631
+ }, "下载", 8, Uo),
1623
1632
  l("button", {
1624
1633
  class: "p-button p-button-sm p-button-text",
1625
1634
  type: "button",
1626
1635
  disabled: _.value || c.current,
1627
1636
  onClick: (k) => He(o, c.number),
1628
1637
  title: c.current ? "当前那一版不许删:先切到别的版本" : "删掉这一版(别的版本不受影响)"
1629
- }, "删", 8, qo)
1638
+ }, "删", 8, Ko)
1630
1639
  ])
1631
1640
  ], 2))), 128))
1632
- ])) : (b(), v("p", Vo, "这个块还没有版本记录(它从没被保存过)。")) : (b(), v("p", Io, "正在读版本…(没读到时点「刷新版本」)")),
1633
- J.value && J.value.id === o.id ? (b(), v("div", Go, [
1641
+ ])) : (b(), v("p", qo, "这个块还没有版本记录(它从没被保存过)。")) : (b(), v("p", No, "正在读版本…(没读到时点「刷新版本」)")),
1642
+ G.value && G.value.id === o.id ? (b(), v("div", Vo, [
1634
1643
  l("div", Jo, [
1635
- l("strong", null, "看 v" + m(J.value.number) + " 的正文(只读)", 1),
1644
+ l("strong", null, "看 v" + m(G.value.number) + " 的正文(只读)", 1),
1636
1645
  l("button", {
1637
1646
  class: "p-button p-button-sm p-button-text",
1638
1647
  type: "button",
1639
- onClick: e[4] || (e[4] = (c) => J.value = null)
1648
+ onClick: e[4] || (e[4] = (c) => G.value = null)
1640
1649
  }, "收起")
1641
1650
  ]),
1642
- (b(!0), v(M, null, U(J.value.files, (c, k) => (b(), v("details", {
1651
+ (b(!0), v(A, null, U(G.value.files, (c, k) => (b(), v("details", {
1643
1652
  key: k,
1644
1653
  class: "mbc__viewer-file"
1645
1654
  }, [
1646
- l("summary", Wo, m(k) + "(" + m(ve(c.length)) + ")", 1),
1647
- l("pre", Yo, m(c), 1)
1655
+ l("summary", Go, m(k) + "(" + m(ve(c.length)) + ")", 1),
1656
+ l("pre", Wo, m(c), 1)
1648
1657
  ]))), 128))
1649
1658
  ])) : x("", !0)
1650
1659
  ])
@@ -1652,29 +1661,29 @@ ${o}` : o;
1652
1661
  ]))), 128))
1653
1662
  ])
1654
1663
  ]),
1655
- l("section", Zo, [
1656
- e[50] || (e[50] = l("h3", { class: "mbc__title" }, "导出去改(用你自己的编辑器)", -1)),
1657
- l("div", Xo, [
1658
- e[27] || (e[27] = l("span", { class: "mbc__label" }, "导出范围", -1)),
1659
- l("label", Qo, [
1664
+ l("section", Yo, [
1665
+ e[53] || (e[53] = l("h3", { class: "mbc__title" }, "导出去改(用你自己的编辑器)", -1)),
1666
+ l("div", Zo, [
1667
+ e[28] || (e[28] = l("span", { class: "mbc__label" }, "导出范围", -1)),
1668
+ l("label", Xo, [
1660
1669
  l("input", {
1661
1670
  type: "radio",
1662
1671
  name: "mbc-scope",
1663
1672
  value: "one",
1664
1673
  checked: H.value === "one",
1665
1674
  onChange: e[5] || (e[5] = (o) => H.value = "one")
1666
- }, null, 40, es),
1667
- e[26] || (e[26] = E(" 仅这一个块 ", -1))
1675
+ }, null, 40, Qo),
1676
+ e[27] || (e[27] = C(" 仅这一个块 ", -1))
1668
1677
  ]),
1669
- l("label", ts, [
1678
+ l("label", es, [
1670
1679
  l("input", {
1671
1680
  type: "radio",
1672
1681
  name: "mbc-scope",
1673
1682
  value: "all",
1674
1683
  checked: H.value === "all",
1675
1684
  onChange: e[6] || (e[6] = (o) => H.value = "all")
1676
- }, null, 40, ns),
1677
- E(" 全部块(" + m(f.value.length) + " 个) ", 1)
1685
+ }, null, 40, ts),
1686
+ C(" 全部块(" + m(f.value.length) + " 个) ", 1)
1678
1687
  ]),
1679
1688
  H.value === "one" ? (b(), v("select", {
1680
1689
  key: 0,
@@ -1683,43 +1692,44 @@ ${o}` : o;
1683
1692
  disabled: _.value || f.value.length === 0,
1684
1693
  onChange: e[7] || (e[7] = (o) => Ee(o.target.value))
1685
1694
  }, [
1686
- f.value.length === 0 ? (b(), v("option", ss, "(库里还没有块)")) : x("", !0),
1687
- (b(!0), v(M, null, U(f.value, (o) => (b(), v("option", {
1695
+ f.value.length === 0 ? (b(), v("option", os, "(库里还没有块)")) : x("", !0),
1696
+ (b(!0), v(A, null, U(f.value, (o) => (b(), v("option", {
1688
1697
  key: o.id,
1689
1698
  value: o.id
1690
- }, m(o.module) + " / " + m(o.name || o.id), 9, as))), 128))
1691
- ], 40, os)) : x("", !0)
1699
+ }, m(o.module) + " / " + m(o.name || o.id), 9, ss))), 128))
1700
+ ], 40, ns)) : x("", !0)
1692
1701
  ]),
1693
- l("div", is, [
1694
- e[28] || (e[28] = l("label", { for: "mbc-dir" }, "导出目录", -1)),
1702
+ l("div", as, [
1703
+ e[29] || (e[29] = l("label", { for: "mbc-dir" }, "导出目录", -1)),
1695
1704
  l("input", {
1696
1705
  id: "mbc-dir",
1697
1706
  class: "p-inputtext p-component mbc__grow mbc__mono",
1698
1707
  type: "text",
1699
1708
  readonly: "",
1700
- value: P.value ? P.value.name : "(还没选:点右边那个按钮选一个文件夹)"
1701
- }, null, 8, ls),
1709
+ value: j.value ? j.value.name : "(还没选:点右边那个按钮选一个文件夹)"
1710
+ }, null, 8, is),
1702
1711
  l("button", {
1703
1712
  class: "p-button p-button-sm p-button-outlined",
1704
1713
  type: "button",
1705
1714
  disabled: _.value,
1706
1715
  onClick: e[8] || (e[8] = (o) => it("export"))
1707
- }, "选择文件夹", 8, rs),
1716
+ }, "选择文件夹", 8, ls),
1708
1717
  l("button", {
1709
- class: "p-button p-button-sm",
1718
+ class: "p-button p-button-sm mbc__act-export",
1710
1719
  type: "button",
1711
1720
  disabled: _.value || H.value === "one" && !q.value,
1712
- title: H.value === "one" && !q.value ? "先在左边挑一个块(或者把范围改成「全部块」)" : "",
1713
- onClick: e[9] || (e[9] = (o) => qt())
1714
- }, m(I.value ? "导出中…" : "导出"), 9, cs)
1721
+ title: H.value === "one" && !q.value ? "先在左边挑一个块(或者把范围改成「全部块」)" : "把库里的块铺到你选的文件夹",
1722
+ onClick: e[9] || (e[9] = (o) => Vt())
1723
+ }, m(I.value ? "导出中…" : "导出"), 9, rs)
1715
1724
  ]),
1716
- l("p", us, [
1717
- E(m(H.value === "all" ? `这一趟会铺全部 ${f.value.length} 个块` : q.value ? `这一趟只铺「${q.value.module} / ${q.value.name || q.value.id}」这一个块` : "先挑一个块") + "; ", 1),
1718
- e[29] || (e[29] = l("span", { class: "mbc__mono" }, "workspace/<可读名>-<块 uuid>/", -1)),
1719
- e[30] || (e[30] = E(" 只在选中块的包里出现。 ", -1))
1725
+ l("p", cs, [
1726
+ C(m(H.value === "all" ? `这一趟铺全部 ${f.value.length} 个块` : q.value ? `这一趟只铺「${q.value.module} / ${q.value.name || q.value.id}」` : "先挑一个块") + " ⇒ ", 1),
1727
+ e[30] || (e[30] = l("span", { class: "mbc__mono" }, "workspace/<可读名>-<块 uuid>/", -1)),
1728
+ e[31] || (e[31] = C(",顶层另附开发说明与 ", -1)),
1729
+ e[32] || (e[32] = l("span", { class: "mbc__mono" }, "example/", -1)),
1730
+ e[33] || (e[33] = C("。 ", -1))
1720
1731
  ]),
1721
- e[51] || (e[51] = nn('<p class="mbc__hint" data-v-4b400b4f> 代码会铺在 <span class="mbc__mono" data-v-4b400b4f>workspace/&lt;可读名&gt;-&lt;块 uuid&gt;/</span>, 顶层另附 <span class="mbc__mono" data-v-4b400b4f>GUIDE.lock.md</span>(怎么改)、<span class="mbc__mono" data-v-4b400b4f>pages.lock.ts</span>(Page 枚举)、 <span class="mbc__mono" data-v-4b400b4f>backend.lock.pyi</span>(能用的库 / ctx / 环境变量 / 模型)、 <span class="mbc__mono" data-v-4b400b4f>labull.css</span> 与 <span class="mbc__mono" data-v-4b400b4f>CONTROLS.lock.html</span>(主题与控件清单)—— 那几份都是**生成物**。 另外还有一份 <span class="mbc__mono" data-v-4b400b4f>example/</span>(身份证 OCR 的完整例子):它**与这个顶层同构**, 顶层那几份生成物在里面各有一份同名副本,改名 / 搬走之后参考清单还跟着走。 </p>', 1)),
1722
- G.value ? (b(), v("p", ds, m(G.value), 1)) : x("", !0),
1732
+ J.value ? (b(), v("p", us, m(J.value), 1)) : x("", !0),
1723
1733
  h.value.active ? (b(), v("div", {
1724
1734
  key: 1,
1725
1735
  class: W(["mbc__progress", { "is-failed": h.value.failed }]),
@@ -1730,102 +1740,102 @@ ${o}` : o;
1730
1740
  }, [
1731
1741
  l("div", {
1732
1742
  class: "mbc__progress-bar",
1733
- style: kt($.value)
1743
+ style: $t($.value)
1734
1744
  }, null, 4)
1735
- ], 10, ps)) : x("", !0),
1745
+ ], 10, ds)) : x("", !0),
1736
1746
  h.value.active ? (b(), v("p", {
1737
1747
  key: 2,
1738
1748
  class: W(["mbc__hint", { "mbc__progress-note": h.value.failed }])
1739
1749
  }, m(h.value.failed ? "✗" : "") + " " + m(h.value.percent) + "% · " + m(h.value.stage), 3)) : x("", !0),
1740
- A.value ? (b(), v("div", fs, [
1741
- l("p", ms, "「" + m(A.value.target.name) + "」里现在有 " + m(A.value.inventory.dirs) + " 个文件夹 / " + m(A.value.inventory.files) + " 个文件", 1),
1742
- l("p", bs, [
1743
- e[31] || (e[31] = E(" 接下来会", -1)),
1744
- e[32] || (e[32] = l("b", null, "先全部删掉", -1)),
1745
- e[33] || (e[33] = E("再铺一遍 —— 包括你改过、还没读回库的东西。 清空只动这个目录", -1)),
1746
- e[34] || (e[34] = l("b", null, "里面", -1)),
1747
- e[35] || (e[35] = E("的子项:目录本身、以及它外面的任何东西都不会被碰。", -1)),
1748
- A.value.inventory.items.length > 0 ? (b(), v("span", vs, "(" + m(A.value.inventory.items.slice(0, 6).map((o) => o.name).join(" / ")) + m(A.value.inventory.items.length > 6 ? " …" : "") + ")", 1)) : x("", !0)
1750
+ O.value ? (b(), v("div", ps, [
1751
+ l("p", fs, "「" + m(O.value.target.name) + "」里现在有 " + m(O.value.inventory.dirs) + " 个文件夹 / " + m(O.value.inventory.files) + " 个文件", 1),
1752
+ l("p", ms, [
1753
+ e[34] || (e[34] = C(" 接下来会", -1)),
1754
+ e[35] || (e[35] = l("b", null, "先全部删掉", -1)),
1755
+ e[36] || (e[36] = C("再铺一遍 —— 包括你改过、还没读回库的东西。 清空只动这个目录", -1)),
1756
+ e[37] || (e[37] = l("b", null, "里面", -1)),
1757
+ e[38] || (e[38] = C("的子项:目录本身、以及它外面的任何东西都不会被碰。", -1)),
1758
+ O.value.inventory.items.length > 0 ? (b(), v("span", bs, "(" + m(O.value.inventory.items.slice(0, 6).map((o) => o.name).join(" / ")) + m(O.value.inventory.items.length > 6 ? " …" : "") + ")", 1)) : x("", !0)
1749
1759
  ]),
1750
- l("div", hs, [
1760
+ l("div", vs, [
1751
1761
  l("button", {
1752
1762
  class: "p-button p-button-sm",
1753
1763
  type: "button",
1754
1764
  disabled: _.value,
1755
- onClick: e[10] || (e[10] = (o) => Vt())
1756
- }, "清空并导出", 8, gs),
1765
+ onClick: e[10] || (e[10] = (o) => Jt())
1766
+ }, "清空并导出", 8, hs),
1757
1767
  l("button", {
1758
1768
  class: "p-button p-button-sm p-button-outlined",
1759
1769
  type: "button",
1760
1770
  disabled: _.value,
1761
1771
  onClick: e[11] || (e[11] = (o) => Gt())
1762
- }, "只覆盖", 8, ys),
1772
+ }, "只覆盖", 8, gs),
1763
1773
  l("button", {
1764
1774
  class: "p-button p-button-sm p-button-text",
1765
1775
  type: "button",
1766
1776
  disabled: _.value,
1767
- onClick: e[12] || (e[12] = (o) => Jt())
1768
- }, "取消", 8, _s)
1777
+ onClick: e[12] || (e[12] = (o) => Wt())
1778
+ }, "取消", 8, ys)
1769
1779
  ])
1770
1780
  ])) : x("", !0),
1771
- T.value ? (b(), v("div", ks, [
1772
- l("p", $s, "删掉「" + m(T.value.row.module) + " / " + m(T.value.row.name || T.value.row.id) + "」的代码文件", 1),
1773
- l("p", ws, [
1774
- e[44] || (e[44] = l("b", null, "库里那一份代码正文会被清空", -1)),
1775
- e[45] || (e[45] = E("(入口 / 清单 / 后端一起); ", -1)),
1776
- T.value.target ? (b(), v(M, { key: 0 }, [
1777
- e[36] || (e[36] = E(" 同时清掉你本机那个块文件夹 ", -1)),
1778
- l("span", xs, m(T.value.target.name) + "/" + m(T.value.folder), 1),
1779
- T.value.inventory && T.value.inventory.items.some((o) => o.name === T.value?.folder) ? (b(), v(M, { key: 0 }, [
1780
- E(" (它现在在顶层,里面有东西:本次会先清空)。 ")
1781
+ S.value ? (b(), v("div", _s, [
1782
+ l("p", ks, "删掉「" + m(S.value.row.module) + " / " + m(S.value.row.name || S.value.row.id) + "」的代码文件", 1),
1783
+ l("p", $s, [
1784
+ e[47] || (e[47] = l("b", null, "库里那一份代码正文会被清空", -1)),
1785
+ e[48] || (e[48] = C("(入口 / 清单 / 后端一起); ", -1)),
1786
+ S.value.target ? (b(), v(A, { key: 0 }, [
1787
+ e[39] || (e[39] = C(" 同时清掉你本机那个块文件夹 ", -1)),
1788
+ l("span", ws, m(S.value.target.name) + "/" + m(S.value.folder), 1),
1789
+ S.value.inventory && S.value.inventory.items.some((o) => o.name === S.value?.folder) ? (b(), v(A, { key: 0 }, [
1790
+ C(" (它现在在顶层,里面有东西:本次会先清空)。 ")
1781
1791
  ], 64)) : x("", !0),
1782
- e[37] || (e[37] = l("b", null, "只动这一个块的文件夹", -1)),
1783
- e[38] || (e[38] = E(":别的块、", -1)),
1784
- e[39] || (e[39] = l("span", { class: "mbc__mono" }, "example/", -1)),
1785
- e[40] || (e[40] = E("、以及目录外面的一切都不会被碰。 ", -1))
1786
- ], 64)) : (b(), v(M, { key: 1 }, [
1787
- e[41] || (e[41] = E(" 现在没有选中开发目录 / 或者读不到它,所以", -1)),
1788
- e[42] || (e[42] = l("b", null, "本机那份不动", -1)),
1789
- e[43] || (e[43] = E(",只清库里那份。 ", -1))
1792
+ e[40] || (e[40] = l("b", null, "只动这一个块的文件夹", -1)),
1793
+ e[41] || (e[41] = C(":别的块、", -1)),
1794
+ e[42] || (e[42] = l("span", { class: "mbc__mono" }, "example/", -1)),
1795
+ e[43] || (e[43] = C("、以及目录外面的一切都不会被碰。 ", -1))
1796
+ ], 64)) : (b(), v(A, { key: 1 }, [
1797
+ e[44] || (e[44] = C(" 现在没有选中开发目录 / 或者读不到它,所以", -1)),
1798
+ e[45] || (e[45] = l("b", null, "本机那份不动", -1)),
1799
+ e[46] || (e[46] = C(",只清库里那份。 ", -1))
1790
1800
  ], 64)),
1791
- e[46] || (e[46] = l("br", null, null, -1)),
1792
- e[47] || (e[47] = E(" 🔴 ", -1)),
1793
- e[48] || (e[48] = l("b", null, "块本身留着", -1)),
1794
- e[49] || (e[49] = E('(这一行不动):页面上那块会显示成占位框,而不是"库里没有这个块"; 删错了也能用「回滚上一版」找回来(不过那个按钮**不在这个控制台里**,走管理后台 / 接口)。 ', -1))
1801
+ e[49] || (e[49] = l("br", null, null, -1)),
1802
+ e[50] || (e[50] = C(" 🔴 ", -1)),
1803
+ e[51] || (e[51] = l("b", null, "块本身留着", -1)),
1804
+ e[52] || (e[52] = C('(这一行不动):页面上那块会显示成占位框,而不是"库里没有这个块"; 删错了也能用「回滚上一版」找回来(不过那个按钮**不在这个控制台里**,走管理后台 / 接口)。 ', -1))
1795
1805
  ]),
1796
- l("div", Cs, [
1806
+ l("div", xs, [
1797
1807
  l("button", {
1798
1808
  class: "p-button p-button-sm",
1799
1809
  type: "button",
1800
1810
  disabled: _.value,
1801
1811
  onClick: e[13] || (e[13] = (o) => Le())
1802
- }, "确认删除代码文件", 8, Es),
1812
+ }, "确认删除代码文件", 8, Cs),
1803
1813
  l("button", {
1804
1814
  class: "p-button p-button-sm p-button-text",
1805
1815
  type: "button",
1806
1816
  disabled: _.value,
1807
- onClick: e[14] || (e[14] = (o) => T.value = null)
1808
- }, "取消", 8, Ss)
1817
+ onClick: e[14] || (e[14] = (o) => S.value = null)
1818
+ }, "取消", 8, Es)
1809
1819
  ])
1810
1820
  ])) : x("", !0)
1811
1821
  ]),
1812
1822
  l("section", Ts, [
1813
- e[57] || (e[57] = l("h3", { class: "mbc__title" }, "读回改动", -1)),
1814
- l("div", Bs, [
1815
- e[52] || (e[52] = l("label", { for: "mbc-read-dir" }, "读回目录", -1)),
1823
+ e[59] || (e[59] = l("h3", { class: "mbc__title" }, "读回改动", -1)),
1824
+ l("div", Ss, [
1825
+ e[54] || (e[54] = l("label", { for: "mbc-read-dir" }, "读回目录", -1)),
1816
1826
  l("input", {
1817
1827
  id: "mbc-read-dir",
1818
1828
  class: "p-inputtext p-component mbc__grow mbc__mono",
1819
1829
  type: "text",
1820
1830
  readonly: "",
1821
- value: O.value ? O.value.name : "(还没选:导出会自动填上,也可以自己选一个)"
1822
- }, null, 8, Ms),
1831
+ value: M.value ? M.value.name : "(还没选:导出会自动填上,也可以自己选一个)"
1832
+ }, null, 8, Bs),
1823
1833
  l("button", {
1824
1834
  class: "p-button p-button-sm p-button-outlined",
1825
1835
  type: "button",
1826
1836
  disabled: _.value,
1827
1837
  onClick: e[15] || (e[15] = (o) => it("read"))
1828
- }, "选择文件夹", 8, Os),
1838
+ }, "选择文件夹", 8, Ms),
1829
1839
  l("button", {
1830
1840
  class: "p-button p-button-sm p-button-outlined",
1831
1841
  type: "button",
@@ -1833,31 +1843,31 @@ ${o}` : o;
1833
1843
  onClick: e[16] || (e[16] = (o) => lt())
1834
1844
  }, m(X.value ? "读回中…" : "读回改动"), 9, As)
1835
1845
  ]),
1836
- O.value && P.value && O.value.name !== P.value.name ? (b(), v("p", Rs, " 读回的是「" + m(O.value.name) + "」(与导出目录「" + m(P.value.name) + "」不是同一个 —— 想同步就再选一次)。 ", 1)) : (b(), v("p", Ps, "读回目录默认跟着导出目录;要读别的文件夹就点「选择文件夹」单独选一个。")),
1837
- B.value ? (b(), v(M, { key: 2 }, [
1846
+ M.value && j.value && M.value.name !== j.value.name ? (b(), v("p", Os, " 读回的是「" + m(M.value.name) + "」(与导出目录「" + m(j.value.name) + "」不是同一个 —— 想同步就再选一次)。 ", 1)) : (b(), v("p", Rs, "读回目录默认跟着导出目录;要读别的文件夹就点「选择文件夹」单独选一个。")),
1847
+ B.value ? (b(), v(A, { key: 2 }, [
1838
1848
  Me.value.length > 0 ? (b(), v("p", js, [
1839
- E(" 扫到 " + m(B.value.blocks.length) + " 个块,其中 " + m(Me.value.length) + " 个可以存;已经勾了 ", 1),
1840
- l("b", null, m(Oe.value.length), 1),
1841
- e[53] || (e[53] = E(" 个。 ", -1)),
1849
+ C(" 扫到 " + m(B.value.blocks.length) + " 个块,其中 " + m(Me.value.length) + " 个可以存;已经勾了 ", 1),
1850
+ l("b", null, m(Ae.value.length), 1),
1851
+ e[55] || (e[55] = C(" 个。 ", -1)),
1842
1852
  l("button", {
1843
1853
  class: "p-button p-button-sm p-button-text",
1844
1854
  type: "button",
1845
1855
  disabled: _.value,
1846
1856
  onClick: e[17] || (e[17] = (o) => rt(!0))
1847
- }, "全选可存的", 8, Ns),
1857
+ }, "全选可存的", 8, Ps),
1848
1858
  l("button", {
1849
1859
  class: "p-button p-button-sm p-button-text",
1850
1860
  type: "button",
1851
- disabled: _.value || Oe.value.length === 0,
1861
+ disabled: _.value || Ae.value.length === 0,
1852
1862
  onClick: e[18] || (e[18] = (o) => rt(!1))
1853
- }, "全不选", 8, Is)
1863
+ }, "全不选", 8, Ns)
1854
1864
  ])) : x("", !0),
1855
- B.value.blocks.length > 0 ? (b(), v("ul", Ls, [
1856
- (b(!0), v(M, null, U(B.value.blocks, (o) => (b(), v("li", {
1865
+ B.value.blocks.length > 0 ? (b(), v("ul", Is, [
1866
+ (b(!0), v(A, null, U(B.value.blocks, (o) => (b(), v("li", {
1857
1867
  key: o.id,
1858
1868
  class: "mbc__block"
1859
1869
  }, [
1860
- l("label", Ds, [
1870
+ l("label", Ls, [
1861
1871
  l("span", {
1862
1872
  class: W(["p-checkbox p-component", { "p-disabled": !o.canApply }])
1863
1873
  }, [
@@ -1866,87 +1876,97 @@ ${o}` : o;
1866
1876
  type: "checkbox",
1867
1877
  disabled: !o.canApply,
1868
1878
  checked: Q.value[o.id] === !0,
1869
- onChange: (c) => Yt(o.id, c)
1870
- }, null, 40, zs),
1871
- e[54] || (e[54] = l("span", { class: "p-checkbox-box" }, null, -1))
1879
+ onChange: (c) => Zt(o.id, c)
1880
+ }, null, 40, Ds),
1881
+ e[56] || (e[56] = l("span", { class: "p-checkbox-box" }, null, -1))
1872
1882
  ], 2),
1873
- l("span", Fs, m(o.name || o.id), 1),
1883
+ l("span", zs, m(o.name || o.id), 1),
1874
1884
  l("span", {
1875
1885
  class: W(["p-tag", o.status === "modified" ? "p-tag-success" : o.status === "missing" ? "p-tag-warning" : ""])
1876
1886
  }, m(t[o.status]), 3),
1877
- l("span", Hs, m(o.module || "—"), 1)
1887
+ l("span", Fs, m(o.module || "—"), 1)
1878
1888
  ]),
1879
- l("p", Us, [
1880
- o.status === "missing" ? (b(), v(M, { key: 0 }, [
1881
- E("目录里没有这一块,勾不上")
1882
- ], 64)) : o.changedFiles.length > 0 ? (b(), v(M, { key: 1 }, [
1883
- e[55] || (e[55] = E("改了:", -1)),
1884
- l("span", Ks, m(o.changedFiles.join(" / ")), 1)
1885
- ], 64)) : (b(), v(M, { key: 2 }, [
1886
- E("内容与库里一致")
1889
+ l("p", Hs, [
1890
+ o.status === "missing" ? (b(), v(A, { key: 0 }, [
1891
+ C("目录里没有这一块,勾不上")
1892
+ ], 64)) : o.changedFiles.length > 0 ? (b(), v(A, { key: 1 }, [
1893
+ e[57] || (e[57] = C("改了:", -1)),
1894
+ l("span", Us, m(o.changedFiles.join(" / ")), 1)
1895
+ ], 64)) : (b(), v(A, { key: 2 }, [
1896
+ C("内容与库里一致")
1887
1897
  ], 64))
1888
1898
  ]),
1889
- o.blockedWhy ? (b(), v("p", qs, "不能存:" + m(o.blockedWhy), 1)) : x("", !0),
1890
- l("p", Vs, m(o.folder || o.where), 1)
1899
+ o.blockedWhy ? (b(), v("p", Ks, "不能存:" + m(o.blockedWhy), 1)) : x("", !0),
1900
+ l("p", qs, m(o.folder || o.where), 1)
1891
1901
  ]))), 128))
1892
- ])) : (b(), v("p", Gs, "这个目录里没有认出任何块。")),
1902
+ ])) : (b(), v("p", Vs, "这个目录里没有认出任何块。")),
1893
1903
  B.value.unmatched.length > 0 ? (b(), v("p", Js, "认不出归属的文件夹(" + m(B.value.unmatched.length) + "):" + m(B.value.unmatched.join(" / ")), 1)) : x("", !0),
1894
- (B.value.skipped ?? []).length > 0 ? (b(), v("p", Ws, [
1895
- E(" 忽略了 " + m((B.value.skipped ?? []).length) + " 个文件夹(名字里没有 uuid,当测试文件处理 —— 与忽略 ", 1),
1896
- e[56] || (e[56] = l("span", { class: "mbc__mono" }, "example/", -1)),
1897
- E(" 同一个规矩):" + m((B.value.skipped ?? []).join(" / ")), 1)
1904
+ (B.value.skipped ?? []).length > 0 ? (b(), v("p", Gs, [
1905
+ C(" 忽略了 " + m((B.value.skipped ?? []).length) + " 个文件夹(名字里没有 uuid,当测试文件处理 —— 与忽略 ", 1),
1906
+ e[58] || (e[58] = l("span", { class: "mbc__mono" }, "example/", -1)),
1907
+ C(" 同一个规矩):" + m((B.value.skipped ?? []).join(" / ")), 1)
1898
1908
  ])) : x("", !0),
1899
- B.value.failures.length > 0 ? (b(), v("ul", Ys, [
1900
- (b(!0), v(M, null, U(B.value.failures, (o, c) => (b(), v("li", { key: c }, m(o.where || o.kind) + ":" + m(o.message), 1))), 128))
1909
+ B.value.failures.length > 0 ? (b(), v("ul", Ws, [
1910
+ (b(!0), v(A, null, U(B.value.failures, (o, c) => (b(), v("li", { key: c }, m(o.where || o.kind) + ":" + m(o.message), 1))), 128))
1901
1911
  ])) : x("", !0),
1902
- l("div", Zs, [
1912
+ l("div", Ys, [
1903
1913
  l("button", {
1904
- class: "p-button p-button-sm",
1914
+ class: "p-button p-button-sm mbc__act-import",
1905
1915
  type: "button",
1906
1916
  disabled: _.value,
1907
- onClick: e[19] || (e[19] = (o) => Wt())
1908
- }, m(oe.value ? "保存中…" : `保存选中的块(${Oe.value.length})`), 9, Xs)
1917
+ onClick: e[19] || (e[19] = (o) => Yt())
1918
+ }, m(oe.value ? "保存中…" : `保存选中的块(${Ae.value.length})`), 9, Zs)
1909
1919
  ])
1910
1920
  ], 64)) : x("", !0)
1911
1921
  ]),
1912
- Z.value.length > 0 || ae.value.length > 0 ? (b(), v("section", Qs, [
1913
- l("h3", ea, m(Z.value.length > 0 ? "前端校验拦下的问题" : "保存结果"), 1),
1914
- Z.value.length > 0 ? (b(), v("ul", ta, [
1915
- (b(!0), v(M, null, U(Z.value, (o, c) => (b(), v("li", { key: c }, m(o), 1))), 128))
1916
- ])) : (b(), v("ul", na, [
1917
- (b(!0), v(M, null, U(ae.value, (o) => (b(), v("li", {
1922
+ Z.value.length > 0 || ae.value.length > 0 ? (b(), v("section", Xs, [
1923
+ l("h3", Qs, m(Z.value.length > 0 ? "前端校验拦下的问题" : "保存结果"), 1),
1924
+ Z.value.length > 0 ? (b(), v("ul", ea, [
1925
+ (b(!0), v(A, null, U(Z.value, (o, c) => (b(), v("li", { key: c }, m(o), 1))), 128))
1926
+ ])) : (b(), v("ul", ta, [
1927
+ (b(!0), v(A, null, U(ae.value, (o) => (b(), v("li", {
1918
1928
  key: o.id,
1919
1929
  class: W({ "is-ok": o.ok })
1920
1930
  }, [
1921
1931
  l("strong", null, m(o.name || o.id) + ":" + m(o.ok ? "已保存" : "没保存"), 1),
1922
- !o.ok && o.error ? (b(), v("span", oa, m(o.error), 1)) : x("", !0),
1923
- !o.ok && (o.issues ?? []).length > 0 ? (b(), v("ul", sa, [
1924
- (b(!0), v(M, null, U(o.issues, (c, k) => (b(), v("li", { key: k }, m(c), 1))), 128))
1932
+ !o.ok && o.error ? (b(), v("span", na, m(o.error), 1)) : x("", !0),
1933
+ !o.ok && (o.issues ?? []).length > 0 ? (b(), v("ul", oa, [
1934
+ (b(!0), v(A, null, U(o.issues, (c, k) => (b(), v("li", { key: k }, m(c), 1))), 128))
1925
1935
  ])) : x("", !0)
1926
1936
  ], 2))), 128))
1927
1937
  ]))
1928
- ])) : x("", !0)
1929
- ])) : x("", !0)
1930
- ], 64)) : x("", !0);
1938
+ ])) : x("", !0),
1939
+ l("footer", sa, [
1940
+ E.value ? (b(), v("p", aa, m(E.value), 1)) : y.value ? (b(), v("p", ia, m(y.value), 1)) : (b(), v("p", la, "—"))
1941
+ ])
1942
+ ])) : x("", !0),
1943
+ d.value ? (b(), v("button", {
1944
+ key: 1,
1945
+ class: "mbc__close",
1946
+ type: "button",
1947
+ title: "关掉 magic block 控制台(Esc)",
1948
+ onClick: e[20] || (e[20] = (o) => d.value = !1)
1949
+ }, "×")) : x("", !0)
1950
+ ])) : x("", !0);
1931
1951
  }
1932
- }), da = /* @__PURE__ */ Ct(aa, [["__scopeId", "data-v-4b400b4f"]]);
1952
+ }), ma = /* @__PURE__ */ Et(ra, [["__scopeId", "data-v-f4b26cd9"]]);
1933
1953
  export {
1934
1954
  on as API_BASE,
1935
1955
  Cn as BLOCK_BACKEND_FILE,
1936
1956
  xe as BLOCK_ENTRY,
1937
1957
  Ve as BLOCK_MANIFEST,
1938
1958
  rn as CLIENT_SOURCE,
1939
- Ae as MANIFEST_KEYS,
1940
- da as MagicBlockConsole,
1941
- ua as MagicBlockPage,
1959
+ Oe as MANIFEST_KEYS,
1960
+ ma as MagicBlockConsole,
1961
+ fa as MagicBlockPage,
1942
1962
  st as NAME_MAX,
1943
- An as buildPreview,
1963
+ On as buildPreview,
1944
1964
  xn as checkSelection,
1945
1965
  dn as installBridge,
1946
- jn as loadBlockRender,
1966
+ Pn as loadBlockRender,
1947
1967
  Rn as onBlockRenderRefresh,
1948
1968
  kn as parseManifest,
1949
- Pn as refreshBlockRender,
1969
+ jn as refreshBlockRender,
1950
1970
  $n as validFileName,
1951
1971
  vn as validName,
1952
1972
  wn as validateBlock