@mentra/sdk 2.1.1 โ†’ 2.1.2-alpha.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.
Files changed (60) hide show
  1. package/dist/app/session/events.d.ts +4 -2
  2. package/dist/app/session/events.d.ts.map +1 -1
  3. package/dist/app/session/events.js +3 -0
  4. package/dist/app/session/index.d.ts +21 -5
  5. package/dist/app/session/index.d.ts.map +1 -1
  6. package/dist/app/session/index.js +80 -21
  7. package/dist/app/session/modules/audio.d.ts +190 -0
  8. package/dist/app/session/modules/audio.d.ts.map +1 -0
  9. package/dist/app/session/modules/audio.js +317 -0
  10. package/dist/app/session/modules/camera-managed-extension.d.ts +154 -0
  11. package/dist/app/session/modules/camera-managed-extension.d.ts.map +1 -0
  12. package/dist/app/session/modules/camera-managed-extension.js +239 -0
  13. package/dist/app/session/modules/camera.d.ts +55 -1
  14. package/dist/app/session/modules/camera.d.ts.map +1 -1
  15. package/dist/app/session/modules/camera.js +72 -0
  16. package/dist/app/session/modules/index.d.ts +4 -0
  17. package/dist/app/session/modules/index.d.ts.map +1 -0
  18. package/dist/app/session/modules/index.js +19 -0
  19. package/dist/app/session/modules/location.d.ts +16 -0
  20. package/dist/app/session/modules/location.d.ts.map +1 -0
  21. package/dist/app/session/modules/location.js +55 -0
  22. package/dist/app/webview/index.d.ts.map +1 -1
  23. package/dist/app/webview/index.js +0 -1
  24. package/dist/examples/managed-rtmp-streaming-example.d.ts +2 -0
  25. package/dist/examples/managed-rtmp-streaming-example.d.ts.map +1 -0
  26. package/dist/examples/managed-rtmp-streaming-example.js +158 -0
  27. package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts +11 -0
  28. package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts.map +1 -0
  29. package/dist/examples/managed-rtmp-streaming-with-restream-example.js +124 -0
  30. package/dist/index.d.ts +4 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +5 -1
  33. package/dist/types/enums.d.ts +3 -1
  34. package/dist/types/enums.d.ts.map +1 -1
  35. package/dist/types/enums.js +2 -0
  36. package/dist/types/index.d.ts +6 -6
  37. package/dist/types/index.d.ts.map +1 -1
  38. package/dist/types/index.js +7 -1
  39. package/dist/types/message-types.d.ts +16 -4
  40. package/dist/types/message-types.d.ts.map +1 -1
  41. package/dist/types/message-types.js +19 -3
  42. package/dist/types/messages/app-to-cloud.d.ts +76 -3
  43. package/dist/types/messages/app-to-cloud.d.ts.map +1 -1
  44. package/dist/types/messages/app-to-cloud.js +28 -0
  45. package/dist/types/messages/cloud-to-app.d.ts +45 -1
  46. package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
  47. package/dist/types/messages/cloud-to-app.js +8 -0
  48. package/dist/types/messages/cloud-to-glasses.d.ts +38 -1
  49. package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -1
  50. package/dist/types/messages/cloud-to-glasses.js +8 -0
  51. package/dist/types/messages/glasses-to-cloud.d.ts +21 -4
  52. package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
  53. package/dist/types/messages/glasses-to-cloud.js +7 -3
  54. package/dist/types/models.d.ts +13 -0
  55. package/dist/types/models.d.ts.map +1 -1
  56. package/dist/types/models.js +9 -0
  57. package/dist/types/streams.d.ts +7 -1
  58. package/dist/types/streams.d.ts.map +1 -1
  59. package/dist/types/streams.js +6 -2
  60. package/package.json +1 -1
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ /**
3
+ * ๐Ÿ”Š Audio Module
4
+ *
5
+ * Audio functionality for App Sessions.
6
+ * Handles audio playback on connected glasses.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AudioManager = void 0;
10
+ const types_1 = require("../../../types");
11
+ /**
12
+ * ๐Ÿ”Š Audio Module Implementation
13
+ *
14
+ * Audio management for App Sessions.
15
+ * Provides methods for:
16
+ * - ๐ŸŽต Playing audio on glasses
17
+ * - โน๏ธ Stopping audio playback
18
+ * - ๐Ÿ” Monitoring audio request status
19
+ * - ๐Ÿงน Cleanup and cancellation
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Play audio
24
+ * const result = await session.audio.playAudio({
25
+ * audioUrl: 'https://example.com/sound.mp3',
26
+ * volume: 0.8
27
+ * });
28
+ *
29
+ * // Stop all audio
30
+ * session.audio.stopAudio();
31
+ * ```
32
+ */
33
+ class AudioManager {
34
+ /**
35
+ * Create a new AudioManager
36
+ *
37
+ * @param packageName - The App package name
38
+ * @param sessionId - The current session ID
39
+ * @param send - Function to send messages to the cloud
40
+ * @param session - Reference to the parent AppSession (optional)
41
+ * @param logger - Logger instance for debugging
42
+ */
43
+ constructor(packageName, sessionId, send, session, logger) {
44
+ /** Map to store pending audio play request promises */
45
+ this.pendingAudioRequests = new Map();
46
+ this.packageName = packageName;
47
+ this.sessionId = sessionId;
48
+ this.send = send;
49
+ this.session = session;
50
+ this.logger = logger || console;
51
+ }
52
+ // =====================================
53
+ // ๐ŸŽต Audio Playback Functionality
54
+ // =====================================
55
+ /**
56
+ * ๐Ÿ”Š Play audio on the connected glasses
57
+ * @param options - Audio playback configuration
58
+ * @returns Promise that resolves with playback result
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * // Play audio from URL
63
+ * const result = await session.audio.playAudio({
64
+ * audioUrl: 'https://example.com/sound.mp3',
65
+ * volume: 0.8
66
+ * });
67
+ * ```
68
+ */
69
+ async playAudio(options) {
70
+ return new Promise((resolve, reject) => {
71
+ try {
72
+ // Validate input
73
+ if (!options.audioUrl) {
74
+ reject(new Error('audioUrl must be provided'));
75
+ return;
76
+ }
77
+ // Generate unique request ID
78
+ const requestId = `audio_req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
79
+ // Store promise resolvers for when we get the response
80
+ this.pendingAudioRequests.set(requestId, { resolve, reject });
81
+ // Create audio play request message
82
+ const message = {
83
+ type: types_1.AppToCloudMessageType.AUDIO_PLAY_REQUEST,
84
+ packageName: this.packageName,
85
+ sessionId: this.sessionId,
86
+ requestId,
87
+ timestamp: new Date(),
88
+ audioUrl: options.audioUrl,
89
+ volume: options.volume ?? 1.0,
90
+ stopOtherAudio: options.stopOtherAudio ?? true
91
+ };
92
+ // Send request to cloud
93
+ this.send(message);
94
+ // Set timeout to avoid hanging promises
95
+ const timeoutMs = 60000; // 60 seconds
96
+ if (this.session && this.session.resources) {
97
+ // Use session's resource tracker for automatic cleanup
98
+ this.session.resources.setTimeout(() => {
99
+ if (this.pendingAudioRequests.has(requestId)) {
100
+ this.pendingAudioRequests.get(requestId).reject(new Error('Audio play request timed out'));
101
+ this.pendingAudioRequests.delete(requestId);
102
+ this.logger.warn({ requestId }, `๐Ÿ”Š Audio play request timed out`);
103
+ }
104
+ }, timeoutMs);
105
+ }
106
+ else {
107
+ // Fallback to regular setTimeout if session not available
108
+ setTimeout(() => {
109
+ if (this.pendingAudioRequests.has(requestId)) {
110
+ this.pendingAudioRequests.get(requestId).reject(new Error('Audio play request timed out'));
111
+ this.pendingAudioRequests.delete(requestId);
112
+ this.logger.warn({ requestId }, `๐Ÿ”Š Audio play request timed out`);
113
+ }
114
+ }, timeoutMs);
115
+ }
116
+ }
117
+ catch (error) {
118
+ const errorMessage = error instanceof Error ? error.message : String(error);
119
+ reject(new Error(`Failed to play audio: ${errorMessage}`));
120
+ }
121
+ });
122
+ }
123
+ /**
124
+ * ๐Ÿ”‡ Stop audio playback on the connected glasses
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * // Stop all currently playing audio
129
+ * session.audio.stopAudio();
130
+ * ```
131
+ */
132
+ stopAudio() {
133
+ try {
134
+ // Create audio stop request message
135
+ const message = {
136
+ type: types_1.AppToCloudMessageType.AUDIO_STOP_REQUEST,
137
+ packageName: this.packageName,
138
+ sessionId: this.sessionId,
139
+ timestamp: new Date()
140
+ };
141
+ // Send request to cloud (one-way, no response expected)
142
+ this.send(message);
143
+ this.logger.info(`๐Ÿ”‡ Audio stop request sent`);
144
+ }
145
+ catch (error) {
146
+ const errorMessage = error instanceof Error ? error.message : String(error);
147
+ this.logger.error(`Failed to stop audio: ${errorMessage}`);
148
+ }
149
+ }
150
+ /**
151
+ * ๐Ÿ—ฃ๏ธ Convert text to speech and play it on the connected glasses
152
+ * @param text - Text to convert to speech (required)
153
+ * @param options - Text-to-speech configuration (optional)
154
+ * @returns Promise that resolves with playback result
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * // Basic text-to-speech
159
+ * const result = await session.audio.speak('Hello, world!');
160
+ *
161
+ * // With custom voice settings
162
+ * const result = await session.audio.speak('Hello, world!', {
163
+ * voice_id: 'your_voice_id',
164
+ * voice_settings: {
165
+ * stability: 0.5,
166
+ * speed: 1.2
167
+ * },
168
+ * volume: 0.8
169
+ * });
170
+ * ```
171
+ */
172
+ async speak(text, options = {}) {
173
+ // Validate input
174
+ if (!text) {
175
+ throw new Error('text must be provided');
176
+ }
177
+ // Get the HTTPS server URL from the session
178
+ const baseUrl = this.session?.getHttpsServerUrl?.();
179
+ if (!baseUrl) {
180
+ throw new Error('Cannot determine server URL for TTS endpoint');
181
+ }
182
+ // Build query parameters for the TTS endpoint
183
+ const queryParams = new URLSearchParams();
184
+ queryParams.append('text', text);
185
+ if (options.voice_id) {
186
+ queryParams.append('voice_id', options.voice_id);
187
+ }
188
+ if (options.model_id) {
189
+ queryParams.append('model_id', options.model_id);
190
+ }
191
+ if (options.voice_settings) {
192
+ queryParams.append('voice_settings', JSON.stringify(options.voice_settings));
193
+ }
194
+ // Construct the TTS URL
195
+ const ttsUrl = `${baseUrl}/api/tts?${queryParams.toString()}`;
196
+ this.logger.info({ text, ttsUrl }, `๐Ÿ—ฃ๏ธ Generating speech from text`);
197
+ // Use the existing playAudio method to play the TTS audio
198
+ return this.playAudio({
199
+ audioUrl: ttsUrl,
200
+ volume: options.volume
201
+ });
202
+ }
203
+ // =====================================
204
+ // ๐Ÿ“ฅ Response Handling
205
+ // =====================================
206
+ /**
207
+ * ๐Ÿ“ฅ Handle audio play response from cloud
208
+ *
209
+ * This method is called internally when an audio play response is received.
210
+ * It resolves the corresponding pending promise with the response data.
211
+ *
212
+ * @param response - The audio play response received
213
+ * @internal This method is used internally by AppSession
214
+ */
215
+ handleAudioPlayResponse(response) {
216
+ const pendingRequest = this.pendingAudioRequests.get(response.requestId);
217
+ if (pendingRequest) {
218
+ // Resolve the promise with the response data
219
+ pendingRequest.resolve({
220
+ success: response.success,
221
+ error: response.error,
222
+ duration: response.duration
223
+ });
224
+ // Clean up
225
+ this.pendingAudioRequests.delete(response.requestId);
226
+ this.logger.info({
227
+ requestId: response.requestId,
228
+ success: response.success,
229
+ duration: response.duration
230
+ }, `๐Ÿ”Š Audio play response received`);
231
+ }
232
+ else {
233
+ this.logger.warn({ requestId: response.requestId }, `๐Ÿ”Š Received audio play response for unknown request ID`);
234
+ }
235
+ }
236
+ // =====================================
237
+ // ๐Ÿ” Status and Management
238
+ // =====================================
239
+ /**
240
+ * ๐Ÿ” Check if there are pending audio requests
241
+ * @param requestId - Optional specific request ID to check
242
+ * @returns True if there are pending requests (or specific request exists)
243
+ */
244
+ hasPendingRequest(requestId) {
245
+ if (requestId) {
246
+ return this.pendingAudioRequests.has(requestId);
247
+ }
248
+ return this.pendingAudioRequests.size > 0;
249
+ }
250
+ /**
251
+ * ๐Ÿ“Š Get the number of pending audio requests
252
+ * @returns Number of pending requests
253
+ */
254
+ getPendingRequestCount() {
255
+ return this.pendingAudioRequests.size;
256
+ }
257
+ /**
258
+ * ๐Ÿ“‹ Get all pending request IDs
259
+ * @returns Array of pending request IDs
260
+ */
261
+ getPendingRequestIds() {
262
+ return Array.from(this.pendingAudioRequests.keys());
263
+ }
264
+ /**
265
+ * โŒ Cancel a specific audio request
266
+ * @param requestId - The request ID to cancel
267
+ * @returns True if the request was found and cancelled
268
+ */
269
+ cancelAudioRequest(requestId) {
270
+ const pendingRequest = this.pendingAudioRequests.get(requestId);
271
+ if (pendingRequest) {
272
+ pendingRequest.reject(new Error('Audio request cancelled'));
273
+ this.pendingAudioRequests.delete(requestId);
274
+ this.logger.info({ requestId }, `๐Ÿ”Š Audio request cancelled`);
275
+ return true;
276
+ }
277
+ return false;
278
+ }
279
+ /**
280
+ * ๐Ÿงน Cancel all pending audio requests
281
+ * @returns Number of requests that were cancelled
282
+ */
283
+ cancelAllAudioRequests() {
284
+ const count = this.pendingAudioRequests.size;
285
+ this.pendingAudioRequests.forEach((request, requestId) => {
286
+ request.reject(new Error('Audio request cancelled due to cleanup'));
287
+ this.logger.debug({ requestId }, `๐Ÿ”Š Audio request cancelled during cleanup`);
288
+ });
289
+ this.pendingAudioRequests.clear();
290
+ if (count > 0) {
291
+ this.logger.info({ cancelledCount: count }, `๐Ÿงน Cancelled all pending audio requests`);
292
+ }
293
+ return count;
294
+ }
295
+ // =====================================
296
+ // ๐Ÿ”ง Internal Management
297
+ // =====================================
298
+ /**
299
+ * ๐Ÿ”„ Update the session ID when reconnecting
300
+ * @param newSessionId - The new session ID
301
+ * @internal Used by AppSession during reconnection
302
+ */
303
+ updateSessionId(newSessionId) {
304
+ this.sessionId = newSessionId;
305
+ this.logger.debug({ newSessionId }, `๐Ÿ”„ Audio module session ID updated`);
306
+ }
307
+ /**
308
+ * ๐Ÿงน Cancel all pending requests (cleanup)
309
+ * @returns Object with count of cancelled requests
310
+ * @internal Used by AppSession during cleanup
311
+ */
312
+ cancelAllRequests() {
313
+ const audioRequests = this.cancelAllAudioRequests();
314
+ return { audioRequests };
315
+ }
316
+ }
317
+ exports.AudioManager = AudioManager;
@@ -0,0 +1,154 @@
1
+ /**
2
+ * ๐Ÿ“ท Camera Module Managed Streaming Extension
3
+ *
4
+ * Extends the camera module with managed streaming capabilities.
5
+ * Apps can request managed streams and receive HLS/DASH URLs without managing RTMP endpoints.
6
+ */
7
+ import { ManagedStreamStatus, RestreamDestination } from '../../../types';
8
+ import { VideoConfig, AudioConfig, StreamConfig } from '../../../types/rtmp-stream';
9
+ import { Logger } from 'pino';
10
+ /**
11
+ * Configuration options for a managed stream
12
+ */
13
+ export interface ManagedStreamOptions {
14
+ /** Stream quality preset */
15
+ quality?: '720p' | '1080p';
16
+ /** Enable WebRTC for ultra-low latency viewing */
17
+ enableWebRTC?: boolean;
18
+ /** Optional video configuration settings */
19
+ video?: VideoConfig;
20
+ /** Optional audio configuration settings */
21
+ audio?: AudioConfig;
22
+ /** Optional stream configuration settings */
23
+ stream?: StreamConfig;
24
+ /** Optional RTMP destinations to re-stream to (YouTube, Twitch, etc) */
25
+ restreamDestinations?: RestreamDestination[];
26
+ }
27
+ /**
28
+ * Result returned when starting a managed stream
29
+ */
30
+ export interface ManagedStreamResult {
31
+ /** HLS URL for viewing the stream */
32
+ hlsUrl: string;
33
+ /** DASH URL for viewing the stream */
34
+ dashUrl: string;
35
+ /** WebRTC URL if enabled */
36
+ webrtcUrl?: string;
37
+ /** Internal stream ID */
38
+ streamId: string;
39
+ }
40
+ /**
41
+ * ๐Ÿ“น Managed Streaming Extension for Camera Module
42
+ *
43
+ * Provides managed streaming capabilities where the cloud handles
44
+ * RTMP endpoints and returns HLS/DASH URLs for viewing.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * // Start a managed stream
49
+ * const urls = await session.camera.startManagedStream({
50
+ * quality: '720p',
51
+ * enableWebRTC: true
52
+ * });
53
+ * console.log('HLS URL:', urls.hlsUrl);
54
+ * console.log('DASH URL:', urls.dashUrl);
55
+ *
56
+ * // Monitor managed stream status
57
+ * session.camera.onManagedStreamStatus((status) => {
58
+ * console.log('Managed stream status:', status.status);
59
+ * });
60
+ *
61
+ * // Stop managed stream
62
+ * await session.camera.stopManagedStream();
63
+ * ```
64
+ */
65
+ export declare class CameraManagedExtension {
66
+ private send;
67
+ private packageName;
68
+ private sessionId;
69
+ private logger;
70
+ private session?;
71
+ private isManagedStreaming;
72
+ private currentManagedStreamId?;
73
+ private currentManagedStreamUrls?;
74
+ private managedStreamStatus?;
75
+ private pendingManagedStreamRequest?;
76
+ constructor(packageName: string, sessionId: string, send: (message: any) => void, logger: Logger, session?: any);
77
+ /**
78
+ * ๐Ÿ“น Start a managed stream
79
+ *
80
+ * The cloud will handle the RTMP endpoint and return HLS/DASH URLs for viewing.
81
+ * Multiple apps can consume the same managed stream simultaneously.
82
+ *
83
+ * @param options - Configuration options for the managed stream
84
+ * @returns Promise that resolves with viewing URLs when the stream is ready
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const urls = await session.camera.startManagedStream({
89
+ * quality: '1080p',
90
+ * enableWebRTC: true,
91
+ * video: { fps: 30 },
92
+ * audio: { sampleRate: 48000 }
93
+ * });
94
+ * ```
95
+ */
96
+ startManagedStream(options?: ManagedStreamOptions): Promise<ManagedStreamResult>;
97
+ /**
98
+ * ๐Ÿ›‘ Stop the current managed stream
99
+ *
100
+ * This will stop streaming for this app only. If other apps are consuming
101
+ * the same managed stream, it will continue for them.
102
+ *
103
+ * @returns Promise that resolves when the stop request is sent
104
+ */
105
+ stopManagedStream(): Promise<void>;
106
+ /**
107
+ * ๐Ÿ“Š Check if currently managed streaming
108
+ *
109
+ * @returns true if a managed stream is active
110
+ */
111
+ isManagedStreamActive(): boolean;
112
+ /**
113
+ * ๐Ÿ”— Get current managed stream URLs
114
+ *
115
+ * @returns Current stream URLs or undefined if not streaming
116
+ */
117
+ getManagedStreamUrls(): ManagedStreamResult | undefined;
118
+ /**
119
+ * ๐Ÿ“Š Get current managed stream status
120
+ *
121
+ * @returns Current stream status or undefined
122
+ */
123
+ getManagedStreamStatus(): ManagedStreamStatus | undefined;
124
+ /**
125
+ * ๐Ÿ”” Register a handler for managed stream status updates
126
+ *
127
+ * @param handler - Function to call when stream status changes
128
+ * @returns Cleanup function to unregister the handler
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const cleanup = session.camera.onManagedStreamStatus((status) => {
133
+ * console.log('Status:', status.status);
134
+ * if (status.status === 'active') {
135
+ * console.log('Stream is live!');
136
+ * }
137
+ * });
138
+ *
139
+ * // Later, unregister the handler
140
+ * cleanup();
141
+ * ```
142
+ */
143
+ onManagedStreamStatus(handler: (status: ManagedStreamStatus) => void): () => void;
144
+ /**
145
+ * Handle incoming managed stream status messages
146
+ * Called by the parent AppSession when messages are received
147
+ */
148
+ handleManagedStreamStatus(status: ManagedStreamStatus): void;
149
+ /**
150
+ * ๐Ÿงน Clean up all managed streaming state
151
+ */
152
+ cleanup(): void;
153
+ }
154
+ //# sourceMappingURL=camera-managed-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-managed-extension.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera-managed-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,mBAAmB,EAKnB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAC,CAAM;IAGtB,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,wBAAwB,CAAC,CAAsB;IACvD,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAGlD,OAAO,CAAC,2BAA2B,CAAC,CAGlC;gBAGA,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,GAAG;IASf;;;;;;;;;;;;;;;;;;OAkBG;IACG,kBAAkB,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAyC1F;;;;;;;OAOG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBxC;;;;OAIG;IACH,qBAAqB,IAAI,OAAO;IAIhC;;;;OAIG;IACH,oBAAoB,IAAI,mBAAmB,GAAG,SAAS;IAIvD;;;;OAIG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,SAAS;IAIzD;;;;;;;;;;;;;;;;;;OAkBG;IACH,qBAAqB,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,GAAG,MAAM,IAAI;IAYjF;;;OAGG;IACH,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAwD5D;;OAEG;IACH,OAAO,IAAI,IAAI;CAahB"}