@ngenux/ngage-whiteboarding 1.0.0 → 1.0.2

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 CHANGED
@@ -1,249 +1,343 @@
1
- # React Collaborative Whiteboard
2
-
3
- A React component library for creating collaborative whiteboards with real-time synchronization via WebSockets.
4
-
5
- ## ✨ Features
6
-
7
- - 🎨 **Real-time collaborative drawing** - Multiple users can draw simultaneously
8
- - 🔧 **Multiple drawing tools** - Pencil, shapes (rectangle, ellipse, arrow), eraser, line tools
9
- - â†Šī¸ **Undo/Redo functionality** - Per-user undo/redo with collaborative support
10
- - đŸ‘Ĩ **Multi-user support** - Admin controls and user permissions
11
- - 📱 **Responsive design** - Works on desktop, tablet, and mobile
12
- - 🔒 **Admin controls** - Lock/unlock canvas, clear canvas, user management
13
- - 💾 **Export functionality** - PNG, JPEG, PDF export options
14
- - đŸ—œī¸ **Data compression** - Optimized performance with automatic compression
15
- - ⚡ **Real-time sync** - Ultra-smooth 60fps collaborative drawing experience
16
- - đŸŽ¯ **TypeScript support** - Fully typed for better development experience
17
-
18
- ## đŸ“Ļ Installation
19
-
20
- ```bash
21
- npm install @ngenux/ngage-whiteboarding
22
- ```
23
-
24
- ## 🚀 Quick Start
25
-
26
- ### Basic Setup
27
-
28
- ```tsx
29
- import React from 'react';
30
- import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';
31
-
32
- function App() {
33
- return (
34
- <WhiteboardProvider webSocketUrl="ws://localhost:3001">
35
- <Whiteboard
36
- roomId="room-123"
37
- userId="user-456"
38
- isAdmin={true}
39
- allowedUsers={['user-456', 'user-789']}
40
- />
41
- </WhiteboardProvider>
42
- );
43
- }
44
-
45
- export default App;
46
- ```
47
-
48
- ### Advanced Usage with Multiple Rooms
49
-
50
- ```tsx
51
- import React, { useState } from 'react';
52
- import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';
53
-
54
- function CollaborativeApp() {
55
- const [currentRoom, setCurrentRoom] = useState('room-1');
56
- const [currentUser] = useState('user-' + Math.random().toString(36).substr(2, 9));
57
-
58
- return (
59
- <WhiteboardProvider webSocketUrl="wss://your-websocket-server.com">
60
- <div>
61
- <select value={currentRoom} onChange={(e) => setCurrentRoom(e.target.value)}>
62
- <option value="room-1">Room 1</option>
63
- <option value="room-2">Room 2</option>
64
- <option value="room-3">Room 3</option>
65
- </select>
66
-
67
- <Whiteboard
68
- roomId={currentRoom}
69
- userId={currentUser}
70
- isAdmin={currentUser === 'admin-user'}
71
- allowedUsers={[currentUser, 'other-user-1', 'other-user-2']}
72
- />
73
- </div>
74
- </WhiteboardProvider>
75
- );
76
- }
77
- ```
78
-
79
- ## 📝 API Reference
80
-
81
- ### WhiteboardProvider Props
82
-
83
- | Prop | Type | Required | Description |
84
- |------|------|----------|-------------|
85
- | `webSocketUrl` | `string` | ✅ | WebSocket server URL for real-time collaboration |
86
- | `children` | `ReactNode` | ✅ | Child components (typically contains `<Whiteboard>`) |
87
-
88
- ### Whiteboard Props
89
-
90
- | Prop | Type | Required | Default | Description |
91
- |------|------|----------|---------|-------------|
92
- | `roomId` | `string` | ✅ | - | Unique identifier for the collaboration room |
93
- | `userId` | `string` | ✅ | - | Unique identifier for the current user |
94
- | `isAdmin` | `boolean` | ❌ | `false` | Whether user has admin privileges (clear, lock/unlock) |
95
- | `allowedUsers` | `string[]` | ❌ | `[]` | Array of user IDs who have drawing permissions |
96
-
97
- ### Hooks
98
-
99
- #### useWhiteboardStream
100
-
101
- Automatically captures the whiteboard canvas as a video stream (30 FPS). No manual start/stop controls needed.
102
-
103
- ```tsx
104
- import { useWhiteboardStream } from '@ngenux/ngage-whiteboarding';
105
-
106
- function VideoStreamComponent() {
107
- const { mediaStream } = useWhiteboardStream();
108
-
109
- return (
110
- <div>
111
- {mediaStream && (
112
- <video
113
- srcObject={mediaStream}
114
- autoPlay
115
- muted
116
- style={{ width: '300px', height: '200px' }}
117
- />
118
- )}
119
- </div>
120
- );
121
- }
122
- ```
123
-
124
- **Note:** Stream capture starts automatically when the whiteboard canvas is available and can be controlled via the whiteboard context's `captureEnabled` state.
125
-
126
- ## 🎨 Features in Detail
127
-
128
- ### Drawing Tools
129
- - **Pencil**: Freehand drawing
130
- - **Shapes**: Rectangle, Ellipse, Arrow, Line
131
- - **Eraser**: Remove parts of drawings
132
- - **Select**: Move and transform shapes
133
- - **Pan**: Navigate around the canvas
134
-
135
- ### Collaborative Features
136
- - **Real-time drawing**: See other users draw in real-time
137
- - **User permissions**: Control who can draw
138
- - **Admin controls**: Lock/unlock canvas, clear all drawings
139
- - **Per-user undo/redo**: Each user maintains their own undo stack
140
-
141
- ### Export Options
142
- - **PNG**: Transparent or solid background
143
- - **JPEG**: Solid background (white if transparent is selected)
144
- - **PDF-format**: High-quality PNG optimized for printing/PDF conversion
145
-
146
- ## đŸ› ī¸ Development
147
-
148
- ### Building the Package
149
-
150
- ```bash
151
- # Install dependencies
152
- npm install
153
-
154
- # Build the package
155
- npm run build
156
-
157
- # Watch mode for development
158
- npm run dev
159
-
160
- # Preview package contents
161
- npm run pack-preview
162
-
163
- # Clean build artifacts
164
- npm run clean
165
- ```
166
-
167
- ### Package Structure
168
-
169
- ```
170
- dist/
171
- ├── index.js # CommonJS build
172
- ├── index.esm.js # ES modules build
173
- ├── index.d.ts # TypeScript definitions
174
- └── *.map # Source maps
175
- ```
176
-
177
- ## 🔧 TypeScript Support
178
-
179
- The package includes full TypeScript definitions:
180
-
181
- ```tsx
182
- import type {
183
- WhiteboardProps,
184
- WhiteboardProviderProps,
185
- ToolType,
186
- StrokeStyle
187
- } from '@ngenux/ngage-whiteboarding';
188
-
189
- const MyWhiteboard: React.FC<WhiteboardProps> = (props) => {
190
- // Your implementation
191
- };
192
- ```
193
-
194
- ## 🌐 Browser Support
195
-
196
- - Chrome 80+
197
- - Firefox 75+
198
- - Safari 13+
199
- - Edge 80+
200
-
201
- ## 📱 Responsive Design
202
-
203
- The whiteboard automatically adapts to different screen sizes and supports touch interactions on mobile devices.
204
-
205
- ## ⚡ Performance
206
-
207
- - **Optimized rendering**: Uses Konva.js for high-performance 2D canvas rendering
208
- - **Data compression**: Automatic compression of collaborative data
209
- - **Throttled updates**: Optimized for 60fps real-time collaboration
210
- - **Memory efficient**: Smart cleanup of stale collaborative data
211
-
212
- ## 🐛 Troubleshooting
213
-
214
- ### Common Issues
215
-
216
- 1. **WebSocket connection fails**
217
- - Ensure your WebSocket server is running and accessible
218
- - Check CORS configuration on your server
219
- - Verify the `webSocketUrl` is correct
220
-
221
- 2. **Drawing doesn't sync between users**
222
- - Verify all users are in the same `roomId`
223
- - Check WebSocket server is properly broadcasting messages
224
- - Ensure `userId` is unique for each user
225
-
226
- 3. **TypeScript errors**
227
- - Make sure you're importing types correctly
228
- - Verify your TypeScript configuration includes the package types
229
-
230
- ## 📄 License
231
-
232
- MIT
233
-
234
- ## 🤝 Contributing
235
-
236
- Contributions are welcome! Please feel free to submit a Pull Request.
237
-
238
- ## 📞 Support
239
-
240
- If you encounter any issues or have questions, please file an issue on the GitHub repository.
241
-
242
- ---
243
-
244
- ## 👨‍đŸ’ģ Author
245
-
246
- **ng-sushil**
247
- - GitHub: [@ng-sushil](https://github.com/ng-sushil)
248
-
1
+ # React Collaborative Whiteboard
2
+
3
+ A React component library for creating collaborative whiteboards with real-time synchronization via WebSockets.
4
+
5
+ ## ✨ Features
6
+
7
+ - 🎨 **Real-time collaborative drawing** - Multiple users can draw simultaneously
8
+ - 🔧 **Multiple drawing tools** - Pencil, shapes (rectangle, ellipse, arrow), eraser, line tools
9
+ - â†Šī¸ **Undo/Redo functionality** - Per-user undo/redo with collaborative support
10
+ - đŸ‘Ĩ **Multi-user support** - Admin controls and user permissions
11
+ - 📱 **Responsive design** - Works on desktop, tablet, and mobile
12
+ - 🔒 **Admin controls** - Lock/unlock canvas, clear canvas, user management
13
+ - 💾 **Export functionality** - PNG, JPEG, PDF export options
14
+ - đŸ—œī¸ **Data compression** - Optimized performance with automatic compression
15
+ - ⚡ **Real-time sync** - Ultra-smooth 60fps collaborative drawing experience
16
+ - đŸŽ¯ **TypeScript support** - Fully typed for better development experience
17
+
18
+ ## 📋 Prerequisites
19
+
20
+ This package requires the following dependencies in your project:
21
+
22
+ - **React** 16.8+ (with Hooks support)
23
+ - **Tailwind CSS** 3.0+ (for styling)
24
+ - **Vite** or similar modern bundler (recommended)
25
+
26
+ ### Optional but Recommended:
27
+ - **shadcn/ui** setup for consistent design system
28
+
29
+ ## đŸ“Ļ Installation
30
+
31
+ ### Step 1: Install the Package
32
+
33
+ ```bash
34
+ npm install @ngenux/ngage-whiteboarding
35
+ ```
36
+
37
+ ### Step 2: Setup Tailwind CSS (if not already installed)
38
+
39
+ ```bash
40
+ npm install -D tailwindcss postcss autoprefixer
41
+ npx tailwindcss init -p
42
+ ```
43
+
44
+ ### Step 3: Configure Tailwind
45
+
46
+ Update your `tailwind.config.js` to include the package components:
47
+
48
+ ```js
49
+ /** @type {import('tailwindcss').Config} */
50
+ module.exports = {
51
+ content: [
52
+ "./src/**/*.{js,ts,jsx,tsx}",
53
+ "./node_modules/@ngenux/ngage-whiteboarding/**/*.{js,jsx,ts,tsx}",
54
+ ],
55
+ theme: {
56
+ extend: {},
57
+ },
58
+ plugins: [],
59
+ }
60
+ ```
61
+
62
+ ### Step 4: Import Styles
63
+
64
+ Add the package CSS to your main CSS file or import it in your main component:
65
+
66
+ ```css
67
+ /* In your main CSS file (e.g., src/index.css) */
68
+ @tailwind base;
69
+ @tailwind components;
70
+ @tailwind utilities;
71
+ ```
72
+
73
+ ```tsx
74
+ // Or import in your main component
75
+ import '@ngenux/ngage-whiteboarding/dist/styles.css';
76
+ ```
77
+
78
+ ### Step 5: Verify Setup
79
+
80
+ Create a simple test component to verify everything is working:
81
+
82
+ ```tsx
83
+ import React from 'react';
84
+ import '@ngenux/ngage-whiteboarding/dist/styles.css';
85
+ import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';
86
+
87
+ function TestWhiteboard() {
88
+ return (
89
+ <div style={{ width: '100vw', height: '100vh' }}>
90
+ <WhiteboardProvider webSocketUrl="ws://localhost:3001">
91
+ <Whiteboard
92
+ roomId="test-room"
93
+ userId="test-user"
94
+ isAdmin={true}
95
+ allowedUsers={['test-user']}
96
+ />
97
+ </WhiteboardProvider>
98
+ </div>
99
+ );
100
+ }
101
+
102
+ export default TestWhiteboard;
103
+ ```
104
+
105
+ If you see a styled whiteboard with a toolbar and sidebar, your setup is complete! 🎉
106
+
107
+ ## 🚀 Quick Start
108
+
109
+ ### Basic Setup
110
+
111
+ ```tsx
112
+ import React from 'react';
113
+ import '@ngenux/ngage-whiteboarding/dist/styles.css'; // Import the CSS
114
+ import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';
115
+
116
+ function App() {
117
+ return (
118
+ <WhiteboardProvider webSocketUrl="ws://localhost:3001">
119
+ <Whiteboard
120
+ roomId="room-123"
121
+ userId="user-456"
122
+ isAdmin={true}
123
+ allowedUsers={['user-456', 'user-789']}
124
+ />
125
+ </WhiteboardProvider>
126
+ );
127
+ }
128
+
129
+ export default App;
130
+ ```
131
+
132
+ ### For Vite Projects
133
+
134
+ If you're using Vite, make sure your `vite.config.js` includes:
135
+
136
+ ```js
137
+ import { defineConfig } from 'vite'
138
+ import react from '@vitejs/plugin-react'
139
+
140
+ export default defineConfig({
141
+ plugins: [react()],
142
+ css: {
143
+ postcss: './postcss.config.js', // Ensure PostCSS is configured
144
+ },
145
+ })
146
+ ```
147
+
148
+ ### For shadcn/ui Projects
149
+
150
+ If you're using shadcn/ui, you can enhance the integration with our utility functions:
151
+
152
+ ```tsx
153
+ import { cn } from '@ngenux/ngage-whiteboarding'; // Use our cn utility
154
+
155
+ // Or use with your existing shadcn/ui cn function
156
+ import { cn } from '@/lib/utils';
157
+ import { Whiteboard } from '@ngenux/ngage-whiteboarding';
158
+
159
+ const customClasses = cn('your-custom-classes', 'conditional-class');
160
+ ```
161
+
162
+ ### Advanced Usage with Multiple Rooms
163
+
164
+ ```tsx
165
+ import React, { useState } from 'react';
166
+ import { WhiteboardProvider, Whiteboard } from '@ngenux/ngage-whiteboarding';
167
+
168
+ function CollaborativeApp() {
169
+ const [currentRoom, setCurrentRoom] = useState('room-1');
170
+ const [currentUser] = useState('user-' + Math.random().toString(36).substr(2, 9));
171
+
172
+ return (
173
+ <WhiteboardProvider webSocketUrl="wss://your-websocket-server.com">
174
+ <div>
175
+ <select value={currentRoom} onChange={(e) => setCurrentRoom(e.target.value)}>
176
+ <option value="room-1">Room 1</option>
177
+ <option value="room-2">Room 2</option>
178
+ <option value="room-3">Room 3</option>
179
+ </select>
180
+
181
+ <Whiteboard
182
+ roomId={currentRoom}
183
+ userId={currentUser}
184
+ isAdmin={currentUser === 'admin-user'}
185
+ allowedUsers={[currentUser, 'other-user-1', 'other-user-2']}
186
+ />
187
+ </div>
188
+ </WhiteboardProvider>
189
+ );
190
+ }
191
+ ```
192
+
193
+ ## 📝 API Reference
194
+
195
+ ### WhiteboardProvider Props
196
+
197
+ | Prop | Type | Required | Description |
198
+ |------|------|----------|-------------|
199
+ | `webSocketUrl` | `string` | ✅ | WebSocket server URL for real-time collaboration |
200
+ | `children` | `ReactNode` | ✅ | Child components (typically contains `<Whiteboard>`) |
201
+
202
+ ### Whiteboard Props
203
+
204
+ | Prop | Type | Required | Default | Description |
205
+ |------|------|----------|---------|-------------|
206
+ | `roomId` | `string` | ✅ | - | Unique identifier for the collaboration room |
207
+ | `userId` | `string` | ✅ | - | Unique identifier for the current user |
208
+ | `isAdmin` | `boolean` | ❌ | `false` | Whether user has admin privileges (clear, lock/unlock) |
209
+ | `allowedUsers` | `string[]` | ❌ | `[]` | Array of user IDs who have drawing permissions |
210
+
211
+ ### Hooks
212
+
213
+ #### useWhiteboardStream
214
+
215
+ Automatically captures the whiteboard canvas as a video stream (30 FPS). No manual start/stop controls needed.
216
+
217
+ ```tsx
218
+ import { useWhiteboardStream } from '@ngenux/ngage-whiteboarding';
219
+
220
+ function VideoStreamComponent() {
221
+ const { mediaStream } = useWhiteboardStream();
222
+
223
+ return (
224
+ <div>
225
+ {mediaStream && (
226
+ <video
227
+ srcObject={mediaStream}
228
+ autoPlay
229
+ muted
230
+ style={{ width: '300px', height: '200px' }}
231
+ />
232
+ )}
233
+ </div>
234
+ );
235
+ }
236
+ ```
237
+
238
+ **Note:** Stream capture starts automatically when the whiteboard canvas is available and can be controlled via the whiteboard context's `captureEnabled` state.
239
+
240
+ ## 🎨 Features in Detail
241
+
242
+ ### Drawing Tools
243
+ - **Pencil**: Freehand drawing
244
+ - **Shapes**: Rectangle, Ellipse, Arrow, Line
245
+ - **Eraser**: Remove parts of drawings
246
+ - **Select**: Move and transform shapes
247
+ - **Pan**: Navigate around the canvas
248
+
249
+ ### Collaborative Features
250
+ - **Real-time drawing**: See other users draw in real-time
251
+ - **User permissions**: Control who can draw
252
+ - **Admin controls**: Lock/unlock canvas, clear all drawings
253
+ - **Per-user undo/redo**: Each user maintains their own undo stack
254
+
255
+ ### Export Options
256
+ - **PNG**: Transparent or solid background
257
+ - **JPEG**: Solid background (white if transparent is selected)
258
+ - **PDF-format**: High-quality PNG optimized for printing/PDF conversion
259
+
260
+ ## 🔧 TypeScript Support
261
+
262
+ The package includes full TypeScript definitions:
263
+
264
+ ```tsx
265
+ import type {
266
+ WhiteboardProps,
267
+ WhiteboardProviderProps,
268
+ ToolType,
269
+ StrokeStyle
270
+ } from '@ngenux/ngage-whiteboarding';
271
+
272
+ const MyWhiteboard: React.FC<WhiteboardProps> = (props) => {
273
+ // Your implementation
274
+ };
275
+ ```
276
+
277
+ ## 🌐 Browser Support
278
+
279
+ - Chrome 80+
280
+ - Firefox 75+
281
+ - Safari 13+
282
+ - Edge 80+
283
+
284
+ **Note:** Requires a modern browser with WebSocket support and ES6+ features.
285
+
286
+ ## 📱 Responsive Design
287
+
288
+ The whiteboard automatically adapts to different screen sizes and supports touch interactions on mobile devices.
289
+
290
+ ## ⚡ Performance
291
+
292
+ - **Optimized rendering**: Uses Konva.js for high-performance 2D canvas rendering
293
+ - **Data compression**: Automatic compression of collaborative data
294
+ - **Throttled updates**: Optimized for 60fps real-time collaboration
295
+ - **Memory efficient**: Smart cleanup of stale collaborative data
296
+
297
+ ## 🐛 Troubleshooting
298
+
299
+ ### Common Issues
300
+
301
+ 1. **Styles not appearing / Components look unstyled**
302
+ - ✅ Ensure Tailwind CSS is installed and configured in your project
303
+ - ✅ Add the package path to your `tailwind.config.js` content array
304
+ - ✅ Import the package CSS: `import '@ngenux/ngage-whiteboarding/dist/styles.css'`
305
+ - ✅ Verify your PostCSS configuration is working
306
+
307
+ 2. **WebSocket connection fails**
308
+ - Ensure your WebSocket server is running and accessible
309
+ - Check CORS configuration on your server
310
+ - Verify the `webSocketUrl` is correct
311
+
312
+ 3. **Drawing doesn't sync between users**
313
+ - Verify all users are in the same `roomId`
314
+ - Check WebSocket server is properly broadcasting messages
315
+ - Ensure `userId` is unique for each user
316
+
317
+ 4. **TypeScript errors**
318
+ - Make sure you're importing types correctly
319
+ - Verify your TypeScript configuration includes the package types
320
+ - Ensure React types are properly installed
321
+
322
+ 5. **Build errors with Vite/bundler**
323
+ - Update to the latest version of your bundler
324
+ - Ensure PostCSS and Tailwind plugins are properly configured
325
+ - Check that the package is included in your bundler's dependency optimization
326
+
327
+ ## 📄 License
328
+
329
+ MIT
330
+
331
+
332
+ ## 📞 Support
333
+
334
+ If you encounter any issues or have questions, please file an issue on the [GitHub repository](https://github.com/ngenux-accelerators/ngage-whiteboarding/issues).
335
+
336
+ ---
337
+
338
+ ## 👨‍đŸ’ģ Author
339
+
340
+ **ng-sushil**
341
+ - GitHub: [@ng-sushil](https://github.com/ng-sushil)
342
+
249
343
  **Happy collaborating! 🎨✨**
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import './src/styles.css';
1
2
  import { Whiteboard } from './src/components/Whiteboard';
2
3
  import { WhiteboardProvider } from './src/context/WhiteboardContext';
3
4
  import { useCapture } from './src/hooks/useCapture';
4
- export { Whiteboard, WhiteboardProvider, useCapture as useWhiteboardStream };
5
+ import { cn } from './src/lib/utils';
6
+ export { Whiteboard, WhiteboardProvider, useCapture as useWhiteboardStream, cn };
5
7
  export type { WhiteboardProps } from './src/components/Whiteboard';
6
8
  export type { ShapeProps, ToolType, StrokeStyle, WhiteboardState, DrawingAction, CompressedData } from './src/types';
7
9
  export interface WhiteboardProviderProps {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,IAAI,mBAAmB,EAAE,CAAC;AAG7E,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.tsx"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,IAAI,mBAAmB,EAAE,EAAE,EAAE,CAAC;AAGjF,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}