@memlab/mcp-server 2.18.1 → 2.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -16
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +109 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +194 -3
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +102 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +99 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +404 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +30 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +106 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +196 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +240 -14
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +5 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +368 -22
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +685 -24
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +49 -40
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +79 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2523 -197
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +221 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +203 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +566 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +17 -0
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +280 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +116 -50
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +6 -2
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +35 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +398 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +29 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +294 -23
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +53 -5
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +18 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +210 -51
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +14 -2
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +53 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +313 -89
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +7 -5
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +492 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +219 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +238 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +507 -15
- package/dist/utils.js.map +1 -1
- package/package.json +7 -6
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { getSnapshot } from '../heap-state.js';
|
|
12
|
-
import {
|
|
12
|
+
import { withAnonymizedBanner } from '../anonymized-snapshot.js';
|
|
13
|
+
import { formatBytes, errorResult, toolResult, looksLikeFailurePayload, suggestionsSuppressed, } from '../utils.js';
|
|
14
|
+
import { classifyNonProductionString } from '../artifact-classes.js';
|
|
15
|
+
import { buildStringIndex, stringIndexIsCached } from '../string-index.js';
|
|
13
16
|
export function registerDuplicatedStrings(server) {
|
|
14
17
|
server.tool('memlab_duplicated_strings', 'Find duplicated string instances in the heap. Shows strings that appear multiple times, ranked by total retained size — a common source of memory waste. Use after memlab_class_histogram shows high string counts. ' +
|
|
15
18
|
'⚠ Full-heap scan — slow and memory-heavy on very large heaps (millions of nodes); raise min_count to bound the work.', {
|
|
@@ -31,50 +34,29 @@ export function registerDuplicatedStrings(server) {
|
|
|
31
34
|
}, async ({ limit, min_count, include_node_ids }) => {
|
|
32
35
|
try {
|
|
33
36
|
const snapshot = getSnapshot();
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (node.name === 'system / SlicedString')
|
|
41
|
-
return;
|
|
42
|
-
const strNode = node.toStringNode();
|
|
43
|
-
if (!strNode)
|
|
44
|
-
return;
|
|
45
|
-
const value = strNode.stringValue;
|
|
46
|
-
const entry = stringMap.get(value);
|
|
47
|
-
if (entry) {
|
|
48
|
-
entry.count++;
|
|
49
|
-
entry.total_size += node.retainedSize;
|
|
50
|
-
if (entry.example_node_ids.length < 3) {
|
|
51
|
-
entry.example_node_ids.push(node.id);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
stringMap.set(value, {
|
|
56
|
-
count: 1,
|
|
57
|
-
total_size: node.retainedSize,
|
|
58
|
-
example_node_ids: [node.id],
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
});
|
|
37
|
+
// Shared with memlab_intern_opportunities, which needs the same
|
|
38
|
+
// value -> {count, size, ids} map. Cached per snapshot, so running the
|
|
39
|
+
// two back to back (the common case) walks every string node once
|
|
40
|
+
// instead of twice.
|
|
41
|
+
const reused = stringIndexIsCached();
|
|
42
|
+
const { byValue: stringMap } = buildStringIndex(snapshot);
|
|
62
43
|
const duplicated = Array.from(stringMap.entries())
|
|
63
44
|
.filter(([, stats]) => stats.count >= min_count)
|
|
64
|
-
.sort((a, b) => b[1].
|
|
45
|
+
.sort((a, b) => b[1].totalSize - a[1].totalSize)
|
|
65
46
|
.slice(0, limit)
|
|
66
47
|
.map(([value, stats]) => {
|
|
67
|
-
const per_copy_size = stats.count > 0 ? stats.
|
|
48
|
+
const per_copy_size = stats.count > 0 ? stats.totalSize / stats.count : 0;
|
|
68
49
|
const potential_savings = (stats.count - 1) * per_copy_size;
|
|
69
50
|
return {
|
|
70
51
|
value: value.length > 200 ? value.substring(0, 200) + '...' : value,
|
|
71
52
|
count: stats.count,
|
|
72
|
-
total_size: stats.
|
|
73
|
-
total_size_formatted: formatBytes(stats.
|
|
53
|
+
total_size: stats.totalSize,
|
|
54
|
+
total_size_formatted: formatBytes(stats.totalSize),
|
|
74
55
|
potential_savings,
|
|
75
|
-
example_node_ids: stats.
|
|
56
|
+
example_node_ids: stats.exampleIds.slice(0, 3),
|
|
76
57
|
field_context: null,
|
|
77
58
|
actionability: null,
|
|
59
|
+
harness_what: null,
|
|
78
60
|
};
|
|
79
61
|
});
|
|
80
62
|
if (duplicated.length === 0) {
|
|
@@ -131,7 +113,19 @@ export function registerDuplicatedStrings(server) {
|
|
|
131
113
|
}
|
|
132
114
|
}
|
|
133
115
|
}
|
|
134
|
-
|
|
116
|
+
// Non-production content outranks the app/framework split: whether it
|
|
117
|
+
// was injected by the measurement harness or exists only in a DEV
|
|
118
|
+
// build, it is not memory the shipped app has, so it must never be
|
|
119
|
+
// counted toward an interning win (see classifyNonProductionString).
|
|
120
|
+
const nonProd = classifyNonProductionString(d.value);
|
|
121
|
+
if (nonProd != null) {
|
|
122
|
+
d.actionability = 'harness';
|
|
123
|
+
d.harness_what =
|
|
124
|
+
nonProd.kind === 'dev-build'
|
|
125
|
+
? `${nonProd.what} — DEV build only, absent in production`
|
|
126
|
+
: nonProd.what;
|
|
127
|
+
}
|
|
128
|
+
else if (appCount > 0 && frameworkCount > 0) {
|
|
135
129
|
d.actionability = 'mixed';
|
|
136
130
|
}
|
|
137
131
|
else if (frameworkCount > 0) {
|
|
@@ -142,6 +136,8 @@ export function registerDuplicatedStrings(server) {
|
|
|
142
136
|
}
|
|
143
137
|
}
|
|
144
138
|
const appActionableCount = duplicated.filter(d => d.actionability === 'app' || d.actionability === 'mixed').length;
|
|
139
|
+
const harnessEntries = duplicated.filter(d => d.actionability === 'harness');
|
|
140
|
+
const harnessBytes = harnessEntries.reduce((sum, d) => sum + d.potential_savings, 0);
|
|
145
141
|
const lines = duplicated.map((d, i) => {
|
|
146
142
|
const val = d.value.length > 80 ? d.value.slice(0, 80) + '...' : d.value;
|
|
147
143
|
const nodeIdsPart = include_node_ids
|
|
@@ -150,7 +146,11 @@ export function registerDuplicatedStrings(server) {
|
|
|
150
146
|
const context = d.field_context
|
|
151
147
|
? `\n commonly held as: ${d.field_context}`
|
|
152
148
|
: '';
|
|
153
|
-
const actionLabel = d.actionability
|
|
149
|
+
const actionLabel = d.actionability === 'harness'
|
|
150
|
+
? ` [harness — ${d.harness_what ?? 'measurement harness'}; not app memory]`
|
|
151
|
+
: d.actionability
|
|
152
|
+
? ` [${d.actionability}]`
|
|
153
|
+
: '';
|
|
154
154
|
const savingsLabel = d.potential_savings > 0
|
|
155
155
|
? `, savings: ${formatBytes(d.potential_savings)}`
|
|
156
156
|
: '';
|
|
@@ -176,14 +176,23 @@ export function registerDuplicatedStrings(server) {
|
|
|
176
176
|
'Consider string interning with a `Map<string, string>` pool applied at ingestion time, ' +
|
|
177
177
|
'or deduplicating at the data source.');
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
// Harness content is excluded from the headline: the number a caller
|
|
180
|
+
// acts on must be reclaimable from the application.
|
|
181
|
+
const totalSavings = duplicated.reduce((sum, d) => d.actionability === 'harness' ? sum : sum + d.potential_savings, 0);
|
|
180
182
|
const summaryLine = appActionableCount > 0
|
|
181
183
|
? `${appActionableCount} of ${duplicated.length} entries are app-actionable`
|
|
182
184
|
: `${duplicated.length} entries (all framework-held)`;
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
+
const harnessNote = harnessEntries.length > 0
|
|
186
|
+
? `\n\n⚠️ **${harnessEntries.length} entr${harnessEntries.length === 1 ? 'y' : 'ies'} (${formatBytes(harnessBytes)}) excluded from the total as measurement-harness content** — the CDP/devtools bridge injected into the page to drive this session, not application memory. Interning it reclaims nothing in production.`
|
|
187
|
+
: '';
|
|
188
|
+
// The two string tools answer different questions and their outputs
|
|
189
|
+
// used to restate each other. Say which is which, once, and note that
|
|
190
|
+
// the expensive scan is shared rather than repeated.
|
|
191
|
+
const relatedNote = `\n\n_This is the raw per-VALUE duplication table. \`memlab_intern_opportunities\` groups the same strings by property x parent shape and estimates what a canonical intern pool would actually reclaim (accounting for co-retention and the length cap) — use it to decide whether to write the fix, and this to see the values. It reuses this snapshot's string scan${reused ? ', which was itself already cached' : ''}, so running both costs one pass over the string nodes, not two._`;
|
|
192
|
+
const body = `Duplicated strings (${summaryLine}):\n\n${lines.join('\n')}\n\n**Total interning savings: ${formatBytes(totalSavings)}** (if each string were stored only once, harness content excluded)${harnessNote}${suggestionsSuppressed() ? '' : relatedNote}`;
|
|
193
|
+
return toolResult(withAnonymizedBanner(snapshot, suggestions.length > 0
|
|
185
194
|
? `${body}\n\n---\n\n${suggestions.join('\n')}`
|
|
186
|
-
: body);
|
|
195
|
+
: body));
|
|
187
196
|
}
|
|
188
197
|
catch (err) {
|
|
189
198
|
return errorResult(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicated-strings.js","sourceRoot":"","sources":["../../src/tools/duplicated-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,uBAAuB,
|
|
1
|
+
{"version":3,"file":"duplicated-strings.js","sourceRoot":"","sources":["../../src/tools/duplicated-strings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerEvalAcross(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=eval-across.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-across.d.ts","sourceRoot":"","sources":["../../src/tools/eval-across.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAuBvE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2I1D"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { getCurrentHandle, getMetadataByHandle, listSnapshots, setCurrentSnapshot, } from '../heap-state.js';
|
|
12
|
+
import { errorResult, toolResult } from '../utils.js';
|
|
13
|
+
import { runEval } from './eval.js';
|
|
14
|
+
function textOf(result) {
|
|
15
|
+
const content = result?.content;
|
|
16
|
+
if (!Array.isArray(content))
|
|
17
|
+
return '(no output)';
|
|
18
|
+
return content
|
|
19
|
+
.map(c => (typeof c?.text === 'string' ? c.text : ''))
|
|
20
|
+
.join('\n')
|
|
21
|
+
.trim();
|
|
22
|
+
}
|
|
23
|
+
export function registerEvalAcross(server) {
|
|
24
|
+
server.tool('memlab_eval_across', 'Run ONE `memlab_eval` program against SEVERAL resident snapshots and return the results side by side. ' +
|
|
25
|
+
'Exists because the interesting questions in a leak hunt are comparative — "how many of these were there at each rung?", ' +
|
|
26
|
+
'"did this collection grow?", "is the new population retained the same way as the old one?" — and answering them with ' +
|
|
27
|
+
'`memlab_eval` alone costs one switch + one paste + one manual diff per rung, which is enough friction that the question ' +
|
|
28
|
+
'often just does not get asked. The code, the sandbox and the helper surface are identical to `memlab_eval` (this calls the ' +
|
|
29
|
+
'same implementation, not a copy), so anything that runs there runs here.\n\n' +
|
|
30
|
+
'Node ids are per-capture, so write code that computes COMPARABLE values (counts, sizes, shapes, string values) rather than ' +
|
|
31
|
+
'code that hardcodes ids from one rung. `helpers.load(name)` still refuses cross-snapshot reads unless you pass ' +
|
|
32
|
+
'`{allowCrossSnapshot: true}`.\n\n' +
|
|
33
|
+
'The active snapshot is restored when the run finishes, including on failure, so this does not disturb an in-progress investigation.', {
|
|
34
|
+
code: z
|
|
35
|
+
.string()
|
|
36
|
+
.describe('JavaScript to run against each snapshot. Same conventions as memlab_eval: assign to `result`, iterate with `snapshot.nodes.forEach`, use `helpers.*`. Run `memlab_eval({mode:"describe_env"})` for the full surface.'),
|
|
37
|
+
handles: z
|
|
38
|
+
.array(z.string())
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Snapshot handles to run against, in the order you want them reported (oldest rung first reads best). Defaults to every resident snapshot in load order.'),
|
|
41
|
+
timeout_ms: z
|
|
42
|
+
.number()
|
|
43
|
+
.optional()
|
|
44
|
+
.default(60000)
|
|
45
|
+
.describe('Execution timeout in milliseconds, applied PER snapshot (default 60000).'),
|
|
46
|
+
max_nodes: z
|
|
47
|
+
.number()
|
|
48
|
+
.int()
|
|
49
|
+
.min(1)
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Per-snapshot node-visit budget for full-heap walks. Defaults to a budget SCALED from each loaded graph (6 full passes, floored at 20,000,000). On overrun that rung reports a partial result instead of failing the whole run.'),
|
|
52
|
+
stop_on_error: z
|
|
53
|
+
.boolean()
|
|
54
|
+
.optional()
|
|
55
|
+
.default(false)
|
|
56
|
+
.describe('Stop at the first snapshot whose code throws (default false: record the error for that rung and continue, so one bad rung does not discard the others).'),
|
|
57
|
+
}, async ({ code, handles, timeout_ms, max_nodes, stop_on_error }) => {
|
|
58
|
+
const originalHandle = getCurrentHandle();
|
|
59
|
+
try {
|
|
60
|
+
const resident = listSnapshots().map(m => m.handle);
|
|
61
|
+
if (resident.length === 0) {
|
|
62
|
+
return errorResult(new Error('No snapshots are loaded. Load them with memlab_load_snapshot({keep_previous: true}) first — this tool compares snapshots that are already resident, it does not open files.'));
|
|
63
|
+
}
|
|
64
|
+
const targets = handles != null && handles.length > 0 ? handles : resident;
|
|
65
|
+
const unknown = targets.filter(h => getMetadataByHandle(h) == null);
|
|
66
|
+
if (unknown.length > 0) {
|
|
67
|
+
return errorResult(new Error(`Unknown snapshot handle(s): ${unknown.join(', ')}. Resident: ${resident.join(', ')}. ` +
|
|
68
|
+
'Handles come from memlab_snapshots or the alias passed to memlab_load_snapshot.'));
|
|
69
|
+
}
|
|
70
|
+
if (targets.length < 2) {
|
|
71
|
+
// Not an error — a single-handle run is a legitimate way to script
|
|
72
|
+
// one rung — but the whole point of the tool is the comparison.
|
|
73
|
+
// Saying so beats silently returning a one-row report.
|
|
74
|
+
// (falls through and runs)
|
|
75
|
+
}
|
|
76
|
+
const sections = [];
|
|
77
|
+
let failures = 0;
|
|
78
|
+
for (const handle of targets) {
|
|
79
|
+
if (!setCurrentSnapshot(handle)) {
|
|
80
|
+
sections.push(`### ${handle}\n\n(could not switch to this snapshot)`);
|
|
81
|
+
failures++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const meta = getMetadataByHandle(handle);
|
|
85
|
+
const header = `### ${handle}${meta ? ` — ${meta.fileName}` : ''}`;
|
|
86
|
+
try {
|
|
87
|
+
const res = await runEval({ code, timeout_ms, max_nodes });
|
|
88
|
+
const body = textOf(res);
|
|
89
|
+
if (/^Error:/m.test(body))
|
|
90
|
+
failures++;
|
|
91
|
+
sections.push(`${header}\n\n${body}`);
|
|
92
|
+
if (stop_on_error && /^Error:/m.test(body)) {
|
|
93
|
+
sections.push('_Stopped here: stop_on_error is set and this rung failed._');
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
failures++;
|
|
99
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
100
|
+
sections.push(`${header}\n\nError: ${msg}`);
|
|
101
|
+
if (stop_on_error) {
|
|
102
|
+
sections.push('_Stopped here: stop_on_error is set and this rung failed._');
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const lines = [
|
|
108
|
+
`## eval across ${targets.length} snapshot(s)`,
|
|
109
|
+
'',
|
|
110
|
+
`Order: ${targets.join(' → ')}${failures > 0 ? ` · ${failures} rung(s) reported an error` : ''}`,
|
|
111
|
+
'',
|
|
112
|
+
...(targets.length < 2
|
|
113
|
+
? [
|
|
114
|
+
'_Only one snapshot targeted — this tool exists for the comparison; load a second rung with `keep_previous: true` to get one._',
|
|
115
|
+
'',
|
|
116
|
+
]
|
|
117
|
+
: []),
|
|
118
|
+
sections.join('\n\n'),
|
|
119
|
+
'',
|
|
120
|
+
'_Values are comparable across rungs; node IDS are not — they are assigned per capture. Compare counts, sizes, shapes and string values, never ids._',
|
|
121
|
+
];
|
|
122
|
+
return toolResult(lines.join('\n'));
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
return errorResult(err);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
// Restore whatever the caller had active, so a comparison run is not a
|
|
129
|
+
// hidden state change for every tool that follows it.
|
|
130
|
+
if (originalHandle != null)
|
|
131
|
+
setCurrentSnapshot(originalHandle);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=eval-across.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-across.js","sourceRoot":"","sources":["../../src/tools/eval-across.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/eval.d.ts
CHANGED
|
@@ -8,5 +8,84 @@
|
|
|
8
8
|
* @oncall memory_lab
|
|
9
9
|
*/
|
|
10
10
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import { toolResult } from '../utils.js';
|
|
12
|
+
/**
|
|
13
|
+
* Wall-clock budget for one eval, scaled from the loaded graph.
|
|
14
|
+
*
|
|
15
|
+
* A fixed 60 s default is right for an indexed lookup and wrong for everything
|
|
16
|
+
* else: a full-heap walk on a 6M-node graph takes two to four minutes, so every
|
|
17
|
+
* large-snapshot eval aborted on its first attempt and had to be re-issued with
|
|
18
|
+
* an explicit `timeout_ms`. That is a guaranteed wasted call per question, and
|
|
19
|
+
* the node count needed to avoid it is already known.
|
|
20
|
+
*
|
|
21
|
+
* The floor stays at 60 s so small heaps behave exactly as before.
|
|
22
|
+
*/
|
|
23
|
+
export declare function scaledEvalTimeoutMs(): number;
|
|
24
|
+
/**
|
|
25
|
+
* Default `max_nodes`, scaled to the loaded graph.
|
|
26
|
+
*
|
|
27
|
+
* A probe that makes several passes over the heap is the normal shape — one
|
|
28
|
+
* pass to census classes, one to match shapes, one to size things — so the
|
|
29
|
+
* budget has to be a MULTIPLE of the node count, not a constant. At the old
|
|
30
|
+
* flat 20,000,000 a routine two-pass probe on an 8.24M-node capture aborted
|
|
31
|
+
* mid-walk and returned a partial value; because the result was assigned after
|
|
32
|
+
* the loops, what came back was `undefined` with a note, which reads as a
|
|
33
|
+
* legitimate empty answer.
|
|
34
|
+
*
|
|
35
|
+
* Six passes is generous on purpose: the wall-clock timeout above is the real
|
|
36
|
+
* guard against a runaway eval, and this budget exists to stop pathological
|
|
37
|
+
* traversals, not ordinary multi-pass analysis.
|
|
38
|
+
*/
|
|
39
|
+
export declare function scaledWalkBudget(): number;
|
|
40
|
+
/**
|
|
41
|
+
* Shorten a heap result STRUCTURALLY rather than mid-string.
|
|
42
|
+
*
|
|
43
|
+
* A census result is an array of rows or a `{key: count}` map, and cutting the
|
|
44
|
+
* JSON at a byte offset yields unparseable output plus a re-run with a
|
|
45
|
+
* hand-written limit — which is what actually happened to a detached-class
|
|
46
|
+
* census whose `blink::HeapVectorBacking<…>` keys blew the cap. Dropping whole
|
|
47
|
+
* entries keeps the value valid JSON and keeps the largest rows, which are the
|
|
48
|
+
* ones the question was about.
|
|
49
|
+
*
|
|
50
|
+
* Blink's C++ template names are elided first: they are frequently most of the
|
|
51
|
+
* payload and none of the information, and `abbreviateBlinkTypeName` is the same
|
|
52
|
+
* elision the table renderers already use.
|
|
53
|
+
*/
|
|
54
|
+
export declare function shrinkResult(value: unknown, maxBytes: number): {
|
|
55
|
+
value: unknown;
|
|
56
|
+
truncated: boolean;
|
|
57
|
+
droppedEntries: number;
|
|
58
|
+
keptEntries: number;
|
|
59
|
+
};
|
|
60
|
+
export declare function unwrapNode<T>(node: T): T;
|
|
11
61
|
export declare function registerEval(server: McpServer): void;
|
|
62
|
+
export declare function runEval({ mode, code, section, timeout_ms, save_as, max_nodes, sample, restrict_to_ids, dry_run, max_result_bytes, ownsScanBudget, }: {
|
|
63
|
+
mode?: 'eval' | 'describe_env' | 'list_saved' | 'lint';
|
|
64
|
+
code?: string;
|
|
65
|
+
section?: string;
|
|
66
|
+
timeout_ms?: number;
|
|
67
|
+
save_as?: string;
|
|
68
|
+
max_nodes?: number;
|
|
69
|
+
/** Visit every Nth node in a full-heap walk. 1/undefined = every node. */
|
|
70
|
+
sample?: number;
|
|
71
|
+
/** Restrict `snapshot.nodes.forEach` to these node ids. */
|
|
72
|
+
restrict_to_ids?: number[];
|
|
73
|
+
dry_run?: boolean;
|
|
74
|
+
max_result_bytes?: number;
|
|
75
|
+
/**
|
|
76
|
+
* True only for a direct `memlab_eval` MCP call, which owns the scan budget
|
|
77
|
+
* the guardrail armed for it and may therefore re-arm it to a scaled value.
|
|
78
|
+
* Left false by every in-process caller — `memlab_eval_across`,
|
|
79
|
+
* `memlab_ladder_probe`, `memlab_batch` — because those run MANY evals inside
|
|
80
|
+
* ONE MCP call and each re-arm would reset the shared wall clock.
|
|
81
|
+
*/
|
|
82
|
+
ownsScanBudget?: boolean;
|
|
83
|
+
}): Promise<ReturnType<typeof toolResult>>;
|
|
84
|
+
/**
|
|
85
|
+
* A result that says "none of them" — 0, `[]`, `{}`, or an empty Map/Set.
|
|
86
|
+
*
|
|
87
|
+
* `undefined`/`null` are deliberately NOT included: those mean "the code
|
|
88
|
+
* assigned nothing", which is a different failure and is already handled.
|
|
89
|
+
*/
|
|
90
|
+
export declare function isEmptyCensusResult(v: unknown): boolean;
|
|
12
91
|
//# sourceMappingURL=eval.d.ts.map
|
package/dist/tools/eval.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/tools/eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/tools/eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAuBvE,OAAO,EAGL,UAAU,EAgBX,MAAM,aAAa,CAAC;AAYrB;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf;IACD,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAkFA;AAwCD,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAMxC;AAiZD,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwIpD;AAqCD,wBAAsB,OAAO,CAAC,EAC5B,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,UAAU,EACV,OAAO,EACP,SAAS,EACT,MAAM,EACN,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,cAAc,GACf,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAywDzC;AA2HD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAQvD"}
|