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