@cogitator-ai/evals 0.12.0 → 0.13.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 +75 -26
- package/dist/comparison-stats.d.ts +104 -0
- package/dist/comparison-stats.d.ts.map +1 -0
- package/dist/comparison-stats.js +179 -0
- package/dist/comparison-stats.js.map +1 -0
- package/dist/eval-comparison.d.ts +2 -51
- package/dist/eval-comparison.d.ts.map +1 -1
- package/dist/eval-comparison.js +12 -149
- package/dist/eval-comparison.js.map +1 -1
- package/dist/eval-suite.d.ts +33 -0
- package/dist/eval-suite.d.ts.map +1 -1
- package/dist/eval-suite.js +81 -2
- package/dist/eval-suite.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/metrics/types.d.ts +25 -0
- package/dist/metrics/types.d.ts.map +1 -1
- package/dist/metrics/types.js.map +1 -1
- package/dist/reporters/comparison.d.ts +24 -0
- package/dist/reporters/comparison.d.ts.map +1 -0
- package/dist/reporters/comparison.js +290 -0
- package/dist/reporters/comparison.js.map +1 -0
- package/dist/reporters/format.d.ts +21 -0
- package/dist/reporters/format.d.ts.map +1 -1
- package/dist/reporters/format.js +31 -0
- package/dist/reporters/format.js.map +1 -1
- package/dist/reporters/github.d.ts.map +1 -1
- package/dist/reporters/github.js +1 -16
- package/dist/reporters/github.js.map +1 -1
- package/dist/reporters/html-format.d.ts +11 -0
- package/dist/reporters/html-format.d.ts.map +1 -0
- package/dist/reporters/html-format.js +111 -0
- package/dist/reporters/html-format.js.map +1 -0
- package/dist/reporters/html.d.ts +12 -0
- package/dist/reporters/html.d.ts.map +1 -0
- package/dist/reporters/html.js +119 -0
- package/dist/reporters/html.js.map +1 -0
- package/dist/reporters/index.d.ts +20 -6
- package/dist/reporters/index.d.ts.map +1 -1
- package/dist/reporters/index.js +15 -4
- package/dist/reporters/index.js.map +1 -1
- package/dist/reporters/markdown.d.ts +15 -0
- package/dist/reporters/markdown.d.ts.map +1 -0
- package/dist/reporters/markdown.js +67 -0
- package/dist/reporters/markdown.js.map +1 -0
- package/dist/runs/compare.d.ts +103 -0
- package/dist/runs/compare.d.ts.map +1 -0
- package/dist/runs/compare.js +208 -0
- package/dist/runs/compare.js.map +1 -0
- package/dist/runs/index.d.ts +9 -0
- package/dist/runs/index.d.ts.map +1 -0
- package/dist/runs/index.js +5 -0
- package/dist/runs/index.js.map +1 -0
- package/dist/runs/json.d.ts +11 -0
- package/dist/runs/json.d.ts.map +1 -0
- package/dist/runs/json.js +58 -0
- package/dist/runs/json.js.map +1 -0
- package/dist/runs/run.d.ts +44 -0
- package/dist/runs/run.d.ts.map +1 -0
- package/dist/runs/run.js +136 -0
- package/dist/runs/run.js.map +1 -0
- package/dist/runs/schema.d.ts +504 -0
- package/dist/runs/schema.d.ts.map +1 -0
- package/dist/runs/schema.js +171 -0
- package/dist/runs/schema.js.map +1 -0
- package/dist/runs/store.d.ts +57 -0
- package/dist/runs/store.d.ts.map +1 -0
- package/dist/runs/store.js +146 -0
- package/dist/runs/store.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/** Escapes text for HTML content and attribute values */
|
|
2
|
+
export function escapeHtml(value) {
|
|
3
|
+
return value
|
|
4
|
+
.replace(/&/g, '&')
|
|
5
|
+
.replace(/</g, '<')
|
|
6
|
+
.replace(/>/g, '>')
|
|
7
|
+
.replace(/"/g, '"')
|
|
8
|
+
.replace(/'/g, ''');
|
|
9
|
+
}
|
|
10
|
+
/** Text that may be long or span lines: as it is when short, folded in `<details>` otherwise */
|
|
11
|
+
export function foldable(value, max = 120) {
|
|
12
|
+
const line = value.replace(/\s+/g, ' ').trim();
|
|
13
|
+
if (line.length <= max && !value.includes('\n'))
|
|
14
|
+
return escapeHtml(value);
|
|
15
|
+
const summary = [...line]
|
|
16
|
+
.slice(0, max - 3)
|
|
17
|
+
.join('')
|
|
18
|
+
.trimEnd();
|
|
19
|
+
return `<details><summary>${escapeHtml(summary)}...</summary><pre>${escapeHtml(value)}</pre></details>`;
|
|
20
|
+
}
|
|
21
|
+
const STYLE = `
|
|
22
|
+
:root {
|
|
23
|
+
color-scheme: light dark;
|
|
24
|
+
--bg: #ffffff;
|
|
25
|
+
--surface: #f5f6f8;
|
|
26
|
+
--text: #1c1f24;
|
|
27
|
+
--muted: #5b6370;
|
|
28
|
+
--border: #d9dde3;
|
|
29
|
+
--pass: #1a7f37;
|
|
30
|
+
--fail: #cf222e;
|
|
31
|
+
--warn: #9a6700;
|
|
32
|
+
}
|
|
33
|
+
@media (prefers-color-scheme: dark) {
|
|
34
|
+
:root {
|
|
35
|
+
--bg: #0f1115;
|
|
36
|
+
--surface: #181b21;
|
|
37
|
+
--text: #e6e8eb;
|
|
38
|
+
--muted: #9aa3ae;
|
|
39
|
+
--border: #2c313a;
|
|
40
|
+
--pass: #3fb950;
|
|
41
|
+
--fail: #f85149;
|
|
42
|
+
--warn: #d29922;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
* { box-sizing: border-box; }
|
|
46
|
+
body {
|
|
47
|
+
margin: 0;
|
|
48
|
+
padding: 24px 16px 48px;
|
|
49
|
+
background: var(--bg);
|
|
50
|
+
color: var(--text);
|
|
51
|
+
font: 14px/1.5 system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
52
|
+
}
|
|
53
|
+
main { max-width: 1100px; margin: 0 auto; }
|
|
54
|
+
h1 { font-size: 22px; margin: 0 0 4px; }
|
|
55
|
+
h2 { font-size: 16px; margin: 32px 0 8px; }
|
|
56
|
+
.sub { color: var(--muted); margin: 0 0 16px; }
|
|
57
|
+
.tiles { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
58
|
+
.tile { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; min-width: 110px; }
|
|
59
|
+
.tile b { display: block; font-size: 18px; }
|
|
60
|
+
.tile span { color: var(--muted); font-size: 12px; }
|
|
61
|
+
.scroll { overflow-x: auto; }
|
|
62
|
+
table { border-collapse: collapse; width: 100%; }
|
|
63
|
+
th, td { border-bottom: 1px solid var(--border); padding: 6px 8px; text-align: left; vertical-align: top; }
|
|
64
|
+
th { color: var(--muted); font-weight: 600; font-size: 12px; }
|
|
65
|
+
td.n, th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
66
|
+
.pass { color: var(--pass); font-weight: 600; }
|
|
67
|
+
.fail { color: var(--fail); font-weight: 600; }
|
|
68
|
+
.warn { color: var(--warn); }
|
|
69
|
+
.muted { color: var(--muted); }
|
|
70
|
+
code { font: 12px ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
71
|
+
pre { white-space: pre-wrap; word-break: break-word; margin: 6px 0 0; font: 12px ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
72
|
+
details summary { cursor: pointer; }
|
|
73
|
+
ul { padding-left: 20px; }
|
|
74
|
+
`;
|
|
75
|
+
/** A self-contained HTML page: inline CSS, no scripts and no external assets */
|
|
76
|
+
export function htmlDocument(title, body) {
|
|
77
|
+
return [
|
|
78
|
+
'<!doctype html>',
|
|
79
|
+
'<html lang="en">',
|
|
80
|
+
'<head>',
|
|
81
|
+
'<meta charset="utf-8">',
|
|
82
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
83
|
+
`<title>${escapeHtml(title)}</title>`,
|
|
84
|
+
`<style>${STYLE}</style>`,
|
|
85
|
+
'</head>',
|
|
86
|
+
'<body>',
|
|
87
|
+
'<main>',
|
|
88
|
+
body,
|
|
89
|
+
'</main>',
|
|
90
|
+
'</body>',
|
|
91
|
+
'</html>',
|
|
92
|
+
'',
|
|
93
|
+
].join('\n');
|
|
94
|
+
}
|
|
95
|
+
/** A table, its cells already HTML; `numeric` marks the columns aligned right */
|
|
96
|
+
export function htmlTable(headers, rows, numeric = new Set()) {
|
|
97
|
+
const head = headers
|
|
98
|
+
.map((h, i) => `<th${numeric.has(i) ? ' class="n"' : ''}>${escapeHtml(h)}</th>`)
|
|
99
|
+
.join('');
|
|
100
|
+
const body = rows
|
|
101
|
+
.map((row) => `<tr>${row.map((c, i) => `<td${numeric.has(i) ? ' class="n"' : ''}>${c}</td>`).join('')}</tr>`)
|
|
102
|
+
.join('\n');
|
|
103
|
+
return `<div class="scroll"><table><thead><tr>${head}</tr></thead><tbody>\n${body}\n</tbody></table></div>`;
|
|
104
|
+
}
|
|
105
|
+
/** A row of figures, each value already HTML */
|
|
106
|
+
export function htmlTiles(tiles) {
|
|
107
|
+
return `<div class="tiles">${tiles
|
|
108
|
+
.map(([label, value]) => `<div class="tile"><b>${value}</b><span>${escapeHtml(label)}</span></div>`)
|
|
109
|
+
.join('')}</div>`;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=html-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-format.js","sourceRoot":"","sources":["../../src/reporters/html-format.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,MAAc,GAAG;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC;SACtB,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;SACjB,IAAI,CAAC,EAAE,CAAC;SACR,OAAO,EAAE,CAAC;IACb,OAAO,qBAAqB,UAAU,CAAC,OAAO,CAAC,qBAAqB,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC;AAC1G,CAAC;AAED,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDb,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,IAAY;IACtD,OAAO;QACL,iBAAiB;QACjB,kBAAkB;QAClB,QAAQ;QACR,wBAAwB;QACxB,sEAAsE;QACtE,UAAU,UAAU,CAAC,KAAK,CAAC,UAAU;QACrC,UAAU,KAAK,UAAU;QACzB,SAAS;QACT,QAAQ;QACR,QAAQ;QACR,IAAI;QACJ,SAAS;QACT,SAAS;QACT,SAAS;QACT,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,SAAS,CACvB,OAA0B,EAC1B,IAAoC,EACpC,UAA+B,IAAI,GAAG,EAAE;IAExC,MAAM,IAAI,GAAG,OAAO;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;SAC/E,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,MAAM,IAAI,GAAG,IAAI;SACd,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CACjG;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,yCAAyC,IAAI,yBAAyB,IAAI,0BAA0B,CAAC;AAC9G,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,SAAS,CAAC,KAA6D;IACrF,OAAO,sBAAsB,KAAK;SAC/B,GAAG,CACF,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,wBAAwB,KAAK,aAAa,UAAU,CAAC,KAAK,CAAC,eAAe,CAC/F;SACA,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EvalSuiteResult } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* A self-contained HTML page of a suite run: the totals, the aggregated metrics, the assertions
|
|
4
|
+
* and every case with its scores and the failures of each of its trials. Inline CSS for light and
|
|
5
|
+
* dark color schemes, no scripts, no external assets, and every value from the run escaped
|
|
6
|
+
*/
|
|
7
|
+
export declare function htmlPage(result: EvalSuiteResult): string;
|
|
8
|
+
/** Writes the HTML page of a suite run */
|
|
9
|
+
export declare function htmlReport(result: EvalSuiteResult, options: {
|
|
10
|
+
path: string;
|
|
11
|
+
}): void;
|
|
12
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/reporters/html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAmD7D;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAqFxD;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAEnF"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { caseFlags, caseProblems, num, trialsPerCase } from './format.js';
|
|
3
|
+
import { escapeHtml, foldable, htmlDocument, htmlTable, htmlTiles } from './html-format.js';
|
|
4
|
+
function scoresCell(r) {
|
|
5
|
+
if (r.scores.length === 0)
|
|
6
|
+
return '<span class="muted">-</span>';
|
|
7
|
+
return r.scores
|
|
8
|
+
.map((s) => {
|
|
9
|
+
const failed = s.error !== undefined ? ` <span class="fail">${escapeHtml(s.error)}</span>` : '';
|
|
10
|
+
return `<code>${escapeHtml(s.name)}</code> ${escapeHtml(num(s.score))}${failed}`;
|
|
11
|
+
})
|
|
12
|
+
.join('<br>');
|
|
13
|
+
}
|
|
14
|
+
function statusCell(r) {
|
|
15
|
+
const parts = [];
|
|
16
|
+
if (r.error !== undefined)
|
|
17
|
+
parts.push(`<span class="fail">error</span> ${foldable(r.error, 80)}`);
|
|
18
|
+
else
|
|
19
|
+
parts.push('<span class="pass">answered</span>');
|
|
20
|
+
for (const flag of caseFlags(r))
|
|
21
|
+
parts.push(`<span class="warn">${escapeHtml(flag)}</span>`);
|
|
22
|
+
if (r.trials && r.trials.length > 1) {
|
|
23
|
+
const answered = r.trials.filter((t) => t.error === undefined).length;
|
|
24
|
+
parts.push(`<span class="muted">${answered} of ${r.trials.length} trials answered</span>`);
|
|
25
|
+
for (const problem of caseProblems(r)) {
|
|
26
|
+
parts.push(`<span class="fail">${foldable(problem, 80)}</span>`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return parts.join('<br>');
|
|
30
|
+
}
|
|
31
|
+
function outputCell(r) {
|
|
32
|
+
if (!r.turns || r.turns.length === 0)
|
|
33
|
+
return foldable(r.output);
|
|
34
|
+
const conversation = r.turns
|
|
35
|
+
.map((turn) => `user: ${turn.input}\nagent: ${turn.error !== undefined ? `(error) ${turn.error}` : turn.output}`)
|
|
36
|
+
.join('\n\n');
|
|
37
|
+
return `<details><summary>${r.turns.length} turns</summary><pre>${escapeHtml(conversation)}</pre></details>`;
|
|
38
|
+
}
|
|
39
|
+
function runCell(r) {
|
|
40
|
+
const parts = [];
|
|
41
|
+
if (r.traceId !== undefined)
|
|
42
|
+
parts.push(`<code>${escapeHtml(r.traceId)}</code>`);
|
|
43
|
+
if (r.prompt) {
|
|
44
|
+
const version = r.prompt.version !== undefined ? ` v${r.prompt.version}` : '';
|
|
45
|
+
parts.push(`<span class="muted">${escapeHtml(r.prompt.key + version)}</span>`);
|
|
46
|
+
}
|
|
47
|
+
return parts.length > 0 ? parts.join('<br>') : '<span class="muted">-</span>';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A self-contained HTML page of a suite run: the totals, the aggregated metrics, the assertions
|
|
51
|
+
* and every case with its scores and the failures of each of its trials. Inline CSS for light and
|
|
52
|
+
* dark color schemes, no scripts, no external assets, and every value from the run escaped
|
|
53
|
+
*/
|
|
54
|
+
export function htmlPage(result) {
|
|
55
|
+
const { stats } = result;
|
|
56
|
+
const title = result.name === undefined ? 'Eval results' : `Eval results: ${result.name}`;
|
|
57
|
+
const passed = result.assertions.filter((a) => a.passed).length;
|
|
58
|
+
const failed = result.assertions.length - passed;
|
|
59
|
+
const trials = trialsPerCase(result);
|
|
60
|
+
const sections = [
|
|
61
|
+
`<h1>${escapeHtml(title)}</h1>`,
|
|
62
|
+
...(result.runId !== undefined
|
|
63
|
+
? [`<p class="sub">Run <code>${escapeHtml(result.runId)}</code></p>`]
|
|
64
|
+
: []),
|
|
65
|
+
htmlTiles([
|
|
66
|
+
['cases', escapeHtml(String(stats.total))],
|
|
67
|
+
...(trials > 1 ? [['trials per case', escapeHtml(String(trials))]] : []),
|
|
68
|
+
['errored', escapeHtml(String(stats.errors ?? 0))],
|
|
69
|
+
...(stats.metricErrors
|
|
70
|
+
? [['metric errors', escapeHtml(String(stats.metricErrors))]]
|
|
71
|
+
: []),
|
|
72
|
+
['duration', `${escapeHtml(String(stats.duration))} ms`],
|
|
73
|
+
['cost', `${escapeHtml(num(stats.cost))} USD`],
|
|
74
|
+
...(result.assertions.length > 0
|
|
75
|
+
? [
|
|
76
|
+
[
|
|
77
|
+
'assertions',
|
|
78
|
+
`<span class="${failed > 0 ? 'fail' : 'pass'}">${passed} / ${result.assertions.length}</span>`,
|
|
79
|
+
],
|
|
80
|
+
]
|
|
81
|
+
: []),
|
|
82
|
+
]),
|
|
83
|
+
];
|
|
84
|
+
const metrics = Object.values(result.aggregated);
|
|
85
|
+
if (metrics.length > 0) {
|
|
86
|
+
sections.push('<h2>Metrics</h2>', htmlTable(['Metric', 'Mean', 'P50', 'P95', 'Min', 'Max', 'Cases'], metrics.map((m) => [
|
|
87
|
+
`<code>${escapeHtml(m.name)}</code>`,
|
|
88
|
+
...[m.mean, m.p50, m.p95, m.min, m.max].map((v) => escapeHtml(num(v))),
|
|
89
|
+
m.count === undefined ? '-' : escapeHtml(String(m.count)),
|
|
90
|
+
]), new Set([1, 2, 3, 4, 5, 6])));
|
|
91
|
+
}
|
|
92
|
+
if (result.assertions.length > 0) {
|
|
93
|
+
sections.push('<h2>Assertions</h2>', htmlTable(['Result', 'Assertion', 'Details'], result.assertions.map((a) => [
|
|
94
|
+
a.passed ? '<span class="pass">pass</span>' : '<span class="fail">fail</span>',
|
|
95
|
+
`<code>${escapeHtml(a.name)}</code>`,
|
|
96
|
+
escapeHtml(a.message),
|
|
97
|
+
])));
|
|
98
|
+
}
|
|
99
|
+
if (result.results.length > 0) {
|
|
100
|
+
const showRun = result.results.some((r) => r.traceId !== undefined || r.prompt !== undefined);
|
|
101
|
+
sections.push('<h2>Cases</h2>', htmlTable(['#', 'Input', 'Expected', 'Output', 'Scores', 'Status', ...(showRun ? ['Trace'] : [])], result.results.map((r, i) => [
|
|
102
|
+
String(i + 1),
|
|
103
|
+
foldable(r.case.input),
|
|
104
|
+
r.case.expected === undefined
|
|
105
|
+
? '<span class="muted">-</span>'
|
|
106
|
+
: foldable(r.case.expected),
|
|
107
|
+
outputCell(r),
|
|
108
|
+
scoresCell(r),
|
|
109
|
+
statusCell(r),
|
|
110
|
+
...(showRun ? [runCell(r)] : []),
|
|
111
|
+
]), new Set([0])));
|
|
112
|
+
}
|
|
113
|
+
return htmlDocument(title, sections.join('\n'));
|
|
114
|
+
}
|
|
115
|
+
/** Writes the HTML page of a suite run */
|
|
116
|
+
export function htmlReport(result, options) {
|
|
117
|
+
writeFileSync(options.path, htmlPage(result), 'utf-8');
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/reporters/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EvalStats } from '../assertions/index.js';
|
|
2
|
-
import type { EvalToolCall, EvalToolResult, EvalTurnResult, Passage } from '../metrics/types.js';
|
|
2
|
+
import type { EvalPrompt, EvalToolCall, EvalToolResult, EvalTurnResult, Passage } from '../metrics/types.js';
|
|
3
3
|
export interface AggregatedMetric {
|
|
4
4
|
name: string;
|
|
5
5
|
mean: number;
|
|
@@ -46,6 +46,10 @@ export interface ReportedCase {
|
|
|
46
46
|
retrieved?: readonly Passage[];
|
|
47
47
|
/** Each turn of a multi-turn case */
|
|
48
48
|
turns?: readonly EvalTurnResult[];
|
|
49
|
+
/** The trace of the agent run, the last turn's for a multi-turn case */
|
|
50
|
+
traceId?: string;
|
|
51
|
+
/** The versioned instructions the agent run used, the last turn's for a multi-turn case */
|
|
52
|
+
prompt?: EvalPrompt;
|
|
49
53
|
scores: Array<{
|
|
50
54
|
name: string;
|
|
51
55
|
score: number;
|
|
@@ -56,21 +60,29 @@ export interface ReportedCase {
|
|
|
56
60
|
trials?: readonly ReportedCase[];
|
|
57
61
|
}
|
|
58
62
|
export interface EvalSuiteResult {
|
|
63
|
+
/** The suite's `name`, the title of the markdown and html reports */
|
|
64
|
+
name?: string;
|
|
65
|
+
/** The id of the run */
|
|
66
|
+
runId?: string;
|
|
59
67
|
results: ReportedCase[];
|
|
60
68
|
aggregated: Record<string, AggregatedMetric>;
|
|
61
69
|
assertions: AssertionResult[];
|
|
62
70
|
stats: EvalStats;
|
|
63
71
|
}
|
|
64
|
-
export type ReporterType = 'console' | 'json' | 'csv' | 'ci' | 'junit' | 'github';
|
|
72
|
+
export type ReporterType = 'console' | 'json' | 'csv' | 'ci' | 'junit' | 'github' | 'markdown' | 'html';
|
|
65
73
|
export type ReporterOptions = {
|
|
66
74
|
/**
|
|
67
|
-
* Base path of file reports. Each file reporter writes it with its own
|
|
68
|
-
*
|
|
75
|
+
* Base path of file reports. Each file reporter writes it with its own extension, so
|
|
76
|
+
* `./reports/eval` gives `eval.json`, `eval.csv`, `eval.xml`, `eval.md` and `eval.html`.
|
|
69
77
|
*/
|
|
70
78
|
path?: string;
|
|
71
79
|
};
|
|
72
|
-
/** The
|
|
73
|
-
export
|
|
80
|
+
/** The extension of a file report */
|
|
81
|
+
export type ReportExtension = 'json' | 'csv' | 'xml' | 'md' | 'html';
|
|
82
|
+
/** The file a reporter writes: the base path, without a report extension, with the reporter's */
|
|
83
|
+
export declare function reportPath(base: string | undefined, extension: ReportExtension, fallback?: string): string;
|
|
84
|
+
/** Creates the directory of a report file, returning the path */
|
|
85
|
+
export declare function prepare(path: string): string;
|
|
74
86
|
/**
|
|
75
87
|
* Runs the reporters in the order given, except `ci`, which runs last so its verdict is the
|
|
76
88
|
* final line of the output. `ci` sets `process.exitCode` to 1 when an assertion failed instead
|
|
@@ -83,4 +95,6 @@ export { csvReport } from './csv.js';
|
|
|
83
95
|
export { ciReport } from './ci.js';
|
|
84
96
|
export { junitReport } from './junit.js';
|
|
85
97
|
export { githubReport } from './github.js';
|
|
98
|
+
export { markdownReport, markdownSummary } from './markdown.js';
|
|
99
|
+
export { htmlReport, htmlPage } from './html.js';
|
|
86
100
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"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"}
|
package/dist/reporters/index.js
CHANGED
|
@@ -6,13 +6,16 @@ import { csvReport } from './csv.js';
|
|
|
6
6
|
import { ciReport } from './ci.js';
|
|
7
7
|
import { junitReport } from './junit.js';
|
|
8
8
|
import { githubReport } from './github.js';
|
|
9
|
+
import { markdownReport } from './markdown.js';
|
|
10
|
+
import { htmlReport } from './html.js';
|
|
9
11
|
const DEFAULT_BASE = 'eval-report';
|
|
10
|
-
/** The file a reporter writes: the base path with the reporter's
|
|
11
|
-
export function reportPath(base, extension) {
|
|
12
|
-
const stem = (base ??
|
|
12
|
+
/** The file a reporter writes: the base path, without a report extension, with the reporter's */
|
|
13
|
+
export function reportPath(base, extension, fallback = DEFAULT_BASE) {
|
|
14
|
+
const stem = (base ?? fallback).replace(/\.(json|csv|xml|md|html)$/i, '');
|
|
13
15
|
return `${stem}.${extension}`;
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
/** Creates the directory of a report file, returning the path */
|
|
18
|
+
export function prepare(path) {
|
|
16
19
|
mkdirSync(dirname(path), { recursive: true });
|
|
17
20
|
return path;
|
|
18
21
|
}
|
|
@@ -41,6 +44,12 @@ export function report(result, type, options) {
|
|
|
41
44
|
case 'github':
|
|
42
45
|
githubReport(result);
|
|
43
46
|
break;
|
|
47
|
+
case 'markdown':
|
|
48
|
+
markdownReport(result, { path: prepare(reportPath(options?.path, 'md')) });
|
|
49
|
+
break;
|
|
50
|
+
case 'html':
|
|
51
|
+
htmlReport(result, { path: prepare(reportPath(options?.path, 'html')) });
|
|
52
|
+
break;
|
|
44
53
|
case 'ci':
|
|
45
54
|
ciReport(result);
|
|
46
55
|
break;
|
|
@@ -53,4 +62,6 @@ export { csvReport } from './csv.js';
|
|
|
53
62
|
export { ciReport } from './ci.js';
|
|
54
63
|
export { junitReport } from './junit.js';
|
|
55
64
|
export { githubReport } from './github.js';
|
|
65
|
+
export { markdownReport, markdownSummary } from './markdown.js';
|
|
66
|
+
export { htmlReport, htmlPage } from './html.js';
|
|
56
67
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EvalSuiteResult } from './index.js';
|
|
2
|
+
/** Most failures the summary lists before it counts the rest */
|
|
3
|
+
export declare const MARKDOWN_MAX_FAILURES = 25;
|
|
4
|
+
/**
|
|
5
|
+
* A compact Markdown summary of a suite run for a pull request comment: the totals, the mean of
|
|
6
|
+
* each metric with the cases it covers, the assertions and the failures of every case and trial.
|
|
7
|
+
* Every value from the run is escaped, so no answer can break the tables or hide the rest of the
|
|
8
|
+
* comment
|
|
9
|
+
*/
|
|
10
|
+
export declare function markdownSummary(result: EvalSuiteResult): string;
|
|
11
|
+
/** Writes the Markdown summary of a suite run */
|
|
12
|
+
export declare function markdownReport(result: EvalSuiteResult, options: {
|
|
13
|
+
path: string;
|
|
14
|
+
}): void;
|
|
15
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/reporters/markdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,gEAAgE;AAChE,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAUxC;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAkD/D;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAEvF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { caseLabel, caseProblems, cell, num, trialsPerCase } from './format.js';
|
|
3
|
+
/** Most failures the summary lists before it counts the rest */
|
|
4
|
+
export const MARKDOWN_MAX_FAILURES = 25;
|
|
5
|
+
/** The failures of the cases, of every trial: errored runs, then metrics that failed */
|
|
6
|
+
function failures(result) {
|
|
7
|
+
return result.results.flatMap((r, i) => {
|
|
8
|
+
const label = caseLabel(i, r.case.input);
|
|
9
|
+
return caseProblems(r).map((problem) => ({ label, problem }));
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A compact Markdown summary of a suite run for a pull request comment: the totals, the mean of
|
|
14
|
+
* each metric with the cases it covers, the assertions and the failures of every case and trial.
|
|
15
|
+
* Every value from the run is escaped, so no answer can break the tables or hide the rest of the
|
|
16
|
+
* comment
|
|
17
|
+
*/
|
|
18
|
+
export function markdownSummary(result) {
|
|
19
|
+
const { stats } = result;
|
|
20
|
+
const passed = result.assertions.filter((a) => a.passed).length;
|
|
21
|
+
const failed = result.assertions.length - passed;
|
|
22
|
+
const trials = trialsPerCase(result);
|
|
23
|
+
const totals = [
|
|
24
|
+
`**${stats.total}** cases${trials > 1 ? ` x **${trials}** trials` : ''}`,
|
|
25
|
+
`**${stats.errors ?? 0}** errored`,
|
|
26
|
+
...(stats.metricErrors ? [`**${stats.metricErrors}** metric errors`] : []),
|
|
27
|
+
`${stats.duration} ms`,
|
|
28
|
+
`${num(stats.cost)} USD`,
|
|
29
|
+
...(result.assertions.length > 0
|
|
30
|
+
? [`assertions: **${passed}** passed, **${failed}** failed`]
|
|
31
|
+
: []),
|
|
32
|
+
];
|
|
33
|
+
const title = result.name === undefined ? 'Eval results' : `Eval results: ${cell(result.name)}`;
|
|
34
|
+
const lines = [`### ${title}`, '', totals.join(' | '), ''];
|
|
35
|
+
const metrics = Object.values(result.aggregated);
|
|
36
|
+
if (metrics.length > 0) {
|
|
37
|
+
lines.push('| Metric | Mean | Cases |', '| --- | ---: | ---: |');
|
|
38
|
+
for (const m of metrics) {
|
|
39
|
+
lines.push(`| ${cell(m.name)} | ${num(m.mean)} | ${m.count === undefined ? '-' : m.count} |`);
|
|
40
|
+
}
|
|
41
|
+
lines.push('');
|
|
42
|
+
}
|
|
43
|
+
if (result.assertions.length > 0) {
|
|
44
|
+
lines.push('| Assertion | Result | Details |', '| --- | --- | --- |');
|
|
45
|
+
for (const a of result.assertions) {
|
|
46
|
+
lines.push(`| ${cell(a.name)} | ${a.passed ? 'pass' : '**fail**'} | ${cell(a.message)} |`);
|
|
47
|
+
}
|
|
48
|
+
lines.push('');
|
|
49
|
+
}
|
|
50
|
+
const failedCases = failures(result);
|
|
51
|
+
if (failedCases.length > 0) {
|
|
52
|
+
lines.push(`**Failures** (${failedCases.length})`, '', '| Case | Problem |', '| --- | --- |');
|
|
53
|
+
for (const { label, problem } of failedCases.slice(0, MARKDOWN_MAX_FAILURES)) {
|
|
54
|
+
lines.push(`| ${cell(label)} | ${cell(problem)} |`);
|
|
55
|
+
}
|
|
56
|
+
if (failedCases.length > MARKDOWN_MAX_FAILURES) {
|
|
57
|
+
lines.push('', `and ${failedCases.length - MARKDOWN_MAX_FAILURES} more`);
|
|
58
|
+
}
|
|
59
|
+
lines.push('');
|
|
60
|
+
}
|
|
61
|
+
return lines.join('\n');
|
|
62
|
+
}
|
|
63
|
+
/** Writes the Markdown summary of a suite run */
|
|
64
|
+
export function markdownReport(result, options) {
|
|
65
|
+
writeFileSync(options.path, markdownSummary(result), 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/reporters/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ComparisonTest } from '../comparison-stats.js';
|
|
3
|
+
import type { EvalRunSource } from './run.js';
|
|
4
|
+
export declare const CompareRunsOptionsSchema: z.ZodObject<{
|
|
5
|
+
alpha: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
test: z.ZodDefault<z.ZodEnum<{
|
|
7
|
+
t: "t";
|
|
8
|
+
wilcoxon: "wilcoxon";
|
|
9
|
+
}>>;
|
|
10
|
+
seed: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>;
|
|
11
|
+
metrics: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export interface CompareRunsOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Significance level, 0.05 by default. A metric is significant when its p-value, adjusted with
|
|
16
|
+
* Holm's correction across the compared metrics, is below it, and its `ci` covers `1 - alpha`
|
|
17
|
+
*/
|
|
18
|
+
alpha?: number;
|
|
19
|
+
/** Test of metrics that are not binary: `t` (paired t-test, the default) or `wilcoxon` */
|
|
20
|
+
test?: 't' | 'wilcoxon';
|
|
21
|
+
/** Seeds the bootstrap of each metric's `ci`, so the intervals are the same on every call */
|
|
22
|
+
seed?: number | string;
|
|
23
|
+
/**
|
|
24
|
+
* The metrics to compare. Default: every per-case metric both runs have and scored on at least
|
|
25
|
+
* one matched case, the others named in `warnings`, so a metric without data neither shows two
|
|
26
|
+
* means of 0 nor weakens the Holm correction of the others
|
|
27
|
+
*/
|
|
28
|
+
metrics?: string[];
|
|
29
|
+
}
|
|
30
|
+
export type RunWinner = 'base' | 'head' | 'tie';
|
|
31
|
+
/** How the score of a case moved from the base run to the head run */
|
|
32
|
+
export interface RunCaseChange {
|
|
33
|
+
caseKey: string;
|
|
34
|
+
/** The case input on one line, shortened */
|
|
35
|
+
input: string;
|
|
36
|
+
base: number;
|
|
37
|
+
head: number;
|
|
38
|
+
/** `head` minus `base` */
|
|
39
|
+
delta: number;
|
|
40
|
+
}
|
|
41
|
+
export interface RunMetricComparison {
|
|
42
|
+
/** Mean score of the base run over the compared cases, NaN when `n` is 0 */
|
|
43
|
+
base: number;
|
|
44
|
+
head: number;
|
|
45
|
+
/** Cases compared: matched cases at least one run scored, an errored side counting as a 0 */
|
|
46
|
+
n: number;
|
|
47
|
+
/** Mean of the paired differences, head minus base */
|
|
48
|
+
difference: number;
|
|
49
|
+
/** Percentile bootstrap confidence interval of `difference` at `1 - alpha` */
|
|
50
|
+
ci: {
|
|
51
|
+
low: number;
|
|
52
|
+
high: number;
|
|
53
|
+
};
|
|
54
|
+
/** Cohen's d of the paired differences (dz), NaN with fewer than 2 cases */
|
|
55
|
+
effectSize: number;
|
|
56
|
+
test: ComparisonTest;
|
|
57
|
+
pValue: number;
|
|
58
|
+
/** `pValue` after Holm's correction across the compared metrics */
|
|
59
|
+
adjustedPValue: number;
|
|
60
|
+
significant: boolean;
|
|
61
|
+
/** The higher run when significant, by the test's direction */
|
|
62
|
+
winner: RunWinner;
|
|
63
|
+
/** Cases whose score rose, the largest rise first */
|
|
64
|
+
improved: RunCaseChange[];
|
|
65
|
+
/** Cases whose score fell, the largest fall first */
|
|
66
|
+
regressed: RunCaseChange[];
|
|
67
|
+
}
|
|
68
|
+
/** Which run a side of a comparison is */
|
|
69
|
+
export interface RunRef {
|
|
70
|
+
runId: string;
|
|
71
|
+
name?: string;
|
|
72
|
+
startedAt: string;
|
|
73
|
+
}
|
|
74
|
+
/** A case only one of the runs has */
|
|
75
|
+
export interface RunCaseRef {
|
|
76
|
+
caseKey: string;
|
|
77
|
+
input: string;
|
|
78
|
+
}
|
|
79
|
+
export interface RunComparison {
|
|
80
|
+
base: RunRef;
|
|
81
|
+
head: RunRef;
|
|
82
|
+
/** The run more metrics name as their winner, a tie when as many name each */
|
|
83
|
+
winner: RunWinner;
|
|
84
|
+
metrics: Record<string, RunMetricComparison>;
|
|
85
|
+
/** Cases both runs have, matched by `caseKey` */
|
|
86
|
+
matched: number;
|
|
87
|
+
/** Cases only the head run has */
|
|
88
|
+
added: RunCaseRef[];
|
|
89
|
+
/** Cases only the base run has */
|
|
90
|
+
removed: RunCaseRef[];
|
|
91
|
+
/**
|
|
92
|
+
* What makes the runs harder to compare: other cases, other prompts, other metrics or judge,
|
|
93
|
+
* and metrics left out because no matched case was scored on them
|
|
94
|
+
*/
|
|
95
|
+
warnings: string[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Compares two saved runs, or suite results, case by case: cases are matched by their `caseKey`,
|
|
99
|
+
* and each metric both runs have is compared as `EvalComparison` compares its sides, the base run
|
|
100
|
+
* in the baseline's place and the head run in the challenger's
|
|
101
|
+
*/
|
|
102
|
+
export declare function compareRuns(baseSource: EvalRunSource, headSource: EvalRunSource, options?: CompareRunsOptions): RunComparison;
|
|
103
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/runs/compare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AAI5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,eAAO,MAAM,wBAAwB;;;;;;;;iBAKnC,CAAC;AAEH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,IAAI,CAAC,EAAE,GAAG,GAAG,UAAU,CAAC;IACxB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEhD,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,CAAC,EAAE,MAAM,CAAC;IACV,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,MAAM,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,qDAAqD;IACrD,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC7C,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,kCAAkC;IAClC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA8JD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EACzB,UAAU,EAAE,aAAa,EACzB,OAAO,GAAE,kBAAuB,GAC/B,aAAa,CAyDf"}
|