@ac-bench/measure-duration 0.1.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/LICENSE +28 -0
- package/README.md +34 -0
- package/dist/_harness-overhead.d.ts +36 -0
- package/dist/_harness-overhead.d.ts.map +1 -0
- package/dist/_harness-overhead.js +62 -0
- package/dist/_harness-overhead.js.map +1 -0
- package/dist/_iteration-protocol.d.ts +18 -0
- package/dist/_iteration-protocol.d.ts.map +1 -0
- package/dist/_iteration-protocol.js +17 -0
- package/dist/_iteration-protocol.js.map +1 -0
- package/dist/_iteration-source.d.ts +64 -0
- package/dist/_iteration-source.d.ts.map +1 -0
- package/dist/_iteration-source.js +135 -0
- package/dist/_iteration-source.js.map +1 -0
- package/dist/_pool.d.ts +48 -0
- package/dist/_pool.d.ts.map +1 -0
- package/dist/_pool.js +219 -0
- package/dist/_pool.js.map +1 -0
- package/dist/_process-execution.d.ts +62 -0
- package/dist/_process-execution.d.ts.map +1 -0
- package/dist/_process-execution.js +142 -0
- package/dist/_process-execution.js.map +1 -0
- package/dist/_run-case.d.ts +32 -0
- package/dist/_run-case.d.ts.map +1 -0
- package/dist/_run-case.js +267 -0
- package/dist/_run-case.js.map +1 -0
- package/dist/_sampling-options.d.ts +61 -0
- package/dist/_sampling-options.d.ts.map +1 -0
- package/dist/_sampling-options.js +19 -0
- package/dist/_sampling-options.js.map +1 -0
- package/dist/_sampling-report.d.ts +44 -0
- package/dist/_sampling-report.d.ts.map +1 -0
- package/dist/_sampling-report.js +43 -0
- package/dist/_sampling-report.js.map +1 -0
- package/dist/_spawn-baseline.d.ts +35 -0
- package/dist/_spawn-baseline.d.ts.map +1 -0
- package/dist/_spawn-baseline.js +22 -0
- package/dist/_spawn-baseline.js.map +1 -0
- package/dist/_statistics-schema.d.ts +28 -0
- package/dist/_statistics-schema.d.ts.map +1 -0
- package/dist/_statistics-schema.js +59 -0
- package/dist/_statistics-schema.js.map +1 -0
- package/dist/_statistics.d.ts +25 -0
- package/dist/_statistics.d.ts.map +1 -0
- package/dist/_statistics.js +72 -0
- package/dist/_statistics.js.map +1 -0
- package/dist/_types.d.ts +302 -0
- package/dist/_types.d.ts.map +1 -0
- package/dist/_types.js +57 -0
- package/dist/_types.js.map +1 -0
- package/dist/_warnings.d.ts +62 -0
- package/dist/_warnings.d.ts.map +1 -0
- package/dist/_warnings.js +132 -0
- package/dist/_warnings.js.map +1 -0
- package/dist/decl.d.ts +21 -0
- package/dist/decl.d.ts.map +1 -0
- package/dist/decl.js +54 -0
- package/dist/decl.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/iteration-child.d.ts +2 -0
- package/dist/iteration-child.d.ts.map +1 -0
- package/dist/iteration-child.js +37 -0
- package/dist/iteration-child.js.map +1 -0
- package/dist/options.d.ts +59 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +2 -0
- package/dist/options.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +205 -0
- package/dist/plugin.js.map +1 -0
- package/dist/spawn-overhead.d.ts +59 -0
- package/dist/spawn-overhead.d.ts.map +1 -0
- package/dist/spawn-overhead.js +80 -0
- package/dist/spawn-overhead.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { createRelativeErrorPolicy, Sampler, } from "@ac-bench/core/runner";
|
|
2
|
+
import { defaults, formatError } from "@ac-kit/core";
|
|
3
|
+
import { calibrateHarnessOverhead, detectHarnessShape, } from "./_harness-overhead.js";
|
|
4
|
+
import { SINGLE_ITERATION_OPTION } from "./_iteration-protocol.js";
|
|
5
|
+
import { commandCaseCommand, iterationProcessCommand, measureIteration, measureSpawnBaseline, spawnBaselineReport, summariseColdStart, } from "./_iteration-source.js";
|
|
6
|
+
import { ProcessGroup } from "./_process-execution.js";
|
|
7
|
+
import { DURATION_SAMPLING_DEFAULTS, } from "./_sampling-options.js";
|
|
8
|
+
import { summarise } from "./_statistics.js";
|
|
9
|
+
import { detectWarnings_ } from "./_warnings.js";
|
|
10
|
+
/** Above this predicted batch duration, cancellation is checked per iteration. */
|
|
11
|
+
const LONG_BATCH_MS_ = 200;
|
|
12
|
+
/**
|
|
13
|
+
* Runs one benchmark case under the adaptive sampler.
|
|
14
|
+
*
|
|
15
|
+
* The loop belongs to the sampler: it decides how many samples to take next and
|
|
16
|
+
* when the interval around the estimate is tight enough. What happens here is
|
|
17
|
+
* only the measuring — the timed span is `performance.now()` immediately around
|
|
18
|
+
* one iteration and nothing else, so hooks, statistics and reporting stay
|
|
19
|
+
* outside the number being reported.
|
|
20
|
+
*
|
|
21
|
+
* An iteration is one call in this process, one fresh process running this same
|
|
22
|
+
* case body, or one execution of an external program. All three go through the
|
|
23
|
+
* same loop and the same stopping rule; only what an iteration _is_ differs.
|
|
24
|
+
*
|
|
25
|
+
* @param title Case name, carried into the reported result.
|
|
26
|
+
* @param runFn The work to measure.
|
|
27
|
+
* @param context Run context, used to report the result and check for abort.
|
|
28
|
+
* @param options Sampling policy and execution mode.
|
|
29
|
+
*/
|
|
30
|
+
export async function runDurationCase(title, runFn, context, options) {
|
|
31
|
+
const { signal } = context;
|
|
32
|
+
signal.throwIfAborted();
|
|
33
|
+
// A spawned iteration re-enters this same case body; without this it would
|
|
34
|
+
// start a sampling run of its own, one process deep, forever.
|
|
35
|
+
if (context.measureOptions[SINGLE_ITERATION_OPTION] === true) {
|
|
36
|
+
await runSingleIteration_(runFn, options, signal);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const sampling = defaults(options?.conditionOptions?.sampling, DURATION_SAMPLING_DEFAULTS);
|
|
40
|
+
const tags = options?.tags ?? {};
|
|
41
|
+
const command = resolveCommand_(context, options);
|
|
42
|
+
const execution = options?.commandCase !== undefined
|
|
43
|
+
? "command"
|
|
44
|
+
: (options?.execution ?? "in-process");
|
|
45
|
+
if (command !== null && options?.overheadMs !== undefined) {
|
|
46
|
+
if (options.subtractSpawnBaseline === true) {
|
|
47
|
+
throw new Error(`Case "${title}" declares both overheadMs and subtractSpawnBaseline; they would be subtracted twice`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const subtractBaseline = command !== null &&
|
|
51
|
+
options?.overheadMs === undefined &&
|
|
52
|
+
options?.subtractSpawnBaseline !== false;
|
|
53
|
+
const group = command === null ? null : new ProcessGroup();
|
|
54
|
+
const coldStartPhases = [];
|
|
55
|
+
let overheadMs = options?.overheadMs ?? 0;
|
|
56
|
+
let baselineStatistics = null;
|
|
57
|
+
const sampler = new Sampler(createRelativeErrorPolicy(sampling), {
|
|
58
|
+
bounds: sampling,
|
|
59
|
+
signal,
|
|
60
|
+
costOf: (ms) => ms,
|
|
61
|
+
});
|
|
62
|
+
const timings = [];
|
|
63
|
+
const correctedTimings = [];
|
|
64
|
+
const adjustedTimings = [];
|
|
65
|
+
let measuredMs = 0;
|
|
66
|
+
let startedAt = null;
|
|
67
|
+
let endedAt = 0;
|
|
68
|
+
let shape = "sync";
|
|
69
|
+
let harnessMs = 0;
|
|
70
|
+
let harnessOverhead = null;
|
|
71
|
+
try {
|
|
72
|
+
// The case's own setup runs inside each spawned process, so that a cold
|
|
73
|
+
// start is measured whole rather than with its preparation hoisted out.
|
|
74
|
+
if (command === null) {
|
|
75
|
+
await options?.setup?.(signal);
|
|
76
|
+
}
|
|
77
|
+
if (command === null) {
|
|
78
|
+
// Warmup runs before the pilot and is never counted in the statistics.
|
|
79
|
+
for (let iteration = 0; iteration < sampling.warmup; iteration++) {
|
|
80
|
+
signal.throwIfAborted();
|
|
81
|
+
await options?.beforeEach?.(signal);
|
|
82
|
+
const returned = runFn(signal);
|
|
83
|
+
if (iteration === 0) {
|
|
84
|
+
shape = detectHarnessShape(runFn, returned);
|
|
85
|
+
}
|
|
86
|
+
await returned;
|
|
87
|
+
await options?.afterEach?.(signal);
|
|
88
|
+
}
|
|
89
|
+
// After warmup and before the pilot, so the shape is known and the
|
|
90
|
+
// measurement has not started.
|
|
91
|
+
const harness = await calibrateHarnessOverhead(shape, sampling.outlierThreshold, signal);
|
|
92
|
+
harnessMs = sampling.subtractHarnessOverhead ? harness.medianMs : 0;
|
|
93
|
+
harnessOverhead = {
|
|
94
|
+
shape,
|
|
95
|
+
medianMs: harness.medianMs,
|
|
96
|
+
share: 0,
|
|
97
|
+
subtracted: sampling.subtractHarnessOverhead,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// A spawn is orders of magnitude above the call overhead a harness
|
|
102
|
+
// correction addresses; what it needs removed is the program's own
|
|
103
|
+
// start-up, which is what the baseline measures.
|
|
104
|
+
baselineStatistics = await measureSpawnBaseline(group, command, { warmup: sampling.warmup, runs: sampling.minRuns }, signal);
|
|
105
|
+
if (subtractBaseline && baselineStatistics !== null) {
|
|
106
|
+
overheadMs = baselineStatistics.medianMs;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (let size = sampler.nextBatch(); size !== null;) {
|
|
110
|
+
const sliceStartedAt = performance.now();
|
|
111
|
+
startedAt ??= sliceStartedAt;
|
|
112
|
+
const batch = [];
|
|
113
|
+
const longBatch = size * (measuredMs / Math.max(1, timings.length)) > LONG_BATCH_MS_;
|
|
114
|
+
for (let iteration = 0; iteration < size; iteration++) {
|
|
115
|
+
if (longBatch || command !== null) {
|
|
116
|
+
signal.throwIfAborted();
|
|
117
|
+
}
|
|
118
|
+
await options?.beforeEach?.(signal);
|
|
119
|
+
const spanMs = command === null
|
|
120
|
+
? await measureInProcess_(runFn, signal)
|
|
121
|
+
: await measureIteration(group, command, coldStartPhases, signal);
|
|
122
|
+
await options?.afterEach?.(signal);
|
|
123
|
+
measuredMs += spanMs;
|
|
124
|
+
timings.push(spanMs);
|
|
125
|
+
// Negatives are kept rather than clamped: a one-sided truncation
|
|
126
|
+
// would bias the result upward exactly where the correction helps.
|
|
127
|
+
const corrected = spanMs - harnessMs;
|
|
128
|
+
correctedTimings.push(corrected);
|
|
129
|
+
adjustedTimings.push(corrected - overheadMs);
|
|
130
|
+
// The controller steers on the number a comparison is made on.
|
|
131
|
+
batch.push(corrected - overheadMs);
|
|
132
|
+
}
|
|
133
|
+
endedAt = performance.now();
|
|
134
|
+
sampler.observe(batch, endedAt - sliceStartedAt);
|
|
135
|
+
context.progress(timings.length);
|
|
136
|
+
if (signal.aborted) {
|
|
137
|
+
sampler.stop("cancelled");
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
size = sampler.nextBatch();
|
|
141
|
+
// A batch is a slice, and this is the boundary between two of them: a
|
|
142
|
+
// sibling case takes the next one. Asking the sampler first means a
|
|
143
|
+
// case that is done never spends a turn discovering it.
|
|
144
|
+
if (size !== null) {
|
|
145
|
+
await context.round();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
sampler.stop(signal.aborted ? "cancelled" : "failure");
|
|
151
|
+
await group?.dispose();
|
|
152
|
+
context.setCaseResult({
|
|
153
|
+
name: title,
|
|
154
|
+
tags,
|
|
155
|
+
statistics: null,
|
|
156
|
+
adjusted: null,
|
|
157
|
+
overheadMs,
|
|
158
|
+
timings: [],
|
|
159
|
+
sampling: null,
|
|
160
|
+
harnessOverhead: null,
|
|
161
|
+
execution,
|
|
162
|
+
spawnBaseline: null,
|
|
163
|
+
coldStart: null,
|
|
164
|
+
estimate: null,
|
|
165
|
+
contamination: null,
|
|
166
|
+
warnings: [],
|
|
167
|
+
failure: await failureMessage_(error, options, signal),
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
await group?.dispose();
|
|
172
|
+
if (command === null) {
|
|
173
|
+
await options?.teardown?.(signal);
|
|
174
|
+
}
|
|
175
|
+
const result = sampler.result();
|
|
176
|
+
const report = {
|
|
177
|
+
...result.metadata,
|
|
178
|
+
stopReason: result.stopReason,
|
|
179
|
+
measuredMs,
|
|
180
|
+
activeMs: result.activeMs,
|
|
181
|
+
elapsedMs: startedAt === null ? 0 : endedAt - startedAt,
|
|
182
|
+
samples: timings.length,
|
|
183
|
+
batches: result.batches,
|
|
184
|
+
};
|
|
185
|
+
// Outliers are flagged, never removed: dropping them would let the controller
|
|
186
|
+
// reach its target by discarding the evidence that it had not.
|
|
187
|
+
const statistics = summarise(correctedTimings, sampling.outlierThreshold);
|
|
188
|
+
if (harnessOverhead !== null) {
|
|
189
|
+
harnessOverhead = {
|
|
190
|
+
...harnessOverhead,
|
|
191
|
+
share: statistics.medianMs > 0
|
|
192
|
+
? harnessOverhead.medianMs / statistics.medianMs
|
|
193
|
+
: 1,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const spawnBaseline = command === null
|
|
197
|
+
? null
|
|
198
|
+
: spawnBaselineReport(command, baselineStatistics, statistics.medianMs, subtractBaseline && baselineStatistics !== null);
|
|
199
|
+
context.setCaseResult({
|
|
200
|
+
name: title,
|
|
201
|
+
tags,
|
|
202
|
+
statistics,
|
|
203
|
+
adjusted: overheadMs > 0
|
|
204
|
+
? summarise(adjustedTimings, sampling.outlierThreshold)
|
|
205
|
+
: null,
|
|
206
|
+
overheadMs,
|
|
207
|
+
timings,
|
|
208
|
+
sampling: report,
|
|
209
|
+
harnessOverhead,
|
|
210
|
+
execution,
|
|
211
|
+
spawnBaseline,
|
|
212
|
+
coldStart: summariseColdStart(coldStartPhases),
|
|
213
|
+
estimate: null,
|
|
214
|
+
contamination: null,
|
|
215
|
+
warnings: detectWarnings_({
|
|
216
|
+
timings,
|
|
217
|
+
statistics,
|
|
218
|
+
overheadMs,
|
|
219
|
+
minRuns: sampling.minRuns,
|
|
220
|
+
sampling: report,
|
|
221
|
+
harnessOverhead,
|
|
222
|
+
spawnBaseline,
|
|
223
|
+
needsBaselineArgs: command !== null && command.baselineArgs === null,
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
// After the timed region, and only on request: `child.send` has no transfer
|
|
227
|
+
// list, so every sample is copied across the boundary.
|
|
228
|
+
if (context.measureOptions["emitSamples"] === true) {
|
|
229
|
+
context.attach(JSON.stringify(timings), "application/json", `${title} samples`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async function measureInProcess_(runFn, signal) {
|
|
233
|
+
const begin = performance.now();
|
|
234
|
+
await runFn(signal);
|
|
235
|
+
return performance.now() - begin;
|
|
236
|
+
}
|
|
237
|
+
/** What one iteration executes, or `null` when it is a call in this process. */
|
|
238
|
+
function resolveCommand_(context, options) {
|
|
239
|
+
if (options?.commandCase !== undefined) {
|
|
240
|
+
return commandCaseCommand(options.commandCase.command, options.commandCase.args, options.commandCase.options);
|
|
241
|
+
}
|
|
242
|
+
return options?.execution === "per-iteration-process"
|
|
243
|
+
? iterationProcessCommand(context.caseId)
|
|
244
|
+
: null;
|
|
245
|
+
}
|
|
246
|
+
/** The body of one spawned iteration: setup and teardown are part of the sample. */
|
|
247
|
+
async function runSingleIteration_(runFn, options, signal) {
|
|
248
|
+
await options?.setup?.(signal);
|
|
249
|
+
try {
|
|
250
|
+
await runFn(signal);
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
await options?.teardown?.(signal);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function failureMessage_(error, options, signal) {
|
|
257
|
+
let failureMessage;
|
|
258
|
+
try {
|
|
259
|
+
await options?.teardown?.(signal);
|
|
260
|
+
failureMessage = formatError(error);
|
|
261
|
+
}
|
|
262
|
+
catch (tearDownError) {
|
|
263
|
+
failureMessage = formatError(new SuppressedError(tearDownError, error, "teardown failed after case failure"));
|
|
264
|
+
}
|
|
265
|
+
return failureMessage;
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=_run-case.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_run-case.js","sourceRoot":"","sources":["../src/_run-case.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CentralEstimator, RelativeErrorTarget, SamplingBounds } from "@ac-bench/core/runner";
|
|
2
|
+
/**
|
|
3
|
+
* Every sampling knob, fully populated.
|
|
4
|
+
*
|
|
5
|
+
* Frozen because it is the only place a default is applied: nothing downstream
|
|
6
|
+
* may write `?? someDefault`, which is what makes a cross-wired option (reading
|
|
7
|
+
* `minRuns` from `minTimeMs`, say) a single-file defect rather than a class of
|
|
8
|
+
* them.
|
|
9
|
+
*/
|
|
10
|
+
export type DurationSampling = SamplingBounds & {
|
|
11
|
+
/**
|
|
12
|
+
* Warmup iterations run before any measured samples, letting the JIT
|
|
13
|
+
* specialise and caches warm.
|
|
14
|
+
*
|
|
15
|
+
* Defaults to 3.
|
|
16
|
+
*/
|
|
17
|
+
warmup: number;
|
|
18
|
+
/**
|
|
19
|
+
* How tight the confidence interval must be, relative to the estimate, before
|
|
20
|
+
* sampling stops.
|
|
21
|
+
*
|
|
22
|
+
* `"auto"` (the default) derives a target from the spread observed on this
|
|
23
|
+
* machine for this case, so a noisy runner and a quiet workstation each get
|
|
24
|
+
* an appropriate one. `"off"` reproduces the fixed-bound loop exactly, which
|
|
25
|
+
* is what a differential or regression run wants.
|
|
26
|
+
*/
|
|
27
|
+
relativeError: RelativeErrorTarget;
|
|
28
|
+
/** Confidence level for the reported interval. Defaults to 0.95. */
|
|
29
|
+
confidenceLevel: number;
|
|
30
|
+
/**
|
|
31
|
+
* Defaults to `"median"`, whose uncertainty is the distribution-free
|
|
32
|
+
* order-statistic interval — the right choice for a distribution whose right
|
|
33
|
+
* tail is made of GC pauses and scheduler preemptions.
|
|
34
|
+
*/
|
|
35
|
+
estimator: CentralEstimator;
|
|
36
|
+
/** Modified Z-score above which a sample is flagged. Defaults to 3.5. */
|
|
37
|
+
outlierThreshold: number;
|
|
38
|
+
/**
|
|
39
|
+
* Whether to subtract the harness overhead from each sample. Defaults to
|
|
40
|
+
* `false`.
|
|
41
|
+
*/
|
|
42
|
+
subtractHarnessOverhead: boolean;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* With an error target driving the loop, `maxRuns` is a safety net rather than
|
|
46
|
+
* the primary control, and a `minTimeMs` that dominates the controller would
|
|
47
|
+
* make the controller pointless.
|
|
48
|
+
*/
|
|
49
|
+
export declare const DURATION_SAMPLING_DEFAULTS: {
|
|
50
|
+
readonly warmup: 3;
|
|
51
|
+
readonly minRuns: 10;
|
|
52
|
+
readonly maxRuns: 100000;
|
|
53
|
+
readonly minTimeMs: 250;
|
|
54
|
+
readonly maxTimeMs: 10000;
|
|
55
|
+
readonly relativeError: "auto";
|
|
56
|
+
readonly confidenceLevel: 0.95;
|
|
57
|
+
readonly estimator: "median";
|
|
58
|
+
readonly outlierThreshold: 3.5;
|
|
59
|
+
readonly subtractHarnessOverhead: false;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=_sampling-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_sampling-options.d.ts","sourceRoot":"","sources":["../src/_sampling-options.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,MAAM,uBAAuB,CAAC;AAG/B;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG;IAC/C;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;;OAQG;IACH,aAAa,EAAE,mBAAmB,CAAC;IAEnC,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,SAAS,EAAE,gBAAgB,CAAC;IAE5B,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,uBAAuB,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;qBAC9B,CAAC;sBACA,EAAE;sBACF,MAAO;wBACL,GAAG;wBACH,KAAM;4BACF,MAAM;8BACJ,IAAI;wBACV,QAAQ;;;CAGiB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DEFAULT_OUTLIER_THRESHOLD } from "@ac-kit/math-stats";
|
|
2
|
+
/**
|
|
3
|
+
* With an error target driving the loop, `maxRuns` is a safety net rather than
|
|
4
|
+
* the primary control, and a `minTimeMs` that dominates the controller would
|
|
5
|
+
* make the controller pointless.
|
|
6
|
+
*/
|
|
7
|
+
export const DURATION_SAMPLING_DEFAULTS = {
|
|
8
|
+
warmup: 3,
|
|
9
|
+
minRuns: 10,
|
|
10
|
+
maxRuns: 100000,
|
|
11
|
+
minTimeMs: 250,
|
|
12
|
+
maxTimeMs: 10000,
|
|
13
|
+
relativeError: "auto",
|
|
14
|
+
confidenceLevel: 0.95,
|
|
15
|
+
estimator: "median",
|
|
16
|
+
outlierThreshold: DEFAULT_OUTLIER_THRESHOLD,
|
|
17
|
+
subtractHarnessOverhead: false,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=_sampling-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_sampling-options.js","sourceRoot":"","sources":["../src/_sampling-options.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAkD/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,MAAO;IAChB,SAAS,EAAE,GAAG;IACd,SAAS,EAAE,KAAM;IACjB,aAAa,EAAE,MAAM;IACrB,eAAe,EAAE,IAAI;IACrB,SAAS,EAAE,QAAQ;IACnB,gBAAgB,EAAE,yBAAyB;IAC3C,uBAAuB,EAAE,KAAK;CACM,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
export declare const durationStopReasonSchema: z.ZodMiniEnum<{
|
|
3
|
+
cancelled: "cancelled";
|
|
4
|
+
failure: "failure";
|
|
5
|
+
"max-runs": "max-runs";
|
|
6
|
+
"max-time": "max-time";
|
|
7
|
+
"min-time": "min-time";
|
|
8
|
+
mixed: "mixed";
|
|
9
|
+
"policy-satisfied": "policy-satisfied";
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* What the sampler did, and how well it did it.
|
|
13
|
+
*
|
|
14
|
+
* Three clocks rather than two, because round-robin interleaving makes wall
|
|
15
|
+
* time and this-case time different numbers — and because `measuredMs /
|
|
16
|
+
* activeMs` is a directly observable contamination ratio.
|
|
17
|
+
*/
|
|
18
|
+
export declare const durationSamplingReportSchema: z.ZodMiniObject<{
|
|
19
|
+
requestedRelativeError: z.ZodMiniUnion<readonly [z.ZodMiniNumber<number>, z.ZodMiniLiteral<"auto">, z.ZodMiniLiteral<"off">]>;
|
|
20
|
+
effectiveRelativeErrorTarget: z.ZodMiniNullable<z.ZodMiniNumber<number>>;
|
|
21
|
+
achievedRelativeError: z.ZodMiniNullable<z.ZodMiniNumber<number>>;
|
|
22
|
+
targetReached: z.ZodMiniBoolean<boolean>;
|
|
23
|
+
confidenceLevel: z.ZodMiniNumber<number>;
|
|
24
|
+
estimator: z.ZodMiniEnum<{
|
|
25
|
+
mean: "mean";
|
|
26
|
+
median: "median";
|
|
27
|
+
}>;
|
|
28
|
+
stopReason: z.ZodMiniEnum<{
|
|
29
|
+
cancelled: "cancelled";
|
|
30
|
+
failure: "failure";
|
|
31
|
+
"max-runs": "max-runs";
|
|
32
|
+
"max-time": "max-time";
|
|
33
|
+
"min-time": "min-time";
|
|
34
|
+
mixed: "mixed";
|
|
35
|
+
"policy-satisfied": "policy-satisfied";
|
|
36
|
+
}>;
|
|
37
|
+
measuredMs: z.ZodMiniNumber<number>;
|
|
38
|
+
activeMs: z.ZodMiniNumber<number>;
|
|
39
|
+
elapsedMs: z.ZodMiniNumber<number>;
|
|
40
|
+
samples: z.ZodMiniNumber<number>;
|
|
41
|
+
batches: z.ZodMiniNumber<number>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
export type DurationSamplingReport = z.infer<typeof durationSamplingReportSchema>;
|
|
44
|
+
//# sourceMappingURL=_sampling-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_sampling-report.d.ts","sourceRoot":"","sources":["../src/_sampling-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,eAAO,MAAM,wBAAwB;;;;;;;;EASnC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;iBAyBvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,4BAA4B,CACnC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
export const durationStopReasonSchema = z.enum([
|
|
3
|
+
"policy-satisfied",
|
|
4
|
+
"min-time",
|
|
5
|
+
"max-time",
|
|
6
|
+
"max-runs",
|
|
7
|
+
"cancelled",
|
|
8
|
+
"failure",
|
|
9
|
+
/** Pooled from executions that did not agree on why they stopped. */
|
|
10
|
+
"mixed",
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* What the sampler did, and how well it did it.
|
|
14
|
+
*
|
|
15
|
+
* Three clocks rather than two, because round-robin interleaving makes wall
|
|
16
|
+
* time and this-case time different numbers — and because `measuredMs /
|
|
17
|
+
* activeMs` is a directly observable contamination ratio.
|
|
18
|
+
*/
|
|
19
|
+
export const durationSamplingReportSchema = z.object({
|
|
20
|
+
requestedRelativeError: z.union([
|
|
21
|
+
z.number(),
|
|
22
|
+
z.literal("auto"),
|
|
23
|
+
z.literal("off"),
|
|
24
|
+
]),
|
|
25
|
+
effectiveRelativeErrorTarget: z.nullable(z.number()),
|
|
26
|
+
achievedRelativeError: z.nullable(z.number()),
|
|
27
|
+
targetReached: z.boolean(),
|
|
28
|
+
confidenceLevel: z.number(),
|
|
29
|
+
estimator: z.enum(["mean", "median"]),
|
|
30
|
+
stopReason: durationStopReasonSchema,
|
|
31
|
+
/** Sum of the per-iteration timed spans. What the statistics describe. */
|
|
32
|
+
measuredMs: z.number(),
|
|
33
|
+
/**
|
|
34
|
+
* Wall time attributable to this case, hooks and recomputation included. The
|
|
35
|
+
* time bounds apply here, never to `elapsedMs`.
|
|
36
|
+
*/
|
|
37
|
+
activeMs: z.number(),
|
|
38
|
+
/** First slice to last. Under interleaving it includes other cases' work. */
|
|
39
|
+
elapsedMs: z.number(),
|
|
40
|
+
samples: z.number(),
|
|
41
|
+
batches: z.number(),
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=_sampling-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_sampling-report.js","sourceRoot":"","sources":["../src/_sampling-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9C,kBAAkB;IAClB,UAAU;IACV,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;IACT,qEAAqE;IACrE,OAAO;CACP,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACpD,sBAAsB,EAAE,CAAC,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,MAAM,EAAE;QACV,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACjB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;KAChB,CAAC;IACF,4BAA4B,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpD,qBAAqB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7C,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrC,UAAU,EAAE,wBAAwB;IAEpC,0EAA0E;IAC1E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB;;;OAGG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,6EAA6E;IAC7E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IAErB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
/** Share of a case's median above which the baseline is most of the number. */
|
|
3
|
+
export declare const SPAWN_BASELINE_DOMINATES = 0.75;
|
|
4
|
+
/**
|
|
5
|
+
* What starting the program costs when it is asked to do nothing.
|
|
6
|
+
*
|
|
7
|
+
* A benchmark whose iteration is a whole process pays this on every sample
|
|
8
|
+
* while an in-process contender pays none of it. It is reported next to the
|
|
9
|
+
* result rather than folded into it, so a comparison can never quietly be
|
|
10
|
+
* between one number that had start-up removed and one that did not.
|
|
11
|
+
*/
|
|
12
|
+
export declare const spawnBaselineReportSchema: z.ZodMiniObject<{
|
|
13
|
+
command: z.ZodMiniString<string>;
|
|
14
|
+
statistics: z.ZodMiniObject<{
|
|
15
|
+
samples: z.ZodMiniNumber<number>;
|
|
16
|
+
meanMs: z.ZodMiniNumber<number>;
|
|
17
|
+
stdDevMs: z.ZodMiniNumber<number>;
|
|
18
|
+
confidence95Ms: z.ZodMiniNumber<number>;
|
|
19
|
+
medianMs: z.ZodMiniNumber<number>;
|
|
20
|
+
medianConfidence95Ms: z.ZodMiniNumber<number>;
|
|
21
|
+
madMs: z.ZodMiniNumber<number>;
|
|
22
|
+
minMs: z.ZodMiniNumber<number>;
|
|
23
|
+
maxMs: z.ZodMiniNumber<number>;
|
|
24
|
+
p95Ms: z.ZodMiniNumber<number>;
|
|
25
|
+
p99Ms: z.ZodMiniNumber<number>;
|
|
26
|
+
relativeStdDev: z.ZodMiniNumber<number>;
|
|
27
|
+
relativeMad: z.ZodMiniNumber<number>;
|
|
28
|
+
outlierIndices: z.ZodMiniArray<z.ZodMiniNumber<number>>;
|
|
29
|
+
opsPerSecond: z.ZodMiniNullable<z.ZodMiniNumber<number>>;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
share: z.ZodMiniNumber<number>;
|
|
32
|
+
subtracted: z.ZodMiniBoolean<boolean>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export type SpawnBaselineReport = z.infer<typeof spawnBaselineReportSchema>;
|
|
35
|
+
//# sourceMappingURL=_spawn-baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_spawn-baseline.d.ts","sourceRoot":"","sources":["../src/_spawn-baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAI9B,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;iBAQpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
import { durationStatisticsSchema } from "./_statistics-schema.js";
|
|
3
|
+
/** Share of a case's median above which the baseline is most of the number. */
|
|
4
|
+
export const SPAWN_BASELINE_DOMINATES = 0.75;
|
|
5
|
+
/**
|
|
6
|
+
* What starting the program costs when it is asked to do nothing.
|
|
7
|
+
*
|
|
8
|
+
* A benchmark whose iteration is a whole process pays this on every sample
|
|
9
|
+
* while an in-process contender pays none of it. It is reported next to the
|
|
10
|
+
* result rather than folded into it, so a comparison can never quietly be
|
|
11
|
+
* between one number that had start-up removed and one that did not.
|
|
12
|
+
*/
|
|
13
|
+
export const spawnBaselineReportSchema = z.object({
|
|
14
|
+
/** Program measured, as invoked. */
|
|
15
|
+
command: z.string(),
|
|
16
|
+
statistics: durationStatisticsSchema,
|
|
17
|
+
/** Baseline median as a fraction of the case median. */
|
|
18
|
+
share: z.number(),
|
|
19
|
+
/** Whether it was removed from the samples behind `adjusted`. */
|
|
20
|
+
subtracted: z.boolean(),
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=_spawn-baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_spawn-baseline.js","sourceRoot":"","sources":["../src/_spawn-baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,oCAAoC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,UAAU,EAAE,wBAAwB;IACpC,wDAAwD;IACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,iEAAiE;IACjE,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;CACvB,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
/**
|
|
3
|
+
* Descriptive statistics for a set of timing samples.
|
|
4
|
+
*
|
|
5
|
+
* Both a mean with dispersion and a median with percentiles are reported. The
|
|
6
|
+
* mean is what most tools show and is comparable across runs; the median and
|
|
7
|
+
* MAD are robust to the long right tail that dominates benchmarks involving
|
|
8
|
+
* I/O, garbage collection or process scheduling.
|
|
9
|
+
*/
|
|
10
|
+
export declare const durationStatisticsSchema: z.ZodMiniObject<{
|
|
11
|
+
samples: z.ZodMiniNumber<number>;
|
|
12
|
+
meanMs: z.ZodMiniNumber<number>;
|
|
13
|
+
stdDevMs: z.ZodMiniNumber<number>;
|
|
14
|
+
confidence95Ms: z.ZodMiniNumber<number>;
|
|
15
|
+
medianMs: z.ZodMiniNumber<number>;
|
|
16
|
+
medianConfidence95Ms: z.ZodMiniNumber<number>;
|
|
17
|
+
madMs: z.ZodMiniNumber<number>;
|
|
18
|
+
minMs: z.ZodMiniNumber<number>;
|
|
19
|
+
maxMs: z.ZodMiniNumber<number>;
|
|
20
|
+
p95Ms: z.ZodMiniNumber<number>;
|
|
21
|
+
p99Ms: z.ZodMiniNumber<number>;
|
|
22
|
+
relativeStdDev: z.ZodMiniNumber<number>;
|
|
23
|
+
relativeMad: z.ZodMiniNumber<number>;
|
|
24
|
+
outlierIndices: z.ZodMiniArray<z.ZodMiniNumber<number>>;
|
|
25
|
+
opsPerSecond: z.ZodMiniNullable<z.ZodMiniNumber<number>>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type DurationStatistics = z.infer<typeof durationStatisticsSchema>;
|
|
28
|
+
//# sourceMappingURL=_statistics-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_statistics-schema.d.ts","sourceRoot":"","sources":["../src/_statistics-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;iBAgDnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as z from "zod/mini";
|
|
2
|
+
/**
|
|
3
|
+
* Descriptive statistics for a set of timing samples.
|
|
4
|
+
*
|
|
5
|
+
* Both a mean with dispersion and a median with percentiles are reported. The
|
|
6
|
+
* mean is what most tools show and is comparable across runs; the median and
|
|
7
|
+
* MAD are robust to the long right tail that dominates benchmarks involving
|
|
8
|
+
* I/O, garbage collection or process scheduling.
|
|
9
|
+
*/
|
|
10
|
+
export const durationStatisticsSchema = z.object({
|
|
11
|
+
/** Number of measured samples. */
|
|
12
|
+
samples: z.number(),
|
|
13
|
+
/** Arithmetic mean, in milliseconds. */
|
|
14
|
+
meanMs: z.number(),
|
|
15
|
+
/** Sample standard deviation (Bessel-corrected), in milliseconds. */
|
|
16
|
+
stdDevMs: z.number(),
|
|
17
|
+
/** Half-width of the 95% confidence interval of the mean. */
|
|
18
|
+
confidence95Ms: z.number(),
|
|
19
|
+
/** Median, in milliseconds. */
|
|
20
|
+
medianMs: z.number(),
|
|
21
|
+
/**
|
|
22
|
+
* Half-width of the 95% confidence interval of the median.
|
|
23
|
+
*
|
|
24
|
+
* Distribution-free, from the order statistics, so it does not assume the
|
|
25
|
+
* heavy right tail away the way the mean's normal approximation does. The
|
|
26
|
+
* underlying interval can be asymmetric about the median; this is half its
|
|
27
|
+
* total width, which is what combining executions needs.
|
|
28
|
+
*/
|
|
29
|
+
medianConfidence95Ms: z.number(),
|
|
30
|
+
/**
|
|
31
|
+
* Median absolute deviation, in milliseconds. A dispersion measure that a
|
|
32
|
+
* handful of extreme samples cannot inflate.
|
|
33
|
+
*/
|
|
34
|
+
madMs: z.number(),
|
|
35
|
+
/** Minimum sample, in milliseconds. */
|
|
36
|
+
minMs: z.number(),
|
|
37
|
+
/** Maximum sample, in milliseconds. */
|
|
38
|
+
maxMs: z.number(),
|
|
39
|
+
/** 95th percentile, in milliseconds. */
|
|
40
|
+
p95Ms: z.number(),
|
|
41
|
+
/** 99th percentile, in milliseconds. */
|
|
42
|
+
p99Ms: z.number(),
|
|
43
|
+
/** Standard deviation as a fraction of the mean. */
|
|
44
|
+
relativeStdDev: z.number(),
|
|
45
|
+
/**
|
|
46
|
+
* Median absolute deviation as a fraction of the median.
|
|
47
|
+
*
|
|
48
|
+
* The robust counterpart of {@link DurationStatistics.relativeStdDev}. Garbage
|
|
49
|
+
* collection and scheduler preemption give benchmark timings a heavy right
|
|
50
|
+
* tail, which inflates the standard deviation without saying anything about
|
|
51
|
+
* the typical case.
|
|
52
|
+
*/
|
|
53
|
+
relativeMad: z.number(),
|
|
54
|
+
/** Indices of samples flagged by `findOutliers`. */
|
|
55
|
+
outlierIndices: z.array(z.number()),
|
|
56
|
+
/** Operations per second, derived from the mean. */
|
|
57
|
+
opsPerSecond: z.nullable(z.number()),
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=_statistics-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_statistics-schema.js","sourceRoot":"","sources":["../src/_statistics-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,kCAAkC;IAClC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,wCAAwC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,qEAAqE;IACrE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,6DAA6D;IAC7D,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,+BAA+B;IAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB;;;;;;;OAOG;IACH,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE;IAChC;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,uCAAuC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,uCAAuC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,wCAAwC;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,wCAAwC;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,oDAAoD;IACpD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B;;;;;;;OAOG;IACH,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,oDAAoD;IACpD,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,oDAAoD;IACpD,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACpC,CAAC,CAAC"}
|