@hyperframes/core 0.7.107 → 0.7.109

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 (89) hide show
  1. package/dist/audio/audioFxAutomation.d.ts +63 -0
  2. package/dist/audio/audioFxAutomation.d.ts.map +1 -0
  3. package/dist/audio/audioFxAutomation.js +219 -0
  4. package/dist/audio/audioFxAutomation.js.map +1 -0
  5. package/dist/audio/audioFxGraph.d.ts +73 -0
  6. package/dist/audio/audioFxGraph.d.ts.map +1 -0
  7. package/dist/audio/audioFxGraph.js +649 -0
  8. package/dist/audio/audioFxGraph.js.map +1 -0
  9. package/dist/audio/audioFxTail.d.ts +28 -0
  10. package/dist/audio/audioFxTail.d.ts.map +1 -0
  11. package/dist/audio/audioFxTail.js +95 -0
  12. package/dist/audio/audioFxTail.js.map +1 -0
  13. package/dist/audio/audioFxWorklets.d.ts +8 -0
  14. package/dist/audio/audioFxWorklets.d.ts.map +1 -0
  15. package/dist/audio/audioFxWorklets.js +263 -0
  16. package/dist/audio/audioFxWorklets.js.map +1 -0
  17. package/dist/audioAutomation.d.ts +191 -0
  18. package/dist/audioAutomation.d.ts.map +1 -0
  19. package/dist/audioAutomation.js +488 -0
  20. package/dist/audioAutomation.js.map +1 -0
  21. package/dist/audioCarve.d.ts +216 -0
  22. package/dist/audioCarve.d.ts.map +1 -0
  23. package/dist/audioCarve.js +608 -0
  24. package/dist/audioCarve.js.map +1 -0
  25. package/dist/audioFx.d.ts +182 -0
  26. package/dist/audioFx.d.ts.map +1 -0
  27. package/dist/audioFx.js +813 -0
  28. package/dist/audioFx.js.map +1 -0
  29. package/dist/audioFxCopy.d.ts +89 -0
  30. package/dist/audioFxCopy.d.ts.map +1 -0
  31. package/dist/audioFxCopy.js +340 -0
  32. package/dist/audioFxCopy.js.map +1 -0
  33. package/dist/audioFxEq.d.ts +75 -0
  34. package/dist/audioFxEq.d.ts.map +1 -0
  35. package/dist/audioFxEq.js +153 -0
  36. package/dist/audioFxEq.js.map +1 -0
  37. package/dist/audioFxJobs.d.ts +52 -0
  38. package/dist/audioFxJobs.d.ts.map +1 -0
  39. package/dist/audioFxJobs.js +92 -0
  40. package/dist/audioFxJobs.js.map +1 -0
  41. package/dist/audioFxPresets.d.ts +91 -0
  42. package/dist/audioFxPresets.d.ts.map +1 -0
  43. package/dist/audioFxPresets.js +320 -0
  44. package/dist/audioFxPresets.js.map +1 -0
  45. package/dist/audioFxProfiles.d.ts +65 -0
  46. package/dist/audioFxProfiles.d.ts.map +1 -0
  47. package/dist/audioFxProfiles.js +209 -0
  48. package/dist/audioFxProfiles.js.map +1 -0
  49. package/dist/audioLeveller.d.ts +62 -0
  50. package/dist/audioLeveller.d.ts.map +1 -0
  51. package/dist/audioLeveller.js +208 -0
  52. package/dist/audioLeveller.js.map +1 -0
  53. package/dist/canaryRegistry.d.ts.map +1 -1
  54. package/dist/canaryRegistry.js +8 -0
  55. package/dist/canaryRegistry.js.map +1 -1
  56. package/dist/compiler/compositionScoping.d.ts +3 -0
  57. package/dist/compiler/compositionScoping.d.ts.map +1 -1
  58. package/dist/compiler/compositionScoping.js +34 -11
  59. package/dist/compiler/compositionScoping.js.map +1 -1
  60. package/dist/compiler/htmlBundler.d.ts.map +1 -1
  61. package/dist/compiler/htmlBundler.js +42 -2
  62. package/dist/compiler/htmlBundler.js.map +1 -1
  63. package/dist/editing/affordances.d.ts +3 -0
  64. package/dist/editing/affordances.d.ts.map +1 -1
  65. package/dist/editing/affordances.js +1 -0
  66. package/dist/editing/affordances.js.map +1 -1
  67. package/dist/generated/audio-fx-runtime-inline.d.ts +3 -0
  68. package/dist/generated/audio-fx-runtime-inline.d.ts.map +1 -0
  69. package/dist/generated/audio-fx-runtime-inline.js +7 -0
  70. package/dist/generated/audio-fx-runtime-inline.js.map +1 -0
  71. package/dist/generated/runtime-inline.js +1 -1
  72. package/dist/generated/runtime-inline.js.map +1 -1
  73. package/dist/hyperframe.runtime.iife.js +238 -28
  74. package/dist/runtime/applyVariableBindings.d.ts +45 -0
  75. package/dist/runtime/applyVariableBindings.d.ts.map +1 -0
  76. package/dist/runtime/applyVariableBindings.js +194 -0
  77. package/dist/runtime/applyVariableBindings.js.map +1 -0
  78. package/dist/runtime/audioAutomationVolume.d.ts +17 -0
  79. package/dist/runtime/audioAutomationVolume.d.ts.map +1 -0
  80. package/dist/runtime/audioAutomationVolume.js +49 -0
  81. package/dist/runtime/audioAutomationVolume.js.map +1 -0
  82. package/dist/runtime/media.d.ts.map +1 -1
  83. package/dist/runtime/media.js +17 -1
  84. package/dist/runtime/media.js.map +1 -1
  85. package/dist/runtime/variableScope.d.ts +9 -0
  86. package/dist/runtime/variableScope.d.ts.map +1 -0
  87. package/dist/runtime/variableScope.js +21 -0
  88. package/dist/runtime/variableScope.js.map +1 -0
  89. package/package.json +51 -6
@@ -0,0 +1,608 @@
1
+ /**
2
+ * Voiceover carve: find the bands a voice occupies and dip a music bed there,
3
+ * so the voice sits in front without ducking the whole track.
4
+ *
5
+ * This is a relationship between two tracks, not an effect on one. The controls
6
+ * live on the bed being processed and name the voice to listen to, the same way
7
+ * a sidechain compressor works: you select the track that gets quieter and pick
8
+ * what makes it quieter.
9
+ *
10
+ * The output is an ordinary FX chain of peaking filters, so a carve is just a
11
+ * chain the studio generated rather than a separate rendering path.
12
+ */
13
+ import { defaultAudioFxParams, HF_AUDIO_FX_CHAIN_VERSION, } from "./audioFx.js";
14
+ export const HF_AUDIO_CARVE_ATTR = "data-fx-carve";
15
+ /** Third-octave centres spanning the range speech actually occupies. */
16
+ const CANDIDATE_CENTERS_HZ = [160, 250, 400, 630, 1000, 1600, 2500, 4000, 6000];
17
+ const FRAME = 4096;
18
+ const HOP = 2048;
19
+ /** Short, deliberately dull effects. Nothing here is ever a voiceover. */
20
+ const SFX_NAME = /sfx|foley|whoosh|impact|riser|stinger|swoosh|thud|boom|click|ding|beep|ambien|room[-_ ]?tone/i;
21
+ // `\b` treats `_` as a word character, so `\bbed\b` does not match `bed_01`
22
+ // or `music_bed_loop` — exactly the separator an asset name is likely to use.
23
+ // These short words need a boundary that actually excludes letters and
24
+ // digits on both sides; everything else here is long enough that a
25
+ // substring match is already the intent (`music` inside `bgmusic` is fine).
26
+ const NOT_WORD = "(?<![a-z0-9])";
27
+ const NOT_WORD_END = "(?![a-z0-9])";
28
+ const wordish = (term) => `${NOT_WORD}${term}${NOT_WORD_END}`;
29
+ /** A bed, which is the thing being carved rather than the thing carving it. */
30
+ const MUSIC_NAME = new RegExp(`music|bgm|${wordish("bed")}|soundtrack|score|${wordish("song")}|theme|instrumental|track\\d`, "i");
31
+ /** Speech. */
32
+ const VOICE_NAME = new RegExp(`voice|${wordish("vo")}|${wordish("vox")}|narrat|speech|dialog|monolog|announce|` +
33
+ `${wordish("tts")}|talk|interview|podcast|recap|script`, "i");
34
+ /**
35
+ * Classify a track from its id and filename together.
36
+ *
37
+ * Both, because either can be the informative one: an author naming elements `a1`
38
+ * and `a2` may still have `narration.mp3` and `bgm.mp3` as their sources, and one
39
+ * naming them `voice` and `music` may have opaque hashes for filenames.
40
+ *
41
+ * Voice is tested first: a file called `voiceover-music-bed.wav` is more likely the
42
+ * voiceover than the bed, and a track matching both hints is better offered than
43
+ * hidden.
44
+ */
45
+ export function classifyAudioName(...parts) {
46
+ const text = parts.filter(Boolean).join(" ");
47
+ if (VOICE_NAME.test(text))
48
+ return "voice";
49
+ if (SFX_NAME.test(text))
50
+ return "sfx";
51
+ if (MUSIC_NAME.test(text))
52
+ return "music";
53
+ return "unknown";
54
+ }
55
+ /**
56
+ * Do these two clips share any time at all?
57
+ *
58
+ * A voice that never plays while the bed does cannot mask it, so it has no business
59
+ * in the carve: it would contribute silence to the analysis and, worse, invite the
60
+ * author to wonder why including it changed nothing.
61
+ *
62
+ * An unknown duration counts as unbounded rather than as zero. Refusing a track
63
+ * because its length is not written down would drop the commonest case there is — a
64
+ * clip whose duration the composition leaves to the media itself.
65
+ */
66
+ export function clipsOverlap(a, b) {
67
+ const end = (clip) => typeof clip.duration === "number" && Number.isFinite(clip.duration)
68
+ ? // Negative is clamped to zero-length rather than passed through: a
69
+ // clip cannot un-play time, and letting it through inverts the
70
+ // interval (end before start), which reads as overlapping everything
71
+ // it is nowhere near.
72
+ clip.start + Math.max(0, clip.duration)
73
+ : Number.POSITIVE_INFINITY;
74
+ return a.start < end(b) && b.start < end(a);
75
+ }
76
+ /**
77
+ * Could this track be the voice a carve listens to?
78
+ *
79
+ * Music and SFX are out: a bed is the thing being carved, and a 200 ms whoosh has
80
+ * no speech to make room for. Everything else stays in, including names that say
81
+ * nothing — see `HfAudioNameKind`.
82
+ */
83
+ export function couldBeCarveSource(...parts) {
84
+ const kind = classifyAudioName(...parts);
85
+ return kind === "voice" || kind === "unknown";
86
+ }
87
+ export const DEFAULT_CARVE = {
88
+ enabled: true,
89
+ sources: [],
90
+ // A quarter, because the knob's range was doubled and this is the point on the
91
+ // new scale that produces what the panel has always defaulted to. Switching
92
+ // carve on sounds the same as it did; the extra range is above, not under.
93
+ strength: 0.25,
94
+ };
95
+ /**
96
+ * Strength as the six numbers the analysis needs.
97
+ *
98
+ * Each is a straight line from "barely there" to as far as the effect goes. The
99
+ * slopes are twice what they first were: the top of the knob was not strong
100
+ * enough to sit a bed under a loud voice, so what used to be full strength is now
101
+ * the halfway point and everything above it is new range. Quarter strength is
102
+ * therefore where the separate controls' own defaults land, which is what the
103
+ * panel defaults to.
104
+ */
105
+ export function carveProfile(strength) {
106
+ const s = Number.isFinite(strength) ? Math.min(1, Math.max(0, strength)) : 0.5;
107
+ return {
108
+ // 2 dB is audible-but-subtle. Past about 10 the hole starts being heard as
109
+ // the effect rather than as room for the voice — which is a price worth
110
+ // paying at the top of the knob, and why the range now runs past it.
111
+ maxCutDb: Number((2 + s * 16).toFixed(2)),
112
+ // One band carves the single worst collision; six is every candidate band
113
+ // speech meaningfully occupies.
114
+ bands: Math.max(1, Math.min(6, Math.round(1 + s * 6))),
115
+ // Wider at low strength so a gentle carve is a tilt rather than a notch.
116
+ q: Number((1.1 + s * 1.2).toFixed(2)),
117
+ // Always weighted toward where masking hurts; at the top, entirely.
118
+ intelligibilityBias: Number(Math.min(1, 0.6 + s * 0.4).toFixed(2)),
119
+ // No level ducking at all at zero: the carve is then purely spectral.
120
+ duckDb: Number((s * 24).toFixed(2)),
121
+ // How far under the voice to aim. Deeper targets at higher strength.
122
+ headroomDb: Number((6 + s * 12).toFixed(2)),
123
+ };
124
+ }
125
+ /**
126
+ * Read carve settings from an attribute.
127
+ *
128
+ * Projects written before the collapse to one knob carry the six mechanism
129
+ * numbers instead; their depth is the one that says most about intent, so it maps
130
+ * back onto strength rather than being dropped. Everything else about such a
131
+ * carve is re-derived, which is the point of having one control.
132
+ */
133
+ export function normalizeCarveSettings(raw) {
134
+ // `source` and `dynamic` are gone from the type but still out there in files.
135
+ const legacy = raw;
136
+ const num = (v) => {
137
+ const n = typeof v === "number" ? v : Number(v);
138
+ return Number.isFinite(n) ? n : null;
139
+ };
140
+ // No attribute at all is not a carve to read, it is the absence of one — so the
141
+ // defaults apply whole, dynamic included. Only a stored object gets the reading
142
+ // below, where a missing `dynamic` means the static carve it was written as.
143
+ if (raw === undefined || raw === null)
144
+ return { ...DEFAULT_CARVE };
145
+ const strength = num(raw?.strength);
146
+ const legacyDepth = num(raw?.maxCutDb);
147
+ const resolved = strength !== null
148
+ ? strength
149
+ : legacyDepth !== null
150
+ ? // The inverse of the depth line in `carveProfile`, so the 6 dB default
151
+ // reads back as the strength that produces 6 dB.
152
+ (legacyDepth - 2) / 16
153
+ : DEFAULT_CARVE.strength;
154
+ // A carve written before this took a list names its one voice in `source`.
155
+ const stored = Array.isArray(raw?.sources)
156
+ ? raw.sources
157
+ : typeof legacy?.source === "string"
158
+ ? [legacy.source]
159
+ : [];
160
+ return {
161
+ // Absent means on: every carve written before the flag existed was applied.
162
+ enabled: raw?.enabled !== false,
163
+ sources: stored.filter((id) => typeof id === "string" && id !== ""),
164
+ strength: Math.min(1, Math.max(0, resolved)),
165
+ };
166
+ }
167
+ /**
168
+ * Every voice as one signal on the BED's clock.
169
+ *
170
+ * The analysis asks one question — where and when is speech masking this bed — and
171
+ * that question has one answer even when three people are talking at different
172
+ * times. Summing them onto the bed's timeline first means the existing analysis
173
+ * needs no notion of "which voice": bands come out of all the speech there is, and
174
+ * the envelopes rise wherever any of it is happening.
175
+ *
176
+ * `offsetSeconds` is where each voice starts relative to the bed. Audio before the
177
+ * bed begins is dropped rather than folded in at zero: it plays over nothing and
178
+ * cannot mask anything, and shifting it would put a cut where there is no voice.
179
+ *
180
+ * Summed, not averaged. Two people speaking at once mask more than either alone,
181
+ * which is exactly what the carve should answer to.
182
+ */
183
+ export function mixCarveSources(parts, sampleRate) {
184
+ const placed = parts.map((part) => ({
185
+ samples: part.samples,
186
+ at: Math.round(part.offsetSeconds * sampleRate),
187
+ }));
188
+ const length = placed.reduce((max, p) => Math.max(max, p.at + p.samples.length), 0);
189
+ if (length <= 0)
190
+ return new Float32Array(0);
191
+ const mixed = new Float32Array(length);
192
+ for (const { samples, at } of placed) {
193
+ // A voice starting before the bed contributes only the part that overlaps it.
194
+ const from = at < 0 ? -at : 0;
195
+ for (let i = from; i < samples.length; i += 1) {
196
+ const target = at + i;
197
+ if (target < 0 || target >= length)
198
+ continue;
199
+ mixed[target] = (mixed[target] ?? 0) + (samples[i] ?? 0);
200
+ }
201
+ }
202
+ return mixed;
203
+ }
204
+ /** Averaged power spectrum, Welch-style. */
205
+ function powerSpectrum(mono, sampleRate) {
206
+ const n = Math.max(mono.length, FRAME);
207
+ const padded = mono.length >= FRAME
208
+ ? mono
209
+ : (() => {
210
+ const p = new Float32Array(FRAME);
211
+ p.set(mono);
212
+ return p;
213
+ })();
214
+ const window = new Float32Array(FRAME);
215
+ for (let i = 0; i < FRAME; i++)
216
+ window[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / (FRAME - 1));
217
+ const bins = FRAME / 2 + 1;
218
+ const acc = new Float64Array(bins);
219
+ // Reused across hops. These used to be allocated inside the loop: a 5-minute
220
+ // 48 kHz voiceover is ~7000 hops, so ~460 MB of transient Float64Array
221
+ // churned through the main thread for a single carve. `re` is fully
222
+ // overwritten below; only `im` has to be cleared.
223
+ const re = new Float64Array(FRAME);
224
+ const im = new Float64Array(FRAME);
225
+ //
226
+ // Every hop is still read. Striding them — Welch's average is supposed to
227
+ // settle long before 7000 windows — was measured on a 5-minute voiceover and
228
+ // moves the result: at strength 0.9 the chosen band set changed (630 Hz for
229
+ // 160 Hz), and it did not converge back to the full read even at 2048
230
+ // windows. 27x faster is not worth silently redrawing the author's carve.
231
+ let frames = 0;
232
+ for (let start = 0; start + FRAME <= n; start += HOP) {
233
+ // Goertzel-free naive DFT would be O(n^2); use a real FFT via recursion on
234
+ // a copied frame. FRAME is a power of two so the radix-2 split is exact.
235
+ im.fill(0);
236
+ for (let i = 0; i < FRAME; i++)
237
+ re[i] = (padded[start + i] ?? 0) * window[i];
238
+ fft(re, im);
239
+ for (let k = 0; k < bins; k++)
240
+ acc[k] += re[k] * re[k] + im[k] * im[k];
241
+ frames++;
242
+ }
243
+ if (frames === 0)
244
+ frames = 1;
245
+ const freqs = [];
246
+ const power = [];
247
+ for (let k = 0; k < bins; k++) {
248
+ freqs.push((k * sampleRate) / FRAME);
249
+ power.push(acc[k] / frames);
250
+ }
251
+ return { freqs, power };
252
+ }
253
+ /** In-place iterative radix-2 FFT. */
254
+ function fft(re, im) {
255
+ const n = re.length;
256
+ for (let i = 1, j = 0; i < n; i++) {
257
+ let bit = n >> 1;
258
+ for (; j & bit; bit >>= 1)
259
+ j ^= bit;
260
+ j ^= bit;
261
+ if (i < j) {
262
+ [re[i], re[j]] = [re[j], re[i]];
263
+ [im[i], im[j]] = [im[j], im[i]];
264
+ }
265
+ }
266
+ for (let len = 2; len <= n; len <<= 1) {
267
+ const ang = (-2 * Math.PI) / len;
268
+ const wr = Math.cos(ang);
269
+ const wi = Math.sin(ang);
270
+ for (let i = 0; i < n; i += len) {
271
+ let cr = 1;
272
+ let ci = 0;
273
+ for (let k = 0; k < len / 2; k++) {
274
+ const ur = re[i + k];
275
+ const ui = im[i + k];
276
+ const vr = re[i + k + len / 2] * cr - im[i + k + len / 2] * ci;
277
+ const vi = re[i + k + len / 2] * ci + im[i + k + len / 2] * cr;
278
+ re[i + k] = ur + vr;
279
+ im[i + k] = ui + vi;
280
+ re[i + k + len / 2] = ur - vr;
281
+ im[i + k + len / 2] = ui - vi;
282
+ const ncr = cr * wr - ci * wi;
283
+ ci = cr * wi + ci * wr;
284
+ cr = ncr;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ function bandPower(freqs, power, center) {
290
+ const lo = center / Math.pow(2, 1 / 6);
291
+ const hi = center * Math.pow(2, 1 / 6);
292
+ let sum = 0;
293
+ let count = 0;
294
+ for (let i = 0; i < freqs.length; i++) {
295
+ if (freqs[i] >= lo && freqs[i] < hi) {
296
+ sum += power[i];
297
+ count++;
298
+ }
299
+ }
300
+ return count > 0 ? sum / count : 0;
301
+ }
302
+ /**
303
+ * How far the bias may move a band in the ranking, in dB, at full strength.
304
+ *
305
+ * This has to be on the scale of the thing it competes with. Speech spreads
306
+ * 20-30 dB across these candidate bands — it falls off roughly 6 dB per octave
307
+ * above the fundamental — so a bias that can only shift the ranking by a few dB
308
+ * cannot shift it at all. 30 dB gives the 0.7 default about 21 dB of authority
309
+ * over the low bands, enough to cross a normal voice's tilt, while still leaving
310
+ * a band the voice genuinely dominates able to win: the bias reweights the
311
+ * ranking, it does not override the spectrum.
312
+ */
313
+ const BIAS_AUTHORITY_DB = 30;
314
+ /**
315
+ * Ranking penalty for a candidate band, in dB. Zero at 2 kHz, where speech
316
+ * intelligibility lives and where a bed most often masks a voice, rising as a
317
+ * band sits further away in either direction.
318
+ *
319
+ * Applied in dB, and that is the point. As a multiplicative weight of
320
+ * `1 - bias + bias * shaped` it is bounded below by `1 - bias`, so the most it
321
+ * could ever move a ranking is `10*log10(1/(1 - bias))`: 5.2 dB at the 0.7
322
+ * default, 3 dB at 0.5. Against speech's own 20-30 dB tilt that is no influence,
323
+ * and every bias below ~0.95 ranks exactly like bias 0 — selecting the
324
+ * fundamental every time, the precise outcome the bias exists to prevent. A
325
+ * fixture whose bands sit 2 dB apart cannot tell the two apart.
326
+ */
327
+ function intelligibilityPenaltyDb(center, bias) {
328
+ const octavesFrom2k = Math.log2(center / 2000);
329
+ const shaped = Math.exp(-(octavesFrom2k * octavesFrom2k) / 2);
330
+ return bias * BIAS_AUTHORITY_DB * (1 - shaped);
331
+ }
332
+ /**
333
+ * Analyse a voice and return the bands to dip in the bed. Bands come back in
334
+ * ascending frequency; the deepest cut lands on the strongest band and the
335
+ * others scale with their relative weight, floored at half depth so a selected
336
+ * band still does something audible.
337
+ */
338
+ export function analyseCarveBands(voice, sampleRate, profile) {
339
+ if (voice.length === 0)
340
+ return [];
341
+ const { freqs, power } = powerSpectrum(voice, sampleRate);
342
+ const scored = CANDIDATE_CENTERS_HZ.map((center) => {
343
+ const bandPowerAt = bandPower(freqs, power, center);
344
+ return {
345
+ center,
346
+ hasEnergy: bandPowerAt > 0,
347
+ // A band with no energy scores -Infinity rather than a large negative
348
+ // number, so it can never outrank a real band however favourably the bias
349
+ // views its frequency.
350
+ scoreDb: bandPowerAt > 0
351
+ ? 10 * Math.log10(bandPowerAt) -
352
+ intelligibilityPenaltyDb(center, profile.intelligibilityBias)
353
+ : Number.NEGATIVE_INFINITY,
354
+ };
355
+ }).sort((a, b) => b.scoreDb - a.scoreDb);
356
+ const selected = scored.slice(0, Math.max(1, profile.bands)).filter((b) => b.hasEnergy);
357
+ if (selected.length === 0)
358
+ return [];
359
+ const topDb = selected[0].scoreDb;
360
+ return selected
361
+ .map(({ center, scoreDb }) => {
362
+ // Same relative depth as a ratio of linear scores would give — a band 3 dB
363
+ // under the strongest gets half its cut — read off the dB difference.
364
+ const relative = Math.pow(10, (scoreDb - topDb) / 10);
365
+ const depth = Math.min(profile.maxCutDb, Math.max(profile.maxCutDb / 2, profile.maxCutDb * relative));
366
+ return { freq: center, gainDb: -Number(depth.toFixed(2)), q: profile.q };
367
+ })
368
+ .sort((a, b) => a.freq - b.freq);
369
+ }
370
+ /**
371
+ * How far below a band's own loudest moment counts as nothing to carve. A voice
372
+ * 30 dB down on its peak is a room tone or a breath, not speech, and the bed
373
+ * should be flat there.
374
+ */
375
+ const DYNAMIC_RANGE_DB = 30;
376
+ /**
377
+ * Envelope follower time constants, in seconds. Asymmetric on purpose, the way
378
+ * a ducker is: the cut has to be there by the time a word is audible, and has to
379
+ * leave slowly enough that the bed does not pump between syllables.
380
+ */
381
+ const ATTACK_S = 0.05;
382
+ const RELEASE_S = 0.25;
383
+ /**
384
+ * Release for the level envelope, which is far slower than the filters' own.
385
+ *
386
+ * A notch closing quickly is inaudible — nothing about the bed's loudness
387
+ * changes. The whole bed coming back is not: at a filter's 0.25s the music
388
+ * jumped to full the instant a word ended, and what you hear then is the effect
389
+ * switching off rather than a mix breathing. Slower than any gap inside a
390
+ * sentence, so it rides through the pauses between words and only recovers
391
+ * between sentences.
392
+ *
393
+ * It also has to be well clear of the envelope's own step. A long voice is
394
+ * measured about every 0.3s, so a release anywhere near that puts the entire
395
+ * recovery inside one step — a jump, whatever the constant claims.
396
+ */
397
+ const DUCK_RELEASE_S = 1.6;
398
+ /**
399
+ * Windows an envelope may spend. Held under `MAX_AUTOMATION_POINTS` with room
400
+ * for the two end points, because `normalizeAutomation` truncates an over-budget
401
+ * lane rather than thinning it — losing the tail would leave the last cut held
402
+ * for the rest of the bed, which is the one failure this feature must not have.
403
+ */
404
+ const POINT_BUDGET = 400;
405
+ /** Below this a cut is inaudible, so it is recorded as no cut at all. */
406
+ const SNAP_DB = 0.2;
407
+ /**
408
+ * Smallest move worth its own breakpoint. Coarse enough that a lane stays
409
+ * editable by hand — a syllable-rate envelope at the analysis hop draws a point
410
+ * every 85 ms, which is a wall of handles nobody can grab — and fine enough that
411
+ * the shape is unchanged, since the segments either side interpolate.
412
+ */
413
+ const STEP_DB = 0.5;
414
+ /**
415
+ * Thin a raw per-frame envelope down to the points where its value actually
416
+ * moved by `stepDb`, anchoring the run each drop ends.
417
+ *
418
+ * Segments interpolate, so dropping a run of equal values does not hold them —
419
+ * it draws a straight line from wherever the last kept point was, which turned
420
+ * a silent stretch before the run into a slow slide into it. Keeping the last
421
+ * value of the run pins the plateau flat and puts the whole move where it
422
+ * belongs. Shared by the two envelope builders below, which differ only in how
423
+ * `raw` gets built.
424
+ */
425
+ function simplifyStepPoints(raw, stepDb) {
426
+ const points = [{ t: 0, v: 0 }];
427
+ let lastKept = 0;
428
+ let keptIndex = -1;
429
+ raw.forEach((pt, i) => {
430
+ if (i !== raw.length - 1 && Math.abs(pt.v - lastKept) < stepDb)
431
+ return;
432
+ if (i > 0 && keptIndex !== i - 1)
433
+ points.push(raw[i - 1]);
434
+ points.push(pt);
435
+ lastKept = pt.v;
436
+ keptIndex = i;
437
+ });
438
+ return points;
439
+ }
440
+ /**
441
+ * Turn each carved band into an envelope that follows the voice's level in that
442
+ * same band.
443
+ *
444
+ * The depth from `analyseCarveBands` becomes the envelope's ceiling rather than a
445
+ * constant: full depth where that band is at its loudest in the voice, flat where
446
+ * the voice is silent, scaled in dB between the two. Written as automation on the
447
+ * filters' gain, so playback and render both already know how to follow it.
448
+ *
449
+ * Times are relative to the voice clip, since that is what was measured. A caller
450
+ * placing these on another element shifts them by the gap between the two clips'
451
+ * starts. This assumes the voice plays from its own beginning at its `data-start`
452
+ * — a clip with a media offset would need that added.
453
+ */
454
+ export function analyseCarveDynamics(voice, sampleRate, bands) {
455
+ if (voice.length === 0 || bands.length === 0)
456
+ return [];
457
+ const window = new Float32Array(FRAME);
458
+ for (let i = 0; i < FRAME; i++)
459
+ window[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / (FRAME - 1));
460
+ // One window per emitted point, so the hop is what keeps the lane in budget.
461
+ const hop = Math.max(FRAME, Math.ceil(voice.length / POINT_BUDGET));
462
+ const bins = FRAME / 2 + 1;
463
+ const freqs = [];
464
+ for (let k = 0; k < bins; k++)
465
+ freqs.push((k * sampleRate) / FRAME);
466
+ const times = [];
467
+ const perBand = bands.map(() => []);
468
+ // Reused across windows, as in powerSpectrum. `re` is fully overwritten
469
+ // below; only `im` has to be cleared. The hop here is already bounded by
470
+ // POINT_BUDGET, so there is nothing to stride.
471
+ const re = new Float64Array(FRAME);
472
+ const im = new Float64Array(FRAME);
473
+ for (let start = 0; start < voice.length; start += hop) {
474
+ im.fill(0);
475
+ for (let i = 0; i < FRAME; i++)
476
+ re[i] = (voice[start + i] ?? 0) * window[i];
477
+ fft(re, im);
478
+ const power = [];
479
+ for (let k = 0; k < bins; k++)
480
+ power.push(re[k] * re[k] + im[k] * im[k]);
481
+ times.push((start + FRAME / 2) / sampleRate);
482
+ bands.forEach((band, b) => perBand[b].push(bandPower(freqs, power, band.freq)));
483
+ }
484
+ const duration = voice.length / sampleRate;
485
+ const attack = 1 - Math.exp(-(hop / sampleRate) / ATTACK_S);
486
+ const release = 1 - Math.exp(-(hop / sampleRate) / RELEASE_S);
487
+ return bands.map((band, b) => {
488
+ const powers = perBand[b];
489
+ const peak = Math.max(...powers);
490
+ let level = 0;
491
+ const raw = [];
492
+ powers.forEach((p, i) => {
493
+ // Relative to this band's own loudest moment, so a quiet band still gets a
494
+ // full envelope rather than a permanently shallow one.
495
+ const target = p > 0 && peak > 0 ? Math.max(0, 1 + (10 * Math.log10(p / peak)) / DYNAMIC_RANGE_DB) : 0;
496
+ level += (target > level ? attack : release) * (target - level);
497
+ const scaled = band.gainDb * level;
498
+ const v = Math.abs(scaled) < SNAP_DB ? 0 : Number(scaled.toFixed(1));
499
+ raw.push({ t: Number(times[i].toFixed(3)), v });
500
+ });
501
+ const points = simplifyStepPoints(raw, STEP_DB);
502
+ // The last point's value is held for the rest of the bed, so it has to be
503
+ // no cut and it has to be at the end of the voice.
504
+ points.push({ t: Number(Math.max(duration, points.at(-1).t).toFixed(3)), v: 0 });
505
+ return { freq: band.freq, points };
506
+ });
507
+ }
508
+ /** Level in dB of one window, or -Infinity for silence. */
509
+ function windowDb(samples, from, count) {
510
+ let sum = 0;
511
+ let n = 0;
512
+ for (let i = from; i < from + count; i++) {
513
+ const s = samples[i];
514
+ if (s === undefined)
515
+ break;
516
+ sum += s * s;
517
+ n += 1;
518
+ }
519
+ if (n === 0)
520
+ return Number.NEGATIVE_INFINITY;
521
+ const rms = Math.sqrt(sum / n);
522
+ return rms > 0 ? 20 * Math.log10(rms) : Number.NEGATIVE_INFINITY;
523
+ }
524
+ /**
525
+ * The level envelope that keeps a bed under a voice.
526
+ *
527
+ * The spectral carve makes room in the frequency domain, which does nothing
528
+ * about a bed that is simply louder than the voice: the notches sit in the right
529
+ * places while the level goes on winning. This measures both tracks over the
530
+ * same windows and returns the gain the bed needs to sit `headroomDb` under the
531
+ * voice — no more than `duckDb`, and nothing at all where the voice is not
532
+ * speaking, so pauses stay open rather than being held down.
533
+ *
534
+ * Times are in seconds from the start of the *voice* clip; `offsetSeconds` is
535
+ * how far into the bed the voice's start falls, so the two are read at the same
536
+ * moment of the composition even when the clips begin at different times.
537
+ */
538
+ export function analyseCarveDuck(voice, bed, sampleRate, profile, offsetSeconds) {
539
+ if (voice.length === 0 || profile.duckDb <= 0)
540
+ return [];
541
+ const hop = Math.max(FRAME, Math.ceil(voice.length / POINT_BUDGET));
542
+ const bedOffset = Math.round(offsetSeconds * sampleRate);
543
+ const voiceDbs = [];
544
+ const bedDbs = [];
545
+ const times = [];
546
+ for (let start = 0; start < voice.length; start += hop) {
547
+ voiceDbs.push(windowDb(voice, start, FRAME));
548
+ bedDbs.push(windowDb(bed, start + bedOffset, FRAME));
549
+ times.push((start + FRAME / 2) / sampleRate);
550
+ }
551
+ // Speaking, rather than merely non-zero: a room tone 30 dB under the voice's
552
+ // own peak is not something to duck for, and gating on it is what keeps the
553
+ // bed up through pauses.
554
+ const voicePeak = Math.max(...voiceDbs);
555
+ const speakingFloor = voicePeak - DYNAMIC_RANGE_DB;
556
+ const attack = 1 - Math.exp(-(hop / sampleRate) / ATTACK_S);
557
+ const release = 1 - Math.exp(-(hop / sampleRate) / DUCK_RELEASE_S);
558
+ let level = 0;
559
+ const raw = [];
560
+ voiceDbs.forEach((vDb, i) => {
561
+ const bDb = bedDbs[i] ?? Number.NEGATIVE_INFINITY;
562
+ // How far over the line the bed is, right now.
563
+ const over = vDb > speakingFloor && Number.isFinite(bDb) ? bDb - (vDb - profile.headroomDb) : 0;
564
+ const target = Math.min(profile.duckDb, Math.max(0, over));
565
+ level += (target > level ? attack : release) * (target - level);
566
+ const v = level < SNAP_DB ? 0 : -Number(level.toFixed(1));
567
+ raw.push({ t: Number(times[i].toFixed(3)), v });
568
+ });
569
+ // Let the release finish past the last word. A lane's final point has to be no
570
+ // cut — otherwise the bed stays dipped for the rest of the clip — but jumping
571
+ // there from a full duck is the same flip the slow release exists to prevent,
572
+ // moved to the end of the narration. So the decay carries on at its own rate
573
+ // beyond the voice until it is inaudible, and only then pins.
574
+ const hopSeconds = hop / sampleRate;
575
+ let tailTime = times.at(-1) ?? 0;
576
+ while (level >= SNAP_DB) {
577
+ level += release * -level;
578
+ tailTime += hopSeconds;
579
+ raw.push({
580
+ t: Number(tailTime.toFixed(3)),
581
+ v: level < SNAP_DB ? 0 : -Number(level.toFixed(1)),
582
+ });
583
+ }
584
+ const points = simplifyStepPoints(raw, STEP_DB);
585
+ // Pin the end at no cut, unless the release already got there — a second point
586
+ // at the same time and value is just noise in the lane.
587
+ const duration = voice.length / sampleRate;
588
+ const last = points.at(-1);
589
+ const endTime = Number(Math.max(duration, last.t).toFixed(3));
590
+ if (!(last.v === 0 && last.t >= endTime))
591
+ points.push({ t: endTime, v: 0 });
592
+ return points;
593
+ }
594
+ /** Carve bands as an ordinary FX chain of peaking filters. */
595
+ export function carveBandsToChain(bands) {
596
+ const nodes = bands.map((b) => ({
597
+ type: "peaking",
598
+ enabled: true,
599
+ params: {
600
+ ...defaultAudioFxParams("peaking"),
601
+ frequency: b.freq,
602
+ gain: b.gainDb,
603
+ q: b.q,
604
+ },
605
+ }));
606
+ return { version: HF_AUDIO_FX_CHAIN_VERSION, nodes };
607
+ }
608
+ //# sourceMappingURL=audioCarve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioCarve.js","sourceRoot":"","sources":["../src/audioCarve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,oBAAoB,EACpB,yBAAyB,GAG1B,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAEnD,wEAAwE;AACxE,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAEzF,MAAM,KAAK,GAAG,IAAI,CAAC;AACnB,MAAM,GAAG,GAAG,IAAI,CAAC;AA8EjB,0EAA0E;AAC1E,MAAM,QAAQ,GACZ,+FAA+F,CAAC;AAClG,4EAA4E;AAC5E,8EAA8E;AAC9E,uEAAuE;AACvE,mEAAmE;AACnE,4EAA4E;AAC5E,MAAM,QAAQ,GAAG,eAAe,CAAC;AACjC,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,GAAG,QAAQ,GAAG,IAAI,GAAG,YAAY,EAAE,CAAC;AAE9E,+EAA+E;AAC/E,MAAM,UAAU,GAAG,IAAI,MAAM,CAC3B,aAAa,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,CAAC,MAAM,CAAC,8BAA8B,EAC7F,GAAG,CACJ,CAAC;AACF,cAAc;AACd,MAAM,UAAU,GAAG,IAAI,MAAM,CAC3B,SAAS,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,yCAAyC;IAC/E,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,EACzD,GAAG,CACJ,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAG,KAA6C;IAEhD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,SAAS,CAAC;AACnB,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,CAAa,EAAE,CAAa;IACvD,MAAM,GAAG,GAAG,CAAC,IAAgB,EAAU,EAAE,CACvC,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjE,CAAC,CAAC,mEAAmE;YACnE,+DAA+D;YAC/D,qEAAqE;YACrE,sBAAsB;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC;QACzC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC/B,OAAO,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAG,KAA6C;IACjF,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,KAAK,CAAC,CAAC;IACzC,OAAO,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,EAAE;IACX,+EAA+E;IAC/E,4EAA4E;IAC5E,2EAA2E;IAC3E,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/E,OAAO;QACL,2EAA2E;QAC3E,wEAAwE;QACxE,qEAAqE;QACrE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzC,0EAA0E;QAC1E,gCAAgC;QAChC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtD,yEAAyE;QACzE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrC,oEAAoE;QACpE,mBAAmB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAClE,sEAAsE;QACtE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnC,qEAAqE;QACrE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,GAA0D;IAE1D,8EAA8E;IAC9E,MAAM,MAAM,GAAG,GAAoE,CAAC;IACpF,MAAM,GAAG,GAAG,CAAC,CAAU,EAAiB,EAAE;QACxC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC,CAAC;IACF,gFAAgF;IAChF,gFAAgF;IAChF,6EAA6E;IAC7E,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC;IACnE,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GACZ,QAAQ,KAAK,IAAI;QACf,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,WAAW,KAAK,IAAI;YACpB,CAAC,CAAC,uEAAuE;gBACvE,iDAAiD;gBACjD,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,EAAE;YACxB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC;IAC/B,2EAA2E;IAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC;QACxC,CAAC,CAAC,GAAG,CAAC,OAAO;QACb,CAAC,CAAC,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ;YAClC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;YACjB,CAAC,CAAC,EAAE,CAAC;IACT,OAAO;QACL,4EAA4E;QAC5E,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,KAAK;QAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,EAAE,CAAC;QACjF,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAkE,EAClE,UAAkB;IAElB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC;KAChD,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC;QACrC,8EAA8E;QAC9E,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;YACtB,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM;gBAAE,SAAS;YAC7C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4CAA4C;AAC5C,SAAS,aAAa,CACpB,IAAkB,EAClB,UAAkB;IAElB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,IAAI,KAAK;QAClB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACZ,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,EAAE,CAAC;IAEX,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAElG,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACnC,6EAA6E;IAC7E,uEAAuE;IACvE,oEAAoE;IACpE,kDAAkD;IAClD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,EAAE;IACF,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,sEAAsE;IACtE,0EAA0E;IAC1E,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,GAAG,EAAE,CAAC;QACrD,2EAA2E;QAC3E,yEAAyE;QACzE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;YAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QAC9E,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,CAAC,CAAE,IAAI,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC;QAC5E,MAAM,EAAE,CAAC;IACX,CAAC;IACD,IAAI,MAAM,KAAK,CAAC;QAAE,MAAM,GAAG,CAAC,CAAC;IAE7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,sCAAsC;AACtC,SAAS,GAAG,CAAC,EAAgB,EAAE,EAAgB;IAC7C,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC;YAAE,CAAC,IAAI,GAAG,CAAC;QACpC,CAAC,IAAI,GAAG,CAAC;QACT,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC;YAClC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;YAChC,IAAI,EAAE,GAAG,CAAC,CAAC;YACX,IAAI,EAAE,GAAG,CAAC,CAAC;YACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACjC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;gBACtB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;gBACtB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAE,GAAG,EAAE,CAAC;gBACjE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAE,GAAG,EAAE,CAAC;gBACjE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBACpB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBACpB,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBAC9B,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;gBAC9B,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;gBAC9B,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;gBACvB,EAAE,GAAG,GAAG,CAAC;YACX,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAe,EAAE,KAAe,EAAE,MAAc;IACjE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAE,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,CAAE,GAAG,EAAE,EAAE,CAAC;YACtC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC;YACjB,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IACD,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;;;;;;;;;;GAYG;AACH,SAAS,wBAAwB,CAAC,MAAc,EAAE,IAAY;IAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,OAAO,IAAI,GAAG,iBAAiB,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAmB,EACnB,UAAkB,EAClB,OAAuB;IAEvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACjD,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACpD,OAAO;YACL,MAAM;YACN,SAAS,EAAE,WAAW,GAAG,CAAC;YAC1B,sEAAsE;YACtE,0EAA0E;YAC1E,uBAAuB;YACvB,OAAO,EACL,WAAW,GAAG,CAAC;gBACb,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;oBAC5B,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC;gBAC/D,CAAC,CAAC,MAAM,CAAC,iBAAiB;SAC/B,CAAC;IACJ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC;IACnC,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3B,2EAA2E;QAC3E,sEAAsE;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,OAAO,CAAC,QAAQ,EAChB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAC5D,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IAC3E,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B;;;;GAIG;AACH,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtB,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB;;;;;;;;;;;;;GAaG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB,yEAAyE;AACzE,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;;;;;;;;;GAUG;AACH,SAAS,kBAAkB,CACzB,GAAwC,EACxC,MAAc;IAEd,MAAM,MAAM,GAA+B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM;YAAE,OAAO;QACvE,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,KAAK,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;QAChB,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AASD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAmB,EACnB,UAAkB,EAClB,KAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAExD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAElG,6EAA6E;IAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;IAChD,wEAAwE;IACxE,yEAAyE;IACzE,+CAA+C;IAC/C,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,GAAG,EAAE,CAAC;QACvD,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;YAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;QAC7E,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACZ,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,SAAS,CAAC,CAAC;IAE9D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;QACjC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,GAAG,GAA+B,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACtB,2EAA2E;YAC3E,uDAAuD;YACvD,MAAM,MAAM,GACV,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1F,KAAK,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChD,0EAA0E;QAC1E,mDAAmD;QACnD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2DAA2D;AAC3D,SAAS,QAAQ,CAAC,OAAqB,EAAE,IAAY,EAAE,KAAa;IAClE,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,SAAS;YAAE,MAAM;QAC3B,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,CAAC,IAAI,CAAC,CAAC;IACT,CAAC;IACD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/B,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAmB,EACnB,GAAiB,EACjB,UAAkB,EAClB,OAAuB,EACvB,aAAqB;IAErB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAEzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,GAAG,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,6EAA6E;IAC7E,4EAA4E;IAC5E,yBAAyB;IACzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,SAAS,GAAG,gBAAgB,CAAC;IAEnD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,cAAc,CAAC,CAAC;IAEnE,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,GAAG,GAA+B,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC;QAClD,+CAA+C;QAC/C,MAAM,IAAI,GAAG,GAAG,GAAG,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,KAAK,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAChE,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM,UAAU,GAAG,GAAG,GAAG,UAAU,CAAC;IACpC,IAAI,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,KAAK,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC;QAC1B,QAAQ,IAAI,UAAU,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC;YACP,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChD,+EAA+E;IAC/E,wDAAwD;IACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACpD,MAAM,KAAK,GAAoB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI;QACb,MAAM,EAAE;YACN,GAAG,oBAAoB,CAAC,SAAS,CAAC;YAClC,SAAS,EAAE,CAAC,CAAC,IAAI;YACjB,IAAI,EAAE,CAAC,CAAC,MAAM;YACd,CAAC,EAAE,CAAC,CAAC,CAAC;SACP;KACF,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,CAAC;AACvD,CAAC"}