@mastra/evals 1.6.0 → 1.7.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/CHANGELOG.md +58 -0
- package/dist/checks-64AonnEK.js +379 -0
- package/dist/checks-64AonnEK.js.map +1 -0
- package/dist/checks-DGTgg-nW.cjs +479 -0
- package/dist/checks-DGTgg-nW.cjs.map +1 -0
- package/dist/checks.cjs +14 -56
- package/dist/checks.js +2 -3
- package/dist/docs/SKILL.md +2 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-evals-built-in-scorers.md +4 -4
- package/dist/docs/references/docs-evals-overview.md +6 -4
- package/dist/docs/references/docs-evals-quick-checks.md +2 -2
- package/dist/docs/references/reference-evals-answer-relevancy.md +5 -5
- package/dist/docs/references/reference-evals-answer-similarity.md +1 -1
- package/dist/docs/references/reference-evals-bias.md +4 -4
- package/dist/docs/references/reference-evals-checks.md +3 -3
- package/dist/docs/references/reference-evals-completeness.md +5 -5
- package/dist/docs/references/reference-evals-content-similarity.md +5 -5
- package/dist/docs/references/reference-evals-context-precision.md +5 -5
- package/dist/docs/references/reference-evals-context-recall.md +11 -11
- package/dist/docs/references/reference-evals-context-relevance.md +15 -15
- package/dist/docs/references/reference-evals-faithfulness.md +4 -4
- package/dist/docs/references/reference-evals-hallucination.md +11 -11
- package/dist/docs/references/reference-evals-keyword-coverage.md +6 -6
- package/dist/docs/references/reference-evals-noise-sensitivity.md +15 -15
- package/dist/docs/references/reference-evals-prompt-alignment.md +20 -20
- package/dist/docs/references/reference-evals-rubric.md +2 -2
- package/dist/docs/references/reference-evals-scorer-utils.md +4 -4
- package/dist/docs/references/reference-evals-summarization.md +203 -0
- package/dist/docs/references/reference-evals-textual-difference.md +4 -4
- package/dist/docs/references/reference-evals-tool-call-accuracy.md +4 -4
- package/dist/docs/references/reference-evals-toxicity.md +5 -5
- package/dist/docs/references/reference-evals-trajectory-accuracy.md +10 -10
- package/dist/index.cjs +12 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/scorers/llm/index.d.ts +1 -0
- package/dist/scorers/llm/index.d.ts.map +1 -1
- package/dist/scorers/llm/summarization/index.d.ts +55 -0
- package/dist/scorers/llm/summarization/index.d.ts.map +1 -0
- package/dist/scorers/llm/summarization/prompts.d.ts +48 -0
- package/dist/scorers/llm/summarization/prompts.d.ts.map +1 -0
- package/dist/scorers/prebuilt/index.cjs +2753 -2848
- package/dist/scorers/prebuilt/index.cjs.map +1 -1
- package/dist/scorers/prebuilt/index.js +2735 -2791
- package/dist/scorers/prebuilt/index.js.map +1 -1
- package/dist/scorers/utils.cjs +966 -101
- package/dist/scorers/utils.cjs.map +1 -1
- package/dist/scorers/utils.js +939 -2
- package/dist/scorers/utils.js.map +1 -1
- package/package.json +11 -10
- package/dist/checks.cjs.map +0 -1
- package/dist/checks.js.map +0 -1
- package/dist/chunk-GGHVFNVI.cjs +0 -233
- package/dist/chunk-GGHVFNVI.cjs.map +0 -1
- package/dist/chunk-IZLA36WC.cjs +0 -654
- package/dist/chunk-IZLA36WC.cjs.map +0 -1
- package/dist/chunk-UJ4WCQ3F.js +0 -626
- package/dist/chunk-UJ4WCQ3F.js.map +0 -1
- package/dist/chunk-WEADJCUA.js +0 -216
- package/dist/chunk-WEADJCUA.js.map +0 -1
|
@@ -15,7 +15,7 @@ The `runEvals` pipeline uses two extraction strategies, depending on whether obs
|
|
|
15
15
|
|
|
16
16
|
### Trace-based extraction (preferred)
|
|
17
17
|
|
|
18
|
-
When the target's `Mastra` instance has storage configured, the pipeline fetches the full execution trace from the observability store and calls `extractTrajectoryFromTrace()`. This produces a hierarchical trajectory with nested `children
|
|
18
|
+
When the target's `Mastra` instance has storage configured, the pipeline fetches the full execution trace from the observability store and calls `extractTrajectoryFromTrace()`. This produces a hierarchical trajectory with nested `children` that captures the complete execution tree. The tree includes nested agent runs and tool calls within workflow steps. It also includes model generations.
|
|
19
19
|
|
|
20
20
|
For example, a workflow that calls an agent, which in turn calls tools, produces:
|
|
21
21
|
|
|
@@ -35,8 +35,8 @@ workflow_run
|
|
|
35
35
|
|
|
36
36
|
When storage isn't available, the pipeline falls back to:
|
|
37
37
|
|
|
38
|
-
- **Agents:** `extractTrajectory()
|
|
39
|
-
- **Workflows:** `extractWorkflowTrajectory()
|
|
38
|
+
- **Agents:** `extractTrajectory()`, Extracts `ToolCallStep` entries from `toolInvocations` in the agent's message output. Produces a flat list of tool calls.
|
|
39
|
+
- **Workflows:** `extractWorkflowTrajectory()`, Extracts `WorkflowStepStep` entries from `stepResults`. Produces a flat list of workflow steps.
|
|
40
40
|
|
|
41
41
|
These fallbacks don't capture nested execution or non-tool-call spans.
|
|
42
42
|
|
|
@@ -105,7 +105,7 @@ All step types share the base properties `name`, `durationMs`, `metadata`, and `
|
|
|
105
105
|
|
|
106
106
|
## Expected steps
|
|
107
107
|
|
|
108
|
-
When defining expected trajectories, use `ExpectedStep` instead of the full `TrajectoryStep` discriminated union. `ExpectedStep` is a discriminated union that mirrors `TrajectoryStep
|
|
108
|
+
When defining expected trajectories, use `ExpectedStep` instead of the full `TrajectoryStep` discriminated union. `ExpectedStep` is a discriminated union that mirrors `TrajectoryStep`: when you specify a `stepType`, you get autocomplete for that variant's fields (e.g., `toolArgs` for `tool_call`, `modelId` for `model_generation`). All variant-specific fields are optional, so you only assert against what you care about.
|
|
109
109
|
|
|
110
110
|
Omit `stepType` entirely to match any step by name only.
|
|
111
111
|
|
|
@@ -199,8 +199,8 @@ This function returns an instance of the MastraScorer class. See the [MastraScor
|
|
|
199
199
|
|
|
200
200
|
The code-based scorer resolves `expectedTrajectory` from two sources, in order of priority:
|
|
201
201
|
|
|
202
|
-
1. **Constructor option
|
|
203
|
-
2. **Dataset item
|
|
202
|
+
1. **Constructor option**: A static trajectory passed when creating the scorer. Used for all dataset items.
|
|
203
|
+
2. **Dataset item**: An `expectedTrajectory` field on the dataset item, passed through the `runEvals` pipeline. Allows different expected trajectories per item.
|
|
204
204
|
|
|
205
205
|
```typescript
|
|
206
206
|
// Static: same expected trajectory for all items
|
|
@@ -474,10 +474,10 @@ The `createTrajectoryScorerCode()` function from `@mastra/evals/scorers/prebuilt
|
|
|
474
474
|
|
|
475
475
|
The unified scorer evaluates four dimensions:
|
|
476
476
|
|
|
477
|
-
1. **Accuracy
|
|
478
|
-
2. **Efficiency
|
|
479
|
-
3. **Blacklist
|
|
480
|
-
4. **Tool failures
|
|
477
|
+
1. **Accuracy**: Matches actual steps against expected steps (if `steps` is configured). Uses the `ordering` mode.
|
|
478
|
+
2. **Efficiency**: Checks step budgets (`maxSteps`, `maxTotalTokens`, `maxTotalDurationMs`) and redundant calls (`noRedundantCalls`).
|
|
479
|
+
3. **Blacklist**: Checks for forbidden tools or sequences. Any violation immediately results in a score of **0.0** regardless of other dimensions.
|
|
480
|
+
4. **Tool failures**: Detects retry and fallback patterns. It also detects argument correction patterns.
|
|
481
481
|
|
|
482
482
|
The final score is a weighted combination of active dimensions, normalized by which dimensions are active. Default weights are accuracy 0.4, efficiency 0.3, tool failures 0.2, blacklist 0.1, but you can customize them via the `weights` option. Blacklist violations override everything to 0. When nested evaluations are present, the score is 70% top-level and 30% nested average.
|
|
483
483
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* @mastra/evals - Evaluation framework for AI agents
|
|
4
|
+
*
|
|
5
|
+
* This package uses subpath exports. Import from specific paths:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
10
|
+
* import { getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
11
|
+
* */
|
|
12
|
+
//#endregion
|
|
2
13
|
|
|
3
|
-
//# sourceMappingURL=index.cjs.map
|
|
4
14
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @mastra/evals - Evaluation framework for AI agents\n *\n * This package uses subpath exports. Import from specific paths:\n *\n * @example\n * ```ts\n * import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';\n * import { getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';\n * */\n\n// This package uses subpath exports - see package.json for available paths\n"],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* @mastra/evals - Evaluation framework for AI agents
|
|
4
|
+
*
|
|
5
|
+
* This package uses subpath exports. Import from specific paths:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
10
|
+
* import { getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
11
|
+
* */
|
|
12
|
+
//#endregion
|
|
13
|
+
export {};
|
|
1
14
|
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
3
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @mastra/evals - Evaluation framework for AI agents\n *\n * This package uses subpath exports. Import from specific paths:\n *\n * @example\n * ```ts\n * import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';\n * import { getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';\n * */\n\n// This package uses subpath exports - see package.json for available paths\n"],"mappings":""}
|
|
@@ -11,5 +11,6 @@ export * from './context-recall/index.js';
|
|
|
11
11
|
export * from './noise-sensitivity/index.js';
|
|
12
12
|
export * from './prompt-alignment/index.js';
|
|
13
13
|
export * from './rubric/index.js';
|
|
14
|
+
export * from './summarization/index.js';
|
|
14
15
|
export * from './trajectory/index.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scorers/llm/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scorers/llm/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ScorerRunInputForAgent, ScorerRunOutputForAgent } from '@mastra/core/evals';
|
|
2
|
+
import type { MastraModelConfig } from '@mastra/core/llm';
|
|
3
|
+
import type { ScorerRunInputForLLMJudge, ScorerRunOutputForLLMJudge } from '../../utils.js';
|
|
4
|
+
export interface SummarizationMetricOptions {
|
|
5
|
+
scale?: number;
|
|
6
|
+
/** Text the summary is judged against. Defaults to the user message of the run input. */
|
|
7
|
+
source?: string;
|
|
8
|
+
sourceExtractor?: (input: ScorerRunInputForAgent, output: ScorerRunOutputForAgent) => string;
|
|
9
|
+
/** Upper bound on the coverage questions drawn from the source. Defaults to 10. */
|
|
10
|
+
maxQuestions?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a scorer that evaluates a summary against the text it condenses.
|
|
14
|
+
*
|
|
15
|
+
* The scorer judges two axes and returns the lower one, so a summary cannot pass
|
|
16
|
+
* by being faithful but empty, or thorough but wrong:
|
|
17
|
+
* - Alignment: supported claims / total claims
|
|
18
|
+
* - Coverage: answered questions / total questions
|
|
19
|
+
*
|
|
20
|
+
* Coverage is judged in a separate call that never receives the source text, so
|
|
21
|
+
* the judge cannot answer a question from information the summary left out.
|
|
22
|
+
*
|
|
23
|
+
* @param model - Language model used as the judge
|
|
24
|
+
* @param options - Source resolution, question cap, and score scaling
|
|
25
|
+
* @returns A scorer producing `min(alignment, coverage) × scale`
|
|
26
|
+
* @throws When `maxQuestions` is below 1
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const scorer = createSummarizationScorer({
|
|
31
|
+
* model: 'openai/gpt-5.5',
|
|
32
|
+
* options: { maxQuestions: 10 },
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const result = await scorer.run(run);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSummarizationScorer({ model, options, }: {
|
|
39
|
+
model: MastraModelConfig;
|
|
40
|
+
options?: SummarizationMetricOptions;
|
|
41
|
+
}): import("@mastra/core/evals").MastraScorer<string, ScorerRunInputForLLMJudge, ScorerRunOutputForLLMJudge, Record<"preprocessStepResult", {
|
|
42
|
+
alignment: {
|
|
43
|
+
claim: string;
|
|
44
|
+
supported: boolean;
|
|
45
|
+
reason: string;
|
|
46
|
+
}[];
|
|
47
|
+
questions: string[];
|
|
48
|
+
}> & Record<"analyzeStepResult", {
|
|
49
|
+
coverage: {
|
|
50
|
+
question: string;
|
|
51
|
+
answered: boolean;
|
|
52
|
+
reason: string;
|
|
53
|
+
}[];
|
|
54
|
+
}> & Record<"generateScoreStepResult", number> & Record<"generateReasonStepResult", string>>;
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/scorers/llm/summarization/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAU1D,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAQzF,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,uBAAuB,KAAK,MAAM,CAAC;IAC7F,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,OAAY,GACb,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC;;;;;;;;;;;;;6FA4EA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const SUMMARIZATION_AGENT_INSTRUCTIONS = "You are a strict summarization evaluator. Your job is to determine whether a summary is factually faithful to its source text and whether it preserves the information the source states.\n\nKey Principles:\n1. Judge only against the text you are given, never against prior knowledge\n2. A claim is supported only when the source states or directly implies it\n3. Treat approximations as deviations when the source is precise: \"about 2020\" does not match \"2020\"\n4. Allow semantically equivalent phrasing: \"founded in Boston\" matches \"based in Boston\"\n5. Judge each claim and each question independently\n6. Factual accuracy and information coverage are separate concerns and are judged separately";
|
|
2
|
+
/**
|
|
3
|
+
* Builds the preprocess prompt, which covers everything that needs the source text.
|
|
4
|
+
*
|
|
5
|
+
* Claims are extracted from the summary and judged against the source in one pass,
|
|
6
|
+
* so every verdict carries the claim it belongs to. Questions are drawn from the
|
|
7
|
+
* source for the coverage step that follows.
|
|
8
|
+
*
|
|
9
|
+
* @param maxQuestions - Upper bound on the generated questions
|
|
10
|
+
* @returns A prompt asking for `{ alignment, questions }`
|
|
11
|
+
*/
|
|
12
|
+
export declare function createSourceJudgementPrompt({ sourceText, summary, maxQuestions, }: {
|
|
13
|
+
sourceText: string;
|
|
14
|
+
summary: string;
|
|
15
|
+
maxQuestions: number;
|
|
16
|
+
}): string;
|
|
17
|
+
/**
|
|
18
|
+
* Builds the analyze prompt, which answers the coverage questions.
|
|
19
|
+
*
|
|
20
|
+
* The source text is deliberately absent. A judge that could see it would answer
|
|
21
|
+
* from the source instead of the summary, which would hide exactly the omissions
|
|
22
|
+
* this axis exists to measure.
|
|
23
|
+
*
|
|
24
|
+
* @returns A prompt asking for `{ coverage }`
|
|
25
|
+
*/
|
|
26
|
+
export declare function createCoveragePrompt({ summary, questions }: {
|
|
27
|
+
summary: string;
|
|
28
|
+
questions: string[];
|
|
29
|
+
}): string;
|
|
30
|
+
/**
|
|
31
|
+
* Builds the prompt that explains a finished score.
|
|
32
|
+
*
|
|
33
|
+
* Both axis scores and the failing claims and questions are passed in so the
|
|
34
|
+
* explanation names the axis that decided the result instead of recalculating it.
|
|
35
|
+
*
|
|
36
|
+
* @returns A prompt asking for a one-sentence explanation of the score
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSummarizationReasonPrompt({ sourceText, summary, score, scale, alignmentScore, coverageScore, unsupportedClaims, missingQuestions, }: {
|
|
39
|
+
sourceText: string;
|
|
40
|
+
summary: string;
|
|
41
|
+
score: number;
|
|
42
|
+
scale: number;
|
|
43
|
+
alignmentScore: number;
|
|
44
|
+
coverageScore: number;
|
|
45
|
+
unsupportedClaims: string[];
|
|
46
|
+
missingQuestions: string[];
|
|
47
|
+
}): string;
|
|
48
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../src/scorers/llm/summarization/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,qsBAQgD,CAAC;AAE9F;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,UAAU,EACV,OAAO,EACP,YAAY,GACb,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,UAqEA;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,UAuDpG;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,EAC9C,UAAU,EACV,OAAO,EACP,KAAK,EACL,KAAK,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,UAmCA"}
|