webcodecs-node 0.5.2 → 0.7.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.
- package/README.md +279 -0
- package/dist/backends/types.d.ts +2 -0
- package/dist/backends/types.d.ts.map +1 -1
- package/dist/backends/types.js.map +1 -1
- package/dist/canvas/canvas-utils.d.ts +115 -0
- package/dist/canvas/canvas-utils.d.ts.map +1 -0
- package/dist/canvas/canvas-utils.js +169 -0
- package/dist/canvas/canvas-utils.js.map +1 -0
- package/dist/canvas/frame-loop.d.ts +113 -0
- package/dist/canvas/frame-loop.d.ts.map +1 -0
- package/dist/canvas/frame-loop.js +291 -0
- package/dist/canvas/frame-loop.js.map +1 -0
- package/dist/canvas/gpu-context.d.ts +61 -0
- package/dist/canvas/gpu-context.d.ts.map +1 -0
- package/dist/canvas/gpu-context.js +134 -0
- package/dist/canvas/gpu-context.js.map +1 -0
- package/dist/canvas/index.d.ts +22 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +25 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/canvas/types.d.ts +101 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas/types.js +7 -0
- package/dist/canvas/types.js.map +1 -0
- package/dist/codec-utils/formats.d.ts.map +1 -1
- package/dist/codec-utils/formats.js +31 -0
- package/dist/codec-utils/formats.js.map +1 -1
- package/dist/config/ffmpeg-quality.d.ts +14 -0
- package/dist/config/ffmpeg-quality.d.ts.map +1 -0
- package/dist/config/ffmpeg-quality.js +41 -0
- package/dist/config/ffmpeg-quality.js.map +1 -0
- package/dist/containers/Muxer.d.ts.map +1 -1
- package/dist/containers/Muxer.js +4 -1
- package/dist/containers/Muxer.js.map +1 -1
- package/dist/core/AudioData.d.ts +2 -1
- package/dist/core/AudioData.d.ts.map +1 -1
- package/dist/core/AudioData.js.map +1 -1
- package/dist/core/VideoFrame.d.ts +2 -2
- package/dist/core/VideoFrame.d.ts.map +1 -1
- package/dist/core/VideoFrame.js +58 -48
- package/dist/core/VideoFrame.js.map +1 -1
- package/dist/decoders/AudioDecoder.d.ts +1 -0
- package/dist/decoders/AudioDecoder.d.ts.map +1 -1
- package/dist/decoders/AudioDecoder.js +39 -17
- package/dist/decoders/AudioDecoder.js.map +1 -1
- package/dist/decoders/ImageDecoder.d.ts +1 -0
- package/dist/decoders/ImageDecoder.d.ts.map +1 -1
- package/dist/decoders/ImageDecoder.js +40 -3
- package/dist/decoders/ImageDecoder.js.map +1 -1
- package/dist/decoders/VideoDecoder.d.ts +12 -0
- package/dist/decoders/VideoDecoder.d.ts.map +1 -1
- package/dist/decoders/VideoDecoder.js +56 -13
- package/dist/decoders/VideoDecoder.js.map +1 -1
- package/dist/demos/demo-1080p-transcode.js +8 -2
- package/dist/demos/demo-1080p-transcode.js.map +1 -1
- package/dist/demos/demo-audio-visualizer.d.ts +11 -0
- package/dist/demos/demo-audio-visualizer.d.ts.map +1 -0
- package/dist/demos/demo-audio-visualizer.js +281 -0
- package/dist/demos/demo-audio-visualizer.js.map +1 -0
- package/dist/demos/demo-dvd-logo.d.ts +8 -0
- package/dist/demos/demo-dvd-logo.d.ts.map +1 -0
- package/dist/demos/demo-dvd-logo.js +196 -0
- package/dist/demos/demo-dvd-logo.js.map +1 -0
- package/dist/demos/demo-four-corners.js +9 -0
- package/dist/demos/demo-four-corners.js.map +1 -1
- package/dist/demos/demo-streaming.js +6 -0
- package/dist/demos/demo-streaming.js.map +1 -1
- package/dist/demos/demo-webcodecs.js +1 -0
- package/dist/demos/demo-webcodecs.js.map +1 -1
- package/dist/encoders/AudioEncoder.d.ts +3 -0
- package/dist/encoders/AudioEncoder.d.ts.map +1 -1
- package/dist/encoders/AudioEncoder.js +70 -28
- package/dist/encoders/AudioEncoder.js.map +1 -1
- package/dist/encoders/ImageEncoder.d.ts +80 -0
- package/dist/encoders/ImageEncoder.d.ts.map +1 -0
- package/dist/encoders/ImageEncoder.js +156 -0
- package/dist/encoders/ImageEncoder.js.map +1 -0
- package/dist/encoders/VideoEncoder.d.ts +11 -0
- package/dist/encoders/VideoEncoder.d.ts.map +1 -1
- package/dist/encoders/VideoEncoder.js +58 -7
- package/dist/encoders/VideoEncoder.js.map +1 -1
- package/dist/encoders/index.d.ts +1 -0
- package/dist/encoders/index.d.ts.map +1 -1
- package/dist/encoders/index.js +1 -0
- package/dist/encoders/index.js.map +1 -1
- package/dist/formats/color-space.d.ts +94 -1
- package/dist/formats/color-space.d.ts.map +1 -1
- package/dist/formats/color-space.js +51 -1
- package/dist/formats/color-space.js.map +1 -1
- package/dist/formats/pixel-formats.d.ts +17 -1
- package/dist/formats/pixel-formats.d.ts.map +1 -1
- package/dist/formats/pixel-formats.js +74 -4
- package/dist/formats/pixel-formats.js.map +1 -1
- package/dist/hardware/detection.d.ts.map +1 -1
- package/dist/hardware/detection.js +5 -2
- package/dist/hardware/detection.js.map +1 -1
- package/dist/hardware/encoder-args.d.ts.map +1 -1
- package/dist/hardware/encoder-args.js +6 -6
- package/dist/hardware/encoder-args.js.map +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/node-av/NodeAvAudioDecoder.d.ts.map +1 -1
- package/dist/node-av/NodeAvAudioDecoder.js +3 -0
- package/dist/node-av/NodeAvAudioDecoder.js.map +1 -1
- package/dist/node-av/NodeAvAudioEncoder.d.ts +5 -0
- package/dist/node-av/NodeAvAudioEncoder.d.ts.map +1 -1
- package/dist/node-av/NodeAvAudioEncoder.js +102 -9
- package/dist/node-av/NodeAvAudioEncoder.js.map +1 -1
- package/dist/node-av/NodeAvVideoEncoder.d.ts +2 -0
- package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -1
- package/dist/node-av/NodeAvVideoEncoder.js +44 -6
- package/dist/node-av/NodeAvVideoEncoder.js.map +1 -1
- package/dist/node-av/WebPImageDecoder.d.ts +54 -0
- package/dist/node-av/WebPImageDecoder.d.ts.map +1 -0
- package/dist/node-av/WebPImageDecoder.js +176 -0
- package/dist/node-av/WebPImageDecoder.js.map +1 -0
- package/dist/polyfills/OffscreenCanvas.d.ts +141 -7
- package/dist/polyfills/OffscreenCanvas.d.ts.map +1 -1
- package/dist/polyfills/OffscreenCanvas.js +217 -17
- package/dist/polyfills/OffscreenCanvas.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/native-frame.d.ts +74 -0
- package/dist/types/native-frame.d.ts.map +1 -0
- package/dist/types/native-frame.js +32 -0
- package/dist/types/native-frame.js.map +1 -0
- package/dist/utils/codec-validation.d.ts +33 -0
- package/dist/utils/codec-validation.d.ts.map +1 -0
- package/dist/utils/codec-validation.js +247 -0
- package/dist/utils/codec-validation.js.map +1 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/type-guards.d.ts +29 -1
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/dist/utils/type-guards.js +47 -2
- package/dist/utils/type-guards.js.map +1 -1
- package/docs/api.md +155 -0
- package/docs/configuration.md +27 -0
- package/examples/README.md +28 -1
- package/examples/canvas-encoding.ts +222 -0
- package/examples/offscreen-canvas.ts +230 -0
- package/package.json +9 -3
|
@@ -1,35 +1,235 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OffscreenCanvas
|
|
2
|
+
* OffscreenCanvas Polyfill using skia-canvas
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Provides a Web-compatible OffscreenCanvas API for Node.js,
|
|
5
|
+
* making it easy to port browser code to Node.js.
|
|
6
|
+
*
|
|
7
|
+
* skia-canvas provides:
|
|
8
|
+
* - Metal acceleration on macOS
|
|
9
|
+
* - Vulkan acceleration on Linux/Windows
|
|
10
|
+
* - Automatic CPU fallback
|
|
11
|
+
*/
|
|
12
|
+
import { Canvas as SkiaCanvas } from 'skia-canvas';
|
|
13
|
+
import { VideoFrame } from '../core/VideoFrame.js';
|
|
14
|
+
/**
|
|
15
|
+
* ImageData polyfill compatible with skia-canvas
|
|
6
16
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
export class ImageDataPolyfill {
|
|
18
|
+
data;
|
|
19
|
+
width;
|
|
20
|
+
height;
|
|
21
|
+
colorSpace = 'srgb';
|
|
22
|
+
colorType = 'rgba'; // Required by skia-canvas
|
|
23
|
+
constructor(dataOrWidth, widthOrHeight, height) {
|
|
24
|
+
if (typeof dataOrWidth === 'number') {
|
|
25
|
+
this.width = dataOrWidth;
|
|
26
|
+
this.height = widthOrHeight;
|
|
27
|
+
this.data = new Uint8ClampedArray(this.width * this.height * 4);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
this.data = dataOrWidth;
|
|
31
|
+
this.width = widthOrHeight;
|
|
32
|
+
this.height = height ?? dataOrWidth.length / 4 / widthOrHeight;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Blob polyfill for convertToBlob
|
|
38
|
+
*/
|
|
39
|
+
class BlobPolyfill {
|
|
40
|
+
_buffer;
|
|
41
|
+
type;
|
|
42
|
+
size;
|
|
43
|
+
constructor(buffer, type) {
|
|
44
|
+
this._buffer = buffer;
|
|
45
|
+
this.type = type;
|
|
46
|
+
this.size = buffer.length;
|
|
47
|
+
}
|
|
48
|
+
async arrayBuffer() {
|
|
49
|
+
return this._buffer.buffer.slice(this._buffer.byteOffset, this._buffer.byteOffset + this._buffer.byteLength);
|
|
50
|
+
}
|
|
51
|
+
async text() {
|
|
52
|
+
return this._buffer.toString('utf-8');
|
|
53
|
+
}
|
|
54
|
+
stream() {
|
|
55
|
+
const buffer = this._buffer;
|
|
56
|
+
return new ReadableStream({
|
|
57
|
+
start(controller) {
|
|
58
|
+
controller.enqueue(new Uint8Array(buffer));
|
|
59
|
+
controller.close();
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
slice(start, end, contentType) {
|
|
64
|
+
const sliced = this._buffer.slice(start, end);
|
|
65
|
+
return new BlobPolyfill(sliced, contentType ?? this.type);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* OffscreenCanvas Polyfill
|
|
70
|
+
*
|
|
71
|
+
* Provides a Web-compatible OffscreenCanvas API using skia-canvas.
|
|
72
|
+
* This makes it easy to port browser canvas code to Node.js.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const canvas = new OffscreenCanvasPolyfill(1920, 1080);
|
|
77
|
+
* const ctx = canvas.getContext('2d');
|
|
78
|
+
* ctx.fillStyle = 'red';
|
|
79
|
+
* ctx.fillRect(0, 0, 1920, 1080);
|
|
80
|
+
*
|
|
81
|
+
* // Create VideoFrame for encoding
|
|
82
|
+
* const frame = new VideoFrame(canvas, { timestamp: 0 });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export class OffscreenCanvasPolyfill {
|
|
86
|
+
_canvas;
|
|
87
|
+
_ctx = null;
|
|
88
|
+
/**
|
|
89
|
+
* Create a new OffscreenCanvas with the specified dimensions
|
|
90
|
+
*/
|
|
91
|
+
constructor(width, height) {
|
|
92
|
+
this._canvas = new SkiaCanvas(width, height);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the width of the canvas
|
|
96
|
+
*/
|
|
97
|
+
get width() {
|
|
98
|
+
return this._canvas.width;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Set the width of the canvas (creates new internal canvas)
|
|
102
|
+
*/
|
|
103
|
+
set width(value) {
|
|
104
|
+
const height = this._canvas.height;
|
|
105
|
+
this._canvas = new SkiaCanvas(value, height);
|
|
106
|
+
this._ctx = null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the height of the canvas
|
|
110
|
+
*/
|
|
111
|
+
get height() {
|
|
112
|
+
return this._canvas.height;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set the height of the canvas (creates new internal canvas)
|
|
116
|
+
*/
|
|
117
|
+
set height(value) {
|
|
118
|
+
const width = this._canvas.width;
|
|
119
|
+
this._canvas = new SkiaCanvas(width, value);
|
|
120
|
+
this._ctx = null;
|
|
121
|
+
}
|
|
122
|
+
getContext(contextId, options) {
|
|
123
|
+
if (contextId === '2d') {
|
|
124
|
+
if (!this._ctx) {
|
|
125
|
+
this._ctx = this._canvas.getContext('2d');
|
|
126
|
+
}
|
|
127
|
+
return this._ctx;
|
|
128
|
+
}
|
|
129
|
+
// WebGL not supported
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Convert canvas content to a Blob
|
|
134
|
+
*
|
|
135
|
+
* @param options - Optional encoding options
|
|
136
|
+
* @returns Promise resolving to a Blob containing the image data
|
|
137
|
+
*/
|
|
138
|
+
async convertToBlob(options) {
|
|
139
|
+
const type = options?.type ?? 'image/png';
|
|
140
|
+
const quality = options?.quality ?? 0.92;
|
|
141
|
+
let format;
|
|
142
|
+
let mimeType;
|
|
143
|
+
if (type === 'image/jpeg' || type === 'image/jpg') {
|
|
144
|
+
format = 'jpg';
|
|
145
|
+
mimeType = 'image/jpeg';
|
|
146
|
+
}
|
|
147
|
+
else if (type === 'image/webp') {
|
|
148
|
+
format = 'webp';
|
|
149
|
+
mimeType = 'image/webp';
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
format = 'png';
|
|
153
|
+
mimeType = 'image/png';
|
|
154
|
+
}
|
|
155
|
+
const buffer = await this._canvas.toBuffer(format, {
|
|
156
|
+
quality,
|
|
157
|
+
});
|
|
158
|
+
return new BlobPolyfill(buffer, mimeType);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Transfer canvas content to an ImageBitmap
|
|
162
|
+
*
|
|
163
|
+
* Note: This creates a copy of the pixel data, as true zero-copy
|
|
164
|
+
* transfer is not possible in Node.js the same way as in browsers.
|
|
165
|
+
*
|
|
166
|
+
* @returns ImageBitmap-like object with the canvas content
|
|
167
|
+
*/
|
|
168
|
+
transferToImageBitmap() {
|
|
169
|
+
const pixels = this._getImageData();
|
|
170
|
+
return {
|
|
171
|
+
width: this._canvas.width,
|
|
172
|
+
height: this._canvas.height,
|
|
173
|
+
_data: pixels,
|
|
174
|
+
close: () => {
|
|
175
|
+
// No-op in Node.js
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get raw RGBA pixel data from canvas
|
|
181
|
+
* (Internal method for VideoFrame construction)
|
|
182
|
+
*/
|
|
183
|
+
_getImageData() {
|
|
184
|
+
const buffer = this._canvas.toBufferSync('raw', {
|
|
185
|
+
colorType: 'rgba',
|
|
186
|
+
});
|
|
187
|
+
return new Uint8ClampedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get the underlying skia-canvas Canvas
|
|
191
|
+
* (Non-standard, for advanced use cases)
|
|
192
|
+
*/
|
|
193
|
+
get _skiaCanvas() {
|
|
194
|
+
return this._canvas;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Enable/disable GPU acceleration
|
|
198
|
+
* (Non-standard, for performance tuning)
|
|
199
|
+
*/
|
|
200
|
+
get gpu() {
|
|
201
|
+
return this._canvas.gpu;
|
|
202
|
+
}
|
|
203
|
+
set gpu(value) {
|
|
204
|
+
this._canvas.gpu = value;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Re-export core VideoFrame as VideoFramePolyfill for compatibility
|
|
208
|
+
export { VideoFrame as VideoFramePolyfill };
|
|
17
209
|
/**
|
|
18
210
|
* Install the OffscreenCanvas polyfill globally
|
|
211
|
+
*
|
|
212
|
+
* This makes OffscreenCanvas available as a global, matching browser behavior.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* import { installOffscreenCanvasPolyfill } from 'webcodecs-node';
|
|
217
|
+
* installOffscreenCanvasPolyfill();
|
|
218
|
+
*
|
|
219
|
+
* // Now you can use OffscreenCanvas like in a browser
|
|
220
|
+
* const canvas = new OffscreenCanvas(1920, 1080);
|
|
221
|
+
* ```
|
|
19
222
|
*/
|
|
20
223
|
export function installOffscreenCanvasPolyfill() {
|
|
21
224
|
const g = globalThis;
|
|
22
225
|
if (typeof g.OffscreenCanvas === 'undefined') {
|
|
23
226
|
g.OffscreenCanvas = OffscreenCanvasPolyfill;
|
|
24
227
|
}
|
|
25
|
-
if (typeof g.OffscreenCanvasRenderingContext2D === 'undefined') {
|
|
26
|
-
g.OffscreenCanvasRenderingContext2D = OffscreenCanvasRenderingContext2DPolyfill;
|
|
27
|
-
}
|
|
28
228
|
if (typeof g.ImageData === 'undefined') {
|
|
29
229
|
g.ImageData = ImageDataPolyfill;
|
|
30
230
|
}
|
|
31
231
|
if (typeof g.VideoFrame === 'undefined') {
|
|
32
|
-
g.VideoFrame =
|
|
232
|
+
g.VideoFrame = VideoFrame;
|
|
33
233
|
}
|
|
34
234
|
}
|
|
35
235
|
//# sourceMappingURL=OffscreenCanvas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OffscreenCanvas.js","sourceRoot":"","sources":["../../src/polyfills/OffscreenCanvas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"OffscreenCanvas.js","sourceRoot":"","sources":["../../src/polyfills/OffscreenCanvas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;GAEG;AACH,MAAM,OAAO,iBAAiB;IACnB,IAAI,CAAoB;IACxB,KAAK,CAAS;IACd,MAAM,CAAS;IACf,UAAU,GAAW,MAAM,CAAC;IAC5B,SAAS,GAAW,MAAM,CAAC,CAAC,0BAA0B;IAI/D,YACE,WAAuC,EACvC,aAAqB,EACrB,MAAe;QAEf,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;YAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC;YAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC;QACjE,CAAC;IACH,CAAC;CACF;AAYD;;GAEG;AACH,MAAM,YAAY;IACR,OAAO,CAAS;IACf,IAAI,CAAS;IACb,IAAI,CAAS;IAEtB,YAAY,MAAc,EAAE,IAAY;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAC9B,IAAI,CAAC,OAAO,CAAC,UAAU,EACvB,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CACnC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,MAAM;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,OAAO,IAAI,cAAc,CAAC;YACxB,KAAK,CAAC,UAAU;gBACd,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC3C,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAc,EAAE,GAAY,EAAE,WAAoB;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9C,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,uBAAuB;IAC1B,OAAO,CAAa;IACpB,IAAI,GAAe,IAAI,CAAC;IAEhC;;OAEG;IACH,YAAY,KAAa,EAAE,MAAc;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAI,KAAK,CAAC,KAAa;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM,CAAC,KAAa;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAUD,UAAU,CAAC,SAAiB,EAAE,OAAa;QACzC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QACD,sBAAsB;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,OAGnB;QACC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,WAAW,CAAC;QAC1C,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;QAEzC,IAAI,MAAc,CAAC;QACnB,IAAI,QAAgB,CAAC;QAErB,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAClD,MAAM,GAAG,KAAK,CAAC;YACf,QAAQ,GAAG,YAAY,CAAC;QAC1B,CAAC;aAAM,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,GAAG,MAAM,CAAC;YAChB,QAAQ,GAAG,YAAY,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,KAAK,CAAC;YACf,QAAQ,GAAG,WAAW,CAAC;QACzB,CAAC;QAED,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,OAAe,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC1D,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;;OAOG;IACH,qBAAqB;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAEpC,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;YAC3B,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,GAAG,EAAE;gBACV,mBAAmB;YACrB,CAAC;SACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,MAAM,MAAM,GAAI,IAAI,CAAC,OAAe,CAAC,YAAY,CAAC,KAAK,EAAE;YACvD,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACpF,CAAC;IAED;;;OAGG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,IAAI,GAAG;QACL,OAAQ,IAAI,CAAC,OAAe,CAAC,GAAG,CAAC;IACnC,CAAC;IAED,IAAI,GAAG,CAAC,KAAc;QACnB,IAAI,CAAC,OAAe,CAAC,GAAG,GAAG,KAAK,CAAC;IACpC,CAAC;CACF;AAED,oEAAoE;AACpE,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,CAAC;AAK5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,8BAA8B;IAC5C,MAAM,CAAC,GAAG,UAAqC,CAAC;IAEhD,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,WAAW,EAAE,CAAC;QAC7C,CAAC,CAAC,eAAe,GAAG,uBAAuB,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,WAAW,EAAE,CAAC;QACvC,CAAC,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,WAAW,EAAE,CAAC;QACxC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { type BufferSource, DOMException, type CodecState, type HardwareAccelera
|
|
|
5
5
|
export { type DOMRectInit, DOMRectReadOnly, type PlaneLayout, } from './geometry.js';
|
|
6
6
|
export { type VideoPixelFormat, type VideoFrameBufferInit, type VideoFrameInit, type VideoFrameCopyToOptions, } from './video.js';
|
|
7
7
|
export { type AudioSampleFormat, type AudioDataInit, type AudioDataCopyToOptions, } from './audio.js';
|
|
8
|
+
export { type NativeFrame, type NativeVideoFrame, type NativeAudioFrame, isNativeFrame, hasUnref, hasClone, } from './native-frame.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,WAAW,EAChB,eAAe,EACf,KAAK,WAAW,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,uBAAuB,GAC7B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,WAAW,EAChB,eAAe,EACf,KAAK,WAAW,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,uBAAuB,GAC7B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,aAAa,EACb,QAAQ,EACR,QAAQ,GACT,MAAM,mBAAmB,CAAC"}
|
package/dist/types/index.js
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
export { DOMException, } from './common.js';
|
|
6
6
|
// Geometry types
|
|
7
7
|
export { DOMRectReadOnly, } from './geometry.js';
|
|
8
|
+
// Native frame types (for node-av integration)
|
|
9
|
+
export { isNativeFrame, hasUnref, hasClone, } from './native-frame.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAe;AACf,OAAO,EAEL,YAAY,GAQb,MAAM,aAAa,CAAC;AAErB,iBAAiB;AACjB,OAAO,EAEL,eAAe,GAEhB,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAe;AACf,OAAO,EAEL,YAAY,GAQb,MAAM,aAAa,CAAC;AAErB,iBAAiB;AACjB,OAAO,EAEL,eAAe,GAEhB,MAAM,eAAe,CAAC;AAiBvB,+CAA+C;AAC/C,OAAO,EAIL,aAAa,EACb,QAAQ,EACR,QAAQ,GACT,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native frame interface for node-av integration
|
|
3
|
+
*
|
|
4
|
+
* Represents a native (non-JavaScript) audio or video frame from the node-av backend.
|
|
5
|
+
* These frames hold references to native memory that must be properly released.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Base interface for native frames from node-av
|
|
9
|
+
*/
|
|
10
|
+
export interface NativeFrame {
|
|
11
|
+
/**
|
|
12
|
+
* Convert the native frame data to a JavaScript Buffer.
|
|
13
|
+
* For video frames, returns raw pixel data.
|
|
14
|
+
* For audio frames, returns raw PCM samples.
|
|
15
|
+
*/
|
|
16
|
+
toBuffer(): Buffer;
|
|
17
|
+
/**
|
|
18
|
+
* Release the native resources associated with this frame.
|
|
19
|
+
* Should be called when the frame is no longer needed.
|
|
20
|
+
* Some implementations may not have this method (returns undefined).
|
|
21
|
+
*/
|
|
22
|
+
unref?(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Create a clone of this native frame.
|
|
25
|
+
* Returns a new frame with its own native resources.
|
|
26
|
+
* Some implementations may not support cloning.
|
|
27
|
+
*/
|
|
28
|
+
clone?(): NativeFrame;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Native video frame with additional video-specific properties
|
|
32
|
+
*/
|
|
33
|
+
export interface NativeVideoFrame extends NativeFrame {
|
|
34
|
+
/** Frame width in pixels */
|
|
35
|
+
readonly width?: number;
|
|
36
|
+
/** Frame height in pixels */
|
|
37
|
+
readonly height?: number;
|
|
38
|
+
/** Pixel format (e.g., 'yuv420p', 'rgba') */
|
|
39
|
+
readonly format?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Native audio frame with additional audio-specific properties
|
|
43
|
+
*/
|
|
44
|
+
export interface NativeAudioFrame extends NativeFrame {
|
|
45
|
+
/** Number of audio samples per channel */
|
|
46
|
+
readonly nbSamples?: number;
|
|
47
|
+
/** Sample rate in Hz */
|
|
48
|
+
readonly sampleRate?: number;
|
|
49
|
+
/** Number of audio channels */
|
|
50
|
+
readonly channels?: number;
|
|
51
|
+
/** Sample format (e.g., 'fltp', 's16') */
|
|
52
|
+
readonly format?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Type guard to check if an object is a NativeFrame
|
|
56
|
+
*
|
|
57
|
+
* A NativeFrame must have both toBuffer() and unref() methods.
|
|
58
|
+
* This distinguishes it from objects like skia-canvas Canvas which
|
|
59
|
+
* have toBuffer() but are not native frames from node-av.
|
|
60
|
+
*/
|
|
61
|
+
export declare function isNativeFrame(obj: unknown): obj is NativeFrame;
|
|
62
|
+
/**
|
|
63
|
+
* Type guard to check if a NativeFrame has unref capability
|
|
64
|
+
*/
|
|
65
|
+
export declare function hasUnref(frame: NativeFrame): frame is NativeFrame & {
|
|
66
|
+
unref(): void;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Type guard to check if a NativeFrame has clone capability
|
|
70
|
+
*/
|
|
71
|
+
export declare function hasClone(frame: NativeFrame): frame is NativeFrame & {
|
|
72
|
+
clone(): NativeFrame;
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=native-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-frame.d.ts","sourceRoot":"","sources":["../../src/types/native-frame.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,IAAI,IAAI,CAAC;IAEf;;;;OAIG;IACH,KAAK,CAAC,IAAI,WAAW,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,wBAAwB;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAO9D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,WAAW,GAAG;IAAE,KAAK,IAAI,IAAI,CAAA;CAAE,CAErF;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,IAAI,WAAW,GAAG;IAAE,KAAK,IAAI,WAAW,CAAA;CAAE,CAE5F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native frame interface for node-av integration
|
|
3
|
+
*
|
|
4
|
+
* Represents a native (non-JavaScript) audio or video frame from the node-av backend.
|
|
5
|
+
* These frames hold references to native memory that must be properly released.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Type guard to check if an object is a NativeFrame
|
|
9
|
+
*
|
|
10
|
+
* A NativeFrame must have both toBuffer() and unref() methods.
|
|
11
|
+
* This distinguishes it from objects like skia-canvas Canvas which
|
|
12
|
+
* have toBuffer() but are not native frames from node-av.
|
|
13
|
+
*/
|
|
14
|
+
export function isNativeFrame(obj) {
|
|
15
|
+
return Boolean(obj &&
|
|
16
|
+
typeof obj === 'object' &&
|
|
17
|
+
typeof obj.toBuffer === 'function' &&
|
|
18
|
+
typeof obj.unref === 'function');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Type guard to check if a NativeFrame has unref capability
|
|
22
|
+
*/
|
|
23
|
+
export function hasUnref(frame) {
|
|
24
|
+
return typeof frame.unref === 'function';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Type guard to check if a NativeFrame has clone capability
|
|
28
|
+
*/
|
|
29
|
+
export function hasClone(frame) {
|
|
30
|
+
return typeof frame.clone === 'function';
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=native-frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-frame.js","sourceRoot":"","sources":["../../src/types/native-frame.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsDH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,OAAO,OAAO,CACZ,GAAG;QACH,OAAO,GAAG,KAAK,QAAQ;QACvB,OAAQ,GAAmB,CAAC,QAAQ,KAAK,UAAU;QACnD,OAAQ,GAAmB,CAAC,KAAK,KAAK,UAAU,CACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAkB;IACzC,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAkB;IACzC,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codec string validation according to WebCodecs specification
|
|
3
|
+
*
|
|
4
|
+
* The WebCodecs spec requires strict validation of codec strings:
|
|
5
|
+
* - Case-sensitive matching
|
|
6
|
+
* - Fully qualified codec strings (no ambiguous "vp9", must be "vp09.xx.xx.xx")
|
|
7
|
+
* - Valid profile/level parameters
|
|
8
|
+
*
|
|
9
|
+
* @see https://www.w3.org/TR/webcodecs-codec-registry/
|
|
10
|
+
*/
|
|
11
|
+
export interface CodecValidationResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
supported: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validate a video codec string according to WebCodecs spec
|
|
18
|
+
*
|
|
19
|
+
* Returns { valid: true, supported: true } for valid, supported codecs
|
|
20
|
+
* Returns { valid: true, supported: false } for valid but unsupported codecs
|
|
21
|
+
* Returns { valid: false, supported: false } for invalid codec strings
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateVideoCodec(codec: string): CodecValidationResult;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a codec config is valid (should throw TypeError if invalid)
|
|
26
|
+
* This checks for missing/empty required fields
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateVideoDecoderConfig(config: unknown): void;
|
|
29
|
+
/**
|
|
30
|
+
* Check if an encoder config is valid (should throw TypeError if invalid)
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateVideoEncoderConfig(config: unknown): void;
|
|
33
|
+
//# sourceMappingURL=codec-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec-validation.d.ts","sourceRoot":"","sources":["../../src/utils/codec-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CA0DvE;AAyJD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAchE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA+ChE"}
|