@opendaw/studio-core 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AudioInputDevices.d.ts +8 -0
- package/dist/AudioInputDevices.d.ts.map +1 -0
- package/dist/AudioInputDevices.js +30 -0
- package/dist/AudioUnitOrdering.d.ts +3 -0
- package/dist/AudioUnitOrdering.d.ts.map +1 -0
- package/dist/AudioUnitOrdering.js +7 -0
- package/dist/EffectBox.d.ts +2 -2
- package/dist/EffectBox.d.ts.map +1 -1
- package/dist/Engine.d.ts +31 -10
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +22 -11
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +39 -22
- package/dist/EngineWorklet.d.ts +22 -13
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +47 -56
- package/dist/MeterWorklet.d.ts.map +1 -1
- package/dist/MeterWorklet.js +2 -2
- package/dist/Project.d.ts +7 -3
- package/dist/Project.d.ts.map +1 -1
- package/dist/Project.js +22 -4
- package/dist/ProjectApi.d.ts +0 -1
- package/dist/ProjectApi.d.ts.map +1 -1
- package/dist/ProjectApi.js +16 -11
- package/dist/ProjectEnv.d.ts +1 -0
- package/dist/ProjectEnv.d.ts.map +1 -1
- package/dist/ProjectMigration.d.ts.map +1 -1
- package/dist/ProjectMigration.js +20 -3
- package/dist/RecordingWorklet.d.ts +15 -3
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +111 -16
- package/dist/WorkerAgents.d.ts +2 -2
- package/dist/WorkerAgents.d.ts.map +1 -1
- package/dist/Worklets.d.ts +1 -1
- package/dist/Worklets.d.ts.map +1 -1
- package/dist/Worklets.js +2 -2
- package/dist/capture/Capture.d.ts +22 -0
- package/dist/capture/Capture.d.ts.map +1 -0
- package/dist/capture/Capture.js +32 -0
- package/dist/capture/CaptureAudio.d.ts +17 -0
- package/dist/capture/CaptureAudio.d.ts.map +1 -0
- package/dist/capture/CaptureAudio.js +106 -0
- package/dist/capture/CaptureManager.d.ts +12 -0
- package/dist/capture/CaptureManager.d.ts.map +1 -0
- package/dist/capture/CaptureManager.js +38 -0
- package/dist/capture/CaptureMidi.d.ts +13 -0
- package/dist/capture/CaptureMidi.d.ts.map +1 -0
- package/dist/capture/CaptureMidi.js +50 -0
- package/dist/capture/RecordAudio.d.ts +21 -0
- package/dist/capture/RecordAudio.d.ts.map +1 -0
- package/dist/capture/RecordAudio.js +66 -0
- package/dist/capture/RecordMidi.d.ts +15 -0
- package/dist/capture/RecordMidi.d.ts.map +1 -0
- package/dist/capture/RecordMidi.js +85 -0
- package/dist/capture/RecordTrack.d.ts +7 -0
- package/dist/capture/RecordTrack.d.ts.map +1 -0
- package/dist/capture/RecordTrack.js +23 -0
- package/dist/capture/Recording.d.ts +9 -0
- package/dist/capture/Recording.d.ts.map +1 -0
- package/dist/capture/Recording.js +65 -0
- package/dist/capture/RecordingContext.d.ts +14 -0
- package/dist/capture/RecordingContext.d.ts.map +1 -0
- package/dist/capture/RecordingContext.js +1 -0
- package/dist/dawproject/AudioUnitExportLayout.d.ts +10 -0
- package/dist/dawproject/AudioUnitExportLayout.d.ts.map +1 -0
- package/dist/dawproject/AudioUnitExportLayout.js +64 -0
- package/dist/dawproject/BuiltinDevices.d.ts +9 -0
- package/dist/dawproject/BuiltinDevices.d.ts.map +1 -0
- package/dist/dawproject/BuiltinDevices.js +70 -0
- package/dist/dawproject/DawProject.d.ts +22 -0
- package/dist/dawproject/DawProject.d.ts.map +1 -0
- package/dist/dawproject/DawProject.js +49 -0
- package/dist/dawproject/DawProjectExporter.d.ts +9 -0
- package/dist/dawproject/DawProjectExporter.d.ts.map +1 -0
- package/dist/dawproject/DawProjectExporter.js +252 -0
- package/dist/dawproject/DawProjectExporter.test.d.ts +2 -0
- package/dist/dawproject/DawProjectExporter.test.d.ts.map +1 -0
- package/dist/dawproject/DawProjectExporter.test.js +49 -0
- package/dist/dawproject/DawProjectImport.d.ts +12 -0
- package/dist/dawproject/DawProjectImport.d.ts.map +1 -0
- package/dist/dawproject/DawProjectImport.js +389 -0
- package/dist/dawproject/DawProjectImport.test.d.ts +2 -0
- package/dist/dawproject/DawProjectImport.test.d.ts.map +1 -0
- package/dist/dawproject/DawProjectImport.test.js +15 -0
- package/dist/dawproject/DeviceIO.d.ts +8 -0
- package/dist/dawproject/DeviceIO.d.ts.map +1 -0
- package/dist/dawproject/DeviceIO.js +63 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/processors.js +3 -3
- package/dist/processors.js.map +4 -4
- package/dist/samples/MainThreadSampleLoader.d.ts +1 -0
- package/dist/samples/MainThreadSampleLoader.d.ts.map +1 -1
- package/dist/samples/MainThreadSampleLoader.js +10 -6
- package/dist/samples/MainThreadSampleManager.d.ts +5 -5
- package/dist/samples/MainThreadSampleManager.d.ts.map +1 -1
- package/dist/samples/MainThreadSampleManager.js +1 -0
- package/dist/samples/SampleProvider.d.ts +2 -2
- package/dist/samples/SampleProvider.d.ts.map +1 -1
- package/dist/samples/SampleStorage.d.ts.map +1 -1
- package/dist/samples/SampleStorage.js +2 -3
- package/dist/workers.js +2 -2
- package/dist/workers.js.map +4 -4
- package/package.json +17 -17
- package/dist/DawProjectIO.d.ts +0 -7
- package/dist/DawProjectIO.d.ts.map +0 -1
- package/dist/DawProjectIO.js +0 -73
- package/dist/samples/SamplePeaks.d.ts +0 -6
- package/dist/samples/SamplePeaks.d.ts.map +0 -1
- package/dist/samples/SamplePeaks.js +0 -9
package/dist/Project.js
CHANGED
@@ -7,7 +7,7 @@ import { AudioUnitType } from "@opendaw/studio-enums";
|
|
7
7
|
import { Mixer } from "./Mixer";
|
8
8
|
import { ProjectApi } from "./ProjectApi";
|
9
9
|
import { ProjectMigration } from "./ProjectMigration";
|
10
|
-
import {
|
10
|
+
import { CaptureManager } from "./capture/CaptureManager";
|
11
11
|
// Main Entry Point for a Project
|
12
12
|
//
|
13
13
|
export class Project {
|
@@ -54,6 +54,10 @@ export class Project {
|
|
54
54
|
ProjectMigration.migrate(skeleton);
|
55
55
|
return new Project(env, skeleton.boxGraph, skeleton.mandatoryBoxes);
|
56
56
|
}
|
57
|
+
static skeleton(env, skeleton) {
|
58
|
+
ProjectMigration.migrate(skeleton);
|
59
|
+
return new Project(env, skeleton.boxGraph, skeleton.mandatoryBoxes);
|
60
|
+
}
|
57
61
|
#terminator = new Terminator();
|
58
62
|
#env;
|
59
63
|
boxGraph;
|
@@ -63,6 +67,7 @@ export class Project {
|
|
63
67
|
masterAudioUnit;
|
64
68
|
timelineBox;
|
65
69
|
api;
|
70
|
+
captureManager;
|
66
71
|
editing;
|
67
72
|
selection;
|
68
73
|
boxAdapters;
|
@@ -78,8 +83,8 @@ export class Project {
|
|
78
83
|
this.masterBusBox = masterBusBox;
|
79
84
|
this.masterAudioUnit = masterAudioUnit;
|
80
85
|
this.timelineBox = timelineBox;
|
81
|
-
this.liveStreamReceiver = this.#terminator.own(new LiveStreamReceiver());
|
82
86
|
this.api = new ProjectApi(this);
|
87
|
+
this.captureManager = this.#terminator.own(new CaptureManager(this));
|
83
88
|
this.editing = new Editing(this.boxGraph);
|
84
89
|
this.selection = new VertexSelection(this.editing, this.boxGraph);
|
85
90
|
this.parameterFieldAdapters = new ParameterFieldAdapters();
|
@@ -87,20 +92,34 @@ export class Project {
|
|
87
92
|
this.userEditingManager = new UserEditingManager(this.editing);
|
88
93
|
this.userEditingManager.follow(this.userInterfaceBox);
|
89
94
|
this.selection.switch(this.userInterfaceBox.selection);
|
95
|
+
this.liveStreamReceiver = this.#terminator.own(new LiveStreamReceiver());
|
90
96
|
this.mixer = new Mixer(this.rootBoxAdapter.audioUnits);
|
91
97
|
console.debug(`Project was created on ${this.rootBoxAdapter.created.toString()}`);
|
92
98
|
}
|
93
99
|
own(terminable) { return this.#terminator.own(terminable); }
|
94
100
|
ownAll(...terminables) { return this.#terminator.ownAll(...terminables); }
|
95
101
|
spawn() { return this.#terminator.spawn(); }
|
102
|
+
get env() { return this.#env; }
|
96
103
|
get bpm() { return this.timelineBox.bpm.getValue(); }
|
97
104
|
get rootBoxAdapter() { return this.boxAdapters.adapterFor(this.rootBox, RootBoxAdapter); }
|
98
105
|
get timelineBoxAdapter() { return this.boxAdapters.adapterFor(this.timelineBox, TimelineBoxAdapter); }
|
99
|
-
get
|
106
|
+
get sampleManager() { return this.#env.sampleManager; }
|
100
107
|
get clipSequencing() { return panic("Only available in audio context"); }
|
101
108
|
get isAudioContext() { return false; }
|
102
109
|
get isMainThread() { return true; }
|
103
110
|
get liveStreamBroadcaster() { return panic("Only available in audio context"); }
|
111
|
+
get skeleton() {
|
112
|
+
return {
|
113
|
+
boxGraph: this.boxGraph,
|
114
|
+
mandatoryBoxes: {
|
115
|
+
rootBox: this.rootBox,
|
116
|
+
timelineBox: this.timelineBox,
|
117
|
+
masterBusBox: this.masterBusBox,
|
118
|
+
masterAudioUnit: this.masterAudioUnit,
|
119
|
+
userInterfaceBox: this.userInterfaceBox
|
120
|
+
}
|
121
|
+
};
|
122
|
+
}
|
104
123
|
toArrayBuffer() {
|
105
124
|
const output = ByteArrayOutput.create();
|
106
125
|
output.writeInt(ProjectDecoder.MAGIC_HEADER_OPEN);
|
@@ -119,5 +138,4 @@ export class Project {
|
|
119
138
|
}
|
120
139
|
copy() { return Project.load(this.#env, this.toArrayBuffer()); }
|
121
140
|
terminate() { this.#terminator.terminate(); }
|
122
|
-
toDawProject() { return DawProjectIO.encode(this); }
|
123
141
|
}
|
package/dist/ProjectApi.d.ts
CHANGED
@@ -39,7 +39,6 @@ export type NoteRegionParams = {
|
|
39
39
|
};
|
40
40
|
export declare class ProjectApi {
|
41
41
|
#private;
|
42
|
-
static readonly AudioUnitOrdering: Record<string, int>;
|
43
42
|
constructor(project: Project);
|
44
43
|
setBpm(value: number): void;
|
45
44
|
catchupAndSubscribeBpm(observer: Observer<number>): Subscription;
|
package/dist/ProjectApi.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ProjectApi.d.ts","sourceRoot":"","sources":["../src/ProjectApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,EACL,GAAG,EACH,QAAQ,EACR,MAAM,EAEN,YAAY,EAEf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,IAAI,EAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,
|
1
|
+
{"version":3,"file":"ProjectApi.d.ts","sourceRoot":"","sources":["../src/ProjectApi.ts"],"names":[],"mappings":"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"}
|
package/dist/ProjectApi.js
CHANGED
@@ -2,17 +2,12 @@ import { asDefined, asInstanceOf, assert, clamp, Option, Strings, UUID } from "@
|
|
2
2
|
import { PPQN } from "@opendaw/lib-dsp";
|
3
3
|
import { IndexedBox, StringField } from "@opendaw/lib-box";
|
4
4
|
import { AudioUnitType } from "@opendaw/studio-enums";
|
5
|
-
import { AudioBusBox, AudioUnitBox, NoteClipBox, NoteEventBox, NoteEventCollectionBox, NoteRegionBox, TrackBox, ValueClipBox, ValueEventCollectionBox, ValueRegionBox } from "@opendaw/studio-boxes";
|
5
|
+
import { AudioBusBox, AudioUnitBox, CaptureAudioBox, CaptureMidiBox, NoteClipBox, NoteEventBox, NoteEventCollectionBox, NoteRegionBox, TrackBox, ValueClipBox, ValueEventCollectionBox, ValueRegionBox } from "@opendaw/studio-boxes";
|
6
6
|
import { IconSymbol, TrackType } from "@opendaw/studio-adapters";
|
7
7
|
import { ColorCodes } from "./ColorCodes";
|
8
|
+
import { AudioUnitOrdering } from "./AudioUnitOrdering";
|
8
9
|
// noinspection JSUnusedGlobalSymbols
|
9
10
|
export class ProjectApi {
|
10
|
-
static AudioUnitOrdering = {
|
11
|
-
[AudioUnitType.Instrument]: 0,
|
12
|
-
[AudioUnitType.Aux]: 1,
|
13
|
-
[AudioUnitType.Bus]: 2,
|
14
|
-
[AudioUnitType.Output]: 3
|
15
|
-
};
|
16
11
|
#project;
|
17
12
|
constructor(project) { this.#project = project; }
|
18
13
|
setBpm(value) {
|
@@ -34,7 +29,7 @@ export class ProjectApi {
|
|
34
29
|
const inputBox = asDefined(asInstanceOf(box, AudioUnitBox).input.pointerHub.incoming().at(0)).box;
|
35
30
|
return "label" in inputBox && inputBox.label instanceof StringField ? inputBox.label.getValue() : "N/A";
|
36
31
|
});
|
37
|
-
const audioUnitBox = this.#createAudioUnit(AudioUnitType.Instrument, index);
|
32
|
+
const audioUnitBox = this.#createAudioUnit(AudioUnitType.Instrument, this.#trackTypeToCapture(boxGraph, trackType), index);
|
38
33
|
const uniqueName = Strings.getUniqueName(existingNames, name ?? defaultName);
|
39
34
|
const iconSymbol = icon ?? defaultIcon;
|
40
35
|
const instrumentBox = create(boxGraph, audioUnitBox.input, uniqueName, iconSymbol);
|
@@ -58,7 +53,7 @@ export class ProjectApi {
|
|
58
53
|
box.icon.setValue(IconSymbol.toName(icon));
|
59
54
|
box.color.setValue(color);
|
60
55
|
});
|
61
|
-
const audioUnitBox = this.#createAudioUnit(type);
|
56
|
+
const audioUnitBox = this.#createAudioUnit(type, Option.None);
|
62
57
|
TrackBox.create(boxGraph, UUID.generate(), box => {
|
63
58
|
box.tracks.refer(audioUnitBox.tracks);
|
64
59
|
box.target.refer(audioUnitBox);
|
@@ -182,7 +177,7 @@ export class ProjectApi {
|
|
182
177
|
IndexedBox.removeOrder(rootBox.audioUnits, audioUnitBox.index.getValue());
|
183
178
|
audioUnitBox.delete();
|
184
179
|
}
|
185
|
-
#createAudioUnit(type, index) {
|
180
|
+
#createAudioUnit(type, capture, index) {
|
186
181
|
const { boxGraph, rootBox, masterBusBox } = this.#project;
|
187
182
|
const insertIndex = index ?? this.#sortAudioUnitOrdering(type);
|
188
183
|
console.debug(`createAudioUnit type: ${type}, insertIndex: ${insertIndex}`);
|
@@ -191,6 +186,7 @@ export class ProjectApi {
|
|
191
186
|
box.output.refer(masterBusBox.input);
|
192
187
|
box.index.setValue(insertIndex);
|
193
188
|
box.type.setValue(type);
|
189
|
+
capture.ifSome(capture => box.capture.refer(capture));
|
194
190
|
});
|
195
191
|
}
|
196
192
|
#createTrack({ field, target, trackType, insertIndex }) {
|
@@ -203,7 +199,6 @@ export class ProjectApi {
|
|
203
199
|
});
|
204
200
|
}
|
205
201
|
#sortAudioUnitOrdering(type) {
|
206
|
-
const { AudioUnitOrdering } = ProjectApi;
|
207
202
|
const { rootBox } = this.#project;
|
208
203
|
const boxes = IndexedBox.collectIndexedBoxes(rootBox.audioUnits, AudioUnitBox);
|
209
204
|
const order = AudioUnitOrdering[type];
|
@@ -219,4 +214,14 @@ export class ProjectApi {
|
|
219
214
|
}
|
220
215
|
return insertIndex;
|
221
216
|
}
|
217
|
+
#trackTypeToCapture(boxGraph, trackType) {
|
218
|
+
switch (trackType) {
|
219
|
+
case TrackType.Audio:
|
220
|
+
return Option.wrap(CaptureAudioBox.create(boxGraph, UUID.generate()));
|
221
|
+
case TrackType.Notes:
|
222
|
+
return Option.wrap(CaptureMidiBox.create(boxGraph, UUID.generate()));
|
223
|
+
default:
|
224
|
+
return Option.None;
|
225
|
+
}
|
226
|
+
}
|
222
227
|
}
|
package/dist/ProjectEnv.d.ts
CHANGED
package/dist/ProjectEnv.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ProjectEnv.d.ts","sourceRoot":"","sources":["../src/ProjectEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAA;AAEtD,MAAM,WAAW,UAAU;IACvB,aAAa,EAAE,aAAa,CAAA;CAC/B"}
|
1
|
+
{"version":3,"file":"ProjectEnv.d.ts","sourceRoot":"","sources":["../src/ProjectEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAA;AAEtD,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,aAAa,CAAA;CAC/B"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../src/ProjectMigration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,0BAA0B,CAAA;
|
1
|
+
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../src/ProjectMigration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,0BAA0B,CAAA;AAevD,qBAAa,gBAAgB;IACzB,MAAM,CAAC,OAAO,CAAC,EAAC,QAAQ,EAAE,cAAc,EAAC,EAAE,cAAc,CAAC,QAAQ,GAAG,IAAI;CAoE5E"}
|
package/dist/ProjectMigration.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
import { GrooveShuffleBox, ValueEventCurveBox } from "@opendaw/studio-boxes";
|
2
|
-
import { asInstanceOf, UUID } from "@opendaw/lib-std";
|
1
|
+
import { CaptureAudioBox, CaptureMidiBox, GrooveShuffleBox, ValueEventCurveBox } from "@opendaw/studio-boxes";
|
2
|
+
import { asDefined, asInstanceOf, UUID } from "@opendaw/lib-std";
|
3
|
+
import { AudioUnitType } from "@opendaw/studio-enums";
|
3
4
|
export class ProjectMigration {
|
4
5
|
static migrate({ boxGraph, mandatoryBoxes }) {
|
5
6
|
const { rootBox } = mandatoryBoxes;
|
@@ -16,7 +17,8 @@ export class ProjectMigration {
|
|
16
17
|
boxGraph.endTransaction();
|
17
18
|
}
|
18
19
|
// TODO We can remove this when we delete all not-migrated, local(!) project files from my machine
|
19
|
-
|
20
|
+
// We need to run on a copy, because we might add more boxes during the migration
|
21
|
+
boxGraph.boxes().slice().forEach(box => box.accept({
|
20
22
|
visitZeitgeistDeviceBox: (box) => {
|
21
23
|
if (box.groove.targetAddress.isEmpty()) {
|
22
24
|
console.debug("Migrate 'ZeitgeistDeviceBox' to GrooveShuffleBox");
|
@@ -54,6 +56,21 @@ export class ProjectMigration {
|
|
54
56
|
boxGraph.endTransaction();
|
55
57
|
}
|
56
58
|
}
|
59
|
+
},
|
60
|
+
visitAudioUnitBox: (box) => {
|
61
|
+
if (box.type.getValue() !== AudioUnitType.Instrument || box.capture.nonEmpty()) {
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
boxGraph.beginTransaction();
|
65
|
+
const captureBox = asDefined(box.input.pointerHub.incoming().at(0)?.box
|
66
|
+
.accept({
|
67
|
+
visitVaporisateurDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
68
|
+
visitNanoDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
69
|
+
visitPlayfieldDeviceBox: () => CaptureMidiBox.create(boxGraph, UUID.generate()),
|
70
|
+
visitTapeDeviceBox: () => CaptureAudioBox.create(boxGraph, UUID.generate())
|
71
|
+
}));
|
72
|
+
box.capture.refer(captureBox);
|
73
|
+
boxGraph.endTransaction();
|
57
74
|
}
|
58
75
|
}));
|
59
76
|
}
|
@@ -1,6 +1,18 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { int, Observer, Option, Subscription, Terminable, UUID } from "@opendaw/lib-std";
|
2
|
+
import { AudioData, RingBuffer, SampleLoader, SampleLoaderState } from "@opendaw/studio-adapters";
|
3
|
+
import { Peaks } from "@opendaw/lib-fusion";
|
4
|
+
export declare class RecordingWorklet extends AudioWorkletNode implements Terminable, SampleLoader {
|
3
5
|
#private;
|
4
|
-
|
6
|
+
readonly uuid: UUID.Format;
|
7
|
+
constructor(context: BaseAudioContext, config: RingBuffer.Config, outputLatency: number);
|
8
|
+
get numberOfFrames(): int;
|
9
|
+
get data(): Option<AudioData>;
|
10
|
+
get peaks(): Option<Peaks>;
|
11
|
+
get state(): SampleLoaderState;
|
12
|
+
invalidate(): void;
|
13
|
+
subscribe(observer: Observer<SampleLoaderState>): Subscription;
|
14
|
+
finalize(): Promise<void>;
|
15
|
+
terminate(): void;
|
16
|
+
toString(): string;
|
5
17
|
}
|
6
18
|
//# sourceMappingURL=RecordingWorklet.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RecordingWorklet.d.ts","sourceRoot":"","sources":["../src/RecordingWorklet.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"RecordingWorklet.d.ts","sourceRoot":"","sources":["../src/RecordingWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,GAAG,EAIH,QAAQ,EACR,MAAM,EAEN,YAAY,EACZ,UAAU,EACV,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACH,SAAS,EAET,UAAU,EACV,YAAY,EACZ,iBAAiB,EAEpB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,KAAK,EAAgC,MAAM,qBAAqB,CAAA;AA2CxE,qBAAa,gBAAiB,SAAQ,gBAAiB,YAAW,UAAU,EAAE,YAAY;;IACtF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAkB;gBAahC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM;IAgCvF,IAAI,cAAc,IAAI,GAAG,CAA6C;IACtE,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAoB;IACjD,IAAI,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAqB;IAC/C,IAAI,KAAK,IAAI,iBAAiB,CAAqB;IAEnD,UAAU,IAAI,IAAI;IAElB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,YAAY;IAQxD,QAAQ;IAyBd,SAAS,IAAI,IAAI;IAKjB,QAAQ,IAAI,MAAM;CAMrB"}
|
package/dist/RecordingWorklet.js
CHANGED
@@ -1,31 +1,126 @@
|
|
1
|
-
import {
|
2
|
-
import { Files } from "@opendaw/lib-dom";
|
1
|
+
import { Arrays, assert, ByteArrayInput, isUndefined, Notifier, Option, Progress, Terminable, UUID } from "@opendaw/lib-std";
|
3
2
|
import { mergeChunkPlanes, RingBuffer } from "@opendaw/studio-adapters";
|
4
|
-
import {
|
3
|
+
import { SamplePeaks, SamplePeakWorker } from "@opendaw/lib-fusion";
|
5
4
|
import { RenderQuantum } from "./RenderQuantum";
|
5
|
+
import { WorkerAgents } from "./WorkerAgents";
|
6
|
+
import { SampleStorage } from "./samples/SampleStorage";
|
7
|
+
import { BPMTools } from "@opendaw/lib-dsp";
|
8
|
+
class PeaksWriter {
|
9
|
+
numChannels;
|
10
|
+
data;
|
11
|
+
stages;
|
12
|
+
dataOffset = 0;
|
13
|
+
shift = 7;
|
14
|
+
dataIndex;
|
15
|
+
numFrames = 0 | 0;
|
16
|
+
constructor(numChannels) {
|
17
|
+
this.numChannels = numChannels;
|
18
|
+
this.data = Arrays.create(() => new Int32Array(1 << 20), numChannels); // TODO auto-resize
|
19
|
+
this.dataIndex = new Int32Array(numChannels);
|
20
|
+
this.stages = [this];
|
21
|
+
}
|
22
|
+
get numPeaks() { return Math.ceil(this.numFrames / (1 << this.shift)); }
|
23
|
+
unitsEachPeak() { return 1 << this.shift; }
|
24
|
+
append(frames) {
|
25
|
+
for (let channel = 0; channel < this.numChannels; ++channel) {
|
26
|
+
const channelFrames = frames[channel];
|
27
|
+
assert(channelFrames.length === RenderQuantum, "Invalid number of frames.");
|
28
|
+
let min = Number.POSITIVE_INFINITY;
|
29
|
+
let max = Number.NEGATIVE_INFINITY;
|
30
|
+
for (let i = 0; i < RenderQuantum; ++i) {
|
31
|
+
const frame = channelFrames[i];
|
32
|
+
min = Math.min(frame, min);
|
33
|
+
max = Math.max(frame, max);
|
34
|
+
}
|
35
|
+
this.data[channel][this.dataIndex[channel]++] = SamplePeakWorker.pack(min, max);
|
36
|
+
}
|
37
|
+
this.numFrames += RenderQuantum;
|
38
|
+
}
|
39
|
+
nearest(_unitsPerPixel) { return this.stages.at(0) ?? null; }
|
40
|
+
}
|
6
41
|
export class RecordingWorklet extends AudioWorkletNode {
|
42
|
+
uuid = UUID.generate();
|
43
|
+
#output;
|
44
|
+
#notifier;
|
7
45
|
#reader;
|
8
|
-
|
46
|
+
#peakWriter;
|
47
|
+
#data = Option.None;
|
48
|
+
#peaks = Option.None;
|
49
|
+
#isRecording = true;
|
50
|
+
#truncateLatency;
|
51
|
+
#state = { type: "record" };
|
52
|
+
constructor(context, config, outputLatency) {
|
9
53
|
super(context, "recording-processor", {
|
10
54
|
numberOfInputs: 1,
|
11
55
|
channelCount: config.numberOfChannels,
|
12
56
|
channelCountMode: "explicit",
|
13
57
|
processorOptions: config
|
14
58
|
});
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
59
|
+
if (isUndefined(outputLatency)) {
|
60
|
+
// TODO Talk to the user
|
61
|
+
console.warn("outputLatency is undefined. Please use Chrome.");
|
62
|
+
}
|
63
|
+
this.#peakWriter = new PeaksWriter(config.numberOfChannels);
|
64
|
+
this.#truncateLatency = Math.floor((outputLatency ?? 0) * this.context.sampleRate / RenderQuantum);
|
65
|
+
this.#output = [];
|
66
|
+
this.#notifier = new Notifier();
|
20
67
|
this.#reader = RingBuffer.reader(config, array => {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
68
|
+
if (this.#isRecording) {
|
69
|
+
if (this.#truncateLatency === 0) {
|
70
|
+
this.#output.push(array);
|
71
|
+
this.#peakWriter.append(array);
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
if (--this.#truncateLatency === 0) {
|
75
|
+
this.#peaks = Option.wrap(this.#peakWriter);
|
76
|
+
}
|
77
|
+
}
|
28
78
|
}
|
29
79
|
});
|
30
80
|
}
|
81
|
+
get numberOfFrames() { return this.#output.length * RenderQuantum; }
|
82
|
+
get data() { return this.#data; }
|
83
|
+
get peaks() { return this.#peaks; }
|
84
|
+
get state() { return this.#state; }
|
85
|
+
invalidate() { }
|
86
|
+
subscribe(observer) {
|
87
|
+
if (this.#state.type === "loaded") {
|
88
|
+
observer(this.#state);
|
89
|
+
return Terminable.Empty;
|
90
|
+
}
|
91
|
+
return this.#notifier.subscribe(observer);
|
92
|
+
}
|
93
|
+
async finalize() {
|
94
|
+
this.#reader.stop();
|
95
|
+
this.#isRecording = false;
|
96
|
+
const sample_rate = this.context.sampleRate;
|
97
|
+
const numberOfFrames = this.#output.length * RenderQuantum;
|
98
|
+
const numberOfChannels = this.channelCount;
|
99
|
+
const frames = mergeChunkPlanes(this.#output, RenderQuantum, numberOfFrames);
|
100
|
+
const audioData = {
|
101
|
+
sampleRate: sample_rate,
|
102
|
+
numberOfChannels,
|
103
|
+
numberOfFrames,
|
104
|
+
frames
|
105
|
+
};
|
106
|
+
this.#data = Option.wrap(audioData);
|
107
|
+
const shifts = SamplePeaks.findBestFit(numberOfFrames);
|
108
|
+
const peaks = await WorkerAgents
|
109
|
+
.Peak.generateAsync(Progress.Empty, shifts, frames, numberOfFrames, numberOfChannels);
|
110
|
+
this.#peaks = Option.wrap(SamplePeaks.from(new ByteArrayInput(peaks)));
|
111
|
+
const bpm = BPMTools.detect(frames[0], sample_rate);
|
112
|
+
const duration = numberOfFrames / sample_rate;
|
113
|
+
const meta = { name: "Recording", bpm, sample_rate, duration };
|
114
|
+
await SampleStorage.store(this.uuid, audioData, peaks, meta);
|
115
|
+
this.#setState({ type: "loaded" });
|
116
|
+
}
|
117
|
+
terminate() {
|
118
|
+
this.#reader.stop();
|
119
|
+
this.#isRecording = false;
|
120
|
+
}
|
121
|
+
toString() { return `{RecordingWorklet}`; }
|
122
|
+
#setState(value) {
|
123
|
+
this.#state = value;
|
124
|
+
this.#notifier.notify(this.#state);
|
125
|
+
}
|
31
126
|
}
|
package/dist/WorkerAgents.d.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import { Option } from "@opendaw/lib-std";
|
2
|
-
import type { OpfsProtocol,
|
2
|
+
import type { OpfsProtocol, SamplePeakProtocol } from "@opendaw/lib-fusion";
|
3
3
|
import { Messenger } from "@opendaw/lib-runtime";
|
4
4
|
export declare class WorkerAgents {
|
5
5
|
static install(workerURL: string): void;
|
6
6
|
static messenger: Option<Messenger>;
|
7
|
-
static get Peak():
|
7
|
+
static get Peak(): SamplePeakProtocol;
|
8
8
|
static get Opfs(): OpfsProtocol;
|
9
9
|
}
|
10
10
|
//# sourceMappingURL=WorkerAgents.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"WorkerAgents.d.ts","sourceRoot":"","sources":["../src/WorkerAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,MAAM,EAAY,MAAM,kBAAkB,CAAA;AACzE,OAAO,KAAK,EAAC,YAAY,EAAE,
|
1
|
+
{"version":3,"file":"WorkerAgents.d.ts","sourceRoot":"","sources":["../src/WorkerAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,MAAM,EAAY,MAAM,kBAAkB,CAAA;AACzE,OAAO,KAAK,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAEzE,OAAO,EAAe,SAAS,EAAC,MAAM,sBAAsB,CAAA;AAE5D,qBAAa,YAAY;IACrB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKvC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAc;IAGjD,MAAM,KAAK,IAAI,IAAI,kBAAkB,CAapC;IAGD,MAAM,KAAK,IAAI,IAAI,YAAY,CAS9B;CACJ"}
|
package/dist/Worklets.d.ts
CHANGED
@@ -11,6 +11,6 @@ export declare class Worklets {
|
|
11
11
|
constructor(context: BaseAudioContext);
|
12
12
|
createMeter(numberOfChannels: int): MeterWorklet;
|
13
13
|
createEngine(project: Project, exportConfiguration?: ExportStemsConfiguration): EngineWorklet;
|
14
|
-
createRecording(numberOfChannels: int, numChunks: int): RecordingWorklet;
|
14
|
+
createRecording(numberOfChannels: int, numChunks: int, outputLatency: number): RecordingWorklet;
|
15
15
|
}
|
16
16
|
//# sourceMappingURL=Worklets.d.ts.map
|
package/dist/Worklets.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Worklets.d.ts","sourceRoot":"","sources":["../src/Worklets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAC,wBAAwB,EAAa,MAAM,0BAA0B,CAAA;AAC7E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAGjC,qBAAa,QAAQ;;WACJ,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQtF,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ;gBAMnC,OAAO,EAAE,gBAAgB;IAErC,WAAW,CAAC,gBAAgB,EAAE,GAAG,GAAG,YAAY;IAIhD,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,wBAAwB,GAAG,aAAa;IAI7F,eAAe,CAAC,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,GAAG,gBAAgB;
|
1
|
+
{"version":3,"file":"Worklets.d.ts","sourceRoot":"","sources":["../src/Worklets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAC,wBAAwB,EAAa,MAAM,0BAA0B,CAAA;AAC7E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAGjC,qBAAa,QAAQ;;WACJ,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQtF,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,GAAG,QAAQ;gBAMnC,OAAO,EAAE,gBAAgB;IAErC,WAAW,CAAC,gBAAgB,EAAE,GAAG,GAAG,YAAY;IAIhD,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,wBAAwB,GAAG,aAAa;IAI7F,eAAe,CAAC,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,GAAG,gBAAgB;CAOlG"}
|
package/dist/Worklets.js
CHANGED
@@ -21,11 +21,11 @@ export class Worklets {
|
|
21
21
|
createEngine(project, exportConfiguration) {
|
22
22
|
return new EngineWorklet(this.#context, project, exportConfiguration);
|
23
23
|
}
|
24
|
-
createRecording(numberOfChannels, numChunks) {
|
24
|
+
createRecording(numberOfChannels, numChunks, outputLatency) {
|
25
25
|
const audioBytes = numberOfChannels * numChunks * RenderQuantum * Float32Array.BYTES_PER_ELEMENT;
|
26
26
|
const pointerBytes = Int32Array.BYTES_PER_ELEMENT * 2;
|
27
27
|
const sab = new SharedArrayBuffer(audioBytes + pointerBytes);
|
28
28
|
const buffer = { sab, numChunks, numberOfChannels, bufferSize: RenderQuantum };
|
29
|
-
return new RecordingWorklet(this.#context, buffer);
|
29
|
+
return new RecordingWorklet(this.#context, buffer, outputLatency);
|
30
30
|
}
|
31
31
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { MutableObservableValue, Option, Terminable, UUID } from "@opendaw/lib-std";
|
2
|
+
import { AudioUnitBox } from "@opendaw/studio-boxes";
|
3
|
+
import { CaptureBox } from "@opendaw/studio-adapters";
|
4
|
+
import { RecordingContext } from "./RecordingContext";
|
5
|
+
import { CaptureManager } from "./CaptureManager";
|
6
|
+
export declare abstract class Capture<BOX extends CaptureBox = CaptureBox> implements Terminable {
|
7
|
+
#private;
|
8
|
+
protected constructor(manager: CaptureManager, audioUnitBox: AudioUnitBox, captureBox: BOX);
|
9
|
+
abstract prepareRecording(context: RecordingContext): Promise<void>;
|
10
|
+
abstract startRecording(context: RecordingContext): Terminable;
|
11
|
+
abstract get deviceLabel(): Option<string>;
|
12
|
+
get uuid(): UUID.Format;
|
13
|
+
get manager(): CaptureManager;
|
14
|
+
get audioUnitBox(): AudioUnitBox;
|
15
|
+
get captureBox(): BOX;
|
16
|
+
get armed(): MutableObservableValue<boolean>;
|
17
|
+
get deviceId(): MutableObservableValue<Option<string>>;
|
18
|
+
own<T extends Terminable>(terminable: T): T;
|
19
|
+
ownAll<T extends Terminable>(...terminables: ReadonlyArray<T>): void;
|
20
|
+
terminate(): void;
|
21
|
+
}
|
22
|
+
//# sourceMappingURL=Capture.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Capture.d.ts","sourceRoot":"","sources":["../../src/capture/Capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,sBAAsB,EACtB,MAAM,EACN,UAAU,EAEV,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAEnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAE/C,8BAAsB,OAAO,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU,CAAE,YAAW,UAAU;;IAUpF,SAAS,aAAa,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG;IAmB1F,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IACnE,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,UAAU;IAC9D,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;IAE1C,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAyC;IAChE,IAAI,OAAO,IAAI,cAAc,CAAuB;IACpD,IAAI,YAAY,IAAI,YAAY,CAA4B;IAC5D,IAAI,UAAU,IAAI,GAAG,CAA0B;IAC/C,IAAI,KAAK,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAqB;IACjE,IAAI,QAAQ,IAAI,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAwB;IAE9E,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC;IAC3C,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IACpE,SAAS,IAAI,IAAI;CACpB"}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { DefaultObservableValue, MappedMutableObservableValue, Option, Terminator } from "@opendaw/lib-std";
|
2
|
+
export class Capture {
|
3
|
+
#terminator = new Terminator();
|
4
|
+
#manager;
|
5
|
+
#audioUnitBox;
|
6
|
+
#captureBox;
|
7
|
+
#deviceId;
|
8
|
+
#armed;
|
9
|
+
constructor(manager, audioUnitBox, captureBox) {
|
10
|
+
this.#manager = manager;
|
11
|
+
this.#audioUnitBox = audioUnitBox;
|
12
|
+
this.#captureBox = captureBox;
|
13
|
+
this.#deviceId = new MappedMutableObservableValue(captureBox.deviceId, {
|
14
|
+
fx: x => x.length > 0 ? Option.wrap(x) : Option.None,
|
15
|
+
fy: y => y.match({ none: () => "", some: x => x })
|
16
|
+
});
|
17
|
+
this.#armed = this.#terminator.own(new DefaultObservableValue(false));
|
18
|
+
this.#terminator.ownAll(this.#captureBox.deviceId.catchupAndSubscribe(owner => {
|
19
|
+
const id = owner.getValue();
|
20
|
+
this.#deviceId.setValue(id.length > 0 ? Option.wrap(id) : Option.None);
|
21
|
+
}));
|
22
|
+
}
|
23
|
+
get uuid() { return this.#audioUnitBox.address.uuid; }
|
24
|
+
get manager() { return this.#manager; }
|
25
|
+
get audioUnitBox() { return this.#audioUnitBox; }
|
26
|
+
get captureBox() { return this.#captureBox; }
|
27
|
+
get armed() { return this.#armed; }
|
28
|
+
get deviceId() { return this.#deviceId; }
|
29
|
+
own(terminable) { return this.#terminator.own(terminable); }
|
30
|
+
ownAll(...terminables) { this.#terminator.ownAll(...terminables); }
|
31
|
+
terminate() { this.#terminator.terminate(); }
|
32
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { ObservableOption, Option, Terminable } from "@opendaw/lib-std";
|
2
|
+
import { AudioUnitBox, CaptureAudioBox } from "@opendaw/studio-boxes";
|
3
|
+
import { Capture } from "./Capture";
|
4
|
+
import { RecordingContext } from "./RecordingContext";
|
5
|
+
import { CaptureManager } from "./CaptureManager";
|
6
|
+
export declare class CaptureAudio extends Capture<CaptureAudioBox> {
|
7
|
+
#private;
|
8
|
+
constructor(manager: CaptureManager, audioUnitBox: AudioUnitBox, captureBox: CaptureAudioBox);
|
9
|
+
get gainDb(): number;
|
10
|
+
get stream(): ObservableOption<MediaStream>;
|
11
|
+
get streamDeviceId(): Option<string>;
|
12
|
+
get deviceLabel(): Option<string>;
|
13
|
+
get streamMediaTrack(): Option<MediaStreamTrack>;
|
14
|
+
prepareRecording({}: RecordingContext): Promise<void>;
|
15
|
+
startRecording({ audioContext, worklets, project, engine, sampleManager }: RecordingContext): Terminable;
|
16
|
+
}
|
17
|
+
//# sourceMappingURL=CaptureAudio.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"CaptureAudio.d.ts","sourceRoot":"","sources":["../../src/capture/CaptureAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAO,MAAM,kBAAkB,CAAA;AACjH,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAI/C,qBAAa,YAAa,SAAQ,OAAO,CAAC,eAAe,CAAC;;gBAQ1C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe;IA4B5F,IAAI,MAAM,IAAI,MAAM,CAAsB;IAE1C,IAAI,MAAM,IAAI,gBAAgB,CAAC,WAAW,CAAC,CAAsB;IAEjE,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,CAEnC;IAED,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAEhC;IAED,IAAI,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAE/C;IAEK,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,cAAc,CAAC,EAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAC,EAAE,gBAAgB,GAAG,UAAU;CA6DzG"}
|