webcodecs-node 0.7.2 → 0.7.5

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 (105) hide show
  1. package/README.md +94 -12
  2. package/dist/config/ffmpeg-quality.d.ts +10 -1
  3. package/dist/config/ffmpeg-quality.d.ts.map +1 -1
  4. package/dist/config/ffmpeg-quality.js +12 -38
  5. package/dist/config/ffmpeg-quality.js.map +1 -1
  6. package/dist/config/webcodecs-config.d.ts +58 -0
  7. package/dist/config/webcodecs-config.d.ts.map +1 -0
  8. package/dist/config/webcodecs-config.js +187 -0
  9. package/dist/config/webcodecs-config.js.map +1 -0
  10. package/dist/containers/Demuxer.d.ts +3 -1
  11. package/dist/containers/Demuxer.d.ts.map +1 -1
  12. package/dist/containers/Demuxer.js +26 -19
  13. package/dist/containers/Demuxer.js.map +1 -1
  14. package/dist/containers/FFmpegMuxer.d.ts +42 -0
  15. package/dist/containers/FFmpegMuxer.d.ts.map +1 -0
  16. package/dist/containers/FFmpegMuxer.js +311 -0
  17. package/dist/containers/FFmpegMuxer.js.map +1 -0
  18. package/dist/containers/FFmpegSpawnMuxer.d.ts +42 -0
  19. package/dist/containers/FFmpegSpawnMuxer.d.ts.map +1 -0
  20. package/dist/containers/FFmpegSpawnMuxer.js +311 -0
  21. package/dist/containers/FFmpegSpawnMuxer.js.map +1 -0
  22. package/dist/containers/FallbackMuxer.d.ts +42 -0
  23. package/dist/containers/FallbackMuxer.d.ts.map +1 -0
  24. package/dist/containers/FallbackMuxer.js +311 -0
  25. package/dist/containers/FallbackMuxer.js.map +1 -0
  26. package/dist/containers/Muxer.d.ts +75 -107
  27. package/dist/containers/Muxer.d.ts.map +1 -1
  28. package/dist/containers/Muxer.js +184 -243
  29. package/dist/containers/Muxer.js.map +1 -1
  30. package/dist/containers/MuxerWithFallback.d.ts +110 -0
  31. package/dist/containers/MuxerWithFallback.d.ts.map +1 -0
  32. package/dist/containers/MuxerWithFallback.js +239 -0
  33. package/dist/containers/MuxerWithFallback.js.map +1 -0
  34. package/dist/containers/NodeAvMuxer.d.ts +118 -0
  35. package/dist/containers/NodeAvMuxer.d.ts.map +1 -0
  36. package/dist/containers/NodeAvMuxer.js +338 -0
  37. package/dist/containers/NodeAvMuxer.js.map +1 -0
  38. package/dist/containers/extract.d.ts.map +1 -1
  39. package/dist/containers/extract.js +3 -1
  40. package/dist/containers/extract.js.map +1 -1
  41. package/dist/containers/index.d.ts +20 -14
  42. package/dist/containers/index.d.ts.map +1 -1
  43. package/dist/containers/index.js +21 -14
  44. package/dist/containers/index.js.map +1 -1
  45. package/dist/containers/muxer-types.d.ts +117 -0
  46. package/dist/containers/muxer-types.d.ts.map +1 -0
  47. package/dist/containers/muxer-types.js +45 -0
  48. package/dist/containers/muxer-types.js.map +1 -0
  49. package/dist/containers/transcode.d.ts.map +1 -1
  50. package/dist/containers/transcode.js +171 -150
  51. package/dist/containers/transcode.js.map +1 -1
  52. package/dist/core/VideoFrame.d.ts +19 -0
  53. package/dist/core/VideoFrame.d.ts.map +1 -1
  54. package/dist/core/VideoFrame.js +11 -0
  55. package/dist/core/VideoFrame.js.map +1 -1
  56. package/dist/decoders/VideoDecoder.d.ts +1 -0
  57. package/dist/decoders/VideoDecoder.d.ts.map +1 -1
  58. package/dist/decoders/VideoDecoder.js +6 -4
  59. package/dist/decoders/VideoDecoder.js.map +1 -1
  60. package/dist/demos/demo-audio-visualizer-mediabunny.d.ts +10 -0
  61. package/dist/demos/demo-audio-visualizer-mediabunny.d.ts.map +1 -0
  62. package/dist/demos/demo-audio-visualizer-mediabunny.js +357 -0
  63. package/dist/demos/demo-audio-visualizer-mediabunny.js.map +1 -0
  64. package/dist/demos/demo-audio-visualizer-nodeav.d.ts +10 -0
  65. package/dist/demos/demo-audio-visualizer-nodeav.d.ts.map +1 -0
  66. package/dist/demos/demo-audio-visualizer-nodeav.js +318 -0
  67. package/dist/demos/demo-audio-visualizer-nodeav.js.map +1 -0
  68. package/dist/demos/demo-muxer-fallback.d.ts +8 -0
  69. package/dist/demos/demo-muxer-fallback.d.ts.map +1 -0
  70. package/dist/demos/demo-muxer-fallback.js +165 -0
  71. package/dist/demos/demo-muxer-fallback.js.map +1 -0
  72. package/dist/encoders/AudioEncoder.d.ts +2 -0
  73. package/dist/encoders/AudioEncoder.d.ts.map +1 -1
  74. package/dist/encoders/AudioEncoder.js +7 -4
  75. package/dist/encoders/AudioEncoder.js.map +1 -1
  76. package/dist/hardware/decoder-args.d.ts.map +1 -1
  77. package/dist/hardware/decoder-args.js +35 -14
  78. package/dist/hardware/decoder-args.js.map +1 -1
  79. package/dist/hardware/detection.d.ts.map +1 -1
  80. package/dist/hardware/detection.js +39 -0
  81. package/dist/hardware/detection.js.map +1 -1
  82. package/dist/hardware/encoder-args.d.ts.map +1 -1
  83. package/dist/hardware/encoder-args.js +43 -5
  84. package/dist/hardware/encoder-args.js.map +1 -1
  85. package/dist/hardware/types.d.ts.map +1 -1
  86. package/dist/hardware/types.js +30 -28
  87. package/dist/hardware/types.js.map +1 -1
  88. package/dist/node-av/NodeAvVideoEncoder.d.ts +5 -0
  89. package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -1
  90. package/dist/node-av/NodeAvVideoEncoder.js +76 -23
  91. package/dist/node-av/NodeAvVideoEncoder.js.map +1 -1
  92. package/dist/utils/avc.d.ts +2 -0
  93. package/dist/utils/avc.d.ts.map +1 -1
  94. package/dist/utils/avc.js +36 -8
  95. package/dist/utils/avc.js.map +1 -1
  96. package/dist/utils/codec-validation.d.ts.map +1 -1
  97. package/dist/utils/codec-validation.js +18 -8
  98. package/dist/utils/codec-validation.js.map +1 -1
  99. package/dist/utils/hevc.d.ts +2 -0
  100. package/dist/utils/hevc.d.ts.map +1 -1
  101. package/dist/utils/hevc.js +42 -8
  102. package/dist/utils/hevc.js.map +1 -1
  103. package/docs/api.md +20 -2
  104. package/docs/configuration.md +10 -7
  105. package/package.json +1 -1
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Muxer with Fallback - Primary node-av muxer with FFmpeg spawn fallback
3
+ *
4
+ * This muxer attempts to use the fast node-av muxer first, and automatically
5
+ * falls back to FFmpeg spawn if it fails. This provides the best of both worlds:
6
+ * fast muxing when possible, with reliable fallback for edge cases.
7
+ */
8
+ import { MuxerError } from './muxer-types.js';
9
+ import { Muxer as NodeAvMuxer } from './Muxer.js';
10
+ import { FFmpegSpawnMuxer } from './FFmpegSpawnMuxer.js';
11
+ /**
12
+ * Muxer that tries node-av first, then falls back to FFmpeg spawn
13
+ *
14
+ * This implementation buffers all chunks and only performs the actual
15
+ * muxing when close() is called. This allows seamless fallback if the
16
+ * primary muxer fails at any point.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const muxer = new MuxerWithFallback({
21
+ * path: 'output.mp4',
22
+ * onFallback: (err) => console.warn('Using FFmpeg fallback:', err.message),
23
+ * });
24
+ *
25
+ * await muxer.open();
26
+ * await muxer.addVideoTrack({ codec: 'avc1.64001E', ... });
27
+ * await muxer.addAudioTrack({ codec: 'mp4a.40.2', ... });
28
+ *
29
+ * for (const chunk of videoChunks) await muxer.writeVideoChunk(chunk);
30
+ * for (const chunk of audioChunks) await muxer.writeAudioChunk(chunk);
31
+ *
32
+ * const result = await muxer.closeWithResult();
33
+ * console.log(`Muxed with ${result.backend} in ${result.durationMs}ms`);
34
+ * ```
35
+ */
36
+ export class MuxerWithFallback {
37
+ config;
38
+ videoConfig = null;
39
+ audioConfig = null;
40
+ videoChunks = [];
41
+ audioChunks = [];
42
+ _videoChunkCount = 0;
43
+ _audioChunkCount = 0;
44
+ isOpen = false;
45
+ usedBackend = null;
46
+ constructor(config) {
47
+ this.config = config;
48
+ }
49
+ async open(timeout) {
50
+ this.isOpen = true;
51
+ // We don't actually open anything yet - we buffer chunks
52
+ // and open the muxer during close()
53
+ }
54
+ async addVideoTrack(config) {
55
+ if (!this.isOpen) {
56
+ throw new MuxerError('Muxer not opened', 'node-av', 'addTrack');
57
+ }
58
+ this.videoConfig = config;
59
+ return 0;
60
+ }
61
+ async addAudioTrack(config) {
62
+ if (!this.isOpen) {
63
+ throw new MuxerError('Muxer not opened', 'node-av', 'addTrack');
64
+ }
65
+ this.audioConfig = config;
66
+ return this.videoConfig ? 1 : 0;
67
+ }
68
+ async writeVideoChunk(chunk) {
69
+ if (!this.isOpen || !this.videoConfig) {
70
+ throw new MuxerError('Video track not configured', 'node-av', 'write');
71
+ }
72
+ this.videoChunks.push(chunk);
73
+ this._videoChunkCount++;
74
+ }
75
+ async writeAudioChunk(chunk) {
76
+ if (!this.isOpen || !this.audioConfig) {
77
+ throw new MuxerError('Audio track not configured', 'node-av', 'write');
78
+ }
79
+ this.audioChunks.push(chunk);
80
+ this._audioChunkCount++;
81
+ }
82
+ /**
83
+ * Close the muxer and finalize the output file
84
+ */
85
+ async close(timeout) {
86
+ await this.closeWithResult(timeout);
87
+ }
88
+ /**
89
+ * Close the muxer and return detailed result including which backend was used
90
+ */
91
+ async closeWithResult(timeout) {
92
+ if (!this.isOpen) {
93
+ return {
94
+ path: this.config.path,
95
+ videoChunkCount: 0,
96
+ audioChunkCount: 0,
97
+ durationMs: 0,
98
+ backend: 'node-av',
99
+ };
100
+ }
101
+ const startTime = Date.now();
102
+ // If force backend is specified, use only that
103
+ if (this.config.forceBackend === 'ffmpeg-spawn') {
104
+ await this.muxWithFFmpeg();
105
+ this.usedBackend = 'ffmpeg-spawn';
106
+ }
107
+ else if (this.config.forceBackend === 'node-av') {
108
+ await this.muxWithNodeAv(timeout);
109
+ this.usedBackend = 'node-av';
110
+ }
111
+ else {
112
+ // Try node-av first, fallback to FFmpeg
113
+ try {
114
+ await this.muxWithNodeAv(timeout);
115
+ this.usedBackend = 'node-av';
116
+ }
117
+ catch (error) {
118
+ // Notify about fallback
119
+ if (this.config.onFallback) {
120
+ this.config.onFallback(error);
121
+ }
122
+ // Fall back to FFmpeg
123
+ await this.muxWithFFmpeg();
124
+ this.usedBackend = 'ffmpeg-spawn';
125
+ }
126
+ }
127
+ this.isOpen = false;
128
+ const durationMs = Date.now() - startTime;
129
+ return {
130
+ path: this.config.path,
131
+ videoChunkCount: this._videoChunkCount,
132
+ audioChunkCount: this._audioChunkCount,
133
+ durationMs,
134
+ backend: this.usedBackend,
135
+ };
136
+ }
137
+ async muxWithNodeAv(timeout) {
138
+ const muxer = new NodeAvMuxer({
139
+ path: this.config.path,
140
+ format: this.config.format,
141
+ });
142
+ try {
143
+ await muxer.open(timeout);
144
+ if (this.videoConfig) {
145
+ await muxer.addVideoTrack(this.videoConfig);
146
+ }
147
+ if (this.audioConfig) {
148
+ await muxer.addAudioTrack(this.audioConfig);
149
+ }
150
+ // Write all buffered chunks
151
+ for (const chunk of this.videoChunks) {
152
+ await muxer.writeVideoChunk(chunk);
153
+ }
154
+ for (const chunk of this.audioChunks) {
155
+ await muxer.writeAudioChunk(chunk);
156
+ }
157
+ await muxer.close(timeout);
158
+ }
159
+ catch (error) {
160
+ // Try to clean up partial file
161
+ try {
162
+ await muxer.close(1000);
163
+ }
164
+ catch {
165
+ // Ignore cleanup errors
166
+ }
167
+ throw error;
168
+ }
169
+ }
170
+ async muxWithFFmpeg() {
171
+ const muxer = new FFmpegSpawnMuxer({
172
+ path: this.config.path,
173
+ format: this.config.format,
174
+ });
175
+ await muxer.open();
176
+ if (this.videoConfig) {
177
+ await muxer.addVideoTrack(this.videoConfig);
178
+ }
179
+ if (this.audioConfig) {
180
+ await muxer.addAudioTrack(this.audioConfig);
181
+ }
182
+ // Write all buffered chunks
183
+ for (const chunk of this.videoChunks) {
184
+ await muxer.writeVideoChunk(chunk);
185
+ }
186
+ for (const chunk of this.audioChunks) {
187
+ await muxer.writeAudioChunk(chunk);
188
+ }
189
+ await muxer.close();
190
+ }
191
+ get videoChunkCount() {
192
+ return this._videoChunkCount;
193
+ }
194
+ get audioChunkCount() {
195
+ return this._audioChunkCount;
196
+ }
197
+ /**
198
+ * Get which backend was used for muxing (available after close)
199
+ */
200
+ get backend() {
201
+ return this.usedBackend;
202
+ }
203
+ }
204
+ /**
205
+ * Convenience function to mux video and audio chunks to a file
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const result = await muxChunks({
210
+ * path: 'output.mp4',
211
+ * video: { config: videoTrackConfig, chunks: videoChunks },
212
+ * audio: { config: audioTrackConfig, chunks: audioChunks },
213
+ * });
214
+ * console.log(`Created ${result.path} using ${result.backend}`);
215
+ * ```
216
+ */
217
+ export async function muxChunks(options) {
218
+ const muxer = new MuxerWithFallback({
219
+ path: options.path,
220
+ format: options.format,
221
+ onFallback: options.onFallback,
222
+ forceBackend: options.forceBackend,
223
+ });
224
+ await muxer.open();
225
+ if (options.video) {
226
+ await muxer.addVideoTrack(options.video.config);
227
+ for (const chunk of options.video.chunks) {
228
+ await muxer.writeVideoChunk(chunk);
229
+ }
230
+ }
231
+ if (options.audio) {
232
+ await muxer.addAudioTrack(options.audio.config);
233
+ for (const chunk of options.audio.chunks) {
234
+ await muxer.writeAudioChunk(chunk);
235
+ }
236
+ }
237
+ return muxer.closeWithResult();
238
+ }
239
+ //# sourceMappingURL=MuxerWithFallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MuxerWithFallback.js","sourceRoot":"","sources":["../../src/containers/MuxerWithFallback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Node-av Muxer - Fast muxer using node-av's FormatContext API
3
+ *
4
+ * Uses node-av's low-level FormatContext API to provide a WebCodecs-compatible interface
5
+ * that accepts EncodedVideoChunk and EncodedAudioChunk objects. This is the fast path
6
+ * (~5ms muxing time) used by the main Muxer class.
7
+ */
8
+ import { FormatContext } from 'node-av';
9
+ import { EncodedVideoChunk } from '../core/EncodedVideoChunk.js';
10
+ import { EncodedAudioChunk } from '../core/EncodedAudioChunk.js';
11
+ import type { IMuxer, MuxerConfig, VideoTrackConfig, AudioTrackConfig } from './muxer-types.js';
12
+ export type { MuxerConfig, VideoTrackConfig, AudioTrackConfig } from './muxer-types.js';
13
+ /**
14
+ * Node-av based muxer that accepts WebCodecs-compatible chunks
15
+ *
16
+ * Uses node-av's low-level FormatContext API for direct packet writing.
17
+ * This is the fast implementation (~5ms) used internally by the main Muxer class.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const muxer = new NodeAvMuxer({ path: 'output.mp4' });
22
+ * await muxer.open();
23
+ * await muxer.addVideoTrack({
24
+ * codec: 'avc1.42001E',
25
+ * codedWidth: 640,
26
+ * codedHeight: 480,
27
+ * framerate: 30,
28
+ * description: spsNaluBuffer, // Optional: H.264 SPS/PPS
29
+ * });
30
+ *
31
+ * // Write encoded chunks from VideoEncoder
32
+ * await muxer.writeVideoChunk(chunk);
33
+ *
34
+ * await muxer.close();
35
+ * ```
36
+ */
37
+ export declare class NodeAvMuxer implements IMuxer {
38
+ private formatContext;
39
+ private config;
40
+ private _videoStreamIndex;
41
+ private _audioStreamIndex;
42
+ private _videoConfig;
43
+ private _audioConfig;
44
+ private _videoChunkCount;
45
+ private _audioChunkCount;
46
+ private _headerWritten;
47
+ constructor(config: MuxerConfig);
48
+ /**
49
+ * Open the muxer for writing
50
+ *
51
+ * @param timeout - Operation timeout in milliseconds (default: 15000)
52
+ */
53
+ open(timeout?: number): Promise<void>;
54
+ /**
55
+ * Add a video track to the output
56
+ *
57
+ * @param config - Video track configuration
58
+ * @returns Stream index for the video track
59
+ */
60
+ addVideoTrack(config: VideoTrackConfig): Promise<number>;
61
+ /**
62
+ * Add an audio track to the output
63
+ *
64
+ * @param config - Audio track configuration
65
+ * @returns Stream index for the audio track
66
+ */
67
+ addAudioTrack(config: AudioTrackConfig): Promise<number>;
68
+ /**
69
+ * Write header if not already written
70
+ */
71
+ private writeHeaderIfNeeded;
72
+ /**
73
+ * Write an encoded video chunk to the output container
74
+ *
75
+ * @param chunk - EncodedVideoChunk from VideoEncoder
76
+ */
77
+ writeVideoChunk(chunk: EncodedVideoChunk): Promise<void>;
78
+ /**
79
+ * Write an encoded audio chunk to the output container
80
+ *
81
+ * @param chunk - EncodedAudioChunk from AudioEncoder
82
+ */
83
+ writeAudioChunk(chunk: EncodedAudioChunk): Promise<void>;
84
+ /**
85
+ * Finalize and close the muxer
86
+ *
87
+ * @param timeout - Operation timeout in milliseconds (default: 10000)
88
+ */
89
+ close(timeout?: number): Promise<void>;
90
+ /**
91
+ * Get the underlying FormatContext (for advanced use)
92
+ */
93
+ get native(): FormatContext | null;
94
+ /**
95
+ * Get number of video chunks written
96
+ */
97
+ get videoChunkCount(): number;
98
+ /**
99
+ * Get number of audio chunks written
100
+ */
101
+ get audioChunkCount(): number;
102
+ }
103
+ /**
104
+ * Helper class for stream copy (remux) operations
105
+ * This copies encoded data from one container to another without re-encoding
106
+ */
107
+ export declare class StreamCopier {
108
+ private srcDemuxer;
109
+ private dstMuxer;
110
+ /**
111
+ * Remux a file from one container format to another
112
+ * This performs a stream copy without re-encoding
113
+ */
114
+ static remux(inputPath: string, outputPath: string, options?: {
115
+ format?: string;
116
+ }): Promise<void>;
117
+ }
118
+ //# sourceMappingURL=NodeAvMuxer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeAvMuxer.d.ts","sourceRoot":"","sources":["../../src/containers/NodeAvMuxer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,aAAa,EAiBd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAI1B,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAwCxF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,WAAY,YAAW,MAAM;IACxC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAS;gBAEnB,MAAM,EAAE,WAAW;IAI/B;;;;OAIG;IACG,IAAI,CAAC,OAAO,GAAE,MAA8B,GAAG,OAAO,CAAC,IAAI,CAAC;IAelE;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAgC9D;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IA+B9D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C9D;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C9D;;;;OAIG;IACG,KAAK,CAAC,OAAO,GAAE,MAA+B,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBpE;;OAEG;IACH,IAAI,MAAM,IAAI,aAAa,GAAG,IAAI,CAEjC;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;CACF;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,QAAQ,CAAoC;IAEpD;;;OAGG;WACU,KAAK,CAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC,IAAI,CAAC;CAiCjB"}