@lark-apaas/coding-preset-vite-react 0.1.1-alpha.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +13 -0
  2. package/lib/index.d.ts +52 -0
  3. package/lib/index.d.ts.map +1 -0
  4. package/lib/index.js +410 -0
  5. package/lib/index.js.map +1 -0
  6. package/lib/plugins/capabilities.d.ts +23 -0
  7. package/lib/plugins/capabilities.d.ts.map +1 -0
  8. package/lib/plugins/capabilities.js +151 -0
  9. package/lib/plugins/capabilities.js.map +1 -0
  10. package/lib/plugins/dev-logs.d.ts +44 -0
  11. package/lib/plugins/dev-logs.d.ts.map +1 -0
  12. package/lib/plugins/dev-logs.js +544 -0
  13. package/lib/plugins/dev-logs.js.map +1 -0
  14. package/lib/plugins/error-overlay.d.ts +19 -0
  15. package/lib/plugins/error-overlay.d.ts.map +1 -0
  16. package/lib/plugins/error-overlay.js +136 -0
  17. package/lib/plugins/error-overlay.js.map +1 -0
  18. package/lib/plugins/fonts-mirror.d.ts +14 -0
  19. package/lib/plugins/fonts-mirror.d.ts.map +1 -0
  20. package/lib/plugins/fonts-mirror.js +70 -0
  21. package/lib/plugins/fonts-mirror.js.map +1 -0
  22. package/lib/plugins/health.d.ts +19 -0
  23. package/lib/plugins/health.d.ts.map +1 -0
  24. package/lib/plugins/health.js +36 -0
  25. package/lib/plugins/health.js.map +1 -0
  26. package/lib/plugins/hmr-timing.d.ts +13 -0
  27. package/lib/plugins/hmr-timing.d.ts.map +1 -0
  28. package/lib/plugins/hmr-timing.js +93 -0
  29. package/lib/plugins/hmr-timing.js.map +1 -0
  30. package/lib/plugins/html-minify.d.ts +18 -0
  31. package/lib/plugins/html-minify.d.ts.map +1 -0
  32. package/lib/plugins/html-minify.js +100 -0
  33. package/lib/plugins/html-minify.js.map +1 -0
  34. package/lib/plugins/module-alias.d.ts +12 -0
  35. package/lib/plugins/module-alias.d.ts.map +1 -0
  36. package/lib/plugins/module-alias.js +78 -0
  37. package/lib/plugins/module-alias.js.map +1 -0
  38. package/lib/plugins/og-meta.d.ts +21 -0
  39. package/lib/plugins/og-meta.d.ts.map +1 -0
  40. package/lib/plugins/og-meta.js +60 -0
  41. package/lib/plugins/og-meta.js.map +1 -0
  42. package/lib/plugins/polyfill.d.ts +11 -0
  43. package/lib/plugins/polyfill.d.ts.map +1 -0
  44. package/lib/plugins/polyfill.js +140 -0
  45. package/lib/plugins/polyfill.js.map +1 -0
  46. package/lib/plugins/routes.d.ts +26 -0
  47. package/lib/plugins/routes.d.ts.map +1 -0
  48. package/lib/plugins/routes.js +265 -0
  49. package/lib/plugins/routes.js.map +1 -0
  50. package/lib/plugins/slardar.d.ts +24 -0
  51. package/lib/plugins/slardar.d.ts.map +1 -0
  52. package/lib/plugins/slardar.js +74 -0
  53. package/lib/plugins/slardar.js.map +1 -0
  54. package/lib/plugins/static-assets.d.ts +10 -0
  55. package/lib/plugins/static-assets.d.ts.map +1 -0
  56. package/lib/plugins/static-assets.js +307 -0
  57. package/lib/plugins/static-assets.js.map +1 -0
  58. package/lib/plugins/view-context.d.ts +22 -0
  59. package/lib/plugins/view-context.d.ts.map +1 -0
  60. package/lib/plugins/view-context.js +165 -0
  61. package/lib/plugins/view-context.js.map +1 -0
  62. package/lib/plugins/vite-client-patch.d.ts +4 -0
  63. package/lib/plugins/vite-client-patch.d.ts.map +1 -0
  64. package/lib/plugins/vite-client-patch.js +37 -0
  65. package/lib/plugins/vite-client-patch.js.map +1 -0
  66. package/lib/plugins/ws-watchdog.d.ts +22 -0
  67. package/lib/plugins/ws-watchdog.d.ts.map +1 -0
  68. package/lib/plugins/ws-watchdog.js +103 -0
  69. package/lib/plugins/ws-watchdog.js.map +1 -0
  70. package/lib/polyfills/index.d.ts +15 -0
  71. package/lib/polyfills/index.d.ts.map +1 -0
  72. package/lib/polyfills/index.js +36 -0
  73. package/lib/polyfills/index.js.map +1 -0
  74. package/lib/utils/normalize-base-path.d.ts +37 -0
  75. package/lib/utils/normalize-base-path.d.ts.map +1 -0
  76. package/lib/utils/normalize-base-path.js +57 -0
  77. package/lib/utils/normalize-base-path.js.map +1 -0
  78. package/lib/utils/snapdom-proxy.d.ts +12 -0
  79. package/lib/utils/snapdom-proxy.d.ts.map +1 -0
  80. package/lib/utils/snapdom-proxy.js +75 -0
  81. package/lib/utils/snapdom-proxy.js.map +1 -0
  82. package/package.json +9 -15
  83. package/dist/index.d.ts +0 -320
  84. package/dist/index.js +0 -1941
  85. package/dist/index.js.map +0 -1
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.errorOverlayPlugin = errorOverlayPlugin;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const OVERLAY_PATH = '/@error-overlay.js';
40
+ /**
41
+ * 解析 overlay 客户端脚本路径。
42
+ *
43
+ * 包发布后目录结构:
44
+ * lib/plugins/error-overlay.js ← 该文件运行时位置
45
+ * src/overlay/*.js ← 静态资源(package.json files 字段包含)
46
+ *
47
+ * 开发时(vitest 直接跑 src):__dirname 是 src/plugins/,跨同级 → src/overlay。
48
+ */
49
+ function resolveClientScriptPath() {
50
+ const candidates = [
51
+ path.resolve(__dirname, '../../src/overlay/vite-client.js'), // lib/plugins → src/overlay
52
+ path.resolve(__dirname, '../overlay/vite-client.js'), // src/plugins → src/overlay
53
+ ];
54
+ return candidates.find((p) => fs.existsSync(p)) ?? null;
55
+ }
56
+ function processClientScript(clientBasePath) {
57
+ const scriptPath = resolveClientScriptPath();
58
+ if (!scriptPath)
59
+ return '// error-overlay client script not found';
60
+ let code = fs.readFileSync(scriptPath, 'utf-8');
61
+ // 客户端脚本里被替换的几个变量(与原 preset 行为对齐)
62
+ const env = {
63
+ 'process.env.FORCE_FRAMEWORK_DOMAIN_MAIN': JSON.stringify(process.env.FORCE_FRAMEWORK_DOMAIN_MAIN ?? ''),
64
+ 'process.env.CLIENT_BASE_PATH': JSON.stringify(clientBasePath),
65
+ };
66
+ for (const [k, v] of Object.entries(env)) {
67
+ code = code.replace(new RegExp(k.replace(/\./g, '\\.'), 'g'), v);
68
+ }
69
+ return code;
70
+ }
71
+ /**
72
+ * 自定义 HMR error overlay。
73
+ *
74
+ * - 关掉 Vite 原生 overlay(`server.hmr.overlay = false`)
75
+ * - dev middleware 暴露 `/@error-overlay.js`(按 clientBasePath 加前缀)
76
+ * - HTML head 注入 `<script type="module" src="...">`
77
+ *
78
+ * 只在 dev 期生效;build 时整个 `configureServer` / `transformIndexHtml` 分支不触发。
79
+ */
80
+ function errorOverlayPlugin(options = {}) {
81
+ const { enabled = true, clientBasePath = '' } = options;
82
+ const overlayPath = clientBasePath + OVERLAY_PATH;
83
+ return {
84
+ name: 'miaoda-error-overlay',
85
+ enforce: 'pre',
86
+ // 关掉 Vite 原生 overlay
87
+ config(config) {
88
+ if (!enabled)
89
+ return;
90
+ return {
91
+ server: {
92
+ ...config.server,
93
+ hmr: config.server?.hmr === false
94
+ ? false
95
+ : {
96
+ ...(typeof config.server?.hmr === 'object' ? config.server.hmr : {}),
97
+ overlay: false,
98
+ },
99
+ },
100
+ };
101
+ },
102
+ configureServer(server) {
103
+ if (!enabled)
104
+ return;
105
+ server.middlewares.use((req, res, next) => {
106
+ if (req.url !== overlayPath)
107
+ return next();
108
+ try {
109
+ const code = processClientScript(clientBasePath);
110
+ res.setHeader('Content-Type', 'application/javascript');
111
+ res.setHeader('Cache-Control', 'no-cache');
112
+ res.end(code);
113
+ }
114
+ catch (e) {
115
+ console.error('[miaoda-error-overlay] serve failed:', e);
116
+ res.statusCode = 500;
117
+ res.end(`// error: ${e instanceof Error ? e.message : String(e)}`);
118
+ }
119
+ });
120
+ },
121
+ transformIndexHtml(html) {
122
+ if (!enabled)
123
+ return html;
124
+ const tags = [
125
+ {
126
+ tag: 'script',
127
+ attrs: { type: 'module', src: overlayPath },
128
+ injectTo: 'head',
129
+ },
130
+ ];
131
+ return { html, tags };
132
+ },
133
+ };
134
+ }
135
+ exports.default = errorOverlayPlugin;
136
+ //# sourceMappingURL=error-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-overlay.js","sourceRoot":"","sources":["../../src/plugins/error-overlay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface FontsMirrorPluginOptions {
3
+ /** Mirror 完整基址,默认 `https://miaoda.feishu.cn/fonts` */
4
+ mirror?: string;
5
+ /** 关闭(调试时兜底) */
6
+ disabled?: boolean;
7
+ /** 命中时打 warning(便于找出源码里的旧引用) */
8
+ warnOnMatch?: boolean;
9
+ /** 排除 id 子串或正则 */
10
+ exclude?: (string | RegExp)[];
11
+ }
12
+ export declare function fontsMirrorPlugin(options?: FontsMirrorPluginOptions): Plugin | false;
13
+ export default fontsMirrorPlugin;
14
+ //# sourceMappingURL=fonts-mirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts-mirror.d.ts","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAgBnC,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB;IAClB,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,GAAG,KAAK,CAwDxF;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fontsMirrorPlugin = fontsMirrorPlugin;
4
+ /**
5
+ * 编译时把 `fonts.googleapis.com` / `fonts.gstatic.com` 全量改写到妙搭字体代理,
6
+ * 屏蔽 Google Fonts 在内网 / 部分客户端不可达导致的白屏。
7
+ *
8
+ * - 命中文件类型:html / css / scss / less / styl / js / ts / tsx / vue / svelte 等
9
+ * - URL pathname 保持与 Google Fonts 一致(`/css`、`/css2?family=...&wght=...`),
10
+ * 任意模型输出形式都能被代理;只换域名
11
+ * - 关闭:`{ disabled: true }` 或环境变量 `MIAODA_FONTS_MIRROR_OFF=1`
12
+ */
13
+ const DEFAULT_MIRROR = 'https://miaoda.feishu.cn/fonts';
14
+ const GOOGLE_FONTS_RE = /https?:\/\/fonts\.(googleapis|gstatic)\.com/g;
15
+ const HAS_GOOGLE_FONTS = /fonts\.(googleapis|gstatic)\.com/;
16
+ const TRANSFORM_EXT = /\.(html|css|scss|sass|less|styl|js|jsx|ts|tsx|mjs|cjs|vue|svelte)(\?|$)/;
17
+ function fontsMirrorPlugin(options = {}) {
18
+ const envDisabled = process.env.MIAODA_FONTS_MIRROR_OFF === '1';
19
+ if (options.disabled || envDisabled)
20
+ return false;
21
+ const mirror = options.mirror ?? DEFAULT_MIRROR;
22
+ const warn = options.warnOnMatch ?? false;
23
+ const exclude = options.exclude ?? [];
24
+ const shouldExclude = (id) => exclude.some((p) => (typeof p === 'string' ? id.includes(p) : p.test(id)));
25
+ const stats = { files: 0, occurrences: 0 };
26
+ return {
27
+ name: 'miaoda-fonts-mirror',
28
+ enforce: 'pre',
29
+ buildStart() {
30
+ stats.files = 0;
31
+ stats.occurrences = 0;
32
+ },
33
+ transformIndexHtml(html) {
34
+ if (!HAS_GOOGLE_FONTS.test(html))
35
+ return html;
36
+ const matches = html.match(GOOGLE_FONTS_RE);
37
+ const replaced = html.replace(GOOGLE_FONTS_RE, mirror);
38
+ stats.files += 1;
39
+ stats.occurrences += matches?.length ?? 0;
40
+ if (warn) {
41
+ console.warn(`[miaoda-fonts-mirror] rewrote ${matches?.length ?? 0} occurrence(s) in index.html`);
42
+ }
43
+ return replaced;
44
+ },
45
+ transform(code, id) {
46
+ if (!TRANSFORM_EXT.test(id))
47
+ return null;
48
+ if (shouldExclude(id))
49
+ return null;
50
+ if (!HAS_GOOGLE_FONTS.test(code))
51
+ return null;
52
+ const matches = code.match(GOOGLE_FONTS_RE);
53
+ if (!matches)
54
+ return null;
55
+ stats.files += 1;
56
+ stats.occurrences += matches.length;
57
+ if (warn) {
58
+ console.warn(`[miaoda-fonts-mirror] rewrote ${matches.length} occurrence(s) in ${id}`);
59
+ }
60
+ return { code: code.replace(GOOGLE_FONTS_RE, mirror), map: null };
61
+ },
62
+ closeBundle() {
63
+ if (stats.files > 0) {
64
+ console.log(`[miaoda-fonts-mirror] ✓ rewrote ${stats.occurrences} occurrence(s) across ${stats.files} file(s) → ${mirror}`);
65
+ }
66
+ },
67
+ };
68
+ }
69
+ exports.default = fontsMirrorPlugin;
70
+ //# sourceMappingURL=fonts-mirror.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts-mirror.js","sourceRoot":"","sources":["../../src/plugins/fonts-mirror.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * 给妙搭沙箱外壳提供统一的 health endpoint。
4
+ *
5
+ * 协议(飞书文档 - 妙搭应用 Health Check 接口规范):
6
+ * - HTTP connection refused / timeout → dev server 没起来 → 外壳重启沙箱
7
+ * - 200 + { ready: true } → 应用已就绪
8
+ * - 200 + { ready: false } → 还在启动,按 error 描述判断重试
9
+ *
10
+ * 不归本接口管:
11
+ * - vite compile error / runtime error / 资源加载失败 → 浏览器侧自己上报
12
+ */
13
+ export interface HealthMiddlewarePluginOptions {
14
+ /** Health endpoint 路径,默认 `/dev/health`。 */
15
+ endpoint?: string;
16
+ }
17
+ export declare function healthMiddlewarePlugin(options?: HealthMiddlewarePluginOptions): Plugin;
18
+ export default healthMiddlewarePlugin;
19
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/plugins/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAElD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,6BAA6B;IAC5C,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,6BAAkC,GAAG,MAAM,CA+B1F;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.healthMiddlewarePlugin = healthMiddlewarePlugin;
4
+ function healthMiddlewarePlugin(options = {}) {
5
+ const endpoint = options.endpoint ?? '/dev/health';
6
+ let viteReady = false;
7
+ return {
8
+ name: 'miaoda-health',
9
+ apply: 'serve',
10
+ configureServer(server) {
11
+ const httpServer = server.httpServer;
12
+ // 三种状态:
13
+ // - middleware 模式(无 httpServer) → 认为已就绪
14
+ // - httpServer.listening 已 true → 已就绪
15
+ // - 否则注册一次 listening 回调
16
+ if (!httpServer || httpServer.listening) {
17
+ viteReady = true;
18
+ }
19
+ else {
20
+ httpServer.once('listening', () => {
21
+ viteReady = true;
22
+ });
23
+ }
24
+ server.middlewares.use(endpoint, (req, res, next) => {
25
+ if (req.method && req.method !== 'GET')
26
+ return next();
27
+ res.setHeader('Content-Type', 'application/json');
28
+ res.setHeader('Cache-Control', 'no-store');
29
+ res.statusCode = 200;
30
+ res.end(JSON.stringify({ ready: viteReady }));
31
+ });
32
+ },
33
+ };
34
+ }
35
+ exports.default = healthMiddlewarePlugin;
36
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/plugins/health.ts"],"names":[],"mappings":";;AAkBA,wDA+BC;AA/BD,SAAgB,sBAAsB,CAAC,UAAyC,EAAE;IAChF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,OAAO;QAEd,eAAe,CAAC,MAAqB;YACnC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YACrC,QAAQ;YACR,2CAA2C;YAC3C,4CAA4C;YAC5C,0BAA0B;YAC1B,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;gBACxC,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;oBAChC,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;gBAClD,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK;oBAAE,OAAO,IAAI,EAAE,CAAC;gBACtD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;gBAClD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAC3C,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED,kBAAe,sBAAsB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * HMR 计时插件(Vite 8+)。
4
+ *
5
+ * 监听文件变更记录起始时间,在 `hotUpdate` 钩子里算出耗时 + 文件数 + 累计大小,
6
+ * 通过 `server.hot.send({ type: 'custom', event: 'hmr-timing' })` 广播给浏览器;
7
+ * 浏览器侧由 inspector / dev panel 收消息展示。
8
+ *
9
+ * dev 期专用;build 完全不挂 hook。
10
+ */
11
+ export declare function hmrTimingPlugin(): Plugin;
12
+ export default hmrTimingPlugin;
13
+ //# sourceMappingURL=hmr-timing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-timing.d.ts","sourceRoot":"","sources":["../../src/plugins/hmr-timing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAmC,MAAM,MAAM,CAAC;AAIpE;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,MAAM,CA+CxC;AAED,eAAe,eAAe,CAAC"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.hmrTimingPlugin = hmrTimingPlugin;
37
+ const fs = __importStar(require("node:fs"));
38
+ const VALID_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx', '.css', '.json', '.html'];
39
+ /**
40
+ * HMR 计时插件(Vite 8+)。
41
+ *
42
+ * 监听文件变更记录起始时间,在 `hotUpdate` 钩子里算出耗时 + 文件数 + 累计大小,
43
+ * 通过 `server.hot.send({ type: 'custom', event: 'hmr-timing' })` 广播给浏览器;
44
+ * 浏览器侧由 inspector / dev panel 收消息展示。
45
+ *
46
+ * dev 期专用;build 完全不挂 hook。
47
+ */
48
+ function hmrTimingPlugin() {
49
+ let startTime = 0;
50
+ const changedFiles = new Set();
51
+ let server = null;
52
+ return {
53
+ name: 'miaoda-hmr-timing',
54
+ configureServer(devServer) {
55
+ server = devServer;
56
+ server.watcher.on('change', (file) => {
57
+ startTime = Date.now();
58
+ changedFiles.add(file);
59
+ });
60
+ },
61
+ hotUpdate(_ctx) {
62
+ if (!server || changedFiles.size === 0)
63
+ return;
64
+ const duration = Date.now() - startTime;
65
+ const cwd = process.cwd();
66
+ const validFiles = [...changedFiles]
67
+ .map((f) => f.replace(cwd, '').replace(/\\/g, '/'))
68
+ .filter((p) => {
69
+ if (!p)
70
+ return false;
71
+ if (p.includes('/node_modules/'))
72
+ return false;
73
+ return VALID_EXTENSIONS.some((ext) => p.toLowerCase().endsWith(ext));
74
+ });
75
+ const totalSize = validFiles.reduce((sum, p) => {
76
+ try {
77
+ return sum + fs.statSync(cwd + p).size;
78
+ }
79
+ catch {
80
+ return sum;
81
+ }
82
+ }, 0);
83
+ server.hot.send({
84
+ type: 'custom',
85
+ event: 'hmr-timing',
86
+ data: { duration, fileCount: validFiles.length, fileTotalSize: totalSize },
87
+ });
88
+ changedFiles.clear();
89
+ },
90
+ };
91
+ }
92
+ exports.default = hmrTimingPlugin;
93
+ //# sourceMappingURL=hmr-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-timing.js","sourceRoot":"","sources":["../../src/plugins/hmr-timing.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,0CA+CC;AA7DD,4CAA8B;AAG9B,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAElF;;;;;;;;GAQG;AACH,SAAgB,eAAe;IAC7B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,IAAI,MAAM,GAAyB,IAAI,CAAC;IAExC,OAAO;QACL,IAAI,EAAE,mBAAmB;QAEzB,eAAe,CAAC,SAAwB;YACtC,MAAM,GAAG,SAAS,CAAC;YACnB,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACnC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,SAAS,CAAC,IAAsB;YAC9B,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO;YAE/C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAE1B,MAAM,UAAU,GAAG,CAAC,GAAG,YAAY,CAAC;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;iBAClD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBACZ,IAAI,CAAC,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACrB,IAAI,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC/C,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;YAEL,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC7C,IAAI,CAAC;oBACH,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC,EAAE,CAAC,CAAC,CAAC;YAEN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,YAAY;gBACnB,IAAI,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE;aAC3E,CAAC,CAAC;YAEH,YAAY,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,kBAAe,eAAe,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * 压缩 HTML,同时保护 HBS(Handlebars)占位符。
4
+ *
5
+ * `{{csrfToken}}` / `{{{appAvatar}}}` 这类占位符是部署运行时(vefaas)替换的,
6
+ * 直接交给 html-minifier-terser 会被解析破坏。先把它们抽出来用 `__HBS_<i>__`
7
+ * 占位,压缩完再放回去。
8
+ */
9
+ export declare function minifyHtmlWithHbsProtection(html: string): Promise<string>;
10
+ /**
11
+ * 仅 build 期生效的 HTML 压缩插件。
12
+ *
13
+ * dev 期完全 no-op(不挂 hook、不读盘);
14
+ * build 完毕时(closeBundle)读 `outDir/index.html` 压缩后写回。
15
+ */
16
+ export declare function htmlMinifyPlugin(): Plugin;
17
+ export default htmlMinifyPlugin;
18
+ //# sourceMappingURL=html-minify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-minify.d.ts","sourceRoot":"","sources":["../../src/plugins/html-minify.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB/E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CA4BzC;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.minifyHtmlWithHbsProtection = minifyHtmlWithHbsProtection;
37
+ exports.htmlMinifyPlugin = htmlMinifyPlugin;
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const html_minifier_terser_1 = require("html-minifier-terser");
41
+ /**
42
+ * 压缩 HTML,同时保护 HBS(Handlebars)占位符。
43
+ *
44
+ * `{{csrfToken}}` / `{{{appAvatar}}}` 这类占位符是部署运行时(vefaas)替换的,
45
+ * 直接交给 html-minifier-terser 会被解析破坏。先把它们抽出来用 `__HBS_<i>__`
46
+ * 占位,压缩完再放回去。
47
+ */
48
+ async function minifyHtmlWithHbsProtection(html) {
49
+ const placeholders = [];
50
+ let processed = html.replace(/\{\{\{?.+?\}\}\}?/g, (match) => {
51
+ const i = placeholders.length;
52
+ placeholders.push(match);
53
+ return `__HBS_${i}__`;
54
+ });
55
+ processed = await (0, html_minifier_terser_1.minify)(processed, {
56
+ collapseWhitespace: true,
57
+ removeComments: true,
58
+ removeRedundantAttributes: true,
59
+ removeEmptyAttributes: true,
60
+ minifyCSS: true,
61
+ // 不压 JS:inline script 里可能引用了 HBS 占位符
62
+ minifyJS: false,
63
+ });
64
+ return processed.replace(/__HBS_(\d+)__/g, (_, i) => placeholders[Number(i)]);
65
+ }
66
+ /**
67
+ * 仅 build 期生效的 HTML 压缩插件。
68
+ *
69
+ * dev 期完全 no-op(不挂 hook、不读盘);
70
+ * build 完毕时(closeBundle)读 `outDir/index.html` 压缩后写回。
71
+ */
72
+ function htmlMinifyPlugin() {
73
+ let config;
74
+ let isDev = false;
75
+ return {
76
+ name: 'miaoda-html-minify',
77
+ configResolved(resolvedConfig) {
78
+ config = resolvedConfig;
79
+ isDev = resolvedConfig.command === 'serve';
80
+ },
81
+ async closeBundle() {
82
+ if (isDev || !config)
83
+ return;
84
+ const htmlPath = path.resolve(config.build.outDir, 'index.html');
85
+ if (!fs.existsSync(htmlPath))
86
+ return;
87
+ try {
88
+ const source = fs.readFileSync(htmlPath, 'utf-8');
89
+ const minified = await minifyHtmlWithHbsProtection(source);
90
+ fs.writeFileSync(htmlPath, minified);
91
+ }
92
+ catch (e) {
93
+ // 单独捕获:minify 失败不应该把整个 build 拖崩,输出文件仍然是 Vite 写出的原版
94
+ console.warn(`[miaoda-html-minify] minify failed, keeping unminified HTML:`, e);
95
+ }
96
+ },
97
+ };
98
+ }
99
+ exports.default = htmlMinifyPlugin;
100
+ //# sourceMappingURL=html-minify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-minify.js","sourceRoot":"","sources":["../../src/plugins/html-minify.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,kEAmBC;AAQD,4CA4BC;AAnED,4CAA8B;AAC9B,gDAAkC;AAClC,+DAA8C;AAG9C;;;;;;GAMG;AACI,KAAK,UAAU,2BAA2B,CAAC,IAAY;IAC5D,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3D,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;QAC9B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,SAAS,CAAC,IAAI,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,SAAS,GAAG,MAAM,IAAA,6BAAM,EAAC,SAAS,EAAE;QAClC,kBAAkB,EAAE,IAAI;QACxB,cAAc,EAAE,IAAI;QACpB,yBAAyB,EAAE,IAAI;QAC/B,qBAAqB,EAAE,IAAI;QAC3B,SAAS,EAAE,IAAI;QACf,qCAAqC;QACrC,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,MAAsB,CAAC;IAC3B,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,OAAO;QACL,IAAI,EAAE,oBAAoB;QAE1B,cAAc,CAAC,cAAc;YAC3B,MAAM,GAAG,cAAc,CAAC;YACxB,KAAK,GAAG,cAAc,CAAC,OAAO,KAAK,OAAO,CAAC;QAC7C,CAAC;QAED,KAAK,CAAC,WAAW;YACf,IAAI,KAAK,IAAI,CAAC,MAAM;gBAAE,OAAO;YAE7B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YACjE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO;YAErC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClD,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC,MAAM,CAAC,CAAC;gBAC3D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,mDAAmD;gBACnD,OAAO,CAAC,IAAI,CAAC,8DAA8D,EAAE,CAAC,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,kBAAe,gBAAgB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * 把业务工程里 `import 'clsx'` / `import 'echarts'` / `import 'echarts-for-react'`
4
+ * 这种裸 import 强制指向 preset 自带的 ESM wrapper(`src/module-alias/*.mjs`)。
5
+ *
6
+ * 解决的问题:第三方扩展(如 `echarts-wordcloud`)自带独立 echarts 副本时,
7
+ * 业务代码和扩展跑在两份 echarts 实例上,wordcloud 注册不到主实例 → 渲染丢失。
8
+ * Wrapper 强制所有 echarts 指针指向 preset 自带版本,全栈共用一份实例。
9
+ */
10
+ export declare function moduleAliasPlugin(): Plugin;
11
+ export default moduleAliasPlugin;
12
+ //# sourceMappingURL=module-alias.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-alias.d.ts","sourceRoot":"","sources":["../../src/plugins/module-alias.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA8B1C;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.moduleAliasPlugin = moduleAliasPlugin;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ /**
40
+ * 把业务工程里 `import 'clsx'` / `import 'echarts'` / `import 'echarts-for-react'`
41
+ * 这种裸 import 强制指向 preset 自带的 ESM wrapper(`src/module-alias/*.mjs`)。
42
+ *
43
+ * 解决的问题:第三方扩展(如 `echarts-wordcloud`)自带独立 echarts 副本时,
44
+ * 业务代码和扩展跑在两份 echarts 实例上,wordcloud 注册不到主实例 → 渲染丢失。
45
+ * Wrapper 强制所有 echarts 指针指向 preset 自带版本,全栈共用一份实例。
46
+ */
47
+ function moduleAliasPlugin() {
48
+ // 兼容两种运行时布局:
49
+ // - 编译后:__dirname = lib/plugins/,wrapper 在 ../../src/module-alias/
50
+ // - src 直跑(vitest):__dirname = src/plugins/,wrapper 在 ../module-alias/
51
+ const candidates = [
52
+ path.resolve(__dirname, '../../src/module-alias'),
53
+ path.resolve(__dirname, '../module-alias'),
54
+ ];
55
+ function resolveAlias(name) {
56
+ for (const dir of candidates) {
57
+ const p = path.join(dir, `${name}.mjs`);
58
+ if (fs.existsSync(p))
59
+ return p;
60
+ }
61
+ return null;
62
+ }
63
+ return {
64
+ name: 'miaoda-module-alias',
65
+ enforce: 'pre',
66
+ resolveId: {
67
+ filter: { id: /^(clsx|echarts|echarts-for-react)$/ },
68
+ handler(source, importer) {
69
+ // 别把 wrapper 自己内部的 import 又拐回 wrapper(死循环)
70
+ if (importer && importer.includes('module-alias'))
71
+ return null;
72
+ return resolveAlias(source);
73
+ },
74
+ },
75
+ };
76
+ }
77
+ exports.default = moduleAliasPlugin;
78
+ //# sourceMappingURL=module-alias.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-alias.js","sourceRoot":"","sources":["../../src/plugins/module-alias.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,8CA8BC;AA1CD,4CAA8B;AAC9B,gDAAkC;AAGlC;;;;;;;GAOG;AACH,SAAgB,iBAAiB;IAC/B,aAAa;IACb,qEAAqE;IACrE,yEAAyE;IACzE,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wBAAwB,CAAC;QACjD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC;KAC3C,CAAC;IAEF,SAAS,YAAY,CAAC,IAAY;QAChC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;YACxC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,KAAK;QAEd,SAAS,EAAE;YACT,MAAM,EAAE,EAAE,EAAE,EAAE,oCAAoC,EAAE;YACpD,OAAO,CAAC,MAAc,EAAE,QAA4B;gBAClD,2CAA2C;gBAC3C,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAC/D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,kBAAe,iBAAiB,CAAC"}