@linkdesk/plugin-sdk 0.1.38 → 0.1.40
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/README.md +2 -2
- package/dev-host/linkdesk-mock.generated.ts +1 -0
- package/dist/eslint/checks/dangling-names.d.ts +65 -0
- package/dist/eslint/checks/dangling-names.d.ts.map +1 -0
- package/dist/eslint/checks/dangling-names.js +469 -0
- package/dist/eslint/checks/dangling-names.js.map +1 -0
- package/dist/eslint/checks/retired-names.d.ts +46 -0
- package/dist/eslint/checks/retired-names.d.ts.map +1 -0
- package/dist/eslint/checks/retired-names.js +90 -0
- package/dist/eslint/checks/retired-names.js.map +1 -0
- package/dist/eslint/index.d.ts +11 -0
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +9 -0
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/lint.d.ts +22 -0
- package/dist/eslint/lint.d.ts.map +1 -1
- package/dist/eslint/lint.js +63 -1
- package/dist/eslint/lint.js.map +1 -1
- package/package.json +1 -1
- package/schemas/host-css-names.json +1099 -0
- package/schemas/host-reserved.json +13 -2
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ npm install -D @linkdesk/plugin-sdk
|
|
|
18
18
|
> 自动生成,**勿手改**——由 `scripts/generate-api-cheatsheet.mjs` 从 `@linkdesk/contracts` 的 `linkdesk.d.ts` 现读产出,
|
|
19
19
|
> `npm run check` 机械盯漂。完整签名与逐方法说明见 `linkdesk.d.ts` 本体(IDE 里可直接跳转)。
|
|
20
20
|
|
|
21
|
-
**15 个域接口 → 46 个命名空间 /
|
|
21
|
+
**15 个域接口 → 46 个命名空间 / 244 个方法**,全部经 `window.linkdesk.<命名空间>.<方法>` 调用。 (plus 1 deprecated alias/es `config`, not counted twice)
|
|
22
22
|
|
|
23
23
|
| Namespace | Methods | Method | Notes |
|
|
24
24
|
|:--|:--:|:--|:--|
|
|
@@ -55,7 +55,7 @@ npm install -D @linkdesk/plugin-sdk
|
|
|
55
55
|
| `lsp` | 4 | `spawn` `write` `dispose` `onData` | E5.6#14-lsp:LSP 桥——自动补全/F12/诊断/重命名 |
|
|
56
56
|
| `protocol` | 3 | `listProtocols` `getActiveProtocolId` `setActiveProtocolId` | E5.7#49:protocol——协议注册表(主进程直答) |
|
|
57
57
|
| `viewContainer` | 4 | `getViewContainer` `getViews` `getView` `registerView` | E5.7#58:viewContainer——真 IPC 查询/更新(问壳侧注册表) |
|
|
58
|
-
| `plugins` |
|
|
58
|
+
| `plugins` | 14 | `resolvePath` `resolveEntry`° `getCompatibility`° `listDirs`° `listAll`° `listDisabledDirs`° `readManifest`° `readAllManifests`° `packageDownload`° `packageExtract`° `packageCancel`° `packageUpdateCheck`° `packageStageUpdate`° `packageCommitUpdate`° | 插件发现——双端注入:resolvePath 双端同面 |
|
|
59
59
|
| `pluginManager` | 13 | `list` `enable` `disable` `uninstall` `install` `installWithProgress`° `reinstall` `getDisabled` `getUninstalled` `isDisabled` `update`° `checkUpdates`° `notifyManifestChanged`° | 插件管理——桥接 IpcBridgeHandler → loader 函数 |
|
|
60
60
|
| `bridge` ⚠️ | 4 | `onRequest` `respond` `broadcast` `notifyConfigChanged` | 壳↔插件通信中继——壳 preload 独有 |
|
|
61
61
|
| `pool` | 31 | `pushLayout` `onReady` `toggleDevTools` `onSidebarAction` `onTabAction` `onTabBarRects` `onDragPosition` `pushAdsorbHint` `onAdsorbIndex` `pushQuickPick` `onQuickPickAction` `pushDialog` `onDialogAction` `pushFloatingPanel` `onFloatingPanelAction` `onMemoryPressure` `createWindow` `closeWindow` `onWindowClosed` `onWindowBoundsChanged` `onLayout` `ready` `sidebarAction` `tabAction` `tabBarRects` `dragPosition` `onAdsorbHint` `adsorbIndex` `registerBeforeClose` `unregisterBeforeClose` `beforeClose` | 池控制——壳 preload:推送布局 + 注册池→壳动作回调 |
|
|
@@ -252,6 +252,7 @@ export const linkdeskMock: Record<string, unknown> = {
|
|
|
252
252
|
plugins: {
|
|
253
253
|
resolvePath: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.resolvePath", ..._args); return ""; },
|
|
254
254
|
resolveEntry: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.resolveEntry", ..._args); },
|
|
255
|
+
getCompatibility: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.getCompatibility", ..._args); },
|
|
255
256
|
listDirs: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.listDirs", ..._args); return []; },
|
|
256
257
|
listAll: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.listAll", ..._args); return []; },
|
|
257
258
|
listDisabledDirs: async (..._args: unknown[]) => { console.info("[linkdesk-mock] plugins.listDisabledDirs", ..._args); return []; },
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type CheckViolation } from "./scan.js";
|
|
2
|
+
import { type PluginIdResolution } from "./plugin-prefix.js";
|
|
3
|
+
/** 判级文案——作者面(00 总纲 §〇d:这一面允许「名字 + 文件:行 + 两步修法」) */
|
|
4
|
+
export declare const DANGLING_NAME_WHY: {
|
|
5
|
+
readonly jsClassname: string;
|
|
6
|
+
readonly cssAnimation: "`animation` 引用的关键帧在本方没有 `@keyframes` 定义 ⇒ **动画静默消失**(不报错、只是不动)。";
|
|
7
|
+
};
|
|
8
|
+
/** 随包下发的宿主 CSS 定义集(`schemas/host-css-names.json`,与壳运行时清单同一生成器) */
|
|
9
|
+
export interface HostCssNames {
|
|
10
|
+
version: number;
|
|
11
|
+
generatedFrom: string;
|
|
12
|
+
/** 宿主定义/提及的类名全集(裸定义全 ldk-* + 宿主加载的第三方 CSS 名) */
|
|
13
|
+
classes: string[];
|
|
14
|
+
/** 宿主关键帧名全集(@keyframes 定义 + 保留关键帧账) */
|
|
15
|
+
keyframes: string[];
|
|
16
|
+
reservedKeyframeCount: number;
|
|
17
|
+
}
|
|
18
|
+
/** 读随包宿主定义集;缺失/坏 ⇒ null(调用方 fail-closed 报「未核验」,⛔ 不许当 0 处通过) */
|
|
19
|
+
export declare function loadHostCssNames(file?: string): HostCssNames | null;
|
|
20
|
+
/** 一处悬空引用站点 */
|
|
21
|
+
export interface DanglingNameSite {
|
|
22
|
+
/** 工程相对路径(正斜杠) */
|
|
23
|
+
file: string;
|
|
24
|
+
/** 1-based */
|
|
25
|
+
line: number;
|
|
26
|
+
/** 被引用但两个定义集里都没有的名字 */
|
|
27
|
+
name: string;
|
|
28
|
+
/** 引用通道:JS className 字面量 / CSS animation 引用 */
|
|
29
|
+
via: "js-classname" | "css-animation";
|
|
30
|
+
}
|
|
31
|
+
export interface DanglingNameReport {
|
|
32
|
+
root: string;
|
|
33
|
+
pluginId: string | null;
|
|
34
|
+
/** 非 null ⇒ fail-closed(宿主定义集读不到 ⇒ 「未核验」,⛔ 不许当 0 处通过) */
|
|
35
|
+
error: string | null;
|
|
36
|
+
/** 宿主定义集规模(审计读数用;error 非 null 时为 0) */
|
|
37
|
+
hostClassCount: number;
|
|
38
|
+
hostKeyframeCount: number;
|
|
39
|
+
/** 产物/源码 JS 喊的 `ldk-*` 名站点数 */
|
|
40
|
+
ldkRefs: number;
|
|
41
|
+
/** CSS `animation:` 引用点数 */
|
|
42
|
+
kfRefs: number;
|
|
43
|
+
/** 射程外计数(含插值的模板 / 动态拼接——静态读不出,⛔ 不判) */
|
|
44
|
+
skipped: {
|
|
45
|
+
interp: number;
|
|
46
|
+
dynamic: number;
|
|
47
|
+
};
|
|
48
|
+
/** 非 `ldk-` 且两个定义集都没有的未判名数(自有命名空间 / DOM 钩子 / 第三方内联) */
|
|
49
|
+
notJudgedCount: number;
|
|
50
|
+
/** `ldk-*` 名只被包内自己满足(归 `plugin-prefix.ts` 前缀腿判红,本腿不判悬空) */
|
|
51
|
+
borrowedLdk: string[];
|
|
52
|
+
/** 悬空站点 */
|
|
53
|
+
dangling: DanglingNameSite[];
|
|
54
|
+
/** 腿报点 = fail-closed + 悬空 */
|
|
55
|
+
violations: CheckViolation[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 跑本仓悬空名判据(作者侧唯一入口)。返回结构化报告——**同一份实现,没有第二条判据路径**。
|
|
59
|
+
* ⚠️ `host` / `resolution` 可注入(单测用);缺省读随包 `schemas/host-css-names.json`。
|
|
60
|
+
*/
|
|
61
|
+
export declare function runDanglingNameCheck(root: string, opts?: {
|
|
62
|
+
host?: HostCssNames | null;
|
|
63
|
+
resolution?: PluginIdResolution;
|
|
64
|
+
}): DanglingNameReport;
|
|
65
|
+
//# sourceMappingURL=dangling-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dangling-names.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/dangling-names.ts"],"names":[],"mappings":"AA+CA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAQnB,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,mDAAmD;AACnD,eAAO,MAAM,iBAAiB;;;CAMpB,CAAC;AAEX,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAWD,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,MAA4B,GAAG,YAAY,GAAG,IAAI,CAexF;AAuLD,eAAe;AACf,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc;IACd,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,GAAG,EAAE,cAAc,GAAG,eAAe,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW;IACX,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,6BAA6B;IAC7B,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAaD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAAO,GACzE,kBAAkB,CA6GpB"}
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-css-namespace 腿·**插件域悬空名判据**(E6#119 · 2026-09-19)。
|
|
3
|
+
*
|
|
4
|
+
* ── 规则一句话 ──
|
|
5
|
+
* 插件产物是**冻结的快照**:发布那一刻的名字被烘进 bundle,之后宿主改名/删除它不会知道
|
|
6
|
+
* (实证:`.ldk-input` 那一路,`settings` v1.0.12 → v1.0.13 输入框丢底色/边框/圆角,**零报错**)。
|
|
7
|
+
* 本腿把格 1 那把尺子(壳仓 `scripts/plugin-dangling-name-audit.mjs`,E6#114)搬到**作者自己的仓里**:
|
|
8
|
+
* 作者在他自己的 CI / 本地就能跑出红黄,不必来问维护者——「让第三方插件作者自由制造插件」的机械兑现。
|
|
9
|
+
* 规则正文 = `docs/02-Electron架构/E6_插件生态与发布/插件兼容机械化/06-任务-判据铺开.md`。
|
|
10
|
+
*
|
|
11
|
+
* ── 🔴 这不是第二把尺子(三份同口径)──
|
|
12
|
+
* 判据口径的唯一真相源 = 壳仓 `scripts/plugin-dangling-name-audit.mjs`(格 1 尺子)。三份实现同口径:
|
|
13
|
+
* ① 壳尺子(产物层只读审计)② 壳运行时腿 `src/core/compat/dangling-scan.ts`(格 4,**已与格 1 在
|
|
14
|
+
* 随包 6 zip 上对账逐只相等**,对账测试常驻壳 check)③ **本腿**(作者侧,本文件)。
|
|
15
|
+
* 跨包无法 import ⇒ 照 E6#112 `锚⑨` 先例用**锚词**把口径钉住:壳尺子 `--self-test` 的 `锚⑩`
|
|
16
|
+
* 与本包单测各断言一遍(下方「口径锚词」块 + 壳尺子 §判据 的原句逐字同源——改一边不改另一边必红)。
|
|
17
|
+
*
|
|
18
|
+
* ── 口径锚词(与格 1 尺子逐字同源——`锚⑩` 断言的另一半)──
|
|
19
|
+
* · 🔴 判据:只判「**不属于它自己**的名字」;
|
|
20
|
+
* · **悬空** = 须判定的引用,在「自身定义集 ∪ 当前宿主定义集」里都没有;
|
|
21
|
+
* · 动态拼接一律**跳过并计数**(静态读不出运行时拼出来的名字,拦就假红);
|
|
22
|
+
* · 非 `ldk-` 的未定义名**不计悬空**(自有命名空间 / DOM 钩子 / 第三方内联)——假红比漏报更坏;
|
|
23
|
+
* · `ldk-*` 名只被包内自己满足 ⇒ borrowedLdk(归本包前缀腿判红,本腿不判悬空);
|
|
24
|
+
* · 产物 CSS 里 `animation:` / `animation-name:` 引用的**关键帧名**(引用方与定义方分离)。
|
|
25
|
+
*
|
|
26
|
+
* ── 域差异(如实写,不是漏了)──
|
|
27
|
+
* 格 1 尺子扫**产物**(构建后的 bundle),本腿扫**作者源码**(src 树,`scan.ts` 的 SKIP_DIRS 已排
|
|
28
|
+
* node_modules/dist)——域不同、判定口径同一份。测试/mock 文件不进产物 ⇒ 本腿照既有各腿口径跳过
|
|
29
|
+
* (`isTestOrMockRel`),否则夹具里的假名字当场假红。
|
|
30
|
+
*
|
|
31
|
+
* ── 宿主定义集(作者侧拿不到壳源码 ⇒ 随包下发)──
|
|
32
|
+
* `schemas/host-css-names.json`(本格新增的随包 schema)——壳侧 `scripts/gen-host-css-manifest.mjs`
|
|
33
|
+
* 从 `collectHostDefs()`(格 1/格 2 同一采集器)生成,与壳运行时清单 `host-css.generated.ts`
|
|
34
|
+
* **同一生成器同一次采集**(⛔ 两份口径不会分叉)。🔴 **保底(fail-closed)**:宿主定义集读不到
|
|
35
|
+
* ⇒ 报「**未核验**」违规——⛔ **不许当成 0 处通过**(假绿比假红更坏:作者会以为已经查过了)。
|
|
36
|
+
*
|
|
37
|
+
* ── 明确不做的三件(防越界)──
|
|
38
|
+
* ⛔ 不判「该不该退役 / 老不老」(时间不设阈值——本层红线③);
|
|
39
|
+
* ⛔ 不判**前缀**(「裸定义必须 `<pluginId>-` 开头」是 `plugin-prefix.ts` 的活;自己定义的 `ldk-*`
|
|
40
|
+
* 归它判红,本腿只把它从悬空里排除);
|
|
41
|
+
* ⛔ 不做退役名提示(那是 `retired-names.ts` 的活,且**永远只是提示、不是拒绝**)。
|
|
42
|
+
*
|
|
43
|
+
* 知情绕行 = 标准 disable 注释(`CHECK_IDS.cssNamespace`,与类名/关键帧/token/形态同一 id)。
|
|
44
|
+
*/
|
|
45
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
46
|
+
import { resolve, dirname } from "node:path";
|
|
47
|
+
import { fileURLToPath } from "node:url";
|
|
48
|
+
import { collectCssUnits, collectFiles, isTestOrMockRel, relPath, } from "./scan.js";
|
|
49
|
+
import { bareClassDefinitions, keyframeDefinitions, animationRefs, splitSelector, } from "./css-selectors.js";
|
|
50
|
+
import { buildDisableIndex, isDisabled, CHECK_IDS } from "./disable.js";
|
|
51
|
+
import { resolvePluginIdForCss } from "./plugin-prefix.js";
|
|
52
|
+
/** 判级文案——作者面(00 总纲 §〇d:这一面允许「名字 + 文件:行 + 两步修法」) */
|
|
53
|
+
export const DANGLING_NAME_WHY = {
|
|
54
|
+
jsClassname: "它喊的名字宿主已经没有、自己也没定义 ⇒ 发布后**静默丢样式**(零报错)。「宿主改一个类名," +
|
|
55
|
+
"插件侧要升依赖+重打包两件、少任何一件就静默失样」是这条判据的真实发生率来源。",
|
|
56
|
+
cssAnimation: "`animation` 引用的关键帧在本方没有 `@keyframes` 定义 ⇒ **动画静默消失**(不报错、只是不动)。",
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* 包内宿主 CSS 定义集定位(dist/eslint/checks/x.js → ../../../schemas = 包根/schemas;src 直跑同样命中)。
|
|
60
|
+
* 🔴 路径式 resolve(`reserved-classes.ts` 同款)——`new URL(<字面量>, import.meta.url)` 会被 Vite 改写。
|
|
61
|
+
*/
|
|
62
|
+
const HOST_CSS_NAMES_FILE = resolve(dirname(fileURLToPath(import.meta.url)), "../../../schemas/host-css-names.json");
|
|
63
|
+
/** 读随包宿主定义集;缺失/坏 ⇒ null(调用方 fail-closed 报「未核验」,⛔ 不许当 0 处通过) */
|
|
64
|
+
export function loadHostCssNames(file = HOST_CSS_NAMES_FILE) {
|
|
65
|
+
if (!existsSync(file))
|
|
66
|
+
return null;
|
|
67
|
+
try {
|
|
68
|
+
const raw = JSON.parse(readFileSync(file, "utf8"));
|
|
69
|
+
if (!Array.isArray(raw.classes) || !Array.isArray(raw.keyframes))
|
|
70
|
+
return null;
|
|
71
|
+
return {
|
|
72
|
+
version: raw.version ?? 0,
|
|
73
|
+
generatedFrom: raw.generatedFrom ?? "",
|
|
74
|
+
classes: raw.classes,
|
|
75
|
+
keyframes: raw.keyframes,
|
|
76
|
+
reservedKeyframeCount: raw.reservedKeyframeCount ?? 0,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** 名字形态(与格 1 尺子 `IDENT` 同款)——⛔ 别放宽成「像名字就行」 */
|
|
84
|
+
const IDENT = /^-?[_a-zA-Z][\w-]*$/;
|
|
85
|
+
/** 宿主/共享命名空间:硬约束 23 —— `ldk-` 整个命名空间属宿主侧,插件不得定义 */
|
|
86
|
+
const HOST_NAMESPACE = /^ldk-/;
|
|
87
|
+
/** 偏移 → 1-based 行号 */
|
|
88
|
+
const lineAt = (text, index) => text.slice(0, index).split("\n").length;
|
|
89
|
+
/* jscpd:ignore-start */
|
|
90
|
+
/* ↑ 与壳仓两份移植(scripts/plugin-dangling-name-audit.mjs / src/core/compat/dangling-scan.ts)的
|
|
91
|
+
JS 词法段逐行同构——跨包无法 import;口径由 `锚⑩`(锚词)+ 单测钉住,见文件头。 */
|
|
92
|
+
/**
|
|
93
|
+
* 极简 JS 词法遍历:跳过字符串 / 模板正文 / 注释 / 正则,只对**代码**里的标识符回调。
|
|
94
|
+
* 模板的 `${…}` 内部仍是代码 ⇒ 递归进去(嵌套模板一并处理)。与格 1 `scanCode` 逐行同构。
|
|
95
|
+
*/
|
|
96
|
+
function scanCode(text, start, onWord) {
|
|
97
|
+
const regexAllowed = (prev) => prev === "" || /[([{,;:=!&|?+\-*%~^<>]/.test(prev) || prev === "return" || prev === "typeof";
|
|
98
|
+
let i = start;
|
|
99
|
+
let prev = "";
|
|
100
|
+
while (i < text.length) {
|
|
101
|
+
const c = text[i];
|
|
102
|
+
const c2 = text[i + 1];
|
|
103
|
+
if (c === "/" && c2 === "/") {
|
|
104
|
+
const e = text.indexOf("\n", i);
|
|
105
|
+
i = e < 0 ? text.length : e + 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (c === "/" && c2 === "*") {
|
|
109
|
+
const e = text.indexOf("*/", i + 2);
|
|
110
|
+
i = e < 0 ? text.length : e + 2;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (c === '"' || c === "'") {
|
|
114
|
+
i = skipString(text, i, c);
|
|
115
|
+
prev = '"';
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (c === "`") {
|
|
119
|
+
i = skipTemplate(text, i, onWord);
|
|
120
|
+
prev = "`";
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (c === "/" && regexAllowed(prev)) {
|
|
124
|
+
i = skipRegex(text, i);
|
|
125
|
+
prev = "/";
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (/[A-Za-z_$]/.test(c)) {
|
|
129
|
+
let j = i;
|
|
130
|
+
while (j < text.length && /[\w$]/.test(text[j]))
|
|
131
|
+
j++;
|
|
132
|
+
const word = text.slice(i, j);
|
|
133
|
+
onWord(word, j);
|
|
134
|
+
prev = word;
|
|
135
|
+
i = j;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (!/\s/.test(c))
|
|
139
|
+
prev = c;
|
|
140
|
+
i++;
|
|
141
|
+
}
|
|
142
|
+
return i;
|
|
143
|
+
}
|
|
144
|
+
const skipString = (text, i, quote) => {
|
|
145
|
+
let j = i + 1;
|
|
146
|
+
while (j < text.length) {
|
|
147
|
+
if (text[j] === "\\") {
|
|
148
|
+
j += 2;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (text[j] === quote)
|
|
152
|
+
return j + 1;
|
|
153
|
+
j++;
|
|
154
|
+
}
|
|
155
|
+
return text.length;
|
|
156
|
+
};
|
|
157
|
+
const skipTemplate = (text, i, onWord) => {
|
|
158
|
+
let j = i + 1;
|
|
159
|
+
while (j < text.length) {
|
|
160
|
+
if (text[j] === "\\") {
|
|
161
|
+
j += 2;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (text[j] === "`")
|
|
165
|
+
return j + 1;
|
|
166
|
+
if (text[j] === "$" && text[j + 1] === "{") {
|
|
167
|
+
j = skipBraced(text, j + 2, onWord);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
j++;
|
|
171
|
+
}
|
|
172
|
+
return text.length;
|
|
173
|
+
};
|
|
174
|
+
/** 从 `${` 之后扫到配对的 `}`(内部按代码处理:字符串/模板/嵌套括号都过一遍) */
|
|
175
|
+
const skipBraced = (text, i, onWord) => {
|
|
176
|
+
let depth = 1;
|
|
177
|
+
let j = i;
|
|
178
|
+
while (j < text.length) {
|
|
179
|
+
const c = text[j];
|
|
180
|
+
if (c === '"' || c === "'") {
|
|
181
|
+
j = skipString(text, j, c);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (c === "`") {
|
|
185
|
+
j = skipTemplate(text, j, onWord);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (c === "/" && text[j + 1] === "/") {
|
|
189
|
+
const e = text.indexOf("\n", j);
|
|
190
|
+
j = e < 0 ? text.length : e + 1;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (c === "/" && text[j + 1] === "*") {
|
|
194
|
+
const e = text.indexOf("*/", j + 2);
|
|
195
|
+
j = e < 0 ? text.length : e + 2;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (/[A-Za-z_$]/.test(c)) {
|
|
199
|
+
let k = j;
|
|
200
|
+
while (k < text.length && /[\w$]/.test(text[k]))
|
|
201
|
+
k++;
|
|
202
|
+
onWord(text.slice(j, k), k);
|
|
203
|
+
j = k;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (c === "{")
|
|
207
|
+
depth++;
|
|
208
|
+
else if (c === "}") {
|
|
209
|
+
depth--;
|
|
210
|
+
if (depth === 0)
|
|
211
|
+
return j + 1;
|
|
212
|
+
}
|
|
213
|
+
j++;
|
|
214
|
+
}
|
|
215
|
+
return text.length;
|
|
216
|
+
};
|
|
217
|
+
const skipRegex = (text, i) => {
|
|
218
|
+
let j = i + 1;
|
|
219
|
+
let inClass = false;
|
|
220
|
+
while (j < text.length) {
|
|
221
|
+
const c = text[j];
|
|
222
|
+
if (c === "\\") {
|
|
223
|
+
j += 2;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (c === "[")
|
|
227
|
+
inClass = true;
|
|
228
|
+
else if (c === "]")
|
|
229
|
+
inClass = false;
|
|
230
|
+
else if (c === "/" && !inClass)
|
|
231
|
+
return j + 1;
|
|
232
|
+
else if (c === "\n")
|
|
233
|
+
return j; // 未闭合 ⇒ 当除法处理,别吞掉整段代码
|
|
234
|
+
j++;
|
|
235
|
+
}
|
|
236
|
+
return text.length;
|
|
237
|
+
};
|
|
238
|
+
function shoutSites(text) {
|
|
239
|
+
const literals = [];
|
|
240
|
+
const skipped = { interp: 0, dynamic: 0 };
|
|
241
|
+
const push = (raw, at) => {
|
|
242
|
+
const line = lineAt(text, at);
|
|
243
|
+
for (const tok of raw.split(/\s+/)) {
|
|
244
|
+
if (IDENT.test(tok))
|
|
245
|
+
literals.push({ name: tok, line });
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
/** `word` 之后紧跟的实参是不是字面量(`(` 可选 + 引号) */
|
|
249
|
+
const literalArg = (after, allowSelector) => {
|
|
250
|
+
const m = /^\s*\(\s*(["'`])([\s\S]*?)\1\s*\)/.exec(text.slice(after));
|
|
251
|
+
if (!m)
|
|
252
|
+
return null;
|
|
253
|
+
if (m[1] === "`" && m[2].includes("${"))
|
|
254
|
+
return { interp: true };
|
|
255
|
+
return { raw: allowSelector ? [...m[2].matchAll(/\.(-?[_a-zA-Z][\w-]*)/g)].map((x) => x[1]).join(" ") : m[2] };
|
|
256
|
+
};
|
|
257
|
+
scanCode(text, 0, (word, end) => {
|
|
258
|
+
if (word === "className" || word === "class") {
|
|
259
|
+
let i = end;
|
|
260
|
+
while (i < text.length && /\s/.test(text[i]))
|
|
261
|
+
i++;
|
|
262
|
+
// 必须是赋值位(`className: "x"` / `className = "x"`)——读法 / 比较 / 箭头都不是站点
|
|
263
|
+
if (text[i] !== ":" && text[i] !== "=")
|
|
264
|
+
return;
|
|
265
|
+
if (text[i] === "=" && (text[i + 1] === "=" || text[i + 1] === ">"))
|
|
266
|
+
return;
|
|
267
|
+
i++;
|
|
268
|
+
while (i < text.length && /\s/.test(text[i]))
|
|
269
|
+
i++;
|
|
270
|
+
let braced = false;
|
|
271
|
+
if (text[i] === "{") {
|
|
272
|
+
braced = true;
|
|
273
|
+
i++;
|
|
274
|
+
while (i < text.length && /\s/.test(text[i]))
|
|
275
|
+
i++;
|
|
276
|
+
}
|
|
277
|
+
const ch = text[i];
|
|
278
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
279
|
+
let j = i + 1;
|
|
280
|
+
let raw = "";
|
|
281
|
+
let closed = false;
|
|
282
|
+
while (j < text.length) {
|
|
283
|
+
if (text[j] === "\\") {
|
|
284
|
+
raw += text[j + 1] ?? "";
|
|
285
|
+
j += 2;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (text[j] === ch) {
|
|
289
|
+
closed = true;
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
raw += text[j];
|
|
293
|
+
j++;
|
|
294
|
+
}
|
|
295
|
+
if (!closed) {
|
|
296
|
+
skipped.dynamic++;
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (ch === "`" && raw.includes("${")) {
|
|
300
|
+
skipped.interp++;
|
|
301
|
+
return;
|
|
302
|
+
} // 插值模板 ⇒ 射程外
|
|
303
|
+
if (braced) {
|
|
304
|
+
let k = j + 1;
|
|
305
|
+
while (k < text.length && /\s/.test(text[k]))
|
|
306
|
+
k++;
|
|
307
|
+
if (text[k] !== "}") {
|
|
308
|
+
skipped.dynamic++;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
push(raw, i);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
skipped.dynamic++; // 变量 / 函数调用 / 三元 …… 静态读不出
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (word === "classList") {
|
|
319
|
+
const m = /^\s*\.\s*(add|remove|toggle|contains)\s*\(\s*(["'])([\s\S]*?)\2/.exec(text.slice(end));
|
|
320
|
+
if (m)
|
|
321
|
+
push(m[3], end + m.index + m[0].length);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (word === "querySelector" || word === "querySelectorAll" || word === "closest" || word === "matches") {
|
|
325
|
+
const r = literalArg(end, true);
|
|
326
|
+
if (r?.interp)
|
|
327
|
+
skipped.interp++;
|
|
328
|
+
else if (r?.raw != null)
|
|
329
|
+
push(r.raw, end);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
return { literals, skipped };
|
|
333
|
+
}
|
|
334
|
+
/* jscpd:ignore-end */
|
|
335
|
+
/** 本腿扫描的 JS 族扩展名(作者源码域——格 1 尺子在产物域只见到 bundle 后的 .js/.html) */
|
|
336
|
+
const JS_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".html"];
|
|
337
|
+
/** 一个选择器里的类名(剥属性选择器后再抓 `.x`) */
|
|
338
|
+
const classTokensIn = (sel) => [...String(sel).replace(/\[[^\]]*\]/g, " ").matchAll(/\.(-?[_a-zA-Z][\w-]*)/g)].map((m) => m[1]);
|
|
339
|
+
/** 一处悬空引用的报点文案(作者面:名字 + 出处 + 两步修法) */
|
|
340
|
+
function messageOf(site, hostClassCount) {
|
|
341
|
+
const channel = site.via === "js-classname" ? "JS className" : "CSS `animation:`";
|
|
342
|
+
return (`\`${site.name}\`(${channel} 引用,本仓 ${site.file}:${site.line})在本仓 CSS 与宿主定义集` +
|
|
343
|
+
`(${hostClassCount} 个类名)里都找不到 ⇒ ${site.via === "js-classname" ? DANGLING_NAME_WHY.jsClassname : DANGLING_NAME_WHY.cssAnimation} ` +
|
|
344
|
+
`修法两步:① 换成宿主真实存在的名字,或在本仓补定义(自有类名须以 \`<pluginId>-\` 开头;` +
|
|
345
|
+
`\`ldk-*\` 只许宿主定义);② 重新打包发版。知情绕行 = // eslint-disable-next-line ${CHECK_IDS.cssNamespace} -- 理由。`);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* 跑本仓悬空名判据(作者侧唯一入口)。返回结构化报告——**同一份实现,没有第二条判据路径**。
|
|
349
|
+
* ⚠️ `host` / `resolution` 可注入(单测用);缺省读随包 `schemas/host-css-names.json`。
|
|
350
|
+
*/
|
|
351
|
+
export function runDanglingNameCheck(root, opts = {}) {
|
|
352
|
+
const absRoot = resolve(root);
|
|
353
|
+
const host = opts.host !== undefined ? opts.host : loadHostCssNames();
|
|
354
|
+
const resolution = opts.resolution ?? resolvePluginIdForCss(absRoot);
|
|
355
|
+
const report = {
|
|
356
|
+
root: absRoot,
|
|
357
|
+
pluginId: resolution.pluginId,
|
|
358
|
+
error: resolution.error,
|
|
359
|
+
hostClassCount: host?.classes.length ?? 0,
|
|
360
|
+
hostKeyframeCount: host?.keyframes.length ?? 0,
|
|
361
|
+
ldkRefs: 0,
|
|
362
|
+
kfRefs: 0,
|
|
363
|
+
skipped: { interp: 0, dynamic: 0 },
|
|
364
|
+
notJudgedCount: 0,
|
|
365
|
+
borrowedLdk: [],
|
|
366
|
+
dangling: [],
|
|
367
|
+
violations: [],
|
|
368
|
+
};
|
|
369
|
+
// 🔴 保底(fail-closed,不可豁免):宿主定义集读不到 ⇒ 「未核验」报红——⛔ 不许静默当 0 处通过
|
|
370
|
+
if (!host) {
|
|
371
|
+
report.error = report.error ?? "宿主定义集读不到";
|
|
372
|
+
report.violations.push({
|
|
373
|
+
file: "plugin.json",
|
|
374
|
+
line: 1,
|
|
375
|
+
message: "宿主 CSS 定义集(@linkdesk/plugin-sdk 的 schemas/host-css-names.json)**读不到** ⇒ 本腿**未核验**。" +
|
|
376
|
+
"「0 处通过」在这里是假绿(假绿比假红更坏:你会以为已经查过了)。修复:重装 @linkdesk/plugin-sdk(包不完整)。",
|
|
377
|
+
});
|
|
378
|
+
return report;
|
|
379
|
+
}
|
|
380
|
+
if (resolution.error || !resolution.pluginId) {
|
|
381
|
+
// 身份读不到时前缀腿已 fail-closed 报同一件事 ⇒ 本腿不重复报,但照常跑判定(判定不依赖身份)
|
|
382
|
+
report.error = resolution.error;
|
|
383
|
+
}
|
|
384
|
+
const hostClasses = new Set(host.classes);
|
|
385
|
+
const hostKeyframes = new Set(host.keyframes);
|
|
386
|
+
// ① 自身定义集先**全量收齐**(CSS 半边——collectCssUnits 与前几条判据同一批站点、同一豁免索引)
|
|
387
|
+
const cssUnits = collectCssUnits(absRoot, [CHECK_IDS.cssNamespace]);
|
|
388
|
+
const selfDefs = new Set();
|
|
389
|
+
const selfKeyframes = new Set();
|
|
390
|
+
const cssMentions = new Set();
|
|
391
|
+
for (const unit of cssUnits) {
|
|
392
|
+
for (const d of bareClassDefinitions(unit.cleaned))
|
|
393
|
+
selfDefs.add(d.name);
|
|
394
|
+
for (const k of keyframeDefinitions(unit.cleaned))
|
|
395
|
+
selfKeyframes.add(k.name);
|
|
396
|
+
for (const m of unit.cleaned.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
|
397
|
+
const sel = m[1].trim();
|
|
398
|
+
if (sel.startsWith("@") || !m[2].trim())
|
|
399
|
+
continue;
|
|
400
|
+
for (const one of splitSelector(sel.replace(/\[[^\]]*\]/g, " "))) {
|
|
401
|
+
for (const n of classTokensIn(one))
|
|
402
|
+
cssMentions.add(n);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const jsSites = [];
|
|
407
|
+
const notJudged = new Set();
|
|
408
|
+
for (const file of collectFiles(absRoot, JS_EXTS)) {
|
|
409
|
+
const rel = relPath(absRoot, file);
|
|
410
|
+
if (isTestOrMockRel(rel))
|
|
411
|
+
continue;
|
|
412
|
+
const src = readSource(file);
|
|
413
|
+
const { literals, skipped } = shoutSites(src);
|
|
414
|
+
report.skipped.interp += skipped.interp;
|
|
415
|
+
report.skipped.dynamic += skipped.dynamic;
|
|
416
|
+
if (literals.length === 0)
|
|
417
|
+
continue;
|
|
418
|
+
const disabled = buildDisableIndex(src, [CHECK_IDS.cssNamespace]);
|
|
419
|
+
for (const l of literals)
|
|
420
|
+
jsSites.push({ site: l, rel, disabled });
|
|
421
|
+
}
|
|
422
|
+
// ③ 判定:须判定的引用,在「自身定义集 ∪ 宿主定义集」里都没有 ⇒ 悬空
|
|
423
|
+
const dangling = new Map();
|
|
424
|
+
const satisfiedBySelfOnly = new Set();
|
|
425
|
+
for (const { site, rel, disabled } of jsSites) {
|
|
426
|
+
if (!HOST_NAMESPACE.test(site.name)) {
|
|
427
|
+
// 非 ldk- 的未定义名不计悬空(自有命名空间 / DOM 钩子 / 第三方内联)——误报控,只计数
|
|
428
|
+
if (!selfDefs.has(site.name) && !cssMentions.has(site.name) && !hostClasses.has(site.name)) {
|
|
429
|
+
notJudged.add(site.name);
|
|
430
|
+
}
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
report.ldkRefs++;
|
|
434
|
+
if (hostClasses.has(site.name))
|
|
435
|
+
continue;
|
|
436
|
+
if (selfDefs.has(site.name)) {
|
|
437
|
+
satisfiedBySelfOnly.add(site.name);
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
if (isDisabled(disabled, site.line, CHECK_IDS.cssNamespace))
|
|
441
|
+
continue;
|
|
442
|
+
const entry = { name: site.name, via: "js-classname", file: rel, line: site.line };
|
|
443
|
+
if (!dangling.has(site.name))
|
|
444
|
+
dangling.set(site.name, entry);
|
|
445
|
+
}
|
|
446
|
+
for (const unit of cssUnits) {
|
|
447
|
+
for (const ref of animationRefs(unit.cleaned)) {
|
|
448
|
+
report.kfRefs++;
|
|
449
|
+
if (selfKeyframes.has(ref.name) || hostKeyframes.has(ref.name))
|
|
450
|
+
continue;
|
|
451
|
+
if (isDisabled(unit.disabled, ref.line, CHECK_IDS.cssNamespace))
|
|
452
|
+
continue;
|
|
453
|
+
const entry = { name: ref.name, via: "css-animation", file: unit.rel, line: ref.line };
|
|
454
|
+
if (!dangling.has(ref.name))
|
|
455
|
+
dangling.set(ref.name, entry);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
report.notJudgedCount = notJudged.size;
|
|
459
|
+
report.borrowedLdk = [...satisfiedBySelfOnly].sort();
|
|
460
|
+
report.dangling = [...dangling.values()].sort((x, y) => x.name.localeCompare(y.name) || x.file.localeCompare(y.file) || x.line - y.line);
|
|
461
|
+
for (const site of report.dangling) {
|
|
462
|
+
report.violations.push({ file: site.file, line: site.line, message: messageOf(site, report.hostClassCount) });
|
|
463
|
+
}
|
|
464
|
+
return report;
|
|
465
|
+
}
|
|
466
|
+
function readSource(abs) {
|
|
467
|
+
return readFileSync(abs, "utf8");
|
|
468
|
+
}
|
|
469
|
+
//# sourceMappingURL=dangling-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dangling-names.js","sourceRoot":"","sources":["../../../src/eslint/checks/dangling-names.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** 退役登记条目(`host-reserved.json` `retired[]` 的形状——7 字段,唯一真相源 = `scripts/lib/retired-ledger.mjs`) */
|
|
2
|
+
export interface RetiredEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
kind: string;
|
|
5
|
+
since: string;
|
|
6
|
+
why: string;
|
|
7
|
+
replacedBy: string;
|
|
8
|
+
landing: string;
|
|
9
|
+
approvedBy: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RetiredLedger {
|
|
12
|
+
file: string;
|
|
13
|
+
/** false ⇒ 账没读到(判据空转——报告里必须能看出来,⛔ 不许静默) */
|
|
14
|
+
found: boolean;
|
|
15
|
+
retired: RetiredEntry[];
|
|
16
|
+
}
|
|
17
|
+
/** 读退役登记栏(只取 `retired[]`;账缺失/坏 ⇒ found=false,⛔ 不许静默丢) */
|
|
18
|
+
export declare function loadRetiredLedger(file?: string): RetiredLedger;
|
|
19
|
+
/** 一处退役名引用的提示(名字 + 哪天退的休 + 替身 + 出处) */
|
|
20
|
+
export interface RetiredNameHint {
|
|
21
|
+
/** 退役名 */
|
|
22
|
+
name: string;
|
|
23
|
+
/** 退役生效日(账里的 `since`,写日期不写版本号) */
|
|
24
|
+
since: string;
|
|
25
|
+
/** 替身(账里的 `replacedBy`) */
|
|
26
|
+
replacedBy: string;
|
|
27
|
+
/** 工程相对路径(正斜杠) */
|
|
28
|
+
file: string;
|
|
29
|
+
/** 1-based */
|
|
30
|
+
line: number;
|
|
31
|
+
}
|
|
32
|
+
export interface RetiredNameReport {
|
|
33
|
+
root: string;
|
|
34
|
+
/** 账的加载实况(found=false ⇒ 本腿空转,报告里必须能看出来) */
|
|
35
|
+
ledger: RetiredLedger;
|
|
36
|
+
/** 扫过的源码文件数(审计读数用) */
|
|
37
|
+
filesScanned: number;
|
|
38
|
+
/** 提示站点(⛔ 不进 violations——本腿永远只是提示) */
|
|
39
|
+
hints: RetiredNameHint[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 跑本仓退役名提示(作者侧入口)。🔴 `hints` 永不进 violations——升级成拒绝 = 越界(见文件头)。
|
|
43
|
+
* ⚠️ `ledger` 可注入(单测用);缺省读随包 `schemas/host-reserved.json` 的 `retired[]`。
|
|
44
|
+
*/
|
|
45
|
+
export declare function runRetiredNameHint(root: string, ledger?: RetiredLedger): RetiredNameReport;
|
|
46
|
+
//# sourceMappingURL=retired-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retired-names.d.ts","sourceRoot":"","sources":["../../../src/eslint/checks/retired-names.ts"],"names":[],"mappings":"AAyBA,kGAAkG;AAClG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAUD,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAA2B,GAAG,aAAa,CAQlF;AAED,uCAAuC;AACvC,MAAM,WAAW,eAAe;IAC9B,UAAU;IACV,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,MAAM,EAAE,aAAa,CAAC;IACtB,sBAAsB;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAaD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,aAAmC,GAAG,iBAAiB,CAoC/G"}
|