mechanica 1.0.0
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/editor.d.ts +26 -0
- package/dist/editor.js +2671 -0
- package/dist/editor.js.map +1 -0
- package/dist/main.d.ts +40 -0
- package/dist/main.js +40 -0
- package/dist/main.js.map +1 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.js +322 -0
- package/dist/plugin.js.map +1 -0
- package/dist/style.css +697 -0
- package/package.json +50 -0
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Plugin as Plugin_2 } from 'vue';
|
|
2
|
+
import { RendererElement } from 'vue';
|
|
3
|
+
import { RendererNode } from 'vue';
|
|
4
|
+
import { VNode } from 'vue';
|
|
5
|
+
|
|
6
|
+
export declare const Content: {
|
|
7
|
+
props: never[];
|
|
8
|
+
render: () => (VNode<RendererNode, RendererElement, {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
}> | null)[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export declare const createMechanica: () => Plugin_2;
|
|
14
|
+
|
|
15
|
+
export { }
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
declare global {
|
|
19
|
+
type ComponentInfo<T extends SchemaItem> = {
|
|
20
|
+
id?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
order?: number;
|
|
23
|
+
group?: string;
|
|
24
|
+
props?: T;
|
|
25
|
+
};
|
|
26
|
+
var defineBlock: <T extends SchemaItem = {}>(input: ComponentInfo<T>) => SchemaType<T>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
declare module 'compact-json-schema' {
|
|
31
|
+
interface SchemaAliases {
|
|
32
|
+
"image": {
|
|
33
|
+
src: "string";
|
|
34
|
+
previewSrc: "string?";
|
|
35
|
+
};
|
|
36
|
+
"file": {
|
|
37
|
+
src: "string";
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { registerAlias } from "compact-json-schema";
|
|
2
|
+
import { h } from "vue";
|
|
3
|
+
import { blocksMap } from "virtual:builder-blocks";
|
|
4
|
+
const createMechanica = () => {
|
|
5
|
+
return {
|
|
6
|
+
install(app) {
|
|
7
|
+
app.onUnmount(() => {
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
const renderBlocks = (state, baseKey) => {
|
|
13
|
+
return state.map((item, index) => {
|
|
14
|
+
const block = blocksMap.get(item.blockId);
|
|
15
|
+
if (!block) return null;
|
|
16
|
+
const content = { ...item.data, key: item.id };
|
|
17
|
+
if (!item.children) {
|
|
18
|
+
return h(block, content);
|
|
19
|
+
}
|
|
20
|
+
const children = {};
|
|
21
|
+
const slotsData = Array.isArray(item.children) ? { default: item.children } : item.children;
|
|
22
|
+
if (slotsData) {
|
|
23
|
+
for (let key in slotsData) {
|
|
24
|
+
children[key] = () => renderBlocks(slotsData[key]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return h(block, content, children);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const Content = {
|
|
31
|
+
props: [],
|
|
32
|
+
render: () => renderBlocks(window.state.content ?? [])
|
|
33
|
+
};
|
|
34
|
+
registerAlias("image", { type: "object", format: "image", properties: { src: "string", previewSrc: "string?" } });
|
|
35
|
+
registerAlias("file", { type: "object", format: "file", properties: { src: "string" } });
|
|
36
|
+
export {
|
|
37
|
+
Content,
|
|
38
|
+
createMechanica
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../src/createMechanica.ts","../src/renderBlocks.ts","../src/components/Content.ts","../src/index.ts"],"sourcesContent":["import { Plugin } from \"vue\";\r\n\r\nexport const createMechanica = (): Plugin => {\r\n return {\r\n install(app) {\r\n\r\n \r\n\r\n app.onUnmount(() => {\r\n\r\n })\r\n }\r\n }\r\n}","import { h } from \"vue\"\r\nimport { blocksMap } from 'virtual:builder-blocks'\r\n\r\nexport const renderBlocks = (state: any[], baseKey?: string) => {\r\n\r\n return state.map((item, index) => {\r\n const block = blocksMap.get(item.blockId)\r\n if (!block) return null\r\n\r\n const content = { ...item.data, key: baseKey? baseKey+index: item.id }\r\n\r\n if (!item.children) {\r\n return h(block, content)\r\n } \r\n\r\n const children: Record<string, any> = {}\r\n const slotsData = Array.isArray(item.children)? { default: item.children }: item.children\r\n if (slotsData) {\r\n for (let key in slotsData) {\r\n children[key] = () => renderBlocks(slotsData[key])\r\n }\r\n }\r\n\r\n return h(block, content, children)\r\n })\r\n}\r\n","import { renderBlocks } from \"../renderBlocks\"\r\n\r\nconst Content = {\r\n props: [],\r\n render: () => renderBlocks((window as any).state.content ?? [])\r\n}\r\n\r\nexport default Content","import { SchemaItem, SchemaType, registerAlias } from 'compact-json-schema'\r\n\r\nexport { createMechanica } from './createMechanica'\r\nexport { default as Content } from './components/Content'\r\nexport {}\r\n\r\ndeclare global {\r\n\r\n type ComponentInfo<T extends SchemaItem> = {\r\n id?: string,\r\n name?: string,\r\n order?: number,\r\n group?: string,\r\n props?: T\r\n }\r\n\r\n var defineBlock: <T extends SchemaItem = {}>(input: ComponentInfo<T>) => SchemaType<T>\r\n}\r\n\r\ndeclare module 'compact-json-schema' {\r\n export interface SchemaAliases {\r\n \"image\": { src: \"string\", previewSrc: \"string?\" },\r\n \"file\": { src: \"string\" }\r\n }\r\n}\r\n\r\nregisterAlias(\"image\", { type: \"object\", format: \"image\", properties: { src: \"string\", previewSrc: \"string?\" } })\r\nregisterAlias(\"file\", { type: \"object\", format: \"file\", properties: { src: \"string\" } })\r\n"],"names":[],"mappings":";;;AAEO,MAAM,kBAAkB,MAAc;AACpC,SAAA;AAAA,IACL,QAAQ,KAAK;AAIX,UAAI,UAAU,MAAM;AAAA,MAAA,CAEnB;AAAA,IAAA;AAAA,EAEL;AACF;ACVa,MAAA,eAAe,CAAC,OAAc,YAAqB;AAE9D,SAAO,MAAM,IAAI,CAAC,MAAM,UAAU;AAChC,UAAM,QAAQ,UAAU,IAAI,KAAK,OAAO;AACpC,QAAA,CAAC,MAAc,QAAA;AAEb,UAAA,UAAU,EAAE,GAAG,KAAK,MAAM,KAA6B,KAAK,GAAG;AAEjE,QAAA,CAAC,KAAK,UAAU;AACX,aAAA,EAAE,OAAO,OAAO;AAAA,IAAA;AAGzB,UAAM,WAAgC,CAAC;AACjC,UAAA,YAAY,MAAM,QAAQ,KAAK,QAAQ,IAAG,EAAE,SAAS,KAAK,SAAS,IAAG,KAAK;AACjF,QAAI,WAAW;AACb,eAAS,OAAO,WAAW;AACzB,iBAAS,GAAG,IAAI,MAAM,aAAa,UAAU,GAAG,CAAC;AAAA,MAAA;AAAA,IACnD;AAGK,WAAA,EAAE,OAAO,SAAS,QAAQ;AAAA,EAAA,CAClC;AACH;ACvBA,MAAM,UAAU;AAAA,EACd,OAAO,CAAC;AAAA,EACR,QAAQ,MAAM,aAAc,OAAe,MAAM,WAAW,CAAE,CAAA;AAChE;ACqBA,cAAc,SAAS,EAAE,MAAM,UAAU,QAAQ,SAAS,YAAY,EAAE,KAAK,UAAU,YAAY,aAAa;AAChH,cAAc,QAAQ,EAAE,MAAM,UAAU,QAAQ,QAAQ,YAAY,EAAE,KAAK,SAAS,GAAG;"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin as Plugin_2 } from 'vite';
|
|
2
|
+
|
|
3
|
+
declare const mechanicaPlugin: (options?: PluginOptions) => Plugin_2;
|
|
4
|
+
export default mechanicaPlugin;
|
|
5
|
+
|
|
6
|
+
declare type PluginOptions = {
|
|
7
|
+
basePath?: string;
|
|
8
|
+
entry?: string;
|
|
9
|
+
variables?: string;
|
|
10
|
+
pages?: string;
|
|
11
|
+
};
|
|
12
|
+
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { join, parse as parse$1, resolve } from "path";
|
|
5
|
+
import { parse } from "@babel/parser";
|
|
6
|
+
import _generate from "@babel/generator";
|
|
7
|
+
import { walk } from "estree-walker";
|
|
8
|
+
const collectBlocks = async (ctx, dir, isDev) => {
|
|
9
|
+
const lines = [];
|
|
10
|
+
const blockNames = [];
|
|
11
|
+
const blocks = fs.readdirSync(dir, { recursive: true });
|
|
12
|
+
let index = 0;
|
|
13
|
+
for (let blockPath of blocks) {
|
|
14
|
+
if (typeof blockPath !== "string") continue;
|
|
15
|
+
if (!blockPath.endsWith(".vue")) continue;
|
|
16
|
+
const content = fs.readFileSync(join(dir, blockPath), "utf-8");
|
|
17
|
+
if (!content.includes("defineBlock")) continue;
|
|
18
|
+
const file = await ctx.resolve(`/src/blocks/${blockPath}?block`);
|
|
19
|
+
if (!file) continue;
|
|
20
|
+
lines.push(`import block${index} from "${file.id}"`);
|
|
21
|
+
blockNames.push(`block${index}`);
|
|
22
|
+
index++;
|
|
23
|
+
}
|
|
24
|
+
lines.push(`export const blocksList = [${blockNames.join(", ")}]`);
|
|
25
|
+
lines.push(`export const blocksMap = new Map(blocksList.map(file => [ file.blockId, file ]))`);
|
|
26
|
+
if (isDev) {
|
|
27
|
+
lines.push(`
|
|
28
|
+
import.meta.hot?.accept(() => {
|
|
29
|
+
|
|
30
|
+
})
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
return lines.join("\n");
|
|
34
|
+
};
|
|
35
|
+
const generate = ((_a = _generate) == null ? void 0 : _a.default) ?? _generate;
|
|
36
|
+
const getValue = (node, key) => {
|
|
37
|
+
var _a2;
|
|
38
|
+
return ((_a2 = node.properties.find((item) => {
|
|
39
|
+
var _a3;
|
|
40
|
+
return ((_a3 = item.key) == null ? void 0 : _a3.name) === key;
|
|
41
|
+
})) == null ? void 0 : _a2.value) ?? null;
|
|
42
|
+
};
|
|
43
|
+
const objectToNode = (obj, deep = true) => {
|
|
44
|
+
return {
|
|
45
|
+
type: "ObjectExpression",
|
|
46
|
+
properties: Object.entries(obj).map(([key, value]) => ({
|
|
47
|
+
type: "ObjectProperty",
|
|
48
|
+
key: { type: "Identifier", name: key },
|
|
49
|
+
value: deep ? valueToNode(value) : value
|
|
50
|
+
}))
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const valueToNode = (value) => {
|
|
54
|
+
if (value === null) return { type: "NullLiteral" };
|
|
55
|
+
if (typeof value === "boolean") return { type: "BooleanLiteral", value };
|
|
56
|
+
if (typeof value === "string") return { type: "StringLiteral", value };
|
|
57
|
+
if (Array.isArray(value)) return { type: "ArrayExpression", elements: value.map((item) => valueToNode(item)) };
|
|
58
|
+
if (typeof value === "object") return objectToNode(value);
|
|
59
|
+
};
|
|
60
|
+
const parseDefineBlock = (code, defaultId) => {
|
|
61
|
+
var _a2;
|
|
62
|
+
const ast = parse(code, { sourceType: "module" });
|
|
63
|
+
let defineBlockNode;
|
|
64
|
+
let defineComponentNode;
|
|
65
|
+
let toDelete;
|
|
66
|
+
const slotNames = [];
|
|
67
|
+
walk(ast.program, {
|
|
68
|
+
enter(node) {
|
|
69
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
70
|
+
if (node.callee.name === "_defineComponent") {
|
|
71
|
+
defineComponentNode = node.arguments[0];
|
|
72
|
+
}
|
|
73
|
+
if (node.callee.name === "defineBlock") {
|
|
74
|
+
defineBlockNode = node;
|
|
75
|
+
}
|
|
76
|
+
if (node.callee.name === "_renderSlot" || node.callee.name === "_ssrRenderSlot") {
|
|
77
|
+
for (let arg of node.arguments) {
|
|
78
|
+
if (arg.type === "StringLiteral" && !slotNames.includes(arg.value)) {
|
|
79
|
+
slotNames.push(arg.value);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
leave(node) {
|
|
86
|
+
if (node.type === "VariableDeclarator" && defineBlockNode && node.init === defineBlockNode) {
|
|
87
|
+
node.init = { type: "Identifier", name: "__props" };
|
|
88
|
+
}
|
|
89
|
+
if (node.type === "ExpressionStatement" && defineBlockNode && node.expression === defineBlockNode) {
|
|
90
|
+
toDelete = node;
|
|
91
|
+
}
|
|
92
|
+
if (toDelete && (node.type === "BlockStatement" || node.type === "Program")) {
|
|
93
|
+
const index = node.body.indexOf(toDelete);
|
|
94
|
+
if (index >= 0) {
|
|
95
|
+
node.body.splice(index, 1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if ((defineBlockNode == null ? void 0 : defineBlockNode.type) !== "CallExpression" || (defineComponentNode == null ? void 0 : defineComponentNode.type) !== "ObjectExpression") {
|
|
101
|
+
return { ast, blockId: null };
|
|
102
|
+
}
|
|
103
|
+
const blockSchema = defineBlockNode.arguments[0];
|
|
104
|
+
if (blockSchema.type !== "ObjectExpression") {
|
|
105
|
+
return { ast, blockId: null };
|
|
106
|
+
}
|
|
107
|
+
const blockId = ((_a2 = getValue(blockSchema, "id")) == null ? void 0 : _a2.value) ?? defaultId;
|
|
108
|
+
if (!blockId) {
|
|
109
|
+
return { ast, blockId: null };
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
blockId,
|
|
113
|
+
blockSchema,
|
|
114
|
+
slotNames,
|
|
115
|
+
ast,
|
|
116
|
+
defineComponentNode
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
const generateDefineBlock = (code, attachBlockSchema = true, defaultId) => {
|
|
120
|
+
const { blockId, blockSchema, slotNames, ast, defineComponentNode } = parseDefineBlock(code, defaultId);
|
|
121
|
+
if (blockId === null) {
|
|
122
|
+
return generate(ast.program);
|
|
123
|
+
}
|
|
124
|
+
defineComponentNode.properties.push(...objectToNode({ blockId }).properties);
|
|
125
|
+
if (attachBlockSchema) {
|
|
126
|
+
const _slots = getValue(blockSchema, "slots");
|
|
127
|
+
if (!_slots && slotNames.length > 0) {
|
|
128
|
+
blockSchema.properties.push(...objectToNode({
|
|
129
|
+
slots: Object.fromEntries(slotNames.map((key) => [key, true]))
|
|
130
|
+
}).properties);
|
|
131
|
+
}
|
|
132
|
+
defineComponentNode.properties.push(
|
|
133
|
+
...objectToNode({ blockSchema }, false).properties
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const props = getValue(blockSchema, "props");
|
|
137
|
+
const keys = (props == null ? void 0 : props.properties.map((item) => {
|
|
138
|
+
var _a2;
|
|
139
|
+
return (_a2 = item.key) == null ? void 0 : _a2.name;
|
|
140
|
+
}).filter((item) => !!item)) ?? [];
|
|
141
|
+
if (keys.length > 0) {
|
|
142
|
+
const existingProps = getValue(defineComponentNode, "props");
|
|
143
|
+
if (existingProps) {
|
|
144
|
+
const obj = objectToNode(Object.fromEntries(keys.map((key) => [key, { type: null }])));
|
|
145
|
+
existingProps.properties.push(...obj.properties);
|
|
146
|
+
} else {
|
|
147
|
+
defineComponentNode.properties.push({
|
|
148
|
+
type: "ObjectProperty",
|
|
149
|
+
key: { type: "Identifier", name: "props" },
|
|
150
|
+
value: valueToNode(keys)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return generate(ast.program);
|
|
155
|
+
};
|
|
156
|
+
const getUniqueName = async (folder, fileName) => {
|
|
157
|
+
const files = await fs.promises.readdir(folder);
|
|
158
|
+
const { name, ext } = parse$1(fileName);
|
|
159
|
+
let counter = 1;
|
|
160
|
+
let newName = fileName;
|
|
161
|
+
while (files.includes(newName)) {
|
|
162
|
+
newName = `${name}(${counter})${ext}`;
|
|
163
|
+
counter++;
|
|
164
|
+
}
|
|
165
|
+
return newName;
|
|
166
|
+
};
|
|
167
|
+
const blockListModuleId = "virtual:builder-blocks";
|
|
168
|
+
const resolvedBlockListModuleId = "\0" + blockListModuleId;
|
|
169
|
+
const mechanicaPlugin = (options = {}) => {
|
|
170
|
+
let isDev = true;
|
|
171
|
+
let isSsr = false;
|
|
172
|
+
let server;
|
|
173
|
+
const blocksDir = normalizePath(join(process.cwd(), "src/blocks"));
|
|
174
|
+
const triggerHotUpdate = (server2) => {
|
|
175
|
+
const module = server2.moduleGraph.getModuleById(resolvedBlockListModuleId);
|
|
176
|
+
if (module) {
|
|
177
|
+
server2.ws.send({
|
|
178
|
+
type: "update",
|
|
179
|
+
updates: Array.from(module.importers.values()).map((mod) => ({
|
|
180
|
+
type: "js-update",
|
|
181
|
+
timestamp: Date.now(),
|
|
182
|
+
path: mod.url,
|
|
183
|
+
acceptedPath: mod.url
|
|
184
|
+
}))
|
|
185
|
+
});
|
|
186
|
+
return module;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
return {
|
|
190
|
+
name: "mechanica",
|
|
191
|
+
enforce: "post",
|
|
192
|
+
config(_config, env) {
|
|
193
|
+
isDev = env.mode === "development";
|
|
194
|
+
isSsr = !!env.isSsrBuild;
|
|
195
|
+
env.command === "build";
|
|
196
|
+
return {
|
|
197
|
+
optimizeDeps: {
|
|
198
|
+
exclude: ["virtual:builder-blocks", "virtual:page"]
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
buildStart() {
|
|
203
|
+
this.addWatchFile(blocksDir);
|
|
204
|
+
},
|
|
205
|
+
transform(code, id) {
|
|
206
|
+
const [path, query] = id.split("?");
|
|
207
|
+
if (query === "block") {
|
|
208
|
+
if (code.includes("type=script")) {
|
|
209
|
+
return {
|
|
210
|
+
code: code.replace("type=script", "type=script&block=true&"),
|
|
211
|
+
map: null
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (code.includes("defineBlock") && query.includes("block")) {
|
|
216
|
+
const name = parse$1(path).name;
|
|
217
|
+
return generateDefineBlock(code, isDev || isSsr, name);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
resolveId(id) {
|
|
221
|
+
if (id === blockListModuleId) return resolvedBlockListModuleId;
|
|
222
|
+
},
|
|
223
|
+
async load(id) {
|
|
224
|
+
if (id === resolvedBlockListModuleId) {
|
|
225
|
+
return await collectBlocks(this, blocksDir, isDev);
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
configureServer(_server) {
|
|
229
|
+
server = _server;
|
|
230
|
+
server.middlewares.use("/@mechanica", async (req, res, next) => {
|
|
231
|
+
var _a2;
|
|
232
|
+
if ((_a2 = req.url) == null ? void 0 : _a2.startsWith("/assets/")) {
|
|
233
|
+
const path = resolve(`.mech/${req.url}`);
|
|
234
|
+
if (!fs.existsSync(path)) {
|
|
235
|
+
res.statusCode = 404;
|
|
236
|
+
return res.end(`File ${req.url} not found`);
|
|
237
|
+
}
|
|
238
|
+
return fs.createReadStream(path).pipe(res);
|
|
239
|
+
}
|
|
240
|
+
const chunks = [];
|
|
241
|
+
for await (let chunk of req) {
|
|
242
|
+
chunks.push(chunk);
|
|
243
|
+
}
|
|
244
|
+
const body = Buffer.concat(chunks);
|
|
245
|
+
if (req.url === "/upload") {
|
|
246
|
+
fs.mkdirSync(resolve(`.mech/assets`), { recursive: true });
|
|
247
|
+
const sourceName = req.headers["x-file-name"] ?? "file";
|
|
248
|
+
const fileName = await getUniqueName(resolve(`.mech/assets`), sourceName);
|
|
249
|
+
await fs.promises.writeFile(resolve(`.mech/assets/${fileName}`), body);
|
|
250
|
+
res.setHeader("content-type", "application-json").end(JSON.stringify({ src: `/@mechanica/assets/${fileName}`, name: sourceName }));
|
|
251
|
+
}
|
|
252
|
+
if (req.url === "/save") {
|
|
253
|
+
fs.mkdirSync(resolve(`.mech/pages`), { recursive: true });
|
|
254
|
+
const obj = JSON.parse(body.toString("utf-8"));
|
|
255
|
+
const pageData = { content: obj.content };
|
|
256
|
+
await fs.promises.writeFile(resolve(`.mech/pages/${obj.dev.currentPage}.json`), JSON.stringify(pageData, null, 2));
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
watchChange(id, change) {
|
|
262
|
+
if (server && id.startsWith(blocksDir)) {
|
|
263
|
+
if (server) {
|
|
264
|
+
const module = triggerHotUpdate(server);
|
|
265
|
+
if (module && (change.event === "create" || change.event === "delete")) {
|
|
266
|
+
server.reloadModule(module);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
handleHotUpdate(ctx) {
|
|
272
|
+
const { file, modules, server: server2 } = ctx;
|
|
273
|
+
if (file.startsWith(blocksDir)) {
|
|
274
|
+
const module = triggerHotUpdate(server2);
|
|
275
|
+
if (module) {
|
|
276
|
+
return [...modules, module];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
transformIndexHtml: {
|
|
281
|
+
order: "pre",
|
|
282
|
+
async handler(html, ctx) {
|
|
283
|
+
var _a2;
|
|
284
|
+
if (!isDev && process.env.HTML_GENERATE !== "true") {
|
|
285
|
+
return html;
|
|
286
|
+
}
|
|
287
|
+
let str = html;
|
|
288
|
+
if (isDev) {
|
|
289
|
+
const currentPage = ((_a2 = ctx.originalUrl) == null ? void 0 : _a2.slice(1)) || "index";
|
|
290
|
+
const pages = fs.readdirSync(resolve(`.mech/pages`));
|
|
291
|
+
const availablePages = pages.map((path) => parse$1(path).name);
|
|
292
|
+
let content = [];
|
|
293
|
+
if (availablePages.includes(currentPage)) {
|
|
294
|
+
const pageData = fs.readFileSync(resolve(`.mech/pages/${currentPage}.json`), "utf-8");
|
|
295
|
+
content = JSON.parse(pageData).content;
|
|
296
|
+
}
|
|
297
|
+
const state = {
|
|
298
|
+
content,
|
|
299
|
+
dev: {
|
|
300
|
+
currentPage,
|
|
301
|
+
availablePages
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const stateStr = `
|
|
305
|
+
<script>
|
|
306
|
+
window.state=${JSON.stringify(state)}
|
|
307
|
+
<\/script>
|
|
308
|
+
<script type="module">
|
|
309
|
+
import 'mechanica/editor'
|
|
310
|
+
<\/script>
|
|
311
|
+
`;
|
|
312
|
+
str = str.replace("<body>", "<body>\n" + stateStr);
|
|
313
|
+
}
|
|
314
|
+
return str;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
};
|
|
319
|
+
export {
|
|
320
|
+
mechanicaPlugin as default
|
|
321
|
+
};
|
|
322
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../src/vitePlugin/collectBlocks.ts","../src/vitePlugin/parseDefineBlock.ts","../src/vitePlugin/vitePluginUtils.ts","../src/vitePlugin/vitePlugin.ts"],"sourcesContent":["import fs from 'fs'\r\nimport { join } from 'path'\r\n\r\ntype PluginContext = {\r\n resolve: (str: string) => Promise<{ id: string } | null>\r\n}\r\n\r\nexport const collectBlocks = async (ctx: PluginContext, dir: string, isDev: boolean) => {\r\n const lines: string[] = []\r\n const blockNames: string[] = []\r\n const blocks = fs.readdirSync(dir, { recursive: true })\r\n\r\n let index = 0\r\n for (let blockPath of blocks) {\r\n if (typeof blockPath !== \"string\") continue\r\n if (!blockPath.endsWith(\".vue\")) continue\r\n\r\n const content = fs.readFileSync(join(dir, blockPath), \"utf-8\")\r\n if (!content.includes(\"defineBlock\")) continue\r\n\r\n const file = await ctx.resolve(`/src/blocks/${blockPath}?block`)\r\n if (!file) continue\r\n lines.push(`import block${index} from \"${file.id}\"`)\r\n blockNames.push(`block${index}`)\r\n \r\n index++\r\n }\r\n\r\n // const curvesBuilder = await ctx.resolve('@curves_digital/builder/dev')\r\n // if (curvesBuilder) {\r\n // lines.push(`import { DevBlobBlock } from \"${curvesBuilder.id}\"`)\r\n // blockNames.push(\"DevBlobBlock\")\r\n // }\r\n\r\n lines.push(`export const blocksList = [${blockNames.join(\", \")}]`)\r\n lines.push(`export const blocksMap = new Map(blocksList.map(file => [ file.blockId, file ]))`)\r\n \r\n if (isDev) {\r\n lines.push(`\r\nimport.meta.hot?.accept(() => {\r\n \r\n}) \r\n`)\r\n }\r\n\r\n return lines.join(\"\\n\")\r\n}","import { parse } from '@babel/parser'\r\nimport _generate from '@babel/generator'\r\nimport { Node, walk } from 'estree-walker'\r\n\r\nconst generate = (_generate as any)?.default ?? _generate\r\n\r\nconst getValue = (node: any, key: string) => {\r\n return node.properties.find((item: any) => item.key?.name === key)?.value ?? null\r\n}\r\n\r\nconst objectToNode = (obj: Record<string, any>, deep = true): { type: \"ObjectExpression\", properties: any[] } => {\r\n return {\r\n type: \"ObjectExpression\",\r\n properties: Object.entries(obj).map(([key, value]) => ({\r\n type: \"ObjectProperty\",\r\n key: { type: \"Identifier\", name: key },\r\n value: deep? valueToNode(value): value\r\n }))\r\n }\r\n}\r\n\r\nconst valueToNode = (value: any): any => {\r\n if (value === null) return { type: \"NullLiteral\" }\r\n if (typeof value === \"boolean\") return { type: \"BooleanLiteral\", value }\r\n if (typeof value === \"string\") return { type: \"StringLiteral\", value }\r\n if (Array.isArray(value)) return { type: \"ArrayExpression\", elements: value.map(item => valueToNode(item)) }\r\n if (typeof value === \"object\") return objectToNode(value)\r\n}\r\n\r\nexport const parseDefineBlock = (code: string, defaultId: string) => {\r\n\r\n const ast = parse(code, { sourceType: \"module\" })\r\n\r\n let defineBlockNode!: Node \r\n let defineComponentNode!: Node\r\n let toDelete!: Node\r\n const slotNames: string[] = []\r\n walk(ast.program as any, {\r\n enter(node) {\r\n if (node.type === 'CallExpression' && node.callee.type === 'Identifier') {\r\n if (node.callee.name === '_defineComponent') {\r\n defineComponentNode = node.arguments[0]\r\n }\r\n if (node.callee.name === 'defineBlock') {\r\n defineBlockNode = node\r\n }\r\n if (node.callee.name === '_renderSlot' || node.callee.name === '_ssrRenderSlot') {\r\n for (let arg of node.arguments as any) {\r\n if (arg.type === 'StringLiteral' && !slotNames.includes(arg.value)) {\r\n slotNames.push(arg.value)\r\n }\r\n }\r\n }\r\n }\r\n },\r\n leave(node) {\r\n if (node.type === 'VariableDeclarator' && defineBlockNode && node.init === defineBlockNode) {\r\n node.init = { type: \"Identifier\", name: \"__props\" }\r\n }\r\n if (node.type === 'ExpressionStatement' && defineBlockNode && node.expression === defineBlockNode) {\r\n toDelete = node\r\n }\r\n if (toDelete && (node.type ==='BlockStatement' || node.type === 'Program')) {\r\n const index = node.body.indexOf(toDelete as any)\r\n if (index >= 0) {\r\n node.body.splice(index, 1)\r\n }\r\n }\r\n }\r\n })\r\n\r\n if (defineBlockNode?.type !== 'CallExpression' || defineComponentNode?.type !== 'ObjectExpression') {\r\n return { ast, blockId: null }\r\n }\r\n const blockSchema = defineBlockNode.arguments[0]\r\n if (blockSchema.type !== 'ObjectExpression') {\r\n return { ast, blockId: null }\r\n }\r\n\r\n const blockId = getValue(blockSchema, \"id\")?.value as string ?? defaultId\r\n if (!blockId) {\r\n return { ast, blockId: null }\r\n }\r\n\r\n return {\r\n blockId,\r\n blockSchema,\r\n slotNames,\r\n ast,\r\n defineComponentNode\r\n }\r\n}\r\n\r\nexport const generateDefineBlock = (code: string, attachBlockSchema = true, defaultId: string) => {\r\n\r\n const { blockId, blockSchema, slotNames, ast, defineComponentNode } = parseDefineBlock(code, defaultId)\r\n if (blockId === null) {\r\n return generate(ast.program)\r\n }\r\n \r\n defineComponentNode.properties.push(...objectToNode({ blockId }).properties)\r\n\r\n if (attachBlockSchema) {\r\n const _slots = getValue(blockSchema, 'slots')\r\n if (!_slots && slotNames.length > 0) {\r\n blockSchema.properties.push(...objectToNode({\r\n slots: Object.fromEntries(slotNames.map(key => [ key, true ]))\r\n }).properties)\r\n }\r\n\r\n defineComponentNode.properties.push(\r\n ...objectToNode({ blockSchema }, false).properties,\r\n )\r\n }\r\n\r\n const props = getValue(blockSchema, 'props')\r\n const keys: string[] = props?.properties.map((item: any) => item.key?.name).filter((item: any) => !!item) ?? []\r\n\r\n if (keys.length > 0) {\r\n const existingProps = getValue(defineComponentNode, 'props')\r\n if (existingProps) { \r\n const obj = objectToNode(Object.fromEntries(keys.map(key => [ key, { type: null } ])))\r\n existingProps.properties.push(...obj.properties)\r\n } else {\r\n defineComponentNode.properties.push({\r\n type: \"ObjectProperty\",\r\n key: { type: \"Identifier\", name: \"props\" },\r\n value: valueToNode(keys)\r\n } as any)\r\n }\r\n }\r\n\r\n return generate(ast.program)\r\n}","import { join, parse } from \"path\"\r\nimport fs from 'fs'\r\n\r\nexport const getUniqueName = async (folder: string, fileName: string) => {\r\n\r\n const files = await fs.promises.readdir(folder)\r\n const { name, ext } = parse(fileName)\r\n\r\n let counter = 1\r\n let newName = fileName\r\n \r\n while (files.includes(newName)) {\r\n newName = `${name}(${counter})${ext}`\r\n counter++\r\n }\r\n\r\n return newName\r\n}","import { normalizePath, Plugin, ViteDevServer } from 'vite'\r\nimport { collectBlocks } from './collectBlocks'\r\nimport { generateDefineBlock } from './parseDefineBlock'\r\nimport { basename, join, parse, posix, resolve } from 'path'\r\nimport { uid, walkTree } from '../../../common/utils/blocks'\r\nimport fs from 'fs'\r\nimport { getUniqueName } from './vitePluginUtils'\r\n\r\ntype PluginOptions = {\r\n basePath?: string,\r\n entry?: string,\r\n variables?: string,\r\n pages?: string\r\n}\r\n\r\nconst blockListModuleId = 'virtual:builder-blocks'\r\nconst resolvedBlockListModuleId = '\\0'+blockListModuleId\r\n\r\nconst mechanicaPlugin = (options: PluginOptions = {}): Plugin => {\r\n\r\n let isDev = true\r\n let isSsr = false\r\n let isBuild = false\r\n let server: ViteDevServer\r\n \r\n const blocksDir = normalizePath(join(process.cwd(), \"src/blocks\"))\r\n\r\n const triggerHotUpdate = (server: ViteDevServer) => {\r\n const module = server.moduleGraph.getModuleById(resolvedBlockListModuleId)\r\n if (module) {\r\n // TODO: обновлять модуль, только если изменилась схема\r\n\r\n // server.moduleGraph.invalidateModule(module)\r\n server.ws.send({\r\n type: \"update\",\r\n updates: Array.from(module.importers.values()).map(mod => ({\r\n type: \"js-update\",\r\n timestamp: Date.now(),\r\n path: mod.url,\r\n acceptedPath: mod.url\r\n }))\r\n })\r\n\r\n return module\r\n }\r\n }\r\n\r\n return {\r\n name: \"mechanica\",\r\n enforce: \"post\",\r\n config(_config, env) {\r\n isDev = env.mode === 'development'\r\n isSsr = !!env.isSsrBuild\r\n isBuild = env.command === \"build\"\r\n\r\n return {\r\n optimizeDeps: {\r\n exclude: [ \"virtual:builder-blocks\", \"virtual:page\" ]\r\n }\r\n }\r\n },\r\n buildStart() {\r\n this.addWatchFile(blocksDir)\r\n },\r\n transform(code, id) {\r\n const [path, query] = id.split('?');\r\n if (query === \"block\") {\r\n if (code.includes(\"type=script\")) {\r\n return {\r\n code: code.replace(\"type=script\", \"type=script&block=true&\"),\r\n map: null\r\n }\r\n }\r\n }\r\n if (code.includes(\"defineBlock\") && query.includes(\"block\")) {\r\n const name = parse(path).name\r\n return generateDefineBlock(code, isDev || isSsr, name)\r\n }\r\n },\r\n resolveId(id) {\r\n if (id === blockListModuleId) return resolvedBlockListModuleId\r\n },\r\n async load(id) {\r\n if (id === resolvedBlockListModuleId) {\r\n return await collectBlocks(this, blocksDir, isDev)\r\n }\r\n },\r\n configureServer(_server) {\r\n server = _server\r\n\r\n // server.ws.on(\"mechanica:saveState\", (msg) => {\r\n // const obj = JSON.parse(msg)\r\n\r\n // createMechFolder()\r\n // const pageData = { content: obj.content }\r\n // fs.writeFileSync(resolve(`.mech/pages/${obj.dev.currentPage}.json`), JSON.stringify(pageData, null, 2))\r\n // })\r\n\r\n server.middlewares.use(\"/@mechanica\", async (req, res, next) => {\r\n if (req.url?.startsWith(\"/assets/\")) {\r\n const path = resolve(`.mech/${req.url}`)\r\n if (!fs.existsSync(path)) {\r\n res.statusCode = 404\r\n return res.end(`File ${req.url} not found`)\r\n }\r\n return fs.createReadStream(path).pipe(res)\r\n }\r\n const chunks = []\r\n for await (let chunk of req) {\r\n chunks.push(chunk)\r\n }\r\n const body = Buffer.concat(chunks)\r\n\r\n if (req.url === \"/upload\") {\r\n fs.mkdirSync(resolve(`.mech/assets`), { recursive: true })\r\n const sourceName = (req.headers[\"x-file-name\"] as string) ?? 'file'\r\n const fileName = await getUniqueName(resolve(`.mech/assets`), sourceName)\r\n await fs.promises.writeFile(resolve(`.mech/assets/${fileName}`), body)\r\n\r\n res\r\n .setHeader(\"content-type\", \"application-json\")\r\n .end(JSON.stringify({ src: `/@mechanica/assets/${fileName}`, name: sourceName }))\r\n }\r\n\r\n if (req.url === \"/save\") {\r\n fs.mkdirSync(resolve(`.mech/pages`), { recursive: true })\r\n const obj = JSON.parse(body.toString(\"utf-8\"))\r\n const pageData = { content: obj.content }\r\n await fs.promises.writeFile(resolve(`.mech/pages/${obj.dev.currentPage}.json`), JSON.stringify(pageData, null, 2))\r\n }\r\n return\r\n })\r\n\r\n },\r\n watchChange(id, change) {\r\n if (server && id.startsWith(blocksDir)) {\r\n if (server) {\r\n const module = triggerHotUpdate(server)\r\n if (module && (change.event === 'create' || change.event === 'delete')) {\r\n server.reloadModule(module)\r\n }\r\n }\r\n }\r\n },\r\n handleHotUpdate(ctx) {\r\n const { file, modules, server } = ctx\r\n if (file.startsWith(blocksDir)) {\r\n const module = triggerHotUpdate(server)\r\n if (module) {\r\n return [ ...modules, module ]\r\n }\r\n }\r\n },\r\n transformIndexHtml: {\r\n order: \"pre\",\r\n async handler(html, ctx) {\r\n if (!isDev && process.env.HTML_GENERATE !== \"true\") {\r\n return html\r\n }\r\n \r\n let str = html\r\n if (isDev) {\r\n const currentPage = ctx.originalUrl?.slice(1) || 'index'\r\n const pages = fs.readdirSync(resolve(`.mech/pages`))\r\n const availablePages = pages.map(path => parse(path).name)\r\n\r\n let content: any[] = []\r\n if (availablePages.includes(currentPage)) {\r\n const pageData = fs.readFileSync(resolve(`.mech/pages/${currentPage}.json`), \"utf-8\")\r\n content = JSON.parse(pageData).content\r\n }\r\n\r\n const state = {\r\n content,\r\n dev: {\r\n currentPage,\r\n availablePages\r\n }\r\n }\r\n\r\n const stateStr = `\r\n <script>\r\n window.state=${JSON.stringify(state)}\r\n </script>\r\n <script type=\"module\">\r\n import 'mechanica/editor'\r\n </script>\r\n `\r\n\r\n str = str.replace(\"<body>\", \"<body>\\n\" + stateStr)\r\n }\r\n return str\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default mechanicaPlugin"],"names":["_a","parse","server"],"mappings":";;;;;;;AAOO,MAAM,gBAAgB,OAAO,KAAoB,KAAa,UAAmB;AACtF,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAuB,CAAC;AAC9B,QAAM,SAAS,GAAG,YAAY,KAAK,EAAE,WAAW,MAAM;AAEtD,MAAI,QAAQ;AACZ,WAAS,aAAa,QAAQ;AACxB,QAAA,OAAO,cAAc,SAAU;AACnC,QAAI,CAAC,UAAU,SAAS,MAAM,EAAG;AAEjC,UAAM,UAAU,GAAG,aAAa,KAAK,KAAK,SAAS,GAAG,OAAO;AAC7D,QAAI,CAAC,QAAQ,SAAS,aAAa,EAAG;AAEtC,UAAM,OAAO,MAAM,IAAI,QAAQ,eAAe,SAAS,QAAQ;AAC/D,QAAI,CAAC,KAAM;AACX,UAAM,KAAK,eAAe,KAAK,UAAU,KAAK,EAAE,GAAG;AACxC,eAAA,KAAK,QAAQ,KAAK,EAAE;AAE/B;AAAA,EAAA;AASF,QAAM,KAAK,8BAA8B,WAAW,KAAK,IAAI,CAAC,GAAG;AACjE,QAAM,KAAK,kFAAkF;AAE7F,MAAI,OAAO;AACT,UAAM,KAAK;AAAA;AAAA;AAAA;AAAA,CAId;AAAA,EAAA;AAGQ,SAAA,MAAM,KAAK,IAAI;AACxB;AC1CA,MAAM,aAAY,sCAAmB,YAAW;AAEhD,MAAM,WAAW,CAAC,MAAW,QAAgB;;AACpC,WAAAA,MAAA,KAAK,WAAW,KAAK,CAAC,SAAA;;AAAc,aAAAA,MAAA,KAAK,QAAL,gBAAAA,IAAU,UAAS;AAAA,GAAG,MAA1D,gBAAAA,IAA6D,UAAS;AAC/E;AAEA,MAAM,eAAe,CAAC,KAA0B,OAAO,SAA0D;AACxG,SAAA;AAAA,IACL,MAAM;AAAA,IACN,YAAY,OAAO,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;AAAA,MACrD,MAAM;AAAA,MACN,KAAK,EAAE,MAAM,cAAc,MAAM,IAAI;AAAA,MACrC,OAAO,OAAM,YAAY,KAAK,IAAG;AAAA,IAAA,EACjC;AAAA,EACJ;AACF;AAEA,MAAM,cAAc,CAAC,UAAoB;AACvC,MAAI,UAAU,KAAa,QAAA,EAAE,MAAM,cAAc;AACjD,MAAI,OAAO,UAAU,kBAAkB,EAAE,MAAM,kBAAkB,MAAM;AACvE,MAAI,OAAO,UAAU,iBAAiB,EAAE,MAAM,iBAAiB,MAAM;AACrE,MAAI,MAAM,QAAQ,KAAK,UAAU,EAAE,MAAM,mBAAmB,UAAU,MAAM,IAAI,CAAA,SAAQ,YAAY,IAAI,CAAC,EAAE;AAC3G,MAAI,OAAO,UAAU,SAAU,QAAO,aAAa,KAAK;AAC1D;AAEa,MAAA,mBAAmB,CAAC,MAAc,cAAsB;;AAEnE,QAAM,MAAM,MAAM,MAAM,EAAE,YAAY,UAAU;AAE5C,MAAA;AACA,MAAA;AACA,MAAA;AACJ,QAAM,YAAsB,CAAC;AAC7B,OAAK,IAAI,SAAgB;AAAA,IACvB,MAAM,MAAM;AACV,UAAI,KAAK,SAAS,oBAAoB,KAAK,OAAO,SAAS,cAAc;AACnE,YAAA,KAAK,OAAO,SAAS,oBAAoB;AACrB,gCAAA,KAAK,UAAU,CAAC;AAAA,QAAA;AAEpC,YAAA,KAAK,OAAO,SAAS,eAAe;AACpB,4BAAA;AAAA,QAAA;AAEpB,YAAI,KAAK,OAAO,SAAS,iBAAiB,KAAK,OAAO,SAAS,kBAAkB;AACtE,mBAAA,OAAO,KAAK,WAAkB;AACjC,gBAAA,IAAI,SAAS,mBAAmB,CAAC,UAAU,SAAS,IAAI,KAAK,GAAG;AACxD,wBAAA,KAAK,IAAI,KAAK;AAAA,YAAA;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IAEJ;AAAA,IACA,MAAM,MAAM;AACV,UAAI,KAAK,SAAS,wBAAwB,mBAAmB,KAAK,SAAS,iBAAiB;AAC1F,aAAK,OAAO,EAAE,MAAM,cAAc,MAAM,UAAU;AAAA,MAAA;AAEpD,UAAI,KAAK,SAAS,yBAAyB,mBAAmB,KAAK,eAAe,iBAAiB;AACtF,mBAAA;AAAA,MAAA;AAEb,UAAI,aAAa,KAAK,SAAQ,oBAAoB,KAAK,SAAS,YAAY;AAC1E,cAAM,QAAQ,KAAK,KAAK,QAAQ,QAAe;AAC/C,YAAI,SAAS,GAAG;AACT,eAAA,KAAK,OAAO,OAAO,CAAC;AAAA,QAAA;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,CACD;AAED,OAAI,mDAAiB,UAAS,qBAAoB,2DAAqB,UAAS,oBAAoB;AAC3F,WAAA,EAAE,KAAK,SAAS,KAAK;AAAA,EAAA;AAExB,QAAA,cAAc,gBAAgB,UAAU,CAAC;AAC3C,MAAA,YAAY,SAAS,oBAAoB;AACpC,WAAA,EAAE,KAAK,SAAS,KAAK;AAAA,EAAA;AAG9B,QAAM,YAAUA,MAAA,SAAS,aAAa,IAAI,MAA1B,gBAAAA,IAA6B,UAAmB;AAChE,MAAI,CAAC,SAAS;AACL,WAAA,EAAE,KAAK,SAAS,KAAK;AAAA,EAAA;AAGvB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,CAAC,MAAc,oBAAoB,MAAM,cAAsB;AAE1F,QAAA,EAAE,SAAS,aAAa,WAAW,KAAK,wBAAwB,iBAAiB,MAAM,SAAS;AACtG,MAAI,YAAY,MAAM;AACb,WAAA,SAAS,IAAI,OAAO;AAAA,EAAA;AAGT,sBAAA,WAAW,KAAK,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,UAAU;AAE3E,MAAI,mBAAmB;AACf,UAAA,SAAS,SAAS,aAAa,OAAO;AAC5C,QAAI,CAAC,UAAU,UAAU,SAAS,GAAG;AACvB,kBAAA,WAAW,KAAK,GAAG,aAAa;AAAA,QAC1C,OAAO,OAAO,YAAY,UAAU,IAAI,SAAO,CAAE,KAAK,IAAK,CAAC,CAAC;AAAA,MAC9D,CAAA,EAAE,UAAU;AAAA,IAAA;AAGf,wBAAoB,WAAW;AAAA,MAC7B,GAAG,aAAa,EAAE,YAAY,GAAG,KAAK,EAAE;AAAA,IAC1C;AAAA,EAAA;AAGI,QAAA,QAAQ,SAAS,aAAa,OAAO;AAC3C,QAAM,QAAiB,+BAAO,WAAW,IAAI,CAAC;;AAAc,YAAAA,MAAA,KAAK,QAAL,gBAAAA,IAAU;AAAA,KAAM,OAAO,CAAC,SAAc,CAAC,CAAC,UAAS,CAAC;AAE1G,MAAA,KAAK,SAAS,GAAG;AACb,UAAA,gBAAgB,SAAS,qBAAqB,OAAO;AAC3D,QAAI,eAAe;AACjB,YAAM,MAAM,aAAa,OAAO,YAAY,KAAK,IAAI,CAAA,QAAO,CAAE,KAAK,EAAE,MAAM,KAAO,CAAA,CAAC,CAAC,CAAC;AACrF,oBAAc,WAAW,KAAK,GAAG,IAAI,UAAU;AAAA,IAAA,OAC1C;AACL,0BAAoB,WAAW,KAAK;AAAA,QAClC,MAAM;AAAA,QACN,KAAK,EAAE,MAAM,cAAc,MAAM,QAAQ;AAAA,QACzC,OAAO,YAAY,IAAI;AAAA,MAAA,CACjB;AAAA,IAAA;AAAA,EACV;AAGK,SAAA,SAAS,IAAI,OAAO;AAC7B;AClIa,MAAA,gBAAgB,OAAO,QAAgB,aAAqB;AAEvE,QAAM,QAAQ,MAAM,GAAG,SAAS,QAAQ,MAAM;AAC9C,QAAM,EAAE,MAAM,QAAQC,QAAM,QAAQ;AAEpC,MAAI,UAAU;AACd,MAAI,UAAU;AAEP,SAAA,MAAM,SAAS,OAAO,GAAG;AAC9B,cAAU,GAAG,IAAI,IAAI,OAAO,IAAI,GAAG;AACnC;AAAA,EAAA;AAGK,SAAA;AACT;ACFA,MAAM,oBAAoB;AAC1B,MAAM,4BAA4B,OAAK;AAEvC,MAAM,kBAAkB,CAAC,UAAyB,OAAe;AAE/D,MAAI,QAAQ;AACZ,MAAI,QAAQ;AAER,MAAA;AAEJ,QAAM,YAAY,cAAc,KAAK,QAAQ,IAAI,GAAG,YAAY,CAAC;AAE3D,QAAA,mBAAmB,CAACC,YAA0B;AAClD,UAAM,SAASA,QAAO,YAAY,cAAc,yBAAyB;AACzE,QAAI,QAAQ;AAIVA,cAAO,GAAG,KAAK;AAAA,QACb,MAAM;AAAA,QACN,SAAS,MAAM,KAAK,OAAO,UAAU,QAAQ,EAAE,IAAI,CAAQ,SAAA;AAAA,UACzD,MAAM;AAAA,UACN,WAAW,KAAK,IAAI;AAAA,UACpB,MAAM,IAAI;AAAA,UACV,cAAc,IAAI;AAAA,QAAA,EAClB;AAAA,MAAA,CACH;AAEM,aAAA;AAAA,IAAA;AAAA,EAEX;AAEO,SAAA;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO,SAAS,KAAK;AACnB,cAAQ,IAAI,SAAS;AACb,cAAA,CAAC,CAAC,IAAI;AACJ,UAAI,YAAY;AAEnB,aAAA;AAAA,QACL,cAAc;AAAA,UACZ,SAAS,CAAE,0BAA0B,cAAe;AAAA,QAAA;AAAA,MAExD;AAAA,IACF;AAAA,IACA,aAAa;AACX,WAAK,aAAa,SAAS;AAAA,IAC7B;AAAA,IACA,UAAU,MAAM,IAAI;AAClB,YAAM,CAAC,MAAM,KAAK,IAAI,GAAG,MAAM,GAAG;AAClC,UAAI,UAAU,SAAS;AACjB,YAAA,KAAK,SAAS,aAAa,GAAG;AACzB,iBAAA;AAAA,YACL,MAAM,KAAK,QAAQ,eAAe,yBAAyB;AAAA,YAC3D,KAAK;AAAA,UACP;AAAA,QAAA;AAAA,MACF;AAEF,UAAI,KAAK,SAAS,aAAa,KAAK,MAAM,SAAS,OAAO,GAAG;AACrD,cAAA,OAAOD,QAAM,IAAI,EAAE;AACzB,eAAO,oBAAoB,MAAM,SAAS,OAAO,IAAI;AAAA,MAAA;AAAA,IAEzD;AAAA,IACA,UAAU,IAAI;AACR,UAAA,OAAO,kBAA0B,QAAA;AAAA,IACvC;AAAA,IACA,MAAM,KAAK,IAAI;AACb,UAAI,OAAO,2BAA2B;AACpC,eAAO,MAAM,cAAc,MAAM,WAAW,KAAK;AAAA,MAAA;AAAA,IAErD;AAAA,IACA,gBAAgB,SAAS;AACd,eAAA;AAUT,aAAO,YAAY,IAAI,eAAe,OAAO,KAAK,KAAK,SAAS;;AAC9D,aAAID,MAAA,IAAI,QAAJ,gBAAAA,IAAS,WAAW,aAAa;AACnC,gBAAM,OAAO,QAAQ,SAAS,IAAI,GAAG,EAAE;AACvC,cAAI,CAAC,GAAG,WAAW,IAAI,GAAG;AACxB,gBAAI,aAAa;AACjB,mBAAO,IAAI,IAAI,QAAQ,IAAI,GAAG,YAAY;AAAA,UAAA;AAE5C,iBAAO,GAAG,iBAAiB,IAAI,EAAE,KAAK,GAAG;AAAA,QAAA;AAE3C,cAAM,SAAS,CAAC;AAChB,uBAAe,SAAS,KAAK;AAC3B,iBAAO,KAAK,KAAK;AAAA,QAAA;AAEb,cAAA,OAAO,OAAO,OAAO,MAAM;AAE7B,YAAA,IAAI,QAAQ,WAAW;AACzB,aAAG,UAAU,QAAQ,cAAc,GAAG,EAAE,WAAW,MAAM;AACzD,gBAAM,aAAc,IAAI,QAAQ,aAAa,KAAgB;AAC7D,gBAAM,WAAW,MAAM,cAAc,QAAQ,cAAc,GAAG,UAAU;AAClE,gBAAA,GAAG,SAAS,UAAU,QAAQ,gBAAgB,QAAQ,EAAE,GAAG,IAAI;AAErE,cACG,UAAU,gBAAgB,kBAAkB,EAC5C,IAAI,KAAK,UAAU,EAAE,KAAK,sBAAsB,QAAQ,IAAI,MAAM,WAAA,CAAY,CAAC;AAAA,QAAA;AAGhF,YAAA,IAAI,QAAQ,SAAS;AACvB,aAAG,UAAU,QAAQ,aAAa,GAAG,EAAE,WAAW,MAAM;AACxD,gBAAM,MAAM,KAAK,MAAM,KAAK,SAAS,OAAO,CAAC;AAC7C,gBAAM,WAAW,EAAE,SAAS,IAAI,QAAQ;AACxC,gBAAM,GAAG,SAAS,UAAU,QAAQ,eAAe,IAAI,IAAI,WAAW,OAAO,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,QAAA;AAEnH;AAAA,MAAA,CACD;AAAA,IAEH;AAAA,IACA,YAAY,IAAI,QAAQ;AACtB,UAAI,UAAU,GAAG,WAAW,SAAS,GAAG;AACtC,YAAI,QAAQ;AACJ,gBAAA,SAAS,iBAAiB,MAAM;AACtC,cAAI,WAAW,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AACtE,mBAAO,aAAa,MAAM;AAAA,UAAA;AAAA,QAC5B;AAAA,MACF;AAAA,IAEJ;AAAA,IACA,gBAAgB,KAAK;AACnB,YAAM,EAAE,MAAM,SAAS,QAAAE,QAAW,IAAA;AAC9B,UAAA,KAAK,WAAW,SAAS,GAAG;AACxB,cAAA,SAAS,iBAAiBA,OAAM;AACtC,YAAI,QAAQ;AACH,iBAAA,CAAE,GAAG,SAAS,MAAO;AAAA,QAAA;AAAA,MAC9B;AAAA,IAEJ;AAAA,IACA,oBAAoB;AAAA,MAClB,OAAO;AAAA,MACP,MAAM,QAAQ,MAAM,KAAK;;AACvB,YAAI,CAAC,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AAC3C,iBAAA;AAAA,QAAA;AAGT,YAAI,MAAM;AACV,YAAI,OAAO;AACT,gBAAM,gBAAcF,MAAA,IAAI,gBAAJ,gBAAAA,IAAiB,MAAM,OAAM;AACjD,gBAAM,QAAQ,GAAG,YAAY,QAAQ,aAAa,CAAC;AACnD,gBAAM,iBAAiB,MAAM,IAAI,UAAQC,QAAM,IAAI,EAAE,IAAI;AAEzD,cAAI,UAAiB,CAAC;AAClB,cAAA,eAAe,SAAS,WAAW,GAAG;AAClC,kBAAA,WAAW,GAAG,aAAa,QAAQ,eAAe,WAAW,OAAO,GAAG,OAAO;AAC1E,sBAAA,KAAK,MAAM,QAAQ,EAAE;AAAA,UAAA;AAGjC,gBAAM,QAAQ;AAAA,YACZ;AAAA,YACA,KAAK;AAAA,cACH;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAEA,gBAAM,WAAW;AAAA;AAAA,2BAEA,KAAK,UAAU,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtC,gBAAM,IAAI,QAAQ,UAAU,aAAa,QAAQ;AAAA,QAAA;AAE5C,eAAA;AAAA,MAAA;AAAA,IACT;AAAA,EAEJ;AACF;"}
|