@memlab/mcp-server 2.3.0 → 2.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +18 -14
  2. package/bin/.eslintrc.js +26 -0
  3. package/bin/memlab-cli.js +313 -0
  4. package/dist/artifact-classes.d.ts +86 -0
  5. package/dist/artifact-classes.d.ts.map +1 -0
  6. package/dist/artifact-classes.js +261 -0
  7. package/dist/artifact-classes.js.map +1 -0
  8. package/dist/capture-mode.d.ts +60 -0
  9. package/dist/capture-mode.d.ts.map +1 -0
  10. package/dist/capture-mode.js +39 -0
  11. package/dist/capture-mode.js.map +1 -0
  12. package/dist/guardrail.d.ts.map +1 -1
  13. package/dist/guardrail.js +13 -0
  14. package/dist/guardrail.js.map +1 -1
  15. package/dist/heap-state.d.ts +96 -2
  16. package/dist/heap-state.d.ts.map +1 -1
  17. package/dist/heap-state.js +197 -2
  18. package/dist/heap-state.js.map +1 -1
  19. package/dist/index.js +41 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/progress.d.ts +25 -0
  22. package/dist/progress.d.ts.map +1 -0
  23. package/dist/progress.js +46 -0
  24. package/dist/progress.js.map +1 -0
  25. package/dist/result-handles.d.ts +11 -0
  26. package/dist/result-handles.d.ts.map +1 -0
  27. package/dist/result-handles.js +77 -0
  28. package/dist/result-handles.js.map +1 -0
  29. package/dist/string-index.d.ts +55 -0
  30. package/dist/string-index.d.ts.map +1 -0
  31. package/dist/string-index.js +91 -0
  32. package/dist/string-index.js.map +1 -0
  33. package/dist/tool-registry.d.ts +42 -0
  34. package/dist/tool-registry.d.ts.map +1 -0
  35. package/dist/tool-registry.js +20 -0
  36. package/dist/tool-registry.js.map +1 -0
  37. package/dist/tools/analyze-run.d.ts +12 -0
  38. package/dist/tools/analyze-run.d.ts.map +1 -0
  39. package/dist/tools/analyze-run.js +343 -0
  40. package/dist/tools/analyze-run.js.map +1 -0
  41. package/dist/tools/app-heap.d.ts +12 -0
  42. package/dist/tools/app-heap.d.ts.map +1 -0
  43. package/dist/tools/app-heap.js +140 -0
  44. package/dist/tools/app-heap.js.map +1 -0
  45. package/dist/tools/auto-investigate.d.ts.map +1 -1
  46. package/dist/tools/auto-investigate.js +91 -49
  47. package/dist/tools/auto-investigate.js.map +1 -1
  48. package/dist/tools/batch.d.ts +12 -0
  49. package/dist/tools/batch.d.ts.map +1 -0
  50. package/dist/tools/batch.js +168 -0
  51. package/dist/tools/batch.js.map +1 -0
  52. package/dist/tools/cache-analysis.d.ts.map +1 -1
  53. package/dist/tools/cache-analysis.js +156 -5
  54. package/dist/tools/cache-analysis.js.map +1 -1
  55. package/dist/tools/class-histogram.d.ts.map +1 -1
  56. package/dist/tools/class-histogram.js +14 -3
  57. package/dist/tools/class-histogram.js.map +1 -1
  58. package/dist/tools/collection-trend.d.ts +55 -0
  59. package/dist/tools/collection-trend.d.ts.map +1 -0
  60. package/dist/tools/collection-trend.js +315 -0
  61. package/dist/tools/collection-trend.js.map +1 -0
  62. package/dist/tools/detached-dom.d.ts +2 -0
  63. package/dist/tools/detached-dom.d.ts.map +1 -1
  64. package/dist/tools/detached-dom.js +291 -20
  65. package/dist/tools/detached-dom.js.map +1 -1
  66. package/dist/tools/dev-artifacts.d.ts +62 -6
  67. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  68. package/dist/tools/dev-artifacts.js +466 -23
  69. package/dist/tools/dev-artifacts.js.map +1 -1
  70. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  71. package/dist/tools/diff-snapshots.js +101 -44
  72. package/dist/tools/diff-snapshots.js.map +1 -1
  73. package/dist/tools/dominator-attribution.d.ts +12 -0
  74. package/dist/tools/dominator-attribution.d.ts.map +1 -0
  75. package/dist/tools/dominator-attribution.js +189 -0
  76. package/dist/tools/dominator-attribution.js.map +1 -0
  77. package/dist/tools/dominator-chain.d.ts +12 -0
  78. package/dist/tools/dominator-chain.d.ts.map +1 -0
  79. package/dist/tools/dominator-chain.js +92 -0
  80. package/dist/tools/dominator-chain.js.map +1 -0
  81. package/dist/tools/duplicate-objects.d.ts +12 -0
  82. package/dist/tools/duplicate-objects.d.ts.map +1 -0
  83. package/dist/tools/duplicate-objects.js +172 -0
  84. package/dist/tools/duplicate-objects.js.map +1 -0
  85. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  86. package/dist/tools/duplicated-strings.js +46 -38
  87. package/dist/tools/duplicated-strings.js.map +1 -1
  88. package/dist/tools/eval.d.ts +1 -0
  89. package/dist/tools/eval.d.ts.map +1 -1
  90. package/dist/tools/eval.js +787 -30
  91. package/dist/tools/eval.js.map +1 -1
  92. package/dist/tools/explain-delta.d.ts +12 -0
  93. package/dist/tools/explain-delta.d.ts.map +1 -0
  94. package/dist/tools/explain-delta.js +170 -0
  95. package/dist/tools/explain-delta.js.map +1 -0
  96. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  97. package/dist/tools/find-nodes-by-class.js +112 -13
  98. package/dist/tools/find-nodes-by-class.js.map +1 -1
  99. package/dist/tools/finding-index.d.ts +22 -0
  100. package/dist/tools/finding-index.d.ts.map +1 -0
  101. package/dist/tools/finding-index.js +247 -0
  102. package/dist/tools/finding-index.js.map +1 -0
  103. package/dist/tools/for-each.d.ts.map +1 -1
  104. package/dist/tools/for-each.js +15 -3
  105. package/dist/tools/for-each.js.map +1 -1
  106. package/dist/tools/get-references.d.ts.map +1 -1
  107. package/dist/tools/get-references.js +35 -6
  108. package/dist/tools/get-references.js.map +1 -1
  109. package/dist/tools/get-referrers.d.ts.map +1 -1
  110. package/dist/tools/get-referrers.js +52 -6
  111. package/dist/tools/get-referrers.js.map +1 -1
  112. package/dist/tools/hunt-report.d.ts +12 -0
  113. package/dist/tools/hunt-report.d.ts.map +1 -0
  114. package/dist/tools/hunt-report.js +186 -0
  115. package/dist/tools/hunt-report.js.map +1 -0
  116. package/dist/tools/hypothesis.d.ts +12 -0
  117. package/dist/tools/hypothesis.d.ts.map +1 -0
  118. package/dist/tools/hypothesis.js +221 -0
  119. package/dist/tools/hypothesis.js.map +1 -0
  120. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  121. package/dist/tools/intern-opportunities.js +721 -75
  122. package/dist/tools/intern-opportunities.js.map +1 -1
  123. package/dist/tools/ladder.d.ts +33 -0
  124. package/dist/tools/ladder.d.ts.map +1 -0
  125. package/dist/tools/ladder.js +266 -0
  126. package/dist/tools/ladder.js.map +1 -0
  127. package/dist/tools/largest-objects.d.ts.map +1 -1
  128. package/dist/tools/largest-objects.js +43 -16
  129. package/dist/tools/largest-objects.js.map +1 -1
  130. package/dist/tools/leak-report.d.ts +12 -0
  131. package/dist/tools/leak-report.d.ts.map +1 -0
  132. package/dist/tools/leak-report.js +256 -0
  133. package/dist/tools/leak-report.js.map +1 -0
  134. package/dist/tools/load-snapshot.d.ts +78 -0
  135. package/dist/tools/load-snapshot.d.ts.map +1 -1
  136. package/dist/tools/load-snapshot.js +519 -29
  137. package/dist/tools/load-snapshot.js.map +1 -1
  138. package/dist/tools/map-entries.d.ts +12 -0
  139. package/dist/tools/map-entries.d.ts.map +1 -0
  140. package/dist/tools/map-entries.js +139 -0
  141. package/dist/tools/map-entries.js.map +1 -0
  142. package/dist/tools/match-object.d.ts +12 -0
  143. package/dist/tools/match-object.d.ts.map +1 -0
  144. package/dist/tools/match-object.js +165 -0
  145. package/dist/tools/match-object.js.map +1 -0
  146. package/dist/tools/object-shape.d.ts.map +1 -1
  147. package/dist/tools/object-shape.js +92 -30
  148. package/dist/tools/object-shape.js.map +1 -1
  149. package/dist/tools/population-diff.d.ts +57 -0
  150. package/dist/tools/population-diff.d.ts.map +1 -0
  151. package/dist/tools/population-diff.js +338 -0
  152. package/dist/tools/population-diff.js.map +1 -0
  153. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  154. package/dist/tools/quick-diagnosis.js +12 -4
  155. package/dist/tools/quick-diagnosis.js.map +1 -1
  156. package/dist/tools/retainer-layers.d.ts +23 -0
  157. package/dist/tools/retainer-layers.d.ts.map +1 -0
  158. package/dist/tools/retainer-layers.js +179 -0
  159. package/dist/tools/retainer-layers.js.map +1 -0
  160. package/dist/tools/retainer-summary.d.ts +1 -0
  161. package/dist/tools/retainer-summary.d.ts.map +1 -1
  162. package/dist/tools/retainer-summary.js +128 -32
  163. package/dist/tools/retainer-summary.js.map +1 -1
  164. package/dist/tools/retainer-trace.d.ts.map +1 -1
  165. package/dist/tools/retainer-trace.js +105 -25
  166. package/dist/tools/retainer-trace.js.map +1 -1
  167. package/dist/tools/search-nodes.d.ts.map +1 -1
  168. package/dist/tools/search-nodes.js +5 -1
  169. package/dist/tools/search-nodes.js.map +1 -1
  170. package/dist/tools/search-strings.d.ts.map +1 -1
  171. package/dist/tools/search-strings.js +53 -7
  172. package/dist/tools/search-strings.js.map +1 -1
  173. package/dist/tools/sequence-analysis.d.ts +49 -0
  174. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  175. package/dist/tools/sequence-analysis.js +268 -78
  176. package/dist/tools/sequence-analysis.js.map +1 -1
  177. package/dist/tools/shape-histogram.d.ts.map +1 -1
  178. package/dist/tools/shape-histogram.js +9 -2
  179. package/dist/tools/shape-histogram.js.map +1 -1
  180. package/dist/tools/sliced-strings.d.ts.map +1 -1
  181. package/dist/tools/sliced-strings.js +22 -4
  182. package/dist/tools/sliced-strings.js.map +1 -1
  183. package/dist/tools/snapshot-header.d.ts +28 -0
  184. package/dist/tools/snapshot-header.d.ts.map +1 -0
  185. package/dist/tools/snapshot-header.js +111 -0
  186. package/dist/tools/snapshot-header.js.map +1 -0
  187. package/dist/tools/string-patterns.d.ts.map +1 -1
  188. package/dist/tools/string-patterns.js +5 -4
  189. package/dist/tools/string-patterns.js.map +1 -1
  190. package/dist/tools/tools-index.d.ts +12 -0
  191. package/dist/tools/tools-index.d.ts.map +1 -0
  192. package/dist/tools/tools-index.js +342 -0
  193. package/dist/tools/tools-index.js.map +1 -0
  194. package/dist/tools/verify-fix.d.ts +23 -0
  195. package/dist/tools/verify-fix.d.ts.map +1 -0
  196. package/dist/tools/verify-fix.js +211 -0
  197. package/dist/tools/verify-fix.js.map +1 -0
  198. package/dist/tools/weakmap-entries.d.ts.map +1 -1
  199. package/dist/tools/weakmap-entries.js +6 -1
  200. package/dist/tools/weakmap-entries.js.map +1 -1
  201. package/dist/utils.d.ts +204 -1
  202. package/dist/utils.d.ts.map +1 -1
  203. package/dist/utils.js +478 -8
  204. package/dist/utils.js.map +1 -1
  205. package/package.json +5 -4
@@ -9,8 +9,10 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import { getSnapshot, getSnapshotEnv } from '../heap-state.js';
12
- import { queryNodes, formatQueryNodesResult, formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
13
- import { collectDevRoots, classifyDevOnly } from './dev-artifacts.js';
12
+ import { queryNodes, formatQueryNodesResult, formatBytes, formatNumber, isNodeWorthInspecting, markdownTable, truncateNodeName, errorResult, toolResult, boundedDominatorRetainedSize, } from '../utils.js';
13
+ import memlabCore from '@memlab/core';
14
+ const { NumericSet } = memlabCore;
15
+ import { collectDevRoots, classifyDevOnly, computeReachableWithoutDevRoots, summarizeDevRoots, } from './dev-artifacts.js';
14
16
  function isDetachedDOMNode(node) {
15
17
  if (node.id <= 3)
16
18
  return false;
@@ -18,6 +20,40 @@ function isDetachedDOMNode(node) {
18
20
  return true;
19
21
  return node.name.startsWith('Detached ');
20
22
  }
23
+ // A detached node is only an actual leak if it is still reachable from a GC
24
+ // root — i.e. it has a shortest-path retainer edge. Detached nodes with NO
25
+ // retainer path found are typically GC-eligible (about to be collected) or
26
+ // retained only through weak references, and should not be counted toward a
27
+ // leak total. This distinguishes the "which half is real" problem where a
28
+ // snapshot's detached-node list mixes genuinely-pinned nodes with transient
29
+ // ones. `hasPathEdge` is the same reachability signal used to walk retainers.
30
+ function isPinned(node) {
31
+ return Boolean(node.hasPathEdge);
32
+ }
33
+ function emptySplit() {
34
+ return {
35
+ pinnedCount: 0,
36
+ pinnedRetained: 0,
37
+ noPathCount: 0,
38
+ noPathRetained: 0,
39
+ pinnedIds: [],
40
+ };
41
+ }
42
+ /**
43
+ * Two different numbers, and quoting the wrong one has produced published
44
+ * errors: on one round the plain sum read 9.7 MB where the amount actually
45
+ * reclaimable was 308 KB. Lead with the dominator-deduped figure and keep the
46
+ * sum visible but explicitly labelled.
47
+ */
48
+ function formatReachabilitySplit(split, snapshot) {
49
+ const deduped = boundedDominatorRetainedSize(new NumericSet(split.pinnedIds), snapshot);
50
+ const bound = deduped.exact ? '' : ' (upper bound; deep dominator chain)';
51
+ return [
52
+ `- Pinned (retainer path to a GC root — actionable leak): ${formatNumber(split.pinnedCount)} nodes, **${formatBytes(deduped.retained)} reclaimable**${bound} (dominator-deduped)`,
53
+ ` - sum over nodes: ${formatBytes(split.pinnedRetained)} — double-counts nested detached subtrees; do NOT quote this as the size of the leak`,
54
+ `- No retainer path found (likely GC-eligible / weak-only — exclude from leak totals): ${formatNumber(split.noPathCount)} nodes, ${formatBytes(split.noPathRetained)}`,
55
+ ];
56
+ }
21
57
  function extractElementTag(name) {
22
58
  // V8 names detached DOM as "Detached <div>" or "Detached <div class="...">"
23
59
  const match = name.match(/^(?:Detached\s+)?<(\w+)/);
@@ -30,7 +66,7 @@ function extractTestId(node) {
30
66
  return testIdMatch[1];
31
67
  return '(no testid)';
32
68
  }
33
- function getFirstNonFrameworkRetainer(node) {
69
+ export function getFirstNonFrameworkRetainer(node) {
34
70
  const frameworkNames = new Set([
35
71
  'system / Context',
36
72
  '(GC roots)',
@@ -55,14 +91,94 @@ function getFirstNonFrameworkRetainer(node) {
55
91
  from.type !== 'synthetic' &&
56
92
  from.type !== 'native') {
57
93
  const edgeName = String(edge.name_or_index);
58
- return `${from.name} (${from.type}) .${edgeName}`;
94
+ // V8 leaves anonymous functions/objects unnamed; printing the empty
95
+ // string renders as a leading blank that reads like a formatting bug.
96
+ const fromName = from.name.length > 0 ? from.name : '(anonymous)';
97
+ return `${fromName} (${from.type}) .${edgeName}`;
59
98
  }
60
99
  cur = from;
61
100
  }
62
101
  return '(unknown)';
63
102
  }
103
+ // Climbing more than this many dominator hops means the detached subtree is
104
+ // pathologically deep; give up rather than pay for it on every node.
105
+ const MAX_DOMINATOR_HOPS = 64;
106
+ // Distinct owners tracked per group before the count is reported as "N+".
107
+ // Bounds memory when a group spans one owner per node (100k+ detached nodes).
108
+ const MAX_TRACKED_OWNERS = 1000;
109
+ /**
110
+ * Resolve the node that is ACCOUNTABLE for a detached node: the nearest
111
+ * dominator above it that is not itself detached DOM and is worth naming.
112
+ *
113
+ * Why this is not the same as `getFirstNonFrameworkRetainer`: that walks the
114
+ * shortest RETAINER path, which is only one of possibly many references and need
115
+ * not dominate the node at all. Grouping by it and then saying "fixing this
116
+ * frees X" is wrong whenever the group's nodes are also held elsewhere — the
117
+ * whole point of the dominator tree is that freeing a dominator DOES free
118
+ * everything below it.
119
+ *
120
+ * Returns a resolver closure rather than a bare function so the walk can be
121
+ * memoized: sibling detached nodes share ancestors, and every chain member's
122
+ * answer is the same node. Cached entries are per-load only (the closure lives
123
+ * for one tool call).
124
+ */
125
+ function makeDominatorResolver() {
126
+ const cache = new Map();
127
+ return function resolve(node) {
128
+ const chain = [];
129
+ const seen = new Set([node.id]);
130
+ let cur = node.dominatorNode ?? null;
131
+ let owner = null;
132
+ let hops = 0;
133
+ // Whether the walk ended for a reason intrinsic to the graph (found an
134
+ // owner, or ran out of dominators) rather than because THIS walk ran out of
135
+ // budget. Only an intrinsic result may be memoized — see below.
136
+ let conclusive = false;
137
+ while (cur && hops < MAX_DOMINATOR_HOPS) {
138
+ const cached = cache.get(cur.id);
139
+ if (cached !== undefined) {
140
+ owner = cached;
141
+ conclusive = true;
142
+ break;
143
+ }
144
+ if (seen.has(cur.id))
145
+ break;
146
+ seen.add(cur.id);
147
+ chain.push(cur.id);
148
+ if (!isDetachedDOMNode(cur) &&
149
+ cur.name !== '(GC roots)' &&
150
+ isNodeWorthInspecting(cur)) {
151
+ owner = cur;
152
+ conclusive = true;
153
+ break;
154
+ }
155
+ const next = cur.dominatorNode ?? null;
156
+ if (!next || next.id === cur.id) {
157
+ // The chain genuinely ends here: there is no owner above, and that is a
158
+ // property of the graph, not of this walk.
159
+ conclusive = true;
160
+ break;
161
+ }
162
+ cur = next;
163
+ hops++;
164
+ }
165
+ // Memoize ONLY a conclusive result. Caching a hop-cap or cycle-break exit
166
+ // would store "no owner" — a fact about this walk's 64-hop budget — as if it
167
+ // were a fact about the node. A later, deeper node whose own budget WOULD
168
+ // have reached a real owner then short-circuits on the poisoned entry and is
169
+ // reported as "no single owner", which is precisely the unsound ownership
170
+ // claim this grouping exists to eliminate.
171
+ if (conclusive) {
172
+ for (const id of chain)
173
+ cache.set(id, owner);
174
+ }
175
+ return owner;
176
+ };
177
+ }
64
178
  export function registerDetachedDom(server) {
65
- server.tool('memlab_detached_dom', 'Find detached DOM elements still retained in memory. These are common sources of memory leaks — DOM nodes removed from the document but kept alive by JavaScript references. Supports count-only and ids-only modes for large result sets. Use group_by to aggregate by element tag, retainer pattern, or data-testid. ' +
179
+ server.tool('memlab_detached_dom', 'Find detached DOM elements still retained in memory. These are common sources of memory leaks — DOM nodes removed from the document but kept alive by JavaScript references. Supports count-only and ids-only modes for large result sets. Use group_by to aggregate by dominator (accountable owner), element tag, retainer pattern, or data-testid. ' +
180
+ 'Prefer group_by: "dominator" when you intend to act on the result: it groups by the nearest non-detached DOMINATOR, so releasing that one object provably frees the whole group. The other groupings key on a shortest retainer path, which need not dominate the nodes — they report an "Owners" column (distinct accountable dominators) so a group split across many owners is not mistaken for a single fix. ' +
181
+ 'Reports a pinned-vs-GC-eligible split: detached nodes with a retainer path to a GC root are actual leaks, while nodes with no retainer path found are typically GC-eligible (transient / weak-only) and should be excluded from leak totals — set only_with_retainer_path to list/aggregate just the pinned ones. ' +
66
182
  '⚠ Full-heap scan — slow on very large heaps (millions of nodes); use count-only / ids-only modes and group_by to bound output.', {
67
183
  output_mode: z
68
184
  .enum(['full', 'count', 'ids'])
@@ -70,9 +186,9 @@ export function registerDetachedDom(server) {
70
186
  .default('full')
71
187
  .describe('Output verbosity: "full" returns node summaries (default), "count" returns only the total count, "ids" returns only node IDs'),
72
188
  group_by: z
73
- .enum(['element', 'retainer', 'testid'])
189
+ .enum(['element', 'retainer', 'testid', 'dominator'])
74
190
  .optional()
75
- .describe('Group detached DOM nodes instead of listing individually. "element" groups by HTML tag (div, span, button), "retainer" groups by first non-framework retainer (the component/module holding them), "testid" groups by data-testid attribute.'),
191
+ .describe('Group detached DOM nodes instead of listing individually. "dominator" groups by the nearest non-detached dominator — the object that provably frees the whole group when released (use this to decide what to fix); "element" groups by HTML tag (div, span, button); "retainer" groups by first non-framework retainer on the shortest path (which need not dominate the nodes); "testid" groups by data-testid attribute.'),
76
192
  offset: z
77
193
  .number()
78
194
  .optional()
@@ -87,8 +203,13 @@ export function registerDetachedDom(server) {
87
203
  .boolean()
88
204
  .optional()
89
205
  .default(true)
90
- .describe("Report how much detached DOM is retained ONLY via dev/extension globals (__REACT_DEVTOOLS_GLOBAL_HOOK__, window.Debug, …) and would be GC'd in production (default true). Use memlab_dev_artifacts for the full breakdown."),
91
- }, async ({ output_mode, group_by, offset, limit, classify_dev_only }) => {
206
+ .describe('Report how much detached DOM is retained ONLY via dev/automation artifacts — dev/extension globals (__REACT_DEVTOOLS_GLOBAL_HOOK__, window.Debug, …) or the Blink a11y/CDP cache (AXObjectCacheImpl, which co-retains detached DOM under automation) — and so should be excluded from production leak totals (default true). Use memlab_dev_artifacts for the full breakdown.'),
207
+ only_with_retainer_path: z
208
+ .boolean()
209
+ .optional()
210
+ .default(false)
211
+ .describe('Only include detached nodes that have a retainer path to a GC root (i.e. actually pinned / leaked). When false (default) all detached nodes are included, but the summary always reports the pinned-vs-GC-eligible split so transient / weak-only detached DOM is not mistaken for a leak.'),
212
+ }, async ({ output_mode, group_by, offset, limit, classify_dev_only, only_with_retainer_path, }) => {
92
213
  try {
93
214
  const env = getSnapshotEnv();
94
215
  if (env === 'node') {
@@ -101,19 +222,47 @@ export function registerDetachedDom(server) {
101
222
  }
102
223
  const snapshot = getSnapshot();
103
224
  const devRoots = classify_dev_only ? collectDevRoots(snapshot) : null;
225
+ // Reachability pass (dev roots as sinks) so co-retention via multiple
226
+ // dev roots — e.g. detached DOM held by BOTH the DevTools console and
227
+ // the a11y cache — is correctly counted as a dev/automation artifact.
228
+ const reached = devRoots && devRoots.byId.size > 0
229
+ ? computeReachableWithoutDevRoots(snapshot, devRoots)
230
+ : undefined;
104
231
  if (group_by) {
105
232
  const groups = new Map();
233
+ const resolveOwner = makeDominatorResolver();
106
234
  let totalDetached = 0;
107
235
  let totalRetainedAll = 0;
108
236
  let devOnlyRetained = 0;
237
+ const split = emptySplit();
109
238
  snapshot.nodes.forEach(node => {
110
239
  if (!isDetachedDOMNode(node))
111
240
  return;
112
241
  totalDetached++;
113
242
  totalRetainedAll += node.retainedSize;
114
- if (devRoots && classifyDevOnly(node, devRoots).devOnly) {
243
+ const pinned = isPinned(node);
244
+ if (pinned) {
245
+ split.pinnedCount++;
246
+ split.pinnedRetained += node.retainedSize;
247
+ split.pinnedIds.push(node.id);
248
+ }
249
+ else {
250
+ split.noPathCount++;
251
+ split.noPathRetained += node.retainedSize;
252
+ }
253
+ const nodeIsDevOnly = devRoots
254
+ ? classifyDevOnly(node, devRoots, reached).devOnly
255
+ : false;
256
+ if (nodeIsDevOnly) {
115
257
  devOnlyRetained += node.retainedSize;
116
258
  }
259
+ // With only_with_retainer_path, exclude GC-eligible (no-path) nodes
260
+ // from the group aggregation — they are still counted in the split.
261
+ if (only_with_retainer_path && !pinned)
262
+ return;
263
+ // Resolved for every grouping, not just 'dominator': the other keys
264
+ // need it to report how many distinct owners they span.
265
+ const owner = resolveOwner(node);
117
266
  let key;
118
267
  switch (group_by) {
119
268
  case 'element':
@@ -125,11 +274,33 @@ export function registerDetachedDom(server) {
125
274
  case 'testid':
126
275
  key = extractTestId(node);
127
276
  break;
277
+ case 'dominator':
278
+ // No owner = the dominator is the GC root itself, i.e. the node
279
+ // is reachable through two or more independent paths. Naming
280
+ // that outcome matters more than the others: it is precisely the
281
+ // case where "fix this retainer and X is freed" is false.
282
+ key = owner
283
+ ? `@${owner.id} ${truncateNodeName(owner.name, owner.type, owner.self_size, 60)}`
284
+ : '(no single owner — dominated by the GC root, i.e. reachable via ≥2 independent paths)';
285
+ break;
128
286
  }
129
287
  const existing = groups.get(key);
130
288
  if (existing) {
131
289
  existing.count++;
132
290
  existing.totalRetained += node.retainedSize;
291
+ if (nodeIsDevOnly)
292
+ existing.devOnlyCount++;
293
+ if (owner) {
294
+ if (existing.ownerIds.size < MAX_TRACKED_OWNERS) {
295
+ existing.ownerIds.add(owner.id);
296
+ }
297
+ else if (!existing.ownerIds.has(owner.id)) {
298
+ existing.ownersTruncated = true;
299
+ }
300
+ }
301
+ else {
302
+ existing.ownerlessCount++;
303
+ }
133
304
  if (node.retainedSize > existing.maxRetainedSize) {
134
305
  existing.exampleId = node.id;
135
306
  existing.maxRetainedSize = node.retainedSize;
@@ -141,10 +312,26 @@ export function registerDetachedDom(server) {
141
312
  totalRetained: node.retainedSize,
142
313
  exampleId: node.id,
143
314
  maxRetainedSize: node.retainedSize,
315
+ devOnlyCount: nodeIsDevOnly ? 1 : 0,
316
+ ownerIds: new Set(owner ? [owner.id] : []),
317
+ ownersTruncated: false,
318
+ ownerlessCount: owner ? 0 : 1,
319
+ // The owner's own retained size, not the sum of the group's
320
+ // detached nodes: releasing it frees everything it dominates.
321
+ ownerRetained: owner ? owner.retainedSize : 0,
144
322
  });
145
323
  }
146
324
  });
147
325
  if (groups.size === 0) {
326
+ if (totalDetached > 0) {
327
+ return toolResult([
328
+ `Detached DOM grouped by ${group_by}: ${formatNumber(totalDetached)} total nodes, ${formatBytes(totalRetainedAll)} total retained`,
329
+ ...formatReachabilitySplit(split, snapshot),
330
+ only_with_retainer_path
331
+ ? '_No pinned (retainer-path) detached nodes — all detached DOM is GC-eligible / weak-only, not a leak._'
332
+ : '',
333
+ ].join('\n'));
334
+ }
148
335
  return toolResult('No detached DOM nodes found.');
149
336
  }
150
337
  const sorted = [...groups.entries()]
@@ -154,15 +341,36 @@ export function registerDetachedDom(server) {
154
341
  ? 'Element'
155
342
  : group_by === 'retainer'
156
343
  ? 'Retainer'
157
- : 'data-testid';
344
+ : group_by === 'dominator'
345
+ ? 'Dominator (accountable owner)'
346
+ : 'data-testid';
347
+ // Per-group dev-only share. Without this the caller has to run
348
+ // dev_artifacts separately and mentally join the two outputs, which is
349
+ // exactly the step that gets skipped before a group is reported as a
350
+ // production leak.
351
+ const showDevOnly = devRoots != null &&
352
+ sorted.some(([, stats]) => stats.devOnlyCount > 0);
353
+ // In dominator mode the owner count is 1 by construction, so the
354
+ // interesting column is what that owner frees; for every other
355
+ // grouping it is how many owners the group is split across.
356
+ const isDominatorMode = group_by === 'dominator';
357
+ const ownerCountLabel = (stats) => {
358
+ const n = stats.ownerIds.size;
359
+ const shown = stats.ownersTruncated ? `${n}+` : String(n);
360
+ if (n === 0)
361
+ return stats.ownerlessCount > 0 ? 'none' : '-';
362
+ return stats.ownerlessCount > 0 ? `${shown} (+unowned)` : shown;
363
+ };
158
364
  const headers = [
159
365
  groupLabel,
160
366
  'Count',
367
+ ...(showDevOnly ? ['Dev-only'] : []),
161
368
  'Total Retained',
162
369
  '% of Detached',
370
+ ...(isDominatorMode ? ['Owner Frees'] : ['Owners']),
163
371
  'Example ID',
164
372
  ];
165
- const rightCols = new Set([1, 2, 3]);
373
+ const rightCols = new Set(showDevOnly ? [1, 2, 3, 4, 5] : [1, 2, 3, 4]);
166
374
  const rows = sorted.map(([key, stats]) => {
167
375
  const pct = totalRetainedAll > 0
168
376
  ? ((stats.totalRetained / totalRetainedAll) * 100).toFixed(1) +
@@ -171,44 +379,107 @@ export function registerDetachedDom(server) {
171
379
  return [
172
380
  key.length > 60 ? key.slice(0, 57) + '...' : key,
173
381
  formatNumber(stats.count),
382
+ ...(showDevOnly
383
+ ? [
384
+ stats.devOnlyCount === 0
385
+ ? '—'
386
+ : stats.devOnlyCount === stats.count
387
+ ? 'ALL'
388
+ : `${formatNumber(stats.devOnlyCount)}/${formatNumber(stats.count)}`,
389
+ ]
390
+ : []),
174
391
  formatBytes(stats.totalRetained),
175
392
  pct,
393
+ isDominatorMode
394
+ ? stats.ownerRetained > 0
395
+ ? formatBytes(stats.ownerRetained)
396
+ : '-'
397
+ : ownerCountLabel(stats),
176
398
  `@${stats.exampleId}`,
177
399
  ];
178
400
  });
179
401
  const lines = [
180
402
  `Detached DOM grouped by ${group_by}: ${formatNumber(totalDetached)} total nodes, ${formatBytes(totalRetainedAll)} total retained`,
181
- '',
182
- markdownTable(headers, rows, rightCols),
403
+ ...formatReachabilitySplit(split, snapshot),
183
404
  ];
405
+ if (only_with_retainer_path) {
406
+ lines.push('_(groups below show pinned nodes only)_');
407
+ }
408
+ lines.push('', markdownTable(headers, rows, rightCols));
409
+ if (isDominatorMode) {
410
+ const ownerless = sorted.find(([, s]) => s.ownerIds.size === 0 && s.ownerlessCount > 0);
411
+ lines.push('', "_Grouped by the nearest non-detached **dominator**: releasing that object frees every detached node in its row. **Owner Frees** is the owner's own retained size — the true, non-overlapping figure, and the amount actually reclaimed (it also covers whatever else the owner holds). Total Retained is a plain sum over the group, so it double-counts nested detached subtrees and can exceed Owner Frees._");
412
+ if (ownerless) {
413
+ lines.push(`_⚠ ${formatNumber(ownerless[1].count)} node(s) (${formatBytes(ownerless[1].totalRetained)}) have **no single owner** — their dominator is the GC root, so they are reachable through two or more independent paths and no one object frees them. Use \`memlab_retainer_summary\` / \`memlab_get_referrers\` to enumerate every path; all of them must be cut._`);
414
+ }
415
+ }
416
+ else {
417
+ const notSingleOwner = sorted.filter(([, s]) => s.ownerIds.size === 0 ||
418
+ s.ownerIds.size + (s.ownerlessCount > 0 ? 1 : 0) > 1).length;
419
+ lines.push('', `_**Owners** = distinct accountable dominators the group spans (\`none\` = dominated by the GC root, i.e. reachable via ≥2 independent paths). This grouping keys on ${group_by === 'retainer' ? 'the first non-framework retainer along the SHORTEST retainer path, which need not dominate the nodes' : `the node's ${group_by}`}, so only a group with **Owners = 1** is freed by fixing one object.${notSingleOwner > 0 ? ` ${formatNumber(notSingleOwner)} of the ${formatNumber(sorted.length)} groups below are not single-owner — for those, "fixing this frees X" is wrong; re-run with \`group_by: "dominator"\` to see what actually frees them.` : ''}_`);
420
+ }
184
421
  if (devRoots && devRoots.byId.size > 0 && devOnlyRetained > 0) {
185
422
  const pct = totalRetainedAll > 0
186
423
  ? ((devOnlyRetained / totalRetainedAll) * 100).toFixed(0)
187
424
  : '0';
188
- lines.push('', `⚠ **${formatBytes(devOnlyRetained)} (${pct}%) of this detached DOM is retained ONLY via dev/extension globals** (${[...new Set(devRoots.byId.values())].join(', ')}) — it would be garbage-collected in production. Exclude it from leak totals; run \`memlab_dev_artifacts\` for the breakdown.`);
425
+ lines.push('', `⚠ **${formatBytes(devOnlyRetained)} (${pct}%) of this detached DOM is retained ONLY via dev/automation artifacts** (${summarizeDevRoots(devRoots)}) — dev-global retention would be GC'd in production, and a11y/CDP-cache retention is automation-inflated (not present at that scale in a normal session). Exclude it from leak totals; run \`memlab_dev_artifacts\` for the breakdown.`);
189
426
  }
190
427
  if (sorted.length > 0) {
191
- lines.push('', `**Suggested action:** Use \`memlab_retainer_summary\` with node_ids from the top group's example to trace the common retention pattern.`);
428
+ // In dominator mode point at the largest row that HAS an owner
429
+ // the ownerless bucket can top the table, and "run dominator_chain
430
+ // on it" is meaningless there (it is already at the root).
431
+ const topOwned = isDominatorMode
432
+ ? sorted.find(([, s]) => s.ownerIds.size > 0)
433
+ : undefined;
434
+ lines.push('', isDominatorMode
435
+ ? topOwned
436
+ ? `**Suggested action:** Run \`memlab_dominator_chain\` on the largest owned group's owner to find the accountable application object, then \`memlab_retainer_summary\` on its example (\`@${topOwned[1].exampleId}\`) for the reference that holds it.`
437
+ : '**Suggested action:** No group has a single owner — every detached node here is reachable via multiple independent paths. Use `memlab_retainer_summary` on an example to enumerate the paths; each one must be cut.'
438
+ : `**Suggested action:** Use \`memlab_retainer_summary\` with node_ids from the top group's example to trace the common retention pattern. Before acting on a group, confirm its **Owners** is 1 — or re-run with \`group_by: "dominator"\`, which groups by what a fix actually frees.`);
192
439
  }
193
440
  return toolResult(lines.join('\n'));
194
441
  }
442
+ const split = emptySplit();
443
+ snapshot.nodes.forEach(node => {
444
+ if (!isDetachedDOMNode(node))
445
+ return;
446
+ if (isPinned(node)) {
447
+ split.pinnedCount++;
448
+ split.pinnedRetained += node.retainedSize;
449
+ split.pinnedIds.push(node.id);
450
+ }
451
+ else {
452
+ split.noPathCount++;
453
+ split.noPathRetained += node.retainedSize;
454
+ }
455
+ });
456
+ const predicate = only_with_retainer_path
457
+ ? (n) => isDetachedDOMNode(n) && isPinned(n)
458
+ : isDetachedDOMNode;
195
459
  const effectiveLimit = output_mode === 'ids' ? Math.min(limit, 10000) : Math.min(limit, 500);
196
- const result = queryNodes(snapshot, isDetachedDOMNode, {
460
+ const result = queryNodes(snapshot, predicate, {
197
461
  limit: effectiveLimit,
198
462
  offset,
199
463
  outputMode: output_mode,
200
464
  });
201
- const output = formatQueryNodesResult(result, offset);
465
+ const splitBlock = output_mode === 'ids'
466
+ ? ''
467
+ : formatReachabilitySplit(split, snapshot).join('\n') + '\n\n';
468
+ const output = splitBlock + formatQueryNodesResult(result, offset);
202
469
  if (result.total_count > 0 && output_mode === 'full') {
203
470
  const devNote = devRoots && devRoots.byId.size > 0
204
- ? ` Dev/extension globals (${[...new Set(devRoots.byId.values())].join(', ')}) are present — run \`memlab_dev_artifacts\` to exclude DevTools-only retention from leak totals.`
471
+ ? ` Dev/extension globals (${summarizeDevRoots(devRoots)}) are present — run \`memlab_dev_artifacts\` to exclude DevTools-only retention from leak totals.`
472
+ : '';
473
+ const pinnedNote = split.noPathCount > 0
474
+ ? ` ${formatNumber(split.noPathCount)} detached node(s) have no retainer path (likely GC-eligible / weak-only) — pass only_with_retainer_path to focus on the ${formatNumber(split.pinnedCount)} pinned one(s).`
205
475
  : '';
206
476
  return toolResult(output +
207
477
  '\n\n---\n\n' +
208
478
  '**Suggested action:** Check for missing `removeEventListener` calls, ' +
209
479
  'React component cleanup in `useEffect` return, or refs not cleared on unmount. ' +
210
480
  'Use `memlab_retainer_trace` on top entries to find the retention path. ' +
211
- 'Use `group_by: "retainer"` to see which components are retaining the most detached DOM.' +
481
+ 'Use `group_by: "dominator"` to see which objects are accountable for the most detached DOM (releasing one frees its whole group), or `group_by: "retainer"` for the shortest-path view.' +
482
+ pinnedNote +
212
483
  devNote);
213
484
  }
214
485
  return toolResult(output);
@@ -1 +1 @@
1
- {"version":3,"file":"detached-dom.js","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"detached-dom.js","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,22 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
11
  import type { IHeapNode, IHeapSnapshot } from '@memlab/core';
12
12
  export interface DevRoots {
13
13
  byId: Map<number, string>;
14
+ categoryById: Map<number, DevRootCategory>;
14
15
  }
16
+ export type DevRootCategory = 'console' | 'a11y' | 'devGlobal' | 'reactDebugStack' | 'reactFastRefresh' | 'harness';
17
+ /**
18
+ * One-line summary of the dev/automation roots present, as counts per family.
19
+ *
20
+ * The full list was printed on every call and is unbounded: each Blink a11y
21
+ * object and each bridge export is its own root, so a measured WhatsApp Web run
22
+ * spent ~1,500 tokens per call on a single comma-separated line of names, and an
23
+ * Ads Manager run repeated an entire multi-sentence React warning inside it.
24
+ * Nothing downstream keyed on the individual names — the reader needs to know
25
+ * WHICH FAMILIES are present, which is what the categories already encode.
26
+ * `show_roots: true` restores the full list for the rare case of chasing one
27
+ * specific root.
28
+ */
29
+ export declare function summarizeDevRoots(devRoots: DevRoots, showAll?: boolean): string;
15
30
  /**
16
31
  * Find the dev/extension "root" objects: the targets of dev-global edges on
17
32
  * the Window/global object, plus any node whose own name marks it as a
@@ -19,13 +34,54 @@ export interface DevRoots {
19
34
  */
20
35
  export declare function collectDevRoots(snapshot: IHeapSnapshot): DevRoots;
21
36
  /**
22
- * Classify whether a node is retained ONLY via a dev/extension global. We walk
23
- * the dominator chain upward: if a dev root *dominates* the node, then every
24
- * path from a GC root to the node passes through that dev object, so it would
25
- * be collected in production. Using the dominator (not the shortest retainer)
26
- * makes the "only via" claim rigorous.
37
+ * Reachability from GC roots with every dev/automation root treated as a sink
38
+ * (its outgoing edges are not followed). Returns a bitmap indexed by
39
+ * `node.nodeIndex`: 1 = still reachable from a real GC root without passing
40
+ * through a dev root (production-reachable), 0 = reachable ONLY through one or
41
+ * more dev roots (a dev/automation-only artifact).
42
+ *
43
+ * This is stricter and more complete than a dominator walk: when an object is
44
+ * co-retained by SEVERAL different dev roots (e.g. the DevTools console AND the
45
+ * a11y cache both point at the same detached-DOM subtree), no single dev root
46
+ * dominates it, so a dominator walk misses it — but it is still dev-only because
47
+ * every path to it passes through some dev root. This pass catches that case.
48
+ */
49
+ export declare function computeReachableWithoutDevRoots(snapshot: IHeapSnapshot, devRoots: DevRoots): Uint8Array;
50
+ export interface DevOnlyTotals {
51
+ nodes: number;
52
+ retained: number;
53
+ byCategory: Map<DevRootCategory, {
54
+ nodes: number;
55
+ selfBytes: number;
56
+ }>;
57
+ }
58
+ /**
59
+ * Whole-heap total of everything retained ONLY via dev/automation roots, plus a
60
+ * per-source breakdown.
61
+ *
62
+ * This is deliberately independent of any display threshold. The previous
63
+ * implementation accumulated the total inside the same loop that filtered
64
+ * candidates by `min_retained_size`, so the headline number only counted
65
+ * objects above the cutoff. With the 512 KB default that made a heap holding
66
+ * thousands of small console-retained objects report **0 B dev-only** — read by
67
+ * a caller as "this is production-real". Whole classes of artifact (per-event
68
+ * log strings, one logged object per interaction) are individually tiny and
69
+ * collectively large, which is exactly the case that matters.
70
+ *
71
+ * Attribution is a single BFS over the dev-only subgraph, seeded from each dev
72
+ * root's dev-only successors and OR-ing a category bit as it goes, so a subtree
73
+ * co-retained by several artifact families is counted under each.
74
+ */
75
+ export declare function summarizeDevOnly(snapshot: IHeapSnapshot, devRoots: DevRoots, reached: Uint8Array): DevOnlyTotals;
76
+ /**
77
+ * Classify whether a node is retained ONLY via dev/automation roots. Prefer the
78
+ * reachability bitmap from `computeReachableWithoutDevRoots` (rigorous and
79
+ * complete, including multi-dev-root co-retention). Without a bitmap, fall back
80
+ * to a dominator walk: if a dev root *dominates* the node, every path to it
81
+ * passes through that dev object — conservative, catches only single-dev-root
82
+ * retention.
27
83
  */
28
- export declare function classifyDevOnly(node: IHeapNode, devRoots: DevRoots, maxWalk?: number): {
84
+ export declare function classifyDevOnly(node: IHeapNode, devRoots: DevRoots, reached?: Uint8Array, maxWalk?: number): {
29
85
  devOnly: boolean;
30
86
  via: string | null;
31
87
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dev-artifacts.d.ts","sourceRoot":"","sources":["../../src/tools/dev-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAC,SAAS,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AA4B3D,MAAM,WAAW,QAAQ;IAEvB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,QAAQ,CAqBjE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,SAAO,GACb;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAYxC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwG5D"}
1
+ {"version":3,"file":"dev-artifacts.d.ts","sourceRoot":"","sources":["../../src/tools/dev-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAY,SAAS,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAwJtE,MAAM,WAAW,QAAQ;IAEvB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG1B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,MAAM,GACN,WAAW,GACX,iBAAiB,GACjB,kBAAkB,GAClB,SAAS,CAAC;AAWd;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,MAAM,CAoB7E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,QAAQ,CAoGjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,QAAQ,GACjB,UAAU,CA0BZ;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,GAAG,CAAC,eAAe,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CACtE;AAWD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,UAAU,GAClB,aAAa,CAgEf;AAyBD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,UAAU,EACpB,OAAO,SAAO,GACb;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAmBxC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkN5D"}