@opensip-cli/dashboard 0.1.10 → 0.1.12

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 (150) hide show
  1. package/README.md +4 -2
  2. package/dist/client-bundle.generated.d.ts.map +1 -1
  3. package/dist/client-bundle.generated.js +1 -1
  4. package/dist/client-bundle.generated.js.map +1 -1
  5. package/dist/code-paths/graph-view-model.js +0 -1
  6. package/dist/code-paths/graph-view-model.js.map +1 -1
  7. package/dist/css/theme.js +1 -1
  8. package/dist/generator.d.ts +2 -0
  9. package/dist/generator.d.ts.map +1 -1
  10. package/dist/generator.js +10 -4
  11. package/dist/generator.js.map +1 -1
  12. package/dist/report-cup-icon.d.ts +17 -0
  13. package/dist/report-cup-icon.d.ts.map +1 -0
  14. package/dist/report-cup-icon.js +34 -0
  15. package/dist/report-cup-icon.js.map +1 -0
  16. package/dist/tool-tabs-registrations.js +10 -0
  17. package/dist/tool-tabs-registrations.js.map +1 -1
  18. package/package.json +3 -3
  19. package/dist/__tests__/catalog-provenance.test.d.ts +0 -11
  20. package/dist/__tests__/catalog-provenance.test.d.ts.map +0 -1
  21. package/dist/__tests__/catalog-provenance.test.js +0 -112
  22. package/dist/__tests__/catalog-provenance.test.js.map +0 -1
  23. package/dist/__tests__/coupling-attribution.test.d.ts +0 -9
  24. package/dist/__tests__/coupling-attribution.test.d.ts.map +0 -1
  25. package/dist/__tests__/coupling-attribution.test.js +0 -95
  26. package/dist/__tests__/coupling-attribution.test.js.map +0 -1
  27. package/dist/__tests__/dashboard-bundle-weight.test.d.ts +0 -23
  28. package/dist/__tests__/dashboard-bundle-weight.test.d.ts.map +0 -1
  29. package/dist/__tests__/dashboard-bundle-weight.test.js +0 -80
  30. package/dist/__tests__/dashboard-bundle-weight.test.js.map +0 -1
  31. package/dist/__tests__/dashboard-cell-containment.test.d.ts +0 -2
  32. package/dist/__tests__/dashboard-cell-containment.test.d.ts.map +0 -1
  33. package/dist/__tests__/dashboard-cell-containment.test.js +0 -52
  34. package/dist/__tests__/dashboard-cell-containment.test.js.map +0 -1
  35. package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts +0 -10
  36. package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts.map +0 -1
  37. package/dist/__tests__/dashboard-cytoscape-vendor.test.js +0 -40
  38. package/dist/__tests__/dashboard-cytoscape-vendor.test.js.map +0 -1
  39. package/dist/__tests__/dashboard-editor-link.test.d.ts +0 -14
  40. package/dist/__tests__/dashboard-editor-link.test.d.ts.map +0 -1
  41. package/dist/__tests__/dashboard-editor-link.test.js +0 -87
  42. package/dist/__tests__/dashboard-editor-link.test.js.map +0 -1
  43. package/dist/__tests__/dashboard-el.test.d.ts +0 -18
  44. package/dist/__tests__/dashboard-el.test.d.ts.map +0 -1
  45. package/dist/__tests__/dashboard-el.test.js +0 -90
  46. package/dist/__tests__/dashboard-el.test.js.map +0 -1
  47. package/dist/__tests__/dashboard-filters.test.d.ts +0 -9
  48. package/dist/__tests__/dashboard-filters.test.d.ts.map +0 -1
  49. package/dist/__tests__/dashboard-filters.test.js +0 -87
  50. package/dist/__tests__/dashboard-filters.test.js.map +0 -1
  51. package/dist/__tests__/dashboard-function-card-singleton.test.d.ts +0 -9
  52. package/dist/__tests__/dashboard-function-card-singleton.test.d.ts.map +0 -1
  53. package/dist/__tests__/dashboard-function-card-singleton.test.js +0 -75
  54. package/dist/__tests__/dashboard-function-card-singleton.test.js.map +0 -1
  55. package/dist/__tests__/dashboard-function-card.test.d.ts +0 -10
  56. package/dist/__tests__/dashboard-function-card.test.d.ts.map +0 -1
  57. package/dist/__tests__/dashboard-function-card.test.js +0 -439
  58. package/dist/__tests__/dashboard-function-card.test.js.map +0 -1
  59. package/dist/__tests__/dashboard-function-row.test.d.ts +0 -11
  60. package/dist/__tests__/dashboard-function-row.test.d.ts.map +0 -1
  61. package/dist/__tests__/dashboard-function-row.test.js +0 -102
  62. package/dist/__tests__/dashboard-function-row.test.js.map +0 -1
  63. package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts +0 -9
  64. package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts.map +0 -1
  65. package/dist/__tests__/dashboard-generator-graph-catalog.test.js +0 -77
  66. package/dist/__tests__/dashboard-generator-graph-catalog.test.js.map +0 -1
  67. package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts +0 -13
  68. package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts.map +0 -1
  69. package/dist/__tests__/dashboard-graph-offline.integration.test.js +0 -57
  70. package/dist/__tests__/dashboard-graph-offline.integration.test.js.map +0 -1
  71. package/dist/__tests__/dashboard-graph-scc.test.d.ts +0 -17
  72. package/dist/__tests__/dashboard-graph-scc.test.d.ts.map +0 -1
  73. package/dist/__tests__/dashboard-graph-scc.test.js +0 -89
  74. package/dist/__tests__/dashboard-graph-scc.test.js.map +0 -1
  75. package/dist/__tests__/dashboard-graph-view-model.test.d.ts +0 -12
  76. package/dist/__tests__/dashboard-graph-view-model.test.d.ts.map +0 -1
  77. package/dist/__tests__/dashboard-graph-view-model.test.js +0 -331
  78. package/dist/__tests__/dashboard-graph-view-model.test.js.map +0 -1
  79. package/dist/__tests__/dashboard-help-drawer.test.d.ts +0 -9
  80. package/dist/__tests__/dashboard-help-drawer.test.d.ts.map +0 -1
  81. package/dist/__tests__/dashboard-help-drawer.test.js +0 -95
  82. package/dist/__tests__/dashboard-help-drawer.test.js.map +0 -1
  83. package/dist/__tests__/dashboard-html.test.d.ts +0 -2
  84. package/dist/__tests__/dashboard-html.test.d.ts.map +0 -1
  85. package/dist/__tests__/dashboard-html.test.js +0 -169
  86. package/dist/__tests__/dashboard-html.test.js.map +0 -1
  87. package/dist/__tests__/dashboard-indexes.test.d.ts +0 -11
  88. package/dist/__tests__/dashboard-indexes.test.d.ts.map +0 -1
  89. package/dist/__tests__/dashboard-indexes.test.js +0 -214
  90. package/dist/__tests__/dashboard-indexes.test.js.map +0 -1
  91. package/dist/__tests__/dashboard-pagination.test.d.ts +0 -15
  92. package/dist/__tests__/dashboard-pagination.test.d.ts.map +0 -1
  93. package/dist/__tests__/dashboard-pagination.test.js +0 -140
  94. package/dist/__tests__/dashboard-pagination.test.js.map +0 -1
  95. package/dist/__tests__/dashboard-path-utils.test.d.ts +0 -13
  96. package/dist/__tests__/dashboard-path-utils.test.d.ts.map +0 -1
  97. package/dist/__tests__/dashboard-path-utils.test.js +0 -62
  98. package/dist/__tests__/dashboard-path-utils.test.js.map +0 -1
  99. package/dist/__tests__/dashboard-search.test.d.ts +0 -10
  100. package/dist/__tests__/dashboard-search.test.d.ts.map +0 -1
  101. package/dist/__tests__/dashboard-search.test.js +0 -52
  102. package/dist/__tests__/dashboard-search.test.js.map +0 -1
  103. package/dist/__tests__/dashboard-sessions.test.d.ts +0 -14
  104. package/dist/__tests__/dashboard-sessions.test.d.ts.map +0 -1
  105. package/dist/__tests__/dashboard-sessions.test.js +0 -332
  106. package/dist/__tests__/dashboard-sessions.test.js.map +0 -1
  107. package/dist/__tests__/dashboard-trace.test.d.ts +0 -16
  108. package/dist/__tests__/dashboard-trace.test.d.ts.map +0 -1
  109. package/dist/__tests__/dashboard-trace.test.js +0 -170
  110. package/dist/__tests__/dashboard-trace.test.js.map +0 -1
  111. package/dist/__tests__/dashboard-validation.integration.test.d.ts +0 -14
  112. package/dist/__tests__/dashboard-validation.integration.test.d.ts.map +0 -1
  113. package/dist/__tests__/dashboard-validation.integration.test.js +0 -221
  114. package/dist/__tests__/dashboard-validation.integration.test.js.map +0 -1
  115. package/dist/__tests__/dashboard-view-conformance.test.d.ts +0 -12
  116. package/dist/__tests__/dashboard-view-conformance.test.d.ts.map +0 -1
  117. package/dist/__tests__/dashboard-view-conformance.test.js +0 -52
  118. package/dist/__tests__/dashboard-view-conformance.test.js.map +0 -1
  119. package/dist/__tests__/dashboard-view-coupling.test.d.ts +0 -7
  120. package/dist/__tests__/dashboard-view-coupling.test.d.ts.map +0 -1
  121. package/dist/__tests__/dashboard-view-coupling.test.js +0 -360
  122. package/dist/__tests__/dashboard-view-coupling.test.js.map +0 -1
  123. package/dist/__tests__/dashboard-view-distribution.test.d.ts +0 -10
  124. package/dist/__tests__/dashboard-view-distribution.test.d.ts.map +0 -1
  125. package/dist/__tests__/dashboard-view-distribution.test.js +0 -249
  126. package/dist/__tests__/dashboard-view-distribution.test.js.map +0 -1
  127. package/dist/__tests__/dashboard-view-graph.test.d.ts +0 -13
  128. package/dist/__tests__/dashboard-view-graph.test.d.ts.map +0 -1
  129. package/dist/__tests__/dashboard-view-graph.test.js +0 -299
  130. package/dist/__tests__/dashboard-view-graph.test.js.map +0 -1
  131. package/dist/__tests__/dashboard-view-template.test.d.ts +0 -20
  132. package/dist/__tests__/dashboard-view-template.test.d.ts.map +0 -1
  133. package/dist/__tests__/dashboard-view-template.test.js +0 -206
  134. package/dist/__tests__/dashboard-view-template.test.js.map +0 -1
  135. package/dist/__tests__/dashboard.test.d.ts +0 -2
  136. package/dist/__tests__/dashboard.test.d.ts.map +0 -1
  137. package/dist/__tests__/dashboard.test.js +0 -129
  138. package/dist/__tests__/dashboard.test.js.map +0 -1
  139. package/dist/__tests__/graph-tab.test.d.ts +0 -10
  140. package/dist/__tests__/graph-tab.test.d.ts.map +0 -1
  141. package/dist/__tests__/graph-tab.test.js +0 -78
  142. package/dist/__tests__/graph-tab.test.js.map +0 -1
  143. package/dist/client/el.d.ts +0 -17
  144. package/dist/client/el.d.ts.map +0 -1
  145. package/dist/client/el.js +0 -36
  146. package/dist/client/el.js.map +0 -1
  147. package/dist/code-paths/__tests__/views-registry.test.d.ts +0 -18
  148. package/dist/code-paths/__tests__/views-registry.test.d.ts.map +0 -1
  149. package/dist/code-paths/__tests__/views-registry.test.js +0 -41
  150. package/dist/code-paths/__tests__/views-registry.test.js.map +0 -1
@@ -1,129 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { generateDashboardHtml } from '../generator.js';
3
- function makeSession(overrides = {}) {
4
- return {
5
- id: 'sess-1',
6
- tool: 'fit',
7
- startedAt: new Date().toISOString(),
8
- completedAt: new Date().toISOString(),
9
- cwd: '/proj',
10
- score: 92,
11
- passed: true,
12
- durationMs: 100,
13
- // Tool-owned opaque detail; contracts no longer carries summary/checks.
14
- payload: { summary: { total: 10, passed: 9, failed: 1, errors: 0, warnings: 0 }, checks: [] },
15
- ...overrides,
16
- };
17
- }
18
- // Catalog entry shapes are fitness-owned (L1); the dashboard consumes
19
- // them structurally, so the test supplies plain objects.
20
- const checkCatalog = [
21
- {
22
- slug: 'no-console-log',
23
- name: 'No console.log',
24
- icon: '🚫',
25
- description: 'Forbids console.log in production',
26
- tags: ['quality'],
27
- confidence: 'high',
28
- source: 'built-in',
29
- },
30
- ];
31
- const recipeCatalog = [
32
- {
33
- name: 'default',
34
- displayName: 'Default',
35
- description: 'All checks',
36
- tags: [],
37
- selectorType: 'all',
38
- mode: 'parallel',
39
- timeout: 30_000,
40
- },
41
- ];
42
- describe('generateDashboardHtml', () => {
43
- it('produces a complete HTML5 document', () => {
44
- const html = generateDashboardHtml({ sessions: [makeSession()] });
45
- expect(html).toContain('<!DOCTYPE html>');
46
- expect(html).toContain('</html>');
47
- });
48
- it('inlines the latest session score in the document title', () => {
49
- const html = generateDashboardHtml({ sessions: [makeSession({ score: 85 })] });
50
- expect(html).toContain('Pass Rate: 85%');
51
- });
52
- it('omits the score from the title when there are no sessions', () => {
53
- const html = generateDashboardHtml({ sessions: [] });
54
- expect(html).toMatch(/<title>OpenSIP CLI<\/title>/);
55
- });
56
- it('inlines session, check catalog, and recipe catalog as JS data', () => {
57
- const html = generateDashboardHtml({
58
- sessions: [makeSession({ id: 'special-session-id' })],
59
- checkCatalog,
60
- recipeCatalog,
61
- });
62
- expect(html).toContain('special-session-id');
63
- expect(html).toContain('no-console-log');
64
- expect(html).toContain('default');
65
- });
66
- it('escapes < and > in inlined JSON to prevent script injection', () => {
67
- // A session whose cwd contains a fake </script> tag must not break out
68
- const evil = makeSession({ cwd: '</script><script>alert(1)</script>' });
69
- const html = generateDashboardHtml({ sessions: [evil] });
70
- expect(html).not.toMatch(/<\/script>\s*<script>alert\(1\)/);
71
- expect(html).toContain(String.raw `</script>`);
72
- });
73
- // Regression for the 2026-05-25 audit fix on serializeOptionalBlob.
74
- // The 'literal' arm (used for editorProtocol) previously called
75
- // JSON.stringify without escapeForScriptContext; JSON.stringify does not
76
- // escape `<`, so a caller-controlled editorProtocol containing the literal
77
- // sequence `</script>` would close the inline <script> block. After the
78
- // fix, both arms apply the same escape — `<` becomes `<`.
79
- it('escapes </script> in editorProtocol literal so it cannot close the inline script block', () => {
80
- const html = generateDashboardHtml({
81
- sessions: [],
82
- editorProtocol: '</script><img src=x onerror=alert(1)>',
83
- });
84
- // The escaped form must be present; the raw form must NOT appear inside
85
- // the EDITOR_PROTOCOL constant assignment.
86
- const literalLine = html
87
- .split('\n')
88
- .find((line) => line.startsWith('const EDITOR_PROTOCOL = '));
89
- expect(literalLine).toBeDefined();
90
- expect(literalLine ?? '').not.toContain('</script>');
91
- // The escape function rewrites `<` to the JS Unicode escape `<`,
92
- // which the HTML tokenizer does not match against `</script>`.
93
- // (`String.raw`<`` is the 1-char `<` because the JS lexer processes
94
- // Unicode escapes before String.raw sees them — a backslash literal
95
- // is required for the 6-character on-disk sequence.)
96
- expect(literalLine ?? '').toContain('\\u003c');
97
- });
98
- // Regression for the 2026-05-25 audit fix on the <title> interpolation:
99
- // session.score is typed `number` but originates from a SQLite column; a
100
- // corrupted row carrying a non-numeric value would otherwise interpolate
101
- // directly into the page title. coerceScoreForTitle falls back to 0 for
102
- // anything non-finite.
103
- it('renders score 0 in <title> when the session score is non-finite', () => {
104
- const bad = makeSession({ score: Number.NaN });
105
- const html = generateDashboardHtml({ sessions: [bad] });
106
- expect(html).toMatch(/<title>OpenSIP CLI — Pass Rate: 0%<\/title>/);
107
- });
108
- it('renders all three tab panels (overview, fitness, simulation)', () => {
109
- const html = generateDashboardHtml({ sessions: [] });
110
- expect(html).toContain('id="panel-overview"');
111
- expect(html).toContain('id="panel-fitness"');
112
- expect(html).toContain('id="panel-simulation"');
113
- });
114
- it('includes inline CSS', () => {
115
- const html = generateDashboardHtml({ sessions: [] });
116
- expect(html).toMatch(/<style>[\s\S]+?<\/style>/);
117
- });
118
- it('partitions sessions into fit vs sim arrays in the page script', () => {
119
- const html = generateDashboardHtml({
120
- sessions: [
121
- makeSession({ id: 'fit-1', tool: 'fit' }),
122
- makeSession({ id: 'sim-1', tool: 'sim' }),
123
- ],
124
- });
125
- expect(html).toContain("sessions.filter(s => s.tool === 'fit')");
126
- expect(html).toContain("sessions.filter(s => s.tool === 'sim')");
127
- });
128
- });
129
- //# sourceMappingURL=dashboard.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,SAAS,WAAW,CAAC,YAAoC,EAAE;IACzD,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,GAAG;QACf,wEAAwE;QACxE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7F,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,yDAAyD;AACzD,MAAM,YAAY,GAAG;IACnB;QACE,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,UAAU,EAAE,MAAM;QAClB,MAAM,EAAE,UAAU;KACnB;CACF,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,YAAY;QACzB,IAAI,EAAE,EAAE;QACR,YAAY,EAAE,KAAK;QACnB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,MAAM;KAChB;CACF,CAAC;AAEF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,IAAI,GAAG,qBAAqB,CAAC;YACjC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACrD,YAAY;YACZ,aAAa;SACd,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,uEAAuE;QACvE,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,GAAG,EAAE,oCAAoC,EAAE,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAA,WAAW,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,oEAAoE;IACpE,gEAAgE;IAChE,yEAAyE;IACzE,2EAA2E;IAC3E,wEAAwE;IACxE,0DAA0D;IAC1D,EAAE,CAAC,wFAAwF,EAAE,GAAG,EAAE;QAChG,MAAM,IAAI,GAAG,qBAAqB,CAAC;YACjC,QAAQ,EAAE,EAAE;YACZ,cAAc,EAAE,uCAAuC;SACxD,CAAC,CAAC;QACH,wEAAwE;QACxE,2CAA2C;QAC3C,MAAM,WAAW,GAAG,IAAI;aACrB,KAAK,CAAC,IAAI,CAAC;aACX,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACrD,iEAAiE;QACjE,+DAA+D;QAC/D,oEAAoE;QACpE,oEAAoE;QACpE,qDAAqD;QACrD,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,wEAAwE;IACxE,yEAAyE;IACzE,yEAAyE;IACzE,wEAAwE;IACxE,uBAAuB;IACvB,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,IAAI,GAAG,qBAAqB,CAAC;YACjC,QAAQ,EAAE;gBACR,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;gBACzC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;aAC1C;SACF,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,10 +0,0 @@
1
- /**
2
- * @fileoverview Dashboard graph-tab render wiring (Plan B, Phase 5 Task 5.4).
3
- *
4
- * Feeds a DashboardInput carrying graphRuleCatalog + graphRecipeCatalog through
5
- * generateDashboardHtml and asserts the emitted HTML embeds the graph rule
6
- * slugs + recipe names. Also re-confirms decoupling: @opensip-cli/dashboard
7
- * has no @opensip-cli/graph dependency.
8
- */
9
- export {};
10
- //# sourceMappingURL=graph-tab.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-tab.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/graph-tab.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -1,78 +0,0 @@
1
- /**
2
- * @fileoverview Dashboard graph-tab render wiring (Plan B, Phase 5 Task 5.4).
3
- *
4
- * Feeds a DashboardInput carrying graphRuleCatalog + graphRecipeCatalog through
5
- * generateDashboardHtml and asserts the emitted HTML embeds the graph rule
6
- * slugs + recipe names. Also re-confirms decoupling: @opensip-cli/dashboard
7
- * has no @opensip-cli/graph dependency.
8
- */
9
- import { readFileSync } from 'node:fs';
10
- import { dirname, join } from 'node:path';
11
- import { fileURLToPath } from 'node:url';
12
- import { describe, expect, it } from 'vitest';
13
- import { generateDashboardHtml } from '../generator.js';
14
- const HERE = dirname(fileURLToPath(import.meta.url));
15
- describe('dashboard graph-tab — rule/recipe catalog wiring', () => {
16
- const html = generateDashboardHtml({
17
- sessions: [],
18
- graphRuleCatalog: [
19
- { slug: 'graph:orphan-subtree', defaultSeverity: 'warning', source: 'built-in' },
20
- { slug: 'graph:duplicated-function-body', defaultSeverity: 'warning', source: 'built-in' },
21
- ],
22
- graphRecipeCatalog: [
23
- {
24
- name: 'default',
25
- displayName: 'Default',
26
- description: 'Run all graph rules',
27
- tags: ['default'],
28
- selectorType: 'all',
29
- },
30
- ],
31
- });
32
- it('emits the graphRuleCatalog JS const carrying the rule slugs', () => {
33
- expect(html).toContain('const graphRuleCatalog =');
34
- expect(html).toContain('graph:orphan-subtree');
35
- expect(html).toContain('graph:duplicated-function-body');
36
- });
37
- it('emits the graphRecipeCatalog JS const carrying the recipe display name', () => {
38
- expect(html).toContain('const graphRecipeCatalog =');
39
- expect(html).toContain('Default');
40
- });
41
- it('keeps the graphRuleCatalog/graphRecipeCatalog consts distinct from the fitness check/recipe consts', () => {
42
- // The fitness-owned consts are still emitted; the graph consts must not
43
- // clobber them (distinct keys).
44
- expect(html).toContain('const checkCatalog =');
45
- expect(html).toContain('const recipeCatalog =');
46
- expect(html).toContain('const graphRuleCatalog =');
47
- expect(html).toContain('const graphRecipeCatalog =');
48
- });
49
- it('renders the Catalog rule cell without a monospace/font-mono override (item 13)', () => {
50
- // The Rule slug cell used to force font-family: var(--font-mono,monospace).
51
- // It must now inherit the shared .data-table td styling instead. Guard the
52
- // renderGraphRuleCatalog source against the regression. `renderGraphRuleCatalog`
53
- // now lives in the typed client bundle (L4) — esbuild emits double-quoted
54
- // strings, so the marker is the bundled (double-quote) form.
55
- const ruleCellMarker = 'el("td", { text: rule.slug,';
56
- const idx = html.indexOf(ruleCellMarker);
57
- expect(idx).toBeGreaterThan(-1);
58
- const cellDecl = html.slice(idx, idx + 120);
59
- expect(cellDecl).not.toContain('font-mono');
60
- expect(cellDecl).not.toContain('monospace');
61
- });
62
- it('gives .data-table td a shared font baseline (standard site font, 13px)', () => {
63
- // There are several `.data-table td` rules (containment default,
64
- // font baseline, …). Assert that the font baseline lives on one of
65
- // them rather than assuming a single rule / source order.
66
- const baselineRule = html
67
- .split('.data-table td')
68
- .find((seg) => seg.startsWith(' {') && seg.slice(0, seg.indexOf('}')).includes('font-size: 13px'));
69
- expect(baselineRule).toBeDefined();
70
- expect(baselineRule).toContain('font-family: var(--font)');
71
- });
72
- it('@opensip-cli/dashboard declares no @opensip-cli/graph dependency (decoupled)', () => {
73
- const pkg = JSON.parse(readFileSync(join(HERE, '..', '..', 'package.json'), 'utf8'));
74
- expect(pkg.dependencies?.['@opensip-cli/graph']).toBeUndefined();
75
- expect(pkg.devDependencies?.['@opensip-cli/graph']).toBeUndefined();
76
- });
77
- });
78
- //# sourceMappingURL=graph-tab.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"graph-tab.test.js","sourceRoot":"","sources":["../../src/__tests__/graph-tab.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,MAAM,IAAI,GAAG,qBAAqB,CAAC;QACjC,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE;YAChB,EAAE,IAAI,EAAE,sBAAsB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE;YAChF,EAAE,IAAI,EAAE,gCAAgC,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE;SAC3F;QACD,kBAAkB,EAAE;YAClB;gBACE,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,SAAS;gBACtB,WAAW,EAAE,qBAAqB;gBAClC,IAAI,EAAE,CAAC,SAAS,CAAC;gBACjB,YAAY,EAAE,KAAK;aACpB;SACF;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oGAAoG,EAAE,GAAG,EAAE;QAC5G,wEAAwE;QACxE,gCAAgC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,4EAA4E;QAC5E,2EAA2E;QAC3E,iFAAiF;QACjF,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,cAAc,GAAG,6BAA6B,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,iEAAiE;QACjE,mEAAmE;QACnE,0DAA0D;QAC1D,MAAM,YAAY,GAAG,IAAI;aACtB,KAAK,CAAC,gBAAgB,CAAC;aACvB,IAAI,CACH,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAC5F,CAAC;QACJ,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAGlF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,17 +0,0 @@
1
- /**
2
- * `el(tag, attrs, children)` — tiny DOM-builder helper used everywhere a string
3
- * of `document.createElement` + setAttribute calls would otherwise live.
4
- *
5
- * Special attribute keys: `text` sets `textContent`, `class` sets `className`,
6
- * anything starting with `on` is treated as an event listener (e.g. `onclick`),
7
- * everything else passes through to `setAttribute`. `children` may include strings
8
- * (auto-wrapped into text nodes) or `null`/`undefined` (skipped).
9
- *
10
- * First module migrated out of the legacy String.raw emitters (L4): real,
11
- * type-checked TypeScript (DOM lib) bundled into the inlined client `<script>`.
12
- */
13
- type ElAttrs = Record<string, unknown>;
14
- type ElChild = Node | string | null | undefined;
15
- export declare function el(tag: string, attrs?: ElAttrs, children?: readonly ElChild[]): HTMLElement;
16
- export {};
17
- //# sourceMappingURL=el.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"el.d.ts","sourceRoot":"","sources":["../../src/client/el.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvC,KAAK,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAEhD,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,WAAW,CAiB3F"}
package/dist/client/el.js DELETED
@@ -1,36 +0,0 @@
1
- /**
2
- * `el(tag, attrs, children)` — tiny DOM-builder helper used everywhere a string
3
- * of `document.createElement` + setAttribute calls would otherwise live.
4
- *
5
- * Special attribute keys: `text` sets `textContent`, `class` sets `className`,
6
- * anything starting with `on` is treated as an event listener (e.g. `onclick`),
7
- * everything else passes through to `setAttribute`. `children` may include strings
8
- * (auto-wrapped into text nodes) or `null`/`undefined` (skipped).
9
- *
10
- * First module migrated out of the legacy String.raw emitters (L4): real,
11
- * type-checked TypeScript (DOM lib) bundled into the inlined client `<script>`.
12
- */
13
- export function el(tag, attrs, children) {
14
- const e = document.createElement(tag);
15
- if (attrs)
16
- Object.entries(attrs).forEach(([k, v]) => {
17
- if (k === 'text')
18
- e.textContent = v;
19
- else if (k === 'class')
20
- e.className = v;
21
- else if (k.startsWith('on'))
22
- e.addEventListener(k.slice(2), v);
23
- else
24
- e.setAttribute(k, v);
25
- });
26
- if (children)
27
- children.forEach((c) => {
28
- // `append(string)` creates a text node — identical to the prior
29
- // appendChild(createTextNode(...)); `append(node)` appends the node. Skip
30
- // null/undefined; an empty string '' is still appended (as before).
31
- if (typeof c === 'string' || c)
32
- e.append(c);
33
- });
34
- return e;
35
- }
36
- //# sourceMappingURL=el.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"el.js","sourceRoot":"","sources":["../../src/client/el.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,UAAU,EAAE,CAAC,GAAW,EAAE,KAAe,EAAE,QAA6B;IAC5E,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,KAAK;QACP,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;YACvC,IAAI,CAAC,KAAK,MAAM;gBAAE,CAAC,CAAC,WAAW,GAAG,CAAW,CAAC;iBACzC,IAAI,CAAC,KAAK,OAAO;gBAAE,CAAC,CAAC,SAAS,GAAG,CAAW,CAAC;iBAC7C,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAkB,CAAC,CAAC;;gBAC3E,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAW,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,IAAI,QAAQ;QACV,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACrB,gEAAgE;YAChE,0EAA0E;YAC1E,oEAAoE;YACpE,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC;gBAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1,18 +0,0 @@
1
- /**
2
- * @vitest-environment jsdom
3
- *
4
- * Restructured Code Paths explore-tab set (Plan D — shipped).
5
- *
6
- * The explore-tab restructure has shipped: the Code Paths bundle registers
7
- * exactly the kept views (graph / coupling) plus the ranked-distribution
8
- * "Functions" affordance, and the single-metric / standalone-SCC view sources
9
- * were deleted. The former standalone Search subtab was folded into the
10
- * Functions view as an in-table name filter, so it no longer registers a
11
- * `search` view.
12
- *
13
- * The views now live in the typed client bundle (L4) and register themselves
14
- * into the bundle's `views` global at load; this test boots the bundle and reads
15
- * the registered ids (the old string-emitter source match is gone).
16
- */
17
- export {};
18
- //# sourceMappingURL=views-registry.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"views-registry.test.d.ts","sourceRoot":"","sources":["../../../src/code-paths/__tests__/views-registry.test.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;GAeG"}
@@ -1,41 +0,0 @@
1
- /// <reference lib="dom" />
2
- /**
3
- * @vitest-environment jsdom
4
- *
5
- * Restructured Code Paths explore-tab set (Plan D — shipped).
6
- *
7
- * The explore-tab restructure has shipped: the Code Paths bundle registers
8
- * exactly the kept views (graph / coupling) plus the ranked-distribution
9
- * "Functions" affordance, and the single-metric / standalone-SCC view sources
10
- * were deleted. The former standalone Search subtab was folded into the
11
- * Functions view as an in-table name filter, so it no longer registers a
12
- * `search` view.
13
- *
14
- * The views now live in the typed client bundle (L4) and register themselves
15
- * into the bundle's `views` global at load; this test boots the bundle and reads
16
- * the registered ids (the old string-emitter source match is gone).
17
- */
18
- import { describe, expect, it } from 'vitest';
19
- import { DASHBOARD_CLIENT_BUNDLE } from '../../client-bundle.generated.js';
20
- function registeredViewIds() {
21
- const head = `
22
- var sessions = [];
23
- var EDITOR_PROTOCOL = null;
24
- `;
25
- const tail = `return views.map(function(v) { return v.id; });`;
26
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, sonarjs/code-eval -- Trusted source: our own bundled dashboard JS.
27
- const factory = new Function(head + DASHBOARD_CLIENT_BUNDLE + tail);
28
- return factory();
29
- }
30
- describe('Code Paths explore-tab set', () => {
31
- it('bundle registers exactly {graph, coupling, distribution}', () => {
32
- expect(new Set(registeredViewIds())).toEqual(new Set(['graph', 'coupling', 'distribution']));
33
- });
34
- it('drops the single-metric + standalone-SCC + standalone-search views', () => {
35
- const ids = registeredViewIds();
36
- for (const removed of ['big', 'hot', 'wide', 'untested', 'sccs', 'search']) {
37
- expect(ids).not.toContain(removed);
38
- }
39
- });
40
- });
41
- //# sourceMappingURL=views-registry.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"views-registry.test.js","sourceRoot":"","sources":["../../../src/code-paths/__tests__/views-registry.test.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG;;;CAGd,CAAC;IACA,MAAM,IAAI,GAAG,iDAAiD,CAAC;IAC/D,kIAAkI;IAClI,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,GAAG,uBAAuB,GAAG,IAAI,CAAC,CAAC;IACpE,OAAO,OAAO,EAAc,CAAC;AAC/B,CAAC;AAED,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC3E,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}