labull-framework 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/magic-block.js +528 -519
- package/dist/style.css +1 -1
- package/dist/types/magic-block-render.d.ts +7 -0
- package/package.json +1 -1
package/dist/magic-block.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineComponent as We, ref as w, computed as
|
|
1
|
+
import { defineComponent as We, ref as w, computed as C, watch as he, nextTick as Et, onMounted as Ze, onActivated as Ct, onBeforeUnmount as Xe, openBlock as h, createElementBlock as b, normalizeStyle as Qe, normalizeClass as J, unref as be, createElementVNode as p, toDisplayString as v, createCommentVNode as x, Fragment as j, renderList as Q, withModifiers as Bt, withDirectives as Tt, vModelText as At, createStaticVNode as Ot, createTextVNode as ue } from "vue";
|
|
2
2
|
import { useRoute as et, useRouter as tt } from "vue-router";
|
|
3
|
-
import { A as Mt, b as
|
|
3
|
+
import { A as Mt, b as V, c as Me, u as nt } from "./chunk-index-BWpDbB19.js";
|
|
4
4
|
import { _ as ot } from "./chunk-_plugin-vue_export-helper-CHgC5LLL.js";
|
|
5
|
-
const
|
|
5
|
+
const q = "__mb", st = "call", Pe = "reply", at = "host-ready", it = "height", Pt = "html, body { overflow: hidden !important; }", Rt = `
|
|
6
6
|
(function () {
|
|
7
7
|
var seq = 0, waiting = {}, queue = [], ready = false, last = -1;
|
|
8
8
|
function call(method, args) {
|
|
@@ -10,16 +10,16 @@ const G = "__mb", st = "call", Pe = "reply", at = "host-ready", it = "height", P
|
|
|
10
10
|
function run() {
|
|
11
11
|
var id = ++seq;
|
|
12
12
|
waiting[id] = { resolve: resolve, reject: reject };
|
|
13
|
-
parent.postMessage({ '${
|
|
13
|
+
parent.postMessage({ '${q}': '${st}', id: id, method: method, args: args }, '*');
|
|
14
14
|
}
|
|
15
15
|
if (ready) run(); else queue.push(run);
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
window.addEventListener('message', function (event) {
|
|
19
19
|
var data = event.data, pending;
|
|
20
|
-
if (!data || data['${
|
|
21
|
-
if (data['${
|
|
22
|
-
if (data['${
|
|
20
|
+
if (!data || data['${q}'] === undefined) return;
|
|
21
|
+
if (data['${q}'] === '${at}') { ready = true; queue.splice(0).forEach(function (run) { run(); }); return; }
|
|
22
|
+
if (data['${q}'] !== '${Pe}') return;
|
|
23
23
|
if (!(pending = waiting[data.id])) return;
|
|
24
24
|
delete waiting[data.id];
|
|
25
25
|
if (data.ok) pending.resolve(data.value); else pending.reject(new Error(data.error || '调用失败'));
|
|
@@ -58,7 +58,7 @@ const G = "__mb", st = "call", Pe = "reply", at = "host-ready", it = "height", P
|
|
|
58
58
|
if (height > 0) height += 1;
|
|
59
59
|
if (height === last) return; /* 一样高就不再发:否则「宿主改高度 → 触发观察 → 又发一次」会转个不停 */
|
|
60
60
|
last = height;
|
|
61
|
-
parent.postMessage({ '${
|
|
61
|
+
parent.postMessage({ '${q}': '${it}', height: height }, '*');
|
|
62
62
|
}
|
|
63
63
|
function start() {
|
|
64
64
|
report();
|
|
@@ -89,68 +89,68 @@ async function Nt(t, e, n) {
|
|
|
89
89
|
// 带上 HttpOnly 会话 cookie;authHeaders('POST') 给 CSRF 头(缺了 403)
|
|
90
90
|
headers: l ? { "Content-Type": l.type || "application/octet-stream", ...Me("POST") } : { "Content-Type": "application/json", ...Me("POST") },
|
|
91
91
|
body: l ?? JSON.stringify(n ?? {})
|
|
92
|
-
}),
|
|
92
|
+
}), u = await r.text().catch(() => "");
|
|
93
93
|
if (r.ok) {
|
|
94
|
-
if (!
|
|
94
|
+
if (!u) return null;
|
|
95
95
|
try {
|
|
96
|
-
return JSON.parse(
|
|
96
|
+
return JSON.parse(u);
|
|
97
97
|
} catch {
|
|
98
|
-
return
|
|
98
|
+
return u;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
let
|
|
101
|
+
let c = u;
|
|
102
102
|
try {
|
|
103
|
-
const d = JSON.parse(
|
|
104
|
-
typeof d?.message == "string" && (
|
|
103
|
+
const d = JSON.parse(u);
|
|
104
|
+
typeof d?.message == "string" && (c = d.message);
|
|
105
105
|
} catch {
|
|
106
|
-
|
|
106
|
+
c = u;
|
|
107
107
|
}
|
|
108
|
-
throw new Error(
|
|
108
|
+
throw new Error(c ? `${e} 调用失败:${c.slice(0, 300)}` : `${e} 调用失败(${r.status})`);
|
|
109
109
|
}
|
|
110
110
|
function It(t, e) {
|
|
111
|
-
const n = (
|
|
111
|
+
const n = (u) => {
|
|
112
112
|
try {
|
|
113
|
-
t.contentWindow?.postMessage(
|
|
114
|
-
} catch (
|
|
115
|
-
console.warn("[magic-block] 有一条宿主消息没能发给块(协议继续走):",
|
|
113
|
+
t.contentWindow?.postMessage(u, "*");
|
|
114
|
+
} catch (c) {
|
|
115
|
+
console.warn("[magic-block] 有一条宿主消息没能发给块(协议继续走):", c);
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
|
-
async function s(
|
|
119
|
-
if (
|
|
120
|
-
if (
|
|
121
|
-
const d = typeof
|
|
118
|
+
async function s(u, c) {
|
|
119
|
+
if (u === "getMe") return await V("/auth/me");
|
|
120
|
+
if (u === "navigateTab") {
|
|
121
|
+
const d = typeof c[0] == "string" ? c[0].trim() : "";
|
|
122
122
|
if (!d || !e.onNavigateTab) throw new Error(`跳不了 ${d || "(空路径)"}:这个页面没有把宿主接到路由上`);
|
|
123
123
|
return await e.onNavigateTab(d);
|
|
124
124
|
}
|
|
125
|
-
if (
|
|
126
|
-
const d = typeof
|
|
125
|
+
if (u === "backend") {
|
|
126
|
+
const d = typeof c[0] == "string" ? c[0].trim() : "", f = c[1];
|
|
127
127
|
if (!d) throw new Error("后端调用的路由名是空的:要写成 magicBackendApi.类名.方法名(参数)");
|
|
128
128
|
if (!f || typeof f != "object" || Array.isArray(f)) throw new Error(`magicBackendApi.${d}(params) 的参数要么是一个对象,要么是一个文件(File / Blob)`);
|
|
129
129
|
return await Nt(e.uuid, d, f);
|
|
130
130
|
}
|
|
131
|
-
throw new Error(`不认识的方法:${String(
|
|
131
|
+
throw new Error(`不认识的方法:${String(u)}(这块桥只有 getMe / navigateTab / backend 三个)`);
|
|
132
132
|
}
|
|
133
|
-
const l = (
|
|
134
|
-
if (
|
|
135
|
-
const
|
|
136
|
-
if (!
|
|
137
|
-
if (
|
|
138
|
-
const f = typeof
|
|
133
|
+
const l = (u) => {
|
|
134
|
+
if (u.source !== t.contentWindow) return;
|
|
135
|
+
const c = u.data;
|
|
136
|
+
if (!c) return;
|
|
137
|
+
if (c[q] === it) {
|
|
138
|
+
const f = typeof c.height == "number" ? c.height : NaN;
|
|
139
139
|
Number.isFinite(f) && f > 0 && e.onHeight?.(f);
|
|
140
140
|
return;
|
|
141
141
|
}
|
|
142
|
-
if (
|
|
143
|
-
const d =
|
|
142
|
+
if (c[q] !== st) return;
|
|
143
|
+
const d = c.id;
|
|
144
144
|
(async () => {
|
|
145
145
|
try {
|
|
146
|
-
n({ [
|
|
146
|
+
n({ [q]: Pe, id: d, ok: !0, value: await s(String(c.method), c.args ?? []) });
|
|
147
147
|
} catch (f) {
|
|
148
|
-
n({ [
|
|
148
|
+
n({ [q]: Pe, id: d, ok: !1, error: f instanceof Error ? f.message : String(f) });
|
|
149
149
|
}
|
|
150
150
|
})();
|
|
151
151
|
};
|
|
152
152
|
window.addEventListener("message", l);
|
|
153
|
-
const r = () => n({ [
|
|
153
|
+
const r = () => n({ [q]: at });
|
|
154
154
|
return r(), t.addEventListener("load", r), () => {
|
|
155
155
|
window.removeEventListener("message", l), t.removeEventListener("load", r);
|
|
156
156
|
};
|
|
@@ -169,16 +169,16 @@ function Dt(t) {
|
|
|
169
169
|
}
|
|
170
170
|
const Ft = /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)>\s*<\/script\s*>/gi, Ht = /<link\b([^>]*?)\bhref\s*=\s*(["'])(.*?)\2([^>]*?)\/?>/gi;
|
|
171
171
|
function Kt(t, e) {
|
|
172
|
-
const n = [], s = (
|
|
173
|
-
return { html: t.replace(Ft, (
|
|
172
|
+
const n = [], s = (u) => (n.push(u), Dt(n.length - 1));
|
|
173
|
+
return { html: t.replace(Ft, (u, c, d, f, _) => {
|
|
174
174
|
const y = Ue(f, e);
|
|
175
|
-
return y === void 0 ?
|
|
175
|
+
return y === void 0 ? u : s(`<script${c}${_}>
|
|
176
176
|
${ut(e[y] ?? "")}
|
|
177
177
|
<\/script>`);
|
|
178
|
-
}).replace(Ht, (
|
|
179
|
-
if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${
|
|
178
|
+
}).replace(Ht, (u, c, d, f, _) => {
|
|
179
|
+
if (!/\brel\s*=\s*(?:"|')?stylesheet/i.test(`${c}${_}`)) return u;
|
|
180
180
|
const y = Ue(f, e);
|
|
181
|
-
return y === void 0 ?
|
|
181
|
+
return y === void 0 ? u : s(`<style>
|
|
182
182
|
${e[y]}
|
|
183
183
|
</style>`);
|
|
184
184
|
}), slots: n };
|
|
@@ -205,17 +205,17 @@ ${e}
|
|
|
205
205
|
function qt(t, e = "") {
|
|
206
206
|
const n = typeof e == "string" ? e : e.bootstrap ?? "", s = typeof e == "string" ? "" : e.css ?? "", l = typeof e == "string" ? "" : e.themeCss ?? "", r = t[rt];
|
|
207
207
|
if (r === void 0) return "";
|
|
208
|
-
const { html:
|
|
208
|
+
const { html: u, slots: c } = Kt(r, t), d = Ut(qe(qe(u, l), s), n), f = d.split(ct);
|
|
209
209
|
if (f.length === 1) return d;
|
|
210
210
|
let _ = f[0] ?? "";
|
|
211
211
|
for (let y = 1; y < f.length; y += 1) {
|
|
212
|
-
const S = f[y] ?? "",
|
|
213
|
-
_ += (
|
|
212
|
+
const S = f[y] ?? "", B = S.indexOf("\0"), L = Number(S.slice(0, B));
|
|
213
|
+
_ += (c[L] ?? "") + S.slice(B + 1);
|
|
214
214
|
}
|
|
215
215
|
return _;
|
|
216
216
|
}
|
|
217
|
-
const
|
|
218
|
-
let
|
|
217
|
+
const ge = /* @__PURE__ */ new Map();
|
|
218
|
+
let de = null;
|
|
219
219
|
const Re = /* @__PURE__ */ new Set();
|
|
220
220
|
function Gt(t) {
|
|
221
221
|
return Re.add(t), () => {
|
|
@@ -223,26 +223,26 @@ function Gt(t) {
|
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
225
|
function Jt() {
|
|
226
|
-
|
|
226
|
+
ge.clear(), de = null;
|
|
227
227
|
for (const t of Re) t();
|
|
228
228
|
}
|
|
229
229
|
async function Vt(t) {
|
|
230
230
|
const e = [...new Set(t)].filter(Boolean);
|
|
231
|
-
if (e.some((n) => !
|
|
232
|
-
|
|
231
|
+
if (e.some((n) => !ge.has(n))) {
|
|
232
|
+
de && await de.catch(() => {
|
|
233
233
|
});
|
|
234
|
-
const n = e.filter((s) => !
|
|
235
|
-
n.length > 0 && (
|
|
236
|
-
for (const l of s) l?.id &&
|
|
234
|
+
const n = e.filter((s) => !ge.has(s));
|
|
235
|
+
n.length > 0 && (de = V(`/magic-blocks/render?ids=${n.map(encodeURIComponent).join(",")}`).then((s) => {
|
|
236
|
+
for (const l of s) l?.id && ge.set(l.id, l);
|
|
237
237
|
return s;
|
|
238
238
|
}).catch(() => []).finally(() => {
|
|
239
|
-
|
|
240
|
-
}), await
|
|
239
|
+
de = null;
|
|
240
|
+
}), await de.catch(() => {
|
|
241
241
|
}));
|
|
242
242
|
}
|
|
243
|
-
return e.map((n) =>
|
|
243
|
+
return e.map((n) => ge.get(n)).filter((n) => !!n);
|
|
244
244
|
}
|
|
245
|
-
const
|
|
245
|
+
const pe = "labull.css", je = "CONTROLS.lock.html";
|
|
246
246
|
function Yt(t, e) {
|
|
247
247
|
const n = String(e || "");
|
|
248
248
|
if (/@font-face|@keyframes/i.test(n)) return !0;
|
|
@@ -251,36 +251,36 @@ function Yt(t, e) {
|
|
|
251
251
|
}
|
|
252
252
|
function pt(t, e, n) {
|
|
253
253
|
for (let s = 0; s < t.length; s += 1) {
|
|
254
|
-
const l = t[s], r = String(l.cssText || ""),
|
|
254
|
+
const l = t[s], r = String(l.cssText || ""), u = String(l.selectorText || "");
|
|
255
255
|
if (l.cssRules && l.cssRules.length > 0) {
|
|
256
|
-
const
|
|
257
|
-
if (pt(l.cssRules,
|
|
256
|
+
const c = [];
|
|
257
|
+
if (pt(l.cssRules, c, n), c.length === 0) continue;
|
|
258
258
|
const d = r.slice(0, r.indexOf("{")).trim();
|
|
259
259
|
e.push(`${d} {
|
|
260
|
-
${
|
|
260
|
+
${c.map((f) => " " + f).join(`
|
|
261
261
|
`)}
|
|
262
262
|
}`);
|
|
263
263
|
continue;
|
|
264
264
|
}
|
|
265
|
-
Yt(
|
|
265
|
+
Yt(u, r) && (e.push(r), n.n += 1);
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
function ft() {
|
|
269
269
|
const t = [], e = [], n = { n: 0 };
|
|
270
270
|
let s = 0;
|
|
271
271
|
const l = typeof document > "u" ? [] : Array.from(document.styleSheets);
|
|
272
|
-
for (const
|
|
273
|
-
const
|
|
272
|
+
for (const u of l) {
|
|
273
|
+
const c = u.href || "(内联 <style>)";
|
|
274
274
|
let d = null;
|
|
275
275
|
try {
|
|
276
|
-
d =
|
|
276
|
+
d = u.cssRules;
|
|
277
277
|
} catch {
|
|
278
|
-
e.push(
|
|
278
|
+
e.push(c);
|
|
279
279
|
continue;
|
|
280
280
|
}
|
|
281
281
|
if (!d || d.length === 0) continue;
|
|
282
282
|
const f = [];
|
|
283
|
-
pt(d, f, n), f.length !== 0 && (s += 1, t.push(`/* ── ${
|
|
283
|
+
pt(d, f, n), f.length !== 0 && (s += 1, t.push(`/* ── ${c} ── */`, ...f));
|
|
284
284
|
}
|
|
285
285
|
return { css: [
|
|
286
286
|
"/* 生成物:每次导出都会重写,别手改。",
|
|
@@ -335,7 +335,7 @@ function Wt() {
|
|
|
335
335
|
<head>
|
|
336
336
|
<meta charset="utf-8">
|
|
337
337
|
<title>labull 控件清单</title>
|
|
338
|
-
<link rel="stylesheet" href="${
|
|
338
|
+
<link rel="stylesheet" href="${pe}">
|
|
339
339
|
<style>
|
|
340
340
|
body { margin: 0; padding: 16px; }
|
|
341
341
|
h1 { margin: 0 0 4px; font-size: 18px; }
|
|
@@ -351,10 +351,10 @@ function Wt() {
|
|
|
351
351
|
<body>
|
|
352
352
|
<h1>labull 控件清单</h1>
|
|
353
353
|
<p class="lead">
|
|
354
|
-
这些类名来自 <code>${
|
|
354
|
+
这些类名来自 <code>${pe}</code>(与应用同源同版本)。块里别自己写一套配色 / 按钮:
|
|
355
355
|
把这一行加进 <code>index.open.html</code> 的 <code><head></code>,
|
|
356
356
|
下面每一块 markup 都能直接用:
|
|
357
|
-
<code><link rel="stylesheet" href="${
|
|
357
|
+
<code><link rel="stylesheet" href="${pe}"></code>
|
|
358
358
|
<br />
|
|
359
359
|
⚠️ 这里**只有 CSS,没有 JS 组件**:下拉 / 日期 / 弹窗那些要装了 PrimeVue 才有行为(块里没有构建步骤)。
|
|
360
360
|
</p>
|
|
@@ -363,8 +363,8 @@ ${n}
|
|
|
363
363
|
</html>
|
|
364
364
|
`;
|
|
365
365
|
}
|
|
366
|
-
const
|
|
367
|
-
let Ie = "",
|
|
366
|
+
const ie = /* @__PURE__ */ new Map(), Ne = /* @__PURE__ */ new Set(), Zt = 4e3;
|
|
367
|
+
let Ie = "", we = null;
|
|
368
368
|
function Ge() {
|
|
369
369
|
for (const t of Ne) t();
|
|
370
370
|
}
|
|
@@ -373,46 +373,49 @@ function Xt(t) {
|
|
|
373
373
|
Ne.delete(t);
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
|
-
function
|
|
376
|
+
function $e() {
|
|
377
377
|
return Ie;
|
|
378
378
|
}
|
|
379
379
|
function Qt(t, e) {
|
|
380
380
|
const n = String(t || "").trim(), s = String(e || "").trim();
|
|
381
381
|
if (!n || !s) return () => {
|
|
382
382
|
};
|
|
383
|
-
let l =
|
|
384
|
-
return l || (l = /* @__PURE__ */ new Set(),
|
|
385
|
-
const r =
|
|
386
|
-
r && (r.delete(s), r.size === 0 &&
|
|
383
|
+
let l = ie.get(n);
|
|
384
|
+
return l || (l = /* @__PURE__ */ new Set(), ie.set(n, l)), l.add(s), () => {
|
|
385
|
+
const r = ie.get(n);
|
|
386
|
+
r && (r.delete(s), r.size === 0 && ie.delete(n));
|
|
387
387
|
};
|
|
388
388
|
}
|
|
389
389
|
function Le(t, e) {
|
|
390
|
-
const n =
|
|
390
|
+
const n = ie.get(String(t || ""));
|
|
391
391
|
if (!n) return null;
|
|
392
392
|
for (const s of n)
|
|
393
393
|
if (s !== e) return s;
|
|
394
394
|
return null;
|
|
395
395
|
}
|
|
396
396
|
function en(t) {
|
|
397
|
-
return [...
|
|
397
|
+
return [...ie.get(String(t || "")) ?? []];
|
|
398
398
|
}
|
|
399
399
|
function tn(t, e) {
|
|
400
|
-
const n =
|
|
400
|
+
const n = ie.get(String(t || ""));
|
|
401
401
|
return !n || n.size === 0 || n.has(e) ? null : Le(t, e);
|
|
402
402
|
}
|
|
403
403
|
function mt(t, e = Zt) {
|
|
404
|
-
Ie = String(t || ""),
|
|
405
|
-
|
|
404
|
+
Ie = String(t || ""), we !== null && clearTimeout(we), we = setTimeout(() => {
|
|
405
|
+
we = null, Ie = "", Ge();
|
|
406
406
|
}, Math.max(1, e)), Ge();
|
|
407
407
|
}
|
|
408
408
|
const nn = ["data-magic-block", "data-magic-module"], on = ["srcdoc", "title", "scrolling"], sn = { class: "mb__state" }, an = { class: "mb__brief" }, ln = {
|
|
409
409
|
key: 0,
|
|
410
410
|
class: "mb__reason"
|
|
411
411
|
}, rn = {
|
|
412
|
+
key: 1,
|
|
413
|
+
class: "mb__issues"
|
|
414
|
+
}, cn = {
|
|
412
415
|
key: 2,
|
|
413
416
|
class: "mb__ring",
|
|
414
417
|
"aria-hidden": "true"
|
|
415
|
-
},
|
|
418
|
+
}, un = ["title", "aria-label"], dn = ["title", "aria-label"], pn = ["title", "aria-label"], fn = ["title", "aria-label"], mn = /* @__PURE__ */ We({
|
|
416
419
|
__name: "MagicBlockHost",
|
|
417
420
|
props: {
|
|
418
421
|
uuid: {},
|
|
@@ -426,74 +429,74 @@ const nn = ["data-magic-block", "data-magic-module"], on = ["srcdoc", "title", "
|
|
|
426
429
|
theme: { type: Boolean, default: !0 }
|
|
427
430
|
},
|
|
428
431
|
setup(t) {
|
|
429
|
-
const e = t, n = et(), s = tt(), { isStaff: l } = nt(), r = w(null),
|
|
430
|
-
let y = null, S = null,
|
|
431
|
-
const
|
|
432
|
-
const m =
|
|
432
|
+
const e = t, n = et(), s = tt(), { isStaff: l } = nt(), r = w(null), u = w(null), c = w(null), d = w(!1), f = w(0), _ = w(0);
|
|
433
|
+
let y = null, S = null, B = null, L = null, Y = null, A = null;
|
|
434
|
+
const T = (m) => typeof m == "number" ? `${m}rem` : m ?? "", U = C(() => e.name.trim() || e.uuid), N = C(() => c.value?.state ?? ""), z = C(() => N.value === "invalid" ? "校验不通过" : N.value === "draft" ? "未开发" : U.value), le = C(() => (c.value?.brief ?? "").trim() || (c.value?.name ?? "").trim() || U.value), G = C(() => (c.value?.reason ?? "").trim()), W = C(() => c.value?.issues ?? []), M = C(() => e.flexible && !e.fullSize && f.value > 0), E = C(() => {
|
|
435
|
+
const m = T(e.height);
|
|
433
436
|
if (!m || typeof document > "u") return 0;
|
|
434
437
|
const k = document.createElement("div");
|
|
435
438
|
k.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;height:${m}`, (r.value ?? document.body).appendChild(k);
|
|
436
|
-
const
|
|
437
|
-
return k.remove(),
|
|
438
|
-
}),
|
|
439
|
-
const m = { "--mb-width":
|
|
440
|
-
return e.fullSize ? { ...m, height: `${
|
|
441
|
-
}),
|
|
439
|
+
const I = parseFloat(getComputedStyle(k).height) || 0;
|
|
440
|
+
return k.remove(), I;
|
|
441
|
+
}), Ee = C(() => Math.max(_.value, f.value, E.value, 1)), H = C(() => {
|
|
442
|
+
const m = { "--mb-width": T(e.width) || (e.responsive ? "100%" : "auto"), "--mb-height": T(e.height) || "12rem" };
|
|
443
|
+
return e.fullSize ? { ...m, height: `${Ee.value}px`, flexShrink: "0" } : M.value ? { ...m, height: `${f.value}px`, flexGrow: "0" } : m;
|
|
444
|
+
}), Z = C(() => {
|
|
442
445
|
const m = {};
|
|
443
|
-
for (const [k,
|
|
446
|
+
for (const [k, I] of Object.entries(c.value?.files ?? {})) k !== Lt && (m[k] = I);
|
|
444
447
|
return m;
|
|
445
|
-
}),
|
|
446
|
-
let
|
|
447
|
-
function
|
|
448
|
+
}), re = C(() => N.value === "ok" && typeof Z.value[rt] == "string");
|
|
449
|
+
let K = null;
|
|
450
|
+
function ce() {
|
|
448
451
|
if (!e.theme) return "";
|
|
449
|
-
if (
|
|
452
|
+
if (K !== null || (K = "", typeof document > "u")) return K;
|
|
450
453
|
try {
|
|
451
|
-
|
|
454
|
+
K = ft().css;
|
|
452
455
|
} catch {
|
|
453
|
-
|
|
456
|
+
K = "";
|
|
454
457
|
}
|
|
455
|
-
return
|
|
458
|
+
return K;
|
|
456
459
|
}
|
|
457
|
-
const
|
|
458
|
-
if (!
|
|
460
|
+
const ye = C(() => {
|
|
461
|
+
if (!re.value) return "";
|
|
459
462
|
const m = { bootstrap: Rt };
|
|
460
463
|
e.fullSize && (m.css = Pt);
|
|
461
|
-
const k =
|
|
462
|
-
return k && (m.themeCss = k), qt(
|
|
464
|
+
const k = ce();
|
|
465
|
+
return k && (m.themeCss = k), qt(Z.value, m);
|
|
463
466
|
});
|
|
464
|
-
async function
|
|
465
|
-
const k = s.getRoutes().map((
|
|
467
|
+
async function Ce(m) {
|
|
468
|
+
const k = s.getRoutes().map((I) => I.path);
|
|
466
469
|
if (!k.includes(m)) throw new Error(`这个应用里没有页面 ${m}。能跳的页面只有:${k.length > 0 ? k.join(" / ") : "(还没有配路由)"}`);
|
|
467
470
|
return await s.push(m), s.currentRoute.value.fullPath || m;
|
|
468
471
|
}
|
|
469
|
-
function
|
|
470
|
-
|
|
471
|
-
const m =
|
|
472
|
-
m && (
|
|
472
|
+
function _e() {
|
|
473
|
+
B?.(), B = null;
|
|
474
|
+
const m = u.value;
|
|
475
|
+
m && (B = It(m, { uuid: e.uuid, onHeight: (k) => {
|
|
473
476
|
f.value = k;
|
|
474
|
-
}, onNavigateTab:
|
|
477
|
+
}, onNavigateTab: Ce }));
|
|
475
478
|
}
|
|
476
|
-
async function
|
|
479
|
+
async function fe() {
|
|
477
480
|
const m = e.uuid, k = await Vt([m]);
|
|
478
|
-
m === e.uuid && (
|
|
481
|
+
m === e.uuid && (c.value = k.find((I) => I.id === m) ?? null);
|
|
479
482
|
}
|
|
480
|
-
function
|
|
483
|
+
function ke() {
|
|
481
484
|
window.dispatchEvent(new CustomEvent("magic-block:open-console", { detail: { uuid: e.uuid } }));
|
|
482
485
|
}
|
|
483
|
-
function
|
|
484
|
-
m &&
|
|
486
|
+
function me(m = !1) {
|
|
487
|
+
m && Y?.(), Y = Qt(e.uuid, n.path);
|
|
485
488
|
}
|
|
486
|
-
const
|
|
489
|
+
const R = C(() => {
|
|
487
490
|
if (!l.value) return "";
|
|
488
491
|
const m = Le(e.uuid, n.path);
|
|
489
492
|
return m ? `管理员:跳到还挂着这个块的页面 ${m}(点一下这一块会亮红框)` : "管理员:这个块只在本页挂着 —— 点一下会亮几秒红框";
|
|
490
493
|
});
|
|
491
|
-
function
|
|
494
|
+
function ee() {
|
|
492
495
|
if (!l.value) return;
|
|
493
496
|
const m = Le(e.uuid, n.path);
|
|
494
497
|
mt(e.uuid), m && s.push(m);
|
|
495
498
|
}
|
|
496
|
-
function
|
|
499
|
+
function te(m) {
|
|
497
500
|
let k = m.parentElement;
|
|
498
501
|
for (; k; ) {
|
|
499
502
|
if (getComputedStyle(k).overflowY !== "visible" && k.clientHeight > 0) return k;
|
|
@@ -501,112 +504,118 @@ const nn = ["data-magic-block", "data-magic-module"], on = ["srcdoc", "title", "
|
|
|
501
504
|
}
|
|
502
505
|
return document.documentElement;
|
|
503
506
|
}
|
|
504
|
-
function
|
|
507
|
+
function ne() {
|
|
505
508
|
const m = r.value;
|
|
506
509
|
if (!m) return 0;
|
|
507
|
-
const k =
|
|
508
|
-
return Math.max(0, Math.floor(Math.max(
|
|
510
|
+
const k = te(m), I = k === document.documentElement ? window.innerHeight : k.clientHeight, se = k === document.documentElement ? window.innerHeight : k.getBoundingClientRect().top + k.clientHeight;
|
|
511
|
+
return Math.max(0, Math.floor(Math.max(se - m.getBoundingClientRect().top, I)));
|
|
509
512
|
}
|
|
510
|
-
function
|
|
513
|
+
function D() {
|
|
511
514
|
if (!e.fullSize || !r.value) return;
|
|
512
|
-
const m =
|
|
515
|
+
const m = ne();
|
|
513
516
|
m > 0 && Math.abs(m - _.value) > 1 && (_.value = m);
|
|
514
517
|
}
|
|
515
|
-
function
|
|
518
|
+
function oe() {
|
|
516
519
|
if (!e.fullSize || !r.value) {
|
|
517
520
|
S?.disconnect(), S = null, y = null;
|
|
518
521
|
return;
|
|
519
522
|
}
|
|
520
|
-
const m =
|
|
521
|
-
y !== m && (y = m, S?.disconnect(), S = null),
|
|
523
|
+
const m = te(r.value);
|
|
524
|
+
y !== m && (y = m, S?.disconnect(), S = null), D(), !(S || typeof ResizeObserver > "u") && (S = new ResizeObserver(() => D()), S.observe(m));
|
|
522
525
|
}
|
|
523
|
-
return
|
|
524
|
-
f.value = 0, _.value = 0,
|
|
525
|
-
}, { flush: "post" }),
|
|
526
|
-
Et().then(() =>
|
|
527
|
-
}),
|
|
526
|
+
return he(u, () => _e()), he(ye, () => {
|
|
527
|
+
f.value = 0, _.value = 0, oe();
|
|
528
|
+
}, { flush: "post" }), he(() => [e.fullSize, e.height, e.uuid], () => {
|
|
529
|
+
Et().then(() => oe());
|
|
530
|
+
}), he(d, (m) => {
|
|
528
531
|
if (!m) return;
|
|
529
532
|
const k = r.value;
|
|
530
533
|
!k || !k.isConnected || k.offsetParent === null || k.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
531
|
-
}),
|
|
532
|
-
f.value = 0,
|
|
534
|
+
}), he(() => e.uuid, () => {
|
|
535
|
+
f.value = 0, c.value = null, me(!0), d.value = $e() === e.uuid, fe();
|
|
533
536
|
}), Ze(() => {
|
|
534
|
-
|
|
535
|
-
d.value =
|
|
536
|
-
}), d.value =
|
|
537
|
+
L = Gt(() => void fe()), A = Xt(() => {
|
|
538
|
+
d.value = $e() === e.uuid;
|
|
539
|
+
}), d.value = $e() === e.uuid, me(), oe(), fe();
|
|
537
540
|
}), Ct(() => {
|
|
538
|
-
|
|
541
|
+
me(!0), d.value = $e() === e.uuid, oe();
|
|
539
542
|
}), Xe(() => {
|
|
540
|
-
S?.disconnect(), S = null,
|
|
541
|
-
}), (m, k) => (
|
|
543
|
+
S?.disconnect(), S = null, L?.(), L = null, A?.(), A = null, Y?.(), Y = null, B?.(), B = null;
|
|
544
|
+
}), (m, k) => (h(), b("div", {
|
|
542
545
|
ref_key: "el",
|
|
543
546
|
ref: r,
|
|
544
|
-
class:
|
|
545
|
-
style: Qe(
|
|
547
|
+
class: J(["mb", { "mb--responsive": t.responsive, "mb--full": t.fullSize, "mb--admin": be(l), "mb--lit": be(l) && d.value }]),
|
|
548
|
+
style: Qe(H.value),
|
|
546
549
|
"data-magic-block": t.uuid,
|
|
547
550
|
"data-magic-module": t.module
|
|
548
551
|
}, [
|
|
549
|
-
|
|
552
|
+
re.value ? (h(), b("iframe", {
|
|
550
553
|
key: 0,
|
|
551
554
|
ref_key: "frame",
|
|
552
|
-
ref:
|
|
555
|
+
ref: u,
|
|
553
556
|
class: "mb__frame",
|
|
554
|
-
srcdoc:
|
|
555
|
-
title:
|
|
557
|
+
srcdoc: ye.value,
|
|
558
|
+
title: U.value,
|
|
556
559
|
scrolling: t.fullSize ? "no" : void 0,
|
|
557
560
|
sandbox: "allow-scripts allow-forms allow-modals allow-popups allow-downloads"
|
|
558
|
-
}, null, 8, on)) : (
|
|
561
|
+
}, null, 8, on)) : (h(), b("div", {
|
|
559
562
|
key: 1,
|
|
560
|
-
class:
|
|
561
|
-
onClick:
|
|
563
|
+
class: J(["mb__empty", { "mb__empty--off": N.value === "invalid", "mb__empty--draft": N.value === "draft" }]),
|
|
564
|
+
onClick: ee
|
|
562
565
|
}, [
|
|
563
|
-
p("p", sn,
|
|
564
|
-
p("p", an,
|
|
565
|
-
|
|
566
|
+
p("p", sn, v(z.value), 1),
|
|
567
|
+
p("p", an, v(le.value), 1),
|
|
568
|
+
N.value === "invalid" && G.value ? (h(), b("p", ln, v(G.value), 1)) : x("", !0),
|
|
569
|
+
N.value === "invalid" && W.value.length > 0 ? (h(), b("ul", rn, [
|
|
570
|
+
(h(!0), b(j, null, Q(W.value, (I, se) => (h(), b("li", {
|
|
571
|
+
key: se,
|
|
572
|
+
class: "mb__issue"
|
|
573
|
+
}, v(I.message), 1))), 128))
|
|
574
|
+
])) : x("", !0),
|
|
566
575
|
p("button", {
|
|
567
576
|
class: "mb__go",
|
|
568
577
|
type: "button",
|
|
569
|
-
onClick: Bt(
|
|
578
|
+
onClick: Bt(ke, ["stop"])
|
|
570
579
|
}, "去控制台")
|
|
571
580
|
], 2)),
|
|
572
|
-
|
|
573
|
-
|
|
581
|
+
be(l) ? (h(), b("span", cn)) : x("", !0),
|
|
582
|
+
be(l) && re.value ? (h(), b(j, { key: 3 }, [
|
|
574
583
|
p("button", {
|
|
575
584
|
class: "mb__grab mb__grab--top",
|
|
576
585
|
type: "button",
|
|
577
|
-
title:
|
|
578
|
-
"aria-label":
|
|
579
|
-
onClick:
|
|
580
|
-
}, null, 8,
|
|
586
|
+
title: R.value,
|
|
587
|
+
"aria-label": R.value,
|
|
588
|
+
onClick: ee
|
|
589
|
+
}, null, 8, un),
|
|
581
590
|
p("button", {
|
|
582
591
|
class: "mb__grab mb__grab--right",
|
|
583
592
|
type: "button",
|
|
584
|
-
title:
|
|
585
|
-
"aria-label":
|
|
586
|
-
onClick:
|
|
587
|
-
}, null, 8,
|
|
593
|
+
title: R.value,
|
|
594
|
+
"aria-label": R.value,
|
|
595
|
+
onClick: ee
|
|
596
|
+
}, null, 8, dn),
|
|
588
597
|
p("button", {
|
|
589
598
|
class: "mb__grab mb__grab--bottom",
|
|
590
599
|
type: "button",
|
|
591
|
-
title:
|
|
592
|
-
"aria-label":
|
|
593
|
-
onClick:
|
|
594
|
-
}, null, 8,
|
|
600
|
+
title: R.value,
|
|
601
|
+
"aria-label": R.value,
|
|
602
|
+
onClick: ee
|
|
603
|
+
}, null, 8, pn),
|
|
595
604
|
p("button", {
|
|
596
605
|
class: "mb__grab mb__grab--left",
|
|
597
606
|
type: "button",
|
|
598
|
-
title:
|
|
599
|
-
"aria-label":
|
|
600
|
-
onClick:
|
|
601
|
-
}, null, 8,
|
|
607
|
+
title: R.value,
|
|
608
|
+
"aria-label": R.value,
|
|
609
|
+
onClick: ee
|
|
610
|
+
}, null, 8, fn)
|
|
602
611
|
], 64)) : x("", !0)
|
|
603
612
|
], 14, nn));
|
|
604
613
|
}
|
|
605
|
-
}),
|
|
606
|
-
function
|
|
614
|
+
}), ns = /* @__PURE__ */ ot(mn, [["__scopeId", "data-v-e40128e9"]]), Be = "index.open.html", Te = "magic-block.open.yaml", xe = ["id", "module", "name", "brief"], ze = 40, hn = /^(?![A-Za-z]:)(?!\/)[A-Za-z0-9._\-/]+$/, bn = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, gn = /^[a-z][a-z0-9]*$/, vn = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
615
|
+
function yn(t) {
|
|
607
616
|
return t.length > 0 && t.length <= ze && !/[\u0000-\u001f\u007f]/.test(t);
|
|
608
617
|
}
|
|
609
|
-
const
|
|
618
|
+
const _n = {
|
|
610
619
|
id: "块的 uuid,必须与页面里挂载它时写死的那个 uuid 逐字一致",
|
|
611
620
|
module: "模块名(小写字母与数字,必须以字母开头),例如 home",
|
|
612
621
|
name: `可读名:可以用中文,不超过 ${ze} 个字符`,
|
|
@@ -616,7 +625,7 @@ function Je(t) {
|
|
|
616
625
|
const e = Object.keys(t);
|
|
617
626
|
return e.length > 0 ? `现在包里有:${e.join(" / ")}` : "现在这个包是空的";
|
|
618
627
|
}
|
|
619
|
-
function
|
|
628
|
+
function kn(t) {
|
|
620
629
|
let e = "";
|
|
621
630
|
for (let n = 0; n < t.length; n += 1) {
|
|
622
631
|
const s = t[n];
|
|
@@ -627,7 +636,7 @@ function _n(t) {
|
|
|
627
636
|
}
|
|
628
637
|
return t;
|
|
629
638
|
}
|
|
630
|
-
function
|
|
639
|
+
function wn(t) {
|
|
631
640
|
let e = "";
|
|
632
641
|
for (let n = 0; n < t.length; n += 1) {
|
|
633
642
|
const s = t[n];
|
|
@@ -638,54 +647,54 @@ function kn(t) {
|
|
|
638
647
|
}
|
|
639
648
|
return -1;
|
|
640
649
|
}
|
|
641
|
-
function
|
|
650
|
+
function $n(t) {
|
|
642
651
|
return !t || t[0] !== '"' && t[0] !== "'" ? t : t.length >= 2 && t[t.length - 1] === t[0] ? t.slice(1, -1).trim() : t;
|
|
643
652
|
}
|
|
644
|
-
function
|
|
653
|
+
function xn(t) {
|
|
645
654
|
const e = [], n = {}, s = {};
|
|
646
655
|
t.split(/\r?\n/).forEach((l, r) => {
|
|
647
|
-
const
|
|
648
|
-
if (!
|
|
649
|
-
if (
|
|
650
|
-
e.push(`第 ${
|
|
656
|
+
const u = r + 1, c = kn(l).trim();
|
|
657
|
+
if (!c) return;
|
|
658
|
+
if (c.startsWith("-")) {
|
|
659
|
+
e.push(`第 ${u} 行是列表写法(${c}):清单只认「键: 值」,四个键各占一行 —— 例如 name: 客户档案`);
|
|
651
660
|
return;
|
|
652
661
|
}
|
|
653
|
-
const d =
|
|
662
|
+
const d = wn(c);
|
|
654
663
|
if (d < 0) {
|
|
655
|
-
e.push(`第 ${
|
|
664
|
+
e.push(`第 ${u} 行不是「键: 值」(${c}):清单只认「键: 值」与 # 注释 —— 要么删掉这一行,要么照 name: 客户档案 写`);
|
|
656
665
|
return;
|
|
657
666
|
}
|
|
658
|
-
const f =
|
|
659
|
-
if (!
|
|
660
|
-
e.push(`第 ${
|
|
667
|
+
const f = c.slice(0, d).trim();
|
|
668
|
+
if (!vn.test(f)) {
|
|
669
|
+
e.push(`第 ${u} 行的键名不合法(${f}):键名只许字母或下划线开头,认得的键只有 ${xe.join(" / ")}`);
|
|
661
670
|
return;
|
|
662
671
|
}
|
|
663
|
-
if (!
|
|
664
|
-
e.push(`第 ${
|
|
672
|
+
if (!xe.includes(f)) {
|
|
673
|
+
e.push(`第 ${u} 行的键不认识(${f}):清单只有 ${xe.join(" / ")} 这四个键`);
|
|
665
674
|
return;
|
|
666
675
|
}
|
|
667
676
|
if (f in s) {
|
|
668
|
-
e.push(`第 ${
|
|
677
|
+
e.push(`第 ${u} 行重复写了 ${f}(第 ${s[f]} 行已经写过):一个键只许出现一次`);
|
|
669
678
|
return;
|
|
670
679
|
}
|
|
671
|
-
s[f] =
|
|
680
|
+
s[f] = u, n[f] = $n(c.slice(d + 1).trim());
|
|
672
681
|
});
|
|
673
|
-
for (const l of
|
|
682
|
+
for (const l of xe) {
|
|
674
683
|
const r = n[l] ?? "";
|
|
675
684
|
if (r === "") {
|
|
676
|
-
e.push(`清单里缺少 ${l}(或者是空的):${
|
|
685
|
+
e.push(`清单里缺少 ${l}(或者是空的):${_n[l]}`);
|
|
677
686
|
continue;
|
|
678
687
|
}
|
|
679
|
-
l === "id" && !
|
|
688
|
+
l === "id" && !bn.test(r) ? e.push(`清单里的 id 不是 uuid:${r} —— 要 8-4-4-4-12 那种十六进制`) : l === "module" && !gn.test(r) ? e.push(
|
|
680
689
|
`清单里的 module 不合法:${r} —— 它同时是 Django 的 app label,所以只许小写字母与数字、必须以字母开头(不能有横线与下划线),例如 home / orders`
|
|
681
|
-
) : l === "name" && !
|
|
690
|
+
) : l === "name" && !yn(r) && e.push(`清单里的 name 不合法:${r} —— 不能超过 ${ze} 个字符、不能含控制字符(中文可以)`);
|
|
682
691
|
}
|
|
683
692
|
return [n, e];
|
|
684
693
|
}
|
|
685
|
-
function xn(t) {
|
|
686
|
-
return mn.test(t) && !t.split("/").includes("..");
|
|
687
|
-
}
|
|
688
694
|
function Sn(t) {
|
|
695
|
+
return hn.test(t) && !t.split("/").includes("..");
|
|
696
|
+
}
|
|
697
|
+
function En(t) {
|
|
689
698
|
const e = [], n = t[Be];
|
|
690
699
|
n === void 0 ? e.push(`包里缺入口:必须有 ${Be}(${Je(t)})`) : n.trim() || e.push(`${Be} 不能是空文件`);
|
|
691
700
|
const s = t[Te];
|
|
@@ -695,31 +704,31 @@ function Sn(t) {
|
|
|
695
704
|
else if (!s.trim())
|
|
696
705
|
e.push(`${Te} 不能是空文件`);
|
|
697
706
|
else {
|
|
698
|
-
const [r,
|
|
699
|
-
l = r, e.push(...
|
|
707
|
+
const [r, u] = xn(s);
|
|
708
|
+
l = r, e.push(...u);
|
|
700
709
|
}
|
|
701
710
|
for (const r of Object.keys(t))
|
|
702
|
-
|
|
711
|
+
Sn(r) || e.push(`文件名不合法:${r}(只许字母数字与 . _ - /,且不许 .. 与绝对路径)`);
|
|
703
712
|
return { manifest: l, issues: e };
|
|
704
713
|
}
|
|
705
|
-
function
|
|
714
|
+
function Cn(t) {
|
|
706
715
|
const e = [];
|
|
707
716
|
if (t.length === 0)
|
|
708
717
|
return e.push("一个块都没勾:请在「读回改动」的结果里勾上要保存的块"), { selected: 0, issues: e };
|
|
709
718
|
for (const n of t) {
|
|
710
719
|
const s = n.name?.trim() || "(没有名字的块)";
|
|
711
|
-
for (const l of
|
|
720
|
+
for (const l of En(n.files ?? {}).issues) e.push(`${s}:${l}`);
|
|
712
721
|
}
|
|
713
722
|
return { selected: t.length, issues: e };
|
|
714
723
|
}
|
|
715
724
|
const Ve = "pages.lock.ts";
|
|
716
|
-
function
|
|
725
|
+
function Bn(t, e) {
|
|
717
726
|
const n = String(t || "").split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
718
727
|
if (n.length === 0) return `Page${e + 1}`;
|
|
719
728
|
const s = n.map((l) => l[0].toUpperCase() + l.slice(1)).join("");
|
|
720
729
|
return /^[0-9]/.test(s) ? `P${s}` : s;
|
|
721
730
|
}
|
|
722
|
-
function
|
|
731
|
+
function Tn(t, e) {
|
|
723
732
|
if (!e.has(t))
|
|
724
733
|
return e.add(t), t;
|
|
725
734
|
let n = 2;
|
|
@@ -727,12 +736,12 @@ function Bn(t, e) {
|
|
|
727
736
|
const s = `${t}${n}`;
|
|
728
737
|
return e.add(s), s;
|
|
729
738
|
}
|
|
730
|
-
function
|
|
739
|
+
function An(t) {
|
|
731
740
|
const e = (t ?? []).filter((r) => r && typeof r.path == "string" && r.path.trim() !== ""), n = /* @__PURE__ */ new Set(), s = [];
|
|
732
|
-
e.forEach((r,
|
|
733
|
-
const
|
|
734
|
-
let d = s.find((f) => f.title ===
|
|
735
|
-
d || (d = { title:
|
|
741
|
+
e.forEach((r, u) => {
|
|
742
|
+
const c = r.group?.trim() || "(没写 meta.group)";
|
|
743
|
+
let d = s.find((f) => f.title === c);
|
|
744
|
+
d || (d = { title: c, rows: [] }, s.push(d)), d.rows.push({ key: Tn(Bn(r.path, u), n), row: r });
|
|
736
745
|
});
|
|
737
746
|
const l = [
|
|
738
747
|
"/* 生成物:**每次导出都会重写**,别手改 —— 改了下次导出就没了。",
|
|
@@ -758,8 +767,8 @@ function Tn(t) {
|
|
|
758
767
|
l.push("export const Page = {");
|
|
759
768
|
for (const r of s) {
|
|
760
769
|
l.push(` // ── ${r.title} ──`);
|
|
761
|
-
for (const
|
|
762
|
-
l.push(` /** ${
|
|
770
|
+
for (const u of r.rows)
|
|
771
|
+
l.push(` /** ${u.row.title?.trim() || u.row.path}(${u.row.path}) */`), l.push(` ${u.key}: '${u.row.path}',`);
|
|
763
772
|
}
|
|
764
773
|
l.push("} as const", "");
|
|
765
774
|
}
|
|
@@ -806,78 +815,78 @@ function Tn(t) {
|
|
|
806
815
|
function ht() {
|
|
807
816
|
return typeof window < "u" && typeof window.showDirectoryPicker == "function";
|
|
808
817
|
}
|
|
809
|
-
const
|
|
818
|
+
const On = "这个浏览器没法直接写你本机的文件夹(少了 File System Access API):请用 Chrome / Edge,并且从 https 或 http://localhost 打开这个页面(内网 http 会更少 API)。";
|
|
810
819
|
async function Ae() {
|
|
811
|
-
if (!ht()) throw new Error(
|
|
820
|
+
if (!ht()) throw new Error(On);
|
|
812
821
|
try {
|
|
813
822
|
const t = await window.showDirectoryPicker({ mode: "readwrite", id: "labull-magic-block" });
|
|
814
823
|
return { name: t.name, handle: t };
|
|
815
824
|
} catch (t) {
|
|
816
825
|
const e = t instanceof Error ? t.name : "";
|
|
817
|
-
throw e === "AbortError" ? new Error("取消选目录了:想导出就再点一次「选择文件夹」") : e === "SecurityError" ? new Error(`选不了这个目录:浏览器不让(${
|
|
826
|
+
throw e === "AbortError" ? new Error("取消选目录了:想导出就再点一次「选择文件夹」") : e === "SecurityError" ? new Error(`选不了这个目录:浏览器不让(${Se(t)})—— 换一个目录,或确认页面是 https / localhost`) : new Error(`选目录失败:${Se(t)}`);
|
|
818
827
|
}
|
|
819
828
|
}
|
|
820
|
-
function
|
|
829
|
+
function Se(t) {
|
|
821
830
|
return (t instanceof Error ? t.message.trim() : String(t)) || "没有说原因";
|
|
822
831
|
}
|
|
823
|
-
function
|
|
832
|
+
function Mn(t) {
|
|
824
833
|
const e = String(t ?? "").split("/");
|
|
825
834
|
for (const n of e)
|
|
826
835
|
if (!n || n === "." || n === ".." || n.includes("\\") || /^[A-Za-z]:/.test(n))
|
|
827
836
|
throw new Error(`路径不合法:${t}(要相对路径,不许 .. / 盘符 / 反斜杠)`);
|
|
828
837
|
return e;
|
|
829
838
|
}
|
|
830
|
-
const
|
|
831
|
-
function
|
|
839
|
+
const Pn = 8;
|
|
840
|
+
function Rn(t) {
|
|
832
841
|
const e = /* @__PURE__ */ new Map();
|
|
833
842
|
return (n) => {
|
|
834
843
|
const s = n.join("\0"), l = e.get(s);
|
|
835
844
|
if (l) return l;
|
|
836
845
|
let r = Promise.resolve(t);
|
|
837
|
-
for (let
|
|
838
|
-
const
|
|
839
|
-
r = f ?? r.then((_) => _.getDirectoryHandle(
|
|
846
|
+
for (let u = 0; u < n.length; u += 1) {
|
|
847
|
+
const c = n[u], d = n.slice(0, u + 1).join("\0"), f = e.get(d);
|
|
848
|
+
r = f ?? r.then((_) => _.getDirectoryHandle(c, { create: !0 })), f || e.set(d, r);
|
|
840
849
|
}
|
|
841
850
|
return r;
|
|
842
851
|
};
|
|
843
852
|
}
|
|
844
|
-
async function
|
|
845
|
-
const s = Object.entries(e ?? {}).map(([_, y]) => ({ path: _, parts:
|
|
846
|
-
let
|
|
853
|
+
async function jn(t, e, n) {
|
|
854
|
+
const s = Object.entries(e ?? {}).map(([_, y]) => ({ path: _, parts: Mn(_), body: String(y ?? "") })), l = s.length, r = [], u = Rn(t.handle);
|
|
855
|
+
let c = 0, d = 0;
|
|
847
856
|
n?.(0, l);
|
|
848
857
|
const f = async () => {
|
|
849
858
|
for (; ; ) {
|
|
850
|
-
const _ =
|
|
851
|
-
|
|
859
|
+
const _ = c;
|
|
860
|
+
c += 1;
|
|
852
861
|
const y = s[_];
|
|
853
862
|
if (!y) return;
|
|
854
863
|
try {
|
|
855
|
-
const
|
|
864
|
+
const L = await (await (await u(y.parts.slice(0, -1))).getFileHandle(y.parts[y.parts.length - 1], { create: !0 })).createWritable();
|
|
856
865
|
try {
|
|
857
|
-
await
|
|
866
|
+
await L.write(y.body);
|
|
858
867
|
} finally {
|
|
859
|
-
await
|
|
868
|
+
await L.close();
|
|
860
869
|
}
|
|
861
870
|
d += 1;
|
|
862
871
|
} catch (S) {
|
|
863
|
-
r.push({ path: y.path, message:
|
|
872
|
+
r.push({ path: y.path, message: Se(S) });
|
|
864
873
|
}
|
|
865
874
|
n?.(d + r.length, l);
|
|
866
875
|
}
|
|
867
876
|
};
|
|
868
|
-
return await Promise.all(Array.from({ length: Math.max(1, Math.min(
|
|
877
|
+
return await Promise.all(Array.from({ length: Math.max(1, Math.min(Pn, l)) }, () => f())), r.sort((_, y) => _.path < y.path ? -1 : _.path > y.path ? 1 : 0), { written: d, failed: r, total: l };
|
|
869
878
|
}
|
|
870
|
-
async function
|
|
879
|
+
async function Nn(t, e) {
|
|
871
880
|
const n = { items: [], topCount: 0, files: 0, dirs: 0 }, s = async (l, r) => {
|
|
872
|
-
for (const
|
|
873
|
-
if (
|
|
881
|
+
for (const u of await ve(l)) {
|
|
882
|
+
if (u.kind === "file") {
|
|
874
883
|
n.files += 1;
|
|
875
884
|
continue;
|
|
876
885
|
}
|
|
877
|
-
n.dirs += 1, !(r >= e.maxDepth) && (e.skipDirs.includes(
|
|
886
|
+
n.dirs += 1, !(r >= e.maxDepth) && (e.skipDirs.includes(u.name) || await s(u, r + 1));
|
|
878
887
|
}
|
|
879
888
|
};
|
|
880
|
-
for (const l of await
|
|
889
|
+
for (const l of await ve(t.handle))
|
|
881
890
|
if (n.items.push({ name: l.name, dir: l.kind === "directory" }), l.kind === "file") n.files += 1;
|
|
882
891
|
else {
|
|
883
892
|
if (n.dirs += 1, e.skipDirs.includes(l.name) || e.maxDepth <= 0) continue;
|
|
@@ -885,83 +894,83 @@ async function jn(t, e) {
|
|
|
885
894
|
}
|
|
886
895
|
return n.topCount = n.items.length, n;
|
|
887
896
|
}
|
|
888
|
-
async function
|
|
897
|
+
async function In(t) {
|
|
889
898
|
const e = [];
|
|
890
|
-
for (const s of await
|
|
899
|
+
for (const s of await ve(t.handle)) e.push(s.name);
|
|
891
900
|
let n = 0;
|
|
892
901
|
for (const s of e)
|
|
893
902
|
await t.handle.removeEntry(s, { recursive: !0 }), n += 1;
|
|
894
903
|
return n;
|
|
895
904
|
}
|
|
896
|
-
function
|
|
905
|
+
function Ln(t, e) {
|
|
897
906
|
if (t.name === e.blocksDir)
|
|
898
907
|
throw new Error(
|
|
899
908
|
`你选中的是「${e.blocksDir}」这一层(它就是放代码的那一层):导出会铺成 ${e.blocksDir}/${e.blocksDir}/…。请选它**上面**那一层 —— 也就是开发目录本身。`
|
|
900
909
|
);
|
|
901
910
|
}
|
|
902
|
-
async function
|
|
911
|
+
async function ve(t) {
|
|
903
912
|
const e = [];
|
|
904
913
|
for await (const n of t.values()) e.push(n);
|
|
905
914
|
return e.sort((n, s) => n.name < s.name ? -1 : n.name > s.name ? 1 : 0), e;
|
|
906
915
|
}
|
|
907
|
-
function
|
|
916
|
+
function zn(t) {
|
|
908
917
|
return t.charCodeAt(0) === 65279 ? t.slice(1) : t;
|
|
909
918
|
}
|
|
910
|
-
function
|
|
919
|
+
function Dn(t) {
|
|
911
920
|
const e = t.lastIndexOf(".");
|
|
912
921
|
return e <= 0 ? "" : t.slice(e).toLowerCase();
|
|
913
922
|
}
|
|
914
923
|
async function bt(t, e, n, s) {
|
|
915
924
|
const l = {};
|
|
916
|
-
for (const r of await
|
|
917
|
-
const
|
|
925
|
+
for (const r of await ve(t)) {
|
|
926
|
+
const u = e ? `${e}/${r.name}` : r.name;
|
|
918
927
|
if (r.kind === "directory") {
|
|
919
928
|
if (n.skipDirs.includes(r.name)) continue;
|
|
920
|
-
const
|
|
921
|
-
for (const [d, f] of Object.entries(await bt(
|
|
929
|
+
const c = r;
|
|
930
|
+
for (const [d, f] of Object.entries(await bt(c, u, n, s)))
|
|
922
931
|
l[`${r.name}/${d}`] = f;
|
|
923
932
|
continue;
|
|
924
933
|
}
|
|
925
934
|
if (!n.platformFiles.includes(r.name)) {
|
|
926
|
-
if (!n.textExt.includes(
|
|
935
|
+
if (!n.textExt.includes(Dn(r.name))) {
|
|
927
936
|
s.failures.push({
|
|
928
937
|
kind: "file",
|
|
929
|
-
where:
|
|
938
|
+
where: u,
|
|
930
939
|
message: `不是文本文件(认得的扩展名:${n.textExt.join(" ")}),已跳过`
|
|
931
940
|
});
|
|
932
941
|
continue;
|
|
933
942
|
}
|
|
934
943
|
try {
|
|
935
|
-
const
|
|
936
|
-
if (
|
|
944
|
+
const c = await r.getFile();
|
|
945
|
+
if (c.size > n.maxFileBytes) {
|
|
937
946
|
s.failures.push({
|
|
938
947
|
kind: "file",
|
|
939
|
-
where:
|
|
940
|
-
message: `文件 ${Math.round(
|
|
948
|
+
where: u,
|
|
949
|
+
message: `文件 ${Math.round(c.size / 1024)} KB 超过上限 ${Math.floor(n.maxFileBytes / 1024)} KB,已跳过`
|
|
941
950
|
});
|
|
942
951
|
continue;
|
|
943
952
|
}
|
|
944
|
-
l[r.name] =
|
|
945
|
-
} catch (
|
|
946
|
-
s.failures.push({ kind: "file", where:
|
|
953
|
+
l[r.name] = zn(await c.text());
|
|
954
|
+
} catch (c) {
|
|
955
|
+
s.failures.push({ kind: "file", where: u, message: `读不了这个文件:${Se(c)}` });
|
|
947
956
|
}
|
|
948
957
|
}
|
|
949
958
|
}
|
|
950
959
|
return l;
|
|
951
960
|
}
|
|
952
961
|
async function gt(t, e, n, s, l) {
|
|
953
|
-
const r = await
|
|
954
|
-
if (
|
|
962
|
+
const r = await ve(t), u = r.filter((d) => d.kind === "directory"), c = r.filter((d) => d.kind === "file");
|
|
963
|
+
if (u.length === 0 || c.some((d) => d.name === s.entry)) {
|
|
955
964
|
l.folders.push({ where: e.join("/"), files: await bt(t, e.join("/"), s, l) });
|
|
956
965
|
return;
|
|
957
966
|
}
|
|
958
|
-
for (const d of
|
|
967
|
+
for (const d of c)
|
|
959
968
|
e.length === 0 && s.rootSkipFiles.includes(d.name.toLowerCase()) || l.failures.push({
|
|
960
969
|
kind: "file",
|
|
961
970
|
where: [...e, d.name].join("/"),
|
|
962
971
|
message: `这一层直接放着一份文件,但它自己不是块文件夹、也没有 ${s.entry},文件没有归属`
|
|
963
972
|
});
|
|
964
|
-
for (const d of
|
|
973
|
+
for (const d of u)
|
|
965
974
|
if (!s.skipDirs.includes(d.name)) {
|
|
966
975
|
if (n >= s.maxDepth) {
|
|
967
976
|
l.truncated = !0, l.failures.push({
|
|
@@ -977,11 +986,11 @@ async function gt(t, e, n, s, l) {
|
|
|
977
986
|
function Ye(t) {
|
|
978
987
|
return t >= 1024 * 1024 ? `${(t / 1024 / 1024).toFixed(1)} MB` : `${Math.max(1, Math.round(t / 1024))} KB`;
|
|
979
988
|
}
|
|
980
|
-
async function
|
|
989
|
+
async function Fn(t, e) {
|
|
981
990
|
const n = { root: t.name, folders: [], failures: [], truncated: !1 };
|
|
982
991
|
await gt(t.handle, [], 0, e, n);
|
|
983
992
|
const s = n.folders.reduce(
|
|
984
|
-
(l, r) => l + Object.values(r.files).reduce((
|
|
993
|
+
(l, r) => l + Object.values(r.files).reduce((u, c) => u + c.length, 0),
|
|
985
994
|
0
|
|
986
995
|
);
|
|
987
996
|
if (s > e.maxBodyBytes)
|
|
@@ -990,113 +999,113 @@ async function Dn(t, e) {
|
|
|
990
999
|
);
|
|
991
1000
|
return n;
|
|
992
1001
|
}
|
|
993
|
-
const
|
|
1002
|
+
const Hn = {
|
|
994
1003
|
key: 0,
|
|
995
1004
|
class: "mbc"
|
|
996
|
-
},
|
|
1005
|
+
}, Kn = { class: "mbc__head" }, Un = ["disabled"], qn = {
|
|
997
1006
|
key: 0,
|
|
998
1007
|
class: "mbc__error"
|
|
999
|
-
},
|
|
1008
|
+
}, Gn = {
|
|
1000
1009
|
key: 1,
|
|
1001
1010
|
class: "mbc__notice"
|
|
1002
|
-
},
|
|
1011
|
+
}, Jn = { class: "mbc__panel" }, Vn = { class: "mbc__title" }, Yn = { class: "mbc__list" }, Wn = ["title", "onClick"], Zn = { class: "mbc__module" }, Xn = { class: "mbc__name" }, Qn = {
|
|
1003
1012
|
key: 0,
|
|
1004
1013
|
class: "mbc__where"
|
|
1005
|
-
},
|
|
1014
|
+
}, eo = {
|
|
1006
1015
|
key: 0,
|
|
1007
1016
|
class: "mbc__detail"
|
|
1008
|
-
},
|
|
1017
|
+
}, to = {
|
|
1009
1018
|
key: 0,
|
|
1010
1019
|
class: "mbc__hint"
|
|
1011
|
-
},
|
|
1020
|
+
}, no = { class: "mbc__meta" }, oo = { class: "mbc__mono" }, so = { class: "mbc__actions" }, ao = ["disabled", "onClick"], io = ["disabled", "onClick"], lo = ["disabled", "onClick"], ro = { class: "mbc__panel" }, co = { class: "mbc__field" }, uo = ["value"], po = ["disabled"], fo = ["disabled"], mo = {
|
|
1012
1021
|
key: 0,
|
|
1013
1022
|
class: "mbc__hint"
|
|
1014
|
-
},
|
|
1023
|
+
}, ho = ["aria-valuenow"], bo = {
|
|
1015
1024
|
key: 3,
|
|
1016
1025
|
class: "mbc__confirm"
|
|
1017
|
-
},
|
|
1026
|
+
}, go = { class: "mbc__confirm-title" }, vo = { class: "mbc__confirm-body" }, yo = {
|
|
1018
1027
|
key: 0,
|
|
1019
1028
|
class: "mbc__mono"
|
|
1020
|
-
},
|
|
1029
|
+
}, _o = { class: "mbc__actions" }, ko = ["disabled"], wo = ["disabled"], $o = ["disabled"], xo = { class: "mbc__panel" }, So = { class: "mbc__field" }, Eo = ["value"], Co = ["disabled"], Bo = ["disabled"], To = {
|
|
1021
1030
|
key: 0,
|
|
1022
1031
|
class: "mbc__hint"
|
|
1023
|
-
},
|
|
1032
|
+
}, Ao = {
|
|
1024
1033
|
key: 1,
|
|
1025
1034
|
class: "mbc__hint"
|
|
1026
|
-
},
|
|
1035
|
+
}, Oo = {
|
|
1027
1036
|
key: 0,
|
|
1028
1037
|
class: "mbc__scan"
|
|
1029
|
-
},
|
|
1038
|
+
}, Mo = { class: "mbc__pick" }, Po = ["disabled", "checked", "onChange"], Ro = { class: "mbc__name" }, jo = { class: "mbc__module" }, No = { class: "mbc__hint" }, Io = { class: "mbc__mono" }, Lo = {
|
|
1030
1039
|
key: 0,
|
|
1031
1040
|
class: "mbc__problem"
|
|
1032
|
-
},
|
|
1041
|
+
}, zo = { class: "mbc__hint mbc__mono" }, Do = {
|
|
1033
1042
|
key: 1,
|
|
1034
1043
|
class: "mbc__hint"
|
|
1035
|
-
},
|
|
1044
|
+
}, Fo = {
|
|
1036
1045
|
key: 2,
|
|
1037
1046
|
class: "mbc__problem"
|
|
1038
|
-
},
|
|
1047
|
+
}, Ho = {
|
|
1039
1048
|
key: 3,
|
|
1040
1049
|
class: "mbc__failures"
|
|
1041
|
-
},
|
|
1050
|
+
}, Ko = { class: "mbc__field mbc__field--end" }, Uo = ["disabled"], qo = {
|
|
1042
1051
|
key: 2,
|
|
1043
1052
|
class: "mbc__panel"
|
|
1044
|
-
},
|
|
1053
|
+
}, Go = { class: "mbc__title" }, Jo = {
|
|
1045
1054
|
key: 0,
|
|
1046
1055
|
class: "mbc__failures"
|
|
1047
|
-
},
|
|
1056
|
+
}, Vo = {
|
|
1048
1057
|
key: 1,
|
|
1049
1058
|
class: "mbc__failures"
|
|
1050
|
-
},
|
|
1059
|
+
}, Yo = { key: 0 }, Wo = {
|
|
1051
1060
|
key: 1,
|
|
1052
1061
|
class: "mbc__failures mbc__failures--nested"
|
|
1053
|
-
}, Oe = 2,
|
|
1062
|
+
}, Oe = 2, Zo = /* @__PURE__ */ We({
|
|
1054
1063
|
__name: "MagicBlockConsole",
|
|
1055
1064
|
setup(t) {
|
|
1056
|
-
const e = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: n } = nt(), s = tt(), l = et(), r = w(!1),
|
|
1065
|
+
const e = { modified: "有改动", unchanged: "没改动", missing: "目录里没有" }, { isStaff: n } = nt(), s = tt(), l = et(), r = w(!1), u = w(""), c = w([]), d = w(""), f = w(""), _ = w(""), y = w(!1), S = w(!1), B = w(!1), L = w(!1), Y = w(!1), A = w(null), T = w(null), U = w(null), N = w(""), z = w(null), le = w({}), G = w([]), W = w([]), M = w(null), E = w({ active: !1, percent: 0, stage: "", failed: !1 }), Ee = C(() => ({
|
|
1057
1066
|
width: `${Math.max(0, Math.min(100, E.value.percent))}%`,
|
|
1058
1067
|
background: E.value.failed ? "var(--sp-color-danger)" : "var(--sp-color-primary, var(--primary-color))"
|
|
1059
1068
|
}));
|
|
1060
|
-
function
|
|
1069
|
+
function H(i, o) {
|
|
1061
1070
|
E.value = { active: !0, percent: Math.max(E.value.percent, i), stage: o, failed: !1 };
|
|
1062
1071
|
try {
|
|
1063
|
-
const a = window.localStorage.getItem("mb:progress") ?? "[]",
|
|
1064
|
-
|
|
1072
|
+
const a = window.localStorage.getItem("mb:progress") ?? "[]", g = JSON.parse(a);
|
|
1073
|
+
g.push({ p: E.value.percent, s: o, t: Math.round(performance.now()) }), window.localStorage.setItem("mb:progress", JSON.stringify(g));
|
|
1065
1074
|
} catch {
|
|
1066
1075
|
}
|
|
1067
1076
|
}
|
|
1068
|
-
function
|
|
1069
|
-
|
|
1077
|
+
function Z(i, o) {
|
|
1078
|
+
H(i ? 100 : E.value.percent, o), E.value = { active: !i, percent: i ? 100 : E.value.percent, stage: o, failed: !i };
|
|
1070
1079
|
}
|
|
1071
|
-
const
|
|
1072
|
-
function
|
|
1080
|
+
const re = (i) => (i.disabledReason ?? "").trim(), K = (i) => (i.issues ?? []).map((o) => String(o?.message ?? "")).filter(Boolean), ce = (i) => en(i.id);
|
|
1081
|
+
function ye(i) {
|
|
1073
1082
|
d.value = d.value === i.id ? "" : i.id;
|
|
1074
1083
|
const o = l?.path ?? "", a = tn(i.id, o);
|
|
1075
1084
|
mt(i.id);
|
|
1076
|
-
const
|
|
1085
|
+
const g = i.name || i.id;
|
|
1077
1086
|
if (a) {
|
|
1078
|
-
_.value = `「${
|
|
1087
|
+
_.value = `「${g}」不在这一页:正在跳到 ${a}`, s?.push?.(a);
|
|
1079
1088
|
return;
|
|
1080
1089
|
}
|
|
1081
|
-
const $ =
|
|
1082
|
-
_.value = $.length === 0 ? `「${
|
|
1090
|
+
const $ = ce(i);
|
|
1091
|
+
_.value = $.length === 0 ? `「${g}」这次会话里还没在页面上露过面:先打开挂着它的那一页,再点一次` : `「${g}」就在这一页(${$.join(" / ")}):已经把它标红`;
|
|
1083
1092
|
}
|
|
1084
|
-
function
|
|
1085
|
-
const o =
|
|
1086
|
-
return
|
|
1093
|
+
function Ce(i) {
|
|
1094
|
+
const o = ce(i), a = o.length === 0 ? "点一下:这次会话里它还没在页面上露过面" : `点一下:把「${i.name || i.id}」标红并跳到 ${o.join(" / ")}`, g = re(i);
|
|
1095
|
+
return g ? `${g}
|
|
1087
1096
|
${a}` : a;
|
|
1088
1097
|
}
|
|
1089
|
-
const
|
|
1090
|
-
const i =
|
|
1091
|
-
return i ?
|
|
1092
|
-
}),
|
|
1093
|
-
function
|
|
1098
|
+
const _e = C(() => {
|
|
1099
|
+
const i = u.value.trim().toLowerCase();
|
|
1100
|
+
return i ? c.value.filter((o) => `${o.module} ${o.name} ${o.brief}`.toLowerCase().includes(i)) : c.value;
|
|
1101
|
+
}), fe = C(() => (z.value?.blocks ?? []).filter((i) => i.canApply)), ke = C(() => fe.value.filter((i) => le.value[i.id] === !0));
|
|
1102
|
+
function me() {
|
|
1094
1103
|
const i = s?.getRoutes?.() ?? [], o = /* @__PURE__ */ new Set(), a = [];
|
|
1095
|
-
for (const
|
|
1096
|
-
const $ = typeof
|
|
1097
|
-
if (!$ || o.has($) || $.includes(":") || $.includes("*") ||
|
|
1104
|
+
for (const g of i) {
|
|
1105
|
+
const $ = typeof g?.path == "string" ? g.path.trim() : "";
|
|
1106
|
+
if (!$ || o.has($) || $.includes(":") || $.includes("*") || g.redirect || !g.components?.default || g.meta?.tab === !1) continue;
|
|
1098
1107
|
o.add($);
|
|
1099
|
-
const F =
|
|
1108
|
+
const F = g.meta?.title ?? g.meta?.sub, O = g.meta?.group;
|
|
1100
1109
|
a.push({
|
|
1101
1110
|
path: $,
|
|
1102
1111
|
title: typeof F == "string" && F.trim() ? F.trim() : $,
|
|
@@ -1105,287 +1114,287 @@ ${a}` : a;
|
|
|
1105
1114
|
}
|
|
1106
1115
|
return a;
|
|
1107
1116
|
}
|
|
1108
|
-
function
|
|
1117
|
+
function R(i) {
|
|
1109
1118
|
return (i instanceof Error ? i.message.trim() : String(i)) || "请求没有到达后端(网络或登录态的问题),请重试";
|
|
1110
1119
|
}
|
|
1111
|
-
function
|
|
1120
|
+
function ee(i) {
|
|
1112
1121
|
const o = i?.issues;
|
|
1113
1122
|
return Array.isArray(o) ? o.map((a) => typeof a == "string" ? a : String(a?.message ?? "")).filter(Boolean) : [];
|
|
1114
1123
|
}
|
|
1115
|
-
async function
|
|
1124
|
+
async function te(i, o) {
|
|
1116
1125
|
const a = JSON.stringify(o);
|
|
1117
1126
|
try {
|
|
1118
|
-
return await
|
|
1119
|
-
} catch (
|
|
1120
|
-
const $ =
|
|
1127
|
+
return await V(i, { method: "POST", body: a });
|
|
1128
|
+
} catch (g) {
|
|
1129
|
+
const $ = R(g), F = await fetch(`http://localhost:3000${i}`, {
|
|
1121
1130
|
method: "POST",
|
|
1122
1131
|
credentials: "include",
|
|
1123
1132
|
headers: { "Content-Type": "application/json", ...Me("POST", !0) },
|
|
1124
1133
|
body: a
|
|
1125
|
-
}).then((
|
|
1134
|
+
}).then((X) => X.json()).catch(() => null), O = ee(F);
|
|
1126
1135
|
throw O.length === 0 ? new Error($) : new Error(`${String(F?.message ?? $)}
|
|
1127
1136
|
- ${O.join(`
|
|
1128
1137
|
- `)}`);
|
|
1129
1138
|
}
|
|
1130
1139
|
}
|
|
1131
|
-
async function
|
|
1140
|
+
async function ne() {
|
|
1132
1141
|
try {
|
|
1133
|
-
const i = await
|
|
1134
|
-
|
|
1142
|
+
const i = await V("/magic-blocks/index");
|
|
1143
|
+
c.value = i.blocks ?? [];
|
|
1135
1144
|
} catch (i) {
|
|
1136
|
-
f.value =
|
|
1145
|
+
f.value = R(i);
|
|
1137
1146
|
}
|
|
1138
1147
|
}
|
|
1139
|
-
async function
|
|
1148
|
+
async function D(i, o) {
|
|
1140
1149
|
o.value = !0, f.value = "";
|
|
1141
1150
|
try {
|
|
1142
1151
|
await i(), Jt();
|
|
1143
1152
|
} catch (a) {
|
|
1144
|
-
f.value =
|
|
1153
|
+
f.value = R(a);
|
|
1145
1154
|
} finally {
|
|
1146
1155
|
o.value = !1;
|
|
1147
1156
|
}
|
|
1148
1157
|
}
|
|
1149
|
-
const
|
|
1158
|
+
const oe = (i) => D(async () => {
|
|
1150
1159
|
S.value = !0;
|
|
1151
1160
|
try {
|
|
1152
|
-
await
|
|
1161
|
+
await V("/magic-blocks/check", { method: "POST", body: JSON.stringify(i ? { blocks: [i] } : {}) }), _.value = i ? "这一块重新体检完了" : "全部块重新体检完了", await ne();
|
|
1153
1162
|
} finally {
|
|
1154
1163
|
S.value = !1;
|
|
1155
1164
|
}
|
|
1156
|
-
}, y),
|
|
1165
|
+
}, y), m = (i) => D(async () => {
|
|
1157
1166
|
const o = await Ae();
|
|
1158
|
-
i === "export" ? (A.value = o,
|
|
1167
|
+
i === "export" ? (A.value = o, T.value || (T.value = o)) : (T.value = o, A.value || (A.value = o)), _.value = i === "export" ? `导出目录:${o.name}${T.value === o ? "(读回目录也填成它了)" : ""}` : `读回目录:${o.name}`;
|
|
1159
1168
|
}, y);
|
|
1160
|
-
async function
|
|
1161
|
-
if (
|
|
1162
|
-
const i = await
|
|
1163
|
-
return
|
|
1169
|
+
async function k() {
|
|
1170
|
+
if (U.value) return U.value;
|
|
1171
|
+
const i = await V("/magic-blocks/rules");
|
|
1172
|
+
return U.value = i.rules, i.rules;
|
|
1164
1173
|
}
|
|
1165
|
-
const
|
|
1174
|
+
const I = () => D(async () => {
|
|
1166
1175
|
if (!ht()) throw new Error("这个浏览器没法直接写你本机的文件夹:请用 Chrome / Edge,并从 https 或 localhost 打开");
|
|
1167
|
-
|
|
1176
|
+
B.value = !0, _.value = "", N.value = "", f.value = "", E.value = { active: !0, percent: 0, stage: "准备…", failed: !1 };
|
|
1168
1177
|
try {
|
|
1169
1178
|
const i = A.value ?? await Ae();
|
|
1170
|
-
A.value = i,
|
|
1171
|
-
const o = await
|
|
1172
|
-
|
|
1173
|
-
const a = await
|
|
1179
|
+
A.value = i, T.value || (T.value = i);
|
|
1180
|
+
const o = await te("/magic-blocks/export", {});
|
|
1181
|
+
U.value = o.rules, Ln(i, o.rules);
|
|
1182
|
+
const a = await Nn(i, o.rules);
|
|
1174
1183
|
if (a.topCount > 0) {
|
|
1175
|
-
|
|
1184
|
+
H(5, "等你确认要不要先清空"), M.value = { target: i, inventory: a };
|
|
1176
1185
|
return;
|
|
1177
1186
|
}
|
|
1178
|
-
await
|
|
1187
|
+
await se(i, o, !1);
|
|
1179
1188
|
} catch (i) {
|
|
1180
|
-
throw
|
|
1189
|
+
throw Z(!1, "导出失败"), i;
|
|
1181
1190
|
} finally {
|
|
1182
|
-
|
|
1191
|
+
B.value = !1;
|
|
1183
1192
|
}
|
|
1184
1193
|
}, y);
|
|
1185
|
-
async function
|
|
1194
|
+
async function se(i, o, a) {
|
|
1186
1195
|
try {
|
|
1187
|
-
|
|
1188
|
-
const
|
|
1196
|
+
H(20, "收主题与控件清单…");
|
|
1197
|
+
const g = { ...o.files, [Ve]: An(me()) };
|
|
1189
1198
|
let $ = "";
|
|
1190
1199
|
await new Promise((P) => {
|
|
1191
1200
|
setTimeout(P, 0);
|
|
1192
1201
|
});
|
|
1193
1202
|
try {
|
|
1194
1203
|
const P = ft();
|
|
1195
|
-
|
|
1204
|
+
g[pe] = P.css, g[je] = Wt(), $ = P.skipped.length > 0 ? `;⚠️ 有 ${P.skipped.length} 张样式表读不到规则(跨源):${P.skipped.join(" / ")}` : "";
|
|
1196
1205
|
} catch (P) {
|
|
1197
|
-
$ = `;主题 CSS 没收成(${
|
|
1206
|
+
$ = `;主题 CSS 没收成(${R(P)}):${pe} 没写,其余照旧`;
|
|
1198
1207
|
}
|
|
1199
1208
|
let F = "";
|
|
1200
|
-
a && (
|
|
1201
|
-
const O = Object.keys(
|
|
1202
|
-
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1209
|
+
a && (H(35, "清空目录…"), F = `,先清掉了 ${await In(i)} 项`);
|
|
1210
|
+
const O = Object.keys(g).length, X = a ? 45 : 30;
|
|
1211
|
+
H(X, `写文件 0/${O}…`);
|
|
1212
|
+
const ae = await jn(i, g, (P, He) => {
|
|
1213
|
+
H(X + Math.round(P / Math.max(1, He) * (95 - X)), `写文件 ${P}/${He}…`);
|
|
1205
1214
|
});
|
|
1206
|
-
|
|
1207
|
-
const St =
|
|
1208
|
-
|
|
1209
|
-
} catch (
|
|
1210
|
-
throw
|
|
1215
|
+
H(98, "收尾…");
|
|
1216
|
+
const St = ae.failed.length > 0 ? `;⚠️ ${ae.failed.length} 个文件没写成:${ae.failed.slice(0, 3).map((P) => `${P.path}(${P.message})`).join("、")}` + (ae.failed.length > 3 ? ` 等 ${ae.failed.length} 条` : "") : "";
|
|
1217
|
+
N.value = `铺到「${i.name}」:${o.blocks} 个块、${ae.written} 个文件(含 ${Ve} / ${pe} / ${je})${F}${St}${$}`, _.value = ae.failed.length > 0 ? "导出完了,但有文件没写成(见下面那句)" : "导出完了:用你自己的编辑器改,改完回这里「读回改动」", Z(!0, "完成");
|
|
1218
|
+
} catch (g) {
|
|
1219
|
+
throw Z(!1, "导出中途失败(已经铺进去的文件不会自己删掉)"), g;
|
|
1211
1220
|
}
|
|
1212
1221
|
}
|
|
1213
|
-
const vt = () =>
|
|
1222
|
+
const vt = () => D(async () => {
|
|
1214
1223
|
const i = M.value;
|
|
1215
1224
|
if (M.value = null, !!i) {
|
|
1216
|
-
|
|
1225
|
+
B.value = !0;
|
|
1217
1226
|
try {
|
|
1218
|
-
|
|
1219
|
-
const o = await
|
|
1220
|
-
|
|
1227
|
+
H(15, "重新取一份开发包…");
|
|
1228
|
+
const o = await te("/magic-blocks/export", {});
|
|
1229
|
+
U.value = o.rules, await se(i.target, o, !0);
|
|
1221
1230
|
} catch (o) {
|
|
1222
|
-
throw
|
|
1231
|
+
throw Z(!1, "导出失败"), o;
|
|
1223
1232
|
} finally {
|
|
1224
|
-
|
|
1233
|
+
B.value = !1;
|
|
1225
1234
|
}
|
|
1226
1235
|
}
|
|
1227
|
-
}, y), yt = () =>
|
|
1236
|
+
}, y), yt = () => D(async () => {
|
|
1228
1237
|
const i = M.value;
|
|
1229
1238
|
if (M.value = null, !!i) {
|
|
1230
|
-
|
|
1239
|
+
B.value = !0;
|
|
1231
1240
|
try {
|
|
1232
|
-
|
|
1233
|
-
const o = await
|
|
1234
|
-
|
|
1241
|
+
H(15, "重新取一份开发包…");
|
|
1242
|
+
const o = await te("/magic-blocks/export", {});
|
|
1243
|
+
U.value = o.rules, await se(i.target, o, !1);
|
|
1235
1244
|
} catch (o) {
|
|
1236
|
-
throw
|
|
1245
|
+
throw Z(!1, "导出失败"), o;
|
|
1237
1246
|
} finally {
|
|
1238
|
-
|
|
1247
|
+
B.value = !1;
|
|
1239
1248
|
}
|
|
1240
1249
|
}
|
|
1241
1250
|
}, y);
|
|
1242
1251
|
function _t() {
|
|
1243
|
-
M.value = null, E.value = { active: !1, percent: 0, stage: "", failed: !1 }, _.value = "这次没有导出(目录里的东西一个字节都没动)",
|
|
1252
|
+
M.value = null, E.value = { active: !1, percent: 0, stage: "", failed: !1 }, _.value = "这次没有导出(目录里的东西一个字节都没动)", N.value = "";
|
|
1244
1253
|
}
|
|
1245
|
-
const De = () =>
|
|
1246
|
-
const i =
|
|
1247
|
-
|
|
1254
|
+
const De = () => D(async () => {
|
|
1255
|
+
const i = T.value ?? await Ae();
|
|
1256
|
+
T.value = i, A.value || (A.value = i), L.value = !0, _.value = "", G.value = [], W.value = [];
|
|
1248
1257
|
try {
|
|
1249
|
-
const o = await
|
|
1250
|
-
throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${
|
|
1251
|
-
}), a = await
|
|
1258
|
+
const o = await k().catch((O) => {
|
|
1259
|
+
throw new Error(`取不到扫描规则(GET /magic-blocks/rules):${R(O)}`);
|
|
1260
|
+
}), a = await Fn(i, o), g = await V("/magic-blocks/read", {
|
|
1252
1261
|
method: "POST",
|
|
1253
1262
|
body: JSON.stringify({ ...a, includeMissing: !1 })
|
|
1254
1263
|
});
|
|
1255
|
-
|
|
1264
|
+
z.value = g;
|
|
1256
1265
|
const $ = {};
|
|
1257
|
-
for (const O of
|
|
1258
|
-
|
|
1259
|
-
const F = (
|
|
1260
|
-
_.value = `扫到 ${
|
|
1266
|
+
for (const O of g.blocks ?? []) $[O.id] = O.status === "modified" && O.canApply;
|
|
1267
|
+
le.value = $;
|
|
1268
|
+
const F = (g.blocks ?? []).reduce((O, X) => ({ ...O, [X.status]: (O[X.status] ?? 0) + 1 }), {});
|
|
1269
|
+
_.value = `扫到 ${g.folders} 个文件夹、${g.files} 个文件:有改动 ${F.modified ?? 0} / 没改动 ${F.unchanged ?? 0}` + (g.complete ? "" : "(层数到了上限,没走完,可能还有块没扫到)");
|
|
1261
1270
|
} finally {
|
|
1262
|
-
|
|
1271
|
+
L.value = !1;
|
|
1263
1272
|
}
|
|
1264
|
-
}, y), kt = () =>
|
|
1265
|
-
const i =
|
|
1266
|
-
if (
|
|
1273
|
+
}, y), kt = () => D(async () => {
|
|
1274
|
+
const i = ke.value, o = Cn(i);
|
|
1275
|
+
if (G.value = o.issues, W.value = [], o.issues.length > 0)
|
|
1267
1276
|
throw _.value = "", new Error(`前端校验没过(${o.issues.length} 条),没有发请求:
|
|
1268
1277
|
- ${o.issues.join(`
|
|
1269
1278
|
- `)}`);
|
|
1270
|
-
|
|
1279
|
+
Y.value = !0, _.value = "";
|
|
1271
1280
|
try {
|
|
1272
|
-
const a = await
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1275
|
-
await De(), _.value = `${
|
|
1281
|
+
const a = await te("/magic-blocks/import", { updatedBy: "", blocks: i });
|
|
1282
|
+
W.value = a.results ?? [], _.value = `保存:成功 ${a.saved} 个、失败 ${a.failed} 个`, await ne();
|
|
1283
|
+
const g = _.value;
|
|
1284
|
+
await De(), _.value = `${g};已重新读回该目录`;
|
|
1276
1285
|
} finally {
|
|
1277
|
-
|
|
1286
|
+
Y.value = !1;
|
|
1278
1287
|
}
|
|
1279
|
-
}, y), wt = (i) =>
|
|
1280
|
-
await
|
|
1281
|
-
}, y), $t = (i) =>
|
|
1282
|
-
window.confirm(`删掉「${i.name || i.id}」?库里这一行(连同它的文件包)会一起没。`) && (await
|
|
1288
|
+
}, y), wt = (i) => D(async () => {
|
|
1289
|
+
await V(`/magic-blocks/${encodeURIComponent(i.id)}/rollback`, { method: "POST" }), _.value = `「${i.name || i.id}」已回滚到上一版`, await ne();
|
|
1290
|
+
}, y), $t = (i) => D(async () => {
|
|
1291
|
+
window.confirm(`删掉「${i.name || i.id}」?库里这一行(连同它的文件包)会一起没。`) && (await V(`/magic-blocks/${encodeURIComponent(i.id)}`, { method: "DELETE" }), _.value = `「${i.name || i.id}」已删除`, await ne());
|
|
1283
1292
|
}, y);
|
|
1284
1293
|
function xt(i, o) {
|
|
1285
1294
|
const a = o.target;
|
|
1286
|
-
|
|
1295
|
+
le.value[i] = a?.checked === !0;
|
|
1287
1296
|
}
|
|
1288
1297
|
function Fe(i) {
|
|
1289
1298
|
const o = i.detail?.uuid ?? "";
|
|
1290
1299
|
r.value = !0, d.value = o;
|
|
1291
1300
|
}
|
|
1292
1301
|
return Ze(() => {
|
|
1293
|
-
window.addEventListener("magic-block:open-console", Fe),
|
|
1302
|
+
window.addEventListener("magic-block:open-console", Fe), ne(), k().catch(() => {
|
|
1294
1303
|
});
|
|
1295
|
-
}), Xe(() => window.removeEventListener("magic-block:open-console", Fe)), (i, o) =>
|
|
1304
|
+
}), Xe(() => window.removeEventListener("magic-block:open-console", Fe)), (i, o) => be(n) ? (h(), b(j, { key: 0 }, [
|
|
1296
1305
|
p("button", {
|
|
1297
1306
|
class: "fab",
|
|
1298
1307
|
type: "button",
|
|
1299
1308
|
title: "magic block 控制台",
|
|
1300
1309
|
onClick: o[0] || (o[0] = (a) => r.value = !0)
|
|
1301
1310
|
}, "块"),
|
|
1302
|
-
r.value ? (
|
|
1303
|
-
p("header",
|
|
1311
|
+
r.value ? (h(), b("aside", Hn, [
|
|
1312
|
+
p("header", Kn, [
|
|
1304
1313
|
o[12] || (o[12] = p("strong", null, "magic block", -1)),
|
|
1305
1314
|
Tt(p("input", {
|
|
1306
|
-
"onUpdate:modelValue": o[1] || (o[1] = (a) =>
|
|
1315
|
+
"onUpdate:modelValue": o[1] || (o[1] = (a) => u.value = a),
|
|
1307
1316
|
class: "p-inputtext p-component mbc__grow",
|
|
1308
1317
|
type: "search",
|
|
1309
1318
|
placeholder: "筛选 module / 名字"
|
|
1310
1319
|
}, null, 512), [
|
|
1311
|
-
[At,
|
|
1320
|
+
[At, u.value]
|
|
1312
1321
|
]),
|
|
1313
1322
|
p("button", {
|
|
1314
1323
|
class: "p-button p-button-sm",
|
|
1315
1324
|
type: "button",
|
|
1316
1325
|
disabled: y.value,
|
|
1317
|
-
onClick: o[2] || (o[2] = (a) =>
|
|
1318
|
-
},
|
|
1326
|
+
onClick: o[2] || (o[2] = (a) => oe())
|
|
1327
|
+
}, v(S.value ? "体检中…" : "重新体检全部"), 9, Un),
|
|
1319
1328
|
p("button", {
|
|
1320
1329
|
class: "p-button p-button-sm p-button-text",
|
|
1321
1330
|
type: "button",
|
|
1322
1331
|
onClick: o[3] || (o[3] = (a) => r.value = !1)
|
|
1323
1332
|
}, "关闭")
|
|
1324
1333
|
]),
|
|
1325
|
-
f.value ? (
|
|
1326
|
-
_.value ? (
|
|
1327
|
-
p("section",
|
|
1328
|
-
p("h3",
|
|
1329
|
-
p("ul",
|
|
1330
|
-
(
|
|
1334
|
+
f.value ? (h(), b("p", qn, v(f.value), 1)) : x("", !0),
|
|
1335
|
+
_.value ? (h(), b("p", Gn, v(_.value), 1)) : x("", !0),
|
|
1336
|
+
p("section", Jn, [
|
|
1337
|
+
p("h3", Vn, "库里的块(" + v(_e.value.length) + " / " + v(c.value.length) + ")", 1),
|
|
1338
|
+
p("ul", Yn, [
|
|
1339
|
+
(h(!0), b(j, null, Q(_e.value, (a) => (h(), b("li", {
|
|
1331
1340
|
key: a.id
|
|
1332
1341
|
}, [
|
|
1333
1342
|
p("button", {
|
|
1334
1343
|
type: "button",
|
|
1335
|
-
class:
|
|
1336
|
-
title:
|
|
1337
|
-
onClick: (
|
|
1344
|
+
class: J(["mbc__row", { "is-active": a.id === d.value }]),
|
|
1345
|
+
title: Ce(a),
|
|
1346
|
+
onClick: (g) => ye(a)
|
|
1338
1347
|
}, [
|
|
1339
|
-
p("span",
|
|
1340
|
-
p("span",
|
|
1341
|
-
|
|
1348
|
+
p("span", Zn, v(a.module || "unassigned"), 1),
|
|
1349
|
+
p("span", Xn, v(a.name || a.id), 1),
|
|
1350
|
+
ce(a).length > 0 ? (h(), b("span", Qn, v(ce(a).join(" / ")), 1)) : x("", !0),
|
|
1342
1351
|
p("em", {
|
|
1343
|
-
class:
|
|
1344
|
-
},
|
|
1345
|
-
], 10,
|
|
1346
|
-
d.value === a.id ? (
|
|
1347
|
-
(
|
|
1352
|
+
class: J({ "is-off": a.enabled === !1 })
|
|
1353
|
+
}, v(a.enabled === !1 ? re(a) || "校验失败已停用" : "可用"), 3)
|
|
1354
|
+
], 10, Wn),
|
|
1355
|
+
d.value === a.id ? (h(), b("div", eo, [
|
|
1356
|
+
(h(!0), b(j, null, Q(K(a).slice(0, Oe), (g, $) => (h(), b("p", {
|
|
1348
1357
|
key: $,
|
|
1349
1358
|
class: "mbc__problem"
|
|
1350
|
-
},
|
|
1351
|
-
|
|
1352
|
-
p("dl",
|
|
1359
|
+
}, v(g), 1))), 128)),
|
|
1360
|
+
K(a).length > Oe ? (h(), b("p", to, "还有 " + v(K(a).length - Oe) + " 条体检问题,点「体检这一块」看最新结论", 1)) : x("", !0),
|
|
1361
|
+
p("dl", no, [
|
|
1353
1362
|
o[13] || (o[13] = p("dt", null, "文件", -1)),
|
|
1354
|
-
p("dd", null,
|
|
1363
|
+
p("dd", null, v((a.fileNames || []).join(" / ") || "(没有文件)"), 1),
|
|
1355
1364
|
o[14] || (o[14] = p("dt", null, "更新", -1)),
|
|
1356
|
-
p("dd", null,
|
|
1365
|
+
p("dd", null, v(a.updatedAt || "—"), 1),
|
|
1357
1366
|
o[15] || (o[15] = p("dt", null, "上一版", -1)),
|
|
1358
|
-
p("dd", null,
|
|
1367
|
+
p("dd", null, v(a.hasPrev ? a.prevUpdatedAt || "有" : "没有"), 1),
|
|
1359
1368
|
o[16] || (o[16] = p("dt", null, "id", -1)),
|
|
1360
|
-
p("dd",
|
|
1369
|
+
p("dd", oo, v(a.id), 1)
|
|
1361
1370
|
]),
|
|
1362
|
-
p("div",
|
|
1371
|
+
p("div", so, [
|
|
1363
1372
|
p("button", {
|
|
1364
1373
|
class: "p-button p-button-sm p-button-outlined",
|
|
1365
1374
|
type: "button",
|
|
1366
1375
|
disabled: y.value,
|
|
1367
|
-
onClick: (
|
|
1368
|
-
}, "体检这一块", 8,
|
|
1376
|
+
onClick: (g) => oe(a.id)
|
|
1377
|
+
}, "体检这一块", 8, ao),
|
|
1369
1378
|
p("button", {
|
|
1370
1379
|
class: "p-button p-button-sm p-button-outlined",
|
|
1371
1380
|
type: "button",
|
|
1372
1381
|
disabled: y.value || !a.hasPrev,
|
|
1373
|
-
onClick: (
|
|
1374
|
-
}, "回滚上一版", 8,
|
|
1382
|
+
onClick: (g) => wt(a)
|
|
1383
|
+
}, "回滚上一版", 8, io),
|
|
1375
1384
|
p("button", {
|
|
1376
1385
|
class: "p-button p-button-sm p-button-text",
|
|
1377
1386
|
type: "button",
|
|
1378
1387
|
disabled: y.value,
|
|
1379
|
-
onClick: (
|
|
1380
|
-
}, "删除", 8,
|
|
1388
|
+
onClick: (g) => $t(a)
|
|
1389
|
+
}, "删除", 8, lo)
|
|
1381
1390
|
])
|
|
1382
1391
|
])) : x("", !0)
|
|
1383
1392
|
]))), 128))
|
|
1384
1393
|
])
|
|
1385
1394
|
]),
|
|
1386
|
-
p("section",
|
|
1395
|
+
p("section", ro, [
|
|
1387
1396
|
o[23] || (o[23] = p("h3", { class: "mbc__title" }, "导出去改(用你自己的编辑器)", -1)),
|
|
1388
|
-
p("div",
|
|
1397
|
+
p("div", co, [
|
|
1389
1398
|
o[17] || (o[17] = p("label", { for: "mbc-dir" }, "导出目录", -1)),
|
|
1390
1399
|
p("input", {
|
|
1391
1400
|
id: "mbc-dir",
|
|
@@ -1393,25 +1402,25 @@ ${a}` : a;
|
|
|
1393
1402
|
type: "text",
|
|
1394
1403
|
readonly: "",
|
|
1395
1404
|
value: A.value ? A.value.name : "(还没选:点右边那个按钮选一个文件夹)"
|
|
1396
|
-
}, null, 8,
|
|
1405
|
+
}, null, 8, uo),
|
|
1397
1406
|
p("button", {
|
|
1398
1407
|
class: "p-button p-button-sm p-button-outlined",
|
|
1399
1408
|
type: "button",
|
|
1400
1409
|
disabled: y.value,
|
|
1401
|
-
onClick: o[4] || (o[4] = (a) =>
|
|
1402
|
-
}, "选择文件夹", 8,
|
|
1410
|
+
onClick: o[4] || (o[4] = (a) => m("export"))
|
|
1411
|
+
}, "选择文件夹", 8, po),
|
|
1403
1412
|
p("button", {
|
|
1404
1413
|
class: "p-button p-button-sm",
|
|
1405
1414
|
type: "button",
|
|
1406
1415
|
disabled: y.value,
|
|
1407
|
-
onClick: o[5] || (o[5] = (a) =>
|
|
1408
|
-
},
|
|
1416
|
+
onClick: o[5] || (o[5] = (a) => I())
|
|
1417
|
+
}, v(B.value ? "导出中…" : "导出"), 9, fo)
|
|
1409
1418
|
]),
|
|
1410
1419
|
o[24] || (o[24] = Ot('<p class="mbc__hint" data-v-7c262207> 代码会铺在 <span class="mbc__mono" data-v-7c262207>workspace/<可读名>-<块 uuid>/</span>, 顶层另附 <span class="mbc__mono" data-v-7c262207>GUIDE.lock.md</span>(怎么改)、<span class="mbc__mono" data-v-7c262207>pages.lock.ts</span>(Page 枚举)、 <span class="mbc__mono" data-v-7c262207>backend.lock.pyi</span>(能用的库 / ctx / 环境变量 / 模型)、 <span class="mbc__mono" data-v-7c262207>labull.css</span> 与 <span class="mbc__mono" data-v-7c262207>CONTROLS.lock.html</span>(主题与控件清单)—— 那几份都是**生成物**。 </p>', 1)),
|
|
1411
|
-
|
|
1412
|
-
E.value.active ? (
|
|
1420
|
+
N.value ? (h(), b("p", mo, v(N.value), 1)) : x("", !0),
|
|
1421
|
+
E.value.active ? (h(), b("div", {
|
|
1413
1422
|
key: 1,
|
|
1414
|
-
class:
|
|
1423
|
+
class: J(["mbc__progress", { "is-failed": E.value.failed }]),
|
|
1415
1424
|
role: "progressbar",
|
|
1416
1425
|
"aria-valuenow": E.value.percent,
|
|
1417
1426
|
"aria-valuemin": "0",
|
|
@@ -1419,136 +1428,136 @@ ${a}` : a;
|
|
|
1419
1428
|
}, [
|
|
1420
1429
|
p("div", {
|
|
1421
1430
|
class: "mbc__progress-bar",
|
|
1422
|
-
style: Qe(
|
|
1431
|
+
style: Qe(Ee.value)
|
|
1423
1432
|
}, null, 4)
|
|
1424
|
-
], 10,
|
|
1425
|
-
E.value.active ? (
|
|
1433
|
+
], 10, ho)) : x("", !0),
|
|
1434
|
+
E.value.active ? (h(), b("p", {
|
|
1426
1435
|
key: 2,
|
|
1427
|
-
class:
|
|
1428
|
-
},
|
|
1429
|
-
M.value ? (
|
|
1430
|
-
p("p",
|
|
1431
|
-
p("p",
|
|
1432
|
-
o[18] || (o[18] =
|
|
1436
|
+
class: J(["mbc__hint", { "mbc__progress-note": E.value.failed }])
|
|
1437
|
+
}, v(E.value.failed ? "✗" : "") + " " + v(E.value.percent) + "% · " + v(E.value.stage), 3)) : x("", !0),
|
|
1438
|
+
M.value ? (h(), b("div", bo, [
|
|
1439
|
+
p("p", go, "「" + v(M.value.target.name) + "」里现在有 " + v(M.value.inventory.dirs) + " 个文件夹 / " + v(M.value.inventory.files) + " 个文件", 1),
|
|
1440
|
+
p("p", vo, [
|
|
1441
|
+
o[18] || (o[18] = ue(" 接下来会", -1)),
|
|
1433
1442
|
o[19] || (o[19] = p("b", null, "先全部删掉", -1)),
|
|
1434
|
-
o[20] || (o[20] =
|
|
1443
|
+
o[20] || (o[20] = ue("再铺一遍 —— 包括你改过、还没读回库的东西。 清空只动这个目录", -1)),
|
|
1435
1444
|
o[21] || (o[21] = p("b", null, "里面", -1)),
|
|
1436
|
-
o[22] || (o[22] =
|
|
1437
|
-
M.value.inventory.items.length > 0 ? (
|
|
1445
|
+
o[22] || (o[22] = ue("的子项:目录本身、以及它外面的任何东西都不会被碰。 ", -1)),
|
|
1446
|
+
M.value.inventory.items.length > 0 ? (h(), b("span", yo, "(" + v(M.value.inventory.items.slice(0, 6).map((a) => a.name).join(" / ")) + v(M.value.inventory.items.length > 6 ? " …" : "") + ")", 1)) : x("", !0)
|
|
1438
1447
|
]),
|
|
1439
|
-
p("div",
|
|
1448
|
+
p("div", _o, [
|
|
1440
1449
|
p("button", {
|
|
1441
1450
|
class: "p-button p-button-sm",
|
|
1442
1451
|
type: "button",
|
|
1443
1452
|
disabled: y.value,
|
|
1444
1453
|
onClick: o[6] || (o[6] = (a) => vt())
|
|
1445
|
-
}, "清空并导出", 8,
|
|
1454
|
+
}, "清空并导出", 8, ko),
|
|
1446
1455
|
p("button", {
|
|
1447
1456
|
class: "p-button p-button-sm p-button-outlined",
|
|
1448
1457
|
type: "button",
|
|
1449
1458
|
disabled: y.value,
|
|
1450
1459
|
onClick: o[7] || (o[7] = (a) => yt())
|
|
1451
|
-
}, "只覆盖", 8,
|
|
1460
|
+
}, "只覆盖", 8, wo),
|
|
1452
1461
|
p("button", {
|
|
1453
1462
|
class: "p-button p-button-sm p-button-text",
|
|
1454
1463
|
type: "button",
|
|
1455
1464
|
disabled: y.value,
|
|
1456
1465
|
onClick: o[8] || (o[8] = (a) => _t())
|
|
1457
|
-
}, "取消", 8,
|
|
1466
|
+
}, "取消", 8, $o)
|
|
1458
1467
|
])
|
|
1459
1468
|
])) : x("", !0)
|
|
1460
1469
|
]),
|
|
1461
|
-
p("section",
|
|
1470
|
+
p("section", xo, [
|
|
1462
1471
|
o[28] || (o[28] = p("h3", { class: "mbc__title" }, "读回改动", -1)),
|
|
1463
|
-
p("div",
|
|
1472
|
+
p("div", So, [
|
|
1464
1473
|
o[25] || (o[25] = p("label", { for: "mbc-read-dir" }, "读回目录", -1)),
|
|
1465
1474
|
p("input", {
|
|
1466
1475
|
id: "mbc-read-dir",
|
|
1467
1476
|
class: "p-inputtext p-component mbc__grow mbc__mono",
|
|
1468
1477
|
type: "text",
|
|
1469
1478
|
readonly: "",
|
|
1470
|
-
value:
|
|
1471
|
-
}, null, 8,
|
|
1479
|
+
value: T.value ? T.value.name : "(还没选:导出会自动填上,也可以自己选一个)"
|
|
1480
|
+
}, null, 8, Eo),
|
|
1472
1481
|
p("button", {
|
|
1473
1482
|
class: "p-button p-button-sm p-button-outlined",
|
|
1474
1483
|
type: "button",
|
|
1475
1484
|
disabled: y.value,
|
|
1476
|
-
onClick: o[9] || (o[9] = (a) =>
|
|
1477
|
-
}, "选择文件夹", 8,
|
|
1485
|
+
onClick: o[9] || (o[9] = (a) => m("read"))
|
|
1486
|
+
}, "选择文件夹", 8, Co),
|
|
1478
1487
|
p("button", {
|
|
1479
1488
|
class: "p-button p-button-sm p-button-outlined",
|
|
1480
1489
|
type: "button",
|
|
1481
1490
|
disabled: y.value,
|
|
1482
1491
|
onClick: o[10] || (o[10] = (a) => De())
|
|
1483
|
-
},
|
|
1492
|
+
}, v(L.value ? "读回中…" : "读回改动"), 9, Bo)
|
|
1484
1493
|
]),
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
(
|
|
1494
|
+
T.value && A.value && T.value.name !== A.value.name ? (h(), b("p", To, " 读回的是「" + v(T.value.name) + "」(与导出目录「" + v(A.value.name) + "」不是同一个 —— 想同步就再选一次)。 ", 1)) : (h(), b("p", Ao, "读回目录默认跟着导出目录;要读别的文件夹就点「选择文件夹」单独选一个。")),
|
|
1495
|
+
z.value ? (h(), b(j, { key: 2 }, [
|
|
1496
|
+
z.value.blocks.length > 0 ? (h(), b("ul", Oo, [
|
|
1497
|
+
(h(!0), b(j, null, Q(z.value.blocks, (a) => (h(), b("li", {
|
|
1489
1498
|
key: a.id,
|
|
1490
1499
|
class: "mbc__block"
|
|
1491
1500
|
}, [
|
|
1492
|
-
p("label",
|
|
1501
|
+
p("label", Mo, [
|
|
1493
1502
|
p("span", {
|
|
1494
|
-
class:
|
|
1503
|
+
class: J(["p-checkbox p-component", { "p-disabled": !a.canApply }])
|
|
1495
1504
|
}, [
|
|
1496
1505
|
p("input", {
|
|
1497
1506
|
class: "p-checkbox-input",
|
|
1498
1507
|
type: "checkbox",
|
|
1499
1508
|
disabled: !a.canApply,
|
|
1500
|
-
checked:
|
|
1501
|
-
onChange: (
|
|
1502
|
-
}, null, 40,
|
|
1509
|
+
checked: le.value[a.id] === !0,
|
|
1510
|
+
onChange: (g) => xt(a.id, g)
|
|
1511
|
+
}, null, 40, Po),
|
|
1503
1512
|
o[26] || (o[26] = p("span", { class: "p-checkbox-box" }, null, -1))
|
|
1504
1513
|
], 2),
|
|
1505
|
-
p("span",
|
|
1514
|
+
p("span", Ro, v(a.name || a.id), 1),
|
|
1506
1515
|
p("span", {
|
|
1507
|
-
class:
|
|
1508
|
-
},
|
|
1509
|
-
p("span",
|
|
1516
|
+
class: J(["p-tag", a.status === "modified" ? "p-tag-success" : a.status === "missing" ? "p-tag-warning" : ""])
|
|
1517
|
+
}, v(e[a.status]), 3),
|
|
1518
|
+
p("span", jo, v(a.module || "—"), 1)
|
|
1510
1519
|
]),
|
|
1511
|
-
p("p",
|
|
1512
|
-
a.status === "missing" ? (
|
|
1513
|
-
|
|
1514
|
-
], 64)) : a.changedFiles.length > 0 ? (
|
|
1515
|
-
o[27] || (o[27] =
|
|
1516
|
-
p("span",
|
|
1517
|
-
], 64)) : (
|
|
1518
|
-
|
|
1520
|
+
p("p", No, [
|
|
1521
|
+
a.status === "missing" ? (h(), b(j, { key: 0 }, [
|
|
1522
|
+
ue("目录里没有这一块,勾不上")
|
|
1523
|
+
], 64)) : a.changedFiles.length > 0 ? (h(), b(j, { key: 1 }, [
|
|
1524
|
+
o[27] || (o[27] = ue("改了:", -1)),
|
|
1525
|
+
p("span", Io, v(a.changedFiles.join(" / ")), 1)
|
|
1526
|
+
], 64)) : (h(), b(j, { key: 2 }, [
|
|
1527
|
+
ue("内容与库里一致")
|
|
1519
1528
|
], 64))
|
|
1520
1529
|
]),
|
|
1521
|
-
a.blockedWhy ? (
|
|
1522
|
-
p("p",
|
|
1530
|
+
a.blockedWhy ? (h(), b("p", Lo, "不能存:" + v(a.blockedWhy), 1)) : x("", !0),
|
|
1531
|
+
p("p", zo, v(a.folder || a.where), 1)
|
|
1523
1532
|
]))), 128))
|
|
1524
|
-
])) : (
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
(
|
|
1533
|
+
])) : (h(), b("p", Do, "这个目录里没有认出任何块。")),
|
|
1534
|
+
z.value.unmatched.length > 0 ? (h(), b("p", Fo, "认不出归属的文件夹(" + v(z.value.unmatched.length) + "):" + v(z.value.unmatched.join(" / ")), 1)) : x("", !0),
|
|
1535
|
+
z.value.failures.length > 0 ? (h(), b("ul", Ho, [
|
|
1536
|
+
(h(!0), b(j, null, Q(z.value.failures, (a, g) => (h(), b("li", { key: g }, v(a.where || a.kind) + ":" + v(a.message), 1))), 128))
|
|
1528
1537
|
])) : x("", !0),
|
|
1529
|
-
p("div",
|
|
1538
|
+
p("div", Ko, [
|
|
1530
1539
|
p("button", {
|
|
1531
1540
|
class: "p-button p-button-sm",
|
|
1532
1541
|
type: "button",
|
|
1533
1542
|
disabled: y.value,
|
|
1534
1543
|
onClick: o[11] || (o[11] = (a) => kt())
|
|
1535
|
-
},
|
|
1544
|
+
}, v(Y.value ? "保存中…" : `保存选中的块(${ke.value.length})`), 9, Uo)
|
|
1536
1545
|
])
|
|
1537
1546
|
], 64)) : x("", !0)
|
|
1538
1547
|
]),
|
|
1539
|
-
|
|
1540
|
-
p("h3",
|
|
1541
|
-
|
|
1542
|
-
(
|
|
1543
|
-
])) : (
|
|
1544
|
-
(
|
|
1548
|
+
G.value.length > 0 || W.value.length > 0 ? (h(), b("section", qo, [
|
|
1549
|
+
p("h3", Go, v(G.value.length > 0 ? "前端校验拦下的问题" : "保存结果"), 1),
|
|
1550
|
+
G.value.length > 0 ? (h(), b("ul", Jo, [
|
|
1551
|
+
(h(!0), b(j, null, Q(G.value, (a, g) => (h(), b("li", { key: g }, v(a), 1))), 128))
|
|
1552
|
+
])) : (h(), b("ul", Vo, [
|
|
1553
|
+
(h(!0), b(j, null, Q(W.value, (a) => (h(), b("li", {
|
|
1545
1554
|
key: a.id,
|
|
1546
|
-
class:
|
|
1555
|
+
class: J({ "is-ok": a.ok })
|
|
1547
1556
|
}, [
|
|
1548
|
-
p("strong", null,
|
|
1549
|
-
!a.ok && a.error ? (
|
|
1550
|
-
!a.ok && (a.issues ?? []).length > 0 ? (
|
|
1551
|
-
(
|
|
1557
|
+
p("strong", null, v(a.name || a.id) + ":" + v(a.ok ? "已保存" : "没保存"), 1),
|
|
1558
|
+
!a.ok && a.error ? (h(), b("span", Yo, v(a.error), 1)) : x("", !0),
|
|
1559
|
+
!a.ok && (a.issues ?? []).length > 0 ? (h(), b("ul", Wo, [
|
|
1560
|
+
(h(!0), b(j, null, Q(a.issues, (g, $) => (h(), b("li", { key: $ }, v(g), 1))), 128))
|
|
1552
1561
|
])) : x("", !0)
|
|
1553
1562
|
], 2))), 128))
|
|
1554
1563
|
]))
|
|
@@ -1556,25 +1565,25 @@ ${a}` : a;
|
|
|
1556
1565
|
])) : x("", !0)
|
|
1557
1566
|
], 64)) : x("", !0);
|
|
1558
1567
|
}
|
|
1559
|
-
}),
|
|
1568
|
+
}), os = /* @__PURE__ */ ot(Zo, [["__scopeId", "data-v-7c262207"]]);
|
|
1560
1569
|
export {
|
|
1561
1570
|
Mt as API_BASE,
|
|
1562
1571
|
Lt as BLOCK_BACKEND_FILE,
|
|
1563
1572
|
rt as BLOCK_ENTRY,
|
|
1564
1573
|
Te as BLOCK_MANIFEST,
|
|
1565
1574
|
Rt as CLIENT_SOURCE,
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1575
|
+
xe as MANIFEST_KEYS,
|
|
1576
|
+
os as MagicBlockConsole,
|
|
1577
|
+
ns as MagicBlockHost,
|
|
1569
1578
|
ze as NAME_MAX,
|
|
1570
1579
|
qt as buildPreview,
|
|
1571
|
-
|
|
1580
|
+
Cn as checkSelection,
|
|
1572
1581
|
It as installBridge,
|
|
1573
1582
|
Vt as loadBlockRender,
|
|
1574
1583
|
Gt as onBlockRenderRefresh,
|
|
1575
|
-
|
|
1584
|
+
xn as parseManifest,
|
|
1576
1585
|
Jt as refreshBlockRender,
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1586
|
+
Sn as validFileName,
|
|
1587
|
+
yn as validName,
|
|
1588
|
+
En as validateBlock
|
|
1580
1589
|
};
|