fidelity-kit 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +28 -3
  2. package/dist/commands/build.d.ts +2 -0
  3. package/dist/commands/build.d.ts.map +1 -1
  4. package/dist/commands/build.js +2 -1
  5. package/dist/commands/build.js.map +1 -1
  6. package/dist/commands/dev.d.ts +7 -1
  7. package/dist/commands/dev.d.ts.map +1 -1
  8. package/dist/commands/dev.js +9 -2
  9. package/dist/commands/dev.js.map +1 -1
  10. package/dist/commands/hash.d.ts +2 -0
  11. package/dist/commands/hash.d.ts.map +1 -1
  12. package/dist/commands/hash.js +7 -3
  13. package/dist/commands/hash.js.map +1 -1
  14. package/dist/commands/process.d.ts +6 -0
  15. package/dist/commands/process.d.ts.map +1 -1
  16. package/dist/commands/process.js +35 -7
  17. package/dist/commands/process.js.map +1 -1
  18. package/dist/commands/serve.d.ts +3 -1
  19. package/dist/commands/serve.d.ts.map +1 -1
  20. package/dist/commands/serve.js +2 -1
  21. package/dist/commands/serve.js.map +1 -1
  22. package/dist/core/compare.d.ts +9 -2
  23. package/dist/core/compare.d.ts.map +1 -1
  24. package/dist/core/compare.js +9 -5
  25. package/dist/core/compare.js.map +1 -1
  26. package/dist/core/hash.d.ts +3 -1
  27. package/dist/core/hash.d.ts.map +1 -1
  28. package/dist/core/hash.js +39 -12
  29. package/dist/core/hash.js.map +1 -1
  30. package/dist/core/hash.test.js +24 -1
  31. package/dist/core/hash.test.js.map +1 -1
  32. package/dist/core/paths.d.ts +5 -2
  33. package/dist/core/paths.d.ts.map +1 -1
  34. package/dist/core/paths.js +6 -3
  35. package/dist/core/paths.js.map +1 -1
  36. package/dist/core/process.d.ts +54 -3
  37. package/dist/core/process.d.ts.map +1 -1
  38. package/dist/core/process.js +485 -55
  39. package/dist/core/process.js.map +1 -1
  40. package/dist/core/process.test.d.ts +2 -0
  41. package/dist/core/process.test.d.ts.map +1 -0
  42. package/dist/core/process.test.js +405 -0
  43. package/dist/core/process.test.js.map +1 -0
  44. package/dist/core/progress.d.ts +8 -0
  45. package/dist/core/progress.d.ts.map +1 -0
  46. package/dist/core/progress.js +2 -0
  47. package/dist/core/progress.js.map +1 -0
  48. package/dist/core/scan.d.ts +11 -2
  49. package/dist/core/scan.d.ts.map +1 -1
  50. package/dist/core/scan.js +104 -18
  51. package/dist/core/scan.js.map +1 -1
  52. package/dist/core/suite.test.js +24 -1
  53. package/dist/core/suite.test.js.map +1 -1
  54. package/dist/progress.d.ts +12 -0
  55. package/dist/progress.d.ts.map +1 -0
  56. package/dist/progress.js +46 -0
  57. package/dist/progress.js.map +1 -0
  58. package/dist/progress.test.d.ts +2 -0
  59. package/dist/progress.test.d.ts.map +1 -0
  60. package/dist/progress.test.js +36 -0
  61. package/dist/progress.test.js.map +1 -0
  62. package/dist/run.d.ts +4 -1
  63. package/dist/run.d.ts.map +1 -1
  64. package/dist/run.js +32 -6
  65. package/dist/run.js.map +1 -1
  66. package/dist/server.d.ts +1 -1
  67. package/dist/server.d.ts.map +1 -1
  68. package/dist/server.js +23 -5
  69. package/dist/server.js.map +1 -1
  70. package/dist/server.test.js +73 -1
  71. package/dist/server.test.js.map +1 -1
  72. package/dist/watch.d.ts +9 -0
  73. package/dist/watch.d.ts.map +1 -0
  74. package/dist/watch.js +96 -0
  75. package/dist/watch.js.map +1 -0
  76. package/dist/watch.test.d.ts +2 -0
  77. package/dist/watch.test.d.ts.map +1 -0
  78. package/dist/watch.test.js +171 -0
  79. package/dist/watch.test.js.map +1 -0
  80. package/package.json +2 -1
  81. package/viewer/assets/{ViewControls-Ck9smy3A.js → ViewControls-CTETl5oY.js} +1 -1
  82. package/viewer/assets/{_-Bn1LyOgm.js → _-U-2B0GSx.js} +1 -1
  83. package/viewer/assets/{index-BZCd8VsK.js → index-G0mSU6zI.js} +2 -2
  84. package/viewer/assets/{routes-sEPFkb5w.js → routes-DX90MTkh.js} +1 -1
  85. package/viewer/index.html +1 -1
@@ -0,0 +1,405 @@
1
+ import { mkdtemp, mkdir, readFile, rm, stat, utimes, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import sharp from 'sharp';
5
+ import { afterEach, expect, test, vi } from 'vitest';
6
+ import * as comparison from './compare.js';
7
+ import * as scanning from './scan.js';
8
+ import { processSuite, SuiteProcessor } from './process.js';
9
+ const roots = [];
10
+ afterEach(async () => {
11
+ vi.restoreAllMocks();
12
+ await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
13
+ });
14
+ const image = (v) => sharp({ create: { width: 8, height: 8, channels: 3, background: { r: v, g: v, b: v } } })
15
+ .avif({ lossless: true })
16
+ .toBuffer();
17
+ const index = async (root) => JSON.parse(await readFile(join(root, 'index.json'), 'utf8'));
18
+ async function addScene(root, scene, value = 100) {
19
+ const dir = join(root, scene, 'beauty');
20
+ await mkdir(dir, { recursive: true });
21
+ for (const renderer of ['ref', 'a', 'b'])
22
+ await writeFile(join(dir, `${renderer}.avif`), await image(value));
23
+ return dir;
24
+ }
25
+ async function fixture() {
26
+ const root = await mkdtemp(join(tmpdir(), 'fk-process-'));
27
+ roots.push(root);
28
+ await writeFile(join(root, 'fidelity.json'), JSON.stringify({ title: 'T', renderers: [{ id: 'ref', reference: true }, { id: 'a' }, { id: 'b' }] }));
29
+ return { root, dir: await addScene(root, 'one') };
30
+ }
31
+ const aKey = 'one/beauty/a.vs-ref.metrics.json';
32
+ test('persisted signatures detect older timestamps and size-only changes, and reuse future timestamps', async () => {
33
+ const { root, dir } = await fixture();
34
+ const file = join(dir, 'a.avif');
35
+ const future = new Date('2040-01-01');
36
+ await utimes(file, future, future);
37
+ expect(await processSuite(root)).toMatchObject({ computed: 2 });
38
+ expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
39
+ await writeFile(file, await image(160));
40
+ const old = new Date('2000-01-01');
41
+ await utimes(file, old, old);
42
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
43
+ expect((await index(root)).metrics[aKey].maxError).toBeGreaterThan(0);
44
+ await writeFile(file, Buffer.concat([await readFile(file), Buffer.from('padding')]));
45
+ await utimes(file, old, old);
46
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
47
+ });
48
+ test('missing outputs, malformed metrics, and old cache formats are recomputed', async () => {
49
+ const { root, dir } = await fixture();
50
+ await processSuite(root);
51
+ await rm(join(dir, 'a.vs-ref.delta.webp'));
52
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
53
+ const metrics = join(root, aKey);
54
+ const saved = JSON.parse(await readFile(metrics, 'utf8'));
55
+ await writeFile(metrics, JSON.stringify({ ...saved, width: -1 }));
56
+ expect(await processSuite(root)).toMatchObject({ computed: 1 });
57
+ const { source: _source, ...legacy } = saved;
58
+ await writeFile(metrics, JSON.stringify(legacy));
59
+ expect(await processSuite(root)).toMatchObject({ computed: 1 });
60
+ });
61
+ test('coalesces shared input changes and updates metadata without comparing images', async () => {
62
+ const { root, dir } = await fixture();
63
+ const processor = await SuiteProcessor.create(root);
64
+ await processor.initialize();
65
+ const compare = vi.spyOn(comparison, 'compareImages');
66
+ await writeFile(join(dir, 'ref.avif'), await image(140));
67
+ await writeFile(join(dir, 'a.avif'), await image(120));
68
+ processor.notify(['one/beauty/ref.avif', 'one/beauty/a.avif', 'one/beauty/ref.avif']);
69
+ expect(await processor.flush()).toMatchObject({ computed: 2, failed: [] });
70
+ expect(compare).toHaveBeenCalledTimes(2);
71
+ compare.mockClear();
72
+ await writeFile(join(root, 'one/scene.json'), JSON.stringify({ title: 'Renamed' }));
73
+ processor.notify(['one/scene.json']);
74
+ expect(await processor.flush()).toMatchObject({ computed: 0, skipped: 0 });
75
+ expect(compare).not.toHaveBeenCalled();
76
+ expect((await index(root)).root.scenes[0].title).toBe('Renamed');
77
+ });
78
+ test('adds and removes scenes and images while retaining explicit empty scenes', async () => {
79
+ const { root, dir } = await fixture();
80
+ const processor = await SuiteProcessor.create(root);
81
+ await processor.initialize();
82
+ await addScene(root, 'group/two');
83
+ processor.notify(['group/two/beauty/a.avif']);
84
+ expect(await processor.flush()).toMatchObject({ computed: 2 });
85
+ await rm(join(dir, 'ref.avif'));
86
+ processor.notify(['one/beauty/ref.avif']);
87
+ await processor.flush();
88
+ expect(Object.keys((await index(root)).metrics)).not.toContain(aKey);
89
+ await writeFile(join(dir, 'ref.avif'), await image(130));
90
+ processor.notify(['one/beauty/ref.avif']);
91
+ expect(await processor.flush()).toMatchObject({ computed: 2 });
92
+ await writeFile(join(root, 'one/scene.json'), '{}');
93
+ await rm(dir, { recursive: true });
94
+ processor.notify(['one/beauty/ref.avif', 'one/beauty/a.avif', 'one/beauty/b.avif', 'one/scene.json']);
95
+ await processor.flush();
96
+ expect((await index(root)).root.scenes[0].images).toEqual({});
97
+ await rm(join(root, 'group'), { recursive: true });
98
+ processor.removeDirectory('group');
99
+ await processor.flush();
100
+ expect((await index(root)).root.groups).toEqual([]);
101
+ expect((await index(root)).metrics).toEqual({});
102
+ await rm(join(root, 'one/scene.json'));
103
+ processor.notify(['one/scene.json']);
104
+ await processor.flush();
105
+ expect((await index(root)).root.scenes).toEqual([]);
106
+ });
107
+ test('discards in-flight results and waits for a settled batch before recomputing', async () => {
108
+ const { root, dir } = await fixture();
109
+ const processor = await SuiteProcessor.create(root, { concurrency: 1 });
110
+ await processor.initialize();
111
+ const started = Promise.withResolvers();
112
+ const release = Promise.withResolvers();
113
+ const original = comparison.compareImages;
114
+ const compare = vi.spyOn(comparison, 'compareImages').mockImplementationOnce(async (...args) => {
115
+ const result = await original(...args);
116
+ started.resolve();
117
+ await release.promise;
118
+ return result;
119
+ });
120
+ await writeFile(join(dir, 'a.avif'), await image(120));
121
+ processor.notify(['one/beauty/a.avif']);
122
+ const running = processor.flush();
123
+ await started.promise;
124
+ await writeFile(join(dir, 'a.avif'), await image(180));
125
+ processor.notify(['one/beauty/a.avif'], true);
126
+ release.resolve();
127
+ expect(await running).toMatchObject({ computed: 0 });
128
+ expect((await index(root)).metrics[aKey]).toBeUndefined();
129
+ expect(compare).toHaveBeenCalledTimes(1);
130
+ processor.settle();
131
+ expect(await processor.flush()).toMatchObject({ computed: 1 });
132
+ expect(compare).toHaveBeenCalledTimes(2);
133
+ expect((await index(root)).metrics[aKey].maxError).toBeGreaterThan(0.25);
134
+ });
135
+ test('deleting and recreating a scene cannot publish its previous running comparison', async () => {
136
+ const { root, dir } = await fixture();
137
+ const processor = await SuiteProcessor.create(root, { concurrency: 1 });
138
+ await processor.initialize();
139
+ const started = Promise.withResolvers();
140
+ const release = Promise.withResolvers();
141
+ const original = comparison.compareImages;
142
+ vi.spyOn(comparison, 'compareImages').mockImplementationOnce(async (...args) => {
143
+ const result = await original(...args);
144
+ started.resolve();
145
+ await release.promise;
146
+ return result;
147
+ });
148
+ await writeFile(join(dir, 'a.avif'), await image(130));
149
+ processor.notify(['one/beauty/a.avif']);
150
+ const running = processor.flush();
151
+ await started.promise;
152
+ await rm(join(root, 'one'), { recursive: true });
153
+ processor.removeDirectory('one');
154
+ release.resolve();
155
+ expect(await running).toMatchObject({ computed: 0, failed: [] });
156
+ expect((await index(root)).metrics).toEqual({});
157
+ await addScene(root, 'one', 170);
158
+ processor.notify(['one/beauty/a.avif']);
159
+ expect(await processor.flush()).toMatchObject({ computed: 2 });
160
+ expect((await index(root)).metrics[aKey].maxError).toBe(0);
161
+ });
162
+ test('streams discovery into a globally bounded queue', async () => {
163
+ const { root } = await fixture();
164
+ await addScene(root, 'two');
165
+ const started = Promise.withResolvers();
166
+ const discovered = Promise.withResolvers();
167
+ const originalCompare = comparison.compareImages;
168
+ let active = 0;
169
+ let maximum = 0;
170
+ vi.spyOn(comparison, 'compareImages').mockImplementation(async (...args) => {
171
+ active++;
172
+ maximum = Math.max(maximum, active);
173
+ if (active === 2)
174
+ started.resolve();
175
+ await discovered.promise;
176
+ try {
177
+ return await originalCompare(...args);
178
+ }
179
+ finally {
180
+ active--;
181
+ }
182
+ });
183
+ const originalScan = scanning.scanSuite;
184
+ vi.spyOn(scanning, 'scanSuite').mockImplementation((path, options) => originalScan(path, {
185
+ ...options,
186
+ onScene: async (scene) => {
187
+ if (scene.path === 'two') {
188
+ await started.promise;
189
+ discovered.resolve();
190
+ }
191
+ await options?.onScene?.(scene);
192
+ },
193
+ }));
194
+ expect(await processSuite(root, { concurrency: 2 })).toMatchObject({ computed: 4, failed: [] });
195
+ expect(maximum).toBe(2);
196
+ });
197
+ test('ignores all generated outputs and keeps renderer/pass configuration fixed', async () => {
198
+ const { root } = await fixture();
199
+ const processor = await SuiteProcessor.create(root);
200
+ await processor.initialize();
201
+ const before = (await stat(join(root, 'index.json'))).mtimeMs;
202
+ processor.notify([
203
+ 'index.json',
204
+ aKey,
205
+ 'one/beauty/a.vs-ref.delta.webp',
206
+ 'one/beauty/a.avif.uuid.tmp',
207
+ 'fidelity.json',
208
+ 'one/new-pass/a.avif',
209
+ 'one/beauty/new-renderer.avif',
210
+ ]);
211
+ expect(await processor.flush()).toEqual({ computed: 0, skipped: 0, failed: [] });
212
+ expect((await stat(join(root, 'index.json'))).mtimeMs).toBe(before);
213
+ });
214
+ test('failed pairs do not spin and retry after a new input revision', async () => {
215
+ const { root, dir } = await fixture();
216
+ const processor = await SuiteProcessor.create(root);
217
+ await processor.initialize();
218
+ await writeFile(join(dir, 'a.avif'), 'partial');
219
+ processor.notify(['one/beauty/a.avif']);
220
+ expect((await processor.flush()).failed).toHaveLength(1);
221
+ processor.notify(['one/beauty/a.avif']);
222
+ expect(await processor.flush()).toEqual({ computed: 0, skipped: 0, failed: [] });
223
+ await writeFile(join(dir, 'a.avif'), await image(150));
224
+ processor.notify(['one/beauty/a.avif']);
225
+ expect(await processor.flush()).toMatchObject({ computed: 1, failed: [] });
226
+ });
227
+ test('multiple references invalidate both incoming and outgoing comparisons', async () => {
228
+ const { root, dir } = await fixture();
229
+ const config = JSON.parse(await readFile(join(root, 'fidelity.json'), 'utf8'));
230
+ config.renderers[2].reference = true;
231
+ await writeFile(join(root, 'fidelity.json'), JSON.stringify(config));
232
+ const processor = await SuiteProcessor.create(root);
233
+ expect(await processor.initialize()).toMatchObject({ computed: 4 });
234
+ await writeFile(join(dir, 'b.avif'), await image(140));
235
+ processor.notify(['one/beauty/b.avif']);
236
+ expect(await processor.flush()).toMatchObject({ computed: 3 });
237
+ });
238
+ test('metrics-only processing avoids delta encoding and reuses its results', async () => {
239
+ const { root } = await fixture();
240
+ const config = JSON.parse(await readFile(join(root, 'fidelity.json'), 'utf8'));
241
+ await writeFile(join(root, 'fidelity.json'), JSON.stringify({ ...config, delta: false }));
242
+ const compare = vi.spyOn(comparison, 'compareImages');
243
+ expect(await processSuite(root)).toMatchObject({ computed: 2 });
244
+ for (const result of compare.mock.results)
245
+ expect((await result.value).deltaImage.length).toBe(0);
246
+ expect((await index(root)).metrics[aKey].maxError).toBe(0);
247
+ await expect(stat(join(root, 'one/beauty/a.vs-ref.delta.webp'))).rejects.toMatchObject({ code: 'ENOENT' });
248
+ expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
249
+ });
250
+ test('one-shot changes remove stale index records after files disappeared before startup', async () => {
251
+ const { root, dir } = await fixture();
252
+ await processSuite(root);
253
+ await rm(dir, { recursive: true });
254
+ const { processChanges } = await import('./process.js');
255
+ expect(await processChanges(root, ['one/beauty/ref.avif'])).toMatchObject({ computed: 0, failed: [] });
256
+ expect((await index(root)).metrics).toEqual({});
257
+ expect((await index(root)).root.scenes).toEqual([]);
258
+ });
259
+ test('output-directory removal invalidates its scene even without individual unlink events', async () => {
260
+ const { root, dir } = await fixture();
261
+ const processor = await SuiteProcessor.create(root);
262
+ await processor.initialize();
263
+ await rm(dir, { recursive: true });
264
+ processor.removeDirectory('one/beauty');
265
+ await processor.flush();
266
+ expect((await index(root)).metrics).toEqual({});
267
+ expect((await index(root)).root.scenes).toEqual([]);
268
+ });
269
+ test('metrics and heatmaps have independent input-signature caches', async () => {
270
+ const { root, dir } = await fixture();
271
+ await processSuite(root);
272
+ const metrics = join(root, aKey);
273
+ const delta = join(dir, 'a.vs-ref.delta.webp');
274
+ const cache = `${delta}.json`;
275
+ const originalMetrics = await readFile(metrics, 'utf8');
276
+ const originalMetricsStat = await stat(metrics);
277
+ const compare = vi.spyOn(comparison, 'compareImages');
278
+ await rm(delta);
279
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
280
+ expect(compare).toHaveBeenLastCalledWith(expect.any(String), expect.any(String), { delta: true });
281
+ expect(await readFile(metrics, 'utf8')).toBe(originalMetrics);
282
+ expect((await stat(metrics)).mtimeMs).toBe(originalMetricsStat.mtimeMs);
283
+ expect((await sharp(delta).metadata()).format).toBe('webp');
284
+ const originalDelta = await readFile(delta);
285
+ const originalDeltaStat = await stat(delta);
286
+ const originalCache = await readFile(cache, 'utf8');
287
+ const originalCacheStat = await stat(cache);
288
+ await rm(metrics);
289
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
290
+ expect(compare).toHaveBeenLastCalledWith(expect.any(String), expect.any(String), { delta: false });
291
+ expect(await readFile(delta)).toEqual(originalDelta);
292
+ expect((await stat(delta)).mtimeMs).toBe(originalDeltaStat.mtimeMs);
293
+ expect(await readFile(cache, 'utf8')).toBe(originalCache);
294
+ expect((await stat(cache)).mtimeMs).toBe(originalCacheStat.mtimeMs);
295
+ const saved = JSON.parse(await readFile(metrics, 'utf8'));
296
+ await writeFile(metrics, JSON.stringify({ ...saved, source: { ...saved.source, renderer: { ...saved.source.renderer, size: -1 } } }));
297
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
298
+ expect(compare).toHaveBeenLastCalledWith(expect.any(String), expect.any(String), { delta: false });
299
+ expect((await stat(delta)).mtimeMs).toBe(originalDeltaStat.mtimeMs);
300
+ const currentMetrics = await readFile(metrics, 'utf8');
301
+ await writeFile(cache, '{}');
302
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
303
+ expect(await readFile(metrics, 'utf8')).toBe(currentMetrics);
304
+ expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
305
+ });
306
+ test('legacy AVIF metrics stay untouched while WebP heatmaps are generated', async () => {
307
+ const { root, dir } = await fixture();
308
+ await processSuite(root);
309
+ const file = join(root, aKey);
310
+ const saved = JSON.parse(await readFile(file, 'utf8'));
311
+ delete saved.source.reference.path;
312
+ delete saved.source.renderer.path;
313
+ saved.source.delta = true;
314
+ await writeFile(file, JSON.stringify(saved));
315
+ const originalMetrics = await readFile(file, 'utf8');
316
+ const before = (await stat(file)).mtimeMs;
317
+ await rm(join(dir, 'a.vs-ref.delta.webp'));
318
+ await rm(join(dir, 'a.vs-ref.delta.webp.json'));
319
+ await writeFile(join(dir, 'a.vs-ref.delta.avif'), await image(0));
320
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
321
+ expect(await readFile(file, 'utf8')).toBe(originalMetrics);
322
+ expect((await stat(file)).mtimeMs).toBe(before);
323
+ expect((await sharp(join(dir, 'a.vs-ref.delta.webp')).metadata()).format).toBe('webp');
324
+ expect((await index(root)).metrics[aKey].deltaFile).toBe('a.vs-ref.delta.webp');
325
+ });
326
+ const encoded = (format, value) => sharp({ create: { width: 8, height: 8, channels: 3, background: { r: value, g: value, b: value } } })
327
+ .toFormat(format)
328
+ .toBuffer();
329
+ test('selects AVIF, WebP, PNG, then JPG and reselects sources during incremental processing', async () => {
330
+ const { root, dir } = await fixture();
331
+ await rm(join(dir, 'ref.avif'));
332
+ await writeFile(join(dir, 'ref.png'), await encoded('png', 100));
333
+ for (const [extension, format, value] of [
334
+ ['avif', 'avif', 120],
335
+ ['webp', 'webp', 140],
336
+ ['png', 'png', 160],
337
+ ['jpg', 'jpeg', 180],
338
+ ])
339
+ await writeFile(join(dir, `a.${extension}`), await encoded(format, value));
340
+ const processor = await SuiteProcessor.create(root);
341
+ expect(await processor.initialize()).toMatchObject({ computed: 2, failed: [] });
342
+ for (const extension of ['avif', 'webp', 'png', 'jpg']) {
343
+ const data = await index(root);
344
+ expect(data.root.scenes[0].imageFiles.beauty).toMatchObject({ ref: 'ref.png', a: `a.${extension}` });
345
+ expect((await scanning.scanScene(root, 'one', processor.config))?.imageFiles).toEqual(data.root.scenes[0].imageFiles);
346
+ await rm(join(dir, `a.${extension}`));
347
+ processor.notify([`one/beauty/a.${extension}`]);
348
+ expect(await processor.flush()).toMatchObject({ computed: extension === 'jpg' ? 0 : 1, failed: [] });
349
+ }
350
+ expect((await index(root)).metrics[aKey]).toBeUndefined();
351
+ await writeFile(join(dir, 'a.jpg'), await encoded('jpeg', 180));
352
+ processor.notify(['one/beauty/a.jpg']);
353
+ await processor.flush();
354
+ await writeFile(join(dir, 'a.webp'), await encoded('webp', 140));
355
+ processor.notify(['one/beauty/a.webp']);
356
+ expect(await processor.flush()).toMatchObject({ computed: 1, failed: [] });
357
+ expect((await index(root)).root.scenes[0].imageFiles.beauty.a).toBe('a.webp');
358
+ const compare = vi.spyOn(comparison, 'compareImages');
359
+ await writeFile(join(dir, 'a.png'), await encoded('png', 160));
360
+ processor.notify(['one/beauty/a.png']);
361
+ expect(await processor.flush()).toMatchObject({ computed: 0 });
362
+ expect(compare).not.toHaveBeenCalled();
363
+ });
364
+ test('source format changes invalidate caches even when size and mtime match', async () => {
365
+ const { root, dir } = await fixture();
366
+ await rm(join(dir, 'a.avif'));
367
+ const jpg = await encoded('jpeg', 180);
368
+ const png = await encoded('png', 160);
369
+ const size = Math.max(jpg.length, png.length);
370
+ const timestamp = new Date('2000-01-01');
371
+ for (const [extension, bytes] of [
372
+ ['jpg', jpg],
373
+ ['png', png],
374
+ ]) {
375
+ await writeFile(join(dir, `a.${extension}`), Buffer.concat([bytes, Buffer.alloc(size - bytes.length)]));
376
+ await utimes(join(dir, `a.${extension}`), timestamp, timestamp);
377
+ }
378
+ expect(await processSuite(root)).toMatchObject({ computed: 2 });
379
+ const previous = (await index(root)).metrics[aKey].maxError;
380
+ await rm(join(dir, 'a.png'));
381
+ expect(await processSuite(root)).toMatchObject({ computed: 1, skipped: 1 });
382
+ expect((await index(root)).metrics[aKey].maxError).toBeGreaterThan(previous);
383
+ expect(await processSuite(root)).toMatchObject({ computed: 0, skipped: 2 });
384
+ });
385
+ test('warm-cache discovery retains every pair in scenes with multiple outputs', async () => {
386
+ const { root, dir } = await fixture();
387
+ await rm(dir, { recursive: true });
388
+ const outputs = ['beauty', 'direct', 'ao'];
389
+ const renderers = [{ id: 'ref', reference: true }, { id: 'a' }, { id: 'b' }];
390
+ await writeFile(join(root, 'fidelity.json'), JSON.stringify({ title: 'T', renderers, outputs: outputs.map((id) => ({ id })) }));
391
+ const bytes = await encoded('png', 100);
392
+ for (let i = 0; i < 12; i++)
393
+ for (const output of outputs) {
394
+ const path = join(root, `scene-${i}`, output);
395
+ await mkdir(path, { recursive: true });
396
+ for (const renderer of renderers)
397
+ await writeFile(join(path, `${renderer.id}.png`), bytes);
398
+ }
399
+ expect(await processSuite(root)).toEqual({ computed: 72, skipped: 0, failed: [] });
400
+ for (let i = 0; i < 5; i++) {
401
+ expect(await processSuite(root)).toEqual({ computed: 0, skipped: 72, failed: [] });
402
+ expect(Object.keys((await index(root)).metrics)).toHaveLength(72);
403
+ }
404
+ });
405
+ //# sourceMappingURL=process.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.test.js","sourceRoot":"","sources":["../../src/core/process.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5D,MAAM,KAAK,GAAa,EAAE,CAAC;AAC3B,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,EAAE,CAAC,eAAe,EAAE,CAAC;IACrB,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC,CAAC,CAAC;AACH,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;KACtF,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACxB,QAAQ,EAAE,CAAC;AAChB,MAAM,KAAK,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACnG,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa,EAAE,KAAK,GAAG,GAAG;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACxC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,KAAK,MAAM,QAAQ,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC;QAAE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7G,OAAO,GAAG,CAAC;AACb,CAAC;AACD,KAAK,UAAU,OAAO;IACpB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAC3B,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CACtG,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;AACpD,CAAC;AACD,MAAM,IAAI,GAAG,kCAAkC,CAAC;AAEhD,IAAI,CAAC,iGAAiG,EAAE,KAAK,IAAI,EAAE;IACjH,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;IACnC,MAAM,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;IAC9F,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACtF,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,SAAS,EAAE,CAAC;IACpB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IACpF,SAAS,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACrC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACvC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAClC,SAAS,CAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IAChC,SAAS,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,SAAS,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,SAAS,CAAC,MAAM,CAAC,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACtG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACvC,SAAS,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACrC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;IAC7F,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,aAAa,CAAC;IAC1C,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;QAC7F,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;IAClC,MAAM,OAAO,CAAC,OAAO,CAAC;IACtB,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,OAAO,EAAE,CAAC;IAClB,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1D,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACzC,SAAS,CAAC,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;IAChG,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,aAAa,CAAC;IAC1C,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,sBAAsB,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;QAC7E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;IAClC,MAAM,OAAO,CAAC,OAAO,CAAC;IACtB,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,CAAC,OAAO,EAAE,CAAC;IAClB,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;IACjE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACjC,MAAM,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IACjD,MAAM,eAAe,GAAG,UAAU,CAAC,aAAa,CAAC;IACjD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;QACzE,MAAM,EAAE,CAAC;QACT,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,UAAU,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,MAAM,eAAe,CAAC,GAAG,IAAI,CAAC,CAAC;QACxC,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC;IACxC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CACnE,YAAY,CAAC,IAAI,EAAE;QACjB,GAAG,OAAO;QACV,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,CAAC,OAAO,CAAC;gBACtB,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;YACD,MAAM,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;KACF,CAAC,CACH,CAAC;IACF,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAChG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;IAC3F,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,SAAS,CAAC,MAAM,CAAC;QACf,YAAY;QACZ,IAAI;QACJ,gCAAgC;QAChC,4BAA4B;QAC5B,eAAe;QACf,qBAAqB;QACrB,8BAA8B;KAC/B,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACjF,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IAChD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACzD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACjF,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;IACvF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC;IACrC,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IACpE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;IACtF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1F,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClG,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3G,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oFAAoF,EAAE,KAAK,IAAI,EAAE;IACpG,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACvG,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;IACtG,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC7B,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,SAAS,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;IAC9E,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,GAAG,KAAK,OAAO,CAAC;IAC9B,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAEtD,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IAChB,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClG,MAAM,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACxE,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;IAClB,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACnG,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACpE,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,CACb,OAAO,EACP,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAC5G,CAAC;IACF,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACnG,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEpE,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7D,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;IACtF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1C,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3D,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvF,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAClF,CAAC,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,MAAwC,EAAE,KAAa,EAAE,EAAE,CAC1E,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;KAClG,QAAQ,CAAC,MAAM,CAAC;KAChB,QAAQ,EAAE,CAAC;AAEhB,IAAI,CAAC,uFAAuF,EAAE,KAAK,IAAI,EAAE;IACvG,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IAChC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI;QACvC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC;QACrB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC;QACrB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC;QACnB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC;KACZ;QACR,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,SAAS,EAAE,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAChF,KAAK,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,SAAS,EAAE,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,OAAO,CACnF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAC/B,CAAC;QACF,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC;QACtC,SAAS,CAAC,MAAM,CAAC,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACvG,CAAC;IACD,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1D,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAChE,SAAS,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACjE,SAAS,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,SAAS,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;IACxF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;IACzC,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI;QAC/B,CAAC,KAAK,EAAE,GAAG,CAAC;QACZ,CAAC,KAAK,EAAE,GAAG,CAAC;KACJ,EAAE,CAAC;QACX,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACxG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IAC5D,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC7E,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;IACzF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7E,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,EAC3B,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAClF,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;QACzB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,KAAK,MAAM,QAAQ,IAAI,SAAS;gBAAE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7F,CAAC;IACH,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface ProgressUpdate {
2
+ phase: string;
3
+ completed: number;
4
+ total: number;
5
+ unit: string;
6
+ }
7
+ export type ProgressCallback = (update: ProgressUpdate) => void;
8
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/core/progress.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/core/progress.ts"],"names":[],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import { type FidelityConfig } from './schema.js';
2
+ import type { ProgressCallback } from './progress.js';
2
3
  export interface SceneNode {
3
4
  /** Slash-joined path from the root, e.g. `surfaces/standard_surface/brass`. */
4
5
  path: string;
@@ -7,6 +8,8 @@ export interface SceneNode {
7
8
  hasReadme: boolean;
8
9
  /** output id -> renderer ids that have an image */
9
10
  images: Record<string, string[]>;
11
+ /** Selected source filenames by output and renderer; absent in legacy indexes. */
12
+ imageFiles?: Record<string, Record<string, string>>;
10
13
  }
11
14
  export interface GroupNode {
12
15
  path: string;
@@ -20,7 +23,13 @@ export interface Suite {
20
23
  root: GroupNode;
21
24
  }
22
25
  export declare function readConfig(root: string): Promise<FidelityConfig>;
23
- /** A directory is a scene when any `<output>/<renderer>.avif` exists in it; every other directory is a group. */
24
- export declare function scanSuite(root: string): Promise<Suite>;
26
+ /** A directory is a scene when it contains a configured source image or scene.json. */
27
+ export declare function scanSuite(root: string, options?: {
28
+ config?: FidelityConfig;
29
+ onScene?: (scene: SceneNode) => Promise<void>;
30
+ onProgress?: ProgressCallback;
31
+ }): Promise<Suite>;
32
+ /** Scan one known scene without walking the rest of the suite. */
33
+ export declare function scanScene(root: string, rel: string, config: FidelityConfig): Promise<SceneNode | null>;
25
34
  export declare function allScenes(g: GroupNode): Generator<SceneNode>;
26
35
  //# sourceMappingURL=scan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEjF,MAAM,WAAW,SAAS;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AACD,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB;AAaD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEtE;AAED,iHAAiH;AACjH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAmC5D;AAED,wBAAiB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAG7D"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/core/scan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACjC,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AACD,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB;AAaD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAEtE;AAkCD,uFAAuF;AACvF,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC1B,GACL,OAAO,CAAC,KAAK,CAAC,CA0DhB;AAED,kEAAkE;AAClE,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAO5G;AAwBD,wBAAiB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAG7D"}