libbitsub 1.0.0

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 ADDED
@@ -0,0 +1,355 @@
1
+ # libbit(map)sub
2
+
3
+ High-performance WASM renderer for graphical subtitles (PGS and VobSub), written in Rust.
4
+
5
+ Started as a fork of Arcus92's [libpgs-js](https://github.com/Arcus92/libpgs-js), this project is re-engineered to maximize performance and extend functionality to VobSub, which was not supported by the original library. It remains fully backward compatible (only for PGS - obliviously). Special thanks to the original project for the inspiration!
6
+
7
+ ## Features
8
+
9
+ - **PGS (Blu-ray)** subtitle parsing and rendering
10
+ - **VobSub (DVD)** subtitle parsing and rendering
11
+ - **High-performance** Rust-based rendering engine compiled to WebAssembly
12
+ - **Zero-copy** data transfer between JS and WASM where possible
13
+ - **Caching** for decoded bitmaps to optimize repeated rendering
14
+ - **TypeScript** support with full type definitions
15
+
16
+ ## Showcase
17
+
18
+ ### PGS (Created using Spp2Pgs)
19
+
20
+ https://gist.github.com/user-attachments/assets/55ac8e11-1964-4fb9-923e-dcac82dc7703
21
+
22
+ ### Vobsub
23
+
24
+ https://gist.github.com/user-attachments/assets/a89ae9fe-23e4-4bc3-8cad-16a3f0fea665
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ bun add libbitsub
30
+ ```
31
+
32
+ ### Setup for Web Workers (Recommended)
33
+
34
+ For best performance with large subtitle files, copy the WASM files to your public folder so Web Workers can access them:
35
+
36
+ ```bash
37
+ # For Next.js, Vite, or similar frameworks
38
+ mkdir -p public/libbitsub
39
+ cp node_modules/libbitsub/pkg/libbitsub_bg.wasm public/libbitsub/
40
+ cp node_modules/libbitsub/pkg/libbitsub.js public/libbitsub/
41
+ ```
42
+
43
+ This enables off-main-thread parsing which prevents UI freezing when loading large PGS files.
44
+
45
+ ## Prerequisites
46
+
47
+ To build from source, you need:
48
+
49
+ - [Rust](https://rustup.rs/) (1.70+)
50
+ - [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
51
+
52
+ ```bash
53
+ # Install wasm-pack
54
+ cargo install wasm-pack
55
+ ```
56
+
57
+ ## Building
58
+
59
+ ```bash
60
+ # Build WASM module and TypeScript wrapper
61
+ bun run build
62
+
63
+ # Build WASM only (for development)
64
+ bun run build:wasm
65
+
66
+ # Build release version (optimized)
67
+ bun run build:wasm:release
68
+ ```
69
+
70
+ ## Usage
71
+
72
+ ### Initialize WASM
73
+
74
+ Before using any renderer, you must initialize the WASM module:
75
+
76
+ ```typescript
77
+ import { initWasm } from 'libbitsub'
78
+
79
+ // Initialize WASM (do this once at app startup)
80
+ await initWasm()
81
+ ```
82
+
83
+ ## High-Level API (Video Integration)
84
+
85
+ The high-level API automatically handles video synchronization, canvas overlay, and subtitle fetching.
86
+
87
+ ### PGS Subtitles (Video-Integrated)
88
+
89
+ ```typescript
90
+ import { PgsRenderer } from 'libbitsub'
91
+
92
+ // Create renderer with video element
93
+ const renderer = new PgsRenderer({
94
+ video: videoElement,
95
+ subUrl: '/subtitles/movie.sup',
96
+ workerUrl: '/libbitsub.js', // Optional, kept for API compatibility
97
+ // Lifecycle callbacks (optional)
98
+ onLoading: () => console.log('Loading subtitles...'),
99
+ onLoaded: () => console.log('Subtitles loaded!'),
100
+ onError: (error) => console.error('Failed to load:', error)
101
+ })
102
+
103
+ // The renderer automatically:
104
+ // - Fetches the subtitle file
105
+ // - Creates a canvas overlay on the video
106
+ // - Syncs rendering with video playback
107
+ // - Handles resize events
108
+
109
+ // When done:
110
+ renderer.dispose()
111
+ ```
112
+
113
+ ### VobSub Subtitles (Video-Integrated)
114
+
115
+ ```typescript
116
+ import { VobSubRenderer } from 'libbitsub'
117
+
118
+ // Create renderer with video element
119
+ const renderer = new VobSubRenderer({
120
+ video: videoElement,
121
+ subUrl: '/subtitles/movie.sub',
122
+ idxUrl: '/subtitles/movie.idx', // Optional, defaults to .sub path with .idx extension
123
+ workerUrl: '/libbitsub.js', // Optional
124
+ // Lifecycle callbacks (optional)
125
+ onLoading: () => setIsLoading(true),
126
+ onLoaded: () => setIsLoading(false),
127
+ onError: (error) => {
128
+ setIsLoading(false)
129
+ console.error('Subtitle error:', error)
130
+ }
131
+ })
132
+
133
+ // When done:
134
+ renderer.dispose()
135
+ ```
136
+
137
+ ### Subtitle Display Settings
138
+
139
+ Both `PgsRenderer` and `VobSubRenderer` support real-time customization of subtitle size and position:
140
+
141
+ ```typescript
142
+ // Get current settings
143
+ const settings = renderer.getDisplaySettings()
144
+ console.log(settings)
145
+ // Output: { scale: 1.0, verticalOffset: 0 }
146
+
147
+ // Update settings
148
+ renderer.setDisplaySettings({
149
+ scale: 1.2, // 1.2 = 120% size
150
+ verticalOffset: -10 // -10% (move up 10% of video height)
151
+ })
152
+
153
+ // Reset to defaults
154
+ renderer.resetDisplaySettings()
155
+ ```
156
+
157
+ **Settings Reference:**
158
+
159
+ - `scale` (number): Scale factor for subtitles.
160
+ - `1.0` = 100% (Original size)
161
+ - `0.5` = 50%
162
+ - `2.0` = 200%
163
+ - Range: `0.1` to `3.0`
164
+
165
+ - `verticalOffset` (number): Vertical position offset as a percentage of video height.
166
+ - `0` = Original position
167
+ - Negative values move up (e.g., `-10` moves up by 10% of height)
168
+ - Positive values move down (e.g., `10` moves down by 10% of height)
169
+ - Range: `-50` to `50`
170
+
171
+ ## Low-Level API (Programmatic Use)
172
+
173
+ For more control over rendering, use the low-level parsers directly.
174
+
175
+ ### PGS Subtitles (Low-Level)
176
+
177
+ ```typescript
178
+ import { initWasm, PgsParser } from 'libbitsub'
179
+
180
+ await initWasm()
181
+
182
+ const parser = new PgsParser()
183
+
184
+ // Load PGS data from a .sup file
185
+ const response = await fetch('subtitles.sup')
186
+ const data = new Uint8Array(await response.arrayBuffer())
187
+ parser.load(data)
188
+
189
+ // Get timestamps
190
+ const timestamps = parser.getTimestamps() // Float64Array in milliseconds
191
+
192
+ // Render at a specific time
193
+ const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
194
+ if (subtitleData) {
195
+ for (const comp of subtitleData.compositionData) {
196
+ ctx.putImageData(comp.pixelData, comp.x, comp.y)
197
+ }
198
+ }
199
+
200
+ // Clean up
201
+ parser.dispose()
202
+ ```
203
+
204
+ ### VobSub Subtitles (Low-Level)
205
+
206
+ ```typescript
207
+ import { initWasm, VobSubParserLowLevel } from 'libbitsub'
208
+
209
+ await initWasm()
210
+
211
+ const parser = new VobSubParserLowLevel()
212
+
213
+ // Load from IDX + SUB files
214
+ const idxResponse = await fetch('subtitles.idx')
215
+ const idxContent = await idxResponse.text()
216
+ const subResponse = await fetch('subtitles.sub')
217
+ const subData = new Uint8Array(await subResponse.arrayBuffer())
218
+
219
+ parser.loadFromData(idxContent, subData)
220
+
221
+ // Or load from SUB file only
222
+ // parser.loadFromSubOnly(subData);
223
+
224
+ // Render
225
+ const subtitleData = parser.renderAtTimestamp(currentTimeInSeconds)
226
+ if (subtitleData) {
227
+ for (const comp of subtitleData.compositionData) {
228
+ ctx.putImageData(comp.pixelData, comp.x, comp.y)
229
+ }
230
+ }
231
+
232
+ parser.dispose()
233
+ ```
234
+
235
+ ### Unified Parser
236
+
237
+ For handling both formats with a single API:
238
+
239
+ ```typescript
240
+ import { initWasm, UnifiedSubtitleParser } from 'libbitsub'
241
+
242
+ await initWasm()
243
+
244
+ const parser = new UnifiedSubtitleParser()
245
+
246
+ // Load PGS
247
+ parser.loadPgs(pgsData)
248
+
249
+ // Or load VobSub
250
+ // parser.loadVobSub(idxContent, subData);
251
+
252
+ console.log(parser.format) // 'pgs' or 'vobsub'
253
+
254
+ const subtitleData = parser.renderAtTimestamp(time)
255
+ // ... render to canvas
256
+
257
+ parser.dispose()
258
+ ```
259
+
260
+ ## API Reference
261
+
262
+ ### High-Level (Video-Integrated)
263
+
264
+ #### `PgsRenderer`
265
+
266
+ - `constructor(options: VideoSubtitleOptions)` - Create video-integrated PGS renderer
267
+ - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
268
+ - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
269
+ - `resetDisplaySettings(): void` - Reset display settings to defaults
270
+ - `dispose(): void` - Clean up all resources
271
+
272
+ #### `VobSubRenderer`
273
+
274
+ - `constructor(options: VideoVobSubOptions)` - Create video-integrated VobSub renderer
275
+ - `getDisplaySettings(): SubtitleDisplaySettings` - Get current display settings
276
+ - `setDisplaySettings(settings: Partial<SubtitleDisplaySettings>): void` - Update display settings
277
+ - `resetDisplaySettings(): void` - Reset display settings to defaults
278
+ - `dispose(): void` - Clean up all resources
279
+
280
+ ### Low-Level (Programmatic)
281
+
282
+ #### `PgsParser`
283
+
284
+ - `load(data: Uint8Array): number` - Load PGS data, returns display set count
285
+ - `getTimestamps(): Float64Array` - Get all timestamps in milliseconds
286
+ - `count: number` - Number of display sets
287
+ - `findIndexAtTimestamp(timeSeconds: number): number` - Find index for timestamp
288
+ - `renderAtIndex(index: number): SubtitleData | undefined` - Render at index
289
+ - `renderAtTimestamp(timeSeconds: number): SubtitleData | undefined` - Render at time
290
+ - `clearCache(): void` - Clear decoded bitmap cache
291
+ - `dispose(): void` - Release resources
292
+
293
+ #### `VobSubParserLowLevel`
294
+
295
+ - `loadFromData(idxContent: string, subData: Uint8Array): void` - Load IDX + SUB
296
+ - `loadFromSubOnly(subData: Uint8Array): void` - Load SUB only
297
+ - Same rendering methods as PgsParser
298
+
299
+ #### `UnifiedSubtitleParser`
300
+
301
+ - `loadPgs(data: Uint8Array): number` - Load PGS data
302
+ - `loadVobSub(idxContent: string, subData: Uint8Array): void` - Load VobSub
303
+ - `loadVobSubOnly(subData: Uint8Array): void` - Load SUB only
304
+ - `format: 'pgs' | 'vobsub' | null` - Current format
305
+ - Same rendering methods as above
306
+
307
+ ### Types
308
+
309
+ #### `VideoSubtitleOptions`
310
+
311
+ ```typescript
312
+ interface VideoSubtitleOptions {
313
+ video: HTMLVideoElement // Video element to sync with
314
+ subUrl: string // URL to subtitle file
315
+ workerUrl?: string // Worker URL (for API compatibility)
316
+ onLoading?: () => void // Called when subtitle loading starts
317
+ onLoaded?: () => void // Called when subtitle loading completes
318
+ onError?: (error: Error) => void // Called when subtitle loading fails
319
+ }
320
+ ```
321
+
322
+ #### `VideoVobSubOptions`
323
+
324
+ ```typescript
325
+ interface VideoVobSubOptions extends VideoSubtitleOptions {
326
+ idxUrl?: string // URL to .idx file (optional)
327
+ }
328
+ ```
329
+
330
+ #### `SubtitleDisplaySettings`
331
+
332
+ ```typescript
333
+ interface SubtitleDisplaySettings {
334
+ // Scale factor (1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
335
+ scale: number
336
+ // Vertical offset as % of video height (-50 to 50)
337
+ verticalOffset: number
338
+ }
339
+ ```
340
+
341
+ #### `SubtitleData`
342
+
343
+ ```typescript
344
+ interface SubtitleData {
345
+ width: number // Screen width
346
+ height: number // Screen height
347
+ compositionData: SubtitleCompositionData[]
348
+ }
349
+
350
+ interface SubtitleCompositionData {
351
+ pixelData: ImageData // RGBA pixel data
352
+ x: number // X position
353
+ y: number // Y position
354
+ }
355
+ ```
@@ -0,0 +1,11 @@
1
+ /**
2
+ * libbitsub - High-performance WASM renderer for graphical subtitles
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { PgsRenderer, VobSubRenderer, type VideoSubtitleOptions, type VideoVobSubOptions, type SubtitleRendererStats } from './wrapper';
7
+ export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './wrapper';
8
+ export { initWasm, isWasmInitialized, type SubtitleData, type SubtitleCompositionData, type SubtitleDisplaySettings } from './wrapper';
9
+ export type { RenderResult, SubtitleFrame, VobSubFrame } from './wrapper';
10
+ export { PGSRenderer, VobsubRenderer, UnifiedSubtitleRenderer } from './wrapper';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,WAAW,EACX,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,WAAW,CAAA;AAGlB,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAGlF,OAAO,EACL,QAAQ,EACR,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC7B,MAAM,WAAW,CAAA;AAGlB,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAGzE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * libbitsub - High-performance WASM renderer for graphical subtitles
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ // High-level video-integrated renderers (compatible with old libpgs-js API)
7
+ export { PgsRenderer, VobSubRenderer } from './wrapper';
8
+ // Low-level parsers for programmatic use
9
+ export { PgsParser, VobSubParserLowLevel, UnifiedSubtitleParser } from './wrapper';
10
+ // Utility exports
11
+ export { initWasm, isWasmInitialized } from './wrapper';
12
+ // Legacy aliases
13
+ export { PGSRenderer, VobsubRenderer, UnifiedSubtitleRenderer } from './wrapper';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,4EAA4E;AAC5E,OAAO,EACL,WAAW,EACX,cAAc,EAIf,MAAM,WAAW,CAAA;AAElB,yCAAyC;AACzC,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAElF,kBAAkB;AAClB,OAAO,EACL,QAAQ,EACR,iBAAiB,EAIlB,MAAM,WAAW,CAAA;AAKlB,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Low-level subtitle parsers for libbitsub.
3
+ * Use these for programmatic access to subtitle data without video integration.
4
+ */
5
+ import type { SubtitleData } from './types';
6
+ /**
7
+ * Low-level PGS subtitle parser using WASM.
8
+ * Use this for programmatic access to PGS data without video integration.
9
+ */
10
+ export declare class PgsParser {
11
+ private parser;
12
+ private timestamps;
13
+ constructor();
14
+ /**
15
+ * Load PGS subtitle data from a Uint8Array.
16
+ */
17
+ load(data: Uint8Array): number;
18
+ /**
19
+ * Get all timestamps in milliseconds.
20
+ */
21
+ getTimestamps(): Float64Array;
22
+ /**
23
+ * Get the number of display sets.
24
+ */
25
+ get count(): number;
26
+ /**
27
+ * Find the display set index for a given timestamp in seconds.
28
+ */
29
+ findIndexAtTimestamp(timeSeconds: number): number;
30
+ /**
31
+ * Render subtitle at the given index.
32
+ */
33
+ renderAtIndex(index: number): SubtitleData | undefined;
34
+ /**
35
+ * Render subtitle at the given timestamp in seconds.
36
+ */
37
+ renderAtTimestamp(timeSeconds: number): SubtitleData | undefined;
38
+ /**
39
+ * Convert WASM frame to SubtitleData.
40
+ */
41
+ private convertFrame;
42
+ /**
43
+ * Clear internal caches.
44
+ */
45
+ clearCache(): void;
46
+ /**
47
+ * Dispose of resources.
48
+ */
49
+ dispose(): void;
50
+ }
51
+ /**
52
+ * Low-level VobSub subtitle parser using WASM.
53
+ * Use this for programmatic access to VobSub data without video integration.
54
+ */
55
+ export declare class VobSubParserLowLevel {
56
+ private parser;
57
+ private timestamps;
58
+ constructor();
59
+ /**
60
+ * Load VobSub from IDX and SUB data.
61
+ */
62
+ loadFromData(idxContent: string, subData: Uint8Array): void;
63
+ /**
64
+ * Load VobSub from SUB file only.
65
+ */
66
+ loadFromSubOnly(subData: Uint8Array): void;
67
+ /**
68
+ * Get all timestamps in milliseconds.
69
+ */
70
+ getTimestamps(): Float64Array;
71
+ /**
72
+ * Get the number of subtitle entries.
73
+ */
74
+ get count(): number;
75
+ /**
76
+ * Find the subtitle index for a given timestamp in seconds.
77
+ */
78
+ findIndexAtTimestamp(timeSeconds: number): number;
79
+ /**
80
+ * Render subtitle at the given index.
81
+ */
82
+ renderAtIndex(index: number): SubtitleData | undefined;
83
+ /**
84
+ * Render subtitle at the given timestamp in seconds.
85
+ */
86
+ renderAtTimestamp(timeSeconds: number): SubtitleData | undefined;
87
+ /**
88
+ * Convert WASM frame to SubtitleData.
89
+ */
90
+ private convertFrame;
91
+ /**
92
+ * Clear internal caches.
93
+ */
94
+ clearCache(): void;
95
+ /**
96
+ * Dispose of resources.
97
+ */
98
+ dispose(): void;
99
+ }
100
+ /**
101
+ * Unified subtitle parser that handles both PGS and VobSub formats.
102
+ */
103
+ export declare class UnifiedSubtitleParser {
104
+ private renderer;
105
+ private timestamps;
106
+ constructor();
107
+ /**
108
+ * Load PGS subtitle data.
109
+ */
110
+ loadPgs(data: Uint8Array): number;
111
+ /**
112
+ * Load VobSub from IDX and SUB data.
113
+ */
114
+ loadVobSub(idxContent: string, subData: Uint8Array): void;
115
+ /**
116
+ * Load VobSub from SUB file only.
117
+ */
118
+ loadVobSubOnly(subData: Uint8Array): void;
119
+ /**
120
+ * Get the current subtitle format.
121
+ */
122
+ get format(): 'pgs' | 'vobsub' | null;
123
+ /**
124
+ * Get all timestamps in milliseconds.
125
+ */
126
+ getTimestamps(): Float64Array;
127
+ /**
128
+ * Get the number of subtitle entries.
129
+ */
130
+ get count(): number;
131
+ /**
132
+ * Find the subtitle index for a given timestamp in seconds.
133
+ */
134
+ findIndexAtTimestamp(timeSeconds: number): number;
135
+ /**
136
+ * Render subtitle at the given index.
137
+ */
138
+ renderAtIndex(index: number): SubtitleData | undefined;
139
+ /**
140
+ * Render subtitle at the given timestamp in seconds.
141
+ */
142
+ renderAtTimestamp(timeSeconds: number): SubtitleData | undefined;
143
+ /**
144
+ * Convert WASM result to SubtitleData.
145
+ */
146
+ private convertResult;
147
+ /**
148
+ * Clear internal caches.
149
+ */
150
+ clearCache(): void;
151
+ /**
152
+ * Dispose of resources.
153
+ */
154
+ dispose(): void;
155
+ }
156
+ //# sourceMappingURL=parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/ts/parsers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,YAAY,EAQb,MAAM,SAAS,CAAA;AAGhB;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,UAAU,CAAoC;;IAOtD;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAO9B;;OAEG;IACH,aAAa,IAAI,YAAY;IAI7B;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAKjD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAStD;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAMhE;;OAEG;IACH,OAAO,CAAC,YAAY;IAsCpB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAED;;;GAGG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,UAAU,CAAoC;;IAOtD;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAM3D;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAM1C;;OAEG;IACH,aAAa,IAAI,YAAY;IAI7B;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAKjD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAStD;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAMhE;;OAEG;IACH,OAAO,CAAC,YAAY;IAmCpB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,UAAU,CAAoC;;IAOtD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAOjC;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAMzD;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAMzC;;OAEG;IACH,IAAI,MAAM,IAAI,KAAK,GAAG,QAAQ,GAAG,IAAI,CAKpC;IAED;;OAEG;IACH,aAAa,IAAI,YAAY;IAI7B;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAKjD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAStD;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAShE;;OAEG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}