@journium/js 1.0.1 → 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
@@ -77,11 +77,12 @@ import { init } from '@journium/js';
77
77
  const journium = init({
78
78
  publishableKey: 'your-journium-publishable-key',
79
79
  apiHost: 'https://your-custom-instance.com', // Optional: defaults to 'https://events.journium.app'
80
- config: {
80
+ options: {
81
81
  debug: true, // Enable debug logging
82
82
  flushAt: 10, // Send events after N events
83
83
  flushInterval: 5000, // Send events every N milliseconds
84
84
  sessionTimeout: 1800000, // Session timeout (30 minutes)
85
+ autoTrackPageviews: true, // Track pageview events (default: true)
85
86
  autocapture: { // Configure automatic event capture
86
87
  captureClicks: true, // Track click events
87
88
  captureFormSubmits: true, // Track form submissions
@@ -98,85 +99,148 @@ journium.startAutocapture();
98
99
 
99
100
  ## API Reference
100
101
 
101
- ### `init(config: JourniumConfig)`
102
- Initialize the Journium SDK with your configuration.
102
+ ### Functions
103
103
 
104
- ```javascript
105
- const journium = init({
106
- publishableKey: 'your-journium-publishable-key',
107
- apiHost: 'https://events.journium.app', // Optional
108
- config: { /* optional local config */ }
109
- });
110
- ```
104
+ #### `init(config: JourniumConfig)`
105
+ Initializes and returns a new JourniumAnalytics instance.
111
106
 
112
- ### `journium.track(eventName, properties?)`
113
- Track custom events with optional properties.
107
+ **Parameters:**
108
+ - `config: JourniumConfig` - Configuration object for Journium
109
+ - `publishableKey: string` - Your Journium publishable key (required)
110
+ - `apiHost?: string` - Custom API endpoint (optional, defaults to 'https://events.journium.app')
111
+ - `options?: JourniumLocalOptions` - Local configuration options (optional)
114
112
 
115
- ```javascript
116
- // Simple event
117
- journium.track('feature_used');
118
-
119
- // Event with properties
120
- journium.track('purchase_completed', {
121
- product_id: 'prod_123',
122
- amount: 29.99,
123
- currency: 'USD'
124
- });
125
- ```
113
+ **Returns:** `JourniumAnalytics` - Analytics instance for tracking events
126
114
 
127
- ### `journium.identify(distinctId, attributes?)`
128
- Identify a user when they log in or sign up.
115
+ ### JourniumAnalytics Instance Methods
129
116
 
130
- ```javascript
131
- journium.identify('user_12345', {
132
- name: 'John Doe',
133
- email: 'john@example.com',
134
- signup_date: '2024-01-15'
135
- });
136
- ```
117
+ #### `track(event: string, properties?: Record<string, unknown>): void`
118
+ Tracks custom events with optional properties.
137
119
 
138
- ### `journium.reset()`
139
- Reset user identity when they log out.
120
+ **Parameters:**
121
+ - `event: string` - Event name to track
122
+ - `properties?: Record<string, unknown>` - Optional event properties
140
123
 
141
- ```javascript
142
- journium.reset();
143
- ```
124
+ #### `identify(distinctId: string, attributes?: Record<string, unknown>): void`
125
+ Identifies a user and associates future events with their identity.
144
126
 
145
- ### `journium.capturePageview(properties?)`
146
- Manually capture pageview events.
127
+ **Parameters:**
128
+ - `distinctId: string` - Unique user identifier
129
+ - `attributes?: Record<string, unknown>` - Optional user attributes
147
130
 
148
- ```javascript
149
- // Simple pageview
150
- journium.capturePageview();
131
+ #### `reset(): void`
132
+ Resets user identity, typically called on logout.
151
133
 
152
- // Pageview with custom properties
153
- journium.capturePageview({
154
- section: 'pricing',
155
- experiment_variant: 'v2'
156
- });
157
- ```
134
+ **Returns:** `void`
158
135
 
159
- ### `journium.startAutocapture()` / `journium.stopAutocapture()`
160
- Control automatic event capture for clicks, pageviews, and form interactions.
136
+ #### `capturePageview(properties?: Record<string, unknown>): void`
137
+ Manually captures pageview events.
161
138
 
162
- ```javascript
163
- // Start automatic capture
164
- journium.startAutocapture();
139
+ **Parameters:**
140
+ - `properties?: Record<string, unknown>` - Optional pageview properties
165
141
 
166
- // Stop automatic capture
167
- journium.stopAutocapture();
142
+ #### `startAutocapture(): void`
143
+ Starts automatic event capture for clicks, form interactions, and pageviews.
144
+
145
+ **Returns:** `void`
146
+
147
+ **Note:** Autocapture behavior is configured during initialization via the `autocapture` option.
148
+
149
+ #### `stopAutocapture(): void`
150
+ Stops automatic event capture.
151
+
152
+ **Returns:** `void`
153
+
154
+ #### `flush(): Promise<void>`
155
+ Manually sends all queued events to the server immediately.
156
+
157
+ **Returns:** `Promise<void>` - Promise that resolves when events are sent
158
+
159
+ #### `destroy(): void`
160
+ Cleans up the SDK, stops all tracking, and sends remaining events.
161
+
162
+ **Returns:** `void`
163
+
164
+ #### `getEffectiveOptions(): JourniumLocalOptions`
165
+ Returns the effective configuration options (merged local and remote options).
166
+
167
+ **Returns:** `JourniumLocalOptions` - Current effective configuration
168
+
169
+ ### Types
170
+
171
+ #### `JourniumConfig`
172
+ Configuration object for initializing Journium.
173
+
174
+ ```typescript
175
+ interface JourniumConfig {
176
+ publishableKey: string;
177
+ apiHost?: string;
178
+ options?: JourniumLocalOptions;
179
+ }
168
180
  ```
169
181
 
170
- ### `journium.flush()`
171
- Manually send queued events to the server.
182
+ #### `JourniumLocalOptions`
183
+ Local configuration options that can be set on the client.
184
+
185
+ ```typescript
186
+ interface JourniumLocalOptions {
187
+ debug?: boolean; // Enable debug logging
188
+ flushAt?: number; // Number of events before auto-flush
189
+ flushInterval?: number; // Flush interval in milliseconds
190
+ autocapture?: boolean | AutocaptureOptions; // Auto-capture configuration
191
+ autoTrackPageviews?: boolean; // Automatic pageview tracking
192
+ sessionTimeout?: number; // Session timeout in milliseconds
193
+ sampling?: {
194
+ enabled?: boolean;
195
+ rate?: number;
196
+ };
197
+ features?: {
198
+ enableGeolocation?: boolean;
199
+ enableSessionRecording?: boolean;
200
+ enablePerformanceTracking?: boolean;
201
+ };
202
+ }
203
+ ```
172
204
 
173
- ```javascript
174
- await journium.flush();
205
+ #### `AutocaptureOptions`
206
+ Configuration for automatic event capture.
207
+
208
+ ```typescript
209
+ interface AutocaptureOptions {
210
+ captureClicks?: boolean; // Capture click events
211
+ captureFormSubmits?: boolean; // Capture form submissions
212
+ captureFormChanges?: boolean; // Capture form field changes
213
+ captureTextSelection?: boolean; // Capture text selection events
214
+ ignoreClasses?: string[]; // CSS classes to ignore
215
+ ignoreElements?: string[]; // HTML elements to ignore
216
+ captureContentText?: boolean; // Capture element text content
217
+ }
175
218
  ```
176
219
 
177
- ### `journium.destroy()`
178
- Clean up the SDK and send any remaining events.
220
+ ### Browser Support
179
221
 
180
- ```javascript
181
- journium.destroy();
222
+ - ✅ Modern browsers (ES2017+)
223
+ - ✅ Chrome 60+
224
+ - ✅ Firefox 55+
225
+ - ✅ Safari 11+
226
+ - ✅ Edge 79+
227
+
228
+ ### Bundle Formats
229
+
230
+ The package includes multiple build formats:
231
+
232
+ - **ESM**: `dist/index.esm.js` - For modern bundlers (webpack, Vite, Rollup)
233
+ - **CommonJS**: `dist/index.cjs` - For Node.js environments
234
+ - **UMD**: `dist/index.umd.js` - For browser `<script>` tags
235
+
236
+ #### UMD Usage
237
+
238
+ ```html
239
+ <script src="node_modules/@journium/js/dist/index.umd.js"></script>
240
+ <script>
241
+ const analytics = window.JourniumAnalytics.init({
242
+ publishableKey: 'your-publishable-key'
243
+ });
244
+ analytics.track('page_loaded');
245
+ </script>
182
246
  ```
@@ -0,0 +1,26 @@
1
+ import { JourniumConfig } from '@journium/core';
2
+ export declare class JourniumAnalytics {
3
+ private client;
4
+ private pageviewTracker;
5
+ private autocaptureTracker;
6
+ private config;
7
+ private autocaptureEnabled;
8
+ constructor(config: JourniumConfig);
9
+ private resolveAutocaptureOptions;
10
+ track(event: string, properties?: Record<string, unknown>): void;
11
+ identify(distinctId: string, attributes?: Record<string, unknown>): void;
12
+ reset(): void;
13
+ capturePageview(properties?: Record<string, unknown>): void;
14
+ startAutocapture(): void;
15
+ stopAutocapture(): void;
16
+ flush(): Promise<void>;
17
+ getEffectiveOptions(): import("@journium/core").JourniumLocalOptions;
18
+ destroy(): void;
19
+ }
20
+ export declare const init: (config: JourniumConfig) => JourniumAnalytics;
21
+ declare const _default: {
22
+ init: (config: JourniumConfig) => JourniumAnalytics;
23
+ JourniumAnalytics: typeof JourniumAnalytics;
24
+ };
25
+ export default _default;
26
+ //# sourceMappingURL=JourniumAnalytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JourniumAnalytics.d.ts","sourceRoot":"","sources":["../src/JourniumAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAsB,MAAM,gBAAgB,CAAC;AAKpE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,kBAAkB,CAAU;gBAExB,MAAM,EAAE,cAAc;IAYlC,OAAO,CAAC,yBAAyB;IAiBjC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxE,KAAK,IAAI,IAAI;IAIb,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D,gBAAgB,IAAI,IAAI;IAcxB,eAAe,IAAI,IAAI;IAMjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,mBAAmB;IAInB,OAAO,IAAI,IAAI;CAKhB;AAED,eAAO,MAAM,IAAI,GAAI,QAAQ,cAAc,KAAG,iBAE7C,CAAC;;mBAF2B,cAAc,KAAG,iBAAiB;;;AAI/D,wBAA2C"}
@@ -0,0 +1,25 @@
1
+ import { JourniumConfig, JourniumLocalOptions } from '@journium/core';
2
+ export declare class JourniumClient {
3
+ private config;
4
+ private effectiveOptions;
5
+ private queue;
6
+ private flushTimer;
7
+ private initialized;
8
+ private identityManager;
9
+ private optionsStorageKey;
10
+ constructor(config: JourniumConfig);
11
+ private loadCachedOptions;
12
+ private saveCachedOptions;
13
+ private initializeSync;
14
+ private fetchRemoteOptionsAsync;
15
+ private fetchAndCacheRemoteOptions;
16
+ private startFlushTimer;
17
+ private sendEvents;
18
+ identify(distinctId: string, attributes?: Record<string, unknown>): void;
19
+ reset(): void;
20
+ track(event: string, properties?: Record<string, unknown>): void;
21
+ flush(): Promise<void>;
22
+ destroy(): void;
23
+ getEffectiveOptions(): JourniumLocalOptions;
24
+ }
25
+ //# sourceMappingURL=JourniumClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JourniumClient.d.ts","sourceRoot":"","sources":["../src/JourniumClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,oBAAoB,EAAwH,MAAM,gBAAgB,CAAC;AAE3M,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,gBAAgB,CAAwB;IAChD,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,iBAAiB,CAAU;gBAEvB,MAAM,EAAE,cAAc;IAsClC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,cAAc;YA0BR,uBAAuB;YAOvB,0BAA0B;IAyCxC,OAAO,CAAC,eAAe;YAWT,UAAU;IA8BxB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAyB5E,KAAK,IAAI,IAAI;IAiBb,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IA4C9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,OAAO,IAAI,IAAI;IAQf,mBAAmB,IAAI,oBAAoB;CAG5C"}
@@ -1,23 +1,11 @@
1
- import { JourniumClient } from './client';
2
- export interface AutocaptureConfig {
3
- captureClicks?: boolean;
4
- captureFormSubmits?: boolean;
5
- captureFormChanges?: boolean;
6
- captureTextSelection?: boolean;
7
- ignoreClasses?: string[];
8
- ignoreElements?: string[];
9
- captureContentText?: boolean;
10
- }
11
- export interface AutocaptureEvent {
12
- event: string;
13
- properties: Record<string, any>;
14
- }
1
+ import { JourniumClient } from './JourniumClient';
2
+ import { AutocaptureOptions } from '@journium/core';
15
3
  export declare class AutocaptureTracker {
16
4
  private client;
17
- private config;
5
+ private options;
18
6
  private listeners;
19
7
  private isActive;
20
- constructor(client: JourniumClient, config?: AutocaptureConfig);
8
+ constructor(client: JourniumClient, options?: AutocaptureOptions);
21
9
  start(): void;
22
10
  stop(): void;
23
11
  private addClickListener;
@@ -1 +1 @@
1
- {"version":3,"file":"autocapture.d.ts","sourceRoot":"","sources":["../src/autocapture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,cAAc,EAAE,MAAM,GAAE,iBAAsB;IAclE,KAAK,IAAI,IAAI;IAwBb,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,oBAAoB;IAiE5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,eAAe;CAKxB"}
1
+ {"version":3,"file":"autocapture.d.ts","sourceRoot":"","sources":["../src/autocapture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAa,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE/D,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,kBAAuB;IAcpE,KAAK,IAAI,IAAI;IAwBb,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,oBAAoB;IAiE5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,eAAe;CAKxB"}
package/dist/client.d.ts CHANGED
@@ -1,24 +1,25 @@
1
- import { JourniumConfig } from '@journium/core';
1
+ import { JourniumConfig, JourniumLocalOptions } from '@journium/core';
2
2
  export declare class JourniumClient {
3
3
  private config;
4
- private effectiveConfig;
4
+ private effectiveOptions;
5
5
  private queue;
6
6
  private flushTimer;
7
7
  private initialized;
8
8
  private identityManager;
9
- private configStorageKey;
9
+ private optionsStorageKey;
10
10
  constructor(config: JourniumConfig);
11
- private loadCachedConfig;
12
- private saveCachedConfig;
11
+ private loadCachedOptions;
12
+ private saveCachedOptions;
13
13
  private initializeSync;
14
- private fetchRemoteConfigAsync;
15
- private fetchAndCacheRemoteConfig;
14
+ private fetchRemoteOptionsAsync;
15
+ private fetchAndCacheRemoteOptions;
16
16
  private startFlushTimer;
17
17
  private sendEvents;
18
- identify(distinctId: string, attributes?: Record<string, any>): void;
18
+ identify(distinctId: string, attributes?: Record<string, unknown>): void;
19
19
  reset(): void;
20
- track(event: string, properties?: Record<string, any>): void;
20
+ track(event: string, properties?: Record<string, unknown>): void;
21
21
  flush(): Promise<void>;
22
22
  destroy(): void;
23
+ getEffectiveOptions(): JourniumLocalOptions;
23
24
  }
24
25
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAqI,MAAM,gBAAgB,CAAC;AAElM,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,gBAAgB,CAAU;gBAEtB,MAAM,EAAE,cAAc;IAsClC,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,cAAc;YA0BR,sBAAsB;YAOtB,yBAAyB;IAyCvC,OAAO,CAAC,eAAe;YAWT,UAAU;IA8BxB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI;IAyBxE,KAAK,IAAI,IAAI;IAiBb,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,IAAI;IA4C1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,OAAO,IAAI,IAAI;CAOhB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,oBAAoB,EAAwH,MAAM,gBAAgB,CAAC;AAE3M,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,gBAAgB,CAAwB;IAChD,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,iBAAiB,CAAU;gBAEvB,MAAM,EAAE,cAAc;IAsClC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,cAAc;YA0BR,uBAAuB;YAOvB,0BAA0B;IAyCxC,OAAO,CAAC,eAAe;YAWT,UAAU;IA8BxB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAyB5E,KAAK,IAAI,IAAI;IAiBb,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IA4C9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,OAAO,IAAI,IAAI;IAQf,mBAAmB,IAAI,oBAAoB;CAG5C"}